int SrvrMergeSelectedWalls( uint32_t client_id, INDEX iWorld, INDEX iDefinite, PORTHOAREA rect ) { GETWORLD(iWorld ); //PWALL pDefinite = GetWall( iDefinite ); WALLSELECTINFO si; // normal 1 si.r.n[0] = rect->w; si.r.n[1] = rect->h; si.r.n[2] = 0; si.r.o[0] = rect->x; si.r.o[1] = rect->y; si.r.o[2] = 0; si.iWorld = iWorld; si.nwalls = 0; if( !ForAllWalls( world->walls, CheckWallSelect, &si ) ) { Log1( "Found %d walls to merge: %d", si.nwalls ); if( si.nwalls == 2 && ( GetWall( si.walls[0] )->iSector != GetWall( si.walls[1] )->iSector ) ) { SrvrMergeWalls( client_id, iWorld, si.walls[0], si.walls[1] ); } if( si.nwalls == 1 && iDefinite != INVALID_INDEX && si.walls[0] != iDefinite ) { SrvrMergeWalls( client_id, iWorld, iDefinite, si.walls[0] ); } return TRUE; } return FALSE; }
char Map::GetConnectionIndex(int i, int j, bool wall) { int index = 0; if (wall) { int id = GetWall(i, j); if (id == 4) id = 3; if (GetWall(i, j - 1) < id) { index |= 1; } if (GetWall(i + 1, j) < id) { index |= 2; } if (GetWall(i, j + 1) < id) { index |= 4; } if (GetWall(i - 1, j) < id) { index |= 8; } } else { int id = GetBlock(i, j); if (GetBlock(i, j - 1) < id) { index |= 1; } if (GetBlock(i + 1, j) < id) { index |= 2; } if (GetBlock(i, j + 1) < id) { index |= 4; } if (GetBlock(i - 1, j) < id) { index |= 8; } } return index; }
void Map::SetWall(int i, int j, int id) { if (GetWall(i, j) == id || !ValidateBlock(i, j)) return; walls[i][j].Id = id; if (id == 0) { if (blocks[i][j].Id == 0) blocks[i][j].lightSource = MAX_LIGHT; } UpdateBlock(i, j); UpdateNearBlocks(i, j); lightDirty = true; }
//! check if the current hypothesis extension violates reordering constraints bool ReorderingConstraint::Check( const WordsBitmap &bitmap, size_t startPos, size_t endPos ) const { // nothing to be checked, we are done if (! IsActive() ) return true; VERBOSE(3,"CHECK " << bitmap << " " << startPos << "-" << endPos); // check walls size_t firstGapPos = bitmap.GetFirstGapPos(); // filling first gap -> no wall violation possible if (firstGapPos != startPos) { // if there is a wall before the last word, // we created a gap while moving through wall // -> violation for( size_t pos = firstGapPos; pos < endPos; pos++ ) { if( GetWall( pos ) ) { VERBOSE(3," hitting wall " << pos << std::endl); return false; } } } // monotone -> no violation possible size_t lastPos = bitmap.GetLastPos(); if ((lastPos == NOT_FOUND && startPos == 0) || // nothing translated (firstGapPos > lastPos && // no gaps firstGapPos == startPos)) { // translating first empty word VERBOSE(3," montone, fine." << std::endl); return true; } // check zones for(size_t z = 0; z < m_zone.size(); z++ ) { const size_t startZone = m_zone[z][0]; const size_t endZone = m_zone[z][1]; // fine, if translation has not reached zone yet and phrase outside zone if (lastPos < startZone && ( endPos < startZone || startPos > endZone ) ) { continue; } // already completely translated zone, no violations possible if (firstGapPos > endZone) { continue; } // some words are translated beyond the start // let's look closer if some are in the zone size_t numWordsInZoneTranslated = 0; if (lastPos >= startZone) { for(size_t pos = startZone; pos <= endZone; pos++ ) { if( bitmap.GetValue( pos ) ) { numWordsInZoneTranslated++; } } } // all words in zone translated, no violation possible if (numWordsInZoneTranslated == endZone-startZone+1) { continue; } // flag if this is an active zone bool activeZone = (numWordsInZoneTranslated > 0); // fine, if zone completely untranslated and phrase outside zone if (!activeZone && ( endPos < startZone || startPos > endZone ) ) { continue; } // violation, if phrase completely outside active zone if (activeZone && ( endPos < startZone || startPos > endZone ) ) { VERBOSE(3," outside active zone" << std::endl); return false; } // ok, this is what we know now: // * the phrase is in the zone (at least partially) // * either zone is already active, or it becomes active now // check, if we are setting us up for a dead end due to distortion limits int distortionLimit = StaticData::Instance().GetMaxDistortion(); if (startPos != firstGapPos && endZone-firstGapPos >= distortionLimit) { VERBOSE(3," dead end due to distortion limit" << std::endl); return false; } // let us check on phrases that are partially outside // phrase overlaps at the beginning, always ok if (startPos <= startZone) { continue; } // phrase goes beyond end, has to fill zone completely if (endPos > endZone) { if (endZone-startPos+1 < // num. words filled in by phrase endZone-startZone+1-numWordsInZoneTranslated) { // num. untranslated VERBOSE(3," overlap end, but not completing" << std::endl); return false; } else { continue; } } // now we are down to phrases that are completely inside the zone // we have to check local walls bool seenUntranslatedBeforeStartPos = false; for(size_t pos = startZone; pos < endZone && pos < endPos; pos++ ) { // be careful when there is a gap before phrase if( !bitmap.GetValue( pos ) // untranslated word && pos < startPos ) { // before startPos seenUntranslatedBeforeStartPos = true; } if( seenUntranslatedBeforeStartPos && GetLocalWall( pos, z ) ) { VERBOSE(3," local wall violation" << std::endl); return false; } } // passed all checks for this zone, on to the next one } // passed all checks, no violations VERBOSE(3," fine." << std::endl); return true; }
int ValidateWorldLinks( INDEX iWorld ) { GETWORLD(iWorld); int status = TRUE; int nLines; PFLATLAND_MYLINESEG *pLines; int nWalls; PWALL *pWalls; int nSectors; PSECTOR *pSectors; int nNames; PNAME *pNames; pSectors = GetLinearSectorArray( world->sectors, &nSectors ); pWalls = GetLinearWallArray( world->walls, &nWalls ); pLines = GetLinearLineArray( world->lines, &nLines ); pNames = GetLinearNameArray( world->names, &nNames ); { int n, m, refcount; for( n = 0; n < nLines; n++ ) { refcount = 0; for( m = 0; m < nWalls; m++ ) { if( GetLine( pWalls[m]->iLine ) == pLines[n] ) { if( pWalls[m]->iWallInto != INVALID_INDEX ) { refcount++; if( refcount == 2 ) { //pLines[n] = NULL; break; } } } else { //pLines[n] = NULL; break; } } if( m == nWalls ) { status = FALSE; Log1( "Line %08x is unreferenced... deleting now.", pLines[n] ); DeleteLine( world->lines, pLines[n] ); pLines[n] = NULL; } } for( n = 0; n < nWalls; n++ ) { if( !pWalls[n] ) continue; for( m = 0; m < nLines; m++ ) { if( GetLine( pWalls[n]->iLine ) == pLines[m] ) { // if this line is shared - remove the other reference to it. /* if( pWalls[n]->wall_into ) { int i; for( i = 0; i < nWalls; i++ ) { if( pWalls[i] == pWalls[n]->wall_into ) pWalls[i] = NULL; } } pLines[m] = NULL; // clear line reference... */ break; } } if( m == nLines ) { status = FALSE; Log3( "Wall %08x in Sector %d referenced line %08x that does not exist", pWalls[n], GetSector( pWalls[n]->iSector )->iName, pWalls[n]->iLine ); } } for( n = 0; n < nLines; n++ ) { int count = 0; if( !pLines[n]->refcount ) Log( "Line exists with no reference count" ); for( m = 0; m < nWalls; m++ ) { if( GetLine( pWalls[m]->iLine ) == pLines[n] ) { count++; } } if( count != pLines[n]->refcount ) { Log2( "Line reference count of %d does not match actual %d" , pLines[n]->refcount , count ); } } for( n = 0; n < nSectors; n++ ) { PWALL pStart, pCur; int priorend = TRUE; if( pSectors[n]->iName != INVALID_INDEX ) { int i; for( i = 0; i < nNames; i++ ) { if( GetName( pSectors[n]->iName ) == pNames[i] ) break; } if( i == nNames ) { Log2( "Name %08x referenced by Sector %d does not exist", pSectors[n]->iName, n ); } } pCur = pStart = GetWall( pSectors[n]->iWall ); do { if( pCur->iLine == INVALID_INDEX ) { Log1( "Wall in sector %d has an invalid line def", pSectors[n]->iName ); } for( m = 0; m < nWalls; m++ ) { if( pWalls[m] == pCur ) break; } if( m == nWalls ) { status = FALSE; Log4( "Sector %*.*s referenced wall %08x that does not exist", GetName( pSectors[n]->iName )->name[0].length, GetName( pSectors[n]->iName )->name[0].length, GetName( pSectors[n]->iName )->name[0].name, pCur ); } // code goes here.... if( priorend ) { priorend = pCur->flags.wall_start_end; pCur = GetWall( pCur->iWallStart ); } else { priorend = pCur->flags.wall_end_end; pCur = GetWall( pCur->iWallEnd ); } }while( pCur != pStart ); } } Release( pLines ); Release( pWalls ); Release( pSectors ); Release( pNames ); return status; }