ID:160162
 
Ok not sure if this goes here but couldnt think of any other place to put it. Im using Shadowdarke's pixel projectile library and found that if I have directional projectiles (like an arrow for example) that they dont face the right direction(or anywhere near) and they always face east no matter which direction they are moving. Was wondering if im missing something in the library. Or how I can fix that

Edit:
Ok for anybody whos interested I made a couple of short adjustments to Shadowdarke's Library in order to make directional projectiles face the right way. Now im not the most experienced coder so this might not be the best way to do it but it gets the job done and does it nicely. I use this verb to create the different icon states
mob/verb
Make_Icon(arg as icon)
var/icon/I=new(arg)
for(var/i=1,i<=12,i++)
var/icon/N=new(arg)
N.Turn(-i*30)
I.Insert(N,"[i*30]")
del(N)
usr.icon=I
usr<<ftp(I)

Then i modified part of the projectile code to change the icon state when the projectile was create like this
//this is under the object definition
direct(atom/A)
//returns the direction of the projectile in degrees rounded to the closest 30 degrees
var/sx = (A.x - x) * 32
var/sy = (A.y - y) * 32
var/sh=sqrt(sx*sx+sy*sy)
var/deg=round(arcsin(sy/sh))
if(sx<0&&sy>0)//probably not the best but its my work around for arctan its simple and works
deg+=90
if(sx<0&&sy<0)
deg+=270
if(sx<0&&sy==0)
deg+=180
if(sx>=0&&sy<0)
deg+=360
var/i=0
deg-=15//this little part rounds the degree to the nearest 30 either up or down depending on which is closer
for(deg,deg>=0,deg-=30)
i++
deg=i*30
return deg

//this is part of shadowdarke's projectile code that i added in the icon state changes to
if(isnum(destination)) // an angle
P.dx = cos(destination) * P.speed
P.dy = sin(destination) * P.speed
var/i=0
for(destination-15,destination>=0,destination-=30)
i++
P.icon_state="[i*30]"
else if(istype(destination, /atom))
P.icon_state="[P.direct(destination)]"
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
If you plan on having angular motion, then you have two options:

1.) Dynamically create a rotated icon using icon.Turn().
2.) Make an icon state for all 361 angles. (integer angles)
In response to Kakashi24142
ok so his library doesnt deal with the direction of the projectile so i would need to go in and modify it to change the direction of the projectile to match its direction
In response to NightJumper88
Yep. Btw, I would not recommend (1) because that would become very laggy. Instead of making icon states for all the angles, make them only for all angles that are multiples of 45 starting from 0 to get a close approximation. To get closer, try multiples of 30 starting from 0.
In response to Kakashi24142
ok so pretty much what i would have to do is either make 360 different icon states for each angle and then put some code in his library to find the angle (already does this for one situation but the other would have to add in a quick trig function to find angle easy enough) and change the projectile state to that.

Or maybe make a different icon state every 30 degrees (so i only have to make 12 different states) and set a window that it would be the different icon states.

Or could i make a quick proc to use the turn() proc to make all the images for me is that possible?
In response to NightJumper88
NightJumper88 wrote:
Or could i make a quick proc to use the turn() proc to make all the images for me is that possible?

You can use turn() to do it, but I wouldn't recommend using turn() to dynamically generate 360 different icon_states at runtime. Instead it might be a better idea to use a combination of Turn() and Insert() to build up a .dmi of all the desired states, and then use ftp() to save it to your harddrive. Then use that icon in your game.
In response to NightJumper88
I suggest the 2nd option with the multiples of 30 degrees. What you do is modify the library so that the icon state is changed to the closest angle. (i.e. if the direction it's moving is 45 degrees north from east, then the closest multiple of 30 could either be 30 or 60, so you choose whether to round up or down.)
In response to Jon88
Thats what I was actually getting to not do it at runtime but make the dmi file and save it to use in my game
I also hit this problem. Replacing ShadowDarke's procedure with the following one will use the directional state by using get_dir on the projectile's starting point and its destination. If you want the direction to be continuously updated, then you'll also need to make a couple of changes in the UpdatePosition() proc.

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(isnum(destination)) // an angle
P.dx = cos(destination) * P.speed
P.dy = sin(destination) * P.speed
var/atom/dest=locate(P.x+round(P.dx/32), P.y+round(P.dy/32), P.z)
P.dir=get_dir(P, dest)

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)
P.dir=get_dir(P, destination)
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) sleep(P.delay)

return P
In response to Kakashi24142
2.) Make an icon state for all 361 angles. (integer angles)

Or he could just use the turn() proc :P. It could get CPU intensive, though, unless he cached the icons and kept references to them with fcopy_rsc().
In response to Nickr5
Im doing something similar but a little more advance so that its looks nicer for diagnals. Ill post what i do once i get it done and maybe make a small library attachment to go with his library for future use if i get the icon making done
bump for edit on first post
NightJumper88 wrote:
Ok not sure if this goes here but couldnt think of any other place to put it.

This is a fine place for the question. Most libraries, including PixelProjectiles, have a link to the owner's forum. You might want to post questions there too. I tend to check my forum more often that the BYOND forums and I'm sure I miss tons of posts related to my libraries because of the vast number of posts here.


Im using Shadowdarke's pixel projectile library and found that if I have directional projectiles (like an arrow for example) that they dont face the right direction(or anywhere near) and they always face east no matter which direction they are moving. Was wondering if im missing something in the library. Or how I can fix that

PixelProjectiles doesn't have directional icons because no one requested them before. I'll work on a general purpose direction system for the library. :)


Edit:
Ok for anybody whos interested I made a couple of short adjustments to Shadowdarke's Library in order to make directional projectiles face the right way.

It's generally a bad idea to directly change a library when you don't have to. If the library is updated and you download the new version, all your changes will be overwritten.

If you can't wait for the new version of the library to come out (and who knows when I'll get around to that? :( ), you can add your modifications without changing the library itself. FirePixelProjectile() returns the projectile that has been fired so that you can perform additional manipulations on it beyond what the library automatically does. You can make a custom proc to call FirePixelProjectile() and update the direction based on the projectiles dx and dy vars.

This should conform to your icon_states:
proc/FireFancyProjectile(atom/owner, destination, proj_type = /obj/sd_px_projectile)
var/obj/sd_px_projectile/P = FirePixelProjectile(owner, destination, proj_type)
P.DisplayAccurateDirection(30)
return P

obj/sd_px_projectile/proc/DisplayAccurateDirection(multiple = 1)
/* Changes the projectiles icon_state to match the direction it travels.
"multiple" is the nearest multiple that the angle will be rounded to. */

var/angle = 0
if(dx || dy) // (0,0) would produce an error
angle = arccos(dx/sqrt(dx*dx+dy*dy))
if(dy<0) angle = 360-angle
icon_state = "[round(angle, multiple)]"

In response to Shadowdarke
OK thanks ill try that out