/** ** Attack with unit at new position ** ** @param unit pointer to unit. ** @param pos map position to attack. ** @param target or unit to be attacked. ** @param flush if true, flush command queue. */ void CommandAttack(CUnit &unit, const Vec2i &pos, CUnit *target, int flush) { Assert(Map.Info.IsPointOnMap(pos)); if (IsUnitValidForNetwork(unit) == false) { return ; } COrderPtr *order; if (!unit.Type->CanAttack) { ClearNewAction(unit); order = &unit.NewOrder; } else { order = GetNextOrder(unit, flush); if (order == NULL) { return; } } if (target && target->IsAlive()) { *order = COrder::NewActionAttack(unit, *target); } else { *order = COrder::NewActionAttack(unit, pos); } ClearSavedAction(unit); }
/** ** Board a transporter with unit. ** ** @param unit pointer to unit. ** @param dest unit to be boarded. ** @param flush if true, flush command queue. */ void CommandBoard(CUnit *unit, CUnit *dest, int flush) { COrder *order; // // Check if unit is still valid? (NETWORK!) // if (!unit->Removed && unit->Orders[0]->Action != UnitActionDie) { // // Destination could be killed. // Should be handled in action, but is not possible! // Unit::Refs is used as timeout counter. // if (dest->Destroyed) { return; } if (unit->Type->Building) { // FIXME: should find a better way for pending orders. order = &unit->NewOrder; ReleaseOrder(order); } else if (!(order = GetNextOrder(unit, flush))) { return; } order->Init(); order->Action = UnitActionBoard; order->Goal = dest; dest->RefsIncrease(); order->Range = 1; } ClearSavedAction(unit); }
/** ** Building starts upgrading to. ** ** @param unit pointer to unit. ** @param type upgrade to type ** @param flush if true, flush command queue. */ void CommandUpgradeTo(CUnit *unit, CUnitType *type, int flush) { COrder *order; // // Check if unit is still valid and Goal still alive? (NETWORK!) // if (!unit->Removed && unit->Orders[0]->Action != UnitActionDie) { // // Check if enough resources remains? (NETWORK!) // if (unit->Player->CheckUnitType(type)) { return; } if (!flush) { DebugPrint("FIXME: must support order queing!!"); } if (!(order = GetNextOrder(unit, flush))) { return; } order->Init(); // FIXME: if you give quick an other order, the resources are lost! unit->Player->SubUnitType(type); order->Action = UnitActionUpgradeTo; order->Type = type; } ClearSavedAction(unit); }
/** ** Unload a transporter. ** ** @param unit pointer to unit. ** @param x X map position to unload. ** @param y Y map position to unload. ** @param what unit to be unloaded, NoUnitP all. ** @param flush if true, flush command queue. */ void CommandUnload(CUnit *unit, int x, int y, CUnit *what, int flush) { COrder *order; // // Check if unit is still valid? (NETWORK!) // if (!unit->Removed && unit->Orders[0]->Action != UnitActionDie) { if (!(order = GetNextOrder(unit, flush))) { return; } order->Init(); order->Action = UnitActionUnload; order->X = x; order->Y = y; // // Destination could be killed. // Should be handled in action, but is not possible! // Unit::Refs is used as timeout counter. // if (what && !what->Destroyed) { order->Goal = what; what->RefsIncrease(); } } ClearSavedAction(unit); }
/** ** Send unit to harvest resources ** ** @param unit pointer to unit. ** @param dest destination unit. ** @param flush if true, flush command queue. */ void CommandResource(CUnit &unit, CUnit &dest, int flush) { if (IsUnitValidForNetwork(unit) == false) { return ; } if (dest.Destroyed) { return ; } if (!unit.Type->Building && !unit.Type->Harvester) { ClearSavedAction(unit); return ; } COrderPtr *order; if (unit.Type->Building) { ClearNewAction(unit); order = &unit.NewOrder; } else { order = GetNextOrder(unit, flush); if (order == NULL) { return; } } *order = COrder::NewActionResource(unit, dest); ClearSavedAction(unit); }
/** ** Let unit returning goods. ** ** @param unit pointer to unit. ** @param goal bring goods to this depot. ** @param flush if true, flush command queue. */ void CommandReturnGoods(CUnit *unit, CUnit *goal, int flush) { COrder *order; // // Check if unit is still valid and Goal still alive? (NETWORK!) // if (!unit->Removed && unit->Orders[0]->Action != UnitActionDie) { // FIXME: more races, could happen with many orders in queue. if (!unit->Type->Building && !unit->Type->Harvester && !unit->ResourcesHeld) { ClearSavedAction(unit); return; } if (unit->Type->Building) { // FIXME: should find a better way for pending orders. order = &unit->NewOrder; ReleaseOrder(order); } else if (!(order = GetNextOrder(unit, flush))) { return; } order->Init(); order->Action = UnitActionReturnGoods; // // Destination could be killed. NETWORK! // if (goal && !goal->Destroyed) { order->Goal = goal; goal->RefsIncrease(); } order->Range = 1; } ClearSavedAction(unit); }
/** ** Cast a spell at position or unit. ** ** @param unit Pointer to unit. ** @param pos map position to spell cast on. ** @param dest Spell cast on unit (if exist). ** @param spell Spell type pointer. ** @param flush If true, flush command queue. */ void CommandSpellCast(CUnit &unit, const Vec2i &pos, CUnit *dest, const SpellType &spell, int flush, bool isAutocast) { DebugPrint(": %d casts %s at %d %d on %d\n" _C_ UnitNumber(unit) _C_ spell.Ident.c_str() _C_ pos.x _C_ pos.y _C_ dest ? UnitNumber(*dest) : 0); Assert(unit.Type->CanCastSpell[spell.Slot]); Assert(Map.Info.IsPointOnMap(pos)); if (IsUnitValidForNetwork(unit) == false) { return ; } //Wyrmgus start CMapField &mf = *Map.Field(unit.tilePos); if ((mf.Flags & MapFieldBridge) && !unit.Type->BoolFlag[BRIDGE_INDEX].value && unit.Type->UnitType == UnitTypeLand) { std::vector<CUnit *> table; Select(unit.tilePos, unit.tilePos, table); for (size_t i = 0; i != table.size(); ++i) { if (!table[i]->Removed && table[i]->Type->BoolFlag[BRIDGE_INDEX].value && table[i]->CanMove()) { CommandStopUnit(*table[i]); //always stop the raft if a new command is issued } } } //Wyrmgus end COrderPtr *order = GetNextOrder(unit, flush); if (order == NULL) { return; } *order = COrder::NewActionSpellCast(spell, pos, dest, true); ClearSavedAction(unit); }
/** ** Attack ground with unit. ** ** @param unit pointer to unit. ** @param x X map position to fire on. ** @param y Y map position to fire on. ** @param flush if true, flush command queue. */ void CommandAttackGround(CUnit *unit, int x, int y, int flush) { COrder *order; Assert(x >= 0 && y >= 0 && x < Map.Info.MapWidth && y < Map.Info.MapHeight); // // Check if unit is still valid? (NETWORK!) // if (!unit->Removed && unit->Orders[0]->Action != UnitActionDie) { if (unit->Type->Building) { // FIXME: should find a better way for pending orders. order = &unit->NewOrder; ReleaseOrder(order); } else if (!(order = GetNextOrder(unit, flush))) { return; } order->Init(); order->Action = UnitActionAttackGround; order->X = x; order->Y = y; order->Range = unit->Stats->Variables[ATTACKRANGE_INDEX].Max; order->MinRange = unit->Type->MinAttackRange; DebugPrint("FIXME this next\n"); } ClearSavedAction(unit); }
/** ** Let an unit patrol from current to new position ** ** FIXME: want to support patroling between units. ** ** @param unit pointer to unit. ** @param x X map position to patrol between. ** @param y Y map position to patrol between. ** @param flush if true, flush command queue. */ void CommandPatrolUnit(CUnit *unit, int x, int y, int flush) { COrder *order; Assert(x >= 0 && y >= 0 && x < Map.Info.MapWidth && y < Map.Info.MapHeight); // // Check if unit is still valid? (NETWORK!) // if (!unit->Removed && unit->Orders[0]->Action != UnitActionDie) { if (!CanMove(unit)) { // FIXME: should find a better way for pending orders. order = &unit->NewOrder; ReleaseOrder(order); } else if (!(order = GetNextOrder(unit, flush))) { return; } order->Init(); order->Action = UnitActionPatrol; order->X = x; order->Y = y; Assert(!(unit->X & ~0xFFFF) && !(unit->Y & ~0xFFFF)); order->Arg1.Patrol.X = unit->X; order->Arg1.Patrol.Y = unit->Y; } ClearSavedAction(unit); }
/** ** Building starts training an unit. ** ** @param unit pointer to unit. ** @param type unit type to train. ** @param flush if true, flush command queue. */ void CommandTrainUnit(CUnit &unit, CUnitType &type, int) { if (IsUnitValidForNetwork(unit) == false) { return ; } // Check if enough resources remains? (NETWORK!) // FIXME: wrong if append to message queue!!! if (unit.Player->CheckLimits(type) < 0 || unit.Player->CheckUnitType(type)) { return; } // Not already training? if (!EnableTrainingQueue && unit.CurrentAction() == UnitActionTrain) { DebugPrint("Unit queue disabled!\n"); return; } const int noFlushCommands = 0; COrderPtr *order = GetNextOrder(unit, noFlushCommands); if (order == NULL) { return; } *order = COrder::NewActionTrain(unit, type); ClearSavedAction(unit); }
/** ** Send unit harvest a location ** ** @param unit pointer to unit. ** @param pos map position for harvest. ** @param flush if true, flush command queue. */ void CommandResourceLoc(CUnit &unit, const Vec2i &pos, int flush) { if (IsUnitValidForNetwork(unit) == false) { return ; } if (!unit.Type->Building && !unit.Type->BoolFlag[HARVESTER_INDEX].value) { ClearSavedAction(unit); return ; } //Wyrmgus start CMapField &mf = *Map.Field(unit.tilePos); if ((mf.Flags & MapFieldBridge) && !unit.Type->BoolFlag[BRIDGE_INDEX].value && unit.Type->UnitType == UnitTypeLand) { std::vector<CUnit *> table; Select(unit.tilePos, unit.tilePos, table); for (size_t i = 0; i != table.size(); ++i) { if (!table[i]->Removed && table[i]->Type->BoolFlag[BRIDGE_INDEX].value && table[i]->CanMove()) { CommandStopUnit(*table[i]); //always stop the raft if a new command is issued } } } //Wyrmgus end COrderPtr *order; if (unit.Type->Building) { ClearNewAction(unit); order = &unit.NewOrder; } else { order = GetNextOrder(unit, flush); if (order == NULL) { return; } } *order = COrder::NewActionResource(unit, pos); ClearSavedAction(unit); }
/** ** Send unit to harvest resources ** ** @param unit pointer to unit. ** @param dest destination unit. ** @param flush if true, flush command queue. */ void CommandResource(CUnit *unit, CUnit *dest, int flush) { COrder *order; // // Check if unit is still valid and Goal still alive? (NETWORK!) // if (!unit->Removed && unit->Orders[0]->Action != UnitActionDie && !dest->Destroyed) { // FIXME: more races, could happen with many orders in queue. if (!unit->Type->Building && !unit->Type->Harvester) { ClearSavedAction(unit); return; } // FIXME: if low-level supports searching, pass NoUnitP down. if (unit->Type->Building) { // FIXME: should find a better way for pending orders. order = &unit->NewOrder; ReleaseOrder(order); } else if (!(order = GetNextOrder(unit, flush))) { return; } order->Init(); order->Action = UnitActionResource; order->Goal = dest; dest->RefsIncrease(); order->Range = 1; } ClearSavedAction(unit); }
/** ** Stop unit. ** ** @param unit pointer to unit. */ void CommandStopUnit(CUnit &unit) { // Ignore that the unit could be removed. COrderPtr *order = GetNextOrder(unit, FlushCommands); // Flush them. Assert(order); Assert(*order == NULL); *order = COrder::NewActionStill(); ClearSavedAction(unit); ClearNewAction(unit); }
/** ** Unload a transporter. ** ** @param unit pointer to unit. ** @param pos map position to unload. ** @param what unit to be unloaded, NULL for all. ** @param flush if true, flush command queue. */ void CommandUnload(CUnit &unit, const Vec2i &pos, CUnit *what, int flush) { if (IsUnitValidForNetwork(unit) == false) { return ; } COrderPtr *order = GetNextOrder(unit, flush); if (order == NULL) { return; } *order = COrder::NewActionUnload(pos, what); ClearSavedAction(unit); }
/** ** Order an already formed Order structure ** ** @param unit pointer to unit ** @param cpyorder pointer to valid order ** @param flush if true, flush command queue. */ void CommandAnyOrder(CUnit *unit, COrder *cpyorder, int flush) { COrder *order; if (!(order = GetNextOrder(unit, flush))) { return; } *order = *cpyorder; if (order->Goal) { order->Goal->RefsIncrease(); } ClearSavedAction(unit); }
/** ** Attack with unit at new position ** ** @param unit pointer to unit. ** @param x X map position to attack. ** @param y Y map position to attack. ** @param attack or unit to be attacked. ** @param flush if true, flush command queue. */ void CommandAttack(CUnit *unit, int x, int y, CUnit *attack, int flush) { COrder *order; Assert(x >= 0 && y >= 0 && x < Map.Info.MapWidth && y < Map.Info.MapHeight); // // Check if unit is still valid? (NETWORK!) // if (!unit->Removed && unit->Orders[0]->Action != UnitActionDie) { if (!unit->Type->CanAttack) { // FIXME: should find a better way for pending orders. order = &unit->NewOrder; ReleaseOrder(order); } else if (!(order = GetNextOrder(unit, flush))) { return; } order->Init(); order->Action = UnitActionAttack; if (attack) { // // Destination could be killed. // Should be handled in action, but is not possible! // Unit::Refs is used as timeout counter. // if (attack->Destroyed) { order->X = attack->X + attack->Type->TileWidth / 2; order->Y = attack->Y + attack->Type->TileHeight / 2; } else { // Removed, Dying handled by action routine. order->Goal = attack; attack->RefsIncrease(); order->Range = unit->Stats->Variables[ATTACKRANGE_INDEX].Max; order->MinRange = unit->Type->MinAttackRange; } } else if (Map.WallOnMap(x,y)) { // FIXME: look into action_attack.c about this ugly problem order->X = x; order->Y = y; order->Range = unit->Stats->Variables[ATTACKRANGE_INDEX].Max; order->MinRange = unit->Type->MinAttackRange; } else { order->X = x; order->Y = y; } } ClearSavedAction(unit); }
/** ** Stop unit. ** ** @param unit pointer to unit. */ void CommandStopUnit(CUnit *unit) { COrder *order; // Ignore that the unit could be removed. order = GetNextOrder(unit, FlushCommands); // Flush them. Assert(order); order->Init(); order->Action = UnitActionStill; ReleaseOrder(&unit->SavedOrder); ReleaseOrder(&unit->NewOrder); unit->SavedOrder = unit->NewOrder = *order; }
/** ** Cast a spell at position or unit. ** ** @param unit Pointer to unit. ** @param x X map position to spell cast on. ** @param y Y map position to spell cast on. ** @param dest Spell cast on unit (if exist). ** @param spell Spell type pointer. ** @param flush If true, flush command queue. */ void CommandSpellCast(CUnit *unit, int x, int y, CUnit *dest, SpellType *spell, int flush) { COrder *order; Assert(x >= 0 && y >= 0 && x < Map.Info.MapWidth && y < Map.Info.MapHeight); DebugPrint(": %d casts %s at %d %d on %d\n" _C_ UnitNumber(unit) _C_ spell->Ident.c_str() _C_ x _C_ y _C_ dest ? UnitNumber(dest) : 0); Assert(unit->Type->CanCastSpell[spell->Slot]); // // Check if unit is still valid? (NETWORK!) // if (!unit->Removed && unit->Orders[0]->Action != UnitActionDie) { // FIXME: should I check here, if there is still enough mana? if (!(order = GetNextOrder(unit, flush))) { return; } order->Init(); order->Action = UnitActionSpellCast; order->Range = spell->Range; if (dest) { // // Destination could be killed. // Should be handled in action, but is not possible! // Unit::Refs is used as timeout counter. // if (dest->Destroyed) { // FIXME: where check if spell needs an unit as destination? // FIXME: dest->Type is now set to 0. maybe we shouldn't bother. order->X = dest->X /*+ dest->Type->TileWidth / 2*/ - order->Range; order->Y = dest->Y /*+ dest->Type->TileHeight / 2*/ - order->Range; order->Range <<= 1; } else { order->Goal = dest; dest->RefsIncrease(); } } else { order->X = x; order->Y = y; } order->Arg1.Spell = spell; } ClearSavedAction(unit); }
/** ** Building starts researching. ** ** @param unit pointer to unit. ** @param what what to research. ** @param flush if true, flush command queue. */ void CommandResearch(CUnit &unit, CUpgrade &what, int flush) { if (IsUnitValidForNetwork(unit) == false) { return ; } // Check if enough resources remains? (NETWORK!) if (unit.Player->CheckCosts(what.Costs)) { return; } COrderPtr *order = GetNextOrder(unit, flush); if (order == NULL) { return; } *order = COrder::NewActionResearch(unit, what); ClearSavedAction(unit); }
/** ** Stand ground. ** ** @param unit pointer to unit. ** @param flush if true, flush command queue. */ void CommandStandGround(CUnit &unit, int flush) { COrderPtr *order; if (unit.Type->Building) { ClearNewAction(unit); order = &unit.NewOrder; } else { order = GetNextOrder(unit, flush); if (order == NULL) { return; } } *order = COrder::NewActionStandGround(); ClearSavedAction(unit); }
/** ** Stand ground. ** ** @param unit pointer to unit. ** @param flush if true, flush command queue. */ void CommandStandGround(CUnit *unit, int flush) { COrder *order; // Ignore that the unit could be removed. if (unit->Type->Building) { // FIXME: should find a better way for pending orders. order = &unit->NewOrder; ReleaseOrder(order); } else if (!(order = GetNextOrder(unit, flush))) { return; } order->Init(); order->Action = UnitActionStandGround; ClearSavedAction(unit); }
/** ** Send unit harvest a location ** ** @param unit pointer to unit. ** @param x X map position for harvest. ** @param y Y map position for harvest. ** @param flush if true, flush command queue. */ void CommandResourceLoc(CUnit *unit, int x, int y, int flush) { COrder *order; int nx; int ny; // // Check if unit is still valid? (NETWORK!) // if (!unit->Removed && unit->Orders[0]->Action != UnitActionDie) { if (unit->Type->Building) { // FIXME: should find a better way for pending orders. order = &unit->NewOrder; ReleaseOrder(order); } else if (!(order = GetNextOrder(unit, flush))) { return; } order->Init(); order->Action = UnitActionResource; // Find the closest piece of wood next to a tile where the unit can move if (!FindTerrainType(0, (unit->Type->MovementMask), 1, 20, unit->Player, x, y, &nx, &ny)) { DebugPrint("FIXME: Give up???\n"); } // Max Value > 1 if ((abs(nx - x) | abs(ny - y)) > 1) { if (!FindTerrainType(0, MapFieldForest, 0, 20, unit->Player, nx, ny, &nx, &ny)) { DebugPrint("FIXME: Give up???\n"); } } else { // The destination is next to a reacahble tile. nx = x; ny = y; } order->X = nx; order->Y = ny; order->Range = 1; } ClearSavedAction(unit); }
/** ** Building starts researching. ** ** @param unit pointer to unit. ** @param what what to research. ** @param flush if true, flush command queue. */ void CommandResearch(CUnit *unit, CUpgrade *what, int flush) { COrder *order; // // Check if unit is still valid and Goal still alive? (NETWORK!) // if (!unit->Removed && unit->Orders[0]->Action != UnitActionDie) { // // Check if enough resources remains? (NETWORK!) // if (unit->Player->CheckCosts(what->Costs)) { return; } if (!flush) { DebugPrint("FIXME: must support order queing!!"); } else { if (unit->Orders[0]->Action == UnitActionResearch) { const CUpgrade *upgrade; // Cancel current research upgrade = unit->Data.Research.Upgrade; unit->Player->UpgradeTimers.Upgrades[upgrade->ID] = 0; unit->Player->AddCostsFactor(upgrade->Costs, CancelResearchCostsFactor); unit->SubAction = 0; } } if (!(order = GetNextOrder(unit, flush))) { return; } order->Init(); // FIXME: if you give quick an other order, the resources are lost! unit->Player->SubCosts(what->Costs); order->Action = UnitActionResearch; order->X = order->Y = -1; order->Arg1.Upgrade = what; } ClearSavedAction(unit); }
/** ** Send a unit building ** ** @param unit pointer to unit. ** @param pos map position to build. ** @param what Unit type to build. ** @param flush if true, flush command queue. */ void CommandBuildBuilding(CUnit &unit, const Vec2i &pos, CUnitType &what, int flush) { if (IsUnitValidForNetwork(unit) == false) { return ; } COrderPtr *order; if (unit.Type->Building) { ClearNewAction(unit); order = &unit.NewOrder; } else { order = GetNextOrder(unit, flush); if (order == NULL) { return; } } *order = COrder::NewActionBuild(unit, pos, what); ClearSavedAction(unit); }
/** ** Cast a spell at position or unit. ** ** @param unit Pointer to unit. ** @param pos map position to spell cast on. ** @param dest Spell cast on unit (if exist). ** @param spell Spell type pointer. ** @param flush If true, flush command queue. */ void CommandSpellCast(CUnit &unit, const Vec2i &pos, CUnit *dest, const SpellType &spell, int flush) { DebugPrint(": %d casts %s at %d %d on %d\n" _C_ UnitNumber(unit) _C_ spell.Ident.c_str() _C_ pos.x _C_ pos.y _C_ dest ? UnitNumber(*dest) : 0); Assert(unit.Type->CanCastSpell[spell.Slot]); Assert(Map.Info.IsPointOnMap(pos)); if (IsUnitValidForNetwork(unit) == false) { return ; } COrderPtr *order = GetNextOrder(unit, flush); if (order == NULL) { return; } *order = COrder::NewActionSpellCast(spell, pos, dest); ClearSavedAction(unit); }
/** ** Building starts upgrading to. ** ** @param unit pointer to unit. ** @param type upgrade to type ** @param flush if true, flush command queue. */ void CommandUpgradeTo(CUnit &unit, CUnitType &type, int flush) { if (IsUnitValidForNetwork(unit) == false) { return ; } // Check if enough resources remains? (NETWORK!) if (unit.Player->CheckUnitType(type)) { return; } COrderPtr *order = GetNextOrder(unit, flush); if (order == NULL) { return; } *order = COrder::NewActionUpgradeTo(unit, type); ClearSavedAction(unit); }
/** ** Follow unit to new position ** ** @param unit pointer to unit. ** @param dest unit to be followed ** @param flush if true, flush command queue. */ void CommandFollow(CUnit &unit, CUnit &dest, int flush) { if (IsUnitValidForNetwork(unit) == false) { return ; } COrderPtr *order; if (!unit.CanMove()) { ClearNewAction(unit); order = &unit.NewOrder; } else { order = GetNextOrder(unit, flush); if (order == NULL) { return; } } *order = COrder::NewActionFollow(dest); ClearSavedAction(unit); }
//Wyrmgus start //void CommandTrainUnit(CUnit &unit, CUnitType &type, int) void CommandTrainUnit(CUnit &unit, CUnitType &type, int player, int) //Wyrmgus end { if (IsUnitValidForNetwork(unit) == false) { return ; } // Check if enough resources remains? (NETWORK!) // FIXME: wrong if append to message queue!!! //Wyrmgus start // if (unit.Player->CheckLimits(type) < 0 // || unit.Player->CheckUnitType(type)) { if (Players[player].CheckLimits(type) < 0 || Players[player].CheckUnitType(type)) { //Wyrmgus end return; } //Wyrmgus start if (unit.Type->Stats[unit.Player->Index].UnitStock[type.Slot] != 0 && unit.UnitStock[type.Slot] == 0) { if (player == ThisPlayer->Index) { ThisPlayer->Notify(NotifyYellow, unit.tilePos, "%s", _("The stock is empty, wait until it is replenished.")); } return; } //Wyrmgus end // Not already training? if (!EnableTrainingQueue && unit.CurrentAction() == UnitActionTrain) { DebugPrint("Unit queue disabled!\n"); return; } const int noFlushCommands = 0; COrderPtr *order = GetNextOrder(unit, noFlushCommands); if (order == NULL) { return; } //Wyrmgus start // *order = COrder::NewActionTrain(unit, type); *order = COrder::NewActionTrain(unit, type, player); //Wyrmgus end ClearSavedAction(unit); }
/** ** Attack with unit at new position ** ** @param unit pointer to unit. ** @param pos map position to attack. ** @param target or unit to be attacked. ** @param flush if true, flush command queue. */ void CommandAttack(CUnit &unit, const Vec2i &pos, CUnit *target, int flush) { Assert(Map.Info.IsPointOnMap(pos)); if (IsUnitValidForNetwork(unit) == false) { return ; } //Wyrmgus start CMapField &mf = *Map.Field(unit.tilePos); CMapField &new_mf = *Map.Field(pos); if ((mf.Flags & MapFieldBridge) && !unit.Type->BoolFlag[BRIDGE_INDEX].value && unit.Type->UnitType == UnitTypeLand) { std::vector<CUnit *> table; Select(unit.tilePos, unit.tilePos, table); for (size_t i = 0; i != table.size(); ++i) { if (!table[i]->Removed && table[i]->Type->BoolFlag[BRIDGE_INDEX].value && table[i]->CanMove()) { CommandStopUnit(*table[i]); //always stop the raft if a new command is issued } } } //Wyrmgus end COrderPtr *order; //Wyrmgus start // if (!unit.Type->CanAttack) { if (!unit.CanAttack()) { //Wyrmgus end ClearNewAction(unit); order = &unit.NewOrder; } else { order = GetNextOrder(unit, flush); if (order == NULL) { return; } } if (target && target->IsAlive()) { *order = COrder::NewActionAttack(unit, *target); } else { *order = COrder::NewActionAttack(unit, pos); } ClearSavedAction(unit); }
/** ** Move unit to new position ** ** @param unit pointer to unit. ** @param pos map position to move to. ** @param flush if true, flush command queue. */ void CommandMove(CUnit &unit, const Vec2i &pos, int flush) { Assert(Map.Info.IsPointOnMap(pos)); if (IsUnitValidForNetwork(unit) == false) { return ; } COrderPtr *order; if (!unit.CanMove()) { ClearNewAction(unit); order = &unit.NewOrder; } else { order = GetNextOrder(unit, flush); if (order == NULL) { return; } } *order = COrder::NewActionMove(pos); ClearSavedAction(unit); }