Fixed RepairBridgeOrderTargeter & hut logic - it now ignores dangling bridges & rejects bridges under repair
Closes #4354
This commit is contained in:
@@ -80,10 +80,12 @@ namespace OpenRA.Mods.RA
|
|||||||
readonly BridgeInfo info;
|
readonly BridgeInfo info;
|
||||||
readonly string type;
|
readonly string type;
|
||||||
|
|
||||||
|
readonly Lazy<bool> isDangling;
|
||||||
ushort template;
|
ushort template;
|
||||||
Dictionary<CPos, byte> footprint;
|
Dictionary<CPos, byte> footprint;
|
||||||
|
|
||||||
public BridgeHut Hut { get; internal set; }
|
public BridgeHut Hut { get; private set; }
|
||||||
|
public bool IsDangling { get { return isDangling.Value; } }
|
||||||
|
|
||||||
public Bridge(Actor self, BridgeInfo info)
|
public Bridge(Actor self, BridgeInfo info)
|
||||||
{
|
{
|
||||||
@@ -92,6 +94,7 @@ namespace OpenRA.Mods.RA
|
|||||||
health.RemoveOnDeath = false;
|
health.RemoveOnDeath = false;
|
||||||
this.info = info;
|
this.info = info;
|
||||||
type = self.Info.Name;
|
type = self.Info.Name;
|
||||||
|
isDangling = new Lazy<bool>(() => huts[0] == huts[1] && (neighbours[0] == null || neighbours[1] == null));
|
||||||
building = self.Trait<Building>();
|
building = self.Trait<Building>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,18 +147,24 @@ namespace OpenRA.Mods.RA
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BridgeHut GetHut(int index)
|
internal void AddHut(BridgeHut hut)
|
||||||
{
|
{
|
||||||
if (huts[index] != null)
|
if (huts[0] == huts[1])
|
||||||
return huts[index]; // Already found
|
huts[1] = hut;
|
||||||
|
if (Hut == null)
|
||||||
var n = neighbours[index];
|
{
|
||||||
if (n == null)
|
Hut = hut; // Assume only one until called again
|
||||||
return huts[index] = Hut; // End piece
|
if (huts[0] == null)
|
||||||
|
huts[0] = hut; // Set only first time
|
||||||
return huts[index] = n.Hut ?? n.GetHut(index);
|
for (var d = 0; d <= 1; d++)
|
||||||
|
for (var b = neighbours[d]; b != null; b = b.Hut == null ? b.neighbours[d] : null)
|
||||||
|
b.huts[1 - d] = hut;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Hut = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BridgeHut GetHut(int index) { return huts[index]; }
|
||||||
public Bridge GetNeighbor(int[] offset, BridgeLayer bridges)
|
public Bridge GetNeighbor(int[] offset, BridgeLayer bridges)
|
||||||
{
|
{
|
||||||
if (offset == null)
|
if (offset == null)
|
||||||
@@ -309,7 +318,7 @@ namespace OpenRA.Mods.RA
|
|||||||
{
|
{
|
||||||
if (b.health.DamageState > damage)
|
if (b.health.DamageState > damage)
|
||||||
damage = b.health.DamageState;
|
damage = b.health.DamageState;
|
||||||
if (b.Hut == null && b.neighbours[d] != null)
|
if (b.Hut == null && d >= 0 && b.neighbours[d] != null)
|
||||||
AggregateDamageState(b.neighbours[d], d, ref damage);
|
AggregateDamageState(b.neighbours[d], d, ref damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,18 +23,17 @@ namespace OpenRA.Mods.RA
|
|||||||
|
|
||||||
class BridgeHut : IDemolishable
|
class BridgeHut : IDemolishable
|
||||||
{
|
{
|
||||||
Lazy<Bridge> firstBridge;
|
public readonly Bridge FirstBridge;
|
||||||
int repairDirections = 0;
|
|
||||||
public readonly Bridge Bridge;
|
public readonly Bridge Bridge;
|
||||||
public Bridge FirstBridge { get { return firstBridge.Value; } }
|
|
||||||
public DamageState BridgeDamageState { get { return Bridge.AggregateDamageState(); } }
|
public DamageState BridgeDamageState { get { return Bridge.AggregateDamageState(); } }
|
||||||
public bool Repairing { get { return repairDirections > 0; } }
|
public bool Repairing { get { return repairDirections > 0; } }
|
||||||
|
int repairDirections = 0;
|
||||||
|
|
||||||
public BridgeHut(ActorInitializer init)
|
public BridgeHut(ActorInitializer init)
|
||||||
{
|
{
|
||||||
Bridge = init.Get<ParentActorInit>().value.Trait<Bridge>();
|
Bridge = init.Get<ParentActorInit>().value.Trait<Bridge>();
|
||||||
Bridge.Hut = this;
|
Bridge.AddHut(this);
|
||||||
firstBridge = new Lazy<Bridge>(() => Bridge.Enumerate(0, true).Last());
|
FirstBridge = Bridge.Enumerate(0, true).Last();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Repair(Actor repairer)
|
public void Repair(Actor repairer)
|
||||||
|
|||||||
@@ -38,22 +38,22 @@ namespace OpenRA.Mods.RA
|
|||||||
if (order.OrderString != "RepairBridge")
|
if (order.OrderString != "RepairBridge")
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var bridge = order.TargetActor.TraitOrDefault<BridgeHut>();
|
var hut = order.TargetActor.TraitOrDefault<BridgeHut>();
|
||||||
if (bridge == null)
|
if (hut == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return bridge.BridgeDamageState > DamageState.Undamaged ? "Attack" : null;
|
return hut.BridgeDamageState == DamageState.Undamaged || hut.Repairing || hut.Bridge.IsDangling ? null : "Attack";
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResolveOrder(Actor self, Order order)
|
public void ResolveOrder(Actor self, Order order)
|
||||||
{
|
{
|
||||||
if (order.OrderString == "RepairBridge")
|
if (order.OrderString == "RepairBridge")
|
||||||
{
|
{
|
||||||
var bridge = order.TargetActor.TraitOrDefault<BridgeHut>();
|
var hut = order.TargetActor.TraitOrDefault<BridgeHut>();
|
||||||
if (bridge == null)
|
if (hut == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (bridge.BridgeDamageState == DamageState.Undamaged)
|
if (hut.BridgeDamageState == DamageState.Undamaged || hut.Repairing || hut.Bridge.IsDangling)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
self.SetTargetLine(Target.FromOrder(self.World, order), Color.Yellow);
|
self.SetTargetLine(Target.FromOrder(self.World, order), Color.Yellow);
|
||||||
@@ -70,12 +70,12 @@ namespace OpenRA.Mods.RA
|
|||||||
|
|
||||||
public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
|
public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
|
||||||
{
|
{
|
||||||
var bridge = target.TraitOrDefault<BridgeHut>();
|
var hut = target.TraitOrDefault<BridgeHut>();
|
||||||
if (bridge == null)
|
if (hut == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Require force attack to heal partially damaged bridges to avoid unnecessary cursor noise
|
// Require force attack to heal partially damaged bridges to avoid unnecessary cursor noise
|
||||||
var damage = bridge.BridgeDamageState;
|
var damage = hut.BridgeDamageState;
|
||||||
if (!modifiers.HasModifier(TargetModifiers.ForceAttack) && damage != DamageState.Dead)
|
if (!modifiers.HasModifier(TargetModifiers.ForceAttack) && damage != DamageState.Dead)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -83,8 +83,8 @@ namespace OpenRA.Mods.RA
|
|||||||
if (modifiers.HasModifier(TargetModifiers.ForceMove))
|
if (modifiers.HasModifier(TargetModifiers.ForceMove))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Can't repair an undamaged bridge
|
// Can't repair a bridge that is undamaged, already under repair, or dangling
|
||||||
if (damage == DamageState.Undamaged)
|
if (damage == DamageState.Undamaged || hut.Repairing || hut.Bridge.IsDangling)
|
||||||
cursor = "goldwrench-blocked";
|
cursor = "goldwrench-blocked";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -2240,7 +2240,6 @@ Rules:
|
|||||||
Inherits: E6
|
Inherits: E6
|
||||||
Buildable:
|
Buildable:
|
||||||
Prerequisites: ~barracks
|
Prerequisites: ~barracks
|
||||||
-RepairsBridges:
|
|
||||||
Captures:
|
Captures:
|
||||||
CaptureTypes: building
|
CaptureTypes: building
|
||||||
Sabotage: False
|
Sabotage: False
|
||||||
|
|||||||
Reference in New Issue
Block a user