View previous topic :: View next topic |
Author |
Message |
metlslime
Joined: 05 Feb 2008 Posts: 177
|
Posted: Sat Mar 28, 2009 4:33 am Post subject: |
|
|
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 |
|
 |
MeTcHsteekle
Joined: 15 May 2008 Posts: 397 Location: its a secret
|
Posted: Sat Mar 28, 2009 12:56 pm Post subject: |
|
|
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 |
|
 |
mh

Joined: 12 Jan 2008 Posts: 910
|
Posted: Thu Apr 08, 2010 7:56 pm Post subject: |
|
|
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 |
|
 |
qbism

Joined: 04 Nov 2004 Posts: 82
|
Posted: Fri Apr 09, 2010 4:03 am Post subject: |
|
|
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 |
|
 |
|
|
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
|