diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index cc183dd6..afbe3218 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -318,7 +318,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." return var/datum/antagonist/cult/antag = mob_viewer.mind.has_antag_datum(/datum/antagonist/cult,TRUE) - if(!antag) + if(!antag?.cult_team) return var/datum/objective/sacrifice/sac_objective = locate() in antag.cult_team.objectives diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm index 808022d2..a80ccb9c 100644 --- a/code/game/gamemodes/clock_cult/clock_cult.dm +++ b/code/game/gamemodes/clock_cult/clock_cult.dm @@ -45,8 +45,11 @@ Credit where due: // PROCS // /////////// -/proc/is_servant_of_ratvar(mob/M) - return istype(M) && !isobserver(M) && M.mind && M.mind.has_antag_datum(/datum/antagonist/clockcult) +/proc/is_servant_of_ratvar(mob/M, require_full_power = FALSE, holy_water_check = FALSE) + if(!istype(M) || isobserver(M)) + return FALSE + var/datum/antagonist/clockcult/D = M?.mind?.has_antag_datum(/datum/antagonist/clockcult) + return D && (!require_full_power || !D.neutered) && (!holy_water_check || !D.ignore_holy_water) /proc/is_eligible_servant(mob/M) if(!istype(M)) @@ -70,12 +73,14 @@ Credit where due: return TRUE return FALSE -/proc/add_servant_of_ratvar(mob/L, silent = FALSE, create_team = TRUE) +/proc/add_servant_of_ratvar(mob/L, silent = FALSE, create_team = TRUE, override_type) if(!L || !L.mind) return var/update_type = /datum/antagonist/clockcult if(silent) update_type = /datum/antagonist/clockcult/silent + if(override_type) //prioritizes + update_type = override_type var/datum/antagonist/clockcult/C = new update_type(L.mind) C.make_team = create_team C.show_in_roundend = create_team //tutorial scarabs begone @@ -105,9 +110,6 @@ Credit where due: L.playsound_local(get_turf(L), 'sound/ambience/antag/clockcultalr.ogg', 40, TRUE, frequency = 100000, pressure_affected = FALSE) flash_color(L, flash_color = list("#BE8700", "#BE8700", "#BE8700", rgb(0,0,0)), flash_time = 5) - - - /proc/remove_servant_of_ratvar(mob/L, silent = FALSE) if(!L || !L.mind) return diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index e7cc3c53..ebf2b46e 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -3,8 +3,11 @@ /datum/game_mode var/list/datum/mind/cult = list() -/proc/iscultist(mob/living/M) - return istype(M) && M.mind && M.mind.has_antag_datum(/datum/antagonist/cult) +/proc/iscultist(mob/living/M, require_full_power = FALSE, holy_water_check = FALSE) + if(!istype(M)) + return FALSE + var/datum/antagonist/cult/D = M?.mind?.has_antag_datum(/datum/antagonist/cult) + return D && (!require_full_power || !D.neutered) && (!holy_water_check || !D.ignore_holy_water) /datum/team/cult/proc/is_sacrifice_target(datum/mind/mind) for(var/datum/objective/sacrifice/sac_objective in objectives) @@ -93,7 +96,7 @@ add_cultist(cult_mind, 0, equip=TRUE) if(!main_cult) var/datum/antagonist/cult/C = cult_mind.has_antag_datum(/datum/antagonist/cult,TRUE) - if(C && C.cult_team) + if(C?.cult_team) main_cult = C.cult_team ..() diff --git a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm index 97d7f0c1..6eedffb1 100644 --- a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm +++ b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm @@ -270,9 +270,15 @@ sigil_name = "Vitality Matrix" var/revive_cost = 150 var/sigil_active = FALSE + var/min_drain_health = -INFINITY + var/can_dust = TRUE var/animation_number = 3 //each cycle increments this by 1, at 4 it produces an animation and resets var/static/list/damage_heal_order = list(CLONE, TOX, BURN, BRUTE, OXY) //we heal damage in this order +/obj/effect/clockwork/sigil/vitality/neutered + min_drain_health = 20 + can_dust = FALSE + /obj/effect/clockwork/sigil/vitality/examine(mob/user) ..() if(is_servant_of_ratvar(user) || isobserver(user)) @@ -297,7 +303,7 @@ animation_number++ if(!is_servant_of_ratvar(L)) var/vitality_drained = 0 - if(L.stat == DEAD && !consumed_vitality) + if(L.stat == DEAD && !consumed_vitality && can_dust) consumed_vitality = TRUE //Prevent the target from being consumed multiple times vitality_drained = L.maxHealth var/obj/effect/temp_visual/ratvar/sigil/vitality/V = new /obj/effect/temp_visual/ratvar/sigil/vitality(get_turf(src)) @@ -309,7 +315,7 @@ if(!L.dropItemToGround(W)) qdel(W) L.dust() - else + else if(L.health > min_drain_health) if(!GLOB.ratvar_awakens && L.stat == CONSCIOUS) vitality_drained = L.adjustToxLoss(1) else diff --git a/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm b/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm index ec712f2e..a4866751 100644 --- a/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm +++ b/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm @@ -36,6 +36,24 @@ speed_multiplier = 0 no_cost = TRUE +/obj/item/clockwork/slab/traitor + var/spent = FALSE + +/obj/item/clockwork/slab/traitor/check_uplink_validity() + return !spent + +/obj/item/clockwork/slab/traitor/attack_self(mob/living/user) + if(!is_servant_of_ratvar(user) && !spent) + to_chat(user, "You press your hand onto [src], golden tendrils of light latching onto you. Was this the best of ideas?") + if(add_servant_of_ratvar(user, FALSE, FALSE, /datum/antagonist/clockcult/neutered/traitor)) + spent = TRUE + // Add some (5 KW) power so they don't suffer for 100 ticks + GLOB.clockwork_power += 5000 + // This intentionally does not use adjust_clockwork_power. + else + to_chat(user, "[src] falls dark. It appears you weren't worthy.") + return ..() + //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/clockwork/slab/debug/attack_hand(mob/living/user) if(!is_servant_of_ratvar(user)) diff --git a/code/modules/antagonists/clockcult/clock_scripture.dm b/code/modules/antagonists/clockcult/clock_scripture.dm index 753de786..16d251fe 100644 --- a/code/modules/antagonists/clockcult/clock_scripture.dm +++ b/code/modules/antagonists/clockcult/clock_scripture.dm @@ -30,6 +30,7 @@ Applications: 8 servants, 3 caches, and 100 CV var/primary_component var/important = FALSE //important scripture will be italicized in the slab's interface var/sort_priority = 1 //what position the scripture should have in a list of scripture. Should be based off of component costs/reqs, but you can't initial() lists. + var/requires_full_power = FALSE //requires the user to be a full, non neutered servant of ratvar //messages for offstation scripture recital, courtesy ratvar's generals(and neovgre) var/static/list/neovgre_penalty = list("Go to the station.", "Useless.", "Don't waste time.", "Pathetic.", "Wasteful.") @@ -77,6 +78,9 @@ Applications: 8 servants, 3 caches, and 100 CV /datum/clockwork_scripture/proc/can_recite() //If the words can be spoken if(!invoker || !slab || invoker.get_active_held_item() != slab) return FALSE + if(!is_servant_of_ratvar(invoker, requires_full_power)) + to_chat(invoker, "You aren't strongly connected enough to Ratvar to invoke this!") + return FALSE if(!invoker.can_speak_vocal()) to_chat(invoker, "You are unable to speak the words of the scripture!") return FALSE @@ -236,18 +240,21 @@ Applications: 8 servants, 3 caches, and 100 CV return FALSE return TRUE +/datum/clockwork_scripture/create_object/proc/get_spawn_path(mob/user) + return object_path + /datum/clockwork_scripture/create_object/scripture_effects() if(creator_message && observer_message) invoker.visible_message(observer_message, creator_message) else if(creator_message) to_chat(invoker, creator_message) - var/obj/O = new object_path (get_turf(invoker)) + var/to_spawn = get_spawn_path(invoker) + var/obj/O = new to_spawn(get_turf(invoker)) O.ratvar_act() //update the new object so it gets buffed if ratvar is alive if(isitem(O) && put_object_in_hands) invoker.put_in_hands(O) return TRUE - //Used specifically to create construct shells. /datum/clockwork_scripture/create_object/construct put_object_in_hands = FALSE diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm index 6d6b1fa9..c8ba5eba 100644 --- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm +++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm @@ -88,7 +88,7 @@ sort_priority = 4 quickbind = TRUE quickbind_desc = "Creates a Sigil of Submission, which will convert non-Servants that remain on it." - + requires_full_power = TRUE //Kindle: Charges the slab with blazing energy. It can be released to stun and silence a target. /datum/clockwork_scripture/ranged_ability/kindle @@ -211,6 +211,7 @@ quickbind = TRUE quickbind_desc = "Returns you to Reebe." var/client_color + requires_full_power = TRUE /datum/clockwork_scripture/abscond/check_special_requirements() if(is_reebe(invoker.z)) diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm index 4e1a5b42..d6296aea 100644 --- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm +++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_scripts.dm @@ -50,7 +50,6 @@ return FALSE return ..() - //Vitality Matrix: Creates a sigil which will drain health from nonservants and can use that health to heal or even revive servants. /datum/clockwork_scripture/create_object/vitality_matrix descname = "Trap, Damage to Healing" @@ -77,6 +76,10 @@ return FALSE return ..() +/datum/clockwork_scripture/create_object/vitality_matrix/get_spawn_path(mob/user) + if(!is_servant_of_ratvar(user, TRUE)) + return /obj/effect/clockwork/sigil/vitality/neutered + return ..() //Judicial Visor: Creates a judicial visor, which can smite an area. /datum/clockwork_scripture/create_object/judicial_visor diff --git a/code/modules/antagonists/clockcult/clockcult.dm b/code/modules/antagonists/clockcult/clockcult.dm index d68e9b59..87f9e7d0 100644 --- a/code/modules/antagonists/clockcult/clockcult.dm +++ b/code/modules/antagonists/clockcult/clockcult.dm @@ -5,14 +5,26 @@ antagpanel_category = "Clockcult" job_rank = ROLE_SERVANT_OF_RATVAR antag_moodlet = /datum/mood_event/cult - var/datum/action/innate/hierophant/hierophant_network = new() + var/datum/action/innate/hierophant/hierophant_network = new var/datum/team/clockcult/clock_team var/make_team = TRUE //This should be only false for tutorial scarabs + var/neutered = FALSE //can not use round ending, gibbing, converting, or similar things with unmatched round impact + var/ignore_eligibility_check = FALSE + var/ignore_holy_water = FALSE /datum/antagonist/clockcult/silent silent = TRUE show_in_antagpanel = FALSE //internal +/datum/antagonist/clockcult/neutered + neutered = TRUE + +/datum/antagonist/clockcult/neutered/traitor + ignore_eligibility_check = TRUE + ignore_holy_water = TRUE + show_in_roundend = FALSE + make_team = FALSE + /datum/antagonist/clockcult/Destroy() qdel(hierophant_network) return ..() @@ -37,7 +49,7 @@ /datum/antagonist/clockcult/can_be_owned(datum/mind/new_owner) . = ..() - if(.) + if(. && !ignore_eligibility_check) . = is_eligible_servant(new_owner.current) /datum/antagonist/clockcult/greet() diff --git a/code/modules/antagonists/cult/blood_magic.dm b/code/modules/antagonists/cult/blood_magic.dm index a1bfc067..50d24821 100644 --- a/code/modules/antagonists/cult/blood_magic.dm +++ b/code/modules/antagonists/cult/blood_magic.dm @@ -560,7 +560,9 @@ var/turf/T = get_turf(target) if(istype(target, /obj/item/stack/sheet/metal)) var/obj/item/stack/sheet/candidate = target - if(candidate.use(50)) + if(!iscultist(user, TRUE)) + to_chat(user, "You are not strongly connected enough to Nar'sie to use make constructs...") + else if(candidate.use(50)) uses-- to_chat(user, "A dark cloud emanates from your hand and swirls around the metal, twisting it into a construct shell!") new /obj/structure/constructshell(T) @@ -577,7 +579,9 @@ SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) else if(istype(target,/mob/living/silicon/robot)) var/mob/living/silicon/robot/candidate = target - if(candidate.mmi) + if(!iscultist(user, TRUE)) + to_chat(user, "You are not strongly connected enough to Nar'sie to use make constructs...") + else if(candidate.mmi) user.visible_message("A dark cloud emanates from [user]'s hand and swirls around [candidate]!") playsound(T, 'sound/machines/airlock_alien_prying.ogg', 80, 1) var/prev_color = candidate.color @@ -796,6 +800,8 @@ if("Blood Beam (500)") if(uses < 500) to_chat(user, "You need 500 charges to perform this rite.") + else if(!iscultist(user, TRUE)) + to_chat(user, "You are not strongly connected to Nar'sie enough to use something of this power.") else var/obj/rite = new /obj/item/blood_beam() uses -= 500 diff --git a/code/modules/antagonists/cult/cult.dm b/code/modules/antagonists/cult/cult.dm index 47cf2abf..fd8d2ce1 100644 --- a/code/modules/antagonists/cult/cult.dm +++ b/code/modules/antagonists/cult/cult.dm @@ -10,15 +10,27 @@ var/datum/action/innate/cult/blood_magic/magic = new job_rank = ROLE_CULTIST var/ignore_implant = FALSE + var/make_team = TRUE var/give_equipment = FALSE var/datum/team/cult/cult_team + var/neutered = FALSE //can not use round ending, gibbing, converting, or similar things with unmatched round impact + var/ignore_eligibility_checks = FALSE + var/ignore_holy_water = FALSE +/datum/antagonist/cult/neutered + neutered = TRUE + +/datum/antagonist/cult/neutered/traitor + ignore_eligibility_checks = TRUE + ignore_holy_water = TRUE + show_in_roundend = FALSE + make_team = FALSE /datum/antagonist/cult/get_team() return cult_team /datum/antagonist/cult/create_team(datum/team/cult/new_team) - if(!new_team) + if(!new_team && make_team) //todo remove this and allow admin buttons to create more than one cult for(var/datum/antagonist/cult/H in GLOB.antagonists) if(!H.owner) @@ -29,13 +41,12 @@ cult_team = new /datum/team/cult cult_team.setup_objectives() return - if(!istype(new_team)) + if(make_team && !istype(new_team)) stack_trace("Wrong team type passed to [type] initialization.") cult_team = new_team /datum/antagonist/cult/proc/add_objectives() - objectives |= cult_team.objectives - owner.objectives |= objectives + objectives |= cult_team?.objectives /datum/antagonist/cult/Destroy() QDEL_NULL(communion) @@ -44,7 +55,7 @@ /datum/antagonist/cult/can_be_owned(datum/mind/new_owner) . = ..() - if(. && !ignore_implant) + if(. && !ignore_implant && !ignore_eligibility_checks) . = is_convertable_to_cult(new_owner.current,cult_team) /datum/antagonist/cult/greet() @@ -62,7 +73,7 @@ SSticker.mode.update_cult_icons_added(owner) current.log_message("has been converted to the cult of Nar'Sie!", LOG_ATTACK, color="#960000") - if(cult_team.blood_target && cult_team.blood_target_image && current.client) + if(cult_team?.blood_target && cult_team.blood_target_image && current.client) current.client.images += cult_team.blood_target_image @@ -105,13 +116,13 @@ current = mob_override current.faction |= "cult" current.grant_language(/datum/language/narsie) - if(!cult_team.cult_master) + if(!cult_team?.cult_master) vote.Grant(current) communion.Grant(current) if(ishuman(current)) magic.Grant(current) current.throw_alert("bloodsense", /obj/screen/alert/bloodsense) - if(cult_team.cult_risen) + if(cult_team?.cult_risen) cult_team.rise(current) if(cult_team.cult_ascendent) cult_team.ascend(current) @@ -143,7 +154,7 @@ owner.current.visible_message("[owner.current] looks like [owner.current.p_theyve()] just reverted to [owner.current.p_their()] old faith!", null, null, null, owner.current) to_chat(owner.current, "An unfamiliar white light flashes through your mind, cleansing the taint of the Geometer and all your memories as her servant.") owner.current.log_message("has renounced the cult of Nar'Sie!", LOG_ATTACK, color="#960000") - if(cult_team.blood_target && cult_team.blood_target_image && owner.current.client) + if(cult_team?.blood_target && cult_team.blood_target_image && owner.current.client) owner.current.client.images -= cult_team.blood_target_image . = ..() @@ -205,7 +216,7 @@ throwing.Grant(current) current.update_action_buttons_icon() current.apply_status_effect(/datum/status_effect/cult_master) - if(cult_team.cult_risen) + if(cult_team?.cult_risen) cult_team.rise(current) if(cult_team.cult_ascendent) cult_team.ascend(current) diff --git a/code/modules/antagonists/cult/cult_comms.dm b/code/modules/antagonists/cult/cult_comms.dm index 761412e9..80214432 100644 --- a/code/modules/antagonists/cult/cult_comms.dm +++ b/code/modules/antagonists/cult/cult_comms.dm @@ -74,7 +74,7 @@ /datum/action/innate/cult/mastervote/IsAvailable() var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE) - if(!C || C.cult_team.cult_vote_called || !ishuman(owner)) + if(!C?.cult_team || C.cult_team.cult_vote_called || !ishuman(owner)) return FALSE return ..() @@ -82,6 +82,9 @@ var/choice = alert(owner, "The mantle of leadership is heavy. Success in this role requires an expert level of communication and experience. Are you sure?",, "Yes", "No") if(choice == "Yes" && IsAvailable()) var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + if(!C.cult_team) + to_chat(owner, "Do you not alreaady lead yourself?") + return pollCultists(owner,C.cult_team) /proc/pollCultists(var/mob/living/Nominee,datum/team/cult/team) //Cult Master Poll @@ -151,6 +154,9 @@ var/datum/antagonist/cult/antag = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE) if(!antag) return + if(!antag.cult_team) + to_chat(owner, "You have no team. You are alone.") + return for(var/i in 1 to 4) chant(i) var/list/destinations = list() @@ -261,7 +267,10 @@ return FALSE var/datum/antagonist/cult/C = caller.mind.has_antag_datum(/datum/antagonist/cult,TRUE) - + if(!C.cult_team) + to_chat(ranged_ability_user, "What is the point of marking a target for yourself?") + remove_ranged_ability() + return if(target in view(7, get_turf(ranged_ability_user))) if(C.cult_team.blood_target) to_chat(ranged_ability_user, "The cult has already designated a target!") @@ -330,8 +339,11 @@ /datum/action/innate/cult/ghostmark/Activate() var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + if(!C.cult_team) + to_chat(owner, "You are alone. You do not have a team.") + return if(C.cult_team.blood_target) - if(cooldown>world.time) + if(cooldown > world.time) reset_blood_target(C.cult_team) to_chat(owner, "You have cleared the cult's blood target!") deltimer(C.cult_team.blood_target_reset_timer) @@ -339,7 +351,7 @@ else to_chat(owner, "The cult has already designated a target!") return - if(cooldown>world.time) + if(cooldown > world.time) to_chat(owner, "You aren't ready to place another blood mark yet!") return target = owner.orbiting?.parent || get_turf(owner) diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm index 10759afc..a2ee047c 100644 --- a/code/modules/antagonists/cult/cult_items.dm +++ b/code/modules/antagonists/cult/cult_items.dm @@ -6,6 +6,21 @@ throw_range = 5 w_class = WEIGHT_CLASS_SMALL +/obj/item/tome/traitor + var/spent = FALSE + +/obj/item/tome/traitor/check_uplink_validity() + return !spent + +/obj/item/tome/traitor/attack_self(mob/living/user) + if(!iscultist(user) && !spent) + to_chat(user, "You press your hand onto [src], sinister tendrils of corrupted magic swirling around you. Was this the best of ideas?") + if(user.mind.add_antag_datum(/datum/antagonist/cult/neutered/traitor)) + spent = TRUE + else + to_chat(user, "[src] falls dark. It appears you weren't worthy.") + return ..() + /obj/item/melee/cultblade/dagger name = "ritual dagger" desc = "A strange dagger said to be used by sinister groups for \"preparing\" a corpse before sacrificing it to their dark gods." @@ -496,7 +511,7 @@ var/global/curselimit = 0 /obj/item/shuttle_curse/attack_self(mob/living/user) - if(!iscultist(user)) + if(!iscultist(user, TRUE)) user.dropItemToGround(src, TRUE) user.Knockdown(100) to_chat(user, "A powerful force shoves you away from [src]!") diff --git a/code/modules/antagonists/cult/ritual.dm b/code/modules/antagonists/cult/ritual.dm index 69941f58..a9c77567 100644 --- a/code/modules/antagonists/cult/ritual.dm +++ b/code/modules/antagonists/cult/ritual.dm @@ -59,6 +59,9 @@ This file contains the cult dagger and rune list code rune_to_scribe = GLOB.rune_types[entered_rune_name] if(!rune_to_scribe) return + if(!iscultist(user, initial(rune_to_scribe.requires_full_power))) + to_chat(user, "You aren't strongly connected enough to Nar'sie to do draw this.") + return if(initial(rune_to_scribe.req_keyword)) chosen_keyword = stripped_input(user, "Enter a keyword for the new rune.", "Words of Power") if(!chosen_keyword) @@ -84,8 +87,8 @@ This file contains the cult dagger and rune list code to_chat(user, "Only one ritual site remains - it must be reserved for the final summoning!") return if(ispath(rune_to_scribe, /obj/effect/rune/narsie)) - var/datum/objective/eldergod/summon_objective = locate() in user_antag.cult_team.objectives - var/datum/objective/sacrifice/sac_objective = locate() in user_antag.cult_team.objectives + var/datum/objective/eldergod/summon_objective = locate() in user_antag.cult_team?.objectives + var/datum/objective/sacrifice/sac_objective = locate() in user_antag.cult_team?.objectives if(!summon_objective) to_chat(user, "Nar'Sie does not wish to be summoned!") return diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index 927d4c73..df696a97 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -32,6 +32,7 @@ Runes can either be invoked by one's self or with many different cultists. Each var/scribe_delay = 40 //how long the rune takes to create var/scribe_damage = 0.1 //how much damage you take doing it + var/requires_full_power = FALSE //requires full power to draw or invoke var/invoke_damage = 0 //how much damage invokers take when invoking it var/construct_invoke = TRUE //if constructs can invoke it @@ -185,6 +186,7 @@ structure_check() searches for nearby cultist structures required for the invoca color = RUNE_COLOR_OFFER req_cultists = 1 rune_in_use = FALSE + requires_full_power = TRUE /obj/effect/rune/convert/do_invoke_glow() return @@ -457,6 +459,7 @@ structure_check() searches for nearby cultist structures required for the invoca pixel_y = -32 scribe_delay = 500 //how long the rune takes to create scribe_damage = 40.1 //how much damage you take doing it + requires_full_power = TRUE var/used = FALSE /obj/effect/rune/narsie/Initialize(mapload, set_keyword) @@ -481,6 +484,9 @@ structure_check() searches for nearby cultist structures required for the invoca fail_invoke() return var/datum/antagonist/cult/user_antag = user.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + if(!user_antag.cult_team) + to_chat(user, "You can't seem to make the arcane links to your fellows that you'd need to use this.") + return var/datum/objective/eldergod/summon_objective = locate() in user_antag.cult_team.objectives var/area/place = get_area(src) if(!(place in summon_objective.summon_spots)) @@ -811,6 +817,7 @@ structure_check() searches for nearby cultist structures required for the invoca invoke_damage = 10 construct_invoke = FALSE color = RUNE_COLOR_DARKRED + requires_full_power = TRUE var/mob/living/affecting = null var/ghost_limit = 3 var/ghosts = 0 @@ -941,6 +948,7 @@ structure_check() searches for nearby cultist structures required for the invoca color = RUNE_COLOR_DARKRED req_cultists = 3 scribe_delay = 100 + requires_full_power = TRUE /obj/effect/rune/apocalypse/invoke(var/list/invokers) if(rune_in_use) @@ -949,6 +957,9 @@ structure_check() searches for nearby cultist structures required for the invoca var/area/place = get_area(src) var/mob/living/user = invokers[1] var/datum/antagonist/cult/user_antag = user.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + if(!user_antag.cult_team) + to_chat(user, "You can't seem to make the arcane links to your fellows that you'd need to use this.") + return var/datum/objective/eldergod/summon_objective = locate() in user_antag.cult_team.objectives if(summon_objective.summon_spots.len <= 1) to_chat(user, "Only one ritual site remains - it must be reserved for the final summoning!") diff --git a/code/modules/antagonists/wizard/equipment/soulstone.dm b/code/modules/antagonists/wizard/equipment/soulstone.dm index 40551ae2..02d78035 100644 --- a/code/modules/antagonists/wizard/equipment/soulstone.dm +++ b/code/modules/antagonists/wizard/equipment/soulstone.dm @@ -31,12 +31,12 @@ /obj/item/soulstone/pickup(mob/living/user) ..() - if(!iscultist(user) && !iswizard(user) && !usability) + if(!iscultist(user, TRUE) && !iswizard(user) && !usability) to_chat(user, "An overwhelming feeling of dread comes over you as you pick up the soulstone. It would be wise to be rid of this quickly.") /obj/item/soulstone/examine(mob/user) - ..() - if(usability || iscultist(user) || iswizard(user) || isobserver(user)) + . = ..() + if(usability || iscultist(user, TRUE) || iswizard(user) || isobserver(user)) if (old_shard) to_chat(user, "A soulstone, used to capture a soul, either from dead humans or from freed shades.") else @@ -53,7 +53,7 @@ //////////////////////////////Capturing//////////////////////////////////////////////////////// /obj/item/soulstone/attack(mob/living/carbon/human/M, mob/living/user) - if(!iscultist(user) && !iswizard(user) && !usability) + if(!iscultist(user, TRUE) && !iswizard(user) && !usability) user.Unconscious(100) to_chat(user, "Your body is wracked with debilitating pain!") return @@ -74,7 +74,7 @@ /obj/item/soulstone/attack_self(mob/living/user) if(!in_range(src, user)) return - if(!iscultist(user) && !iswizard(user) && !usability) + if(!iscultist(user, TRUE) && !iswizard(user) && !usability) user.Unconscious(100) to_chat(user, "Your body is wracked with debilitating pain!") return @@ -102,18 +102,18 @@ desc = "A wicked machine used by those skilled in magical arts. It is inactive." /obj/structure/constructshell/examine(mob/user) - ..() - if(iscultist(user) || iswizard(user) || user.stat == DEAD) - to_chat(user, "A construct shell, used to house bound souls from a soulstone.") - to_chat(user, "Placing a soulstone with a soul into this shell allows you to produce your choice of the following:") - to_chat(user, "An Artificer, which can produce more shells and soulstones, as well as fortifications.") - to_chat(user, "A Wraith, which does high damage and can jaunt through walls, though it is quite fragile.") - to_chat(user, "A Juggernaut, which is very hard to kill and can produce temporary walls, but is slow.") + . = ..() + if(iscultist(user, TRUE) || iswizard(user) || user.stat == DEAD) + . += "A construct shell, used to house bound souls from a soulstone." + . += "Placing a soulstone with a soul into this shell allows you to produce your choice of the following:" + . += "An Artificer, which can produce more shells and soulstones, as well as fortifications." + . += "A Wraith, which does high damage and can jaunt through walls, though it is quite fragile." + . += "A Juggernaut, which is very hard to kill and can produce temporary walls, but is slow." /obj/structure/constructshell/attackby(obj/item/O, mob/user, params) if(istype(O, /obj/item/soulstone)) var/obj/item/soulstone/SS = O - if(!iscultist(user) && !iswizard(user) && !SS.usability) + if(!iscultist(user, TRUE) && !iswizard(user) && !SS.usability) to_chat(user, "An overwhelming feeling of dread comes over you as you attempt to place the soulstone into the shell. It would be wise to be rid of this quickly.") user.Dizzy(30) return @@ -145,7 +145,7 @@ if("VICTIM") var/mob/living/carbon/human/T = target var/datum/antagonist/cult/C = user.mind.has_antag_datum(/datum/antagonist/cult,TRUE) - if(C && C.cult_team.is_sacrifice_target(T.mind)) + if(C && C.cult_team?.is_sacrifice_target(T.mind)) if(iscultist(user)) to_chat(user, "\"This soul is mine. SACRIFICE THEM!\"") else diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index c4ccaff1..62017aa6 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -393,6 +393,9 @@ var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult) if(!C) return + if(!C.cult_team) + to_chat(the_construct, "You are alone, and have no team.") + return var/datum/objective/eldergod/summon_objective = locate() in C.cult_team.objectives if(summon_objective.check_completion()) diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index a073997b..c4710476 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -51,7 +51,8 @@ for(var/datum/antagonist/cult/C in GLOB.antagonists) if(!C.owner) continue - all_cults |= C.cult_team + if(C.cult_team) + all_cults |= C.cult_team for(var/datum/team/cult/T in all_cults) deltimer(T.blood_target_reset_timer) T.blood_target = src diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index d1e57c66..544c379c 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -222,7 +222,7 @@ data = 1 data++ M.jitteriness = min(M.jitteriness+4,10) - if(iscultist(M)) + if(iscultist(M, FALSE, TRUE)) for(var/datum/action/innate/cult/blood_magic/BM in M.actions) to_chat(M, "Your blood rites falter as holy water scours your body!") for(var/datum/action/innate/cult/blood_spell/BS in BM.spells) @@ -249,7 +249,7 @@ if("emote") M.visible_message("[M] [pick("whimpers quietly", "shivers as though cold", "glances around in paranoia")].") if(data >= 60) // 30 units, 135 seconds - if(iscultist(M) || is_servant_of_ratvar(M)) + if(iscultist(M, FALSE, TRUE) || is_servant_of_ratvar(M, FALSE, TRUE)) if(iscultist(M)) SSticker.mode.remove_cultist(M.mind, FALSE, TRUE) else if(is_servant_of_ratvar(M)) diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm index f93bdbae..e8dcffd1 100644 --- a/code/modules/uplink/uplink_items.dm +++ b/code/modules/uplink/uplink_items.dm @@ -1775,6 +1775,22 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes restricted_roles = list("Chaplain") surplus = 5 //Very low chance to get it in a surplus crate even without being the chaplain +/datum/uplink_item/role_restricted/clockwork_slab + name = "Clockwork Slab" + desc = "A reverse engineered clockwork slab. Is this really a good idea?" + item = /obj/item/clockwork/slab/traitor + cost = 20 + refundable = TRUE + //restricted_roles = list("Chaplain","Curator") + +/datum/uplink_item/role_restricted/arcane_tome + name = "Arcane Tome" + desc = "A 'replica' of a Nar'sian tome. This is probably a bad idea..." + item = /obj/item/tome/traitor + cost = 20 + refundable = TRUE + //restricted_roles = list("Chaplain","Curator") + /datum/uplink_item/role_restricted/explosive_hot_potato name = "Exploding Hot Potato" desc = "A potato rigged with explosives. On activation, a special mechanism is activated that prevents it from being dropped. \