[MIRROR] Department Goals Subsystem (#12816)

Co-authored-by: Will <7099514+Willburd@users.noreply.github.com>
Co-authored-by: Guti <guti23400@gmail.com>
This commit is contained in:
CHOMPStation2StaffMirrorBot
2026-06-09 15:11:15 -07:00
committed by GitHub
parent 2bdf48b78d
commit 2d09ccfdc7
16 changed files with 631 additions and 104 deletions
@@ -1,4 +1,3 @@
#define GOAL_GENERAL "Common Goal"
#define GOAL_MEDICAL "Medical Goal"
#define GOAL_SECURITY "Security Goal"
@@ -0,0 +1,156 @@
SUBSYSTEM_DEF(departmentgoals)
name = "Department Goals"
wait = 5 SECONDS
dependencies = list(
/datum/controller/subsystem/mobs
)
runlevels = RUNLEVEL_GAME
VAR_PRIVATE/min_goals = 2
VAR_PRIVATE/max_goals = 5
VAR_PRIVATE/list/currentrun = list()
var/list/active_department_goals = list() // List of goal datums that were assigned on round start
VAR_PRIVATE/completed_goals = 0
/datum/controller/subsystem/departmentgoals/Initialize()
for(var/category in list(GOAL_GENERAL, GOAL_MEDICAL, GOAL_SECURITY, GOAL_ENGINEERING, GOAL_CARGO, GOAL_RESEARCH))
active_department_goals[category] = list()
// Get the pool of available goals
var/list/all_goal_types = list()
for(var/datum/goal/checked_goal as anything in subtypesof(/datum/goal))
if(checked_goal.name == /datum/goal::name || !checked_goal.enabled)
continue
all_goal_types += checked_goal
// Pick random goals
for(var/count = 1 to rand(min_goals, max_goals))
var/new_path = pick(all_goal_types)
all_goal_types -= new_path
var/datum/goal/new_goal = new new_path()
active_department_goals[new_goal.category] += new_goal
RegisterSignal(SSdcs, COMSIG_GLOB_ROUND_START, PROC_REF(handle_round_start))
RegisterSignal(SSdcs, COMSIG_GLOB_ROUND_END, PROC_REF(handle_round_end))
return SS_INIT_SUCCESS
/datum/controller/subsystem/departmentgoals/Shutdown()
UnregisterSignal(SSdcs, COMSIG_GLOB_ROUND_START)
UnregisterSignal(SSdcs, COMSIG_GLOB_ROUND_END)
. = ..()
/datum/controller/subsystem/departmentgoals/stat_entry(msg)
msg = "G: [length(active_department_goals)] | F: [completed_goals] | Cr: [length(currentrun)]"
return ..()
/datum/controller/subsystem/departmentgoals/fire()
// If no queue exists, make one and start it
if(!length(currentrun))
for(var/category in active_department_goals)
var/list/dept_goals = active_department_goals[category]
for(var/datum/goal/dept_goal in dept_goals)
currentrun += dept_goal
completed_goals = 0
// Solve the current queue until empty, over multiple ticks if needed
while(length(currentrun))
var/datum/goal/dept_goal = currentrun[1]
completed_goals += dept_goal.check_completion()
currentrun -= dept_goal
if(MC_TICK_CHECK)
return
///////////////////////////////////////////////////////////////////////////////////////////////
// Signals for roundstart announcements and round end praise
///////////////////////////////////////////////////////////////////////////////////////////////
/datum/controller/subsystem/departmentgoals/proc/handle_round_start()
SIGNAL_HANDLER
// Lets admins set somes stuff quickly
addtimer(CALLBACK(src, PROC_REF(announce_goals)), 30 SECONDS)
/datum/controller/subsystem/departmentgoals/proc/announce_goals()
var/list/all_goals = list()
for(var/category in active_department_goals)
var/list/cat_goals = active_department_goals[category]
if(!length(cat_goals))
continue
all_goals += cat_goals
if(!length(all_goals))
GLOB.command_announcement.Announce("There are no department goals for this shift.", "Station Resource Department")
return
GLOB.command_announcement.Announce("Department goals have been updated for this shift. (Check your IC tab's \"Check Round Goals\" for details!)", "Station Resource Department")
/datum/controller/subsystem/departmentgoals/proc/handle_round_end()
SIGNAL_HANDLER
if(!length(active_department_goals))
return
show_goal_status_to(world)
/datum/controller/subsystem/departmentgoals/proc/show_goal_status_to(user)
to_chat(user, span_notice(span_world("Department goals are:")))
var/any_goals = FALSE
for(var/category in active_department_goals)
var/list/cat_goals = active_department_goals[category]
if(!length(cat_goals))
continue
to_chat(user, span_filter_system(span_bold("[category]:")))
for(var/datum/goal/G in cat_goals)
to_chat(user, span_filter_system("[G.get_completed() ? span_notice("[G.name]") : span_danger("[G.name]")]: [span_filter_system("[G.goal_text]")] [G.progress_string()]"))
any_goals = TRUE
if(!any_goals)
to_chat(user, span_info("There are no station goals."))
/// Debugging only, should probably leave commented out as well. Adds one of each goal type to the active list
/datum/controller/subsystem/departmentgoals/proc/debug_remove_all_goals()
for(var/category in active_department_goals)
var/list/active_goals_sublist = active_department_goals[category]
QDEL_LIST(active_goals_sublist)
/datum/controller/subsystem/departmentgoals/proc/debug_add_all_goals()
for(var/subtype in subtypesof(/datum/goal))
var/datum/goal/goal_template = subtype
if(goal_template.name == /datum/goal::name)
continue
var/list/active_goals_sublist = active_department_goals[goal_template.category]
active_goals_sublist += new goal_template()
// Move these helpers when upported or make a tgui instead
/mob/verb/check_round_goals()
set name = "Check Round Goals"
set desc = "View currently active round goals, and if they have been completed."
set category = "IC.Notes"
SSdepartmentgoals.show_goal_status_to(usr)
ADMIN_VERB(add_department_goal, R_EVENT, "Add Department Goal", "Adds a goal for the station to reach.", ADMIN_CATEGORY_EVENTS)
var/choice = tgui_input_list(usr,"Choose goal to add:","New Goal", subtypesof(/datum/goal))
if(!choice)
return
var/datum/goal/template = choice
var/list/dept_goals = SSdepartmentgoals.active_department_goals[template.category]
dept_goals += new template()
log_admin("[key_name(usr)] has added a department goal: [template.name].")
ADMIN_VERB(remove_department_goal, R_EVENT, "Remove Department Goal", "Remove a goal from the station's current department goals.", ADMIN_CATEGORY_EVENTS)
var/list/all_goals = list()
for(var/category in SSdepartmentgoals.active_department_goals)
all_goals += SSdepartmentgoals.active_department_goals[category]
if(!length(all_goals))
to_chat(usr, span_warning("There are no station goals."))
return
var/datum/goal/choice = tgui_input_list(usr,"Choose goal to remove:","Remove Goal", all_goals)
if(!choice)
return
log_admin("[key_name(usr)] has removed the department goal: [choice].")
SSdepartmentgoals.active_department_goals[choice.category] -= choice
qdel(choice)
+118
View File
@@ -0,0 +1,118 @@
/datum/goal/cargo
category = GOAL_CARGO
/datum/goal/cargo/New()
. = ..()
RegisterSignal(SSdcs,COMSIG_GLOB_SUPPLY_SHUTTLE_SELL_ITEM,PROC_REF(handle_cargo_sale))
/datum/goal/cargo/Destroy(force)
UnregisterSignal(SSdcs,COMSIG_GLOB_SUPPLY_SHUTTLE_SELL_ITEM)
. = ..()
/datum/goal/cargo/proc/handle_cargo_sale(datum/source, atom/movable/sold_item, sold_successfully, datum/exported_crate/export_data, area/shuttle_subarea)
SIGNAL_HANDLER
return
// Sell sheets
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/goal/cargo/sell_sheets
name = "Sell Refined Materials"
var/mat_to_sell = MAT_STEEL
/datum/goal/cargo/sell_sheets/New()
. = ..()
// Decide the sheet to sell
mat_to_sell = pick(list(
MAT_STEEL,
MAT_BRONZE,
MAT_COPPER,
MAT_DIAMOND,
MAT_GOLD,
MAT_LEAD,
MAT_IRON,
MAT_PLATINUM,
MAT_PHORON,
MAT_DURASTEEL,
MAT_PLASTEEL,
MAT_MORPHIUM,
MAT_METALHYDROGEN,
MAT_VALHOLLIDE,
MAT_SUPERMATTER
))
switch(mat_to_sell)
if(MAT_SUPERMATTER, MAT_VALHOLLIDE, MAT_METALHYDROGEN, MAT_MORPHIUM)
goal_count = rand(25,50)
else
goal_count = rand(150,300)
var/datum/material/mat_datum = get_material_by_name(mat_to_sell)
goal_text = "Export a total of [goal_count] [mat_datum.name] [mat_datum.sheet_plural_name]."
/datum/goal/cargo/sell_sheets/handle_cargo_sale(datum/source, atom/movable/sold_item, sold_successfully, datum/exported_crate/export_data, area/shuttle_subarea)
if(!sold_successfully)
return
if(!istype(sold_item,/obj/structure/closet/crate))
return
for(var/obj/item/stack/material/sheet_stack in sold_item)
if(!sheet_stack.material || sheet_stack.material.name != mat_to_sell)
continue
current_count += sheet_stack.amount
// Sell chemicals
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/goal/cargo/sell_chemicals
name = "Export Chemical Tanks"
var/chosen_reagent = null
/datum/goal/cargo/sell_chemicals/New()
. = ..()
goal_count = rand(6,10) * CARGOTANKER_VOLUME
chosen_reagent = pick(list(
REAGENT_ID_BICARIDINE,
REAGENT_ID_ANTITOXIN,
REAGENT_ID_KELOTANE,
REAGENT_ID_DERMALINE,
REAGENT_ID_TRICORDRAZINE,
REAGENT_ID_ADRANOL,
REAGENT_ID_INAPROVALINE,
REAGENT_ID_DEXALIN,
REAGENT_ID_TRAMADOL,
REAGENT_ID_ALKYSINE,
REAGENT_ID_IMIDAZOLINE,
REAGENT_ID_SPACEACILLIN,
REAGENT_ID_CARTHATOLINE,
REAGENT_ID_HYRONALIN,
REAGENT_ID_RYETALYN,
REAGENT_ID_PERIDAXON,
REAGENT_ID_LUBE,
REAGENT_ID_CLEANER,
REAGENT_ID_PAINT,
REAGENT_ID_SACID,
REAGENT_ID_PACID
))
var/datum/reagent/chem = SSchemistry.chemical_reagents[chosen_reagent]
goal_text = "Export [goal_count]u of [chem.name]."
/datum/goal/cargo/sell_chemicals/handle_cargo_sale(datum/source, atom/movable/sold_item, sold_successfully, datum/exported_crate/export_data, area/shuttle_subarea)
if(!sold_successfully)
return
if(!istype(sold_item,/obj/vehicle/train/trolley_tank))
return
current_count += sold_item.reagents.get_reagent_amount(chosen_reagent)
// Drill Rock
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/goal/cargo/mine_rock
name = "Mining Productivity"
/datum/goal/cargo/mine_rock/New()
goal_count = rand(3500,5500)
goal_text = "Drill through at least [goal_count] rock walls, keeping our miners in shape!"
/datum/goal/cargo/mine_rock/check_completion()
current_count = GLOB.rocks_drilled_roundstat
. = ..()
@@ -0,0 +1,91 @@
/datum/goal/common
category = GOAL_GENERAL
// Clean floors
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/goal/common/clean_floors
name = "Clean Dirty Floors"
/datum/goal/common/clean_floors/New()
. = ..()
goal_count = rand(3000,6000)
goal_text = "Clean up [goal_count] dirty sections of floor, this station gets filthy!"
RegisterSignal(SSdcs,COMSIG_GLOB_WASHED_FLOOR,PROC_REF(handle_mopped_floor))
/datum/goal/common/clean_floors/Destroy(force)
UnregisterSignal(SSdcs,COMSIG_GLOB_WASHED_FLOOR)
. = ..()
/datum/goal/common/clean_floors/proc/handle_mopped_floor(turf/source)
SIGNAL_HANDLER
current_count++
// Cardio
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/goal/common/just_walk
name = "Cardio Quota"
/datum/goal/common/just_walk/New()
. = ..()
goal_count = rand(10000,90000)
goal_text = "Crew should take at least [goal_count] steps to ensure their cardio quotas are met."
/datum/goal/common/just_walk/check_completion()
current_count = GLOB.step_taken_shift_roundstat
. = ..()
// Grow plants
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/goal/common/grow_plants
name = "Grow Crops"
/datum/goal/common/grow_plants/New()
. = ..()
goal_count = rand(200,500)
goal_text = "Crew should grow at least [goal_count] plants of any type to encourage hydroponics and kitchen crew productivity."
/datum/goal/common/grow_plants/check_completion()
current_count = GLOB.seed_planted_shift_roundstat
. = ..()
// Food cooked
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/goal/common/food_prepared
name = "Cook Food"
/datum/goal/common/food_prepared/New()
. = ..()
goal_count = rand(50,200)
goal_text = "Get those friers ready, and cook up at least [goal_count] meals of any type for the crew!"
RegisterSignal(SSdcs,COMSIG_GLOB_FOOD_PREPARED,PROC_REF(handle_food_prepared))
/datum/goal/common/food_prepared/Destroy(force)
UnregisterSignal(SSdcs,COMSIG_GLOB_FOOD_PREPARED)
. = ..()
/datum/goal/common/food_prepared/proc/handle_food_prepared(datum/recipe/source, obj/container, list/results)
SIGNAL_HANDLER
current_count++
// Trash searched
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/goal/common/trashpiles
name = "Clean Out Maintenance Trash"
/datum/goal/common/trashpiles/New()
. = ..()
goal_count = rand(40,200)
goal_text = "Get that trash cleaned out of maintenance! Dig at least [goal_count] things out of the trashpiles in maintenance."
RegisterSignal(SSdcs,COMSIG_GLOB_TRASHPILE_SEARCHED,PROC_REF(handle_trash_searched))
/datum/goal/common/trashpiles/Destroy(force)
UnregisterSignal(SSdcs,COMSIG_GLOB_TRASHPILE_SEARCHED)
. = ..()
/datum/goal/common/trashpiles/proc/handle_trash_searched(datum/source, mob/living/user, list/searched_by)
SIGNAL_HANDLER
current_count++
@@ -0,0 +1,23 @@
/datum/goal
var/name = "goal"
var/category = null
var/goal_text = "Do nothing! Congratulations."
var/enabled = TRUE // Allows easy disabling downstream
var/current_count = 0
var/goal_count = 1
VAR_PRIVATE/completed = FALSE
/// Handles midround announcement, the override should pass TRUE to the parent call if the goal completes during the round!
/datum/goal/proc/check_completion()
SHOULD_CALL_PARENT(TRUE)
if(current_count >= goal_count && !completed)
GLOB.command_announcement.Announce("The [category] \"[name]\" has been completed, congratulations!", "Central Command")
completed = TRUE
return completed
/datum/goal/proc/get_completed() // Faster, does not recalculate
return completed
/datum/goal/proc/progress_string()
return span_info("Completion: [span_bold( "[FLOOR((current_count / goal_count) * 100,1)]" )]%")
@@ -0,0 +1,6 @@
/datum/goal/engineering
category = GOAL_ENGINEERING
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -0,0 +1,31 @@
/datum/goal/medical
category = GOAL_MEDICAL
// Autopsies
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/goal/medical/autopsies
name = "Perform Autopsies"
var/list/scanned_mobs = list() // List of mob NAMES scanned, no refs here
/datum/goal/medical/autopsies/New()
. = ..()
goal_count = rand(15,30)
goal_text = "Perform at least [goal_count] autopsies on deceased monkeys or crew to train medical skills or determine cause of death."
RegisterSignal(SSdcs,COMSIG_GLOB_AUTOPSY_PERFORMED,PROC_REF(handle_autopsy_perform))
/datum/goal/medical/autopsies/Destroy(force)
UnregisterSignal(SSdcs,COMSIG_GLOB_AUTOPSY_PERFORMED)
. = ..()
/datum/goal/medical/autopsies/check_completion()
current_count = scanned_mobs.len
. = ..()
/datum/goal/medical/autopsies/proc/handle_autopsy_perform(atom/source, mob/user, mob/target)
SIGNAL_HANDLER
if(!target?.dna?.real_name) // Should never happen unless somethings broken horribly
return
if(target.dna.real_name in scanned_mobs)
return
scanned_mobs += target.dna.real_name
@@ -0,0 +1,62 @@
/datum/goal/research
category = GOAL_RESEARCH
// Extract artifacts
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/goal/research/extract_artifacts
name = "Extract Artifact Powers"
/datum/goal/research/extract_artifacts/New()
. = ..()
goal_count = rand(35,50)
goal_text = "Extract the powers of [goal_count] artifacts to prove RnD's overblown budget is needed."
RegisterSignal(SSdcs,COMSIG_GLOB_HARVEST_ARTIFACT,PROC_REF(handle_artifact_harvest))
/datum/goal/research/extract_artifacts/Destroy(force)
UnregisterSignal(SSdcs,COMSIG_GLOB_HARVEST_ARTIFACT)
. = ..()
/datum/goal/research/extract_artifacts/proc/handle_artifact_harvest(atom/source, obj/item/anobattery/inserted_battery, mob/user)
SIGNAL_HANDLER
current_count++
// Extract slimes
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/goal/research/extract_slime_cores
name = "Extract Slime Cores"
/datum/goal/research/extract_slime_cores/New()
. = ..()
goal_count = rand(50,100)
goal_text = "Extract the cores of [goal_count] slimes, regardless of type."
RegisterSignal(SSdcs,COMSIG_GLOB_HARVEST_SLIME_CORE,PROC_REF(handle_slime_harvest))
/datum/goal/research/extract_slime_cores/Destroy(force)
UnregisterSignal(SSdcs,COMSIG_GLOB_HARVEST_SLIME_CORE)
. = ..()
/datum/goal/research/extract_slime_cores/proc/handle_slime_harvest(atom/source)
SIGNAL_HANDLER
current_count++
// Build Mechs
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/goal/research/build_mechs
name = "Construct Mechs"
/datum/goal/research/build_mechs/New()
. = ..()
goal_count = rand(10,20)
goal_text = "Flex the RnD budget and produce [goal_count] mechs of any type."
RegisterSignal(SSdcs,COMSIG_GLOB_MECH_CONSTRUCTED,PROC_REF(handle_mech_construction))
/datum/goal/research/build_mechs/Destroy(force)
UnregisterSignal(SSdcs,COMSIG_GLOB_MECH_CONSTRUCTED)
. = ..()
/datum/goal/research/build_mechs/proc/handle_mech_construction(atom/source)
SIGNAL_HANDLER
current_count++
@@ -0,0 +1,22 @@
/datum/goal/security
category = GOAL_SECURITY
// Forensics samples
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/goal/security/forensics_samples
name = "Collect Forensics Samples"
/datum/goal/security/forensics_samples/New()
. = ..()
goal_count = rand(25,50)
goal_text = "Collect [goal_count] samples using the detective's forensics tools."
RegisterSignal(SSdcs,COMSIG_GLOB_FORENSICS_COLLECTED,PROC_REF(handle_forensic_collection))
/datum/goal/security/forensics_samples/Destroy(force)
UnregisterSignal(SSdcs,COMSIG_GLOB_FORENSICS_COLLECTED)
. = ..()
/datum/goal/security/forensics_samples/proc/handle_forensic_collection(atom/source, atom/target, mob/user)
SIGNAL_HANDLER
current_count++
+13
View File
@@ -0,0 +1,13 @@
// Prey eaten
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/goal/common/prey_eaten
name = "Crew \"Morale\" Booster"
/datum/goal/common/prey_eaten/New()
. = ..()
goal_count = rand(10,30)
goal_text = "Crew should engage in more \"Recreational\" activities, with and even inside each other! Have at least [goal_count] \"breaks\" together and find out just how close you can be as a crew!"
/datum/goal/common/prey_eaten/check_completion()
current_count = GLOB.prey_eaten_roundstat
. = ..()
-101
View File
@@ -1,101 +0,0 @@
GLOBAL_LIST(department_goals)
GLOBAL_LIST(active_department_goals)
/hook/startup/proc/initializeDepartmentGoals()
GLOB.department_goals = list(GOAL_GENERAL, GOAL_MEDICAL, GOAL_SECURITY, GOAL_ENGINEERING, GOAL_CARGO, GOAL_RESEARCH)
GLOB.active_department_goals = list(GOAL_GENERAL, GOAL_MEDICAL, GOAL_SECURITY, GOAL_ENGINEERING, GOAL_CARGO, GOAL_RESEARCH)
for(var/category in GLOB.department_goals)
GLOB.department_goals[category] = list()
for(var/subtype in subtypesof(/datum/goal))
var/datum/goal/SG = new subtype()
if(SG.name == "goal")
continue
if(SG.category == category)
GLOB.department_goals[category] |= SG
for(var/category in GLOB.active_department_goals)
GLOB.active_department_goals[category] = list()
var/list/cat_goals = GLOB.department_goals[category]
var/goal_count = rand(2,4)
for(var/count = 1 to goal_count)
var/datum/goal/G
if(LAZYLEN(cat_goals))
G = pick(cat_goals)
if(G)
G.active_goal = TRUE
cat_goals -= G
GLOB.active_department_goals[category] |= G
return 1
/hook/roundend/proc/checkDepartmentGoals()
for(var/category in GLOB.active_department_goals)
var/list/cat_goals = GLOB.active_department_goals[category]
to_world(span_world("[category]"))
if(!LAZYLEN(cat_goals))
to_world(span_filter_system("There were no assigned goals!"))
else
for(var/datum/goal/G in cat_goals)
var/success = G.check_completion()
to_world(span_filter_system("[success ? span_notice("[G.name]") : span_warning("[G.name]")]"))
to_world(span_filter_system("[G.goal_text]"))
return 1
/datum/goal
var/name = "goal"
var/goal_text = "Do nothing! Congratulations."
var/active_goal = FALSE
var/category = GOAL_GENERAL
/datum/goal/proc/check_completion()
return FALSE
/datum/goal/common
name = "goal"
goal_text = "Congratulations, you still do nothing."
/datum/goal/medical
name = "goal"
goal_text = "Congratulations, you still do nothing."
category = GOAL_MEDICAL
/datum/goal/security
name = "goal"
goal_text = "Congratulations, you still do nothing."
category = GOAL_SECURITY
/datum/goal/engineering
name = "goal"
goal_text = "Congratulations, you still do nothing."
category = GOAL_ENGINEERING
/datum/goal/cargo
name = "goal"
goal_text = "Congratulations, you still do nothing."
category = GOAL_CARGO
/datum/goal/research
name = "goal"
goal_text = "Congratulations, you still do nothing."
category = GOAL_RESEARCH
@@ -138,6 +138,9 @@
pose_move = FALSE
remove_pose_indicator()
if(client && !is_incorporeal() && isturf(loc))
GLOB.step_taken_shift_roundstat++
// This calculates the amount of slowdown to receive from items worn. This does NOT include species modifiers.
// It is in a seperate place to avoid an infinite loop situation with dragging mobs dragging each other.
// Also its nice to have these things seperated.
+23
View File
@@ -305,3 +305,26 @@
news.Swap(1, 3) // List is sorted in ascending order of timestamp, we want descending
return news
/datum/data/pda/app/goals
name = "Departmental Goals"
icon = "list-check"
template = "pda_depgoals"
/datum/data/pda/app/goals/update_ui(mob/user, list/data)
data["goals"] = get_goals()
/datum/data/pda/app/goals/proc/get_goals()
var/list/goals = list()
var/index = 0
for(var/category in SSdepartmentgoals.active_department_goals)
var/list/dept_goal = SSdepartmentgoals.active_department_goals[category]
for(var/datum/goal/goal in dept_goal)
goals += list(list(
"name" = goal.name,
"description" = goal.goal_text,
"count" = FLOOR((goal.current_count / goal.goal_count) * 100, 1),
"index" = ++index
))
return goals
+2 -1
View File
@@ -50,7 +50,8 @@
new/datum/data/pda/app/nerdle,
new/datum/data/pda/app/game_launcher,
new/datum/data/pda/utility/scanmode/notes,
new/datum/data/pda/utility/flashlight)
new/datum/data/pda/utility/flashlight,
new/datum/data/pda/app/goals)
var/list/shortcut_cache = list()
var/list/shortcut_cat_order = list()
var/list/notifying_programs = list()
@@ -0,0 +1,72 @@
import { useBackend } from 'tgui/backend';
import {
Box,
NoticeBox,
ProgressBar,
Section,
Stack,
} from 'tgui-core/components';
type Data = {
goals: Goal[];
};
type Goal = {
name: string;
description: string;
count: number;
index: number;
};
export const pda_depgoals = (props) => {
const { data } = useBackend<Data>();
const { goals } = data;
return (
<Box>
{(!goals.length && (
<NoticeBox>No departmental goals found!</NoticeBox>
)) || <GoalsDisplay />}
</Box>
);
};
const GoalsDisplay = (props) => {
const { data } = useBackend<Data>();
const { goals } = data;
return (
<Stack vertical fill>
{goals.length > 0 &&
goals.map((goal) => (
<Section key={goal.index}>
<Stack vertical>
<Stack.Item>
<Box fontSize="4">{goal.name}</Box>
<Box fontSize="2" color="gray">
{goal.description}
</Box>
</Stack.Item>
<Stack.Item>
<ProgressBar
value={goal.count}
minValue={0}
maxValue={100}
ranges={{
good: [85, 100],
average: [25, 85],
bad: [0, 25],
}}
>
<Stack align="baseline">
{!!goal.name && <Stack.Item grow>{goal.count}%</Stack.Item>}
</Stack>
</ProgressBar>
</Stack.Item>
</Stack>
</Section>
))}
</Stack>
);
};
+9 -1
View File
@@ -88,6 +88,7 @@
#include "code\__defines\crafting.dm"
#include "code\__defines\damage_organs.dm"
#include "code\__defines\database.dm"
#include "code\__defines\departmentgoals.dm"
#include "code\__defines\diseases.dm"
#include "code\__defines\dna.dm"
#include "code\__defines\do_afters.dm"
@@ -601,6 +602,7 @@
#include "code\controllers\subsystems\cryoplanets.dm"
#include "code\controllers\subsystems\dbcore.dm"
#include "code\controllers\subsystems\dcs.dm"
#include "code\controllers\subsystems\departmentgoals.dm"
#include "code\controllers\subsystems\early_assets.dm"
#include "code\controllers\subsystems\emergency_shuttle.dm"
#include "code\controllers\subsystems\events.dm"
@@ -834,6 +836,13 @@
#include "code\datums\components\traits\unlucky.dm"
#include "code\datums\components\traits\waddle.dm"
#include "code\datums\components\traits\weaver.dm"
#include "code\datums\departmentgoals\cargogoals.dm"
#include "code\datums\departmentgoals\commongoals.dm"
#include "code\datums\departmentgoals\departmentgoal.dm"
#include "code\datums\departmentgoals\engineeringgoals.dm"
#include "code\datums\departmentgoals\medicalgoals.dm"
#include "code\datums\departmentgoals\researchgoals.dm"
#include "code\datums\departmentgoals\securitygoals.dm"
#include "code\datums\diseases\_disease.dm"
#include "code\datums\diseases\_MobProcs.dm"
#include "code\datums\diseases\anxiety.dm"
@@ -987,7 +996,6 @@
#include "code\datums\repositories\decls.dm"
#include "code\datums\repositories\repository.dm"
#include "code\datums\repositories\unique.dm"
#include "code\datums\roundstats\_defines_local.dm"
#include "code\datums\status_effects\_status_effect.dm"
#include "code\datums\status_effects\_status_effect_helpers.dm"
#include "code\datums\status_effects\grouped_effect.dm"