diff --git a/src/lua_baselib.c b/src/lua_baselib.c index f51143556..d64f8abd2 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2202,6 +2202,19 @@ static int lib_pExplodeMissile(lua_State *L) return 0; } +static int lib_pMobjTouchingSectorSpecial(lua_State *L) +{ + mobj_t *mo = *((mobj_t**)luaL_checkudata(L, 1, META_MOBJ)); + INT32 section = (INT32)luaL_checkinteger(L, 2); + INT32 number = (INT32)luaL_checkinteger(L, 3); + //HUDSAFE + INLEVEL + if (!mo) + return LUA_ErrInvalid(L, "mobj_t"); + LUA_PushUserdata(L, P_MobjTouchingSectorSpecial(mo, section, number), META_SECTOR); + return 1; +} + static int lib_pPlayerTouchingSectorSpecial(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); @@ -2353,17 +2366,6 @@ static int lib_pFadeLight(lua_State *L) return 0; } -static int lib_pThingOnSpecial3DFloor(lua_State *L) -{ - mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); - NOHUD - INLEVEL - if (!mo) - return LUA_ErrInvalid(L, "mobj_t"); - LUA_PushUserdata(L, P_ThingOnSpecial3DFloor(mo), META_SECTOR); - return 1; -} - static int lib_pIsFlagAtBase(lua_State *L) { mobjtype_t flag = luaL_checkinteger(L, 1); @@ -4056,6 +4058,7 @@ static luaL_Reg lib[] = { {"P_SetMobjStateNF",lib_pSetMobjStateNF}, {"P_DoSuperTransformation",lib_pDoSuperTransformation}, {"P_ExplodeMissile",lib_pExplodeMissile}, + {"P_MobjTouchingSectorSpecial",lib_pMobjTouchingSectorSpecial}, {"P_PlayerTouchingSectorSpecial",lib_pPlayerTouchingSectorSpecial}, {"P_FindLowestFloorSurrounding",lib_pFindLowestFloorSurrounding}, {"P_FindHighestFloorSurrounding",lib_pFindHighestFloorSurrounding}, @@ -4068,7 +4071,6 @@ static luaL_Reg lib[] = { {"P_LinedefExecute",lib_pLinedefExecute}, {"P_SpawnLightningFlash",lib_pSpawnLightningFlash}, {"P_FadeLight",lib_pFadeLight}, - {"P_ThingOnSpecial3DFloor",lib_pThingOnSpecial3DFloor}, {"P_IsFlagAtBase",lib_pIsFlagAtBase}, {"P_SetupLevelSky",lib_pSetupLevelSky}, {"P_SetSkyboxMobj",lib_pSetSkyboxMobj}, diff --git a/src/p_mobj.c b/src/p_mobj.c index 2c6315271..d0af3112e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9611,13 +9611,9 @@ static boolean P_MobjRegularThink(mobj_t *mobj) break; case MT_BLUEFLAG: case MT_REDFLAG: - { - sector_t* sec2; - sec2 = P_ThingOnSpecial3DFloor(mobj); - if ((sec2 && GETSECSPECIAL(sec2->special, 4) == 2) || (GETSECSPECIAL(mobj->subsector->sector->special, 4) == 2)) + if (P_MobjTouchingSectorSpecial(mobj, 4, 2)) mobj->fuse = 1; // Return to base. break; - } case MT_SPINDUST: // Spindash dust mobj->momx = FixedMul(mobj->momx, (3*FRACUNIT)/4); // originally 50000 mobj->momy = FixedMul(mobj->momy, (3*FRACUNIT)/4); // same diff --git a/src/p_spec.c b/src/p_spec.c index 49ba3adaf..265cba2b5 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3926,6 +3926,99 @@ boolean P_IsMobjTouchingPolyobj(mobj_t *mo, polyobj_t *po, sector_t *polysec) } } +static sector_t *P_MobjTouching3DFloorSpecial(mobj_t *mo, sector_t *sector, INT32 section, INT32 number) +{ + ffloor_t *rover; + + for (rover = sector->ffloors; rover; rover = rover->next) + { + if (GETSECSPECIAL(rover->master->frontsector->special, section) != number) + continue; + + if (!(rover->flags & FF_EXISTS)) + continue; + + if (!P_IsMobjTouching3DFloor(mo, rover, sector)) + continue; + + // This FOF has the special we're looking for, but are we allowed to touch it? + if (sector == mo->subsector->sector + || (rover->master->frontsector->flags & SF_TRIGGERSPECIAL_TOUCH)) + return rover->master->frontsector; + } + + return NULL; +} + +static sector_t *P_MobjTouchingPolyobjSpecial(mobj_t *mo, INT32 section, INT32 number) +{ + polyobj_t *po; + sector_t *polysec; + boolean touching = false; + boolean inside = false; + + for (po = mo->subsector->polyList; po; po = (polyobj_t *)(po->link.next)) + { + if (po->flags & POF_NOSPECIALS) + continue; + + polysec = po->lines[0]->backsector; + + if (GETSECSPECIAL(polysec->special, section) != number) + continue; + + touching = (polysec->flags & SF_TRIGGERSPECIAL_TOUCH) && P_MobjTouchingPolyobj(po, mo); + inside = P_MobjInsidePolyobj(po, mo); + + if (!(inside || touching)) + continue; + + if (!P_IsMobjTouchingPolyobj(mo, po, polysec)) + continue; + + return polysec; + } + + return NULL; +} + +sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number) +{ + msecnode_t *node; + sector_t *result; + + result = P_MobjTouching3DFloorSpecial(mo, mo->subsector->sector, section, number); + if (result) + return result; + + result = P_MobjTouchingPolyobjSpecial(mo, section, number); + if (result) + return result; + + if (GETSECSPECIAL(mo->subsector->sector->special, section) == number) + return mo->subsector->sector; + + for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next) + { + if (node->m_sector == mo->subsector->sector) // Don't duplicate + continue; + + result = P_MobjTouching3DFloorSpecial(mo, node->m_sector, section, number); + if (result) + return result; + + //TODO: Check polyobjects in node->m_sector + + if (!(node->m_sector->flags & SF_TRIGGERSPECIAL_TOUCH)) + continue; + + if (GETSECSPECIAL(mo->subsector->sector->special, section) == number) + return node->m_sector; + } + + return NULL; +} + // // P_PlayerTouchingSectorSpecial // @@ -3939,63 +4032,10 @@ boolean P_IsMobjTouchingPolyobj(mobj_t *mo, polyobj_t *po, sector_t *polysec) // sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 number) { - msecnode_t *node; - ffloor_t *rover; - if (!player->mo) return NULL; - // Check default case first - if (GETSECSPECIAL(player->mo->subsector->sector->special, section) == number) - return player->mo->subsector->sector; - - // Hmm.. maybe there's a FOF that has it... - for (rover = player->mo->subsector->sector->ffloors; rover; rover = rover->next) - { - if (GETSECSPECIAL(rover->master->frontsector->special, section) != number) - continue; - - if (!(rover->flags & FF_EXISTS)) - continue; - - if (!P_IsMobjTouching3DFloor(player->mo, rover, player->mo->subsector->sector)) - continue; - - // This FOF has the special we're looking for! - return rover->master->frontsector; - } - - for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next) - { - if (GETSECSPECIAL(node->m_sector->special, section) == number) - { - // This sector has the special we're looking for, but - // are we allowed to touch it? - if (node->m_sector == player->mo->subsector->sector - || (node->m_sector->flags & SF_TRIGGERSPECIAL_TOUCH)) - return node->m_sector; - } - - // Hmm.. maybe there's a FOF that has it... - for (rover = node->m_sector->ffloors; rover; rover = rover->next) - { - if (GETSECSPECIAL(rover->master->frontsector->special, section) != number) - continue; - - if (!(rover->flags & FF_EXISTS)) - continue; - - if (!P_IsMobjTouching3DFloor(player->mo, rover, node->m_sector)) - continue; - - // This FOF has the special we're looking for, but are we allowed to touch it? - if (node->m_sector == player->mo->subsector->sector - || (rover->master->frontsector->flags & SF_TRIGGERSPECIAL_TOUCH)) - return rover->master->frontsector; - } - } - - return NULL; + return P_MobjTouchingSectorSpecial(player->mo, section, number); } static sector_t *P_Check3DFloorTriggers(player_t *player, sector_t *sector, line_t *sourceline) @@ -4874,35 +4914,6 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers } } -/** Checks if an object is standing on or is inside a special 3D floor. - * If so, the sector is returned. - * - * \param mo Object to check. - * \return Pointer to the sector with a special type, or NULL if no special 3D - * floors are being contacted. - * \sa P_PlayerOnSpecial3DFloor - */ -sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo) -{ - ffloor_t *rover; - - for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next) - { - if (!rover->master->frontsector->special) - continue; - - if (!(rover->flags & FF_EXISTS)) - continue; - - if (!P_IsMobjTouching3DFloor(mo, rover, mo->subsector->sector)) - continue; - - return rover->master->frontsector; - } - - return NULL; -} - #define TELEPORTED(mo) (mo->subsector->sector != originalsector) /** Checks if a player is standing on or is inside a 3D floor (e.g. water) and diff --git a/src/p_spec.h b/src/p_spec.h index 79cd4a6f4..2ff2cd64c 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -320,6 +320,7 @@ void P_SpawnSpecials(boolean fromnetsave); // every tic void P_UpdateSpecials(void); +sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number); sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 number); void P_PlayerInSpecialSector(player_t *player); void P_CheckPushableTrigger(mobj_t *mobj, sector_t *sec); @@ -922,6 +923,4 @@ void T_PlaneDisplace(planedisplace_t *pd); void P_CalcHeight(player_t *player); -sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo); - #endif