Building hotkeys
This commit is contained in:
@@ -1,254 +1,254 @@
|
|||||||
#region Copyright & License Information
|
#region Copyright & License Information
|
||||||
/*
|
/*
|
||||||
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
|
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
|
||||||
* This file is part of OpenRA.
|
* This file is part of OpenRA.
|
||||||
*
|
*
|
||||||
* OpenRA is free software: you can redistribute it and/or modify
|
* OpenRA is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* OpenRA is distributed in the hope that it will be useful,
|
* OpenRA is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
|
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenRA.FileFormats;
|
using OpenRA.FileFormats;
|
||||||
using OpenRA.GameRules;
|
using OpenRA.GameRules;
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
using OpenRA.Traits.Activities;
|
using OpenRA.Traits.Activities;
|
||||||
|
|
||||||
namespace OpenRA
|
namespace OpenRA
|
||||||
{
|
{
|
||||||
public class Actor
|
public class Actor
|
||||||
{
|
{
|
||||||
[Sync]
|
[Sync]
|
||||||
public readonly TypeDictionary traits = new TypeDictionary();
|
public readonly TypeDictionary traits = new TypeDictionary();
|
||||||
public readonly ActorInfo Info;
|
public readonly ActorInfo Info;
|
||||||
|
|
||||||
public readonly World World;
|
public readonly World World;
|
||||||
public readonly uint ActorID;
|
public readonly uint ActorID;
|
||||||
|
|
||||||
[Sync]
|
[Sync]
|
||||||
public int2 Location;
|
public int2 Location;
|
||||||
[Sync]
|
[Sync]
|
||||||
public Player Owner;
|
public Player Owner;
|
||||||
[Sync]
|
[Sync]
|
||||||
public int Health;
|
public int Health;
|
||||||
IActivity currentActivity;
|
IActivity currentActivity;
|
||||||
|
|
||||||
public Actor(World world, string name, int2 location, Player owner)
|
public Actor(World world, string name, int2 location, Player owner)
|
||||||
{
|
{
|
||||||
World = world;
|
World = world;
|
||||||
ActorID = world.NextAID();
|
ActorID = world.NextAID();
|
||||||
Location = location;
|
Location = location;
|
||||||
CenterLocation = Traits.Util.CenterOfCell(Location);
|
CenterLocation = Traits.Util.CenterOfCell(Location);
|
||||||
Owner = owner;
|
Owner = owner;
|
||||||
|
|
||||||
if (name != null)
|
if (name != null)
|
||||||
{
|
{
|
||||||
if (!Rules.Info.ContainsKey(name.ToLowerInvariant()))
|
if (!Rules.Info.ContainsKey(name.ToLowerInvariant()))
|
||||||
throw new NotImplementedException("No rules definition for unit {0}".F(name.ToLowerInvariant()));
|
throw new NotImplementedException("No rules definition for unit {0}".F(name.ToLowerInvariant()));
|
||||||
|
|
||||||
Info = Rules.Info[name.ToLowerInvariant()];
|
Info = Rules.Info[name.ToLowerInvariant()];
|
||||||
Health = this.GetMaxHP();
|
Health = this.GetMaxHP();
|
||||||
|
|
||||||
foreach (var trait in Info.TraitsInConstructOrder())
|
foreach (var trait in Info.TraitsInConstructOrder())
|
||||||
traits.Add(trait.Create(this));
|
traits.Add(trait.Create(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
Size = Lazy.New(() =>
|
Size = Lazy.New(() =>
|
||||||
{
|
{
|
||||||
var si = Info.Traits.GetOrDefault<SelectableInfo>();
|
var si = Info.Traits.GetOrDefault<SelectableInfo>();
|
||||||
if (si != null && si.Bounds != null)
|
if (si != null && si.Bounds != null)
|
||||||
return new float2(si.Bounds[0], si.Bounds[1]);
|
return new float2(si.Bounds[0], si.Bounds[1]);
|
||||||
|
|
||||||
// auto size from render
|
// auto size from render
|
||||||
var firstSprite = traits.WithInterface<IRender>().SelectMany(x => x.Render(this)).FirstOrDefault();
|
var firstSprite = traits.WithInterface<IRender>().SelectMany(x => x.Render(this)).FirstOrDefault();
|
||||||
if (firstSprite.Sprite == null) return float2.Zero;
|
if (firstSprite.Sprite == null) return float2.Zero;
|
||||||
return firstSprite.Sprite.size;
|
return firstSprite.Sprite.size;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Tick()
|
public void Tick()
|
||||||
{
|
{
|
||||||
var wasIdle = currentActivity is Idle;
|
var wasIdle = currentActivity is Idle;
|
||||||
while (currentActivity != null)
|
while (currentActivity != null)
|
||||||
{
|
{
|
||||||
var a = currentActivity;
|
var a = currentActivity;
|
||||||
currentActivity = a.Tick(this) ?? new Idle();
|
currentActivity = a.Tick(this) ?? new Idle();
|
||||||
|
|
||||||
if (a == currentActivity) break;
|
if (a == currentActivity) break;
|
||||||
|
|
||||||
if (currentActivity is Idle)
|
if (currentActivity is Idle)
|
||||||
{
|
{
|
||||||
if (!wasIdle)
|
if (!wasIdle)
|
||||||
foreach (var ni in traits.WithInterface<INotifyIdle>())
|
foreach (var ni in traits.WithInterface<INotifyIdle>())
|
||||||
ni.Idle(this);
|
ni.Idle(this);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsIdle
|
public bool IsIdle
|
||||||
{
|
{
|
||||||
get { return currentActivity == null || currentActivity is Idle; }
|
get { return currentActivity == null || currentActivity is Idle; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public float2 CenterLocation;
|
public float2 CenterLocation;
|
||||||
|
|
||||||
Lazy<float2> Size;
|
OpenRA.FileFormats.Lazy<float2> Size;
|
||||||
|
|
||||||
public IEnumerable<Renderable> Render()
|
public IEnumerable<Renderable> Render()
|
||||||
{
|
{
|
||||||
var mods = traits.WithInterface<IRenderModifier>();
|
var mods = traits.WithInterface<IRenderModifier>();
|
||||||
var sprites = traits.WithInterface<IRender>().SelectMany(x => x.Render(this));
|
var sprites = traits.WithInterface<IRender>().SelectMany(x => x.Render(this));
|
||||||
return mods.Aggregate(sprites, (m, p) => p.ModifyRender(this, m));
|
return mods.Aggregate(sprites, (m, p) => p.ModifyRender(this, m));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Order Order( int2 xy, MouseInput mi )
|
public Order Order( int2 xy, MouseInput mi )
|
||||||
{
|
{
|
||||||
if (Owner != World.LocalPlayer)
|
if (Owner != World.LocalPlayer)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (!World.Map.IsInMap(xy.X, xy.Y))
|
if (!World.Map.IsInMap(xy.X, xy.Y))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var underCursor = World.FindUnitsAtMouse(mi.Location)
|
var underCursor = World.FindUnitsAtMouse(mi.Location)
|
||||||
.Where(a => a.Info.Traits.Contains<SelectableInfo>())
|
.Where(a => a.Info.Traits.Contains<SelectableInfo>())
|
||||||
.OrderByDescending(a => a.Info.Traits.Get<SelectableInfo>().Priority)
|
.OrderByDescending(a => a.Info.Traits.Get<SelectableInfo>().Priority)
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
|
|
||||||
return traits.WithInterface<IIssueOrder>()
|
return traits.WithInterface<IIssueOrder>()
|
||||||
.Select( x => x.IssueOrder( this, xy, mi, underCursor ) )
|
.Select( x => x.IssueOrder( this, xy, mi, underCursor ) )
|
||||||
.FirstOrDefault( x => x != null );
|
.FirstOrDefault( x => x != null );
|
||||||
}
|
}
|
||||||
|
|
||||||
public RectangleF GetBounds(bool useAltitude)
|
public RectangleF GetBounds(bool useAltitude)
|
||||||
{
|
{
|
||||||
var si = Info.Traits.GetOrDefault<SelectableInfo>();
|
var si = Info.Traits.GetOrDefault<SelectableInfo>();
|
||||||
|
|
||||||
var size = Size.Value;
|
var size = Size.Value;
|
||||||
var loc = CenterLocation - 0.5f * size;
|
var loc = CenterLocation - 0.5f * size;
|
||||||
|
|
||||||
if (si != null && si.Bounds != null && si.Bounds.Length > 2)
|
if (si != null && si.Bounds != null && si.Bounds.Length > 2)
|
||||||
loc += new float2(si.Bounds[2], si.Bounds[3]);
|
loc += new float2(si.Bounds[2], si.Bounds[3]);
|
||||||
|
|
||||||
if (useAltitude)
|
if (useAltitude)
|
||||||
{
|
{
|
||||||
var unit = traits.GetOrDefault<Unit>();
|
var unit = traits.GetOrDefault<Unit>();
|
||||||
if (unit != null) loc -= new float2(0, unit.Altitude);
|
if (unit != null) loc -= new float2(0, unit.Altitude);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new RectangleF(loc.X, loc.Y, size.X, size.Y);
|
return new RectangleF(loc.X, loc.Y, size.X, size.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsDead { get { return Health <= 0; } }
|
public bool IsDead { get { return Health <= 0; } }
|
||||||
public bool IsInWorld { get; set; }
|
public bool IsInWorld { get; set; }
|
||||||
public bool RemoveOnDeath = true;
|
public bool RemoveOnDeath = true;
|
||||||
|
|
||||||
public DamageState GetDamageState()
|
public DamageState GetDamageState()
|
||||||
{
|
{
|
||||||
if (Health <= 0)
|
if (Health <= 0)
|
||||||
return DamageState.Dead;
|
return DamageState.Dead;
|
||||||
|
|
||||||
if (Health < this.GetMaxHP() * World.Defaults.ConditionYellow)
|
if (Health < this.GetMaxHP() * World.Defaults.ConditionYellow)
|
||||||
return DamageState.Half;
|
return DamageState.Half;
|
||||||
|
|
||||||
return DamageState.Normal;
|
return DamageState.Normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InflictDamage(Actor attacker, int damage, WarheadInfo warhead)
|
public void InflictDamage(Actor attacker, int damage, WarheadInfo warhead)
|
||||||
{
|
{
|
||||||
if (IsDead) return; /* overkill! don't count extra hits as more kills! */
|
if (IsDead) return; /* overkill! don't count extra hits as more kills! */
|
||||||
|
|
||||||
var rawDamage = damage;
|
var rawDamage = damage;
|
||||||
var oldState = GetDamageState();
|
var oldState = GetDamageState();
|
||||||
|
|
||||||
/* apply the damage modifiers, if we have any. */
|
/* apply the damage modifiers, if we have any. */
|
||||||
var modifier = (float)traits.WithInterface<IDamageModifier>()
|
var modifier = (float)traits.WithInterface<IDamageModifier>()
|
||||||
.Select(t => t.GetDamageModifier()).Product();
|
.Select(t => t.GetDamageModifier()).Product();
|
||||||
|
|
||||||
damage = (int)(damage * modifier);
|
damage = (int)(damage * modifier);
|
||||||
|
|
||||||
Health -= damage;
|
Health -= damage;
|
||||||
if (Health <= 0)
|
if (Health <= 0)
|
||||||
{
|
{
|
||||||
Health = 0;
|
Health = 0;
|
||||||
|
|
||||||
attacker.Owner.Kills++;
|
attacker.Owner.Kills++;
|
||||||
Owner.Deaths++;
|
Owner.Deaths++;
|
||||||
|
|
||||||
if (RemoveOnDeath)
|
if (RemoveOnDeath)
|
||||||
World.AddFrameEndTask(w => w.Remove(this));
|
World.AddFrameEndTask(w => w.Remove(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
var maxHP = this.GetMaxHP();
|
var maxHP = this.GetMaxHP();
|
||||||
|
|
||||||
if (Health > maxHP) Health = maxHP;
|
if (Health > maxHP) Health = maxHP;
|
||||||
|
|
||||||
Log.Write("InflictDamage: {0} #{1} -> {2} #{3} raw={4} adj={5} hp={6} mod={7}",
|
Log.Write("InflictDamage: {0} #{1} -> {2} #{3} raw={4} adj={5} hp={6} mod={7}",
|
||||||
attacker.Info.Name, attacker.ActorID, Info.Name, ActorID, rawDamage, damage, Health, modifier);
|
attacker.Info.Name, attacker.ActorID, Info.Name, ActorID, rawDamage, damage, Health, modifier);
|
||||||
|
|
||||||
var newState = GetDamageState();
|
var newState = GetDamageState();
|
||||||
|
|
||||||
foreach (var nd in traits.WithInterface<INotifyDamage>())
|
foreach (var nd in traits.WithInterface<INotifyDamage>())
|
||||||
nd.Damaged(this, new AttackInfo
|
nd.Damaged(this, new AttackInfo
|
||||||
{
|
{
|
||||||
Attacker = attacker,
|
Attacker = attacker,
|
||||||
Damage = damage,
|
Damage = damage,
|
||||||
DamageState = newState,
|
DamageState = newState,
|
||||||
DamageStateChanged = newState != oldState,
|
DamageStateChanged = newState != oldState,
|
||||||
Warhead = warhead
|
Warhead = warhead
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void QueueActivity( IActivity nextActivity )
|
public void QueueActivity( IActivity nextActivity )
|
||||||
{
|
{
|
||||||
if( currentActivity == null )
|
if( currentActivity == null )
|
||||||
{
|
{
|
||||||
currentActivity = nextActivity;
|
currentActivity = nextActivity;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var act = currentActivity;
|
var act = currentActivity;
|
||||||
while( act.NextActivity != null )
|
while( act.NextActivity != null )
|
||||||
{
|
{
|
||||||
act = act.NextActivity;
|
act = act.NextActivity;
|
||||||
}
|
}
|
||||||
act.NextActivity = nextActivity;
|
act.NextActivity = nextActivity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CancelActivity()
|
public void CancelActivity()
|
||||||
{
|
{
|
||||||
if( currentActivity != null )
|
if( currentActivity != null )
|
||||||
currentActivity.Cancel( this );
|
currentActivity.Cancel( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
// For pathdebug, et al
|
// For pathdebug, et al
|
||||||
public IActivity GetCurrentActivity()
|
public IActivity GetCurrentActivity()
|
||||||
{
|
{
|
||||||
return currentActivity;
|
return currentActivity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
return (int)ActorID;
|
return (int)ActorID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Equals( object obj )
|
public override bool Equals( object obj )
|
||||||
{
|
{
|
||||||
var o = obj as Actor;
|
var o = obj as Actor;
|
||||||
return ( o != null && o.ActorID == ActorID );
|
return ( o != null && o.ActorID == ActorID );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ using OpenRA.Network;
|
|||||||
using OpenRA.Server;
|
using OpenRA.Server;
|
||||||
using OpenRA.Support;
|
using OpenRA.Support;
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
|
using OpenRA.Widgets;
|
||||||
|
|
||||||
using Timer = OpenRA.Support.Timer;
|
using Timer = OpenRA.Support.Timer;
|
||||||
using XRandom = OpenRA.Thirdparty.Random;
|
using XRandom = OpenRA.Thirdparty.Random;
|
||||||
|
|
||||||
@@ -47,7 +49,7 @@ namespace OpenRA
|
|||||||
public static Controller controller;
|
public static Controller controller;
|
||||||
internal static Chrome chrome;
|
internal static Chrome chrome;
|
||||||
internal static UserSettings Settings;
|
internal static UserSettings Settings;
|
||||||
|
|
||||||
internal static OrderManager orderManager;
|
internal static OrderManager orderManager;
|
||||||
|
|
||||||
public static bool skipMakeAnims = true;
|
public static bool skipMakeAnims = true;
|
||||||
@@ -69,12 +71,12 @@ namespace OpenRA
|
|||||||
|
|
||||||
foreach (var dir in manifest.Folders) FileSystem.Mount(dir);
|
foreach (var dir in manifest.Folders) FileSystem.Mount(dir);
|
||||||
foreach (var pkg in manifest.Packages) FileSystem.Mount(pkg);
|
foreach (var pkg in manifest.Packages) FileSystem.Mount(pkg);
|
||||||
|
|
||||||
Timer.Time("mount temporary packages: {0}");
|
Timer.Time("mount temporary packages: {0}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void LoadModAssemblies(Manifest m)
|
public static void LoadModAssemblies(Manifest m)
|
||||||
{
|
{
|
||||||
// All the core namespaces
|
// All the core namespaces
|
||||||
var asms = typeof(Game).Assembly.GetNamespaces()
|
var asms = typeof(Game).Assembly.GetNamespaces()
|
||||||
.Select(c => Pair.New(typeof(Game).Assembly, c))
|
.Select(c => Pair.New(typeof(Game).Assembly, c))
|
||||||
@@ -102,9 +104,9 @@ namespace OpenRA
|
|||||||
|
|
||||||
throw new InvalidOperationException("Cannot locate type: {0}".F(classname));
|
throw new InvalidOperationException("Cannot locate type: {0}".F(classname));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Dictionary<string,MapStub> AvailableMaps;
|
public static Dictionary<string, MapStub> AvailableMaps;
|
||||||
|
|
||||||
// TODO: Do this nicer
|
// TODO: Do this nicer
|
||||||
static Dictionary<string, MapStub> FindMaps(string[] mods)
|
static Dictionary<string, MapStub> FindMaps(string[] mods)
|
||||||
{
|
{
|
||||||
@@ -118,48 +120,48 @@ namespace OpenRA
|
|||||||
|
|
||||||
return paths.Select(p => new MapStub(new Folder(p))).ToDictionary(m => m.Uid);
|
return paths.Select(p => new MapStub(new Folder(p))).ToDictionary(m => m.Uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ChangeMods()
|
static void ChangeMods()
|
||||||
{
|
{
|
||||||
Timer.Time( "----ChangeMods" );
|
Timer.Time("----ChangeMods");
|
||||||
var manifest = new Manifest(LobbyInfo.GlobalSettings.Mods);
|
var manifest = new Manifest(LobbyInfo.GlobalSettings.Mods);
|
||||||
Timer.Time( "manifest: {0}" );
|
Timer.Time("manifest: {0}");
|
||||||
LoadModAssemblies(manifest);
|
LoadModAssemblies(manifest);
|
||||||
SheetBuilder.Initialize(renderer);
|
SheetBuilder.Initialize(renderer);
|
||||||
LoadModPackages(manifest);
|
LoadModPackages(manifest);
|
||||||
Timer.Time( "load assemblies, packages: {0}" );
|
Timer.Time("load assemblies, packages: {0}");
|
||||||
packageChangePending = false;
|
packageChangePending = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LoadMap(string mapName)
|
static void LoadMap(string mapName)
|
||||||
{
|
{
|
||||||
Timer.Time( "----LoadMap" );
|
Timer.Time("----LoadMap");
|
||||||
SheetBuilder.Initialize(renderer);
|
SheetBuilder.Initialize(renderer);
|
||||||
var manifest = new Manifest(LobbyInfo.GlobalSettings.Mods);
|
var manifest = new Manifest(LobbyInfo.GlobalSettings.Mods);
|
||||||
Timer.Time( "manifest: {0}" );
|
Timer.Time("manifest: {0}");
|
||||||
|
|
||||||
if (!Game.AvailableMaps.ContainsKey(mapName))
|
if (!Game.AvailableMaps.ContainsKey(mapName))
|
||||||
throw new InvalidDataException("Cannot find map with Uid {0}".F(mapName));
|
throw new InvalidDataException("Cannot find map with Uid {0}".F(mapName));
|
||||||
|
|
||||||
var map = new Map( Game.AvailableMaps[mapName].Package );
|
var map = new Map(Game.AvailableMaps[mapName].Package);
|
||||||
|
|
||||||
viewport = new Viewport(clientSize, map.TopLeft, map.BottomRight, renderer);
|
viewport = new Viewport(clientSize, map.TopLeft, map.BottomRight, renderer);
|
||||||
world = null; // trying to access the old world will NRE, rather than silently doing it wrong.
|
world = null; // trying to access the old world will NRE, rather than silently doing it wrong.
|
||||||
ChromeProvider.Initialize(manifest.Chrome);
|
ChromeProvider.Initialize(manifest.Chrome);
|
||||||
Timer.Time( "viewport, ChromeProvider: {0}" );
|
Timer.Time("viewport, ChromeProvider: {0}");
|
||||||
world = new World(manifest,map);
|
world = new World(manifest, map);
|
||||||
Timer.Time( "world: {0}" );
|
Timer.Time("world: {0}");
|
||||||
|
|
||||||
SequenceProvider.Initialize(manifest.Sequences);
|
SequenceProvider.Initialize(manifest.Sequences);
|
||||||
Timer.Time( "ChromeProv, SeqProv: {0}" );
|
Timer.Time("ChromeProv, SeqProv: {0}");
|
||||||
|
|
||||||
chrome = new Chrome(renderer, manifest);
|
chrome = new Chrome(renderer, manifest);
|
||||||
Timer.Time( "chrome: {0}" );
|
Timer.Time("chrome: {0}");
|
||||||
|
|
||||||
Timer.Time( "----end LoadMap" );
|
Timer.Time("----end LoadMap");
|
||||||
Debug("Map change {0} -> {1}".F(Game.mapName, mapName));
|
Debug("Map change {0} -> {1}".F(Game.mapName, mapName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void MoveViewport(int2 loc)
|
public static void MoveViewport(int2 loc)
|
||||||
{
|
{
|
||||||
viewport.Center(loc);
|
viewport.Center(loc);
|
||||||
@@ -174,21 +176,21 @@ namespace OpenRA
|
|||||||
|
|
||||||
CurrentHost = host;
|
CurrentHost = host;
|
||||||
CurrentPort = port;
|
CurrentPort = port;
|
||||||
|
|
||||||
orderManager = new OrderManager(new NetworkConnection( host, port ), ChooseReplayFilename());
|
orderManager = new OrderManager(new NetworkConnection(host, port), ChooseReplayFilename());
|
||||||
}
|
}
|
||||||
|
|
||||||
static string ChooseReplayFilename()
|
static string ChooseReplayFilename()
|
||||||
{
|
{
|
||||||
return DateTime.UtcNow.ToString("OpenRA-yyyy-MM-ddThhmmssZ.rep");
|
return DateTime.UtcNow.ToString("OpenRA-yyyy-MM-ddThhmmssZ.rep");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void JoinLocal()
|
static void JoinLocal()
|
||||||
{
|
{
|
||||||
if (orderManager != null) orderManager.Dispose();
|
if (orderManager != null) orderManager.Dispose();
|
||||||
orderManager = new OrderManager(new EchoConnection());
|
orderManager = new OrderManager(new EchoConnection());
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lastTime = Environment.TickCount;
|
static int lastTime = Environment.TickCount;
|
||||||
|
|
||||||
static void ResetTimer()
|
static void ResetTimer()
|
||||||
@@ -242,7 +244,7 @@ namespace OpenRA
|
|||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void DumpSyncReport( int frame )
|
internal static void DumpSyncReport(int frame)
|
||||||
{
|
{
|
||||||
var f = syncReports.FirstOrDefault(a => a.First == frame);
|
var f = syncReports.FirstOrDefault(a => a.First == frame);
|
||||||
if (f == null)
|
if (f == null)
|
||||||
@@ -262,11 +264,11 @@ namespace OpenRA
|
|||||||
// TODO: Only do this on mod change
|
// TODO: Only do this on mod change
|
||||||
Timer.Time("----begin maplist");
|
Timer.Time("----begin maplist");
|
||||||
AvailableMaps = FindMaps(LobbyInfo.GlobalSettings.Mods);
|
AvailableMaps = FindMaps(LobbyInfo.GlobalSettings.Mods);
|
||||||
Timer.Time( "maplist: {0}" );
|
Timer.Time("maplist: {0}");
|
||||||
ChangeMods();
|
ChangeMods();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mapChangePending)
|
if (mapChangePending)
|
||||||
{
|
{
|
||||||
mapName = LobbyInfo.GlobalSettings.Map;
|
mapName = LobbyInfo.GlobalSettings.Map;
|
||||||
@@ -281,9 +283,9 @@ namespace OpenRA
|
|||||||
using (new PerfSample("tick_time"))
|
using (new PerfSample("tick_time"))
|
||||||
{
|
{
|
||||||
lastTime += Settings.Timestep;
|
lastTime += Settings.Timestep;
|
||||||
chrome.Tick( world );
|
chrome.Tick(world);
|
||||||
|
|
||||||
orderManager.TickImmediate( world );
|
orderManager.TickImmediate(world);
|
||||||
|
|
||||||
var isNetTick = LocalTick % NetTickScale == 0;
|
var isNetTick = LocalTick % NetTickScale == 0;
|
||||||
|
|
||||||
@@ -309,7 +311,7 @@ namespace OpenRA
|
|||||||
using (new PerfSample("render"))
|
using (new PerfSample("render"))
|
||||||
{
|
{
|
||||||
++RenderFrame;
|
++RenderFrame;
|
||||||
viewport.DrawRegions( world );
|
viewport.DrawRegions(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
PerfHistory.items["render"].Tick();
|
PerfHistory.items["render"].Tick();
|
||||||
@@ -364,7 +366,7 @@ namespace OpenRA
|
|||||||
|
|
||||||
if (mapName != LobbyInfo.GlobalSettings.Map)
|
if (mapName != LobbyInfo.GlobalSettings.Map)
|
||||||
mapChangePending = true;
|
mapChangePending = true;
|
||||||
|
|
||||||
if (string.Join(",", oldLobbyInfo.GlobalSettings.Mods)
|
if (string.Join(",", oldLobbyInfo.GlobalSettings.Mods)
|
||||||
!= string.Join(",", LobbyInfo.GlobalSettings.Mods))
|
!= string.Join(",", LobbyInfo.GlobalSettings.Mods))
|
||||||
{
|
{
|
||||||
@@ -379,18 +381,18 @@ namespace OpenRA
|
|||||||
|
|
||||||
static void LoadShellMap(string map)
|
static void LoadShellMap(string map)
|
||||||
{
|
{
|
||||||
LoadMap(map);
|
LoadMap(map);
|
||||||
world.Queries = new World.AllQueries(world);
|
world.Queries = new World.AllQueries(world);
|
||||||
|
|
||||||
foreach (var p in world.players.Values)
|
foreach (var p in world.players.Values)
|
||||||
foreach (var q in world.players.Values)
|
foreach (var q in world.players.Values)
|
||||||
p.Stances[q] = ChooseInitialStance(p, q);
|
p.Stances[q] = ChooseInitialStance(p, q);
|
||||||
|
|
||||||
foreach (var gs in world.WorldActor.traits.WithInterface<IGameStarted>())
|
foreach (var gs in world.WorldActor.traits.WithInterface<IGameStarted>())
|
||||||
gs.GameStarted(world);
|
gs.GameStarted(world);
|
||||||
orderManager.StartGame();
|
orderManager.StartGame();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void StartGame()
|
internal static void StartGame()
|
||||||
{
|
{
|
||||||
LoadMap(LobbyInfo.GlobalSettings.Map);
|
LoadMap(LobbyInfo.GlobalSettings.Map);
|
||||||
@@ -405,13 +407,13 @@ namespace OpenRA
|
|||||||
foreach (var p in world.players.Values)
|
foreach (var p in world.players.Values)
|
||||||
foreach (var q in world.players.Values)
|
foreach (var q in world.players.Values)
|
||||||
p.Stances[q] = ChooseInitialStance(p, q);
|
p.Stances[q] = ChooseInitialStance(p, q);
|
||||||
|
|
||||||
world.Queries = new World.AllQueries(world);
|
world.Queries = new World.AllQueries(world);
|
||||||
|
|
||||||
foreach (var gs in world.WorldActor.traits.WithInterface<IGameStarted>())
|
foreach (var gs in world.WorldActor.traits.WithInterface<IGameStarted>())
|
||||||
gs.GameStarted(world);
|
gs.GameStarted(world);
|
||||||
|
|
||||||
viewport.GoToStartLocation( world.LocalPlayer );
|
viewport.GoToStartLocation(world.LocalPlayer);
|
||||||
orderManager.StartGame();
|
orderManager.StartGame();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,7 +425,7 @@ namespace OpenRA
|
|||||||
var pc = GetClientForPlayer(p);
|
var pc = GetClientForPlayer(p);
|
||||||
var qc = GetClientForPlayer(q);
|
var qc = GetClientForPlayer(q);
|
||||||
|
|
||||||
return pc.Team != 0 && pc.Team == qc.Team
|
return pc.Team != 0 && pc.Team == qc.Team
|
||||||
? Stance.Ally : Stance.Enemy;
|
? Stance.Ally : Stance.Enemy;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -441,8 +443,8 @@ namespace OpenRA
|
|||||||
if (ev == MouseInputEvent.Down)
|
if (ev == MouseInputEvent.Down)
|
||||||
lastPos = new int2(e.Location);
|
lastPos = new int2(e.Location);
|
||||||
|
|
||||||
if (ev == MouseInputEvent.Move &&
|
if (ev == MouseInputEvent.Move &&
|
||||||
(e.Button == MouseButtons.Middle ||
|
(e.Button == MouseButtons.Middle ||
|
||||||
e.Button == (MouseButtons.Left | MouseButtons.Right)))
|
e.Button == (MouseButtons.Left | MouseButtons.Right)))
|
||||||
{
|
{
|
||||||
var p = new int2(e.Location);
|
var p = new int2(e.Location);
|
||||||
@@ -450,7 +452,7 @@ namespace OpenRA
|
|||||||
lastPos = p;
|
lastPos = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
viewport.DispatchMouseInput( world,
|
viewport.DispatchMouseInput(world,
|
||||||
new MouseInput
|
new MouseInput
|
||||||
{
|
{
|
||||||
Button = (MouseButton)(int)e.Button,
|
Button = (MouseButton)(int)e.Button,
|
||||||
@@ -459,8 +461,8 @@ namespace OpenRA
|
|||||||
Modifiers = modifierKeys,
|
Modifiers = modifierKeys,
|
||||||
});
|
});
|
||||||
|
|
||||||
if( sync != world.SyncHash() && world == initialWorld )
|
if (sync != world.SyncHash() && world == initialWorld)
|
||||||
throw new InvalidOperationException( "Desync in DispatchMouseInput" );
|
throw new InvalidOperationException("Desync in DispatchMouseInput");
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static bool IsHost
|
internal static bool IsHost
|
||||||
@@ -487,11 +489,11 @@ namespace OpenRA
|
|||||||
{ ')', '0' },
|
{ ')', '0' },
|
||||||
};
|
};
|
||||||
|
|
||||||
public static void HandleKeyPress( KeyPressEventArgs e, Modifiers modifiers )
|
public static void HandleKeyPress(KeyPressEventArgs e, Modifiers modifiers)
|
||||||
{
|
{
|
||||||
int sync = world.SyncHash();
|
int sync = world.SyncHash();
|
||||||
|
|
||||||
if( e.KeyChar == '\r' )
|
if (e.KeyChar == '\r')
|
||||||
chat.Toggle();
|
chat.Toggle();
|
||||||
else if (Game.chat.isChatting)
|
else if (Game.chat.isChatting)
|
||||||
chat.TypeChar(e.KeyChar);
|
chat.TypeChar(e.KeyChar);
|
||||||
@@ -503,12 +505,17 @@ namespace OpenRA
|
|||||||
Game.controller.selection.DoControlGroup(world,
|
Game.controller.selection.DoControlGroup(world,
|
||||||
c - '0', modifiers);
|
c - '0', modifiers);
|
||||||
|
|
||||||
if (c == 'h')
|
if (c == 08)
|
||||||
Game.controller.GotoNextBase();
|
Game.controller.GotoNextBase();
|
||||||
|
|
||||||
|
if (c == 09)
|
||||||
|
BuildPaletteWidget.TabChange((Control.ModifierKeys & Keys.Shift) == Keys.Shift ? true : false);
|
||||||
|
|
||||||
|
BuildPaletteWidget.DoBuildingHotkey(c, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( sync != Game.world.SyncHash() )
|
if (sync != Game.world.SyncHash())
|
||||||
throw new InvalidOperationException( "Desync in OnKeyPress" );
|
throw new InvalidOperationException("Desync in OnKeyPress");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void HandleModifierKeys(Modifiers mods)
|
public static void HandleModifierKeys(Modifiers mods)
|
||||||
@@ -539,15 +546,15 @@ namespace OpenRA
|
|||||||
throw new InvalidOperationException("Unable to find game root.");
|
throw new InvalidOperationException("Unable to find game root.");
|
||||||
Directory.SetCurrentDirectory("..");
|
Directory.SetCurrentDirectory("..");
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadUserSettings(settings);
|
LoadUserSettings(settings);
|
||||||
LobbyInfo.GlobalSettings.Mods = Settings.InitialMods;
|
LobbyInfo.GlobalSettings.Mods = Settings.InitialMods;
|
||||||
|
|
||||||
// Load the default mod to access required files
|
// Load the default mod to access required files
|
||||||
LoadModPackages(new Manifest(LobbyInfo.GlobalSettings.Mods));
|
LoadModPackages(new Manifest(LobbyInfo.GlobalSettings.Mods));
|
||||||
|
|
||||||
Renderer.SheetSize = Settings.SheetSize;
|
Renderer.SheetSize = Settings.SheetSize;
|
||||||
|
|
||||||
bool windowed = !Game.Settings.Fullscreen;
|
bool windowed = !Game.Settings.Fullscreen;
|
||||||
var resolution = GetResolution(settings);
|
var resolution = GetResolution(settings);
|
||||||
renderer = new Renderer(resolution, windowed);
|
renderer = new Renderer(resolution, windowed);
|
||||||
@@ -555,21 +562,21 @@ namespace OpenRA
|
|||||||
|
|
||||||
controller = new Controller();
|
controller = new Controller();
|
||||||
clientSize = new int2(resolution);
|
clientSize = new int2(resolution);
|
||||||
|
|
||||||
Sound.Initialize();
|
Sound.Initialize();
|
||||||
PerfHistory.items["render"].hasNormalTick = false;
|
PerfHistory.items["render"].hasNormalTick = false;
|
||||||
PerfHistory.items["batches"].hasNormalTick = false;
|
PerfHistory.items["batches"].hasNormalTick = false;
|
||||||
PerfHistory.items["text"].hasNormalTick = false;
|
PerfHistory.items["text"].hasNormalTick = false;
|
||||||
PerfHistory.items["cursor"].hasNormalTick = false;
|
PerfHistory.items["cursor"].hasNormalTick = false;
|
||||||
AvailableMaps = FindMaps(LobbyInfo.GlobalSettings.Mods);
|
AvailableMaps = FindMaps(LobbyInfo.GlobalSettings.Mods);
|
||||||
|
|
||||||
ChangeMods();
|
ChangeMods();
|
||||||
|
|
||||||
if( Settings.Replay != "" )
|
if (Settings.Replay != "")
|
||||||
orderManager = new OrderManager( new ReplayConnection( Settings.Replay ) );
|
orderManager = new OrderManager(new ReplayConnection(Settings.Replay));
|
||||||
else
|
else
|
||||||
JoinLocal();
|
JoinLocal();
|
||||||
|
|
||||||
LoadShellMap(new Manifest(LobbyInfo.GlobalSettings.Mods).ShellmapUid);
|
LoadShellMap(new Manifest(LobbyInfo.GlobalSettings.Mods).ShellmapUid);
|
||||||
|
|
||||||
ResetTimer();
|
ResetTimer();
|
||||||
|
|||||||
@@ -1,198 +1,198 @@
|
|||||||
#region Copyright & License Information
|
#region Copyright & License Information
|
||||||
/*
|
/*
|
||||||
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
|
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
|
||||||
* This file is part of OpenRA.
|
* This file is part of OpenRA.
|
||||||
*
|
*
|
||||||
* OpenRA is free software: you can redistribute it and/or modify
|
* OpenRA is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* OpenRA is distributed in the hope that it will be useful,
|
* OpenRA is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
|
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenRA.FileFormats;
|
using OpenRA.FileFormats;
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
|
|
||||||
namespace OpenRA
|
namespace OpenRA
|
||||||
{
|
{
|
||||||
public enum PowerState { Normal, Low, Critical };
|
public enum PowerState { Normal, Low, Critical };
|
||||||
|
|
||||||
public class Player
|
public class Player
|
||||||
{
|
{
|
||||||
public Actor PlayerActor;
|
public Actor PlayerActor;
|
||||||
public int Kills;
|
public int Kills;
|
||||||
public int Deaths;
|
public int Deaths;
|
||||||
|
|
||||||
public readonly string Palette;
|
public readonly string Palette;
|
||||||
public readonly Color Color;
|
public readonly Color Color;
|
||||||
|
|
||||||
public readonly string PlayerName;
|
public readonly string PlayerName;
|
||||||
public readonly string InternalName;
|
public readonly string InternalName;
|
||||||
public readonly CountryInfo Country;
|
public readonly CountryInfo Country;
|
||||||
public readonly int Index;
|
public readonly int Index;
|
||||||
|
|
||||||
public int Cash = 10000;
|
public int Cash = 10000;
|
||||||
public int Ore = 0;
|
public int Ore = 0;
|
||||||
public int OreCapacity;
|
public int OreCapacity;
|
||||||
public int DisplayCash = 0;
|
public int DisplayCash = 0;
|
||||||
public int PowerProvided = 0;
|
public int PowerProvided = 0;
|
||||||
public int PowerDrained = 0;
|
public int PowerDrained = 0;
|
||||||
|
|
||||||
public ShroudRenderer Shroud;
|
public ShroudRenderer Shroud;
|
||||||
public World World { get; private set; }
|
public World World { get; private set; }
|
||||||
|
|
||||||
public static List<Tuple<string, string, Color>> PlayerColors( World world )
|
public static List<OpenRA.FileFormats.Tuple<string, string, Color>> PlayerColors(World world)
|
||||||
{
|
{
|
||||||
return world.WorldActor.Info.Traits.WithInterface<PlayerColorPaletteInfo>()
|
return world.WorldActor.Info.Traits.WithInterface<PlayerColorPaletteInfo>()
|
||||||
.Where(p => p.Playable)
|
.Where(p => p.Playable)
|
||||||
.Select(p => Tuple.New(p.Name, p.DisplayName, p.Color))
|
.Select(p => OpenRA.FileFormats.Tuple.New(p.Name, p.DisplayName, p.Color))
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Player( World world, Session.Client client )
|
public Player( World world, Session.Client client )
|
||||||
{
|
{
|
||||||
World = world;
|
World = world;
|
||||||
Shroud = new ShroudRenderer(this, world.Map);
|
Shroud = new ShroudRenderer(this, world.Map);
|
||||||
|
|
||||||
PlayerActor = world.CreateActor("Player", new int2(int.MaxValue, int.MaxValue), this);
|
PlayerActor = world.CreateActor("Player", new int2(int.MaxValue, int.MaxValue), this);
|
||||||
|
|
||||||
if (client != null)
|
if (client != null)
|
||||||
{
|
{
|
||||||
Index = client.Index;
|
Index = client.Index;
|
||||||
Palette = PlayerColors(world)[client.PaletteIndex % PlayerColors(world).Count()].a;
|
Palette = PlayerColors(world)[client.PaletteIndex % PlayerColors(world).Count()].a;
|
||||||
Color = PlayerColors(world)[client.PaletteIndex % PlayerColors(world).Count()].c;
|
Color = PlayerColors(world)[client.PaletteIndex % PlayerColors(world).Count()].c;
|
||||||
PlayerName = client.Name;
|
PlayerName = client.Name;
|
||||||
InternalName = "Multi{0}".F(client.Index);
|
InternalName = "Multi{0}".F(client.Index);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Index = -1;
|
Index = -1;
|
||||||
PlayerName = InternalName = "Neutral";
|
PlayerName = InternalName = "Neutral";
|
||||||
Palette = "neutral";
|
Palette = "neutral";
|
||||||
Color = Color.Gray; // HACK HACK
|
Color = Color.Gray; // HACK HACK
|
||||||
}
|
}
|
||||||
|
|
||||||
Country = world.GetCountries()
|
Country = world.GetCountries()
|
||||||
.FirstOrDefault(c => client != null && client.Country == c.Name)
|
.FirstOrDefault(c => client != null && client.Country == c.Name)
|
||||||
?? world.GetCountries().Random(world.SharedRandom);
|
?? world.GetCountries().Random(world.SharedRandom);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdatePower()
|
void UpdatePower()
|
||||||
{
|
{
|
||||||
var oldBalance = PowerProvided - PowerDrained;
|
var oldBalance = PowerProvided - PowerDrained;
|
||||||
|
|
||||||
PowerProvided = 0;
|
PowerProvided = 0;
|
||||||
PowerDrained = 0;
|
PowerDrained = 0;
|
||||||
|
|
||||||
var myBuildings = World.Queries.OwnedBy[this]
|
var myBuildings = World.Queries.OwnedBy[this]
|
||||||
.WithTrait<Building>();
|
.WithTrait<Building>();
|
||||||
|
|
||||||
foreach (var a in myBuildings)
|
foreach (var a in myBuildings)
|
||||||
{
|
{
|
||||||
var p = a.Trait.GetPowerUsage();
|
var p = a.Trait.GetPowerUsage();
|
||||||
if (p > 0)
|
if (p > 0)
|
||||||
PowerProvided += p;
|
PowerProvided += p;
|
||||||
else
|
else
|
||||||
PowerDrained -= p;
|
PowerDrained -= p;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PowerProvided - PowerDrained < 0)
|
if (PowerProvided - PowerDrained < 0)
|
||||||
if (PowerProvided - PowerDrained != oldBalance)
|
if (PowerProvided - PowerDrained != oldBalance)
|
||||||
GiveAdvice(World.WorldActor.Info.Traits.Get<EvaAlertsInfo>().LowPower);
|
GiveAdvice(World.WorldActor.Info.Traits.Get<EvaAlertsInfo>().LowPower);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetSiloFullness()
|
public float GetSiloFullness()
|
||||||
{
|
{
|
||||||
return (float)Ore / OreCapacity;
|
return (float)Ore / OreCapacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PowerState GetPowerState()
|
public PowerState GetPowerState()
|
||||||
{
|
{
|
||||||
if (PowerProvided >= PowerDrained) return PowerState.Normal;
|
if (PowerProvided >= PowerDrained) return PowerState.Normal;
|
||||||
if (PowerProvided > PowerDrained / 2) return PowerState.Low;
|
if (PowerProvided > PowerDrained / 2) return PowerState.Low;
|
||||||
return PowerState.Critical;
|
return PowerState.Critical;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateOreCapacity()
|
void UpdateOreCapacity()
|
||||||
{
|
{
|
||||||
OreCapacity = World.Queries.OwnedBy[this]
|
OreCapacity = World.Queries.OwnedBy[this]
|
||||||
.Where(a => a.traits.Contains<StoresOre>())
|
.Where(a => a.traits.Contains<StoresOre>())
|
||||||
.Select(a => a.Info.Traits.Get<StoresOreInfo>())
|
.Select(a => a.Info.Traits.Get<StoresOreInfo>())
|
||||||
.Sum(b => b.Capacity);
|
.Sum(b => b.Capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GiveAdvice(string advice)
|
void GiveAdvice(string advice)
|
||||||
{
|
{
|
||||||
// todo: store the condition or something.
|
// todo: store the condition or something.
|
||||||
// repeat after World.Defaults.SpeakDelay, as long as the condition holds.
|
// repeat after World.Defaults.SpeakDelay, as long as the condition holds.
|
||||||
Sound.PlayToPlayer(this, advice);
|
Sound.PlayToPlayer(this, advice);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GiveCash( int num ) { Cash += num; }
|
public void GiveCash( int num ) { Cash += num; }
|
||||||
public void GiveOre(int num)
|
public void GiveOre(int num)
|
||||||
{
|
{
|
||||||
Ore += num;
|
Ore += num;
|
||||||
|
|
||||||
if (Ore > OreCapacity)
|
if (Ore > OreCapacity)
|
||||||
Ore = OreCapacity; // trim off the overflow.
|
Ore = OreCapacity; // trim off the overflow.
|
||||||
|
|
||||||
if (Ore > .8 * OreCapacity)
|
if (Ore > .8 * OreCapacity)
|
||||||
GiveAdvice(World.WorldActor.Info.Traits.Get<EvaAlertsInfo>().SilosNeeded);
|
GiveAdvice(World.WorldActor.Info.Traits.Get<EvaAlertsInfo>().SilosNeeded);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TakeCash( int num )
|
public bool TakeCash( int num )
|
||||||
{
|
{
|
||||||
if (Cash + Ore < num) return false;
|
if (Cash + Ore < num) return false;
|
||||||
if (Ore <= num)
|
if (Ore <= num)
|
||||||
{
|
{
|
||||||
num -= Ore;
|
num -= Ore;
|
||||||
Ore = 0;
|
Ore = 0;
|
||||||
Cash -= num;
|
Cash -= num;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Ore -= num;
|
Ore -= num;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const float displayCashFracPerFrame = .07f;
|
const float displayCashFracPerFrame = .07f;
|
||||||
const int displayCashDeltaPerFrame = 37;
|
const int displayCashDeltaPerFrame = 37;
|
||||||
|
|
||||||
public void Tick()
|
public void Tick()
|
||||||
{
|
{
|
||||||
UpdatePower();
|
UpdatePower();
|
||||||
UpdateOreCapacity();
|
UpdateOreCapacity();
|
||||||
|
|
||||||
var totalMoney = Cash + Ore;
|
var totalMoney = Cash + Ore;
|
||||||
var diff = Math.Abs(totalMoney - DisplayCash);
|
var diff = Math.Abs(totalMoney - DisplayCash);
|
||||||
var move = Math.Min(Math.Max((int)(diff * displayCashFracPerFrame),
|
var move = Math.Min(Math.Max((int)(diff * displayCashFracPerFrame),
|
||||||
displayCashDeltaPerFrame), diff);
|
displayCashDeltaPerFrame), diff);
|
||||||
|
|
||||||
var eva = World.WorldActor.Info.Traits.Get<EvaAlertsInfo>();
|
var eva = World.WorldActor.Info.Traits.Get<EvaAlertsInfo>();
|
||||||
if (DisplayCash < totalMoney)
|
if (DisplayCash < totalMoney)
|
||||||
{
|
{
|
||||||
DisplayCash += move;
|
DisplayCash += move;
|
||||||
Sound.PlayToPlayer(this, eva.CashTickUp);
|
Sound.PlayToPlayer(this, eva.CashTickUp);
|
||||||
}
|
}
|
||||||
else if (DisplayCash > totalMoney)
|
else if (DisplayCash > totalMoney)
|
||||||
{
|
{
|
||||||
DisplayCash -= move;
|
DisplayCash -= move;
|
||||||
Sound.PlayToPlayer(this, eva.CashTickDown);
|
Sound.PlayToPlayer(this, eva.CashTickDown);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Dictionary<Player, Stance> Stances = new Dictionary<Player, Stance>();
|
public Dictionary<Player, Stance> Stances = new Dictionary<Player, Stance>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,48 +1,49 @@
|
|||||||
#region Copyright & License Information
|
#region Copyright & License Information
|
||||||
/*
|
/*
|
||||||
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
|
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
|
||||||
* This file is part of OpenRA.
|
* This file is part of OpenRA.
|
||||||
*
|
*
|
||||||
* OpenRA is free software: you can redistribute it and/or modify
|
* OpenRA is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* OpenRA is distributed in the hope that it will be useful,
|
* OpenRA is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
|
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
namespace OpenRA.Traits
|
namespace OpenRA.Traits
|
||||||
{
|
{
|
||||||
class ValuedInfo : ITraitInfo
|
class ValuedInfo : ITraitInfo
|
||||||
{
|
{
|
||||||
public readonly int Cost = 0;
|
public readonly int Cost = 0;
|
||||||
public readonly string Description = "";
|
public readonly string Description = "";
|
||||||
public readonly string LongDesc = "";
|
public readonly string LongDesc = "";
|
||||||
|
|
||||||
public virtual object Create(Actor self) { return new Valued(); }
|
public virtual object Create(Actor self) { return new Valued(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
class BuildableInfo : ValuedInfo
|
class BuildableInfo : ValuedInfo
|
||||||
{
|
{
|
||||||
public readonly int TechLevel = -1;
|
public readonly int TechLevel = -1;
|
||||||
public readonly string[] Prerequisites = { };
|
public readonly string[] Prerequisites = { };
|
||||||
public readonly string[] BuiltAt = { };
|
public readonly string[] BuiltAt = { };
|
||||||
public readonly string[] Owner = { };
|
public readonly string[] Owner = { };
|
||||||
|
|
||||||
public readonly string Icon = null;
|
public readonly string Icon = null;
|
||||||
public readonly string[] AlternateName = { };
|
public readonly string[] AlternateName = { };
|
||||||
public readonly int BuildPaletteOrder = 50;
|
public readonly int BuildPaletteOrder = 50;
|
||||||
|
public readonly string Hotkey = null;
|
||||||
public override object Create(Actor self) { return new Buildable(); }
|
|
||||||
}
|
public override object Create(Actor self) { return new Buildable(); }
|
||||||
|
}
|
||||||
class Valued { } /* halfway to buildable */
|
|
||||||
class Buildable { }
|
class Valued { } /* halfway to buildable */
|
||||||
}
|
class Buildable { }
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,72 +1,72 @@
|
|||||||
#region Copyright & License Information
|
#region Copyright & License Information
|
||||||
/*
|
/*
|
||||||
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
|
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
|
||||||
* This file is part of OpenRA.
|
* This file is part of OpenRA.
|
||||||
*
|
*
|
||||||
* OpenRA is free software: you can redistribute it and/or modify
|
* OpenRA is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* OpenRA is distributed in the hope that it will be useful,
|
* OpenRA is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
|
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenRA.FileFormats;
|
using OpenRA.FileFormats;
|
||||||
|
|
||||||
namespace OpenRA.Traits
|
namespace OpenRA.Traits
|
||||||
{
|
{
|
||||||
class ScreenShakerInfo : ITraitInfo
|
class ScreenShakerInfo : ITraitInfo
|
||||||
{
|
{
|
||||||
public object Create( Actor self ) { return new ScreenShaker(); }
|
public object Create( Actor self ) { return new ScreenShaker(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ScreenShaker : ITick
|
public class ScreenShaker : ITick
|
||||||
{
|
{
|
||||||
int ticks = 0;
|
int ticks = 0;
|
||||||
List<Tuple<int, float2, int>> shakeEffects = new List<Tuple<int, float2, int>>();
|
List<OpenRA.FileFormats.Tuple<int, float2, int>> shakeEffects = new List<OpenRA.FileFormats.Tuple<int, float2, int>>();
|
||||||
|
|
||||||
public void Tick (Actor self)
|
public void Tick (Actor self)
|
||||||
{
|
{
|
||||||
Game.viewport.Scroll(getScrollOffset());
|
Game.viewport.Scroll(getScrollOffset());
|
||||||
shakeEffects.RemoveAll(t => t.a == ticks);
|
shakeEffects.RemoveAll(t => t.a == ticks);
|
||||||
ticks++;
|
ticks++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddEffect(int time, float2 position, int intensity)
|
public void AddEffect(int time, float2 position, int intensity)
|
||||||
{
|
{
|
||||||
shakeEffects.Add(Tuple.New(ticks + time, position, intensity));
|
shakeEffects.Add(OpenRA.FileFormats.Tuple.New(ticks + time, position, intensity));
|
||||||
}
|
}
|
||||||
|
|
||||||
public float2 getScrollOffset()
|
public float2 getScrollOffset()
|
||||||
{
|
{
|
||||||
int xFreq = 4;
|
int xFreq = 4;
|
||||||
int yFreq = 5;
|
int yFreq = 5;
|
||||||
|
|
||||||
return GetIntensity() * new float2(
|
return GetIntensity() * new float2(
|
||||||
(float) Math.Sin((ticks*2*Math.PI)/xFreq) ,
|
(float) Math.Sin((ticks*2*Math.PI)/xFreq) ,
|
||||||
(float) Math.Cos((ticks*2*Math.PI)/yFreq));
|
(float) Math.Cos((ticks*2*Math.PI)/yFreq));
|
||||||
}
|
}
|
||||||
|
|
||||||
public float GetIntensity()
|
public float GetIntensity()
|
||||||
{
|
{
|
||||||
var cp = Game.viewport.Location
|
var cp = Game.viewport.Location
|
||||||
+ .5f * new float2(Game.viewport.Width, Game.viewport.Height);
|
+ .5f * new float2(Game.viewport.Width, Game.viewport.Height);
|
||||||
|
|
||||||
var intensity = 24 * 24 * 100 * shakeEffects.Sum(
|
var intensity = 24 * 24 * 100 * shakeEffects.Sum(
|
||||||
e => e.c / (e.b - cp).LengthSquared);
|
e => e.c / (e.b - cp).LengthSquared);
|
||||||
|
|
||||||
return Math.Min(intensity, 10);
|
return Math.Min(intensity, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,95 +1,95 @@
|
|||||||
#region Copyright & License Information
|
#region Copyright & License Information
|
||||||
/*
|
/*
|
||||||
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
|
* Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford.
|
||||||
* This file is part of OpenRA.
|
* This file is part of OpenRA.
|
||||||
*
|
*
|
||||||
* OpenRA is free software: you can redistribute it and/or modify
|
* OpenRA is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* OpenRA is distributed in the hope that it will be useful,
|
* OpenRA is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
|
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenRA;
|
using OpenRA;
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
using OpenRA.Graphics;
|
using OpenRA.Graphics;
|
||||||
using OpenRA.FileFormats;
|
using OpenRA.FileFormats;
|
||||||
using OpenRA.Orders;
|
using OpenRA.Orders;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace OpenRA.Widgets
|
namespace OpenRA.Widgets
|
||||||
{
|
{
|
||||||
class BuildPaletteWidget : Widget
|
class BuildPaletteWidget : Widget
|
||||||
{
|
{
|
||||||
public int Columns = 3;
|
public int Columns = 3;
|
||||||
public int Rows = 5;
|
public int Rows = 5;
|
||||||
|
|
||||||
string currentTab = "Building";
|
string currentTab = "Building";
|
||||||
bool paletteOpen = false;
|
bool paletteOpen = false;
|
||||||
Dictionary<string, string[]> tabImageNames;
|
Dictionary<string, string[]> tabImageNames;
|
||||||
Dictionary<string, Sprite> tabSprites;
|
Dictionary<string, Sprite> tabSprites;
|
||||||
static float2 paletteOpenOrigin = new float2(Game.viewport.Width - 215, 280);
|
static float2 paletteOpenOrigin = new float2(Game.viewport.Width - 215, 280);
|
||||||
static float2 paletteClosedOrigin = new float2(Game.viewport.Width - 16, 280);
|
static float2 paletteClosedOrigin = new float2(Game.viewport.Width - 16, 280);
|
||||||
static float2 paletteOrigin = paletteClosedOrigin;
|
static float2 paletteOrigin = paletteClosedOrigin;
|
||||||
const int paletteAnimationLength = 7;
|
const int paletteAnimationLength = 7;
|
||||||
int paletteAnimationFrame = 0;
|
int paletteAnimationFrame = 0;
|
||||||
bool paletteAnimating = false;
|
bool paletteAnimating = false;
|
||||||
List<Pair<Rectangle, Action<MouseInput>>> buttons = new List<Pair<Rectangle,Action<MouseInput>>>();
|
List<Pair<Rectangle, Action<MouseInput>>> buttons = new List<Pair<Rectangle,Action<MouseInput>>>();
|
||||||
Animation cantBuild;
|
Animation cantBuild;
|
||||||
Animation ready;
|
Animation ready;
|
||||||
Animation clock;
|
Animation clock;
|
||||||
List<string> visibleTabs = new List<string>();
|
List<string> visibleTabs = new List<string>();
|
||||||
|
|
||||||
public BuildPaletteWidget() : base() { }
|
public BuildPaletteWidget() : base() { }
|
||||||
|
|
||||||
public BuildPaletteWidget(Widget other)
|
public BuildPaletteWidget(Widget other)
|
||||||
: base(other)
|
: base(other)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException("Why are you Cloning BuildPalette?");
|
throw new NotImplementedException("Why are you Cloning BuildPalette?");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Widget Clone() { return new BuildPaletteWidget(this); }
|
public override Widget Clone() { return new BuildPaletteWidget(this); }
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
cantBuild = new Animation("clock");
|
cantBuild = new Animation("clock");
|
||||||
cantBuild.PlayFetchIndex("idle", () => 0);
|
cantBuild.PlayFetchIndex("idle", () => 0);
|
||||||
ready = new Animation("pips");
|
ready = new Animation("pips");
|
||||||
ready.PlayRepeating("ready");
|
ready.PlayRepeating("ready");
|
||||||
clock = new Animation("clock");
|
clock = new Animation("clock");
|
||||||
|
|
||||||
tabSprites = Rules.Info.Values
|
tabSprites = Rules.Info.Values
|
||||||
.Where(u => u.Traits.Contains<BuildableInfo>())
|
.Where(u => u.Traits.Contains<BuildableInfo>())
|
||||||
.ToDictionary(
|
.ToDictionary(
|
||||||
u => u.Name,
|
u => u.Name,
|
||||||
u => SpriteSheetBuilder.LoadAllSprites(u.Traits.Get<BuildableInfo>().Icon ?? (u.Name + "icon"))[0]);
|
u => SpriteSheetBuilder.LoadAllSprites(u.Traits.Get<BuildableInfo>().Icon ?? (u.Name + "icon"))[0]);
|
||||||
|
|
||||||
var groups = Rules.Categories();
|
var groups = Rules.Categories();
|
||||||
|
|
||||||
tabImageNames = groups.Select(
|
tabImageNames = groups.Select(
|
||||||
(g, i) => Pair.New(g,
|
(g, i) => Pair.New(g,
|
||||||
OpenRA.Graphics.Util.MakeArray(3,
|
OpenRA.Graphics.Util.MakeArray(3,
|
||||||
n => i.ToString())))
|
n => i.ToString())))
|
||||||
.ToDictionary(a => a.First, a => a.Second);
|
.ToDictionary(a => a.First, a => a.Second);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Tick(World world)
|
public override void Tick(World world)
|
||||||
{
|
{
|
||||||
visibleTabs.Clear();
|
visibleTabs.Clear();
|
||||||
foreach (var q in tabImageNames)
|
foreach (var q in tabImageNames)
|
||||||
if (!Rules.TechTree.BuildableItems(world.LocalPlayer, q.Key).Any())
|
if (!Rules.TechTree.BuildableItems(world.LocalPlayer, q.Key).Any())
|
||||||
{
|
{
|
||||||
@@ -97,84 +97,84 @@ namespace OpenRA.Widgets
|
|||||||
currentTab = null;
|
currentTab = null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
visibleTabs.Add(q.Key);
|
visibleTabs.Add(q.Key);
|
||||||
|
|
||||||
if (currentTab == null)
|
if (currentTab == null)
|
||||||
currentTab = visibleTabs.FirstOrDefault();
|
currentTab = visibleTabs.FirstOrDefault();
|
||||||
|
|
||||||
TickPaletteAnimation(world);
|
TickPaletteAnimation(world);
|
||||||
|
|
||||||
base.Tick(world);
|
base.Tick(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TickPaletteAnimation(World world)
|
void TickPaletteAnimation(World world)
|
||||||
{
|
{
|
||||||
if (!paletteAnimating)
|
if (!paletteAnimating)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Increment frame
|
// Increment frame
|
||||||
if (paletteOpen)
|
if (paletteOpen)
|
||||||
paletteAnimationFrame++;
|
paletteAnimationFrame++;
|
||||||
else
|
else
|
||||||
paletteAnimationFrame--;
|
paletteAnimationFrame--;
|
||||||
|
|
||||||
// Calculate palette position
|
// Calculate palette position
|
||||||
if (paletteAnimationFrame <= paletteAnimationLength)
|
if (paletteAnimationFrame <= paletteAnimationLength)
|
||||||
paletteOrigin = float2.Lerp(paletteClosedOrigin, paletteOpenOrigin, paletteAnimationFrame * 1.0f / paletteAnimationLength);
|
paletteOrigin = float2.Lerp(paletteClosedOrigin, paletteOpenOrigin, paletteAnimationFrame * 1.0f / paletteAnimationLength);
|
||||||
|
|
||||||
var eva = world.WorldActor.Info.Traits.Get<EvaAlertsInfo>();
|
var eva = world.WorldActor.Info.Traits.Get<EvaAlertsInfo>();
|
||||||
|
|
||||||
// Play palette-open sound at the start of the activate anim (open)
|
// Play palette-open sound at the start of the activate anim (open)
|
||||||
if (paletteAnimationFrame == 1 && paletteOpen)
|
if (paletteAnimationFrame == 1 && paletteOpen)
|
||||||
Sound.Play(eva.BuildPaletteOpen);
|
Sound.Play(eva.BuildPaletteOpen);
|
||||||
|
|
||||||
// Play palette-close sound at the start of the activate anim (close)
|
// Play palette-close sound at the start of the activate anim (close)
|
||||||
if (paletteAnimationFrame == paletteAnimationLength + -1 && !paletteOpen)
|
if (paletteAnimationFrame == paletteAnimationLength + -1 && !paletteOpen)
|
||||||
Sound.Play(eva.BuildPaletteClose);
|
Sound.Play(eva.BuildPaletteClose);
|
||||||
|
|
||||||
// Animation is complete
|
// Animation is complete
|
||||||
if ((paletteAnimationFrame == 0 && !paletteOpen)
|
if ((paletteAnimationFrame == 0 && !paletteOpen)
|
||||||
|| (paletteAnimationFrame == paletteAnimationLength && paletteOpen))
|
|| (paletteAnimationFrame == paletteAnimationLength && paletteOpen))
|
||||||
{
|
{
|
||||||
paletteAnimating = false;
|
paletteAnimating = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetCurrentTab(string produces)
|
public void SetCurrentTab(string produces)
|
||||||
{
|
{
|
||||||
if (!paletteOpen)
|
if (!paletteOpen)
|
||||||
paletteAnimating = true;
|
paletteAnimating = true;
|
||||||
paletteOpen = true;
|
paletteOpen = true;
|
||||||
currentTab = produces;
|
currentTab = produces;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool HandleInput(MouseInput mi)
|
public override bool HandleInput(MouseInput mi)
|
||||||
{
|
{
|
||||||
// Are we able to handle this event?
|
// Are we able to handle this event?
|
||||||
if (!IsVisible() || !GetEventBounds().Contains(mi.Location.X,mi.Location.Y))
|
if (!IsVisible() || !GetEventBounds().Contains(mi.Location.X,mi.Location.Y))
|
||||||
return base.HandleInput(mi);
|
return base.HandleInput(mi);
|
||||||
|
|
||||||
if (base.HandleInput(mi))
|
if (base.HandleInput(mi))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (mi.Event == MouseInputEvent.Down)
|
if (mi.Event == MouseInputEvent.Down)
|
||||||
{
|
{
|
||||||
var action = buttons.Where(a => a.First.Contains(mi.Location.ToPoint()))
|
var action = buttons.Where(a => a.First.Contains(mi.Location.ToPoint()))
|
||||||
.Select(a => a.Second).FirstOrDefault();
|
.Select(a => a.Second).FirstOrDefault();
|
||||||
if (action == null)
|
if (action == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
action(mi);
|
action(mi);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Draw (World world)
|
public override void Draw (World world)
|
||||||
{
|
{
|
||||||
int paletteHeight = DrawPalette(world, currentTab);
|
int paletteHeight = DrawPalette(world, currentTab);
|
||||||
DrawBuildTabs(world, paletteHeight);
|
DrawBuildTabs(world, paletteHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
int DrawPalette(World world, string queueName)
|
int DrawPalette(World world, string queueName)
|
||||||
@@ -307,98 +307,107 @@ namespace OpenRA.Widgets
|
|||||||
Game.chrome.renderer.RgbaSpriteRenderer.Flush();
|
Game.chrome.renderer.RgbaSpriteRenderer.Flush();
|
||||||
|
|
||||||
return 48 * y + 9;
|
return 48 * y + 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
Action<MouseInput> HandleClick(string name, World world)
|
Action<MouseInput> HandleClick(string name, World world)
|
||||||
{
|
{
|
||||||
return mi => {
|
return mi => {
|
||||||
var eva = world.WorldActor.Info.Traits.Get<EvaAlertsInfo>();
|
var eva = world.WorldActor.Info.Traits.Get<EvaAlertsInfo>();
|
||||||
Sound.Play(eva.TabClick);
|
Sound.Play(eva.TabClick);
|
||||||
|
|
||||||
if (name != null)
|
if (name != null)
|
||||||
HandleBuildPalette(world, name, (mi.Button == MouseButton.Left));
|
HandleBuildPalette(world, name, (mi.Button == MouseButton.Left));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Action<MouseInput> HandleTabClick(string button, World world)
|
static void Hotkey(World world, String name)
|
||||||
{
|
{
|
||||||
return mi => {
|
var eva = world.WorldActor.Info.Traits.Get<EvaAlertsInfo>();
|
||||||
if (mi.Button != MouseButton.Left)
|
Sound.Play(eva.TabClick);
|
||||||
return;
|
|
||||||
|
if (name != null)
|
||||||
var eva = world.WorldActor.Info.Traits.Get<EvaAlertsInfo>();
|
HandleBuildPalette(world, name, true);
|
||||||
Sound.Play(eva.TabClick);
|
}
|
||||||
var wasOpen = paletteOpen;
|
|
||||||
paletteOpen = (currentTab == button && wasOpen) ? false : true;
|
Action<MouseInput> HandleTabClick(string button, World world)
|
||||||
currentTab = button;
|
{
|
||||||
if (wasOpen != paletteOpen)
|
return mi => {
|
||||||
paletteAnimating = true;
|
if (mi.Button != MouseButton.Left)
|
||||||
};
|
return;
|
||||||
}
|
|
||||||
|
var eva = world.WorldActor.Info.Traits.Get<EvaAlertsInfo>();
|
||||||
static string Description( string a )
|
Sound.Play(eva.TabClick);
|
||||||
{
|
var wasOpen = paletteOpen;
|
||||||
if( a[ 0 ] == '@' )
|
paletteOpen = (currentTab == button && wasOpen) ? false : true;
|
||||||
return "any " + a.Substring( 1 );
|
currentTab = button;
|
||||||
else
|
if (wasOpen != paletteOpen)
|
||||||
return Rules.Info[ a.ToLowerInvariant() ].Traits.Get<BuildableInfo>().Description;
|
paletteAnimating = true;
|
||||||
}
|
};
|
||||||
|
}
|
||||||
void HandleBuildPalette( World world, string item, bool isLmb )
|
|
||||||
{
|
static string Description( string a )
|
||||||
var player = world.LocalPlayer;
|
{
|
||||||
var unit = Rules.Info[item];
|
if( a[ 0 ] == '@' )
|
||||||
var queue = player.PlayerActor.traits.Get<Traits.ProductionQueue>();
|
return "any " + a.Substring( 1 );
|
||||||
var eva = world.WorldActor.Info.Traits.Get<EvaAlertsInfo>();
|
else
|
||||||
var producing = queue.AllItems(unit.Category).FirstOrDefault( a => a.Item == item );
|
return Rules.Info[ a.ToLowerInvariant() ].Traits.Get<BuildableInfo>().Description;
|
||||||
|
}
|
||||||
if (isLmb)
|
|
||||||
{
|
static void HandleBuildPalette( World world, string item, bool isLmb )
|
||||||
if (producing != null && producing == queue.CurrentItem(unit.Category))
|
{
|
||||||
{
|
var player = world.LocalPlayer;
|
||||||
if (producing.Done)
|
var unit = Rules.Info[item];
|
||||||
{
|
var queue = player.PlayerActor.traits.Get<Traits.ProductionQueue>();
|
||||||
if (unit.Traits.Contains<BuildingInfo>())
|
var eva = world.WorldActor.Info.Traits.Get<EvaAlertsInfo>();
|
||||||
Game.controller.orderGenerator = new PlaceBuildingOrderGenerator(player.PlayerActor, item);
|
var producing = queue.AllItems(unit.Category).FirstOrDefault( a => a.Item == item );
|
||||||
return;
|
|
||||||
}
|
if (isLmb)
|
||||||
|
{
|
||||||
if (producing.Paused)
|
if (producing != null && producing == queue.CurrentItem(unit.Category))
|
||||||
{
|
{
|
||||||
Game.IssueOrder(Order.PauseProduction(player, item, false));
|
if (producing.Done)
|
||||||
return;
|
{
|
||||||
}
|
if (unit.Traits.Contains<BuildingInfo>())
|
||||||
}
|
Game.controller.orderGenerator = new PlaceBuildingOrderGenerator(player.PlayerActor, item);
|
||||||
|
return;
|
||||||
StartProduction(world, item);
|
}
|
||||||
}
|
|
||||||
else
|
if (producing.Paused)
|
||||||
{
|
{
|
||||||
if (producing != null)
|
Game.IssueOrder(Order.PauseProduction(player, item, false));
|
||||||
{
|
return;
|
||||||
// instant cancel of things we havent really started yet, and things that are finished
|
}
|
||||||
if (producing.Paused || producing.Done || producing.TotalCost == producing.RemainingCost)
|
}
|
||||||
{
|
|
||||||
Sound.Play(eva.CancelledAudio);
|
StartProduction(world, item);
|
||||||
Game.IssueOrder(Order.CancelProduction(player, item));
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
if (producing != null)
|
||||||
Sound.Play(eva.OnHoldAudio);
|
{
|
||||||
Game.IssueOrder(Order.PauseProduction(player, item, true));
|
// instant cancel of things we havent really started yet, and things that are finished
|
||||||
}
|
if (producing.Paused || producing.Done || producing.TotalCost == producing.RemainingCost)
|
||||||
}
|
{
|
||||||
}
|
Sound.Play(eva.CancelledAudio);
|
||||||
}
|
Game.IssueOrder(Order.CancelProduction(player, item));
|
||||||
|
}
|
||||||
void StartProduction( World world, string item )
|
else
|
||||||
{
|
{
|
||||||
var eva = world.WorldActor.Info.Traits.Get<EvaAlertsInfo>();
|
Sound.Play(eva.OnHoldAudio);
|
||||||
var unit = Rules.Info[item];
|
Game.IssueOrder(Order.PauseProduction(player, item, true));
|
||||||
|
}
|
||||||
Sound.Play(unit.Traits.Contains<BuildingInfo>() ? eva.BuildingSelectAudio : eva.UnitSelectAudio);
|
}
|
||||||
Game.IssueOrder(Order.StartProduction(world.LocalPlayer, item,
|
}
|
||||||
Game.controller.GetModifiers().HasModifier(Modifiers.Shift) ? 5 : 1));
|
}
|
||||||
|
|
||||||
|
static void StartProduction( World world, string item )
|
||||||
|
{
|
||||||
|
var eva = world.WorldActor.Info.Traits.Get<EvaAlertsInfo>();
|
||||||
|
var unit = Rules.Info[item];
|
||||||
|
|
||||||
|
Sound.Play(unit.Traits.Contains<BuildingInfo>() ? eva.BuildingSelectAudio : eva.UnitSelectAudio);
|
||||||
|
Game.IssueOrder(Order.StartProduction(world.LocalPlayer, item,
|
||||||
|
Game.controller.GetModifiers().HasModifier(Modifiers.Shift) ? 5 : 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Dictionary<string, string> CategoryNameRemaps = new Dictionary<string, string>
|
static Dictionary<string, string> CategoryNameRemaps = new Dictionary<string, string>
|
||||||
@@ -408,32 +417,32 @@ namespace OpenRA.Widgets
|
|||||||
{ "Plane", "Aircraft" },
|
{ "Plane", "Aircraft" },
|
||||||
{ "Ship", "Ships" },
|
{ "Ship", "Ships" },
|
||||||
{ "Vehicle", "Vehicles" },
|
{ "Vehicle", "Vehicles" },
|
||||||
};
|
};
|
||||||
|
|
||||||
void DrawBuildTabs( World world, int paletteHeight)
|
void DrawBuildTabs( World world, int paletteHeight)
|
||||||
{
|
{
|
||||||
const int tabWidth = 24;
|
const int tabWidth = 24;
|
||||||
const int tabHeight = 40;
|
const int tabHeight = 40;
|
||||||
var x = paletteOrigin.X - tabWidth;
|
var x = paletteOrigin.X - tabWidth;
|
||||||
var y = paletteOrigin.Y + 9;
|
var y = paletteOrigin.Y + 9;
|
||||||
|
|
||||||
var queue = world.LocalPlayer.PlayerActor.traits.Get<Traits.ProductionQueue>();
|
var queue = world.LocalPlayer.PlayerActor.traits.Get<Traits.ProductionQueue>();
|
||||||
|
|
||||||
foreach (var q in tabImageNames)
|
foreach (var q in tabImageNames)
|
||||||
{
|
{
|
||||||
var groupName = q.Key;
|
var groupName = q.Key;
|
||||||
if (!visibleTabs.Contains(groupName))
|
if (!visibleTabs.Contains(groupName))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
string[] tabKeys = { "normal", "ready", "selected" };
|
string[] tabKeys = { "normal", "ready", "selected" };
|
||||||
var producing = queue.CurrentItem(groupName);
|
var producing = queue.CurrentItem(groupName);
|
||||||
var index = q.Key == currentTab ? 2 : (producing != null && producing.Done) ? 1 : 0;
|
var index = q.Key == currentTab ? 2 : (producing != null && producing.Done) ? 1 : 0;
|
||||||
var race = world.LocalPlayer.Country.Race;
|
var race = world.LocalPlayer.Country.Race;
|
||||||
WidgetUtils.DrawRGBA(ChromeProvider.GetImage(Game.chrome.renderer,"tabs-"+tabKeys[index], race+"-"+q.Key), new float2(x, y));
|
WidgetUtils.DrawRGBA(ChromeProvider.GetImage(Game.chrome.renderer,"tabs-"+tabKeys[index], race+"-"+q.Key), new float2(x, y));
|
||||||
|
|
||||||
var rect = new Rectangle((int)x,(int)y,(int)tabWidth,(int)tabHeight);
|
var rect = new Rectangle((int)x,(int)y,(int)tabWidth,(int)tabHeight);
|
||||||
buttons.Add(Pair.New(rect, HandleTabClick(groupName, world)));
|
buttons.Add(Pair.New(rect, HandleTabClick(groupName, world)));
|
||||||
|
|
||||||
if (rect.Contains(Game.chrome.lastMousePos.ToPoint()))
|
if (rect.Contains(Game.chrome.lastMousePos.ToPoint()))
|
||||||
{
|
{
|
||||||
var text = CategoryNameRemaps.ContainsKey(groupName) ? CategoryNameRemaps[groupName] : groupName;
|
var text = CategoryNameRemaps.ContainsKey(groupName) ? CategoryNameRemaps[groupName] : groupName;
|
||||||
@@ -444,20 +453,20 @@ namespace OpenRA.Widgets
|
|||||||
|
|
||||||
Game.chrome.renderer.BoldFont.DrawText(text,
|
Game.chrome.renderer.BoldFont.DrawText(text,
|
||||||
new float2(rect.Left - sz.X - 20, rect.Top + 12), Color.White);
|
new float2(rect.Left - sz.X - 20, rect.Top + 12), Color.White);
|
||||||
}
|
}
|
||||||
|
|
||||||
y += tabHeight;
|
y += tabHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
Game.chrome.renderer.RgbaSpriteRenderer.Flush();
|
Game.chrome.renderer.RgbaSpriteRenderer.Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawRightAligned(string text, int2 pos, Color c)
|
void DrawRightAligned(string text, int2 pos, Color c)
|
||||||
{
|
{
|
||||||
Game.chrome.renderer.BoldFont.DrawText(text,
|
Game.chrome.renderer.BoldFont.DrawText(text,
|
||||||
pos - new int2(Game.chrome.renderer.BoldFont.Measure(text).X, 0), c);
|
pos - new int2(Game.chrome.renderer.BoldFont.Measure(text).X, 0), c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawProductionTooltip(World world, string unit, int2 pos)
|
void DrawProductionTooltip(World world, string unit, int2 pos)
|
||||||
{
|
{
|
||||||
pos.Y += 15;
|
pos.Y += 15;
|
||||||
@@ -481,6 +490,9 @@ namespace OpenRA.Widgets
|
|||||||
DrawRightAligned( "${0}".F(buildable.Cost), pos + new int2(-5,5),
|
DrawRightAligned( "${0}".F(buildable.Cost), pos + new int2(-5,5),
|
||||||
world.LocalPlayer.Cash + world.LocalPlayer.Ore >= buildable.Cost ? Color.White : Color.Red);
|
world.LocalPlayer.Cash + world.LocalPlayer.Ore >= buildable.Cost ? Color.White : Color.Red);
|
||||||
|
|
||||||
|
if (buildable.Hotkey != null)
|
||||||
|
DrawRightAligned("{0}".F(buildable.Hotkey.ToUpper()), pos + new int2(-5, 35),Color.White);
|
||||||
|
|
||||||
var bi = info.Traits.GetOrDefault<BuildingInfo>();
|
var bi = info.Traits.GetOrDefault<BuildingInfo>();
|
||||||
if (bi != null)
|
if (bi != null)
|
||||||
DrawRightAligned("{1}{0}".F(bi.Power, bi.Power > 0 ? "+" : ""), pos + new int2(-5, 20),
|
DrawRightAligned("{1}{0}".F(bi.Power, bi.Power > 0 ? "+" : ""), pos + new int2(-5, 20),
|
||||||
@@ -506,6 +518,43 @@ namespace OpenRA.Widgets
|
|||||||
p.ToInt2(), Color.White);
|
p.ToInt2(), Color.White);
|
||||||
|
|
||||||
Game.chrome.renderer.RgbaSpriteRenderer.Flush();
|
Game.chrome.renderer.RgbaSpriteRenderer.Flush();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public static void DoBuildingHotkey(char c, World world)
|
||||||
|
{
|
||||||
|
if (Game.world.LocalPlayer == null) return;
|
||||||
|
|
||||||
|
var buildable = Rules.TechTree.BuildableItems(Game.world.LocalPlayer, Chrome.rootWidget.GetWidget<BuildPaletteWidget>("INGAME_BUILD_PALETTE").currentTab);
|
||||||
|
|
||||||
|
var toBuild = buildable.FirstOrDefault(b => Rules.Info[b.ToLowerInvariant()].Traits.Get<BuildableInfo>().Hotkey == c.ToString());
|
||||||
|
|
||||||
|
if (toBuild != null) Hotkey(world, toBuild);
|
||||||
|
|
||||||
|
}
|
||||||
|
public static void TabChange(bool shift)
|
||||||
|
{
|
||||||
|
var p = Chrome.rootWidget.GetWidget<BuildPaletteWidget>("INGAME_BUILD_PALETTE");
|
||||||
|
int size = p.visibleTabs.Count();
|
||||||
|
if (size > 0)
|
||||||
|
{
|
||||||
|
string last = p.visibleTabs.Last();
|
||||||
|
string first = p.visibleTabs.First();
|
||||||
|
int current = p.visibleTabs.IndexOf(p.currentTab);
|
||||||
|
if (!shift)
|
||||||
|
{
|
||||||
|
if (current + 1 >= size)
|
||||||
|
p.SetCurrentTab(p.visibleTabs.FirstOrDefault());
|
||||||
|
else
|
||||||
|
p.SetCurrentTab(p.visibleTabs[current + 1]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (current - 1 < 0)
|
||||||
|
p.SetCurrentTab(p.visibleTabs.LastOrDefault());
|
||||||
|
else
|
||||||
|
p.SetCurrentTab(p.visibleTabs[current - 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user