sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel, bool back) { // [RH] allow per-plane lighting if (floorlightlevel != NULL) { *floorlightlevel = sec->floorlightsec == NULL ? sec->lightlevel : sec->floorlightsec->lightlevel; } if (ceilinglightlevel != NULL) { *ceilinglightlevel = sec->ceilinglightsec == NULL ? // killough 4/11/98 sec->lightlevel : sec->ceilinglightsec->lightlevel; } FakeSide = FAKED_Center; if (!sec->heightsec || sec->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) return sec; if (!camera || !camera->subsector || !camera->subsector->sector) return sec; const sector_t* s = sec->heightsec; sector_t *heightsec = camera->subsector->sector->heightsec; bool underwater = r_fakingunderwater || (heightsec && viewz <= P_FloorHeight(viewx, viewy, heightsec)); bool doorunderwater = false; int diffTex = (s->MoreFlags & SECF_CLIPFAKEPLANES); // Replace sector being drawn with a copy to be hacked *tempsec = *sec; // Replace floor and ceiling height with control sector's heights. if (diffTex) { if (CopyPlaneIfValid (&tempsec->floorplane, &s->floorplane, &sec->ceilingplane)) tempsec->floorpic = s->floorpic; else if (s->MoreFlags & SECF_FAKEFLOORONLY) { if (underwater) { tempsec->colormap = s->colormap; if (!(s->MoreFlags & SECF_NOFAKELIGHT)) { tempsec->lightlevel = s->lightlevel; if (floorlightlevel != NULL) { *floorlightlevel = s->floorlightsec == NULL ? s->lightlevel : s->floorlightsec->lightlevel; } if (ceilinglightlevel != NULL) { *ceilinglightlevel = s->ceilinglightsec == NULL ? s->lightlevel : s->ceilinglightsec->lightlevel; } } FakeSide = FAKED_BelowFloor; return tempsec; } return sec; } } else { tempsec->floorplane = s->floorplane; } if (!(s->MoreFlags & SECF_FAKEFLOORONLY)) { if (diffTex) { if (CopyPlaneIfValid (&tempsec->ceilingplane, &s->ceilingplane, &sec->floorplane)) tempsec->ceilingpic = s->ceilingpic; } else { tempsec->ceilingplane = s->ceilingplane; } } fixed_t refceilz = P_CeilingHeight(viewx, viewy, s); fixed_t orgceilz = P_CeilingHeight(viewx, viewy, sec); // [RH] Allow viewing underwater areas through doors/windows that // are underwater but not in a water sector themselves. // Only works if you cannot see the top surface of any deep water // sectors at the same time. if (back && !r_fakingunderwater && curline->frontsector->heightsec == NULL) { fixed_t fcz1 = P_CeilingHeight(curline->v1->x, curline->v1->y, frontsector); fixed_t fcz2 = P_CeilingHeight(curline->v2->x, curline->v2->y, frontsector); if (fcz1 <= P_FloorHeight(curline->v1->x, curline->v1->y, s) && fcz2 <= P_FloorHeight(curline->v2->x, curline->v2->y, s)) { // will any columns of this window be visible or will they be blocked // by 1s lines and closed doors? if (memchr(solidcol + rw_start, 0, rw_stop - rw_start + 1) != NULL) { doorunderwater = true; r_fakingunderwater = true; } } } if (underwater || doorunderwater) { tempsec->floorplane = sec->floorplane; tempsec->ceilingplane = s->floorplane; P_InvertPlane(&tempsec->ceilingplane); P_ChangeCeilingHeight(tempsec, -1); tempsec->colormap = s->colormap; } // killough 11/98: prevent sudden light changes from non-water sectors: if ((underwater && !back) || doorunderwater) { // head-below-floor hack tempsec->floorpic = diffTex ? sec->floorpic : s->floorpic; tempsec->floor_xoffs = s->floor_xoffs; tempsec->floor_yoffs = s->floor_yoffs; tempsec->floor_xscale = s->floor_xscale; tempsec->floor_yscale = s->floor_yscale; tempsec->floor_angle = s->floor_angle; tempsec->base_floor_angle = s->base_floor_angle; tempsec->base_floor_yoffs = s->base_floor_yoffs; tempsec->ceilingplane = s->floorplane; P_InvertPlane(&tempsec->ceilingplane); P_ChangeCeilingHeight(tempsec, -1); if (s->ceilingpic == skyflatnum) { tempsec->floorplane = tempsec->ceilingplane; P_InvertPlane(&tempsec->floorplane); P_ChangeFloorHeight(tempsec, +1); tempsec->ceilingpic = tempsec->floorpic; tempsec->ceiling_xoffs = tempsec->floor_xoffs; tempsec->ceiling_yoffs = tempsec->floor_yoffs; tempsec->ceiling_xscale = tempsec->floor_xscale; tempsec->ceiling_yscale = tempsec->floor_yscale; tempsec->ceiling_angle = tempsec->floor_angle; tempsec->base_ceiling_angle = tempsec->base_floor_angle; tempsec->base_ceiling_yoffs = tempsec->base_floor_yoffs; } else { tempsec->ceilingpic = diffTex ? s->floorpic : s->ceilingpic; tempsec->ceiling_xoffs = s->ceiling_xoffs; tempsec->ceiling_yoffs = s->ceiling_yoffs; tempsec->ceiling_xscale = s->ceiling_xscale; tempsec->ceiling_yscale = s->ceiling_yscale; tempsec->ceiling_angle = s->ceiling_angle; tempsec->base_ceiling_angle = s->base_ceiling_angle; tempsec->base_ceiling_yoffs = s->base_ceiling_yoffs; } if (!(s->MoreFlags & SECF_NOFAKELIGHT)) { tempsec->lightlevel = s->lightlevel; if (floorlightlevel != NULL) { *floorlightlevel = s->floorlightsec == NULL ? s->lightlevel : s->floorlightsec->lightlevel; } if (ceilinglightlevel != NULL) { *ceilinglightlevel = s->ceilinglightsec == NULL ? s->lightlevel : s->ceilinglightsec->lightlevel; } } FakeSide = FAKED_BelowFloor; } else if (heightsec && viewz >= P_CeilingHeight(viewx, viewy, heightsec) && orgceilz > refceilz && !(s->MoreFlags & SECF_FAKEFLOORONLY)) { // Above-ceiling hack tempsec->ceilingplane = s->ceilingplane; tempsec->floorplane = s->ceilingplane; P_InvertPlane(&tempsec->floorplane); P_ChangeFloorHeight(tempsec, +1); tempsec->colormap = s->colormap; tempsec->ceilingpic = diffTex ? sec->ceilingpic : s->ceilingpic; tempsec->floorpic = s->ceilingpic; tempsec->floor_xoffs = tempsec->ceiling_xoffs = s->ceiling_xoffs; tempsec->floor_yoffs = tempsec->ceiling_yoffs = s->ceiling_yoffs; tempsec->floor_xscale = tempsec->ceiling_xscale = s->ceiling_xscale; tempsec->floor_yscale = tempsec->ceiling_yscale = s->ceiling_yscale; tempsec->floor_angle = tempsec->ceiling_angle = s->ceiling_angle; tempsec->base_floor_angle = tempsec->base_ceiling_angle = s->base_ceiling_angle; tempsec->base_floor_yoffs = tempsec->base_ceiling_yoffs = s->base_ceiling_yoffs; if (s->floorpic != skyflatnum) { tempsec->ceilingplane = sec->ceilingplane; tempsec->floorpic = s->floorpic; tempsec->floor_xoffs = s->floor_xoffs; tempsec->floor_yoffs = s->floor_yoffs; tempsec->floor_xscale = s->floor_xscale; tempsec->floor_yscale = s->floor_yscale; tempsec->floor_angle = s->floor_angle; } if (!(s->MoreFlags & SECF_NOFAKELIGHT)) { tempsec->lightlevel = s->lightlevel; if (floorlightlevel != NULL) { *floorlightlevel = s->floorlightsec == NULL ? s->lightlevel : s->floorlightsec->lightlevel; } if (ceilinglightlevel != NULL) { *ceilinglightlevel = s->ceilinglightsec == NULL ? s->lightlevel : s->ceilinglightsec->lightlevel; } } FakeSide = FAKED_AboveCeiling; } sec = tempsec; // Use other sector return sec; }
// // Move a plane (floor or ceiling) and check for crushing // [RH] Crush specifies the actual amount of crushing damage inflictable. // (Use -1 to prevent it from trying to crush) // DMover::EResult DMover::MovePlane (fixed_t speed, fixed_t dest, bool crush, int floorOrCeiling, int direction) { bool flag; fixed_t lastpos; switch (floorOrCeiling) { case 0: // FLOOR switch (direction) { case -1: // DOWN lastpos = P_FloorHeight(m_Sector); if (lastpos - speed < dest) { P_ChangeFloorHeight(m_Sector, dest - lastpos); flag = P_ChangeSector (m_Sector, crush); if (flag == true) { P_ChangeFloorHeight(m_Sector, lastpos - dest); P_ChangeSector (m_Sector, crush); //return crushed; } return pastdest; } else { P_ChangeFloorHeight(m_Sector, -speed); flag = P_ChangeSector (m_Sector, crush); if (flag == true) { P_ChangeFloorHeight(m_Sector, speed); // should be lastpos P_ChangeSector (m_Sector, crush); return crushed; } } break; case 1: // UP lastpos = P_FloorHeight(m_Sector); if (lastpos + speed > dest) { P_ChangeFloorHeight(m_Sector, dest - lastpos); flag = P_ChangeSector (m_Sector, crush); if (flag == true) { P_ChangeFloorHeight(m_Sector, lastpos - dest); P_ChangeSector (m_Sector, crush); } return pastdest; } else { // COULD GET CRUSHED P_ChangeFloorHeight(m_Sector, speed); flag = P_ChangeSector (m_Sector, crush); if (flag == true) { if (crush) return crushed; P_ChangeFloorHeight(m_Sector, -speed); P_ChangeSector (m_Sector, crush); return crushed; } } break; } break; case 1: // CEILING switch(direction) { case -1: // DOWN lastpos = P_CeilingHeight(m_Sector); if (lastpos - speed < dest) { P_SetCeilingHeight(m_Sector, dest); flag = P_ChangeSector (m_Sector, crush); if (flag == true) { P_SetCeilingHeight(m_Sector, lastpos); P_ChangeSector (m_Sector, crush); } return pastdest; } else { // COULD GET CRUSHED P_SetCeilingHeight(m_Sector, lastpos - speed); flag = P_ChangeSector (m_Sector, crush); if (flag == true) { if (crush) return crushed; P_SetCeilingHeight(m_Sector, lastpos); P_ChangeSector (m_Sector, crush); return crushed; } } break; case 1: // UP lastpos = P_CeilingHeight(m_Sector); if (lastpos + speed > dest) { P_SetCeilingHeight(m_Sector, dest); flag = P_ChangeSector (m_Sector, crush); if (flag == true) { P_SetCeilingHeight(m_Sector, lastpos); P_ChangeSector (m_Sector, crush); } return pastdest; } else { P_SetCeilingHeight(m_Sector, lastpos + speed); flag = P_ChangeSector (m_Sector, crush); // UNUSED #if 0 if (flag == true) { P_ChangeCeilingHeight(m_Sector, -speed); P_ChangeSector (m_Sector, crush); return crushed; } #endif } break; } break; } return ok; }