/** ** Auto repair. ** ** @param unit pointer to unit. ** @param on 1 for auto repair on, 0 for off. */ void CommandAutoRepair(CUnit &unit, int on) { if (IsUnitValidForNetwork(unit) == false) { return ; } unit.AutoRepair = on; }
/** ** 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); }
/** ** 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); }
/** ** 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); }
/** ** 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); }
/** ** 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); }
/** ** Auto spell cast. ** ** @param unit pointer to unit. ** @param spellid Spell id. ** @param on 1 for auto cast on, 0 for off. */ void CommandAutoSpellCast(CUnit &unit, int spellid, int on) { if (IsUnitValidForNetwork(unit) == false) { return ; } unit.AutoCastSpell[spellid] = on; }
/** ** Set new rally point for unit ** ** @param unit pointer to unit. ** @param pos new rally point map position. */ void CommandRallyPoint(CUnit &unit, const Vec2i &pos) { Assert(Map.Info.IsPointOnMap(pos)); if (IsUnitValidForNetwork(unit) == false) { return ; } unit.RallyPointPos = pos; }
/** ** 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); }
/** ** 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); }
/** ** 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); }
/** ** 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); }
/** ** 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); }
/** ** 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 ; } //Wyrmgus start CMapField &mf = *Map.Field(unit.tilePos); CMapField &new_mf = *Map.Field(pos); //if the unit is a land unit over a raft, move the raft instead of the unit 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 if ((new_mf.Flags & MapFieldWaterAllowed) || (new_mf.Flags & MapFieldCoastAllowed) || (mf.Flags & MapFieldWaterAllowed)) { // if is standing on water, tell the raft to go to the nearest coast, even if the ultimate goal is on land CommandStopUnit(unit); CommandMove(*table[i], pos, flush); return; } } } } //Wyrmgus end 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); }
/** ** Repair unit ** ** @param unit pointer to unit. ** @param pos map position to repair. ** @param dest or unit to be repaired. FIXME: not supported ** @param flush if true, flush command queue. */ void CommandRepair(CUnit &unit, const Vec2i &pos, CUnit *dest, 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; } } if (dest) { *order = COrder::NewActionRepair(unit, *dest); } else { *order = COrder::NewActionRepair(pos); } ClearSavedAction(unit); }
/** ** Let unit returning goods. ** ** @param unit pointer to unit. ** @param depot bring goods to this depot. ** @param flush if true, flush command queue. */ void CommandReturnGoods(CUnit &unit, CUnit *depot, int flush) { if (IsUnitValidForNetwork(unit) == false) { return ; } if ((unit.Type->BoolFlag[HARVESTER_INDEX].value && unit.ResourcesHeld == 0) || (!unit.Type->Building && !unit.Type->BoolFlag[HARVESTER_INDEX].value)) { 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::NewActionReturnGoods(unit, depot); ClearSavedAction(unit); }