Refactor AutoCarryall trait and rename to Carryall
Fixup Carryable
This commit is contained in:
@@ -72,7 +72,7 @@
|
|||||||
<Compile Include="Activities\SwallowActor.cs" />
|
<Compile Include="Activities\SwallowActor.cs" />
|
||||||
<Compile Include="SpriteLoaders\R8Loader.cs" />
|
<Compile Include="SpriteLoaders\R8Loader.cs" />
|
||||||
<Compile Include="Traits\AttackSwallow.cs" />
|
<Compile Include="Traits\AttackSwallow.cs" />
|
||||||
<Compile Include="Traits\AutoCarryall.cs" />
|
<Compile Include="Traits\Carryall.cs" />
|
||||||
<Compile Include="Traits\Buildings\ProductionFromMapEdge.cs" />
|
<Compile Include="Traits\Buildings\ProductionFromMapEdge.cs" />
|
||||||
<Compile Include="Traits\Buildings\DamagedWithoutFoundation.cs" />
|
<Compile Include="Traits\Buildings\DamagedWithoutFoundation.cs" />
|
||||||
<Compile Include="Traits\Buildings\LaysTerrain.cs" />
|
<Compile Include="Traits\Buildings\LaysTerrain.cs" />
|
||||||
|
|||||||
@@ -7,16 +7,15 @@
|
|||||||
* see COPYING.
|
* see COPYING.
|
||||||
*/
|
*/
|
||||||
#endregion
|
#endregion
|
||||||
using System;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenRA.Activities;
|
using OpenRA.Activities;
|
||||||
using OpenRA.Mods.Common.Traits;
|
using OpenRA.Mods.Common.Traits;
|
||||||
using OpenRA.Mods.D2k.Activities;
|
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
|
|
||||||
namespace OpenRA.Mods.D2k.Traits
|
namespace OpenRA.Mods.D2k.Traits
|
||||||
{
|
{
|
||||||
[Desc("Can be carried by units with the trait `AutoCarryall`.")]
|
[Desc("Can be carried by units with the trait `Carryall`.")]
|
||||||
public class CarryableInfo : ITraitInfo
|
public class CarryableInfo : ITraitInfo
|
||||||
{
|
{
|
||||||
[Desc("Required distance away from destination before requesting a pickup.")]
|
[Desc("Required distance away from destination before requesting a pickup.")]
|
||||||
@@ -32,7 +31,7 @@ namespace OpenRA.Mods.D2k.Traits
|
|||||||
|
|
||||||
public bool Reserved { get; private set; }
|
public bool Reserved { get; private set; }
|
||||||
|
|
||||||
// If we're locked there isnt much we can do. We'll have to wait for the carrier to finish with us. We should not move or get new orders!
|
// If we're locked there isn't much we can do. We'll have to wait for the carrier to finish with us. We should not move or get new orders!
|
||||||
bool locked;
|
bool locked;
|
||||||
|
|
||||||
public bool WantsTransport { get; private set; }
|
public bool WantsTransport { get; private set; }
|
||||||
@@ -62,15 +61,14 @@ namespace OpenRA.Mods.D2k.Traits
|
|||||||
|
|
||||||
Destination = destination;
|
Destination = destination;
|
||||||
this.afterLandActivity = afterLandActivity;
|
this.afterLandActivity = afterLandActivity;
|
||||||
|
WantsTransport = true;
|
||||||
|
|
||||||
if (locked || Reserved)
|
if (locked || Reserved)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
WantsTransport = true;
|
|
||||||
|
|
||||||
// Inform all idle carriers
|
// Inform all idle carriers
|
||||||
var carriers = self.World.ActorsWithTrait<AutoCarryall>()
|
var carriers = self.World.ActorsWithTrait<Carryall>()
|
||||||
.Where(c => !c.Trait.Busy && !c.Actor.IsDead && c.Actor.Owner == self.Owner)
|
.Where(c => !c.Trait.IsBusy && !c.Actor.IsDead && c.Actor.Owner == self.Owner && c.Actor.IsInWorld)
|
||||||
.OrderBy(p => (self.Location - p.Actor.Location).LengthSquared);
|
.OrderBy(p => (self.Location - p.Actor.Location).LengthSquared);
|
||||||
|
|
||||||
foreach (var carrier in carriers)
|
foreach (var carrier in carriers)
|
||||||
@@ -90,7 +88,7 @@ namespace OpenRA.Mods.D2k.Traits
|
|||||||
WantsTransport = false;
|
WantsTransport = false;
|
||||||
afterLandActivity = null;
|
afterLandActivity = null;
|
||||||
|
|
||||||
// TODO: We could implement something like a carrier.Trait<AutoCarryAll>().CancelTransportNotify(self) and call it here
|
// TODO: We could implement something like a carrier.Trait<Carryall>().CancelTransportNotify(self) and call it here
|
||||||
}
|
}
|
||||||
|
|
||||||
// We do not handle Harvested notification
|
// We do not handle Harvested notification
|
||||||
@@ -99,8 +97,8 @@ namespace OpenRA.Mods.D2k.Traits
|
|||||||
public Actor GetClosestIdleCarrier()
|
public Actor GetClosestIdleCarrier()
|
||||||
{
|
{
|
||||||
// Find carriers
|
// Find carriers
|
||||||
var carriers = self.World.ActorsWithTrait<AutoCarryall>()
|
var carriers = self.World.ActorsWithTrait<Carryall>()
|
||||||
.Where(p => p.Actor.Owner == self.Owner && !p.Trait.Busy)
|
.Where(p => p.Actor.Owner == self.Owner && !p.Trait.IsBusy && p.Actor.IsInWorld)
|
||||||
.Select(h => h.Actor);
|
.Select(h => h.Actor);
|
||||||
|
|
||||||
return WorldUtils.ClosestTo(carriers, self);
|
return WorldUtils.ClosestTo(carriers, self);
|
||||||
|
|||||||
@@ -7,57 +7,63 @@
|
|||||||
* see COPYING.
|
* see COPYING.
|
||||||
*/
|
*/
|
||||||
#endregion
|
#endregion
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenRA.Graphics;
|
using OpenRA.Graphics;
|
||||||
using OpenRA.Mods.Common.Activities;
|
using OpenRA.Mods.Common.Activities;
|
||||||
using OpenRA.Mods.Common.Traits;
|
using OpenRA.Mods.Common.Traits;
|
||||||
using OpenRA.Mods.D2k.Activities;
|
|
||||||
using OpenRA.Mods.RA;
|
|
||||||
using OpenRA.Mods.RA.Traits;
|
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
|
|
||||||
namespace OpenRA.Mods.D2k.Traits
|
namespace OpenRA.Mods.D2k.Traits
|
||||||
{
|
{
|
||||||
[Desc("Automatically transports harvesters with the Carryable trait between resource fields and refineries")]
|
[Desc("Automatically transports harvesters with the Carryable trait between resource fields and refineries.")]
|
||||||
public class AutoCarryallInfo : ITraitInfo, Requires<IBodyOrientationInfo>
|
public class CarryallInfo : ITraitInfo, Requires<IBodyOrientationInfo>
|
||||||
{
|
{
|
||||||
public object Create(ActorInitializer init) { return new AutoCarryall(init.Self, this); }
|
[Desc("Set to false when the carryall should not automatically get new jobs.")]
|
||||||
|
public readonly bool Automatic = true;
|
||||||
|
|
||||||
|
public object Create(ActorInitializer init) { return new Carryall(init.Self, this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AutoCarryall : INotifyBecomingIdle, INotifyKilled, ISync, IRender
|
public class Carryall : INotifyBecomingIdle, INotifyKilled, ISync, IRender
|
||||||
{
|
{
|
||||||
readonly Actor self;
|
readonly Actor self;
|
||||||
readonly WRange carryHeight;
|
readonly WRange carryHeight;
|
||||||
|
readonly CarryallInfo info;
|
||||||
|
|
||||||
// The actor we are currently carrying.
|
// The actor we are currently carrying.
|
||||||
[Sync] Actor carrying;
|
[Sync] public Actor Carrying { get; internal set; }
|
||||||
bool isCarrying;
|
public bool IsCarrying { get; internal set; }
|
||||||
|
|
||||||
// TODO: Use ActorPreviews so that this can support actors with multiple sprites
|
// TODO: Use ActorPreviews so that this can support actors with multiple sprites
|
||||||
Animation anim;
|
Animation anim;
|
||||||
|
|
||||||
public bool Busy { get; internal set; }
|
public bool IsBusy { get; internal set; }
|
||||||
|
|
||||||
public AutoCarryall(Actor self, AutoCarryallInfo info)
|
public Carryall(Actor self, CarryallInfo info)
|
||||||
{
|
{
|
||||||
this.self = self;
|
this.self = self;
|
||||||
|
this.info = info;
|
||||||
|
|
||||||
|
IsBusy = false;
|
||||||
|
IsCarrying = false;
|
||||||
carryHeight = self.Trait<Helicopter>().Info.LandAltitude;
|
carryHeight = self.Trait<Helicopter>().Info.LandAltitude;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnBecomingIdle(Actor self)
|
public void OnBecomingIdle(Actor self)
|
||||||
{
|
{
|
||||||
FindCarryableForTransport();
|
if (info.Automatic)
|
||||||
|
FindCarryableForTransport();
|
||||||
|
|
||||||
if (!Busy)
|
if (!IsBusy)
|
||||||
self.QueueActivity(new HeliFlyCircle(self));
|
self.QueueActivity(new HeliFlyCircle(self));
|
||||||
}
|
}
|
||||||
|
|
||||||
// A carryable notifying us that he'd like to be carried
|
// A carryable notifying us that he'd like to be carried
|
||||||
public bool RequestTransportNotify(Actor carryable)
|
public bool RequestTransportNotify(Actor carryable)
|
||||||
{
|
{
|
||||||
if (Busy)
|
if (IsBusy || !info.Automatic)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (ReserveCarryable(carryable))
|
if (ReserveCarryable(carryable))
|
||||||
@@ -71,29 +77,32 @@ namespace OpenRA.Mods.D2k.Traits
|
|||||||
|
|
||||||
void FindCarryableForTransport()
|
void FindCarryableForTransport()
|
||||||
{
|
{
|
||||||
// get all carryables who want transport
|
if (!self.IsInWorld)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Get all carryables who want transport
|
||||||
var carryables = self.World.ActorsWithTrait<Carryable>()
|
var carryables = self.World.ActorsWithTrait<Carryable>()
|
||||||
.Where(p =>
|
.Where(p =>
|
||||||
{
|
{
|
||||||
var actor = p.Actor;
|
var actor = p.Actor;
|
||||||
if (actor == null)
|
if (actor == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (actor.Owner != self.Owner)
|
if (actor.Owner != self.Owner)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (actor.IsDead)
|
if (actor.IsDead)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var trait = p.Trait;
|
var trait = p.Trait;
|
||||||
if (trait.Reserved)
|
if (trait.Reserved)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!trait.WantsTransport)
|
if (!trait.WantsTransport)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
.OrderBy(p => (self.Location - p.Actor.Location).LengthSquared);
|
.OrderBy(p => (self.Location - p.Actor.Location).LengthSquared);
|
||||||
|
|
||||||
foreach (var p in carryables)
|
foreach (var p in carryables)
|
||||||
@@ -112,8 +121,8 @@ namespace OpenRA.Mods.D2k.Traits
|
|||||||
{
|
{
|
||||||
if (carryable.Trait<Carryable>().Reserve(self))
|
if (carryable.Trait<Carryable>().Reserve(self))
|
||||||
{
|
{
|
||||||
carrying = carryable;
|
Carrying = carryable;
|
||||||
Busy = true;
|
IsBusy = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,24 +132,26 @@ namespace OpenRA.Mods.D2k.Traits
|
|||||||
// Unreserve the carryable
|
// Unreserve the carryable
|
||||||
public void UnreserveCarryable()
|
public void UnreserveCarryable()
|
||||||
{
|
{
|
||||||
if (carrying != null)
|
if (Carrying != null)
|
||||||
{
|
{
|
||||||
if (carrying.IsInWorld && !carrying.IsDead)
|
if (Carrying.IsInWorld && !Carrying.IsDead)
|
||||||
carrying.Trait<Carryable>().UnReserve(self);
|
Carrying.Trait<Carryable>().UnReserve(self);
|
||||||
|
|
||||||
carrying = null;
|
Carrying = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Busy = false;
|
IsBusy = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// INotifyKilled
|
// INotifyKilled
|
||||||
public void Killed(Actor self, AttackInfo e)
|
public void Killed(Actor self, AttackInfo e)
|
||||||
{
|
{
|
||||||
if (carrying != null)
|
if (Carrying != null)
|
||||||
{
|
{
|
||||||
if (isCarrying && carrying.IsInWorld && !carrying.IsDead)
|
if (IsCarrying && Carrying.IsInWorld && !Carrying.IsDead)
|
||||||
carrying.Kill(e.Attacker);
|
Carrying.Kill(e.Attacker);
|
||||||
|
|
||||||
|
Carrying = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
UnreserveCarryable();
|
UnreserveCarryable();
|
||||||
@@ -149,7 +160,9 @@ namespace OpenRA.Mods.D2k.Traits
|
|||||||
// Called when carryable is inside.
|
// Called when carryable is inside.
|
||||||
public void AttachCarryable(Actor carryable)
|
public void AttachCarryable(Actor carryable)
|
||||||
{
|
{
|
||||||
isCarrying = true;
|
IsBusy = true;
|
||||||
|
IsCarrying = true;
|
||||||
|
Carrying = carryable;
|
||||||
|
|
||||||
// Create a new animation for our carryable unit
|
// Create a new animation for our carryable unit
|
||||||
var rs = carryable.Trait<RenderSprites>();
|
var rs = carryable.Trait<RenderSprites>();
|
||||||
@@ -161,7 +174,7 @@ namespace OpenRA.Mods.D2k.Traits
|
|||||||
// Called when released
|
// Called when released
|
||||||
public void CarryableReleased()
|
public void CarryableReleased()
|
||||||
{
|
{
|
||||||
isCarrying = false;
|
IsCarrying = false;
|
||||||
anim = null;
|
anim = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,7 +184,8 @@ namespace OpenRA.Mods.D2k.Traits
|
|||||||
if (anim != null && !self.World.FogObscures(self))
|
if (anim != null && !self.World.FogObscures(self))
|
||||||
{
|
{
|
||||||
anim.Tick();
|
anim.Tick();
|
||||||
var renderables = anim.Render(self.CenterPosition + new WVec(0, 0, -carryHeight.Range), wr.Palette("player" + carrying.Owner.InternalName));
|
var renderables = anim.Render(self.CenterPosition + new WVec(0, 0, -carryHeight.Range),
|
||||||
|
wr.Palette("player" + Carrying.Owner.InternalName));
|
||||||
|
|
||||||
foreach (var rr in renderables)
|
foreach (var rr in renderables)
|
||||||
yield return rr;
|
yield return rr;
|
||||||
@@ -29,7 +29,7 @@ carryall.scripted:
|
|||||||
|
|
||||||
carryall:
|
carryall:
|
||||||
Inherits: carryall.scripted
|
Inherits: carryall.scripted
|
||||||
AutoCarryall:
|
Carryall:
|
||||||
Buildable:
|
Buildable:
|
||||||
Queue: Aircraft
|
Queue: Aircraft
|
||||||
BuildPaletteOrder: 120
|
BuildPaletteOrder: 120
|
||||||
|
|||||||
Reference in New Issue
Block a user