diff --git a/doc/ChangeLog.html b/doc/ChangeLog.html index beaa7275f..ad1dc1e72 100644 --- a/doc/ChangeLog.html +++ b/doc/ChangeLog.html @@ -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). diff --git a/src/include/unit.h b/src/include/unit.h index 3d908d489..4a3012db1 100644 --- a/src/include/unit.h +++ b/src/include/unit.h @@ -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 diff --git a/src/unit/unit.cpp b/src/unit/unit.cpp index 749b76d47..e091802eb 100644 --- a/src/unit/unit.cpp +++ b/src/unit/unit.cpp @@ -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); } /*---------------------------------------------------------------------------- diff --git a/src/video/cursor.cpp b/src/video/cursor.cpp index f3c53fcde..b11b979c6 100644 --- a/src/video/cursor.cpp +++ b/src/video/cursor.cpp @@ -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) {