diff --git a/aurorastation.dme b/aurorastation.dme
index b0135610e24..8d7cac106ba 100644
--- a/aurorastation.dme
+++ b/aurorastation.dme
@@ -188,6 +188,7 @@
#include "code\controllers\subsystems\plants.dm"
#include "code\controllers\subsystems\power.dm"
#include "code\controllers\subsystems\radio.dm"
+#include "code\controllers\subsystems\responseteam.dm"
#include "code\controllers\subsystems\statistics.dm"
#include "code\controllers\subsystems\sun.dm"
#include "code\controllers\subsystems\sunlight.dm"
@@ -365,7 +366,6 @@
#include "code\game\atoms_movable.dm"
#include "code\game\base_turf.dm"
#include "code\game\periodic_news.dm"
-#include "code\game\response_team.dm"
#include "code\game\shuttle_engines.dm"
#include "code\game\sound.dm"
#include "code\game\supplyshuttle.dm"
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index fd4ba869071..02c5c7c7a8e 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -282,6 +282,16 @@ var/list/gamemode_cache = list()
var/rounds_until_hard_restart = -1 // Changes how often a hard restart will be executed.
+ var/ert_base_chance = 10
+ var/ert_green_inc = 1
+ var/ert_yellow_inc = 1
+ var/ert_blue_inc = 2
+ var/ert_red_inc = 3
+ var/ert_delta_inc = 10
+ var/ert_scaling_factor = 1
+ var/ert_scaling_factor_antag = 1
+ var/ert_scaling_factor_dead = 2
+
/datum/configuration/New()
var/list/L = typesof(/datum/game_mode) - /datum/game_mode
for (var/T in L)
@@ -865,6 +875,25 @@ var/list/gamemode_cache = list()
if ("rounds_until_hard_restart")
rounds_until_hard_restart = text2num(value)
+ if ("ert_base_chance")
+ ert_base_chance = text2num(value)
+ if ("ert_green_inc")
+ ert_green_inc = text2num(value)
+ if ("ert_yellow_inc")
+ ert_yellow_inc = text2num(value)
+ if ("ert_blue_inc")
+ ert_blue_inc = text2num(value)
+ if ("ert_red_inc")
+ ert_red_inc = text2num(value)
+ if ("ert_delta_inc")
+ ert_delta_inc = text2num(value)
+ if ("ert_scaling_factor")
+ ert_scaling_factor = text2num(value)
+ if ("ert_scaling_factor_antag")
+ ert_scaling_factor_antag = text2num(value)
+ if ("ert_scaling_factor_dead")
+ ert_scaling_factor_dead = text2num(value)
+
else
log_misc("Unknown setting in configuration: '[name]'")
diff --git a/code/controllers/subsystems/responseteam.dm b/code/controllers/subsystems/responseteam.dm
new file mode 100644
index 00000000000..a2c599edf38
--- /dev/null
+++ b/code/controllers/subsystems/responseteam.dm
@@ -0,0 +1,164 @@
+/var/datum/controller/subsystem/responseteam/SSresponseteam
+
+/datum/controller/subsystem/responseteam
+ name = "Response Team"
+ wait = 1800 //Fire only every 3 minutes - Not more often needed for now
+
+ var/ert_progression_chance = 0
+ var/percentage_antagonists = 0
+ var/percentage_dead = 0
+ var/can_call_ert = TRUE
+ var/ert_type = "NanoTrasen Response Team" //what ert type will be deployed
+ var/send_emergency_team = 0
+
+/datum/controller/subsystem/responseteam/Recover()
+ ert_progression_chance = SSresponseteam.ert_progression_chance
+ can_call_ert = SSresponseteam.can_call_ert
+ ert_type = SSresponseteam.ert_type
+ send_emergency_team = SSresponseteam.send_emergency_team
+
+/datum/controller/subsystem/responseteam/New()
+ NEW_SS_GLOBAL(SSresponseteam)
+
+/datum/controller/subsystem/responseteam/stat_entry()
+ var/out = "PC:[ert_progression_chance] "
+ out += "BC:[config.ert_base_chance]\n"
+ out += "PA:[percentage_antagonists] "
+ out += "PAF:[config.ert_scaling_factor_antag]\n"
+ out += "PD:[percentage_dead] "
+ out += "PDF:[config.ert_scaling_factor_dead]\n"
+ out += "SF:[config.ert_scaling_factor] "
+ out += "CC:[can_call_ert] "
+ ..(out)
+
+/datum/controller/subsystem/responseteam/fire()
+ if(send_emergency_team == 0) // There is no ERT at the time.
+ var/total = 0
+ var/deadcount = 0
+ var/antagonists = 0
+ for(var/mob/living/carbon/human/H in mob_list)
+ if(!H.isMonkey() || H.client)
+ total++
+ if(is_special_character(H) >= 1) antagonists++
+ if(H.stat == 2) deadcount++
+
+ if(total == 0)
+ percentage_antagonists = 0
+ percentage_dead = 0
+ else
+ percentage_antagonists = round(100 * antagonists / total)
+ percentage_dead = round(100 * deadcount / total)
+
+
+ switch(get_security_level())
+ if("green")
+ ert_progression_chance += config.ert_green_inc
+ if("blue")
+ ert_progression_chance += config.ert_yellow_inc
+ if("red")
+ ert_progression_chance += config.ert_blue_inc
+ if("delta")
+ ert_progression_chance += config.ert_green_inc
+ else
+ ert_progression_chance += 1
+
+/datum/controller/subsystem/responseteam/proc/trigger_armed_response_team(var/forced_choice = FALSE)
+ if(!can_call_ert && !forced_choice)
+ return
+ if(send_emergency_team)
+ return
+
+ var/ert_chance = ert_progression_chance + config.ert_base_chance // Is incremented by fire.
+ ert_chance += config.ert_scaling_factor_dead*percentage_dead // the more people are dead, the higher the chance
+ ert_chance += config.ert_scaling_factor_antag*percentage_antagonists // the more antagonists, the higher the chance
+ ert_chance *= config.ert_scaling_factor
+ ert_chance = min(ert_chance, 100)
+
+ command_announcement.Announce("It would appear that an emergency response team was requested for [station_name()]. We will prepare and send one as soon as possible.", "[current_map.boss_name]")
+
+ if(forced_choice)
+ ert_type = forced_choice
+ else if(!forced_choice && !prob(ert_chance))
+ ert_type = "Tau Ceti Foreign Legion"
+
+ can_call_ert = FALSE // Only one call per round, gentleman.
+ send_emergency_team = 1
+
+ feedback_set("ert_called",ert_chance)
+ feedback_set_details("ert_called",ert_type)
+
+ sleep(600 * 5)
+ send_emergency_team = 0 // Can no longer join the ERT.
+ ert_type = "NanoTrasen Response Team"
+
+
+/client/proc/response_team()
+ set name = "Dispatch Emergency Response Team"
+ set category = "Special Verbs"
+ set desc = "Send an emergency response team to the station"
+
+ if(!holder)
+ to_chat(usr, "Only administrators may use this command.")
+ return
+ if(!ROUND_IS_STARTED)
+ to_chat(usr, "The round hasn't started yet!")
+ return
+ if(SSresponseteam.send_emergency_team)
+ to_chat(usr, "[current_map.boss_name] has already dispatched an emergency response team!")
+ return
+ if(alert("Do you want to dispatch an Emergency Response Team?",,"Yes","No") != "Yes")
+ return
+ if(get_security_level() != "red") // Allow admins to reconsider if the alert level isn't Red
+ switch(alert("The station is not in red alert. Do you still want to dispatch a response team?",,"Yes","No"))
+ if("No")
+ return
+
+ var/choice = input("Select the response team type","Response team selection") as null|anything in list("NanoTrasen Response Team", "Tau Ceti Foreign Legion")
+
+ if(!choice)
+ choice = FALSE
+
+ if(SSresponseteam.send_emergency_team)
+ to_chat(usr, "Looks like somebody beat you to it!")
+ return
+
+ message_admins("[key_name_admin(usr)] is dispatching an Emergency Response Team.", 1)
+ log_admin("[key_name(usr)] used Dispatch Response Team.",admin_key=key_name(usr))
+ SSresponseteam.trigger_armed_response_team(choice)
+
+client/verb/JoinResponseTeam()
+
+ set name = "Join Response Team"
+ set category = "IC"
+
+ if(!MayRespawn(1))
+ to_chat(usr, "You cannot join the response team at this time.")
+ return
+
+ if(istype(usr,/mob/abstract/observer) || istype(usr,/mob/abstract/new_player))
+
+ if(!SSresponseteam.send_emergency_team)
+ to_chat(usr, "No emergency response team is currently being sent.")
+ return
+
+ if(jobban_isbanned(usr, "Antagonist") || jobban_isbanned(usr, "Emergency Response Team") || jobban_isbanned(usr, "Security Officer"))
+ to_chat(usr, "You are jobbanned from the emergency reponse team!")
+ return
+
+ switch(SSresponseteam.ert_type)
+
+ if("Tau Ceti Foreign Legion")
+ if(legion.current_antagonists.len >= legion.hard_cap)
+ to_chat(usr, "The emergency response team is already full!")
+ return
+
+ legion.create_default(usr)
+
+ else
+ if(ert.current_antagonists.len >= ert.hard_cap)
+ to_chat(usr, "The emergency response team is already full!")
+ return
+
+ ert.create_default(usr)
+ else
+ to_chat(usr, "You need to be an observer or new player to use this.")
\ No newline at end of file
diff --git a/code/game/response_team.dm b/code/game/response_team.dm
deleted file mode 100644
index 36956074fc1..00000000000
--- a/code/game/response_team.dm
+++ /dev/null
@@ -1,150 +0,0 @@
-//STRIKE TEAMS
-//Thanks to Kilakk for the admin-button portion of this code.
-
-var/global/send_emergency_team = 0 // Used for automagic response teams
- // 'admin_emergency_team' for admin-spawned response teams
-var/ert_base_chance = 10 // Default base chance. Will be incremented by increment ERT chance.
-var/can_call_ert
-var/ert_type = "NanoTrasen Response Team" //what ert type will be deployed
-
-/client/proc/response_team()
- set name = "Dispatch Emergency Response Team"
- set category = "Special Verbs"
- set desc = "Send an emergency response team to the station"
-
- if(!holder)
- to_chat(usr, "Only administrators may use this command.")
- return
- if(!ROUND_IS_STARTED)
- to_chat(usr, "The round hasn't started yet!")
- return
- if(send_emergency_team)
- to_chat(usr, "[current_map.boss_name] has already dispatched an emergency response team!")
- return
- if(alert("Do you want to dispatch an Emergency Response Team?",,"Yes","No") != "Yes")
- return
- if(get_security_level() != "red") // Allow admins to reconsider if the alert level isn't Red
- switch(alert("The station is not in red alert. Do you still want to dispatch a response team?",,"Yes","No"))
- if("No")
- return
-
- var/choice = input("Select the response team type","Response team selection") as null|anything in list("NanoTrasen Response Team", "Tau Ceti Foreign Legion")
-
- if(choice)
- ert_type = choice
-
- if(send_emergency_team)
- to_chat(usr, "Looks like somebody beat you to it!")
- return
-
- message_admins("[key_name_admin(usr)] is dispatching an Emergency Response Team.", 1)
- log_admin("[key_name(usr)] used Dispatch Response Team.",admin_key=key_name(usr))
- trigger_armed_response_team(1, TRUE)
-
-client/verb/JoinResponseTeam()
-
- set name = "Join Response Team"
- set category = "IC"
-
- if(!MayRespawn(1))
- to_chat(usr, "You cannot join the response team at this time.")
- return
-
- if(istype(usr,/mob/abstract/observer) || istype(usr,/mob/abstract/new_player))
-
- if(!send_emergency_team)
- to_chat(usr, "No emergency response team is currently being sent.")
- return
-
- if(jobban_isbanned(usr, "Antagonist") || jobban_isbanned(usr, "Emergency Response Team") || jobban_isbanned(usr, "Security Officer"))
- to_chat(usr, "You are jobbanned from the emergency reponse team!")
- return
-
- switch(ert_type)
-
- if("Tau Ceti Foreign Legion")
- if(legion.current_antagonists.len >= legion.hard_cap)
- to_chat(usr, "The emergency response team is already full!")
- return
-
- legion.create_default(usr)
-
- else
- if(ert.current_antagonists.len >= ert.hard_cap)
- to_chat(usr, "The emergency response team is already full!")
- return
-
- ert.create_default(usr)
- else
- to_chat(usr, "You need to be an observer or new player to use this.")
-
-// returns a number of dead players in %
-proc/percentage_dead()
- var/total = 0
- var/deadcount = 0
- for(var/mob/living/carbon/human/H in mob_list)
- if(H.client) // Monkeys and mice don't have a client, amirite?
- if(H.stat == 2) deadcount++
- total++
-
- if(total == 0) return 0
- else return round(100 * deadcount / total)
-
-// counts the number of antagonists in %
-proc/percentage_antagonists()
- var/total = 0
- var/antagonists = 0
- for(var/mob/living/carbon/human/H in mob_list)
- if(is_special_character(H) >= 1)
- antagonists++
- total++
-
- if(total == 0) return 0
- else return round(100 * antagonists / total)
-
-// Increments the ERT chance automatically, so that the later it is in the round,
-// the more likely an ERT is to be able to be called.
-proc/increment_ert_chance()
- while(send_emergency_team == 0) // There is no ERT at the time.
- if(get_security_level() == "green")
- ert_base_chance += 1
- if(get_security_level() == "blue")
- ert_base_chance += 2
- if(get_security_level() == "red")
- ert_base_chance += 3
- if(get_security_level() == "delta")
- ert_base_chance += 10 // Need those big guns
- sleep(600 * 3) // Minute * Number of Minutes
-
-
-proc/trigger_armed_response_team(var/force = 0, forced_choice = FALSE)
- if(!can_call_ert && !force)
- return
- if(send_emergency_team)
- return
-
- var/send_team_chance = ert_base_chance // Is incremented by increment_ert_chance.
- send_team_chance += 2*percentage_dead() // the more people are dead, the higher the chance
- send_team_chance += percentage_antagonists() // the more antagonists, the higher the chance
- send_team_chance = min(send_team_chance, 100)
-
- if(force) send_team_chance = 100
-
- // there's only a certain chance a team will be sent
- if(!prob(send_team_chance))
- command_announcement.Announce("It would appear that an emergency response team was requested for [station_name()]. Unfortunately, we were unable to send one at this time.", "[current_map.boss_name]")
- can_call_ert = 0 // Only one call per round, ladies.
- return
-
- command_announcement.Announce("It would appear that an emergency response team was requested for [station_name()]. We will prepare and send one as soon as possible.", "[current_map.boss_name]")
-
- if(!forced_choice)
- var/random_team = pick("NanoTrasen Response Team", "Tau Ceti Foreign Legion")
- ert_type = random_team
-
- can_call_ert = 0 // Only one call per round, gentleman.
- send_emergency_team = 1
-
- sleep(600 * 5)
- send_emergency_team = 0 // Can no longer join the ERT.
- ert_type = "NanoTrasen Response Team"
\ No newline at end of file
diff --git a/code/modules/security levels/keycard authentication.dm b/code/modules/security levels/keycard authentication.dm
index 642aa28c142..77f0c96a5b8 100644
--- a/code/modules/security levels/keycard authentication.dm
+++ b/code/modules/security levels/keycard authentication.dm
@@ -154,7 +154,7 @@
to_chat(usr, "All emergency response teams are dispatched and can not be called at this time.")
return
- trigger_armed_response_team(1)
+ SSresponseteam.trigger_armed_response_team()
feedback_inc("alert_keycard_auth_ert",1)
/obj/machinery/keycard_auth/proc/is_ert_blocked()
diff --git a/config/example/config.txt b/config/example/config.txt
index 0bd0ab6d356..a25d92c7b3a 100644
--- a/config/example/config.txt
+++ b/config/example/config.txt
@@ -521,3 +521,13 @@ FORCE_MAP aurora
# 0 - do this after every round.
# n - do this every n rounds.
#ROUNDS_UNTIL_HARD_RESTART -1
+
+ERT_BASE_CHANCE 10
+ERT_GREEN_INC 1
+ERT_YELLOW_INC 1
+ERT_BLUE_INC 2
+ERT_RED_INC 3
+ERT_DELTA_INC 10
+ERT_SCALING_FACTOR 1
+ERT_SCALING_FACTOR_ANTAG 1
+ERT_SCALING_FACTOR_DEAD 2
\ No newline at end of file
diff --git a/html/changelogs/arrow768-ert-chance.yml b/html/changelogs/arrow768-ert-chance.yml
new file mode 100644
index 00000000000..2aa80056223
--- /dev/null
+++ b/html/changelogs/arrow768-ert-chance.yml
@@ -0,0 +1,41 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+# balance
+# admin
+# backend
+# security
+# refactor
+#################################
+
+# Your name.
+author: Arrow768
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - tweak: "The chance to get a ERT or the TCFL is now based on the progression of the round."