Esempio n. 1
0
        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);
            }
        }
Esempio n. 2
0
 public RendererCellContents(RendererCellContents contents, int density)
 {
     Type     = contents.Type;
     Density  = density;
     Info     = contents.Info;
     Sequence = contents.Sequence;
     Palette  = contents.Palette;
 }
Esempio n. 3
0
 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);
     }
 }
Esempio n. 4
0
        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);
                }
            }
        }
Esempio n. 5
0
        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);
                }
            }
        }
Esempio n. 6
0
        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());
            }
        }
Esempio n. 7
0
        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());
            }
        }