PixelProjectiles

by Shadowdarke
Pixel based directional projectiles [More]
To download this library for your Linux/Mac installation, enter this on your command line:

DreamDownload byond://Shadowdarke.PixelProjectiles##version=3

Emulator users, in the BYOND pager go to File | Open Location and enter this URL:

byond://Shadowdarke.PixelProjectiles##version=3

2200 downloads
Version 3
Date added: May 10 2005
Last updated: Jul 29 2009
16 fans
Pixel Projectiles provides a simple interface for customizable directional projectiles that can fire at any angle, speed, and duration between updates and guarantees accurate hits.

Hooks are provided to allow you to define:
  • how hits are determined.
  • what happens when the projectile hits an atom.
  • what happens when the projectile reachs max range without a hit

  • Also includes a handy proc for spread shots. Fire an even spread or random shrapnel within the cone of fire with one easy proc call.

    Version 3: (04-04-2006)
  • Fixed a bug that caused high velocity projectiles to occasionally miss. Kudos to DarkCampainger for not only noticing it, but also finding the fix! (DarkCampainger, XxDohxX)

Comments

Ease: (Mar 14 2013, 12:59 am)
Firstly; Shadowdarke, this is an amazing library. I love it. Truly I do.

Anyway, I have one small suggestion (that I've implemented in to my own game): owner's direction!

FirePixelProjectile(owner, "dir[owner.dir]", /obj/sd_px_projectile/)

proc/FirePixelProjectile(atom/owner, destination, proj_type = \
/obj/sd_px_projectile)
/* fires a pixel based projectile of type proj_type from owner to
destination. Destination may be a turf or angle of fire. */

if(!owner) return
var/obj/sd_px_projectile/P = new proj_type()
P.owner = owner
P.loc = P.TurfOf(owner)
P.pixel_x = P.cx
P.pixel_y = P.cy

if(istext(destination))
destination=copytext(destination,4)
if(destination=="4") //East
destination=0
else if(destination=="5") //Northeast
destination=45
else if(destination=="1") //North
destination=90
else if(destination=="9") //Northwest
destination=135
else if(destination=="8") //West
destination=180
else if(destination=="10") //Southwest
destination=225
else if(destination=="2") //South
destination=270
else if(destination=="6") //South east
destination=315
if(isnum(destination)) // an angle
P.dx = cos(destination) * P.speed
P.dy = sin(destination) * P.speed

else if(istype(destination, /atom))
var
atom/A = destination
dx = (A.x - owner.x) * 32 + A.pixel_x - owner.pixel_x
dy = (A.y - owner.y) * 32 + A.pixel_y - owner.pixel_y
px_dist = sqrt(dx * dx + dy * dy)
if(px_dist) // unit vector times P.speed
P.dx = P.speed * dx / px_dist
P.dy = P.speed * dy / px_dist
else // owner and target in exact same position
P.Hit(A)
return P

else
world.log << "Invalid destination: FirePixelProjectile([owner], [destination], \
[proj_type])"
del(P)
return

if(P)
spawn(P.delay) // so this proc can return normally
while(P)
P.UpdatePosition()
//if(P && (alert("[P.x]:[P.cx], [P.y]:[P.cy]",,"Ok", "Delete")=="Delete"))
// del(P)
if(P) sleep(P.delay)

return P


It's not the most elegant; I'm sure something done with the directional bit flags would be a million times better, but I'm still not comfortable using them yet.

The "dir[owner.dir]" bit is so that the proc recognises it as text.

~Ease~
ArchAngel075: (Feb 13 2013, 8:59 am)
(note that any tabs, spaces and indentations are represented by a ">>", one set of two ">" is == one indentation)

Hi I have a suggestion for a further control over the projectile :

I was fiddling with the handling of Hit and found that using a extra variable for a projectile
ie
obj/sd_px_projectile/Bullet
passThrough = 2

Now on Hit(atom/A) i had some small code like :
if(A.density == 1)
if(src.passThrough >= 1)
src.passThrough -= 1
else
del(src)

what this will do is when it enters a dense object it will deduct from passThrough, if passThrough is 0 then it deletes the projectile..

this allows projectiles to pass through dense objects X times. and a value of 0.5 for passThrough will allow only entry into a dense object, but not exit.

-end-
Syntty: (Jun 18 2011, 12:45 pm)
How could you make so that the projectile's icon state changes according to the direction the projectile (arrow in this case) is flying?
Spirit Gun 84: (Feb 13 2011, 3:01 pm)
Very efficient.