diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index 8e59c63cfbd70..fb6fabfe1f5f9 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -347,7 +347,8 @@ . = ..() -/obj/docking_port/mobile/emergency/request(obj/docking_port/stationary/S, area/signal_origin, reason, red_alert, set_coefficient=null) +/// DOPPLER EDIT ADDITION: add silent mode support +/obj/docking_port/mobile/emergency/request(obj/docking_port/stationary/S, area/signal_origin, reason, red_alert, set_coefficient=null, silent=FALSE) if(!isnum(set_coefficient)) set_coefficient = SSsecurity_level.current_security_level.shuttle_call_time_mod alert_coeff = set_coefficient @@ -368,13 +369,15 @@ else SSshuttle.emergency_last_call_loc = null - priority_announce( - text = "The emergency shuttle has been called. [red_alert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [(timeLeft(60 SECONDS))] minutes.[reason][SSshuttle.emergency_last_call_loc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ][SSshuttle.admin_emergency_no_recall ? "\n\nWarning: Shuttle recall subroutines disabled; Recall not possible." : ""]", - title = "Emergency Shuttle Dispatched", - sound = ANNOUNCER_SHUTTLECALLED, - sender_override = "Emergency Shuttle Uplink Alert", - color_override = "orange", - ) + if(!silent) /// DOPPLER ADDITION BEGIN + priority_announce( + text = "The emergency shuttle has been called. [red_alert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [(timeLeft(60 SECONDS))] minutes.[reason][SSshuttle.emergency_last_call_loc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ][SSshuttle.admin_emergency_no_recall ? "\n\nWarning: Shuttle recall subroutines disabled; Recall not possible." : ""]", + title = "Emergency Shuttle Dispatched", + sound = ANNOUNCER_SHUTTLECALLED, + sender_override = "Emergency Shuttle Uplink Alert", + color_override = "orange", + ) + /// DOPPLER EDIT END /obj/docking_port/mobile/emergency/cancel(area/signalOrigin) if(mode != SHUTTLE_CALL) diff --git a/config/doppler/config_doppler.txt b/config/doppler/config_doppler.txt index 850982e886d2b..2263e231f25b4 100644 --- a/config/doppler/config_doppler.txt +++ b/config/doppler/config_doppler.txt @@ -6,3 +6,15 @@ CRYO_MIN_SSD_TIME 9000 ## If uncommented, suicide will be disabled. DISABLE_SUICIDE + +## Enables autotransfer +AUTOTRANSFER + +# First autotransfer vote time (2 hrs) +VOTE_AUTOTRANSFER_INITIAL 72000 + +# Interval between autotransfer votes after the first (0.5 hrs) +VOTE_AUTOTRANSFER_INTERVAL 18000 + +# Maximum number of votes before the system forces roundend (2, meaning first vote at 2.0 hrs, second at 2.5hrs, and forced at 3.0hrs) +VOTE_AUTOTRANSFER_MAXIMUM 2 \ No newline at end of file diff --git a/modular_doppler/autotransfer/autotransfer.dm b/modular_doppler/autotransfer/autotransfer.dm new file mode 100644 index 0000000000000..3303245f4b10a --- /dev/null +++ b/modular_doppler/autotransfer/autotransfer.dm @@ -0,0 +1,54 @@ +#define NO_MAXVOTES_CAP -1 + +SUBSYSTEM_DEF(autotransfer) + name = "Autotransfer Vote" + flags = SS_KEEP_TIMING | SS_BACKGROUND + wait = 1 MINUTES + + var/starttime + var/targettime + var/voteinterval + var/maxvotes + var/curvotes = 0 + +/datum/controller/subsystem/autotransfer/Initialize() + if(!CONFIG_GET(flag/autotransfer)) //Autotransfer voting disabled. + can_fire = FALSE + return SS_INIT_NO_NEED + + var/init_vote = CONFIG_GET(number/vote_autotransfer_initial) + starttime = REALTIMEOFDAY + targettime = starttime + init_vote + voteinterval = CONFIG_GET(number/vote_autotransfer_interval) + maxvotes = CONFIG_GET(number/vote_autotransfer_maximum) + return SS_INIT_SUCCESS + +/datum/controller/subsystem/autotransfer/Recover() + starttime = SSautotransfer.starttime + voteinterval = SSautotransfer.voteinterval + curvotes = SSautotransfer.curvotes + +/datum/controller/subsystem/autotransfer/fire() + if(REALTIMEOFDAY < targettime) + return + if(maxvotes == NO_MAXVOTES_CAP || maxvotes > curvotes) + SSvote.initiate_vote(/datum/vote/transfer_vote, "automatic transfer", forced = TRUE) + targettime = targettime + voteinterval + curvotes++ + else + SSshuttle.autoEnd() + +/** + * At shift start, pulls the autotransfer interval from config and applies + * + * Arguments: + * * real_round_shift_time - World time the round left the pregame lobby + */ +/datum/controller/subsystem/autotransfer/proc/new_shift(real_round_start_time) + var/init_vote = CONFIG_GET(number/vote_autotransfer_initial) // Check if an admin has manually set an override in the pre-game lobby + starttime = real_round_start_time + targettime = starttime + init_vote + log_game("Autotransfer enabled, first vote in [DisplayTimeText(targettime - starttime)]") + message_admins("Autotransfer enabled, first vote in [DisplayTimeText(targettime - starttime)]") + +#undef NO_MAXVOTES_CAP diff --git a/modular_doppler/autotransfer/autotransfer_config.dm b/modular_doppler/autotransfer/autotransfer_config.dm new file mode 100644 index 0000000000000..8c4bb820de80a --- /dev/null +++ b/modular_doppler/autotransfer/autotransfer_config.dm @@ -0,0 +1,24 @@ +/// Length of time before the first autotransfer vote is called (deciseconds, default 2 hours) +/// Set to 0 to disable the subsystem altogether. +/datum/config_entry/number/vote_autotransfer_initial + config_entry_value = 72000 + min_val = 0 + +///length of time to wait before subsequent autotransfer votes (deciseconds, default 30 minutes) +/datum/config_entry/number/vote_autotransfer_interval + config_entry_value = 18000 + min_val = 0 + +/// maximum extensions until the round autoends. +/// Set to 0 to force automatic crew transfer after the 'vote_autotransfer_initial' elapsed. +/// Set to -1 to disable the maximum extensions cap. +/datum/config_entry/number/vote_autotransfer_maximum + config_entry_value = 4 + min_val = -1 + +/// Determines if the autotransfer system runs or not. +/datum/config_entry/flag/autotransfer + + +/// Determines if the transfer vote can be started by anyone or not. +/datum/config_entry/flag/allow_vote_transfer diff --git a/modular_doppler/autotransfer/shuttle.dm b/modular_doppler/autotransfer/shuttle.dm new file mode 100644 index 0000000000000..f0fd0ab1953bf --- /dev/null +++ b/modular_doppler/autotransfer/shuttle.dm @@ -0,0 +1,15 @@ +/// ADDITIONAL PROC EDITS AS FOLLOWS: +// - code/modules/shuttle/emergency.dm - /obj/docking_port/mobile/emergency/request + +/datum/controller/subsystem/shuttle + var/endvote_passed = FALSE + +/datum/controller/subsystem/shuttle/proc/autoEnd() + if(EMERGENCY_IDLE_OR_RECALLED) + SSshuttle.emergency.request(silent = TRUE) + priority_announce("The shift has come to an end and the shuttle called. [SSsecurity_level.get_current_level_as_number() == SEC_LEVEL_RED ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [emergency.timeLeft(600)] minutes.", null, ANNOUNCER_SHUTTLECALLED, "Priority", color_override = "orange") + log_game("Round end vote passed. Shuttle has been auto-called.") + message_admins("Round end vote passed. Shuttle has been auto-called.") + emergency_no_recall = TRUE + endvote_passed = TRUE + SSevents.can_fire = FALSE // we're going home diff --git a/modular_doppler/autotransfer/transfer_vote.dm b/modular_doppler/autotransfer/transfer_vote.dm new file mode 100644 index 0000000000000..61ddb8a7ba912 --- /dev/null +++ b/modular_doppler/autotransfer/transfer_vote.dm @@ -0,0 +1,47 @@ +#define CHOICE_TRANSFER "Initiate Crew Transfer" +#define CHOICE_CONTINUE "Continue Playing" + +/datum/vote/transfer_vote + name = "Transfer" + default_choices = list( + CHOICE_TRANSFER, + CHOICE_CONTINUE, + ) + default_message = "Vote to initiate a transfer, forcing a shuttle call \ + that cannot be recalled. Don't touch it unless it's not working \ + automatically." + +/datum/vote/transfer_vote/toggle_votable() + CONFIG_SET(flag/allow_vote_transfer, !CONFIG_GET(flag/allow_vote_transfer)) + +/datum/vote/transfer_vote/is_config_enabled() + return CONFIG_GET(flag/autotransfer) && CONFIG_GET(flag/allow_vote_transfer) + +/datum/vote/transfer_vote/can_be_initiated(forced) + . = ..() + if(. != VOTE_AVAILABLE) + return . + + if(forced) + return VOTE_AVAILABLE + + if(!CONFIG_GET(flag/autotransfer) || !CONFIG_GET(flag/allow_vote_transfer)) + return "Transfer voting is disabled." + + return VOTE_AVAILABLE + +/datum/vote/transfer_vote/finalize_vote(winning_option) + if(winning_option == CHOICE_CONTINUE) + return + + if(winning_option == CHOICE_TRANSFER) + SSshuttle.autoEnd() + var/obj/machinery/computer/communications/comms_console = locate() in GLOB.shuttle_caller_list + if(comms_console) + comms_console.post_status("shuttle") + return + + CRASH("[type] wasn't passed a valid winning choice. (Got: [winning_option || "null"])") + +#undef CHOICE_TRANSFER +#undef CHOICE_CONTINUE diff --git a/tgstation.dme b/tgstation.dme index 221a28d96d74d..15915e1924c05 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -6465,6 +6465,10 @@ #include "modular_doppler\automapper\code\area_spawn_subsystem.dm" #include "modular_doppler\automapper\code\automap_template.dm" #include "modular_doppler\automapper\code\automapper_subsystem.dm" +#include "modular_doppler\autotransfer\autotransfer.dm" +#include "modular_doppler\autotransfer\autotransfer_config.dm" +#include "modular_doppler\autotransfer\shuttle.dm" +#include "modular_doppler\autotransfer\transfer_vote.dm" #include "modular_doppler\cell_component\code\cell_component.dm" #include "modular_doppler\colony_fabricator\code\cargo_packs.dm" #include "modular_doppler\colony_fabricator\code\colony_fabricator.dm"