Big finalized update

This commit is contained in:
Robustin
2017-04-30 16:30:35 -04:00
parent 06c3116c2d
commit 4a4c2a498c
16 changed files with 358 additions and 224 deletions

View File

@@ -487,45 +487,53 @@
/proc/pollCultists(var/mob/living/Nominee) // Cult Master Poll
var/time_passed = world.time
set waitfor = FALSE
var/list/yes_voters = new
var/list/cult_total = new
if(world.time<1800)
if(world.time<1)
Nominee << "It would be premature to select a leader while everyone is still settling in, try again in [round((1800-world.time)/10)] seconds"
return
for(var/datum/mind/B in SSticker.mode.cult)
if(!istype(B.current, /mob/living))
if(!isliving(B.current))
continue
var/mob/living/M = B.current
if(isliving(M))
M << 'sound/misc/notice2.ogg' //Alerting them to their consideration
M << 'sound/hallucinations/im_here1.ogg'
M.verbs -= /mob/living/proc/cult_master
to_chat(M, "<span class='cultlarge'>[Nominee] has asserted that they are worthy of leading the cult. A vote will be called shortly.</span>")
sleep(200)
switch(askuser(M,"[Nominee] seeks to lead your cult, do you support them?","Please answer in 20 seconds!","Yes","No","Abstain", StealFocus=0, Timeout=200))
if(1)
to_chat(M, "<span class='cultlarge'>Acolyte [Nominee] has asserted that they are worthy of leading the cult. A vote will be called shortly.</span>")
sleep(250)
for(var/datum/mind/B in SSticker.mode.cult)
if(!isliving(B.current))
continue
var/mob/living/M = B.current
M << 'sound/magic/exit_blood.ogg'
switch(askuser(M,"[Nominee] seeks to lead your cult, do you support them?","Please answer in 20 seconds!","Yes","No","Abstain", StealFocus=0, Timeout=200))
if(1)
if((world.time-time_passed)>500)
M << "<span class='danger'>Sorry, your vote came too late!</span>"
M << 'sound/machines/buzz-sigh.ogg'
else
M << "<span class='notice'>Choice registered: Yes.</span>"
if((world.time-time_passed)>400)
M << "<span class='danger'>Sorry, your vote came too late!</span>"
M << 'sound/machines/buzz-sigh.ogg'
else
yes_voters += M
cult_total += M
if(2)
yes_voters += M
cult_total += M
if(2)
if((world.time-time_passed)>500)
M << "<span class='danger'>Sorry, your vote came too late!</span>"
M << 'sound/machines/buzz-sigh.ogg'
else
M << "<span class='danger'>Choice registered: No.</span>"
cult_total += M
if(3)
M << "<span class='danger'>Choice registered: Abstain.</span>"
sleep(400)
if(3)
M << "<span class='danger'>Choice registered: Abstain.</span>"
sleep(300)
if(yes_voters.len > (cult_total.len/2))
var/datum/action/innate/cultmast/finalreck/FinalReckoning= new()
var/datum/action/innate/cultmast/cultmark/Mark= new()
var/datum/action/innate/cultmast/finalreck/FinalReckoning = new()
var/datum/action/innate/cultmast/cultmark/Mark = new()
FinalReckoning.Grant(Nominee)
Mark.Grant(Nominee)
Nominee.mind.special_role = "Cult Master"
Nominee.update_action_buttons_icon()
SSticker.mode.set_antag_hud(Nominee,"cultmaster")
GLOB.cult_mastered = 1
GLOB.cult_mastered = TRUE
for(var/datum/mind/B in SSticker.mode.cult)
if(isliving(B.current))
B.current << "<span class='cultlarge'>[Nominee] has the cult's support and is now their master. Follow their orders to the best of your ability!"
@@ -537,6 +545,8 @@
B.current.verbs += /mob/living/proc/cult_master
return FALSE
/proc/poll_helper(var/mob/living/M)
/proc/makeBody(mob/dead/observer/G_found) // Uses stripped down and bastardized code from respawn character
if(!G_found || !G_found.key)
return

View File

@@ -24,27 +24,6 @@
//doesn't have an object argument because this is "Stacking" with the animate call above
//3 billion% intentional
atom/proc/RotateAnimation(speed = 10, clockwise = 1, segments = 6, degrees = 90)
if(!segments || !degrees)
return
var/segment = degrees/segments
if(!clockwise)
segment = -segment
var/list/matrices = list()
for(var/i in 1 to segments-1)
var/matrix/M = matrix(transform)
M.Turn(segment*i)
matrices += M
var/matrix/last = matrix(transform)
matrices += last
speed /= segments
animate(src, transform = matrices[1], time = speed)
for(var/i in 2 to segments) //2 because 1 is covered above
animate(transform = matrices[i], time = speed)
//Dumps the matrix data in format a-f
/matrix/proc/tolist()
. = list()

View File

@@ -4,7 +4,9 @@ GLOBAL_VAR_INIT(secret_force_mode, "secret") // if this is anything but "secret"
GLOBAL_VAR_INIT(wavesecret, 0) // meteor mode, delays wave progression, terrible name
GLOBAL_DATUM(start_state, /datum/station_state) // Used in round-end report
GLOBAL_VAR_INIT(blood_target, 0)
GLOBAL_VAR_INIT(sac_target, 0)
// Cult, needs to be global so admin cultists are functional
GLOBAL_VAR_INIT(blood_target, null) // Cult Master's target or Construct's Master
GLOBAL_DATUM(sac_mind, /datum/mind)
GLOBAL_VAR_INIT(sac_image, null)
GLOBAL_VAR_INIT(cult_mastered, FALSE)
GLOBAL_VAR_INIT(sac_complete, FALSE)

View File

@@ -264,66 +264,91 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
name = "Blood Sense"
desc = "Allows you to sense blood that is manipulated by dark magicks."
icon_state = "cult_sense"
var/obj/effect/overlay/finder
alerttooltipstyle = "cult"
var/image/sacimage
var/mob/sacmob
var/angle = 0
var/mob/living/simple_animal/hostile/construct/Cviewer = null
/obj/screen/alert/bloodsense/Initialize()
..()
finder = new('icons/mob/screen_alert.dmi', "no_sacrifice")
var/datum/mind/sacmind = GLOB.sac_target
sacmob = sacmind.current
var/datum/job/sacjob = SSjob.GetJob(sacmind.assigned_role)
var/datum/preferences/sacpref = sacmob.client.prefs
var/icon/reshape = get_flat_human_icon(null, sacjob, sacpref)
reshape.Shift(SOUTH, 4)
reshape.Crop(7,4,26,30)
reshape.Crop(-5,-2,26,29)
sacimage = reshape
add_overlay(finder.icon)
sacimage = GLOB.sac_image
START_PROCESSING(SSprocessing, src)
process()
/obj/screen/alert/bloodsense/Destroy()
qdel(finder)
finder = null
sacimage = null
Cviewer = null
STOP_PROCESSING(SSprocessing, src)
return ..()
/obj/screen/alert/bloodsense/process()
if (!GLOB.sac_target)
return
if(!GLOB.blood_target && !GLOB.sac_complete)
var/atom/blood_target
if(GLOB.blood_target)
blood_target = GLOB.blood_target
if(Cviewer)
if(Cviewer.seeking && Cviewer.master)
blood_target = Cviewer.master
if(!blood_target && !GLOB.sac_complete)
if(icon_state == "runed_sense0")
return
animate(src, transform = null, time = 1, loop = 0)
angle = 0
cut_overlays()
finder.icon_state = "no_sacrifice"
desc = "Nar-Sie demands that [GLOB.sac_target] be sacrificed before the summoning can begin."
add_overlay(finder.icon)
icon_state = "runed_sense0"
desc = "Nar-Sie demands that [GLOB.sac_mind] be sacrificed before the summoning ritual can begin."
add_overlay(sacimage)
return
if(!GLOB.blood_target && GLOB.sac_complete)
cut_overlays()
finder.icon_state = "sacrifice"
desc = "The sacrifice is complete, prepare to summon Nar-Sie!"
add_overlay(finder.icon)
return
var/turf/Q = get_turf(GLOB.blood_target)
var/turf/A = get_turf(mob_viewer)
if(Q.z != A.z) //The target is on a different Z level, we cannot sense that far.
return
var/target_angle = Get_Angle(GLOB.blood_target, mob_viewer)
// var/target_dist = get_dist(A, Q)
if(finder.icon_state != "arrow")
cut_overlays()
finder.icon_state = "arrow"
if(!blood_target && GLOB.sac_complete)
if(icon_state == "runed_sense1")
return
animate(src, transform = null, time = 1, loop = 0)
angle = 0
cut_overlays()
icon_state = "runed_sense1"
var/image/narnar = new('icons/mob/screen_alert.dmi', "mini_nar")
desc = "The sacrifice is complete, prepare to summon Nar-Sie!"
add_overlay(narnar)
return
if(!blood_target)
return
var/turf/P = get_turf(blood_target)
var/turf/Q = get_turf(mob_viewer)
var/area/A = get_area(P)
if(P.z != Q.z) //The target is on a different Z level, we cannot sense that far.
return
desc = "You are currently tracking [blood_target] in [A.name]"
var/target_angle = Get_Angle(mob_viewer, blood_target)
var/target_dist = get_dist(P, Q)
cut_overlays()
switch(target_dist)
if(0 to 1)
icon_state = "runed_sense2"
if(2 to 8)
icon_state = "arrow8"
if(9 to 15)
icon_state = "arrow7"
if(16 to 22)
icon_state = "arrow6"
if(23 to 29)
icon_state = "arrow5"
if(30 to 36)
icon_state = "arrow4"
if(37 to 43)
icon_state = "arrow3"
if(44 to 50)
icon_state = "arrow2"
if(51 to 57)
icon_state = "arrow1"
if(58 to 64)
icon_state = "arrow0"
if(65 to 400)
icon_state = "arrow"
var/difference = target_angle - angle
angle = target_angle
if(difference < 0)
finder.RotateAnimation(5, 0, 6, difference)
else
finder.RotateAnimation(5, 1, 6, difference)
add_overlay(finder.icon)
if(!difference)
return
var/matrix/final = matrix(transform)
final.Turn(difference)
animate(src, transform = final, time = 5, loop = 0)

View File

@@ -7,18 +7,67 @@
qdel(communion)
return ..()
/datum/antagonist/cultist/proc/add_objectives()
var/list/target_candidates = list()
for(var/mob/living/carbon/human/player in GLOB.player_list)
if(player.mind && !is_convertable_to_cult(player) && !owner && isliving(player))
target_candidates += player.mind
if(target_candidates.len == 0)
message_admins("Cult Sacrifice: Could not find unconvertable target, checking for convertable target.")
for(var/mob/living/carbon/human/player in GLOB.player_list)
if(player.mind && (player != owner) && isliving(player))
target_candidates += player.mind
if(target_candidates.len > 0)
GLOB.sac_mind = pick(target_candidates)
if(!GLOB.sac_mind)
message_admins("Cult Sacrifice: ERROR - Null target chosen!")
else
var/datum/job/sacjob = SSjob.GetJob(GLOB.sac_mind.assigned_role)
var/icon/reshape = get_flat_human_icon(null, sacjob, GLOB.sac_mind.current.client.prefs)
reshape.Shift(SOUTH, 4)
reshape.Shift(EAST, 1)
reshape.Crop(7,4,26,31)
reshape.Crop(-5,-3,26,30)
GLOB.sac_image = reshape
else
message_admins("Cult Sacrifice: Could not find unconvertable or convertable target. WELP!")
GLOB.sac_complete = TRUE
SSticker.mode.cult_objectives += "sacrifice"
SSticker.mode.cult_objectives += "eldergod"
on_gain()
/datum/antagonist/cultist/proc/special_cult_memorization(datum/mind/cult_mind)
for(var/obj_count in 1 to 2)
var/explanation
switch(SSticker.mode.cult_objectives[obj_count])
if("sacrifice")
if(GLOB.sac_mind)
explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role] via invoking a Sacrifice rune with them on it and three acolytes around it."
else
explanation = "The veil has already been weakened here, proceed to the final objective."
if("eldergod")
explanation = "Summon Nar-Sie by invoking the rune 'Summon Nar-Sie' with nine acolytes on it. You must do this after sacrificing your target."
to_chat(cult_mind.current, "<B>Objective #[obj_count]</B>: [explanation]")
cult_mind.memory += "<B>Objective #[obj_count]</B>: [explanation]<BR>"
/datum/antagonist/cultist/can_be_owned(mob/living/new_body)
. = ..()
if(.)
. = is_convertable_to_cult(new_body)
/datum/antagonist/cultist/on_gain()
if(SSticker.mode.cult_objectives.len == 0)
add_objectives()
return
if(SSticker && SSticker.mode && owner.mind)
SSticker.mode.cult += owner.mind
SSticker.mode.update_cult_icons_added(owner.mind)
if(istype(SSticker.mode, /datum/game_mode/cult))
var/datum/game_mode/cult/C = SSticker.mode
C.memorize_cult_objectives(owner.mind)
else
special_cult_memorization(owner.mind)
if(jobban_isbanned(owner, ROLE_CULTIST))
INVOKE_ASYNC(SSticker.mode, /datum/game_mode.proc/replace_jobbaned_player, owner, ROLE_CULTIST, ROLE_CULTIST)
if(owner.mind)
@@ -29,7 +78,7 @@
/datum/antagonist/cultist/apply_innate_effects()
owner.faction |= "cult"
owner.verbs += /mob/living/proc/cult_help
if(GLOB.cult_mastered == 0)
if(!GLOB.cult_mastered)
owner.verbs += /mob/living/proc/cult_master
communion.Grant(owner)
owner.throw_alert("bloodsense", /obj/screen/alert/bloodsense)

View File

@@ -1400,14 +1400,7 @@
to_chat(current, "<font color=\"purple\"><b><i>You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie.</b></i></font>")
to_chat(current, "<font color=\"purple\"><b><i>Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back.</b></i></font>")
var/datum/game_mode/cult/cult = SSticker.mode
if (istype(cult))
cult.memorize_cult_objectives(src)
else
var/explanation = "Summon Nar-Sie via the use of the appropriate rune (Hell join self). It will only work if nine cultists stand on and around it."
to_chat(current, "<B>Objective #1</B>: [explanation]")
memory += "<B>Objective #1</B>: [explanation]<BR>"
cult.memorize_cult_objectives(src)
var/mob/living/carbon/human/H = current
if (!SSticker.mode.equip_cultist(current))
to_chat(H, "Spawning an amulet from your Master failed.")

View File

@@ -1,32 +1,31 @@
/datum/game_mode
var/list/datum/mind/cult = list()
var/list/cult_objectives = list()
var/eldergod = 1 //for the summon god objective
/proc/iscultist(mob/living/M)
return istype(M) && M.has_antag_datum(/datum/antagonist/cultist, TRUE)
/proc/is_sacrifice_target(datum/mind/mind)
if(SSticker.mode.name == "cult")
var/datum/game_mode/cult/cult_mode = SSticker.mode
if(mind == cult_mode.sacrifice_target)
return 1
return 0
if(mind == GLOB.sac_mind)
return TRUE
return FALSE
/proc/is_convertable_to_cult(mob/living/M)
if(!istype(M))
return 0
return FALSE
if(M.mind)
if(ishuman(M) && (M.mind.assigned_role in list("Captain", "Chaplain")))
return 0
return FALSE
if(is_sacrifice_target(M.mind))
return 0
return FALSE
if(M.mind.enslaved_to && !iscultist(M.mind.enslaved_to))
return 0
return FALSE
else
return 0
return FALSE
if(M.isloyal() || issilicon(M) || isbot(M) || isdrone(M) || is_servant_of_ratvar(M))
return 0 //can't convert machines, shielded, or ratvar's dogs
return 1
return FALSE //can't convert machines, shielded, or ratvar's dogs
return TRUE
/datum/game_mode/cult
name = "cult"
@@ -45,12 +44,10 @@
<span class='notice'>Crew</span>: Prevent the cult from expanding and drive it out."
var/finished = 0
var/eldergod = 1 //for the summon god objective
var/acolytes_needed = 10 //for the survive objective
var/acolytes_survived = 0
var/datum/mind/sacrifice_target = null//The target to be sacrificed
var/list/cultists_to_cult = list() //the cultists we'll convert
@@ -88,10 +85,11 @@
if("survive")
explanation = "Our knowledge must live on. Make sure at least [acolytes_needed] acolytes escape on the shuttle to spread their work on an another station."
if("sacrifice")
if(sacrifice_target)
explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role] via invoking a Sacrifice rune with them on it and three acolytes around it."
if(GLOB.sac_mind)
explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role] via invoking a Sacrifice rune with them on it and three acolytes around it."
else
explanation = "Free objective."
explanation = "The veil has already been weakened here, proceed to the next objective."
GLOB.sac_complete = TRUE
if("eldergod")
explanation = "Summon Nar-Sie by invoking the rune 'Summon Nar-Sie' with nine acolytes on it. You must do this after sacrificing your target."
to_chat(cult_mind.current, "<B>Objective #[obj_count]</B>: [explanation]")
@@ -107,10 +105,17 @@
if(player.mind && !(player.mind in cultists_to_cult))
possible_targets += player.mind
if(possible_targets.len > 0)
sacrifice_target = pick(possible_targets)
GLOB.sac_target = sacrifice_target
if(!sacrifice_target)
GLOB.sac_mind = pick(possible_targets)
if(!GLOB.sac_mind)
message_admins("Cult Sacrifice: ERROR - Null target chosen!")
else
var/datum/job/sacjob = SSjob.GetJob(GLOB.sac_mind.assigned_role)
var/icon/reshape = get_flat_human_icon(null, sacjob, GLOB.sac_mind.current.client.prefs)
reshape.Shift(SOUTH, 4)
reshape.Shift(EAST, 1)
reshape.Crop(7,4,26,31)
reshape.Crop(-5,-3,26,30)
GLOB.sac_image = reshape
else
message_admins("Cult Sacrifice: Could not find unconvertable or convertable target. WELP!")
for(var/datum/mind/cult_mind in cultists_to_cult)
@@ -198,7 +203,7 @@
if(cult_objectives.Find("eldergod"))
cult_fail += eldergod //1 by default, 0 if the elder god has been summoned at least once
if(cult_objectives.Find("sacrifice"))
if(sacrifice_target && !GLOB.sacrificed.Find(sacrifice_target)) //if the target has been GLOB.sacrificed, ignore this step. otherwise, add 1 to cult_fail
if(GLOB.sac_mind && GLOB.sac_complete) //if the target has been GLOB.sacrificed, ignore this step. otherwise, add 1 to cult_fail
cult_fail++
return cult_fail //if any objectives aren't met, failure
@@ -243,16 +248,12 @@
feedback_add_details("cult_objective","cult_survive|FAIL|[acolytes_needed]")
SSticker.news_report = CULT_FAILURE
if("sacrifice")
if(sacrifice_target)
if(sacrifice_target in GLOB.sacrificed)
explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. <span class='greenannounce'>Success!</span>"
feedback_add_details("cult_objective","cult_sacrifice|SUCCESS")
else if(sacrifice_target && sacrifice_target.current)
explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. <span class='boldannounce'>Fail.</span>"
feedback_add_details("cult_objective","cult_sacrifice|FAIL")
else
explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. <span class='boldannounce'>Fail (Gibbed).</span>"
feedback_add_details("cult_objective","cult_sacrifice|FAIL|GIBBED")
if(GLOB.sac_complete)
explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role]. <span class='greenannounce'>Success!</span>"
feedback_add_details("cult_objective","cult_sacrifice|SUCCESS")
else
explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role]. <span class='boldannounce'>Fail.</span>"
feedback_add_details("cult_objective","cult_sacrifice|FAIL")
if("eldergod")
if(!eldergod)
explanation = "Summon Nar-Sie. <span class='greenannounce'>Success!</span>"
@@ -269,12 +270,41 @@
return 1
/datum/game_mode/proc/auto_declare_completion_cult()
if( cult.len || (SSticker && istype(SSticker.mode,/datum/game_mode/cult)) )
var/text = "<br><font size=3><b>The cultists were:</b></font>"
for(var/datum/mind/cultist in cult)
text += printplayer(cultist)
text += "<br>"
to_chat(world, text)
/datum/game_mode/proc/datum_cult_completion()
var/text = ""
var/acolytes_survived = 0
for(var/datum/mind/cult_mind in cult)
if (cult_mind.current && cult_mind.current.stat != DEAD)
if(cult_mind.current.onCentcom() || cult_mind.current.onSyndieBase())
acolytes_survived++
var/cult_fail = 0
cult_fail += eldergod
if(!GLOB.sac_complete)
cult_fail++
if(!cult_fail)
feedback_set_details("round_end_result","win - cult win")
feedback_set("round_end_result",acolytes_survived)
to_chat(world, "<span class='greentext'>The cult has succeeded! Nar-sie has snuffed out another torch in the void!</span>")
else
feedback_set_details("round_end_result","loss - staff stopped the cult")
feedback_set("round_end_result",acolytes_survived)
to_chat(world, "<span class='redtext'>The staff managed to stop the cult! Dark words and heresy are no match for Nanotrasen's finest!</span>")
if(cult_objectives.len)
text += "<br><b>The cultists' objectives were:</b>"
for(var/obj_count in 1 to 2)
var/explanation
switch(cult_objectives[obj_count])
if("sacrifice")
if(GLOB.sac_complete)
explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role]. <span class='greenannounce'>Success!</span>"
else
explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role]. <span class='boldannounce'>Fail.</span>"
if("eldergod")
if(!eldergod)
explanation = "Summon Nar-Sie. <span class='greenannounce'>Success!</span>"
SSticker.news_report = CULT_SUMMON
else
explanation = "Summon Nar-Sie. <span class='boldannounce'>Fail.</span>"
SSticker.news_report = CULT_FAILURE
text += "<br><B>Objective #[obj_count]</B>: [explanation]"
to_chat(world, text)

View File

@@ -75,6 +75,11 @@
set name = "Assert Leadership"
pollCultists(src)
/datum/action/innate/cultmast
background_icon_state = "bg_demon"
buttontooltipstyle = "cult"
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_CONSCIOUS
/datum/action/innate/cultmast/IsAvailable()
if(owner.mind.special_role != "Cult Master")
return 0
@@ -84,15 +89,13 @@
name = "Final Reckoning"
desc = "A single use spell that brings the entire cult to the master's location"
button_icon_state = "sintouch"
background_icon_state = "bg_demon"
buttontooltipstyle = "cult"
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_CONSCIOUS
/datum/action/innate/cultmast/finalreck/Activate()
var/list/destinations = list()
for(var/turf/T in orange(1,owner))
destinations += T
for(var/i in 1 to 4)
owner.chant(i)
if(do_after(owner, 30, target = owner))
for(var/datum/mind/B in SSticker.mode.cult)
if(isliving(B.current) && istype(B.current, /mob/living))
@@ -113,24 +116,35 @@
if(M != owner)
var/turf/final = pick(destinations)
new /obj/effect/overlay/temp/cult/blood(final)
addtimer(CALLBACK(M, /mob/living.proc/reckon, final), 10)
addtimer(CALLBACK(M, /mob/.proc/reckon, final), 10)
else
for(var/datum/action/innate/cultmast/finalreck/H in owner.actions)
qdel(H)
else
return
/mob/living/proc/reckon(var/turf/final)
/mob/proc/reckon(var/turf/final)
new /obj/effect/overlay/temp/cult/blood/out(get_turf(src))
forceMove(final)
/mob/proc/chant(var/i)
switch(i)
if (1)
say("C'arta Forbici!")
if (2)
say("Pleggh E'ntrath!")
playsound(get_turf(src),'sound/magic/clockwork/narsie_attack.ogg', 50, 1)
if (3)
say("Barhah hra Zar'garis!")
playsound(get_turf(src),'sound/magic/clockwork/narsie_attack.ogg', 75, 1)
if (4)
say("N'ath reth Sh'yro eth D'rekkathnor!!!")
playsound(get_turf(src),'sound/magic/clockwork/narsie_attack.ogg', 100, 1)
/datum/action/innate/cultmast/cultmark
name = "Mark Target"
desc = "Marks a target for the cult"
button_icon_state = "cult_mark"
background_icon_state = "bg_demon"
buttontooltipstyle = "cult"
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_CONSCIOUS
var/obj/effect/proc_holder/cultmark/CM
var/time = 0
@@ -141,20 +155,23 @@
/datum/action/innate/cultmast/cultmark/IsAvailable()
if(owner.mind.special_role != "Cult Master")
return 0
if((world.time - time)<1500)
owner << "<span class='cultlarge'><b>You need to wait [round((1500-(world.time-time))/10)] seconds before you can mark another target!</b></span>"
if((world.time - time)<1200 && !CM.active)
owner << "<span class='cultlarge'><b>You need to wait [round((1200-(world.time-time))/10)] seconds before you can mark another target!</b></span>"
return 0
return ..()
/datum/action/innate/cultmast/cultmark/Destroy()
qdel(CM)
CM = null
return ..()
qdel(CM)
CM = null
return ..()
/datum/action/innate/cultmast/cultmark/Activate()
CM.toggle(owner) //the important bit
time = world.time
return TRUE
CM.toggle(owner) //the important bit
if(!active)
time = world.time
else
time = 0
return TRUE
/obj/effect/proc_holder/cultmark
active = FALSE
@@ -173,43 +190,26 @@
if(ranged_ability_user.incapacitated())
remove_ranged_ability()
return
var/turf/T = ranged_ability_user.loc
var/turf/T = get_turf(ranged_ability_user)
if(!isturf(T))
return FALSE
if(target in view(7, get_turf(ranged_ability_user)))
remove_ranged_ability(caller, "The marking rite is complete! It will last for 90 seconds.")
GLOB.blood_target = target
for(var/datum/mind/M in SSticker.mode.cult)
M.current << "<span class='cultlarge'><b>Master [ranged_ability_user] has marked [GLOB.blood_target] as the cult's highest priority, get there immediately!</b></span>"
M.current << pick(sound('sound/hallucinations/over_here2.ogg',0,1,75), sound('sound/hallucinations/over_here3.ogg',0,1,75))
var/marked_turf = get_turf(GLOB.blood_target)
var/image/cult_marker = image('icons/effects/cult_target.dmi', marked_turf, "glow", ABOVE_MOB_LAYER)
M.current.client.images |= cult_marker
remove_ranged_ability(caller, "The marking rite is complete! It will last for one minute.")
addtimer(CALLBACK(GLOBAL_PROC, .proc/reset_blood_target), 1200, TIMER_OVERRIDE)
var/area/A = get_area(target)
for(var/datum/mind/B in SSticker.mode.cult)
var/mob/living/M = B.current
M << "<span class='cultlarge'><b>Master [ranged_ability_user] has marked [GLOB.blood_target] in the [A.name] as the cult's top priority, get there immediately!</b></span>"
M << pick(sound('sound/hallucinations/over_here2.ogg',0,1,75), sound('sound/hallucinations/over_here3.ogg',0,1,75))
var/image/cult_marker = image('icons/effects/cult_target.dmi', target, "glow", ABOVE_MOB_LAYER)
M.client.images |= cult_marker
addtimer(CALLBACK(M, /mob/living/proc/reset_blood_image, cult_marker), 900, TIMER_OVERRIDE)
return TRUE
return FALSE
/proc/reset_blood_target()
for(var/datum/mind/M in SSticker.mode.cult)
M.current << "<span class='cultlarge'><b>The blood mark on [GLOB.blood_target] has expired!</b></span>"
GLOB.blood_target = null
/*
obj/effect/cultmark
var/image/cult_marker
var/mob/living/viewer
obj/effect/cultmark/Initialize(var/mob/living/T, var/atom/BT)
..()
viewer = T
var/marked_turf = get_turf(BT)
cult_marker = image('icons/effects/cult_target.dmi', marked_turf, "glow", ABOVE_MOB_LAYER)
if(viewer.client)
viewer.client.images |= cult_marker
sleep(1200)
qdel(src)
/obj/effect/cultmark/Destroy()
if(viewer.client)
viewer.client.images.Remove(cult_marker)
return ..()*/
/mob/living/proc/reset_blood_image(var/image/cult_marker)
to_chat(src,"<span class='cultlarge'><b>The blood mark on [GLOB.blood_target] has ended!</b></span>")
if(client)
client.images.Remove(cult_marker)
cult_marker = null
GLOB.blood_target = null

View File

@@ -197,35 +197,30 @@ This file contains the arcane tome files.
if(!src || QDELETED(src) || !Adjacent(user) || user.incapacitated() || !check_rune_turf(Turf, user))
return
if(ispath(rune_to_scribe, /obj/effect/rune/narsie))
if(SSticker.mode.name == "cult")
var/datum/game_mode/cult/cult_mode = SSticker.mode
if(!("eldergod" in cult_mode.cult_objectives))
to_chat(user, "<span class='warning'>Nar-Sie does not wish to be summoned!</span>")
return
if(cult_mode.sacrifice_target && !(cult_mode.sacrifice_target in GLOB.sacrificed))
to_chat(user, "<span class='warning'>The sacrifice is not complete. The portal would lack the power to open if you tried!</span>")
return
if(!cult_mode.eldergod)
to_chat(user, "<span class='cultlarge'>\"I am already here. There is no need to try to summon me now.\"</span>")
return
if((loc.z && loc.z != ZLEVEL_STATION) || !A.blob_allowed)
to_chat(user, "<span class='warning'>The Geometer is not interested in lesser locations; the station is the prize!</span>")
return
var/confirm_final = alert(user, "This is the FINAL step to summon Nar-Sie, it is a long, painful ritual and the crew will be alerted to your presence", "Are you prepared for the final battle?", "My life for Nar-Sie!", "No")
if(confirm_final == "No")
to_chat(user, "<span class='cult'>You decide to prepare further before scribing the rune.</span>")
return
Turf = get_turf(user)
A = get_area(src)
if(!check_rune_turf(Turf, user) || (loc.z && loc.z != ZLEVEL_STATION)|| !A.blob_allowed)
return
priority_announce("Figments from an eldritch god are being summoned by [user] into [A.map_name] from an unknown dimension. Disrupt the ritual at all costs!","Central Command Higher Dimensional Affairs", 'sound/AI/spanomalies.ogg')
for(var/B in spiral_range_turfs(1, user, 1))
var/obj/structure/emergency_shield/sanguine/N = new(B)
shields += N
else
if(!("eldergod" in SSticker.mode.cult_objectives))
to_chat(user, "<span class='warning'>Nar-Sie does not wish to be summoned!</span>")
return
if(GLOB.sac_complete)
to_chat(user, "<span class='warning'>The sacrifice is not complete. The portal would lack the power to open if you tried!</span>")
return
if(!SSticker.mode.eldergod)
to_chat(user, "<span class='cultlarge'>\"I am already here. There is no need to try to summon me now.\"</span>")
return
if((loc.z && loc.z != ZLEVEL_STATION) || !A.blob_allowed)
to_chat(user, "<span class='warning'>The Geometer is not interested in lesser locations; the station is the prize!</span>")
return
var/confirm_final = alert(user, "This is the FINAL step to summon Nar-Sie, it is a long, painful ritual and the crew will be alerted to your presence", "Are you prepared for the final battle?", "My life for Nar-Sie!", "No")
if(confirm_final == "No")
to_chat(user, "<span class='cult'>You decide to prepare further before scribing the rune.</span>")
return
Turf = get_turf(user)
A = get_area(src)
if(!check_rune_turf(Turf, user) || (loc.z && loc.z != ZLEVEL_STATION)|| !A.blob_allowed)
return
priority_announce("Figments from an eldritch god are being summoned by [user] into [A.map_name] from an unknown dimension. Disrupt the ritual at all costs!","Central Command Higher Dimensional Affairs", 'sound/AI/spanomalies.ogg')
for(var/B in spiral_range_turfs(1, user, 1))
var/obj/structure/emergency_shield/sanguine/N = new(B)
shields += N
user.visible_message("<span class='warning'>[user] [user.blood_volume ? "cuts open their arm and begins writing in their own blood":"begins sketching out a strange design"]!</span>", \
"<span class='cult'>You [user.blood_volume ? "slice open your arm and ":""]begin drawing a sigil of the Geometer.</span>")
if(user.blood_volume)

View File

@@ -398,25 +398,24 @@ structure_check() searches for nearby cultist structures required for the invoca
return 1
/obj/effect/rune/convert/proc/do_sacrifice(mob/living/sacrificial, list/invokers)
var/big_sac = FALSE
if((((ishuman(sacrificial) || iscyborg(sacrificial)) && sacrificial.stat != DEAD) || is_sacrifice_target(sacrificial.mind)) && invokers.len < 3)
for(var/M in invokers)
to_chat(M, "<span class='cultitalic'>[sacrificial] is too greatly linked to the world! You need three acolytes!</span>")
log_game("Offer rune failed - not enough acolytes and target is living or sac target")
return FALSE
var/sacrifice_fulfilled = FALSE
if(sacrificial.mind)
GLOB.sacrificed += sacrificial.mind
if(is_sacrifice_target(sacrificial.mind))
sacrifice_fulfilled = TRUE
GLOB.sac_complete = TRUE
big_sac = TRUE
else
GLOB.sacrificed += sacrificial
new /obj/effect/overlay/temp/cult/sac(get_turf(src))
for(var/M in invokers)
if(sacrifice_fulfilled)
if(big_sac)
to_chat(M, "<span class='cultlarge'>\"Yes! This is the one I desire! You have done well.\"</span>")
GLOB.sac_complete = TRUE
else
if(ishuman(sacrificial) || iscyborg(sacrificial))
to_chat(M, "<span class='cultlarge'>\"I accept this sacrifice.\"</span>")
@@ -452,7 +451,7 @@ structure_check() searches for nearby cultist structures required for the invoca
scribe_delay = 450 //how long the rune takes to create
scribe_damage = 40.1 //how much damage you take doing it
var/used
var/ignore_gamemode = FALSE
var/ignore_gamemode = TRUE
/obj/effect/rune/narsie/Initialize(mapload, set_keyword)
. = ..()
@@ -491,7 +490,7 @@ structure_check() searches for nearby cultist structures required for the invoca
//BEGIN THE SUMMONING
used = 1
..()
send_to_playing_players('sound/effects/dimensional_rend.ogg') //There used to be a message for this but every time it was changed it got edgier so I removed it
send_to_playing_players('sound/effects/dimensional_rend.ogg')
var/turf/T = get_turf(src)
sleep(40)
if(src)

View File

@@ -258,6 +258,8 @@
if(escaped_total > 0)
feedback_set("escaped_total",escaped_total)
send2irc("Server", "Round just ended.")
if(cult.len && !istype(SSticker.mode,/datum/game_mode/cult))
datum_cult_completion()
return 0

View File

@@ -54,7 +54,7 @@
if(!ishuman(M))//If target is not a human.
return ..()
if(iscultist(M))
to_chat(user, "<span class='cultlarge'>\"Come now, do not capture your fellow's soul.\"</span>")
to_chat(user, "<span class='cultlarge'>\"Come now, do not capture your bretheren's soul.\"</span>")
return
add_logs(user, M, "captured [M.name]'s soul", src)
@@ -132,11 +132,11 @@
if("VICTIM")
var/mob/living/carbon/human/T = target
if(SSticker.mode.name == "cult" && T.mind == SSticker.mode:sacrifice_target)
if(is_sacrifice_target(T.mind))
if(iscultist(user))
to_chat(user, "<span class='cult'><b>\"This soul is mine.</b></span> <span class='cultlarge'>SACRIFICE THEM!\"</span>")
else
to_chat(user, "<span class='danger'>The soulstone doesn't work for no apparent reason.</span>")
to_chat(user, "<span class='danger'>The soulstone seems to reject this soul.</span>")
return 0
if(contents.len)
to_chat(user, "<span class='userdanger'>Capture failed!</span>: The soulstone is full! Free an existing soul to make room.")
@@ -188,7 +188,10 @@
else
makeNewConstruct(/mob/living/simple_animal/hostile/construct/builder/noncult, A, user, 0, T.loc)
for(var/datum/mind/B in SSticker.mode.cult)
if(B == A.mind)
SSticker.mode.cult -= A.mind
SSticker.mode.update_cult_icons_removed(A.mind)
qdel(T)
user.drop_item()
qdel(src)
@@ -200,6 +203,9 @@
var/mob/living/simple_animal/hostile/construct/newstruct = new ctype((loc_override) ? (loc_override) : (get_turf(target)))
if(stoner)
newstruct.faction |= "\ref[stoner]"
newstruct.master = stoner
var/datum/action/innate/seek_master/SM = new()
SM.Grant(newstruct)
newstruct.key = target.key
if(newstruct.mind && ((stoner && iscultist(stoner)) || cultoverride) && SSticker && SSticker.mode)
SSticker.mode.add_cultist(newstruct.mind, 0)
@@ -207,6 +213,9 @@
to_chat(newstruct, "<b>You are still bound to serve the cult[stoner ? " and [stoner]":""], follow their orders and help them complete their goals at all costs.</b>")
else if(stoner)
to_chat(newstruct, "<b>You are still bound to serve your creator, [stoner], follow their orders and help them complete their goals at all costs.</b>")
newstruct.throw_alert("bloodsense", /obj/screen/alert/bloodsense)
var/obj/screen/alert/bloodsense/BS = newstruct.alerts["bloodsense"]
BS.Cviewer = newstruct
newstruct.cancel_camera()

View File

@@ -30,12 +30,20 @@
deathmessage = "collapses in a shattered heap."
var/list/construct_spells = list()
var/playstyle_string = "<b>You are a generic construct! Your job is to not exist, and you should probably adminhelp this.</b>"
var/master = null
var/seeking = FALSE
/mob/living/simple_animal/hostile/construct/Initialize()
. = ..()
for(var/spell in construct_spells)
AddSpell(new spell(null))
/mob/living/simple_animal/hostile/construct/Destroy()
for(var/X in actions)
var/datum/action/A = X
qdel(A)
..()
/mob/living/simple_animal/hostile/construct/Login()
..()
to_chat(src, playstyle_string)
@@ -268,3 +276,36 @@
/mob/living/simple_animal/hostile/construct/harvester/hostile //actually hostile, will move around, hit things
AIStatus = AI_ON
environment_smash = 1 //only token destruction, don't smash the cult wall NO STOP
///////////////////////Master-Tracker///////////////////////
/datum/action/innate/seek_master
name = "Seek your Master"
desc = "You and your master share a soul-link that informs you of their location"
background_icon_state = "bg_demon"
buttontooltipstyle = "cult"
button_icon_state = "cult_mark"
var/tracking = FALSE
var/mob/living/simple_animal/hostile/construct/the_construct
/datum/action/innate/seek_master/Grant(var/mob/living/C)
the_construct = C
..()
/datum/action/innate/seek_master/Activate()
if(!the_construct.master)
to_chat(the_construct, "<span class='cultitalic'>You have no master to seek!</span>")
the_construct.seeking = FALSE
return
if(tracking)
tracking = FALSE
the_construct.seeking = FALSE
to_chat(the_construct, "<span class='cultitalic'>You are no longer tracking your master.</span>")
return
else
tracking = TRUE
the_construct.seeking = TRUE
to_chat(the_construct, "<span class='cultitalic'>You are now tracking your master.</span>")

View File

@@ -1 +1 @@
cult
extended

Binary file not shown.

Before

Width:  |  Height:  |  Size: 185 KiB

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 96 KiB