void UFlareSpacecraftDamageSystem::Start()
{
	// Reload components
	Components = Spacecraft->GetComponentsByClass(UFlareSpacecraftComponent::StaticClass());

	TArray<UFlareSpacecraftComponent*> PowerSources;
	for (int32 ComponentIndex = 0; ComponentIndex < Components.Num(); ComponentIndex++)
	{
		UFlareSpacecraftComponent* Component = Cast<UFlareSpacecraftComponent>(Components[ComponentIndex]);
		// Fill power sources
		if (Component->IsGenerator())
		{
			PowerSources.Add(Component);
		}
	}

	// Second pass, update component power sources and update power
	for (int32 ComponentIndex = 0; ComponentIndex < Components.Num(); ComponentIndex++)
	{
		UFlareSpacecraftComponent* Component = Cast<UFlareSpacecraftComponent>(Components[ComponentIndex]);
		Component->UpdatePowerSources(&PowerSources);
	}
	UpdatePower();

	// Init alive status
	WasAlive = Parent->IsAlive();
	TimeSinceLastExternalDamage = 10000;
}
void ABatteryCollectorCharacter::CollectPickup()
{
	TArray<AActor*> CollectedActors;
	CollectionSphere->GetOverlappingActors(CollectedActors);

	float collectedPower = 0;

	for (int i = 0; i < CollectedActors.Num(); i++)
	{
		APickup* const testPickup = Cast<APickup>(CollectedActors[i]);

		if (testPickup && !testPickup->IsPendingKill() && testPickup->IsActive())
		{
			testPickup->WasCollected();
			ABatteryPickup* const tempBattery = Cast<ABatteryPickup>(testPickup);
			if(tempBattery)
			{
				collectedPower += tempBattery->GetPower();
			}
			testPickup->SetActive(false);
		}
	}

	if (collectedPower > 0)
	{
		UpdatePower(collectedPower);
	}
}
void UFlareSpacecraftDamageSystem::OnElectricDamage(float DamageRatio)
{
	float MaxPower = 0.f;
	float AvailablePower = 0.f;

	float Total = 0.f;
	float GeneratorCount = 0;
	for (int32 ComponentIndex = 0; ComponentIndex < Components.Num(); ComponentIndex++)
	{
		UFlareSpacecraftComponent* Component = Cast<UFlareSpacecraftComponent>(Components[ComponentIndex]);
		MaxPower += Component->GetMaxGeneratedPower();
		AvailablePower += Component->GetGeneratedPower();
	}

	float PowerRatio = AvailablePower/MaxPower;


	//FLOGV("OnElectricDamage initial PowerOutageDelay=%f, PowerOutageAcculumator=%f, DamageRatio=%f, PowerRatio=%f", Data->PowerOutageDelay, Data->PowerOutageAcculumator, DamageRatio, PowerRatio);


	Data->PowerOutageAcculumator += DamageRatio * 2.f;
	if (!Data->PowerOutageDelay && PowerRatio > 0)
	{
		if (FMath::FRand() > 1.f + PowerRatio / 2.f - Data->PowerOutageAcculumator / 2.f)
		{
			Data->PowerOutageDelay += FMath::FRandRange(1, 5) /  (2 * PowerRatio);
			Data->PowerOutageAcculumator = -Data->PowerOutageAcculumator * PowerRatio;
			UpdatePower();
		}
	}
}
void ABatteryCollectorCharacter::CollectPickups()
{
	// Get all overlaping actors
	TArray<AActor*> CollectedActors;
	CollectionSphere->GetOverlappingActors(CollectedActors);

	// track amount of collected power
	float CollectedPower = 0;

	// For each Actor we collected
	for (int32 CollectedCount = 0; CollectedCount < CollectedActors.Num(); ++CollectedCount)
	{
		// Cast the actor to APickup
		APickup* const TestPickup = Cast<APickup>(CollectedActors[CollectedCount]);
		// If the cast if successful and the pickup is valid and active
		if (TestPickup && !TestPickup->IsPendingKill() && TestPickup->IsActive())
		{
			// Call pickup's WasCollected function
			TestPickup->WasCollected();
			// Check is Pickup a BatteryPickup
			ABatteryPickup* const TestBattery = Cast<ABatteryPickup>(TestPickup);
			if (TestBattery)
			{
				CollectedPower += TestBattery->GetPower();
			}
			// Deactivate pickup
			TestPickup->SetActive(false);
		}
	}
	if (CollectedPower > 0)
	{
		// Update character's power level 
		UpdatePower(CollectedPower);
	}
}
/**
 *	Called when we press the E key near a pick up
 */
void ABatteryCollectorCharacter::CollectPickUps()
{
	// Get all overlapping actors and store them in an array for each actor collected
	TArray<AActor*>	CollectedActors;
	CollectionSphere -> GetOverlappingActors(CollectedActors);

	float _collectedPower = 0.f;															// 	Keep track of collected power
	for (int32 iCollected = 0; iCollected < CollectedActors.Num(); ++iCollected)
	{
		APickup* const testPickup = Cast<APickup>(CollectedActors[iCollected]);				//	Cast the actor to a pickup
		if ((testPickup) && (!testPickup -> IsPendingKill()) && (testPickup -> IsActive()))
		{
			testPickup 	-> WasCollected();													//	Battery collected
			ABatteryPickup* const _testBattery = Cast<ABatteryPickup>(testPickup);			//	Check if the pick up is a battery

			if (_testBattery)
			{
				_collectedPower += _testBattery -> GetPower();
			}

			testPickup 	-> SetActive(false);												//	Deactivate pick up
		}
	}
	if (_collectedPower >= 0)
	{
		UpdatePower(_collectedPower);
	}
}
void UFlareSpacecraftDamageSystem::ApplyDamage(float Energy, float Radius, FVector Location, EFlareDamage::Type DamageType, UFlareCompany* DamageSource)
{
	// The damages are applied to all component touching the sphere defined by the radius and the
	// location in parameter.
	// The maximum damage are applied to a component only if its bounding sphere touch the center of
	// the damage sphere. There is a linear decrease of damage with a minumum of 0 if the 2 sphere
	// only touch.

	//FLOGV("Apply %f damages to %s with radius %f at %s", Energy, *(Spacecraft->GetImmatriculation().ToString()), Radius, *Location.ToString());
	//DrawDebugSphere(Spacecraft->GetWorld(), Location, Radius * 100, 12, FColor::Red, true);

	for (int32 ComponentIndex = 0; ComponentIndex < Components.Num(); ComponentIndex++)
	{
		UFlareSpacecraftComponent* Component = Cast<UFlareSpacecraftComponent>(Components[ComponentIndex]);

		float ComponentSize;
		FVector ComponentLocation;
		Component->GetBoundingSphere(ComponentLocation, ComponentSize);

		float Distance = (ComponentLocation - Location).Size() / 100.0f;
		float IntersectDistance =  Radius + ComponentSize/100 - Distance;

		//DrawDebugSphere(Spacecraft->GetWorld(), ComponentLocation, ComponentSize, 12, FColor::Green, true);

		// Hit this component
		if (IntersectDistance > 0)
		{
			//FLOGV("Component %s. ComponentSize=%f, Distance=%f, IntersectDistance=%f", *(Component->GetReadableName()), ComponentSize, Distance, IntersectDistance);
			float Efficiency = FMath::Clamp(IntersectDistance / Radius , 0.0f, 1.0f);
			float InflictedDamageRatio = Component->ApplyDamage(Energy * Efficiency);

			if(DamageSource != NULL && DamageSource != Spacecraft->GetParent()->GetCompany())
			{
				Spacecraft->GetParent()->GetCompany()->GiveReputation(DamageSource, - (InflictedDamageRatio * 30), true);
			}
		}
	}

	// Update power
	UpdatePower();

	// Heat the ship
	Data->Heat += Energy;

	switch (DamageType) {
	case EFlareDamage::DAM_ArmorPiercing:
	case EFlareDamage::DAM_HighExplosive:
	case EFlareDamage::DAM_HEAT:
		//FLOGV("%s Reset TimeSinceLastExternalDamage", *Spacecraft->GetImmatriculation().ToString());
		TimeSinceLastExternalDamage = 0;
		break;
	case EFlareDamage::DAM_Collision:
	case EFlareDamage::DAM_Overheat:
	default:
		// Don't reset timer
		break;
	}
}
Beispiel #7
0
void CCar::Stall()
{
	//m_car_sound->Stall();
	//StopExhausts();
	AscCall(ascSndStall);
	AscCall(ascExhoustStop);
	NeutralDrive();//set zero speed
	b_engine_on=false;
	UpdatePower();//set engine friction;
	m_current_rpm=0.f;

}
 void AAssignment_1Character::NotifyActorBeginOverlap(class AActor* Other)
{
    if (Other != nullptr)
    {
        AWirePickup *TestWire = Cast<AWirePickup>(Other);
        if (TestWire && !TestWire->IsPendingKill() && TestWire->IsActive())
        {
            TestWire->WasCollected();
            UpdatePower(TestWire->GetDrain());
            WireCollisionEffect(TestWire->GetActorLocation());
        }
    }
}
        void UpdateAI(const uint32 diff)
        {
            _events.Update(diff);

            switch (_events.ExecuteEvent())
            {
                case EVENT_CHECK_PLAYERS:
                {
                    bool playerNearWithQuest = CheckPlayers();

                    if (inProgress && !playerNearWithQuest)
                    {
                        inProgress = false;
                        Reset();
                    }
                    else if (!inProgress && playerNearWithQuest)
                    {
                        inProgress = true;
                        _events.ScheduleEvent(EVENT_UPDATE_POWER,  UPDATE_POWER_TIMER);
                        _events.ScheduleEvent(EVENT_SUMMON_ENNEMY, 5000);
                        _events.ScheduleEvent(EVENT_SUMMON_HEALER, 5000);
                    }
                    _events.ScheduleEvent(EVENT_CHECK_PLAYERS, 5000);
                    break;
                }
                case EVENT_UPDATE_POWER:
                    UpdatePower();
                    _events.ScheduleEvent(EVENT_UPDATE_POWER, UPDATE_POWER_TIMER);
                    break;
                case EVENT_SUMMON_ENNEMY:
                    if (ennemiesCount < (healerCount / 2))
                    {
                        SummonEnnemy();
                        _events.ScheduleEvent(EVENT_SUMMON_ENNEMY, 5000);
                    }
                    else
                        _events.ScheduleEvent(EVENT_SUMMON_ENNEMY, 7500);
                    break;
                case EVENT_SUMMON_HEALER:
                    if (healerCount < MAX_HEALER_COUNT)
                        SummonHealer();

                    _events.ScheduleEvent(EVENT_SUMMON_HEALER, 12500);
                    break;
            }
        }
void CASW_Weapon_Blink::ItemPostFrame( void )
{
	BaseClass::ItemPostFrame();

	UpdatePower();

	if ( m_bInReload )
		return;
	
	CBasePlayer *pOwner = GetCommander();
	if ( !pOwner )
		return;

	//Allow a refire as fast as the player can click
	if ( ( ( pOwner->m_nButtons & IN_ATTACK ) == false ) && ( m_flSoonestPrimaryAttack < gpGlobals->curtime ) )
	{
		m_flNextPrimaryAttack = gpGlobals->curtime - 0.1f;
	}
}
    void UpdateAI(const uint32 diff)
    {
        if(ThreatTimer < diff)
        {
            UpdatePower();
            UpdateThreat();
            ThreatTimer = 4000;
        }
        else ThreatTimer -= diff;

        if(CCTimer < diff)
        {
            RemoveCC();
            CCTimer = 8000+rand()%2000;
        }
        else CCTimer -= diff;

        if(mAIType == AI_MELEE) DoMeleeAttackIfReady();
    }
void AAssignment_1Character::CollectPickup()
{
    // Get all overlapping Actors and store them in an array
    TArray<AActor *> CollectedActors;
    CollectionSphere->GetOverlappingActors(CollectedActors);
    
    // Keep track of collected power
    float CollectedPower = 0;
    
    // For each Actor we collected
    for (int32 iCollected = 0; iCollected < CollectedActors.Num(); ++iCollected)
    {
        // Cast the actor to APickup
        APickup* const TestPickup = Cast<APickup>(CollectedActors[iCollected]);
    
        // If the cast is successful and the pickup is valid and active
        if (TestPickup && !TestPickup->IsPendingKill() && TestPickup->IsActive())
        {
            // Call the pickup's WasCollected function
            TestPickup->WasCollected();
            
            // Check to see if the pickup is also a battery
            ABatteryPickup * const TestBattery = Cast<ABatteryPickup>(TestPickup);
            if (TestBattery)
            {
                // Increase the collected power
                CollectedPower = CollectedPower + TestBattery->GetPower();
            }
            
            // Deactivate the pickup
            TestPickup->SetActive(false);
        }
    }
    
    if (CollectedPower != 0)
    {
        UpdatePower(CollectedPower);
    }
}
Beispiel #13
0
void CCar::PhDataUpdate(float step)
{
		if(m_repairing)Revert();
		LimitWheels();
		UpdateFuel(step);

	
		//if(fwp)
		{	
			UpdatePower();
			if(b_engine_on&&!b_starting && m_current_rpm<m_min_rpm)Stall();
		}

		if(bkp)
		{
			UpdateBack();
		}

		if(brp)
			HandBreak();
//////////////////////////////////////////////////////////
	for (int k=0; k<(int)m_doors_update.size(); ++k){
		SDoor* D = m_doors_update[k];
		if (!D->update)
		{
			m_doors_update.erase(m_doors_update.begin()+k);
			--k;
		}
		else
		{
			D->Update();
		}
	}
	
	m_steer_angle=m_steering_wheels.begin()->GetSteerAngle()*0.1f+m_steer_angle*0.9f;
	VERIFY(_valid(m_steer_angle));
}
void UFlareSpacecraftDamageSystem::TickSystem(float DeltaSeconds)
{
	// Apply heat variation : add producted heat then substract radiated heat.

	// Get the to heat production and heat sink surface
	float HeatProduction = 0.f;
	float HeatSinkSurface = 0.f;

	for (int32 i = 0; i < Components.Num(); i++)
	{
		UFlareSpacecraftComponent* Component = Cast<UFlareSpacecraftComponent>(Components[i]);
		HeatProduction += Component->GetHeatProduction();
		HeatSinkSurface += Component->GetHeatSinkSurface();
	}

	// Add a part of sun radiation to ship heat production
	// Sun flow is 3.094KW/m^2 and keep only half and modulate 90% by sun occlusion
	HeatProduction += HeatSinkSurface * 3.094 * 0.5 * (1 - 0.9 * Spacecraft->GetGame()->GetPlanetarium()->GetSunOcclusion());

	// Heat up
	Data->Heat += HeatProduction * DeltaSeconds;
	// Radiate: Stefan-Boltzmann constant=5.670373e-8
	float Temperature = Data->Heat / Description->HeatCapacity;
	float HeatRadiation = 0.f;
	if (Temperature > 0)
	{
		HeatRadiation = HeatSinkSurface * 5.670373e-8 * FMath::Pow(Temperature, 4) / 1000;
	}
	// Don't radiate too much energy : negative temperature is not possible
	Data->Heat -= FMath::Min(HeatRadiation * DeltaSeconds, Data->Heat);

	// Power outage
	if (Data->PowerOutageDelay > 0)
	{
		Data->PowerOutageDelay -=  DeltaSeconds;
		if (Data->PowerOutageDelay <=0)
		{
			Data->PowerOutageDelay = 0;
			UpdatePower(); // To update light
		}
	}

	// Update Alive status
	if (WasAlive && !Parent->IsAlive())
	{
		AFlarePlayerController* PC = Spacecraft->GetGame()->GetPC();

		// Player kill
		if (PC && LastDamageCauser == PC->GetShipPawn() && Spacecraft != PC->GetShipPawn())
		{
			PC->Notify(LOCTEXT("ShipKilled", "Target destroyed"),
				FText::Format(LOCTEXT("ShipKilledFormat", "You destroyed a ship ({0}-class)"), Spacecraft->GetParent()->GetDescription()->Name),
				FName("ship-killed"),
				EFlareNotification::NT_Info);
		}

		// Company kill
		else if (PC && LastDamageCauser && PC->GetCompany() == LastDamageCauser->GetParent()->GetCompany())
		{
			PC->Notify(LOCTEXT("ShipKilledCompany", "Target destroyed"),
				FText::Format(LOCTEXT("ShipKilledCompanyFormat", "Your {0}-class ship destroyed a ship ({1}-class)"),
					Spacecraft->GetParent()->GetDescription()->Name,
					LastDamageCauser->GetParent()->GetDescription()->Name),
				FName("ship-killed"),
				EFlareNotification::NT_Info);
		}

		WasAlive = false;
		OnControlLost();
	}

	TimeSinceLastExternalDamage += DeltaSeconds;
}
Beispiel #15
0
void CCar::ReleasePedals()
{
	Clutch();
	NeutralDrive();//set zero speed
	UpdatePower();//set engine friction;
}