Files
Bubberstation/code/modules/uplink/uplink_devices.dm
Sol N 11cbbba018 Replaceable Traitor Uplinks (#74315)
## About The Pull Request

Following [from the suggestion in this hackmd
](https://hackmd.io/IkDWWkpfQa2lkdevsnLqhA?view#Replacement-Uplinks)with
a few twists of my own, I have made a method for traitors to acquire a
replacement traitor uplink that has its own set of flaws and limiters in
order to prevent abuse.


![ZC0WYDFRzc](https://user-images.githubusercontent.com/116288367/228101432-9352390b-9538-4c62-8dc4-55e2e798c466.png)

The basic pitch is as follows, all traitors now start with a new,
crafting recipe exclusive to them, it costs a teleport beacon, a
bluespace crystal, and some iron and cable coil, and then allows them to
build a static, dense machine that they can synchronize with, which
allows the machine to know what signal it should be looking out for from
the traitor.

![dreamseeker_iErI3vju0C](https://user-images.githubusercontent.com/116288367/228094286-c2bca198-82cd-4ce0-a4a7-c26c24a9327c.gif)

The traitor then uses any radio, sets it to the frequency that has been
added to their static antagonist ui, and then speaks their codeword,
also in the ui, and then a few things happen.

![dreamseeker_gbzSFeHuS5](https://user-images.githubusercontent.com/116288367/228094354-a649c713-f013-4ac2-b8d7-0754a852f987.gif)

Most obviously, they get a replacement uplink that is in the conspicuous
shape of the nukie or lone op uplink. This uplink can be unlocked by
speaking your replacement codeword to it again, it remembers your
previous TC amount and locks all other uplinks associated with your
uplink handler(they can then be unlocked as normal). It also destroys
any other replacement uplinks associated with your uplink handler, which
means you can never have more than one replacement uplink.

This means that if your uplink has been confiscated and you left it
unlocked, if it hasn't been emptied out you can continue from where you
were, and if you want to get back on the TC grind you won't lose the new
TC to whoever stole your uplink. Of course, the new uplink can not be
locked, so you have to be more careful with it or buy an uplink implant
and destroy it. You can destroy your replacement uplink with a
screwdriver right click, same for the machine.

Additionally, the Syndicate Uplink Beacon has another quirk to it, which
is that the teleporter beacon used to create it is intact, which means
people eagle eyed on the teleporter console could go find you, not to
mention that if you use an existing teleporter beacon, someone might
notice its gone missing...

oh also while making the replacement uplink i found a bug caused by a
recent pr that broke debug uplinks due to them not having a purchase
log. thats fixed too

## Why It's Good For The Game

It can be easy to lose your uplink, and as a traitor having your uplink
confiscated, even if it is locked, feels really bad. While the old
traitor objectives were added back to prog traitor to prevent situations
where a confiscated uplink meant that you were completely aimless, I
think that having a backup solution would be good for more inexperienced
traitors or for ones who get unlucky.

Hopefully this is generally balanced well enough but there are a few
levers that can be pulled, but overall I do think that making it so that
traitors can always get a chance to get an uplink and do some objectives
is good for the game. I like the idea of someone getting perma'd,
someone breaks them out, they both craft a new uplink beacon, and then
they go back and get the traitors old gear with stuff they got from the
new uplink, I think that's a cool possibility to throw into the sandbox.

## Changelog
🆑
add: Added new syndicate uplink beacon and associated systems that allow
you to get a replacement traitor uplink
fix: Debug & nukie uplinks no longer runtime and work properly again
/🆑
2023-04-05 16:54:22 +01:00

120 lines
4.2 KiB
Plaintext

// A collection of pre-set uplinks, for admin spawns.
// Radio-like uplink; not an actual radio because this uplink is most commonly
// used for nuke ops, for whom opening the radio GUI and the uplink GUI
// simultaneously is an annoying distraction.
/obj/item/uplink
name = "station bounced radio"
icon = 'icons/obj/radio.dmi'
icon_state = "radio"
inhand_icon_state = "radio"
worn_icon_state = "radio"
desc = "A basic handheld radio that communicates with local telecommunication networks."
lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi'
dog_fashion = /datum/dog_fashion/back
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_BELT
throw_speed = 3
throw_range = 7
w_class = WEIGHT_CLASS_SMALL
/// The uplink flag for this type.
/// See [`code/__DEFINES/uplink.dm`]
var/uplink_flag = UPLINK_TRAITORS
/// If the uplink is lockable, which defaults to false which most subtypes of this item are for debug reasons
var/lockable_uplink = FALSE
/obj/item/uplink/Initialize(mapload, owner, tc_amount = 20, datum/uplink_handler/uplink_handler_override = null)
. = ..()
AddComponent(\
/datum/component/uplink, \
owner = owner, \
lockable = lockable_uplink, \
enabled = TRUE, \
uplink_flag = uplink_flag, \
starting_tc = tc_amount, \
uplink_handler_override = uplink_handler_override, \
)
/obj/item/uplink/debug
name = "debug uplink"
/obj/item/uplink/debug/Initialize(mapload, owner, tc_amount = 9000, datum/uplink_handler/uplink_handler_override = null)
. = ..()
var/datum/component/uplink/hidden_uplink = GetComponent(/datum/component/uplink)
hidden_uplink.name = "debug uplink"
hidden_uplink.uplink_handler.debug_mode = TRUE
/obj/item/uplink/nuclear
uplink_flag = UPLINK_NUKE_OPS
/obj/item/uplink/nuclear/debug
name = "debug nuclear uplink"
uplink_flag = UPLINK_NUKE_OPS
/obj/item/uplink/nuclear/debug/Initialize(mapload, owner, tc_amount = 9000, datum/uplink_handler/uplink_handler_override = null)
. = ..()
var/datum/component/uplink/hidden_uplink = GetComponent(/datum/component/uplink)
hidden_uplink.name = "debug nuclear uplink"
hidden_uplink.uplink_handler.debug_mode = TRUE
/obj/item/uplink/nuclear_restricted
uplink_flag = UPLINK_NUKE_OPS
/obj/item/uplink/nuclear_restricted/Initialize(mapload)
. = ..()
var/datum/component/uplink/hidden_uplink = GetComponent(/datum/component/uplink)
hidden_uplink.allow_restricted = FALSE
/obj/item/uplink/clownop
uplink_flag = UPLINK_CLOWN_OPS
/obj/item/uplink/old
name = "dusty radio"
desc = "A dusty looking radio."
/obj/item/uplink/old/Initialize(mapload, owner, tc_amount = 10, datum/uplink_handler/uplink_handler_override = null)
. = ..()
var/datum/component/uplink/hidden_uplink = GetComponent(/datum/component/uplink)
hidden_uplink.name = "dusty radio"
// Uplink subtype used as replacement uplink
/obj/item/uplink/replacement
lockable_uplink = TRUE
/obj/item/uplink/replacement/Initialize(mapload, owner, tc_amount = 10, datum/uplink_handler/uplink_handler_override = null)
. = ..()
var/datum/component/uplink/hidden_uplink = GetComponent(/datum/component/uplink)
var/mob/living/replacement_needer = owner
if(!istype(replacement_needer))
return
var/datum/antagonist/traitor/traitor_datum = replacement_needer?.mind.has_antag_datum(/datum/antagonist/traitor)
hidden_uplink.unlock_code = traitor_datum?.replacement_uplink_code
become_hearing_sensitive()
/obj/item/uplink/replacement/screwdriver_act_secondary(mob/living/user, obj/item/tool)
tool.play_tool_sound(src)
balloon_alert(user, "deconstructing...")
if (!do_after(user, 3 SECONDS, target = src))
return FALSE
qdel(src)
return TRUE
/obj/item/uplink/replacement/examine(mob/user)
. = ..()
if(!IS_TRAITOR(user))
return
. += span_notice("You can destroy this device with a screwdriver.")
// Multitool uplink
/obj/item/multitool/uplink/Initialize(mapload, owner, tc_amount = 20, datum/uplink_handler/uplink_handler_override = null)
. = ..()
AddComponent(/datum/component/uplink, owner, FALSE, TRUE, UPLINK_TRAITORS, tc_amount)
// Pen uplink
/obj/item/pen/uplink/Initialize(mapload, owner, tc_amount = 20, datum/uplink_handler/uplink_handler_override = null)
. = ..()
AddComponent(/datum/component/uplink, owner, TRUE, FALSE, UPLINK_TRAITORS, tc_amount)