OpenXcom Forum
Contributions => Programming => Topic started by: davide on July 16, 2014, 07:05:35 pm
-
I have this doubt on
BattlescapeGenerator::generateMap() [at line 1283]
int maxLarge = _terrain->getLargeBlockLimit();
int curLarge = 0;
int tries = 0;
while (curLarge != maxLarge && tries <= 50)
{
int randX = RNG::generate(0, (_mapsize_x/10)- 2);
int randY = RNG::generate(0, (_mapsize_y/10)- 2);
if (
!blocks[randX][randY]
&& !blocks[randX + 1][randY]
&& !blocks[randX + 1][randY + 1]
&& !blocks[randX][randY + 1]
&& !landingzone[randX][randY]
&& !landingzone[randX + 1][randY]
&& !landingzone[randX][randY + 1]
&& !landingzone[randX + 1][randY + 1])
{
blocks[randX][randY] = _terrain->getRandomMapBlock(20, MT_DEFAULT, true);
blocksToDo--;
https:// mark mapblocks as used
blocks[randX + 1][randY] = dummy;
blocksToDo--;
blocks[randX + 1][randY + 1] = dummy;
blocksToDo--;
blocks[randX][randY + 1] = dummy;
blocksToDo--;
curLarge++;
}
tries++;
}
Only Maps of square size 20 are found by this line:
_terrain->getRandomMapBlock(20, MT_DEFAULT, true);
Is it right ?
May I fix it ?
I plan to add some position constraints on map block selection and the code is the same
-
just wait, we have to change up a bunch of stuff in the map generator for tftd anyway.
-
may I help ?
As you know I am interesting to TFTD too and I analized its terrains:
- Islands has a constraint on left maps:a group of maps has sea waves
- Port has a constraint on bottom maps: a group of maps has docks
- "Alien base landing (level 1)" has constraint on all maps
- "Crashed Plane" has constraints on central maps for connect segmented part of airplane
- Cruiser/Cargo Ship have huge rectangle maps
Some other very skilled people are interesting to use these features on modding.
I can follow your additional requirements/needs too if you have time to involve me.
-
while I am waiting with patience some feedback about my request
I will explain what I want to make:
MapBlock entity has a new attribute odds to reduce probability to choose a maps
(it is the opposite of frequency)
RuleTerrain entity has new attribute such as original largeBlockLimit it was the max number of maps of size 20x20
in mine proposal it drive maps of size 20x10 and 10x20 too
I would add new attribute
_largeBlockLimit30to40 to set the max number of rectangular maps that have at least one dimension equal to 30 or 40
(10x30, 30x30, 40x10, 40x20, and so on)
I would add new attribute
_largeBlockLimit50orMore to set the max number of rectangular maps that have at least one dimension greater or equal to 50
(50x20, 60x60, 30x50 TFTD ships, 30x70, and so on)
the original source code fragment ,
to support rectangular any sized maps,
in my opinion,
could be update to:
int maxNum = _terrain->getLargeBlockLimit50orMore();
if(maxNum)
AddMaps( _terrain, _mapsize_x, _mapsize_y, 50, 200, maxNum, blocks, landingzone, dummy, blocksToDo);
maxNum = _terrain->getLargeBlockLimit30to40();
if(maxNum)
AddMaps( _terrain, _mapsize_x, _mapsize_y, 30, 40, maxNum, blocks, landingzone, dummy, blocksToDo);
maxNum = _terrain->getLargeBlockLimit10to20();
AddMaps( _terrain, _mapsize_x, _mapsize_y, 10, 20, maxNum, blocks, landingzone, dummy, blocksToDo);
where AddMaps was the core algorithm updated:
void AddMaps
(
RuleTerrain* _terrain, int _mapsize_x, int _mapsize_y,
int minDim, int maxDim, int maxNum,
std::vector< std::vector<MapBlock*> > & blocks, std::vector< std::vector<bool> > & landingzone,
MapBlock* dummy, int& blocksToDo
)
{
int curNum = 0;
int tries = 0;
while (curNum != maxNum && tries <= 50)
{
MapBlock* m = _terrain->getRandomMapBlock(minDim, maxDim, MT_DEFAULT);
if(!m) return;
int mx = (m->getSizeX() / 10);
int my = (m->getSizeY() / 10);
int randX = RNG::generate(0, (_mapsize_x/10) - mx);
int randY = RNG::generate(0, (_mapsize_y/10) - my);
if (
IsFree(blocks, randX, randY, mx, my) &&
IsFree(landingzone, randX, randY, mx, my)
)
{
AddMap(blocks, randX, randY, mx, my, m, dummy, blocksToDo);
curNum++;
}
tries++;
}
}
and minor functions are
bool IsFree(const std::vector< std::vector<MapBlock*> > & blk, int x, int y, int mx, int my)
{
for (int i = x; i < x+mx; i++)
{
for (int j = y; j < y+my; j++)
{
if (blk[i][j])
return false;
}
}
return true;
}
bool IsFree(std::vector< std::vector<bool> > & landingzone, int x, int y, int mx, int my)
{
for (int i = x; i < x+mx; i++)
{
for (int j = y; j < y+my; j++)
{
if (landingzone[i][j])
return false;
}
}
return true;
}
void AddMap(std::vector< std::vector<MapBlock*> > & blk, int x, int y, int mx, int my, MapBlock* m, MapBlock* dummy, int& blocksToDo)
{
for (int i = x; i < x+mx; i++)
{
for (int j = y; j < y+my; j++)
{
blk[i][j] = dummy;
blocksToDo--;
}
}
blk[x][y] = m;
if (m->getType() == MT_DEFAULT)
m->markUsed();
}
and
MapBlock* RuleTerrain::getRandomMapBlock(int minsize, int maxsize, MapBlockType type)
{
std::vector<MapBlock*> compliantMapBlocks;
for (std::vector<MapBlock*>::const_iterator i = _mapBlocks.begin(); i != _mapBlocks.end(); ++i)
{
if (
(*i)->getSizeX() <= maxsize && (*i)->getSizeX() >= minsize &&
(*i)->getSizeY() <= maxsize && (*i)->getSizeY() >= minsize &&
(
(*i)->getSizeX() > minsize || (*i)->getSizeY() > minsize
) &&
((*i)->getType() == type || (*i)->getSubType() == type)
)
{
int odds = RNG::generate(0,99);
if ((*i)->getOdds() > odds)
{
for (int j = 0; j != (*i)->getRemainingUses(); ++j)
{
compliantMapBlocks.push_back((*i));
}
}
}
}
if (compliantMapBlocks.empty()) return 0;
size_t n = RNG::generate(0, compliantMapBlocks.size() - 1);
return compliantMapBlocks[n];
}
-
I add some bugs fix