Exemple #1
0
/**
**  Give up on gathering.
**
**  @param unit  Pointer to unit.
*/
void COrder_Resource::ResourceGiveUp(CUnit &unit)
{
	DebugPrint("%d: Worker %d report: Gave up on resource gathering.\n" _C_ unit.Player->Index _C_ UnitNumber(unit));
	if (this->HasGoal()) {
		DropResource(unit);
		this->ClearGoal();
	}
	this->Finished = true;
}
Exemple #2
0
/**
**  Start harvesting the resource.
**
**  @param unit  Pointer to unit.
**
**  @return      TRUE if ready, otherwise FALSE.
*/
int COrder_Resource::StartGathering(CUnit &unit)
{
	CUnit *goal;
	const ResourceInfo &resinfo = *unit.Type->ResInfo[this->CurrentResource];
	Assert(!unit.IX);
	Assert(!unit.IY);

	//Wyrmgus start
//	if (resinfo.TerrainHarvester) {
	if (Map.Info.IsPointOnMap(this->goalPos)) {
	//Wyrmgus end
		// This shouldn't happened?
#if 0
		if (!Map.IsTerrainResourceOnMap(unit.Orders->goalPos, this->CurrentResource)) {
			DebugPrint("Wood gone, just like that?\n");
			return 0;
		}
#endif
		UnitHeadingFromDeltaXY(unit, this->goalPos - unit.tilePos);
		if (resinfo.WaitAtResource) {
			this->TimeToHarvest = std::max<int>(1, resinfo.WaitAtResource * SPEEDUP_FACTOR / unit.Player->SpeedResourcesHarvest[resinfo.ResourceId]);
		} else {
			this->TimeToHarvest = 1;
		}
		this->DoneHarvesting = 0;
		if (this->CurrentResource != unit.CurrentResource) {
			DropResource(unit);
			unit.CurrentResource = this->CurrentResource;
		}
		return 1;
	}

	goal = this->GetGoal();

	// Target is dead, stop getting resources.
	if (!goal || goal->IsVisibleAsGoal(*unit.Player) == false) {
		// Find an alternative, but don't look too far.
		this->goalPos.x = -1;
		this->goalPos.y = -1;
		if ((goal = UnitFindResource(unit, unit, 15, this->CurrentResource, unit.Player->AiEnabled))) {
			this->State = SUB_START_RESOURCE;
			this->SetGoal(goal);
		} else {
			this->ClearGoal();
			this->Finished = true;
		}
		return 0;
	}

	// FIXME: 0 can happen, if to near placed by map designer.
	Assert(unit.MapDistanceTo(*goal) <= 1);

	// Update the heading of a harvesting unit to looks straight at the resource.
	//Wyrmgus start
//	UnitHeadingFromDeltaXY(unit, goal->tilePos - unit.tilePos + goal->Type->GetHalfTileSize());
	UnitHeadingFromDeltaXY(unit, Vec2i(goal->tilePos.x * PixelTileSize.x, goal->tilePos.y * PixelTileSize.y) - Vec2i(unit.tilePos.x * PixelTileSize.x, unit.tilePos.y * PixelTileSize.y) + goal->Type->GetHalfTilePixelSize() - unit.Type->GetHalfTilePixelSize());
	//Wyrmgus end

	// If resource is still under construction, wait!
	if ((goal->Type->MaxOnBoard && goal->Resource.Active >= goal->Type->MaxOnBoard)
		|| goal->CurrentAction() == UnitActionBuilt) {
		// FIXME: Determine somehow when the resource will be free to use
		// FIXME: Could we somehow find another resource? Think minerals
		// FIXME: We should add a flag for that, and a limited range.
		// However the CPU usage is really low (no pathfinding stuff).
		unit.Wait = 10;
		return 0;
	}

	// Place unit inside the resource
	//Wyrmgus start
//	if (!resinfo.HarvestFromOutside) {
	if (!goal->Type->BoolFlag[HARVESTFROMOUTSIDE_INDEX].value) {
	//Wyrmgus end
		if (goal->Variable[MAXHARVESTERS_INDEX].Value == 0 || goal->Variable[MAXHARVESTERS_INDEX].Value > goal->InsideCount) {
			this->ClearGoal();
			int selected = unit.Selected;
			unit.Remove(goal);
			if (selected && !Preference.DeselectInMine) {
				unit.Removed = 0;
				SelectUnit(unit);
				SelectionChanged();
				unit.Removed = 1;
			}
		} else if (goal->Variable[MAXHARVESTERS_INDEX].Value <= goal->InsideCount) {
			//Resource is full, wait
			unit.Wait = 10;
			return 0;
		}
	}

	if (this->CurrentResource != unit.CurrentResource) {
		DropResource(unit);
		unit.CurrentResource = this->CurrentResource;
	}

	// Activate the resource
	goal->Resource.Active++;

	if (resinfo.WaitAtResource) {
		//Wyrmgus start
//		this->TimeToHarvest = std::max<int>(1, resinfo.WaitAtResource * SPEEDUP_FACTOR / unit.Player->SpeedResourcesHarvest[resinfo.ResourceId]);
		int wait_at_resource = resinfo.WaitAtResource;
		if (!goal->Type->BoolFlag[HARVESTFROMOUTSIDE_INDEX].value) {
			wait_at_resource = resinfo.WaitAtResource * 100 / resinfo.ResourceStep;
		}
		this->TimeToHarvest = std::max<int>(1, wait_at_resource * SPEEDUP_FACTOR / (unit.Player->SpeedResourcesHarvest[resinfo.ResourceId] + goal->Variable[TIMEEFFICIENCYBONUS_INDEX].Value));
		//Wyrmgus end
	} else {
		this->TimeToHarvest = 1;
	}
	this->DoneHarvesting = 0;
	return 1;
}
void SSResourceManager::UpdateSimLayer( const float timestep )
{
	fVector<int> resourceCounts( m_Resources.size( ) );
	for ( auto& it : resourceCounts )
		it = 0;

	// Get number of resources on spawn point
	Entity entityID = 0;
	for ( auto& entity : g_EntityManager.GetEntityMasks( ) )
	{
		if ( entity & GetDenseComponentFlag<ResourceComponent>( ) )
		{
			ResourceComponent* resourceComponent = GetDenseComponent<ResourceComponent>( entityID );
			if ( resourceComponent->SpawnedBy != -1 )
				++resourceCounts[resourceComponent->SpawnedBy];
		}
		++entityID;
	}

	// Initiate resource drop
	m_FirstSpawnDelay -= timestep;
	if ( m_FirstSpawnDelay <= 0.0f && m_InitialSpawn == nullptr )
	{
		int spawnID = 0;
		for ( auto& resource : m_Resources )
		{
			float respawnRate = m_RespawnTypes[resource.RespawnType].RespawnRate;

			resource.LastSpawn -= timestep;
			if ( resource.LastSpawn <= 0.0f )
			{
				resource.LastSpawn = respawnRate / 2.0f + respawnRate * (float) g_Randomizer.SimGenerateRandom( );

				float dropOrgX			= 50.0f * (2.0f * (float) g_Randomizer.SimGenerateRandom( ) - 1.0f);
				float dropOrgZ			= 50.0f * (2.0f * (float) g_Randomizer.SimGenerateRandom( ) - 1.0f);
				glm::vec3 spawnOffset	= glm::vec3( dropOrgX, RESOURCE_RESPAWN_DROP_HEIGHT, dropOrgZ );

				int respawnCount		= GetRespawnAmount( resourceCounts[spawnID], resource.RespawnType );

				for ( int i = 0; i < respawnCount; ++i )
				{
					float		spawnAngle			= (float) g_Randomizer.SimGenerateRandom( ) * glm::pi<float>( ) * 2.0f;
					float		spawnDist			= (float) g_Randomizer.SimGenerateRandom( ) * resource.RespawnRadius;

					glm::vec3	spawnPos;
					spawnPos.x						= resource.Position.x + glm::cos( spawnAngle ) * spawnDist;
					spawnPos.z						= resource.Position.z + glm::sin( spawnAngle ) * spawnDist;
					spawnPos.y						= gfx::g_GFXTerrain.GetHeightAtWorldCoord( spawnPos.x, spawnPos.z );

					float		orientationAngle	= (float) g_Randomizer.SimGenerateRandom( ) * glm::pi<float>( ) * 2.0f;
					glm::quat	spawnOrientation	= glm::rotate( resource.Orientation, orientationAngle, glm::vec3( 0.0f, 1.0f, 0.0f ) );

					pString		model				= m_ResourceModels.at( g_Randomizer.SimRand( 0, (unsigned int) m_ResourceModels.size( ) ) );

					DropResource( spawnPos, resource.Scale, spawnOrientation, model, spawnOffset, spawnID );					
				}
			}

			++spawnID;
		}
	}

	// Drop in initial resources
	else if ( m_FirstSpawnDelay <= 0.0f && m_InitialSpawn )
	{
		for ( auto& resource : *m_InitialSpawn )
			DropResource( resource.Position, resource.Scale, resource.Orientation, resource.ModelPath, glm::vec3( 0.0f, RESOURCE_RESPAWN_DROP_HEIGHT, 0.0f ), -1 );
		tDelete( m_InitialSpawn );
		m_InitialSpawn = nullptr;

		m_FirstSpawnDelay = RESOURCE_SPAWN_INITIAL_DELAY;
	}

	// Update resource drops
	for ( auto& drop : m_ResourceSpawn )
	{
		if ( drop.Active )
		{
			drop.DropTime -= timestep;
			if ( drop.DropTime <= 0.0f )
			{
				drop.Active = false;
				if ( drop.Effect )
					drop.Effect->TimeToLive = drop.Effect->ParticlesTimeToLive;

				EntityFactory::CreateResource( drop.Position.x, drop.Position.z, drop.Scale, drop.Orientation, drop.ModelPath.c_str( ), drop.SpawnedBy );
				g_SSMiniMap.PingLocation( drop.Position );
			}
		}
	}
}