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; } }
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); } } }
//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(); }