From 1f124ac835af3395bde39804e36fb51bfe37d74b Mon Sep 17 00:00:00 2001 From: Contrabang <91113370+Contrabang@users.noreply.github.com> Date: Wed, 9 Jul 2025 07:49:40 -0700 Subject: [PATCH] Refactors beams. Adds tethering. IV drips/bags are now tethered. (#29570) * refactor * tether * tetherrrs * logic fix (i hope) * ci fix * ok please work --- code/__DEFINES/dcs/movable_signals.dm | 5 + code/__HELPERS/unsorted.dm | 12 + code/datums/beam.dm | 230 ++++++++++++------ code/datums/components/tether.dm | 173 +++++++++++++ code/datums/movement_detector.dm | 18 ++ .../demons/shadow_demon/shadow_demon.dm | 2 +- code/game/machinery/iv_drip.dm | 5 +- code/game/objects/structures/tables_racks.dm | 7 +- .../changeling/powers/mutations.dm | 2 +- .../simple_animal/hostile/venus_human_trap.dm | 6 +- code/modules/mod/modules/module_kinesis.dm | 8 +- code/modules/projectiles/guns/medbeam.dm | 7 +- .../reagents/reagent_containers/iv_bag.dm | 34 ++- icons/effects/beam.dmi | Bin 27208 -> 28369 bytes paradise.dme | 1 + 15 files changed, 404 insertions(+), 106 deletions(-) create mode 100644 code/datums/components/tether.dm diff --git a/code/__DEFINES/dcs/movable_signals.dm b/code/__DEFINES/dcs/movable_signals.dm index d4b07c5e9b1..24cad49c6b2 100644 --- a/code/__DEFINES/dcs/movable_signals.dm +++ b/code/__DEFINES/dcs/movable_signals.dm @@ -89,3 +89,8 @@ ///from base of /atom/movable/point_at: (atom/A, obj/effect/temp_visual/point/point) #define COMSIG_MOVABLE_POINTED "movable_pointed" + +///signal sent out by /datum/component/tether when durability/line of sight fails : (atom/tethered) +#define COMSIG_TETHER_DESTROYED "tether_snap" +///a signal sent to /datum/component/tether by the tethered object to stop the tethering : (atom/tethered) +#define COMSIG_TETHER_STOP "tether_stop" diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 96bf3eacf4b..d42a77fa1d9 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -61,6 +61,18 @@ else if(dx < 0) . += 360 +/// Angle between two arbitrary points and horizontal line same as [/proc/get_angle] +/proc/get_angle_raw(start_x, start_y, start_pixel_x, start_pixel_y, end_x, end_y, end_pixel_x, end_pixel_y) + var/dy = (32 * end_y + end_pixel_y) - (32 * start_y + start_pixel_y) + var/dx = (32 * end_x + end_pixel_x) - (32 * start_x + start_pixel_x) + if(!dy) + return (dx >= 0) ? 90 : 270 + . = arctan(dx/dy) + if(dy < 0) + . += 180 + else if(dx < 0) + . += 360 + // Returns location. Returns null if no location was found. /proc/get_teleport_loc(turf/location, mob/target, distance = 1, density = TRUE, errorx = 0, errory = 0, eoffsetx = 0, eoffsety = 0) /* diff --git a/code/datums/beam.dm b/code/datums/beam.dm index 19ac0049481..23776d1d8d0 100644 --- a/code/datums/beam.dm +++ b/code/datums/beam.dm @@ -1,91 +1,153 @@ -//Beam Datum and effect +/** # Beam Datum and Effect + * **IF YOU ARE LAZY AND DO NOT WANT TO READ, GO TO THE BOTTOM OF THE FILE AND USE THAT PROC!** + * + * This is the beam datum! It's a really neat effect for the game in drawing a line from one atom to another. + * It has two parts: + * The datum itself which manages redrawing the beam to constantly keep it pointing from the origin to the target. + * The effect which is what the beams are made out of. They're placed in a line from the origin to target, rotated towards the target and snipped off at the end. + * These effects are kept in a list and constantly created and destroyed (hence the proc names draw and reset, reset destroying all effects and draw creating more.) + * + * You can add more special effects to the beam itself by changing what the drawn beam effects do. For example you can make a vine that pricks people by making the beam_type + * include a crossed proc that damages the crosser. Examples in venus_human_trap.dm +*/ /datum/beam + ///where the beam goes from var/atom/origin = null + ///where the beam goes to var/atom/target = null + ///list of beam objects. These have their visuals set by the visuals var which is created on starting var/list/elements = list() - var/icon/base_icon = null + ///icon used by the beam. var/icon - var/icon_state = "" //icon state of the main segments of the beam + ///icon state of the main segments of the beam + var/icon_state = "" + ///The beam will qdel if it's longer than this many tiles. var/max_distance = 0 - var/endtime = 0 - var/sleep_time = 3 - var/finished = FALSE - var/target_oldloc = null - var/origin_oldloc = null - var/static_beam = FALSE - var/beam_type = /obj/effect/ebeam //must be subtype - var/beamcolor + ///the objects placed in the elements list + var/beam_type = /obj/effect/ebeam + ///This is used as the visual_contents of beams, so you can apply one effect to this and the whole beam will look like that. never gets deleted on redrawing. + var/obj/effect/ebeam/visuals + ///The color of the beam we're drawing. + var/beam_color + ///Should we use a turf for origin/target's x and y values instead + var/use_get_turf -/datum/beam/New(beam_origin, beam_target,beam_icon = 'icons/effects/beam.dmi', beam_icon_state = "b_beam", time = 50, maxdistance = 10, btype = /obj/effect/ebeam, beam_sleep_time = 3, beam_color) - endtime = world.time+time - origin = beam_origin - origin_oldloc = get_turf(origin) - target = beam_target - target_oldloc = get_turf(target) - sleep_time = beam_sleep_time - if(origin_oldloc == origin && target_oldloc == target) - static_beam = TRUE - max_distance = maxdistance - base_icon = new(beam_icon,beam_icon_state) - icon = beam_icon - icon_state = beam_icon_state - beam_type = btype - beamcolor = beam_color +/datum/beam/New( + origin, + target, + icon = 'icons/effects/beam.dmi', + icon_state = "b_beam", + time = INFINITY, + max_distance = INFINITY, + beam_type = /obj/effect/ebeam, + beam_color, + use_get_turf = FALSE +) + src.origin = origin + src.target = target + src.icon = icon + src.icon_state = icon_state + src.max_distance = max_distance + src.beam_type = beam_type + src.beam_color = beam_color + src.use_get_turf = use_get_turf + if(time < INFINITY) + QDEL_IN(src, time) +/** + * Proc called by the atom Beam() proc. Sets up signals, and draws the beam for the first time. + */ /datum/beam/proc/Start() + visuals = new beam_type() + visuals.icon = icon + visuals.icon_state = icon_state + visuals.color = beam_color + visuals.vis_flags = VIS_INHERIT_PLANE|VIS_INHERIT_LAYER + visuals.update_appearance() Draw() - while(!finished && origin && target && world.time < endtime && get_dist(origin,target) max_distance) + qdel(src) + return + if(origin.z != target.z) + if(!use_get_turf || !atoms_share_level(get_turf(origin), get_turf(target))) + qdel(src) + return QDEL_LIST_CONTENTS(elements) + INVOKE_ASYNC(src, PROC_REF(Draw)) /datum/beam/Destroy() - Reset() - target = null + QDEL_LIST_CONTENTS(elements) + QDEL_NULL(visuals) + UnregisterSignal(origin, list(COMSIG_MOVABLE_MOVED, COMSIG_PARENT_QDELETING)) + UnregisterSignal(target, list(COMSIG_MOVABLE_MOVED, COMSIG_PARENT_QDELETING)) origin = null + target = null return ..() +/** + * Creates the beam effects and places them in a line from the origin to the target. Sets their rotation to make the beams face the target, too. + */ /datum/beam/proc/Draw() - var/Angle = round(get_angle(origin, target)) + var/origin_px = origin.pixel_x + origin.pixel_w + var/origin_py = origin.pixel_y + origin.pixel_z + var/target_px = target.pixel_x + target.pixel_w + var/target_py = target.pixel_y + target.pixel_z + var/origin_x = origin.x + var/origin_y = origin.y + var/target_x = target.x + var/target_y = target.y + if(use_get_turf) + var/turf/T = get_turf(origin) + origin_x = T.x + origin_y = T.y + T = get_turf(target) + target_x = T.x + target_y = T.y + + var/Angle = get_angle_raw(origin_x, origin_y, origin_px, origin_py, target_x, target_y, target_px, target_py) + ///var/Angle = round(get_angle(origin,target)) var/matrix/rot_matrix = matrix() + var/turf/origin_turf = get_turf(origin) rot_matrix.Turn(Angle) //Translation vector for origin and target - var/DX = (32*target.x+target.pixel_x)-(32*origin.x+origin.pixel_x) - var/DY = (32*target.y+target.pixel_y)-(32*origin.y+origin.pixel_y) + var/DX = (32 * target_x + target_px) - (32 * origin_x + origin_px) + var/DY = (32 * target_y + target_py) - (32 * origin_y + origin_py) var/N = 0 - var/length = round(sqrt((DX)**2+(DY)**2)) //hypotenuse of the triangle formed by target and origin's displacement + var/length = round(sqrt((DX)**2 + (DY)**2)) // hypotenuse of the triangle formed by target and origin's displacement - for(N in 0 to length-1 step 32)//-1 as we want < not <=, but we want the speed of X in Y to Z and step X - var/obj/effect/ebeam/X = new beam_type(origin_oldloc) - X.owner = src - elements |= X + for(N in 0 to length-1 step 32) // -1 as we want < not <=, but we want the speed of X in Y to Z and step X + if(QDELETED(src)) + break + var/obj/effect/ebeam/segment = new beam_type(origin_turf, src) + elements += segment - //Assign icon, for main segments it's base_icon, for the end, it's icon+icon_state - //cropped by a transparent box of length-N pixel size - if(N+32>length) - var/icon/II = new(icon, icon_state) - II.DrawBox(null, 1, (length-N), 32, 32) - X.icon = II + //Assign our single visual ebeam to each ebeam's vis_contents + //ends are cropped by a transparent box icon of length-N pixel size laid over the visuals obj + if(N + 32 > length) //went past the target, we draw a box of space to cut away from the beam sprite so the icon actually ends at the center of the target sprite + var/icon/II = new(icon, icon_state)//this means we exclude the overshooting object from the visual contents which does mean those visuals don't show up for the final bit of the beam... + II.DrawBox(null, 1, (length-N), 32, 32)//in the future if you want to improve this, remove the drawbox and instead use a 513 filter to cut away at the final object's icon + segment.icon = II + segment.color = beam_color else - X.icon = base_icon - if(beamcolor) - X.color = beamcolor - X.transform = rot_matrix + segment.vis_contents += visuals + segment.transform = rot_matrix //Calculate pixel offsets (If necessary) var/Pixel_x @@ -93,40 +155,44 @@ if(DX == 0) Pixel_x = 0 else - Pixel_x = round(sin(Angle)+32*sin(Angle)*(N+16)/32) + Pixel_x = round(sin(Angle) + 32 * sin(Angle) * (N + 16) / 32) if(DY == 0) Pixel_y = 0 else Pixel_y = round(cos(Angle) + 32 * cos(Angle) * (N + 16) / 32) //Position the effect so the beam is one continous line - var/final_x = X.x - var/final_y = X.y - if(abs(Pixel_x)>32) - final_x += Pixel_x > 0 ? round(Pixel_x / 32) : CEILING(Pixel_x / 32, 1) + var/final_x = segment.x + var/final_y = segment.y + if(abs(Pixel_x) > 32) + final_x += Pixel_x > 0 ? round(Pixel_x/32) : CEILING(Pixel_x/32, 1) Pixel_x %= 32 - if(abs(Pixel_y)>32) - final_y += Pixel_y > 0 ? round(Pixel_y / 32) : CEILING(Pixel_y / 32, 1) + if(abs(Pixel_y) > 32) + final_y += Pixel_y > 0 ? round(Pixel_y/32) : CEILING(Pixel_y/32, 1) Pixel_y %= 32 - var/turf/T = locate(final_x, final_y, X.z) - if(T) - X.forceMove(locate(final_x, final_y, X.z)) - X.pixel_x = origin.pixel_x + Pixel_x - X.pixel_y = origin.pixel_y + Pixel_y + segment.forceMove(locate(final_x, final_y, segment.z)) + segment.pixel_x = origin_px + Pixel_x + segment.pixel_y = origin_py + Pixel_y + CHECK_TICK /obj/effect/ebeam mouse_opacity = MOUSE_OPACITY_TRANSPARENT anchored = TRUE var/datum/beam/owner -/obj/effect/ebeam/Initialize(mapload) +/obj/effect/ebeam/Initialize(mapload, beam_owner) . = ..() + owner = beam_owner var/static/list/loc_connections = list( COMSIG_ATOM_ENTERED = PROC_REF(on_atom_entered), ) AddElement(/datum/element/connect_loc, loc_connections) +/obj/effect/ebeam/Destroy() + owner = null + return ..() + /obj/effect/ebeam/proc/on_atom_entered(datum/source, atom/movable/entered) SIGNAL_HANDLER // ON_ATOM_ENTERED return @@ -134,10 +200,6 @@ /obj/effect/ebeam/ex_act(severity) return -/obj/effect/ebeam/Destroy() - owner = null - return ..() - /obj/effect/ebeam/singularity_pull() return @@ -178,7 +240,15 @@ var/armor = L.run_armor_check(limb_to_hit, LASER) L.apply_damage(damage, BURN, limb_to_hit, armor) -/atom/proc/Beam(atom/BeamTarget, icon_state="b_beam", icon='icons/effects/beam.dmi', time = 5 SECONDS, maxdistance = 10, beam_type = /obj/effect/ebeam, beam_sleep_time = 3, beam_color) - var/datum/beam/newbeam = new(src, BeamTarget, icon, icon_state, time, maxdistance, beam_type, beam_sleep_time, beam_color) +/atom/proc/Beam(atom/BeamTarget, + icon_state = "b_beam", + icon = 'icons/effects/beam.dmi', + time = 5 SECONDS, + maxdistance = 10, + beam_type = /obj/effect/ebeam, + beam_color, + use_get_turf = FALSE +) + var/datum/beam/newbeam = new(src, BeamTarget, icon, icon_state, time, maxdistance, beam_type, beam_color, use_get_turf) INVOKE_ASYNC(newbeam, TYPE_PROC_REF(/datum/beam, Start)) return newbeam diff --git a/code/datums/components/tether.dm b/code/datums/components/tether.dm new file mode 100644 index 00000000000..e5fde3c0ba9 --- /dev/null +++ b/code/datums/components/tether.dm @@ -0,0 +1,173 @@ +/datum/component/tether + dupe_mode = COMPONENT_DUPE_ALLOWED + var/atom/movable/tethered_to + // Durability decreases with every on_range. Snaps when durability = 0. + var/durability = INFINITY + var/max_range = 2 + var/tether_icon_state + + var/datum/movement_detector/tether_tracker + var/datum/movement_detector/parent_tracker + var/datum/beam/beam + var/atom/movable/tether_visual_target + var/tether_name + var/last_movement = 0 + +/datum/component/tether/Initialize(tethered_atom_movable, range = 2, durability = INFINITY, tether_icon_state = "tether", tether_name = "tether") + . = ..() + if(!isatom(parent) || !ismovable(tethered_atom_movable)) + return COMPONENT_INCOMPATIBLE + + src.tethered_to = tethered_atom_movable + src.max_range = range + src.durability = durability // movement is bugged right now. Durability wears out 3 times faster than expected. 1 durability should last 1 tile. + src.tether_icon_state = tether_icon_state + src.tether_name = tether_name + + RegisterSignal(parent, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(on_movement)) + RegisterSignal(tethered_atom_movable, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(pre_tethered_movement)) + RegisterSignal(tethered_atom_movable, COMSIG_ATOM_ATTACK_HAND, PROC_REF(can_equip)) + parent_tracker = new /datum/movement_detector(parent, CALLBACK(src, PROC_REF(parent_check_bounds))) + tether_tracker = new /datum/movement_detector(tethered_atom_movable, CALLBACK(src, PROC_REF(check_bounds))) + parent_tracker.fix_signal() + make_beam(tether_tracker.fix_signal() || tethered_to) + + RegisterSignal(parent, COMSIG_PARENT_QDELETING, PROC_REF(terminate)) + RegisterSignal(tethered_atom_movable, list(COMSIG_PARENT_QDELETING, COMSIG_TETHER_STOP), PROC_REF(terminate)) + + if(get_dist(get_turf(parent), get_turf(tethered_to)) <= max_range) + return + tether_move_towards_parent() + +/datum/component/tether/Destroy(force, silent) + QDEL_NULL(tether_tracker) + QDEL_NULL(parent_tracker) + if(!QDELETED(beam)) + qdel(beam) + beam = null + SEND_SIGNAL(tethered_to, COMSIG_TETHER_DESTROYED) + tether_visual_target = null + tethered_to = null + return ..() + +/datum/component/tether/proc/make_beam(target) + if(target == tether_visual_target) + return + tether_visual_target = target + if(beam) + UnregisterSignal(beam, COMSIG_PARENT_QDELETING) + QDEL_NULL(beam) + var/atom/atom = parent + beam = atom.Beam(tether_visual_target, icon_state = tether_icon_state, time = INFINITY, use_get_turf = TRUE) + RegisterSignal(beam, COMSIG_PARENT_QDELETING, PROC_REF(terminate)) + +// /datum/component/tether/proc/on_movement(atom/source, atom/oldloc, dir, forced) +/datum/component/tether/proc/on_movement(atom/movable/source, newloc) + // check if the item is in range. If not, try to move it towards the parent. + if(get_dist(get_turf(tethered_to), newloc) <= max_range) + return + if(source.pulledby == tethered_to.loc) + return + if(tether_move_towards_parent(newloc)) + return + if(get_dir(parent, newloc) & get_dir(parent, tethered_to)) + return + var/atom/atom = parent + atom?.setDir(get_dir(parent, newloc)) + to_chat(atom, "You can't move in that direction with the [tethered_to] tethered to you!") + return COMPONENT_MOVABLE_BLOCK_PRE_MOVE + +/datum/component/tether/proc/pre_tethered_movement(atom/movable/source, newloc) + // check if the item would be in range at its new tile. If not, return COMPONENT_MOVABLE_BLOCK_PRE_MOVE + if(get_dist(get_turf(parent), newloc) <= max_range) + return + if(get_dir(tethered_to, newloc) & get_dir(tethered_to, parent)) + return + durability_cost() + var/atom/atom = parent + atom?.setDir(get_dir(parent, newloc)) + to_chat(atom, "You can't move in that direction with the [tethered_to] tethered to you!") + return COMPONENT_MOVABLE_BLOCK_PRE_MOVE + +/datum/component/tether/proc/can_equip(atom/source, mob/user) + // Check to make sure we dont go into an inventory outside of our range + if(get_dist(get_turf(parent), get_turf(user)) > max_range) + to_chat(user, "You try to pick up [tethered_to], you can't pull it's [tether_name] any farther!") + return COMPONENT_CANCEL_ATTACK_CHAIN + +/datum/component/tether/proc/parent_check_bounds(atom/movable/source, atom/mover, atom/old_loc, direction) + // check to see if the parent has moved out of range (while inside another objects contents). If it has, pull the tether towards the parent. + if(get_dist(get_turf(parent), get_turf(tethered_to)) <= max_range) + return + if(source.pulledby == tethered_to.loc) + return + tether_move_towards_parent() + +/datum/component/tether/proc/check_bounds(atom/movable/source, atom/mover, atom/old_loc, direction) + // check to see if the tethered object is out of range. + // If it is, make it be dropped from a mob's hand, or open a locker its in. + make_beam(mover) + if(get_dist(get_turf(parent), get_turf(tethered_to)) <= max_range) + return + if(ismovable(mover)) + var/atom/movable/a_mover = mover + if(a_mover.pulledby == parent || a_mover.pulling == parent) + return + tether_move_towards_parent() + +/datum/component/tether/proc/tether_move_towards_parent(parent_newloc) + if(QDELETED(tethered_to) || !istype(tethered_to) || last_movement == world.time) + return TRUE + var/atom/current_loc = tethered_to.loc + var/i = 0 + while(!isturf(current_loc) && current_loc != null && current_loc != current_loc.loc) + if(i++ > 100) + return TRUE + if(ismob(current_loc)) + var/mob/M = current_loc + M.drop_item_to_ground(tethered_to) + current_loc = tethered_to.loc + break + if(istype(current_loc, /obj/item/storage)) + var/obj/item/storage/S = current_loc + S.remove_from_storage(tethered_to, get_turf(tethered_to)) + current_loc = tethered_to.loc + break + if(istype(current_loc, /obj/structure/closet)) + var/obj/structure/closet/C = current_loc + if(C.can_open()) + C.open() + current_loc = tethered_to.loc + break + if(ismovable(current_loc)) + var/atom/movable/AM = current_loc + if(AM.anchored) + return FALSE + if(isturf(AM.loc)) + last_movement = world.time + durability_cost() + step_towards(AM, get_turf(parent)) // holy shitcode + return get_dist(get_turf(parent_newloc || parent), get_turf(tethered_to)) <= max_range + current_loc = current_loc.loc + if(get_dist(get_turf(parent), get_turf(tethered_to)) <= max_range) + return TRUE + last_movement = world.time + durability_cost() + if(!step_towards(tethered_to, get_turf(parent))) // shitcode + return durability_cost(2) // use 3 total durability + return TRUE + +/datum/component/tether/proc/terminate(source, force) + if(QDELETED(src)) + return + qdel(src) + +/datum/component/tether/proc/durability_cost(cost = 1) + if(durability == INFINITY) + return + durability -= cost + if(durability <= 0 && !QDELETED(tethered_to)) + tethered_to.visible_message("[tethered_to]'s [tether_name] wears out and snaps back!") + terminate() + return TRUE // it breaks, let the parent move outside of the range again + return FALSE diff --git a/code/datums/movement_detector.dm b/code/datums/movement_detector.dm index 0de904dde2a..899ef7b0398 100644 --- a/code/datums/movement_detector.dm +++ b/code/datums/movement_detector.dm @@ -33,6 +33,24 @@ UnregisterSignal(target, COMSIG_MOVABLE_MOVED) target = target.loc + +/** + * Movement detectors don't work by default unless the item starts on a turf. + * Run this proc to fix that. + */ +/datum/movement_detector/proc/fix_signal() + // we're already inside something + var/atom/current_target = tracked.loc + var/turf/newturf = get_turf(tracked) + var/i = 0 + while(current_target.loc != newturf && current_target != null) + current_target = current_target.loc + if(i++ <= 100) + return + if(ismovable(current_target)) + RegisterSignal(current_target, COMSIG_MOVABLE_MOVED, PROC_REF(move_react), TRUE) + return current_target + /** * Reacts to any movement that would cause a change in coordinates of the tracked movable atom * This works by detecting movement of either the tracked object, or anything it is inside, recursively diff --git a/code/game/gamemodes/miniantags/demons/shadow_demon/shadow_demon.dm b/code/game/gamemodes/miniantags/demons/shadow_demon/shadow_demon.dm index fad169146e8..ed9e02690b6 100644 --- a/code/game/gamemodes/miniantags/demons/shadow_demon/shadow_demon.dm +++ b/code/game/gamemodes/miniantags/demons/shadow_demon/shadow_demon.dm @@ -232,7 +232,7 @@ var/mob/living/simple_animal/demon/shadow/current_demon = firer if(istype(current_demon)) current_demon.block_shadow_crawl() - firer.Beam(src, icon_state = "grabber_beam", time = INFINITY, maxdistance = INFINITY, beam_sleep_time = 1, beam_type = /obj/effect/ebeam/floor) + firer.Beam(src, icon_state = "grabber_beam", time = INFINITY, maxdistance = INFINITY, beam_type = /obj/effect/ebeam/floor) return ..() /obj/item/projectile/magic/shadow_hand/on_hit(atom/target, blocked, hit_zone) diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index f969e8daaf5..a3e2b884527 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -59,6 +59,7 @@ if(bag) user.put_in_hands(bag) bag.update_icon(UPDATE_OVERLAYS) + bag.update_iv_type() bag = null update_icon(UPDATE_OVERLAYS) @@ -72,6 +73,7 @@ used.forceMove(src) bag = used + bag.update_iv_type() to_chat(user, "You attach [used] to [src].") update_icon(UPDATE_OVERLAYS) START_PROCESSING(SSmachines, src) @@ -95,8 +97,9 @@ . += bag.examine(user) /obj/machinery/iv_drip/Move(NewLoc, direct) + var/oldloc = loc . = ..() - if(!.) // ..() will return 0 if we didn't actually move anywhere. + if(oldloc == loc) // ..() will return 0 if we didn't actually move anywhere, except for some diagonal cases. return playsound(loc, pick('sound/items/cartwheel1.ogg', 'sound/items/cartwheel2.ogg'), 75, TRUE, ignore_walls = FALSE) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 905bcf838f9..013999cbba1 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -840,10 +840,9 @@ held_items += held.UID() /obj/structure/table/tray/Move(NewLoc, direct) - var/atom/OldLoc = loc - + var/atom/oldloc = loc . = ..() - if(!.) // ..() will return 0 if we didn't actually move anywhere. + if(oldloc == loc) // ..() will return 0 if we didn't actually move anywhere, except for some diagonal cases. return if(direct & (direct - 1)) // This represents a diagonal movement, which is split into multiple cardinal movements. We'll handle moving the items on the cardinals only. @@ -857,7 +856,7 @@ if(!held) held_items -= held_uid continue - if(OldLoc != held.loc) + if(oldloc != held.loc) held_items -= held_uid continue held.forceMove(NewLoc) diff --git a/code/modules/antagonists/changeling/powers/mutations.dm b/code/modules/antagonists/changeling/powers/mutations.dm index 3de868857ac..74948f38762 100644 --- a/code/modules/antagonists/changeling/powers/mutations.dm +++ b/code/modules/antagonists/changeling/powers/mutations.dm @@ -292,7 +292,7 @@ /obj/item/projectile/tentacle/fire(setAngle) if(firer) - chain = firer.Beam(src, icon_state = "tentacle", time = INFINITY, maxdistance = INFINITY, beam_sleep_time = 1) + chain = firer.Beam(src, icon_state = "tentacle", time = INFINITY, maxdistance = INFINITY) ..() /mob/proc/tentacle_stab(mob/living/carbon/C) diff --git a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm index 2d79c322411..023b12691f9 100644 --- a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm +++ b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm @@ -22,8 +22,7 @@ anchors += locate(x + 2, y - 2, z) for(var/turf/T in anchors) - var/datum/beam/B = Beam(T, "vine", time=INFINITY, maxdistance=5, beam_type=/obj/effect/ebeam/vine) - B.sleep_time = 10 //these shouldn't move, so let's slow down updates to 1 second (any slower and the deletion of the vines would be too slow) + Beam(T, "vine", time = INFINITY, maxdistance = 5, beam_type = /obj/effect/ebeam/vine) addtimer(CALLBACK(src, PROC_REF(bear_fruit)), growth_time) /obj/structure/alien/resin/flower_bud_enemy/proc/bear_fruit() @@ -76,8 +75,7 @@ for(var/mob/living/L in grasping) if(L.stat == DEAD) var/datum/beam/B = grasping[L] - if(B) - B.End() + qdel(B) grasping -= L //Can attack+pull multiple times per cycle diff --git a/code/modules/mod/modules/module_kinesis.dm b/code/modules/mod/modules/module_kinesis.dm index 070c1122d83..968e9a573eb 100644 --- a/code/modules/mod/modules/module_kinesis.dm +++ b/code/modules/mod/modules/module_kinesis.dm @@ -82,7 +82,7 @@ grabbed_atom.add_overlay(kinesis_icon) pre_pixel_x = grabbed_atom.pixel_x pre_pixel_y = grabbed_atom.pixel_y - beam.chain = beam.Beam(grabbed_atom, icon_state = "kinesis", icon='icons/effects/beam.dmi', time = 100 SECONDS, maxdistance = 15, beam_type = /obj/effect/ebeam, beam_sleep_time = 3) + beam.chain = beam.Beam(grabbed_atom, icon_state = "kinesis", icon='icons/effects/beam.dmi', time = 100 SECONDS, maxdistance = 15, beam_type = /obj/effect/ebeam) kinesis_catcher = mod.wearer.overlay_fullscreen("kinesis", /atom/movable/screen/fullscreen/stretch/cursor_catcher/kinesis, 0) kinesis_catcher.assign_to_mob(mod.wearer) soundloop.start() @@ -113,8 +113,7 @@ if(grabbed_atom.pixel_x == kinesis_catcher.given_x - world.icon_size/2 && grabbed_atom.pixel_y == kinesis_catcher.given_y - world.icon_size/2) return //spare us redrawing if we are standing still animate(grabbed_atom, 0.2 SECONDS, pixel_x = pre_pixel_x + kinesis_catcher.given_x - world.icon_size/2, pixel_y = pre_pixel_y + kinesis_catcher.given_y - world.icon_size/2) - beam.chain.Reset() - beam.chain.Draw() + beam.chain.redrawing() return animate(grabbed_atom, 0.2 SECONDS, pixel_x = pre_pixel_x + kinesis_catcher.given_x - world.icon_size/2, pixel_y = pre_pixel_y + kinesis_catcher.given_y - world.icon_size/2) var/turf/next_turf = get_step_towards(grabbed_atom, kinesis_catcher.given_turf) @@ -137,8 +136,7 @@ else if(direction & WEST) pixel_x_change = -world.icon_size / 2 animate(grabbed_atom, 0.2 SECONDS, pixel_x = pre_pixel_x + pixel_x_change, pixel_y = pre_pixel_y + pixel_y_change) //Not as smooth as I would like, will look into this in the future - beam.chain.Reset() - beam.chain.Draw() + beam.chain.redrawing() if(!isitem(grabbed_atom) || !COOLDOWN_FINISHED(src, hit_cooldown)) return var/atom/hitting_atom diff --git a/code/modules/projectiles/guns/medbeam.dm b/code/modules/projectiles/guns/medbeam.dm index e2cce3d1dda..08950eab8d8 100644 --- a/code/modules/projectiles/guns/medbeam.dm +++ b/code/modules/projectiles/guns/medbeam.dm @@ -54,9 +54,8 @@ current_target = target active = TRUE - var/datum/beam/current_beam = new(user,current_target,time=6000,beam_icon_state="medbeam",btype=/obj/effect/ebeam/medical) + var/datum/beam/current_beam = user.Beam(current_target, "medbeam", time = 10 MINUTES, beam_type = /obj/effect/ebeam/medical) beam_UID = current_beam.UID() - INVOKE_ASYNC(current_beam, TYPE_PROC_REF(/datum/beam, Start)) SSblackbox.record_feedback("tally", "gun_fired", 1, type) @@ -87,6 +86,8 @@ /obj/item/gun/medbeam/proc/los_check(atom/movable/user, mob/target) var/turf/user_turf = user.loc var/datum/beam/current_beam = locateUID(beam_UID) + if(QDELETED(current_beam)) + return FALSE if(mounted) user_turf = get_turf(user) else if(!istype(user_turf)) @@ -104,7 +105,7 @@ qdel(dummy) return FALSE for(var/obj/effect/ebeam/medical/B in turf)// Don't cross the str-beams! - if(B.owner != current_beam) + if(B.owner && B.owner != current_beam && !QDELETED(B)) // only blow up if it has a CONFIRMED different owner than us. Don't want it blowing up on creation/deletion of beams. turf.visible_message("The medbeams cross and EXPLODE!") explosion(B.loc,0,3,5,8, cause = "Crossed beams") qdel(dummy) diff --git a/code/modules/reagents/reagent_containers/iv_bag.dm b/code/modules/reagents/reagent_containers/iv_bag.dm index c5e3245b424..df7ee4f5a25 100644 --- a/code/modules/reagents/reagent_containers/iv_bag.dm +++ b/code/modules/reagents/reagent_containers/iv_bag.dm @@ -18,6 +18,10 @@ var/mob/living/carbon/human/injection_target var/injection_action_delay = 3 SECONDS +/obj/item/reagent_containers/iv_bag/Initialize(mapload) + . = ..() + RegisterSignal(src, COMSIG_TETHER_DESTROYED, PROC_REF(tether_snapped)) + /obj/item/reagent_containers/iv_bag/Destroy() end_processing() return ..() @@ -52,12 +56,34 @@ injection_target = target RegisterSignal(injection_target, COMSIG_PARENT_EXAMINE, PROC_REF(on_examine)) START_PROCESSING(SSobj, src) + update_iv_type() -/obj/item/reagent_containers/iv_bag/proc/end_processing() +/obj/item/reagent_containers/iv_bag/proc/update_iv_type() + var/target = injection_target + injection_target = null + SEND_SIGNAL(src, COMSIG_TETHER_STOP) + injection_target = target + if(!injection_target) + return + if(istype(loc, /obj/machinery/iv_drip)) + injection_target.AddComponent(/datum/component/tether, src, 2, 50, "iv_tether", "tubing") + else + injection_target.AddComponent(/datum/component/tether, src, 1, 5, "iv_tether", "tubing") + +/obj/item/reagent_containers/iv_bag/proc/end_processing(send_signal = TRUE) if(injection_target) UnregisterSignal(injection_target, COMSIG_PARENT_EXAMINE) injection_target = null STOP_PROCESSING(SSobj, src) + if(send_signal) + SEND_SIGNAL(src, COMSIG_TETHER_STOP) + +/obj/item/reagent_containers/iv_bag/proc/tether_snapped() + if(!injection_target) + return + to_chat(injection_target, "[src]'s needle is ripped out of you!") + injection_target.apply_damage(3, BRUTE, pick("r_arm", "l_arm")) + end_processing(FALSE) /obj/item/reagent_containers/iv_bag/process() if(QDELETED(injection_target)) @@ -69,12 +95,6 @@ end_processing() return - if(get_dist(get_turf(src), get_turf(injection_target)) > 1) - to_chat(injection_target, "[src]'s needle is ripped out of you!") - injection_target.apply_damage(3, BRUTE, pick("r_arm", "l_arm")) - end_processing() - return - if(mode) // Injecting if(reagents.total_volume) var/fraction = min(amount_per_transfer_from_this/reagents.total_volume, 1) //The amount of reagents we'll transfer to the person diff --git a/icons/effects/beam.dmi b/icons/effects/beam.dmi index 7bd1e5397130deaf14d484e42a7c3fc276a1d72a..ab11d3de6534bd2b6de4b2ab6d09d3a3f99e4c21 100644 GIT binary patch literal 28369 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 literal 27208 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

(?1+jz$e$-HwhcbxY{WXZT(hrZe{+L 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 diff --git a/paradise.dme b/paradise.dme index ed3cb27b1fb..9db5919be35 100644 --- a/paradise.dme +++ b/paradise.dme @@ -544,6 +544,7 @@ #include "code\datums\components\sticky.dm" #include "code\datums\components\surgery_initiator.dm" #include "code\datums\components\swarming.dm" +#include "code\datums\components\tether.dm" #include "code\datums\components\tilted.dm" #include "code\datums\components\tippable.dm" #include "code\datums\components\two_handed.dm"