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)} /> + + + + + ); +};