public Building(ActorInitializer init, BuildingInfo info) { self = init.Self; topLeft = init.GetValue <LocationInit, CPos>(); Info = info; influence = self.World.WorldActor.Trait <BuildingInfluence>(); occupiedCells = Info.OccupiedTiles(TopLeft) .Select(c => Pair.New(c, SubCell.FullCell)).ToArray(); targetableCells = Info.FootprintTiles(TopLeft, FootprintCellType.Occupied) .Select(c => Pair.New(c, SubCell.FullCell)).ToArray(); transitOnlyCells = Info.TransitOnlyTiles(TopLeft).ToArray(); CenterPosition = init.World.Map.CenterOfCell(topLeft) + Info.CenterOffset(init.World); }
void INotifyKilled.Killed(Actor self, AttackInfo e) { if (IsTraitDisabled || !self.IsInWorld) { return; } if (self.World.SharedRandom.Next(100) > Info.Chance) { return; } if (!Info.DeathTypes.IsEmpty && !e.Damage.DamageTypes.Overlaps(Info.DeathTypes)) { return; } var weapon = ChooseWeaponForExplosion(self); if (weapon == null) { return; } var source = Info.DamageSource == DamageSource.Self ? self : e.Attacker; if (weapon.Report != null && weapon.Report.Any()) { Game.Sound.Play(SoundType.World, weapon.Report, self.World, self.CenterPosition); } if (Info.Type == ExplosionType.Footprint && buildingInfo != null) { var cells = buildingInfo.OccupiedTiles(self.Location); foreach (var c in cells) { weapon.Impact(Target.FromPos(self.World.Map.CenterOfCell(c)), source); } return; } // Use .FromPos since this actor is killed. Cannot use Target.FromActor weapon.Impact(Target.FromPos(self.CenterPosition), source); }
Polygon Bounds(Actor self, WorldRenderer wr, int[] bounds, int height) { int2 left, right, top, bottom; if (bounds != null) { // Convert from WDist to pixels var offset = bounds.Length >= 4 ? new int2(bounds[2] * wr.TileSize.Width / wr.TileScale, bounds[3] * wr.TileSize.Height / wr.TileScale) : int2.Zero; var center = wr.ScreenPxPosition(self.CenterPosition) + offset; left = center - new int2(bounds[0] * wr.TileSize.Width / (2 * wr.TileScale), 0); right = left + new int2(bounds[0] * wr.TileSize.Width / wr.TileScale, 0); top = center - new int2(0, bounds[1] * wr.TileSize.Height / (2 * wr.TileScale)); bottom = top + new int2(0, bounds[1] * wr.TileSize.Height / wr.TileScale); } else { var xMin = int.MaxValue; var xMax = int.MinValue; var yMin = int.MaxValue; var yMax = int.MinValue; foreach (var c in buildingInfo.OccupiedTiles(self.Location)) { xMin = Math.Min(xMin, c.X); xMax = Math.Max(xMax, c.X); yMin = Math.Min(yMin, c.Y); yMax = Math.Max(yMax, c.Y); } left = wr.ScreenPxPosition(self.World.Map.CenterOfCell(new CPos(xMin, yMax)) - new WVec(768, 0, 0)); right = wr.ScreenPxPosition(self.World.Map.CenterOfCell(new CPos(xMax, yMin)) + new WVec(768, 0, 0)); top = wr.ScreenPxPosition(self.World.Map.CenterOfCell(new CPos(xMin, yMin)) - new WVec(0, 768, 0)); bottom = wr.ScreenPxPosition(self.World.Map.CenterOfCell(new CPos(xMax, yMax)) + new WVec(0, 768, 0)); } if (height == 0) { return(new Polygon(new[] { top, left, bottom, right })); } var h = new int2(0, height); return(new Polygon(new[] { top - h, left - h, left, bottom, right, right - h })); }