protected void FromDungeonGen(int seed, DungeonTemplate template) { Log.InfoFormat("Loading template for world {0}({1})...", Id, Name); var gen = new Generator(seed, template); gen.Generate(); var ras = new Rasterizer(seed, gen.ExportGraph()); ras.Rasterize(); var dTiles = ras.ExportMap(); if (Map == null) { Map = new Wmap(Manager.Resources.GameData); Interlocked.Add(ref _entityInc, Map.Load(dTiles, _entityInc)); if (Blocking == 3) { Sight.CalcRegionBlocks(Map); } } else { Map.ResetTiles(); } InitMap(); }
private void FromWorldMap(Stream dat) { var map = new Wmap(GameServer.Manager.GameData); Map = map; entityInc = 0; entityInc += Map.Load(dat, 0); int w = Map.Width, h = Map.Height; Obstacles = new byte[w, h]; for (var y = 0; y < h; y++) { for (var x = 0; x < w; x++) { try { var tile = Map[x, y]; if (GameServer.Manager.GameData.Tiles[tile.TileId].NoWalk) { Obstacles[x, y] = 3; } if (GameServer.Manager.GameData.ObjectDescs.TryGetValue(tile.ObjType, out ObjectDesc desc)) { if (desc.Class == "Wall" || desc.Class == "ConnectedWall" || desc.Class == "CaveWall") { Obstacles[x, y] = 2; } else if (desc.OccupySquare || desc.EnemyOccupySquare) { Obstacles[x, y] = 1; } } } catch (Exception e) { Log.Error(e.ToString()); } } } EnemiesCollision = new CollisionMap <Entity>(0, w, h); PlayersCollision = new CollisionMap <Entity>(1, w, h); Projectiles.Clear(); GameObjects.Clear(); Enemies.Clear(); Players.Clear(); Entities.Clear(); foreach (var i in Map.InstantiateEntities(GameServer.Manager)) { if (i.ObjectDesc != null && (i.ObjectDesc.OccupySquare || i.ObjectDesc.EnemyOccupySquare)) { Obstacles[(int)(i.X - 0.5), (int)(i.Y - 0.5)] = 2; } EnterWorld(i); } }
public unsafe override void RenderSetPiece(World world, IntPoint pos) { GCHandle h = GCHandle.Alloc(world); IntPtr ptr = GCHandle.ToIntPtr(h); GCHandle mapHandle = GCHandle.Alloc(new Wmap(GameServer.Manager.GameData)); LoadJson(ptr.ToPointer(), mapName, &pos, GCHandle.ToIntPtr(mapHandle).ToPointer()); Wmap map = (mapHandle.Target as Wmap); for (int y = 0; y < map.Height; y++) { for (int x = 0; x < map.Width; x++) { try { if (map[x, y].TileId != 0 && map[x, y].TileId != 255) { var tile = world.Map[x + pos.X, y + pos.Y].Clone(); tile.TileId = map[x, y].TileId; tile.ObjType = map[x, y].ObjType; if (tile.ObjType != 0) { tile.ObjId = world.GetNextEntityId(); } world.Map[x + pos.X, y + pos.Y] = tile; } } catch { } } } }
protected override void TickCore(Entity host, RealmTime time, ref object state) { Status = CycleStatus.NotStarted; if (host.HasConditionEffect(ConditionEffectIndex.Paralyzed)) { return; } Wmap map = host.Owner.Map; WmapTile tile = map[(int)host.X, (int)host.Y]; if (tile.Elevation != 0 && tile.Elevation < altitude) { Vector2 vect; vect = new Vector2(map.Width / 2 - host.X, map.Height / 2 - host.Y); vect.Normalize(); float dist = host.GetSpeed(speed) * (time.thisTickTimes / 1000f); host.ValidateAndMove(host.X + vect.X * dist, host.Y + vect.Y * dist); host.UpdateCount++; Status = CycleStatus.InProgress; } else { Status = CycleStatus.Completed; } }
protected World() { Players = new ConcurrentDictionary<int, Player>(); Enemies = new ConcurrentDictionary<int, Enemy>(); Quests = new ConcurrentDictionary<int, Enemy>(); Projectiles = new ConcurrentDictionary<Tuple<int, byte>, Projectile>(); StaticObjects = new ConcurrentDictionary<int, StaticObject>(); Timers = new List<WorldTimer>(); ClientXML = ExtraXML = Empty<string>.Array; Map = new Wmap(); AllowTeleport = true; ShowDisplays = true; ExtraXML = new string[] { XmlDatas.AdditionXml }; }
//private static int DistSqr(IntPoint a, IntPoint b) //{ // return (a.X - b.X)*(a.X - b.X) + (a.Y - b.Y)*(a.Y - b.Y); //} public static void ApplySetPieces(World world) { if (CheckConfig.IsDebugOn()) { Console.WriteLine("Applying set pieces to world {0}({1}).", world.Id, world.Name); } Wmap map = world.Map; int w = map.Width, h = map.Height; Random rand = new Random(); HashSet <Rect> rects = new HashSet <Rect>(); foreach (Tuple <ISetPiece, int, int, WmapTerrain[]> dat in setPieces) { int size = dat.Item1.Size; int count = rand.Next(dat.Item2, dat.Item3); for (int i = 0; i < count; i++) { IntPoint pt = new IntPoint(); Rect rect; int max = 50; do { pt.X = rand.Next(0, w); pt.Y = rand.Next(0, h); rect = new Rect { x = pt.X, y = pt.Y, w = size, h = size }; max--; } while ((Array.IndexOf(dat.Item4, map[pt.X, pt.Y].Terrain) == -1 || rects.Any(_ => Rect.Intersects(rect, _))) && max > 0); if (max <= 0) { continue; } dat.Item1.RenderSetPiece(world, pt); rects.Add(rect); } } if (CheckConfig.IsDebugOn()) { Console.WriteLine("Set pieces applied."); } }
private unsafe void FromWorldMap(Stream dat, void *world, IntPoint *pos, void *wmap) { Wmap map = (GCHandle.FromIntPtr(new IntPtr(wmap)).Target as Wmap); map.Load(dat, 0); int w = map.Width, h = map.Height; pos->X = ((GCHandle.FromIntPtr(new IntPtr(world)).Target as World).Map.Width / 2) - (w / 2); pos->Y = ((GCHandle.FromIntPtr(new IntPtr(world)).Target as World).Map.Width / 2) - (w / 2); IEnumerable <Entity> ens = map.InstantiateEntities((GCHandle.FromIntPtr(new IntPtr(world)).Target as World).Manager); foreach (Entity i in ens) { i.Move(i.X + pos->X, i.Y + pos->Y); (GCHandle.FromIntPtr(new IntPtr(world)).Target as World).EnterWorld(i); } }
public static void RenderFromProto(World world, IntPoint pos, ProtoWorld proto) { var manager = world.Manager; // get map stream int map = 0; if (proto.maps != null && proto.maps.Length > 1) { var rnd = new Random(); map = rnd.Next(0, proto.maps.Length); } var ms = new MemoryStream(proto.wmap[map]); var sp = new Wmap(manager.Resources.GameData); sp.Load(ms, 0); sp.ProjectOntoWorld(world, pos); }
public static void ApplySetPieces(World world) { log.InfoFormat("Applying set pieces to world {0}({1}).", world.Id, world.Name); Wmap map = world.Map; int w = map.Width, h = map.Height; var rand = new Random(); var rects = new HashSet <Rect>(); foreach (var dat in setPieces) { int size = dat.Item1.Size; int count = rand.Next(dat.Item2, dat.Item3); for (int i = 0; i < count; i++) { var pt = new IntPoint(); Rect rect; int max = 50; do { pt.X = rand.Next(0, w); pt.Y = rand.Next(0, h); rect = new Rect { x = pt.X, y = pt.Y, w = size, h = size }; max--; } while ((Array.IndexOf(dat.Item4, map[pt.X, pt.Y].Terrain) == -1 || rects.Any(_ => Rect.Intersects(rect, _))) && max > 0); if (max <= 0) { continue; } dat.Item1.RenderSetPiece(world, pt); rects.Add(rect); } } log.Info("Set pieces applied."); }
protected override void TickCore(Entity host, RealmTime time, ref object state) { int cool = (int)state; if (cool <= 0) { if (host.HasConditionEffect(ConditionEffectIndex.Stunned)) { return; } Position target = new Position { X = host.X + (float)(range * Math.Cos(angle.Value)), Y = host.Y + (float)(range * Math.Sin(angle.Value)), }; Wmap map = host.Owner.Map; WmapTile tile = map[(int)target.X, (int)target.Y]; if (host.Manager.GameData.Tiles[tile.TileId].NoWalk) { return; } if (target.X < 0 || target.Y < 0) { return; } host.Owner.Timers.Add(new WorldTimer(0, (world, t) => { Entity entity = Entity.Resolve(world.Manager, child); entity.Move(target.X, target.Y); (entity as Enemy).Terrain = (host as Enemy).Terrain; world.EnterWorld(entity); })); cool = coolDown.Next(Random); } else { cool -= time.ElaspedMsDelta; } state = cool; }
protected void FromWorldMap(System.IO.Stream dat) { Log.InfoFormat("Loading map for world {0}({1})...", Id, Name); if (Map == null) { Map = new Wmap(Manager.Resources.GameData); Interlocked.Add(ref _entityInc, Map.Load(dat, _entityInc)); if (Blocking == 3) { Sight.CalcRegionBlocks(Map); } } else { Map.ResetTiles(); } InitMap(); }
public static void ApplySetPieces(World world) { Wmap map = world.Map; int w = map.Width, h = map.Height; Random rand = new Random(); HashSet <Rect> rects = new HashSet <Rect>(); foreach (SetPiece setpiece in SetPieceCache) { int size = setpiece.MapSetPiece.Size; int count = rand.Next(setpiece.Min, setpiece.Max); if (setpiece.IsWeeklyEvent) { if (setpiece.DayOfWeek != DateTime.Now.DayOfWeek) { continue; } } for (int i = 0; i < count; i++) { IntPoint pt = new IntPoint(); Rect rect; do { pt.X = rand.Next(0, w); pt.Y = rand.Next(0, h); rect = new Rect { x = pt.X, y = pt.Y, w = size, h = size }; } while ((Array.IndexOf(setpiece.WmapTerrain, map[pt.X, pt.Y].Terrain) == -1 || rects.Any(_ => Rect.Intersects(rect, _)))); setpiece.MapSetPiece.RenderSetPiece(world, pt); rects.Add(rect); } } }
protected override void TickCore(Entity host, RealmTime time, ref object state) { int cool = (int)state; if (cool <= 0) { if (host.HasConditionEffect(ConditionEffectIndex.Stunned)) { return; } double?tossAngle = randomToss ? Random.Next(0, 360) * Math.PI / 180 : angle; Entity en = null; if (tossAngle == null) { en = host.GetNearestEntity(range, null); } if (tossAngle == null && en == null) { return; } Position target = tossAngle == null ? new Position { X = en.X, Y = en.Y } : new Position { X = host.X + (float)(range * Math.Cos(tossAngle.Value)), Y = host.Y + (float)(range * Math.Sin(tossAngle.Value)), }; Wmap map = host.Owner.Map; WmapTile tile = map[(int)target.X, (int)target.Y]; if (host.Manager.GameData.Tiles[tile.TileId].NoWalk) { return; } if (target.X < 0 || target.Y < 0) { return; } if (!throwProjectileEffect) { host.Owner.BroadcastPacket(new ShowEffectPacket { EffectType = EffectType.Throw, Color = new ARGB(0xffffbf00), TargetObjectId = host.Id, PosA = target }, null); } else { host.Owner.BroadcastPacket(new ShowEffectPacket { EffectType = EffectType.ThrowProjectile, Color = new ARGB(child), PosA = target, PosB = new Position { X = host.X, Y = host.Y } //host pos. }, null); } host.Owner.Timers.Add(new WorldTimer(1500, (world, t) => { Entity entity = Entity.Resolve(world.Manager, child); entity.Move(target.X, target.Y); if (entity is Enemy && host is Enemy) { (entity as Enemy).Terrain = (host as Enemy).Terrain; } world.EnterWorld(entity); })); cool = coolDown.Next(Random); } else { cool -= time.ElaspedMsDelta; } state = cool; }
public bool Delete() { lock (this) { if (Players.Count > 0) return false; Id = 0; } Map = null; Players = null; Enemies = null; Projectiles = null; StaticObjects = null; return true; }
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); int[] dropEntities = GetRemovedEntities().Distinct().ToArray(); clientEntities.RemoveWhere(_ => Array.IndexOf(dropEntities, _.Id) != -1); foreach (Entity 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); }
public void SendUpdate(RealmTime time, int Radius = 15, int aos = (int)(Math.PI *RADIUS *RADIUS + 1)) { mapWidth = Owner.Map.Width; mapHeight = Owner.Map.Height; Wmap map = Owner.Map; aos = (int)(Math.PI * Radius * Radius + 1); int _y; int _x; if (FixedCamera) { _x = (int)CameraX; _y = (int)CameraY; } else { _x = (int)X; _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; WmapTile tile; if (x < 0 || x >= mapWidth || y < 0 || y >= mapHeight || map[x, y].TileId == 0xff || 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++; } fameCounter.TileSent(sent); int[] dropEntities = GetRemovedEntities().Distinct().ToArray(); clientEntities.RemoveWhere(_ => Array.IndexOf(dropEntities, _.Id) != -1); foreach (Entity 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); }
protected void FromWorldMap(Stream dat) { log.InfoFormat("Loading map for world {0}({1})...", Id, Name); Map = new Wmap(Manager.GameData); entityInc = 0; entityInc += Map.Load(dat, 0); int w = Map.Width, h = Map.Height; EnemiesCollision = new CollisionMap<Entity>(0, w, h); PlayersCollision = new CollisionMap<Entity>(1, w, h); Projectiles.Clear(); StaticObjects.Clear(); Enemies.Clear(); Players.Clear(); foreach (Entity i in Map.InstantiateEntities(Manager)) { EnterWorld(i); } }
private void FromWorldMap(Stream dat) { var map = new Wmap(Manager.GameData); Map = map; entityInc = 0; entityInc += Map.Load(dat, 0); int w = Map.Width, h = Map.Height; Obstacles = new byte[w, h]; for (var y = 0; y < h; y++) for (var x = 0; x < w; x++) { try { var tile = Map[x, y]; ObjectDesc desc; if (Manager.GameData.Tiles[tile.TileId].NoWalk) Obstacles[x, y] = 3; if (Manager.GameData.ObjectDescs.TryGetValue(tile.ObjType, out desc)) { if (desc.Class == "Wall" || desc.Class == "ConnectedWall" || desc.Class == "CaveWall") Obstacles[x, y] = 2; else if (desc.OccupySquare || desc.EnemyOccupySquare) Obstacles[x, y] = 1; } } catch (Exception ex) { Log.Error(ex); } } EnemiesCollision = new CollisionMap<Entity>(0, w, h); PlayersCollision = new CollisionMap<Entity>(1, w, h); Projectiles.Clear(); StaticObjects.Clear(); Enemies.Clear(); Players.Clear(); foreach (var i in Map.InstantiateEntities(Manager)) { if (i.ObjectDesc != null && (i.ObjectDesc.OccupySquare || i.ObjectDesc.EnemyOccupySquare)) Obstacles[(int)(i.X - 0.5), (int)(i.Y - 0.5)] = 2; EnterWorld(i); } }
public void HandleUpdate(RealmTime time) { Wmap map = Owner.Map; WmapTile tile; World world = GameServer.Manager.GetWorld(Owner.Id); int xBase = (int)X; int yBase = (int)Y; int sent = 0; HashSet <Entity> sendEntities = new HashSet <Entity>(GetNewEntities()); List <UPDATE.TileData> list = new List <UPDATE.TileData>(APPOX_AREA_OF_SIGHT); mapWidth = Owner.Map.Width; mapHeight = Owner.Map.Height; blocksight = (world.Dungeon ? Sight.RayCast(this, 15) : Sight.GetSightCircle(SIGHTRADIUS)).ToList(); foreach (IntPoint i in blocksight.ToList()) { int x = i.X + xBase; int y = i.Y + yBase; if (x < 0 || x >= mapWidth || y < 0 || y >= mapHeight || tiles[x, y] >= (tile = map[x, y]).UpdateCount) { continue; } if (!visibleTiles.ContainsKey(new IntPoint(x, y))) { visibleTiles[new IntPoint(x, y)] = true; } list.Add(new UPDATE.TileData { X = (short)x, Y = (short)y, Tile = tile.TileId }); tiles[x, y] = tile.UpdateCount; sent++; } FameCounter.TileSent(sent); int[] dropEntities = GetRemovedEntities().Distinct().ToArray(); clientEntities.RemoveWhere(_ => Array.IndexOf(dropEntities, _.Id) != -1); List <Entity> toRemove = lastUpdate.Keys.Where(i => !clientEntities.Contains(i)).ToList(); toRemove.ForEach(i => lastUpdate.TryRemove(i, out int val)); foreach (var i in sendEntities) { lastUpdate[i] = i.UpdateCount; } IEnumerable <ObjectDef> newStatics = GetNewStatics(xBase, yBase); IEnumerable <IntPoint> removeStatics = GetRemovedStatics(xBase, yBase); List <int> removedIds = new List <int>(); if (!world.Dungeon) { foreach (IntPoint i in removeStatics.ToArray()) { removedIds.Add(Owner.Map[i.X, i.Y].ObjId); clientStatic.Remove(i); } } if (sendEntities.Count <= 0 && list.Count <= 0 && dropEntities.Length <= 0 && newStatics.ToArray().Length <= 0 && removedIds.Count <= 0) { return; } UPDATE packet = new UPDATE() { Tiles = list.ToArray(), NewObjects = sendEntities.Select(_ => _.ToDefinition()).Concat(newStatics.ToArray()).ToArray(), RemovedObjectIds = dropEntities.Concat(removedIds).ToArray() }; Client.SendMessage(packet); UpdatesSend++; }
protected void FromWorldMap(System.IO.Stream dat) { Wmap map = new Wmap(); this.Map = map; entityInc = 0; entityInc += map.Load(dat, 0); int w = map.Width, h = map.Height; Obstacles = new byte[w, h]; for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { var tile = map[x, y]; ObjectDesc desc; if (XmlDatas.TileDescs[tile.TileId].NoWalk) Obstacles[x, y] = 3; if (XmlDatas.ObjectDescs.TryGetValue(tile.ObjType, out desc)) { if (desc.Class == "Wall" || desc.Class == "ConnectedWall" || desc.Class == "CaveWall") Obstacles[x, y] = 2; else if (desc.OccupySquare || desc.EnemyOccupySquare) Obstacles[x, y] = 1; } } EnemiesCollision = new CollisionMap<Entity>(0, w, h); PlayersCollision = new CollisionMap<Entity>(1, w, h); Projectiles.Clear(); StaticObjects.Clear(); Enemies.Clear(); Players.Clear(); foreach (var i in map.InstantiateEntities()) { if (i.ObjectDesc != null && (i.ObjectDesc.OccupySquare || i.ObjectDesc.EnemyOccupySquare)) Obstacles[(int)(i.X - 0.5), (int)(i.Y - 0.5)] = 2; EnterWorld(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>(AppoxAreaOfSight); int sent = 0; foreach (IntPoint i in Sight.GetSightCircle(SightRadius)) { 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 || tiles[x, y] >= (tile = map[x, y]).UpdateCount) { continue; } World world = Owner; if (world.IsDungeon()) { if (x < X) { for (int XX = _x; XX > x; XX--) { common.data.XmlDatas.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++) { common.data.XmlDatas.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--) { common.data.XmlDatas.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++) { common.data.XmlDatas.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--) { common.data.XmlDatas.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++) { common.data.XmlDatas.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--) { common.data.XmlDatas.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++) { common.data.XmlDatas.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); int[] dropEntities = GetRemovedEntities().Distinct().ToArray(); _clientEntities.RemoveWhere(_ => Array.IndexOf(dropEntities, _.Id) != -1); //purge unused entities List <Entity> toRemove = new List <Entity>(); foreach (Entity i in _lastUpdate.Keys.Where(i => !_clientEntities.Contains(i))) { toRemove.Add(i); } toRemove.ForEach(i => _lastUpdate.Remove(i)); foreach (Entity 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 { Tiles = list.ToArray(), NewObjects = sendEntities.Select(_ => _.ToDefinition()).Concat(newStatics).ToArray(), RemovedObjectIds = dropEntities.Concat(removedIds).ToArray() }; psr.SendPacket(packet); } }