Compare commits

...

27 Commits

Author SHA1 Message Date
Chris Forbes
64782fb254 use ToList rather than List<T>.ctor 2011-05-02 22:23:36 +12:00
Chris Forbes
bd0a953d66 clean up text render of SPW 2011-05-02 22:18:42 +12:00
Chris Forbes
aea8b8da99 remove some more insanity from SPW 2011-05-02 22:14:24 +12:00
Chris Forbes
ba7522bed6 remove a little of the most blatant idiocy from StrategicProgressWidget 2011-05-02 22:09:27 +12:00
Chris Forbes
00e9015671 fix minelayer going to faraway FIX 2011-05-02 21:38:16 +12:00
Chris Forbes
093f159d8e tuned gpsdot to be somewhat nicer 2011-05-02 21:15:09 +12:00
Chris Forbes
2912c921de add custom icon for harvester 2011-05-02 20:00:56 +12:00
Chris Forbes
dd4c5508fa gpsdot has sprites 2011-05-02 19:51:15 +12:00
Mike Bundy
25962d58c6 GpsDot removed when actor .Destroyed. GpsDot removed from BADR 2011-05-02 19:34:36 +12:00
Mike Bundy
bcbac667db Changes how GPS is watched. Changes GPS ability. 2011-05-02 19:31:40 +12:00
Chris Forbes
7923f7d83a add --shp and --png commands to util 2011-05-02 19:18:27 +12:00
Chris Forbes
9d7ac73410 pull BuildingInfluence trait lookup out of the inner loop of building placement 2011-05-02 10:47:25 +12:00
Curtis S
f7bd3951e3 Fixed creeps owning badrs in some map yamls 2011-05-01 15:22:25 +12:00
Chris Forbes
702f787899 fix entering helicopters 2011-05-01 15:20:35 +12:00
Chris Forbes
5675f02c84 fix koth maps; drop nuclear winter 2011-05-01 15:20:34 +12:00
Paul Chote
5c7f1aa237 Fix deb packaging 2011-05-01 12:21:24 +12:00
Chris Forbes
eb3f4ef21d remove random Application.DoEvents() from Game.cs 2011-04-30 14:31:02 +12:00
Chris Forbes
7155747337 remove IShader.Commit 2011-04-30 14:29:32 +12:00
Chris Forbes
279413f05b dont crash on disconnect from lobby 2011-04-30 11:14:25 +12:00
Chris Forbes
f84832a24a remove some duplication in parachute use 2011-04-29 19:52:36 +12:00
Chris Forbes
b26d2e07e9 formatting 2011-04-29 19:50:31 +12:00
Chris Forbes
2b0f553d9d remove a silly lookup in RenderSimpleInfo 2011-04-29 19:47:44 +12:00
Chris Forbes
0b0e857b13 write traitreport to a file on disconnect, not stdout 2011-04-29 19:38:54 +12:00
Chris Forbes
3a0dcf3ae4 trim some crap 2011-04-29 19:37:36 +12:00
Chris Forbes
9ebea704ad clean up CrateDrop 2011-04-29 17:48:29 +12:00
Chris Forbes
71ca0f028e remove some sillyness from LightPaletteRotator 2011-04-29 17:25:13 +12:00
Chris Forbes
2d82f68a89 remove a dumb traitinfo lookup every tick in Crate 2011-04-29 17:20:16 +12:00
42 changed files with 408 additions and 154 deletions

View File

@@ -64,7 +64,6 @@ namespace OpenRA.FileFormats.Graphics
{
void SetValue( string name, float x, float y );
void SetValue( string param, ITexture texture );
void Commit();
void Render( Action a );
}

View File

@@ -24,7 +24,8 @@ namespace OpenRA.FileFormats.Graphics
{
public static Bitmap Load(string filename)
{
return Load(File.OpenRead(filename));
using (var s = File.OpenRead(filename))
return Load(s);
}
public static Bitmap Load(Stream s)

View File

@@ -174,5 +174,11 @@ namespace OpenRA.FileFormats
{
return GetEnumerator();
}
public static ShpReader Load(string filename)
{
using (var s = File.OpenRead(filename))
return new ShpReader(s);
}
}
}

View File

@@ -14,7 +14,6 @@ using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Windows.Forms;
using OpenRA.FileFormats;
using OpenRA.GameRules;
using OpenRA.Graphics;
@@ -308,10 +307,8 @@ namespace OpenRA
internal static void Run()
{
while (!quit)
{
Tick( orderManager, viewport );
Application.DoEvents();
}
OnQuit();
}
@@ -326,7 +323,8 @@ namespace OpenRA
public static void Disconnect()
{
orderManager.world.traitDict.PrintReport();
if (orderManager.world != null)
orderManager.world.traitDict.PrintReport();
if (IsHost && server != null)
server.Shutdown();

View File

@@ -89,7 +89,6 @@ namespace OpenRA.Graphics
s.SetValue( "Scroll", (int) scroll.X, (int) scroll.Y );
s.SetValue( "r1", r1.X, r1.Y );
s.SetValue( "r2", r2.X, r2.Y );
s.Commit();
}
public void EndFrame( IInputHandler inputHandler )

View File

@@ -26,8 +26,9 @@ namespace OpenRA
public void PrintReport()
{
foreach( var t in traits.OrderByDescending(t => t.Value.Queries).TakeWhile(t => t.Value.Queries > 0) )
Console.WriteLine ("{0}: {1}", t.Key.Name, t.Value.Queries );
Log.AddChannel("traitreport", "traitreport.log");
foreach (var t in traits.OrderByDescending(t => t.Value.Queries).TakeWhile(t => t.Value.Queries > 0))
Log.Write("traitreport", "{0}: {1}", t.Key.Name, t.Value.Queries);
}
// construct this delegate once.

View File

@@ -27,8 +27,7 @@ namespace OpenRA.Traits
{
var anim = new Animation(RenderSimple.GetImage(building, Tileset), () => 0);
anim.PlayRepeating("idle");
var rb = building.Traits.Get<RenderSimpleInfo>();
yield return new Renderable(anim.Image, 0.5f * anim.Image.size * (1 - Scale), rb.Palette, 0, Scale);
yield return new Renderable(anim.Image, 0.5f * anim.Image.size * (1 - Scale), Palette, 0, Scale);
}
}

View File

@@ -28,6 +28,8 @@ namespace OpenRA.Traits
public void Tick(Actor self)
{
// todo: don't tick all the time.
if (previousLocation != self.Location)
{
previousLocation = self.Location;

View File

@@ -120,7 +120,7 @@ namespace OpenRA.Traits
// No longer our ally; remove unit vis
if (oldStance == Stance.Ally)
{
var toRemove = new List<Actor>(vis.Select(a => a.Key).Where(a => a.Owner == player));
var toRemove = vis.Select(a => a.Key).Where(a => a.Owner == player).ToList();
foreach (var a in toRemove)
RemoveActor(a);
}

View File

@@ -30,8 +30,10 @@ namespace OpenRA.Mods.RA.Activities
{
// rearm & repair at fix, then back out here to refill the minefield some more
var buildings = self.Info.Traits.Get<MinelayerInfo>().RearmBuildings;
var rearmTarget = self.World.Actors.FirstOrDefault(a => a.Owner != null && self.Owner.Stances[a.Owner] == Stance.Ally
&& buildings.Contains(a.Info.Name));
var rearmTarget = self.World.Actors.Where(a => a.Owner != null && self.Owner.Stances[a.Owner] == Stance.Ally
&& buildings.Contains(a.Info.Name))
.OrderBy( a => (a.Location - self.Location).LengthSquared )
.FirstOrDefault();
if (rearmTarget == null)
return new Wait(20);

View File

@@ -8,9 +8,11 @@
*/
#endregion
using System.Linq;
using OpenRA.Mods.RA.Move;
using OpenRA.Traits;
using OpenRA.Traits.Activities;
using OpenRA.FileFormats;
namespace OpenRA.Mods.RA.Activities
{
@@ -28,13 +30,20 @@ namespace OpenRA.Mods.RA.Activities
if( IsCanceled || target.Destroyed || !target.IsInWorld) return NextActivity;
var mobile = self.Trait<Mobile>();
var cells = target.Trait<IOccupySpace>().OccupiedCells().ToArray();
if (cells.Length == 0)
cells = new OpenRA.FileFormats.Pair<int2, SubCell>[] {
Pair.New(target.Location, SubCell.FullCell) };
var ps1 = new PathSearch( self.World, mobile.Info )
{
checkForBlocked = true,
heuristic = location => 0,
inReverse = true
};
foreach( var cell in target.Trait<IOccupySpace>().OccupiedCells() )
foreach( var cell in cells )
{
ps1.AddInitialCell( cell.First );
if( ( mobile.toCell - cell.First ).LengthSquared <= 2 )

View File

@@ -26,15 +26,15 @@ namespace OpenRA.Mods.RA
public void Killed(Actor self, AttackInfo e)
{
var info = self.Info.Traits.Get<EjectOnDeathInfo>();
var pilot = self.World.CreateActor(false, info.PilotActor.ToLowerInvariant(), new TypeDictionary { new OwnerInit(self.Owner) });
var pilot = self.World.CreateActor(false, info.PilotActor.ToLowerInvariant(),
new TypeDictionary { new OwnerInit(self.Owner) });
var r = self.World.SharedRandom.Next(1, 100);
var aircraft = self.Trait<IMove>();
if (IsSuitableCell(pilot, self.Location) && r > 100 - info.SuccessRate && aircraft.Altitude > 10)
{
var rs = pilot.Trait<RenderSimple>();
self.World.AddFrameEndTask(w => w.Add(
new Parachute(pilot.Owner, rs.anim.Name,
new Parachute(pilot.Owner,
Util.CenterOfCell(Util.CellContaining(self.CenterLocation)),
aircraft.Altitude, pilot)));

View File

@@ -45,11 +45,13 @@ namespace OpenRA.Mods.RA.Buildings
var nearnessCandidates = new List<int2>();
var bi = world.WorldActor.Trait<BuildingInfluence>();
for( int y = scanStart.Y ; y < scanEnd.Y ; y++ )
{
for( int x = scanStart.X ; x < scanEnd.X ; x++ )
{
var at = world.WorldActor.Trait<BuildingInfluence>().GetBuildingAt( new int2( x, y ) );
var at = bi.GetBuildingAt( new int2( x, y ) );
if( at != null && at.Owner.Stances[ p ] == Stance.Ally && at.Info.Traits.Get<BuildingInfo>().BaseNormal )
nearnessCandidates.Add( new int2( x, y ) );
}

View File

@@ -76,7 +76,7 @@ namespace OpenRA.Mods.RA
public void Tick(Actor self)
{
if( ++ticks >= self.Info.Traits.Get<CrateInfo>().Lifetime * 25 )
if( ++ticks >= Info.Lifetime * 25 )
self.Destroy();
}

View File

@@ -18,7 +18,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA
{
public class CrateDropInfo : TraitInfo<CrateDrop>
public class CrateDropInfo : ITraitInfo
{
public readonly int Minimum = 1; // Minumum number of crates
public readonly int Maximum = 255; // Maximum number of crates
@@ -26,67 +26,80 @@ namespace OpenRA.Mods.RA
public readonly string[] ValidWater = {"Water"};
public readonly int SpawnInterval = 180; // Average time (seconds) between crate spawn
public readonly float WaterChance = .2f; // Chance of generating a water crate instead of a land crate
public object Create (ActorInitializer init) { return new CrateDrop(this); }
}
public class CrateDrop : ITick
{
List<Actor> crates = new List<Actor>();
int ticks = 0;
CrateDropInfo Info;
public CrateDrop(CrateDropInfo info) { Info = info; }
public void Tick(Actor self)
{
if (--ticks <= 0)
{
var info = self.Info.Traits.Get<CrateDropInfo>();
ticks = info.SpawnInterval * 25; // todo: randomize
ticks = Info.SpawnInterval * 25; // todo: randomize
crates.RemoveAll(x => !x.IsInWorld); // BUG: this removes crates that are cargo of a BADR!
var toSpawn = Math.Max(0, info.Minimum - crates.Count)
+ (crates.Count < info.Maximum ? 1 : 0);
var toSpawn = Math.Max(0, Info.Minimum - crates.Count)
+ (crates.Count < Info.Maximum ? 1 : 0);
for (var n = 0; n < toSpawn; n++)
SpawnCrate(self, info);
SpawnCrate(self);
}
}
void SpawnCrate(Actor self, CrateDropInfo info)
int2? ChooseDropCell(Actor self, bool inWater, int maxTries)
{
var threshold = 100;
var inWater = self.World.SharedRandom.NextDouble() < info.WaterChance;
for (var n = 0; n < threshold; n++)
for( var n = 0; n < maxTries; n++ )
{
var p = self.World.ChooseRandomCell(self.World.SharedRandom);
// Is this valid terrain?
var terrainType = self.World.GetTerrainType(p);
if (!(inWater ? info.ValidWater : info.ValidGround).Contains(terrainType)) continue;
if (!(inWater ? Info.ValidWater : Info.ValidGround).Contains(terrainType)) continue;
// Don't drop on any actors
if (self.World.WorldActor.Trait<BuildingInfluence>().GetBuildingAt(p) != null) continue;
if (self.World.WorldActor.Trait<UnitInfluence>().GetUnitsAt(p).Any()) continue;
self.World.AddFrameEndTask(w =>
{
var crate = w.CreateActor(false, "crate", new TypeDictionary { new OwnerInit(w.WorldActor.Owner) });
crates.Add(crate);
var startPos = w.ChooseRandomEdgeCell();
var plane = w.CreateActor("badr", new TypeDictionary
{
new LocationInit( startPos ),
new OwnerInit( w.WorldActor.Owner),
new FacingInit( Util.GetFacing(p - startPos, 0) ),
new AltitudeInit( Rules.Info["badr"].Traits.Get<AircraftInfo>().CruiseAltitude ),
});
plane.CancelActivity();
plane.QueueActivity(new FlyAttack(Target.FromCell(p)));
plane.Trait<ParaDrop>().SetLZ(p);
plane.Trait<Cargo>().Load(plane, crate);
});
return;
return p;
}
return null;
}
void SpawnCrate(Actor self)
{
var inWater = self.World.SharedRandom.NextDouble() < Info.WaterChance;
var pp = ChooseDropCell(self, inWater, 100);
if (pp == null) return;
var p = pp.Value; //
self.World.AddFrameEndTask(w =>
{
var crate = w.CreateActor(false, "crate", new TypeDictionary { new OwnerInit(w.WorldActor.Owner) });
crates.Add(crate);
var startPos = w.ChooseRandomEdgeCell();
var plane = w.CreateActor("badr", new TypeDictionary
{
new LocationInit( startPos ),
new OwnerInit( w.WorldActor.Owner),
new FacingInit( Util.GetFacing(p - startPos, 0) ),
new AltitudeInit( Rules.Info["badr"].Traits.Get<AircraftInfo>().CruiseAltitude ),
});
plane.CancelActivity();
plane.QueueActivity(new FlyAttack(Target.FromCell(p)));
plane.Trait<ParaDrop>().SetLZ(p);
plane.Trait<Cargo>().Load(plane, crate);
});
}
}
}

View File

@@ -0,0 +1,79 @@
#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.Collections.Generic;
using System.Drawing;
using OpenRA.Effects;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Mods.RA.Effects
{
class GpsDotInfo : ITraitInfo
{
public readonly string String = "Infantry";
public object Create(ActorInitializer init)
{
return new GpsDot(init, String);
}
}
class GpsDot : IEffect
{
int2 loc;
Color color;
Actor self;
GpsWatcher watcher;
bool show = false;
Animation anim;
public GpsDot(ActorInitializer init, string s)
{
anim = new Animation("gpsdot");
anim.PlayRepeating(s);
self = init.self;
loc = self.CenterLocation;
color = self.Owner.ColorRamp.GetColor(0);
self.World.AddFrameEndTask(w => w.Add(this));
if(self.World.LocalPlayer != null)
watcher = self.World.LocalPlayer.PlayerActor.Trait<GpsWatcher>();
}
public void Tick(World world)
{
show = false;
if (self.Destroyed)
world.AddFrameEndTask(w => w.Remove(this));
if (world.LocalPlayer == null)
return;
if (
self.IsInWorld
&& (watcher.Granted || watcher.GrantedAllies)
&& !self.Trait<HiddenUnderFog>().IsVisible(self)
&& (!self.HasTrait<Cloak>() || !self.Trait<Cloak>().Cloaked)
)
{
show = true;
loc = self.CenterLocation;
}
}
public IEnumerable<Renderable> Render()
{
if (show && !self.Destroyed)
yield return Traits.Util.Centered(self, anim.Image, self.CenterLocation.ToFloat2())
.WithScale(1.5f);
}
}
}

View File

@@ -28,13 +28,16 @@ namespace OpenRA.Mods.RA.Effects
float altitude;
const float fallRate = .3f;
public Parachute(Player owner, string image, float2 location, int altitude, Actor cargo)
public Parachute(Player owner, float2 location, int altitude, Actor cargo)
{
this.location = location;
this.altitude = altitude;
this.cargo = cargo;
this.owner = owner;
var rs = cargo.Trait<RenderSimple>();
var image = rs.anim.Name;
anim = new Animation(image);
if (anim.HasSequence("idle"))
anim.PlayFetchIndex("idle", () => 0);

View File

@@ -9,6 +9,7 @@
#endregion
using System.Collections.Generic;
using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Traits;
@@ -23,12 +24,13 @@ namespace OpenRA.Mods.RA
t += .5f;
}
static readonly string[] ExcludePalettes = { "cursor", "chrome", "colorpicker" };
public void AdjustPalette(Dictionary<string,Palette> palettes)
{
var excludePalettes = new List<string>(){"cursor", "chrome", "colorpicker"};
foreach (var pal in palettes)
{
if (excludePalettes.Contains(pal.Key))
if (ExcludePalettes.Contains(pal.Key))
continue;
var rotate = (int)t % 18;

View File

@@ -12,13 +12,10 @@ using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using OpenRA.Effects;
using OpenRA.Mods.RA.Activities;
using OpenRA.Traits.Activities;
using OpenRA.FileFormats;
using System.Diagnostics;
using OpenRA.Orders;
using OpenRA.Mods.RA.Activities;
using OpenRA.Traits;
using OpenRA.Traits.Activities;
namespace OpenRA.Mods.RA.Move
{

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -63,6 +63,7 @@
<Compile Include="Air\FlyCircle.cs" />
<Compile Include="Air\EjectOnDeath.cs" />
<Compile Include="Effects\CashTick.cs" />
<Compile Include="Effects\GpsDot.cs" />
<Compile Include="GivesBounty.cs" />
<Compile Include="Lint\LintBuildablePrerequisites.cs" />
<Compile Include="ProductionBar.cs" />

View File

@@ -52,11 +52,10 @@ namespace OpenRA.Mods.RA
droppedAt.Add(self.Location);
var a = cargo.Unload(self);
var rs = a.Trait<RenderSimple>();
var aircraft = self.Trait<IMove>();
self.World.AddFrameEndTask(w => w.Add(
new Parachute(self.Owner, rs.anim.Name,
new Parachute(self.Owner,
Util.CenterOfCell(Util.CellContaining(self.CenterLocation)),
aircraft.Altitude, a)));

View File

@@ -9,12 +9,76 @@
#endregion
using System.Linq;
using System.Drawing;
using System.Collections.Generic;
using OpenRA.Effects;
using OpenRA.Mods.RA.Effects;
using OpenRA.Traits;
namespace OpenRA.Mods.RA
{
class GpsWatcherInfo : ITraitInfo
{
public object Create(ActorInitializer init)
{
return new GpsWatcher(init);
}
}
class GpsWatcher : ISync
{
Actor self;
bool Launched = false;
List<Actor> actors = new List<Actor> { };
[Sync]
public bool GrantedAllies = false;
[Sync]
public bool Granted = false;
public GpsWatcher(ActorInitializer init)
{
self = init.self;
}
public void GpsRem(Actor self)
{
actors.Remove(self);
RefreshGps(self);
}
public void GpsAdd(Actor self)
{
actors.Add(self);
RefreshGps(self);
}
public void Launch(Actor self, SupportPowerInfo info)
{
self.World.Add(new DelayedAction((info as GpsPowerInfo).RevealDelay * 25,
() =>
{
Launched = true;
RefreshGps(self);
}));
}
public void RefreshGps(Actor self)
{
Granted = (actors.Count > 0 && Launched);
GrantedAllies = self.World.ActorsWithTrait<GpsWatcher>().Any(p =>
p.Actor.Owner.Stances[self.Owner] == Stance.Ally && p.Trait.Granted);
if (self.World.LocalPlayer == null)
return;
if ((Granted || GrantedAllies) && self.World.LocalPlayer == self.Owner)
{
self.World.WorldActor.Trait<Shroud>().ExploreAll(self.World);
}
}
}
class GpsPowerInfo : SupportPowerInfo
{
public readonly int RevealDelay = 0;
@@ -22,15 +86,14 @@ namespace OpenRA.Mods.RA
public override object Create(ActorInitializer init) { return new GpsPower(init.self, this); }
}
class GpsPower : SupportPower, INotifyKilled, ISync, INotifyStanceChanged, INotifySold
class GpsPower : SupportPower, INotifyKilled, ISync, INotifyStanceChanged, INotifySold, INotifyCapture
{
[Sync]
public bool Granted;
GpsWatcher owner;
public GpsPower(Actor self, GpsPowerInfo info) : base(self, info)
{
Granted = self.World.ActorsWithTrait<GpsPower>()
.Any(p => p.Actor.Owner == self.Owner && p.Trait.Granted);
owner = self.Owner.PlayerActor.Trait<GpsWatcher>();
owner.GpsAdd(self);
}
public override void Charged(Actor self, string key)
@@ -46,43 +109,31 @@ namespace OpenRA.Mods.RA
w.Add(new SatelliteLaunch(self));
/* there is only one shroud, but it is misleadingly available through Player.Shroud */
w.Add(new DelayedAction((Info as GpsPowerInfo).RevealDelay * 25,
() => {
var ateks = self.World.ActorsWithTrait<GpsPower>();
foreach (TraitPair<GpsPower> i in ateks)
{
if (i.Actor.Owner == self.Owner)
{
i.Trait.Granted = true;
}
}
RefreshGps(self);
}));
owner.Launch(self, Info);
});
}
public void Selling(Actor self) { DisableGps(); }
public void Sold(Actor self) { }
public void Killed(Actor self, AttackInfo e) { DisableGps(); }
public void Killed(Actor self, AttackInfo e) { RemoveGps(self); }
void DisableGps()
{
Granted = false;
RefreshGps(self);
}
public void Selling(Actor self) {}
public void Sold(Actor self) { RemoveGps(self); }
void RefreshGps(Actor self)
void RemoveGps(Actor self)
{
if (self.World.LocalPlayer != null)
self.World.LocalShroud.Disabled = self.World.ActorsWithTrait<GpsPower>()
.Any(p => p.Actor.Owner.Stances[self.World.LocalPlayer] == Stance.Ally &&
p.Trait.Granted);
// Extra function just in case something needs to be added later
owner.GpsRem(self);
}
public void StanceChanged(Actor self, Player a, Player b, Stance oldStance, Stance newStance)
{
RefreshGps(self);
owner.RefreshGps(self);
}
public void OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner)
{
RemoveGps(self);
owner = captor.Owner.PlayerActor.Trait<GpsWatcher>();
owner.GpsAdd(self);
}
}
}

View File

@@ -8,14 +8,12 @@
*/
#endregion
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using OpenRA.Graphics;
using OpenRA.Traits;
using OpenRA.Widgets;
using System;
namespace OpenRA.Mods.RA.Widgets
{
@@ -23,79 +21,72 @@ namespace OpenRA.Mods.RA.Widgets
{
bool Initialised = false;
readonly World world;
readonly WorldRenderer worldRenderer;
[ObjectCreator.UseCtor]
public StrategicProgressWidget([ObjectCreator.Param] World world, [ObjectCreator.Param] WorldRenderer worldRenderer)
public StrategicProgressWidget([ObjectCreator.Param] World world)
{
IsVisible = () => true;
this.world = world;
this.worldRenderer = worldRenderer;
}
bool AreMutualAllies(Player a, Player b)
{
return a.Stances[b] == Stance.Ally &&
b.Stances[a] == Stance.Ally;
}
public override void DrawInner()
{
if (!Initialised)
Init();
if (!IsVisible()) return;
int2 offset = int2.Zero;
var svc = world.players.Select(p => p.Value.PlayerActor.TraitOrDefault<StrategicVictoryConditions>()).FirstOrDefault();
var totalWidth = (svc.Total + svc.TotalCritical)*32;
var totalWidth = (svc.Total + svc.TotalCritical) * 32;
int curX = -(totalWidth / 2);
foreach (var a in world.Actors.Where(a => !a.Destroyed && a.HasTrait<StrategicPoint>() && !a.TraitOrDefault<StrategicPoint>().Critical))
foreach (var a in world.ActorsWithTrait<StrategicPoint>().Where(a => a.Trait.Critical))
{
WidgetUtils.DrawRGBA(ChromeProvider.GetImage("strategic", "unowned"), offset + new float2(RenderBounds.Left + curX, RenderBounds.Top));
if (a.Owner == worldRenderer.world.LocalPlayer || (a.Owner.Stances[world.LocalPlayer] == Stance.Ally && world.LocalPlayer.Stances[a.Owner] == Stance.Ally))
if (a.Actor.Owner == world.LocalPlayer || AreMutualAllies(a.Actor.Owner, world.LocalPlayer))
WidgetUtils.DrawRGBA(ChromeProvider.GetImage("strategic", "player_owned"), offset + new float2(RenderBounds.Left + curX, RenderBounds.Top));
else if (!a.Owner.NonCombatant)
else if (!a.Actor.Owner.NonCombatant)
WidgetUtils.DrawRGBA(ChromeProvider.GetImage("strategic", "enemy_owned"), offset + new float2(RenderBounds.Left + curX, RenderBounds.Top));
curX += 32;
}
foreach (var a in world.Actors.Where(a => !a.Destroyed && a.HasTrait<StrategicPoint>() && a.TraitOrDefault<StrategicPoint>().Critical))
foreach (var a in world.ActorsWithTrait<StrategicPoint>().Where(a => !a.Trait.Critical))
{
WidgetUtils.DrawRGBA(ChromeProvider.GetImage("strategic", "critical_unowned"), offset + new float2(RenderBounds.Left + curX, RenderBounds.Top));
if (a.Owner == world.LocalPlayer || (a.Owner.Stances[world.LocalPlayer] == Stance.Ally && world.LocalPlayer.Stances[a.Owner] == Stance.Ally))
if (a.Actor.Owner == world.LocalPlayer || AreMutualAllies(a.Actor.Owner, world.LocalPlayer))
WidgetUtils.DrawRGBA(ChromeProvider.GetImage("strategic", "player_owned"), offset + new float2(RenderBounds.Left + curX, RenderBounds.Top));
else if (!a.Owner.NonCombatant)
else if (!a.Actor.Owner.NonCombatant)
WidgetUtils.DrawRGBA(ChromeProvider.GetImage("strategic", "enemy_owned"), offset + new float2(RenderBounds.Left + curX, RenderBounds.Top));
curX += 32;
}
offset += new int2(0, 32);
if (world.LocalPlayer == null) return;
var pendingWinner = FindFirstWinningPlayer(world);
if (pendingWinner == null) return;
svc = pendingWinner.PlayerActor.TraitOrDefault<StrategicVictoryConditions>();
var winnerSvc = pendingWinner.PlayerActor.Trait<StrategicVictoryConditions>();
if (world.LocalPlayer != null)
{
var tc = "";
var isVictory = pendingWinner == world.LocalPlayer || !AreMutualAllies(pendingWinner, world.LocalPlayer);
var tc = "Strategic {0} in {1}".F(
isVictory ? "victory" : "defeat",
WidgetUtils.FormatTime(Math.Max(winnerSvc.CriticalTicksLeft, winnerSvc.TicksLeft)));
if (pendingWinner != world.LocalPlayer && (pendingWinner.Stances[world.LocalPlayer] != Stance.Ally || world.LocalPlayer.Stances[pendingWinner] != Stance.Ally))
{
// losing
tc = "Strategic defeat in " +
((svc.CriticalTicksLeft > svc.TicksLeft) ? WidgetUtils.FormatTime(svc.CriticalTicksLeft) : WidgetUtils.FormatTime(svc.TicksLeft));
}else
{
// winning
tc = "Strategic victory in " +
((svc.CriticalTicksLeft > svc.TicksLeft) ? WidgetUtils.FormatTime(svc.CriticalTicksLeft) : WidgetUtils.FormatTime(svc.TicksLeft));
}
var size = Game.Renderer.BoldFont.Measure(tc);
Game.Renderer.BoldFont.DrawText(tc, offset + new float2(RenderBounds.Left - size.X / 2 + 1, RenderBounds.Top + 1), Color.Black);
Game.Renderer.BoldFont.DrawText(tc, offset + new float2(RenderBounds.Left - size.X / 2, RenderBounds.Top), Color.WhiteSmoke);
offset += new int2(0, size.Y + 1);
}
var size = Game.Renderer.BoldFont.Measure(tc);
Game.Renderer.BoldFont.DrawText(tc, offset + new float2(RenderBounds.Left - size.X / 2 + 1, RenderBounds.Top + 1), Color.Black);
Game.Renderer.BoldFont.DrawText(tc, offset + new float2(RenderBounds.Left - size.X / 2, RenderBounds.Top), Color.WhiteSmoke);
offset += new int2(0, size.Y + 1);
}
public Player FindFirstWinningPlayer(World world)
@@ -106,7 +97,7 @@ namespace OpenRA.Mods.RA.Widgets
foreach (var p in world.players.Select(p => p.Value).Where(p => !p.NonCombatant))
{
var svc = p.PlayerActor.TraitOrDefault<StrategicVictoryConditions>();
var svc = p.PlayerActor.Trait<StrategicVictoryConditions>();
if (svc.HoldingCritical && svc.CriticalTicksLeft > 0 && svc.CriticalTicksLeft < shortest)
{
@@ -124,9 +115,12 @@ namespace OpenRA.Mods.RA.Widgets
return shortestPlayer;
}
private void Init()
void Init()
{
IsVisible = () => (world.Actors.Where(a => a.HasTrait<StrategicVictoryConditions>()).Any() && world.Actors.Where(a => a.HasTrait<StrategicPoint>()).Any());
var visible = world.ActorsWithTrait<StrategicVictoryConditions>().Any() &&
world.ActorsWithTrait<StrategicPoint>().Any();
IsVisible = () => visible;
Initialised = true;
}
}

View File

@@ -12,7 +12,6 @@ using System;
using System.IO;
using OpenRA.FileFormats;
using OpenRA.FileFormats.Graphics;
using Tao.Cg;
namespace OpenRA.Renderer.Cg
{
@@ -81,7 +80,5 @@ namespace OpenRA.Renderer.Cg
if (param != IntPtr.Zero)
Tao.Cg.CgGl.cgGLSetParameter2f(param, x, y);
}
public void Commit() { }
}
}

View File

@@ -9,12 +9,12 @@
#endregion
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using OpenRA.FileFormats;
using OpenRA.FileFormats.Graphics;
using Tao.OpenGl;
using System.Text;
using System.Collections.Generic;
namespace OpenRA.Renderer.Glsl
{
@@ -141,7 +141,5 @@ namespace OpenRA.Renderer.Glsl
Gl.glUniform2fARB(param,x,y);
GraphicsDevice.CheckGlError();
}
public void Commit() { }
}
}

View File

@@ -15,6 +15,11 @@ using System.Windows.Forms;
using ICSharpCode.SharpZipLib;
using ICSharpCode.SharpZipLib.Zip;
using OpenRA.GameRules;
using OpenRA.FileFormats.Graphics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using OpenRA.FileFormats;
namespace OpenRA.Utility
{
@@ -145,5 +150,67 @@ namespace OpenRA.Utility
public static void AuthenticateAndExtractZip(string[] args) { AuthenticateAndExecute("--extract-zip-inner", args); }
public static void AuthenticateAndInstallRAPackages(string[] args) { AuthenticateAndExecute( "--install-ra-packages-inner", args ); }
public static void AuthenticateAndInstallCncPackages(string[] args) { AuthenticateAndExecute( "--install-cnc-packages-inner", args ); }
public static void ConvertPngToShp(string[] args)
{
var src = args[1];
var dest = Path.ChangeExtension(src, ".shp");
var width = int.Parse(args[2]);
var srcImage = PngLoader.Load(src);
if (srcImage.Width % width != 0)
throw new InvalidOperationException("Bogus width; not a whole number of frames");
using (var destStream = File.Create(dest))
ShpWriter.Write(destStream, width, srcImage.Height,
srcImage.ToFrames(width));
}
static IEnumerable<byte[]> ToFrames(this Bitmap bitmap, int width)
{
for (var x = 0; x < bitmap.Width; x += width)
{
var data = bitmap.LockBits(new Rectangle(x, 0, width, bitmap.Height), ImageLockMode.ReadOnly,
PixelFormat.Format8bppIndexed);
var bytes = new byte[width * bitmap.Height];
for (var i = 0; i < bitmap.Height; i++)
Marshal.Copy(new IntPtr(data.Scan0.ToInt64() + i * data.Stride),
bytes, i * width, width);
bitmap.UnlockBits(data);
yield return bytes;
}
}
public static void ConvertShpToPng(string[] args)
{
var src = args[1];
var dest = Path.ChangeExtension(src, ".png");
var srcImage = ShpReader.Load(src);
using (var bitmap = new Bitmap(srcImage.ImageCount * srcImage.Width, srcImage.Height, PixelFormat.Format8bppIndexed))
{
var x = 0;
foreach (var frame in srcImage)
{
var data = bitmap.LockBits(new Rectangle(x, 0, srcImage.Width, srcImage.Height), ImageLockMode.WriteOnly,
PixelFormat.Format8bppIndexed);
for (var i = 0; i < bitmap.Height; i++)
Marshal.Copy(frame.Image, i * srcImage.Width,
new IntPtr(data.Scan0.ToInt64() + i * data.Stride), srcImage.Width);
Marshal.Copy(frame.Image, 0, data.Scan0, frame.Image.Length);
x += srcImage.Width;
}
bitmap.Save(dest);
}
}
}
}

View File

@@ -36,6 +36,7 @@
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>

View File

@@ -44,6 +44,8 @@ namespace OpenRA.Utility
{ "--install-ra-packages", Command.AuthenticateAndInstallRAPackages },
{ "--install-cnc-packages", Command.AuthenticateAndInstallCncPackages },
{ "--extract-zip", Command.AuthenticateAndExtractZip },
{ "--shp", Command.ConvertPngToShp },
{ "--png", Command.ConvertShpToPng },
};
if (args.Length == 0) { PrintUsage(); return; }
@@ -99,6 +101,8 @@ namespace OpenRA.Utility
Console.WriteLine(" --install-ra-packages PATH Install required packages for RA from CD to PATH");
Console.WriteLine(" --install-cnc-packages PATH Install required packages for C&C from CD to PATH");
Console.WriteLine(" --settings-value SUPPORTDIR KEY Get value of KEY in SUPPORTDIR/settings.yaml");
Console.WriteLine(" --shp PNGFILE FRAMEWIDTH Convert a PNG containing one or more frames to a SHP");
Console.WriteLine(" --png SHPFILE Convert a SHP to a PNG containing all of its frames");
}
static T WithDefault<T>(T def, Func<T> f)

BIN
mods/ra/bits/gpsdot.shp Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -35,6 +35,7 @@ BADR:
Offset: -11, -11
Interval: 2
-EjectOnDeath:
-GpsDot:
BADR.bomber:
CarpetBomb:
@@ -74,6 +75,7 @@ BADR.bomber:
Offset: -11, -11
Interval: 2
-EjectOnDeath:
-GpsDot:
MIG:
Inherits: ^Plane
@@ -177,7 +179,7 @@ YAK:
TRAN:
Inherits: ^Plane
Inherits: ^Helicopter
Buildable:
Queue: Plane
BuildPaletteOrder: 110
@@ -216,7 +218,7 @@ TRAN:
Explosion: UnitExplode
HELI:
Inherits: ^Plane
Inherits: ^Helicopter
Buildable:
Queue: Plane
BuildPaletteOrder: 90
@@ -260,7 +262,7 @@ HELI:
Offset: 0,-10
HIND:
Inherits: ^Plane
Inherits: ^Helicopter
Buildable:
Queue: Plane
BuildPaletteOrder: 90

View File

@@ -28,6 +28,8 @@
ProximityCaptor:
Types:Vehicle
GivesBounty:
GpsDot:
String:Vehicle
^Tank:
AppearsOnRadar:
@@ -59,6 +61,8 @@
ProximityCaptor:
Types:Tank
GivesBounty:
GpsDot:
String:Vehicle
^Infantry:
AppearsOnRadar:
@@ -96,6 +100,8 @@
ProximityCaptor:
Types:Infantry
GivesBounty:
GpsDot:
String:Infantry
^Ship:
AppearsOnRadar:
@@ -119,6 +125,8 @@
ProximityCaptor:
Types:Ship
GivesBounty:
GpsDot:
String:Ship
^Plane:
AppearsOnRadar:
@@ -144,6 +152,12 @@
PilotActor: E1
SuccessRate: 50
GivesBounty:
GpsDot:
String:Plane
^Helicopter:
GpsDot:
String:Helicopter
^Building:
AppearsOnRadar:

View File

@@ -93,6 +93,7 @@ Player:
DebugResourceCash:
DebugResourceOre:
DebugResourceOreCapacity:
GpsWatcher:
World:
OpenWidgetAtGameStart:

View File

@@ -226,6 +226,8 @@ HARV:
Range: 4
RenderUnit:
-AttackMove:
GpsDot:
String:Harvester
MCV:
Inherits: ^Vehicle

View File

@@ -1917,3 +1917,18 @@ boxes09:
idle:
Start: 0
Length: *
gpsdot:
Infantry:
Start: 0
Vehicle:
Start: 1
Ship:
Start: 2
Helicopter:
Start: 3
Plane:
Start: 4
Harvester:
Start: 5

View File

@@ -3,7 +3,7 @@ Version: {VERSION}
Architecture: all
Maintainer: Paul Chote <sleipnir@sleipnirstuff.com>
Installed-Size: {SIZE}
Depends: libopenal1, mono-runtime (>= 2.6.7), libmono-winforms2.0-cil, libfreetype6, libsdl1.2debian, libgl1-mesa-glx, libgl1-mesa-dri, libmono-i18n2.0-cil, ttf-freefont
Depends: libopenal1, mono-runtime (>= 2.6.7), libmono-winforms2.0-cil, libfreetype6, libsdl1.2debian, libgl1-mesa-glx, libgl1-mesa-dri, libmono-i18n2.0-cil
Section: games
Priority: extra
Homepage: http://www.open-ra.org/

View File

@@ -19,10 +19,6 @@ mkdir root
cp -R DEBIAN root
cp -R $rootdir/usr root
# Remove duplicate fonts provided by ttf-freefont
rm root/usr/share/openra/FreeSans.ttf
rm root/usr/share/openra/FreeSansBold.ttf
# Binaries go in /usr/games
mv root/usr/bin/ root/usr/games/
sed "s/\/usr\/bin\//\/usr\/games\//" root/usr/share/applications/openra.desktop > temp