78 lines
2.5 KiB
C#
78 lines
2.5 KiB
C#
#region Copyright & License Information
|
|
/*
|
|
* Copyright 2007-2019 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, either version 3 of
|
|
* the License, or (at your option) any later version. For more
|
|
* information, see COPYING.
|
|
*/
|
|
#endregion
|
|
|
|
using System;
|
|
using System.Drawing;
|
|
using OpenRA.Mods.Common.Traits;
|
|
using OpenRA.Traits;
|
|
|
|
namespace OpenRA.Mods.Common.Activities
|
|
{
|
|
class EnterTransport : Enter
|
|
{
|
|
readonly Passenger passenger;
|
|
readonly int maxTries;
|
|
Actor transport;
|
|
Cargo cargo;
|
|
|
|
public EnterTransport(Actor self, Actor transport, int maxTries = 0, bool repathWhileMoving = true)
|
|
: base(self, transport, EnterBehaviour.Exit, maxTries, repathWhileMoving, Color.Green)
|
|
{
|
|
this.transport = transport;
|
|
this.maxTries = maxTries;
|
|
cargo = transport.Trait<Cargo>();
|
|
passenger = self.Trait<Passenger>();
|
|
}
|
|
|
|
protected override void Unreserve(Actor self, bool abort) { passenger.Unreserve(self); }
|
|
protected override bool CanReserve(Actor self) { return cargo.Unloading || cargo.CanLoad(transport, self); }
|
|
protected override ReserveStatus Reserve(Actor self)
|
|
{
|
|
var status = base.Reserve(self);
|
|
if (status != ReserveStatus.Ready)
|
|
return status;
|
|
if (passenger.Reserve(self, cargo))
|
|
return ReserveStatus.Ready;
|
|
return ReserveStatus.Pending;
|
|
}
|
|
|
|
protected override void OnInside(Actor self)
|
|
{
|
|
self.World.AddFrameEndTask(w =>
|
|
{
|
|
if (self.IsDead || transport.IsDead || !cargo.CanLoad(transport, self))
|
|
return;
|
|
|
|
cargo.Load(transport, self);
|
|
w.Remove(self);
|
|
});
|
|
|
|
Done(self);
|
|
|
|
// Preemptively cancel any activities to avoid an edge-case where successively queued
|
|
// EnterTransports corrupt the actor state. Activities are cancelled again on unload
|
|
self.CancelActivity();
|
|
}
|
|
|
|
protected override bool TryGetAlternateTarget(Actor self, int tries, ref Target target)
|
|
{
|
|
if (tries > maxTries)
|
|
return false;
|
|
var type = target.Actor.Info.Name;
|
|
return TryGetAlternateTargetInCircle(
|
|
self, passenger.Info.AlternateTransportScanRange,
|
|
t => { transport = t.Actor; cargo = t.Actor.Trait<Cargo>(); }, // update transport and cargo
|
|
a => { var c = a.TraitOrDefault<Cargo>(); return c != null && c.Info.Types.Contains(passenger.Info.CargoType) && (c.Unloading || c.CanLoad(a, self)); },
|
|
new Func<Actor, bool>[] { a => a.Info.Name == type }); // Prefer transports of the same type
|
|
}
|
|
}
|
|
}
|