From 962aa9e79d09c6efa6998b473354fa68b51a9306 Mon Sep 17 00:00:00 2001 From: oranges Date: Fri, 28 Sep 2018 09:27:15 +1200 Subject: [PATCH] Merge pull request #40365 from AnturK/team-panel Admin team panel --- code/__HELPERS/roundend.dm | 8 +- code/datums/mind.dm | 35 +--- code/game/gamemodes/objective.dm | 27 ++- code/modules/admin/check_antagonists.dm | 3 +- code/modules/admin/team_panel.dm | 183 ++++++++++++++++++ code/modules/admin/topic.dm | 48 +++++ .../antagonists/_common/antag_datum.dm | 7 + .../modules/antagonists/_common/antag_team.dm | 7 + tgstation.dme | 1 + 9 files changed, 285 insertions(+), 34 deletions(-) create mode 100644 code/modules/admin/team_panel.dm diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 6facc15a3eb3..d37fc83dc6e9 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -410,11 +410,15 @@ var/list/all_teams = list() var/list/all_antagonists = list() + for(var/datum/team/A in GLOB.antagonist_teams) + if(!A.members) + continue + all_teams |= A + for(var/datum/antagonist/A in GLOB.antagonists) if(!A.owner) continue - all_teams |= A.get_team() - all_antagonists += A + all_antagonists |= A for(var/datum/team/T in all_teams) result += T.roundend_report() diff --git a/code/datums/mind.dm b/code/datums/mind.dm index b4ed849cf950..8533d3f16b7b 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -431,40 +431,15 @@ else target_antag = target - + if(!GLOB.admin_objective_list) + generate_admin_objective_list() - var/static/list/choices - if(!choices) - choices = list() - - var/list/allowed_types = list( - /datum/objective/assassinate, - /datum/objective/maroon, - /datum/objective/debrain, - /datum/objective/protect, - /datum/objective/destroy, - /datum/objective/hijack, - /datum/objective/escape, - /datum/objective/survive, - /datum/objective/martyr, - /datum/objective/steal, - /datum/objective/download, - /datum/objective/nuclear, - /datum/objective/capture, - /datum/objective/absorb, - /datum/objective/custom - ) - - for(var/T in allowed_types) - var/datum/objective/X = T - choices[initial(X.name)] = T - if(old_objective) - if(old_objective.name in choices) + if(old_objective.name in GLOB.admin_objective_list) def_value = old_objective.name - var/selected_type = input("Select objective type:", "Objective type", def_value) as null|anything in choices - selected_type = choices[selected_type] + var/selected_type = input("Select objective type:", "Objective type", def_value) as null|anything in GLOB.admin_objective_list + selected_type = GLOB.admin_objective_list[selected_type] if (!selected_type) return diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 88dbc6bfb9b0..6d77197b6e03 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -1,3 +1,5 @@ +GLOBAL_LIST(admin_objective_list) //Prefilled admin assignable objective list + /datum/objective var/datum/mind/owner //The primary owner of the objective. !!SOMEWHAT DEPRECATED!! Prefer using 'team' for new code. var/datum/team/team //An alternative to 'owner': a team. Use this when writing new code. @@ -985,5 +987,28 @@ GLOBAL_LIST_EMPTY(possible_items_special) explanation_text = "Have X or more heads of staff escape on the shuttle disguised as heads, while the real heads are dead" command_staff_only = TRUE +//Ideally this would be all of them but laziness and unusual subtypes +/proc/generate_admin_objective_list() + GLOB.admin_objective_list = list() - + var/list/allowed_types = list( + /datum/objective/assassinate, + /datum/objective/maroon, + /datum/objective/debrain, + /datum/objective/protect, + /datum/objective/destroy, + /datum/objective/hijack, + /datum/objective/escape, + /datum/objective/survive, + /datum/objective/martyr, + /datum/objective/steal, + /datum/objective/download, + /datum/objective/nuclear, + /datum/objective/capture, + /datum/objective/absorb, + /datum/objective/custom + ) + + for(var/T in allowed_types) + var/datum/objective/X = T + GLOB.admin_objective_list[initial(X.name)] = T \ No newline at end of file diff --git a/code/modules/admin/check_antagonists.dm b/code/modules/admin/check_antagonists.dm index 8292bea1bbed..95490b9b30e9 100644 --- a/code/modules/admin/check_antagonists.dm +++ b/code/modules/admin/check_antagonists.dm @@ -164,7 +164,8 @@ dat += "Living crew limit: [CONFIG_GET(number/midround_antag_life_check) * 100]% of crew alive
" dat += "If limits past: [SSticker.mode.round_ends_with_antag_death ? "End The Round" : "Continue As Extended"]
" dat += "End Round Now
" - dat += "[SSticker.delay_end ? "End Round Normally" : "Delay Round End"]" + dat += "[SSticker.delay_end ? "End Round Normally" : "Delay Round End"]
" + dat += "Check Teams" var/connected_players = GLOB.clients.len var/lobby_players = 0 var/observers = 0 diff --git a/code/modules/admin/team_panel.dm b/code/modules/admin/team_panel.dm new file mode 100644 index 000000000000..2b16a66e14ac --- /dev/null +++ b/code/modules/admin/team_panel.dm @@ -0,0 +1,183 @@ +//Split into Team List -> Team Details ? +/datum/admins/proc/team_listing() + var/list/content = list() + for(var/datum/team/T in GLOB.antagonist_teams) + content += "

[T.name] - [T.type]

" + content += "Rename" + content += "Delete" + content += "Communicate" + for(var/command in T.get_admin_commands()) + content += "[command]" + content += "
" + content += "Objectives:
    " + for(var/datum/objective/O in T.objectives) + content += "
  1. [O.explanation_text] - Remove
  2. " + content += "
Add Objective
" + content += "Members:
Add Member" + content += "
" + content += "Create Team
" + return content.Join() + + +/datum/admins/proc/check_teams() + if(!SSticker.HasRoundStarted()) + alert("The game hasn't started yet!") + return + + var/datum/browser/popup = new(usr, "teams", "Team Listing", 500, 500) + popup.set_content(team_listing()) + popup.open() + +/datum/admins/proc/admin_create_team(mob/user) + var/team_name = stripped_input(user,"Team name ?") + if(!team_name) + return + var/datum/team/custom/T = new() + T.name = team_name + + message_admins("[key_name_admin(usr)] created new [name] antagonist team.") + log_admin("[key_name(usr)] created new [name] antagonist team.") + +/datum/team/proc/admin_rename(mob/user) + var/old_name = name + var/team_name = stripped_input(user,"new team name ?","Team rename",old_name) + if(!team_name) + return + name = team_name + message_admins("[key_name_admin(usr)] renamed [old_name] team to [name]") + log_admin("[key_name(usr)] renamed [old_name] team to [name]") + +/datum/team/proc/admin_communicate(mob/user) + var/message = input(user,"Message for the team ?","Team Message") as text|null + if(!message) + return + for(var/datum/mind/M in members) + to_chat(M.current,message) + + message_admins("[key_name_admin(usr)] messaged [name] team with : [message]") + log_admin("Team Message: [key_name(usr)] -> [name] team : [message]") + +/datum/team/proc/admin_add_objective(mob/user) + //any antag with get_team == src => add objective to that antag + //otherwise create new custom antag + if(!GLOB.admin_objective_list) + generate_admin_objective_list() + + var/selected_type = input("Select objective type:", "Objective type") as null|anything in GLOB.admin_objective_list + selected_type = GLOB.admin_objective_list[selected_type] + if (!selected_type) + return + + var/datum/objective/O = new selected_type + O.team = src + O.admin_edit(user) + objectives |= O + + var/custom_antag_name + + for(var/datum/mind/M in members) + var/datum/antagonist/team_antag + for(var/datum/antagonist/A in M.antag_datums) + if(A.get_team() == src) + team_antag = A + if(!team_antag) + team_antag = new /datum/antagonist/custom + if(!custom_antag_name) + custom_antag_name = stripped_input(user, "Custom team antagonist name:", "Custom antag", "Antagonist") + if(!custom_antag_name) + custom_antag_name = "Team Member" + team_antag.name = custom_antag_name + M.add_antag_datum(team_antag,src) + team_antag.objectives |= O + + message_admins("[key_name_admin(usr)] added objective \"[O.explanation_text]\" to [name]") + log_admin("[key_name(usr)] added objective \"[O.explanation_text]\" to [name]") + +/datum/team/proc/admin_remove_objective(mob/user,datum/objective/O) + for(var/datum/mind/M in members) + for(var/datum/antagonist/A in M.antag_datums) + A.objectives -= O + objectives -= O + + message_admins("[key_name_admin(usr)] removed objective \"[O.explanation_text]\" from [name]") + log_admin("[key_name(usr)] removed objective \"[O.explanation_text]\" from [name]") + //qdel maybe + +/datum/team/proc/admin_add_member(mob/user) + var/list/minds = list() + for(var/mob/M in GLOB.mob_list) + if(M.mind) + minds |= M.mind + var/datum/mind/value = input("Select new member:", "New team member", null) as null|anything in minds + if (!value) + return + + message_admins("[key_name_admin(usr)] added [value.name] as a member of [name] team") + log_admin("[key_name(usr)] added [value.name] as a member of [name] team") + + add_member(value) + +/datum/team/proc/admin_remove_member(mob/user,datum/mind/M) + message_admins("[key_name_admin(usr)] removed [M.name] from [name] team") + log_admin("[key_name(usr)] removed [M.name] from [name] team") + remove_member(M) + +//After a bit of consideration i block team deletion if there's any members left until unified objective handling is in. +/datum/team/proc/admin_delete(mob/user) + if(members.len > 0) + to_chat(user,"Team has members left, remove them first and make sure you know what you're doing.") + return + qdel(src) + +/datum/team/Topic(href, href_list) + if(!check_rights(R_ADMIN)) + return + + var/commands = get_admin_commands() + for(var/admin_command in commands) + if(href_list["command"] == admin_command) + var/datum/callback/C = commands[admin_command] + C.Invoke(usr) + return + +/datum/team/proc/get_admin_commands() + return list() + +//Custom team subtype created by the panel, allow forcing hud for the team for now +/datum/team/custom + var/datum/atom_hud/antag/custom_hud + var/custom_hud_state = "traitor" + +/datum/team/custom/add_member(datum/mind/new_member) + . = ..() + if(custom_hud) + custom_hud.join_hud(new_member.current) + set_antag_hud(new_member.current,custom_hud_state) + +/datum/team/custom/remove_member(datum/mind/member) + . = ..() + if(custom_hud) + custom_hud.leave_hud(member.current) + +/datum/team/custom/get_admin_commands() + . = ..() + .["Force HUD"] = CALLBACK(src,.proc/admin_force_hud) + +//This is here if you want admin created teams to tell each other apart easily. +/datum/team/custom/proc/admin_force_hud(mob/user) + var/list/possible_icons = icon_states('icons/mob/hud.dmi') + var/new_hud_state = input(user,"Choose hud icon state","Custom HUD","traitor") as null|anything in possible_icons + if(!new_hud_state) + return + //suppose could ask for color too + custom_hud_state = new_hud_state + custom_hud = new + custom_hud.self_visible = TRUE + GLOB.huds += custom_hud //Make it show in admin hud + + for(var/datum/mind/M in members) + custom_hud.join_hud(M.current) + set_antag_hud(M.current,custom_hud_state) \ No newline at end of file diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 1f1594bb8071..7dd24f5f3c42 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -2556,6 +2556,54 @@ else if(answer == "no") log_query_debug("[usr.key] | Reported no server hang") + else if(href_list["check_teams"]) + if(!check_rights(R_ADMIN)) + return + check_teams() + + else if(href_list["team_command"]) + if(!check_rights(R_ADMIN)) + return + switch(href_list["team_command"]) + if("create_team") + admin_create_team(usr) + if("rename_team") + var/datum/team/T = locate(href_list["team"]) in GLOB.antagonist_teams + if(T) + T.admin_rename(usr) + if("communicate") + var/datum/team/T = locate(href_list["team"]) in GLOB.antagonist_teams + if(T) + T.admin_communicate(usr) + if("delete_team") + var/datum/team/T = locate(href_list["team"]) in GLOB.antagonist_teams + if(T) + T.admin_delete(usr) + if("add_objective") + var/datum/team/T = locate(href_list["team"]) in GLOB.antagonist_teams + if(T) + T.admin_add_objective(usr) + if("remove_objective") + var/datum/team/T = locate(href_list["team"]) in GLOB.antagonist_teams + if(!T) + return + var/datum/objective/O = locate(href_list["tobjective"]) in T.objectives + if(O) + T.admin_remove_objective(usr,O) + if("add_member") + var/datum/team/T = locate(href_list["team"]) in GLOB.antagonist_teams + if(T) + T.admin_add_member(usr) + if("remove_member") + var/datum/team/T = locate(href_list["team"]) in GLOB.antagonist_teams + if(!T) + return + var/datum/mind/M = locate(href_list["tmember"]) in T.members + if(M) + T.admin_remove_member(usr,M) + check_teams() + + /datum/admins/proc/HandleCMode() if(!check_rights(R_ADMIN)) return diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm index 3bb47139e0c2..2c7a698b5911 100644 --- a/code/modules/antagonists/_common/antag_datum.dm +++ b/code/modules/antagonists/_common/antag_datum.dm @@ -219,6 +219,13 @@ GLOBAL_LIST_EMPTY(antagonists) /datum/antagonist/custom antagpanel_category = "Custom" show_name_in_check_antagonists = TRUE //They're all different + var/datum/team/custom_team + +datum/antagonist/custom/create_team(datum/team/team) + custom_team = team + +/datum/antagonist/custom/get_team() + return custom_team /datum/antagonist/custom/admin_add(datum/mind/new_owner,mob/admin) var/custom_name = stripped_input(admin, "Custom antagonist name:", "Custom antag", "Antagonist") diff --git a/code/modules/antagonists/_common/antag_team.dm b/code/modules/antagonists/_common/antag_team.dm index 486b5b04147e..d1771ce3d9e8 100644 --- a/code/modules/antagonists/_common/antag_team.dm +++ b/code/modules/antagonists/_common/antag_team.dm @@ -1,3 +1,5 @@ +GLOBAL_LIST_EMPTY(antagonist_teams) + //A barebones antagonist team. /datum/team var/list/datum/mind/members = list() @@ -7,6 +9,7 @@ /datum/team/New(starting_members) . = ..() + GLOB.antagonist_teams += src if(starting_members) if(islist(starting_members)) for(var/datum/mind/M in starting_members) @@ -14,6 +17,10 @@ else add_member(starting_members) +/datum/team/Destroy(force, ...) + GLOB.antagonist_teams -= src + . = ..() + /datum/team/proc/is_solo() return members.len == 1 diff --git a/tgstation.dme b/tgstation.dme index 568faad3fc94..a10b48fae368 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1082,6 +1082,7 @@ #include "code\modules\admin\sound_emitter.dm" #include "code\modules\admin\sql_message_system.dm" #include "code\modules\admin\stickyban.dm" +#include "code\modules\admin\team_panel.dm" #include "code\modules\admin\topic.dm" #include "code\modules\admin\whitelist.dm" #include "code\modules\admin\DB_ban\functions.dm"