Skip to content

Commit

Permalink
Merge pull request #964 from KnigTheThrasher/sord
Browse files Browse the repository at this point in the history
[PORT] Changes how Cultists obtain the bastard sword. Instead of sacrificing Heretics, you now sacrifice Null Rods, with a caveat.
  • Loading branch information
wraith-54321 authored Jan 27, 2024
2 parents 86cce5e + c9e586b commit add65fd
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 58 deletions.
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

0 comments on commit add65fd

Please sign in to comment.