PostBlocked Sight V2 Tutorial

Posts 1–15 of 27 · Page 1 of 2
Blocked Sight V2 Tutorial
The code below is made from the source kithio released so if you are using fsod or sd then be sure to take your time adding it in without full on copy and paste as it will not work

Link: http://www.mpgh.net/forum/showthread.php?t=893883

I will be posting the whole file as its easier for people to use.

Files modified were :
Player.Update.cs Located - wServer\realm\entities\player
Sight.cs Located - wServer\realm
World.cs Located - wServer\realm
Wmap.cs Located - wServer\realm\terrain

 
Player.Update.cs

Note you will need to replace the entire file with the code below
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using wServer.networking.svrPackets;
using wServer.realm.terrain;

namespace wServer.realm.entities
{
    public partial class Player
    {
        public const int RADIUS = 15;
        const int APPOX_AREA_OF_SIGHT = (int)(Math.PI * RADIUS * RADIUS + 1);

        int mapWidth, mapHeight;

        HashSet<Entity> clientEntities = new HashSet<Entity>();
        HashSet<IntPoint> clientStatic = new HashSet<IntPoint>(new IntPointComparer());
        List<IntPoint> SightTiles = new List<IntPoint>();

        IEnumerable<Entity> GetNewEntities()
        {
            foreach (var i in Owner.Players)
                if (clientEntities.Add(i.Value))
                    yield return i.Value;
            foreach (var i in Owner.PlayersCollision.HitTest(X, Y, RADIUS))
                if (i is Decoy)
                    if (clientEntities.Add(i))
                        yield return i;
            foreach (var i in Owner.EnemiesCollision.HitTest(X, Y, RADIUS))
            {
                if (i is Container)
                {
                    int[] owners = (i as Container).BagOwners;
                    if (owners.Length > 0 && Array.IndexOf(owners, AccountId) == -1) continue;
                }

                if (MathsUtils.DistSqr(i.X, i.Y, X, Y) <= RADIUS * RADIUS)
                    if (clientEntities.Add(i))
                        yield return i;
            }
            if (questEntity != null && clientEntities.Add(questEntity))
                yield return questEntity;
        }

        IEnumerable<int> GetRemovedEntities()
        {
            foreach (var i in clientEntities)
            {
                if (i is Player && i.Owner != null) continue;
                if (!SightTiles.Contains(new IntPoint((int)i.X, (int)i.Y)) && !(i is StaticObject && (i as StaticObject).Static) && i != questEntity)
                    yield return i.Id;
                else if (i.Owner == null)
                    yield return i.Id;
            }
        }

        IEnumerable<ObjectDef> GetNewStatics(int _x, int _y)
        {
            List<ObjectDef> ret = new List<ObjectDef>();
            foreach (var i in SightTiles)
            {
                int x = i.X;
                int y = i.Y;

                if (x < 0 || x >= mapWidth || y < 0 || y >= mapHeight)
                    continue;

                var tile = Owner.Map[x, y];
                if (tile.ObjId != 0 && tile.ObjType != 0 && clientStatic.Add(new IntPoint(x, y)))
                    ret.Add(tile.ToDef(x, y));
            }
            return ret;
        }
        IEnumerable<IntPoint> GetRemovedStatics(int _x, int _y)
        {
            foreach (var i in clientStatic)
            {
                var dx = i.X;
                var dy = i.Y;
                var tile = Owner.Map[i.X, i.Y];
                if (tile.ObjType == 0)
                {
                    int objId = Owner.Map[i.X, i.Y].ObjId;
                    if (objId != 0)
                        yield return i;
                }
            }
        }

        Dictionary<Entity, int> lastUpdate = new Dictionary<Entity, int>();
        void SendUpdate(RealmTime time)
        {
            SightTiles = (Owner.Dungeon ? Sight.RayCast(this, RADIUS) : Sight.GetSightCircle(this, RADIUS).ToList());

            mapWidth = Owner.Map.Width;
            mapHeight = Owner.Map.Height;
            var map = Owner.Map;
            int _x = (int)X;
            int _y = (int)Y;
        
            var sendEntities = new HashSet<Entity>(GetNewEntities());

            var list = new List<UpdatePacket.TileData>(APPOX_AREA_OF_SIGHT);
            int sent = 0;
            foreach (var i in SightTiles)
            {
                int x = i.X;
                int y = i.Y;

                WmapTile tile;
                if (x < 0 || x >= mapWidth ||
                    y < 0 || y >= mapHeight ||
                    tiles[x, y] >= (tile = map[x, y]).UpdateCount) continue;
                list.Add(new UpdatePacket.TileData()
                {
                    X = (short)x,
                    Y = (short)y,
                    Tile = (Tile)tile.TileId
                });
                tiles[x, y] = tile.UpdateCount;
                sent++;
            }
            fames.TileSent(sent);

            var dropEntities = GetRemovedEntities().Distinct().ToArray();
            clientEntities.RemoveWhere(_ => Array.IndexOf(dropEntities, _.Id) != -1);

            foreach (var i in sendEntities)
                lastUpdate[i] = i.UpdateCount;

            var newStatics = GetNewStatics(_x, _y).ToArray();
            var removeStatics = GetRemovedStatics(_x, _y).ToArray();
            List<int> removedIds = new List<int>();
            foreach (var i in removeStatics)
            {
                removedIds.Add(Owner.Map[i.X, i.Y].ObjId);
                clientStatic.Remove(i);
            }

            if (sendEntities.Count > 0 || list.Count > 0 || dropEntities.Length > 0 || newStatics.Length > 0 || removedIds.Count > 0)
            {
                client.SendPacket(new UpdatePacket()
                {
                    Tiles = list.ToArray(),
                    NewObjects = sendEntities.Select(_ => _.ToDefinition()).Concat(newStatics).ToArray(),
                    RemovedObjectIds = dropEntities.Concat(removedIds).ToArray()
                });
            }
            SendNewTick(time);
        }

        int tickId = 0;
        void SendNewTick(RealmTime time)
        {
            var sendEntities = new List<Entity>();
            foreach (var i in clientEntities)
                if (i.UpdateCount > lastUpdate[i])
                {
                    sendEntities.Add(i);
                    lastUpdate[i] = i.UpdateCount;
                }

            if (questEntity != null && (!lastUpdate.ContainsKey(questEntity) || questEntity.UpdateCount > lastUpdate[questEntity]))
            {
                sendEntities.Add(questEntity);
                lastUpdate[questEntity] = questEntity.UpdateCount;
            }

            client.SendPacket(new NewTickPacket()
            {
                TickId = tickId++,
                TickTime = time.thisTickTimes,
                UpdateStatuses = sendEntities.Select(_ => _.ExportStats()).ToArray()
            });

            SightTiles.Clear();
        }
    }
}

 
Sight.cs

Note this was made with Bresenham line algorithm - https://en.wikipedia.org/wiki/Bresen...line_algorithm, also replace the entire file with the code below
Code:
using System;
using System.Collections.Generic;
using wServer.realm.entities;
using wServer.realm.terrain;

namespace wServer.realm
{
    internal static class Sight
    {
        private static readonly Dictionary<int, IntPoint[]> points = new Dictionary<int, IntPoint[]>();

        public static IntPoint[] GetSightCircle(Player player, int radius)
        {
            IntPoint[] ret;
            if (!points.TryGetValue(radius, out ret))
            {
                List<IntPoint> pts = new List<IntPoint>();
                for (int y = -radius; y <= radius; y++)
                    for (int x = -radius; x <= radius; x++)
                    {
                        if (x * x + y * y <= radius * radius)
                            pts.Add(new IntPoint(x + (int)player.X, y + (int)player.Y));
                    }
                ret = points[radius] = pts.ToArray();
            }
            return ret;
        }

        public static List<IntPoint> RayCast(Player player, int radius)
        {
            var map = player.Owner.Map;

            var Tiles = new List<IntPoint>();
            for (var x = -radius; x <= radius; x++)
                for (var y = -radius; y <= radius; y++)
                    if (x * x + y * y <= radius * radius)
                    {
                        var lineData = castLine((int)player.X, (int)player.Y, (int)player.X + x, (int)player.Y + y, player);
                        if (lineData.Item1)
                            Tiles.Add(new IntPoint(x + (int)player.X, y + (int)player.Y));
                        else
                            Tiles.Add(lineData.Item2);
                    }
            for (var x = -1; x <= 1; x++)
                for (var y = -1; y <= 1; y++)
                    Tiles.Add(new IntPoint(x + (int)player.X, y + (int)player.Y));
            return Tiles;
        }

        private static Tuple<bool, IntPoint> castLine(int x, int y, int x2, int y2, Player player)
        {
            int w = x2 - x;
            int h = y2 - y;
            int dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0;
            if (w < 0)
                dx1 = -1;
            else if (w > 0)
                dx1 = 1;
            if (h < 0)
                dy1 = -1;
            else if (h > 0)
                dy1 = 1;
            if (w < 0)
                dx2 = -1;
            else if (w > 0)
                dx2 = 1;
            int longest = Math.Abs(w);
            int shortest = Math.Abs(h);
            if (!(longest > shortest))
            {
                longest = Math.Abs(h);
                shortest = Math.Abs(w);
                if (h < 0) dy2 = -1; else if (h > 0) dy2 = 1;
                dx2 = 0;
            }
            int numerator = longest >> 1;
            for (int i = 0; i <= longest; i++)
            {
                var desc = player.Owner.Map[x, y].ObjectDesc;
                if (desc != null && desc.BlocksSight)
                    return Tuple.Create(false, new IntPoint(x, y));

                numerator += shortest;
                if (!(numerator < longest))
                {
                    numerator -= longest;
                    x += dx1;
                    y += dy1;
                }
                else
                {
                    x += dx2;
                    y += dy2;
                }
            }
            return Tuple.Create(true, new IntPoint(x, y));
        }
    }
}

 
World.cs

This file you wont need to fully replace but i did add a bool to check if the world is a dungeon
Code:
public bool Dungeon { get; set; }
under
Code:
public int Background { get; protected set; }
To use this inside the world file like Nexus.cs you will do this
Code:
public Nexus()
{
	Id = NEXUS_ID;
	Name = "Nexus";
	Dungeon = true; // <---- this was added
}

 
Wmap.cs

This file you will need to replace the entire file as i have modified it to allow for the destructible walls to block the sight as previously i never released a tut on how to do it
Code:
using System;
using System.Collections.Generic;
using System.(IO); // remove the () as mpgh turns it to **** 
using Ionic.Zlib;
using wServer.realm.entities;

namespace wServer.realm.terrain
{
    public enum TileRegion : byte
    {
        None,
        Spawn,
        Realm_Portals,
        Store_1,
        Store_2,
        Store_3,
        Store_4,
        Store_5,
        Store_6,
        Store_7,
        Store_8,
        Store_9,
        Vault,
        Loot,
        Defender,
        Hallway,
        Hallway_1,
        Hallway_2,
        Hallway_3,
        Enemy,
    }
    public enum WmapTerrain : byte
    {
        None,
        Mountains,
        HighSand,
        HighPlains,
        HighForest,
        MidSand,
        MidPlains,
        MidForest,
        LowSand,
        LowPlains,
        LowForest,
        ShoreSand,
        ShorePlains,
    }
    public struct WmapTile
    {
        public byte UpdateCount;
        public ushort TileId;
        public string Name;
        public ushort ObjType;
        public WmapTerrain Terrain;
        public TileRegion Region;
        public byte Elevation;
        public int ObjId;
        public ObjectDesc ObjectDesc;

        public ObjectDef ToDef(int x, int y)
        {
            List<KeyValuePair<StatsType, object>> stats = new List<KeyValuePair<StatsType, object>>();
            if (!string.IsNullOrEmpty(Name))
                foreach (var item in Name.Split(';'))
                {
                    string[] kv = item.Split(':');
                    switch (kv[0])
                    {
                        case "name":
                            stats.Add(new KeyValuePair<StatsType, object>(StatsType.Name, kv[1])); break;
                        case "size":
                            stats.Add(new KeyValuePair<StatsType, object>(StatsType.Size, Utils.FromString(kv[1]))); break;
                        case "eff":
                            stats.Add(new KeyValuePair<StatsType, object>(StatsType.Effects, Utils.FromString(kv[1]))); break;
                        case "conn":
                            stats.Add(new KeyValuePair<StatsType, object>(StatsType.ObjectConnection, Utils.FromString(kv[1]))); break;
                    }
                }
            return new ObjectDef()
            {
                ObjectType = ObjType,
                Stats = new ObjectStats()
                {
                    Id = ObjId,
                    Position = new Position()
                    {
                        X = x + 0.5f,
                        Y = y + 0.5f
                    },
                    Stats = stats.ToArray()
                }
            };
        }

        public WmapTile Clone()
        {
            return new WmapTile()
            {
                UpdateCount = (byte)(UpdateCount + 1),
                TileId = TileId,
                Name = Name,
                ObjType = ObjType,
                Terrain = Terrain,
                Region = Region,
                ObjId = ObjId,
                ObjectDesc = ObjectDesc
            };
        }
    }
    public class Wmap
    {
        XmlData dat;
        public Wmap(XmlData dat)
        {
            this.dat = dat;
        }

        public int Width { get; set; }
        public int Height { get; set; }

        WmapTile[,] tiles;
        public WmapTile this[int x, int y]
        {
            get { return tiles[x, y]; }
            set { tiles[x, y] = value; }
        }

        Tuple<IntPoint, ushort, string>[] entities;
        public int Load(Stream stream, int idBase)
        {
            int ver = stream.ReadByte();
            using (BinaryReader rdr = new BinaryReader(new ZlibStream(stream, CompressionMode.Decompress)))
            {
                if (ver == 0) return LoadV0(rdr, idBase);
                else if (ver == 1) return LoadV1(rdr, idBase);
                else if (ver == 2) return LoadV2(rdr, idBase);
                else throw new NotSupportedException("WMap version " + ver);
            }
        }

        int LoadV0(BinaryReader reader, int idBase)
        {
            List<WmapTile> dict = new List<WmapTile>();
            short c = reader.ReadInt16();
            for (short i = 0; i < c; i++)
            {
                WmapTile tile = new WmapTile();
                tile.TileId = reader.ReadUInt16();
                string obj = reader.ReadString();
                tile.ObjType = string.IsNullOrEmpty(obj) ? (ushort)0 : dat.IdToObjectType[obj];
                tile.Name = reader.ReadString();
                tile.Terrain = (WmapTerrain)reader.ReadByte();
                tile.Region = (TileRegion)reader.ReadByte();
                dat.ObjectDescs.TryGetValue(tile.ObjType, out tile.ObjectDesc);
                dict.Add(tile);
            }
            Width = reader.ReadInt32();
            Height = reader.ReadInt32();
            tiles = new WmapTile[Width, Height];
            int enCount = 0;
            List<Tuple<IntPoint, ushort, string>> entities = new List<Tuple<IntPoint, ushort, string>>();
            for (int y = 0; y < Height; y++)
                for (int x = 0; x < Width; x++)
                {
                    WmapTile tile = dict[reader.ReadInt16()];
                    tile.UpdateCount = 1;

                    var desc = tile.ObjectDesc;
                    if (tile.ObjType != 0 && (desc == null || !desc.Static || desc.Enemy))
                    {
                        entities.Add(new Tuple<IntPoint, ushort, string>(new IntPoint(x, y), tile.ObjType, tile.Name));
                        tile.ObjType = 0;
                    }

                    if (tile.ObjType != 0)
                    {
                        enCount++;
                        tile.ObjId = idBase + enCount;
                    }


                    tiles[x, y] = tile;
                }
            this.entities = entities.ToArray();
            return enCount;
        }

        int LoadV1(BinaryReader reader, int idBase)
        {
            List<WmapTile> dict = new List<WmapTile>();
            short c = reader.ReadInt16();
            for (short i = 0; i < c; i++)
            {
                WmapTile tile = new WmapTile();
                tile.TileId = reader.ReadUInt16();
                string obj = reader.ReadString();
                tile.ObjType = string.IsNullOrEmpty(obj) ? (ushort)0 : dat.IdToObjectType[obj];
                tile.Name = reader.ReadString();
                tile.Terrain = (WmapTerrain)reader.ReadByte();
                tile.Region = (TileRegion)reader.ReadByte();
                tile.Elevation = reader.ReadByte();
                dat.ObjectDescs.TryGetValue(tile.ObjType, out tile.ObjectDesc);
                dict.Add(tile);
            }
            Width = reader.ReadInt32();
            Height = reader.ReadInt32();
            tiles = new WmapTile[Width, Height];
            int enCount = 0;
            List<Tuple<IntPoint, ushort, string>> entities = new List<Tuple<IntPoint, ushort, string>>();
            for (int y = 0; y < Height; y++)
                for (int x = 0; x < Width; x++)
                {
                    WmapTile tile = dict[reader.ReadInt16()];
                    tile.UpdateCount = 1;

                    var desc = tile.ObjectDesc;
                    if (tile.ObjType != 0 && (desc == null || !desc.Static || desc.Enemy))
                    {
                        entities.Add(new Tuple<IntPoint, ushort, string>(new IntPoint(x, y), tile.ObjType, tile.Name));
                        tile.ObjType = 0;
                    }

                    if (tile.ObjType != 0)
                    {
                        enCount++;
                        tile.ObjId = idBase + enCount;
                    }


                    tiles[x, y] = tile;
                }
            this.entities = entities.ToArray();
            return enCount;
        }

        int LoadV2(BinaryReader reader, int idBase)
        {
            List<WmapTile> dict = new List<WmapTile>();
            short c = reader.ReadInt16();
            for (short i = 0; i < c; i++)
            {
                WmapTile tile = new WmapTile();
                tile.TileId = reader.ReadUInt16();
                string obj = reader.ReadString();
                tile.ObjType = string.IsNullOrEmpty(obj) ? (ushort)0 : dat.IdToObjectType[obj];
                tile.Name = reader.ReadString();
                tile.Terrain = (WmapTerrain)reader.ReadByte();
                tile.Region = (TileRegion)reader.ReadByte();
                dat.ObjectDescs.TryGetValue(tile.ObjType, out tile.ObjectDesc);
                dict.Add(tile);
            }
            Width = reader.ReadInt32();
            Height = reader.ReadInt32();
            tiles = new WmapTile[Width, Height];
            int enCount = 0;
            List<Tuple<IntPoint, ushort, string>> entities = new List<Tuple<IntPoint, ushort, string>>();
            for (int y = 0; y < Height; y++)
                for (int x = 0; x < Width; x++)
                {
                    WmapTile tile = dict[reader.ReadInt16()];
                    tile.UpdateCount = 1;
                    tile.Elevation = reader.ReadByte();

                    var desc = tile.ObjectDesc;
                    if (tile.ObjType != 0 && (desc == null || !desc.Static || desc.Enemy))
                    {
                        entities.Add(new Tuple<IntPoint, ushort, string>(new IntPoint(x, y), tile.ObjType, tile.Name));
                        tile.ObjType = 0;
                    }

                    if (tile.ObjType != 0)
                    {
                        enCount++;
                        tile.ObjId = idBase + enCount;
                    }


                    tiles[x, y] = tile;
                }
            this.entities = entities.ToArray();
            return enCount;
        }

        public IEnumerable<Entity> InstantiateEntities(RealmManager manager)
        {
            foreach (var i in entities)
            {
                var entity = Entity.Resolve(manager, i.Item2);
                entity.Move(i.Item1.X + 0.5f, i.Item1.Y + 0.5f);
                if (i.Item3 != null)
                    foreach (var item in i.Item3.Split(';'))
                    {
                        string[] kv = item.Split(':');
                        switch (kv[0])
                        {
                            case "name":
                                entity.Name = kv[1]; break;
                            case "size":
                                entity.Size = Utils.FromString(kv[1]); break;
                            case "eff":
                                entity.ConditionEffects = (ConditionEffects)Utils.FromString(kv[1]); break;
                            case "conn":
                                (entity as ConnectedObject).Connection = ConnectionInfo.Infos[(uint)Utils.FromString(kv[1])]; break;
                        }
                    }
                yield return entity;
            }
        }
    }
}


Any issues send me a private message on mpgh
Damn, u deserve a Fat Rep
Quote Originally Posted by Demon View Post
Damn, u deserve a Fat Rep
xD //10 chars
I get problem my english not good but when i walk to the black tiles this happens At first i just copy and pasted but than after this i thought i should go in and just add whats not there and it still be broken

h t t p : / / i m g u r . c o m / a / C L H V Q

thats error
Quote Originally Posted by SwatSecOne! View Post
I get problem my english not good but when i walk to the black tiles this happens At first i just copy and pasted but than after this i thought i should go in and just add whats not there and it still be broken

h t t p : / / i m g u r . c o m / a / C L H V Q

thats error
u using fsod? cus i made it using the source stated above which is different to fsod alittle
Quote Originally Posted by Slendergo View Post
u using fsod? cus i made it using the source stated above which is different to fsod alittle
No i'm using serhps
Quote Originally Posted by SwatSecOne! View Post
No i'm using serhps
should work the same then
thanks for tutorial
Quote Originally Posted by Nyaro View Post
Good work @Slendergo as always
thanks lol

- - - Updated - - -

Quote Originally Posted by SwatSecOne! View Post
Hey man I was able to fix it and thanks it works but i still have this error

https://gyazo(DOT)com/e399989d3c43fe04d21153bf47d3afb7
u must not have added all the update.cs parts then if ur still getting revealed entities
Quote Originally Posted by Slendergo View Post
thanks lol

- - - Updated - - -



u must not have added all the update.cs parts then if ur still getting revealed entities
When ever I slowly add in the update.cs no entities but my quest will show up not even portals will spawn if I use a key

this is my code
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using wServer.networking.svrPackets;
using wServer.realm.terrain;

namespace wServer.realm.entities
{
    public partial class Player
    {
        public const int RADIUS = 15;
        private const int APPOX_AREA_OF_SIGHT = (int) (Math.PI*RADIUS*RADIUS + 1);

        private readonly HashSet<Entity> clientEntities = new HashSet<Entity>();
        private readonly HashSet<IntPoint> clientStatic = new HashSet<IntPoint>(new IntPointComparer());
        private readonly Dictionary<Entity, int> lastUpdate = new Dictionary<Entity, int>();
        List<IntPoint> SightTiles = new List<IntPoint>();

        private List<byte[,]> Invisible = new List<Byte[,]>();
        private int mapHeight;
        private int mapWidth;
        private int tickId;

        private IEnumerable<Entity> GetNewEntities()
        {
            foreach (var i in Owner.Players)
            {
                if (clientEntities.Add(i.Value))
                    yield return i.Value;
            }
            foreach (Entity i in Owner.PlayersCollision.HitTest(X, Y, RADIUS))
            {
                if (i is Decoy)
                {
                    if (clientEntities.Add(i))
                        yield return i;
                }
            }
            foreach (Entity i in Owner.EnemiesCollision.HitTest(X, Y, RADIUS))
            {
                if (i is Container)
                {
                    int[] owners = (i as Container).BagOwners;
                    if (owners.Length > 0 && Array.IndexOf(owners, AccountId) == -1) continue;
                }
                if (MathsUtils.DistSqr(i.X, i.Y, X, Y) <= RADIUS*RADIUS)
                {
                    if (clientEntities.Add(i))
                        yield return i;
                }
            }
            if (questEntity != null && clientEntities.Add(questEntity))
                yield return questEntity;
        }

        private IEnumerable<int> GetRemovedEntities()
        {
            foreach (Entity i in clientEntities.Where(i => i is Player))
            {
                if ((i as Player).isNotVisible && i != this && !PvP)
                {
                    yield return i.Id;
                }
            }
            foreach (Entity i in clientEntities)
            {
                if (i is Player && i.Owner != null) continue;
                if (!SightTiles.Contains(new IntPoint((int)i.X, (int)i.Y)) && !(i is StaticObject && (i as StaticObject).Static) && i != questEntity)
                        yield return i.Id;
                 if (MathsUtils.DistSqr(i.X, i.Y, X, Y) > RADIUS*RADIUS &&
                    !(i is StaticObject && (i as StaticObject).Static) &&
                    i != questEntity)
                    yield return i.Id;
                else if (i.Owner == null)
                    yield return i.Id;
                if (i is Player)
                    if ((i as Player).isNotVisible && i != this && !PvP)
                        yield return i.Id;
            }
        }

        private IEnumerable<ObjectDef> GetNewStatics(int _x, int _y)
        {
            var ret = new List<ObjectDef>();
            foreach (IntPoint i in Sight.GetSightCircle(RADIUS))
            {
                int x = i.X + _x;
                int y = i.Y + _y;
                if (x < 0 || x >= mapWidth ||
                    y < 0 || y >= mapHeight) continue;
                WmapTile tile = Owner.Map[x, y];
                if (tile.ObjId != 0 && tile.ObjType != 0 && clientStatic.Add(new IntPoint(x, y)))
                {
                    ObjectDef def = tile.ToDef(x, y);
                    string cls = Manager.GameData.ObjectDescs[tile.ObjType].Class;
                    if (cls == "ConnectedWall" || cls == "CaveWall")
                    {
                        bool hasCon = false;
                        foreach (var s in def.Stats.Stats)
                            if (s.Key == StatsType.ObjectConnection && s.Value != null)
                                hasCon = true;
                        if (!hasCon)
                        {
                            var stats = def.Stats.Stats.ToList();
                            stats.Add(new KeyValuePair<StatsType, object>(StatsType.ObjectConnection, (int)ConnectionComputer.Compute((xx, yy) => Owner.Map[x + xx, y + yy].ObjType == tile.ObjType).Bits));
                            def.Stats.Stats = stats.ToArray();
                        }
                    }
                    ret.Add(def);
                }
            }
            return ret;
        }

        private IEnumerable<IntPoint> GetRemovedStatics(int _x, int _y)
        {
            foreach (IntPoint i in clientStatic)
            {
                int dx = i.X - _x;
                int dy = i.Y - _y;
                WmapTile tile = Owner.Map[i.X, i.Y];
                if (dx*dx + dy*dy > RADIUS*RADIUS ||
                    tile.ObjType == 0)
                {
                    int objId = Owner.Map[i.X, i.Y].ObjId;
                    if (objId != 0)
                        yield return i;
                }
            }
        }

        private void SendUpdate(RealmTime time)
        {
            mapWidth = Owner.Map.Width;
            mapHeight = Owner.Map.Height;
            Wmap map = Owner.Map;
            var _x = (int) X;
            var _y = (int) Y;

            var sendEntities = new HashSet<Entity>(GetNewEntities());

            var list = new List<UpdatePacket.TileData>(APPOX_AREA_OF_SIGHT);
            int sent = 0;
            foreach (IntPoint i in Sight.GetSightCircle(RADIUS))
            {
                int x = i.X + _x;
                int y = i.Y + _y;

                bool sightblockedx = false;
                bool sightblockedy = false;
                bool sightblockedxy = false;
                bool sightblockedyx = false;

                WmapTile tile;
                ObjectDesc desc;

                if (x < 0 || x >= mapWidth ||
                    y < 0 || y >= mapHeight ||
                    map[x, y].TileId == 0xff ||
                    tiles[x, y] >= (tile = map[x, y]).UpdateCount) continue;

                World world = Manager.GetWorld(Owner.Id);
                if (world.Dungeon)
                {
                    if (x < X)
                    {
                        for (int XX = _x; XX > x; XX--)
                        {
                            Manager.GameData.ObjectDescs.TryGetValue(map[XX, _y].ObjType, out desc);
                            if (desc != null)
                            {
                                if (desc.BlocksSight)
                                {
                                    sightblockedx = true;
                                }
                            }
                        }
                    }
                    if (x > X)
                    {
                        for (int XX = _x; XX < x; XX++)
                        {
                            Manager.GameData.ObjectDescs.TryGetValue(map[XX, _y].ObjType, out desc);
                            if (desc != null)
                            {
                                if (desc.BlocksSight)
                                {
                                    sightblockedx = true;
                                }
                            }
                        }
                    }
                    if (y < Y)
                    {
                        for (int YY = _y; YY > y; YY--)
                        {
                            Manager.GameData.ObjectDescs.TryGetValue(map[_x, YY].ObjType, out desc);
                            if (desc != null)
                            {
                                if (desc.BlocksSight)
                                {
                                    sightblockedy = true;
                                }
                            }
                        }
                    }
                    if (y > Y)
                    {
                        for (int YY = _y; YY < y; YY++)
                        {
                            Manager.GameData.ObjectDescs.TryGetValue(map[_x, YY].ObjType, out desc);
                            if (desc != null)
                            {
                                if (desc.BlocksSight)
                                {
                                    sightblockedy = true;
                                }
                            }
                        }
                    }
                    if (x < X)
                    {
                        for (int XX = _x; XX > x; XX--)
                        {
                            Manager.GameData.ObjectDescs.TryGetValue(map[XX, y].ObjType, out desc);
                            if (desc != null)
                            {
                                if (desc.BlocksSight)
                                {
                                    sightblockedyx = true;
                                }
                            }
                        }
                    }
                    if (x > X)
                    {
                        for (int XX = _x; XX < x; XX++)
                        {
                            Manager.GameData.ObjectDescs.TryGetValue(map[XX, y].ObjType, out desc);
                            if (desc != null)
                            {
                                if (desc.BlocksSight)
                                {
                                    sightblockedyx = true;
                                }
                            }
                        }
                    }

                    if (y < Y)
                    {
                        for (int YY = _y; YY > y; YY--)
                        {
                            Manager.GameData.ObjectDescs.TryGetValue(map[x, YY].ObjType, out desc);
                            if (desc != null)
                            {
                                if (desc.BlocksSight)
                                {
                                    sightblockedxy = true;
                                }
                            }
                        }
                    }
                    if (y > Y)
                    {
                        for (int YY = _y; YY < y; YY++)
                        {
                            Manager.GameData.ObjectDescs.TryGetValue(map[x, YY].ObjType, out desc);
                            if (desc != null)
                            {
                                if (desc.BlocksSight)
                                {
                                    sightblockedxy = true;
                                }
                            }
                        }
                    }

                    if ((sightblockedy && sightblockedxy) || (sightblockedx && sightblockedyx) ||
                        (sightblockedyx && sightblockedxy))
                    {
                        desc = null;
                        continue;
                    }
                    desc = null;
                }

                list.Add(new UpdatePacket.TileData
                {
                    X = (short) x,
                    Y = (short) y,
                    Tile = (Tile) tile.TileId
                });
                tiles[x, y] = tile.UpdateCount;
                sent++;
            }
            fames.TileSent(sent);

            var dropEntities = GetRemovedEntities().Distinct().ToArray();
            clientEntities.RemoveWhere(_ => Array.IndexOf(dropEntities, _.Id) != -1);

            foreach (var i in sendEntities)
                lastUpdate[i] = i.UpdateCount;

            ObjectDef[] newStatics = GetNewStatics(_x, _y).ToArray();
            IntPoint[] removeStatics = GetRemovedStatics(_x, _y).ToArray();
            var removedIds = new List<int>();
            foreach (IntPoint i in removeStatics)
            {
                removedIds.Add(Owner.Map[i.X, i.Y].ObjId);
                clientStatic.Remove(i);
            }

            if (sendEntities.Count > 0 || list.Count > 0 || dropEntities.Length > 0 ||
                newStatics.Length > 0 || removedIds.Count > 0)
            {
                var packet = new UpdatePacket();
                packet.Tiles = list.ToArray();
                packet.NewObjects = sendEntities.Select(_ => _.ToDefinition()).Concat(newStatics).ToArray();
                packet.RemovedObjectIds = dropEntities.Concat(removedIds).ToArray();
                client.SendPacket(packet);
            }
            SendNewTick(time);
        }

        private void SendNewTick(RealmTime time)
        {
            var sendEntities = new List<Entity>();
            foreach (Entity i in clientEntities)
            {
                if (i.UpdateCount > lastUpdate[i])
                {
                    sendEntities.Add(i);
                    lastUpdate[i] = i.UpdateCount;
                }
            }
            if (questEntity != null &&
                (!lastUpdate.ContainsKey(questEntity) || questEntity.UpdateCount > lastUpdate[questEntity]))
            {
                sendEntities.Add(questEntity);
                lastUpdate[questEntity] = questEntity.UpdateCount;
            }
            var p = new NewTickPacket();
            tickId++;
            p.TickId = tickId;
            p.TickTime = time.thisTickTimes;
            p.UpdateStatuses = sendEntities.Select(_ => _.ExportStats()).ToArray();
            client.SendPacket(p);
        }
    }
}
Posts 1–15 of 27 · Page 1 of 2

Post a Reply

Similar Threads

Tags for this Thread

None

Talk with us