Example #1
0
    public void Update()
    {
        if (projectiles.Count <= 0)         // If nobodys shooting, dont bother getting/setting particles
        {
            return;
        }

        numAlive = pS.GetParticles(particles);

        for (int i = 0; i < projectiles.Count; i++)
        {
            Projectile proj = projectiles[i];

            // TODO: Also do positional hit detection for situations where a projectile slips into a unit without raycast hitting the outer shell (ie rotation)
            // Raycast according to movement path
            RaycastHit hit;
            if (Physics.Raycast(proj.position, proj.direction, out hit, proj.GetSpeed() * Time.deltaTime, mask))
            {
                int  projTeam = proj.GetFrom().Team;
                Unit unit     = null;
                bool hitSelf  = false;
                if (hit.collider.transform.parent)                 // Is this a unit?
                {
                    unit = hit.collider.transform.parent.GetComponent <Unit>();
                    if (unit)                       // Is this a unit?
                    {
                        if (unit != proj.GetFrom()) // If we hit a unit and its not us, damage it
                        {
                            Status status = proj.GetStatus();
                            if (status != null)
                            {
                                if (status.statusType == StatusType.SuperlaserMark)
                                {
                                    status.SetTimeLeft(proj.GetDamage() < gameRules.ABLY_superlaserDmgByStacks[1] ? proj.GetDamage() * SL_turretMult : proj.GetDamage() * SL_superlaserMult);                                     // Store damage in timeLeft field of status
                                }
                                unit.AddStatus(status);
                            }

                            // If we hit an ally, do reduced damage because it was an accidental hit
                            bool doFullDamage = DamageUtils.IgnoresFriendlyFire(proj.GetDamageType()) || unit.Team != projTeam;

                            DamageResult result = unit.Damage(doFullDamage ? proj.GetDamage() : proj.GetDamage() * gameRules.DMG_ffDamageMult, proj.CalcRange(), proj.GetDamageType());

                            if (result.lastHit && proj.GetFrom())
                            {
                                proj.GetFrom().AddKill(unit);
                            }
                        }
                        else
                        {
                            // Ignore this collision
                            hitSelf = true;
                        }
                    }
                }

                // Don't do anything if we are passing through the unit that fired us
                if (!hitSelf)
                {
                    proj.position         = hit.point - proj.direction * gameRules.PRJ_hitOffset;             // Move to contact point
                    particles[i].position = proj.position;

                    particles[i].remainingLifetime = 0;     // Destroy particle
                    toDelete.Add(proj);                     // Destroy projectile

                    Vector3 direction = ((-proj.direction + hit.normal) / 2).normalized;

                    if (unit)
                    {
                        if (unit.GetShields().x > 0)                         // Shielded
                        {
                            vfx.SpawnEffect(VFXType.Hit_Absorbed, proj.position, direction, projTeam);
                        }
                        else                         // Normal hit
                        {
                            vfx.SpawnEffect(VFXType.Hit_Normal, proj.position, direction, projTeam);
                        }
                    }
                    else                     // Terrain
                    {
                        vfx.SpawnEffect(VFXType.Hit_Normal, proj.position, direction, projTeam);
                    }
                    continue;
                }
            }            //if Raycast

            proj.UpdateTimeAlive(Time.deltaTime);
            if (proj.GetTimeAlive() > gameRules.PRJ_maxTimeAlive)
            {
                particles[i].remainingLifetime = 0; // Destroy particle
                toDelete.Add(proj);                 // Destroy projectile
            }

            proj.position += proj.direction * proj.GetSpeed() * Time.deltaTime; // Update projectile position

            particles[i].position = proj.position;                              // Sync particle with projectile
            particles[i].velocity = proj.direction;

            //Debug.DrawRay(proj.position, proj.direction, Color.red);
        }        //for

        for (int i = 0; i < toDelete.Count; i++)
        {
            //Instantiate(test, toDelete[i].position, Quaternion.identity);
            projectiles.Remove(toDelete[i]);
        }
        toDelete.Clear();

        //newProjectilesThisFrame = 0;
        pS.SetParticles(particles, numAlive);
    }     //Update()
Example #2
0
    // Called immediately after a hitscan is spawned
    float Raycast(Hitscan scan)
    {
        // Raycast according to start position, direction, and range
        RaycastHit hit;

        if (Physics.Raycast(scan.startPosition, scan.direction, out hit, scan.GetRange(), mask))
        {
            int  scanTeam = scan.GetFrom().Team;
            Unit unit     = null;
            bool hitSelf  = false;
            if (hit.collider.transform.parent)             // Is this a unit?
            {
                unit = hit.collider.transform.parent.GetComponent <Unit>();
                if (unit)                       // Is this a unit?
                {
                    if (unit != scan.GetFrom()) // If we hit a unit and its not us, damage it
                    {
                        Status status = scan.GetStatus();
                        if (status != null)
                        {
                            if (status.statusType == StatusType.SuperlaserMark)
                            {
                                status.SetTimeLeft(scan.GetDamage() < gameRules.ABLY_superlaserDmgByStacks[1] ? scan.GetDamage() * SL_turretMult : scan.GetDamage() * SL_superlaserMult);                                 // Store damage in timeLeft field of status
                            }
                            unit.AddStatus(status);
                        }

                        float actualRange = (hit.point - scan.startPosition).magnitude;
                        // If we hit an ally, do reduced damage because it was an accidental hit
                        bool doFullDamage = DamageUtils.IgnoresFriendlyFire(scan.GetDamageType()) || unit.Team != scanTeam;

                        DamageResult result = unit.Damage(doFullDamage ? scan.GetDamage() : scan.GetDamage() * gameRules.DMG_ffDamageMult, actualRange, scan.GetDamageType());

                        if (result.lastHit && scan.GetFrom())
                        {
                            scan.GetFrom().AddKill(unit);
                        }
                    }
                    else
                    {
                        // Ignore this collision
                        hitSelf = true;                         // TODO: Adapt friendly fire code for raycasting here
                    }
                }
            }

            Vector3 endPosition = (hit.point - scan.direction * gameRules.PRJ_hitOffset);

            // Don't do anything if we are passing through the unit that fired us
            if (!hitSelf)
            {
                if (unit)
                {
                    if (unit.GetShields().x > 0)                     // Shielded
                    {
                        vfx.SpawnEffect(VFXType.Hit_Absorbed, endPosition, -scan.direction, scanTeam);
                    }
                    else                     // Normal hit
                    {
                        vfx.SpawnEffect(VFXType.Hit_Normal, endPosition, -scan.direction, scanTeam);
                    }
                }
                else                 // Terrain
                {
                    vfx.SpawnEffect(VFXType.Hit_Normal, endPosition, -scan.direction, scanTeam);
                }
                return((scan.startPosition - endPosition).magnitude); // Return actual length of hitscan
            }
        }                                                             //if Raycast
        return(scan.GetRange());
    }