From 2048265d6f1cab10ef21355579bcef14d2c8aa11 Mon Sep 17 00:00:00 2001 From: Testmerge Worker Date: Sat, 1 Mar 2025 19:16:46 +0000 Subject: [PATCH] refactor: fastport tg beam datums (#6597) [testmerge][5618d17] --- code/__DEFINES/beam.dm | 12 + code/__HELPERS/maths.dm | 12 + code/datums/beam.dm | 406 +++++++++++------- .../demons/shadow_demon/shadow_demon.dm | 2 +- .../miniantags/guardian/types/lightning.dm | 4 +- .../changeling/powers/mutations.dm | 4 +- .../ninja_equipment_actions/ninja_johyo.dm | 2 +- .../contractor/items/contractor_hardsuit.dm | 2 +- .../vampire/vampire_powers/bestia_powers.dm | 2 +- .../mining/lavaland/loot/tendril_loot.dm | 2 +- .../hostile/megafauna/ancient_robot.dm | 9 +- .../simple_animal/hostile/megafauna/legion.dm | 4 +- .../simple_animal/hostile/venus_human_trap.dm | 5 +- paradise.dme | 1 + 14 files changed, 284 insertions(+), 183 deletions(-) create mode 100644 code/__DEFINES/beam.dm diff --git a/code/__DEFINES/beam.dm b/code/__DEFINES/beam.dm new file mode 100644 index 00000000000..12d58b70c9a --- /dev/null +++ b/code/__DEFINES/beam.dm @@ -0,0 +1,12 @@ +/// Called before beam is redrawn +#define COMSIG_BEAM_BEFORE_DRAW "beam_before_draw" + #define BEAM_CANCEL_DRAW (1 << 0) + +/// Sent to a beam when an atom enters any turf the beam covers: (obj/effect/ebeam/hit_beam, atom/movable/entered) +#define COMSIG_BEAM_ENTERED "beam_entered" + +/// Sent to a beam when an atom exits any turf the beam covers: (obj/effect/ebeam/hit_beam, atom/movable/exited) +#define COMSIG_BEAM_EXITED "beam_exited" + +/// Sent to a beam when any turf the beam covers changes: (list/datum/callback/post_change_callbacks) +#define COMSIG_BEAM_TURFS_CHANGED "beam_turfs_changed" diff --git a/code/__HELPERS/maths.dm b/code/__HELPERS/maths.dm index 2346fe90c94..bfe4dcb5ab9 100644 --- a/code/__HELPERS/maths.dm +++ b/code/__HELPERS/maths.dm @@ -250,3 +250,15 @@ return "centuple" else //It gets too tedious to use latin prefixes from here. return "[number]-tuple" + +/// 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 diff --git a/code/datums/beam.dm b/code/datums/beam.dm index e77ec9ce2f9..6fbe923356b 100644 --- a/code/datums/beam.dm +++ b/code/datums/beam.dm @@ -1,107 +1,159 @@ -//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 + ///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 + ///If we use an emissive appearance. Don't use until proper tg emissive port + var/emissive = FALSE + /// If set will be used instead of origin's pixel_x in offset calculations + var/override_origin_pixel_x = null + /// If set will be used instead of origin's pixel_y in offset calculations + var/override_origin_pixel_y = null + /// If set will be used instead of targets's pixel_x in offset calculations + var/override_target_pixel_x = null + /// If set will be used instead of targets's pixel_y in offset calculations + var/override_target_pixel_y = null ///the layer of our beam var/beam_layer - /datum/beam/New( - beam_origin, - beam_target, - beam_icon = 'icons/effects/beam.dmi', - beam_icon_state="b_beam", - time = 5 SECONDS, - maxdistance = 10, - btype = /obj/effect/ebeam, - beam_sleep_time = 0.3 SECONDS, + origin, + target, + icon = 'icons/effects/beam.dmi', + icon_state = "b_beam", + time = INFINITY, + max_distance = INFINITY, + beam_type = /obj/effect/ebeam, + beam_color = null, + emissive = TRUE, + override_origin_pixel_x = null, + override_origin_pixel_y = null, + override_target_pixel_x = null, + override_target_pixel_y = null, beam_layer = ABOVE_ALL_MOB_LAYER ) - src.endtime = world.time+time - src.origin = beam_origin - src.origin_oldloc = get_turf(origin) - src.target = beam_target - src.target_oldloc = get_turf(target) - src.sleep_time = beam_sleep_time - if(origin_oldloc == origin && target_oldloc == target) - src.static_beam = TRUE - src.max_distance = maxdistance - src.base_icon = new(beam_icon, beam_icon_state) - src.icon = beam_icon - src.icon_state = beam_icon_state - src.beam_type = btype + 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.emissive = emissive + src.override_origin_pixel_x = override_origin_pixel_x + src.override_origin_pixel_y = override_origin_pixel_y + src.override_target_pixel_x = override_target_pixel_x + src.override_target_pixel_y = override_target_pixel_y src.beam_layer = beam_layer + 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.emissive = emissive + visuals.layer = beam_layer + visuals.update_appearance() Draw() - while(!finished && origin && target && world.time < endtime && get_dist(origin,target)length) - var/icon/II = new(icon, icon_state) - II.DrawBox(null,1,(length-N),32,32) - X.icon = II + var/obj/effect/ebeam/segment = new beam_type(origin_turf, src) + elements += segment + + //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 - X.transform = rot_matrix + segment.vis_contents += visuals + segment.transform = rot_matrix //Calculate pixel offsets (If necessary) var/Pixel_x @@ -116,8 +168,8 @@ 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 + 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 @@ -125,103 +177,55 @@ final_y += Pixel_y > 0 ? round(Pixel_y/32) : CEILING(Pixel_y/32, 1) Pixel_y %= 32 - X.forceMove(locate(final_x, final_y, X.z)) - X.pixel_x = Pixel_x - X.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 - -/** - * This is what you use to start a beam. Example: origin.Beam(target, args). **Store the return of this proc if you don't set maxdist or time, you need it to delete the beam.** - * - * Unless you're making a custom beam effect (see the beam_type argument), you won't actually have to mess with any other procs. Make sure you store the return of this Proc, you'll need it - * to kill the beam. - * **Arguments:** - * BeamTarget: Where you're beaming from. Where do you get origin? You didn't read the docs, fuck you. - * icon_state: What the beam's icon_state is. The datum effect isn't the ebeam object, it doesn't hold any icon and isn't type dependent. - * icon: What the beam's icon file is. Don't change this, man. All beam icons should be in beam.dmi anyways. - * maxdistance: how far the beam will go before stopping itself. Used mainly for two things: preventing lag if the beam may go in that direction and setting a range to abilities that use beams. - * beam_type: The type of your custom beam. This is for adding other wacky stuff for your beam only. Most likely, you won't (and shouldn't) change it. - */ -/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 = 0.3 SECONDS, - beam_layer = ABOVE_ALL_MOB_LAYER -) - var/datum/beam/newbeam = new(src, BeamTarget, icon, icon_state, time, maxdistance, beam_type, beam_sleep_time, beam_layer) - INVOKE_ASYNC(newbeam, TYPE_PROC_REF(/datum/beam, Start)) - return newbeam - - /obj/effect/ebeam mouse_opacity = MOUSE_OPACITY_TRANSPARENT + layer = ABOVE_ALL_MOB_LAYER anchored = TRUE + var/emissive = FALSE var/datum/beam/owner - /obj/effect/ebeam/Initialize(mapload, beam_owner) - . = ..() owner = beam_owner + return ..() +/obj/effect/ebeam/update_overlays() + . = ..() + if(!emissive) + return + var/mutable_appearance/emissive_overlay = emissive_appearance(icon, icon_state, src) + emissive_overlay.transform = transform + emissive_overlay.alpha = alpha + . += emissive_overlay /obj/effect/ebeam/Destroy() owner = null return ..() - -/obj/effect/ebeam/ex_act(severity) - return - - /obj/effect/ebeam/singularity_pull() return - /obj/effect/ebeam/singularity_act() return - -// Subtypes - -/obj/effect/ebeam/floor - plane = FLOOR_PLANE - - -/obj/effect/ebeam/chain - name = "lightning chain" - - -/obj/effect/ebeam/medical - name = "medical beam" - - -/obj/effect/ebeam/vetus - - -/obj/effect/ebeam/vetus/Destroy() - for(var/mob/living/mob in get_turf(src)) - mob.electrocute_act(20, "электрической дуги", flags = SHOCK_NOGLOVES) - return ..() - - -/obj/effect/ebeam/disintegration_telegraph - alpha = 100 - +/obj/effect/ebeam/ex_act(severity) + return /// A beam subtype used for advanced beams, to react to atoms entering the beam /obj/effect/ebeam/reacting /// If TRUE, atoms that exist in the beam's loc when inited count as "entering" the beam var/react_on_init = FALSE - /obj/effect/ebeam/reacting/Initialize(mapload, beam_owner) . = ..() var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = PROC_REF(on_entered) + COMSIG_ATOM_ENTERED = PROC_REF(on_entered), + COMSIG_ATOM_EXITED = PROC_REF(on_exited), + COMSIG_TURF_CHANGE = PROC_REF(on_turf_change), ) AddElement(/datum/element/connect_loc, loc_connections) @@ -231,34 +235,128 @@ for(var/atom/movable/existing as anything in loc) beam_entered(existing) +/obj/effect/ebeam/reacting/proc/on_entered(datum/source, atom/movable/entered) + SIGNAL_HANDLER + + if(isnull(owner)) + return + + beam_entered(entered) -/obj/effect/ebeam/reacting/proc/on_entered(datum/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs) +/obj/effect/ebeam/reacting/proc/on_exited(datum/source, atom/movable/exited) SIGNAL_HANDLER if(isnull(owner)) return - beam_entered(arrived) + beam_exited(exited) + +/obj/effect/ebeam/reacting/proc/on_turf_change(datum/source, path, new_baseturfs, flags, list/datum/callback/post_change_callbacks) + SIGNAL_HANDLER + + if(isnull(owner)) + return + beam_turfs_changed(post_change_callbacks) /// Some atom entered the beam's line /obj/effect/ebeam/reacting/proc/beam_entered(atom/movable/entered) - return + SHOULD_CALL_PARENT(TRUE) + SEND_SIGNAL(owner, COMSIG_BEAM_ENTERED, src, entered) +/// Some atom exited the beam's line +/obj/effect/ebeam/reacting/proc/beam_exited(atom/movable/exited) + SHOULD_CALL_PARENT(TRUE) + SEND_SIGNAL(owner, COMSIG_BEAM_EXITED, src, exited) -/obj/effect/ebeam/reacting/deadly +/// Some turf the beam covers has changed to a new turf type +/obj/effect/ebeam/reacting/proc/beam_turfs_changed(list/datum/callback/post_change_callbacks) + SHOULD_CALL_PARENT(TRUE) + SEND_SIGNAL(owner, COMSIG_BEAM_TURFS_CHANGED, post_change_callbacks) +/** + * This is what you use to start a beam. Example: origin.Beam(target, args). **Store the return of this proc if you don't set maxdist or time, you need it to delete the beam.** + * + * Unless you're making a custom beam effect (see the beam_type argument), you won't actually have to mess with any other procs. Make sure you store the return of this Proc, you'll need it + * to kill the beam. + * **Arguments:** + * BeamTarget: Where you're beaming from. Where do you get origin? You didn't read the docs, fuck you. + * icon_state: What the beam's icon_state is. The datum effect isn't the ebeam object, it doesn't hold any icon and isn't type dependent. + * icon: What the beam's icon file is. Don't change this, man. All beam icons should be in beam.dmi anyways. + * maxdistance: how far the beam will go before stopping itself. Used mainly for two things: preventing lag if the beam may go in that direction and setting a range to abilities that use beams. + * beam_type: The type of your custom beam. This is for adding other wacky stuff for your beam only. Most likely, you won't (and shouldn't) change it. + */ +/atom/proc/Beam(atom/BeamTarget, + icon_state = "b_beam", + icon = 'icons/effects/beam.dmi', + time=INFINITY, + maxdistance=INFINITY, + beam_type=/obj/effect/ebeam, + beam_color = null, + emissive = TRUE, + override_origin_pixel_x = null, + override_origin_pixel_y = null, + override_target_pixel_x = null, + override_target_pixel_y = null, + layer = ABOVE_ALL_MOB_LAYER +) + var/datum/beam/newbeam = new(src,BeamTarget,icon,icon_state,time,maxdistance,beam_type, beam_color, emissive, override_origin_pixel_x, override_origin_pixel_y, override_target_pixel_x, override_target_pixel_y, layer) + INVOKE_ASYNC(newbeam, TYPE_PROC_REF(/datum/beam/, Start)) + return newbeam -/obj/effect/ebeam/reacting/deadly/beam_entered(atom/movable/entered) - entered.ex_act(EXPLODE_DEVASTATE) +// Our collection of ebeam subtypes +/obj/effect/ebeam/floor + plane = FLOOR_PLANE -/obj/effect/ebeam/reacting/disintegration +/obj/effect/ebeam/chain + name = "lightning chain" + layer = LYING_MOB_LAYER + +/obj/effect/ebeam/reacting/vine + name = "thick vine" + mouse_opacity = MOUSE_OPACITY_ICON + desc = "A thick vine, painful to the touch." + +/obj/effect/ebeam/reacting/vine/on_entered(datum/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs) + . = ..() + if(!isliving(arrived)) + return + var/mob/living/target = arrived + if("vines" in target.faction) + return + + target.adjustBruteLoss(5) + to_chat(target, span_danger("You cut yourself on the thorny vines.")) + + +/obj/effect/ebeam/vetus + +/obj/effect/ebeam/vetus/Destroy() + for(var/mob/living/mob in get_turf(src)) + mob.electrocute_act(20, "электрической дуги", flags = SHOCK_NOGLOVES) + return ..() + +/obj/effect/ebeam/vetus_leg + layer = OBJ_LAYER +/obj/effect/ebeam/disintegration_telegraph + alpha = 100 + +/obj/effect/ebeam/medical + name = "medical beam" + +/obj/effect/ebeam/reacting/deadly + +/obj/effect/ebeam/reacting/deadly/on_entered(datum/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs) + arrived.ex_act(EXPLODE_DEVASTATE) + +/obj/effect/ebeam/reacting/disintegration -/obj/effect/ebeam/reacting/disintegration/beam_entered(mob/living/entered) - if(!isliving(entered)) +/obj/effect/ebeam/reacting/disintegration/on_entered(datum/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs) + if(!isliving(arrived)) return + var/mob/living/entered = arrived var/damage = 50 if(entered.stat == DEAD) visible_message(span_danger("[entered] is disintegrated by the beam!")) @@ -273,17 +371,3 @@ var/limb_to_hit = entered.get_organ(pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG)) var/armor = entered.run_armor_check(limb_to_hit, LASER) entered.apply_damage(damage, BURN, limb_to_hit, armor) - - -/obj/effect/ebeam/reacting/vine - name = "thick vine" - mouse_opacity = MOUSE_OPACITY_ICON - desc = "A thick vine, painful to the touch." - - -/obj/effect/ebeam/reacting/vine/beam_entered(mob/living/entered) - if(!isliving(entered) || ("vines" in entered.faction)) - return - entered.adjustBruteLoss(5) - to_chat(entered, span_danger("You cut yourself on the thorny vines.")) - 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 a5026bfb3b7..a4e4f68fb5d 100644 --- a/code/game/gamemodes/miniantags/demons/shadow_demon/shadow_demon.dm +++ b/code/game/gamemodes/miniantags/demons/shadow_demon/shadow_demon.dm @@ -200,7 +200,7 @@ /obj/item/projectile/magic/shadow_hand/fire(setAngle) if(firer) - firer.Beam(src, icon_state = "grabber_beam", time = INFINITY, maxdistance = INFINITY, beam_sleep_time = 1, beam_type = /obj/effect/ebeam/floor, beam_layer = BELOW_MOB_LAYER) + firer.Beam(src, icon_state = "grabber_beam", time = INFINITY, maxdistance = INFINITY, beam_type = /obj/effect/ebeam/floor, layer = BELOW_MOB_LAYER) return ..() diff --git a/code/game/gamemodes/miniantags/guardian/types/lightning.dm b/code/game/gamemodes/miniantags/guardian/types/lightning.dm index dc6f7c9331d..b0f90a69ac9 100644 --- a/code/game/gamemodes/miniantags/guardian/types/lightning.dm +++ b/code/game/gamemodes/miniantags/guardian/types/lightning.dm @@ -32,7 +32,7 @@ /mob/living/simple_animal/hostile/guardian/beam/Manifest() ..() if(summoner) - summonerchain = Beam(summoner, "lightning[rand(1,12)]", 'icons/effects/effects.dmi', time=INFINITY, maxdistance=INFINITY, beam_type=/obj/effect/ebeam/chain, beam_layer = LYING_MOB_LAYER) + summonerchain = Beam(summoner, "lightning[rand(1,12)]", 'icons/effects/effects.dmi', time = INFINITY, maxdistance = INFINITY, beam_type = /obj/effect/ebeam/chain, layer = LYING_MOB_LAYER) while(loc != summoner) if(successfulshocks > 5) successfulshocks = 0 @@ -59,7 +59,7 @@ cleardeletedchains() if(summoner) if(!summonerchain) - summonerchain = Beam(summoner, "lightning[rand(1,12)]", 'icons/effects/effects.dmi', time=INFINITY, maxdistance=INFINITY, beam_type=/obj/effect/ebeam/chain, beam_layer = LYING_MOB_LAYER) + summonerchain = Beam(summoner, "lightning[rand(1,12)]", 'icons/effects/effects.dmi', time = INFINITY, maxdistance = INFINITY, beam_type = /obj/effect/ebeam/chain, layer = LYING_MOB_LAYER) . += chainshock(summonerchain) if(enemychains.len) for(var/chain in enemychains) diff --git a/code/modules/antagonists/changeling/powers/mutations.dm b/code/modules/antagonists/changeling/powers/mutations.dm index b3c07167e2b..7fad3103d9e 100644 --- a/code/modules/antagonists/changeling/powers/mutations.dm +++ b/code/modules/antagonists/changeling/powers/mutations.dm @@ -182,7 +182,7 @@ parent_action.UnregisterSignal(parent_action.owner, COMSIG_MOB_WEAPON_APPEARS) parent_action = null return ..() - + /obj/item/melee/arm_blade/afterattack(atom/target, mob/user, proximity, params) if(!proximity) @@ -398,7 +398,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) intent = firer.a_intent if(intent == INTENT_DISARM) armour_penetration = 100 //ignore block_chance diff --git a/code/modules/antagonists/space_ninja/suit/ninja_equipment_actions/ninja_johyo.dm b/code/modules/antagonists/space_ninja/suit/ninja_equipment_actions/ninja_johyo.dm index 7711a331f79..b9f8f814d2c 100644 --- a/code/modules/antagonists/space_ninja/suit/ninja_equipment_actions/ninja_johyo.dm +++ b/code/modules/antagonists/space_ninja/suit/ninja_equipment_actions/ninja_johyo.dm @@ -97,7 +97,7 @@ /obj/item/projectile/johyo/fire(setAngle) if(firer) firer.say(pick("Get over here!", "Come here!")) - chain = firer.Beam(src, icon_state = "chain_dark", time = INFINITY, maxdistance = INFINITY, beam_sleep_time = 1) + chain = firer.Beam(src, icon_state = "chain_dark", time = INFINITY, maxdistance = INFINITY) . = ..() /obj/item/projectile/johyo/on_hit(atom/target) diff --git a/code/modules/antagonists/traitor/contractor/items/contractor_hardsuit.dm b/code/modules/antagonists/traitor/contractor/items/contractor_hardsuit.dm index 923ed2d6758..85d4ef9d1e1 100644 --- a/code/modules/antagonists/traitor/contractor/items/contractor_hardsuit.dm +++ b/code/modules/antagonists/traitor/contractor/items/contractor_hardsuit.dm @@ -168,7 +168,7 @@ /obj/item/projectile/contractor_hook/fire(setAngle) if(firer) - chain = firer.Beam(src, icon_state = "hard_chain", time = INFINITY, maxdistance = INFINITY, beam_sleep_time = 1) + chain = firer.Beam(src, icon_state = "hard_chain", time = INFINITY, maxdistance = INFINITY) ..() /obj/item/projectile/contractor_hook/on_hit(atom/target, blocked = 0) diff --git a/code/modules/antagonists/vampire/vampire_powers/bestia_powers.dm b/code/modules/antagonists/vampire/vampire_powers/bestia_powers.dm index 245b90251ea..83619be49aa 100644 --- a/code/modules/antagonists/vampire/vampire_powers/bestia_powers.dm +++ b/code/modules/antagonists/vampire/vampire_powers/bestia_powers.dm @@ -671,7 +671,7 @@ /obj/item/projectile/skull_projectile/fire(setAngle) if(firer) - chain = firer.Beam(src, icon_state = "sendbeam", time = INFINITY, maxdistance = INFINITY, beam_sleep_time = 1) + chain = firer.Beam(src, icon_state = "sendbeam", time = INFINITY, maxdistance = INFINITY) var/obj/item/gun/magic/skull_gun/skull_gun = locate() in firer if(skull_gun) diff --git a/code/modules/mining/lavaland/loot/tendril_loot.dm b/code/modules/mining/lavaland/loot/tendril_loot.dm index 53ec519a031..0c023671b49 100644 --- a/code/modules/mining/lavaland/loot/tendril_loot.dm +++ b/code/modules/mining/lavaland/loot/tendril_loot.dm @@ -458,7 +458,7 @@ /obj/item/projectile/hook/fire(setAngle) if(firer) - chain = firer.Beam(src, icon_state = "chain", time = INFINITY, maxdistance = INFINITY, beam_sleep_time = 1) + chain = firer.Beam(src, icon_state = "chain", time = INFINITY, maxdistance = INFINITY) ..() //TODO: root the firer until the chain returns diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/ancient_robot.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/ancient_robot.dm index 77026867a47..e49b7ffe57b 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/ancient_robot.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/ancient_robot.dm @@ -643,7 +643,6 @@ Difficulty: Very Hard var/fake_hp_regen = 2 var/transfer_rate = 0.75 var/who_am_i = null - var/datum/beam/leg_part /mob/living/simple_animal/hostile/ancient_robot_leg/Initialize(mapload, mob/living/ancient, who) . = ..() @@ -665,10 +664,6 @@ Difficulty: Very Hard /mob/living/simple_animal/hostile/ancient_robot_leg/death(gibbed) return //It shouldn't get gibbed by shuttle. -/mob/living/simple_animal/hostile/ancient_robot_leg/Destroy() - QDEL_NULL(leg_part) - return ..() - /mob/living/simple_animal/hostile/ancient_robot_leg/Life(seconds, times_fired) ..() health_and_snap_check(TRUE) @@ -684,12 +679,10 @@ Difficulty: Very Hard return // stops the legs from trying to move on their own /mob/living/simple_animal/hostile/ancient_robot_leg/proc/beam_setup() - leg_part = Beam(core.beam, "leg_connection", 'icons/effects/effects.dmi', time=INFINITY, maxdistance=INFINITY, beam_type=/obj/effect/ebeam) + Beam(core, "leg_connection", 'icons/effects/effects.dmi', time = INFINITY, maxdistance = INFINITY, beam_type = /obj/effect/ebeam/vetus_leg) /mob/living/simple_animal/hostile/ancient_robot_leg/on_changed_z_level(turf/old_turf, turf/new_turf, same_z_layer, notify_contents = TRUE) ..() - if(leg_part) - QDEL_NULL(leg_part) addtimer(CALLBACK(src, PROC_REF(beam_setup)), 1 SECONDS) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm index c52c58737c4..39835b1109c 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm @@ -130,7 +130,7 @@ Difficulty: Medium var/turf/target_location = locate(x + (50 * sin(beam_angle)), y + (50 * cos(beam_angle)), z) var/beam_time = 0.25 SECONDS + ((health / maxHealth) SECONDS) playsound(loc, 'sound/effects/basscannon.ogg', 200, TRUE) - Beam(target_location, icon_state = "death_laser", time = beam_time, maxdistance = INFINITY, beam_type = /obj/effect/ebeam/disintegration_telegraph, beam_layer = ON_EDGED_TURF_LAYER) + Beam(target_location, icon_state = "death_laser", time = beam_time, maxdistance = INFINITY, beam_type = /obj/effect/ebeam/disintegration_telegraph, layer = ON_EDGED_TURF_LAYER) addtimer(CALLBACK(src, PROC_REF(fire_disintegration_laser), target_location), beam_time) ranged_cooldown = world.time + beam_time + 2 SECONDS SLEEP_CHECK_DEATH(src, beam_time + 2 SECONDS) @@ -185,7 +185,7 @@ Difficulty: Medium /mob/living/simple_animal/hostile/megafauna/legion/proc/fire_disintegration_laser(location) playsound(loc, 'sound/weapons/marauder.ogg', 200, TRUE) - Beam(location, icon_state = "death_laser", time = 2 SECONDS, maxdistance = INFINITY, beam_type = /obj/effect/ebeam/reacting/disintegration, beam_layer = ON_EDGED_TURF_LAYER) + Beam(location, icon_state = "death_laser", time = 2 SECONDS, maxdistance = INFINITY, beam_type = /obj/effect/ebeam/reacting/disintegration, layer = ON_EDGED_TURF_LAYER) for(var/turf/t as anything in get_line(src, location)) if(ismineralturf(t)) var/turf/simulated/mineral/M = t 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 ee076fb607d..7d73d86974f 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 @@ -20,8 +20,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/reacting/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/reacting/vine) addtimer(CALLBACK(src, PROC_REF(bear_fruit)), growth_time) /obj/structure/alien/resin/flower_bud_enemy/proc/bear_fruit() @@ -61,7 +60,7 @@ 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/paradise.dme b/paradise.dme index a487d86c060..884a4846693 100644 --- a/paradise.dme +++ b/paradise.dme @@ -36,6 +36,7 @@ #include "code\__DEFINES\antagonists.dm" #include "code\__DEFINES\asset_defines.dm" #include "code\__DEFINES\atmospherics.dm" +#include "code\__DEFINES\beam.dm" #include "code\__DEFINES\blend_modes.dm" #include "code\__DEFINES\blob.dm" #include "code\__DEFINES\borer.dm"