bool COrder_Resource::FindAnotherResource(CUnit &unit) { if (this->CurrentResource) { const ResourceInfo *resinfo = unit.Type->ResInfo[this->CurrentResource]; if (resinfo) { //Wyrmgus start // if (!resinfo.TerrainHarvester) { if (!Map.Info.IsPointOnMap(this->goalPos)) { //Wyrmgus end CUnit *newGoal = UnitFindResource(unit, this->Resource.Mine ? *this->Resource.Mine : unit, 8, this->CurrentResource, 1); if (newGoal) { CUnit *mine = this->Resource.Mine; if (mine) { unit.DeAssignWorkerFromMine(*mine); } unit.AssignWorkerToMine(*newGoal); this->Resource.Mine = newGoal; this->goalPos.x = -1; this->goalPos.y = -1; this->State = SUB_MOVE_TO_RESOURCE; this->SetGoal(newGoal); return true; } } else { Vec2i resPos; //Wyrmgus start // if (FindTerrainType(unit.Type->MovementMask, MapFieldForest, 8, *unit.Player, unit.tilePos, &resPos)) { if ((this->CurrentResource == WoodCost && FindTerrainType(unit.Type->MovementMask, MapFieldForest, 8, *unit.Player, unit.tilePos, &resPos)) || (this->CurrentResource == StoneCost && FindTerrainType(unit.Type->MovementMask, MapFieldRocks, 8, *unit.Player, unit.tilePos, &resPos))) { //Wyrmgus end this->goalPos = resPos; this->State = SUB_MOVE_TO_RESOURCE; DebugPrint("Found a better place to harvest %d,%d\n" _C_ resPos.x _C_ resPos.y); return true; } } } } return false; }
/** ** Initialize ** ** return false if action is canceled, true otherwise. */ bool COrder_Resource::ActionResourceInit(CUnit &unit) { Assert(this->State == SUB_START_RESOURCE); this->Range = 0; CUnit *const goal = this->GetGoal(); CUnit *mine = this->Resource.Mine; if (mine) { unit.DeAssignWorkerFromMine(*mine); this->Resource.Mine = NULL; } if (goal && goal->IsAlive() == false) { return false; } if (goal && goal->CurrentAction() != UnitActionBuilt) { unit.AssignWorkerToMine(*goal); this->Resource.Mine = goal; } UnitGotoGoal(unit, goal, SUB_MOVE_TO_RESOURCE); return true; }
/** ** Wait in depot, for the resources stored. ** ** @param unit Pointer to unit. ** ** @return TRUE if ready, otherwise FALSE. */ bool COrder_Resource::WaitInDepot(CUnit &unit) { const ResourceInfo &resinfo = *unit.Type->ResInfo[this->CurrentResource]; const CUnit *depot = ResourceDepositOnMap(unit.tilePos, resinfo.ResourceId); //Assert(depot); // Range hardcoded. don't stray too far though //Wyrmgus start // if (resinfo.TerrainHarvester) { if (!this->Resource.Mine) { //Wyrmgus end Vec2i pos = this->Resource.Pos; //Wyrmgus start // if (FindTerrainType(unit.Type->MovementMask, MapFieldForest, 10, *unit.Player, pos, &pos)) { if ((this->CurrentResource == WoodCost && FindTerrainType(unit.Type->MovementMask, MapFieldForest, 10, *unit.Player, pos, &pos)) || (this->CurrentResource == StoneCost && FindTerrainType(unit.Type->MovementMask, MapFieldRocks, 10, *unit.Player, pos, &pos))) { //Wyrmgus end if (depot) { DropOutNearest(unit, pos, depot); } this->goalPos = pos; //Wyrmgus start if (this->CurrentResource == WoodCost) { //tree tiles can regrow, so we need to check if any have regrown closer to the worker Vec2i forestPos; int max_forest_range = std::max<int>(abs(unit.tilePos.x - this->goalPos.x), abs(unit.tilePos.y - this->goalPos.y)); if (FindTerrainType(unit.Type->MovementMask, MapFieldForest, max_forest_range, *unit.Player, unit.tilePos, &forestPos)) { if (PlaceReachable(unit, forestPos, 1, 1, 0, 1, max_forest_range * 4)) { this->goalPos = forestPos; } } } //Wyrmgus end } else { if (depot) { DropOutOnSide(unit, LookingW, depot); } this->Finished = true; return false; } } else { const unsigned int tooManyWorkers = 15; CUnit *mine = this->Resource.Mine; const int range = 15; CUnit *newdepot = NULL; CUnit *goal = NULL; const bool longWay = unit.pathFinderData->output.Cycles > 500; //Wyrmgus start // if (unit.Player->AiEnabled && AiPlayer && AiPlayer->BuildDepots) { if (depot && unit.Player->AiEnabled && AiPlayer && AiPlayer->BuildDepots) { //check if the depot is valid //Wyrmgus end // If the depot is overused, we need first to try to switch into another depot // Use depot's ref counter for that if (longWay || !mine || (depot->Refs > tooManyWorkers)) { newdepot = AiGetSuitableDepot(unit, *depot, &goal); if (newdepot == NULL && longWay) { // We need a new depot AiNewDepotRequest(unit); } } } // If goal is not NULL, then we got it in AiGetSuitableDepot if (!goal) { goal = UnitFindResource(unit, newdepot ? *newdepot : (mine ? *mine : unit), mine ? range : 1000, this->CurrentResource, unit.Player->AiEnabled, newdepot ? newdepot : depot); } if (goal) { if (depot) { DropOutNearest(unit, goal->tilePos + goal->Type->GetHalfTileSize(), depot); } if (goal != mine) { if (mine) { unit.DeAssignWorkerFromMine(*mine); } unit.AssignWorkerToMine(*goal); this->Resource.Mine = goal; } this->SetGoal(goal); this->goalPos.x = this->goalPos.y = -1; } else { #ifdef DEBUG const Vec2i &pos = mine ? mine->tilePos : unit.tilePos; DebugPrint("%d: Worker %d report: [%d,%d] Resource gone near [%d,%d] in range %d. Sit and play dumb.\n" _C_ unit.Player->Index _C_ UnitNumber(unit) _C_ unit.tilePos.x _C_ unit.tilePos.y _C_ pos.x _C_ pos.y _C_ range); #endif // DEBUG if (depot) { DropOutOnSide(unit, LookingW, depot); } if (mine) { unit.DeAssignWorkerFromMine(*mine); this->Resource.Mine = NULL; } this->Finished = true; return false; } } return true; }