From ddb2305ddd64c0720a844ed0a574ee96025e4fd5 Mon Sep 17 00:00:00 2001 From: Aurorablade Date: Tue, 15 May 2018 01:40:15 -0400 Subject: [PATCH] updates to TG latest hopefully addressing alot of fox commits..now i got to update the branch... --- code/datums/antagonists/antag_datum.dm | 176 ++++++++++++++++++++--- code/datums/antagonists/antag_helpers.dm | 19 +++ code/datums/antagonists/antag_team.dm | 34 +++++ paradise.dme | 2 + 4 files changed, 212 insertions(+), 19 deletions(-) create mode 100644 code/datums/antagonists/antag_helpers.dm create mode 100644 code/datums/antagonists/antag_team.dm diff --git a/code/datums/antagonists/antag_datum.dm b/code/datums/antagonists/antag_datum.dm index 2464d5a4584..9d84349609f 100644 --- a/code/datums/antagonists/antag_datum.dm +++ b/code/datums/antagonists/antag_datum.dm @@ -1,27 +1,33 @@ -var/global/list/antagonists = list() +GLOBAL_LIST_EMPTY(antagonists) /datum/antagonist var/name = "Antagonist" + var/roundend_category = "other antagonists" //Section of roundend report, datums with same category will be displayed together, also default header for the section + var/show_in_roundend = TRUE //Set to false to hide the antagonists from roundend report var/datum/mind/owner //Mind that owns this datum var/silent = FALSE //Silent will prevent the gain/lose texts to show var/can_coexist_with_others = TRUE //Whether or not the person will be able to have more than one datum var/list/typecache_datum_blacklist = list() //List of datums this type can't coexist with var/delete_on_mind_deletion = TRUE - var/antag_role //the antag type + var/job_rank var/replace_banned = TRUE //Should replace jobbaned player with ghosts if granted. var/list/objectives = list() var/antag_memory = ""//These will be removed with antag datum + var/antag_moodlet //typepath of moodlet that the mob will gain with their status + + //Antag panel properties + var/show_in_antagpanel = TRUE //This will hide adding this antag type in antag panel, use only for internal subtypes that shouldn't be added directly but still show if possessed by mind + var/antagpanel_category = "Uncategorized" //Antagpanel will display these together, REQUIRED + var/show_name_in_check_antagonists = FALSE //Will append antagonist name in admin listings - use for categories that share more than one antag type -/datum/antagonist/New(datum/mind/new_owner) - antagonists += src +/datum/antagonist/New() + GLOB.antagonists += src typecache_datum_blacklist = typecacheof(typecache_datum_blacklist) - if(new_owner) - owner = new_owner /datum/antagonist/Destroy() - antagonists -= src + GLOB.antagonists -= src if(owner) LAZYREMOVE(owner.antag_datums, src) owner = null @@ -37,6 +43,11 @@ var/global/list/antagonists = list() if(is_type_in_typecache(src, A.typecache_datum_blacklist)) return FALSE +//This will be called in add_antag_datum before owner assignment. +//Should return antag datum without owner. +/datum/antagonist/proc/specialization(datum/mind/new_owner) + return src + /datum/antagonist/proc/on_body_transfer(mob/living/old_body, mob/living/new_body) remove_innate_effects(old_body) apply_innate_effects(new_body) @@ -50,7 +61,7 @@ var/global/list/antagonists = list() return //Assign default team and creates one for one of a kind team antagonists -/datum/antagonist/proc/create_team(datum/objective_team/team) +/datum/antagonist/proc/create_team(datum/team/team) return //Proc called when the datum is given to a mind. @@ -65,27 +76,27 @@ var/global/list/antagonists = list() /datum/antagonist/proc/is_banned(mob/M) if(!M) return FALSE - . = (jobban_isbanned(M,"Syndicate") || (antag_role && jobban_isbanned(M,antag_role))) + . = (jobban_isbanned(M, ROLE_SYNDICATE) || (job_rank && jobban_isbanned(M,job_rank))) /datum/antagonist/proc/replace_banned_player() set waitfor = FALSE - var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as a [name]?", "[name]", null, antag_role, 0, 100) - var/mob/dead/observer/theghost = null - if(candidates.len) - theghost = pick(candidates) - to_chat(owner, " Your mob has been taken over by a ghost! Appeal your role ban if you want to avoid this in the future!") - message_admins("[key_name_admin(theghost)] has taken control of ([key_name_admin(owner.current)]) to replace a jobbaned player.") - log_admin("[key_name_admin(theghost)] has taken control of ([key_name_admin(owner.current)]) to replace a jobbaned player.") + var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a [name]?", "[name]", null, job_rank, 50, owner.current) + if(LAZYLEN(candidates)) + var/mob/dead/observer/C = pick(candidates) + to_chat(owner, "Your mob has been taken over by a ghost! Appeal your job ban if you want to avoid this in the future!") + message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(owner.current)]) to replace a jobbaned player.") owner.current.ghostize(0) - owner.current.key = theghost.key + owner.current.key = C.key /datum/antagonist/proc/on_removal() remove_innate_effects() + clear_antag_moodies() if(owner) LAZYREMOVE(owner.antag_datums, src) if(!silent && owner.current) farewell() + owner.objectives -= objectives var/datum/team/team = get_team() if(team) team.remove_member(owner) @@ -94,9 +105,136 @@ var/global/list/antagonists = list() /datum/antagonist/proc/greet() return +/datum/antagonist/proc/farewell() + return + + //Returns the team antagonist belongs to if any. /datum/antagonist/proc/get_team() return -/datum/antagonist/proc/farewell() - return \ No newline at end of file +//Individual roundend report +/datum/antagonist/proc/roundend_report() + var/list/report = list() + + if(!owner) + CRASH("antagonist datum without owner") + + report += printplayer(owner) + + var/objectives_complete = TRUE + if(owner.objectives.len) + report += printobjectives(owner) + for(var/datum/objective/objective in owner.objectives) + if(!objective.check_completion()) + objectives_complete = FALSE + break + + if(owner.objectives.len == 0 || objectives_complete) + report += "The [name] was successful!" + else + report += "The [name] has failed!" + + return report.Join("
") + +//Displayed at the start of roundend_category section, default to roundend_category header +/datum/antagonist/proc/roundend_report_header() + return "The [roundend_category] were:
" + +//Displayed at the end of roundend_category section +/datum/antagonist/proc/roundend_report_footer() + return + + +//ADMIN TOOLS + +//Called when using admin tools to give antag status +/datum/antagonist/proc/admin_add(datum/mind/new_owner,mob/admin) + message_admins("[key_name_admin(admin)] made [new_owner.current] into [name].") + log_admin("[key_name(admin)] made [new_owner.current] into [name].") + new_owner.add_antag_datum(src) + +//Called when removing antagonist using admin tools +/datum/antagonist/proc/admin_remove(mob/user) + if(!user) + return + message_admins("[key_name_admin(user)] has removed [name] antagonist status from [owner.current].") + log_admin("[key_name(user)] has removed [name] antagonist status from [owner.current].") + on_removal() + +//gamemode/proc/is_mode_antag(antagonist/A) => TRUE/FALSE + +//Additional data to display in antagonist panel section +//nuke disk code, genome count, etc +/datum/antagonist/proc/antag_panel_data() + return "" + +/datum/antagonist/proc/enabled_in_preferences(datum/mind/M) + if(job_rank) + if(M.current && M.current.client && (job_rank in M.current.client.prefs.be_special)) + return TRUE + else + return FALSE + return TRUE + +// List if["Command"] = CALLBACK(), user will be appeneded to callback arguments on execution +/datum/antagonist/proc/get_admin_commands() + . = list() + +/datum/antagonist/Topic(href,href_list) + if(!check_rights(R_ADMIN)) + return + //Antag memory edit + if(href_list["memory_edit"]) + edit_memory(usr) + owner.traitor_panel() + return + + //Some commands might delete/modify this datum clearing or changing owner + var/datum/mind/persistent_owner = owner + + 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) + persistent_owner.traitor_panel() + return + +/datum/antagonist/proc/edit_memory(mob/user) + var/new_memo = copytext(trim(input(user,"Write new memory", "Memory", antag_memory) as null|message),1,MAX_MESSAGE_LEN) + if(isnull(new_memo)) + return + antag_memory = new_memo + +//This datum will autofill the name with special_role +//Used as placeholder for minor antagonists, please create proper datums for these +/datum/antagonist/auto_custom + show_in_antagpanel = FALSE + antagpanel_category = "Other" + show_name_in_check_antagonists = TRUE + +/datum/antagonist/auto_custom/on_gain() + ..() + name = owner.special_role + //Add all objectives not already owned by other datums to this one. + var/list/already_registered_objectives = list() + for(var/datum/antagonist/A in owner.antag_datums) + if(A == src) + continue + else + already_registered_objectives |= A.objectives + objectives = owner.objectives - already_registered_objectives + +//This one is created by admin tools for custom objectives +/datum/antagonist/custom + antagpanel_category = "Custom" + show_name_in_check_antagonists = TRUE //They're all different + +/datum/antagonist/custom/admin_add(datum/mind/new_owner,mob/admin) + var/custom_name = stripped_input(admin, "Custom antagonist name:", "Custom antag", "Antagonist") + if(custom_name) + name = custom_name + else + return + ..() \ No newline at end of file diff --git a/code/datums/antagonists/antag_helpers.dm b/code/datums/antagonists/antag_helpers.dm new file mode 100644 index 00000000000..d99920b9e21 --- /dev/null +++ b/code/datums/antagonists/antag_helpers.dm @@ -0,0 +1,19 @@ +//Returns MINDS of the assigned antags of given type/subtypes +/proc/get_antag_minds(antag_type,specific = FALSE) + . = list() + for(var/datum/antagonist/A in GLOB.antagonists) + if(!A.owner) + continue + if(!antag_type || !specific && istype(A,antag_type) || specific && A.type == antag_type) + . += A.owner + +//Get all teams [of type team_type] +/proc/get_all_teams(team_type) + . = list() + for(var/V in GLOB.antagonists) + var/datum/antagonist/A = V + if(!A.owner) + continue + var/datum/team/T = A.get_team() + if(!team_type || istype(T,team_type)) + . |= T \ No newline at end of file diff --git a/code/datums/antagonists/antag_team.dm b/code/datums/antagonists/antag_team.dm new file mode 100644 index 00000000000..372ee26dfad --- /dev/null +++ b/code/datums/antagonists/antag_team.dm @@ -0,0 +1,34 @@ +//A barebones antagonist team. +/datum/team + var/list/datum/mind/members = list() + var/name = "team" + var/member_name = "member" + var/list/objectives = list() //common objectives, these won't be added or removed automatically, subtypes handle this, this is here for bookkeeping purposes. + +/datum/team/New(starting_members) + . = ..() + if(starting_members) + if(islist(starting_members)) + for(var/datum/mind/M in starting_members) + add_member(M) + else + add_member(starting_members) + +/datum/team/proc/is_solo() + return members.len == 1 + +/datum/team/proc/add_member(datum/mind/new_member) + members |= new_member + +/datum/team/proc/remove_member(datum/mind/member) + members -= member + +//Display members/victory/failure/objectives for the team +/datum/team/proc/roundend_report() + var/list/report = list() + + report += "[name]:" + report += "The [member_name]s were:" + report += printplayerlist(members) + + return report.Join("
") \ No newline at end of file diff --git a/paradise.dme b/paradise.dme index f03d37b701c..0a486bdddf9 100644 --- a/paradise.dme +++ b/paradise.dme @@ -228,6 +228,8 @@ #include "code\datums\vision_override.dm" #include "code\datums\vr.dm" #include "code\datums\antagonists\antag_datum.dm" +#include "code\datums\antagonists\antag_helpers.dm" +#include "code\datums\antagonists\antag_team.dm" #include "code\datums\cache\air_alarm.dm" #include "code\datums\cache\apc.dm" #include "code\datums\cache\cache.dm"