diff --git a/code/datums/roundstats/_defines_local.dm b/code/__defines/departmentgoals.dm similarity index 99% rename from code/datums/roundstats/_defines_local.dm rename to code/__defines/departmentgoals.dm index 951d7118ff..580d0e8f69 100644 --- a/code/datums/roundstats/_defines_local.dm +++ b/code/__defines/departmentgoals.dm @@ -1,4 +1,3 @@ - #define GOAL_GENERAL "Common Goal" #define GOAL_MEDICAL "Medical Goal" #define GOAL_SECURITY "Security Goal" diff --git a/code/controllers/subsystems/departmentgoals.dm b/code/controllers/subsystems/departmentgoals.dm new file mode 100644 index 0000000000..b25dfde5b2 --- /dev/null +++ b/code/controllers/subsystems/departmentgoals.dm @@ -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) diff --git a/code/datums/departmentgoals/cargogoals.dm b/code/datums/departmentgoals/cargogoals.dm new file mode 100644 index 0000000000..2d8349b633 --- /dev/null +++ b/code/datums/departmentgoals/cargogoals.dm @@ -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 + . = ..() diff --git a/code/datums/departmentgoals/commongoals.dm b/code/datums/departmentgoals/commongoals.dm new file mode 100644 index 0000000000..02ef05e37b --- /dev/null +++ b/code/datums/departmentgoals/commongoals.dm @@ -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++ diff --git a/code/datums/departmentgoals/departmentgoal.dm b/code/datums/departmentgoals/departmentgoal.dm new file mode 100644 index 0000000000..e726e42f85 --- /dev/null +++ b/code/datums/departmentgoals/departmentgoal.dm @@ -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)]" )]%") diff --git a/code/datums/departmentgoals/engineeringgoals.dm b/code/datums/departmentgoals/engineeringgoals.dm new file mode 100644 index 0000000000..a387dbbf63 --- /dev/null +++ b/code/datums/departmentgoals/engineeringgoals.dm @@ -0,0 +1,6 @@ +/datum/goal/engineering + category = GOAL_ENGINEERING + + +// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/code/datums/departmentgoals/medicalgoals.dm b/code/datums/departmentgoals/medicalgoals.dm new file mode 100644 index 0000000000..3d93d7988d --- /dev/null +++ b/code/datums/departmentgoals/medicalgoals.dm @@ -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 diff --git a/code/datums/departmentgoals/researchgoals.dm b/code/datums/departmentgoals/researchgoals.dm new file mode 100644 index 0000000000..12f9dd8a05 --- /dev/null +++ b/code/datums/departmentgoals/researchgoals.dm @@ -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++ diff --git a/code/datums/departmentgoals/securitygoals.dm b/code/datums/departmentgoals/securitygoals.dm new file mode 100644 index 0000000000..0714aec96d --- /dev/null +++ b/code/datums/departmentgoals/securitygoals.dm @@ -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++ diff --git a/code/datums/departmentgoals/voregoals.dm b/code/datums/departmentgoals/voregoals.dm new file mode 100644 index 0000000000..4b498fa8be --- /dev/null +++ b/code/datums/departmentgoals/voregoals.dm @@ -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 + . = ..() diff --git a/code/datums/roundstats/departmentgoal.dm b/code/datums/roundstats/departmentgoal.dm deleted file mode 100644 index ebebd56136..0000000000 --- a/code/datums/roundstats/departmentgoal.dm +++ /dev/null @@ -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 diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 17263ddf74..364b5cc246 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -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. diff --git a/code/modules/pda/core_apps.dm b/code/modules/pda/core_apps.dm index 080eb339be..a58993e7a8 100644 --- a/code/modules/pda/core_apps.dm +++ b/code/modules/pda/core_apps.dm @@ -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 diff --git a/code/modules/pda/pda.dm b/code/modules/pda/pda.dm index e8c9db2c50..264fcec8cd 100644 --- a/code/modules/pda/pda.dm +++ b/code/modules/pda/pda.dm @@ -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() diff --git a/tgui/packages/tgui/interfaces/Pda/pda_screens/pda_depgoals.tsx b/tgui/packages/tgui/interfaces/Pda/pda_screens/pda_depgoals.tsx new file mode 100644 index 0000000000..0f13132fb7 --- /dev/null +++ b/tgui/packages/tgui/interfaces/Pda/pda_screens/pda_depgoals.tsx @@ -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(); + + const { goals } = data; + + return ( + + {(!goals.length && ( + No departmental goals found! + )) || } + + ); +}; + +const GoalsDisplay = (props) => { + const { data } = useBackend(); + const { goals } = data; + + return ( + + {goals.length > 0 && + goals.map((goal) => ( +
+ + + {goal.name} + + {goal.description} + + + + + + {!!goal.name && {goal.count}%} + + + + +
+ ))} +
+ ); +}; diff --git a/vorestation.dme b/vorestation.dme index 4102356cb0..708c2d4027 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -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"