From dbddc1f6e2c72c2e880013e09fc11e164e4b52ce Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Sun, 24 Apr 2022 03:27:53 +0200 Subject: [PATCH] [MIRROR] Makes the blood filter not suck so much [MDB IGNORE] (#13040) * Makes the blood filter not suck so much (#66325) Adds a whitelist to the blood filter, you can use it in hand to bring up a UI similar to the plumbing filters. When using the blood filter for surgery it will only filter out chems in the whitelist, unless the list is empty in which case it will filter all chems. Makes the surgery loop until all filterable chems are removed, similar to tend wounds. Holding a health analyzer in your off hand while using the blood filter will display a chem scan of the subject after each surgery step similar to tend wounds. * Makes the blood filter not suck so much Co-authored-by: GoblinBackwards <22856555+GoblinBackwards@users.noreply.github.com> --- code/modules/surgery/blood_filter.dm | 38 +++++++++++++++++++- code/modules/surgery/tools.dm | 37 +++++++++++++++++++ tgui/packages/tgui/interfaces/BloodFilter.js | 29 +++++++++++++++ 3 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 tgui/packages/tgui/interfaces/BloodFilter.js diff --git a/code/modules/surgery/blood_filter.dm b/code/modules/surgery/blood_filter.dm index 59eca843018..b52bed3186b 100644 --- a/code/modules/surgery/blood_filter.dm +++ b/code/modules/surgery/blood_filter.dm @@ -16,6 +16,36 @@ return FALSE return ..() +/datum/surgery_step/filter_blood/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE) + if(!..()) + return + while(has_filterable_chems(target, tool)) + if(!..()) + break + +/** + * Checks if the mob contains chems we can filter + * + * If the blood filter's whitelist is empty this checks if the mob contains any chems + * If the whitelist contains chems it checks if any chems in the mob match chems in the whitelist + * + * Arguments: + * * target - The mob to check the chems of + * * bloodfilter - The blood filter to check the whitelist of + */ +/datum/surgery_step/filter_blood/proc/has_filterable_chems(mob/living/carbon/target, obj/item/blood_filter/bloodfilter) + if(!length(target.reagents?.reagent_list)) + return FALSE + + if(!length(bloodfilter.whitelist)) + return TRUE + + for(var/datum/reagent/chem as anything in target.reagents.reagent_list) + if(chem.type in bloodfilter.whitelist) + return TRUE + + return FALSE + /datum/surgery_step/filter_blood name = "Filter blood" implements = list(/obj/item/blood_filter = 95) @@ -30,12 +60,18 @@ display_pain(target, "You feel a throbbing pain in your chest!") /datum/surgery_step/filter_blood/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) + var/obj/item/blood_filter/bloodfilter = tool if(target.reagents?.total_volume) for(var/datum/reagent/chem as anything in target.reagents.reagent_list) - target.reagents.remove_reagent(chem.type, min(chem.volume * 0.22, 10)) + if(!length(bloodfilter.whitelist) || (chem.type in bloodfilter.whitelist)) + target.reagents.remove_reagent(chem.type, min(chem.volume * 0.22, 10)) display_results(user, target, span_notice("\The [tool] pings as it finishes filtering [target]'s blood."), span_notice("\The [tool] pings as it stops pumping [target]'s blood."), "\The [tool] pings as it stops pumping.") + + if(locate(/obj/item/healthanalyzer) in user.held_items) + chemscan(user, target) + return ..() /datum/surgery_step/filter_blood/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index 8b9e41f8585..6831eadda5c 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -453,3 +453,40 @@ attack_verb_simple = list("pump", "siphon") tool_behaviour = TOOL_BLOODFILTER toolspeed = 1 + /// Assoc list of chem ids to names, used for deciding which chems to filter when used for surgery + var/list/whitelist = list() + +/obj/item/blood_filter/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "BloodFilter", name) + ui.open() + +/obj/item/blood_filter/ui_data(mob/user) + var/list/data = list() + var/list/chem_names = list() + for(var/key in whitelist) + chem_names += whitelist[key] + data["whitelist"] = chem_names + return data + +/obj/item/blood_filter/ui_act(action, params) + . = ..() + if(.) + return + . = TRUE + switch(action) + if("add") + var/new_chem_name = params["name"] + var/chem_id = get_chem_id(new_chem_name) + if(!chem_id || !new_chem_name) + to_chat(usr, span_warning("No such known reagent exists!")) + return + if(!(chem_id in whitelist)) + whitelist[chem_id] = new_chem_name + + + if("remove") + var/chem_name = params["reagent"] + var/chem_id = get_chem_id(chem_name) + whitelist -= chem_id diff --git a/tgui/packages/tgui/interfaces/BloodFilter.js b/tgui/packages/tgui/interfaces/BloodFilter.js new file mode 100644 index 00000000000..45a56eb68a8 --- /dev/null +++ b/tgui/packages/tgui/interfaces/BloodFilter.js @@ -0,0 +1,29 @@ +import { useBackend, useLocalState } from '../backend'; +import { Stack } from '../components'; +import { Window } from '../layouts'; +import { ChemFilterPane } from './ChemFilter'; + +export const BloodFilter = (props, context) => { + const { act, data } = useBackend(context); + const { + whitelist = [], + } = data; + const [chemName, setChemName] = useLocalState(context, 'chemName', ''); + return ( + + + + + setChemName(value)} /> + + + + + ); +};