Пример #1
0
 public MovementRule this[TerrainAttribute Terrain]
 {
     get
     {
         return(MovementRules[(int)Terrain]);
     }
 }
Пример #2
0
        private static void AddItems(MapBlock _block, Random _rnd)
        {
            var itmcnt = 20 + _rnd.Next(_rnd.Next(20));

            for (var i = 0; i < itmcnt; ++i)
            {
                var x = _rnd.Next(Constants.MAP_BLOCK_SIZE);
                var y = _rnd.Next(Constants.MAP_BLOCK_SIZE);

                var attr = TerrainAttribute.GetAttribute(_block.Map[x, y]);
                if (attr.IsPassable)
                {
                    var point = new Point(x, y);
                    var any   = _block.Objects.Where(_tuple => _tuple.Item2 == point).Select(_tuple => _tuple.Item1);
                    var thing = EssenceHelper.GetRandomFakedItem(_rnd);

                    if (any.Any(_thing => !(_thing is Item)))
                    {
                        continue;
                    }

                    _block.AddEssence(thing, point);
                }
            }
        }
Пример #3
0
        private static void AddCreatures(MapBlock _block, Random _rnd)
        {
            var itmcnt = 2 + _rnd.Next(_rnd.Next(2));

            for (var i = 0; i < itmcnt; ++i)
            {
                var x = _rnd.Next(Constants.MAP_BLOCK_SIZE);
                var y = _rnd.Next(Constants.MAP_BLOCK_SIZE);

                var attr = TerrainAttribute.GetAttribute(_block.Map[x, y]);
                if (attr.IsPassable)
                {
                    var point = new Point(x, y);
                    if (_block.Creatures.Values.Contains(point))
                    {
                        continue;
                    }

                    var creature = (AbstractMonster)EssenceHelper.GetRandomFakedCreature <AbstractMonster>(World.Rnd).Essence.Clone(World.TheWorld.Avatar);

                    if (creature.Is <Stair>() && (x == Constants.MAP_BLOCK_SIZE - 1 || y == Constants.MAP_BLOCK_SIZE - 1))
                    {
                        continue;
                    }

                    if (!_block.Rooms.Any(_room => _room.RoomRectangle.Contains(point) && _room.IsConnected))
                    {
                        continue;
                    }

                    _block.CreaturesAdd(creature, point);
                }
            }
        }
Пример #4
0
        private static void GenerateRandomItems(Random _rnd, MapBlock _block)
        {
            var itmcnt = 20 + _rnd.Next(_rnd.Next(20));

            for (var i = 0; i < itmcnt; ++i)
            {
                var x = _rnd.Next(Constants.MAP_BLOCK_SIZE);
                var y = _rnd.Next(Constants.MAP_BLOCK_SIZE);

                var attr = TerrainAttribute.GetAttribute(_block.Map[x, y]);
                if (attr.IsNotPassable)
                {
                    continue;
                }


                var point = new Point(x, y);
                var thing = World.Rnd.Next(2) == 0 ? EssenceHelper.GetFakedThing(_rnd) : EssenceHelper.GetRandomFakedItem(_rnd);

                if (thing.Is <Stair>())
                {
                    if (x == Constants.MAP_BLOCK_SIZE - 1 || y == Constants.MAP_BLOCK_SIZE - 1)
                    {
                        continue;
                    }
                }

                var any = _block.Objects.Where(_tuple => _tuple.Item2 == point).Select(_tuple => _tuple.Item1);

                if (thing is Item)
                {
                    if (any.Any(_thing => !(_thing is Item)))
                    {
                        continue;
                    }
                }
                else if (any.Any())
                {
                    continue;
                }

                _block.AddEssence(thing, point);
            }
        }
Пример #5
0
        public void SetMapCell(MapBlock _mapBlock, Point _inBlockCoords, float _rnd, Point _onLiveMapCoords, LiveMap _liveMap)
        {
            ResetCached();

            Rnd = _rnd;
            m_items.Clear();
            Thing = null;

            InBlockCoords = _inBlockCoords;
            m_mapBlock    = _mapBlock;
            m_seenMask    = ((UInt32)1) << InBlockCoords.X;

            Terrain          = _mapBlock.Map[_inBlockCoords.X, _inBlockCoords.Y];
            TerrainAttribute = TerrainAttribute.GetAttribute(Terrain);

            IsSeenBefore    = (_mapBlock.SeenCells[_inBlockCoords.Y] & m_seenMask) != 0;
            OnLiveMapCoords = _onLiveMapCoords;

            ClearTemp();
        }
 public bool HasAttribute(TerrainAttribute Attribute)
 {
     return(_TerrainAttributes[(int)Attribute]);
 }
        public static MapBlock GenerateBlock(Point _blockId, Surface _surface)
        {
            var block    = new MapBlock(_blockId);
            var baseType = _surface.GetBlockType(_blockId);

            if (baseType == EMapBlockTypes.NONE)
            {
                return(block);
            }

            var rnd = new Random(block.RandomSeed);
            var pm  = new EMapBlockTypes[Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE];

            var points = Constants.MAP_BLOCK_SIZE * Constants.MAP_BLOCK_SIZE;
            var toAdd  = new List <EMapBlockTypes> {
                baseType, baseType, baseType
            };

            #region размытие границ с соседними блоками

            foreach (var dir in Util.AllDirections)
            {
                Point from;
                Point to;
                switch (dir)
                {
                case EDirections.UP:
                    from = Point.Zero;
                    to   = new Point(Constants.MAP_BLOCK_SIZE - 2, 0);
                    break;

                case EDirections.DOWN:
                    from = new Point(1, Constants.MAP_BLOCK_SIZE - 1);
                    to   = new Point(Constants.MAP_BLOCK_SIZE - 1, Constants.MAP_BLOCK_SIZE - 1);
                    break;

                case EDirections.LEFT:
                    from = new Point(0, Constants.MAP_BLOCK_SIZE - 1);
                    to   = new Point(0, 1);
                    break;

                case EDirections.RIGHT:
                    from = new Point(Constants.MAP_BLOCK_SIZE - 1, 0);
                    to   = new Point(Constants.MAP_BLOCK_SIZE - 1, Constants.MAP_BLOCK_SIZE - 2);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                var delta          = dir.GetDelta();
                var nearestBlockId = _blockId + delta;

                var type = _surface.GetBlockType(nearestBlockId);
                if (type == EMapBlockTypes.NONE)
                {
                    type = baseType;
                }

                toAdd.Add(type);

                if (_surface.Blocks.ContainsKey(nearestBlockId))
                {
                    var nearestBlock = _surface.Blocks[nearestBlockId];
                    foreach (var point in from.GetLineToPoints(to))
                    {
                        type =
                            TerrainAttribute.GetMapBlockType(
                                nearestBlock.Map[
                                    (point.X + delta.X + Constants.MAP_BLOCK_SIZE) % Constants.MAP_BLOCK_SIZE,
                                    (point.Y + delta.Y + Constants.MAP_BLOCK_SIZE) % Constants.MAP_BLOCK_SIZE]);
                        pm[point.X, point.Y] = type;
                        points--;
                    }
                }
                else
                {
                    foreach (var point in from.GetLineToPoints(to))
                    {
                        pm[point.X, point.Y] = type;
                        points--;
                    }
                }
            }

            #endregion

            foreach (var t in toAdd)
            {
                var pnt = Point.Zero;
                while (pm[pnt.X, pnt.Y] != EMapBlockTypes.NONE)
                {
                    pnt = new Point(1 + rnd.Next(Constants.MAP_BLOCK_SIZE - 2), 1 + rnd.Next(Constants.MAP_BLOCK_SIZE - 2));
                }
                pm[pnt.X, pnt.Y] = t;
                points--;
            }

            var dpoints = Util.AllDeltas;
            while (points > 0)
            {
                foreach (var point in Point.AllBlockPoints)
                {
                    var xy = pm[point.X, point.Y];
                    if (xy == 0)
                    {
                        continue;
                    }

                    var dpoint = dpoints[rnd.Next(4)];
                    var x1     = point.X + dpoint.X;
                    if (x1 < 0 || x1 == Constants.MAP_BLOCK_SIZE)
                    {
                        continue;
                    }
                    var y1 = point.Y + dpoint.Y;
                    if (y1 < 0 || y1 == Constants.MAP_BLOCK_SIZE)
                    {
                        continue;
                    }
                    var xy1 = pm[x1, y1];
                    if (xy1 == 0)
                    {
                        pm[x1, y1] = xy;
                        points--;
                    }
                }
            }

            #region заполнение карты блока

            foreach (var pnt in new Rct(0, 0, Constants.MAP_BLOCK_SIZE, Constants.MAP_BLOCK_SIZE).AllPoints)
            {
                ETerrains tr;
                switch (pm[pnt.X, pnt.Y])
                {
                case EMapBlockTypes.NONE:
                    continue;

                case EMapBlockTypes.GROUND:
                    tr = ETerrains.GRASS;
                    break;

                case EMapBlockTypes.FOREST:
                    tr = ETerrains.FOREST;
                    break;

                case EMapBlockTypes.SEA:
                    tr = ETerrains.SEA;
                    break;

                case EMapBlockTypes.DEEP_SEA:
                    tr = ETerrains.DEEP_SEA;
                    break;

                case EMapBlockTypes.FRESH_WATER:
                    tr = ETerrains.FRESH_WATER;
                    break;

                case EMapBlockTypes.DEEP_FRESH_WATER:
                    tr = ETerrains.DEEP_FRESH_WATER;
                    break;

                case EMapBlockTypes.CITY:
                    tr = ETerrains.GROUND;
                    break;

                case EMapBlockTypes.COAST:
                    tr = ETerrains.COAST;
                    break;

                case EMapBlockTypes.LAKE_COAST:
                    tr = ETerrains.LAKE_COAST;
                    break;

                case EMapBlockTypes.MOUNT:
                    tr = ETerrains.MOUNT;
                    break;

                case EMapBlockTypes.SWAMP:
                    tr = ETerrains.SWAMP;
                    break;

                case EMapBlockTypes.ETERNAL_SNOW:
                    tr = ETerrains.ETERNAL_SNOW;
                    break;

                case EMapBlockTypes.SHRUBS:
                    tr = ETerrains.SHRUBS;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
                block.Map[pnt.X, pnt.Y] = tr;
            }

            #endregion

            return(block);
        }
Пример #8
0
        public override void GenerateCityBlock(MapBlock _block, Random _rnd, WorldLayer _layer)
        {
            var roadPoints = new List <Point>();

            for (var i = 0; i < Constants.MAP_BLOCK_SIZE; ++i)
            {
                if (_rnd.Next(2) == 0)
                {
                    roadPoints.Add(new Point(0, i));
                }
                if (_rnd.Next(2) == 0)
                {
                    roadPoints.Add(new Point(1, i));
                }
                if (_rnd.Next(2) == 0)
                {
                    roadPoints.Add(new Point(i, 0));
                }
                if (_rnd.Next(2) == 0)
                {
                    roadPoints.Add(new Point(i, 1));
                }
            }

            if (roadPoints.All(point => TerrainAttribute.GetAttribute(_block.Map[point.X, point.Y]).IsPassable))
            {
                foreach (var point in roadPoints)
                {
                    _block.Map[point.X, point.Y] = ETerrains.ROAD;
                }
            }

            var terrains = m_buildings.Where(_building => _building.BlockId == _block.BlockId).ToDictionary(_b => _b, _building => _building.Room.AreaRectangle.AllPoints.Select(_point => _block.Map[_point.X, _point.Y]).Distinct().ToArray());

            foreach (var pair in terrains)
            {
                if (pair.Value.Any(_terrains => TerrainAttribute.GetAttribute(_terrains).IsNotPassable))
                {
                    m_buildings.Remove(pair.Key);
                }
            }

            var buildings = m_buildings.Where(_pair => _pair.BlockId == _block.BlockId).ToArray();

            foreach (var building in buildings)
            {
                _block.AddRoom(building.Room);
                building.Fill(_block, _layer);
                var citizens = m_citizens.Where(_citizen => _citizen.Roles.OfType <AbstractCitizenRole>().First().Building == building).ToArray();
                foreach (var citizen in citizens)
                {
                    if (m_already.Contains(citizen))
                    {
                        throw new ApplicationException();
                    }
                    m_already.Add(citizen);

                    Tuple <ETileset, FColor> tuple = null;
                    foreach (var color in citizen.Roles.First().Colors)
                    {
                        tuple = Tuple.Create(citizen.Tileset, color);
                        if (!m_conf.Contains(tuple))
                        {
                            break;
                        }
                    }
                    if (tuple == null)
                    {
                        throw new ApplicationException();
                    }

                    m_conf.Add(tuple);
                    citizen.SetLerpColor(tuple.Item2);
                    _block.CreaturesAdd(citizen, building.Room.RoomRectangle.Center);
                }
            }
        }
Пример #9
0
        public TreeMazeDungeonLayer(Point _enterCoords, Random _rnd)
            : base(_enterCoords)
        {
            var enterBlock = BaseMapBlock.GetBlockId(_enterCoords);

            var size   = _rnd.Next(5) + _rnd.Next(5) + 5;
            var center = new Point(size, size) / 2;
            var map    = new EMapBlockTypes[size, size];

            var list     = LayerHelper.GetRandomPoints(center, _rnd, map, size, EMapBlockTypes.GROUND, EMapBlockTypes.NONE);
            var blockIds = list.Distinct().Select(_point => _point - center + enterBlock).ToArray();

            foreach (var blockId in blockIds)
            {
                BaseMapBlock block;
                if (!m_mazeBlocks.TryGetValue(blockId, out block))
                {
                    block = new BaseMapBlock(blockId);
                }

                if (BaseMapBlock.GetBlockId(EnterCoords) == blockId)
                {
                    GenerateInternal(block, new[] { BaseMapBlock.GetInBlockCoords(EnterCoords) });
                }
                else
                {
                    GenerateInternal(block);
                }
                m_mazeBlocks[block.BlockId] = block;
            }

            var connectionPoints = new List <ConnectionPoint>();

            foreach (var block in blockIds.Select(_blockId => m_mazeBlocks[_blockId]))
            {
                var rnd = new Random(block.RandomSeed);
                foreach (var room in block.Rooms)
                {
                    connectionPoints.AddRange(AddConnectionPoints(block, room, rnd));
                }
            }

            LinkRooms(connectionPoints);

            foreach (var mapBlock in m_mazeBlocks.Values)
            {
                foreach (var room in mapBlock.Rooms.Where(_room => _room.IsConnected))
                {
                    var border = room.RoomRectangle.BorderPoints.ToArray();
                    foreach (var point in border)
                    {
                        if (_rnd.NextDouble() > 0.7)
                        {
                            var dir = EDirections.NONE;
                            if (point.X > 0 && TerrainAttribute.GetAttribute(mapBlock.Map[point.X - 1, point.Y]).IsNotPassable)
                            {
                                dir = EDirections.RIGHT;
                            }
                            else if (point.X < Constants.MAP_BLOCK_SIZE - 1 && TerrainAttribute.GetAttribute(mapBlock.Map[point.X + 1, point.Y]).IsNotPassable)
                            {
                                dir = EDirections.LEFT;
                            }
                            else if (point.Y > 0 && TerrainAttribute.GetAttribute(mapBlock.Map[point.X, point.Y - 1]).IsNotPassable)
                            {
                                dir = EDirections.DOWN;
                            }
                            else if (point.Y < Constants.MAP_BLOCK_SIZE - 1 && TerrainAttribute.GetAttribute(mapBlock.Map[point.X, point.Y + 1]).IsNotPassable)
                            {
                                dir = EDirections.UP;
                            }
                            if (dir == EDirections.NONE)
                            {
                                continue;
                            }
                            var fColor = new FColor(3f, (float)_rnd.NextDouble(), (float)_rnd.NextDouble(), (float)_rnd.NextDouble());
                            mapBlock.AddEssence(new OnWallTorch(new LightSource(_rnd.Next(4) + 3, fColor), dir, EssenceHelper.GetFirstFoundedMaterial <WoodMaterial>()), point);
                            break;
                        }
                    }
                }
            }
        }