Additionally, internally renamed VisualBounds to SelectionOverlayBounds to avoid confusion with RenderBounds. This step was necessary to prevent actors with selectable area smaller than their graphics to be removed too early from ScreenMap even though part of the graphics should still be visible. RA cruisers were a prime example, but to a lesser extent several other actors were affected as well. This separation also serves as preparation to determine the final RenderBounds from multiple source bounds later, to fix the remaining ScreenMap issues (building 'bibs', aircraft shadows).
74 lines
2.3 KiB
C#
74 lines
2.3 KiB
C#
#region Copyright & License Information
|
|
/*
|
|
* Copyright 2007-2017 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.Collections.Generic;
|
|
using OpenRA.Primitives;
|
|
using OpenRA.Traits;
|
|
|
|
namespace OpenRA.Mods.Common.Traits
|
|
{
|
|
class ImmobileInfo : ITraitInfo, IOccupySpaceInfo
|
|
{
|
|
public readonly bool OccupiesSpace = true;
|
|
public object Create(ActorInitializer init) { return new Immobile(init, this); }
|
|
|
|
public IReadOnlyDictionary<CPos, SubCell> OccupiedCells(ActorInfo info, CPos location, SubCell subCell = SubCell.Any)
|
|
{
|
|
var occupied = OccupiesSpace ? new Dictionary<CPos, SubCell>() { { location, SubCell.FullCell } } :
|
|
new Dictionary<CPos, SubCell>();
|
|
|
|
return new ReadOnlyDictionary<CPos, SubCell>(occupied);
|
|
}
|
|
|
|
bool IOccupySpaceInfo.SharesCell { get { return false; } }
|
|
}
|
|
|
|
class Immobile : IOccupySpace, ISync, INotifyAddedToWorld, INotifyRemovedFromWorld
|
|
{
|
|
[Sync] readonly CPos location;
|
|
[Sync] readonly WPos position;
|
|
readonly IEnumerable<Pair<CPos, SubCell>> occupied;
|
|
|
|
public Immobile(ActorInitializer init, ImmobileInfo info)
|
|
{
|
|
location = init.Get<LocationInit, CPos>();
|
|
position = init.World.Map.CenterOfCell(location);
|
|
|
|
if (info.OccupiesSpace)
|
|
occupied = new[] { Pair.New(TopLeft, SubCell.FullCell) };
|
|
else
|
|
occupied = new Pair<CPos, SubCell>[0];
|
|
}
|
|
|
|
public CPos TopLeft { get { return location; } }
|
|
public WPos CenterPosition { get { return position; } }
|
|
public IEnumerable<Pair<CPos, SubCell>> OccupiedCells() { return occupied; }
|
|
|
|
void INotifyAddedToWorld.AddedToWorld(Actor self)
|
|
{
|
|
self.World.ActorMap.AddInfluence(self, this);
|
|
self.World.ActorMap.AddPosition(self, this);
|
|
|
|
if (!self.RenderBounds.Size.IsEmpty)
|
|
self.World.ScreenMap.Add(self);
|
|
}
|
|
|
|
void INotifyRemovedFromWorld.RemovedFromWorld(Actor self)
|
|
{
|
|
self.World.ActorMap.RemoveInfluence(self, this);
|
|
self.World.ActorMap.RemovePosition(self, this);
|
|
|
|
if (!self.RenderBounds.Size.IsEmpty)
|
|
self.World.ScreenMap.Remove(self);
|
|
}
|
|
}
|
|
}
|