By tracking updates on the ActorMap the HierarchicalPathFinder can be aware of actors moving around the map. We track a subset of immovable actors that always block. These actors can be treated as impassable obstacles just like terrain. When a path needs to be found the abstract path will guide the search around this subset of immovable actors just like it can guide the search around impassable terrain. For path searches that were previously imperformant because some immovable actors created a bottleneck that needed to be routed around, these will now be performant instead. Path searches with bottlenecks created by items such as trees, walls and buildings should see a performance improvement. Bottlenecks created by other units will not benefit. We now maintain two sets of HPFs. One is aware of immovable actors and will be used for path searches that request BlockedByActor.Immovable, BlockedByActor.Stationary and BlockedByActor.All to guide that around the immovable obstacles. The other is aware of terrain only and will be used for searches that request BlockedByActor.None, or if an ignoreActor is provided. A new UI dropdown when using the `/hpf` command will allow switching between the visuals of the two sets.
65 lines
2.2 KiB
C#
65 lines
2.2 KiB
C#
#region Copyright & License Information
|
|
/*
|
|
* Copyright 2007-2022 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, either version 3 of
|
|
* the License, or (at your option) any later version. For more
|
|
* information, see COPYING.
|
|
*/
|
|
#endregion
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using OpenRA.Mods.Common.Traits;
|
|
using OpenRA.Widgets;
|
|
|
|
namespace OpenRA.Mods.Common.Widgets.Logic
|
|
{
|
|
public class HierarchicalPathFinderOverlayLogic : ChromeLogic
|
|
{
|
|
[ObjectCreator.UseCtor]
|
|
public HierarchicalPathFinderOverlayLogic(Widget widget, World world)
|
|
{
|
|
var hpfOverlay = world.WorldActor.Trait<HierarchicalPathFinderOverlay>();
|
|
widget.IsVisible = () => hpfOverlay.Enabled;
|
|
|
|
var locomotors = new Locomotor[] { null }.Concat(
|
|
world.WorldActor.TraitsImplementing<Locomotor>().OrderBy(l => l.Info.Name))
|
|
.ToArray();
|
|
var locomotorSelector = widget.Get<DropDownButtonWidget>("HPF_OVERLAY_LOCOMOTOR");
|
|
locomotorSelector.OnMouseDown = _ =>
|
|
{
|
|
Func<Locomotor, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
|
|
{
|
|
var item = ScrollItemWidget.Setup(
|
|
template,
|
|
() => hpfOverlay.Locomotor == option,
|
|
() => hpfOverlay.Locomotor = option);
|
|
item.Get<LabelWidget>("LABEL").GetText = () => option?.Info.Name ?? "(Selected Units)";
|
|
return item;
|
|
};
|
|
|
|
locomotorSelector.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", locomotors.Length * 30, locomotors, setupItem);
|
|
};
|
|
|
|
var checks = new[] { BlockedByActor.None, BlockedByActor.Immovable };
|
|
var checkSelector = widget.Get<DropDownButtonWidget>("HPF_OVERLAY_CHECK");
|
|
checkSelector.OnMouseDown = _ =>
|
|
{
|
|
Func<BlockedByActor, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
|
|
{
|
|
var item = ScrollItemWidget.Setup(
|
|
template,
|
|
() => hpfOverlay.Check == option,
|
|
() => hpfOverlay.Check = option);
|
|
item.Get<LabelWidget>("LABEL").GetText = () => option.ToString();
|
|
return item;
|
|
};
|
|
|
|
checkSelector.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", checks.Length * 30, checks, setupItem);
|
|
};
|
|
}
|
|
}
|
|
}
|