Author Topic: [PROPOSAL] to extend engine to support terrain map blocks of any rect size  (Read 4351 times)

Offline davide

  • Commander
  • *****
  • Posts: 565
    • View Profile
I have this doubt on

BattlescapeGenerator::generateMap() [at line 1283]

Code: [Select]
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

« Last Edit: September 11, 2014, 03:19:06 pm by davide »

Offline Warboy1982

  • Administrator
  • Commander
  • *****
  • Posts: 2333
  • Developer
    • View Profile
Re: do engine support terrain map block of size over 20x20
« Reply #1 on: July 17, 2014, 03:16:33 am »
just wait, we have to change up a bunch of stuff in the map generator for tftd anyway.

Offline davide

  • Commander
  • *****
  • Posts: 565
    • View Profile
Re: do engine support terrain map block of size over 20x20
« Reply #2 on: July 17, 2014, 10:44:57 am »
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.

« Last Edit: July 18, 2014, 12:41:28 pm by davide »

Offline davide

  • Commander
  • *****
  • Posts: 565
    • View Profile
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:

Code: [Select]
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:

Code: [Select]
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

Code: [Select]
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

Code: [Select]
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];
}

« Last Edit: July 28, 2014, 01:06:40 am by davide »

Offline davide

  • Commander
  • *****
  • Posts: 565
    • View Profile
I add some bugs fix