Skip to content
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

Add celltrigger support to ProximityCapturable #21123

Merged
merged 4 commits into from Dec 3, 2023

Conversation

obrakmann
Copy link
Contributor

This pull request addresses a long-standing TODO comment in ProximityCapturable about eventually adding celltrigger support.

// from which a border should be drawn. The index of the end corner will be (cornerIndex + 1) % 4.
static readonly Dictionary<CVec, int> Offset2CornerIndex = new()
{
{ new CVec(0, -1), 0 },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider making the index an enum i.e. north, east, south, west. even though it is private.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done (kinda). The index represents corners of a cell, not cardinal directions.

var corners = map.Grid.Ramps[ramp].Corners;
var pos = map.CenterOfCell(c) - new WVec(0, 0, map.Grid.Ramps[ramp].CenterHeightOffset);

foreach (var o in Offset2CornerIndex)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would be no option to calculate the border once during construction of a bordered region and be able to render that as a multi line?

it would be so much cheaper than iterating over all cells in the region and then for each cell checking all four neigbouring cells.

or would the region change? i would imagine celltriggers typically remain at one position of the map? i read below the region is already relative to the offset of the actor.

perhaps have a constant bordered region for actors that cannot move. or a relative bordered region.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would be no option to calculate the border once during construction of a bordered region and be able to render that as a multi line?

I gave that a try, but there's a bunch of problems with that. 1) the shroud check requires that the set of drawn lines gets determined every time they get drawn, 2) you'd have to sort the lines so that the ending vertex of a preceding line matches the starting vertex of the following line. I haven't found a nice way to do this, and it probably wouldn't be any cheaper.

Also, in the end the color renderer just draws a bunch of quads individually anyway, so the gain of drawing a multi-line is probably negligible (I guess, no idea really what's costly in terms of drawing).

or would the region change? i would imagine celltriggers typically remain at one position of the map?

Typically not. I suppose moving actors would normally use a ProximityTrigger. When the actor gets removed and added back to the world, the region could theoretically change, though.

if (region.Contains(c + o.Key))
continue;

var start = wr.Viewport.WorldToViewPx(wr.Screen3DPosition(pos + corners[o.Value]));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check contrastWidth and width prior. to avoid calculating the positions.

the whole render is not needed with both widths are zero?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

using OpenRA.Primitives;
using OpenRA.Traits;

namespace OpenRA.Mods.Common.Traits
{
public enum ProximityCapturableType { Range, Region }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

optional. code would be slightly cleaner if you'd split both types up in two traits. i.e. add RangeProximityCapturable.

as the fields per info are different.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no option for a Region + Range? i guess ActorMap would have to support it too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

optional. code would be slightly cleaner if you'd split both types up in two traits. i.e. add RangeProximityCapturable.

Done.

no option for a Region + Range? i guess ActorMap would have to support it too.

No. That would require two different triggers.

@obrakmann obrakmann force-pushed the more-prox-capturable-improvements2 branch from 515352b to 88c4557 Compare October 29, 2023 11:17
Copy link
Contributor

@anvilvapre anvilvapre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

untested.

would like to propose to get some performance metrics on the impact of drawing the borders but also the impact on updating the actor map at each actor movement. i.e. what if a modder add the trait to many/any actor, at what point does it no longer scale.

@obrakmann
Copy link
Contributor Author

the impact on updating the actor map at each actor movement.

This PR doesn't do that. The call to ActorMap.UpdateProximityTrigger has already been in bleed for years.

@anvilvapre
Copy link
Contributor

the impact on updating the actor map at each actor movement.

This PR doesn't do that. The call to ActorMap.UpdateProximityTrigger has already been in bleed for years.

i know. but this would encourage the use(?).

@obrakmann
Copy link
Contributor Author

Still no :). UpdateProximityTrigger is only called for, well, ProximityTriggers, not for CellTriggers. Those are only set once at the time of creation and then don't need any constant maintenance.

And I don't see how adding one trait would encourage the use of the previously already existing trait.

[Desc("Allowed ProximityCaptor actors to capture this actor.")]
public readonly BitSet<CaptureType> CaptorTypes = new("Player", "Vehicle", "Tank", "Infantry");

[Desc("If set, the capturing process stops immediately after another player comes into Range.")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the capitialized Range?

{
var pci = rules.Actors[SystemActors.Player].TraitInfoOrDefault<ProximityCaptorInfo>();
if (pci == null)
throw new YamlException("ProximityCapturableBase requires the `Player` actor to have the ProximityCaptor trait.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider applying nameof.

[Desc("Actor can be captured by units in a specified proximity.")]
public abstract class ProximityCapturableBaseInfo : TraitInfo, IRulesetLoaded
{
[Desc("Allowed ProximityCaptor actors to capture this actor.")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider applying nameof.

public readonly bool Sticky = false;

[Desc("If set, the actor can only be captured via this logic once.",
"This option implies the `Sticky` behaviour as well.")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider applying nameof.

if (!self.IsInWorld || !Info.DrawDecoration)
yield break;

yield return GetRenderable(self, wr);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (!self.IsInWorld || !Info.DrawDecoration)
	return Enumerable.Empty<IRenderable>();

return new[] { GetRenderable(self, wr); }

Minor, but avoids allocating an enumerable if we don't want to draw decorations.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

{
[Desc("Set of cell offsets (relative to the actor's Location) the ProximityCaptor needs to be in to initiate the capture. ",
"A 'Region' ActorInit can be used to override this value per actor. If either is empty or non-existent, ",
"the immediately neighboring cells of the actor will be used.")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider applying nameof.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, except for the ActorInit. It would say "RegionInit" and I suppose that would confuse modders (ie. they'd try adding "RegionInit" to the yaml instead of just "Region".

@anvilvapre
Copy link
Contributor

Still no :). UpdateProximityTrigger is only called for, well, ProximityTriggers, not for CellTriggers. Those are only set once at the time of creation and then don't need any constant maintenance.

And I don't see how adding one trait would encourage the use of the previously already existing trait.

I was thinking about ActorMap.ProximityTrigger.Tick being called more often.

@obrakmann obrakmann force-pushed the more-prox-capturable-improvements2 branch from 88c4557 to 58173aa Compare November 5, 2023 18:14
@obrakmann obrakmann force-pushed the more-prox-capturable-improvements2 branch from 58173aa to a73dfda Compare November 5, 2023 18:25
@obrakmann
Copy link
Contributor Author

I was thinking about ActorMap.ProximityTrigger.Tick being called more often.

Again, this is adding CellTrigger support. ProximityCapturable has been using ProximityTriggers since 2015, and this PR does not change that. This PR does not cause ActorMap.ProximityTrigger.Tick to be called more often.

@obrakmann obrakmann force-pushed the more-prox-capturable-improvements2 branch from a73dfda to 3889e4c Compare November 7, 2023 17:05
@obrakmann
Copy link
Contributor Author

Removed testcase commit

@pchote pchote merged commit 3904576 into OpenRA:bleed Dec 3, 2023
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants