예제 #1
0
    // returns cost to walk to a node.
    // 1.5 = 150% cost, 0.5 = 50% cost. does not always relate to speed (may be related to spell effects being present)
    public float GetNodeCostFactor(int x, int y, bool staticOnly)
    {
        float nodeFactor = 0;
        int   nodeCount  = 0;

        for (int ly = y; ly < y + Unit.Height; ly++)
        {
            for (int lx = x; lx < x + Unit.Width; lx++)
            {
                MapNode node = MapLogic.Instance.Nodes[lx, ly];
                // for walking units, take base node speed as factor
                float baseNodeFactor = 1f;
                if (Unit.IsWalking)
                {
                    baseNodeFactor = Math.Max((byte)1, node.BaseWalkCost) / 8f; // reverse formula for cost compared to speed
                }
                // it would be strange if long-term path included spells and other temporary effects
                if (!staticOnly)
                {
                    foreach (MapObject mobj in node.Objects)
                    {
                        if (!(mobj is MapProjectile))
                        {
                            continue;
                        }
                        MapProjectile proj = (MapProjectile)mobj;
                        // now some magic ;)
                        if (proj.Class == null)
                        {
                            continue;
                        }
                        // logic: the more elemental protection unit has, the more likely it is that it will try to walk right through a spell
                        // we are multiplying it *2 because just "firefac" and "waterfac" don't seem to be powerful enough do make the unit go around with 50 protection
                        switch ((AllodsProjectile)proj.Class.ID)
                        {
                        case AllodsProjectile.FireWall:
                            float firefac = (100 - Unit.Stats.ProtectionFire) / 100f;
                            baseNodeFactor *= 1f + firefac * 2;
                            break;

                        case AllodsProjectile.PoisonCloud:
                        case AllodsProjectile.Blizzard:
                            float waterfac = (100 - Unit.Stats.ProtectionWater) / 100f;
                            baseNodeFactor *= 1f + waterfac * 2;
                            break;

                        // could check for SpecLight, SpecDarkness here. however ROM2 does not seem to do this
                        default:
                            break;
                        }
                    }
                }

                nodeFactor += baseNodeFactor;
                nodeCount++;
            }
        }

        return(nodeFactor / nodeCount);
    }
예제 #2
0
        public override void Process()
        {
            int meanWh = (Unit.Width + Unit.Height) / 2;

            for (int i = 0; i < meanWh * 2; i++)
            {
                float rX = Unit.Width / 2f;
                float rY = Unit.Height / 4f;

                float randRad = UnityEngine.Random.Range(0.0f, 1.0f) * Mathf.PI * 2;

                float pX = -(Mathf.Cos(randRad) * rX);
                float pY = -(Mathf.Sin(randRad) * rY);

                float cZ = -(meanWh / 2f);

                MapProjectile item = new MapProjectile(AllodsProjectile.Healing, Unit, new HealingProjectileLogic((Unit.Width + Unit.Height) / 2f, pX, pY, cZ, Unit));
                item.ZOffset = -64;
                if (Unit.IsFlying)
                {
                    item.ZOffset += 128;
                }
                item.SetPosition(pX, pY, 0);
                item.ZAbsolute = true;
                MapLogic.Instance.AddObject(item, true);
            }
        }
예제 #3
0
 public void SetProjectile(MapProjectile proj)
 {
     Projectile = proj;
     if (Start == 0 && End == 0)
     {
         End = Projectile.Class.Phases - 1;
     }
 }
예제 #4
0
        private void CreateProjectile(AllodsProjectile proj)
        {
            MapProjectile p = new MapProjectile(proj, Unit);

            p.ZOffset = 64;
            MapLogic.Instance.AddObject(p, true);
            Indicators.Add(p);
        }
예제 #5
0
    public static void SpawnProjectileEOT(int id, IPlayerPawn source, float x, float y, float z, int duration, int frequency, int startframes = 0, int endframes = 0, int zoffs = -128, MapProjectileCallback cb = null)
    {
        MapProjectile proj = new MapProjectile(id, source, new MapProjectileLogicEOT(duration, frequency, startframes, endframes), cb);

        proj.ZOffset = zoffs;
        proj.SetPosition(x, y, z);
        MapLogic.Instance.Objects.Add(proj);

        if (NetworkManager.IsServer)
        {
            foreach (ServerClient client in ServerManager.Clients)
            {
                if (client.State != ClientState.Playing)
                {
                    continue;
                }

                Player    p         = MapLogic.Instance.GetNetPlayer(client);
                MapObject sourceObj = (MapObject)source;
                if (sourceObj != null)
                {
                    if (!sourceObj.IsVisibleForNetPlayer(p))
                    {
                        ObjectBecameVisible(p, sourceObj); // force keyframe update for source unit
                    }
                }

                ClientCommands.AddProjectileEOT app;
                app.X          = x;
                app.Y          = y;
                app.Z          = z;
                app.SourceType = (sourceObj != null) ? sourceObj.GetObjectType() : MapObjectType.Object;

                if (app.SourceType == MapObjectType.Human ||
                    app.SourceType == MapObjectType.Monster)
                {
                    app.SourceTag = ((MapUnit)sourceObj).Tag;
                }
                else if (app.SourceType == MapObjectType.Structure)
                {
                    app.SourceTag = ((MapStructure)sourceObj).Tag;
                }
                else
                {
                    app.SourceTag = -1;
                }

                app.TypeID      = id;
                app.Duration    = duration;
                app.StartFrames = startframes;
                app.EndFrames   = endframes;
                app.ZOffset     = zoffs;

                client.SendCommand(app);
            }
        }
    }
예제 #6
0
파일: Server.cs 프로젝트: Logof/UnityAllods
    public static void SpawnProjectileDirectional(int id, IPlayerPawn source, float x, float y, float z, float tgx, float tgy, float tgz, float speed, MapProjectileCallback cb = null)
    {
        MapProjectile proj = new MapProjectile(id, source, new MapProjectileLogicDirectional(tgx, tgy, tgz, speed), cb);

        proj.SetPosition(x, y, z);
        MapLogic.Instance.Objects.Add(proj);
        // todo notify clients

        if (NetworkManager.IsServer)
        {
            foreach (ServerClient client in ServerManager.Clients)
            {
                if (client.State != ClientState.Playing)
                {
                    continue;
                }

                Player    p         = MapLogic.Instance.GetNetPlayer(client);
                MapObject sourceObj = (MapObject)source;
                if (sourceObj != null)
                {
                    if (!sourceObj.IsVisibleForNetPlayer(p))
                    {
                        ObjectBecameVisible(p, sourceObj); // force keyframe update for source unit
                    }
                }

                ClientCommands.AddProjectileDirectional app;
                app.X          = x;
                app.Y          = y;
                app.Z          = z;
                app.TargetX    = tgx;
                app.TargetY    = tgy;
                app.TargetZ    = tgz;
                app.SourceType = (sourceObj != null) ? sourceObj.GetObjectType() : MapObjectType.Object;

                if (app.SourceType == MapObjectType.Human ||
                    app.SourceType == MapObjectType.Monster)
                {
                    app.SourceTag = ((MapUnit)sourceObj).Tag;
                }
                else if (app.SourceType == MapObjectType.Structure)
                {
                    app.SourceTag = ((MapStructure)sourceObj).Tag;
                }
                else
                {
                    app.SourceTag = -1;
                }

                app.Speed  = speed;
                app.TypeID = id;

                client.SendCommand(app);
            }
        }
    }
예제 #7
0
    public static void SpawnProjectileSimple(int id, IPlayerPawn source, float x, float y, float z, float animspeed = 0.5f, float scale = 1f, int start = 0, int end = 0)
    {
        MapProjectile proj = new MapProjectile(id, source, new MapProjectileLogicSimple(animspeed, scale, start, end), null); // this is usually SFX like stuff. projectile plays animation based on typeid and stops.

        proj.SetPosition(x, y, z);
        MapLogic.Instance.Objects.Add(proj);

        if (NetworkManager.IsServer)
        {
            foreach (ServerClient client in ServerManager.Clients)
            {
                if (client.State != ClientState.Playing)
                {
                    continue;
                }

                Player    p         = MapLogic.Instance.GetNetPlayer(client);
                MapObject sourceObj = (MapObject)source;
                if (sourceObj != null)
                {
                    if (!sourceObj.IsVisibleForNetPlayer(p))
                    {
                        ObjectBecameVisible(p, sourceObj); // force keyframe update for source unit
                    }
                }

                ClientCommands.AddProjectileSimple app;
                app.X          = x;
                app.Y          = y;
                app.Z          = z;
                app.SourceType = (sourceObj != null) ? sourceObj.GetObjectType() : MapObjectType.Object;

                if (app.SourceType == MapObjectType.Human ||
                    app.SourceType == MapObjectType.Monster)
                {
                    app.SourceTag = ((MapUnit)sourceObj).Tag;
                }
                else if (app.SourceType == MapObjectType.Structure)
                {
                    app.SourceTag = ((MapStructure)sourceObj).Tag;
                }
                else
                {
                    app.SourceTag = -1;
                }

                app.TypeID    = id;
                app.AnimSpeed = animspeed;
                app.Scale     = scale;
                app.Start     = start;
                app.End       = end;

                client.SendCommand(app);
            }
        }
    }
예제 #8
0
    public static void SpawnProjectileLightning(IPlayerPawn source, float x, float y, float z, MapUnit target, int color, MapProjectileCallback cb = null)
    {
        MapProjectile proj = new MapProjectile(AllodsProjectile.Lightning, source, new MapProjectileLogicLightning(target, color), cb);

        proj.SetPosition(x, y, z);
        MapLogic.Instance.Objects.Add(proj);

        if (NetworkManager.IsServer)
        {
            foreach (ServerClient client in ServerManager.Clients)
            {
                if (client.State != ClientState.Playing)
                {
                    continue;
                }

                Player    p         = MapLogic.Instance.GetNetPlayer(client);
                MapObject sourceObj = (MapObject)source;
                if (sourceObj != null)
                {
                    if (!sourceObj.IsVisibleForNetPlayer(p))
                    {
                        ObjectBecameVisible(p, sourceObj); // force keyframe update for source unit
                    }
                }

                ClientCommands.AddProjectileLightning app;
                app.X          = x;
                app.Y          = y;
                app.Z          = z;
                app.SourceType = (sourceObj != null) ? sourceObj.GetObjectType() : MapObjectType.Object;

                if (app.SourceType == MapObjectType.Human ||
                    app.SourceType == MapObjectType.Monster)
                {
                    app.SourceTag = ((MapUnit)sourceObj).Tag;
                }
                else if (app.SourceType == MapObjectType.Structure)
                {
                    app.SourceTag = ((MapStructure)sourceObj).Tag;
                }
                else
                {
                    app.SourceTag = -1;
                }

                app.TargetTag = target.Tag;
                app.Color     = color;

                client.SendCommand(app);
            }
        }
    }
예제 #9
0
 public void SetProjectile(MapProjectile proj)
 {
     if (Projectile != null && Target != null)
     {
         Target.TargetedBy.Remove(Projectile);
     }
     Projectile = proj;
     if (Target != null)
     {
         Target.TargetedBy.Add(proj);
     }
 }
예제 #10
0
        public void AddMapProjectile(MapProjectile projectile, bool addToMap = true)
        {
            Entity entity = Entity.CreateInstance(GameState.Instance.EntityManager);

            entity.GetTransform().Parent = this.Parent.GetTransform();
            new ProjectileComponent(entity, projectile);
            ProjectileEntites.Add(entity);
            if (addToMap)
            {
                _mapInstance.AddMapProjectile(projectile);
            }
        }
예제 #11
0
        public override void Process()
        {
            Timer++;
            float zatUnit = MapLogic.Instance.GetHeightAt(Unit.X + Unit.FracX + (float)Unit.Width / 2,
                                                          Unit.Y + Unit.FracY + (float)Unit.Height / 2,
                                                          Unit.Width, Unit.Height) / 32;
            float   heightOffset = Mathf.Max(1, ((Unit.Width + Unit.Height) / 4f));
            float   shieldRadius = 0.5f * Mathf.Max(1, ((Unit.Width + Unit.Height) / 2f));
            float   shieldHeight = 0.6f * heightOffset;
            Vector3 initialPos   = new Vector3(Unit.X + Unit.FracX + Unit.Width / 2f, Unit.Y + Unit.FracY + Unit.Height / 2f, 0.1f * heightOffset + zatUnit);

            for (int j = 0; j < 2; j++)
            {
                for (int i = 0; i < Scalar * 16; i++)
                {
                    MapProjectile item        = Grid[i + Scalar * 16 * j];
                    Vector3       particlePos = new Vector3(0, 0, 1);
                    Vector3       pos         = Quaternion.Euler(0, 0, Timer * 2 + 90 * j) * Quaternion.Euler(0, i * 360 / (Scalar * 16), 0) * particlePos;
                    item.SetPosition(pos.x * shieldRadius + initialPos.x, pos.y * shieldRadius + initialPos.y, pos.z * shieldHeight + initialPos.z);
                    item.ZOffset = -64;
                    if (Unit.IsFlying)
                    {
                        item.ZOffset += 128;
                    }
                    item.CurrentFrame = 2 + Mathf.RoundToInt((1f - Mathf.Abs(pos.z)) * 2);
                    item.ZAbsolute    = true;
                    item.DoUpdateView = true;
                }
            }
            for (int j = 0; j < 2; j++)
            {
                for (int i = 0; i < Scalar * 16; i++)
                {
                    MapProjectile item        = Circles[i + Scalar * 16 * j];
                    Vector3       particlePos = new Vector3(0, 1, 0);
                    Vector3       pos         = Quaternion.Euler(0, 0, i * 360 / (Scalar * 16)) * Quaternion.Euler(Timer * 2 + 180 * j, 0, 0) * particlePos;
                    item.SetPosition(pos.x * shieldRadius + initialPos.x, pos.y * shieldRadius + initialPos.y, pos.z * shieldHeight + initialPos.z);
                    item.ZOffset = -64;
                    if (Unit.IsFlying)
                    {
                        item.ZOffset += 128;
                    }
                    item.CurrentFrame = 2 + Mathf.RoundToInt((1f - Mathf.Abs(pos.z)) * 2);
                    item.ZAbsolute    = true;
                    item.DoUpdateView = true;
                }
            }
        }
예제 #12
0
 public void OnUpdateMapProjectile(MapProjectile mapProjectile, int index)
 {
     if (mapProjectile.Changed)
     {
         ServerCommand serverCommand = new ServerCommand(ServerCommand.CommandType.UpdateProjectile);
         serverCommand.SetParameter("MapID", _mapID);
         serverCommand.SetParameter("ProjectileID", index);
         serverCommand.SetParameter("RealX", mapProjectile.Position.X);
         serverCommand.SetParameter("RealY", mapProjectile.Position.Y);
         serverCommand.SetParameter("OnBridge", mapProjectile.OnBridge);
         serverCommand.SetParameter("Destroyed", mapProjectile.Destroyed);
         for (int i = 0; i < _clients.Count; i++)
         {
             _clients[i].AddServerCommand(serverCommand);
         }
     }
 }
예제 #13
0
        public void OnAddMapProjectile(MapProjectile mapProjectile, int index)
        {
            ServerCommand command = new ServerCommand(ServerCommand.CommandType.AddProjectile);

            command.SetParameter("MapID", _mapID);
            command.SetParameter("DataID", mapProjectile.ProjectileID);
            command.SetParameter("RealX", mapProjectile.Position.X);
            command.SetParameter("RealY", mapProjectile.Position.Y);
            command.SetParameter("VelocityX", mapProjectile.Velocity.X);
            command.SetParameter("VelocityY", mapProjectile.Velocity.Y);
            command.SetParameter("Direction", (int)mapProjectile.Direction);
            command.SetParameter("OnBridge", mapProjectile.OnBridge);

            for (int i = 0; i < _clients.Count; i++)
            {
                _clients[i].AddServerCommand(command);
            }
        }
예제 #14
0
    // check if next node is dangerous. used in step-by-step pathfinding to detect that we need to recheck with dynamic mode
    public bool CheckDangerous(int x, int y)
    {
        for (int ly = y; ly < y + Unit.Height; ly++)
        {
            for (int lx = x; lx < x + Unit.Width; lx++)
            {
                MapNode node = MapLogic.Instance.Nodes[lx, ly];

                foreach (MapObject mobj in node.Objects)
                {
                    if (!(mobj is MapProjectile))
                    {
                        continue;
                    }
                    MapProjectile proj = (MapProjectile)mobj;
                    // now some magic ;)
                    if (proj.Class == null)
                    {
                        continue;
                    }

                    switch ((AllodsProjectile)proj.Class.ID)
                    {
                    case AllodsProjectile.FireWall:
                        if (Unit.Stats.ProtectionFire != 100)
                        {
                            return(true);
                        }
                        break;

                    case AllodsProjectile.PoisonCloud:
                    case AllodsProjectile.Blizzard:
                        if (Unit.Stats.ProtectionWater != 100)
                        {
                            return(true);
                        }
                        break;
                    }
                }
            }
        }

        return(false);
    }
예제 #15
0
 public override void OnEnable()
 {
     Scalar = (Unit.Width + Unit.Height) / 2;
     if (Scalar < 1)
     {
         Scalar = 1;
     }
     for (int i = 0; i < Scalar * 16 * 2; i++)
     {
         MapProjectile item = new MapProjectile(AllodsProjectile.Shield, Unit);
         MapLogic.Instance.AddObject(item, true);
         Grid.Add(item);
     }
     for (int i = 0; i < Scalar * 16 * 2; i++)
     {
         MapProjectile item = new MapProjectile(AllodsProjectile.Shield, Unit);
         MapLogic.Instance.AddObject(item, true);
         Circles.Add(item);
     }
 }
예제 #16
0
 public ProjectileComponent(Entity entity, MapProjectile projectile) : base(entity)
 {
     SetProjectile(projectile);
 }
예제 #17
0
        public static MapPacket FromBytes(byte[] bytes)
        {
            using (MemoryStream stream = new MemoryStream(bytes))
            {
                byte[] tempBytes = new byte[sizeof(int)];
                stream.Read(tempBytes, 0, sizeof(int));
                int mapID = BitConverter.ToInt32(tempBytes, 0);

                stream.Read(tempBytes, 0, sizeof(int));
                int dataSize = BitConverter.ToInt32(tempBytes, 0);

                tempBytes = new byte[dataSize];
                stream.Read(tempBytes, 0, dataSize);

                MapPacket mapPacket = new MapPacket(mapID, MapData.FromBytes(tempBytes));

                //add in the map players here

                tempBytes = new byte[sizeof(int)];
                stream.Read(tempBytes, 0, sizeof(int));
                int enemiesCount = BitConverter.ToInt32(tempBytes, 0);

                for (int i = 0; i < enemiesCount; i++)
                {
                    tempBytes = new byte[sizeof(int)];
                    stream.Read(tempBytes, 0, sizeof(int));
                    int size = BitConverter.ToInt32(tempBytes, 0);

                    tempBytes = new byte[size];
                    stream.Read(tempBytes, 0, size);
                    MapEnemy enemy = MapEnemy.FromBytes(tempBytes);
                    mapPacket.Enemies.Add(enemy);
                }

                tempBytes = new byte[sizeof(int)];
                stream.Read(tempBytes, 0, sizeof(int));
                int projectilesCount = BitConverter.ToInt32(tempBytes, 0);

                for (int i = 0; i < projectilesCount; i++)
                {
                    tempBytes = new byte[sizeof(int)];
                    stream.Read(tempBytes, 0, sizeof(int));
                    int size = BitConverter.ToInt32(tempBytes, 0);

                    tempBytes = new byte[size];
                    stream.Read(tempBytes, 0, size);
                    MapProjectile projectile = MapProjectile.FromBytes(tempBytes);
                    mapPacket.Projectiles.Add(projectile);
                }

                tempBytes = new byte[sizeof(int)];
                stream.Read(tempBytes, 0, sizeof(int));
                int itemsCount = BitConverter.ToInt32(tempBytes, 0);

                for (int i = 0; i < itemsCount; i++)
                {
                    tempBytes = new byte[sizeof(int)];
                    stream.Read(tempBytes, 0, sizeof(int));
                    int size = BitConverter.ToInt32(tempBytes, 0);

                    tempBytes = new byte[size];
                    stream.Read(tempBytes, 0, size);
                    MapItem item = MapItem.FromBytes(tempBytes);
                    mapPacket.Items.Add(item);
                }

                return(mapPacket);
            }
        }
예제 #18
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);
        }
예제 #19
0
        public override bool Process()
        {
            if (NetworkManager.IsClient)
            {
                return(false);
            }

            int ballDamage = Spell.GetDamage();

            // 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);
                if (Spell.Item == null)
                {
                    spdf |= DamageFlags.AllowExp;
                }

                // 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))
                            {
                                // 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 - fproj.ProjectileX, mp.ProjectileY - fproj.ProjectileY).magnitude > 1.5f)
                                {
                                    continue;
                                }

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

                fproj.Dispose();
            });

            return(false);
        }
예제 #20
0
 public void SetProjectile(MapProjectile proj)
 {
     Projectile = proj;
 }
예제 #21
0
        public override void Process()
        {
            if (Unit.Flags != LastFlags)
            {
                UnitFlags leftFlags = Unit.Flags;

                // remove unused projectiles
                for (int i = 0; i < Indicators.Count; i++)
                {
                    UnitFlags flag = 0;
                    switch (Indicators[i].ClassID)
                    {
                    case AllodsProjectile.ProtectionFire:
                        flag = UnitFlags.ProtectionFire;
                        break;

                    case AllodsProjectile.ProtectionWater:
                        flag = UnitFlags.ProtectionWater;
                        break;

                    case AllodsProjectile.ProtectionAir:
                        flag = UnitFlags.ProtectionAir;
                        break;

                    case AllodsProjectile.ProtectionEarth:
                        flag = UnitFlags.ProtectionEarth;
                        break;
                    }

                    if ((Unit.Flags & flag) == 0)
                    {
                        Indicators[i].Dispose();
                        i--;
                        continue;
                    }
                    else
                    {
                        leftFlags &= ~flag;
                    }
                }

                if (leftFlags.HasFlag(UnitFlags.ProtectionAir))
                {
                    CreateProjectile(AllodsProjectile.ProtectionAir);
                }
                if (leftFlags.HasFlag(UnitFlags.ProtectionWater))
                {
                    CreateProjectile(AllodsProjectile.ProtectionWater);
                }
                if (leftFlags.HasFlag(UnitFlags.ProtectionEarth))
                {
                    CreateProjectile(AllodsProjectile.ProtectionEarth);
                }
                if (leftFlags.HasFlag(UnitFlags.ProtectionFire))
                {
                    CreateProjectile(AllodsProjectile.ProtectionFire);
                }
                LastFlags = Unit.Flags;
            }

            for (int i = 0; i < Indicators.Count; i++)
            {
                float         indicatorAngle = (Mathf.PI * 2) / Indicators.Count * i + Mathf.PI * 0.5f;
                MapProjectile p = Indicators[i];

                float pX = -Mathf.Cos(indicatorAngle) * 0.25f;
                float pY = Mathf.Sin(indicatorAngle) * 0.25f;

                if (Indicators.Count == 1)
                {
                    pY = -pY;
                }

                float pZ = MapLogic.Instance.GetHeightAt(Unit.X + Unit.FracX, Unit.Y + Unit.FracY, Unit.Width, Unit.Height) / 32
                           + (1f + (((Unit.Width + Unit.Height) / 2f) - 1f) / 2f);

                p.Alpha = (Unit.GetVisibility() == 2) ? 1f : 0;
                p.SetPosition(Unit.X + Unit.FracX + Unit.Width / 2f + pX, Unit.Y + Unit.FracY + Unit.Height / 2f + pY, pZ);
                p.ZAbsolute = true;
                p.ZOffset   = -32;
                if (Unit.IsFlying)
                {
                    p.ZOffset += 128;
                }
                p.CurrentFrame = (p.CurrentFrame + 1) % p.Class.Phases;
                p.DoUpdateView = true;
            }
        }
예제 #22
0
    public virtual bool Update()
    {
        // calculate target direction!
        // check if target is gone
        if (Target != null && (!Target.IsAlive || !Target.IsLinked))
        {
            Target = null;
        }

        Projectile.Alpha = 0;

        if (Target != null && SubProjectiles.Count <= 0)
        {
            // special magic for lightning
            Projectile.LightLevel = 256;
            TargetCenter          = new Vector2(Target.X + (float)Target.Width / 2 + Target.FracX, Target.Y + (float)Target.Height / 2 + Target.FracY);
            TargetAngle           = Projectile.Angle = MapObject.FaceVector(TargetCenter.x - Projectile.ProjectileX, TargetCenter.y - Projectile.ProjectileY);
            TargetDir             = new Vector2(TargetCenter.x - Projectile.ProjectileX, TargetCenter.y - Projectile.ProjectileY);
            TargetDst             = TargetDir.magnitude;
            TargetDir.Normalize();
            // spawn projectiles along the way
            Density = 0.2f;
            for (float i = 0; i < TargetDst; i += Density)
            {
                MapProjectile visProj = new MapProjectile(Color == 0 ? AllodsProjectile.Lightning : AllodsProjectile.ChainLightning);
                visProj.LightLevel   = 0;
                visProj.CurrentFrame = Color == 0 ? 0 : (5 * (Color - 1));
                visProj.SetPosition(Projectile.ProjectileX + TargetDir.x * i, Projectile.ProjectileY + TargetDir.y * i, 0); // for now
                MapLogic.Instance.Objects.Add(visProj);
                SubProjectiles.Add(visProj);
            }

            Projectile.CallCallback();
        }

        AnimTime += 0.08f;

        float   hUDiff     = MapLogic.Instance.GetHeightAt(TargetCenter.x, TargetCenter.y, 1, 1) / 32f;
        float   htOrig     = MapLogic.Instance.GetHeightAt(Projectile.ProjectileX, Projectile.ProjectileY, 1, 1) / 32f;
        float   angleToDst = Mathf.Atan2(TargetDir.y, TargetDir.x);
        float   sinScale   = TargetDst / 8 * Mathf.Sin((float)MapLogic.Instance.LevelTime / 2 * TargetDst);
        Vector2 offs       = new Vector2(0, 1);
        float   sinX       = Mathf.Cos(angleToDst) * offs.x - Mathf.Sin(angleToDst) * offs.y;
        float   sinY       = Mathf.Cos(angleToDst) * offs.y + Mathf.Sin(angleToDst) * offs.x;

        for (int i = 0; i < SubProjectiles.Count; i++)
        {
            float idst = Density * i;
            // get angle from first to second. calculate sin wave
            float baseX = Projectile.ProjectileX + TargetDir.x * idst;
            float baseY = Projectile.ProjectileY + TargetDir.y * idst;

            float         sscale = (Sin10(idst / TargetDst) * sinScale);
            MapProjectile sub    = SubProjectiles[i];
            int           cframe = (Color == 0 ? 0 : (5 * (Color - 1)));
            sub.CurrentFrame = (int)(cframe + 4 * AnimTime);
            sub.LightLevel   = 0;
            if (i % 12 == 0)
            {
                sub.LightLevel = (int)(512 * (1f - AnimTime));
            }
            float htDiff = MapLogic.Instance.GetHeightAt(baseX + sinX * sscale, baseY + sinY * sscale, 1, 1) / 32f;
            float lval   = (float)i / SubProjectiles.Count;
            float htLerp = hUDiff * lval + htOrig * (1f - lval);

            sub.SetPosition(baseX + sinX * sscale, baseY + sinY * sscale, -htDiff + htLerp);
        }

        if (AnimTime > 1)
        {
            foreach (MapProjectile sub in SubProjectiles)
            {
                sub.Dispose();
            }

            Projectile.Dispose();
            return(false);
        }

        return(true);
    }
예제 #23
0
 public void OnRemoveMapProjectile(MapProjectile mapProjectile, int index)
 {
 }
예제 #24
0
        private void RecieveServerCommand()
        {
            byte[] bytes      = ReadData(sizeof(int), _networkStream);
            int    packetSize = BitConverter.ToInt32(bytes, 0);

            bytes = ReadData(packetSize, _networkStream);
            ServerCommand command = ServerCommand.FromBytes(bytes);

            int             eventID;
            int             enemyID;
            int             enemyIndex;
            int             mapID;
            int             mapX;
            int             mapY;
            float           realX;
            float           realY;
            FacingDirection direction;
            MapData         map;
            int             projectileID;
            int             playerID;
            string          playerName;
            int             itemIndex;
            int             itemID;
            int             count;

            switch (command.GetCommandType())
            {
            case ServerCommand.CommandType.Disconnect:
                this.Disconnect();
                Console.WriteLine("Server Disconnected");
                break;

            case ServerCommand.CommandType.ShowMessage:

                if (_messageBox == null)
                {
                    _messageBox = new MessageBox((string)command.GetParameter("Message"), _gameState, false);
                    _gameState.AddControl(_messageBox);
                }

                break;

            case ServerCommand.CommandType.ShowOptions:

                if (_messageBox == null)
                {
                    string message = (string)command.GetParameter("Message");
                    _messageBox = new MessageBox(message, _gameState, false);
                    string[] options = ((string)command.GetParameter("Options")).Split(',');
                    for (int i = 0; i < options.Length; i++)
                    {
                        _messageBox.AddOption(options[i]);
                    }
                    _messageBox.SetSelectedOption(0);
                    _gameState.AddControl(_messageBox);
                }

                break;

            case ServerCommand.CommandType.AddMapEnemy:

                enemyID = (int)command.GetParameter("EnemyID");
                mapID   = (int)command.GetParameter("MapID");
                if (_gameState.MapEntity.FindComponent <MapComponent>().GetMapInstance().GetMapPacket().MapID == mapID)
                {
                    mapX = (int)command.GetParameter("MapX");
                    mapY = (int)command.GetParameter("MapY");
                    bool     onBridge = (bool)command.GetParameter("OnBridge");
                    MapEnemy mapEnemy = new MapEnemy(enemyID, mapX, mapY, onBridge);
                    MapComponent.Instance.AddMapEnemy(mapEnemy);
                }

                break;

            case ServerCommand.CommandType.UpdateMapEnemy:

                enemyIndex = (int)command.GetParameter("EnemyIndex");
                mapID      = (int)command.GetParameter("MapID");
                if ((_gameState.MapEntity.FindComponent <MapComponent>()).GetMapInstance().GetMapPacket().MapID == mapID)
                {
                    int HP = (int)command.GetParameter("HP");
                    mapX      = (int)command.GetParameter("MapX");
                    mapY      = (int)command.GetParameter("MapY");
                    realX     = (float)command.GetParameter("RealX");
                    realY     = (float)command.GetParameter("RealY");
                    direction = (FacingDirection)command.GetParameter("Direction");
                    bool onBridge = (bool)command.GetParameter("OnBridge");
                    bool dead     = (bool)command.GetParameter("Dead");
                    MapEnemyComponent enemyComponent = MapComponent.Instance.EnemyEntites[enemyIndex].FindComponent <MapEnemyComponent>();
                    enemyComponent.UpdateMapEnemy(HP, mapX, mapY, realX, realY, direction, onBridge, dead);

                    if (dead)
                    {
                        MapComponent.Instance.EnemyEntites[enemyIndex].Destroy();
                        MapComponent.Instance.EnemyEntites.RemoveAt(enemyIndex);
                        MapComponent.Instance.GetMapInstance().RemoveMapEnemy(enemyIndex);
                    }
                }

                break;

            case ServerCommand.CommandType.UpdateMapEvent:

                eventID = (int)command.GetParameter("EventID");
                mapID   = (int)command.GetParameter("MapID");
                if (_gameState.MapEntity.FindComponent <MapComponent>().GetMapInstance().GetMapPacket().MapID == mapID)
                {
                    mapX      = (int)command.GetParameter("MapX");
                    mapY      = (int)command.GetParameter("MapY");
                    realX     = (float)command.GetParameter("RealX");
                    realY     = (float)command.GetParameter("RealY");
                    direction = (FacingDirection)command.GetParameter("Direction");
                    bool onBridge = (bool)command.GetParameter("OnBridge");

                    map = _gameState.MapEntity.FindComponent <MapComponent>().GetMapInstance().GetMapData();
                    if (map != null)
                    {
                        map.GetMapEvent(eventID).MapX           = mapX;
                        map.GetMapEvent(eventID).MapY           = mapY;
                        map.GetMapEvent(eventID).RealX          = realX;
                        map.GetMapEvent(eventID).RealY          = realY;
                        map.GetMapEvent(eventID).EventDirection = direction;
                        map.GetMapEvent(eventID).OnBridge       = onBridge;
                    }
                }

                break;

            case ServerCommand.CommandType.ChangeMapEventDirection:

                eventID = (int)command.GetParameter("EventID");
                mapID   = (int)command.GetParameter("MapID");
                if (_gameState.MapEntity.FindComponent <MapComponent>().GetMapInstance().GetMapPacket().MapID == mapID)
                {
                    direction = (FacingDirection)command.GetParameter("Direction");

                    map = _gameState.MapEntity.FindComponent <MapComponent>().GetMapInstance().GetMapData();
                    if (map != null)
                    {
                        map.GetMapEvent(eventID).EventDirection = direction;
                    }
                }

                break;

            case ServerCommand.CommandType.ChangeMapEventSprite:

                mapID = (int)command.GetParameter("MapID");
                if (_gameState.MapEntity.FindComponent <MapComponent>().GetMapInstance().GetMapPacket().MapID == mapID)
                {
                    eventID = (int)command.GetParameter("EventID");
                    int spriteID = (int)command.GetParameter("SpriteID");
                    _gameState.MapEntity.FindComponent <MapComponent>().ChangeMapEventSprite(eventID, spriteID);
                }

                break;

            case ServerCommand.CommandType.ChangeMapEventRenderPriority:

                mapID = (int)command.GetParameter("MapID");
                if (_gameState.MapEntity.FindComponent <MapComponent>().GetMapInstance().GetMapPacket().MapID == mapID)
                {
                    eventID = (int)command.GetParameter("EventID");
                    RenderPriority priority = (RenderPriority)command.GetParameter("RenderPriority");
                    _gameState.MapEntity.FindComponent <MapComponent>().ChangeMapEventRenderPriority(eventID, priority);
                }

                break;

            case ServerCommand.CommandType.ChangeMapEventEnabled:

                mapID = (int)command.GetParameter("MapID");
                if (_gameState.MapEntity.FindComponent <MapComponent>().GetMapInstance().GetMapPacket().MapID == mapID)
                {
                    eventID = (int)command.GetParameter("EventID");
                    bool enabled = (bool)command.GetParameter("Enabled");
                    _gameState.MapEntity.FindComponent <MapComponent>().ChangeMapEventEnabled(eventID, enabled);
                }

                break;

            case ServerCommand.CommandType.AddProjectile:

                mapID = (int)command.GetParameter("MapID");
                if (_gameState.MapEntity.FindComponent <MapComponent>().GetMapInstance().GetMapPacket().MapID == mapID)
                {
                    {
                        int dataID = (int)command.GetParameter("DataID");
                        realX     = (float)command.GetParameter("RealX");
                        realY     = (float)command.GetParameter("RealY");
                        direction = (FacingDirection)command.GetParameter("Direction");
                        bool onBridge = (bool)command.GetParameter("OnBridge");

                        MapProjectile projectile = new MapProjectile(dataID, CharacterType.Player, -1, new Vector2(realX, realY), direction);
                        projectile.OnBridge = onBridge;
                        MapComponent.Instance.AddMapProjectile(projectile);
                    }
                }

                break;

            case ServerCommand.CommandType.UpdateProjectile:

                mapID = (int)command.GetParameter("MapID");
                if (_gameState.MapEntity.FindComponent <MapComponent>().GetMapInstance().GetMapPacket().MapID == mapID)
                {
                    projectileID = (int)command.GetParameter("ProjectileID");
                    if (projectileID < MapComponent.Instance.ProjectileEntites.Count)
                    {
                        realX = (float)command.GetParameter("RealX");
                        realY = (float)command.GetParameter("RealY");
                        bool onBridge  = (bool)command.GetParameter("OnBridge");
                        bool destroyed = (bool)command.GetParameter("Destroyed");
                        ProjectileComponent component = MapComponent.Instance.ProjectileEntites[projectileID].FindComponent <ProjectileComponent>();
                        component.SetRealPosition(realX, realY);
                        component.SetOnBridge(onBridge);
                        if (destroyed)
                        {
                            MapComponent.Instance.ProjectileEntites[projectileID].Destroy();
                            MapComponent.Instance.ProjectileEntites.RemoveAt(projectileID);
                            MapComponent.Instance.GetMapInstance().RemoveMapProjectile(projectileID);
                        }
                    }
                }

                break;

            case ServerCommand.CommandType.AddMapItem:

                mapID = (int)command.GetParameter("MapID");
                MapComponent mapComponent = _gameState.MapEntity.FindComponent <MapComponent>();
                if (mapComponent.GetMapInstance().GetMapPacket().MapID == mapID)
                {
                    itemID   = (int)command.GetParameter("ItemID");
                    count    = (int)command.GetParameter("Count");
                    mapX     = (int)command.GetParameter("MapX");
                    mapY     = (int)command.GetParameter("MapY");
                    playerID = (int)command.GetParameter("PlayerID");
                    bool    onBridge = (bool)command.GetParameter("OnBridge");
                    MapItem mapItem  = new MapItem(itemID, count, mapX, mapY, playerID, onBridge);
                    MapComponent.Instance.AddMapItem(mapItem);
                }

                break;

            case ServerCommand.CommandType.RemoveMapItem:

                mapID = (int)command.GetParameter("MapID");
                if (_gameState.MapEntity.FindComponent <MapComponent>().GetMapInstance().GetMapPacket().MapID == mapID)
                {
                    itemIndex = (int)command.GetParameter("ItemIndex");
                    if (itemIndex < MapComponent.Instance.MapItemEntities.Count)
                    {
                        MapComponent.Instance.MapItemEntities[itemIndex].Destroy();
                        MapComponent.Instance.MapItemEntities.RemoveAt(itemIndex);
                        MapComponent.Instance.GetMapInstance().RemoveMapItem(itemIndex);
                    }
                }

                break;

            case ServerCommand.CommandType.UpdateMapItem:

                mapID = (int)command.GetParameter("MapID");
                if (_gameState.MapEntity.FindComponent <MapComponent>().GetMapInstance().GetMapPacket().MapID == mapID)
                {
                    itemIndex = (int)command.GetParameter("ItemIndex");
                    if (itemIndex < MapComponent.Instance.MapItemEntities.Count)
                    {
                        playerID = (int)command.GetParameter("PlayerID");
                        count    = (int)command.GetParameter("Count");
                        MapComponent.Instance.MapItemEntities[itemIndex].FindComponent <MapItemComponent>().GetMapItem().PlayerID = playerID;
                        MapComponent.Instance.MapItemEntities[itemIndex].FindComponent <MapItemComponent>().GetMapItem().Count    = count;
                    }
                }

                break;

            case ServerCommand.CommandType.ShowShop:

                int      shopID = (int)command.GetParameter("ShopID");
                ShopData data   = ShopData.GetData(shopID);
                if (data != null)
                {
                    if (InventoryPanel.Instance == null)
                    {
                        GameState.Instance.ToggleInventory();
                    }
                    _gameState.AddControl(new GUI.ShopPanel(_gameState, data));
                }
                else
                {
                    AddClientCommand(new ClientCommand(ClientCommand.CommandType.CloseShop));
                }

                break;

            case ServerCommand.CommandType.TradeRequest:
                playerID   = (int)command.GetParameter("PlayerID");
                playerName = (string)command.GetParameter("PlayerName");
                MessagePanel.Instance.AddMessage(playerName + " would like to trade.");

                break;

            case ServerCommand.CommandType.StartTrade:
                playerID   = (int)command.GetParameter("PlayerID");
                playerName = (string)command.GetParameter("PlayerName");

                if (InventoryPanel.Instance == null)
                {
                    GameState.Instance.ToggleInventory();
                }

                _gameState.AddControl(new GUI.TradePanel(_gameState, playerID, playerName));
                break;

            case ServerCommand.CommandType.AcceptTrade:
                if (TradePanel.Instance != null)
                {
                    TradePanel.Instance.TradeRequest.TradeOffer2.Accepted = true;
                }
                break;

            case ServerCommand.CommandType.EndTrade:
                if (TradePanel.Instance != null)
                {
                    TradePanel.Instance.Close();
                }
                break;

            case ServerCommand.CommandType.AddTradeItem:
                itemID = (int)command.GetParameter("ItemID");
                count  = (int)command.GetParameter("Count");

                if (TradePanel.Instance != null)
                {
                    TradePanel.Instance.TradeRequest.TradeOffer2.AddItem(itemID, count);
                    TradePanel.Instance.TradeRequest.TradeOffer1.Accepted = false;
                    TradePanel.Instance.TradeRequest.TradeOffer2.Accepted = false;
                }

                break;

            case ServerCommand.CommandType.RemoveTradeItem:
                itemIndex = (int)command.GetParameter("ItemIndex");
                count     = (int)command.GetParameter("Count");

                if (TradePanel.Instance != null)
                {
                    TradePanel.Instance.TradeRequest.TradeOffer2.RemoveItem(itemIndex, count);
                    TradePanel.Instance.TradeRequest.TradeOffer1.Accepted = false;
                    TradePanel.Instance.TradeRequest.TradeOffer2.Accepted = false;
                }

                break;

            case ServerCommand.CommandType.CantTrade:
                if (TradePanel.Instance != null)
                {
                    TradePanel.Instance.TradeRequest.TradeOffer1.Accepted = false;
                    TradePanel.Instance.TradeRequest.TradeOffer2.Accepted = false;
                }
                break;

            case ServerCommand.CommandType.OpenBank:
                if (InventoryPanel.Instance == null)
                {
                    GameState.Instance.ToggleInventory();
                }

                _gameState.AddControl(new BankPanel(_gameState));

                break;

            case ServerCommand.CommandType.ShowWorkbench:
                int workbenchID = (int)command.GetParameter("WorkbenchID");

                if (InventoryPanel.Instance == null)
                {
                    GameState.Instance.ToggleInventory();
                }

                _gameState.AddControl(new GUI.WorkbenchPanel(_gameState, workbenchID));

                break;
            }
        }
예제 #25
0
 private void SetProjectile(MapProjectile projectile)
 {
     _projectile = projectile;
     _data       = ProjectileData.GetProjectileData(projectile.ProjectileID);
     SetRealPosition(_projectile.Position.X, _projectile.Position.Y);
 }
예제 #26
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);
        }
예제 #27
0
 public override void OnEnable()
 {
     Indicator         = new MapProjectile(AllodsProjectile.PoisonSign, Unit);
     Indicator.ZOffset = 64;
     MapLogic.Instance.Objects.Add(Indicator);
 }