protected virtual void UpdateRenderedSprite(CPos cell, RendererCellContents content) { var density = content.Density; var type = content.Type; if (content.Density > 0) { // The call chain for this method (that starts with AddDirtyCell()) guarantees // that the new content type would still be suitable for this renderer, // but that is a bit too fragile to rely on in case the code starts changing. if (!Info.RenderTypes.Contains(type.Info.Type)) { return; } var sprites = type.Variants[content.Variant]; var maxDensity = type.Info.MaxDensity; var frame = int2.Lerp(0, sprites.Length - 1, density, maxDensity); UpdateSpriteLayers(cell, sprites, frame, type.Palette); } else { UpdateSpriteLayers(cell, null, 0, null); } }
public RendererCellContents(RendererCellContents contents, int density) { Type = contents.Type; Density = density; Info = contents.Info; Sequence = contents.Sequence; Palette = contents.Palette; }
protected virtual void UpdateRenderedSprite(CPos cell, RendererCellContents content) { if (content.Density > 0) { var maxDensity = ResourceLayer.GetMaxDensity(content.Type); var frame = int2.Lerp(0, content.Sequence.Length - 1, content.Density, maxDensity); UpdateSpriteLayers(cell, content.Sequence, frame, content.Palette); } else { UpdateSpriteLayers(cell, null, 0, null); } }
void IWorldLoaded.WorldLoaded(World w, WorldRenderer wr) { var resources = w.WorldActor.TraitsImplementing <ResourceType>() .ToDictionary(r => r.Info.ResourceType, r => r); foreach (var r in resources) { if (spriteLayer == null) { var first = r.Value.Variants.First().Value.GetSprite(0); var emptySprite = new Sprite(first.Sheet, Rectangle.Empty, TextureChannel.Alpha); spriteLayer = new TerrainSpriteLayer(w, wr, emptySprite, first.BlendMode, wr.World.Type != WorldType.Editor); } if (shadowLayer == null) { var firstWithShadow = r.Value.Variants.Values.FirstOrDefault(v => v.ShadowStart > 0); if (firstWithShadow != null) { var first = firstWithShadow.GetShadow(0, WAngle.Zero); var emptySprite = new Sprite(first.Sheet, Rectangle.Empty, TextureChannel.Alpha); shadowLayer = new TerrainSpriteLayer(w, wr, emptySprite, first.BlendMode, wr.World.Type != WorldType.Editor); } } // All resources must share a blend mode var sprites = r.Value.Variants.Values.SelectMany(v => Exts.MakeArray(v.Length, x => v.GetSprite(x))); if (sprites.Any(s => s.BlendMode != spriteLayer.BlendMode)) { throw new InvalidDataException("Resource sprites specify different blend modes. " + "Try using different ResourceRenderer traits for resource types that use different blend modes."); } } // Initialize the RenderContent with the initial map state // because the shroud may not be enabled. foreach (var cell in w.Map.AllCells) { var type = ResourceLayer.GetResource(cell).Type; if (type != null && Info.RenderTypes.Contains(type.Info.Type)) { var resourceContent = ResourceLayer.GetResource(cell); var rendererCellContents = new RendererCellContents(ChooseRandomVariant(resourceContent.Type), resourceContent.Type, resourceContent.Density); RenderContent[cell] = rendererCellContents; UpdateRenderedSprite(cell, rendererCellContents); } } }
void IWorldLoaded.WorldLoaded(World w, WorldRenderer wr) { var resources = w.WorldActor.TraitsImplementing <ResourceType>() .ToDictionary(r => r.Info.ResourceType, r => r); // Build the sprite layer dictionary for rendering resources // All resources that have the same palette must also share a sheet and blend mode foreach (var r in resources) { var layer = spriteLayers.GetOrAdd(r.Value.Palette, pal => { var first = r.Value.Variants.First().Value.GetSprite(0); return(new TerrainSpriteLayer(w, wr, first.Sheet, first.BlendMode, pal, wr.World.Type != WorldType.Editor)); }); // Validate that sprites are compatible with this layer var sheet = layer.Sheet; var sprites = r.Value.Variants.Values.SelectMany(v => Exts.MakeArray(v.Length, x => v.GetSprite(x))); if (sprites.Any(s => s.Sheet != sheet)) { throw new InvalidDataException("Resource sprites span multiple sheets. Try loading their sequences earlier."); } var blendMode = layer.BlendMode; if (sprites.Any(s => s.BlendMode != blendMode)) { throw new InvalidDataException("Resource sprites specify different blend modes. " + "Try using different palettes for resource types that use different blend modes."); } } // Initialize the RenderContent with the initial map state // because the shroud may not be enabled. foreach (var cell in w.Map.AllCells) { var type = ResourceLayer.GetResourceType(cell); if (type != null && Info.RenderTypes.Contains(type.Info.Type)) { var resourceContent = ResourceLayer.GetResource(cell); var rendererCellContents = new RendererCellContents(ChooseRandomVariant(resourceContent.Type), resourceContent.Type, resourceContent.Density); RenderContent[cell] = rendererCellContents; UpdateRenderedSprite(cell, rendererCellContents); } } }
void ITickRender.TickRender(WorldRenderer wr, Actor self) { foreach (var cell in dirty) { if (self.World.FogObscures(cell)) { continue; } var resourceContent = ResourceLayer.GetResource(cell); if (resourceContent.Density > 0) { var cellContents = RenderContent[cell]; var variant = cellContents.Variant; if (cellContents.Variant == null || cellContents.Type != resourceContent.Type) { variant = ChooseRandomVariant(resourceContent.Type); } var rendererCellContents = new RendererCellContents(variant, resourceContent.Type, resourceContent.Density); RenderContent[cell] = rendererCellContents; UpdateRenderedSprite(cell, rendererCellContents); } else { var rendererCellContents = RendererCellContents.Empty; RenderContent[cell] = rendererCellContents; UpdateRenderedSprite(cell, rendererCellContents); } cleanDirty.Enqueue(cell); } while (cleanDirty.Count > 0) { dirty.Remove(cleanDirty.Dequeue()); } }
void ITickRender.TickRender(WorldRenderer wr, Actor self) { foreach (var cell in dirty) { if (!ResourceLayer.IsVisible(cell)) { continue; } var rendererCellContents = RendererCellContents.Empty; var contents = ResourceLayer.GetResource(cell); if (contents.Density > 0) { rendererCellContents = RenderContents[cell]; // Contents are the same, so just update the density if (rendererCellContents.Type == contents.Type) { rendererCellContents = new RendererCellContents(rendererCellContents, contents.Density); } else { rendererCellContents = CreateRenderCellContents(wr, contents, cell); } } RenderContents[cell] = rendererCellContents; UpdateRenderedSprite(cell, rendererCellContents); cleanDirty.Enqueue(cell); } while (cleanDirty.Count > 0) { dirty.Remove(cleanDirty.Dequeue()); } }