[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-10 00:11:15 +02:00
committed by GitHub
co-authored by Will Guti
parent 2bdf48b78d
commit 2d09ccfdc7
16 changed files with 631 additions and 104 deletions
+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
. = ..()
-7
View File
@@ -1,7 +0,0 @@
#define GOAL_GENERAL "Common Goal"
#define GOAL_MEDICAL "Medical Goal"
#define GOAL_SECURITY "Security Goal"
#define GOAL_ENGINEERING "Engineering Goal"
#define GOAL_CARGO "Cargo Goal"
#define GOAL_RESEARCH "Research Goal"
-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