The actor and smudge definitions are now stored as raw MiniYamlNodes in the map. It is now the responsibility of the consumers to parse these into real objects.
159 lines
3.9 KiB
C#
159 lines
3.9 KiB
C#
#region Copyright & License Information
|
|
/*
|
|
* Copyright 2007-2015 The OpenRA Developers (see AUTHORS)
|
|
* This file is part of OpenRA, which is free software. It is made
|
|
* available to you under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation. For more information,
|
|
* see COPYING.
|
|
*/
|
|
#endregion
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using OpenRA.Graphics;
|
|
using OpenRA.Mods.Common.Effects;
|
|
using OpenRA.Traits;
|
|
|
|
namespace OpenRA.Mods.Common.Traits
|
|
{
|
|
[Desc("Attach this to the world actor.", "Order of the layers defines the Z sorting.")]
|
|
public class SmudgeLayerInfo : ITraitInfo
|
|
{
|
|
public readonly string Type = "Scorch";
|
|
|
|
[Desc("Sprite sequence name")]
|
|
public readonly string Sequence = "scorch";
|
|
|
|
public readonly int SmokePercentage = 25;
|
|
|
|
[Desc("Sprite sequence name")]
|
|
public readonly string SmokeType = "smoke_m";
|
|
|
|
public readonly string SmokePalette = "effect";
|
|
|
|
public readonly string Palette = "terrain";
|
|
|
|
public object Create(ActorInitializer init) { return new SmudgeLayer(this); }
|
|
}
|
|
|
|
public class SmudgeLayer : IRenderOverlay, IWorldLoaded, ITickRender
|
|
{
|
|
struct Smudge
|
|
{
|
|
public string Type;
|
|
public int Depth;
|
|
public Sprite Sprite;
|
|
}
|
|
|
|
public SmudgeLayerInfo Info;
|
|
Dictionary<CPos, Smudge> tiles;
|
|
Dictionary<CPos, Smudge> dirty;
|
|
Dictionary<string, Sprite[]> smudges;
|
|
World world;
|
|
|
|
public SmudgeLayer(SmudgeLayerInfo info)
|
|
{
|
|
this.Info = info;
|
|
}
|
|
|
|
public void WorldLoaded(World w, WorldRenderer wr)
|
|
{
|
|
world = w;
|
|
tiles = new Dictionary<CPos, Smudge>();
|
|
dirty = new Dictionary<CPos, Smudge>();
|
|
smudges = new Dictionary<string, Sprite[]>();
|
|
|
|
var types = world.Map.SequenceProvider.Sequences(Info.Sequence);
|
|
foreach (var t in types)
|
|
{
|
|
var seq = world.Map.SequenceProvider.GetSequence(Info.Sequence, t);
|
|
var sprites = Exts.MakeArray(seq.Length, x => seq.GetSprite(x));
|
|
smudges.Add(t, sprites);
|
|
}
|
|
|
|
// Add map smudges
|
|
foreach (var s in w.Map.SmudgeDefinitions)
|
|
{
|
|
var name = s.Key;
|
|
var vals = name.Split(' ');
|
|
var type = vals[0];
|
|
|
|
if (!smudges.ContainsKey(type))
|
|
continue;
|
|
|
|
var loc = vals[1].Split(',');
|
|
var cell = new CPos(Exts.ParseIntegerInvariant(loc[0]), Exts.ParseIntegerInvariant(loc[1]));
|
|
var depth = Exts.ParseIntegerInvariant(vals[2]);
|
|
|
|
var smudge = new Smudge
|
|
{
|
|
Type = type,
|
|
Depth = depth,
|
|
Sprite = smudges[type][depth]
|
|
};
|
|
|
|
tiles.Add(cell, smudge);
|
|
}
|
|
}
|
|
|
|
public void AddSmudge(CPos loc)
|
|
{
|
|
if (Game.CosmeticRandom.Next(0, 100) <= Info.SmokePercentage)
|
|
world.AddFrameEndTask(w => w.Add(new Smoke(w, world.Map.CenterOfCell(loc), Info.SmokeType, Info.SmokePalette)));
|
|
|
|
if (!dirty.ContainsKey(loc) && !tiles.ContainsKey(loc))
|
|
{
|
|
// No smudge; create a new one
|
|
var st = smudges.Keys.Random(world.SharedRandom);
|
|
dirty[loc] = new Smudge { Type = st, Depth = 0, Sprite = smudges[st][0] };
|
|
}
|
|
else
|
|
{
|
|
// Existing smudge; make it deeper
|
|
var tile = dirty.ContainsKey(loc) ? dirty[loc] : tiles[loc];
|
|
var maxDepth = smudges[tile.Type].Length;
|
|
if (tile.Depth < maxDepth - 1)
|
|
{
|
|
tile.Depth++;
|
|
tile.Sprite = smudges[tile.Type][tile.Depth];
|
|
}
|
|
|
|
dirty[loc] = tile;
|
|
}
|
|
}
|
|
|
|
public void TickRender(WorldRenderer wr, Actor self)
|
|
{
|
|
var remove = new List<CPos>();
|
|
foreach (var kv in dirty)
|
|
{
|
|
if (!self.World.FogObscures(kv.Key))
|
|
{
|
|
tiles[kv.Key] = kv.Value;
|
|
remove.Add(kv.Key);
|
|
}
|
|
}
|
|
|
|
foreach (var r in remove)
|
|
dirty.Remove(r);
|
|
}
|
|
|
|
public void Render(WorldRenderer wr)
|
|
{
|
|
var pal = wr.Palette(Info.Palette);
|
|
|
|
foreach (var kv in tiles)
|
|
{
|
|
if (!wr.Viewport.VisibleCells.Contains(kv.Key))
|
|
continue;
|
|
|
|
if (world.ShroudObscures(kv.Key))
|
|
continue;
|
|
|
|
new SpriteRenderable(kv.Value.Sprite, world.Map.CenterOfCell(kv.Key),
|
|
WVec.Zero, -511, pal, 1f, true).Render(wr); // TODO ZOffset is ignored
|
|
}
|
|
}
|
|
}
|
|
}
|