Merge branches 'bugfixes', 'shroud', 'cargo' and 'minimap'
This commit is contained in:
36
OpenRa.Game/Traits/Activities/EnterTransport.cs
Normal file
36
OpenRa.Game/Traits/Activities/EnterTransport.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenRa.Game.Traits.Activities
|
||||
{
|
||||
class EnterTransport : IActivity
|
||||
{
|
||||
public IActivity NextActivity { get; set; }
|
||||
bool isCanceled;
|
||||
public Actor transport;
|
||||
|
||||
public EnterTransport(Actor self, Actor transport)
|
||||
{
|
||||
this.transport = transport;
|
||||
}
|
||||
|
||||
public IActivity Tick(Actor self)
|
||||
{
|
||||
if (isCanceled) return NextActivity;
|
||||
if (transport == null || !transport.IsInWorld) return NextActivity;
|
||||
|
||||
var cargo = transport.traits.Get<Cargo>();
|
||||
if (cargo.IsFull(transport))
|
||||
return NextActivity;
|
||||
|
||||
cargo.Load(transport, self);
|
||||
Game.world.AddFrameEndTask(w => w.Remove(self));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public void Cancel(Actor self) { isCanceled = true; NextActivity = null; }
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ namespace OpenRa.Game.Traits.Activities
|
||||
{
|
||||
public IActivity NextActivity { get; set; }
|
||||
|
||||
public int desiredFacing;
|
||||
int desiredFacing;
|
||||
|
||||
public Turn( int desiredFacing )
|
||||
{
|
||||
|
||||
69
OpenRa.Game/Traits/Activities/UnloadCargo.cs
Normal file
69
OpenRa.Game/Traits/Activities/UnloadCargo.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenRa.Game.Traits.Activities
|
||||
{
|
||||
class UnloadCargo : IActivity
|
||||
{
|
||||
public IActivity NextActivity { get; set; }
|
||||
bool isCanceled;
|
||||
|
||||
int2? ChooseExitTile(Actor self)
|
||||
{
|
||||
// is anyone still hogging this tile?
|
||||
if (Game.UnitInfluence.GetUnitsAt(self.Location).Count() > 1)
|
||||
return null;
|
||||
|
||||
for (var i = -1; i < 2; i++)
|
||||
for (var j = -1; j < 2; j++)
|
||||
if ((i != 0 || j != 0) &&
|
||||
Game.IsCellBuildable(self.Location + new int2(i, j),
|
||||
UnitMovementType.Foot))
|
||||
return self.Location + new int2(i, j);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public IActivity Tick(Actor self)
|
||||
{
|
||||
if (isCanceled) return NextActivity;
|
||||
|
||||
// if we're a thing that can turn, turn to the
|
||||
// right facing for the unload animation
|
||||
var unit = self.traits.GetOrDefault<Unit>();
|
||||
if (unit != null && unit.Facing != self.Info.UnloadFacing)
|
||||
return new Turn(self.Info.UnloadFacing) { NextActivity = this };
|
||||
|
||||
// todo: handle the BS of open/close sequences, which are inconsistent,
|
||||
// for reasons that probably make good sense to the westwood guys.
|
||||
|
||||
var cargo = self.traits.Get<Cargo>();
|
||||
if (cargo.IsEmpty(self))
|
||||
return NextActivity;
|
||||
|
||||
var ru = self.traits.WithInterface<RenderUnit>().FirstOrDefault();
|
||||
if (ru != null)
|
||||
ru.PlayCustomAnimation(self, "unload", null);
|
||||
|
||||
var exitTile = ChooseExitTile(self);
|
||||
if (exitTile == null)
|
||||
return this;
|
||||
|
||||
var actor = cargo.Unload(self);
|
||||
|
||||
Game.world.AddFrameEndTask(w =>
|
||||
{
|
||||
w.Add(actor);
|
||||
actor.traits.Get<Mobile>().TeleportTo(actor, self.Location);
|
||||
actor.CancelActivity();
|
||||
actor.QueueActivity(new Move(exitTile.Value, 0));
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public void Cancel(Actor self) { NextActivity = null; isCanceled = true; }
|
||||
}
|
||||
}
|
||||
85
OpenRa.Game/Traits/Cargo.cs
Normal file
85
OpenRa.Game/Traits/Cargo.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using OpenRa.Game.GameRules;
|
||||
using OpenRa.Game.Traits.Activities;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class Cargo : IPips, IOrder
|
||||
{
|
||||
List<Actor> cargo = new List<Actor>();
|
||||
|
||||
public Cargo(Actor self) {}
|
||||
|
||||
public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor)
|
||||
{
|
||||
// todo: check if there is an unoccupied `land` tile adjacent
|
||||
if (mi.Button == MouseButton.Right && underCursor == self && cargo.Count > 0)
|
||||
{
|
||||
var unit = underCursor.traits.GetOrDefault<Unit>();
|
||||
if (unit != null && unit.Altitude > 0) return null;
|
||||
|
||||
return new Order("Deploy", self, null, int2.Zero, null);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
if (order.OrderString == "Deploy")
|
||||
{
|
||||
// todo: eject the units
|
||||
self.CancelActivity();
|
||||
self.QueueActivity(new UnloadCargo());
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsFull(Actor self)
|
||||
{
|
||||
return cargo.Count == self.Info.Passengers;
|
||||
}
|
||||
|
||||
public bool IsEmpty(Actor self)
|
||||
{
|
||||
return cargo.Count == 0;
|
||||
}
|
||||
|
||||
public Actor Unload(Actor self)
|
||||
{
|
||||
var a = cargo[0];
|
||||
cargo.RemoveAt(0);
|
||||
return a;
|
||||
}
|
||||
|
||||
public IEnumerable<PipType> GetPips( Actor self )
|
||||
{
|
||||
for (var i = 0; i < self.Info.Passengers; i++)
|
||||
if (i >= cargo.Count)
|
||||
yield return PipType.Transparent;
|
||||
else
|
||||
yield return GetPipForPassenger(cargo[i]);
|
||||
}
|
||||
|
||||
static PipType GetPipForPassenger(Actor a)
|
||||
{
|
||||
// probably not actually right yet; fix to match real-ra
|
||||
|
||||
if (a.traits.Contains<AutoHeal>())
|
||||
return PipType.Yellow;
|
||||
if (!a.traits.WithInterface<AttackBase>().Any())
|
||||
return PipType.Yellow; // noncombat [E6,SPY,THF]
|
||||
if (a.traits.Contains<C4Demolition>())
|
||||
return PipType.Red; // E7
|
||||
|
||||
return PipType.Green;
|
||||
}
|
||||
|
||||
public void Load(Actor self, Actor a)
|
||||
{
|
||||
cargo.Add(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ namespace OpenRa.Game.Traits
|
||||
}
|
||||
|
||||
// Display 5 pips indicating the current charge status
|
||||
public IEnumerable<PipType> GetPips()
|
||||
public IEnumerable<PipType> GetPips(Actor self)
|
||||
{
|
||||
const int numPips = 5;
|
||||
for (int i = 0; i < numPips; i++)
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace OpenRa.Game.Traits
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<PipType> GetPips()
|
||||
public IEnumerable<PipType> GetPips(Actor self)
|
||||
{
|
||||
const int numPips = 7;
|
||||
for (int i = 0; i < numPips; i++)
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace OpenRa.Game.Traits
|
||||
|
||||
public void Attacking(Actor self) { --ammo; }
|
||||
|
||||
public IEnumerable<PipType> GetPips()
|
||||
public IEnumerable<PipType> GetPips(Actor self)
|
||||
{
|
||||
return Graphics.Util.MakeArray(self.Info.Ammo,
|
||||
i => ammo > i ? PipType.Green : PipType.Transparent);
|
||||
|
||||
@@ -18,7 +18,16 @@ namespace OpenRa.Game.Traits
|
||||
public int2 toCell
|
||||
{
|
||||
get { return self.Location; }
|
||||
set { Game.UnitInfluence.Remove(self, this); self.Location = value; Game.UnitInfluence.Add(self, this); }
|
||||
set
|
||||
{
|
||||
if (self.Location != value)
|
||||
{
|
||||
Game.UnitInfluence.Remove(self, this);
|
||||
self.Location = value;
|
||||
self.Owner.Shroud.Explore(self);
|
||||
}
|
||||
Game.UnitInfluence.Add(self, this);
|
||||
}
|
||||
}
|
||||
|
||||
public Mobile(Actor self)
|
||||
|
||||
42
OpenRa.Game/Traits/Passenger.cs
Normal file
42
OpenRa.Game/Traits/Passenger.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using OpenRa.Game.Traits.Activities;
|
||||
|
||||
namespace OpenRa.Game.Traits
|
||||
{
|
||||
class Passenger : IOrder
|
||||
{
|
||||
public Passenger(Actor self) { }
|
||||
|
||||
public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor)
|
||||
{
|
||||
if (mi.Button != MouseButton.Right)
|
||||
return null;
|
||||
|
||||
if (underCursor == null || underCursor.Owner != self.Owner)
|
||||
return null;
|
||||
|
||||
var cargo = underCursor.traits.GetOrDefault<Cargo>();
|
||||
if (cargo == null || cargo.IsFull(underCursor))
|
||||
return null;
|
||||
|
||||
var umt = self.traits.WithInterface<IMovement>().First().GetMovementType();
|
||||
if (!underCursor.Info.PassengerTypes.Contains(umt))
|
||||
return null;
|
||||
|
||||
return new Order("EnterTransport", self, underCursor, int2.Zero, null);
|
||||
}
|
||||
|
||||
public void ResolveOrder(Actor self, Order order)
|
||||
{
|
||||
if (order.OrderString == "EnterTransport")
|
||||
{
|
||||
self.CancelActivity();
|
||||
self.QueueActivity(new Move(order.TargetActor.Location, 1));
|
||||
self.QueueActivity(new EnterTransport(self, order.TargetActor));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ namespace OpenRa.Game.Traits
|
||||
this.self = self;
|
||||
}
|
||||
|
||||
public IEnumerable<PipType> GetPips()
|
||||
public IEnumerable<PipType> GetPips(Actor self)
|
||||
{
|
||||
for (int i = 0; i < self.Info.OrePips; i++)
|
||||
{
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace OpenRa.Game.Traits
|
||||
interface IDamageModifier { float GetDamageModifier(); }
|
||||
interface ISpeedModifier { float GetSpeedModifier(); }
|
||||
interface IPaletteModifier { void AdjustPalette(Bitmap b); }
|
||||
interface IPips { IEnumerable<PipType> GetPips(); }
|
||||
interface IPips { IEnumerable<PipType> GetPips(Actor self); }
|
||||
interface ITags { IEnumerable<TagType> GetTags(); }
|
||||
interface IMovement
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user