From a4a9c82b6bb7ed6f63be04ff3b82017015ec99e2 Mon Sep 17 00:00:00 2001
From: Crystalic <39885003+blackcrystall@users.noreply.github.com>
Date: Fri, 28 Jun 2024 21:27:47 +0500
Subject: [PATCH] roles in list
---
code/datums/emergency_calls/cryo_marines.dm | 2 +-
.../emergency_calls/cryo_marines_heavy.dm | 2 +-
code/game/gamemodes/cm_initialize.dm | 8 +-
code/game/jobs/job/marine/squad/engineer.dm | 12 +-
code/game/jobs/job/marine/squad/medic.dm | 12 +-
code/game/jobs/job/marine/squads.dm | 303 +++++++++--------
code/game/jobs/role_authority.dm | 308 ++++--------------
code/modules/mob/new_player/new_player.dm | 8 +-
8 files changed, 240 insertions(+), 415 deletions(-)
diff --git a/code/datums/emergency_calls/cryo_marines.dm b/code/datums/emergency_calls/cryo_marines.dm
index fb8d4b8a5a69..ff8d7e2cc26e 100644
--- a/code/datums/emergency_calls/cryo_marines.dm
+++ b/code/datums/emergency_calls/cryo_marines.dm
@@ -44,7 +44,7 @@
sleep(5)
var/datum/squad/marine/cryo/cryo_squad = GLOB.RoleAuthority.squads_by_type[/datum/squad/marine/cryo]
- if(leaders < cryo_squad.max_leaders && (!mind || (HAS_FLAG(human.client.prefs.toggles_ert, PLAY_LEADER) && check_timelock(human.client, JOB_SQUAD_LEADER, time_required_for_job))))
+ if(leaders < cryo_squad.roles_cap[JOB_SQUAD_LEADER] && (!mind || (HAS_FLAG(human.client.prefs.toggles_ert, PLAY_LEADER) && check_timelock(human.client, JOB_SQUAD_LEADER, time_required_for_job))))
leader = human
leaders++
human.client?.prefs.copy_all_to(human, JOB_SQUAD_LEADER, TRUE, TRUE)
diff --git a/code/datums/emergency_calls/cryo_marines_heavy.dm b/code/datums/emergency_calls/cryo_marines_heavy.dm
index 42f25a461254..14155cdd8673 100644
--- a/code/datums/emergency_calls/cryo_marines_heavy.dm
+++ b/code/datums/emergency_calls/cryo_marines_heavy.dm
@@ -36,7 +36,7 @@
sleep(5)
var/datum/squad/marine/cryo/cryo_squad = GLOB.RoleAuthority.squads_by_type[/datum/squad/marine/cryo]
- if(leaders < cryo_squad.max_leaders && HAS_FLAG(H.client.prefs.toggles_ert, PLAY_LEADER) && check_timelock(H.client, JOB_SQUAD_LEADER, time_required_for_job))
+ if(leaders < cryo_squad.roles_cap[JOB_SQUAD_LEADER] && HAS_FLAG(H.client.prefs.toggles_ert, PLAY_LEADER) && check_timelock(H.client, JOB_SQUAD_LEADER, time_required_for_job))
leader = H
leaders++
arm_equipment(H, /datum/equipment_preset/uscm/leader_equipped/cryo, TRUE, TRUE)
diff --git a/code/game/gamemodes/cm_initialize.dm b/code/game/gamemodes/cm_initialize.dm
index ae6cdf10c64e..84d5dc84b75f 100644
--- a/code/game/gamemodes/cm_initialize.dm
+++ b/code/game/gamemodes/cm_initialize.dm
@@ -119,10 +119,10 @@ Additional game mode variables.
xeno_starting_num = clamp((GLOB.readied_players/CONFIG_GET(number/xeno_number_divider)), xeno_required_num, INFINITY) //(n, minimum, maximum)
surv_starting_num = clamp((GLOB.readied_players/CONFIG_GET(number/surv_number_divider)), 2, 8) //this doesnt run
marine_starting_num = GLOB.player_list.len - xeno_starting_num - surv_starting_num
- for(var/datum/squad/sq in GLOB.RoleAuthority.squads)
- if(sq)
- sq.max_engineers = engi_slot_formula(marine_starting_num)
- sq.max_medics = medic_slot_formula(marine_starting_num)
+ for(var/datum/squad/target_squad in GLOB.RoleAuthority.squads)
+ if(target_squad)
+ target_squad.roles_cap[JOB_SQUAD_ENGI] = engi_slot_formula(marine_starting_num)
+ target_squad.roles_cap[JOB_SQUAD_MEDIC] = medic_slot_formula(marine_starting_num)
for(var/i in GLOB.RoleAuthority.roles_by_name)
var/datum/job/J = GLOB.RoleAuthority.roles_by_name[i]
diff --git a/code/game/jobs/job/marine/squad/engineer.dm b/code/game/jobs/job/marine/squad/engineer.dm
index a4422572f218..d3e3946a2d78 100644
--- a/code/game/jobs/job/marine/squad/engineer.dm
+++ b/code/game/jobs/job/marine/squad/engineer.dm
@@ -8,9 +8,9 @@
entry_message_body = "You have the equipment and skill to build fortifications, reroute power lines, and bunker down. Your squaddies will look to you when it comes to construction in the field of battle."
/datum/job/marine/engineer/set_spawn_positions(count)
- for(var/datum/squad/sq in GLOB.RoleAuthority.squads)
- if(sq)
- sq.max_engineers = engi_slot_formula(count)
+ for(var/datum/squad/target_squad in GLOB.RoleAuthority.squads)
+ if(target_squad)
+ target_squad.roles_cap[JOB_SQUAD_ENGI] = engi_slot_formula(count)
/datum/job/marine/engineer/get_total_positions(latejoin=0)
var/slots = engi_slot_formula(get_total_marines())
@@ -21,9 +21,9 @@
total_positions_so_far = slots
if(latejoin)
- for(var/datum/squad/sq in GLOB.RoleAuthority.squads)
- if(sq)
- sq.max_engineers = slots
+ for(var/datum/squad/target_squad in GLOB.RoleAuthority.squads)
+ if(target_squad)
+ target_squad.roles_cap[JOB_SQUAD_ENGI] = slots
return (slots*4)
diff --git a/code/game/jobs/job/marine/squad/medic.dm b/code/game/jobs/job/marine/squad/medic.dm
index 450d1176658f..b30dc7c6434c 100644
--- a/code/game/jobs/job/marine/squad/medic.dm
+++ b/code/game/jobs/job/marine/squad/medic.dm
@@ -8,9 +8,9 @@
entry_message_body = "You tend the wounds of your squad mates and make sure they are healthy and active. You may not be a fully-fledged doctor, but you stand between life and death when it matters."
/datum/job/marine/medic/set_spawn_positions(count)
- for(var/datum/squad/sq in GLOB.RoleAuthority.squads)
- if(sq)
- sq.max_medics = medic_slot_formula(count)
+ for(var/datum/squad/target_squad in GLOB.RoleAuthority.squads)
+ if(target_squad)
+ target_squad.roles_cap[JOB_SQUAD_MEDIC] = medic_slot_formula(count)
/datum/job/marine/medic/get_total_positions(latejoin=0)
var/slots = medic_slot_formula(get_total_marines())
@@ -21,9 +21,9 @@
total_positions_so_far = slots
if(latejoin)
- for(var/datum/squad/sq in GLOB.RoleAuthority.squads)
- if(sq)
- sq.max_medics = slots
+ for(var/datum/squad/target_squad in GLOB.RoleAuthority.squads)
+ if(target_squad)
+ target_squad.roles_cap[JOB_SQUAD_MEDIC] = slots
return (slots*4)
diff --git a/code/game/jobs/job/marine/squads.dm b/code/game/jobs/job/marine/squads.dm
index 3285e75e45c3..b6f26c75f750 100644
--- a/code/game/jobs/job/marine/squads.dm
+++ b/code/game/jobs/job/marine/squads.dm
@@ -43,21 +43,19 @@
var/list/access = list()
/// Can use any squad vendor regardless of squad connection
var/omni_squad_vendor = FALSE
- /// maximum # of engineers allowed in the squad
- var/max_engineers = 3
- /// maximum # of squad medics allowed in the squad
- var/max_medics = 4
- /// maximum # of specs allowed in the squad
- var/max_specialists = 1
- /// maximum # of fireteam leaders allowed in the suqad
- var/max_tl = 2
- /// maximum # of smartgunners allowed in the squad
- var/max_smartgun = 1
- /// maximum # of squad leaders allowed in the squad
- var/max_leaders = 1
+ /// Squad roles max caps per role list
+ var/list/roles_cap = list(
+ JOB_SQUAD_ENGI = 3,
+ JOB_SQUAD_MEDIC = 4,
+ JOB_SQUAD_SMARTGUN = 1,
+ JOB_SQUAD_SPECIALIST = 1,
+ JOB_SQUAD_TEAM_LEADER = 2,
+ JOB_SQUAD_LEADER = 1,
+ )
+ /// Squad roles actual number of players list
+ var/list/roles_in = list()
/// Squad headsets default radio frequency
var/radio_freq = 1461
-
/// Whether this squad can be used by marines
var/usable = FALSE
/// Whether this squad can be picked at roundstart
@@ -190,12 +188,14 @@
roundstart = FALSE
prepend_squad_name_to_assignment = FALSE
- max_engineers = 0
- max_medics = 0
- max_specialists = 0
- max_tl = 0
- max_smartgun = 0
- max_leaders = 0
+ roles_cap = list(
+ JOB_SQUAD_ENGI = 0,
+ JOB_SQUAD_MEDIC = 0,
+ JOB_SQUAD_SMARTGUN = 0,
+ JOB_SQUAD_SPECIALIST = 0,
+ JOB_SQUAD_TEAM_LEADER = 0,
+ JOB_SQUAD_LEADER = 0,
+ )
/datum/squad/marine/sof
name = SQUAD_SOF
@@ -317,15 +317,15 @@
break
/// Sets an overwatch officer for the squad, returning TRUE on success
-/datum/squad/proc/assume_overwatch(mob/M)
+/datum/squad/proc/assume_overwatch(mob/target_mob)
var/mob/previous
if(overwatch_officer)
- if(overwatch_officer == M)
+ if(overwatch_officer == target_mob)
return FALSE
previous = overwatch_officer
overwatch_officer = null
clear_ref_tracking(previous)
- overwatch_officer = M
+ overwatch_officer = target_mob
RegisterSignal(overwatch_officer, COMSIG_PARENT_QDELETING, PROC_REF(personnel_deleted), override = TRUE)
return TRUE
@@ -339,30 +339,31 @@
return TRUE
/// Clear deletion signal as needed for mob - to call *after* removal
-/datum/squad/proc/clear_ref_tracking(mob/M)
- if(!M) return FALSE
- if(M in marines_list)
+/datum/squad/proc/clear_ref_tracking(mob/target_mob)
+ if(!target_mob)
+ return FALSE
+ if(target_mob in marines_list)
return FALSE
- if(overwatch_officer == M)
+ if(overwatch_officer == target_mob)
return FALSE
- UnregisterSignal(M, COMSIG_PARENT_QDELETING)
+ UnregisterSignal(target_mob, COMSIG_PARENT_QDELETING)
return TRUE
/// Clear references in squad listing upon deletion. Zap also erases the kept records.
/// NOTE: zap will be set true for a forced COMSIG_PARENT_QDELETING
-/datum/squad/proc/personnel_deleted(mob/M, zap = FALSE)
+/datum/squad/proc/personnel_deleted(mob/target_mob, zap = FALSE)
SIGNAL_HANDLER
- if(M == overwatch_officer)
+ if(target_mob == overwatch_officer)
overwatch_officer = null
- if(M == squad_leader)
+ if(target_mob == squad_leader)
squad_leader = null
- SStracking.stop_tracking(tracking_id, M)
+ SStracking.stop_tracking(tracking_id, target_mob)
if(zap)
- marines_list.Remove(M)
+ marines_list.Remove(target_mob)
return
- var/idx = marines_list.Find(M)
+ var/idx = marines_list.Find(target_mob)
if(idx)
- marines_list[idx] = M.name // legacy behavior, replace mob ref index by name. very weird
+ marines_list[idx] = target_mob.name // legacy behavior, replace mob ref index by name. very weird
/*
* Send a text message to the squad members following legacy overwatch usage
@@ -388,9 +389,9 @@
if(leader_only)
targets = list(squad_leader)
else
- for(var/mob/M in marines_list)
- if(!M.stat && M.client)
- targets += M.client
+ for(var/mob/target_mob in marines_list)
+ if(!target_mob.stat && target_mob.client)
+ targets += target_mob.client
if(displayed_icon)
message = "[icon2html(displayed_icon, targets, dir = null)] [message]"
@@ -428,73 +429,64 @@
to_chat(SL, "[SPAN_BLUE("SL Overwatch: [nametext][text]")]", type = MESSAGE_TYPE_RADIO)
return
else
- for(var/mob/living/carbon/human/M in marines_list)
- if(!M.stat && M.client) //Only living and connected people in our squad
+ for(var/mob/living/carbon/human/target_mob in marines_list)
+ if(!target_mob.stat && target_mob.client) //Only living and connected people in our squad
if(plus_name)
- M << sound('sound/effects/tech_notification.ogg')
- to_chat(M, "[SPAN_BLUE("Overwatch: [nametext][text]")]", type = MESSAGE_TYPE_RADIO)
+ target_mob << sound('sound/effects/tech_notification.ogg')
+ to_chat(target_mob, "[SPAN_BLUE("Overwatch: [nametext][text]")]", type = MESSAGE_TYPE_RADIO)
//Straight-up insert a marine into a squad.
//This sets their ID, increments the total count, and so on. Everything else is done in job_controller.dm.
//So it does not check if the squad is too full already, or randomize it, etc.
-/datum/squad/proc/put_marine_in_squad(mob/living/carbon/human/M, obj/item/card/id/ID)
-
- if(!istype(M))
+/datum/squad/proc/put_marine_in_squad(mob/living/carbon/human/target_mob, obj/item/card/id/id_card)
+ if(!istype(target_mob))
return FALSE //Logic
- if(!src.usable)
+ if(!usable)
return FALSE
- if(!M.job)
+ if(!target_mob.job)
return FALSE //Not yet
- if(M.assigned_squad)
+ if(target_mob.assigned_squad)
return FALSE //already in a squad
- var/obj/item/card/id/C = ID
- if(!C)
- C = M.get_idcard()
- if(!C)
- C = M.get_active_hand()
- if(!istype(C))
+ if(!id_card)
+ id_card = target_mob.wear_id
+ if(!id_card)
+ id_card = target_mob.get_active_hand()
+
+ if(!istype(id_card))
return FALSE //No ID found
- var/assignment = M.job
+ var/assignment = target_mob.job
var/paygrade
var/list/extra_access = list()
- switch(GET_DEFAULT_ROLE(M.job))
+ var/mob_role = GET_DEFAULT_ROLE(target_mob.job)
+ switch(mob_role)
if(JOB_SQUAD_ENGI)
assignment = JOB_SQUAD_ENGI
- num_engineers++
- C.claimedgear = FALSE
+ id_card.claimedgear = FALSE
if(JOB_SQUAD_MEDIC)
assignment = JOB_SQUAD_MEDIC
- num_medics++
- C.claimedgear = FALSE
+ id_card.claimedgear = FALSE
if(JOB_SQUAD_SPECIALIST)
assignment = JOB_SQUAD_SPECIALIST
- num_specialists++
if(JOB_SQUAD_TEAM_LEADER)
assignment = JOB_SQUAD_TEAM_LEADER
- num_tl++
- M.important_radio_channels += radio_freq
+ target_mob.important_radio_channels += radio_freq
if(JOB_SQUAD_SMARTGUN)
assignment = JOB_SQUAD_SMARTGUN
- num_smartgun++
if(JOB_SQUAD_LEADER)
if(squad_leader && GET_DEFAULT_ROLE(squad_leader.job) != JOB_SQUAD_LEADER) //field promoted SL
var/old_lead = squad_leader
demote_squad_leader() //replaced by the real one
SStracking.start_tracking(tracking_id, old_lead)
assignment = squad_type + " Leader"
- squad_leader = M
- SStracking.set_leader(tracking_id, M)
- SStracking.start_tracking("marine_sl", M)
-
- if(GET_DEFAULT_ROLE(M.job) == JOB_SQUAD_LEADER) //field promoted SL don't count as real ones
- num_leaders++
-
+ squad_leader = target_mob
+ SStracking.set_leader(tracking_id, target_mob)
+ SStracking.start_tracking("marine_sl", target_mob)
if(JOB_MARINE_RAIDER)
assignment = JOB_MARINE_RAIDER
if(name == JOB_MARINE_RAIDER)
@@ -507,85 +499,86 @@
demote_squad_leader() //replaced by the real one
SStracking.start_tracking(tracking_id, old_lead)
assignment = squad_type + " Leader"
- squad_leader = M
- SStracking.set_leader(tracking_id, M)
- SStracking.start_tracking("marine_sl", M)
- if(GET_DEFAULT_ROLE(M.job) == JOB_MARINE_RAIDER_SL) //field promoted SL don't count as real ones
- num_leaders++
+ squad_leader = target_mob
+ SStracking.set_leader(tracking_id, target_mob)
+ SStracking.start_tracking("marine_sl", target_mob)
+ mob_role = JOB_SQUAD_LEADER
if(JOB_MARINE_RAIDER_CMD)
assignment = JOB_MARINE_RAIDER_CMD
if(name == JOB_MARINE_RAIDER)
assignment = "Officer"
- RegisterSignal(M, COMSIG_PARENT_QDELETING, PROC_REF(personnel_deleted), override = TRUE)
+ if(mob_role in roles_cap)
+ roles_in[mob_role]++
+
+ RegisterSignal(target_mob, COMSIG_PARENT_QDELETING, PROC_REF(personnel_deleted), override = TRUE)
if(assignment != JOB_SQUAD_LEADER)
- SStracking.start_tracking(tracking_id, M)
+ SStracking.start_tracking(tracking_id, target_mob)
count++ //Add up the tally. This is important in even squad distribution.
- if(GET_DEFAULT_ROLE(M.job) != JOB_SQUAD_MARINE)
- log_admin("[key_name(M)] has been assigned as [name] [M.job]") // we don't want to spam squad marines but the others are useful
+ if(GET_DEFAULT_ROLE(target_mob.job) != JOB_SQUAD_MARINE)
+ log_admin("[key_name(target_mob)] has been assigned as [name] [target_mob.job]") // we don't want to spam squad marines but the others are useful
- marines_list += M
- M.assigned_squad = src //Add them to the squad
- C.access += (src.access + extra_access) //Add their squad access to their ID
+ marines_list += target_mob
+ target_mob.assigned_squad = src //Add them to the squad
+ id_card.access += (src.access + extra_access) //Add their squad access to their ID
if(prepend_squad_name_to_assignment)
- C.assignment = "[name] [assignment]"
+ id_card.assignment = "[name] [assignment]"
else
- C.assignment = assignment
+ id_card.assignment = assignment
- SEND_SIGNAL(M, COMSIG_SET_SQUAD)
+ SEND_SIGNAL(target_mob, COMSIG_SET_SQUAD)
if(paygrade)
- C.paygrade = paygrade
- C.name = "[C.registered_name]'s ID Card ([C.assignment])"
+ id_card.paygrade = paygrade
+ id_card.name = "[id_card.registered_name]'s ID Card ([id_card.assignment])"
- var/obj/item/device/radio/headset/almayer/marine/headset = locate() in list(M.wear_l_ear, M.wear_r_ear)
+ var/obj/item/device/radio/headset/almayer/marine/headset = locate() in list(target_mob.wear_l_ear, target_mob.wear_r_ear)
if(headset && radio_freq)
headset.set_frequency(radio_freq)
- M.update_inv_head()
- M.update_inv_wear_suit()
- M.update_inv_gloves()
+ target_mob.update_inv_head()
+ target_mob.update_inv_wear_suit()
+ target_mob.update_inv_gloves()
return TRUE
//proc used by the overwatch console to transfer marine to another squad
-/datum/squad/proc/remove_marine_from_squad(mob/living/carbon/human/M, obj/item/card/id/ID)
- if(M.assigned_squad != src)
+/datum/squad/proc/remove_marine_from_squad(mob/living/carbon/human/target_mob, obj/item/card/id/id_card)
+ if(target_mob.assigned_squad != src)
return //not assigned to the correct squad
- var/obj/item/card/id/C = ID
- if(!istype(C))
- C = M.get_idcard()
- if(!istype(C))
+ if(!istype(id_card))
+ id_card = target_mob.get_idcard()
+ if(!istype(id_card))
return FALSE //Abort, no ID found
- C.access -= src.access
- C.assignment = M.job
- C.name = "[C.registered_name]'s ID Card ([C.assignment])"
+ id_card.access -= src.access
+ id_card.assignment = target_mob.job
+ id_card.name = "[id_card.registered_name]'s ID Card ([id_card.assignment])"
- forget_marine_in_squad(M)
+ forget_marine_in_squad(target_mob)
//gracefully remove a marine from squad system, alive, dead or otherwise
-/datum/squad/proc/forget_marine_in_squad(mob/living/carbon/human/M)
- if(M.assigned_squad.squad_leader == M)
- if(GET_DEFAULT_ROLE(M.job) != JOB_SQUAD_LEADER) //a field promoted SL, not a real one
+/datum/squad/proc/forget_marine_in_squad(mob/living/carbon/human/target_mob)
+ if(target_mob.assigned_squad.squad_leader == target_mob)
+ if(GET_DEFAULT_ROLE(target_mob.job) != JOB_SQUAD_LEADER) //a field promoted SL, not a real one
demote_squad_leader()
else
- M.assigned_squad.squad_leader = null
+ target_mob.assigned_squad.squad_leader = null
update_squad_leader()
else
- if(M.assigned_fireteam)
- if(fireteam_leaders[M.assigned_fireteam] == M)
- unassign_ft_leader(M.assigned_fireteam, TRUE, FALSE)
- unassign_fireteam(M, FALSE)
+ if(target_mob.assigned_fireteam)
+ if(fireteam_leaders[target_mob.assigned_fireteam] == target_mob)
+ unassign_ft_leader(target_mob.assigned_fireteam, TRUE, FALSE)
+ unassign_fireteam(target_mob, FALSE)
count--
- marines_list -= M
- personnel_deleted(M, zap = TRUE) // Free all refs and Zap it entierly as this is on purpose
- clear_ref_tracking(M)
+ marines_list -= target_mob
+ personnel_deleted(target_mob, zap = TRUE) // Free all refs and Zap it entierly as this is on purpose
+ clear_ref_tracking(target_mob)
update_free_mar()
- M.assigned_squad = null
+ target_mob.assigned_squad = null
- switch(GET_DEFAULT_ROLE(M.job))
+ switch(GET_DEFAULT_ROLE(target_mob.job))
if(JOB_SQUAD_ENGI)
num_engineers--
if(JOB_SQUAD_MEDIC)
@@ -758,13 +751,13 @@
SStracking.start_tracking(new_id, H)
//moved the main proc for ft management from human.dm here to make it support both examine and squad info way to edit fts
-/datum/squad/proc/manage_fireteams(mob/living/carbon/human/target)
- var/obj/item/card/id/ID = target.get_idcard()
+/datum/squad/proc/manage_fireteams(mob/living/carbon/human/target_mob)
+ var/obj/item/card/id/ID = target_mob.get_idcard()
if(!ID || !(ID.rank in GLOB.ROLES_MARINES))
return
- if(ID.rank == JOB_SQUAD_LEADER || squad_leader == target) //if SL/aSL are chosen
+ if(ID.rank == JOB_SQUAD_LEADER || squad_leader == target_mob) //if SL/aSL are chosen
var/choice = tgui_input_list(squad_leader, "Manage Fireteams and Team leaders.", "Fireteams Management", list("Cancel", "Unassign Fireteam 1 Leader", "Unassign Fireteam 2 Leader", "Unassign Fireteam 3 Leader", "Unassign all Team Leaders"))
- if(target.assigned_squad != src)
+ if(target_mob.assigned_squad != src)
return //in case they somehow change squad while SL is choosing
if(squad_leader.is_mob_incapacitated() || !hasHUD(squad_leader,"squadleader"))
return //if SL got knocked out or demoted while choosing
@@ -774,77 +767,77 @@
if("Unassign Fireteam 3 Leader") unassign_ft_leader("FT3", TRUE)
if("Unassign all Team Leaders") unassign_all_ft_leaders()
else return
- target.hud_set_squad()
+ target_mob.hud_set_squad()
return
- if(target.assigned_fireteam)
- if(fireteam_leaders[target.assigned_fireteam] == target) //Check if person already is FT leader
+ if(target_mob.assigned_fireteam)
+ if(fireteam_leaders[target_mob.assigned_fireteam] == target_mob) //Check if person already is FT leader
var/choice = tgui_input_list(squad_leader, "Manage Fireteams and Team leaders.", "Fireteams Management", list("Cancel", "Unassign from Team Leader position"))
- if(target.assigned_squad != src)
+ if(target_mob.assigned_squad != src)
return
if(squad_leader.is_mob_incapacitated() || !hasHUD(squad_leader,"squadleader"))
return
if(choice == "Unassign from Team Leader position")
- unassign_ft_leader(target.assigned_fireteam, TRUE)
- target.hud_set_squad()
+ unassign_ft_leader(target_mob.assigned_fireteam, TRUE)
+ target_mob.hud_set_squad()
return
var/choice = tgui_input_list(squad_leader, "Manage Fireteams and Team leaders.", "Fireteams Management", list("Remove from Fireteam", "Assign to Fireteam 1", "Assign to Fireteam 2", "Assign to Fireteam 3", "Assign as Team Leader"))
- if(target.assigned_squad != src)
+ if(target_mob.assigned_squad != src)
return
if(squad_leader.is_mob_incapacitated() || !hasHUD(squad_leader,"squadleader"))
return
switch(choice)
- if("Remove from Fireteam") unassign_fireteam(target)
- if("Assign to Fireteam 1") assign_fireteam("FT1", target)
- if("Assign to Fireteam 2") assign_fireteam("FT2", target)
- if("Assign to Fireteam 3") assign_fireteam("FT3", target)
- if("Assign as Team Leader") assign_ft_leader(target.assigned_fireteam, target)
+ if("Remove from Fireteam") unassign_fireteam(target_mob)
+ if("Assign to Fireteam 1") assign_fireteam("FT1", target_mob)
+ if("Assign to Fireteam 2") assign_fireteam("FT2", target_mob)
+ if("Assign to Fireteam 3") assign_fireteam("FT3", target_mob)
+ if("Assign as Team Leader") assign_ft_leader(target_mob.assigned_fireteam, target_mob)
else return
- target.hud_set_squad()
+ target_mob.hud_set_squad()
return
var/choice = tgui_input_list(squad_leader, "Manage Fireteams and Team leaders.", "Fireteams Management", list("Cancel", "Assign to Fireteam 1", "Assign to Fireteam 2", "Assign to Fireteam 3"))
- if(target.assigned_squad != src)
+ if(target_mob.assigned_squad != src)
return
if(squad_leader.is_mob_incapacitated() || !hasHUD(squad_leader,"squadleader"))
return
switch(choice)
- if("Assign to Fireteam 1") assign_fireteam("FT1", target)
- if("Assign to Fireteam 2") assign_fireteam("FT2", target)
- if("Assign to Fireteam 3") assign_fireteam("FT3", target)
+ if("Assign to Fireteam 1") assign_fireteam("FT1", target_mob)
+ if("Assign to Fireteam 2") assign_fireteam("FT2", target_mob)
+ if("Assign to Fireteam 3") assign_fireteam("FT3", target_mob)
else return
- target.hud_set_squad()
+ target_mob.hud_set_squad()
return
//Managing MIA and KIA statuses for marines
-/datum/squad/proc/change_squad_status(mob/living/carbon/human/target)
- if(target == squad_leader)
+/datum/squad/proc/change_squad_status(mob/living/carbon/human/target_mob)
+ if(target_mob == squad_leader)
return //you can't mark yourself KIA
var/choice = tgui_input_list(squad_leader, "Marine status management: M.I.A. for missing marines, K.I.A. for confirmed unrevivable dead.", "Squad Management", list("Cancel", "Remove status", "M.I.A.", "K.I.A."))
- if(target.assigned_squad != src)
+ if(target_mob.assigned_squad != src)
return //in case they somehow change squad while SL is choosing
if(squad_leader.is_mob_incapacitated() || !hasHUD(squad_leader,"squadleader"))
return //if SL got knocked out or demoted while choosing
switch(choice)
- if("Remove status") target.squad_status = null
+ if("Remove status") target_mob.squad_status = null
if("M.I.A.")
- target.squad_status = choice
- to_chat(squad_leader, FONT_SIZE_BIG(SPAN_BLUE("You set [target]'s status as Missing In Action.")))
- if(target.stat == CONSCIOUS)
- to_chat(target, FONT_SIZE_HUGE(SPAN_BLUE("You were marked as Missing In Action by Squad Leader.")))
+ target_mob.squad_status = choice
+ to_chat(squad_leader, FONT_SIZE_BIG(SPAN_BLUE("You set [target_mob]'s status as Missing In Action.")))
+ if(target_mob.stat == CONSCIOUS)
+ to_chat(target_mob, FONT_SIZE_HUGE(SPAN_BLUE("You were marked as Missing In Action by Squad Leader.")))
if("K.I.A.")
- target.squad_status = choice
- if(target.assigned_fireteam)
- if(fireteam_leaders[target.assigned_fireteam] == target)
- unassign_ft_leader(target.assigned_fireteam, TRUE, FALSE)
- unassign_fireteam(target, FALSE)
- to_chat(squad_leader, FONT_SIZE_BIG(SPAN_BLUE("You set [target]'s status as Killed In Action. If they were Team Leader or in fireteam, they were demoted and unassigned.")))
- if(target.stat == CONSCIOUS)
- to_chat(target, FONT_SIZE_HUGE(SPAN_BLUE("You were marked as Killed In Action by Squad Leader.")))
+ target_mob.squad_status = choice
+ if(target_mob.assigned_fireteam)
+ if(fireteam_leaders[target_mob.assigned_fireteam] == target_mob)
+ unassign_ft_leader(target_mob.assigned_fireteam, TRUE, FALSE)
+ unassign_fireteam(target_mob, FALSE)
+ to_chat(squad_leader, FONT_SIZE_BIG(SPAN_BLUE("You set [target_mob]'s status as Killed In Action. If they were Team Leader or in fireteam, they were demoted and unassigned.")))
+ if(target_mob.stat == CONSCIOUS)
+ to_chat(target_mob, FONT_SIZE_HUGE(SPAN_BLUE("You were marked as Killed In Action by Squad Leader.")))
else return
- if(target.assigned_fireteam)
- update_fireteam(target.assigned_fireteam)
+ if(target_mob.assigned_fireteam)
+ update_fireteam(target_mob.assigned_fireteam)
else
update_free_mar()
- target.hud_set_squad()
+ target_mob.hud_set_squad()
return
diff --git a/code/game/jobs/role_authority.dm b/code/game/jobs/role_authority.dm
index a9017e2cc8d3..0da8b84bf1cd 100644
--- a/code/game/jobs/role_authority.dm
+++ b/code/game/jobs/role_authority.dm
@@ -375,65 +375,35 @@ I hope it's easier to tell what the heck this proc is even doing, unlike previou
J.current_positions--
return 1
-/datum/authority/branch/role/proc/free_role_admin(datum/job/J, latejoin = 1, user) //Specific proc that used for admin "Free Job Slots" verb (round tab)
- if(!istype(J) || J.total_positions == -1)
+/datum/authority/branch/role/proc/free_role_admin(datum/job/job, latejoin = TRUE, user) //Specific proc that used for admin "Free Job Slots" verb (round tab)
+ if(!istype(job) || job.total_positions == -1)
return
- if(J.current_positions < 1) //this should be filtered earlier, but we still check just in case
- to_chat(user, "There are no [J] job slots occupied.")
+ if(job.current_positions < 1) //this should be filtered earlier, but we still check just in case
+ to_chat(user, "There are no [job] job slots occupied.")
return
//here is the main reason this proc exists - to remove freed squad jobs from squad,
//so latejoining person ends in the squad which's job was freed and not random one
- var/datum/squad/sq = null
- if(GLOB.job_squad_roles.Find(J.title))
+ var/datum/squad/squad = null
+ if(GLOB.job_squad_roles.Find(job.title))
var/list/squad_list = list()
- for(sq in GLOB.RoleAuthority.squads)
- if(sq.usable)
- squad_list += sq
- sq = null
- sq = input(user, "Select squad you want to free [J.title] slot from.", "Squad Selection") as null|anything in squad_list
- if(!sq)
+ for(squad in GLOB.RoleAuthority.squads)
+ if(squad.roundstart && squad.usable && squad.name != "Root")
+ squad_list += squad
+ squad = null
+ squad = tgui_input_list(user, "Select squad you want to free [job.title] slot from.", "Squad Selection", squad_list)
+ if(!squad)
return
- switch(J.title)
- if(JOB_SQUAD_ENGI)
- if(sq.num_engineers > 0)
- sq.num_engineers--
- else
- to_chat(user, "There are no [J.title] slots occupied in [sq.name] Squad.")
- return
- if(JOB_SQUAD_MEDIC)
- if(sq.num_medics > 0)
- sq.num_medics--
- else
- to_chat(user, "There are no [J.title] slots occupied in [sq.name] Squad.")
- return
- if(JOB_SQUAD_SPECIALIST)
- if(sq.num_specialists > 0)
- sq.num_specialists--
- else
- to_chat(user, "There are no [J.title] slots occupied in [sq.name] Squad.")
- return
- if(JOB_SQUAD_SMARTGUN)
- if(sq.num_smartgun > 0)
- sq.num_smartgun--
- else
- to_chat(user, "There are no [J.title] slots occupied in [sq.name] Squad.")
- return
- if(JOB_SQUAD_TEAM_LEADER)
- if(sq.num_tl > 0)
- sq.num_tl--
- else
- to_chat(user, "There are no [J.title] slots occupied in [sq.name] Squad.")
- return
- if(JOB_SQUAD_LEADER)
- if(sq.num_leaders > 0)
- sq.num_leaders--
- else
- to_chat(user, "There are no [J.title] slots occupied in [sq.name] Squad.")
- return
- J.current_positions--
- message_admins("[key_name(user)] freed the [J.title] job slot[sq ? " in [sq.name] Squad" : ""].")
- return 1
+
+ if(squad.roles_in[job.title] > 0)
+ squad.roles_in[job.title]--
+ else
+ to_chat(user, "There are no [job.title] slots occupied in [squad.name] Squad.")
+ return
+
+ job.current_positions--
+ message_admins("[key_name(user)] freed the [job.title] job slot[squad ? " in [squad.name] Squad" : ""].")
+ return TRUE
/datum/authority/branch/role/proc/modify_role(datum/job/J, amount)
if(!istype(J))
@@ -531,188 +501,66 @@ I hope it's easier to tell what the heck this proc is even doing, unlike previou
SEND_SIGNAL(new_human, COMSIG_POST_SPAWN_UPDATE)
SSround_recording.recorder.track_player(new_human)
-//Find which squad has the least population. If all 4 squads are equal it should just use a random one
-/datum/authority/branch/role/proc/get_lowest_squad(mob/living/carbon/human/H)
- if(!squads.len) //Something went wrong, our squads aren't set up.
- to_world("Warning, something messed up in get_lowest_squad(). No squads set up!")
- return null
-
-
- //we make a list of squad that is randomized so alpha isn't always lowest squad.
- var/list/squads_copy = squads.Copy()
- var/list/mixed_squads = list()
-
- for(var/i= 1 to squads_copy.len)
- var/datum/squad/S = pick_n_take(squads_copy)
- if (S.roundstart && S.usable && S.faction == H.faction && S.name != "Root")
- mixed_squads += S
-
- var/datum/squad/lowest = pick(mixed_squads)
-
- var/datum/pref_squad_name
- if(H && H.client && H.client.prefs.preferred_squad && H.client.prefs.preferred_squad != "None")
- pref_squad_name = H.client.prefs.preferred_squad
-
- for(var/datum/squad/L in mixed_squads)
- if(L.usable)
- if(pref_squad_name && L.name == pref_squad_name)
- lowest = L
- break
-
-
- if(!lowest)
- to_world("Warning! Bug in get_random_squad()!")
- return null
-
- var/lowest_count = lowest.count
- var/current_count = 0
-
- if(!pref_squad_name)
- //Loop through squads.
- for(var/datum/squad/S in mixed_squads)
- if(!S)
- to_world("Warning: Null squad in get_lowest_squad. Call a coder!")
- break //null squad somehow, let's just abort
- current_count = S.count //Grab our current squad's #
- if(current_count >= (lowest_count - 2)) //Current squad count is not much lower than the chosen one. Skip it.
- continue
- lowest_count = current_count //We found a winner! This squad is much lower than our default. Make it the new default.
- lowest = S //'Select' this squad.
-
- return lowest //Return whichever squad won the competition.
-
//This proc is a bit of a misnomer, since there's no actual randomization going on.
-/datum/authority/branch/role/proc/randomize_squad(mob/living/carbon/human/H, skip_limit = FALSE)
- if(!H)
+/datum/authority/branch/role/proc/randomize_squad(mob/living/carbon/human/human, skip_limit = FALSE)
+ if(!human)
return
- if(!squads.len)
- to_chat(H, "Something went wrong with your squad randomizer! Tell a coder!")
+ if(!length(squads))
+ to_chat(human, "Something went wrong with your squad randomizer! Tell a coder!")
return //Shit, where's our squad data
- if(H.assigned_squad) //Wait, we already have a squad. Get outta here!
+ if(human.assigned_squad) //Wait, we already have a squad. Get outta here!
return
- //we make a list of squad that is randomized so alpha isn't always lowest squad.
- var/list/squads_copy = squads.Copy()
- var/list/mixed_squads = list()
- // The following code removes non useable squads from the lists of squads we assign marines too.
- for(var/i= 1 to squads_copy.len)
- var/datum/squad/S = pick_n_take(squads_copy)
- if (S.roundstart && S.usable && S.faction == H.faction && S.name != "Root")
- mixed_squads += S
-
//Deal with IOs first
- if(H.job == JOB_INTEL)
+ if(human.job == JOB_INTEL)
var/datum/squad/intel_squad = get_squad_by_name(SQUAD_MARINE_INTEL)
if(!intel_squad || !istype(intel_squad)) //Something went horribly wrong!
- to_chat(H, "Something went wrong with randomize_squad()! Tell a coder!")
+ to_chat(human, "Something went wrong with randomize_squad()! Tell a coder!")
return
- intel_squad.put_marine_in_squad(H) //Found one, finish up
+ intel_squad.put_marine_in_squad(human)
return
- //Deal with non-standards first.
- //Non-standards are distributed regardless of squad population.
- //If the number of available positions for the job are more than max_whatever, it will break.
- //Ie. 8 squad medic jobs should be available, and total medics in squads should be 8.
- if(H.job != JOB_SQUAD_MARINE && H.job != "Reinforcements")
- var/pref_squad_name
- if(H && H.client && H.client.prefs.preferred_squad && H.client.prefs.preferred_squad != "None")
- pref_squad_name = H.client.prefs.preferred_squad
-
- var/datum/squad/lowest
-
- switch(H.job)
- if(JOB_SQUAD_ENGI)
- for(var/datum/squad/S in mixed_squads)
- if(S.usable && S.roundstart)
- if(!skip_limit && S.num_engineers >= S.max_engineers) continue
- if(pref_squad_name && S.name == pref_squad_name)
- S.put_marine_in_squad(H) //fav squad has a spot for us, no more searching needed.
- return
-
- if(!lowest)
- lowest = S
- else if(S.num_engineers < lowest.num_engineers)
- lowest = S
-
- if(JOB_SQUAD_MEDIC)
- for(var/datum/squad/S in mixed_squads)
- if(S.usable && S.roundstart)
- if(!skip_limit && S.num_medics >= S.max_medics) continue
- if(pref_squad_name && S.name == pref_squad_name)
- S.put_marine_in_squad(H) //fav squad has a spot for us.
- return
-
- if(!lowest)
- lowest = S
- else if(S.num_medics < lowest.num_medics)
- lowest = S
-
- if(JOB_SQUAD_LEADER)
- for(var/datum/squad/S in mixed_squads)
- if(S.usable && S.roundstart)
- if(!skip_limit && S.num_leaders >= S.max_leaders) continue
- if(pref_squad_name && S.name == pref_squad_name)
- S.put_marine_in_squad(H) //fav squad has a spot for us.
- return
-
- if(!lowest)
- lowest = S
- else if(S.num_leaders < lowest.num_leaders)
- lowest = S
-
- if(JOB_SQUAD_SPECIALIST)
- for(var/datum/squad/S in mixed_squads)
- if(S.usable && S.roundstart)
- if(!skip_limit && S.num_specialists >= S.max_specialists) continue
- if(pref_squad_name && S.name == pref_squad_name)
- S.put_marine_in_squad(H) //fav squad has a spot for us.
- return
-
- if(!lowest)
- lowest = S
- else if(S.num_specialists < lowest.num_specialists)
- lowest = S
-
- if(JOB_SQUAD_TEAM_LEADER)
- for(var/datum/squad/S in mixed_squads)
- if(S.usable && S.roundstart)
- if(!skip_limit && S.num_tl >= S.max_tl) continue
- if(pref_squad_name && S.name == pref_squad_name)
- S.put_marine_in_squad(H) //fav squad has a spot for us.
- return
-
- if(!lowest)
- lowest = S
- else if(S.num_tl < lowest.num_tl)
- lowest = S
-
- if(JOB_SQUAD_SMARTGUN)
- for(var/datum/squad/S in mixed_squads)
- if(S.usable && S.roundstart)
- if(!skip_limit && S.num_smartgun >= S.max_smartgun) continue
- if(pref_squad_name && S.name == pref_squad_name)
- S.put_marine_in_squad(H) //fav squad has a spot for us.
- return
-
- if(!lowest)
- lowest = S
- else if(S.num_smartgun < lowest.num_smartgun)
- lowest = S
+ var/slot_check
+ if(human.job != "Reinforcements")
+ slot_check = GET_DEFAULT_ROLE(human.job)
+
+ //we make a list of squad that is randomized so alpha isn't always lowest squad.
+ var/list/mixed_squads = list()
+ for(var/datum/squad/squad in squads)
+ if(squad.roundstart && squad.usable && squad.faction == human.faction && squad.name != "Root")
+ mixed_squads += squad
+
+ var/preferred_squad
+ if(human?.client?.prefs?.preferred_squad)
+ preferred_squad = human.client.prefs.preferred_squad
+
+ var/datum/squad/lowest
+ for(var/datum/squad/squad in mixed_squads)
+ if(slot_check && !skip_limit)
+ if(squad.roles_in[slot_check] >= squad.roles_cap[slot_check])
+ continue
+
+ if(preferred_squad == "None")
+ if(squad.put_marine_in_squad(human))
+ return
+
+ else if(squad.name == preferred_squad) //fav squad has a spot for us, no more searching needed.
+ if(squad.put_marine_in_squad(human))
+ return
+
if(!lowest)
- var/ranpick = rand(1,4)
- lowest = mixed_squads[ranpick]
- if(lowest) lowest.put_marine_in_squad(H)
- else to_chat(H, "Something went badly with randomize_squad()! Tell a coder!")
+ lowest = squad
- else
- //Deal with marines. They get distributed to the lowest populated squad.
- var/datum/squad/given_squad = get_lowest_squad(H)
- if(!given_squad || !istype(given_squad)) //Something went horribly wrong!
- to_chat(H, "Something went wrong with randomize_squad()! Tell a coder!")
- return
- given_squad.put_marine_in_squad(H) //Found one, finish up
+ else if(slot_check)
+ if(squad.roles_in[slot_check] < lowest.roles_in[slot_check])
+ lowest = squad
+
+ if(!lowest || !lowest.put_marine_in_squad(human))
+ to_world("Warning! Bug in get_random_squad()!")
+ return
+ return
/datum/authority/branch/role/proc/get_caste_by_text(name)
var/mob/living/carbon/xenomorph/M
@@ -803,23 +651,7 @@ I hope it's easier to tell what the heck this proc is even doing, unlike previou
// returns TRUE if transfer_marine's role is at max capacity in the new squad
/datum/authority/branch/role/proc/check_squad_capacity(mob/living/carbon/human/transfer_marine, datum/squad/new_squad)
- switch(transfer_marine.job)
- if(JOB_SQUAD_LEADER)
- if(new_squad.num_leaders >= new_squad.max_leaders)
- return TRUE
- if(JOB_SQUAD_SPECIALIST)
- if(new_squad.num_specialists >= new_squad.max_specialists)
- return TRUE
- if(JOB_SQUAD_ENGI)
- if(new_squad.num_engineers >= new_squad.max_engineers)
- return TRUE
- if(JOB_SQUAD_MEDIC)
- if(new_squad.num_medics >= new_squad.max_medics)
- return TRUE
- if(JOB_SQUAD_SMARTGUN)
- if(new_squad.num_smartgun >= new_squad.max_smartgun)
- return TRUE
- if(JOB_SQUAD_TEAM_LEADER)
- if(new_squad.num_tl >= new_squad.max_tl)
- return TRUE
+ if(transfer_marine.job in new_squad.roles_cap)
+ if(new_squad.roles_in[transfer_marine.job] >= new_squad.roles_cap[transfer_marine.job])
+ return TRUE
return FALSE
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index 1bdf075c938e..4afded82983f 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -262,10 +262,10 @@
SSticker.mode.latejoin_update(player_rank)
SSticker.mode.update_gear_scale()
- for(var/datum/squad/sq in GLOB.RoleAuthority.squads)
- if(sq)
- sq.max_engineers = engi_slot_formula(GLOB.clients.len)
- sq.max_medics = medic_slot_formula(GLOB.clients.len)
+ for(var/datum/squad/target_squad in GLOB.RoleAuthority.squads)
+ if(target_squad)
+ target_squad.roles_cap[JOB_SQUAD_ENGI] = engi_slot_formula(length(GLOB.clients))
+ target_squad.roles_cap[JOB_SQUAD_MEDIC] = medic_slot_formula(length(GLOB.clients))
var/latejoin_larva_drop = SSticker.mode.latejoin_larva_drop