Skip to content

Commit

Permalink
Fixed|XG: Teleporting to a teleport destination mobj
Browse files Browse the repository at this point in the history
IssueID #1822
  • Loading branch information
skyjake committed Nov 26, 2019
1 parent 01f36df commit 8b60271
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 15 deletions.
5 changes: 5 additions & 0 deletions doomsday/apps/plugins/common/include/p_map.h
Expand Up @@ -41,6 +41,7 @@ DENG_EXTERN_C mobj_t *PuffSpawned;
#endif

#ifdef __cplusplus
#include <functional>
extern "C" {
#endif

Expand Down Expand Up @@ -192,6 +193,10 @@ coord_t P_GetGravity(void);
*/
dd_bool P_CheckSides(mobj_t *actor, coord_t x, coord_t y);

#ifdef __cplusplus
int P_IterateThinkers(thinkfunc_t func, const std::function<int(thinker_t *)> &);
#endif

#if __JHERETIC__ || __JHEXEN__
/**
* @param mo The mobj whoose position to test.
Expand Down
18 changes: 18 additions & 0 deletions doomsday/apps/plugins/common/src/world/p_map.cpp
Expand Up @@ -2867,6 +2867,24 @@ void P_HandleSectorHeightChange(int sectorIdx)
P_ChangeSector((Sector *)P_ToPtr(DMU_SECTOR, sectorIdx), false /*don't crush*/);
}

int P_IterateThinkers(thinkfunc_t func, const std::function<int(thinker_t *)> &callback)
{
// Helper to convert the std::function to a basic C function pointer for the API call.
struct IterContext
{
const std::function<int(thinker_t *)> *func;

static int callback(thinker_t *thinker, void *ptr)
{
auto *context = reinterpret_cast<IterContext *>(ptr);
return (*context->func)(thinker);
}
};

IterContext context{&callback};
return Thinker_Iterate(func, IterContext::callback, &context);
}

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

dd_bool P_TestMobjLocation(mobj_t *mo)
Expand Down
24 changes: 9 additions & 15 deletions doomsday/apps/plugins/common/src/world/p_xgsec.cpp
Expand Up @@ -2171,21 +2171,15 @@ int C_DECL XSTrav_Teleport(Sector* sector, dd_bool /*ceiling*/, void* /*context*
return false;
}

for(mo = (mobj_t *) P_GetPtrp(sector, DMT_MOBJS); mo; mo = mo->sNext)
{
thinker_t *th = (thinker_t*) mo;

// Not a mobj.
if(th->function != (thinkfunc_t) P_MobjThinker)
continue;

// Not a teleportman.
if(mo->type != MT_TELEPORTMAN)
continue;

ok = true;
break;
}
P_IterateThinkers(P_MobjThinker, [&mo, &ok, sector](thinker_t *th) {
mo = reinterpret_cast<mobj_t *>(th);
if (Mobj_Sector(mo) == sector && mo->type == MT_TELEPORTMAN)
{
ok = true;
return de::LoopAbort;
}
return de::LoopContinue;
});

if(ok)
{
Expand Down

0 comments on commit 8b60271

Please sign in to comment.