Lightning

by Rotem12
generates lines, beams or lightning bolts
ID:1879807
 
Lightning can create a line, beam, lightning bolt or branched lightning bolt between two vectors.

Lightning GitHub

This was made following this article. The article can be used for further explanation of how it works.

Usage is as simple as:
var/vector/start = new (x1 * 32, y1 * 32) // position in pixels
var/vector/dest = new (x2 * 32, y2 * 32) // position in pixels

var/line/l = new(start, dest)
l.Draw(usr.z)

var/bolt/b = new(start, dest)
b.Draw(usr.z)



Updates:

1.10
  • Adds two colored bolt example to demo.


1.09
  • changes demo to target middle of turf.
  • Updates bar for new beam.
  • Re-writes beam.
  • Removes PIXEL_SCALE for beams.
  • Fixes demo lines not working.


1.08
  • Minor optimization.
  • Changes demo bolt precision to shoot from the hand.
  • Fixes force lightning not resetting loop.
  • Adds PIXEL_SCALE flag to segment.
  • Fixes fade parameter being a fixed value of 50.


1.07
  • Renamed atan2 and rand to avoid conflicts.


1.06
  • Drastically reduces appearance churn.


1.05
  • Tiny optimization.
  • Added force lightning demo. Click stickman faces to zap them.


1.04
  • Added ability to draw lines as overlays.
  • Bolts can now be drawn as overlays, this greatly improves CPU usage as well as adds the ability to rotate bolts by changing transform angle on a single object.
  • Added a proc to rotate last made bolt.


1.03
  • Added bar datum to bars, you can adjust the size of the bar via Adjust()
  • Library now supports drawing on client.screen
  • Line vectors can now be rotated


1.02
  • Added beam datum to handle creation of beams.
  • Added parameter to control the thickness of segments
  • Segment type parameter is now defaulted to /obj/segment


1.01
  • Added targets parameter to branched bolt allowing to set amount of branches amount or targets fire branched bolts at.
  • The demo will now clear lines when mode is changed
  • Fixes the library to allow different icon_size


For a full list of changes click here.
Strange, I had to exit byond for it to detect and grab it. Anyways, I will proceed to torture test it!
Updated
  • Added targets parameter to branched bolt allowing to set amount of branches amount or targets fire branched bolts at.
  • The demo will now clear lines when mode is changed
  • Fixes the library to allow different icon_size
Cool concept. Have any images showing it in action?
Images from the demo or in an actual game?
Either, really. I'm curious how it looks but don't have the time to compile it myself.
Added 4 screenshots.
In response to Rotem12
Rotem12 wrote:
Added 4 screenshots.

Where is that? I'm not seeing them on the github page.
On this site's screenshot tab.
Ah, I had to find the link to the library on Github itself. Now I see it. Very cool.
If you'd like an in-game example gif to post, here's gif I made earlier of the branched bolts




I would also mention that, if you notice, occasionally the ends of the bolts will go crazy and shoot waaay far off from where they should end up around. Not sure what causes that.
I love how it it looks with the tanks, that's so pretty, I'm feeling a wee bit proud that someone found a use for it. Yay I helped someone out there.

I'll look into it the crazy behavior, maybe there's something off with the math.

How's performance? I figured that animate could be changed and perhaps bolts could be pooled and relocated to save some but I haven't toyed with it too much.
Yeah, it works great as the game is planned to have many interesting weapons and an Arc-Caster was one of the planned weapons from the get-go. Figuring out how to get something efficient made was an issue though.

Performance wise it can get a little tricky when you call it frequently. This processor is 3.4ghz per core, and the baseline CPU usage of the game is around 2-3. When using this it jumps to about 5-8.

Any way it could be made faster would be nice. I'm not sure how many times animate() is getting called in this case, but perhaps it may be better to use a flick() to an icon_state of it fading away?
My thoughts are that loop can be set to -1. As the animation ends it's soft deleted but if we add it to a pool it can be later re-used.

The actual work would be determining what bolt to reuse, relocating and maybe even rotating it. Rotation will be the most diffcult part and require most effort. Relocating alone should be a peice of cake.

This will most likely cut down any load you have by randomly picking an already generated bolt. There's just a lot of factors to consider like, bolt length, I can't exactly re-use a whole bolt of length 5 as a bolt of length 7.

In the screenshot rotation seems to be the only challenge since all bolts have same range, even a few fixed ranges would be fine.

A perhaps more simple method of pooling segments alone can also be used, while animate will be re-applied to them and calculations will still be done, we can avoid creating double digit objects per bolt.

What FPS are you running on? After I look over the math to find why it's shooting off to strange destinations I'll try to have a setup similar to yours and try to figure comfortable ways to set it up for better performance.
I remember making a Force Lightning skill for an unreleased Star Wars fan-game years ago. It used Kunark's Line Drawer library and it looked pretty cool for being tile-based. Every couple tiles it would fork, and each segment would be attracted to certain objects like explosive barrels, droids, or other people.

This is much fancier-looking.
I have it running at 60fps. Not sure if that's the cause of the issue or not.

The problem seems to be exacerbated the closer the destination is to the source.
In response to Bravo1
Bravo1 wrote:
The problem seems to be exacerbated the closer the destination is to the source.

I updated to attempt fix it, the update effects both normal and branched bolts, the segments are positioned slightly different now, I hope it looks better.

Aside from that, it also aims to branch out other bolts earlier than it did before, what I think happened was it attempted to branch when it's over 90% close to the end leaving it no room.

There's not much point if bolts branch out too late anyway so that should be better now.

EDIT: I also toyed with pooling, just pooling segments is not having any impact, I already know how to rotate an entire bolt, I'll work on it more later in hopes pooling entire bolts can help.
Why not just generate all the rotations up front in a associated list and build the bolts based on the list?

This might have to be done on a player by player basis but it might be a decent alternative to generating them all on the fly.

I'm going to go play with this, I was actually thinking of putting something like a skill that allows the player to shoot lightning rods. Then another skill that releases electricity , which is drawn to anything struck with a lightning rod. Thanks for posting
I released a beam datum for all those who are interested in beams, there's also a parameter to control thickness, it comes handy with lines beams or if you're using a different icon size.

Because of the new thickness parameter I moved /obj/segment from the demo to the library, the parameter now defaults to /obj/segment, you can still use a different type to generate different results.

I've yet to mess with beam "head", I didn't see much need for it with lightning but it may be nice to do so now.