Ejemplo n.º 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());
        }
Ejemplo n.º 2
0
        public override bool Process()
        {
            if (NetworkManager.IsClient)
            {
                return(false);
            }

            int ballDamage = 16;

            // here SpawnProjectile is basically duplicated. except some functions that aren't needed.
            // following offsets are based on unit's width, height and center
            float tX, tY;

            tX = TargetX + 0.5f;
            tY = TargetY + 0.5f;

            float cX, cY;

            if (Spell.User != null)
            {
                cX = Spell.User.X + Spell.User.Width * 0.5f + Spell.User.FracX;
                cY = Spell.User.Y + Spell.User.Height * 0.5f + Spell.User.FracY;
                Vector2 dir = new Vector2(tX - cX, tY - cY).normalized *((Spell.User.Width + Spell.User.Height) / 2) / 1.5f;
                cX += dir.x;
                cY += dir.y;
            }
            else
            {
                cX = tX;
                cY = tY;
            }

            Server.SpawnProjectileDirectional(AllodsProjectile.FireBall, Spell.User, cX, cY, 0,
                                              tX, tY, 0,
                                              10,
                                              (MapProjectile fproj) =>
            {
                //Debug.LogFormat("spell projectile hit!");
                // done, make damage
                DamageFlags spdf = SphereToDamageFlags(Spell);

                // spawn explosion. serverside, since projectile hit callback is serverside as well.
                Server.SpawnProjectileSimple(AllodsProjectile.Explosion, null, fproj.ProjectileX, fproj.ProjectileY, fproj.ProjectileZ);

                // apply damage over 3x3 cells around the fireball
                for (int y = fproj.Y - 1; y <= fproj.Y + 1; y++)
                {
                    for (int x = fproj.X - 1; x <= fproj.X + 1; x++)
                    {
                        if (x < 0 || y < 0 || x >= MapLogic.Instance.Width || y >= MapLogic.Instance.Height)
                        {
                            continue;
                        }

                        int dmg = (int)((2f - (new Vector2(x - fproj.X, y - fproj.Y).magnitude)) * ballDamage);
                        // damage in the center is approximately 1.4 or 1.6
                        MapNode node = MapLogic.Instance.Nodes[x, y];
                        for (int i = 0; i < node.Objects.Count; i++)
                        {
                            MapObject mo = node.Objects[i];
                            if (!(mo is IVulnerable))
                            {
                                continue;
                            }
                            IVulnerable mov = (IVulnerable)mo;
                            mov.TakeDamage(spdf, Spell.User, dmg);
                            mo.DoUpdateInfo = true;
                            mo.DoUpdateView = true;
                            //Debug.LogFormat("{0} <- {1}", mo, dmg);
                        }
                    }
                }

                fproj.Dispose();
                MapLogic.Instance.Objects.Remove(fproj);
            });

            return(false);
        }
Ejemplo n.º 3
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);
        }