void CEnemyMeleeAttack::onTick(unsigned int msecs)
	{
		//BaseSubsystems::Log::Debug(std::to_string(_count)+" - "+_entity->getName() + " Acumulando tiempo de ataque: "+std::to_string(_timeAcum)+" / "+std::to_string(_timeBetweenAttacks));
		_timeAcum += msecs;
		if(canDoDamage())
		{
			Vector3 dir = _target->getPosition() - _entity->getPosition();

			if( dir.squaredLength() <= _maxDist2)
			{
				Vector3 offsetPos = _entity->getPosition();
				offsetPos.y += _upOffset;
				CEntity* ent;

				Vector3 collisionPoint;

				if (_target->getTag() == "player")
				{
					ent = Physics::CServer::getSingletonPtr()->raycastSimple(offsetPos, dir, _maxDist ,Physics::CollisionGroup::ePlayer,collisionPoint);

					if (ent)
					{
						ApplyDamage(ent);

						//Instanciamos la chispa en el punto de colision
						CEntityFactory::getSingletonPtr()->createEntityByType("ChispaDanhoPlayer", collisionPoint, _entity->getMap());
						damageEnemy(collisionPoint);
					
					}

				}
				else if (_target->getTag() == "enemy")
				{
					std::vector<Vector3> pointsCollision;
					Physics::FilterMask mask = Physics::FilterMask(Physics::FilterMask::eEnemyTMask |Physics::FilterMask::eEnemyVMask);
					std::vector<Logic::CEntity*> vecLEnt = Physics::CServer::getSingletonPtr()->raycastMultiple(offsetPos, dir, _maxDist, 64, mask,pointsCollision);
					
					for (int i = 0; i < vecLEnt.size(); ++i)
					{
						if (vecLEnt.at(i)->getEntityID() == _targetID)
						{
							ApplyDamage(vecLEnt.at(i));

							//Generamos particula de choque
							CEntityFactory::getSingletonPtr()->createEntityByType("ChispaDanhoEnemy", pointsCollision.at(i), _entity->getMap());
							break;
						}
					}
				}
			}
		}

	}//tick
	void CEnemyMeleeAttack::process(const std::shared_ptr<Logic::IMessage> &message)
	{
		if(message->getType() == "CONTROLLER_TOUCHED")
		{
			CEntity* other = dynamic_cast<CONTROLLER_TOUCHED*>(message.get())->getEntidad();

			if(other->getEntityID() == _targetID && _entity->getTag() == "enemy" && canDoDamage())
			{
				ApplyDamage(other);
			}
			
		}

		else if (message->getType() == "CHANGE_TARGET")
		{
			// Si no encuentra la palabra "Minion" en el tipo de entidad, entonces puede canibalizar
			if (_entity->getType().find("Minion") == std::string::npos)
			{
				_target =  dynamic_cast<CHANGE_TARGET*>(message.get())->getLogicEntity(); 

				if (_target)
					_targetID = _target->getEntityID();
			}
		}

	} // process
void Player::CheckEnemyCollision(Enemy& e)
{
	if (e.IsSpawned() && !e.IsDying() && CheckCollision(&e))
	{
		ApplyDamage(e.GetContactDamage());
		e.SetHasCollidedWithPlayer(true);
		//_collidedWithPlayer = true;
	}
}
Exemple #4
0
void
System::ExecFrame(double seconds)
{
    if (seconds < 0.01)
    seconds = 0.01;

    STATUS s = DESTROYED;

    if (availability > 0.99)
    s = NOMINAL;
    else if (availability > crit_level)
    s = DEGRADED;
    else
    s = CRITICAL;

    bool repair = false;

    if (components.size() > 0) {
        ListIter<Component> comp = components;
        while (++comp) {
            if (comp->Status() > Component::NOMINAL) {
                repair = true;
                break;
            }
        }
    }

    if (repair) {
        Repair();
    }

    else {
        if (status != s) {
            status = s;
            NetUtil::SendSysStatus(ship, this);
        }

        // collateral damage due to unsafe operation:
        if (power_on && power_level > safety) {
            safety_overload += (float) seconds;

            // inflict some damage now:
            if (safety_overload > 60) {
                safety_overload -= (float) (rand() / (1000 * (power_level-safety)));
                ApplyDamage(15);

                NetUtil::SendSysStatus(ship, this);
            }
        }

        else if (safety_overload > 0) {
            safety_overload -= (float) seconds;
        }
    }
}
void AZombieCharacter::HandleDamage(float DamageAmount, FDamageEvent DamageEvent)
{
	//Handles the given damage amount and effect
	//Makes sures to apply the right debuff (if any - based on the bullet type the player used) and damage to the zombie
	//Takes into consideration the active debuff in order to deactivate it if necessary (ie dot cancels slow effect and vice versa)

	if(IsAlive())
	{

		//Determing the damage type based on the bullet that the player used
		//ie frost damage if frost ammo is equipped
		UPlayerDamageType* DamageType = Cast<UPlayerDamageType>(DamageEvent.DamageTypeClass.GetDefaultObject());
		switch (DamageType->PlayerDamageType)
		{
			case EPlayerDamageType::Dot:
			{
				DisableSlowEffect();
				ApplyDotEffect(DamageAmount);
				break;
			}
			case EPlayerDamageType::Slow:
			{
				DisableDotEffectIfNecessary(true);
				ApplyDamage(DamageAmount);
				ApplySlowEffect();
				break;
			}
			default:
			{
				ApplyDamage(DamageAmount);
				break;
			}
		}

		if (!IsAlive())
		{
			//Stop logic of the AI
			Die();
			
		}
	}
}
//Character has been hit by enemy 
void ABaseCharacter::OnHit_Implementation(AActor *Other)
{
	//server event 
	if (Controller && Role == ROLE_Authority) {
		
		//apply damage received from the other Character.  Ignores hitting other basecharacter (Kid/RubberMan)
		if (dynamic_cast<APatrollingEnemyCharacter*>(Other)){
			ApplyDamage(Cast<APatrollingEnemyCharacter>(Other)->GetAttackDamage());

		}
	}
}
void UDestructibleComponent::ReceiveComponentDamage(float DamageAmount, FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser)
{
	UDamageType const* const DamageTypeCDO = DamageEvent.DamageTypeClass ? DamageEvent.DamageTypeClass->GetDefaultObject<UDamageType>() : GetDefault<UDamageType>();
	if (DamageEvent.IsOfType(FPointDamageEvent::ClassID))
	{
		FPointDamageEvent const* const PointDamageEvent = (FPointDamageEvent*)(&DamageEvent);
		ApplyDamage(DamageAmount, PointDamageEvent->HitInfo.ImpactPoint, PointDamageEvent->ShotDirection, DamageTypeCDO->DestructibleImpulse);
	}
	else if (DamageEvent.IsOfType(FRadialDamageEvent::ClassID))
	{
		FRadialDamageEvent const* const RadialDamageEvent = (FRadialDamageEvent*)(&DamageEvent);
		ApplyRadiusDamage(DamageAmount, RadialDamageEvent->Origin, RadialDamageEvent->Params.OuterRadius, DamageTypeCDO->DestructibleImpulse, false);
	}
}
void
Computer::Distribute(double delivered_energy, double seconds)
{
    if (IsPowerOn()) {
        // convert Joules to Watts:
        energy = (float) (delivered_energy/seconds);

        // brown out:
        if (energy < capacity*0.75f)
        power_on = false;

        // spike:
        else if (energy > capacity*1.5f) {
            power_on = false;
            ApplyDamage(50);
        }
    }
}
Exemple #9
0
    //Apply damage without impact type calculations.
    inline void ApplyDamage(ICombatant& source,ICombatant& target,DamageToken& damageToken)
    {
		ApplyDamage(source,target,damageToken.GetDamageType(),damageToken.GetImpactType(),damageToken.GetDamageAmount());
	}
void UFlareSpacecraftDamageSystem::OnCollision(class AActor* Other, FVector HitLocation, FVector NormalImpulse)
{
	// If receive hit from over actor, like a ship we must apply collision damages.
	// The applied damage energy is 0.2% of the kinetic energy of the other actor. The kinetic
	// energy is calculated from the relative speed between the 2 actors, and only with the relative
	// speed projected in the axis of the collision normal: if 2 very fast ship only slightly touch,
	// only few energy will be decipated by the impact.
	//
	// The damages are applied only to the current actor, the ReceiveHit method of the other actor
	// will also call an it will apply its collision damages itself.

	// If the other actor is a projectile, specific weapon damage code is done in the projectile hit
	// handler: in this case we ignore the collision
	AFlareShell* OtherProjectile = Cast<AFlareShell>(Other);
	if (OtherProjectile)
	{
		return;
	}

	// No primitive component, ignore
	UPrimitiveComponent* OtherRoot = Cast<UPrimitiveComponent>(Other->GetRootComponent());
	if (!OtherRoot)
	{
		return;
	}

	// Ignore debris
	AStaticMeshActor* OtherActor = Cast<AStaticMeshActor>(Other);
	if (OtherActor)
	{
		if (OtherActor->GetName().StartsWith("Debris"))
		{
			return;
		}
	}

	// Relative velocity
	FVector DeltaVelocity = ((OtherRoot->GetPhysicsLinearVelocity() - Spacecraft->Airframe->GetPhysicsLinearVelocity()) / 100);

	// Compute the relative velocity in the impact axis then compute kinetic energy
	/*float ImpactSpeed = DeltaVelocity.Size();
	float ImpactMass = FMath::Min(Spacecraft->GetSpacecraftMass(), OtherRoot->GetMass());
	*/

	//200 m /s -> 6301.873047 * 20000 -> 300 / 2 damage

	float ImpactSpeed = 0;
	float ImpactEnergy = 0;
	float ImpactMass = Spacecraft->GetSpacecraftMass();

	// Check if the mass was set and is valid
	if (ImpactMass > KINDA_SMALL_NUMBER)
	{
		ImpactSpeed = NormalImpulse.Size() / (ImpactMass * 100.f);
		ImpactEnergy = ImpactMass * ImpactSpeed / 8402.f;
	}

	float  Radius = 0.2 + FMath::Sqrt(ImpactEnergy) * 0.11;
	//FLOGV("OnCollision %s", *Spacecraft->GetImmatriculation().ToString());
	//FLOGV("  OtherRoot->GetPhysicsLinearVelocity()=%s", *OtherRoot->GetPhysicsLinearVelocity().ToString());
	//FLOGV("  OtherRoot->GetPhysicsLinearVelocity().Size()=%f", OtherRoot->GetPhysicsLinearVelocity().Size());
	//FLOGV("  Spacecraft->Airframe->GetPhysicsLinearVelocity()=%s", *Spacecraft->Airframe->GetPhysicsLinearVelocity().ToString());
	//FLOGV("  Spacecraft->Airframe->GetPhysicsLinearVelocity().Size()=%f", Spacecraft->Airframe->GetPhysicsLinearVelocity().Size());
	//FLOGV("  dot=%f", FVector::DotProduct(DeltaVelocity.GetUnsafeNormal(), HitNormal.GetUnsafeNormal()));
	/*FLOGV("  DeltaVelocity=%s", *DeltaVelocity.ToString());
	FLOGV("  ImpactSpeed=%f", ImpactSpeed);
	FLOGV("  ImpactMass=%f", ImpactMass);
	FLOGV("  ImpactEnergy=%f", ImpactEnergy);
	FLOGV("  Radius=%f", Radius);*/



	bool HasHit = false;
	FHitResult BestHitResult;
	float BestHitDistance = 0;

	for (int32 ComponentIndex = 0; ComponentIndex < Components.Num(); ComponentIndex++)
	{
		UFlareSpacecraftComponent* Component = Cast<UFlareSpacecraftComponent>(Components[ComponentIndex]);
		if (Component)
		{
			FHitResult HitResult(ForceInit);
			FCollisionQueryParams TraceParams(FName(TEXT("Fragment Trace")), true);
			TraceParams.bTraceComplex = true;
			TraceParams.bReturnPhysicalMaterial = false;
			Component->LineTraceComponent(HitResult, HitLocation, HitLocation + Spacecraft->GetLinearVelocity().GetUnsafeNormal() * 10000, TraceParams);

			if (HitResult.Actor.IsValid()){
				float HitDistance = (HitResult.Location - HitLocation).Size();
				if (!HasHit || HitDistance < BestHitDistance)
				{
					BestHitDistance = HitDistance;
					BestHitResult = HitResult;
				}

				//FLOGV("Collide hit %s at a distance=%f", *Component->GetReadableName(), HitDistance);
				HasHit = true;
			}
		}

	}

	if (HasHit)
	{
		//DrawDebugLine(Spacecraft->GetWorld(), HitLocation, BestHitResult.Location, FColor::Magenta, true);
	}
	else
	{
		int32 BestComponentIndex = -1;
		BestHitDistance = 0;

		for (int32 ComponentIndex = 0; ComponentIndex < Components.Num(); ComponentIndex++)
		{
			UFlareSpacecraftComponent* Component = Cast<UFlareSpacecraftComponent>(Components[ComponentIndex]);
			if (Component)
			{
				float ComponentDistance = (Component->GetComponentLocation() - HitLocation).Size();
				if (BestComponentIndex == -1 || BestHitDistance > ComponentDistance)
				{
					BestComponentIndex = ComponentIndex;
					BestHitDistance = ComponentDistance;
				}
			}
		}
		UFlareSpacecraftComponent* Component = Cast<UFlareSpacecraftComponent>(Components[BestComponentIndex]);


		FCollisionQueryParams TraceParams(FName(TEXT("Fragment Trace")), true);
		TraceParams.bTraceComplex = true;
		TraceParams.bReturnPhysicalMaterial = false;
		Component->LineTraceComponent(BestHitResult, HitLocation, Component->GetComponentLocation(), TraceParams);
		//DrawDebugLine(Spacecraft->GetWorld(), HitLocation, BestHitResult.Location, FColor::Yellow, true);


	}

	AFlareSpacecraft* OtherSpacecraft = Cast<AFlareSpacecraft>(Other);
	UFlareCompany* DamageSource = NULL;
	if (OtherSpacecraft)
	{
		DamageSource = OtherSpacecraft->GetParent()->GetCompany();
		LastDamageCauser = OtherSpacecraft;
	}
	else
	{
		LastDamageCauser = NULL;
	}
	ApplyDamage(ImpactEnergy, Radius, BestHitResult.Location, EFlareDamage::DAM_Collision, DamageSource);
}
void Explosion::Inflict()
{
	ApplyDamage();

	ApplyForceToApplicable();
}