-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make gap generators work when shroud is disabled. #7665
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#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.Linq; | ||
|
||
namespace OpenRA.Traits | ||
{ | ||
[Desc("Removes frozen actors and satellite icons from fog, prevents auto-target. Requires fog enabled.")] | ||
public class CreatesDisruptionFieldInfo : ITraitInfo | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a |
||
{ | ||
public readonly WRange Range = WRange.Zero; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a |
||
|
||
public object Create(ActorInitializer init) { return new CreatesDisruptionField(init.Self, this); } | ||
} | ||
|
||
public class CreatesDisruptionField : ITick, ISync | ||
{ | ||
public WRange Range { get { return cachedDisabled ? WRange.Zero : info.Range; } } | ||
readonly CreatesDisruptionFieldInfo info; | ||
readonly bool lobbyFogDisabled; | ||
[Sync] CPos cachedLocation; | ||
[Sync] bool cachedDisabled; | ||
|
||
public CreatesDisruptionField(Actor self, CreatesDisruptionFieldInfo info) | ||
{ | ||
this.info = info; | ||
lobbyFogDisabled = !self.World.LobbyInfo.GlobalSettings.Fog; | ||
} | ||
|
||
public void Tick(Actor self) | ||
{ | ||
if (lobbyFogDisabled) | ||
return; | ||
|
||
var disabled = self.IsDisabled(); | ||
if (cachedLocation != self.Location || cachedDisabled != disabled) | ||
{ | ||
cachedLocation = self.Location; | ||
cachedDisabled = disabled; | ||
Shroud.UpdateDisruptionGenerator(self.World.Players.Select(p => p.Shroud), self); | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ | |
|
||
namespace OpenRA.Traits | ||
{ | ||
[Desc("Generates shroud, prevents auto-target. Overridden by CreatesDisruptionField if fog is enabled.")] | ||
public class CreatesShroudInfo : ITraitInfo | ||
{ | ||
public readonly WRange Range = WRange.Zero; | ||
|
@@ -21,31 +22,30 @@ public class CreatesShroudInfo : ITraitInfo | |
|
||
public class CreatesShroud : ITick, ISync | ||
{ | ||
public WRange Range { get { return cachedDisabled ? WRange.Zero : info.Range; } } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why did you move this line? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because Phrohdoh told me to. "This should go above all methods and private members." There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. He does have a point. Properties usually go before methods. |
||
readonly CreatesShroudInfo info; | ||
readonly bool lobbyShroudFogDisabled; | ||
readonly bool lobbyShroudDisabled; | ||
[Sync] CPos cachedLocation; | ||
[Sync] bool cachedDisabled; | ||
|
||
public CreatesShroud(Actor self, CreatesShroudInfo info) | ||
{ | ||
this.info = info; | ||
lobbyShroudFogDisabled = !self.World.LobbyInfo.GlobalSettings.Shroud && !self.World.LobbyInfo.GlobalSettings.Fog; | ||
lobbyShroudDisabled = !self.World.LobbyInfo.GlobalSettings.Shroud; | ||
} | ||
|
||
public void Tick(Actor self) | ||
{ | ||
if (lobbyShroudFogDisabled) | ||
if (lobbyShroudDisabled) | ||
return; | ||
|
||
var disabled = self.IsDisabled(); | ||
if (cachedLocation != self.Location || cachedDisabled != disabled) | ||
{ | ||
cachedLocation = self.Location; | ||
cachedDisabled = disabled; | ||
Shroud.UpdateShroudGeneration(self.World.Players.Select(p => p.Shroud), self); | ||
Shroud.UpdateShroudGenerator(self.World.Players.Select(p => p.Shroud), self); | ||
} | ||
} | ||
|
||
public WRange Range { get { return cachedDisabled ? WRange.Zero : info.Range; } } | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ | |
using System.Drawing; | ||
using System.Linq; | ||
using OpenRA.Graphics; | ||
using OpenRA.Primitives; | ||
|
||
namespace OpenRA.Traits | ||
{ | ||
|
@@ -25,6 +26,7 @@ public class FrozenActorLayerInfo : ITraitInfo | |
public class FrozenActor | ||
{ | ||
public readonly MPos[] Footprint; | ||
public readonly CPos[] OccCells; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that's for Occupied Cells. But there already is a method called OccupiedCells() so I wanted to give this a different name to avoid confusion. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This sounds like duplication then. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But that method cannot be used if the actor is null. A frozen actor can exist even after its actor is destroyed. The actor's occupied cells have to be stored in the frozen actor so that they can be used even if the actor is null. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That is what the Footprint above is for. Use that instead. |
||
public readonly WPos CenterPosition; | ||
public readonly Rectangle Bounds; | ||
readonly Actor actor; | ||
|
@@ -37,9 +39,7 @@ public class FrozenActor | |
|
||
public int HP; | ||
public DamageState DamageState; | ||
|
||
public bool Visible; | ||
|
||
public bool IsRendering { get; private set; } | ||
|
||
public FrozenActor(Actor self, MPos[] footprint, CellRegion footprintRegion, Shroud shroud) | ||
|
@@ -48,6 +48,7 @@ public FrozenActor(Actor self, MPos[] footprint, CellRegion footprintRegion, Shr | |
isVisibleTest = shroud.IsVisibleTest(footprintRegion); | ||
|
||
Footprint = footprint; | ||
OccCells = Shroud.GetVisOrigins(actor).ToArray(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should I use "OccCells = self.OccupiesSpace.OccupiedCells().Select(c => c.First).ToArray();" instead of this line? Do I need the checks in GetVisOrigins()? |
||
CenterPosition = self.CenterPosition; | ||
Bounds = self.Bounds; | ||
|
||
|
@@ -64,6 +65,8 @@ public FrozenActor(Actor self, MPos[] footprint, CellRegion footprintRegion, Shr | |
int flashTicks; | ||
IRenderable[] renderables = NoRenderables; | ||
bool needRenderables; | ||
DamageState DamageStateCached; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These are private, so should the naming needs to be camelCase. |
||
Player OwnerCached; | ||
|
||
public void Tick() | ||
{ | ||
|
@@ -98,23 +101,22 @@ public void Flash() | |
|
||
public IEnumerable<IRenderable> Render(WorldRenderer wr) | ||
{ | ||
if (needRenderables) | ||
if (needRenderables && (renderables == NoRenderables || DamageStateCached != DamageState || OwnerCached != Owner)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These extra checks don't look right to me. if needRenderables is true, then I would expect it to generate renderables. If there is some condition where you don't want it to generate renderables, then those conditions should be applied at the point that variable is set. |
||
{ | ||
needRenderables = false; | ||
if (!actor.Destroyed) | ||
{ | ||
IsRendering = true; | ||
renderables = actor.Render(wr).ToArray(); | ||
IsRendering = false; | ||
} | ||
IsRendering = true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please only use the ActorPreview if |
||
var td = new TypeDictionary() { new HealthInit((float)(HP / 1000.0)) }; | ||
var previewInit = new ActorPreviewInitializer(Info, Owner, wr, td); | ||
var preview = Info.Traits.WithInterface<IRenderActorPreviewInfo>().SelectMany(rpi => rpi.RenderPreview(previewInit)); | ||
renderables = preview.SelectMany(p => p.Render(wr, CenterPosition)).ToArray(); | ||
IsRendering = false; | ||
|
||
DamageStateCached = DamageState; | ||
OwnerCached = Owner; | ||
} | ||
|
||
if (flashTicks > 0 && flashTicks % 2 == 0) | ||
{ | ||
var highlight = wr.Palette("highlight"); | ||
return renderables.Concat(renderables.Where(r => !r.IsDecoration) | ||
.Select(r => r.WithPalette(highlight))); | ||
} | ||
.Select(r => r.WithPalette(wr.Palette("highlight")))); | ||
|
||
return renderables; | ||
} | ||
|
@@ -179,7 +181,7 @@ public void Tick(Actor self) | |
public virtual IEnumerable<IRenderable> Render(Actor self, WorldRenderer wr) | ||
{ | ||
return world.ScreenMap.FrozenActorsInBox(owner, wr.Viewport.TopLeft, wr.Viewport.BottomRight) | ||
.Where(f => f.Visible) | ||
.Where(f => f.Visible && !owner.Shroud.IsUnderDisruptionField(f.OccCells)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Like I mentioned above, your disruption checks should be built into |
||
.SelectMany(ff => ff.Render(wr)); | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Requiring an explicit check for IsUnderDisruptionField here is a sign that the existing code is bogus. This code (from before your changes) should have been filtering out FrozenActors that aren't visible, and your changes should have just worked (because it should be making FrozenActors.Visible -> false). Please fix this properly by adding a filter on Visible instead of hacking in a disruption check in these places.