Forum

Grenade help

Discuss programming in the QuakeC language.

Moderator: InsideQC Admins

Grenade help

Postby redrum » Wed Jun 16, 2010 2:46 pm

Hey guys, I've been away for awhile but still have my server up. I've been having this one problem that keeps crashing the server though. I have given the grenades health so that if it takes a hit it will explode as well as exploding when the timer expires. I think it's kinda cool. Anyway, I'll throw a bunch of grenades in the same area as a test. When the first one explodes it triggers all the rest to explode. Ther server doesn't crash. I'll do this test 10 times in a row trying to get the server to crash to no avail.
Then I'll come home one day and the server will be down.
I'm at work so I don't have the actual code right now, but what would be the correct way to achieve what I'm looking for?
I believe I added this to FireGrenade():
Code: Select all
newmis.takedamage = DAMAGE_AIM;
newmis.health = 50;
newmis.th_die = GrenadeExplode;
Welcome to the Overlook Hotel: The-Overlook-Hotel.game-server.cc
User avatar
redrum
 
Posts: 410
Joined: Wed Mar 28, 2007 11:35 pm
Location: Long Island, New York

Postby frag.machine » Wed Jun 16, 2010 5:17 pm

Hey redrum, nice to see ya back!

Why do you think is your mod the root cause of the server crashes ?
Try to put the server running the vanilla progs.dat for some time to check if the crash persists.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
User avatar
frag.machine
 
Posts: 2090
Joined: Sat Nov 25, 2006 1:49 pm

Postby Dr. Shadowborg » Wed Jun 16, 2010 6:42 pm

Couple of things that I thought of off the top of my head: (I've had to deal with stuff like this before with wallmines / dynamite)

When your grenade die function gets called, do something like:

self.takedamage = DAMAGE_NO;

This prevents grenades dying and setting other grenades off again causing overflow insanity.

Another thought is that you need to set a slight delay between grenades dying, thereby preventing massive amounts of explosion particles. (This can cause a crash too.)
User avatar
Dr. Shadowborg
InsideQC Staff
 
Posts: 1110
Joined: Sat Oct 16, 2004 3:34 pm

Postby redrum » Wed Jun 16, 2010 10:08 pm

Hmmmm.

Wouldn't self.takedamage = DAMAGE_NO; prevent the grenade from actually "dying"?

I've exploded about 12 grenades all at once and the server didn't crash, so the delay thing won't help.

This function is def the reason for the crashes b/c when I remove it the server never crashes.
Welcome to the Overlook Hotel: The-Overlook-Hotel.game-server.cc
User avatar
redrum
 
Posts: 410
Joined: Wed Mar 28, 2007 11:35 pm
Location: Long Island, New York

Postby redrum » Wed Jun 16, 2010 10:13 pm

Here's the actual portion of code from FireGrenade();
Code: Select all
   
        newmis.touch = GrenadeTouch;
        newmis.nextthink = time + (2 + r);                                       
        newmis.health = 50;                                                         
        newmis.takedamage = DAMAGE_AIM;
        newmis.th_die = GrenadeExplode;
        newmis.think = GrenadeExplode;


Maybe it's when the newmis.think and newmis.th_die happens at the exact same time???
Welcome to the Overlook Hotel: The-Overlook-Hotel.game-server.cc
User avatar
redrum
 
Posts: 410
Joined: Wed Mar 28, 2007 11:35 pm
Location: Long Island, New York

Postby Sajt » Wed Jun 16, 2010 11:41 pm

If you look at T_Damage/T_RadiusDamage in combat.qc, you'll see that they ignore targets with takedamage set to zero (DAMAGE_NO). When an entity "dies", T_Damage() calls Killed(), which is where th_die gets called. You'll notice that it sets takedamage to DAMAGE_NO before calling th_die.

But since the think function isn't going through that function, takedamage is not being set to DAMAGE_NO when the grenade explodes after its timer expires (but it is when it is "killed").

If the grenade is still damageable when it explodes, you get this fun result: it explodes, looking for nearby entities to damage. One of those "nearby" entities turns out to be the exploding grenade itself. (Normally it would ignore it because it shouldn't be damageable). It therefore damages that grenade (itself), which causes it to explode again, which causes it damage itself again, exploding again... forever (stack overflow/runaway loop).

So, if you were to set takedamage to DAMAGE_NO in GrenadeExplode *before* the call to T_RadiusDamage, everything would be good. (Note: this crash probably also wouldn't happen if the T_RadiusDamage call passed "self" as the "ignore" parameter, which for some reason it doesn't. You could do this, but to be safe you should also clear takedamage as I've described.)
F. A. Špork, an enlightened nobleman and a great patron of art, had a stately Baroque spa complex built on the banks of the River Labe.
Sajt
 
Posts: 1215
Joined: Sat Oct 16, 2004 3:39 am

Postby redrum » Thu Jun 17, 2010 2:35 am

Aha!

That makes total sense, wise man atop the mountain. Thanks.
Welcome to the Overlook Hotel: The-Overlook-Hotel.game-server.cc
User avatar
redrum
 
Posts: 410
Joined: Wed Mar 28, 2007 11:35 pm
Location: Long Island, New York

Postby redrum » Thu Jun 17, 2010 2:33 pm

It's working, so far so good!
Welcome to the Overlook Hotel: The-Overlook-Hotel.game-server.cc
User avatar
redrum
 
Posts: 410
Joined: Wed Mar 28, 2007 11:35 pm
Location: Long Island, New York

Postby redrum » Mon Jun 28, 2010 8:03 pm

OK, another issue.
I was playing around with the smoking grenade code that I found in another thread. I didn't quite care for that "old school" effect. I decided to create a smoke effect from scratch. So I decided to use the puff cloud effect when you use the the shotgun. Here what I tried first:
Code: Select all
void() GrenadeExplode =
{
   local vector dir; //added this

   if (self.voided)
      return;

   self.voided = 1;

  dir = aim (self, 100000); //added this
  FireBullets (256, dir, '0.25 0.25 0' ,0); //added this
   T_RadiusDamage (self, self.owner, 120, world, "grenade");

   WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
   WriteByte (MSG_MULTICAST, TE_EXPLOSION);
   WriteCoord (MSG_MULTICAST, self.origin_x);
   WriteCoord (MSG_MULTICAST, self.origin_y);
   WriteCoord (MSG_MULTICAST, self.origin_z);
   multicast (self.origin, MULTICAST_PHS);

  puff_count = puff_count + 1; //added this

   remove (self);
};


That didn't work, the puff was not appearing. I knew it was something to do with the origin, this part of the code.
Code: Select all
dir = aim (self, 100000); //added this

So I tinkered with it, I changed the self to self.owner and it worked! Doesn't make sense to me because wouldn't that be the player? The player owns the grenade right?
Annnnnyway, I didn't care anymore of why it worked as long as it was working. Then it started crashing the server. :(
Any helpful hints?
Welcome to the Overlook Hotel: The-Overlook-Hotel.game-server.cc
User avatar
redrum
 
Posts: 410
Joined: Wed Mar 28, 2007 11:35 pm
Location: Long Island, New York

Postby redrum » Wed Jun 30, 2010 11:49 pm

Anyone?
Welcome to the Overlook Hotel: The-Overlook-Hotel.game-server.cc
User avatar
redrum
 
Posts: 410
Joined: Wed Mar 28, 2007 11:35 pm
Location: Long Island, New York

Postby Sajt » Thu Jul 01, 2010 12:43 am

Why is the grenade shooting a shotgun blast when it explodes? D:
F. A. Špork, an enlightened nobleman and a great patron of art, had a stately Baroque spa complex built on the banks of the River Labe.
Sajt
 
Posts: 1215
Joined: Sat Oct 16, 2004 3:39 am

Postby redrum » Thu Jul 01, 2010 6:01 pm

for the smoke effect
Welcome to the Overlook Hotel: The-Overlook-Hotel.game-server.cc
User avatar
redrum
 
Posts: 410
Joined: Wed Mar 28, 2007 11:35 pm
Location: Long Island, New York

Postby Sajt » Thu Jul 01, 2010 10:29 pm

You have the grenade shooting bullets, too. In a pretty arbitrary direction, I might add. Remove the "dir = aim..." line and the FireBullets call. You can go in the shotgun code and find the the WriteByte/TE_GUNSHOT code and copy that over (and only that). But that will make a very poor smoke grenade, mind you. You don't have a lot of options for making a smoke grenade in software engines.

The only reasonable way to do smoke screens is big alpha-blended billboards, whose alpha ramps to zero when they come close to the screen (to avoid "popping" your head through a billboarded particle), and with some depth-buffer fudging to get soft intersections with geometry (I think I saw this recently on a thread here somewhere). Anyway it's pretty advanced stuff. There's a reason you don't see smoke grenades in old games.
F. A. Špork, an enlightened nobleman and a great patron of art, had a stately Baroque spa complex built on the banks of the River Labe.
Sajt
 
Posts: 1215
Joined: Sat Oct 16, 2004 3:39 am

Postby ceriux » Fri Jul 02, 2010 5:20 pm

the player would not be the owner of the smoke plume even if he is the owner of the grenade. the grenade is an entitie owned by the player and since the grenade is its own entitie it can own its own entities ( i think right? at least thats how i look at it. )
User avatar
ceriux
 
Posts: 2223
Joined: Sat Sep 06, 2008 3:30 pm
Location: Indiana, USA

Postby Spike » Fri Jul 02, 2010 5:28 pm

aim(foo,bar);

is basically makevectors(self.angles); return v_forward;
except that it doesn't actually change v_forward, and the pitch can be autocorrected vertically in order to try hitting something (bar is meant to be the projectile speed, for moving stuff).
Better to replace with randomized direction vectors instead.

But yeah, as Sajt said your code shoots bullets, its not just a graphical effect (either that or you broke the shotgun!).
Spike
 
Posts: 2892
Joined: Fri Nov 05, 2004 3:12 am
Location: UK


Return to QuakeC Programming

Who is online

Users browsing this forum: No registered users and 1 guest