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 4a208b00a796..465e956b4246 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 = length(GLOB.player_list) - 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..66b667aa133c 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[title] = 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[title] = 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..9161ee082d8c 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[title] = 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[title] = slots return (slots*4) diff --git a/code/game/jobs/job/marine/squads.dm b/code/game/jobs/job/marine/squads.dm index 75f6622506a9..3849c476d978 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 @@ -329,15 +329,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 @@ -351,30 +351,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 @@ -400,9 +401,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]" @@ -440,73 +441,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) @@ -519,85 +511,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) @@ -770,13 +763,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 @@ -786,77 +779,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 b4894eda4d24..ef06253fec25 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(!length(squads)) //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 length(squads_copy)) - 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(!length(squads)) - to_chat(H, "Something went wrong with your squad randomizer! Tell a coder!") + 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 length(squads_copy)) - 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 829379eb28b6..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(length(GLOB.clients)) - sq.max_medics = medic_slot_formula(length(GLOB.clients)) + 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