Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PORT] Changes how Cultists obtain the bastard sword. Instead of sacrificing Heretics, you now sacrifice Null Rods, with a caveat. #964

Merged
merged 1 commit into from
Jan 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions code/game/objects/items/holy_weapons.dm
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
var/chaplain_spawnable = TRUE
/// Short description of what this item is capable of, for radial menu uses.
var/menu_description = "A standard chaplain's weapon. Fits in pockets. Can be worn on the belt."
/// Lazylist, tracks refs()s to all cultists which have been crit or killed by this nullrod.
var/list/cultists_slain

/obj/item/nullrod/Initialize(mapload)
. = ..()
Expand Down Expand Up @@ -59,6 +61,27 @@
user.visible_message(span_suicide("[user] is killing [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to get closer to god!"))
return (BRUTELOSS|FIRELOSS)

/obj/item/nullrod/attack(mob/living/target_mob, mob/living/user, params)
if(!user.mind?.holy_role)
return ..()
if(!IS_CULTIST(target_mob) || istype(target_mob, /mob/living/carbon/human/cult_ghost))
return ..()

var/old_stat = target_mob.stat
. = ..()
if(old_stat < target_mob.stat)
LAZYOR(cultists_slain, REF(target_mob))
return .

/obj/item/nullrod/examine(mob/user)
. = ..()
if(!IS_CULTIST(user) || !GET_ATOM_BLOOD_DNA_LENGTH(src))
return

var/num_slain = LAZYLEN(cultists_slain)
. += span_cultitalic("It has the blood of [num_slain] fallen cultist[num_slain == 1 ? "" : "s"] on it. \
<b>Offering</b> it to Nar'sie will transform it into a [num_slain >= 3 ? "powerful" : "standard"] cult weapon.")

/obj/item/nullrod/godhand
name = "god hand"
desc = "This hand of yours glows with an awesome power!"
Expand Down
136 changes: 89 additions & 47 deletions code/modules/antagonists/cult/runes.dm
Original file line number Diff line number Diff line change
Expand Up @@ -222,52 +222,58 @@ structure_check() searches for nearby cultist structures required for the invoca
/obj/effect/rune/convert/invoke(list/invokers)
if(rune_in_use)
return

var/list/myriad_targets = list()
var/turf/T = get_turf(src)
for(var/mob/living/M in T)
if(!IS_CULTIST(M))
myriad_targets |= M
if(!length(myriad_targets))
for(var/mob/living/non_cultist in loc)
if(!IS_CULTIST(non_cultist))
myriad_targets += non_cultist

if(!length(myriad_targets) && !try_spawn_sword())
fail_invoke()
log_game("Offer rune failed - no eligible targets.")
return

rune_in_use = TRUE
visible_message(span_warning("[src] pulses blood red!"))
var/oldcolor = color
color = RUNE_COLOR_DARKRED
var/mob/living/L = pick(myriad_targets)

var/mob/living/F = invokers[1]
var/datum/antagonist/cult/C = F.mind.has_antag_datum(/datum/antagonist/cult,TRUE)
var/datum/team/cult/Cult_team = C.cult_team
var/is_convertable = is_convertable_to_cult(L,C.cult_team)
if(L.stat != DEAD && is_convertable)
invocation = "Mah'weyh pleggh at e'ntrath!"
..()
if(is_convertable)
do_convert(L, invokers, Cult_team)

if(length(myriad_targets))
var/mob/living/new_convertee = pick(myriad_targets)
var/mob/living/first_invoker = invokers[1]
var/datum/antagonist/cult/first_invoker_datum = first_invoker.mind.has_antag_datum(/datum/antagonist/cult)
var/datum/team/cult/cult_team = first_invoker_datum.get_team()

var/is_convertable = is_convertable_to_cult(new_convertee, cult_team)
if(new_convertee.stat != DEAD && is_convertable)
invocation = "Mah'weyh pleggh at e'ntrath!"
..()
do_convert(new_convertee, invokers, cult_team)

else
invocation = "Barhah hra zar'garis!"
..()
do_sacrifice(new_convertee, invokers, cult_team)

cult_team.check_size() // Triggers the eye glow or aura effects if the cult has grown large enough relative to the crew

else
invocation = "Barhah hra zar'garis!"
..()
do_sacrifice(L, invokers)
animate(src, color = oldcolor, time = 5)
addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_atom_colour)), 5)
Cult_team.check_size() // Triggers the eye glow or aura effects if the cult has grown large enough relative to the crew
do_invoke_glow()

animate(src, color = oldcolor, time = 0.5 SECONDS)
addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_atom_colour)), 0.5 SECONDS)
rune_in_use = FALSE

/obj/effect/rune/convert/proc/do_convert(mob/living/convertee, list/invokers, datum/team/cult/cult_team)
ASSERT(convertee.mind)

if(length(invokers) < 2)
for(var/M in invokers)
to_chat(M, span_warning("You need at least two invokers to convert [convertee]!"))
log_game("Offer rune with [convertee] on it failed - tried conversion with one invoker.")
for(var/invoker in invokers)
to_chat(invoker, span_warning("You need at least two invokers to convert [convertee]!"))
return FALSE

if(convertee.can_block_magic(MAGIC_RESISTANCE|MAGIC_RESISTANCE_HOLY, charge_cost = 0)) //No charge_cost because it can be spammed
for(var/M in invokers)
to_chat(M, span_warning("Something is shielding [convertee]'s mind!"))
log_game("Offer rune with [convertee] on it failed - convertee had anti-magic.")
for(var/invoker in invokers)
to_chat(invoker, span_warning("Something is shielding [convertee]'s mind!"))
return FALSE

var/brutedamage = convertee.getBruteLoss()
Expand Down Expand Up @@ -314,19 +320,11 @@ structure_check() searches for nearby cultist structures required for the invoca
convertee.name = convertee.real_name
return TRUE

/obj/effect/rune/convert/proc/do_sacrifice(mob/living/sacrificial, list/invokers)
var/mob/living/first_invoker = invokers[1]
if(!first_invoker)
return FALSE
var/datum/antagonist/cult/C = first_invoker.mind.has_antag_datum(/datum/antagonist/cult,TRUE)
if(!C)
return FALSE

/obj/effect/rune/convert/proc/do_sacrifice(mob/living/sacrificial, list/invokers, datum/team/cult/cult_team)
var/big_sac = FALSE
if((((ishuman(sacrificial) || iscyborg(sacrificial)) && sacrificial.stat != DEAD) || C.cult_team.is_sacrifice_target(sacrificial.mind)) && length(invokers) < 3)
for(var/M in invokers)
to_chat(M, span_cultitalic("[sacrificial] is too greatly linked to the world! You need three acolytes!"))
log_game("Offer rune with [sacrificial] on it failed - not enough acolytes and target is living or sac target")
if((((ishuman(sacrificial) || iscyborg(sacrificial)) && sacrificial.stat != DEAD) || cult_team.is_sacrifice_target(sacrificial.mind)) && length(invokers) < 3)
for(var/invoker in invokers)
to_chat(invoker, span_cultitalic("[sacrificial] is too greatly linked to the world! You need three acolytes!"))
return FALSE

var/signal_result = SEND_SIGNAL(sacrificial, COMSIG_LIVING_CULT_SACRIFICED, invokers)
Expand All @@ -335,7 +333,7 @@ structure_check() searches for nearby cultist structures required for the invoca

if(sacrificial.mind)
LAZYADD(GLOB.sacrificed, WEAKREF(sacrificial.mind))
for(var/datum/objective/sacrifice/sac_objective in C.cult_team.objectives)
for(var/datum/objective/sacrifice/sac_objective in cult_team.objectives)
if(sac_objective.target == sacrificial.mind)
sac_objective.sacced = TRUE
sac_objective.clear_sacrifice()
Expand All @@ -344,7 +342,7 @@ structure_check() searches for nearby cultist structures required for the invoca
else
LAZYADD(GLOB.sacrificed, WEAKREF(sacrificial))

new /obj/effect/temp_visual/cult/sac(get_turf(src))
new /obj/effect/temp_visual/cult/sac(loc)

if(!(signal_result & SILENCE_SACRIFICE_MESSAGE))
for(var/invoker in invokers)
Expand All @@ -357,26 +355,70 @@ structure_check() searches for nearby cultist structures required for the invoca
to_chat(invoker, span_cultlarge("\"I accept this meager sacrifice.\""))

if(iscyborg(sacrificial))
var/construct_class = show_radial_menu(first_invoker, sacrificial, GLOB.construct_radial_images, require_near = TRUE, tooltips = TRUE)
var/construct_class = show_radial_menu(invokers[1], sacrificial, GLOB.construct_radial_images, require_near = TRUE, tooltips = TRUE)
if(QDELETED(sacrificial) || !construct_class)
return FALSE
sacrificial.grab_ghost()
make_new_construct_from_class(construct_class, THEME_CULT, sacrificial, first_invoker, TRUE, get_turf(src))
make_new_construct_from_class(construct_class, THEME_CULT, sacrificial, invokers[1], TRUE, get_turf(src))
var/mob/living/silicon/robot/sacriborg = sacrificial
sacrificial.log_message("was sacrificed as a cyborg.", LOG_GAME)
sacriborg.mmi = null
qdel(sacrificial)
return TRUE
var/obj/item/soulstone/stone = new /obj/item/soulstone(get_turf(src))

var/obj/item/soulstone/stone = new(loc)
if(sacrificial.mind && !HAS_TRAIT(sacrificial, TRAIT_SUICIDED))
stone.capture_soul(sacrificial, first_invoker, TRUE)
stone.capture_soul(sacrificial, invokers[1], forced = TRUE)

if(sacrificial)
playsound(sacrificial, 'sound/magic/disintegrate.ogg', 100, TRUE)
sacrificial.investigate_log("has been sacrificially gibbed by the cult.", INVESTIGATE_DEATHS)
sacrificial.gib()

try_spawn_sword() // after sharding and gibbing, which potentially dropped a null rod
return TRUE

/// Tries to convert a null rod over the rune to a cult sword
/obj/effect/rune/convert/proc/try_spawn_sword()
for(var/obj/item/nullrod/rod in loc)
if(rod.anchored || (rod.resistance_flags & INDESTRUCTIBLE))
continue

var/num_slain = LAZYLEN(rod.cultists_slain)
var/displayed_message = "[rod] glows an unholy red and begins to transform..."
if(GET_ATOM_BLOOD_DNA_LENGTH(rod))
displayed_message += " The blood of [num_slain] fallen cultist[num_slain == 1 ? "":"s"] is absorbed into [rod]!"

rod.visible_message(span_cultitalic(displayed_message))
switch(num_slain)
if(0, 1)
animate_spawn_sword(rod, /obj/item/melee/cultblade/dagger)
if(2)
animate_spawn_sword(rod, /obj/item/melee/cultblade)
else
animate_spawn_sword(rod, /obj/item/cult_bastard)
return TRUE

return FALSE

/// Does an animation of a null rod transforming into a cult sword
/obj/effect/rune/convert/proc/animate_spawn_sword(obj/item/nullrod/former_rod, new_blade_typepath)
playsound(src, 'sound/effects/magic.ogg', 33, vary = TRUE, extrarange = SILENCED_SOUND_EXTRARANGE, frequency = 0.66)
former_rod.anchored = TRUE
former_rod.Shake()
animate(former_rod, alpha = 0, transform = matrix(former_rod.transform).Scale(0.01), time = 2 SECONDS, easing = BOUNCE_EASING, flags = ANIMATION_PARALLEL)
QDEL_IN(former_rod, 2 SECONDS)

var/obj/item/new_blade = new new_blade_typepath(loc)
var/matrix/blade_matrix_on_spawn = matrix(new_blade.transform)
new_blade.name = "converted [new_blade.name]"
new_blade.anchored = TRUE
new_blade.alpha = 0
new_blade.transform = matrix(new_blade.transform).Scale(0.01)
new_blade.Shake()
animate(new_blade, alpha = 255, transform = blade_matrix_on_spawn, time = 2 SECONDS, easing = BOUNCE_EASING, flags = ANIMATION_PARALLEL)
addtimer(VARSET_CALLBACK(new_blade, anchored, FALSE), 2 SECONDS)

/obj/effect/rune/empower
cultist_name = "Empower"
cultist_desc = "allows cultists to prepare greater amounts of blood magic at far less of a cost."
Expand Down
11 changes: 0 additions & 11 deletions code/modules/antagonists/heretic/heretic_antag.dm
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,6 @@
RegisterSignal(our_mob, COMSIG_MOB_ITEM_AFTERATTACK, PROC_REF(on_item_afterattack))
RegisterSignal(our_mob, COMSIG_MOB_LOGIN, PROC_REF(fix_influence_network))
RegisterSignal(our_mob, COMSIG_LIVING_POST_FULLY_HEAL, PROC_REF(after_fully_healed))
RegisterSignal(our_mob, COMSIG_LIVING_CULT_SACRIFICED, PROC_REF(on_cult_sacrificed))

/datum/antagonist/heretic/remove_innate_effects(mob/living/mob_override)
var/mob/living/our_mob = mob_override || owner.current
Expand All @@ -237,7 +236,6 @@
COMSIG_MOB_ITEM_AFTERATTACK,
COMSIG_MOB_LOGIN,
COMSIG_LIVING_POST_FULLY_HEAL,
COMSIG_LIVING_CULT_SACRIFICED
))

/datum/antagonist/heretic/on_body_transfer(mob/living/old_body, mob/living/new_body)
Expand Down Expand Up @@ -382,15 +380,6 @@
var/datum/heretic_knowledge/living_heart/heart_knowledge = get_knowledge(/datum/heretic_knowledge/living_heart)
heart_knowledge.on_research(source, src)

/// Signal proc for [COMSIG_LIVING_CULT_SACRIFICED] to reward cultists for sacrificing a heretic
/datum/antagonist/heretic/proc/on_cult_sacrificed(mob/living/source, list/invokers)
SIGNAL_HANDLER

new /obj/item/cult_bastard(source.loc)
for(var/mob/living/cultist as anything in invokers)
to_chat(cultist, span_cultlarge("\"A follower of the forgotten gods! You must be rewarded for such a valuable sacrifice.\""))
return SILENCE_SACRIFICE_MESSAGE

/**
* Create our objectives for our heretic.
*/
Expand Down
Loading