Files
OpenRA/OpenRA.Mods.Common/TraitsInterfaces.cs
Gustas 52102da839 Fix harvesters refusing to queue dock orders whenn empty
(cherry picked from commit 19040126046a53fd5092515f2a4895fdd5c9c87a)
2024-12-27 16:30:58 +02:00

963 lines
33 KiB
C#

#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* 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.Collections.Generic;
using OpenRA.Activities;
using OpenRA.Graphics;
using OpenRA.Mods.Common.Activities;
using OpenRA.Mods.Common.Graphics;
using OpenRA.Mods.Common.Terrain;
using OpenRA.Mods.Common.Widgets;
using OpenRA.Primitives;
using OpenRA.Support;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
public enum VisibilityType { Footprint, CenterPosition, GroundPosition }
public enum AttackDelayType { Preparation, Attack }
[Flags]
public enum ResupplyType
{
None = 0,
Rearm = 1,
Repair = 2
}
public interface IQuantizeBodyOrientationInfo : ITraitInfoInterface
{
int QuantizedBodyFacings(ActorInfo ai, SequenceSet sequences, string faction);
}
public interface IPlaceBuildingDecorationInfo : ITraitInfoInterface
{
IEnumerable<IRenderable> RenderAnnotations(WorldRenderer wr, World w, ActorInfo ai, WPos centerPosition);
}
[RequireExplicitImplementation]
public interface IBlocksProjectiles
{
WDist BlockingHeight { get; }
PlayerRelationship ValidRelationships { get; }
}
[RequireExplicitImplementation]
public interface IBlocksProjectilesInfo : ITraitInfoInterface { }
[RequireExplicitImplementation]
public interface INotifyOrderIssued
{
bool OrderIssued(World world, string orderString, Target target);
}
[RequireExplicitImplementation]
public interface INotifySold
{
void Selling(Actor self);
void Sold(Actor self);
}
[RequireExplicitImplementation]
public interface INotifyCustomLayerChanged
{
void CustomLayerChanged(Actor self, byte oldLayer, byte newLayer);
}
[RequireExplicitImplementation]
public interface INotifyCenterPositionChanged
{
void CenterPositionChanged(Actor self, byte oldLayer, byte newLayer);
}
[RequireExplicitImplementation]
public interface INotifyFinishedMoving
{
void FinishedMoving(Actor self, byte oldLayer, byte newLayer);
}
public interface IDemolishableInfo : ITraitInfoInterface { bool IsValidTarget(ActorInfo actorInfo, Actor saboteur); }
public interface IDemolishable
{
bool IsValidTarget(Actor self, Actor saboteur);
void Demolish(Actor self, Actor saboteur, int delay, BitSet<DamageType> damageTypes);
}
[RequireExplicitImplementation]
public interface INotifyCrushed
{
void OnCrush(Actor self, Actor crusher, BitSet<CrushClass> crushClasses);
void WarnCrush(Actor self, Actor crusher, BitSet<CrushClass> crushClasses);
}
[RequireExplicitImplementation]
public interface INotifyAiming
{
void StartedAiming(Actor self, AttackBase attack);
void StoppedAiming(Actor self, AttackBase attack);
}
[RequireExplicitImplementation]
public interface INotifyAttack
{
void Attacking(Actor self, in Target target, Armament a, Barrel barrel);
void PreparingAttack(Actor self, in Target target, Armament a, Barrel barrel);
}
[RequireExplicitImplementation]
public interface INotifyDamageStateChanged { void DamageStateChanged(Actor self, AttackInfo e); }
[RequireExplicitImplementation]
public interface INotifyDamage { void Damaged(Actor self, AttackInfo e); }
[RequireExplicitImplementation]
public interface INotifyKilled { void Killed(Actor self, AttackInfo e); }
[RequireExplicitImplementation]
public interface INotifyAppliedDamage { void AppliedDamage(Actor self, Actor damaged, AttackInfo e); }
[RequireExplicitImplementation]
public interface INotifyResupply
{
void BeforeResupply(Actor host, Actor target, ResupplyType types);
void ResupplyTick(Actor host, Actor target, ResupplyType types);
}
[RequireExplicitImplementation]
public interface INotifyTakeOff { void TakeOff(Actor self); }
[RequireExplicitImplementation]
public interface INotifyLanding { void Landing(Actor self); }
[RequireExplicitImplementation]
public interface INotifyPowerLevelChanged { void PowerLevelChanged(Actor self); }
public interface INotifySupportPower { void Charged(Actor self); void Activated(Actor self); }
public interface INotifyBuildingPlaced { void BuildingPlaced(Actor self); }
public interface INotifyBurstComplete { void FiredBurst(Actor self, in Target target, Armament a); }
public interface INotifyChat { bool OnChat(string from, string message); }
public interface INotifyProduction { void UnitProduced(Actor self, Actor other, CPos exit); }
public interface INotifyOtherProduction { void UnitProducedByOther(Actor self, Actor producer, Actor produced, string productionType, TypeDictionary init); }
public interface INotifyDelivery { void IncomingDelivery(Actor self); void Delivered(Actor self); }
[RequireExplicitImplementation]
public interface INotifyMineLaying
{
void MineLaying(Actor self, CPos location);
void MineLaid(Actor self, Actor mine);
void MineLayingCanceled(Actor self, CPos location);
}
[RequireExplicitImplementation]
public interface INotifyDockHost { void Docked(Actor self, Actor client); void Undocked(Actor self, Actor client); }
[RequireExplicitImplementation]
public interface INotifyDockClient { void Docked(Actor self, Actor host); void Undocked(Actor self, Actor host); }
[RequireExplicitImplementation]
public interface INotifyDockClientMoving
{
void MovingToDock(Actor self, Actor hostActor, IDockHost host);
void MovementCancelled(Actor self);
}
[RequireExplicitImplementation]
public interface INotifyResourceAccepted { void OnResourceAccepted(Actor self, Actor refinery, string resourceType, int count, int value); }
public interface INotifyParachute { void OnParachute(Actor self); void OnLanded(Actor self); }
[RequireExplicitImplementation]
public interface INotifyCapture { void OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner, BitSet<CaptureType> captureTypes); }
public interface INotifyProximityOwnerChanged { void OnProximityOwnerChanged(Actor actor, Player oldOwner, Player newOwner); }
public interface INotifyDiscovered { void OnDiscovered(Actor self, Player discoverer, bool playNotification); }
public interface IRenderActorPreviewInfo : ITraitInfoInterface { IEnumerable<IActorPreview> RenderPreview(ActorPreviewInitializer init); }
public interface ICruiseAltitudeInfo : ITraitInfoInterface { WDist GetCruiseAltitude(); }
public interface IHuskModifier { string HuskActor(Actor self); }
public interface ISeedableResource { void Seed(Actor self); }
[RequireExplicitImplementation]
public interface INotifyInfiltrated { void Infiltrated(Actor self, Actor infiltrator, BitSet<TargetableType> types); }
[RequireExplicitImplementation]
public interface INotifyBlockingMove { void OnNotifyBlockingMove(Actor self, Actor blocking); }
[RequireExplicitImplementation]
public interface INotifyPassengerEntered { void OnPassengerEntered(Actor self, Actor passenger); }
[RequireExplicitImplementation]
public interface INotifyPassengerExited { void OnPassengerExited(Actor self, Actor passenger); }
[RequireExplicitImplementation]
public interface INotifyEnteredCargo { void OnEnteredCargo(Actor self, Actor cargo); }
[RequireExplicitImplementation]
public interface INotifyExitedCargo { void OnExitedCargo(Actor self, Actor cargo); }
public interface INotifyHarvestAction
{
void Harvested(Actor self, string resourceType);
void MovingToResources(Actor self, CPos targetCell);
void MovementCancelled(Actor self);
}
public interface IDockClientInfo : ITraitInfoInterface { }
public interface IDockClient
{
BitSet<DockType> GetDockType { get; }
/// <summary>When null, the client should act as if it can dock but never do.</summary>
DockClientManager DockClientManager { get; }
void OnDockStarted(Actor self, Actor hostActor, IDockHost host);
bool OnDockTick(Actor self, Actor hostActor, IDockHost dock);
void OnDockCompleted(Actor self, Actor hostActor, IDockHost host);
/// <summary>Are we allowed to dock.</summary>
/// <remarks>
/// Does not check if <see cref="Traits.DockClientManager"/> is enabled.
/// Function should only be called from within <see cref="IDockClient"/> or <see cref="Traits.DockClientManager"/>.
/// </remarks>
bool CanDock(BitSet<DockType> type, bool forceEnter = false);
/// <summary>Are we allowed to dock to this <paramref name="host"/>.</summary>
/// <remarks>
/// Does not check if <see cref="Traits.DockClientManager"/> is enabled.
/// Function should only be called from within <see cref="IDockClient"/> or <see cref="Traits.DockClientManager"/>.
/// </remarks>
bool CanDockAt(Actor hostActor, IDockHost host, bool forceEnter = false, bool ignoreOccupancy = false);
/// <summary>Are we allowed to give a docking order for this <paramref name="host"/>.</summary>
/// <remarks>
/// Does not check if <see cref="Traits.DockClientManager"/> is enabled.
/// Function should only be called from within <see cref="IDockClient"/> or <see cref="Traits.DockClientManager"/>.
/// </remarks>
bool CanQueueDockAt(Actor hostActor, IDockHost host, bool forceEnter, bool isQueued);
}
public interface IDockHostInfo : ITraitInfoInterface { }
public interface IDockHost
{
BitSet<DockType> GetDockType { get; }
/// <summary>Use this function instead of ConditionalTrait.IsTraitDisabled.</summary>
bool IsEnabledAndInWorld { get; }
int ReservationCount { get; }
bool CanBeReserved { get; }
WPos DockPosition { get; }
/// <summary>Can this <paramref name="client"/> dock at this <see cref="IDockHost"/>.</summary>
/// <remarks>
/// Does not check <see cref="DockType"/>.
/// Does not check if <see cref="IDockClient"/> is enabled.
/// Does not check if <see cref="DockClientManager"/> is enabled.
/// </remarks>
bool IsDockingPossible(Actor clientActor, IDockClient client, bool ignoreReservations = false);
bool Reserve(Actor self, DockClientManager client);
void UnreserveAll();
void Unreserve(DockClientManager client);
void OnDockStarted(Actor self, Actor clientActor, DockClientManager client);
void OnDockCompleted(Actor self, Actor clientActor, DockClientManager client);
/// <summary>If <paramref name="client"/> is not in range of <see cref="IDockHost"/> queues a child move activity and returns true. If in range returns false.</summary>
bool QueueMoveActivity(Activity moveToDockActivity, Actor self, Actor clientActor, DockClientManager client, MoveCooldownHelper moveCooldownHelper);
/// <summary>Should be called when in range of <see cref="IDockHost"/>.</summary>
void QueueDockActivity(Activity moveToDockActivity, Actor self, Actor clientActor, DockClientManager client);
}
public interface IDockClientManagerInfo : ITraitInfoInterface { }
[RequireExplicitImplementation]
public interface INotifyLoadCargo
{
void Loading(Actor self);
}
[RequireExplicitImplementation]
public interface INotifyUnloadCargo
{
void Unloading(Actor self);
}
[RequireExplicitImplementation]
public interface INotifyDemolition
{
void Demolishing(Actor self);
}
[RequireExplicitImplementation]
public interface INotifyInfiltration
{
void Infiltrating(Actor self);
}
public interface ITechTreePrerequisiteInfo : ITraitInfoInterface
{
IEnumerable<string> Prerequisites(ActorInfo info);
}
public interface ITechTreePrerequisite
{
IEnumerable<string> ProvidesPrerequisites { get; }
}
public interface ITechTreeElement
{
void PrerequisitesAvailable(string key);
void PrerequisitesUnavailable(string key);
void PrerequisitesItemHidden(string key);
void PrerequisitesItemVisible(string key);
}
public interface IProductionIconOverlay
{
Sprite Sprite { get; }
string Palette { get; }
float2 Offset(float2 iconSize);
bool IsOverlayActive(ActorInfo ai);
}
public interface INotifyTransform
{
void BeforeTransform(Actor self);
void OnTransform(Actor self);
void AfterTransform(Actor toActor);
}
public interface INotifyDeployComplete
{
void FinishedDeploy(Actor self);
void FinishedUndeploy(Actor self);
}
public interface INotifyDeployTriggered
{
void Deploy(Actor self, bool skipMakeAnim);
void Undeploy(Actor self, bool skipMakeAnim);
}
public interface IAcceptResources
{
int AcceptResources(Actor self, string resourceType, int count = 1);
}
public interface IDockClientBody
{
void PlayDockAnimation(Actor self, Action after);
void PlayReverseDockAnimation(Actor self, Action after);
}
public interface IProvidesAssetBrowserPalettes
{
IEnumerable<string> PaletteNames { get; }
}
[RequireExplicitImplementation]
public interface IProvidesAssetBrowserColorPickerPalettes
{
IEnumerable<string> ColorPickerPaletteNames { get; }
}
public interface IColorPickerManagerInfo : ITraitInfoInterface
{
(float SMin, float SMax) SaturationRange { get; }
(float VMin, float VMax) ValueRange { get; }
event Action<Color> OnColorPickerColorUpdate;
Color[] PresetColors { get; }
Color RandomPresetColor(MersenneTwister random, IReadOnlyCollection<Color> terrainColors, IReadOnlyCollection<Color> playerColors);
Color RandomValidColor(MersenneTwister random, IReadOnlyCollection<Color> terrainColors, IReadOnlyCollection<Color> playerColors);
Color MakeValid(
Color color, MersenneTwister random, IReadOnlyCollection<Color> terrainColors, IReadOnlyCollection<Color> playerColors, Action<string> onError = null);
void ShowColorDropDown(DropDownButtonWidget dropdownButton, Color initialColor, string initialFaction, WorldRenderer worldRenderer, Action<Color> onExit);
}
public interface ICallForTransport
{
WDist MinimumDistance { get; }
bool WantsTransport { get; }
void MovementCancelled(Actor self);
void RequestTransport(Actor self, CPos destination);
}
public interface IDeathActorInitModifier
{
void ModifyDeathActorInit(Actor self, TypeDictionary init);
}
public interface ITransformActorInitModifier
{
void ModifyTransformActorInit(Actor self, TypeDictionary init);
}
[RequireExplicitImplementation]
public interface IDisableEnemyAutoTarget
{
bool DisableEnemyAutoTarget(Actor self, Actor attacker);
}
[RequireExplicitImplementation]
public interface IOverrideAutoTarget
{
bool TryGetAutoTargetOverride(Actor self, out Target target);
}
[RequireExplicitImplementation]
public interface IWallConnector
{
bool AdjacentWallCanConnect(Actor self, CPos wallLocation, string wallType, out CVec facing);
void SetDirty();
}
[RequireExplicitImplementation]
public interface IActorPreviewInitModifier
{
void ModifyActorPreviewInit(Actor self, TypeDictionary inits);
}
[RequireExplicitImplementation]
public interface IRenderInfantrySequenceModifier
{
bool IsModifyingSequence { get; }
string SequencePrefix { get; }
}
[RequireExplicitImplementation]
public interface IProductionCostModifierInfo : ITraitInfoInterface { int GetProductionCostModifier(TechTree techTree, string queue); }
[RequireExplicitImplementation]
public interface IProductionTimeModifierInfo : ITraitInfoInterface { int GetProductionTimeModifier(TechTree techTree, string queue); }
[RequireExplicitImplementation]
public interface ICashTricklerModifier { int GetCashTricklerModifier(); }
[RequireExplicitImplementation]
public interface IDamageModifier { int GetDamageModifier(Actor attacker, Damage damage); }
[RequireExplicitImplementation]
public interface ISpeedModifier { int GetSpeedModifier(); }
[RequireExplicitImplementation]
public interface IFirepowerModifier { int GetFirepowerModifier(); }
[RequireExplicitImplementation]
public interface IReloadModifier { int GetReloadModifier(); }
[RequireExplicitImplementation]
public interface IReloadAmmoModifier { int GetReloadAmmoModifier(); }
[RequireExplicitImplementation]
public interface IInaccuracyModifier { int GetInaccuracyModifier(); }
[RequireExplicitImplementation]
public interface IRangeModifier { int GetRangeModifier(); }
[RequireExplicitImplementation]
public interface IRangeModifierInfo : ITraitInfoInterface { int GetRangeModifierDefault(); }
[RequireExplicitImplementation]
public interface IPowerModifier { int GetPowerModifier(); }
[RequireExplicitImplementation]
public interface IGivesExperienceModifier { int GetGivesExperienceModifier(); }
[RequireExplicitImplementation]
public interface IGainsExperienceModifier { int GetGainsExperienceModifier(); }
[RequireExplicitImplementation]
public interface ICreatesShroudModifier { int GetCreatesShroudModifier(); }
[RequireExplicitImplementation]
public interface IRevealsShroudModifier { int GetRevealsShroudModifier(); }
[RequireExplicitImplementation]
public interface IDetectCloakedModifier { int GetDetectCloakedModifier(); }
[RequireExplicitImplementation]
public interface IResourceValueModifier { int GetResourceValueModifier(); }
[RequireExplicitImplementation]
public interface ICustomMovementLayer
{
byte Index { get; }
bool InteractsWithDefaultLayer { get; }
bool ReturnToGroundLayerOnIdle { get; }
bool EnabledForLocomotor(LocomotorInfo li);
short EntryMovementCost(LocomotorInfo li, CPos cell);
short ExitMovementCost(LocomotorInfo li, CPos cell);
byte GetTerrainIndex(CPos cell);
WPos CenterOfCell(CPos cell);
}
public interface ICustomMovementLayerInfo : ITraitInfoInterface { }
// For traits that want to be exposed to the "Deploy" UI button / hotkey
[RequireExplicitImplementation]
public interface IIssueDeployOrder
{
Order IssueDeployOrder(Actor self, bool queued);
bool CanIssueDeployOrder(Actor self, bool queued);
}
public enum ActorPreviewType { PlaceBuilding, ColorPicker, MapEditorSidebar }
[RequireExplicitImplementation]
public interface IActorPreviewInitInfo : ITraitInfoInterface
{
IEnumerable<ActorInit> ActorPreviewInits(ActorInfo ai, ActorPreviewType type);
}
public interface IMove
{
Activity MoveTo(CPos cell, int nearEnough = 0, Actor ignoreActor = null,
bool evaluateNearestMovableCell = false, Color? targetLineColor = null);
Activity MoveWithinRange(in Target target, WDist range,
WPos? initialTargetPosition = null, Color? targetLineColor = null);
Activity MoveWithinRange(in Target target, WDist minRange, WDist maxRange,
WPos? initialTargetPosition = null, Color? targetLineColor = null);
Activity MoveFollow(Actor self, in Target target, WDist minRange, WDist maxRange,
WPos? initialTargetPosition = null, Color? targetLineColor = null);
Activity MoveToTarget(Actor self, in Target target,
WPos? initialTargetPosition = null, Color? targetLineColor = null);
Activity ReturnToCell(Actor self);
Activity MoveIntoTarget(Actor self, in Target target);
Activity MoveOntoTarget(Actor self, in Target target, in WVec offset,
WAngle? facing, Color? targetLineColor = null);
Activity LocalMove(Actor self, WPos fromPos, WPos toPos);
int EstimatedMoveDuration(Actor self, WPos fromPos, WPos toPos);
CPos NearestMoveableCell(CPos target);
MovementType CurrentMovementTypes { get; set; }
bool CanEnterTargetNow(Actor self, in Target target);
}
public interface IWrapMove
{
Activity WrapMove(Activity moveInner);
}
public interface IAircraftCenterPositionOffset
{
WVec PositionOffset { get; }
}
public interface IOverrideAircraftLanding
{
HashSet<string> LandableTerrainTypes { get; }
}
public interface IRadarSignature
{
void PopulateRadarSignatureCells(Actor self, List<(CPos Cell, Color Color)> destinationBuffer);
}
public interface IRadarColorModifier { Color RadarColorOverride(Actor self, Color color); }
public interface IObjectivesPanel
{
string PanelName { get; }
int ExitDelay { get; }
}
[RequireExplicitImplementation]
public interface INotifyObjectivesUpdated
{
void OnObjectiveAdded(Player player, int objectiveID);
void OnObjectiveCompleted(Player player, int objectiveID);
void OnObjectiveFailed(Player player, int objectiveID);
}
[RequireExplicitImplementation]
public interface INotifyWinStateChanged
{
void OnPlayerWon(Player winner);
void OnPlayerLost(Player loser);
}
public interface INotifyCashTransfer
{
void OnAcceptingCash(Actor self, Actor donor);
void OnDeliveringCash(Actor self, Actor acceptor);
}
[RequireExplicitImplementation]
public interface ITargetableCells
{
(CPos Cell, SubCell SubCell)[] TargetableCells();
}
[RequireExplicitImplementation]
public interface IPreventsShroudReset { bool PreventShroudReset(Actor self); }
[RequireExplicitImplementation]
public interface IBotEnabled { void BotEnabled(IBot bot); }
[RequireExplicitImplementation]
public interface IBotTick { void BotTick(IBot bot); }
[RequireExplicitImplementation]
public interface IBotRespondToAttack { void RespondToAttack(IBot bot, Actor self, AttackInfo e); }
[RequireExplicitImplementation]
public interface IBotPositionsUpdated
{
void UpdatedBaseCenter(CPos newLocation);
void UpdatedDefenseCenter(CPos newLocation);
}
[RequireExplicitImplementation]
public interface IBotNotifyIdleBaseUnits
{
void UpdatedIdleBaseUnits(List<Actor> idleUnits);
}
[RequireExplicitImplementation]
public interface IBotRequestUnitProduction
{
void RequestUnitProduction(IBot bot, string requestedActor);
int RequestedProductionCount(IBot bot, string requestedActor);
}
[RequireExplicitImplementation]
public interface IBotRequestPauseUnitProduction
{
bool PauseUnitProduction { get; }
}
[RequireExplicitImplementation]
public interface IEditorActorOptions : ITraitInfoInterface
{
IEnumerable<EditorActorOption> ActorOptions(ActorInfo ai, World world);
}
public abstract class EditorActorOption
{
public readonly string Name;
public readonly int DisplayOrder;
protected EditorActorOption(string name, int displayOrder)
{
Name = name;
DisplayOrder = displayOrder;
}
}
public class EditorActorCheckbox : EditorActorOption
{
public readonly Func<EditorActorPreview, bool> GetValue;
public readonly Action<EditorActorPreview, bool> OnChange;
public EditorActorCheckbox(string name, int displayOrder,
Func<EditorActorPreview, bool> getValue,
Action<EditorActorPreview, bool> onChange)
: base(name, displayOrder)
{
GetValue = getValue;
OnChange = onChange;
}
}
public class EditorActorSlider : EditorActorOption
{
public readonly float MinValue;
public readonly float MaxValue;
public readonly int Ticks;
public readonly Func<EditorActorPreview, float> GetValue;
public readonly Action<EditorActorPreview, float> OnChange;
public EditorActorSlider(string name, int displayOrder,
float minValue, float maxValue, int ticks,
Func<EditorActorPreview, float> getValue,
Action<EditorActorPreview, float> onChange)
: base(name, displayOrder)
{
MinValue = minValue;
MaxValue = maxValue;
Ticks = ticks;
GetValue = getValue;
OnChange = onChange;
}
}
public class EditorActorDropdown : EditorActorOption
{
public readonly Func<EditorActorPreview, Dictionary<string, string>> GetLabels;
public readonly Func<EditorActorPreview, Dictionary<string, string>, string> GetValue;
public readonly Action<EditorActorPreview, string> OnChange;
/// <summary>
/// Creates dropdown for editing actor's metadata with dynamically created items.
/// </summary>
public EditorActorDropdown(string name, int displayOrder,
Func<EditorActorPreview, Dictionary<string, string>> getLabels,
Func<EditorActorPreview, Dictionary<string, string>, string> getValue,
Action<EditorActorPreview, string> onChange)
: base(name, displayOrder)
{
GetLabels = getLabels;
GetValue = getValue;
OnChange = onChange;
}
}
[RequireExplicitImplementation]
public interface INotifyEditorPlacementInfo : ITraitInfoInterface
{
object AddedToEditor(EditorActorPreview preview, World editorWorld);
void RemovedFromEditor(EditorActorPreview preview, World editorWorld, object data);
}
[RequireExplicitImplementation]
public interface IPreventMapSpawn
{
bool PreventMapSpawn(World world, ActorReference actorReference);
}
[Flags]
public enum MovementType
{
None = 0,
Horizontal = 1,
Vertical = 2,
Turn = 4
}
public enum MoveResult
{
InProgress,
CompleteCanceled,
CompleteDestinationReached,
CompleteDestinationBlocked,
}
[RequireExplicitImplementation]
public interface INotifyMoving
{
void MovementTypeChanged(Actor self, MovementType type);
}
[RequireExplicitImplementation]
public interface INotifyTimeLimit
{
void NotifyTimerExpired(Actor self);
}
[RequireExplicitImplementation]
public interface ISelectable
{
string Class { get; }
}
public interface IDecoration
{
bool RequiresSelection { get; }
IEnumerable<IRenderable> RenderDecoration(Actor self, WorldRenderer wr, ISelectionDecorations container);
}
[RequireExplicitImplementation]
public interface ITiledTerrainRendererInfo : ITraitInfoInterface
{
bool ValidateTileSprites(ITemplatedTerrainInfo terrainInfo, Action<string> onError);
}
[RequireExplicitImplementation]
public interface ITiledTerrainRenderer
{
Sprite MissingTile { get; }
Sprite TileSprite(TerrainTile r, int? variant = null);
Rectangle TemplateBounds(TerrainTemplateInfo template);
IEnumerable<IRenderable> RenderUIPreview(WorldRenderer wr, TerrainTemplateInfo template, int2 origin, float scale);
IEnumerable<IRenderable> RenderPreview(WorldRenderer wr, TerrainTemplateInfo template, WPos origin);
}
public interface IResourceLayerInfo : ITraitInfoInterface
{
bool TryGetTerrainType(string resourceType, out string terrainType);
bool TryGetResourceIndex(string resourceType, out byte index);
}
[RequireExplicitImplementation]
public interface IResourceLayer
{
event Action<CPos, string> CellChanged;
ResourceLayerContents GetResource(CPos cell);
int GetMaxDensity(string resourceType);
bool CanAddResource(string resourceType, CPos cell, int amount = 1);
int AddResource(string resourceType, CPos cell, int amount = 1);
int RemoveResource(string resourceType, CPos cell, int amount = 1);
void ClearResources(CPos cell);
bool IsVisible(CPos cell);
bool IsEmpty { get; }
IResourceLayerInfo Info { get; }
}
[RequireExplicitImplementation]
public interface IResourceRenderer
{
IEnumerable<string> ResourceTypes { get; }
string GetRenderedResourceType(CPos cell);
string GetRenderedResourceTooltip(CPos cell);
IEnumerable<IRenderable> RenderUIPreview(WorldRenderer wr, string resourceType, int2 origin, float scale);
IEnumerable<IRenderable> RenderPreview(WorldRenderer wr, string resourceType, WPos origin);
}
[RequireExplicitImplementation]
public interface IRadarTerrainLayer
{
event Action<CPos> CellEntryChanged;
bool TryGetTerrainColorPair(MPos uv, out (Color Left, Color Right) value);
}
/// <summary>
/// When performing locomotion or pathfinding related checks,
/// determines whether the blocking rules will be applied when encountering other actors.
/// </summary>
public enum BlockedByActor
{
/// <summary>
/// Actors on the map are ignored, as if they were not present.
/// An actor can only be blocked by impassable terrain.
/// An actor can never be blocked by other actors. The blocking rules will never be evaluated.
/// </summary>
None,
/// <summary>
/// Actors on the map that are moving, or moveable &amp; allied are ignored.
/// An actor is Immovable is any of the following applies:
/// <list type="bullet">
/// <item>Lacks the <see cref="Mobile"/> trait.</item>
/// <item>The <see cref="Mobile"/> trait has <see cref="ConditionalTrait{MobileInfo}.IsTraitDisabled"/> or
/// <see cref="PausableConditionalTrait{MobileInfo}.IsTraitPaused"/> as true.</item>
/// <item>The <see cref="Mobile"/> trait has <see cref="Mobile.IsImmovable"/> as true.</item>
/// </list>
/// Note the above definition means an actor can be Movable, but may not be Moving, i.e. it is Stationary.
/// Actors are allied if their owners have the <see cref="PlayerRelationship.Ally"/> relationship.
/// An actor can be blocked by impassable terrain.
/// An actor can be blocked by immovable actors *if* they are deemed as blocking by the blocking rules.
/// An actor can be blocked by an actor capable of moving, if it is not an ally and *if* they are deemed as
/// blocking by the blocking rules.
/// An actor can never be blocked by an allied actor capable of moving, even if the other actor is stationary.
/// An actor can never be blocked by a moving actor.
/// </summary>
Immovable,
/// <summary>
/// Actors on the map that are moving are ignored.
/// An actor is moving if both of the following apply:
/// <list type="bullet">
/// <item>It is a Moveable actor (see <see cref="Immovable"/>).</item>
/// <item><see cref="Mobile.CurrentMovementTypes"/> contains the flag <see cref="MovementType.Horizontal"/>.</item>
/// </list>
/// Otherwise the actor is deemed to be Stationary.
/// An actor can be blocked by impassable terrain.
/// An actor can be blocked by immovable actors and stationary actors *if* they are deemed as blocking by the
/// blocking rules.
/// An actor can never be blocked by a moving actor.
/// </summary>
Stationary,
/// <summary>
/// Actors on the map are not ignored.
/// An actor can be blocked by impassable terrain.
/// An actor can be blocked by immovable actors, stationary actors and moving actors *if* they are deemed as
/// blocking by the blocking rules.
/// </summary>
All
}
public interface IPositionableInfo : IOccupySpaceInfo
{
bool CanEnterCell(World world, Actor self, CPos cell,
SubCell subCell = SubCell.FullCell, Actor ignoreActor = null, BlockedByActor check = BlockedByActor.All);
}
public interface IPositionable : IOccupySpace
{
bool CanExistInCell(CPos location);
bool IsLeavingCell(CPos location, SubCell subCell = SubCell.Any);
bool CanEnterCell(CPos location, Actor ignoreActor = null, BlockedByActor check = BlockedByActor.All);
SubCell GetValidSubCell(SubCell preferred = SubCell.Any);
SubCell GetAvailableSubCell(CPos location,
SubCell preferredSubCell = SubCell.Any, Actor ignoreActor = null, BlockedByActor check = BlockedByActor.All);
void SetPosition(Actor self, CPos cell, SubCell subCell = SubCell.Any);
void SetPosition(Actor self, WPos pos);
void SetCenterPosition(Actor self, WPos pos);
}
public interface IPathFinder
{
/// <summary>
/// Calculates a path for the actor from multiple possible sources to target.
/// Returned path is *reversed* and given target to source.
/// The shortest path between a source and the target is returned.
/// </summary>
/// <remarks>Path searches are not guaranteed to by symmetric,
/// the source and target locations cannot be swapped.
/// Call <see cref="FindPathToTargetCells"/> instead.</remarks>
List<CPos> FindPathToTargetCell(
Actor self, IEnumerable<CPos> sources, CPos target, BlockedByActor check,
Func<CPos, int> customCost = null,
Actor ignoreActor = null,
bool laneBias = true);
/// <summary>
/// Calculates a path for the actor from source to multiple possible targets.
/// Returned path is *reversed* and given target to source.
/// The shortest path between the source and a target is returned.
/// </summary>
/// <remarks>Path searches are not guaranteed to by symmetric,
/// the source and target locations cannot be swapped.
/// Call <see cref="FindPathToTargetCell"/> instead.</remarks>
List<CPos> FindPathToTargetCells(
Actor self, CPos source, IEnumerable<CPos> targets, BlockedByActor check,
Func<CPos, int> customCost = null,
Actor ignoreActor = null,
bool laneBias = true);
/// <summary>
/// Calculates a path for the actor from multiple possible sources, whilst searching for an acceptable target.
/// Returned path is *reversed* and given target to source.
/// The shortest path between a source and a discovered target is returned.
/// </summary>
List<CPos> FindPathToTargetCellByPredicate(
Actor self, IEnumerable<CPos> sources, Func<CPos, bool> targetPredicate, BlockedByActor check,
Func<CPos, int> customCost = null,
Actor ignoreActor = null,
bool laneBias = true);
/// <summary>
/// Determines if a path exists between source and target.
/// Only terrain is taken into account, i.e. as if <see cref="BlockedByActor.None"/> was given.
/// This would apply for any actor using the given <see cref="Locomotor"/>.
/// </summary>
/// <remarks>Path searches are not guaranteed to by symmetric,
/// the source and target locations cannot be swapped.</remarks>
bool PathExistsForLocomotor(Locomotor locomotor, CPos source, CPos target);
/// <summary>
/// Determines if a path exists between source and target.
/// Terrain and immovable actors are taken into account,
/// i.e. as if <see cref="BlockedByActor.Immovable"/> was given.
/// Implementations are permitted to only account for a subset of actors, for performance.
/// This would apply for any actor using the given <see cref="Locomotor"/>.
/// </summary>
/// <remarks>Path searches are not guaranteed to by symmetric,
/// the source and target locations cannot be swapped.
/// If this method returns false, there is guaranteed to be no path.
/// If it returns true, there *might* be a path.
/// </remarks>
bool PathMightExistForLocomotorBlockedByImmovable(Locomotor locomotor, CPos source, CPos target);
}
}