Index | FAQ | Search | Memberlist | Usergroups | Profile | Log in to check your private messages | Log in | Register

The Floor Is Eating My Spikes!

| 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 |

Posted: Sat Feb 20, 2010 8:10 am Post subject: The Floor Is Eating My Spikes! |

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 |

Teiman Joined: 03 Jun 2007 Posts: 309 |

Posted: Sat Feb 20, 2010 9:48 am Post subject: |

ricochet spikes are the fun (specially with proper ricochets wavs). the subject for the thread is also a win 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 |

Error Inside3D Staff Joined: 05 Nov 2004 Posts: 558 Location: VA, USA

Posted: Sat Feb 20, 2010 10:03 am Post subject: |

oh god, Darkplaces makes everything so much easier

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 |

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

Posted: Sat Feb 20, 2010 8:24 pm Post subject: |

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

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 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

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
_________________
Good God! You shot my leg off!

Back to top |

Supa Joined: 26 Oct 2004 Posts: 122 |

Posted: Sat Feb 20, 2010 9:15 pm Post subject: |

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 |

ceriux Joined: 06 Sep 2008 Posts: 969 Location: Florida, USA |

Posted: Sat Feb 20, 2010 9:38 pm Post subject: |

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 |

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

Posted: Sun Feb 21, 2010 1:52 am Post subject: |

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 |

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

Posted: Sun Feb 21, 2010 6:08 am Post subject: |

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!
_________________
Good God! You shot my leg off!

Back to top |

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

Posted: Sun Feb 21, 2010 6:17 am Post subject: |

Strange why that might be the issue... _________________ <ekiM> Son, you're writing data structures your CPU can't cache.

Back to top |

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

Posted: Mon Feb 22, 2010 1:39 am Post subject: |

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 |

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

Posted: Mon Feb 22, 2010 2:59 am Post subject: |

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.

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 |

Dr. Shadowborg Inside3D Staff Joined: 16 Oct 2004 Posts: 726 |

Posted: Mon Feb 22, 2010 3:13 am Post subject: |

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 |

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

Posted: Mon Feb 22, 2010 6:27 am Post subject: |

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 |

Display posts from previous:

| 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