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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bloodcult endgame changes #8325

Merged
merged 14 commits into from Jun 1, 2020
Merged
97 changes: 97 additions & 0 deletions code/game/gamemodes/cult/cult.dm
Expand Up @@ -2,6 +2,10 @@

/datum/game_mode
var/list/datum/mind/cult = list()
var/list/bloodstone_list = list()
var/anchor_bloodstone
var/anchor_time2kill = 5 MINUTES
var/bloodstone_cooldown = FALSE

/proc/iscultist(mob/living/M)
return istype(M) && M.mind && M.mind.has_antag_datum(/datum/antagonist/cult)
Expand Down Expand Up @@ -164,4 +168,97 @@
devoted to stopping this cult. Note that holy water seems to weaken and eventually return the minds of cultists that ingest it, and mindshield implants will prevent conversion \
altogether."

/datum/game_mode/proc/begin_bloodstone_phase()
for(var/i = 0, i < 4, i++) //four bloodstones
var/spawnpoint = get_turf(pick(GLOB.generic_event_spawns))
new /obj/structure/destructible/cult/bloodstone(spawnpoint)
var/list/bloodstone_areas = list()
for(var/obj/structure/destructible/cult/bloodstone/B in bloodstone_list)
var/area/A = get_area(B)
bloodstone_areas.Add(A.map_name)
priority_announce("Figments of an eldritch god are being pulled through the veil anomaly in [bloodstone_areas[1]], [bloodstone_areas[2]], [bloodstone_areas[3]], and [bloodstone_areas[4]]! Destroy any occult structures located in those areas!","Central Command Higher Dimensional Affairs")
addtimer(CALLBACK(src, .proc/increase_bloodstone_power), 300)
SomeguyManperson marked this conversation as resolved.
Show resolved Hide resolved

/datum/game_mode/proc/increase_bloodstone_power()
if(!bloodstone_list.len) //check if we somehow ran out of bloodstones
return
for(var/obj/structure/destructible/cult/bloodstone/B in bloodstone_list)
if(B.current_fullness == 9)
create_anchor_bloodstone()
return //We're done here
else
B.current_fullness++
B.update_icon()
addtimer(CALLBACK(src, .proc/increase_bloodstone_power), 300)
SomeguyManperson marked this conversation as resolved.
Show resolved Hide resolved

/datum/game_mode/proc/create_anchor_bloodstone()
if(SSticker.mode.anchor_bloodstone)
return
var/obj/structure/destructible/cult/bloodstone/anchor_target = bloodstone_list[1] //which bloodstone is the current cantidate for anchorship
var/anchor_power = 0 //anchor will be faster if there are more stones
for(var/obj/structure/destructible/cult/bloodstone/B in bloodstone_list)
anchor_power++
if(B.obj_integrity > anchor_target.obj_integrity)
anchor_target = B
SSticker.mode.anchor_bloodstone = anchor_target
anchor_target.name = "anchor bloodstone"
anchor_target.desc = "It pulses rythmetically with migrane-inducing light. Something is being reflected on every surface, something that isn't quite there..."
anchor_target.anchor = TRUE
anchor_target.max_integrity = 1200
anchor_target.obj_integrity = 1200
Comment on lines +207 to +208
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isnt that a bit.. much

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be doable, especially if the crew has already bashed a few stones before that stage. In the only test where there was competition the crew was able to take it down after breaking the other 3 stones

anchor_time2kill -= anchor_power * 1 MINUTES //one minute of bloodfuckery shaved off per surviving bloodstone.
anchor_target.set_animate()
var/area/A = get_area(anchor_target)
addtimer(CALLBACK(anchor_target, /obj/structure/destructible/cult/bloodstone.proc/summon), anchor_time2kill)
priority_announce("The anomaly has weakened the veil to a hazardous level in [A.map_name]! Destroy whatever is causing it before something gets through!","Central Command Higher Dimensional Affairs")

/datum/game_mode/proc/cult_loss_bloodstones()
priority_announce("The veil anomaly appears to have been destroyed, shuttle locks have been lifted.","Central Command Higher Dimensional Affairs")
bloodstone_cooldown = TRUE
addtimer(CALLBACK(src, .proc/disable_bloodstone_cooldown), 3000) //5 minutes
SomeguyManperson marked this conversation as resolved.
Show resolved Hide resolved
for(var/datum/mind/M in cult)
var/mob/living/cultist = M.current
if(!cultist)
continue
cultist.playsound_local(cultist, 'sound/magic/demon_dies.ogg', 75, FALSE)
if(isconstruct(cultist))
to_chat(cultist, "<span class='cultbold'>You feel your form lose some of its density, becoming more fragile!</span>")
cultist.maxHealth *= 0.75
cultist.health *= 0.75
else
cultist.Stun(20)
cultist.confused += 15 //30 seconds of confusion
to_chat(cultist, "<span class='narsiesmall'>Your mind is flooded with pain as the last bloodstone is destroyed!</span>")

/datum/game_mode/proc/cult_loss_anchor()
priority_announce("Whatever you did worked. Veil density has returned to a safe level. Shuttle locks lifted.","Central Command Higher Dimensional Affairs")
bloodstone_cooldown = TRUE
addtimer(CALLBACK(src, .proc/disable_bloodstone_cooldown), 4200) //7 minutes
SomeguyManperson marked this conversation as resolved.
Show resolved Hide resolved
for(var/obj/structure/destructible/cult/bloodstone/B in bloodstone_list)
qdel(B)
for(var/datum/mind/M in cult)
var/mob/living/cultist = M.current
if(!cultist)
continue
cultist.playsound_local(cultist, 'sound/effects/screech.ogg', 75, FALSE)
if(isconstruct(cultist))
to_chat(cultist, "<span class='cultbold'>You feel your form lose most of its density, becoming incredibly fragile!</span>")
cultist.maxHealth *= 0.5
cultist.health *= 0.5
else
cultist.Stun(40)
cultist.confused += 30 //one minute of confusion
to_chat(cultist, "<span class='narsiesmall'>You feel a bleakness as the destruction of the anchor cuts off your connection to Nar-Sie!</span>")

/datum/game_mode/proc/disable_bloodstone_cooldown()
bloodstone_cooldown = FALSE
for(var/datum/mind/M in cult)
var/mob/living/L = M.current
if(L)
to_chat(M, "<span class='narsiesmall'>The veil has weakened enough for another attempt, prepare the summoning!</span>")
if(isconstruct(L))
L.maxHealth = initial(L.maxHealth)
to_chat(L, "<span class='cult'>Your form regains its original durability!</span>")
//send message to cultists saying they can do stuff again

#undef CULT_SCALING_COEFFICIENT
254 changes: 254 additions & 0 deletions code/modules/antagonists/cult/cult_structures.dm
Expand Up @@ -6,6 +6,7 @@
var/cooldowntime = 0
break_sound = 'sound/hallucinations/veryfar_noise.ogg'
debris = list(/obj/item/stack/sheet/runed_metal = 1)
var/is_endgame = FALSE //is the structure part of the endgame? stuff that can't be healed/moved have this set to TRUE

/obj/structure/destructible/cult/proc/conceal() //for spells that hide cult presence
density = FALSE
Expand Down Expand Up @@ -42,6 +43,8 @@
return ..()

/obj/structure/destructible/cult/attack_animal(mob/living/simple_animal/M)
if(is_endgame && iscultist(M))
return FALSE //no smash or healing
if(istype(M, /mob/living/simple_animal/hostile/construct/builder))
if(obj_integrity < max_integrity)
M.changeNext_move(CLICK_CD_MELEE)
Expand All @@ -54,7 +57,14 @@
else
..()

/obj/structure/destructible/cult/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
if(iscultist(user) && is_endgame)
return FALSE
return ..()

/obj/structure/destructible/cult/attackby(obj/I, mob/user, params)
if(is_endgame && iscultist(user))
return FALSE
if(istype(I, /obj/item/melee/cultblade/dagger) && iscultist(user))
anchored = !anchored
to_chat(user, "<span class='notice'>You [anchored ? "":"un"]secure \the [src] [anchored ? "to":"from"] the floor.</span>")
Expand Down Expand Up @@ -262,6 +272,250 @@
new N(get_turf(src))
to_chat(user, "<span class='cultitalic'>You summon the [choice] from the archives!</span>")

/////////////////////////////WE'RE IN THE ENDGAME NOW/////////////////////////////
/obj/structure/destructible/cult/pillar
name = "obsidian pillar"
icon_state = "pillar-enter"
icon = 'icons/obj/cult_64x64.dmi'
pixel_x = -16
obj_integrity = 200
max_integrity = 200
break_sound = 'sound/effects/meteorimpact.ogg'
break_message = "<span class='warning'>The pillar crumbles!</span>"
layer = MASSIVE_OBJ_LAYER
var/alt = 0
is_endgame = TRUE

/obj/structure/destructible/cult/pillar/New()
SomeguyManperson marked this conversation as resolved.
Show resolved Hide resolved
..()
var/turf/T = loc
if (!T)
qdel(src)
return
for (var/obj/O in loc)
if(O == src)
continue
O.ex_act(2)
if(!QDELETED(O) && (istype(O, /obj/structure) || istype(O, /obj/machinery)))
qdel(O)
T.narsie_act()

/obj/structure/destructible/cult/pillar/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir, armour_penetration = 0)
..()
update_icon()

/obj/structure/destructible/cult/pillar/Destroy()
new /obj/effect/decal/cleanable/ash(loc)
..()

/obj/structure/destructible/cult/pillar/alt
icon_state = "pillaralt-enter"
alt = 1
SomeguyManperson marked this conversation as resolved.
Show resolved Hide resolved

/obj/structure/destructible/cult/pillar/update_icon()
icon_state = "pillar[alt ? "alt": ""]2"
overlays.len = 0
alexkar598 marked this conversation as resolved.
Show resolved Hide resolved
if (obj_integrity < max_integrity/3)
icon_state = "pillar[alt ? "alt": ""]0"
else if (obj_integrity < 2*max_integrity/3)
icon_state = "pillar[alt ? "alt": ""]1"

/obj/structure/destructible/cult/pillar/conceal()
return

/obj/structure/destructible/cult/pillar/ex_act(var/severity)
switch(severity)
if (1)
SomeguyManperson marked this conversation as resolved.
Show resolved Hide resolved
take_damage(200)
if (2)
SomeguyManperson marked this conversation as resolved.
Show resolved Hide resolved
take_damage(100)
if (3)
SomeguyManperson marked this conversation as resolved.
Show resolved Hide resolved
take_damage(20)

/obj/structure/destructible/cult/bloodstone
name = "bloodstone"
desc = "A large, red stone filling with... something. You get a headache even being near it."
icon_state = "bloodstone-enter1"
icon = 'icons/obj/cult_64x64.dmi'
pixel_x = -16
obj_integrity = 600
max_integrity = 600
break_sound = 'sound/effects/glassbr2.ogg'
break_message = "<span class='warning'>The bloodstone resonates violently before crumbling to the floor!</span>"
layer = MASSIVE_OBJ_LAYER
light_color = "#FF0000"
var/current_fullness = 0
var/anchor = FALSE //are we the bloodstone used to summon nar-sie? used in the final part of the summoning
is_endgame = TRUE

/obj/structure/destructible/cult/bloodstone/New()
SomeguyManperson marked this conversation as resolved.
Show resolved Hide resolved
..()
if (!src.loc)
message_admins("Blood Cult: A blood stone was somehow spawned in nullspace. It has been destroyed.")
qdel(src)
SSshuttle.registerHostileEnvironment(src)
SSticker.mode.bloodstone_list.Add(src)
for (var/obj/O in loc)
if (O != src)
O.ex_act(2)
safe_space()
set_light(3)
for(var/mob/M in GLOB.player_list)
if (M.z == z && M.client)
if (get_dist(M,src)<=20)
M.playsound_local(src, get_sfx("explosion"), 50, 1)
shake_camera(M, 4, 1)
else
M.playsound_local(src, 'sound/effects/explosionfar.ogg', 50, 1)
shake_camera(M, 1, 1)

spawn(10)
var/list/pillars = list()
icon_state = "bloodstone-enter2"
for(var/mob/M in GLOB.player_list)
if (M.z == z && M.client)
if (get_dist(M,src)<=20)
M.playsound_local(src, get_sfx("explosion"), 50, 1)
shake_camera(M, 4, 1)
else
M.playsound_local(src, 'sound/effects/explosionfar.ogg', 50, 1)
shake_camera(M, 1, 1)
var/turf/T1 = locate(x-2,y-2,z)
pillars += new /obj/structure/destructible/cult/pillar(T1)
var/turf/T2 = locate(x+2,y-2,z)
pillars += new /obj/structure/destructible/cult/pillar/alt(T2)
var/turf/T3 = locate(x-2,y+2,z)
pillars += new /obj/structure/destructible/cult/pillar(T3)
var/turf/T4 = locate(x+2,y+2,z)
pillars += new /obj/structure/destructible/cult/pillar/alt(T4)
sleep(10)
icon_state = "bloodstone-enter3"
for(var/mob/M in GLOB.player_list)
if (M.z == z && M.client)
if (get_dist(M,src)<=20)
M.playsound_local(src, get_sfx("explosion"), 50, 1)
shake_camera(M, 4, 1)
else
M.playsound_local(src, 'sound/effects/explosionfar.ogg', 50, 1)
shake_camera(M, 1, 1)
for (var/obj/structure/destructible/cult/pillar/P in pillars)
P.update_icon()

/obj/structure/destructible/cult/bloodstone/proc/summon()
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF //should stop the stone from being destroyed by damage
sound_to_playing_players('sound/effects/dimensional_rend.ogg')
sleep(40)
new /obj/singularity/narsie/large/cult(loc)

/obj/structure/destructible/cult/bloodstone/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir, armour_penetration = 0)
..()
update_icon()

/obj/structure/destructible/cult/bloodstone/ex_act(var/severity)
switch(severity)
if (1)
take_damage(200)
if (2)
take_damage(100)
if (3)
take_damage(20)

/obj/structure/destructible/cult/bloodstone/Destroy()
for(var/mob/M in range(7, loc))
M.playsound_local(M, 'sound/creatures/legion_death.ogg', 75, FALSE) //make it suitably loud
SSticker.mode.bloodstone_list.Remove(src)
SSshuttle.clearHostileEnvironment(src)
for(var/datum/mind/B in SSticker.mode.cult)
if(B.current)
SEND_SOUND(B.current, 'sound/magic/demon_dies.ogg')
if(SSticker.mode.bloodstone_list.len)
to_chat(B.current, "<span class='cultlarge'>The Bloodstone in [get_area(src)] has been destroyed! There are [SSticker.mode.bloodstone_list.len] Bloodstones remaining!.</span>")
new /obj/effect/decal/cleanable/ash(loc)
new /obj/item/ectoplasm(loc)
new /obj/structure/destructible/dead_bloodstone(loc)

if(!(locate(/obj/singularity/narsie) in GLOB.poi_list) && (!SSticker.mode.bloodstone_cooldown && SSticker.mode.bloodstone_list.len <= 0 || anchor))
if(anchor)
SSticker.mode.anchor_bloodstone = null
SSticker.mode.cult_loss_anchor()
else
SSticker.mode.cult_loss_bloodstones()
..()

/obj/structure/destructible/cult/bloodstone/mech_melee_attack(obj/mecha/M)
M.force = round(M.force/6, 1) //damage is reduced since mechs deal triple damage to objects, this sets gygaxes to 15 (5*3) damage and durands to 21 (7*3) damage
. = ..()
M.force = initial(M.force)

/obj/structure/destructible/cult/bloodstone/hulk_damage()
return 15 //no

/obj/structure/destructible/cult/bloodstone/proc/safe_space()
for(var/turf/T in range(5,src))
var/dist = get_dist(src, T)
if (dist <= 2)
T.ChangeTurf(/turf/open/floor/engine/cult)
for (var/obj/structure/S in T)
if(!istype(S,/obj/structure/destructible/cult))
S.ex_act(1)
for (var/obj/machinery/M in T)
qdel(M)
else if (dist <= 4)
if (istype(T,/turf/open/space))
T.ChangeTurf(/turf/open/floor/engine/cult)
else
T.narsie_act(TRUE, TRUE)
else if (dist <= 5)
if (istype(T,/turf/open/space))
T.ChangeTurf(/turf/closed/wall/mineral/cult)
else
T.narsie_act(TRUE, TRUE)

/obj/structure/destructible/cult/bloodstone/update_icon()
icon_state = "bloodstone-[current_fullness]"
overlays.len = 0
SomeguyManperson marked this conversation as resolved.
Show resolved Hide resolved
var/image/I_base = image('icons/obj/cult_64x64.dmi',"bloodstone-base")
I_base.appearance_flags |= RESET_COLOR//we don't want the stone to pulse
overlays += I_base
if (obj_integrity <= max_integrity/3)
overlays.Add("bloodstone_damage2")
else if (obj_integrity <= 2*max_integrity/3)
overlays.Add("bloodstone_damage1")
SomeguyManperson marked this conversation as resolved.
Show resolved Hide resolved
set_light(3+current_fullness, 2+current_fullness)

/obj/structure/destructible/cult/bloodstone/proc/set_animate()
animate(src, color = list(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0), time = 10, loop = -1)
animate(color = list(1.125,0.06,0,0,0,1.125,0.06,0,0.06,0,1.125,0,0,0,0,1,0,0,0,0), time = 2)
animate(color = list(1.25,0.12,0,0,0,1.25,0.12,0,0.12,0,1.25,0,0,0,0,1,0,0,0,0), time = 2)
animate(color = list(1.375,0.19,0,0,0,1.375,0.19,0,0.19,0,1.375,0,0,0,0,1,0,0,0,0), time = 1.5)
animate(color = list(1.5,0.27,0,0,0,1.5,0.27,0,0.27,0,1.5,0,0,0,0,1,0,0,0,0), time = 1.5)
animate(color = list(1.625,0.35,0.06,0,0.06,1.625,0.35,0,0.35,0.06,1.625,0,0,0,0,1,0,0,0,0), time = 1)
animate(color = list(1.75,0.45,0.12,0,0.12,1.75,0.45,0,0.45,0.12,1.75,0,0,0,0,1,0,0,0,0), time = 1)
animate(color = list(1.875,0.56,0.19,0,0.19,1.875,0.56,0,0.56,0.19,1.875,0,0,0,0,1,0,0,0,0), time = 1)
animate(color = list(2,0.67,0.27,0,0.27,2,0.67,0,0.67,0.27,2,0,0,0,0,1,0,0,0,0), time = 5)
animate(color = list(1.875,0.56,0.19,0,0.19,1.875,0.56,0,0.56,0.19,1.875,0,0,0,0,1,0,0,0,0), time = 1)
animate(color = list(1.75,0.45,0.12,0,0.12,1.75,0.45,0,0.45,0.12,1.75,0,0,0,0,1,0,0,0,0), time = 1)
animate(color = list(1.625,0.35,0.06,0,0.06,1.625,0.35,0,0.35,0.06,1.625,0,0,0,0,1,0,0,0,0), time = 1)
animate(color = list(1.5,0.27,0,0,0,1.5,0.27,0,0.27,0,1.5,0,0,0,0,1,0,0,0,0), time = 1)
animate(color = list(1.375,0.19,0,0,0,1.375,0.19,0,0.19,0,1.375,0,0,0,0,1,0,0,0,0), time = 1)
animate(color = list(1.25,0.12,0,0,0,1.25,0.12,0,0.12,0,1.25,0,0,0,0,1,0,0,0,0), time = 1)
animate(color = list(1.125,0.06,0,0,0,1.125,0.06,0,0.06,0,1.125,0,0,0,0,1,0,0,0,0), time = 1)
set_light(20, 20)
update_icon()

/obj/structure/destructible/cult/bloodstone/conceal() //lol
return

/obj/structure/destructible/cult/bloodstone/reveal()
return

/obj/structure/destructible/dead_bloodstone
name = "shattered bloodstone"
desc = "The base of a destroyed bloodstone."
icon = 'icons/obj/cult_64x64.dmi'
icon_state = "bloodstone-base"
pixel_x = -16

/obj/effect/gateway
name = "gateway"
desc = "You're pretty sure that abyss is staring back."
Expand Down