Forum

End Boss engine bug!

Discuss programming topics for the various GPL'd game engine sources.

Moderator: InsideQC Admins

End Boss engine bug!

Postby r00k » Sun Apr 03, 2011 6:14 am

Oh, I think i found a bug in the "teleport.mdl" spike ball from the end level.

Not only does it float around but it's supposed to spin while doing so.

Here's how it's defined in QuakeC
Code: Select all
/*QUAKED misc_teleporttrain (0 .5 .8) (-8 -8 -8) (8 8 8)
This is used for the final bos
*/
void() misc_teleporttrain =
{   
   if (!self.speed)
      self.speed = 100;
   if (!self.target)
      objerror ("func_train without a target");

   self.cnt = 1;
   self.solid = SOLID_NOT;
   self.movetype = MOVETYPE_PUSH;
   self.blocked = train_blocked;
   self.use = train_use;
   self.avelocity = '100 200 300';

   self.noise = ("misc/null.wav");
   precache_sound ("misc/null.wav");
   self.noise1 = ("misc/null.wav");
   precache_sound ("misc/null.wav");

   precache_model2 ("progs/teleport.mdl");
   setmodel (self, "progs/teleport.mdl");
   setsize (self, self.mins , self.maxs);
   setorigin (self, self.origin);

// start trains on the second frame, to make sure their targets have had
// a chance to spawn
   self.nextthink = self.ltime + 0.1;
   self.think = func_train_find;
};


Now, notice the avelocity, and the MOVETYPE_PUSH?

In the normal glQuake engine though, MOVETYPE_PUSH is handled in sv_physics.c in SV_PushMove, but in that function,
the avelocity is not applied to the entitiy.

Adding to the top of SV_PushMove will fix this...

Code: Select all
   if (pusher->v.solid == SOLID_NOT)
   {
      if (pusher->v.avelocity)
      {
         for (i=0 ; i<3 ; i++)
         {                        
             pusher->v.angles[0] = pusher->v.angles[0] + movetime * pusher->v.avelocity[0];   
             pusher->v.angles[1] = pusher->v.angles[1] + movetime * pusher->v.avelocity[1];   
             pusher->v.angles[2] = pusher->v.angles[2] + movetime * pusher->v.avelocity[2];   
         }
      }

      for (i=0 ; i<3 ; i++)
      {
         move[i] = pusher->v.velocity[i] * movetime;
         mins[i] = pusher->v.absmin[i] + move[i];
         maxs[i] = pusher->v.absmax[i] + move[i];
      }
   
      VectorAdd (pusher->v.origin, move, pusher->v.origin);
      pusher->v.ltime += movetime;
      SV_LinkEdict (pusher, false);
      return;
   }
r00k
 
Posts: 1110
Joined: Sat Nov 13, 2004 10:39 pm

Postby Spike » Sun Apr 03, 2011 11:08 am

small note

if (pusher->v.avelocity)

that line will always evaluate to true
Spike
 
Posts: 2892
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Postby mh » Sun Apr 03, 2011 1:18 pm

Code: Select all
if (pusher->v.avelocity[0] || pusher->v.avelocity[1] || pusher->v.avelocity[2])


:?:

Although in practice it doesn't really matter as if the avelocities are 0 pusher->v.angles will come out the same as it was before.

This code will also run for all SOLID_NOT entities. Not sure if that's the intention or if there's something else happening somewhere else that would make it not matter, but a comment to that effect would help.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby r00k » Sun Apr 03, 2011 9:59 pm

I was trying to water down the code to plain Quake standards.
I noticed when adding rotation support to bmodels that the spike entity skipped as it flew in the air, not fluid movement.
But here's what I have for physics pusher

Code: Select all
void SV_Physics_Pusher (edict_t *ent)
{
   float   thinktime;
   float   oldltime;
   float   movetime;

   oldltime = ent->v.ltime;
   
   thinktime = ent->v.nextthink;

   if (thinktime < ent->v.ltime + host_frametime)
   {
      movetime = thinktime - ent->v.ltime;
      if (movetime < 0)
         movetime = 0;
   }
   else
      movetime = host_frametime;

   if (movetime)
   {
      if (ent->v.avelocity[0] && ent->v.avelocity[1] && ent->v.avelocity[2])//R00k: hack to not pushRotate a spinning func_train (ei the floating spike ball on the END map)
         SV_PushMove (ent, movetime);   // advances ent->v.ltime if not blocked
      else         
      if (ent->v.avelocity[0] || ent->v.avelocity[1] || ent->v.avelocity[2])
         SV_PushRotate (ent, movetime);
      else
         SV_PushMove (ent, movetime);   // advances ent->v.ltime if not blocked
   }
      
   if (thinktime > oldltime && thinktime <= ent->v.ltime)
   {
      ent->v.nextthink = 0;
      pr_global_struct->time = sv.time;
      pr_global_struct->self = EDICT_TO_PROG(ent);
      pr_global_struct->other = EDICT_TO_PROG(sv.edicts);
      PR_ExecuteProgram (ent->v.think);
      if (ent->free)
         return;
   }
}


the top part of pushMove looks like this

Code: Select all
void SV_PushMove (edict_t *pusher, float movetime)
{
   int         i, e;
   edict_t      *check;
   vec3_t      mins, maxs, move;
   vec3_t      entorig, pushorig;
   int         num_moved;
   edict_t      **moved_edict; //johnfitz -- dynamically allocate
   vec3_t      *moved_from; //johnfitz -- dynamically allocate
   int         mark; //johnfitz
float      savesolid;

   switch ((int) pusher->v.solid)
   {
   // LordHavoc: valid pusher types
   case SOLID_BSP:
   case SOLID_BBOX:
   case SOLID_SLIDEBOX:
//   case SOLID_CORPSE: // LordHavoc: this would be weird...
      break;
   // LordHavoc: no collisions
   case SOLID_NOT:
   case SOLID_TRIGGER:
      VectorMA (pusher->v.origin, movetime, pusher->v.velocity, pusher->v.origin);
      if (pusher->v.avelocity)//R00k, turn it if it wants to...
         VectorMA (pusher->v.angles, movetime, pusher->v.avelocity, pusher->v.angles);
      pusher->v.ltime += movetime;
      SV_LinkEdict (pusher, false);
      return;
   default:
      Host_Error("SV_PushMove: unrecognized solid type %f\n", pusher->v.solid);
   }
   if (!pusher->v.velocity[0] && !pusher->v.velocity[1] && !pusher->v.velocity[2])
   {
      pusher->v.ltime += movetime;
      return;
   }


So I have isolated that condition to any solid_not|MOVETYPE_PUSH entity that has all three avelocity values set, ie spinning.

I fired up FitzQuake, Zquake, Proquake, etc and non spin the teleport model, but loading up Darkplaces, and it does as the quakeC intended. So this made me think something was left out in the original engine code.
r00k
 
Posts: 1110
Joined: Sat Nov 13, 2004 10:39 pm


Return to Engine Programming

Who is online

Users browsing this forum: No registered users and 1 guest