Inside3D!
     

The Floor Is Eating My Spikes!

 
Post new topic   Reply to topic    Inside3d Forums Forum Index -> QuakeC Programming
View previous topic :: View next topic  
Author Message
Junrall



Joined: 21 Sep 2009
Posts: 136
Location: North West Oregon, USA

PostPosted: Sat Feb 20, 2010 8:10 am    Post subject: The Floor Is Eating My Spikes! Reply with quote

Playing around with ricocheting spikes... they work great, however when they hit the floor they disappear. I've gone through my code from one end to the other and can't seem to figure it out. Would someone mind looking through the code? Maybe a fresh set of eyes will see what I don't.
Also, they don't seem to like doors and switches and when they touch the sky they do not remove themselves. Any ideas?

Code:
void() RicoThink =
{
   if (self.attack_finished < time)
   {
      remove(self);
      return;
   }

   if (self.flags & FL_ONGROUND)
      self.flags = self.flags - FL_ONGROUND;

   self.velocity = self.oldspikevel;
   self.angles = vectoangles(self.velocity);
   self.nextthink = time + 0.1;
};

void() RicoSpikeTouch =
{
   if (other.solid == SOLID_TRIGGER)
      return;
   if (pointcontents(self.origin) == CONTENT_SKY)
   {
      remove(self);
      return;
   }

   if (other.takedamage)
   {
      spawn_touchblood (9);
      T_Damage (other, self, self.owner, 9);
      if (other.health <= 0 && other != world)
         other.solid = SOLID_NOT;
      remove(self);
   }
   else
   {
      WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
      WriteByte (MSG_BROADCAST, TE_GUNSHOT);
      WriteCoord (MSG_BROADCAST, self.origin_x);
      WriteCoord (MSG_BROADCAST, self.origin_y);
      WriteCoord (MSG_BROADCAST, self.origin_z);
      
      self.velocity = ReboVec(self.origin, self.oldspikevel, FALSE);
      self.velocity = 1000 * self.velocity;
      self.angles = vectoangles(self.velocity);
      self.oldspikevel = self.velocity;

      if (self.flags & FL_ONGROUND)
         self.flags = self.flags - FL_ONGROUND;

      self.owner = self;
   }
};

void(vector org, vector dir) LaunchRicoSpike =
{
   newmis = spawn ();
   newmis.owner = self;
   newmis.movetype = MOVETYPE_FLYMISSILE;
   newmis.solid = SOLID_BBOX;

   newmis.touch = RicoSpikeTouch;
   newmis.classname = "spike";
   newmis.think = RicoThink;
   newmis.nextthink = time + 6;
   newmis.attack_finished = time + 5;
   setmodel (newmis, "progs/spike.mdl");
   setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
   setorigin (newmis, org);

   newmis.angles = vectoangles(dir);
   newmis.velocity = dir * 1000;
   newmis.oldspikevel = newmis.velocity;

};

void(float ox) W_FireRicoSpikes =
{
   local vector   dir;

   makevectors (self.v_angle);

   if (self.ammo_nails >= 2 && self.weapon == IT_SUPER_NAILGUN)
   {
      sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
      self.attack_finished = time + 0.2;
      self.currentammo = self.ammo_nails = self.ammo_nails - 2;
      dir = aim (self, 1000);
      LaunchRicoSpike (self.origin + '0 0 16', dir);
      setmodel (newmis, "progs/s_spike.mdl");
      setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
      self.punchangle_x = -2;
      return;
   }

   if (self.ammo_nails < 1)
   {
      self.weapon = W_BestWeapon ();
      W_SetCurrentAmmo ();
      return;
   }

   sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
   self.attack_finished = time + 0.2;
   self.currentammo = self.ammo_nails = self.ammo_nails - 1;
   dir = aim (self, 1000);
   LaunchRicoSpike (self.origin + '0 0 16' + v_right*ox, dir);

   self.punchangle_x = -2;
};


Eventually I'll have the code set up so that some spikes will stick and others will ricochet or bounce of solids. Maybe not an original, but sure is fun to do!
_________________
Good God! You shot my leg off!
Back to top
View user's profile Send private message
Teiman



Joined: 03 Jun 2007
Posts: 309

PostPosted: Sat Feb 20, 2010 9:48 am    Post subject: Reply with quote

ricochet spikes are the fun (specially with proper ricochets wavs).

the subject for the thread is also a win Smile


I don't know much about modding, other people can help much more than me.. I am looking at this anyway.

humm...
setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);

where is the real origin of the model? could be that the model of the spikes end underground?
Back to top
View user's profile Send private message
Error
Inside3D Staff


Joined: 05 Nov 2004
Posts: 558
Location: VA, USA

PostPosted: Sat Feb 20, 2010 10:03 am    Post subject: Reply with quote

oh god, Darkplaces makes everything so much easier Surprised

Code:

//DP_MOVETYPEBOUNCEMISSILE
//idea: id Software
//darkplaces implementation: id Software
//movetype definitions:
//float MOVETYPE_BOUNCEMISSILE = 11; // already in defs.qc
//description:
//MOVETYPE_BOUNCE but without gravity, and with full reflection (no speed loss like grenades have), in other words - bouncing laser bolts.

_________________
Inside3D : Knowledge Is Power
Darkplaces Documentation Wiki
Back to top
View user's profile Send private message Send e-mail Visit poster's website AIM Address Yahoo Messenger MSN Messenger
Junrall



Joined: 21 Sep 2009
Posts: 136
Location: North West Oregon, USA

PostPosted: Sat Feb 20, 2010 8:24 pm    Post subject: Reply with quote

Error wrote:
oh god, Darkplaces makes everything so much easier Surprised

Lol... I'm sure it does:)
I've seen many similar answers for other QC questions... makes me wonder if I should spend time learning how to code for Darkplaces Razz Can I do a check in QC to see if DP is being used or not and create code for DP and standard Quake?
Which creates more questions to pop into my head... which I'll post in another index and discussion Smile

Teiman wrote:
humm...
setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);

where is the real origin of the model? could be that the model of the spikes end underground?

The setsize is directly from Quake's launch_spike function, so I'm not sure if that is the issue or not. Though, you may be right about the spikes ending below ground. Wouldn't the following code take care of that?
Code:
   if (self.flags & FL_ONGROUND)
      self.flags = self.flags - FL_ONGROUND;


Teiman wrote:
ricochet spikes are the fun (specially with proper ricochets wavs).

I have some cool ricochets wavs and bullet zings! In some rough ricochet code I was testing, you can hear the ricochets sounds then a zing/whir as the spike flies by! Very cool Very Happy
_________________
Good God! You shot my leg off!
Back to top
View user's profile Send private message
Supa



Joined: 26 Oct 2004
Posts: 122

PostPosted: Sat Feb 20, 2010 9:15 pm    Post subject: Reply with quote

LaunchRicoSpike wrote:
newmis.nextthink = time + 6;

Is there a reason that the spike's .think function is called so late? I remember from working with rebounding projectiles earlier that the server will mangle the velocity of projectiles on collision, but I can't be sure if that's causing your floor problem with just this. Anyway, so long as you're working on this you should invoke the spike's velocity correction one frame after every touch by adding self.nextthink = time to your touch code.

Code:

      if (other.health <= 0 && other != world)
         other.solid = SOLID_NOT;

You do understand that this will break things like shootable buttons that reset after each trigger, right?

Quote:
Can I do a check in QC to see if DP is being used or not and create code for DP and standard Quake?

All you need to do is check for the pr_checkextension cvar to see if you can use engine-specific extensions or not. Everything you need to know is right here, there's an example right at the beginning to get you started.
Back to top
View user's profile Send private message Send e-mail
ceriux



Joined: 06 Sep 2008
Posts: 968
Location: Florida, USA

PostPosted: Sat Feb 20, 2010 9:38 pm    Post subject: Reply with quote

just make them not solid instead of disappearing and have them remove themselfs if they hit a door or player. thats what i did. worked great.
_________________
QuakeDB - Quake ModDB Group
Back to top
View user's profile Send private message Yahoo Messenger
Junrall



Joined: 21 Sep 2009
Posts: 136
Location: North West Oregon, USA

PostPosted: Sun Feb 21, 2010 1:52 am    Post subject: Reply with quote

Supa wrote:
LaunchRicoSpike wrote:
newmis.nextthink = time + 6;

Is there a reason that the spike's .think function is called so late?... you should invoke the spike's velocity correction one frame after every touch by adding self.nextthink = time to your touch code.

Yep, I see what you mean. I'll fix that right away.

Supa wrote:
Code:

      if (other.health <= 0 && other != world)
         other.solid = SOLID_NOT;

You do understand that this will break things like shootable buttons that reset after each trigger, right?

Nope, didn't know that... I'll try to correct that and take ceriux's suggestion.

Thanks to you both... still have to tackle spike eating floor thing... lol, won't be satisfied till I do!
_________________
Good God! You shot my leg off!
Back to top
View user's profile Send private message
Junrall



Joined: 21 Sep 2009
Posts: 136
Location: North West Oregon, USA

PostPosted: Sun Feb 21, 2010 6:08 am    Post subject: Reply with quote

Ok... I figured it out. The problem was in the ReboVec function... I'm not saying that there is an error in ReboVec... maybe I'm using an older version that hadn't been updated yet? Here is where I got it:
http://forums.inside3d.com/viewtopic.php?t=1146
And here is the fix. Hopefully it doesn't cause problems elsewhere!
In ReboVec change
Code:

spot1 = org - (16*dir);
spot2 = org + (16*dir);


to this
Code:

spot1 = org - (16*olddir);
spot2 = org + (16*olddir);

I'm not sure why, but the above code now lets the spikes bounce off doors, lifts, and switches without any checks!

To be honest, I can't take credit for this. I found the fix in Orion's tutorial, Ricocheting Laser Cannon... which my code is based off... well, heavily so!
What a great tutorial for learning how to tie together vectors, velocity, origin, and angles.
Now that I have a functional ricocheting spike (and finished breaking Orion's code!) I can add my sticky spikes and bouncing spikes to it. And then I'm off to try this with the DP's extensions... hopefully I won't break anything there! Laughing
_________________
Good God! You shot my leg off!
Back to top
View user's profile Send private message
Lardarse



Joined: 05 Nov 2005
Posts: 243
Location: Bristol, UK

PostPosted: Sun Feb 21, 2010 6:17 am    Post subject: Reply with quote

Strange why that might be the issue...
_________________
<ekiM> Son, you're writing data structures your CPU can't cache.
Back to top
View user's profile Send private message
Wazat



Joined: 15 Oct 2004
Posts: 732
Location: Middle 'o the desert, USA

PostPosted: Mon Feb 22, 2010 1:39 am    Post subject: Reply with quote

At that point in the code the only thing that appears to be different between dir and olddir is olddir is normalized, while dir isn't [i]necessarily[/dir] normalized (it's left up to the function that calls ReboVec).

If the calling function is passing a non-normalized direction (i.e. self.velocity), that would probably do it. Dir might be so large that the traceline is starting very far away, behind another wall or inside a solid (i.e. the ceiling or a wall behind, or whatever is 16,000 units away). The fix given is appropriate, since ReboVel doesn't specify in the comment above it that dir should be normalized (other than the variable being named dir, and directions are typically understood to be normalized; not everyone knows that though). It might also be appropriate to move this line:

olddir = normalize(dir);

to above the if statement so olddir can be used instead of dir in the if statement's traceline too.


I'm just not sure why only the floor had the problem. O_o
_________________
When my computer inevitably explodes and kills me, my cat inherits everything I own. He may be the only one capable of continuing my work.
Back to top
View user's profile Send private message MSN Messenger
Junrall



Joined: 21 Sep 2009
Posts: 136
Location: North West Oregon, USA

PostPosted: Mon Feb 22, 2010 2:59 am    Post subject: Reply with quote

Wazat wrote:
...(it's left up to the function that calls ReboVec).

I went back and changed ReboVec back to the way it was and then passed a normalized dir to it (which I hadn't done before)... it worked like a charm! You are right... normalizing a direction is and was intended to be left up to the function that calls ReboVec.

Wazat wrote:
The fix given is appropriate, since ReboVel doesn't specify in the comment above it that dir should be normalized (other than the variable being named dir, and directions are typically understood to be normalized; not everyone knows that though)..

Right again... I WAS one of those people who didn't know. I still don't know what normalize means or what it does... please enlighten me. Smile

Wazat wrote:
It might also be appropriate to move this line:

olddir = normalize(dir);

to above the if statement so olddir can be used instead of dir in the if statement's traceline too.


I'm just not sure why only the floor had the problem. O_o


Just moved olddir = normalize(dir); to above the if statement... works as you said it would.

Lol, so, with the above changes does this mean that ReboVec is at version 2 now! Just kidding!
_________________
Good God! You shot my leg off!
Back to top
View user's profile Send private message
Dr. Shadowborg
Inside3D Staff


Joined: 16 Oct 2004
Posts: 726

PostPosted: Mon Feb 22, 2010 3:13 am    Post subject: Reply with quote

Junrall wrote:

Just moved olddir = normalize(dir); to above the if statement... works as you said it would.

Lol, so, with the above changes does this mean that ReboVec is at version 2 now! Just kidding!


I can't remember the full details regarding that stuff (other than the fact that I'm pretty sure I had a reason for it), but I DO remember that I made that function to do double duty so that you could get just the trace_plane_normal of a surface (I believe this was useful for mines that attached to walls), or if justnorm was set to FALSE the proper ricochet angle. (for flak, and whatnot)

ReboVec hasn't actually changed at all since that was released, so I dunno. (it seems to work properly in Hellsmash, as you will see if you get a ring of power, turn it on and use the machine gun...)

Anyhow, glad you got it working!
_________________
"Roboto suggests Plasma Bazooka."
Back to top
View user's profile Send private message
Lardarse



Joined: 05 Nov 2005
Posts: 243
Location: Bristol, UK

PostPosted: Mon Feb 22, 2010 6:27 am    Post subject: Reply with quote

Normalizing a vector scales it so that its length is 1. This is a technique that's often used to obtain just the direction of the vector, without its length.
_________________
<ekiM> Son, you're writing data structures your CPU can't cache.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Inside3d Forums Forum Index -> QuakeC Programming All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2004 phpBB Group