diff --git a/code/__DEFINES/fish.dm b/code/__DEFINES/fish.dm index 7d4b5e0d547..c64a50cd077 100644 --- a/code/__DEFINES/fish.dm +++ b/code/__DEFINES/fish.dm @@ -2,6 +2,8 @@ #define FISHING_DUD "dud" ///Used in the the hydro tray fishing spot to define a random seed reward #define FISHING_RANDOM_SEED "Random seed" +///Used in the surgery fishing spot to define a random organ reward +#define FISHING_RANDOM_ORGAN "Random organ" // Baseline fishing difficulty levels #define FISHING_DEFAULT_DIFFICULTY 15 @@ -94,6 +96,7 @@ #define FISH_ICON_WEAPON "weapon" #define FISH_ICON_CRITTER "critter" #define FISH_ICON_SEED "seed" +#define FISH_ICON_ORGAN "organ" #define AQUARIUM_ANIMATION_FISH_SWIM "fish" #define AQUARIUM_ANIMATION_FISH_DEAD "dead" diff --git a/code/__DEFINES/organ_movement.dm b/code/__DEFINES/organ_movement.dm index 16f003ede81..04e60eb92f0 100644 --- a/code/__DEFINES/organ_movement.dm +++ b/code/__DEFINES/organ_movement.dm @@ -2,3 +2,5 @@ #define DELETE_IF_REPLACED (1<<0) /// When deleting a brain, we don't delete the identity and the player can keep playing #define NO_ID_TRANSFER (1<<1) +/// Organ inserted by the abductors surgery +#define FROM_ABDUCTOR_SURGERY (1<<2) diff --git a/code/__DEFINES/surgery.dm b/code/__DEFINES/surgery.dm index f510d7a1a94..814c8fed9e5 100644 --- a/code/__DEFINES/surgery.dm +++ b/code/__DEFINES/surgery.dm @@ -93,6 +93,12 @@ #define SURGERY_REQUIRES_REAL_LIMB (1<<4) ///Will grant a bonus during surgery steps to users with TRAIT_MORBID while they're using tools with CRUEL_IMPLEMENT #define SURGERY_MORBID_CURIOSITY (1<<5) +/** + * Instead of checking if the tool used is an actual surgery tool to avoid accidentally whacking patients with the wrong tool, + * it'll check if it has a defined tool behaviour instead. Useful for surgeries that use mechanical tools instead of medical ones, + * like hardware manipulation. + */ +#define SURGERY_CHECK_TOOL_BEHAVIOUR (1<<6) ///Return true if target is not in a valid body position for the surgery #define IS_IN_INVALID_SURGICAL_POSITION(target, surgery) ((surgery.surgery_flags & SURGERY_REQUIRE_RESTING) && (target.mobility_flags & MOBILITY_LIEDOWN && target.body_position != LYING_DOWN)) diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm index 32929ccdb9f..f2faf6ae81f 100644 --- a/code/_globalvars/lists/objects.dm +++ b/code/_globalvars/lists/objects.dm @@ -32,9 +32,13 @@ GLOBAL_LIST_EMPTY(deliverybeacontags) GLOBAL_LIST_EMPTY_TYPED(singularities, /datum/component/singularity) GLOBAL_LIST_EMPTY(item_to_design_list) + /// list of all surgeries by name, associated with their path. GLOBAL_LIST_INIT(surgeries_list, init_surgeries()) +/// list of all surgery steps, associated by their path. +GLOBAL_LIST_INIT(surgery_steps, init_subtypes_w_path_keys(/datum/surgery_step, list())) + /// Global list of all non-cooking related crafting recipes. GLOBAL_LIST_EMPTY(crafting_recipes) /// This is a global list of typepaths, these typepaths are atoms or reagents that are associated with crafting recipes. @@ -80,3 +84,22 @@ GLOBAL_LIST_EMPTY(roundstart_station_borgcharger_areas) /// List of area names of roundstart station mech rechargers, for the low charge/no charge mech screen alert tooltips. GLOBAL_LIST_EMPTY(roundstart_station_mechcharger_areas) + +// List of organ typepaths that are not unit test-able, and shouldn't be spawned by some things, such as certain class prototypes. +GLOBAL_LIST_INIT(prototype_organs, typecacheof(list( + /obj/item/organ, + /obj/item/organ/wings, + /obj/item/organ/wings/functional, + /obj/item/organ/wings/functional/moth, + /obj/item/organ/cyberimp, + /obj/item/organ/cyberimp/brain, + /obj/item/organ/cyberimp/mouth, + /obj/item/organ/cyberimp/arm, + /obj/item/organ/cyberimp/chest, + /obj/item/organ/cyberimp/eyes, + /obj/item/organ/alien, + /obj/item/organ/brain/dullahan, + /obj/item/organ/ears/dullahan, + /obj/item/organ/tongue/dullahan, + /obj/item/organ/eyes/dullahan, +), only_root_path = TRUE)) diff --git a/code/datums/components/shell.dm b/code/datums/components/shell.dm index 9c74920a862..feb6e572bfd 100644 --- a/code/datums/components/shell.dm +++ b/code/datums/components/shell.dm @@ -346,7 +346,11 @@ )) if(attached_circuit.loc == parent || (!QDELETED(attached_circuit) && attached_circuit.loc == null)) var/atom/parent_atom = parent - attached_circuit.forceMove(parent_atom.drop_location()) + var/drop_location = parent_atom.drop_location() + if(drop_location) + attached_circuit.forceMove(drop_location) + else + attached_circuit.moveToNullspace() for(var/obj/item/circuit_component/to_remove as anything in unremovable_circuit_components) attached_circuit.remove_component(to_remove) diff --git a/code/game/machinery/computer/operating_computer.dm b/code/game/machinery/computer/operating_computer.dm index 83a2a08d986..3cba3ad2078 100644 --- a/code/game/machinery/computer/operating_computer.dm +++ b/code/game/machinery/computer/operating_computer.dm @@ -140,7 +140,7 @@ data["patient"]["oxyLoss"] = patient.getOxyLoss() if(patient.surgeries.len) for(var/datum/surgery/procedure in patient.surgeries) - var/datum/surgery_step/surgery_step = procedure.get_surgery_step() + var/datum/surgery_step/surgery_step = GLOB.surgery_steps[procedure.steps[procedure.status]] var/chems_needed = surgery_step.get_chem_list() var/alternative_step var/alt_chems_needed = "" diff --git a/code/game/machinery/dna_infuser/organ_sets/gondola_organs.dm b/code/game/machinery/dna_infuser/organ_sets/gondola_organs.dm index 82c9c9fc8e8..805277b3d9c 100644 --- a/code/game/machinery/dna_infuser/organ_sets/gondola_organs.dm +++ b/code/game/machinery/dna_infuser/organ_sets/gondola_organs.dm @@ -34,7 +34,7 @@ Fluoride Stare: After someone says 5 words, blah blah blah... AddElement(/datum/element/noticable_organ, "%PRONOUN_They radiate%PRONOUN_s an aura of serenity.") AddElement(/datum/element/update_icon_blocker) -/obj/item/organ/heart/gondola/mob_insert(mob/living/carbon/receiver, special, movement_flags) +/obj/item/organ/heart/gondola/on_mob_insert(mob/living/carbon/receiver, special, movement_flags) . = ..() if(!(FACTION_HOSTILE in receiver.faction)) factions_to_remove += FACTION_HOSTILE @@ -42,7 +42,7 @@ Fluoride Stare: After someone says 5 words, blah blah blah... factions_to_remove += FACTION_MINING receiver.faction |= list(FACTION_HOSTILE, FACTION_MINING) -/obj/item/organ/heart/gondola/mob_remove(mob/living/carbon/heartless, special, movement_flags) +/obj/item/organ/heart/gondola/on_mob_remove(mob/living/carbon/heartless, special, movement_flags) . = ..() for(var/faction in factions_to_remove) heartless.faction -= faction @@ -64,11 +64,11 @@ Fluoride Stare: After someone says 5 words, blah blah blah... AddElement(/datum/element/noticable_organ, "%PRONOUN_Their mouth is permanently affixed into a relaxed smile.", BODY_ZONE_PRECISE_MOUTH) AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/gondola) -/obj/item/organ/tongue/gondola/mob_insert(mob/living/carbon/tongue_owner, special, movement_flags) +/obj/item/organ/tongue/gondola/on_mob_insert(mob/living/carbon/tongue_owner, special, movement_flags) . = ..() tongue_owner.add_mood_event("gondola_zen", /datum/mood_event/gondola_serenity) -/obj/item/organ/tongue/gondola/mob_remove(mob/living/carbon/tongue_owner, special, movement_flags) +/obj/item/organ/tongue/gondola/on_mob_remove(mob/living/carbon/tongue_owner, special, movement_flags) tongue_owner.clear_mood_event("gondola_zen") return ..() @@ -87,7 +87,7 @@ Fluoride Stare: After someone says 5 words, blah blah blah... AddElement(/datum/element/noticable_organ, "%PRONOUN_Their left arm has small needles breaching the skin all over it.", BODY_ZONE_L_ARM) AddElement(/datum/element/noticable_organ, "%PRONOUN_Their right arm has small needles breaching the skin all over it.", BODY_ZONE_R_ARM) -/obj/item/organ/liver/gondola/mob_insert(mob/living/carbon/liver_owner, special, movement_flags) +/obj/item/organ/liver/gondola/on_mob_insert(mob/living/carbon/liver_owner, special, movement_flags) . = ..() var/has_left = liver_owner.has_left_hand(check_disabled = FALSE) var/has_right = liver_owner.has_right_hand(check_disabled = FALSE) @@ -102,7 +102,7 @@ Fluoride Stare: After someone says 5 words, blah blah blah... RegisterSignal(liver_owner, COMSIG_LIVING_TRY_PULL, PROC_REF(on_owner_try_pull)) RegisterSignal(liver_owner, COMSIG_CARBON_HELPED, PROC_REF(on_hug)) -/obj/item/organ/liver/gondola/mob_remove(mob/living/carbon/liver_owner, special, movement_flags) +/obj/item/organ/liver/gondola/on_mob_remove(mob/living/carbon/liver_owner, special, movement_flags) . = ..() UnregisterSignal(liver_owner, list(COMSIG_HUMAN_EQUIPPING_ITEM, COMSIG_LIVING_TRY_PULL, COMSIG_CARBON_HELPED)) diff --git a/code/game/machinery/dna_infuser/organ_sets/rat_organs.dm b/code/game/machinery/dna_infuser/organ_sets/rat_organs.dm index f10dcefb0d5..251c5c35a49 100644 --- a/code/game/machinery/dna_infuser/organ_sets/rat_organs.dm +++ b/code/game/machinery/dna_infuser/organ_sets/rat_organs.dm @@ -74,7 +74,7 @@ //but 1.5 damage human_receiver.physiology?.damage_resistance -= 50 -/obj/item/organ/heart/rat/on_mob_remove(mob/living/carbon/heartless, special) +/obj/item/organ/heart/rat/on_mob_remove(mob/living/carbon/heartless, special, movement_flags) . = ..() if(!ishuman(heartless)) return diff --git a/code/game/machinery/dna_infuser/organ_sets/roach_organs.dm b/code/game/machinery/dna_infuser/organ_sets/roach_organs.dm index 2b32ad85702..03955f06ffe 100644 --- a/code/game/machinery/dna_infuser/organ_sets/roach_organs.dm +++ b/code/game/machinery/dna_infuser/organ_sets/roach_organs.dm @@ -72,7 +72,7 @@ QDEL_NULL(roach_shell) return ..() -/obj/item/organ/heart/roach/on_mob_insert(mob/living/carbon/organ_owner, special) +/obj/item/organ/heart/roach/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags) . = ..() if(!ishuman(organ_owner)) return @@ -87,7 +87,7 @@ . = ..() limb.add_bodypart_overlay(roach_shell) -/obj/item/organ/heart/roach/on_mob_remove(mob/living/carbon/organ_owner, special) +/obj/item/organ/heart/roach/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) . = ..() if(!ishuman(organ_owner) || QDELETED(organ_owner)) return @@ -195,7 +195,7 @@ . = ..() AddElement(/datum/element/organ_set_bonus, /datum/status_effect/organ_set_bonus/roach) -/obj/item/organ/liver/roach/on_mob_insert(mob/living/carbon/organ_owner, special) +/obj/item/organ/liver/roach/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags) . = ..() if(!ishuman(organ_owner)) return @@ -203,7 +203,7 @@ var/mob/living/carbon/human/human_owner = owner human_owner.physiology.tox_mod *= 2 -/obj/item/organ/liver/roach/on_mob_remove(mob/living/carbon/organ_owner, special) +/obj/item/organ/liver/roach/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) . = ..() if(!ishuman(organ_owner) || QDELETED(organ_owner)) return diff --git a/code/game/objects/items/body_egg.dm b/code/game/objects/items/body_egg.dm index d5769ceb8d7..7a8d70888f0 100644 --- a/code/game/objects/items/body_egg.dm +++ b/code/game/objects/items/body_egg.dm @@ -15,14 +15,14 @@ if(iscarbon(loc)) Insert(loc) -/obj/item/organ/body_egg/mob_insert(mob/living/carbon/egg_owner, special = FALSE, movement_flags = DELETE_IF_REPLACED) +/obj/item/organ/body_egg/on_mob_insert(mob/living/carbon/egg_owner, special = FALSE, movement_flags) . = ..() egg_owner.add_traits(list(TRAIT_XENO_HOST, TRAIT_XENO_IMMUNE), ORGAN_TRAIT) egg_owner.med_hud_set_status() INVOKE_ASYNC(src, PROC_REF(AddInfectionImages), egg_owner) -/obj/item/organ/body_egg/mob_remove(mob/living/carbon/egg_owner, special, movement_flags) +/obj/item/organ/body_egg/on_mob_remove(mob/living/carbon/egg_owner, special, movement_flags) . = ..() egg_owner.remove_traits(list(TRAIT_XENO_HOST, TRAIT_XENO_IMMUNE), ORGAN_TRAIT) egg_owner.med_hud_set_status() diff --git a/code/modules/antagonists/abductor/equipment/abduction_surgery.dm b/code/modules/antagonists/abductor/equipment/abduction_surgery.dm index 296eef07e81..790dd0f8e53 100644 --- a/code/modules/antagonists/abductor/equipment/abduction_surgery.dm +++ b/code/modules/antagonists/abductor/equipment/abduction_surgery.dm @@ -60,5 +60,5 @@ user.visible_message(span_notice("[user] inserts [tool] into [target]."), span_notice("You insert [tool] into [target].")) user.temporarilyRemoveItemFromInventory(tool, TRUE) var/obj/item/organ/heart/gland/gland = tool - gland.Insert(target, 2) - return 1 + gland.Insert(target, special = TRUE, movement_flags = FROM_ABDUCTOR_SURGERY) + return TRUE diff --git a/code/modules/antagonists/abductor/equipment/gland.dm b/code/modules/antagonists/abductor/equipment/gland.dm index b991a16b831..9f5bae7aad5 100644 --- a/code/modules/antagonists/abductor/equipment/gland.dm +++ b/code/modules/antagonists/abductor/equipment/gland.dm @@ -84,7 +84,7 @@ active_mind_control = FALSE return TRUE -/obj/item/organ/heart/gland/mob_remove(mob/living/carbon/gland_owner, special, movement_flags) +/obj/item/organ/heart/gland/on_mob_remove(mob/living/carbon/gland_owner, special, movement_flags) . = ..() active = FALSE if(initial(uses) == 1) @@ -93,10 +93,10 @@ hud.remove_atom_from_hud(gland_owner) clear_mind_control() -/obj/item/organ/heart/gland/mob_insert(mob/living/carbon/gland_owner, special = FALSE, movement_flags = DELETE_IF_REPLACED) +/obj/item/organ/heart/gland/on_mob_insert(mob/living/carbon/gland_owner, special = FALSE, movement_flags) . = ..() - if(special != 2 && uses) // Special 2 means abductor surgery + if(!(movement_flags & FROM_ABDUCTOR_SURGERY) && uses) Start() var/datum/atom_hud/abductor/hud = GLOB.huds[DATA_HUD_ABDUCTOR] hud.add_atom_to_hud(gland_owner) diff --git a/code/modules/antagonists/changeling/headslug_eggs.dm b/code/modules/antagonists/changeling/headslug_eggs.dm index e2238d9d7e7..5c237b11560 100644 --- a/code/modules/antagonists/changeling/headslug_eggs.dm +++ b/code/modules/antagonists/changeling/headslug_eggs.dm @@ -11,11 +11,11 @@ /// When this egg last got removed from a body. If -1, the egg hasn't been removed from a body. var/removal_time = -1 -/obj/item/organ/body_egg/changeling_egg/mob_insert(mob/living/carbon/egg_owner, special = FALSE, movement_flags = DELETE_IF_REPLACED) +/obj/item/organ/body_egg/changeling_egg/on_mob_insert(mob/living/carbon/egg_owner, special = FALSE, movement_flags) . = ..() hatch_time = world.time + (removal_time == -1 ? EGG_INCUBATION_TIME : (hatch_time - removal_time)) -/obj/item/organ/body_egg/changeling_egg/mob_remove(mob/living/carbon/egg_owner, special, movement_flags) +/obj/item/organ/body_egg/changeling_egg/on_mob_remove(mob/living/carbon/egg_owner, special, movement_flags) . = ..() removal_time = world.time diff --git a/code/modules/antagonists/heretic/items/corrupted_organs.dm b/code/modules/antagonists/heretic/items/corrupted_organs.dm index fec25094bb7..0e8699f6771 100644 --- a/code/modules/antagonists/heretic/items/corrupted_organs.dm +++ b/code/modules/antagonists/heretic/items/corrupted_organs.dm @@ -28,7 +28,7 @@ if (LAZYLEN(hallucinations)) organ_owner.client.images |= hallucinations -/obj/item/organ/eyes/corrupt/on_mob_remove(mob/living/carbon/organ_owner, special) +/obj/item/organ/eyes/corrupt/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) . = ..() if (!LAZYLEN(hallucinations)) return @@ -51,7 +51,7 @@ . = ..() RegisterSignal(organ_owner, COMSIG_MOB_SAY, PROC_REF(on_spoken)) -/obj/item/organ/tongue/corrupt/on_mob_remove(mob/living/carbon/organ_owner, special) +/obj/item/organ/tongue/corrupt/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) . = ..() UnregisterSignal(organ_owner, COMSIG_MOB_SAY) @@ -87,11 +87,11 @@ . = ..() AddElement(/datum/element/corrupted_organ) -/obj/item/organ/liver/corrupt/on_mob_insert(mob/living/carbon/organ_owner, special) +/obj/item/organ/liver/corrupt/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags) . = ..() RegisterSignal(organ_owner, COMSIG_ATOM_EXPOSE_REAGENTS, PROC_REF(on_drank)) -/obj/item/organ/liver/corrupt/on_mob_remove(mob/living/carbon/organ_owner, special) +/obj/item/organ/liver/corrupt/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) . = ..() UnregisterSignal(organ_owner, COMSIG_ATOM_EXPOSE_REAGENTS) @@ -124,11 +124,11 @@ AddElement(/datum/element/corrupted_organ) AddElement(/datum/element/noticable_organ, "%PRONOUN_They %PRONOUN_have an unhealthy pallor.") -/obj/item/organ/stomach/corrupt/on_mob_insert(mob/living/carbon/organ_owner, special) +/obj/item/organ/stomach/corrupt/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags) . = ..() RegisterSignal(organ_owner, COMSIG_ATOM_EXPOSE_REAGENTS, PROC_REF(on_drank)) -/obj/item/organ/stomach/corrupt/on_mob_remove(mob/living/carbon/organ_owner, special) +/obj/item/organ/stomach/corrupt/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) . = ..() UnregisterSignal(organ_owner, COMSIG_ATOM_EXPOSE_REAGENTS) diff --git a/code/modules/antagonists/nightmare/nightmare_organs.dm b/code/modules/antagonists/nightmare/nightmare_organs.dm index ddfe675d412..e4b4528d616 100644 --- a/code/modules/antagonists/nightmare/nightmare_organs.dm +++ b/code/modules/antagonists/nightmare/nightmare_organs.dm @@ -94,13 +94,13 @@ user.temporarilyRemoveItemFromInventory(src, TRUE) Insert(user) -/obj/item/organ/heart/nightmare/on_mob_insert(mob/living/carbon/heart_owner, special) +/obj/item/organ/heart/nightmare/on_mob_insert(mob/living/carbon/heart_owner, special, movement_flags) . = ..() if(special != HEART_SPECIAL_SHADOWIFY) blade = new/obj/item/light_eater heart_owner.put_in_hands(blade) -/obj/item/organ/heart/nightmare/on_mob_remove(mob/living/carbon/heart_owner, special) +/obj/item/organ/heart/nightmare/on_mob_remove(mob/living/carbon/heart_owner, special, movement_flags) . = ..() respawn_progress = 0 if(blade && special != HEART_SPECIAL_SHADOWIFY) diff --git a/code/modules/antagonists/voidwalker/voidwalker_organs.dm b/code/modules/antagonists/voidwalker/voidwalker_organs.dm index 23f1c6fb2fe..760caf3c8d8 100644 --- a/code/modules/antagonists/voidwalker/voidwalker_organs.dm +++ b/code/modules/antagonists/voidwalker/voidwalker_organs.dm @@ -26,7 +26,7 @@ /// Speed modifier given when in gravity var/datum/movespeed_modifier/speed_modifier = /datum/movespeed_modifier/grounded_voidwalker /// The void eater weapon - var/obj/item/glass_breaker = /obj/item/void_eater + var/obj/item/glass_breaker /// Our brain transmit telepathy spell var/datum/action/transmit = /datum/action/cooldown/spell/list_target/telepathy/voidwalker @@ -52,7 +52,7 @@ glass_breaker = new/obj/item/void_eater organ_owner.put_in_hands(glass_breaker) -/obj/item/organ/brain/voidwalker/on_mob_remove(mob/living/carbon/organ_owner, special) +/obj/item/organ/brain/voidwalker/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) . = ..() UnregisterSignal(organ_owner, COMSIG_ENTER_AREA) @@ -72,8 +72,7 @@ transmit.Remove(organ_owner) transmit = initial(transmit) - if(glass_breaker) - qdel(glass_breaker) + QDEL_NULL(glass_breaker) /obj/item/organ/brain/voidwalker/proc/on_atom_entering(mob/living/carbon/organ_owner, atom/entering) SIGNAL_HANDLER diff --git a/code/modules/fishing/fish/chasm_detritus.dm b/code/modules/fishing/fish/chasm_detritus.dm index 9595c552e18..50b35f7d074 100644 --- a/code/modules/fishing/fish/chasm_detritus.dm +++ b/code/modules/fishing/fish/chasm_detritus.dm @@ -43,11 +43,11 @@ GLOBAL_LIST_INIT_TYPED(chasm_detritus_types, /datum/chasm_detritus, init_chasm_d ), ) -/datum/chasm_detritus/proc/dispense_detritus(atom/spawn_location, turf/fishing_spot) +/datum/chasm_detritus/proc/dispense_detritus(atom/spawn_location, atom/fishing_spot) if(prob(default_contents_chance)) var/default_spawn = pick(default_contents[default_contents_key]) return new default_spawn(spawn_location) - return find_chasm_contents(fishing_spot, spawn_location) + return find_chasm_contents(get_turf(fishing_spot), spawn_location) /// Returns the chosen detritus from the given list of things to choose from /datum/chasm_detritus/proc/determine_detritus(list/chasm_stuff) diff --git a/code/modules/fishing/fishing_minigame.dm b/code/modules/fishing/fishing_minigame.dm index a3e9f255e16..a8fa4d26ad8 100644 --- a/code/modules/fishing/fishing_minigame.dm +++ b/code/modules/fishing/fishing_minigame.dm @@ -49,11 +49,13 @@ GLOBAL_LIST_EMPTY(fishing_challenges_by_user) var/reward_path = FISHING_DUD /// Minigame difficulty var/difficulty = FISHING_DEFAULT_DIFFICULTY - // Current phase + /// Current phase var/phase = WAIT_PHASE - // Timer for the next phase + /// Timer for the next phase var/next_phase_timer - // The last time we clicked during the baiting phase + /// The lower and upper bounds of the waiting phase timer + var/list/wait_time_range = list(3 SECONDS, 25 SECONDS) + /// The last time we clicked during the baiting phase var/last_baiting_click /// Fishing mob var/mob/user @@ -126,6 +128,10 @@ GLOBAL_LIST_EMPTY(fishing_challenges_by_user) RegisterSignal(fish_source, COMSIG_FISHING_SOURCE_INTERRUPT_CHALLENGE, PROC_REF(interrupt_challenge)) fish_source.RegisterSignal(user, COMSIG_MOB_COMPLETE_FISHING, TYPE_PROC_REF(/datum/fish_source, on_challenge_completed)) background = comp.fish_source.background + if(comp.fish_source.wait_time_range) + wait_time_range = comp.fish_source.wait_time_range + if(float.spin_frequency) //Using a fishing lure narrows the range a bit, for better or worse. + wait_time_range = list(wait_time_range[1] + 8 SECONDS, wait_time_range[2] - 8 SECONDS) SEND_SIGNAL(user, COMSIG_MOB_BEGIN_FISHING, src) SEND_SIGNAL(rod, COMSIG_ROD_BEGIN_FISHING, src) GLOB.fishing_challenges_by_user[user] = src @@ -209,7 +215,7 @@ GLOBAL_LIST_EMPTY(fishing_challenges_by_user) /datum/fishing_challenge/proc/start(mob/living/user) /// Create fishing line visuals if(!used_rod.internal) - fishing_line = used_rod.create_fishing_line(float, user, target_py = 5) + fishing_line = used_rod.create_fishing_line(float, user, target_py = float.pixel_y + 4) if(isnull(fishing_line)) //couldn't create a fishing line, probably because we don't have a good line of sight. qdel(src) return @@ -369,7 +375,7 @@ GLOBAL_LIST_EMPTY(fishing_challenges_by_user) if(penalty) wait_time = min(timeleft(next_phase_timer) + rand(3 SECONDS, 5 SECONDS), 30 SECONDS) else - wait_time = float.spin_frequency ? rand(11 SECONDS, 17 SECONDS) : rand(3 SECONDS, 25 SECONDS) + wait_time = rand(wait_time_range[1], wait_time_range[2]) if(special_effects & FISHING_MINIGAME_AUTOREEL && wait_time >= 15 SECONDS) wait_time = max(wait_time - 7.5 SECONDS, 15 SECONDS) deltimer(next_phase_timer) @@ -423,6 +429,8 @@ GLOBAL_LIST_EMPTY(fishing_challenges_by_user) send_alert("seed!!!") if(FISH_ICON_BOTTLE) send_alert("bottle!!!") + if(FISH_ICON_ORGAN) + send_alert("organ!!!") else send_alert("!!!") animate(float, pixel_y = 3, time = 5, loop = -1, flags = ANIMATION_RELATIVE) diff --git a/code/modules/fishing/fishing_portal_machine.dm b/code/modules/fishing/fishing_portal_machine.dm index 8b2f1a34e93..ad637031556 100644 --- a/code/modules/fishing/fishing_portal_machine.dm +++ b/code/modules/fishing/fishing_portal_machine.dm @@ -19,6 +19,8 @@ var/long_range_link = FALSE /// contains ALL fishing destinations. var/all_destinations = FALSE + /// If the current active fishing spot is from multitool linkage, this value is the atom it would originally belong to. + var/atom/current_linked_atom /obj/machinery/fishing_portal_generator/Initialize(mapload) . = ..() @@ -202,7 +204,7 @@ if(machine_stat & NOPOWER) balloon_alert(user, "no power!") return ITEM_INTERACT_BLOCKING - if(!istype(selected_source, /datum/fish_source/portal)) //likely from a linked fishing spot + if(!all_destinations && !istype(selected_source, /datum/fish_source/portal)) //likely from a linked fishing spot var/abort = TRUE for(var/atom/spot as anything in linked_fishing_spots) if(linked_fishing_spots[spot] != selected_source) @@ -215,6 +217,7 @@ abort = FALSE if(!abort) RegisterSignal(spot, COMSIG_MOVABLE_Z_CHANGED, PROC_REF(on_fishing_spot_z_level_changed)) + current_linked_atom = spot break if(abort && !all_destinations) balloon_alert(user, "cannot reach linked!") @@ -233,6 +236,7 @@ for(var/atom/spot as anything in linked_fishing_spots) if(linked_fishing_spots[spot] == active.fish_source) UnregisterSignal(spot, COMSIG_MOVABLE_Z_CHANGED) + current_linked_atom = null QDEL_NULL(active) REMOVE_TRAIT(src, TRAIT_CATCH_AND_RELEASE, INNATE_TRAIT) diff --git a/code/modules/fishing/sources/_fish_source.dm b/code/modules/fishing/sources/_fish_source.dm index 09ef60c1ff6..9cde6df476a 100644 --- a/code/modules/fishing/sources/_fish_source.dm +++ b/code/modules/fishing/sources/_fish_source.dm @@ -60,6 +60,7 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons()) )) return_list[FISHING_RANDOM_SEED] = FISH_ICON_SEED + return_list[FISHING_RANDOM_ORGAN] = FISH_ICON_ORGAN return return_list /** @@ -93,6 +94,8 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons()) var/radial_state = "default" ///When selected by the fishing portal, this will be the icon_state of the overlay shown on the machine. var/overlay_state = "portal_aquarium" + ///If set, this overrides the upper and lower bounds of how long you should wait during the waiting phase of the minigame. + var/list/wait_time_range /// Mindless mobs that can fish will never pull up items on this list var/static/list/profound_fisher_blacklist = typecacheof(list( @@ -119,6 +122,8 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons()) for(var/path in fish_counts) if(!(path in fish_table)) stack_trace("path [path] found in the 'fish_counts' list but not in the 'fish_table'") + if(wait_time_range && length(wait_time_range) != 2) + stack_trace("wait_time_range for [type] is set but has length different than two") /datum/fish_source/Destroy() exploded_turfs = null @@ -242,15 +247,14 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons()) UnregisterSignal(user, COMSIG_MOB_COMPLETE_FISHING) if(!success) return - var/turf/fishing_spot = get_turf(challenge.float) - var/atom/movable/reward = dispense_reward(challenge.reward_path, user, fishing_spot) + var/atom/movable/reward = dispense_reward(challenge.reward_path, user, challenge.location) if(reward) user.add_mob_memory(/datum/memory/caught_fish, protagonist = user, deuteragonist = reward.name) SEND_SIGNAL(challenge.used_rod, COMSIG_FISHING_ROD_CAUGHT_FISH, reward, user) challenge.used_rod.on_reward_caught(reward, user) /// Gives out the reward if possible -/datum/fish_source/proc/dispense_reward(reward_path, mob/fisherman, turf/fishing_spot) +/datum/fish_source/proc/dispense_reward(reward_path, mob/fisherman, atom/fishing_spot) var/atom/movable/reward = simple_dispense_reward(reward_path, get_turf(fisherman), fishing_spot) if(!reward) //balloon alert instead fisherman.balloon_alert(fisherman, pick(duds)) @@ -267,7 +271,7 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons()) return reward ///Simplified version of dispense_reward that doesn't need a fisherman. -/datum/fish_source/proc/simple_dispense_reward(reward_path, atom/spawn_location, turf/fishing_spot) +/datum/fish_source/proc/simple_dispense_reward(reward_path, atom/spawn_location, atom/fishing_spot) if(isnull(reward_path)) return null var/area/area = get_area(fishing_spot) @@ -298,7 +302,7 @@ GLOBAL_LIST_INIT(specific_fish_icons, generate_specific_fish_icons()) addtimer(CALLBACK(src, PROC_REF(regen_count), reward_path), regen_time) /// Spawns a reward from a atom path right where the fisherman is. Part of the dispense_reward() logic. -/datum/fish_source/proc/spawn_reward(reward_path, atom/spawn_location, turf/fishing_spot) +/datum/fish_source/proc/spawn_reward(reward_path, atom/spawn_location, atom/fishing_spot) if(reward_path == FISHING_DUD) return if(ispath(reward_path, /datum/chasm_detritus)) diff --git a/code/modules/fishing/sources/source_types.dm b/code/modules/fishing/sources/source_types.dm index e15f290cefe..1828091f061 100644 --- a/code/modules/fishing/sources/source_types.dm +++ b/code/modules/fishing/sources/source_types.dm @@ -294,7 +294,7 @@ mover.long_jump_velocity_limit += rand(-100, 100) ///Cherry on top, fish caught from the randomizer portal also have (almost completely) random traits -/datum/fish_source/portal/random/spawn_reward(reward_path, atom/movable/spawn_location, turf/fishing_spot) +/datum/fish_source/portal/random/spawn_reward(reward_path, atom/spawn_location, atom/fishing_spot) if(!ispath(reward_path, /obj/item/fish)) return ..() @@ -580,7 +580,7 @@ return return ..() -/datum/fish_source/hydro_tray/spawn_reward(reward_path, mob/fisherman, turf/fishing_spot) +/datum/fish_source/hydro_tray/spawn_reward(reward_path, atom/spawn_location, atom/fishing_spot) if(reward_path != FISHING_RANDOM_SEED) var/mob/living/created_reward = ..() if(istype(created_reward)) @@ -649,6 +649,55 @@ ) fishing_difficulty = FISHING_DEFAULT_DIFFICULTY + 13 +/datum/fish_source/surgery + catalog_description = "Surgery" + radial_state = "innards" + overlay_state = "portal_syndicate" //Didn't feel like spriting a new overlay. It's just all red anyway. + background = "background_lavaland" //Kinda red. + fish_table = list(FISHING_RANDOM_ORGAN = 10) + //This should get you below zero difficulty and skip the minigame phase, unless you're wearing something that counteracts this. + fishing_difficulty = -20 + //The range for waiting is also a bit narrower, so it cannot take as few as 3 seconds or as many as 25 to snatch an organ. + wait_time_range = list(6 SECONDS, 12 SECONDS) + +/datum/fish_source/surgery/spawn_reward(reward_path, atom/spawn_location, atom/fishing_spot) + if(istype(fishing_spot, /obj/machinery/fishing_portal_generator)) + var/obj/machinery/fishing_portal_generator/portal = fishing_spot + fishing_spot = portal.current_linked_atom + if(!iscarbon(fishing_spot)) + var/random_type = pick(subtypesof(/obj/item/organ) - GLOB.prototype_organs) + return new random_type(spawn_location) + + var/mob/living/carbon/carbon = fishing_spot + var/list/possible_organs = list() + for(var/datum/surgery/organ_manipulation/operation in carbon.surgeries) + var/datum/surgery_step/manipulate_organs/manip_step = GLOB.surgery_steps[operation.steps[operation.status]] + if(!istype(manip_step)) + continue + for(var/obj/item/organ/organ in operation.operated_bodypart) + if(organ.organ_flags & ORGAN_UNREMOVABLE || !manip_step.can_use_organ(organ)) + continue + possible_organs |= organ + + if(!length(possible_organs)) + return null + var/obj/item/organ/chosen = pick(possible_organs) + chosen.Remove(chosen.owner) + chosen.forceMove(spawn_location) + return chosen + +/datum/fish_source/surgery/generate_wiki_contents(datum/autowiki/fish_sources/wiki) + var/list/data = list() + + data += LIST_VALUE_WRAP_LISTS(list( + FISH_SOURCE_AUTOWIKI_NAME = "Organs", + FISH_SOURCE_AUTOWIKI_DUD = "", + FISH_SOURCE_AUTOWIKI_WEIGHT = 100, + FISH_SOURCE_AUTOWIKI_NOTES = "A random organ from an ongoing organ manipulation surgery.", + )) + + return data + /datum/fish_source/hot_spring catalog_description = "Hot Springs" radial_state = "onsen" diff --git a/code/modules/jobs/job_types/chaplain/chaplain_vorpal_scythe.dm b/code/modules/jobs/job_types/chaplain/chaplain_vorpal_scythe.dm index d2f6f61251d..2debc004e4d 100644 --- a/code/modules/jobs/job_types/chaplain/chaplain_vorpal_scythe.dm +++ b/code/modules/jobs/job_types/chaplain/chaplain_vorpal_scythe.dm @@ -9,11 +9,7 @@ If the scythe isn't empowered when you sheath it, you take a heap of damage and name = "sinister shard" desc = "This shard seems to be directly linked to some sinister entity. It might be your god! It also gives you a really horrible rash when you hold onto it for too long." items_to_create = list(/obj/item/vorpalscythe) - -/obj/item/organ/cyberimp/arm/shard/scythe/mob_insert(mob/living/carbon/receiver, special, movement_flags) - . = ..() - if(receiver.mind) - ADD_TRAIT(receiver.mind, TRAIT_MORBID, ORGAN_TRAIT) + organ_traits = list(TRAIT_MORBID) /obj/item/organ/cyberimp/arm/shard/scythe/Retract() var/obj/item/vorpalscythe/scythe = active_item diff --git a/code/modules/mining/equipment/monster_organs/monster_organ.dm b/code/modules/mining/equipment/monster_organs/monster_organ.dm index b6bd54a361e..ccd3a08c19c 100644 --- a/code/modules/mining/equipment/monster_organs/monster_organ.dm +++ b/code/modules/mining/equipment/monster_organs/monster_organ.dm @@ -83,7 +83,7 @@ deltimer(decay_timer) return ..() -/obj/item/organ/monster_core/mob_insert(mob/living/carbon/target_carbon, special = FALSE, movement_flags) +/obj/item/organ/monster_core/on_mob_insert(mob/living/carbon/target_carbon, special = FALSE, movement_flags) . = ..() if (inert) @@ -96,7 +96,7 @@ target_carbon.visible_message(span_notice("[src] stabilizes as it's inserted.")) return TRUE -/obj/item/organ/monster_core/mob_remove(mob/living/carbon/target_carbon, special, movement_flags) +/obj/item/organ/monster_core/on_mob_remove(mob/living/carbon/target_carbon, special, movement_flags) if (!inert && !special) owner.visible_message(span_notice("[src] rapidly decays as it's removed.")) go_inert() diff --git a/code/modules/mining/equipment/monster_organs/rush_gland.dm b/code/modules/mining/equipment/monster_organs/rush_gland.dm index cf901269e90..8012286975a 100644 --- a/code/modules/mining/equipment/monster_organs/rush_gland.dm +++ b/code/modules/mining/equipment/monster_organs/rush_gland.dm @@ -25,7 +25,7 @@ . = ..() RegisterSignal(organ_owner, COMSIG_GOLIATH_TENTACLED_GRABBED, PROC_REF(trigger_organ_action_on_sig)) -/obj/item/organ/monster_core/rush_gland/on_mob_remove(mob/living/carbon/organ_owner, special) +/obj/item/organ/monster_core/rush_gland/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) . = ..() UnregisterSignal(organ_owner, COMSIG_GOLIATH_TENTACLED_GRABBED) diff --git a/code/modules/mob/living/basic/space_fauna/demon/demon_items.dm b/code/modules/mob/living/basic/space_fauna/demon/demon_items.dm index fdc92d06f66..2af3a42c26d 100644 --- a/code/modules/mob/living/basic/space_fauna/demon/demon_items.dm +++ b/code/modules/mob/living/basic/space_fauna/demon/demon_items.dm @@ -39,7 +39,7 @@ var/datum/action/cooldown/spell/jaunt/bloodcrawl/crawl = new(heart_owner) crawl.Grant(heart_owner) -/obj/item/organ/heart/demon/on_mob_remove(mob/living/carbon/heart_owner, special = FALSE) +/obj/item/organ/heart/demon/on_mob_remove(mob/living/carbon/heart_owner, special = FALSE, movement_flags) . = ..() var/datum/action/cooldown/spell/jaunt/bloodcrawl/crawl = locate() in heart_owner.actions qdel(crawl) diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index 629d79a76b8..97080bc85f9 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -50,7 +50,7 @@ // Brain size logic transform = transform.Scale(brain_size) -/obj/item/organ/brain/mob_insert(mob/living/carbon/brain_owner, special = FALSE, movement_flags) +/obj/item/organ/brain/on_mob_insert(mob/living/carbon/brain_owner, special = FALSE, movement_flags) . = ..() if(!.) return @@ -106,7 +106,7 @@ if(!special && !(brain_owner.living_flags & STOP_OVERLAY_UPDATE_BODY_PARTS)) brain_owner.update_body_parts() -/obj/item/organ/brain/mob_remove(mob/living/carbon/organ_owner, special, movement_flags) +/obj/item/organ/brain/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) // Delete skillchips first as parent proc sets owner to null, and skillchips need to know the brain's owner. if(!QDELETED(organ_owner) && length(skillchips)) if(!special) @@ -123,7 +123,7 @@ BT.on_lose(TRUE) BT.owner = null - if((!gc_destroyed || (owner && !owner.gc_destroyed)) && !(movement_flags & NO_ID_TRANSFER)) + if((!QDELETED(src) || !QDELETED(owner)) && !(movement_flags & NO_ID_TRANSFER)) transfer_identity(organ_owner) if(!special) if(!(organ_owner.living_flags & STOP_OVERLAY_UPDATE_BODY_PARTS)) @@ -457,12 +457,12 @@ owner.RemoveElement(/datum/element/tenacious) . = ..() -/obj/item/organ/brain/lustrous/on_mob_remove(mob/living/carbon/organ_owner, special) +/obj/item/organ/brain/lustrous/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) . = ..() organ_owner.cure_trauma_type(/datum/brain_trauma/special/bluespace_prophet, TRAUMA_RESILIENCE_ABSOLUTE) organ_owner.RemoveElement(/datum/element/tenacious) -/obj/item/organ/brain/lustrous/on_mob_insert(mob/living/carbon/organ_owner, special) +/obj/item/organ/brain/lustrous/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags) . = ..() organ_owner.gain_trauma(/datum/brain_trauma/special/bluespace_prophet, TRAUMA_RESILIENCE_ABSOLUTE) organ_owner.AddElement(/datum/element/tenacious) diff --git a/code/modules/mob/living/carbon/alien/organs.dm b/code/modules/mob/living/carbon/alien/organs.dm index 7db1bb103cc..46bd7bb04f9 100644 --- a/code/modules/mob/living/carbon/alien/organs.dm +++ b/code/modules/mob/living/carbon/alien/organs.dm @@ -103,7 +103,7 @@ . = ..() organ_owner.faction |= ROLE_ALIEN -/obj/item/organ/alien/hivenode/on_mob_remove(mob/living/carbon/organ_owner, special = FALSE) +/obj/item/organ/alien/hivenode/on_mob_remove(mob/living/carbon/organ_owner, special = FALSE, movement_flags) if(organ_owner) organ_owner.faction -= ROLE_ALIEN return ..() @@ -221,11 +221,11 @@ stomach_contents -= source UnregisterSignal(source, list(COMSIG_MOVABLE_MOVED, COMSIG_LIVING_DEATH, COMSIG_QDELETING)) -/obj/item/organ/stomach/alien/mob_insert(mob/living/carbon/stomach_owner, special, movement_flags) +/obj/item/organ/stomach/alien/on_mob_insert(mob/living/carbon/stomach_owner, special, movement_flags) RegisterSignal(stomach_owner, COMSIG_ATOM_RELAYMOVE, PROC_REF(something_moved)) return ..() -/obj/item/organ/stomach/alien/mob_remove(mob/living/carbon/stomach_owner, special, movement_flags) +/obj/item/organ/stomach/alien/on_mob_remove(mob/living/carbon/stomach_owner, special, movement_flags) UnregisterSignal(stomach_owner, COMSIG_ATOM_RELAYMOVE) return ..() diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm index b70139cee05..be65a9a1d3d 100644 --- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm +++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm @@ -78,7 +78,7 @@ for(var/datum/surgery/operations as anything in owner.surgeries) if(operations.location != BODY_ZONE_CHEST) continue - if(!istype(operations.get_surgery_step(), /datum/surgery_step/manipulate_organs/internal)) + if(!ispath(operations.steps[operations.status], /datum/surgery_step/manipulate_organs/internal)) continue attempt_grow(gib_on_success = FALSE) return diff --git a/code/modules/mob/living/carbon/human/dummy.dm b/code/modules/mob/living/carbon/human/dummy.dm index 9970d973a7d..8e078f9fb80 100644 --- a/code/modules/mob/living/carbon/human/dummy.dm +++ b/code/modules/mob/living/carbon/human/dummy.dm @@ -119,6 +119,7 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy) target.dna.features["tail_lizard"] = get_consistent_feature_entry(SSaccessories.tails_list_lizard) target.dna.features["tail_monkey"] = get_consistent_feature_entry(SSaccessories.tails_list_monkey) target.dna.features["pod_hair"] = get_consistent_feature_entry(SSaccessories.pod_hair_list) + target.dna.features["caps"] = get_consistent_feature_entry(SSaccessories.caps_list) target.dna.initialize_dna(create_mutation_blocks = FALSE, randomize_features = FALSE) // UF and UI are nondeterministic, even though the features are the same some blocks will randomize slightly // In practice this doesn't matter, but this is for the sake of 100%(ish) consistency diff --git a/code/modules/mod/modules/modules_medical.dm b/code/modules/mod/modules/modules_medical.dm index 7c0e1c85b05..7c4650ff81a 100644 --- a/code/modules/mod/modules/modules_medical.dm +++ b/code/modules/mod/modules/modules_medical.dm @@ -200,13 +200,10 @@ var/mob/living/carbon/human/organ_receiver = target var/succeed = FALSE if(organ_receiver.surgeries.len) - for(var/datum/surgery/procedure as anything in organ_receiver.surgeries) + for(var/datum/surgery/organ_manipulation/procedure in organ_receiver.surgeries) if(procedure.location != organ.zone) continue - if(!istype(procedure, /datum/surgery/organ_manipulation)) - continue - var/datum/surgery_step/surgery_step = procedure.get_surgery_step() - if(!istype(surgery_step, /datum/surgery_step/manipulate_organs)) + if(!ispath(procedure.steps[procedure.status], /datum/surgery_step/manipulate_organs)) continue succeed = TRUE break diff --git a/code/modules/surgery/organ_manipulation.dm b/code/modules/surgery/organ_manipulation.dm index a5f4a0505f6..5e6b4bb4b51 100644 --- a/code/modules/surgery/organ_manipulation.dm +++ b/code/modules/surgery/organ_manipulation.dm @@ -12,6 +12,38 @@ /datum/surgery_step/close, ) +//So far, this surgery type should be the only way carbon mobs can be fishing spots, also because the comp doesn't allow dupes. +/datum/surgery/organ_manipulation/next_step(mob/living/user, modifiers) + . = ..() + if(!.) + return + if(!ispath(steps[status], /datum/surgery_step/manipulate_organs)) + //The manipulate_organs step either hasn't been reached yet or we're already past it. + if(!HAS_TRAIT(target, TRAIT_FISHING_SPOT)) + return + remove_fishing_spot() + return + + if(HAS_TRAIT(target, TRAIT_FISHING_SPOT)) + return + target.AddComponent(/datum/component/fishing_spot, /datum/fish_source/surgery) + +/datum/surgery/organ_manipulation/Destroy() + if(HAS_TRAIT(target, TRAIT_FISHING_SPOT) && ispath(steps[status], /datum/surgery_step/manipulate_organs)) + remove_fishing_spot() + return ..() + +/** + * The target is a fishing spot, but we're past the step that allows us to fish organs from him, so we need + * to check if there are other organ manipulation surgeries that still meet this criteria before we remove + * the component + */ +/datum/surgery/organ_manipulation/proc/remove_fishing_spot() + for(var/datum/surgery/organ_manipulation/manipulation in target.surgeries) + if(ispath(manipulation.steps[manipulation.status], /datum/surgery_step/manipulate_organs)) + return + qdel(target.GetComponent(/datum/component/fishing_spot)) + /datum/surgery/organ_manipulation/soft possible_locs = list(BODY_ZONE_PRECISE_GROIN, BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM) steps = list( @@ -57,7 +89,7 @@ /datum/surgery/organ_manipulation/mechanic name = "Hardware Manipulation" requires_bodypart_type = BODYTYPE_ROBOTIC - surgery_flags = SURGERY_SELF_OPERABLE | SURGERY_REQUIRE_LIMB + surgery_flags = SURGERY_SELF_OPERABLE | SURGERY_REQUIRE_LIMB | SURGERY_CHECK_TOOL_BEHAVIOUR possible_locs = list(BODY_ZONE_CHEST, BODY_ZONE_HEAD) steps = list( /datum/surgery_step/mechanic_open, @@ -69,32 +101,6 @@ /datum/surgery_step/mechanic_close, ) -/datum/surgery/organ_manipulation/mechanic/next_step(mob/living/user, modifiers) - if(location != user.zone_selected) - return FALSE - if(user.combat_mode) - return FALSE - if(step_in_progress) - return TRUE - - var/try_to_fail = FALSE - if(LAZYACCESS(modifiers, RIGHT_CLICK)) - try_to_fail = TRUE - - var/datum/surgery_step/step = get_surgery_step() - if(isnull(step)) - return FALSE - var/obj/item/tool = user.get_active_held_item() - if(tool) - tool = tool.get_proxy_attacker_for(target, user) - if(step.try_op(user, target, user.zone_selected, tool, src, try_to_fail)) - return TRUE - if(tool && tool.tool_behaviour) //Mechanic organ manipulation isn't done with just surgery tools - to_chat(user, span_warning("This step requires a different tool!")) - return TRUE - - return FALSE - /datum/surgery/organ_manipulation/mechanic/soft possible_locs = list( BODY_ZONE_PRECISE_GROIN, @@ -176,7 +182,7 @@ to_chat(user, span_warning("[target_organ] seems to have been chewed on, you can't use this!")) return SURGERY_STEP_FAIL - if(!can_use_organ(user, meatslab)) + if(!can_use_organ(meatslab)) return SURGERY_STEP_FAIL if (target_zone == BODY_ZONE_PRECISE_EYES) @@ -196,7 +202,7 @@ var/list/unfiltered_organs = target.get_organs_for_zone(target_zone) var/list/organs = list() for(var/organ in unfiltered_organs) - if(can_use_organ(user, organ)) + if(can_use_organ(organ)) organs.Add(organ) if (target_zone == BODY_ZONE_PRECISE_EYES) target_zone = check_zone(target_zone) @@ -295,7 +301,7 @@ return ..() ///You can never use this MUHAHAHAHAHAHAH (because its the byond version of abstract) -/datum/surgery_step/manipulate_organs/proc/can_use_organ(mob/user, obj/item/organ/organ) +/datum/surgery_step/manipulate_organs/proc/can_use_organ(obj/item/organ/organ) return FALSE ///Surgery step for internal organs, like hearts and brains @@ -304,7 +310,7 @@ name = "manipulate organs (hemostat/organ)" ///only operate on internal organs -/datum/surgery_step/manipulate_organs/internal/can_use_organ(mob/user, obj/item/organ/organ) +/datum/surgery_step/manipulate_organs/internal/can_use_organ(obj/item/organ/organ) return !(organ.organ_flags & ORGAN_EXTERNAL) ///prosthetic surgery gives full effectiveness to crowbars (and hemostats) @@ -318,7 +324,7 @@ name = "manipulate features (hemostat/feature)" ///Only operate on external organs -/datum/surgery_step/manipulate_organs/external/can_use_organ(mob/user, obj/item/organ/organ) +/datum/surgery_step/manipulate_organs/external/can_use_organ(obj/item/organ/organ) return (organ.organ_flags & ORGAN_EXTERNAL) ///prosthetic surgery gives full effectiveness to crowbars (and hemostats) diff --git a/code/modules/surgery/organs/_organ.dm b/code/modules/surgery/organs/_organ.dm index e2f05a9ed56..b8784dfdea0 100644 --- a/code/modules/surgery/organs/_organ.dm +++ b/code/modules/surgery/organs/_organ.dm @@ -126,10 +126,6 @@ INITIALIZE_IMMEDIATE(/obj/item/organ) return owner.remove_status_effect(status, type) -/obj/item/organ/proc/on_owner_examine(datum/source, mob/user, list/examine_list) - SIGNAL_HANDLER - return - /obj/item/organ/proc/on_find(mob/living/finder) return diff --git a/code/modules/surgery/organs/external/_visual_organs.dm b/code/modules/surgery/organs/external/_visual_organs.dm index 0b01a174d09..26b089333b2 100644 --- a/code/modules/surgery/organs/external/_visual_organs.dm +++ b/code/modules/surgery/organs/external/_visual_organs.dm @@ -212,13 +212,13 @@ Unlike normal organs, we're actually inside a persons limbs at all times ///Store our old datum here for if our antennae are healed var/original_sprite_datum -/obj/item/organ/antennae/mob_insert(mob/living/carbon/receiver, special, movement_flags) +/obj/item/organ/antennae/on_mob_insert(mob/living/carbon/receiver, special, movement_flags) . = ..() RegisterSignal(receiver, COMSIG_HUMAN_BURNING, PROC_REF(try_burn_antennae)) RegisterSignal(receiver, COMSIG_LIVING_POST_FULLY_HEAL, PROC_REF(heal_antennae)) -/obj/item/organ/antennae/mob_remove(mob/living/carbon/organ_owner, special, movement_flags) +/obj/item/organ/antennae/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) . = ..() UnregisterSignal(organ_owner, list(COMSIG_HUMAN_BURNING, COMSIG_LIVING_POST_FULLY_HEAL)) diff --git a/code/modules/surgery/organs/external/spines.dm b/code/modules/surgery/organs/external/spines.dm index 23c29358a0d..77e0f63e6b0 100644 --- a/code/modules/surgery/organs/external/spines.dm +++ b/code/modules/surgery/organs/external/spines.dm @@ -16,13 +16,13 @@ organ_flags = parent_type::organ_flags | ORGAN_EXTERNAL -/obj/item/organ/spines/mob_insert(mob/living/carbon/receiver, special, movement_flags) +/obj/item/organ/spines/on_mob_insert(mob/living/carbon/receiver, special, movement_flags) // If we have a tail, attempt to add a tail spines overlay var/obj/item/organ/tail/our_tail = receiver.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL) our_tail?.try_insert_tail_spines(our_tail.bodypart_owner) return ..() -/obj/item/organ/spines/mob_remove(mob/living/carbon/organ_owner, special, movement_flags) +/obj/item/organ/spines/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) // If we have a tail, remove any tail spines overlay var/obj/item/organ/tail/our_tail = organ_owner.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL) our_tail?.remove_tail_spines(our_tail.bodypart_owner) diff --git a/code/modules/surgery/organs/external/tails.dm b/code/modules/surgery/organs/external/tails.dm index 8004f88a680..e6c382387a2 100644 --- a/code/modules/surgery/organs/external/tails.dm +++ b/code/modules/surgery/organs/external/tails.dm @@ -22,11 +22,10 @@ ///The overlay for tail spines, if any var/datum/bodypart_overlay/mutant/tail_spines/tail_spines_overlay -/obj/item/organ/tail/mob_insert(mob/living/carbon/receiver, special, movement_flags) +/obj/item/organ/tail/on_mob_insert(mob/living/carbon/receiver, special, movement_flags) . = ..() - if(.) - receiver.clear_mood_event("tail_lost") - receiver.clear_mood_event("tail_balance_lost") + receiver.clear_mood_event("tail_lost") + receiver.clear_mood_event("tail_balance_lost") if(!special) // if some admin wants to give someone tail moodles for tail shenanigans, they can spawn it and do it by hand original_owner ||= WEAKREF(receiver) @@ -77,7 +76,7 @@ bodypart.remove_bodypart_overlay(tail_spines_overlay) QDEL_NULL(tail_spines_overlay) -/obj/item/organ/tail/on_mob_remove(mob/living/carbon/organ_owner, special) +/obj/item/organ/tail/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) . = ..() if(wag_flags & WAG_WAGGING) diff --git a/code/modules/surgery/organs/external/wings/functional_wings.dm b/code/modules/surgery/organs/external/wings/functional_wings.dm index f773630f8bf..77589445834 100644 --- a/code/modules/surgery/organs/external/wings/functional_wings.dm +++ b/code/modules/surgery/organs/external/wings/functional_wings.dm @@ -33,14 +33,14 @@ QDEL_NULL(fly) return ..() -/obj/item/organ/wings/functional/mob_insert(mob/living/carbon/receiver, special, movement_flags) +/obj/item/organ/wings/functional/on_mob_insert(mob/living/carbon/receiver, special, movement_flags) . = ..() if(QDELETED(fly)) fly = new fly.Grant(receiver) -/obj/item/organ/wings/functional/mob_remove(mob/living/carbon/organ_owner, special, movement_flags) +/obj/item/organ/wings/functional/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) . = ..() fly?.Remove(organ_owner) if(wings_open) diff --git a/code/modules/surgery/organs/internal/_internal_organ.dm b/code/modules/surgery/organs/internal/_internal_organ.dm index 0527e6d7980..20b9f8f90f1 100644 --- a/code/modules/surgery/organs/internal/_internal_organ.dm +++ b/code/modules/surgery/organs/internal/_internal_organ.dm @@ -14,7 +14,7 @@ STOP_PROCESSING(SSobj, src) -/obj/item/organ/on_mob_remove(mob/living/carbon/organ_owner, special = FALSE) +/obj/item/organ/on_mob_remove(mob/living/carbon/organ_owner, special = FALSE, movement_flags) . = ..() if((organ_flags & ORGAN_VITAL) && !special && !HAS_TRAIT(organ_owner, TRAIT_GODMODE)) diff --git a/code/modules/surgery/organs/internal/cyberimp/augments_chest.dm b/code/modules/surgery/organs/internal/cyberimp/augments_chest.dm index 6a1e4272cd5..8b77ef5ec78 100644 --- a/code/modules/surgery/organs/internal/cyberimp/augments_chest.dm +++ b/code/modules/surgery/organs/internal/cyberimp/augments_chest.dm @@ -292,7 +292,7 @@ organ_owner.AddElement(/datum/element/forced_gravity, 1) add_organ_trait(TRAIT_STURDY_FRAME) -/obj/item/organ/cyberimp/chest/spine/on_mob_remove(mob/living/carbon/organ_owner, special) +/obj/item/organ/cyberimp/chest/spine/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) . = ..() remove_organ_trait(TRAIT_BOULDER_BREAKER) if(stone_overlay) diff --git a/code/modules/surgery/organs/internal/cyberimp/augments_eyes.dm b/code/modules/surgery/organs/internal/cyberimp/augments_eyes.dm index d720953a24c..204247e4de8 100644 --- a/code/modules/surgery/organs/internal/cyberimp/augments_eyes.dm +++ b/code/modules/surgery/organs/internal/cyberimp/augments_eyes.dm @@ -27,13 +27,13 @@ eye_owner.remove_traits(HUD_traits, ORGAN_TRAIT) balloon_alert(eye_owner, "hud enabled") -/obj/item/organ/cyberimp/eyes/hud/mob_insert(mob/living/carbon/eye_owner, special = FALSE, movement_flags) +/obj/item/organ/cyberimp/eyes/hud/on_mob_insert(mob/living/carbon/eye_owner, special = FALSE, movement_flags) . = ..() eye_owner.add_traits(HUD_traits, ORGAN_TRAIT) toggled_on = TRUE -/obj/item/organ/cyberimp/eyes/hud/mob_remove(mob/living/carbon/eye_owner, special, movement_flags) +/obj/item/organ/cyberimp/eyes/hud/on_mob_remove(mob/living/carbon/eye_owner, special, movement_flags) . = ..() eye_owner.remove_traits(HUD_traits, ORGAN_TRAIT) toggled_on = FALSE diff --git a/code/modules/surgery/organs/internal/ears/_ears.dm b/code/modules/surgery/organs/internal/ears/_ears.dm index 850d45df016..3443cf9249e 100644 --- a/code/modules/surgery/organs/internal/ears/_ears.dm +++ b/code/modules/surgery/organs/internal/ears/_ears.dm @@ -52,7 +52,7 @@ . = ..() update_temp_deafness() -/obj/item/organ/ears/on_mob_remove(mob/living/carbon/organ_owner, special) +/obj/item/organ/ears/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) . = ..() UnregisterSignal(organ_owner, COMSIG_MOB_SAY) REMOVE_TRAIT(organ_owner, TRAIT_DEAF, EAR_DAMAGE) diff --git a/code/modules/surgery/organs/internal/eyes/_eyes.dm b/code/modules/surgery/organs/internal/eyes/_eyes.dm index d7acaa496da..34ce46bc88b 100644 --- a/code/modules/surgery/organs/internal/eyes/_eyes.dm +++ b/code/modules/surgery/organs/internal/eyes/_eyes.dm @@ -50,12 +50,14 @@ /// Scarring on this organ var/scarring = NONE -/obj/item/organ/eyes/mob_insert(mob/living/carbon/receiver, special, movement_flags) +/obj/item/organ/eyes/on_mob_insert(mob/living/carbon/receiver, special, movement_flags) . = ..() receiver.cure_blind(NO_EYES) apply_damaged_eye_effects() refresh(receiver, call_update = TRUE) RegisterSignal(receiver, COMSIG_ATOM_BULLET_ACT, PROC_REF(on_bullet_act)) + if (scarring) + apply_scarring_effects() /// Refreshes the visuals of the eyes /// If call_update is TRUE, we also will call update_body @@ -80,7 +82,7 @@ if(call_update) affected_human.update_body() -/obj/item/organ/eyes/mob_remove(mob/living/carbon/organ_owner, special, movement_flags) +/obj/item/organ/eyes/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) . = ..() if(ishuman(organ_owner)) @@ -260,11 +262,6 @@ owner.cure_blind(EYE_SCARRING_TRAIT) owner.update_body() -/obj/item/organ/eyes/on_mob_insert(mob/living/carbon/eye_owner) - . = ..() - if (scarring) - apply_scarring_effects() - /obj/item/organ/eyes/on_mob_remove(mob/living/carbon/eye_owner) . = ..() if (scarring) @@ -550,14 +547,11 @@ deactivate(close_ui = TRUE) /// Set the initial color of the eyes on insert to be the mob's previous eye color. -/obj/item/organ/eyes/robotic/glow/mob_insert(mob/living/carbon/eye_recipient, special = FALSE, movement_flags = DELETE_IF_REPLACED) +/obj/item/organ/eyes/robotic/glow/on_mob_insert(mob/living/carbon/eye_recipient, special = FALSE, movement_flags) . = ..() left_eye_color_string = eye_color_left right_eye_color_string = eye_color_right update_mob_eye_color(eye_recipient) - -/obj/item/organ/eyes/robotic/glow/on_mob_insert(mob/living/carbon/eye_recipient) - . = ..() deactivate(close_ui = TRUE) eye.forceMove(eye_recipient) @@ -860,6 +854,6 @@ apply_organ_damage(-10) //heal quickly . = ..() -/obj/item/organ/eyes/night_vision/maintenance_adapted/on_mob_remove(mob/living/carbon/unadapted, special = FALSE) +/obj/item/organ/eyes/night_vision/maintenance_adapted/on_mob_remove(mob/living/carbon/unadapted, special = FALSE, movement_flags) REMOVE_TRAIT(unadapted, TRAIT_UNNATURAL_RED_GLOWY_EYES, ORGAN_TRAIT) return ..() diff --git a/code/modules/surgery/organs/internal/heart/_heart.dm b/code/modules/surgery/organs/internal/heart/_heart.dm index 20ad378529f..c1ebed9afbf 100644 --- a/code/modules/surgery/organs/internal/heart/_heart.dm +++ b/code/modules/surgery/organs/internal/heart/_heart.dm @@ -163,7 +163,7 @@ accursed.AddComponent(/datum/component/manual_heart, pump_delay = pump_delay, blood_loss = blood_loss, heal_brute = heal_brute, heal_burn = heal_burn, heal_oxy = heal_oxy) -/obj/item/organ/heart/cursed/on_mob_remove(mob/living/carbon/accursed, special = FALSE) +/obj/item/organ/heart/cursed/on_mob_remove(mob/living/carbon/accursed, special = FALSE, movement_flags) . = ..() qdel(accursed.GetComponent(/datum/component/manual_heart)) @@ -247,7 +247,7 @@ addtimer(VARSET_CALLBACK(src, stabilization_available, TRUE), 5 MINUTES, TIMER_DELETE_ME) // Largely a sanity check -/obj/item/organ/heart/cybernetic/on_mob_remove(mob/living/carbon/heart_owner, special = FALSE) +/obj/item/organ/heart/cybernetic/on_mob_remove(mob/living/carbon/heart_owner, special = FALSE, movement_flags) . = ..() if(HAS_TRAIT_FROM(heart_owner, TRAIT_NOSOFTCRIT, ORGAN_TRAIT)) REMOVE_TRAIT(heart_owner, TRAIT_NOSOFTCRIT, ORGAN_TRAIT) diff --git a/code/modules/surgery/organs/internal/heart/heart_anomalock.dm b/code/modules/surgery/organs/internal/heart/heart_anomalock.dm index df60b8243ef..19f0aef7a52 100644 --- a/code/modules/surgery/organs/internal/heart/heart_anomalock.dm +++ b/code/modules/surgery/organs/internal/heart/heart_anomalock.dm @@ -28,6 +28,10 @@ ///If the core is removable once socketed. var/core_removable = TRUE +/obj/item/organ/heart/cybernetic/anomalock/Destroy() + QDEL_NULL(core) + return ..() + /obj/item/organ/heart/cybernetic/anomalock/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags) . = ..() if(!core) @@ -39,7 +43,7 @@ RegisterSignal(organ_owner, SIGNAL_ADDTRAIT(TRAIT_CRITICAL_CONDITION), PROC_REF(activate_survival)) RegisterSignal(organ_owner, COMSIG_ATOM_EMP_ACT, PROC_REF(on_emp_act)) -/obj/item/organ/heart/cybernetic/anomalock/on_mob_remove(mob/living/carbon/organ_owner, special) +/obj/item/organ/heart/cybernetic/anomalock/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) . = ..() if(!core) return diff --git a/code/modules/surgery/organs/internal/heart/heart_ethereal.dm b/code/modules/surgery/organs/internal/heart/heart_ethereal.dm index 5c6602834cb..0e34fc581c3 100644 --- a/code/modules/surgery/organs/internal/heart/heart_ethereal.dm +++ b/code/modules/surgery/organs/internal/heart/heart_ethereal.dm @@ -21,14 +21,14 @@ add_atom_colour(ethereal_color, FIXED_COLOUR_PRIORITY) update_appearance() -/obj/item/organ/heart/ethereal/mob_insert(mob/living/carbon/heart_owner, special = FALSE, movement_flags) +/obj/item/organ/heart/ethereal/on_mob_insert(mob/living/carbon/heart_owner, special = FALSE, movement_flags) . = ..() RegisterSignal(heart_owner, COMSIG_MOB_STATCHANGE, PROC_REF(on_stat_change)) RegisterSignal(heart_owner, COMSIG_LIVING_POST_FULLY_HEAL, PROC_REF(on_owner_fully_heal)) RegisterSignal(heart_owner, COMSIG_QDELETING, PROC_REF(owner_deleted)) -/obj/item/organ/heart/ethereal/mob_remove(mob/living/carbon/heart_owner, special, movement_flags) +/obj/item/organ/heart/ethereal/on_mob_remove(mob/living/carbon/heart_owner, special, movement_flags) UnregisterSignal(heart_owner, list(COMSIG_MOB_STATCHANGE, COMSIG_LIVING_POST_FULLY_HEAL, COMSIG_QDELETING)) REMOVE_TRAIT(heart_owner, TRAIT_CORPSELOCKED, SPECIES_TRAIT) stop_crystalization_process(heart_owner) diff --git a/code/modules/surgery/organs/internal/liver/_liver.dm b/code/modules/surgery/organs/internal/liver/_liver.dm index 866813d02aa..e3d6d517044 100755 --- a/code/modules/surgery/organs/internal/liver/_liver.dm +++ b/code/modules/surgery/organs/internal/liver/_liver.dm @@ -60,14 +60,15 @@ qdel(GetComponent(/datum/component/squeak)) /// Registers COMSIG_SPECIES_HANDLE_CHEMICAL from owner -/obj/item/organ/liver/on_mob_insert(mob/living/carbon/organ_owner, special) +/obj/item/organ/liver/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags) . = ..() RegisterSignal(organ_owner, COMSIG_SPECIES_HANDLE_CHEMICAL, PROC_REF(handle_chemical)) + RegisterSignal(organ_owner, COMSIG_ATOM_EXAMINE, PROC_REF(on_owner_examine)) /// Unregisters COMSIG_SPECIES_HANDLE_CHEMICAL from owner -/obj/item/organ/liver/on_mob_remove(mob/living/carbon/organ_owner, special) +/obj/item/organ/liver/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) . = ..() - UnregisterSignal(organ_owner, COMSIG_SPECIES_HANDLE_CHEMICAL) + UnregisterSignal(organ_owner, list(COMSIG_SPECIES_HANDLE_CHEMICAL, COMSIG_ATOM_EXAMINE)) /** * This proc can be overriden by liver subtypes so they can handle certain chemicals in special ways. @@ -188,7 +189,7 @@ if(SPT_PROB(3, seconds_per_tick)) owner.emote("drool") -/obj/item/organ/liver/on_owner_examine(datum/source, mob/user, list/examine_list) +/obj/item/organ/liver/proc/on_owner_examine(datum/source, mob/user, list/examine_list) if(!ishuman(owner) || !(organ_flags & ORGAN_FAILING)) return diff --git a/code/modules/surgery/organs/internal/lungs/_lungs.dm b/code/modules/surgery/organs/internal/lungs/_lungs.dm index 53535cfe131..2a604c46cbc 100644 --- a/code/modules/surgery/organs/internal/lungs/_lungs.dm +++ b/code/modules/surgery/organs/internal/lungs/_lungs.dm @@ -154,7 +154,7 @@ add_gas_reaction(/datum/gas/zauker, while_present = PROC_REF(too_much_zauker)) ///Simply exists so that you don't keep any alerts from your previous lack of lungs. -/obj/item/organ/lungs/mob_insert(mob/living/carbon/receiver, special = FALSE, movement_flags) +/obj/item/organ/lungs/on_mob_insert(mob/living/carbon/receiver, special = FALSE, movement_flags) . = ..() receiver.clear_alert(ALERT_NOT_ENOUGH_OXYGEN) @@ -163,7 +163,7 @@ receiver.clear_alert(ALERT_NOT_ENOUGH_PLASMA) receiver.clear_alert(ALERT_NOT_ENOUGH_N2O) -/obj/item/organ/lungs/mob_remove(mob/living/carbon/organ_owner, special, movement_flags) +/obj/item/organ/lungs/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) . = ..() // This is very "manual" I realize, but it's useful to ensure cleanup for gases we're removing happens // Avoids stuck alerts and such diff --git a/code/modules/surgery/organs/internal/stomach/_stomach.dm b/code/modules/surgery/organs/internal/stomach/_stomach.dm index 768f3483c03..40d3265684d 100644 --- a/code/modules/surgery/organs/internal/stomach/_stomach.dm +++ b/code/modules/surgery/organs/internal/stomach/_stomach.dm @@ -246,13 +246,13 @@ disgusted.throw_alert(ALERT_DISGUST, /atom/movable/screen/alert/disgusted) disgusted.add_mood_event("disgust", /datum/mood_event/disgusted) -/obj/item/organ/stomach/mob_insert(mob/living/carbon/receiver, special, movement_flags) +/obj/item/organ/stomach/on_mob_insert(mob/living/carbon/receiver, special, movement_flags) . = ..() receiver.hud_used?.hunger?.update_appearance() -/obj/item/organ/stomach/mob_remove(mob/living/carbon/stomach_owner, special, movement_flags) +/obj/item/organ/stomach/on_mob_remove(mob/living/carbon/stomach_owner, special, movement_flags) if(ishuman(stomach_owner)) - var/mob/living/carbon/human/human_owner = owner + var/mob/living/carbon/human/human_owner = stomach_owner human_owner.clear_alert(ALERT_DISGUST) human_owner.clear_mood_event("disgust") stomach_owner.hud_used?.hunger?.update_appearance() diff --git a/code/modules/surgery/organs/internal/stomach/stomach_golem.dm b/code/modules/surgery/organs/internal/stomach/stomach_golem.dm index c4fa888f6cb..dc6f28787aa 100644 --- a/code/modules/surgery/organs/internal/stomach/stomach_golem.dm +++ b/code/modules/surgery/organs/internal/stomach/stomach_golem.dm @@ -11,11 +11,11 @@ /// How slow are you if you have absolutely nothing in the tank? var/max_hunger_slowdown = 4 -/obj/item/organ/stomach/golem/on_mob_insert(mob/living/carbon/organ_owner, special) +/obj/item/organ/stomach/golem/on_mob_insert(mob/living/carbon/organ_owner, special, movement_flags) . = ..() RegisterSignal(owner, COMSIG_CARBON_ATTEMPT_EAT, PROC_REF(try_eating)) -/obj/item/organ/stomach/golem/on_mob_remove(mob/living/carbon/organ_owner, special) +/obj/item/organ/stomach/golem/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) . = ..() UnregisterSignal(organ_owner, COMSIG_CARBON_ATTEMPT_EAT) organ_owner.remove_movespeed_modifier(/datum/movespeed_modifier/golem_hunger) diff --git a/code/modules/surgery/organs/internal/tongue/_tongue.dm b/code/modules/surgery/organs/internal/tongue/_tongue.dm index b94d434a186..dda3530e6b4 100644 --- a/code/modules/surgery/organs/internal/tongue/_tongue.dm +++ b/code/modules/surgery/organs/internal/tongue/_tongue.dm @@ -124,7 +124,7 @@ food_taste_reaction = FOOD_LIKED return food_taste_reaction -/obj/item/organ/tongue/mob_insert(mob/living/carbon/receiver, special, movement_flags) +/obj/item/organ/tongue/on_mob_insert(mob/living/carbon/receiver, special, movement_flags) . = ..() if(modifies_speech) @@ -138,7 +138,7 @@ REMOVE_TRAIT(receiver, TRAIT_AGEUSIA, NO_TONGUE_TRAIT) apply_tongue_effects() -/obj/item/organ/tongue/mob_remove(mob/living/carbon/organ_owner, special, movement_flags) +/obj/item/organ/tongue/on_mob_remove(mob/living/carbon/organ_owner, special, movement_flags) . = ..() temp_say_mod = "" diff --git a/code/modules/surgery/organs/organ_movement.dm b/code/modules/surgery/organs/organ_movement.dm index 5d9e9b36f46..fa76c8180cd 100644 --- a/code/modules/surgery/organs/organ_movement.dm +++ b/code/modules/surgery/organs/organ_movement.dm @@ -15,12 +15,15 @@ /obj/item/organ/proc/Insert(mob/living/carbon/receiver, special = FALSE, movement_flags) SHOULD_CALL_PARENT(TRUE) - mob_insert(receiver, special, movement_flags) + if(!mob_insert(receiver, special, movement_flags)) + return FALSE bodypart_insert(limb_owner = receiver, movement_flags = movement_flags) if(!special && !(receiver.living_flags & STOP_OVERLAY_UPDATE_BODY_PARTS)) receiver.update_body_parts() + return TRUE + /* * Remove the organ from the select mob. * @@ -44,15 +47,17 @@ * movement_flags - Flags for how we behave in movement. See DEFINES/organ_movement for flags */ /obj/item/organ/proc/mob_insert(mob/living/carbon/receiver, special, movement_flags) - SHOULD_CALL_PARENT(TRUE) + SHOULD_NOT_OVERRIDE(TRUE) if(!iscarbon(receiver)) - stack_trace("Tried to insert organ into non-carbon: [receiver.type]") - return + //We try to insert the organ in a corgi when running the test, expecting it to return FALSE. + if(!PERFORM_ALL_TESTS(organ_sanity)) + stack_trace("Tried to insert organ into non-carbon: [receiver.type]") + return FALSE if(owner == receiver) stack_trace("Organ receiver is already organ owner") - return + return FALSE var/obj/item/organ/replaced = receiver.get_organ_slot(slot) if(replaced) @@ -78,7 +83,7 @@ receiver.organs_slot[slot] = src owner = receiver - on_mob_insert(receiver, special) + on_mob_insert(receiver, special, movement_flags) return TRUE @@ -99,7 +104,6 @@ if(!special) organ_owner.hud_used?.update_locked_slots() - RegisterSignal(owner, COMSIG_ATOM_EXAMINE, PROC_REF(on_owner_examine)) SEND_SIGNAL(src, COMSIG_ORGAN_IMPLANTED, organ_owner) SEND_SIGNAL(organ_owner, COMSIG_CARBON_GAIN_ORGAN, src, special) @@ -141,7 +145,7 @@ * * special - "quick swapping" an organ out - when TRUE, the mob will be unaffected by not having that organ for the moment */ /obj/item/organ/proc/mob_remove(mob/living/carbon/organ_owner, special = FALSE, movement_flags) - SHOULD_CALL_PARENT(TRUE) + SHOULD_NOT_OVERRIDE(TRUE) if(organ_owner) if(organ_owner.organs_slot[slot] == src) @@ -150,7 +154,7 @@ owner = null - on_mob_remove(organ_owner, special) + on_mob_remove(organ_owner, special, movement_flags) return TRUE @@ -172,7 +176,6 @@ for(var/datum/status_effect/effect as anything in organ_effects) organ_owner.remove_status_effect(effect, type) - UnregisterSignal(organ_owner, COMSIG_ATOM_EXAMINE) SEND_SIGNAL(src, COMSIG_ORGAN_REMOVED, organ_owner) SEND_SIGNAL(organ_owner, COMSIG_CARBON_LOSE_ORGAN, src, special) ADD_TRAIT(src, TRAIT_USED_ORGAN, ORGAN_TRAIT) diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index d23267fa326..8b869d3e20b 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -4,8 +4,7 @@ ///The description of the surgery, what it does. var/desc - ///From __DEFINES/surgery.dm - ///Selection: SURGERY_IGNORE_CLOTHES | SURGERY_SELF_OPERABLE | SURGERY_REQUIRE_RESTING | SURGERY_REQUIRE_LIMB | SURGERY_REQUIRES_REAL_LIMB | SURGERY_MORBID_CURIOSITY + ///Bitfield for flags that determine different behaviors and requirement for the surgery. See __DEFINES/surgery.dm var/surgery_flags = SURGERY_REQUIRE_RESTING | SURGERY_REQUIRE_LIMB ///The surgery step we're currently on, increases each time we do a step. var/status = 1 @@ -120,7 +119,7 @@ if(LAZYACCESS(modifiers, RIGHT_CLICK)) try_to_fail = TRUE - var/datum/surgery_step/step = get_surgery_step() + var/datum/surgery_step/step = GLOB.surgery_steps[steps[status]] if(isnull(step)) return FALSE var/obj/item/tool = user.get_active_held_item() @@ -128,16 +127,15 @@ tool = tool.get_proxy_attacker_for(target, user) if(step.try_op(user, target, user.zone_selected, tool, src, try_to_fail)) return TRUE - if(tool && tool.item_flags & SURGICAL_TOOL) //Just because you used the wrong tool it doesn't mean you meant to whack the patient with it + if(!tool) + return FALSE + //Just because you used the wrong tool it doesn't mean you meant to whack the patient with it + if((surgery_flags & SURGERY_CHECK_TOOL_BEHAVIOUR) ? tool.tool_behaviour : (tool.item_flags & SURGICAL_TOOL)) to_chat(user, span_warning("This step requires a different tool!")) return TRUE return FALSE -/datum/surgery/proc/get_surgery_step() - var/step_type = steps[status] - return new step_type - /datum/surgery/proc/get_surgery_next_step() if(status < steps.len) var/step_type = steps[status + 1] diff --git a/code/modules/unit_tests/organs.dm b/code/modules/unit_tests/organs.dm index 8f05a284058..cf01436796d 100644 --- a/code/modules/unit_tests/organs.dm +++ b/code/modules/unit_tests/organs.dm @@ -10,22 +10,9 @@ var/static/list/species_changing_organs = typecacheof(list( /obj/item/organ/brain/shadow/nightmare, )) - // List of organ typepaths which are not test-able, such as certain class prototypes. - var/static/list/test_organ_blacklist = typecacheof(list( - /obj/item/organ, - /obj/item/organ, - /obj/item/organ/wings, - /obj/item/organ/cyberimp, - /obj/item/organ/cyberimp/brain, - /obj/item/organ/cyberimp/mouth, - /obj/item/organ/cyberimp/arm, - /obj/item/organ/cyberimp/chest, - /obj/item/organ/cyberimp/eyes, - /obj/item/organ/alien, - )) /datum/unit_test/organ_sanity/Run() - for(var/obj/item/organ/organ_type as anything in subtypesof(/obj/item/organ) - test_organ_blacklist) + for(var/obj/item/organ/organ_type as anything in subtypesof(/obj/item/organ) - GLOB.prototype_organs) organ_test_insert(organ_type) /datum/unit_test/organ_sanity/proc/organ_test_insert(obj/item/organ/organ_type) diff --git a/code/modules/wiremod/shell/brain_computer_interface.dm b/code/modules/wiremod/shell/brain_computer_interface.dm index 29147aefa94..b31f3ce151b 100644 --- a/code/modules/wiremod/shell/brain_computer_interface.dm +++ b/code/modules/wiremod/shell/brain_computer_interface.dm @@ -93,8 +93,6 @@ var/datum/port/output/user_port - var/datum/weakref/user - var/obj/item/organ/cyberimp/bci/bci /obj/item/circuit_component/bci_core/populate_ports() @@ -111,19 +109,18 @@ /obj/item/circuit_component/bci_core/proc/update_charge_action() CIRCUIT_TRIGGER - var/mob/living/carbon/resolved_owner = user?.resolve() if (show_charge_meter.value) if (charge_action) return charge_action = new(src) - if (resolved_owner) - charge_action.Grant(resolved_owner) + if (bci.owner) + charge_action.Grant(bci.owner) bci.actions += charge_action else if (!charge_action) return - if (resolved_owner) - charge_action.Remove(resolved_owner) + if (bci.owner) + charge_action.Remove(bci.owner) bci.actions -= charge_action QDEL_NULL(charge_action) @@ -139,9 +136,8 @@ bci = shell if (charge_action) - var/mob/living/carbon/resolved_owner = user?.resolve() - if (resolved_owner) - charge_action.Remove(resolved_owner) + if (bci.owner) + charge_action.Remove(bci.owner) bci.actions -= charge_action QDEL_NULL(charge_action) @@ -158,14 +154,13 @@ if (!sent_message) return - var/mob/living/carbon/resolved_owner = user?.resolve() - if (isnull(resolved_owner)) + if (isnull(bci.owner)) return - if (resolved_owner.stat == DEAD) + if (bci.owner.stat == DEAD) return - to_chat(resolved_owner, "You hear a strange, robotic voice in your head... \"[span_robot("[html_encode(sent_message)]")]\"") + to_chat(bci.owner, "You hear a strange, robotic voice in your head... \"[span_robot("[html_encode(sent_message)]")]\"") /obj/item/circuit_component/bci_core/proc/on_organ_implanted(datum/source, mob/living/carbon/owner) SIGNAL_HANDLER @@ -173,7 +168,6 @@ update_charge_action() user_port.set_output(owner) - user = WEAKREF(owner) RegisterSignal(owner, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) RegisterSignal(owner, COMSIG_PROCESS_BORGCHARGER_OCCUPANT, PROC_REF(on_borg_charge)) @@ -183,7 +177,6 @@ SIGNAL_HANDLER user_port.set_output(null) - user = null UnregisterSignal(owner, list( COMSIG_ATOM_EXAMINE, diff --git a/code/modules/zombie/organs.dm b/code/modules/zombie/organs.dm index f6f21b7e1ee..e524bdee5cb 100644 --- a/code/modules/zombie/organs.dm +++ b/code/modules/zombie/organs.dm @@ -23,26 +23,19 @@ GLOB.zombie_infection_list -= src . = ..() -/obj/item/organ/zombie_infection/on_mob_insert(mob/living/carbon/M, special = FALSE, movement_flags) +/obj/item/organ/zombie_infection/on_mob_insert(mob/living/carbon/new_owner, special = FALSE, movement_flags) . = ..() - + RegisterSignal(new_owner, COMSIG_LIVING_DEATH, PROC_REF(organ_owner_died)) START_PROCESSING(SSobj, src) -/obj/item/organ/zombie_infection/on_mob_remove(mob/living/carbon/M, special = FALSE) +/obj/item/organ/zombie_infection/on_mob_remove(mob/living/carbon/new_owner, special = FALSE, movement_flags) . = ..() STOP_PROCESSING(SSobj, src) - if(iszombie(M) && old_species && !special) - M.set_species(old_species) + if(iszombie(new_owner) && old_species && !special) + new_owner.set_species(old_species) if(timer_id) deltimer(timer_id) - -/obj/item/organ/zombie_infection/on_mob_insert(mob/living/carbon/organ_owner, special) - . = ..() - RegisterSignal(organ_owner, COMSIG_LIVING_DEATH, PROC_REF(organ_owner_died)) - -/obj/item/organ/zombie_infection/on_mob_remove(mob/living/carbon/organ_owner, special) - . = ..() - UnregisterSignal(organ_owner, COMSIG_LIVING_DEATH) + UnregisterSignal(new_owner, COMSIG_LIVING_DEATH) /obj/item/organ/zombie_infection/proc/organ_owner_died(mob/living/carbon/source, gibbed) SIGNAL_HANDLER diff --git a/icons/hud/fishing_hud.dmi b/icons/hud/fishing_hud.dmi index f9d2d2ff9c4..84f739f9db2 100644 Binary files a/icons/hud/fishing_hud.dmi and b/icons/hud/fishing_hud.dmi differ diff --git a/icons/hud/radial_fishing.dmi b/icons/hud/radial_fishing.dmi index 8b914f32613..daa4ce8abda 100644 Binary files a/icons/hud/radial_fishing.dmi and b/icons/hud/radial_fishing.dmi differ diff --git a/strings/fishing_tips.txt b/strings/fishing_tips.txt index af67d15e27e..836cab85da5 100644 --- a/strings/fishing_tips.txt +++ b/strings/fishing_tips.txt @@ -54,3 +54,4 @@ Fish can grow in size and weight if you fed them somewhat frequently. Giving the Feeding a fish mutagen can triple the probability of generating evolved offsprings, provided it has an evolution. You can print fishing rods of different materials from an autolathe, which can inrease or decrease fishing difficulty, casting range, experience gained and can have other, special effects. Albeit scarcely, it's possible to catch fish made of the same materials of a custom material fishing rod. Equipping a shiny fishing hook and the quality of the bait can improve your odds. +You can use a fishing rod to snatch random organs during the "manipulate organs" step of the "organ manipulation" surgery. \ No newline at end of file