Beispiel #1
0
        public IEnumerable<Actor> GetUnitsAt(CPos a, SubCell sub)
        {
            if (!map.IsInMap(a)) yield break;

            for( var i = influence[ a.X, a.Y ] ; i != null ; i = i.next )
                if (!i.actor.Destroyed && (i.subCell == sub || i.subCell == SubCell.FullCell))
                    yield return i.actor;
        }
Beispiel #2
0
        public bool AnyUnitsAt(CPos a, SubCell sub)
        {
            for( var i = influence[ a.X, a.Y ] ; i != null ; i = i.next )
                if (i.subCell == sub || i.subCell == SubCell.FullCell)
                    return true;

            return false;
        }
Beispiel #3
0
        public SubCell? FreeSubCell(CPos a)
        {
            if (!HasFreeSubCell(a))
                return null;

            return new[]{ SubCell.TopLeft, SubCell.TopRight, SubCell.Center,
                SubCell.BottomLeft, SubCell.BottomRight }.First(b => !AnyUnitsAt(a,b));
        }
Beispiel #4
0
        public IEnumerable<Actor> GetUnitsAt(CPos a)
        {
            if (!map.IsInMap(a)) yield break;

            for( var i = influence[ a.X, a.Y ] ; i != null ; i = i.next )
                if (!i.actor.Destroyed)
                    yield return i.actor;
        }
Beispiel #5
0
		public static PathSearch FromPoint(World world, MobileInfo mi, Actor self, CPos from, CPos target, bool checkForBlocked)
		{
			var search = new PathSearch(world, mi, self)
			{
				Heuristic = DefaultEstimator(target),
				CheckForBlocked = checkForBlocked
			};

			search.AddInitialCell(from);
			return search;
		}
Beispiel #6
0
        Order(string orderString, Actor subject,
			Actor targetActor, CPos targetLocation, string targetString, bool queued, CPos extraLocation)
        {
            this.OrderString = orderString;
            this.Subject = subject;
            this.TargetActor = targetActor;
            this.TargetLocation = targetLocation;
            this.TargetString = targetString;
            this.Queued = queued;
            this.ExtraLocation = extraLocation;
        }
Beispiel #7
0
        Order(string orderString, Actor subject,
			Actor targetActor, CPos targetLocation, string targetString, bool queued, CPos extraLocation, uint extraData)
        {
            OrderString = orderString;
            Subject = subject;
            TargetActor = targetActor;
            TargetLocation = targetLocation;
            TargetString = targetString;
            Queued = queued;
            ExtraLocation = extraLocation;
            ExtraData = extraData;
        }
Beispiel #8
0
        public static Func<CPos, int> DefaultEstimator(CPos destination)
        {
            return here =>
            {
                var diag = Math.Min(Math.Abs(here.X - destination.X), Math.Abs(here.Y - destination.Y));
                var straight = Math.Abs(here.X - destination.X) + Math.Abs(here.Y - destination.Y);

                // HACK: this relies on fp and cell-size assumptions.
                var h = (3400 * diag / 24) + 100 * (straight - (2 * diag));
                return (int)(h * 1.001);
            };
        }
Beispiel #9
0
		public static PathSearch FromPoints(World world, MobileInfo mi, Actor self, IEnumerable<CPos> froms, CPos target, bool checkForBlocked)
		{
			var search = new PathSearch(world, mi, self)
			{
				Heuristic = DefaultEstimator(target),
				CheckForBlocked = checkForBlocked
			};

			foreach (var sl in froms)
				search.AddInitialCell(sl);

			return search;
		}
Beispiel #10
0
        public CPos ChooseClosestEdgeCell(CPos pos)
        {
            var mpos = pos.ToMPos(this);

            var horizontalBound = ((mpos.U - Bounds.Left) < Bounds.Width / 2) ? Bounds.Left : Bounds.Right;
            var verticalBound = ((mpos.V - Bounds.Top) < Bounds.Height / 2) ? Bounds.Top : Bounds.Bottom;

            var distX = Math.Abs(horizontalBound - mpos.U);
            var distY = Math.Abs(verticalBound - mpos.V);

            return distX < distY ? new MPos(horizontalBound, mpos.V).ToCPos(this) : new MPos(mpos.U, verticalBound).ToCPos(this);
        }
Beispiel #11
0
 public bool Contains(CPos cell)
 {
     return Contains(cell.ToMPos(this));
 }
Beispiel #12
0
        public void UpdateRemoteSearch(MapStatus status, MiniYaml yaml, Action <MapPreview> parseMetadata = null)
        {
            var newData = innerData.Clone();

            newData.Status = status;
            newData.Class  = MapClassification.Remote;

            if (status == MapStatus.DownloadAvailable)
            {
                try
                {
                    var r = FieldLoader.Load <RemoteMapData>(yaml);

                    // Map download has been disabled server side
                    if (!r.downloading)
                    {
                        newData.Status = MapStatus.Unavailable;
                        return;
                    }

                    newData.Title       = r.title;
                    newData.Categories  = r.categories;
                    newData.Author      = r.author;
                    newData.PlayerCount = r.players;
                    newData.Bounds      = r.bounds;
                    newData.TileSet     = r.tileset;

                    var spawns = new CPos[r.spawnpoints.Length / 2];
                    for (var j = 0; j < r.spawnpoints.Length; j += 2)
                    {
                        spawns[j / 2] = new CPos(r.spawnpoints[j], r.spawnpoints[j + 1]);
                    }
                    newData.SpawnPoints = spawns;
                    newData.GridType    = r.map_grid_type;
                    newData.Preview     = new Bitmap(new MemoryStream(Convert.FromBase64String(r.minimap)));

                    var playersString = Encoding.UTF8.GetString(Convert.FromBase64String(r.players_block));
                    newData.Players = new MapPlayers(MiniYaml.FromString(playersString));

                    newData.SetRulesetGenerator(modData, () =>
                    {
                        var rulesString             = Encoding.UTF8.GetString(Convert.FromBase64String(r.rules));
                        var rulesYaml               = new MiniYaml("", MiniYaml.FromString(rulesString)).ToDictionary();
                        var ruleDefinitions         = LoadRuleSection(rulesYaml, "Rules");
                        var weaponDefinitions       = LoadRuleSection(rulesYaml, "Weapons");
                        var voiceDefinitions        = LoadRuleSection(rulesYaml, "Voices");
                        var musicDefinitions        = LoadRuleSection(rulesYaml, "Music");
                        var notificationDefinitions = LoadRuleSection(rulesYaml, "Notifications");
                        var sequenceDefinitions     = LoadRuleSection(rulesYaml, "Sequences");
                        var rules = Ruleset.Load(modData, this, TileSet, ruleDefinitions, weaponDefinitions,
                                                 voiceDefinitions, notificationDefinitions, musicDefinitions, sequenceDefinitions);
                        var flagged = Ruleset.DefinesUnsafeCustomRules(modData, this, ruleDefinitions,
                                                                       weaponDefinitions, voiceDefinitions, notificationDefinitions, sequenceDefinitions);
                        return(Pair.New(rules, flagged));
                    });
                }
                catch (Exception) { }

                // Commit updated data before running the callbacks
                innerData = newData;

                if (innerData.Preview != null)
                {
                    cache.CacheMinimap(this);
                }

                if (parseMetadata != null)
                {
                    parseMetadata(this);
                }
            }

            // Update the status and class unconditionally
            innerData = newData;
        }
Beispiel #13
0
        public WPos CenterOfCell(CPos cell)
        {
            if (TileShape == TileShape.Rectangle)
                return new WPos(1024 * cell.X + 512, 1024 * cell.Y + 512, 0);

            // Convert from diamond cell position (x, y) to world position (u, v):
            // (a) Consider the relationships:
            //  - Center of origin cell is (512, 512)
            //  - +x adds (512, 512) to world pos
            //  - +y adds (-512, 512) to world pos
            // (b) Therefore:
            //  - ax + by adds (a - b) * 512 + 512 to u
            //  - ax + by adds (a + b) * 512 + 512 to v
            var z = Contains(cell) ? 512 * MapHeight.Value[cell] : 0;
            return new WPos(512 * (cell.X - cell.Y), 512 * (cell.X + cell.Y + 1), z);
        }
Beispiel #14
0
		public CPos Clamp(CPos cell)
		{
			var bounds = new Rectangle(Bounds.X, Bounds.Y, Bounds.Width - 1, Bounds.Height - 1);
			return MapToCell(TileShape, CellToMap(TileShape, cell).Clamp(bounds));
		}
Beispiel #15
0
 public bool AnyUnitsAt(CPos a)
 {
     return influence[ a.X, a.Y ] != null;
 }
Beispiel #16
0
        public static Order Deserialize(World world, BinaryReader r)
        {
            try
            {
                var type = (OrderType)r.ReadByte();
                switch (type)
                {
                case OrderType.Fields:
                {
                    var order = r.ReadString();
                    var flags = (OrderFields)r.ReadByte();

                    Actor subject = null;
                    if (flags.HasField(OrderFields.Subject))
                    {
                        var subjectId = r.ReadUInt32();
                        if (world != null)
                        {
                            TryGetActorFromUInt(world, subjectId, out subject);
                        }
                    }

                    var target = Target.Invalid;
                    if (flags.HasField(OrderFields.Target))
                    {
                        switch ((TargetType)r.ReadByte())
                        {
                        case TargetType.Actor:
                        {
                            Actor targetActor;
                            if (world != null && TryGetActorFromUInt(world, r.ReadUInt32(), out targetActor))
                            {
                                target = Target.FromActor(targetActor);
                            }
                            break;
                        }

                        case TargetType.FrozenActor:
                        {
                            var playerActorID = r.ReadUInt32();
                            var frozenActorID = r.ReadUInt32();

                            Actor playerActor;
                            if (world == null || !TryGetActorFromUInt(world, playerActorID, out playerActor))
                            {
                                break;
                            }

                            if (playerActor.Owner.FrozenActorLayer == null)
                            {
                                break;
                            }

                            var frozen = playerActor.Owner.FrozenActorLayer.FromID(frozenActorID);
                            if (frozen != null)
                            {
                                target = Target.FromFrozenActor(frozen);
                            }

                            break;
                        }

                        case TargetType.Terrain:
                        {
                            if (flags.HasField(OrderFields.TargetIsCell))
                            {
                                var cell    = new CPos(r.ReadInt32());
                                var subCell = (SubCell)r.ReadByte();
                                if (world != null)
                                {
                                    target = Target.FromCell(world, cell, subCell);
                                }
                            }
                            else
                            {
                                var pos = new WPos(r.ReadInt32(), r.ReadInt32(), r.ReadInt32());
                                target = Target.FromPos(pos);
                            }

                            break;
                        }
                        }
                    }

                    var targetString = flags.HasField(OrderFields.TargetString) ? r.ReadString() : null;
                    var queued       = flags.HasField(OrderFields.Queued);

                    Actor[] extraActors = null;
                    if (flags.HasField(OrderFields.ExtraActors))
                    {
                        var count = r.ReadInt32();
                        if (world != null)
                        {
                            extraActors = Exts.MakeArray(count, _ => world.GetActorById(r.ReadUInt32()));
                        }
                        else
                        {
                            r.ReadBytes(4 * count);
                        }
                    }

                    var extraLocation = flags.HasField(OrderFields.ExtraLocation) ? new CPos(r.ReadInt32()) : CPos.Zero;
                    var extraData     = flags.HasField(OrderFields.ExtraData) ? r.ReadUInt32() : 0;

                    if (world == null)
                    {
                        return(new Order(order, null, target, targetString, queued, extraActors, extraLocation, extraData));
                    }

                    if (subject == null && flags.HasField(OrderFields.Subject))
                    {
                        return(null);
                    }

                    return(new Order(order, subject, target, targetString, queued, extraActors, extraLocation, extraData));
                }

                case OrderType.Handshake:
                {
                    var name         = r.ReadString();
                    var targetString = r.ReadString();

                    return(new Order(name, null, false)
                        {
                            Type = OrderType.Handshake, TargetString = targetString
                        });
                }

                default:
                {
                    Log.Write("debug", "Received unknown order with type {0}", type);
                    return(null);
                }
                }
            }
            catch (Exception e)
            {
                Log.Write("debug", "Caught exception while processing order");
                Log.Write("debug", e.ToString());

                // HACK: this can hopefully go away in the future
                Game.Debug("Ignoring malformed order that would have crashed the game");
                Game.Debug("Please file a bug report and include the replay from this match");

                return(null);
            }
        }
Beispiel #17
0
 public bool IsInMap(CPos xy)
 {
     return IsInMap(xy.X, xy.Y);
 }
Beispiel #18
0
 public static IEnumerable <Actor> FindActorsInBox(this World world, CPos tl, CPos br)
 {
     // TODO: Support diamond boxes for isometric maps?
     return(world.FindActorsInBox(tl.TopLeft, br.BottomRight));
 }
Beispiel #19
0
 Order(string orderString, Actor subject, Target target, string targetString, bool queued, Actor[] extraActors, CPos extraLocation, uint extraData)
 {
     OrderString   = orderString ?? "";
     Subject       = subject;
     Target        = target;
     TargetString  = targetString;
     Queued        = queued;
     ExtraActors   = extraActors;
     ExtraLocation = extraLocation;
     ExtraData     = extraData;
 }
Beispiel #20
0
        public static CPos ClampToWorld(this World world, CPos xy)
        {
            var r = world.Map.Bounds;

            return(xy.Clamp(new Rectangle(r.X, r.Y, r.Width - 1, r.Height - 1)));
        }
Beispiel #21
0
 public static TerrainTypeInfo GetTerrainInfo(this World world, CPos cell)
 {
     return(world.TileSet.Terrain[world.GetTerrainType(cell)]);
 }
Beispiel #22
0
        public static string GetTerrainType(this World world, CPos cell)
        {
            var custom = world.Map.CustomTerrain[cell.X, cell.Y];

            return(custom ?? world.TileSet.GetTerrainType(world.Map.MapTiles.Value[cell.X, cell.Y]));
        }
Beispiel #23
0
        // Both ranges are inclusive because everything that calls it is designed for maxRange being inclusive:
        // it rounds the actual distance up to the next integer so that this call
        // will return any cells that intersect with the requested range circle.
        // The returned positions are sorted by distance from the center.
        public IEnumerable<CPos> FindTilesInAnnulus(CPos center, int minRange, int maxRange)
        {
            if (maxRange < minRange)
                throw new ArgumentOutOfRangeException("maxRange", "Maximum range is less than the minimum range.");

            if (maxRange > TilesByDistance.Length)
                throw new ArgumentOutOfRangeException("maxRange", "The requested range ({0}) exceeds the maximum allowed ({1})".F(maxRange, MaxTilesInCircleRange));

            for (var i = minRange; i <= maxRange; i++)
            {
                foreach (var offset in TilesByDistance[i])
                {
                    var t = offset + center;
                    if (Contains(t))
                        yield return t;
                }
            }
        }
Beispiel #24
0
 public CPos ChooseClosestEdgeCell(CPos cell)
 {
     return(ChooseClosestEdgeCell(cell.ToMPos(TileShape)).ToCPos(TileShape));
 }
Beispiel #25
0
 public byte GetTerrainIndex(CPos cell)
 {
     var uv = cell.ToMPos(this);
     var custom = CustomTerrain[uv];
     return custom != byte.MaxValue ? custom : cachedTileSet.Value.GetTerrainIndex(MapTiles.Value[uv]);
 }
Beispiel #26
0
        public Player(World world, Session.Client client, PlayerReference pr, MersenneTwister playerRandom)
        {
            World           = world;
            InternalName    = pr.Name;
            PlayerReference = pr;

            inMissionMap = world.Map.Visibility.HasFlag(MapVisibility.MissionSelector);

            // Real player or host-created bot
            if (client != null)
            {
                ClientIndex = client.Index;
                Color       = client.Color;
                PlayerName  = ResolvePlayerName(client, world.LobbyInfo.Clients, world.Map.Rules.Actors["player"].TraitInfos <IBotInfo>());

                BotType        = client.Bot;
                Faction        = ResolveFaction(world, client.Faction, playerRandom, !pr.LockFaction);
                DisplayFaction = ResolveDisplayFaction(world, client.Faction);

                var assignSpawnPoints = world.WorldActor.TraitOrDefault <IAssignSpawnPoints>();
                HomeLocation      = assignSpawnPoints?.AssignHomeLocation(world, client, playerRandom) ?? pr.HomeLocation;
                SpawnPoint        = assignSpawnPoints?.SpawnPointForPlayer(this) ?? client.SpawnPoint;
                DisplaySpawnPoint = client.SpawnPoint;
            }
            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        = ResolveFaction(world, pr.Faction, playerRandom, false);
                DisplayFaction = ResolveDisplayFaction(world, pr.Faction);
                HomeLocation   = pr.HomeLocation;
                SpawnPoint     = DisplaySpawnPoint = 0;
            }

            if (!spectating)
            {
                PlayerMask = new LongBitSet <PlayerBitMask>(InternalName);
            }

            // Set this property before running any Created callbacks on the player actor
            IsBot = BotType != null;

            // Special case handling is required for the Player actor:
            // Since Actor.Created would be called before PlayerActor is assigned here
            // querying player traits in INotifyCreated.Created would crash.
            // Therefore assign the uninitialized actor and run the Created callbacks
            // by calling Initialize ourselves.
            var playerActorType = world.Type == WorldType.Editor ? EditorPlayerActorType : PlayerActorType;

            PlayerActor = new Actor(world, playerActorType, new TypeDictionary {
                new OwnerInit(this)
            });
            PlayerActor.Initialize(true);

            Shroud           = PlayerActor.Trait <Shroud>();
            FrozenActorLayer = PlayerActor.TraitOrDefault <FrozenActorLayer>();

            // Enable the bot logic on the host
            if (IsBot && Game.IsHost)
            {
                var logic = PlayerActor.TraitsImplementing <IBot>().FirstOrDefault(b => b.Info.Type == 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");

            unlockRenderPlayer = PlayerActor.TraitsImplementing <IUnlocksRenderPlayer>().ToArray();
        }
Beispiel #27
0
 public int FacingBetween(CPos cell, CPos towards, int fallbackfacing)
 {
     return(Traits.Util.GetFacing(CenterOfCell(towards) - CenterOfCell(cell), fallbackfacing));
 }
Beispiel #28
0
 public bool FogObscures(CPos p)
 {
     return(RenderPlayer != null && !RenderPlayer.Shroud.IsVisible(p));
 }
Beispiel #29
0
        public bool HasFreeSubCell(CPos a)
        {
            if (!AnyUnitsAt(a))
                return true;

            return new[]{ SubCell.TopLeft, SubCell.TopRight, SubCell.Center,
                SubCell.BottomLeft, SubCell.BottomRight }.Any(b => !AnyUnitsAt(a,b));
        }
Beispiel #30
0
 public bool ShroudObscures(CPos p)
 {
     return(RenderPlayer != null && !RenderPlayer.Shroud.IsExplored(p));
 }
Beispiel #31
0
        // Resolve an array index from cell coordinates
        int Index(CPos cell)
        {
            var uv = Map.CellToMap(Shape, cell);

            return(uv.Y * Size.Width + uv.X);
        }
Beispiel #32
0
 public static int HashCPos(CPos i2)
 {
     return(((i2.X * 5) ^ (i2.Y * 3)) / 4);
 }
Beispiel #33
0
 Order(string orderString, Actor subject,
       Actor targetActor, CPos targetLocation, string targetString, bool queued, CPos extraLocation, uint extraData)
 {
     this.OrderString    = orderString;
     this.Subject        = subject;
     this.TargetActor    = targetActor;
     this.TargetLocation = targetLocation;
     this.TargetString   = targetString;
     this.Queued         = queued;
     this.ExtraLocation  = extraLocation;
     this.ExtraData      = extraData;
 }
Beispiel #34
0
 public CPos Clamp(CPos cell)
 {
     return(Clamp(cell.ToMPos(this)).ToCPos(this));
 }
Beispiel #35
0
 public WPos CenterOfSubCell(CPos cell, SubCell subCell)
 {
     var index = (int)subCell;
     if (index >= 0 && index <= SubCellOffsets.Length)
         return CenterOfCell(cell) + SubCellOffsets[index];
     return CenterOfCell(cell);
 }
Beispiel #36
0
		public PathSearch FromPoint(CPos from)
		{
			AddInitialCell(from);
			return this;
		}
Beispiel #37
0
 public CPos Clamp(CPos cell)
 {
     var bounds = new Rectangle(Bounds.X, Bounds.Y, Bounds.Width - 1, Bounds.Height - 1);
     return cell.ToMPos(this).Clamp(bounds).ToCPos(this);
 }
Beispiel #38
0
 public TerrainTypeInfo GetTerrainInfo(CPos cell)
 {
     return(cachedTileSet.Value[GetTerrainIndex(cell)]);
 }
Beispiel #39
0
 public int FacingBetween(CPos cell, CPos towards, int fallbackfacing)
 {
     return Traits.Util.GetFacing(CenterOfCell(towards) - CenterOfCell(cell), fallbackfacing);
 }
Beispiel #40
0
 // Resolve an array index from cell coordinates
 int Index(CPos cell)
 {
     return(Index(cell.ToMPos(Shape)));
 }
Beispiel #41
0
 public IEnumerable<CPos> FindTilesInCircle(CPos center, int maxRange)
 {
     return FindTilesInAnnulus(center, 0, maxRange);
 }
Beispiel #42
0
		public void FixOpenAreas(Ruleset rules)
		{
			var r = new Random();
			var tileset = rules.TileSets[Tileset];

			for (var j = Bounds.Top; j < Bounds.Bottom; j++)
			{
				for (var i = Bounds.Left; i < Bounds.Right; i++)
				{
					var cell = new CPos(i, j);
					var type = MapTiles.Value[cell].Type;
					var index = MapTiles.Value[cell].Index;
					if (!tileset.Templates.ContainsKey(type))
					{
						Console.WriteLine("Unknown Tile ID {0}".F(type));
						continue;
					}

					var template = tileset.Templates[type];
					if (!template.PickAny)
						continue;

					index = (byte)r.Next(0, template.TilesCount);
					MapTiles.Value[cell] = new TerrainTile(type, index);
				}
			}
		}
Beispiel #43
0
 public TerrainTypeInfo GetTerrainInfo(CPos cell)
 {
     return cachedTileSet.Value[GetTerrainIndex(cell)];
 }
Beispiel #44
0
		public int GetTerrainIndex(CPos cell)
		{
			var custom = CustomTerrain[cell];
			return custom != -1 ? custom : cachedTileSet.Value.GetTerrainIndex(MapTiles.Value[cell]);
		}
Beispiel #45
0
 public static CPos Max(CPos a, CPos b)
 {
     return new CPos(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y));
 }
Beispiel #46
0
 public IEnumerable <CPos> FindTilesInCircle(CPos center, int maxRange, bool allowOutsideBounds = false)
 {
     return(FindTilesInAnnulus(center, 0, maxRange, allowOutsideBounds));
 }
Beispiel #47
0
		public void AddInitialCell(CPos location)
		{
			if (!self.World.Map.Contains(location))
				return;

			CellInfo[location] = new CellInfo(0, location, false);
			Queue.Add(new PathDistance(Heuristic(location), location));
		}
Beispiel #48
0
		public static CPos MapToCell(TileShape shape, CPos map)
		{
			if (shape == TileShape.Rectangle)
				return map;

			// Convert from rectangular map position to diamond cell position
			//  - The staggered rows make this fiddly (hint: draw a diagram!)
			// (a) Consider the relationships:
			//  - +1u (even -> odd) adds (1, -1) to (x, y)
			//  - +1v (even -> odd) adds (1, 0) to (x, y)
			//  - +1v (odd -> even) adds (0, 1) to (x, y)
			// (b) Therefore:
			//  - au + 2bv adds (a + b) to (x, y)
			//  - a correction factor is added if v is odd
			var offset = (map.Y & 1) == 1 ? 1 : 0;
			var y = (map.Y - offset) / 2 - map.X;
			var x = map.Y - y;
			return new CPos(x, y);
		}
Beispiel #49
0
		public static CPos CellToMap(TileShape shape, CPos cell)
		{
			if (shape == TileShape.Rectangle)
				return cell;

			// Convert from diamond cell (x, y) position to rectangular map position (u, v)
			//  - The staggered rows make this fiddly (hint: draw a diagram!)
			// (a) Consider the relationships:
			//  - +1x (even -> odd) adds (0, 1) to (u, v)
			//  - +1x (odd -> even) adds (1, 1) to (u, v)
			//  - +1y (even -> odd) adds (-1, 1) to (u, v)
			//  - +1y (odd -> even) adds (0, 1) to (u, v)
			// (b) Therefore:
			//  - ax + by adds (a - b)/2 to u (only even increments count)
			//  - ax + by adds a + b to v
			var u = (cell.X - cell.Y) / 2;
			var v = cell.X + cell.Y;
			return new CPos(u, v);
		}
Beispiel #50
0
 public bool IsInMap(CPos xy)
 {
     return(IsInMap(xy.X, xy.Y));
 }