private void AddTileToRenderList(GameObject obj, int worldX, int worldY, bool useObjectHandles, int maxZ) { for (; obj != null; obj = obj.Right) { if (obj.CurrentRenderIndex == _renderIndex || obj.IsDestroyed || !obj.AllowedToDraw) { continue; } if (_updateDrawPosition && obj.CurrentRenderIndex != _renderIndex || obj.IsPositionChanged) { obj.UpdateRealScreenPosition(_offset); } //obj.UseInRender = 0xFF; float drawX = obj.RealScreenPosition.X; float drawY = obj.RealScreenPosition.Y; if (drawX < _minPixel.X || drawX > _maxPixel.X) { break; } int z = obj.Z; int maxObjectZ = obj.PriorityZ; bool ismobile = false; StaticTiles itemData = default; bool changinAlpha = false; switch (obj) { case Mobile _: maxObjectZ += Constants.DEFAULT_CHARACTER_HEIGHT; ismobile = true; break; default: if (GameObjectHelper.TryGetStaticData(obj, out itemData)) { if (obj is Static st) { if (StaticFilters.IsCave(st.OriginalGraphic)) { if (Engine.Profile.Current.EnableCaveBorder && !st.IsBordered()) { st.SetBorder(true); } else if (!Engine.Profile.Current.EnableCaveBorder && st.IsBordered()) { st.SetBorder(false); } } else if (StaticFilters.IsTree(st.OriginalGraphic)) { if (Engine.Profile.Current.TreeToStumps && st.Graphic != Constants.TREE_REPLACE_GRAPHIC) { st.SetGraphic(Constants.TREE_REPLACE_GRAPHIC); } else if (st.OriginalGraphic != st.Graphic && !Engine.Profile.Current.TreeToStumps) { st.RestoreOriginalGraphic(); } } } if (_noDrawRoofs && itemData.IsRoof) { if (_alphaChanged) { changinAlpha = obj.ProcessAlpha(0); } else { changinAlpha = obj.AlphaHue != 0; } if (!changinAlpha) { continue; } } if ((Engine.Profile.Current.TreeToStumps && itemData.IsFoliage) || (Engine.Profile.Current.HideVegetation && StaticFilters.IsVegetation(obj.Graphic))) { continue; } maxObjectZ += itemData.Height; } break; } if (maxObjectZ > maxZ) { break; } obj.CurrentRenderIndex = _renderIndex; bool iscorpse = !ismobile && obj is Item item && item.IsCorpse; if (!ismobile && !iscorpse && itemData.IsInternal) { continue; } bool island = !ismobile && !iscorpse && obj is Land; if (!island && z >= _maxZ) { if (!changinAlpha) { if (_alphaChanged) { changinAlpha = obj.ProcessAlpha(0); } else { changinAlpha = obj.AlphaHue != 0; } if (!changinAlpha) { continue; } } } int testMinZ = (int)drawY + z * 4; int testMaxZ = (int)drawY; if (island) { Land t = obj as Land; if (t.IsStretched) { testMinZ -= t.MinZ * 4; } else { testMinZ = testMaxZ; } } else { testMinZ = testMaxZ; } if (testMinZ < _minPixel.Y || testMaxZ > _maxPixel.Y) { continue; } if (obj.OverheadMessageContainer != null && !obj.OverheadMessageContainer.IsEmpty) { _overheadManager.AddOverhead(obj.OverheadMessageContainer); } if (ismobile || iscorpse) { AddOffsetCharacterTileToRenderList(obj, useObjectHandles); } else if (itemData.IsFoliage) { bool check = World.Player.X <= worldX && World.Player.Y <= worldY; if (!check) { check = World.Player.Y <= worldY && World.Player.Position.X <= worldX + 1; if (!check) { check = World.Player.X <= worldX && World.Player.Y <= worldY + 1; } } if (check) { Rectangle rect = new Rectangle((int)drawX - obj.FrameInfo.X, (int)drawY - obj.FrameInfo.Y, obj.FrameInfo.Width, obj.FrameInfo.Height); Rectangle r = World.Player.GetOnScreenRectangle(); check = Exstentions.InRect(ref rect, ref r); } if (obj is Static st) { st.CharacterIsBehindFoliage = check; } else if (obj is Multi m) { m.CharacterIsBehindFoliage = check; } else if (obj is Item it) { it.CharacterIsBehindFoliage = check; } } if (_alphaChanged && !changinAlpha) { if (itemData.IsTranslucent) { obj.ProcessAlpha(178); } else if (!itemData.IsFoliage && obj.AlphaHue != 0xFF) { obj.ProcessAlpha(0xFF); } } if (_renderListCount >= _renderList.Length) { int newsize = _renderList.Length + 1000; //_renderList.Resize(newsize); Array.Resize(ref _renderList, newsize); } if (useObjectHandles) { obj.UseObjectHandles = (ismobile || iscorpse || obj is Item it && !it.IsLocked && !it.IsMulti) && !obj.ClosedObjectHandles; _objectHandlesCount++; } else if (obj.ClosedObjectHandles) { obj.ClosedObjectHandles = false; obj.ObjectHandlesOpened = false; } else if (obj.UseObjectHandles) { obj.ObjectHandlesOpened = false; obj.UseObjectHandles = false; } //ref var weak = ref _renderList[_renderListCount]; //if (weak == null) // weak = new WeakReference<GameObject>(obj); //else // weak.SetTarget(obj); _renderList[_renderListCount] = obj; //_renderList.Enqueue(obj); //obj.UseInRender = (byte) _renderIndex; _renderListCount++; } }
private void AddTileToRenderList(GameObject obj, int worldX, int worldY, bool useObjectHandles, int maxZ) { for (; obj != null; obj = obj.Right) { if (obj.CurrentRenderIndex == _renderIndex || obj.IsDisposed) { continue; } if (_updateDrawPosition && obj.CurrentRenderIndex != _renderIndex || obj.IsPositionChanged) { obj.UpdateRealScreenPosition(_offset); } //obj.UseInRender = 0xFF; float drawX = obj.RealScreenPosition.X; float drawY = obj.RealScreenPosition.Y; if (drawX < _minPixel.X || drawX > _maxPixel.X) { break; } int z = obj.Z; int maxObjectZ = obj.PriorityZ; bool mounted = false; bool ismobile = false; StaticTiles itemData = default; bool changinAlpha = false; switch (obj) { case Mobile mob: maxObjectZ += Constants.DEFAULT_CHARACTER_HEIGHT; ismobile = true; mounted = mob.IsMounted; break; default: if (GameObjectHelper.TryGetStaticData(obj, out itemData)) { if (obj is Static st) { if (StaticFilters.IsCave(st.OriginalGraphic)) { if (Engine.Profile.Current.EnableCaveBorder && !st.IsBordered()) { st.SetBorder(true); } else if (!Engine.Profile.Current.EnableCaveBorder && st.IsBordered()) { st.SetBorder(false); } } else if (StaticFilters.IsTree(st.OriginalGraphic)) { if (Engine.Profile.Current.TreeToStumps && st.Graphic != Constants.TREE_REPLACE_GRAPHIC) { st.SetGraphic(Constants.TREE_REPLACE_GRAPHIC); } else if (st.OriginalGraphic != st.Graphic && !Engine.Profile.Current.TreeToStumps) { st.RestoreOriginalGraphic(); } } } if (_noDrawRoofs && itemData.IsRoof) { if (_alphaChanged) { changinAlpha = obj.ProcessAlpha(0); } else { changinAlpha = obj.AlphaHue != 0; } if (!changinAlpha) { continue; } } if ((Engine.Profile.Current.TreeToStumps && itemData.IsFoliage) || (Engine.Profile.Current.HideVegetation && StaticFilters.IsVegetation(obj.Graphic))) { continue; } maxObjectZ += itemData.Height; } break; } if (maxObjectZ > maxZ) { break; } obj.CurrentRenderIndex = _renderIndex; bool iscorpse = !ismobile && obj is Item item && item.IsCorpse; if (!ismobile && !iscorpse && itemData.IsInternal) { continue; } bool island = !ismobile && !iscorpse && obj is Land; if (!island && z >= _maxZ) { if (!changinAlpha) { if (_alphaChanged) { changinAlpha = obj.ProcessAlpha(0); } else { changinAlpha = obj.AlphaHue != 0; } if (!changinAlpha) { continue; } } } int testMinZ = (int)drawY + z * 4; int testMaxZ = (int)drawY; if (island) { Land t = obj as Land; if (t.IsStretched) { testMinZ -= t.MinZ * 4; } else { testMinZ = testMaxZ; } } else { testMinZ = testMaxZ; } if (testMinZ < _minPixel.Y || testMaxZ > _maxPixel.Y) { continue; } if (obj.HasOverheads && obj.Overheads.Count != 0) { int offY; if (ismobile && !mounted || iscorpse) { offY = -22; } else { switch (obj) { case Multi _: case Static _: offY = -44; break; //case Item _: // offY = 44; //break; default: offY = 0; break; } } for (int i = 0; i < obj.Overheads.Count; i++) { TextOverhead v = obj.Overheads[i]; //v.RealScreenPosition.X = drawX; //v.RealScreenPosition.Y = drawY; ref var bounds = ref v.Bounds; bounds.X = (v.Texture.Width / 2) - 22; bounds.Y = offY + v.Texture.Height; bounds.Width = v.Texture.Width; bounds.Height = v.Texture.Height; Overheads.AddOverhead(v); offY += v.Texture.Height; if (_alphaChanged) { if (v.TimeToLive > 0 && v.TimeToLive <= Constants.TIME_FADEOUT_TEXT) { if (!v.IsOverlapped) { v.ProcessAlpha(0); } } else if (!v.IsOverlapped && v.AlphaHue != 0xFF) { v.ProcessAlpha(0xFF); } } } } if (ismobile || iscorpse) { AddOffsetCharacterTileToRenderList(obj, useObjectHandles); } else if (itemData.IsFoliage) { if (obj is Static st) { bool check = World.Player.X <= worldX && World.Player.Y <= worldY; if (!check) { check = World.Player.Y <= worldY && World.Player.Position.X <= worldX + 1; if (!check) { check = World.Player.X <= worldX && World.Player.Y <= worldY + 1; } } if (check) { Rectangle rect = new Rectangle((int)drawX - st.FrameInfo.X, (int)drawY - st.FrameInfo.Y, st.FrameInfo.Width, st.FrameInfo.Height); Rectangle r = World.Player.GetOnScreenRectangle(); check = Exstentions.InRect(ref rect, ref r); } st.CharacterIsBehindFoliage = check; } else if (obj is Multi m) { bool check = World.Player.X <= worldX && World.Player.Y <= worldY; if (!check) { check = World.Player.Y <= worldY && World.Player.Position.X <= worldX + 1; if (!check) { check = World.Player.X <= worldX && World.Player.Y <= worldY + 1; } } if (check) { Rectangle rect = new Rectangle((int)drawX - m.FrameInfo.X, (int)drawY - m.FrameInfo.Y, m.FrameInfo.Width, m.FrameInfo.Height); var r = World.Player.GetOnScreenRectangle(); check = Exstentions.InRect(ref rect, ref r); } m.CharacterIsBehindFoliage = check; } } if (_alphaChanged && !changinAlpha) { if (itemData.IsTranslucent) { obj.ProcessAlpha(178); } else if (!itemData.IsFoliage && obj.AlphaHue != 0xFF) { obj.ProcessAlpha(0xFF); } } if (_renderListCount >= _renderList.Length) { int newsize = _renderList.Length + 1000; //_renderList.Resize(newsize); Array.Resize(ref _renderList, newsize); } if (useObjectHandles) { obj.UseObjectHandles = (ismobile || iscorpse || obj is Item it && !it.IsLocked && !it.IsMulti) && !obj.ClosedObjectHandles; _objectHandlesCount++; } else if (obj.ClosedObjectHandles) { obj.ClosedObjectHandles = false; obj.ObjectHandlesOpened = false; } else if (obj.UseObjectHandles) { obj.ObjectHandlesOpened = false; obj.UseObjectHandles = false; } ref var weak = ref _renderList[_renderListCount];
private void AddTileToRenderList(GameObject obj, int worldX, int worldY, bool useObjectHandles, int maxZ /*, GameObject entity*/) { /*sbyte HeightChecks = 0; * if(entity != null) * { * if(entity.X < worldX && entity.Y > worldY) * { * HeightChecks = 1; * } * else if (entity.Y < worldY && entity.X > worldX) * { * HeightChecks = -1; * } * }*/ for (; obj != null; obj = obj.Right) { if (obj.CurrentRenderIndex == _renderIndex || !obj.AllowedToDraw) { continue; } if (UpdateDrawPosition && obj.CurrentRenderIndex != _renderIndex || obj.IsPositionChanged) { obj.UpdateRealScreenPosition(_offset.X, _offset.Y); } obj.UseInRender = 0xFF; int drawX = obj.RealScreenPosition.X; int drawY = obj.RealScreenPosition.Y; if (drawX < _minPixel.X || drawX > _maxPixel.X) { break; } int maxObjectZ = obj.PriorityZ; StaticTiles itemData = _emptyStaticTiles; bool changinAlpha = false; bool island = false; bool iscorpse = false; bool ismobile = false; switch (obj) { case Mobile _: maxObjectZ += Constants.DEFAULT_CHARACTER_HEIGHT; ismobile = true; break; case Land _: island = true; goto SKIP_HANDLES_CHECK; case Item it when it.IsCorpse: iscorpse = true; goto default; default: if (GameObjectHelper.TryGetStaticData(obj, out itemData)) { if (itemData.IsFoliage && World.Season >= Seasons.Winter) { continue; } if (obj is Static st) { if (StaticFilters.IsTree(st.OriginalGraphic)) { if (Engine.Profile.Current.TreeToStumps && st.Graphic != Constants.TREE_REPLACE_GRAPHIC) { st.SetGraphic(Constants.TREE_REPLACE_GRAPHIC); } else if (st.OriginalGraphic != st.Graphic && !Engine.Profile.Current.TreeToStumps) { st.RestoreOriginalGraphic(); } } } if (_noDrawRoofs && itemData.IsRoof) { if (_alphaChanged) { changinAlpha = obj.ProcessAlpha(0); } else { changinAlpha = obj.AlphaHue != 0; } if (!changinAlpha) { continue; } } if (Engine.Profile.Current.TreeToStumps && itemData.IsFoliage || Engine.Profile.Current.HideVegetation && StaticFilters.IsVegetation(obj.Graphic)) { continue; } //if (HeightChecks <= 0 && (!itemData.IsBridge || ((itemData.Flags & TileFlag.StairBack | TileFlag.StairRight) != 0) || itemData.IsWall)) { maxObjectZ += itemData.Height; } } break; } if (useObjectHandles && NameOverHeadManager.IsAllowed(obj as Entity)) { obj.UseObjectHandles = (ismobile || iscorpse || obj is Item it && (!it.IsLocked || it.IsLocked && itemData.IsContainer) && !it.IsMulti) && !obj.ClosedObjectHandles && _objectHandlesCount <= 400; if (obj.UseObjectHandles) { _objectHandlesCount++; } } else if (obj.ClosedObjectHandles) { obj.ClosedObjectHandles = false; obj.ObjectHandlesOpened = false; } else if (obj.UseObjectHandles) { obj.ObjectHandlesOpened = false; obj.UseObjectHandles = false; } SKIP_HANDLES_CHECK: if (maxObjectZ > maxZ) { break; } obj.CurrentRenderIndex = _renderIndex; if (!island) { obj.UpdateTextCoords(); } else { goto SKIP_INTERNAL_CHECK; } if (!ismobile && !iscorpse && !island && itemData.IsInternal) { continue; } SKIP_INTERNAL_CHECK: int z = obj.Z; if (!island && z >= _maxZ) { if (!changinAlpha) { if (_alphaChanged) { changinAlpha = obj.ProcessAlpha(0); } else { changinAlpha = obj.AlphaHue != 0; } if (!changinAlpha) { obj.UseInRender = (byte)_renderIndex; continue; } } } int testMaxZ = drawY; if (testMaxZ > _maxPixel.Y) { continue; } int testMinZ = drawY + (z << 2); if (island) { Land t = obj as Land; if (t.IsStretched) { testMinZ -= t.MinZ << 2; } else { testMinZ = testMaxZ; } } else { testMinZ = testMaxZ; } if (testMinZ < _minPixel.Y) { continue; } if (ismobile || iscorpse) { AddOffsetCharacterTileToRenderList(obj, useObjectHandles); } else if (!island && itemData.IsFoliage) { bool check = World.Player.X <= worldX && World.Player.Y <= worldY; if (!check) { check = World.Player.Y <= worldY && World.Player.X <= worldX + 1; if (!check) { check = World.Player.X <= worldX && World.Player.Y <= worldY + 1; } } if (check) { _rectangleObj.X = drawX - obj.FrameInfo.X; _rectangleObj.Y = drawY - obj.FrameInfo.Y; _rectangleObj.Width = obj.FrameInfo.Width; _rectangleObj.Height = obj.FrameInfo.Height; check = Exstentions.InRect(ref _rectangleObj, ref _rectanglePlayer); } switch (obj) { case Static st: st.CharacterIsBehindFoliage = check; break; case Multi m: m.CharacterIsBehindFoliage = check; break; case Item it: it.CharacterIsBehindFoliage = check; break; } } if (!island && _alphaChanged && !changinAlpha) { if (itemData.IsTranslucent) { obj.ProcessAlpha(178); } else if (!itemData.IsFoliage && obj.AlphaHue != 0xFF) { obj.ProcessAlpha(0xFF); } } if (_renderListCount >= _renderList.Length) { int newsize = _renderList.Length + 1000; Array.Resize(ref _renderList, newsize); } _renderList[_renderListCount++] = obj; obj.UseInRender = (byte)_renderIndex; } }