From ae02b2fcaf9758ba011288933650e7b20b17f978 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 16 Feb 2016 21:00:34 +0100 Subject: [PATCH] - added NextHighestCeiling/NextLowestFloorAt functions. Not tested yet! --- src/p_acs.cpp | 41 +++--------------- src/p_sectors.cpp | 108 ++++++++++++++++++++++++++++++++++++++++++++++ src/r_defs.h | 13 ++++++ 3 files changed, 127 insertions(+), 35 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 7155c98e6..9d2899d7e 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -4181,47 +4181,18 @@ bool DLevelScript::DoCheckActorTexture(int tid, AActor *activator, int string, b } int i, numff; FTextureID secpic; - sector_t *sec = actor->Sector; - numff = sec->e->XFloor.ffloors.Size(); + sector_t *resultsec; + F3DFloor *resffloor; if (floor) { - // Looking through planes from top to bottom - for (i = 0; i < numff; ++i) - { - F3DFloor *ff = sec->e->XFloor.ffloors[i]; - - if ((ff->flags & (FF_EXISTS | FF_SOLID)) == (FF_EXISTS | FF_SOLID) && - actor->Z() >= ff->top.plane->ZatPoint(actor)) - { // This floor is beneath our feet. - secpic = *ff->top.texture; - break; - } - } - if (i == numff) - { // Use sector's floor - secpic = sec->GetTexture(sector_t::floor); - } + actor->Sector->NextLowestFloorAt(actor, actor->Z(), &resultsec, &resffloor); + secpic = resffloor ? *resffloor->top.texture : resultsec->planes[sector_t::floor].Texture; } else { - fixed_t z = actor->Top(); - // Looking through planes from bottom to top - for (i = numff-1; i >= 0; --i) - { - F3DFloor *ff = sec->e->XFloor.ffloors[i]; - - if ((ff->flags & (FF_EXISTS | FF_SOLID)) == (FF_EXISTS | FF_SOLID) && - z <= ff->bottom.plane->ZatPoint(actor)) - { // This floor is above our eyes. - secpic = *ff->bottom.texture; - break; - } - } - if (i < 0) - { // Use sector's ceiling - secpic = sec->GetTexture(sector_t::ceiling); - } + actor->Sector->NextHighestCeilingAt(actor, actor->Top(), &resultsec, &resffloor); + secpic = resffloor ? *resffloor->bottom.texture : resultsec->planes[sector_t::ceiling].Texture; } return tex == TexMan[secpic]; } diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 1a4d218cf..51d007878 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -932,6 +932,74 @@ fixed_t sector_t::LowestFloorAt(fixed_t x, fixed_t y, sector_t **resultsec) } +fixed_t sector_t::NextHighestCeilingAt(fixed_t x, fixed_t y, fixed_t z, sector_t **resultsec, F3DFloor **resultffloor) +{ + sector_t *sec = this; + while (true) + { + // Looking through planes from bottom to top + for (int i = sec->e->XFloor.ffloors.Size() - 1; i >= 0; --i) + { + F3DFloor *ff = sec->e->XFloor.ffloors[i]; + + fixed_t ffz = ff->bottom.plane->ZatPoint(x, y); + if ((ff->flags & (FF_EXISTS | FF_SOLID)) == (FF_EXISTS | FF_SOLID) && z <= ffz) + { // This floor is above our eyes. + if (resultsec) *resultsec = sec; + if (resultffloor) *resultffloor = ff; + return ffz; + } + } + if (sec->PortalBlocksMovement(sector_t::ceiling)) + { // Use sector's floor + if (resultffloor) *resultffloor = NULL; + if (resultsec) *resultsec = sec; + return sec->ceilingplane.ZatPoint(x, y); + } + else + { + FDisplacement &disp = sec->CeilingDisplacement(); + x += disp.pos.x; + y += disp.pos.y; + } + } +} + +fixed_t sector_t::NextLowestFloorAt(fixed_t x, fixed_t y, fixed_t z, sector_t **resultsec, F3DFloor **resultffloor) +{ + sector_t *sec = this; + while (true) + { + // Looking through planes from top to bottom + unsigned numff = sec->e->XFloor.ffloors.Size(); + for (unsigned i = 0; i < numff; ++i) + { + F3DFloor *ff = sec->e->XFloor.ffloors[i]; + + fixed_t ffz = ff->top.plane->ZatPoint(x, y); + if ((ff->flags & (FF_EXISTS | FF_SOLID)) == (FF_EXISTS | FF_SOLID) && z >= ffz) + { // This floor is beneath our feet. + if (resultsec) *resultsec = sec; + if (resultffloor) *resultffloor = ff; + return ffz; + } + } + if (sec->PortalBlocksMovement(sector_t::floor)) + { // Use sector's floor + if (resultffloor) *resultffloor = NULL; + if (resultsec) *resultsec = sec; + return sec->floorplane.ZatPoint(x, y); + } + else + { + FDisplacement &disp = sec->FloorDisplacement(); + x += disp.pos.x; + y += disp.pos.y; + sec = P_PointInSector(x, y); + } + } +} + //=========================================================================== // // Calculates the height of a sector plane, respecting portal offsets @@ -1163,3 +1231,43 @@ int side_t::GetLightLevel (bool foggy, int baselight, bool is3dlight, int *pfake return baselight; } +#include "c_dispatch.h" +#include "d_player.h" + +CCMD(highestceiling) +{ + sector_t *sec; + fixed_t h = players[consoleplayer].mo->Sector->HighestCeilingAt(players[consoleplayer].mo, &sec); + Printf("Check at position %f,%f, height = %f, srcsector = %d dstsector = %d, srcgroup = %d, dstgroup = %d\n", + players[consoleplayer].mo->X() / 65536., players[consoleplayer].mo->Y() / 65536., h / 65536., + players[consoleplayer].mo->Sector->sectornum, sec->sectornum, players[consoleplayer].mo->Sector->PortalGroup, sec->PortalGroup); +} + +CCMD(lowestfloor) +{ + sector_t *sec; + fixed_t h = players[consoleplayer].mo->Sector->LowestFloorAt(players[consoleplayer].mo, &sec); + Printf("Check at position %f,%f, height = %f, srcsector = %d dstsector = %d, srcgroup = %d, dstgroup = %d\n", + players[consoleplayer].mo->X() / 65536., players[consoleplayer].mo->Y() / 65536., h / 65536., + players[consoleplayer].mo->Sector->sectornum, sec->sectornum, players[consoleplayer].mo->Sector->PortalGroup, sec->PortalGroup); +} + +CCMD(nexthighestceiling) +{ + sector_t *sec; + F3DFloor *ff; + fixed_t h = players[consoleplayer].mo->Sector->NextHighestCeilingAt(players[consoleplayer].mo, players[consoleplayer].mo->Top(), &sec, &ff); + Printf("Check at position %f,%f, height = %f, srcsector = %d dstsector = %d, srcgroup = %d, dstgroup = %d, 3dfloor = %d\n", + players[consoleplayer].mo->X() / 65536., players[consoleplayer].mo->Y() / 65536., h / 65536., + players[consoleplayer].mo->Sector->sectornum, sec->sectornum, players[consoleplayer].mo->Sector->PortalGroup, sec->PortalGroup, !!ff); +} + +CCMD(nextlowestfloor) +{ + sector_t *sec; + F3DFloor *ff; + fixed_t h = players[consoleplayer].mo->Sector->NextLowestFloorAt(players[consoleplayer].mo, players[consoleplayer].mo->Z(), &sec, &ff); + Printf("Check at position %f,%f, height = %f, srcsector = %d dstsector = %d, srcgroup = %d, dstgroup = %d, 3dfloor = %d\n", + players[consoleplayer].mo->X() / 65536., players[consoleplayer].mo->Y() / 65536., h / 65536., + players[consoleplayer].mo->Sector->sectornum, sec->sectornum, players[consoleplayer].mo->Sector->PortalGroup, sec->PortalGroup, !!ff); +} diff --git a/src/r_defs.h b/src/r_defs.h index 15b7337cd..739151c06 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -764,6 +764,19 @@ struct sector_t return LowestFloorAt(a->X(), a->Y(), resultsec); } + fixed_t NextHighestCeilingAt(fixed_t x, fixed_t y, fixed_t z, sector_t **resultsec = NULL, F3DFloor **resultffloor = NULL); + fixed_t NextLowestFloorAt(fixed_t x, fixed_t y, fixed_t z, sector_t **resultsec = NULL, F3DFloor **resultffloor = NULL); + + fixed_t NextHighestCeilingAt(AActor *a, fixed_t z, sector_t **resultsec = NULL, F3DFloor **resultffloor = NULL) + { + return NextHighestCeilingAt(a->X(), a->Y(), z, resultsec, resultffloor); + } + + fixed_t NextLowestFloorAt(AActor *a, fixed_t z, sector_t **resultsec = NULL, F3DFloor **resultffloor = NULL) + { + return NextLowestFloorAt(a->X(), a->Y(), z, resultsec, resultffloor); + } + // ... for ceilings fixed_t CeilingAtPoint(fixed_t x, fixed_t y, int refgroup) const {