diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm index 68515426c3..e71243994d 100644 --- a/code/__DEFINES/antagonists.dm +++ b/code/__DEFINES/antagonists.dm @@ -69,6 +69,9 @@ #define LINGBLOOD_EXPLOSION_THRESHOLD (LINGBLOOD_DETECTION_THRESHOLD * LINGBLOOD_EXPLOSION_MULT) //Hey, important to note here: the explosion threshold is explicitly more than, rather than more than or equal to. This stops a single loud ability from triggering the explosion threshold. ///Heretics -- +GLOBAL_LIST_EMPTY(living_heart_cache) //A list of all living hearts in existance, for us to iterate through. + + #define IS_HERETIC(mob) (mob.mind?.has_antag_datum(/datum/antagonist/heretic)) #define IS_HERETIC_MONSTER(mob) (mob.mind?.has_antag_datum(/datum/antagonist/heretic_monster)) diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index d8617e0b48..0ee07951a9 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -455,7 +455,7 @@ If not set, defaults to check_completion instead. Set it. It's used by cryo. var/target_real_name // Has to be stored because the target's real_name can change over the course of the round var/target_missing_id -/datum/objective/escape/escape_with_identity/find_target() +/datum/objective/escape/escape_with_identity/find_target(dupe_search_range, blacklist) target = ..() update_explanation_text() @@ -553,7 +553,7 @@ GLOBAL_LIST_EMPTY(possible_items) for(var/I in subtypesof(/datum/objective_item/steal)) new I -/datum/objective/steal/find_target() +/datum/objective/steal/find_target(dupe_search_range, blacklist) var/list/datum/mind/owners = get_owners() var/approved_targets = list() check_items: @@ -631,7 +631,7 @@ GLOBAL_LIST_EMPTY(possible_items_special) for(var/I in subtypesof(/datum/objective_item/special) + subtypesof(/datum/objective_item/stack)) new I -/datum/objective/steal/special/find_target() +/datum/objective/steal/special/find_target(dupe_search_range, blacklist) return set_target(pick(GLOB.possible_items_special)) /datum/objective/steal/exchange @@ -844,7 +844,7 @@ GLOBAL_LIST_EMPTY(possible_items_special) name = "destroy AI" martyr_compatible = 1 -/datum/objective/destroy/find_target() +/datum/objective/destroy/find_target(dupe_search_range, blacklist) var/list/possible_targets = active_ais(1) var/mob/living/silicon/ai/target_ai = pick(possible_targets) target = target_ai.mind @@ -1124,7 +1124,7 @@ GLOBAL_LIST_EMPTY(possible_items_special) /datum/objective/hoard/heirloom name = "steal heirloom" -/datum/objective/hoard/heirloom/find_target() +/datum/objective/hoard/heirloom/find_target(dupe_search_range, blacklist) set_target(pick(GLOB.family_heirlooms)) GLOBAL_LIST_EMPTY(traitor_contraband) @@ -1141,7 +1141,7 @@ GLOBAL_LIST_EMPTY(cult_contraband) if(!GLOB.cult_contraband.len) GLOB.cult_contraband = list(/obj/item/clockwork/slab,/obj/item/clockwork/component/belligerent_eye,/obj/item/clockwork/component/belligerent_eye/lens_gem,/obj/item/shuttle_curse,/obj/item/cult_shift) -/datum/objective/hoard/collector/find_target() +/datum/objective/hoard/collector/find_target(dupe_search_range, blacklist) var/obj/item/I var/I_type if(prob(50)) @@ -1172,7 +1172,7 @@ GLOBAL_LIST_EMPTY(possible_sabotages) for(var/I in subtypesof(/datum/sabotage_objective)) new I -/datum/objective/sabotage/find_target() +/datum/objective/sabotage/find_target(dupe_search_range, blacklist) var/list/datum/mind/owners = get_owners() var/approved_targets = list() check_sabotages: diff --git a/code/modules/antagonists/eldritch_cult/eldritch_antag.dm b/code/modules/antagonists/eldritch_cult/eldritch_antag.dm index ea226a3cb6..1e43754477 100644 --- a/code/modules/antagonists/eldritch_cult/eldritch_antag.dm +++ b/code/modules/antagonists/eldritch_cult/eldritch_antag.dm @@ -10,6 +10,8 @@ var/give_equipment = TRUE var/list/researched_knowledge = list() var/total_sacrifices = 0 + var/list/sac_targetted = list() //Which targets did living hearts give them, but they did not sac? + var/list/actually_sacced = list() //Which targets did they actually sac? var/ascended = FALSE /datum/antagonist/heretic/admin_add(datum/mind/new_owner,mob/admin) @@ -175,6 +177,17 @@ knowledge_message += "[EK.name]" parts += knowledge_message.Join(", ") + parts += "Targets assigned by living hearts, but not sacrificed:" + if(!sac_targetted.len) + parts += "None." + else + parts += sac_targetted.Join(",") + parts += "Sacrifices performed:" + if(!actually_sacced.len) + parts += "None!" + else + parts += actually_sacced.Join(",") + return parts.Join("
") //////////////// // Knowledge // @@ -213,6 +226,23 @@ if(ascended) . += 20 +/datum/antagonist/heretic/antag_panel() + var/list/parts = list() + parts += ..() + parts += "Targets currently assigned by living hearts (Can give a false negative if they stole someone elses living heart):" + if(!sac_targetted.len) + parts += "None." + else + parts += sac_targetted.Join(",") + parts += "Targets actually sacrificed:" + if(!actually_sacced.len) + parts += "None." + else + parts += actually_sacced.Join(",") + + return (parts.Join("
") + "
") + + //////////////// // Objectives // //////////////// diff --git a/code/modules/antagonists/eldritch_cult/eldritch_items.dm b/code/modules/antagonists/eldritch_cult/eldritch_items.dm index da2c61ad16..fbf0740e50 100644 --- a/code/modules/antagonists/eldritch_cult/eldritch_items.dm +++ b/code/modules/antagonists/eldritch_cult/eldritch_items.dm @@ -6,6 +6,17 @@ w_class = WEIGHT_CLASS_SMALL ///Target var/mob/living/carbon/human/target + var/datum/antagonist/heretic/sac_targetter //The heretic who used this to acquire the current target - gets cleared when target gets sacrificed. + +/obj/item/living_heart/Initialize() + . = ..() + GLOB.living_heart_cache.Add(src) //Add is better than +=. + +/obj/item/living_heart/Destroy() + GLOB.living_heart_cache.Remove(src) + if(sac_targetter && target) + sac_targetter.sac_targetted.Remove(target.real_name) + return ..() /obj/item/living_heart/attack_self(mob/user) . = ..() diff --git a/code/modules/antagonists/eldritch_cult/eldritch_knowledge.dm b/code/modules/antagonists/eldritch_cult/eldritch_knowledge.dm index e0189944e5..481ac08ea5 100644 --- a/code/modules/antagonists/eldritch_cult/eldritch_knowledge.dm +++ b/code/modules/antagonists/eldritch_cult/eldritch_knowledge.dm @@ -1,6 +1,6 @@ /** - * #Eldritch Knwoledge + * #Eldritch Knowledge * * Datum that makes eldritch cultist interesting. * @@ -252,6 +252,10 @@ LH.target = null var/datum/antagonist/heretic/EC = carbon_user.mind.has_antag_datum(/datum/antagonist/heretic) + EC.actually_sacced.Add(H.real_name) + if(LH.sac_targetter) + LH.sac_targetter.sac_targetted.Remove(H.real_name) + LH.sac_targetter = null EC.total_sacrifices++ for(var/X in carbon_user.get_all_gear()) if(!istype(X,/obj/item/forbidden_book)) @@ -265,8 +269,14 @@ var/datum/objective/A = new A.owner = user.mind var/list/targets = list() + var/list/target_blacklist = list() + for(var/obj/item/living_heart/CLH in GLOB.living_heart_cache) + if(!CLH || !CLH.target || !CLH.target.mind) + continue + target_blacklist.Add(CLH.target.mind) + for(var/i in 0 to 3) - var/datum/mind/targeted = A.find_target()//easy way, i dont feel like copy pasting that entire block of code + var/datum/mind/targeted = A.find_target(blacklist = target_blacklist)//easy way, i dont feel like copy pasting that entire block of code if(!targeted) break targets[targeted.current.real_name] = targeted.current @@ -274,9 +284,24 @@ if(!LH.target && targets.len) LH.target = pick(targets) //Tsk tsk, you can and will get another target if you want it or not. + + if(LH.target) + target_blacklist = list() + for(var/obj/item/living_heart/CLH in (GLOB.living_heart_cache - LH)) //Recreate blacklist, excluding ourselves. + if(!CLH || !CLH.target || !CLH.target.mind) + continue + target_blacklist.Add(CLH.target.mind) + if(LH.target.mind in target_blacklist) //Someone was faster, or you tried to cheese the system. + to_chat(user, "It seems you were too slow, and your target of choice has already been selected by another living heart!") + LH.target = null + qdel(A) if(LH.target) to_chat(user,"Your new target has been selected, go and sacrifice [LH.target.real_name]!") + var/datum/antagonist/heretic/EC = carbon_user.mind.has_antag_datum(/datum/antagonist/heretic) + LH.sac_targetter = EC + EC.sac_targetted.Add(LH.target.real_name) + else to_chat(user,"target could not be found for living heart.")