public void RenderShroud(WorldRenderer wr, Shroud shroud) { Update(shroud); var clip = wr.Viewport.CellBounds; var width = clip.Width; for (var j = clip.Top; j < clip.Bottom; j++) { var start = j * tileStride + clip.Left; for (var k = 0; k < width; k++) { var s = tiles[start + k].Shroud; var f = tiles[start + k].Fog; if (s != null) { var pos = tiles[start + k].ScreenPosition - 0.5f * s.size; Game.Renderer.WorldSpriteRenderer.DrawSprite(s, pos, shroudPalette); } if (f != null) { var pos = tiles[start + k].ScreenPosition - 0.5f * f.size; Game.Renderer.WorldSpriteRenderer.DrawSprite(f, pos, fogPalette); } } } }
void Update(Shroud shroud) { var hash = shroud != null ? shroud.Hash : 0; if (shroudHash == hash) { return; } shroudHash = hash; if (shroud == null) { // Players with no shroud see the whole map so we only need to set the edges for (var k = 0; k < tiles.Length; k++) { var shrouded = ObserverShroudedEdges(tiles[k].Position, bounds, useExtendedIndex); tiles[k].Shroud = GetTile(shrouded, tiles[k].Variant); tiles[k].Fog = GetTile(shrouded, tiles[k].Variant); } } else { for (var k = 0; k < tiles.Length; k++) { var shrouded = ShroudedEdges(shroud, tiles[k].Position, useExtendedIndex); var fogged = FoggedEdges(shroud, tiles[k].Position, useExtendedIndex); tiles[k].Shroud = GetTile(shrouded, tiles[k].Variant); tiles[k].Fog = GetTile(fogged, tiles[k].Variant); } } }
void WorldOnRenderPlayerChanged(Player player) { var newShroud = player != null ? player.Shroud : null; if (shroud != newShroud) { if (shroud != null) { shroud.OnShroudChanged -= UpdateShroudCell; } if (newShroud != null) { visibleUnderShroud = puv => newShroud.IsExplored(puv); visibleUnderFog = puv => newShroud.IsVisible(puv); newShroud.OnShroudChanged += UpdateShroudCell; } else { visibleUnderShroud = puv => map.Contains(puv); visibleUnderFog = puv => map.Contains(puv); } shroud = newShroud; } // Dirty the full projected space so the cells outside // the map bounds can be initialized as fully shrouded. cellsDirty.Clear(true); var tl = new PPos(0, 0); var br = new PPos(map.MapSize.X - 1, map.MapSize.Y - 1); UpdateShroud(new ProjectedCellRegion(map, tl, br)); }
void IWorldLoaded.WorldLoaded(World world, WorldRenderer wr) { foreach (var p in world.Players) { if (!p.Playable) { continue; } if (p == world.LocalPlayer) { wr.Viewport.Center(world.Map.CenterOfCell(p.HomeLocation)); } var cells = Shroud.ProjectedCellsInRange(world.Map, p.HomeLocation, info.InitialExploreRange) .ToList(); foreach (var q in world.Players) { if (p.IsAlliedWith(q)) { q.Shroud.ExploreProjectedCells(world, cells); } } } }
PPos[] ProjectedCells(Actor self) { var map = self.World.Map; var range = IsIdleRange(self) ? Range : info.MovingRange; if (range == WDist.Zero) { return(NoCells); } if (Info.Type == VisibilityType.Footprint) { return(self.OccupiesSpace.OccupiedCells() .SelectMany(kv => Shroud.ProjectedCellsInRange(map, kv.First, range, Info.MaxHeightDelta)) .Distinct().ToArray()); } var pos = self.CenterPosition; if (Info.Type == VisibilityType.GroundPosition) { pos -= new WVec(WDist.Zero, WDist.Zero, self.World.Map.DistanceAboveTerrain(pos)); } return(Shroud.ProjectedCellsInRange(map, pos, range, Info.MaxHeightDelta) .ToArray()); }
public override void Activate(Actor self, Order order, SupportPowerManager manager) { base.Activate(self, order, manager); self.World.AddFrameEndTask(w => { Shroud shround = self.Owner.Shroud; WPos destPosition = order.Target.CenterPosition; var cells = Shroud.ProjectedCellsInRange(self.World.Map, self.World.Map.CellContaining(destPosition), WDist.FromCells(info.Radius)); try { shround.AddSource(this, type, cells.ToArray()); } catch { shround.RemoveSource(this); shround.AddSource(this, type, cells.ToArray()); } shround.ExploreProjectedCells(self.World, cells); if (!string.IsNullOrEmpty(info.Sequence)) { string palette = null; if (info.Platte == "player") { palette = "player" + self.Owner.InternalName; } else { palette = info.Platte; } self.World.Add(new SpriteEffect(destPosition, self.World, info.Image, info.Sequence, palette)); } }); }
void Update(Shroud shroud) { var hash = shroud != null ? shroud.Hash : 0; if (shroudHash == hash) { return; } shroudHash = hash; if (shroud == null) { // Players with no shroud see the whole map so we only need to set the edges foreach (var cell in map.Cells) { var t = tiles[cell]; var shrouded = ObserverShroudedEdges(map, t.Position, info.UseExtendedIndex); t.Shroud = shrouded != 0 ? shroudSprites[t.Variant * variantStride + spriteMap[shrouded]] : null; t.Fog = shrouded != 0 ? fogSprites[t.Variant * variantStride + spriteMap[shrouded]] : null; } } else { foreach (var cell in map.Cells) { var t = tiles[cell]; var shrouded = ShroudedEdges(shroud, t.Position, info.UseExtendedIndex); var fogged = FoggedEdges(shroud, t.Position, info.UseExtendedIndex); t.Shroud = shrouded != 0 ? shroudSprites[t.Variant * variantStride + spriteMap[shrouded]] : null; t.Fog = fogged != 0 ? fogSprites[t.Variant * variantStride + spriteMap[fogged]] : null; } } }
internal void Draw(WorldRenderer wr, Shroud shroud) { if (initializePalettes) { if (world.LobbyInfo.GlobalSettings.Fog) { fogPalette = wr.Palette("fog"); } shroudPalette = world.LobbyInfo.GlobalSettings.Fog ? wr.Palette("shroud") : wr.Palette("shroudfog"); initializePalettes = false; } GenerateSprites(shroud); var clipRect = Game.viewport.WorldBounds(wr.world); // We draw the shroud when disabled to hide the sharp map edges DrawShroud(wr, clipRect, sprites, shroudPalette); if (world.LobbyInfo.GlobalSettings.Fog) { DrawShroud(wr, clipRect, fogSprites, fogPalette); } }
PPos[] ProjectedCells(Actor self) { var map = self.World.Map; var range = Range; if (range == WDist.Zero) { return(NoCells); } if (Info.Type == VisibilityType.Footprint) { // PERF: Reuse collection to avoid allocations. footprint.UnionWith(self.OccupiesSpace.OccupiedCells() .SelectMany(kv => Shroud.ProjectedCellsInRange(map, kv.First, range, Info.MaxHeightDelta))); var cells = footprint.ToArray(); footprint.Clear(); return(cells); } var pos = self.CenterPosition; if (Info.Type == VisibilityType.GroundPosition) { pos -= new WVec(WDist.Zero, WDist.Zero, self.World.Map.DistanceAboveTerrain(pos)); } return(Shroud.ProjectedCellsInRange(map, pos, range, Info.MaxHeightDelta) .ToArray()); }
void SetPlayer(Player player, bool forceUpdate = false) { currentPlayer = player; var newShroud = player != null ? player.Shroud : null; if (newShroud != shroud) { if (shroud != null) { shroud.OnShroudChanged -= UpdateShroudCell; } if (newShroud != null) { newShroud.OnShroudChanged += UpdateShroudCell; foreach (var puv in world.Map.ProjectedCells) { UpdateShroudCell(puv); } } shroud = newShroud; } var newPlayerRadarTerrain = currentPlayer != null?currentPlayer.PlayerActor.TraitOrDefault <PlayerRadarTerrain>() : null; if (forceUpdate || newPlayerRadarTerrain != playerRadarTerrain) { if (playerRadarTerrain != null) { playerRadarTerrain.CellTerrainColorChanged -= CellTerrainColorChanged; } else { world.Map.Tiles.CellEntryChanged -= CellTerrainColorChanged; foreach (var rtl in radarTerrainLayers) { rtl.CellEntryChanged -= CellTerrainColorChanged; } } if (newPlayerRadarTerrain != null) { newPlayerRadarTerrain.CellTerrainColorChanged += CellTerrainColorChanged; } else { world.Map.Tiles.CellEntryChanged += CellTerrainColorChanged; foreach (var rtl in radarTerrainLayers) { rtl.CellEntryChanged += CellTerrainColorChanged; } } playerRadarTerrain = newPlayerRadarTerrain; } }
public Player(World world, Session.Client client, PlayerReference pr) { string botType; World = world; InternalName = pr.Name; PlayerReference = pr; // Real player or host-created bot if (client != null) { ClientIndex = client.Index; Color = client.Color; PlayerName = client.Name; botType = client.Bot; Faction = ChooseFaction(world, client.Faction, !pr.LockFaction); DisplayFaction = ChooseDisplayFaction(world, client.Faction); } else { // Map player ClientIndex = 0; // Owned by the host (TODO: fix this) Color = pr.Color; PlayerName = pr.Name; NonCombatant = pr.NonCombatant; Playable = pr.Playable; Spectating = pr.Spectating; botType = pr.Bot; Faction = ChooseFaction(world, pr.Faction, false); DisplayFaction = ChooseDisplayFaction(world, pr.Faction); } PlayerActor = world.CreateActor("Player", new TypeDictionary { new OwnerInit(this) }); Shroud = PlayerActor.Trait <Shroud>(); fogVisibilities = PlayerActor.TraitsImplementing <IFogVisibilityModifier>().ToArray(); // Enable the bot logic on the host IsBot = botType != null; if (IsBot && Game.IsHost) { var logic = PlayerActor.TraitsImplementing <IBot>().FirstOrDefault(b => b.Info.Name == botType); if (logic == null) { Log.Write("debug", "Invalid bot type: {0}", botType); } else { logic.Activate(this); } } stanceColors.Self = ChromeMetrics.Get <Color>("PlayerStanceColorSelf"); stanceColors.Allies = ChromeMetrics.Get <Color>("PlayerStanceColorAllies"); stanceColors.Enemies = ChromeMetrics.Get <Color>("PlayerStanceColorEnemies"); stanceColors.Neutrals = ChromeMetrics.Get <Color>("PlayerStanceColorNeutrals"); }
internal Actor(World world, string name, TypeDictionary initDict) { var init = new ActorInitializer(this, initDict); World = world; ActorID = world.NextAID(); if (initDict.Contains <OwnerInit>()) { Owner = init.Get <OwnerInit, Player>(); } occupySpace = Lazy.New(() => TraitOrDefault <IOccupySpace>()); if (name != null) { if (!Rules.Info.ContainsKey(name.ToLowerInvariant())) { throw new NotImplementedException("No rules definition for unit {0}".F(name.ToLowerInvariant())); } Info = Rules.Info[name.ToLowerInvariant()]; foreach (var trait in Info.TraitsInConstructOrder()) { AddTrait(trait.Create(init)); } } Move = Lazy.New(() => TraitOrDefault <IMove>()); Facing = Lazy.New(() => TraitOrDefault <IFacing>()); Size = Lazy.New(() => { var si = Info.Traits.GetOrDefault <SelectableInfo>(); if (si != null && si.Bounds != null) { return(new int2(si.Bounds[0], si.Bounds[1])); } return(TraitsImplementing <IAutoSelectionSize>().Select(x => x.SelectionSize(this)).FirstOrDefault()); }); if (this.HasTrait <RevealsShroud>()) { Sight = new Shroud.ActorVisibility { range = this.Trait <RevealsShroud>().RevealRange, vis = Shroud.GetVisOrigins(this).ToArray() }; } ApplyIRender = (x, wr) => x.Render(this, wr); ApplyRenderModifier = (m, p, wr) => p.ModifyRender(this, wr, m); Bounds = Cached.New(() => CalculateBounds(false)); ExtendedBounds = Cached.New(() => CalculateBounds(true)); }
Sprite ChooseFog(Shroud s, int i, int j) { if (!s.IsVisible(i, j)) { return(shadowBits[0xf]); } if (!s.IsExplored(i, j)) { return(shadowBits[0xf]); } // bits are for unexploredness: up, right, down, left var v = 0; // bits are for unexploredness: TL, TR, BR, BL var u = 0; if (!s.IsVisible(i, j - 1)) { v |= 1; u |= 3; } if (!s.IsVisible(i + 1, j)) { v |= 2; u |= 6; } if (!s.IsVisible(i, j + 1)) { v |= 4; u |= 12; } if (!s.IsVisible(i - 1, j)) { v |= 8; u |= 9; } var uSides = u; if (!s.IsVisible(i - 1, j - 1)) { u |= 1; } if (!s.IsVisible(i + 1, j - 1)) { u |= 2; } if (!s.IsVisible(i + 1, j + 1)) { u |= 4; } if (!s.IsVisible(i - 1, j + 1)) { u |= 8; } return(shadowBits[SpecialShroudTiles[u ^ uSides][v]]); }
static int ShroudedEdges(Shroud s, CPos p, bool useExtendedIndex) { if (!s.IsExplored(p.X, p.Y)) { return(15); } // If a side is shrouded then we also count the corners var u = 0; if (!s.IsExplored(p.X, p.Y - 1)) { u |= 0x13; } if (!s.IsExplored(p.X + 1, p.Y)) { u |= 0x26; } if (!s.IsExplored(p.X, p.Y + 1)) { u |= 0x4C; } if (!s.IsExplored(p.X - 1, p.Y)) { u |= 0x89; } var uside = u & 0x0F; if (!s.IsExplored(p.X - 1, p.Y - 1)) { u |= 0x01; } if (!s.IsExplored(p.X + 1, p.Y - 1)) { u |= 0x02; } if (!s.IsExplored(p.X + 1, p.Y + 1)) { u |= 0x04; } if (!s.IsExplored(p.X - 1, p.Y + 1)) { u |= 0x08; } // RA provides a set of frames for tiles with shrouded // corners but unshrouded edges. We want to detect this // situation without breaking the edge -> corner enabling // in other combinations. The XOR turns off the corner // bits that are enabled twice, which gives the behavior // we want here. return(useExtendedIndex ? u ^ uside : u& 0x0F); }
PPos[] ProjectedCells(World world) { var map = world.Map; var range = revealRadius; if (range == WDist.Zero) { return(NoCells); } return(Shroud.ProjectedCellsInRange(map, pos, WDist.Zero, range).ToArray()); }
public static bool AnyVisible(this Shroud shroud, OccupiedCells cells) { foreach (var cell in cells) { if (shroud.IsVisible(cell.First)) { return(true); } } return(false); }
public void WorldLoaded(World world, WorldRenderer wr) { var spawns = world.Actors.Where(a => a.Info.Name == "mpspawn") .Select(a => a.Location) .ToArray(); var taken = world.LobbyInfo.Clients.Where(c => c.SpawnPoint != 0 && c.Slot != null) .Select(c => spawns[c.SpawnPoint - 1]).ToList(); var available = spawns.Except(taken).ToList(); // Set spawn foreach (var kv in world.LobbyInfo.Slots) { var player = FindPlayerInSlot(world, kv.Key); if (player == null) { continue; } var client = world.LobbyInfo.ClientInSlot(kv.Key); var spid = (client == null || client.SpawnPoint == 0) ? ChooseSpawnPoint(world, available, taken) : spawns[client.SpawnPoint - 1]; Start.Add(player, spid); player.SpawnPoint = (client == null || client.SpawnPoint == 0) ? spawns.IndexOf(spid) + 1 : client.SpawnPoint; } // Explore allied shroud var map = world.Map; foreach (var p in Start.Keys) { var cells = Shroud.ProjectedCellsInRange(map, Start[p], info.InitialExploreRange); foreach (var q in world.Players) { if (p.IsAlliedWith(q)) { q.Shroud.ExploreProjectedCells(world, cells); } } } // Set viewport if (world.LocalPlayer != null && Start.ContainsKey(world.LocalPlayer)) { wr.Viewport.Center(map.CenterOfCell(Start[world.LocalPlayer])); } }
public Player(World world, Session.Client client, Session.Slot slot, PlayerReference pr) { World = world; InternalName = pr.Name; PlayerReference = pr; string botType = null; // Real player or host-created bot if (client != null) { ClientIndex = client.Index; Color = client.Color; PlayerName = client.Name; botType = client.Bot; Country = ChooseCountry(world, client.Race, !pr.LockRace); DisplayCountry = ChooseDisplayCountry(world, client.Race); } else { // Map player ClientIndex = 0; // Owned by the host (TODO: fix this) Color = pr.Color; PlayerName = pr.Name; NonCombatant = pr.NonCombatant; Playable = pr.Playable; Spectating = pr.Spectating; botType = pr.Bot; Country = ChooseCountry(world, pr.Race, false); DisplayCountry = ChooseDisplayCountry(world, pr.Race); } PlayerActor = world.CreateActor("Player", new TypeDictionary { new OwnerInit(this) }); Shroud = PlayerActor.Trait <Shroud>(); // Enable the bot logic on the host IsBot = botType != null; if (IsBot && Game.IsHost) { var logic = PlayerActor.TraitsImplementing <IBot>() .FirstOrDefault(b => b.Info.Name == botType); if (logic == null) { Log.Write("debug", "Invalid bot type: {0}", botType); } else { logic.Activate(this); } } }
public static bool AnyExplored(this Shroud shroud, OccupiedCells cells) { // PERF: Avoid LINQ. foreach (var cell in cells) { if (shroud.IsExplored(cell.First)) { return(true); } } return(false); }
public static bool AnyExplored(this Shroud shroud, PPos[] puvs) { // PERF: Avoid LINQ. foreach (var puv in puvs) { if (shroud.IsExplored(puv)) { return(true); } } return(false); }
public static bool AnyVisible(this Shroud shroud, Pair <CPos, SubCell>[] cells) { // PERF: Avoid LINQ. foreach (var cell in cells) { if (shroud.IsVisible(cell.First)) { return(true); } } return(false); }
void Update(Shroud newShroud) { if (currentShroud != newShroud) { if (currentShroud != null) { currentShroud.CellsChanged -= MarkCellsDirty; } if (newShroud != null) { shroudDirty.Clear(true); newShroud.CellsChanged += MarkCellsDirty; } cellsDirty.Clear(); cellsAndNeighborsDirty.Clear(); currentShroud = newShroud; } if (currentShroud != null) { mapBorderShroudIsCached = false; // We need to mark newly dirtied areas of the shroud. // Expand the dirty area to cover the neighboring cells, since shroud is affected by neighboring cells. foreach (var cell in cellsDirty) { cellsAndNeighborsDirty.Add(cell); foreach (var direction in CVec.Directions) { cellsAndNeighborsDirty.Add(cell + direction); } } foreach (var cell in cellsAndNeighborsDirty) { shroudDirty[cell] = true; } cellsDirty.Clear(); cellsAndNeighborsDirty.Clear(); } else if (!mapBorderShroudIsCached) { mapBorderShroudIsCached = true; CacheMapBorderShroud(); } }
void UpdateShroud(Shroud shroud) { var visibleUnderShroud = shroud.IsExploredTest(updatedRegion); var visibleUnderFog = shroud.IsVisibleTest(updatedRegion); foreach (var cell in updatedRegion) { var shrouded = GetEdges(cell, visibleUnderShroud); var fogged = GetEdges(cell, visibleUnderFog); var shroudTile = tiles[cell]; var variant = shroudTile.Variant; shroudTile.Shroud = GetTile(shroudSprites, shrouded, variant); shroudTile.Fog = GetTile(fogSprites, fogged, variant); tiles[cell] = shroudTile; } }
void SetPlayer(Player player) { currentPlayer = player; var newRenderShroud = player != null ? player.Shroud : null; if (newRenderShroud != renderShroud) { if (renderShroud != null) { renderShroud.CellsChanged -= MarkShroudDirty; } if (newRenderShroud != null) { // Redraw the full shroud sprite MarkShroudDirty(world.Map.AllCells.MapCoords.Select(uv => (PPos)uv)); // Update the notification binding newRenderShroud.CellsChanged += MarkShroudDirty; } renderShroud = newRenderShroud; } var newPlayerRadarTerrain = currentPlayer != null?currentPlayer.PlayerActor.TraitOrDefault <PlayerRadarTerrain>() : null; if (newPlayerRadarTerrain != playerRadarTerrain) { if (playerRadarTerrain != null) { playerRadarTerrain.CellTerrainColorChanged -= CellTerrainColorChanged; } if (newPlayerRadarTerrain != null) { newPlayerRadarTerrain.CellTerrainColorChanged += CellTerrainColorChanged; } playerRadarTerrain = newPlayerRadarTerrain; } }
CPos[] Cells(Actor self) { var map = self.World.Map; var range = Range; if (range == WDist.Zero) { return(NoCells); } if (info.Type == VisibilityType.Footprint) { return(self.OccupiesSpace.OccupiedCells() .SelectMany(kv => Shroud.CellsInRange(map, kv.First, range)) .Distinct().ToArray()); } return(Shroud.CellsInRange(map, self.CenterPosition, range) .ToArray()); }
public void RenderShroud(WorldRenderer wr, Shroud shroud) { Update(shroud, wr.Viewport.VisibleCells); foreach (var cell in CellRegion.Expand(wr.Viewport.VisibleCells, 1)) { var t = tiles[cell]; if (t.Shroud != null) { var pos = t.ScreenPosition - 0.5f * t.Shroud.size; Game.Renderer.WorldSpriteRenderer.DrawSprite(t.Shroud, pos, shroudPalette); } if (t.Fog != null) { var pos = t.ScreenPosition - 0.5f * t.Fog.size; Game.Renderer.WorldSpriteRenderer.DrawSprite(t.Fog, pos, fogPalette); } } }
internal World(Manifest manifest, Map map, OrderManager orderManager) { this.orderManager = orderManager; orderGenerator_ = new UnitOrderGenerator(); Map = map; TileSet = Rules.TileSets[Map.Tileset]; TileSet.LoadTiles(); SharedRandom = new XRandom(orderManager.LobbyInfo.GlobalSettings.RandomSeed); WorldActor = CreateActor("World", new TypeDictionary()); LocalShroud = WorldActor.Trait <Shroud>(); ActorMap = new ActorMap(this); // Add players foreach (var cmp in WorldActor.TraitsImplementing <ICreatePlayers>()) { cmp.CreatePlayers(this); } // Set defaults for any unset stances foreach (var p in Players) { foreach (var q in Players) { if (!p.Stances.ContainsKey(q)) { p.Stances[q] = Stance.Neutral; } } } Sound.SoundVolumeModifier = 1.0f; foreach (var wlh in WorldActor.TraitsImplementing <IWorldLoaded>()) { wlh.WorldLoaded(this); } }
public ShroudLayer(MPos bounds) { Bounds = bounds * new MPos(2, 2); Shroud = new Shroud[Bounds.X, Bounds.Y]; for (int x = 0; x < Bounds.X; x++) { for (int y = 0; y < Bounds.Y; y++) { var shroud = new Shroud(new MPos(x, y)); var list = new List <Shroud>() { shroud }; Shroud[x, y] = shroud; listenerPositions.Add(new MPos(x, y), list); } } }
void Update(Shroud shroud, CellRegion region) { if (shroud != null) { // If the current shroud hasn't changed and we have already updated the specified area, we don't need to do anything. if (lastShroudHash == shroud.Hash && !clearedForNullShroud && updatedRegion != null && updatedRegion.Contains(region)) { return; } lastShroudHash = shroud.Hash; clearedForNullShroud = false; updatedRegion = region; UpdateShroud(shroud); } else if (!clearedForNullShroud) { // We need to clear any applied shroud. clearedForNullShroud = true; updatedRegion = new CellRegion(map.TileShape, new CPos(0, 0), new CPos(-1, -1)); UpdateNullShroud(); } }
public override void Tick() { // Enable/Disable the radar var enabled = IsEnabled(); if (enabled != cachedEnabled) { Sound.Play(enabled ? RadarOnlineSound : RadarOfflineSound); } cachedEnabled = enabled; if (enabled) { var rp = world.RenderPlayer; var newRenderShroud = rp != null ? rp.Shroud : null; if (newRenderShroud != renderShroud) { if (renderShroud != null) { renderShroud.CellsChanged -= MarkShroudDirty; } if (newRenderShroud != null) { // Redraw the full shroud sprite using (var bitmap = Minimap.ShroudBitmap(world)) OpenRA.Graphics.Util.FastCopyIntoSprite(shroudSprite, bitmap); // Update the notification binding newRenderShroud.CellsChanged += MarkShroudDirty; } dirtyShroudCells.Clear(); renderShroud = newRenderShroud; } // The actor layer is updated every tick var stride = radarSheet.Size.Width; var dx = actorSprite.Bounds.Left - world.Map.Bounds.Left; var dy = actorSprite.Bounds.Top - world.Map.Bounds.Top; Array.Clear(radarData, 4 * (actorSprite.Bounds.Top * stride + actorSprite.Bounds.Left), 4 * actorSprite.Bounds.Height * stride); unsafe { fixed(byte *colorBytes = &radarData[0]) { var colors = (int *)colorBytes; foreach (var t in world.ActorsWithTrait <IRadarSignature>()) { if (!t.Actor.IsInWorld || world.FogObscures(t.Actor)) { continue; } foreach (var cell in t.Trait.RadarSignatureCells(t.Actor)) { var uv = cell.First.ToMPos(world.Map); if (world.Map.Bounds.Contains(uv.U, uv.V)) { colors[(uv.V + dy) * stride + uv.U + dx] = cell.Second.ToArgb(); } } } } } } var targetFrame = enabled ? AnimationLength : 0; hasRadar = enabled && frame == AnimationLength; if (frame == targetFrame) { return; } frame += enabled ? 1 : -1; radarMinimapHeight = float2.Lerp(0, 1, (float)frame / AnimationLength); Animating(frame * 1f / AnimationLength); // Update map rectangle for event handling var ro = RenderOrigin; mapRect = new Rectangle(previewOrigin.X + ro.X, previewOrigin.Y + ro.Y, mapRect.Width, mapRect.Height); // Animation is complete if (frame == targetFrame) { if (enabled) { AfterOpen(); } else { AfterClose(); } } }
public HiddenUnderFog(Actor self) { shroud = self.World.WorldActor.traits.Get<Shroud>(); }