Merge pull request #2968 from pchote/map-chooser
Map chooser polish & refactoring
This commit is contained in:
@@ -190,7 +190,8 @@ namespace OpenRA
|
|||||||
else
|
else
|
||||||
if (orderManager.NetFrameNumber == 0)
|
if (orderManager.NetFrameNumber == 0)
|
||||||
orderManager.LastTickTime = Environment.TickCount;
|
orderManager.LastTickTime = Environment.TickCount;
|
||||||
|
|
||||||
|
world.TickRender(worldRenderer);
|
||||||
viewport.Tick();
|
viewport.Tick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -217,6 +217,7 @@
|
|||||||
<Compile Include="World.cs" />
|
<Compile Include="World.cs" />
|
||||||
<Compile Include="WorldUtils.cs" />
|
<Compile Include="WorldUtils.cs" />
|
||||||
<Compile Include="Network\ReplayRecorderConnection.cs" />
|
<Compile Include="Network\ReplayRecorderConnection.cs" />
|
||||||
|
<Compile Include="Widgets\TooltipContainerWidget.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">
|
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ namespace OpenRA.Traits
|
|||||||
}
|
}
|
||||||
|
|
||||||
public interface ITick { void Tick(Actor self); }
|
public interface ITick { void Tick(Actor self); }
|
||||||
|
public interface ITickRender { void TickRender(WorldRenderer wr, Actor self); }
|
||||||
public interface IRender { IEnumerable<Renderable> Render(Actor self, WorldRenderer wr); }
|
public interface IRender { IEnumerable<Renderable> Render(Actor self, WorldRenderer wr); }
|
||||||
public interface IAutoSelectionSize { int2 SelectionSize(Actor self); }
|
public interface IAutoSelectionSize { int2 SelectionSize(Actor self); }
|
||||||
|
|
||||||
|
|||||||
@@ -12,31 +12,42 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
using OpenRA.FileFormats;
|
using OpenRA.FileFormats;
|
||||||
using OpenRA.Graphics;
|
using OpenRA.Graphics;
|
||||||
|
using OpenRA.Network;
|
||||||
|
|
||||||
namespace OpenRA.Widgets
|
namespace OpenRA.Widgets
|
||||||
{
|
{
|
||||||
public class MapPreviewWidget : Widget
|
public class MapPreviewWidget : Widget
|
||||||
{
|
{
|
||||||
public Func<Map> Map = () => null;
|
public Func<Map> Map = () => null;
|
||||||
public Func<Dictionary<int2, Color>> SpawnColors = () => new Dictionary<int2, Color>();
|
public Func<Dictionary<int2, Session.Client>> SpawnClients = () => new Dictionary<int2, Session.Client>();
|
||||||
public Action<MouseInput> OnMouseDown = _ => {};
|
public Action<MouseInput> OnMouseDown = _ => {};
|
||||||
public Action<int, int2> OnTooltip = (_, __) => { };
|
public Action<int, int2> OnTooltip = (_, __) => { };
|
||||||
public bool IgnoreMouseInput = false;
|
public bool IgnoreMouseInput = false;
|
||||||
public bool ShowSpawnPoints = true;
|
public bool ShowSpawnPoints = true;
|
||||||
|
|
||||||
static readonly Cache<Map,Bitmap> PreviewCache = new Cache<Map, Bitmap>(stub => Minimap.RenderMapPreview( new Map( stub.Path )));
|
public readonly string TooltipContainer;
|
||||||
|
public readonly string TooltipTemplate = "SPAWN_TOOLTIP";
|
||||||
|
Lazy<TooltipContainerWidget> tooltipContainer;
|
||||||
|
public int TooltipSpawnIndex = -1;
|
||||||
|
|
||||||
public MapPreviewWidget() : base() { }
|
public MapPreviewWidget() : base()
|
||||||
|
{
|
||||||
|
tooltipContainer = Lazy.New(() => Ui.Root.Get<TooltipContainerWidget>(TooltipContainer));
|
||||||
|
}
|
||||||
|
|
||||||
protected MapPreviewWidget(MapPreviewWidget other)
|
protected MapPreviewWidget(MapPreviewWidget other)
|
||||||
: base(other)
|
: base(other)
|
||||||
{
|
{
|
||||||
lastMap = other.lastMap;
|
lastMap = other.lastMap;
|
||||||
Map = other.Map;
|
Map = other.Map;
|
||||||
SpawnColors = other.SpawnColors;
|
SpawnClients = other.SpawnClients;
|
||||||
ShowSpawnPoints = other.ShowSpawnPoints;
|
ShowSpawnPoints = other.ShowSpawnPoints;
|
||||||
|
TooltipTemplate = other.TooltipTemplate;
|
||||||
|
TooltipContainer = other.TooltipContainer;
|
||||||
|
tooltipContainer = Lazy.New(() => Ui.Root.Get<TooltipContainerWidget>(TooltipContainer));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Widget Clone() { return new MapPreviewWidget(this); }
|
public override Widget Clone() { return new MapPreviewWidget(this); }
|
||||||
@@ -53,6 +64,18 @@ namespace OpenRA.Widgets
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void MouseEntered()
|
||||||
|
{
|
||||||
|
if (TooltipContainer == null) return;
|
||||||
|
tooltipContainer.Value.SetTooltip(TooltipTemplate, new WidgetArgs() {{ "preview", this }});
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void MouseExited()
|
||||||
|
{
|
||||||
|
if (TooltipContainer == null) return;
|
||||||
|
tooltipContainer.Value.RemoveTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
public int2 ConvertToPreview(int2 point)
|
public int2 ConvertToPreview(int2 point)
|
||||||
{
|
{
|
||||||
var map = Map();
|
var map = Map();
|
||||||
@@ -68,19 +91,30 @@ namespace OpenRA.Widgets
|
|||||||
public override void Draw()
|
public override void Draw()
|
||||||
{
|
{
|
||||||
var map = Map();
|
var map = Map();
|
||||||
if( map == null ) return;
|
if (map == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Preview unavailable
|
||||||
|
if (!Loaded)
|
||||||
|
{
|
||||||
|
GeneratePreview();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (lastMap != map)
|
if (lastMap != map)
|
||||||
{
|
{
|
||||||
lastMap = map;
|
lastMap = map;
|
||||||
|
|
||||||
// Update image data
|
// Update image data
|
||||||
var preview = PreviewCache[map];
|
Bitmap preview;
|
||||||
if( mapChooserSheet == null || mapChooserSheet.Size.Width != preview.Width || mapChooserSheet.Size.Height != preview.Height )
|
lock (syncRoot)
|
||||||
mapChooserSheet = new Sheet(new Size( preview.Width, preview.Height ) );
|
preview = Previews[map.Uid];
|
||||||
|
|
||||||
mapChooserSheet.Texture.SetData( preview );
|
if (mapChooserSheet == null || mapChooserSheet.Size.Width != preview.Width || mapChooserSheet.Size.Height != preview.Height)
|
||||||
mapChooserSprite = new Sprite( mapChooserSheet, new Rectangle( 0, 0, map.Bounds.Width, map.Bounds.Height ), TextureChannel.Alpha );
|
mapChooserSheet = new Sheet(new Size(preview.Width, preview.Height));
|
||||||
|
|
||||||
|
mapChooserSheet.Texture.SetData(preview);
|
||||||
|
mapChooserSprite = new Sprite(mapChooserSheet, new Rectangle(0, 0, map.Bounds.Width, map.Bounds.Height), TextureChannel.Alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update map rect
|
// Update map rect
|
||||||
@@ -90,13 +124,14 @@ namespace OpenRA.Widgets
|
|||||||
var dh = (int)(PreviewScale * (size - map.Bounds.Height)) / 2;
|
var dh = (int)(PreviewScale * (size - map.Bounds.Height)) / 2;
|
||||||
MapRect = new Rectangle(RenderBounds.X + dw, RenderBounds.Y + dh, (int)(map.Bounds.Width * PreviewScale), (int)(map.Bounds.Height * PreviewScale));
|
MapRect = new Rectangle(RenderBounds.X + dw, RenderBounds.Y + dh, (int)(map.Bounds.Width * PreviewScale), (int)(map.Bounds.Height * PreviewScale));
|
||||||
|
|
||||||
Game.Renderer.RgbaSpriteRenderer.DrawSprite( mapChooserSprite,
|
Game.Renderer.RgbaSpriteRenderer.DrawSprite(mapChooserSprite,
|
||||||
new float2(MapRect.Location),
|
new float2(MapRect.Location),
|
||||||
new float2( MapRect.Size ) );
|
new float2(MapRect.Size));
|
||||||
|
|
||||||
|
TooltipSpawnIndex = -1;
|
||||||
if (ShowSpawnPoints)
|
if (ShowSpawnPoints)
|
||||||
{
|
{
|
||||||
var colors = SpawnColors();
|
var colors = SpawnClients().ToDictionary(c => c.Key, c => c.Value.ColorRamp.GetColor(0));
|
||||||
|
|
||||||
var spawnPoints = map.GetSpawnPoints().ToList();
|
var spawnPoints = map.GetSpawnPoints().ToList();
|
||||||
foreach (var p in spawnPoints)
|
foreach (var p in spawnPoints)
|
||||||
@@ -113,21 +148,82 @@ namespace OpenRA.Widgets
|
|||||||
|
|
||||||
if ((pos - Viewport.LastMousePos).LengthSquared < 64)
|
if ((pos - Viewport.LastMousePos).LengthSquared < 64)
|
||||||
{
|
{
|
||||||
OnTooltip(spawnPoints.IndexOf(p) + 1, pos);
|
TooltipSpawnIndex = spawnPoints.IndexOf(p) + 1;
|
||||||
|
|
||||||
|
// Legacy tooltip behavior
|
||||||
|
if (TooltipContainer == null)
|
||||||
|
OnTooltip(TooltipSpawnIndex, pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
// Async map preview generation bits
|
||||||
/// Forces loading the preview into the map cache.
|
enum PreviewStatus { Invalid, Uncached, Generating, Cached }
|
||||||
/// </summary>
|
static Thread previewLoaderThread;
|
||||||
public Bitmap LoadMapPreview()
|
static object syncRoot = new object();
|
||||||
{
|
static Queue<string> cacheUids = new Queue<string>();
|
||||||
var map = Map();
|
static readonly Dictionary<string, Bitmap> Previews = new Dictionary<string, Bitmap>();
|
||||||
if( map == null ) return null;
|
|
||||||
|
|
||||||
return PreviewCache[map];
|
void LoadAsyncInternal()
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
string uid;
|
||||||
|
lock (syncRoot)
|
||||||
|
{
|
||||||
|
if (cacheUids.Count == 0)
|
||||||
|
break;
|
||||||
|
uid = cacheUids.Peek();
|
||||||
|
}
|
||||||
|
|
||||||
|
var bitmap = Minimap.RenderMapPreview(Game.modData.AvailableMaps[uid]);
|
||||||
|
lock (syncRoot)
|
||||||
|
{
|
||||||
|
// TODO: We should add previews to a sheet here (with multiple previews per sheet)
|
||||||
|
Previews.Add(uid, bitmap);
|
||||||
|
cacheUids.Dequeue();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Yuck... But this helps the UI Jank when opening the map selector significantly.
|
||||||
|
Thread.Sleep(50);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GeneratePreview()
|
||||||
|
{
|
||||||
|
var m = Map();
|
||||||
|
if (m == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var status = Status(m);
|
||||||
|
if (status == PreviewStatus.Uncached)
|
||||||
|
lock (syncRoot)
|
||||||
|
cacheUids.Enqueue(m.Uid);
|
||||||
|
|
||||||
|
if (previewLoaderThread == null || !previewLoaderThread.IsAlive)
|
||||||
|
{
|
||||||
|
previewLoaderThread = new Thread(LoadAsyncInternal);
|
||||||
|
previewLoaderThread.Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static PreviewStatus Status(Map m)
|
||||||
|
{
|
||||||
|
if (m == null)
|
||||||
|
return PreviewStatus.Invalid;
|
||||||
|
|
||||||
|
lock (syncRoot)
|
||||||
|
{
|
||||||
|
if (Previews.ContainsKey(m.Uid))
|
||||||
|
return PreviewStatus.Cached;
|
||||||
|
|
||||||
|
if (cacheUids.Contains(m.Uid))
|
||||||
|
return PreviewStatus.Generating;
|
||||||
|
}
|
||||||
|
return PreviewStatus.Uncached;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Loaded { get { return Status(Map()) == PreviewStatus.Cached; } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ namespace OpenRA.Widgets
|
|||||||
{
|
{
|
||||||
public class ScrollItemWidget : ButtonWidget
|
public class ScrollItemWidget : ButtonWidget
|
||||||
{
|
{
|
||||||
|
public string ItemKey;
|
||||||
|
|
||||||
public ScrollItemWidget()
|
public ScrollItemWidget()
|
||||||
: base()
|
: base()
|
||||||
{
|
{
|
||||||
@@ -28,6 +30,7 @@ namespace OpenRA.Widgets
|
|||||||
IsVisible = () => false;
|
IsVisible = () => false;
|
||||||
VisualHeight = 0;
|
VisualHeight = 0;
|
||||||
IgnoreChildMouseOver = true;
|
IgnoreChildMouseOver = true;
|
||||||
|
Key = other.Key;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Func<bool> IsSelected = () => false;
|
public Func<bool> IsSelected = () => false;
|
||||||
@@ -59,5 +62,12 @@ namespace OpenRA.Widgets
|
|||||||
w.OnDoubleClick = onDoubleClick;
|
w.OnDoubleClick = onDoubleClick;
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ScrollItemWidget Setup(string key, ScrollItemWidget template, Func<bool> isSelected, Action onClick)
|
||||||
|
{
|
||||||
|
var w = Setup(template, isSelected, onClick);
|
||||||
|
w.ItemKey = key;
|
||||||
|
return w;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
using OpenRA.Graphics;
|
using OpenRA.Graphics;
|
||||||
|
|
||||||
namespace OpenRA.Widgets
|
namespace OpenRA.Widgets
|
||||||
@@ -143,6 +144,25 @@ namespace OpenRA.Widgets
|
|||||||
ListOffset = 0;
|
ListOffset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ScrollToItem(string itemKey)
|
||||||
|
{
|
||||||
|
var item = Children.FirstOrDefault(c =>
|
||||||
|
{
|
||||||
|
var si = c as ScrollItemWidget;
|
||||||
|
return si != null && si.ItemKey == itemKey;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (item == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Scroll the item to be visible
|
||||||
|
if (item.Bounds.Top + ListOffset < 0)
|
||||||
|
ListOffset = ItemSpacing - item.Bounds.Top;
|
||||||
|
|
||||||
|
if (item.Bounds.Bottom + ListOffset > RenderBounds.Height)
|
||||||
|
ListOffset = RenderBounds.Height - item.Bounds.Bottom - ItemSpacing;
|
||||||
|
}
|
||||||
|
|
||||||
public override void Tick ()
|
public override void Tick ()
|
||||||
{
|
{
|
||||||
if (UpPressed) Scroll(1);
|
if (UpPressed) Scroll(1);
|
||||||
|
|||||||
@@ -13,11 +13,10 @@ using System.Drawing;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenRA.FileFormats;
|
using OpenRA.FileFormats;
|
||||||
using OpenRA.Graphics;
|
using OpenRA.Graphics;
|
||||||
using OpenRA.Mods.RA;
|
|
||||||
using OpenRA.Widgets;
|
using OpenRA.Widgets;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace OpenRA.Mods.Cnc.Widgets
|
namespace OpenRA.Widgets
|
||||||
{
|
{
|
||||||
public class TooltipContainerWidget : Widget
|
public class TooltipContainerWidget : Widget
|
||||||
{
|
{
|
||||||
@@ -13,6 +13,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenRA.Effects;
|
using OpenRA.Effects;
|
||||||
using OpenRA.FileFormats;
|
using OpenRA.FileFormats;
|
||||||
|
using OpenRA.Graphics;
|
||||||
using OpenRA.Network;
|
using OpenRA.Network;
|
||||||
using OpenRA.Orders;
|
using OpenRA.Orders;
|
||||||
using OpenRA.Support;
|
using OpenRA.Support;
|
||||||
@@ -192,7 +193,12 @@ namespace OpenRA
|
|||||||
|
|
||||||
while (frameEndActions.Count != 0)
|
while (frameEndActions.Count != 0)
|
||||||
frameEndActions.Dequeue()(this);
|
frameEndActions.Dequeue()(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For things that want to update their render state once per tick, ignoring pause state
|
||||||
|
public void TickRender(WorldRenderer wr)
|
||||||
|
{
|
||||||
|
ActorsWithTrait<ITickRender>().Do(x => x.Trait.TickRender(wr, x.Actor));
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Actor> Actors { get { return actors; } }
|
public IEnumerable<Actor> Actors { get { return actors; } }
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using OpenRA.FileFormats;
|
using OpenRA.FileFormats;
|
||||||
|
using OpenRA.Graphics;
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
|
|
||||||
namespace OpenRA.Mods.Cnc
|
namespace OpenRA.Mods.Cnc
|
||||||
@@ -22,7 +23,7 @@ namespace OpenRA.Mods.Cnc
|
|||||||
public object Create(ActorInitializer init) { return new CncMenuPaletteEffect(this); }
|
public object Create(ActorInitializer init) { return new CncMenuPaletteEffect(this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CncMenuPaletteEffect : IPaletteModifier, ITick
|
public class CncMenuPaletteEffect : IPaletteModifier, ITickRender
|
||||||
{
|
{
|
||||||
public enum EffectType { None, Black, Desaturated }
|
public enum EffectType { None, Black, Desaturated }
|
||||||
public readonly CncMenuPaletteEffectInfo Info;
|
public readonly CncMenuPaletteEffectInfo Info;
|
||||||
@@ -40,7 +41,7 @@ namespace OpenRA.Mods.Cnc
|
|||||||
to = type;
|
to = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Tick(Actor self)
|
public void TickRender(WorldRenderer wr, Actor self)
|
||||||
{
|
{
|
||||||
if (remainingFrames > 0)
|
if (remainingFrames > 0)
|
||||||
remainingFrames--;
|
remainingFrames--;
|
||||||
|
|||||||
@@ -111,10 +111,10 @@
|
|||||||
<Compile Include="Widgets\ProductionTabsWidget.cs" />
|
<Compile Include="Widgets\ProductionTabsWidget.cs" />
|
||||||
<Compile Include="Widgets\SupportPowersWidget.cs" />
|
<Compile Include="Widgets\SupportPowersWidget.cs" />
|
||||||
<Compile Include="Widgets\ToggleButtonWidget.cs" />
|
<Compile Include="Widgets\ToggleButtonWidget.cs" />
|
||||||
<Compile Include="Widgets\TooltipContainerWidget.cs" />
|
|
||||||
<Compile Include="WithFire.cs" />
|
<Compile Include="WithFire.cs" />
|
||||||
<Compile Include="WithRoof.cs" />
|
<Compile Include="WithRoof.cs" />
|
||||||
<Compile Include="Widgets\ResourceBarWidget.cs" />
|
<Compile Include="Widgets\ResourceBarWidget.cs" />
|
||||||
|
<Compile Include="Widgets\Logic\SpawnSelectorTooltipLogic.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">
|
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">
|
||||||
|
|||||||
79
OpenRA.Mods.Cnc/Widgets/Logic/SpawnSelectorTooltipLogic.cs
Normal file
79
OpenRA.Mods.Cnc/Widgets/Logic/SpawnSelectorTooltipLogic.cs
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
#region Copyright & License Information
|
||||||
|
/*
|
||||||
|
* Copyright 2007-2013 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;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using OpenRA.Widgets;
|
||||||
|
using OpenRA.Network;
|
||||||
|
|
||||||
|
namespace OpenRA.Mods.Cnc.Widgets.Logic
|
||||||
|
{
|
||||||
|
public class SpawnSelectorTooltipLogic
|
||||||
|
{
|
||||||
|
[ObjectCreator.UseCtor]
|
||||||
|
public SpawnSelectorTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, MapPreviewWidget preview)
|
||||||
|
{
|
||||||
|
widget.IsVisible = () => preview.TooltipSpawnIndex != -1;
|
||||||
|
var label = widget.Get<LabelWidget>("LABEL");
|
||||||
|
var flag = widget.Get<ImageWidget>("FLAG");
|
||||||
|
var team = widget.Get<LabelWidget>("TEAM");
|
||||||
|
|
||||||
|
var ownerFont = Game.Renderer.Fonts[label.Font];
|
||||||
|
var teamFont = Game.Renderer.Fonts[team.Font];
|
||||||
|
var cachedWidth = 0;
|
||||||
|
var labelText = "";
|
||||||
|
string playerCountry = null;
|
||||||
|
var playerTeam = -1;
|
||||||
|
|
||||||
|
tooltipContainer.BeforeRender = () =>
|
||||||
|
{
|
||||||
|
var client = preview.SpawnClients().Values.FirstOrDefault(c => c.SpawnPoint == preview.TooltipSpawnIndex);
|
||||||
|
|
||||||
|
var teamWidth = 0;
|
||||||
|
if (client == null)
|
||||||
|
{
|
||||||
|
labelText = "Available spawn";
|
||||||
|
playerCountry = null;
|
||||||
|
playerTeam = 0;
|
||||||
|
widget.Bounds.Height = 25;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
labelText = client.Name;
|
||||||
|
playerCountry = client.Country;
|
||||||
|
playerTeam = client.Team;
|
||||||
|
widget.Bounds.Height = playerTeam > 0 ? 40 : 25;
|
||||||
|
teamWidth = teamFont.Measure(team.GetText()).X;
|
||||||
|
}
|
||||||
|
|
||||||
|
label.Bounds.X = playerCountry != null ? flag.Bounds.Right + 5 : 5;
|
||||||
|
|
||||||
|
var textWidth = ownerFont.Measure(labelText).X;
|
||||||
|
if (textWidth != cachedWidth)
|
||||||
|
{
|
||||||
|
label.Bounds.Width = textWidth;
|
||||||
|
widget.Bounds.Width = 2*label.Bounds.X + textWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
widget.Bounds.Width = Math.Max(teamWidth + 10, label.Bounds.Right + 5);
|
||||||
|
team.Bounds.Width = widget.Bounds.Width;
|
||||||
|
};
|
||||||
|
|
||||||
|
label.GetText = () => labelText;
|
||||||
|
flag.IsVisible = () => playerCountry != null;
|
||||||
|
flag.GetImageCollection = () => "flags";
|
||||||
|
flag.GetImageName = () => playerCountry;
|
||||||
|
team.GetText = () => "Team {0}".F(playerTeam);
|
||||||
|
team.IsVisible = () => playerTeam > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
|||||||
mapPreview.Map = () => Map;
|
mapPreview.Map = () => Map;
|
||||||
mapPreview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint( orderManager, mapPreview, Map, mi );
|
mapPreview.OnMouseDown = mi => LobbyUtils.SelectSpawnPoint( orderManager, mapPreview, Map, mi );
|
||||||
mapPreview.OnTooltip = (spawnPoint, pos) => LobbyUtils.ShowSpawnPointTooltip(orderManager, spawnPoint, pos);
|
mapPreview.OnTooltip = (spawnPoint, pos) => LobbyUtils.ShowSpawnPointTooltip(orderManager, spawnPoint, pos);
|
||||||
mapPreview.SpawnColors = () => LobbyUtils.GetSpawnColors(orderManager, Map);
|
mapPreview.SpawnClients = () => LobbyUtils.GetSpawnClients(orderManager, Map);
|
||||||
|
|
||||||
var mapTitle = lobby.GetOrNull<LabelWidget>("MAP_TITLE");
|
var mapTitle = lobby.GetOrNull<LabelWidget>("MAP_TITLE");
|
||||||
if (mapTitle != null)
|
if (mapTitle != null)
|
||||||
@@ -122,6 +122,20 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
|||||||
mapTitle.GetText = () => Map.Title;
|
mapTitle.GetText = () => Map.Title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var mapType = lobby.GetOrNull<LabelWidget>("MAP_TYPE");
|
||||||
|
if (mapType != null)
|
||||||
|
{
|
||||||
|
mapType.IsVisible = () => Map != null;
|
||||||
|
mapType.GetText = () => Map.Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
var mapAuthor = lobby.GetOrNull<LabelWidget>("MAP_AUTHOR");
|
||||||
|
if (mapAuthor != null)
|
||||||
|
{
|
||||||
|
mapAuthor.IsVisible = () => Map != null;
|
||||||
|
mapAuthor.GetText = () => "Created by {0}".F(Map.Author);
|
||||||
|
}
|
||||||
|
|
||||||
CountryNames = Rules.Info["world"].Traits.WithInterface<CountryInfo>()
|
CountryNames = Rules.Info["world"].Traits.WithInterface<CountryInfo>()
|
||||||
.Where(c => c.Selectable)
|
.Where(c => c.Selectable)
|
||||||
.ToDictionary(a => a.Race, a => a.Name);
|
.ToDictionary(a => a.Race, a => a.Name);
|
||||||
|
|||||||
@@ -150,14 +150,14 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
|||||||
color.AttachPanel(colorChooser);
|
color.AttachPanel(colorChooser);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Dictionary<int2, Color> GetSpawnColors(OrderManager orderManager, Map map)
|
public static Dictionary<int2, Session.Client> GetSpawnClients(OrderManager orderManager, Map map)
|
||||||
{
|
{
|
||||||
var spawns = map.GetSpawnPoints();
|
var spawns = map.GetSpawnPoints();
|
||||||
return orderManager.LobbyInfo.Clients
|
return orderManager.LobbyInfo.Clients
|
||||||
.Where( c => c.SpawnPoint != 0)
|
.Where(c => c.SpawnPoint != 0)
|
||||||
.ToDictionary(
|
.ToDictionary(
|
||||||
c => spawns[c.SpawnPoint - 1],
|
c => spawns[c.SpawnPoint - 1],
|
||||||
c => c.ColorRamp.GetColor(0));
|
c => c);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SelectSpawnPoint(OrderManager orderManager, MapPreviewWidget mapPreview, Map map, MouseInput mi)
|
public static void SelectSpawnPoint(OrderManager orderManager, MapPreviewWidget mapPreview, Map map, MouseInput mi)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using OpenRA.FileFormats;
|
using OpenRA.FileFormats;
|
||||||
@@ -19,10 +20,13 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
|||||||
public class MapChooserLogic
|
public class MapChooserLogic
|
||||||
{
|
{
|
||||||
Map map;
|
Map map;
|
||||||
|
|
||||||
|
// May be a subset of available maps if a mode filter is active
|
||||||
|
Dictionary<string, Map> visibleMaps;
|
||||||
|
|
||||||
ScrollPanelWidget scrollpanel;
|
ScrollPanelWidget scrollpanel;
|
||||||
ScrollItemWidget itemTemplate;
|
ScrollItemWidget itemTemplate;
|
||||||
string gameMode;
|
string gameMode;
|
||||||
Thread mapLoaderThread;
|
|
||||||
|
|
||||||
[ObjectCreator.UseCtor]
|
[ObjectCreator.UseCtor]
|
||||||
internal MapChooserLogic(Widget widget, string initialMap, Action onExit, Action<Map> onSelect)
|
internal MapChooserLogic(Widget widget, string initialMap, Action onExit, Action<Map> onSelect)
|
||||||
@@ -34,6 +38,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
|||||||
|
|
||||||
scrollpanel = widget.Get<ScrollPanelWidget>("MAP_LIST");
|
scrollpanel = widget.Get<ScrollPanelWidget>("MAP_LIST");
|
||||||
scrollpanel.ScrollVelocity = 40f;
|
scrollpanel.ScrollVelocity = 40f;
|
||||||
|
scrollpanel.Layout = new GridLayout(scrollpanel);
|
||||||
|
|
||||||
itemTemplate = scrollpanel.Get<ScrollItemWidget>("MAP_TEMPLATE");
|
itemTemplate = scrollpanel.Get<ScrollItemWidget>("MAP_TEMPLATE");
|
||||||
|
|
||||||
@@ -55,7 +60,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
|||||||
{
|
{
|
||||||
var item = ScrollItemWidget.Setup(template,
|
var item = ScrollItemWidget.Setup(template,
|
||||||
() => gameMode == ii.First,
|
() => gameMode == ii.First,
|
||||||
() => { gameMode = ii.First; EnumerateMapsAsync(); });
|
() => { gameMode = ii.First; EnumerateMaps(); });
|
||||||
item.Get<LabelWidget>("LABEL").GetText = () => showItem(ii);
|
item.Get<LabelWidget>("LABEL").GetText = () => showItem(ii);
|
||||||
return item;
|
return item;
|
||||||
};
|
};
|
||||||
@@ -66,34 +71,34 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
|||||||
gameModeDropdown.GetText = () => showItem(gameModes.First(m => m.First == gameMode));
|
gameModeDropdown.GetText = () => showItem(gameModes.First(m => m.First == gameMode));
|
||||||
}
|
}
|
||||||
|
|
||||||
EnumerateMapsAsync();
|
var randomMapButton = widget.GetOrNull<ButtonWidget>("RANDOMMAP_BUTTON");
|
||||||
}
|
if (randomMapButton != null)
|
||||||
|
{
|
||||||
|
randomMapButton.OnClick = () =>
|
||||||
|
{
|
||||||
|
var kv = visibleMaps.Random(Game.CosmeticRandom);
|
||||||
|
map = kv.Value;
|
||||||
|
scrollpanel.ScrollToItem(kv.Key);
|
||||||
|
};
|
||||||
|
randomMapButton.IsDisabled = () => visibleMaps == null || visibleMaps.Count == 0;
|
||||||
|
}
|
||||||
|
|
||||||
void EnumerateMapsAsync()
|
EnumerateMaps();
|
||||||
{
|
|
||||||
if (mapLoaderThread != null && mapLoaderThread.IsAlive)
|
|
||||||
mapLoaderThread.Abort(); // violent, but should be fine since we are not doing anything sensitive in this thread
|
|
||||||
|
|
||||||
mapLoaderThread = new Thread(EnumerateMaps);
|
|
||||||
mapLoaderThread.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnumerateMaps()
|
void EnumerateMaps()
|
||||||
{
|
{
|
||||||
Game.RunAfterTick(() => scrollpanel.RemoveChildren()); // queue removal in case another thread added any items to the game queue
|
|
||||||
scrollpanel.Layout = new GridLayout(scrollpanel);
|
|
||||||
scrollpanel.ScrollToTop();
|
|
||||||
|
|
||||||
var maps = Game.modData.AvailableMaps
|
var maps = Game.modData.AvailableMaps
|
||||||
.Where(kv => kv.Value.Selectable)
|
.Where(kv => kv.Value.Selectable)
|
||||||
.Where(kv => kv.Value.Type == gameMode || gameMode == null)
|
.Where(kv => kv.Value.Type == gameMode || gameMode == null)
|
||||||
.OrderBy(kv => kv.Value.PlayerCount)
|
.OrderBy(kv => kv.Value.PlayerCount)
|
||||||
.ThenBy(kv => kv.Value.Title);
|
.ThenBy(kv => kv.Value.Title);
|
||||||
|
|
||||||
|
scrollpanel.RemoveChildren();
|
||||||
foreach (var kv in maps)
|
foreach (var kv in maps)
|
||||||
{
|
{
|
||||||
var m = kv.Value;
|
var m = kv.Value;
|
||||||
var item = ScrollItemWidget.Setup(itemTemplate, () => m == map, () => map = m);
|
var item = ScrollItemWidget.Setup(kv.Key, itemTemplate, () => m == map, () => map = m);
|
||||||
|
|
||||||
var titleLabel = item.Get<LabelWidget>("TITLE");
|
var titleLabel = item.Get<LabelWidget>("TITLE");
|
||||||
titleLabel.GetText = () => m.Title;
|
titleLabel.GetText = () => m.Title;
|
||||||
@@ -102,17 +107,21 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
|||||||
previewWidget.IgnoreMouseOver = true;
|
previewWidget.IgnoreMouseOver = true;
|
||||||
previewWidget.IgnoreMouseInput = true;
|
previewWidget.IgnoreMouseInput = true;
|
||||||
previewWidget.Map = () => m;
|
previewWidget.Map = () => m;
|
||||||
previewWidget.LoadMapPreview();
|
previewWidget.IsVisible = () => previewWidget.RenderBounds.IntersectsWith(scrollpanel.RenderBounds);
|
||||||
|
|
||||||
var detailsWidget = item.Get<LabelWidget>("DETAILS");
|
var previewLoadingWidget = item.GetOrNull<BackgroundWidget>("PREVIEW_PLACEHOLDER");
|
||||||
|
if (previewLoadingWidget != null)
|
||||||
|
previewLoadingWidget.IsVisible = () => !previewWidget.Loaded;
|
||||||
|
|
||||||
|
var detailsWidget = item.GetOrNull<LabelWidget>("DETAILS");
|
||||||
if (detailsWidget != null)
|
if (detailsWidget != null)
|
||||||
detailsWidget.GetText = () => "{0} ({1})".F(m.Type, m.PlayerCount);
|
detailsWidget.GetText = () => "{0} ({1} players)".F(m.Type, m.PlayerCount);
|
||||||
|
|
||||||
var authorWidget = item.Get<LabelWidget>("AUTHOR");
|
var authorWidget = item.GetOrNull<LabelWidget>("AUTHOR");
|
||||||
if (authorWidget != null)
|
if (authorWidget != null)
|
||||||
authorWidget.GetText = () => m.Author;
|
authorWidget.GetText = () => "Created by {0}".F(m.Author);
|
||||||
|
|
||||||
var sizeWidget = item.Get<LabelWidget>("SIZE");
|
var sizeWidget = item.GetOrNull<LabelWidget>("SIZE");
|
||||||
if (sizeWidget != null)
|
if (sizeWidget != null)
|
||||||
{
|
{
|
||||||
var size = m.Bounds.Width + "x" + m.Bounds.Height;
|
var size = m.Bounds.Width + "x" + m.Bounds.Height;
|
||||||
@@ -124,8 +133,12 @@ namespace OpenRA.Mods.RA.Widgets.Logic
|
|||||||
sizeWidget.GetText = () => size;
|
sizeWidget.GetText = () => size;
|
||||||
}
|
}
|
||||||
|
|
||||||
Game.RunAfterTick(() => scrollpanel.AddChild(item));
|
scrollpanel.AddChild(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
visibleMaps = maps.ToDictionary(kv => kv.Key, kv => kv.Value);
|
||||||
|
if (visibleMaps.ContainsValue(map))
|
||||||
|
scrollpanel.ScrollToItem(visibleMaps.First(m => m.Value == map).Key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,13 +32,28 @@ Container@SERVER_LOBBY:
|
|||||||
Y:1
|
Y:1
|
||||||
Width:192
|
Width:192
|
||||||
Height:192
|
Height:192
|
||||||
|
TooltipContainer:TOOLTIP_CONTAINER
|
||||||
Label@MAP_TITLE:
|
Label@MAP_TITLE:
|
||||||
X:PARENT_RIGHT-15-WIDTH
|
X:PARENT_RIGHT-15-WIDTH
|
||||||
Y:225
|
Y:227
|
||||||
Width:194
|
Width:194
|
||||||
Height:25
|
Height:25
|
||||||
Font:Bold
|
Font:Bold
|
||||||
Align:Center
|
Align:Center
|
||||||
|
Label@MAP_TYPE:
|
||||||
|
X:PARENT_RIGHT-15-WIDTH
|
||||||
|
Y:242
|
||||||
|
Width:194
|
||||||
|
Height:25
|
||||||
|
Font:TinyBold
|
||||||
|
Align:Center
|
||||||
|
Label@MAP_AUTHOR:
|
||||||
|
X:PARENT_RIGHT-15-WIDTH
|
||||||
|
Y:255
|
||||||
|
Width:194
|
||||||
|
Height:25
|
||||||
|
Font:Tiny
|
||||||
|
Align:Center
|
||||||
ScrollPanel@PLAYERS:
|
ScrollPanel@PLAYERS:
|
||||||
X:15
|
X:15
|
||||||
Y:30
|
Y:30
|
||||||
@@ -329,13 +344,13 @@ Container@SERVER_LOBBY:
|
|||||||
Font:Bold
|
Font:Bold
|
||||||
Checkbox@ALLOWCHEATS_CHECKBOX:
|
Checkbox@ALLOWCHEATS_CHECKBOX:
|
||||||
X:15
|
X:15
|
||||||
Y:255
|
Y:257
|
||||||
Width:130
|
Width:130
|
||||||
Height:20
|
Height:20
|
||||||
Text: Allow Cheats
|
Text: Allow Cheats
|
||||||
Checkbox@CRATES_CHECKBOX:
|
Checkbox@CRATES_CHECKBOX:
|
||||||
X:160
|
X:160
|
||||||
Y:255
|
Y:257
|
||||||
Width:80
|
Width:80
|
||||||
Height:20
|
Height:20
|
||||||
Text: Crates
|
Text: Crates
|
||||||
@@ -347,13 +362,6 @@ Container@SERVER_LOBBY:
|
|||||||
Font:Bold
|
Font:Bold
|
||||||
Visible:false
|
Visible:false
|
||||||
Text:Assign
|
Text:Assign
|
||||||
Button@RANDOMMAP_BUTTON:
|
|
||||||
X:PARENT_RIGHT-120-15-40
|
|
||||||
Y:255
|
|
||||||
Width:120
|
|
||||||
Height:25
|
|
||||||
Text:Random Map
|
|
||||||
Font:Bold
|
|
||||||
ScrollPanel@CHAT_DISPLAY:
|
ScrollPanel@CHAT_DISPLAY:
|
||||||
X:15
|
X:15
|
||||||
Y:285
|
Y:285
|
||||||
@@ -396,6 +404,7 @@ Container@SERVER_LOBBY:
|
|||||||
Height:25
|
Height:25
|
||||||
Align:Right
|
Align:Right
|
||||||
Text:Chat:
|
Text:Chat:
|
||||||
|
TooltipContainer@TOOLTIP_CONTAINER:
|
||||||
Button@DISCONNECT_BUTTON:
|
Button@DISCONNECT_BUTTON:
|
||||||
X:0
|
X:0
|
||||||
Y:499
|
Y:499
|
||||||
|
|||||||
@@ -6,62 +6,78 @@ Container@MAPCHOOSER_PANEL:
|
|||||||
Height:535
|
Height:535
|
||||||
Children:
|
Children:
|
||||||
Label@TITLE:
|
Label@TITLE:
|
||||||
Width:790
|
Width:PARENT_RIGHT
|
||||||
Y:0-25
|
Y:0-25
|
||||||
Font:BigBold
|
Font:BigBold
|
||||||
Contrast:true
|
Contrast:true
|
||||||
Align:Center
|
Align:Center
|
||||||
Text: Select Map
|
Text: Select Map
|
||||||
Background@bg:
|
Background@bg:
|
||||||
Width:790
|
Width:PARENT_RIGHT
|
||||||
Height:500
|
Height:500
|
||||||
Background:panel-black
|
Background:panel-black
|
||||||
Children:
|
Children:
|
||||||
|
Label@GAMEMODE_DESC:
|
||||||
|
X:PARENT_RIGHT - WIDTH - 220
|
||||||
|
Y:10
|
||||||
|
Width:200
|
||||||
|
Height:25
|
||||||
|
Font: Bold
|
||||||
|
Align: Right
|
||||||
|
Text:Filter:
|
||||||
|
DropDownButton@GAMEMODE_FILTER:
|
||||||
|
X:PARENT_RIGHT - WIDTH - 15
|
||||||
|
Y:10
|
||||||
|
Width:200
|
||||||
|
Height:25
|
||||||
ScrollPanel@MAP_LIST:
|
ScrollPanel@MAP_LIST:
|
||||||
X:15
|
X:15
|
||||||
Y:30
|
Y:45
|
||||||
Width:PARENT_RIGHT - 30
|
Width:PARENT_RIGHT - 30
|
||||||
Height:455
|
Height:440
|
||||||
Children:
|
Children:
|
||||||
ScrollItem@MAP_TEMPLATE:
|
ScrollItem@MAP_TEMPLATE:
|
||||||
Width:180
|
Width:168
|
||||||
Height:208
|
Height:217
|
||||||
X:2
|
X:2
|
||||||
Y:0
|
Y:0
|
||||||
Visible:false
|
Visible:false
|
||||||
Children:
|
Children:
|
||||||
|
Background@PREVIEW_PLACEHOLDER:
|
||||||
|
X:(PARENT_RIGHT - WIDTH)/2
|
||||||
|
Y:4
|
||||||
|
Width:158
|
||||||
|
Height:158
|
||||||
|
Background:panel-black
|
||||||
|
ClickThrough: false
|
||||||
|
MapPreview@PREVIEW:
|
||||||
|
X:(PARENT_RIGHT - WIDTH)/2
|
||||||
|
Y:4
|
||||||
|
Width:158
|
||||||
|
Height:158
|
||||||
Label@TITLE:
|
Label@TITLE:
|
||||||
X:2
|
X:2
|
||||||
Y:PARENT_BOTTOM-47
|
Y:PARENT_BOTTOM-48
|
||||||
Width:PARENT_RIGHT-4
|
Width:PARENT_RIGHT-4
|
||||||
Height:25
|
|
||||||
Align:Center
|
Align:Center
|
||||||
Label@DETAILS:
|
Label@DETAILS:
|
||||||
Width:PARENT_RIGHT-4
|
Width:PARENT_RIGHT-4
|
||||||
X:2
|
X:2
|
||||||
Y:PARENT_BOTTOM-35
|
Y:PARENT_BOTTOM-34
|
||||||
Align:Center
|
Align:Center
|
||||||
Height:25
|
|
||||||
Font:Tiny
|
Font:Tiny
|
||||||
Label@AUTHOR:
|
Label@AUTHOR:
|
||||||
Width:PARENT_RIGHT-4
|
Width:PARENT_RIGHT-4
|
||||||
X:2
|
X:2
|
||||||
Y:PARENT_BOTTOM-26
|
Y:PARENT_BOTTOM-22
|
||||||
Align:Center
|
Align:Center
|
||||||
Height:25
|
|
||||||
Font:Tiny
|
Font:Tiny
|
||||||
Label@SIZE:
|
Label@SIZE:
|
||||||
Width:PARENT_RIGHT-4
|
Width:PARENT_RIGHT-4
|
||||||
X:2
|
X:2
|
||||||
Y:PARENT_BOTTOM-17
|
Y:PARENT_BOTTOM-10
|
||||||
Align:Center
|
Align:Center
|
||||||
Height:25
|
|
||||||
Font:Tiny
|
Font:Tiny
|
||||||
MapPreview@PREVIEW:
|
|
||||||
X:(PARENT_RIGHT - WIDTH)/2
|
|
||||||
Y:4
|
|
||||||
Width:160
|
|
||||||
Height:160
|
|
||||||
Button@BUTTON_CANCEL:
|
Button@BUTTON_CANCEL:
|
||||||
Key:escape
|
Key:escape
|
||||||
X:0
|
X:0
|
||||||
@@ -69,9 +85,16 @@ Container@MAPCHOOSER_PANEL:
|
|||||||
Width:140
|
Width:140
|
||||||
Height:35
|
Height:35
|
||||||
Text:Cancel
|
Text:Cancel
|
||||||
|
Button@RANDOMMAP_BUTTON:
|
||||||
|
Key:space
|
||||||
|
X:PARENT_RIGHT - 150 - WIDTH
|
||||||
|
Y:499
|
||||||
|
Width:140
|
||||||
|
Height:35
|
||||||
|
Text:Random
|
||||||
Button@BUTTON_OK:
|
Button@BUTTON_OK:
|
||||||
Key:return
|
Key:return
|
||||||
X:790 - WIDTH
|
X:PARENT_RIGHT - WIDTH
|
||||||
Y:499
|
Y:499
|
||||||
Width:140
|
Width:140
|
||||||
Height:35
|
Height:35
|
||||||
|
|||||||
@@ -99,3 +99,23 @@ Background@SUPPORT_POWER_TOOLTIP:
|
|||||||
Y:20
|
Y:20
|
||||||
Font:TinyBold
|
Font:TinyBold
|
||||||
VAlign:Top
|
VAlign:Top
|
||||||
|
|
||||||
|
Background@SPAWN_TOOLTIP:
|
||||||
|
Logic:SpawnSelectorTooltipLogic
|
||||||
|
Background:panel-black
|
||||||
|
Width:141
|
||||||
|
Children:
|
||||||
|
Label@LABEL:
|
||||||
|
X:5
|
||||||
|
Height:23
|
||||||
|
Font:Bold
|
||||||
|
Image@FLAG:
|
||||||
|
X:5
|
||||||
|
Y:5
|
||||||
|
Width:32
|
||||||
|
Height:16
|
||||||
|
Label@TEAM:
|
||||||
|
Y:21
|
||||||
|
Height:15
|
||||||
|
Font:TinyBold
|
||||||
|
Align:center
|
||||||
@@ -230,5 +230,6 @@ PVICE:
|
|||||||
DrawLineToTarget:
|
DrawLineToTarget:
|
||||||
Selectable:
|
Selectable:
|
||||||
Voice: DinoVoice
|
Voice: DinoVoice
|
||||||
|
SelectionDecorations:
|
||||||
ActorLostNotification:
|
ActorLostNotification:
|
||||||
Notification: unitlost.aud
|
Notification: unitlost.aud
|
||||||
|
|||||||
Reference in New Issue
Block a user