Add an ICreationActivity interface
This commit is contained in:
@@ -82,6 +82,7 @@ namespace OpenRA
|
|||||||
readonly INotifyIdle[] tickIdles;
|
readonly INotifyIdle[] tickIdles;
|
||||||
readonly ITargetablePositions[] targetablePositions;
|
readonly ITargetablePositions[] targetablePositions;
|
||||||
WPos[] staticTargetablePositions;
|
WPos[] staticTargetablePositions;
|
||||||
|
bool created;
|
||||||
|
|
||||||
internal Actor(World world, string name, TypeDictionary initDict)
|
internal Actor(World world, string name, TypeDictionary initDict)
|
||||||
{
|
{
|
||||||
@@ -138,6 +139,35 @@ namespace OpenRA
|
|||||||
SyncHashes = TraitsImplementing<ISync>().Select(sync => new SyncHash(sync)).ToArray();
|
SyncHashes = TraitsImplementing<ISync>().Select(sync => new SyncHash(sync)).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void Created()
|
||||||
|
{
|
||||||
|
created = true;
|
||||||
|
|
||||||
|
foreach (var t in TraitsImplementing<INotifyCreated>())
|
||||||
|
t.Created(this);
|
||||||
|
|
||||||
|
// The initial activity should run before any activities queued by INotifyCreated.Created
|
||||||
|
// However, we need to know which traits are enabled (via conditions), so wait for after the calls and insert the activity as the first
|
||||||
|
ICreationActivity creationActivity = null;
|
||||||
|
foreach (var ica in TraitsImplementing<ICreationActivity>())
|
||||||
|
{
|
||||||
|
if (!ica.IsTraitEnabled())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (creationActivity != null)
|
||||||
|
throw new InvalidOperationException("More than one enabled ICreationActivity trait: {0} and {1}".F(creationActivity.GetType().Name, ica.GetType().Name));
|
||||||
|
|
||||||
|
var activity = ica.GetCreationActivity();
|
||||||
|
if (activity == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
creationActivity = ica;
|
||||||
|
|
||||||
|
activity.Queue(CurrentActivity);
|
||||||
|
CurrentActivity = activity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Tick()
|
public void Tick()
|
||||||
{
|
{
|
||||||
var wasIdle = IsIdle;
|
var wasIdle = IsIdle;
|
||||||
@@ -214,11 +244,15 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
if (!queued)
|
if (!queued)
|
||||||
CancelActivity();
|
CancelActivity();
|
||||||
|
|
||||||
QueueActivity(nextActivity);
|
QueueActivity(nextActivity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void QueueActivity(Activity nextActivity)
|
public void QueueActivity(Activity nextActivity)
|
||||||
{
|
{
|
||||||
|
if (!created)
|
||||||
|
throw new InvalidOperationException("An activity was queued before the actor was created. Queue it inside the INotifyCreated.Created callback instead.");
|
||||||
|
|
||||||
if (CurrentActivity == null)
|
if (CurrentActivity == null)
|
||||||
CurrentActivity = nextActivity;
|
CurrentActivity = nextActivity;
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using OpenRA.Activities;
|
||||||
using OpenRA.FileSystem;
|
using OpenRA.FileSystem;
|
||||||
using OpenRA.Graphics;
|
using OpenRA.Graphics;
|
||||||
using OpenRA.Network;
|
using OpenRA.Network;
|
||||||
@@ -538,4 +539,7 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
[RequireExplicitImplementation]
|
[RequireExplicitImplementation]
|
||||||
public interface IUnlocksRenderPlayer { bool RenderPlayerUnlocked { get; } }
|
public interface IUnlocksRenderPlayer { bool RenderPlayerUnlocked { get; } }
|
||||||
|
|
||||||
|
[RequireExplicitImplementation]
|
||||||
|
public interface ICreationActivity { Activity GetCreationActivity(); }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -330,10 +330,10 @@ namespace OpenRA
|
|||||||
public Actor CreateActor(bool addToWorld, string name, TypeDictionary initDict)
|
public Actor CreateActor(bool addToWorld, string name, TypeDictionary initDict)
|
||||||
{
|
{
|
||||||
var a = new Actor(this, name, initDict);
|
var a = new Actor(this, name, initDict);
|
||||||
foreach (var t in a.TraitsImplementing<INotifyCreated>())
|
a.Created();
|
||||||
t.Created(a);
|
|
||||||
if (addToWorld)
|
if (addToWorld)
|
||||||
Add(a);
|
Add(a);
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public class Aircraft : ITick, ISync, IFacing, IPositionable, IMove, IIssueOrder, IResolveOrder, IOrderVoice, IDeathActorInitModifier,
|
public class Aircraft : ITick, ISync, IFacing, IPositionable, IMove, IIssueOrder, IResolveOrder, IOrderVoice, IDeathActorInitModifier,
|
||||||
INotifyCreated, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyActorDisposing, INotifyBecomingIdle,
|
INotifyCreated, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyActorDisposing, INotifyBecomingIdle,
|
||||||
IActorPreviewInitModifier, IIssueDeployOrder, IObservesVariables
|
IActorPreviewInitModifier, IIssueDeployOrder, IObservesVariables, ICreationActivity
|
||||||
{
|
{
|
||||||
static readonly Pair<CPos, SubCell>[] NoCells = { };
|
static readonly Pair<CPos, SubCell>[] NoCells = { };
|
||||||
|
|
||||||
@@ -309,8 +309,6 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
notifyMoving = self.TraitsImplementing<INotifyMoving>().ToArray();
|
notifyMoving = self.TraitsImplementing<INotifyMoving>().ToArray();
|
||||||
positionOffsets = self.TraitsImplementing<IAircraftCenterPositionOffset>().ToArray();
|
positionOffsets = self.TraitsImplementing<IAircraftCenterPositionOffset>().ToArray();
|
||||||
overrideAircraftLanding = self.TraitOrDefault<IOverrideAircraftLanding>();
|
overrideAircraftLanding = self.TraitOrDefault<IOverrideAircraftLanding>();
|
||||||
|
|
||||||
self.QueueActivity(MoveIntoWorld(self, moveIntoWorldDelay));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void INotifyAddedToWorld.AddedToWorld(Actor self)
|
void INotifyAddedToWorld.AddedToWorld(Actor self)
|
||||||
@@ -1164,6 +1162,11 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
inits.Add(new DynamicFacingInit(() => Facing));
|
inits.Add(new DynamicFacingInit(() => Facing));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Activity ICreationActivity.GetCreationActivity()
|
||||||
|
{
|
||||||
|
return MoveIntoWorld(self, moveIntoWorldDelay);
|
||||||
|
}
|
||||||
|
|
||||||
public class AircraftMoveOrderTargeter : IOrderTargeter
|
public class AircraftMoveOrderTargeter : IOrderTargeter
|
||||||
{
|
{
|
||||||
readonly Aircraft aircraft;
|
readonly Aircraft aircraft;
|
||||||
|
|||||||
@@ -130,8 +130,6 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
mobile = self.Trait<Mobile>();
|
mobile = self.Trait<Mobile>();
|
||||||
resLayer = self.World.WorldActor.Trait<ResourceLayer>();
|
resLayer = self.World.WorldActor.Trait<ResourceLayer>();
|
||||||
claimLayer = self.World.WorldActor.Trait<ResourceClaimLayer>();
|
claimLayer = self.World.WorldActor.Trait<ResourceClaimLayer>();
|
||||||
|
|
||||||
self.QueueActivity(new CallFunc(() => ChooseNewProc(self, null)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void INotifyCreated.Created(Actor self)
|
void INotifyCreated.Created(Actor self)
|
||||||
@@ -141,6 +139,8 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
conditionManager = self.TraitOrDefault<ConditionManager>();
|
conditionManager = self.TraitOrDefault<ConditionManager>();
|
||||||
UpdateCondition(self);
|
UpdateCondition(self);
|
||||||
|
|
||||||
|
self.QueueActivity(new CallFunc(() => ChooseNewProc(self, null)));
|
||||||
|
|
||||||
// Note: This is queued in a FrameEndTask because otherwise the activity is dropped/overridden while moving out of a factory.
|
// Note: This is queued in a FrameEndTask because otherwise the activity is dropped/overridden while moving out of a factory.
|
||||||
if (Info.SearchOnCreation)
|
if (Info.SearchOnCreation)
|
||||||
self.World.AddFrameEndTask(w => self.QueueActivity(new FindAndDeliverResources(self)));
|
self.World.AddFrameEndTask(w => self.QueueActivity(new FindAndDeliverResources(self)));
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Mobile : PausableConditionalTrait<MobileInfo>, IIssueOrder, IResolveOrder, IOrderVoice, IPositionable, IMove, ITick,
|
public class Mobile : PausableConditionalTrait<MobileInfo>, IIssueOrder, IResolveOrder, IOrderVoice, IPositionable, IMove, ITick, ICreationActivity,
|
||||||
IFacing, IDeathActorInitModifier, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyBlockingMove, IActorPreviewInitModifier, INotifyBecomingIdle
|
IFacing, IDeathActorInitModifier, INotifyAddedToWorld, INotifyRemovedFromWorld, INotifyBlockingMove, IActorPreviewInitModifier, INotifyBecomingIdle
|
||||||
{
|
{
|
||||||
readonly Actor self;
|
readonly Actor self;
|
||||||
@@ -256,7 +256,6 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
Locomotor = self.World.WorldActor.TraitsImplementing<Locomotor>()
|
Locomotor = self.World.WorldActor.TraitsImplementing<Locomotor>()
|
||||||
.Single(l => l.Info.Name == Info.Locomotor);
|
.Single(l => l.Info.Name == Info.Locomotor);
|
||||||
|
|
||||||
self.QueueActivity(MoveIntoWorld(self, moveIntoWorldDelay));
|
|
||||||
base.Created(self);
|
base.Created(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -897,6 +896,11 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Activity ICreationActivity.GetCreationActivity()
|
||||||
|
{
|
||||||
|
return MoveIntoWorld(self, moveIntoWorldDelay);
|
||||||
|
}
|
||||||
|
|
||||||
class MoveOrderTargeter : IOrderTargeter
|
class MoveOrderTargeter : IOrderTargeter
|
||||||
{
|
{
|
||||||
readonly Mobile mobile;
|
readonly Mobile mobile;
|
||||||
|
|||||||
Reference in New Issue
Block a user