diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm
index bff46717b1..e661baacd7 100644
--- a/code/controllers/subsystem/shuttle.dm
+++ b/code/controllers/subsystem/shuttle.dm
@@ -197,6 +197,13 @@ SUBSYSTEM_DEF(shuttle)
if(emergency.timeLeft(1) > emergencyCallTime * 0.4)
emergency.request(null, set_coefficient = 0.4)
+/datum/controller/subsystem/shuttle/proc/block_recall(lockout_timer)
+ emergencyNoRecall = TRUE
+ addtimer(CALLBACK(src, .proc/unblock_recall), lockout_timer)
+
+/datum/controller/subsystem/shuttle/proc/unblock_recall()
+ emergencyNoRecall = FALSE
+
/datum/controller/subsystem/shuttle/proc/getShuttle(id)
for(var/obj/docking_port/mobile/M in mobile)
if(M.id == id)
@@ -309,9 +316,7 @@ SUBSYSTEM_DEF(shuttle)
return 1
/datum/controller/subsystem/shuttle/proc/canRecall()
- if(!emergency || emergency.mode != SHUTTLE_CALL)
- return
- if(SSticker.mode.name == "meteor")
+ if(!emergency || emergency.mode != SHUTTLE_CALL || emergencyNoRecall || SSticker.mode.name == "meteor")
return
var/security_num = seclevel2num(get_security_level())
switch(security_num)
diff --git a/code/game/gamemodes/cult/blood_magic.dm b/code/game/gamemodes/cult/blood_magic.dm
index 04b56c9f7d..dd66edcfb1 100644
--- a/code/game/gamemodes/cult/blood_magic.dm
+++ b/code/game/gamemodes/cult/blood_magic.dm
@@ -172,7 +172,6 @@
name = "Twisted Construction"
desc = "A sinister spell used to convert:
Plasteel into runed metal
25 metal into a construct shell
Cyborgs directly into constructs
Cyborg shells into construct shells
Airlocks into runed airlocks (harm intent)"
button_icon_state = "transmute"
- charges = 50
magic_path = "/obj/item/melee/blood_magic/construction"
/datum/action/innate/cult/blood_spell/equipment
@@ -180,7 +179,6 @@
desc = "A crucial spell that enables you to summon either a ritual dagger or combat gear including armored robes, the nar'sien bola, and an eldritch longsword."
button_icon_state = "equip"
magic_path = "/obj/item/melee/blood_magic/armor"
- charges = 1
/datum/action/innate/cult/blood_spell/equipment/Activate()
var/choice = alert(owner,"Choose your equipment type",,"Combat Equipment","Ritual Dagger","Cancel")
@@ -271,8 +269,8 @@
qdel(src)
/datum/action/innate/cult/blood_spell/veiling
- name = "Conceal Runes"
- desc = "A multi-function spell that alternates between hiding and revealing nearby runes."
+ name = "Conceal Presence"
+ desc = "A multi-function spell that alternates between hiding and revealing nearby cult runes, structures, turf, and airlocks."
invocation = "Kla'atu barada nikt'o!"
button_icon_state = "gone"
charges = 10
@@ -291,6 +289,8 @@
S.conceal()
for(var/turf/open/floor/engine/cult/T in range(5,owner))
T.realappearance.alpha = 0
+ for(var/obj/machinery/door/airlock/cult/AL in range(5, owner))
+ AL.conceal()
revealing = TRUE
name = "Reveal Runes"
button_icon_state = "back"
@@ -302,10 +302,12 @@
SEND_SOUND(owner, sound('sound/magic/enter_blood.ogg',0,1,25))
for(var/obj/effect/rune/R in range(7,owner)) //More range in case you weren't standing in exactly the same spot
R.reveal()
- for(var/obj/structure/destructible/cult/S in range(7,owner))
+ for(var/obj/structure/destructible/cult/S in range(6,owner))
S.reveal()
- for(var/turf/open/floor/engine/cult/T in range(7,owner))
+ for(var/turf/open/floor/engine/cult/T in range(6,owner))
T.realappearance.alpha = initial(T.realappearance.alpha)
+ for(var/obj/machinery/door/airlock/cult/AL in range(6, owner))
+ AL.reveal()
revealing = FALSE
name = "Conceal Runes"
button_icon_state = "gone"
@@ -529,13 +531,13 @@
var/turf/T = get_turf(target)
if(istype(target, /obj/item/stack/sheet/metal))
var/obj/item/stack/sheet/candidate = target
- if(candidate.use(25))
- uses-=25
+ if(candidate.use(50))
+ uses--
to_chat(user, "A dark cloud eminates from your hand and swirls around the metal, twisting it into a construct shell!")
new /obj/structure/constructshell(T)
SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25))
else
- to_chat(user, "You need more metal to produce a construct shell!")
+ to_chat(user, "You need 50 metal to produce a construct shell!")
else if(istype(target, /obj/item/stack/sheet/plasteel))
var/obj/item/stack/sheet/plasteel/candidate = target
var/quantity = min(candidate.amount, uses)
@@ -563,19 +565,19 @@
if("Artificer")
makeNewConstruct(/mob/living/simple_animal/hostile/construct/builder, candidate, user, 0, T)
SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25))
- uses -= 50
+ uses--
candidate.mmi = null
qdel(candidate)
else
candidate.color = prev_color
else
- uses -= 50
+ uses--
to_chat(user, "A dark cloud eminates from you hand and swirls around [candidate] - twisting it into a construct shell!")
new /obj/structure/constructshell(T)
SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25))
else if(istype(target,/obj/machinery/door/airlock))
target.narsie_act()
- uses -= 50
+ uses--
user.visible_message("Black ribbons suddenly eminate from [user]'s hand and cling to the airlock - twisting and corrupting it!")
SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25))
else
@@ -701,7 +703,7 @@
if(B.bloodiness == 100) //Bonus for "pristine" bloodpools, also to prevent cheese with footprint spam
temp += 30
else
- temp += max((B.bloodiness**2)/800,0.5)
+ temp += max((B.bloodiness**2)/800,1)
new /obj/effect/temp_visual/cult/turf/floor(get_turf(B))
qdel(B)
for(var/obj/effect/decal/cleanable/trail_holder/TH in view(T, 2))
diff --git a/code/game/machinery/doors/airlock_types.dm b/code/game/machinery/doors/airlock_types.dm
index 2874e6bf1b..feb1cfc22a 100644
--- a/code/game/machinery/doors/airlock_types.dm
+++ b/code/game/machinery/doors/airlock_types.dm
@@ -409,6 +409,7 @@
damage_deflection = 10
var/openingoverlaytype = /obj/effect/temp_visual/cult/door
var/friendly = FALSE
+ var/stealthy = FALSE
/obj/machinery/door/airlock/cult/Initialize()
. = ..()
@@ -421,18 +422,36 @@
if(!density)
return 1
if(friendly || iscultist(L) || istype(L, /mob/living/simple_animal/shade) || isconstruct(L))
- new openingoverlaytype(loc)
+ if(!stealthy)
+ new openingoverlaytype(loc)
return 1
else
- new /obj/effect/temp_visual/cult/sac(loc)
- var/atom/throwtarget
- throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(L, src)))
- SEND_SOUND(L, sound(pick('sound/hallucinations/turn_around1.ogg','sound/hallucinations/turn_around2.ogg'),0,1,50))
- flash_color(L, flash_color="#960000", flash_time=20)
- L.Knockdown(40)
- L.throw_at(throwtarget, 5, 1,src)
+ if(!stealthy)
+ new /obj/effect/temp_visual/cult/sac(loc)
+ var/atom/throwtarget
+ throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(L, src)))
+ SEND_SOUND(L, sound(pick('sound/hallucinations/turn_around1.ogg','sound/hallucinations/turn_around2.ogg'),0,1,50))
+ flash_color(L, flash_color="#960000", flash_time=20)
+ L.Knockdown(40)
+ L.throw_at(throwtarget, 5, 1,src)
return 0
+/obj/machinery/door/airlock/cult/proc/conceal()
+ icon = 'icons/obj/doors/airlocks/station/maintenance.dmi'
+ overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi'
+ name = "airlock"
+ desc = "It opens and closes."
+ stealthy = TRUE
+ update_icon()
+
+/obj/machinery/door/airlock/cult/proc/reveal()
+ icon = initial(icon)
+ overlays_file = initial(overlays_file)
+ name = initial(name)
+ desc = initial(desc)
+ stealthy = initial(stealthy)
+ update_icon()
+
/obj/machinery/door/airlock/cult/narsie_act()
return
diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm
index 84a6cc1b9e..66124f8b6d 100644
--- a/code/game/objects/structures/girders.dm
+++ b/code/game/objects/structures/girders.dm
@@ -168,7 +168,7 @@
qdel(src)
return
- if(S.sheettype)
+ if(S.sheettype && S.sheettype != "runed")
var/M = S.sheettype
if(state == GIRDER_DISPLACED)
if(S.get_amount() < 2)
diff --git a/code/modules/antagonists/cult/cult_comms.dm b/code/modules/antagonists/cult/cult_comms.dm
index bedb7dc9bc..68c93fa04c 100644
--- a/code/modules/antagonists/cult/cult_comms.dm
+++ b/code/modules/antagonists/cult/cult_comms.dm
@@ -80,8 +80,10 @@
return ..()
/datum/action/innate/cult/mastervote/Activate()
- var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE)
- pollCultists(owner,C.cult_team)
+ var/choice = alert(owner, "The mantle of leadership is a heavy. Success in this role requires an expert level of communication and experience. Are you sure?",, "Yes", "No")
+ if(choice == "Yes" && IsAvailable())
+ var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE)
+ pollCultists(owner,C.cult_team)
/proc/pollCultists(var/mob/living/Nominee,datum/team/cult/team) //Cult Master Poll
if(world.time < CULT_POLL_WAIT)
diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm
index 6bf65fa234..e98f89718b 100644
--- a/code/modules/antagonists/cult/cult_items.dm
+++ b/code/modules/antagonists/cult/cult_items.dm
@@ -503,7 +503,19 @@
if(SSshuttle.emergency.mode == SHUTTLE_CALL)
var/cursetime = 1800
var/timer = SSshuttle.emergency.timeLeft(1) + cursetime
+ var/security_num = seclevel2num(get_security_level())
+ var/set_coefficient = 1
+ switch(security_num)
+ if(SEC_LEVEL_GREEN)
+ set_coefficient = 2
+ if(SEC_LEVEL_BLUE)
+ set_coefficient = 1
+ else
+ set_coefficient = 0.5
+ var/surplus = timer - (SSshuttle.emergencyCallTime * set_coefficient)
SSshuttle.emergency.setTimer(timer)
+ if(surplus > 0)
+ SSshuttle.block_recall(surplus)
to_chat(user, "You shatter the orb! A dark essence spirals into the air, then disappears.")
playsound(user.loc, 'sound/effects/glassbr1.ogg', 50, 1)
qdel(src)
@@ -511,18 +523,20 @@
var/global/list/curses
if(!curses)
curses = list("A fuel technician just slit his own throat and begged for death. The shuttle will be delayed by three minutes.",
- "The shuttle's navigation programming was replaced by a file containing two words, IT COMES. The shuttle will be delayed by three minutes.",
- "The shuttle's custodian tore out his guts and began painting strange shapes on the floor. The shuttle will be delayed by three minutes.",
- "A shuttle engineer began screaming 'DEATH IS NOT THE END' and ripped out wires until an arc flash seared off her flesh. The shuttle will be delayed by three minutes.",
- "A shuttle inspector started laughing madly over the radio and then threw herself into an engine turbine. The shuttle will be delayed by three minutes.",
- "The shuttle dispatcher was found dead with bloody symbols carved into their flesh. The shuttle will be delayed by three minutes.")
+ "The shuttle's navigation programming was replaced by a file containing just two words: IT COMES.",
+ "The shuttle's custodian was found washing the windows with their own blood.",
+ "A shuttle engineer began screaming 'DEATH IS NOT THE END' and ripped out wires until an arc flash seared off her flesh.",
+ "A shuttle inspector started laughing madly over the radio and then threw herself into an engine turbine.",
+ "The shuttle dispatcher was found dead with bloody symbols carved into their flesh.",
+ "The shuttle's transponder is emitting the encoded message 'FEAR THE OLD BLOOD' in lieu of its assigned identification signal.")
var/message = pick_n_take(curses)
+ message += "
The shuttle will be delayed by three minutes."
priority_announce("[message]", "System Failure", 'sound/misc/notice1.ogg')
curselimit++
/obj/item/device/cult_shift
name = "veil shifter"
- desc = "This relic teleports you forward a medium distance."
+ desc = "This relic instantly teleports you, and anything you're pulling, forward by a moderate distance."
icon = 'icons/obj/cult.dmi'
icon_state ="shifter"
var/uses = 4
diff --git a/code/modules/antagonists/cult/cult_structures.dm b/code/modules/antagonists/cult/cult_structures.dm
index ea8e18d7aa..84cc26d81a 100644
--- a/code/modules/antagonists/cult/cult_structures.dm
+++ b/code/modules/antagonists/cult/cult_structures.dm
@@ -57,6 +57,7 @@
/obj/structure/destructible/cult/attackby(obj/I, mob/user, params)
if(istype(I, /obj/item/melee/cultblade/dagger) && iscultist(user))
anchored = !anchored
+ density = !density
to_chat(user, "You [anchored ? "":"un"]secure \the [src] [anchored ? "to":"from"] the floor.")
if(!anchored)
icon_state = "[initial(icon_state)]_off"
diff --git a/code/modules/antagonists/cult/ritual.dm b/code/modules/antagonists/cult/ritual.dm
index 20ac8c88cf..8167a1c0d9 100644
--- a/code/modules/antagonists/cult/ritual.dm
+++ b/code/modules/antagonists/cult/ritual.dm
@@ -68,6 +68,9 @@ This file contains the cult dagger and rune list code
A = get_area(src)
if(!src || QDELETED(src) || !Adjacent(user) || user.incapacitated() || !check_rune_turf(Turf, user))
return
+ if(ispath(rune_to_scribe, /obj/effect/rune/summon) && (!is_station_level(Turf.z) || A.map_name == "Space"))
+ to_chat(user, "The veil is not weak enough here to summon a cultist, you must be on station!")
+ return
if(ispath(rune_to_scribe, /obj/effect/rune/apocalypse))
if((world.time - SSticker.round_start_time) <= 6000)
var/wait = 6000 - (world.time - SSticker.round_start_time)
diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm
index fc7d6ecc64..8e6ae30d28 100644
--- a/code/modules/antagonists/cult/runes.dm
+++ b/code/modules/antagonists/cult/runes.dm
@@ -426,22 +426,19 @@ structure_check() searches for nearby cultist structures required for the invoca
else
var/area/A = get_area(T)
if(A.map_name == "Space")
- actual_selected_rune.handle_portal("space")
+ actual_selected_rune.handle_portal("space", T)
target.visible_message("There is a boom of outrushing air as something appears above the rune!", null, "You hear a boom.")
else
fail_invoke()
-/obj/effect/rune/teleport/proc/handle_portal(portal_type)
+/obj/effect/rune/teleport/proc/handle_portal(portal_type, turf/origin)
var/turf/T = get_turf(src)
- if(inner_portal)
- qdel(inner_portal) //We need fresh effects/animations
- if(outer_portal)
- qdel(outer_portal)
+ close_portal() // To avoid stacking descriptions/animations
playsound(T, pick('sound/effects/sparks1.ogg', 'sound/effects/sparks2.ogg', 'sound/effects/sparks3.ogg', 'sound/effects/sparks4.ogg'), 100, TRUE, 14)
inner_portal = new /obj/effect/temp_visual/cult/portal(T)
if(portal_type == "space")
- light_color = RUNE_COLOR_TELEPORT
- desc += "
A tear in reality reveals a black void interspersed with dots of light... something recently teleported here from space!"
+ light_color = color
+ desc += "
A tear in reality reveals a black void interspersed with dots of light... something recently teleported here from space.
The void feels like it's trying to pull you to the [dir2text(get_dir(T, origin))]!"
else
inner_portal.icon_state = "lava"
light_color = LIGHT_COLOR_FIRE
@@ -452,6 +449,8 @@ structure_check() searches for nearby cultist structures required for the invoca
addtimer(CALLBACK(src, .proc/close_portal), 600, TIMER_UNIQUE)
/obj/effect/rune/teleport/proc/close_portal()
+ qdel(inner_portal)
+ qdel(outer_portal)
desc = initial(desc)
light_range = 0
update_light()
@@ -842,9 +841,13 @@ structure_check() searches for nearby cultist structures required for the invoca
var/turf/T = get_turf(src)
var/choice = alert(user,"You tear open a connection to the spirit realm...",,"Summon a Cult Ghost","Ascend as a Dark Spirit","Cancel")
if(choice == "Summon a Cult Ghost")
+ var/area/A = get_area(T)
+ if(A.map_name == "Space" || is_mining_level(T.z))
+ to_chat(user, "The veil is not weak enough here to manifest spirits, you must be on station!")
+ return
notify_ghosts("Manifest rune invoked in [get_area(src)].", 'sound/effects/ghost2.ogg', source = src)
var/list/ghosts_on_rune = list()
- for(var/mob/dead/observer/O in get_turf(src))
+ for(var/mob/dead/observer/O in T)
if(O.client && !jobban_isbanned(O, ROLE_CULTIST))
ghosts_on_rune += O
if(!ghosts_on_rune.len)
@@ -853,7 +856,7 @@ structure_check() searches for nearby cultist structures required for the invoca
log_game("Manifest rune failed - no nearby ghosts")
return list()
var/mob/dead/observer/ghost_to_spawn = pick(ghosts_on_rune)
- var/mob/living/carbon/human/cult_ghost/new_human = new(get_turf(src))
+ var/mob/living/carbon/human/cult_ghost/new_human = new(T)
new_human.real_name = ghost_to_spawn.real_name
new_human.alpha = 150 //Makes them translucent
new_human.equipOutfit(/datum/outfit/ghost_cultist) //give them armor
diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm
index 6c6f39ffc1..1c12b48919 100644
--- a/code/modules/mob/living/simple_animal/constructs.dm
+++ b/code/modules/mob/living/simple_animal/constructs.dm
@@ -125,19 +125,19 @@
response_harm = "harmlessly punches"
harm_intent_damage = 0
obj_damage = 90
- melee_damage_lower = 30
- melee_damage_upper = 30
+ melee_damage_lower = 25
+ melee_damage_upper = 25
attacktext = "smashes their armored gauntlet into"
speed = 2.5
environment_smash = ENVIRONMENT_SMASH_WALLS
attack_sound = 'sound/weapons/punch3.ogg'
status_flags = 0
mob_size = MOB_SIZE_LARGE
- force_threshold = 11
+ force_threshold = 10
construct_spells = list(/obj/effect/proc_holder/spell/targeted/forcewall/cult,
/obj/effect/proc_holder/spell/dumbfire/juggernaut)
runetype = /datum/action/innate/cult/create_rune/wall
- playstyle_string = "You are a Juggernaut. Though slow, your shell can withstand extreme punishment, \
+ playstyle_string = "You are a Juggernaut. Though slow, your shell can withstand heavy punishment, \
create shield walls, rip apart enemies and walls alike, and even deflect energy weapons."
/mob/living/simple_animal/hostile/construct/armored/hostile //actually hostile, will move around, hit things
@@ -146,7 +146,7 @@
/mob/living/simple_animal/hostile/construct/armored/bullet_act(obj/item/projectile/P)
if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))
- var/reflectchance = 80 - round(P.damage/3)
+ var/reflectchance = 60 - round(P.damage/3)
if(prob(reflectchance))
apply_damage(P.damage * 0.5, P.damage_type)
visible_message("The [P.name] is reflected by [src]'s armored shell!", \
@@ -184,8 +184,8 @@
icon_living = "floating"
maxHealth = 65
health = 65
- melee_damage_lower = 25
- melee_damage_upper = 25
+ melee_damage_lower = 20
+ melee_damage_upper = 20
retreat_distance = 2 //AI wraiths will move in and out of combat
attacktext = "slashes"
attack_sound = 'sound/weapons/bladeslice.ogg'
diff --git a/code/modules/spells/spell_types/construct_spells.dm b/code/modules/spells/spell_types/construct_spells.dm
index 07e75002bc..64605e0587 100644
--- a/code/modules/spells/spell_types/construct_spells.dm
+++ b/code/modules/spells/spell_types/construct_spells.dm
@@ -280,9 +280,9 @@
/obj/effect/proc_holder/spell/dumbfire/juggernaut
name = "Gauntlet Echo"
- desc = "Channels energy into your gauntlet - firing its essence forward in a slow-moving but devastating blow."
- proj_icon_state = "cursehand0"
- proj_name = "Shadowfist"
+ desc = "Channels energy into your gauntlet - firing its essence forward in a slow moving, yet devastating, attack."
+ proj_icon_state = "cultfist"
+ proj_name = "gauntlet echo"
proj_type = "/obj/effect/proc_holder/spell/targeted/inflict_handler/juggernaut" //IMPORTANT use only subtypes of this
proj_lifespan = 15
proj_step_delay = 7
diff --git a/icons/mob/actions/actions_cult.dmi b/icons/mob/actions/actions_cult.dmi
index 07432d2a27..c2e0467781 100644
Binary files a/icons/mob/actions/actions_cult.dmi and b/icons/mob/actions/actions_cult.dmi differ
diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi
index b2299a75fe..34e6a8134b 100644
Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ