public bool ExtractData(GetDataEventArgs args, MemoryStream data, PvPPlayer attacker, out ProjectileNewArgs arg)
        {
            arg = null;
            if (PresetData.ProjectileDummy.Contains(Type))
            {
                return(false);
            }

            arg = new ProjectileNewArgs {
                Args     = args,
                Attacker = attacker,

                Identity  = data.ReadInt16(),
                Position  = new Vector2(data.ReadSingle(), data.ReadSingle()),
                Velocity  = new Vector2(data.ReadSingle(), data.ReadSingle()),
                Knockback = data.ReadSingle(),
                Damage    = data.ReadInt16(),
                Owner     = data.ReadByte(),
                Type      = data.ReadInt16(),
                AiFlags   = (BitsByte)data.ReadByte(),
                Ai0       = AiFlags[0] ? Ai0 = data.ReadSingle() : 0,
                Ai1       = AiFlags[1] ? data.ReadSingle() : 0,

                Ai = new float[Projectile.maxAI],

                Proj   = new PvPProjectile(Type, Identity),
                Weapon = ProjectileUtils.GetProjectileWeapon(attacker, Type)
            };

            return(true);
        }
    void OnDrawGizmos()
    {     // Positions of this object and the target on the same plane
        Vector3 planarTarget  = new Vector3(target.position.x, 0, target.position.z);
        Vector3 planarPostion = new Vector3(transform.position.x, 0, transform.position.z);

        // Planar distance between objects
        distance = Vector3.Distance(planarTarget, planarPostion);
        // Distance along the y axis between objects
        float yOffset = transform.position.y - target.position.y;

        speed = ProjectileUtils.LaunchSpeed(distance, yOffset, 9.8f, angle * Mathf.Deg2Rad);
        Vector3 velocity            = new Vector3(0, speed * Mathf.Sin(angle * Mathf.Deg2Rad), speed * Mathf.Cos(angle * Mathf.Deg2Rad));
        float   angleBetweenObjects = Vector3.SignedAngle(Vector3.forward, planarTarget - planarPostion, Vector3.up);
        Vector3 finalVelocity       = Quaternion.AngleAxis(angleBetweenObjects, Vector3.up) * velocity;

        Gizmos.DrawLine(transform.position, transform.position + finalVelocity);

        Vector3 lastPosition = transform.position;

        for (float t = 0.0f; t < 10.0f; t += 0.05f)
        {
            Vector3 nextPosition = transform.position + finalVelocity * t + Vector3.down * (9.8f / 2.0f) * t * t;
            Gizmos.DrawLine(lastPosition, nextPosition);

            lastPosition = nextPosition;
        }
    }
Exemple #3
0
/*
 *  public void Observe(SlugEvents ev) {
 *      if (ev == SlugEvents.HitGround) {
 *          bounceCount++;
 *          ZRotationStepCurrent *= 2;
 *          if (bounceCount >= bouncesToExplode) {
 *              Explode();
 *          }
 *      }
 *  }
 */
    private void Explode(Collider2D col)
    {
        ProjectileUtils.ImpactAnimationAndSound(transform, col, properties);
        ProjectileUtils.NotifyCollider(col, properties);
        explosionWave.CastAOE("enemy", transform.position);
        gameObject.SetActive(false);
    }
Exemple #4
0
        public ProjectileNewArgs(GetDataEventArgs args, MemoryStream data, PvPPlayer attacker)
        {
            Args     = args;
            Attacker = attacker;

            Identity  = data.ReadInt16();
            Position  = new Vector2(data.ReadSingle(), data.ReadSingle());
            Velocity  = new Vector2(data.ReadSingle(), data.ReadSingle());
            Knockback = data.ReadSingle();
            Damage    = data.ReadInt16();
            Owner     = data.ReadByte();
            Type      = data.ReadInt16();
            AiFlags   = (BitsByte)data.ReadByte();
            Ai0       = 0;
            Ai1       = 0;
            if (AiFlags[0])
            {
                Ai0 = data.ReadSingle();
            }
            if (AiFlags[1])
            {
                Ai1 = data.ReadSingle();
            }
            Ai = new float[Projectile.maxAI];

            Weapon = ProjectileUtils.GetProjectileWeapon(attacker, Type);
        }
 void Update()
 {
     if (launched)
     {
         ProjectileUtils.UpdatePositionStraightLine(transform, properties);
     }
 }
Exemple #6
0
 public void OnTriggerEnter2D(Collider2D col)
 {
     if (col.tag == properties.victimTag)
     {
         ProjectileUtils.ImpactAnimationAndSound(transform, col, properties);
         ProjectileUtils.NotifyCollider(col, properties);
         gameObject.SetActive(false);
     }
 }
Exemple #7
0
 private void Explode(Collider2D col)
 {
     explosion.gameObject.SetActive(true);
     explosion.transform.position = this.transform.position;
     explosion.Play("1");
     //ProjectileUtils.ImpactAnimationAndSound(transform, col, properties);
     ProjectileUtils.NotifyCollider(col, properties);
     gameObject.SetActive(false);
 }
Exemple #8
0
    // Update is called once per frame
    void Update()
    {
        Vector3 force = transform.forward * transform.localScale.z;

        RaycastHit hit;

        if (ProjectileUtils.BallisticCast(transform.position, force, out hit, precision))
        {
            hitPosition = hit.point;
        }
    }
Exemple #9
0
    private void Explode(Collider2D col = null)
    {
        explosion.transform.position = this.transform.position;
        explosion.gameObject.SetActive(true);
        if (col != null)
        {
            ProjectileUtils.NotifyCollider(col, properties);
        }

        flash.ResetMaterial();
        gameObject.SetActive(false);
    }
        /// <summary>
        /// This method will calculate if there is valid line of sight between the explosion origin and the specific Part
        /// In order to avoid collisions with the same missile part, It will not take into account those parts beloging to same vessel that contains the explosive part
        /// </summary>
        /// <param name="part"></param>
        /// <param name="explosivePart"></param>
        /// <param name="hit"> out property with the actual hit</param>
        /// <returns></returns>
        private bool IsInLineOfSight(Part part, Part explosivePart, out RaycastHit hit, out float distance, out List <Tuple <float, float, float> > intermediateParts)
        {
            Ray partRay  = new Ray(Position, part.transform.position - Position);
            var hitCount = Physics.RaycastNonAlloc(partRay, lineOfSightHits, Range, 9076737);

            if (hitCount == lineOfSightHits.Length) // If there's a whole bunch of stuff in the way (unlikely), then we need to increase the size of our hits buffer.
            {
                lineOfSightHits = Physics.RaycastAll(partRay, Range, 9076737);
                hitCount        = lineOfSightHits.Length;
            }
            intermediateParts = new List <Tuple <float, float, float> >();
            using (var hitsEnu = lineOfSightHits.Take(hitCount).OrderBy(x => x.distance).GetEnumerator())
                while (hitsEnu.MoveNext())
                {
                    Part partHit = hitsEnu.Current.collider.GetComponentInParent <Part>();
                    if (partHit == null)
                    {
                        continue;
                    }
                    if (ProjectileUtils.IsIgnoredPart(partHit))
                    {
                        continue;                                         // Ignore ignored parts.
                    }
                    hit      = hitsEnu.Current;
                    distance = hit.distance;
                    if (partHit == part)
                    {
                        return(true);
                    }
                    if (partHit != part)
                    {
                        // ignoring collisions against the explosive
                        if (explosivePart != null && partHit.vessel == explosivePart.vessel)
                        {
                            continue;
                        }
                        if (FlightGlobals.currentMainBody != null && hit.collider.gameObject == FlightGlobals.currentMainBody.gameObject)
                        {
                            return(false);                                                                                                              // Terrain hit. Full absorption. Should avoid NREs in the following.
                        }
                        var partHP     = partHit.Damage();
                        var partArmour = partHit.GetArmorThickness();
                        if (partHP > 0) // Ignore parts that are already dead but not yet removed from the game.
                        {
                            intermediateParts.Add(new Tuple <float, float, float>(hit.distance, partHP, partArmour));
                        }
                    }
                }

            hit      = new RaycastHit();
            distance = 0;
            return(false);
        }
Exemple #11
0
        private void SetupTransition()
        {
            Service.UXController.HUD.Visible = false;
            if (this.battleData.BattleType == BattleType.PveDefend)
            {
                List <IAssetVO> battleProjectileAssets = ProjectileUtils.GetBattleProjectileAssets(Service.CurrentPlayer.Map, this.battleData.BattleVO, this.battleData.AttackerDeployableData, null, null, null, null, this.battleData.AttackerEquipment, this.battleData.DefenderEquipment);
                Service.SpecialAttackController.PreloadSpecialAttackMiscAssets();
                Service.ProjectileViewManager.LoadProjectileAssetsAndCreatePools(battleProjectileAssets);
                Service.GameStateMachine.SetState(this);
                this.OnWorldLoadComplete();
                Service.EventManager.SendEvent(EventId.BattleLoadedForDefend, this.battleData);
                this.OnWorldTransitionComplete();
                return;
            }
            IMapDataLoader mapDataLoader;

            if (this.battleData.PvpTarget != null)
            {
                mapDataLoader = Service.PvpMapDataLoader;
                ((PvpMapDataLoader)mapDataLoader).Initialize(this.battleData);
            }
            else if (this.battleData.MemberWarData != null)
            {
                mapDataLoader = Service.WarBaseMapDataLoader;
                ((WarBaseMapDataLoader)mapDataLoader).Initialize(this.battleData);
            }
            else
            {
                mapDataLoader = Service.NpcMapDataLoader;
                bool isPveBuffBase = this.battleData.BattleType == BattleType.PveBuffBase;
                ((NpcMapDataLoader)mapDataLoader).Initialize(this.battleData, isPveBuffBase);
            }
            EventManager eventManager = Service.EventManager;

            eventManager.RegisterObserver(this, EventId.MapDataProcessingStart, EventPriority.Default);
            eventManager.RegisterObserver(this, EventId.WorldLoadComplete, EventPriority.Default);
            WorldTransitioner worldTransitioner = Service.WorldTransitioner;

            if (worldTransitioner.IsSoftWiping())
            {
                worldTransitioner.ContinueWipe(this, mapDataLoader, new TransitionCompleteDelegate(this.OnWorldTransitionComplete));
            }
            else if (this.battleData.BattleType == BattleType.PvpAttackSquadWar || this.battleData.BattleType == BattleType.PveBuffBase)
            {
                worldTransitioner.StartTransition(new WarboardToWarbaseTransition(this, mapDataLoader, new TransitionCompleteDelegate(this.OnWorldTransitionComplete), false, false));
            }
            else
            {
                worldTransitioner.StartTransition(new WorldToWorldTransition(this, mapDataLoader, new TransitionCompleteDelegate(this.OnWorldTransitionComplete), false, false));
            }
        }
Exemple #12
0
 public void OnTriggerEnter2D(Collider2D col)
 {
     if (col.tag == "Player")
     {
         if (properties.explosionAnimator != null)
         {
             ProjectileUtils.ImpactAnimationAndSound(transform, col, properties);
         }
         ProjectileUtils.NotifyCollider(col, properties);
         // NO WE DONT DO THAT FOR BREATH OR ANY AOE PROJ  gameObject.SetActive(false);
         // 2 types de proj se distingue les aoe (leurs effets dure sur la duree et sur un espace)
         // et les non aoe (bullets)
     }
 }
Exemple #13
0
        public List <IAssetVO> GetProjectilePreloads(Map map)
        {
            List <string> attackerWarBuffs = null;
            List <string> defenderWarBuffs = null;
            Squad         currentSquad     = Service.SquadController.StateManager.GetCurrentSquad();

            if (currentSquad != null)
            {
                SquadWarManager warManager = Service.SquadController.WarManager;
                attackerWarBuffs = warManager.GetBuffBasesOwnedBySquad(currentSquad.SquadID);
                defenderWarBuffs = warManager.GetBuffBasesOwnedBySquad(this.squadId);
            }
            return(ProjectileUtils.GetBattleProjectileAssets(map, null, null, attackerWarBuffs, defenderWarBuffs, this.defenderSquadTroops, this.defenderChampions, this.battleData.AttackerEquipment, this.battleData.DefenderEquipment));
        }
        public override void Execute()
        {
            base.Execute();
            IntPosition     position       = new IntPosition(Units.GridToBoardX(this.gridX), Units.GridToBoardZ(this.gridZ));
            IDataController dataController = Service.Get <IDataController>();
            List <IAssetVO> assets         = new List <IAssetVO>();

            ProjectileUtils.AddTroopProjectileAssets(this.troopUid, assets, dataController);
            Service.Get <ProjectileViewManager>().LoadProjectileAssetsAndCreatePools(assets);
            TroopTypeVO    troop          = dataController.Get <TroopTypeVO>(this.troopUid);
            TroopSpawnData troopSpawnData = new TroopSpawnData(troop, position, TroopSpawnMode.LeashedToSpawnPoint, this.amount);

            Service.Get <SimTimerManager>().CreateSimTimer(1500u, false, new TimerDelegate(this.OnSpawnTimer), troopSpawnData);
            this.parent.ChildComplete(this);
        }
    private bool tryHitTarget(RangedAttackAbility rangedAttack, Vector3 position, Frame target, out Vector3 force, int steps)
    {
        float velocity = rangedAttack.weapon.range / 2.0f;

        float velocityStep = velocity / (float)steps;

        Vector3 direction = target.position - position;

        direction.y = 0.0f;

        float distance = direction.magnitude;

        direction.Normalize();

        for (int i = 0; i < steps + 1; i++)
        {
            if (ProjectileUtils.canHitCoordinate(distance, 0.0f, velocity))
            {
                float angle1 = ProjectileUtils.calculateAngle1ToHitCoordinate(distance, 0.0f, velocity);
                float angle2 = ProjectileUtils.calculateAngle2ToHitCoordinate(distance, 0.0f, velocity);

                if (ProjectileUtils.tryHitWithBallisticCast(target, position, velocity * direction, angle1, out force))
                {
                    return(true);
                }

                if (ProjectileUtils.tryHitWithBallisticCast(target, position, velocity * direction, angle2, out force))
                {
                    return(true);
                }

                if (!hasFallback)
                {
                    fallbackPosition = position;
                    fallBackVelocity = force;
                    hasFallback      = true;
                }
            }

            velocity += velocityStep;
        }

        force = Vector3.negativeInfinity;
        return(false);
    }
        private void LoadBulletAssets(Bullet bullet)
        {
            IDataController dc   = Service.Get <IDataController>();
            List <IAssetVO> list = new List <IAssetVO>();

            ProjectileUtils.AddProjectileAssets(bullet.ProjectileType, list, dc);
            if (bullet.AppliedBuffs != null)
            {
                int i     = 0;
                int count = bullet.AppliedBuffs.Count;
                while (i < count)
                {
                    list.Add(bullet.AppliedBuffs[i].BuffType);
                    i++;
                }
            }
            this.LoadProjectileAssetsAndCreatePools(list);
        }
Exemple #17
0
        public override void Execute()
        {
            base.Execute();
            Vector3 zero = Vector3.zero;

            zero.x = Units.BoardToWorldX(this.boardX);
            zero.z = Units.BoardToWorldX(this.boardZ);
            IDataController     dataController      = Service.Get <IDataController>();
            SpecialAttackTypeVO specialAttackTypeVO = dataController.Get <SpecialAttackTypeVO>(this.prepareArgs[0]);
            SpecialAttack       specialAttack       = Service.Get <SpecialAttackController>().DeploySpecialAttack(specialAttackTypeVO, TeamType.Attacker, zero);

            if (specialAttack != null)
            {
                List <IAssetVO> assets = new List <IAssetVO>();
                ProjectileUtils.AddProjectileAssets(specialAttackTypeVO.ProjectileType, assets, dataController);
                Service.Get <ProjectileViewManager>().LoadProjectileAssetsAndCreatePools(assets);
                Service.Get <EventManager>().SendEvent(EventId.SpecialAttackDeployed, specialAttack);
            }
            this.parent.ChildComplete(this);
        }
    public void OnTriggerEnter2D(Collider2D col)
    {
        if (col.tag == properties.victimTag || col.tag == "World")
        {
            ProjectileUtils.RandomizeImpactPosition(transform, impactAnimator.transform);
            impactAnimator.gameObject.SetActive(true);
            if (col.tag == "World")
            {
                impactAnimator.transform.right = transform.right;
                impactAnimator.Play("2");
            }
            else
            {
                impactAnimator.Play("1");
                ProjectileUtils.NotifyCollider(col, properties);
            }

            gameObject.SetActive(false);
        }
    }
Exemple #19
0
    public static bool tryHitWithBallisticCast(Frame target, Vector3 position, Vector3 velocity, float angle, out Vector3 force)
    {
        force = Vector3.RotateTowards(velocity, Vector3.up, angle, 0.0f);



        // Cast the ballistic curve to see, if it hits the target, otherwise, keep looking!
        RaycastHit hit;

        if (ProjectileUtils.BallisticCast(position, force, out hit))
        {
            Frame d = hit.collider.GetComponent <Frame>();

            if (d == target)
            {
                return(true);
            }
        }

        return(false);
    }
Exemple #20
0
        public override void AI()
        {
            int num1 = Dust.NewDust(projectile.position, projectile.width, projectile.height, 15, projectile.velocity.X * 0.5f, projectile.velocity.Y * 0.5f);

            Main.dust[num1].noGravity = true;
            Main.dust[num1].velocity *= 0.9f;

            if (projectile.timeLeft <= 300f || (ProjectileUtils.CountProjectiles(projectile.type) > 1 && ProjectileUtils.HasLeastTimeleft(projectile.whoAmI)))
            {
                projectile.alpha += 5;
                if (projectile.alpha > 255)
                {
                    projectile.alpha = 255;
                    projectile.Kill();
                }
            }

            projectile.localAI[1]--;
            if (projectile.owner == Main.myPlayer)
            {
                float max = 400f;
                for (int i = 0; i < Main.npc.Length; i++)
                {
                    NPC nPC = Main.npc[i];
                    if (nPC.active && !nPC.friendly && nPC.damage > 0 && !nPC.dontTakeDamage && Vector2.Distance(projectile.Center, nPC.Center) <= max)
                    {
                        float Speed    = 9f;
                        float rotation = (float)Math.Atan2(projectile.Center.Y - nPC.Center.Y, projectile.Center.X - nPC.Center.X);
                        if (projectile.localAI[1] <= 0)
                        {
                            Vector2 speed = new Vector2((float)((Math.Cos(rotation) * Speed) * -1), (float)((Math.Sin(rotation) * Speed) * -1));
                            //Main.PlaySound(2, (int)projectile.position.X, (int)projectile.position.Y, 12);
                            Projectile.NewProjectile(projectile.Center.X, projectile.Center.Y, speed.X, speed.Y, mod.ProjectileType("LightningBlast"), projectile.damage, projectile.knockBack, projectile.owner);
                            projectile.localAI[1] = Main.rand.Next(16, 60);
                        }
                    }
                }
            }
        }
    private Vector3 getVelocityForTarget(Vector3 position, Vector3 target, float initialAngle)
    {
        float gravity = GameSettings.gravity;
        // Selected angle in radians
        float angle = initialAngle * Mathf.Deg2Rad;

        // Positions of this object and the target on the same plane
        Vector3 planarTarget  = new Vector3(target.x, 0, target.z);
        Vector3 planarPostion = new Vector3(position.x, 0, position.z);


        // Planar distance between objects
        float distance = Vector3.Distance(planarTarget, planarPostion);
        // Distance along the y axis between objects
        float yOffset = position.y - target.y;

        float   speed    = ProjectileUtils.LaunchSpeed(distance, yOffset, gravity, angle);
        Vector3 velocity = new Vector3(0, speed * Mathf.Sin(angle), speed * Mathf.Cos(angle));

        float angleBetweenObjects = Vector3.SignedAngle(Vector3.forward, planarTarget - planarPostion, Vector3.up);

        timeOfFlight = ProjectileUtils.TimeOfFlight(speed, angle, yOffset, gravity);
        return(Quaternion.AngleAxis(angleBetweenObjects, Vector3.up) * velocity);
    }
Exemple #22
0
        public List <IAssetVO> GetProjectilePreloads(Map map)
        {
            List <string> attackerWarBuffs = null;
            List <string> defenderWarBuffs = null;

            if (this.isPveBuffBase)
            {
                Squad currentSquad = Service.Get <SquadController>().StateManager.GetCurrentSquad();
                if (currentSquad != null)
                {
                    SquadWarManager warManager = Service.Get <SquadController>().WarManager;
                    attackerWarBuffs = warManager.GetBuffBasesOwnedBySquad(currentSquad.SquadID);
                }
            }
            List <string> attackerEquipment = null;
            List <string> defenderEquipment = null;

            if (this.battleData != null)
            {
                attackerEquipment = this.battleData.AttackerEquipment;
                defenderEquipment = this.battleData.DefenderEquipment;
            }
            return(ProjectileUtils.GetBattleProjectileAssets(map, this.battle, null, attackerWarBuffs, defenderWarBuffs, null, null, attackerEquipment, defenderEquipment));
        }
Exemple #23
0
    public void CastAOE(string victimsTag, Vector2 pos)
    {
        Vector2 center = new Vector2(pos.x - transform.right.x * (boxSize.x / 2) + boxOffset.x * transform.right.x,
                                     pos.y - (boxSize.y / 2) + boxOffset.y);

        float duration = 1.5f;

        Debug.DrawLine(center, new Vector2(center.x, center.y + boxSize.y), Color.red, duration);
        Debug.DrawLine(center, new Vector2(center.x + boxSize.x * transform.right.x, center.y), Color.blue, duration);
        Debug.DrawLine(new Vector2(center.x + boxSize.x * transform.right.x, center.y),
                       new Vector2(center.x + boxSize.x * transform.right.x, center.y + boxSize.y), Color.cyan, duration);

        Vector2 centre = new Vector2(pos.x + boxOffset.x * transform.right.x, pos.y + boxOffset.y);

        RaycastHit2D[] hits = Physics2D.BoxCastAll(centre, boxSize, 0, transform.right, 0, layerMask);

        for (int i = 0; i < hits.Length; i++)
        {
            if (hits[i].collider.tag == victimsTag)
            {
                ProjectileUtils.NotifyCollider(hits[i].collider, projectileProp);
            }
        }
    }
Exemple #24
0
        void FixedUpdate()
        {
            if (!gameObject.activeInHierarchy)
            {
                return;
            }
            //floating origin and velocity offloading corrections
            if (!FloatingOrigin.Offset.IsZero() || !Krakensbane.GetFrameVelocity().IsZero())
            {
                transform.position -= FloatingOrigin.OffsetNonKrakensbane;
                prevPosition       -= FloatingOrigin.OffsetNonKrakensbane;
                startPosition      -= FloatingOrigin.OffsetNonKrakensbane;
            }
            distanceFromStart = Vector3.Distance(transform.position, startPosition);

            if (Time.time - startTime < stayTime && transform.parent != null)
            {
                transform.rotation = transform.parent.rotation;
                transform.position = spawnTransform.position;
                //+(transform.parent.rigidbody.velocity*Time.fixedDeltaTime);
            }
            else
            {
                if (transform.parent != null && parentRB)
                {
                    transform.parent = null;
                    rb.isKinematic   = false;
                    rb.velocity      = parentRB.velocity + Krakensbane.GetFrameVelocityV3f();
                }
            }

            if (rb && !rb.isKinematic)
            {
                //physics
                if (FlightGlobals.RefFrameIsRotating)
                {
                    rb.velocity += FlightGlobals.getGeeForceAtPosition(transform.position) * Time.fixedDeltaTime;
                }

                //guidance and attitude stabilisation scales to atmospheric density.
                float atmosMultiplier =
                    Mathf.Clamp01(2.5f *
                                  (float)
                                  FlightGlobals.getAtmDensity(FlightGlobals.getStaticPressure(transform.position),
                                                              FlightGlobals.getExternalTemperature(), FlightGlobals.currentMainBody));

                //model transform. always points prograde
                transform.rotation = Quaternion.RotateTowards(transform.rotation,
                                                              Quaternion.LookRotation(rb.velocity + Krakensbane.GetFrameVelocity(), transform.up),
                                                              atmosMultiplier * (0.5f * (Time.time - startTime)) * 50 * Time.fixedDeltaTime);


                if (Time.time - startTime < thrustTime && Time.time - startTime > stayTime)
                {
                    thrustVector.x = randomThrustDeviation * (1 - (Mathf.PerlinNoise(4 * Time.time, randThrustSeed) * 2)) / massScalar; //this needs to scale w/ rocket mass, or light projectiles will be
                    thrustVector.y = randomThrustDeviation * (1 - (Mathf.PerlinNoise(randThrustSeed, 4 * Time.time) * 2)) / massScalar; //far more affected than heavier ones
                    rb.AddRelativeForce(thrustVector);
                }//0.012/rocketmass - use .012 as baseline, it's the mass of hte hydra, which the randomTurstdeviation was originally calibrated for
            }

            if (Time.time - startTime > thrustTime)
            {
                foreach (var pe in pEmitters)
                {
                    if (pe != null)
                    {
                        pe.emit = false;
                    }
                }
            }
            if (Time.time - startTime > 0.1f + stayTime)
            {
                hasPenetrated = true;
                hasDetonated  = false;
                penTicker     = 0;

                currPosition = transform.position;
                float dist = (currPosition - prevPosition).magnitude;
                RocketRay = new Ray(prevPosition, currPosition - prevPosition);
                var hits = Physics.RaycastAll(RocketRay, dist, 9076737);
                if (hits.Length > 0)
                {
                    var orderedHits = hits.OrderBy(x => x.distance);

                    using (var hitsEnu = orderedHits.GetEnumerator())
                    {
                        while (hitsEnu.MoveNext())
                        {
                            if (!hasPenetrated || hasDetonated)
                            {
                                break;
                            }

                            RaycastHit hit     = hitsEnu.Current;
                            Part       hitPart = null;
                            KerbalEVA  hitEVA  = null;

                            try
                            {
                                hitPart = hit.collider.gameObject.GetComponentInParent <Part>();
                                hitEVA  = hit.collider.gameObject.GetComponentUpwards <KerbalEVA>();
                            }
                            catch (NullReferenceException e)
                            {
                                Debug.LogWarning("[BDArmory.BDArmory]:NullReferenceException for Kinetic Hit: " + e.Message);
                                return;
                            }

                            if (hitEVA != null)
                            {
                                hitPart = hitEVA.part;
                                // relative velocity, separate from the below statement, because the hitpart might be assigned only above
                                if (hitPart.rb != null)
                                {
                                    impactVelocity = (rb.velocity - (hitPart.rb.velocity + Krakensbane.GetFrameVelocityV3f())).magnitude;
                                }
                                else
                                {
                                    impactVelocity = rb.velocity.magnitude;
                                }
                                ProjectileUtils.ApplyDamage(hitPart, hit, 1, 1, caliber, rocketMass, impactVelocity, bulletDmgMult, distanceFromStart, explosive, false, sourceVessel, rocketName);
                                break;
                            }

                            if (hitPart != null && hitPart.vessel == sourceVessel)
                            {
                                continue;                                                     //avoid autohit;
                            }
                            Vector3 impactVector = rb.velocity;
                            if (hitPart != null && hitPart.rb != null)
                            {
                                // using relative velocity vector instead of just rocket velocity
                                // since KSP vessels can easily be moving faster than rockets
                                impactVector = rb.velocity - (hitPart.rb.velocity + Krakensbane.GetFrameVelocityV3f());
                            }

                            float hitAngle = Vector3.Angle(impactVector, -hit.normal);

                            if (ProjectileUtils.CheckGroundHit(hitPart, hit, caliber))
                            {
                                ProjectileUtils.CheckBuildingHit(hit, rocketMass, rb.velocity, bulletDmgMult);
                                Detonate(hit.point, false);
                                return;
                            }

                            impactVelocity = impactVector.magnitude;
                            if (gravitic)
                            {
                                var ME = hitPart.FindModuleImplementing <ModuleMassAdjust>();
                                if (ME == null)
                                {
                                    ME = (ModuleMassAdjust)hitPart.AddModule("ModuleMassAdjust");
                                }
                                ME.massMod  += massMod;
                                ME.duration += BDArmorySettings.WEAPON_FX_DURATION;
                            }
                            if (concussion)
                            {
                                hitPart.rb.AddForceAtPosition(impactVector.normalized * impulse, hit.point, ForceMode.Acceleration);
                                Detonate(hit.point, false);
                                hasDetonated = true;
                                return; //impulse rounds shouldn't penetrate/do damage
                            }
                            float anglemultiplier = (float)Math.Cos(Math.PI * hitAngle / 180.0);

                            float thickness         = ProjectileUtils.CalculateThickness(hitPart, anglemultiplier);
                            float penetration       = ProjectileUtils.CalculatePenetration(caliber, rocketMass, impactVelocity);
                            float penetrationFactor = ProjectileUtils.CalculateArmorPenetration(hitPart, anglemultiplier, hit, penetration, thickness, caliber);
                            if (penetration > thickness)
                            {
                                rb.velocity = rb.velocity * (float)Math.Sqrt(thickness / penetration);
                                if (penTicker > 0)
                                {
                                    rb.velocity *= 0.55f;
                                }
                            }

                            if (penetrationFactor > 1)
                            {
                                hasPenetrated = true;
                                ProjectileUtils.ApplyDamage(hitPart, hit, 1, penetrationFactor, caliber, rocketMass, impactVelocity, bulletDmgMult, distanceFromStart, explosive, false, sourceVessel, rocketName);
                                penTicker += 1;
                                ProjectileUtils.CheckPartForExplosion(hitPart);

                                if (explosive)
                                {
                                    transform.position += (rb.velocity * Time.fixedDeltaTime) / 3;

                                    Detonate(transform.position, false);
                                    hasDetonated = true;
                                }
                            }
                            else // stopped by armor
                            {
                                if (hitPart.rb != null && hitPart.rb.mass > 0)
                                {
                                    float forceAverageMagnitude = impactVelocity * impactVelocity *
                                                                  (1f / hit.distance) * rocketMass;

                                    float accelerationMagnitude =
                                        forceAverageMagnitude / (hitPart.vessel.GetTotalMass() * 1000);

                                    hitPart.rb.AddForceAtPosition(impactVector.normalized * accelerationMagnitude, hit.point, ForceMode.Acceleration);

                                    if (BDArmorySettings.DRAW_DEBUG_LABELS)
                                    {
                                        Debug.Log("[BDArmory.PooledRocket]: Force Applied " + Math.Round(accelerationMagnitude, 2) + "| Vessel mass in kgs=" + hitPart.vessel.GetTotalMass() * 1000 + "| rocket effective mass =" + rocketMass);
                                    }
                                }

                                hasPenetrated = false;
                                ProjectileUtils.ApplyDamage(hitPart, hit, 1, penetrationFactor, caliber, rocketMass, impactVelocity, bulletDmgMult, distanceFromStart, explosive, false, sourceVessel, rocketName);
                                Detonate(hit.point, false);
                                hasDetonated = true;
                            }

                            if (penTicker >= 2)
                            {
                                Detonate(hit.point, false);
                                return;
                            }

                            if (rb.velocity.magnitude <= 100 && hasPenetrated && (Time.time - startTime > thrustTime))
                            {
                                if (BDArmorySettings.DRAW_DEBUG_LABELS)
                                {
                                    Debug.Log("[BDArmory.PooledRocket]: Rocket ballistic velocity too low, stopping");
                                }
                                Detonate(hit.point, false);
                                return;
                            }
                            if (!hasPenetrated || hasDetonated)
                            {
                                break;
                            }
                        }
                    }
                }
            }
            else if (FlightGlobals.getAltitudeAtPos(currPosition) <= 0)
            {
                Detonate(currPosition, false);
            }
            prevPosition = currPosition;

            if (Time.time - startTime > lifeTime) // life's 10s, quite a long time for faster rockets
            {
                Detonate(transform.position, true);
            }
            if (distanceFromStart >= maxAirDetonationRange)//rockets are performance intensive, lets cull those that have flown too far away
            {
                Detonate(transform.position, false);
            }
            if (ProximityAirDetonation(distanceFromStart))
            {
                Detonate(transform.position, false);
            }
        }
        private List <BlastHitEvent> ProcessingBlastSphere()
        {
            explosionEventsPreProcessing.Clear();
            explosionEventsPartsAdded.Clear();
            explosionEventsBuildingAdded.Clear();
            explosionEventsVesselsHitByMissiles.Clear();

            string sourceVesselName = null;

            if (BDACompetitionMode.Instance)
            {
                switch (ExplosionSource)
                {
                case ExplosionSourceType.Missile:
                    var explosivePart = ExplosivePart ? ExplosivePart.FindModuleImplementing <BDExplosivePart>() : null;
                    sourceVesselName = explosivePart ? explosivePart.sourcevessel.GetName() : SourceVesselName;
                    break;

                case ExplosionSourceType.Bullet:
                    sourceVesselName = SourceVesselName;
                    break;

                default:
                    break;
                }
            }
            var overlapSphereColliderCount = Physics.OverlapSphereNonAlloc(Position, Range, overlapSphereColliders, 9076737);

            if (overlapSphereColliderCount == overlapSphereColliders.Length)
            {
                overlapSphereColliders     = Physics.OverlapSphere(Position, Range, 9076737);
                overlapSphereColliderCount = overlapSphereColliders.Length;
            }
            using (var hitCollidersEnu = overlapSphereColliders.Take(overlapSphereColliderCount).GetEnumerator())
            {
                while (hitCollidersEnu.MoveNext())
                {
                    if (hitCollidersEnu.Current == null)
                    {
                        continue;
                    }

                    Part partHit = hitCollidersEnu.Current.GetComponentInParent <Part>();
                    if (partHit == null)
                    {
                        continue;
                    }
                    if (ProjectileUtils.IsIgnoredPart(partHit))
                    {
                        continue;                                         // Ignore ignored parts.
                    }
                    if (partHit != null && partHit.mass > 0 && !explosionEventsPartsAdded.Contains(partHit))
                    {
                        var damaged = ProcessPartEvent(partHit, sourceVesselName, explosionEventsPreProcessing, explosionEventsPartsAdded);
                        // If the explosion derives from a missile explosion, count the parts damaged for missile hit scores.
                        if (damaged && ExplosionSource == ExplosionSourceType.Missile && BDACompetitionMode.Instance)
                        {
                            if (sourceVesselName != null && BDACompetitionMode.Instance.Scores.ContainsKey(sourceVesselName)) // Check that the source vessel is in the competition.
                            {
                                var damagedVesselName = partHit.vessel != null?partHit.vessel.GetName() : null;

                                if (damagedVesselName != null && damagedVesselName != sourceVesselName && BDACompetitionMode.Instance.Scores.ContainsKey(damagedVesselName)) // Check that the damaged vessel is in the competition and isn't the source vessel.
                                {
                                    if (BDACompetitionMode.Instance.Scores[damagedVesselName].missilePartDamageCounts.ContainsKey(sourceVesselName))
                                    {
                                        ++BDACompetitionMode.Instance.Scores[damagedVesselName].missilePartDamageCounts[sourceVesselName];
                                    }
                                    else
                                    {
                                        BDACompetitionMode.Instance.Scores[damagedVesselName].missilePartDamageCounts[sourceVesselName] = 1;
                                    }
                                    if (!BDACompetitionMode.Instance.Scores[damagedVesselName].everyoneWhoHitMeWithMissiles.Contains(sourceVesselName))
                                    {
                                        BDACompetitionMode.Instance.Scores[damagedVesselName].everyoneWhoHitMeWithMissiles.Add(sourceVesselName);
                                    }
                                    ++BDACompetitionMode.Instance.Scores[sourceVesselName].totalDamagedPartsDueToMissiles;
                                    BDACompetitionMode.Instance.Scores[damagedVesselName].lastMissileHitTime             = Planetarium.GetUniversalTime();
                                    BDACompetitionMode.Instance.Scores[damagedVesselName].lastPersonWhoHitMeWithAMissile = sourceVesselName;
                                    if (explosionEventsVesselsHitByMissiles.ContainsKey(damagedVesselName))
                                    {
                                        ++explosionEventsVesselsHitByMissiles[damagedVesselName];
                                    }
                                    else
                                    {
                                        explosionEventsVesselsHitByMissiles[damagedVesselName] = 1;
                                    }
                                    if (BDArmorySettings.REMOTE_LOGGING_ENABLED)
                                    {
                                        BDAScoreService.Instance.TrackMissileParts(sourceVesselName, damagedVesselName, 1);
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        DestructibleBuilding building = hitCollidersEnu.Current.GetComponentInParent <DestructibleBuilding>();

                        if (building != null && !explosionEventsBuildingAdded.Contains(building))
                        {
                            ProcessBuildingEvent(building, explosionEventsPreProcessing, explosionEventsBuildingAdded);
                        }
                    }
                }
            }
            if (explosionEventsVesselsHitByMissiles.Count > 0)
            {
                string message = "";
                foreach (var vesselName in explosionEventsVesselsHitByMissiles.Keys)
                {
                    message += (message == "" ? "" : " and ") + vesselName + " had " + explosionEventsVesselsHitByMissiles[vesselName];
                }
                message += " parts damaged due to missile strike" + (SourceWeaponName != null ? " (" + SourceWeaponName + ")" : "") + (sourceVesselName != null ? " from " + sourceVesselName : "") + ".";
                BDACompetitionMode.Instance.competitionStatus.Add(message);
                // Note: damage hasn't actually been applied to the parts yet, just assigned as events, so we can't know if they survived.
                foreach (var vesselName in explosionEventsVesselsHitByMissiles.Keys) // Note: sourceVesselName is already checked for being in the competition before damagedVesselName is added to explosionEventsVesselsHitByMissiles, so we don't need to check it here.
                {
                    if (BDACompetitionMode.Instance.Scores[vesselName].missileHitCounts.ContainsKey(sourceVesselName))
                    {
                        ++BDACompetitionMode.Instance.Scores[vesselName].missileHitCounts[sourceVesselName];
                    }
                    else
                    {
                        BDACompetitionMode.Instance.Scores[vesselName].missileHitCounts[sourceVesselName] = 1;
                    }
                }
            }
            return(explosionEventsPreProcessing);
        }
        void Detonate()                                                                                          //borrowed from Stockalike Project Orion
        {
            if (hasDetonated || FlightGlobals.currentMainBody == null || VesselSpawner.Instance.vesselsSpawning) // Don't trigger on scene changes or during spawning.
            {
                return;
            }
            if (BDArmorySettings.DRAW_DEBUG_LABELS)
            {
                Debug.Log("[BDArmory.NukeTest]: Running Detonate() on nerva in vessel " + Sourcevessel);
            }
            //affect any nearby parts/vessels that aren't the source vessel

            Dictionary <string, int> vesselsHitByMissiles = new Dictionary <string, int>();

            using (var blastHits = Physics.OverlapSphere(part.transform.position, thermalRadius, 9076737).AsEnumerable().GetEnumerator())
            {
                partsHit.Clear();
                while (blastHits.MoveNext())
                {
                    if (blastHits.Current == null)
                    {
                        continue;
                    }
                    if (blastHits.Current.gameObject == FlightGlobals.currentMainBody.gameObject)
                    {
                        continue;                                                                           // Ignore terrain hits.
                    }
                    Part partHit = blastHits.Current.GetComponentInParent <Part>();
                    if (partHit == null)
                    {
                        continue;
                    }
                    if (ProjectileUtils.IsIgnoredPart(partHit))
                    {
                        continue;                                         // Ignore ignored parts.
                    }
                    if (partsHit.Contains(partHit))
                    {
                        continue;                             // Don't hit the same part multiple times.
                    }
                    partsHit.Add(partHit);
                    if (partHit != null && partHit.mass > 0)
                    {
                        var   distToG0      = Math.Max((part.transform.position - partHit.transform.position).magnitude, 1f);
                        float radiativeArea = !double.IsNaN(partHit.radiativeArea) ? (float)partHit.radiativeArea : partHit.GetArea();
                        if (BDArmorySettings.DRAW_DEBUG_LABELS && double.IsNaN(partHit.radiativeArea))
                        {
                            Debug.Log("[BDArmory.NukeTest]: radiative area of part " + partHit + " was NaN, using approximate area " + radiativeArea + " instead.");
                        }
                        //if (partHit.vessel != this.vessel)
                        if (partHit != part)
                        {
                            partHit.skinTemperature += fluence * 3370000000 / (4 * Math.PI * Math.Pow(distToG0, 2.0)) * radiativeArea / 2; // Fluence scales linearly w/ yield, 1 Kt will produce between 33 TJ and 337 kJ at 0-1000m,
                        } // everything gets heated via atmosphere

                        Ray        LoSRay = new Ray(part.transform.position, partHit.transform.position - part.transform.position);
                        RaycastHit hit;
                        if (Physics.Raycast(LoSRay, out hit, distToG0, 9076737)) // only add impulse to parts with line of sight to detonation
                        {
                            KerbalEVA eva         = hit.collider.gameObject.GetComponentUpwards <KerbalEVA>();
                            Part      p           = eva ? eva.part : hit.collider.gameObject.GetComponentInParent <Part>();
                            float     blastDamage = 100;
                            if (p == partHit)
                            {
                                //if (p.vessel != this.vessel)
                                if (p != part)
                                {
                                    // Forces
                                    if (p.rb != null && p.rb.mass > 0) // Don't apply forces to physicsless parts.
                                    {
                                        var blastImpulse = Mathf.Pow(3.01f * 1100f / distToG0, 1.25f) * 6.894f * lastValidAtmDensity * yieldCubeRoot * radiativeArea / 3f;
                                        // Math.Pow(Math.Pow(Math.Pow(9.54e-3 * 2200.0 / distToG0, 1.95), 4.0) + Math.Pow(Math.Pow(3.01 * 1100.0 / distToG0, 1.25), 4.0), 0.25) * 6.894 * vessel.atmDensity * Math.Pow(yield, 1.0 / 3.0) * partHit.radiativeArea / 3.0; //assuming a 0.05 kT yield
                                        if (float.IsNaN(blastImpulse))
                                        {
                                            Debug.LogWarning("[BDArmory.NukeTest]: blast impulse is NaN. distToG0: " + distToG0 + ", vessel: " + vessel + ", atmDensity: " + lastValidAtmDensity + ", yield^(1/3): " + yieldCubeRoot + ", partHit: " + partHit + ", radiativeArea: " + radiativeArea);
                                        }
                                        else
                                        {
                                            if (BDArmorySettings.DRAW_DEBUG_LABELS)
                                            {
                                                Debug.Log("[BDArmory.NukeTest]: Applying " + blastImpulse.ToString("0.0") + " impulse to " + p + " of mass " + p.mass + " at distance " + distToG0 + "m");
                                            }
                                            p.rb.AddForceAtPosition((partHit.transform.position - part.transform.position).normalized * (float)blastImpulse, partHit.transform.position, ForceMode.Impulse);
                                        }
                                    }

                                    // Damage
                                    blastDamage = ((float)((yield * 3370000000) / (4f * Mathf.PI * distToG0 * distToG0) * (radiativeArea / 2f)));
                                    if (float.IsNaN(blastDamage))
                                    {
                                        Debug.LogWarning("[BDArmory.NukeTest]: blast damage is NaN. distToG0: " + distToG0 + ", yield: " + yield + ", part: " + partHit + ", radiativeArea: " + radiativeArea);
                                        continue;
                                    }
                                    p.AddExplosiveDamage(blastDamage, 100, ExplosionSourceType.Missile);

                                    // Scoring
                                    var aName = Sourcevessel;       // Attacker
                                    var tName = p.vessel.GetName(); // Target
                                    if (tName != null && aName != tName && BDACompetitionMode.Instance.Scores.ContainsKey(tName) && BDACompetitionMode.Instance.Scores.ContainsKey(aName))
                                    {
                                        // Part hit counts
                                        if (BDACompetitionMode.Instance.Scores[tName].missilePartDamageCounts.ContainsKey(aName))
                                        {
                                            ++BDACompetitionMode.Instance.Scores[tName].missilePartDamageCounts[aName];
                                        }
                                        else
                                        {
                                            BDACompetitionMode.Instance.Scores[tName].missilePartDamageCounts[aName] = 1;
                                        }
                                        if (!BDACompetitionMode.Instance.Scores[tName].everyoneWhoHitMeWithMissiles.Contains(aName))
                                        {
                                            BDACompetitionMode.Instance.Scores[tName].everyoneWhoHitMeWithMissiles.Add(aName);
                                        }
                                        ++BDACompetitionMode.Instance.Scores[aName].totalDamagedPartsDueToMissiles;
                                        BDACompetitionMode.Instance.Scores[tName].lastMissileHitTime             = Planetarium.GetUniversalTime();
                                        BDACompetitionMode.Instance.Scores[tName].lastPersonWhoHitMeWithAMissile = aName;
                                        if (vesselsHitByMissiles.ContainsKey(tName))
                                        {
                                            ++vesselsHitByMissiles[tName];
                                        }
                                        else
                                        {
                                            vesselsHitByMissiles[tName] = 1;
                                        }
                                        if (BDArmorySettings.REMOTE_LOGGING_ENABLED)
                                        {
                                            BDAScoreService.Instance.TrackMissileParts(aName, tName, 1);
                                        }

                                        // Part damage scoring
                                        var tData = BDACompetitionMode.Instance.Scores[tName];
                                        if (tData.damageFromMissiles.ContainsKey(aName))
                                        {
                                            tData.damageFromMissiles[aName] += blastDamage;
                                        }
                                        else
                                        {
                                            tData.damageFromMissiles.Add(aName, blastDamage);
                                        }
                                        if (BDArmorySettings.REMOTE_LOGGING_ENABLED)
                                        {
                                            BDAScoreService.Instance.TrackMissileDamage(aName, tName, blastDamage);
                                        }
                                        if (BDArmorySettings.DRAW_DEBUG_LABELS)
                                        {
                                            Debug.Log("[BDArmory.NukeTest]: " + aName + " did " + blastDamage + " blast damage to " + tName + " at " + distToG0.ToString("0.000") + "m");
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        DestructibleBuilding building = blastHits.Current.GetComponentInParent <DestructibleBuilding>();

                        if (building != null)
                        {
                            var distToEpicenter = Mathf.Max((part.transform.position - building.transform.position).magnitude, 1f);
                            var blastImpulse    = Mathf.Pow(3.01f * 1100f / distToEpicenter, 1.25f) * 6.894f * lastValidAtmDensity * yieldCubeRoot;
                            // blastImpulse = (((((Math.Pow((Math.Pow((Math.Pow((9.54 * Math.Pow(10.0, -3.0) * (2200.0 / distToEpicenter)), 1.95)), 4.0) + Math.Pow((Math.Pow((3.01 * (1100.0 / distToEpicenter)), 1.25)), 4.0)), 0.25)) * 6.894) * (vessel.atmDensity)) * Math.Pow(yield, (1.0 / 3.0))));
                            if (!double.IsNaN(blastImpulse) && blastImpulse > 140) //140kPa, level at which reinforced concrete structures are destroyed
                            {
                                building.Demolish();
                            }
                        }
                    }
                }
            }
            if (vesselsHitByMissiles.Count > 0)
            {
                string message = "";
                foreach (var vesselName in vesselsHitByMissiles.Keys)
                {
                    message += (message == "" ? "" : " and ") + vesselName + " had " + vesselsHitByMissiles[vesselName];
                }
                message += " parts damaged (Blast Wave) by " + Sourcevessel + "'s exploding engine core.";
                BDACompetitionMode.Instance.competitionStatus.Add(message);
                Debug.Log("[BDArmory.NukeTest]: " + message);
            }
            ExplosionFx.CreateExplosion(part.transform.position, 1, explModelPath, explSoundPath, ExplosionSourceType.Missile, 0, null, Sourcevessel, "Reactor Containment Failure");
            hasDetonated = true;
            if (part.vessel != null) // Already in the process of being destroyed.
            {
                part.Destroy();
            }
        }
 /// <summary>
 /// Gets the position of the projectile.
 /// </summary>
 /// <returns></returns>
 public Vector2 GetPosition()
 {
     return(ProjectileUtils.GetMainProjectile(this.identity, this.type, this.OwnerProjectile.Index).position);
 }
Exemple #28
0
 public List <IAssetVO> GetProjectilePreloads(Map map)
 {
     return(ProjectileUtils.GetBattleProjectileAssets(map, null, null, null, null, this.pvpTarget.GuildDonatedTroops, this.pvpTarget.Champions, this.battleData.AttackerEquipment, this.pvpTarget.Equipment));
 }
Exemple #29
0
        public override bool PreDraw(SpriteBatch spriteBatch, Color lightColor)
        {
            ProjectileUtils.DrawAfterImages(projectile, spriteBatch, lightColor);

            return(true);
        }
        private ProjectileView SpawnProjectile(Bullet bullet, bool isOnGround)
        {
            if (!ProjectileUtils.AreAllBulletAssetsLoaded(bullet, this.loadedAssets))
            {
                this.LoadBulletAssets(bullet);
                if (bullet.ProjectileType != null)
                {
                    Service.Get <StaRTSLogger>().Warn("Loading assets on demand for projectile " + bullet.ProjectileType.Uid);
                }
            }
            bool             isDeflection   = bullet.IsDeflection;
            ProjectileTypeVO projectileType = bullet.ProjectileType;
            GameObject       gunLocator     = bullet.GunLocator;
            Vector3          vector;

            if (!isDeflection && gunLocator != null)
            {
                vector = gunLocator.transform.position;
            }
            else
            {
                vector = bullet.SpawnWorldLocation;
            }
            Vector3 targetWorldLocation = bullet.TargetWorldLocation;

            if (isOnGround)
            {
                vector.y = 0f;
                targetWorldLocation.y = 0f;
            }
            else if (projectileType.IsBeam || (bullet.Owner != null && bullet.Target != null && bullet.Target.ShieldBorderComp != null))
            {
                targetWorldLocation.y = vector.y;
            }
            ProjectileView projectileView = (this.projectilePool.Count > 0) ? this.projectilePool.Pop() : new ProjectileView();

            projectileView.Init(projectileType, bullet, isOnGround);
            if (!isDeflection && !string.IsNullOrEmpty(projectileType.MuzzleFlashAssetName))
            {
                this.StartDirectionalEmitter(bullet.Owner, gunLocator, vector, targetWorldLocation, projectileType.MuzzleFlashAssetName, projectileType.MuzzleFlashFadeTime);
                int num = 0;
                if (bullet.AppliedBuffs != null)
                {
                    num = bullet.AppliedBuffs.Count;
                }
                FactionType ownerFaction = bullet.OwnerFaction;
                for (int i = 0; i < num; i++)
                {
                    string muzzleAssetNameBasedOnFaction = bullet.AppliedBuffs[i].BuffType.GetMuzzleAssetNameBasedOnFaction(ownerFaction);
                    if (!string.IsNullOrEmpty(muzzleAssetNameBasedOnFaction))
                    {
                        this.StartDirectionalEmitter(bullet.Owner, gunLocator, vector, targetWorldLocation, muzzleAssetNameBasedOnFaction, projectileType.MuzzleFlashFadeTime);
                    }
                }
            }
            GameObject     gameObject      = null;
            float          num2            = bullet.TravelTime / 1000f;
            GameObject     gameObject2     = null;
            ParticleSystem particleSystem  = null;
            string         bulletAssetName = projectileType.GetBulletAssetName(isOnGround);
            EmitterPool    emitter         = this.GetEmitter(bulletAssetName);

            if (emitter != null)
            {
                float num3 = num2;
                float delayPostEmitterStop = 0f;
                if (projectileType.IsBeam)
                {
                    num3 = num2 * (float)(projectileType.BeamEmitterLength - projectileType.BeamInitialZeroes) / (float)(projectileType.BeamLifeLength - projectileType.BeamInitialZeroes);
                    delayPostEmitterStop = num2 - num3;
                }
                if (emitter is MultipleEmittersPool)
                {
                    MultipleEmittersPool multipleEmittersPool = (MultipleEmittersPool)emitter;
                    gameObject = multipleEmittersPool.GetEmitterRoot();
                    if (gameObject != null)
                    {
                        multipleEmittersPool.StopEmissionAndReturnToPool(gameObject, num3, delayPostEmitterStop);
                    }
                }
                else if (emitter is SingleEmitterPool)
                {
                    SingleEmitterPool singleEmitterPool = (SingleEmitterPool)emitter;
                    particleSystem = singleEmitterPool.GetEmitter();
                    if (particleSystem != null)
                    {
                        singleEmitterPool.StopEmissionAndReturnToPool(particleSystem, num3, delayPostEmitterStop);
                    }
                }
                if (this.meshes.ContainsKey(bulletAssetName))
                {
                    gameObject2 = this.meshes[bulletAssetName].GetMesh();
                }
            }
            Transform targetTransform = this.GetTargetTransform(bullet, vector, targetWorldLocation);

            if (gameObject2 != null && particleSystem != null)
            {
                projectileView.InitWithMeshAndEmitter(num2, vector, targetWorldLocation, gameObject2, particleSystem, targetTransform);
            }
            else if (gameObject2 != null && gameObject == null)
            {
                projectileView.InitWithMesh(num2, vector, targetWorldLocation, gameObject2, targetTransform);
            }
            else if (particleSystem != null)
            {
                projectileView.InitWithEmitter(num2, vector, targetWorldLocation, particleSystem, targetTransform);
            }
            else if (gameObject != null)
            {
                projectileView.InitWithEmitters(num2, vector, targetWorldLocation, gameObject, gameObject2, targetTransform);
            }
            else
            {
                projectileView.InitWithoutBullet(num2, vector, targetWorldLocation, targetTransform);
            }
            this.activeProjectiles.Add(projectileView);
            if (!isOnGround && !string.IsNullOrEmpty(projectileType.GroundBulletAssetName))
            {
                this.SpawnProjectile(bullet, true);
            }
            return(projectileView);
        }