public void Recalc(LiveMap _liveMap) { m_lightsCount = 0; m_edgesCount = 0; var avatarXY = BaseMapBlock.GetInBlockCoords(World.TheWorld.Avatar.GeoInfo.LiveCoords) + new Point(32, 32); m_lights[m_lightsCount++] = new Light { LightSource = new AvatarSight(), Point = new PointF(avatarXY.X, avatarXY.Y), LiveMapCell = World.TheWorld.Avatar[0, 0] }; #if DEBUG using (new Profiler("LosManagerEx.Recalc")) #endif { ПодготовкаКарты(_liveMap, avatarXY); СформироватьМассивГраней(); while (m_fboBlit.CountOfBuffers < (m_lightsCount + 2)) { m_fboBlit.AddTextureBuffer(); } Отрисовка(avatarXY); ОбновитьСостояниеОсвещенностиКарты(_liveMap); } GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.Enable(EnableCap.Texture2D); }
private void GenerateInternal(BaseMapBlock _block, params Point[] _objects) { var rnd = new Random(_block.RandomSeed); MapBlockHelper.Clear(_block, rnd, this, DefaultWalls); var rooms = LayerHelper.GenerateRooms(rnd, new Rct(0, 0, Constants.MAP_BLOCK_SIZE - 1, Constants.MAP_BLOCK_SIZE - 1), new List <Point>(_objects), _block.BlockId); foreach (var room in rooms) { MapBlockHelper.Fill(_block, rnd, this, DefaultEmptySpaces, room.RoomRectangle); _block.AddRoom(room); } }
public override void AddStair(WorldLayer _enterFromLayer, Point _worldCoords, Stair _stair) { var blockId = BaseMapBlock.GetBlockId(EnterCoords); var inBlockCoords = BaseMapBlock.GetInBlockCoords(EnterCoords); var block = this[blockId]; if (_stair is StairUp) { block.AddEssence(new StairDown(_enterFromLayer, EssenceHelper.GetFirstFoundedMaterial <MineralMaterial>()), inBlockCoords); } else { block.AddEssence(new StairUp(_enterFromLayer, EssenceHelper.GetFirstFoundedMaterial <MineralMaterial>()), inBlockCoords); } }
/// <summary> /// добавление коридоров, идущих из комнат /// </summary> private IEnumerable<ConnectionPoint> AddConnectionPoints(BaseMapBlock _block, Room _room, Random _rnd) { if (_block.BlockId == BaseMapBlock.GetBlockId(EnterCoords) && _room.RoomRectangle.Contains(BaseMapBlock.GetInBlockCoords(EnterCoords))) { _room.IsConnected = true; } var trys = 0; do { trys++; var cps = new List<ConnectionPoint>(); var dirs = _rnd.GetRandomDirections(); foreach (var dir in dirs.AllDirectionsIn()) { int val; Point begin; switch (dir) { case EDirections.UP: val = _room.RoomRectangle.Left + _rnd.Next(_room.RoomRectangle.Width); begin = new Point(val, _room.RoomRectangle.Top - 1); break; case EDirections.DOWN: val = _room.RoomRectangle.Left + _rnd.Next(_room.RoomRectangle.Width); begin = new Point(val, _room.RoomRectangle.Bottom); break; case EDirections.LEFT: val = _room.RoomRectangle.Top + _rnd.Next(_room.RoomRectangle.Height); begin = new Point(_room.RoomRectangle.Left - 1, val); break; case EDirections.RIGHT: val = _room.RoomRectangle.Top + _rnd.Next(_room.RoomRectangle.Height); begin = new Point(_room.RoomRectangle.Right, val); break; default: throw new ArgumentOutOfRangeException(); } var end = begin; var delta = dir.GetDelta(); if (!m_mazeBlocks.ContainsKey(BaseMapBlock.GetBlockId(begin + _block.BlockId*Constants.MAP_BLOCK_SIZE + delta*Constants.MAP_BLOCK_SIZE))) { continue; } do { end += delta; if (!_room.AreaRectangle.Contains(end)) break; } while (true); cps.Add(new ConnectionPoint(begin + _block.BlockId*Constants.MAP_BLOCK_SIZE, end + _block.BlockId*Constants.MAP_BLOCK_SIZE, _room, dir)); } if (cps.Count > 1 || (trys > 5 && cps.Count > 0) || trys > 20) { foreach (var connectionPoint in cps) { yield return connectionPoint; } break; } } while (true); }
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; } } } } }
private void GenerateInternal(BaseMapBlock _block, params Point[] _objects) { var rnd = new Random(_block.RandomSeed); MapBlockHelper.Clear(_block, rnd, this, DefaultWalls); var rooms = LayerHelper.GenerateRooms(rnd, new Rct(0, 0, Constants.MAP_BLOCK_SIZE - 1, Constants.MAP_BLOCK_SIZE - 1), new List<Point>(_objects), _block.BlockId); foreach (var room in rooms) { MapBlockHelper.Fill(_block, rnd, this, DefaultEmptySpaces, room.RoomRectangle); _block.AddRoom(room); } }
public void MoveCreature(Creature _creature, Point _worldCoord, WorldLayer _layer = null) { if (_layer == null) { _layer = World.TheWorld.Avatar.GeoInfo.Layer; } _creature[0, 0].ResetCached(); var info = InfoByCreature[_creature]; if (_creature.GeoInfo.WorldCoords != info.WorldCoords) { throw new ApplicationException(); } if (_layer != info.Layer) { if (_creature.IsAvatar) { //Если аватар ушел на другой уровень var allCreatures = InfoByCreature.Keys.ToArray(); foreach (var creature in allCreatures) { if (creature.IsAvatar) { continue; } if (creature is AbstractDummyCreature) { CreatureIsDead(creature); } else { ExcludeCreature(creature); } } info.Layer = _layer; World.TheWorld.LiveMap.Reset(); } else { throw new NotImplementedException(); } } else { if (info.WorldCoords == _worldCoord) { throw new ApplicationException(); } PointByCreature.Remove(info); var oldBlockId = BaseMapBlock.GetBlockId(info.WorldCoords); var newBlockId = BaseMapBlock.GetBlockId(_worldCoord); var delta = _worldCoord - info.WorldCoords; if (oldBlockId != newBlockId) { var newCell = info[delta]; if (_creature.IsAvatar) { World.TheWorld.LiveMap.AvatarChangesBlock(oldBlockId, newBlockId, newCell.LiveMapBlock.LiveMapBlockId); } } if (info.LiveCoords != null) { if (_creature is AbstractDummyCreature) { if (!DummyCreatureByPoint[info.WorldCoords].Remove(info)) { throw new ApplicationException(); } List <CreatureGeoInfo> list; if (!DummyCreatureByPoint.TryGetValue(_worldCoord, out list)) { list = new List <CreatureGeoInfo>(); DummyCreatureByPoint.Add(_worldCoord, list); } list.Add(info); } else { if (!CreatureByPoint.Remove(info.WorldCoords)) { throw new ApplicationException(); } CreatureByPoint.Add(_worldCoord, info); } info.LiveCoords += delta; info.WorldCoords = _worldCoord; PointByCreature.Add(info, _worldCoord); } } if (info.LiveCoords != null) { _creature[0, 0].ResetCached(); if (_creature.IsAvatar) { MessageManager.SendMessage(this, WorldMessage.AvatarMove); } } }
private void ConnectTwoRooms(Room _room1, Room _room2, IDictionary <Point, EDirections> _forbid, IDictionary <Point, Connector> _connectors, params Point[] _points) { var rnd = new Random(m_mazeBlocks[_room1.BlockId].RandomSeed); var pnt = _points[0]; var defEmpty = DefaultEmptySpaces.ToArray(); Point point = null; for (var i = 1; i < _points.Length; ++i) { var line = pnt.GetLineToPoints(_points[i]).ToArray(); var border = Util.GetDirection(pnt, _points[i]).GetBorders().ToArray(); for (var index = 0; index < line.Length; index++) { if (point == line[index]) { continue; } point = line[index]; Connector connector; if (_connectors.TryGetValue(point, out connector)) { _room1.Connect(connector.Rooms.ToArray()); connector.Rooms.Add(_room1); if (_room2 != null) { ConnectTwoRooms(_room2, null, _forbid, _connectors, _points.Reverse().ToArray()); } return; } if (_room2 != null) { _connectors.Add(point, new Connector(_room1, _room2)); } else { _connectors.Add(point, new Connector(_room1)); } var inBlock = BaseMapBlock.GetInBlockCoords(point); var blockId = BaseMapBlock.GetBlockId(point); BaseMapBlock block; if (!m_mazeBlocks.TryGetValue(blockId, out block)) { block = new MapBlock(blockId); MapBlockHelper.Clear(block, rnd, this, DefaultWalls); m_mazeBlocks[blockId] = block; } block.Map[inBlock.X, inBlock.Y] = defEmpty.RandomItem(rnd); if (index != 0 && index < line.Length - 1) { foreach (var delta in border) { var borderPnt = point + delta.Key; EDirections dir; if (!_forbid.TryGetValue(borderPnt, out dir)) { dir = EDirections.DOWN | EDirections.UP | EDirections.LEFT | EDirections.RIGHT; } _forbid[borderPnt] = dir & delta.Value; } } } pnt = _points[i]; } _room1.Connect(_room2); }
/// <summary> /// добавление коридоров, идущих из комнат /// </summary> private IEnumerable <ConnectionPoint> AddConnectionPoints(BaseMapBlock _block, Room _room, Random _rnd) { if (_block.BlockId == BaseMapBlock.GetBlockId(EnterCoords) && _room.RoomRectangle.Contains(BaseMapBlock.GetInBlockCoords(EnterCoords))) { _room.IsConnected = true; } var trys = 0; do { trys++; var cps = new List <ConnectionPoint>(); var dirs = _rnd.GetRandomDirections(); foreach (var dir in dirs.AllDirectionsIn()) { int val; Point begin; switch (dir) { case EDirections.UP: val = _room.RoomRectangle.Left + _rnd.Next(_room.RoomRectangle.Width); begin = new Point(val, _room.RoomRectangle.Top - 1); break; case EDirections.DOWN: val = _room.RoomRectangle.Left + _rnd.Next(_room.RoomRectangle.Width); begin = new Point(val, _room.RoomRectangle.Bottom); break; case EDirections.LEFT: val = _room.RoomRectangle.Top + _rnd.Next(_room.RoomRectangle.Height); begin = new Point(_room.RoomRectangle.Left - 1, val); break; case EDirections.RIGHT: val = _room.RoomRectangle.Top + _rnd.Next(_room.RoomRectangle.Height); begin = new Point(_room.RoomRectangle.Right, val); break; default: throw new ArgumentOutOfRangeException(); } var end = begin; var delta = dir.GetDelta(); if (!m_mazeBlocks.ContainsKey(BaseMapBlock.GetBlockId(begin + _block.BlockId * Constants.MAP_BLOCK_SIZE + delta * Constants.MAP_BLOCK_SIZE))) { continue; } do { end += delta; if (!_room.AreaRectangle.Contains(end)) { break; } } while (true); cps.Add(new ConnectionPoint(begin + _block.BlockId * Constants.MAP_BLOCK_SIZE, end + _block.BlockId * Constants.MAP_BLOCK_SIZE, _room, dir)); } if (cps.Count > 1 || (trys > 5 && cps.Count > 0) || trys > 20) { foreach (var connectionPoint in cps) { yield return(connectionPoint); } break; } } while (true); }
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; } } } } }