Skip to content

Commit

Permalink
Refactor|libhexen: Pass mobj-on-top-mobj arguments via Mobj_BoxIterator
Browse files Browse the repository at this point in the history
  • Loading branch information
danij-deng committed Oct 26, 2013
1 parent 7905415 commit 6abbc42
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 77 deletions.
70 changes: 46 additions & 24 deletions doomsday/plugins/common/src/p_map.cpp
Expand Up @@ -102,10 +102,6 @@ static float topSlope, bottomSlope;
static coord_t startPos[3]; // start position for trajectory line checks
static coord_t endPos[3]; // end position for trajectory checks

#if __JHEXEN__
static mobj_t *onMobj; // generic global onMobj...used for landing on pods/players
#endif

#if !__JHEXEN__
static int tmUnstuck; // $unstuck: used to check unsticking
#endif
Expand Down Expand Up @@ -2755,38 +2751,60 @@ void P_ThrustSpike(mobj_t *mobj)
Mobj_BoxIterator(&box, PIT_ThrustStompThing, mobj);
}

int PIT_CheckOnmobjZ(mobj_t* thing, void * /*context*/)
struct pit_checkonmobjz_params_t
{
if(!(thing->flags & (MF_SOLID | MF_SPECIAL | MF_SHOOTABLE)))
mobj_t *riderMobj;
mobj_t *mountMobj;
};

/// @return @c false= Continue iteration.
static int PIT_CheckOnMobjZ(mobj_t *cand, void *context)
{
pit_checkonmobjz_params_t &parm = *static_cast<pit_checkonmobjz_params_t *>(context);

if(!(cand->flags & (MF_SOLID | MF_SPECIAL | MF_SHOOTABLE)))
{
return false; // Can't hit thing.
}

coord_t blockdist = thing->radius + tmThing->radius;
if(fabs(thing->origin[VX] - tm[VX]) >= blockdist ||
fabs(thing->origin[VY] - tm[VY]) >= blockdist)
coord_t blockdist = cand->radius + parm.riderMobj->radius;
if(fabs(cand->origin[VX] - tm[VX]) >= blockdist ||
fabs(cand->origin[VY] - tm[VY]) >= blockdist)
{
return false; // Didn't hit thing.
}

if(thing == tmThing)
return false; // Don't clip against self.
// Don't clip against self.
if(cand == parm.riderMobj) return false;

if(tmThing->origin[VZ] > thing->origin[VZ] + thing->height)
// Above or below?
if(parm.riderMobj->origin[VZ] > cand->origin[VZ] + cand->height)
{
return false;
}
else if(parm.riderMobj->origin[VZ] + parm.riderMobj->height < cand->origin[VZ])
{
return false;
else if(tmThing->origin[VZ] + tmThing->height < thing->origin[VZ])
return false; // Under thing.
}

if(IS_CLIENT)
{
// Players cannot hit their clmobjs.
if(tmThing->player)
// Players must not ride their clmobjs.
if(parm.riderMobj->player)
{
if(thing == ClPlayer_ClMobj(tmThing->player - players))
if(cand == ClPlayer_ClMobj(parm.riderMobj->player - players))
{
return false;
}
}
}

if(thing->flags & MF_SOLID)
onMobj = thing;
if(cand->flags & MF_SOLID)
{
parm.mountMobj = cand;
}

return (thing->flags & MF_SOLID) != 0;
return (cand->flags & MF_SOLID) != 0;
}

mobj_t *P_CheckOnMobj(mobj_t *mo)
Expand Down Expand Up @@ -2831,15 +2849,19 @@ mobj_t *P_CheckOnMobj(mobj_t *mo)
AABoxd tmBoxExpanded(tmBox.minX - MAXRADIUS, tmBox.minY - MAXRADIUS,
tmBox.maxX + MAXRADIUS, tmBox.maxY + MAXRADIUS);

pit_checkonmobjz_params_t parm;
parm.riderMobj = tmThing;
parm.mountMobj = 0;

VALIDCOUNT++;
if(Mobj_BoxIterator(&tmBoxExpanded, PIT_CheckOnmobjZ, 0))
if(Mobj_BoxIterator(&tmBoxExpanded, PIT_CheckOnMobjZ, &parm))
{
*tmThing = oldMo;
return onMobj;
*tmThing = oldMo; /// @todo Necessary? -ds
return parm.mountMobj;
}
}

*tmThing = oldMo;
*tmThing = oldMo; /// @todo Necessary? -ds
return 0;
}

Expand Down
111 changes: 58 additions & 53 deletions doomsday/plugins/common/src/p_start.cpp
Expand Up @@ -1061,35 +1061,37 @@ void G_DeathMatchSpawnPlayer(int playerNum)

#if defined(__JHERETIC__) || defined(__JHEXEN__)

typedef struct {
coord_t pos[2], minDist;
} unstuckmobjinlineparams_t;
struct unstuckmobjinline_params_t
{
coord_t pos[2];
coord_t minDist;
};

int unstuckMobjInLine(Line *li, void *context)
/// @return @c false= continue iteration.
static int unstuckMobjInLine(Line *li, void *context)
{
unstuckmobjinlineparams_t *params = (unstuckmobjinlineparams_t*) context;
unstuckmobjinline_params_t &parm = *static_cast<unstuckmobjinline_params_t *>(context);

if(!P_GetPtrp(li, DMU_BACK_SECTOR))
{
/*
* Project the point (mo position) onto this line. If the
* resultant point lies on the line and the current position is
* in range of that point, adjust the position moving it away from
* the projected point.
* Project the point (mo position) onto this line. If the resultant point
* lies on the line and the current position is in range of that point,
* adjust the position moving it away from the projected point.
*/

coord_t lineOrigin[2]; P_GetDoublepv(P_GetPtrp(li, DMU_VERTEX0), DMU_XY, lineOrigin);
coord_t lineDirection[2]; P_GetDoublepv(li, DMU_DXY, lineDirection);

coord_t result[2];
coord_t pos = V2d_ProjectOnLine(result, params->pos, lineOrigin, lineDirection);
coord_t pos = V2d_ProjectOnLine(result, parm.pos, lineOrigin, lineDirection);

if(pos > 0 && pos < 1)
{
coord_t dist = M_ApproxDistance(params->pos[VX] - result[VX],
params->pos[VY] - result[VY]);
coord_t dist = M_ApproxDistance(parm.pos[VX] - result[VX],
parm.pos[VY] - result[VY]);

if(dist >= 0 && dist < params->minDist)
if(dist >= 0 && dist < parm.minDist)
{
// Derive the line normal.
coord_t len = M_ApproxDistance(lineDirection[0], lineDirection[1]);
Expand All @@ -1107,60 +1109,67 @@ int unstuckMobjInLine(Line *li, void *context)
normal[VY] = -unit[VX];

// Adjust the position.
params->pos[VX] += normal[VX] * params->minDist;
params->pos[VY] += normal[VY] * params->minDist;
parm.pos[VX] += normal[VX] * parm.minDist;
parm.pos[VY] += normal[VY] * parm.minDist;
}
}
}

return false; // Continue iteration.
}

typedef struct {
struct pit_findnearestfacingline_params_t
{
mobj_t *mo;
coord_t dist;
Line *line;
} nearestfacinglineparams_t;
};

/// @return @c false= continue iteration.
static int PIT_FindNearestFacingLine(Line *line, void *context)
{
nearestfacinglineparams_t *params = (nearestfacinglineparams_t*) context;
pit_findnearestfacingline_params_t &parm = *static_cast<pit_findnearestfacingline_params_t *>(context);

coord_t off;
coord_t dist = Line_PointDistance(line, params->mo->origin, &off);
coord_t dist = Line_PointDistance(line, parm.mo->origin, &off);

// Wrong way or too far?
if(off < 0 || off > P_GetDoublep(line, DMU_LENGTH) || dist < 0)
return false; // Wrong way or too far.
{
return false;
}

if(!params->line || dist < params->dist)
if(!parm.line || dist < parm.dist)
{
params->line = line;
params->dist = dist;
parm.line = line;
parm.dist = dist;
}

return false; // Continue.
return false;
}

/// @return @c false= continue iteration.
static int turnMobjToNearestLine(thinker_t *th, void *context)
{
mobj_t *mo = (mobj_t *) th;
mobjtype_t type = *((mobjtype_t *) context);
mobj_t *mo = reinterpret_cast<mobj_t *>(th);
mobjtype_t type = *static_cast<mobjtype_t *>(context);

if(mo->type != type)
return false; // Continue iteration.
// @todo Why not type-prune at an earlier point? We could specify a
// custom comparison func for Thinker_Iterate...
if(mo->type != type) return false;

#ifdef _DEBUG
VERBOSE( Con_Message("Checking mo %i...", mo->thinker.id) );
#endif

nearestfacinglineparams_t parm;
AABoxd aaBox(mo->origin[VX] - 50, mo->origin[VY] - 50,
mo->origin[VX] + 50, mo->origin[VY] + 50);

pit_findnearestfacingline_params_t parm;
parm.mo = mo;
parm.dist = 0;
parm.line = 0;

AABoxd aaBox(mo->origin[VX] - 50, mo->origin[VY] - 50,
mo->origin[VX] + 50, mo->origin[VY] + 50);

VALIDCOUNT++;
Line_BoxIterator(&aaBox, LIF_SECTOR, PIT_FindNearestFacingLine, &parm);

Expand All @@ -1178,43 +1187,39 @@ static int turnMobjToNearestLine(thinker_t *th, void *context)
#endif
}

return false; // Continue iteration.
return false;
}

static int moveMobjOutOfNearbyLines(thinker_t *th, void *paramaters)
/// @return @c false= continue iteration.
static int moveMobjOutOfNearbyLines(thinker_t *th, void *context)
{
mobj_t *mo = (mobj_t *) th;
mobjtype_t type = *((mobjtype_t *)paramaters);
mobj_t *mo = reinterpret_cast<mobj_t *>(th);
mobjtype_t type = *static_cast<mobjtype_t *>(context);

// @todo Why not type-prune at an earlier point? We could specify a
// custom comparison func for Thinker_Iterate...
if(mo->type != type)
return false; // Continue iteration.
if(mo->type != type) return false;

AABoxd aaBox;
aaBox.minX = mo->origin[VX] - mo->radius;
aaBox.minY = mo->origin[VY] - mo->radius;
aaBox.maxX = mo->origin[VX] + mo->radius;
aaBox.maxY = mo->origin[VY] + mo->radius;
AABoxd aaBox(mo->origin[VX] - mo->radius, mo->origin[VY] - mo->radius,
mo->origin[VX] + mo->radius, mo->origin[VY] + mo->radius);

unstuckmobjinlineparams_t params;
params.pos[VX] = mo->origin[VX];
params.pos[VY] = mo->origin[VY];
params.minDist = mo->radius / 2;
unstuckmobjinline_params_t parm;
parm.pos[VX] = mo->origin[VX];
parm.pos[VY] = mo->origin[VY];
parm.minDist = mo->radius / 2;

VALIDCOUNT++;
Line_BoxIterator(&aaBox, LIF_SECTOR, unstuckMobjInLine, &parm);

Line_BoxIterator(&aaBox, LIF_SECTOR, unstuckMobjInLine, &params);

if(!FEQUAL(mo->origin[VX], params.pos[VX]) || !FEQUAL(mo->origin[VY], params.pos[VY]))
if(!FEQUAL(mo->origin[VX], parm.pos[VX]) || !FEQUAL(mo->origin[VY], parm.pos[VY]))
{
P_MobjUnlink(mo);
mo->origin[VX] = params.pos[VX];
mo->origin[VY] = params.pos[VY];
mo->origin[VX] = parm.pos[VX];
mo->origin[VY] = parm.pos[VY];
P_MobjLink(mo);
}

return false; // Continue iteration.
return false;
}

void P_MoveThingsOutOfWalls()
Expand Down

0 comments on commit 6abbc42

Please sign in to comment.