Items with no size act unexpectedly as they can fail to be returned when querying partition bins as they do not intersect along the top or left edges of the bin. We prevent such items being added in the first place to avoid this scenario. As a side effect - we must now prevent any Immobile items that do not have size from being added to the screen map.
73 lines
2.1 KiB
C#
73 lines
2.1 KiB
C#
#region Copyright & License Information
|
|
/*
|
|
* Copyright 2007-2015 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. 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; }
|
|
|
|
public void AddedToWorld(Actor self)
|
|
{
|
|
self.World.ActorMap.AddInfluence(self, this);
|
|
self.World.ActorMap.AddPosition(self, this);
|
|
|
|
if (!self.Bounds.Size.IsEmpty)
|
|
self.World.ScreenMap.Add(self);
|
|
}
|
|
|
|
public void RemovedFromWorld(Actor self)
|
|
{
|
|
self.World.ActorMap.RemoveInfluence(self, this);
|
|
self.World.ActorMap.RemovePosition(self, this);
|
|
|
|
if (!self.Bounds.Size.IsEmpty)
|
|
self.World.ScreenMap.Remove(self);
|
|
}
|
|
}
|
|
}
|