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;
}
/*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)
{
SWORD sx,sy, xmin,xmax, ymin,ymax, x,y, xmid;
bool placed;
unsigned sWidth = getStructureWidth(psStructure);
unsigned sBreadth = getStructureBreadth(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 */
xmin = (SWORD)(sx - 1);
xmax = (SWORD)(sx + sWidth);
xmid = (SWORD)(sx + (sWidth-1)/2);
ymin = (SWORD)(sy - 1);
ymax = (SWORD)(sy + sBreadth);
StructureBounds bounds = getStructureBounds(psStructure);
int xmin = bounds.map.x - 1;
int xmax = bounds.map.x + bounds.size.x;
int ymin = bounds.map.y - 1;
int ymax = bounds.map.y + bounds.size.y;
if (xmin < 0)
{
xmin = 0;
@ -2179,73 +2175,86 @@ bool placeDroid(STRUCTURE *psStructure, UDWORD *droidX, UDWORD *droidY)
ymax = (SWORD)mapHeight;
}
/* Look for a clear location for the droid across the bottom */
/* start in the middle */
placed = false;
y = ymax;
/* middle to right */
for(x = xmid; x < xmax; x++)
/* Round direction to nearest 90°. */
uint16_t direction = (psStructure->rot.direction + 0x2000)&0xC000;
/* We sort all adjacent tiles by their Manhattan distance to the
target droid exit tile, misplaced by (1/3, 1/4) tiles.
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))
{
placed = true;
break;
}
sx = 12 * (xmin + 1) + 4;
sy = 12 * ymax + 3;
}
/* left to middle */
if (!placed)
else if (direction == 0x4000)
{
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))
{
placed = true;
break;
tiles.push_back(Vector2i(12 * x - sx, 12 * y - sy));
}
}
}
/* across the top */
if (!placed)
if (tiles.size() == 0)
{
y = ymin;
for(x = xmin; x < xmax; x++)
{
if (structClearTile(x, y))
{
placed = true;
break;
}
}
return false;
}
/* 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;
for(y = ymin; y < ymax; y++)
{
if (structClearTile(x, y))
{
placed = true;
break;
}
}
wx += TILE_UNITS / 2;
}
/* the right */
if (!placed)
if (2 * sx >= xmin + xmax)
{
x = xmax;
for(y = ymin; y < ymax; y++)
{
if (structClearTile(x, y))
{
placed = true;
break;
}
}
wx -= TILE_UNITS / 2;
}
*droidX = x;
*droidY = y;
return placed;
if (2 * sy <= ymin + ymax)
{
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
@ -2271,7 +2280,7 @@ static bool structPlaceDroid(STRUCTURE *psStructure, DROID_TEMPLATE *psTempl, DR
//create a droid near to the structure
syncDebug("Placing new droid at (%d,%d)", x, y);
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);
if (!psNewDroid)
{

View File

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