Introduce IDefaultVisibility.

This commit is contained in:
Paul Chote
2015-06-13 15:42:13 +01:00
parent 0a2757d0e0
commit b887d2bfd7
7 changed files with 115 additions and 18 deletions

View File

@@ -154,12 +154,7 @@ namespace OpenRA
if (a.TraitsImplementing<IVisibilityModifier>().Any(t => !t.IsVisible(a, this)))
return false;
if (a.Owner.IsAlliedWith(this))
return true;
// Actors are hidden under shroud, but not under fog by default
// TODO: Shroud exploration should be implemented as an IVisibility modifier!
return Shroud.GetVisOrigins(a).Any(Shroud.IsExplored);
return a.Trait<IDefaultVisibility>().IsVisible(a, this);
}
#region Scripting interface

View File

@@ -167,6 +167,8 @@ namespace OpenRA.Traits
IEnumerable<Pair<CPos, Color>> RadarSignatureCells(Actor self);
}
public interface IDefaultVisibilityInfo { }
public interface IDefaultVisibility { bool IsVisible(Actor self, Player byPlayer); }
public interface IVisibilityModifier { bool IsVisible(Actor self, Player byPlayer); }
public interface IFogVisibilityModifier { bool HasFogVisibility(Player byPlayer); }

View File

@@ -676,6 +676,8 @@
<Compile Include="Widgets\EditorViewportControllerWidget.cs" />
<Compile Include="Traits\World\PaletteFromPaletteWithAlpha.cs" />
<Compile Include="Traits\World\PaletteFromPlayerPaletteWithAlpha.cs" />
<Compile Include="Traits\Modifiers\HiddenUnderShroud.cs" />
<Compile Include="Traits\Modifiers\AlwaysVisible.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>

View File

@@ -0,0 +1,24 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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. For more information,
* see COPYING.
*/
#endregion
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("The actor is always considered visible for targeting and rendering purposes.")]
public class AlwaysVisibleInfo : TraitInfo<AlwaysVisible>, IDefaultVisibilityInfo { }
public class AlwaysVisible : IDefaultVisibility
{
public bool IsVisible(Actor self, Player byPlayer)
{
return true;
}
}
}

View File

@@ -17,17 +17,21 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("This actor will remain visible (but not updated visually) under fog, once discovered.")]
public class FrozenUnderFogInfo : ITraitInfo, Requires<BuildingInfo>
public class FrozenUnderFogInfo : ITraitInfo, Requires<BuildingInfo>, IDefaultVisibilityInfo
{
public readonly bool StartsRevealed = false;
[Desc("Players with these stances can always see the actor.")]
public readonly Stance AlwaysVisibleStances = Stance.Ally;
public object Create(ActorInitializer init) { return new FrozenUnderFog(init, this); }
}
public class FrozenUnderFog : IRenderModifier, IVisibilityModifier, ITick, ISync
public class FrozenUnderFog : IRenderModifier, IDefaultVisibility, ITick, ISync
{
[Sync] public int VisibilityHash;
readonly FrozenUnderFogInfo info;
readonly bool startsRevealed;
readonly MPos[] footprint;
@@ -41,6 +45,8 @@ namespace OpenRA.Mods.Common.Traits
public FrozenUnderFog(ActorInitializer init, FrozenUnderFogInfo info)
{
this.info = info;
// Spawned actors (e.g. building husks) shouldn't be revealed
startsRevealed = info.StartsRevealed && !init.Contains<ParentActorInit>();
var footprintCells = FootprintUtils.Tiles(init.Self).ToList();
@@ -54,7 +60,11 @@ namespace OpenRA.Mods.Common.Traits
public bool IsVisible(Actor self, Player byPlayer)
{
return byPlayer == null || visible[byPlayer];
if (byPlayer == null)
return true;
var stance = self.Owner.Stances[byPlayer];
return info.AlwaysVisibleStances.HasFlag(stance) || visible[byPlayer];
}
public void Tick(Actor self)

View File

@@ -16,18 +16,22 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("The actor stays invisible under fog of war.")]
public class HiddenUnderFogInfo : TraitInfo<HiddenUnderFog> { }
public class HiddenUnderFog : IRenderModifier, IVisibilityModifier
public class HiddenUnderFogInfo : HiddenUnderShroudInfo
{
public bool IsVisible(Actor self, Player byPlayer)
{
return byPlayer == null || Shroud.GetVisOrigins(self).Any(byPlayer.Shroud.IsVisible);
}
public override object Create(ActorInitializer init) { return new HiddenUnderFog(this); }
}
public IEnumerable<IRenderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<IRenderable> r)
public class HiddenUnderFog : HiddenUnderShroud
{
public HiddenUnderFog(HiddenUnderFogInfo info)
: base(info) { }
protected override bool IsVisibleInner(Actor self, Player byPlayer)
{
return IsVisible(self, self.World.RenderPlayer) ? r : SpriteRenderable.None;
if (!VisibilityFootprint(self).Any(byPlayer.Shroud.IsVisible))
return false;
return base.IsVisibleInner(self, byPlayer);
}
}
}

View File

@@ -0,0 +1,60 @@
#region Copyright & License Information
/*
* Copyright 2007-2015 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. For more information,
* see COPYING.
*/
#endregion
using System.Collections.Generic;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("The actor stays invisible under the shroud.")]
public class HiddenUnderShroudInfo : ITraitInfo, IDefaultVisibilityInfo
{
[Desc("Players with these stances can always see the actor.")]
public readonly Stance AlwaysVisibleStances = Stance.Ally;
public virtual object Create(ActorInitializer init) { return new HiddenUnderShroud(this); }
}
public class HiddenUnderShroud : IDefaultVisibility, IRenderModifier
{
readonly HiddenUnderShroudInfo info;
public HiddenUnderShroud(HiddenUnderShroudInfo info)
{
this.info = info;
}
protected IEnumerable<CPos> VisibilityFootprint(Actor self)
{
return Shroud.GetVisOrigins(self);
}
protected virtual bool IsVisibleInner(Actor self, Player byPlayer)
{
return VisibilityFootprint(self).Any(byPlayer.Shroud.IsExplored);
}
public bool IsVisible(Actor self, Player byPlayer)
{
if (byPlayer == null)
return true;
var stance = self.Owner.Stances[byPlayer];
return info.AlwaysVisibleStances.HasFlag(stance) || IsVisibleInner(self, byPlayer);
}
public IEnumerable<IRenderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<IRenderable> r)
{
return IsVisible(self, self.World.RenderPlayer) ? r : SpriteRenderable.None;
}
}
}