[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

🆑
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.
/🆑

* Fixes contractor support unit

---------

Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com>
This commit is contained in:
SkyratBot
2024-01-25 09:28:51 -05:00
committed by GitHub
co-authored by John Willard
parent b8313673d1
commit d6f58bda31
8 changed files with 72 additions and 82 deletions
+1
View File
@@ -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"
@@ -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."
@@ -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
@@ -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
@@ -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
+4 -23
View File
@@ -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
@@ -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."
}
}
@@ -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<Info>();
const { theme } = data;
const { theme, given_uplink } = data;
return (
<Window width={620} height={650} theme={theme}>
<Window.Content>
@@ -248,9 +249,11 @@ export const AntagInfoTraitor = (props) => {
</Stack.Item>
</Stack>
</Stack.Item>
<Stack.Item>
<UplinkSection />
</Stack.Item>
{!!given_uplink && (
<Stack.Item>
<UplinkSection />
</Stack.Item>
)}
<Stack.Item>
<CodewordsSection />
</Stack.Item>