Merge remote-tracking branch 'upstream/master'

master
Ginger88895 2014-02-14 14:15:46 +00:00
commit b0b72a73cd
2 changed files with 86 additions and 74 deletions

View File

@ -2140,28 +2140,24 @@ static bool structClearTile(UWORD x, UWORD y)
return true; return true;
} }
/*find a location near to a structure to start the droid of*/ /* An auxiliary function for std::stable_sort in placeDroid */
static bool comparePlacementPoints(Vector2i a, Vector2i b)
{
return abs(a.x) + abs(a.y) < abs(b.x) + abs(b.y);
}
/* Find a location near to a structure to start the droid of */
bool placeDroid(STRUCTURE *psStructure, UDWORD *droidX, UDWORD *droidY) bool placeDroid(STRUCTURE *psStructure, UDWORD *droidX, UDWORD *droidY)
{ {
SWORD sx,sy, xmin,xmax, ymin,ymax, x,y, xmid;
bool placed;
unsigned sWidth = getStructureWidth(psStructure);
unsigned sBreadth = getStructureBreadth(psStructure);
CHECK_STRUCTURE(psStructure); CHECK_STRUCTURE(psStructure);
/* Get the tile coords for the top left of the structure */
sx = (SWORD)(psStructure->pos.x - sWidth * TILE_UNITS/2);
sx = map_coord(sx);
sy = (SWORD)(psStructure->pos.y - sBreadth * TILE_UNITS/2);
sy = map_coord(sy);
/* Find the four corners of the square */ /* Find the four corners of the square */
xmin = (SWORD)(sx - 1); StructureBounds bounds = getStructureBounds(psStructure);
xmax = (SWORD)(sx + sWidth); int xmin = bounds.map.x - 1;
xmid = (SWORD)(sx + (sWidth-1)/2); int xmax = bounds.map.x + bounds.size.x;
ymin = (SWORD)(sy - 1); int ymin = bounds.map.y - 1;
ymax = (SWORD)(sy + sBreadth); int ymax = bounds.map.y + bounds.size.y;
if (xmin < 0) if (xmin < 0)
{ {
xmin = 0; xmin = 0;
@ -2179,73 +2175,86 @@ bool placeDroid(STRUCTURE *psStructure, UDWORD *droidX, UDWORD *droidY)
ymax = (SWORD)mapHeight; ymax = (SWORD)mapHeight;
} }
/* Look for a clear location for the droid across the bottom */ /* Round direction to nearest 90°. */
/* start in the middle */ uint16_t direction = (psStructure->rot.direction + 0x2000)&0xC000;
placed = false;
y = ymax; /* We sort all adjacent tiles by their Manhattan distance to the
/* middle to right */ target droid exit tile, misplaced by (1/3, 1/4) tiles.
for(x = xmid; x < xmax; x++) Since only whole coordinates are sorted, this makes sure sorting
is deterministic. Target coordinates, multiplied by 12 to eliminate
floats, are stored in (sx, sy). */
int sx, sy;
if (direction == 0x0)
{ {
if (structClearTile(x, y)) sx = 12 * (xmin + 1) + 4;
{ sy = 12 * ymax + 3;
placed = true;
break;
}
} }
/* left to middle */ else if (direction == 0x4000)
if (!placed)
{ {
for(x = xmin; x < xmid; x++) sx = 12 * xmax + 3;
sy = 12 * (ymax - 1) - 4;
}
else if (direction == 0x8000)
{
sx = 12 * (xmax - 1) - 4;
sy = 12 * ymin - 3;
}
else
{
sx = 12 * xmin - 3;
sy = 12 * (ymin + 1) + 4;
}
std::vector<Vector2i> tiles;
for (int x = xmin; x <= xmax; ++x)
{
for (int y = ymin; y <= ymax; ++y)
{ {
if (structClearTile(x, y)) if (structClearTile(x, y))
{ {
placed = true; tiles.push_back(Vector2i(12 * x - sx, 12 * y - sy));
break;
} }
} }
} }
/* across the top */
if (!placed) if (tiles.size() == 0)
{ {
y = ymin; return false;
for(x = xmin; x < xmax; x++)
{
if (structClearTile(x, y))
{
placed = true;
break;
}
}
} }
/* the left */
if (!placed) std::sort(tiles.begin(), tiles.end(), comparePlacementPoints);
/* Store best tile coordinates in (sx, sy),
which are also map coordinates of its north-west corner.
Store world coordinates of this tile's center in (wx, wy) */
sx = (tiles[0].x + sx) / 12;
sy = (tiles[0].y + sy) / 12;
int wx = world_coord(sx) + TILE_UNITS / 2;
int wy = world_coord(sy) + TILE_UNITS / 2;
/* Finally, find world coordinates of the structure point closest to (mx, my).
For simplicity, round to grid vertices. */
if (2 * sx <= xmin + xmax)
{ {
x = xmin; wx += TILE_UNITS / 2;
for(y = ymin; y < ymax; y++)
{
if (structClearTile(x, y))
{
placed = true;
break;
}
}
} }
/* the right */ if (2 * sx >= xmin + xmax)
if (!placed)
{ {
x = xmax; wx -= TILE_UNITS / 2;
for(y = ymin; y < ymax; y++)
{
if (structClearTile(x, y))
{
placed = true;
break;
}
}
} }
*droidX = x; if (2 * sy <= ymin + ymax)
*droidY = y; {
return placed; wy += TILE_UNITS / 2;
}
if (2 * sy >= ymin + ymax)
{
wy -= TILE_UNITS / 2;
}
*droidX = wx;
*droidY = wy;
return true;
} }
/* Place a newly manufactured droid next to a factory and then send if off /* Place a newly manufactured droid next to a factory and then send if off
@ -2271,7 +2280,7 @@ static bool structPlaceDroid(STRUCTURE *psStructure, DROID_TEMPLATE *psTempl, DR
//create a droid near to the structure //create a droid near to the structure
syncDebug("Placing new droid at (%d,%d)", x, y); syncDebug("Placing new droid at (%d,%d)", x, y);
turnOffMultiMsg(true); turnOffMultiMsg(true);
psNewDroid = buildDroid(psTempl, world_coord(x), world_coord(y), psStructure->player, false, &initialOrders); psNewDroid = buildDroid(psTempl, x, y, psStructure->player, false, &initialOrders);
turnOffMultiMsg(false); turnOffMultiMsg(false);
if (!psNewDroid) if (!psNewDroid)
{ {

View File

@ -9,6 +9,9 @@ if len(sys.argv) < 3:
config = ConfigParser.ConfigParser() config = ConfigParser.ConfigParser()
config.read(sys.argv[1]) config.read(sys.argv[1])
def lowcase_first_letter(s):
return s[0].lower() + s[1:]
def is_number(s): def is_number(s):
try: try:
int(s) int(s)
@ -58,20 +61,20 @@ for section in config.sections():
tmp = {} tmp = {}
comps = result.split(':') comps = result.split(':')
if comps[0].isupper(): if comps[0].isupper():
tmp['weaponSubClass'] = comps[0] tmp['filterWeaponSubClass'] = [ comps[0] ]
elif comps[0] in ['Cyborgs', 'Droids', 'Transport']: elif comps[0] in ['Cyborgs', 'Droids', 'Transport']:
tmp['bodyClass'] = comps[0] tmp['filterBodyClass'] = [ comps[0] ]
elif comps[0] in ['Wall', 'Structure', 'Defense']: elif comps[0] in ['Wall', 'Structure', 'Defense']:
tmp['structureType'] = comps[0] tmp['filterStructureType'] = [ comps[0] ]
elif comps[0] in ['RearmPoints', 'ProductionPoints', 'ResearchPoints', 'RepairPoints', 'Sensor', 'ECM', 'PowerPoints', 'Construct']: elif comps[0] in ['RearmPoints', 'ProductionPoints', 'ResearchPoints', 'RepairPoints', 'Sensor', 'ECM', 'PowerPoints', 'Construct']:
pass # affects a global state pass # affects a global state
else: # forgot something... else: # forgot something...
print 'Unknown filter: %s' % comps[0] print 'Unknown filter: %s' % comps[0]
sys.exit(1) sys.exit(1)
if len(comps) > 2: if len(comps) > 2:
tmp[comps[1]] = int(comps[2]) tmp[lowcase_first_letter(comps[1])] = int(comps[2])
else: else:
tmp[comps[0]] = int(comps[1]) tmp[lowcase_first_letter(comps[0])] = int(comps[1])
accum.append(tmp) accum.append(tmp)
entry['results'] = accum entry['results'] = accum
entry['id'] = section # for backwards compatibility entry['id'] = section # for backwards compatibility