Jump to content

Home

[code] Four-Barreled Weapon


recombinant

Recommended Posts

My latest dilemma in this series involves the following weapon (fusion cutter from Dark Forces, unskinned)...

 

As you can see, I've labeled the four barrels to show where the projectiles are supposed to be fired from...

 

Fusion4Barrel.jpg

 

Is is possible to have separate fire origins? I was planning on seeing if our weapon modeler could create four "tag_flash" tags named "tag_flash", "tag_flash1", "tag_flash2", and "tag_flash3" and alternate them in CG_AddPlayerWeapon(), but I wasn't sure if that was the right way to go. Any ideas?

 

For primary fire, we want to have it fire sequentially 1,2,3,4,1... and on alt-fire do all four at once (don't know if that's doable however).

 

If anyone has already done something like this and would like to share some of their insights I'd appreciate it. Otherwise I'll keep plugging away at it...

 

Thanks!

 

:D

Link to comment
Share on other sites

Sure it's possible

 

well, that helps a bit.

 

but you'd have to do some code changes to make it work.

 

i'm not worried about that so much (that's why i prefixed the thread name with "

")... i was hoping to bounce the idea of some of the more experienced coders to see if my methodology was a) not the best way to do it, b) overly complex and there was actually some simpler way of accomplishing it, and i'm going in the wrong direction.

 

but if the method of attack seems reasonable to you and others then I'm willing to trust your judgment. :D

 

thanks!

Link to comment
Share on other sites

sorry was lazy, i ment the blaster code

so that u can forgive me ;)

here is a straith paste of what i mean

 

//static void WP_FireBlaster( gentity_t *ent, qboolean altFire )
static void WP_FireBlaster( gentity_t *ent, qboolean altFire, qboolean isAtst)
//---------------------------------------------------------
{
vec3_t	dir, angs, newMuzzle;

//NOTETOSELF : probably npc use this , as an atst

vectoangles( forward, angs );

if ( altFire )
{// add some slop to the alt-fire direction
	angs[PITCH] += crandom() * BLASTER_SPREAD;
	angs[YAW]	+= crandom() * BLASTER_SPREAD;
}

AngleVectors( angs, dir, NULL, NULL );

// FIXME: if temp_org does not have clear trace to inside the bbox, don't shoot!

if ( isAtst )
{
	newMuzzle[0] = muzzle[0] - atst_muzzleone.value;
	newMuzzle[1] = muzzle[1] - atst_muzzletwo.value;
	newMuzzle[2] = muzzle[2] + atst_muzzletre.value;

	if (altFire)
	{
		newMuzzle[0] += atst_muzzlefor.value;
		newMuzzle[1] -= atst_muzzlefiv.value;
	}

	WP_FireBlasterMissile( ent, newMuzzle, dir, altFire );
}
else
{
	WP_FireBlasterMissile( ent, muzzle, dir, altFire );
}

if ( isAtst )
{//fire the 'second' one also
	if (!altFire)
	{
		newMuzzle[1] += atst_muzzlesix.value;
	}
	WP_FBlasterAgain(ent, altFire, newMuzzle);
	if (altFire)
	{//3rd and 4th !
		WP_FBlasterAgain(ent, altFire, newMuzzle);
		WP_FBlasterAgain(ent, altFire, newMuzzle);
	}
}
}//endatstcode

Link to comment
Share on other sites

...well, if it's going to have to be really in-depth fix, then I'll have to go for it.

 

I'm going to try out the multiple tag method first and see how that goes (since our modeler already put them in the model).

 

I'll keep you posted on my progress.

 

:D

Link to comment
Share on other sites

You'll need the multiple tag_flash#'s clientside for rendering the muzzle "powder flash" on firing, and then you'll have to create 4 vec3_t muzzle points (see the vec3_t array Code referenced above) as offsets from the player origin to determine where the 'bullet' originates serverside.

 

You have the right idea.

Link to comment
Share on other sites

Yeah, Azymn stated what I was getting at. At the minimum, you'll need to change the clientside to make the muzzle flash work correctly.

 

You can also play with some stuff server depending on how close you want the bolt orientation to the actual muzzle, but it's not really that critical. Raven did really simple system based off the viewpoint or something like that. I made MotF be based off the actual ghoul2 model but that's 1) complicated and 2) screws up the crosshair alignment.

Link to comment
Share on other sites

something's not right here. i must be making my modifications in the wrong location (btw, this only refers to the "tag_flash" issue - I haven't gotten back to the muzzle stuff...).

 

During one click of the mouse button, my debug statement in cg_weapons.c, CG_AddPlayerWeapon output the following (written out to the console):

 

iFusionBarrel: 0
iFusionBarrel: 1
iFusionBarrel: 2
iFusionBarrel: 3
iFusionBarrel: 0
iFusionBarrel: 1
iFusionBarrel: 2
iFusionBarrel: 3
iFusionBarrel: 0

 

based on the value of iFusionBarrel, it decides which tag_flash to use:

 

CG_Printf("iFusionBarrel: %i\n", iFusionBarrel); // jodfmod debug
if (iFusionBarrel == 0) 
{
 CG_PositionEntityOnTag( &flash, &gun, gun.hModel, "tag_flash");
}
else if (iFusionBarrel == 1) 
{
 CG_PositionEntityOnTag( &flash, &gun, gun.hModel, "tag_flash1");
}
else if (iFusionBarrel == 2) 
{
 CG_PositionEntityOnTag( &flash, &gun, gun.hModel, "tag_flash2");
}
else if (iFusionBarrel == 3) 
{
 CG_PositionEntityOnTag( &flash, &gun, gun.hModel, "tag_flash3");
}

iFusionBarrel++;
if (iFusionBarrel == 4)
{
 iFusionBarrel = 0;
}

 

So obviously that must be the wrong place to put it, or have the firing logic to the incrementing... because this seems to just increment over and over. thus creating a random (practically) selection of the tag_flash...

 

This was a similar problem I was having in CG_CalcMuzzlePoint.

 

Hmmm...

Link to comment
Share on other sites

Originally posted by razorace

Well, is iFusionBarrel a global varible?

 

...not currently.

 

Basically, I was using it locally within CG_AddPlayerWeapon(), but I'm beginning to see that I've been narrowing my scope too much.

 

So I'm thinking I should probably make iFusionBarrel global, and increment it when firing instead. Then in CG_AddPlayerWeapon() use the appropriate tag_flash. Sound reasonable?

 

...then on to the muzzle issue.

Link to comment
Share on other sites

OK. Looks like that was the right way to go. Funny. Just this morning before I read your post I was mulling all this over (as I often do when getting ready for work...) and it occurred to me that I needed to have the separation - i.e. increment it in the firing function.

 

...then razor asked the above question which confirmed my suspicions.

 

So now I have a g_iFusionBarrel global that maintains the current flash "index" and it gets incremented in CG_FireWeapon(). It seems to be working correctly now.

 

Now I have to deal with the projectile issue.

 

:D

Link to comment
Share on other sites

OK... good point.

 

So I added a component to the centity_s struct and now in CG_AddPlayerWeapon I do the following:

 

CG_Printf("cent->fusionBarrelIndex: %i\n", cent->fusionBarrelIndex); // jodfmod debug
if (cent->fusionBarrelIndex == 0) 
{
 CG_PositionEntityOnTag( &flash, &gun, gun.hModel, "tag_flash");
}
else if (cent->fusionBarrelIndex == 1) 
{
 CG_PositionEntityOnTag( &flash, &gun, gun.hModel, "tag_flash1");
}
else if (cent->fusionBarrelIndex == 2) 
{
 CG_PositionEntityOnTag( &flash, &gun, gun.hModel, "tag_flash2");
}
else if (cent->fusionBarrelIndex == 3) 
{
 CG_PositionEntityOnTag( &flash, &gun, gun.hModel, "tag_flash3");
}

 

...and increment it in CG_FireWeapon() like so:

 

// lightning gun only does this this on initial press
if ( ent->weapon == WP_FUSION_CUTTER ) {

 //---------------------------------------------------------
 // jodfmod - increment barrel index for the current entity
 //---------------------------------------------------------
 cent->fusionBarrelIndex++; 
 if (cent->fusionBarrelIndex == 4)
 {
   cent->fusionBarrelIndex = 0;
 }
 //---------------------------------------------------------

 if ( cent->pe.lightningFiring ) {
   return;
 }
}

 

So hopefully that will work OK...

Link to comment
Share on other sites

Well, I was able to get the four-barreled weapon firing working last night!

 

At first, I was somewhat dubious about my edits, but it worked just like I wanted it to!

 

Thanks for the help, gentlemen (with special shouts going out to Azymn)!!!

 

:sbdance

Link to comment
Share on other sites

Originally posted by razorace

Yep, just check out how the server handles the creation of alt-fire effects/missiles and simply create 4 bolts with a simple vertical offset (based on your oientation if you're picky).

 

good suggestion, razor.

 

thanks!

 

:D

Link to comment
Share on other sites

Looks like I've almost got it going, but there's something up with my vector math...

 

stupidly, I just added/subtracted offset values from the second element a temporary muzzle entity I create in the routine, mistakenly thinking that this would do what I want.

 

The funny thing is that if I'm turned one way, it looks like I"m shooting one big projectile (since from that perspective they're all stacked one on top of another), and if I turn 90 degrees I get four projectiles horizontally - basically what I wanted.

 

So obviously it's offsetting the muzzle on one axis only in threespace (duh).

 

My next question is...

 

How can I come up with the appropriate offsets that will always be perpendicular to the player's view, thus creating four projectiles in a row horizontally that shoot forward?

 

Here's a diagram of what I'm trying to accomplish (the black dashed arrow is the muzzle vector, and the red arrows are the desired vectors offset from the muzzle):

 

VectorDiagram.gif

 

(I've always had a problem with vectors in math... grrrrr...)

 

Thanks!

 

:D

Link to comment
Share on other sites

Since i'm bored-crazy right now, and you've got most of it done...

 

static void ShootFourShots( gentity_t *ent )

{

gentity_t *missile1;

gentity_t *missile2;

gentity_t *missile3;

gentity_t *missile4;

 

vec3_t tmpMuzzle, newMuzzle;

 

VectorCopy(fusionMuzzle[0], tmpMuzzle);

VectorCopy(ent->s.pos.trBase, newMuzzle);

 

VectorMA(newMuzzle, tmpMuzzle[0], forward, newMuzzle);

VectorMA(newMuzzle, tmpMuzzle[1], right, newMuzzle);

newMuzzle[2] += ent->client->ps.viewheight + tmpMuzzle[2];

 

SnapVector( newMuzzle );

 

missile1 = CreateMissile( newMuzzle, forward, FUSION_CUTTER_VELOCITY, 10000, ent, qfalse);

 

...rinse, repeat as necessary....

 

:)

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...