Inside3D!
     

The mysterious engine killing teleporter
Goto page Previous  1, 2
 
Post new topic   Reply to topic    Inside3d Forums Forum Index -> Engine Programming
View previous topic :: View next topic  
Author Message
metlslime



Joined: 05 Feb 2008
Posts: 177

PostPosted: Sat Mar 28, 2009 4:33 am    Post subject: Reply with quote

note, tyr-glquake does not break on White Room, so Tyrann must have more to his fix than the code snippet from above.
Back to top
View user's profile Send private message
MeTcHsteekle



Joined: 15 May 2008
Posts: 397
Location: its a secret

PostPosted: Sat Mar 28, 2009 12:56 pm    Post subject: Reply with quote

metlslime wrote:

So I guess the more robust method of FTE and DP is the way to go.


Damn, the tough way around eh?
_________________
bah
Back to top
View user's profile Send private message AIM Address
mh



Joined: 12 Jan 2008
Posts: 909

PostPosted: Thu Apr 08, 2010 7:56 pm    Post subject: Reply with quote

Here's the more robust version as it's currently coded in DirectQ. Any other engine's allocators are going to be different of course, and the C++ stuff won't be usable, but it should nonetheless be straightforward to port.
Code:
void SV_TouchLinks (edict_t *ent, areanode_t *node)
{
   link_t          *l, *next;
   edict_t          *touch;
   int          old_self, old_other, touched = 0, i;

   // Static due to recursive function
   static edict_t **list = NULL;

   if (!list)
   {
      // alloc first time (to keep it off the stack - 256K - ouch!)
      list = (edict_t **) Pool_Permanent->Alloc (MAX_EDICTS * sizeof (edict_t *));
   }

loc0:;
   // ensure
   touched = 0;

   // Build a list of touched edicts since linked list may change during touch
   for (l = node->trigger_edicts.next; l != &node->trigger_edicts; l = l->next)
   {
      touch = EDICT_FROM_AREA(l);

      if (touch == ent) continue;
      if (touch->free) continue;
      if (!touch->v.touch || touch->v.solid != SOLID_TRIGGER) continue;

      if (ent->v.absmin[0] > touch->v.absmax[0] || ent->v.absmin[1] > touch->v.absmax[1] || ent->v.absmin[2] > touch->v.absmax[2] ||
         ent->v.absmax[0] < touch->v.absmin[0] || ent->v.absmax[1] < touch->v.absmin[1] || ent->v.absmax[2] < touch->v.absmin[2])
         continue;

      list[touched++] = touch;

      if (touched == MAX_EDICTS)
      {
         Con_DPrintf ("SV_TouchLinks: ");
         Con_DPrintf ("too many touched trigger_edicts (max = %d)\n", MAX_EDICTS);
         break;
      }
   }

   // touch linked edicts
   for (i = 0; i < touched; ++i)
   {
      int ednum;

      touch = list[i];

      ednum = GetNumberForEdict(touch);

      old_self = SVProgs->GlobalStruct->self;
      old_other = SVProgs->GlobalStruct->other;

      SVProgs->GlobalStruct->self = EDICT_TO_PROG(touch);
      SVProgs->GlobalStruct->other = EDICT_TO_PROG(ent);
      SVProgs->GlobalStruct->time = SV_TIME;
      SVProgs->ExecuteProgram (touch->v.touch);

      SVProgs->GlobalStruct->self = old_self;
      SVProgs->GlobalStruct->other = old_other;
   }

   // recurse down both sides
   if (node->axis == -1)
      return;

   if (ent->v.absmax[node->axis] > node->dist)
   {
      // order reversed to reduce code
      if (ent->v.absmin[node->axis] < node->dist) SV_TouchLinks(ent, node->children[1]);
      node = node->children[0];
      goto loc0;
   }
   else
   {
      if (ent->v.absmin[node->axis] < node->dist)
      {
         node = node->children[1];
         goto loc0;
      }
   }
}

_________________
DirectQ Engine - New release 1.8.666a, 9th August 2010
MHQuake Blog (General)
Direct3D 8 Quake Engines
Back to top
View user's profile Send private message Visit poster's website
qbism



Joined: 04 Nov 2004
Posts: 82

PostPosted: Fri Apr 09, 2010 4:03 am    Post subject: Reply with quote

I cursed like a pirate simply trying to get to that teleport, but porting mh's code above to makaqu (plus Q_malloc)
Code:
void SV_TouchLinks ( edict_t *ent, areanode_t *node )
{
   link_t      *l, *next;
   edict_t      *touch;
   int         old_self, old_other, touched = 0, i;

   // Static due to recursive function
   static edict_t **list = NULL;

   if (!list)
   {
      // alloc first time (to keep it off the stack - 256K - ouch!)
      list = (edict_t **) Q_malloc (MAX_EDICTS * sizeof (edict_t *));
   }
loc0:;
   // ensure
   touched = 0;

   // Build a list of touched edicts since linked list may change during touch
   for (l = node->trigger_edicts.next; l != &node->trigger_edicts; l = l->next)
   {
      touch = EDICT_FROM_AREA(l);

      if (touch == ent) continue;
      if (touch->free) continue;
      if (!touch->v.touch || touch->v.solid != SOLID_TRIGGER) continue;

      if (ent->v.absmin[0] > touch->v.absmax[0] || ent->v.absmin[1] > touch->v.absmax[1] || ent->v.absmin[2] > touch->v.absmax[2] ||
         ent->v.absmax[0] < touch->v.absmin[0] || ent->v.absmax[1] < touch->v.absmin[1] || ent->v.absmax[2] < touch->v.absmin[2])
         continue;

      list[touched++] = touch;

      if (touched == MAX_EDICTS)
      {
         Con_DPrintf ("SV_TouchLinks: ");
         Con_DPrintf ("too many touched trigger_edicts (max = %d)\n", MAX_EDICTS);
         break;
      }
   }

   // touch linked edicts
   for (i = 0; i < touched; ++i)
   {
      int ednum;

      touch = list[i];

      ednum = NUM_FOR_EDICT(touch);

       old_self = pr_global_struct->self;
      old_other = pr_global_struct->other;

      pr_global_struct->self = EDICT_TO_PROG(touch);
      pr_global_struct->other = EDICT_TO_PROG(ent);
      pr_global_struct->time = sv.time;
      PR_ExecuteProgram (touch->v.touch);

      pr_global_struct->self = old_self;
      pr_global_struct->other = old_other;
   }

   // recurse down both sides
   if (node->axis == -1)
      return;

   if (ent->v.absmax[node->axis] > node->dist)
   {
      // order reversed to reduce code
      if (ent->v.absmin[node->axis] < node->dist) SV_TouchLinks(ent, node->children[1]);
      node = node->children[0];
      goto loc0;
   }
   else
   {
      if (ent->v.absmin[node->axis] < node->dist)
      {
         node = node->children[1];
         goto loc0;
      }
   }
}

NOTE- this is not tested except for this specific case, and it didn't seem to break standard teleports in a quick run-through.
_________________
http://qbism.com
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 -> Engine Programming All times are GMT
Goto page Previous  1, 2
Page 2 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