diff --git a/src/game/editor/auto_map.cpp b/src/game/editor/auto_map.cpp index 06606fc3d..9d8fea957 100644 --- a/src/game/editor/auto_map.cpp +++ b/src/game/editor/auto_map.cpp @@ -72,6 +72,10 @@ void CAutoMapper::Load(const char* pTileName) // new configuration, get the name pLine++; CConfiguration NewConf; + NewConf.m_StartX = 0; + NewConf.m_StartY = 0; + NewConf.m_EndX = 0; + NewConf.m_EndY = 0; int ConfigurationID = m_lConfigs.add(NewConf); pCurrentConf = &m_lConfigs[ConfigurationID]; str_copy(pCurrentConf->m_aName, pLine, str_length(pLine)); @@ -254,6 +258,11 @@ void CAutoMapper::Load(const char* pTileName) CPosRule NewPosRule = {x, y, Value, NewIndexList}; pCurrentIndex->m_aRules.add(NewPosRule); + pCurrentConf->m_StartX = min(pCurrentConf->m_StartX, NewPosRule.m_X); + pCurrentConf->m_StartY = min(pCurrentConf->m_StartY, NewPosRule.m_Y); + pCurrentConf->m_EndX = max(pCurrentConf->m_EndX, NewPosRule.m_X); + pCurrentConf->m_EndY = max(pCurrentConf->m_EndY, NewPosRule.m_Y); + if(x == 0 && y == 0) { for(int i = 0; i < NewIndexList.size(); ++i) { @@ -343,7 +352,63 @@ const char* CAutoMapper::GetConfigName(int Index) return m_lConfigs[Index].m_aName; } -void CAutoMapper::Proceed(CLayerTiles *pLayer, int ConfigID, int Seed) +void CAutoMapper::ProceedLocalized(CLayerTiles *pLayer, int ConfigID, int Seed, int X, int Y, int Width, int Height) +{ + if(!m_FileLoaded || pLayer->m_Readonly || ConfigID < 0 || ConfigID >= m_lConfigs.size()) + return; + + if(Width < 0) + Width = pLayer->m_Width; + + if(Height < 0) + Height = pLayer->m_Height; + + CConfiguration *pConf = &m_lConfigs[ConfigID]; + + int CommitFromX = max(X + pConf->m_StartX, 0); + int CommitFromY = max(Y + pConf->m_StartY, 0); + int CommitToX = min(X + Width + pConf->m_EndX, pLayer->m_Width); + int CommitToY = min(Y + Height + pConf->m_EndY, pLayer->m_Height); + + int UpdateFromX = max(X + 3 * pConf->m_StartX, 0); + int UpdateFromY = max(Y + 3 * pConf->m_StartY, 0); + int UpdateToX = min(X + Width + 3 * pConf->m_EndX, pLayer->m_Width); + int UpdateToY = min(Y + Height + 3 * pConf->m_EndY, pLayer->m_Height); + + CLayerTiles *pUpdateLayer; + if (UpdateFromX != 0 || UpdateFromY != 0 || UpdateToX != pLayer->m_Width || UpdateToY != pLayer->m_Width) + { // Needs a layer to work on + pUpdateLayer = new CLayerTiles(UpdateToX - UpdateFromX, UpdateToY - UpdateFromY); + + for(int y = UpdateFromY; y < UpdateToY; y++) { + for(int x = UpdateFromX; x < UpdateToX; x++) + { + CTile *in = &pLayer->m_pTiles[y*pLayer->m_Width+x]; + CTile *out = &pUpdateLayer->m_pTiles[(y-UpdateFromY)*pUpdateLayer->m_Width+x-UpdateFromX]; + out->m_Index = in->m_Index; + out->m_Flags = in->m_Flags; + } + } + } + else + { + pUpdateLayer = pLayer; + } + + Proceed(pUpdateLayer, ConfigID, Seed, UpdateFromX, UpdateFromY); + + for(int y = CommitFromY; y < CommitToY; y++) { + for(int x = CommitFromX; x < CommitToX; x++) + { + CTile *in = &pUpdateLayer->m_pTiles[(y-UpdateFromY)*pUpdateLayer->m_Width+x-UpdateFromX]; + CTile *out = &pLayer->m_pTiles[y*pLayer->m_Width+x]; + out->m_Index = in->m_Index; + out->m_Flags = in->m_Flags; + } + } +} + +void CAutoMapper::Proceed(CLayerTiles *pLayer, int ConfigID, int Seed, int SeedOffsetX, int SeedOffsetY) { if(!m_FileLoaded || pLayer->m_Readonly || ConfigID < 0 || ConfigID >= m_lConfigs.size()) return; @@ -359,18 +424,10 @@ void CAutoMapper::Proceed(CLayerTiles *pLayer, int ConfigID, int Seed) // don't make copy if it's requested CLayerTiles *pReadLayer; - if(pRun->m_AutomapCopy) - { - pReadLayer = new CLayerTiles(pLayer->m_Width, pLayer->m_Height); - } - else - { - pReadLayer = pLayer; - } - - // copy tiles if(pRun->m_AutomapCopy) { + pReadLayer = new CLayerTiles(pLayer->m_Width, pLayer->m_Height); + for(int y = 0; y < pLayer->m_Height; y++) { for(int x = 0; x < pLayer->m_Width; x++) { @@ -381,6 +438,10 @@ void CAutoMapper::Proceed(CLayerTiles *pLayer, int ConfigID, int Seed) } } } + else + { + pReadLayer = pLayer; + } // auto map for(int y = 0; y < pLayer->m_Height; y++) { @@ -438,7 +499,7 @@ void CAutoMapper::Proceed(CLayerTiles *pLayer, int ConfigID, int Seed) } if(RespectRules && - (pIndexRule->m_RandomProbability >= 1.0 || HashLocation(Seed, h, i, x, y) < HASH_MAX * pIndexRule->m_RandomProbability)) + (pIndexRule->m_RandomProbability >= 1.0 || HashLocation(Seed, h, i, x + SeedOffsetX, y + SeedOffsetY) < HASH_MAX * pIndexRule->m_RandomProbability)) { pTile->m_Index = pIndexRule->m_ID; pTile->m_Flags = pIndexRule->m_Flag; diff --git a/src/game/editor/auto_map.h b/src/game/editor/auto_map.h index 1eb8d8284..845a93e7e 100644 --- a/src/game/editor/auto_map.h +++ b/src/game/editor/auto_map.h @@ -48,13 +48,19 @@ class CAutoMapper { array m_aRuns; char m_aName[128]; + int m_StartX; + int m_StartY; + int m_EndX; + int m_EndY; }; public: + CAutoMapper(class CEditor *pEditor); void Load(const char* pTileName); - void Proceed(class CLayerTiles *pLayer, int ConfigID, int Seed=0); + void ProceedLocalized(class CLayerTiles *pLayer, int ConfigID, int Seed=0, int X=0, int Y=0, int Width=-1, int Height=-1); + void Proceed(class CLayerTiles *pLayer, int ConfigID, int Seed=0, int SeedOffsetX=0, int SeedOffsetY=0); int ConfigNamesNum() const { return m_lConfigs.size(); } const char* GetConfigName(int Index); diff --git a/src/game/editor/editor.h b/src/game/editor/editor.h index a9984d333..baecf5966 100644 --- a/src/game/editor/editor.h +++ b/src/game/editor/editor.h @@ -553,7 +553,7 @@ public: void GetSize(float *w, float *h) { *w = m_Width*32.0f; *h = m_Height*32.0f; } - void TryInvokeAutomapper(); + void FlagModified(int x, int y, int w, int h); int m_TexID; int m_Game; diff --git a/src/game/editor/layer_tiles.cpp b/src/game/editor/layer_tiles.cpp index ef593f2f6..a26c62901 100644 --- a/src/game/editor/layer_tiles.cpp +++ b/src/game/editor/layer_tiles.cpp @@ -397,8 +397,7 @@ void CLayerTiles::FillSelection(bool Empty, CLayer *pBrush, CUIRect Rect) SetTile(fx, fy, pLt->m_pTiles[(y*pLt->m_Width + x%pLt->m_Width) % (pLt->m_Width*pLt->m_Height)]); } } - m_pEditor->m_Map.m_Modified = true; - TryInvokeAutomapper(); + FlagModified(sx, sy, w, h); } void CLayerTiles::BrushDraw(CLayer *pBrush, float wx, float wy) @@ -421,8 +420,7 @@ void CLayerTiles::BrushDraw(CLayer *pBrush, float wx, float wy) SetTile(fx, fy, l->m_pTiles[y*l->m_Width+x]); } - m_pEditor->m_Map.m_Modified = true; - TryInvokeAutomapper(); + FlagModified(sx, sy, l->m_Width, l->m_Height); } void CLayerTiles::BrushFlipX() @@ -700,7 +698,7 @@ int CLayerTiles::RenderProperties(CUIRect *pToolBox) if(m_pEditor->DoButton_Editor(&s_AutoMapperButtonAuto, "A", m_AutoAutoMap, &ButtonAuto, 0, "Automatically run automap after modifications.")) { m_AutoAutoMap = !m_AutoAutoMap; - TryInvokeAutomapper(); + FlagModified(0, 0, m_Width, m_Height); } } if(m_pEditor->DoButton_Editor(&s_AutoMapperButton, "Automap", 0, &Button, 0, "Run the automapper")) @@ -828,23 +826,22 @@ int CLayerTiles::RenderProperties(CUIRect *pToolBox) } else if(Prop == PROP_AUTOMAPPER) { - if (m_Image >= 0) + if (m_Image >= 0 && m_pEditor->m_Map.m_lImages[m_Image]->m_AutoMapper.ConfigNamesNum() > 0) m_AutoMapperConfig = NewVal%m_pEditor->m_Map.m_lImages[m_Image]->m_AutoMapper.ConfigNamesNum(); else m_AutoMapperConfig = -1; } if(Prop != -1) { - m_pEditor->m_Map.m_Modified = true; - TryInvokeAutomapper(); + FlagModified(0, 0, m_Width, m_Height); } return 0; } -void CLayerTiles::TryInvokeAutomapper() { +void CLayerTiles::FlagModified(int x, int y, int w, int h) { + m_pEditor->m_Map.m_Modified = true; if (m_Seed != 0 && m_AutoMapperConfig != -1 && m_AutoAutoMap) { - m_pEditor->m_Map.m_lImages[m_Image]->m_AutoMapper.Proceed(this, m_AutoMapperConfig, m_Seed); - m_pEditor->m_Map.m_Modified = true; + m_pEditor->m_Map.m_lImages[m_Image]->m_AutoMapper.ProceedLocalized(this, m_AutoMapperConfig, m_Seed, x, y, w, h); } } @@ -995,8 +992,7 @@ void CLayerTele::BrushDraw(CLayer *pBrush, float wx, float wy) m_pTiles[fy*m_Width+fx].m_Index = 0; } } - m_pEditor->m_Map.m_Modified = true; - TryInvokeAutomapper(); + FlagModified(sx, sy, l->m_Width, l->m_Height); } void CLayerTele::BrushFlipX() @@ -1109,6 +1105,7 @@ void CLayerTele::FillSelection(bool Empty, CLayer *pBrush, CUIRect Rect) } } } + FlagModified(sx, sy, w, h); } CLayerSpeedup::CLayerSpeedup(int w, int h) @@ -1263,8 +1260,7 @@ void CLayerSpeedup::BrushDraw(CLayer *pBrush, float wx, float wy) m_pTiles[fy*m_Width+fx].m_Index = 0; } } - m_pEditor->m_Map.m_Modified = true; - TryInvokeAutomapper(); + FlagModified(sx, sy, l->m_Width, l->m_Height); } void CLayerSpeedup::BrushFlipX() @@ -1385,6 +1381,7 @@ void CLayerSpeedup::FillSelection(bool Empty, CLayer *pBrush, CUIRect Rect) } } } + FlagModified(sx, sy, w, h); } CLayerFront::CLayerFront(int w, int h) @@ -1452,8 +1449,7 @@ void CLayerFront::BrushDraw(CLayer *pBrush, float wx, float wy) SetTile(fx, fy, l->m_pTiles[y*l->m_Width+x]); } - m_pEditor->m_Map.m_Modified = true; - TryInvokeAutomapper(); + FlagModified(sx, sy, l->m_Width, l->m_Height); } CLayerSwitch::CLayerSwitch(int w, int h) @@ -1606,8 +1602,7 @@ void CLayerSwitch::BrushDraw(CLayer *pBrush, float wx, float wy) m_pSwitchTile[fy*m_Width+fx].m_Delay = 0; } } - m_pEditor->m_Map.m_Modified = true; - TryInvokeAutomapper(); + FlagModified(sx, sy, l->m_Width, l->m_Height); } void CLayerSwitch::FillSelection(bool Empty, CLayer *pBrush, CUIRect Rect) @@ -1664,6 +1659,7 @@ void CLayerSwitch::FillSelection(bool Empty, CLayer *pBrush, CUIRect Rect) } } } + FlagModified(sx, sy, w, h); } //------------------------------------------------------ @@ -1807,8 +1803,7 @@ void CLayerTune::BrushDraw(CLayer *pBrush, float wx, float wy) m_pTiles[fy*m_Width+fx].m_Index = 0; } } - m_pEditor->m_Map.m_Modified = true; - TryInvokeAutomapper(); + FlagModified(sx, sy, l->m_Width, l->m_Height); } @@ -1921,4 +1916,6 @@ void CLayerTune::FillSelection(bool Empty, CLayer *pBrush, CUIRect Rect) } } } + + FlagModified(sx, sy, w, h); }