diff --git a/data/editor/desert_main.rules b/data/editor/desert_main.rules new file mode 100644 index 000000000..0102a1973 --- /dev/null +++ b/data/editor/desert_main.rules @@ -0,0 +1,227 @@ +[Desert] +Index 1 +BaseTile + +#random +Index 2 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 3 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +#top +Index 16 +Pos 0 -1 EMPTY + +#right +Index 17 +Pos 1 0 EMPTY + +#bottom +Index 18 +Pos 0 1 EMPTY + +#left +Index 19 +Pos -1 0 EMPTY + +#corner top-right +Index 33 +Pos 0 -1 EMPTY +Pos 1 0 EMPTY + +#corner top-left +Index 32 +Pos 0 -1 EMPTY +Pos -1 0 EMPTY + +#corner bottom-left +Index 35 +Pos 0 1 EMPTY +Pos -1 0 EMPTY + +#corner bottom-right +Index 34 +Pos 0 1 EMPTY +Pos 1 0 EMPTY + +#inside corner top-right +Index 51 +Pos -1 1 EMPTY +Pos -1 0 FULL +Pos 0 1 FULL + +#inside corner top-left +Index 50 +Pos 1 1 EMPTY +Pos 1 0 FULL +Pos 0 1 FULL + +#inside corner bottom-left +Index 49 +Pos 1 -1 EMPTY +Pos 1 0 FULL +Pos 0 -1 FULL + +#inside corner bottom-right +Index 48 +Pos -1 -1 EMPTY +Pos -1 0 FULL +Pos 0 -1 FULL + +[Mine] +Index 81 +BaseTile + +#random +Index 82 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 500 + +Index 83 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 500 + +Index 84 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 500 + +Index 85 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 500 + +Index 86 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 500 + +Index 100 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 500 + +Index 101 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 500 + +Index 102 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 500 + +Index 117 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 500 + +Index 118 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 500 + +Index 133 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 500 + +Index 134 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 500 + +#top +Index 96 +Pos 0 -1 EMPTY + +#right +Index 97 +Pos 1 0 EMPTY + +#bottom +Index 98 +Pos 0 1 EMPTY + +#left +Index 99 +Pos -1 0 EMPTY + +#corner top-right +Index 113 +Pos 0 -1 EMPTY +Pos 1 0 EMPTY + +#corner top-left +Index 112 +Pos 0 -1 EMPTY +Pos -1 0 EMPTY + +#corner bottom-left +Index 115 +Pos 0 1 EMPTY +Pos -1 0 EMPTY + +#corner bottom-right +Index 114 +Pos 0 1 EMPTY +Pos 1 0 EMPTY + +#inside corner top-right +Index 131 +Pos -1 1 EMPTY +Pos -1 0 FULL +Pos 0 1 FULL + +#inside corner top-left +Index 130 +Pos 1 1 EMPTY +Pos 1 0 FULL +Pos 0 1 FULL + +#inside corner bottom-left +Index 129 +Pos 1 -1 EMPTY +Pos 1 0 FULL +Pos 0 -1 FULL + +#inside corner bottom-right +Index 128 +Pos -1 -1 EMPTY +Pos -1 0 FULL +Pos 0 -1 FULL diff --git a/data/editor/grass_main.rules b/data/editor/grass_main.rules new file mode 100644 index 000000000..b909eb0e8 --- /dev/null +++ b/data/editor/grass_main.rules @@ -0,0 +1,225 @@ +[Grass] +Index 1 +BaseTile + +#random bones +Index 2 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 3 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 66 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 67 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 68 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 +#--------- + +#top +Index 16 +Pos 0 -1 EMPTY + +#right +Index 21 +Pos 1 0 EMPTY + +#bottom +Index 52 +Pos 0 1 EMPTY + +#left +Index 20 +Pos -1 0 EMPTY + +#corner top-right +Index 5 +Pos 0 -1 EMPTY +Pos 1 0 EMPTY + +#corner top-left +Index 4 +Pos 0 -1 EMPTY +Pos -1 0 EMPTY + +#corner bottom-left +Index 36 +Pos 0 1 EMPTY +Pos -1 0 EMPTY + +#corner bottom-right +Index 37 +Pos 0 1 EMPTY +Pos 1 0 EMPTY + +#inside corner top-right +Index 54 +Pos -1 1 EMPTY +Pos -1 0 FULL +Pos 0 1 FULL + +#inside corner top-left +Index 53 +Pos 1 1 EMPTY +Pos 1 0 FULL +Pos 0 1 FULL + +#inside corner bottom-left +Index 49 +Pos 1 -1 EMPTY +Pos 1 0 FULL +Pos 0 -1 FULL + +#inside corner bottom-right +Index 48 +Pos -1 -1 EMPTY +Pos -1 0 FULL +Pos 0 -1 FULL + +#right bottom +Index 22 +Pos -1 0 EMPTY +Pos -1 1 FULL +Pos 0 1 FULL + +#left bottom +Index 38 +Pos 1 0 EMPTY +Pos 1 1 FULL +Pos 0 1 FULL + +#top corner right 2 +Index 33 +Pos 0 -1 EMPTY +Pos 1 0 EMPTY +Pos 1 1 FULL + +#top corner left 2 +Index 32 +Pos 0 -1 EMPTY +Pos -1 0 EMPTY +Pos -1 1 FULL + +[Cave] +Index 13 +BaseTile + +#random bones +Index 29 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 42 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 43 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 44 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 45 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 +#--------- + +#top +Index 26 +Pos 0 -1 EMPTY + +#right +Index 25 +Pos 1 0 EMPTY + +#bottom +Index 10 +Pos 0 1 EMPTY + +#left +Index 24 +Pos -1 0 EMPTY + +#corner top-right +Index 9 +Pos 0 -1 EMPTY +Pos 1 0 EMPTY + +#corner top-left +Index 8 +Pos 0 -1 EMPTY +Pos -1 0 EMPTY + +#corner bottom-left +Index 40 +Pos 0 1 EMPTY +Pos -1 0 EMPTY + +#corner bottom-right +Index 41 +Pos 0 1 EMPTY +Pos 1 0 EMPTY + +#inside corner top-right +Index 12 +Pos -1 1 EMPTY +Pos -1 0 FULL +Pos 0 1 FULL + +#inside corner top-left +Index 11 +Pos 1 1 EMPTY +Pos 1 0 FULL +Pos 0 1 FULL + +#inside corner bottom-left +Index 27 +Pos 1 -1 EMPTY +Pos 1 0 FULL +Pos 0 -1 FULL + +#inside corner bottom-right +Index 28 +Pos -1 -1 EMPTY +Pos -1 0 FULL +Pos 0 -1 FULL diff --git a/data/editor/jungle_main.rules b/data/editor/jungle_main.rules new file mode 100644 index 000000000..3b9670201 --- /dev/null +++ b/data/editor/jungle_main.rules @@ -0,0 +1,220 @@ +[Jungle] +Index 1 +BaseTile + +#random bricks +Index 66 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 67 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +#top +Index 16 +Pos 0 -1 EMPTY + +Index 96 +Pos 0 -1 EMPTY +Random 4 + +Index 97 +Pos 0 -1 EMPTY +Random 4 + +Index 98 +Pos 0 -1 EMPTY +Random 4 + +#right +Index 21 +Pos 1 0 EMPTY + +#bottom +Index 52 +Pos 0 1 EMPTY + +Index 99 +Pos 0 1 EMPTY +Random 4 + +Index 100 +Pos 0 1 EMPTY +Random 4 + +Index 101 +Pos 0 1 EMPTY +Random 4 + +#left +Index 21 XFLIP +Pos -1 0 EMPTY + +#corner top-right +Index 5 +Pos 0 -1 EMPTY +Pos 1 0 EMPTY + +#corner top-left +Index 5 XFLIP +Pos 0 -1 EMPTY +Pos -1 0 EMPTY + +#corner bottom-left +Index 37 XFLIP +Pos 0 1 EMPTY +Pos -1 0 EMPTY + +#corner bottom-right +Index 37 +Pos 0 1 EMPTY +Pos 1 0 EMPTY + +#inside corner top-right +Index 54 +Pos -1 1 EMPTY +Pos -1 0 FULL +Pos 0 1 FULL + +#inside corner top-left +Index 54 XFLIP +Pos 1 1 EMPTY +Pos 1 0 FULL +Pos 0 1 FULL + +#inside corner bottom-left +Index 48 XFLIP +Pos 1 -1 EMPTY +Pos 1 0 FULL +Pos 0 -1 FULL + +#inside corner bottom-right +Index 48 +Pos -1 -1 EMPTY +Pos -1 0 FULL +Pos 0 -1 FULL + +#right bottom +Index 22 +Pos -1 0 EMPTY +Pos -1 1 FULL +Pos 0 1 FULL + +#left bottom +Index 22 XFLIP +Pos 1 0 EMPTY +Pos 1 1 FULL +Pos 0 1 FULL + +#top corner right 2 +Index 33 +Pos 0 -1 EMPTY +Pos 1 0 EMPTY +Pos 1 1 FULL + +#top corner left 2 +Index 32 +Pos 0 -1 EMPTY +Pos -1 0 EMPTY +Pos -1 1 FULL + +[Jungle dark] +Index 13 +BaseTile + +#random bricks +Index 42 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 43 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 44 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 + +Index 45 +Pos 0 1 FULL +Pos 0 -1 FULL +Pos 1 0 FULL +Pos -1 0 FULL +Random 150 +#--------- + +#top +Index 26 +Pos 0 -1 EMPTY + +#right +Index 25 +Pos 1 0 EMPTY + +#bottom +Index 10 +Pos 0 1 EMPTY + +#left +Index 24 +Pos -1 0 EMPTY + +#corner top-right +Index 9 +Pos 0 -1 EMPTY +Pos 1 0 EMPTY + +#corner top-left +Index 8 +Pos 0 -1 EMPTY +Pos -1 0 EMPTY + +#corner bottom-left +Index 40 +Pos 0 1 EMPTY +Pos -1 0 EMPTY + +#corner bottom-right +Index 41 +Pos 0 1 EMPTY +Pos 1 0 EMPTY + +#inside corner top-right +Index 12 +Pos -1 1 EMPTY +Pos -1 0 FULL +Pos 0 1 FULL + +#inside corner top-left +Index 11 +Pos 1 1 EMPTY +Pos 1 0 FULL +Pos 0 1 FULL + +#inside corner bottom-left +Index 27 +Pos 1 -1 EMPTY +Pos 1 0 FULL +Pos 0 -1 FULL + +#inside corner bottom-right +Index 28 +Pos -1 -1 EMPTY +Pos -1 0 FULL +Pos 0 -1 FULL diff --git a/data/editor/winter_main.rules b/data/editor/winter_main.rules new file mode 100644 index 000000000..eaeaec8e3 --- /dev/null +++ b/data/editor/winter_main.rules @@ -0,0 +1,177 @@ +[Winter] +Index 1 +BaseTile + +#top +Index 17 +Pos 0 -1 EMPTY + +Index 18 +Pos 0 -1 EMPTY +Pos -1 0 INDEX 17 + +Index 19 +Pos 0 -1 EMPTY +Pos -1 0 INDEX 18 + +#bottom +Index 97 +Pos 0 1 EMPTY + +Index 98 +Pos 0 1 EMPTY +Pos -1 0 INDEX 97 + +Index 99 +Pos 0 1 EMPTY +Pos -1 0 INDEX 98 + +#right +Index 2 XFLIP +Pos 1 0 EMPTY + +#left +Index 2 +Pos -1 0 EMPTY + +#corner top right +Index 20 +Pos 0 -1 EMPTY +Pos 1 0 EMPTY + +Index 24 +Pos 0 -1 EMPTY +Pos 1 0 EMPTY +Pos -1 0 INDEX 17 + +#corner top left +Index 16 +Pos 0 -1 EMPTY +Pos -1 0 EMPTY + +#corner bottom right +Index 100 +Pos 0 1 EMPTY +Pos 1 0 EMPTY + +#corner bottom left +Index 96 +Pos 0 1 EMPTY +Pos -1 0 EMPTY + +#inside corner top right +Index 8 +Pos 0 1 FULL +Pos -1 0 FULL +Pos -1 1 EMPTY + +#inside corner top left +Index 7 +Pos 0 1 FULL +Pos 1 0 FULL +Pos 1 1 EMPTY + +#inside corner bottom right +Index 4 +Pos 0 -1 FULL +Pos -1 0 FULL +Pos -1 -1 EMPTY + +#inside corner bottom left +Index 3 +Pos 0 -1 FULL +Pos 1 0 FULL +Pos 1 -1 EMPTY + +#one tile height +Index 113 +Pos 0 1 EMPTY +Pos 0 -1 EMPTY + +Index 114 +Pos 0 1 EMPTY +Pos 0 -1 EMPTY +Pos -1 0 INDEX 113 + +Index 115 +Pos 0 1 EMPTY +Pos 0 -1 EMPTY +Pos -1 0 INDEX 114 + +#one tile height right +Index 116 +Pos 0 1 EMPTY +Pos 0 -1 EMPTY +Pos 1 0 EMPTY + +Index 120 +Pos 0 1 EMPTY +Pos 0 -1 EMPTY +Pos 1 0 EMPTY +Pos -1 0 INDEX 113 + +#one tile height left +Index 112 +Pos 0 1 EMPTY +Pos 0 -1 EMPTY +Pos -1 0 EMPTY + +#one tile height link right +Index 6 +Pos -1 -1 EMPTY +Pos -1 0 FULL +Pos 0 -1 FULL +Pos -1 1 EMPTY + +#one tile height link left +Index 5 +Pos 1 -1 EMPTY +Pos 1 0 FULL +Pos 0 -1 FULL +Pos 1 1 EMPTY + +[Winter dark] +Index 177 +BaseTile + +#bottom +Index 194 +Pos 0 1 EMPTY + +Index 195 +Pos 0 1 EMPTY +Pos -1 0 INDEX 194 + +Index 196 +Pos 0 1 EMPTY +Pos -1 0 INDEX 195 + +#right +Index 178 XFLIP +Pos 1 0 EMPTY + +#left +Index 178 +Pos -1 0 EMPTY + +#corner bottom right +Index 197 +Pos 0 1 EMPTY +Pos 1 0 EMPTY + +#corner bottom left +Index 193 +Pos 0 1 EMPTY +Pos -1 0 EMPTY + +#inside corner top right +Index 180 +Pos 0 1 FULL +Pos -1 0 FULL +Pos -1 1 EMPTY + +#inside corner top left +Index 179 +Pos 0 1 FULL +Pos 1 0 FULL +Pos 1 1 EMPTY diff --git a/src/game/editor/auto_map.cpp b/src/game/editor/auto_map.cpp new file mode 100644 index 000000000..528e459bf --- /dev/null +++ b/src/game/editor/auto_map.cpp @@ -0,0 +1,202 @@ +#include // sscanf + +#include +#include +#include + +#include "auto_map.h" +#include "editor.h" + +CAutoMapper::CAutoMapper(CEditor *pEditor) +{ + m_pEditor = pEditor; + m_FileLoaded = false; +} + +void CAutoMapper::Load(const char* pTileName) +{ + char aPath[256]; + str_format(aPath, sizeof(aPath), "editor/%s.rules", pTileName); + IOHANDLE RulesFile = m_pEditor->Storage()->OpenFile(aPath, IOFLAG_READ, IStorage::TYPE_ALL); + if(!RulesFile) + return; + + CLineReader LineReader; + LineReader.Init(RulesFile); + + CConfiguration *pCurrentConf = 0; + CIndexRule *pCurrentIndex = 0; + + char aBuf[256]; + + // read each line + while(char *pLine = LineReader.Get()) + { + // skip blank/empty lines as well as comments + if(str_length(pLine) > 0 && pLine[0] != '#' && pLine[0] != '\n' && pLine[0] != '\r' + && pLine[0] != '\t' && pLine[0] != '\v' && pLine[0] != ' ') + { + if(pLine[0]== '[') + { + // new configuration, get the name + pLine++; + + CConfiguration NewConf; + int ID = m_lConfigs.add(NewConf); + pCurrentConf = &m_lConfigs[ID]; + + str_copy(pCurrentConf->m_aName, pLine, str_length(pLine)); + } + else + { + if(!str_comp_num(pLine, "Index", 5)) + { + // new index + int ID = 0; + char aFlip[128] = ""; + + sscanf(pLine, "Index %d %127s", &ID, aFlip); + + CIndexRule NewIndexRule; + NewIndexRule.m_ID = ID; + NewIndexRule.m_Flag = 0; + NewIndexRule.m_RandomValue = 0; + NewIndexRule.m_BaseTile = false; + + if(str_length(aFlip) > 0) + { + if(!str_comp(aFlip, "XFLIP")) + NewIndexRule.m_Flag = TILEFLAG_VFLIP; + else if(!str_comp(aFlip, "YFLIP")) + NewIndexRule.m_Flag = TILEFLAG_HFLIP; + } + + // add the index rule object and make it current + int ArrayID = pCurrentConf->m_aIndexRules.add(NewIndexRule); + pCurrentIndex = &pCurrentConf->m_aIndexRules[ArrayID]; + } + else if(!str_comp_num(pLine, "BaseTile", 8) && pCurrentIndex) + { + pCurrentIndex->m_BaseTile = true; + } + else if(!str_comp_num(pLine, "Pos", 3) && pCurrentIndex) + { + int x = 0, y = 0; + char aValue[128]; + int Value = CPosRule::EMPTY; + bool IndexValue = false; + + sscanf(pLine, "Pos %d %d %127s", &x, &y, aValue); + + if(!str_comp(aValue, "FULL")) + Value = CPosRule::FULL; + else if(!str_comp_num(aValue, "INDEX", 5)) + { + sscanf(pLine, "Pos %*d %*d INDEX %d", &Value); + IndexValue = true; + } + + CPosRule NewPosRule = {x, y, Value, IndexValue}; + pCurrentIndex->m_aRules.add(NewPosRule); + } + else if(!str_comp_num(pLine, "Random", 6) && pCurrentIndex) + { + sscanf(pLine, "Random %d", &pCurrentIndex->m_RandomValue); + } + } + } + } + + io_close(RulesFile); + + str_format(aBuf, sizeof(aBuf),"loaded %s", aPath); + m_pEditor->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "editor", aBuf); + + m_FileLoaded = true; +} + +const char* CAutoMapper::GetConfigName(int Index) +{ + if(Index < 0 || Index >= m_lConfigs.size()) + return ""; + + return m_lConfigs[Index].m_aName; +} + +void CAutoMapper::Proceed(CLayerTiles *pLayer, int ConfigID) +{ + if(!m_FileLoaded || pLayer->m_Readonly || ConfigID < 0 || ConfigID >= m_lConfigs.size()) + return; + + CConfiguration *pConf = &m_lConfigs[ConfigID]; + + if(!pConf->m_aIndexRules.size()) + return; + + int BaseTile = 1; + + // find base tile if there is one + for(int i = 0; i < pConf->m_aIndexRules.size(); ++i) + { + if(pConf->m_aIndexRules[i].m_BaseTile) + { + BaseTile = pConf->m_aIndexRules[i].m_ID; + break; + } + } + + // auto map ! + int MaxIndex = pLayer->m_Width*pLayer->m_Height; + for(int y = 0; y < pLayer->m_Height; y++) + for(int x = 0; x < pLayer->m_Width; x++) + { + CTile *pTile = &(pLayer->m_pTiles[y*pLayer->m_Width+x]); + if(pTile->m_Index == 0) + continue; + + pTile->m_Index = BaseTile; + m_pEditor->m_Map.m_Modified = true; + + if(y == 0 || y == pLayer->m_Height-1 || x == 0 || x == pLayer->m_Width-1) + continue; + + for(int i = 0; i < pConf->m_aIndexRules.size(); ++i) + { + if(pConf->m_aIndexRules[i].m_BaseTile) + continue; + + bool RespectRules = true; + for(int j = 0; j < pConf->m_aIndexRules[i].m_aRules.size() && RespectRules; ++j) + { + CPosRule *pRule = &pConf->m_aIndexRules[i].m_aRules[j]; + int CheckIndex = (y+pRule->m_Y)*pLayer->m_Width+(x+pRule->m_X); + + if(CheckIndex < 0 || CheckIndex >= MaxIndex) + RespectRules = false; + else + { + if(pRule->m_IndexValue) + { + if(pLayer->m_pTiles[CheckIndex].m_Index != pRule->m_Value) + RespectRules = false; + } + else + { + if(pLayer->m_pTiles[CheckIndex].m_Index > 0 && pRule->m_Value == CPosRule::EMPTY) + RespectRules = false; + + if(pLayer->m_pTiles[CheckIndex].m_Index == 0 && pRule->m_Value == CPosRule::FULL) + RespectRules = false; + } + } + } + + if(RespectRules && + (pConf->m_aIndexRules[i].m_RandomValue <= 1 || (int)((float)rand() / ((float)RAND_MAX + 1) * pConf->m_aIndexRules[i].m_RandomValue) == 1)) + { + pTile->m_Index = pConf->m_aIndexRules[i].m_ID; + pTile->m_Flags = pConf->m_aIndexRules[i].m_Flag; + } + } + } +} diff --git a/src/game/editor/auto_map.h b/src/game/editor/auto_map.h new file mode 100644 index 000000000..4f4cf92ee --- /dev/null +++ b/src/game/editor/auto_map.h @@ -0,0 +1,54 @@ +#ifndef GAME_EDITOR_ED_AUTO_MAP_H +#define GAME_EDITOR_ED_AUTO_MAP_H + +#include + +class CAutoMapper +{ + struct CPosRule + { + int m_X; + int m_Y; + int m_Value; + bool m_IndexValue; + + enum + { + EMPTY=0, + FULL + }; + }; + + struct CIndexRule + { + int m_ID; + array m_aRules; + int m_Flag; + int m_RandomValue; + bool m_BaseTile; + }; + + struct CConfiguration + { + array m_aIndexRules; + char m_aName[128]; + }; + +public: + CAutoMapper(class CEditor *pEditor); + + void Load(const char* pTileName); + void Proceed(class CLayerTiles *pLayer, int ConfigID); + + int ConfigNamesNum() { return m_lConfigs.size(); } + const char* GetConfigName(int Index); + + const bool IsLoaded() { return m_FileLoaded; } +private: + array m_lConfigs; + class CEditor *m_pEditor; + bool m_FileLoaded; +}; + + +#endif diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index bc00c4a2a..907552dca 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -8,20 +8,20 @@ #include #include #include -#include #include #include #include +#include -#include #include +#include +#include #include +#include #include +#include "auto_map.h" #include "editor.h" -#include - -#include int CEditor::ms_CheckerTexture; int CEditor::ms_BackgroundTexture; @@ -1899,6 +1899,7 @@ void CEditor::ReplaceImage(const char *pFileName, int StorageType, void *pUser) *pImg = ImgInfo; pImg->m_External = External; pEditor->ExtractName(pFileName, pImg->m_aName, sizeof(pImg->m_aName)); + pImg->m_AutoMapper.Load(pImg->m_aName); pImg->m_TexID = pEditor->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, CImageInfo::FORMAT_AUTO, 0); pEditor->SortImages(); for(int i = 0; i < pEditor->m_Map.m_lImages.size(); ++i) @@ -1930,6 +1931,7 @@ void CEditor::AddImage(const char *pFileName, int StorageType, void *pUser) pImg->m_TexID = pEditor->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, CImageInfo::FORMAT_AUTO, 0); pImg->m_External = 1; // external by default str_copy(pImg->m_aName, aBuf, sizeof(pImg->m_aName)); + pImg->m_AutoMapper.Load(pImg->m_aName); pEditor->m_Map.m_lImages.add(pImg); pEditor->SortImages(); if(pEditor->m_SelectedImage > -1 && pEditor->m_SelectedImage < pEditor->m_Map.m_lImages.size()) diff --git a/src/game/editor/editor.h b/src/game/editor/editor.h index c77799547..353b07743 100644 --- a/src/game/editor/editor.h +++ b/src/game/editor/editor.h @@ -3,23 +3,26 @@ #ifndef GAME_EDITOR_EDITOR_H #define GAME_EDITOR_EDITOR_H -#include +#include + #include -#include +#include + #include +#include #include #include -#include +#include #include #include -#include #include +#include #include #include -#include +#include "auto_map.h" typedef void (*INDEX_MODIFY_FUNC)(int *pIndex); @@ -230,6 +233,7 @@ public: CEditor *m_pEditor; CEditorImage(CEditor *pEditor) + : m_AutoMapper(pEditor) { m_pEditor = pEditor; m_TexID = -1; @@ -249,6 +253,7 @@ public: int m_External; char m_aName[128]; unsigned char m_aTileFlags[256]; + class CAutoMapper m_AutoMapper; }; class CEditorMap @@ -684,6 +689,7 @@ public: static int PopupSelectGametileOp(CEditor *pEditor, CUIRect View); static int PopupImage(CEditor *pEditor, CUIRect View); static int PopupMenuFile(CEditor *pEditor, CUIRect View); + static int PopupSelectConfigAutoMap(CEditor *pEditor, CUIRect View); static void CallbackOpenMap(const char *pFileName, int StorageType, void *pUser); static void CallbackAppendMap(const char *pFileName, int StorageType, void *pUser); @@ -694,6 +700,9 @@ public: void PopupSelectGametileOpInvoke(float x, float y); int PopupSelectGameTileOpResult(); + + void PopupSelectConfigAutoMapInvoke(float x, float y); + int PopupSelectConfigAutoMapResult(); vec4 ButtonColorMul(const void *pID); diff --git a/src/game/editor/io.cpp b/src/game/editor/io.cpp index 7207e49fe..987404b8a 100644 --- a/src/game/editor/io.cpp +++ b/src/game/editor/io.cpp @@ -449,6 +449,9 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int Storag if(pName) str_copy(pImg->m_aName, pName, 128); + // load auto mapper file + pImg->m_AutoMapper.Load(pImg->m_aName); + m_lImages.add(pImg); // unload image diff --git a/src/game/editor/layer_tiles.cpp b/src/game/editor/layer_tiles.cpp index b792eda96..81944636a 100644 --- a/src/game/editor/layer_tiles.cpp +++ b/src/game/editor/layer_tiles.cpp @@ -360,14 +360,32 @@ void CLayerTiles::ShowInfo() int CLayerTiles::RenderProperties(CUIRect *pToolBox) { CUIRect Button; - pToolBox->HSplitBottom(12.0f, pToolBox, &Button); - + bool InGameGroup = !find_linear(m_pEditor->m_Map.m_pGameGroup->m_lLayers.all(), this).empty(); - if(m_pEditor->m_Map.m_pGameLayer == this) + if(m_pEditor->m_Map.m_pGameLayer != this) + { + if(m_Image >= 0 && m_Image < m_pEditor->m_Map.m_lImages.size() && m_pEditor->m_Map.m_lImages[m_Image]->m_AutoMapper.IsLoaded()) + { + static int s_AutoMapperButton = 0; + pToolBox->HSplitBottom(12.0f, pToolBox, &Button); + if(m_pEditor->DoButton_Editor(&s_AutoMapperButton, "Auto map", 0, &Button, 0, "")) + m_pEditor->PopupSelectConfigAutoMapInvoke(m_pEditor->UI()->MouseX(), m_pEditor->UI()->MouseY()); + + int Result = m_pEditor->PopupSelectConfigAutoMapResult(); + if(Result > -1) + { + m_pEditor->m_Map.m_lImages[m_Image]->m_AutoMapper.Proceed(this, Result); + return 1; + } + } + } + else InGameGroup = false; if(InGameGroup) { + pToolBox->HSplitBottom(2.0f, pToolBox, 0); + pToolBox->HSplitBottom(12.0f, pToolBox, &Button); static int s_ColclButton = 0; if(m_pEditor->DoButton_Editor(&s_ColclButton, "Game tiles", 0, &Button, 0, "Constructs game tiles from this layer")) m_pEditor->PopupSelectGametileOpInvoke(m_pEditor->UI()->MouseX(), m_pEditor->UI()->MouseY()); diff --git a/src/game/editor/popups.cpp b/src/game/editor/popups.cpp index 3ae29725e..0a691fdff 100644 --- a/src/game/editor/popups.cpp +++ b/src/game/editor/popups.cpp @@ -1,10 +1,14 @@ /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ /* If you are missing that file, acquire a complete release at teeworlds.com. */ + +#include + #include #include #include #include #include + #include "editor.h" @@ -737,3 +741,43 @@ int CEditor::PopupSelectGameTileOpResult() s_GametileOpSelected = -1; return Result; } + +static int s_AutoMapConfigSelected = -1; + +int CEditor::PopupSelectConfigAutoMap(CEditor *pEditor, CUIRect View) +{ + CLayerTiles *pLayer = static_cast(pEditor->GetSelectedLayer(0)); + CUIRect Button; + static int s_AutoMapperConfigButtons[256]; + CAutoMapper *pAutoMapper = &pEditor->m_Map.m_lImages[pLayer->m_Image]->m_AutoMapper; + + for(int i = 0; i < pAutoMapper->ConfigNamesNum(); ++i) + { + View.HSplitTop(2.0f, 0, &View); + View.HSplitTop(12.0f, &Button, &View); + if(pEditor->DoButton_Editor(&s_AutoMapperConfigButtons[i], pAutoMapper->GetConfigName(i), 0, &Button, 0, 0)) + s_AutoMapConfigSelected = i; + } + + return 0; +} + +void CEditor::PopupSelectConfigAutoMapInvoke(float x, float y) +{ + static int s_AutoMapConfigSelectID = 0; + s_AutoMapConfigSelected = -1; + CLayerTiles *pLayer = static_cast(GetSelectedLayer(0)); + if(pLayer && pLayer->m_Image >= 0 && pLayer->m_Image < m_Map.m_lImages.size() && + m_Map.m_lImages[pLayer->m_Image]->m_AutoMapper.ConfigNamesNum()) + UiInvokePopupMenu(&s_AutoMapConfigSelectID, 0, x, y, 120.0f, 12.0f+14.0f*m_Map.m_lImages[pLayer->m_Image]->m_AutoMapper.ConfigNamesNum(), PopupSelectConfigAutoMap); +} + +int CEditor::PopupSelectConfigAutoMapResult() +{ + if(s_AutoMapConfigSelected < 0) + return -1; + + int Result = s_AutoMapConfigSelected; + s_AutoMapConfigSelected = -1; + return Result; +}