From 932eeeecef607db81b06be3a4115b612b9efcb60 Mon Sep 17 00:00:00 2001 From: DeltaFire Date: Mon, 3 Aug 2020 14:43:50 +0200 Subject: [PATCH] rites actually work now Rites can be casted now, added a show info option on the sigil of rites, adds a TON of debug messages, if this is PRd while they are still in yell at me loudly. Also adds the rite of advancement, a rite used to implant organs into a servant, without surgery being required. --- code/__DEFINES/clockcult.dm | 2 +- .../clockcult/clock_effects/clock_sigils.dm | 23 +++++- .../clockcult/clock_helpers/clock_rites.dm | 82 ++++++++++++++++--- 3 files changed, 91 insertions(+), 16 deletions(-) diff --git a/code/__DEFINES/clockcult.dm b/code/__DEFINES/clockcult.dm index a42ba4996f..5f4317060d 100644 --- a/code/__DEFINES/clockcult.dm +++ b/code/__DEFINES/clockcult.dm @@ -23,7 +23,7 @@ GLOBAL_VAR_INIT(script_scripture_unlocked, FALSE) //If script scripture is avail GLOBAL_VAR_INIT(application_scripture_unlocked, FALSE) //If application scripture is available GLOBAL_VAR_INIT(judgement_scripture_unlocked, FALSE) //If judgement scripture is available GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not used to track existing scripture -GLOBAL_LIST_INIT(clock_rites, list(typesof(/datum/clockwork_rite) - /datum/clockwork_rite)) +GLOBAL_LIST_EMPTY(all_clockwork_rites) //a list containing all clockwork rites. Filled the first time any cultist interacts with a sigil of rites. //Scripture tiers and requirements; peripherals should never be used #define SCRIPTURE_PERIPHERAL "Peripheral" diff --git a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm index a3802eb949..4a9313cae4 100644 --- a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm +++ b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm @@ -422,11 +422,28 @@ return if(!is_servant_of_ratvar(user)) return + generate_all_rites() var/list/possible_rites = list() - for(var/datum/clockwork_rite/R in GLOB.clock_rites) + for(var/datum/clockwork_rite/R in GLOB.all_clockwork_rites) possible_rites[R] = R - var/input_key = input(user, "Choose a rite to cast", "Casting a rite") as null|anything in possible_rites + message_admins("[R]") + var/input_key = input(user, "Choose a rite", "Choosing a rite") as null|anything in possible_rites if(!input_key) return var/datum/clockwork_rite/CR = possible_rites[input_key] - CR.try_cast(src, user) + if(!CR) + return + var/choice = alert(user, "What to do with this rite?", "What to do?", "Cast", "Show Info", "Cancel") + switch(choice) + if("Cast") + CR.try_cast(src, user) + if("Show Info") + var/infotext = CR.build_info() + to_chat(user, infotext) + +/obj/effect/clockwork/sigil/rite/proc/generate_all_rites() //The first time someone uses a sigil of rites, all the rites are actually generated. No need to have a bunch of random datums laying around all the time. + if(GLOB.all_clockwork_rites.len) //we already generated the list + return + for(var/V in subtypesof(/datum/clockwork_rite)) + var/datum/clockwork_rite/R = new V + GLOB.all_clockwork_rites += R diff --git a/code/modules/antagonists/clockcult/clock_helpers/clock_rites.dm b/code/modules/antagonists/clockcult/clock_helpers/clock_rites.dm index 7ca4c0ec45..351103ef1a 100644 --- a/code/modules/antagonists/clockcult/clock_helpers/clock_rites.dm +++ b/code/modules/antagonists/clockcult/clock_helpers/clock_rites.dm @@ -1,16 +1,19 @@ //This file is for clock rites, mainly used by the Sigil of Rites in clock_sigils.dm //The rites themselves are in this file to prevent bloating the other file too much, aswell as for easier access +#define INFINITE -1 + //The base clockwork rite. This should never be visible /datum/clockwork_rite var/name = "Some random clockwork rite that you should not be able to see" //The name of the rite + var/desc = "Someone forgot to set the description of this rite.. you shouldn't see this." //What does this rite do? Shown to cultists if they choose 'Show Info' after selecting the rite. var/list/required_ingredients = list() //What does this rite require? var/power_cost = 0 //How much power does this rite cost.. or does it even add power? var/requires_human = FALSE //Does the rite require a ../carbon/human on the rune? var/must_be_servant = TRUE //If the above is true, does the human need to be a servant? var/target_can_be_invoker = TRUE //Does this rite work if the invoker is also the target? var/cast_time = 0 //How long does the rite take to cast? - var/limit = -1 //How often can this rite be used per round? Set this to -1 for unlimited, 0 for disallowed, anything above 0 for a limit + var/limit = INFINITE //How often can this rite be used per round? Set this to INFINITE for unlimited, 0 for disallowed, anything above 0 for a limit var/times_used = 0 //How often has the rite already been used this shift? var/rite_cast_sound = 'sound/items/bikehorn.ogg' //The sound played when successfully casting the rite. If it honks, the one adding the rite forgot to set one (or was just lazy). @@ -20,11 +23,12 @@ if(!R || !R.loc) return FALSE var/turf/T = R.loc + message_admins("Turf: [T]") if(!T) //Uh oh something is fucky return FALSE - if(limit != -1 && times_used >= limit) //Is the limit on casts exceeded? - to_chat(invoker, "There are no more uses left for this rite!") + if(limit != INFINITE && times_used >= limit) //Is the limit on casts exceeded? + to_chat(invoker, "There are no more uses left for this rite!") return FALSE var/mob/living/carbon/human/H //This is only used if requires_human is TRUE @@ -39,12 +43,14 @@ if(required_ingredients.len) //In case this requires materials var/is_missing_materials = FALSE - for(var/obj/item/I in required_ingredients) + for(var/I in required_ingredients) var/obj/item/Material = locate(I) in T if(!Material) is_missing_materials = TRUE + message_admins("Failed at: [I]") break - if(!is_missing_materials) + message_admins("Found [Material] when searching for [I] - Success!") + if(is_missing_materials) var/still_required_string = "" for(var/i = 1 to required_ingredients.len) var/obj/O = required_ingredients[i] @@ -60,7 +66,7 @@ return FALSE R.performing_rite = TRUE if(!do_after(invoker, cast_time, target = R)) - to_chat(invoker, "span class='warning'>Your rite is disrupted.") + to_chat(invoker, "Your rite is disrupted.") R.performing_rite = FALSE return FALSE . = cast(invoker, T, H) @@ -73,24 +79,27 @@ R.performing_rite = FALSE return -/datum/clockwork_rite/proc/cast(/mob/living/invoker, var/turf/T, var/mob/living/carbon/human/target) //Casts the rite and uses up ingredients. Doublechecks some things to prevent bypassing some restrictions via funky timing or badminnery. +/datum/clockwork_rite/proc/cast(var/mob/living/invoker, var/turf/T, var/mob/living/carbon/human/target) //Casts the rite and uses up ingredients. Doublechecks some things to prevent bypassing some restrictions via funky timing or badminnery. + if(!T || !invoker) + return FALSE if(requires_human && !target) return FALSE if(power_cost && !get_clockwork_power(power_cost)) return FALSE adjust_clockwork_power(-power_cost) - if(limit != -1 && times_used >= limit) + if(limit != INFINITE && times_used >= limit) return FALSE if(required_ingredients.len) var/is_missing_materials = FALSE - for(var/obj/item/I in required_ingredients) + for(var/I in required_ingredients) var/obj/item/Material = locate(I) in T if(!Material) is_missing_materials = TRUE + message_admins("Failed at: [I]") break - else - qdel(Material) - if(!is_missing_materials) + qdel(Material) + message_admins("Found [Material] when searching for [I] - Success!") + if(is_missing_materials) return FALSE playsound(T, rite_cast_sound, 50, 2) return TRUE @@ -99,3 +108,52 @@ if(cast_succeeded) times_used++ return TRUE + +/datum/clockwork_rite/proc/build_info() //Constructs the info text of a given rite, based on the vars of the rite + . = "" + . += "This is the [name].\n" + . += "[desc]\n" + . += "It requires: " + if(required_ingredients.len) + var/material_string = "" + for(var/i = 1 to required_ingredients.len) + var/obj/O = required_ingredients[i] + if(i != 1) + material_string += ", " + material_string += "a [initial(O.name)]" + . += "[material_string].\n" + else + . += "no materials.\n" + . += "It [power_cost >= 0 ? "costs" : "generates"] [power_cost ? "[power_cost]" : "no"] power.\n" + . += "It requires [requires_human ? " a human" : " no"] target.\n" + if(requires_human) + . += "The target [must_be_servant ? "cannot be" : "can be"] a nonservant.\n" + . += "The target [target_can_be_invoker ? "can be" : "cannot be"] the invoker.\n" + . += "It requires [cast_time/10] seconds to cast.\n" + . += "It has been used [times_used] times, out of [limit != INFINITE ? ", [limit]" : "infinite"] available uses." + +/datum/clockwork_rite/advancement + name = "Rite of Advancement" + desc = "This rite is used to augment a servant with organs or cybernetic implants. The organ of choice, aswell as the servant and the required ingredients must be placed on the sigil for this rite to take place." + required_ingredients = list(/obj/item/assembly/prox_sensor, /obj/item/stock_parts/cell) + power_cost = 500 + requires_human = TRUE + cast_time = 40 + +/datum/clockwork_rite/advancement/cast(var/mob/living/invoker, var/turf/T, var/mob/living/carbon/human/target) + message_admins("Turf: [T]") + var/obj/item/organ/O = locate(/obj/item/organ) in T + if(!O) + message_admins("No organ found!") + return FALSE + if(istype(O, /obj/item/organ/brain)) //NOPE + return FALSE + message_admins("Organ to implant: [O]") + . = ..() + if(!.) + message_admins("Parent Rite cast failed - aborting") + return FALSE + O.Insert(target) + new /obj/effect/temp_visual/ratvar/sigil/transgression(T) + +#undef INFINITE