Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
Gamer With Dignity

Projectile colliding with the player on spawn

Recommended Posts

I'm having trouble making a mod that adds projectile bullets to Doom. I have the bullets spawn in using an ACS script, but every time they do, they immediately collide with the player and disappear. Setting the NOCLIP flag fixes this, but then it doesn't collide with enemies or walls.

How do I make a projectile bullet that will collide with enemies but not with the player?

#library "Projectile"
#include "zcommon.acs"

Script "SpawnBullet" (VOID) NET
{
	int uid1 = UniqueTID();
	int uid2 = UniqueTID();
	int ptc = (GetActorPitch(0)>>8)+random(-2,2);
	int ang = (GetActorAngle(0)>>8)+random(-2,2);
	int speed = cos(GetActorPitch(0)) * 250 >> 16;
        int vspeed = -sin(GetActorPitch(0)) * 250 >> 16;
	Spawn("MapSpot", GetActorX(0), GetActorY(0), GetActorViewHeight(0)-12.0, uid1);
	SpawnProjectile(uid1, "PistolBullet", ang, speed, vspeed, 0, uid2);
	SetActorPitch(uid2, ptc);
	Thing_ChangeTID(uid2, 0);
}

Share this post


Link to post

The only way would be to make the first parameter of SpawnProjectile use the player's own tid rather than that of a map spot. Then you won't have any option to spawn the projectile at an arbitrary height, though. You'd have to solve that problem via a custom weapon actor in DECORATE rather than via ACS.

EDIT: I can think of an ACS-only solution now: After spawning the projectile using the player's tid, change the projectile's position via SetActorPosition.

Share this post


Link to post
scifista42 said:

EDIT: I can think of an ACS-only solution now: After spawning the projectile using the player's tid, change the projectile's position via SetActorPosition.

Thanks I tried that. This is the updated code:

#library "Projectile"
#include "zcommon.acs"

Script "SpawnBullet" (VOID) NET
{
	int uid = UniqueTID();
	int ptc = (GetActorPitch(0)>>8)+random(-2,2);
	int ang = (GetActorAngle(0)>>8)+random(-2,2);
	int speed = cos(GetActorPitch(0)) * 250 >> 16;
        int vspeed = -sin(GetActorPitch(0)) * 250 >> 16;
	SpawnProjectile(0, "PistolBullet", ang, speed, vspeed, 0, uid);
	SetActorPosition(uid, GetActorX(uid), GetActorY(uid), GetActorViewHeight(0)-12.0, FALSE);
	SetActorPitch(uid, ptc);
	Thing_ChangeTID(uid, 0);
}
It seems to only be working with bullets pitched at an upwards angle. What I think is happening is that the downward facing bullets are spawning at doomguy's feet and then colliding with the floor before it gets a chance to set the position.

Is there some way that I can make the projectile invincible until I set a flag on it from within ACS? That way I can make sure it doesn't die before the position is set.

Share this post


Link to post

The projectile collides with the player because the player isn't the projectile's "target" pointer. You could try using SetPointer to put the player as the projectile's target pointer.

Share this post


Link to post

I'm not really sure if that would work, though. Iirc, if you spawn a projectile with something it can collide with, it'll collide with it immediately before doing anything else.

You might be better of doing some nonsense with spawning a projectile through a CustomInventory item given to the player, because that will definitely set the projectile's target before it finished spawning.

Share this post


Link to post

The target of a projectile is the actor that shot it (in this case, the player), not the thing being shot at. This is how the game knows who to give credit for what the projectile kills.

Then again, I am still learning DECORATE and haven't dipped into ACS yet, so I might be wrong in this context.

Share this post


Link to post
Albertoni said:

Alternatively, spawn it without movement and then
https://zdoom.org/wiki/SetActorVelocity


Thanks I tried this and it works. Now it's just a matter of tweaking everything.

Albertoni said:

Also, you might want to call UniqueTID only once for each player. You might run out of tids like that lol


It calls UniqueTID only once at the beginning of the spawn function, and then at the end of it calls Thing_ChangeTID to free up the TID by giving the bullet a TID of 0. Is that okay or is there a better way of doing it?

Share this post


Link to post
Gamer With Dignity said:

Is that okay or is there a better way of doing it?

It -should- be okay. If you want to be really sure it's okay, change your code to
UniqueTID(10000);
That way, you'll get an almost-100%-unique TID. Then print the TID to the console or the screen. If after a second you get the same TID, then it's (almost) good.

What do I mean by almost? Well, if your mod is intended to be compatible with ZDoom stuff, you might want to change the code to UniqueTID(0, 1000);. Since in ZDoom things can have IDs, you might run into compatibility problems. Read the Parameters part of the wiki: https://zdoom.org/wiki/UniqueTID

Sorry if I'm hard to understand, I't's almost 3:30AM here and I was just giving the last check of the night to some sites, feel free to ask if I said something confusing or didn't make sense :)

Share this post


Link to post
Gamer With Dignity said:

It calls UniqueTID only once at the beginning of the spawn function, and then at the end of it calls Thing_ChangeTID to free up the TID by giving the bullet a TID of 0. Is that okay or is there a better way of doing it?

I think your way is actually the optimal way.

Share this post


Link to post

In case any of you were mistaken into thinking I know what I'm doing...

https://mega.nz/#!TwYj0KYT!Zqojwa8IkcamX4Lwq85blgZCoN36oceSIFp307OI3Q0

Script "SpawnBullet" (VOID) NET
{
	int uid = UniqueTID();
	int ptc = GetActorPitch(0);
	int ang = GetActorAngle(0)>>8;
	int speed = FixedMul(cos(ptc), 10.0);
        int vspeed = -sin(ptc);
	Print (f: vspeed);
	SpawnProjectile(0, "PistolBullet", ang, speed>>16, 0, 0, uid);
	SetActorPosition(uid, GetActorX(uid), GetActorY(uid), GetActorViewHeight(0)-4.0, FALSE);
	SetActorVelocity(uid, 0, 0, vspeed, TRUE, FALSE);
	SetActorPitch(uid, FixedMul(ptc,0.7));
	Thing_ChangeTID(uid, 0);
}
I've resorted to multiplying the bullet horizontal speed by an arbitrary value of 10 because for some reason there isn't a 1:1 ratio between vertical and horizontal speeds. It's causing my bullets to drift towards the horizon rather than ascending/descending at the correct rate. What ratio should I be using instead, and why the heck can't I pass the same values to SetActorVelocity as I do to SpawnProjectile?

Also I think a significant amount of accuracy is being lost by the horizontal angle conversion ( int ang = GetActorAngle(0)>>8; )

The more I tweak this the more broken it becomes. Zdoom's data types are really starting to piss me off. I need help :(

/gripe

Share this post


Link to post
Gamer With Dignity said:

there isn't a 1:1 ratio between vertical and horizontal speeds.

The ratio should be 1:1. Try setting both the projectile's speed and vspeed within SetActorVelocity - you might need some sin/cos functions for the velx/vely parameters, but you'll also achieve higher accuracy. I'm also not sure if you need to use SetActorPitch at all. Also, isn't the projectile's DECORATE-coded behavior influencing its movement somehow?

Gamer With Dignity said:

why the heck can't I pass the same values to SetActorVelocity as I do to SpawnProjectile?

SpawnProjectile is based on Thing_Projectile, which was inherited from Hexen, which is 20+ years old and its parameter values were limited to range 0-255, whereas SetActorVelocity is a newer ZDoom-specific function that can handle fixed point numbers.

Gamer With Dignity said:

Also I think a significant amount of accuracy is being lost by the horizontal angle conversion ( int ang = GetActorAngle(0)>>8; )

And also by this: ( speed>>16 )

Share this post


Link to post
scifista42 said:

The ratio should be 1:1. Try setting both the projectile's speed and vspeed within SetActorVelocity - you might need some sin/cos functions for the velx/vely parameters, but you'll also achieve higher accuracy.


Yeah I was hoping that I would be able to get by without having to use trig functions to set two components of lateral velocity, but I guess that's not gonna happen.

scifista42 said:

I'm also not sure if you need to use SetActorPitch at all.


If you take a look at the mod itself, pitch is used in determining which voxel models the bullet should use. I created different models for the bullets ranging a full 180 degrees of pitch, with one model per every 10 degrees. I could change it to use a custom inventory though. The decision to use pitch is an arbitrary one.

scifista42 said:

Also, isn't the projectile's DECORATE-coded behavior influencing its movement somehow?


I don't think so since calling SpawnProjectile from ACS and specifying 0 for each velocity just results in a motionless bullet. And I doubt the DECORATE is having a multiplicative effect on speed but I could be wrong.

scifista42 said:

SpawnProjectile is based on Thing_Projectile, which was inherited from Hexen, which is 20+ years old and its parameter values were limited to range 0-255, whereas SetActorVelocity is a newer ZDoom-specific function that can handle fixed point numbers.


Very interesting! I'll keep that in mind.

scifista42 said:

And also by this: ( speed>>16 )


I'm probably going to find a way to fix the precision loss problem on my own, I just haven't put any thought into it yet. I'll try to get this one done by Thanksgiving.

Share this post


Link to post

Now I realized, according to their wiki pages, the velocities in SpawnProjectile and Thing_Projectile are given in "units per 8 tics", whereas the velocities in SetActorVelocity are presumably given in units per 1 tic, so you might be able to avoid trig functions if you just change your arbitrary value 10 to 8.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×