From 13705da08d43c332f766b5f3c8177375d3201b4d Mon Sep 17 00:00:00 2001 From: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com> Date: Sat, 23 Nov 2024 13:27:02 +0200 Subject: [PATCH] fixes a few issues with the chipped quirk (#87764) ## About The Pull Request the text displayed when this quirk's gained would include the skillchip's typepath rather than its name. this fixes that. also fixes an issue with how the callback timer was being handled, which would lead to a runtime whenever the quirk was removed (since addtimer returns the id and not the callback itself). also fixes the scratch effect never actually working because an organ slot was being provided to `get_organ_by_type` rather than the type. also fixes the itchy effect not going away after the skillchip is removed (it gets added again if the skillchip is reimplanted). ## Why It's Good For The Game fixes a few issues with the chipped quirk ## Changelog :cl: fix: fixes the chipped quirk displaying the skill chip's typepath rather than its name fix: fixes chipped quirk's itchy effect not working fix: the chipped quirk's itchy effect now goes away when the skillchip is removed /:cl: --------- Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> --- code/__DEFINES/dcs/signals/signals_object.dm | 6 ++ code/datums/quirks/positive_quirks/chipped.dm | 70 +++++++++++++------ code/datums/status_effects/_status_effect.dm | 6 +- .../library/skill_learning/skillchip.dm | 4 +- 4 files changed, 62 insertions(+), 24 deletions(-) diff --git a/code/__DEFINES/dcs/signals/signals_object.dm b/code/__DEFINES/dcs/signals/signals_object.dm index 2b6c1b32206..8b5778602e0 100644 --- a/code/__DEFINES/dcs/signals/signals_object.dm +++ b/code/__DEFINES/dcs/signals/signals_object.dm @@ -539,3 +539,9 @@ #define COMSIG_ITEM_WEIGHT_CLASS_CHANGED "item_weight_class_changed" /// Sent from /obj/item/update_weight_class(), to its loc. (obj/item/changed_item, old_w_class, new_w_class) #define COMSIG_ATOM_CONTENTS_WEIGHT_CLASS_CHANGED "atom_contents_weight_class_changed" + +///Sent from /obj/item/skillchip/on_implant() +#define COMSIG_SKILLCHIP_IMPLANTED "skillchip_implanted" + +///Sent from /obj/item/skillchip/on_remove() +#define COMSIG_SKILLCHIP_REMOVED "skillchip_removed" diff --git a/code/datums/quirks/positive_quirks/chipped.dm b/code/datums/quirks/positive_quirks/chipped.dm index 7f43fc07b5b..474e8a4adcd 100644 --- a/code/datums/quirks/positive_quirks/chipped.dm +++ b/code/datums/quirks/positive_quirks/chipped.dm @@ -5,7 +5,7 @@ value = 2 gain_text = span_notice("The chip in your head itches a bit.") lose_text = span_danger("You don't feel so chipped anymore..") - medical_record_text = "Patient explained how they got caught up in 'the skillchip chase' recently, and now the chip in they head itches every so often. Dumbass." + medical_record_text = "Patient explained how they got caught up in 'the skillchip chase' recently, and now the chip in their head itches every so often. Dumbass." mail_goodies = list( /obj/item/skillchip/matrix_taunt, /obj/item/skillchip/big_pointer, @@ -14,44 +14,70 @@ ) /// Variable that holds the chip, used on removal. var/obj/item/skillchip/installed_chip - var/datum/callback/itchy_timer + ///itchy status effect we give our owner + var/datum/itchy_effect /datum/quirk_constant_data/chipped associated_typepath = /datum/quirk/chipped customization_options = list(/datum/preference/choiced/chipped) /datum/quirk/chipped/add_to_holder(mob/living/new_holder, quirk_transfer, client/client_source) - var/obj/item/skillchip/chip_pref = GLOB.quirk_chipped_choice[client_source?.prefs?.read_preference(/datum/preference/choiced/chipped)] + var/chip_pref = client_source?.prefs?.read_preference(/datum/preference/choiced/chipped) - if(!chip_pref) + if(isnull(chip_pref)) return ..() - - gain_text = span_notice("The [chip_pref] in your head itches a bit.") + installed_chip = GLOB.quirk_chipped_choice[chip_pref] || GLOB.quirk_chipped_choice[pick(GLOB.quirk_chipped_choice)] + gain_text = span_notice("The [installed_chip::name] in your head itches a bit.") lose_text = span_notice("Your head stops itching so much.") return ..() /datum/quirk/chipped/add_unique(client/client_source) - - var/preferred_chip = GLOB.quirk_chipped_choice[client_source?.prefs?.read_preference(/datum/preference/choiced/chipped)] - if(isnull(preferred_chip)) //Client is gone or they chose a random chip - preferred_chip = GLOB.quirk_chipped_choice[pick(GLOB.quirk_chipped_choice)] + if(!iscarbon(quirk_holder)) + return var/mob/living/carbon/quirk_holder_carbon = quirk_holder - if(iscarbon(quirk_holder)) - installed_chip = new preferred_chip() - quirk_holder_carbon.implant_skillchip(installed_chip, force = TRUE) + installed_chip = new installed_chip() + + RegisterSignals(installed_chip, list(COMSIG_QDELETING, COMSIG_SKILLCHIP_REMOVED), PROC_REF(remove_effect)) + RegisterSignal(installed_chip, COMSIG_SKILLCHIP_IMPLANTED, PROC_REF(apply_effect)) + + quirk_holder_carbon.implant_skillchip(installed_chip, force = TRUE) installed_chip.try_activate_skillchip(silent = FALSE, force = TRUE) - var/obj/item/organ/brain/itchy_brain = quirk_holder.get_organ_by_type(ORGAN_SLOT_BRAIN) - itchy_timer = addtimer(CALLBACK(src, PROC_REF(cause_itchy), itchy_brain), rand(5 SECONDS, 10 MINUTES)) // they get The Itch from a poor quality install every so often +/datum/quirk/chipped/proc/apply_effect(datum/source, obj/item/brain_applied) + SIGNAL_HANDLER + var/mob/living/carbon/quirk_holder_carbon = quirk_holder + if(brain_applied == quirk_holder_carbon.get_organ_slot(ORGAN_SLOT_BRAIN)) + itchy_effect = quirk_holder.apply_status_effect(/datum/status_effect/itchy_skillchip_quirk) + +/datum/quirk/chipped/proc/remove_effect(datum/source, obj/item/brain_removed) + SIGNAL_HANDLER + var/mob/living/carbon/quirk_holder_carbon = quirk_holder + if(QDELING(source) || brain_removed == quirk_holder_carbon.get_organ_slot(ORGAN_SLOT_BRAIN)) + quirk_holder.remove_status_effect(itchy_effect) + itchy_effect = null /datum/quirk/chipped/remove() - qdel(installed_chip) - deltimer(itchy_timer) - . = ..() + QDEL_NULL(installed_chip) + if(itchy_effect) + quirk_holder.remove_status_effect(itchy_effect) + itchy_effect = null + return ..() -/datum/quirk/chipped/proc/cause_itchy(obj/item/organ/brain/itchy_brain) +/datum/status_effect/itchy_skillchip_quirk + id = "itchy skillchip" + tick_interval_lowerbound = 5 SECONDS + tick_interval_upperbound = 10 MINUTES + ///lower damage we apply to our itchy owner + var/minimum_damage = 1 + ///upper damage we apply to our itchy owner + var/maximum_damage = 5 - itchy_brain.apply_organ_damage(rand(1, 5), maximum = itchy_brain.maxHealth * 0.3) - to_chat(itchy_brain.owner, span_warning("Your [itchy_brain] itches.")) - itchy_timer = addtimer(CALLBACK(itchy_brain, PROC_REF(cause_itchy)), rand(5 SECONDS, 10 MINUTES)) // it will never end +/datum/status_effect/itchy_skillchip_quirk/tick(seconds_between_ticks) + var/mob/living/carbon/carbon_owner = owner + var/obj/item/organ/brain/itchy_brain = carbon_owner.get_organ_slot(ORGAN_SLOT_BRAIN) + if(isnull(itchy_brain)) + return + itchy_brain.apply_organ_damage(rand(minimum_damage, maximum_damage), maximum = itchy_brain.maxHealth * 0.3) + if(owner.stat == CONSCIOUS && !owner.incapacitated && owner.get_empty_held_indexes()) + to_chat(owner, span_warning("You scratch the itch in your head.")) diff --git a/code/datums/status_effects/_status_effect.dm b/code/datums/status_effects/_status_effect.dm index df525fa8c81..9f3e3a54904 100644 --- a/code/datums/status_effects/_status_effect.dm +++ b/code/datums/status_effects/_status_effect.dm @@ -12,6 +12,10 @@ /// While processing, this becomes the world.time when the next tick will occur. /// -1 = will prevent ticks, and if duration is also unlimited (-1), stop processing wholesale. var/tick_interval = 1 SECONDS + ///If our tick intervals are set to be a dynamic value within a range, the lowerbound of said range + var/tick_interval_lowerbound + ///If our tick intervals are set to be a dynamic value within a range, the upperbound of said range + var/tick_interval_upperbound /// The mob affected by the status effect. VAR_FINAL/mob/living/owner /// How many of the effect can be on one mob, and/or what happens when you try to add a duplicate. @@ -112,7 +116,7 @@ return if(tick_interval != STATUS_EFFECT_NO_TICK && tick_interval < world.time) - var/tick_length = initial(tick_interval) + var/tick_length = (tick_interval_upperbound && tick_interval_lowerbound) ? rand(tick_interval_lowerbound, tick_interval_upperbound) : initial(tick_interval) tick(tick_length / (1 SECONDS)) tick_interval = world.time + tick_length if(QDELING(src)) diff --git a/code/modules/library/skill_learning/skillchip.dm b/code/modules/library/skill_learning/skillchip.dm index 5ca3f784ecb..f534e391bcb 100644 --- a/code/modules/library/skill_learning/skillchip.dm +++ b/code/modules/library/skill_learning/skillchip.dm @@ -132,10 +132,12 @@ * * owner_brain - The brain that this skillchip was implanted in to. */ /obj/item/skillchip/proc/on_implant(obj/item/organ/brain/owner_brain) + SHOULD_CALL_PARENT(TRUE) if(holding_brain) CRASH("Skillchip is trying to be implanted into [owner_brain], but it's already implanted in [holding_brain]") holding_brain = owner_brain + SEND_SIGNAL(src, COMSIG_SKILLCHIP_IMPLANTED, holding_brain) /** * Called when a skillchip is activated. @@ -172,7 +174,7 @@ try_deactivate_skillchip(silent, TRUE) COOLDOWN_RESET(src, chip_cooldown) - + SEND_SIGNAL(src, COMSIG_SKILLCHIP_REMOVED, holding_brain) holding_brain = null /**