diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index bdc6ea2980..7c116cc606 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -334,7 +334,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 15d7744205..7b798f19e4 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 497cc2f1c3..8ec4123201 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 daa4e24c69..431416ede0 100644 --- a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm +++ b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm @@ -279,9 +279,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)) @@ -306,7 +312,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)) @@ -318,7 +324,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, forced = TRUE) else diff --git a/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm b/code/modules/antagonists/clockcult/clock_items/clockwork_slab.dm index b12c72b4af..6e7d830db6 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 753de786dc..16d251fe92 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 5d7a95222f..6349ecb581 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 4e1a5b42cb..d6296aeaa0 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 cf3d88983c..cbfd443744 100644 --- a/code/modules/antagonists/clockcult/clockcult.dm +++ b/code/modules/antagonists/clockcult/clockcult.dm @@ -5,15 +5,27 @@ antagpanel_category = "Clockcult" job_rank = ROLE_SERVANT_OF_RATVAR antag_moodlet = /datum/mood_event/cult + var/datum/action/innate/hierophant/hierophant_network = new threat = 3 - 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 ..() @@ -38,7 +50,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 c4a8c1e827..bea86d8bb4 100644 --- a/code/modules/antagonists/cult/blood_magic.dm +++ b/code/modules/antagonists/cult/blood_magic.dm @@ -439,7 +439,7 @@ "A feeling of warmth washes over you, rays of holy light surround your body and protect you from the flash of light!") else // cult doesn't stun any longer when halos are out, instead it does burn damage + knockback! var/datum/antagonist/cult/user_antag = user.mind.has_antag_datum(/datum/antagonist/cult,TRUE) - if(user_antag.cult_team.cult_ascendent) + if(user_antag.cult_team?.cult_ascendent) if(!iscultist(L)) L.adjustFireLoss(20) if(L.move_resist < MOVE_FORCE_STRONG) @@ -577,7 +577,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) @@ -600,7 +602,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 @@ -820,6 +824,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 1746fd135c..023794182a 100644 --- a/code/modules/antagonists/cult/cult.dm +++ b/code/modules/antagonists/cult/cult.dm @@ -11,15 +11,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) @@ -30,12 +42,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 + objectives |= cult_team?.objectives /datum/antagonist/cult/Destroy() QDEL_NULL(communion) @@ -44,7 +56,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 +74,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 +117,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) @@ -144,7 +156,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 . = ..() @@ -206,7 +218,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 761412e9f8..8021443217 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 b31bfc0693..11c0e9ade5 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." @@ -509,7 +524,7 @@ var/static/curselimit = 0 /obj/item/shuttle_curse/attack_self(mob/living/user) - if(!iscultist(user)) + if(!iscultist(user, TRUE)) user.dropItemToGround(src, TRUE) user.DefaultCombatKnockdown(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 e92f562db3..40804ccc24 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 ec763a66d7..b0538d6521 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 @@ -458,6 +460,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) @@ -482,6 +485,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)) @@ -812,6 +818,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 @@ -942,6 +949,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) @@ -950,6 +958,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 0f43dfaf3a..d7f1046cd7 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) . += "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 @@ -103,7 +103,7 @@ /obj/structure/constructshell/examine(mob/user) . = ..() - if(iscultist(user) || iswizard(user) || user.stat == DEAD) + 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." @@ -113,7 +113,7 @@ /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 a6366c03fe..674cc722d8 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -392,6 +392,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 a073997b9d..c471047682 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 d9b2aafb4b..b73838e6c1 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -332,7 +332,7 @@ data = list("misc" = 1) data["misc"]++ 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) if(!BM.holy_dispel) BM.holy_dispel = TRUE @@ -361,7 +361,7 @@ if("emote") M.visible_message("[M] [pick("whimpers quietly", "shivers as though cold", "glances around in paranoia")].") if(data["misc"] >= 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/uplink_roles.dm b/code/modules/uplink/uplink_items/uplink_roles.dm index 3d28010133..778edf8cc8 100644 --- a/code/modules/uplink/uplink_items/uplink_roles.dm +++ b/code/modules/uplink/uplink_items/uplink_roles.dm @@ -92,6 +92,22 @@ 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") + +/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") + /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. \