The Floor Is Eating My Spikes!
Moderator: InsideQC Admins
13 posts
• Page 1 of 1
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?
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!
Also, they don't seem to like doors and switches and when they touch the sky they do not remove themselves. Any ideas?
- Code: Select all
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!
-

Junrall - Posts: 191
- Joined: Mon Sep 21, 2009 12:27 am
- Location: North West Oregon, USA
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?
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?
- Teiman
- Posts: 309
- Joined: Sun Jun 03, 2007 9:39 am
oh god, Darkplaces makes everything so much easier
- Code: Select all
//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.
-

Error - InsideQC Staff
- Posts: 865
- Joined: Fri Nov 05, 2004 5:15 am
- Location: VA, USA
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
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: Select all
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!
-

Junrall - Posts: 191
- Joined: Mon Sep 21, 2009 12:27 am
- Location: North West Oregon, USA
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: Select all
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?
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.
-

Supa - Posts: 164
- Joined: Tue Oct 26, 2004 8:10 am
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: Select all
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!
-

Junrall - Posts: 191
- Joined: Mon Sep 21, 2009 12:27 am
- Location: North West Oregon, USA
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
to this
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!
http://forums.inside3d.com/viewtopic.php?t=1146
And here is the fix. Hopefully it doesn't cause problems elsewhere!
In ReboVec change
- Code: Select all
spot1 = org - (16*dir);
spot2 = org + (16*dir);
to this
- Code: Select all
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!
-

Junrall - Posts: 191
- Joined: Mon Sep 21, 2009 12:27 am
- Location: North West Oregon, USA
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
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.
- Wazat
- Posts: 771
- Joined: Fri Oct 15, 2004 9:50 pm
- Location: Middle 'o the desert, USA
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!
-

Junrall - Posts: 191
- Joined: Mon Sep 21, 2009 12:27 am
- Location: North West Oregon, USA
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!
-

Dr. Shadowborg - InsideQC Staff
- Posts: 1110
- Joined: Sat Oct 16, 2004 3:34 pm
13 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 1 guest
