Beispiel #1
0
        public override void MonoTriggerEnter(GameObject gameObject, Collider2D coll)
        {
            if (coll.gameObject.Equals(GetOwnerData().GetBody()))
            {
                return;
            }

            Character ch = coll.gameObject.GetChar();

            ProjectileData d = GetProjectileData(gameObject);

            // if projectile was saved, it means special effects are to be applied
            if (d != null)
            {
                if (ch == null)
                {
                    Destroyable des = coll.gameObject.GetComponent <Destroyable>();

                    if (des == null)
                    {
                        ForceDestroyProjectile(d.proj);
                        return;
                    }

                    if (!Owner.CanAttack(des))
                    {
                        return;
                    }
                }
                else if (!Owner.CanAttack(ch))
                {
                    return;
                }

                // missile hit target
                if (d.target != null)
                {
                    if (coll.gameObject.Equals(d.target.GetData().GetBody()))
                    {
                        d.target = null;
                    }
                }

                if (d.ignore != null && d.ignore.Equals(coll.gameObject))
                {
                    return;
                }

                if (chainEffect && !d.chained)
                {
                    for (int i = 0; i < chainProjectilesCount; i++)
                    {
                        GameObject activeProjectile;

                        activeProjectile = CreateSkillProjectile("projectile_00", true, d.proj.transform);
                        if (activeProjectile != null)
                        {
                            Rigidbody2D rb = activeProjectile.GetComponent <Rigidbody2D>();

                            Vector3 nv = Quaternion.Euler(new Vector3(0, 0, Random.Range(-90, 90))) * d.rb.velocity.normalized;
                            rb.velocity = nv * force;

                            Object.Destroy(activeProjectile, GetProjectileLifetime(force));

                            if (SaveProjectiles())
                            {
                                ProjectileData data = new ProjectileData();
                                data.proj                = activeProjectile;
                                data.target              = null;
                                data.interpolTimer       = 0;
                                data.rb                  = rb;
                                data.penetratedTargets   = 0;
                                data.maxPenetrateTargets = chainPenetrations + 1;
                                data.chained             = true;
                                data.ignore              = coll.gameObject;

                                if (chainPenetrations > 0)
                                {
                                    data.hits = new GameObject[chainPenetrations + 1];
                                }

                                if (returnBack)
                                {
                                    data.waypoints.Push(activeProjectile.transform.position);
                                }

                                data.SaveHit(coll.gameObject);
                                data.penetratedTargets++;
                                projectiles.Add(data);
                                MonoUpdate(rb.gameObject, true);
                            }
                        }
                    }
                }

                if (d.maxPenetrateTargets > 0 && d.penetratedTargets > 0 && (penetrateChangeDamage < 0 || penetrateChangeDamage > 0))
                {
                    ApplyEffects(Owner, coll.gameObject, false, d.penetratedTargets);
                }
                else
                {
                    ApplyEffects(Owner, coll.gameObject);
                }

                bool destroy = false;

                if (maxPenetratedTargets > 0 && d.maxPenetrateTargets > 0)
                {
                    // check if penetrated too many
                    d.penetratedTargets++;
                    if (d.penetratedTargets >= d.maxPenetrateTargets)
                    {
                        destroy = true;
                    }

                    // find next target
                    if (!destroy && navigateChangeTargetAfterHit)
                    {
                        ProjectileHitAnimation(d.proj);

                        float angle = d.proj.transform.rotation.eulerAngles.z;
                        if (!navigateLookOnlyForward)
                        {
                            /*foreach (Collider2D hit in Physics2D.OverlapCircleAll(d.proj.transform.position, navigateAimArea))
                             * {
                             *      if (hit.gameObject.Equals(d.proj))
                             *              continue;
                             *
                             *      Character targetCh = hit.gameObject.GetChar();
                             *      if (targetCh == null || !Owner.CanAttack(targetCh) || hit.gameObject.Equals(coll.gameObject))
                             *              continue;
                             *
                             *      d.target = targetCh;
                             *      AdjustToTarget(d);
                             *      break;
                             * }*/

                            List <GameObject> candidates = new List <GameObject>();

                            foreach (Collider2D c in Physics2D.OverlapCircleAll(d.proj.transform.position, navigateAimArea))
                            {
                                if (c.gameObject.Equals(d.proj))
                                {
                                    continue;
                                }

                                if (d.HasHit(c.gameObject))
                                {
                                    continue;
                                }

                                if (!Utils.CanSee(c.gameObject, d.proj.transform.position))
                                {
                                    continue;
                                }

                                Character targetCh = c.gameObject.GetChar();
                                if (targetCh == null || !Owner.CanAttack(targetCh))
                                {
                                    continue;
                                }

                                candidates.Add(c.gameObject);
                            }

                            candidates.Sort((x, y) => (int)Utils.DistanceSqr(Owner.GetData().GetBody().transform.position, x.transform.position) - (int)Utils.DistanceSqr(Owner.GetData().GetBody().transform.position, y.transform.position));

                            foreach (GameObject c in candidates)
                            {
                                Character targetCh = c.GetChar();
                                if (targetCh == null || !Owner.CanAttack(targetCh))
                                {
                                    continue;
                                }

                                d.target = targetCh;
                                d.SaveHit(c.gameObject);
                                AdjustToTarget(d);
                                break;
                            }
                        }
                        else
                        {
                            Vector3 direction = new Vector3(d.rb.velocity.x, d.rb.velocity.y);
                            Vector3 perpend   = Utils.GetPerpendicularVector(d.proj.transform.position, direction + d.proj.transform.position);

                            List <GameObject> candidates = new List <GameObject>();

                            foreach (Collider2D c in Physics2D.OverlapAreaAll(d.proj.transform.position + perpend * navigateAimArea / 2f + direction.normalized * navigateAimArea, d.proj.transform.position + perpend * (-navigateAimArea / 2f)))
                            {
                                if (c.gameObject.Equals(d.proj))
                                {
                                    continue;
                                }

                                if (d.HasHit(c.gameObject))
                                {
                                    continue;
                                }

                                if (!Utils.CanSee(c.gameObject, d.proj.transform.position))
                                {
                                    continue;
                                }

                                candidates.Add(c.gameObject);
                                break;
                            }

                            candidates.Sort((x, y) => (int)Utils.DistanceSqr(Owner.GetData().GetBody().transform.position, x.transform.position) - (int)Utils.DistanceSqr(Owner.GetData().GetBody().transform.position, y.transform.position));

                            foreach (GameObject c in candidates)
                            {
                                Character targetCh = c.GetChar();
                                if (targetCh == null || !Owner.CanAttack(targetCh))
                                {
                                    continue;
                                }

                                d.target = targetCh;
                                d.SaveHit(c.gameObject);
                                AdjustToTarget(d);
                                break;
                            }
                        }
                    }
                }

                if (maxPenetratedTargets == 0 || destroy)
                {
                    if (returnBack)
                    {
                        returningBack = true;
                        AdjustToTarget(d);
                    }
                    else
                    {
                        if (explodeEffect)
                        {
                            GameObject explosion = CreateParticleEffect(explodeEffectName, false, gameObject.transform.position);
                            explosion.GetComponent <ParticleSystem>().Play();
                            Object.Destroy(explosion, 2f);
                        }

                        DestroyProjectile(gameObject);
                    }
                }
            }
            else
            {
                if (ch == null)
                {
                    Destroyable des = coll.gameObject.GetComponent <Destroyable>();
                    if (des != null && !Owner.CanAttack(des))
                    {
                        return;
                    }
                }
                else if (!Owner.CanAttack(ch))
                {
                    return;
                }

                ApplyEffects(Owner, coll.gameObject);
                DestroyProjectile(gameObject);
            }
        }
Beispiel #2
0
        public override void MonoUpdate(GameObject gameObject, bool fixedUpdate)
        {
            if (returningBack)
            {
                ProjectileData d = GetProjectileData(gameObject);
                if (d == null || d.proj == null)
                {
                    return;
                }

                if (d.lastUpdateTime + updateInterval <= Time.time)
                {
                    d.lastUpdateTime = Time.time;

                    if (!d.hasNextWaypoint)
                    {
                        AdjustToTarget(d);
                    }

                    if (d.hasNextWaypoint)
                    {
                        float dist = Utils.DistanceSqr(d.nextWaypoint, d.proj.transform.position);
                        if (dist < 2 * 2)
                        {
                            d.hasNextWaypoint = false;
                        }
                    }
                    else
                    {
                        returningBack = false;

                        if (explodeEffect)
                        {
                            GameObject explosion = CreateParticleEffect(explodeEffectName, false, gameObject.transform.position);
                            explosion.GetComponent <ParticleSystem>().Play();
                            Object.Destroy(explosion, 2f);
                        }

                        ForceDestroyProjectile(gameObject);
                        return;
                    }
                }
            }

            if (navigateToTarget)
            {
                //if (fixedUpdate)
                {
                    ProjectileData d = GetProjectileData(gameObject);
                    if (d == null || d.proj == null)
                    {
                        return;
                    }

                    if (d.lastUpdateTime + updateInterval <= Time.time)
                    {
                        d.lastUpdateTime = Time.time;

                        // find new target
                        if (d.target == null)
                        {
                            //if (d.lastChooseTarget + chooseTargetInterval < Time.time)
                            {
                                d.lastChooseTarget = Time.time;

                                if (!navigateLookOnlyForward)
                                {
                                    float angle = d.proj.transform.rotation.eulerAngles.z;

                                    List <GameObject> candidates = new List <GameObject>();

                                    foreach (Collider2D c in Physics2D.OverlapCircleAll(d.proj.transform.position, navigateAimArea))
                                    {
                                        if (c.gameObject.Equals(d.proj))
                                        {
                                            continue;
                                        }

                                        if (d.HasHit(c.gameObject))
                                        {
                                            continue;
                                        }

                                        if (!Utils.CanSee(c.gameObject, d.proj.transform.position))
                                        {
                                            continue;
                                        }

                                        Character targetCh = c.gameObject.GetChar();
                                        if (targetCh == null || !Owner.CanAttack(targetCh))
                                        {
                                            continue;
                                        }

                                        candidates.Add(c.gameObject);
                                    }

                                    candidates.Sort((x, y) => (int)Utils.DistanceSqr(Owner.GetData().GetBody().transform.position, x.transform.position) - (int)Utils.DistanceSqr(Owner.GetData().GetBody().transform.position, y.transform.position));

                                    foreach (GameObject c in candidates)
                                    {
                                        Character targetCh = c.GetChar();
                                        if (targetCh == null || !Owner.CanAttack(targetCh))
                                        {
                                            continue;
                                        }

                                        d.target = targetCh;
                                        d.SaveHit(c.gameObject);
                                        AdjustToTarget(d);
                                        break;
                                    }
                                }
                                else                                 // scan only forward targets
                                {
                                    float angle = d.proj.transform.rotation.eulerAngles.z;

                                    Vector3 direction = new Vector3(d.rb.velocity.x, d.rb.velocity.y);
                                    Vector3 perpend   = Utils.GetPerpendicularVector(d.proj.transform.position, direction + d.proj.transform.position);

                                    Debug.DrawRay(d.proj.transform.position, perpend * 10, Color.red, 1f);

                                    Debug.DrawLine(d.proj.transform.position, d.proj.transform.position + perpend * navigateAimArea / 2f + direction.normalized * navigateAimArea, Color.green, 1f);
                                    Debug.DrawLine(d.proj.transform.position, d.proj.transform.position + perpend * (-navigateAimArea / 2f), Color.blue, 1f);

                                    List <GameObject> candidates = new List <GameObject>();

                                    foreach (Collider2D c in Physics2D.OverlapAreaAll(d.proj.transform.position + perpend * navigateAimArea / 2f + direction.normalized * navigateAimArea, d.proj.transform.position + perpend * (-navigateAimArea / 2f)))
                                    {
                                        if (c.gameObject.Equals(d.proj))
                                        {
                                            continue;
                                        }

                                        if (d.HasHit(c.gameObject))
                                        {
                                            continue;
                                        }

                                        if (!Utils.CanSee(c.gameObject, d.proj.transform.position))
                                        {
                                            continue;
                                        }

                                        candidates.Add(c.gameObject);
                                    }

                                    candidates.Sort((x, y) => (int)Utils.DistanceSqr(Owner.GetData().GetBody().transform.position, x.transform.position) - (int)Utils.DistanceSqr(Owner.GetData().GetBody().transform.position, y.transform.position));

                                    foreach (GameObject c in candidates)
                                    {
                                        Character targetCh = c.GetChar();
                                        if (targetCh == null || !Owner.CanAttack(targetCh))
                                        {
                                            continue;
                                        }

                                        d.target = targetCh;
                                        d.SaveHit(c.gameObject);
                                        AdjustToTarget(d);
                                        break;
                                    }
                                }
                            }
                        }

                        if (d.target != null)
                        {
                            AdjustToTarget(d);
                        }
                    }
                }
            }
        }