[NO GBP] Decthulufies tethers to stop players from turning themselves into MODsuit bodyhorror (#88289)

## About The Pull Request
Not adding a limit on how many you can have attached at once was a
mistake. MODsuits can only attach one tether at a time and they're
*slightly* slower to cut. You still can attach yourself to more than one
anchor manually (or mob via embedding), but this prevents you from being
attached to more than one machine/structure at a time. Tether anchors
now also only support one link at most.
Tethers no longer require you to click on a specific tile and have a
couple of transparent pixels to the side to make them easier to cut in a
hurry.
Closes #88057

## Why It's Good For The Game


![image](https://github.com/user-attachments/assets/4702e57c-4366-45db-99e8-099b4d9c500d)


![image](https://github.com/user-attachments/assets/3808633b-43c0-49ee-8ef6-9b06f29d1ff1)

## Changelog
🆑
fix: You cannot have more than one MODtether (excluding manual
connections)
qol: Tethers are easier to cut (require less pixelhunting)
/🆑
This commit is contained in:
SmArtKar
2024-12-01 14:28:40 +01:00
committed by GitHub
parent 579f5e5a28
commit e1f41fc807
5 changed files with 66 additions and 9 deletions
@@ -91,6 +91,13 @@
cooldown_time = 1.5 SECONDS
required_slots = list(ITEM_SLOT_GLOVES)
/obj/item/mod/module/tether/used()
if(HAS_TRAIT_FROM(mod.wearer, TRAIT_TETHER_ATTACHED, REF(src)))
balloon_alert(mod.wearer, "already tethered!")
playsound(src, 'sound/items/weapons/gun/general/dry_fire.ogg', 25, TRUE)
return FALSE
return ..()
/obj/item/mod/module/tether/on_select_use(atom/target)
. = ..()
if(!.)
@@ -139,7 +146,10 @@
/obj/projectile/tether/proc/on_embedded(datum/source, obj/item/payload, atom/hit)
SIGNAL_HANDLER
firer.AddComponent(/datum/component/tether, hit, 7, "MODtether", payload, parent_module = parent_module)
if (HAS_TRAIT_FROM(hit, TRAIT_TETHER_ATTACHED, REF(parent_module)))
return
firer.AddComponent(/datum/component/tether, hit, 7, "MODtether", payload, parent_module = parent_module, tether_trait_source = REF(parent_module))
/obj/projectile/tether/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change)
. = ..()
@@ -161,7 +171,12 @@
return
if (istype(target, /obj/item/tether_anchor) || isstructure(target) || ismachinery(target))
firer.AddComponent(/datum/component/tether, target, 7, "MODtether", parent_module = parent_module)
if(HAS_TRAIT_FROM(target, TRAIT_TETHER_ATTACHED, REF(parent_module)))
return
var/avoid_target_trait = FALSE
if (istype(target, /obj/item/tether_anchor))
avoid_target_trait = TRUE
firer.AddComponent(/datum/component/tether, target, 7, "MODtether", parent_module = parent_module, tether_trait_source = REF(parent_module), no_target_trait = avoid_target_trait)
return
var/hitx = impact_x
@@ -182,7 +197,7 @@
anchor.pixel_x = hitx
anchor.pixel_y = hity
anchor.anchored = TRUE
firer.AddComponent(/datum/component/tether, anchor, 7, "MODtether", parent_module = parent_module)
firer.AddComponent(/datum/component/tether, anchor, 7, "MODtether", parent_module = parent_module, tether_trait_source = REF(parent_module))
/obj/projectile/tether/Destroy()
QDEL_NULL(line)
@@ -210,8 +225,12 @@
if (!can_interact(user) || !user.CanReach(src) || !isturf(loc))
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
if(HAS_TRAIT_FROM(user, TRAIT_TETHER_ATTACHED, REF(src)))
balloon_alert(user, "already tethered!")
return
balloon_alert(user, "attached tether")
user.AddComponent(/datum/component/tether, src, 7, "tether")
user.AddComponent(/datum/component/tether, src, 7, "tether", tether_trait_source = REF(src))
return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN
/obj/item/tether_anchor/mouse_drop_receive(atom/target, mob/user, params)
@@ -221,9 +240,13 @@
if (!isliving(target) || !target.CanReach(src))
return
if(HAS_TRAIT_FROM(target, TRAIT_TETHER_ATTACHED, REF(src)))
balloon_alert(user, "already tethered!")
return
if (target == user)
balloon_alert(user, "attached tether")
user.AddComponent(/datum/component/tether, src, 7, "tether")
user.AddComponent(/datum/component/tether, src, 7, "tether", tether_trait_source = REF(src), no_target_trait = TRUE)
return
balloon_alert(user, "attaching tether...")
@@ -231,9 +254,13 @@
if (!do_after(user, 5 SECONDS, target))
return
if(HAS_TRAIT_FROM(target, TRAIT_TETHER_ATTACHED, REF(src)))
balloon_alert(user, "already tethered!")
return
balloon_alert(user, "attached tether")
to_chat(target, span_userdanger("[user] attaches a tether to you!"))
target.AddComponent(/datum/component/tether, src, 7, "tether")
target.AddComponent(/datum/component/tether, src, 7, "tether", tether_trait_source = REF(src), no_target_trait = TRUE)
/datum/embed_data/tether_projectile
embed_chance = 65 //spiky