diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 2df42fbb51..ec78eb49b2 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -6,7 +6,7 @@ ) #define Z_TURFS(ZLEVEL) block(locate(1,1,ZLEVEL), locate(world.maxx, world.maxy, ZLEVEL)) -#define CULT_POLL_WAIT 2400 +#define CULT_POLL_WAIT 2400 /proc/get_area(atom/A) if (!istype(A)) @@ -314,10 +314,10 @@ // Will return a list of active candidates. It increases the buffer 5 times until it finds a candidate which is active within the buffer. -/proc/get_candidates(be_special_type, afk_bracket = config.inactivity_period, jobbanType) +/proc/get_candidates(be_special_type, afk_bracket = config.inactivity_period, jobbanType) var/list/candidates = list() // Keep looping until we find a non-afk candidate within the time bracket (we limit the bracket to 10 minutes (6000)) - while(!candidates.len && afk_bracket < config.afk_period) + while(!candidates.len && afk_bracket < config.afk_period) for(var/mob/dead/observer/G in GLOB.player_list) if(G.client != null) if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD)) @@ -486,69 +486,66 @@ ++i return L -/proc/pollCultists(var/mob/living/Nominee) // Cult Master Poll - var/time_passed = world.time - var/list/yes_voters = new - var/list/cult_total = new - 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(!isliving(B.current)) - continue - var/mob/living/M = B.current - if(isliving(M)) - M << 'sound/hallucinations/im_here1.ogg' - M.verbs -= /mob/living/proc/cult_master - to_chat(M, "Acolyte [Nominee] has asserted that they are worthy of leading the cult. A vote will be called shortly.") - 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 << "Sorry, your vote came too late!" - M << 'sound/machines/buzz-sigh.ogg' - else - M << "Choice registered: Yes." - yes_voters += M - cult_total += M - if(2) - if((world.time-time_passed)>500) - M << "Sorry, your vote came too late!" - M << 'sound/machines/buzz-sigh.ogg' - else - M << "Choice registered: No." - cult_total += M - if(3) - M << "Choice registered: Abstain." - 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() - FinalReckoning.Grant(Nominee) - Mark.Grant(Nominee) - Nominee.mind.special_role = "Cult Master" - Nominee.update_action_buttons_icon() - Nominee.apply_status_effect(/datum/status_effect/cult_master) - SSticker.mode.set_antag_hud(Nominee,"cultmaster") - GLOB.cult_mastered = TRUE - for(var/datum/mind/B in SSticker.mode.cult) - if(!B.current.incapacitated()) - to_chat(B.current,"[Nominee] has the cult's support and is now their master. Follow their orders to the best of your ability!") - return TRUE - else - for(var/datum/mind/B in SSticker.mode.cult) - if(!B.current.incapacitated()) - to_chat(B.current, "[Nominee] could not win the cult's support and shall continue to serve as an acolyte.") - B.current.verbs += /mob/living/proc/cult_master - return FALSE - -/proc/poll_helper(var/mob/living/M) - +/proc/pollCultists(var/mob/living/Nominee) // Cult Master Poll + var/time_passed = world.time + var/list/yes_voters = new + var/list/cult_total = new + if(world.time < CULT_POLL_WAIT) + Nominee << "It would be premature to select a leader while everyone is still settling in, try again in [round((CULT_POLL_WAIT-world.time)/10)] seconds" + return + for(var/datum/mind/B in SSticker.mode.cult) + var/mob/living/M = B.current + if(!M.incapacitated()) + M << 'sound/hallucinations/im_here1.ogg' + M.verbs -= /mob/living/proc/cult_master + to_chat(M, "Acolyte [Nominee] has asserted that they are worthy of leading the cult. A vote will be called shortly.") + sleep(250) + for(var/datum/mind/B in SSticker.mode.cult) + var/mob/living/M = B.current + if(!M.incapacitated()) + 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) + to_chat(M, "Sorry, your vote came too late!") + M << 'sound/machines/buzz-sigh.ogg' + else + M << "Choice registered: Yes." + yes_voters += M + cult_total += M + if(2) + if((world.time-time_passed)>500) + to_chat(M, "Sorry, your vote came too late!") + M << 'sound/machines/buzz-sigh.ogg' + else + to_chat(M, "Choice registered: No.") + cult_total += M + if(3) + to_chat(M, "Choice registered: Abstain.") + 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() + FinalReckoning.Grant(Nominee) + Mark.Grant(Nominee) + Nominee.mind.special_role = "Cult Master" + Nominee.update_action_buttons_icon() + Nominee.apply_status_effect(/datum/status_effect/cult_master) + SSticker.mode.set_antag_hud(Nominee,"cultmaster") + GLOB.cult_mastered = TRUE + for(var/datum/mind/B in SSticker.mode.cult) + if(!B.current.incapacitated()) + to_chat(B.current,"[Nominee] has the cult's support and is now their master. Follow their orders to the best of your ability!") + return TRUE + else + for(var/datum/mind/B in SSticker.mode.cult) + if(!B.current.incapacitated()) + to_chat(B.current, "[Nominee] could not win the cult's support and shall continue to serve as an acolyte.") + 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 @@ -577,7 +574,7 @@ winset(C, "mainwindow", "flash=5") /proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank) - if(!SSticker.IsRoundInProgress() || !character) + if(!SSticker.IsRoundInProgress() || !character) return var/area/A = get_area(character) var/message = "\ diff --git a/code/datums/antagonists/datum_cult.dm b/code/datums/antagonists/datum_cult.dm index 30c0aa8450..59f165ff37 100644 --- a/code/datums/antagonists/datum_cult.dm +++ b/code/datums/antagonists/datum_cult.dm @@ -5,6 +5,51 @@ qdel(communion) return ..() +/datum/antagonist/cult/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) && (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/datum/preferences/sacface = GLOB.sac_mind.current.client.prefs + var/icon/reshape = get_flat_human_icon(null, sacjob, sacface) + 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/cult/proc/cult_memorization(datum/mind/cult_mind) + var/mob/living/current = cult_mind.current + for(var/obj_count = 1,obj_count <= SSticker.mode.cult_objectives.len,obj_count++) + 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(current, "Objective #[obj_count]: [explanation]") + cult_mind.memory += "Objective #[obj_count]: [explanation]
" + /datum/antagonist/cult/can_be_owned(datum/mind/new_owner) . = ..() if(.) @@ -12,14 +57,17 @@ /datum/antagonist/cult/on_gain() . = ..() - SSticker.mode.cult += owner + var/mob/living/current = owner.current + if(SSticker.mode.cult_objectives.len == 0) + add_objectives() + return + SSticker.mode.cult += owner // Only add after they've been given objectives + cult_memorization(owner) + if(jobban_isbanned(current, ROLE_CULTIST)) + addtimer(CALLBACK(SSticker.mode, /datum/game_mode.proc/replace_jobbaned_player, current, ROLE_CULTIST, ROLE_CULTIST), 0) SSticker.mode.update_cult_icons_added(owner) - if(istype(SSticker.mode, /datum/game_mode/cult)) - var/datum/game_mode/cult/C = SSticker.mode - C.memorize_cult_objectives(owner) - if(jobban_isbanned(owner.current, ROLE_CULTIST)) - addtimer(CALLBACK(SSticker.mode, /datum/game_mode.proc/replace_jobbaned_player, owner.current, ROLE_CULTIST, ROLE_CULTIST), 0) - owner.current.log_message("Has been converted to the cult of Nar'Sie!", INDIVIDUAL_ATTACK_LOG) + current.throw_alert("bloodsense", /obj/screen/alert/bloodsense) + current.log_message("Has been converted to the cult of Nar'Sie!", INDIVIDUAL_ATTACK_LOG) /datum/antagonist/cult/apply_innate_effects(mob/living/mob_override) . = ..() @@ -28,6 +76,8 @@ current = mob_override current.faction |= "cult" current.verbs += /mob/living/proc/cult_help + if(!GLOB.cult_mastered) + current.verbs += /mob/living/proc/cult_master communion.Grant(current) /datum/antagonist/cult/remove_innate_effects(mob/living/mob_override) @@ -38,6 +88,10 @@ current.faction -= "cult" current.verbs -= /mob/living/proc/cult_help communion.Remove(current) + owner.current.verbs -= /mob/living/proc/cult_master + for(var/datum/action/innate/cultmast/H in owner.current.actions) + qdel(H) + current.clear_alert("bloodsense") /datum/antagonist/cult/on_removal() owner.wipe_memory() diff --git a/code/datums/mind.dm b/code/datums/mind.dm index f4a535e4c4..22ac5c65d6 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -52,7 +52,7 @@ var/linglink var/miming = 0 // Mime's vow of silence - var/list/antag_datums + var/list/antag_datums var/antag_hud_icon_state = null //this mind's ANTAG_HUD should have this icon_state var/datum/atom_hud/antag/antag_hud = null //this mind's antag HUD var/datum/gang/gang_datum //Which gang this mind belongs to, if any @@ -69,10 +69,10 @@ /datum/mind/Destroy() SSticker.minds -= src - if(islist(antag_datums)) - for(var/i in antag_datums) - qdel(i) - antag_datums = null + if(islist(antag_datums)) + for(var/i in antag_datums) + qdel(i) + antag_datums = null return ..() /datum/mind/proc/transfer_to(mob/new_character, var/force_key_move = 0) @@ -90,12 +90,12 @@ new_character.mind.current = null var/datum/atom_hud/antag/hud_to_transfer = antag_hud//we need this because leave_hud() will clear this list - var/mob/living/old_current = current + var/mob/living/old_current = current current = new_character //associate ourself with our new body new_character.mind = src //and associate our new body with ourself - for(var/a in antag_datums) //Makes sure all antag datums effects are applied in the new body - var/datum/antagonist/A = a - A.on_body_transfer(old_current, current) + for(var/a in antag_datums) //Makes sure all antag datums effects are applied in the new body + var/datum/antagonist/A = a + A.on_body_transfer(old_current, current) if(iscarbon(new_character)) var/mob/living/carbon/C = new_character C.last_mind = src @@ -111,42 +111,42 @@ /datum/mind/proc/wipe_memory() memory = null -// Datum antag mind procs -/datum/mind/proc/add_antag_datum(datum_type) - if(!datum_type) - return - var/datum/antagonist/A = new datum_type(src) - if(!A.can_be_owned(src)) - qdel(A) - return - LAZYADD(antag_datums, A) - A.on_gain() - return A - -/datum/mind/proc/remove_antag_datum(datum_type) - if(!datum_type) - return - var/datum/antagonist/A = has_antag_datum(datum_type) - if(A) - A.on_removal() - return TRUE - -/datum/mind/proc/remove_all_antag_datums() //For the Lazy amongst us. - for(var/a in antag_datums) - var/datum/antagonist/A = a - A.on_removal() - -/datum/mind/proc/has_antag_datum(datum_type, check_subtypes = TRUE) - if(!datum_type) - return - . = FALSE - for(var/a in antag_datums) - var/datum/antagonist/A = a - if(check_subtypes && istype(A, datum_type)) - return A - else if(A.type == datum_type) - return A - +// Datum antag mind procs +/datum/mind/proc/add_antag_datum(datum_type) + if(!datum_type) + return + var/datum/antagonist/A = new datum_type(src) + if(!A.can_be_owned(src)) + qdel(A) + return + LAZYADD(antag_datums, A) + A.on_gain() + return A + +/datum/mind/proc/remove_antag_datum(datum_type) + if(!datum_type) + return + var/datum/antagonist/A = has_antag_datum(datum_type) + if(A) + A.on_removal() + return TRUE + +/datum/mind/proc/remove_all_antag_datums() //For the Lazy amongst us. + for(var/a in antag_datums) + var/datum/antagonist/A = a + A.on_removal() + +/datum/mind/proc/has_antag_datum(datum_type, check_subtypes = TRUE) + if(!datum_type) + return + . = FALSE + for(var/a in antag_datums) + var/datum/antagonist/A = a + if(check_subtypes && istype(A, datum_type)) + return A + else if(A.type == datum_type) + return A + /* Removes antag type's references from a mind. objectives, uplinks, powers etc are all handled. @@ -293,7 +293,7 @@ to_chat(recipient, "[output]") /datum/mind/proc/edit_memory() - if(!SSticker.HasRoundStarted()) + if(!SSticker.HasRoundStarted()) alert("Not before round-start!", "Alert") return @@ -1181,7 +1181,7 @@ log_admin("[key_name_admin(usr)] has made [current] unable to ascend as a devil.") return if(!ishuman(current) && !iscyborg(current)) - to_chat(usr, "This only works on humans and cyborgs!") + to_chat(usr, "This only works on humans and cyborgs!") return SSticker.mode.devils += src special_role = "devil" @@ -1230,17 +1230,17 @@ log_admin("[key_name(usr)] turned [current] into abductor.") SSticker.mode.update_abductor_icons_added(src) if("equip") - if(!ishuman(current)) - to_chat(usr, "This only works on humans!") - return - - var/mob/living/carbon/human/H = current + if(!ishuman(current)) + to_chat(usr, "This only works on humans!") + return + + var/mob/living/carbon/human/H = current var/gear = alert("Agent or Scientist Gear","Gear","Agent","Scientist") if(gear) if(gear=="Agent") - H.equipOutfit(/datum/outfit/abductor/agent) + H.equipOutfit(/datum/outfit/abductor/agent) else - H.equipOutfit(/datum/outfit/abductor/scientist) + H.equipOutfit(/datum/outfit/abductor/scientist) else if (href_list["monkey"]) var/mob/living/L = current @@ -1437,8 +1437,8 @@ special_role = "Cultist" to_chat(current, "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.") to_chat(current, "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.") - var/datum/game_mode/cult/cult = SSticker.mode - cult.memorize_cult_objectives(src) + var/datum/antagonist/cult/C + C.cult_memorization(src) var/mob/living/carbon/human/H = current if (!SSticker.mode.equip_cultist(current)) to_chat(H, "Spawning an amulet from your Master failed.") @@ -1502,8 +1502,8 @@ H.set_species(/datum/species/abductor) var/datum/species/abductor/S = H.dna.species - if(role == "Scientist") - S.scientist = TRUE + if(role == "Scientist") + S.scientist = TRUE S.team = team var/list/obj/effect/landmark/abductor/agent_landmarks = new @@ -1522,8 +1522,8 @@ if("Agent") L = agent_landmarks[team] if("Scientist") - L = scientist_landmarks[team] - H.forceMove(L.loc) + L = scientist_landmarks[team] + H.forceMove(L.loc) /datum/mind/proc/AddSpell(obj/effect/proc_holder/spell/S) spell_list += S diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index b67ad1f74b..3b30d3e44a 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -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.mind && M.mind.has_antag_datum(ANTAG_DATUM_CULT) /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" @@ -34,10 +33,10 @@ antag_flag = ROLE_CULTIST restricted_jobs = list("Chaplain","AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel") protected_jobs = list() - required_players = 1 - required_enemies = 1 - recommended_enemies = 1 - enemy_minimum_age = 0 + required_players = 24 + required_enemies = 4 + recommended_enemies = 4 + enemy_minimum_age = 14 announce_span = "cult" announce_text = "Some crew members are trying to start a cult to Nar-Sie!\n\ @@ -79,23 +78,6 @@ return (cultists_to_cult.len>=required_enemies) -/datum/game_mode/cult/proc/memorize_cult_objectives(datum/mind/cult_mind) - for(var/obj_count = 1,obj_count <= cult_objectives.len,obj_count++) - var/explanation - switch(cult_objectives[obj_count]) - 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(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 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, "Objective #[obj_count]: [explanation]") - cult_mind.memory += "Objective #[obj_count]: [explanation]
" - /datum/game_mode/cult/post_setup() modePlayer += cultists_to_cult if("sacrifice" in cult_objectives) @@ -111,7 +93,8 @@ 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) + var/datum/preferences/sacface = GLOB.sac_mind.current.client.prefs + var/icon/reshape = get_flat_human_icon(null, sacjob, sacface) reshape.Shift(SOUTH, 4) reshape.Shift(EAST, 1) reshape.Crop(7,4,26,31) @@ -249,16 +232,12 @@ SSblackbox.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]. Success!" - SSblackbox.add_details("cult_objective","cult_sacrifice|SUCCESS") - else if(sacrifice_target && sacrifice_target.current) - explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Fail." - SSblackbox.add_details("cult_objective","cult_sacrifice|FAIL") - else - explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Fail (Gibbed)." - SSblackbox.add_details("cult_objective","cult_sacrifice|FAIL|GIBBED") + if(GLOB.sac_complete) + explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role]. Success!" + SSblackbox.add_details("cult_objective","cult_sacrifice|SUCCESS") + else + explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role]. Fail." + SSblackbox.add_details("cult_objective","cult_sacrifice|FAIL") if("eldergod") if(!eldergod) explanation = "Summon Nar-Sie. Success!" diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index a496715af2..2ec87b1945 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -258,6 +258,8 @@ if(escaped_total > 0) SSblackbox.set_val("escaped_total",escaped_total) send2irc("Server", "Round just ended.") + if(cult.len && !istype(SSticker.mode,/datum/game_mode/cult)) + datum_cult_completion() return 0 diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index 37ef42291d..7285c2fa75 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -14,8 +14,8 @@ stop_automated_movement = 1 status_flags = CANPUSH attack_sound = 'sound/weapons/punch1.ogg' - see_in_dark = 7 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + see_in_dark = 7 + lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 @@ -31,20 +31,20 @@ deathmessage = "collapses in a shattered heap." var/list/construct_spells = list() var/playstyle_string = "You are a generic construct! Your job is to not exist, and you should probably adminhelp this." - var/master = null - var/seeking = FALSE + 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/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) @@ -92,11 +92,11 @@ /mob/living/simple_animal/hostile/construct/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE) return 0 - -/mob/living/simple_animal/hostile/construct/adjustHealth(amount, updating_health = TRUE, forced = FALSE) - . = ..() - if(updating_health) - update_health_hud() + +/mob/living/simple_animal/hostile/construct/adjustHealth(amount, updating_health = TRUE, forced = FALSE) + . = ..() + if(updating_health) + update_health_hud() /////////////////Juggernaut/////////////// /mob/living/simple_animal/hostile/construct/armored @@ -127,6 +127,38 @@ 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, "You have no master to seek!") + the_construct.seeking = FALSE + return + if(tracking) + tracking = FALSE + the_construct.seeking = FALSE + to_chat(the_construct, "You are no longer tracking your master.") + return + else + tracking = TRUE + the_construct.seeking = TRUE + to_chat(the_construct, "You are now tracking your master.") + + /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) @@ -281,22 +313,22 @@ /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 - - - -/////////////////////////////ui stuff///////////////////////////// - -/mob/living/simple_animal/hostile/construct/update_health_hud() - if(hud_used) - if(health >= maxHealth) - hud_used.healths.icon_state = "[icon_state]_health0" - else if(health > maxHealth*0.8) - hud_used.healths.icon_state = "[icon_state]_health2" - else if(health > maxHealth*0.6) - hud_used.healths.icon_state = "[icon_state]_health3" - else if(health > maxHealth*0.4) - hud_used.healths.icon_state = "[icon_state]_health4" - else if(health > maxHealth*0.2) - hud_used.healths.icon_state = "[icon_state]_health5" - else + + + +/////////////////////////////ui stuff///////////////////////////// + +/mob/living/simple_animal/hostile/construct/update_health_hud() + if(hud_used) + if(health >= maxHealth) + hud_used.healths.icon_state = "[icon_state]_health0" + else if(health > maxHealth*0.8) + hud_used.healths.icon_state = "[icon_state]_health2" + else if(health > maxHealth*0.6) + hud_used.healths.icon_state = "[icon_state]_health3" + else if(health > maxHealth*0.4) + hud_used.healths.icon_state = "[icon_state]_health4" + else if(health > maxHealth*0.2) + hud_used.healths.icon_state = "[icon_state]_health5" + else hud_used.healths.icon_state = "[icon_state]_health6" \ No newline at end of file