Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MIRROR] New operative reinforcement option: Intelligence Overwatch Agent #2753

Merged
merged 1 commit into from
Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
229 changes: 197 additions & 32 deletions _maps/templates/lazy_templates/nukie_base.dmm

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions code/__DEFINES/cameranets.dm
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@
#define CAMERANET_NETWORK_BAR "bar"
#define CAMERANET_NETWORK_INTERROGATION "interrogation"
#define CAMERANET_NETWORK_ABDUCTOR "abductor"
#define OPERATIVE_CAMERA_NET "operative"
2 changes: 2 additions & 0 deletions code/__DEFINES/dcs/signals/signals_operatives.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/// For when a new teammate is added to a nukie team
#define COMSIG_NUKE_TEAM_ADDITION "nuke_team_addition"
1 change: 1 addition & 0 deletions code/__DEFINES/role_preferences.dm
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
#define ROLE_WIZARD_APPRENTICE "apprentice"
#define ROLE_SYNDICATE_MONKEY "Syndicate Monkey Agent"
#define ROLE_CONTRACTOR_SUPPORT "Contractor Support Unit"
#define ROLE_OPERATIVE_OVERWATCH "Operative Overwatch Agent"
#define ROLE_SYNDICATE_SABOBORG "Syndicate Sabotage Cyborg"
#define ROLE_SYNDICATE_MEDBORG "Syndicate Medical Cyborg"
#define ROLE_SYNDICATE_ASSAULTBORG "Syndicate Assault Cyborg"
Expand Down
1 change: 1 addition & 0 deletions code/_globalvars/lists/mapping.dm
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ GLOBAL_LIST_EMPTY(gorilla_start)
GLOBAL_LIST_EMPTY(wizardstart)
GLOBAL_LIST_EMPTY(nukeop_start)
GLOBAL_LIST_EMPTY(nukeop_leader_start)
GLOBAL_LIST_EMPTY(nukeop_overwatch_start)
GLOBAL_LIST_EMPTY(newplayer_start)
GLOBAL_LIST_EMPTY(prisonwarp) //admin prisoners go to these
GLOBAL_LIST_EMPTY(holdingfacility) //captured people go here (ninja energy net)
Expand Down
10 changes: 10 additions & 0 deletions code/game/objects/effects/landmarks.dm
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,16 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark)
GLOB.nukeop_leader_start += loc
return INITIALIZE_HINT_QDEL

/obj/effect/landmark/start/nukeop_overwatch
name = "nukeop overwatch"
icon = 'icons/effects/landmarks_static.dmi'
icon_state = "snukeop_leader_spawn"

/obj/effect/landmark/start/nukeop_overwatch/Initialize(mapload)
..()
GLOB.nukeop_overwatch_start += loc
return INITIALIZE_HINT_QDEL

// Must be immediate because players will
// join before SSatom initializes everything.
INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
Expand Down
33 changes: 26 additions & 7 deletions code/modules/antagonists/_common/antag_spawner.dm
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,13 @@
/// The applied outfit
var/datum/outfit/syndicate/outfit = /datum/outfit/syndicate/reinforcement
/// The antag datum applied
var/datum/antagonist/nukeop/reinforcement/antag_datum = /datum/antagonist/nukeop/reinforcement
var/antag_datum = /datum/antagonist/nukeop/reinforcement
/// Style used by the droppod
var/pod_style = STYLE_SYNDICATE
/// Do we use a random subtype of the outfit?
var/use_subtypes = TRUE
/// Where do we land our pod?
var/turf/spawn_location

/obj/item/antag_spawner/nuke_ops/proc/check_usability(mob/user)
if(used)
Expand Down Expand Up @@ -143,7 +145,6 @@

/obj/item/antag_spawner/nuke_ops/spawn_antag(client/our_client, turf/T, kind, datum/mind/user)
var/mob/living/carbon/human/nukie = new()
var/obj/structure/closet/supplypod/pod = setup_pod()
our_client.prefs.safe_transfer_prefs_to(nukie, is_antag = TRUE)
nukie.ckey = our_client.key
var/datum/mind/op_mind = nukie.mind
Expand All @@ -152,15 +153,33 @@
else
nukie.forceMove(locate(1,1,1))

antag_datum = new()

antag_datum.nukeop_outfit = use_subtypes ? pick(subtypesof(outfit)) : outfit
var/new_datum = new antag_datum()

var/datum/antagonist/nukeop/creator_op = user.has_antag_datum(/datum/antagonist/nukeop, TRUE)
op_mind.add_antag_datum(antag_datum, creator_op ? creator_op.get_team() : null)
op_mind.add_antag_datum(new_datum, creator_op ? creator_op.get_team() : null)
op_mind.special_role = special_role_name

if(outfit)
var/datum/antagonist/nukeop/nukie_datum = op_mind.has_antag_datum(antag_datum)
nukie_datum.nukeop_outfit = use_subtypes ? pick(subtypesof(outfit)) : outfit

var/obj/structure/closet/supplypod/pod = setup_pod()
nukie.forceMove(pod)
new /obj/effect/pod_landingzone(get_turf(src), pod)
new /obj/effect/pod_landingzone(spawn_location ? spawn_location : get_turf(src), pod)

/obj/item/antag_spawner/nuke_ops/overwatch
name = "overwatch support beacon"
desc = "Assigns an Overwatch Intelligence Agent to your operation. Stationed at their own remote outpost, they can view station cameras, alarms, and even move the Infiltrator shuttle! \
Also, all members of your operation will recieve body cameras that they can view your progress from."
special_role_name = ROLE_OPERATIVE_OVERWATCH
outfit = /datum/outfit/syndicate/support
use_subtypes = FALSE
antag_datum = /datum/antagonist/nukeop/support

/obj/item/antag_spawner/nuke_ops/overwatch/Initialize(mapload)
. = ..()
if(length(GLOB.nukeop_overwatch_start)) //Otherwise, it will default to the datum's spawn point anyways
spawn_location = pick(GLOB.nukeop_overwatch_start)

//////CLOWN OP
/obj/item/antag_spawner/nuke_ops/clown
Expand Down
1 change: 0 additions & 1 deletion code/modules/antagonists/nukeop/datums/operative.dm
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
var/datum/component/uplink/uplink = owner.find_syndicate_uplink()
if (uplink)
uplink.uplink_handler.add_telecrystals(extra_tc)

var/datum/component/uplink/uplink = owner.find_syndicate_uplink()
if(uplink)
var/datum/team/nuclear/nuke_team = get_team()
Expand Down
54 changes: 54 additions & 0 deletions code/modules/antagonists/nukeop/datums/operative_support.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/datum/antagonist/nukeop/support
name = ROLE_OPERATIVE_OVERWATCH
show_to_ghosts = TRUE
send_to_spawnpoint = TRUE
nukeop_outfit = /datum/outfit/syndicate/support

/datum/antagonist/nukeop/support/greet()
owner.current.playsound_local(get_turf(owner.current), 'sound/machines/printer.ogg', 100, 0, use_reverb = FALSE)
to_chat(owner, span_big("You are a [name]! You've been temporarily assigned to provide camera overwatch and manage communications for a nuclear operative team!"))
to_chat(owner, span_red("Use your tools to set up your equipment however you like, but do NOT attempt to leave your outpost."))
owner.announce_objectives()

/datum/antagonist/nukeop/support/on_gain()
..()
for(var/datum/mind/teammate_mind in nuke_team.members)
var/mob/living/our_teammate = teammate_mind.current
our_teammate.AddComponent( \
/datum/component/simple_bodycam, \
camera_name = "operative bodycam", \
c_tag = "[our_teammate.real_name]", \
network = OPERATIVE_CAMERA_NET, \
emp_proof = FALSE, \
)
our_teammate.playsound_local(get_turf(owner.current), 'sound/weapons/egloves.ogg', 100, 0)
to_chat(our_teammate, span_notice("A Syndicate Overwatch Intelligence Agent has been assigned to your team. Smile, you're on camera!"))

RegisterSignal(nuke_team, COMSIG_NUKE_TEAM_ADDITION, PROC_REF(late_bodycam))

owner.current.grant_language(/datum/language/codespeak)

/datum/antagonist/nukeop/support/get_spawnpoint()
return pick(GLOB.nukeop_overwatch_start)

/datum/antagonist/nukeop/support/forge_objectives()
var/datum/objective/overwatch/objective = new
objective.owner = owner
objectives += objective

/datum/antagonist/nukeop/support/proc/late_bodycam(datum/source, mob/living/new_teammate)
SIGNAL_HANDLER
new_teammate.AddComponent( \
/datum/component/simple_bodycam, \
camera_name = "operative bodycam", \
c_tag = "[new_teammate.real_name]", \
network = OPERATIVE_CAMERA_NET, \
emp_proof = FALSE, \
)
to_chat(new_teammate, span_notice("You have been equipped with a bodycam, viewable by your Overwatch Intelligence Agent. Make sure to show them a good performance!"))

/datum/objective/overwatch
explanation_text = "Provide intelligence support and overwatch to your operative team!"

/datum/objective/overwatch/check_completion()
return GLOB.station_was_nuked
4 changes: 4 additions & 0 deletions code/modules/antagonists/nukeop/datums/operative_team.dm
Original file line number Diff line number Diff line change
Expand Up @@ -313,5 +313,9 @@
return TRUE
return FALSE

/datum/team/nuclear/add_member(datum/mind/new_member)
..()
SEND_SIGNAL(src, COMSIG_NUKE_TEAM_ADDITION, new_member.current)

#undef SPAWN_AT_BASE
#undef SPAWN_AT_INFILTRATOR
46 changes: 46 additions & 0 deletions code/modules/antagonists/nukeop/equipment/overwatch_tools.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
///One of the special items that spawns in the overwatch agent's room.
/obj/item/paper/fluff/overwatch
name = "OVERWATCH NOTES #1"
color = COLOR_RED
desc = "A note from Syndicate leadership regarding your new job. You should read this!"
default_raw_text = @{"
Congratulations! You have been picked to be the Sole Survivor of an anti-Nanotrasen suicide mission!
We're kidding of course, these types of missions tend to have abnormally high survival rates. I guess that says a lot about who your team will be going up against.
<br>
You've been assigned to provide intelligence support to the ground-pounders carrying out the operation.
Each operative has been equipped with a bodycam that can be accessed via your Overwatch Camera Console.
Additionally, you have been given the boards to access station alerts, cameras, and remotely control the infiltrator shuttle.
<br>
Feel free to set up your workplace however you like. We've provided the tools and boards in your backroom.
<br>
Happy hunting!
"}

/obj/machinery/computer/security/overwatch
name = "overwatch camera console"
desc = "Allows you to view members of your operative team via their bodycam feeds. We call them 'bodycams', but they're actually a swarm of tiny, near-imperceptible camera drones that follow each target. \
It is believed that adversaries either don't notice the drones, or avoid attacking them in hopes that they'll capture footage of their combat prowess against our operatives."
icon_screen = "commsyndie"
icon_keyboard = "syndie_key"
network = list(OPERATIVE_CAMERA_NET)
circuit = /obj/item/circuitboard/computer/overwatch

/obj/item/circuitboard/computer/overwatch
name = "Overwatch Body Cameras"
build_path = /obj/machinery/computer/security/overwatch
greyscale_colors = CIRCUIT_COLOR_SECURITY

/obj/item/circuitboard/computer/syndicate_shuttle_docker
name = "Shuttle Controller"
build_path = /obj/machinery/computer/camera_advanced/shuttle_docker/syndicate
greyscale_colors = CIRCUIT_COLOR_SECURITY

/obj/item/clothing/glasses/overwatch
name = "intelligence glasses"
desc = "A set of incredibly advanced sunglasses, providing you with an array of different sensor scans and visual readouts for pretty much anything you look at. \
It's kind of overwhelming, actually. Wearing this for a few hours will probably give you a migrane."
icon_state = "sunhudmed"
flags_cover = GLASSESCOVERSEYES
flash_protect = FLASH_PROTECTION_WELDER
clothing_traits = list(TRAIT_REAGENT_SCANNER)
var/list/hudlist = list(DATA_HUD_MEDICAL_ADVANCED, DATA_HUD_DIAGNOSTIC_ADVANCED, DATA_HUD_SECURITY_ADVANCED)
21 changes: 21 additions & 0 deletions code/modules/antagonists/nukeop/outfits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,17 @@
r_hand = /obj/item/tank/internals/plasmaman/belt/full
tc = 0

/datum/outfit/syndicate/support/plasmaman
name = "Nuclear Operative Overwatch Agent (Plasmaman)"
back = /obj/item/storage/backpack/satchel
head = /obj/item/clothing/head/helmet/space/plasmaman/syndie
uniform = /obj/item/clothing/under/plasmaman/syndicate
glasses = /obj/item/clothing/glasses/overwatch
suit = /obj/item/clothing/suit/jacket/letterman_syndie
r_hand = /obj/item/tank/internals/plasmaman/belt/full
command_radio = TRUE
tc = 0

/datum/outfit/syndicate/reinforcement/gorlex
name = "Syndicate Operative - Gorlex Reinforcement"
suit = /obj/item/clothing/suit/armor/vest/alt
Expand Down Expand Up @@ -191,3 +202,13 @@
var/obj/item/shield/energy/shield = locate() in H.held_items
shield.icon_state = "[shield.base_icon_state]1"
H.update_held_items()

/datum/outfit/syndicate/support
name = "Nuclear Operative Overwatch Agent"
back = /obj/item/storage/backpack/satchel
uniform = /obj/item/clothing/under/syndicate/tacticool
glasses = /obj/item/clothing/glasses/overwatch
suit = /obj/item/clothing/suit/jacket/letterman_syndie
shoes = /obj/item/clothing/shoes/sandal
command_radio = TRUE
tc = 0
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
/datum/outfit/syndicate/reinforcement/interdyne = /datum/outfit/syndicate/reinforcement/plasmaman,
/datum/outfit/syndicate/reinforcement/mi13 = /datum/outfit/syndicate/reinforcement/plasmaman,
/datum/outfit/syndicate/reinforcement/waffle = /datum/outfit/syndicate/reinforcement/plasmaman,
/datum/outfit/syndicate/support = /datum/outfit/syndicate/support/plasmaman,
)

/// If the bones themselves are burning clothes won't help you much
Expand Down
3 changes: 3 additions & 0 deletions code/modules/power/cable.dm
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,9 @@ GLOBAL_LIST_INIT(wire_node_generating_types, typecacheof(list(/obj/structure/gri
/obj/item/stack/cable_coil/five
amount = 5

/obj/item/stack/cable_coil/thirty
amount = 30

/obj/item/stack/cable_coil/cut
amount = null
icon_state = "coil2"
Expand Down
1 change: 1 addition & 0 deletions code/modules/shuttle/syndicate.dm
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,6 @@
y_offset = -1
whitelist_turfs = list(/turf/open/space, /turf/open/floor/plating, /turf/open/lava, /turf/closed/mineral, /turf/open/openspace, /turf/open/misc)
see_hidden = TRUE
circuit = /obj/item/circuitboard/computer/syndicate_shuttle_docker

#undef SYNDICATE_CHALLENGE_TIMER
8 changes: 8 additions & 0 deletions code/modules/uplink/uplink_items/nukeops.dm
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,14 @@
Its chameleon projector lets it disguise itself as a Nanotrasen cyborg, on top it has thermal vision and a pinpointer."
item = /obj/item/antag_spawner/nuke_ops/borg_tele/saboteur

/datum/uplink_item/reinforcements/overwatch_agent
name = "Overwatch Intelligence Agent"
desc = "An Overwatch Intelligence Agent is assigned to your operation. They can view your progress and help coordinate using your \
operative team's body-cams. They can also pilot the shuttle remotely and view the station's camera net. \
If you're a meathead who's just here to kill people and don't care about strategising or intel, you'll still have someone to bear witness to your murder-spree!"
item = /obj/item/antag_spawner/nuke_ops/overwatch
cost = 12

// ~~ Disposable Sentry Gun ~~
// Technically not a spawn but it is a kind of reinforcement...I guess.

Expand Down
3 changes: 3 additions & 0 deletions tgstation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@
#include "code\__DEFINES\dcs\signals\signals_music.dm"
#include "code\__DEFINES\dcs\signals\signals_object.dm"
#include "code\__DEFINES\dcs\signals\signals_operating_computer.dm"
#include "code\__DEFINES\dcs\signals\signals_operatives.dm"
#include "code\__DEFINES\dcs\signals\signals_painting.dm"
#include "code\__DEFINES\dcs\signals\signals_proxmonitor.dm"
#include "code\__DEFINES\dcs\signals\signals_radiation.dm"
Expand Down Expand Up @@ -3251,10 +3252,12 @@
#include "code\modules\antagonists\nukeop\datums\operative_leader.dm"
#include "code\modules\antagonists\nukeop\datums\operative_lone.dm"
#include "code\modules\antagonists\nukeop\datums\operative_reinforcement.dm"
#include "code\modules\antagonists\nukeop\datums\operative_support.dm"
#include "code\modules\antagonists\nukeop\datums\operative_team.dm"
#include "code\modules\antagonists\nukeop\equipment\borgchameleon.dm"
#include "code\modules\antagonists\nukeop\equipment\nuclear_authentication_disk.dm"
#include "code\modules\antagonists\nukeop\equipment\nuclear_challenge.dm"
#include "code\modules\antagonists\nukeop\equipment\overwatch_tools.dm"
#include "code\modules\antagonists\nukeop\equipment\pinpointer.dm"
#include "code\modules\antagonists\nukeop\equipment\nuclear_bomb\_nuclear_bomb.dm"
#include "code\modules\antagonists\nukeop\equipment\nuclear_bomb\beer_nuke.dm"
Expand Down
Loading