예제 #1
0
        public override bool Process()
        {
            if (NetworkManager.IsClient)
            {
                return(false);
            }

            if (TicsSinceLastDrop < 0 || TicsSinceLastDrop > 6)
            {
                TicsSinceLastDrop = 0;

                // spawn random blizzard projectile in 4x4 grid (center at 1,1)
                float rndX = UnityEngine.Random.Range(-1, 3) + TargetX;
                float rndY = UnityEngine.Random.Range(-1, 3) + TargetY;
                if (rndX >= 0 && rndY >= 0 &&
                    rndX < MapLogic.Instance.Width &&
                    rndY < MapLogic.Instance.Height)
                {
                    Server.SpawnProjectileDirectional(AllodsProjectile.Blizzard, Spell.User, rndX + 0.5f, rndY + 0.5f, 4f, rndX + 0.5f, rndY + 0.5f, 0f, 3f, proj =>
                    {
                        Server.SpawnProjectileSimple(AllodsProjectile.Blizzard, Spell.User, rndX + 0.5f, rndY + 0.5f, 0f, 1f, 1f, 0, 7);
                        // find something to damage in this cell
                        MapNode node = MapLogic.Instance.Nodes[proj.X, proj.Y];
                        for (int i = 0; i < node.Objects.Count; i++)
                        {
                            MapObject mo = node.Objects[i];
                            if (!(mo is IVulnerable))
                            {
                                continue;
                            }
                            IVulnerable vul = (IVulnerable)mo;
                            int dmg         = Spell.GetDamage();
                            vul.TakeDamage(DamageFlags.Water | (Spell.Item == null?DamageFlags.AllowExp:0), Spell.User, dmg);
                        }
                    });
                }
            }

            TicsSinceLastDrop++;
            TicsTotal++;

            return(TicsTotal < MapLogic.TICRATE * Spell.GetDuration());
        }
예제 #2
0
        public override bool Process()
        {
            if (NetworkManager.IsClient)
            {
                return(false);
            }

            // 5x5, but remove corners
            for (int y = TargetY - 2; y <= TargetY + 2; y++)
            {
                for (int x = TargetX - 2; x <= TargetX + 2; x++)
                {
                    // check for corner tiles :)
                    if ((x == TargetX - 2 || x == TargetX + 2) && (y == TargetY - 2 || y == TargetY + 2))
                    {
                        continue;
                    }
                    if (x < 0 || y < 0 ||
                        x >= MapLogic.Instance.Width ||
                        y >= MapLogic.Instance.Height)
                    {
                        continue;
                    }

                    // check if there are FIRE effects on this cell, don't spawn fog
                    bool spawnblocked = false;
                    foreach (MapObject mo in MapLogic.Instance.Nodes[x, y].Objects)
                    {
                        if (!(mo is MapProjectile))
                        {
                            continue;
                        }

                        MapProjectile mp = (MapProjectile)mo;
                        if (mp.Class == null || mp.Class.ID != (int)AllodsProjectile.PoisonCloud)
                        {
                            continue;
                        }

                        // don't remove if on edge of fire wall
                        if (new Vector2(mp.ProjectileX - x + 0.5f, mp.ProjectileY - y + 0.5f).magnitude > 0.8f)
                        {
                            continue;
                        }

                        spawnblocked = true;
                        break;
                    }

                    if (spawnblocked)
                    {
                        continue;
                    }

                    Server.SpawnProjectileEOT(AllodsProjectile.PoisonCloud, Spell.User, x + 0.5f, y + 0.5f, 0, (int)(MapLogic.TICRATE * Spell.GetDuration()), 40, 0, 0, 16, proj =>
                    {
                        DamageFlags spdf = SphereToDamageFlags(Spell);
                        // get projectile cells
                        int axFrom = Mathf.Max(0, Mathf.FloorToInt(proj.ProjectileX));
                        int axTo   = Mathf.Min(MapLogic.Instance.Width - 1, Mathf.CeilToInt(proj.ProjectileX));
                        int ayFrom = Mathf.Max(0, Mathf.FloorToInt(proj.ProjectileY));
                        int ayTo   = Mathf.Min(MapLogic.Instance.Height - 1, Mathf.CeilToInt(proj.ProjectileY));
                        for (int py = ayFrom; py <= ayTo; py++)
                        {
                            for (int px = axFrom; px <= axTo; px++)
                            {
                                // check how much projectile is on this cell
                                float pdst = 1f - Mathf.Min(1f, new Vector2(px + 0.5f - proj.ProjectileX, py + 0.5f - proj.ProjectileY).magnitude);
                                // 0..1 effect power
                                MapNode node = MapLogic.Instance.Nodes[px, py];
                                for (int i = 0; i < node.Objects.Count; i++)
                                {
                                    MapObject mo = node.Objects[i];
                                    if (!(mo is MapUnit))
                                    {
                                        continue;
                                    }
                                    MapUnit mov = (MapUnit)mo;
                                    int dmg     = (int)(Spell.GetIndirectPower() * pdst);
                                    if (dmg <= 0)
                                    {
                                        continue;                                                                       // don't add null effects
                                    }
                                    SpellEffects.Effect eff = new SpellEffects.Poison(this, dmg, MapLogic.TICRATE * 8); // originally 8 seconds
                                    mov.AddSpellEffects(eff);
                                }
                            }
                        }
                    });
                }
            }

            return(false);
        }
예제 #3
0
        public override bool Process()
        {
            if (TargetUnit == null)
            {
                return(false);
            }

            SpellEffects.Effect eff = new SpellEffects.ProtectionWater((int)(MapLogic.TICRATE * Spell.GetDuration()), Spell.GetProtection());
            TargetUnit.AddSpellEffects(eff);
            return(false);
        }
예제 #4
0
        public override bool Process()
        {
            if (NetworkManager.IsClient)
            {
                return(false);
            }

            // we need to spawn several EoT projectiles at the destination
            // 5x2

            float   sourceX   = Spell.User.X + Spell.User.FracX + Spell.User.Width / 2f;
            float   sourceY   = Spell.User.Y + Spell.User.FracY + Spell.User.Height / 2f;
            Vector2 direction = new Vector2(TargetX + 0.5f - sourceX, TargetY + 0.5f - sourceY);
            float   angle     = Mathf.Atan2(direction.y, direction.x) - (Mathf.PI / 180) * 90;

            for (int x = -2; x <= 2; x++)
            {
                for (int y = 0; y < 2; y++)
                {
                    // rotate x and y
                    float fx = x;
                    float fy = y;
                    float rx = Mathf.Cos(angle) * x - Mathf.Sin(angle) * y;
                    float ry = Mathf.Cos(angle) * y + Mathf.Sin(angle) * x;
                    Server.SpawnProjectileEOT(AllodsProjectile.FireWall, Spell.User, TargetX + rx + 0.5f, TargetY + ry + 0.5f, 0, (int)(MapLogic.TICRATE * Spell.GetDuration()), 10, 4, 4, 16, proj =>
                    {
                        DamageFlags spdf = SphereToDamageFlags(Spell);
                        if (Spell.Item == null)
                        {
                            spdf |= DamageFlags.AllowExp;
                        }
                        // get projectile cells
                        int axFrom = Mathf.Max(0, Mathf.FloorToInt(proj.ProjectileX));
                        int axTo   = Mathf.Min(MapLogic.Instance.Width - 1, Mathf.CeilToInt(proj.ProjectileX));
                        int ayFrom = Mathf.Max(0, Mathf.FloorToInt(proj.ProjectileY));
                        int ayTo   = Mathf.Min(MapLogic.Instance.Height - 1, Mathf.CeilToInt(proj.ProjectileY));
                        for (int py = ayFrom; py <= ayTo; py++)
                        {
                            for (int px = axFrom; px <= axTo; px++)
                            {
                                // check how much projectile is on this cell
                                float pdst = 1f - Mathf.Min(1f, new Vector2(px + 0.5f - proj.ProjectileX, py + 0.5f - proj.ProjectileY).magnitude);
                                // 0..1 effect power
                                MapNode node = MapLogic.Instance.Nodes[px, py];
                                for (int i = 0; i < node.Objects.Count; i++)
                                {
                                    MapObject mo = node.Objects[i];
                                    if (!(mo is IVulnerable))
                                    {
                                        // aoe fire effect: remove cloud effects if any
                                        if (!(mo is MapProjectile))
                                        {
                                            continue;
                                        }

                                        MapProjectile mp = (MapProjectile)mo;
                                        if (mp.Class == null || mp.Class.ID != (int)AllodsProjectile.PoisonCloud)
                                        {
                                            continue;
                                        }

                                        // don't remove if on edge of fire wall
                                        if (new Vector2(mp.ProjectileX - proj.ProjectileX, mp.ProjectileY - proj.ProjectileY).magnitude > 0.8f)
                                        {
                                            continue;
                                        }

                                        mp.Dispose();
                                        i--;
                                        continue;
                                    }
                                    else
                                    {
                                        IVulnerable mov = (IVulnerable)mo;
                                        int dmg         = (int)(Spell.GetDamage() * pdst);
                                        mov.TakeDamage(spdf, Spell.User, dmg);
                                    }
                                }
                            }
                        }
                    });
                }
            }

            return(false);
        }
예제 #5
0
        public override bool Process()
        {
            if (NetworkManager.IsClient)
            {
                return(false);
            }

            // 11x11, but remove corners
            for (int y = TargetY - 5; y <= TargetY + 5; y++)
            {
                for (int x = TargetX - 5; x <= TargetX + 5; x++)
                {
                    // check for corner tiles :)
                    if (new Vector2(x - TargetX, y - TargetY).magnitude > 5.5f)
                    {
                        continue;
                    }
                    if (x < 0 || y < 0 ||
                        x >= MapLogic.Instance.Width ||
                        y >= MapLogic.Instance.Height)
                    {
                        continue;
                    }

                    // remove light effects
                    MapNode node = MapLogic.Instance.Nodes[x, y];
                    for (int i = 0; i < node.Objects.Count; i++)
                    {
                        MapObject mo = node.Objects[i];
                        if (mo is MapProjectile &&
                            ((((MapProjectile)mo).ClassID == AllodsProjectile.SpecDarkness) || (((MapProjectile)mo).ClassID == AllodsProjectile.SpecLight)))
                        {
                            mo.Dispose();
                            i--;
                            continue;
                        }
                    }

                    float power      = Spell.GetScanRange();
                    int   lightlevel = (int)(-(power * 32));

                    Server.SpawnProjectileEOT(AllodsProjectile.SpecDarkness, Spell.User, x + 0.5f, y + 0.5f, 0, (int)(MapLogic.TICRATE * Spell.GetDuration()), MapLogic.TICRATE / 2, 0, 0, 16, proj =>
                    {
                        MapNode pnode = MapLogic.Instance.Nodes[proj.X, proj.Y];
                        for (int i = 0; i < pnode.Objects.Count; i++)
                        {
                            MapObject mo = pnode.Objects[i];
                            if (!(mo is MapUnit))
                            {
                                continue;
                            }

                            MapUnit mov = (MapUnit)mo;
                            // don't affect AI units
                            if (mov.Player == null || mov.Player.DoFullAI)
                            {
                                continue;
                            }

                            SpellEffects.Effect eff = new SpellEffects.Darkness(MapLogic.TICRATE / 2, Spell.GetScanRange()); // 1 second
                            mov.AddSpellEffects(eff);
                        }
                    }, lightlevel);
                }
            }

            return(false);
        }