#include "stdafx.h" #include "nel_patch_paint.h" #include "paint_fill.h" #include "paint_undo.h" #include "paint_vcolor.h" #include "paint_to_nel.h" #include "nel/3d/landscape.h" /*-------------------------------------------------------------------*/ void CFillPatch::fillTile (int mesh, int patch, std::vector &vectMesh, int tileSet, int rot, int group, bool _256, const CTileBank& bank) { // Only if the landscape is valid if (_Landscape) { // Nel patch changement manager CNelPatchChanger nelPatchChg (_Landscape); // Clear tile description tileDesc descClear; descClear.setTile (0, 0, 0, tileIndex (0,0), tileIndex (0,0), tileIndex (0,0)); // Fill tile description tileDesc descFill; // Four fill descriptor LeftTop, LeftBottom, RightTop, RightBottom // Fill with clear ? if (tileSet==-1) descFill.setTile (0, 0, 0, tileIndex (0,0), tileIndex (0,0), tileIndex (0,0)); // Tiles numbers uint numU=1<getUIPatch (patch).NbTilesU; uint numV=1<getUIPatch (patch).NbTilesV; // For all tiles for (uint v=0; vselectTile (tileSet, false, _256, group, bank); // Quit if no tile if (nTile==-1) return; // Check if the tiles are locked and if they are near a locked tile uint vv; uint uu; bool nearLocked = false; bool locked = false; for (vv=0; vv<(uint)_256+1; vv++) for (uu=0; uu<(uint)_256+1; uu++) { // Get the tile EPM_PaintTile *pTile=&_MouseProc->metaTile[mesh][patch*NUM_TILE_SEL+(vv+v)*MAX_TILE_IN_PATCH+uu+u]; nlassert (pTile->Mesh==mesh); nlassert (pTile->patch==patch); // Locked ? if (_256) { // Locked ? if (_MouseProc->isLocked256 (_PObj, pTile)) { locked = true; break; } } else { // Locked ? if (_MouseProc->isLockedEx (_PObj, pTile, vectMesh, _Landscape)) { locked = true; break; } } // Near a locked tile ? uint n; for (n=0; n<4; n++) { // Neighbor ? if (pTile->voisins[n]) { if (_256) { // Neighbor locked ? if (_MouseProc->isLocked256 (_PObj, pTile->voisins[n])) { nearLocked = true; } } else { // Neighbor locked ? if (_MouseProc->isLockedEx (_PObj, pTile->voisins[n], vectMesh, _Landscape)) { nearLocked = true; } } } } } // If unlocked if (!locked) { // Near a locked tile ? if (nearLocked) { // For all tiles in this tile for (vv=0; vv<(uint)_256+1; vv++) for (uu=0; uu<(uint)_256+1; uu++) { // Get the tile pointer EPM_PaintTile *pTile=&_MouseProc->metaTile[mesh][patch*NUM_TILE_SEL+(vv+v)*MAX_TILE_IN_PATCH+uu+u]; nlassert (pTile->Mesh==mesh); nlassert (pTile->patch==patch); // Clear the tile _MouseProc->ClearATile (pTile, vectMesh, _Landscape, nelPatchChg, _256, !_256); } } else // Not near a locked tile ? { // For all tiles in this tile, check it is compatible bool compatible = true; if (tileSet!=-1) { for (vv=0; vv<(uint)_256+1; vv++) for (uu=0; uu<(uint)_256+1; uu++) { // Get the tile pointer EPM_PaintTile *pTile=&_MouseProc->metaTile[mesh][patch*NUM_TILE_SEL+(vv+v)*MAX_TILE_IN_PATCH+uu+u]; nlassert (pTile->Mesh==mesh); nlassert (pTile->patch==patch); // Check if neighborhood must be cleared uint n; for (n=0; n<4; n++) { // Neighborhood not in this patch? if ((pTile->voisins[n])&&((pTile->voisins[n]->Mesh!=mesh)||(pTile->voisins[n]->patch!=patch))) { // Neigborhood not compatible ? tileDesc descNei; _MouseProc->GetTile (pTile->voisins[n]->Mesh, pTile->voisins[n]->tile, descNei, vectMesh, _Landscape); // If empty, compatible if (descNei.getNumLayer()==0) continue; // Voisin have one layer if (descNei.getNumLayer()==1) { // Check rotation if (descNei.getLayer(0).Rotate==((pTile->rotate[n]+rot)&3)) { // Get the tile set int neiTileSet; int number; CTileBank::TTileType type; bank.getTileXRef (descNei.getLayer(0).Tile, neiTileSet, number, type); // Same tileSet if (tileSet==neiTileSet) continue; } } // Not compatible compatible = false; break; } } // Breaked ? if (n<4) break; } } // Compatible ? if (compatible) { // Set each tiles for (vv=0; vv<(uint)_256+1; vv++) for (uu=0; uu<(uint)_256+1; uu++) { // Get the tile pointer EPM_PaintTile *pTile=&_MouseProc->metaTile[mesh][patch*NUM_TILE_SEL+(vv+v)*MAX_TILE_IN_PATCH+uu+u]; nlassert (pTile->Mesh==mesh); nlassert (pTile->patch==patch); if (tileSet!=-1) { // 256 tile ? if (_256) { switch (((uu&1)<<1)|(vv&1)) { case 0: // LeftTop descFill.setTile (1, ((0-rot)&3)+1, 0, tileIndex (nTile, rot), tileIndex (0, 0), tileIndex (0, 0)); break; case 1: // LeftBottom descFill.setTile (1, ((1-rot)&3)+1, 0, tileIndex (nTile, rot), tileIndex (0, 0), tileIndex (0, 0)); break; case 2: // RightTop descFill.setTile (1, ((3-rot)&3)+1, 0, tileIndex (nTile, rot), tileIndex (0, 0), tileIndex (0, 0)); break; case 3: // RightBottom descFill.setTile (1, ((2-rot)&3)+1, 0, tileIndex (nTile, rot), tileIndex (0, 0), tileIndex (0, 0)); break; default: nlassert (0); // no ! } } else // Set the tile descFill.setTile (1, 0, 0, tileIndex (nTile, rot), tileIndex (0, 0), tileIndex (0, 0)); } // Get the displace index tileDesc descOrig; _MouseProc->GetTile (mesh, pTile->tile, descOrig, vectMesh, _Landscape); // Fill the current tile with the current tileset and rotation descFill.setDisplace (descOrig.getDisplace ()); _MouseProc->SetTile (mesh, pTile->tile, descFill, vectMesh, _Landscape, nelPatchChg, NULL); } } else { // For all tiles in this tile for (vv=0; vv<(uint)_256+1; vv++) for (uu=0; uu<(uint)_256+1; uu++) { // Get the tile pointer EPM_PaintTile *pTile=&_MouseProc->metaTile[mesh][patch*NUM_TILE_SEL+(vv+v)*MAX_TILE_IN_PATCH+uu+u]; nlassert (pTile->Mesh==mesh); nlassert (pTile->patch==patch); // Clear the tile _MouseProc->ClearATile (pTile, vectMesh, _Landscape, nelPatchChg, _256, !_256); } } } } } // Flush nel chgt nelPatchChg.applyChanges (true); } } /*-------------------------------------------------------------------*/ void CFillPatch::fillColor (int mesh, int patch, std::vector &vectMesh, const CRGBA& color, uint16 blend, CPaintColor& paintColor) { // Only if the landscape is valid if (_Landscape) { // Nel patch changement manager CNelPatchChanger nelPatchChg (_Landscape); // Tiles numbers uint numU=(1<getUIPatch (patch).NbTilesU)+1; uint numV=(1<getUIPatch (patch).NbTilesV)+1; // For all tiles for (uint v=0; v &vectMesh, const CTileBank& bank) { // Only if the landscape is valid if (_Landscape) { // Nel patch changement manager CNelPatchChanger nelPatchChg (_Landscape); // Tiles numbers uint numU=1<getUIPatch (patch).NbTilesU; uint numV=1<getUIPatch (patch).NbTilesV; // For all tiles for (uint v=0; vmetaTile[mesh][patch*NUM_TILE_SEL+(v)*MAX_TILE_IN_PATCH+u]; nlassert (pTile->Mesh==mesh); nlassert (pTile->patch==patch); // Set the displace _MouseProc->PutADisplacetile ( pTile, bank, vectMesh, _Landscape, nelPatchChg); } // Flush nel chgt nelPatchChg.applyChanges (true); } } /*-------------------------------------------------------------------*/