示例#1
0
        protected override List <Lifetime> CreateLifetimes(ModifierInfo modifierInfo)
        {
            BlastInfo bi       = (BlastInfo)modifierInfo;
            float     duration = bi.TimeToPeak + bi.TimeToGround + bi.TimeToRoll + bi.TimeToLie;

            lifetime = new DurationBasedLifetime(duration);
            return(new List <Lifetime>(new [] { lifetime }));
        }
		protected override void simulateSelfPeriodic(float timeDelta)
		{
			for (int i = 0; i < _blasts.Count; ++i) {
				BlastInfo bi = _blasts [i];

				bi.timeElapsed += timeDelta;
				if (bi.timeElapsed > _adsr.totalDuration) {
					_blasts.RemoveAt (i);
					i--;
				}
			}
		}
		protected override void activatePeriodic ()
		{
			BlastInfo bi = new BlastInfo ();
			bi.center.X = Interpolate.Lerp (centerMin.X, centerMax.X, nextFloat ());
			bi.center.Y = Interpolate.Lerp (centerMin.Y, centerMax.Y, nextFloat ());
			bi.center.Z = Interpolate.Lerp (centerMin.Z, centerMax.Z, nextFloat ());
			bi.forceMagnitude = Interpolate.Lerp (explosiveForceMin, explosiveForceMax, nextFloat ());
			bi.timeElapsed = 0f;
			_blasts.Add (bi);
			if (explosionEventHandlers != null) {
				explosionEventHandlers (bi.center, bi.forceMagnitude);
			}
		}
		protected override void effectParticlePeriodic(SSParticle particle, float timeDelta)
		{
			for (int i = 0; i < _blasts.Count; ++i) {
				BlastInfo bi = _blasts [i];

				// TODO inverse square law or something similar
				Vector3 dist = particle.pos - bi.center;
				if (dist != Vector3.Zero) {
					float acc = _adsr.computeLevel (bi.timeElapsed) * bi.forceMagnitude 
							  / dist.LengthSquared / particle.mass;
					Vector3 dir = (particle.pos - bi.center).Normalized ();
					particle.vel += (acc * dir);
				}
			}
		}
示例#5
0
        public BlastModifier(BlastInfo info, Entity caster, Entity target,
                             Camera camera, SkillId skillId, Vector3 collidedProjectilePosition,
                             Environment environment,
                             CollectionOfInteractions modifierInteractionCollection,
                             WallHitConfig wallHitConfig, float damageScale) : base(info, caster, target, environment, modifierInteractionCollection)
        {
            this.info    = info;
            this.caster  = caster;
            targetEntity = target;
            this.camera  = camera;
            this.skillId = skillId;
            this.collidedProjectilePosition = collidedProjectilePosition;
            this.environment     = environment;
            this.wallHitConfig   = wallHitConfig;
            this.damageScale     = damageScale;
            this.targetAnimation = target.GetComponent <AnimationComponent>().Animation;
            targetCharacter      = target.GetComponent <SkillComponent>().Character;
            UserInput userInput = target.GetComponent <HeroStateMachineComponent>().UserInput;

            targetDefaultUserInput = (DefaultUserInput)userInput;
            switch (this.info.AnimationProfile)
            {
            case BlastModifierConfig.AnimationProfile.Far:
                animProfile = new FarAnimProfile();
                break;

            case BlastModifierConfig.AnimationProfile.High:
                animProfile = new HighAnimProfile();
                break;

            case BlastModifierConfig.AnimationProfile.Medium:
                animProfile = new MediumAnimProfile();
                break;
            }

            StatsComponent targetStatsComponent = targetEntity.GetComponent <StatsComponent>();
            bool           found;

            extraLyingDurationStats = targetStatsComponent.CharacterStats.FindStats(
                StatsType.ExtraLyingDuration, out found
                );
            if (found)
            {
                lifetime.DynamicExtraDuration += extraLyingDurationStats.BakedFloatValue;
            }
            casterMovementComponent = casterEntity.GetComponent <MovementComponent>();
        }
示例#6
0
        private void ExecutePartBlastEvent(PartBlastHitEvent eventToExecute)
        {
            if (eventToExecute.Part == null || eventToExecute.Part.Rigidbody == null || eventToExecute.Part.vessel == null || eventToExecute.Part.partInfo == null)
            {
                return;
            }

            try
            {
                Part      part         = eventToExecute.Part;
                Rigidbody rb           = part.Rigidbody;
                var       realDistance = eventToExecute.Distance;

                if (!eventToExecute.IsNegativePressure)
                {
                    BlastInfo blastInfo =
                        BlastPhysicsUtils.CalculatePartBlastEffects(part, realDistance,
                                                                    part.vessel.totalMass * 1000f, Power, Range);

                    if (BDArmorySettings.DRAW_DEBUG_LABELS)
                    {
                        Debug.Log(
                            "[BDArmory]: Executing blast event Part: {" + part.name + "}, " +
                            " VelocityChange: {" + blastInfo.VelocityChange + "}," +
                            " Distance: {" + realDistance + "}," +
                            " TotalPressure: {" + blastInfo.TotalPressure + "}," +
                            " Damage: {" + blastInfo.Damage + "}," +
                            " EffectiveArea: {" + blastInfo.EffectivePartArea + "}," +
                            " Positive Phase duration: {" + blastInfo.PositivePhaseDuration + "}," +
                            " Vessel mass: {" + Math.Round(part.vessel.totalMass * 1000f) + "}," +
                            " TimeIndex: {" + TimeIndex + "}," +
                            " TimePlanned: {" + eventToExecute.TimeToImpact + "}," +
                            " NegativePressure: {" + eventToExecute.IsNegativePressure + "}");
                    }

                    // Add Reverse Negative Event
                    ExplosionEvents.Enqueue(new PartBlastHitEvent()
                    {
                        Distance           = Range - realDistance,
                        Part               = part,
                        TimeToImpact       = 2 * (Range / ExplosionVelocity) + (Range - realDistance) / ExplosionVelocity,
                        IsNegativePressure = true,
                        NegativeForce      = blastInfo.VelocityChange * 0.25f
                    });

                    AddForceAtPosition(rb,
                                       (eventToExecute.HitPoint + part.rb.velocity * TimeIndex - Position).normalized *
                                       blastInfo.VelocityChange *
                                       BDArmorySettings.EXP_IMP_MOD,
                                       eventToExecute.HitPoint + part.rb.velocity * TimeIndex);

                    var damage = part.AddExplosiveDamage(blastInfo.Damage, Caliber, ExplosionSource);
                    if (BDArmorySettings.BATTLEDAMAGE)
                    {
                        Misc.BattleDamageHandler.CheckDamageFX(part, 50, 0.5f, true, SourceVesselName, eventToExecute.Hit);
                    }

                    // Update scoring structures
                    switch (ExplosionSource)
                    {
                    case ExplosionSourceType.Bullet:
                    case ExplosionSourceType.Missile:
                        var aName = eventToExecute.SourceVesselName; // Attacker
                        var tName = part.vessel.GetName();           // Target
                        if (aName != tName && BDACompetitionMode.Instance.Scores.ContainsKey(tName) && BDACompetitionMode.Instance.Scores.ContainsKey(aName))
                        {
                            var tData = BDACompetitionMode.Instance.Scores[tName];
                            // Track damage
                            switch (ExplosionSource)
                            {
                            case ExplosionSourceType.Bullet:
                                if (tData.damageFromBullets.ContainsKey(aName))
                                {
                                    tData.damageFromBullets[aName] += damage;
                                }
                                else
                                {
                                    tData.damageFromBullets.Add(aName, damage);
                                }
                                if (BDArmorySettings.REMOTE_LOGGING_ENABLED)
                                {
                                    BDAScoreService.Instance.TrackDamage(aName, tName, damage);
                                }
                                break;

                            case ExplosionSourceType.Missile:
                                if (tData.damageFromMissiles.ContainsKey(aName))
                                {
                                    tData.damageFromMissiles[aName] += damage;
                                }
                                else
                                {
                                    tData.damageFromMissiles.Add(aName, damage);
                                }
                                if (BDArmorySettings.REMOTE_LOGGING_ENABLED)
                                {
                                    BDAScoreService.Instance.TrackMissileDamage(aName, tName, damage);
                                }
                                break;

                            default:
                                break;
                            }
                        }
                        break;

                    default:
                        break;
                    }
                }
                else
                {
                    if (BDArmorySettings.DRAW_DEBUG_LABELS)
                    {
                        Debug.Log(
                            "[BDArmory]: Executing blast event Part: {" + part.name + "}, " +
                            " VelocityChange: {" + eventToExecute.NegativeForce + "}," +
                            " Distance: {" + realDistance + "}," +
                            " Vessel mass: {" + Math.Round(part.vessel.totalMass * 1000f) + "}," +
                            " TimeIndex: {" + TimeIndex + "}," +
                            " TimePlanned: {" + eventToExecute.TimeToImpact + "}," +
                            " NegativePressure: {" + eventToExecute.IsNegativePressure + "}");
                    }
                    AddForceAtPosition(rb, (Position - part.transform.position).normalized * eventToExecute.NegativeForce * BDArmorySettings.EXP_IMP_MOD * 0.25f, part.transform.position);
                }
            }
            catch
            {
                // ignored due to depending on previous event an object could be disposed
            }
        }
示例#7
0
        private void ExecutePartBlastEvent(PartBlastHitEvent eventToExecute)
        {
            if (eventToExecute.Part == null || eventToExecute.Part.Rigidbody == null || eventToExecute.Part.vessel == null || eventToExecute.Part.partInfo == null)
            {
                return;
            }

            Part      part         = eventToExecute.Part;
            Rigidbody rb           = part.Rigidbody;
            var       realDistance = eventToExecute.Distance;

            if (!eventToExecute.IsNegativePressure)
            {
                BlastInfo blastInfo =
                    BlastPhysicsUtils.CalculatePartBlastEffects(part, realDistance,
                                                                part.vessel.totalMass * 1000f, Power, Range);

                // Overly simplistic approach: simply reduce damage by amount of HP/2 and Armour in the way. (HP/2 to simulate weak parts not fully blocking damage.) Does not account for armour reduction or angle of incidence of intermediate parts.
                // A better approach would be to properly calculate the damage and pressure in CalculatePartBlastEffects due to the series of parts in the way.
                var damageWithoutIntermediateParts      = blastInfo.Damage;
                var cumulativeHPOfIntermediateParts     = eventToExecute.IntermediateParts.Select(p => p.Item2).Sum();
                var cumulativeArmourOfIntermediateParts = eventToExecute.IntermediateParts.Select(p => p.Item3).Sum();
                blastInfo.Damage = Mathf.Max(0f, blastInfo.Damage - 0.5f * cumulativeHPOfIntermediateParts - cumulativeArmourOfIntermediateParts);

                if (blastInfo.Damage > 0)
                {
                    if (BDArmorySettings.DRAW_DEBUG_LABELS)
                    {
                        Debug.Log(
                            "[BDArmory.ExplosionFX]: Executing blast event Part: {" + part.name + "}, " +
                            " VelocityChange: {" + blastInfo.VelocityChange + "}," +
                            " Distance: {" + realDistance + "}," +
                            " TotalPressure: {" + blastInfo.TotalPressure + "}," +
                            " Damage: {" + blastInfo.Damage + "} (reduced from " + damageWithoutIntermediateParts + " by " + eventToExecute.IntermediateParts.Count + " parts)," +
                            " EffectiveArea: {" + blastInfo.EffectivePartArea + "}," +
                            " Positive Phase duration: {" + blastInfo.PositivePhaseDuration + "}," +
                            " Vessel mass: {" + Math.Round(part.vessel.totalMass * 1000f) + "}," +
                            " TimeIndex: {" + TimeIndex + "}," +
                            " TimePlanned: {" + eventToExecute.TimeToImpact + "}," +
                            " NegativePressure: {" + eventToExecute.IsNegativePressure + "}");
                    }

                    // Add Reverse Negative Event
                    ExplosionEvents.Enqueue(new PartBlastHitEvent()
                    {
                        Distance           = Range - realDistance,
                        Part               = part,
                        TimeToImpact       = 2 * (Range / ExplosionVelocity) + (Range - realDistance) / ExplosionVelocity,
                        IsNegativePressure = true,
                        NegativeForce      = blastInfo.VelocityChange * 0.25f
                    });

                    if (rb != null && rb.mass > 0)
                    {
                        AddForceAtPosition(rb,
                                           (eventToExecute.HitPoint + rb.velocity * TimeIndex - Position).normalized *
                                           blastInfo.VelocityChange *
                                           BDArmorySettings.EXP_IMP_MOD,
                                           eventToExecute.HitPoint + rb.velocity * TimeIndex);
                    }

                    var damage = part.AddExplosiveDamage(blastInfo.Damage, Caliber, ExplosionSource);
                    if (BDArmorySettings.BATTLEDAMAGE)
                    {
                        Misc.BattleDamageHandler.CheckDamageFX(part, 50, 0.5f, true, SourceVesselName, eventToExecute.Hit);
                    }

                    // Update scoring structures
                    switch (ExplosionSource)
                    {
                    case ExplosionSourceType.Bullet:
                    case ExplosionSourceType.Missile:
                        var aName = eventToExecute.SourceVesselName; // Attacker
                        var tName = part.vessel.GetName();           // Target
                        if (aName != tName && BDACompetitionMode.Instance.Scores.ContainsKey(tName) && BDACompetitionMode.Instance.Scores.ContainsKey(aName))
                        {
                            var tData = BDACompetitionMode.Instance.Scores[tName];
                            // Track damage
                            switch (ExplosionSource)
                            {
                            case ExplosionSourceType.Bullet:
                                if (tData.damageFromBullets.ContainsKey(aName))
                                {
                                    tData.damageFromBullets[aName] += damage;
                                }
                                else
                                {
                                    tData.damageFromBullets.Add(aName, damage);
                                }
                                if (BDArmorySettings.REMOTE_LOGGING_ENABLED)
                                {
                                    BDAScoreService.Instance.TrackDamage(aName, tName, damage);
                                }
                                break;

                            case ExplosionSourceType.Missile:
                                if (tData.damageFromMissiles.ContainsKey(aName))
                                {
                                    tData.damageFromMissiles[aName] += damage;
                                }
                                else
                                {
                                    tData.damageFromMissiles.Add(aName, damage);
                                }
                                if (BDArmorySettings.REMOTE_LOGGING_ENABLED)
                                {
                                    BDAScoreService.Instance.TrackMissileDamage(aName, tName, damage);
                                }
                                break;

                            default:
                                break;
                            }
                        }
                        break;

                    default:
                        break;
                    }
                }
                else if (BDArmorySettings.DRAW_DEBUG_LABELS)
                {
                    Debug.Log("[BDArmory.ExplosiveFX]: Part " + part.name + " at distance " + realDistance + "m took no damage due to parts with " + cumulativeHPOfIntermediateParts + "HP and " + cumulativeArmourOfIntermediateParts + " Armour in the way.");
                }
            }
            else
            {
                if (BDArmorySettings.DRAW_DEBUG_LABELS)
                {
                    Debug.Log(
                        "[BDArmory.ExplosionFX]: Executing blast event Part: {" + part.name + "}, " +
                        " VelocityChange: {" + eventToExecute.NegativeForce + "}," +
                        " Distance: {" + realDistance + "}," +
                        " Vessel mass: {" + Math.Round(part.vessel.totalMass * 1000f) + "}," +
                        " TimeIndex: {" + TimeIndex + "}," +
                        " TimePlanned: {" + eventToExecute.TimeToImpact + "}," +
                        " NegativePressure: {" + eventToExecute.IsNegativePressure + "}");
                }
                if (rb != null && rb.mass > 0)
                {
                    AddForceAtPosition(rb, (Position - part.transform.position).normalized * eventToExecute.NegativeForce * BDArmorySettings.EXP_IMP_MOD * 0.25f, part.transform.position);
                }
            }
        }
示例#8
0
        private void ExecutePartBlastEvent(PartBlastHitEvent eventToExecute)
        {
            if (eventToExecute.Part == null || eventToExecute.Part.Rigidbody == null || eventToExecute.Part.vessel == null || eventToExecute.Part.partInfo == null)
            {
                return;
            }

            try
            {
                Part      part         = eventToExecute.Part;
                Rigidbody rb           = part.Rigidbody;
                var       realDistance = eventToExecute.Distance;


                if (!eventToExecute.IsNegativePressure)
                {
                    BlastInfo blastInfo =
                        BlastPhysicsUtils.CalculatePartBlastEffects(part, realDistance,
                                                                    part.vessel.totalMass * 1000f, Power, Range);

                    if (BDArmorySettings.DRAW_DEBUG_LABELS)
                    {
                        Debug.Log(
                            "[BDArmory]: Executing blast event Part: {" + part.name + "}, " +
                            " VelocityChange: {" + blastInfo.VelocityChange + "}," +
                            " Distance: {" + realDistance + "}," +
                            " TotalPressure: {" + blastInfo.TotalPressure + "}," +
                            " Damage: {" + blastInfo.Damage + "}," +
                            " EffectiveArea: {" + blastInfo.EffectivePartArea + "}," +
                            " Positive Phase duration: {" + blastInfo.PositivePhaseDuration + "}," +
                            " Vessel mass: {" + Math.Round(part.vessel.totalMass * 1000f) + "}," +
                            " TimeIndex: {" + TimeIndex + "}," +
                            " TimePlanned: {" + eventToExecute.TimeToImpact + "}," +
                            " NegativePressure: {" + eventToExecute.IsNegativePressure + "}");
                    }

                    // Add Reverse Negative Event
                    ExplosionEvents.Enqueue(new PartBlastHitEvent()
                    {
                        Distance           = Range - realDistance,
                        Part               = part,
                        TimeToImpact       = 2 * (Range / ExplosionVelocity) + (Range - realDistance) / ExplosionVelocity,
                        IsNegativePressure = true,
                        NegativeForce      = blastInfo.VelocityChange * 0.25f
                    });

                    AddForceAtPosition(rb,
                                       (eventToExecute.HitPoint + part.rb.velocity * TimeIndex - Position).normalized *
                                       blastInfo.VelocityChange *
                                       BDArmorySettings.EXP_IMP_MOD,
                                       eventToExecute.HitPoint + part.rb.velocity * TimeIndex);

                    part.AddExplosiveDamage(blastInfo.Damage,
                                            Caliber, IsMissile);
                }
                else
                {
                    if (BDArmorySettings.DRAW_DEBUG_LABELS)
                    {
                        Debug.Log(
                            "[BDArmory]: Executing blast event Part: {" + part.name + "}, " +
                            " VelocityChange: {" + eventToExecute.NegativeForce + "}," +
                            " Distance: {" + realDistance + "}," +
                            " Vessel mass: {" + Math.Round(part.vessel.totalMass * 1000f) + "}," +
                            " TimeIndex: {" + TimeIndex + "}," +
                            " TimePlanned: {" + eventToExecute.TimeToImpact + "}," +
                            " NegativePressure: {" + eventToExecute.IsNegativePressure + "}");
                    }
                    AddForceAtPosition(rb, (Position - part.transform.position).normalized * eventToExecute.NegativeForce * BDArmorySettings.EXP_IMP_MOD * 0.25f, part.transform.position);
                }
            }
            catch
            {
                // ignored due to depending on previous event an object could be disposed
            }
        }