Calculate building placement offsets in screen space.
This commit is contained in:
committed by
Oliver Brakmann
parent
0161d68237
commit
0f6dda3f5f
@@ -26,8 +26,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
readonly EditorActorLayer editorLayer;
|
||||
readonly EditorViewportControllerWidget editorWidget;
|
||||
readonly ActorPreviewWidget preview;
|
||||
readonly CVec locationOffset;
|
||||
readonly WVec previewOffset;
|
||||
readonly WVec centerOffset;
|
||||
readonly PlayerReference owner;
|
||||
readonly CVec[] footprint;
|
||||
|
||||
@@ -49,10 +48,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
|
||||
var buildingInfo = actor.TraitInfoOrDefault<BuildingInfo>();
|
||||
if (buildingInfo != null)
|
||||
{
|
||||
locationOffset = -buildingInfo.LocationOffset();
|
||||
previewOffset = buildingInfo.CenterOffset(world);
|
||||
}
|
||||
centerOffset = buildingInfo.CenterOffset(world);
|
||||
|
||||
var td = new TypeDictionary();
|
||||
td.Add(new FacingInit(facing));
|
||||
@@ -91,17 +87,16 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
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)
|
||||
{
|
||||
// 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;
|
||||
|
||||
var newActorReference = new ActorReference(Actor.Name);
|
||||
newActorReference.Add(new OwnerInit(owner.Name));
|
||||
|
||||
cell += locationOffset;
|
||||
newActorReference.Add(new LocationInit(cell));
|
||||
|
||||
var ios = Actor.TraitInfoOrDefault<IOccupySpaceInfo>();
|
||||
@@ -128,8 +123,8 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
|
||||
public void Tick()
|
||||
{
|
||||
var cell = worldRenderer.Viewport.ViewToWorld(Viewport.LastMousePos);
|
||||
var pos = world.Map.CenterOfCell(cell + locationOffset) + previewOffset;
|
||||
var cell = worldRenderer.Viewport.ViewToWorld(Viewport.LastMousePos - worldRenderer.ScreenPxOffset(centerOffset));
|
||||
var pos = world.Map.CenterOfCell(cell) + centerOffset;
|
||||
|
||||
var origin = worldRenderer.Viewport.WorldToViewPx(worldRenderer.ScreenPxPosition(pos));
|
||||
|
||||
|
||||
@@ -33,14 +33,18 @@ namespace OpenRA.Mods.Common.Orders
|
||||
readonly string faction;
|
||||
readonly Sprite buildOk;
|
||||
readonly Sprite buildBlocked;
|
||||
readonly Viewport viewport;
|
||||
readonly WVec centerOffset;
|
||||
readonly int2 topLeftScreenOffset;
|
||||
IActorPreview[] preview;
|
||||
|
||||
bool initialized;
|
||||
|
||||
public PlaceBuildingOrderGenerator(ProductionQueue queue, string name)
|
||||
public PlaceBuildingOrderGenerator(ProductionQueue queue, string name, WorldRenderer worldRenderer)
|
||||
{
|
||||
var world = queue.Actor.World;
|
||||
this.queue = queue;
|
||||
viewport = worldRenderer.Viewport;
|
||||
placeBuildingInfo = queue.Actor.Owner.PlayerActor.Info.TraitInfo<PlaceBuildingInfo>();
|
||||
building = name;
|
||||
|
||||
@@ -53,6 +57,8 @@ namespace OpenRA.Mods.Common.Orders
|
||||
|
||||
var info = map.Rules.Actors[building];
|
||||
buildingInfo = info.TraitInfo<BuildingInfo>();
|
||||
centerOffset = buildingInfo.CenterOffset(world);
|
||||
topLeftScreenOffset = -worldRenderer.ScreenPxOffset(centerOffset);
|
||||
|
||||
var buildableInfo = info.TraitInfo<BuildableInfo>();
|
||||
var mostLikelyProducer = queue.MostLikelyProducer();
|
||||
@@ -99,7 +105,7 @@ namespace OpenRA.Mods.Common.Orders
|
||||
if (mi.Button == MouseButton.Left)
|
||||
{
|
||||
var orderType = "PlaceBuilding";
|
||||
var topLeft = cell - buildingInfo.LocationOffset();
|
||||
var topLeft = viewport.ViewToWorld(Viewport.LastMousePos + topLeftScreenOffset);
|
||||
|
||||
var plugInfo = world.Map.Rules.Actors[building].TraitInfoOrDefault<PlugInfo>();
|
||||
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> RenderAboveShroud(WorldRenderer wr, World world)
|
||||
{
|
||||
var xy = wr.Viewport.ViewToWorld(Viewport.LastMousePos);
|
||||
var topLeft = xy - buildingInfo.LocationOffset();
|
||||
var offset = world.Map.CenterOfCell(topLeft) + buildingInfo.CenterOffset(world);
|
||||
var topLeft = viewport.ViewToWorld(Viewport.LastMousePos + topLeftScreenOffset);
|
||||
var centerPosition = world.Map.CenterOfCell(topLeft) + centerOffset;
|
||||
var rules = world.Map.Rules;
|
||||
|
||||
var actorInfo = rules.Actors[building];
|
||||
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;
|
||||
|
||||
var cells = new Dictionary<CPos, CellType>();
|
||||
@@ -219,7 +224,7 @@ namespace OpenRA.Mods.Common.Orders
|
||||
}
|
||||
|
||||
var previewRenderables = preview
|
||||
.SelectMany(p => p.Render(wr, offset))
|
||||
.SelectMany(p => p.Render(wr, centerPosition))
|
||||
.OrderBy(WorldRenderer.RenderableScreenZPositionComparisonKey);
|
||||
|
||||
foreach (var r in previewRenderables)
|
||||
|
||||
@@ -144,11 +144,6 @@ namespace OpenRA.Mods.Common.Traits
|
||||
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)
|
||||
{
|
||||
var off = (w.Map.CenterOfCell(new CPos(Dimensions.X, Dimensions.Y)) - w.Map.CenterOfCell(new CPos(1, 1))) / 2;
|
||||
|
||||
@@ -200,7 +200,7 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user