Merge pull request #8477 from pchote/actor-visibility

Move actor visibility checks out of Shroud
This commit is contained in:
Oliver Brakmann
2015-06-19 23:38:23 +02:00
50 changed files with 274 additions and 59 deletions

View File

@@ -49,6 +49,8 @@ namespace OpenRA
public Shroud Shroud;
public World World { get; private set; }
readonly IFogVisibilityModifier[] fogVisibilities;
CountryInfo ChooseCountry(World world, string name, bool requireSelectable = true)
{
var selectableCountries = world.Map.Rules.Actors["world"].Traits
@@ -113,6 +115,9 @@ namespace OpenRA
PlayerActor = world.CreateActor("Player", new TypeDictionary { new OwnerInit(this) });
Shroud = PlayerActor.Trait<Shroud>();
fogVisibilities = PlayerActor.TraitsImplementing<IFogVisibilityModifier>()
.ToArray();
// Enable the bot logic on the host
IsBot = botType != null;
if (IsBot && Game.IsHost)
@@ -149,6 +154,27 @@ namespace OpenRA
nsc.Trait.StanceChanged(nsc.Actor, this, target, oldStance, s);
}
public bool CanViewActor(Actor a)
{
if (a.TraitsImplementing<IVisibilityModifier>().Any(t => !t.IsVisible(a, this)))
return false;
return a.Trait<IDefaultVisibility>().IsVisible(a, this);
}
public bool CanTargetActor(Actor a)
{
if (HasFogVisibility)
return true;
if (a.TraitsImplementing<IVisibilityModifier>().Any(t => !t.IsVisible(a, this)))
return false;
return a.Trait<IDefaultVisibility>().IsVisible(a, this);
}
public bool HasFogVisibility { get { return fogVisibilities.Any(f => f.HasFogVisibility(this)); } }
#region Scripting interface
Lazy<ScriptPlayerInterface> luaInterface;

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

@@ -33,8 +33,6 @@ namespace OpenRA.Traits
readonly CellLayer<short> generatedShroudCount;
readonly CellLayer<bool> explored;
readonly Lazy<IFogVisibilityModifier[]> fogVisibilities;
// Cache of visibility that was added, so no matter what crazy trait code does, it
// can't make us invalid.
readonly Dictionary<Actor, CPos[]> visibility = new Dictionary<Actor, CPos[]>();
@@ -62,8 +60,6 @@ namespace OpenRA.Traits
self.World.ActorAdded += a => { CPos[] shrouded = null; AddShroudGeneration(a, ref shrouded); };
self.World.ActorRemoved += RemoveShroudGeneration;
fogVisibilities = Exts.Lazy(() => self.TraitsImplementing<IFogVisibilityModifier>().ToArray());
shroudEdgeTest = map.Contains;
isExploredTest = IsExploredCore;
isVisibleTest = IsVisibleCore;
@@ -342,11 +338,6 @@ namespace OpenRA.Traits
}
}
public bool IsExplored(Actor a)
{
return GetVisOrigins(a).Any(IsExplored);
}
public bool IsVisible(WPos pos)
{
return IsVisible(map.CellContaining(pos));
@@ -394,31 +385,6 @@ namespace OpenRA.Traits
}
}
// Actors are hidden under shroud, but not under fog by default
public bool IsVisible(Actor a)
{
if (a.TraitsImplementing<IVisibilityModifier>().Any(t => !t.IsVisible(a, self.Owner)))
return false;
return a.Owner.IsAlliedWith(self.Owner) || IsExplored(a);
}
public bool IsTargetable(Actor a)
{
if (HasFogVisibility())
return true;
if (a.TraitsImplementing<IVisibilityModifier>().Any(t => !t.IsVisible(a, self.Owner)))
return false;
return GetVisOrigins(a).Any(IsVisible);
}
public bool HasFogVisibility()
{
return fogVisibilities.Value.Any(f => f.HasFogVisibility(self.Owner));
}
public bool Contains(MPos uv)
{
// Check that uv is inside the map area. There is nothing special

View File

@@ -70,12 +70,9 @@ namespace OpenRA
set { renderPlayer = value; }
}
public bool FogObscures(Actor a) { return RenderPlayer != null && !RenderPlayer.Shroud.IsVisible(a); }
public bool FogObscures(Actor a) { return RenderPlayer != null && !RenderPlayer.CanViewActor(a); }
public bool FogObscures(CPos p) { return RenderPlayer != null && !RenderPlayer.Shroud.IsVisible(p); }
public bool FogObscures(WPos pos) { return RenderPlayer != null && !RenderPlayer.Shroud.IsVisible(pos); }
public bool FogObscures(MPos uv) { return RenderPlayer != null && !RenderPlayer.Shroud.IsVisible(uv); }
public bool ShroudObscures(Actor a) { return RenderPlayer != null && !RenderPlayer.Shroud.IsExplored(a); }
public bool ShroudObscures(CPos p) { return RenderPlayer != null && !RenderPlayer.Shroud.IsExplored(p); }
public bool ShroudObscures(WPos pos) { return RenderPlayer != null && !RenderPlayer.Shroud.IsExplored(pos); }
public bool ShroudObscures(MPos uv) { return RenderPlayer != null && !RenderPlayer.Shroud.IsExplored(uv); }

View File

@@ -61,7 +61,7 @@ namespace OpenRA.Mods.Common.Activities
// HACK: This would otherwise break targeting frozen actors
// The problem is that Shroud.IsTargetable returns false (as it should) for
// frozen actors, but we do want to explicitly target the underlying actor here.
if (!attack.Info.IgnoresVisibility && type == TargetType.Actor && !Target.Actor.HasTrait<FrozenUnderFog>() && !self.Owner.Shroud.IsTargetable(Target.Actor))
if (!attack.Info.IgnoresVisibility && type == TargetType.Actor && !Target.Actor.HasTrait<FrozenUnderFog>() && !self.Owner.CanTargetActor(Target.Actor))
return NextActivity;
// Try to move within range

View File

@@ -0,0 +1,36 @@
#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;
using System.Linq;
using OpenRA.GameRules;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Lint
{
class CheckDefaultVisibility : ILintPass
{
public void Run(Action<string> emitError, Action<string> emitWarning, Map map)
{
foreach (var actorInfo in map.Rules.Actors)
{
if (actorInfo.Key.StartsWith("^"))
continue;
var count = actorInfo.Value.Traits.WithInterface<IDefaultVisibilityInfo>().Count();
if (count == 0)
emitError("Actor type `{0}` does not define a default visibility type!".F(actorInfo.Key));
else if (count > 1)
emitError("Actor type `{0}` defines multiple default visibility types!".F(actorInfo.Key));
}
}
}
}

View File

@@ -676,6 +676,9 @@
<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="Lint\CheckDefaultVisibility.cs" />
<Compile Include="Traits\Modifiers\AlwaysVisible.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>

View File

@@ -156,7 +156,7 @@ namespace OpenRA.Mods.Common.Traits
a.AppearsHostileTo(self) &&
!a.HasTrait<AutoTargetIgnore>() &&
attack.HasAnyValidWeapons(Target.FromActor(a)) &&
self.Owner.Shroud.IsTargetable(a))
self.Owner.CanTargetActor(a))
.ClosestTo(self);
}
}

View File

@@ -24,7 +24,7 @@ namespace OpenRA.Mods.Common.Traits
public override int GetSelectionShares(Actor collector)
{
// don't ever hide the map for people who have GPS.
if (collector.Owner.Shroud.HasFogVisibility())
if (collector.Owner.HasFogVisibility)
return 0;
return base.GetSelectionShares(collector);

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
{
return IsVisible(self, self.World.RenderPlayer) ? r : SpriteRenderable.None;
public HiddenUnderFog(HiddenUnderFogInfo info)
: base(info) { }
protected override bool IsVisibleInner(Actor self, Player byPlayer)
{
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;
}
}
}

View File

@@ -77,7 +77,7 @@ namespace OpenRA.Mods.Common.Traits
continue;
// The actor is not currently visible
if (!self.Owner.Shroud.IsVisible(actor.Actor))
if (!self.Owner.CanViewActor(actor.Actor))
continue;
visibleActorIds.Add(actor.Actor.ActorID);

View File

@@ -20,7 +20,7 @@ namespace OpenRA.Mods.RA.Traits
public void Infiltrated(Actor self, Actor infiltrator)
{
infiltrator.Owner.Shroud.Explore(self.Owner.Shroud);
if (!self.Owner.Shroud.HasFogVisibility())
if (!self.Owner.HasFogVisibility)
self.Owner.Shroud.ResetExploration();
}
}

View File

@@ -137,7 +137,7 @@ namespace OpenRA.Mods.RA.Traits
var targetUnits = power.UnitsInRange(xy).Where(a => !world.FogObscures(a));
foreach (var unit in targetUnits)
if (manager.Self.Owner.Shroud.IsTargetable(unit))
if (manager.Self.Owner.CanTargetActor(unit))
yield return new SelectionBoxRenderable(unit, Color.Red);
}
@@ -217,7 +217,7 @@ namespace OpenRA.Mods.RA.Traits
public IEnumerable<IRenderable> RenderAfterWorld(WorldRenderer wr, World world)
{
foreach (var unit in power.UnitsInRange(sourceLocation))
if (manager.Self.Owner.Shroud.IsTargetable(unit))
if (manager.Self.Owner.CanTargetActor(unit))
yield return new SelectionBoxRenderable(unit, Color.Red);
}
@@ -238,7 +238,7 @@ namespace OpenRA.Mods.RA.Traits
foreach (var unit in power.UnitsInRange(sourceLocation))
{
var offset = world.Map.CenterOfCell(xy) - world.Map.CenterOfCell(sourceLocation);
if (manager.Self.Owner.Shroud.IsTargetable(unit))
if (manager.Self.Owner.CanTargetActor(unit))
foreach (var r in unit.Render(wr))
yield return r.OffsetBy(offset);
}
@@ -246,7 +246,7 @@ namespace OpenRA.Mods.RA.Traits
// Unit tiles
foreach (var unit in power.UnitsInRange(sourceLocation))
{
if (manager.Self.Owner.Shroud.IsTargetable(unit))
if (manager.Self.Owner.CanTargetActor(unit))
{
var targetCell = unit.Location + (xy - sourceLocation);
var canEnter = manager.Self.Owner.Shroud.IsExplored(targetCell) &&

View File

@@ -826,6 +826,7 @@ Rules:
Description: Provides an overview of the battlefield.\n Requires power to operate.
-AirstrikePower:
airstrike.proxy:
AlwaysVisible:
AirstrikePower:
Icon: airstrike
StartFullyCharged: True

View File

@@ -921,6 +921,7 @@ Rules:
Amount: 500
UseCashTick: yes
airstrike.proxy:
AlwaysVisible:
AirstrikePower:
Icon: airstrike
StartFullyCharged: True

View File

@@ -753,6 +753,7 @@ Rules:
Buildable:
Prerequisites: ~disabled
airstrike.proxy:
AlwaysVisible:
AirstrikePower:
Icon: airstrike
StartFullyCharged: True

View File

@@ -162,6 +162,8 @@ C17:
HP: 25
Armor:
Type: Heavy
HiddenUnderFog:
AlwaysVisibleStances: None
WithFacingSpriteBody:
Cargo:
MaxWeight: 10

View File

@@ -367,6 +367,7 @@ BRIDGE4:
SpawnOffset: 3,2
BRIDGEHUT:
HiddenUnderShroud:
Building:
Footprint: __ __
Dimensions: 2,2

View File

@@ -642,6 +642,7 @@
-TargetableUnit:
^Bridge:
HiddenUnderShroud:
Tooltip:
Name: Bridge
TargetableBuilding:
@@ -656,6 +657,7 @@
ScriptTriggers:
^Crate:
HiddenUnderShroud:
Tooltip:
Name: Crate
GenericName: Crate

View File

@@ -31,6 +31,7 @@ CRATE:
Units: mcv
mpspawn:
AlwaysVisible:
Immobile:
OccupiesSpace: false
RenderEditorOnly:
@@ -38,6 +39,7 @@ mpspawn:
BodyOrientation:
waypoint:
AlwaysVisible:
Immobile:
OccupiesSpace: false
RenderEditorOnly:
@@ -51,6 +53,7 @@ waypoint:
Palette: colorpicker
CAMERA:
AlwaysVisible:
Immobile:
OccupiesSpace: false
Health:
@@ -60,6 +63,7 @@ CAMERA:
BodyOrientation:
CAMERA.small:
AlwaysVisible:
Immobile:
OccupiesSpace: false
Health:

View File

@@ -1,4 +1,5 @@
Player:
AlwaysVisible:
PlaceBuilding:
TechTree:
SupportPowerManager:

View File

@@ -938,21 +938,25 @@ BRIK:
Type: concrete
BARRACKS:
AlwaysVisible:
Tooltip:
Name: Infantry Production
Description: Infantry Production
VEHICLEPRODUCTION:
AlwaysVisible:
Tooltip:
Name: Vehicle Production
Description: Vehicle Production
ANYPOWER:
AlwaysVisible:
Tooltip:
Name: Power Plant
Description: Power Plant
ANYHQ:
AlwaysVisible:
Tooltip:
Name: a communications center
Description: a communications center

View File

@@ -1,4 +1,5 @@
^BaseWorld:
AlwaysVisible:
Inherits: ^Palettes
ScreenMap:
ActorMap:

View File

@@ -1,4 +1,5 @@
spicebloom:
HiddenUnderShroud:
RenderBuilding:
Building:
Footprint: x

View File

@@ -278,6 +278,7 @@
TargetTypes: Air
GroundedTargetTypes: Ground
HiddenUnderFog:
AlwaysVisibleStances: None
GivesExperience:
DrawLineToTarget:
ActorLostNotification:

View File

@@ -1,4 +1,5 @@
crate:
HiddenUnderShroud:
Tooltip:
Name: Crate
Crate:
@@ -114,12 +115,14 @@ crate:
CustomBounds: 16,16
mpspawn:
AlwaysVisible:
Immobile:
OccupiesSpace: false
RenderEditorOnly:
BodyOrientation:
waypoint:
AlwaysVisible:
Immobile:
OccupiesSpace: false
RenderEditorOnly:
@@ -136,6 +139,7 @@ waypoint:
Palette: colorpicker
camera:
AlwaysVisible:
Immobile:
OccupiesSpace: false
Health:
@@ -145,6 +149,7 @@ camera:
BodyOrientation:
wormspawner:
AlwaysVisible:
Immobile:
OccupiesSpace: false
RenderEditorOnly:
@@ -152,6 +157,7 @@ wormspawner:
WormSpawner:
upgrade.conyard:
AlwaysVisible:
Tooltip:
Name: Construction Yard Upgrade
Description: Unlocks new construction options
@@ -170,6 +176,7 @@ upgrade.conyard:
ProvidesPrerequisite@upgradename:
upgrade.barracks:
AlwaysVisible:
Tooltip:
Name: Barracks Upgrade
Description: Unlocks additional infantry
@@ -188,6 +195,7 @@ upgrade.barracks:
ProvidesPrerequisite@upgradename:
upgrade.light:
AlwaysVisible:
Tooltip:
Name: Light Factory Upgrade
Description: Unlocks additional light units
@@ -206,6 +214,7 @@ upgrade.light:
ProvidesPrerequisite@upgradename:
upgrade.heavy:
AlwaysVisible:
Tooltip:
Name: Heavy Factory Upgrade
Description: Unlocks advanced technology and heavy weapons
@@ -225,6 +234,7 @@ upgrade.heavy:
ProvidesPrerequisite@upgradename:
upgrade.hightech:
AlwaysVisible:
Tooltip:
Name: High Tech Factory Upgrade
Description: Unlocks the Air Strike superweapon

View File

@@ -1,4 +1,5 @@
Player:
AlwaysVisible:
TechTree:
ClassicProductionQueue@Building:
Type: Building

View File

@@ -1,4 +1,5 @@
^concrete:
AlwaysVisible:
Building:
Adjacent: 4
TerrainTypes: Rock
@@ -493,6 +494,7 @@ starport:
VisualBounds: 96,64
wall:
HiddenUnderShroud:
Buildable:
Queue: Building
Prerequisites: barracks

View File

@@ -1,5 +1,6 @@
^BaseWorld:
Inherits: ^Palettes
AlwaysVisible:
ScreenMap:
ActorMap:
TerrainGeometryOverlay:

View File

@@ -1405,6 +1405,7 @@ Rules:
RenderSprites:
Image: E7
PRISON:
HiddenUnderShroud:
Immobile:
OccupiesSpace: false
BodyOrientation:

View File

@@ -1301,6 +1301,7 @@ Rules:
RenderSprites:
Image: E7
PRISON:
HiddenUnderShroud:
Immobile:
OccupiesSpace: false
BodyOrientation:
@@ -1321,6 +1322,7 @@ Rules:
RevealsShroud:
Range: 40c0
CAMERA.Jeep:
AlwaysVisible:
Mobile:
TerrainSpeeds:
RevealsShroud:

View File

@@ -1622,6 +1622,7 @@ Rules:
Tooltip:
ShowOwnerRow: false
Camera.Truk:
AlwaysVisible:
Mobile:
TerrainSpeeds:
RevealsShroud:
@@ -1674,6 +1675,7 @@ Rules:
CloakDelay: 0
Palette:
CloakUpgrade:
AlwaysVisible:
Immobile:
OccupiesSpace: false
BodyOrientation:

View File

@@ -879,6 +879,7 @@ Rules:
Power:
Amount: 0
MINVV:
HiddenUnderFog:
Building:
Adjacent: 99
TerrainTypes: Clear,Road

View File

@@ -1329,10 +1329,12 @@ Rules:
E7:
-AnnounceOnKill:
powerproxy.paratroopers:
AlwaysVisible:
ParatroopersPower:
DisplayBeacon: false
DropItems: E1,E1,E2,E3,E4
powerproxy.parazombies:
AlwaysVisible:
ParatroopersPower:
DropItems: ZOMBIE,ZOMBIE,ZOMBIE,ZOMBIE,ZOMBIE
QuantizedFacings: 8

View File

@@ -2258,6 +2258,7 @@ Rules:
ProvidesPrerequisite:
Prerequisite: givefix
MAINLAND:
AlwaysVisible:
Tooltip:
Name: Reach the mainland
ProvidesPrerequisite:
@@ -2269,6 +2270,7 @@ Rules:
Buildable:
Prerequisites: givefix
GIVEFIX:
AlwaysVisible:
Tooltip:
Name: Weapons Factory or Helipad
MIG:

View File

@@ -1059,11 +1059,13 @@ Rules:
GenericStancePrefix: false
ShowOwnerRow: false
SovietSquad:
AlwaysVisible:
ParatroopersPower:
DropItems: E1,E1,E2,E4,E4
QuantizedFacings: 8
DisplayBeacon: false
SovietPlatoonUnits:
AlwaysVisible:
ParatroopersPower:
DropItems: E1,E1,E2,E4,E4,E1,E1,E2,E4,E4
QuantizedFacings: 8

View File

@@ -487,6 +487,7 @@ SBRIDGE4:
SpawnOffset: 2,1
BRIDGEHUT:
HiddenUnderShroud:
Building:
Footprint: __ __
Dimensions: 2,2
@@ -497,6 +498,7 @@ BRIDGEHUT:
TargetTypes: BridgeHut, C4
BRIDGEHUT.small:
HiddenUnderShroud:
Building:
Footprint: _
Dimensions: 1,1

View File

@@ -604,6 +604,7 @@
-TransformOnCapture:
^Bridge:
HiddenUnderShroud:
Tooltip:
Name: Bridge
TargetableBuilding:
@@ -653,6 +654,7 @@
RequireTilesets: DESERT
^Crate:
HiddenUnderShroud:
Tooltip:
Name: Crate
GenericName: Crate

View File

@@ -1,4 +1,5 @@
MINP:
HiddenUnderShroud:
Mine:
CrushClasses: mine
DetonateClasses: mine
@@ -27,6 +28,7 @@ MINP:
OccupiesSpace: true
MINV:
HiddenUnderShroud:
Mine:
CrushClasses: mine
DetonateClasses: mine
@@ -165,6 +167,7 @@ HEALCRATE:
Effect: heal
CAMERA:
AlwaysVisible:
Immobile:
OccupiesSpace: false
Health:
@@ -180,6 +183,7 @@ CAMERA:
Image: camera
camera.paradrop:
AlwaysVisible:
Immobile:
OccupiesSpace: false
Health:
@@ -191,6 +195,7 @@ camera.paradrop:
BodyOrientation:
SONAR:
AlwaysVisible:
Immobile:
OccupiesSpace: false
Health:
@@ -220,6 +225,7 @@ FLARE:
BodyOrientation:
MINE:
HiddenUnderShroud:
Tooltip:
Name: Ore Mine
RenderBuilding:
@@ -238,6 +244,7 @@ MINE:
SeedsResource:
GMINE:
HiddenUnderShroud:
Tooltip:
Name: Gem Mine
RenderBuilding:
@@ -257,6 +264,7 @@ GMINE:
ResourceType: Gems
RAILMINE:
HiddenUnderShroud:
Tooltip:
Name: Abandoned Mine
RenderBuilding:
@@ -273,6 +281,7 @@ RAILMINE:
ExcludeTilesets: INTERIOR
QUEE:
HiddenUnderShroud:
Tooltip:
Name: Queen Ant
Building:
@@ -288,6 +297,7 @@ QUEE:
UseTerrainPalette: true
LAR1:
HiddenUnderShroud:
Tooltip:
Name: Ant Larva
Building:
@@ -304,6 +314,7 @@ LAR1:
UseTerrainPalette: true
LAR2:
HiddenUnderShroud:
Tooltip:
Name: Ant Larvae
Building:
@@ -320,6 +331,7 @@ LAR2:
UseTerrainPalette: true
powerproxy.parabombs:
AlwaysVisible:
AirstrikePower:
Icon: parabombs
Description: Parabombs (Single Use)
@@ -334,6 +346,7 @@ powerproxy.parabombs:
CameraActor: camera
powerproxy.sonarpulse:
AlwaysVisible:
SpawnActorPower:
Icon: sonar
Description: Sonar Pulse
@@ -348,6 +361,7 @@ powerproxy.sonarpulse:
EffectPalette: moveflash
powerproxy.paratroopers:
AlwaysVisible:
ParatroopersPower:
Icon: paratroopers
Description: Paratroopers
@@ -361,12 +375,14 @@ powerproxy.paratroopers:
BeaconPoster: pinficon
mpspawn:
AlwaysVisible:
Immobile:
OccupiesSpace: false
RenderEditorOnly:
BodyOrientation:
waypoint:
AlwaysVisible:
Immobile:
OccupiesSpace: false
RenderEditorOnly:

View File

@@ -1,4 +1,5 @@
Player:
AlwaysVisible:
TechTree:
ClassicProductionQueue@Building:
Type: Building

View File

@@ -1617,16 +1617,19 @@ WOOD:
Type: woodfence
BARRACKS:
AlwaysVisible:
Tooltip:
Name: Infantry Production
Description: Infantry Production
TECHCENTER:
AlwaysVisible:
Tooltip:
Name: Tech Center
Description: Tech Center
ANYPOWER:
AlwaysVisible:
Tooltip:
Name: Power Plant
Description: Power Plant

View File

@@ -1,5 +1,6 @@
^BaseWorld:
Inherits: ^Palettes
AlwaysVisible:
ActorMap:
ScreenMap:
TerrainGeometryOverlay:

View File

@@ -127,6 +127,7 @@
RequireTilesets: TEMPERAT
^Crate:
HiddenUnderShroud:
Tooltip:
Name: Crate
Crate:
@@ -140,6 +141,7 @@
CustomBounds: 24,24
^Wall:
HiddenUnderShroud:
AppearsOnRadar:
Building:
Dimensions: 1,1
@@ -184,6 +186,7 @@
MustBeDestroyed:
^BuildingPlug:
AlwaysVisible:
Building:
BuildSounds: place2.aud
KillsSelf:
@@ -534,6 +537,7 @@
WithActiveAnimation:
^Tree:
HiddenUnderShroud:
RenderBuilding:
Palette: terrain
Building:
@@ -545,6 +549,7 @@
Name: Tree
^Rock:
HiddenUnderShroud:
RenderBuilding:
Palette: terrain
Building:
@@ -556,6 +561,7 @@
Name: Rock
^Veinhole:
HiddenUnderShroud:
RadarColorFromTerrain:
Terrain: Tiberium
RenderBuilding:

View File

@@ -1,10 +1,12 @@
mpspawn:
AlwaysVisible:
Immobile:
OccupiesSpace: false
RenderEditorOnly:
BodyOrientation:
waypoint:
AlwaysVisible:
Immobile:
OccupiesSpace: false
RenderEditorOnly:
@@ -26,6 +28,7 @@ waypoint:
Palette: colorpicker
CAMERA:
AlwaysVisible:
Immobile:
OccupiesSpace: false
Health:

View File

@@ -1,4 +1,5 @@
Player:
AlwaysVisible:
TechTree:
ClassicProductionQueue@Building:
Type: Building

View File

@@ -137,26 +137,31 @@ GASILO:
VisualBounds: 80, 48, -5, 0
ANYPOWER:
AlwaysVisible:
Tooltip:
Name: Power Plant
Description: Power Plant
BARRACKS:
AlwaysVisible:
Tooltip:
Name: Infantry Production
Description: Infantry Production
FACTORY:
AlwaysVisible:
Tooltip:
Name: Vehicle Production
Description: Vehicle Production
RADAR:
AlwaysVisible:
Tooltip:
Name: Radar
Description: Radar
TECH:
AlwaysVisible:
Tooltip:
Name: Tech Center
Description: Tech Center

View File

@@ -1,5 +1,6 @@
^BaseWorld:
Inherits: ^Palettes
AlwaysVisible:
ScreenMap:
ActorMap:
LoadWidgetAtGameStart: