forked from BeeStation/BeeStation-Hornet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sacrifice_knowledge.dm
492 lines (409 loc) · 21.9 KB
/
sacrifice_knowledge.dm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
// The knowledge and process of heretic sacrificing.
/// How long we put the target so sleep for (during sacrifice).
#define SACRIFICE_SLEEP_DURATION 12 SECONDS
/// How long sacrifices must stay in the shadow realm to survive.
#define SACRIFICE_REALM_DURATION 2.5 MINUTES
/**
* Allows the heretic to sacrifice living heart targets.
*/
/datum/heretic_knowledge/hunt_and_sacrifice
name = "Heartbeat of the Mansus"
desc = "Allows you to sacrifice targets to the Mansus by bringing them to a rune in critical (or worse) condition. \
If you have no targets, stand on a transmutation rune and invoke it to aquire some."
required_atoms = list(/mob/living/carbon/human = 1)
cost = 0
priority = MAX_KNOWLEDGE_PRIORITY // Should be at the top
route = HERETIC_PATH_START
/// Whether we've generated a heretic sacrifice z-level yet, from any heretic.
var/static/heretic_level_generated = FALSE
/// If TRUE, we skip the ritual when our target list is empty. Done to avoid locking up the heretic.
var/skip_this_ritual = FALSE
/// A weakref to the mind of our heretic.
var/datum/mind/heretic_mind
/// Lazylist of minds that we won't pick as targets.
var/list/datum/mind/target_blacklist
/// An assoc list of [ref] to [timers] - a list of all the timers of people in the shadow realm currently
var/return_timers
/datum/heretic_knowledge/hunt_and_sacrifice/Destroy(force, ...)
heretic_mind = null
LAZYCLEARLIST(target_blacklist)
return ..()
/datum/heretic_knowledge/hunt_and_sacrifice/on_research(mob/user, regained = FALSE)
. = ..()
obtain_targets(user, silent = TRUE)
heretic_mind = user.mind
if(!heretic_level_generated)
heretic_level_generated = TRUE
message_admins("Generating z-level for heretic sacrifices...")
INVOKE_ASYNC(src, PROC_REF(generate_heretic_z_level))
/// Generate the sacrifice z-level.
/datum/heretic_knowledge/hunt_and_sacrifice/proc/generate_heretic_z_level()
var/datum/map_template/heretic_sacrifice_level/new_level = new()
if(!new_level.load_new_z())
message_admins("The heretic sacrifice z-level failed to load. Any heretics are gonna have a field day disemboweling people, probably. Up to you if you're fine with it.")
CRASH("Failed to initialize heretic sacrifice z-level!")
/datum/heretic_knowledge/hunt_and_sacrifice/recipe_snowflake_check(mob/living/user, list/atoms, list/selected_atoms, turf/loc)
var/datum/antagonist/heretic/heretic_datum = IS_HERETIC(user)
// First we have to check if the heretic has a Living Heart.
// You may wonder why we don't straight up prevent them from invoking the ritual if they don't have one -
// Hunt and sacrifice should always be invokable for clarity's sake, even if it'll fail immediately.
if(heretic_datum.has_living_heart() != HERETIC_HAS_LIVING_HEART)
loc.balloon_alert(user, "ritual failed, no living heart!")
return FALSE
// We've got no targets set, let's try to set some.
// If we recently failed to aquire targets, we will be unable to aquire any.
if(!LAZYLEN(heretic_datum.sac_targets))
atoms += user
return TRUE
// If we have targets, we can check to see if we can do a sacrifice
// Let's remove any humans in our atoms list that aren't a sac target
for(var/mob/living/carbon/human/sacrifice in atoms)
// If the mob's not in soft crit or worse, or isn't one of the sacrifices, remove it from the list
if(sacrifice.stat < SOFT_CRIT || !(WEAKREF(sacrifice) in heretic_datum.sac_targets))
atoms -= sacrifice
// Finally, return TRUE if we have a target in the list
if(locate(/mob/living/carbon/human) in atoms)
return TRUE
// or FALSE if we don't
loc.balloon_alert(user, "ritual failed, no sacrifice found!")
return FALSE
/datum/heretic_knowledge/hunt_and_sacrifice/on_finished_recipe(mob/living/user, list/selected_atoms, turf/loc)
var/datum/antagonist/heretic/heretic_datum = IS_HERETIC(user)
if(!LAZYLEN(heretic_datum.sac_targets))
if(obtain_targets(user))
return TRUE
else
loc.balloon_alert(user, "ritual failed, no targets found!")
return FALSE
sacrifice_process(user, selected_atoms, loc)
return TRUE
/**
* Obtain a list of targets for the user to hunt down and sacrifice.
* Tries to get four targets (minds) with living human currents.
*
* Returns FALSE if no targets are found, TRUE if the targets list was populated.
*/
/datum/heretic_knowledge/hunt_and_sacrifice/proc/obtain_targets(mob/living/user, silent = FALSE)
// First construct a list of minds that are valid objective targets.
var/list/datum/mind/valid_targets = list()
for(var/mob/player in SSticker.mode.current_players[CURRENT_LIVING_PLAYERS])
if(player.mind)
var/datum/mind/possible_target = player.mind
if(possible_target == user.mind)
continue
if(possible_target in target_blacklist)
continue
if(!ishuman(player))
continue
if(player.stat == DEAD)
continue
valid_targets += possible_target
else
continue
if(!length(valid_targets))
if(!silent)
to_chat(user,"<span class='hierophant'>No sacrifice targets could be found!</span>")
return FALSE
// Now, let's try to get four targets.
// - One completely random
// - One from your department
// - One from security
// - One from heads of staff ("high value")
var/list/datum/mind/final_targets = list()
// First target, any command.
for(var/datum/mind/head_mind as anything in shuffle_inplace(valid_targets))
if(head_mind.assigned_role in list("Captain", "Head of Personnel", "Chief Engineer", "Head of Security", "Research Director", "Chief Medical Officer"))
final_targets += head_mind
valid_targets -= head_mind
break
// Second target, any security
for(var/datum/mind/sec_mind as anything in shuffle_inplace(valid_targets))
if(sec_mind.assigned_role in list("Security Officer", "Warden", "Detective", "Head of Security", "Brig Physician", "Deputy"))
final_targets += sec_mind
valid_targets -= sec_mind
break
// Third target, someone in their department.
for(var/datum/mind/department_mind as anything in shuffle_inplace(valid_targets))
if(department_mind.assigned_role == user.mind.assigned_role)
final_targets += department_mind
valid_targets -= department_mind
break
// Final target, just get someone random.
final_targets += pick_n_take(valid_targets)
// If any of our targets failed to aquire,
// Let's run a loop until we get four total, grabbing random targets.
var/target_sanity = 0
while(length(final_targets) < 4 && length(valid_targets) > 4 && target_sanity < 25)
final_targets += pick_n_take(valid_targets)
target_sanity++
var/datum/antagonist/heretic/heretic_datum = IS_HERETIC(user)
if(!silent)
to_chat(user, "<span class='danger'>Your targets have been determined. Your Living Heart will allow you to track their position. Go forth, and sacrifice them!</span>")
for(var/datum/mind/chosen_mind as anything in final_targets)
heretic_datum.add_sacrifice_target(chosen_mind.current)
if(!silent)
to_chat(user, "<span class='danger'>[chosen_mind.current.real_name], the [chosen_mind.assigned_role].</span>")
return TRUE
/**
* Begin the process of sacrificing the target.
*
* Arguments
* * user - the mob doing the sacrifice (a heretic)
* * selected_atoms - a list of all atoms chosen. Should be (at least) one human.
* * loc - the turf the sacrifice is occuring on
*/
/datum/heretic_knowledge/hunt_and_sacrifice/proc/sacrifice_process(mob/living/user, list/selected_atoms)
var/datum/antagonist/heretic/heretic_datum = IS_HERETIC(user)
var/mob/living/carbon/human/sacrifice = locate() in selected_atoms
if(!sacrifice)
CRASH("[type] sacrifice_process didn't have a human in the atoms list. How'd it make it so far?")
if(!(WEAKREF(sacrifice) in heretic_datum.sac_targets))
CRASH("[type] sacrifice_process managed to get a non-target human. This is incorrect.")
if(sacrifice.mind)
LAZYADD(target_blacklist, sacrifice.mind)
LAZYREMOVE(heretic_datum.sac_targets, WEAKREF(sacrifice))
to_chat(user, "<span class='hypnophrase'>Your patron accepts your offer.</span>")
if(sacrifice.mind?.assigned_role in list("Captain", "Head of Personnel", "Chief Engineer", "Head of Security", "Research Director", "Chief Medical Officer"))
heretic_datum.knowledge_points++
heretic_datum.high_value_sacrifices++
heretic_datum.total_sacrifices++
heretic_datum.knowledge_points += 2
if(!begin_sacrifice(sacrifice))
disembowel_target(sacrifice)
/**
* This proc is called from [proc/sacrifice_process] after the heretic successfully sacrifices [sac_target].
*
* Sets off a chain that sends the person sacrificed to the shadow realm to dodge hands to fight for survival.
*
* Arguments
* * sac_target - the mob being sacrificed.
*/
/datum/heretic_knowledge/hunt_and_sacrifice/proc/begin_sacrifice(mob/living/carbon/human/sac_target)
. = FALSE
var/datum/antagonist/heretic/our_heretic = heretic_mind?.has_antag_datum(/datum/antagonist/heretic)
if(!our_heretic)
CRASH("[type] - begin_sacrifice was called, and no heretic [heretic_mind ? "antag datum":"mind"] could be found!")
if(!LAZYLEN(GLOB.heretic_sacrifice_landmarks))
CRASH("[type] - begin_sacrifice was called, but no heretic sacrifice landmarks were found!")
var/obj/effect/landmark/heretic/destination_landmark = GLOB.heretic_sacrifice_landmarks[our_heretic.heretic_path]
if(!destination_landmark)
CRASH("[type] - begin_sacrifice could not find a destination landmark to send the sacrifice! (heretic's path: [our_heretic.heretic_path])")
var/turf/destination = get_turf(destination_landmark)
sac_target.visible_message("<span class='danger'>[sac_target] begins to shudder violenty as dark tendrils begin to drag them into thin air!</span>")
sac_target.handcuffed = new /obj/item/restraints/handcuffs/energy/cult(sac_target)
sac_target.update_handcuffed()
sac_target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 85, 150)
sac_target.do_jitter_animation(100)
log_combat(heretic_mind.current, sac_target, "sacrificed")
if(sac_target.legcuffed)
sac_target.legcuffed.forceMove(sac_target.drop_location())
sac_target.legcuffed.dropped(sac_target)
sac_target.legcuffed = null
sac_target.update_inv_legcuffed()
addtimer(CALLBACK(sac_target, TYPE_PROC_REF(/mob/living/carbon, do_jitter_animation), 100), SACRIFICE_SLEEP_DURATION * (1/3))
addtimer(CALLBACK(sac_target, TYPE_PROC_REF(/mob/living/carbon, do_jitter_animation), 100), SACRIFICE_SLEEP_DURATION * (2/3))
// If our target is dead, try to revive them
// and if we fail to revive them, don't proceede the chain
if(!sac_target.heal_and_revive(50, "<span class='danger'>[sac_target]'s heart begins to beat with an unholy force as they return from death!</span>"))
return
if(sac_target.AdjustUnconscious(SACRIFICE_SLEEP_DURATION))
to_chat(sac_target, "<span class='hypnophrase'>Your mind feels torn apart as you fall into a shallow slumber...</span>")
else
to_chat(sac_target, "<span class='hypnophrase'>Your mind begins to tear apart as you watch dark tendrils envelop you.</span>")
sac_target.AdjustParalyzed(SACRIFICE_SLEEP_DURATION * 1.2)
sac_target.AdjustImmobilized(SACRIFICE_SLEEP_DURATION * 1.2)
addtimer(CALLBACK(src, PROC_REF(after_target_sleeps), sac_target, destination), SACRIFICE_SLEEP_DURATION * 0.5) // Teleport to the minigame
return TRUE
/**
* This proc is called from [proc/begin_sacrifice] after the [sac_target] falls asleep, shortly after the sacrifice occurs.
*
* Teleports the [sac_target] to the heretic room, asleep.
* If it fails to teleport, they will be disemboweled and stop the chain.
*
* Arguments
* * sac_target - the mob being sacrificed.
* * destination - the spot they're being teleported to.
*/
/datum/heretic_knowledge/hunt_and_sacrifice/proc/after_target_sleeps(mob/living/carbon/human/sac_target, turf/destination)
if(QDELETED(sac_target))
return
// The target disconnected or something, we shouldn't bother sending them along.
if(!sac_target.client || !sac_target.mind)
disembowel_target(sac_target)
return
// Send 'em to the destination. If the teleport fails, just disembowel them and stop the chain
if(!destination || !do_teleport(sac_target, destination, asoundin = 'sound/magic/repulse.ogg', asoundout = 'sound/magic/blind.ogg', no_effects = TRUE, channel = TELEPORT_CHANNEL_MAGIC, forced = TRUE, no_wake = TRUE))
disembowel_target(sac_target)
return
// If our target died during the (short) wait timer,
// and we fail to revive them (using a lower number than before),
// just disembowel them and stop the chain
if(!sac_target.heal_and_revive(75, "<span class='danger'>[sac_target]'s heart begins to beat with an unholy force as they return from death!</span>"))
disembowel_target(sac_target)
return
to_chat(sac_target, "<span class='big'><span class='hypnophrase'>Unnatural forces begin to claw at your very being from beyond the veil.</span></span>")
sac_target.apply_status_effect(/datum/status_effect/unholy_determination, SACRIFICE_REALM_DURATION)
addtimer(CALLBACK(src, PROC_REF(after_target_wakes), sac_target), SACRIFICE_SLEEP_DURATION * 0.5) // Begin the minigame
RegisterSignal(sac_target, COMSIG_MOVABLE_Z_CHANGED, PROC_REF(on_target_escape)) // Cheese condition
RegisterSignal(sac_target, COMSIG_MOB_DEATH, PROC_REF(on_target_death)) // Loss condition
/**
* This proc is called from [proc/after_target_sleeps] when the [sac_target] should be waking up.
*
* Begins the survival minigame, featuring the sacrifice targets.
* Gives them Helgrasp, throwing cursed hands towards them that they must dodge to survive.
* Also gives them a status effect, Unholy Determination, to help them in this endeavor.
*
* Then applies some miscellaneous effects.
*/
/datum/heretic_knowledge/hunt_and_sacrifice/proc/after_target_wakes(mob/living/carbon/human/sac_target)
if(QDELETED(sac_target))
return
// About how long should the helgrasp last? (1 metab a tick = helgrasp_time / 2 ticks (so, 1 minute = 60 seconds = 30 ticks))
var/helgrasp_time = 1 MINUTES
sac_target.reagents?.add_reagent(/datum/reagent/helgrasp/heretic, helgrasp_time / 20)
sac_target.apply_necropolis_curse(CURSE_BLINDING | CURSE_GRASPING)
SEND_SIGNAL(sac_target, COMSIG_ADD_MOOD_EVENT, "shadow_realm", /datum/mood_event/shadow_realm)
sac_target.flash_act()
sac_target.blur_eyes(15)
sac_target.Jitter(10)
sac_target.Dizzy(10)
sac_target.hallucination += 12
sac_target.emote("scream")
to_chat(sac_target, "<span class='reallybig'><span class='hypnophrase'>The grasping hands of the Mansus reveal themselves to you!</span></span>")
to_chat(sac_target, "<span class='hypnophrase'>You feel invigorated! Fight to survive!</span>")
// When it runs out, let them know they're almost home free
addtimer(CALLBACK(src, PROC_REF(after_helgrasp_ends), sac_target), helgrasp_time)
// Win condition
var/win_timer = addtimer(CALLBACK(src, PROC_REF(return_target), sac_target), SACRIFICE_REALM_DURATION, TIMER_STOPPABLE)
LAZYSET(return_timers, REF(sac_target), win_timer)
/**
* This proc is called from [proc/after_target_wakes] after the helgrasp runs out in the [sac_target].
*
* It gives them a message letting them know it's getting easier and they're almost free.
*/
/datum/heretic_knowledge/hunt_and_sacrifice/proc/after_helgrasp_ends(mob/living/carbon/human/sac_target)
if(QDELETED(sac_target) || sac_target.stat == DEAD)
return
to_chat(sac_target, "<span class='hypnophrase'>The worst is behind you... Not much longer! Hold fast, or expire!</span>")
/**
* This proc is called from [proc/begin_sacrifice] if the target survived the shadow realm, or [COMSIG_MOB_DEATH] if they don't.
*
* Teleports [sac_target] back to a random safe turf on the station (or observer spawn if it fails to find a safe turf).
* Also clears their status effects, unregisters any signals associated with the shadow realm, and sends a message
* to the heretic who did the sacrificed about whether they survived, and where they ended up.
*
* Arguments
* * sac_target - the mob being sacrificed
* * heretic - the heretic who originally did the sacrifice.
*/
/datum/heretic_knowledge/hunt_and_sacrifice/proc/return_target(mob/living/carbon/human/sac_target)
if(QDELETED(sac_target))
return
var/current_timer = LAZYACCESS(return_timers, REF(sac_target))
if(current_timer)
deltimer(current_timer)
LAZYREMOVE(return_timers, REF(sac_target))
UnregisterSignal(sac_target, COMSIG_MOVABLE_Z_CHANGED)
UnregisterSignal(sac_target, COMSIG_MOB_DEATH)
sac_target.remove_status_effect(/datum/status_effect/necropolis_curse)
sac_target.remove_status_effect(/datum/status_effect/unholy_determination)
sac_target.reagents?.del_reagent(/datum/reagent/helgrasp/heretic)
SEND_SIGNAL(sac_target, COMSIG_CLEAR_MOOD_EVENT, "shadow_realm")
// Wherever we end up, we sure as hell won't be able to explain
sac_target.slurring += 20
sac_target.cultslurring += 20
sac_target.stuttering += 20
// They're already back on the station for some reason, don't bother teleporting
if(is_station_level(sac_target.z))
return
// Teleport them to a random safe coordinate on the station z level.
var/turf/open/floor/safe_turf = find_safe_turf(extended_safety_checks = TRUE)
var/obj/effect/landmark/observer_start/backup_loc = locate(/obj/effect/landmark/observer_start) in GLOB.landmarks_list
if(!safe_turf)
safe_turf = get_turf(backup_loc)
stack_trace("[type] - return_target was unable to find a safe turf for [sac_target] to return to. Defaulting to observer start turf.")
if(!do_teleport(sac_target, safe_turf, asoundout = 'sound/magic/blind.ogg', no_effects = TRUE, channel = TELEPORT_CHANNEL_FREE, forced = TRUE, no_wake = TRUE))
safe_turf = get_turf(backup_loc)
sac_target.forceMove(safe_turf)
stack_trace("[type] - return_target was unable to teleport [sac_target] to the observer start turf. Forcemoving.")
if(sac_target.stat == DEAD)
after_return_dead_target(sac_target)
else
after_return_live_target(sac_target)
if(heretic_mind?.current)
var/composed_return_message = ""
composed_return_message += "<span class='notice'>Your victim, [sac_target], was returned to the station - </span>"
if(sac_target.stat == DEAD)
composed_return_message += "<span class='red'>dead. </span>"
else
composed_return_message += "<span class='green'>alive, but with a shattered mind. </span>"
composed_return_message += "<span class='notice'>You hear a whisper... </span>"
composed_return_message += "<span class='hypnophrase'>[get_area_name(safe_turf, TRUE)]</span>"
to_chat(heretic_mind.current, composed_return_message)
/**
* If they die in the shadow realm, they lost. Send them back.
*/
/datum/heretic_knowledge/hunt_and_sacrifice/proc/on_target_death(mob/living/carbon/human/sac_target, gibbed)
SIGNAL_HANDLER
if(gibbed) // Nothing to return
return
return_target(sac_target)
/**
* If they somehow cheese the shadow realm by teleporting out, they are disemboweled and killed.
*/
/datum/heretic_knowledge/hunt_and_sacrifice/proc/on_target_escape(mob/living/carbon/human/sac_target, old_z, new_z)
SIGNAL_HANDLER
to_chat(sac_target, "<span class='boldwarning'>Your attempt to escape the Mansus is not taken kindly!</span>")
// Ends up calling return_target() via death signal to clean up.
disembowel_target(sac_target)
/**
* This proc is called from [proc/return_target] if the [sac_target] survives the shadow realm.
*
* Gives the sacrifice target some after effects upon ariving back to reality.
*/
/datum/heretic_knowledge/hunt_and_sacrifice/proc/after_return_live_target(mob/living/carbon/human/sac_target)
to_chat(sac_target, "<span class='hypnophrase'>The fight is over, but at great cost. You have been returned to the station in one piece.</span>")
to_chat(sac_target, "<span class='big'><span class='hypnophrase'>You don't remember anything leading up to the experience - All you can think about are those horrific hands...</span></span>")
// Oh god where are we?
sac_target.flash_act()
sac_target.Jitter(60)
sac_target.blur_eyes(50)
sac_target.Dizzy(30)
sac_target.AdjustKnockdown(80)
sac_target.adjustStaminaLoss(120)
// Glad i'm outta there, though!
SEND_SIGNAL(sac_target, COMSIG_ADD_MOOD_EVENT, "shadow_realm_survived", /datum/mood_event/shadow_realm_live)
SEND_SIGNAL(sac_target, COMSIG_ADD_MOOD_EVENT, "shadow_realm_survived_sadness", /datum/mood_event/shadow_realm_live_sad)
// Could use a little pick-me-up...
sac_target.reagents?.add_reagent(/datum/reagent/medicine/atropine, 8)
sac_target.reagents?.add_reagent(/datum/reagent/medicine/epinephrine, 8)
/**
* This proc is called from [proc/return_target] if the target dies in the shadow realm.
*
* After teleporting the target back to the station (dead),
* it spawns a special red broken illusion on their spot, for style.
*/
/datum/heretic_knowledge/hunt_and_sacrifice/proc/after_return_dead_target(mob/living/carbon/human/sac_target)
to_chat(sac_target, "<span class='hypnophrase'>You failed to resist the horrors of the Mansus! Your ruined body has been returned to the station.</span>")
to_chat(sac_target, "<span class='big'><span class='hypnophrase'>The experience leaves your mind torn and memories tattered. You will not remember anything leading up to the experience if revived.</span></span>")
var/obj/effect/visible_heretic_influence/illusion = new(get_turf(sac_target))
illusion.name = "\improper weakened rift in reality"
illusion.desc = "A rift wide enough for something... or someone... to come through."
illusion.color = COLOR_DARK_RED
/**
* "Fuck you" proc that gets called if the chain is interrupted at some points.
* Disembowels the [sac_target] and brutalizes their body. Throws some gibs around for good measure.
*/
/datum/heretic_knowledge/hunt_and_sacrifice/proc/disembowel_target(mob/living/carbon/human/sac_target)
if(heretic_mind)
log_combat(heretic_mind.current, sac_target, "disemboweled via sacrifice")
sac_target.spill_organs()
sac_target.apply_damage(250, BRUTE)
if(sac_target.stat != DEAD)
sac_target.investigate_log("has been killed by heretic sacrifice.", INVESTIGATE_DEATHS)
sac_target.death()
sac_target.visible_message(
"<span class='danger'>[sac_target]'s organs are pulled out of [sac_target.p_their()] chest by shadowy hands!</span>",
"<span class='userdanger'>Your organs are violently pulled out of your chest by shadowy hands!</span>"
)
new /obj/effect/gibspawner/human/bodypartless(get_turf(sac_target))