From 6f2b229bf266e090cbca5ac3d0027b35133ec409 Mon Sep 17 00:00:00 2001 From: Feenie <62373791+FeenieRU@users.noreply.github.com> Date: Wed, 23 Oct 2024 01:15:25 +0300 Subject: [PATCH 001/344] qdel optimize (#3558) ## About The Pull Request That PR optimizes qdel and SSgarbage procs. Based on: https://github.com/tgstation/tgstation/pull/79568 https://github.com/tgstation/tgstation/pull/76956 https://github.com/tgstation/tgstation/pull/80443 https://github.com/tgstation/tgstation/pull/80628 ## Why It's Good For The Game Better performance. Tested on downstream: https://github.com/CeladonSS13/Shiptest/pull/1025 ## Changelog :cl: code: Changing qdel() and SSgarbage procs code: rewrite /Destroy(force, silent) to /Destroy(force) /:cl: --------- Signed-off-by: Feenie <62373791+FeenieRU@users.noreply.github.com> --- code/__DEFINES/dcs/signals/signals.dm | 1 + code/controllers/master.dm | 4 + code/controllers/subsystem.dm | 27 +- code/controllers/subsystem/garbage.dm | 243 ++++++++++-------- code/datums/aquarium.dm | 2 +- code/datums/components/admin_popup.dm | 2 +- code/datums/components/aquarium.dm | 2 +- code/datums/components/attachment.dm | 2 +- code/datums/components/attachment_holder.dm | 2 +- code/datums/components/creamed.dm | 2 +- code/datums/components/deadchat_control.dm | 2 +- code/datums/components/food/edible.dm | 2 +- code/datums/components/food/food_storage.dm | 2 +- code/datums/components/gunpoint.dm | 2 +- code/datums/components/manual_blinking.dm | 2 +- code/datums/components/manual_breathing.dm | 2 +- code/datums/components/pellet_cloud.dm | 2 +- code/datums/components/shielded.dm | 2 +- code/datums/components/weatherannouncer.dm | 2 +- code/datums/datum.dm | 22 +- code/datums/elements/food/edible.dm | 2 +- code/datums/progressbar.dm | 8 +- code/game/machinery/camera/camera.dm | 5 + code/modules/admin/verbs/debug.dm | 3 + .../view_variables/reference_tracking.dm | 224 +++++++++------- code/modules/clothing/chameleon.dm | 92 +++---- code/modules/unit_tests/create_and_destroy.dm | 3 + .../unit_tests/find_reference_sanity.dm | 46 ++-- 28 files changed, 426 insertions(+), 284 deletions(-) diff --git a/code/__DEFINES/dcs/signals/signals.dm b/code/__DEFINES/dcs/signals/signals.dm index 638b5220bc3c..ce91420033dc 100644 --- a/code/__DEFINES/dcs/signals/signals.dm +++ b/code/__DEFINES/dcs/signals/signals.dm @@ -42,6 +42,7 @@ #define COMSIG_COMPONENT_REMOVING "component_removing" /// before a datum's Destroy() is called: (force), returning a nonzero value will cancel the qdel operation #define COMSIG_PARENT_PREQDELETED "parent_preqdeleted" +#define COMSIG_PREQDELETED "parent_preqdeleted" /// just before a datum's Destroy() is called: (force), at this point none of the other components chose to interrupt qdel and Destroy will be called #define COMSIG_PARENT_QDELETING "parent_qdeleting" /// generic topic handler (usr, href_list) diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 302c0de4a427..46090ebb48c5 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -489,6 +489,10 @@ GLOBAL_REAL(Master, /datum/controller/master) = new continue if ((SS_flags & (SS_TICKER|SS_KEEP_TIMING)) == SS_KEEP_TIMING && SS.last_fire + (SS.wait * 0.75) > world.time) continue + if (SS.postponed_fires >= 1) + SS.postponed_fires-- + SS.update_nextfire() + continue SS.enqueue() . = 1 diff --git a/code/controllers/subsystem.dm b/code/controllers/subsystem.dm index f6e35bec6e59..332fcef0787c 100644 --- a/code/controllers/subsystem.dm +++ b/code/controllers/subsystem.dm @@ -75,6 +75,9 @@ /// Tracks the amount of completed runs for the subsystem var/times_fired = 0 + /// How many fires have we been requested to postpone + var/postponed_fires = 0 + /// Time the subsystem entered the queue, (for timing and priority reasons) var/queued_time = 0 @@ -132,6 +135,26 @@ Master.subsystems -= src return ..() +/datum/controller/subsystem/proc/update_nextfire(reset_time = FALSE) + var/queue_node_flags = flags + + if (reset_time) + postponed_fires = 0 + if (queue_node_flags & SS_TICKER) + next_fire = world.time + (world.tick_lag * wait) + else + next_fire = world.time + wait + return + + if (queue_node_flags & SS_TICKER) + next_fire = world.time + (world.tick_lag * wait) + else if (queue_node_flags & SS_POST_FIRE_TIMING) + next_fire = world.time + wait + (world.tick_lag * (tick_overrun/100)) + else if (queue_node_flags & SS_KEEP_TIMING) + next_fire += wait + else + next_fire = queued_time + wait + (world.tick_lag * (tick_overrun/100)) + //Queue it to run. // (we loop thru a linked list until we get to the end or find the right point) // (this lets us sort our run order correctly without having to re-sort the entire already sorted list) @@ -251,8 +274,8 @@ //could be used to postpone a costly subsystem for (default one) var/cycles, cycles //for instance, during cpu intensive operations like explosions /datum/controller/subsystem/proc/postpone(cycles = 1) - if(next_fire - world.time < wait) - next_fire += (wait*cycles) + if (can_fire && cycles >= 1) + postponed_fires += cycles //usually called via datum/controller/subsystem/New() when replacing a subsystem (i.e. due to a recurring crash) //should attempt to salvage what it can from the old instance of subsystem diff --git a/code/controllers/subsystem/garbage.dm b/code/controllers/subsystem/garbage.dm index da58d4764516..60372d39d95b 100644 --- a/code/controllers/subsystem/garbage.dm +++ b/code/controllers/subsystem/garbage.dm @@ -94,32 +94,38 @@ SUBSYSTEM_DEF(garbage) /datum/controller/subsystem/garbage/Shutdown() //Adds the del() log to the qdel log file - var/list/dellog = list() + var/list/del_log = list() //sort by how long it's wasted hard deleting sortTim(items, cmp=/proc/cmp_qdel_item_time, associative = TRUE) for(var/path in items) var/datum/qdel_item/I = items[path] - dellog += "Path: [path]" + var/list/entry = list() + del_log[path] = entry + if (I.qdel_flags & QDEL_ITEM_SUSPENDED_FOR_LAG) - dellog += "\tSUSPENDED FOR LAG" + entry["SUSPENDED FOR LAG"] = TRUE if (I.failures) - dellog += "\tFailures: [I.failures]" - dellog += "\tqdel() Count: [I.qdels]" - dellog += "\tDestroy() Cost: [I.destroy_time]ms" + entry["Failures"] = I.failures + entry["qdel() Count"] = I.qdels + entry["Destroy() Cost (ms)"] = I.destroy_time + if (I.hard_deletes) - dellog += "\tTotal Hard Deletes: [I.hard_deletes]" - dellog += "\tTime Spent Hard Deleting: [I.hard_delete_time]ms" - dellog += "\tHighest Time Spent Hard Deleting: [I.hard_delete_max]ms" + entry["Total Hard Deletes"] = I.hard_deletes + entry["Time Spend Hard Deleting (ms)"] = I.hard_delete_time + entry["Highest Time Spend Hard Deleting (ms)"] = I.hard_delete_max if (I.hard_deletes_over_threshold) - dellog += "\tHard Deletes Over Threshold: [I.hard_deletes_over_threshold]" + entry["Hard Deletes Over Threshold"] = I.hard_deletes_over_threshold if (I.slept_destroy) - dellog += "\tSleeps: [I.slept_destroy]" + entry["Total Sleeps"] = I.slept_destroy if (I.no_respect_force) - dellog += "\tIgnored force: [I.no_respect_force] times" + entry["Total Ignored Force"] = I.no_respect_force if (I.no_hint) - dellog += "\tNo hint: [I.no_hint] times" - log_qdel(dellog.Join("\n")) + entry["Total No Hint"] = I.no_hint + if(LAZYLEN(I.extra_details)) + entry["Deleted Metadata"] = I.extra_details + + log_qdel("", del_log) /datum/controller/subsystem/garbage/fire() //the fact that this resets its processing each fire (rather then resume where it left off) is intentional. @@ -139,8 +145,6 @@ SUBSYSTEM_DEF(garbage) state = SS_RUNNING break - - /datum/controller/subsystem/garbage/proc/InitQueues() if (isnull(queues)) // Only init the queues if they don't already exist, prevents overriding of recovered lists queues = new(GC_QUEUE_COUNT) @@ -167,7 +171,10 @@ SUBSYSTEM_DEF(garbage) lastlevel = level - //We do this rather then for(var/refID in queue) because that sort of for loop copies the whole list. +// 1 from the hard reference in the queue, and 1 from the variable used before this +#define REFS_WE_EXPECT 2 + + //We do this rather then for(var/list/ref_info in queue) because that sort of for loop copies the whole list. //Normally this isn't expensive, but the gc queue can grow to 40k items, and that gets costly/causes overrun. for (var/i in 1 to length(queue)) var/list/L = queue[i] @@ -178,21 +185,19 @@ SUBSYSTEM_DEF(garbage) continue var/queued_at_time = L[GC_QUEUE_ITEM_QUEUE_TIME] - var/GCd_at_time = L[GC_QUEUE_ITEM_GCD_DESTROYED] if(queued_at_time > cut_off_time) break // Everything else is newer, skip them count++ - var/refID = L[GC_QUEUE_ITEM_REF] - var/datum/D - D = locate(refID) + var/datum/D = L[GC_QUEUE_ITEM_REF] - if (!D || D.gc_destroyed != GCd_at_time) // So if something else coincidently gets the same ref, it's not deleted by mistake + // If that's all we've got, send er off + if (refcount(D) == REFS_WE_EXPECT) ++gcedlasttick ++totalgcs pass_counts[level]++ #ifdef REFERENCE_TRACKING - reference_find_on_fail -= refID //It's deleted we don't care anymore. + reference_find_on_fail -= text_ref(D) //It's deleted we don't care anymore. #endif if (MC_TICK_CHECK) return @@ -208,20 +213,30 @@ SUBSYSTEM_DEF(garbage) switch (level) if (GC_QUEUE_CHECK) #ifdef REFERENCE_TRACKING - if(reference_find_on_fail[refID]) - INVOKE_ASYNC(D, TYPE_PROC_REF(/datum, find_references)) + // Decides how many refs to look for (potentially) + // Based off the remaining and the ones we can account for + var/remaining_refs = refcount(D) - REFS_WE_EXPECT + if(reference_find_on_fail[text_ref(D)]) + INVOKE_ASYNC(D, TYPE_PROC_REF(/datum,find_references), remaining_refs) ref_searching = TRUE #ifdef GC_FAILURE_HARD_LOOKUP else - INVOKE_ASYNC(D, TYPE_PROC_REF(/datum, find_references)) + INVOKE_ASYNC(D, TYPE_PROC_REF(/datum,find_references), remaining_refs) ref_searching = TRUE #endif - reference_find_on_fail -= refID + reference_find_on_fail -= text_ref(D) #endif var/type = D.type var/datum/qdel_item/I = items[type] - log_world("## TESTING: GC: -- [text_ref(D)] | [type] was unable to be GC'd --") + var/message = "## TESTING: GC: -- [text_ref(D)] | [type] was unable to be GC'd --" + message = "[message] (ref count of [refcount(D)])" + log_world(message) + + var/detail = D.dump_harddel_info() + if(detail) + LAZYADD(I.extra_details, detail) + #ifdef TESTING for(var/c in GLOB.admins) //Using testing() here would fill the logs with ADMIN_VV garbage var/client/admin = c @@ -231,6 +246,12 @@ SUBSYSTEM_DEF(garbage) #endif I.failures++ + if (I.qdel_flags & QDEL_ITEM_SUSPENDED_FOR_LAG) + #ifdef REFERENCE_TRACKING + if(ref_searching) + return //ref searching intentionally cancels all further fires while running so things that hold references don't end up getting deleted, so we want to return here instead of continue + #endif + continue if (GC_QUEUE_HARDDELETE) HardDelete(D) if (MC_TICK_CHECK) @@ -250,41 +271,41 @@ SUBSYSTEM_DEF(garbage) queue.Cut(1,count+1) count = 0 +#undef REFS_WE_EXPECT + /datum/controller/subsystem/garbage/proc/Queue(datum/D, level = GC_QUEUE_FILTER) if (isnull(D)) return if (level > GC_QUEUE_COUNT) - HardDelete(D, TRUE) + HardDelete(D) return var/queue_time = world.time - var/refid = text_ref(D) if (D.gc_destroyed <= 0) D.gc_destroyed = queue_time var/list/queue = queues[level] - - queue[++queue.len] = list(queue_time, refid, D.gc_destroyed) // not += for byond reasons + queue[++queue.len] = list(queue_time, D, D.gc_destroyed) // not += for byond reasons //this is mainly to separate things profile wise. -/datum/controller/subsystem/garbage/proc/HardDelete(datum/D, force) +/datum/controller/subsystem/garbage/proc/HardDelete(datum/D) ++delslasttick ++totaldels var/type = D.type var/refID = text_ref(D) - var/datum/qdel_item/I = items[type] - - if (!force && I.qdel_flags & QDEL_ITEM_SUSPENDED_FOR_LAG) - return + var/datum/qdel_item/type_info = items[type] + var/detail = D.dump_harddel_info() + if(detail) + LAZYADD(type_info.extra_details, detail) var/tick_usage = TICK_USAGE del(D) tick_usage = TICK_USAGE_TO_MS(tick_usage) - I.hard_deletes++ - I.hard_delete_time += tick_usage - if (tick_usage > I.hard_delete_max) - I.hard_delete_max = tick_usage + type_info.hard_deletes++ + type_info.hard_delete_time += tick_usage + if (tick_usage > type_info.hard_delete_max) + type_info.hard_delete_max = tick_usage if (tick_usage > highest_del_ms) highest_del_ms = tick_usage highest_del_type_string = "[type]" @@ -295,14 +316,14 @@ SUBSYSTEM_DEF(garbage) postpone(time) var/threshold = CONFIG_GET(number/hard_deletes_overrun_threshold) if (threshold && (time > threshold SECONDS)) - if (!(I.qdel_flags & QDEL_ITEM_ADMINS_WARNED)) + if (!(type_info.qdel_flags & QDEL_ITEM_ADMINS_WARNED)) log_game("Error: [type]([refID]) took longer than [threshold] seconds to delete (took [round(time/10, 0.1)] seconds to delete)") message_admins("Error: [type]([refID]) took longer than [threshold] seconds to delete (took [round(time/10, 0.1)] seconds to delete).") - I.qdel_flags |= QDEL_ITEM_ADMINS_WARNED - I.hard_deletes_over_threshold++ + type_info.qdel_flags |= QDEL_ITEM_ADMINS_WARNED + type_info.hard_deletes_over_threshold++ var/overrun_limit = CONFIG_GET(number/hard_deletes_overrun_limit) - if (overrun_limit && I.hard_deletes_over_threshold >= overrun_limit) - I.qdel_flags |= QDEL_ITEM_SUSPENDED_FOR_LAG + if (overrun_limit && type_info.hard_deletes_over_threshold >= overrun_limit) + type_info.qdel_flags |= QDEL_ITEM_SUSPENDED_FOR_LAG /datum/controller/subsystem/garbage/Recover() InitQueues() //We first need to create the queues before recovering data @@ -324,79 +345,85 @@ SUBSYSTEM_DEF(garbage) var/no_hint = 0 //!Number of times it's not even bother to give a qdel hint var/slept_destroy = 0 //!Number of times it's slept in its destroy var/qdel_flags = 0 //!Flags related to this type's trip thru qdel. + var/list/extra_details //!Lazylist of string metadata about the deleted objects /datum/qdel_item/New(mytype) name = "[mytype]" - /// Should be treated as a replacement for the 'del' keyword. /// /// Datums passed to this will be given a chance to clean up references to allow the GC to collect them. -/proc/qdel(datum/D, force=FALSE, ...) - if(!istype(D)) - del(D) +/proc/qdel(datum/to_delete, force = FALSE) + if(!istype(to_delete)) + del(to_delete) return - var/datum/qdel_item/I = SSgarbage.items[D.type] - if (!I) - I = SSgarbage.items[D.type] = new /datum/qdel_item(D.type) - I.qdels++ + var/datum/qdel_item/trash = SSgarbage.items[to_delete.type] + if (isnull(trash)) + trash = SSgarbage.items[to_delete.type] = new /datum/qdel_item(to_delete.type) + trash.qdels++ - if(isnull(D.gc_destroyed)) - if (SEND_SIGNAL(D, COMSIG_PARENT_PREQDELETED, force)) // Give the components a chance to prevent their parent from being deleted - return - D.gc_destroyed = GC_CURRENTLY_BEING_QDELETED - var/start_time = world.time - var/start_tick = world.tick_usage - SEND_SIGNAL(D, COMSIG_PARENT_QDELETING, force) // Let the (remaining) components know about the result of Destroy - var/hint = D.Destroy(arglist(args.Copy(2))) // Let our friend know they're about to get fucked up. - if(world.time != start_time) - I.slept_destroy++ - else - I.destroy_time += TICK_USAGE_TO_MS(start_tick) - if(!D) + if(!isnull(to_delete.gc_destroyed)) + if(to_delete.gc_destroyed == GC_CURRENTLY_BEING_QDELETED) + CRASH("[to_delete.type] destroy proc was called multiple times, likely due to a qdel loop in the Destroy logic") + return + + if (SEND_SIGNAL(to_delete, COMSIG_PREQDELETED, force)) // Give the components a chance to prevent their parent from being deleted + return + + to_delete.gc_destroyed = GC_CURRENTLY_BEING_QDELETED + var/start_time = world.time + var/start_tick = world.tick_usage + SEND_SIGNAL(to_delete, COMSIG_PARENT_QDELETING, force) // Let the (remaining) components know about the result of Destroy + var/hint = to_delete.Destroy(force) // Let our friend know they're about to get fucked up. + + if(world.time != start_time) + trash.slept_destroy++ + else + trash.destroy_time += TICK_USAGE_TO_MS(start_tick) + + if(isnull(to_delete)) + return + + switch(hint) + if (QDEL_HINT_QUEUE) //qdel should queue the object for deletion. + SSgarbage.Queue(to_delete) + if (QDEL_HINT_IWILLGC) + to_delete.gc_destroyed = world.time return - switch(hint) - if (QDEL_HINT_QUEUE) //qdel should queue the object for deletion. - SSgarbage.Queue(D) - if (QDEL_HINT_IWILLGC) - D.gc_destroyed = world.time + if (QDEL_HINT_LETMELIVE) //qdel should let the object live after calling destory. + if(!force) + to_delete.gc_destroyed = null //clear the gc variable (important!) return - if (QDEL_HINT_LETMELIVE) //qdel should let the object live after calling destory. - if(!force) - D.gc_destroyed = null //clear the gc variable (important!) - return - // Returning LETMELIVE after being told to force destroy - // indicates the objects Destroy() does not respect force - #ifdef TESTING - if(!I.no_respect_force) - testing("WARNING: [D.type] has been force deleted, but is \ - returning an immortal QDEL_HINT, indicating it does \ - not respect the force flag for qdel(). It has been \ - placed in the queue, further instances of this type \ - will also be queued.") - #endif - I.no_respect_force++ + // Returning LETMELIVE after being told to force destroy + // indicates the objects Destroy() does not respect force + #ifdef TESTING + if(!trash.no_respect_force) + testing("WARNING: [to_delete.type] has been force deleted, but is \ + returning an immortal QDEL_HINT, indicating it does \ + not respect the force flag for qdel(). It has been \ + placed in the queue, further instances of this type \ + will also be queued.") + #endif + trash.no_respect_force++ - SSgarbage.Queue(D) - if (QDEL_HINT_HARDDEL) //qdel should assume this object won't gc, and queue a hard delete - SSgarbage.Queue(D, GC_QUEUE_HARDDELETE) - if (QDEL_HINT_HARDDEL_NOW) //qdel should assume this object won't gc, and hard del it post haste. - SSgarbage.HardDelete(D, TRUE) - #ifdef REFERENCE_TRACKING - if (QDEL_HINT_FINDREFERENCE) //qdel will, if REFERENCE_TRACKING is enabled, display all references to this object, then queue the object for deletion. - SSgarbage.Queue(D) - D.find_references() - if (QDEL_HINT_IFFAIL_FINDREFERENCE) //qdel will, if REFERENCE_TRACKING is enabled and the object fails to collect, display all references to this object. - SSgarbage.Queue(D) - SSgarbage.reference_find_on_fail[text_ref(D)] = TRUE + SSgarbage.Queue(to_delete) + if (QDEL_HINT_HARDDEL) //qdel should assume this object won't gc, and queue a hard delete + SSgarbage.Queue(to_delete, GC_QUEUE_HARDDELETE) + if (QDEL_HINT_HARDDEL_NOW) //qdel should assume this object won't gc, and hard del it post haste. + SSgarbage.HardDelete(to_delete) + #ifdef REFERENCE_TRACKING + if (QDEL_HINT_FINDREFERENCE) //qdel will, if REFERENCE_TRACKING is enabled, display all references to this object, then queue the object for deletion. + SSgarbage.Queue(to_delete) + INVOKE_ASYNC(to_delete, TYPE_PROC_REF(/datum, find_references)) + if (QDEL_HINT_IFFAIL_FINDREFERENCE) //qdel will, if REFERENCE_TRACKING is enabled and the object fails to collect, display all references to this object. + SSgarbage.Queue(to_delete) + SSgarbage.reference_find_on_fail[text_ref(to_delete)] = TRUE + #endif + else + #ifdef TESTING + if(!trash.no_hint) + testing("WARNING: [to_delete.type] is not returning a qdel hint. It is being placed in the queue. Further instances of this type will also be queued.") #endif - else - #ifdef TESTING - if(!I.no_hint) - testing("WARNING: [D.type] is not returning a qdel hint. It is being placed in the queue. Further instances of this type will also be queued.") - #endif - I.no_hint++ - SSgarbage.Queue(D) - else if(D.gc_destroyed == GC_CURRENTLY_BEING_QDELETED) - CRASH("[D.type] destroy proc was called multiple times, likely due to a qdel loop in the Destroy logic") + trash.no_hint++ + SSgarbage.Queue(to_delete) diff --git a/code/datums/aquarium.dm b/code/datums/aquarium.dm index da8c3afeb531..37a38f7849e6 100644 --- a/code/datums/aquarium.dm +++ b/code/datums/aquarium.dm @@ -136,7 +136,7 @@ . = ..() REMOVE_TRAIT(parent, TRAIT_FISH_CASE_COMPATIBILE, REF(src)) -/datum/component/aquarium_content/Destroy(force, silent) +/datum/component/aquarium_content/Destroy(force) if(current_aquarium) remove_from_aquarium() QDEL_NULL(vc_obj) diff --git a/code/datums/components/admin_popup.dm b/code/datums/components/admin_popup.dm index 88ef0d97fabf..98d0eccfbf2a 100644 --- a/code/datums/components/admin_popup.dm +++ b/code/datums/components/admin_popup.dm @@ -26,7 +26,7 @@ PROC_REF(delete_self), ) -/datum/component/admin_popup/Destroy(force, silent) +/datum/component/admin_popup/Destroy(force) var/client/parent_client = parent parent_client?.screen -= admin_popup diff --git a/code/datums/components/aquarium.dm b/code/datums/components/aquarium.dm index da8c3afeb531..37a38f7849e6 100644 --- a/code/datums/components/aquarium.dm +++ b/code/datums/components/aquarium.dm @@ -136,7 +136,7 @@ . = ..() REMOVE_TRAIT(parent, TRAIT_FISH_CASE_COMPATIBILE, REF(src)) -/datum/component/aquarium_content/Destroy(force, silent) +/datum/component/aquarium_content/Destroy(force) if(current_aquarium) remove_from_aquarium() QDEL_NULL(vc_obj) diff --git a/code/datums/components/attachment.dm b/code/datums/components/attachment.dm index 01e3abedd80b..1d1edcd44545 100644 --- a/code/datums/components/attachment.dm +++ b/code/datums/components/attachment.dm @@ -52,7 +52,7 @@ for(var/signal in signals) RegisterSignal(parent, signal, signals[signal]) -/datum/component/attachment/Destroy(force, silent) +/datum/component/attachment/Destroy(force) REMOVE_TRAIT(parent, TRAIT_ATTACHABLE, "attachable") if(actions && length(actions)) var/obj/item/gun/parent = src.parent diff --git a/code/datums/components/attachment_holder.dm b/code/datums/components/attachment_holder.dm index 82968a17604b..f83a55eb201a 100644 --- a/code/datums/components/attachment_holder.dm +++ b/code/datums/components/attachment_holder.dm @@ -57,7 +57,7 @@ SIGNAL_HANDLER qdel(src) -/datum/component/attachment_holder/Destroy(force, silent) +/datum/component/attachment_holder/Destroy(force) QDEL_LIST(attachments) attachments = null return ..() diff --git a/code/datums/components/creamed.dm b/code/datums/components/creamed.dm index 019bb7362bd2..c2cf5d07a28e 100644 --- a/code/datums/components/creamed.dm +++ b/code/datums/components/creamed.dm @@ -39,7 +39,7 @@ GLOBAL_LIST_INIT(creamable, typecacheof(list( var/atom/A = parent A.add_overlay(creamface) -/datum/component/creamed/Destroy(force, silent) +/datum/component/creamed/Destroy(force) var/atom/A = parent A.cut_overlay(creamface) qdel(creamface) diff --git a/code/datums/components/deadchat_control.dm b/code/datums/components/deadchat_control.dm index f34960db1072..6030214bf8b7 100644 --- a/code/datums/components/deadchat_control.dm +++ b/code/datums/components/deadchat_control.dm @@ -24,7 +24,7 @@ notify_ghosts("[parent] is now deadchat controllable!", source = parent, action = NOTIFY_ORBIT, header="Something Interesting!") -/datum/component/deadchat_control/Destroy(force, silent) +/datum/component/deadchat_control/Destroy(force) inputs = null orbiters = null ckey_to_cooldown = null diff --git a/code/datums/components/food/edible.dm b/code/datums/components/food/edible.dm index cde77f969911..729c50f2349f 100644 --- a/code/datums/components/food/edible.dm +++ b/code/datums/components/food/edible.dm @@ -142,7 +142,7 @@ Behavior that's still missing from this component that original food items had t src.after_eat = after_eat src.on_consume = on_consume -/datum/component/edible/Destroy(force, silent) +/datum/component/edible/Destroy(force) QDEL_NULL(pre_eat) QDEL_NULL(on_compost) QDEL_NULL(after_eat) diff --git a/code/datums/components/food/food_storage.dm b/code/datums/components/food/food_storage.dm index 259ef4a8b6c6..6bc3641711b3 100644 --- a/code/datums/components/food/food_storage.dm +++ b/code/datums/components/food/food_storage.dm @@ -29,7 +29,7 @@ bad_chance_of_discovery = _bad_chance good_chance_of_discovery = _good_chance -/datum/component/food_storage/Destroy(force, silent) +/datum/component/food_storage/Destroy(force) if(stored_item) stored_item.forceMove(stored_item.drop_location()) stored_item.dropped() diff --git a/code/datums/components/gunpoint.dm b/code/datums/components/gunpoint.dm index 85701e9c7626..ab7b1e641410 100644 --- a/code/datums/components/gunpoint.dm +++ b/code/datums/components/gunpoint.dm @@ -46,7 +46,7 @@ addtimer(CALLBACK(src, PROC_REF(update_stage), 2), GUNPOINT_DELAY_STAGE_2) -/datum/component/gunpoint/Destroy(force, silent) +/datum/component/gunpoint/Destroy(force) var/mob/living/shooter = parent shooter.remove_status_effect(STATUS_EFFECT_HOLDUP) target.remove_status_effect(STATUS_EFFECT_HELDUP) diff --git a/code/datums/components/manual_blinking.dm b/code/datums/components/manual_blinking.dm index d97e88ca8fe9..e33d5f558d81 100644 --- a/code/datums/components/manual_blinking.dm +++ b/code/datums/components/manual_blinking.dm @@ -22,7 +22,7 @@ last_blink = world.time to_chat(C, "You suddenly realize you're blinking manually.") -/datum/component/manual_blinking/Destroy(force, silent) +/datum/component/manual_blinking/Destroy(force) E = null STOP_PROCESSING(SSdcs, src) to_chat(parent, "You revert back to automatic blinking.") diff --git a/code/datums/components/manual_breathing.dm b/code/datums/components/manual_breathing.dm index bcae15536ca7..882887f0ccc5 100644 --- a/code/datums/components/manual_breathing.dm +++ b/code/datums/components/manual_breathing.dm @@ -22,7 +22,7 @@ last_breath = world.time to_chat(C, "You suddenly realize you're breathing manually.") -/datum/component/manual_breathing/Destroy(force, silent) +/datum/component/manual_breathing/Destroy(force) L = null STOP_PROCESSING(SSdcs, src) to_chat(parent, "You revert back to automatic breathing.") diff --git a/code/datums/components/pellet_cloud.dm b/code/datums/components/pellet_cloud.dm index 19b1e2094993..9ef5b57d1fa1 100644 --- a/code/datums/components/pellet_cloud.dm +++ b/code/datums/components/pellet_cloud.dm @@ -60,7 +60,7 @@ else if(isgrenade(parent) || islandmine(parent) || issupplypod(parent)) radius = magnitude -/datum/component/pellet_cloud/Destroy(force, silent) +/datum/component/pellet_cloud/Destroy(force) purple_hearts = null pellets = null targets_hit = null diff --git a/code/datums/components/shielded.dm b/code/datums/components/shielded.dm index 81cb0c2b4d40..7c2c3473e2d0 100644 --- a/code/datums/components/shielded.dm +++ b/code/datums/components/shielded.dm @@ -50,7 +50,7 @@ if(recharge_start_delay) START_PROCESSING(SSdcs, src) -/datum/component/shielded/Destroy(force, silent) +/datum/component/shielded/Destroy(force) if(wearer) shield_icon = "broken" UnregisterSignal(wearer, COMSIG_ATOM_UPDATE_OVERLAYS) diff --git a/code/datums/components/weatherannouncer.dm b/code/datums/components/weatherannouncer.dm index a5e622d8669e..7da27dcbba2f 100644 --- a/code/datums/components/weatherannouncer.dm +++ b/code/datums/components/weatherannouncer.dm @@ -38,7 +38,7 @@ speaker.update_appearance(UPDATE_ICON) update_light_color() -/datum/component/weather_announcer/Destroy(force, silent) +/datum/component/weather_announcer/Destroy(force) STOP_PROCESSING(SSprocessing, src) return ..() diff --git a/code/datums/datum.dm b/code/datums/datum.dm index e2f478ba7834..97da48745fae 100644 --- a/code/datums/datum.dm +++ b/code/datums/datum.dm @@ -44,8 +44,12 @@ var/datum/weakref/weak_reference #ifdef REFERENCE_TRACKING - var/running_find_references + /// When was this datum last touched by a reftracker? + /// If this value doesn't match with the start of the search + /// We know this datum has never been seen before, and we should check it var/last_find_references = 0 + /// How many references we're trying to find when searching + var/references_to_clear = 0 #ifdef REFERENCE_TRACKING_DEBUG ///Stores info about where refs are found, used for sanity checks and testing var/list/found_refs @@ -226,3 +230,19 @@ qdel(D) else return returned + +/// Return text from this proc to provide extra context to hard deletes that happen to it +/// Optional, you should use this for cases where replication is difficult and extra context is required +/// Can be called more then once per object, use harddel_deets_dumped to avoid duplicate calls (I am so sorry) +/datum/proc/dump_harddel_info() + return + +/image + var/harddel_deets_dumped = FALSE + +///images are pretty generic, this should help a bit with tracking harddels related to them +/image/dump_harddel_info() + if(harddel_deets_dumped) + return + harddel_deets_dumped = TRUE + return "Image icon: [icon] - icon_state: [icon_state] [loc ? "loc: [loc] ([loc.x],[loc.y],[loc.z])" : ""]" diff --git a/code/datums/elements/food/edible.dm b/code/datums/elements/food/edible.dm index a06a5ec28b79..615422198d88 100644 --- a/code/datums/elements/food/edible.dm +++ b/code/datums/elements/food/edible.dm @@ -143,7 +143,7 @@ Behavior that's still missing from this component that original food items had t src.after_eat = after_eat src.on_consume = on_consume -/datum/component/edible/Destroy(force, silent) +/datum/component/edible/Destroy(force) QDEL_NULL(pre_eat) QDEL_NULL(on_compost) QDEL_NULL(after_eat) diff --git a/code/datums/progressbar.dm b/code/datums/progressbar.dm index 7134d2e8ecef..9dea05393577 100644 --- a/code/datums/progressbar.dm +++ b/code/datums/progressbar.dm @@ -16,7 +16,8 @@ var/last_progress = 0 ///Variable to ensure smooth visual stacking on multiple progress bars. var/listindex = 0 - + ///The type of our last value for bar_loc, for debugging + var/location_type /datum/progressbar/New(mob/User, goal_number, atom/target) . = ..() @@ -32,6 +33,7 @@ return goal = goal_number bar_loc = target + location_type = bar_loc.type bar = image('icons/effects/progressbar.dmi', bar_loc, "prog_bar_0", HUD_LAYER) bar.plane = ABOVE_HUD_PLANE bar.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA @@ -135,6 +137,10 @@ QDEL_IN(src, PROGRESSBAR_ANIMATION_TIME) +///Progress bars are very generic, and what hangs a ref to them depends heavily on the context in which they're used +///So let's make hunting harddels easier yeah? +/datum/progressbar/dump_harddel_info() + return "Owner's type: [location_type]" #undef PROGRESSBAR_ANIMATION_TIME #undef PROGRESSBAR_HEIGHT diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index fda41eab7789..21eb3cc362b7 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -99,6 +99,11 @@ /obj/machinery/camera/proc/create_prox_monitor() if(!proximity_monitor) proximity_monitor = new(src, 1) + RegisterSignal(proximity_monitor, COMSIG_PARENT_QDELETING, PROC_REF(proximity_deleted)) + +/obj/machinery/camera/proc/proximity_deleted() + SIGNAL_HANDLER + proximity_monitor = null /obj/machinery/camera/proc/set_area_motion(area/A) area_motion = A diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 2c269ce1ee9a..61d8b2757836 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -614,6 +614,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that dellog += "
X(+=;LUUHZ<{PKDML{vJ?+hNLCKqGLW!RaO;Bep8#s|(oquxt>CssxbytHp7GbZdbQJI=y|H$zee2Md z8tN8#;WI19vuA5_2${P7y+`%`H;Vtt?fTo3W%NhBH#H5>+a5-~o_9XFKa2rx@+QL0 z0)BTsT{ |u$UlqRNwIk%Mi=eqnoXG1*6^M698A9qxy-$Dn8r^`%AfB^|+0q z4}QSDZ~6IzNN!V`T-jEubB`ZaotXW6FUvaser=n!DATkMMg=}SdpF@I%iJ+*U9!VR zzPA= h2nX1Qz2@6J}x^M8nsX0hwpjaETLP29N zQB)5vOH0cNeCIN=3j{8O@Q@?CY`AZ&pSuw}ay$FBeT3z?f%a{UZ2P!uUfPC`#Z2+r za+-GiK74;;T(y!R{Cefj2^iC!lPhU|@uVlNzOdYuaR9Sh(oL2(w`k PWqu-+XDORa&NmJk55X_7Y|HB zBs9}Jm}sB9c=QO(_ngy{eZJG#oJ8<78#8hfPXR>a)Q|UeBV$#~8`?GgzKlL?*JCga z;{ys!GjU0%K$^SXceMOw@oaM0zF1#MK}`xZ`}Xj|KW-j{*$D?v_Qlo;<;wm5#D7Wn zrLdfDhZlw*O9rjDDqxFtIKQxC31lYX?NqPxrHhx|+ZzS?+uvdzzdb(c&(9;MyM4DH zPvh&5C$26UaXj?EjOE(1I& >NE7*!w)Bg& zYEeJ^8Re-86{e$Fyj7LDAv$w?2edjj1Tj8;E|x_^=3rzE4CTjPW5013@8=wHY2!_F z?YqHH`X;BwM|Vl1Trcw4c+Rbw+r!xx?P;@YQS@ASCqv3i6fAlG1F-ruo%s96Tsq`b zmr8fwJ;qbv!u@^2v-f|~jJpaiReq{`QYx|Of87;Svi*4J$0Wuc^~_6j Db`k9`B%A*G@-)$!0w-(lbg-An{>5t1dw28?0=t~=Vb~h<@ z2&tauFAo44v N26+7FeDw?mJ8P$PYuomD4ZRNKKhWijPtSxy-g=t2RDP^}_Tzl>@MUC? z)qD@y_BKK8lIHL0D}h-fw6^r7M&^yh5T|YBc2)4prI+;s&eraV-d@J`2?b;${bWAc zjpV6J(EaDj8dTxd%j}7OFzHO@`H{qAyPnb7$9iRvYGoI%zO0mAmJZ%PR^=&-O8`$# z7kKOFJw^751;>Q0pN>Vw3U;4{8i*u}$}RY5Zj|5myHqPM{gsAzn4TDd>!-)*?sNfV ztM|#F>|36wF~7DQrw(BGvFX9nr~&m7hVbzoX5lWn$Qqdn?eU@MAC4L;%iM7pB=2wW ze)!5? +S5(IU%UUSA}h;3_51(VxipKV(_YZJ=-TjAa4Ql1@%W=d7k{FG z{35z9IHu*833Pud@CvL)@zdR1+_=GT)}(UJ%bAbp2JpZ!gJEXqYJA^)rml=1lVJy& zc2^?#*42LMXK4L?ncH$fjyfrIU;Z)fqJ $D zC!={2r-7WE_W*Men-5v 0*tvRDZI60eY^#Wuuqx^(b3s zP%Gnv`+iaY{)oG@D-aOEydInYusnAT2n0^_008VKU6E`6fD+ID>qY+Y2+2QwH&YVP X2%9o}VFEeS!T@s FF@HFfqzV*p@)WnVhl9oKWVM znQ7Haa$_LTKb-0PB-p)MwaqQ(^9+dd?e8m)JaMdShufMj$^0+Bop4VcDudp@6W5sg zQp3t*qC$o;#j~F i-lf&jn?Xsan3 z`R5(x2S5xRy0GBA0+Br`?@tD2dcvGh!kvO?%nksXx`8qq`t1nOso=MtGL&<*n}C(3 zXt|7+=3_MnHF9zZuS+@-LcHWp6rUQrAAU5?Y1CWHyVR5^;WN)IhHnWR2X$Ko(CX_? zz!k<(6R(@{s_%fo9E8d>T%o7rG<}tnWLh+oTzF*fxOg~~#li`BNF$O$3BS_ZOyXox z!M{nUs-^VKhV*YEGUT>iz=5M@!jxkd=2PKi`D?o^msy0zNMgXA_(-=p5*+ARZFpUT zJr#l?8CESQM*J|5A=x~-_j85CB&F6TvwZ<%Ob;BE!y=@6|A7l$k0=^L0zNvE&$C); zb)W!je!al@Ou?xwyXliT@&RC%V<~Kit=>Hv1GARv!Bf)lNSJbY(a?l>@c^`G+%<^5 zQ<>YZcbhG0e#^?Kto5#LqTbQ_EGxmZ{MK+)&3j@8&yIgysHR|Pk+b6)j(YLxX7*WP zmFjEwN<1Iq&^f2_GM `1Elk<>zLX?2Pz*(r^m$K}TX_M>olF!m!9yMxnWV+-cWb2 58^;9s4%4k8F3zoi#B2kOW|2dO%If^?e?* z?3jpZr%%chy $BYI0OJtBhI`#P1N?@Ve3!tw2x`uVT?7L+PzN?=+D3-z4nYZf_etU9G z3f-Wa_()Z4p!`D|rK+o!sB-UP0&{U+fBCzsQcClZ+pQJ#e;QQsZJmDj2|`)XP v3!VKn4&&^lPp-x52|4)jQ7BbT17(HBTt{P-|89~?!&M3U|!Wi&fO zD%BP3Z=4|}_rSai02=k=6`uvqm2kzG0B=hLOO^I(ya|a(xP ych$+Z)V;ZA{}g5T0wly5g%^rj@eVMkKg>|(;_wm(wF%;X zPF&1cD2o@-76^ExhzbVEd(6~3_{rkWN;iF|(WS7fXEY{a5NkH0NvFB7eM-PtHv&%* z4F;4f4JmSb9G{}_J{VQ@qemFTT)h8&(~K!#0bBc+4a~%`X7K*l3)|UUkJGAnT%DPJ zZ&{I$oHMg@PLvy1g9aYW`!iAV<1$D!|-}Mr90q6(yf=t94n90gMnb7=VdX; z@u6Qg0U((r%Jty0T`H Ej*gp-mtIRBufkizO6FpmU32ZcysryVx*d}5ffeQY_8K>(h=HW-ZzY(5 dtYxd?qStBHC)2nzlx5Hg5qcFV@3A{5;+L-tdMW7me-9gx@- zn+VIU@6P>;Y-@k+h4kA^<%2@3QJrmkajd7`JJzE+GG&23+d&h}`B;xIW+18Al`a(% z0=WsO2E|sOA%jry7co;V)zwQBKwV6a9Q0Q8Bk#Bs@6_*rPx+z#p;ydMY$iR+{_mV> zG&==<)lIqrMm#{wgvDmoZ<%c|^TMeBskS W;3%_C?hywo+@S(& zBqhnGw#KlV@0eLd3x=ISYdhIa9t#$qjw@}adoA! !wM)nF9`yLJuf#|?%rCfW3aaSEVjU8QN3yyY^*UrJ ze3ihB0Eo-Ud!J4Bq}FF!cLDi^y5&aLQC?(ev1GWq+QK-WDM-{>*OgUQgMdYtF{{EP zD~{MgxFdA a4sYw01q^zI~_4)EZEF;+0l>Q)Wk#k4p8mC7$rJ zcrj#5vK$VED&2`C_2MTR8u5UE7sPf-a!HD-;qJ&YPFzLWI&BnH9ouY@j*2E)<53%l zRA%gls!rn6?>{BGo6%NmL^t$F-)UER2tk*(DA^O!(g1o q9nb=BAUDejsI>>#S^?{R6klyzc9d~%x>sV@mo7_9C zSeiWawRx#a^~bgjqm&Mj#CJ`NU1Wqo#DEyX5|wvLDy$W>xZzg)GraRf=%wpSz`^gC zIce!~gR3RwrkB8zCwbkPb;0~VhL8NJ0LQT|=nL`@dv$-DY!iIkhlt4=u22%7p*P`` zV`9iPo>^qqRf5z`2lKSCITzuX&Nwdz!+C(7{$2|HvfB7?E^;cIA=-A=pf5<7N3wZ` zVKLhu9xR@nKZ}=R`b~_R=1e3y1@WD9DAV!BoKyf0w3#=j?fERpcIo#AMJ6SxmHLqt zX-09kSz>Vtl1G=7SC*DJ4=T2gI*j{8TA*hFE^Q?xH}*e4AN!nfZUmmHpM|{^bN0%} zhu~(?U~V^D&qx+2pZcf@^Majh04LU;z4`Oq{Iqao)ktn_hIk(1hKK08)ZQSSg%t=; zDlDpM*Lk4#$Qsqoir0Vo9r#)Dtv!Dy*$~uY!r_J!3kVgxW#7UYgaeW)q$QUh2zf>T zJaJro;kT8nSv7$WTx0OsMqMGYHI3#m!$deE1|0mu^9j91_$Ej~$DuONcl-KXnk8I) zIOe(GPyVj8!3z&-ks&3YMg}0MepBH(LvgxlbJP-=;1fJDc4=Vx3?Jafobf!5plUk! zBW>Pghh4%%6TuW{!ll9WY-jFnF7*e0o}7baQHmgHe$ybyN3?U1LRVKz_Sbv#z=P90 zGdS$}O6M1P>UOgc=-_&ed!JzBF~|6Av$@D3Ol~!Z;{XC3N!5PJF@Eb`q>{g+GHTrJ z|09%}_J2DJ{M*z1rxU~f)F|rFDPG9MdeG6R9+Vu5AUj 8W+sz7ziiOuaHu%pcFI9Kim&N@uPVi|uWV++Kp_Ujc-2ZZKZTp3a?Tw$H5 zvGJoOc*mWfT EWX>6T?gAtk6VBq?wly-=tYoeUvJxH}AE*Eh!RqD0Vx_%Y zBc@#7`WdQ~QqNDHWbYHi9Ms2$c*}JyB3liEntrLju6g~9uWshW< G^^EaLDnY9nO(U&q;E5D&YtF%mEn00=cAx)W?16TQv4nN$U6@Yi2rE>6PNW z7Q^~Hv^87SXtaE=vH5KYf=F)Nbi9X4QcQZ_b&r>~pdXsN;JE^Glm$t(NgK7K~ axKL0$Yn(79DxaO?#E;O*Hg(^>-t>N1c)bG`lYY|w7M^)uq2t* zUBxkleC_H@bj8gWRAh1gb8ih{K^9^D_GctMs L}Y0=h5VtI^1Ogc zFr6~yiBza|woTZPwJVUK28r&soSSwfG;}fh+fH4G9Mq4SUyuR;`}LIz=q>~3s~x1e z? (QY+4%UV5&@!T&qQ4jb5Zu?>b?V8@p9QXMF1ym4n`1^6{)! zbFA?_47OPISMEA%Vk|*_nt*RV)J|yl+qnCr(w(Nf?vRmpKqxsWElTP(PX+a#>D$#G z{GQxgHAh3;4(j#Z>^#Q#Gf3n1YwM-`6!5Dcy3k6{(w7cym7t~>R6!k`$D9j-6owYX zlhtBLj<~0~T3-%3H&}AS*~@SS8L<9QnJJ$(HVka6 xZ^mqH~xN^5~*qUiC(=UL{0HjPbR7abdJUv1e>9}AZjsw7EC(mMDJ%r|03 z;|PuBc7vX|W#UssyA2LFl!srqhDA_m>Kf3*I9K2t^oDD8rO7$2!u|{FEHPaazvd9Z zb_EaC4cM4-i{(b5<)tBao?bVgLPE9el(EJ9_VHT8HmS!`- iCp6WCA@j6&2|{pvWLaDxT|Ci9I?il&woI4J_FWh6I Gk?~w zUHWDI{cb7i7;_NE(FA2(YIRxVja$`9^J?kbYd?PM`fjBPfe+MVMd+tDe!ZX4dKjy! z 2GijI=;5Y*R15ec4;LHc_=~On-_Gv6XUI zpI}pTRg(PQ@%7h|*L@AAZlM8=eF9=#i!huIT#-CoQ21I4TCL-{{7~seV+HTOJf28A z`BRIon}eG_u;-YD3%#EUIBB8`pne!rkf9jzGd0M-C&+~$bn*m&eR%Wi$|PtC4(;M5 zNS~8a+v=ZMgN6?Ut!}T0o#H)(#~y4t-2LLZHUe1P{!PRVeqfyi<2Xh4p@rzcHxowc zhPq#G1HT}x7a8N=kQX6pM+Zzko#Wjf_X+AIURZJ@BHg<%x9dQh2aws*6MpQ@FmBh5 z3q4)P-u%yzsQ(66pl)LiwMPB? `R4j`lF9auF*;kc>6gx%YKIkEmCkRdaBV z!QYbX=-CwMUreK|A@Nx4?@a&PlEq#X(?btra&ucugvd(ZYgB%H+19>|qHp)_Y>wUg zSVsDr*x=|66uP>fgm9L{co$H-nz&EtBd(~%@KzV#UDqi=qxT#mA*Q42C8!!#FxmV! zGE>=*`GN@qf01Z-V76$%TJ8M{m8eYg2Aa*`H&N@-qudXQQ7=#^1`NS&(q43D6#}_D z ~@w6&y;HE#cQL0{QV@O~ceLwR_9~ zcg@FNPJHQ;S^mE4Ra`ZY1rppWqx3;{+%HZOGfQLsW!sf@lUP920)(Ix;7zN$0+I1M z1WESZSD+m?WDfe8ny~Zo#c!fVYA7QO>!k84E3)~gK@B*d9Y;UG?FZaG=OT|=SU$FK zr?sC)l;ZdAB4Aa$UA3?q-b|yrpcQl{5;!zGINaJah*v zGr#@1d;8&haN_E{jB4vZg&&5*9}6$;NU|)gybU0m3REvV3VeC@3$KMDICr!E_8W4U z#uhsomU`p2sdG5y!#i6^Hm4X@x0&Beeb6ZYE=ig#OS#j54=5dMNmk^nibI>xm|Z`J zucmh8$s4(Zn*4%u0It&jy`|tPebbMZyBjk2Jp+5@PQN`Ejm(8B_O$Lh$wgwS CN z;JA7RpP ") - var/nullify_spell = input(owner, "Choose a spell to remove.", "Current Spells") as null|anything in spells - if(nullify_spell) - qdel(nullify_spell) - return - var/entered_spell_name - var/datum/action/innate/cult/blood_spell/BS - var/list/possible_spells = list() - for(var/I in subtypesof(/datum/action/innate/cult/blood_spell)) - var/datum/action/innate/cult/blood_spell/J = I - var/cult_name = initial(J.name) - possible_spells[cult_name] = J - possible_spells += "(REMOVE SPELL)" - entered_spell_name = input(owner, "Pick a blood spell to prepare...", "Spell Choices") as null|anything in possible_spells - if(entered_spell_name == "(REMOVE SPELL)") - var/nullify_spell = input(owner, "Choose a spell to remove.", "Current Spells") as null|anything in spells - if(nullify_spell) - qdel(nullify_spell) - return - BS = possible_spells[entered_spell_name] - if(QDELETED(src) || owner.incapacitated() || !BS || (rune && !(locate(/obj/effect/rune/empower) in range(1, owner))) || (spells.len >= limit)) - return - to_chat(owner,"You begin to carve unnatural symbols into your flesh!") - SEND_SOUND(owner, sound('sound/weapons/slice.ogg',0,1,10)) - if(!channeling) - channeling = TRUE - else - to_chat(owner, "You are already invoking blood magic!") - return - if(do_after(owner, 100 - rune*60, target = owner)) - if(ishuman(owner)) - var/mob/living/carbon/human/H = owner - H.bleed(40 - rune*32) - var/datum/action/innate/cult/blood_spell/new_spell = new BS(owner) - new_spell.Grant(owner, src) - spells += new_spell - Positioning() - to_chat(owner, "Your wounds glow with power, you have prepared a [new_spell.name] invocation!") - channeling = FALSE - -/datum/action/innate/cult/blood_spell //The next generation of talismans, handles storage/creation of blood magic - name = "Blood Magic" - button_icon_state = "telerune" - desc = "Fear the Old Blood." - var/charges = 1 - var/magic_path = null - var/obj/item/melee/blood_magic/hand_magic - var/datum/action/innate/cult/blood_magic/all_magic - var/base_desc //To allow for updating tooltips - var/invocation - var/health_cost = 0 - -/datum/action/innate/cult/blood_spell/Grant(mob/living/owner, datum/action/innate/cult/blood_magic/BM) - if(health_cost) - desc += "KS@^s# zDJ?l}D2u-$hkfc0GB}>uV{=LUfRnT5jFgh5z%QaXx9%+!ilk-O)ISSx_}RiH>k302 znNUgE;2>009d@S%1#y>lxLOFV)>rKtD9hX06h_XL(2c&JL(qFTix;RT9oIzrlb0|) z6#Zz{Rhq@$psyd+) phD0tnNPN zH)(QXehYfR*_miw%Q5Tefsdu}s-EpvalEgpOg|K_w1Yj9bGM`BU~7j6FS==5ur;nx z(cSq+pfL2bl-X>5g*;FdgjC1o@>tV^{&~&Ppr25eYqC1&DQo2TWbpSScY4x+*-urD z;C-*Dv#;GD8#8yS+v)yTdgkV0lC5^y<=?I_d|3i}p}W$~LBE{?j`V-}y=Of od_VB=VjLBxqgx)6QxF@T!Cri93=&N`W`qP%03ZRl` zq*C&oEI0Q&j+BvIn|YX2@k#XT@JlBq<}f<4F3Yv!zSXN3zOy6Kv87Y$cIs*Cjrg^8 zYw=)2uzH4SS9jm&a;Ii;>zl+v1l6TNNc3Rg6+2tFfU%4CQA;H#N8Ub_8dz<-dhI0? zno2%LVmn}gg>4+5_#WP}Uj0CLQ@3SPi+7s)Rc?_sa})5|3U3T9i5r^0$(!HUr8+U; zhmn)d`x$2+^fFuJXOqup#%Pr6_q&2~t3JWG+Bwd{3QwB4N2~XFm#74~+FAMO1^%j_ z=PoN?mZuD9D*-VClhVu`q4p&L%|NSHktly$CTDFFuA|Ri@Lb(ae0|l|5Vp3NDl| z$7Hbjp)WcdNGof^so*6Y;^OgSM6!7AwM{_SkAt%}Uf;cQTW^%W6@PlUhl5!b9o >Gz&0IxiK@&349T;pgDNwfZk0dc(-3}&lj|_JtI%|Lcyaty&4s)*&(rpP{0W#4 zr^BTpD0b+f*>~0`BryeG9=RDyH)08m&!hn?qO n0(zNW@Rb)&Jy%{D(YKCiQ{oU*vx}9Gd+0sns=|T6yK0 z(@1O)dWFD4pL+Fi9G>q>UZ=cjg1)Y4qmP3PIp)C%uL^z*YIj!i4WwSld^tbu^RMIJ zJMAi9YF$K3`AA-O93f3cutyhN%B6z6M> B{KDKe= z5*P1e#P>wQYD6wkS?^(0xTl(Mj?iA8>GZLG9dx+x>i3%-_9*&po?DxTqMP?_!rv?v z_*Opt0dWsuM!?Rd5O{BBHr_PrzSU#34jvq|KG~@B-w^T${5I z1+X2BM?gjhUPtFBR@&})J{J9uq$Rkvdti;~Ue9NYUNCH}``S(|dxN>vWZ0===lo zhS6wb?@bZ$*DOfv3Ht>MyNEzv&Q)&-R;LvmKdTgmb}#7}eAz}3wNHRcmdbxrV!A(F zfUSks+&>5XJcramL_3fC`Sj4VqnTGdQ^BxXqtXqg98V?eS4b@C9pm$2&nc3@i`O%W zcJ1ta vT* zr{U%0HEZ|1XHsE?2bi^a3$TTAk s7gyqInkuOH}c)yU3hKB2x)=ddEA(Z;Ka>SHP`?5 zXzagZ1W6)9dCl$F<``9)%>1j`;`efjyq2}$x1*X{LeEOFw@3!uHWC;VV3iAE`P$dh zzg+cOcg3qN_6D=J5Z2u(OGrebhhd4n!_;+2i5Ko=I|DZEn2G(O+=S8phqK|Qz9Ro^ z5+=+5J}%nxmp8>WaZ$q+KJJu#sR$PHr8~ds7TL)CMwAtNF4hfyG(NGTPpR9_tN#{{ z9D5G-4C)9dO2HI>PxrpCehzv6J&0Zg^)uKP-Hu4T2YsL%Eh1|;YJXf?dy@I9?g}8& z@*ds=Q6kDQ%cg(JD_NPitSR^Zqor%n958Usr{w342Qs+5bovh|*?-oI8;oFQXGbSc zde*qyM7*PwNBOs|T&JiLZdFKoZm4O$OJG;jxp}6vtEOPy)* `|hwlYW40-*#x z#6Zt-H}z-H=G&Bsgph;E<}Itl+xS);a|Ky=0Kb8nEmO(24l=qL)G$m2sEciJu@xr) z%HgYFW#RTf&;A8V8vo|WN$(@sP_>TaU8A1mWefcny#d_A?VsiA{bddzm94u1Vk$Ng zY+s3hK|A`c2HVy+i~7Uc-s(7!hsxX!ea6 j4yZUEbcMG8yx06}cvU~c4XZ=R#(iF{;Q8 vp0;Hzzxuy&f_rvYY>IOJ5)h5FS0Vl}#*qzC=?C6n{XMGtN8@c4% zx)F@_EG&;%Xd`!-?}wv5S&^s&y6vMv2NO9EXA-R2F0TlMpK(^2#KvT)0ZPBNM@#j! zG-8M2?0ty#e~@Si_Ef!>VAsD30Ql#B?*jBMyBEA+^*bd~d8#J7?; zuwzycgqfHw=AE&av-#xOeCX&Mbiy71uv;9}$lbXoC>UuEINMlAMs8Jf&3j(p(uR|+ zO0Vi^??(=- vewX~(?k`n;2l8!`{&m%kZ4D7aUcBrj9%rwl~T|QlZBz0 z?Q J`$yK!cN*!cUNTt z0~#HQDjTL-ks9jsxVI11I!uy` Ot|JRY5@ZXAKLbVlgD1l7^iW zXbP4LQ6$|vL356M4I^<6L<2vEo2dn^{Us@G;5~IJt B)Nf(qr$Vn+@^L zO3SMjhfR%&zKxorc$d6`k%y`=_ixcV-8VPzxVXdO!eS%Q&};A1--s+PZL9E2d9?4t zx%JguQ#n(_GVq&K!~jK2tG&eCvWlUpM0G7KA<2 7Fsbk_$c zpI9aW>ii%la+EO`K9PMyziP5I=|(_1mG?b Date: Mon, 7 Oct 2024 00:04:47 -0400 Subject: [PATCH 003/344] Removes A Lot Of Cruft (#3447) Removes the following: Swarmers Bloodcult Soulstones Everything Devils Meteor Gamemode Area/shuttle - [x] Compiles and runs on my local I'm fairly sure none of this stuff fits regardless of if it works with the game. And area/shuttle is annoying to see in sdmm. God I hate it when you start pulling one thing out and it's easier to just pull the rest out than to adjust it to work in the event that someone might use it for an event once. :cl: code: A large amount of cruft has been deleted. /:cl: --- .../RandomRuins/ReebeRuins/reebe_swarmers.dmm | 471 ------ .../shuttles/nanotrasen/nanotrasen_mimir.dmm | 169 +-- check_regex.yaml | 4 +- code/__DEFINES/atom_hud.dm | 30 +- code/__DEFINES/cinematics.dm | 3 - code/__DEFINES/cult.dm | 29 - code/__DEFINES/is_helpers.dm | 4 - code/__DEFINES/language.dm | 1 - code/__DEFINES/misc.dm | 5 - code/__DEFINES/mobs.dm | 4 - code/__DEFINES/preferences.dm | 1 - code/__DEFINES/role_preferences.dm | 4 - code/__DEFINES/status_effects.dm | 2 - code/__DEFINES/traits.dm | 4 - code/__HELPERS/areas.dm | 1 - code/__HELPERS/game.dm | 1 - code/_globalvars/game_modes.dm | 3 - code/_globalvars/lists/maintenance_loot.dm | 1 - code/_globalvars/lists/poll_ignore.dm | 2 - code/_onclick/hud/_defines.dm | 1 - code/_onclick/hud/alert.dm | 109 -- code/_onclick/hud/devil.dm | 69 - code/_onclick/hud/hud.dm | 2 - code/_onclick/hud/human.dm | 33 - code/_onclick/hud/swarmer.dm | 98 -- code/_onclick/other_mobs.dm | 8 - code/controllers/subsystem/shuttle.dm | 2 +- code/controllers/subsystem/ticker.dm | 6 - code/controllers/subsystem/traumas.dm | 14 +- code/datums/ai_laws.dm | 15 - code/datums/cinematic.dm | 53 - code/datums/components/soulstoned.dm | 33 - code/datums/hud.dm | 4 - code/datums/map_zones.dm | 2 +- code/datums/mind.dm | 20 +- .../mood_events/generic_positive_events.dm | 5 - code/datums/ruins/reebe.dm | 7 - code/datums/saymode.dm | 6 +- code/datums/status_effects/buffs.dm | 29 - code/datums/status_effects/debuffs.dm | 13 - code/game/alternate_appearance.dm | 28 - code/game/area/Space_Station_13_areas.dm | 1350 ----------------- code/game/area/areas.dm | 2 +- code/game/area/areas/shuttles.dm | 185 --- code/game/area/ship_areas.dm | 14 + code/game/atoms.dm | 60 - code/game/gamemodes/cult/cult.dm | 182 --- .../devil/devil_agent/devil_agent.dm | 44 - code/game/gamemodes/devil/devil_game_mode.dm | 106 -- code/game/gamemodes/devil/game_mode.dm | 26 - code/game/gamemodes/devil/objectives.dm | 113 -- .../gamemodes/dynamic/dynamic_rulesets.dm | 2 +- .../dynamic/dynamic_rulesets_roundstart.dm | 149 -- code/game/gamemodes/events.dm | 9 +- code/game/gamemodes/game_mode.dm | 3 - code/game/gamemodes/meteor/meteor.dm | 61 - code/game/gamemodes/objective.dm | 15 +- code/game/machinery/computer/arcade.dm | 1 - code/game/machinery/doors/airlock.dm | 20 - code/game/machinery/doors/airlock_types.dm | 109 -- code/game/machinery/drone_dispenser.dm | 22 - code/game/machinery/shieldgen.dm | 21 - code/game/machinery/syndicatebeacon.dm | 4 - code/game/objects/effects/blessing.dm | 7 - code/game/objects/effects/forcefields.dm | 8 - code/game/objects/items/AI_modules.dm | 2 +- code/game/objects/items/blueprints.dm | 1 - .../items/implants/implant_mindshield.dm | 5 +- code/game/objects/items/robot/robot_parts.dm | 1 - code/game/objects/items/shuttle_creator.dm | 1 - .../items/stacks/sheets/sheet_types.dm | 1 - code/game/objects/items/storage/belt.dm | 26 - .../game/objects/items/storage/uplink_kits.dm | 9 - code/game/objects/items/toys.dm | 25 - code/game/objects/structures/ai_core.dm | 1 - code/game/objects/structures/bedsheet_bin.dm | 2 +- .../objects/structures/door_assembly_types.dm | 14 - .../objects/structures/ghost_role_spawners.dm | 52 - code/game/objects/structures/girders.dm | 54 - code/game/turfs/closed/wall/misc_walls.dm | 12 - code/game/turfs/open/floor.dm | 5 - code/game/turfs/open/floor/reinf_floor.dm | 30 - code/modules/admin/admin.dm | 16 - code/modules/admin/fun_balloon.dm | 5 - code/modules/admin/sql_ban_system.dm | 4 +- code/modules/admin/topic.dm | 21 - code/modules/admin/verbs/one_click_antag.dm | 33 - code/modules/admin/verbs/pray.dm | 5 - code/modules/antagonists/borer/borer.dm | 4 - code/modules/antagonists/cult/blood_magic.dm | 803 ---------- code/modules/antagonists/cult/cult.dm | 397 ----- code/modules/antagonists/cult/cult_comms.dm | 461 ------ code/modules/antagonists/cult/cult_items.dm | 524 ------- .../antagonists/cult/cult_structures.dm | 291 ---- .../antagonists/cult/cult_turf_overlay.dm | 32 - .../antagonists/cult/rune_spawn_action.dm | 115 -- code/modules/antagonists/cult/runes.dm | 1029 ------------- code/modules/antagonists/devil/devil.dm | 506 ------ code/modules/antagonists/devil/imp/imp.dm | 68 - .../devil/sintouched/objectives.dm | 23 - .../devil/sintouched/sintouched.dm | 76 - .../devil/true_devil/_true_devil.dm | 221 --- .../antagonists/devil/true_devil/inventory.dm | 48 - .../antagonists/disease/disease_datum.dm | 10 - .../nukeop/equipment/nuclear_challenge.dm | 3 - .../nukeop/equipment/nuclearbomb.dm | 2 - .../revenant/revenant_abilities.dm | 2 +- code/modules/antagonists/swarmer/swarmer.dm | 677 --------- .../antagonists/swarmer/swarmer_event.dm | 28 - .../antagonists/wizard/equipment/soulstone.dm | 354 ----- .../antagonists/wizard/equipment/spellbook.dm | 12 - code/modules/asset_cache/asset_list_items.dm | 1 - .../awaymissions/mission_code/snowdin.dm | 6 - .../mission_code/stationCollision.dm | 155 -- code/modules/cargo/exports/lavaland.dm | 4 - code/modules/cargo/exports/parts.dm | 7 - code/modules/client/preferences.dm | 3 - code/modules/clothing/outfits/standard.dm | 7 - code/modules/clothing/shoes/miscellaneous.dm | 23 - code/modules/clothing/under/color.dm | 9 +- code/modules/events/devil.dm | 53 - code/modules/events/major_dust.dm | 19 - code/modules/events/meateor_wave.dm | 11 - code/modules/events/meteor_wave.dm | 76 - code/modules/language/language_holder.dm | 5 - code/modules/library/lib_codex_gigas.dm | 104 -- code/modules/mapping/writer.dm | 2 +- .../mining/lavaland/necropolis_chests.dm | 10 +- code/modules/mining/shelters.dm | 2 +- code/modules/mob/living/carbon/human/death.dm | 2 - .../mob/living/carbon/human/examine.dm | 2 - code/modules/mob/living/living.dm | 18 - code/modules/mob/living/living_defense.dm | 26 - code/modules/mob/living/silicon/laws.dm | 10 - code/modules/mob/living/silicon/login.dm | 2 - code/modules/mob/living/silicon/robot/laws.dm | 6 - code/modules/mob/living/silicon/silicon.dm | 24 - .../mob/living/simple_animal/constructs.dm | 501 ------ .../mob/living/simple_animal/friendly/dog.dm | 44 - .../hostile/megafauna/swarmer.dm | 285 ---- .../modules/mob/living/simple_animal/shade.dm | 66 - code/modules/mob/mob_helpers.dm | 3 - code/modules/mob/transform_procs.dm | 5 - code/modules/paperwork/contract.dm | 314 ---- code/modules/paperwork/photocopier.dm | 33 +- code/modules/power/singularity/narsie.dm | 238 --- .../chemistry/reagents/other_reagents.dm | 61 +- .../chemistry/recipes/pyrotechnics.dm | 10 - code/modules/recycling/conveyor2.dm | 4 +- code/modules/shuttle/shuttle.dm | 10 +- code/modules/shuttle/supply.dm | 167 -- code/modules/spells/spell.dm | 14 - .../spells/spell_types/construct_spells.dm | 327 ---- code/modules/spells/spell_types/devil.dm | 236 --- .../modules/spells/spell_types/devil_boons.dm | 76 - .../spell_types/pointed/mind_transfer.dm | 2 +- code/modules/spells/spell_types/shapeshift.dm | 3 +- code/modules/spells/spell_types/wizard.dm | 26 - code/modules/station_goals/shield.dm | 23 - code/modules/surgery/bodyparts/head.dm | 5 - code/modules/surgery/bodyparts/parts.dm | 29 - .../surgery/experimental_dissection.dm | 2 +- code/modules/surgery/organs/vocal_cords.dm | 26 +- code/modules/unit_tests/create_and_destroy.dm | 2 - code/modules/uplink/uplink_items.dm | 7 - shiptest.dme | 42 - 166 files changed, 167 insertions(+), 12801 deletions(-) delete mode 100644 _maps/RandomRuins/ReebeRuins/reebe_swarmers.dmm delete mode 100644 code/__DEFINES/cult.dm delete mode 100644 code/_onclick/hud/devil.dm delete mode 100644 code/_onclick/hud/swarmer.dm delete mode 100644 code/datums/components/soulstoned.dm delete mode 100644 code/game/area/Space_Station_13_areas.dm delete mode 100644 code/game/area/areas/shuttles.dm delete mode 100644 code/game/gamemodes/cult/cult.dm delete mode 100644 code/game/gamemodes/devil/devil_agent/devil_agent.dm delete mode 100644 code/game/gamemodes/devil/devil_game_mode.dm delete mode 100644 code/game/gamemodes/devil/game_mode.dm delete mode 100644 code/game/gamemodes/devil/objectives.dm delete mode 100644 code/game/gamemodes/meteor/meteor.dm delete mode 100644 code/modules/antagonists/cult/blood_magic.dm delete mode 100644 code/modules/antagonists/cult/cult.dm delete mode 100644 code/modules/antagonists/cult/cult_comms.dm delete mode 100644 code/modules/antagonists/cult/cult_items.dm delete mode 100644 code/modules/antagonists/cult/cult_structures.dm delete mode 100644 code/modules/antagonists/cult/cult_turf_overlay.dm delete mode 100644 code/modules/antagonists/cult/rune_spawn_action.dm delete mode 100644 code/modules/antagonists/cult/runes.dm delete mode 100644 code/modules/antagonists/devil/devil.dm delete mode 100644 code/modules/antagonists/devil/imp/imp.dm delete mode 100644 code/modules/antagonists/devil/sintouched/objectives.dm delete mode 100644 code/modules/antagonists/devil/sintouched/sintouched.dm delete mode 100644 code/modules/antagonists/devil/true_devil/_true_devil.dm delete mode 100644 code/modules/antagonists/devil/true_devil/inventory.dm delete mode 100644 code/modules/antagonists/swarmer/swarmer.dm delete mode 100644 code/modules/antagonists/swarmer/swarmer_event.dm delete mode 100644 code/modules/antagonists/wizard/equipment/soulstone.dm delete mode 100644 code/modules/awaymissions/mission_code/stationCollision.dm delete mode 100644 code/modules/events/devil.dm delete mode 100644 code/modules/events/major_dust.dm delete mode 100644 code/modules/events/meateor_wave.dm delete mode 100644 code/modules/events/meteor_wave.dm delete mode 100644 code/modules/library/lib_codex_gigas.dm delete mode 100644 code/modules/mob/living/simple_animal/constructs.dm delete mode 100644 code/modules/mob/living/simple_animal/hostile/megafauna/swarmer.dm delete mode 100644 code/modules/mob/living/simple_animal/shade.dm delete mode 100644 code/modules/power/singularity/narsie.dm delete mode 100644 code/modules/spells/spell_types/construct_spells.dm delete mode 100644 code/modules/spells/spell_types/devil.dm delete mode 100644 code/modules/spells/spell_types/devil_boons.dm diff --git a/_maps/RandomRuins/ReebeRuins/reebe_swarmers.dmm b/_maps/RandomRuins/ReebeRuins/reebe_swarmers.dmm deleted file mode 100644 index 7c864f829fda..000000000000 --- a/_maps/RandomRuins/ReebeRuins/reebe_swarmers.dmm +++ /dev/null @@ -1,471 +0,0 @@ -//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"a" = ( -/turf/template_noop, -/area/template_noop) -"t" = ( -/turf/open/floor/grass/fairy/reebe, -/area/overmap_encounter/planetoid/reebe) -"u" = ( -/obj/structure/flora/tree/jungle{ - icon = 'icons/obj/flora/chapeltree.dmi'; - icon_state = "churchtree"; - pixel_x = -16; - pixel_y = 0 - }, -/turf/open/floor/grass/fairy/reebe, -/area/overmap_encounter/planetoid/reebe) -"x" = ( -/mob/living/simple_animal/hostile/asteroid/hivelord/legion/crystal, -/turf/open/floor/grass/fairy/reebe, -/area/overmap_encounter/planetoid/reebe) -"N" = ( -/turf/closed/mineral/random/reebe, -/area/ruin/reebe) -"R" = ( -/mob/living/simple_animal/hostile/megafauna/swarmer_swarm_beacon, -/turf/open/floor/grass/fairy/reebe, -/area/ruin/reebe) -"X" = ( -/turf/closed/mineral/random/reebe, -/area/overmap_encounter/planetoid/reebe) - -(1,1,1) = {" -a -a -a -a -a -a -a -a -t -t -t -a -a -a -a -a -a -a -a -a -"} -(2,1,1) = {" -a -a -t -t -t -t -a -a -N -u -t -t -N -N -t -t -t -t -a -a -"} -(3,1,1) = {" -a -t -N -t -N -x -t -t -t -N -N -t -t -t -t -N -N -t -a -a -"} -(4,1,1) = {" -a -t -t -N -N -N -N -N -N -N -N -N -N -N -N -N -N -t -a -a -"} -(5,1,1) = {" -t -t -N -N -N -N -N -N -N -N -N -N -N -N -N -N -t -u -a -a -"} -(6,1,1) = {" -a -t -N -N -N -N -N -N -N -N -N -N -N -N -N -N -t -t -t -a -"} -(7,1,1) = {" -a -t -N -N -N -N -N -N -N -N -N -N -N -N -N -N -N -N -t -a -"} -(8,1,1) = {" -a -t -N -N -N -N -N -N -N -N -N -N -N -N -N -N -N -N -t -a -"} -(9,1,1) = {" -a -t -N -N -N -N -N -N -N -N -N -N -N -N -N -N -N -N -t -a -"} -(10,1,1) = {" -t -t -N -N -N -N -N -N -N -N -N -N -N -N -N -N -N -N -t -a -"} -(11,1,1) = {" -t -u -t -N -N -N -N -N -N -R -N -N -N -N -N -N -N -t -t -a -"} -(12,1,1) = {" -t -t -t -N -N -N -N -N -N -N -N -N -N -N -N -N -N -N -t -a -"} -(13,1,1) = {" -t -N -t -N -N -N -N -N -N -N -N -N -N -N -N -N -N -t -t -a -"} -(14,1,1) = {" -t -t -N -N -N -N -N -N -N -N -N -N -N -N -N -N -N -t -a -a -"} -(15,1,1) = {" -a -t -N -N -N -N -N -N -N -N -N -N -N -N -N -N -N -t -t -a -"} -(16,1,1) = {" -t -t -t -N -N -N -N -N -N -N -N -N -N -N -N -N -N -N -t -a -"} -(17,1,1) = {" -t -t -t -t -N -N -N -N -N -N -N -N -N -N -N -N -N -N -t -a -"} -(18,1,1) = {" -a -a -a -t -N -N -N -N -N -N -N -t -t -t -t -N -N -t -t -a -"} -(19,1,1) = {" -a -a -a -t -t -t -t -t -t -t -t -t -N -X -u -t -t -t -a -a -"} -(20,1,1) = {" -a -a -a -a -a -a -a -a -a -a -a -a -t -t -t -a -a -a -a -a -"} diff --git a/_maps/shuttles/nanotrasen/nanotrasen_mimir.dmm b/_maps/shuttles/nanotrasen/nanotrasen_mimir.dmm index 716d68f653a9..7791494023f4 100644 --- a/_maps/shuttles/nanotrasen/nanotrasen_mimir.dmm +++ b/_maps/shuttles/nanotrasen/nanotrasen_mimir.dmm @@ -2314,20 +2314,6 @@ /obj/item/reagent_containers/food/snacks/urinalcake, /turf/open/floor/plasteel/white, /area/ship/crew/toilet) -"nb" = ( -/obj/structure/table/wood, -/obj/structure/window/reinforced/tinted/frosted{ - dir = 8 - }, -/obj/structure/window/reinforced/tinted/frosted{ - dir = 4 - }, -/obj/item/flashlight/lamp{ - pixel_y = 13 - }, -/obj/item/book/codex_gigas, -/turf/open/floor/wood, -/area/ship/crew/dorm) "nh" = ( /turf/closed/wall/r_wall, /area/ship/crew/dorm/dormtwo) @@ -2804,32 +2790,6 @@ /obj/effect/turf_decal/siding/wood, /turf/open/floor/wood, /area/ship/crew/hydroponics) -"qe" = ( -/obj/structure/closet/secure_closet/freezer{ - name = "Refrigerator"; - desc = "A refrigerated cabinet for food." - }, -/obj/effect/turf_decal/siding/wideplating/light/end{ - dir = 4 - }, -/obj/item/storage/fancy/egg_box, -/obj/item/storage/fancy/egg_box, -/obj/item/reagent_containers/condiment/milk, -/obj/item/reagent_containers/condiment/milk, -/obj/item/reagent_containers/condiment/milk, -/obj/item/reagent_containers/condiment/soymilk, -/obj/item/reagent_containers/condiment/soymilk, -/obj/item/reagent_containers/condiment/soymilk, -/obj/item/reagent_containers/condiment/flour, -/obj/item/reagent_containers/condiment/flour, -/obj/item/reagent_containers/condiment/flour, -/obj/item/reagent_containers/condiment/sugar, -/obj/item/reagent_containers/condiment/sugar, -/obj/item/reagent_containers/condiment/rice, -/obj/item/reagent_containers/food/snacks/tofu, -/obj/item/reagent_containers/food/snacks/tofu, -/turf/open/floor/plasteel/mono/white, -/area/ship/crew/canteen/kitchen) "qh" = ( /obj/machinery/hydroponics/constructable{ pixel_y = 8 @@ -3876,27 +3836,6 @@ /obj/structure/table, /turf/open/floor/plasteel, /area/ship/crew/canteen/kitchen) -"xb" = ( -/obj/structure/table, -/obj/item/reagent_containers/condiment/sugar{ - pixel_y = 4 - }, -/obj/item/reagent_containers/condiment/rice{ - pixel_y = 10; - pixel_x = 3 - }, -/obj/item/reagent_containers/condiment/enzyme{ - pixel_x = -5; - pixel_y = 5 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{ - dir = 5 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{ - dir = 5 - }, -/turf/open/floor/plasteel/mono/white, -/area/ship/crew/canteen/kitchen) "xc" = ( /obj/effect/turf_decal/siding/wood/end{ dir = 8 @@ -4100,10 +4039,6 @@ "ys" = ( /turf/closed/wall/r_wall, /area/ship/crew/dorm) -"yu" = ( -/obj/item/clothing/mask/gas/monkeymask, -/turf/open/floor/plating, -/area/ship/maintenance/fore) "yw" = ( /obj/effect/decal/cleanable/food/tomato_smudge, /obj/effect/turf_decal/siding/wood{ @@ -4460,21 +4395,6 @@ }, /turf/open/floor/plasteel/tech/grid, /area/ship/maintenance/starboard) -"AH" = ( -/obj/structure/table, -/obj/item/toy/figure/chef, -/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4, -/obj/item/reagent_containers/condiment/saltshaker{ - pixel_y = 10; - pixel_x = -7 - }, -/obj/item/reagent_containers/condiment/peppermill{ - pixel_x = 8; - pixel_y = 9 - }, -/turf/open/floor/plasteel/mono/white, -/area/ship/crew/canteen/kitchen) "AI" = ( /obj/machinery/atmospherics/pipe/simple/cyan/hidden/layer4{ dir = 6 @@ -4567,6 +4487,19 @@ }, /turf/open/floor/plasteel, /area/ship/security/prison) +"Bf" = ( +/obj/structure/table/wood, +/obj/structure/window/reinforced/tinted/frosted{ + dir = 8 + }, +/obj/structure/window/reinforced/tinted/frosted{ + dir = 4 + }, +/obj/item/flashlight/lamp{ + pixel_y = 13 + }, +/turf/open/floor/wood, +/area/ship/crew/dorm) "Bi" = ( /obj/structure/cable{ icon_state = "1-2" @@ -4921,6 +4854,27 @@ /obj/effect/spawner/lootdrop/ration, /turf/open/floor/plasteel, /area/ship/security/prison) +"Dj" = ( +/obj/structure/table, +/obj/item/reagent_containers/condiment/sugar{ + pixel_y = 4 + }, +/obj/item/reagent_containers/condiment/rice{ + pixel_y = 10; + pixel_x = 3 + }, +/obj/item/reagent_containers/condiment/enzyme{ + pixel_x = -5; + pixel_y = 5 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4{ + dir = 5 + }, +/turf/open/floor/plasteel/mono/white, +/area/ship/crew/canteen/kitchen) "Dm" = ( /obj/structure/window/reinforced/spawner{ dir = 1 @@ -5863,6 +5817,21 @@ /obj/effect/turf_decal/siding/yellow, /turf/open/floor/plasteel, /area/ship/security/prison) +"Ie" = ( +/obj/structure/table, +/obj/item/toy/figure/chef, +/obj/machinery/atmospherics/pipe/simple/supply/hidden/layer2, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden/layer4, +/obj/item/reagent_containers/condiment/saltshaker{ + pixel_y = 10; + pixel_x = -7 + }, +/obj/item/reagent_containers/condiment/peppermill{ + pixel_x = 8; + pixel_y = 9 + }, +/turf/open/floor/plasteel/mono/white, +/area/ship/crew/canteen/kitchen) "Ig" = ( /obj/machinery/door/poddoor/shutters/preopen{ id = "quickpoint_shut"; @@ -6210,6 +6179,10 @@ }, /turf/open/floor/plasteel, /area/ship/security) +"Kc" = ( +/obj/item/clothing/mask/gas/monkeymask, +/turf/open/floor/plating, +/area/ship/maintenance/fore) "Kg" = ( /obj/effect/turf_decal/siding/red{ dir = 8 @@ -8459,6 +8432,32 @@ }, /turf/open/floor/wood, /area/ship/crew/dorm/dormfour) +"Xf" = ( +/obj/structure/closet/secure_closet/freezer{ + name = "Refrigerator"; + desc = "A refrigerated cabinet for food." + }, +/obj/effect/turf_decal/siding/wideplating/light/end{ + dir = 4 + }, +/obj/item/storage/fancy/egg_box, +/obj/item/storage/fancy/egg_box, +/obj/item/reagent_containers/condiment/milk, +/obj/item/reagent_containers/condiment/milk, +/obj/item/reagent_containers/condiment/milk, +/obj/item/reagent_containers/condiment/soymilk, +/obj/item/reagent_containers/condiment/soymilk, +/obj/item/reagent_containers/condiment/soymilk, +/obj/item/reagent_containers/condiment/flour, +/obj/item/reagent_containers/condiment/flour, +/obj/item/reagent_containers/condiment/flour, +/obj/item/reagent_containers/condiment/sugar, +/obj/item/reagent_containers/condiment/sugar, +/obj/item/reagent_containers/condiment/rice, +/obj/item/reagent_containers/food/snacks/tofu, +/obj/item/reagent_containers/food/snacks/tofu, +/turf/open/floor/plasteel/mono/white, +/area/ship/crew/canteen/kitchen) "Xg" = ( /obj/machinery/door/window{ dir = 4 @@ -9144,7 +9143,7 @@ Mv Lu rq Hm -nb +Bf dJ VG oM @@ -9550,8 +9549,8 @@ PP td VK Fg -AH -xb +Ie +Dj nR zq mU @@ -9674,7 +9673,7 @@ pe Rr KQ wa -qe +Xf Ad gZ eF @@ -10356,7 +10355,7 @@ oI VU Dy nh -yu +Kc nK jY jY diff --git a/check_regex.yaml b/check_regex.yaml index 41174bd9aa22..a56bd83644d3 100644 --- a/check_regex.yaml +++ b/check_regex.yaml @@ -29,7 +29,7 @@ standards: - exactly: [1, "/area text paths", '"/area'] - exactly: [17, "/datum text paths", '"/datum'] - exactly: [4, "/mob text paths", '"/mob'] - - exactly: [42, "/obj text paths", '"/obj'] + - exactly: [36, "/obj text paths", '"/obj'] - exactly: [0, "/turf text paths", '"/turf'] - exactly: [115, "text2path uses", "text2path"] @@ -38,7 +38,7 @@ standards: - exactly: [ - 262, + 261, "non-bitwise << uses", '(?[souls]" - switch(souls) - if(0,null) - icon_state = "Devil-1" - if(1,2) - icon_state = "Devil-2" - if(3 to 5) - icon_state = "Devil-3" - if(6 to 8) - icon_state = "Devil-4" - if(9 to INFINITY) - icon_state = "Devil-5" - else - icon_state = "Devil-6" - -/atom/movable/screen/devil/soul_counter/proc/clear() - invisibility = INVISIBILITY_ABSTRACT - /atom/movable/screen/ling icon = 'icons/hud/screen_changeling.dmi' invisibility = INVISIBILITY_ABSTRACT @@ -338,10 +309,6 @@ lingstingdisplay.hud = src infodisplay += lingstingdisplay - devilsouldisplay = new /atom/movable/screen/devil/soul_counter - devilsouldisplay.hud = src - infodisplay += devilsouldisplay - zone_select = new /atom/movable/screen/zone_sel() zone_select.icon = ui_style zone_select.hud = src diff --git a/code/_onclick/hud/swarmer.dm b/code/_onclick/hud/swarmer.dm deleted file mode 100644 index 6aba23fab5c7..000000000000 --- a/code/_onclick/hud/swarmer.dm +++ /dev/null @@ -1,98 +0,0 @@ - - -/atom/movable/screen/swarmer - icon = 'icons/mob/swarmer.dmi' - -/atom/movable/screen/swarmer/FabricateTrap - icon_state = "ui_trap" - name = "Create trap (Costs 5 Resources)" - desc = "Creates a trap that will nonlethally shock any non-swarmer that attempts to cross it. (Costs 5 resources)" - -/atom/movable/screen/swarmer/FabricateTrap/Click() - if(isswarmer(usr)) - var/mob/living/simple_animal/hostile/swarmer/S = usr - S.CreateTrap() - -/atom/movable/screen/swarmer/Barricade - icon_state = "ui_barricade" - name = "Create barricade (Costs 5 Resources)" - desc = "Creates a destructible barricade that will stop any non swarmer from passing it. Also allows disabler beams to pass through. (Costs 5 resources)" - -/atom/movable/screen/swarmer/Barricade/Click() - if(isswarmer(usr)) - var/mob/living/simple_animal/hostile/swarmer/S = usr - S.CreateBarricade() - -/atom/movable/screen/swarmer/Replicate - icon_state = "ui_replicate" - name = "Replicate (Costs 50 Resources)" - desc = "Creates another of our kind." - -/atom/movable/screen/swarmer/Replicate/Click() - if(isswarmer(usr)) - var/mob/living/simple_animal/hostile/swarmer/S = usr - S.CreateSwarmer() - -/atom/movable/screen/swarmer/RepairSelf - icon_state = "ui_self_repair" - name = "Repair self" - desc = "Repairs damage to our body." - -/atom/movable/screen/swarmer/RepairSelf/Click() - if(isswarmer(usr)) - var/mob/living/simple_animal/hostile/swarmer/S = usr - S.RepairSelf() - -/atom/movable/screen/swarmer/ToggleLight - icon_state = "ui_light" - name = "Toggle light" - desc = "Toggles our inbuilt light on or off." - -/atom/movable/screen/swarmer/ToggleLight/Click() - if(isswarmer(usr)) - var/mob/living/simple_animal/hostile/swarmer/S = usr - S.ToggleLight() - -/atom/movable/screen/swarmer/ContactSwarmers - icon_state = "ui_contact_swarmers" - name = "Contact swarmers" - desc = "Sends a message to all other swarmers, should they exist." - -/atom/movable/screen/swarmer/ContactSwarmers/Click() - if(isswarmer(usr)) - var/mob/living/simple_animal/hostile/swarmer/S = usr - S.ContactSwarmers() - -/datum/hud/swarmer/New(mob/owner) - ..() - var/atom/movable/screen/using - - using = new /atom/movable/screen/swarmer/FabricateTrap() - using.screen_loc = ui_hand_position(2) - using.hud = src - static_inventory += using - - using = new /atom/movable/screen/swarmer/Barricade() - using.screen_loc = ui_hand_position(1) - using.hud = src - static_inventory += using - - using = new /atom/movable/screen/swarmer/Replicate() - using.screen_loc = ui_zonesel - using.hud = src - static_inventory += using - - using = new /atom/movable/screen/swarmer/RepairSelf() - using.screen_loc = ui_storage1 - using.hud = src - static_inventory += using - - using = new /atom/movable/screen/swarmer/ToggleLight() - using.screen_loc = ui_back - using.hud = src - static_inventory += using - - using = new /atom/movable/screen/swarmer/ContactSwarmers() - using.screen_loc = ui_inventory - using.hud = src - static_inventory += using diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index 806e3e6df328..8e848963567e 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -177,14 +177,6 @@ /atom/proc/attack_drone(mob/living/simple_animal/drone/user) attack_hand(user) //defaults to attack_hand. Override it when you don't want drones to do same stuff as humans. - -/* - True Devil -*/ - -/mob/living/carbon/true_devil/UnarmedAttack(atom/A, proximity) - A.attack_hand(src) - /* Brain */ diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index c9666d85608d..19df8eaf236c 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -151,7 +151,7 @@ SUBSYSTEM_DEF(shuttle) mapzone.parallax_movedir = travel_dir - var/area/shuttle/transit/transit_area = new() + var/area/hyperspace/transit_area = new() vlevel.fill_in(transit_path, transit_area) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index c9be29ce95bc..f12de2427f75 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -445,12 +445,6 @@ SUBSYSTEM_DEF(ticker) news_message = "[station_name()] has been evacuated after transmitting the following distress beacon:\n\n[emergency_reason]" else news_message = "The crew of [station_name()] has been evacuated amid unconfirmed reports of enemy activity." - if(CULT_ESCAPE) - news_message = "Security Alert: A group of religious fanatics have escaped from [station_name()]." - if(CULT_FAILURE) - news_message = "Following the dismantling of a restricted cult aboard [station_name()], we would like to remind all employees that worship outside of the Chapel is strictly prohibited, and cause for termination." - if(CULT_SUMMON) - news_message = "Company officials would like to clarify that [station_name()] was scheduled to be decommissioned following meteor damage earlier this year. Earlier reports of an unknowable eldritch horror were made in error." if(NUKE_MISS) news_message = "The Syndicate have bungled a terrorist attack [station_name()], detonating a nuclear weapon in empty space nearby." if(OPERATIVES_KILLED) diff --git a/code/controllers/subsystem/traumas.dm b/code/controllers/subsystem/traumas.dm index ecf43af5cc9d..2cc479a6c0a2 100644 --- a/code/controllers/subsystem/traumas.dm +++ b/code/controllers/subsystem/traumas.dm @@ -44,10 +44,9 @@ SUBSYSTEM_DEF(traumas) "skeletons" = typecacheof(list(/mob/living/simple_animal/hostile/human/skeleton)), "snakes" = typecacheof(list(/mob/living/simple_animal/hostile/retaliate/poison/snake)), "robots" = typecacheof(list(/mob/living/silicon/robot, /mob/living/silicon/ai, - /mob/living/simple_animal/drone, /mob/living/simple_animal/bot, /mob/living/simple_animal/hostile/swarmer)), + /mob/living/simple_animal/drone, /mob/living/simple_animal/bot)), "doctors" = typecacheof(list(/mob/living/simple_animal/bot/medbot)), - "the supernatural" = typecacheof(list(/mob/living/simple_animal/hostile/construct, - /mob/living/simple_animal/revenant, /mob/living/simple_animal/shade)), + "the supernatural" = typecacheof(list(/mob/living/simple_animal/revenant)), "aliens" = typecacheof(list(/mob/living/carbon/alien, /mob/living/simple_animal/slime, /mob/living/simple_animal/hostile/facehugger)), "conspiracies" = typecacheof(list(/mob/living/simple_animal/bot/secbot, /mob/living/simple_animal/drone, /mob/living/simple_animal/pet/penguin)), @@ -104,7 +103,7 @@ SUBSYSTEM_DEF(traumas) "robots" = typecacheof(list( /obj/machinery/computer/upload, /obj/item/aiModule/, /obj/machinery/recharge_station, - /obj/item/aicard, /obj/item/deactivated_swarmer, /obj/effect/mob_spawn/swarmer)), + /obj/item/aicard)), "doctors" = typecacheof(list( /obj/item/clothing/under/rank/medical, @@ -124,11 +123,6 @@ SUBSYSTEM_DEF(traumas) /obj/item/card/id/captains_spare, /obj/item/card/id/centcom, /obj/machinery/door/airlock/command)), "the supernatural" = typecacheof(list( - /obj/structure/destructible/cult, /obj/item/tome, - /obj/item/restraints/legcuffs/bola/cult, /obj/item/clothing/suit/space/hardsuit/cult, - /obj/effect/rune, - /obj/machinery/door/airlock/cult, /obj/singularity/narsie, - /obj/item/soulstone, /obj/item/clothing/suit/wizrobe, /obj/item/clothing/head/wizard, /obj/item/spellbook, /obj/item/staff, /obj/item/clothing/suit/space/hardsuit/shielded/wizard, /obj/item/clothing/suit/space/hardsuit/wizard, /obj/item/clothing/under/rank/civilian/chaplain)), @@ -160,7 +154,7 @@ SUBSYSTEM_DEF(traumas) phobia_turfs = list( "space" = typecacheof(list(/turf/open/space, /turf/open/floor/holofloor/space, /turf/open/floor/fakespace)), - "the supernatural" = typecacheof(list(/turf/open/floor/plasteel/cult, /turf/closed/wall/mineral/cult)), + "the supernatural" = typecacheof(/turf/closed/wall/mineral/cult, /turf/open/floor/plasteel/cult), "aliens" = typecacheof(list( /turf/open/floor/plating/abductor, /turf/open/floor/plating/abductor2, /turf/open/floor/mineral/abductor, /turf/closed/wall/mineral/abductor)), diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm index 372e51280f4a..3f07eb3b15be 100644 --- a/code/datums/ai_laws.dm +++ b/code/datums/ai_laws.dm @@ -1,4 +1,3 @@ -#define LAW_DEVIL "devil" #define LAW_ZEROTH "zeroth" #define LAW_INHERENT "inherent" #define LAW_SUPPLIED "supplied" @@ -15,7 +14,6 @@ var/list/ion = list() var/list/hacked = list() var/mob/living/silicon/owner - var/list/devillaws = list() var/id = DEFAULT_AI_LAWID /datum/ai_laws/Destroy(force, ...) @@ -408,8 +406,6 @@ /datum/ai_laws/proc/get_law_amount(groups) var/law_amount = 0 - if(devillaws && (LAW_DEVIL in groups)) - law_amount++ if(zeroth && (LAW_ZEROTH in groups)) law_amount++ if(ion.len && (LAW_ION in groups)) @@ -425,9 +421,6 @@ law_amount++ return law_amount -/datum/ai_laws/proc/set_law_sixsixsix(laws) - devillaws = laws - /datum/ai_laws/proc/set_zeroth_law(law, law_borg = null) zeroth = law if(law_borg) //Making it possible for slaved borgs to see a different law 0 than their AI. --NEO @@ -564,10 +557,6 @@ zeroth = null zeroth_borg = null -/datum/ai_laws/proc/clear_law_sixsixsix(force) - if(force || !is_devil(owner)) - devillaws = null - /datum/ai_laws/proc/associate(mob/living/silicon/M) if(!owner) owner = M @@ -583,10 +572,6 @@ /datum/ai_laws/proc/get_law_list(include_zeroth = FALSE, show_numbers = TRUE, render_html = TRUE) var/list/data = list() - if (include_zeroth && devillaws) - for(var/law in devillaws) - data += "[show_numbers ? "666:" : ""] [render_html ? "[law]" : law]" - if (include_zeroth && zeroth) data += "[show_numbers ? "0:" : ""] [render_html ? "[zeroth]" : zeroth]" diff --git a/code/datums/cinematic.dm b/code/datums/cinematic.dm index cbb7df599326..9529cd19567a 100644 --- a/code/datums/cinematic.dm +++ b/code/datums/cinematic.dm @@ -182,47 +182,6 @@ special() screen.icon_state = "summary_malf" -/datum/cinematic/cult - id = CINEMATIC_CULT - -/datum/cinematic/cult/content() - screen.icon_state = null - flick("intro_cult",screen) - sleep(25) - cinematic_sound(sound('sound/magic/enter_blood.ogg')) - sleep(28) - cinematic_sound(sound('sound/machines/terminal_off.ogg')) - sleep(20) - flick("station_corrupted",screen) - cinematic_sound(sound('sound/effects/ghost.ogg')) - sleep(70) - special() - -/datum/cinematic/cult_nuke - id = CINEMATIC_CULT_NUKE - -/datum/cinematic/cult_nuke/content() - flick("intro_nuke",screen) - sleep(35) - flick("station_explode_fade_red",screen) - cinematic_sound(sound('sound/effects/explosion_distant.ogg')) - special() - screen.icon_state = "summary_cult" - -/datum/cinematic/cult_fail - id = CINEMATIC_CULT_FAIL - -/datum/cinematic/cult_fail/content() - screen.icon_state = "station_intact" - sleep(20) - cinematic_sound(sound('sound/creatures/narsie_rises.ogg')) - sleep(60) - cinematic_sound(sound('sound/effects/explosion_distant.ogg')) - sleep(10) - cinematic_sound(sound('sound/magic/demon_dies.ogg')) - sleep(30) - special() - /datum/cinematic/nuke_annihilation id = CINEMATIC_ANNIHILATION @@ -274,15 +233,3 @@ cinematic_sound(sound('sound/items/airhorn.ogg')) flick("summary_selfdes",screen) //??? special() - -/* Intended usage. -Nuke.Explosion() - -> Cinematic(NUKE_BOOM,world) - -> ActualExplosion() - -> Mode.OnExplosion() - - -Narsie() - -> Cinematic(CULT,world) -*/ - diff --git a/code/datums/components/soulstoned.dm b/code/datums/components/soulstoned.dm deleted file mode 100644 index 04e514062879..000000000000 --- a/code/datums/components/soulstoned.dm +++ /dev/null @@ -1,33 +0,0 @@ -//adds godmode while in the container, prevents moving, and clears these effects up after leaving the stone -/datum/component/soulstoned - var/atom/movable/container - -/datum/component/soulstoned/Initialize(atom/movable/container) - if(!isanimal(parent)) - return COMPONENT_INCOMPATIBLE - var/mob/living/simple_animal/S = parent - - src.container = container - - S.forceMove(container) - - S.status_flags |= GODMODE - ADD_TRAIT(S, TRAIT_IMMOBILIZED, SOULSTONE_TRAIT) - ADD_TRAIT(S, TRAIT_HANDS_BLOCKED, SOULSTONE_TRAIT) - S.health = S.maxHealth - S.bruteloss = 0 - - RegisterSignal(S, COMSIG_MOVABLE_MOVED, PROC_REF(free_prisoner)) - -/datum/component/soulstoned/proc/free_prisoner() - SIGNAL_HANDLER - - var/mob/living/simple_animal/S = parent - if(S.loc != container) - qdel(src) - -/datum/component/soulstoned/UnregisterFromParent() - var/mob/living/simple_animal/S = parent - S.status_flags &= ~GODMODE - REMOVE_TRAIT(S, TRAIT_IMMOBILIZED, SOULSTONE_TRAIT) - REMOVE_TRAIT(S, TRAIT_HANDS_BLOCKED, SOULSTONE_TRAIT) diff --git a/code/datums/hud.dm b/code/datums/hud.dm index 24865387794a..4703a31ea0f8 100644 --- a/code/datums/hud.dm +++ b/code/datums/hud.dm @@ -14,7 +14,6 @@ GLOBAL_LIST_INIT(huds, list( DATA_HUD_SENTIENT_DISEASE = new/datum/atom_hud/sentient_disease(), DATA_HUD_AI_DETECT = new/datum/atom_hud/ai_detector(), DATA_HUD_FAN = new/datum/atom_hud/data/human/fan_hud(), - ANTAG_HUD_CULT = new/datum/atom_hud/antag(), ANTAG_HUD_REV = new/datum/atom_hud/antag(), ANTAG_HUD_OPS = new/datum/atom_hud/antag(), ANTAG_HUD_WIZ = new/datum/atom_hud/antag(), @@ -23,9 +22,6 @@ GLOBAL_LIST_INIT(huds, list( ANTAG_HUD_NINJA = new/datum/atom_hud/antag/hidden(), ANTAG_HUD_CHANGELING = new/datum/atom_hud/antag/hidden(), ANTAG_HUD_ABDUCTOR = new/datum/atom_hud/antag/hidden(), - ANTAG_HUD_DEVIL = new/datum/atom_hud/antag(), - ANTAG_HUD_SINTOUCHED = new/datum/atom_hud/antag/hidden(), - ANTAG_HUD_SOULLESS = new/datum/atom_hud/antag/hidden(), ANTAG_HUD_BROTHER = new/datum/atom_hud/antag/hidden(), ANTAG_HUD_OBSESSED = new/datum/atom_hud/antag/hidden(), ANTAG_HUD_FUGITIVE = new/datum/atom_hud/antag(), diff --git a/code/datums/map_zones.dm b/code/datums/map_zones.dm index c4e304fb5394..bf103242c8db 100644 --- a/code/datums/map_zones.dm +++ b/code/datums/map_zones.dm @@ -637,7 +637,7 @@ var/ty = destination_y var/turf/DT = locate(tx, ty, destination_z) var/itercount = 0 - while(DT.density || istype(DT.loc,/area/shuttle)) // Extend towards the center of the map, trying to look for a better place to arrive + while(DT.density) // Extend towards the center of the map, trying to look for a better place to arrive if (itercount++ >= 100) log_game("SPACE Z-TRANSIT ERROR: Could not find a safe place to land [arrived] within 100 iterations.") break diff --git a/code/datums/mind.dm b/code/datums/mind.dm index ee3ca3631332..395b1a3e4431 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -345,12 +345,6 @@ remove_antag_datum(/datum/antagonist/wizard) special_role = null -/datum/mind/proc/remove_cultist() - if(src in SSticker.mode.cult) - SSticker.mode.remove_cultist(src, 0, 0) - special_role = null - remove_antag_equip() - /datum/mind/proc/remove_antag_equip() var/list/Mob_Contents = current.get_contents() for(var/obj/item/I in Mob_Contents) @@ -363,7 +357,6 @@ remove_traitor() remove_nukeop() remove_wizard() - remove_cultist() /datum/mind/proc/equip_traitor(employer = "The Syndicate", silent = FALSE, datum/antagonist/uplink_owner) if(!current) @@ -436,10 +429,7 @@ //Link a new mobs mind to the creator of said mob. They will join any team they are currently on, and will only switch teams when their creator does. /datum/mind/proc/enslave_mind_to_creator(mob/living/creator) - if(iscultist(creator)) - SSticker.mode.add_cultist(src) - - else if(is_nuclear_operative(creator)) + if(is_nuclear_operative(creator)) var/datum/antagonist/nukeop/converter = creator.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE) var/datum/antagonist/nukeop/N = new() N.send_to_spawnpoint = FALSE @@ -708,14 +698,6 @@ assigned_role = ROLE_WIZARD add_antag_datum(/datum/antagonist/wizard) - -/datum/mind/proc/make_Cultist() - if(!has_antag_datum(/datum/antagonist/cult,TRUE)) - SSticker.mode.add_cultist(src,FALSE,equip=TRUE) - special_role = ROLE_CULTIST - to_chat(current, "You catch a glimpse of the Realm of Nar'Sie, The Geometer of Blood. You now see how flimsy your world is, you see that it should be open to the knowledge of Nar'Sie.") - to_chat(current, "Assist your new brethren in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back.") - /datum/mind/proc/AddSpell(obj/effect/proc_holder/spell/S) spell_list += S S.action.Grant(current) diff --git a/code/datums/mood_events/generic_positive_events.dm b/code/datums/mood_events/generic_positive_events.dm index f9e339c3c081..1ab201bc0186 100644 --- a/code/datums/mood_events/generic_positive_events.dm +++ b/code/datums/mood_events/generic_positive_events.dm @@ -96,11 +96,6 @@ mood_change = 3 hidden = TRUE -/datum/mood_event/cult - description = "I have seen the truth, praise the almighty one!\n" - mood_change = 10 //maybe being a cultist isnt that bad after all - hidden = TRUE - /datum/mood_event/family_heirloom description = "My family heirloom is safe with me.\n" mood_change = 1 diff --git a/code/datums/ruins/reebe.dm b/code/datums/ruins/reebe.dm index bec9986d75b8..d1a9de3e024f 100644 --- a/code/datums/ruins/reebe.dm +++ b/code/datums/ruins/reebe.dm @@ -11,13 +11,6 @@ suffix = "reebe_arena.dmm" ruin_tags = list(RUIN_TAG_BOSS_COMBAT, RUIN_TAG_MEDIUM_LOOT, RUIN_TAG_LIVEABLE) -/datum/map_template/ruin/reebe/swarmers - name = "Swarmer Island" - id = "swarmers" - description = "Looks like someone has occupied Reebe in the cultists' absence." - suffix = "reebe_swarmers.dmm" - ruin_tags = list(RUIN_TAG_MEDIUM_COMBAT, RUIN_TAG_MINOR_LOOT, RUIN_TAG_LIVEABLE) - /datum/map_template/ruin/reebe/island name = "Island Cache" id = "islandcache" diff --git a/code/datums/saymode.dm b/code/datums/saymode.dm index 848940d4e9d9..708a81107313 100644 --- a/code/datums/saymode.dm +++ b/code/datums/saymode.dm @@ -95,15 +95,11 @@ return FALSE -/datum/saymode/binary //everything that uses .b (silicons, drones, swarmers) +/datum/saymode/binary //everything that uses .b (silicons, drones) key = MODE_KEY_BINARY mode = MODE_BINARY /datum/saymode/binary/handle_message(mob/living/user, message, datum/language/language) - if(isswarmer(user)) - var/mob/living/simple_animal/hostile/swarmer/S = user - S.swarmer_chat(message) - return FALSE if(isdrone(user)) var/mob/living/simple_animal/drone/D = user D.drone_chat(message) diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm index 749745dd6a7c..93d2cda195c0 100644 --- a/code/datums/status_effects/buffs.dm +++ b/code/datums/status_effects/buffs.dm @@ -85,35 +85,6 @@ desc = "You are being resurrected!" icon_state = "wish_granter" -/datum/status_effect/cult_master - id = "The Cult Master" - duration = -1 - alert_type = null - on_remove_on_mob_delete = TRUE - var/alive = TRUE - -/datum/status_effect/cult_master/proc/deathrattle() - if(!QDELETED(GLOB.cult_narsie)) - return //if Nar'Sie is alive, don't even worry about it - var/area/A = get_area(owner) - for(var/datum/mind/B in SSticker.mode.cult) - if(isliving(B.current)) - var/mob/living/M = B.current - SEND_SOUND(M, sound('sound/hallucinations/veryfar_noise.ogg')) - to_chat(M, "The Cult's Master, [owner], has fallen in \the [A]!") - -/datum/status_effect/cult_master/tick() - if(owner.stat != DEAD && !alive) - alive = TRUE - return - if(owner.stat == DEAD && alive) - alive = FALSE - deathrattle() - -/datum/status_effect/cult_master/on_remove() - deathrattle() - . = ..() - /datum/status_effect/blooddrunk id = "blooddrunk" duration = 10 diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index 17e2208cdebe..6d803d98ec47 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -253,19 +253,6 @@ /datum/status_effect/pacify/on_remove() REMOVE_TRAIT(owner, TRAIT_PACIFISM, "status_effect") -/datum/status_effect/cultghost //is a cult ghost and can't use manifest runes - id = "cult_ghost" - duration = -1 - alert_type = null - -/datum/status_effect/cultghost/on_apply() - owner.see_invisible = SEE_INVISIBLE_OBSERVER - owner.see_in_dark = 2 - -/datum/status_effect/cultghost/tick() - if(owner.reagents) - owner.reagents.del_reagent(/datum/reagent/water/holywater) //can't be deconverted - /datum/status_effect/crusher_mark id = "crusher_mark" duration = 300 //if you leave for 30 seconds you lose the mark, deal with it diff --git a/code/game/alternate_appearance.dm b/code/game/alternate_appearance.dm index 96f09636fec3..873828d2c260 100644 --- a/code/game/alternate_appearance.dm +++ b/code/game/alternate_appearance.dm @@ -130,32 +130,6 @@ GLOBAL_LIST_EMPTY(active_alternate_appearances) /datum/atom_hud/alternate_appearance/basic/observers/mobShouldSee(mob/M) return isobserver(M) -/datum/atom_hud/alternate_appearance/basic/noncult - -/datum/atom_hud/alternate_appearance/basic/noncult/New() - ..() - for(var/mob in GLOB.player_list) - if(mobShouldSee(mob)) - add_hud_to(mob) - -/datum/atom_hud/alternate_appearance/basic/noncult/mobShouldSee(mob/M) - if(!iscultist(M)) - return TRUE - return FALSE - -/datum/atom_hud/alternate_appearance/basic/cult - -/datum/atom_hud/alternate_appearance/basic/cult/New() - ..() - for(var/mob in GLOB.player_list) - if(mobShouldSee(mob)) - add_hud_to(mob) - -/datum/atom_hud/alternate_appearance/basic/cult/mobShouldSee(mob/M) - if(iscultist(M)) - return TRUE - return FALSE - /datum/atom_hud/alternate_appearance/basic/blessedAware /datum/atom_hud/alternate_appearance/basic/blessedAware/New() @@ -167,8 +141,6 @@ GLOBAL_LIST_EMPTY(active_alternate_appearances) /datum/atom_hud/alternate_appearance/basic/blessedAware/mobShouldSee(mob/M) if(M.mind && (M.mind.assigned_role == "Chaplain")) return TRUE - if (istype(M, /mob/living/simple_animal/hostile/construct/wraith)) - return TRUE if(isrevenant(M) || iswizard(M)) return TRUE return FALSE diff --git a/code/game/area/Space_Station_13_areas.dm b/code/game/area/Space_Station_13_areas.dm deleted file mode 100644 index 3fb4fcd5efeb..000000000000 --- a/code/game/area/Space_Station_13_areas.dm +++ /dev/null @@ -1,1350 +0,0 @@ -/* - -### This file contains a list of all the areas in your station. Format is as follows: - -/area/CATEGORY/OR/DESCRIPTOR/NAME (you can make as many subdivisions as you want) - name = "NICE NAME" (not required but makes things really nice) - icon = 'ICON FILENAME' (defaults to 'icons/turf/areas.dmi') - icon_state = "NAME OF ICON" (defaults to "unknown" (blank)) - requires_power = FALSE (defaults to true) - ambientsounds = list() (defaults to GENERIC from sound.dm. override it as "ambientsounds = list('sound/ambience/signal.ogg')" or using another define. - -NOTE: there are two lists of areas in the end of this file: centcom and station itself. Please maintain these lists valid. --rastaf0 - -*/ - - -/*-----------------------------------------------------------------------------*/ - -/* Shiptest Begin - -/area/ai_monitored //stub defined ai_monitored.dm - -/area/ai_monitored/turret_protected - -/area/space - icon_state = "space" - requires_power = TRUE - always_unpowered = TRUE - dynamic_lighting = DYNAMIC_LIGHTING_DISABLED - power_light = FALSE - power_equip = FALSE - power_environ = FALSE - area_flags = UNIQUE_AREA | CAVES_ALLOWED | MOB_SPAWN_ALLOWED - outdoors = TRUE - ambientsounds = SPACE - flags_1 = CAN_BE_DIRTY_1 - sound_environment = SOUND_AREA_SPACE - -/area/space/nearstation - icon_state = "space_near" - dynamic_lighting = DYNAMIC_LIGHTING_IFSTARLIGHT - -/area/start - name = "start area" - icon_state = "start" - requires_power = FALSE - dynamic_lighting = DYNAMIC_LIGHTING_DISABLED - has_gravity = STANDARD_GRAVITY - - -/area/testroom - requires_power = FALSE - name = "Test Room" - icon_state = "storage" - -//EXTRA - -/area/asteroid - name = "Asteroid" - icon_state = "asteroid" - requires_power = FALSE - has_gravity = STANDARD_GRAVITY - area_flags = UNIQUE_AREA | CAVES_ALLOWED | MOB_SPAWN_ALLOWED - ambientsounds = MINING - flags_1 = CAN_BE_DIRTY_1 - sound_environment = SOUND_AREA_ASTEROID - -/area/asteroid/nearstation - dynamic_lighting = DYNAMIC_LIGHTING_FORCED - ambientsounds = RUINS - always_unpowered = FALSE - requires_power = TRUE - area_flags = UNIQUE_AREA - -/area/asteroid/nearstation/bomb_site - name = "Bomb Testing Asteroid" - -//STATION13 - -//Maintenance - -/area/maintenance - ambientsounds = MAINTENANCE - lighting_colour_tube = "#ffe5cb" - lighting_colour_bulb = "#ffdbb4" - area_flags = UNIQUE_AREA - sound_environment = SOUND_AREA_TUNNEL_ENCLOSED - -//Departments - -/area/maintenance/department/chapel - name = "Chapel Maintenance" - icon_state = "maint_chapel" - -/area/maintenance/department/chapel/monastery - name = "Monastery Maintenance" - icon_state = "maint_monastery" - -/area/maintenance/department/crew_quarters/bar - name = "Bar Maintenance" - icon_state = "maint_bar" - sound_environment = SOUND_AREA_WOODFLOOR - -/area/maintenance/department/crew_quarters/dorms - name = "Dormitory Maintenance" - icon_state = "maint_dorms" - -/area/maintenance/department/eva - name = "EVA Maintenance" - icon_state = "maint_eva" - -/area/maintenance/department/electrical - name = "Electrical Maintenance" - icon_state = "maint_electrical" - -/area/maintenance/department/engine/atmos - name = "Atmospherics Maintenance" - icon_state = "maint_atmos" - -/area/maintenance/department/security - name = "Security Maintenance" - icon_state = "maint_sec" - -/area/maintenance/department/security/upper - name = "Upper Security Maintenance" - -/area/maintenance/department/security/brig - name = "Brig Maintenance" - icon_state = "maint_brig" - -/area/maintenance/department/medical - name = "Medbay Maintenance" - icon_state = "medbay_maint" - -/area/maintenance/department/medical/central - name = "Central Medbay Maintenance" - icon_state = "medbay_maint_central" - -/area/maintenance/department/medical/morgue - name = "Morgue Maintenance" - icon_state = "morgue_maint" - -/area/maintenance/department/science - name = "Science Maintenance" - icon_state = "maint_sci" - -/area/maintenance/department/science/central - name = "Central Science Maintenance" - icon_state = "maint_sci_central" - -/area/maintenance/department/cargo - name = "Cargo Maintenance" - icon_state = "maint_cargo" - -/area/maintenance/department/bridge - name = "Bridge Maintenance" - icon_state = "maint_bridge" - -/area/maintenance/department/engine - name = "Engineering Maintenance" - icon_state = "maint_engi" - -/area/maintenance/department/science/xenobiology - name = "Xenobiology Maintenance" - icon_state = "xenomaint" - area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA | XENOBIOLOGY_COMPATIBLE - - -//Maintenance - Generic - -/area/maintenance/aft - name = "Aft Maintenance" - icon_state = "amaint" - -/area/maintenance/aft/upper - name = "Upper Aft Maintenance" - -/area/maintenance/aft/secondary - name = "Aft Maintenance" - icon_state = "amaint_2" - -/area/maintenance/central - name = "Central Maintenance" - icon_state = "maintcentral" - -/area/maintenance/central/secondary - name = "Central Maintenance" - icon_state = "maintcentral" - -/area/maintenance/fore - name = "Fore Maintenance" - icon_state = "fmaint" - -/area/maintenance/fore/upper - name = "Upper Fore Maintenance" - -/area/maintenance/fore/secondary - name = "Fore Maintenance" - icon_state = "fmaint_2" - -/area/maintenance/starboard - name = "Starboard Maintenance" - icon_state = "smaint" - -/area/maintenance/starboard/upper - name = "Upper Starboard Maintenance" - -/area/maintenance/starboard/central - name = "Central Starboard Maintenance" - icon_state = "smaint" - -/area/maintenance/starboard/secondary - name = "Secondary Starboard Maintenance" - icon_state = "smaint_2" - -/area/maintenance/starboard/aft - name = "Starboard Quarter Maintenance" - icon_state = "asmaint" - -/area/maintenance/starboard/aft/secondary - name = "Secondary Starboard Quarter Maintenance" - icon_state = "asmaint_2" - -/area/maintenance/starboard/fore - name = "Starboard Bow Maintenance" - icon_state = "fsmaint" - -/area/maintenance/port - name = "Port Maintenance" - icon_state = "pmaint" - -/area/maintenance/port/central - name = "Central Port Maintenance" - icon_state = "maintcentral" - -/area/maintenance/port/aft - name = "Port Quarter Maintenance" - icon_state = "apmaint" - -/area/maintenance/port/fore - name = "Port Bow Maintenance" - icon_state = "fpmaint" - -/area/maintenance/disposal - name = "Waste Disposal" - icon_state = "disposal" - -/area/maintenance/disposal/incinerator - name = "Incinerator" - icon_state = "disposal" - - -//Hallway -/area/hallway - sound_environment = SOUND_AREA_STANDARD_STATION - -/area/hallway - lighting_colour_tube = "#ffce99" - lighting_colour_bulb = "#ffdbb4" - lighting_brightness_tube = 7 - - -/area/hallway/primary/aft - name = "Aft Primary Hallway" - icon_state = "hallA" - -/area/hallway/primary/fore - name = "Fore Primary Hallway" - icon_state = "hallF" - -/area/hallway/primary/starboard - name = "Starboard Primary Hallway" - icon_state = "hallS" - -/area/hallway/primary/port - name = "Port Primary Hallway" - icon_state = "hallP" - -/area/hallway/primary/central - name = "Central Primary Hallway" - icon_state = "hallC" - -/area/hallway/primary/upper - name = "Upper Central Primary Hallway" - icon_state = "hallC" - - -/area/hallway/secondary/command - name = "Command Hallway" - icon_state = "bridge_hallway" - -/area/hallway/secondary/construction - name = "Construction Area" - icon_state = "construction" - -/area/hallway/secondary/exit - name = "Escape Shuttle Hallway" - icon_state = "escape" - -/area/hallway/secondary/exit/departure_lounge - name = "Departure Lounge" - icon_state = "escape_lounge" - -/area/hallway/secondary/entry - name = "Arrival Shuttle Hallway" - icon_state = "entry" - -/area/hallway/secondary/service - name = "Service Hallway" - icon_state = "hall_service" - -//Command - -/area/bridge - name = "Bridge" - icon_state = "bridge" - ambientsounds = list('sound/ambience/signal.ogg') - lighting_colour_tube = "#ffce99" - lighting_colour_bulb = "#ffdbb4" - lighting_brightness_tube = 6 - sound_environment = SOUND_AREA_STANDARD_STATION - -/area/bridge/meeting_room - name = "Heads of Staff Meeting Room" - icon_state = "meeting" - sound_environment = SOUND_AREA_MEDIUM_SOFTFLOOR - -/area/bridge/meeting_room/council - name = "Council Chamber" - icon_state = "meeting" - sound_environment = SOUND_AREA_MEDIUM_SOFTFLOOR - -/area/bridge/showroom/corporate - name = "Corporate Showroom" - icon_state = "showroom" - sound_environment = SOUND_AREA_MEDIUM_SOFTFLOOR - -/area/crew_quarters/heads/captain - name = "Captain's Office" - icon_state = "captain" - sound_environment = SOUND_AREA_WOODFLOOR - -/area/crew_quarters/heads/captain/private - name = "Captain's Quarters" - icon_state = "captain" - sound_environment = SOUND_AREA_WOODFLOOR - -/area/crew_quarters/heads/chief - name = "Chief Engineer's Office" - icon_state = "ce_office" - -/area/crew_quarters/heads/cmo - name = "Chief Medical Officer's Office" - icon_state = "cmo_office" - -/area/crew_quarters/heads/head_of_personnel - name = "Head of Personnel's Office" - icon_state = "hop_office" - -/area/crew_quarters/heads/hos - name = "Head of Security's Office" - icon_state = "hos_office" - -/area/crew_quarters/heads/hor - name = "Research Director's Office" - icon_state = "rd_office" - -/area/comms - name = "Communications Relay" - icon_state = "tcomsatcham" - lighting_colour_tube = "#e2feff" - lighting_colour_bulb = "#d5fcff" - sound_environment = SOUND_AREA_STANDARD_STATION - -/area/server - name = "Messaging Server Room" - icon_state = "server" - sound_environment = SOUND_AREA_STANDARD_STATION - -//Crew - -/area/crew_quarters - lighting_colour_tube = "#ffce99" - lighting_colour_bulb = "#ffdbb4" - lighting_brightness_tube = 6 - sound_environment = SOUND_AREA_STANDARD_STATION - -/area/crew_quarters/dorms - name = "Dormitories" - icon_state = "Sleep" - area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA - -/area/crew_quarters/dorms/barracks - name = "Sleep Barracks" - -/area/crew_quarters/dorms/barracks/male - name = "Male Sleep Barracks" - -/area/crew_quarters/dorms/barracks/female - name = "Female Sleep Barracks" - -/area/crew_quarters/toilet - name = "Dormitory Toilets" - icon_state = "toilet" - lighting_colour_tube = "#e3ffff" - lighting_colour_bulb = "#d5ffff" - sound_environment = SOUND_AREA_SMALL_ENCLOSED - -/area/crew_quarters/toilet/auxiliary - name = "Auxiliary Restrooms" - icon_state = "toilet" - -/area/crew_quarters/toilet/locker - name = "Locker Toilets" - icon_state = "toilet" - -/area/crew_quarters/toilet/restrooms - name = "Restrooms" - icon_state = "toilet" - -/area/crew_quarters/locker - name = "Locker Room" - icon_state = "locker" - -/area/crew_quarters/lounge - name = "Lounge" - icon_state = "yellow" - sound_environment = SOUND_AREA_SMALL_SOFTFLOOR - -/area/crew_quarters/fitness - name = "Fitness Room" - icon_state = "fitness" - -/area/crew_quarters/fitness/locker_room - name = "Unisex Locker Room" - icon_state = "fitness" - -/area/crew_quarters/fitness/locker_room/male - name = "Male Locker Room" - -/area/crew_quarters/fitness/locker_room/female - name = "Female Locker Room" - - -/area/crew_quarters/fitness/recreation - name = "Recreation Area" - icon_state = "fitness" - -/area/crew_quarters/cafeteria - name = "Cafeteria" - icon_state = "cafeteria" - -/area/crew_quarters/kitchen - name = "Kitchen" - icon_state = "kitchen" - lighting_colour_tube = "#e3ffff" - lighting_colour_bulb = "#d5ffff" - -/area/crew_quarters/kitchen/coldroom - name = "Kitchen Cold Room" - icon_state = "kitchen_cold" - sound_environment = SOUND_AREA_SMALL_ENCLOSED - -/area/crew_quarters/bar - name = "Bar" - icon_state = "bar" - mood_bonus = 5 - mood_message = "I love being in the bar!\n" - lighting_colour_tube = "#fff4d6" - lighting_colour_bulb = "#ffebc1" - sound_environment = SOUND_AREA_WOODFLOOR - -/area/crew_quarters/bar/atrium - name = "Atrium" - icon_state = "bar" - sound_environment = SOUND_AREA_WOODFLOOR - -/area/crew_quarters/electronic_marketing_den - name = "Electronic Marketing Den" - icon_state = "bar" - -/area/crew_quarters/abandoned_gambling_den - name = "Abandoned Gambling Den" - icon_state = "abandoned_g_den" - -/area/crew_quarters/abandoned_gambling_den/secondary - icon_state = "abandoned_g_den_2" - -/area/crew_quarters/theatre - name = "Theatre" - icon_state = "Theatre" - sound_environment = SOUND_AREA_WOODFLOOR - -/area/crew_quarters/theatre/abandoned - name = "Abandoned Theatre" - icon_state = "Theatre" - -/area/library - name = "Library" - icon_state = "library" - flags_1 = CULT_PERMITTED_1 - lighting_colour_tube = "#ffce99" - lighting_colour_bulb = "#ffdbb4" - sound_environment = SOUND_AREA_LARGE_SOFTFLOOR - -/area/library/lounge - name = "Library Lounge" - icon_state = "library" - sound_environment = SOUND_AREA_LARGE_SOFTFLOOR - -/area/library/artgallery - name = " Art Gallery" - icon_state = "library" - -/area/library/private - name = "Library Private Study" - icon_state = "library" - -/area/library/upper - name = "Library Upper Floor" - icon_state = "library" - -/area/library/printer - name = "Library Printer Room" - icon_state = "library" - -/area/library/abandoned - name = "Abandoned Library" - icon_state = "library" - flags_1 = CULT_PERMITTED_1 - -/area/chapel - icon_state = "chapel" - ambientsounds = HOLY - flags_1 = NONE - sound_environment = SOUND_AREA_LARGE_ENCLOSED - -/area/chapel/main - name = "Chapel" - -/area/chapel/main/monastery - name = "Monastery" - -/area/chapel/office - name = "Chapel Office" - icon_state = "chapeloffice" - -/area/chapel/asteroid - name = "Chapel Asteroid" - icon_state = "explored" - sound_environment = SOUND_AREA_ASTEROID - -/area/chapel/asteroid/monastery - name = "Monastery Asteroid" - -/area/chapel/dock - name = "Chapel Dock" - icon_state = "construction" - -/area/lawoffice - name = "Law Office" - icon_state = "law" - sound_environment = SOUND_AREA_SMALL_SOFTFLOOR - - -//Engineering - -/area/engine - ambientsounds = ENGINEERING - lighting_colour_tube = "#ffce93" - lighting_colour_bulb = "#ffbc6f" - sound_environment = SOUND_AREA_LARGE_ENCLOSED - -/area/engine/engine_smes - name = "Engineering SMES" - icon_state = "engine_smes" - -/area/engine/engineering - name = "Engineering" - icon_state = "engine" - -/area/engine/atmos - name = "Atmospherics" - icon_state = "atmos" - flags_1 = CULT_PERMITTED_1 - -/area/engine/atmos/upper - name = "Upper Atmospherics" - -/area/engine/atmospherics_engine - name = "Atmospherics Engine" - icon_state = "atmos_engine" - area_flags = BLOBS_ALLOWED | UNIQUE_AREA - sound_environment = SOUND_AREA_LARGE_ENCLOSED - -/area/engine/engine_room //donut station specific - name = "Engine Room" - icon_state = "atmos_engine" - -/area/engine/lobby - name = "Engineering Lobby" - icon_state = "engi_lobby" - -/area/engine/engine_room/external - name = "Supermatter External Access" - icon_state = "engine_foyer" - -/area/engine/supermatter - name = "Supermatter Engine" - icon_state = "engine_sm" - area_flags = BLOBS_ALLOWED | UNIQUE_AREA - sound_environment = SOUND_AREA_SMALL_ENCLOSED - -/area/engine/break_room - name = "Engineering Foyer" - icon_state = "engine_foyer" - sound_environment = SOUND_AREA_SMALL_ENCLOSED - -/area/engine/gravity_generator - name = "Gravity Generator Room" - icon_state = "grav_gen" - -/area/engine/storage - name = "Engineering Storage" - icon_state = "engi_storage" - sound_environment = SOUND_AREA_SMALL_ENCLOSED - -/area/engine/storage_shared - name = "Shared Engineering Storage" - icon_state = "engi_storage" - -/area/engine/transit_tube - name = "Transit Tube" - icon_state = "transit_tube" - - -//Solars - -/area/solar - requires_power = FALSE - dynamic_lighting = DYNAMIC_LIGHTING_IFSTARLIGHT - area_flags = UNIQUE_AREA - flags_1 = NONE - ambientsounds = ENGINEERING - sound_environment = SOUND_AREA_SPACE - -/area/solar/fore - name = "Fore Solar Array" - icon_state = "yellow" - sound_environment = SOUND_AREA_STANDARD_STATION - -/area/solar/aft - name = "Aft Solar Array" - icon_state = "yellow" - -/area/solar/aux/port - name = "Port Bow Auxiliary Solar Array" - icon_state = "panelsA" - -/area/solar/aux/starboard - name = "Starboard Bow Auxiliary Solar Array" - icon_state = "panelsA" - -/area/solar/starboard - name = "Starboard Solar Array" - icon_state = "panelsS" - -/area/solar/starboard/aft - name = "Starboard Quarter Solar Array" - icon_state = "panelsAS" - -/area/solar/starboard/fore - name = "Starboard Bow Solar Array" - icon_state = "panelsFS" - -/area/solar/port - name = "Port Solar Array" - icon_state = "panelsP" - -/area/solar/port/aft - name = "Port Quarter Solar Array" - icon_state = "panelsAP" - -/area/solar/port/fore - name = "Port Bow Solar Array" - icon_state = "panelsFP" - -/area/solar/aisat - name = "AI Satellite Solars" - icon_state = "yellow" - - -//Solar Maint - -/area/maintenance/solars - name = "Solar Maintenance" - icon_state = "yellow" - -/area/maintenance/solars/port - name = "Port Solar Maintenance" - icon_state = "SolarcontrolP" - -/area/maintenance/solars/port/aft - name = "Port Quarter Solar Maintenance" - icon_state = "SolarcontrolAP" - -/area/maintenance/solars/port/fore - name = "Port Bow Solar Maintenance" - icon_state = "SolarcontrolFP" - -/area/maintenance/solars/starboard - name = "Starboard Solar Maintenance" - icon_state = "SolarcontrolS" - -/area/maintenance/solars/starboard/aft - name = "Starboard Quarter Solar Maintenance" - icon_state = "SolarcontrolAS" - -/area/maintenance/solars/starboard/fore - name = "Starboard Bow Solar Maintenance" - icon_state = "SolarcontrolFS" - -//Teleporter - -/area/teleporter - name = "Teleporter Room" - icon_state = "teleporter" - ambientsounds = ENGINEERING - -/area/gateway - name = "Gateway" - icon_state = "gateway" - ambientsounds = ENGINEERING - sound_environment = SOUND_AREA_STANDARD_STATION - -//MedBay - -/area/medical - name = "Medical" - icon_state = "medbay3" - ambientsounds = MEDICAL - lighting_colour_tube = "#e7f8ff" - lighting_colour_bulb = "#d5f2ff" - sound_environment = SOUND_AREA_STANDARD_STATION - -/area/medical/abandoned - name = "Abandoned Medbay" - icon_state = "medbay3" - ambientsounds = list('sound/ambience/signal.ogg') - sound_environment = SOUND_AREA_SMALL_ENCLOSED - -/area/medical/medbay/central - name = "Medbay Central" - icon_state = "medbay" - -/area/medical/medbay/lobby - name = "Medbay Lobby" - icon_state = "medbay" - - //Medbay is a large area, these additional areas help level out APC load. - -/area/medical/medbay/zone2 - name = "Medbay" - icon_state = "medbay2" - -/area/medical/medbay/aft - name = "Medbay Aft" - icon_state = "medbay3" - -/area/medical/storage - name = "Medbay Storage" - icon_state = "medbay2" - -/area/medical/paramedic - name = "Paramedic Dispatch" - icon_state = "medbay2" - -/area/medical/office - name = "Medical Office" - icon_state = "medoffice" - -/area/medical/surgery/room_c - name = "Surgery C" - icon_state = "surgery" - -/area/medical/surgery/room_d - name = "Surgery D" - icon_state = "surgery" - -/area/medical/break_room - name = "Medical Break Room" - icon_state = "medbay2" - -/area/medical/coldroom - name = "Medical Cold Room" - icon_state = "kitchen_cold" - -/area/medical/patients_rooms - name = "Patients' Rooms" - icon_state = "patients" - sound_environment = SOUND_AREA_SMALL_SOFTFLOOR - -/area/medical/patients_rooms/room_a - name = "Patient Room A" - icon_state = "patients" - -/area/medical/patients_rooms/room_b - name = "Patient Room B" - icon_state = "patients" - -/area/medical/virology - name = "Virology" - icon_state = "virology" - flags_1 = CULT_PERMITTED_1 - -/area/medical/morgue - name = "Morgue" - icon_state = "morgue" - ambientsounds = SPOOKY - sound_environment = SOUND_AREA_SMALL_ENCLOSED - -/area/medical/chemistry - name = "Chemistry" - icon_state = "chem" - -/area/medical/pharmacy - name = "Pharmacy" - icon_state = "pharmacy" - -/area/medical/surgery - name = "Surgery" - icon_state = "surgery" - -/area/medical/surgery/room_b - name = "Surgery B" - icon_state = "surgery" - -/area/medical/cryo - name = "Cryogenics" - icon_state = "cryo" - -/area/medical/exam_room - name = "Exam Room" - icon_state = "exam_room" - -/area/medical/genetics - name = "Genetics Lab" - icon_state = "genetics" - -/area/medical/sleeper - name = "Medbay Treatment Center" - icon_state = "exam_room" - -/area/medical/psychology - name = "Psychology Office" - icon_state = "psychology" - mood_bonus = 3 - mood_message = "I feel at ease here.\n" - ambientsounds = list('sound/ambience/aurora_caelus_short.ogg') - -//Security - -/area/security - name = "Security" - icon_state = "security" - ambientsounds = HIGHSEC - lighting_colour_tube = "#ffeee2" - lighting_colour_bulb = "#ffdfca" - sound_environment = SOUND_AREA_STANDARD_STATION - -/area/security/main - name = "Security Office" - icon_state = "security" - -/area/security/brig - name = "Brig" - icon_state = "brig" - -/area/security/brig/upper - name = "Brig Overlook" - -/area/security/courtroom - name = "Courtroom" - icon_state = "courtroom" - sound_environment = SOUND_AREA_LARGE_ENCLOSED - -/area/security/prison - name = "Prison Wing" - icon_state = "sec_prison" - -/area/security/prison/toilet //radproof - name = "Prison Toilet" - icon_state = "sec_prison_safe" - -/area/security/prison/safe //radproof - name = "Prison Wing Cells" - icon_state = "sec_prison_safe" - -/area/security/prison/upper - name = "Upper Prison Wing" - icon_state = "prison_upper" - -/area/security/prison/visit - name = "Prison Visitation Area" - icon_state = "prison_visit" - -/area/security/prison/rec - name = "Prison Rec Room" - icon_state = "prison_rec" - -/area/security/prison/mess - name = "Prison Mess Hall" - icon_state = "prison_mess" - -/area/security/prison/work - name = "Prison Work Room" - icon_state = "prison_work" - -/area/security/prison/shower - name = "Prison Shower" - icon_state = "prison_shower" - -/area/security/prison/workout - name = "Prison Gym" - icon_state = "prison_workout" - -/area/security/prison/garden - name = "Prison Garden" - icon_state = "prison_garden" - -/area/security/processing - name = "Labor Shuttle Dock" - icon_state = "sec_prison" - -/area/security/processing/cremation - name = "Security Crematorium" - icon_state = "sec_prison" - sound_environment = SOUND_AREA_SMALL_ENCLOSED - -/area/security/warden - name = "Brig Control" - icon_state = "Warden" - sound_environment = SOUND_AREA_SMALL_SOFTFLOOR - -/area/security/detectives_office - name = "Detective's Office" - icon_state = "detective" - ambientsounds = list('sound/ambience/ambidet1.ogg','sound/ambience/ambidet2.ogg') - -/area/security/detectives_office/private_investigators_office - name = "Private Investigator's Office" - icon_state = "detective" - sound_environment = SOUND_AREA_SMALL_SOFTFLOOR - -/area/security/range - name = "Firing Range" - icon_state = "firingrange" - -/area/security/execution - icon_state = "execution_room" - -/area/security/execution/transfer - name = "Transfer Centre" - -/area/security/execution/education - name = "Prisoner Education Chamber" - -/area/security/nuke_storage - name = "Vault" - icon_state = "nuke_storage" - -/area/ai_monitored/nuke_storage - name = "Vault" - icon_state = "nuke_storage" - -/area/security/checkpoint - name = "Security Checkpoint" - icon_state = "checkpoint1" - -/area/security/checkpoint/auxiliary - icon_state = "checkpoint_aux" - -/area/security/checkpoint/escape - icon_state = "checkpoint_esc" - -/area/security/checkpoint/supply - name = "Security Post - Cargo Bay" - icon_state = "checkpoint_supp" - -/area/security/checkpoint/engineering - name = "Security Post - Engineering" - icon_state = "checkpoint_engi" - -/area/security/checkpoint/medical - name = "Security Post - Medbay" - icon_state = "checkpoint_med" - -/area/security/checkpoint/science - name = "Security Post - Science" - icon_state = "checkpoint_sci" - -/area/security/checkpoint/science/research - name = "Security Post - Research Division" - icon_state = "checkpoint_res" - -/area/security/checkpoint/customs - name = "Customs" - icon_state = "customs_point" - -/area/security/checkpoint/customs/auxiliary - icon_state = "customs_point_aux" - - -//Service - -/area/quartermaster - name = "Quartermasters" - icon_state = "quart" - lighting_colour_tube = "#ffe3cc" - lighting_colour_bulb = "#ffdbb8" - sound_environment = SOUND_AREA_STANDARD_STATION - -/area/quartermaster/sorting - name = "Delivery Office" - icon_state = "cargo_delivery" - sound_environment = SOUND_AREA_STANDARD_STATION - -/area/quartermaster/warehouse - name = "Warehouse" - icon_state = "cargo_warehouse" - sound_environment = SOUND_AREA_LARGE_ENCLOSED - -/area/quartermaster/warehouse/upper - name = "Upper Warehouse" - -/area/quartermaster/office - name = "Cargo Office" - icon_state = "quartoffice" - -/area/quartermaster/storage - name = "Cargo Bay" - icon_state = "cargo_bay" - sound_environment = SOUND_AREA_LARGE_ENCLOSED - -/area/quartermaster/qm - name = "Quartermaster's Office" - icon_state = "quart" - -/area/quartermaster/qm/perch - name = "Quartermaster's Perch" - icon_state = "quartperch" - -/area/quartermaster/miningdock - name = "Mining Dock" - icon_state = "mining" - -/area/quartermaster/miningoffice - name = "Mining Office" - icon_state = "mining" - -/area/janitor - name = "Custodial Closet" - icon_state = "janitor" - flags_1 = CULT_PERMITTED_1 - sound_environment = SOUND_AREA_SMALL_ENCLOSED - -/area/hydroponics - name = "Hydroponics" - icon_state = "hydro" - sound_environment = SOUND_AREA_STANDARD_STATION - -/area/hydroponics/upper - name = "Upper Hydroponics" - icon_state = "hydro" - -/area/hydroponics/garden - name = "Garden" - icon_state = "garden" - -/area/hydroponics/garden/abandoned - name = "Abandoned Garden" - icon_state = "abandoned_garden" - sound_environment = SOUND_AREA_SMALL_ENCLOSED - -/area/hydroponics/garden/monastery - name = "Monastery Garden" - icon_state = "hydro" - - -//Science - -/area/science - name = "Science Division" - icon_state = "toxlab" - lighting_colour_tube = "#f0fbff" - lighting_colour_bulb = "#e4f7ff" - sound_environment = SOUND_AREA_STANDARD_STATION - -/area/science/lab - name = "Research and Development" - icon_state = "toxlab" - -/area/science/xenobiology - name = "Xenobiology Lab" - icon_state = "toxlab" - -/area/science/storage - name = "Toxins Storage" - icon_state = "toxstorage" - -/area/science/test_area - name = "Toxins Test Area" - icon_state = "toxtest" - area_flags = BLOBS_ALLOWED | UNIQUE_AREA - -/area/science/mixing - name = "Toxins Mixing Lab" - icon_state = "toxmix" - -/area/science/mixing/chamber - name = "Toxins Mixing Chamber" - icon_state = "toxmix" - area_flags = BLOBS_ALLOWED | UNIQUE_AREA - -/area/science/misc_lab - name = "Testing Lab" - icon_state = "toxmisc" - -/area/science/misc_lab/range - name = "Research Testing Range" - icon_state = "toxmisc" - -/area/science/server - name = "Research Division Server Room" - icon_state = "server" - -/area/science/explab - name = "Experimentation Lab" - icon_state = "toxmisc" - -/area/science/robotics - name = "Robotics" - icon_state = "medresearch" - -/area/science/robotics/mechbay - name = "Mech Bay" - icon_state = "mechbay" - -/area/science/robotics/lab - name = "Robotics Lab" - icon_state = "ass_line" - -/area/science/research - name = "Research Division" - icon_state = "medresearch" - -/area/science/research/abandoned - name = "Abandoned Research Lab" - icon_state = "medresearch" - sound_environment = SOUND_AREA_SMALL_ENCLOSED - -/area/science/nanite - name = "Nanite Lab" - icon_state = "toxmisc" - -//Storage -/area/storage - sound_environment = SOUND_AREA_STANDARD_STATION - -/area/storage/tools - name = "Auxiliary Tool Storage" - icon_state = "storage" - -/area/storage/primary - name = "Primary Tool Storage" - icon_state = "primarystorage" - -/area/storage/art - name = "Art Supply Storage" - icon_state = "storage" - -/area/storage/tcom - name = "Telecomms Storage" - icon_state = "green" - area_flags = BLOBS_ALLOWED | UNIQUE_AREA - -/area/storage/eva - name = "EVA Storage" - icon_state = "eva" - -/area/storage/emergency/starboard - name = "Starboard Emergency Storage" - icon_state = "emergencystorage" - -/area/storage/emergency/port - name = "Port Emergency Storage" - icon_state = "emergencystorage" - -/area/storage/tech - name = "Technical Storage" - icon_state = "auxstorage" - -//Construction - -/area/construction - name = "Construction Area" - icon_state = "yellow" - ambientsounds = ENGINEERING - sound_environment = SOUND_AREA_STANDARD_STATION - -/area/construction/mining/aux_base - name = "Auxiliary Base Construction" - icon_state = "aux_base_construction" - sound_environment = SOUND_AREA_MEDIUM_SOFTFLOOR - -/area/construction/storage_wing - name = "Storage Wing" - icon_state = "storage_wing" - -// Vacant Rooms -/area/vacant_room - name = "Vacant Room" - icon_state = "vacant_room" - ambientsounds = MAINTENANCE - -/area/vacant_room/office - name = "Vacant Office" - icon_state = "vacant_office" - -/area/vacant_room/commissary - name = "Vacant Commissary" - icon_state = "vacant_commissary" - -//AI - -/area/ai_monitored - sound_environment = SOUND_AREA_STANDARD_STATION - -/area/ai_monitored/security/armory - name = "Armory" - icon_state = "armory" - ambientsounds = HIGHSEC - -/area/ai_monitored/security/armory/upper - name = "Upper Armory" - -/area/ai_monitored/storage/eva - name = "EVA Storage" - icon_state = "eva" - ambientsounds = HIGHSEC - -/area/ai_monitored/storage/eva/upper - name = "Upper EVA Storage" - -/area/ai_monitored/storage/satellite - name = "AI Satellite Maint" - icon_state = "storage" - ambientsounds = HIGHSEC - - //Turret_protected - -/area/ai_monitored/turret_protected - ambientsounds = list('sound/ambience/ambimalf.ogg', 'sound/ambience/ambitech.ogg', 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambiatmos.ogg', 'sound/ambience/ambiatmos2.ogg') - -/area/ai_monitored/turret_protected/ai_upload - name = "AI Upload Chamber" - icon_state = "ai_upload" - sound_environment = SOUND_AREA_SMALL_ENCLOSED - -/area/ai_monitored/turret_protected/ai_upload_foyer - name = "AI Upload Access" - icon_state = "ai_foyer" - sound_environment = SOUND_AREA_SMALL_ENCLOSED - -/area/ai_monitored/turret_protected/ai - name = "AI Chamber" - icon_state = "ai_chamber" - -/area/ai_monitored/turret_protected/aisat - name = "AI Satellite" - icon_state = "ai" - sound_environment = SOUND_ENVIRONMENT_ROOM - -/area/ai_monitored/turret_protected/aisat/atmos - name = "AI Satellite Atmos" - icon_state = "ai" - -/area/ai_monitored/turret_protected/aisat/foyer - name = "AI Satellite Foyer" - icon_state = "ai" - -/area/ai_monitored/turret_protected/aisat/service - name = "AI Satellite Service" - icon_state = "ai" - -/area/ai_monitored/turret_protected/aisat/hallway - name = "AI Satellite Hallway" - icon_state = "ai" - -/area/aisat - name = "AI Satellite Exterior" - icon_state = "yellow" - -/area/ai_monitored/turret_protected/aisat_interior - name = "AI Satellite Antechamber" - icon_state = "ai" - sound_environment = SOUND_AREA_LARGE_ENCLOSED - -/area/ai_monitored/turret_protected/AIsatextAS - name = "AI Sat Ext" - icon_state = "storage" - -/area/ai_monitored/turret_protected/AIsatextAP - name = "AI Sat Ext" - icon_state = "storage" - - -// Telecommunications Satellite - -/area/tcommsat - ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg', 'sound/ambience/ambitech.ogg',\ - 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambitech3.ogg', 'sound/ambience/ambimystery.ogg') - -/area/tcommsat/computer - name = "Telecomms Control Room" - icon_state = "tcomsatcomp" - sound_environment = SOUND_AREA_MEDIUM_SOFTFLOOR - -/area/tcommsat/server - name = "Telecomms Server Room" - icon_state = "tcomsatcham" - -/area/tcommsat/server/upper - name = "Upper Telecomms Server Room" - -//External Hull Access -/area/maintenance/external - name = "External Hull Access" - icon_state = "amaint" - -/area/maintenance/external/aft - name = "Aft External Hull Access" - -/area/maintenance/external/port - name = "Port External Hull Access" - -/area/maintenance/external/port/bow - name = "Port Bow External Hull Access" - -Shiptest End */ diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 9c0ecb225c41..bc2f62f99e0c 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -113,7 +113,7 @@ GLOBAL_LIST_EMPTY(teleportlocs) /proc/process_teleport_locs() for(var/V in GLOB.sortedAreas) var/area/AR = V - if(istype(AR, /area/shuttle) || AR.area_flags & NOTELEPORT) + if(AR.area_flags & NOTELEPORT) continue if(GLOB.teleportlocs[AR.name]) continue diff --git a/code/game/area/areas/shuttles.dm b/code/game/area/areas/shuttles.dm deleted file mode 100644 index 625129ae236f..000000000000 --- a/code/game/area/areas/shuttles.dm +++ /dev/null @@ -1,185 +0,0 @@ - -//These are shuttle areas; all subtypes are only used as teleportation markers, they have no actual function beyond that. -//Multi area shuttles are a thing now, use subtypes! ~ninjanomnom - -/area/shuttle - name = "Shuttle" - requires_power = FALSE - dynamic_lighting = DYNAMIC_LIGHTING_FORCED - has_gravity = STANDARD_GRAVITY - always_unpowered = FALSE - // Loading the same shuttle map at a different time will produce distinct area instances. - area_flags = NONE - icon_state = "shuttle" - flags_1 = CAN_BE_DIRTY_1 - lighting_colour_tube = "#fff0dd" - lighting_colour_bulb = "#ffe1c1" - area_limited_icon_smoothing = TRUE - sound_environment = SOUND_ENVIRONMENT_ROOM - //The mobile port attached to this area - var/obj/docking_port/mobile/mobile_port - - -/area/shuttle/Destroy() - mobile_port = null - . = ..() - -/area/shuttle/PlaceOnTopReact(turf/T, list/new_baseturfs, turf/fake_turf_type, flags) - . = ..() - if(length(new_baseturfs) > 1 || fake_turf_type) - return // More complicated larger changes indicate this isn't a player - if(ispath(new_baseturfs[1], /turf/open/floor/plating) && !(/turf/baseturf_skipover/shuttle in new_baseturfs)) - new_baseturfs.Insert(1, /turf/baseturf_skipover/shuttle) - -/area/shuttle/proc/link_to_shuttle(obj/docking_port/mobile/M) - mobile_port = M - -////////////////////////////Multi-area shuttles//////////////////////////// - -////////////////////////////Syndicate infiltrator//////////////////////////// - -/area/shuttle/syndicate - name = "Syndicate Infiltrator" - ambientsounds = HIGHSEC - -/area/shuttle/syndicate/bridge - name = "Syndicate Infiltrator Control" - -/area/shuttle/syndicate/medical - name = "Syndicate Infiltrator Medbay" - -/area/shuttle/syndicate/armory - name = "Syndicate Infiltrator Armory" - -/area/shuttle/syndicate/eva - name = "Syndicate Infiltrator EVA" - -/area/shuttle/syndicate/hallway - -/area/shuttle/syndicate/airlock - name = "Syndicate Infiltrator Airlock" - -////////////////////////////Pirate Shuttle//////////////////////////// - -/area/shuttle/pirate - name = "Pirate Shuttle" - requires_power = TRUE - -////////////////////////////Bounty Hunter Shuttles//////////////////////////// - -/area/shuttle/hunter - name = "Hunter Shuttle" - dynamic_lighting = DYNAMIC_LIGHTING_DISABLED - -////////////////////////////White Ship//////////////////////////// - -/area/shuttle/abandoned - name = "Abandoned Ship" - requires_power = TRUE - -/area/shuttle/abandoned/bridge - name = "Abandoned Ship Bridge" - -/area/shuttle/abandoned/engine - name = "Abandoned Ship Engine" - -/area/shuttle/abandoned/bar - name = "Abandoned Ship Bar" - -/area/shuttle/abandoned/crew - name = "Abandoned Ship Crew Quarters" - -/area/shuttle/abandoned/cargo - name = "Abandoned Ship Cargo Bay" - -/area/shuttle/abandoned/medbay - name = "Abandoned Ship Medbay" - -/area/shuttle/abandoned/pod - name = "Abandoned Ship Pod" - -/area/shuttle/abandoned/atmospherics - name = "Abandoned Ship atmospherics"//WS station edit - -/area/shuttle/abandoned/coridor - name = "Abandoned Ship coridor"//WS station edit -////////////////////////////Single-area shuttles//////////////////////////// - -/area/shuttle/transit - name = "Hyperspace" - desc = "Weeeeee" - dynamic_lighting = DYNAMIC_LIGHTING_DISABLED - -/area/shuttle/custom - name = "Custom player shuttle" - flags_1 = CAN_BE_DIRTY_1 - -/area/shuttle/custom/powered - name = "Custom Powered player shuttle" - requires_power = FALSE - -/area/shuttle/arrival - name = "Arrival Shuttle" - area_flags = UNIQUE_AREA// SSjob refers to this area for latejoiners - -/area/shuttle/pod_1 - name = "Escape Pod One" - -/area/shuttle/pod_2 - name = "Escape Pod Two" - -/area/shuttle/pod_3 - name = "Escape Pod Three" - -/area/shuttle/pod_4 - name = "Escape Pod Four" - -/area/shuttle/mining - name = "Mining Shuttle" - -/area/shuttle/mining/large - name = "Mining Shuttle" - requires_power = TRUE - -/area/shuttle/labor - name = "Labor Camp Shuttle" - -/area/shuttle/supply - name = "Supply Shuttle" - area_flags = NOTELEPORT - -/area/shuttle/escape - name = "Emergency Shuttle" - flags_1 = CAN_BE_DIRTY_1 - -/area/shuttle/escape/backup - name = "Backup Emergency Shuttle" - -/area/shuttle/escape/luxury - name = "Luxurious Emergency Shuttle" - area_flags = NOTELEPORT - -/area/shuttle/escape/arena - name = "The Arena" - area_flags = NOTELEPORT - -/area/shuttle/escape/meteor - name = "\proper a meteor with engines strapped to it" - -/area/shuttle/transport - name = "Transport Shuttle" - -/area/shuttle/sbc_starfury - name = "SBC Starfury" - -/area/shuttle/sbc_fighter1 - name = "SBC Fighter 1" - -/area/shuttle/sbc_fighter2 - name = "SBC Fighter 2" - -/area/shuttle/sbc_corvette - name = "SBC corvette" - -/area/shuttle/syndicate_scout - name = "Syndicate Scout" diff --git a/code/game/area/ship_areas.dm b/code/game/area/ship_areas.dm index 54d74fc9538a..b1d47670aa2d 100644 --- a/code/game/area/ship_areas.dm +++ b/code/game/area/ship_areas.dm @@ -46,6 +46,20 @@ NOTE: there are two lists of areas in the end of this file: centcom and station name = "Test Room" icon_state = "storage" +/area/hyperspace + icon_state = "space" + requires_power = TRUE + always_unpowered = TRUE + dynamic_lighting = DYNAMIC_LIGHTING_DISABLED + power_light = FALSE + power_equip = FALSE + power_environ = FALSE + area_flags = UNIQUE_AREA | CAVES_ALLOWED | MOB_SPAWN_ALLOWED + outdoors = TRUE + ambientsounds = SPACE + flags_1 = CAN_BE_DIRTY_1 + sound_environment = SOUND_AREA_SPACE + //EXTRA /area/asteroid diff --git a/code/game/atoms.dm b/code/game/atoms.dm index a140ec099085..e7c9c19325a6 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -353,66 +353,6 @@ return TRUE return !density -/** - * Is this atom currently located on centcom - * - * Specifically, is it on the z level and within the centcom areas - * - * You can also be in a shuttleshuttle during endgame transit - * - * Used in gamemode to identify mobs who have escaped and for some other areas of the code - * who don't want atoms where they shouldn't be - */ -/atom/proc/onCentCom() - var/turf/T = get_turf(src) - if(!T) - return FALSE - - if(is_reserved_level(T)) - for(var/A in SSshuttle.mobile) - var/obj/docking_port/mobile/M = A - if(M.launch_status == ENDGAME_TRANSIT) - for(var/place in M.shuttle_areas) - var/area/shuttle/shuttle_area = place - if(T in shuttle_area) - return TRUE - - if(!is_centcom_level(T))//if not, don't bother - return FALSE - - //Check for centcom itself - if(istype(T.loc, /area/centcom)) - return TRUE - - //Check for centcom shuttles - for(var/A in SSshuttle.mobile) - var/obj/docking_port/mobile/M = A - if(M.launch_status == ENDGAME_LAUNCHED) - for(var/place in M.shuttle_areas) - var/area/shuttle/shuttle_area = place - if(T in shuttle_area) - return TRUE - -/** - * Is the atom in any of the centcom syndicate areas - * - * Either in the syndie base on centcom, or any of their shuttles - * - * Also used in gamemode code for win conditions - */ -/atom/proc/onSyndieBase() - var/turf/T = get_turf(src) - if(!T) - return FALSE - - if(!is_centcom_level(T))//if not, don't bother - return FALSE - - if(istype(T.loc, /area/shuttle/syndicate) || istype(T.loc, /area/syndicate_mothership)) - return TRUE - - return FALSE - /** * Is the atom in an away mission * diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm deleted file mode 100644 index f7ce7b036eb5..000000000000 --- a/code/game/gamemodes/cult/cult.dm +++ /dev/null @@ -1,182 +0,0 @@ -#define CULT_SCALING_COEFFICIENT 9.3 //Roughly one new cultist at roundstart per this many players - -/datum/game_mode - var/list/datum/mind/cult = list() - -/proc/iscultist(mob/living/M) - return M.mind?.has_antag_datum(/datum/antagonist/cult) - -/datum/team/cult/proc/is_sacrifice_target(datum/mind/mind) - for(var/datum/objective/sacrifice/sac_objective in objectives) - if(mind == sac_objective.target) - return TRUE - return FALSE - -/proc/is_convertable_to_cult(mob/living/M,datum/team/cult/specific_cult) - if(!istype(M)) - return FALSE - if(M.mind) - if(specific_cult && specific_cult.is_sacrifice_target(M.mind)) - return FALSE - if(M.mind.enslaved_to && !iscultist(M.mind.enslaved_to)) - return FALSE - if(M.mind.unconvertable) - return FALSE - else - return FALSE - if(HAS_TRAIT(M, TRAIT_MINDSHIELD) || issilicon(M) || isbot(M) || isdrone(M) || !M.client) - return FALSE //can't convert machines, shielded, or braindead - return TRUE - -/datum/game_mode/cult - name = "cult" - config_tag = "cult" - report_type = "cult" - antag_flag = ROLE_CULTIST - false_report_weight = 10 - restricted_jobs = list("Chaplain","AI", "Cyborg", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Brig Physician", "SolGov Representative", "Prisoner") //WS edit - Brig Physicians, SolGov Rep - protected_jobs = list() - required_players = 29 - 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\ - Cultists: Carry out Nar'Sie's will.\n\ - Crew: Prevent the cult from expanding and drive it out." - - title_icon = "cult" - - var/finished = 0 - - var/acolytes_needed = 10 //for the survive objective - var/acolytes_survived = 0 - - var/list/cultists_to_cult = list() //the cultists we'll convert - - var/datum/team/cult/main_cult - - -/datum/game_mode/cult/pre_setup() - if(CONFIG_GET(flag/protect_roles_from_antagonist)) - restricted_jobs += protected_jobs - - if(CONFIG_GET(flag/protect_assistant_from_antagonist)) - restricted_jobs += "Assistant" - - //cult scaling goes here - recommended_enemies = 1 + round(num_players()/CULT_SCALING_COEFFICIENT) - var/remaining = (num_players() % CULT_SCALING_COEFFICIENT) * 10 //Basically the % of how close the population is toward adding another cultis - if(prob(remaining)) - recommended_enemies++ - - - for(var/cultists_number = 1 to recommended_enemies) - if(!antag_candidates.len) - break - var/datum/mind/cultist = antag_pick(antag_candidates) - antag_candidates -= cultist - cultists_to_cult += cultist - cultist.special_role = ROLE_CULTIST - cultist.restricted_roles = restricted_jobs - log_game("[key_name(cultist)] has been selected as a cultist") - - if(cultists_to_cult.len>=required_enemies) - for(var/antag in cultists_to_cult) - GLOB.pre_setup_antags += antag - return TRUE - else - setup_error = "Not enough cultist candidates" - return FALSE - - -/datum/game_mode/cult/post_setup() - main_cult = new - - for(var/datum/mind/cult_mind in cultists_to_cult) - add_cultist(cult_mind, 0, equip=TRUE, cult_team = main_cult) - GLOB.pre_setup_antags -= cult_mind - - main_cult.setup_objectives() //Wait until all cultists are assigned to make sure none will be chosen as sacrifice. - - . = ..() - -/datum/game_mode/proc/add_cultist(datum/mind/cult_mind, stun , equip = FALSE, datum/team/cult/cult_team = null) - if (!istype(cult_mind)) - return FALSE - - var/datum/antagonist/cult/new_cultist = new() - new_cultist.give_equipment = equip - - if(cult_mind.add_antag_datum(new_cultist,cult_team)) - if(stun) - cult_mind.current.Unconscious(100) - return TRUE - -/datum/game_mode/proc/remove_cultist(datum/mind/cult_mind, silent, stun) - if(cult_mind.current) - var/datum/antagonist/cult/cult_datum = cult_mind.has_antag_datum(/datum/antagonist/cult) - if(!cult_datum) - return FALSE - cult_datum.silent = silent - cult_mind.remove_antag_datum(cult_datum) - if(stun) - cult_mind.current.Unconscious(100) - return TRUE - -/datum/game_mode/cult/proc/check_cult_victory() - return main_cult.check_cult_victory() - - -/datum/game_mode/cult/set_round_result() - ..() - if(check_cult_victory()) - SSticker.mode_result = "win - cult win" - SSticker.news_report = CULT_SUMMON - else - SSticker.mode_result = "loss - staff stopped the cult" - SSticker.news_report = CULT_FAILURE - -/datum/game_mode/cult/proc/check_survive() - 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++ - if(acolytes_survived>=acolytes_needed) - return 0 - else - return 1 - - -/datum/game_mode/cult/generate_report() - return "Some stations in your sector have reported evidence of blood sacrifice and strange magic. Ties to the Wizards' Federation have been proven not to exist, and many employees \ - have disappeared; even Central Command employees light-years away have felt strange presences and at times hysterical compulsions. Interrogations point towards this being the work of \ - the cult of Nar'Sie. If evidence of this cult is discovered aboard your station, extreme caution and extreme vigilance must be taken going forward, and all resources should be \ - 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/cult/generate_credit_text() - var/list/round_credits = list() - var/len_before_addition - - round_credits += " The Cult of Nar'Sie:
" - len_before_addition = round_credits.len - for(var/datum/mind/cultist in cult) - round_credits += "[cultist.name] as a cult fanatic
" - - var/datum/objective/eldergod/summon_objective = locate() in main_cult.objectives - if(summon_objective && summon_objective.summoned) - round_credits += "Nar'Sie as the eldritch abomination
" - - if(len_before_addition == round_credits.len) - round_credits += list("The cultists have learned the danger of eldritch magic!
", "They all disappeared!
") - round_credits += "
" - - round_credits += ..() - return round_credits - -#undef CULT_SCALING_COEFFICIENT diff --git a/code/game/gamemodes/devil/devil_agent/devil_agent.dm b/code/game/gamemodes/devil/devil_agent/devil_agent.dm deleted file mode 100644 index c8fb62faba09..000000000000 --- a/code/game/gamemodes/devil/devil_agent/devil_agent.dm +++ /dev/null @@ -1,44 +0,0 @@ -/datum/game_mode/devil/devil_agents - name = "Devil Agents" - config_tag = "devil_agents" - required_players = 25 - required_enemies = 3 - recommended_enemies = 8 - reroll_friendly = 0 - - traitors_possible = 10 //hard limit on traitors if scaling is turned off - num_modifier = 4 - objective_count = 2 - - var/list/devil_target_list = list() //will update to be a child of internal affairs when bothered - var/list/devil_late_joining_list = list() - minimum_devils = 3 - - announce_text = "There are devil agents onboard the station, trying to outbid each other!\n\ - + Devils: Purchase souls and interfere with your rivals!\n\ - + Crew: Resist the lure of sin and remain pure!" - -/datum/game_mode/devil/devil_agents/post_setup() - var/i = 0 - for(var/datum/mind/devil in devils) - i++ - if(i + 1 > devils.len) - i = 0 - devil_target_list[devil] = devils[i + 1] - ..() - -/datum/game_mode/devil/devil_agents/add_devil_objectives(datum/mind/devil_mind, quantity) - ..(devil_mind, quantity - give_outsell_objective(devil_mind)) - -/datum/game_mode/devil/devil_agents/proc/give_outsell_objective(datum/mind/devil) - //If you override this method, have it return the number of objectives added. - if(devil_target_list.len && devil_target_list[devil]) // Is a double agent - var/datum/mind/target_mind = devil_target_list[devil] - var/datum/antagonist/devil/D = target_mind.has_antag_datum(/datum/antagonist/devil) - var/datum/objective/devil/outsell/outsellobjective = new - outsellobjective.owner = devil - outsellobjective.target = target_mind - outsellobjective.update_explanation_text() - D.objectives += outsellobjective - return 1 - return 0 diff --git a/code/game/gamemodes/devil/devil_game_mode.dm b/code/game/gamemodes/devil/devil_game_mode.dm deleted file mode 100644 index 9d002f4a029d..000000000000 --- a/code/game/gamemodes/devil/devil_game_mode.dm +++ /dev/null @@ -1,106 +0,0 @@ -/datum/game_mode/devil - name = "devil" - config_tag = "devil" - report_type = "devil" - antag_flag = ROLE_DEVIL - false_report_weight = 1 - protected_jobs = list("Prisoner", "Lawyer", "Curator", "Chaplain", "Head of Security", "Captain", "AI") - required_players = 0 - required_enemies = 1 - recommended_enemies = 4 - reroll_friendly = 1 - enemy_minimum_age = 0 - title_icon = "devil" - - var/traitors_possible = 4 //hard limit on devils if scaling is turned off - var/num_modifier = 0 // Used for gamemodes, that are a child of traitor, that need more than the usual. - var/objective_count = 2 - var/minimum_devils = 1 - - announce_text = "There are devils onboard the station!\n\ - + Devils: Purchase souls and tempt the crew to sin!\n\ - + Crew: Resist the lure of sin and remain pure!" - -/datum/game_mode/devil/pre_setup() - if(CONFIG_GET(flag/protect_roles_from_antagonist)) - restricted_jobs += protected_jobs - if(CONFIG_GET(flag/protect_assistant_from_antagonist)) - restricted_jobs += "Assistant" - - var/num_devils = 1 - - var/tsc = CONFIG_GET(number/traitor_scaling_coeff) - if(tsc) - num_devils = max(minimum_devils, min(round(num_players() / (tsc * 3))+ 2 + num_modifier, round(num_players() / (tsc * 1.5)) + num_modifier)) - else - num_devils = max(minimum_devils, min(num_players(), traitors_possible)) - - for(var/j = 0, j < num_devils, j++) - if (!antag_candidates.len) - break - var/datum/mind/devil = antag_pick(antag_candidates) - devils += devil - devil.special_role = traitor_name - devil.restricted_roles = restricted_jobs - - log_game("[key_name(devil)] has been selected as a [traitor_name]") - antag_candidates.Remove(devil) - - if(devils.len < required_enemies) - setup_error = "Not enough devil candidates" - return FALSE - for(var/antag in devils) - GLOB.pre_setup_antags += antag - return TRUE - - -/datum/game_mode/devil/post_setup() - for(var/datum/mind/devil in devils) - post_setup_finalize(devil) - ..() - return TRUE - -/datum/game_mode/devil/generate_report() - return "Infernal creatures have been seen nearby offering great boons in exchange for souls. This is considered theft against Nanotrasen, as all employment contracts contain a lien on the \ - employee's soul. If anyone sells their soul in error, contact an attorney to overrule the sale. Be warned that if the devil purchases enough souls, a gateway to hell may open." - -/datum/game_mode/devil/proc/post_setup_finalize(datum/mind/devil) - add_devil(devil.current, ascendable = TRUE) //Devil gamemode devils are ascendable. - GLOB.pre_setup_antags -= devil - add_devil_objectives(devil,2) - -/proc/is_devil(mob/living/M) - return M.mind?.has_antag_datum(/datum/antagonist/devil) - -/proc/add_devil(mob/living/L, ascendable = FALSE) - if(!L || !L.mind) - return FALSE - var/datum/antagonist/devil/devil_datum = L.mind.add_antag_datum(/datum/antagonist/devil) - devil_datum.ascendable = ascendable - return devil_datum - -/proc/remove_devil(mob/living/L) - if(!L || !L.mind) - return FALSE - var/datum/antagonist/devil_datum = L.mind.has_antag_datum(/datum/antagonist/devil) - devil_datum.on_removal() - return TRUE - -/datum/game_mode/devil/generate_credit_text() - var/list/round_credits = list() - var/len_before_addition - - round_credits += "The Tempting Devils:
" - len_before_addition = round_credits.len - var/datum/antagonist/devil/devil_info - for(var/datum/mind/devil in devils) - devil_info = devil.has_antag_datum(/datum/antagonist/devil) - if(devil_info) // This should never fail, but better to be sure - round_credits += "[devil_info.truename] in the form of [devil.name]
" - devil_info = null - if(len_before_addition == round_credits.len) - round_credits += list("The devils were all utterly destroyed!
", "The love of Space Jesus shines through!
") - round_credits += "
" - - round_credits += ..() - return round_credits diff --git a/code/game/gamemodes/devil/game_mode.dm b/code/game/gamemodes/devil/game_mode.dm deleted file mode 100644 index f91b863483c5..000000000000 --- a/code/game/gamemodes/devil/game_mode.dm +++ /dev/null @@ -1,26 +0,0 @@ -/datum/game_mode - var/list/datum/mind/devils = list() - var/devil_ascended = 0 // Number of arch devils on station - -/datum/game_mode/proc/add_devil_objectives(datum/mind/devil_mind, quantity) - var/list/validtypes = list(/datum/objective/devil/soulquantity, /datum/objective/devil/soulquality, /datum/objective/devil/sintouch, /datum/objective/devil/buy_target) - var/datum/antagonist/devil/D = devil_mind.has_antag_datum(/datum/antagonist/devil) - for(var/i = 1 to quantity) - var/type = pick(validtypes) - var/datum/objective/devil/objective = new type(null) - objective.owner = devil_mind - D.objectives += objective - if(!istype(objective, /datum/objective/devil/buy_target)) - validtypes -= type //prevent duplicate objectives, EXCEPT for buy_target. - else - objective.find_target() - -/datum/game_mode/proc/update_soulless_icons_added(datum/mind/soulless_mind) - var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_SOULLESS] - hud.join_hud(soulless_mind.current) - set_antag_hud(soulless_mind.current, "soulless") - -/datum/game_mode/proc/update_soulless_icons_removed(datum/mind/soulless_mind) - var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_SOULLESS] - hud.leave_hud(soulless_mind.current) - set_antag_hud(soulless_mind.current, null) diff --git a/code/game/gamemodes/devil/objectives.dm b/code/game/gamemodes/devil/objectives.dm deleted file mode 100644 index f3d5ce575f85..000000000000 --- a/code/game/gamemodes/devil/objectives.dm +++ /dev/null @@ -1,113 +0,0 @@ -/datum/objective/devil - -/datum/objective/devil/soulquantity - explanation_text = "You shouldn't see this text. Error:DEVIL1" - target_amount = 4 - -/datum/objective/devil/soulquantity/New() - target_amount = pick(6,7,8) - update_explanation_text() - -/datum/objective/devil/soulquantity/update_explanation_text() - explanation_text = "Purchase, and retain control over at least [target_amount] souls." - -/datum/objective/devil/soulquantity/check_completion() - var/count = 0 - var/datum/antagonist/devil/devilDatum = owner.has_antag_datum(/datum/antagonist/devil) - var/list/souls = devilDatum.soulsOwned - for(var/S in souls) //Just a sanity check. - var/datum/mind/L = S - if(L.soulOwner == owner) - count++ - return count >= target_amount - - - -/datum/objective/devil/soulquality - explanation_text = "You shouldn't see this text. Error:DEVIL2" - var/contractType - var/contractName - -/datum/objective/devil/soulquality/New() - contractType = pick(CONTRACT_POWER, CONTRACT_WEALTH, CONTRACT_PRESTIGE, CONTRACT_MAGIC, CONTRACT_REVIVE, CONTRACT_KNOWLEDGE/*, CONTRACT_UNWILLING*/) - target_amount = pick(1,2) - switch(contractType) - if(CONTRACT_POWER) - contractName = "for power" - if(CONTRACT_WEALTH) - contractName = "for wealth" - if(CONTRACT_PRESTIGE) - contractName = "for prestige" - if(CONTRACT_MAGIC) - contractName = "for magic" - if(CONTRACT_REVIVE) - contractName = "of revival" - if(CONTRACT_KNOWLEDGE) - contractName = "for knowledge" - update_explanation_text() - -/datum/objective/devil/soulquality/update_explanation_text() - explanation_text = "Have mortals sign at least [target_amount] contracts [contractName]" - -/datum/objective/devil/soulquality/check_completion() - var/count = 0 - var/datum/antagonist/devil/devilDatum = owner.has_antag_datum(/datum/antagonist/devil) - var/list/souls = devilDatum.soulsOwned - for(var/S in souls) - var/datum/mind/L = S - if(!L.owns_soul() && L.damnation_type == contractType) - count++ - return count>=target_amount - - - -/datum/objective/devil/sintouch - explanation_text = "You shouldn't see this text. Error:DEVIL3" - -/datum/objective/devil/sintouch/New() - target_amount = pick(4,5) - explanation_text = "Ensure at least [target_amount] mortals are sintouched." - -/datum/objective/devil/sintouch/check_completion() - var/list/touched = get_antag_minds(/datum/antagonist/sintouched) - return touched.len >= target_amount - - -/datum/objective/devil/buy_target - explanation_text = "You shouldn't see this text. Error:DEVIL4" - -/datum/objective/devil/buy_target/update_explanation_text() - if(target) - explanation_text = "Purchase and retain the soul of [target.name], the [target.assigned_role]." - else - explanation_text = "Free objective." - -/datum/objective/devil/buy_target/check_completion() - return target.soulOwner == owner - - -/datum/objective/devil/outsell - explanation_text = "You shouldn't see this text. Error:DEVIL5" - -/datum/objective/devil/outsell/New() - -/datum/objective/devil/outsell/update_explanation_text() - var/datum/antagonist/devil/opponent = target.has_antag_datum(/datum/antagonist/devil) - explanation_text = "Purchase and retain control over more souls than [opponent.truename], known to mortals as [target.name], the [target.assigned_role]." - -/datum/objective/devil/outsell/check_completion() - var/selfcount = 0 - var/datum/antagonist/devil/devilDatum = owner.has_antag_datum(/datum/antagonist/devil) - var/list/souls = devilDatum.soulsOwned - for(var/S in souls) - var/datum/mind/L = S - if(L.soulOwner == owner) - selfcount++ - var/targetcount = 0 - devilDatum = target.has_antag_datum(/datum/antagonist/devil) - souls = devilDatum.soulsOwned - for(var/S in souls) - var/datum/mind/L = S - if(L.soulOwner == target) - targetcount++ - return selfcount > targetcount diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets.dm b/code/game/gamemodes/dynamic/dynamic_rulesets.dm index 1e6a2da4d867..7163dd0ca54e 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets.dm @@ -35,7 +35,7 @@ var/list/enemy_roles = list() /// If enemy_roles was set, this is the amount of enemy job workers needed per threat_level range (0-10,10-20,etc) IMPORTANT: DOES NOT WORK ON ROUNDSTART RULESETS. var/required_enemies = list(1,1,0,0,0,0,0,0,0,0) - /// The rule needs this many candidates (post-trimming) to be executed (example: Cult needs 4 players at round start) + /// The rule needs this many candidates (post-trimming) to be executed var/required_candidates = 0 /// 1 -> 9, probability for this rule to be picked against other rules var/weight = 5 diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm index 8c8fe19d0a97..70d9c8405204 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm @@ -191,65 +191,6 @@ M.add_antag_datum(new antag_datum()) return TRUE -////////////////////////////////////////////// -// // -// BLOOD CULT // -// // -////////////////////////////////////////////// - -/datum/dynamic_ruleset/roundstart/bloodcult - name = "Blood Cult" - antag_flag = ROLE_CULTIST - antag_datum = /datum/antagonist/cult - minimum_required_age = 14 - restricted_roles = list("AI", "Cyborg", "Prisoner", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Chaplain", "Head of Personnel", "Research Director", "Chief Medical Officer", "Chief Engineer", "SolGov Representative") - required_candidates = 2 - weight = 3 - cost = 35 - requirements = list(100,90,80,60,40,30,10,10,10,10) - high_population_requirement = 10 - flags = HIGHLANDER_RULESET - antag_cap = list(2,2,2,3,3,4,4,4,4,4) - var/datum/team/cult/main_cult - -/datum/dynamic_ruleset/roundstart/bloodcult/ready(forced = FALSE) - required_candidates = antag_cap[indice_pop] - . = ..() - -/datum/dynamic_ruleset/roundstart/bloodcult/pre_execute() - . = ..() - var/cultists = antag_cap[indice_pop] - mode.antags_rolled += cultists - for(var/cultists_number = 1 to cultists) - if(candidates.len <= 0) - break - var/mob/M = pick_n_take(candidates) - assigned += M.mind - M.mind.special_role = ROLE_CULTIST - M.mind.restricted_roles = restricted_roles - GLOB.pre_setup_antags += M.mind - return TRUE - -/datum/dynamic_ruleset/roundstart/bloodcult/execute() - main_cult = new - for(var/datum/mind/M in assigned) - var/datum/antagonist/cult/new_cultist = new antag_datum() - new_cultist.cult_team = main_cult - new_cultist.give_equipment = TRUE - M.add_antag_datum(new_cultist) - GLOB.pre_setup_antags -= M - main_cult.setup_objectives() - return TRUE - -/datum/dynamic_ruleset/roundstart/bloodcult/round_result() - ..() - if(main_cult.check_cult_victory()) - SSticker.mode_result = "win - cult win" - SSticker.news_report = CULT_SUMMON - else - SSticker.mode_result = "loss - staff stopped the cult" - SSticker.news_report = CULT_FAILURE - ////////////////////////////////////////////// // // // NUCLEAR OPERATIVES // @@ -382,93 +323,3 @@ for(var/datum/mind/V in assigned) V.assigned_role = "Clown Operative" V.special_role = "Clown Operative" - -////////////////////////////////////////////// -// // -// DEVIL // -// // -////////////////////////////////////////////// - -/datum/dynamic_ruleset/roundstart/devil - name = "Devil" - antag_flag = ROLE_DEVIL - antag_datum = /datum/antagonist/devil - restricted_roles = list("Lawyer", "Curator", "Chaplain", "Prisoner", "Head of Security", "Captain", "AI") - required_candidates = 1 - weight = 3 - cost = 0 - requirements = list(101,101,101,101,101,101,101,101,101,101) - high_population_requirement = 101 - antag_cap = list(1,1,1,2,2,2,3,3,3,4) - -/datum/dynamic_ruleset/roundstart/devil/pre_execute() - . = ..() - var/num_devils = antag_cap[indice_pop] - mode.antags_rolled += num_devils - - for(var/j = 0, j < num_devils, j++) - if (!candidates.len) - break - var/mob/devil = pick_n_take(candidates) - assigned += devil.mind - devil.mind.special_role = ROLE_DEVIL - devil.mind.restricted_roles = restricted_roles - GLOB.pre_setup_antags += devil.mind - - log_game("[key_name(devil)] has been selected as a devil") - return TRUE - -/datum/dynamic_ruleset/roundstart/devil/execute() - for(var/datum/mind/devil in assigned) - add_devil(devil.current, ascendable = TRUE) - GLOB.pre_setup_antags -= devil - add_devil_objectives(devil,2) - return TRUE - -/datum/dynamic_ruleset/roundstart/devil/proc/add_devil_objectives(datum/mind/devil_mind, quantity) - var/list/validtypes = list(/datum/objective/devil/soulquantity, /datum/objective/devil/soulquality, /datum/objective/devil/sintouch, /datum/objective/devil/buy_target) - var/datum/antagonist/devil/D = devil_mind.has_antag_datum(/datum/antagonist/devil) - for(var/i = 1 to quantity) - var/type = pick(validtypes) - var/datum/objective/devil/objective = new type(null) - objective.owner = devil_mind - D.objectives += objective - if(!istype(objective, /datum/objective/devil/buy_target)) - validtypes -= type - else - objective.find_target() - -////////////////////////////////////////////// -// // -// METEOR // -// // -////////////////////////////////////////////// - -/datum/dynamic_ruleset/roundstart/meteor - name = "Meteor" - persistent = TRUE - required_candidates = 0 - weight = 3 - cost = 0 - requirements = list(101,101,101,101,101,101,101,101,101,101) - high_population_requirement = 101 - var/meteordelay = 2000 - var/nometeors = 0 - var/rampupdelta = 5 - -/datum/dynamic_ruleset/roundstart/meteor/rule_process() - if(nometeors || meteordelay > world.time - SSticker.round_start_time) - return - - var/list/wavetype = GLOB.meteors_normal - var/meteorminutes = (world.time - SSticker.round_start_time - meteordelay) / 10 / 60 - - if (prob(meteorminutes)) - wavetype = GLOB.meteors_threatening - - if (prob(meteorminutes/2)) - wavetype = GLOB.meteors_catastrophic - - var/ramp_up_final = clamp(round(meteorminutes/rampupdelta), 1, 10) - - spawn_meteors(ramp_up_final, wavetype) diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm index 56f873a50bd1..7db8207c9d71 100644 --- a/code/game/gamemodes/events.dm +++ b/code/game/gamemodes/events.dm @@ -47,11 +47,10 @@ for(var/area/A in GLOB.sortedAreas) if(!A.requires_power || A.always_unpowered) continue - if(!istype(A, /area/shuttle)) - A.power_light = TRUE - A.power_equip = TRUE - A.power_environ = TRUE - A.power_change() + A.power_light = TRUE + A.power_equip = TRUE + A.power_environ = TRUE + A.power_change() /proc/power_restore_quick() priority_announce("All SMESs have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", 'sound/ai/poweron.ogg') diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 391ad852664f..00bc1bc95e13 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -418,9 +418,6 @@ return max(0, enemy_minimum_age - C.player_age) -/datum/game_mode/proc/remove_antag_for_borging(datum/mind/newborgie) - SSticker.mode.remove_cultist(newborgie, 0, 0) - /datum/game_mode/proc/generate_station_goals() var/list/possible = list() for(var/T in subtypesof(/datum/station_goal)) diff --git a/code/game/gamemodes/meteor/meteor.dm b/code/game/gamemodes/meteor/meteor.dm deleted file mode 100644 index 9149f5da35f6..000000000000 --- a/code/game/gamemodes/meteor/meteor.dm +++ /dev/null @@ -1,61 +0,0 @@ -/datum/game_mode/meteor - name = "meteor" - config_tag = "meteor" - report_type = "meteor" - false_report_weight = 1 - var/meteordelay = 2000 - var/nometeors = 0 - var/rampupdelta = 5 - required_players = 0 - - announce_span = "danger" - announce_text = "A major meteor shower is bombarding the station! The crew needs to evacuate or survive the onslaught." - - title_icon = "meteor" - -/datum/game_mode/meteor/process() - if(nometeors || meteordelay > world.time - SSticker.round_start_time) - return - - var/list/wavetype = GLOB.meteors_normal - var/meteorminutes = (world.time - SSticker.round_start_time - meteordelay) / 10 / 60 - - - if (prob(meteorminutes)) - wavetype = GLOB.meteors_threatening - - if (prob(meteorminutes/2)) - wavetype = GLOB.meteors_catastrophic - - var/ramp_up_final = clamp(round(meteorminutes/rampupdelta), 1, 10) - - spawn_meteors(ramp_up_final, wavetype) - - -/datum/game_mode/meteor/special_report() - var/survivors = 0 - var/list/survivor_list = list() - - for(var/mob/living/player in GLOB.player_list) - if(player.stat != DEAD) - ++survivors - - if(player.onCentCom()) - survivor_list += "[player.real_name] escaped to the safety of CentCom." - else if(player.onSyndieBase()) - survivor_list += "[player.real_name] escaped to the (relative) safety of Syndicate Space." - else - survivor_list += "[player.real_name] survived but is stranded without any hope of rescue." - - if(survivors) - return "The following survived the meteor storm:" - else - return "
[survivor_list.Join("
")]Nobody survived the meteor storm!" - -/datum/game_mode/meteor/set_round_result() - ..() - SSticker.mode_result = "end - evacuation" - -/datum/game_mode/meteor/generate_report() - return "[pick("Asteroids have", "Meteors have", "Large rocks have", "Stellar minerals have", "Space hail has", "Debris has")] been detected near your station, and a collision is possible, \ - though unlikely. Be prepared for largescale impacts and destruction. Please note that the debris will prevent the escape shuttle from arriving quickly." diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 65e161f2176b..ec74c51acc95 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -58,18 +58,11 @@ GLOBAL_LIST_EMPTY(objectives) /datum/objective/proc/considered_escaped(datum/mind/M) if(!considered_alive(M)) return FALSE - if(considered_exiled(M)) - return FALSE - if(M.force_escaped) - return TRUE - if(SSticker.force_ending || SSticker.mode.station_was_nuked) // Just let them win. + if(SSticker.force_ending) // Just let them win. return TRUE if(SSshuttle.jump_mode != BS_JUMP_COMPLETED) return FALSE - var/turf/location = get_turf(M.current) - if(!location || istype(location, /turf/open/floor/mineral/plastitanium/red/brig)) // Fails if they are in the shuttle brig - return FALSE - return location.onCentCom() || location.onSyndieBase() + return TRUE /datum/objective/proc/check_completion() return completed @@ -233,7 +226,7 @@ GLOBAL_LIST_EMPTY(objectives) ..() /datum/objective/maroon/check_completion() - return !target || !considered_alive(target) || (!target.current.onCentCom() && !target.current.onSyndieBase()) + return !target || !considered_alive(target) /datum/objective/maroon/update_explanation_text() if(target && target.current) @@ -334,7 +327,7 @@ GLOBAL_LIST_EMPTY(objectives) name = "detain" /datum/objective/jailbreak/detain/check_completion() - return completed || (!considered_escaped(target) && (considered_alive(target) && target.current.onCentCom())) + return completed || (!considered_escaped(target) && (considered_alive(target))) /datum/objective/jailbreak/detain/update_explanation_text() ..() diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 4d9d5078b622..4219a0710e50 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -1,7 +1,6 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list( /obj/item/storage/box/snappops = 2, /obj/item/toy/talking/AI = 2, - /obj/item/toy/talking/codex_gigas = 2, /obj/item/clothing/under/syndicate/tacticool = 2, /obj/item/toy/sword = 2, /obj/item/toy/gun = 2, diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 3412321b380b..2d76d7ecb351 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -370,26 +370,6 @@ audible_message("You hear a click from the bottom of the door.", null, 1) update_appearance() -/obj/machinery/door/airlock/narsie_act() - var/turf/T = get_turf(src) - var/obj/machinery/door/airlock/cult/A - if(GLOB.cult_narsie) - var/runed = prob(20) - if(glass) - if(runed) - A = new/obj/machinery/door/airlock/cult/glass(T) - else - A = new/obj/machinery/door/airlock/cult/unruned/glass(T) - else - if(runed) - A = new/obj/machinery/door/airlock/cult(T) - else - A = new/obj/machinery/door/airlock/cult/unruned(T) - A.name = name - else - A = new /obj/machinery/door/airlock/cult/weak(T) - qdel(src) - /obj/machinery/door/airlock/Destroy() QDEL_NULL(wires) QDEL_NULL(electronics) diff --git a/code/game/machinery/doors/airlock_types.dm b/code/game/machinery/doors/airlock_types.dm index 492ce30f6ac4..f6e6840f552b 100644 --- a/code/game/machinery/doors/airlock_types.dm +++ b/code/game/machinery/doors/airlock_types.dm @@ -461,115 +461,6 @@ security_level = 1 has_hatch = FALSE -////////////////////////////////// -/* - Cult Airlocks -*/ - -/obj/machinery/door/airlock/cult - name = "cult airlock" - icon = 'icons/obj/doors/airlocks/cult/runed/cult.dmi' - overlays_file = 'icons/obj/doors/airlocks/cult/runed/overlays.dmi' - assemblytype = /obj/structure/door_assembly/door_assembly_cult - hackProof = TRUE - aiControlDisabled = AI_WIRE_DISABLED - req_access = list(ACCESS_BLOODCULT) - damage_deflection = 10 - has_hatch = FALSE - var/openingoverlaytype = /obj/effect/temp_visual/cult/door - var/friendly = FALSE - var/stealthy = FALSE - -/obj/machinery/door/airlock/cult/Initialize() - . = ..() - new openingoverlaytype(loc) - -/obj/machinery/door/airlock/cult/canAIControl(mob/user) - return (iscultist(user) && !isAllPowerCut()) - -/obj/machinery/door/airlock/cult/on_break() - if(!panel_open) - panel_open = TRUE - -/obj/machinery/door/airlock/cult/isElectrified() - return FALSE - -/obj/machinery/door/airlock/cult/hasPower() - return TRUE - -/obj/machinery/door/airlock/cult/allowed(mob/living/L) - if(!density) - return 1 - if(friendly || iscultist(L) || istype(L, /mob/living/simple_animal/shade) || isconstruct(L)) - if(!stealthy) - new openingoverlaytype(loc) - return 1 - else - 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.Paralyze(40) - L.throw_at(throwtarget, 5, 1) - 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_appearance() - -/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_appearance() - -/obj/machinery/door/airlock/cult/narsie_act() - return - -/obj/machinery/door/airlock/cult/emp_act(severity) - return - -/obj/machinery/door/airlock/cult/friendly - friendly = TRUE - -/obj/machinery/door/airlock/cult/glass - glass = TRUE - opacity = FALSE - -/obj/machinery/door/airlock/cult/glass/friendly - friendly = TRUE - -/obj/machinery/door/airlock/cult/unruned - icon = 'icons/obj/doors/airlocks/cult/unruned/cult.dmi' - overlays_file = 'icons/obj/doors/airlocks/cult/unruned/overlays.dmi' - assemblytype = /obj/structure/door_assembly/door_assembly_cult/unruned - openingoverlaytype = /obj/effect/temp_visual/cult/door/unruned - -/obj/machinery/door/airlock/cult/unruned/friendly - friendly = TRUE - -/obj/machinery/door/airlock/cult/unruned/glass - glass = TRUE - opacity = FALSE - -/obj/machinery/door/airlock/cult/unruned/glass/friendly - friendly = TRUE - -/obj/machinery/door/airlock/cult/weak - name = "brittle cult airlock" - desc = "An airlock hastily corrupted by blood magic, it is unusually brittle in this state." - normal_integrity = 150 - damage_deflection = 5 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) - ////////////////////////////////// /* Misc Airlocks diff --git a/code/game/machinery/drone_dispenser.dm b/code/game/machinery/drone_dispenser.dm index 4603044ab285..bb79d5f7e46e 100644 --- a/code/game/machinery/drone_dispenser.dm +++ b/code/game/machinery/drone_dispenser.dm @@ -108,28 +108,6 @@ recharge_sound = null recharge_message = null -/obj/machinery/droneDispenser/swarmer - name = "swarmer fabricator" - desc = "An alien machine of unknown origin. It whirs and hums with green-blue light, the air above it shimmering." - icon = 'icons/obj/objects.dmi' - icon_state = "hivebot_fab" - icon_off = "hivebot_fab" - icon_on = "hivebot_fab" - icon_recharging = "hivebot_fab" - icon_creating = "hivebot_fab_on" - metal_cost = 0 - glass_cost = 0 - cooldownTime = 300 //30 seconds - maximum_idle = 0 // Swarmers have no restraint - dispense_type = /obj/effect/mob_spawn/swarmer - begin_create_message = "hums softly as an interface appears above it, scrolling by at unreadable speed." - end_create_message = "materializes a strange shell, which drops to the ground." - recharging_text = "Its lights are slowly increasing in brightness." - work_sound = 'sound/effects/empulse.ogg' - create_sound = 'sound/effects/phasein.ogg' - break_sound = 'sound/effects/empulse.ogg' - break_message = "slowly falls dark, lights stuttering." - /obj/machinery/droneDispenser/examine(mob/user) . = ..() if((mode == DRONE_RECHARGING) && !machine_stat && recharging_text) diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index 47db5ce6d0ef..e6e754c4b807 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -43,27 +43,6 @@ if(.) //damage was dealt new /obj/effect/temp_visual/impact_effect/ion(loc) -/obj/structure/emergency_shield/sanguine - name = "sanguine barrier" - desc = "A potent shield summoned by cultists to defend their rites." - icon_state = "shield-red" - max_integrity = 60 - -/obj/structure/emergency_shield/sanguine/emp_act(severity) - return - -/obj/structure/emergency_shield/invoker - name = "Invoker's Shield" - desc = "A weak shield summoned by cultists to protect them while they carry out delicate rituals." - color = "#FF0000" - max_integrity = 20 - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - layer = ABOVE_MOB_LAYER - -/obj/structure/emergency_shield/invoker/emp_act(severity) - return - - /obj/machinery/shieldgen name = "anti-breach shielding projector" desc = "Used to seal minor hull breaches." diff --git a/code/game/machinery/syndicatebeacon.dm b/code/game/machinery/syndicatebeacon.dm index 12085b7d62d4..b46ccaca9f60 100644 --- a/code/game/machinery/syndicatebeacon.dm +++ b/code/game/machinery/syndicatebeacon.dm @@ -148,7 +148,3 @@ /obj/item/sbeacondrop/penetratorturret desc = "A label on it reads: Warning: Activating this device will send a penetrator turret to your location." droptype = /obj/machinery/porta_turret/syndicate/shuttle - -/obj/item/sbeacondrop/constructshell - desc = "A label on it reads: Warning: Activating this device will send a Nar'sian construct shell to your location." - droptype = /obj/structure/constructshell diff --git a/code/game/objects/effects/blessing.dm b/code/game/objects/effects/blessing.dm index be2d89707882..66b027f2e516 100644 --- a/code/game/objects/effects/blessing.dm +++ b/code/game/objects/effects/blessing.dm @@ -16,14 +16,7 @@ I.alpha = 64 I.appearance_flags = RESET_ALPHA add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/blessedAware, "blessing", I) - RegisterSignal(loc, COMSIG_ATOM_INTERCEPT_TELEPORT, PROC_REF(block_cult_teleport)) /obj/effect/blessing/Destroy() UnregisterSignal(loc, COMSIG_ATOM_INTERCEPT_TELEPORT) return ..() - -/obj/effect/blessing/proc/block_cult_teleport(datum/source, channel, turf/origin, turf/destination) - SIGNAL_HANDLER - - if(channel == TELEPORT_CHANNEL_CULT) - return COMPONENT_BLOCK_TELEPORT diff --git a/code/game/objects/effects/forcefields.dm b/code/game/objects/effects/forcefields.dm index e46d8d92e82a..d4278d775888 100644 --- a/code/game/objects/effects/forcefields.dm +++ b/code/game/objects/effects/forcefields.dm @@ -19,14 +19,6 @@ /obj/effect/forcefield/singularity_pull() return -/obj/effect/forcefield/cult - desc = "An unholy shield that blocks all attacks." - name = "glowing wall" - icon = 'icons/effects/cult_effects.dmi' - icon_state = "cultshield" - CanAtmosPass = ATMOS_PASS_NO - timeleft = 200 - ///////////Mimewalls/////////// /obj/effect/forcefield/mime diff --git a/code/game/objects/items/AI_modules.dm b/code/game/objects/items/AI_modules.dm index e29a5f25fe5e..1968da023376 100644 --- a/code/game/objects/items/AI_modules.dm +++ b/code/game/objects/items/AI_modules.dm @@ -49,7 +49,7 @@ AI MODULES //Handle the lawcap if(law_datum) var/tot_laws = 0 - for(var/lawlist in list(law_datum.devillaws, law_datum.inherent, law_datum.supplied, law_datum.ion, law_datum.hacked, laws)) + for(var/lawlist in list(law_datum.inherent, law_datum.supplied, law_datum.ion, law_datum.hacked, laws)) for(var/mylaw in lawlist) if(mylaw != "") tot_laws++ diff --git a/code/game/objects/items/blueprints.dm b/code/game/objects/items/blueprints.dm index d2ce379274dc..232b4570a97e 100644 --- a/code/game/objects/items/blueprints.dm +++ b/code/game/objects/items/blueprints.dm @@ -150,7 +150,6 @@ if(A.outdoors) return AREA_SPACE var/list/SPECIALS = list( - /area/shuttle, /area/centcom, /area/asteroid, /area/tdome, diff --git a/code/game/objects/items/implants/implant_mindshield.dm b/code/game/objects/items/implants/implant_mindshield.dm index 121fa9f0c234..0a7094fb3895 100644 --- a/code/game/objects/items/implants/implant_mindshield.dm +++ b/code/game/objects/items/implants/implant_mindshield.dm @@ -28,10 +28,7 @@ deconverted = TRUE if(!silent) - if(target.mind in SSticker.mode.cult) - to_chat(target, "You feel something interfering with your mental conditioning, but you resist it!") - else - to_chat(target, "You feel a sense of peace and security. You are now protected from brainwashing.") + to_chat(target, "You feel a sense of peace and security. You are now protected from brainwashing.") ADD_TRAIT(target, TRAIT_MINDSHIELD, "implant") target.sec_hud_set_implants() if(deconverted) diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index 3194c1302512..6aba20463392 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -289,7 +289,6 @@ if(M.laws.id == DEFAULT_AI_LAWID) O.make_laws() - SSticker.mode.remove_antag_for_borging(B.mind) O.job = "Cyborg" O.cell = chest.cell diff --git a/code/game/objects/items/shuttle_creator.dm b/code/game/objects/items/shuttle_creator.dm index 781020f87318..9f25041d1f00 100644 --- a/code/game/objects/items/shuttle_creator.dm +++ b/code/game/objects/items/shuttle_creator.dm @@ -218,7 +218,6 @@ /obj/item/shuttle_creator/proc/check_current_area(mob/user) var/static/area_or_turf_fail_types = typecacheof(list( /turf/open/space, - /area/shuttle )) //Check to see if the user can make a new area to prevent spamming if(user) diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 041f979d06a3..c2a0391d3d8b 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -7,7 +7,6 @@ * Plastic * Cardboard * Paper Frames - * Runed Metal (cult) * Bronze (bake brass) */ diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index 54ccfc301e9c..c6d55e03ef48 100644 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -405,32 +405,6 @@ var/datum/component/storage/STR = GetComponent(/datum/component/storage) STR.max_items = 5 -/obj/item/storage/belt/soulstone - name = "soul stone belt" - desc = "Designed for ease of access to the shards during a fight, as to not let a single enemy spirit slip away." - icon_state = "soulstone" - item_state = "soulstone" - -/obj/item/storage/belt/soulstone/ComponentInitialize() - . = ..() - var/datum/component/storage/STR = GetComponent(/datum/component/storage) - STR.max_items = 6 - STR.set_holdable(list( - /obj/item/soulstone - )) - -/obj/item/storage/belt/soulstone/full/PopulateContents() - for(var/i in 1 to 6) - new /obj/item/soulstone(src) - -/obj/item/storage/belt/soulstone/full/chappy/PopulateContents() - for(var/i in 1 to 6) - new /obj/item/soulstone/anybody/chaplain(src) - -/obj/item/storage/belt/soulstone/full/purified/PopulateContents() - for(var/i in 1 to 6) - new /obj/item/soulstone/anybody/purified(src) - /obj/item/storage/belt/champion name = "championship belt" desc = "Proves to the world that you are the strongest!" diff --git a/code/game/objects/items/storage/uplink_kits.dm b/code/game/objects/items/storage/uplink_kits.dm index 3ef2d547931a..9516c7128090 100644 --- a/code/game/objects/items/storage/uplink_kits.dm +++ b/code/game/objects/items/storage/uplink_kits.dm @@ -561,12 +561,3 @@ /obj/item/storage/box/syndie_kit/signaler/PopulateContents() for(var/i in 1 to 6) new /obj/item/assembly/signaler(src) - -/obj/item/storage/box/syndie_kit/cultconstructkit - name = "cult construct kit" - desc = "A sleek, sturdy box with an ominous, dark energy inside. Yikes." - -/obj/item/storage/box/syndie_kit/cultconstructkit/PopulateContents() - new /obj/item/storage/belt/soulstone/full/purified(src) - new /obj/item/sbeacondrop/constructshell(src) - new /obj/item/sbeacondrop/constructshell(src) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 7d2828c41660..6d6d258b5b0c 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -542,31 +542,6 @@ /obj/item/toy/talking/AI/generate_messages() return list(generate_ion_law()) -/obj/item/toy/talking/codex_gigas - name = "Toy Codex Gigas" - desc = "A tool to help you write fictional devils!" - icon = 'icons/obj/library.dmi' - icon_state = "demonomicon" - lefthand_file = 'icons/mob/inhands/misc/books_lefthand.dmi' - righthand_file = 'icons/mob/inhands/misc/books_righthand.dmi' - w_class = WEIGHT_CLASS_SMALL - recharge_time = 60 - -/obj/item/toy/talking/codex_gigas/activation_message(mob/user) - user.visible_message( - "[user] presses the button on \the [src].", - "You press the button on \the [src].", - "You hear a soft click.") - -/obj/item/toy/talking/codex_gigas/generate_messages() - var/datum/fakeDevil/devil = new - var/list/messages = list() - messages += "Some fun facts about: [devil.truename]" - messages += "[GLOB.lawlorify[LORE][devil.obligation]]" - messages += "[GLOB.lawlorify[LORE][devil.ban]]" - messages += "[GLOB.lawlorify[LORE][devil.banish]]" - return messages - /obj/item/toy/talking/owl name = "owl action figure" desc = "An action figure modeled after 'The Owl', defender of justice." diff --git a/code/game/objects/structures/ai_core.dm b/code/game/objects/structures/ai_core.dm index 1994ff330dd9..dba1c510767d 100644 --- a/code/game/objects/structures/ai_core.dm +++ b/code/game/objects/structures/ai_core.dm @@ -220,7 +220,6 @@ to_chat(user, "You connect the monitor.") if(brain) var/mob/living/brain/B = brain.brainmob - SSticker.mode.remove_antag_for_borging(B.mind) var/mob/living/silicon/ai/A = null diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index 31e9d9a0b8fc..8ee8d8214f80 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -209,7 +209,7 @@ LINEN BINS /obj/item/bedsheet/cult name = "cultist's bedsheet" - desc = "You might dream of Nar'Sie if you sleep with this. It seems rather tattered and glows of an eldritch presence." + desc = "You might dream of elder gods if you sleep with this. It seems rather tattered." icon_state = "sheetcult" item_state = "sheetcult" dream_messages = list("a tome", "a floating red crystal", "a glowing sword", "a bloody symbol", "a massive humanoid figure") diff --git a/code/game/objects/structures/door_assembly_types.dm b/code/game/objects/structures/door_assembly_types.dm index d2bcf77cfda7..b77f86be469f 100644 --- a/code/game/objects/structures/door_assembly_types.dm +++ b/code/game/objects/structures/door_assembly_types.dm @@ -141,20 +141,6 @@ airlock_type = /obj/machinery/door/airlock/shuttle glass_type = /obj/machinery/door/airlock/shuttle/glass -/obj/structure/door_assembly/door_assembly_cult - name = "cult airlock assembly" - icon = 'icons/obj/doors/airlocks/cult/runed/cult.dmi' - base_name = "cult airlock" - overlays_file = 'icons/obj/doors/airlocks/cult/runed/overlays.dmi' - airlock_type = /obj/machinery/door/airlock/cult - glass_type = /obj/machinery/door/airlock/cult/glass - -/obj/structure/door_assembly/door_assembly_cult/unruned - icon = 'icons/obj/doors/airlocks/cult/unruned/cult.dmi' - overlays_file = 'icons/obj/doors/airlocks/cult/unruned/overlays.dmi' - airlock_type = /obj/machinery/door/airlock/cult/unruned - glass_type = /obj/machinery/door/airlock/cult/unruned/glass - /obj/structure/door_assembly/door_assembly_viro name = "virology airlock assembly" icon = 'icons/obj/doors/airlocks/station/virology.dmi' diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm index aed3ae724c59..f8893a3e3bc9 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -102,58 +102,6 @@ head = /obj/item/clothing/head/helmet/gladiator uniform = /obj/item/clothing/under/costume/gladiator/ash_walker -/obj/effect/mob_spawn/human/demonic_friend - name = "Essence of friendship" - desc = "Oh boy! Oh boy! A friend!" - mob_name = "Demonic friend" - icon = 'icons/obj/cardboard_cutout.dmi' - icon_state = "cutout_basic" - outfit = /datum/outfit/demonic_friend - death = FALSE - roundstart = FALSE - random = TRUE - id_job = "SuperFriend" - var/obj/effect/proc_holder/spell/targeted/summon_friend/spell - var/datum/mind/owner - assignedrole = "SuperFriend" - -/obj/effect/mob_spawn/human/demonic_friend/Initialize(mapload, datum/mind/owner_mind, obj/effect/proc_holder/spell/targeted/summon_friend/summoning_spell) - . = ..() - owner = owner_mind - flavour_text = "You have been given a reprieve from your eternity of torment, to be [owner.name]'s friend for [owner.p_their()] short mortal coil." - important_info = "Be aware that if you do not live up to [owner.name]'s expectations, they can send you back to hell with a single thought. [owner.name]'s death will also return you to hell." - var/area/A = get_area(src) - if(!mapload && A) - notify_ghosts("\A friendship shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE) - objectives = "Be [owner.name]'s friend, and keep [owner.name] alive, so you don't get sent back to hell." - spell = summoning_spell - - -/obj/effect/mob_spawn/human/demonic_friend/special(mob/living/L) - if(!QDELETED(owner.current) && owner.current.stat != DEAD) - L.fully_replace_character_name(null,"[owner.name]'s best friend") - soullink(/datum/soullink/oneway, owner.current, L) - spell.friend = L - spell.charge_counter = spell.charge_max - L.mind.hasSoul = FALSE - var/mob/living/carbon/human/H = L - var/obj/item/worn = H.wear_id - var/obj/item/card/id/id = worn.GetID() - id.registered_name = L.real_name - id.update_label() - else - to_chat(L, "Your owner is already dead! You will soon perish.") - addtimer(CALLBACK(L, TYPE_PROC_REF(/mob, dust), 150)) //Give em a few seconds as a mercy. - -/datum/outfit/demonic_friend - name = "Demonic Friend" - uniform = /obj/item/clothing/under/misc/assistantformal - shoes = /obj/item/clothing/shoes/laceup - r_pocket = /obj/item/radio - back = /obj/item/storage/backpack - implants = list(/obj/item/implant/mindshield) //No revolutionaries, he's MY friend. - id = /obj/item/card/id - /obj/effect/mob_spawn/human/syndicate name = "Syndicate Operative" roundstart = FALSE diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index df0d3cf1f43c..5f35e69d098e 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -314,10 +314,6 @@ new remains(loc) qdel(src) -/obj/structure/girder/narsie_act() - new /obj/structure/girder/cult(loc) - qdel(src) - /obj/structure/girder/displaced name = "displaced girder" icon_state = "displaced" @@ -339,56 +335,6 @@ new remains(loc, 2) qdel(src) - - -//////////////////////////////////////////// cult girder ////////////////////////////////////////////// - -/obj/structure/girder/cult - name = "runed girder" - desc = "Framework made of a strange and shockingly cold metal. It doesn't seem to have any bolts." - icon = 'icons/obj/cult.dmi' - icon_state= "cultgirder" - can_displace = FALSE - -/obj/structure/girder/cult/attackby(obj/item/W, mob/user, params) - add_fingerprint(user) - if(W.tool_behaviour == TOOL_WELDER) - if(!W.tool_start_check(user, amount=0)) - return - - to_chat(user, "You start slicing apart the girder...") - if(W.use_tool(src, user, 40, volume=50)) - to_chat(user, "You slice apart the girder.") - var/obj/item/stack/sheet/mineral/hidden/hellstone/R = new(drop_location(), 1) - transfer_fingerprints_to(R) - qdel(src) - - else if(istype(W, /obj/item/stack/sheet/mineral/hidden/hellstone)) - var/obj/item/stack/sheet/mineral/hidden/hellstone/R = W - if(R.get_amount() < 1) - to_chat(user, "You need at least one sheet of runed metal to construct a runed wall!") - return 0 - user.visible_message("[user] begins laying runed metal on [src]...", "You begin constructing a runed wall...") - if(do_after(user, 50, target = src)) - if(R.get_amount() < 1) - return - user.visible_message("[user] plates [src] with runed metal.", "You construct a runed wall.") - R.use(1) - var/turf/T = get_turf(src) - T.PlaceOnTop(/turf/closed/wall/mineral/cult) - qdel(src) - - else - return ..() - -/obj/structure/girder/cult/narsie_act() - return - -/obj/structure/girder/cult/deconstruct(disassembled = TRUE) - if(!(flags_1 & NODECONSTRUCT_1)) - new /obj/item/stack/sheet/mineral/hidden/hellstone(drop_location(), 1) - qdel(src) - /obj/structure/girder/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) switch(the_rcd.mode) if(RCD_FLOORWALL) diff --git a/code/game/turfs/closed/wall/misc_walls.dm b/code/game/turfs/closed/wall/misc_walls.dm index e37fc13c340b..1c18fdd9904f 100644 --- a/code/game/turfs/closed/wall/misc_walls.dm +++ b/code/game/turfs/closed/wall/misc_walls.dm @@ -8,24 +8,12 @@ canSmoothWith = null sheet_type = /obj/item/stack/sheet/mineral/hidden/hellstone sheet_amount = 1 - girder_type = /obj/structure/girder/cult - max_integrity = 600 /turf/closed/wall/mineral/cult/Initialize(mapload, inherited_virtual_z) new /obj/effect/temp_visual/cult/turf(src) . = ..() -/turf/closed/wall/mineral/cult/Exited(atom/movable/AM, atom/newloc) - . = ..() - if(istype(AM, /mob/living/simple_animal/hostile/construct/harvester)) //harvesters can go through cult walls, dragging something with - var/mob/living/simple_animal/hostile/construct/harvester/H = AM - var/atom/movable/stored_pulling = H.pulling - if(stored_pulling) - stored_pulling.setDir(get_dir(stored_pulling.loc, newloc)) - stored_pulling.forceMove(src) - H.start_pulling(stored_pulling, supress_message = TRUE) - /turf/closed/wall/mineral/cult/artificer name = "runed stone wall" desc = "A cold stone wall engraved with indecipherable symbols. Studying them causes your head to pound." diff --git a/code/game/turfs/open/floor.dm b/code/game/turfs/open/floor.dm index f7eac409b836..23fdfcc6d998 100644 --- a/code/game/turfs/open/floor.dm +++ b/code/game/turfs/open/floor.dm @@ -180,11 +180,6 @@ else if(prob(50)) ReplaceWithLattice() -/turf/open/floor/narsie_act(force, ignore_mobs, probability = 20) - . = ..() - if(.) - ChangeTurf(/turf/open/floor/engine/cult, flags = CHANGETURF_INHERIT_AIR) - /turf/open/floor/acid_melt() ScrapeAway(flags = CHANGETURF_INHERIT_AIR) diff --git a/code/game/turfs/open/floor/reinf_floor.dm b/code/game/turfs/open/floor/reinf_floor.dm index 7fb94e541bda..9094b0a3238f 100644 --- a/code/game/turfs/open/floor/reinf_floor.dm +++ b/code/game/turfs/open/floor/reinf_floor.dm @@ -141,36 +141,6 @@ name = "hydrogen mix floor" initial_gas_mix = ATMOS_TANK_HYDROGEN_FUEL -/turf/open/floor/engine/cult - name = "engraved floor" - desc = "The air smells strange over this sinister flooring." - icon_state = "plating" - floor_tile = null - var/obj/effect/cult_turf/overlay/floor/bloodcult/realappearance - - -/turf/open/floor/engine/cult/Initialize(mapload, inherited_virtual_z) - . = ..() - new /obj/effect/temp_visual/cult/turf/floor(src) - realappearance = new /obj/effect/cult_turf/overlay/floor/bloodcult(src) - realappearance.linked = src - -/turf/open/floor/engine/cult/Destroy() - be_removed() - return ..() - -/turf/open/floor/engine/cult/ChangeTurf(path, new_baseturf, flags) - if(path != type) - be_removed() - return ..() - -/turf/open/floor/engine/cult/proc/be_removed() - qdel(realappearance) - realappearance = null - -/turf/open/floor/engine/cult/airless - initial_gas_mix = AIRLESS_ATMOS - /turf/open/floor/engine/vacuum name = "vacuum floor" initial_gas_mix = AIRLESS_ATMOS diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index d05fd3ee3b98..b62a7830cc0d 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -850,22 +850,6 @@ if(!ai_number) to_chat(usr, "No AIs located" , confidential = TRUE) -/datum/admins/proc/output_all_devil_info() - var/devil_number = 0 - for(var/datum/mind/D in SSticker.mode.devils) - devil_number++ - var/datum/antagonist/devil/devil = D.has_antag_datum(/datum/antagonist/devil) - to_chat(usr, "Devil #[devil_number]:
" + devil.printdevilinfo(), confidential = TRUE) - if(!devil_number) - to_chat(usr, "No Devils located" , confidential = TRUE) - -/datum/admins/proc/output_devil_info(mob/living/M) - if(is_devil(M)) - var/datum/antagonist/devil/devil = M.mind.has_antag_datum(/datum/antagonist/devil) - to_chat(usr, devil.printdevilinfo(), confidential = TRUE) - else - to_chat(usr, "[M] is not a devil.", confidential = TRUE) - /datum/admins/proc/dynamic_mode_options(mob/user) var/dat = {"Dynamic Mode Options
diff --git a/code/modules/admin/fun_balloon.dm b/code/modules/admin/fun_balloon.dm index 04e84097f6d1..0be2f41696e6 100644 --- a/code/modules/admin/fun_balloon.dm +++ b/code/modules/admin/fun_balloon.dm @@ -136,8 +136,3 @@ /obj/effect/forcefield/arena_shuttle_entrance/proc/do_bloodbath(mob/living/L) var/obj/item/mine/pressure/pickup/bloodbath/B = new (L) B.mine_effect(L) - -/area/shuttle_arena - name = "arena" - has_gravity = STANDARD_GRAVITY - requires_power = FALSE diff --git a/code/modules/admin/sql_ban_system.dm b/code/modules/admin/sql_ban_system.dm index 28646666b46a..bd3d189f85eb 100644 --- a/code/modules/admin/sql_ban_system.dm +++ b/code/modules/admin/sql_ban_system.dm @@ -285,8 +285,8 @@ var/list/long_job_lists = list("Service" = GLOB.service_positions, "Ghost and Other Roles" = list(ROLE_BRAINWASHED, ROLE_DEATHSQUAD, ROLE_DRONE, ROLE_LAVALAND, ROLE_MIND_TRANSFER, ROLE_POSIBRAIN, ROLE_SENTIENCE), "Antagonist Positions" = list(ROLE_ABDUCTOR, ROLE_ALIEN, - ROLE_BROTHER, ROLE_CHANGELING, ROLE_CULTIST, - ROLE_DEVIL, ROLE_INTERNAL_AFFAIRS, ROLE_MALF, + ROLE_BROTHER, ROLE_CHANGELING, + ROLE_INTERNAL_AFFAIRS, ROLE_MALF, ROLE_MONKEY, ROLE_NINJA, ROLE_OPERATIVE, ROLE_OVERTHROW, ROLE_REV, ROLE_REVENANT, ROLE_REV_HEAD, ROLE_SYNDICATE, diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 7f546f5a6e7d..5123eed0be58 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -78,13 +78,6 @@ else message_admins("[key_name_admin(usr)] tried to create changelings. Unfortunately, there were no candidates available.") log_admin("[key_name(usr)] failed to create changelings.") - if("cult") - if(src.makeCult()) - message_admins("[key_name(usr)] started a cult.") - log_admin("[key_name(usr)] started a cult.") - else - message_admins("[key_name_admin(usr)] tried to start a cult. Unfortunately, there were no candidates available.") - log_admin("[key_name(usr)] failed to start a cult.") if("wizard") message_admins("[key_name(usr)] is creating a wizard...") if(src.makeWizard()) @@ -350,14 +343,6 @@ M.change_mob_type(/mob/living/simple_animal/parrot , null, null, delmob) if("polyparrot") M.change_mob_type(/mob/living/simple_animal/parrot/Polly , null, null, delmob) - if("constructjuggernaut") - M.change_mob_type(/mob/living/simple_animal/hostile/construct/juggernaut , null, null, delmob) - if("constructartificer") - M.change_mob_type(/mob/living/simple_animal/hostile/construct/artificer , null, null, delmob) - if("constructwraith") - M.change_mob_type(/mob/living/simple_animal/hostile/construct/wraith , null, null, delmob) - if("shade") - M.change_mob_type(/mob/living/simple_animal/shade , null, null, delmob) else if(href_list["boot2"]) if(!check_rights(R_ADMIN)) @@ -1140,12 +1125,6 @@ return output_ai_laws() - else if(href_list["admincheckdevilinfo"]) - if(!check_rights(R_ADMIN)) - return - var/mob/M = locate(href_list["admincheckdevilinfo"]) - output_devil_info(M) - else if(href_list["adminmoreinfo"]) var/mob/M = locate(href_list["adminmoreinfo"]) in GLOB.mob_list if(!ismob(M)) diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index abdecf91de60..e30519342ffb 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -16,7 +16,6 @@ var/dat = {" Make Traitors
Make Changelings
- Make Cult
Make Wizard (Requires Ghosts)
Make Nuke Team (Requires Ghosts)
Make Response Team (Requires Ghosts)
@@ -113,38 +112,6 @@ new_character.mind.make_Wizard() return TRUE - -/datum/admins/proc/makeCult() - var/datum/game_mode/cult/temp = new - if(CONFIG_GET(flag/protect_roles_from_antagonist)) - temp.restricted_jobs += temp.protected_jobs - - if(CONFIG_GET(flag/protect_assistant_from_antagonist)) - temp.restricted_jobs += "Assistant" - - var/list/mob/living/carbon/human/candidates = list() - var/mob/living/carbon/human/H = null - - for(var/mob/living/carbon/human/applicant in GLOB.player_list) - if(isReadytoRumble(applicant, ROLE_CULTIST)) - if(temp.age_check(applicant.client)) - if(!(applicant.job in temp.restricted_jobs)) - candidates += applicant - - if(candidates.len) - var/numCultists = min(candidates.len, 4) - - for(var/i = 0, iYou are feeling far too docile to do that.") return - if(iscultist(victim) || HAS_TRAIT(victim, TRAIT_MINDSHIELD)) - to_chat(src, "[victim]'s mind seems to be blocked by some unknown force!") - return - else log_game("[src]/([src.ckey]) assumed control of [victim]/([victim.ckey] with borer powers.") diff --git a/code/modules/antagonists/cult/blood_magic.dm b/code/modules/antagonists/cult/blood_magic.dm deleted file mode 100644 index b4bfb265386d..000000000000 --- a/code/modules/antagonists/cult/blood_magic.dm +++ /dev/null @@ -1,803 +0,0 @@ -/datum/action/innate/cult/blood_magic //Blood magic handles the creation of blood spells (formerly talismans) - name = "Prepare Blood Magic" - button_icon_state = "carve" - desc = "Prepare blood magic by carving runes into your flesh. This is easier with an empowering rune." - var/list/spells = list() - var/channeling = FALSE - -/datum/action/innate/cult/blood_magic/Grant() - ..() - button.screen_loc = DEFAULT_BLOODSPELLS - button.moved = DEFAULT_BLOODSPELLS - button.ordered = FALSE - -/datum/action/innate/cult/blood_magic/Remove() - for(var/X in spells) - qdel(X) - ..() - -/datum/action/innate/cult/blood_magic/IsAvailable() - if(!iscultist(owner)) - return FALSE - return ..() - -/datum/action/innate/cult/blood_magic/proc/Positioning() - var/list/screen_loc_split = splittext(button.screen_loc,",") - var/list/screen_loc_X = splittext(screen_loc_split[1],":") - var/list/screen_loc_Y = splittext(screen_loc_split[2],":") - var/pix_X = text2num(screen_loc_X[2]) - for(var/datum/action/innate/cult/blood_spell/B in spells) - if(B.button.locked) - var/order = pix_X+spells.Find(B)*31 - B.button.screen_loc = "[screen_loc_X[1]]:[order],[screen_loc_Y[1]]:[screen_loc_Y[2]]" - B.button.moved = B.button.screen_loc - -/datum/action/innate/cult/blood_magic/Activate() - var/rune = FALSE - var/limit = RUNELESS_MAX_BLOODCHARGE - for(var/obj/effect/rune/empower/R in range(1, owner)) - rune = TRUE - break - if(rune) - limit = MAX_BLOODCHARGE - if(spells.len >= limit) - if(rune) - to_chat(owner, "You cannot store more than [MAX_BLOODCHARGE] spells. Pick a spell to remove.") - else - to_chat(owner, "You cannot store more than [RUNELESS_MAX_BLOODCHARGE] spells without an empowering rune! Pick a spell to remove.
Deals [health_cost] damage to your arm per use." - base_desc = desc - desc += "
Has [charges] use\s remaining." - all_magic = BM - ..() - button.locked = TRUE - button.ordered = FALSE - -/datum/action/innate/cult/blood_spell/Remove() - if(all_magic) - all_magic.spells -= src - if(hand_magic) - qdel(hand_magic) - hand_magic = null - ..() - -/datum/action/innate/cult/blood_spell/IsAvailable() - if(!iscultist(owner) || owner.incapacitated() || !charges) - return FALSE - return ..() - -/datum/action/innate/cult/blood_spell/Activate() - if(magic_path) //If this spell flows from the hand - if(!hand_magic) - hand_magic = new magic_path(owner, src) - if(!owner.put_in_hands(hand_magic)) - qdel(hand_magic) - hand_magic = null - to_chat(owner, "You have no empty hand for invoking blood magic!") - return - to_chat(owner, "Your wounds glow as you invoke the [name].") - return - if(hand_magic) - qdel(hand_magic) - hand_magic = null - to_chat(owner, "You snuff out the spell, saving it for later.") - - -//Cult Blood Spells -/datum/action/innate/cult/blood_spell/stun - name = "Stun" - desc = "Empowers your hand to stun and mute a victim on contact." - button_icon_state = "hand" - magic_path = "/obj/item/melee/blood_magic/stun" - health_cost = 10 - -/datum/action/innate/cult/blood_spell/teleport - name = "Teleport" - desc = "Empowers your hand to teleport yourself or another cultist to a teleport rune on contact." - button_icon_state = "tele" - magic_path = "/obj/item/melee/blood_magic/teleport" - health_cost = 7 - -/datum/action/innate/cult/blood_spell/emp - name = "Electromagnetic Pulse" - desc = "Emits a large electromagnetic pulse." - button_icon_state = "emp" - health_cost = 10 - invocation = "Ta'gh fara'qha fel d'amar det!" - -/datum/action/innate/cult/blood_spell/emp/Activate() - owner.visible_message( - "[owner]'s hand flashes a bright blue!", \ - "You speak the cursed words, emitting an EMP blast from your hand.") - empulse(owner, 2, 5) - owner.whisper(invocation, language = /datum/language/common) - charges-- - if(charges<=0) - qdel(src) - -/datum/action/innate/cult/blood_spell/shackles - name = "Shadow Shackles" - desc = "Empowers your hand to start handcuffing victim on contact, and mute them if successful." - button_icon_state = "cuff" - charges = 4 - magic_path = "/obj/item/melee/blood_magic/shackles" - -/datum/action/innate/cult/blood_spell/construction - name = "Twisted Construction" - desc = "Empowers your hand to corrupt certain metalic objects.
Converts:
Plasteel into runed metal
50 metal into a construct shell
Living cyborgs into constructs after a delay
Cyborg shells into construct shells
Airlocks into brittle runed airlocks after a delay (harm intent)" - button_icon_state = "transmute" - magic_path = "/obj/item/melee/blood_magic/construction" - health_cost = 12 - -/datum/action/innate/cult/blood_spell/horror - name = "Hallucinations" - desc = "Gives hallucinations to a target at range. A silent and invisible spell." - button_icon_state = "horror" - var/obj/effect/proc_holder/horror/PH - charges = 4 - -/datum/action/innate/cult/blood_spell/horror/New() - PH = new() - PH.attached_action = src - ..() - -/datum/action/innate/cult/blood_spell/horror/Destroy() - var/obj/effect/proc_holder/horror/destroy = PH - . = ..() - if(destroy && !QDELETED(destroy)) - QDEL_NULL(destroy) - -/datum/action/innate/cult/blood_spell/horror/Activate() - PH.toggle(owner) //the important bit - return TRUE - -/obj/effect/proc_holder/horror - active = FALSE - ranged_mousepointer = 'icons/effects/mouse_pointers/cult_target.dmi' - var/datum/action/innate/cult/blood_spell/attached_action - -/obj/effect/proc_holder/horror/Destroy() - var/datum/action/innate/cult/blood_spell/AA = attached_action - . = ..() - if(AA && !QDELETED(AA)) - QDEL_NULL(AA) - -/obj/effect/proc_holder/horror/proc/toggle(mob/user) - if(active) - remove_ranged_ability("You dispel the magic...") - else - add_ranged_ability(user, "You prepare to horrify a target...") - -/obj/effect/proc_holder/horror/InterceptClickOn(mob/living/caller, params, atom/target) - if(..()) - return - if(ranged_ability_user.incapacitated() || !iscultist(caller)) - remove_ranged_ability() - return - var/turf/T = get_turf(ranged_ability_user) - if(!isturf(T)) - return FALSE - if(target in view(7, get_turf(ranged_ability_user))) - if(!ishuman(target) || iscultist(target)) - return - var/mob/living/carbon/human/H = target - H.hallucination = max(H.hallucination, 120) - SEND_SOUND(ranged_ability_user, sound('sound/effects/ghost.ogg',0,1,50)) - var/image/C = image('icons/effects/cult_effects.dmi',H,"bloodsparkles", ABOVE_MOB_LAYER) - add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/cult, "cult_apoc", C, NONE) - addtimer(CALLBACK(H, TYPE_PROC_REF(/atom, remove_alt_appearance),"cult_apoc",TRUE), 2400, TIMER_OVERRIDE|TIMER_UNIQUE) - to_chat(ranged_ability_user,"[H] has been cursed with living nightmares!") - attached_action.charges-- - attached_action.desc = attached_action.base_desc - attached_action.desc += "
Has [attached_action.charges] use\s remaining." - attached_action.UpdateButtonIcon() - if(attached_action.charges <= 0) - remove_ranged_ability("You have exhausted the spell's power!") - qdel(src) - -/datum/action/innate/cult/blood_spell/veiling - name = "Conceal Presence" - desc = "Alternates between hiding and revealing nearby cult structures and runes." - invocation = "Kla'atu barada nikt'o!" - button_icon_state = "gone" - charges = 10 - var/revealing = FALSE //if it reveals or not - -/datum/action/innate/cult/blood_spell/veiling/Activate() - if(!revealing) - owner.visible_message("Thin grey dust falls from [owner]'s hand!", \ - "You invoke the veiling spell, hiding nearby runes.") - charges-- - SEND_SOUND(owner, sound('sound/magic/smoke.ogg',0,1,25)) - owner.whisper(invocation, language = /datum/language/common) - for(var/obj/effect/rune/R in range(5,owner)) - R.conceal() - for(var/obj/structure/destructible/cult/S in range(5,owner)) - 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" - else - owner.visible_message( - "A flash of light shines from [owner]'s hand!", \ - "You invoke the counterspell, revealing nearby runes.") - charges-- - owner.whisper(invocation, language = /datum/language/common) - 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(6,owner)) - S.reveal() - 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" - if(charges<= 0) - qdel(src) - desc = base_desc - desc += "
Has [charges] use\s remaining." - UpdateButtonIcon() - -/datum/action/innate/cult/blood_spell/manipulation - name = "Blood Rites" - desc = "Empowers your hand to absorb blood to be used for advanced rites, or heal a cultist on contact. Use the spell in-hand to cast advanced rites." - invocation = "Fel'th Dol Ab'orod!" - button_icon_state = "manip" - charges = 5 - magic_path = "/obj/item/melee/blood_magic/manipulator" - - -// The "magic hand" items -/obj/item/melee/blood_magic - name = "\improper magical aura" - desc = "A sinister looking aura that distorts the flow of reality around it." - icon = 'icons/obj/items.dmi' - lefthand_file = 'icons/mob/inhands/misc/touchspell_lefthand.dmi' - righthand_file = 'icons/mob/inhands/misc/touchspell_righthand.dmi' - icon_state = "disintegrate" - item_state = "disintegrate" - item_flags = NEEDS_PERMIT | ABSTRACT | DROPDEL - - w_class = WEIGHT_CLASS_HUGE - throwforce = 0 - throw_range = 0 - throw_speed = 0 - var/invocation - var/uses = 1 - var/health_cost = 0 //The amount of health taken from the user when invoking the spell - var/datum/action/innate/cult/blood_spell/source - -/obj/item/melee/blood_magic/New(loc, spell) - if(spell) - source = spell - uses = source.charges - health_cost = source.health_cost - ..() - -/obj/item/melee/blood_magic/Destroy() - if(!QDELETED(source)) - if(uses <= 0) - source.hand_magic = null - qdel(source) - source = null - else - source.hand_magic = null - source.charges = uses - source.desc = source.base_desc - source.desc += "
Has [uses] use\s remaining." - source.UpdateButtonIcon() - return ..() - -/obj/item/melee/blood_magic/attack_self(mob/living/user) - afterattack(user, user, TRUE) - -/obj/item/melee/blood_magic/attack(mob/living/M, mob/living/carbon/user) - if(!iscarbon(user) || !iscultist(user)) - uses = 0 - qdel(src) - return - log_combat(user, M, "used a cult spell on", source.name, "") - M.lastattacker = user.real_name - M.lastattackerckey = user.ckey - -/obj/item/melee/blood_magic/afterattack(atom/target, mob/living/carbon/user, proximity) - . = ..() - if(invocation) - user.whisper(invocation, language = /datum/language/common) - if(health_cost) - if(user.active_hand_index == 1) - user.apply_damage(health_cost, BRUTE, BODY_ZONE_L_ARM) - else - user.apply_damage(health_cost, BRUTE, BODY_ZONE_R_ARM) - if(uses <= 0) - qdel(src) - else if(source) - source.desc = source.base_desc - source.desc += "
Has [uses] use\s remaining." - source.UpdateButtonIcon() - -//Stun -/obj/item/melee/blood_magic/stun - name = "Stunning Aura" - desc = "Will stun and mute a weak-minded victim on contact." - color = RUNE_COLOR_RED - invocation = "Fuu ma'jin!" - -/obj/item/melee/blood_magic/stun/afterattack(atom/target, mob/living/carbon/user, proximity) - if(!isliving(target) || !proximity) - return - var/mob/living/L = target - if(iscultist(target)) - return - if(iscultist(user)) - user.visible_message("[user] holds up [user.p_their()] hand, which explodes in a flash of red light!", \ - "You attempt to stun [L] with the spell!") - - user.mob_light(_range = 3, _color = LIGHT_COLOR_BLOOD_MAGIC, _duration = 0.2 SECONDS) - - var/anti_magic_source = L.anti_magic_check() - if(anti_magic_source) - - L.mob_light(_range = 2, _color = LIGHT_COLOR_HOLY_MAGIC, _duration = 10 SECONDS) - var/mutable_appearance/forbearance = mutable_appearance('icons/effects/genetics.dmi', "servitude", -MUTATIONS_LAYER) - L.add_overlay(forbearance) - addtimer(CALLBACK(L, TYPE_PROC_REF(/atom, cut_overlay), forbearance), 100) - - if(istype(anti_magic_source, /obj/item)) - var/obj/item/ams_object = anti_magic_source - target.visible_message( - "[L] starts to glow in a halo of light!", \ - "Your [ams_object.name] begins to glow, emitting a blanket of holy light which surrounds you and protects you from the flash of light!") - else - target.visible_message( - "[L] starts to glow in a halo of light!", \ - "A feeling of warmth washes over you, rays of holy light surround your body and protect you from the flash of light!") - - else - if(HAS_TRAIT(target, TRAIT_MINDSHIELD)) - var/mob/living/carbon/C = L - to_chat(user, "Their mind was stronger than expected, but you still managed to do some damage!") - C.stuttering += 8 - C.dizziness += 30 - C.Jitter(8) - C.drop_all_held_items() - C.bleed(40) - C.apply_damage(60, STAMINA, BODY_ZONE_CHEST) - else - to_chat(user, "In a brilliant flash of red, [L] falls to the ground!") - L.Paralyze(160) - L.flash_act(1,1) - if(issilicon(target)) - var/mob/living/silicon/S = L - S.emp_act(EMP_HEAVY) - else if(iscarbon(target)) - var/mob/living/carbon/C = L - C.silent += 6 - C.stuttering += 15 - C.cultslurring += 15 - C.Jitter(15) - uses-- - ..() - -//Teleportation -/obj/item/melee/blood_magic/teleport - name = "Teleporting Aura" - color = RUNE_COLOR_TELEPORT - desc = "Will teleport a cultist to a teleport rune on contact." - invocation = "Sas'so c'arta forbici!" - -/obj/item/melee/blood_magic/teleport/afterattack(atom/target, mob/living/carbon/user, proximity) - if(!iscultist(target) || !proximity) - to_chat(user, "You can only teleport adjacent cultists with this spell!") - return - if(iscultist(user)) - var/list/potential_runes = list() - var/list/teleportnames = list() - for(var/R in GLOB.teleport_runes) - var/obj/effect/rune/teleport/T = R - potential_runes[avoid_assoc_duplicate_keys(T.listkey, teleportnames)] = T - - if(!potential_runes.len) - to_chat(user, "There are no valid runes to teleport to!") - log_game("Teleport talisman failed - no other teleport runes") - return - - var/turf/T = get_turf(src) - if(is_away_level(T)) - to_chat(user, "You are not in the right dimension!") - log_game("Teleport spell failed - user in away mission") - return - - var/input_rune_key = input(user, "Choose a rune to teleport to.", "Rune to Teleport to") as null|anything in potential_runes //we know what key they picked - var/obj/effect/rune/teleport/actual_selected_rune = potential_runes[input_rune_key] //what rune does that key correspond to? - if(QDELETED(src) || !user || !user.is_holding(src) || user.incapacitated() || !actual_selected_rune || !proximity) - return - var/turf/dest = get_turf(actual_selected_rune) - if(dest.is_blocked_turf(TRUE)) - to_chat(user, "The target rune is blocked. You cannot teleport there.") - return - uses-- - var/turf/origin = get_turf(user) - var/mob/living/L = target - if(do_teleport(L, dest, channel = TELEPORT_CHANNEL_CULT)) - origin.visible_message("Dust flows from [user]'s hand, and [user.p_they()] disappear[user.p_s()] with a sharp crack!", \ - "You speak the words of the talisman and find yourself somewhere else!", "You hear a sharp crack.") - dest.visible_message("There is a boom of outrushing air as something appears above the rune!", null, "You hear a boom.") - ..() - -//Shackles -/obj/item/melee/blood_magic/shackles - name = "Shackling Aura" - desc = "Will start handcuffing a victim on contact, and mute them if successful." - invocation = "In'totum Lig'abis!" - color = "#000000" // black - -/obj/item/melee/blood_magic/shackles/afterattack(atom/target, mob/living/carbon/user, proximity) - if(iscultist(user) && iscarbon(target) && proximity) - var/mob/living/carbon/C = target - if(C.canBeHandcuffed()) - CuffAttack(C, user) - else - user.visible_message("This victim doesn't have enough arms to complete the restraint!") - return - ..() - -/obj/item/melee/blood_magic/shackles/proc/CuffAttack(mob/living/carbon/C, mob/living/user) - if(!C.handcuffed) - playsound(loc, 'sound/weapons/cablecuff.ogg', 30, TRUE, -2) - C.visible_message("[user] begins restraining [C] with dark magic!", \ - "[user] begins shaping dark magic shackles around your wrists!") - if(do_after(user, 3 SECONDS, C)) - if(!C.handcuffed) - C.set_handcuffed(new /obj/item/restraints/handcuffs/energy/cult/used(C)) - C.update_handcuffed() - C.silent += 5 - to_chat(user, "You shackle [C].") - log_combat(user, C, "shackled") - uses-- - else - to_chat(user, "[C] is already bound.") - else - to_chat(user, "You fail to shackle [C].") - else - to_chat(user, "[C] is already bound.") - - -/obj/item/restraints/handcuffs/energy/cult //For the shackling spell - name = "shadow shackles" - desc = "Shackles that bind the wrists with sinister magic." - trashtype = /obj/item/restraints/handcuffs/energy/used - item_flags = DROPDEL - -/obj/item/restraints/handcuffs/energy/cult/used/dropped(mob/user) - user.visible_message("[user]'s shackles shatter in a discharge of dark magic!", \ - "Your [src] shatters in a discharge of dark magic!") - . = ..() - - -//Construction: Converts 50 metal to a construct shell, plasteel to runed metal, airlock to brittle runed airlock, a borg to a construct, or borg shell to a construct shell -/obj/item/melee/blood_magic/construction - name = "Twisting Aura" - desc = "Corrupts certain metalic objects on contact." - invocation = "Ethra p'ni dedol!" - color = "#000000" // black - var/channeling = FALSE - -/obj/item/melee/blood_magic/construction/examine(mob/user) - . = ..() - . += {"A sinister spell used to convert:\n - Plasteel into runed metal\n - [METAL_TO_CONSTRUCT_SHELL_CONVERSION] metal into a construct shell\n - Living cyborgs into constructs after a delay\n - Cyborg shells into construct shells\n - Airlocks into brittle runed airlocks after a delay (harm intent)"} - -/obj/item/melee/blood_magic/construction/afterattack(atom/target, mob/user, proximity_flag, click_parameters) - if(proximity_flag && iscultist(user)) - if(channeling) - to_chat(user, "You are already invoking twisted construction!") - return - var/turf/T = get_turf(target) - if(istype(target, /obj/item/stack/sheet/metal)) - var/obj/item/stack/sheet/candidate = target - if(candidate.use(METAL_TO_CONSTRUCT_SHELL_CONVERSION)) - uses-- - to_chat(user, "A dark cloud emanates 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 [METAL_TO_CONSTRUCT_SHELL_CONVERSION] metal to produce a construct shell!") - return - else if(istype(target, /obj/item/stack/sheet/plasteel)) - var/obj/item/stack/sheet/plasteel/candidate = target - var/quantity = candidate.amount - if(candidate.use(quantity)) - uses -- - new /obj/item/stack/sheet/mineral/hidden/hellstone(T,quantity) - to_chat(user, "A dark cloud emanates from you hand and swirls around the plasteel, transforming it into runed metal!") - SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) - else if(istype(target,/mob/living/silicon/robot)) - var/mob/living/silicon/robot/candidate = target - if(candidate.mmi) - channeling = TRUE - user.visible_message("A dark cloud emanates from [user]'s hand and swirls around [candidate]!") - playsound(T, 'sound/machines/creaking.ogg', 80, TRUE) - var/prev_color = candidate.color - candidate.color = "black" - if(do_after(user, 90, target = candidate)) - candidate.emp_act(EMP_HEAVY) - var/list/constructs = list( - "Juggernaut" = image(icon = 'icons/mob/cult.dmi', icon_state = "juggernaut"), - "Wraith" = image(icon = 'icons/mob/cult.dmi', icon_state = "wraith"), - "Artificer" = image(icon = 'icons/mob/cult.dmi', icon_state = "artificer") - ) - var/construct_class = show_radial_menu(user, src, constructs, custom_check = CALLBACK(src, PROC_REF(check_menu), user), require_near = TRUE, tooltips = TRUE) - if(!check_menu(user)) - return - if(QDELETED(candidate)) - channeling = FALSE - return - user.visible_message("The dark cloud recedes from what was formerly [candidate], revealing a\n [construct_class]!") - switch(construct_class) - if("Juggernaut") - makeNewConstruct(/mob/living/simple_animal/hostile/construct/juggernaut, candidate, user, 0, T) - if("Wraith") - makeNewConstruct(/mob/living/simple_animal/hostile/construct/wraith, candidate, user, 0, T) - if("Artificer") - makeNewConstruct(/mob/living/simple_animal/hostile/construct/artificer, candidate, user, 0, T) - else - return - uses-- - candidate.mmi = null - qdel(candidate) - channeling = FALSE - else - channeling = FALSE - candidate.color = prev_color - return - else - uses-- - to_chat(user, "A dark cloud emanates 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)) - qdel(candidate) - else if(istype(target,/obj/machinery/door/airlock)) - channeling = TRUE - playsound(T, 'sound/machines/airlockforced.ogg', 50, TRUE) - do_sparks(5, TRUE, target) - if(do_after(user, 50, target = user)) - if(QDELETED(target)) - channeling = FALSE - return - target.narsie_act() - uses-- - user.visible_message("Black ribbons suddenly emanate from [user]'s hand and cling to the airlock - twisting and corrupting it!") - SEND_SOUND(user, sound('sound/effects/magic.ogg',0,1,25)) - channeling = FALSE - else - channeling = FALSE - return - else - to_chat(user, "The spell will not work on [target]!") - return - ..() - -/obj/item/melee/blood_magic/construction/proc/check_menu(mob/user) - if(!istype(user)) - return FALSE - if(user.incapacitated() || !user.Adjacent(src)) - return FALSE - return TRUE - - -//Armor: Gives the target a basic cultist combat loadout -/obj/item/melee/blood_magic/armor - name = "Arming Aura" - desc = "Will equipt cult combat gear onto a cultist on contact." - color = "#33cc33" // green - -/obj/item/melee/blood_magic/armor/afterattack(atom/target, mob/living/carbon/user, proximity) - if(iscarbon(target) && proximity) - uses-- - var/mob/living/carbon/C = target - C.visible_message("Otherworldly armor suddenly appears on [C]!") - C.equip_to_slot_or_del(new /obj/item/clothing/under/color/black,ITEM_SLOT_ICLOTHING) - C.equip_to_slot_or_del(new /obj/item/clothing/suit/hooded/cultrobes/alt(user), ITEM_SLOT_OCLOTHING) - C.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult/alt(user), ITEM_SLOT_FEET) - C.equip_to_slot_or_del(new /obj/item/storage/backpack/cultpack(user), ITEM_SLOT_BACK) - if(C == user) - qdel(src) //Clears the hands - C.put_in_hands(new /obj/item/restraints/legcuffs/bola/cult(user)) - ..() - -/obj/item/melee/blood_magic/manipulator - name = "Blood Rite Aura" - desc = "Absorbs blood from anything you touch. Touching cultists and constructs can heal them. Use in-hand to cast an advanced rite." - color = "#7D1717" - -/obj/item/melee/blood_magic/manipulator/examine(mob/user) - . = ..() - . += "Blood spear, blood bolt barrage, and blood beam cost [BLOOD_SPEAR_COST], [BLOOD_BARRAGE_COST], and [BLOOD_BEAM_COST] charges respectively." - -/obj/item/melee/blood_magic/manipulator/afterattack(atom/target, mob/living/carbon/human/user, proximity) - if(proximity) - if(ishuman(target)) - var/mob/living/carbon/human/H = target - if(NOBLOOD in H.dna.species.species_traits) - to_chat(user,"Blood rites do not work on species with no blood!") - return - if(iscultist(H)) - if(H.stat == DEAD) - to_chat(user,"Only a revive rune can bring back the dead!") - return - if(H.blood_volume < BLOOD_VOLUME_SAFE) - var/restore_blood = BLOOD_VOLUME_SAFE - H.blood_volume - if(uses*2 < restore_blood) - H.blood_volume += uses*2 - to_chat(user,"You use the last of your blood rites to restore what blood you could!") - uses = 0 - return ..() - else - H.blood_volume = BLOOD_VOLUME_SAFE - uses -= round(restore_blood/2) - to_chat(user,"Your blood rites have restored [H == user ? "your" : "[H.p_their()]"] blood to safe levels!") - var/overall_damage = H.getBruteLoss() + H.getFireLoss() + H.getToxLoss() + H.getOxyLoss() - if(overall_damage == 0) - to_chat(user,"That cultist doesn't require healing!") - else - var/ratio = uses/overall_damage - if(H == user) - to_chat(user,"Your blood healing is far less efficient when used on yourself!") - ratio *= 0.35 // Healing is half as effective if you can't perform a full heal - uses -= round(overall_damage) // Healing is 65% more "expensive" even if you can still perform the full heal - if(ratio>1) - ratio = 1 - uses -= round(overall_damage) - H.visible_message("[H] is fully healed by [H==user ? "[H.p_their()]":"[H]'s"]'s blood magic!") - else - H.visible_message("[H] is partially healed by [H==user ? "[H.p_their()]":"[H]'s"] blood magic.") - uses = 0 - ratio *= -1 - H.adjustOxyLoss((overall_damage*ratio) * (H.getOxyLoss() / overall_damage), 0) - H.adjustToxLoss((overall_damage*ratio) * (H.getToxLoss() / overall_damage), 0) - H.adjustFireLoss((overall_damage*ratio) * (H.getFireLoss() / overall_damage), 0) - H.adjustBruteLoss((overall_damage*ratio) * (H.getBruteLoss() / overall_damage), 0) - H.updatehealth() - playsound(get_turf(H), 'sound/magic/staff_healing.ogg', 25) - new /obj/effect/temp_visual/cult/sparks(get_turf(H)) - user.Beam(H,icon_state="sendbeam",time=15) - else - if(H.stat == DEAD) - to_chat(user,"[H.p_their(TRUE)] blood has stopped flowing, you'll have to find another way to extract it.") - return - if(H.cultslurring) - to_chat(user,"[H.p_their(TRUE)] blood has been tainted by an even stronger form of blood magic, it's no use to us like this!") - return - if(H.blood_volume > BLOOD_VOLUME_SAFE) - H.blood_volume -= 100 - uses += 50 - user.Beam(H,icon_state="drainbeam",time=10) - playsound(get_turf(H), 'sound/magic/enter_blood.ogg', 50) - H.visible_message("[user] drains some of [H]'s blood!") - to_chat(user,"Your blood rite gains 50 charges from draining [H]'s blood.") - new /obj/effect/temp_visual/cult/sparks(get_turf(H)) - else - to_chat(user,"[H.p_theyre(TRUE)] missing too much blood - you cannot drain [H.p_them()] further!") - return - if(isconstruct(target)) - var/mob/living/simple_animal/M = target - var/missing = M.maxHealth - M.health - if(missing) - if(uses > missing) - M.adjustHealth(-missing) - M.visible_message("[M] is fully healed by [user]'s blood magic!") - uses -= missing - else - M.adjustHealth(-uses) - M.visible_message("[M] is partially healed by [user]'s blood magic!") - uses = 0 - playsound(get_turf(M), 'sound/magic/staff_healing.ogg', 25) - user.Beam(M,icon_state="sendbeam",time=10) - if(istype(target, /obj/effect/decal/cleanable/blood)) - blood_draw(target, user) - ..() - -/obj/item/melee/blood_magic/manipulator/proc/blood_draw(atom/target, mob/living/carbon/human/user) - var/temp = 0 - var/turf/T = get_turf(target) - if(T) - for(var/obj/effect/decal/cleanable/blood/B in view(T, 2)) - if(B.blood_state == BLOOD_STATE_HUMAN) - if(B.bloodiness == 100) //Bonus for "pristine" bloodpools, also to prevent cheese with footprint spam - temp += 30 - else - temp += max((B.bloodiness**2)/800,1) - new /obj/effect/temp_visual/cult/turf/floor(get_turf(B)) - qdel(B) - if(temp) - user.Beam(T,icon_state="drainbeam",time=15) - new /obj/effect/temp_visual/cult/sparks(get_turf(user)) - playsound(T, 'sound/magic/enter_blood.ogg', 50) - to_chat(user, "Your blood rite has gained [round(temp)] charge\s from blood sources around you!") - uses += max(1, round(temp)) - -/obj/item/melee/blood_magic/manipulator/attack_self(mob/living/user) - if(iscultist(user)) - var/list/options = list("Blood Beam (500)") - var/choice = input(user, "Choose a greater blood rite...", "Greater Blood Rites") as null|anything in options - if(!choice) - to_chat(user, "You decide against conducting a greater blood rite.") - return - switch(choice) - if("Blood Beam (500)") - if(uses < BLOOD_BEAM_COST) - to_chat(user, "You need [BLOOD_BEAM_COST] charges to perform this rite.") - else - var/obj/rite = new /obj/item/blood_beam() - uses -= BLOOD_BEAM_COST - qdel(src) - if(user.put_in_hands(rite)) - to_chat(user, "Your hands glow with POWER OVERWHELMING!!!") - else - to_chat(user, "You need a free hand for this rite!") - qdel(rite) diff --git a/code/modules/antagonists/cult/cult.dm b/code/modules/antagonists/cult/cult.dm deleted file mode 100644 index d6330b386f29..000000000000 --- a/code/modules/antagonists/cult/cult.dm +++ /dev/null @@ -1,397 +0,0 @@ -#define SUMMON_POSSIBILITIES 3 -#define CULT_VICTORY 1 -#define CULT_LOSS 0 -#define CULT_NARSIE_KILLED -1 - -/datum/antagonist/cult - name = "Cultist" - roundend_category = "cultists" - antagpanel_category = "Cult" - antag_moodlet = /datum/mood_event/cult - var/datum/action/innate/cult/comm/communion = new - var/datum/action/innate/cult/mastervote/vote = new - var/datum/action/innate/cult/blood_magic/magic = new - job_rank = ROLE_CULTIST - antag_hud_type = ANTAG_HUD_CULT - antag_hud_name = "cult" - var/ignore_implant = FALSE - var/give_equipment = FALSE - var/datum/team/cult/cult_team - - -/datum/antagonist/cult/get_team() - return cult_team - -/datum/antagonist/cult/create_team(datum/team/cult/new_team) - if(!new_team) - //todo remove this and allow admin buttons to create more than one cult - for(var/datum/antagonist/cult/H in GLOB.antagonists) - if(!H.owner) - continue - if(H.cult_team) - cult_team = H.cult_team - return - cult_team = new /datum/team/cult - cult_team.setup_objectives() - return - if(!istype(new_team)) - stack_trace("Wrong team type passed to [type] initialization.") - cult_team = new_team - -/datum/antagonist/cult/proc/add_objectives() - objectives |= cult_team.objectives - -/datum/antagonist/cult/Destroy() - QDEL_NULL(communion) - QDEL_NULL(vote) - return ..() - -/datum/antagonist/cult/can_be_owned(datum/mind/new_owner) - . = ..() - if(. && !ignore_implant) - . = is_convertable_to_cult(new_owner.current,cult_team) - -/datum/antagonist/cult/greet() - to_chat(owner, "You are a member of the cult!") - owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/bloodcult.ogg', 100, FALSE, pressure_affected = FALSE, use_reverb = FALSE)//subject to change - owner.announce_objectives() - -/datum/antagonist/cult/on_gain() - . = ..() - var/mob/living/current = owner.current - add_objectives() - if(give_equipment) - equip_cultist() - SSticker.mode.cult += owner // Only add after they've been given objectives - current.log_message("has been converted to the cult of Nar'Sie!", LOG_ATTACK, color="#960000") - - if(cult_team.blood_target && cult_team.blood_target_image && current.client) - current.client.images += cult_team.blood_target_image - - -/datum/antagonist/cult/proc/equip_cultist() - var/mob/living/carbon/H = owner.current - if(!istype(H)) - return - to_chat(owner, "These will help you jumpstart a cult of your own in this sector. Use them well, and remember - you are not the only one.") - - -/datum/antagonist/cult/proc/cult_give_item(obj/item/item_path, mob/living/carbon/human/mob) - var/list/slots = list( - "backpack" = ITEM_SLOT_BACKPACK, - "left pocket" = ITEM_SLOT_LPOCKET, - "right pocket" = ITEM_SLOT_RPOCKET - ) - - var/T = new item_path(mob) - var/item_name = initial(item_path.name) - var/where = mob.equip_in_one_of_slots(T, slots) - if(!where) - to_chat(mob, "Unfortunately, you weren't able to get a [item_name]. This is very bad and you should adminhelp immediately (press F1).") - return 0 - else - to_chat(mob, "You have a [item_name] in your [where].") - if(where == "backpack") - SEND_SIGNAL(mob.back, COMSIG_TRY_STORAGE_SHOW, mob) - return TRUE - -/datum/antagonist/cult/apply_innate_effects(mob/living/mob_override) - . = ..() - var/mob/living/current = owner.current - if(mob_override) - current = mob_override - add_antag_hud(antag_hud_type, antag_hud_name, current) - handle_clown_mutation(current, mob_override ? null : "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.") - current.faction |= "cult" - current.grant_language(/datum/language/narsie, TRUE, TRUE, LANGUAGE_CULTIST) - if(!cult_team.cult_master) - vote.Grant(current) - communion.Grant(current) - if(ishuman(current)) - magic.Grant(current) - current.throw_alert("bloodsense", /atom/movable/screen/alert/bloodsense) - if(cult_team.cult_risen) - cult_team.rise(current) - if(cult_team.cult_ascendent) - cult_team.ascend(current) - -/datum/antagonist/cult/remove_innate_effects(mob/living/mob_override) - . = ..() - var/mob/living/current = owner.current - if(mob_override) - current = mob_override - remove_antag_hud(antag_hud_type, current) - handle_clown_mutation(current, removing = FALSE) - current.faction -= "cult" - current.remove_language(/datum/language/narsie, TRUE, TRUE, LANGUAGE_CULTIST) - vote.Remove(current) - communion.Remove(current) - magic.Remove(current) - current.clear_alert("bloodsense") - if(ishuman(current)) - var/mob/living/carbon/human/H = current - H.eye_color = initial(H.eye_color) - H.dna.update_ui_block(DNA_EYE_COLOR_BLOCK) - REMOVE_TRAIT(H, CULT_EYES, null) - H.remove_overlay(HALO_LAYER) - H.update_body() - -/datum/antagonist/cult/on_removal() - SSticker.mode.cult -= owner - if(!silent) - owner.current.visible_message(" ", null, null, null, owner.current) - to_chat(owner.current, "An unfamiliar white light flashes through your mind, cleansing the taint of the Geometer and all your memories as her servant.") - owner.current.log_message("has renounced the cult of Nar'Sie!", LOG_ATTACK, color="#960000") - if(cult_team.blood_target && cult_team.blood_target_image && owner.current.client) - owner.current.client.images -= cult_team.blood_target_image - . = ..() - -/datum/antagonist/cult/admin_add(datum/mind/new_owner,mob/admin) - give_equipment = FALSE - new_owner.add_antag_datum(src) - message_admins("[key_name_admin(admin)] has cult'ed [key_name_admin(new_owner)].") - log_admin("[key_name(admin)] has cult'ed [key_name(new_owner)].") - -/datum/antagonist/cult/admin_remove(mob/user) - message_admins("[key_name_admin(user)] has decult'ed [key_name_admin(owner)].") - log_admin("[key_name(user)] has decult'ed [key_name(owner)].") - SSticker.mode.remove_cultist(owner,silent=TRUE) //disgusting - -/datum/antagonist/cult/get_admin_commands() - . = ..() - .["Dagger"] = CALLBACK(src, PROC_REF(admin_give_dagger)) - .["Metal"] = CALLBACK(src, PROC_REF(admin_take_all)) - -/datum/antagonist/cult/proc/admin_give_dagger(mob/admin) - if(!equip_cultist()) - to_chat(admin, "Spawning dagger failed!") - -/datum/antagonist/cult/proc/admin_take_all(mob/admin) - return - -/datum/antagonist/cult/master - ignore_implant = TRUE - show_in_antagpanel = FALSE //Feel free to add this later - var/datum/action/innate/cult/master/finalreck/reckoning = new - var/datum/action/innate/cult/master/cultmark/bloodmark = new - var/datum/action/innate/cult/master/pulse/throwing = new - -/datum/antagonist/cult/master/Destroy() - QDEL_NULL(reckoning) - QDEL_NULL(bloodmark) - QDEL_NULL(throwing) - return ..() - -/datum/antagonist/cult/master/on_gain() - . = ..() - var/mob/living/current = owner.current - set_antag_hud(current, "cultmaster") - -/datum/antagonist/cult/master/greet() - to_chat(owner.current, "You are the cult's Master. As the cult's Master, you have a unique title and loud voice when communicating, are capable of marking \ - targets, such as a location or a noncultist, to direct the cult to them, and, finally, you are capable of summoning the entire living cult to your location once.") - to_chat(owner.current, "Use these abilities to direct the cult to victory at any cost.") - -/datum/antagonist/cult/master/apply_innate_effects(mob/living/mob_override) - . = ..() - var/mob/living/current = owner.current - if(mob_override) - current = mob_override - if(!cult_team.reckoning_complete) - reckoning.Grant(current) - bloodmark.Grant(current) - throwing.Grant(current) - current.update_action_buttons_icon() - current.apply_status_effect(/datum/status_effect/cult_master) - if(cult_team.cult_risen) - cult_team.rise(current) - if(cult_team.cult_ascendent) - cult_team.ascend(current) - -/datum/antagonist/cult/master/remove_innate_effects(mob/living/mob_override) - . = ..() - var/mob/living/current = owner.current - if(mob_override) - current = mob_override - reckoning.Remove(current) - bloodmark.Remove(current) - throwing.Remove(current) - current.update_action_buttons_icon() - current.remove_status_effect(/datum/status_effect/cult_master) - - if(ishuman(current)) - var/mob/living/carbon/human/H = current - H.eye_color = initial(H.eye_color) - H.dna.update_ui_block(DNA_EYE_COLOR_BLOCK) - REMOVE_TRAIT(H, CULT_EYES, null) - H.remove_overlay(HALO_LAYER) - H.update_body() - -/datum/team/cult - name = "Cult" - - var/blood_target - var/image/blood_target_image - var/blood_target_reset_timer - - var/cult_vote_called = FALSE - var/mob/living/cult_master - var/reckoning_complete = FALSE - var/cult_risen = FALSE - var/cult_ascendent = FALSE - -/datum/team/cult/proc/check_size() - if(cult_ascendent) - return - var/alive = 0 - var/cultplayers = 0 - for(var/I in GLOB.player_list) - var/mob/M = I - if(M.stat != DEAD) - if(iscultist(M)) - ++cultplayers - else - ++alive - var/ratio = cultplayers/alive - if(ratio > CULT_RISEN && !cult_risen) - for(var/datum/mind/B in members) - if(B.current) - SEND_SOUND(B.current, 'sound/hallucinations/i_see_you2.ogg') - to_chat(B.current, "The veil weakens as your cult grows, your eyes begin to glow...") - addtimer(CALLBACK(src, PROC_REF(rise), B.current), 200) - cult_risen = TRUE - - if(ratio > CULT_ASCENDENT && !cult_ascendent) - for(var/datum/mind/B in members) - if(B.current) - SEND_SOUND(B.current, 'sound/hallucinations/im_here1.ogg') - to_chat(B.current, "Your cult is ascendent and the red harvest approaches - you cannot hide your true nature for much longer!!") - addtimer(CALLBACK(src, PROC_REF(ascend), B.current), 200) - cult_ascendent = TRUE - - -/datum/team/cult/proc/rise(cultist) - if(ishuman(cultist)) - var/mob/living/carbon/human/H = cultist - H.eye_color = "f00" - H.dna.update_ui_block(DNA_EYE_COLOR_BLOCK) - ADD_TRAIT(H, CULT_EYES, CULT_TRAIT) - H.update_body() - -/datum/team/cult/proc/ascend(cultist) - if(ishuman(cultist)) - var/mob/living/carbon/human/H = cultist - new /obj/effect/temp_visual/cult/sparks(get_turf(H), H.dir) - var/istate = pick("halo1","halo2","halo3","halo4","halo5","halo6") - var/mutable_appearance/new_halo_overlay = mutable_appearance('icons/effects/32x64.dmi', istate, -HALO_LAYER) - H.overlays_standing[HALO_LAYER] = new_halo_overlay - H.apply_overlay(HALO_LAYER) - -/datum/objective/sacrifice/find_target(dupe_search_range) - if(!istype(team, /datum/team/cult)) - return - var/datum/team/cult/C = team - var/list/target_candidates = list() - for(var/mob/living/carbon/human/player in GLOB.player_list) - if(player.mind && !player.mind.has_antag_datum(/datum/antagonist/cult) && !is_convertable_to_cult(player) && player.stat != DEAD) - target_candidates += player.mind - if(target_candidates.len == 0) - message_admins("Cult Sacrifice: Could not find unconvertible target, checking for convertible target.") - for(var/mob/living/carbon/human/player in GLOB.player_list) - if(player.mind && !player.mind.has_antag_datum(/datum/antagonist/cult) && player.stat != DEAD) - target_candidates += player.mind - listclearnulls(target_candidates) - if(LAZYLEN(target_candidates)) - target = pick(target_candidates) - update_explanation_text() - else - message_admins("Cult Sacrifice: Could not find unconvertible or convertible target. WELP!") - for(var/datum/mind/M in C.members) - if(M.current) - M.current.clear_alert("bloodsense") - M.current.throw_alert("bloodsense", /atom/movable/screen/alert/bloodsense) - -/datum/team/cult/proc/setup_objectives() - var/datum/objective/sacrifice/sac_objective = new - sac_objective.team = src - sac_objective.find_target() - objectives += sac_objective - - var/datum/objective/eldergod/summon_objective = new - summon_objective.team = src - objectives += summon_objective - - -/datum/objective/sacrifice - var/sacced = FALSE - var/sac_image - -/datum/objective/sacrifice/check_completion() - return sacced || completed - -/datum/objective/sacrifice/update_explanation_text() - if(target) - explanation_text = "Sacrifice [target], the [target.assigned_role] via invoking an Offer rune with [target.p_them()] on it and three acolytes around it." - else - explanation_text = "The veil has already been weakened here, proceed to the final objective." - -/datum/objective/eldergod - var/summoned = FALSE - var/killed = FALSE - var/list/summon_spots = list() - -/datum/objective/eldergod/New() - ..() - var/sanity = 0 - while(summon_spots.len < SUMMON_POSSIBILITIES && sanity < 100) - var/area/summon_area = pick(GLOB.sortedAreas - summon_spots) - if(summon_area && (summon_area.area_flags & VALID_TERRITORY)) - summon_spots += summon_area - sanity++ - update_explanation_text() - -/datum/objective/eldergod/update_explanation_text() - explanation_text = "Summon Nar'Sie by invoking the rune 'Summon Nar'Sie'. The summoning can only be accomplished in [english_list(summon_spots)] - where the veil is weak enough for the ritual to begin." - -/datum/objective/eldergod/check_completion() - if(killed) - return CULT_NARSIE_KILLED // You failed so hard that even the code went backwards. - return summoned || completed - -/datum/team/cult/proc/check_cult_victory() - for(var/datum/objective/O in objectives) - if(O.check_completion() == CULT_NARSIE_KILLED) - return CULT_NARSIE_KILLED - else if(!O.check_completion()) - return CULT_LOSS - return CULT_VICTORY - -/datum/team/cult/roundend_report() - var/list/parts = list() - var/victory = check_cult_victory() - - if(victory == CULT_NARSIE_KILLED) // Epic failure, you summoned your god and then someone killed it. - parts += "Nar'sie has been killed! The cult will haunt the universe no longer!" - else if(victory) - parts += "The cult has succeeded! Nar'Sie has snuffed out another torch in the void!" - else - parts += "The staff managed to stop the cult! Dark words and heresy are no match for Nanotrasen's finest!" - - if(objectives.len) - parts += "The cultists' objectives were:" - var/count = 1 - for(var/datum/objective/objective in objectives) - if(objective.check_completion()) - parts += "Objective #[count]: [objective.explanation_text] Success!" - else - parts += "Objective #[count]: [objective.explanation_text] Fail." - count++ - - if(members.len) - parts += "The cultists were:" - parts += printplayerlist(members) - - return "[parts.Join("" - -/datum/team/cult/is_gamemode_hero() - return SSticker.mode.name == "cult" diff --git a/code/modules/antagonists/cult/cult_comms.dm b/code/modules/antagonists/cult/cult_comms.dm deleted file mode 100644 index 0c070e8e423f..000000000000 --- a/code/modules/antagonists/cult/cult_comms.dm +++ /dev/null @@ -1,461 +0,0 @@ -// Contains cult communion, guide, and cult master abilities - -/datum/action/innate/cult - icon_icon = 'icons/mob/actions/actions_cult.dmi' - background_icon_state = "bg_demon" - buttontooltipstyle = "cult" - check_flags = AB_CHECK_HANDS_BLOCKED|AB_CHECK_IMMOBILE|AB_CHECK_CONSCIOUS - -/datum/action/innate/cult/IsAvailable() - if(!iscultist(owner)) - return FALSE - return ..() - -/datum/action/innate/cult/comm - name = "Communion" - desc = "Whispered words that all cultists can hear.
")]
Warning:Nearby non-cultists can still hear you." - button_icon_state = "cult_comms" - -/datum/action/innate/cult/comm/Activate() - var/input = stripped_input(usr, "Please choose a message to tell to the other acolytes.", "Voice of Blood", "") - if(!input || !IsAvailable()) - return - if(CHAT_FILTER_CHECK(input)) - to_chat(usr, "You cannot send a message that contains a word prohibited in IC chat!") - return - cultist_commune(usr, input) - -/datum/action/innate/cult/comm/proc/cultist_commune(mob/living/user, message) - var/my_message - if(!message) - return - user.whisper("O bidai nabora se[pick("'","`")]sma!", language = /datum/language/common) - user.whisper(html_decode(message)) - var/title = "Acolyte" - var/span = "cult italic" - if(user.mind && user.mind.has_antag_datum(/datum/antagonist/cult/master)) - span = "cultlarge" - title = "Master" - else if(!ishuman(user)) - title = "Construct" - my_message = "[title] [findtextEx(user.name, user.real_name) ? user.name : "[user.real_name] (as [user.name])"]: [message]" - for(var/i in GLOB.player_list) - var/mob/M = i - if(iscultist(M)) - to_chat(M, my_message) - else if(M in GLOB.dead_mob_list) - var/link = FOLLOW_LINK(M, user) - to_chat(M, "[link] [my_message]") - - user.log_talk(message, LOG_SAY, tag="cult") - -/datum/action/innate/cult/comm/spirit - name = "Spiritual Communion" - desc = "Conveys a message from the spirit realm that all cultists can hear." - -/datum/action/innate/cult/comm/spirit/IsAvailable() - if(iscultist(owner.mind.current)) - return TRUE - -/datum/action/innate/cult/comm/spirit/cultist_commune(mob/living/user, message) - var/my_message - if(!message) - return - my_message = "The [user.name]: [message]" - for(var/i in GLOB.player_list) - var/mob/M = i - if(iscultist(M)) - to_chat(M, my_message) - else if(M in GLOB.dead_mob_list) - var/link = FOLLOW_LINK(M, user) - to_chat(M, "[link] [my_message]") - -/datum/action/innate/cult/mastervote - name = "Assert Leadership" - button_icon_state = "cultvote" - -/datum/action/innate/cult/mastervote/IsAvailable() - var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE) - if(!C || C.cult_team.cult_vote_called || !ishuman(owner)) - return FALSE - return ..() - -/datum/action/innate/cult/mastervote/Activate() - var/choice = alert(owner, "The mantle of leadership is 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(mob/living/Nominee,datum/team/cult/team) //Cult Master Poll - if(world.time < CULT_POLL_WAIT) - to_chat(Nominee, "It would be premature to select a leader while everyone is still settling in, try again in [DisplayTimeText(CULT_POLL_WAIT-world.time)].") - return - team.cult_vote_called = TRUE //somebody's trying to be a master, make sure we don't let anyone else try - for(var/datum/mind/B in team.members) - if(B.current) - B.current.update_action_buttons_icon() - if(!B.current.incapacitated()) - SEND_SOUND(B.current, 'sound/hallucinations/im_here1.ogg') - to_chat(B.current, "Acolyte [Nominee] has asserted that [Nominee.p_theyre()] worthy of leading the cult. A vote will be called shortly.") - sleep(100) - var/list/asked_cultists = list() - for(var/datum/mind/B in team.members) - if(B.current && B.current != Nominee && !B.current.incapacitated()) - SEND_SOUND(B.current, 'sound/magic/exit_blood.ogg') - asked_cultists += B.current - var/list/yes_voters = pollCandidates("[Nominee] seeks to lead your cult, do you support [Nominee.p_them()]?", poll_time = 300, group = asked_cultists) - if(QDELETED(Nominee) || Nominee.incapacitated()) - team.cult_vote_called = FALSE - for(var/datum/mind/B in team.members) - if(B.current) - B.current.update_action_buttons_icon() - if(!B.current.incapacitated()) - to_chat(B.current,"[Nominee] has died in the process of attempting to win the cult's support!") - return FALSE - if(!Nominee.mind) - team.cult_vote_called = FALSE - for(var/datum/mind/B in team.members) - if(B.current) - B.current.update_action_buttons_icon() - if(!B.current.incapacitated()) - to_chat(B.current,"[Nominee] has gone catatonic in the process of attempting to win the cult's support!") - return FALSE - if(LAZYLEN(yes_voters) <= LAZYLEN(asked_cultists) * 0.5) - team.cult_vote_called = FALSE - for(var/datum/mind/B in team.members) - if(B.current) - B.current.update_action_buttons_icon() - if(!B.current.incapacitated()) - to_chat(B.current, "[Nominee] could not win the cult's support and shall continue to serve as an acolyte.") - return FALSE - team.cult_master = Nominee - SSticker.mode.remove_cultist(Nominee.mind, TRUE) - Nominee.mind.add_antag_datum(/datum/antagonist/cult/master) - for(var/datum/mind/B in team.members) - if(B.current) - for(var/datum/action/innate/cult/mastervote/vote in B.current.actions) - vote.Remove(B.current) - if(!B.current.incapacitated()) - to_chat(B.current,"[Nominee] has won the cult's support and is now their master. Follow [Nominee.p_their()] orders to the best of your ability!") - return TRUE - -/datum/action/innate/cult/master/IsAvailable() - if(!owner.mind || !owner.mind.has_antag_datum(/datum/antagonist/cult/master) || GLOB.cult_narsie) - return 0 - return ..() - -/datum/action/innate/cult/master/finalreck - name = "Final Reckoning" - desc = "A single-use spell that brings the entire cult to the master's location." - button_icon_state = "sintouch" - -/datum/action/innate/cult/master/finalreck/Activate() - var/datum/antagonist/cult/antag = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE) - if(!antag) - return - for(var/i in 1 to 4) - chant(i) - var/list/destinations = list() - for(var/turf/T in orange(1, owner)) - if(!T.is_blocked_turf(TRUE)) - destinations += T - if(!LAZYLEN(destinations)) - to_chat(owner, "You need more space to summon your cult!") - return - if(do_after(owner, 30, target = owner)) - for(var/datum/mind/B in antag.cult_team.members) - if(B.current && B.current.stat != DEAD) - var/turf/mobloc = get_turf(B.current) - switch(i) - if(1) - new /obj/effect/temp_visual/cult/sparks(mobloc, B.current.dir) - playsound(mobloc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - if(2) - new /obj/effect/temp_visual/dir_setting/cult/phase/out(mobloc, B.current.dir) - playsound(mobloc, "sparks", 75, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - if(3) - new /obj/effect/temp_visual/dir_setting/cult/phase(mobloc, B.current.dir) - playsound(mobloc, "sparks", 100, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - if(4) - playsound(mobloc, 'sound/magic/exit_blood.ogg', 100, TRUE) - if(B.current != owner) - var/turf/final = pick(destinations) - if(istype(B.current.loc, /obj/item/soulstone)) - var/obj/item/soulstone/S = B.current.loc - S.release_shades(owner) - B.current.setDir(SOUTH) - new /obj/effect/temp_visual/cult/blood(final) - addtimer(CALLBACK(B.current, TYPE_PROC_REF(/mob, reckon), final), 10) - else - return - antag.cult_team.reckoning_complete = TRUE - Remove(owner) - -/mob/proc/reckon(turf/final) - new /obj/effect/temp_visual/cult/blood/out(get_turf(src)) - forceMove(final) - -/datum/action/innate/cult/master/finalreck/proc/chant(chant_number) - switch(chant_number) - if(1) - owner.say("C'arta forbici!", language = /datum/language/common, forced = "cult invocation") - if(2) - owner.say("Pleggh e'ntrath!", language = /datum/language/common, forced = "cult invocation") - playsound(get_turf(owner),'sound/magic/clockwork/narsie_attack.ogg', 50, TRUE) - if(3) - owner.say("Barhah hra zar'garis!", language = /datum/language/common, forced = "cult invocation") - playsound(get_turf(owner),'sound/magic/clockwork/narsie_attack.ogg', 75, TRUE) - if(4) - owner.say("N'ath reth sh'yro eth d'rekkathnor!!!", language = /datum/language/common, forced = "cult invocation") - playsound(get_turf(owner),'sound/magic/clockwork/narsie_attack.ogg', 100, TRUE) - -/datum/action/innate/cult/master/cultmark - name = "Mark Target" - desc = "Marks a target for the cult." - button_icon_state = "cult_mark" - var/obj/effect/proc_holder/cultmark/CM - var/cooldown = 0 - var/base_cooldown = 1200 - -/datum/action/innate/cult/master/cultmark/New(Target) - CM = new() - CM.attached_action = src - ..() - -/datum/action/innate/cult/master/cultmark/IsAvailable() - if(cooldown > world.time) - if(!CM.active) - to_chat(owner, "You need to wait [DisplayTimeText(cooldown - world.time)] before you can mark another target!") - return FALSE - return ..() - -/datum/action/innate/cult/master/cultmark/Destroy() - QDEL_NULL(CM) - return ..() - -/datum/action/innate/cult/master/cultmark/Activate() - CM.toggle(owner) //the important bit - return TRUE - -/obj/effect/proc_holder/cultmark - active = FALSE - ranged_mousepointer = 'icons/effects/mouse_pointers/cult_target.dmi' - var/datum/action/innate/cult/master/cultmark/attached_action - -/obj/effect/proc_holder/cultmark/Destroy() - attached_action = null - return ..() - -/obj/effect/proc_holder/cultmark/proc/toggle(mob/user) - if(active) - remove_ranged_ability("You cease the marking ritual.") - else - add_ranged_ability(user, "You prepare to mark a target for your cult...") - -/obj/effect/proc_holder/cultmark/InterceptClickOn(mob/living/caller, params, atom/target) - if(..()) - return - if(ranged_ability_user.incapacitated()) - remove_ranged_ability() - return - var/turf/T = get_turf(ranged_ability_user) - if(!isturf(T)) - return FALSE - - var/datum/antagonist/cult/C = caller.mind.has_antag_datum(/datum/antagonist/cult,TRUE) - - if(target in view(7, get_turf(ranged_ability_user))) - if(C.cult_team.blood_target) - to_chat(ranged_ability_user, "The cult has already designated a target!") - return FALSE - C.cult_team.blood_target = target - var/area/A = get_area(target) - attached_action.cooldown = world.time + attached_action.base_cooldown - addtimer(CALLBACK(attached_action.owner, TYPE_PROC_REF(/mob, update_action_buttons_icon)), attached_action.base_cooldown) - C.cult_team.blood_target_image = image('icons/effects/mouse_pointers/cult_target.dmi', target, "glow", ABOVE_MOB_LAYER) - C.cult_team.blood_target_image.appearance_flags = RESET_COLOR - C.cult_team.blood_target_image.pixel_x = -target.pixel_x - C.cult_team.blood_target_image.pixel_y = -target.pixel_y - for(var/datum/mind/B in SSticker.mode.cult) - if(B.current && B.current.stat != DEAD && B.current.client) - to_chat(B.current, "[ranged_ability_user] has marked [C.cult_team.blood_target] in the [A.name] as the cult's top priority, get there immediately!") - SEND_SOUND(B.current, sound(pick('sound/hallucinations/over_here2.ogg','sound/hallucinations/over_here3.ogg'),0,1,75)) - B.current.client.images += C.cult_team.blood_target_image - attached_action.owner.update_action_buttons_icon() - remove_ranged_ability("The marking rite is complete! It will last for 90 seconds.") - C.cult_team.blood_target_reset_timer = addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(reset_blood_target),C.cult_team), 900, TIMER_STOPPABLE) - return TRUE - return FALSE - -/proc/reset_blood_target(datum/team/cult/team) - for(var/datum/mind/B in team.members) - if(B.current && B.current.stat != DEAD && B.current.client) - if(team.blood_target) - to_chat(B.current,"The blood mark has expired!") - B.current.client.images -= team.blood_target_image - QDEL_NULL(team.blood_target_image) - team.blood_target = null - - -/datum/action/innate/cult/master/cultmark/ghost - name = "Mark a Blood Target for the Cult" - desc = "Marks a target for the entire cult to track." - -/datum/action/innate/cult/master/cultmark/ghost/IsAvailable() - if(istype(owner, /mob/dead/observer) && iscultist(owner.mind.current)) - return TRUE - else - qdel(src) - -/datum/action/innate/cult/ghostmark //Ghost version - name = "Blood Mark your Target" - desc = "Marks whatever you are orbitting - for the entire cult to track." - button_icon_state = "cult_mark" - var/tracking = FALSE - var/cooldown = 0 - var/base_cooldown = 600 - -/datum/action/innate/cult/ghostmark/IsAvailable() - if(istype(owner, /mob/dead/observer) && iscultist(owner.mind.current)) - return TRUE - else - qdel(src) - -/datum/action/innate/cult/ghostmark/proc/reset_button() - if(owner) - name = "Blood Mark your Target" - desc = "Marks whatever you are orbitting - for the entire cult to track." - button_icon_state = "cult_mark" - owner.update_action_buttons_icon() - SEND_SOUND(owner, 'sound/magic/enter_blood.ogg') - to_chat(owner,"Your previous mark is gone - you are now ready to create a new blood mark.") - -/datum/action/innate/cult/ghostmark/Activate() - var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE) - if(C.cult_team.blood_target) - if(cooldown>world.time) - reset_blood_target(C.cult_team) - to_chat(owner, "You have cleared the cult's blood target!") - deltimer(C.cult_team.blood_target_reset_timer) - return - else - to_chat(owner, "The cult has already designated a target!") - return - if(cooldown>world.time) - to_chat(owner, "You aren't ready to place another blood mark yet!") - return - target = owner.orbiting?.parent || get_turf(owner) - if(!target) - return - C.cult_team.blood_target = target - var/area/A = get_area(target) - cooldown = world.time + base_cooldown - addtimer(CALLBACK(owner, TYPE_PROC_REF(/mob, update_action_buttons_icon)), base_cooldown) - C.cult_team.blood_target_image = image('icons/effects/mouse_pointers/cult_target.dmi', target, "glow", ABOVE_MOB_LAYER) - C.cult_team.blood_target_image.appearance_flags = RESET_COLOR - C.cult_team.blood_target_image.pixel_x = -target.pixel_x - C.cult_team.blood_target_image.pixel_y = -target.pixel_y - SEND_SOUND(owner, sound(pick('sound/hallucinations/over_here2.ogg','sound/hallucinations/over_here3.ogg'),0,1,75)) - owner.client.images += C.cult_team.blood_target_image - for(var/datum/mind/B in SSticker.mode.cult) - if(B.current && B.current.stat != DEAD && B.current.client) - to_chat(B.current, "[owner] has marked [C.cult_team.blood_target] in the [A.name] as the cult's top priority, get there immediately!") - SEND_SOUND(B.current, sound(pick('sound/hallucinations/over_here2.ogg','sound/hallucinations/over_here3.ogg'),0,1,75)) - B.current.client.images += C.cult_team.blood_target_image - to_chat(owner,"You have marked the [target] for the cult! It will last for [DisplayTimeText(base_cooldown)].") - name = "Clear the Blood Mark" - desc = "Remove the Blood Mark you previously set." - button_icon_state = "emp" - owner.update_action_buttons_icon() - C.cult_team.blood_target_reset_timer = addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(reset_blood_target),C.cult_team), base_cooldown, TIMER_STOPPABLE) - addtimer(CALLBACK(src, PROC_REF(reset_button)), base_cooldown) - - -//////// ELDRITCH PULSE ///////// - - - -/datum/action/innate/cult/master/pulse - name = "Eldritch Pulse" - desc = "Seize upon a fellow cultist or cult structure and teleport it to a nearby location." - icon_icon = 'icons/mob/actions/actions_spells.dmi' - button_icon_state = "arcane_barrage" - var/obj/effect/proc_holder/pulse/PM - var/cooldown = 0 - var/base_cooldown = 150 - var/throwing = FALSE - var/mob/living/throwee - -/datum/action/innate/cult/master/pulse/New() - PM = new() - PM.attached_action = src - ..() - -/datum/action/innate/cult/master/pulse/IsAvailable() - if(!owner.mind || !owner.mind.has_antag_datum(/datum/antagonist/cult/master)) - return FALSE - if(cooldown > world.time) - if(!PM.active) - to_chat(owner, "You need to wait [DisplayTimeText(cooldown - world.time)] before you can pulse again!") - return FALSE - return ..() - -/datum/action/innate/cult/master/pulse/Destroy() - PM.attached_action = null //What the fuck is even going on here. - QDEL_NULL(PM) - return ..() - - -/datum/action/innate/cult/master/pulse/Activate() - PM.toggle(owner) //the important bit - return TRUE - -/obj/effect/proc_holder/pulse - active = FALSE - ranged_mousepointer = 'icons/effects/mouse_pointers/throw_target.dmi' - var/datum/action/innate/cult/master/pulse/attached_action - -/obj/effect/proc_holder/pulse/Destroy() - attached_action = null - return ..() - - -/obj/effect/proc_holder/pulse/proc/toggle(mob/user) - if(active) - remove_ranged_ability("You cease your preparations...") - attached_action.throwing = FALSE - else - add_ranged_ability(user, "You prepare to tear through the fabric of reality...") - -/obj/effect/proc_holder/pulse/InterceptClickOn(mob/living/caller, params, atom/target) - if(..()) - return - if(ranged_ability_user.incapacitated()) - remove_ranged_ability() - return - var/turf/T = get_turf(ranged_ability_user) - if(!isturf(T)) - return FALSE - if(target in view(7, get_turf(ranged_ability_user))) - if((!(iscultist(target) || istype(target, /obj/structure/destructible/cult)) || target == caller) && !(attached_action.throwing)) - return - if(!attached_action.throwing) - attached_action.throwing = TRUE - attached_action.throwee = target - SEND_SOUND(ranged_ability_user, sound('sound/weapons/thudswoosh.ogg')) - to_chat(ranged_ability_user,"You reach through the veil with your mind's eye and seize [target]!") - return - else - new /obj/effect/temp_visual/cult/sparks(get_turf(attached_action.throwee), ranged_ability_user.dir) - var/distance = get_dist(attached_action.throwee, target) - if(distance >= 16) - return - playsound(target,'sound/magic/exit_blood.ogg') - attached_action.throwee.Beam(target,icon_state="sendbeam",time=4) - attached_action.throwee.forceMove(get_turf(target)) - new /obj/effect/temp_visual/cult/sparks(get_turf(target), ranged_ability_user.dir) - attached_action.throwing = FALSE - attached_action.cooldown = world.time + attached_action.base_cooldown - remove_ranged_ability("A pulse of blood magic surges through you as you shift [attached_action.throwee] through time and space.") - caller.update_action_buttons_icon() - addtimer(CALLBACK(caller, TYPE_PROC_REF(/mob, update_action_buttons_icon)), attached_action.base_cooldown) diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm deleted file mode 100644 index 5dce420df1cf..000000000000 --- a/code/modules/antagonists/cult/cult_items.dm +++ /dev/null @@ -1,524 +0,0 @@ -/obj/item/tome - name = "arcane tome" - desc = "An old, dusty tome with frayed edges and a sinister-looking cover." - icon_state ="tome" - throw_speed = 2 - throw_range = 5 - w_class = WEIGHT_CLASS_SMALL - -/datum/action/innate/dash/cult - name = "Rend the Veil" - desc = "Use the sword to shear open the flimsy fabric of this reality and teleport to your target." - icon_icon = 'icons/mob/actions/actions_cult.dmi' - button_icon_state = "phaseshift" - dash_sound = 'sound/magic/enter_blood.ogg' - recharge_sound = 'sound/magic/exit_blood.ogg' - beam_effect = "sendbeam" - phasein = /obj/effect/temp_visual/dir_setting/cult/phase - phaseout = /obj/effect/temp_visual/dir_setting/cult/phase/out - -/datum/action/innate/dash/cult/IsAvailable() - if(iscultist(owner) && current_charges) - return TRUE - else - return FALSE - -/obj/item/restraints/legcuffs/bola/cult - name = "\improper Nar'Sien bola" - desc = "A strong bola, bound with dark magic that allows it to pass harmlessly through Nar'Sien cultists. Throw it to trip and slow your victim." - icon_state = "bola_cult" - item_state = "bola_cult" - breakouttime = 60 - knockdown = 30 - -/obj/item/restraints/legcuffs/bola/cult/attack_hand(mob/living/user) - . = ..() - if(!iscultist(user)) - to_chat(user, "The bola seems to take on a life of its own!") - ensnare(user) - -/obj/item/restraints/legcuffs/bola/cult/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) - if(iscultist(hit_atom)) - return - . = ..() - -/obj/item/clothing/head/hooded/cult_hoodie - name = "ancient cultist hood" - icon_state = "culthood" - desc = "A torn, dust-caked hood. Strange letters line the inside." - flags_inv = HIDEFACE|HIDEHAIR|HIDEEARS - flags_cover = HEADCOVERSEYES - armor = list("melee" = 40, "bullet" = 30, "laser" = 40,"energy" = 40, "bomb" = 25, "bio" = 10, "rad" = 0, "fire" = 10, "acid" = 10) - cold_protection = HEAD - min_cold_protection_temperature = HELMET_MIN_TEMP_PROTECT - heat_protection = HEAD - max_heat_protection_temperature = HELMET_MAX_TEMP_PROTECT - -/obj/item/clothing/suit/hooded/cultrobes - name = "ancient cultist robes" - desc = "A ragged, dusty set of robes. Strange letters line the inside." - icon_state = "cultrobes" - item_state = "cultrobes" - body_parts_covered = CHEST|GROIN|LEGS|ARMS - allowed = list(/obj/item/tome, /obj/item/tank) - armor = list("melee" = 40, "bullet" = 30, "laser" = 40,"energy" = 40, "bomb" = 25, "bio" = 10, "rad" = 0, "fire" = 10, "acid" = 10) - flags_inv = HIDEJUMPSUIT - cold_protection = CHEST|GROIN|LEGS|ARMS - min_cold_protection_temperature = ARMOR_MIN_TEMP_PROTECT - heat_protection = CHEST|GROIN|LEGS|ARMS - max_heat_protection_temperature = ARMOR_MAX_TEMP_PROTECT - hoodtype = /obj/item/clothing/head/hooded/cult_hoodie - - -/obj/item/clothing/head/hooded/cult_hoodie/alt - name = "cultist hood" - desc = "An armored hood worn by the followers of Nar'Sie." - icon_state = "cult_hoodalt" - item_state = "cult_hoodalt" - -/obj/item/clothing/suit/hooded/cultrobes/alt - name = "cultist robes" - desc = "An armored set of robes worn by the followers of Nar'Sie." - icon_state = "cultrobesalt" - item_state = "cultrobesalt" - hoodtype = /obj/item/clothing/head/hooded/cult_hoodie/alt - -/obj/item/clothing/suit/hooded/cultrobes/alt/ghost - item_flags = DROPDEL - -/obj/item/clothing/suit/hooded/cultrobes/alt/ghost/Initialize() - . = ..() - ADD_TRAIT(src, TRAIT_NODROP, CULT_TRAIT) - -/obj/item/clothing/head/helmet/space/hardsuit/cult - name = "\improper Nar'Sien hardened helmet" - desc = "A heavily-armored helmet worn by warriors of the Nar'Sien cult. It can withstand hard vacuum." - icon_state = "cult_helmet" - item_state = "cult_helmet" - armor = list("melee" = 70, "bullet" = 50, "laser" = 30,"energy" = 40, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 40, "acid" = 75) - light_system = NO_LIGHT_SUPPORT - light_range = 0 - actions_types = list() - -/obj/item/clothing/suit/space/hardsuit/cult - name = "\improper Nar'Sien hardened armor" - icon_state = "cult_armor" - item_state = "cult_armor" - desc = "A heavily-armored exosuit worn by warriors of the Nar'Sien cult. It can withstand hard vacuum." - w_class = WEIGHT_CLASS_BULKY - allowed = list(/obj/item/tome, /obj/item/tank/internals/) - armor = list("melee" = 70, "bullet" = 50, "laser" = 30,"energy" = 40, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 40, "acid" = 75) - helmettype = /obj/item/clothing/head/helmet/space/hardsuit/cult - -/obj/item/sharpener/cult - name = "eldritch whetstone" - desc = "A block, empowered by dark magic. Sharp weapons will be enhanced when used on the stone." - icon_state = "cult_sharpener" - used = 0 - increment = 5 - max = 40 - prefix = "darkened" - -/obj/item/sharpener/cult/update_icon_state() - icon_state = "cult_sharpener[used ? "_used" : ""]" - return ..() - -/obj/item/clothing/suit/hooded/cultrobes/cult_shield - name = "empowered cultist armor" - desc = "Empowered armor which creates a powerful shield around the user." - icon_state = "cult_armor" - item_state = "cult_armor" - w_class = WEIGHT_CLASS_BULKY - armor = list("melee" = 50, "bullet" = 40, "laser" = 50,"energy" = 50, "bomb" = 50, "bio" = 30, "rad" = 30, "fire" = 50, "acid" = 60) - var/current_charges = 3 - hoodtype = /obj/item/clothing/head/hooded/cult_hoodie/cult_shield - -/obj/item/clothing/head/hooded/cult_hoodie/cult_shield - name = "empowered cultist helmet" - desc = "Empowered helmet which creates a powerful shield around the user." - icon_state = "cult_hoodalt" - armor = list("melee" = 50, "bullet" = 40, "laser" = 50,"energy" = 50, "bomb" = 50, "bio" = 30, "rad" = 30, "fire" = 50, "acid" = 60) - -/obj/item/clothing/suit/hooded/cultrobes/cult_shield/equipped(mob/living/user, slot) - ..() - if(!iscultist(user)) - to_chat(user, "\"I wouldn't advise that.\"") - to_chat(user, "An overwhelming sense of nausea overpowers you!") - user.dropItemToGround(src, TRUE) - user.Dizzy(30) - user.Paralyze(100) - -/obj/item/clothing/suit/hooded/cultrobes/cult_shield/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - if(current_charges) - owner.visible_message("\The [attack_text] is deflected in a burst of blood-red sparks!") - current_charges-- - new /obj/effect/temp_visual/cult/sparks(get_turf(owner)) - if(!current_charges) - owner.visible_message("The runed shield around [owner] suddenly disappears!") - owner.update_inv_wear_suit() - return 1 - return 0 - -/obj/item/clothing/suit/hooded/cultrobes/cult_shield/worn_overlays(isinhands) - . = ..() - if(!isinhands && current_charges) - . += mutable_appearance('icons/effects/cult_effects.dmi', "shield-cult", MOB_LAYER + 0.01) - -/obj/item/clothing/suit/hooded/cultrobes/berserker - name = "flagellant's robes" - desc = "Blood-soaked robes infused with dark magic; allows the user to move at inhuman speeds, but at the cost of increased damage." - allowed = list(/obj/item/tome) - armor = list("melee" = -45, "bullet" = -45, "laser" = -45,"energy" = -55, "bomb" = -45, "bio" = -45, "rad" = -45, "fire" = 0, "acid" = 0) - slowdown = -0.6 - hoodtype = /obj/item/clothing/head/hooded/cult_hoodie/berserkerhood - -/obj/item/clothing/head/hooded/cult_hoodie/berserkerhood - name = "flagellant's hood" - desc = "Blood-soaked hood infused with dark magic." - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) - -/obj/item/clothing/suit/hooded/cultrobes/berserker/equipped(mob/living/user, slot) - ..() - if(!iscultist(user)) - to_chat(user, "\"I wouldn't advise that.\"") - to_chat(user, "An overwhelming sense of nausea overpowers you!") - user.dropItemToGround(src, TRUE) - user.Dizzy(30) - user.Paralyze(100) - -/obj/item/clothing/glasses/hud/health/night/cultblind - desc = "may Nar'Sie guide you through the darkness and shield you from the light." - name = "zealot's blindfold" - icon_state = "blindfold" - item_state = "blindfold" - flash_protect = FLASH_PROTECTION_FLASH - -/obj/item/clothing/glasses/hud/health/night/cultblind/equipped(mob/living/user, slot) - ..() - if(prob(30)) - to_chat(user, "\"You want to be blind, do you?\"") - user.dropItemToGround(src, TRUE) - user.Dizzy(30) - user.Paralyze(100) - user.blind_eyes(30) - else - return - -/obj/item/reagent_containers/glass/beaker/unholywater - name = "flask of unholy water" - desc = "Toxic to nonbelievers; reinvigorating to the faithful - this flask may be sipped or thrown." - icon = 'icons/obj/drinks/drinks.dmi' - icon_state = "holyflask" - color = "#333333" - list_reagents = list(/datum/reagent/fuel/unholywater = 50) - can_have_cap = FALSE - cap_icon_state = null - cap_on = FALSE - -/obj/item/cult_shift - name = "veil shifter" - 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 - -/obj/item/cult_shift/examine(mob/user) - . = ..() - if(uses) - . += "It has [uses] use\s remaining." - else - . += "It seems drained." - -/obj/item/cult_shift/proc/handle_teleport_grab(turf/T, mob/user) - var/mob/living/carbon/C = user - if(C.pulling) - var/atom/movable/pulled = C.pulling - do_teleport(pulled, T, channel = TELEPORT_CHANNEL_CULT) - . = pulled - -/obj/item/cult_shift/attack_self(mob/user) - if(!uses || !iscarbon(user)) - to_chat(user, "\The [src] is dull and unmoving in your hands.") - return - - var/mob/living/carbon/C = user - var/turf/mobloc = get_turf(C) - var/turf/destination = get_teleport_loc(mobloc,C,9,1,3,1,0,1) - - if(destination) - uses-- - if(uses <= 0) - icon_state ="shifter_drained" - playsound(mobloc, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - new /obj/effect/temp_visual/dir_setting/cult/phase/out(mobloc, C.dir) - - var/atom/movable/pulled = handle_teleport_grab(destination, C) - if(do_teleport(C, destination, channel = TELEPORT_CHANNEL_CULT)) - if(pulled) - C.start_pulling(pulled) //forcemove resets pulls, so we need to re-pull - new /obj/effect/temp_visual/dir_setting/cult/phase(destination, C.dir) - playsound(destination, 'sound/effects/phasein.ogg', 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - playsound(destination, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - - else - to_chat(C, "The veil cannot be torn here!") - -/obj/item/flashlight/flare/culttorch - name = "void torch" - desc = "Used by veteran cultists to instantly transport items to their needful brethren." - w_class = WEIGHT_CLASS_SMALL - light_range = 1 - icon_state = "torch" - item_state = "torch" - color = "#ff0000" - on_damage = 15 - slot_flags = null - on = TRUE - var/charges = 5 - -/obj/item/flashlight/flare/culttorch/afterattack(atom/movable/A, mob/user, proximity) - if(!proximity) - return - if(!iscultist(user)) - to_chat(user, "That doesn't seem to do anything useful.") - return - - if(istype(A, /obj/item)) - - var/list/cultists = list() - for(var/datum/mind/M in SSticker.mode.cult) - if(M.current && M.current.stat != DEAD) - cultists |= M.current - var/mob/living/cultist_to_receive = input(user, "Who do you wish to call to [src]?", "Followers of the Geometer") as null|anything in (cultists - user) - if(!Adjacent(user) || !src || QDELETED(src) || user.incapacitated()) - return - if(!cultist_to_receive) - to_chat(user, "You require a destination!") - log_game("Void torch failed - no target") - return - if(cultist_to_receive.stat == DEAD) - to_chat(user, "[cultist_to_receive] has died!") - log_game("Void torch failed - target died") - return - if(!iscultist(cultist_to_receive)) - to_chat(user, "[cultist_to_receive] is not a follower of the Geometer!") - log_game("Void torch failed - target was deconverted") - return - if(A in user.GetAllContents()) - to_chat(user, "[A] must be on a surface in order to teleport it!") - return - to_chat(user, "You ignite [A] with \the [src], turning it to ash, but through the torch's flames you see that [A] has reached [cultist_to_receive]!") - cultist_to_receive.put_in_hands(A) - charges-- - to_chat(user, "\The [src] now has [charges] charge\s.") - if(charges == 0) - qdel(src) - - else - ..() - to_chat(user, "\The [src] can only transport items!") - -/obj/item/blood_beam - name = "\improper magical aura" - desc = "Sinister looking aura that distorts the flow of reality around it." - lefthand_file = 'icons/mob/inhands/misc/touchspell_lefthand.dmi' - righthand_file = 'icons/mob/inhands/misc/touchspell_righthand.dmi' - icon_state = "disintegrate" - item_state = "disintegrate" - item_flags = ABSTRACT | DROPDEL - w_class = WEIGHT_CLASS_HUGE - throwforce = 0 - throw_range = 0 - throw_speed = 0 - var/charging = FALSE - var/firing = FALSE - var/angle - -/obj/item/blood_beam/Initialize() - . = ..() - ADD_TRAIT(src, TRAIT_NODROP, CULT_TRAIT) - - -/obj/item/blood_beam/afterattack(atom/A, mob/living/user, flag, params) - . = ..() - if(firing || charging) - return - var/C = user.client - if(ishuman(user) && C) - angle = mouse_angle_from_client(C) - else - qdel(src) - return - charging = TRUE - INVOKE_ASYNC(src, PROC_REF(charge), user) - if(do_after(user, 90, target = user)) - firing = TRUE - INVOKE_ASYNC(src, PROC_REF(pewpew), user, params) - var/obj/structure/emergency_shield/invoker/N = new(user.loc) - if(do_after(user, 90, target = user)) - user.Paralyze(40) - to_chat(user, "You have exhausted the power of this spell!") - firing = FALSE - if(N) - qdel(N) - qdel(src) - charging = FALSE - -/obj/item/blood_beam/proc/charge(mob/user) - var/obj/O - playsound(src, 'sound/magic/lightning_chargeup.ogg', 100, TRUE) - for(var/i in 1 to 12) - if(!charging) - break - if(i > 1) - sleep(15) - if(i < 4) - O = new /obj/effect/temp_visual/cult/rune_spawn/rune1/inner(user.loc, 30, "#ff0000") - else - O = new /obj/effect/temp_visual/cult/rune_spawn/rune5(user.loc, 30, "#ff0000") - new /obj/effect/temp_visual/dir_setting/cult/phase/out(user.loc, user.dir) - if(O) - qdel(O) - -/obj/item/blood_beam/proc/pewpew(mob/user, params) - var/turf/targets_from = get_turf(src) - var/spread = 40 - var/second = FALSE - var/set_angle = angle - for(var/i in 1 to 12) - if(second) - set_angle = angle - spread - spread -= 8 - else - sleep(15) - set_angle = angle + spread - second = !second //Handles beam firing in pairs - if(!firing) - break - playsound(src, 'sound/magic/exit_blood.ogg', 75, TRUE) - new /obj/effect/temp_visual/dir_setting/cult/phase(user.loc, user.dir) - var/turf/temp_target = get_turf_in_angle(set_angle, targets_from, 40) - for(var/turf/T in getline(targets_from,temp_target)) - if (locate(/obj/effect/blessing, T)) - temp_target = T - playsound(T, 'sound/machines/clockcult/ark_damage.ogg', 50, TRUE) - new /obj/effect/temp_visual/at_shield(T, T) - break - T.narsie_act(TRUE, TRUE) - for(var/mob/living/target in T.contents) - if(iscultist(target)) - new /obj/effect/temp_visual/cult/sparks(T) - if(ishuman(target)) - var/mob/living/carbon/human/H = target - if(H.stat != DEAD) - H.reagents.add_reagent(/datum/reagent/fuel/unholywater, 7) - if(isshade(target) || isconstruct(target)) - var/mob/living/simple_animal/M = target - if(M.health+15 < M.maxHealth) - M.adjustHealth(-15) - else - M.health = M.maxHealth - else - var/mob/living/L = target - if(L.density) - L.Paralyze(20) - L.adjustBruteLoss(45) - playsound(L, 'sound/hallucinations/wail.ogg', 50, TRUE) - L.emote("scream") - user.Beam(temp_target, icon_state="blood_beam", time = 7, beam_type = /obj/effect/ebeam/blood) - - -/obj/effect/ebeam/blood - name = "blood beam" - -/obj/item/shield/mirror - name = "mirror shield" - desc = "An infamous shield used by Nar'Sien sects to confuse and disorient their enemies. Its edges are weighted for use as a throwing weapon - capable of disabling multiple foes with preternatural accuracy." - icon_state = "mirror_shield" // eshield1 for expanded - lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi' - force = 5 - throwforce = 15 - throw_speed = 1 - throw_range = 4 - w_class = WEIGHT_CLASS_BULKY - attack_verb = list("bumped", "prodded") - hitsound = 'sound/weapons/smash.ogg' - var/illusions = 2 - -/obj/item/shield/mirror/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - if(iscultist(owner)) - if(istype(hitby, /obj/projectile)) - var/obj/projectile/P = hitby - if(P.damage_type == BRUTE || P.damage_type == BURN) - if(P.damage >= 30) - var/turf/T = get_turf(owner) - T.visible_message("The sheer force from [P] shatters the mirror shield!") - new /obj/effect/temp_visual/cult/sparks(T) - playsound(T, 'sound/effects/glassbr3.ogg', 100) - owner.Paralyze(25) - qdel(src) - return FALSE - if(P.reflectable & REFLECT_NORMAL) - return FALSE //To avoid reflection chance double-dipping with block chance - . = ..() - if(.) - playsound(src, 'sound/weapons/parry.ogg', 100, TRUE) - if(illusions > 0) - illusions-- - addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/item/shield/mirror, readd)), 450) - if(prob(60)) - var/mob/living/simple_animal/hostile/illusion/M = new(owner.loc) - M.faction = list("cult") - M.Copy_Parent(owner, 70, 10, 5) - M.move_to_delay = owner.cached_multiplicative_slowdown - else - var/mob/living/simple_animal/hostile/illusion/escape/E = new(owner.loc) - E.Copy_Parent(owner, 70, 10) - E.GiveTarget(owner) - E.Goto(owner, owner.cached_multiplicative_slowdown, E.minimum_distance) - return TRUE - else - if(prob(50)) - var/mob/living/simple_animal/hostile/illusion/H = new(owner.loc) - H.Copy_Parent(owner, 100, 20, 5) - H.faction = list("cult") - H.GiveTarget(owner) - H.move_to_delay = owner.cached_multiplicative_slowdown - to_chat(owner, "[src] betrays you!") - return FALSE - -/obj/item/shield/mirror/proc/readd() - illusions++ - if(illusions == initial(illusions) && isliving(loc)) - var/mob/living/holder = loc - to_chat(holder, "The shield's illusions are back at full strength!") - -/obj/item/shield/mirror/IsReflect() - if(prob(block_chance)) - return TRUE - return FALSE - -/obj/item/shield/mirror/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) - var/turf/T = get_turf(hit_atom) - var/datum/thrownthing/D = throwingdatum - if(isliving(hit_atom)) - var/mob/living/L = hit_atom - if(iscultist(L)) - playsound(src, 'sound/weapons/throwtap.ogg', 50) - if(L.put_in_active_hand(src)) - L.visible_message("[L] catches [src] out of the air!") - else - L.visible_message("[src] bounces off of [L], as if repelled by an unseen force!") - else if(!..()) - if(!L.anti_magic_check()) - L.Paralyze(30) - if(D?.thrower) - for(var/mob/living/Next in orange(2, T)) - if(!Next.density || iscultist(Next)) - continue - throw_at(Next, 3, 1, D.thrower) - return - throw_at(D.thrower, 7, 1, null) - else - ..() diff --git a/code/modules/antagonists/cult/cult_structures.dm b/code/modules/antagonists/cult/cult_structures.dm deleted file mode 100644 index 6f8f2f6e7775..000000000000 --- a/code/modules/antagonists/cult/cult_structures.dm +++ /dev/null @@ -1,291 +0,0 @@ -/obj/structure/destructible/cult - density = TRUE - anchored = TRUE - icon = 'icons/obj/cult.dmi' - light_power = 2 - var/cooldowntime = 0 - break_sound = 'sound/hallucinations/veryfar_noise.ogg' - debris = list(/obj/item/stack/sheet/mineral/hidden/hellstone = 1) - -/obj/structure/destructible/cult/proc/conceal() //for spells that hide cult presence - density = FALSE - visible_message("[src] fades away.") - invisibility = INVISIBILITY_OBSERVER - alpha = 100 //To help ghosts distinguish hidden runes - light_range = 0 - light_power = 0 - update_light() - STOP_PROCESSING(SSfastprocess, src) - -/obj/structure/destructible/cult/proc/reveal() //for spells that reveal cult presence - density = initial(density) - invisibility = 0 - visible_message("[src] suddenly appears!") - alpha = initial(alpha) - light_range = initial(light_range) - light_power = initial(light_power) - update_light() - START_PROCESSING(SSfastprocess, src) - - -/obj/structure/destructible/cult/examine(mob/user) - . = ..() - . += "\The [src] is [anchored ? "":"not "]secured to the floor." - if((iscultist(user) || isobserver(user)) && cooldowntime > world.time) - . += "The magic in [src] is too weak, [p_they()] will be ready to use again in [DisplayTimeText(cooldowntime - world.time)]." - -/obj/structure/destructible/cult/examine_status(mob/user) - if(iscultist(user) || isobserver(user)) - var/t_It = p_they(TRUE) - var/t_is = p_are() - return "[t_It] [t_is] at [round(obj_integrity * 100 / max_integrity)]% stability." - return ..() - -/obj/structure/destructible/cult/attack_animal(mob/living/simple_animal/M) - if(istype(M, /mob/living/simple_animal/hostile/construct/artificer)) - if(obj_integrity < max_integrity) - M.changeNext_move(CLICK_CD_MELEE) - obj_integrity = min(max_integrity, obj_integrity + 5) - Beam(M, icon_state="sendbeam", time=4) - M.visible_message("[M] repairs \the [src].", \ - "You repair [src], leaving [p_they()] at [round(obj_integrity * 100 / max_integrity)]% stability.") - else - to_chat(M, "You cannot repair [src], as [p_theyre()] undamaged!") - else - ..() - -/obj/structure/destructible/cult/set_anchored(anchorvalue) - . = ..() - if(isnull(.)) - return - update_appearance() - -/obj/structure/destructible/cult/update_icon_state() - icon_state = "[initial(icon_state)][anchored ? null : "_off"]" - return ..() - -/obj/structure/destructible/cult/proc/check_menu(mob/user) - if(!istype(user)) - return FALSE - if(user.incapacitated() || !user.Adjacent(src)) - return FALSE - return TRUE - -/obj/structure/destructible/cult/talisman - name = "altar" - desc = "A bloodstained altar dedicated to Nar'Sie." - icon_state = "talismanaltar" - break_message = "The altar shatters, leaving only the wailing of the damned!" - -/obj/structure/destructible/cult/talisman/attack_hand(mob/living/user) - . = ..() - if(.) - return - if(!iscultist(user)) - to_chat(user, "You're pretty sure you know exactly what this is used for and you can't seem to touch it.") - return - if(!anchored) - to_chat(user, "You need to anchor [src] to the floor with your dagger first.") - return - if(cooldowntime > world.time) - to_chat(user, "The magic in [src] is weak, it will be ready to use again in [DisplayTimeText(cooldowntime - world.time)].") - return - var/list/items = list( - "Eldritch Whetstone" = image(icon = 'icons/obj/kitchen.dmi', icon_state = "cult_sharpener"), - "Construct Shell" = image(icon = 'icons/obj/wizard.dmi', icon_state = "construct_cult"), - "Flask of Unholy Water" = image(icon = 'icons/obj/drinks/drinks.dmi', icon_state = "holyflask") - ) - var/choice = show_radial_menu(user, src, items, custom_check = CALLBACK(src, PROC_REF(check_menu), user), require_near = TRUE, tooltips = TRUE) - var/list/pickedtype = list() - switch(choice) - if("Eldritch Whetstone") - pickedtype += /obj/item/sharpener/cult - if("Construct Shell") - pickedtype += /obj/structure/constructshell - if("Flask of Unholy Water") - pickedtype += /obj/item/reagent_containers/glass/beaker/unholywater - else - return - if(src && !QDELETED(src) && anchored && pickedtype && Adjacent(user) && !user.incapacitated() && iscultist(user) && cooldowntime <= world.time) - cooldowntime = world.time + 2400 - for(var/N in pickedtype) - new N(get_turf(src)) - to_chat(user, "You kneel before the altar and your faith is rewarded with the [choice]!") - -/obj/structure/destructible/cult/forge - name = "daemon forge" - desc = "A forge used in crafting the unholy weapons used by the armies of Nar'Sie." - icon_state = "forge" - light_range = 2 - light_color = LIGHT_COLOR_LAVA - break_message = "The force breaks apart into shards with a howling scream!" - -/obj/structure/destructible/cult/forge/attack_hand(mob/living/user) - . = ..() - if(.) - return - if(!iscultist(user)) - to_chat(user, "The heat radiating from [src] pushes you back.") - return - if(!anchored) - to_chat(user, "You need to anchor [src] to the floor with your dagger first.") - return - if(cooldowntime > world.time) - to_chat(user, "The magic in [src] is weak, it will be ready to use again in [DisplayTimeText(cooldowntime - world.time)].") - return - var/list/items = list( - "Shielded Robe" = image(icon = 'icons/obj/clothing/suits.dmi', icon_state = "cult_armor"), - "Flagellant's Robe" = image(icon = 'icons/obj/clothing/suits.dmi', icon_state = "cultrobes"), - "Mirror Shield" = image(icon = 'icons/obj/shields.dmi', icon_state = "mirror_shield") - ) - var/choice = show_radial_menu(user, src, items, custom_check = CALLBACK(src, PROC_REF(check_menu), user), require_near = TRUE, tooltips = TRUE) - var/list/pickedtype = list() - switch(choice) - if("Shielded Robe") - pickedtype += /obj/item/clothing/suit/hooded/cultrobes/cult_shield - if("Flagellant's Robe") - pickedtype += /obj/item/clothing/suit/hooded/cultrobes/berserker - if("Mirror Shield") - pickedtype += /obj/item/shield/mirror - else - return - if(src && !QDELETED(src) && anchored && pickedtype && Adjacent(user) && !user.incapacitated() && iscultist(user) && cooldowntime <= world.time) - cooldowntime = world.time + 2400 - for(var/N in pickedtype) - new N(get_turf(src)) - to_chat(user, "You work the forge as dark knowledge guides your hands, creating the [choice]!") - - - -/obj/structure/destructible/cult/pylon - name = "pylon" - desc = "A floating crystal that slowly heals those faithful to Nar'Sie." - icon_state = "pylon" - light_range = 1.5 - light_color = COLOR_SOFT_RED - break_sound = 'sound/effects/glassbr2.ogg' - break_message = "The blood-red crystal falls to the floor and shatters!" - var/heal_delay = 25 - var/last_heal = 0 - var/corrupt_delay = 50 - var/last_corrupt = 0 - -/obj/structure/destructible/cult/pylon/New() - START_PROCESSING(SSfastprocess, src) - ..() - -/obj/structure/destructible/cult/pylon/Destroy() - STOP_PROCESSING(SSfastprocess, src) - return ..() - -/obj/structure/destructible/cult/pylon/process() - if(!anchored) - return - if(last_heal <= world.time) - last_heal = world.time + heal_delay - for(var/mob/living/L in range(5, src)) - if(iscultist(L) || isshade(L) || isconstruct(L)) - if(L.health != L.maxHealth) - new /obj/effect/temp_visual/heal(get_turf(src), "#960000") - if(ishuman(L)) - L.adjustBruteLoss(-1, 0) - L.adjustFireLoss(-1, 0) - L.updatehealth() - if(isshade(L) || isconstruct(L)) - var/mob/living/simple_animal/M = L - if(M.health < M.maxHealth) - M.adjustHealth(-3) - if(ishuman(L) && L.blood_volume < BLOOD_VOLUME_NORMAL) - L.blood_volume += 1.0 - CHECK_TICK - if(last_corrupt <= world.time) - var/list/validturfs = list() - var/list/cultturfs = list() - for(var/T in circleviewturfs(src, 5)) - if(istype(T, /turf/open/floor/engine/cult)) - cultturfs |= T - continue - var/static/list/blacklisted_pylon_turfs = typecacheof(list( - /turf/closed, - /turf/open/floor/engine/cult, - /turf/open/space, - /turf/open/lava, - /turf/open/chasm)) - if(is_type_in_typecache(T, blacklisted_pylon_turfs)) - continue - else - validturfs |= T - - last_corrupt = world.time + corrupt_delay - - if(length(validturfs)) - var/turf/T = pick(validturfs) - if(istype(T, /turf/open/floor/plating)) - T.PlaceOnTop(/turf/open/floor/engine/cult, flags = CHANGETURF_INHERIT_AIR) - else - T.ChangeTurf(/turf/open/floor/engine/cult, flags = CHANGETURF_INHERIT_AIR) - else if (length(cultturfs)) - var/turf/open/floor/engine/cult/F = pick(cultturfs) - new /obj/effect/temp_visual/cult/turf/floor(F) - else - // Are we in space or something? No cult turfs or - // convertable turfs? - last_corrupt = world.time + corrupt_delay*2 - -/obj/structure/destructible/cult/tome - name = "archives" - desc = "A desk covered in arcane manuscripts and tomes in unknown languages. Looking at the text makes your skin crawl." - icon_state = "tomealtar" - light_range = 1.5 - light_color = LIGHT_COLOR_FIRE - break_message = "The books and tomes of the archives burn into ash as the desk shatters!" - -/obj/structure/destructible/cult/tome/attack_hand(mob/living/user) - . = ..() - if(.) - return - if(!iscultist(user)) - to_chat(user, "These books won't open and it hurts to even try and read the covers.") - return - if(!anchored) - to_chat(user, "You need to anchor [src] to the floor with your dagger first.") - return - if(cooldowntime > world.time) - to_chat(user, "The magic in [src] is weak, it will be ready to use again in [DisplayTimeText(cooldowntime - world.time)].") - return - var/list/items = list( - // [CELADON-EDIT] - CELADON_RETURN_CONTENT - // "Zealot's Blindfold" = image(icon = 'icons/obj/clothing/eyes/eyes.dmi', icon_state = "blindfold"), // CELADON-EDIT - ORIGINAL - "Zealot's Blindfold" = image(icon = 'mod_celadon/_storge_icons/icons/clothing/obj/eyes.dmi', icon_state = "blindfold"), - // [/CELADON-EDIT] - "Veil Walker Set" = image(icon = 'icons/obj/cult.dmi', icon_state = "shifter") - ) - var/choice = show_radial_menu(user, src, items, custom_check = CALLBACK(src, PROC_REF(check_menu), user), require_near = TRUE, tooltips = TRUE) - var/list/pickedtype = list() - switch(choice) - if("Zealot's Blindfold") - pickedtype += /obj/item/clothing/glasses/hud/health/night/cultblind - if("Veil Walker Set") - pickedtype += /obj/item/cult_shift - pickedtype += /obj/item/flashlight/flare/culttorch - else - return - if(src && !QDELETED(src) && anchored && pickedtype.len && Adjacent(user) && !user.incapacitated() && iscultist(user) && cooldowntime <= world.time) - cooldowntime = world.time + 2400 - for(var/N in pickedtype) - new N(get_turf(src)) - to_chat(user, "You summon the [choice] from the archives!") - -/obj/effect/gateway - name = "gateway" - desc = "You're pretty sure that abyss is staring back." - icon = 'icons/obj/cult.dmi' - icon_state = "hole" - density = TRUE - anchored = TRUE - -/obj/effect/gateway/singularity_act() - return - -/obj/effect/gateway/singularity_pull() - return diff --git a/code/modules/antagonists/cult/cult_turf_overlay.dm b/code/modules/antagonists/cult/cult_turf_overlay.dm deleted file mode 100644 index 2e950326bf8a..000000000000 --- a/code/modules/antagonists/cult/cult_turf_overlay.dm +++ /dev/null @@ -1,32 +0,0 @@ -//an "overlay" used by clockwork walls and floors to appear normal to mesons. -/obj/effect/cult_turf/overlay - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - var/atom/linked - -/obj/effect/cult_turf/overlay/examine(mob/user) - if(linked) - linked.examine(user) - -/obj/effect/cult_turf/overlay/ex_act() - return FALSE - -/obj/effect/cult_turf/overlay/singularity_act() - return -/obj/effect/cult_turf/overlay/singularity_pull() - return - -/obj/effect/cult_turf/overlay/singularity_pull(S, current_size) - return - -/obj/effect/cult_turf/overlay/Destroy() - if(linked) - linked = null - . = ..() - -/obj/effect/cult_turf/overlay/floor - icon = 'icons/turf/floors.dmi' - icon_state = "clockwork_floor" - layer = TURF_LAYER - -/obj/effect/cult_turf/overlay/floor/bloodcult - icon_state = "cult" diff --git a/code/modules/antagonists/cult/rune_spawn_action.dm b/code/modules/antagonists/cult/rune_spawn_action.dm deleted file mode 100644 index 2829141405dd..000000000000 --- a/code/modules/antagonists/cult/rune_spawn_action.dm +++ /dev/null @@ -1,115 +0,0 @@ -//after a delay, creates a rune below you. for constructs creating runes. -/datum/action/innate/cult/create_rune - name = "Summon Rune" - desc = "Summons a rune" - background_icon_state = "bg_demon" - var/obj/effect/rune/rune_type - var/cooldown = 0 - var/base_cooldown = 1800 - var/scribe_time = 60 - var/damage_interrupt = TRUE - var/action_interrupt = TRUE - var/obj/effect/temp_visual/cult/rune_spawn/rune_word_type - var/obj/effect/temp_visual/cult/rune_spawn/rune_innerring_type - var/obj/effect/temp_visual/cult/rune_spawn/rune_center_type - var/rune_color - -/datum/action/innate/cult/create_rune/IsAvailable() - if(!rune_type || cooldown > world.time) - return FALSE - return ..() - -/datum/action/innate/cult/create_rune/proc/turf_check(turf/T) - if(!T) - return FALSE - if(isspaceturf(T)) - to_chat(owner, "You cannot scribe runes in space!") - return FALSE - if(locate(/obj/effect/rune) in T) - to_chat(owner, "There is already a rune here.") - return FALSE - return TRUE - - -/datum/action/innate/cult/create_rune/Activate() - var/turf/T = get_turf(owner) - if(turf_check(T)) - var/chosen_keyword - if(initial(rune_type.req_keyword)) - chosen_keyword = stripped_input(owner, "Enter a keyword for the new rune.", "Words of Power") - if(!chosen_keyword) - return - //the outer ring is always the same across all runes - var/obj/effect/temp_visual/cult/rune_spawn/R1 = new(T, scribe_time, rune_color) - //the rest are not always the same, so we need types for em - var/obj/effect/temp_visual/cult/rune_spawn/R2 - if(rune_word_type) - R2 = new rune_word_type(T, scribe_time, rune_color) - var/obj/effect/temp_visual/cult/rune_spawn/R3 - if(rune_innerring_type) - R3 = new rune_innerring_type(T, scribe_time, rune_color) - var/obj/effect/temp_visual/cult/rune_spawn/R4 - if(rune_center_type) - R4 = new rune_center_type(T, scribe_time, rune_color) - - cooldown = base_cooldown + world.time - owner.update_action_buttons_icon() - addtimer(CALLBACK(owner, TYPE_PROC_REF(/mob, update_action_buttons_icon)), base_cooldown) - var/list/health - if(damage_interrupt && isliving(owner)) - var/mob/living/L = owner - health = list("health" = L.health) - var/scribe_mod = scribe_time - if(istype(T, /turf/open/floor/engine/cult)) - scribe_mod *= 0.5 - playsound(T, 'sound/magic/enter_blood.ogg', 100, FALSE) - if(do_after(owner, scribe_mod, target = owner, extra_checks = CALLBACK(owner, TYPE_PROC_REF(/mob, break_do_after_checks), health, action_interrupt))) - var/obj/effect/rune/new_rune = new rune_type(owner.loc) - new_rune.keyword = chosen_keyword - else - qdel(R1) - if(R2) - qdel(R2) - if(R3) - qdel(R3) - if(R4) - qdel(R4) - cooldown = 0 - owner.update_action_buttons_icon() - -//teleport rune -/datum/action/innate/cult/create_rune/tele - name = "Summon Teleport Rune" - desc = "Summons a teleport rune to your location, as though it has been there all along..." - button_icon_state = "telerune" - rune_type = /obj/effect/rune/teleport - rune_word_type = /obj/effect/temp_visual/cult/rune_spawn/rune2 - rune_innerring_type = /obj/effect/temp_visual/cult/rune_spawn/rune2/inner - rune_center_type = /obj/effect/temp_visual/cult/rune_spawn/rune2/center - rune_color = RUNE_COLOR_TELEPORT - -/datum/action/innate/cult/create_rune/wall - name = "Summon Barrier Rune" - desc = "Summons an active barrier rune to your location, as though it has been there all along..." - button_icon_state = "barrier" - rune_type = /obj/effect/rune/wall - rune_word_type = /obj/effect/temp_visual/cult/rune_spawn/rune4 - rune_innerring_type = /obj/effect/temp_visual/cult/rune_spawn/rune4/inner - rune_center_type = /obj/effect/temp_visual/cult/rune_spawn/rune4/center - rune_color = RUNE_COLOR_DARKRED - -/datum/action/innate/cult/create_rune/wall/Activate() - . = ..() - var/obj/effect/rune/wall/W = locate(/obj/effect/rune/wall) in owner.loc - if(W) - W.spread_density() - -/datum/action/innate/cult/create_rune/revive - name = "Summon Revive Rune" - desc = "Summons a revive rune to your location, as though it has been there all along..." - button_icon_state = "revive" - rune_type = /obj/effect/rune/raise_dead - rune_word_type = /obj/effect/temp_visual/cult/rune_spawn/rune1 - rune_innerring_type = /obj/effect/temp_visual/cult/rune_spawn/rune1/inner - rune_center_type = /obj/effect/temp_visual/cult/rune_spawn/rune1/center - rune_color = RUNE_COLOR_MEDIUMRED diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm deleted file mode 100644 index 3382672071cc..000000000000 --- a/code/modules/antagonists/cult/runes.dm +++ /dev/null @@ -1,1029 +0,0 @@ -GLOBAL_LIST_EMPTY(sacrificed) //a mixed list of minds and mobs -GLOBAL_LIST(rune_types) //Every rune that can be drawn by ritual daggers -GLOBAL_LIST_EMPTY(teleport_runes) -GLOBAL_LIST_EMPTY(wall_runes) -/* - -This file contains runes. -Runes are used by the cult to cause many different effects and are paramount to their success. -They are drawn with a ritual dagger in blood, and are distinguishable to cultists and normal crew by examining. -Fake runes can be drawn in crayon to fool people. -Runes can either be invoked by one's self or with many different cultists. Each rune has a specific incantation that the cultists will say when invoking it. - - -*/ - -/obj/effect/rune - name = "rune" - var/cultist_name = "basic rune" - desc = "An odd collection of symbols drawn in what seems to be blood." - var/cultist_desc = "a basic rune with no function." //This is shown to cultists who examine the rune in order to determine its true purpose. - anchored = TRUE - icon = 'icons/obj/rune.dmi' - icon_state = "1" - resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF - layer = SIGIL_LAYER - color = RUNE_COLOR_RED - - var/invocation = "Aiy ele-mayo!" //This is said by cultists when the rune is invoked. - var/req_cultists = 1 //The amount of cultists required around the rune to invoke it. If only 1, any cultist can invoke it. - var/req_cultists_text //if we have a description override for required cultists to invoke - var/rune_in_use = FALSE // Used for some runes, this is for when you want a rune to not be usable when in use. - - var/scribe_delay = 40 //how long the rune takes to create - var/scribe_damage = 0.1 //how much damage you take doing it - var/invoke_damage = 0 //how much damage invokers take when invoking it - var/construct_invoke = TRUE //if constructs can invoke it - - var/req_keyword = 0 //If the rune requires a keyword - go figure amirite - var/keyword //The actual keyword for the rune - -/obj/effect/rune/Initialize(mapload, set_keyword) - . = ..() - if(set_keyword) - keyword = set_keyword - var/image/I = image(icon = 'icons/effects/blood.dmi', icon_state = null, loc = src) - I.override = TRUE - add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/silicons, "cult_runes", I) - -/obj/effect/rune/examine(mob/user) - . = ..() - if(iscultist(user) || user.stat == DEAD) //If they're a cultist or a ghost, tell them the effects - . += "Name: [cultist_name]\n"+\ - "Effects: [capitalize(cultist_desc)]\n"+\ - "Required Acolytes: [req_cultists_text ? "[req_cultists_text]":"[req_cultists]"]" - if(req_keyword && keyword) - . += "Keyword: [keyword]" - -/obj/effect/rune/attack_hand(mob/living/user) - . = ..() - if(.) - return - if(!iscultist(user)) - to_chat(user, "You aren't able to understand the words of [src].") - return - var/list/invokers = can_invoke(user) - if(invokers.len >= req_cultists) - invoke(invokers) - else - to_chat(user, "You need [req_cultists - invokers.len] more adjacent cultists to use this rune in such a manner.") - fail_invoke() - -/obj/effect/rune/attack_animal(mob/living/simple_animal/M) - if(istype(M, /mob/living/simple_animal/shade) || istype(M, /mob/living/simple_animal/hostile/construct)) - if(istype(M, /mob/living/simple_animal/hostile/construct/wraith/angelic) || istype(M, /mob/living/simple_animal/hostile/construct/juggernaut/angelic) || istype(M, /mob/living/simple_animal/hostile/construct/artificer/angelic)) - to_chat(M, "You purge the rune!") - qdel(src) - else if(construct_invoke || !iscultist(M)) //if you're not a cult construct we want the normal fail message - attack_hand(M) - else - to_chat(M, "You are unable to invoke the rune!") - -/obj/effect/rune/proc/conceal() //for talisman of revealing/hiding - visible_message("[src] fades away.") - invisibility = INVISIBILITY_OBSERVER - alpha = 100 //To help ghosts distinguish hidden runes - -/obj/effect/rune/proc/reveal() //for talisman of revealing/hiding - invisibility = 0 - visible_message("[src] suddenly appears!") - alpha = initial(alpha) - -/* - -There are a few different procs each rune runs through when a cultist activates it. -can_invoke() is called when a cultist activates the rune with an empty hand. If there are multiple cultists, this rune determines if the required amount is nearby. -invoke() is the rune's actual effects. -fail_invoke() is called when the rune fails, via not enough people around or otherwise. Typically this just has a generic 'fizzle' effect. -structure_check() searches for nearby cultist structures required for the invocation. Proper structures are pylons, forges, archives, and altars. - -*/ - -/obj/effect/rune/proc/can_invoke(mob/living/user=null) - //This proc determines if the rune can be invoked at the time. If there are multiple required cultists, it will find all nearby cultists. - var/list/invokers = list() //people eligible to invoke the rune - if(user) - invokers += user - if(req_cultists > 1 || istype(src, /obj/effect/rune/convert)) - var/list/things_in_range = range(1, src) - for(var/mob/living/L in things_in_range) - if(iscultist(L)) - if(L == user) - continue - if(ishuman(L)) - var/mob/living/carbon/human/H = L - if((HAS_TRAIT(H, TRAIT_MUTE)) || H.silent) - continue - if(L.stat) - continue - invokers += L - return invokers - -/obj/effect/rune/proc/invoke(list/invokers) - //This proc contains the effects of the rune as well as things that happen afterwards. If you want it to spawn an object and then delete itself, have both here. - for(var/M in invokers) - if(isliving(M)) - var/mob/living/L = M - if(invocation) - L.say(invocation, language = /datum/language/common, ignore_spam = TRUE, forced = "cult invocation") - if(invoke_damage) - L.apply_damage(invoke_damage, BRUTE) - to_chat(L, "[src] saps your strength!") - else if(istype(M, /obj/item/toy/plush/narplush)) - var/obj/item/toy/plush/narplush/P = M - P.visible_message("[P] squeaks loudly!") - do_invoke_glow() - -/obj/effect/rune/proc/do_invoke_glow() - set waitfor = FALSE - animate(src, transform = matrix()*2, alpha = 0, time = 5, flags = ANIMATION_END_NOW) //fade out - sleep(5) - animate(src, transform = matrix(), alpha = 255, time = 0, flags = ANIMATION_END_NOW) - -/obj/effect/rune/proc/fail_invoke() - //This proc contains the effects of a rune if it is not invoked correctly, through either invalid wording or not enough cultists. By default, it's just a basic fizzle. - visible_message("The markings pulse with a small flash of red light, then fall dark.") - var/oldcolor = color - color = rgb(255, 0, 0) - animate(src, color = oldcolor, time = 5) - addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_atom_colour)), 5) - -//Malformed Rune: This forms if a rune is not drawn correctly. Invoking it does nothing but hurt the user. -/obj/effect/rune/malformed - cultist_name = "malformed rune" - cultist_desc = "a senseless rune written in gibberish. No good can come from invoking this." - invocation = "Ra'sha yoka!" - invoke_damage = 30 - -/obj/effect/rune/malformed/Initialize(mapload, set_keyword) - . = ..() - icon_state = "[rand(1,7)]" - color = rgb(rand(0,255), rand(0,255), rand(0,255)) - -/obj/effect/rune/malformed/invoke(list/invokers) - ..() - qdel(src) - -//Rite of Offering: Converts or sacrifices a target. -/obj/effect/rune/convert - cultist_name = "Offer" - cultist_desc = "offers a noncultist above it to Nar'Sie, either converting them or sacrificing them." - req_cultists_text = "2 for conversion, 3 for living sacrifices and sacrifice targets." - invocation = "Mah'weyh pleggh at e'ntrath!" - icon_state = "3" - color = RUNE_COLOR_OFFER - req_cultists = 1 - rune_in_use = FALSE - -/obj/effect/rune/convert/do_invoke_glow() - return - -/obj/effect/rune/convert/invoke(list/invokers) - if(rune_in_use) - return - var/list/myriad_targets = list() - var/turf/T = get_turf(src) - for(var/mob/living/M in T) - if(!iscultist(M)) - myriad_targets |= M - if(!myriad_targets.len) - fail_invoke() - log_game("Offer rune failed - no eligible targets") - return - rune_in_use = TRUE - visible_message("[src] pulses blood red!") - var/oldcolor = color - color = RUNE_COLOR_DARKRED - var/mob/living/L = pick(myriad_targets) - - var/mob/living/F = invokers[1] - var/datum/antagonist/cult/C = F.mind.has_antag_datum(/datum/antagonist/cult,TRUE) - var/datum/team/cult/Cult_team = C.cult_team - var/is_convertable = is_convertable_to_cult(L,C.cult_team) - if(L.stat != DEAD && is_convertable) - invocation = "Mah'weyh pleggh at e'ntrath!" - ..() - if(is_convertable) - do_convert(L, invokers) - else - invocation = "Barhah hra zar'garis!" - ..() - do_sacrifice(L, invokers) - animate(src, color = oldcolor, time = 5) - addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_atom_colour)), 5) - Cult_team.check_size() // Triggers the eye glow or aura effects if the cult has grown large enough relative to the crew - rune_in_use = FALSE - -/obj/effect/rune/convert/proc/do_convert(mob/living/convertee, list/invokers) - if(invokers.len < 2) - for(var/M in invokers) - to_chat(M, "You need at least two invokers to convert [convertee]!") - log_game("Offer rune failed - tried conversion with one invoker") - return 0 - if(convertee.anti_magic_check(TRUE, TRUE, FALSE, 0)) //Not chargecost because it can be spammed - for(var/M in invokers) - to_chat(M, "Something is shielding [convertee]'s mind!") - log_game("Offer rune failed - convertee had anti-magic") - return 0 - var/brutedamage = convertee.getBruteLoss() - var/burndamage = convertee.getFireLoss() - if(brutedamage || burndamage) - convertee.adjustBruteLoss(-(brutedamage * 0.75)) - convertee.adjustFireLoss(-(burndamage * 0.75)) - convertee.visible_message( - "[convertee] writhes in pain [brutedamage || burndamage ? "even as [convertee.p_their()] wounds heal and close" : "as the markings below [convertee.p_them()] glow a bloody red"]!", // Hello there buddy! Come here often? I hope you were wondering wtf this string was - "AAAAAAAAAAAAAA-") - SSticker.mode.add_cultist(convertee.mind, 1) - convertee.mind.special_role = ROLE_CULTIST - to_chat(convertee, "Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible, truth. The veil of reality has been ripped away \ - and something evil takes root.") - to_chat(convertee, "Assist your new compatriots in their dark dealings. Your goal is theirs, and theirs is yours. You serve the Geometer above all else. Bring it back.\ - ") - if(ishuman(convertee)) - var/mob/living/carbon/human/H = convertee - H.uncuff() - H.stuttering = 0 - H.cultslurring = 0 - if(prob(1) || SSevents.holidays && SSevents.holidays[APRIL_FOOLS]) - H.say("You son of a bitch! I'm in.", forced = "That son of a bitch! They're in.") - return 1 - -/obj/effect/rune/convert/proc/do_sacrifice(mob/living/sacrificial, list/invokers) - var/mob/living/first_invoker = invokers[1] - if(!first_invoker) - return FALSE - var/datum/antagonist/cult/C = first_invoker.mind.has_antag_datum(/datum/antagonist/cult,TRUE) - if(!C) - return - - - var/big_sac = FALSE - if((((ishuman(sacrificial) || iscyborg(sacrificial)) && sacrificial.stat != DEAD) || C.cult_team.is_sacrifice_target(sacrificial.mind)) && invokers.len < 3) - for(var/M in invokers) - to_chat(M, "[sacrificial] is too greatly linked to the world! You need three acolytes!") - log_game("Offer rune failed - not enough acolytes and target is living or sac target") - return FALSE - if(sacrificial.mind) - GLOB.sacrificed += sacrificial.mind - for(var/datum/objective/sacrifice/sac_objective in C.cult_team.objectives) - if(sac_objective.target == sacrificial.mind) - sac_objective.sacced = TRUE - sac_objective.update_explanation_text() - big_sac = TRUE - else - GLOB.sacrificed += sacrificial - - new /obj/effect/temp_visual/cult/sac(get_turf(src)) - for(var/M in invokers) - if(big_sac) - to_chat(M, "\"Yes! This is the one I desire! You have done well.\"") - else - if(ishuman(sacrificial) || iscyborg(sacrificial)) - to_chat(M, "\"I accept this sacrifice.\"") - else - to_chat(M, "\"I accept this meager sacrifice.\"") - - var/obj/item/soulstone/stone = new /obj/item/soulstone(get_turf(src)) - if(sacrificial.mind) - stone.invisibility = INVISIBILITY_MAXIMUM //so it's not picked up during transfer_soul() - stone.transfer_soul("FORCE", sacrificial, usr) - stone.invisibility = 0 - - if(sacrificial) - if(iscyborg(sacrificial)) - playsound(sacrificial, 'sound/magic/disable_tech.ogg', 100, TRUE) - sacrificial.dust() //To prevent the MMI from remaining - else - playsound(sacrificial, 'sound/magic/disintegrate.ogg', 100, TRUE) - sacrificial.gib() - return TRUE - - - -/obj/effect/rune/empower - cultist_name = "Empower" - cultist_desc = "allows cultists to prepare greater amounts of blood magic at far less of a cost." - invocation = "H'drak v'loso, mir'kanas verbot!" - icon_state = "3" - color = RUNE_COLOR_TALISMAN - construct_invoke = FALSE - -/obj/effect/rune/empower/invoke(list/invokers) - . = ..() - var/mob/living/user = invokers[1] //the first invoker is always the user - for(var/datum/action/innate/cult/blood_magic/BM in user.actions) - BM.Activate() - -/obj/effect/rune/teleport - cultist_name = "Teleport" - cultist_desc = "warps everything above it to another chosen teleport rune." - invocation = "Sas'so c'arta forbici!" - icon_state = "2" - color = RUNE_COLOR_TELEPORT - req_keyword = TRUE - light_power = 4 - var/obj/effect/temp_visual/cult/portal/inner_portal //The portal "hint" for off-station teleportations - var/obj/effect/temp_visual/cult/rune_spawn/rune2/outer_portal - var/listkey - - -/obj/effect/rune/teleport/Initialize(mapload, set_keyword) - . = ..() - var/area/A = get_area(src) - var/locname = initial(A.name) - listkey = set_keyword ? "[set_keyword] [locname]":"[locname]" - GLOB.teleport_runes += src - -/obj/effect/rune/teleport/Destroy() - GLOB.teleport_runes -= src - return ..() - -/obj/effect/rune/teleport/invoke(list/invokers) - var/mob/living/user = invokers[1] //the first invoker is always the user - var/list/potential_runes = list() - var/list/teleportnames = list() - for(var/R in GLOB.teleport_runes) - var/obj/effect/rune/teleport/T = R - if(T != src && !is_away_level(T)) - potential_runes[avoid_assoc_duplicate_keys(T.listkey, teleportnames)] = T - - if(!potential_runes.len) - to_chat(user, "There are no valid runes to teleport to!") - log_game("Teleport rune failed - no other teleport runes") - fail_invoke() - return - - var/turf/T = get_turf(src) - if(is_away_level(T)) - to_chat(user, "You are not in the right dimension!") - log_game("Teleport rune failed - user in away mission") - fail_invoke() - return - - var/input_rune_key = input(user, "Choose a rune to teleport to.", "Rune to Teleport to") as null|anything in potential_runes //we know what key they picked - var/obj/effect/rune/teleport/actual_selected_rune = potential_runes[input_rune_key] //what rune does that key correspond to? - if(!Adjacent(user) || !src || QDELETED(src) || user.incapacitated() || !actual_selected_rune) - fail_invoke() - return - - var/turf/target = get_turf(actual_selected_rune) - if(target.is_blocked_turf(TRUE)) - to_chat(user, "The target rune is blocked. Attempting to teleport to it would be massively unwise.") - fail_invoke() - return - var/movedsomething = FALSE - var/moveuserlater = FALSE - var/movesuccess = FALSE - for(var/atom/movable/A in T) - if(istype(A, /obj/effect/dummy/phased_mob)) - continue - if(ismob(A)) - if(!isliving(A)) //Let's not teleport ghosts and AI eyes. - continue - if(ishuman(A)) - new /obj/effect/temp_visual/dir_setting/cult/phase/out(T, A.dir) - new /obj/effect/temp_visual/dir_setting/cult/phase(target, A.dir) - if(A == user) - moveuserlater = TRUE - movedsomething = TRUE - continue - if(!A.anchored) - movedsomething = TRUE - if(do_teleport(A, target, channel = TELEPORT_CHANNEL_CULT)) - movesuccess = TRUE - if(movedsomething) - ..() - if(moveuserlater) - if(do_teleport(user, target, channel = TELEPORT_CHANNEL_CULT)) - movesuccess = TRUE - if(movesuccess) - visible_message("There is a sharp crack of inrushing air, and everything above the rune disappears!", null, "You hear a sharp crack.") - to_chat(user, "You[moveuserlater ? "r vision blurs, and you suddenly appear somewhere else":" send everything above the rune away"].") - else - to_chat(user, "You[moveuserlater ? "r vision blurs briefly, but nothing happens":" try send everything above the rune away, but the teleportation fails"].") - var/area/A = get_area(T) - if(initial(A.name) == "Space") - actual_selected_rune.handle_portal("space", T) - if(movesuccess) - 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, turf/origin) - var/turf/T = get_turf(src) - 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") - set_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" - set_light_color(LIGHT_COLOR_FIRE) - desc += "
A tear in reality reveals a coursing river of lava... something recently teleported here from the Lavaland Mines!" - outer_portal = new(T, 600, color) - light_range = 4 - update_light() - addtimer(CALLBACK(src, PROC_REF(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() - -//Ritual of Dimensional Rending: Calls forth the avatar of Nar'Sie upon the station. -/obj/effect/rune/narsie - cultist_name = "Nar'Sie" - cultist_desc = "tears apart dimensional barriers, calling forth the Geometer. Requires 9 invokers." - invocation = "TOK-LYR RQA-NAP G'OLT-ULOFT!!" - req_cultists = 9 - icon = 'icons/effects/96x96.dmi' - color = RUNE_COLOR_DARKRED - icon_state = "rune_large" - pixel_x = -32 //So the big ol' 96x96 sprite shows up right - pixel_y = -32 - scribe_delay = 500 //how long the rune takes to create - scribe_damage = 40.1 //how much damage you take doing it - var/used = FALSE - -/obj/effect/rune/narsie/Initialize(mapload, set_keyword) - . = ..() - SSpoints_of_interest.make_point_of_interest(src) - -/obj/effect/rune/narsie/Destroy() - SSpoints_of_interest.remove_point_of_interest(src) - . = ..() - -/obj/effect/rune/narsie/conceal() //can't hide this, and you wouldn't want to - return - -/obj/effect/rune/narsie/invoke(list/invokers) - if(used) - return - var/mob/living/user = invokers[1] - var/datum/antagonist/cult/user_antag = user.mind.has_antag_datum(/datum/antagonist/cult,TRUE) - var/datum/objective/eldergod/summon_objective = locate() in user_antag.cult_team.objectives - var/area/place = get_area(src) - if(!(place in summon_objective.summon_spots)) - to_chat(user, "The Geometer can only be summoned where the veil is weak - in [english_list(summon_objective.summon_spots)]!") - return - if(locate(/obj/singularity/narsie) in SSpoints_of_interest.other_points_of_interest) - for(var/M in invokers) - to_chat(M, "Nar'Sie is already on this plane!") - log_game("Nar'Sie rune failed - already summoned") - return - //BEGIN THE SUMMONING - used = TRUE - ..() - sound_to_playing_players('sound/effects/dimensional_rend.ogg') - var/turf/T = get_turf(src) - sleep(40) - if(src) - color = RUNE_COLOR_RED - new /obj/singularity/narsie/large/cult(T) //Causes Nar'Sie to spawn even if the rune has been removed - -//Rite of Resurrection: Requires a dead or inactive cultist. When reviving the dead, you can only perform one revival for every three sacrifices your cult has carried out. -/obj/effect/rune/raise_dead - cultist_name = "Revive" - cultist_desc = "requires a dead, mindless, or inactive cultist placed upon the rune. For each three bodies sacrificed to the dark patron, one body will be mended and their mind awoken" - invocation = "Pasnar val'keriam usinar. Savrae ines amutan. Yam'toth remium il'tarat!" //Depends on the name of the user - see below - icon_state = "1" - color = RUNE_COLOR_MEDIUMRED - var/static/sacrifices_used = -SOULS_TO_REVIVE // Cultists get one "free" revive - -/obj/effect/rune/raise_dead/examine(mob/user) - . = ..() - if(iscultist(user) || user.stat == DEAD) - . += "Sacrifices unrewarded: [LAZYLEN(GLOB.sacrificed) - sacrifices_used]" - -/obj/effect/rune/raise_dead/invoke(list/invokers) - var/turf/T = get_turf(src) - var/mob/living/mob_to_revive - var/list/potential_revive_mobs = list() - var/mob/living/user = invokers[1] - if(rune_in_use) - return - rune_in_use = TRUE - for(var/mob/living/M in T.contents) - if(iscultist(M) && (M.stat == DEAD || !M.client || M.client.is_afk())) - potential_revive_mobs |= M - if(!potential_revive_mobs.len) - to_chat(user, "There are no dead cultists on the rune!") - log_game("Raise Dead rune failed - no cultists to revive") - fail_invoke() - return - if(potential_revive_mobs.len > 1) - mob_to_revive = input(user, "Choose a cultist to revive.", "Cultist to Revive") as null|anything in potential_revive_mobs - else - mob_to_revive = potential_revive_mobs[1] - if(QDELETED(src) || !validness_checks(mob_to_revive, user)) - fail_invoke() - return - if(user.name == "Herbert West") - invocation = "To life, to life, I bring them!" - else - invocation = initial(invocation) - ..() - if(mob_to_revive.stat == DEAD) - var/diff = LAZYLEN(GLOB.sacrificed) - SOULS_TO_REVIVE - sacrifices_used - if(diff < 0) - to_chat(user, "Your cult must carry out [abs(diff)] more sacrifice\s before it can revive another cultist!") - fail_invoke() - return - sacrifices_used += SOULS_TO_REVIVE - mob_to_revive.revive(full_heal = TRUE, admin_revive = TRUE) //This does remove traits and such, but the rune might actually see some use because of it! - mob_to_revive.grab_ghost() - if(!mob_to_revive.client || mob_to_revive.client.is_afk()) - set waitfor = FALSE - var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a [mob_to_revive.name], an inactive blood cultist?", ROLE_CULTIST, null, ROLE_CULTIST, 50, mob_to_revive) - if(LAZYLEN(candidates)) - var/mob/dead/observer/C = pick(candidates) - to_chat(mob_to_revive.mind, "Your physical form has been taken over by another soul due to your inactivity! Ahelp if you wish to regain your form.") - message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(mob_to_revive)]) to replace an AFK player.") - mob_to_revive.ghostize(0) - mob_to_revive.key = C.key - else - fail_invoke() - return - SEND_SOUND(mob_to_revive, 'sound/ambience/antag/bloodcult.ogg') - to_chat(mob_to_revive, "\"PASNAR SAVRAE YAM'TOTH. Arise.\"") - mob_to_revive.visible_message( - "[mob_to_revive] draws in a huge breath, red light shining from [mob_to_revive.p_their()] eyes.", \ - "You awaken suddenly from the void. You're alive!") - rune_in_use = FALSE - -/obj/effect/rune/raise_dead/proc/validness_checks(mob/living/target_mob, mob/living/user) - var/turf/T = get_turf(src) - if(QDELETED(user)) - return FALSE - if(!Adjacent(user) || user.incapacitated()) - return FALSE - if(QDELETED(target_mob)) - return FALSE - if(!(target_mob in T.contents)) - to_chat(user, "The cultist to revive has been moved!") - log_game("Raise Dead rune failed - revival target moved") - return FALSE - return TRUE - -/obj/effect/rune/raise_dead/fail_invoke() - ..() - rune_in_use = FALSE - for(var/mob/living/M in range(1,src)) - if(iscultist(M) && M.stat == DEAD) - M.visible_message("[M] twitches.") - -//Rite of the Corporeal Shield: When invoked, becomes solid and cannot be passed. Invoke again to undo. -/obj/effect/rune/wall - cultist_name = "Barrier" - cultist_desc = "when invoked, makes a temporary invisible wall to block passage. Can be invoked again to reverse this." - invocation = "Khari'd! Eske'te tannin!" - icon_state = "4" - color = RUNE_COLOR_DARKRED - CanAtmosPass = ATMOS_PASS_DENSITY - var/datum/timedevent/density_timer - var/recharging = FALSE - -/obj/effect/rune/wall/Initialize(mapload, set_keyword) - . = ..() - GLOB.wall_runes += src - -/obj/effect/rune/wall/examine(mob/user) - . = ..() - if(density && iscultist(user)) - if(density_timer) - . += "The air above this rune has hardened into a barrier that will last [DisplayTimeText(density_timer.timeToRun - world.time)]." - -/obj/effect/rune/wall/Destroy() - GLOB.wall_runes -= src - return ..() - -/obj/effect/rune/wall/BlockThermalConductivity() - return density - -/obj/effect/rune/wall/invoke(list/invokers) - if(recharging) - return - var/mob/living/user = invokers[1] - ..() - density = !density - update_state() - if(density) - spread_density() - var/carbon_user = iscarbon(user) - user.visible_message( - "[user] [carbon_user ? "places [user.p_their()] hands on":"stares intently at"] [src], and [density ? "the air above it begins to shimmer" : "the shimmer above it fades"].", \ - "You channel [carbon_user ? "your life ":""]energy into [src], [density ? "temporarily preventing" : "allowing"] passage above it.") - if(carbon_user) - var/mob/living/carbon/C = user - C.apply_damage(2, BRUTE, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) - -/obj/effect/rune/wall/proc/spread_density() - for(var/R in GLOB.wall_runes) - var/obj/effect/rune/wall/W = R - if(W.virtual_z() == virtual_z() && get_dist(src, W) <= 2 && !W.density && !W.recharging) - W.density = TRUE - W.update_state() - W.spread_density() - density_timer = addtimer(CALLBACK(src, PROC_REF(lose_density)), 3000, TIMER_STOPPABLE) - -/obj/effect/rune/wall/proc/lose_density() - if(density) - recharging = TRUE - density = FALSE - update_state() - var/oldcolor = color - add_atom_colour("#696969", FIXED_COLOUR_PRIORITY) - animate(src, color = oldcolor, time = 50, easing = EASE_IN) - addtimer(CALLBACK(src, PROC_REF(recharge)), 50) - -/obj/effect/rune/wall/proc/recharge() - recharging = FALSE - add_atom_colour(RUNE_COLOR_MEDIUMRED, FIXED_COLOUR_PRIORITY) - -/obj/effect/rune/wall/proc/update_state() - deltimer(density_timer) - air_update_turf(TRUE) - if(density) - var/mutable_appearance/shimmer = mutable_appearance('icons/effects/effects.dmi', "barriershimmer", ABOVE_MOB_LAYER) - shimmer.appearance_flags |= RESET_COLOR - shimmer.alpha = 60 - shimmer.color = "#701414" - add_overlay(shimmer) - add_atom_colour(RUNE_COLOR_RED, FIXED_COLOUR_PRIORITY) - else - cut_overlays() - add_atom_colour(RUNE_COLOR_MEDIUMRED, FIXED_COLOUR_PRIORITY) - -//Rite of Joined Souls: Summons a single cultist. -/obj/effect/rune/summon - cultist_name = "Summon Cultist" - cultist_desc = "summons a single cultist to the rune. Requires 2 invokers." - invocation = "N'ath reth sh'yro eth d'rekkathnor!" - req_cultists = 2 - invoke_damage = 10 - icon_state = "3" - color = RUNE_COLOR_SUMMON - -/obj/effect/rune/summon/invoke(list/invokers) - var/mob/living/user = invokers[1] - var/list/cultists = list() - for(var/datum/mind/M in SSticker.mode.cult) - if(!(M.current in invokers) && M.current && M.current.stat != DEAD) - cultists |= M.current - var/mob/living/cultist_to_summon = input(user, "Who do you wish to call to [src]?", "Followers of the Geometer") as null|anything in cultists - if(!Adjacent(user) || !src || QDELETED(src) || user.incapacitated()) - return - if(!cultist_to_summon) - to_chat(user, "You require a summoning target!") - fail_invoke() - log_game("Summon Cultist rune failed - no target") - return - if(cultist_to_summon.stat == DEAD) - to_chat(user, "[cultist_to_summon] has died!") - fail_invoke() - log_game("Summon Cultist rune failed - target died") - return - if(cultist_to_summon.pulledby || cultist_to_summon.buckled) - to_chat(user, "[cultist_to_summon] is being held in place!") - fail_invoke() - log_game("Summon Cultist rune failed - target restrained") - return - if(!iscultist(cultist_to_summon)) - to_chat(user, "[cultist_to_summon] is not a follower of the Geometer!") - fail_invoke() - log_game("Summon Cultist rune failed - target was deconverted") - return - if(is_away_level(cultist_to_summon)) - to_chat(user, "[cultist_to_summon] is not in our dimension!") - fail_invoke() - log_game("Summon Cultist rune failed - target in away mission") - return - cultist_to_summon.visible_message( - "[cultist_to_summon] suddenly disappears in a flash of red light!", \ - "Overwhelming vertigo consumes you as you are hurled through the air!") - ..() - visible_message("A foggy shape materializes atop [src] and solidifes into [cultist_to_summon]!") - cultist_to_summon.forceMove(get_turf(src)) - qdel(src) - -//Rite of Boiling Blood: Deals extremely high amounts of damage to non-cultists nearby -/obj/effect/rune/blood_boil - cultist_name = "Boil Blood" - cultist_desc = "boils the blood of non-believers who can see the rune, rapidly dealing extreme amounts of damage. Requires 3 invokers." - invocation = "Dedo ol'btoh!" - icon_state = "4" - color = RUNE_COLOR_BURNTORANGE - light_color = LIGHT_COLOR_LAVA - req_cultists = 3 - invoke_damage = 10 - construct_invoke = FALSE - var/tick_damage = 25 - rune_in_use = FALSE - -/obj/effect/rune/blood_boil/do_invoke_glow() - return - -/obj/effect/rune/blood_boil/invoke(list/invokers) - if(rune_in_use) - return - ..() - rune_in_use = TRUE - var/turf/T = get_turf(src) - visible_message("[src] turns a bright, glowing orange!") - color = "#FC9B54" - set_light(6, 1, color) - for(var/mob/living/L in viewers(T)) - if(!iscultist(L) && L.blood_volume) - var/atom/I = L.anti_magic_check(chargecost = 0) - if(I) - if(isitem(I)) - to_chat(L, "[I] suddenly burns hotly before returning to normal!") - continue - to_chat(L, "Your blood boils in your veins!") - animate(src, color = "#FCB56D", time = 4) - sleep(4) - if(QDELETED(src)) - return - do_area_burn(T, 0.5) - animate(src, color = "#FFDF80", time = 5) - sleep(5) - if(QDELETED(src)) - return - do_area_burn(T, 1) - animate(src, color = "#FFFDF4", time = 6) - sleep(6) - if(QDELETED(src)) - return - do_area_burn(T, 1.5) - new /obj/effect/hotspot(T) - qdel(src) - -/obj/effect/rune/blood_boil/proc/do_area_burn(turf/T, multiplier) - set_light(6, 1, color) - for(var/mob/living/L in viewers(T)) - if(!iscultist(L) && L.blood_volume) - if(L.anti_magic_check(chargecost = 0)) - continue - L.take_overall_damage(tick_damage*multiplier, tick_damage*multiplier) - -//Rite of Spectral Manifestation: Summons a ghost on top of the rune as a cultist human with no items. User must stand on the rune at all times, and takes damage for each summoned ghost. -/obj/effect/rune/manifest - cultist_name = "Spirit Realm" - cultist_desc = "manifests a spirit servant of the Geometer and allows you to ascend as a spirit yourself. The invoker must not move from atop the rune, and will take damage for each summoned spirit." - invocation = "Gal'h'rfikk harfrandid mud'gib!" //how the fuck do you pronounce this - icon_state = "7" - invoke_damage = 10 - construct_invoke = FALSE - color = RUNE_COLOR_DARKRED - var/mob/living/affecting = null - var/ghost_limit = 3 - var/ghosts = 0 - -/obj/effect/rune/manifest/Initialize() - . = ..() - - -/obj/effect/rune/manifest/can_invoke(mob/living/user) - if(!(user in get_turf(src))) - to_chat(user, "You must be standing on [src]!") - fail_invoke() - log_game("Manifest rune failed - user not standing on rune") - return list() - if(user.has_status_effect(STATUS_EFFECT_SUMMONEDGHOST)) - to_chat(user, "Ghosts can't summon more ghosts!") - fail_invoke() - log_game("Manifest rune failed - user is a ghost") - return list() - return ..() - -/obj/effect/rune/manifest/invoke(list/invokers) - . = ..() - var/mob/living/user = invokers[1] - 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") - if(ghosts >= ghost_limit) - to_chat(user, "You are sustaining too many ghosts to summon more!") - fail_invoke() - log_game("Manifest rune failed - too many summoned ghosts") - return list() - notify_ghosts("Manifest rune invoked in [get_area(src)].", 'sound/effects/ghost2.ogg', source = src, header = "Manifest rune") - var/list/ghosts_on_rune = list() - for(var/mob/dead/observer/O in T) - if(O.client && !is_banned_from(O.ckey, ROLE_CULTIST) && !QDELETED(src) && !(isAdminObserver(O) && (O.client.prefs.toggles & ADMIN_IGNORE_CULT_GHOST)) && !QDELETED(O)) - ghosts_on_rune += O - if(!ghosts_on_rune.len) - to_chat(user, "There are no spirits near [src]!") - fail_invoke() - 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(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 - new_human.apply_status_effect(STATUS_EFFECT_SUMMONEDGHOST) //ghosts can't summon more ghosts - new_human.see_invisible = SEE_INVISIBLE_OBSERVER - ghosts++ - playsound(src, 'sound/magic/exit_blood.ogg', 50, TRUE) - visible_message("A cloud of red mist forms above [src], and from within steps... a [new_human.gender == FEMALE ? "wo":""]man.") - to_chat(user, "Your blood begins flowing into [src]. You must remain in place and conscious to maintain the forms of those summoned. This will hurt you slowly but surely...") - var/obj/structure/emergency_shield/invoker/N = new(T) - new_human.key = ghost_to_spawn.key - SSticker.mode.add_cultist(new_human.mind, 0) - to_chat(new_human, "You are a servant of the Geometer. You have been made semi-corporeal by the cult of Nar'Sie, and you are to serve them at all costs.") - - while(!QDELETED(src) && !QDELETED(user) && !QDELETED(new_human) && (user in T)) - if(user.stat != CONSCIOUS || HAS_TRAIT(new_human, TRAIT_CRITICAL_CONDITION)) - break - user.apply_damage(0.1, BRUTE) - sleep(1) - - qdel(N) - ghosts-- - if(new_human) - new_human.visible_message( - "[new_human] suddenly dissolves into bones and ashes.", \ - "Your link to the world fades. Your form breaks apart.") - for(var/obj/I in new_human) - new_human.dropItemToGround(I, TRUE) - new_human.dust() - else if(choice == "Ascend as a Dark Spirit") - affecting = user - affecting.add_atom_colour(RUNE_COLOR_DARKRED, ADMIN_COLOUR_PRIORITY) - affecting.visible_message( - "[affecting] freezes statue-still, glowing an unearthly red.", \ - "You see what lies beyond. All is revealed. In this form you find that your voice booms louder and you can mark targets for the entire cult") - var/mob/dead/observer/G = affecting.ghostize(1) - var/datum/action/innate/cult/comm/spirit/CM = new - var/datum/action/innate/cult/ghostmark/GM = new - G.name = "Dark Spirit of [G.name]" - G.color = "red" - CM.Grant(G) - GM.Grant(G) - while(!QDELETED(affecting)) - if(!(affecting in T)) - user.visible_message("A spectral tendril wraps around [affecting] and pulls [affecting.p_them()] back to the rune!") - Beam(affecting, icon_state="drainbeam", time=2) - affecting.forceMove(get_turf(src)) //NO ESCAPE :^) - if(affecting.key) - affecting.visible_message( - "[affecting] slowly relaxes, the glow around [affecting.p_them()] dimming.", \ - "You are re-united with your physical form. [src] releases its hold over you.") - affecting.Paralyze(40) - break - if(affecting.health <= 10) - to_chat(G, "Your body can no longer sustain the connection!") - break - sleep(5) - CM.Remove(G) - GM.Remove(G) - affecting.remove_atom_colour(ADMIN_COLOUR_PRIORITY, RUNE_COLOR_DARKRED) - affecting.grab_ghost() - affecting = null - rune_in_use = FALSE - -/mob/living/carbon/human/cult_ghost/spill_organs(no_brain, no_organs, no_bodyparts) //cult ghosts never drop a brain - no_brain = TRUE - . = ..() - -/mob/living/carbon/human/cult_ghost/getorganszone(zone, subzones = 0) - . = ..() - for(var/obj/item/organ/brain/B in .) //they're not that smart, really - . -= B - - -/obj/effect/rune/apocalypse - cultist_name = "Apocalypse" - cultist_desc = "a harbinger of the end times. Grows in strength with the cult's desperation - but at the risk of... side effects." - invocation = "Ta'gh fara'qha fel d'amar det!" - icon = 'icons/effects/96x96.dmi' - icon_state = "apoc" - pixel_x = -32 - pixel_y = -32 - color = RUNE_COLOR_DARKRED - req_cultists = 3 - scribe_delay = 100 - -/obj/effect/rune/apocalypse/invoke(list/invokers) - if(rune_in_use) - return - . = ..() - var/area/place = get_area(src) - var/mob/living/user = invokers[1] - var/datum/antagonist/cult/user_antag = user.mind.has_antag_datum(/datum/antagonist/cult,TRUE) - var/datum/objective/eldergod/summon_objective = locate() in user_antag.cult_team.objectives - if(summon_objective.summon_spots.len <= 1) - to_chat(user, "Only one ritual site remains - it must be reserved for the final summoning!") - return - if(!(place in summon_objective.summon_spots)) - to_chat(user, "The Apocalypse rune will remove a ritual site, where Nar'Sie can be summoned, it can only be scribed in [english_list(summon_objective.summon_spots)]!") - return - summon_objective.summon_spots -= place - rune_in_use = TRUE - var/turf/T = get_turf(src) - new /obj/effect/temp_visual/dir_setting/curse/grasp_portal/fading(T) - var/intensity = 0 - for(var/mob/living/M in GLOB.player_list) - if(iscultist(M)) - intensity++ - intensity = max(60, 360 - (360*(intensity/GLOB.player_list.len + 0.3)**2)) //significantly lower intensity for "winning" cults - var/duration = intensity*10 - playsound(T, 'sound/magic/enter_blood.ogg', 100, TRUE) - visible_message("A colossal shockwave of energy bursts from the rune, disintegrating it in the process!") - for(var/mob/living/L in range(src, 3)) - L.Paralyze(30) - empulse(T, 0.42*(intensity), 1) - var/list/images = list() - var/zmatch = T.virtual_z() - var/datum/atom_hud/AH = GLOB.huds[DATA_HUD_SECURITY_ADVANCED] - for(var/mob/living/M in GLOB.alive_mob_list) - if(M.virtual_z() != zmatch) - continue - if(ishuman(M)) - if(!iscultist(M)) - AH.remove_hud_from(M) - addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(hudFix), M), duration) - var/image/A = image('icons/mob/cult.dmi',M,"cultist", ABOVE_MOB_LAYER) - A.override = 1 - add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/noncult, "human_apoc", A, NONE) - addtimer(CALLBACK(M, TYPE_PROC_REF(/atom, remove_alt_appearance),"human_apoc",TRUE), duration) - images += A - SEND_SOUND(M, pick(sound('sound/ambience/antag/bloodcult.ogg'),sound('sound/spookoween/ghost_whisper.ogg'),sound('sound/spookoween/ghosty_wind.ogg'))) - else - var/construct = pick("floater","artificer","behemoth") - var/image/B = image('icons/mob/mob.dmi',M,construct, ABOVE_MOB_LAYER) - B.override = 1 - add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/noncult, "mob_apoc", B, NONE) - addtimer(CALLBACK(M, TYPE_PROC_REF(/atom, remove_alt_appearance),"mob_apoc",TRUE), duration) - images += B - if(!iscultist(M)) - if(M.client) - var/image/C = image('icons/effects/cult_effects.dmi',M,"bloodsparkles", ABOVE_MOB_LAYER) - add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/cult, "cult_apoc", C, NONE) - addtimer(CALLBACK(M, TYPE_PROC_REF(/atom, remove_alt_appearance),"cult_apoc",TRUE), duration) - images += C - else - to_chat(M, "An Apocalypse Rune was invoked in the [place.name], it is no longer available as a summoning site!") - SEND_SOUND(M, 'sound/effects/pope_entry.ogg') - image_handler(images, duration) - if(intensity>=285) // Based on the prior formula, this means the cult makes up <15% of current players - var/outcome = rand(1,80) - switch(outcome) - if(1 to 10) - var/datum/round_event_control/disease_outbreak/D = new() - // var/datum/round_event_control/mice_migration/M = new() - D.runEvent() - // M.runEvent() - if(11 to 20) - var/datum/round_event_control/radiation_storm/RS = new() - RS.runEvent() - if(21 to 30) - var/datum/round_event_control/brand_intelligence/BI = new() - BI.runEvent() - if(31 to 40) - var/datum/round_event_control/immovable_rod/R = new() - R.runEvent() - R.runEvent() - R.runEvent() - if(41 to 50) - var/datum/round_event_control/meteor_wave/MW = new() - MW.runEvent() - if(51 to 60) - var/datum/round_event_control/spider_infestation/SI = new() - SI.runEvent() - if(61 to 80) - var/datum/round_event_control/spacevine/SV = new() - var/datum/round_event_control/grey_tide/GT = new() - SV.runEvent() - GT.runEvent() - qdel(src) - -/obj/effect/rune/apocalypse/proc/image_handler(list/images, duration) - var/end = world.time + duration - set waitfor = 0 - while(end>world.time) - for(var/image/I in images) - I.override = FALSE - animate(I, alpha = 0, time = 25, flags = ANIMATION_PARALLEL) - sleep(35) - for(var/image/I in images) - animate(I, alpha = 255, time = 25, flags = ANIMATION_PARALLEL) - sleep(25) - for(var/image/I in images) - if(I.icon_state != "bloodsparkles") - I.override = TRUE - sleep(190) - - - -/proc/hudFix(mob/living/carbon/human/target) - if(!target || !target.client) - return - var/obj/O = target.get_item_by_slot(ITEM_SLOT_EYES) - if(istype(O, /obj/item/clothing/glasses/hud/security)) - var/datum/atom_hud/AH = GLOB.huds[DATA_HUD_SECURITY_ADVANCED] - AH.add_hud_to(target) diff --git a/code/modules/antagonists/devil/devil.dm b/code/modules/antagonists/devil/devil.dm deleted file mode 100644 index db087e100e2f..000000000000 --- a/code/modules/antagonists/devil/devil.dm +++ /dev/null @@ -1,506 +0,0 @@ -#define BLOOD_THRESHOLD 3 //How many souls are needed per stage. -#define TRUE_THRESHOLD 7 -#define ARCH_THRESHOLD 12 - -#define BASIC_DEVIL 0 -#define BLOOD_lizard 1 -#define TRUE_DEVIL 2 -#define ARCH_DEVIL 3 - -#define LOSS_PER_DEATH 2 - -#define SOULVALUE soulsOwned.len-reviveNumber - -#define DEVILRESURRECTTIME 600 - -GLOBAL_LIST_EMPTY(allDevils) -GLOBAL_LIST_INIT(lawlorify, list ( - LORE = list( - OBLIGATION_FOOD = "This devil seems to always offer its victims food before slaughtering them.", - OBLIGATION_FIDDLE = "This devil will never turn down a musical challenge.", - OBLIGATION_DANCEOFF = "This devil will never turn down a dance off.", - OBLIGATION_GREET = "This devil seems to only be able to converse with people it knows the name of.", - OBLIGATION_PRESENCEKNOWN = "This devil seems to be unable to attack from stealth.", - OBLIGATION_SAYNAME = "He will always chant his name upon killing someone.", - OBLIGATION_ANNOUNCEKILL = "This devil always loudly announces his kills for the world to hear.", - OBLIGATION_ANSWERTONAME = "This devil always responds to his truename.", - BAN_HURTWOMAN = "This devil seems to prefer hunting men.", - BAN_CHAPEL = "This devil avoids holy ground.", - BAN_HURTPRIEST = "The annointed clergy appear to be immune to his powers.", - BAN_AVOIDWATER = "The devil seems to have some sort of aversion to water, though it does not appear to harm him.", - BAN_STRIKEUNCONSCIOUS = "This devil only shows interest in those who are awake.", - BAN_HURTlizard = "This devil will not strike a lizardman first.", - BAN_HURTANIMAL = "This devil avoids hurting animals.", - BANISH_WATER = "To banish the devil, you must infuse its body with holy water.", - BANISH_COFFIN = "This devil will return to life if its remains are not placed within a coffin.", - BANISH_FORMALDYHIDE = "To banish the devil, you must inject its lifeless body with embalming fluid.", - BANISH_RUNES = "This devil will resurrect after death, unless its remains are within a rune.", - BANISH_CANDLES = "A large number of nearby lit candles will prevent it from resurrecting.", - BANISH_DESTRUCTION = "Its corpse must be utterly destroyed to prevent resurrection.", - BANISH_FUNERAL_GARB = "If clad in funeral garments, this devil will be unable to resurrect. Should the clothes not fit, lay them gently on top of the devil's corpse." - ), - LAW = list( - OBLIGATION_FOOD = "When not acting in self defense, you must always offer your victim food before harming them.", - OBLIGATION_FIDDLE = "When not in immediate danger, if you are challenged to a musical duel, you must accept it. You are not obligated to duel the same person twice.", - OBLIGATION_DANCEOFF = "When not in immediate danger, if you are challenged to a dance off, you must accept it. You are not obligated to face off with the same person twice.", - OBLIGATION_GREET = "You must always greet other people by their last name before talking with them.", - OBLIGATION_PRESENCEKNOWN = "You must always make your presence known before attacking.", - OBLIGATION_SAYNAME = "You must always say your true name after you kill someone.", - OBLIGATION_ANNOUNCEKILL = "Upon killing someone, you must make your deed known to all within earshot, over comms if reasonably possible.", - OBLIGATION_ANSWERTONAME = "If you are not under attack, you must always respond to your true name.", - BAN_HURTWOMAN = "You must never harm a female outside of self defense.", - BAN_CHAPEL = "You must never attempt to enter the chapel.", - BAN_HURTPRIEST = "You must never attack a priest.", - BAN_AVOIDWATER = "You must never willingly touch a wet surface.", - BAN_STRIKEUNCONSCIOUS = "You must never strike an unconscious person.", - BAN_HURTlizard = "You must never harm a lizardman outside of self defense.", - BAN_HURTANIMAL = "You must never harm a non-sentient creature or robot outside of self defense.", - BANISH_WATER = "If your corpse is filled with holy water, you will be unable to resurrect.", - BANISH_COFFIN = "If your corpse is in a coffin, you will be unable to resurrect.", - BANISH_FORMALDYHIDE = "If your corpse is embalmed, you will be unable to resurrect.", - BANISH_RUNES = "If your corpse is placed within a rune, you will be unable to resurrect.", - BANISH_CANDLES = "If your corpse is near lit candles, you will be unable to resurrect.", - BANISH_DESTRUCTION = "If your corpse is destroyed, you will be unable to resurrect.", - BANISH_FUNERAL_GARB = "If your corpse is clad in funeral garments, you will be unable to resurrect." - ) - )) - -//These are also used in the codex gigas, so let's declare them globally. -GLOBAL_LIST_INIT(devil_pre_title, list("Dark ", "Hellish ", "Fallen ", "Fiery ", "Sinful ", "Blood ", "Fluffy ")) -GLOBAL_LIST_INIT(devil_title, list("Lord ", "Prelate ", "Count ", "Viscount ", "Vizier ", "Elder ", "Adept ")) -GLOBAL_LIST_INIT(devil_syllable, list("hal", "ve", "odr", "neit", "ci", "quon", "mya", "folth", "wren", "geyr", "hil", "niet", "twou", "phi", "coa")) -GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master", ", the Lord of all things", ", Jr.")) -/datum/antagonist/devil - name = "Devil" - roundend_category = "devils" - antagpanel_category = "Devil" - job_rank = ROLE_DEVIL - antag_hud_type = ANTAG_HUD_DEVIL - antag_hud_name = "devil" - show_to_ghosts = TRUE - var/obligation - var/ban - var/banish - var/truename - var/list/datum/mind/soulsOwned = new - var/reviveNumber = 0 - var/form = BASIC_DEVIL - var/static/list/devil_spells = typecacheof(list( - /obj/effect/proc_holder/spell/aimed/fireball/hellish, - /obj/effect/proc_holder/spell/targeted/infernal_jaunt, - /obj/effect/proc_holder/spell/targeted/sintouch, - /obj/effect/proc_holder/spell/targeted/sintouch/ascended, - /obj/effect/proc_holder/spell/targeted/summon_contract, - /obj/effect/proc_holder/spell/targeted/conjure_item/violin, - /obj/effect/proc_holder/spell/targeted/summon_dancefloor)) - var/ascendable = FALSE - -/datum/antagonist/devil/can_be_owned(datum/mind/new_owner) - . = ..() - return . && (ishuman(new_owner.current) || iscyborg(new_owner.current)) - -/datum/antagonist/devil/get_admin_commands() - . = ..() - .["Toggle ascendable"] = CALLBACK(src, PROC_REF(admin_toggle_ascendable)) - - -/datum/antagonist/devil/proc/admin_toggle_ascendable(mob/admin) - ascendable = !ascendable - message_admins("[key_name_admin(admin)] set [key_name_admin(owner)] devil ascendable to [ascendable]") - log_admin("[key_name_admin(admin)] set [key_name(owner)] devil ascendable to [ascendable])") - -/datum/antagonist/devil/admin_add(datum/mind/new_owner,mob/admin) - switch(alert(admin,"Should the devil be able to ascend",,"Yes","No","Cancel")) - if("Yes") - ascendable = TRUE - if("No") - ascendable = FALSE - else - return - new_owner.add_antag_datum(src) - message_admins("[key_name_admin(admin)] has devil'ed [key_name_admin(new_owner)]. [ascendable ? "(Ascendable)":""]") - log_admin("[key_name(admin)] has devil'ed [key_name(new_owner)]. [ascendable ? "(Ascendable)":""]") - -/datum/antagonist/devil/antag_listing_name() - return ..() + "([truename])" - -/proc/devilInfo(name) - if(GLOB.allDevils[lowertext(name)]) - return GLOB.allDevils[lowertext(name)] - else - var/datum/fakeDevil/devil = new /datum/fakeDevil(name) - GLOB.allDevils[lowertext(name)] = devil - return devil - -/proc/randomDevilName() - var/name = "" - if(prob(65)) - if(prob(35)) - name = pick(GLOB.devil_pre_title) - name += pick(GLOB.devil_title) - var/probability = 100 - name += pick(GLOB.devil_syllable) - while(prob(probability)) - name += pick(GLOB.devil_syllable) - probability -= 20 - if(prob(40)) - name += pick(GLOB.devil_suffix) - return name - -/proc/randomdevilobligation() - return pick(OBLIGATION_FOOD, OBLIGATION_FIDDLE, OBLIGATION_DANCEOFF, OBLIGATION_GREET, OBLIGATION_PRESENCEKNOWN, OBLIGATION_SAYNAME, OBLIGATION_ANNOUNCEKILL, OBLIGATION_ANSWERTONAME) - -/proc/randomdevilban() - return pick(BAN_HURTWOMAN, BAN_CHAPEL, BAN_HURTPRIEST, BAN_AVOIDWATER, BAN_STRIKEUNCONSCIOUS, BAN_HURTLIZARD, BAN_HURTANIMAL) - -/proc/randomdevilbanish() - return pick(BANISH_WATER, BANISH_COFFIN, BANISH_FORMALDYHIDE, BANISH_RUNES, BANISH_CANDLES, BANISH_DESTRUCTION, BANISH_FUNERAL_GARB) - -/datum/antagonist/devil/proc/add_soul(datum/mind/soul) - if(soulsOwned.Find(soul)) - return - soulsOwned += soul - owner.current.set_nutrition(NUTRITION_LEVEL_FULL) - to_chat(owner.current, "You feel satiated as you received a new soul.") - update_hud() - switch(SOULVALUE) - if(0) - to_chat(owner.current, "Your hellish powers have been restored.") - give_appropriate_spells() - if(BLOOD_THRESHOLD) - increase_blood_lizard() - if(TRUE_THRESHOLD) - increase_true_devil() - if(ARCH_THRESHOLD) - increase_arch_devil() - -/datum/antagonist/devil/proc/remove_soul(datum/mind/soul) - if(soulsOwned.Remove(soul)) - check_regression() - to_chat(owner.current, "You feel as though a soul has slipped from your grasp.") - update_hud() - -/datum/antagonist/devil/proc/check_regression() - if(form == ARCH_DEVIL) - return //arch devil can't regress - //Yes, fallthrough behavior is intended, so I can't use a switch statement. - if(form == TRUE_DEVIL && SOULVALUE < TRUE_THRESHOLD) - regress_blood_lizard() - if(form == BLOOD_lizard && SOULVALUE < BLOOD_THRESHOLD) - regress_humanoid() - if(SOULVALUE < 0) - give_appropriate_spells() - to_chat(owner.current, "As punishment for your failures, all of your powers except contract creation have been revoked.") - -/datum/antagonist/devil/proc/regress_humanoid() - to_chat(owner.current, "Your powers weaken, have more contracts be signed to regain power.") - if(ishuman(owner.current)) - var/mob/living/carbon/human/H = owner.current - H.set_species(/datum/species/human, 1) - H.regenerate_icons() - give_appropriate_spells() - if(istype(owner.current.loc, /obj/effect/dummy/phased_mob/slaughter/)) - owner.current.forceMove(get_turf(owner.current))//Fixes dying while jaunted leaving you permajaunted. - form = BASIC_DEVIL - -/datum/antagonist/devil/proc/regress_blood_lizard() - var/mob/living/carbon/true_devil/D = owner.current - to_chat(D, "Your powers weaken, have more contracts be signed to regain power.") - D.oldform.forceMove(D.drop_location()) - owner.transfer_to(D.oldform) - give_appropriate_spells() - qdel(D) - form = BLOOD_lizard - update_hud() - - -/datum/antagonist/devil/proc/increase_blood_lizard() - to_chat(owner.current, "You feel as though your humanoid form is about to shed. You will soon turn into a blood lizard.") - sleep(50) - if(ishuman(owner.current)) - var/mob/living/carbon/human/H = owner.current - H.set_species(/datum/species/lizard, 1) - H.underwear = "Nude" - H.undershirt = "Nude" - H.socks = "Nude" - H.dna.features["mcolor"] = "511" //A deep red - H.regenerate_icons() - else //Did the devil get hit by a staff of transmutation? - owner.current.color = "#501010" - give_appropriate_spells() - form = BLOOD_lizard - - - -/datum/antagonist/devil/proc/increase_true_devil() - to_chat(owner.current, "You feel as though your current form is about to shed. You will soon turn into a true devil.") - sleep(50) - var/mob/living/carbon/true_devil/A = new /mob/living/carbon/true_devil(owner.current.loc) - A.faction |= "hell" - owner.current.forceMove(A) - A.oldform = owner.current - owner.transfer_to(A) - A.set_devil_name() - give_appropriate_spells() - form = TRUE_DEVIL - update_hud() - -/datum/antagonist/devil/proc/increase_arch_devil() - if(!ascendable) - return - var/mob/living/carbon/true_devil/D = owner.current - to_chat(D, "You feel as though your form is about to ascend.") - sleep(50) - if(!D) - return - D.visible_message("[D]'s skin begins to erupt with spikes.", \ - "Your flesh begins creating a shield around yourself.") - sleep(100) - if(!D) - return - D.visible_message("The horns on [D]'s head slowly grow and elongate.", \ - "Your body continues to mutate. Your telepathic abilities grow.") - sleep(90) - if(!D) - return - D.visible_message("[D]'s body begins to violently stretch and contort.", \ - "You begin to rend apart the final barriers to ultimate power.") - sleep(40) - if(!D) - return - to_chat(D, "Yes!") - sleep(10) - if(!D) - return - to_chat(D, "YES!!") - sleep(10) - if(!D) - return - to_chat(D, "YE--") - sleep(1) - if(!D) - return - send_to_playing_players("\"SLOTH, WRATH, GLUTTONY, ACEDIA, ENVY, GREED, PRIDE! FIRES OF HELL AWAKEN!!\"") - sound_to_playing_players('sound/hallucinations/veryfar_noise.ogg') - give_appropriate_spells() - D.convert_to_archdevil() - if(istype(D.loc, /obj/effect/dummy/phased_mob/slaughter/)) - D.forceMove(get_turf(D))//Fixes dying while jaunted leaving you permajaunted. - var/area/A = get_area(owner.current) - if(A) - notify_ghosts("An arch devil has ascended in \the [A.name]. Reach out to the devil to be given a new shell for your soul.", source = owner.current, action=NOTIFY_ATTACK) - sleep(50) - form = ARCH_DEVIL - -/datum/antagonist/devil/proc/remove_spells() - for(var/X in owner.spell_list) - var/obj/effect/proc_holder/spell/S = X - if(is_type_in_typecache(S, devil_spells)) - owner.RemoveSpell(S) - -/datum/antagonist/devil/proc/give_summon_contract() - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_contract(null)) - if(obligation == OBLIGATION_FIDDLE) - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/conjure_item/violin(null)) - else if(obligation == OBLIGATION_DANCEOFF) - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/summon_dancefloor(null)) - -/datum/antagonist/devil/proc/give_appropriate_spells() - remove_spells() - give_summon_contract() - if(SOULVALUE >= ARCH_THRESHOLD && ascendable) - give_arch_spells() - else if(SOULVALUE >= TRUE_THRESHOLD) - give_true_spells() - else if(SOULVALUE >= BLOOD_THRESHOLD) - give_blood_spells() - else if(SOULVALUE >= 0) - give_base_spells() - -/datum/antagonist/devil/proc/give_base_spells() - owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball/hellish(null)) - -/datum/antagonist/devil/proc/give_blood_spells() - owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball/hellish(null)) - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/infernal_jaunt(null)) - -/datum/antagonist/devil/proc/give_true_spells() - owner.AddSpell(new /obj/effect/proc_holder/spell/aimed/fireball/hellish(null)) - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/infernal_jaunt(null)) - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/sintouch(null)) - -/datum/antagonist/devil/proc/give_arch_spells() - owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/sintouch/ascended(null)) - -/datum/antagonist/devil/proc/beginResurrectionCheck(mob/living/body) - if(SOULVALUE>0) - to_chat(owner.current, "Your body has been damaged to the point that you may no longer use it. At the cost of some of your power, you will return to life soon. Remain in your body.") - sleep(DEVILRESURRECTTIME) - if (!body || body.stat == DEAD) - if(SOULVALUE>0) - if(check_banishment(body)) - to_chat(owner.current, "Unfortunately, the mortals have finished a ritual that prevents your resurrection.") - return -1 - else - to_chat(owner.current, "WE LIVE AGAIN!") - return hellish_resurrection(body) - else - to_chat(owner.current, "Unfortunately, the power that stemmed from your contracts has been extinguished. You no longer have enough power to resurrect.") - return -1 - else - to_chat(owner.current, "You seem to have resurrected without your hellish powers.") - else - to_chat(owner.current, "Your hellish powers are too weak to resurrect yourself.") - -/datum/antagonist/devil/proc/check_banishment(mob/living/body) - switch(banish) - if(BANISH_WATER) - if(iscarbon(body)) - var/mob/living/carbon/H = body - return H.reagents.has_reagent(/datum/reagent/water/holywater) - return 0 - if(BANISH_COFFIN) - return (body && istype(body.loc, /obj/structure/closet/crate/coffin)) - if(BANISH_FORMALDYHIDE) - if(iscarbon(body)) - var/mob/living/carbon/H = body - return H.reagents.has_reagent(/datum/reagent/toxin/formaldehyde) - return 0 - if(BANISH_RUNES) - if(body) - for(var/obj/effect/decal/cleanable/crayon/R in range(0,body)) - if (R.name == "rune") - return 1 - return 0 - if(BANISH_CANDLES) - if(body) - var/count = 0 - for(var/obj/item/candle/C in range(1,body)) - count += C.lit - if(count>=4) - return 1 - return 0 - if(BANISH_DESTRUCTION) - if(body) - return 0 - return 1 - if(BANISH_FUNERAL_GARB) - if(ishuman(body)) - var/mob/living/carbon/human/H = body - if(H.w_uniform && istype(H.w_uniform, /obj/item/clothing/under/suit/white_on_white)) - return 1 - return 0 - else - for(var/obj/item/clothing/under/suit/white_on_white/B in range(0,body)) - if(B.loc == get_turf(B)) //Make sure it's not in someone's inventory or something. - return 1 - return 0 - -/datum/antagonist/devil/proc/hellish_resurrection(mob/living/body) - message_admins("[key_name_admin(owner)] (true name is: [truename]) is resurrecting using hellish energy.
?F0J^nqSPC~}3^Cu)#C(Spq<(~-zVuw_Lu#5`^*6aO6TdrX
z1LN**`CQw4)k6bb1qLRguR!+Ajk+o^wcAxIr1~(U8-8c&YS|YsC*?O|v`>d$ruVbS
zEkn#EE9i#7vrPkaz`Zge3b03e734X1P^Mf`!gXo}#C9FXLJh(Nd}R$||IGKTe&eU8
zQ`M`hF}(33c3Pj7Ml!_PZs@)h%s=Txq*sqHg5=D Z?1ce_yGHkt6ml9u)?3)wmG J{XdE2IQlmJpR eZ
zLSbmW9+-d;5x6X@SjW1kN5;R#|_
zBmCc2^!x
57RN%{HXUF3N%x6Jc{udc^y5%}*i$n^UHpD$O7y;#hrnj*}!&QJP<
zd_Yz%@Du}M{+!IjbbXHxxh>7grRas$?`9UDgG=FGpCkJ;RRMGA5&yNXd7q9IX?TPt
z$=`R@kv$D94*jlnI8KZU%b5+I}!nQ;}NWh&hKQ)nhCASif
z=FVW>gIx*y0MfLo7&8R-htZG9%VIb>aBs@n6zGMr!4*yR`_lRyH9;4LcR=z`jOJ_<
z)9JU9Bp#P&hn3Lj;FU$5hjh&2nHjpU8!I_`C(@;=ZJPsZq
zJWyTm^peX`r(mWgD5SGfs>OLKffPmROfLy{$~^2IjoJGh2MWo-sa|RJXKlZ6Rld8G
z{Vr;y#Xo76??~<4;Zo