Inside3D!
     

Nukes!
Goto page 1, 2  Next
 
Post new topic   Reply to topic    Inside3d Forums Forum Index -> QuakeC Programming
View previous topic :: View next topic  
Author Message
redrum



Joined: 28 Mar 2007
Posts: 367
Location: Long Island, New York

PostPosted: Sat Dec 01, 2007 3:11 pm    Post subject: Nukes! Reply with quote

Guys, I'm attempting to make a nuke launcher.
Basically you use the rocket launcher, when you have 12 or more rockets you can launch a "nuke".
I created W_FireNuke based on W_FireRocket and I made T_NukeTouch based on T_MissileTouch. I just changed the amount of damage.
In testing I got this error on the server:

IFNOT 12708(???) branch 2
client.qc : Frag
client.qc : ClientObituary
combat.qc : Killed
combat.qc : T_Damage
combat.qc : T_RadiusDamage
weapons.qc : T_NukeTouch
<NO FUNCTION>
runaway loop error
SV_Error: Program error


any help???
_________________
Welcome to the Overlook Hotel 69.113.123.178:27500
Back to top
View user's profile Send private message Send e-mail
redrum



Joined: 28 Mar 2007
Posts: 367
Location: Long Island, New York

PostPosted: Sat Dec 01, 2007 4:57 pm    Post subject: Reply with quote

Code:
void() T_NukeTouch =
{
   if (self.voided) {
      return;
   }
   self.voided = 1;
     
        T_RadiusDamage (self, self.owner, 800, world, "rocket");
        T_RadiusDamage (self, self.owner, 800, world, "rocket");
        T_RadiusDamage (self, self.owner, 800, world, "rocket");
        T_RadiusDamage (self, self.owner, 800, world, "rocket");
        T_RadiusDamage (self, self.owner, 800, world, "rocket");
        T_RadiusDamage (self, self.owner, 800, world, "rocket");
        T_RadiusDamage (self, self.owner, 800, world, "rocket");
        T_RadiusDamage (self, self.owner, 800, world, "rocket");
        T_RadiusDamage (self, self.owner, 800, world, "rocket");
        T_RadiusDamage (self, self.owner, 800, world, "rocket");
        T_RadiusDamage (self, self.owner, 800, world, "rocket");

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

   remove (self);
};



Code:
void() W_FireNuke =

{
   if (deathmatch != 4)
      self.currentammo = self.ammo_rockets = self.ammo_rockets - 12;
   
   sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);

        traceline (self.origin, self.origin + v_forward*40, FALSE, self);
        if (trace_fraction == 1)
        {
        makevectors (self.angles);
        self.velocity = self.velocity - v_forward * 2000;                                                 
        }
       
   msg_entity = self;
   WriteByte (MSG_ONE, SVC_BIGKICK);
       
   newmis = spawn ();
   newmis.owner = self;
   newmis.movetype = MOVETYPE_FLYMISSILE;
   newmis.solid = SOLID_BBOX;
   
// set newmis speed

   makevectors (self.v_angle);
   newmis.velocity = aim(self, 1000);
   newmis.velocity = newmis.velocity * 40;                                       
   newmis.angles = vectoangles(newmis.velocity);

   newmis.touch = T_NukeTouch;
   newmis.voided = 0;
       
   
// set newmis duration
   
        newmis.nextthink = time + 0.01;                                     
        newmis.think = RocketSpeedChange;                                   
   newmis.classname = "rocket";

   setmodel (newmis, "progs/missile.mdl");
   setsize (newmis, '8 8 8', '8 8 8');                                       
   setorigin (newmis, self.origin + v_forward*8 + '0 0 16');
};


Here are my 2 functions, any suggestions?
_________________
Welcome to the Overlook Hotel 69.113.123.178:27500
Back to top
View user's profile Send private message Send e-mail
Orion



Joined: 12 Jan 2007
Posts: 414
Location: Brazil

PostPosted: Sat Dec 01, 2007 5:07 pm    Post subject: Reply with quote

Why that bunch of radius damages?!?!?
Use only one.
_________________
There's no signature here. Stop looking for one.
Back to top
View user's profile Send private message
redrum



Joined: 28 Mar 2007
Posts: 367
Location: Long Island, New York

PostPosted: Sat Dec 01, 2007 5:12 pm    Post subject: Reply with quote

It didn't work right, only one entity would explode from a nuke?
_________________
Welcome to the Overlook Hotel 69.113.123.178:27500
Back to top
View user's profile Send private message Send e-mail
daemon



Joined: 07 Nov 2007
Posts: 62

PostPosted: Sat Dec 01, 2007 5:21 pm    Post subject: Reply with quote

Yea, my guess is that is has something to do with all those T_RadiusDamage()s being called at the same time. T_RadiusDamage has a findradius inside of it, which is a kind of loop, and running that many at the same time would probably cause that kind of error. But that's just my guess.
_________________
-daemon [ daemonforge.org ]
Back to top
View user's profile Send private message Visit poster's website
redrum



Joined: 28 Mar 2007
Posts: 367
Location: Long Island, New York

PostPosted: Sat Dec 01, 2007 11:46 pm    Post subject: Reply with quote

I get this error on the server, it repeats itself numerous times then it will stop. Then it starts again. When this is happening and I fire the nuke is when it crashes.

WARNING: ED_Alloc: no free edicts

What does this mean???
_________________
Welcome to the Overlook Hotel 69.113.123.178:27500
Back to top
View user's profile Send private message Send e-mail
Sajt



Joined: 16 Oct 2004
Posts: 1026

PostPosted: Sun Dec 02, 2007 12:54 am    Post subject: Reply with quote

Set the fourth argument to T_RadiusDamage to 'self' instead of 'world'?
_________________
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.
Back to top
View user's profile Send private message
redrum



Joined: 28 Mar 2007
Posts: 367
Location: Long Island, New York

PostPosted: Sun Dec 02, 2007 1:28 am    Post subject: Reply with quote

Sajt, can you explain that whole line of code for me so I can understand the whole thing please? Thanks.
_________________
Welcome to the Overlook Hotel 69.113.123.178:27500
Back to top
View user's profile Send private message Send e-mail
Electro



Joined: 29 Dec 2004
Posts: 241
Location: Brisbane, Australia

PostPosted: Mon Dec 03, 2007 6:25 am    Post subject: Reply with quote

Code:
T_RadiusDamage (self, self.owner, 800, world, "rocket");
        T_RadiusDamage (self, self.owner, 800, world, "rocket");
        T_RadiusDamage (self, self.owner, 800, world, "rocket");
        T_RadiusDamage (self, self.owner, 800, world, "rocket");
        T_RadiusDamage (self, self.owner, 800, world, "rocket");
        T_RadiusDamage (self, self.owner, 800, world, "rocket");
        T_RadiusDamage (self, self.owner, 800, world, "rocket");
        T_RadiusDamage (self, self.owner, 800, world, "rocket");
        T_RadiusDamage (self, self.owner, 800, world, "rocket");
        T_RadiusDamage (self, self.owner, 800, world, "rocket");
        T_RadiusDamage (self, self.owner, 800, world, "rocket");


is the same as

Code:
T_RadiusDamage (self, self.owner, 8800, world, "rocket"); // 8800 = 800 * 11



I think something you'd rather want, is an entity that gets spawned that does thinks every 0.02 seconds or something that does a T_RingDamage or something... and into that you'd put something like a min/max range for it to take effect, then each time move the ring out more and weaken the damage etc.
Anyway, that single line of code does the same as using a slab of T_RadiusDamage calls.
_________________
Unit reporting!
http://www.bendarling.net/
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
Sajt



Joined: 16 Oct 2004
Posts: 1026

PostPosted: Mon Dec 03, 2007 8:19 am    Post subject: Reply with quote

Nevermind what I said, it probably won't change anything.

The fourth parameter to T_RadiusDamage is 'ignore', which you generally set to the thing that is exploding, but it only really matters if said thing has takedamage and a few other things set (IIRC).
_________________
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.
Back to top
View user's profile Send private message
r00k



Joined: 13 Nov 2004
Posts: 483

PostPosted: Mon Dec 03, 2007 8:56 am    Post subject: Reply with quote

I think your original crash
Quote:

IFNOT 12708(???) branch 2
client.qc : Frag


was based on the bug in your frag() code ?
Back to top
View user's profile Send private message
FrikaC
Site Admin


Joined: 08 Oct 2004
Posts: 947

PostPosted: Mon Dec 03, 2007 2:45 pm    Post subject: Reply with quote

Electro wrote:

is the same as

Code:
T_RadiusDamage (self, self.owner, 8800, world, "rocket"); // 8800 = 800 * 11


I think something you'd rather want, is an entity that gets spawned that does thinks every 0.02 seconds or something that does a T_RingDamage or something... and into that you'd put something like a min/max range for it to take effect, then each time move the ring out more and weaken the damage etc.
Anyway, that single line of code does the same as using a slab of T_RadiusDamage calls.


Not quite. The radius in T_RadiusDamage is based on the damage amount, so repeat calls will therefore keep the radius low and accumulate a whole bunch of damage. A better option to have the same behavior, if indeed that's what is desired, would be to create a new version of T_RadiusDamage that takes damage and radius parameters.
Back to top
View user's profile Send private message Send e-mail
Orion



Joined: 12 Jan 2007
Posts: 414
Location: Brazil

PostPosted: Mon Dec 03, 2007 2:53 pm    Post subject: Reply with quote

Yeah, that's right.
T_RadiusDamage() already does damage to various entities at the same time, and 8800 is, more or less, an infinite radius in Quake.

Try this instead, it will have 800 radius (or whatever you want) and 8000 damage (or whatever too).

Copy and paste this code at combat.qc just after T_RadiusDamage():

Code:

void(entity inflictor, entity attacker, float damage, float radius, entity ignore, string dtype) NewRadiusDamage =
{
   local   float    points;
   local   entity   head;
   local   vector   org, v;

   head = findradius(inflictor.origin, radius);
   
   while (head)
   {
      if (head != ignore)
      {
         if (head.takedamage)
         {
            org = head.origin + (head.mins + head.maxs)*0.5;
            points = 0.5*vlen (inflictor.origin - org);
            if (points < 0)
               points = 0;
            points = damage - points;
            if (head == attacker)
               points = points * 0.5;
            if (points > 0)
            {
               if (CanDamage (head, inflictor))
               {   
                  head.deathtype = dtype;
                  // shambler takes half damage from all explosions
                  if (head.classname == "monster_shambler")                  
                     T_Damage (head, inflictor, attacker, points*0.5);
                  else
                     T_Damage (head, inflictor, attacker, points);
               }
            }
         }
      }
      head = head.chain;
   }
};



Then, at your nuke touch function use this instead:

Code:

NewRadiusDamage (self, self.owner, 8000, 800, world, "rocket");


That should work.
_________________
There's no signature here. Stop looking for one.
Back to top
View user's profile Send private message
redrum



Joined: 28 Mar 2007
Posts: 367
Location: Long Island, New York

PostPosted: Mon Dec 03, 2007 3:31 pm    Post subject: Reply with quote

WOW!!!
You guys are blowing my mind!
Thanks for all the feedback Smile

Can someone explain the T_RadiusDamage code to me with all the arguments and what they do?
_________________
Welcome to the Overlook Hotel 69.113.123.178:27500
Back to top
View user's profile Send private message Send e-mail
daemon



Joined: 07 Nov 2007
Posts: 62

PostPosted: Tue Dec 04, 2007 5:37 am    Post subject: Reply with quote

Code:
void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDamage =
{
   local   float    points;
   local   entity   head;
   local   vector   org;


   head = findradius(inflictor.origin, damage+40); //makes head equal to the first entity in a radius based upon damage + 40 quake units around the origin of the thing inflicting the damage, and temporarily assigns a .chain on all entities within that radius. .chain being the next entity inside the radius.
   
   while (head) // loop inside the following brackets until head equals world. (head will eventually equal world because the last entity inside the radius will have a .chain pointing to world)

   {
      if (head != ignore) // if head is not the entity set to be ignored, then do the following code inside the brackets.

      {
         if (head.takedamage) // if head is flagged to be able to take damage do the following code.

         {
            org = head.origin + (head.mins + head.maxs)*0.5; // sets org to a position at or slightly above head's origin depending on the head's bbox paramaters.

            points = 0.5*vlen (inflictor.origin - org); // sets points to a value equal to half of the distance from the inflictor's origin to org at impact.

            if (points < 0)
               points = 0; // if points are negative, set to 0.

            points = damage - points; // since points previoulsy represented distance from impact, subtract points from damage to get the minimized damage.

            if (head == attacker)
               points = points * 0.5; // if the attacker ends up damaging themself, half the damage to them

            if (points > 0) // if there are any points left after subtracting from damage, then do the code in the following brackets.

            {
               if (CanDamage (head, inflictor)) // if there are no walls in between the inflictor and the head...

               {   // shambler takes half damage from all explosions
                  if (head.classname == "monster_shambler")                  
                     T_Damage (head, inflictor, attacker, points*0.5); // shamblers take half radius damage

                  else
                     T_Damage (head, inflictor, attacker, points); // everyone else takes full damage

               }
            }
         }
      }
      head = head.chain; // apply damage to the next entity in the radius.

   }
};

_________________
-daemon [ daemonforge.org ]


Last edited by daemon on Sat Dec 08, 2007 7:44 pm; edited 1 time in total
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    Inside3d Forums Forum Index -> QuakeC Programming All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
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