Calculate building placement offsets in screen space.

This commit is contained in:
Paul Chote
2017-09-10 11:09:18 +00:00
committed by Oliver Brakmann
parent 0161d68237
commit 0f6dda3f5f
4 changed files with 19 additions and 24 deletions

View File

@@ -26,8 +26,7 @@ namespace OpenRA.Mods.Common.Widgets
readonly EditorActorLayer editorLayer; readonly EditorActorLayer editorLayer;
readonly EditorViewportControllerWidget editorWidget; readonly EditorViewportControllerWidget editorWidget;
readonly ActorPreviewWidget preview; readonly ActorPreviewWidget preview;
readonly CVec locationOffset; readonly WVec centerOffset;
readonly WVec previewOffset;
readonly PlayerReference owner; readonly PlayerReference owner;
readonly CVec[] footprint; readonly CVec[] footprint;
@@ -49,10 +48,7 @@ namespace OpenRA.Mods.Common.Widgets
var buildingInfo = actor.TraitInfoOrDefault<BuildingInfo>(); var buildingInfo = actor.TraitInfoOrDefault<BuildingInfo>();
if (buildingInfo != null) if (buildingInfo != null)
{ centerOffset = buildingInfo.CenterOffset(world);
locationOffset = -buildingInfo.LocationOffset();
previewOffset = buildingInfo.CenterOffset(world);
}
var td = new TypeDictionary(); var td = new TypeDictionary();
td.Add(new FacingInit(facing)); td.Add(new FacingInit(facing));
@@ -91,17 +87,16 @@ namespace OpenRA.Mods.Common.Widgets
return false; return false;
} }
var cell = worldRenderer.Viewport.ViewToWorld(mi.Location); var cell = worldRenderer.Viewport.ViewToWorld(mi.Location - worldRenderer.ScreenPxOffset(centerOffset));
if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Down) if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Down)
{ {
// Check the actor is inside the map // Check the actor is inside the map
if (!footprint.All(c => world.Map.Tiles.Contains(cell + locationOffset + c))) if (!footprint.All(c => world.Map.Tiles.Contains(cell + c)))
return true; return true;
var newActorReference = new ActorReference(Actor.Name); var newActorReference = new ActorReference(Actor.Name);
newActorReference.Add(new OwnerInit(owner.Name)); newActorReference.Add(new OwnerInit(owner.Name));
cell += locationOffset;
newActorReference.Add(new LocationInit(cell)); newActorReference.Add(new LocationInit(cell));
var ios = Actor.TraitInfoOrDefault<IOccupySpaceInfo>(); var ios = Actor.TraitInfoOrDefault<IOccupySpaceInfo>();
@@ -128,8 +123,8 @@ namespace OpenRA.Mods.Common.Widgets
public void Tick() public void Tick()
{ {
var cell = worldRenderer.Viewport.ViewToWorld(Viewport.LastMousePos); var cell = worldRenderer.Viewport.ViewToWorld(Viewport.LastMousePos - worldRenderer.ScreenPxOffset(centerOffset));
var pos = world.Map.CenterOfCell(cell + locationOffset) + previewOffset; var pos = world.Map.CenterOfCell(cell) + centerOffset;
var origin = worldRenderer.Viewport.WorldToViewPx(worldRenderer.ScreenPxPosition(pos)); var origin = worldRenderer.Viewport.WorldToViewPx(worldRenderer.ScreenPxPosition(pos));

View File

@@ -33,14 +33,18 @@ namespace OpenRA.Mods.Common.Orders
readonly string faction; readonly string faction;
readonly Sprite buildOk; readonly Sprite buildOk;
readonly Sprite buildBlocked; readonly Sprite buildBlocked;
readonly Viewport viewport;
readonly WVec centerOffset;
readonly int2 topLeftScreenOffset;
IActorPreview[] preview; IActorPreview[] preview;
bool initialized; bool initialized;
public PlaceBuildingOrderGenerator(ProductionQueue queue, string name) public PlaceBuildingOrderGenerator(ProductionQueue queue, string name, WorldRenderer worldRenderer)
{ {
var world = queue.Actor.World; var world = queue.Actor.World;
this.queue = queue; this.queue = queue;
viewport = worldRenderer.Viewport;
placeBuildingInfo = queue.Actor.Owner.PlayerActor.Info.TraitInfo<PlaceBuildingInfo>(); placeBuildingInfo = queue.Actor.Owner.PlayerActor.Info.TraitInfo<PlaceBuildingInfo>();
building = name; building = name;
@@ -53,6 +57,8 @@ namespace OpenRA.Mods.Common.Orders
var info = map.Rules.Actors[building]; var info = map.Rules.Actors[building];
buildingInfo = info.TraitInfo<BuildingInfo>(); buildingInfo = info.TraitInfo<BuildingInfo>();
centerOffset = buildingInfo.CenterOffset(world);
topLeftScreenOffset = -worldRenderer.ScreenPxOffset(centerOffset);
var buildableInfo = info.TraitInfo<BuildableInfo>(); var buildableInfo = info.TraitInfo<BuildableInfo>();
var mostLikelyProducer = queue.MostLikelyProducer(); var mostLikelyProducer = queue.MostLikelyProducer();
@@ -99,7 +105,7 @@ namespace OpenRA.Mods.Common.Orders
if (mi.Button == MouseButton.Left) if (mi.Button == MouseButton.Left)
{ {
var orderType = "PlaceBuilding"; var orderType = "PlaceBuilding";
var topLeft = cell - buildingInfo.LocationOffset(); var topLeft = viewport.ViewToWorld(Viewport.LastMousePos + topLeftScreenOffset);
var plugInfo = world.Map.Rules.Actors[building].TraitInfoOrDefault<PlugInfo>(); var plugInfo = world.Map.Rules.Actors[building].TraitInfoOrDefault<PlugInfo>();
if (plugInfo != null) if (plugInfo != null)
@@ -162,14 +168,13 @@ namespace OpenRA.Mods.Common.Orders
public IEnumerable<IRenderable> Render(WorldRenderer wr, World world) { yield break; } public IEnumerable<IRenderable> Render(WorldRenderer wr, World world) { yield break; }
public IEnumerable<IRenderable> RenderAboveShroud(WorldRenderer wr, World world) public IEnumerable<IRenderable> RenderAboveShroud(WorldRenderer wr, World world)
{ {
var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos); var topLeft = viewport.ViewToWorld(Viewport.LastMousePos + topLeftScreenOffset);
var topLeft = xy - buildingInfo.LocationOffset(); var centerPosition = world.Map.CenterOfCell(topLeft) + centerOffset;
var offset = world.Map.CenterOfCell(topLeft) + buildingInfo.CenterOffset(world);
var rules = world.Map.Rules; var rules = world.Map.Rules;
var actorInfo = rules.Actors[building]; var actorInfo = rules.Actors[building];
foreach (var dec in actorInfo.TraitInfos<IPlaceBuildingDecorationInfo>()) foreach (var dec in actorInfo.TraitInfos<IPlaceBuildingDecorationInfo>())
foreach (var r in dec.Render(wr, world, actorInfo, offset)) foreach (var r in dec.Render(wr, world, actorInfo, centerPosition))
yield return r; yield return r;
var cells = new Dictionary<CPos, CellType>(); var cells = new Dictionary<CPos, CellType>();
@@ -219,7 +224,7 @@ namespace OpenRA.Mods.Common.Orders
} }
var previewRenderables = preview var previewRenderables = preview
.SelectMany(p => p.Render(wr, offset)) .SelectMany(p => p.Render(wr, centerPosition))
.OrderBy(WorldRenderer.RenderableScreenZPositionComparisonKey); .OrderBy(WorldRenderer.RenderableScreenZPositionComparisonKey);
foreach (var r in previewRenderables) foreach (var r in previewRenderables)

View File

@@ -144,11 +144,6 @@ namespace OpenRA.Mods.Common.Traits
yield return t; yield return t;
} }
public CVec LocationOffset()
{
return new CVec(Dimensions.X / 2, Dimensions.Y > 1 ? (Dimensions.Y + 1) / 2 : 0);
}
public WVec CenterOffset(World w) public WVec CenterOffset(World w)
{ {
var off = (w.Map.CenterOfCell(new CPos(Dimensions.X, Dimensions.Y)) - w.Map.CenterOfCell(new CPos(1, 1))) / 2; var off = (w.Map.CenterOfCell(new CPos(Dimensions.X, Dimensions.Y)) - w.Map.CenterOfCell(new CPos(1, 1))) / 2;

View File

@@ -200,7 +200,7 @@ namespace OpenRA.Mods.Common.Widgets
if (item != null && item.Done && actor.HasTraitInfo<BuildingInfo>()) if (item != null && item.Done && actor.HasTraitInfo<BuildingInfo>())
{ {
World.OrderGenerator = new PlaceBuildingOrderGenerator(CurrentQueue, icon.Name); World.OrderGenerator = new PlaceBuildingOrderGenerator(CurrentQueue, icon.Name, worldRenderer);
return true; return true;
} }