resources moved off player onto a synced trait

This commit is contained in:
Chris Forbes
2010-05-12 18:29:25 +12:00
parent a4592e7019
commit 46e465cf33
24 changed files with 186 additions and 152 deletions

View File

@@ -63,7 +63,7 @@ namespace OpenRA
public void AddLine(Session.Client p, string text)
{
AddLine(Player.PlayerColors( Game.world )[p.PaletteIndex].Color, p.Name, text);
AddLine(Game.world.PlayerColors()[p.PaletteIndex].Color, p.Name, text);
}
public void AddLine(Color c, string from, string text)

View File

@@ -188,7 +188,7 @@ namespace OpenRA.Graphics
lineRenderer.FillRect(new RectangleF(
Game.viewport.Location.X + pos.X + 2,
Game.viewport.Location.Y + pos.Y + 2,
12, 12), Player.PlayerColors(world)[ p.Second.PaletteIndex % Player.PlayerColors(world).Count() ].Color);
12, 12), Game.world.PlayerColors()[p.Second.PaletteIndex % Game.world.PlayerColors().Count()].Color);
rgbaRenderer.DrawSprite(ownedSpawnPoint, pos, "chrome");
}

View File

@@ -84,6 +84,7 @@
<Compile Include="Traits\AI\EmitInfantryOnSell.cs" />
<Compile Include="Traits\AI\ReturnOnIdle.cs" />
<Compile Include="Traits\Attack\AttackLeap.cs" />
<Compile Include="Traits\Player\PlayerResources.cs" />
<Compile Include="Traits\RevealsShroud.cs" />
<Compile Include="Traits\Player\ConquestVictoryConditions.cs" />
<Compile Include="Traits\Modifiers\HiddenUnderFog.cs" />

View File

@@ -16,9 +16,8 @@
* You should have received a copy of the GNU General Public License
* along with OpenRA. If not, see <http://www.gnu.org/licenses/>.
*/
#endregion
using System;
#endregion
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
@@ -43,23 +42,9 @@ namespace OpenRA
public readonly CountryInfo Country;
public readonly int Index;
public int Cash = 10000;
public int Ore = 0;
public int OreCapacity;
public int DisplayCash = 0;
public int PowerProvided = 0;
public int PowerDrained = 0;
public ShroudRenderer Shroud;
public World World { get; private set; }
public static List<PlayerColorPaletteInfo> PlayerColors(World world)
{
return world.WorldActor.Info.Traits.WithInterface<PlayerColorPaletteInfo>()
.Where(p => p.Playable)
.ToList();
}
public Player( World world, Session.Client client )
{
World = world;
@@ -69,9 +54,9 @@ namespace OpenRA
if (client != null)
{
Index = client.Index;
Palette = PlayerColors(world)[client.PaletteIndex % PlayerColors(world).Count()].Name;
Color = PlayerColors(world)[client.PaletteIndex % PlayerColors(world).Count()].Color;
Index = client.Index;
Palette = world.PlayerColors()[client.PaletteIndex % world.PlayerColors().Count()].Name;
Color = world.PlayerColors()[client.PaletteIndex % world.PlayerColors().Count()].Color;
PlayerName = client.Name;
InternalName = "Multi{0}".F(client.Index);
}
@@ -88,101 +73,13 @@ namespace OpenRA
?? world.GetCountries().Random(world.SharedRandom);
}
void UpdatePower()
{
var oldBalance = PowerProvided - PowerDrained;
PowerProvided = 0;
PowerDrained = 0;
var myBuildings = World.Queries.OwnedBy[this]
.WithTrait<Building>();
foreach (var a in myBuildings)
{
var p = a.Trait.GetPowerUsage();
if (p > 0)
PowerProvided += p;
else
PowerDrained -= p;
}
if (PowerProvided - PowerDrained < 0)
if (PowerProvided - PowerDrained != oldBalance)
GiveAdvice(World.WorldActor.Info.Traits.Get<EvaAlertsInfo>().LowPower);
}
public float GetSiloFullness() { return (float)Ore / OreCapacity; }
public PowerState GetPowerState()
{
if (PowerProvided >= PowerDrained) return PowerState.Normal;
if (PowerProvided > PowerDrained / 2) return PowerState.Low;
return PowerState.Critical;
}
void GiveAdvice(string advice)
public void GiveAdvice(string advice)
{
// todo: store the condition or something.
// repeat after World.Defaults.SpeakDelay, as long as the condition holds.
Sound.PlayToPlayer(this, advice);
}
public void GiveCash( int num ) { Cash += num; }
public void GiveOre(int num)
{
Ore += num;
if (Ore > OreCapacity)
Ore = OreCapacity; // trim off the overflow.
if (Ore > .8 * OreCapacity)
GiveAdvice(World.WorldActor.Info.Traits.Get<EvaAlertsInfo>().SilosNeeded);
}
public bool TakeCash( int num )
{
if (Cash + Ore < num) return false;
if (Ore <= num)
{
num -= Ore;
Ore = 0;
Cash -= num;
}
else
Ore -= num;
return true;
}
const float displayCashFracPerFrame = .07f;
const int displayCashDeltaPerFrame = 37;
public void Tick()
{
UpdatePower();
OreCapacity = World.Queries.OwnedBy[this].WithTrait<StoresOre>()
.Sum(a => a.Actor.Info.Traits.Get<StoresOreInfo>().Capacity);
var totalMoney = Cash + Ore;
var diff = Math.Abs(totalMoney - DisplayCash);
var move = Math.Min(Math.Max((int)(diff * displayCashFracPerFrame),
displayCashDeltaPerFrame), diff);
var eva = World.WorldActor.Info.Traits.Get<EvaAlertsInfo>();
if (DisplayCash < totalMoney)
{
DisplayCash += move;
Sound.PlayToPlayer(this, eva.CashTickUp);
}
else if (DisplayCash > totalMoney)
{
DisplayCash -= move;
Sound.PlayToPlayer(this, eva.CashTickDown);
}
}
public Dictionary<Player, Stance> Stances = new Dictionary<Player, Stance>();
}
}

View File

@@ -43,7 +43,7 @@ namespace OpenRA.Traits.Activities
var costPerHp = (hostBuilding.Info.Traits.Get<RepairsUnitsInfo>().URepairPercent * unitCost) / hp;
var hpToRepair = Math.Min(hostBuilding.Info.Traits.Get<RepairsUnitsInfo>().URepairStep, hp - self.Health);
var cost = (int)Math.Ceiling(costPerHp * hpToRepair);
if (!self.Owner.TakeCash(cost))
if (!self.Owner.PlayerActor.traits.Get<PlayerResources>().TakeCash(cost))
{
remainingTicks = 1;
return this;

View File

@@ -35,7 +35,7 @@ namespace OpenRA.Traits.Activities
var hp = self.Info.Traits.Get<OwnedActorInfo>().HP;
var refund = self.World.Defaults.RefundPercent * self.Health * cost / hp;
self.Owner.GiveCash((int)refund);
self.Owner.PlayerActor.traits.Get<PlayerResources>().GiveCash((int)refund);
self.Health = 0;
foreach (var ns in self.traits.WithInterface<INotifySold>())
ns.Sold(self);

View File

@@ -129,7 +129,7 @@ namespace OpenRA.Traits
var costPerHp = (self.World.Defaults.RepairPercent * buildingValue) / maxHP;
var hpToRepair = Math.Min(self.World.Defaults.RepairStep, maxHP - self.Health);
var cost = (int)Math.Ceiling(costPerHp * hpToRepair);
if (!self.Owner.TakeCash(cost))
if (!self.Owner.PlayerActor.traits.Get<PlayerResources>().TakeCash(cost))
{
remainingTicks = 1;
return;

View File

@@ -0,0 +1,127 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace OpenRA.Traits
{
class PlayerResourcesInfo : ITraitInfo
{
public readonly int InitialCash = 10000;
public readonly int InitialOre = 0;
public object Create(Actor self) { return new PlayerResources(self.Owner); }
}
public class PlayerResources : ITick
{
Player Owner;
public PlayerResources(Player p)
{
Owner = p;
Cash = p.PlayerActor.Info.Traits.Get<PlayerResourcesInfo>().InitialCash;
Ore = p.PlayerActor.Info.Traits.Get<PlayerResourcesInfo>().InitialOre;
}
[Sync]
public int Cash;
[Sync]
public int Ore;
[Sync]
public int OreCapacity;
[Sync]
public int DisplayCash;
[Sync]
public int PowerProvided;
[Sync]
public int PowerDrained;
void UpdatePower()
{
var oldBalance = PowerProvided - PowerDrained;
PowerProvided = 0;
PowerDrained = 0;
var myBuildings = Owner.World.Queries.OwnedBy[Owner].WithTrait<Building>();
foreach (var a in myBuildings)
{
var q = a.Trait.GetPowerUsage();
if (q > 0)
PowerProvided += q;
else
PowerDrained -= q;
}
if (PowerProvided - PowerDrained < 0)
if (PowerProvided - PowerDrained != oldBalance)
Owner.GiveAdvice(Rules.Info["world"].Traits.Get<EvaAlertsInfo>().LowPower);
}
public PowerState GetPowerState()
{
if (PowerProvided >= PowerDrained) return PowerState.Normal;
if (PowerProvided > PowerDrained / 2) return PowerState.Low;
return PowerState.Critical;
}
public float GetSiloFullness() { return (float)Ore / OreCapacity; }
public void GiveCash(int num) { Cash += num; }
public void GiveOre(int num)
{
Ore += num;
if (Ore > OreCapacity)
Ore = OreCapacity; // trim off the overflow.
if (Ore > .8 * OreCapacity)
Owner.GiveAdvice(Owner.World.WorldActor.Info.Traits.Get<EvaAlertsInfo>().SilosNeeded);
}
public bool TakeCash(int num)
{
if (Cash + Ore < num) return false;
if (Ore <= num)
{
num -= Ore;
Ore = 0;
Cash -= num;
}
else
Ore -= num;
return true;
}
const float displayCashFracPerFrame = .07f;
const int displayCashDeltaPerFrame = 37;
public void Tick(Actor self)
{
UpdatePower();
OreCapacity = self.World.Queries.OwnedBy[Owner].WithTrait<StoresOre>()
.Sum(a => a.Actor.Info.Traits.Get<StoresOreInfo>().Capacity);
var totalMoney = Cash + Ore;
var diff = Math.Abs(totalMoney - DisplayCash);
var move = Math.Min(Math.Max((int)(diff * displayCashFracPerFrame),
displayCashDeltaPerFrame), diff);
var eva = self.World.WorldActor.Info.Traits.Get<EvaAlertsInfo>();
if (DisplayCash < totalMoney)
{
DisplayCash += move;
Sound.PlayToPlayer(self.Owner, eva.CashTickUp);
}
else if (DisplayCash > totalMoney)
{
DisplayCash -= move;
Sound.PlayToPlayer(self.Owner, eva.CashTickDown);
}
}
}
}

View File

@@ -47,7 +47,7 @@ namespace OpenRA.Traits
{
while( p.Value.Count > 0 && !Rules.TechTree.BuildableItems( self.Owner, p.Key ).Contains( p.Value[ 0 ].Item ) )
{
self.Owner.GiveCash(p.Value[0].TotalCost - p.Value[0].RemainingCost); // refund what's been paid so far.
self.Owner.PlayerActor.traits.Get<PlayerResources>().GiveCash(p.Value[0].TotalCost - p.Value[0].RemainingCost); // refund what's been paid so far.
FinishProduction(p.Key);
}
if( p.Value.Count > 0 )
@@ -137,7 +137,7 @@ namespace OpenRA.Traits
else if( lastIndex == 0 )
{
var item = queue[0];
self.Owner.GiveCash(item.TotalCost - item.RemainingCost); // refund what's been paid so far.
self.Owner.PlayerActor.traits.Get<PlayerResources>().GiveCash(item.TotalCost - item.RemainingCost); // refund what's been paid so far.
FinishProduction(category);
}
}
@@ -232,7 +232,7 @@ namespace OpenRA.Traits
if (Paused) return;
if (player.GetPowerState() != PowerState.Normal)
if (player.PlayerActor.traits.Get<PlayerResources>().GetPowerState() != PowerState.Normal)
{
if (--slowdown <= 0)
slowdown = player.PlayerActor.Info.Traits.Get<ProductionQueueInfo>().LowPowerSlowdown;
@@ -241,7 +241,7 @@ namespace OpenRA.Traits
}
var costThisFrame = RemainingCost / RemainingTime;
if (costThisFrame != 0 && !player.TakeCash(costThisFrame)) return;
if (costThisFrame != 0 && !player.PlayerActor.traits.Get<PlayerResources>().TakeCash(costThisFrame)) return;
RemainingCost -= costThisFrame;
RemainingTime -= 1;
if (RemainingTime > 0) return;

View File

@@ -34,7 +34,8 @@ namespace OpenRA.Traits
public void BuildingComplete( Actor self )
{
anim.PlayFetchIndex( "idle", () => (int)( 4.9 * self.Owner.GetSiloFullness() ) );
anim.PlayFetchIndex( "idle",
() => (int)( 4.9 * self.Owner.PlayerActor.traits.Get<PlayerResources>().GetSiloFullness() ) );
}
}
}

View File

@@ -34,8 +34,8 @@ namespace OpenRA.Traits
{
// Steal half the ore the building holds
var toSteal = self.Info.Traits.Get<StoresOreInfo>().Capacity / 2;
self.Owner.TakeCash(toSteal);
thief.Owner.GiveCash(toSteal);
self.Owner.PlayerActor.traits.Get<PlayerResources>().TakeCash(toSteal);
thief.Owner.PlayerActor.traits.Get<PlayerResources>().GiveCash(toSteal);
var eva = thief.World.WorldActor.Info.Traits.Get<EvaAlertsInfo>();
Sound.PlayToPlayer(thief.Owner, eva.CreditsStolen);
@@ -46,7 +46,7 @@ namespace OpenRA.Traits
var numPips = self.Info.Traits.Get<StoresOreInfo>().Pips;
return Graphics.Util.MakeArray( numPips,
i => (self.World.LocalPlayer.GetSiloFullness() > i * 1.0f / numPips)
i => (self.World.LocalPlayer.PlayerActor.traits.Get<PlayerResources>().GetSiloFullness() > i * 1.0f / numPips)
? PipType.Yellow : PipType.Transparent );
}
}

View File

@@ -108,7 +108,7 @@ namespace OpenRA.Traits
.Where(a => Rules.Info[a].Traits.Get<BuildableInfo>().Owner.Contains(Owner.Country.Race));
if (Info.Prerequisites.Count() == 0)
return Owner.GetPowerState() == PowerState.Normal;
return Owner.PlayerActor.traits.Get<PlayerResources>().GetPowerState() == PowerState.Normal;
return effectivePrereq.Any() &&
effectivePrereq.All(a => buildings[a].Any(b => !b.traits.Get<Building>().Disabled));

View File

@@ -487,17 +487,14 @@ namespace OpenRA.Widgets
Game.chrome.renderer.BoldFont.DrawText(buildable.Description, p.ToInt2() + new int2(5, 5), Color.White);
DrawRightAligned( "${0}".F(buildable.Cost), pos + new int2(-5,5),
world.LocalPlayer.Cash + world.LocalPlayer.Ore >= buildable.Cost ? Color.White : Color.Red);
DrawRightAligned("${0}".F(buildable.Cost), pos + new int2(-5, 5), Color.White);
if (buildable.Hotkey != null)
DrawRightAligned("{0}".F(buildable.Hotkey.ToUpper()), pos + new int2(-5, 35),Color.White);
var bi = info.Traits.GetOrDefault<BuildingInfo>();
if (bi != null)
DrawRightAligned("{1}{0}".F(bi.Power, bi.Power > 0 ? "+" : ""), pos + new int2(-5, 20),
world.LocalPlayer.PowerProvided - world.LocalPlayer.PowerDrained + bi.Power >= 0
? Color.White : Color.Red);
DrawRightAligned("{1}{0}".F(bi.Power, bi.Power > 0 ? "+" : ""), pos + new int2(-5, 20), Color.White);
p += new int2(5, 20);

View File

@@ -69,8 +69,8 @@ namespace OpenRA.Widgets.Delegates
var color = template.GetWidget<ButtonWidget>("COLOR");
color.OnMouseUp = CyclePalette;
var colorBlock = color.GetWidget<ColorBlockWidget>("COLORBLOCK");
colorBlock.GetColor = () => Player.PlayerColors(Game.world)[c.PaletteIndex % Player.PlayerColors(Game.world).Count].Color;
var colorBlock = color.GetWidget<ColorBlockWidget>("COLORBLOCK");
colorBlock.GetColor = () => Game.world.PlayerColors()[c.PaletteIndex % Game.world.PlayerColors().Count].Color;
var faction = template.GetWidget<ButtonWidget>("FACTION");
faction.OnMouseUp = CycleRace;
@@ -90,8 +90,8 @@ namespace OpenRA.Widgets.Delegates
}
else
{
var color = template.GetWidget<ColorBlockWidget>("COLOR");
color.GetColor = () => Player.PlayerColors(Game.world)[c.PaletteIndex % Player.PlayerColors(Game.world).Count].Color;
var color = template.GetWidget<ColorBlockWidget>("COLOR");
color.GetColor = () => Game.world.PlayerColors()[c.PaletteIndex % Game.world.PlayerColors().Count].Color;
var faction = template.GetWidget<LabelWidget>("FACTION");
faction.GetText = () => c.Country;
@@ -118,13 +118,13 @@ namespace OpenRA.Widgets.Delegates
bool SpawnPointAvailable(int index) { return (index == 0) || Game.LobbyInfo.Clients.All(c => c.SpawnPoint != index); }
bool CyclePalette(MouseInput mi)
{
var d = (mi.Button == MouseButton.Left) ? +1 : Player.PlayerColors(Game.world).Count() - 1;
var newIndex = ((int)Game.LocalClient.PaletteIndex + d) % Player.PlayerColors(Game.world).Count();
{
var d = (mi.Button == MouseButton.Left) ? +1 : Game.world.PlayerColors().Count() - 1;
var newIndex = ((int)Game.LocalClient.PaletteIndex + d) % Game.world.PlayerColors().Count();
while (!PaletteAvailable(newIndex) && newIndex != (int)Game.LocalClient.PaletteIndex)
newIndex = (newIndex + d) % Player.PlayerColors(Game.world).Count();
while (!PaletteAvailable(newIndex) && newIndex != (int)Game.LocalClient.PaletteIndex)
newIndex = (newIndex + d) % Game.world.PlayerColors().Count();
Game.IssueOrder(
Order.Chat("/pal " + newIndex));

View File

@@ -74,7 +74,7 @@ namespace OpenRA.Widgets
ChromeProvider.GetImage(Game.chrome.renderer, "spawnpoints", "unowned"), pos, "chrome");
else
{
var playerColors = Player.PlayerColors(world);
var playerColors = Game.world.PlayerColors();
Game.chrome.lineRenderer.FillRect(new RectangleF(
Game.viewport.Location.X + pos.X + 2,
Game.viewport.Location.Y + pos.Y + 2,

View File

@@ -43,6 +43,8 @@ namespace OpenRA.Widgets
public override void Draw(World world)
{
var playerResources = world.LocalPlayer.PlayerActor.traits.Get<PlayerResources>();
var digitCollection = "digits-" + world.LocalPlayer.Country.Race;
var chromeCollection = "chrome-" + world.LocalPlayer.Country.Race;
@@ -50,7 +52,7 @@ namespace OpenRA.Widgets
ChromeProvider.GetImage(Game.chrome.renderer, chromeCollection, "moneybin"),
new float2(Bounds.Left, 0), "chrome");
var moneyDigits = world.LocalPlayer.DisplayCash.ToString();
var moneyDigits = playerResources.DisplayCash.ToString();
var x = Bounds.Right - 65;
foreach (var d in moneyDigits.Reverse())

View File

@@ -163,8 +163,11 @@ namespace OpenRA.Widgets
void DrawPower(World world)
{
var resources = world.LocalPlayer.PlayerActor.traits.Get<PlayerResources>();
// Nothing to draw
if (world.LocalPlayer.PowerProvided == 0 && world.LocalPlayer.PowerDrained == 0)
if (resources.PowerProvided == 0
&& resources.PowerDrained == 0)
return;
var renderer = Game.chrome.renderer;
@@ -176,18 +179,18 @@ namespace OpenRA.Widgets
var barEnd = barStart + new float2(powerSize.Width, 0);
float powerScaleBy = 100;
var maxPower = Math.Max(world.LocalPlayer.PowerProvided, world.LocalPlayer.PowerDrained);
var maxPower = Math.Max(resources.PowerProvided, resources.PowerDrained);
while (maxPower >= powerScaleBy) powerScaleBy *= 2;
// Current power supply
var powerLevelTemp = barStart.X + (barEnd.X - barStart.X) * (world.LocalPlayer.PowerProvided / powerScaleBy);
var powerLevelTemp = barStart.X + (barEnd.X - barStart.X) * (resources.PowerProvided / powerScaleBy);
lastPowerProvidedPos = float2.Lerp(lastPowerProvidedPos.GetValueOrDefault(powerLevelTemp), powerLevelTemp, .3f);
float2 powerLevel = new float2(lastPowerProvidedPos.Value, barStart.Y);
var color = Color.LimeGreen;
if (world.LocalPlayer.GetPowerState() == PowerState.Low)
if (resources.GetPowerState() == PowerState.Low)
color = Color.Orange;
if (world.LocalPlayer.GetPowerState() == PowerState.Critical)
if (resources.GetPowerState() == PowerState.Critical)
color = Color.Red;
var colorDark = Graphics.Util.Lerp(0.25f, color, Color.Black);
@@ -208,7 +211,7 @@ namespace OpenRA.Widgets
// Power usage indicator
var indicator = ChromeProvider.GetImage(renderer, radarCollection, "power-indicator");
var powerDrainedTemp = barStart.X + (barEnd.X - barStart.X) * (world.LocalPlayer.PowerDrained / powerScaleBy);
var powerDrainedTemp = barStart.X + (barEnd.X - barStart.X) * (resources.PowerDrained / powerScaleBy);
lastPowerDrainedPos = float2.Lerp(lastPowerDrainedPos.GetValueOrDefault(powerDrainedTemp), powerDrainedTemp, .3f);
float2 powerDrainLevel = new float2(lastPowerDrainedPos.Value - indicator.size.X / 2, barStart.Y - 1);

View File

@@ -158,9 +158,6 @@ namespace OpenRA
var acts = frameEndActions;
frameEndActions = new List<Action<World>>();
foreach (var a in acts) a(this);
foreach (var player in players.Values)
player.Tick();
WorldRenderer.Tick();
}

View File

@@ -241,5 +241,12 @@ namespace OpenRA
{
return new float2(Gauss1D(r, samples), Gauss1D(r, samples));
}
public static List<PlayerColorPaletteInfo> PlayerColors(this World world)
{
return world.WorldActor.Info.Traits.WithInterface<PlayerColorPaletteInfo>()
.Where(p => p.Playable)
.ToList();
}
}
}

View File

@@ -38,7 +38,7 @@ namespace OpenRA.Mods.RA
collector.World.AddFrameEndTask(w =>
{
var amount = (info as GiveCashCrateActionInfo).Amount;
collector.Owner.GiveCash(amount);
collector.Owner.PlayerActor.traits.Get<PlayerResources>().GiveCash(amount);
});
base.Activate(collector);
}

View File

@@ -56,7 +56,7 @@ namespace OpenRA.Mods.RA
public void Deliver(Actor self, Actor proc)
{
proc.Owner.GiveOre(contents.Sum(kv => kv.Key.ValuePerUnit * kv.Value));
proc.Owner.PlayerActor.traits.Get<PlayerResources>().GiveOre(contents.Sum(kv => kv.Key.ValuePerUnit * kv.Value));
contents.Clear();
}

View File

@@ -37,7 +37,7 @@ namespace OpenRA.Mods.RA
public bool Disabled
{
get { return (self.Owner.GetPowerState() != PowerState.Normal); }
get { return (self.Owner.PlayerActor.traits.Get<PlayerResources>().GetPowerState() != PowerState.Normal); }
set {} // Cannot explicity set
}
}

View File

@@ -37,6 +37,7 @@ Player:
SelectTargetSound: select1.aud
UnitType: a10
ConquestVictoryConditions:
PlayerResources:
World:
GlobalDefaults:

View File

@@ -78,6 +78,7 @@ Player:
SelectTargetSound: slcttgt1.aud
FlareType: flare
ConquestVictoryConditions:
PlayerResources:
World: