diff --git a/code/__DEFINES/ARES.dm b/code/__DEFINES/ARES.dm
index 0e3cc4a8ff6e..b48bf2e28c2f 100644
--- a/code/__DEFINES/ARES.dm
+++ b/code/__DEFINES/ARES.dm
@@ -28,6 +28,7 @@
#define ARES_RECORD_MAINTENANCE "Maintenance Ticket"
#define ARES_RECORD_ACCESS "Access Ticket"
#define ARES_RECORD_FLIGHT "Flight Record"
+#define ARES_RECORD_TECH "Tech Control Record"
/// Not by ARES logged through marine_announcement()
#define ARES_LOG_NONE 0
diff --git a/code/controllers/subsystem/objectives_controller.dm b/code/controllers/subsystem/objectives_controller.dm
index a858dff07475..38accda46004 100644
--- a/code/controllers/subsystem/objectives_controller.dm
+++ b/code/controllers/subsystem/objectives_controller.dm
@@ -96,6 +96,7 @@ SUBSYSTEM_DEF(objectives)
ai_silent_announcement(message, ":v", TRUE)
ai_silent_announcement(message, ":t", TRUE)
+ log_ares_tech(MAIN_AI_SYSTEM, FALSE, "TECH REPORT", "[round(tree.points, 0.1)] points available.", 0)
tree.total_points_last_sitrep = tree.total_points
next_sitrep = world.time + SITREP_INTERVAL
diff --git a/code/game/machinery/ARES/ARES_interface.dm b/code/game/machinery/ARES/ARES_interface.dm
index dd99240b2550..d6f58f371715 100644
--- a/code/game/machinery/ARES/ARES_interface.dm
+++ b/code/game/machinery/ARES/ARES_interface.dm
@@ -183,6 +183,17 @@
logged_orders += list(current_order)
data["records_requisition"] = logged_orders
+ var/list/logged_techs = list()
+ for(var/datum/ares_record/tech/tech_unlock as anything in datacore.records_tech)
+ var/list/current_tech = list()
+ current_tech["time"] = tech_unlock.time
+ current_tech["details"] = tech_unlock.details
+ current_tech["user"] = tech_unlock.user
+ current_tech["tier_changer"] = tech_unlock.is_tier
+ current_tech["ref"] = "\ref[tech_unlock]"
+ logged_techs += list(current_tech)
+ data["records_tech"] = logged_techs
+
var/list/logged_convos = list()
var/list/active_convo = list()
var/active_ref
@@ -317,6 +328,9 @@
if("page_deleted_1to1")
last_menu = current_menu
current_menu = "deleted_talks"
+ if("page_tech")
+ last_menu = current_menu
+ current_menu = "tech_log"
// -- Delete Button -- //
if("delete_record")
@@ -345,6 +359,10 @@
new_title = "[record.title] at [record.time]"
new_details = "[record.details] Launched by [record.user]."
datacore.records_bombardment -= record
+ if(ARES_RECORD_TECH)
+ new_title = "[record.title] at [record.time]"
+ new_details = record.details
+ datacore.records_tech -= record
new_delete.details = new_details
new_delete.user = last_login
diff --git a/code/game/machinery/ARES/ARES_interface_admin.dm b/code/game/machinery/ARES/ARES_interface_admin.dm
index e388c0eb453d..cdc385589c37 100644
--- a/code/game/machinery/ARES/ARES_interface_admin.dm
+++ b/code/game/machinery/ARES/ARES_interface_admin.dm
@@ -307,6 +307,9 @@
if("page_deleted_1to1")
admin_interface.last_menu = admin_interface.current_menu
admin_interface.current_menu = "deleted_talks"
+ if("page_tech")
+ admin_interface.last_menu = admin_interface.current_menu
+ admin_interface.current_menu = "tech_log"
if("page_access_management")
admin_interface.last_menu = admin_interface.current_menu
admin_interface.current_menu = "access_management"
diff --git a/code/game/machinery/ARES/ARES_procs.dm b/code/game/machinery/ARES/ARES_procs.dm
index 90616add6d25..1212d1509a01 100644
--- a/code/game/machinery/ARES/ARES_procs.dm
+++ b/code/game/machinery/ARES/ARES_procs.dm
@@ -80,6 +80,8 @@ GLOBAL_LIST_INIT(maintenance_categories, list(
var/list/records_security = list()
/// Holds all (/datum/ares_record/flight)s
var/list/records_flight = list()
+ /// Holds all (/datum/ares_record/tech)s
+ var/list/records_tech = list()
/// Is nuke request usable or not?
var/nuke_available = TRUE
@@ -177,6 +179,16 @@ GLOBAL_LIST_INIT(maintenance_categories, list(
return FALSE
var/datum/ares_datacore/datacore = GLOB.ares_datacore
datacore.records_flight.Add(new /datum/ares_record/flight(details, user_name))
+
+/proc/log_ares_tech(user_name, tier_tech = FALSE, title, details, point_cost, current_points)
+ if(!ares_can_log())
+ return FALSE
+ var/new_details = "[title] - [details]"
+ if(point_cost)
+ new_details += " - Used [point_cost] INT of [current_points]."
+ var/datum/ares_datacore/datacore = GLOB.ares_datacore
+ datacore.records_tech.Add(new /datum/ares_record/tech(title, new_details, user_name, tier_tech))
+
// ------ End ARES Logging Procs ------ //
// ------ ARES Interface Procs ------ //
diff --git a/code/game/machinery/ARES/ARES_records.dm b/code/game/machinery/ARES/ARES_records.dm
index e8dc11fa3995..5bfe50dce068 100644
--- a/code/game/machinery/ARES/ARES_records.dm
+++ b/code/game/machinery/ARES/ARES_records.dm
@@ -58,6 +58,18 @@
src.details = details
src.user = user
+/datum/ares_record/tech
+ record_name = ARES_RECORD_TECH
+ /// If this tech unlock changed the tier.
+ var/is_tier = FALSE
+
+/datum/ares_record/tech/New(title, details, user, tier_tech)
+ time = worldtime2text()
+ src.title = title
+ src.details = details
+ src.user = user
+ is_tier = tier_tech
+
/datum/ares_record/deletion
record_name = ARES_RECORD_DELETED
diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm
index 103e3f709afe..a1d7f00cf94a 100644
--- a/code/game/machinery/camera/presets.dm
+++ b/code/game/machinery/camera/presets.dm
@@ -97,7 +97,7 @@
/obj/structure/machinery/camera/autoname/almayer/containment/ares
name = "ares core camera"
- network = list(CAMERA_NET_ALMAYER, CAMERA_NET_ARES)
+ network = list(CAMERA_NET_ARES)
//used by the landing camera dropship equipment. Do not place them right under where the dropship lands.
//Should place them near each corner of your LZs.
diff --git a/code/modules/cm_tech/tech.dm b/code/modules/cm_tech/tech.dm
index dea505f3237a..1750f7e7dbbf 100644
--- a/code/modules/cm_tech/tech.dm
+++ b/code/modules/cm_tech/tech.dm
@@ -21,9 +21,11 @@
var/background_icon = "background"
var/background_icon_locked = "marine"
- var/announce_name
+ var/announce_name = "ALMAYER SPECIAL ASSETS AUTHORIZED"
var/announce_message
+ var/is_tier_changer = FALSE
+
/datum/tech/proc/can_unlock(mob/M)
SHOULD_CALL_PARENT(TRUE)
@@ -58,6 +60,7 @@
return TRUE
+
/** Called when a tech is unlocked. Usually, benefits can be applied here
* however, the purchase can still be cancelled by returning FALSE
*
@@ -69,11 +72,17 @@
unlocked = TRUE
to_chat(user, SPAN_HELPFUL("You have purchased the '[name]' tech node."))
log_admin("[key_name_admin(user)] has bought '[name]' via tech points.")
+ if(!is_tier_changer)
+ var/log_details = announce_message
+ if(!log_details)
+ log_details = name
+ var/current_points = holder.points
+ log_ares_tech(user.real_name, is_tier_changer, announce_name, log_details, required_points, current_points)
holder.spend_points(required_points)
update_icon(node)
if(!(tech_flags & TECH_FLAG_NO_ANNOUNCE) && announce_message && announce_name)
- marine_announcement(announce_message, announce_name, 'sound/misc/notice2.ogg')
+ marine_announcement(announce_message, announce_name, 'sound/misc/notice2.ogg', logging = ARES_LOG_NONE)
return TRUE
diff --git a/code/modules/cm_tech/techs/abstract/transitory.dm b/code/modules/cm_tech/techs/abstract/transitory.dm
index 7798b6053d0e..1737b6b21ee6 100644
--- a/code/modules/cm_tech/techs/abstract/transitory.dm
+++ b/code/modules/cm_tech/techs/abstract/transitory.dm
@@ -7,6 +7,7 @@
var/datum/tier/next
var/techs_to_unlock = 0
+ is_tier_changer = TRUE
/datum/tech/transitory/check_tier_level(mob/M)
if(before && before != holder.tier.type)
@@ -22,7 +23,7 @@
return TRUE
-/datum/tech/transitory/on_unlock()
+/datum/tech/transitory/on_unlock(mob/user)
. = ..()
if(!next)
return
@@ -31,6 +32,10 @@
if(next_tier)
holder.tier = next_tier
holder.on_tier_change(previous_tier)
+ if(flags & TREE_FLAG_MARINE)
+ /// Due to calling parent, points will have already been spent by now.
+ var/current_points = holder.points + required_points
+ log_ares_tech(user.real_name, is_tier_changer, "ALMAYER DEFCON LEVEL INCREASED", "THREAT ASSESSMENT LEVEL INCREASED TO LEVEL [next_tier.tier].\n\nLEVEL [next_tier.tier] assets have been authorised to handle the situation.", required_points, current_points)
/datum/tech/transitory/get_tier_overlay()
if(!next)
diff --git a/code/modules/cm_tech/techs/marine/tier1/points.dm b/code/modules/cm_tech/techs/marine/tier1/points.dm
index d6bb5bace6fc..7768d8da2ab7 100644
--- a/code/modules/cm_tech/techs/marine/tier1/points.dm
+++ b/code/modules/cm_tech/techs/marine/tier1/points.dm
@@ -31,7 +31,6 @@
icon_state = "budget_ds"
desc = "Distributes resources to the dropship fabricator."
- announce_name = "ALMAYER SPECIAL ASSETS AUTHORIZED"
announce_message = "Additional dropship part fabricator points have been authorised for this operation."
required_points = 12
diff --git a/code/modules/cm_tech/techs/marine/tier2/orbital_ammo.dm b/code/modules/cm_tech/techs/marine/tier2/orbital_ammo.dm
index 303ea6121734..51675ccd27f2 100644
--- a/code/modules/cm_tech/techs/marine/tier2/orbital_ammo.dm
+++ b/code/modules/cm_tech/techs/marine/tier2/orbital_ammo.dm
@@ -7,8 +7,6 @@
tier = /datum/tier/two
- announce_name = "ALMAYER SPECIAL ASSETS AUTHORIZED"
-
var/type_to_give
/datum/tech/repeatable/ob/on_unlock()
diff --git a/code/modules/cm_tech/techs/marine/tier3/cryo_spec.dm b/code/modules/cm_tech/techs/marine/tier3/cryo_spec.dm
index acee904af305..06770b1d6afe 100644
--- a/code/modules/cm_tech/techs/marine/tier3/cryo_spec.dm
+++ b/code/modules/cm_tech/techs/marine/tier3/cryo_spec.dm
@@ -3,7 +3,6 @@
desc = "Wakes up an additional specialist to fight against any threats."
icon_state = "overshield"
- announce_name = "ALMAYER SPECIAL ASSETS AUTHORIZED"
announce_message = "An additional specialist is being taken out of cryo."
required_points = 8
diff --git a/code/modules/cm_tech/techs/marine/tier3/cryorine.dm b/code/modules/cm_tech/techs/marine/tier3/cryorine.dm
index 404fbd07c2ae..19200698db02 100644
--- a/code/modules/cm_tech/techs/marine/tier3/cryorine.dm
+++ b/code/modules/cm_tech/techs/marine/tier3/cryorine.dm
@@ -4,7 +4,6 @@
desc = "Wakes up additional troops to fight against any threats."
icon_state = "cryotroops"
- announce_name = "ALMAYER SPECIAL ASSETS AUTHORIZED"
announce_message = "Additional troops are being taken out of cryo."
required_points = 6
diff --git a/code/modules/cm_tech/trees/marine.dm b/code/modules/cm_tech/trees/marine.dm
index aae057b90198..046712f9656b 100644
--- a/code/modules/cm_tech/trees/marine.dm
+++ b/code/modules/cm_tech/trees/marine.dm
@@ -174,4 +174,4 @@ GLOBAL_LIST_EMPTY(tech_controls_marine)
return //No need to announce tier updates for tier 1
var/name = "ALMAYER DEFCON LEVEL INCREASED"
var/input = "THREAT ASSESSMENT LEVEL INCREASED TO LEVEL [tier.tier].\n\nLEVEL [tier.tier] assets have been authorised to handle the situation."
- marine_announcement(input, name, 'sound/AI/commandreport.ogg')
+ marine_announcement(input, name, 'sound/AI/commandreport.ogg', logging = ARES_LOG_NONE)
diff --git a/maps/map_files/USS_Almayer/USS_Almayer.dmm b/maps/map_files/USS_Almayer/USS_Almayer.dmm
index dec4291668b1..7147e463a773 100644
--- a/maps/map_files/USS_Almayer/USS_Almayer.dmm
+++ b/maps/map_files/USS_Almayer/USS_Almayer.dmm
@@ -3928,10 +3928,10 @@
/turf/open/floor/almayer/aicore/no_build,
/area/almayer/command/airoom)
"avM" = (
-/obj/structure/machinery/computer/cameras/almayer/ares{
+/obj/structure/machinery/computer/cameras/almayer{
dir = 8;
pixel_x = 17;
- pixel_y = 6
+ pixel_y = 8
},
/obj/structure/surface/table/reinforced/almayer_B{
climbable = 0;
@@ -3943,7 +3943,14 @@
pixel_y = 6
},
/obj/item/tool/pen,
-/turf/open/floor/almayer/aicore/no_build,
+/obj/structure/machinery/computer/cameras/almayer/ares{
+ dir = 8;
+ pixel_x = 17;
+ pixel_y = -6
+ },
+/turf/open/floor/almayer/no_build{
+ icon_state = "ai_floors"
+ },
/area/almayer/command/airoom)
"avN" = (
/obj/structure/machinery/telecomms/processor/preset_two,
@@ -4624,7 +4631,13 @@
/obj/item/storage/belt/medical/full,
/obj/structure/machinery/computer/working_joe{
dir = 8;
- pixel_x = 17
+ pixel_x = 17;
+ pixel_y = 8
+ },
+/obj/structure/machinery/computer/cameras/almayer/ares{
+ dir = 8;
+ pixel_x = 17;
+ pixel_y = -6
},
/turf/open/floor/almayer{
icon_state = "plate"
@@ -5971,13 +5984,13 @@
/area/almayer/living/grunt_rnr)
"aDX" = (
/obj/structure/surface/table/almayer,
-/obj/structure/machinery/computer/cameras/containment{
- dir = 4
- },
/obj/structure/sign/safety/terminal{
pixel_x = 8;
pixel_y = 32
},
+/obj/structure/machinery/computer/cameras/almayer/ares{
+ dir = 4
+ },
/turf/open/floor/almayer{
icon_state = "plate"
},
@@ -9207,7 +9220,8 @@
"aWb" = (
/obj/structure/machinery/computer/working_joe{
dir = 4;
- pixel_x = -17
+ pixel_x = -17;
+ pixel_y = 8
},
/obj/structure/machinery/door_control/brbutton{
id = "engie_store";
@@ -9216,6 +9230,11 @@
pixel_y = 26;
req_one_access_txt = "6"
},
+/obj/structure/machinery/computer/cameras/almayer/ares{
+ dir = 4;
+ pixel_x = -17;
+ pixel_y = -6
+ },
/turf/open/floor/almayer{
dir = 1;
icon_state = "orangecorner"
@@ -33301,6 +33320,11 @@
pixel_x = -1;
pixel_y = 3
},
+/obj/item/reagent_container/spray/cleaner{
+ layer = 3.04;
+ pixel_x = 5;
+ pixel_y = 22
+ },
/turf/open/floor/wood/ship,
/area/almayer/living/commandbunks)
"hlH" = (
@@ -37753,13 +37777,14 @@
layer = 3.2;
pixel_y = 4
},
-/obj/structure/machinery/computer/secure_data{
- dir = 4;
- pixel_y = 23
- },
/obj/structure/machinery/light{
dir = 8
},
+/obj/structure/machinery/computer/secure_data{
+ dir = 4;
+ pixel_y = 23;
+ layer = 2.99
+ },
/turf/open/floor/almayer{
dir = 8;
icon_state = "red"
@@ -38468,15 +38493,6 @@
/obj/structure/machinery/light{
dir = 8
},
-/obj/item/clothing/mask/cigarette/pipe{
- layer = 2.8;
- pixel_y = -7
- },
-/obj/item/reagent_container/spray/cleaner{
- layer = 3.04;
- pixel_x = -4;
- pixel_y = 7
- },
/obj/structure/machinery/door_control/brbutton{
id = "Brig Lockdown Shutters";
name = "Brig Lockdown";
@@ -38495,6 +38511,9 @@
pixel_x = 8;
pixel_y = 26
},
+/obj/structure/machinery/computer/cameras/almayer/ares{
+ dir = 4
+ },
/turf/open/floor/wood/ship,
/area/almayer/living/commandbunks)
"jbO" = (
@@ -46010,6 +46029,14 @@
"lFp" = (
/turf/closed/wall/almayer,
/area/almayer/engineering/lower/workshop/hangar)
+"lFq" = (
+/obj/structure/pipes/vents/pump/no_boom{
+ dir = 1
+ },
+/turf/open/floor/almayer/aicore/no_build{
+ icon_state = "ai_plates"
+ },
+/area/almayer/command/airoom)
"lFr" = (
/obj/structure/machinery/firealarm{
dir = 8;
@@ -50484,15 +50511,14 @@
/area/almayer/hallways/upper/starboard)
"nkX" = (
/obj/structure/surface/table/almayer,
-/obj/structure/machinery/computer/cameras/almayer_network{
- dir = 4;
- layer = 2.8;
- pixel_y = 5
- },
/obj/structure/sign/safety/terminal{
pixel_x = 8;
pixel_y = 32
},
+/obj/structure/machinery/computer/cameras/almayer/ares{
+ dir = 4;
+ pixel_y = 5
+ },
/turf/open/floor/almayer{
dir = 9;
icon_state = "red"
@@ -51397,6 +51423,10 @@
pixel_x = -1;
pixel_y = 2
},
+/obj/item/clothing/mask/cigarette/pipe{
+ layer = 2.8;
+ pixel_x = 14
+ },
/turf/open/floor/wood/ship,
/area/almayer/living/commandbunks)
"nCD" = (
@@ -56362,14 +56392,14 @@
},
/area/almayer/living/briefing)
"pmV" = (
-/obj/structure/prop/server_equipment/yutani_server/broken{
- density = 0;
- desc = "A powerful server tower housing various AI functions.";
- name = "server tower";
- pixel_y = 16
- },
/obj/structure/pipes/standard/simple/hidden/supply/no_boom,
-/turf/open/floor/almayer/aicore/no_build,
+/obj/structure/machinery/computer/tech_control{
+ pixel_y = 16;
+ density = 0
+ },
+/turf/open/floor/almayer/no_build{
+ icon_state = "ai_floors"
+ },
/area/almayer/command/airoom)
"pnh" = (
/obj/structure/ladder{
@@ -139811,7 +139841,7 @@ cqm
gTH
qit
ebN
-cxc
+qQS
gwn
pfT
jYR
@@ -140622,8 +140652,8 @@ ebN
ebN
roH
ebN
-ebN
-ebN
+daz
+daz
daz
wnh
wnh
@@ -141434,8 +141464,8 @@ ebN
ebN
gXs
ebN
-ebN
-ebN
+daz
+daz
daz
wnh
wnh
@@ -141636,9 +141666,9 @@ ebN
ebN
gbg
uVv
-yit
+lFq
ebN
-cxc
+qQS
kBy
kBy
gfu
diff --git a/tgui/packages/tgui/interfaces/AresAdmin.js b/tgui/packages/tgui/interfaces/AresAdmin.js
index 4f19cf452b17..539aad868eec 100644
--- a/tgui/packages/tgui/interfaces/AresAdmin.js
+++ b/tgui/packages/tgui/interfaces/AresAdmin.js
@@ -18,6 +18,7 @@ const PAGES = {
'security': () => Security,
'requisitions': () => Requisitions,
'emergency': () => Emergency,
+ 'tech_log': () => TechLogs,
'admin_access_log': () => AdminAccessLogs,
'access_management': () => AccessManagement,
'maintenance_management': () => MaintManagement,
@@ -255,6 +256,18 @@ const MainMenu = (props, context) => {
onClick={() => act('page_requisitions')}
/>
+
+
@@ -1573,6 +1586,120 @@ const Emergency = (props, context) => {
);
};
+const TechLogs = (props, context) => {
+ const { data, act } = useBackend(context);
+ const {
+ logged_in,
+ access_text,
+ last_page,
+ current_menu,
+ records_tech,
+ access_level,
+ } = data;
+
+ return (
+ <>
+
+
+
+
+
+
+ {logged_in}, {access_text}
+
+ Remote Admin: {admin_login}
+
+
+ act('logout')}
+ />
+
+
+
+
+ Tech Control Logs
+ {!!records_tech.length && (
+
+
+ Time
+
+
+ Authenticator
+
+
+ Details
+
+
+ )}
+ {records_tech.map((record, i) => {
+ return (
+
+
+ {record.time}
+
+
+ {record.user}
+
+ {!!record.tier_changer && (
+
+ {record.details}
+
+ )}
+ {!record.tier_changer && (
+
+ {record.details}
+
+ )}
+
+
+ act('delete_record', { record: record.ref })}
+ />
+
+
+ );
+ })}
+
+ >
+ );
+};
+
// -------------------------------------------------------------------- //
// Anything below this line is exclusive to the Admin Remote Interface.
// -------------------------------------------------------------------- //
diff --git a/tgui/packages/tgui/interfaces/AresInterface.jsx b/tgui/packages/tgui/interfaces/AresInterface.jsx
index 79ad85044ec1..4045cba6509c 100644
--- a/tgui/packages/tgui/interfaces/AresInterface.jsx
+++ b/tgui/packages/tgui/interfaces/AresInterface.jsx
@@ -22,6 +22,7 @@ const PAGES = {
'security': () => Security,
'requisitions': () => Requisitions,
'emergency': () => Emergency,
+ 'tech_log': () => TechLogs,
};
export const AresInterface = (props) => {
@@ -256,7 +257,7 @@ const MainMenu = (props) => {
{
onClick={() => act('page_requisitions')}
/>
+
+ act('page_tech')}
+ />
+
)}
{access_level >= 6 && (
@@ -1545,3 +1558,115 @@ const Emergency = (props) => {
>
);
};
+
+const TechLogs = (props, context) => {
+ const { data, act } = useBackend(context);
+ const {
+ logged_in,
+ access_text,
+ last_page,
+ current_menu,
+ records_tech,
+ access_level,
+ } = data;
+
+ return (
+ <>
+
+
+
+ act('go_back')}
+ disabled={last_page === current_menu}
+ />
+ act('home')}
+ />
+
+
+
+ {logged_in}, {access_text}
+
+
+ act('logout')}
+ />
+
+
+
+
+ Tech Control Logs
+ {!!records_tech.length && (
+
+
+ Time
+
+
+ Authenticator
+
+
+ Details
+
+
+ )}
+ {records_tech.map((record, i) => {
+ return (
+
+
+ {record.time}
+
+
+ {record.user}
+
+ {!!record.tier_changer && (
+
+ {record.details}
+
+ )}
+ {!record.tier_changer && (
+
+ {record.details}
+
+ )}
+
+
+ act('delete_record', { record: record.ref })}
+ />
+
+
+ );
+ })}
+
+ >
+ );
+};