From d6f58bda31bbfbbe0d2624e5d38007d49a6e2fd0 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Thu, 25 Jan 2024 15:28:51 +0100 Subject: [PATCH] [MIRROR] Fixes contractor support unit (#26220) * Fixes contractor support unit (#81054) ## About The Pull Request This does what I suggested on https://github.com/tgstation/tgstation/pull/79884 and some more fixes that I found while messing around. This was a big oversight when I was adding contractor originally, uplinks were reworked entirely and I didn't take it into account properly, this hopefully will fix those. I also gave contractor support units their own flavor and removed their uplink section since they do not get one, so they aren't an "MI13 agent" or anything, they work solely for this one guy. There were reports that people being contracted didn't send them back with their equipment but I haven't been able to replicate that bug and I do not see an issue report on it so I am going to assume that for now it is fine. ## Why It's Good For The Game Closes https://github.com/tgstation/tgstation/issues/79883 Contractor support units now properly work as intended and don't feel like a buggy mess. ## Changelog :cl: fix: Contractor support units now don't have flavortext telling them they work for someone else but their agent. fix: Contractor support units now comes in an antag spawner (like syndicate monkey, nukie borgs/reinforcements). fix: Syndicate monkeys now get their monkey antag datum. /:cl: * Fixes contractor support unit --------- Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com> --- code/__DEFINES/role_preferences.dm | 1 + .../antagonists/_common/antag_spawner.dm | 27 ++++++++++++++-- .../traitor/contractor/contract_teammate.dm | 31 ++----------------- .../traitor/contractor/syndicate_contract.dm | 19 ++++++------ .../antagonists/traitor/datum_traitor.dm | 30 +++++++++--------- .../modules/uplink/uplink_items/contractor.dm | 27 +++------------- strings/antagonist_flavor/traitor_flavor.json | 8 +++++ .../tgui/interfaces/AntagInfoTraitor.tsx | 11 ++++--- 8 files changed, 72 insertions(+), 82 deletions(-) diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index e7ebc19c682..90e3f328f6e 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -86,6 +86,7 @@ #define ROLE_SLAUGHTER_DEMON "Slaughter Demon" #define ROLE_WIZARD_APPRENTICE "apprentice" #define ROLE_SYNDICATE_MONKEY "Syndicate Monkey Agent" +#define ROLE_CONTRACTOR_SUPPORT "Contractor Support Unit" //Spawner roles #define ROLE_ANCIENT_CREW "Ancient Crew" diff --git a/code/modules/antagonists/_common/antag_spawner.dm b/code/modules/antagonists/_common/antag_spawner.dm index 6ff809b59cb..9ef40a9cebf 100644 --- a/code/modules/antagonists/_common/antag_spawner.dm +++ b/code/modules/antagonists/_common/antag_spawner.dm @@ -332,7 +332,15 @@ return to_chat(user, span_notice("You activate [src] and wait for confirmation.")) - var/list/baddie_candidates = SSpolling.poll_ghost_candidates("Do you want to play as a [role_to_play]?", check_jobban = poll_role_check, role = poll_role_check, poll_time = 10 SECONDS, ignore_category = poll_ignore_category, pic_source = src, role_name_text = role_to_play) + var/list/baddie_candidates = SSpolling.poll_ghost_candidates( + "Do you want to play as a [role_to_play]?", + check_jobban = poll_role_check, + role = poll_role_check, + poll_time = 10 SECONDS, + ignore_category = poll_ignore_category, + pic_source = src, + role_name_text = role_to_play, + ) if(!LAZYLEN(baddie_candidates)) to_chat(user, span_warning(fail_text)) return @@ -359,7 +367,7 @@ else spawned_mob.forceMove(locate(1,1,1)) - antag_datum = new() + op_mind.add_antag_datum(antag_datum) if(ishuman(spawned_mob)) var/mob/living/carbon/human/human_mob = spawned_mob @@ -373,6 +381,21 @@ spawned_mob.forceMove(pod) new /obj/effect/pod_landingzone(get_turf(src), pod) +/obj/item/antag_spawner/loadout/contractor + name = "contractor support beacon" + desc = "A beacon sold to the most prestigeous syndicate members, a single-use radio for calling immediate backup." + icon = 'icons/obj/devices/voice.dmi' + icon_state = "nukietalkie" + outfit = /datum/outfit/contractor_partner + use_subtypes = FALSE + antag_datum = /datum/antagonist/traitor/contractor_support + poll_ignore_category = ROLE_TRAITOR + role_to_play = ROLE_CONTRACTOR_SUPPORT + +/obj/item/antag_spawner/loadout/contractor/do_special_things(mob/living/carbon/human/contractor_support, mob/user) + to_chat(contractor_support, "\n[span_alertwarning("[user.real_name] is your superior. Follow any, and all orders given by them. You're here to support their mission only.")]") + to_chat(contractor_support, "[span_alertwarning("Should they perish, or be otherwise unavailable, you're to assist other active agents in this mission area to the best of your ability.")]") + /obj/item/antag_spawner/loadout/monkey_man name = "monkey agent beacon" desc = "Call up some backup from ARC for monkey mayhem." diff --git a/code/modules/antagonists/traitor/contractor/contract_teammate.dm b/code/modules/antagonists/traitor/contractor/contract_teammate.dm index 1aebd9fb951..54fc958c1f8 100644 --- a/code/modules/antagonists/traitor/contractor/contract_teammate.dm +++ b/code/modules/antagonists/traitor/contractor/contract_teammate.dm @@ -1,35 +1,8 @@ -///Spawns a contractor partner to a spawning user, with a given key to assign to the new player. -/proc/spawn_contractor_partner(mob/living/user, key) - var/mob/living/carbon/human/partner = new() - var/datum/outfit/contractor_partner/partner_outfit = new() - - partner_outfit.equip(partner) - - var/obj/structure/closet/supplypod/arrival_pod = new(null, STYLE_SYNDICATE) - arrival_pod.explosionSize = list(0,0,0,1) - arrival_pod.bluespace = TRUE - - var/turf/free_location = find_obstruction_free_location(2, user) - - // We really want to send them - if we can't find a nice location just land it on top of them. - if (!free_location) - free_location = get_turf(user) - - partner.forceMove(arrival_pod) - partner.ckey = key - - /// We give a reference to the mind that'll be the support unit - var/datum/antagonist/traitor/contractor_support/new_datum = partner.mind.add_antag_datum(/datum/antagonist/traitor/contractor_support) - - to_chat(partner, "\n[span_alertwarning("[user.real_name] is your superior. Follow any, and all orders given by them. You're here to support their mission only.")]") - to_chat(partner, "[span_alertwarning("Should they perish, or be otherwise unavailable, you're to assist other active agents in this mission area to the best of your ability.")]") - - new /obj/effect/pod_landingzone(free_location, arrival_pod) - return new_datum - /// Support unit gets it's own very basic antag datum for admin logging. /datum/antagonist/traitor/contractor_support name = "Contractor Support Unit" + job_rank = ROLE_CONTRACTOR_SUPPORT + employer = "Contractor Support Unit" show_in_roundend = FALSE give_objectives = TRUE give_uplink = FALSE diff --git a/code/modules/antagonists/traitor/contractor/syndicate_contract.dm b/code/modules/antagonists/traitor/contractor/syndicate_contract.dm index 3f7370031da..6af7a8d81d5 100644 --- a/code/modules/antagonists/traitor/contractor/syndicate_contract.dm +++ b/code/modules/antagonists/traitor/contractor/syndicate_contract.dm @@ -100,16 +100,15 @@ if(traitor_data.uplink_handler.contractor_hub.current_contract == src) traitor_data.uplink_handler.contractor_hub.current_contract = null - if(iscarbon(person_sent)) - for(var/obj/item/person_contents in person_sent.gather_belongings()) - if(ishuman(person_sent)) - var/mob/living/carbon/human/human_sent = person_sent - if(person_contents == human_sent.w_uniform) - continue //So all they're left with are shoes and uniform. - if(person_contents == human_sent.shoes) - continue - person_sent.transferItemToLoc(person_contents) - victim_belongings.Add(WEAKREF(person_contents)) + for(var/obj/item/person_contents as anything in person_sent.gather_belongings()) + if(ishuman(person_sent)) + var/mob/living/carbon/human/human_sent = person_sent + if(person_contents == human_sent.w_uniform) + continue //So all they're left with are shoes and uniform. + if(person_contents == human_sent.shoes) + continue + person_sent.transferItemToLoc(person_contents) + victim_belongings.Add(WEAKREF(person_contents)) var/obj/structure/closet/supplypod/extractionpod/pod = source // Handle the pod returning diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm index d338abca641..ea88c7e4900 100644 --- a/code/modules/antagonists/traitor/datum_traitor.dm +++ b/code/modules/antagonists/traitor/datum_traitor.dm @@ -34,7 +34,7 @@ ///if TRUE, this traitor will always get hijacking as their final objective var/is_hijacker = FALSE - ///the name of the antag flavor this traitor has. + ///the name of the antag flavor this traitor has, set in Traitor's setup if not preset. var/employer ///assoc list of strings set up after employer is given @@ -188,22 +188,23 @@ return ..() /datum/antagonist/traitor/proc/pick_employer() - var/faction = prob(75) ? FLAVOR_FACTION_SYNDICATE : FLAVOR_FACTION_NANOTRASEN - var/list/possible_employers = list() + if(!employer) + var/faction = prob(75) ? FLAVOR_FACTION_SYNDICATE : FLAVOR_FACTION_NANOTRASEN + var/list/possible_employers = list() - possible_employers.Add(GLOB.syndicate_employers, GLOB.nanotrasen_employers) + possible_employers.Add(GLOB.syndicate_employers, GLOB.nanotrasen_employers) - if(istype(ending_objective, /datum/objective/hijack)) - possible_employers -= GLOB.normal_employers - else //escape or martyrdom - possible_employers -= GLOB.hijack_employers + if(istype(ending_objective, /datum/objective/hijack)) + possible_employers -= GLOB.normal_employers + else //escape or martyrdom + possible_employers -= GLOB.hijack_employers - switch(faction) - if(FLAVOR_FACTION_SYNDICATE) - possible_employers -= GLOB.nanotrasen_employers - if(FLAVOR_FACTION_NANOTRASEN) - possible_employers -= GLOB.syndicate_employers - employer = pick(possible_employers) + switch(faction) + if(FLAVOR_FACTION_SYNDICATE) + possible_employers -= GLOB.nanotrasen_employers + if(FLAVOR_FACTION_NANOTRASEN) + possible_employers -= GLOB.syndicate_employers + employer = pick(possible_employers) traitor_flavor = strings(TRAITOR_FLAVOR_FILE, employer) /// Generates a complete set of traitor objectives up to the traitor objective limit, including non-generic objectives such as martyr and hijack. @@ -308,6 +309,7 @@ data["allies"] = traitor_flavor["allies"] data["goal"] = traitor_flavor["goal"] data["has_uplink"] = uplink ? TRUE : FALSE + data["given_uplink"] = give_uplink if(uplink) data["uplink_intro"] = traitor_flavor["uplink"] data["uplink_unlock_info"] = uplink.unlock_text diff --git a/code/modules/uplink/uplink_items/contractor.dm b/code/modules/uplink/uplink_items/contractor.dm index 1364f8b088b..b774d05e59d 100644 --- a/code/modules/uplink/uplink_items/contractor.dm +++ b/code/modules/uplink/uplink_items/contractor.dm @@ -82,28 +82,9 @@ cost = 1 /datum/uplink_item/contractor/partner - name = "Reinforcements" - desc = "Upon purchase we'll contact available units in the area. Should there be an agent free, \ - we'll send them down to assist you immediately. If no units are free, we give a full refund." - item = /obj/effect/gibspawner/generic + name = "Contractor Reinforcement" + desc = "A reinforecment operative will be sent to aid you in your goals, \ + they are paid separately, and will not take a cut from your profits." + item = /obj/item/antag_spawner/loadout/contractor limited_stock = 1 cost = 2 - -/datum/uplink_item/contractor/partner/spawn_item(spawn_path, mob/user, datum/uplink_handler/uplink_handler, atom/movable/source) - to_chat(user, span_notice("The uplink vibrates quietly, connecting to nearby agents...")) - var/list/candidates = SSpolling.poll_ghost_candidates( - question = "Do you want to play as the Contractor Support Unit for [user.real_name]?", - check_jobban = ROLE_TRAITOR, - role = ROLE_TRAITOR, - poll_time = 10 SECONDS, - ignore_category = POLL_IGNORE_CONTRACTOR_SUPPORT, - pic_source = /obj/item/modular_computer/pda/syndicate_contract_uplink, - role_name_text = "contractor support unit", - ) - if(!LAZYLEN(candidates)) - to_chat(user, span_notice("No available agents at this time, please try again later.")) - limited_stock++ - return //bobux no icon - var/mob/dead/observer/selected_player = pick(candidates) - uplink_handler.contractor_hub.contractor_teammate = spawn_contractor_partner(user, selected_player.key) - return source //for log icon diff --git a/strings/antagonist_flavor/traitor_flavor.json b/strings/antagonist_flavor/traitor_flavor.json index 93da8d01374..773d2f55370 100644 --- a/strings/antagonist_flavor/traitor_flavor.json +++ b/strings/antagonist_flavor/traitor_flavor.json @@ -111,5 +111,13 @@ "roundend_report": "was a terrorist from Waffle Corporation.", "ui_theme": "syndicate", "uplink": "You have been provided with a standard uplink to accomplish your task." + }, + "Contractor Support Unit": { + "allies": "You are being sent to help your designated agent. Their allegiences are above all others.", + "goal": "Help your designated agent to the furtest extent you can, their life is above your own.", + "introduction": "You are the Contractor Support Agent.", + "roundend_report": "was a contractor support agent.", + "ui_theme": "syndicate", + "uplink": "You do not come with your own uplink, defer to your agent." } } diff --git a/tgui/packages/tgui/interfaces/AntagInfoTraitor.tsx b/tgui/packages/tgui/interfaces/AntagInfoTraitor.tsx index 049a70313b8..3aea989ac27 100644 --- a/tgui/packages/tgui/interfaces/AntagInfoTraitor.tsx +++ b/tgui/packages/tgui/interfaces/AntagInfoTraitor.tsx @@ -37,6 +37,7 @@ type Info = { has_uplink: BooleanLike; uplink_intro: string; uplink_unlock_info: string; + given_uplink: BooleanLike; objectives: Objective[]; }; @@ -233,7 +234,7 @@ const CodewordsSection = (props) => { // SKYRAT EDIT: change height from 580 to 650 export const AntagInfoTraitor = (props) => { const { data } = useBackend(); - const { theme } = data; + const { theme, given_uplink } = data; return ( @@ -248,9 +249,11 @@ export const AntagInfoTraitor = (props) => { - - - + {!!given_uplink && ( + + + + )}