diff --git a/OpenRA.Game/Traits/Player/PlayerResources.cs b/OpenRA.Game/Traits/Player/PlayerResources.cs index e0742edd6b..d80efe4335 100644 --- a/OpenRA.Game/Traits/Player/PlayerResources.cs +++ b/OpenRA.Game/Traits/Player/PlayerResources.cs @@ -86,7 +86,7 @@ namespace OpenRA.Traits public int DisplayCash; public int DisplayOre; - public int IncomePerMin; + public int IncomePerMinute; int incomeCounter; public double IncomeChange; @@ -206,8 +206,8 @@ namespace OpenRA.Traits if (self.World.FrameNumber % 1500 == 0) { - IncomeChange = IncomePerMin == 0 ? 0 : (double)(incomeCounter - IncomePerMin) / IncomePerMin; - IncomePerMin = incomeCounter; + IncomeChange = IncomePerMinute == 0 ? 0 : (double)(incomeCounter - IncomePerMinute) / IncomePerMinute; + IncomePerMinute = incomeCounter; incomeCounter = 0; } } diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 988c9c1d70..565d1ba819 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -256,6 +256,7 @@ + diff --git a/OpenRA.Mods.RA/OrderCounter.cs b/OpenRA.Mods.RA/OrderCounter.cs new file mode 100644 index 0000000000..9b9182fa70 --- /dev/null +++ b/OpenRA.Mods.RA/OrderCounter.cs @@ -0,0 +1,49 @@ +#region Copyright & License Information +/* + * Copyright 2007-2011 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 OpenRA.Traits; + +namespace OpenRA.Mods.RA +{ + public class OrderCounterInfo : TraitInfo { } + + public class OrderCounter : IResolveOrder + { + public int Orders; + + public void ResolveOrder(Actor self, Order order) + { + switch (order.OrderString) + { + case "Chat": + case "TeamChat": + case "HandshakeResponse": + case "PauseRequest": + case "PauseGame": + case "StartGame": + case "Disconnected": + case "ServerError": + case "SyncInfo": + return; + } + if (order.OrderString.StartsWith("Dev")) + { + return; + } + Orders++; + } + + public static double OrdersPerMinute(OrderCounter counter, World world) + { + return world.FrameNumber == 0 ? 0 : counter.Orders / (world.FrameNumber / 1500.0); + } + } +} diff --git a/OpenRA.Mods.RA/Widgets/Logic/ObserverStatsLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/ObserverStatsLogic.cs index 5744641c1b..58093544db 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/ObserverStatsLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/ObserverStatsLogic.cs @@ -23,11 +23,11 @@ namespace OpenRA.Mods.RA.Widgets.Logic { ContainerWidget basicStatsHeaders; ContainerWidget economicStatsHeaders; - ContainerWidget supportStatsHeaders; + ContainerWidget productionStatsHeaders; ScrollPanelWidget playerStatsPanel; ScrollItemWidget basicPlayerTemplate; ScrollItemWidget economicPlayerTemplate; - ScrollItemWidget supportPlayerTemplate; + ScrollItemWidget productionPlayerTemplate; ScrollItemWidget teamTemplate; DropDownButtonWidget statsDropDown; LabelWidget title; @@ -44,14 +44,14 @@ namespace OpenRA.Mods.RA.Widgets.Logic basicStatsHeaders = widget.Get("BASIC_STATS_HEADERS"); economicStatsHeaders = widget.Get("ECONOMIC_STATS_HEADERS"); - supportStatsHeaders = widget.Get("SUPPORT_STATS_HEADERS"); + productionStatsHeaders = widget.Get("PRODUCTION_STATS_HEADERS"); playerStatsPanel = widget.Get("PLAYER_STATS_PANEL"); playerStatsPanel.Layout = new GridLayout(playerStatsPanel); basicPlayerTemplate = playerStatsPanel.Get("BASIC_PLAYER_TEMPLATE"); economicPlayerTemplate = playerStatsPanel.Get("ECONOMIC_PLAYER_TEMPLATE"); - supportPlayerTemplate = playerStatsPanel.Get("SUPPORT_PLAYER_TEMPLATE"); + productionPlayerTemplate = playerStatsPanel.Get("PRODUCTION_PLAYER_TEMPLATE"); teamTemplate = playerStatsPanel.Get("TEAM_TEMPLATE"); @@ -85,13 +85,13 @@ namespace OpenRA.Mods.RA.Widgets.Logic }, new StatsDropDownOption { - Title = "Support", - IsSelected = () => supportStatsHeaders.Visible, + Title = "Production", + IsSelected = () => productionStatsHeaders.Visible, OnClick = () => { ClearStats(); - statsDropDown.GetText = () => "Support"; - LoadStats(SupportStats); + statsDropDown.GetText = () => "Production"; + LoadStats(ProductionStats); } } }; @@ -116,7 +116,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic playerStatsPanel.Children.Clear(); basicStatsHeaders.Visible = false; economicStatsHeaders.Visible = false; - supportStatsHeaders.Visible = false; + productionStatsHeaders.Visible = false; } void LoadStats(Func forEachPlayer) @@ -137,14 +137,17 @@ namespace OpenRA.Mods.RA.Widgets.Logic } } - ScrollItemWidget SupportStats(Player player) + ScrollItemWidget ProductionStats(Player player) { - supportStatsHeaders.Visible = true; - var template = SetupPlayerScrollItemWidget(supportPlayerTemplate, player); + productionStatsHeaders.Visible = true; + var template = SetupPlayerScrollItemWidget(productionPlayerTemplate, player); AddPlayerFlagAndName(template, player); - var supportPowers = template.Get("SUPPORT_POWERS"); + var production = template.Get("PRODUCTION_ICONS"); + production.GetPlayer = () => player; + + var supportPowers = template.Get("SUPPORT_POWER_ICONS"); supportPowers.GetPlayer = () => player; return template; @@ -159,12 +162,12 @@ namespace OpenRA.Mods.RA.Widgets.Logic var res = player.PlayerActor.Trait(); template.Get("CASH").GetText = () => "$" + (res.DisplayCash + res.DisplayOre); - template.Get("INCOME").GetText = () => "$" + res.IncomePerMin; + template.Get("INCOME").GetText = () => "$" + res.IncomePerMinute; var change = template.Get("INCOME_CHANGE"); change.GetText = () => Math.Round(res.IncomeChange * 100, 1, MidpointRounding.AwayFromZero) + "%"; change.GetColor = () => { - var c = Math.Round(res.IncomeChange, 1, MidpointRounding.AwayFromZero); + var c = Math.Round(res.IncomeChange * 100, 1, MidpointRounding.AwayFromZero); if (c < 0) return Color.Red; if (c > 0) return Color.LimeGreen; return Color.White; @@ -178,8 +181,8 @@ namespace OpenRA.Mods.RA.Widgets.Logic template.Get("TOTAL_EARNED").GetText = () => "$" + res.TotalEarned; template.Get("TOTAL_SPENT").GetText = () => "$" + res.TotalSpent; - var numHarvesters = template.Get("NUMBER_HARVESTERS"); - numHarvesters.GetText = () => world.Actors.Count(a => a.Owner == player && !a.IsDead() && a.HasTrait()).ToString(); + var harvesters = template.Get("NUMBER_HARVESTERS"); + harvesters.GetText = () => world.Actors.Count(a => a.Owner == player && !a.IsDead() && a.HasTrait()).ToString(); return template; } @@ -193,7 +196,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic var res = player.PlayerActor.Trait(); template.Get("CASH").GetText = () => "$" + (res.DisplayCash + res.DisplayOre); - template.Get("INCOME").GetText = () => "$" + res.IncomePerMin; + template.Get("INCOME").GetText = () => "$" + res.IncomePerMinute; var powerRes = player.PlayerActor.Trait(); var power = template.Get("POWER"); @@ -202,9 +205,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic template.Get("KILLS").GetText = () => player.Kills.ToString(); template.Get("DEATHS").GetText = () => player.Deaths.ToString(); - - var production = template.Get("PRODUCTION_ICONS"); - production.GetPlayer = () => player; + template.Get("ORDERS").GetText = () => OrderCounter.OrdersPerMinute(player.PlayerActor.Trait(), world).ToString("F1"); return template; } diff --git a/mods/ra/chrome/ingame.yaml b/mods/ra/chrome/ingame.yaml index 81286f367e..81c3e18e08 100644 --- a/mods/ra/chrome/ingame.yaml +++ b/mods/ra/chrome/ingame.yaml @@ -468,14 +468,14 @@ Container@OBSERVER_ROOT: Font:Bold Text:Deaths Align:Right - Label@PRODUCTION_HEADER - X:585 + Label@ORDERS_HEADER: + X:605 Y:40 - Width:PARENT_RIGHT-625 + Width:40 Height:25 Font:Bold - Text:Production - Align:Center + Text:APM + Align:Right Container@ECONOMIC_STATS_HEADERS: X:0 Y:0 @@ -532,7 +532,7 @@ Container@OBSERVER_ROOT: Font:Bold Text:Harvesters Align:Right - Container@SUPPORT_STATS_HEADERS: + Container@PRODUCTION_STATS_HEADERS: X:0 Y:0 Width:PARENT_RIGHT @@ -545,14 +545,20 @@ Container@OBSERVER_ROOT: Height:25 Font:Bold Text:Player - Label@SUPPORT_POWERS_HEADER: + Label@PRODUCTION_HEADER X:245 Y:40 - Width:300 + Width:320 + Height:25 + Font:Bold + Text:Production + Label@SUPPORT_POWERS_HEADER: + X:565 + Y:40 + Width:320 Height:25 Font:Bold Text:Support Powers - Align:Center ScrollPanel@PLAYER_STATS_PANEL: X:25 Y:70 @@ -618,11 +624,12 @@ Container@OBSERVER_ROOT: Width:40 Height:PARENT_BOTTOM Align:Right - ObserverProductionIcons@PRODUCTION_ICONS: + Label@ORDERS: X:575 Y:0 - Width:240 + Width:40 Height:PARENT_BOTTOM + Align:Right ScrollItem@ECONOMIC_PLAYER_TEMPLATE: X:0 Y:0 @@ -678,7 +685,7 @@ Container@OBSERVER_ROOT: Width:60 Height:PARENT_BOTTOM Align:Right - ScrollItem@SUPPORT_PLAYER_TEMPLATE: + ScrollItem@PRODUCTION_PLAYER_TEMPLATE: X:0 Y:0 Width:PARENT_RIGHT-35 @@ -697,10 +704,15 @@ Container@OBSERVER_ROOT: Width:160 Height:PARENT_BOTTOM Font:Bold - ObserverSupportPowerIcons@SUPPORT_POWERS: + ObserverProductionIcons@PRODUCTION_ICONS: X:215 Y:0 - Width:300 + Width:320 + Height:PARENT_BOTTOM + ObserverSupportPowerIcons@SUPPORT_POWER_ICONS: + X:535 + Y:0 + Width:320 Height:PARENT_BOTTOM Background@FMVPLAYER: Width:WINDOW_RIGHT diff --git a/mods/ra/rules/system.yaml b/mods/ra/rules/system.yaml index 5b51cd4c91..c449756dda 100644 --- a/mods/ra/rules/system.yaml +++ b/mods/ra/rules/system.yaml @@ -190,6 +190,7 @@ Player: GpsWatcher: Shroud: BaseAttackNotifier: + OrderCounter: World: OpenWidgetAtGameStart: