Index | FAQ | Search | Memberlist | Usergroups | Profile | Log in to check your private messages | Log in | Register

The mysterious engine killing teleporter Goto page Previous 1, 2

| Inside3d Forums Forum Index -> Engine Programming

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 |

Display posts from previous:

| 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