OpenXcom Forum
Modding => Help => Topic started by: robin on November 13, 2020, 10:24:39 pm
-
is it possible to make roads with large (20x20 tiles) map blocks?
anyone tried?
thanks
-
no, only 10x10
-
i see thanks.
-
no, only 10x10
... BattlescapeGenerator::addLine ... ???
it is difficult ... but perhaps with a great effort it can be done ? ::)
-
it is difficult ... but perhaps with a great effort it can be done ? ::)
of course, nobody is stopping you
-
To be honest... I don't think it is a good idea after all.
For example, what happens when the map is 50x50? Do the maps at the edge get cut in half? Not good.
I would need to go up to 60x60 map size, which IMO is too big and I don't want to.
-
robin, it's possible but it's not easy.
You need to first use 'addLine' to place 10x10 blocks, and then use checkBlock/removeBlock/addBlock to check the entire map and replace the 10x10s with 20x20s. And that would require a 60x60 map, because with a 50x50 then you'd also need 10x20 or 20x10 blocks and more scripting.
-
robin, it's possible but it's not easy.
You need to first use 'addLine' to place 10x10 blocks, and then use checkBlock/removeBlock/addBlock to check the entire map and replace the 10x10s with 20x20s. And that would require a 60x60 map, because with a 50x50 then you'd also need 10x20 or 20x10 blocks and more scripting.
yeah I thought about scripting it but I'd like to avoid doing it. I'll settle for something more conventional
-
Another option would be to use a normal addLine command with 10x10 blocks, but those blocks are only say one side of the road, then use checkBlock to find the line and fillArea+conditionals+rects to place 10x10 blocks that are the other half of the road.
-
Another option would be to use a normal addLine command with 10x10 blocks, but those blocks are only say one side of the road, then use checkBlock to find the line and fillArea+conditionals+rects to place 10x10 blocks that are the other half of the road.
Actually I was assuming that the addLine function source code could be improved to work with maps larger than 10x10 but homogeneous in the line (20x20 or 10x20 or 20x10)
/**
* draws a line along the map either horizontally, vertically or both.
* @param direction the direction to draw the line
* @param rects the positions to allow the line to be drawn in.
* @return if the blocks were added or not.
*/
bool BattlescapeGenerator::addLine(MapDirection direction, const std::vector<SDL_Rect*> *rects, RuleTerrain *terrain, int verticalGroup, int horizontalGroup, int crossingGroup)
{
if (direction == MD_BOTH)
{
if (addLine(MD_VERTICAL, rects, terrain, verticalGroup, horizontalGroup, crossingGroup))
{
addLine(MD_HORIZONTAL, rects, terrain, verticalGroup, horizontalGroup, crossingGroup);
return true;
}
return false;
}
int tries = 0;
bool placed = false;
int roadX, roadY = 0;
int *iteratorValue = &roadX;
int comparator = verticalGroup;
int typeToAdd = horizontalGroup;
int limit = _mapsize_x / 10;
if (direction == MD_VERTICAL)
{
iteratorValue = &roadY;
comparator = horizontalGroup;
typeToAdd = verticalGroup;
limit = _mapsize_y / 10;
}
while (!placed)
{
placed = selectPosition(rects, roadX, roadY, 10, 10);
for (*iteratorValue = 0; *iteratorValue < limit; *iteratorValue += 1)
{
if (placed && _blocks[roadX][roadY] != 0 && _blocks[roadX][roadY]->isInGroup(comparator) == false)
{
placed = false;
break;
}
}
if (tries++ > 20)
{
return false;
}
}
*iteratorValue = 0;
while (*iteratorValue < limit)
{
if (_blocks[roadX][roadY] == 0)
{
addBlock(roadX, roadY, terrain->getRandomMapBlock(10, 10, typeToAdd), terrain);
SDL_Rect blockRect;
blockRect.x = roadX;
blockRect.y = roadY;
blockRect.w = 1;
blockRect.h = 1;
// Only add unique positions for loading vertical levels
auto it = std::find_if(_placedBlockRects.begin(), _placedBlockRects.end(), [&](const SDL_Rect& rect) { return rect.x == roadX && rect.y == roadY; });
if (it == _placedBlockRects.end())
{
_placedBlockRects.push_back(blockRect);
}
}
else if (_blocks[roadX][roadY]->isInGroup(comparator))
{
_blocks[roadX][roadY] = terrain->getRandomMapBlock(10, 10, crossingGroup);
clearModule(roadX * 10, roadY * 10, 10, 10);
int terrainMapDataSetIDOffset = loadExtraTerrain(terrain);
loadMAP(_blocks[roadX][roadY], roadX * 10, roadY * 10, 0, terrain, terrainMapDataSetIDOffset);
SDL_Rect blockRect;
blockRect.x = roadX;
blockRect.y = roadY;
blockRect.w = 1;
blockRect.h = 1;
// Only add unique positions for loading vertical levels
auto it = std::find_if(_placedBlockRects.begin(), _placedBlockRects.end(), [&](const SDL_Rect& rect) { return rect.x == roadX && rect.y == roadY; });
if (it == _placedBlockRects.end())
{
_placedBlockRects.push_back(blockRect);
}
}
*iteratorValue += 1;
}
return true;
}
-
I tried, and it even worked, but only for straight lines. Dealing with crossing involves much more case handling, I gave up in the end. :(
-
I tried, and it even worked, but only for straight lines. Dealing with crossing involves much more case handling, I gave up in the end. :(
As brainstorm:
Addline with crossing allows only 10x10 maps, AddLine2 could add line of maps of different size (but equal) but it does not allow crossing