private void Construct(Position position, float buildingValue, OsnowaBaseTile buildingBaseTile) { if (buildingValue >= 0) { Values.Set(position, buildingValue); } //if(!new[]{ _tileset.Wall.Id, _tileset.DoorHorizontalClosed.Id}.Contains(_tileMatricesByte[TilemapLayers.Standing].Get(position))) // _tileMatricesByte[TilemapLayers.Standing].Set(position, 0); _tileMatricesByte[(int)TilemapLayer.Decoration].Set(position, 0); _tileMatricesByte[(int)buildingBaseTile.Layer].Set(position, buildingBaseTile.Id); }
public FovArea FetchVisibilityFov(Position center, int sightRange) { if (_cachedFovArea == null || _cachedFovArea.Center != center || _cachedFovArea.SightRange != sightRange) { HashSet <Position> fovPositions = _fovCalculator.CalculateFov(center, sightRange, position => _grid.IsPassingLight(position) || position == center); _cachedFovArea = new FovArea { Center = center, SightRange = sightRange, Positions = fovPositions }; } return(_cachedFovArea); }
private Position GetRandomWalkablePositionOnBiggestArea(IOsnowaContext osnowaContext, bool farFromPlayer = true, float chanceForPreferredBiomeRequirement = 1f) { Position position; bool positionIsAccepted; do { position = _rng.NextPosition(osnowaContext.PositionFlags.XSize, osnowaContext.PositionFlags.YSize); positionIsAccepted = (!farFromPlayer || Position.Distance(osnowaContext.StartingPosition, position) > 25) && osnowaContext.PositionFlags.Get(position).HasFlag(PositionFlag.Walkable); } while (!positionIsAccepted); return(position); }
/// <summary> /// Marking /// </summary> private void MarkIsolatedAreas(IOsnowaContext context) { var floodSpiller = new FloodSpiller(); PositionFlags positionFlags = context.PositionFlags; var stopwatch = Stopwatch.StartNew(); byte areaIndex = 0; byte biggestAreaIndex = 0; int maxArea = 0; for (int probeX = 0; probeX < context.PositionFlags.XSize; probeX += 10) { for (int probeY = 0; probeY < context.PositionFlags.YSize; probeY += 10) { bool isFine = false; int totalVisited = 0; Position start = new Position(probeX, probeY); var parameters = new FloodParameters(start.x, start.y) { Qualifier = (x, y) => positionFlags.IsWalkable(x, y), NeighbourProcessor = (x, y, mark) => { if (!isFine) { isFine = true; areaIndex += 1; } totalVisited += 1; } }; int[,] markMatrix = new int[context.PositionFlags.XSize, context.PositionFlags.YSize]; floodSpiller.SpillFlood(parameters, markMatrix); if (totalVisited > 50) { // BUG looks like areas are not isolated, all are of same size of the whole island! // Debug.Log("visited " + totalVisited + "from " + start.x + ", " + start.y + " with index " + areaIndex); } if (totalVisited > maxArea) { maxArea = totalVisited; biggestAreaIndex = areaIndex; } } } Debug.Log("biggest isolated area index: " + biggestAreaIndex); Debug.Log("biggest isolated area index: " + maxArea); Debug.Log("marking isolated areas took: " + stopwatch.ElapsedMilliseconds); }
private Position BuildHouse(Area area) { bool ValidForBeingDoor(Position position) => position.y == area.Bounds.yMin && position.x > area.Bounds.xMin && position.x < area.Bounds.xMax - 1; Position doorPosition = RepeatedActionExecutor.Execute(() => { var position = _rng.Choice(area.Perimeter); return(ValidForBeingDoor(position), position); }); foreach (Position position in area.Perimeter) { if (position != doorPosition) { Construct(position, House, _tileset.Wall); } else { Construct(position, -1f, null); } } OsnowaBaseTile roofBaseTile = _tileset.Roof; foreach (Position housePosition in area.Positions) { Construct(housePosition, -1f, roofBaseTile); if (housePosition != doorPosition) { _grid.SetWalkability(housePosition, 0f); _walkability.Set(housePosition, 0f); } } BoundsInt boundsForRoofAdditions = area.Bounds; ++boundsForRoofAdditions.xMin; ++boundsForRoofAdditions.yMin; --boundsForRoofAdditions.xMax; --boundsForRoofAdditions.yMax; return(doorPosition); }
private void GeneratePlayer(IOsnowaContext osnowaContext) { Position startingPlayerPosition = new Position(osnowaContext.PositionFlags.XSize / 2, osnowaContext.PositionFlags.YSize / 2); // context.StartingPosition; if (osnowaContext.PositionFlags.Get(startingPlayerPosition + Position.Up).HasFlag(PositionFlag.Walkable)) { startingPlayerPosition = startingPlayerPosition + Position.Up; } if (osnowaContext.PositionFlags.Get(startingPlayerPosition + Position.Up).HasFlag(PositionFlag.Walkable)) { startingPlayerPosition = startingPlayerPosition + Position.Up; } //Position position = villageWithEntrance?.Entrance ?? context.Villages.First().Square.Positions.First(); GameEntity playerEntity; _entityGenerator.GenerateActorFromRecipeeAndAddToContext(_context, _gameConfig.EntityRecipees.Player, startingPlayerPosition, out playerEntity, true); }
public IFloodArea FetchWalkableFlood(Position center, int floodRange) { // performance: maybe we should keep a few last calculated results for center-floodRange pairs if (_cachedFloodArea == null) { _cachedFloodArea = new FloodArea(center, floodRange); } int expectedMatrixSize = floodRange * 2 + 1; if (_cachedFloodArea.ArraySize < expectedMatrixSize) { _cachedFloodArea.IncreaseMatrix(expectedMatrixSize); } if (_cachedFloodArea.Center != center) { _cachedFloodArea.Center = center; int boundsSize = floodRange * 2; _cachedFloodArea.Bounds = new Bounds(center.x - floodRange, center.y - floodRange, boundsSize, boundsSize); } var findHighestMark = new FindHighestMarkNeighbourProcessor(); var parameters = new FloodParameters(center.x, center.y) { Qualifier = (x, y) => _grid.IsWalkable(new Position(x, y)), BoundsRestriction = BoundsUtilities.ToFloodBounds(_cachedFloodArea.Bounds), NeighbourProcessor = findHighestMark.Process }; Position furthestPosition = center; _floodSpiller.SpillFlood(parameters, _cachedFloodArea.ValueMatrix); _cachedFloodArea.FurthestPosition = furthestPosition; return(_cachedFloodArea); }
private bool IsWater(Position position) { return(_tileMatricesByte[(int)TilemapLayer.Soil].Get(position) == 0); }