Renormalize line endings and fix copyright headers again.
This commit is contained in:
@@ -66,11 +66,11 @@ namespace OpenRA.Mods.RA.Activities
|
||||
|
||||
self.World.AddFrameEndTask(w =>
|
||||
{
|
||||
if (actor.Destroyed) return;
|
||||
if (actor.Destroyed) return;
|
||||
|
||||
var mobile = actor.Trait<Mobile>();
|
||||
mobile.SetPosition(actor, self.Location);
|
||||
|
||||
mobile.SetPosition(actor, self.Location);
|
||||
|
||||
w.Add(actor);
|
||||
actor.CancelActivity();
|
||||
actor.QueueActivity(mobile.MoveTo(exitTile.Value, 0));
|
||||
|
||||
@@ -1,43 +1,43 @@
|
||||
#region Copyright & License Information
|
||||
#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 OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
public class FlyCircle : CancelableActivity
|
||||
{
|
||||
public override IActivity Tick(Actor self)
|
||||
{
|
||||
var cruiseAltitude = self.Info.Traits.Get<PlaneInfo>().CruiseAltitude;
|
||||
|
||||
if (IsCanceled) return NextActivity;
|
||||
|
||||
var aircraft = self.Trait<Aircraft>();
|
||||
|
||||
var desiredFacing = aircraft.Facing + 64; // we can't possibly turn this fast.
|
||||
if (aircraft.Altitude == cruiseAltitude)
|
||||
aircraft.Facing = Util.TickFacing(aircraft.Facing, desiredFacing, aircraft.ROT);
|
||||
|
||||
if (aircraft.Altitude < cruiseAltitude)
|
||||
++aircraft.Altitude;
|
||||
|
||||
FlyUtil.Fly(self, cruiseAltitude);
|
||||
return this;
|
||||
}
|
||||
|
||||
public override IEnumerable<float2> GetCurrentPath()
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
|
||||
namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
public class FlyCircle : CancelableActivity
|
||||
{
|
||||
public override IActivity Tick(Actor self)
|
||||
{
|
||||
var cruiseAltitude = self.Info.Traits.Get<PlaneInfo>().CruiseAltitude;
|
||||
|
||||
if (IsCanceled) return NextActivity;
|
||||
|
||||
var aircraft = self.Trait<Aircraft>();
|
||||
|
||||
var desiredFacing = aircraft.Facing + 64; // we can't possibly turn this fast.
|
||||
if (aircraft.Altitude == cruiseAltitude)
|
||||
aircraft.Facing = Util.TickFacing(aircraft.Facing, desiredFacing, aircraft.ROT);
|
||||
|
||||
if (aircraft.Altitude < cruiseAltitude)
|
||||
++aircraft.Altitude;
|
||||
|
||||
FlyUtil.Fly(self, cruiseAltitude);
|
||||
return this;
|
||||
}
|
||||
|
||||
public override IEnumerable<float2> GetCurrentPath()
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Mods.RA.Buildings;
|
||||
using OpenRA.Mods.RA.Orders;
|
||||
@@ -40,13 +40,13 @@ namespace OpenRA.Mods.RA.Air
|
||||
{
|
||||
/* not spawning in the air, so try to assoc. with our afld. this is a hack. */
|
||||
var afld = self.World.FindUnits(self.CenterLocation, self.CenterLocation)
|
||||
.FirstOrDefault( a => a.HasTrait<Reservable>() );
|
||||
|
||||
if (afld != null)
|
||||
{
|
||||
var res = afld.Trait<Reservable>();
|
||||
if (res != null)
|
||||
reservation = res.Reserve(afld, self, this);
|
||||
.FirstOrDefault( a => a.HasTrait<Reservable>() );
|
||||
|
||||
if (afld != null)
|
||||
{
|
||||
var res = afld.Trait<Reservable>();
|
||||
if (res != null)
|
||||
reservation = res.Reserve(afld, self, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -88,7 +88,7 @@ namespace OpenRA.Mods.RA.Air
|
||||
var target = self.World.ClampToWorld(order.TargetLocation);
|
||||
self.SetTargetLine(Target.FromCell(target), Color.Green);
|
||||
self.CancelActivity();
|
||||
self.QueueActivity(Fly.ToCell(target));
|
||||
self.QueueActivity(Fly.ToCell(target));
|
||||
self.QueueActivity(new FlyCircle());
|
||||
}
|
||||
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Mods.RA.Buildings;
|
||||
#endregion
|
||||
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Mods.RA.Buildings;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Air
|
||||
@@ -33,29 +33,29 @@ namespace OpenRA.Mods.RA.Air
|
||||
self.QueueActivity(new Rearm());
|
||||
}
|
||||
else
|
||||
{
|
||||
// nowhere to land, pick something friendly and circle over it.
|
||||
|
||||
// i'd prefer something we own
|
||||
var someBuilding = self.World.ActorsWithTrait<Building>()
|
||||
.Select( a => a.Actor )
|
||||
.FirstOrDefault(a => a.Owner == self.Owner);
|
||||
|
||||
// failing that, something unlikely to shoot at us
|
||||
if (someBuilding == null)
|
||||
someBuilding = self.World.ActorsWithTrait<Building>()
|
||||
.Select( a => a.Actor )
|
||||
.FirstOrDefault(a => self.Owner.Stances[a.Owner] == Stance.Ally);
|
||||
|
||||
if (someBuilding == null)
|
||||
{
|
||||
// ... going down the garden to eat worms ...
|
||||
self.QueueActivity(new FlyOffMap());
|
||||
self.QueueActivity(new RemoveSelf());
|
||||
return;
|
||||
}
|
||||
|
||||
self.QueueActivity(Fly.ToCell(someBuilding.Location));
|
||||
{
|
||||
// nowhere to land, pick something friendly and circle over it.
|
||||
|
||||
// i'd prefer something we own
|
||||
var someBuilding = self.World.ActorsWithTrait<Building>()
|
||||
.Select( a => a.Actor )
|
||||
.FirstOrDefault(a => a.Owner == self.Owner);
|
||||
|
||||
// failing that, something unlikely to shoot at us
|
||||
if (someBuilding == null)
|
||||
someBuilding = self.World.ActorsWithTrait<Building>()
|
||||
.Select( a => a.Actor )
|
||||
.FirstOrDefault(a => self.Owner.Stances[a.Owner] == Stance.Ally);
|
||||
|
||||
if (someBuilding == null)
|
||||
{
|
||||
// ... going down the garden to eat worms ...
|
||||
self.QueueActivity(new FlyOffMap());
|
||||
self.QueueActivity(new RemoveSelf());
|
||||
return;
|
||||
}
|
||||
|
||||
self.QueueActivity(Fly.ToCell(someBuilding.Location));
|
||||
self.QueueActivity(new FlyCircle());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits.Activities;
|
||||
using OpenRA.Traits.Activities;
|
||||
using OpenRA.Mods.RA.Buildings;
|
||||
|
||||
namespace OpenRA.Mods.RA.Air
|
||||
@@ -24,13 +24,13 @@ namespace OpenRA.Mods.RA.Air
|
||||
int2 w1, w2, w3; /* tangent points to turn circles */
|
||||
|
||||
public static Actor ChooseAirfield(Actor self)
|
||||
{
|
||||
return self.World.ActorsWithTrait<Reservable>()
|
||||
.Where(a => a.Actor.Owner == self.Owner)
|
||||
.Where(a => self.Info.Traits.Get<PlaneInfo>().RearmBuildings.Contains(a.Actor.Info.Name)
|
||||
&& !Reservable.IsReserved(a.Actor))
|
||||
.OrderBy(a => (a.Actor.CenterLocation - self.CenterLocation).LengthSquared)
|
||||
.Select(a => a.Actor)
|
||||
{
|
||||
return self.World.ActorsWithTrait<Reservable>()
|
||||
.Where(a => a.Actor.Owner == self.Owner)
|
||||
.Where(a => self.Info.Traits.Get<PlaneInfo>().RearmBuildings.Contains(a.Actor.Info.Name)
|
||||
&& !Reservable.IsReserved(a.Actor))
|
||||
.OrderBy(a => (a.Actor.CenterLocation - self.CenterLocation).LengthSquared)
|
||||
.Select(a => a.Actor)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,18 @@
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
/* tag trait for "bases": mcv/fact */
|
||||
public class BaseBuildingInfo : TraitInfo<BaseBuilding> { }
|
||||
public class BaseBuilding { }
|
||||
}
|
||||
#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 OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
/* tag trait for "bases": mcv/fact */
|
||||
public class BaseBuildingInfo : TraitInfo<BaseBuilding> { }
|
||||
public class BaseBuilding { }
|
||||
}
|
||||
|
||||
@@ -53,8 +53,8 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
if (remainingTicks == 0)
|
||||
{
|
||||
var csv = self.Info.Traits.GetOrDefault<CustomSellValueInfo>();
|
||||
var buildingValue = csv != null ? csv.Value : self.Info.Traits.Get<ValuedInfo>().Cost;
|
||||
|
||||
var buildingValue = csv != null ? csv.Value : self.Info.Traits.Get<ValuedInfo>().Cost;
|
||||
|
||||
var hpToRepair = Math.Min(Info.RepairStep, Health.MaxHP - Health.HP);
|
||||
var cost = (hpToRepair * Info.RepairPercent * buildingValue) / (Health.MaxHP * 100);
|
||||
if (!self.Owner.PlayerActor.Trait<PlayerResources>().TakeCash(cost))
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Mods.RA.Effects;
|
||||
|
||||
namespace OpenRA.Mods.RA.Buildings
|
||||
@@ -35,9 +35,9 @@ namespace OpenRA.Mods.RA.Buildings
|
||||
pr.GiveCash(refund);
|
||||
|
||||
foreach (var ns in self.TraitsImplementing<INotifySold>())
|
||||
ns.Sold(self);
|
||||
|
||||
if (self.World.LocalPlayer != null && self.Owner.Stances[self.World.LocalPlayer] == Stance.Ally)
|
||||
ns.Sold(self);
|
||||
|
||||
if (self.World.LocalPlayer != null && self.Owner.Stances[self.World.LocalPlayer] == Stance.Ally)
|
||||
self.World.AddFrameEndTask(w => w.Add(new CashTick(refund, 30, 2, self.CenterLocation, self.Owner.ColorRamp.GetColor(0))));
|
||||
|
||||
self.Destroy();
|
||||
|
||||
@@ -68,18 +68,18 @@ namespace OpenRA.Mods.RA
|
||||
canCloak = (e.DamageState < DamageState.Critical);
|
||||
if (Cloaked && !canCloak)
|
||||
DoUncloak();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static readonly Renderable[] Nothing = { };
|
||||
public IEnumerable<Renderable>
|
||||
ModifyRender(Actor self, IEnumerable<Renderable> rs)
|
||||
{
|
||||
if (remainingTime > 0)
|
||||
return rs;
|
||||
|
||||
if (Cloaked && IsVisible(self))
|
||||
return rs.Select(a => a.WithPalette("shadow"));
|
||||
else
|
||||
return rs;
|
||||
|
||||
if (Cloaked && IsVisible(self))
|
||||
return rs.Select(a => a.WithPalette("shadow"));
|
||||
else
|
||||
return Nothing;
|
||||
}
|
||||
|
||||
@@ -107,10 +107,10 @@ namespace OpenRA.Mods.RA
|
||||
if (!Cloaked || self.Owner == self.World.LocalPlayer ||
|
||||
self.World.LocalPlayer == null ||
|
||||
self.Owner.Stances[self.World.LocalPlayer] == Stance.Ally)
|
||||
return true;
|
||||
|
||||
return self.World.ActorsWithTrait<DetectCloaked>().Any(a =>
|
||||
a.Actor.Owner.Stances[self.Owner] != Stance.Ally &&
|
||||
return true;
|
||||
|
||||
return self.World.ActorsWithTrait<DetectCloaked>().Any(a =>
|
||||
a.Actor.Owner.Stances[self.Owner] != Stance.Ally &&
|
||||
(self.Location - a.Actor.Location).Length < a.Actor.Info.Traits.Get<DetectCloakedInfo>().Range);
|
||||
}
|
||||
|
||||
|
||||
@@ -47,9 +47,9 @@ namespace OpenRA.Mods.RA
|
||||
if (self.Owner.WinState == WinState.Lost) return;
|
||||
self.Owner.WinState = WinState.Lost;
|
||||
|
||||
Game.Debug("{0} is defeated.".F(self.Owner.PlayerName));
|
||||
|
||||
foreach (var a in self.World.Actors.Where(a => a.Owner == self.Owner))
|
||||
Game.Debug("{0} is defeated.".F(self.Owner.PlayerName));
|
||||
|
||||
foreach (var a in self.World.Actors.Where(a => a.Owner == self.Owner))
|
||||
a.Kill(a);
|
||||
|
||||
if (self.Owner == self.World.LocalPlayer)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Mods.RA.Buildings;
|
||||
|
||||
/*
|
||||
@@ -95,13 +95,13 @@ namespace OpenRA.Mods.RA
|
||||
public bool CanEnterCell(int2 cell)
|
||||
{
|
||||
if (!self.World.Map.IsInMap(cell.X, cell.Y)) return false;
|
||||
var type = self.World.GetTerrainType(cell);
|
||||
if (!Info.TerrainTypes.Contains(type))
|
||||
return false;
|
||||
|
||||
if (self.World.WorldActor.Trait<BuildingInfluence>().GetBuildingAt(cell) != null) return false;
|
||||
if (self.World.WorldActor.Trait<UnitInfluence>().GetUnitsAt(cell).Any()) return false;
|
||||
|
||||
var type = self.World.GetTerrainType(cell);
|
||||
if (!Info.TerrainTypes.Contains(type))
|
||||
return false;
|
||||
|
||||
if (self.World.WorldActor.Trait<BuildingInfluence>().GetBuildingAt(cell) != null) return false;
|
||||
if (self.World.WorldActor.Trait<UnitInfluence>().GetUnitsAt(cell).Any()) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,45 +48,45 @@ namespace OpenRA.Mods.RA
|
||||
for (var n = 0; n < toSpawn; n++)
|
||||
SpawnCrate(self, info);
|
||||
}
|
||||
}
|
||||
|
||||
void SpawnCrate(Actor self, CrateDropInfo info)
|
||||
{
|
||||
var threshold = 100;
|
||||
var inWater = self.World.SharedRandom.NextDouble() < info.WaterChance;
|
||||
|
||||
for (var n = 0; n < threshold; 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;
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
void SpawnCrate(Actor self, CrateDropInfo info)
|
||||
{
|
||||
var threshold = 100;
|
||||
var inWater = self.World.SharedRandom.NextDouble() < info.WaterChance;
|
||||
|
||||
for (var n = 0; n < threshold; 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;
|
||||
|
||||
// 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 FlyAttackLoop(p));
|
||||
plane.Trait<ParaDrop>().SetLZ(p);
|
||||
plane.Trait<Cargo>().Load(plane, crate);
|
||||
});
|
||||
return;
|
||||
}
|
||||
});
|
||||
plane.CancelActivity();
|
||||
plane.QueueActivity(new FlyAttackLoop(p));
|
||||
plane.Trait<ParaDrop>().SetLZ(p);
|
||||
plane.Trait<Cargo>().Load(plane, crate);
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
public readonly int Arm = 0;
|
||||
public readonly bool Shadow = false;
|
||||
public readonly bool Proximity = false;
|
||||
public readonly float Angle = 0;
|
||||
public readonly float Angle = 0;
|
||||
public readonly int TrailInterval = 2;
|
||||
|
||||
public IEffect Create(ProjectileArgs args) { return new Bullet( this, args ); }
|
||||
@@ -82,8 +82,8 @@ namespace OpenRA.Mods.RA.Effects
|
||||
return (int)(rawFacing < 128
|
||||
? rawFacing - scale * attitude
|
||||
: rawFacing + scale * attitude);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int ticksToNextSmoke;
|
||||
|
||||
public void Tick( World world )
|
||||
@@ -102,13 +102,13 @@ namespace OpenRA.Mods.RA.Effects
|
||||
|
||||
var highPos = (Info.High || Info.Angle > 0)
|
||||
? (pos - new float2(0, GetAltitude()))
|
||||
: pos;
|
||||
|
||||
if (--ticksToNextSmoke < 0)
|
||||
{
|
||||
world.AddFrameEndTask(w => w.Add(
|
||||
new Smoke(w, highPos.ToInt2(), Info.Trail)));
|
||||
ticksToNextSmoke = Info.TrailInterval;
|
||||
: pos;
|
||||
|
||||
if (--ticksToNextSmoke < 0)
|
||||
{
|
||||
world.AddFrameEndTask(w => w.Add(
|
||||
new Smoke(w, highPos.ToInt2(), Info.Trail)));
|
||||
ticksToNextSmoke = Info.TrailInterval;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Effects
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
public readonly string Image = null;
|
||||
public readonly int ROT = 5;
|
||||
public readonly int RangeLimit = 0;
|
||||
public readonly bool TurboBoost = false;
|
||||
public readonly bool TurboBoost = false;
|
||||
public readonly int TrailInterval = 2;
|
||||
|
||||
public IEffect Create(ProjectileArgs args) { return new Missile( this, args ); }
|
||||
@@ -70,7 +70,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
}
|
||||
|
||||
// In pixels
|
||||
const int MissileCloseEnough = 7;
|
||||
const int MissileCloseEnough = 7;
|
||||
int ticksToNextSmoke;
|
||||
|
||||
public void Tick( World world )
|
||||
@@ -107,12 +107,12 @@ namespace OpenRA.Mods.RA.Effects
|
||||
|
||||
if (Info.Trail != null)
|
||||
{
|
||||
var sp = (SubPxPosition - (move * 3) / 2) / 1024 - new int2(0, Altitude);
|
||||
|
||||
if (--ticksToNextSmoke < 0)
|
||||
{
|
||||
world.AddFrameEndTask(w => w.Add(new Smoke(w, sp, Info.Trail)));
|
||||
ticksToNextSmoke = Info.TrailInterval;
|
||||
var sp = (SubPxPosition - (move * 3) / 2) / 1024 - new int2(0, Altitude);
|
||||
|
||||
if (--ticksToNextSmoke < 0)
|
||||
{
|
||||
world.AddFrameEndTask(w => w.Add(new Smoke(w, sp, Info.Trail)));
|
||||
ticksToNextSmoke = Info.TrailInterval;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace OpenRA.Mods.RA.Effects
|
||||
|
||||
public RepairIndicator(Actor a, int frames)
|
||||
{
|
||||
this.a = a; anim.PlayRepeating("repair");
|
||||
this.a = a; anim.PlayRepeating("repair");
|
||||
framesLeft = frames;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@ namespace OpenRA.Mods.RA
|
||||
[WeaponReference]
|
||||
public readonly string Weapon = "UnitExplode";
|
||||
[WeaponReference]
|
||||
public readonly string EmptyWeapon = "UnitExplode";
|
||||
|
||||
public readonly string EmptyWeapon = "UnitExplode";
|
||||
|
||||
public readonly int Chance = 100;
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ namespace OpenRA.Mods.RA
|
||||
public void Damaged(Actor self, AttackInfo e)
|
||||
{
|
||||
if (e.DamageState == DamageState.Dead)
|
||||
{
|
||||
if (self.World.SharedRandom.Next(100) > self.Info.Traits.Get<ExplodesInfo>().Chance)
|
||||
{
|
||||
if (self.World.SharedRandom.Next(100) > self.Info.Traits.Get<ExplodesInfo>().Chance)
|
||||
return;
|
||||
|
||||
var weapon = ChooseWeaponForExplosion(self);
|
||||
|
||||
@@ -13,7 +13,7 @@ using System.Linq;
|
||||
using OpenRA.GameRules;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.RA.Effects;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.FileFormats;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
@@ -41,14 +41,14 @@ namespace OpenRA.Mods.RA
|
||||
var cost = self.Info.Traits.Get<ValuedInfo>().Cost;
|
||||
Levels = Info.CostThreshold.Select(t => (int)(t * cost)).ToArray();
|
||||
RankAnim = new Animation("rank");
|
||||
RankAnim.PlayFetchIndex("rank", () => Level - 1);
|
||||
|
||||
if (init.Contains<ExperienceInit>())
|
||||
{
|
||||
Experience = init.Get<ExperienceInit, int>();
|
||||
|
||||
while (Level < Levels.Length && Experience >= Levels[Level])
|
||||
Level++;
|
||||
RankAnim.PlayFetchIndex("rank", () => Level - 1);
|
||||
|
||||
if (init.Contains<ExperienceInit>())
|
||||
{
|
||||
Experience = init.Get<ExperienceInit, int>();
|
||||
|
||||
while (Level < Levels.Length && Experience >= Levels[Level])
|
||||
Level++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace OpenRA.Mods.RA
|
||||
int Level = 0;
|
||||
|
||||
public void GiveOneLevel()
|
||||
{
|
||||
{
|
||||
if (Level < Levels.Length)
|
||||
GiveExperience(Levels[Level] - Experience);
|
||||
}
|
||||
@@ -94,40 +94,40 @@ namespace OpenRA.Mods.RA
|
||||
}
|
||||
|
||||
public IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> rs)
|
||||
{
|
||||
if (self.Owner == self.World.LocalPlayer && Level > 0)
|
||||
return InnerModifyRender(self, rs);
|
||||
else
|
||||
return rs;
|
||||
}
|
||||
|
||||
IEnumerable<Renderable> InnerModifyRender(Actor self, IEnumerable<Renderable> rs)
|
||||
{
|
||||
foreach (var r in rs)
|
||||
yield return r;
|
||||
|
||||
RankAnim.Tick(); // hack
|
||||
var bounds = self.GetBounds(false);
|
||||
yield return new Renderable(RankAnim.Image,
|
||||
new float2(bounds.Right - 6, bounds.Bottom - 8), "effect", (int)self.CenterLocation.Y);
|
||||
{
|
||||
if (self.Owner == self.World.LocalPlayer && Level > 0)
|
||||
return InnerModifyRender(self, rs);
|
||||
else
|
||||
return rs;
|
||||
}
|
||||
|
||||
IEnumerable<Renderable> InnerModifyRender(Actor self, IEnumerable<Renderable> rs)
|
||||
{
|
||||
foreach (var r in rs)
|
||||
yield return r;
|
||||
|
||||
RankAnim.Tick(); // hack
|
||||
var bounds = self.GetBounds(false);
|
||||
yield return new Renderable(RankAnim.Image,
|
||||
new float2(bounds.Right - 6, bounds.Bottom - 8), "effect", (int)self.CenterLocation.Y);
|
||||
}
|
||||
}
|
||||
|
||||
class ExperienceInit : IActorInit<int>
|
||||
{
|
||||
[FieldFromYamlKey]
|
||||
public readonly int value = 0;
|
||||
|
||||
public ExperienceInit() { }
|
||||
|
||||
public ExperienceInit(int init)
|
||||
{
|
||||
value = init;
|
||||
}
|
||||
|
||||
public int Value(World world)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
class ExperienceInit : IActorInit<int>
|
||||
{
|
||||
[FieldFromYamlKey]
|
||||
public readonly int value = 0;
|
||||
|
||||
public ExperienceInit() { }
|
||||
|
||||
public ExperienceInit(int init)
|
||||
{
|
||||
value = init;
|
||||
}
|
||||
|
||||
public int Value(World world)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,13 +63,13 @@ namespace OpenRA.Mods.RA
|
||||
}
|
||||
|
||||
Actor ClosestProc(Actor self, Actor ignore)
|
||||
{
|
||||
var refs = self.World.ActorsWithTrait<IAcceptOre>()
|
||||
.Where(x => x.Actor != ignore && x.Actor.Owner == self.Owner)
|
||||
{
|
||||
var refs = self.World.ActorsWithTrait<IAcceptOre>()
|
||||
.Where(x => x.Actor != ignore && x.Actor.Owner == self.Owner)
|
||||
.ToList();
|
||||
var mi = self.Info.Traits.Get<MobileInfo>();
|
||||
var path = self.World.WorldActor.Trait<PathFinder>().FindPath(
|
||||
PathSearch.FromPoints(self.World, mi,
|
||||
PathSearch.FromPoints(self.World, mi,
|
||||
refs.Select(r => r.Actor.Location + r.Trait.DeliverOffset),
|
||||
self.Location, false));
|
||||
path.Reverse();
|
||||
|
||||
@@ -26,8 +26,8 @@ namespace OpenRA.Mods.RA
|
||||
public Color RadarColorOverride(Actor self)
|
||||
{
|
||||
return Color.FromArgb(128, self.Owner.ColorRamp.GetColor(0));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static readonly Renderable[] Nothing = { };
|
||||
public IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> r)
|
||||
{
|
||||
|
||||
@@ -1,16 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class LintBuildablePrerequisites : ILintPass
|
||||
{
|
||||
public void Run(Action<string> emitError)
|
||||
{
|
||||
emitError("Hello World");
|
||||
}
|
||||
}
|
||||
}
|
||||
#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 System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class LintBuildablePrerequisites : ILintPass
|
||||
{
|
||||
public void Run(Action<string> emitError)
|
||||
{
|
||||
emitError("Hello World");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,12 +87,12 @@ namespace OpenRA.Mods.RA.Move
|
||||
{
|
||||
using (new PerfSample("Pathfinder"))
|
||||
{
|
||||
using(search)
|
||||
while (!search.queue.Empty)
|
||||
{
|
||||
var p = search.Expand(world);
|
||||
if (search.heuristic(p) == 0)
|
||||
return MakePath(search.cellInfo, p);
|
||||
using(search)
|
||||
while (!search.queue.Empty)
|
||||
{
|
||||
var p = search.Expand(world);
|
||||
if (search.heuristic(p) == 0)
|
||||
return MakePath(search.cellInfo, p);
|
||||
}
|
||||
|
||||
// no path exists
|
||||
@@ -114,35 +114,35 @@ namespace OpenRA.Mods.RA.Move
|
||||
ret.Add(pathNode);
|
||||
CheckSanePath(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public List<int2> FindBidiPath( /* searches from both ends toward each other */
|
||||
PathSearch fromSrc,
|
||||
PathSearch fromDest)
|
||||
{
|
||||
using (new PerfSample("Pathfinder"))
|
||||
{
|
||||
using (fromSrc)
|
||||
using (fromDest)
|
||||
while (!fromSrc.queue.Empty && !fromDest.queue.Empty)
|
||||
{
|
||||
/* make some progress on the first search */
|
||||
var p = fromSrc.Expand(world);
|
||||
|
||||
if (fromDest.cellInfo[p.X, p.Y].Seen && fromDest.cellInfo[p.X, p.Y].MinCost < float.PositiveInfinity)
|
||||
return MakeBidiPath(fromSrc, fromDest, p);
|
||||
|
||||
/* make some progress on the second search */
|
||||
var q = fromDest.Expand(world);
|
||||
|
||||
if (fromSrc.cellInfo[q.X, q.Y].Seen && fromSrc.cellInfo[q.X, q.Y].MinCost < float.PositiveInfinity)
|
||||
return MakeBidiPath(fromSrc, fromDest, q);
|
||||
}
|
||||
|
||||
return new List<int2>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public List<int2> FindBidiPath( /* searches from both ends toward each other */
|
||||
PathSearch fromSrc,
|
||||
PathSearch fromDest)
|
||||
{
|
||||
using (new PerfSample("Pathfinder"))
|
||||
{
|
||||
using (fromSrc)
|
||||
using (fromDest)
|
||||
while (!fromSrc.queue.Empty && !fromDest.queue.Empty)
|
||||
{
|
||||
/* make some progress on the first search */
|
||||
var p = fromSrc.Expand(world);
|
||||
|
||||
if (fromDest.cellInfo[p.X, p.Y].Seen && fromDest.cellInfo[p.X, p.Y].MinCost < float.PositiveInfinity)
|
||||
return MakeBidiPath(fromSrc, fromDest, p);
|
||||
|
||||
/* make some progress on the second search */
|
||||
var q = fromDest.Expand(world);
|
||||
|
||||
if (fromSrc.cellInfo[q.X, q.Y].Seen && fromSrc.cellInfo[q.X, q.Y].MinCost < float.PositiveInfinity)
|
||||
return MakeBidiPath(fromSrc, fromDest, q);
|
||||
}
|
||||
|
||||
return new List<int2>();
|
||||
}
|
||||
}
|
||||
|
||||
static List<int2> MakeBidiPath(PathSearch a, PathSearch b, int2 p)
|
||||
|
||||
@@ -191,37 +191,37 @@ namespace OpenRA.Mods.RA.Move
|
||||
search.AddInitialCell( sl );
|
||||
|
||||
return search;
|
||||
}
|
||||
|
||||
static readonly Queue<CellInfo[,]> cellInfoPool = new Queue<CellInfo[,]>();
|
||||
|
||||
static CellInfo[,] GetFromPool()
|
||||
{
|
||||
lock (cellInfoPool)
|
||||
return cellInfoPool.Dequeue();
|
||||
}
|
||||
|
||||
static void PutBackIntoPool(CellInfo[,] ci)
|
||||
{
|
||||
lock (cellInfoPool)
|
||||
cellInfoPool.Enqueue(ci);
|
||||
}
|
||||
|
||||
static readonly Queue<CellInfo[,]> cellInfoPool = new Queue<CellInfo[,]>();
|
||||
|
||||
static CellInfo[,] GetFromPool()
|
||||
{
|
||||
lock (cellInfoPool)
|
||||
return cellInfoPool.Dequeue();
|
||||
}
|
||||
|
||||
static void PutBackIntoPool(CellInfo[,] ci)
|
||||
{
|
||||
lock (cellInfoPool)
|
||||
cellInfoPool.Enqueue(ci);
|
||||
}
|
||||
|
||||
CellInfo[ , ] InitCellInfo()
|
||||
{
|
||||
CellInfo[,] result = null;
|
||||
while (cellInfoPool.Count > 0)
|
||||
{
|
||||
var cellInfo = GetFromPool();
|
||||
if (cellInfo.GetUpperBound(0) != world.Map.MapSize.X - 1 ||
|
||||
cellInfo.GetUpperBound(1) != world.Map.MapSize.Y - 1)
|
||||
{
|
||||
Log.Write("debug", "Discarding old pooled CellInfo of wrong size.");
|
||||
continue;
|
||||
}
|
||||
|
||||
result = cellInfo;
|
||||
break;
|
||||
{
|
||||
CellInfo[,] result = null;
|
||||
while (cellInfoPool.Count > 0)
|
||||
{
|
||||
var cellInfo = GetFromPool();
|
||||
if (cellInfo.GetUpperBound(0) != world.Map.MapSize.X - 1 ||
|
||||
cellInfo.GetUpperBound(1) != world.Map.MapSize.Y - 1)
|
||||
{
|
||||
Log.Write("debug", "Discarding old pooled CellInfo of wrong size.");
|
||||
continue;
|
||||
}
|
||||
|
||||
result = cellInfo;
|
||||
break;
|
||||
}
|
||||
|
||||
if (result == null)
|
||||
@@ -243,20 +243,20 @@ namespace OpenRA.Mods.RA.Move
|
||||
int straight = Math.Abs( d.X - d.Y );
|
||||
return (3400 * diag / 24) + (100 * straight);
|
||||
};
|
||||
}
|
||||
|
||||
bool disposed;
|
||||
public void Dispose()
|
||||
{
|
||||
if (disposed)
|
||||
return;
|
||||
|
||||
disposed = true;
|
||||
GC.SuppressFinalize(this);
|
||||
PutBackIntoPool(cellInfo);
|
||||
cellInfo = null;
|
||||
}
|
||||
|
||||
~PathSearch() { Dispose(); }
|
||||
}
|
||||
|
||||
bool disposed;
|
||||
public void Dispose()
|
||||
{
|
||||
if (disposed)
|
||||
return;
|
||||
|
||||
disposed = true;
|
||||
GC.SuppressFinalize(this);
|
||||
PutBackIntoPool(cellInfo);
|
||||
cellInfo = null;
|
||||
}
|
||||
|
||||
~PathSearch() { Dispose(); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,42 +1,52 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Orders
|
||||
{
|
||||
public class DeployOrderTargeter : IOrderTargeter
|
||||
{
|
||||
readonly Func<bool> useDeployCursor;
|
||||
|
||||
public DeployOrderTargeter( string order, int priority )
|
||||
: this( order, priority, () => true )
|
||||
{
|
||||
}
|
||||
|
||||
public DeployOrderTargeter( string order, int priority, Func<bool> useDeployCursor )
|
||||
{
|
||||
this.OrderID = order;
|
||||
this.OrderPriority = priority;
|
||||
this.useDeployCursor = useDeployCursor;
|
||||
}
|
||||
|
||||
public string OrderID { get; private set; }
|
||||
public int OrderPriority { get; private set; }
|
||||
|
||||
public bool CanTargetActor( Actor self, Actor target, bool forceAttack, bool forceMove, bool forceQueued, ref string cursor )
|
||||
{
|
||||
IsQueued = forceQueued;
|
||||
cursor = useDeployCursor() ? "deploy" : "deploy-blocked";
|
||||
return self == target;
|
||||
}
|
||||
|
||||
public bool CanTargetLocation(Actor self, int2 location, List<Actor> actorsAtLocation, bool forceAttack, bool forceMove, bool forceQueued, ref string cursor)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsQueued { get; protected set; }
|
||||
}
|
||||
}
|
||||
#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 System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Orders
|
||||
{
|
||||
public class DeployOrderTargeter : IOrderTargeter
|
||||
{
|
||||
readonly Func<bool> useDeployCursor;
|
||||
|
||||
public DeployOrderTargeter( string order, int priority )
|
||||
: this( order, priority, () => true )
|
||||
{
|
||||
}
|
||||
|
||||
public DeployOrderTargeter( string order, int priority, Func<bool> useDeployCursor )
|
||||
{
|
||||
this.OrderID = order;
|
||||
this.OrderPriority = priority;
|
||||
this.useDeployCursor = useDeployCursor;
|
||||
}
|
||||
|
||||
public string OrderID { get; private set; }
|
||||
public int OrderPriority { get; private set; }
|
||||
|
||||
public bool CanTargetActor( Actor self, Actor target, bool forceAttack, bool forceMove, bool forceQueued, ref string cursor )
|
||||
{
|
||||
IsQueued = forceQueued;
|
||||
cursor = useDeployCursor() ? "deploy" : "deploy-blocked";
|
||||
return self == target;
|
||||
}
|
||||
|
||||
public bool CanTargetLocation(Actor self, int2 location, List<Actor> actorsAtLocation, bool forceAttack, bool forceMove, bool forceQueued, ref string cursor)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsQueued { get; protected set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,15 +6,15 @@
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Mods.RA.Effects;
|
||||
using OpenRA.Mods.RA.Move;
|
||||
using OpenRA.Mods.RA.Render;
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Mods.RA.Effects;
|
||||
using OpenRA.Mods.RA.Move;
|
||||
using OpenRA.Mods.RA.Render;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
|
||||
@@ -6,75 +6,75 @@
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Mods.RA.Air;
|
||||
using OpenRA.Mods.RA.Effects;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class ParaDropInfo : TraitInfo<ParaDrop>
|
||||
{
|
||||
public readonly int LZRange = 4;
|
||||
public readonly string ChuteSound = "chute1.aud";
|
||||
}
|
||||
|
||||
public class ParaDrop : ITick
|
||||
{
|
||||
readonly List<int2> droppedAt = new List<int2>();
|
||||
int2 lz;
|
||||
|
||||
public void SetLZ(int2 lz)
|
||||
{
|
||||
this.lz = lz;
|
||||
droppedAt.Clear();
|
||||
}
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
var info = self.Info.Traits.Get<ParaDropInfo>();
|
||||
var r = info.LZRange;
|
||||
|
||||
if ((self.Location - lz).LengthSquared <= r * r && !droppedAt.Contains(self.Location))
|
||||
{
|
||||
var cargo = self.Trait<Cargo>();
|
||||
if (cargo.IsEmpty(self))
|
||||
FinishedDropping(self);
|
||||
else
|
||||
{
|
||||
if (!IsSuitableCell(cargo.Peek(self), self.Location))
|
||||
return;
|
||||
|
||||
// unload a dude here
|
||||
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,
|
||||
Util.CenterOfCell(Util.CellContaining(self.CenterLocation)),
|
||||
aircraft.Altitude, a)));
|
||||
|
||||
Sound.Play(info.ChuteSound, self.CenterLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IsSuitableCell(Actor actorToDrop, int2 p)
|
||||
{
|
||||
return actorToDrop.Trait<ITeleportable>().CanEnterCell(p);
|
||||
}
|
||||
|
||||
void FinishedDropping(Actor self)
|
||||
{
|
||||
self.CancelActivity();
|
||||
self.QueueActivity(new FlyOffMap { Interruptible = false });
|
||||
self.QueueActivity(new RemoveSelf());
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Mods.RA.Air;
|
||||
using OpenRA.Mods.RA.Effects;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class ParaDropInfo : TraitInfo<ParaDrop>
|
||||
{
|
||||
public readonly int LZRange = 4;
|
||||
public readonly string ChuteSound = "chute1.aud";
|
||||
}
|
||||
|
||||
public class ParaDrop : ITick
|
||||
{
|
||||
readonly List<int2> droppedAt = new List<int2>();
|
||||
int2 lz;
|
||||
|
||||
public void SetLZ(int2 lz)
|
||||
{
|
||||
this.lz = lz;
|
||||
droppedAt.Clear();
|
||||
}
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
var info = self.Info.Traits.Get<ParaDropInfo>();
|
||||
var r = info.LZRange;
|
||||
|
||||
if ((self.Location - lz).LengthSquared <= r * r && !droppedAt.Contains(self.Location))
|
||||
{
|
||||
var cargo = self.Trait<Cargo>();
|
||||
if (cargo.IsEmpty(self))
|
||||
FinishedDropping(self);
|
||||
else
|
||||
{
|
||||
if (!IsSuitableCell(cargo.Peek(self), self.Location))
|
||||
return;
|
||||
|
||||
// unload a dude here
|
||||
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,
|
||||
Util.CenterOfCell(Util.CellContaining(self.CenterLocation)),
|
||||
aircraft.Altitude, a)));
|
||||
|
||||
Sound.Play(info.ChuteSound, self.CenterLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IsSuitableCell(Actor actorToDrop, int2 p)
|
||||
{
|
||||
return actorToDrop.Trait<ITeleportable>().CanEnterCell(p);
|
||||
}
|
||||
|
||||
void FinishedDropping(Actor self)
|
||||
{
|
||||
self.CancelActivity();
|
||||
self.QueueActivity(new FlyOffMap { Interruptible = false });
|
||||
self.QueueActivity(new RemoveSelf());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@ namespace OpenRA.Mods.RA
|
||||
.Any();
|
||||
|
||||
base.Tick(self);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static ActorInfo[] None = { };
|
||||
public override IEnumerable<ActorInfo> AllItems()
|
||||
{
|
||||
@@ -51,7 +51,7 @@ namespace OpenRA.Mods.RA
|
||||
{
|
||||
// Find a production structure to build this actor
|
||||
var producers = self.World
|
||||
.ActorsWithTrait<Production>()
|
||||
.ActorsWithTrait<Production>()
|
||||
.Where(x => x.Actor.Owner == self.Owner)
|
||||
.Where(x => x.Trait.Info.Produces.Contains(Info.Type))
|
||||
.OrderByDescending(x => x.Actor.IsPrimaryBuilding() ? 1 : 0 ); // prioritize the primary.
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace OpenRA.Mods.RA
|
||||
public readonly Actor self;
|
||||
public ProductionQueueInfo Info;
|
||||
PowerManager PlayerPower;
|
||||
PlayerResources PlayerResources;
|
||||
PlayerResources PlayerResources;
|
||||
string Race;
|
||||
|
||||
// A list of things we are currently building
|
||||
@@ -55,7 +55,7 @@ namespace OpenRA.Mods.RA
|
||||
[Sync]
|
||||
public bool CurrentDone { get { return QueueLength == 0 ? false : Queue[0].Done; } }
|
||||
|
||||
// A list of things we could possibly build, even if our race doesn't normally get it
|
||||
// A list of things we could possibly build, even if our race doesn't normally get it
|
||||
public Dictionary<ActorInfo, ProductionState> Produceable;
|
||||
|
||||
public ProductionQueue( Actor self, Actor playerActor, ProductionQueueInfo info )
|
||||
@@ -65,7 +65,7 @@ namespace OpenRA.Mods.RA
|
||||
PlayerResources = playerActor.Trait<PlayerResources>();
|
||||
PlayerPower = playerActor.Trait<PowerManager>();
|
||||
|
||||
Race = self.Owner.Country.Race;
|
||||
Race = self.Owner.Country.Race;
|
||||
Produceable = InitTech(playerActor);
|
||||
}
|
||||
|
||||
@@ -75,26 +75,26 @@ namespace OpenRA.Mods.RA
|
||||
PlayerResources = newOwner.PlayerActor.Trait<PlayerResources>();
|
||||
Queue.Clear();
|
||||
|
||||
// Produceable contains the tech from the original owner - this is desired so we don't clear it.
|
||||
// Produceable contains the tech from the original owner - this is desired so we don't clear it.
|
||||
Produceable = InitTech(self.Owner.PlayerActor);
|
||||
}
|
||||
|
||||
Dictionary<ActorInfo, ProductionState> InitTech(Actor playerActor)
|
||||
{
|
||||
var tech = new Dictionary<ActorInfo, ProductionState>();
|
||||
var ttc = playerActor.Trait<TechTree>();
|
||||
|
||||
foreach (var a in AllBuildables(Info.Type))
|
||||
{
|
||||
var bi = a.Traits.Get<BuildableInfo>();
|
||||
// Can our race build this by satisfying normal prereqs?
|
||||
var buildable = bi.Owner.Contains(Race);
|
||||
tech.Add(a, new ProductionState() { Visible = buildable && !bi.Hidden });
|
||||
if (buildable)
|
||||
ttc.Add(a.Name, a.Traits.Get<BuildableInfo>().Prerequisites.ToList(), this);
|
||||
}
|
||||
|
||||
return tech;
|
||||
}
|
||||
|
||||
Dictionary<ActorInfo, ProductionState> InitTech(Actor playerActor)
|
||||
{
|
||||
var tech = new Dictionary<ActorInfo, ProductionState>();
|
||||
var ttc = playerActor.Trait<TechTree>();
|
||||
|
||||
foreach (var a in AllBuildables(Info.Type))
|
||||
{
|
||||
var bi = a.Traits.Get<BuildableInfo>();
|
||||
// Can our race build this by satisfying normal prereqs?
|
||||
var buildable = bi.Owner.Contains(Race);
|
||||
tech.Add(a, new ProductionState() { Visible = buildable && !bi.Hidden });
|
||||
if (buildable)
|
||||
ttc.Add(a.Name, a.Traits.Get<BuildableInfo>().Prerequisites.ToList(), this);
|
||||
}
|
||||
|
||||
return tech;
|
||||
}
|
||||
|
||||
IEnumerable<ActorInfo> AllBuildables(string category)
|
||||
|
||||
@@ -1,49 +1,49 @@
|
||||
#region Copyright & License Information
|
||||
#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.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class ProductionBarInfo : ITraitInfo
|
||||
{
|
||||
public object Create(ActorInitializer init) { return new ProductionBar( init.self ); }
|
||||
}
|
||||
|
||||
class ProductionBar : ISelectionBar
|
||||
{
|
||||
Actor self;
|
||||
public ProductionBar(Actor self) { this.self = self; }
|
||||
|
||||
public float GetValue()
|
||||
{
|
||||
// only people we like should see our production status.
|
||||
if (self.World.LocalPlayer != null && self.Owner.Stances[self.World.LocalPlayer] != Stance.Ally)
|
||||
return 0;
|
||||
|
||||
var queue = self.TraitsImplementing<ProductionQueue>().FirstOrDefault(q => q.CurrentItem() != null);
|
||||
if (queue == null)
|
||||
{
|
||||
var produces = self.Trait<Production>().Info.Produces;
|
||||
queue = self.Owner.PlayerActor.TraitsImplementing<ProductionQueue>()
|
||||
.FirstOrDefault(q => produces.Contains(q.Info.Type));
|
||||
}
|
||||
|
||||
if (queue == null || queue.CurrentItem() == null)
|
||||
return 0f;
|
||||
|
||||
return 1 - (float)queue.CurrentItem().RemainingCost / queue.CurrentItem().TotalCost;
|
||||
}
|
||||
|
||||
public Color GetColor() { return Color.SkyBlue; }
|
||||
}
|
||||
}
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class ProductionBarInfo : ITraitInfo
|
||||
{
|
||||
public object Create(ActorInitializer init) { return new ProductionBar( init.self ); }
|
||||
}
|
||||
|
||||
class ProductionBar : ISelectionBar
|
||||
{
|
||||
Actor self;
|
||||
public ProductionBar(Actor self) { this.self = self; }
|
||||
|
||||
public float GetValue()
|
||||
{
|
||||
// only people we like should see our production status.
|
||||
if (self.World.LocalPlayer != null && self.Owner.Stances[self.World.LocalPlayer] != Stance.Ally)
|
||||
return 0;
|
||||
|
||||
var queue = self.TraitsImplementing<ProductionQueue>().FirstOrDefault(q => q.CurrentItem() != null);
|
||||
if (queue == null)
|
||||
{
|
||||
var produces = self.Trait<Production>().Info.Produces;
|
||||
queue = self.Owner.PlayerActor.TraitsImplementing<ProductionQueue>()
|
||||
.FirstOrDefault(q => produces.Contains(q.Info.Type));
|
||||
}
|
||||
|
||||
if (queue == null || queue.CurrentItem() == null)
|
||||
return 0f;
|
||||
|
||||
return 1 - (float)queue.CurrentItem().RemainingCost / queue.CurrentItem().TotalCost;
|
||||
}
|
||||
|
||||
public Color GetColor() { return Color.SkyBlue; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +1,46 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("OpenRA.Mods.RA")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("OpenRA.Mods.RA")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2010")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("23828b43-3536-4681-bc2f-2eb2e0972354")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
#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.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("OpenRA.Mods.RA")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("OpenRA.Mods.RA")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2010")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("23828b43-3536-4681-bc2f-2eb2e0972354")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
|
||||
@@ -1,206 +1,206 @@
|
||||
#region Copyright & License Information
|
||||
#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.Linq;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class ProximityCapturableInfo : ITraitInfo
|
||||
{
|
||||
public readonly bool Permanent = false;
|
||||
public readonly int Range = 5;
|
||||
public readonly bool MustBeClear = false;
|
||||
public readonly string[] CaptorTypes = {"Vehicle", "Tank", "Infantry"};
|
||||
|
||||
public object Create(ActorInitializer init) { return new ProximityCapturable(init.self, this); }
|
||||
}
|
||||
|
||||
public class ProximityCapturable : ITick, ISync
|
||||
{
|
||||
[Sync]
|
||||
public Player Owner { get { return Captured ? Self.Owner : OriginalOwner; } }
|
||||
|
||||
[Sync]
|
||||
public readonly Player OriginalOwner;
|
||||
|
||||
public ProximityCapturableInfo Info;
|
||||
|
||||
[Sync]
|
||||
public int Range;
|
||||
|
||||
[Sync]
|
||||
public bool Permanent;
|
||||
|
||||
[Sync]
|
||||
public bool Captured = false;
|
||||
|
||||
[Sync]
|
||||
public bool MustBeClear = false;
|
||||
|
||||
public string[] CaptorTypes = {};
|
||||
|
||||
public Actor Self;
|
||||
|
||||
public ProximityCapturable(Actor self, ProximityCapturableInfo info)
|
||||
{
|
||||
Info = info;
|
||||
Range = info.Range;
|
||||
Permanent = info.Permanent;
|
||||
MustBeClear = info.MustBeClear;
|
||||
Self = self;
|
||||
OriginalOwner = self.Owner;
|
||||
CaptorTypes = info.CaptorTypes;
|
||||
}
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
if (Captured && Permanent) return; // Permanent capture
|
||||
|
||||
//var playersNear = CountPlayersNear(self, OriginalOwner, Range);
|
||||
|
||||
if (!Captured)
|
||||
{
|
||||
var captor = GetInRange(self, OriginalOwner, Range, CaptorTypes);
|
||||
|
||||
if (captor != null)
|
||||
{
|
||||
if (MustBeClear && !IsClear(self, captor.Owner, Range, OriginalOwner, CaptorTypes)) return;
|
||||
|
||||
ChangeOwnership(self, captor, OriginalOwner);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// if the area must be clear, and there is more than 1 player nearby => return ownership to default
|
||||
if (MustBeClear && !IsClear(self, Owner, Range, OriginalOwner, CaptorTypes))
|
||||
{
|
||||
// Revert Ownership
|
||||
ChangeOwnership(self, Owner, OriginalOwner);
|
||||
return;
|
||||
}
|
||||
|
||||
// See if the 'temporary' owner still is in range
|
||||
if (!IsStillInRange(self, self.Owner, Range, CaptorTypes))
|
||||
{
|
||||
// no.. So find a new one
|
||||
var captor = GetInRange(self, OriginalOwner, Range, CaptorTypes);
|
||||
|
||||
if (captor != null) // got one
|
||||
{
|
||||
ChangeOwnership(self, captor, Owner);
|
||||
return;
|
||||
}
|
||||
|
||||
// Revert Ownership otherwise
|
||||
ChangeOwnership(self, Owner, OriginalOwner);
|
||||
}
|
||||
}
|
||||
|
||||
private void ChangeOwnership(Actor self, Player previousOwner, Player originalOwner)
|
||||
{
|
||||
self.World.AddFrameEndTask(w =>
|
||||
{
|
||||
if (self.Destroyed) return;
|
||||
|
||||
// momentarily remove from world so the ownership queries don't get confused
|
||||
w.Remove(self);
|
||||
self.Owner = originalOwner;
|
||||
w.Add(self);
|
||||
|
||||
if (self.Owner == self.World.LocalPlayer)
|
||||
w.Add(new FlashTarget(self));
|
||||
|
||||
Captured = false;
|
||||
|
||||
foreach (var t in self.TraitsImplementing<INotifyCapture>())
|
||||
t.OnCapture(self, self, previousOwner, self.Owner);
|
||||
});
|
||||
}
|
||||
|
||||
private void ChangeOwnership(Actor self, Actor captor, Player previousOwner)
|
||||
{
|
||||
self.World.AddFrameEndTask(w =>
|
||||
{
|
||||
if (self.Destroyed || (captor.Destroyed || !captor.IsInWorld)) return;
|
||||
|
||||
// momentarily remove from world so the ownership queries don't get confused
|
||||
w.Remove(self);
|
||||
self.Owner = captor.Owner;
|
||||
w.Add(self);
|
||||
|
||||
if (self.Owner == self.World.LocalPlayer)
|
||||
w.Add(new FlashTarget(self));
|
||||
|
||||
Captured = true;
|
||||
|
||||
foreach (var t in self.TraitsImplementing<INotifyCapture>())
|
||||
t.OnCapture(self, captor, previousOwner, self.Owner);
|
||||
});
|
||||
}
|
||||
|
||||
static bool AreMutualAllies(Player a, Player b)
|
||||
{
|
||||
return a.Stances[b] == Stance.Ally &&
|
||||
b.Stances[a] == Stance.Ally;
|
||||
}
|
||||
|
||||
public static bool IsClear(Actor self, Player currentOwner, int range, Player originalOwner, string[] actorTypes)
|
||||
{
|
||||
var unitsInRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range);
|
||||
*/
|
||||
#endregion
|
||||
|
||||
return unitsInRange.Where(a => !a.Destroyed && a.IsInWorld && a != self && !a.Owner.NonCombatant && a.Owner != originalOwner)
|
||||
.Where(a => a.Owner != currentOwner)
|
||||
.Where(a => actorTypes.Length == 0 || (a.HasTrait<ProximityCaptor>() && a.Trait<ProximityCaptor>().HasAny(actorTypes)))
|
||||
using System.Linq;
|
||||
using OpenRA.Effects;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class ProximityCapturableInfo : ITraitInfo
|
||||
{
|
||||
public readonly bool Permanent = false;
|
||||
public readonly int Range = 5;
|
||||
public readonly bool MustBeClear = false;
|
||||
public readonly string[] CaptorTypes = {"Vehicle", "Tank", "Infantry"};
|
||||
|
||||
public object Create(ActorInitializer init) { return new ProximityCapturable(init.self, this); }
|
||||
}
|
||||
|
||||
public class ProximityCapturable : ITick, ISync
|
||||
{
|
||||
[Sync]
|
||||
public Player Owner { get { return Captured ? Self.Owner : OriginalOwner; } }
|
||||
|
||||
[Sync]
|
||||
public readonly Player OriginalOwner;
|
||||
|
||||
public ProximityCapturableInfo Info;
|
||||
|
||||
[Sync]
|
||||
public int Range;
|
||||
|
||||
[Sync]
|
||||
public bool Permanent;
|
||||
|
||||
[Sync]
|
||||
public bool Captured = false;
|
||||
|
||||
[Sync]
|
||||
public bool MustBeClear = false;
|
||||
|
||||
public string[] CaptorTypes = {};
|
||||
|
||||
public Actor Self;
|
||||
|
||||
public ProximityCapturable(Actor self, ProximityCapturableInfo info)
|
||||
{
|
||||
Info = info;
|
||||
Range = info.Range;
|
||||
Permanent = info.Permanent;
|
||||
MustBeClear = info.MustBeClear;
|
||||
Self = self;
|
||||
OriginalOwner = self.Owner;
|
||||
CaptorTypes = info.CaptorTypes;
|
||||
}
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
if (Captured && Permanent) return; // Permanent capture
|
||||
|
||||
//var playersNear = CountPlayersNear(self, OriginalOwner, Range);
|
||||
|
||||
if (!Captured)
|
||||
{
|
||||
var captor = GetInRange(self, OriginalOwner, Range, CaptorTypes);
|
||||
|
||||
if (captor != null)
|
||||
{
|
||||
if (MustBeClear && !IsClear(self, captor.Owner, Range, OriginalOwner, CaptorTypes)) return;
|
||||
|
||||
ChangeOwnership(self, captor, OriginalOwner);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// if the area must be clear, and there is more than 1 player nearby => return ownership to default
|
||||
if (MustBeClear && !IsClear(self, Owner, Range, OriginalOwner, CaptorTypes))
|
||||
{
|
||||
// Revert Ownership
|
||||
ChangeOwnership(self, Owner, OriginalOwner);
|
||||
return;
|
||||
}
|
||||
|
||||
// See if the 'temporary' owner still is in range
|
||||
if (!IsStillInRange(self, self.Owner, Range, CaptorTypes))
|
||||
{
|
||||
// no.. So find a new one
|
||||
var captor = GetInRange(self, OriginalOwner, Range, CaptorTypes);
|
||||
|
||||
if (captor != null) // got one
|
||||
{
|
||||
ChangeOwnership(self, captor, Owner);
|
||||
return;
|
||||
}
|
||||
|
||||
// Revert Ownership otherwise
|
||||
ChangeOwnership(self, Owner, OriginalOwner);
|
||||
}
|
||||
}
|
||||
|
||||
private void ChangeOwnership(Actor self, Player previousOwner, Player originalOwner)
|
||||
{
|
||||
self.World.AddFrameEndTask(w =>
|
||||
{
|
||||
if (self.Destroyed) return;
|
||||
|
||||
// momentarily remove from world so the ownership queries don't get confused
|
||||
w.Remove(self);
|
||||
self.Owner = originalOwner;
|
||||
w.Add(self);
|
||||
|
||||
if (self.Owner == self.World.LocalPlayer)
|
||||
w.Add(new FlashTarget(self));
|
||||
|
||||
Captured = false;
|
||||
|
||||
foreach (var t in self.TraitsImplementing<INotifyCapture>())
|
||||
t.OnCapture(self, self, previousOwner, self.Owner);
|
||||
});
|
||||
}
|
||||
|
||||
private void ChangeOwnership(Actor self, Actor captor, Player previousOwner)
|
||||
{
|
||||
self.World.AddFrameEndTask(w =>
|
||||
{
|
||||
if (self.Destroyed || (captor.Destroyed || !captor.IsInWorld)) return;
|
||||
|
||||
// momentarily remove from world so the ownership queries don't get confused
|
||||
w.Remove(self);
|
||||
self.Owner = captor.Owner;
|
||||
w.Add(self);
|
||||
|
||||
if (self.Owner == self.World.LocalPlayer)
|
||||
w.Add(new FlashTarget(self));
|
||||
|
||||
Captured = true;
|
||||
|
||||
foreach (var t in self.TraitsImplementing<INotifyCapture>())
|
||||
t.OnCapture(self, captor, previousOwner, self.Owner);
|
||||
});
|
||||
}
|
||||
|
||||
static bool AreMutualAllies(Player a, Player b)
|
||||
{
|
||||
return a.Stances[b] == Stance.Ally &&
|
||||
b.Stances[a] == Stance.Ally;
|
||||
}
|
||||
|
||||
public static bool IsClear(Actor self, Player currentOwner, int range, Player originalOwner, string[] actorTypes)
|
||||
{
|
||||
var unitsInRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range);
|
||||
|
||||
return unitsInRange.Where(a => !a.Destroyed && a.IsInWorld && a != self && !a.Owner.NonCombatant && a.Owner != originalOwner)
|
||||
.Where(a => a.Owner != currentOwner)
|
||||
.Where(a => actorTypes.Length == 0 || (a.HasTrait<ProximityCaptor>() && a.Trait<ProximityCaptor>().HasAny(actorTypes)))
|
||||
.All(a => AreMutualAllies(a.Owner, currentOwner));
|
||||
}
|
||||
|
||||
// TODO exclude other NeutralActor that arent permanent
|
||||
public static bool IsStillInRange(Actor self, Player currentOwner, int range, string[] actorTypes)
|
||||
{
|
||||
var unitsInRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range);
|
||||
|
||||
return unitsInRange
|
||||
.Where(a => a.Owner == currentOwner && !a.Destroyed && a.IsInWorld && a != self)
|
||||
.Where(a => actorTypes.Length == 0 || (a.HasTrait<ProximityCaptor>() && a.Trait<ProximityCaptor>().HasAny(actorTypes)))
|
||||
.Any();
|
||||
}
|
||||
|
||||
// TODO exclude other NeutralActor that arent permanent
|
||||
public static Actor GetInRange(Actor self, Player originalOwner, int range, string[] actorTypes)
|
||||
{
|
||||
var unitsInRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range);
|
||||
|
||||
return unitsInRange
|
||||
.Where(a => a.Owner != originalOwner && !a.Destroyed && a.IsInWorld && a != self)
|
||||
.Where(a => !a.Owner.PlayerRef.OwnsWorld)
|
||||
.Where(a => !a.Owner.PlayerRef.NonCombatant)
|
||||
.Where(a => actorTypes.Length == 0 || (a.HasTrait<ProximityCaptor>() && a.Trait<ProximityCaptor>().HasAny(actorTypes)))
|
||||
.OrderBy(a => (a.CenterLocation - self.CenterLocation).LengthSquared)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
public static int CountPlayersNear(Actor self, Player ignoreMe, int range, string[] actorTypes)
|
||||
{
|
||||
var unitsInRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range);
|
||||
|
||||
return unitsInRange
|
||||
.Where(a => a.Owner != ignoreMe && !a.Destroyed && a.IsInWorld && a != self)
|
||||
.Where(a => !a.Owner.PlayerRef.OwnsWorld)
|
||||
.Where(a => !a.Owner.PlayerRef.NonCombatant)
|
||||
.Where(a =>actorTypes.Length == 0 || ( a.HasTrait<ProximityCaptor>() && a.Trait<ProximityCaptor>().HasAny(actorTypes)))
|
||||
.Select(a => a.Owner)
|
||||
.Distinct()
|
||||
.Count();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO exclude other NeutralActor that arent permanent
|
||||
public static bool IsStillInRange(Actor self, Player currentOwner, int range, string[] actorTypes)
|
||||
{
|
||||
var unitsInRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range);
|
||||
|
||||
return unitsInRange
|
||||
.Where(a => a.Owner == currentOwner && !a.Destroyed && a.IsInWorld && a != self)
|
||||
.Where(a => actorTypes.Length == 0 || (a.HasTrait<ProximityCaptor>() && a.Trait<ProximityCaptor>().HasAny(actorTypes)))
|
||||
.Any();
|
||||
}
|
||||
|
||||
// TODO exclude other NeutralActor that arent permanent
|
||||
public static Actor GetInRange(Actor self, Player originalOwner, int range, string[] actorTypes)
|
||||
{
|
||||
var unitsInRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range);
|
||||
|
||||
return unitsInRange
|
||||
.Where(a => a.Owner != originalOwner && !a.Destroyed && a.IsInWorld && a != self)
|
||||
.Where(a => !a.Owner.PlayerRef.OwnsWorld)
|
||||
.Where(a => !a.Owner.PlayerRef.NonCombatant)
|
||||
.Where(a => actorTypes.Length == 0 || (a.HasTrait<ProximityCaptor>() && a.Trait<ProximityCaptor>().HasAny(actorTypes)))
|
||||
.OrderBy(a => (a.CenterLocation - self.CenterLocation).LengthSquared)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
public static int CountPlayersNear(Actor self, Player ignoreMe, int range, string[] actorTypes)
|
||||
{
|
||||
var unitsInRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range);
|
||||
|
||||
return unitsInRange
|
||||
.Where(a => a.Owner != ignoreMe && !a.Destroyed && a.IsInWorld && a != self)
|
||||
.Where(a => !a.Owner.PlayerRef.OwnsWorld)
|
||||
.Where(a => !a.Owner.PlayerRef.NonCombatant)
|
||||
.Where(a =>actorTypes.Length == 0 || ( a.HasTrait<ProximityCaptor>() && a.Trait<ProximityCaptor>().HasAny(actorTypes)))
|
||||
.Select(a => a.Owner)
|
||||
.Distinct()
|
||||
.Count();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
#region Copyright & License Information
|
||||
#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 OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Render
|
||||
{
|
||||
class RenderEditorOnlyInfo : RenderSimpleInfo
|
||||
{
|
||||
public override object Create(ActorInitializer init) { return new RenderEditorOnly(init.self); }
|
||||
}
|
||||
|
||||
class RenderEditorOnly : RenderSimple
|
||||
{
|
||||
public RenderEditorOnly(Actor self) : base(self, () => 0) { }
|
||||
|
||||
static readonly Renderable[] Nothing = { };
|
||||
public override IEnumerable<Renderable> Render(Actor self) { return Nothing; }
|
||||
}
|
||||
}
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA.Render
|
||||
{
|
||||
class RenderEditorOnlyInfo : RenderSimpleInfo
|
||||
{
|
||||
public override object Create(ActorInitializer init) { return new RenderEditorOnly(init.self); }
|
||||
}
|
||||
|
||||
class RenderEditorOnly : RenderSimple
|
||||
{
|
||||
public RenderEditorOnly(Actor self) : base(self, () => 0) { }
|
||||
|
||||
static readonly Renderable[] Nothing = { };
|
||||
public override IEnumerable<Renderable> Render(Actor self) { return Nothing; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Drawing;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Traits;
|
||||
|
||||
@@ -33,8 +33,8 @@ namespace OpenRA.Mods.RA
|
||||
public IDisposable Reserve(Actor self, Actor forActor, Aircraft derp)
|
||||
{
|
||||
reservedFor = forActor;
|
||||
herp = derp;
|
||||
|
||||
herp = derp;
|
||||
|
||||
// NOTE: we really dont care about the GC eating DisposableActions that apply to a world *other* than
|
||||
// the one we're playing in.
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
|
||||
@@ -23,10 +23,10 @@ namespace OpenRA.Mods.RA
|
||||
public void WorldLoaded(World world)
|
||||
{
|
||||
foreach (var actorReference in world.Map.Actors.Value)
|
||||
{
|
||||
// if there is no real player associated, dont spawn it.
|
||||
var ownerName = actorReference.Value.InitDict.Get<OwnerInit>().PlayerName;
|
||||
if (!world.players.Values.Any(p => p.InternalName == ownerName))
|
||||
{
|
||||
// if there is no real player associated, dont spawn it.
|
||||
var ownerName = actorReference.Value.InitDict.Get<OwnerInit>().PlayerName;
|
||||
if (!world.players.Values.Any(p => p.InternalName == ownerName))
|
||||
continue;
|
||||
|
||||
var initDict = actorReference.Value.InitDict;
|
||||
|
||||
@@ -132,16 +132,16 @@ namespace OpenRA.Mods.RA
|
||||
public string VoicePhraseForOrder(Actor self, Order order)
|
||||
{
|
||||
return order.OrderString == "Disguise" ? "Attack" : null;
|
||||
}
|
||||
|
||||
public Color RadarColorOverride(Actor self)
|
||||
{
|
||||
if (!Disguised || self.World.LocalPlayer == null ||
|
||||
self.Owner.Stances[self.World.LocalPlayer] == Stance.Ally)
|
||||
return self.Owner.ColorRamp.GetColor(0);
|
||||
|
||||
return disguisedAsPlayer.ColorRamp.GetColor(0);
|
||||
}
|
||||
}
|
||||
|
||||
public Color RadarColorOverride(Actor self)
|
||||
{
|
||||
if (!Disguised || self.World.LocalPlayer == null ||
|
||||
self.Owner.Stances[self.World.LocalPlayer] == Stance.Ally)
|
||||
return self.Owner.ColorRamp.GetColor(0);
|
||||
|
||||
return disguisedAsPlayer.ColorRamp.GetColor(0);
|
||||
}
|
||||
}
|
||||
|
||||
class IgnoresDisguiseInfo : TraitInfo<IgnoresDisguise> {}
|
||||
|
||||
@@ -1,46 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class StrategicPointInfo : ITraitInfo
|
||||
{
|
||||
public readonly bool Critical = false;
|
||||
|
||||
public object Create(ActorInitializer init) { return new StrategicPoint(init.self, this); }
|
||||
}
|
||||
|
||||
public class StrategicPoint : INotifyCapture, ITick, ISync
|
||||
{
|
||||
[Sync] public Actor Self;
|
||||
[Sync] public bool Critical;
|
||||
[Sync] public Player OriginalOwner;
|
||||
[Sync] public int TicksOwned = 0;
|
||||
|
||||
public StrategicPointInfo Info;
|
||||
|
||||
public StrategicPoint(Actor self, StrategicPointInfo info)
|
||||
{
|
||||
Self = self;
|
||||
Info = info;
|
||||
OriginalOwner = self.Owner;
|
||||
|
||||
Critical = info.Critical;
|
||||
}
|
||||
|
||||
public void OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner)
|
||||
{
|
||||
TicksOwned = 0;
|
||||
}
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
if (OriginalOwner == self.Owner || self.Owner.WinState != WinState.Undefined) return;
|
||||
|
||||
TicksOwned++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#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 System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
public class StrategicPointInfo : ITraitInfo
|
||||
{
|
||||
public readonly bool Critical = false;
|
||||
|
||||
public object Create(ActorInitializer init) { return new StrategicPoint(init.self, this); }
|
||||
}
|
||||
|
||||
public class StrategicPoint : INotifyCapture, ITick, ISync
|
||||
{
|
||||
[Sync] public Actor Self;
|
||||
[Sync] public bool Critical;
|
||||
[Sync] public Player OriginalOwner;
|
||||
[Sync] public int TicksOwned = 0;
|
||||
|
||||
public StrategicPointInfo Info;
|
||||
|
||||
public StrategicPoint(Actor self, StrategicPointInfo info)
|
||||
{
|
||||
Self = self;
|
||||
Info = info;
|
||||
OriginalOwner = self.Owner;
|
||||
|
||||
Critical = info.Critical;
|
||||
}
|
||||
|
||||
public void OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner)
|
||||
{
|
||||
TicksOwned = 0;
|
||||
}
|
||||
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
if (OriginalOwner == self.Owner || self.Owner.WinState != WinState.Undefined) return;
|
||||
|
||||
TicksOwned++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Mods.RA.Air;
|
||||
using OpenRA.Mods.RA.Air;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
@@ -20,8 +20,8 @@ namespace OpenRA.Mods.RA
|
||||
[ActorReference]
|
||||
public readonly string UnitType = "badr.bomber";
|
||||
[ActorReference]
|
||||
public readonly string FlareType = null;
|
||||
|
||||
public readonly string FlareType = null;
|
||||
|
||||
public readonly int FlareTime = 25 * 60 * 2; // 2 minutes
|
||||
|
||||
public override object Create(ActorInitializer init) { return new AirstrikePower(init.self, this); }
|
||||
@@ -40,12 +40,12 @@ namespace OpenRA.Mods.RA
|
||||
{
|
||||
new LocationInit( order.TargetLocation ),
|
||||
new OwnerInit( self.Owner ),
|
||||
}) : null;
|
||||
|
||||
if (flare != null)
|
||||
{
|
||||
flare.QueueActivity(new Wait(info.FlareTime));
|
||||
flare.QueueActivity(new RemoveSelf());
|
||||
}) : null;
|
||||
|
||||
if (flare != null)
|
||||
{
|
||||
flare.QueueActivity(new Wait(info.FlareTime));
|
||||
flare.QueueActivity(new RemoveSelf());
|
||||
}
|
||||
|
||||
var a = w.CreateActor(info.UnitType, new TypeDictionary
|
||||
|
||||
@@ -46,40 +46,40 @@ namespace OpenRA.Mods.RA
|
||||
w.Add(new DelayedAction((Info as GpsPowerInfo).RevealDelay * 25,
|
||||
() => { Granted = true; RefreshGps(self); }));
|
||||
});
|
||||
}
|
||||
|
||||
public void Selling(Actor self)
|
||||
{
|
||||
DisableGps();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void Selling(Actor self)
|
||||
{
|
||||
DisableGps();
|
||||
}
|
||||
|
||||
public void Sold(Actor self) { }
|
||||
|
||||
public void Damaged(Actor self, AttackInfo e)
|
||||
{
|
||||
if (e.DamageState == DamageState.Dead)
|
||||
{
|
||||
{
|
||||
DisableGps();
|
||||
}
|
||||
}
|
||||
|
||||
void DisableGps()
|
||||
{
|
||||
Granted = false;
|
||||
RefreshGps(self);
|
||||
}
|
||||
|
||||
void DisableGps()
|
||||
{
|
||||
Granted = false;
|
||||
RefreshGps(self);
|
||||
}
|
||||
|
||||
void RefreshGps(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);
|
||||
}
|
||||
|
||||
public void StanceChanged(Actor self, Player a, Player b, Stance oldStance, Stance newStance)
|
||||
{
|
||||
RefreshGps(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);
|
||||
}
|
||||
|
||||
public void StanceChanged(Actor self, Player a, Player b, Stance oldStance, Stance newStance)
|
||||
{
|
||||
RefreshGps(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Mods.RA.Air;
|
||||
#endregion
|
||||
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Mods.RA.Activities;
|
||||
using OpenRA.Mods.RA.Air;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
@@ -22,8 +22,8 @@ namespace OpenRA.Mods.RA
|
||||
[ActorReference]
|
||||
public string UnitType = "badr";
|
||||
[ActorReference]
|
||||
public string FlareType = "flare";
|
||||
|
||||
public string FlareType = "flare";
|
||||
|
||||
public readonly int FlareTime = 25 * 60 * 2; // 2 minutes
|
||||
|
||||
public override object Create(ActorInitializer init) { return new ParatroopersPower(init.self, this); }
|
||||
@@ -45,12 +45,12 @@ namespace OpenRA.Mods.RA
|
||||
{
|
||||
new LocationInit( order.TargetLocation ),
|
||||
new OwnerInit( self.Owner ),
|
||||
}) : null;
|
||||
|
||||
if (flare != null)
|
||||
{
|
||||
flare.QueueActivity(new Wait(info.FlareTime));
|
||||
flare.QueueActivity(new RemoveSelf());
|
||||
}) : null;
|
||||
|
||||
if (flare != null)
|
||||
{
|
||||
flare.QueueActivity(new Wait(info.FlareTime));
|
||||
flare.QueueActivity(new RemoveSelf());
|
||||
}
|
||||
|
||||
var a = w.CreateActor(info.UnitType, new TypeDictionary
|
||||
|
||||
@@ -1,43 +1,43 @@
|
||||
#region Copyright & License Information
|
||||
#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.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class SupportPowerChargeBarInfo : ITraitInfo
|
||||
{
|
||||
public object Create(ActorInitializer init) { return new SupportPowerChargeBar(init.self); }
|
||||
}
|
||||
|
||||
class SupportPowerChargeBar : ISelectionBar
|
||||
{
|
||||
Actor self;
|
||||
public SupportPowerChargeBar(Actor self) { this.self = self; }
|
||||
|
||||
public float GetValue()
|
||||
{
|
||||
// only people we like should see our charge status.
|
||||
if (self.World.LocalPlayer != null && self.Owner.Stances[self.World.LocalPlayer] != Stance.Ally)
|
||||
return 0;
|
||||
|
||||
var spm = self.Owner.PlayerActor.Trait<SupportPowerManager>();
|
||||
var power = spm.GetPowersForActor(self).FirstOrDefault(sp => !sp.Disabled);
|
||||
|
||||
if (power == null) return 0;
|
||||
|
||||
return 1 - (float)power.RemainingTime / power.TotalTime;
|
||||
}
|
||||
|
||||
public Color GetColor() { return Color.Magenta; }
|
||||
}
|
||||
}
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
class SupportPowerChargeBarInfo : ITraitInfo
|
||||
{
|
||||
public object Create(ActorInitializer init) { return new SupportPowerChargeBar(init.self); }
|
||||
}
|
||||
|
||||
class SupportPowerChargeBar : ISelectionBar
|
||||
{
|
||||
Actor self;
|
||||
public SupportPowerChargeBar(Actor self) { this.self = self; }
|
||||
|
||||
public float GetValue()
|
||||
{
|
||||
// only people we like should see our charge status.
|
||||
if (self.World.LocalPlayer != null && self.Owner.Stances[self.World.LocalPlayer] != Stance.Ally)
|
||||
return 0;
|
||||
|
||||
var spm = self.Owner.PlayerActor.Trait<SupportPowerManager>();
|
||||
var power = spm.GetPowersForActor(self).FirstOrDefault(sp => !sp.Disabled);
|
||||
|
||||
if (power == null) return 0;
|
||||
|
||||
return 1 - (float)power.RemainingTime / power.TotalTime;
|
||||
}
|
||||
|
||||
public Color GetColor() { return Color.Magenta; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,11 +34,11 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
init.world.ActorAdded += ActorAdded;
|
||||
init.world.ActorRemoved += ActorRemoved;
|
||||
}
|
||||
|
||||
static string MakeKey(SupportPower sp)
|
||||
{
|
||||
return sp.Info.AllowMultiple ? sp.Info.OrderName + "_" + sp.self.ActorID : sp.Info.OrderName;
|
||||
}
|
||||
|
||||
static string MakeKey(SupportPower sp)
|
||||
{
|
||||
return sp.Info.AllowMultiple ? sp.Info.OrderName + "_" + sp.self.ActorID : sp.Info.OrderName;
|
||||
}
|
||||
|
||||
void ActorAdded(Actor a)
|
||||
@@ -47,7 +47,7 @@ namespace OpenRA.Mods.RA
|
||||
return;
|
||||
|
||||
foreach (var t in a.TraitsImplementing<SupportPower>())
|
||||
{
|
||||
{
|
||||
var key = MakeKey(t);
|
||||
|
||||
if (Powers.ContainsKey(key))
|
||||
@@ -74,7 +74,7 @@ namespace OpenRA.Mods.RA
|
||||
return;
|
||||
|
||||
foreach (var t in a.TraitsImplementing<SupportPower>())
|
||||
{
|
||||
{
|
||||
var key = MakeKey(t);
|
||||
Powers[key].Instances.Remove(t);
|
||||
if (Powers[key].Instances.Count == 0 && !Powers[key].Disabled)
|
||||
@@ -99,17 +99,17 @@ namespace OpenRA.Mods.RA
|
||||
{
|
||||
if (Powers.ContainsKey(key))
|
||||
Powers[key].Target();
|
||||
}
|
||||
|
||||
static readonly SupportPowerInstance[] NoInstances = {};
|
||||
|
||||
public IEnumerable<SupportPowerInstance> GetPowersForActor(Actor a)
|
||||
{
|
||||
if (a.Owner != self.Owner || !a.HasTrait<SupportPower>())
|
||||
return NoInstances;
|
||||
|
||||
return a.TraitsImplementing<SupportPower>()
|
||||
.Select(t => Powers[MakeKey(t)]);
|
||||
}
|
||||
|
||||
static readonly SupportPowerInstance[] NoInstances = {};
|
||||
|
||||
public IEnumerable<SupportPowerInstance> GetPowersForActor(Actor a)
|
||||
{
|
||||
if (a.Owner != self.Owner || !a.HasTrait<SupportPower>())
|
||||
return NoInstances;
|
||||
|
||||
return a.TraitsImplementing<SupportPower>()
|
||||
.Select(t => Powers[MakeKey(t)]);
|
||||
}
|
||||
|
||||
public class SupportPowerInstance
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.FileFormats;
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.RA
|
||||
@@ -22,9 +22,9 @@ namespace OpenRA.Mods.RA
|
||||
public void Tick(Actor self)
|
||||
{
|
||||
t += .25f;
|
||||
}
|
||||
|
||||
static string[] excludePalettes = { "cursor", "chrome", "colorpicker" };
|
||||
}
|
||||
|
||||
static string[] excludePalettes = { "cursor", "chrome", "colorpicker" };
|
||||
static uint[] temp = new uint[7];
|
||||
|
||||
public void AdjustPalette(Dictionary<string,Palette> palettes)
|
||||
@@ -32,15 +32,15 @@ namespace OpenRA.Mods.RA
|
||||
foreach (var pal in palettes)
|
||||
{
|
||||
if (excludePalettes.Contains(pal.Key))
|
||||
continue;
|
||||
|
||||
continue;
|
||||
|
||||
var colors = pal.Value.Values;
|
||||
var rotate = (int)t % 7;
|
||||
|
||||
for (var i = 0; i < 7; i++)
|
||||
temp[(rotate + i) % 7] = colors[0x60 + i];
|
||||
|
||||
for (var i = 0; i < 7; i++)
|
||||
for (var i = 0; i < 7; i++)
|
||||
temp[(rotate + i) % 7] = colors[0x60 + i];
|
||||
|
||||
for (var i = 0; i < 7; i++)
|
||||
pal.Value.SetColor(0x60 + i, temp[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace OpenRA.Mods.RA.Widgets.Delegates
|
||||
|
||||
widget.GetWidget<LabelWidget>("CONNECTING_DESC").GetText = () =>
|
||||
"Connecting to {0}:{1}...".F(host, port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ConnectionFailedDelegate : IWidgetDelegate
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace OpenRA.Mods.RA.Widgets.Delegates
|
||||
{
|
||||
[ObjectCreator.UseCtor]
|
||||
public DeveloperModeDelegate( [ObjectCreator.Param] World world )
|
||||
{
|
||||
{
|
||||
var devmodeBG = Widget.RootWidget.GetWidget("INGAME_ROOT").GetWidget("DEVELOPERMODE_BG");
|
||||
var devModeButton = Widget.RootWidget.GetWidget<ButtonWidget>("INGAME_DEVELOPERMODE_BUTTON");
|
||||
|
||||
@@ -65,15 +65,15 @@ namespace OpenRA.Mods.RA.Widgets.Delegates
|
||||
devmodeBG.GetWidget<CheckboxWidget>("ENABLE_TECH").OnChange += _ => Order(world, "DevEnableTech");
|
||||
|
||||
devmodeBG.GetWidget<CheckboxWidget>("UNLIMITED_POWER").BindReadOnly(devTrait, "UnlimitedPower");
|
||||
devmodeBG.GetWidget<CheckboxWidget>("UNLIMITED_POWER").OnChange += _ => Order(world, "DevUnlimitedPower");
|
||||
|
||||
devmodeBG.GetWidget<CheckboxWidget>("BUILD_ANYWHERE").BindReadOnly(devTrait, "BuildAnywhere");
|
||||
devmodeBG.GetWidget<CheckboxWidget>("UNLIMITED_POWER").OnChange += _ => Order(world, "DevUnlimitedPower");
|
||||
|
||||
devmodeBG.GetWidget<CheckboxWidget>("BUILD_ANYWHERE").BindReadOnly(devTrait, "BuildAnywhere");
|
||||
devmodeBG.GetWidget<CheckboxWidget>("BUILD_ANYWHERE").OnChange += _ => Order(world, "DevBuildAnywhere");
|
||||
|
||||
devmodeBG.GetWidget<ButtonWidget>("GIVE_EXPLORATION").OnMouseUp = mi =>
|
||||
{
|
||||
world.IssueOrder(new Order("DevGiveExploration", world.LocalPlayer.PlayerActor, false));
|
||||
return true;
|
||||
|
||||
devmodeBG.GetWidget<ButtonWidget>("GIVE_EXPLORATION").OnMouseUp = mi =>
|
||||
{
|
||||
world.IssueOrder(new Order("DevGiveExploration", world.LocalPlayer.PlayerActor, false));
|
||||
return true;
|
||||
};
|
||||
|
||||
devModeButton.IsVisible = () => { return world.LobbyInfo.GlobalSettings.AllowCheats; };
|
||||
|
||||
@@ -31,44 +31,44 @@ namespace OpenRA.Mods.RA.Widgets.Delegates
|
||||
public GameInitDelegate([ObjectCreator.Param] Widget widget)
|
||||
{
|
||||
Info = (widget as GameInitInfoWidget);
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
Game.ConnectionStateChanged += orderManager =>
|
||||
{
|
||||
Widget.CloseWindow();
|
||||
switch (orderManager.Connection.ConnectionState)
|
||||
{
|
||||
case ConnectionState.PreConnecting:
|
||||
Widget.OpenWindow("MAINMENU_BG");
|
||||
break;
|
||||
case ConnectionState.Connecting:
|
||||
Widget.OpenWindow("CONNECTING_BG",
|
||||
new Dictionary<string, object> { { "host", orderManager.Host }, { "port", orderManager.Port } });
|
||||
break;
|
||||
case ConnectionState.NotConnected:
|
||||
Widget.OpenWindow("CONNECTION_FAILED_BG",
|
||||
new Dictionary<string, object> { { "orderManager", orderManager } });
|
||||
break;
|
||||
case ConnectionState.Connected:
|
||||
var lobby = Game.OpenWindow(orderManager.world, "SERVER_LOBBY");
|
||||
lobby.GetWidget<ChatDisplayWidget>("CHAT_DISPLAY").ClearChat();
|
||||
lobby.GetWidget("CHANGEMAP_BUTTON").Visible = true;
|
||||
lobby.GetWidget("LOCKTEAMS_CHECKBOX").Visible = true;
|
||||
lobby.GetWidget("ALLOWCHEATS_CHECKBOX").Visible = true;
|
||||
lobby.GetWidget("DISCONNECT_BUTTON").Visible = true;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
if (FileSystem.Exists(Info.TestFile))
|
||||
ContinueLoading();
|
||||
else
|
||||
{
|
||||
MainMenuButtonsDelegate.DisplayModSelector();
|
||||
ShowInstallMethodDialog();
|
||||
}
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
Game.ConnectionStateChanged += orderManager =>
|
||||
{
|
||||
Widget.CloseWindow();
|
||||
switch (orderManager.Connection.ConnectionState)
|
||||
{
|
||||
case ConnectionState.PreConnecting:
|
||||
Widget.OpenWindow("MAINMENU_BG");
|
||||
break;
|
||||
case ConnectionState.Connecting:
|
||||
Widget.OpenWindow("CONNECTING_BG",
|
||||
new Dictionary<string, object> { { "host", orderManager.Host }, { "port", orderManager.Port } });
|
||||
break;
|
||||
case ConnectionState.NotConnected:
|
||||
Widget.OpenWindow("CONNECTION_FAILED_BG",
|
||||
new Dictionary<string, object> { { "orderManager", orderManager } });
|
||||
break;
|
||||
case ConnectionState.Connected:
|
||||
var lobby = Game.OpenWindow(orderManager.world, "SERVER_LOBBY");
|
||||
lobby.GetWidget<ChatDisplayWidget>("CHAT_DISPLAY").ClearChat();
|
||||
lobby.GetWidget("CHANGEMAP_BUTTON").Visible = true;
|
||||
lobby.GetWidget("LOCKTEAMS_CHECKBOX").Visible = true;
|
||||
lobby.GetWidget("ALLOWCHEATS_CHECKBOX").Visible = true;
|
||||
lobby.GetWidget("DISCONNECT_BUTTON").Visible = true;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
if (FileSystem.Exists(Info.TestFile))
|
||||
ContinueLoading();
|
||||
else
|
||||
{
|
||||
MainMenuButtonsDelegate.DisplayModSelector();
|
||||
ShowInstallMethodDialog();
|
||||
}
|
||||
}
|
||||
|
||||
void ShowInstallMethodDialog()
|
||||
@@ -116,8 +116,8 @@ namespace OpenRA.Mods.RA.Widgets.Delegates
|
||||
};
|
||||
|
||||
Action onComplete = () =>
|
||||
{
|
||||
if (!error)
|
||||
{
|
||||
if (!error)
|
||||
Game.RunAfterTick(ContinueLoading);
|
||||
};
|
||||
|
||||
@@ -221,6 +221,6 @@ namespace OpenRA.Mods.RA.Widgets.Delegates
|
||||
wc.CancelAsync();
|
||||
cancelled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,15 +112,15 @@ namespace OpenRA.Mods.RA.Widgets.Delegates
|
||||
if (Game.IsHost)
|
||||
orderManager.IssueOrder(Order.Command(
|
||||
"lockteams {0}".F(!orderManager.LobbyInfo.GlobalSettings.LockTeams)));
|
||||
};
|
||||
|
||||
var allowCheats = lobby.GetWidget<CheckboxWidget>("ALLOWCHEATS_CHECKBOX");
|
||||
allowCheats.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats;
|
||||
allowCheats.OnChange += _ =>
|
||||
{
|
||||
if (Game.IsHost)
|
||||
orderManager.IssueOrder(Order.Command(
|
||||
"allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats)));
|
||||
};
|
||||
|
||||
var allowCheats = lobby.GetWidget<CheckboxWidget>("ALLOWCHEATS_CHECKBOX");
|
||||
allowCheats.IsChecked = () => orderManager.LobbyInfo.GlobalSettings.AllowCheats;
|
||||
allowCheats.OnChange += _ =>
|
||||
{
|
||||
if (Game.IsHost)
|
||||
orderManager.IssueOrder(Order.Command(
|
||||
"allowcheats {0}".F(!orderManager.LobbyInfo.GlobalSettings.AllowCheats)));
|
||||
};
|
||||
|
||||
var startGameButton = lobby.GetWidget("START_GAME_BUTTON");
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Server;
|
||||
@@ -185,25 +185,25 @@ namespace OpenRA.Mods.RA.Widgets.Delegates
|
||||
{
|
||||
var dc = widget.GetWidget("DIRECTCONNECT_BG");
|
||||
|
||||
dc.GetWidget<TextFieldWidget>("SERVER_ADDRESS").Text = Game.Settings.Player.LastServer;
|
||||
|
||||
dc.GetWidget("JOIN_BUTTON").OnMouseUp = mi =>
|
||||
{
|
||||
var address = dc.GetWidget<TextFieldWidget>("SERVER_ADDRESS").Text;
|
||||
var cpts = address.Split(':').ToArray();
|
||||
if (cpts.Length < 1 || cpts.Length > 2)
|
||||
return true;
|
||||
|
||||
int port;
|
||||
if (cpts.Length != 2 || !int.TryParse(cpts[1], out port))
|
||||
port = 1234;
|
||||
|
||||
Game.Settings.Player.LastServer = address;
|
||||
Game.Settings.Save();
|
||||
|
||||
Widget.CloseWindow();
|
||||
Game.JoinServer(cpts[0], port);
|
||||
return true;
|
||||
dc.GetWidget<TextFieldWidget>("SERVER_ADDRESS").Text = Game.Settings.Player.LastServer;
|
||||
|
||||
dc.GetWidget("JOIN_BUTTON").OnMouseUp = mi =>
|
||||
{
|
||||
var address = dc.GetWidget<TextFieldWidget>("SERVER_ADDRESS").Text;
|
||||
var cpts = address.Split(':').ToArray();
|
||||
if (cpts.Length < 1 || cpts.Length > 2)
|
||||
return true;
|
||||
|
||||
int port;
|
||||
if (cpts.Length != 2 || !int.TryParse(cpts[1], out port))
|
||||
port = 1234;
|
||||
|
||||
Game.Settings.Player.LastServer = address;
|
||||
Game.Settings.Save();
|
||||
|
||||
Widget.CloseWindow();
|
||||
Game.JoinServer(cpts[0], port);
|
||||
return true;
|
||||
};
|
||||
|
||||
dc.GetWidget("CANCEL_BUTTON").OnMouseUp = mi =>
|
||||
|
||||
@@ -164,9 +164,9 @@ namespace OpenRA.Mods.RA.Widgets
|
||||
|
||||
int updateTicks = 0;
|
||||
public override void Tick()
|
||||
{
|
||||
var hasRadarNew = world
|
||||
.ActorsWithTrait<ProvidesRadar>()
|
||||
{
|
||||
var hasRadarNew = world
|
||||
.ActorsWithTrait<ProvidesRadar>()
|
||||
.Any(a => a.Actor.Owner == world.LocalPlayer && a.Trait.IsActive);
|
||||
|
||||
if (hasRadarNew != hasRadar)
|
||||
|
||||
@@ -1,123 +1,133 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Widgets;
|
||||
|
||||
namespace OpenRA.Mods.RA.Widgets
|
||||
{
|
||||
public class StrategicProgressWidget : Widget
|
||||
{
|
||||
bool Initialised = false;
|
||||
readonly World world;
|
||||
readonly WorldRenderer worldRenderer;
|
||||
[ObjectCreator.UseCtor]
|
||||
public StrategicProgressWidget([ObjectCreator.Param] World world, [ObjectCreator.Param] WorldRenderer worldRenderer)
|
||||
{
|
||||
IsVisible = () => true;
|
||||
this.world = world;
|
||||
this.worldRenderer = worldRenderer;
|
||||
}
|
||||
|
||||
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;
|
||||
int curX = -(totalWidth / 2);
|
||||
|
||||
foreach (var a in world.Actors.Where(a => !a.Destroyed && a.HasTrait<StrategicPoint>() && !a.TraitOrDefault<StrategicPoint>().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))
|
||||
WidgetUtils.DrawRGBA(ChromeProvider.GetImage("strategic", "player_owned"), offset + new float2(RenderBounds.Left + curX, RenderBounds.Top));
|
||||
else if (!a.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))
|
||||
{
|
||||
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))
|
||||
WidgetUtils.DrawRGBA(ChromeProvider.GetImage("strategic", "player_owned"), offset + new float2(RenderBounds.Left + curX, RenderBounds.Top));
|
||||
else if (!a.Owner.NonCombatant)
|
||||
WidgetUtils.DrawRGBA(ChromeProvider.GetImage("strategic", "enemy_owned"), offset + new float2(RenderBounds.Left + curX, RenderBounds.Top));
|
||||
|
||||
curX += 32;
|
||||
}
|
||||
offset += new int2(0, 32);
|
||||
|
||||
var pendingWinner = FindFirstWinningPlayer(world);
|
||||
if (pendingWinner == null) return;
|
||||
svc = pendingWinner.PlayerActor.TraitOrDefault<StrategicVictoryConditions>();
|
||||
|
||||
if (world.LocalPlayer != null)
|
||||
{
|
||||
var tc = "";
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Player FindFirstWinningPlayer(World world)
|
||||
{
|
||||
// loop through all players, see who is 'winning' and get the one with the shortest 'time to win'
|
||||
int shortest = int.MaxValue;
|
||||
Player shortestPlayer = null;
|
||||
|
||||
foreach (var p in world.players.Select(p => p.Value).Where(p => !p.NonCombatant))
|
||||
{
|
||||
var svc = p.PlayerActor.TraitOrDefault<StrategicVictoryConditions>();
|
||||
|
||||
if (svc.HoldingCritical && svc.CriticalTicksLeft > 0 && svc.CriticalTicksLeft < shortest)
|
||||
{
|
||||
shortest = svc.CriticalTicksLeft;
|
||||
shortestPlayer = p;
|
||||
}
|
||||
|
||||
if (svc.Holding && svc.TicksLeft > 0 && svc.TicksLeft < shortest)
|
||||
{
|
||||
shortest = svc.TicksLeft;
|
||||
shortestPlayer = p;
|
||||
}
|
||||
}
|
||||
|
||||
return shortestPlayer;
|
||||
}
|
||||
|
||||
private void Init()
|
||||
{
|
||||
IsVisible = () => (world.Actors.Where(a => a.HasTrait<StrategicVictoryConditions>()).Any() && world.Actors.Where(a => a.HasTrait<StrategicPoint>()).Any());
|
||||
Initialised = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#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 System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Traits;
|
||||
using OpenRA.Widgets;
|
||||
|
||||
namespace OpenRA.Mods.RA.Widgets
|
||||
{
|
||||
public class StrategicProgressWidget : Widget
|
||||
{
|
||||
bool Initialised = false;
|
||||
readonly World world;
|
||||
readonly WorldRenderer worldRenderer;
|
||||
[ObjectCreator.UseCtor]
|
||||
public StrategicProgressWidget([ObjectCreator.Param] World world, [ObjectCreator.Param] WorldRenderer worldRenderer)
|
||||
{
|
||||
IsVisible = () => true;
|
||||
this.world = world;
|
||||
this.worldRenderer = worldRenderer;
|
||||
}
|
||||
|
||||
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;
|
||||
int curX = -(totalWidth / 2);
|
||||
|
||||
foreach (var a in world.Actors.Where(a => !a.Destroyed && a.HasTrait<StrategicPoint>() && !a.TraitOrDefault<StrategicPoint>().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))
|
||||
WidgetUtils.DrawRGBA(ChromeProvider.GetImage("strategic", "player_owned"), offset + new float2(RenderBounds.Left + curX, RenderBounds.Top));
|
||||
else if (!a.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))
|
||||
{
|
||||
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))
|
||||
WidgetUtils.DrawRGBA(ChromeProvider.GetImage("strategic", "player_owned"), offset + new float2(RenderBounds.Left + curX, RenderBounds.Top));
|
||||
else if (!a.Owner.NonCombatant)
|
||||
WidgetUtils.DrawRGBA(ChromeProvider.GetImage("strategic", "enemy_owned"), offset + new float2(RenderBounds.Left + curX, RenderBounds.Top));
|
||||
|
||||
curX += 32;
|
||||
}
|
||||
offset += new int2(0, 32);
|
||||
|
||||
var pendingWinner = FindFirstWinningPlayer(world);
|
||||
if (pendingWinner == null) return;
|
||||
svc = pendingWinner.PlayerActor.TraitOrDefault<StrategicVictoryConditions>();
|
||||
|
||||
if (world.LocalPlayer != null)
|
||||
{
|
||||
var tc = "";
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Player FindFirstWinningPlayer(World world)
|
||||
{
|
||||
// loop through all players, see who is 'winning' and get the one with the shortest 'time to win'
|
||||
int shortest = int.MaxValue;
|
||||
Player shortestPlayer = null;
|
||||
|
||||
foreach (var p in world.players.Select(p => p.Value).Where(p => !p.NonCombatant))
|
||||
{
|
||||
var svc = p.PlayerActor.TraitOrDefault<StrategicVictoryConditions>();
|
||||
|
||||
if (svc.HoldingCritical && svc.CriticalTicksLeft > 0 && svc.CriticalTicksLeft < shortest)
|
||||
{
|
||||
shortest = svc.CriticalTicksLeft;
|
||||
shortestPlayer = p;
|
||||
}
|
||||
|
||||
if (svc.Holding && svc.TicksLeft > 0 && svc.TicksLeft < shortest)
|
||||
{
|
||||
shortest = svc.TicksLeft;
|
||||
shortestPlayer = p;
|
||||
}
|
||||
}
|
||||
|
||||
return shortestPlayer;
|
||||
}
|
||||
|
||||
private void Init()
|
||||
{
|
||||
IsVisible = () => (world.Actors.Where(a => a.HasTrait<StrategicVictoryConditions>()).Any() && world.Actors.Where(a => a.HasTrait<StrategicPoint>()).Any());
|
||||
Initialised = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,123 +1,133 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Network;
|
||||
using OpenRA.Orders;
|
||||
using OpenRA.Widgets;
|
||||
|
||||
namespace OpenRA.Mods.RA.Widgets
|
||||
{
|
||||
public class WorldCommandWidget : Widget
|
||||
{
|
||||
public World World { get { return OrderManager.world; } }
|
||||
|
||||
public string AttackMoveKey = "a";
|
||||
public string StopKey = "s";
|
||||
public string ScatterKey = "x";
|
||||
public string DeployKey = "f";
|
||||
public string BaseCycleKey = "backspace";
|
||||
public readonly OrderManager OrderManager;
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public WorldCommandWidget([ObjectCreator.Param] OrderManager orderManager )
|
||||
{
|
||||
OrderManager = orderManager;
|
||||
}
|
||||
|
||||
public override void DrawInner() { }
|
||||
|
||||
public override string GetCursor(int2 pos) { return null; }
|
||||
|
||||
public override bool HandleKeyPressInner(KeyInput e)
|
||||
{
|
||||
if (World == null) return false;
|
||||
if (World.LocalPlayer == null) return false;
|
||||
|
||||
return ProcessInput(e);
|
||||
}
|
||||
|
||||
bool ProcessInput(KeyInput e)
|
||||
{
|
||||
if (e.Modifiers == Modifiers.None && e.Event == KeyInputEvent.Down)
|
||||
{
|
||||
if (e.KeyName == BaseCycleKey)
|
||||
return CycleBases();
|
||||
|
||||
if (!World.Selection.Actors.Any())
|
||||
return false;
|
||||
|
||||
if (e.KeyName == AttackMoveKey)
|
||||
return PerformAttackMove();
|
||||
|
||||
if (e.KeyName == StopKey)
|
||||
return PerformStop();
|
||||
|
||||
if (e.KeyName == ScatterKey)
|
||||
return PerformScatter();
|
||||
|
||||
if (e.KeyName == DeployKey)
|
||||
return PerformDeploy();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// todo: take ALL this garbage and route it through the OrderTargeter stuff.
|
||||
|
||||
bool PerformAttackMove()
|
||||
{
|
||||
World.OrderGenerator = new GenericSelectTarget(World.Selection.Actors, "AttackMove",
|
||||
"attackmove", MouseButton.Right);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PerformKeyboardOrderOnSelection(Func<Actor, Order> f)
|
||||
{
|
||||
var orders = World.Selection.Actors.Select(f).ToArray();
|
||||
foreach (var o in orders) World.IssueOrder(o);
|
||||
World.PlayVoiceForOrders(orders);
|
||||
}
|
||||
|
||||
bool PerformStop()
|
||||
{
|
||||
PerformKeyboardOrderOnSelection(a => new Order("Stop", a, false));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PerformScatter()
|
||||
{
|
||||
PerformKeyboardOrderOnSelection(a => new Order("Scatter", a, false));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PerformDeploy()
|
||||
{
|
||||
/* hack: two orders here -- DeployTransform and Unload. */
|
||||
PerformKeyboardOrderOnSelection(a => new Order("DeployTransform", a, false));
|
||||
PerformKeyboardOrderOnSelection(a => new Order("Unload", a, false));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CycleBases()
|
||||
{
|
||||
var bases = World.ActorsWithTrait<BaseBuilding>()
|
||||
.Where( a => a.Actor.Owner == World.LocalPlayer ).ToArray();
|
||||
if (!bases.Any()) return true;
|
||||
|
||||
var next = bases
|
||||
.Select(b => b.Actor)
|
||||
.SkipWhile(b => !World.Selection.Actors.Contains(b))
|
||||
.Skip(1)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (next == null)
|
||||
next = bases.Select(b => b.Actor).First();
|
||||
|
||||
World.Selection.Combine(World, new Actor[] { next }, false, true);
|
||||
Game.viewport.Center(World.Selection.Actors);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#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 System.Linq;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Network;
|
||||
using OpenRA.Orders;
|
||||
using OpenRA.Widgets;
|
||||
|
||||
namespace OpenRA.Mods.RA.Widgets
|
||||
{
|
||||
public class WorldCommandWidget : Widget
|
||||
{
|
||||
public World World { get { return OrderManager.world; } }
|
||||
|
||||
public string AttackMoveKey = "a";
|
||||
public string StopKey = "s";
|
||||
public string ScatterKey = "x";
|
||||
public string DeployKey = "f";
|
||||
public string BaseCycleKey = "backspace";
|
||||
public readonly OrderManager OrderManager;
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public WorldCommandWidget([ObjectCreator.Param] OrderManager orderManager )
|
||||
{
|
||||
OrderManager = orderManager;
|
||||
}
|
||||
|
||||
public override void DrawInner() { }
|
||||
|
||||
public override string GetCursor(int2 pos) { return null; }
|
||||
|
||||
public override bool HandleKeyPressInner(KeyInput e)
|
||||
{
|
||||
if (World == null) return false;
|
||||
if (World.LocalPlayer == null) return false;
|
||||
|
||||
return ProcessInput(e);
|
||||
}
|
||||
|
||||
bool ProcessInput(KeyInput e)
|
||||
{
|
||||
if (e.Modifiers == Modifiers.None && e.Event == KeyInputEvent.Down)
|
||||
{
|
||||
if (e.KeyName == BaseCycleKey)
|
||||
return CycleBases();
|
||||
|
||||
if (!World.Selection.Actors.Any())
|
||||
return false;
|
||||
|
||||
if (e.KeyName == AttackMoveKey)
|
||||
return PerformAttackMove();
|
||||
|
||||
if (e.KeyName == StopKey)
|
||||
return PerformStop();
|
||||
|
||||
if (e.KeyName == ScatterKey)
|
||||
return PerformScatter();
|
||||
|
||||
if (e.KeyName == DeployKey)
|
||||
return PerformDeploy();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// todo: take ALL this garbage and route it through the OrderTargeter stuff.
|
||||
|
||||
bool PerformAttackMove()
|
||||
{
|
||||
World.OrderGenerator = new GenericSelectTarget(World.Selection.Actors, "AttackMove",
|
||||
"attackmove", MouseButton.Right);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PerformKeyboardOrderOnSelection(Func<Actor, Order> f)
|
||||
{
|
||||
var orders = World.Selection.Actors.Select(f).ToArray();
|
||||
foreach (var o in orders) World.IssueOrder(o);
|
||||
World.PlayVoiceForOrders(orders);
|
||||
}
|
||||
|
||||
bool PerformStop()
|
||||
{
|
||||
PerformKeyboardOrderOnSelection(a => new Order("Stop", a, false));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PerformScatter()
|
||||
{
|
||||
PerformKeyboardOrderOnSelection(a => new Order("Scatter", a, false));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PerformDeploy()
|
||||
{
|
||||
/* hack: two orders here -- DeployTransform and Unload. */
|
||||
PerformKeyboardOrderOnSelection(a => new Order("DeployTransform", a, false));
|
||||
PerformKeyboardOrderOnSelection(a => new Order("Unload", a, false));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CycleBases()
|
||||
{
|
||||
var bases = World.ActorsWithTrait<BaseBuilding>()
|
||||
.Where( a => a.Actor.Owner == World.LocalPlayer ).ToArray();
|
||||
if (!bases.Any()) return true;
|
||||
|
||||
var next = bases
|
||||
.Select(b => b.Actor)
|
||||
.SkipWhile(b => !World.Selection.Actors.Contains(b))
|
||||
.Skip(1)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (next == null)
|
||||
next = bases.Select(b => b.Actor).First();
|
||||
|
||||
World.Selection.Combine(World, new Actor[] { next }, false, true);
|
||||
Game.viewport.Center(World.Selection.Actors);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user