diff --git a/code/datums/beam.dm b/code/datums/beam.dm new file mode 100644 index 0000000000..12c22430db --- /dev/null +++ b/code/datums/beam.dm @@ -0,0 +1,138 @@ +//Beam Datum and effect +/datum/beam + var/atom/origin = null + var/atom/target = null + var/list/elements = list() + var/icon/base_icon = null + var/icon + var/icon_state = "" //icon state of the main segments of the beam + var/max_distance = 0 + var/endtime = 0 + var/sleep_time = 3 + var/finished = 0 + var/target_oldloc = null + var/origin_oldloc = null + var/static_beam = 0 + var/beam_type = /obj/effect/ebeam //must be subtype + +/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) + 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 = 1 + max_distance = maxdistance + base_icon = new(beam_icon,beam_icon_state) + icon = beam_icon + icon_state = beam_icon_state + beam_type = btype + +/datum/beam/proc/Start() + 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 + else + X.icon = base_icon + X.transform = rot_matrix + + //Calculate pixel offsets (If necessary) + var/Pixel_x + var/Pixel_y + if(DX == 0) + Pixel_x = 0 + else + 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/a + if(abs(Pixel_x)>32) + a = Pixel_x > 0 ? round(Pixel_x/32) : Ceiling(Pixel_x/32) + X.x += a + Pixel_x %= 32 + if(abs(Pixel_y)>32) + a = Pixel_y > 0 ? round(Pixel_y/32) : Ceiling(Pixel_y/32) + X.y += a + Pixel_y %= 32 + + X.pixel_x = Pixel_x + X.pixel_y = Pixel_y + +/obj/effect/ebeam + mouse_opacity = 0 + anchored = TRUE + var/datum/beam/owner + +/obj/effect/ebeam/Destroy() + owner = null + return ..() + +/obj/effect/ebeam/singularity_pull() + return +/obj/effect/ebeam/singularity_act() + return + +/obj/effect/ebeam/deadly/Crossed(atom/A) + ..() + A.ex_act(1) + +/atom/proc/Beam(atom/BeamTarget,icon_state="b_beam",icon='icons/effects/beam.dmi',time=50, maxdistance=10,beam_type=/obj/effect/ebeam,beam_sleep_time=3) + var/datum/beam/newbeam = new(src,BeamTarget,icon,icon_state,time,maxdistance,beam_type,beam_sleep_time) + spawn(0) + newbeam.Start() + return newbeam diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 7a027d207b..46da7ae2ba 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -127,78 +127,6 @@ found += A.search_contents_for(path,filter_path) return found - - - -/* -Beam code by Gunbuddy - -Beam() proc will only allow one beam to come from a source at a time. Attempting to call it more than -once at a time per source will cause graphical errors. -Also, the icon used for the beam will have to be vertical and 32x32. -The math involved assumes that the icon is vertical to begin with so unless you want to adjust the math, -its easier to just keep the beam vertical. -*/ -/atom/proc/Beam(atom/BeamTarget,icon_state="b_beam",icon='icons/effects/beam.dmi',time=50, maxdistance=10) - //BeamTarget represents the target for the beam, basically just means the other end. - //Time is the duration to draw the beam - //Icon is obviously which icon to use for the beam, default is beam.dmi - //Icon_state is what icon state is used. Default is b_beam which is a blue beam. - //Maxdistance is the longest range the beam will persist before it gives up. - var/EndTime=world.time+time - while(BeamTarget&&world.timelength) - var/icon/II=new(icon,icon_state) - II.DrawBox(null,1,(length-N),32,32) - II.Turn(Angle) - X.icon=II - else X.icon=I - var/Pixel_x=round(sin(Angle)+32*sin(Angle)*(N+16)/32) - var/Pixel_y=round(cos(Angle)+32*cos(Angle)*(N+16)/32) - if(DX==0) Pixel_x=0 - if(DY==0) Pixel_y=0 - if(Pixel_x>32) - for(var/a=0, a<=Pixel_x,a+=32) - X.x++ - Pixel_x-=32 - if(Pixel_x<-32) - for(var/a=0, a>=Pixel_x,a-=32) - X.x-- - Pixel_x+=32 - if(Pixel_y>32) - for(var/a=0, a<=Pixel_y,a+=32) - X.y++ - Pixel_y-=32 - if(Pixel_y<-32) - for(var/a=0, a>=Pixel_y,a-=32) - X.y-- - Pixel_y+=32 - X.pixel_x=Pixel_x - X.pixel_y=Pixel_y - sleep(3) //Changing this to a lower value will cause the beam to follow more smoothly with movement, but it will also be more laggy. - //I've found that 3 ticks provided a nice balance for my use. - for(var/obj/effect/overlay/beam/O in orange(10,src)) if(O.BeamSource==src) qdel(O) - - //All atoms /atom/proc/examine(mob/user, var/distance = -1, var/infix = "", var/suffix = "") //This reformat names to get a/an properly working on item descriptions when they are bloody diff --git a/code/modules/clothing/spacesuits/rig/modules/ninja.dm b/code/modules/clothing/spacesuits/rig/modules/ninja.dm index 31e08a9f35..b5d58c8da6 100644 --- a/code/modules/clothing/spacesuits/rig/modules/ninja.dm +++ b/code/modules/clothing/spacesuits/rig/modules/ninja.dm @@ -161,6 +161,7 @@ if(holder && holder.wearer) if(..(target) && target) + set_dir(get_dir(src,target)) // Face the target holder.wearer.Beam(target,"n_beam",,10) return 1 return 0 diff --git a/polaris.dme b/polaris.dme index c5b957df64..eaadb5ba94 100644 --- a/polaris.dme +++ b/polaris.dme @@ -178,6 +178,7 @@ #include "code\controllers\subsystems\machines.dm" #include "code\datums\ai_law_sets.dm" #include "code\datums\ai_laws.dm" +#include "code\datums\beam.dm" #include "code\datums\browser.dm" #include "code\datums\category.dm" #include "code\datums\computerfiles.dm"