Пример #1
0
        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);
                    }
                }
            }
        }
Пример #2
0
        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);
                }
            }
        }
Пример #3
0
        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));
        }
Пример #4
0
        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);
                    }
                }
            }
        }
Пример #5
0
        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));
                }
            });
        }
Пример #7
0
        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;
                }
            }
        }
Пример #8
0
        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);
            }
        }
Пример #9
0
        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());
        }
Пример #10
0
        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;
            }
        }
Пример #11
0
        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");
        }
Пример #12
0
        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));
        }
Пример #13
0
        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]]);
        }
Пример #14
0
        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);
        }
Пример #15
0
        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());
        }
Пример #16
0
        public static bool AnyVisible(this Shroud shroud, OccupiedCells cells)
        {
            foreach (var cell in cells)
            {
                if (shroud.IsVisible(cell.First))
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #17
0
        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]));
            }
        }
Пример #18
0
        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);
                }
            }
        }
Пример #19
0
        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);
        }
Пример #20
0
        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);
        }
Пример #21
0
        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);
        }
Пример #22
0
        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();
            }
        }
Пример #23
0
        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;
            }
        }
Пример #24
0
        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;
            }
        }
Пример #25
0
        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());
        }
Пример #26
0
        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);
                }
            }
        }
Пример #27
0
        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);
            }
        }
Пример #28
0
        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);
                }
            }
        }
Пример #29
0
        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();
            }
        }
Пример #30
0
        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();
                }
            }
        }
Пример #31
0
 public HiddenUnderFog(Actor self)
 {
     shroud = self.World.WorldActor.traits.Get<Shroud>();
 }