/*
**	Wait in wood deposit.
*/
local int WaitInWoodDeposit(Unit* unit)
{
    Unit* destu;

    DebugLevel3("Waiting\n");

    if( !unit->Value ) {
	//
	//	Drop out unit at nearest point to target.
	//
	destu=WoodDepositOnMap(unit->X,unit->Y);
	DropOutNearest(unit
		,unit->Command.Data.Move.SX
		,unit->Command.Data.Move.SY
		,destu->Type->TileWidth
		,destu->Type->TileHeight);

	//
	//	Return to chop point.
	//
	unit->Command.Action=UnitActionHarvest;
	unit->Command.Data.Move.Fast=1;
	unit->Command.Data.Move.Goal=NoUnitP;
	unit->Command.Data.Move.Range=0;
	unit->Command.Data.Move.DX=unit->Command.Data.Move.SX;
	unit->Command.Data.Move.DY=unit->Command.Data.Move.SY;

	if( UnitVisible(unit) ) {
	    MustRedraw|=RedrawMap;
	}
	unit->Wait=1;
	unit->WoodToHarvest=CHOP_FOR_WOOD;
	return 1;
    }

    if( unit->Value<UNIT_MAX_WAIT ) {
	unit->Wait=unit->Value;
    } else {
	unit->Wait=UNIT_MAX_WAIT;
    }
    unit->Value-=unit->Wait;

    return 0;
}
示例#2
0
/**
**  Find something else to do when the resource is exhausted.
**  This is called from GatherResource when the resource is empty.
**
**  @param unit    pointer to harvester unit.
**  @param source  pointer to resource unit.
*/
void COrder_Resource::LoseResource(CUnit &unit, CUnit &source)
{
	CUnit *depot;
	const ResourceInfo &resinfo = *unit.Type->ResInfo[this->CurrentResource];

	//Wyrmgus start
	const CUnitType &source_type = *source.Type;
	
//	Assert((unit.Container == &source && !resinfo.HarvestFromOutside)
//		   || (!unit.Container && resinfo.HarvestFromOutside));
	Assert((unit.Container == &source && !source_type.BoolFlag[HARVESTFROMOUTSIDE_INDEX].value)
		   || (!unit.Container && source_type.BoolFlag[HARVESTFROMOUTSIDE_INDEX].value));
	//Wyrmgus end

	//Wyrmgus start
//	if (resinfo.HarvestFromOutside) {
	if (source_type.BoolFlag[HARVESTFROMOUTSIDE_INDEX].value) {
	//Wyrmgus end
		this->ClearGoal();
		--source.Resource.Active;
	}

	// Continue to harvest if we aren't fully loaded
	//Wyrmgus start
//	if (resinfo.HarvestFromOutside && unit.ResourcesHeld < resinfo.ResourceCapacity) {
	if (source_type.BoolFlag[HARVESTFROMOUTSIDE_INDEX].value && unit.ResourcesHeld < resinfo.ResourceCapacity) {
	//Wyrmgus end
		CUnit *goal = UnitFindResource(unit, unit, 15, this->CurrentResource, 1);

		if (goal) {
			this->goalPos.x = -1;
			this->goalPos.y = -1;
			this->State = SUB_START_RESOURCE;
			this->SetGoal(goal);
			return;
		}
	}

	// If we are fully loaded first search for a depot.
	if (unit.ResourcesHeld && (depot = FindDeposit(unit, 1000, unit.CurrentResource))) {
		if (unit.Container) {
			DropOutNearest(unit, depot->tilePos + depot->Type->GetHalfTileSize(), &source);
		}
		// Remember where it mined, so it can look around for another resource.
		//
		//FIXME!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
		//unit.CurrentOrder()->Arg1.ResourcePos = (unit.X << 16) | unit.Y;
		this->DoneHarvesting = true;
		UnitGotoGoal(unit, depot, SUB_MOVE_TO_DEPOT);
		DebugPrint("%d: Worker %d report: Resource is exhausted, Going to depot\n"
				   _C_ unit.Player->Index _C_ UnitNumber(unit));
		return;
	}
	// No depot found, or harvester empty
	// Dump the unit outside and look for something to do.
	if (unit.Container) {
		//Wyrmgus start
//		Assert(!resinfo.HarvestFromOutside);
		Assert(!source_type.BoolFlag[HARVESTFROMOUTSIDE_INDEX].value);
		//Wyrmgus end
		DropOutOnSide(unit, LookingW, &source);
	}
	this->goalPos.x = -1;
	this->goalPos.y = -1;
	//use depot as goal
	depot = UnitFindResource(unit, unit, 15, this->CurrentResource, unit.Player->AiEnabled);
	if (depot) {
		DebugPrint("%d: Worker %d report: Resource is exhausted, Found another resource.\n"
				   _C_ unit.Player->Index _C_ UnitNumber(unit));
		this->State = SUB_START_RESOURCE;
		this->SetGoal(depot);
	} else {
		DebugPrint("%d: Worker %d report: Resource is exhausted, Just sits around confused.\n"
				   _C_ unit.Player->Index _C_ UnitNumber(unit));
		this->Finished = true;
	}
}
示例#3
0
/**
**  Stop gathering from the resource, go home.
**
**  @param unit  Poiner to unit.
**
**  @return      TRUE if ready, otherwise FALSE.
*/
int COrder_Resource::StopGathering(CUnit &unit)
{
	CUnit *source = 0;
	const ResourceInfo &resinfo = *unit.Type->ResInfo[this->CurrentResource];

	//Wyrmgus start
//	if (!resinfo.TerrainHarvester) {
	if (!Map.Info.IsPointOnMap(this->goalPos)) {
	//Wyrmgus end
		//Wyrmgus start
//		if (resinfo.HarvestFromOutside) {
		if (this->GetGoal() && this->GetGoal()->Type->BoolFlag[HARVESTFROMOUTSIDE_INDEX].value) {
		//Wyrmgus end
			source = this->GetGoal();
			this->ClearGoal();
		} else {
			source = unit.Container;
		}
		source->Resource.Active--;
		Assert(source->Resource.Active >= 0);
		//Store resource position.
		this->Resource.Mine = source;
		
		if (Preference.MineNotifications && unit.Player->Index == ThisPlayer->Index 
			&& source->IsAlive()
			&& !source->MineLow
			&& source->ResourcesHeld * 100 / source->Variable[GIVERESOURCE_INDEX].Max <= 10
			//Wyrmgus start
//			&& source->Variable[GIVERESOURCE_INDEX].Max > DefaultIncomes[this->CurrentResource]) {
			&& source->Variable[GIVERESOURCE_INDEX].Max > (DefaultIncomes[this->CurrentResource] * 10)) {
			//Wyrmgus end
				//Wyrmgus start
//				unit.Player->Notify(NotifyYellow, source->tilePos, _("%s is running low!"), source->Type->Name.c_str());
				unit.Player->Notify(NotifyYellow, source->tilePos, _("Our %s is nearing depletion!"), source->Type->Name.c_str());
				//Wyrmgus end
				source->MineLow = 1;
		}

		if (source->Type->MaxOnBoard) {
			int count = 0;
			CUnit *worker = source->Resource.Workers;
			CUnit *next = NULL;
			for (; NULL != worker; worker = worker->NextWorker) {
				Assert(worker->CurrentAction() == UnitActionResource);
				COrder_Resource &order = *static_cast<COrder_Resource *>(worker->CurrentOrder());
				if (worker != &unit && order.IsGatheringWaiting()) {
					count++;
					if (next) {
						if (next->Wait > worker->Wait) {
							next = worker;
						}
					} else {
						next = worker;
					}
				}
			}
			if (next) {
				if (!unit.Player->AiEnabled) {
					DebugPrint("%d: Worker %d report: Unfreez resource gathering of %d <Wait %d> on %d [Assigned: %d Waiting %d].\n"
							   _C_ unit.Player->Index _C_ UnitNumber(unit)
							   _C_ UnitNumber(*next) _C_ next->Wait
							   _C_ UnitNumber(*source) _C_ source->Resource.Assigned
							   _C_ count);
				}
				next->Wait = 0;
				//source->Data.Resource.Waiting = count - 1;
				//Assert(source->Data.Resource.Assigned >= source->Data.Resource.Waiting);
				//StartGathering(next);
			}
		}
	} else {
		// Store resource position.
		this->Resource.Pos = unit.tilePos;
		Assert(this->Resource.Mine == NULL);
	}

#ifdef DEBUG
	if (!unit.ResourcesHeld) {
		DebugPrint("Unit %d is empty???\n" _C_ UnitNumber(unit));
	}
#endif

	// Find and send to resource deposit.
	CUnit *depot = FindDeposit(unit, 1000, unit.CurrentResource);
	if (!depot || !unit.ResourcesHeld || this->Finished) {
		//Wyrmgus start
//		if (!(resinfo.HarvestFromOutside || resinfo.TerrainHarvester)) {
		if (!((source && source->Type->BoolFlag[HARVESTFROMOUTSIDE_INDEX].value) || Map.Info.IsPointOnMap(this->goalPos))) {
		//Wyrmgus end
			Assert(unit.Container);
			DropOutOnSide(unit, LookingW, source);
		}
		CUnit *mine = this->Resource.Mine;

		if (mine) {
			unit.DeAssignWorkerFromMine(*mine);
			this->Resource.Mine = NULL;
		}

		DebugPrint("%d: Worker %d report: Can't find a resource [%d] deposit.\n"
				   _C_ unit.Player->Index _C_ UnitNumber(unit) _C_ unit.CurrentResource);
		this->Finished = true;
		return 0;
	} else {
		//Wyrmgus start
//		if (!(resinfo.HarvestFromOutside || resinfo.TerrainHarvester)) {
		if (!((source && source->Type->BoolFlag[HARVESTFROMOUTSIDE_INDEX].value) || Map.Info.IsPointOnMap(this->goalPos))) {
		//Wyrmgus end
			Assert(unit.Container);
			DropOutNearest(unit, depot->tilePos + depot->Type->GetHalfTileSize(), source);
		}
		UnitGotoGoal(unit, depot, SUB_MOVE_TO_DEPOT);
	}
	if (IsOnlySelected(unit)) {
		SelectedUnitChanged();
	}
#if 1
	return 1;
#endif
}
示例#4
0
/**
**  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;
}