From 5df7dfdaacb7adf91c4d3b0f9093607ae83449d3 Mon Sep 17 00:00:00 2001 From: Fox McCloud Date: Tue, 15 May 2018 21:55:44 -0400 Subject: [PATCH] Preps the Way for Datumized Antags --- code/datums/antagonists/antag_datum.dm | 40 +++++++++++++---- .../antagonists}/antag_hud.dm | 25 ++++++----- .../antagonists}/antag_spawner.dm | 32 +++++++------- code/datums/mind.dm | 44 +++++++++++-------- code/game/gamemodes/game_mode.dm | 31 +++++++------ code/modules/admin/topic.dm | 4 +- .../admin/verbs/infiltratorteam_syndicate.dm | 4 +- paradise.dme | 4 +- 8 files changed, 111 insertions(+), 73 deletions(-) rename code/{game/gamemodes => datums/antagonists}/antag_hud.dm (78%) rename code/{game/gamemodes => datums/antagonists}/antag_spawner.dm (89%) diff --git a/code/datums/antagonists/antag_datum.dm b/code/datums/antagonists/antag_datum.dm index 51ca4e5d39c..39053fa79d9 100644 --- a/code/datums/antagonists/antag_datum.dm +++ b/code/datums/antagonists/antag_datum.dm @@ -13,14 +13,6 @@ GLOBAL_LIST_EMPTY(antagonists) 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() GLOB.antagonists += src @@ -110,4 +102,36 @@ GLOBAL_LIST_EMPTY(antagonists) //Returns the team antagonist belongs to if any. /datum/antagonist/proc/get_team() + return + +//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 \ No newline at end of file diff --git a/code/game/gamemodes/antag_hud.dm b/code/datums/antagonists/antag_hud.dm similarity index 78% rename from code/game/gamemodes/antag_hud.dm rename to code/datums/antagonists/antag_hud.dm index 4b290932e8e..693b0b9450d 100644 --- a/code/game/gamemodes/antag_hud.dm +++ b/code/datums/antagonists/antag_hud.dm @@ -1,11 +1,12 @@ /datum/atom_hud/antag hud_icons = list(SPECIALROLE_HUD,NATIONS_HUD) - var/self_visible = 1 + var/self_visible = TRUE /datum/atom_hud/antag/hidden - self_visible = 0 + self_visible = FALSE -/datum/atom_hud/antag/proc/join_hud(mob/M,var/slave) +/datum/atom_hud/antag/proc/join_hud(mob/M, slave) + //sees_hud should be set to 0 if the mob does not get to see it's own hud type. if(!istype(M)) CRASH("join_hud(): [M] ([M.type]) is not a mob!") if(M.mind.antag_hud && !slave) //note: please let this runtime if a mob has no mind, as mindless mobs shouldn't be getting antagged @@ -16,6 +17,8 @@ M.mind.antag_hud = src /datum/atom_hud/antag/proc/leave_hud(mob/M) + if(!M) + return if(!istype(M)) CRASH("leave_hud(): [M] ([M.type]) is not a mob!") remove_from_hud(M) @@ -26,7 +29,7 @@ //GAME_MODE PROCS //called to set a mob's antag icon state -/datum/game_mode/proc/set_antag_hud(mob/M, new_icon_state) +/proc/set_antag_hud(mob/M, new_icon_state) if(!istype(M)) CRASH("set_antag_hud(): [M] ([M.type]) is not a mob!") var/image/holder = M.hud_list[SPECIALROLE_HUD] @@ -36,7 +39,7 @@ M.mind.antag_hud_icon_state = new_icon_state //Nations Icons -/datum/game_mode/proc/set_nations_hud(mob/M, new_icon_state) +/proc/set_nations_hud(mob/M, new_icon_state) if(!istype(M)) CRASH("set_antag_hud(): [M] ([M.type]) is not a mob!") var/image/holder = M.hud_list[NATIONS_HUD] @@ -47,9 +50,9 @@ //MIND PROCS //these are called by mind.transfer_to() -/datum/mind/proc/transfer_antag_huds(var/datum/atom_hud/antag/newhud) +/datum/mind/proc/transfer_antag_huds(datum/atom_hud/antag/newhud) leave_all_huds() - ticker.mode.set_antag_hud(current, antag_hud_icon_state) + set_antag_hud(current, antag_hud_icon_state) if(newhud) newhud.join_hud(current) @@ -77,11 +80,11 @@ name = mastername thrallhud = new() -/datum/mindslaves/proc/add_serv_hud(datum/mind/serv_mind,var/icon) - thrallhud.join_hud(serv_mind.current,1) +/datum/mindslaves/proc/add_serv_hud(datum/mind/serv_mind, icon) + thrallhud.join_hud(serv_mind.current, 1) icontype = "hud[icon]" - ticker.mode.set_antag_hud(serv_mind.current,icontype) + set_antag_hud(serv_mind.current, icontype) /datum/mindslaves/proc/leave_serv_hud(datum/mind/free_mind) thrallhud.leave_hud(free_mind.current) - ticker.mode.set_antag_hud(free_mind.current,null) \ No newline at end of file + set_antag_hud(free_mind.current, null) \ No newline at end of file diff --git a/code/game/gamemodes/antag_spawner.dm b/code/datums/antagonists/antag_spawner.dm similarity index 89% rename from code/game/gamemodes/antag_spawner.dm rename to code/datums/antagonists/antag_spawner.dm index 23fed691ec6..c81f30efc83 100644 --- a/code/game/gamemodes/antag_spawner.dm +++ b/code/datums/antagonists/antag_spawner.dm @@ -2,12 +2,12 @@ throw_speed = 1 throw_range = 5 w_class = WEIGHT_CLASS_TINY - var/used = 0 + var/used = FALSE -/obj/item/antag_spawner/proc/spawn_antag(var/client/C, var/turf/T, var/type = "") +/obj/item/antag_spawner/proc/spawn_antag(client/C, turf/T, type = "") return -/obj/item/antag_spawner/proc/equip_antag(mob/target as mob) +/obj/item/antag_spawner/proc/equip_antag(mob/target) return @@ -16,41 +16,41 @@ desc = "A single-use teleporter used to deploy a Syndicate Cyborg on the field." icon = 'icons/obj/device.dmi' icon_state = "locator" - var/checking = 0 + var/checking = FALSE var/TC_cost = 0 var/borg_to_spawn var/list/possible_types = list("Assault", "Medical") -/obj/item/antag_spawner/borg_tele/attack_self(mob/user as mob) +/obj/item/antag_spawner/borg_tele/attack_self(mob/user) if(used) to_chat(user, "[src] is out of power!") return if(!(user.mind in ticker.mode.syndicates)) to_chat(user, "AUTHENTICATION FAILURE. ACCESS DENIED.") - return 0 + return FALSE if(checking) to_chat(user, "[src] is already checking for possible borgs.") return borg_to_spawn = input("What type of borg would you like to teleport?", "Cyborg Type", type) as null|anything in possible_types if(!borg_to_spawn || checking || used) return - checking = 1 + checking = TRUE to_chat(user, "The device is now checking for possible borgs.") var/list/borg_candidates = pollCandidates("Do you want to play as a Syndicate [borg_to_spawn] borg?", ROLE_OPERATIVE, 1) if(borg_candidates.len > 0 && !used) - checking = 0 - used = 1 + checking = FALSE + used = TRUE var/mob/M = pick(borg_candidates) var/client/C = M.client spawn_antag(C, get_turf(src.loc), "syndieborg") else - checking = 0 + checking = FALSE to_chat(user, "Unable to connect to Syndicate command. Please wait and try again later or use the teleporter on your uplink to get your points refunded.") return -/obj/item/antag_spawner/borg_tele/spawn_antag(var/client/C, var/turf/T, var/type = "") +/obj/item/antag_spawner/borg_tele/spawn_antag(client/C, turf/T, type = "") if(!borg_to_spawn) //If there's no type at all, let it still be used but don't do anything - used = 0 + used = FALSE return var/datum/effect_system/spark_spread/S = new /datum/effect_system/spark_spread S.set_up(4, 1, src) @@ -79,7 +79,7 @@ var/objective_verb = "Kill" var/mob/living/demon_type = /mob/living/simple_animal/slaughter -/obj/item/antag_spawner/slaughter_demon/attack_self(mob/user as mob) +/obj/item/antag_spawner/slaughter_demon/attack_self(mob/user) if(level_blocks_magic(user.z))//this is to make sure the wizard does NOT summon a demon from the Den.. to_chat(user, "You should probably wait until you reach the station.") return @@ -87,7 +87,7 @@ if(used) to_chat(user, "This bottle already has a broken seal.") return - used = 1 + used = TRUE to_chat(user, "You break the seal on the bottle, calling upon the dire spirits of the underworld...") var/list/candidates = pollCandidates("Do you want to play as a slaughter demon summoned by [user.real_name]?", ROLE_DEMON, 1, 100) @@ -100,10 +100,10 @@ playsound(user.loc, 'sound/effects/Glassbr1.ogg', 100, 1) qdel(src) else - used = 0 + used = FALSE to_chat(user, "The demons do not respond to your summon. Perhaps you should try again later.") -/obj/item/antag_spawner/slaughter_demon/spawn_antag(var/client/C, var/turf/T, var/type = "", mob/user as mob) +/obj/item/antag_spawner/slaughter_demon/spawn_antag(client/C, turf/T, type = "", mob/user) var /obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(T) var/mob/living/simple_animal/slaughter/S = new demon_type(holder) S.vialspawned = TRUE diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 8bc1034206e..08bd6252d99 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -1230,15 +1230,32 @@ // Datum antag mind procs -/datum/mind/proc/add_antag_datum(datum_type, on_gain = TRUE) - if(!datum_type) +/datum/mind/proc/add_antag_datum(datum_type_or_instance, team) + if(!datum_type_or_instance) return - if(!can_hold_antag_datum(datum_type)) + var/datum/antagonist/A + if(!ispath(datum_type_or_instance)) + A = datum_type_or_instance + if(!istype(A)) + return + else + A = new datum_type_or_instance() + //Choose snowflake variation if antagonist handles it + var/datum/antagonist/S = A.specialization(src) + if(S && S != A) + qdel(A) + A = S + if(!A.can_be_owned(src)) + qdel(A) return - var/datum/antagonist/A = new datum_type(src) - antag_datums += A - if(on_gain) - A.on_gain() + A.owner = src + LAZYADD(antag_datums, A) + A.create_team(team) + var/datum/team/antag_team = A.get_team() + if(antag_team) + antag_team.add_member(src) + A.on_gain() + return A /datum/mind/proc/remove_antag_datum(datum_type) if(!datum_type) @@ -1248,6 +1265,7 @@ A.on_removal() return TRUE + /datum/mind/proc/remove_all_antag_datums() //For the Lazy amongst us. for(var/a in antag_datums) var/datum/antagonist/A = a @@ -1264,18 +1282,6 @@ else if(A.type == datum_type) return A -/datum/mind/proc/can_hold_antag_datum(datum_type) - if(!datum_type) - return - . = TRUE - if(has_antag_datum(datum_type)) - return FALSE - for(var/i in antag_datums) - var/datum/antagonist/A = i - if(is_type_in_typecache(A, A.typecache_datum_blacklist)) - return FALSE - - /datum/mind/proc/find_syndicate_uplink() var/list/L = current.get_contents() for(var/obj/item/I in L) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 4a2622c536d..702b59853dc 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -107,7 +107,7 @@ tries_left = 5 //reset our tries since we found a new chump //make sure we have chumps before we try misinforming them. if we don't make a note of it. if(!chumps.len) - log_debug("Game mode failed to find ANY chumps. This is likely due to the server being in extreme low-pop with no one set to opposed or skeptical.") + log_debug("Game mode failed to find ANY chumps. This is likely due to the server being in extreme low-pop with no one set to opposed or skeptical.") return 0 //we've got chumps! misinform them! for(var/mob/living/carbon/human/chump in chumps) @@ -493,31 +493,36 @@ proc/display_roundstart_logout_report() message_admins("[M] ([M.key] has been converted into [role_type] with an active antagonist jobban for said role since no ghost has volunteered to take their place.") to_chat(M, "You have been converted into [role_type] with an active jobban. Any further violations of the rules on your part are likely to result in a permanent ban.") -/datum/game_mode/proc/printplayer(datum/mind/ply, fleecheck) - var/text = "
[ply.key] was [ply.name] the [ply.assigned_role] and" +/proc/printplayer(datum/mind/ply, fleecheck) + var/jobtext = "" + if(ply.assigned_role) + jobtext = " the [ply.assigned_role]" + var/text = "[ply.key] was [ply.name][jobtext] and" if(ply.current) if(ply.current.stat == DEAD) - text += " died" + text += " died" else - text += " survived" - if(fleecheck && !is_station_level(ply.current.z)) - text += " while fleeing the station" + text += " survived" + if(fleecheck) + var/turf/T = get_turf(ply.current) + if(!T || !is_station_level(T.z)) + text += " while fleeing the station" if(ply.current.real_name != ply.name) text += " as [ply.current.real_name]" else - text += " had their body destroyed" + text += " had their body destroyed" return text -/datum/game_mode/proc/printobjectives(datum/mind/ply) - var/text = "" +/proc/printobjectives(datum/mind/ply) + var/list/objective_parts = list() var/count = 1 for(var/datum/objective/objective in ply.objectives) if(objective.check_completion()) - text += "
Objective #[count]: [objective.explanation_text] Success!" + objective_parts += "Objective #[count]: [objective.explanation_text] Success!" else - text += "
Objective #[count]: [objective.explanation_text] Fail." + objective_parts += "Objective #[count]: [objective.explanation_text] Fail." count++ - return text + return objective_parts.Join("
") /datum/game_mode/proc/generate_station_goals() var/list/possible = list() diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 44328429dc0..bc5f67d49a8 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1941,7 +1941,7 @@ newtraitor.mind.special_role = SPECIAL_ROLE_TRAITOR var/datum/atom_hud/antag/tatorhud = huds[ANTAG_HUD_TRAITOR] tatorhud.join_hud(newtraitor) - ticker.mode.set_antag_hud(newtraitor, "hudsyndicate") + set_antag_hud(newtraitor, "hudsyndicate") else to_chat(usr, "ERROR: Failed to create a traitor.") return @@ -3436,7 +3436,7 @@ hunter_mob.mind.special_role = SPECIAL_ROLE_TRAITOR var/datum/atom_hud/antag/tatorhud = huds[ANTAG_HUD_TRAITOR] tatorhud.join_hud(hunter_mob) - ticker.mode.set_antag_hud(hunter_mob, "hudsyndicate") + set_antag_hud(hunter_mob, "hudsyndicate") /proc/admin_jump_link(var/atom/target) if(!target) return diff --git a/code/modules/admin/verbs/infiltratorteam_syndicate.dm b/code/modules/admin/verbs/infiltratorteam_syndicate.dm index cba1beb2cf6..a3f30117cdd 100644 --- a/code/modules/admin/verbs/infiltratorteam_syndicate.dm +++ b/code/modules/admin/verbs/infiltratorteam_syndicate.dm @@ -109,7 +109,7 @@ var/global/sent_syndicate_infiltration_team = 0 new_syndicate_infiltrator.mind.store_memory("Starting Equipment:
- Syndicate Headset ((.h for your radio))
- Chameleon Jumpsuit ((right click to Change Color))
- Agent ID card ((disguise as another job))
- Uplink Implant ((top left of screen))
- Dust Implant ((destroys your body on death))
- Combat Gloves ((insulated, disguised as black gloves))
- Anything bought with your uplink implant") var/datum/atom_hud/antag/opshud = huds[ANTAG_HUD_OPS] opshud.join_hud(new_syndicate_infiltrator.mind.current) - ticker.mode.set_antag_hud(new_syndicate_infiltrator.mind.current, "hudoperative") + set_antag_hud(new_syndicate_infiltrator.mind.current, "hudoperative") new_syndicate_infiltrator.regenerate_icons() num_spawned++ if(!teamsize) @@ -127,7 +127,7 @@ var/global/sent_syndicate_infiltration_team = 0 syndimgmtmob.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/syndicate, slot_wear_mask) var/datum/atom_hud/antag/opshud = huds[ANTAG_HUD_OPS] opshud.join_hud(syndimgmtmob.mind.current) - ticker.mode.set_antag_hud(syndimgmtmob.mind.current, "hudoperative") + set_antag_hud(syndimgmtmob.mind.current, "hudoperative") syndimgmtmob.mind.special_role = "Syndicate Management Consultant" syndimgmtmob.regenerate_icons() to_chat(syndimgmtmob, "You have spawned as Syndicate Management. You should brief them on their mission before they go.") diff --git a/paradise.dme b/paradise.dme index 303c0ebaed9..ffbc020b78e 100644 --- a/paradise.dme +++ b/paradise.dme @@ -241,6 +241,8 @@ #include "code\datums\vr.dm" #include "code\datums\antagonists\antag_datum.dm" #include "code\datums\antagonists\antag_helpers.dm" +#include "code\datums\antagonists\antag_hud.dm" +#include "code\datums\antagonists\antag_spawner.dm" #include "code\datums\antagonists\antag_team.dm" #include "code\datums\cache\air_alarm.dm" #include "code\datums\cache\apc.dm" @@ -403,8 +405,6 @@ #include "code\game\dna\genes\powers.dm" #include "code\game\dna\genes\vg_disabilities.dm" #include "code\game\dna\genes\vg_powers.dm" -#include "code\game\gamemodes\antag_hud.dm" -#include "code\game\gamemodes\antag_spawner.dm" #include "code\game\gamemodes\factions.dm" #include "code\game\gamemodes\game_mode.dm" #include "code\game\gamemodes\gameticker.dm"