where do I find this nice prototype?
On my HDD only at the moment
I'll throw a link here some rainy day (need to fix/finish few things first)... but i'm honestly not sure if it would be
that useful. It's easy to get lost in UI stuff and comments barely exists at this moment, so better to extract the essence of a whole thing if anyone wants. While everything below is in C++, it should be possible to recreate everything in r412 dlls (and maaany older revs), or even ported to scripts.
TL;DR:
-
GetCoords() (
FOHexMap.cs)
-
GetField() (
FOClassic.h/
FOnline.h/
HexManager.h)
-
PrepPoint, PointVec (
SpriteManager.h)
-
DrawPoints() (
SpriteManager.cpp)
We start with small function to deal with hexes. It's simplified version of
GetCoords() - converts hx,hy to 2d space resizing each hex to 2x1, where left part is a place for pixel, and right part is a null space for hexes above/below.
H H H H H
H H H H
H H H H H
void FOC::Hex2D( uint16& hexX, uint16& hexY, uint16 mapWidth )
{
const uint16 hx = hexX, hy = hexY;
Hex2D( hx, hy, hexX, hexY, mapWidth );
}
void FOC::Hex2D( uint16 hexX, uint16 hexY, uint16& x2d, uint16& y2d, uint16 mapWidth )
{
int x = hexY - hexX * 2;
int y = hexY + hexX / 2;
if( hexX > 1 )
x += hexX / 2;
x += mapWidth;
x2d = x;
y2d = y;
}
As any FOnline map should
look like this, after conversion to 2d we have a huge area outside scrollblockers which we need to get rid of.
// define minimap bounds
uint16 minPX = uint16( -1 ), maxPX = 0, minPY = uint16( -1 ), maxPY = 0;
for( uint16 hexX = 0; hexX < mapWidth; hexX++ )
{
for( uint16 hexY = 0; hexY < mapHeight; hexY++ )
{
bool show = false;
uint dummy = 0;
// check if current hex is going to be part of minimap
if( GetHex( hexX, hexY, show, dummy ) && show )
{
// convert hex position to 2d position
uint16 px = hexX, py = hexY;
Hex2D( px, py, mapWidth );
// update bounds
minPX = std::min( minPX, px );
maxPX = std::max( maxPX, px );
minPY = std::min( minPY, py );
maxPY = std::max( maxPY, py );
}
}
}
Here
GetHex() function is checking if there's anything interesting at specified position - will there be pixel placed for current hex or not? At this point it doesn't matter
what it's going to be. For test purposes i checked for scrollblockers, as seen in previous post.
Field* mapField = (Field*)(GameOpt.ClientMap);
// ...
Field& field = mapField[hexY * mapWidth + hexX];
if( field.ScrollBlock )
// ...
Once bounds are set, we process the map one more time and prepare draw data.
// process map
PointVec minimap;
for( uint16 hexX = 0; hexX < mapWidth; hexX++ )
{
for( uint16 hexY = 0; hexY < mapHeight; hexY++ )
{
// convert hex position to 2d position
uint16 px = hexX, py = hexY;
Hex2D( px, py, mapWidth );
// ignore everything outside bounds
if( px < minPX || px > maxPX || py < minPY || py > maxPY )
continue;
bool show = false;
uint color = 0;
if( !GetHex( hexX, hexY, show, color ) || !show )
continue;
// adjust position
px -= minPX;
py -= minPY;
minimap.push_back( PrepPoint( px, py, color ) );
}
}
Here,
GetHex() is used fully and tells if given hex is part of minimap, and if it is - what color should be used for a pixel. In hardcoded minimap, it's done by
FOClient::LmapPrepareMap();
GetHex() does similiar thing, except it works with single hex, and returns info only, without changing anything.
Anyway, once we process whole map, all what's left is to
finally draw a whole thing.
Our BFF now is
SpriteManager::DrawPoint(), which is also used internally after calling
DrawPrimitive() from scripts.
DrawPoints() accepts two tasty arguments, which sadly are not available for scripts in clean r412 -
offset and
zoom. That plus minimap bounds calculated earlier, allows to easily get pixel-size of minimap, resize, and move it around/stick to corner/etc without rebuilding whole thing.
SprMngr.DrawPoints( DRAW_PRIMITIVE_POINTLIST, minimap );
tada.wavObviously, doing all above every cycle is waste of CPU time, as majority of minimap does not change as long sceneries/walls doesn't. So if minimap should include critters/items/any other dynamic elements, they can be put into separate
PointVec (updated every time) which will be drawn after the one with walls.
...wrote waaay more than i initially planned, but oh well. Majority is probably boring/obvious stuff, but maybe some detail would push someone in right direction.