Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MIRROR] Infrared Emitters use beam datums (As God intended) #2486

Merged
merged 1 commit into from
Mar 20, 2024
Merged
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
9 changes: 9 additions & 0 deletions code/__DEFINES/dcs/signals/signals_beam.dm
Original file line number Diff line number Diff line change
@@ -1,3 +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"
73 changes: 66 additions & 7 deletions code/datums/beam.dm
Original file line number Diff line number Diff line change
Expand Up @@ -163,16 +163,16 @@
Pixel_y = round(cos(Angle)+32*cos(Angle)*(N+16)/32)

//Position the effect so the beam is one continous line
var/a
var/final_x = segment.x
var/final_y = segment.y
if(abs(Pixel_x)>32)
a = Pixel_x > 0 ? round(Pixel_x/32) : CEILING(Pixel_x/32, 1)
segment.x += a
final_x += Pixel_x > 0 ? round(Pixel_x/32) : CEILING(Pixel_x/32, 1)
Pixel_x %= 32
if(abs(Pixel_y)>32)
a = Pixel_y > 0 ? round(Pixel_y/32) : CEILING(Pixel_y/32, 1)
segment.y += a
final_y += Pixel_y > 0 ? round(Pixel_y/32) : CEILING(Pixel_y/32, 1)
Pixel_y %= 32

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
Expand All @@ -194,6 +194,7 @@
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()
Expand All @@ -202,9 +203,69 @@

/obj/effect/ebeam/singularity_pull()
return

/obj/effect/ebeam/singularity_act()
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_EXITED = PROC_REF(on_exited),
COMSIG_TURF_CHANGE = PROC_REF(on_turf_change),
)
AddElement(/datum/element/connect_loc, loc_connections)

if(!isturf(loc) || isnull(owner) || mapload || !react_on_init)
return

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_exited(datum/source, atom/movable/exited)
SIGNAL_HANDLER

if(isnull(owner))
return

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)
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)

/// 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.**
*
Expand All @@ -221,5 +282,3 @@
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 )
INVOKE_ASYNC(newbeam, TYPE_PROC_REF(/datum/beam/, Start))
return newbeam


20 changes: 3 additions & 17 deletions code/modules/antagonists/heretic/magic/fire_blast.dm
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

/datum/action/cooldown/spell/charged/beam/fire_blast/send_beam(atom/origin, mob/living/carbon/to_beam, bounces = 4)
// Send a beam from the origin to the hit mob
origin.Beam(to_beam, icon_state = "solar_beam", time = beam_duration, beam_type = /obj/effect/ebeam/fire)
origin.Beam(to_beam, icon_state = "solar_beam", time = beam_duration, beam_type = /obj/effect/ebeam/reacting/fire)

// If they block the magic, the chain wont necessarily stop,
// but likely will (due to them not catching on fire)
Expand Down Expand Up @@ -141,25 +141,11 @@
owner.adjustStaminaLoss(2 * tick_damage * seconds_between_ticks)

// The beam fireblast spits out, causes people to walk through it to be on fire
/obj/effect/ebeam/fire
/obj/effect/ebeam/reacting/fire
name = "fire beam"

/obj/effect/ebeam/fire/Initialize(mapload)
/obj/effect/ebeam/reacting/fire/beam_entered(atom/movable/entered)
. = ..()
var/static/list/loc_connections = list(
COMSIG_ATOM_ENTERED = PROC_REF(on_entered),
)
AddElement(/datum/element/connect_loc, loc_connections)

if(!isturf(loc) || mapload) // idk if this would ever be maploaded but you never know
return

for(var/mob/living/living_mob in loc)
on_entered(entered = living_mob)

/obj/effect/ebeam/fire/proc/on_entered(datum/source, atom/movable/entered)
SIGNAL_HANDLER

if(!isliving(entered))
return
var/mob/living/living_entered = entered
Expand Down
Loading
Loading