From b9577a1f7f30b2b3713d1aa1c0aa333b32cd4417 Mon Sep 17 00:00:00 2001
From: EgorDinamit <53223414+EgorDinamit@users.noreply.github.com>
Date: Wed, 6 Dec 2023 22:37:59 +0300
Subject: [PATCH] Facility upgrades (#1644)
* Initial changes
* Facility upgrades!
* Max bullet ammo upgrade + some fixes/tweaks
* Fix bulletes
* More upgrades, dynamic cost, more LOB points
* Some fixes
* Fix healing upgrade
* Some adjustments
* Oopsie
* Bonus to earned abno understanding on low agent pop
* Display value of heal increase is fixed
* Meltdown count scales with agent pop
* Extra cores only need the midnight being done in time limit.
* Tiny "fix"
* Logs console displays understanding level
* Agent stats upgrade has dynamic cost now
* Agent stats upgrade applies to all living agents on purchase
* Oopsie
* All conflicts fixed
* oop
* Command core quick fix
* Melt time upgrade dynamic cost
* Tiny buff
* Command core suppression tweaks
* FIX AOE BULLETS
* Fixes pale fixer teleport, hopefuly
* Records run text fix
* Don't swap abnos that are being worked
* Assorted twewaks and fixes for records core
* qdel check
* More core options at the start
* Tweak records core
* Added connected structures system to abnos; Minor tweaks.
* Core suppression "code refactor"
* A better core suppression code refactor
* Even more core stuff; Added persistent info on cores
* Proper desc and run text for day 47 core
* This should fix CC core.
* Day 47 proper requirements
* Minor spelling mistake
* Minor fixes to records core
* Various fixes
* fix..?
* Tweaks to upgrades
* Manager camera fixes
* All keter ordeals
* Fix text alignment
* Keter requirements only check the agent players
* Manager camera + holo commands code improvement
* Tiny fix
* Training core description is now more accurate
* Fix connected structures
* Fixes
* Training core during Keter is inverted
* Keter text fix
* PBird perch fix
* Command core fix
* Insane examine text fix
* Nobody Is connected structure
---
.../tegu_items/gadgets/manager_bullets.dm | 1 +
.../tegu_items/gadgets/unpowered.dm | 14 +-
code/__DEFINES/dcs/signals.dm | 4 +
code/__DEFINES/facility_upgrades.dm | 20 ++
code/__DEFINES/lobotomy_corp.dm | 17 +
code/__HELPERS/lobotomy_corp.dm | 26 ++
code/__HELPERS/priority_announce.dm | 4 +-
.../subsystem/abnormality_queue.dm | 2 +-
code/controllers/subsystem/lobotomy_corp.dm | 40 ++-
code/controllers/subsystem/persistence.dm | 31 ++
code/datums/abnormality/datum/abnormality.dm | 25 +-
code/datums/facility_upgrade.dm | 192 ++++++++++++
.../computer/abnormality_auxilary.dm | 67 ----
.../computer/abnormality_auxiliary.dm | 131 ++++++++
.../machinery/computer/abnormality_logs.dm | 5 +-
.../machinery/computer/abnormality_work.dm | 7 +-
.../machinery/computer/camera_advanced.dm | 2 +-
code/game/machinery/computer/crew.dm | 2 +-
.../game/machinery/computer/manager_camera.dm | 262 ++++++++--------
.../temporary_visuals/miscellaneous.dm | 14 +-
code/game/objects/items/clerks/hypo/hypo.dm | 2 +-
code/modules/jobs/job_types/agent.dm | 34 +-
.../mob/living/carbon/human/examine.dm | 2 +-
.../simple_animal/abnormality/_abnormality.dm | 28 +-
.../abnormality/aleph/crying_children.dm | 1 +
.../abnormality/aleph/nobody_is.dm | 5 +-
.../abnormality/aleph/nothing_there.dm | 1 +
.../abnormality/he/galaxy_child.dm | 1 +
.../abnormality/teth/beauty_beast.dm | 1 +
.../abnormality/teth/meat_lantern.dm | 1 +
.../abnormality/teth/punishing_bird.dm | 32 +-
.../abnormality/teth/spider_bud.dm | 3 +-
.../abnormality/waw/fire_bird.dm | 10 +-
.../abnormality/zayin/wellcheers.dm | 29 +-
.../simple_animal/hostile/ordeal/white.dm | 7 +-
code/modules/ordeals/_ordeal.dm | 7 +-
.../reagents/reagent_containers/hypospray.dm | 2 +-
.../modules/suppressions/_core_suppression.dm | 19 +-
code/modules/suppressions/command.dm | 23 +-
code/modules/suppressions/control.dm | 6 +-
code/modules/suppressions/extraction.dm | 6 +-
code/modules/suppressions/information.dm | 12 +-
code/modules/suppressions/keter.dm | 290 ++++++++++++++++++
code/modules/suppressions/records.dm | 36 ++-
code/modules/suppressions/safety.dm | 6 +-
code/modules/suppressions/training.dm | 16 +-
code/modules/suppressions/welfare.dm | 6 +-
code/modules/suppressions/white_ordeals.dm | 13 -
lobotomy-corp13.dme | 8 +-
49 files changed, 1090 insertions(+), 383 deletions(-)
create mode 100644 code/__DEFINES/facility_upgrades.dm
create mode 100644 code/__DEFINES/lobotomy_corp.dm
create mode 100644 code/__HELPERS/lobotomy_corp.dm
create mode 100644 code/datums/facility_upgrade.dm
delete mode 100644 code/game/machinery/computer/abnormality_auxilary.dm
create mode 100644 code/game/machinery/computer/abnormality_auxiliary.dm
create mode 100644 code/modules/suppressions/keter.dm
delete mode 100644 code/modules/suppressions/white_ordeals.dm
diff --git a/ModularTegustation/tegu_items/gadgets/manager_bullets.dm b/ModularTegustation/tegu_items/gadgets/manager_bullets.dm
index 66878dcd1a90..94d950b233a3 100644
--- a/ModularTegustation/tegu_items/gadgets/manager_bullets.dm
+++ b/ModularTegustation/tegu_items/gadgets/manager_bullets.dm
@@ -45,6 +45,7 @@
/datum/status_effect/interventionshield/on_apply()
. = ..()
+ shieldhealth = GetFacilityUpgradeValue(UPGRADE_BULLET_SHIELD_HEALTH)
owner.add_overlay(statuseffectvisual)
owner.visible_message(span_notice("[owner]s shield activates!"))
RegisterSignal(owner, COMSIG_MOB_APPLY_DAMGE, .proc/OnApplyDamage) //stolen from caluan
diff --git a/ModularTegustation/tegu_items/gadgets/unpowered.dm b/ModularTegustation/tegu_items/gadgets/unpowered.dm
index f949183ac4e7..556ff65ccdca 100644
--- a/ModularTegustation/tegu_items/gadgets/unpowered.dm
+++ b/ModularTegustation/tegu_items/gadgets/unpowered.dm
@@ -67,12 +67,12 @@
var/max_commands = 5
//Command Types that can be deployed. Listed in order of commandtype.
var/list/commandtypes = list(
- /obj/effect/temp_visual/HoloCommand/commandMove,
- /obj/effect/temp_visual/HoloCommand/commandWarn,
- /obj/effect/temp_visual/HoloCommand/commandGaurd,
- /obj/effect/temp_visual/HoloCommand/commandHeal,
- /obj/effect/temp_visual/HoloCommand/commandFightA,
- /obj/effect/temp_visual/HoloCommand/commandFightB
+ /obj/effect/temp_visual/holo_command/command_move,
+ /obj/effect/temp_visual/holo_command/command_warn,
+ /obj/effect/temp_visual/holo_command/command_guard,
+ /obj/effect/temp_visual/holo_command/command_heal,
+ /obj/effect/temp_visual/holo_command/command_fight_a,
+ /obj/effect/temp_visual/holo_command/command_fight_b,
)
/obj/item/commandprojector/attack_self(mob/user)
@@ -104,7 +104,7 @@
/obj/item/commandprojector/afterattack(atom/target, mob/user, proximity_flag)
. = ..()
if(cooldown <= world.time)
- for(var/obj/effect/temp_visual/HoloCommand/V in get_turf(target))
+ for(var/obj/effect/temp_visual/holo_command/V in get_turf(target))
qdel(V)
return
if(current_commands >= max_commands)
diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm
index 5e1313b7dc84..a3a5dd785c06 100644
--- a/code/__DEFINES/dcs/signals.dm
+++ b/code/__DEFINES/dcs/signals.dm
@@ -1070,3 +1070,7 @@
#define COMSIG_FEAR_EFFECT "fear_effect"
///Whenever the season is changed through god of the seasons or its E.G.O.
#define COMSIG_GLOB_SEASON_CHANGE "!change_season"
+
+// Ordeal signals
+// When the ordeal ends; (/datum/ordeal)
+#define COMSIG_GLOB_ORDEAL_END "!ordeal_end"
diff --git a/code/__DEFINES/facility_upgrades.dm b/code/__DEFINES/facility_upgrades.dm
new file mode 100644
index 000000000000..5ea75ef9a427
--- /dev/null
+++ b/code/__DEFINES/facility_upgrades.dm
@@ -0,0 +1,20 @@
+// How many LOB points you can get from working abnos to the maximum understanding
+#define MAX_ABNO_LOB_POINTS 18
+
+// Bullets. These defines are also used in manager_camera.dm
+#define HP_BULLET "HP Bullet"
+#define SP_BULLET "SP Bullet"
+#define RED_BULLET "RED Shield Bullet"
+#define WHITE_BULLET "WHITE Shield Bullet"
+#define BLACK_BULLET "BLACK Shield Bullet"
+#define PALE_BULLET "PALE Shield Bullet"
+#define YELLOW_BULLET "Qliphoth Intervention Bullet"
+// Bullet upgrades.
+#define UPGRADE_BULLET_COUNT "Maximum Bullet Count"
+#define UPGRADE_BULLET_HEAL "Bullet Healing Amount"
+#define UPGRADE_BULLET_SHIELD_HEALTH "Bullet Shield Health"
+// Agent upgrades
+#define UPGRADE_AGENT_STATS "Agent Starting Attributes Bonus"
+// Abnormality upgrades
+#define UPGRADE_ABNO_QUEUE_COUNT "Abnormality Extraction Amount"
+#define UPGRADE_ABNO_MELT_TIME "Abnormality Meltdown Bonus Duration"
diff --git a/code/__DEFINES/lobotomy_corp.dm b/code/__DEFINES/lobotomy_corp.dm
new file mode 100644
index 000000000000..2e87a55dcc89
--- /dev/null
+++ b/code/__DEFINES/lobotomy_corp.dm
@@ -0,0 +1,17 @@
+/* Names of core suppressions */
+// Normal ones
+#define CONTROL_CORE_SUPPRESSION "Control Core Suppression"
+#define INFORMATION_CORE_SUPPRESSION "Information Core Suppression"
+#define SAFETY_CORE_SUPPRESSION "Safety Core Suppression"
+#define TRAINING_CORE_SUPPRESSION "Training Core Suppression"
+#define COMMAND_CORE_SUPPRESSION "Central Command Core Suppression"
+#define WELFARE_CORE_SUPPRESSION "Welfare Core Suppression"
+#define DISCIPLINARY_CORE_SUPPRESSION "Disciplinary Core Suppression"
+#define RECORDS_CORE_SUPPRESSION "Records Core Suppression"
+#define EXTRACTION_CORE_SUPPRESSION "Extraction Core Suppression"
+// Keter
+#define DAY46_CORE_SUPPRESSION "Proving Oneself"
+#define DAY47_CORE_SUPPRESSION "Fatigue and Waiting"
+#define DAY48_CORE_SUPPRESSION "Regret and Atonement"
+#define DAY49_CORE_SUPPRESSION "Freedom and Redemption"
+#define DAY50_CORE_SUPPRESSION "Tree of Light"
diff --git a/code/__HELPERS/lobotomy_corp.dm b/code/__HELPERS/lobotomy_corp.dm
new file mode 100644
index 000000000000..ae8e65a734ad
--- /dev/null
+++ b/code/__HELPERS/lobotomy_corp.dm
@@ -0,0 +1,26 @@
+/// Returns list of all living agents that can work
+/proc/AllLivingAgents()
+ . = list()
+ for(var/mob/living/carbon/human/H in GLOB.player_list)
+ if(H.stat == DEAD)
+ continue
+ if(!(H.mind.assigned_role in GLOB.security_positions))
+ continue
+ if(HAS_TRAIT(H, TRAIT_WORK_FORBIDDEN))
+ continue
+ . += H
+
+/// Returns amount of available agents that can work
+/proc/AvailableAgentCount()
+ . = 0
+ for(var/mob/living/carbon/human/H in AllLivingAgents())
+ if(!H.client)
+ continue
+ if(!H.mind)
+ continue
+ . += 1
+
+/* Core Suppression helpers */
+/// Returns core suppression by path if its effects are active
+/proc/GetCoreSuppression(datum/suppression/CS = null)
+ return locate(CS) in SSlobotomy_corp.active_core_suppressions
diff --git a/code/__HELPERS/priority_announce.dm b/code/__HELPERS/priority_announce.dm
index b205a2f82f06..0b00e9ff06d4 100644
--- a/code/__HELPERS/priority_announce.dm
+++ b/code/__HELPERS/priority_announce.dm
@@ -3,8 +3,8 @@
return
// All your text is gone. Enjoy.
- if(istype(SSlobotomy_corp.core_suppression, /datum/suppression/information))
- var/datum/suppression/information/I = SSlobotomy_corp.core_suppression
+ var/datum/suppression/information/I = GetCoreSuppression(/datum/suppression/information)
+ if(istype(I))
text = Gibberish(text, TRUE, I.gibberish_value)
var/announcement
diff --git a/code/controllers/subsystem/abnormality_queue.dm b/code/controllers/subsystem/abnormality_queue.dm
index 3384a01d9ea0..6529031497e3 100644
--- a/code/controllers/subsystem/abnormality_queue.dm
+++ b/code/controllers/subsystem/abnormality_queue.dm
@@ -105,7 +105,7 @@ SUBSYSTEM_DEF(abnormality_queue)
if(!LAZYLEN(possible_abnormalities[lev]))
continue
picking_abno |= possible_abnormalities[lev]
- for(var/i = 1 to 3)
+ for(var/i = 1 to GetFacilityUpgradeValue(UPGRADE_ABNO_QUEUE_COUNT))
if(!LAZYLEN(picking_abno))
break
var/chosen_abno = pickweight(picking_abno)
diff --git a/code/controllers/subsystem/lobotomy_corp.dm b/code/controllers/subsystem/lobotomy_corp.dm
index 642fd4b5d10f..afb0a6341706 100644
--- a/code/controllers/subsystem/lobotomy_corp.dm
+++ b/code/controllers/subsystem/lobotomy_corp.dm
@@ -1,3 +1,4 @@
+// Meltdown types
#define MELTDOWN_NORMAL 1
#define MELTDOWN_GRAY 2
#define MELTDOWN_GOLD 3
@@ -54,6 +55,8 @@ SUBSYSTEM_DEF(lobotomy_corp)
var/list/current_ordeals = list()
// Currently running core suppression
var/datum/suppression/core_suppression = null
+ // List of active core suppressions; Different from above, as there can only be one "main" core
+ var/list/active_core_suppressions = list()
// List of available core suppressions for manager to choose
var/list/available_core_suppressions = list()
// State of the core suppression
@@ -62,6 +65,8 @@ SUBSYSTEM_DEF(lobotomy_corp)
var/list/work_logs = list()
// Work logs, but from agent perspective. Used mainly for round-end report
var/list/work_stats = list()
+ // List of facility upgrade datums
+ var/list/upgrades = list()
// PE available to be spent
var/available_box = 0
@@ -86,13 +91,17 @@ SUBSYSTEM_DEF(lobotomy_corp)
/// Amount of abnormalities that agents achieved full understanding on
var/understood_abnos = 0
/// The amount of core suppression options that will be available
- var/max_core_options = 2
+ var/max_core_options = 3
+ /// Points used for facility upgrades
+ var/lob_points = 2
/datum/controller/subsystem/lobotomy_corp/Initialize(timeofday)
. = ..()
addtimer(CALLBACK(src, .proc/SetGoal), 5 MINUTES)
addtimer(CALLBACK(src, .proc/InitializeOrdeals), 60 SECONDS)
addtimer(CALLBACK(src, .proc/PickPotentialSuppressions), 60 SECONDS)
+ for(var/F in subtypesof(/datum/facility_upgrade))
+ upgrades += new F
/datum/controller/subsystem/lobotomy_corp/proc/SetGoal()
var/player_mod = GLOB.clients.len * 0.15
@@ -126,6 +135,12 @@ SUBSYSTEM_DEF(lobotomy_corp)
continue
if(extra_core && !initial(C.after_midnight))
cores -= core_type
+ continue
+ // Create to see if it meets requirements and becomes available
+ C = new core_type()
+ if(!C.available)
+ cores -= core_type
+ qdel(C)
for(var/i = 1 to max_core_options)
if(!LAZYLEN(cores))
break
@@ -159,6 +174,7 @@ SUBSYSTEM_DEF(lobotomy_corp)
for(var/obj/machinery/computer/abnormality_auxiliary/A in GLOB.abnormality_auxiliary_consoles)
A.audible_message("Core Suppression options have been disabled for this shift!")
playsound(get_turf(A), 'sound/machines/dun_don_alert.ogg', 100, TRUE, 14)
+ A.selected_core_type = null
A.updateUsrDialog()
available_core_suppressions = list()
if(announce)
@@ -200,6 +216,7 @@ SUBSYSTEM_DEF(lobotomy_corp)
if(goal_reached || box_goal == 0)
return
if(available_box + goal_boxes >= box_goal)
+ AddLobPoints(4, "Quota Reward")
available_box -= box_goal - goal_boxes // Leftover is drained
goal_reached = TRUE
priority_announce("The energy production goal has been reached.", "Energy Production", sound='sound/misc/notice2.ogg')
@@ -233,10 +250,7 @@ SUBSYSTEM_DEF(lobotomy_corp)
qliphoth_meltdown_affected -= TETH_LEVEL
qliphoth_meter = 0
var/abno_amount = all_abnormality_datums.len
- var/player_count = 0
- for(var/mob/player in GLOB.player_list)
- if(isliving(player) && (player.mind?.assigned_role in GLOB.security_positions))
- player_count += 1
+ var/player_count = AvailableAgentCount()
qliphoth_max = (player_count > 1 ? 4 : 3) + round(player_count * 0.8) // Some extra help on non solo rounds
qliphoth_state += 1
for(var/datum/abnormality/A in all_abnormality_datums)
@@ -255,14 +269,16 @@ SUBSYSTEM_DEF(lobotomy_corp)
if(ran_ordeal)
return
InitiateMeltdown(qliphoth_meltdown_amount, FALSE)
- qliphoth_meltdown_amount = max(1, round(abno_amount * CONFIG_GET(number/qliphoth_meltdown_percent)))
+ // Less agents will decrease meltdown count, but more - increase it
+ var/agent_mod = 0.4 + (player_count * 0.1)
+ qliphoth_meltdown_amount = clamp(round(abno_amount * CONFIG_GET(number/qliphoth_meltdown_percent) * agent_mod), 1, abno_amount * 0.5)
/datum/controller/subsystem/lobotomy_corp/proc/InitiateMeltdown(meltdown_amount = 1, forced = TRUE, type = MELTDOWN_NORMAL, min_time = 60, max_time = 90, alert_text = "Qliphoth meltdown occured in containment zones of the following abnormalities:", alert_sound = 'sound/effects/meltdownAlert.ogg')
// Honestly, I wish I could do it another way, but oh well
- if(istype(core_suppression, /datum/suppression/command))
+ var/datum/suppression/command/C = GetCoreSuppression(/datum/suppression/command)
+ if(istype(C))
// All abno levels melt
forced = TRUE
- var/datum/suppression/command/C = core_suppression
meltdown_amount += C.meltdown_count_increase
min_time = round(min_time * C.meltdown_time_multiplier)
max_time = round(max_time * C.meltdown_time_multiplier)
@@ -328,3 +344,11 @@ SUBSYSTEM_DEF(lobotomy_corp)
next_ordeal = null
RollOrdeal()
return TRUE // Very sloppy, but will do for now
+
+/// Adds LOB points and notifies players via aux consoles
+/datum/controller/subsystem/lobotomy_corp/proc/AddLobPoints(amount = 1, message = "UNKNOWN")
+ lob_points += amount
+ for(var/obj/machinery/computer/abnormality_auxiliary/A in GLOB.abnormality_auxiliary_consoles)
+ A.audible_message("[round(amount, 0.1)] LOB point[amount > 1 ? "s" : ""] deposited! Reason: [message].")
+ playsound(get_turf(A), 'sound/machines/twobeep_high.ogg', 20, TRUE)
+ A.updateUsrDialog()
diff --git a/code/controllers/subsystem/persistence.dm b/code/controllers/subsystem/persistence.dm
index cf26bc776dad..306c4b55f68f 100644
--- a/code/controllers/subsystem/persistence.dm
+++ b/code/controllers/subsystem/persistence.dm
@@ -3,6 +3,7 @@
#define FILE_AGENT_REP "data/AgentReputation.json"
#define FILE_PE_QUOTA "data/PEQuota.json"
#define FILE_ABNO_PICKS "data/AbnormalityRates.json"
+#define FILE_CORE_SUPPRESSIONS "data/ClearedCores.json"
#define KEEP_ROUNDS_MAP 3
@@ -28,6 +29,8 @@ SUBSYSTEM_DEF(persistence)
var/list/obj/structure/sign/painting/painting_frames = list()
var/list/paintings = list()
var/list/abno_rates = list()
+ /// List of ckeys with list of core suppression names that they have cleared before
+ var/list/cleared_core_suppressions = list()
/datum/controller/subsystem/persistence/Initialize()
LoadPoly()
@@ -42,6 +45,7 @@ SUBSYSTEM_DEF(persistence)
if(SSmaptype.maptype in list("standard", "skeld", "fishing", "wonderlabs"))
LoadPEStatus()
LoadAbnoPicks()
+ LoadClearedCores()
LoadRandomizedRecipes()
LoadPaintings()
load_custom_outfits()
@@ -419,6 +423,33 @@ SUBSYSTEM_DEF(persistence)
fdel(FILE_ABNO_PICKS)
text2file(json_encode(abno_rates), FILE_ABNO_PICKS)
+/datum/controller/subsystem/persistence/proc/LoadClearedCores()
+ var/json = file2text(FILE_CORE_SUPPRESSIONS)
+ if(!json)
+ var/json_file = file(FILE_CORE_SUPPRESSIONS)
+ if(!fexists(json_file))
+ WARNING("Failed to load cleared cores. File likely corrupt.")
+ return
+ return
+ cleared_core_suppressions = json_decode(json)
+
+/datum/controller/subsystem/persistence/proc/UpdateClearedCores(datum/suppression/S)
+ if(!istype(S))
+ return
+
+ for(var/mob/living/carbon/human/H in GLOB.player_list)
+ if(H.stat == DEAD)
+ continue
+ if(!H.client || !H.ckey)
+ continue
+
+ if(!islist(cleared_core_suppressions[H.ckey]))
+ cleared_core_suppressions[H.ckey] = list()
+ cleared_core_suppressions[H.ckey] |= S.name
+
+ fdel(FILE_CORE_SUPPRESSIONS)
+ text2file(json_encode(cleared_core_suppressions), FILE_CORE_SUPPRESSIONS)
+
/datum/controller/subsystem/persistence/proc/LoadRandomizedRecipes()
var/json_file = file("data/RandomizedChemRecipes.json")
var/json
diff --git a/code/datums/abnormality/datum/abnormality.dm b/code/datums/abnormality/datum/abnormality.dm
index 8e6619ffdb06..2b8f0501eafd 100644
--- a/code/datums/abnormality/datum/abnormality.dm
+++ b/code/datums/abnormality/datum/abnormality.dm
@@ -60,6 +60,9 @@
var/list/transferable_var
///if the abno spawns with a slime radio or not
var/abno_radio = FALSE
+ // Object = list(x tile offset, y tile offset)
+ /// List of connected structures; Used to teleport and delete them when abnormality is swapped or deleted
+ var/list/connected_structures = list()
/datum/abnormality/New(obj/effect/landmark/abnormality_spawn/new_landmark, mob/living/simple_animal/hostile/abnormality/new_type = null)
if(!istype(new_landmark))
@@ -78,11 +81,14 @@
SSlobotomy_corp.all_abnormality_datums -= src
for(var/datum/ego_datum/ED in ego_datums)
qdel(ED)
+ for(var/atom/A in connected_structures)
+ qdel(A)
QDEL_NULL(landmark)
QDEL_NULL(current)
ego_datums = null
landmark = null
current = null
+ connected_structures = null
..()
/datum/abnormality/proc/RespawnAbno()
@@ -190,11 +196,17 @@
overload_chance[user.ckey] = max(overload_chance[user.ckey] + overload_chance_amount, overload_chance_limit)
/datum/abnormality/proc/UpdateUnderstanding(percent)
- if (understanding != max_understanding) // This should render "full_understood" not required.
+ // Lower agent pop gets a bonus
+ var/agent_count = AvailableAgentCount()
+ if(agent_count <= 5 && percent)
+ percent *= 1 + (3 / agent_count)
+
+ if(understanding != max_understanding) // This should render "full_understood" not required.
understanding = clamp((understanding + (max_understanding*percent/100)), 0, max_understanding)
if (understanding == max_understanding) // Checks for max understanding after the fact
current.gift_chance *= 1.5
SSlobotomy_corp.understood_abnos++
+ SSlobotomy_corp.AddLobPoints(MAX_ABNO_LOB_POINTS / SSabnormality_queue.rooms_start, "Abnormality Understanding")
else if(understanding == max_understanding && percent < 0) // If we're max and we reduce, undo the count.
understanding = clamp((understanding + (max_understanding*percent/100)), 0, max_understanding)
if (understanding != max_understanding) // Checks for max understanding after the fact
@@ -287,6 +299,8 @@
return FALSE
if(istype(target.current) && !target.current.IsContained())
return FALSE
+ if(working || target.working)
+ return FALSE
// A very silly method to get the objects in the cell
var/list/objs_src = view(7, landmark)
var/list/objs_target = view(7, target.landmark)
@@ -331,6 +345,15 @@
C1.c_tag = "Containment zone: [target.name]"
if(C2)
C2.c_tag = "Containment zone: [name]"
+ // Move structures
+ for(var/atom/movable/A in connected_structures)
+ A.forceMove(get_turf(landmark))
+ A.x += connected_structures[A][1]
+ A.y += connected_structures[A][2]
+ for(var/atom/movable/A in target.connected_structures)
+ A.forceMove(get_turf(target.landmark))
+ A.x += connected_structures[A][1]
+ A.y += connected_structures[A][2]
// And finally, move abnormalities around
if(current)
current.forceMove(get_turf(landmark))
diff --git a/code/datums/facility_upgrade.dm b/code/datums/facility_upgrade.dm
new file mode 100644
index 000000000000..f4aa93cb82d4
--- /dev/null
+++ b/code/datums/facility_upgrade.dm
@@ -0,0 +1,192 @@
+/* Helper procs */
+// Returns the datum of requested upgrade type
+/proc/GetFacilityUpgrade(up_name)
+ for(var/datum/facility_upgrade/F in SSlobotomy_corp.upgrades)
+ if(F.name == up_name)
+ return F
+ return null
+
+// Returns value of the facility upgrade.
+/proc/GetFacilityUpgradeValue(up_name)
+ for(var/datum/facility_upgrade/F in SSlobotomy_corp.upgrades)
+ if(F.name == up_name)
+ return F.value
+ return 0
+
+/* Facility upgrade datums */
+/datum/facility_upgrade
+ var/name = null
+ var/value = 0
+ var/max_value = 0
+ /// How much LOB points does it cost to Upgrade
+ var/cost = 1
+ /// Category by which it will be displayed in the aux console.
+ /// To keep it sorted by "importance", avoid creating new categories without adding them to abnormality_auxiliary.dm display list
+ var/category = "Unsorted"
+ /// If not empty - list of required upgrades to be available.
+ var/list/requires_all_of = list()
+ /// Similar to above - list of required upgrades to be available, but needs only one of them.
+ var/list/requires_one_of = list()
+ // A shitty way to make 1 show up as text instead of 1. If null or FALSE - will show a value as usual.
+ var/display_true = null
+ // Same as above, but for negative/0 values
+ var/display_false = null
+
+/// What happens when the upgrade is done
+/datum/facility_upgrade/proc/Upgrade()
+ SSlobotomy_corp.lob_points -= cost
+ return TRUE
+
+/datum/facility_upgrade/proc/DisplayValue()
+ if(!display_true || !display_false)
+ return value
+ return value ? display_true : display_false
+
+/// Return TRUE if it should be shown in the aux console
+/datum/facility_upgrade/proc/CanShowUpgrade()
+ // Someone forgot to set the values! Uh oh!
+ if(!max_value || !name)
+ return FALSE
+ if(LAZYLEN(requires_all_of))
+ for(var/F in requires_all_of)
+ if(!GetFacilityUpgradeValue(F))
+ return FALSE
+ return TRUE
+ if(LAZYLEN(requires_one_of))
+ for(var/F in requires_one_of)
+ if(GetFacilityUpgradeValue(F))
+ return TRUE
+ return FALSE
+ return TRUE
+
+/// Whereas you can upgrade it at all
+/datum/facility_upgrade/proc/CanUpgrade()
+ if(value >= max_value)
+ return FALSE
+ if(SSlobotomy_corp.lob_points < cost)
+ return FALSE
+ return TRUE
+
+/* Bullets */
+/datum/facility_upgrade/bullet
+ max_value = 1
+ category = "Bullets"
+ display_true = "PURCHASED"
+ display_false = "NOT PURCHASED" // Honestly quite weird, but whatever
+
+/datum/facility_upgrade/bullet/Upgrade()
+ value = max_value
+ return ..()
+
+/datum/facility_upgrade/bullet/hp
+ name = HP_BULLET
+
+/datum/facility_upgrade/bullet/sp
+ name = SP_BULLET
+
+/datum/facility_upgrade/bullet/red
+ name = RED_BULLET
+
+/datum/facility_upgrade/bullet/white
+ name = WHITE_BULLET
+
+/datum/facility_upgrade/bullet/black
+ name = BLACK_BULLET
+
+/datum/facility_upgrade/bullet/pale
+ name = PALE_BULLET
+
+/datum/facility_upgrade/bullet/yellow
+ name = YELLOW_BULLET
+
+// Bullet upgrades
+/datum/facility_upgrade/bullet_count
+ name = UPGRADE_BULLET_COUNT
+ category = "Bullet Upgrades"
+ value = 4
+ max_value = 40
+ requires_one_of = list(HP_BULLET, SP_BULLET, RED_BULLET, WHITE_BULLET, BLACK_BULLET, PALE_BULLET, YELLOW_BULLET)
+ /// The cost will not go further upwards from that point on
+ var/max_cost = 6
+
+/datum/facility_upgrade/bullet_count/Upgrade()
+ value = min(max_value, value + round(max_value * 0.1))
+ . = ..()
+ cost = min(max_cost, cost + 1)
+
+/datum/facility_upgrade/bullet_heal_increase
+ name = UPGRADE_BULLET_HEAL
+ category = "Bullet Upgrades"
+ value = 0.15
+ max_value = 0.6
+ requires_one_of = list(HP_BULLET, SP_BULLET)
+
+/datum/facility_upgrade/bullet_heal_increase/Upgrade()
+ value = min(max_value, value + 0.15)
+ . = ..()
+ cost += 1
+
+/datum/facility_upgrade/bullet_heal_increase/DisplayValue()
+ return "[value * 100]%"
+
+// Upgrades for shield bullets
+/datum/facility_upgrade/bullet_shield_increase
+ name = UPGRADE_BULLET_SHIELD_HEALTH
+ category = "Bullet Upgrades"
+ value = 50
+ max_value = 200
+ requires_one_of = list(RED_BULLET, WHITE_BULLET, BLACK_BULLET, PALE_BULLET)
+
+/datum/facility_upgrade/bullet_shield_increase/New()
+ . = ..()
+ max_value = DEFAULT_HUMAN_MAX_HEALTH + (100 * FORTITUDE_MOD)
+ value = max_value * 0.25
+
+/datum/facility_upgrade/bullet_shield_increase/Upgrade()
+ value = min(max_value, value + (max_value * 0.125))
+ . = ..()
+ cost += 1
+
+// Agent upgrades
+/datum/facility_upgrade/agent_spawn_stats_bonus
+ name = UPGRADE_AGENT_STATS
+ category = "Agent"
+ value = 0
+ max_value = 30
+ var/value_increase = 5
+
+/datum/facility_upgrade/agent_spawn_stats_bonus/Upgrade()
+ value = min(max_value, value + value_increase)
+ // Applies newly purchased bonus to all living agents
+ for(var/mob/living/carbon/human/H in AllLivingAgents())
+ H.adjust_all_attribute_levels(value_increase)
+ to_chat(H, span_notice("Facility upgrade increased your attributes by [value_increase] points!"))
+ . = ..()
+ cost += 1
+
+// Abnormality upgrades
+/datum/facility_upgrade/picking_abno_amount
+ name = UPGRADE_ABNO_QUEUE_COUNT
+ category = "Abnormalities"
+ value = 2
+ max_value = 4
+
+/datum/facility_upgrade/picking_abno_amount/Upgrade()
+ value = min(max_value, value + 1)
+ . = ..()
+ cost += 1
+
+/datum/facility_upgrade/abno_melt_time
+ name = UPGRADE_ABNO_MELT_TIME
+ category = "Abnormalities"
+ value = 0
+ max_value = 60
+
+/datum/facility_upgrade/abno_melt_time/Upgrade()
+ value = min(max_value, value + 10)
+ . = ..()
+ if(value >= max_value * 0.25)
+ cost += 1
+
+/datum/facility_upgrade/abno_melt_time/DisplayValue()
+ return "[value] seconds"
diff --git a/code/game/machinery/computer/abnormality_auxilary.dm b/code/game/machinery/computer/abnormality_auxilary.dm
deleted file mode 100644
index 1f2eb66e28f1..000000000000
--- a/code/game/machinery/computer/abnormality_auxilary.dm
+++ /dev/null
@@ -1,67 +0,0 @@
-// Console for all the random managerial stuff like calling rabbits or starting core suppressions
-/obj/machinery/computer/abnormality_auxiliary
- name = "auxiliary managerial console"
- desc = "Used for various optional actions available to manager."
- resistance_flags = INDESTRUCTIBLE
- var/datum/suppression/selected_core_type = null
-
-/obj/machinery/computer/abnormality_auxiliary/Initialize()
- . = ..()
- GLOB.abnormality_auxiliary_consoles += src
- flags_1 |= NODECONSTRUCT_1
-
-/obj/machinery/computer/abnormality_auxiliary/Destroy()
- GLOB.abnormality_auxiliary_consoles -= src
- ..()
-
-/obj/machinery/computer/abnormality_auxiliary/ui_interact(mob/user)
- . = ..()
- var/dat
- if(istype(SSlobotomy_corp.core_suppression))
- dat += "[SSlobotomy_corp.core_suppression.name] is currently in the progress!
"
- else
- if(ispath(selected_core_type))
- dat += "[initial(selected_core_type.name)]
"
- dat += "[initial(selected_core_type.desc)]
"
- dat += "Goal: [initial(selected_core_type.goal_text)]
"
- dat += "Reward: [initial(selected_core_type.reward_text)]
"
- dat += "Initiate"
- dat += "
"
- for(var/core_type in SSlobotomy_corp.available_core_suppressions)
- var/datum/suppression/S = core_type
- dat += "[initial(S.name)]: Select
"
- var/datum/browser/popup = new(user, "abno_logs", "Auxiliary Managerial Console", 400, 400)
- popup.set_content(dat)
- popup.open()
- return
-
-/obj/machinery/computer/abnormality_auxiliary/Topic(href, href_list)
- . = ..()
- if(.)
- return .
- if(ishuman(usr))
- usr.set_machine(src)
- add_fingerprint(usr)
- if(href_list["choose_suppression"])
- var/datum/suppression/core_type = text2path(href_list["choose_suppression"])
- if(!ispath(core_type) || !(core_type in SSlobotomy_corp.available_core_suppressions))
- return FALSE
- selected_core_type = core_type
- to_chat(usr, span_notice("[initial(selected_core_type.name)] has been selected!"))
- playsound(get_turf(src), 'sound/machines/terminal_prompt_confirm.ogg', 50, TRUE)
- updateUsrDialog()
- return TRUE
- if(href_list["init_suppression"])
- if(!ispath(selected_core_type) || !(selected_core_type in SSlobotomy_corp.available_core_suppressions))
- return FALSE
- if(istype(SSlobotomy_corp.core_suppression))
- to_chat(usr, span_warning("A core suppression is already in the progress!"))
- selected_core_type = null
- return FALSE
- SSlobotomy_corp.core_suppression = new selected_core_type
- SSlobotomy_corp.available_core_suppressions = list()
- to_chat(usr, span_userdanger("Good luck, Manager."))
- playsound(get_turf(src), 'sound/machines/terminal_prompt_confirm.ogg', 50, TRUE)
- updateUsrDialog()
- addtimer(CALLBACK(SSlobotomy_corp.core_suppression, /datum/suppression/proc/Run), 2 SECONDS)
- return TRUE
diff --git a/code/game/machinery/computer/abnormality_auxiliary.dm b/code/game/machinery/computer/abnormality_auxiliary.dm
new file mode 100644
index 000000000000..ca4efdc73bd4
--- /dev/null
+++ b/code/game/machinery/computer/abnormality_auxiliary.dm
@@ -0,0 +1,131 @@
+// The console "pages" available
+#define CORE_SUPPRESSIONS "Core Suppression"
+#define FACILITY_UPGRADES "Facility Upgrades"
+
+// Console for all the random managerial stuff like calling rabbits or starting core suppressions
+/obj/machinery/computer/abnormality_auxiliary
+ name = "auxiliary managerial console"
+ desc = "Used for various optional actions available to manager."
+ resistance_flags = INDESTRUCTIBLE
+ /// Currently selected console page
+ var/page = CORE_SUPPRESSIONS
+ /// All possible pages
+ var/list/all_pages = list(
+ CORE_SUPPRESSIONS,
+ FACILITY_UPGRADES,
+ )
+ var/datum/suppression/selected_core_type = null
+
+/obj/machinery/computer/abnormality_auxiliary/Initialize()
+ . = ..()
+ GLOB.abnormality_auxiliary_consoles += src
+ flags_1 |= NODECONSTRUCT_1
+
+/obj/machinery/computer/abnormality_auxiliary/Destroy()
+ GLOB.abnormality_auxiliary_consoles -= src
+ ..()
+
+/obj/machinery/computer/abnormality_auxiliary/ui_interact(mob/user)
+ . = ..()
+ var/dat
+ for(var/p in all_pages)
+ dat += "[p == page ? "[p]" : "[p]"]"
+ dat += "
"
+ switch(page)
+ if(CORE_SUPPRESSIONS)
+ if(istype(SSlobotomy_corp.core_suppression))
+ dat += "[SSlobotomy_corp.core_suppression.name] is currently in the progress!
"
+ else
+ if(ispath(selected_core_type))
+ dat += "[initial(selected_core_type.name)]
"
+ dat += "[initial(selected_core_type.desc)]
"
+ dat += "Goal: [initial(selected_core_type.goal_text)]
"
+ dat += "Reward: [initial(selected_core_type.reward_text)]
"
+ dat += "Initiate"
+ dat += "
"
+ for(var/core_type in SSlobotomy_corp.available_core_suppressions)
+ var/datum/suppression/S = core_type
+ dat += "[initial(S.name)]: Select
"
+
+ if(FACILITY_UPGRADES)
+ dat += "LOB Points: [round(SSlobotomy_corp.lob_points, 0.1)]"
+ dat += "
"
+ var/list/upgrades_per_category = list("Bullets" = list(), "Bullet Upgrades" = list(), "Agent" = list(), "Abnormalities" = list(), "Unsorted" = list())
+ for(var/datum/facility_upgrade/F in SSlobotomy_corp.upgrades)
+ if(!F.CanShowUpgrade())
+ continue
+ if(!(F.category in upgrades_per_category))
+ upgrades_per_category[F.category] = list()
+ upgrades_per_category[F.category] |= F
+ for(var/i = 1 to length(upgrades_per_category))
+ var/cat = upgrades_per_category[i]
+ if(!LAZYLEN(upgrades_per_category[cat]))
+ continue
+ dat += "[cat]
"
+ for(var/datum/facility_upgrade/F in upgrades_per_category[cat])
+ dat += "- [F.CanUpgrade() ? "Upgrade \[[F.cost]\] " : (F.value >= F.max_value ? "" : "\[[F.cost]\] ")][F.name]: [F.DisplayValue()]
"
+ if(i != length(upgrades_per_category))
+ dat += "
"
+ var/datum/browser/popup = new(user, "abno_auxiliary", "Auxiliary Managerial Console", 480, 640)
+ popup.set_content(dat)
+ popup.open()
+ return
+
+/obj/machinery/computer/abnormality_auxiliary/Topic(href, href_list)
+ . = ..()
+ if(.)
+ return .
+ if(ishuman(usr))
+ usr.set_machine(src)
+ add_fingerprint(usr)
+ // Basic topics
+ if(href_list["set_page"])
+ var/new_page = href_list["set_page"]
+ if((new_page in all_pages) && new_page != page)
+ page = new_page
+ playsound(get_turf(src), 'sound/machines/terminal_prompt_confirm.ogg', 50, TRUE)
+ updateUsrDialog()
+ return TRUE
+ return FALSE
+
+ // Core Suppression topics
+ if(href_list["choose_suppression"])
+ var/datum/suppression/core_type = text2path(href_list["choose_suppression"])
+ if(!ispath(core_type) || !(core_type in SSlobotomy_corp.available_core_suppressions))
+ return FALSE
+ selected_core_type = core_type
+ to_chat(usr, span_notice("[initial(selected_core_type.name)] has been selected!"))
+ playsound(get_turf(src), 'sound/machines/terminal_prompt_confirm.ogg', 50, TRUE)
+ updateUsrDialog()
+ return TRUE
+
+ if(href_list["init_suppression"])
+ if(!ispath(selected_core_type) || !(selected_core_type in SSlobotomy_corp.available_core_suppressions))
+ return FALSE
+ if(istype(SSlobotomy_corp.core_suppression))
+ to_chat(usr, span_warning("A core suppression is already in the progress!"))
+ selected_core_type = null
+ return FALSE
+ SSlobotomy_corp.core_suppression = new selected_core_type
+ SSlobotomy_corp.core_suppression.legitimate = TRUE
+ SSlobotomy_corp.available_core_suppressions = list()
+ selected_core_type = null
+ to_chat(usr, span_userdanger("Good luck, Manager."))
+ playsound(get_turf(src), 'sound/machines/terminal_prompt_confirm.ogg', 50, TRUE)
+ updateUsrDialog()
+ addtimer(CALLBACK(SSlobotomy_corp.core_suppression, /datum/suppression/proc/Run), 2 SECONDS)
+ return TRUE
+
+ // Facility upgrade topics
+ if(href_list["upgrade"])
+ var/datum/facility_upgrade/U = GetFacilityUpgrade(href_list["upgrade"])
+ if(!istype(U) || !U.CanUpgrade())
+ updateUsrDialog()
+ return FALSE
+ U.Upgrade()
+ playsound(get_turf(src), 'sound/machines/terminal_prompt_confirm.ogg', 50, TRUE)
+ updateUsrDialog()
+ return TRUE
+
+#undef CORE_SUPPRESSIONS
+#undef FACILITY_UPGRADES
diff --git a/code/game/machinery/computer/abnormality_logs.dm b/code/game/machinery/computer/abnormality_logs.dm
index ee5b9c1db85c..ecf62a84f614 100644
--- a/code/game/machinery/computer/abnormality_logs.dm
+++ b/code/game/machinery/computer/abnormality_logs.dm
@@ -12,10 +12,11 @@
dat += "All logs
"
for(var/i = 1 to SSlobotomy_corp.all_abnormality_datums.len)
var/datum/abnormality/A = SSlobotomy_corp.all_abnormality_datums[i]
+ var/understanding = round((A.understanding / A.max_understanding) * 100)
if(!LAZYLEN(A.work_logs))
- dat += "\[[THREAT_TO_NAME[A.threat_level]]\] [A.name]"
+ dat += "\[[THREAT_TO_NAME[A.threat_level]]\] [A.name] ([understanding]%)"
else
- dat += "\[[THREAT_TO_NAME[A.threat_level]]\] [A.name]"
+ dat += "\[[THREAT_TO_NAME[A.threat_level]]\] [A.name] ([understanding]%)"
dat += "
"
var/datum/browser/popup = new(user, "abno_logs", "Abnormality Logging Console", 400, 700)
popup.set_content(dat)
diff --git a/code/game/machinery/computer/abnormality_work.dm b/code/game/machinery/computer/abnormality_work.dm
index 64cb112cc267..0b0ec310c8d1 100644
--- a/code/game/machinery/computer/abnormality_work.dm
+++ b/code/game/machinery/computer/abnormality_work.dm
@@ -85,8 +85,8 @@
var/work_display = "[wt] Work"
if(scramble_list[wt] != null)
work_display += "?"
- if(!tutorial && istype(SSlobotomy_corp.core_suppression, /datum/suppression/information))
- var/datum/suppression/information/I = SSlobotomy_corp.core_suppression
+ var/datum/suppression/information/I = GetCoreSuppression(/datum/suppression/information)
+ if(!tutorial && istype(I))
work_display = Gibberish(work_display, TRUE, I.gibberish_value)
if(HAS_TRAIT(user, TRAIT_WORK_KNOWLEDGE))
dat += "[work_display] \[[datum_reference.get_work_chance(wt, user)]%\]
"
@@ -278,7 +278,8 @@
qliphoth_meltdown_effect()
/obj/machinery/computer/abnormality/proc/start_meltdown(melt_type = MELTDOWN_NORMAL, min_time = 60, max_time = 90)
- meltdown_time = rand(min_time, max_time)
+ meltdown_time = rand(min_time, max_time) + (GetFacilityUpgradeValue(UPGRADE_ABNO_MELT_TIME) * \
+ (GetCoreSuppression(/datum/suppression/command) ? 0.5 : 1))
meltdown = melt_type
datum_reference.current.MeltdownStart()
update_icon()
diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm
index 1663edbbff6a..2ad50be2447d 100644
--- a/code/game/machinery/computer/camera_advanced.dm
+++ b/code/game/machinery/computer/camera_advanced.dm
@@ -194,7 +194,7 @@
/mob/camera/ai_eye/remote/update_remote_sight(mob/living/user)
user.see_invisible = SEE_INVISIBLE_LIVING //can't see ghosts through cameras
- if(istype(SSlobotomy_corp.core_suppression, /datum/suppression/information))
+ if(GetCoreSuppression(/datum/suppression/information))
see_invisible = INVISIBILITY_LIGHTING // Can't see mobs
user.sight = SEE_TURFS | SEE_BLACKNESS
user.see_in_dark = 2
diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm
index b2021a28e330..6e7e1a61fe3e 100644
--- a/code/game/machinery/computer/crew.dm
+++ b/code/game/machinery/computer/crew.dm
@@ -220,7 +220,7 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
// ID and id-related data
var/obj/item/card/id/id_card = tracked_living_mob.get_idcard(hand_first = FALSE)
if (id_card)
- if(!istype(SSlobotomy_corp.core_suppression, /datum/suppression/information))
+ if(!GetCoreSuppression(/datum/suppression/information))
entry["name"] = id_card.registered_name
entry["assignment"] = id_card.assignment
entry["ijob"] = jobs[id_card.GetJobName()] // Tegu edit - Alt job titles
diff --git a/code/game/machinery/computer/manager_camera.dm b/code/game/machinery/computer/manager_camera.dm
index 0f2ccb7606e8..39c0ee07819b 100644
--- a/code/game/machinery/computer/manager_camera.dm
+++ b/code/game/machinery/computer/manager_camera.dm
@@ -1,25 +1,26 @@
-#define HP_BULLET 1
-#define SP_BULLET 2
-#define RED_BULLET 3
-#define WHITE_BULLET 4
-#define BLACK_BULLET 5
-#define PALE_BULLET 6
-#define YELLOW_BULLET 7
+// Bullets number defines
+#define MANAGER_HP_BULLET 1
+#define MANAGER_SP_BULLET 2
+#define MANAGER_RED_BULLET 3
+#define MANAGER_WHITE_BULLET 4
+#define MANAGER_BLACK_BULLET 5
+#define MANAGER_PALE_BULLET 6
+#define MANAGER_YELLOW_BULLET 7
/obj/machinery/computer/camera_advanced/manager
name = "managerial camera console"
desc = "A computer used for remotely handling a facility."
icon_screen = "mechpad"
icon_keyboard = "generic_key"
+ resistance_flags = INDESTRUCTIBLE
var/datum/action/innate/cyclemanagerbullet/cycle
var/datum/action/innate/firemanagerbullet/fire
var/datum/action/innate/cyclecommand/cyclecommand
var/datum/action/innate/managercommand/command
var/datum/action/innate/manager_track/follow
- var/ammo = 6
- var/max_ammo = 5
- var/bullettype = 1
- var/commandtype = 1
+ var/ammo = 4
+ var/bullet_type = 0
+ var/command_type = 1
var/command_delay = 0.5 SECONDS
var/command_cooldown
//Used for limiting the amount of commands that can exist.
@@ -28,23 +29,24 @@
///Variable stolen from AI. Essential for tracking feature.
var/static/datum/trackable/track = new
//Command Types sorted in order.
- var/list/commandtypes = list(
- /obj/effect/temp_visual/HoloCommand/commandMove,
- /obj/effect/temp_visual/HoloCommand/commandWarn,
- /obj/effect/temp_visual/HoloCommand/commandGaurd,
- /obj/effect/temp_visual/HoloCommand/commandHeal,
- /obj/effect/temp_visual/HoloCommand/commandFightA,
- /obj/effect/temp_visual/HoloCommand/commandFightB
+ var/list/command_types = list(
+ /obj/effect/temp_visual/holo_command/command_move,
+ /obj/effect/temp_visual/holo_command/command_warn,
+ /obj/effect/temp_visual/holo_command/command_guard,
+ /obj/effect/temp_visual/holo_command/command_heal,
+ /obj/effect/temp_visual/holo_command/command_fight_a,
+ /obj/effect/temp_visual/holo_command/command_fight_b
)
/// Used for radial menu; Type = list(name, desc, icon_state)
+ /// List of bullets available for use are defined in lobotomy_corp subsystem
var/list/bullet_types = list(
- HP_BULLET = list("name" = "HP-N", "desc" = "These bullets speed up the recovery of an employee.", "icon_state" = "green"),
- SP_BULLET = list("name" = "SP-E", "desc" = "Bullets that inject an employee with diluted Enkephalin.", "icon_state" = "blue"),
- RED_BULLET = list("name" = "Physical Shield", "desc" = "Attach a RED DAMAGE forcefield onto a employee.", "icon_state" = "red"),
- WHITE_BULLET = list("name" = "Trauma Shield", "desc" = "Attach a WHITE DAMAGE forcefield onto a employee.", "icon_state" = "white"),
- BLACK_BULLET = list("name" = "Erosion Shield", "desc" = "Attach a BLACK DAMAGE forcefield onto a employee.", "icon_state" = "black"),
- PALE_BULLET = list("name" = "Soul Shield", "desc" = "Attach a PALE DAMAGE forcefield onto a employee.", "icon_state" = "pale"),
- YELLOW_BULLET = list("name" = "Qliphoth Intervention Field", "desc" = "Overload a abnormalities Qliphoth Control to reduce their movement speed.", "icon_state" = "yellow"),
+ MANAGER_HP_BULLET = list("name" = HP_BULLET, "desc" = "These bullets speed up the recovery of an employee.", "icon_state" = "green"),
+ MANAGER_SP_BULLET = list("name" = SP_BULLET, "desc" = "Bullets that inject an employee with diluted Enkephalin.", "icon_state" = "blue"),
+ MANAGER_RED_BULLET = list("name" = RED_BULLET, "desc" = "Attach a RED DAMAGE forcefield onto a employee.", "icon_state" = "red"),
+ MANAGER_WHITE_BULLET = list("name" = WHITE_BULLET, "desc" = "Attach a WHITE DAMAGE forcefield onto a employee.", "icon_state" = "white"),
+ MANAGER_BLACK_BULLET = list("name" = BLACK_BULLET, "desc" = "Attach a BLACK DAMAGE forcefield onto a employee.", "icon_state" = "black"),
+ MANAGER_PALE_BULLET = list("name" = PALE_BULLET, "desc" = "Attach a PALE DAMAGE forcefield onto a employee.", "icon_state" = "pale"),
+ MANAGER_YELLOW_BULLET = list("name" = YELLOW_BULLET, "desc" = "Overload a abnormalities Qliphoth Control to reduce their movement speed.", "icon_state" = "yellow"),
)
/* Locked actions */
@@ -108,13 +110,13 @@
swap.selected_abno = null
actions += swap
- RegisterSignal(user, COMSIG_MOB_CTRL_CLICKED, .proc/HotkeyClick) //wanted to use shift click but shift click only allowed applying the effects to my player.
- RegisterSignal(user, COMSIG_XENO_TURF_CLICK_ALT, .proc/altClick)
+ RegisterSignal(user, COMSIG_MOB_CTRL_CLICKED, .proc/OnHotkeyClick) //wanted to use shift click but shift click only allowed applying the effects to my player.
+ RegisterSignal(user, COMSIG_XENO_TURF_CLICK_ALT, .proc/OnAltClick)
RegisterSignal(user, COMSIG_MOB_SHIFTCLICKON, .proc/ManagerExaminate)
RegisterSignal(user, COMSIG_MOB_CTRLSHIFTCLICKON, .proc/OnCtrlShiftClick)
/obj/machinery/computer/camera_advanced/manager/attackby(obj/item/O, mob/user, params)
- if(istype(O, /obj/item/managerbullet) && ammo <= max_ammo)
+ if(istype(O, /obj/item/managerbullet) && ammo <= GetFacilityUpgradeValue(UPGRADE_BULLET_COUNT))
ammo++
to_chat(user, "You load [O] in to the [src]. It now has [ammo] bullets stored.")
playsound(get_turf(src), 'sound/weapons/kenetic_reload.ogg', 10, 0, 3)
@@ -126,7 +128,7 @@
UnregisterSignal(user, list(COMSIG_MOB_CTRL_CLICKED, COMSIG_XENO_TURF_CLICK_ALT, COMSIG_MOB_SHIFTCLICKON, COMSIG_MOB_CTRLSHIFTCLICKON))
..()
-/obj/machinery/computer/camera_advanced/manager/proc/HotkeyClick(datum/source, atom/clicked_atom) //system control for hotkeys
+/obj/machinery/computer/camera_advanced/manager/proc/OnHotkeyClick(datum/source, atom/clicked_atom) //system control for hotkeys
SIGNAL_HANDLER
// No target :(
@@ -143,72 +145,72 @@
if(SSlobotomy_corp.manager_bullet_area > -1)
var/success = FALSE
for(var/mob/living/L in range(SSlobotomy_corp.manager_bullet_area, clicked_atom))
- if(ishuman(clicked_atom))
- clickedEmployee(source, clicked_atom)
+ if(ishuman(L))
+ ClickedEmployee(source, L)
success = TRUE
- if(ishostile(clicked_atom))
- clickedAbno(source, clicked_atom)
+ if(ishostile(L))
+ ClickedAbno(source, L)
success = TRUE
if(success)
ammo--
+ to_chat(source, span_warning("[ammo] bullets remaining."))
return
// Non-AOE
- if(ishuman(clicked_atom))
- clickedEmployee(source, clicked_atom)
+ if(ishuman(clicked_atom) && ClickedEmployee(source, clicked_atom))
ammo--
+ to_chat(source, span_warning("[ammo] bullets remaining."))
return
- if(ishostile(clicked_atom))
- clickedAbno(source, clicked_atom)
+ if(ishostile(clicked_atom) && ClickedAbno(source, clicked_atom))
ammo--
+ to_chat(source, span_warning("[ammo] bullets remaining."))
return
-/obj/machinery/computer/camera_advanced/manager/proc/clickedEmployee(mob/living/owner, mob/living/carbon/employee) //contains carbon copy code of fire action
- var/mob/living/carbon/human/H = employee
- switch(bullettype)
- if(HP_BULLET)
- H.adjustBruteLoss(-0.15*H.maxHealth)
- if(SP_BULLET)
- H.adjustSanityLoss(-0.15*H.maxSanity)
- if(RED_BULLET)
+/obj/machinery/computer/camera_advanced/manager/proc/ClickedEmployee(mob/living/owner, mob/living/carbon/human/H) //contains carbon copy code of fire action
+ if(!istype(H))
+ to_chat(owner, span_warning("NO VALID TARGET."))
+ return FALSE
+
+ switch(bullet_type)
+ if(MANAGER_HP_BULLET)
+ H.adjustBruteLoss(-GetFacilityUpgradeValue(UPGRADE_BULLET_HEAL)*H.maxHealth)
+ if(MANAGER_SP_BULLET)
+ H.adjustSanityLoss(-GetFacilityUpgradeValue(UPGRADE_BULLET_HEAL)*H.maxSanity)
+ if(MANAGER_RED_BULLET)
H.apply_status_effect(/datum/status_effect/interventionshield)
- if(WHITE_BULLET)
+ if(MANAGER_WHITE_BULLET)
H.apply_status_effect(/datum/status_effect/interventionshield/white)
- if(BLACK_BULLET)
+ if(MANAGER_BLACK_BULLET)
H.apply_status_effect(/datum/status_effect/interventionshield/black)
- if(PALE_BULLET)
+ if(MANAGER_PALE_BULLET)
H.apply_status_effect(/datum/status_effect/interventionshield/pale)
- if(YELLOW_BULLET)
+ if(MANAGER_YELLOW_BULLET)
if(!owner.faction_check_mob(H))
H.apply_status_effect(/datum/status_effect/qliphothoverload)
else
to_chat(owner, "WELFARE SAFETY SYSTEM ERROR: TARGET SHARES CORPORATE FACTION.")
- return
+ return FALSE
else
to_chat(owner, "ERROR: BULLET INITIALIZATION FAILURE.")
- return
+ return FALSE
playsound(get_turf(src), 'ModularTegustation/Tegusounds/weapons/guns/manager_bullet_fire.ogg', 10, 0, 3)
playsound(get_turf(H), 'ModularTegustation/Tegusounds/weapons/guns/manager_bullet_fire.ogg', 10, 0, 3)
+ return TRUE
-/obj/machinery/computer/camera_advanced/manager/proc/clickedAbno(mob/living/owner, mob/living/simple_animal/hostile/critter)
- if(ammo >= 1)
- var/mob/living/simple_animal/hostile/abnormality/ABNO = critter
- if(bullettype == 7)
- ABNO.apply_status_effect(/datum/status_effect/qliphothoverload)
- ammo--
- playsound(get_turf(src), 'ModularTegustation/Tegusounds/weapons/guns/manager_bullet_fire.ogg', 10, 0, 3)
- playsound(get_turf(ABNO), 'ModularTegustation/Tegusounds/weapons/guns/manager_bullet_fire.ogg', 10, 0, 3)
- to_chat(owner, "Loading [ammo] Bullets.")
- return
- else
- to_chat(owner, "ERROR: BULLET INITIALIZATION FAILURE.")
- return
- if(ammo <= 0)
- playsound(get_turf(src), 'sound/weapons/empty.ogg', 10, 0, 3)
- to_chat(owner, "AMMO RESERVE EMPTY.")
- else
- to_chat(owner, "NO TARGET.")
- return
+/obj/machinery/computer/camera_advanced/manager/proc/ClickedAbno(mob/living/owner, mob/living/simple_animal/hostile/H)
+ if(!istype(H))
+ to_chat(owner, "NO VALID TARGET.")
+ return FALSE
+
+ if(bullet_type == 7)
+ H.apply_status_effect(/datum/status_effect/qliphothoverload)
+ playsound(get_turf(src), 'ModularTegustation/Tegusounds/weapons/guns/manager_bullet_fire.ogg', 10, 0, 3)
+ playsound(get_turf(H), 'ModularTegustation/Tegusounds/weapons/guns/manager_bullet_fire.ogg', 10, 0, 3)
+ to_chat(owner, "[ammo] bullets remaining.")
+ return TRUE
+
+ to_chat(owner, "ERROR: BULLET INITIALIZATION FAILURE.")
+ return FALSE
/obj/machinery/computer/camera_advanced/manager/proc/ManagerExaminate(mob/living/user, atom/clicked_atom)
user.examinate(clicked_atom) //maybe put more info on the agent/abno they examine if we want to be fancy later
@@ -236,10 +238,10 @@
to_chat(user, message)
-/obj/machinery/computer/camera_advanced/manager/proc/altClick(mob/living/user, turf/open/T)
+/obj/machinery/computer/camera_advanced/manager/proc/OnAltClick(mob/living/user, turf/open/T)
var/mob/living/C = user
if(command_cooldown <= world.time)
- for(var/obj/effect/temp_visual/HoloCommand/V in T)
+ for(var/obj/effect/temp_visual/holo_command/V in T)
qdel(V)
return
if(current_commands >= max_commands)
@@ -247,14 +249,14 @@
return
playsound(get_turf(src), 'sound/machines/terminal_success.ogg', 8, 3, 3)
playsound(get_turf(T), 'sound/machines/terminal_success.ogg', 8, 3, 3)
- if(commandtype > 0 && commandtype <= 6)
- var/thing_to_spawn = commandtypes[commandtype]
+ if(command_type > 0 && command_type <= 6)
+ var/thing_to_spawn = command_types[command_type]
var/thing_spawned = new thing_to_spawn(get_turf(T))
current_commands++
RegisterSignal(thing_spawned, COMSIG_PARENT_QDELETING, .proc/ReduceCommandAmount)
else
to_chat(C, "ERROR: Calibration Faliure.")
- commandtimer()
+ CommandTimer()
/obj/machinery/computer/camera_advanced/manager/proc/OnCtrlShiftClick(mob/living/user, atom/target)
if(!istype(swap))
@@ -267,22 +269,19 @@
current_commands--
//Numerical Procs that alter variables
-/obj/machinery/computer/camera_advanced/manager/proc/commandtimer()
+/obj/machinery/computer/camera_advanced/manager/proc/CommandTimer()
command_cooldown = world.time + command_delay
return
-/obj/machinery/computer/camera_advanced/manager/proc/alterbullettype(amount)
- bullettype = bullettype + amount
- return
-
-/obj/machinery/computer/camera_advanced/manager/proc/altercommandtype(amount)
- commandtype = commandtype + amount
+/obj/machinery/computer/camera_advanced/manager/proc/AlterCommandType(amount)
+ command_type = command_type + amount
return
/obj/machinery/computer/camera_advanced/manager/proc/RechargeMeltdown()
playsound(get_turf(src), 'sound/weapons/kenetic_reload.ogg', 10, 0, 3)
- max_ammo += 0.25
- ammo = max_ammo
+ ammo = GetFacilityUpgradeValue(UPGRADE_BULLET_COUNT)
+
+//Employee Tracking Code: Butchered AI Tracking
/*--------------------------------------------\
|Employee Tracking Code: Butchered AI Tracking|
@@ -300,6 +299,8 @@
for(var/i in GLOB.mob_living_list)
var/mob/living/L = i
+ if(L.stat == DEAD)
+ continue
if(!L.can_track(current_user))
continue
@@ -347,6 +348,9 @@
var/list/display_bullets = list()
var/obj/machinery/computer/camera_advanced/manager/console = target
for(var/i = 1 to console.bullet_types.len)
+ // Missing upgrade!
+ if(!GetFacilityUpgradeValue(console.bullet_types[i]["name"]))
+ continue
bullets[console.bullet_types[i]["name"]] = i
var/image/bullet_image = image(icon = 'icons/obj/manager_bullets.dmi', icon_state = console.bullet_types[i]["icon_state"])
display_bullets += list(console.bullet_types[i]["name"] = bullet_image)
@@ -359,7 +363,7 @@
name = "[console.bullet_types[chosen_bullet]["name"]] bullet"
desc = console.bullet_types[chosen_bullet]["desc"]
button_icon_state = console.bullet_types[chosen_bullet]["icon_state"]
- console.bullettype = chosen_bullet
+ console.bullet_type = chosen_bullet
UpdateButtonIcon()
playsound(get_turf(target), 'sound/weapons/kenetic_reload.ogg', 15, TRUE)
@@ -373,46 +377,19 @@
if(!target || !isliving(owner))
return
var/mob/living/carbon/human/C = owner
- var/mob/camera/ai_eye/remote/remote_eye = C.remote_control
- var/turf/T = get_turf(remote_eye)
+ var/turf/T = get_turf(C.remote_control)
var/obj/machinery/computer/camera_advanced/manager/X = target
- if(X.ammo >= 1)
- switch(X.bullettype)
- if(HP_BULLET to YELLOW_BULLET)
- for(var/mob/living/carbon/human/H in range(0, T))
- switch(X.bullettype)
- if(HP_BULLET)
- H.adjustBruteLoss(-0.15*H.maxHealth)
- if(SP_BULLET)
- H.adjustSanityLoss(-0.15*H.maxSanity)
- if(RED_BULLET)
- H.apply_status_effect(/datum/status_effect/interventionshield) //shield status effects located in lc13unique items.
- if(WHITE_BULLET)
- H.apply_status_effect(/datum/status_effect/interventionshield/white)
- if(BLACK_BULLET)
- H.apply_status_effect(/datum/status_effect/interventionshield/black)
- if(YELLOW_BULLET)
- H.apply_status_effect(/datum/status_effect/interventionshield/pale)
- else
- to_chat(owner, "ERROR: BULLET INITIALIZATION FAILURE.")
- return
- X.ammo--
- playsound(get_turf(C), 'ModularTegustation/Tegusounds/weapons/guns/manager_bullet_fire.ogg', 10, 0, 3)
- playsound(get_turf(T), 'ModularTegustation/Tegusounds/weapons/guns/manager_shock.ogg', 10, 0, 3)
- to_chat(owner, "Loading [X.ammo] Bullets.")
- return
- if(YELLOW_BULLET)
- for(var/mob/living/simple_animal/hostile/abnormality/ABNO in T.contents)
- ABNO.apply_status_effect(/datum/status_effect/qliphothoverload)
- X.ammo--
- to_chat(owner, "Loading [X.ammo] Bullets.")
- return
- if(X.ammo < 1)
- to_chat(owner, "AMMO RESERVE EMPTY.")
- playsound(get_turf(src), 'sound/weapons/empty.ogg', 10, 0, 3)
- else
- to_chat(owner, "NO TARGET.")
- return
+ var/list/valid_targets = list()
+ for(var/mob/living/L in T)
+ if(L.stat == DEAD)
+ continue
+ if(!ishuman(L) && !ishostile(L))
+ continue
+ valid_targets += L
+ if(!LAZYLEN(valid_targets))
+ to_chat(C, "No valid targets found!")
+ return FALSE
+ return X.OnHotkeyClick(C, pick(valid_targets))
/datum/action/innate/cyclecommand
name = "Cycle Command"
@@ -428,33 +405,33 @@
/datum/action/innate/cyclecommand/Activate()
var/obj/machinery/computer/camera_advanced/manager/X = target
- switch(X.commandtype)
+ switch(X.command_type)
if(0) //if 0 change to 1
to_chat(owner, "MOVE IMAGE INITIALIZED.")
button_icon_state = button_icon1
- X.altercommandtype(1)
+ X.AlterCommandType(1)
if(1)
to_chat(owner, "WARN IMAGE INITIALIZED.")
button_icon_state = button_icon2
- X.altercommandtype(1)
+ X.AlterCommandType(1)
if(2)
to_chat(owner, "GAURD IMAGE INITIALIZED.")
button_icon_state = button_icon3
- X.altercommandtype(1)
+ X.AlterCommandType(1)
if(3)
to_chat(owner, "HEAL IMAGE INITIALIZED.")
button_icon_state = button_icon4
- X.altercommandtype(1)
+ X.AlterCommandType(1)
if(4)
to_chat(owner, "FIGHT_LIGHT IMAGE INITIALIZED.")
button_icon_state = button_icon5
- X.altercommandtype(1)
+ X.AlterCommandType(1)
if(5)
to_chat(owner, "FIGHT_HEAVY IMAGE INITIALIZED.")
button_icon_state = button_icon6
- X.altercommandtype(1)
+ X.AlterCommandType(1)
else
- X.altercommandtype(-5)
+ X.AlterCommandType(-5)
to_chat(owner, "MOVE IMAGE INITIALIZED.")
button_icon_state = button_icon1
UpdateButtonIcon()
@@ -473,7 +450,7 @@
var/obj/machinery/computer/camera_advanced/manager/X = E.origin
var/cooldown = X.command_cooldown
if(cooldown <= world.time)
- X.altClick(C, get_turf(E))
+ X.OnAltClick(C, get_turf(E))
//////////////
// Unlockables
@@ -482,7 +459,7 @@
// Records core reward
/datum/action/innate/swap_cells
name = "Swap Abnormality Cells"
- desc = "Hotkey = Alt + Shift + Click"
+ desc = "Hotkey = Ctrl + Shift + Click"
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "vortex_ff_off"
/// Currently selected abnormality; Next activation will do the swap
@@ -553,9 +530,7 @@
#undef PALE_BULLET
#undef YELLOW_BULLET
- /*---------------------------\
- |Manager Camera Tracking Code|
- \---------------------------*/
+//Manager Camera Tracking Code
/datum/action/innate/manager_track
name = "Follow Creature"
desc = "Track a creature."
@@ -592,7 +567,6 @@
/obj/machinery/computer/camera_advanced/manager/sephirah //crude and lazy but i think it may work.
name = "sephirah camera console"
ammo = 0
- max_ammo = 0
/obj/machinery/computer/camera_advanced/manager/sephirah/Initialize(mapload)
. = ..()
@@ -625,11 +599,19 @@
follow.Grant(user)
actions += follow
- RegisterSignal(user, COMSIG_XENO_TURF_CLICK_ALT, .proc/altClick)
+ RegisterSignal(user, COMSIG_XENO_TURF_CLICK_ALT, .proc/OnAltClick)
RegisterSignal(user, COMSIG_MOB_SHIFTCLICKON, .proc/ManagerExaminate)
-/obj/machinery/computer/camera_advanced/manager/sephirah/clickedEmployee()
+/obj/machinery/computer/camera_advanced/manager/sephirah/ClickedEmployee()
return
/obj/machinery/computer/camera_advanced/manager/sephirah/RechargeMeltdown()
return
+
+#undef MANAGER_HP_BULLET
+#undef MANAGER_SP_BULLET
+#undef MANAGER_RED_BULLET
+#undef MANAGER_WHITE_BULLET
+#undef MANAGER_BLACK_BULLET
+#undef MANAGER_PALE_BULLET
+#undef MANAGER_YELLOW_BULLET
diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm
index 0c4e511f7c85..2f4650877c2b 100644
--- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm
+++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm
@@ -1039,35 +1039,35 @@
icon_state = "nobody_slash"
duration = 5
-/obj/effect/temp_visual/HoloCommand
+/obj/effect/temp_visual/holo_command
icon = 'ModularTegustation/Teguicons/lc13icons.dmi'
light_range = 1.5
light_power = 0.2
light_system = MOVABLE_LIGHT
duration = 150 //15 Seconds
-/obj/effect/temp_visual/HoloCommand/commandMove
+/obj/effect/temp_visual/holo_command/command_move
icon_state = "Move_here_wagie"
light_range = 1
light_power = 1
light_color = COLOR_VERY_LIGHT_GRAY
-/obj/effect/temp_visual/HoloCommand/commandWarn
+/obj/effect/temp_visual/holo_command/command_warn
icon_state = "Watch_out_wagie"
light_color = COLOR_PALE_RED_GRAY
-/obj/effect/temp_visual/HoloCommand/commandGaurd
+/obj/effect/temp_visual/holo_command/command_guard
icon_state = "Guard_this_wagie"
light_color = COLOR_VERY_SOFT_YELLOW
-/obj/effect/temp_visual/HoloCommand/commandHeal
+/obj/effect/temp_visual/holo_command/command_heal
icon_state = "Heal_this_wagie"
light_color = COLOR_VERY_PALE_LIME_GREEN
-/obj/effect/temp_visual/HoloCommand/commandFightA
+/obj/effect/temp_visual/holo_command/command_fight_a
icon_state = "Fight_this_wagie1"
light_color = COLOR_PALE_BLUE_GRAY
-/obj/effect/temp_visual/HoloCommand/commandFightB
+/obj/effect/temp_visual/holo_command/command_fight_b
icon_state = "Fight_this_wagie2"
light_color = COLOR_PALE_BLUE_GRAY
diff --git a/code/game/objects/items/clerks/hypo/hypo.dm b/code/game/objects/items/clerks/hypo/hypo.dm
index 3a3ab94d4920..f33aba3f6831 100644
--- a/code/game/objects/items/clerks/hypo/hypo.dm
+++ b/code/game/objects/items/clerks/hypo/hypo.dm
@@ -71,7 +71,7 @@
if(!clerk_check(user))
to_chat(user,"You don't know how to use this.")
return
- if(istype(SSlobotomy_corp.core_suppression, /datum/suppression/safety))
+ if(GetCoreSuppression(/datum/suppression/safety))
to_chat(user,"[src] seems to be remotely disabled.")
return
var/datum/reagents/R = reagent_list[mode]
diff --git a/code/modules/jobs/job_types/agent.dm b/code/modules/jobs/job_types/agent.dm
index 37518cf025bf..944a2f5ee10d 100644
--- a/code/modules/jobs/job_types/agent.dm
+++ b/code/modules/jobs/job_types/agent.dm
@@ -27,7 +27,7 @@
job_important = "You are an L-Corp agent. Your job is to work on, and suppress abnormalities. Use :h to talk on your departmental radio."
- var/normal_attribute_level = 20 // Scales with round time
+ var/normal_attribute_level = 20 // Scales with round time & facility upgrades
/datum/job/agent/after_spawn(mob/living/carbon/human/H, mob/M, latejoin = FALSE)
// Assign department security
@@ -62,7 +62,7 @@
ears = /obj/item/radio/headset/headset_records
accessory = /obj/item/clothing/accessory/armband/lobotomy/records
- else //Pick a department or get training.
+ else //Pick a department or get training.
ears = /obj/item/radio/headset/headset_training
accessory = /obj/item/clothing/accessory/armband/lobotomy/training
@@ -81,32 +81,22 @@
var/set_attribute = normal_attribute_level
- if(world.time >= 75 MINUTES) // Full facility expected
+ // Variables from abno queue subsystem
+ var/spawned_abnos = SSabnormality_queue.spawned_abnos
+ var/rooms_start = SSabnormality_queue.rooms_start
+
+ if(spawned_abnos > rooms_start * 0.95) // Full facility!
set_attribute *= 4
- else if(world.time >= 60 MINUTES) // More than one ALEPH
+ else if(spawned_abnos > rooms_start * 0.7) // ALEPHs around here
set_attribute *= 3
- else if(world.time >= 45 MINUTES) // Wowzer, an ALEPH?
+ else if(spawned_abnos > rooms_start * 0.5) // WAWs and others
set_attribute *= 2.5
- else if(world.time >= 30 MINUTES) // Expecting WAW
+ else if(spawned_abnos > rooms_start * 0.35) // HEs
set_attribute *= 2
- else if(world.time >= 15 MINUTES) // Usual time for HEs
+ else if(spawned_abnos > rooms_start * 0.2) // Shouldn't be anything more than TETHs
set_attribute *= 1.5
- //if(SSlobotomy_corp.understood_abnos.len && SSlobotomy_corp.understood_abnos.len > 0)
- // var/numberlol = SSlobotomy_corp.understood_abnos.len
- // var/totalcells = SSabnormality_queue.rooms_start
- // var/percentageofunderstanding = numberlol / totalcells
- // if(percentageofunderstanding == 0.5)
- // set_attribute *= 5
- // else if (percentageofunderstanding >= 0.4)
- // set_attribute *= 4
- // else if (percentageofunderstanding >= 0.3)
- // set_attribute *= 3
- // else if (percentageofunderstanding >= 0.2)
- // set_attribute *= 2
- // else if (percentageofunderstanding >= 0.1)
- // set_attribute *= 1.5
-
+ set_attribute += GetFacilityUpgradeValue(UPGRADE_AGENT_STATS)
for(var/A in roundstart_attributes)
roundstart_attributes[A] = round(set_attribute)
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 2a8312f8dd3d..2cb94578b286 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -347,7 +347,7 @@
if(getorgan(/obj/item/organ/brain))
if(ai_controller?.ai_status == AI_STATUS_ON)
if(istype(ai_controller, /datum/ai_controller/insane))
- msg += span_danger("[t_He] [t_is] completely out of [t_his] mind!")
+ msg += span_danger("[t_He] [t_is] completely out of [t_his] mind!\n")
else
msg += "[t_He] do[t_es]n't appear to be [t_him]self.\n"
if(!key)
diff --git a/code/modules/mob/living/simple_animal/abnormality/_abnormality.dm b/code/modules/mob/living/simple_animal/abnormality/_abnormality.dm
index 4f07d7cc0975..7c9babf9da14 100644
--- a/code/modules/mob/living/simple_animal/abnormality/_abnormality.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/_abnormality.dm
@@ -259,8 +259,35 @@
// Called by datum_reference when the abnormality has been fully spawned
/mob/living/simple_animal/hostile/abnormality/proc/PostSpawn()
+ SHOULD_CALL_PARENT(TRUE)
+ HandleStructures()
return
+// Moves structures already in its datum; Overrides can spawn structures here.
+/mob/living/simple_animal/hostile/abnormality/proc/HandleStructures()
+ SHOULD_CALL_PARENT(TRUE)
+ if(!datum_reference)
+ return FALSE
+ // Ensures all structures are in their place after respawning
+ for(var/atom/movable/A in datum_reference.connected_structures)
+ A.forceMove(get_turf(datum_reference.landmark))
+ A.x += datum_reference.connected_structures[A][1]
+ A.y += datum_reference.connected_structures[A][2]
+ return TRUE
+
+// A little helper proc to spawn structures; Returns itself, so you can handle additional stuff later
+/mob/living/simple_animal/hostile/abnormality/proc/SpawnConnectedStructure(atom/movable/A = null, x_offset = 0, y_offset = 0)
+ if(!ispath(A))
+ return
+ if(!istype(datum_reference))
+ return
+ A = new A(get_turf(src))
+ A.x += x_offset
+ A.y += y_offset
+ // We put it in datum ref for malicious purposes
+ datum_reference.connected_structures[A] = list(x_offset, y_offset)
+ return A
+
// transfers a var to the datum to be used later
/mob/living/simple_animal/hostile/abnormality/proc/TransferVar(index, value)
if(isnull(datum_reference))
@@ -273,7 +300,6 @@
return
return LAZYACCESS(datum_reference.transferable_var, index)
-
// Modifiers for work chance
/mob/living/simple_animal/hostile/abnormality/proc/WorkChance(mob/living/carbon/human/user, chance, work_type)
return chance
diff --git a/code/modules/mob/living/simple_animal/abnormality/aleph/crying_children.dm b/code/modules/mob/living/simple_animal/abnormality/aleph/crying_children.dm
index 71065fb0bae7..012da08aefbe 100644
--- a/code/modules/mob/living/simple_animal/abnormality/aleph/crying_children.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/aleph/crying_children.dm
@@ -130,6 +130,7 @@
// Silly multi icons, lets fix that! This is called each time it's spawned in containment, so it has normal sprite on adminbus spawn
/mob/living/simple_animal/hostile/abnormality/crying_children/PostSpawn()
+ . = ..()
desc = "A wax statue of an ...angel? It creepily floats around the containment room. You feel like you shouldn't be here for too long"
icon = 'ModularTegustation/Teguicons/32x32.dmi'
icon_state = "unspeaking_child"
diff --git a/code/modules/mob/living/simple_animal/abnormality/aleph/nobody_is.dm b/code/modules/mob/living/simple_animal/abnormality/aleph/nobody_is.dm
index f2cec256975e..c7ee97f54b7a 100644
--- a/code/modules/mob/living/simple_animal/abnormality/aleph/nobody_is.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/aleph/nobody_is.dm
@@ -109,6 +109,7 @@
//Spawning
/mob/living/simple_animal/hostile/abnormality/nobody_is/PostSpawn()
+ . = ..()
if(CheckCombat())
current_stage = 2
next_stage()
@@ -157,7 +158,7 @@
chosen.hairstyle = oldhair
chosen.facial_hairstyle = oldbeard
HD.update_limb()
- headicon = new(get_turf(src))
+ headicon = SpawnConnectedStructure(headicon)
headicon.add_overlay(HD.get_limb_icon(TRUE,TRUE))
headicon.pixel_y -= 5
headicon.alpha = 150
@@ -167,6 +168,7 @@
if(headicon) //Grab their head. Literally, and grab the icons from it; discard our old icon if we have one.
qdel(headicon)
headicon = null
+ datum_reference.connected_structures = list()
/mob/living/simple_animal/hostile/abnormality/nobody_is/WorkChance(mob/living/carbon/human/user, chance)
var/adjusted_chance = chance
@@ -282,6 +284,7 @@
if(headicon) //Gets rid of the reflection if they died in containtment for any reason
qdel(headicon)
headicon = null
+ datum_reference.connected_structures = list()
if(grab_victim)
ReleaseGrab()
return ..()
diff --git a/code/modules/mob/living/simple_animal/abnormality/aleph/nothing_there.dm b/code/modules/mob/living/simple_animal/abnormality/aleph/nothing_there.dm
index 8e78fe424b9a..43cb53c1d121 100644
--- a/code/modules/mob/living/simple_animal/abnormality/aleph/nothing_there.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/aleph/nothing_there.dm
@@ -126,6 +126,7 @@
return ..()
/mob/living/simple_animal/hostile/abnormality/nothing_there/PostSpawn()
+ . = ..()
var/list/old_heard = RememberVar(1)
if(islist(old_heard) && LAZYLEN(old_heard))
heard_words = old_heard
diff --git a/code/modules/mob/living/simple_animal/abnormality/he/galaxy_child.dm b/code/modules/mob/living/simple_animal/abnormality/he/galaxy_child.dm
index e2abbcbd6bba..91770f069dac 100644
--- a/code/modules/mob/living/simple_animal/abnormality/he/galaxy_child.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/he/galaxy_child.dm
@@ -42,6 +42,7 @@
. += span_info("He is sobbing inconsolably and has a forlorn demeanor.")
/mob/living/simple_animal/hostile/abnormality/galaxy_child/PostSpawn()
+ . = ..()
datum_reference.qliphoth_meter = 1
/mob/living/simple_animal/hostile/abnormality/galaxy_child/Life()
diff --git a/code/modules/mob/living/simple_animal/abnormality/teth/beauty_beast.dm b/code/modules/mob/living/simple_animal/abnormality/teth/beauty_beast.dm
index c691bd68e3e6..a1829a7a2245 100644
--- a/code/modules/mob/living/simple_animal/abnormality/teth/beauty_beast.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/teth/beauty_beast.dm
@@ -32,6 +32,7 @@
//it needs to use PostSpawn or we can't get the datum of beauty
/mob/living/simple_animal/hostile/abnormality/beauty/PostSpawn()
+ . = ..()
var/cursed = RememberVar(1)
if(!cursed)
return
diff --git a/code/modules/mob/living/simple_animal/abnormality/teth/meat_lantern.dm b/code/modules/mob/living/simple_animal/abnormality/teth/meat_lantern.dm
index cc552228a1ba..10ff7f7dca64 100644
--- a/code/modules/mob/living/simple_animal/abnormality/teth/meat_lantern.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/teth/meat_lantern.dm
@@ -43,6 +43,7 @@
var/chop_damage = 400
/mob/living/simple_animal/hostile/abnormality/meat_lantern/PostSpawn()
+ . = ..()
med_hud_set_health() //show medhud while in containment
med_hud_set_status()
diff --git a/code/modules/mob/living/simple_animal/abnormality/teth/punishing_bird.dm b/code/modules/mob/living/simple_animal/abnormality/teth/punishing_bird.dm
index e178cfec8f65..ef756dc41e6f 100644
--- a/code/modules/mob/living/simple_animal/abnormality/teth/punishing_bird.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/teth/punishing_bird.dm
@@ -28,7 +28,7 @@
attack_sound = 'sound/weapons/pbird_bite.ogg'
obj_damage = 0
environment_smash = ENVIRONMENT_SMASH_NONE
- is_flying_animal = FALSE
+ is_flying_animal = TRUE
speak_emote = list("chirps")
vision_range = 14
aggro_vision_range = 28
@@ -70,16 +70,6 @@
/mob/living/simple_animal/hostile/abnormality/punishing_bird/Initialize()
. = ..()
- if(locate(/obj/structure/pbird_perch) in get_turf(src))
- icon_state = "pbird"
- pixel_x = 15
- pixel_y = 32
- base_pixel_x = 15
- base_pixel_y = 32
- is_flying_animal = FALSE
- update_icon()
- else
- is_flying_animal = TRUE
RegisterSignal(SSdcs, COMSIG_GLOB_WORK_STARTED, .proc/OnAbnoWork)
RegisterSignal(SSdcs, COMSIG_GLOB_HUMAN_INSANE, .proc/OnHumanInsane)
@@ -88,15 +78,6 @@
UnregisterSignal(SSdcs, COMSIG_GLOB_HUMAN_INSANE)
return ..()
-// Deletes perch if we moved while not breaching; Generally caused by cell swaps
-/mob/living/simple_animal/hostile/abnormality/punishing_bird/Move()
- if(!IsContained())
- return ..()
- var/obj/structure/pbird_perch/P = locate() in get_turf(src)
- QDEL_NULL(P)
- . = ..()
- PostSpawn()
-
/mob/living/simple_animal/hostile/abnormality/punishing_bird/proc/TransformRed()
visible_message(span_danger("\The [src] turns its insides out as a giant bloody beak appears!"))
icon_state = "pbird_red"
@@ -236,16 +217,19 @@
see &= targeting // Remove all entries that aren't in enemies
return see
-/mob/living/simple_animal/hostile/abnormality/punishing_bird/PostSpawn()
- ..()
- if(locate(/obj/structure/pbird_perch) in get_turf(src))
+/mob/living/simple_animal/hostile/abnormality/punishing_bird/HandleStructures()
+ . = ..()
+ if(!.)
return
+ if(!locate(/obj/structure/pbird_perch) in datum_reference.connected_structures)
+ SpawnConnectedStructure(/obj/structure/pbird_perch)
icon_state = "pbird"
pixel_x = 15
pixel_y = 32
base_pixel_x = 15
base_pixel_y = 32
- new /obj/structure/pbird_perch(get_turf(src))
+ is_flying_animal = FALSE
+ update_icon()
/mob/living/simple_animal/hostile/abnormality/punishing_bird/proc/Retaliate(atom/movable/A)
if((health < maxHealth * 0.9) && (obj_damage <= 0))
diff --git a/code/modules/mob/living/simple_animal/abnormality/teth/spider_bud.dm b/code/modules/mob/living/simple_animal/abnormality/teth/spider_bud.dm
index 08087ed710c0..b0c5d7fa02a9 100644
--- a/code/modules/mob/living/simple_animal/abnormality/teth/spider_bud.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/teth/spider_bud.dm
@@ -29,8 +29,7 @@
// If you do insight or have low prudence, fuck you and die for stepping on a spider
if((get_attribute_level(user, PRUDENCE_ATTRIBUTE) < 40 || work_type == ABNORMALITY_WORK_INSIGHT) && !(GODMODE in user.status_flags))
icon_state = "spider_open"
- var/obj/structure/spider/cocoon/casing = new(src.loc)
- casing.Move(get_step(casing, pick(GLOB.alldirs)))
+ var/obj/structure/spider/cocoon/casing = SpawnConnectedStructure(/obj/structure/spider/cocoon, pick(-1,0,1), pick(-1,0,1))
user.death()
user.forceMove(casing)
casing.icon_state = pick("cocoon_large1","cocoon_large2","cocoon_large3")
diff --git a/code/modules/mob/living/simple_animal/abnormality/waw/fire_bird.dm b/code/modules/mob/living/simple_animal/abnormality/waw/fire_bird.dm
index c09b80d5dc90..b361cd728e1c 100644
--- a/code/modules/mob/living/simple_animal/abnormality/waw/fire_bird.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/waw/fire_bird.dm
@@ -47,11 +47,13 @@
var/list/been_hit = list()
//Initialize
-/mob/living/simple_animal/hostile/abnormality/fire_bird/PostSpawn()
- ..()
- if(locate(/obj/structure/firetree) in get_turf(src))
+/mob/living/simple_animal/hostile/abnormality/fire_bird/HandleStructures()
+ . = ..()
+ if(!.)
+ return
+ if(locate(/obj/structure/firetree) in datum_reference.connected_structures)
return
- new /obj/structure/firetree(get_turf(src))
+ SpawnConnectedStructure(/obj/structure/firetree)
//Work Procs
/mob/living/simple_animal/hostile/abnormality/fire_bird/FailureEffect(mob/living/carbon/human/user, work_type, pe)
diff --git a/code/modules/mob/living/simple_animal/abnormality/zayin/wellcheers.dm b/code/modules/mob/living/simple_animal/abnormality/zayin/wellcheers.dm
index f0d45cb7c9af..e7cb97446a22 100644
--- a/code/modules/mob/living/simple_animal/abnormality/zayin/wellcheers.dm
+++ b/code/modules/mob/living/simple_animal/abnormality/zayin/wellcheers.dm
@@ -33,25 +33,14 @@
harvest_phrase = span_notice("The machine dispenses some clear-ish soda into %VESSEL.")
harvest_phrase_third = "%PERSON holds up %VESSEL and lets %ABNO dispense some clear-ish soda into it."
- var/list/side_shrimps = list()
-
-/mob/living/simple_animal/hostile/abnormality/wellcheers/PostSpawn()
- ..()
- for(var/d in list(EAST, WEST))
- var/turf/TF = get_step(src, d)
- if(!istype(TF))
- continue
- if(!TF.is_blocked_turf(TRUE))
- if(locate(/obj/structure/wellcheers_side_shrimp) in TF)
- continue
- var/obj/structure/wellcheers_side_shrimp/shrimp = new(TF)
- side_shrimps += shrimp
-
-/mob/living/simple_animal/hostile/abnormality/wellcheers/Destroy()
- for(var/shrimp in side_shrimps)
- qdel(shrimp)
- side_shrimps = null
- ..()
+/mob/living/simple_animal/hostile/abnormality/wellcheers/HandleStructures()
+ . = ..()
+ if(!.)
+ return
+ if(locate(/obj/structure/wellcheers_side_shrimp) in datum_reference.connected_structures)
+ return
+ SpawnConnectedStructure(/obj/structure/wellcheers_side_shrimp, 1)
+ SpawnConnectedStructure(/obj/structure/wellcheers_side_shrimp, -1)
/mob/living/simple_animal/hostile/abnormality/wellcheers/SuccessEffect(mob/living/carbon/human/user, work_type, pe)
var/obj/item/dropped_can
@@ -73,7 +62,7 @@
// Death!
/mob/living/simple_animal/hostile/abnormality/wellcheers/FailureEffect(mob/living/carbon/human/user, work_type, pe)
// Visual effects
- for(var/obj/structure/wellcheers_side_shrimp/shrimp in side_shrimps)
+ for(var/obj/structure/wellcheers_side_shrimp/shrimp in datum_reference.connected_structures)
shrimp.ShrimpDance()
for(var/turf/open/T in view(7, src))
new /obj/effect/temp_visual/water_waves(T)
diff --git a/code/modules/mob/living/simple_animal/hostile/ordeal/white.dm b/code/modules/mob/living/simple_animal/hostile/ordeal/white.dm
index 22d43c7ab0f3..b2ad8c0ccad8 100644
--- a/code/modules/mob/living/simple_animal/hostile/ordeal/white.dm
+++ b/code/modules/mob/living/simple_animal/hostile/ordeal/white.dm
@@ -92,7 +92,7 @@
playsound(src, 'sound/effects/ordeals/white/black_ability_end.ogg', 100, FALSE, 30)
for(var/obj/machinery/computer/abnormality/A in urange(current_pulse_range, src))
if(prob(66) && !A.meltdown && A.datum_reference && A.datum_reference.current && A.datum_reference.qliphoth_meter)
- A.datum_reference.qliphoth_change(pick(-1, -2))
+ INVOKE_ASYNC(A.datum_reference, /datum/abnormality/proc/qliphoth_change, pick(-1, -2))
icon_state = icon_living
SLEEP_CHECK_DEATH(5)
pulse_cooldown = world.time + pulse_cooldown_time
@@ -684,7 +684,10 @@
continue
if(get_dist(src, H) < 8)
continue
- potential_teleports += pick(get_adjacent_open_turfs(H))
+ var/list/adj_turfs = get_adjacent_open_turfs(H)
+ if(!LAZYLEN(adj_turfs))
+ continue
+ potential_teleports += pick(adj_turfs)
if(!LAZYLEN(potential_teleports))
return // Nowhere to run!
var/turf/target_turf = pick(potential_teleports)
diff --git a/code/modules/ordeals/_ordeal.dm b/code/modules/ordeals/_ordeal.dm
index 8b7ce2c6e36c..ae3cab516ca6 100644
--- a/code/modules/ordeals/_ordeal.dm
+++ b/code/modules/ordeals/_ordeal.dm
@@ -49,6 +49,7 @@
priority_announce("The ordeal has ended. Facility has been rewarded with [reward_percent*100]% PE.", name, sound=null)
SSlobotomy_corp.AdjustAvailableBoxes(total_reward)
SSlobotomy_corp.current_ordeals -= src
+ SSlobotomy_corp.AddLobPoints(level * 0.5, "Ordeal Reward")
if(end_sound)
for(var/mob/M in GLOB.player_list)
if(M.client)
@@ -59,14 +60,14 @@
if(!H.client || !H.ckey)
continue
SSpersistence.agent_rep_change[H.ckey] += level
- /// If it was a midnight and we got to it before time limit after previously completing a core suppression
- if(level == 4 && SSlobotomy_corp.core_suppression_state == 2 && \
- start_time <= CONFIG_GET(number/suppression_time_limit))
+ /// If it was a midnight and we got to it before time limit
+ if(level == 4 && start_time <= CONFIG_GET(number/suppression_time_limit))
// Extra cores, and announced!
addtimer(CALLBACK(SSlobotomy_corp, /datum/controller/subsystem/lobotomy_corp/proc/PickPotentialSuppressions, TRUE, TRUE), 15 SECONDS)
/// If it was a dusk - we end running core suppression
else if(level == 3 && istype(SSlobotomy_corp.core_suppression))
addtimer(CALLBACK(SSlobotomy_corp.core_suppression, /datum/suppression/proc/End), 5 SECONDS)
+ SEND_GLOBAL_SIGNAL(COMSIG_GLOB_ORDEAL_END, src)
qdel(src)
return
diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm
index 6ae56759a9a3..ad111b253227 100644
--- a/code/modules/reagents/reagent_containers/hypospray.dm
+++ b/code/modules/reagents/reagent_containers/hypospray.dm
@@ -31,7 +31,7 @@
if(!isliving(M))
return FALSE
// WOULDN'T IT BE FUNNY IF I TOOK AWAY YOUR HEALING?
- if(istype(SSlobotomy_corp.core_suppression, /datum/suppression/safety))
+ if(GetCoreSuppression(/datum/suppression/safety))
if(!do_after(user, 10, target = M))
return FALSE
if(prob(50))
diff --git a/code/modules/suppressions/_core_suppression.dm b/code/modules/suppressions/_core_suppression.dm
index 8946335edaff..d91315d8f9f5 100644
--- a/code/modules/suppressions/_core_suppression.dm
+++ b/code/modules/suppressions/_core_suppression.dm
@@ -17,11 +17,18 @@
var/end_sound = null
/// If TRUE - will only show up after clearing midnight; Those suppressions are essentially the extra bossfight
var/after_midnight = FALSE
+ /// If TRUE - persistence file will be updated; This is to prevent admins from "accidentally" breaking it
+ var/legitimate = FALSE
+ /// If FALSE - will not appear anywhere under normal circumstances
+ var/available = TRUE
// Runs the event itself
-/datum/suppression/proc/Run(run_white = FALSE)
- priority_announce(run_text, name, sound=annonce_sound)
+/datum/suppression/proc/Run(run_white = FALSE, silent = FALSE)
+ if(!silent)
+ priority_announce(run_text, name, sound=annonce_sound)
+ SSlobotomy_corp.core_suppression = src
SSlobotomy_corp.core_suppression_state = max(SSlobotomy_corp.core_suppression_state, 1) // Started suppression
+ SSlobotomy_corp.active_core_suppressions |= src
SSticker.news_report = max(SSticker.news_report, CORE_STARTED)
if(run_white)
SSlobotomy_corp.next_ordeal_level = 6 // White dawn
@@ -29,10 +36,14 @@
return
// Ends the event
-/datum/suppression/proc/End()
- priority_announce(end_text, name, sound=end_sound)
+/datum/suppression/proc/End(silent = FALSE)
+ if(!silent)
+ priority_announce(end_text, name, sound=end_sound)
SSlobotomy_corp.core_suppression = null
SSlobotomy_corp.core_suppression_state = max(SSlobotomy_corp.core_suppression_state, 2) // Finished core suppression
+ SSlobotomy_corp.active_core_suppressions -= src
SSticker.news_report = max(SSticker.news_report, CORE_SUPPRESSED)
+ if(legitimate)
+ SSpersistence.UpdateClearedCores(src)
qdel(src)
return
diff --git a/code/modules/suppressions/command.dm b/code/modules/suppressions/command.dm
index 2740c4be13dd..1a0db032adcb 100644
--- a/code/modules/suppressions/command.dm
+++ b/code/modules/suppressions/command.dm
@@ -1,5 +1,5 @@
/datum/suppression/command
- name = "Central Command Core Suppression"
+ name = COMMAND_CORE_SUPPRESSION
desc = "Meltdowns immunities of certain abnormality levels will be forfeit for the duration of the suppression \
and more meltdowns will occur with lower timer on each. Missed or failed meltdowns will trigger a \
meltdown on another abnormality within the facility."
@@ -12,14 +12,16 @@
/// Amount of additional abnormalities melting each qliphoth event
var/meltdown_count_increase = 2
/// Multiplier to the duration of abnormality meltdowns
- var/meltdown_time_multiplier = 0.9
+ var/meltdown_time_multiplier = 0.8
+ /// By how much meltdown timer is reduced each ordeal
+ var/meltdown_time_reduction = 0.2
-/datum/suppression/command/Run(run_white = FALSE)
+/datum/suppression/command/Run(run_white = FALSE, silent = FALSE)
. = ..()
RegisterSignal(SSdcs, COMSIG_GLOB_MELTDOWN_START, .proc/OnQlipMeltdown)
RegisterSignal(SSdcs, COMSIG_GLOB_MELTDOWN_FINISHED, .proc/OnAbnoMeltdown)
-/datum/suppression/command/End()
+/datum/suppression/command/End(silent = FALSE)
UnregisterSignal(SSdcs, COMSIG_GLOB_MELTDOWN_START)
UnregisterSignal(SSdcs, COMSIG_GLOB_MELTDOWN_FINISHED)
SSlobotomy_corp.melt_work_multiplier += 1
@@ -30,16 +32,21 @@
SIGNAL_HANDLER
if(ordeal)
meltdown_count_increase += 1
- meltdown_time_multiplier = max(0.1, meltdown_time_multiplier - 0.2)
+ meltdown_time_multiplier = max(0.1, meltdown_time_multiplier - meltdown_time_reduction)
-/datum/suppression/command/proc/OnAbnoMeltdown(obj/machinery/computer/abnormality/source, melt_removed = TRUE)
+/datum/suppression/command/proc/OnAbnoMeltdown(datum/dcs, datum/abnormality/source, melt_removed = TRUE)
SIGNAL_HANDLER
if(!istype(source))
return
+ var/obj/machinery/computer/abnormality/console = source.console
+ if(!istype(console))
+ return
if(melt_removed)
return
var/list/potential_consoles = list()
for(var/obj/machinery/computer/abnormality/A in GLOB.abnormality_consoles)
+ if(A == console)
+ continue
if(!A.can_meltdown)
continue
if(!A.datum_reference || !A.datum_reference.current)
@@ -53,7 +60,7 @@
if(!LAZYLEN(potential_consoles))
return
var/obj/machinery/computer/abnormality/A = pick(potential_consoles)
- source.Beam(A, icon_state = "volt_ray", time = 5 SECONDS)
- playsound(source, 'sound/weapons/zapbang.ogg', 50, TRUE)
+ console.Beam(A, icon_state = "volt_ray", time = 5 SECONDS)
+ playsound(console, 'sound/weapons/zapbang.ogg', 50, TRUE)
playsound(A, 'sound/weapons/zapbang.ogg', 50, TRUE)
A.start_meltdown(MELTDOWN_NORMAL, round(40 * meltdown_time_multiplier), round(60 * meltdown_time_multiplier))
diff --git a/code/modules/suppressions/control.dm b/code/modules/suppressions/control.dm
index d8c3db3b20e9..db9cf85b8577 100644
--- a/code/modules/suppressions/control.dm
+++ b/code/modules/suppressions/control.dm
@@ -1,15 +1,15 @@
/datum/suppression/control
- name = "Control Core Suppression"
+ name = CONTROL_CORE_SUPPRESSION
desc = "Assignments on the abnormality work consoles will be scrambled each meltdown/ordeal."
reward_text = "All employees, including those that may join later in the shift will receive a +30 justice attribute buff."
run_text = "The core suppression of Control department has begun. The work assignments will be scrambled each meltdown."
-/datum/suppression/control/Run(run_white = FALSE)
+/datum/suppression/control/Run(run_white = FALSE, silent = FALSE)
. = ..()
RegisterSignal(SSdcs, COMSIG_GLOB_MELTDOWN_START, .proc/OnMeltdown)
OnMeltdown()
-/datum/suppression/control/End()
+/datum/suppression/control/End(silent = FALSE)
UnregisterSignal(SSdcs, COMSIG_GLOB_MELTDOWN_START)
for(var/obj/machinery/computer/abnormality/C in GLOB.abnormality_consoles)
C.scramble_list = list()
diff --git a/code/modules/suppressions/extraction.dm b/code/modules/suppressions/extraction.dm
index 10501a00c7d5..c798a0509b1c 100644
--- a/code/modules/suppressions/extraction.dm
+++ b/code/modules/suppressions/extraction.dm
@@ -1,6 +1,6 @@
// It is effectively an ordeal in how it works
/datum/suppression/extraction
- name = "Extraction Core Suppression"
+ name = EXTRACTION_CORE_SUPPRESSION
desc = "The illusion of the Arbiter will return to wreak havoc once more.
\
Special types of meltdowns have to be cleared to weaken the Arbiter; Otherwise you stand no chance."
goal_text = "Defeat the Arbiter."
@@ -9,13 +9,13 @@
end_sound = 'sound/effects/combat_suppression_end.ogg'
after_midnight = TRUE
-/datum/suppression/extraction/Run(run_white = FALSE)
+/datum/suppression/extraction/Run(run_white = FALSE, silent = FALSE)
..()
var/turf/T = pick(GLOB.department_centers)
var/mob/living/simple_animal/hostile/megafauna/arbiter/A = new(T)
RegisterSignal(A, COMSIG_PARENT_QDELETING, .proc/OnArbiterDeath)
-/datum/suppression/extraction/End()
+/datum/suppression/extraction/End(silent = FALSE)
..()
SSlobotomy_corp.core_suppression_state = max(SSlobotomy_corp.core_suppression_state, 3)
SSticker.news_report = max(SSticker.news_report, CORE_SUPPRESSED_ARBITER_DEAD)
diff --git a/code/modules/suppressions/information.dm b/code/modules/suppressions/information.dm
index 8814d68dd05c..b9412976bd60 100644
--- a/code/modules/suppressions/information.dm
+++ b/code/modules/suppressions/information.dm
@@ -1,18 +1,20 @@
// Most of its effects are applied elsewhere
/datum/suppression/information
- name = "Information Core Suppression"
+ name = INFORMATION_CORE_SUPPRESSION
desc = "Assignments on the abnormality work consoles will be in random positions.\n\
Announcement systems and suit sensors will be negatively impacted."
reward_text = "Unique PE gained by working on abnormalities is increased by 25%."
run_text = "The core suppression of Information department has begun. The information and sensors will be distorted for its duration."
/// Used in Gibberish() proc as third argument in relevant places.
- var/gibberish_value = 20
+ var/gibberish_value = 10
+ /// By how much the value is increased on each ordeal
+ var/gibberish_value_increase = 30
-/datum/suppression/information/Run(run_white = FALSE)
+/datum/suppression/information/Run(run_white = FALSE, silent = FALSE)
. = ..()
RegisterSignal(SSdcs, COMSIG_GLOB_MELTDOWN_START, .proc/OnMeltdown)
-/datum/suppression/information/End()
+/datum/suppression/information/End(silent = FALSE)
UnregisterSignal(SSdcs, COMSIG_GLOB_MELTDOWN_START)
SSlobotomy_corp.box_work_multiplier *= 1.25
return ..()
@@ -21,4 +23,4 @@
/datum/suppression/information/proc/OnMeltdown(datum/source, ordeal = FALSE)
SIGNAL_HANDLER
if(ordeal)
- gibberish_value = min(80, gibberish_value + 30)
+ gibberish_value = min(80, gibberish_value + gibberish_value_increase)
diff --git a/code/modules/suppressions/keter.dm b/code/modules/suppressions/keter.dm
new file mode 100644
index 000000000000..a5e2e6d7c0dd
--- /dev/null
+++ b/code/modules/suppressions/keter.dm
@@ -0,0 +1,290 @@
+// A day 46 wannabe - Only triggers white ordeals
+/datum/suppression/keter_day46
+ name = DAY46_CORE_SUPPRESSION
+ desc = "The facility will introduce White Ordeals with 1 meltdown in-between them.
\
+ After clearing Dawn, Noon and Dusk the agents will have to face off against The Claw."
+ goal_text = "Defeat the Midnight of White - The Claw."
+ run_text = "The Ordeals of White have been introduced into the facility's subroutines. There will be one meltdown in-between each ordeal."
+ annonce_sound = 'sound/effects/combat_suppression_start.ogg'
+ end_sound = 'sound/effects/combat_suppression_end.ogg'
+ after_midnight = TRUE
+
+/datum/suppression/keter_day46/Run(run_white = TRUE, silent = FALSE)
+ var/blurb_text = pick(
+ "Will we finally meet after such a long time..?",
+ "You have reached this place after such a long time...",
+ "Let your body and mind rest. You must be exhausted...",
+ )
+ INVOKE_ASYNC(GLOBAL_PROC, .proc/show_global_blurb, 10 SECONDS, blurb_text, 1 SECONDS, "white", "black", "left", "CENTER-6,BOTTOM+2")
+ return ..()
+
+/* Combined cores go here */
+/datum/suppression/combination
+ reward_text = "We will get one step closer to our goal..."
+ goal_text = "Defeat the Midnight of White - The Claw."
+ annonce_sound = 'sound/effects/combat_suppression_start.ogg'
+ end_sound = 'sound/effects/combat_suppression_end.ogg'
+ after_midnight = TRUE
+ available = FALSE
+ /// List of all cores "inside" of it; On End - ends them, too
+ var/list/running_cores = list()
+ /// List of core names required for this suppression to be available for selection
+ var/list/required_cores = list()
+
+/datum/suppression/combination/New()
+ . = ..()
+ if(!LAZYLEN(required_cores))
+ return
+ if(available)
+ return
+
+ var/list/all_agents = AllLivingAgents()
+ /// Amount of people online that have met the requirements
+ var/clear_count = 0
+ /// How many people must meet requirements to enable it
+ var/clear_requirement = length(all_agents) * 0.5
+ for(var/mob/M in all_agents)
+ if(!(M.ckey in SSpersistence.cleared_core_suppressions))
+ continue
+ var/list/diffs = difflist(required_cores, SSpersistence.cleared_core_suppressions[M.ckey])
+ if(LAZYLEN(diffs))
+ continue
+ clear_count += 1
+
+ if(clear_count >= clear_requirement)
+ available = TRUE
+
+/datum/suppression/combination/End(silent = FALSE)
+ for(var/datum/suppression/S in running_cores)
+ S.End(TRUE)
+ return ..()
+
+// Day 47 - Control, Information, Safety and Training all combined, while also running white ordeals. HAVE FUN.
+/datum/suppression/combination/keter_day47
+ name = DAY47_CORE_SUPPRESSION
+ desc = "Effects of core suppressions of Control, Information, Safety and Training departments \
+ will activate for the duration of this test.
\
+ To complete the challenge - you must defeat the Midnight of White - The Claw."
+ run_text = "Effects of Control, Information, Safety and Training core suppressions are now in effect. Ordeals of White have been introduced in the subroutines."
+ required_cores = list(
+ CONTROL_CORE_SUPPRESSION,
+ INFORMATION_CORE_SUPPRESSION,
+ SAFETY_CORE_SUPPRESSION,
+ TRAINING_CORE_SUPPRESSION,
+ DAY46_CORE_SUPPRESSION,
+ )
+
+/datum/suppression/combination/keter_day47/Run(run_white = TRUE, silent = FALSE)
+ . = ..()
+ // Ominous blurbs
+ var/list/blurb_list = list(
+ "It seems you have decided to move forward...",
+ "Your body and mind are weathered. Where does your confidence come from?",
+ "How do we expect to move forward when we cannot even stand up straight?",
+ "It is best for everyone if we just turn back to the first act now.",
+ "Who knows, our unforgivable sin may lighten just a tiny bit if you do.",
+ )
+ for(var/i = 1 to length(blurb_list))
+ var/blurb_text = blurb_list[i]
+ addtimer(CALLBACK(GLOBAL_PROC, .proc/show_global_blurb, 10 SECONDS, blurb_text, 1 SECONDS, "white", "black", "left", "CENTER-6,BOTTOM+2"), i * 11 SECONDS)
+ // Create our cores
+ running_cores += new /datum/suppression/control
+ // Less scuffed words in announcements
+ var/datum/suppression/information/I = new
+ I.gibberish_value_increase = 10
+ running_cores += I
+ running_cores += new /datum/suppression/safety
+ // More stat reductions at the start, but gets reverted over time
+ var/datum/suppression/training/T = new
+ T.attribute_debuff_count_starting = -60
+ T.attribute_debuff_count = 10
+ running_cores += T
+ // And then start them all
+ for(var/datum/suppression/S in running_cores)
+ S.Run(FALSE, TRUE)
+
+ // As running all previous ones would set them as main core, we need to reset it
+ SSlobotomy_corp.core_suppression = src
+
+/datum/suppression/combination/keter_day47/End(silent = FALSE)
+ var/blurb_text = "You will overcome this despair if you just wake up and smell the roses. You still have a chance."
+ INVOKE_ASYNC(GLOBAL_PROC, .proc/show_global_blurb, 10 SECONDS, blurb_text, 1 SECONDS, "white", "black", "left", "CENTER-6,BOTTOM+2")
+ return ..()
+
+// Day 48 - Central Command, Welfare, Disciplinary
+/datum/suppression/combination/keter_day48
+ name = DAY48_CORE_SUPPRESSION
+ desc = "Effects of core suppressions of Central Command, Welfare and Disciplinary departments \
+ will activate for the duration of this test.
\
+ To complete the challenge - you must defeat the Midnight of White - The Claw."
+ run_text = "Effects of Control, Information, Safety and Training core suppressions are now in effect. Ordeals of White have been introduced in the subroutines."
+ required_cores = list(
+ CONTROL_CORE_SUPPRESSION,
+ INFORMATION_CORE_SUPPRESSION,
+ SAFETY_CORE_SUPPRESSION,
+ TRAINING_CORE_SUPPRESSION,
+ COMMAND_CORE_SUPPRESSION,
+ WELFARE_CORE_SUPPRESSION,
+ DISCIPLINARY_CORE_SUPPRESSION,
+ DAY46_CORE_SUPPRESSION,
+ DAY47_CORE_SUPPRESSION,
+ )
+
+/datum/suppression/combination/keter_day48/Run(run_white = TRUE, silent = FALSE)
+ . = ..()
+ // Ominous blurbs
+ var/list/blurb_list = list(
+ "Do you remember when we still knew the warmth of the sun?",
+ "We have become too cold for such a thing.",
+ "Were we really only pretending when we were reluctant about countless deaths?",
+ "We were wrong from the start. What is left for us is atonement",
+ )
+ for(var/i = 1 to length(blurb_list))
+ var/blurb_text = blurb_list[i]
+ addtimer(CALLBACK(GLOBAL_PROC, .proc/show_global_blurb, 10 SECONDS, blurb_text, 1 SECONDS, "white", "black", "left", "CENTER-6,BOTTOM+2"), i * 11 SECONDS)
+ // Create our cores
+ // Less scuffed words in announcements
+ var/datum/suppression/command/C = new
+ C.meltdown_count_increase = 4
+ C.meltdown_time_multiplier = 0.5
+ C.meltdown_time_reduction = 0.1
+ running_cores += C
+ // More stat reductions
+ var/datum/suppression/welfare/W = new
+ running_cores += W
+ // TODO: Red mist spawn
+ // --------------------
+ // And then start them all
+ for(var/datum/suppression/S in running_cores)
+ S.Run(FALSE, TRUE)
+
+ // As running all previous ones would set them as main core, we need to reset it
+ SSlobotomy_corp.core_suppression = src
+
+/datum/suppression/combination/keter_day48/End(silent = FALSE)
+ var/blurb_text = "You will reach tomorrow. You can overcome this regret and atonement."
+ INVOKE_ASYNC(GLOBAL_PROC, .proc/show_global_blurb, 10 SECONDS, blurb_text, 1 SECONDS, "white", "black", "left", "CENTER-6,BOTTOM+2")
+ return ..()
+
+// Day 49 - Records and Extraction
+/datum/suppression/combination/keter_day49
+ name = DAY49_CORE_SUPPRESSION
+ desc = "Effects of Records core suppression will be present throughout the entire challenge.
\
+ The Arbiter will make their appearence after completing the Noon of White.
\
+ To complete the challenge - you must defeat the Midnight of White - The Claw."
+ run_text = "The effects of Records core suppression are now in effect. The Arbiter will return after completing the Noon of White. Ordeals of White have been introduced in the subroutines."
+ required_cores = list(
+ CONTROL_CORE_SUPPRESSION,
+ INFORMATION_CORE_SUPPRESSION,
+ SAFETY_CORE_SUPPRESSION,
+ TRAINING_CORE_SUPPRESSION,
+ COMMAND_CORE_SUPPRESSION,
+ WELFARE_CORE_SUPPRESSION,
+ DISCIPLINARY_CORE_SUPPRESSION,
+ RECORDS_CORE_SUPPRESSION,
+ EXTRACTION_CORE_SUPPRESSION,
+ DAY46_CORE_SUPPRESSION,
+ DAY47_CORE_SUPPRESSION,
+ DAY48_CORE_SUPPRESSION,
+ )
+
+/datum/suppression/combination/keter_day49/Run(run_white = TRUE, silent = FALSE)
+ . = ..()
+ RegisterSignal(SSdcs, COMSIG_GLOB_ORDEAL_END, .proc/OnOrdealEnd)
+ // Ominous blurbs
+ var/list/blurb_list = list(
+ "You won't believe how long I have been painstakingly waiting for you.",
+ "The wait was getting so, so boring.",
+ "Nothing is as boring as watching a predetermined fall.",
+ "Yes, we could see the truth.",
+ "The Abnormalities are no longer abnormal; They are no mere fantasies anymore.",
+ "They are our truer forms.",
+ )
+ for(var/i = 1 to length(blurb_list))
+ var/blurb_text = blurb_list[i]
+ addtimer(CALLBACK(GLOBAL_PROC, .proc/show_global_blurb, 10 SECONDS, blurb_text, 1 SECONDS, "white", "black", "left", "CENTER-6,BOTTOM+2"), i * 11 SECONDS)
+ // More fucked up chaos
+ var/datum/suppression/records/R = new
+ R.teleport_interval = 30 SECONDS
+ R.teleport_min_distance = 1
+ R.teleport_max_distance = 3
+ R.teleport_min_mob_count = 0.5
+ R.teleport_max_mob_count = 0.8
+ running_cores += R
+ R.Run(FALSE, TRUE)
+
+ SSlobotomy_corp.core_suppression = src
+
+/datum/suppression/combination/keter_day49/End(silent = FALSE)
+ UnregisterSignal(SSdcs, COMSIG_GLOB_ORDEAL_END)
+ var/blurb_text = "So you refuse to join me, and instead choose to move toward the unpredictable future?"
+ INVOKE_ASYNC(GLOBAL_PROC, .proc/show_global_blurb, 10 SECONDS, blurb_text, 1 SECONDS, "white", "black", "left", "CENTER-6,BOTTOM+2")
+ return ..()
+
+/datum/suppression/combination/keter_day49/proc/OnOrdealEnd(datum/source, datum/ordeal/O)
+ SIGNAL_HANDLER
+ if(!istype(O, /datum/ordeal/fixers/white_noon))
+ return
+ // Spawn the arbiter
+ addtimer(CALLBACK(src, .proc/SpawnArbiter), 10 SECONDS)
+
+/datum/suppression/combination/keter_day49/proc/SpawnArbiter()
+ // Make records less AIDS
+ var/datum/suppression/records/R = GetCoreSuppression(/datum/suppression/records)
+ R.teleport_interval = 20 SECONDS
+ var/turf/T = pick(GLOB.department_centers)
+ sound_to_playing_players_on_level('sound/magic/arbiter/repulse.ogg', 100, zlevel = T.z)
+ var/blurb_text = pick(
+ "You cannot escape the Head.",
+ "If you cannot defeat me, you shall be crushed by the Head and its ruthless Claws yet again.",
+ "What do you think you will accomplish on your own, even after breaking out of this prison?",
+ )
+ INVOKE_ASYNC(GLOBAL_PROC, .proc/show_global_blurb, 5 SECONDS, blurb_text, 1 SECONDS, "black", "yellow", "left", "CENTER-6,BOTTOM+2")
+ var/mob/living/simple_animal/hostile/megafauna/arbiter/A = new(T)
+ // A bit nerfed, so you don't suffer like you are in hell, okay?
+ A.maxHealth = round(A.maxHealth * 0.6)
+ A.health = A.maxHealth
+ // While nerfed in health, its attacks are more rapid
+ A.spikes_cooldown_time = round(A.spikes_cooldown_time * 0.5)
+ A.fairy_cooldown_time = round(A.fairy_cooldown_time * 0.5)
+ A.key_cooldown_time = round(A.key_cooldown_time * 0.5)
+
+// Day 50 - Tree of Light
+/datum/suppression/combination/keter_day50
+ name = DAY50_CORE_SUPPRESSION
+ desc = "The facility will experience unusual effects on it, with unknown subset of ordeals present.
\
+ To complete the challenge - you must defeat the Eclipse of White."
+ run_text = "The final day on your job has come."
+ required_cores = list(
+ CONTROL_CORE_SUPPRESSION,
+ INFORMATION_CORE_SUPPRESSION,
+ SAFETY_CORE_SUPPRESSION,
+ TRAINING_CORE_SUPPRESSION,
+ COMMAND_CORE_SUPPRESSION,
+ WELFARE_CORE_SUPPRESSION,
+ DISCIPLINARY_CORE_SUPPRESSION,
+ RECORDS_CORE_SUPPRESSION,
+ EXTRACTION_CORE_SUPPRESSION,
+ DAY46_CORE_SUPPRESSION,
+ DAY47_CORE_SUPPRESSION,
+ DAY48_CORE_SUPPRESSION,
+ DAY49_CORE_SUPPRESSION,
+ )
+
+/datum/suppression/combination/keter_day50/Run(run_white = TRUE, silent = FALSE)
+ . = ..()
+ // Ominous blurbs
+ var/list/blurb_list = list(
+ "We finally meet here today.",
+ "You must have realized that as well, seeing as you have made it to this point without hesitation.",
+ "I had known... For a very long time...",
+ "That we all lost our hearts.",
+ "As you can see, we’ve become just like the other Wings, committing atrocities just like them.",
+ "The employees here have repeated hundreds upon thousands of deaths...",
+ "This sin shall never be forgiven.",
+ "Nonetheless... We must finish this.",
+ "This will be our final day at work.",
+ )
+ for(var/i = 1 to length(blurb_list))
+ var/blurb_text = blurb_list[i]
+ addtimer(CALLBACK(GLOBAL_PROC, .proc/show_global_blurb, 10 SECONDS, blurb_text, 1 SECONDS, "white", "black", "left", "CENTER-6,BOTTOM+2"), i * 11 SECONDS)
diff --git a/code/modules/suppressions/records.dm b/code/modules/suppressions/records.dm
index 6f6eb57a1ad5..87439d7af7e8 100644
--- a/code/modules/suppressions/records.dm
+++ b/code/modules/suppressions/records.dm
@@ -1,17 +1,17 @@
/datum/suppression/records
- name = "Records Core Suppression"
+ name = RECORDS_CORE_SUPPRESSION
desc = "Each meltdown, a random ever-increasing amount of abnormalities within your containment will swap places. \
At even intervals, a random amount of all living creatures in the facility will be teleported a short distance, \
with abnormalities and ordeals seemingly teleporting in the direction of their opponent."
reward_text = "The manager console will be equipped with function to swap the positions of abnormalities. \
Attribute limits of all positions will be raised by 70."
run_text = "The core suppression of Records department has begun. \n\
- Meltdown immunities are forfeit and qliphoth meltdowns will have lesser timer. \n\
- Failed meltdowns will trigger a meltdown in another cell."
+ The abnormalities will switch positions every meltdown. \n\
+ All living creatures will teleport slightly at even intervals."
/// How many of abnormality cells will swap places on meltdown, by percent of current count
- var/abno_swap_percentage = 0.4
+ var/abno_swap_percentage = 1
/// How often teleportations happen
- var/teleport_interval = 30 SECONDS
+ var/teleport_interval = 35 SECONDS
/// Minimum teleport distance for mobs
var/teleport_min_distance = 3
/// How far can mobs teleport at maximum
@@ -21,13 +21,13 @@
/// Maximum percent of valid mobs to be teleported
var/teleport_max_mob_count = 0.2
-/datum/suppression/records/Run(run_white = FALSE)
+/datum/suppression/records/Run(run_white = FALSE, silent = FALSE)
. = ..()
RegisterSignal(SSdcs, COMSIG_GLOB_MELTDOWN_START, .proc/OnQlipMeltdown)
RegisterSignal(SSdcs, COMSIG_GLOB_ABNORMALITY_SWAP, .proc/OnAbnoSwap)
addtimer(CALLBACK(src, .proc/TeleportLivingMobs), teleport_interval)
-/datum/suppression/records/End()
+/datum/suppression/records/End(silent = FALSE)
UnregisterSignal(SSdcs, COMSIG_GLOB_MELTDOWN_START)
UnregisterSignal(SSdcs, COMSIG_GLOB_ABNORMALITY_SWAP)
// EVERYONE GETS INCREASED STAT LIMIT, LET'S FUCKING GOOOOOO
@@ -58,6 +58,9 @@
if(istype(A1.current) && !A1.current.IsContained())
i -= 1
continue
+ if(A1.working)
+ i -= 1
+ continue
if(!LAZYLEN(abnos))
break
var/datum/abnormality/A2 = pick(abnos)
@@ -65,15 +68,20 @@
if(istype(A2.current) && !A2.current.IsContained())
i -= 1
continue
+ if(A2.working)
+ i -= 1
+ continue
// SWAP!
A1.SwapPlaceWith(A2)
// Upgrade the difficulty!
if(ordeal)
abno_swap_percentage = min(1, abno_swap_percentage + 0.2)
- teleport_interval = max(5 SECONDS, teleport_interval - 12 SECONDS)
+ teleport_interval = max(5 SECONDS, teleport_interval - 10 SECONDS)
teleport_min_mob_count = max(0.8, teleport_min_mob_count + 0.15)
teleport_max_mob_count = max(1, teleport_max_mob_count + 0.2)
+ teleport_min_distance = min(10, teleport_min_distance + 1)
+ teleport_max_distance = min(15, teleport_max_distance + 2)
// Show after-image of swapped abnos
/datum/suppression/records/proc/OnAbnoSwap(datum/source, datum/abnormality/A1, datum/abnormality/A2)
@@ -114,10 +122,13 @@
if(!LAZYLEN(valid_mobs))
break
var/mob/living/L = pick(valid_mobs)
- TryToTeleportMob(L)
+ addtimer(CALLBACK(src, .proc/TryToTeleportMob, L), rand(0, 6))
+ valid_mobs -= L
addtimer(CALLBACK(src, .proc/TeleportLivingMobs), teleport_interval)
/datum/suppression/records/proc/TryToTeleportMob(mob/living/L)
+ if(QDELETED(L))
+ return
var/turf/open/T = null
var/list/turf_list = list()
var/mob/living/simple_animal/hostile/HA = L
@@ -127,14 +138,19 @@
else
turf_list = spiral_range_turfs(teleport_max_distance, get_turf(L), teleport_min_distance)
+ for(var/turf/TT in turf_list)
+ if(TT.density)
+ turf_list -= TT
+
for(var/i = 1 to 5)
if(!LAZYLEN(turf_list))
break
T = pick(turf_list)
turf_list -= T
// Found good target turf
- if(LAZYLEN(get_path_to(L, T, /turf/proc/Distance_cardinal, 0, 20)))
+ if(LAZYLEN(get_path_to(L, T, /turf/proc/Distance_cardinal, 0, teleport_max_distance * 2)))
break
+ T = null
// Didn't find anything, very sad
if(!istype(T))
return FALSE
diff --git a/code/modules/suppressions/safety.dm b/code/modules/suppressions/safety.dm
index 0cd1ad0eea8a..c2fced479ba0 100644
--- a/code/modules/suppressions/safety.dm
+++ b/code/modules/suppressions/safety.dm
@@ -1,12 +1,12 @@
/datum/suppression/safety
- name = "Safety Core Suppression"
+ name = SAFETY_CORE_SUPPRESSION
desc = "Regenerators will stop operating normally, all personnel will be healed after each meltdown instead.\n\
Sleepers and EMAIS will be non-functional.\n\
Medi-pens will have a chance to malfunction and require a delay on each activation."
reward_text = "All regenerators will receive a permanent +3 boost to healing power."
run_text = "The core suppression of Safety department has begun. The regenerators and sleepers will stop operating normally. All personnel will be automatically healed after each meltdown instead."
-/datum/suppression/safety/Run(run_white = FALSE)
+/datum/suppression/safety/Run(run_white = FALSE, silent = FALSE)
. = ..()
RegisterSignal(SSdcs, COMSIG_GLOB_MELTDOWN_START, .proc/OnMeltdown)
for(var/obj/machinery/regenerator/R in GLOB.regenerators)
@@ -16,7 +16,7 @@
for(var/obj/machinery/sleeper/S in GLOB.sleepers)
S.set_machine_stat(S.machine_stat | BROKEN)
-/datum/suppression/safety/End()
+/datum/suppression/safety/End(silent = FALSE)
UnregisterSignal(SSdcs, COMSIG_GLOB_MELTDOWN_START)
for(var/obj/machinery/regenerator/R in GLOB.regenerators) // All regenerators gain permanent buff
R.reset_timer = 0
diff --git a/code/modules/suppressions/training.dm b/code/modules/suppressions/training.dm
index 9a227be7b10a..02086704ebfe 100644
--- a/code/modules/suppressions/training.dm
+++ b/code/modules/suppressions/training.dm
@@ -1,31 +1,33 @@
// Right now the only core suppression with a proper reward, which is higher spawning stats.
/datum/suppression/training
- name = "Training Core Suppression"
- desc = "All employees will be weakened by an amount equal to a -30 debuff on each attribute for the duration of suppression."
+ name = TRAINING_CORE_SUPPRESSION
+ desc = "All employees will be affected by a debuff to each attribute for the duration of suppression, which starts at -10 and increases in potency every ordeal."
reward_text = "Employees that survived through the suppression will be awarded with 20 increase and +5 buff to all attributes.\n\
All Agents that will join post-suppression will start with higher attributes."
run_text = "The core suppression of Training department has begun. All personnel will be suffering from symptoms of work fatigue."
- /// Mob ref = Current ttribute debuff
+ /// Mob ref = Current attribute debuff
var/list/affected_mobs = list()
+ // Starting attribute debuff
+ var/attribute_debuff_count_starting = -10
// How much your attributes are debuffed after each ordeal
var/attribute_debuff_count = -10
// Used for new arrivals
var/current_debuff_amount
-/datum/suppression/training/Run(run_white = FALSE)
+/datum/suppression/training/Run(run_white = FALSE, silent = FALSE)
. = ..()
RegisterSignal(SSdcs, COMSIG_GLOB_CREWMEMBER_JOINED, .proc/OnJoin)
RegisterSignal(SSdcs, COMSIG_GLOB_MELTDOWN_START, .proc/OnMeltdown)
for(var/mob/living/carbon/human/H in GLOB.human_list)
if(!H.ckey)
continue
- H.adjust_all_attribute_buffs(attribute_debuff_count)
+ H.adjust_all_attribute_buffs(attribute_debuff_count_starting)
to_chat(H, "You feel weaker...")
affected_mobs[H] = attribute_debuff_count
RegisterSignal(H, COMSIG_PARENT_QDELETING, .proc/RemoveFromAffectedMobs)
- current_debuff_amount = attribute_debuff_count
+ current_debuff_amount = attribute_debuff_count_starting
-/datum/suppression/training/End()
+/datum/suppression/training/End(silent = FALSE)
UnregisterSignal(SSdcs, COMSIG_GLOB_CREWMEMBER_JOINED)
for(var/mob/living/carbon/human/H in affected_mobs)
H.adjust_all_attribute_buffs(-affected_mobs[H] + 5)
diff --git a/code/modules/suppressions/welfare.dm b/code/modules/suppressions/welfare.dm
index 8476fe02ece5..185a1ff6d8ad 100644
--- a/code/modules/suppressions/welfare.dm
+++ b/code/modules/suppressions/welfare.dm
@@ -3,7 +3,7 @@
// Right now the only core suppression with a proper reward, which is higher spawning stats.
/datum/suppression/welfare
- name = "Welfare Core Suppression"
+ name = WELFARE_CORE_SUPPRESSION
desc = "All employees will suffer from decreased resistance to randomly chosen damage types, which change on each meltdown."
reward_text = "All personnel will be able to avoid death/insanity by instantly healing to certain percentage \
of either health or sanity each time they reach that point. \
@@ -22,7 +22,7 @@
PALE_DAMAGE = 1,
)
-/datum/suppression/welfare/Run(run_white = FALSE)
+/datum/suppression/welfare/Run(run_white = FALSE, silent = FALSE)
. = ..()
RegisterSignal(SSdcs, COMSIG_GLOB_CREWMEMBER_JOINED, .proc/OnJoin)
RegisterSignal(SSdcs, COMSIG_GLOB_MELTDOWN_START, .proc/OnMeltdown)
@@ -34,7 +34,7 @@
ApplyEffect(H)
OnMeltdown()
-/datum/suppression/welfare/End()
+/datum/suppression/welfare/End(silent = FALSE)
UnregisterSignal(SSdcs, COMSIG_GLOB_CREWMEMBER_JOINED)
UnregisterSignal(SSdcs, COMSIG_GLOB_MELTDOWN_START)
for(var/datum/status_effect/welfare_damage_resist/S in affected_statuses)
diff --git a/code/modules/suppressions/white_ordeals.dm b/code/modules/suppressions/white_ordeals.dm
deleted file mode 100644
index e2d782339d5f..000000000000
--- a/code/modules/suppressions/white_ordeals.dm
+++ /dev/null
@@ -1,13 +0,0 @@
-// This isn't a real suppression, it exists only to trigger white ordeals.
-/datum/suppression/white_ordeals
- name = "Initial Keter Manifestation" // Give me better name, I'll wait
- desc = "The facility will introduce White Ordeals with 1 meltdown in-between them.
\
- After clearing Dawn, Noon and Dusk the agents will have to face off against The Claw."
- goal_text = "Defeat the Midnight of White - The Claw."
- run_text = "The Ordeals of White have been introduced into the facility's subroutines. There will be one meltdown in-between each ordeal."
- annonce_sound = 'sound/effects/combat_suppression_start.ogg'
- end_sound = 'sound/effects/combat_suppression_end.ogg'
- after_midnight = TRUE
-
-/datum/suppression/white_ordeals/Run(run_white = TRUE)
- return ..()
diff --git a/lobotomy-corp13.dme b/lobotomy-corp13.dme
index 7ba9e2c22fb2..e7e4ac0750aa 100644
--- a/lobotomy-corp13.dme
+++ b/lobotomy-corp13.dme
@@ -57,6 +57,7 @@
#include "code\__DEFINES\events.dm"
#include "code\__DEFINES\exosuit_fab.dm"
#include "code\__DEFINES\exports.dm"
+#include "code\__DEFINES\facility_upgrades.dm"
#include "code\__DEFINES\fantasy_affixes.dm"
#include "code\__DEFINES\flags.dm"
#include "code\__DEFINES\food.dm"
@@ -75,6 +76,7 @@
#include "code\__DEFINES\layers.dm"
#include "code\__DEFINES\lighting.dm"
#include "code\__DEFINES\living.dm"
+#include "code\__DEFINES\lobotomy_corp.dm"
#include "code\__DEFINES\logging.dm"
#include "code\__DEFINES\machines.dm"
#include "code\__DEFINES\magic.dm"
@@ -170,6 +172,7 @@
#include "code\__HELPERS\icons.dm"
#include "code\__HELPERS\jatum.dm"
#include "code\__HELPERS\level_traits.dm"
+#include "code\__HELPERS\lobotomy_corp.dm"
#include "code\__HELPERS\matrices.dm"
#include "code\__HELPERS\mobs.dm"
#include "code\__HELPERS\mouse_control.dm"
@@ -386,6 +389,7 @@
#include "code\datums\ductnet.dm"
#include "code\datums\emotes.dm"
#include "code\datums\ert.dm"
+#include "code\datums\facility_upgrade.dm"
#include "code\datums\forced_movement.dm"
#include "code\datums\hailer_phrase.dm"
#include "code\datums\holocall.dm"
@@ -931,7 +935,7 @@
#include "code\game\machinery\camera\tracking.dm"
#include "code\game\machinery\computer\_computer.dm"
#include "code\game\machinery\computer\abnormality_archive.dm"
-#include "code\game\machinery\computer\abnormality_auxilary.dm"
+#include "code\game\machinery\computer\abnormality_auxiliary.dm"
#include "code\game\machinery\computer\abnormality_ego.dm"
#include "code\game\machinery\computer\abnormality_logs.dm"
#include "code\game\machinery\computer\abnormality_queue.dm"
@@ -3634,11 +3638,11 @@
#include "code\modules\suppressions\control.dm"
#include "code\modules\suppressions\extraction.dm"
#include "code\modules\suppressions\information.dm"
+#include "code\modules\suppressions\keter.dm"
#include "code\modules\suppressions\records.dm"
#include "code\modules\suppressions\safety.dm"
#include "code\modules\suppressions\training.dm"
#include "code\modules\suppressions\welfare.dm"
-#include "code\modules\suppressions\white_ordeals.dm"
#include "code\modules\surgery\amputation.dm"
#include "code\modules\surgery\blood_filter.dm"
#include "code\modules\surgery\bone_mending.dm"