From 6c801713e696b27960dff0995754a1bd30ac8769 Mon Sep 17 00:00:00 2001 From: jarod42 <> Date: Mon, 25 Oct 2004 16:05:05 +0000 Subject: [PATCH] s/unit->Building/!CanMove(unit) for movement check. Some CleanUp Now resouce and depot can call harvesters with right click. --- src/action/action_attack.cpp | 23 ++---- src/action/action_move.cpp | 27 +++++-- src/action/action_spellcast.cpp | 2 +- src/action/action_still.cpp | 2 +- src/action/command.cpp | 6 +- src/ai/ai.cpp | 3 +- src/ai/ai_plan.cpp | 2 +- src/ai/ai_resource.cpp | 6 +- src/editor/editloop.cpp | 5 +- src/include/unit.h | 4 +- src/ui/botpanel.cpp | 7 +- src/ui/button_checks.cpp | 4 +- src/ui/mainscr.cpp | 13 ++- src/ui/mouse.cpp | 136 ++++++++++++++++++++------------ src/unit/script_unittype.cpp | 2 +- src/unit/unit.cpp | 45 ++++++----- src/unit/unit_draw.cpp | 43 ++-------- 17 files changed, 169 insertions(+), 161 deletions(-) diff --git a/src/action/action_attack.cpp b/src/action/action_attack.cpp index 2bc906295..e3f69b92d 100644 --- a/src/action/action_attack.cpp +++ b/src/action/action_attack.cpp @@ -240,12 +240,12 @@ static void MoveToTarget(Unit* unit) Unit* goal; int err; - if (!unit->Orders[0].Goal) { - if (unit->Orders[0].X == -1 || unit->Orders[0].Y == -1) { - DebugPrint("FIXME: Wrong goal position, check where set!\n"); - unit->Orders[0].X = unit->Orders[0].Y = 0; - } - } + Assert(unit); + Assert(!unit->Type->Vanishes && !unit->Destroyed && !unit->Removed); + Assert(unit->Orders[0].Action == UnitActionAttack || + unit->Orders[0].Action == UnitActionAttackGround); + Assert(CanMove(unit)); + Assert(unit->Orders[0].Goal || (unit->Orders[0].X != -1 && unit->Orders[0].Y != -1)); err = DoActionMove(unit); @@ -330,9 +330,6 @@ static void MoveToTarget(Unit* unit) return; } - Assert(!unit->Type->Vanishes && !unit->Destroyed && !unit->Removed); - Assert(unit->Orders[0].Action == UnitActionAttack || - unit->Orders[0].Action == UnitActionAttackGround); } /** @@ -345,12 +342,8 @@ static void AttackTarget(Unit* unit) Unit* goal; Unit* temp; - if (!unit->Orders[0].Goal) { - if (unit->Orders[0].X == -1 || unit->Orders[0].Y == -1) { - DebugPrint("FIXME: Wrong goal position, check where set!\n"); - unit->Orders[0].X = unit->Orders[0].Y = 0; - } - } + Assert(unit); + Assert(unit->Orders[0].Goal || (unit->Orders[0].X != -1 && unit->Orders[0].Y != -1)); AnimateActionAttack(unit); if (unit->Reset) { diff --git a/src/action/action_move.cpp b/src/action/action_move.cpp index 97edd9744..7b11e7df3 100644 --- a/src/action/action_move.cpp +++ b/src/action/action_move.cpp @@ -181,6 +181,22 @@ static int ActionMoveGeneric(Unit* unit, const Animation* anim) return d; } +/** +** Test if unit can move. +** For the moment only check for move animation. +** +** @param unit unit to test if it can move. +** +** @return 0 if unit cannot move. +*/ +int CanMove(const Unit* unit) +{ + Assert(unit); + Assert(unit->Type); + return (unit->Type->Animations && unit->Type->Animations->Move); +} + + /** ** Unit moves! Generic function called from other actions. ** @@ -191,13 +207,8 @@ static int ActionMoveGeneric(Unit* unit, const Animation* anim) */ int DoActionMove(Unit* unit) { - if (unit->Type->Animations && unit->Type->Animations->Move) { - return ActionMoveGeneric(unit, unit->Type->Animations->Move); - } - - DebugPrint("Warning tried to move an object, which can't move\n"); - - return PF_UNREACHABLE; + Assert(CanMove(unit)); + return ActionMoveGeneric(unit, unit->Type->Animations->Move); } /** @@ -214,6 +225,8 @@ void HandleActionMove(Unit* unit) { Unit* goal; + Assert(unit); + Assert(CanMove(unit)); if (!unit->SubAction) { // first entry unit->SubAction = 1; NewResetPath(unit); diff --git a/src/action/action_spellcast.cpp b/src/action/action_spellcast.cpp index 34126a062..afc4cf0a4 100644 --- a/src/action/action_spellcast.cpp +++ b/src/action/action_spellcast.cpp @@ -101,7 +101,7 @@ static void SpellMoveToTarget(Unit* unit) // Unit can't move err = 1; - if (unit->Type->Animations && unit->Type->Animations->Move) { + if (CanMove(unit)) { err = DoActionMove(unit); if (!unit->Reset) { return; diff --git a/src/action/action_still.cpp b/src/action/action_still.cpp index 9afa622da..beec4cf70 100644 --- a/src/action/action_still.cpp +++ b/src/action/action_still.cpp @@ -187,7 +187,7 @@ void ActionStillGeneric(Unit* unit, int ground) // Normal units react in reaction range. // Removed units can only attack in AttackRange, from bunker // - if (!type->Building && !unit->Removed && !ground) { + if (CanMove(unit) && !unit->Removed && !ground) { if ((goal = AttackUnitsInReactRange(unit))) { // Weak goal, can choose other unit, come back after attack CommandAttack(unit, goal->X, goal->Y, NULL, FlushCommands); diff --git a/src/action/command.cpp b/src/action/command.cpp index 2b3a819b9..2c31aa5ff 100644 --- a/src/action/command.cpp +++ b/src/action/command.cpp @@ -290,7 +290,7 @@ void CommandFollow(Unit* unit, Unit* dest, int flush) // Check if unit is still valid? (NETWORK!) // if (!unit->Removed && unit->Orders[0].Action != UnitActionDie) { - if (unit->Type->Building) { + if (!CanMove(unit)) { // FIXME: should find a better way for pending orders. order = &unit->NewOrder; ReleaseOrder(order); @@ -339,7 +339,7 @@ void CommandMove(Unit* unit, int x, int y, int flush) // Check if unit is still valid? (NETWORK!) // if (!unit->Removed && unit->Orders[0].Action != UnitActionDie) { - if (unit->Type->Building) { + if (!CanMove(unit)) { // FIXME: should find a better way for pending orders. order = &unit->NewOrder; ReleaseOrder(order); @@ -542,7 +542,7 @@ void CommandPatrolUnit(Unit* unit, int x, int y, int flush) // Check if unit is still valid? (NETWORK!) // if (!unit->Removed && unit->Orders[0].Action != UnitActionDie) { - if (unit->Type->Building) { + if (!CanMove(unit)) { // FIXME: should find a better way for pending orders. order = &unit->NewOrder; ReleaseOrder(order); diff --git a/src/ai/ai.cpp b/src/ai/ai.cpp index 8a7f4981d..47e5fb9a2 100644 --- a/src/ai/ai.cpp +++ b/src/ai/ai.cpp @@ -1392,8 +1392,7 @@ static void AiMoveUnitInTheWay(Unit* unit) continue; } - // FIXME : check movement from animation - if (blockertype->Building) { + if (!CanMove(blocker)) { continue; } diff --git a/src/ai/ai_plan.cpp b/src/ai/ai_plan.cpp index eb00792b7..2bbc9f3d1 100644 --- a/src/ai/ai_plan.cpp +++ b/src/ai/ai_plan.cpp @@ -697,7 +697,7 @@ void AiSendExplorers(void) type = (*unit)->Type; - if (type->Building) { + if (!CanMove(*unit)) { continue; } diff --git a/src/ai/ai_resource.cpp b/src/ai/ai_resource.cpp index 8f0e57f75..0db8929fa 100644 --- a/src/ai/ai_resource.cpp +++ b/src/ai/ai_resource.cpp @@ -153,10 +153,8 @@ static int AiCheckSupply(const PlayerAi* pai, const UnitType* type) // Count what we train. // for (queue = pai->UnitTypeBuilded; queue; queue = queue->Next) { - if (!queue->Type->Building) { - if ((remaining -= queue->Made * queue->Type->Demand) < 0) { - return 0; - } + if ((remaining -= queue->Made * queue->Type->Demand) < 0) { + return 0; } } return 1; diff --git a/src/editor/editloop.cpp b/src/editor/editloop.cpp index b3e684844..ca2512c09 100644 --- a/src/editor/editloop.cpp +++ b/src/editor/editloop.cpp @@ -1200,11 +1200,10 @@ static void EditorCallbackButtonDown(unsigned button __attribute__ ((unused))) if ((MouseButtons & RightButton && UnitUnderCursor)) { if (UnitUnderCursor->Type->GivesResource) { EditorEditResource(); - return; - } - if (!UnitUnderCursor->Type->Building && UnitUnderCursor->HP > 0) { + } else { EditorEditAiProperties(); } + return; } } diff --git a/src/include/unit.h b/src/include/unit.h index 0c463b042..d7a75b791 100644 --- a/src/include/unit.h +++ b/src/include/unit.h @@ -563,7 +563,7 @@ struct _unit_ { /* Seen stuff. */ char VisCount[PlayerMax]; ///< Unit visibility counts struct _seen_stuff_ { - unsigned ByPlayer : 16; ///< Track unit seen by player + unsigned ByPlayer : PlayerMax; ///< Track unit seen by player int Frame; ///< last seen frame/stage of buildings struct _unit_type_* Type; ///< Pointer to last seen unit-type signed char IX; ///< Seen X image displacement to map position @@ -888,6 +888,8 @@ extern int CanTarget(const struct _unit_type_* type, const struct _unit_type_* d /// Can transporter transport the other unit extern int CanTransport(const Unit* transporter, const Unit* unit); + /// Check if unit can move. +extern int CanMove(const Unit*); /// Generate a unit reference, a printable unique string for unit extern char* UnitReference(const Unit*); diff --git a/src/ui/botpanel.cpp b/src/ui/botpanel.cpp index 150c5bf6f..cc80914b3 100644 --- a/src/ui/botpanel.cpp +++ b/src/ui/botpanel.cpp @@ -725,7 +725,7 @@ void DoButtonButtonClicked(int button) // That or a bunker. // if ((NumSelected == 1 && Selected[0]->Orders[0].Action == UnitActionStill && - CoastOnMap(Selected[0]->X, Selected[0]->Y)) || Selected[0]->Type->Building) { + CoastOnMap(Selected[0]->X, Selected[0]->Y)) || !CanMove(Selected[0])) { SendCommandUnload(Selected[0], Selected[0]->X, Selected[0]->Y, NoUnitP, !(KeyModifiers & ModifierShift)); @@ -799,7 +799,7 @@ void DoButtonButtonClicked(int button) case ButtonCancel: case ButtonCancelUpgrade: - if (NumSelected == 1 && Selected[0]->Type->Building) { + if (NumSelected == 1) { if (Selected[0]->Orders[0].Action == UnitActionUpgradeTo) { SendCommandCancelUpgradeTo(Selected[0]); } else if (Selected[0]->Orders[0].Action == UnitActionResearch) { @@ -824,7 +824,8 @@ void DoButtonButtonClicked(int button) case ButtonCancelBuild: // FIXME: johns is this not sure, only building should have this? - if (NumSelected == 1 && Selected[0]->Type->Building) { + Assert(Selected[0]->Orders[0].Action == UnitActionBuild); + if (NumSelected == 1) { SendCommandDismiss(Selected[0]); } ClearStatusLine(); diff --git a/src/ui/button_checks.cpp b/src/ui/button_checks.cpp index 0a12d92b8..fca3bcceb 100644 --- a/src/ui/button_checks.cpp +++ b/src/ui/button_checks.cpp @@ -187,7 +187,7 @@ int ButtonCheckNoNetwork(const Unit* unit __attribute__((unused)), int ButtonCheckNoWork(const Unit* unit, const ButtonAction* button __attribute__((unused))) { - return unit->Type->Building && + return unit->Orders[0].Action != UnitActionTrain && unit->Orders[0].Action != UnitActionUpgradeTo && unit->Orders[0].Action != UnitActionResearch; @@ -204,7 +204,7 @@ int ButtonCheckNoWork(const Unit* unit, int ButtonCheckNoResearch(const Unit* unit, const ButtonAction* button __attribute__((unused))) { - return unit->Type->Building && + return unit->Orders[0].Action != UnitActionUpgradeTo && unit->Orders[0].Action != UnitActionResearch; } diff --git a/src/ui/mainscr.cpp b/src/ui/mainscr.cpp index a396b5091..485ce2e88 100644 --- a/src/ui/mainscr.cpp +++ b/src/ui/mainscr.cpp @@ -606,9 +606,9 @@ static void DrawUnitInfo(const Unit* unit) x = TheUI.InfoPanelX; y = TheUI.InfoPanelY; // - // Show progress for buildings only, if they are selected. + // Show progress if they are selected. // - if (type->Building && NumSelected == 1 && Selected[0] == unit) { + if (NumSelected == 1 && Selected[0] == unit) { // // Building training units. // @@ -1283,11 +1283,10 @@ void DrawInfoPanel(void) PlayersTeamed(ThisPlayer->Player, Selected[0]->Player->Player) || PlayersAllied(ThisPlayer->Player, Selected[0]->Player->Player) || ReplayRevealMap) { - if (Selected[0]->Type->Building && - (Selected[0]->Orders[0].Action == UnitActionBuilded || - Selected[0]->Orders[0].Action == UnitActionResearch || - Selected[0]->Orders[0].Action == UnitActionUpgradeTo || - Selected[0]->Orders[0].Action == UnitActionTrain)) { + if (Selected[0]->Orders[0].Action == UnitActionBuilded || + Selected[0]->Orders[0].Action == UnitActionResearch || + Selected[0]->Orders[0].Action == UnitActionUpgradeTo || + Selected[0]->Orders[0].Action == UnitActionTrain) { i = 3; } else if (Selected[0]->Type->_MaxMana) { i = 2; diff --git a/src/ui/mouse.cpp b/src/ui/mouse.cpp index 7215a51d3..592432a5f 100644 --- a/src/ui/mouse.cpp +++ b/src/ui/mouse.cpp @@ -104,35 +104,26 @@ void CancelBuildingMode(void) */ void DoRightButton(int sx, int sy) { - int i; - int x; - int y; - Unit* dest; - Unit* unit; - Unit* desttransporter; - UnitType* type; - int action; - int acknowledged; - int flush; - int res; - int spellnum; + int i; // iterator for selected units. + int x; // coordonate in tile. + int y; // coordonate in tile. + Unit* dest; // unit under the cursor if any. + Unit* unit; // one of the selected unit. + Unit* desttransporter; // dest if it could transport any unit. + UnitType* type; // type of unit. + int action; // default action for unit. + int acknowledged; // to play sound + int flush; // append command to old command. + int res; // resource id for harvester. + int spellnum; // spell id for spell cast // No unit selected if (!NumSelected) { return; } - // - // Unit selected isn't owned by the player. - // You can't select your own units + foreign unit(s). - // - if (!CanSelectMultipleUnits(Selected[0]->Player)) { - return; - } - x = sx / TileSizeX; y = sy / TileSizeY; - desttransporter = NoUnitP; // // Right mouse with SHIFT appends command to old commands. @@ -145,6 +136,30 @@ void DoRightButton(int sx, int sy) dest = NULL; } + // + // Unit selected isn't owned by the player. + // You can't select your own units + foreign unit(s) + // except if it is neutral and it is a resource. + // + if (!CanSelectMultipleUnits(Selected[0]->Player)) { + unit = Selected[0]; + if (unit->Player->Player != PlayerNumNeutral || dest == NULL) { + return ; + } + // tell to go and harvest from a unit + if (dest->Type->Harvester && + (res = unit->Type->GivesResource) && + dest->Type->ResInfo[res] && + dest->ResourcesHeld < dest->Type->ResInfo[res]->ResourceCapacity && + unit->Type->CanHarvest) { + unit->Blink = 4; + SendCommandResource(dest, unit, flush); + return; + } + return; + } + + desttransporter = NoUnitP; if (dest && dest->Type->CanTransport) { for (i = 0; i < NumSelected; i++) { if (CanTransport(dest, Selected[i])) { @@ -184,7 +199,7 @@ void DoRightButton(int sx, int sy) // // Control + right click on unit is follow anything. // - if ((KeyModifiers & ModifierControl) && dest && dest!=unit) { + if ((KeyModifiers & ModifierControl) && dest && dest != unit) { dest->Blink = 4; SendCommandFollow(unit, dest, flush); continue; @@ -197,9 +212,8 @@ void DoRightButton(int sx, int sy) dest->Blink = 4; DebugPrint("Board transporter\n"); // Let the transporter move to the unit. And QUEUE!!! - // Don't do it for buildings. - if (!dest->Type->Building) { - DebugPrint("Send command follow"); + if (CanMove(dest)) { + DebugPrint("Send command follow\n"); SendCommandFollow(dest, unit, 0); } SendCommandBoard(unit, -1, -1, dest, flush); @@ -210,7 +224,7 @@ void DoRightButton(int sx, int sy) // Handle resource workers. // if (action == MouseActionHarvest) { - if (unit->Type->Harvester) { + if (type->Harvester) { if (dest) { // Return a loaded harvester to deposit if (unit->ResourcesHeld > 0 && @@ -220,10 +234,10 @@ void DoRightButton(int sx, int sy) SendCommandReturnGoods(unit, dest, flush); continue; } - // Go and harvest from a building + // Go and harvest from a unit if ((res = dest->Type->GivesResource) && - unit->Type->ResInfo[res] && - unit->ResourcesHeld < unit->Type->ResInfo[res]->ResourceCapacity && + type->ResInfo[res] && + unit->ResourcesHeld < type->ResInfo[res]->ResourceCapacity && dest->Type->CanHarvest && (dest->Player == unit->Player || (dest->Player->Player == PlayerNumNeutral))) { @@ -234,12 +248,12 @@ void DoRightButton(int sx, int sy) } else { // FIXME: support harvesting more types of terrain. for (res = 0; res < MaxCosts; ++res) { - if (unit->Type->ResInfo[res] && - unit->Type->ResInfo[res]->TerrainHarvester && + if (type->ResInfo[res] && + type->ResInfo[res]->TerrainHarvester && IsMapFieldExplored(unit->Player, x, y) && ForestOnMap(x, y) && ((unit->CurrentResource != res) || - (unit->ResourcesHeld < unit->Type->ResInfo[res]->ResourceCapacity))) { + (unit->ResourcesHeld < type->ResInfo[res]->ResourceCapacity))) { SendCommandResourceLoc(unit, x, y,flush); break; } @@ -250,7 +264,7 @@ void DoRightButton(int sx, int sy) } } // Go and repair - if (unit->Type->RepairRange && dest && + if (type->RepairRange && dest && dest->Type->RepairHP && dest->HP < dest->Stats->HitPoints && (dest->Player == unit->Player || IsAllied(dest->Player, dest))) { @@ -280,12 +294,12 @@ void DoRightButton(int sx, int sy) if (action == MouseActionSpellCast) { // This is for demolition squads and such Assert(unit->Type->CanCastSpell); - for (spellnum = 0; !unit->Type->CanCastSpell[spellnum] && + for (spellnum = 0; !type->CanCastSpell[spellnum] && spellnum < SpellTypeCount ; spellnum++) ; Assert(spellnum != SpellTypeCount); SendCommandSpellCast(unit, x, y, dest, spellnum, flush); } else { - if (CanTarget(unit->Type, dest->Type)) { + if (CanTarget(type, dest->Type)) { SendCommandAttack(unit, x, y, dest, flush); } else { // No valid target SendCommandAttack(unit, x, y, NoUnitP, flush); @@ -344,22 +358,44 @@ void DoRightButton(int sx, int sy) continue; } - // - // Buildings - // - if (type->Building) { - if (dest && dest->Type->GivesResource && dest->Type->CanHarvest) { + // Manage harvester from the destination side. + if (dest && dest->Type->Harvester) { + // tell to return a loaded harvester to deposit + if (dest->ResourcesHeld > 0 && + type->CanStore[dest->CurrentResource] && + dest->Player == unit->Player) { + dest->Blink = 4; + SendCommandReturnGoods(dest, unit, flush); + continue; + } + // tell to go and harvest from a building + if ((res = type->GivesResource) && + dest->Type->ResInfo[res] && + dest->ResourcesHeld < dest->Type->ResInfo[res]->ResourceCapacity && + type->CanHarvest && + dest->Player == unit->Player) { + unit->Blink = 4; + SendCommandResource(dest, unit, flush); + continue; + } + } + + // Manaage new order. + if (!CanMove(unit)) { + // Go and harvest from a unit + if (dest && dest->Type->GivesResource && dest->Type->CanHarvest && + (dest->Player == unit->Player || dest->Player->Player == PlayerNumNeutral)) { dest->Blink = 4; SendCommandResource(unit, dest, flush); continue; } + // FIXME: support harvesting more types of terrain. if (IsMapFieldExplored(unit->Player, x, y) && ForestOnMap(x, y)) { - SendCommandResourceLoc(unit, x, y, flush); - continue; + SendCommandResourceLoc(unit, x, y,flush); + break; } - SendCommandMove(unit, x, y, flush); - continue; } + SendCommandMove(unit, x, y, flush); } ShowOrdersCount = GameCycle + ShowOrders * CYCLES_PER_SECOND; @@ -465,7 +501,7 @@ static void HandleMouseOn(int x, int y) } } } - if (NumSelected == 1 && Selected[0]->Type->Building && !BigMapMode) { + if (NumSelected == 1 && !BigMapMode) { if (Selected[0]->Orders[0].Action == UnitActionTrain) { if (Selected[0]->OrderCount == 1) { if (OnButton(x, y, TheUI.SingleTrainingButton)) { @@ -943,7 +979,7 @@ static int SendAttack(int sx, int sy) y = sy / TileSizeY; for (i = 0; i < NumSelected; ++i) { unit = Selected[i]; - if (unit->Type->CanAttack || unit->Type->Building) { + if (unit->Type->CanAttack) { if ((dest = UnitUnderCursor) && CanTarget(unit->Type, dest->Type)) { dest->Blink = 4; } else { @@ -955,8 +991,10 @@ static int SendAttack(int sx, int sy) ret = 1; } } else { - SendCommandMove(unit, x, y, !(KeyModifiers & ModifierShift)); - ret = 1; + if (CanMove(unit)) { + SendCommandMove(unit, x, y, !(KeyModifiers & ModifierShift)); + ret = 1; + } } } return ret; @@ -1069,7 +1107,7 @@ static int SendResource(int sx, int sy) } } } - if (unit->Type->Building) { + if (!CanMove(unit)) { if (dest && dest->Type->GivesResource && dest->Type->CanHarvest) { dest->Blink = 4; SendCommandResource(unit, dest, !(KeyModifiers & ModifierShift)); diff --git a/src/unit/script_unittype.cpp b/src/unit/script_unittype.cpp index 35ad159c5..b49258098 100644 --- a/src/unit/script_unittype.cpp +++ b/src/unit/script_unittype.cpp @@ -1705,7 +1705,7 @@ void UpdateUnitVariables(const Unit* unit) unit->Variable[i].Enable = 1; } - // HP (do also building under construction :) ). + // HP. unit->Variable[HP_INDEX].Value = unit->HP; unit->Variable[HP_INDEX].Max = unit->Stats->HitPoints; diff --git a/src/unit/unit.cpp b/src/unit/unit.cpp index 15b52001e..cb775e084 100644 --- a/src/unit/unit.cpp +++ b/src/unit/unit.cpp @@ -389,31 +389,35 @@ void InitUnit(Unit* unit, UnitType* type) } /** -** FIXME: Docu +** FIXME: Docu +** +** @param unit unit assigned to player. +** @param player player which have the unit. +** +** @todo FIXME DOCU. */ void AssignUnitToPlayer(Unit* unit, Player* player) { - UnitType* type; + UnitType* type; // type of unit. + Assert(player); type = unit->Type; // // Build player unit table // - if (player && !type->Vanishes && unit->Orders[0].Action != UnitActionDie) { + if (!type->Vanishes && unit->Orders[0].Action != UnitActionDie) { unit->PlayerSlot = player->Units + player->TotalNumUnits++; if (!SaveGameLoading) { - if (type->_HitPoints != 0) { - // If unit is dieing, it's already been lost by all players - // don't count again - if (type->Building && unit->Orders[0].Action != UnitActionDie) { - // FIXME: support more races - if (type != UnitTypeOrcWall && type != UnitTypeHumanWall) { - player->TotalBuildings++; - } - } else if (unit->Orders[0].Action != UnitActionDie) { - player->TotalUnits++; + // If unit is dieing, it's already been lost by all players + // don't count again + if (type->Building) { + // FIXME: support more races + if (type != UnitTypeOrcWall && type != UnitTypeHumanWall) { + player->TotalBuildings++; } + } else { + player->TotalUnits++; } } *unit->PlayerSlot = unit; @@ -431,7 +435,6 @@ void AssignUnitToPlayer(Unit* unit, Player* player) player->NumBuildings++; } } - unit->Player = player; unit->Stats = &type->Stats[unit->Player->Player]; unit->Colors = &player->UnitColors; @@ -627,7 +630,7 @@ static void MarkUnitFieldFlags(const Unit* unit) } #ifdef MAP_REGIONS // Update map splitting. - if (type->Building && (flags & + if (!CanMove(unit) && (flags & (MapFieldLandUnit | MapFieldSeaUnit | MapFieldBuilding | MapFieldUnpassable | MapFieldWall | MapFieldRocks | MapFieldForest))) { MapSplitterTilesOccuped(x, y, x + type->TileWidth - 1, y + type->TileHeight - 1); @@ -661,7 +664,7 @@ static void UnmarkUnitFieldFlags(const Unit* unit) } #ifdef MAP_REGIONS // Update map splitting. - if (type->Building && (flags & + if (!CanMove(unit) && (flags & (MapFieldLandUnit | MapFieldSeaUnit | MapFieldBuilding | MapFieldUnpassable | MapFieldWall | MapFieldRocks | MapFieldForest))){ MapSplitterTilesCleared(x, y, x + type->TileWidth - 1, y + type->TileHeight - 1); @@ -1219,10 +1222,6 @@ void UnitsOnTileUnmarkSeen(const Player* player, int x, int y, int cloak) n = UnitCacheOnTile(x, y, units); while (n) { unit = units[--n]; - if ((unit->X > x || unit->X + unit->Type->TileWidth - 1 < x || - unit->Y > y || unit->Y + unit->Type->TileHeight - 1 < y)) { - DebugPrint("Wrong cache %d %d -> %d %d\n" _C_ x _C_ y _C_ unit->X _C_ unit->Y); - } Assert(unit->X <= x && unit->X + unit->Type->TileWidth - 1 >= x && unit->Y <= y && unit->Y + unit->Type->TileHeight - 1 >= y); if (cloak != (int)unit->Type->PermanentCloak) { @@ -3153,7 +3152,7 @@ void HitUnit(Unit* attacker, Unit* target, int damage) // Attack units in range (which or the attacker?) // if (attacker && !type->Coward) { - if (type->CanAttack && !target->Type->Building) { + if (type->CanAttack) { if (RevealAttacker && CanTarget(target->Type, attacker->Type)) { // Reveal Unit that is attacking goal = attacker; @@ -3176,7 +3175,7 @@ void HitUnit(Unit* attacker, Unit* target, int damage) // // FIXME: Can't attack run away. // - if (!type->Building) { + if (CanMove(target)) { int x; int y; int d; @@ -3411,7 +3410,7 @@ int CanTransport(const Unit* transporter, const Unit* unit) { int i; - if (!transporter->Type->CanTransport || unit->Type->Building) { + if (!transporter->Type->CanTransport) { return 0; } if (transporter->BoardCount >= transporter->Type->MaxOnBoard) { // full diff --git a/src/unit/unit_draw.cpp b/src/unit/unit_draw.cpp index c9726f0fb..3f0ef3b67 100644 --- a/src/unit/unit_draw.cpp +++ b/src/unit/unit_draw.cpp @@ -195,7 +195,7 @@ void DrawUnitSelection(const Unit* unit) color = Players[i].Color; } } - } else if (CursorBuilding && unit->Type->Building && + } else if (CursorBuilding && unit->Type->Building && unit->Orders[0].Action != UnitActionDie && (unit->Player == ThisPlayer || PlayersTeamed(ThisPlayer->Player, unit->Player->Player))) { @@ -1170,43 +1170,10 @@ void DrawShadow(const Unit* unit, const UnitType* type, int frame, Assert(unit); type = unit->Type; } - Assert(!unit || !type || unit->Type == type); - - // - // A building can be under construction and is drawn with construction - // frames. - // - if (type->Building) { - // Draw normal shadow - if (type->ShadowSprite) { - // FIXME: this can be combined with the unit else part. - x -= (type->ShadowWidth - - type->TileWidth * TileSizeX) / 2; - y -= (type->ShadowHeight - - type->TileHeight * TileSizeY) / 2; - x += type->ShadowOffsetX; - y += type->ShadowOffsetY; - if (type->Flip) { - if (frame < 0) { - VideoDrawClipX(type->ShadowSprite, -frame - 1, x, y); - } else { - VideoDrawClip(type->ShadowSprite, frame, x, y); - } - } else { - int row; - - row = type->NumDirections / 2 + 1; - if (frame < 0) { - frame = ((-frame - 1) / row) * type->NumDirections + type->NumDirections - (-frame - 1) % row; - } else { - frame = (frame / row) * type->NumDirections + frame % row; - } - VideoDrawClip(type->ShadowSprite, frame, x, y); - } - } - return; - } + Assert(type); + Assert(!unit || unit->Type == type); + // unit == NULL for the editor if (unit && unit->Orders[0].Action == UnitActionDie) { return; } @@ -1590,7 +1557,7 @@ void ShowOrder(const Unit* unit) ShowSingleOrder(unit, x1, y1, unit->Orders + i); } #endif - if (unit->Type->Building) { + if (!CanMove(unit)) { ShowSingleOrder(unit, x1, y1, &unit->NewOrder); } }