mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-20 03:25:49 +01:00
Reworks cult sharding to not perma kill mindshielded victims [Needs TM] (#20402)
* fucking cult * WERE STILL WORKING ON ITTTT * d * Revert "d" This reverts commit8a4bf06f5c. * MOREEEE * update * Revert "update" This reverts commit65d85eae87. * only chap can do it now lmao * WHOOPS * OK NOW * Update runes.dm * Apply suggestions from code review Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com> * PLEASE TESTMERGE AAA * fixes some stuff, improves it * fixes the code from merge conflict * Update code/game/gamemodes/wizard/soulstone.dm Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com> * fixes a bug with shit not dying due to brains * Adds some GC stuff, Sirr's code reviews. * finishes the last changes and reviews * missed 1 --------- Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com> Co-authored-by: Ryan <80364400+Sirryan2002@users.noreply.github.com>
This commit is contained in:
@@ -199,6 +199,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
#define TRAIT_ELITE_CHALLENGER "elite_challenger"
|
||||
#define TRAIT_SOAPY_MOUTH "soapy_mouth"
|
||||
#define TRAIT_UNREVIVABLE "unrevivable" // Prevents changeling revival
|
||||
#define TRAIT_CULT_IMMUNITY "cult_immunity"
|
||||
#define TRAIT_FLATTENED "flattened"
|
||||
|
||||
//***** ITEM AND MOB TRAITS *****//
|
||||
|
||||
@@ -70,6 +70,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_ELITE_CHALLENGER" = TRAIT_ELITE_CHALLENGER,
|
||||
"TRAIT_SOAPY_MOUTH" = TRAIT_SOAPY_MOUTH,
|
||||
"TRAIT_UNREVIVABLE" = TRAIT_UNREVIVABLE,
|
||||
"TRAIT_CULT_IMMUNITY" = TRAIT_CULT_IMMUNITY,
|
||||
"TRAIT_SHOW_WIRE_INFO" = TRAIT_SHOW_WIRE_INFO,
|
||||
"TRAIT_CAN_BE_EATEN_BY_LIZARDS" = TRAIT_EDIBLE_BUG,
|
||||
"TRAIT_FLATTENED" = TRAIT_FLATTENED
|
||||
|
||||
@@ -211,6 +211,13 @@ GLOBAL_LIST_EMPTY(all_cults)
|
||||
cultist.visible_message("<span class='cult'>[cultist] looks like [cultist.p_they()] just reverted to [cultist.p_their()] old faith!</span>",
|
||||
"<span class='userdanger'>An unfamiliar white light flashes through your mind, cleansing the taint of [SSticker.cultdat ? SSticker.cultdat.entity_title1 : "Nar'Sie"] and the memories of your time as their servant with it.</span>")
|
||||
|
||||
/datum/game_mode/proc/add_cult_immunity(mob/living/target)
|
||||
ADD_TRAIT(target, TRAIT_CULT_IMMUNITY, CULT_TRAIT)
|
||||
addtimer(CALLBACK(src, PROC_REF(remove_cult_immunity), target), 1 MINUTES)
|
||||
|
||||
/datum/game_mode/proc/remove_cult_immunity(mob/living/target)
|
||||
REMOVE_TRAIT(target, TRAIT_CULT_IMMUNITY, CULT_TRAIT)
|
||||
|
||||
|
||||
/**
|
||||
* Decides at the start of the round how many conversions are needed to rise/ascend.
|
||||
|
||||
@@ -229,9 +229,9 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
animate(src, transform = matrix() * 2, alpha = 0, time = 5) // Fade out
|
||||
animate(transform = oldtransform, alpha = 255, time = 0)
|
||||
|
||||
/obj/effect/rune/proc/fail_invoke()
|
||||
/obj/effect/rune/proc/fail_invoke(show_message = TRUE)
|
||||
//This proc contains the effects of a rune if it is not invoked correctly, through either invalid wording or not enough cultists. By default, it's just a basic fizzle.
|
||||
if(!invisibility) // No visible messages if not visible
|
||||
if(!invisibility && show_message) // No visible messages if not visible
|
||||
visible_message("<span class='warning'>The markings pulse with a small flash of red light, then fall dark.</span>")
|
||||
animate(src, color = rgb(255, 0, 0), time = 0)
|
||||
animate(src, color = rune_blood_color, time = 5)
|
||||
@@ -295,7 +295,6 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
for(var/obj/item/organ/internal/brain/brain in H.contents)
|
||||
b_mob = brain.brainmob
|
||||
brain.forceMove(T)
|
||||
O = brain // Convoluted way of making the brain disappear
|
||||
|
||||
else if(istype(O, /obj/item/organ/internal/brain)) // Offering a brain
|
||||
var/obj/item/organ/internal/brain/brain = O
|
||||
@@ -303,7 +302,6 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
|
||||
if(b_mob && b_mob.mind && (!iscultist(b_mob) || is_sacrifice_target(b_mob.mind)))
|
||||
offer_targets += b_mob
|
||||
O.invisibility = INVISIBILITY_MAXIMUM // So that it can't be moved around. This gets qdeleted later
|
||||
|
||||
if(!length(offer_targets))
|
||||
fail_invoke()
|
||||
@@ -313,8 +311,10 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
|
||||
rune_in_use = TRUE
|
||||
var/mob/living/L = pick(offer_targets)
|
||||
if(L.mind in GLOB.sacrificed)
|
||||
fail_invoke()
|
||||
if(HAS_TRAIT(L, TRAIT_CULT_IMMUNITY))
|
||||
fail_invoke(FALSE)
|
||||
for(var/I in invokers)
|
||||
to_chat(I, "<span class='warning'>This sacrifice was already converted recently. Wait a minute before trying again!</span>")
|
||||
rune_in_use = FALSE
|
||||
return
|
||||
|
||||
@@ -325,8 +325,6 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
invocation = "Barhah hra zar'garis!"
|
||||
..()
|
||||
do_sacrifice(L, invokers)
|
||||
if(isbrain(L))
|
||||
qdel(L.loc) // Don't need this anymore!
|
||||
rune_in_use = FALSE
|
||||
|
||||
/obj/effect/rune/convert/proc/do_convert(mob/living/convertee, list/invokers)
|
||||
@@ -389,6 +387,15 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
var/sacrifice_fulfilled
|
||||
var/worthless = FALSE
|
||||
var/datum/game_mode/gamemode = SSticker.mode
|
||||
|
||||
if(isliving(offering) && !isbrain(offering))
|
||||
var/mob/living/L = offering
|
||||
if(isrobot(L) || ismachineperson(L))
|
||||
L.adjustBruteLoss(250)
|
||||
else
|
||||
L.adjustCloneLoss(120)
|
||||
L.death(FALSE)
|
||||
|
||||
if(offering.mind)
|
||||
GLOB.sacrificed += offering.mind
|
||||
if(is_sacrifice_target(offering.mind))
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
slot_flags = SLOT_BELT
|
||||
origin_tech = "bluespace=4;materials=5"
|
||||
|
||||
/// The body/brain of the player inside this construct, transferred over from the soulstone.
|
||||
var/atom/movable/held_body
|
||||
/// Does this soulstone ask the victim whether they want to be turned into a shade
|
||||
var/optional = FALSE
|
||||
/// Can this soul stone be used by anyone, or only cultists/wizards?
|
||||
@@ -24,11 +26,19 @@
|
||||
var/opt_in = FALSE
|
||||
var/purified = FALSE
|
||||
|
||||
/obj/item/soulstone/proc/add_held_body(atom/movable/body)
|
||||
held_body = body
|
||||
RegisterSignal(body, COMSIG_PARENT_QDELETING, PROC_REF(remove_held_body))
|
||||
|
||||
/obj/item/soulstone/proc/remove_held_body()
|
||||
SIGNAL_HANDLER
|
||||
held_body = null
|
||||
|
||||
/obj/item/soulstone/proc/can_use(mob/living/user)
|
||||
if(iscultist(user) && purified && !iswizard(user))
|
||||
return FALSE
|
||||
|
||||
if(iscultist(user) || iswizard(user) || usability)
|
||||
if(iscultist(user) || iswizard(user) || (user.mind?.isholy && purified))
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
@@ -58,12 +68,17 @@
|
||||
. = ..()
|
||||
if(iscultist(user) && purified && !iswizard(user))
|
||||
to_chat(user, "<span class='danger'>[src] reeks of holy magic. You will need to cleanse it with a ritual dagger before anything can be done with it.</span>")
|
||||
return
|
||||
if(user.mind?.isholy)
|
||||
to_chat(user, "<span class='danger'>An overwhelming feeling of dread comes over you as you pick up [src]. It looks fragile enough to break with your hands.</span>")
|
||||
return
|
||||
if(!can_use(user))
|
||||
to_chat(user, "<span class='danger'>An overwhelming feeling of dread comes over you as you pick up [src].</span>")
|
||||
|
||||
/obj/item/soulstone/Destroy() //Stops the shade from being qdel'd immediately and their ghost being sent back to the arrival shuttle.
|
||||
for(var/mob/living/simple_animal/shade/A in src)
|
||||
A.death()
|
||||
remove_held_body()
|
||||
return ..()
|
||||
|
||||
//////////////////////////////Capturing////////////////////////////////////////////////////////
|
||||
@@ -200,17 +215,35 @@
|
||||
..()
|
||||
|
||||
/obj/item/soulstone/attack_self(mob/living/user)
|
||||
if(!in_range(src, user))
|
||||
var/mob/living/simple_animal/shade/S = locate(/mob/living/simple_animal/shade) in contents
|
||||
if(!in_range(src, user) || !S)
|
||||
return
|
||||
|
||||
if(!can_use(user))
|
||||
user.Weaken(10 SECONDS)
|
||||
user.emote("scream")
|
||||
to_chat(user, "<span class='userdanger'>Your body is wracked with debilitating pain!</span>")
|
||||
if(can_use(user))
|
||||
release_shades(user)
|
||||
return
|
||||
|
||||
release_shades(user)
|
||||
return
|
||||
if(!user.mind.isholy)
|
||||
to_chat(user, "<span class='notice'>The shard feels too tough to shatter, you are not holy enough to free its captive!</span>")
|
||||
return
|
||||
|
||||
if(!do_after_once(user, 10 SECONDS, FALSE, src) || !held_body)
|
||||
return
|
||||
|
||||
user.visible_message("[user] shatters the soulstone apart! Releasing [held_body] from their prison!", "You shatter the soulstone holding [held_body], binding them free!", "You hear something shatter with a ghastly crack.")
|
||||
if(ismob(held_body))
|
||||
var/mob/M = held_body
|
||||
M.key = S.key
|
||||
else if(istype(held_body, /obj/item/organ/internal/brain))
|
||||
var/obj/item/organ/internal/brain/B = held_body
|
||||
B.brainmob.key = S.key
|
||||
S.cancel_camera()
|
||||
held_body.forceMove(get_turf(src))
|
||||
SSticker.mode.add_cult_immunity(held_body)
|
||||
remove_held_body()
|
||||
new /obj/effect/temp_visual/cult/sparks(get_turf(src))
|
||||
playsound(src, 'sound/effects/pylon_shatter.ogg', 40, TRUE)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/soulstone/proc/release_shades(mob/user)
|
||||
for(var/mob/living/simple_animal/shade/A in src)
|
||||
@@ -270,7 +303,8 @@
|
||||
to_chat(user, "<span class='userdanger'>Capture failed!</span> The soul has already fled its mortal frame. You attempt to bring it back...")
|
||||
T.Paralyse(40 SECONDS)
|
||||
if(!get_cult_ghost(T, user, TRUE))
|
||||
T.dust() //If we can't get a ghost, kill the sacrifice anyway.
|
||||
add_held_body(T)
|
||||
T.forceMove(src) //If we can't get a ghost, shard the body anyways.
|
||||
|
||||
if("VICTIM")
|
||||
var/mob/living/carbon/human/T = target
|
||||
@@ -300,7 +334,7 @@
|
||||
if((iscultist(T) && purified) || (T.holy && !purified))
|
||||
to_chat(user, "<span class='danger'>Capture failed!</span> The shade recoils away from [src]!")
|
||||
else
|
||||
if(length(contents))
|
||||
if(locate(/mob/living/simple_animal/shade) in contents)
|
||||
to_chat(user, "<span class='danger'>Capture failed!</span>: The soul stone is full! Use or free an existing soul to make room.")
|
||||
else
|
||||
T.forceMove(src) // Put the shade into the stone.
|
||||
@@ -360,6 +394,9 @@
|
||||
to_chat(src, "<span class='userdanger'>You are still bound to serve the cult, follow their orders and help them complete their goals at all costs.</span>")
|
||||
else
|
||||
to_chat(src, "<span class='userdanger'>You are still bound to serve your creator, follow their orders and help them complete their goals at all costs.</span>")
|
||||
SS.held_body.forceMove(src)
|
||||
add_held_body(SS.held_body)
|
||||
SS.remove_held_body()
|
||||
cancel_camera()
|
||||
qdel(shell)
|
||||
qdel(shade)
|
||||
@@ -405,12 +442,16 @@
|
||||
to_chat(S, "<span class='userdanger'>Your soul has been captured! You are now bound to [user.real_name]'s will. Help them succeed in their goals at all costs.</span>")
|
||||
if(forced && user)
|
||||
to_chat(user, "<span class='info'><b>Capture successful!</b>:</span> [M.real_name]'s soul has been ripped from [user.p_their()] body and stored within the soul stone.")
|
||||
if(isrobot(M))//Robots have to dust or else they spill out an empty robot brain, and unequiping them spills robot components that shouldn't spawn.
|
||||
M.dust()
|
||||
else
|
||||
if(!isrobot(M))
|
||||
for(var/obj/item/I in M)
|
||||
M.unEquip(I)
|
||||
M.dust()
|
||||
if(isbrain(M))
|
||||
var/obj/item/organ/internal/brain/brain_obj = M.loc
|
||||
add_held_body(brain_obj)
|
||||
brain_obj.forceMove(src)
|
||||
else
|
||||
add_held_body(M)
|
||||
M.forceMove(src)
|
||||
|
||||
/obj/item/soulstone/proc/get_shade_type()
|
||||
if(purified)
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
del_on_death = TRUE
|
||||
deathmessage = "collapses in a shattered heap."
|
||||
var/construct_type = "shade"
|
||||
/// The body/brain of the player inside this construct, transferred over from the soulstone.
|
||||
var/mob/living/held_body
|
||||
var/list/construct_spells = list()
|
||||
/// Is this a holy/purified construct?
|
||||
var/holy = FALSE
|
||||
@@ -50,9 +52,34 @@
|
||||
|
||||
set_light(2, 3, l_color = SSticker.cultdat ? SSticker.cultdat.construct_glow : LIGHT_COLOR_BLOOD_MAGIC)
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/Destroy()
|
||||
remove_held_body()
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/death(gibbed)
|
||||
. = ..()
|
||||
SSticker.mode.remove_cultist(show_message = FALSE, target_mob = src)
|
||||
if(held_body) // Null check for empty bodies
|
||||
held_body.forceMove(get_turf(src))
|
||||
SSticker.mode.add_cult_immunity(held_body)
|
||||
if(ismob(held_body)) // Check if the held_body is a mob
|
||||
held_body.key = key
|
||||
else if(istype(held_body, /obj/item/organ/internal/brain)) // Check if the held_body is a brain
|
||||
var/obj/item/organ/internal/brain/brain = held_body
|
||||
if(brain.brainmob) // Check if the brain has a brainmob
|
||||
brain.brainmob.key = key // Set the key to the brainmob
|
||||
brain.brainmob.mind.transfer_to(brain.brainmob) // Transfer the mind to the brainmob
|
||||
held_body.cancel_camera()
|
||||
new /obj/effect/temp_visual/cult/sparks(get_turf(src))
|
||||
playsound(src, 'sound/effects/pylon_shatter.ogg', 40, TRUE)
|
||||
. = ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/proc/add_held_body(atom/movable/body)
|
||||
held_body = body
|
||||
RegisterSignal(body, COMSIG_PARENT_QDELETING, PROC_REF(remove_held_body))
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/proc/remove_held_body()
|
||||
SIGNAL_HANDLER
|
||||
held_body = null
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/examine(mob/user)
|
||||
. = ..()
|
||||
|
||||
Reference in New Issue
Block a user