Skip to content
This repository has been archived by the owner on Aug 21, 2023. It is now read-only.

vehicle chaining #941

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions beestation.dme
Original file line number Diff line number Diff line change
Expand Up @@ -3719,6 +3719,7 @@
#include "monkestation\code\datums\votesounds.dm"
#include "monkestation\code\datums\announcers\duke_announcer.dm"
#include "monkestation\code\datums\brain_damage\mild.dm"
#include "monkestation\code\datums\components\chain.dm"
#include "monkestation\code\datums\components\hot_ice.dm"
#include "monkestation\code\datums\components\pricetag.dm"
#include "monkestation\code\datums\components\strong_pull.dm"
Expand Down
44 changes: 44 additions & 0 deletions code/modules/power/cable.dm
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,10 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai
full_w_class = WEIGHT_CLASS_SMALL
grind_results = list(/datum/reagent/copper = 2) //2 copper per cable in the coil
usesound = 'sound/items/deconstruct.ogg'
//MONKESTATION EDIT: The target when tethering two things together
var/atom/movable/tether_target
//MONKESTATION EDIT: A temporary tether before they attach the vehicle to the second thing
var/datum/component/chain/temp_tether

/obj/item/stack/cable_coil/cyborg
is_cyborg = 1
Expand Down Expand Up @@ -589,6 +593,46 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai
amount += extra
update_icon()

//MONKESTATION EDIT: Tethering people to vehicles
/obj/item/stack/cable_coil/afterattack(atom/movable/target, mob/user, proximity_flag)
if(!proximity_flag)
return

if(!istype(target))
return ..()

if(QDELETED(temp_tether))
tether_target = null
temp_tether = null

if(target == tether_target)
to_chat(user,"<span class='notice'>You untie the cable from [target].</span>")
qdel(temp_tether)
tether_target = null
temp_tether = null
return

if(!tether_target)
if(istype(target, /obj/vehicle))
to_chat(user,"<span class='notice'>You tie one end of the cable around [target]</span>")
tether_target = target
temp_tether = target.AddComponent(/datum/component/chain, user, 4)
return

user.visible_message("<span class='notice'>[user] begins tying the other end of the cable [target]</span>","<span class='notice'>You begin tying the other end of the cable [target]</span>")
if(do_after(user, 8 SECONDS, target=target))
target.AddComponent(/datum/component/chain, tether_target, 4)
use(1)
qdel(temp_tether)
temp_tether = null
tether_target = null

/obj/item/stack/cable_coil/dropped(mob/user)
. = ..()
if(temp_tether)
qdel(temp_tether)
temp_tether = null
tether_target = null


///////////////////////////////////////////////
Expand Down
124 changes: 124 additions & 0 deletions monkestation/code/datums/components/chain.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@

/*
This component attaches to things that'll follow another object
Like connecting a person to a wheelchair so they get dragged behind it
*/
/datum/component/chain
//The thing the parent will follow
var/atom/movable/attachment_point

var/atom/movable/owner
var/max_dist
var/equal_force

var/datum/beam/tether_beam

/datum/component/chain/Initialize(target, max_dist=3, equal_force = TRUE, draw_beam = TRUE)
if(!ismovableatom(parent) || !ismovableatom(target))
return COMPONENT_INCOMPATIBLE

owner = parent
attachment_point = target
src.max_dist = max_dist
src.equal_force = equal_force

if(draw_beam)
tether_beam = owner.Beam(target, "usb_cable_beam", 'icons/obj/wiremod.dmi', maxdistance = max_dist+1)

RegisterSignal(target, COMSIG_MOVABLE_PRE_MOVE, .proc/on_attachment_move)
RegisterSignal(owner, COMSIG_MOVABLE_PRE_MOVE, .proc/on_parent_move)
RegisterSignal(owner, COMSIG_ATOM_ATTACK_HAND, .proc/on_parent_touched)
RegisterSignal(owner, COMSIG_ATOM_TOOL_ACT(TOOL_WIRECUTTER), .proc/on_parent_wirecutters)

if(draw_beam)
RegisterSignal(owner, COMSIG_MOVABLE_MOVED, .proc/on_atom_moved)
RegisterSignal(target, COMSIG_MOVABLE_MOVED, .proc/on_atom_moved)

/datum/component/chain/Destroy(force, silent)
. = ..()
if(tether_beam)
qdel(tether_beam)
tether_beam = null
owner = null
attachment_point = null

/datum/component/chain/proc/on_atom_moved(atom/movable/mover, old_loc, movement_dir, forced, old_locs, momentum_change)
SIGNAL_HANDLER

spawn(0)
tether_beam.recalculate()

/datum/component/chain/proc/on_attachment_move(atom/movable/mover, newloc)
SIGNAL_HANDLER

if(!owner)
qdel(src)
return

var/dist = get_dist(owner,newloc)
if(dist < max_dist)
return

if(!owner.anchored)
owner.Move(get_step_towards(owner,mover))

if(isliving(owner))
var/mob/living/living_owner = owner
living_owner.Knockdown(1 SECONDS)

if(dist > max_dist)
owner.visible_message("<span class='notice'>The tether snaps!</span>")
qdel(src)
return

/datum/component/chain/proc/on_parent_move(atom/movable/mover, newloc)
SIGNAL_HANDLER

if(!attachment_point)
qdel(src)
return

var/dist = get_dist(attachment_point,newloc)
if(dist < max_dist)
return

if(dist > max_dist)
qdel(src)
return

if(attachment_point.anchored)
return COMPONENT_MOVABLE_BLOCK_PRE_MOVE

attachment_point.Move(get_step_towards(attachment_point,mover))

if(equal_force)
return

if(isliving(owner))
var/mob/living/living_owner = owner
living_owner.Knockdown(1 SECONDS)
to_chat(owner,"<span class='notice'>You trip on the tether!</span>")
return COMPONENT_MOVABLE_BLOCK_PRE_MOVE

/datum/component/chain/proc/on_parent_touched(datum/source, mob/user)
SIGNAL_HANDLER

INVOKE_ASYNC(src, .proc/untie_parent, user)

/datum/component/chain/proc/untie_parent(mob/user)
if(user == owner)
user.visible_message("<span class='notice'>[user] begins untying the cable from \himself.</span>","<span class='notice'>You begin untying the cable from yourself.</span>")
else
user.visible_message("<span class='notice'>[user] begins untying the cable from [owner].</span>","<span class='notice'>You begin untying the cable from [owner].</span>")
if(do_mob(user, owner, 10 SECONDS))
qdel(src)

/datum/component/chain/proc/on_parent_wirecutters(datum/source, mob/user)
SIGNAL_HANDLER

if(user == owner)
user.visible_message("<span class='notice'>[user] cuts \himself free.</span>","<span class='notice'>You cut yourself free.</span>")
else
user.visible_message("<span class='notice'>[user] cuts [owner] free.</span>","<span class='notice'>[user] cuts you free] free.</span>")
qdel(src)
return COMPONENT_BLOCK_TOOL_ATTACK