public CursorSequence(SpriteCache cache, string cursorSrc, string palette, MiniYaml info) { sprites = cache[cursorSrc]; var d = info.ToDictionary(); start = Exts.ParseIntegerInvariant(d["start"].Value); this.palette = palette; if ((d.ContainsKey("length") && d["length"].Value == "*") || (d.ContainsKey("end") && d["end"].Value == "*")) length = sprites.Length - start; else if (d.ContainsKey("length")) length = Exts.ParseIntegerInvariant(d["length"].Value); else if (d.ContainsKey("end")) length = Exts.ParseIntegerInvariant(d["end"].Value) - start; else length = 1; if (d.ContainsKey("x")) Exts.TryParseIntegerInvariant(d["x"].Value, out Hotspot.X); if (d.ContainsKey("y")) Exts.TryParseIntegerInvariant(d["y"].Value, out Hotspot.Y); }
public virtual ISpriteSequence CreateSequence(ModData modData, TileSet tileSet, SpriteCache cache, string sequence, string animation, MiniYaml info) { return(new DefaultSpriteSequence(modData, tileSet, cache, this, sequence, animation, info)); }
public IReadOnlyDictionary <string, ISpriteSequence> ParseSequences(ModData modData, TileSet tileSet, SpriteCache cache, MiniYamlNode node) { var sequences = new Dictionary <string, ISpriteSequence>(); var nodes = node.Value.ToDictionary(); MiniYaml defaults; if (nodes.TryGetValue("Defaults", out defaults)) { nodes.Remove("Defaults"); nodes = nodes.ToDictionary(kv => kv.Key, kv => MiniYaml.Merge(kv.Value, defaults)); // Merge 'Defaults' animation image value. An example follows. // // - Before - // stand: // Facings: 8 // // - After - // stand: e1 // Facings: 8 foreach (var n in nodes) { n.Value.Value = n.Value.Value ?? defaults.Value; } } foreach (var kvp in nodes) { using (new Support.PerfTimer("new Sequence(\"{0}\")".F(node.Key), 20)) { try { sequences.Add(kvp.Key, CreateSequence(modData, tileSet, cache, node.Key, kvp.Key, kvp.Value)); } catch (FileNotFoundException ex) { // Eat the FileNotFound exceptions from missing sprites OnMissingSpriteError(ex.Message); } } } return(new ReadOnlyDictionary <string, ISpriteSequence>(sequences)); }
public override ISpriteSequence CreateSequence(ModData modData, string tileSet, SpriteCache cache, string sequence, string animation, MiniYaml info) { return(new ClassicSpriteSequence(modData, tileSet, cache, this, sequence, animation, info)); }
public DefaultSpriteSequence(ModData modData, TileSet tileSet, SpriteCache cache, ISpriteSequenceLoader loader, string sequence, string animation, MiniYaml info) { Name = animation; Loader = loader; var d = info.ToDictionary(); try { Start = LoadField <int>(d, "Start", 0); ShadowStart = LoadField <int>(d, "ShadowStart", -1); ShadowZOffset = LoadField <WDist>(d, "ShadowZOffset", DefaultShadowSpriteZOffset).Length; ZOffset = LoadField <WDist>(d, "ZOffset", WDist.Zero).Length; Tick = LoadField <int>(d, "Tick", 40); transpose = LoadField <bool>(d, "Transpose", false); Frames = LoadField <int[]>(d, "Frames", null); var flipX = LoadField <bool>(d, "FlipX", false); var flipY = LoadField <bool>(d, "FlipY", false); Facings = LoadField <int>(d, "Facings", 1); if (Facings < 0) { reverseFacings = true; Facings = -Facings; } var offset = LoadField <float2>(d, "Offset", float2.Zero); var blendMode = LoadField <BlendMode>(d, "BlendMode", BlendMode.Alpha); MiniYaml combine; if (d.TryGetValue("Combine", out combine)) { var combined = Enumerable.Empty <Sprite>(); foreach (var sub in combine.Nodes) { var sd = sub.Value.ToDictionary(); // Allow per-sprite offset, start, and length var subStart = LoadField <int>(sd, "Start", 0); var subOffset = LoadField <float2>(sd, "Offset", float2.Zero); var subFlipX = LoadField <bool>(sd, "FlipX", false); var subFlipY = LoadField <bool>(sd, "FlipY", false); var subSrc = GetSpriteSrc(modData, tileSet, sequence, animation, sub.Key, sd); var subSprites = cache[subSrc].Select( s => new Sprite(s.Sheet, FlipRectangle(s.Bounds, subFlipX, subFlipY), s.Offset + subOffset + offset, s.Channel, blendMode)); var subLength = 0; MiniYaml subLengthYaml; if (sd.TryGetValue("Length", out subLengthYaml) && subLengthYaml.Value == "*") { subLength = subSprites.Count() - subStart; } else { subLength = LoadField <int>(sd, "Length", 1); } combined = combined.Concat(subSprites.Skip(subStart).Take(subLength)); } sprites = combined.ToArray(); } else { // Apply offset to each sprite in the sequence // Different sequences may apply different offsets to the same frame var src = GetSpriteSrc(modData, tileSet, sequence, animation, info.Value, d); sprites = cache[src].Select( s => new Sprite(s.Sheet, FlipRectangle(s.Bounds, flipX, flipY), s.Offset + offset, s.Channel, blendMode)).ToArray(); } MiniYaml length; if (d.TryGetValue("Length", out length) && length.Value == "*") { Length = sprites.Length - Start; } else { Length = LoadField <int>(d, "Length", 1); } // Plays the animation forwards, and then in reverse if (LoadField <bool>(d, "Reverses", false)) { var frames = Frames ?? Exts.MakeArray(Length, i => Start + i); Frames = frames.Concat(frames.Skip(1).Take(frames.Length - 2).Reverse()).ToArray(); Length = 2 * Length - 2; } Stride = LoadField <int>(d, "Stride", Length); if (Length > Stride) { throw new InvalidOperationException( "{0}: Sequence {1}.{2}: Length must be <= stride" .F(info.Nodes[0].Location, sequence, animation)); } if (Start < 0 || Start + Facings * Stride > sprites.Length) { throw new InvalidOperationException( "{5}: Sequence {0}.{1} uses frames [{2}..{3}], but only 0..{4} actually exist" .F(sequence, animation, Start, Start + Facings * Stride - 1, sprites.Length - 1, info.Nodes[0].Location)); } if (ShadowStart + Facings * Stride > sprites.Length) { throw new InvalidOperationException( "{5}: Sequence {0}.{1}'s shadow frames use frames [{2}..{3}], but only [0..{4}] actually exist" .F(sequence, animation, ShadowStart, ShadowStart + Facings * Stride - 1, sprites.Length - 1, info.Nodes[0].Location)); } } catch (FormatException f) { throw new FormatException("Failed to parse sequences for {0}.{1} at {2}:\n{3}".F(sequence, animation, info.Nodes[0].Location, f)); } }
public IReadOnlyDictionary <string, ISpriteSequence> ParseSequences(ModData modData, TileSet tileSet, SpriteCache cache, MiniYamlNode node) { var sequences = new Dictionary <string, ISpriteSequence>(); var nodes = node.Value.ToDictionary(); MiniYaml defaults; if (nodes.TryGetValue("Defaults", out defaults)) { nodes.Remove("Defaults"); foreach (var n in nodes) { n.Value.Nodes = MiniYaml.Merge(new[] { defaults.Nodes, n.Value.Nodes }); n.Value.Value = n.Value.Value ?? defaults.Value; } } foreach (var kvp in nodes) { using (new Support.PerfTimer("new Sequence(\"{0}\")".F(node.Key), 20)) { try { sequences.Add(kvp.Key, CreateSequence(modData, tileSet, cache, node.Key, kvp.Key, kvp.Value)); } catch (FileNotFoundException ex) { // Eat the FileNotFound exceptions from missing sprites OnMissingSpriteError(ex.Message); } } } return(new ReadOnlyDictionary <string, ISpriteSequence>(sequences)); }
public TilesetSpecificSpriteSequence(ModData modData, TileSet tileSet, SpriteCache cache, ISpriteSequenceLoader loader, string sequence, string animation, MiniYaml info) : base(modData, tileSet, cache, loader, sequence, animation, info) { }
public DefaultSpriteSequence(ModData modData, TileSet tileSet, SpriteCache cache, ISpriteSequenceLoader loader, string sequence, string animation, MiniYaml info) { Name = animation; Loader = loader; var d = info.ToDictionary(); try { Start = LoadField(d, "Start", 0); ShadowStart = LoadField(d, "ShadowStart", -1); ShadowZOffset = LoadField(d, "ShadowZOffset", DefaultShadowSpriteZOffset).Length; ZOffset = LoadField(d, "ZOffset", WDist.Zero).Length; ZRamp = LoadField(d, "ZRamp", 0); Tick = LoadField(d, "Tick", 40); transpose = LoadField(d, "Transpose", false); Frames = LoadField <int[]>(d, "Frames", null); useClassicFacingFudge = LoadField(d, "UseClassicFacingFudge", false); var flipX = LoadField(d, "FlipX", false); var flipY = LoadField(d, "FlipY", false); Facings = LoadField(d, "Facings", 1); if (Facings < 0) { reverseFacings = true; Facings = -Facings; } if (useClassicFacingFudge && Facings != 32) { throw new InvalidOperationException( "{0}: Sequence {1}.{2}: UseClassicFacingFudge is only valid for 32 facings" .F(info.Nodes[0].Location, sequence, animation)); } var offset = LoadField(d, "Offset", float3.Zero); var blendMode = LoadField(d, "BlendMode", BlendMode.Alpha); MiniYaml combine; if (d.TryGetValue("Combine", out combine)) { var combined = Enumerable.Empty <Sprite>(); foreach (var sub in combine.Nodes) { var sd = sub.Value.ToDictionary(); // Allow per-sprite offset, flipping, start, and length var subStart = LoadField(sd, "Start", 0); var subOffset = LoadField(sd, "Offset", float3.Zero); var subFlipX = LoadField(sd, "FlipX", false); var subFlipY = LoadField(sd, "FlipY", false); var subSrc = GetSpriteSrc(modData, tileSet, sequence, animation, sub.Key, sd); var subSprites = cache[subSrc].Select( s => new Sprite(s.Sheet, FlipRectangle(s.Bounds, subFlipX, subFlipY), ZRamp, new float3(subFlipX ? -s.Offset.X : s.Offset.X, subFlipY ? -s.Offset.Y : s.Offset.Y, s.Offset.Z) + subOffset + offset, s.Channel, blendMode)); var subLength = 0; MiniYaml subLengthYaml; if (sd.TryGetValue("Length", out subLengthYaml) && subLengthYaml.Value == "*") { subLength = subSprites.Count() - subStart; } else { subLength = LoadField(sd, "Length", 1); } combined = combined.Concat(subSprites.Skip(subStart).Take(subLength)); } sprites = combined.ToArray(); } else { // Apply offset to each sprite in the sequence // Different sequences may apply different offsets to the same frame var src = GetSpriteSrc(modData, tileSet, sequence, animation, info.Value, d); sprites = cache[src].Select( s => new Sprite(s.Sheet, FlipRectangle(s.Bounds, flipX, flipY), ZRamp, new float3(flipX ? -s.Offset.X : s.Offset.X, flipY ? -s.Offset.Y : s.Offset.Y, s.Offset.Z) + offset, s.Channel, blendMode)).ToArray(); } var depthSprite = LoadField <string>(d, "DepthSprite", null); if (!string.IsNullOrEmpty(depthSprite)) { var depthSpriteFrame = LoadField(d, "DepthSpriteFrame", 0); var depthOffset = LoadField(d, "DepthSpriteOffset", float2.Zero); var depthSprites = cache.AllCached(depthSprite) .Select(s => s[depthSpriteFrame]); sprites = sprites.Select(s => { // The depth sprite must live on the same sheet as the main sprite var ds = depthSprites.FirstOrDefault(dss => dss.Sheet == s.Sheet); if (ds == null) { // The sequence has probably overflowed onto a new sheet. // Allocating a new depth sprite on this sheet will almost certainly work ds = cache.Reload(depthSprite)[depthSpriteFrame]; depthSprites = cache.AllCached(depthSprite) .Select(ss => ss[depthSpriteFrame]); // If that doesn't work then we may be referencing a cached sprite from an earlier sheet // TODO: We could try and reallocate the main sprite, but that requires more complicated code and a perf hit // We'll only cross that bridge if this becomes a problem in reality if (ds.Sheet != s.Sheet) { throw new SheetOverflowException("Cross-sheet depth sprite reference: {0}.{1}: {2}"); } } var cw = (ds.Bounds.Left + ds.Bounds.Right) / 2 + (int)(s.Offset.X + depthOffset.X); var ch = (ds.Bounds.Top + ds.Bounds.Bottom) / 2 + (int)(s.Offset.Y + depthOffset.Y); var w = s.Bounds.Width / 2; var h = s.Bounds.Height / 2; var r = Rectangle.FromLTRB(cw - w, ch - h, cw + w, ch + h); return(new SpriteWithSecondaryData(s, r, ds.Channel)); }).ToArray(); } MiniYaml length; if (d.TryGetValue("Length", out length) && length.Value == "*") { Length = sprites.Length - Start; } else { Length = LoadField(d, "Length", 1); } // Plays the animation forwards, and then in reverse if (LoadField(d, "Reverses", false)) { var frames = Frames ?? Exts.MakeArray(Length, i => Start + i); Frames = frames.Concat(frames.Skip(1).Take(frames.Length - 2).Reverse()).ToArray(); Length = 2 * Length - 2; } Stride = LoadField(d, "Stride", Length); if (Length > Stride) { throw new InvalidOperationException( "{0}: Sequence {1}.{2}: Length must be <= stride" .F(info.Nodes[0].Location, sequence, animation)); } if (Frames != null && Length > Frames.Length) { throw new InvalidOperationException( "{0}: Sequence {1}.{2}: Length must be <= Frames.Length" .F(info.Nodes[0].Location, sequence, animation)); } if (Start < 0 || Start + Facings * Stride > sprites.Length) { throw new InvalidOperationException( "{5}: Sequence {0}.{1} uses frames [{2}..{3}], but only 0..{4} actually exist" .F(sequence, animation, Start, Start + Facings * Stride - 1, sprites.Length - 1, info.Nodes[0].Location)); } if (ShadowStart + Facings * Stride > sprites.Length) { throw new InvalidOperationException( "{5}: Sequence {0}.{1}'s shadow frames use frames [{2}..{3}], but only [0..{4}] actually exist" .F(sequence, animation, ShadowStart, ShadowStart + Facings * Stride - 1, sprites.Length - 1, info.Nodes[0].Location)); } } catch (FormatException f) { throw new FormatException("Failed to parse sequences for {0}.{1} at {2}:\n{3}".F(sequence, animation, info.Nodes[0].Location, f)); } }
public DefaultSpriteSequence(ModData modData, TileSet tileSet, SpriteCache cache, ISpriteSequenceLoader loader, string sequence, string animation, MiniYaml info) { this.sequence = sequence; Name = animation; Loader = loader; var d = info.ToDictionary(); try { Start = LoadField(d, "Start", 0); ShadowStart = LoadField(d, "ShadowStart", -1); ShadowZOffset = LoadField(d, "ShadowZOffset", DefaultShadowSpriteZOffset).Length; ZOffset = LoadField(d, "ZOffset", WDist.Zero).Length; ZRamp = LoadField(d, "ZRamp", 0); Tick = LoadField(d, "Tick", 40); transpose = LoadField(d, "Transpose", false); Frames = LoadField <int[]>(d, "Frames", null); IgnoreWorldTint = LoadField(d, "IgnoreWorldTint", false); var flipX = LoadField(d, "FlipX", false); var flipY = LoadField(d, "FlipY", false); Facings = LoadField(d, "Facings", 1); if (Facings < 0) { reverseFacings = true; Facings = -Facings; } var offset = LoadField(d, "Offset", float3.Zero); var blendMode = LoadField(d, "BlendMode", BlendMode.Alpha); Func <int, IEnumerable <int> > getUsedFrames = frameCount => { MiniYaml length; if (d.TryGetValue("Length", out length) && length.Value == "*") { Length = Frames != null ? Frames.Length : frameCount - Start; } else { Length = LoadField(d, "Length", 1); } // Plays the animation forwards, and then in reverse if (LoadField(d, "Reverses", false)) { var frames = Frames != null?Frames.Skip(Start).Take(Length).ToArray() : Exts.MakeArray(Length, i => Start + i); Frames = frames.Concat(frames.Skip(1).Take(Length - 2).Reverse()).ToArray(); Length = 2 * Length - 2; Start = 0; } Stride = LoadField(d, "Stride", Length); if (Length > Stride) { throw new InvalidOperationException( "{0}: Sequence {1}.{2}: Length must be <= stride" .F(info.Nodes[0].Location, sequence, animation)); } if (Frames != null && Length > Frames.Length) { throw new InvalidOperationException( "{0}: Sequence {1}.{2}: Length must be <= Frames.Length" .F(info.Nodes[0].Location, sequence, animation)); } var end = Start + (Facings - 1) * Stride + Length - 1; if (Frames != null) { foreach (var f in Frames) { if (f < 0 || f >= frameCount) { throw new InvalidOperationException( "{5}: Sequence {0}.{1} defines a Frames override that references frame {4}, but only [{2}..{3}] actually exist" .F(sequence, animation, Start, end, f, info.Nodes[0].Location)); } } if (Start < 0 || end >= Frames.Length) { throw new InvalidOperationException( "{5}: Sequence {0}.{1} uses indices [{2}..{3}] of the Frames list, but only {4} frames are defined" .F(sequence, animation, Start, end, Frames.Length, info.Nodes[0].Location)); } } else if (Start < 0 || end >= frameCount) { throw new InvalidOperationException( "{5}: Sequence {0}.{1} uses frames [{2}..{3}], but only 0..{4} actually exist" .F(sequence, animation, Start, end, frameCount - 1, info.Nodes[0].Location)); } if (ShadowStart >= 0 && ShadowStart + (Facings - 1) * Stride + Length > frameCount) { throw new InvalidOperationException( "{5}: Sequence {0}.{1}'s shadow frames use frames [{2}..{3}], but only [0..{4}] actually exist" .F(sequence, animation, ShadowStart, ShadowStart + (Facings - 1) * Stride + Length - 1, frameCount - 1, info.Nodes[0].Location)); } var usedFrames = new List <int>(); for (var facing = 0; facing < Facings; facing++) { for (var frame = 0; frame < Length; frame++) { var i = transpose ? (frame % Length) * Facings + facing : (facing * Stride) + (frame % Length); usedFrames.Add(Frames != null ? Frames[i] : Start + i); } } if (ShadowStart >= 0) { return(usedFrames.Concat(usedFrames.Select(i => i + ShadowStart - Start))); } return(usedFrames); }; MiniYaml combine; if (d.TryGetValue("Combine", out combine)) { var combined = Enumerable.Empty <Sprite>(); foreach (var sub in combine.Nodes) { var sd = sub.Value.ToDictionary(); // Allow per-sprite offset, flipping, start, and length var subStart = LoadField(sd, "Start", 0); var subOffset = LoadField(sd, "Offset", float3.Zero); var subFlipX = LoadField(sd, "FlipX", false); var subFlipY = LoadField(sd, "FlipY", false); var subFrames = LoadField <int[]>(sd, "Frames", null); var subLength = 0; Func <int, IEnumerable <int> > subGetUsedFrames = subFrameCount => { MiniYaml subLengthYaml; if (sd.TryGetValue("Length", out subLengthYaml) && subLengthYaml.Value == "*") { subLength = subFrames != null ? subFrames.Length : subFrameCount - subStart; } else { subLength = LoadField(sd, "Length", 1); } return(subFrames != null?subFrames.Skip(subStart).Take(subLength) : Enumerable.Range(subStart, subLength)); }; var subSrc = GetSpriteSrc(modData, tileSet, sequence, animation, sub.Key, sd); var subSprites = cache[subSrc, subGetUsedFrames].Select( s => s != null ? new Sprite(s.Sheet, FlipRectangle(s.Bounds, subFlipX, subFlipY), ZRamp, new float3(subFlipX ? -s.Offset.X : s.Offset.X, subFlipY ? -s.Offset.Y : s.Offset.Y, s.Offset.Z) + subOffset + offset, s.Channel, blendMode) : null).ToList(); var frames = subFrames != null?subFrames.Skip(subStart).Take(subLength).ToArray() : Exts.MakeArray(subLength, i => subStart + i); combined = combined.Concat(frames.Select(i => subSprites[i])); } sprites = combined.ToArray(); getUsedFrames(sprites.Length); } else { // Apply offset to each sprite in the sequence // Different sequences may apply different offsets to the same frame var src = GetSpriteSrc(modData, tileSet, sequence, animation, info.Value, d); sprites = cache[src, getUsedFrames].Select( s => s != null ? new Sprite(s.Sheet, FlipRectangle(s.Bounds, flipX, flipY), ZRamp, new float3(flipX ? -s.Offset.X : s.Offset.X, flipY ? -s.Offset.Y : s.Offset.Y, s.Offset.Z) + offset, s.Channel, blendMode) : null).ToArray(); } var depthSprite = LoadField <string>(d, "DepthSprite", null); if (!string.IsNullOrEmpty(depthSprite)) { var depthSpriteFrame = LoadField(d, "DepthSpriteFrame", 0); var depthOffset = LoadField(d, "DepthSpriteOffset", float2.Zero); Func <int, IEnumerable <int> > getDepthFrame = _ => new int[] { depthSpriteFrame }; var ds = cache[depthSprite, getDepthFrame][depthSpriteFrame]; sprites = sprites.Select(s => { if (s == null) { return(null); } var cw = (ds.Bounds.Left + ds.Bounds.Right) / 2 + (int)(s.Offset.X + depthOffset.X); var ch = (ds.Bounds.Top + ds.Bounds.Bottom) / 2 + (int)(s.Offset.Y + depthOffset.Y); var w = s.Bounds.Width / 2; var h = s.Bounds.Height / 2; var r = Rectangle.FromLTRB(cw - w, ch - h, cw + w, ch + h); return(new SpriteWithSecondaryData(s, ds.Sheet, r, ds.Channel)); }).ToArray(); } var exportPalette = LoadField <string>(d, "EmbeddedPalette", null); if (exportPalette != null) { var src = GetSpriteSrc(modData, tileSet, sequence, animation, info.Value, d); var metadata = cache.FrameMetadata(src); var i = Frames != null ? Frames[0] : Start; var palettes = metadata != null?metadata.GetOrDefault <EmbeddedSpritePalette>() : null; if (palettes == null || !palettes.TryGetPaletteForFrame(i, out EmbeddedPalette)) { throw new YamlException("Cannot export palettes from {0}: frame {1} does not define an embedded palette".F(src, i)); } } var boundSprites = SpriteBounds(sprites, Frames, Start, Facings, Length, Stride, transpose); if (ShadowStart > 0) { boundSprites = boundSprites.Concat(SpriteBounds(sprites, Frames, ShadowStart, Facings, Length, Stride, transpose)); } Bounds = boundSprites.Union(); } catch (FormatException f) { throw new FormatException("Failed to parse sequences for {0}.{1} at {2}:\n{3}".F(sequence, animation, info.Nodes[0].Location, f)); } }
public void drawSpriteCache(SpriteCache sc, int i) { throw new System.NotImplementedException(); }
public override ISpriteSequence CreateSequence(ModData modData, TileSet tileSet, SpriteCache cache, string sequence, string animation, MiniYaml info) { return(new ExtendedTilesetSpecificSpriteSequence(modData, tileSet, cache, this, sequence, animation, info)); }
private static ScreenBuffer AmbientOcclusion(AABB view, Layer layer, Light[] lights, AABB[] obstacles, int pixelSize) { var data = SpriteCache.Get(layer.DataMapId); var color = SpriteCache.Get(layer.ColorMapId); var viewMin = view.Min.Round(); var viewSize = view.Size.Round(); var sdl2Renderer = Renderer.Instance as SDL2Renderer; // ambient occlusion var aoSize = viewSize / pixelSize; var aoBuffer = sdl2Renderer.CreateScreenBuffer(BufferEnum.AmbientOcclusion1, aoSize); var aoBufferLength = aoBuffer.Data.Length / 4; Parallel.For(0, aoBufferLength, (i, loopState) => { var aoPixel = new Vector2i(i % aoSize.X, i / aoSize.X); var aoIndex = ((aoSize.Y - aoPixel.Y - 1) * aoSize.X + aoPixel.X) * 4; var screenPixel = aoPixel * pixelSize + new Vector2i(pixelSize / 2); var pixelColor = RayTracing.AmbientOcclusion(viewMin + screenPixel, obstacles, probeDistance: 128, rayCount: 4); var finalColor = new Color4b(pixelColor); aoBuffer.Data[aoIndex + 0] = finalColor.A; aoBuffer.Data[aoIndex + 1] = finalColor.B; aoBuffer.Data[aoIndex + 2] = finalColor.G; aoBuffer.Data[aoIndex + 3] = finalColor.R; }); // ambient occlusion & color var viewBuffer = sdl2Renderer.CreateScreenBuffer(BufferEnum.AmbientOcclusion1, viewSize); var viewBufferLength = viewBuffer.Data.Length / 4; Parallel.For(0, viewBufferLength, (i, loopState) => { var viewPixel = new Vector2i(i % viewSize.X, i / viewSize.X); var viewIndex = ((viewSize.Y - viewPixel.Y - 1) * viewSize.X + viewPixel.X) * 4; var colorIndex = (viewMin.Y + viewPixel.Y) * data.Size.X + viewMin.X + viewPixel.X; if (color.Data[colorIndex + 0] > 0) { var aoPixel = viewPixel / pixelSize; var aoIndex = ((aoSize.Y - aoPixel.Y - 1) * aoSize.X + aoPixel.X) * 4; var pixelColor = new Color4f(color.Data[colorIndex]); var aoColor = new Color4f(new Color4b( aoBuffer.Data[aoIndex + 3], aoBuffer.Data[aoIndex + 2], aoBuffer.Data[aoIndex + 1], aoBuffer.Data[aoIndex + 0]).AsUint); var finalColor = new Color4b(pixelColor * aoColor); viewBuffer.Data[viewIndex + 0] = finalColor.A; viewBuffer.Data[viewIndex + 1] = finalColor.B; viewBuffer.Data[viewIndex + 2] = finalColor.G; viewBuffer.Data[viewIndex + 3] = finalColor.R; } else { // just alpha channel viewBuffer.Data[viewIndex] = 0; } }); return(viewBuffer); }
public IReadOnlyDictionary <string, ISpriteSequence> ParseSequences(ModData modData, string tileSet, SpriteCache cache, MiniYamlNode node) { var sequences = new Dictionary <string, ISpriteSequence>(); var nodes = node.Value.ToDictionary(); try { if (nodes.TryGetValue("Defaults", out var defaults)) { nodes.Remove("Defaults"); foreach (var n in nodes) { n.Value.Nodes = MiniYaml.Merge(new[] { defaults.Nodes, n.Value.Nodes }); n.Value.Value = n.Value.Value ?? defaults.Value; } } } catch (Exception e) { throw new InvalidDataException($"Error occurred while parsing {node.Key}", e); } foreach (var kvp in nodes) { using (new Support.PerfTimer($"new Sequence(\"{node.Key}\")", 20)) { try { sequences.Add(kvp.Key, CreateSequence(modData, tileSet, cache, node.Key, kvp.Key, kvp.Value)); } catch (FileNotFoundException ex) { // Defer exception until something tries to access the sequence // This allows the asset installer and OpenRA.Utility to load the game without having the actor assets sequences.Add(kvp.Key, new FileNotFoundSequence(ex)); } } } return(new ReadOnlyDictionary <string, ISpriteSequence>(sequences)); }
void Start() { show(uiMain); // 给主界面按钮加事件 string canvasPath = "main/ui/uiMain/Canvas/buttons/"; levelButton = GameObject.Find(canvasPath + "level2").GetComponent <Button>(); levelButton.onClick.AddListener(delegate() { // 打开level 界面 // Debug.Log("open level window"); Sound.playSound(SoundType.Click); openLevelWindow(); }); unlimitButton = GameObject.Find(canvasPath + "unlimit2").GetComponent <Button>(); unlimitButton.onClick.AddListener(delegate() { // 打开unlimit 界面 Debug.Log("open unlimit window"); Sound.playSound(SoundType.Click); openUnlimitWindow(); }); onlineButton = GameObject.Find(canvasPath + "online2").GetComponent <Button>(); onlineButton.onClick.AddListener(delegate() { //Job.startJob(Params.energyJobKey, delegate() { // Debug.Log("sdfsdfsdfs"); //},10); // 打开online 界面 Debug.Log("open online window"); Sound.playSound(SoundType.Click); openOnlineWindow(); }); // uiLevel 关闭按钮 GameObject closeGo = GameObject.Find("main/ui/uiLevel/Canvas/close"); Button closeButton = closeGo.GetComponent <Button> (); closeButton.onClick.AddListener(delegate() { Sound.playSound(SoundType.Click); show(uiMain); }); // uiUnlimit 关闭按钮和进入按钮 Button go = GameObject.Find("main/ui/uiUnlimit/Canvas/go").GetComponent <Button>(); go.onClick.AddListener(delegate() { Sound.playSound(SoundType.Click); CSUnlimitedGo unlimitedGo = new CSUnlimitedGo(); SocketManager.SendMessageAsyc((int)MiGongOpcode.CSUnlimitedGo, CSUnlimitedGo.SerializeToBytes(unlimitedGo), delegate(int opcode, byte[] data) { ui.SetActive(false); SCUnlimitedGo ret = SCUnlimitedGo.Deserialize(data); // 剩余精力 Params.startEnergySchedule(ret.Energy.Energy, ret.Energy.RefreshTime); int[] stars = { ret.Star1, ret.Star2, ret.Star3, ret.Star4 }; createMap(MapMode.Unlimited, ret.Map.ToArray(), ret.Beans, ret.Time, ret.Speed, ret.Start, ret.End, ret.Pass, ret.EnemyCount, null, stars, null, null); }); }); closeButton = GameObject.Find("main/ui/uiUnlimit/Canvas/close").GetComponent <Button>(); closeButton.onClick.AddListener(delegate() { Sound.playSound(SoundType.Click); show(uiMain); }); // uiOnline 关闭按钮和进入按钮 go = GameObject.Find("main/ui/uiOnline/Canvas/go").GetComponent <Button>(); go.onClick.AddListener(delegate() { Sound.playSound(SoundType.Click); OnPvpClick(); }); closeButton = GameObject.Find("main/ui/uiOnline/Canvas/close").GetComponent <Button>(); closeButton.onClick.AddListener(delegate() { Sound.playSound(SoundType.Click); show(uiMain); }); // 获取登陆基本信息 CSBaseInfo baseInfo = new CSBaseInfo(); SocketManager.SendMessageAsyc((int)MiGongOpcode.CSBaseInfo, CSBaseInfo.SerializeToBytes(baseInfo), delegate(int opcode, byte[] data) { SCBaseInfo ret = SCBaseInfo.Deserialize(data); // TODO 显示精力 // 系统参数 foreach (PBSysPara sp in ret.SysParas) { sysParas.Add(sp.Key, sp.Value); } Params.sysParas = sysParas; Params.energyRecoverTime = int.Parse(sysParas["energyRecoverTime"]); // 精力相关 Params.startEnergySchedule(ret.Energy.Energy, ret.Energy.RefreshTime); foreach (PBNewGuide newGuide in ret.NewGuide) { guideStep.Add(newGuide.Id, newGuide.Step); } this.openPass = ret.OpenPass; // 道具表 Params.init(ret); // 无尽版和pvp是否开启 doShowLock(); // 初始化无尽版的每日星数奖励 //string para = sysParas["unlimitedAwardStar"]; //string[] paras = para.Split(';'); Slider slider = unlimitedAwardGo.transform.Find("starSlider").GetComponent <Slider>(); RectTransform buRec = unlimitedAwardGo.transform.Find("starSlider").GetComponent <RectTransform> (); int len = ret.UnlimitedRewardTable.Count; slider.maxValue = ret.UnlimitedRewardTable[len - 1].Star; Object ob = Resources.Load("chest"); unlimitedAwardSegs = new UnlimitedAwardSeg[len]; for (int i = 0; i < len; i++) { GameObject chestGo = Instantiate(ob) as GameObject; chestGo.transform.localPosition = new Vector3( buRec.rect.width / slider.maxValue * ret.UnlimitedRewardTable[i].Star - buRec.rect.width / 2, 0, 0); chestGo.transform.SetParent(unlimitedAwardGo.transform, false); UnlimitedAwardSeg unlimitedAward = unlimitedAwardSegs[i] = new UnlimitedAwardSeg(); unlimitedAward.star = ret.UnlimitedRewardTable[i].Star; unlimitedAward.image = chestGo.GetComponent <Image>(); Button bt = chestGo.GetComponent <Button>(); int index = i; PBUnlimitedRewardTable table = ret.UnlimitedRewardTable[i]; bt.onClick.AddListener(delegate { Sound.playSound(SoundType.Click); // 如果达到了,就直接领取了,然后就是确定,否则就是显示,然后是确定 if (unlimitedAward.state == 1) { // 领取 Sound.playSound(SoundType.Click); CSUnlimitedAward award = new CSUnlimitedAward(); award.Index = index; SocketManager.SendMessageAsyc((int)MiGongOpcode.CSUnlimitedAward, CSUnlimitedAward.SerializeToBytes(award), (opcode2, data2) => { SCUnlimitedAward retAward = SCUnlimitedAward.Deserialize(data2); unlimitedAward.image.sprite = SpriteCache.getSprite("box/open"); unlimitedAward.state = 2; // 显示 WarnDialog.reward(Message.getText("gainReward"), Message.getText("ok"), table.Gold, table.Reward, null); }); } else { // 显示 WarnDialog.reward(Message.getText("dailyReward"), Message.getText("ok"), table.Gold, table.Reward, null); } }); } }); // 账号,分享,帮助 Button accountButton = GameObject.Find(canvasPath + "more/account").GetComponent <Button>(); accountButton.onClick.AddListener(delegate() { Debug.Log("account"); Sound.playSound(SoundType.Click); closeMorePanel(); doAccount(); }); ssdk.showUserHandler = GetUserInfoResultHandler; Button shareButton = GameObject.Find(canvasPath + "more/share").GetComponent <Button>(); shareButton.onClick.AddListener(delegate() { Debug.Log("share"); // doShare(); Sound.playSound(SoundType.Click); closeMorePanel(); shareWeChat1.transform.parent.gameObject.SetActive(true); }); ssdk.shareHandler = ShareResultHandler; // 分享的三个按钮就 shareWeChat1.onClick.AddListener(delegate() { Debug.Log("share WeChat"); Sound.playSound(SoundType.Click); doShare(PlatformType.WeChat); }); shareWeChat2.onClick.AddListener(delegate() { Debug.Log("share WeChatMoments"); Sound.playSound(SoundType.Click); doShare(PlatformType.WeChatMoments); }); closeShare.onClick.AddListener(delegate() { Sound.playSound(SoundType.Click); shareWeChat1.transform.parent.gameObject.SetActive(false); }); exit.onClick.AddListener(delegate() { Sound.playSound(SoundType.Click); Application.Quit(); }); // show more Button moreButton = GameObject.Find(canvasPath + "moreBt").GetComponent <Button>(); moreButton.onClick.AddListener(delegate() { GameObject moreGo = GameObject.Find(canvasPath + "more"); moreGo.SetActive(!moreGo.activeSelf); }); // hide more Button hideMoreButton = GameObject.Find(canvasPath + "more/clickPanel").GetComponent <Button>(); hideMoreButton.onClick.AddListener(delegate() { closeMorePanel(); }); // Button helpButton = GameObject.Find(canvasPath + "more/help").GetComponent <Button>(); helpButton.onClick.AddListener(delegate() { Debug.Log("help"); // WarnDialog.showWarnDialog("test",null,false,10,20); Sound.playSound(SoundType.Click); closeMorePanel(); Help guideControl = uiHelp.GetComponent <Help>(); guideControl.showHelp(); }); // 背包,商店 Button packetButton = GameObject.Find(canvasPath + "packet").GetComponent <Button>(); packetButton.onClick.AddListener(delegate() { Debug.Log("backet"); Sound.playSound(SoundType.Click); uiPacket.GetComponent <Packet>().showPacket(); }); Button shopButton = GameObject.Find(canvasPath + "shop").GetComponent <Button>(); shopButton.onClick.AddListener(delegate() { Debug.Log("shop"); Sound.playSound(SoundType.Click); uiShop.GetComponent <Shop>().showShop(); }); // 对战中显示奖励界面的进入地图按钮 Button showRewardOk = uiLevel.transform.Find("Canvas/showReward/dialog/ok").GetComponent <Button>(); showRewardOk.onClick.AddListener(delegate() { Sound.playSound(SoundType.Click); onIntoPassClick(); }); Button showRewardClose = uiLevel.transform.Find("Canvas/showReward/dialog/close").GetComponent <Button>(); showRewardClose.onClick.AddListener(delegate() { Sound.playSound(SoundType.Click); uiLevel.transform.Find("Canvas/showReward").gameObject.SetActive(false); }); // 联网对战按钮 // SocketManager.AddServerSendReceive((int)MiGongOpcode.SCMatchingSuccess, matchSuccess); SocketManager.AddServerSendReceive((int)MiGongOpcode.SCMatchingFail, delegate(int opcode, byte[] receiveData) { Debug.Log(""); matching.matchFail(); }); SocketManager.AddServerSendReceive((int)MiGongOpcode.SCBegin, delegate(int opcode, byte[] receiveData) { Debug.Log(""); }); SocketManager.AddServerSendReceive((int)AccountOpcode.SCBeTakePlace, delegate(int opcode, byte[] receiveData) { WarnDialog.showWarnDialog("你的账号在其它地方登录!", delegate() { Application.Quit(); }, true); }); }
private void openUnlimitWindow() { // //获取按钮游戏对象 Object button = Resources.Load("UnlimitItem"); GameObject content = GameObject.Find("main/ui/uiUnlimit/Canvas/scrollView/Viewport/Content"); for (int i = 0; i < content.transform.childCount; i++) { Destroy(content.transform.GetChild(i).gameObject); } // 获取当前关卡 CSUnlimitedInfo unlimitedInfo = new CSUnlimitedInfo(); SocketManager.SendMessageAsyc((int)MiGongOpcode.CSUnlimitedInfo, CSUnlimitedInfo.SerializeToBytes(unlimitedInfo), delegate(int opcode, byte[] data) { show(uiUnlimit); SCUnlimitedInfo ret = SCUnlimitedInfo.Deserialize(data); // Text passText = GameObject.Find("main/ui/uiUnlimit/Canvas/pass").GetComponent <Text>(); passText.text = Message.getText("unlimitRankSelf", ret.Pass, ret.Star, ret.Rank); // //GameObject energyTextGo = GameObject.Find ("main/ui/uiUnlimit/Canvas/energy/Text"); //Text energyText = energyTextGo.GetComponent<Text>(); //energyText.text = Params.energy.ToString(); // 每日星数奖励 //ret.TodayStar Slider slider = unlimitedAwardGo.transform.Find("starSlider").GetComponent <Slider>(); slider.value = ret.TodayStar; float step = slider.maxValue / unlimitedAwardSegs.Length; string[] isLight = null; if (ret.Award.Length > 0) { isLight = ret.Award.Split(';'); } for (int i = 0; i < unlimitedAwardSegs.Length; i++) { //Debug.Log(ret.TodayStar + "," + unlimitedAwardSegs[i].star); // 是否还没点亮 if (ret.TodayStar < unlimitedAwardSegs[i].star) { unlimitedAwardSegs[i].image.sprite = SpriteCache.getSprite("box/unreach"); unlimitedAwardSegs[i].state = 0; } else if (isLight != null && int.Parse(isLight[i]) > 0) { unlimitedAwardSegs[i].image.sprite = SpriteCache.getSprite("box/open"); unlimitedAwardSegs[i].state = 2; } else { unlimitedAwardSegs[i].image.sprite = SpriteCache.getSprite("box/reach"); unlimitedAwardSegs[i].state = 1; } } // 列表 int count = ret.UnlimitedRankInfo.Count; float dis = 0f; GameObject up = Instantiate(button) as GameObject; RectTransform buRec = up.GetComponent <RectTransform> (); Destroy(up); RectTransform contentTrans = content.GetComponent <RectTransform> (); contentTrans.sizeDelta = new Vector2(0, (buRec.rect.height + dis) * count + dis); for (int i = 0; i < count; i++) { PBUnlimitedRankInfo info = ret.UnlimitedRankInfo[i]; up = Instantiate(button) as GameObject; up.transform.localPosition = new Vector3(0, -((buRec.rect.height + dis) * i + dis), 0); up.transform.localScale = new Vector3(1, 1, 1); up.transform.SetParent(content.transform, false); // 生成各个玩家的排名item GameObject textGo = up.transform.Find("rank").gameObject; Text text = textGo.GetComponent <Text> (); text.text = info.Rank + ""; //text.text = Message.getText("unlimitRankItem",info.Rank,info.UserName,info.Star); textGo = up.transform.Find("name").gameObject; text = textGo.GetComponent <Text>(); text.text = info.UserName + ""; textGo = up.transform.Find("pass").gameObject; text = textGo.GetComponent <Text>(); text.text = info.Pass + ""; textGo = up.transform.Find("star").gameObject; text = textGo.GetComponent <Text>(); text.text = info.Star + ""; } }); }
public ClientImpl() { this.spriteCache = new SpriteCache(); }