Fixed bug #928568: Oil platform can be built under a ship
This commit is contained in:
parent
d96a2a3add
commit
36de4e7d2a
4 changed files with 52 additions and 131 deletions
|
@ -35,6 +35,7 @@
|
|||
<ul>
|
||||
<li>Future 2.1 Release<p>
|
||||
<ul>
|
||||
<li>Fixed bug #928568: Oil platform can be built under a ship (from Jimmy Salmon).
|
||||
<li>Fixed bug #913100: Stratagus ignores player race (from Jimmy Salmon).
|
||||
<li>Fixed bug #931995: first oil is free (from Jimmy Salmon).
|
||||
<li>Add SetUseHPForXp() in script to replace compile option (from Joris Dauphin).
|
||||
|
|
|
@ -835,7 +835,7 @@ extern void DropOutNearest(Unit* unit, int x, int y, int addx, int addy);
|
|||
extern void DropOutAll(const Unit* unit);
|
||||
|
||||
/// @todo more docu
|
||||
extern int CanBuildHere(const UnitType* type, int x, int y);
|
||||
extern int CanBuildHere(const Unit* unit, const UnitType* type, int x, int y);
|
||||
/// @todo more docu
|
||||
extern int CanBuildOn(int x, int y, int mask);
|
||||
/// FIXME: more docu
|
||||
|
|
|
@ -1976,20 +1976,21 @@ global void DropOutAll(const Unit* source)
|
|||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Building units
|
||||
-- Building units
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
** Can build unit here.
|
||||
** Hall to near to goldmine.
|
||||
** Refinery or shipyard to near to oil patch.
|
||||
** Can build unit here.
|
||||
** Hall to near to goldmine.
|
||||
** Refinery or shipyard to near to oil patch.
|
||||
**
|
||||
** @param type unit-type to be checked.
|
||||
** @param x Map X position.
|
||||
** @param y Map Y position.
|
||||
** @return True if could build here, otherwise false.
|
||||
** @param type unit-type to be checked.
|
||||
** @param x Map X position.
|
||||
** @param y Map Y position.
|
||||
**
|
||||
** @return True if could build here, otherwise false.
|
||||
*/
|
||||
global int CanBuildHere(const UnitType* type, int x, int y)
|
||||
global int CanBuildHere(const Unit* unit, const UnitType* type, int x, int y)
|
||||
{
|
||||
Unit* table[UnitMax];
|
||||
int n;
|
||||
|
@ -1999,7 +2000,7 @@ global int CanBuildHere(const UnitType* type, int x, int y)
|
|||
int found;
|
||||
|
||||
//
|
||||
// Can't build outside the map
|
||||
// Can't build outside the map
|
||||
//
|
||||
if (x + type->TileWidth > TheMap.Width) {
|
||||
return 0;
|
||||
|
@ -2008,33 +2009,12 @@ global int CanBuildHere(const UnitType* type, int x, int y)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (EditorRunning) {
|
||||
if (type->GivesResource == OilCost) {
|
||||
// FIXME: Better ideas? type->OnlyPlaceable on odd tiles? Yuck.
|
||||
// Oil patches and platforms can only be placed on even tiles
|
||||
if (!(x & 1 && y & 1)) {
|
||||
return 0;
|
||||
}
|
||||
n = UnitCacheSelect(x, y, x + type->TileWidth, y + type->TileHeight, table);
|
||||
for (i = 0; i < n; ++i) {
|
||||
if (table[i]->Type->GivesResource == OilCost) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else if (type->UnitType == UnitTypeFly || type->UnitType == UnitTypeNaval) {
|
||||
// Flyers and naval units can only be placed on odd tiles
|
||||
if (x & 1 || y & 1) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Must be checked before oil!
|
||||
if (type->ShoreBuilding) {
|
||||
found = 0;
|
||||
|
||||
DebugLevel3("Shore building\n");
|
||||
// Need atleast one coast tile
|
||||
// Need at least one coast tile
|
||||
for (h = type->TileHeight; h--;) {
|
||||
for (w = type->TileWidth; w--;) {
|
||||
if (TheMap.Fields[x + w + (y + h) * TheMap.Width].Flags &
|
||||
|
@ -2049,7 +2029,7 @@ global int CanBuildHere(const UnitType* type, int x, int y)
|
|||
}
|
||||
}
|
||||
|
||||
// resource deposit can't be build too near to resource
|
||||
// resource deposit can't be build too near to resource
|
||||
// FIXME: (mr-russ) check bound for Select
|
||||
n = UnitCacheSelect(x - RESOURCE_DISTANCE, y - RESOURCE_DISTANCE,
|
||||
x + type->TileWidth + RESOURCE_DISTANCE, y + type->TileHeight + RESOURCE_DISTANCE, table);
|
||||
|
@ -2059,24 +2039,32 @@ global int CanBuildHere(const UnitType* type, int x, int y)
|
|||
}
|
||||
}
|
||||
|
||||
if (type->MustBuildOnTop && !EditorRunning) {
|
||||
// Resource platform could only be build on resource patch.
|
||||
n = UnitCacheSelect(x, y, x + 1, y + 1, table);
|
||||
if (type->MustBuildOnTop) {
|
||||
Unit* target;
|
||||
|
||||
// Resource platform could only be built on resource patch.
|
||||
target = NULL;
|
||||
n = UnitCacheSelect(x, y, x + type->TileWidth, y + type->TileHeight, table);
|
||||
for (i = 0; i < n; ++i) {
|
||||
if (table[i]->Type != type->MustBuildOnTop) {
|
||||
if (table[i] == unit) {
|
||||
continue;
|
||||
}
|
||||
if (table[i]->Type != type->MustBuildOnTop) {
|
||||
return 0;
|
||||
}
|
||||
if (table[i]->Orders[0].Action == UnitActionBuilded) {
|
||||
continue;
|
||||
return 0;
|
||||
}
|
||||
if (table[i]->Destroyed || table[i]->Orders[0].Action == UnitActionDie) {
|
||||
continue;
|
||||
}
|
||||
if (table[i]->X == x && table[i]->Y == y) {
|
||||
return 1;
|
||||
target = table[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (target) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2084,7 +2072,7 @@ global int CanBuildHere(const UnitType* type, int x, int y)
|
|||
}
|
||||
|
||||
/**
|
||||
** Can build on this point.
|
||||
** Can build on this point.
|
||||
*/
|
||||
global int CanBuildOn(int x, int y, int mask)
|
||||
{
|
||||
|
@ -2095,16 +2083,17 @@ global int CanBuildOn(int x, int y, int mask)
|
|||
}
|
||||
|
||||
/**
|
||||
** Can build unit-type on this point.
|
||||
** Can build unit-type on this point.
|
||||
**
|
||||
** @param unit Worker that want to build the building or NULL.
|
||||
** @param type Building unit-type.
|
||||
** @param x X tile map position.
|
||||
** @param y Y tile map position.
|
||||
** @param unit Worker that want to build the building or NULL.
|
||||
** @param type Building unit-type.
|
||||
** @param x X tile map position.
|
||||
** @param y Y tile map position.
|
||||
** @param real Really build, or just placement
|
||||
** @return True if the building could be build..
|
||||
**
|
||||
** @todo can't handle building units !1x1, needs a rewrite.
|
||||
** @return True if the building could be build..
|
||||
**
|
||||
** @todo can't handle building units !1x1, needs a rewrite.
|
||||
*/
|
||||
global int CanBuildUnitType(const Unit* unit, const UnitType* type, int x, int y, int real)
|
||||
{
|
||||
|
@ -2116,15 +2105,13 @@ global int CanBuildUnitType(const Unit* unit, const UnitType* type, int x, int y
|
|||
|
||||
// Terrain Flags don't matter.
|
||||
if (type->MustBuildOnTop) {
|
||||
return CanBuildHere(type, x, y);
|
||||
return CanBuildHere(unit, type, x, y);
|
||||
}
|
||||
|
||||
//
|
||||
// Remove unit that is building!
|
||||
// Remove unit that is building!
|
||||
//
|
||||
#ifdef DEBUG
|
||||
j = 0;
|
||||
#endif
|
||||
if (unit) {
|
||||
// FIXME: This only works with 1x1 big units
|
||||
DebugCheck(unit->Type->TileWidth != 1 || unit->Type->TileHeight != 1);
|
||||
|
@ -2132,81 +2119,6 @@ global int CanBuildUnitType(const Unit* unit, const UnitType* type, int x, int y
|
|||
TheMap.Fields[unit->X + unit->Y * TheMap.Width].Flags &= ~j;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// FIXME: Should be moved into unittype structure, and allow more types.
|
||||
if (type->ShoreBuilding) {
|
||||
mask = MapFieldLandUnit |
|
||||
MapFieldSeaUnit |
|
||||
MapFieldBuilding | // already occuppied
|
||||
MapFieldWall |
|
||||
MapFieldRocks |
|
||||
MapFieldForest | // wall,rock,forest not 100% clear?
|
||||
MapFieldLandAllowed | // can't build on this
|
||||
//MapFieldUnpassable | // FIXME: I think shouldn't be used
|
||||
MapFieldNoBuilding;
|
||||
} else if (type->Building) {
|
||||
switch (type->UnitType) {
|
||||
case UnitTypeLand:
|
||||
mask = MapFieldLandUnit |
|
||||
MapFieldBuilding | // already occuppied
|
||||
MapFieldWall |
|
||||
MapFieldRocks |
|
||||
MapFieldForest | // wall,rock,forest not 100% clear?
|
||||
MapFieldCoastAllowed |
|
||||
MapFieldWaterAllowed | // can't build on this
|
||||
MapFieldUnpassable | // FIXME: I think shouldn't be used
|
||||
MapFieldNoBuilding;
|
||||
break;
|
||||
case UnitTypeNaval:
|
||||
mask = MapFieldSeaUnit |
|
||||
MapFieldBuilding | // already occuppied
|
||||
MapFieldCoastAllowed |
|
||||
MapFieldLandAllowed | // can't build on this
|
||||
MapFieldUnpassable | // FIXME: I think shouldn't be used
|
||||
MapFieldNoBuilding;
|
||||
break;
|
||||
case UnitTypeFly:
|
||||
mask = MapFieldAirUnit; // already occuppied
|
||||
break;
|
||||
default:
|
||||
DebugLevel1Fn("Were moves this unit?\n");
|
||||
if (unit) {
|
||||
TheMap.Fields[unit->X + unit->Y * TheMap.Width].Flags |= j;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
} else switch (type->UnitType) {
|
||||
case UnitTypeLand:
|
||||
mask = MapFieldLandUnit |
|
||||
MapFieldBuilding | // already occuppied
|
||||
MapFieldWall |
|
||||
MapFieldRocks |
|
||||
MapFieldForest | // wall,rock,forest not 100% clear?
|
||||
MapFieldCoastAllowed |
|
||||
MapFieldWaterAllowed | // can't build on this
|
||||
MapFieldUnpassable; // FIXME: I think shouldn't be used
|
||||
break;
|
||||
case UnitTypeNaval:
|
||||
mask = MapFieldSeaUnit |
|
||||
MapFieldBuilding | // already occuppied
|
||||
MapFieldCoastAllowed |
|
||||
MapFieldLandAllowed | // can't build on this
|
||||
MapFieldUnpassable; // FIXME: I think shouldn't be used
|
||||
break;
|
||||
case UnitTypeFly:
|
||||
mask = MapFieldAirUnit; // already occuppied
|
||||
break;
|
||||
default:
|
||||
DebugLevel1Fn("Were moves this unit?\n");
|
||||
if (unit) {
|
||||
TheMap.Fields[unit->X + unit->Y * TheMap.Width].Flags |= j;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
#endif
|
||||
|
||||
player = NULL;
|
||||
|
||||
if (unit && unit->Player->Type == PlayerPerson) {
|
||||
|
@ -2238,7 +2150,7 @@ global int CanBuildUnitType(const Unit* unit, const UnitType* type, int x, int y
|
|||
//
|
||||
// We can build here: check distance to gold mine/oil patch!
|
||||
//
|
||||
return CanBuildHere(type, x, y);
|
||||
return CanBuildHere(unit, type, x, y);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
|
|
|
@ -482,6 +482,7 @@ local void DrawCursor(const CursorType* type, int x, int y, int frame)
|
|||
*/
|
||||
local void DrawBuildingCursor(void)
|
||||
{
|
||||
int i;
|
||||
int x;
|
||||
int y;
|
||||
int mx;
|
||||
|
@ -521,10 +522,17 @@ local void DrawBuildingCursor(void)
|
|||
//
|
||||
// Draw the allow overlay
|
||||
//
|
||||
f = CanBuildHere(CursorBuilding, mx, my);
|
||||
if (NumSelected) {
|
||||
f = 1;
|
||||
for (i = 0; f && i < NumSelected; ++i) {
|
||||
f = CanBuildHere(Selected[i], CursorBuilding, mx, my);
|
||||
}
|
||||
} else {
|
||||
f = CanBuildHere(NoUnitP, CursorBuilding, mx, my);
|
||||
}
|
||||
|
||||
mask = CursorBuilding->MovementMask;
|
||||
h=CursorBuilding->TileHeight;
|
||||
h = CursorBuilding->TileHeight;
|
||||
BuildingCursorEY = my + h - 1;
|
||||
// reduce to view limits
|
||||
if (my + h > vp->MapY + vp->MapHeight) {
|
||||
|
|
Loading…
Reference in a new issue