예제 #1
0
    public override void Fire(Transform weaponTrans, Vector3 direction, int sortingLayer, out float recoil)
    {
        lastFire_ = Time.time;
        recoil    = 0.0f;
        GameManager.Instance.PlayerScript.HolyTalk();
        var         pos    = GameManager.Instance.PlayerTrans.position;
        const float Radius = 5.0f;

        GameManager.Instance.MakeFlash(pos, Radius * 5f);
        GameManager.Instance.MakePoof(pos, 1, Radius * 1f);
        GameManager.Instance.ShakeCamera(1.0f);
        AudioManager.Instance.PlayClip(AudioManager.Instance.PlayerAudioSource, FireAudio, volumeScale: 1.0f);

        int aliveCount = BlackboardScript.GetEnemies(pos, Radius);

        for (int i = 0; i < aliveCount; ++i)
        {
            int       idx      = BlackboardScript.Matches[i].Idx;
            ActorBase enemy    = BlackboardScript.Enemies[idx];
            var       dir      = enemy.transform.position - pos;
            float     distance = dir.magnitude + 0.0001f;
            dir /= distance;
            dir.Normalize();
            var force = (Radius - distance) * dir * 0.25f;
            enemy.AddForce(force);
            enemy.SetSlowmotion();
        }
    }
예제 #2
0
    // TODO PE: NOT EXPLOSION! SOMETHING COOL!
    IEnumerator ExplodeCo()
    {
        isExploding_ = true;

        while (true)
        {
            var pos = trans_.position;

            GameManager.Instance.MakeFlash(pos, new Color(0.4f, 0.4f, 0.2f), Radius * 1.5f);

            float force = 0.1f;

            int aliveCount = BlackboardScript.GetEnemies(pos, Radius);
            for (int i = 0; i < aliveCount; ++i)
            {
                int       idx   = BlackboardScript.Matches[i].Idx;
                ActorBase enemy = BlackboardScript.Enemies[idx];
                enemy.SetSlowmotion();
//                enemy.AddForce((enemy.transform.position - pos) * force);
            }

            // Kill player if very close, else just push
            float playerDist = BlackboardScript.DistanceToPlayer(pos);
            if (playerDist < Radius * 0.2f)
            {
                GameManager.Instance.PlayerScript.KillPlayer();
            }
            else if (playerDist < 1.0f)
            {
                GameManager.Instance.PlayerScript.AddForce((GameManager.Instance.PlayerTrans.position - pos) * 0.25f);
            }

            yield return(new WaitForSeconds(0.4f));
        }
    }
예제 #3
0
    public static int Swing(Vector3 where, float damage, float radius, AudioClip clipHit, AudioClip clipMiss, out float recoil)
    {
        recoil = -0.2f;

        ProjectileManager.Instance.DeflectSource = where;
        ProjectileManager.Instance.DoDeflect     = true;
        ProjectileManager.Instance.DeflectRadius = radius;

        int aliveCount = BlackboardScript.GetEnemies(where, radius);
        var clip       = aliveCount == 0 ? clipMiss : clipHit;

        AudioManager.Instance.PlayClipWithRandomPitch(AudioManager.Instance.PlayerAudioSource, clip);
        for (int i = 0; i < aliveCount; ++i)
        {
            int       idx   = BlackboardScript.Matches[i].Idx;
            ActorBase enemy = BlackboardScript.Enemies[idx];
            enemy.SetSlowmotion();
            enemy.ApplyDamage(damage, enemy.transform.position - where, 1.0f, true);
        }
        return(aliveCount);
    }
예제 #4
0
파일: ActorBase.cs 프로젝트: zimpzon/Orcs
    IEnumerator ExplodeCo(float delay)
    {
        float explodeTime = Time.time + delay;
        float flashOffset = UnityEngine.Random.value;

        while (Time.time < explodeTime)
        {
            material_.SetFloat(flashParamId_, 0.6f + (Mathf.Sin(((Time.time + flashOffset) * 10) + 1.0f) * 0.5f) * 0.25f);
            yield return(null);
        }

        const float ExplodeRadius = 3.0f;

        AudioManager.Instance.PlayClipWithRandomPitch(AudioManager.Instance.MiscAudioSource, AudioManager.Instance.AudioData.LivingBombExplode);
        GameManager.Instance.MakeCircle(transform_.position, ExplodeRadius);
        GameManager.Instance.MakePoof(transform_.position, 2, ExplodeRadius * 0.2f);
        GameManager.Instance.ShakeCamera(0.4f);

        int  aliveCount = BlackboardScript.GetEnemies(transform_.position, ExplodeRadius);
        bool isFirstHit = true;

        for (int i = 0; i < aliveCount; ++i)
        {
            int       idx   = BlackboardScript.Matches[i].Idx;
            ActorBase enemy = BlackboardScript.Enemies[idx];
            if (enemy != this)
            {
                enemy.OnLivingBombHit(livingBombDamage_ * 0.9f, isFirstHit);
                isFirstHit = false;
            }
        }

        if (BlackboardScript.DistanceToPlayer(transform_.position) < ExplodeRadius * 0.5f)
        {
            GameManager.Instance.PlayerScript.KillPlayer();
        }

        ApplyDamage(livingBombDamage_, RndUtil.RandomInsideUnitCircle().normalized, 0.25f, true);
    }
예제 #5
0
    IEnumerator ThrowCo(Vector3 from, Vector3 to)
    {
        shadowRenderer_.enabled = false;
        var fuseEmission = fuseParticles_.emission;

        fuseEmission.enabled = true;

        float length    = (to - from).magnitude;
        float force     = Mathf.Min(5.0f, length);
        float velocityY = 1.0f * force;
        float downForce = -25.0f;
        float speed     = 5.0f * force;

        float   fuseT0  = Time.time;
        float   fuseT1  = fuseT0 + FuseTime;
        Vector3 dir     = (to - from).normalized;
        Vector3 pos     = from;
        float   offsetY = 0;

        audioSource_.clip   = AudioManager.Instance.AudioData.BombFuseBurn;
        audioSource_.volume = 0.5f * AudioManager.Instance.MasterVolume;
        audioSource_.Play();

        while (Time.time < fuseT1)
        {
            float delta = Time.deltaTime;

            Vector3 showPos = pos;
            showPos.y                 += offsetY;
            trans_.position            = showPos;
            bombRenderer_.sortingOrder = (Mathf.RoundToInt(trans_.position.y * 100f));
            bombMaterial_.SetFloat(flashParamId_, (Mathf.Sin((Time.time * 15) + 1.0f) * 0.5f) * 0.75f);

            offsetY   += velocityY * delta;
            velocityY += downForce * delta;
            if (offsetY <= 0)
            {
                shadowRenderer_.enabled = true;
                velocityY = -velocityY * 0.5f;
            }

            pos   += dir * speed * Time.deltaTime;
            speed *= 1.0f - (5.0f * delta);

            yield return(null);
        }

        fuseEmission.enabled = false;

        audioSource_.clip   = AudioManager.Instance.AudioData.BombExplode;
        audioSource_.volume = 1.0f * AudioManager.Instance.MasterVolume;
        audioSource_.Play();
        GameManager.Instance.MakeFlash(pos, Radius * 1.5f);
        GameManager.Instance.MakePoof(pos, 6, Radius * 1.5f);
        GameManager.Instance.ShakeCamera(4.0f);

        int deadCount = BlackboardScript.GetDeadEnemies(pos, Radius);

        for (int i = 0; i < deadCount; ++i)
        {
            int       idx   = BlackboardScript.Matches[i].Idx;
            ActorBase enemy = BlackboardScript.DeadEnemies[idx];
            enemy.AddForce((enemy.transform.position - pos) * 0.25f);
//            enemy.Explode(2.0f + Random.value * 2);
        }

        int aliveCount = BlackboardScript.GetEnemies(pos, Radius);

        for (int i = 0; i < aliveCount; ++i)
        {
            int       idx   = BlackboardScript.Matches[i].Idx;
            ActorBase enemy = BlackboardScript.Enemies[idx];
            enemy.ApplyDamage(Damage, enemy.transform.position - pos, 1.0f, true);
        }

        for (int i = 0; i < 10; ++i)
        {
            Vector2 rnd      = RndUtil.RandomInsideUnitCircle() * Radius * 0.5f;
            Vector3 flamePos = pos;
            flamePos.x += rnd.x;
            flamePos.y += rnd.y;
            GameManager.Instance.EmitFlame(flamePos, Random.value + 0.5f);
            yield return(null);
        }

        // Kill player if very close, else just push
        float playerDist = BlackboardScript.DistanceToPlayer(pos);

        if (playerDist < 3.0f)
        {
            GameManager.Instance.PlayerScript.AddForce((GameManager.Instance.PlayerTrans.position - pos) * 0.1f);
        }

        Hide();
    }
예제 #6
0
    void TickBasicProjectiles(float delta)
    {
        removeListBasic_.Clear();

        float time = Time.time;

        for (int i = 0; i < basicProjectiles_.Count; ++i)
        {
            var p = basicProjectiles_[i];
            if (p.IsLastFrame)
            {
                if (p.CurrentTarget != null && p.StickySoundRepeater != null)
                {
                    p.StickySoundRepeater.StopClip();
                }

                removeListBasic_.Add(p);
            }
            else
            {
                bool outOfTime     = p.DieTime > 0.0f && time >= p.DieTime;
                bool endOfDistance = p.DistanceTraveled >= p.MaxDistance;
                if (!p.IsLastFrame && (endOfDistance || outOfTime))
                {
                    p.SpriteInfo.Renderer.color = Color.white;
                    p.IsLastFrame = true;
                }

                if (p.IsFirstFrame)
                {
                    p.IsFirstFrame = false;
                }

                float   frameSpeed = p.Speed * delta * Timers.EnemyTimer;
                Vector3 movement   = p.Direction * frameSpeed;

                if (p.ReflectOnEdges)
                {
                    float newX = p.Position.x + movement.x;
                    float newY = p.Position.y + movement.y;
                    if (newX < -arenaBoundsX_ || newX > arenaBoundsX_)
                    {
                        movement    = new Vector3(-movement.x, movement.y, 0.0f);
                        p.Direction = new Vector3(-p.Direction.x, p.Direction.y, 0.0f);
                    }

                    if (newY < -arenaBoundsY_ || newY > arenaBoundsY_)
                    {
                        movement    = new Vector3(movement.x, -movement.y, 0.0f);
                        p.Direction = new Vector3(p.Direction.x, -p.Direction.y, 0.0f);
                    }
                }

                p.Position += movement;

                if (p.StickToTarget && p.CurrentTarget != null)
                {
                    if (p.CurrentTarget.Hp <= 0)
                    {
                        // Target we are stuck to died. Scan for a new one close by or continue moving if nothing found.
                        if (p.StickySoundRepeater != null)
                        {
                            p.StickySoundRepeater.StopClip();
                        }

                        p.CurrentTarget = null;
                        int idxClosest = BlackboardScript.GetIdxClosestEnemy(p.Position, 1.5f, 5);
                        if (idxClosest >= 0)
                        {
                            var closeEnemy = BlackboardScript.Enemies[idxClosest];
                            p.Direction = (closeEnemy.transform.position - p.Position).normalized;
                        }
                        else
                        {
                            // Maintain direction
                        }
                    }
                    else
                    {
                        // Keep sticking to target at specific offset
                        p.Position = p.CurrentTarget.transform.position + p.StickOffset;
                        p.CurrentTarget.SetSlowmotion(0.5f);
                        Vector3 damageDirection = (p.StickOffset * -1).normalized;
                        p.CurrentTarget.ApplyDamage(p.Damage, damageDirection, 0.25f, false);
                        GameManager.Instance.TriggerBlood(p.Position + damageDirection * 0.2f, 8.0f, floorBloodRnd: 0.1f);
                        GameManager.Instance.ShakeCamera(0.1f);
                    }
                }
                else if (p.Type == ProjectileType.HarmsEnemies)
                {
                    // TODO PE: This should be changed to colliders. Might enable walls too?
                    // Find enemies hit by projectile
                    if (BlackboardScript.GetEnemies(p.Position, p.Radius, 1) > 0)
                    {
                        int       matchIdx = BlackboardScript.Matches[0].Idx;
                        ActorBase enemy    = BlackboardScript.Enemies[matchIdx];
                        if (p.StickToTarget)
                        {
                            // Begin sticking to target
                            p.CurrentTarget = enemy;
                            p.StickOffset   = (p.SpriteInfo.Transform.position - enemy.transform.position) * 0.9f;

                            if (p.StickySoundRepeater != null)
                            {
                                p.StickySoundRepeater.StartClipWithRandomPitch(p.CollisionSound);
                            }
                            else
                            {
                                AudioManager.Instance.PlayClipWithRandomPitch(AudioManager.Instance.MiscAudioSource, p.CollisionSound);
                            }
                        }

                        float damage = Basic.CalcDamage(p);
                        if (p.CustomCollisionResponse != null)
                        {
                            p.CustomCollisionResponse(p, enemy, damage, p.Direction);
                        }
                        else
                        {
                            GameManager.Instance.DamageEnemy(enemy, damage, p.Direction, p.Force);
                        }

                        if (p.DieOnCollision)
                        {
                            removeListBasic_.Add(p);
                        }

                        if (p.ReflectOnCollision)
                        {
                            if (UnityEngine.Random.value < 0.5f)
                            {
                                p.Direction = Vector3.Reflect(p.Direction, Vector3.up);
                            }
                            else
                            {
                                p.Direction = Vector3.Reflect(p.Direction, Vector3.right);
                            }
                        }
                    }
                }
                else if (p.Type == ProjectileType.HarmsPlayer && DoDeflect)
                {
                    Vector3 dir      = p.Position - DeflectSource;
                    float   distance = dir.magnitude;
                    if (distance <= DeflectRadius)
                    {
                        // Projectile deflected
                        dir.Normalize();
                        p.Direction = Vector3.Reflect(p.Direction, dir) * 3;
                        float rot_z = Mathf.Atan2(p.Direction.y, p.Direction.x) * Mathf.Rad2Deg;
                        p.SpriteInfo.Transform.rotation = Quaternion.Euler(0f, 0f, rot_z);
                        p.Color = new Color(0.8f, 1.0f, 1.0f);
                        p.SpriteInfo.Renderer.color = p.Color;
                        p.Type = ProjectileType.HarmsEnemies;
                        p.SpriteInfo.Transform.gameObject.layer = LayerFromProjectileType(p.Type);
                    }
                }

                if (p.RotationSpeed > 0.0f)
                {
                    p.SpriteInfo.Transform.rotation = Quaternion.Euler(0.0f, 0.0f, Time.time * (p.CurrentTarget == null ? p.RotationSpeed : p.RotationSpeedWhenStuck));
                }

                if (p.SwayFactor > 0.0f)
                {
                    Vector3 perpendicular = new Vector3(-p.Direction.y, p.Direction.x, 0).normalized;
                    p.SpriteInfo.Transform.position = p.Position + (Mathf.Sin(Time.time * 10) * p.SwayFactor * perpendicular);
                }
                else
                {
                    p.SpriteInfo.Transform.position = p.Position;
                }

                p.DistanceTraveled += frameSpeed;
            }
        }

        DoDeflect = false;

        for (int i = 0; i < removeListBasic_.Count; ++i)
        {
            ProjectileCache.Instance.ReturnSprite(removeListBasic_[i].SpriteInfo);
            removeListBasic_[i].Reset();
            projectileCache_.ReturnObject(removeListBasic_[i]);
            basicProjectiles_.Remove(removeListBasic_[i]);
        }
    }
예제 #7
0
    public override void Fire(Transform weaponTrans, Vector3 direction, int sortingLayer, out float recoil)
    {
        lastFire_ = Time.time;
        recoil    = 0.1f;

        Color color = new Color(0.8f, 0.6f, 0.1f);

        Vector3 worldMuzzle = weaponTrans.TransformPoint(Muzzle);

        worldMuzzle += -direction * 0.2f; // Start a little behind muzzle because its very unfun missing an enemy that is too close

        GameManager.Instance.MakeFlash(worldMuzzle);
        GameManager.Instance.MakePoof(worldMuzzle, 2);
        AudioManager.Instance.PlayClipWithRandomPitch(AudioManager.Instance.PlayerAudioSource, FireAudio);

        ProjectileManager.Basic basic = ProjectileManager.Instance.GetProjectile();
        basic.SpriteInfo = ProjectileCache.Instance.GetSprite();

        basic.Speed       = 100.0f;
        basic.Damage      = 450.0f;
        basic.MaxDistance = 80.0f;

        basic.Radius = 0.1f;
        Vector3 scale = basic.SpriteInfo.Transform.localScale;

        scale.x = 1.0f;
        scale.y = 1.0f;
        scale.z = 1.0f;
        basic.SpriteInfo.Transform.localScale = scale;

        basic.Position = worldMuzzle;
        basic.SpriteInfo.Renderer.sprite         = BulletSprite;
        basic.SpriteInfo.Renderer.sortingLayerID = sortingLayer;
        basic.Direction = direction;
        basic.Color     = color;
        basic.DieTime   = 0.0f;
        basic.Type      = ProjectileManager.ProjectileType.HarmsNothing;
        float rot_z = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;

        basic.SpriteInfo.Transform.rotation = Quaternion.Euler(0f, 0f, rot_z);

        ProjectileManager.Instance.Fire(basic);

        // TODO PE: Spherecast will return sorted list
        // Sniper immediately hits the full line. Since we sort by distance we have to allow a large number of hits or we might not include closest in match list.
        float damage = basic.Damage;
        int   count  = BlackboardScript.GetEnemies(worldMuzzle, worldMuzzle + direction * 1000, 50);
        // Copy matches to local array. Sort it by distance.
        List <BlackboardScript.HitMatch> matches = new List <BlackboardScript.HitMatch>(BlackboardScript.Matches.Take(count));
        var ordered = matches.OrderBy(hit => hit.Distance).Take(5).ToList();

        for (int i = 0; i < ordered.Count; ++i)
        {
            BlackboardScript.HitMatch match = ordered[i];
            ActorBase enemy       = BlackboardScript.Enemies[match.Idx];
            float     enemyDamage = Mathf.Min(enemy.Hp, damage);
            GameManager.Instance.DamageEnemy(enemy, enemyDamage, direction, 1.0f, match.IsHeadshot);
            damage -= enemyDamage;
            if (damage <= 0)
            {
                break;
            }
        }
    }