int EnterCost(IntVector2 origin, IntVector2 destination) { if (BlockedAt(destination)) { return(999); } MapTerrain t = Obstructions.Instance.TerrainAt(destination); // Diagonal check if (origin.x != destination.x && origin.y != destination.y) { if ( BlockedAt(new IntVector2(origin.x, destination.y)) && BlockedAt(new IntVector2(destination.x, origin.y)) ) { return(999); } } if (t && t.difficultTerrain) { return(2); } return(1); // regular movement }
public MapTerrain TerrainAt(IntVector2 iv2) { MapTerrain t = null; terrain.TryGetValue(iv2, out t); return(t); }
private IEnumerable <MapDefinition> CreateMapDefinitions() { var terrain = MapTerrain.FromStream(ResourceManager.GetResourceStream("Terrain1.att")); var lorencia = this.context.Create <MapDefinition>("Lorencia", (short)0, terrain); yield return(lorencia); }
/// <summary> /// Generate a random MapPoint within boundaries. /// </summary> /// <param name="minx">Minimum X Boundary</param> /// <param name="miny">Minmum Y Boundary</param> /// <param name="maxx">Maximum X Boundary</param> /// <param name="maxy">Maximum Y Boundary</param> /// <returns>new point.</returns> public MapPoint GeneratePoint(int minx, int miny, int maxx, int maxy, MapTerrain mt) { int X = rand.Next(minx, maxx); int Y = rand.Next(miny, maxy); return(new MapPoint(X, Y, mt)); }
private static void WriteTerrain(BinaryWriter writer, MapTerrain terrain) { foreach (var row in terrain.Ground) { foreach (var tile in row) { writer.Write((byte)tile.TerrainType); if (tile.RiverType != RiverType.NoRiver) { writer.Write((byte)tile.RiverType); writer.Write((byte)tile.RiverDirection); } if (tile.RoadType != RoadType.NoRoad) { writer.Write((byte)tile.RoadType); writer.Write((byte)tile.RoadDirection); } writer.Write((byte)tile.DisplayOptions); } } if (terrain.Undrground != null) { foreach (var row in terrain.Undrground) { foreach (var tile in row) { writer.Write((byte)tile.TerrainType); } } } }
/// <summary> /// Open the door at the requested location. Returns true if the door was successfully opened /// </summary> /// <param name="p"></param> /// <param name="doorLocation"></param> /// <returns></returns> internal bool OpenDoor(int level, Point doorLocation) { try { //Check there is a door here MapTerrain doorTerrain = GetTerrainAtPoint(player.LocationLevel, doorLocation); if (doorTerrain != MapTerrain.ClosedDoor) { return(false); } //Open the door levels[level].mapSquares[doorLocation.x, doorLocation.y].Terrain = MapTerrain.OpenDoor; levels[level].mapSquares[doorLocation.x, doorLocation.y].SetOpen(); //This is very inefficient since it resets the whole level. Could just do the door //RefreshTCODMap(level); //More efficient version levelTCODMaps[level].SetCell(doorLocation.x, doorLocation.y, !levels[level].mapSquares[doorLocation.x, doorLocation.y].BlocksLight, levels[level].mapSquares[doorLocation.x, doorLocation.y].Walkable); return(true); } catch (ApplicationException) { //Not a valid location - should not occur LogFile.Log.LogEntry("Non-valid location for door requested"); return(false); } }
/// <summary>Initializes a new instance of the <see cref="MapDefinition"/> class.</summary> public MapDefinition(string name, short number, MapTerrain terrain) { this.Number = number; this.Name = name; this.Terrain = terrain; this.Gates = new List <MapGate>(); }
/// <summary> /// Generate a point adjacent to another point. /// </summary> /// <param name="mt">Reference point</param> /// <param name="dist">Distance from point</param> /// <param name="rad"></param> /// <returns>AdjacentPoint</returns> public MapPoint GenerateAdjacentPoint(MapPoint mt, int dist, int angl, MapTerrain mter) { Random rand = new Random(); double angle = Math.PI * angl / 180; double xnew = dist * Math.Cos(angle) - dist * Math.Sin(angle); double ynew = dist * Math.Sin(angle) + dist * Math.Cos(angle); return(new MapPoint((int)xnew + mt.X, (int)ynew + mt.Y, mter)); }
/// <summary> /// Add a range of MapPoints but exclude points of a certain terrain. /// </summary> /// <param name="pg">PointGroup to add</param> /// <param name="mt">MapTerrain to ignore.</param> public void AddRangeAlpha(PointGroup pg, MapTerrain mt) { foreach (MapPoint mp in pg) { if (mp.Terrain != mt) { this.Add(mp); } } }
bool BlockedFlightAt(IntVector2 t) { MapTerrain mt = Obstructions.Instance.TerrainAt(t); if (mt && mt.wall) { return(true); } return(false); }
/// <summary> /// Each pixel in the texture represents the data of a tile /// </summary> /// <param name="sourceImage"></param> /// <returns></returns> MapTerrain[] GetMapData(ref Texture2D level, ref ColorToTerrain[] colorMapings, int xSize, int ySize) { MapTerrain[] mapData = new MapTerrain[xSize * ySize]; for (int y = 0, i = 0; y < ySize; y++) { for (int x = 0; x < xSize; x++, i++) { Color pixelColor = level.GetPixel(x, y); Debug.Log(pixelColor.ToString()); mapData[i] = GetTerrainFromColor(pixelColor, ref colorMapings); } } return(mapData); }
/// <summary> /// Generate a cluster of points that are adjacent to one another. /// </summary> /// <param name="x">Start X</param> /// <param name="y">Start Y</param> /// <param name="points">Number of points in cluster</param> /// <param name="mt">MapTerrain to color point.</param> /// <returns>new PointGroup</returns> public PointGroup GenerateCluster(int x, int y, int points, MapTerrain mt, int dist) { PointGroup newpg = new PointGroup(); PointGenerator pg = new PointGenerator(); for (int i = 0; i < points; i++) { if (i == 0) { newpg.Add(new MapPoint(x, y, mt)); } else { newpg.Add(pg.GenerateAdjacentPoint(newpg[rand.Next(newpg.Count - 1)], dist, rand.Next(360), mt)); } } return(newpg); }
bool BlockedAt(IntVector2 t) { MapTerrain mt = Obstructions.Instance.TerrainAt(t); MapObject o = Obstructions.Instance.MobileAt(t); if (mt && (mt.water || mt.wall)) { return(true); } if (o) { MovementRules mr = o.GetComponent <MovementRules>(); if (mr) { if (mr.team == team) { return(false); } } return(true); // unit block } return(false); }
public override bool CheckAction(bool isMove, Point deltaMove, bool otherMoveSuccess) { Player player = Game.Dungeon.Player; Dungeon dungeon = Game.Dungeon; Point locationAfterMove = player.LocationMap + deltaMove; //First move is pushing off against a wall //Second move is jumping over 0 or more creatures //Not a move or attack = reset if (!isMove) { moveCounter = 0; return(false); } //First move //Must be push off wall if (moveCounter == 0) { //Must be wall MapTerrain pushTerrain = dungeon.Levels[player.LocationLevel].mapSquares[locationAfterMove.x, locationAfterMove.y].Terrain; if (pushTerrain != MapTerrain.Wall && pushTerrain != MapTerrain.ClosedDoor) { moveCounter = 0; return(false); } //Is wall //Success moveCounter = 1; //Need to remember the direction of the first push, since we can only vault opposite this xDelta = locationAfterMove.x - player.LocationMap.x; yDelta = locationAfterMove.y - player.LocationMap.y; LogFile.Log.LogEntryDebug("Wall push stage 1", LogDebugLevel.Medium); return(true); } //Second move //Must be push off same wall if (moveCounter == 1) { int thisDeltaX = locationAfterMove.x - player.LocationMap.x; int thisDeltaY = locationAfterMove.y - player.LocationMap.y; //Must be exactly the same move as last time if (thisDeltaX != xDelta || thisDeltaY != yDelta) { FailPattern(); return(false); } //Success moveCounter = 2; LogFile.Log.LogEntryDebug("Wall push stage 2", LogDebugLevel.Medium); return(true); } //if (moveCounter == 2) else { //Only implementing this for player for now! //Check that this direction opposes the initial push int secondXDelta = locationAfterMove.x - player.LocationMap.x; int secondYDelta = locationAfterMove.y - player.LocationMap.y; if (secondXDelta != -xDelta || secondYDelta != -yDelta) { //Reset FailPattern(); return(false); } //OK, going in right direction //Firstly we need to check that there is a monster to push! SquareContents squareContents = dungeon.MapSquareContents(player.LocationLevel, new Point(locationAfterMove.x, locationAfterMove.y)); if (squareContents.monster == null) { FailNoMonsterToPush(); return(false); } //Need to check what's ahead of the pushed monster Map thisMap = dungeon.Levels[player.LocationLevel]; //We run forward from the monster position until we find a square that will make them stop //Default is to leave them where they are //(Remember to check the creature path finding / AI) //We also set a maximum push-back //Default is not to move the creature anywhere monsterToMove = squareContents.monster; squareToMoveMonsterTo = new Point(locationAfterMove.x, locationAfterMove.y); //Start at the square behind the monster int loopCounter = 1; do { int squareX = locationAfterMove.x + secondXDelta * loopCounter; int squareY = locationAfterMove.y + secondYDelta * loopCounter; //Off the map if (squareX < 0 || squareX > thisMap.width) { break; } if (squareY < 0 || squareY > thisMap.height) { break; } MapTerrain squareTerrain = thisMap.mapSquares[squareX, squareY].Terrain; SquareContents thisContents = dungeon.MapSquareContents(player.LocationLevel, new Point(squareX, squareY)); //Into something non-walkable if (!thisMap.mapSquares[squareX, squareY].Walkable) { break; } //Is there a monster here if (thisContents.monster != null) { break; } //Nothing here, this would be an OK location for the creature to end up squareToMoveMonsterTo = new Point(squareX, squareY); loopCounter++; } while (loopCounter < 6); //Complete move moveCounter = 3; return(true); } }
public override bool CheckAction(bool isMove, Point deltaMove, bool otherMoveSuccess) { Player player = Game.Dungeon.Player; Dungeon dungeon = Game.Dungeon; //First move is no direction move //Not a move or attack = reset if (!isMove) { moveCounter = 0; return(false); } //First move if (moveCounter == 0) { //Must be no direction if (deltaMove != new Point(0, 0)) { return(false); } //Must be next to a monster int isMonster = 0; if (IsMonster(-1, -1)) { isMonster++; } if (IsMonster(-1, 0)) { isMonster++; } if (IsMonster(-1, 1)) { isMonster++; } if (IsMonster(0, -1)) { isMonster++; } if (IsMonster(0, 1)) { isMonster++; } if (IsMonster(1, -1)) { isMonster++; } if (IsMonster(1, 0)) { isMonster++; } if (IsMonster(1, 1)) { isMonster++; } if (isMonster == 0) { LogFile.Log.LogEntryDebug("Evade not started - no monster", LogDebugLevel.Medium); return(false); } //Otherwise we're on moveCounter = 1; LogFile.Log.LogEntryDebug("Evade started", LogDebugLevel.Medium); return(true); } //Second move //Any direction with a monster. We skip past it and then one more square in that direction if we can if (moveCounter == 1) { //Needs to be a monster in the direction of movement Point locationAfterMove = player.LocationMap + deltaMove; SquareContents squareContents = dungeon.MapSquareContents(player.LocationLevel, locationAfterMove); //Bad terrain if (!dungeon.MapSquareIsWalkable(player.LocationLevel, locationAfterMove)) { FailBlocked(); return(false); } //No Monster if (squareContents.monster == null) { FailNoMonster(); return(false); } //Charmed monster if (squareContents.monster != null && squareContents.monster.Charmed) { FailNoMonster(); return(false); } //OK, so we have a monster to evade //Check the 2 squares behind it to find one to jump to (adapted from WallVault) int secondXDelta = locationAfterMove.x - player.LocationMap.x; int secondYDelta = locationAfterMove.y - player.LocationMap.y; Map thisMap = dungeon.Levels[player.LocationLevel]; //We run forward until we find a square to jump to //If we run off the map or can't find a good square, we abort and the move is cancelled //Try to jump max of 2 squares, or fall back to one //Start square after monster int loopCounter = 2; //It's not possible to evade 2 monsters in a row, so worse case we stay where we are squareToMoveTo = player.LocationMap; do { int squareX = player.LocationMap.x + secondXDelta * loopCounter; int squareY = player.LocationMap.y + secondYDelta * loopCounter; //Off the map if (squareX < 0 || squareX > thisMap.width) { break; } if (squareY < 0 || squareY > thisMap.height) { break; } MapTerrain squareTerrain = thisMap.mapSquares[squareX, squareY].Terrain; squareContents = dungeon.MapSquareContents(player.LocationLevel, new Point(squareX, squareY)); //Into a wall if (!thisMap.mapSquares[squareX, squareY].Walkable) { break; } //Is there no monster here? If so, then OK square to jump to if (squareContents.monster != null) { break; } //Empty, set this as OK and carry on looping squareToMoveTo = new Point(squareX, squareY); loopCounter++; } while (loopCounter < 4); //Check the status of the evade if (squareToMoveTo == player.LocationMap) { FailBlocked(); return(false); } //Otherwise we are on and will move in DoMove moveCounter = 2; } return(true); }
public MapPoint(int x, int y, MapTerrain mt) { X = x; Y = y; Terrain = mt; }
private void buttonSave_Click(object sender, EventArgs e) { SaveRule(); SaveScenario(); if (!Id.HasValue) { map = new Map(); _context.Maps.Add(map); } map.Name = txtName.Text; map.ColourMapName = txtColourMap.Text; map.Description = txtDescription.Text; for (int y = 0; y < GRID_SIZE; y++) { for (int x = 0; x < GRID_SIZE; x++) { var cell = _context.TerrainMaps.SingleOrDefault(cell => cell.Map == map && cell.RowId == y && cell.ColumnId == x); if (cell == null) { cell = new MapTerrain() { RowId = y, ColumnId = x, Map = map, }; _context.TerrainMaps.Add(cell); } cell.TerrainId = terrainMap[y][x]; } } foreach (var scenarioData in scenarioList) { var scenario = _context.Scenarios.SingleOrDefault(x => x.Id == scenarioData.Id); if (scenario == null) { scenario = new Scenario() { Map = map, }; _context.Scenarios.Add(scenario); } scenario.Name = scenarioData.Name; scenario.Description = scenarioData.Description; scenario.IsDefault = scenarioData.IsDefault; scenario.EnemyDeckId = scenarioData.EnemyDeckId; _context.SaveChanges(); if (scenarioData.Id == null) { scenarioList.Single(x => x == scenarioData).Id = scenario.Id; } foreach (var ruleData in scenarioData.ScenarioRules) { var rule = _context.ScenarioRules.SingleOrDefault(x => x.Id == ruleData.Id); if (rule == null) { rule = new ScenarioRule(); _context.ScenarioRules.Add(rule); } rule.Name = ruleData.Name; rule.Description = ruleData.Description; var scenarioRuleSet = _context.ScenarioRuleSets.SingleOrDefault(x => x.Scenario == scenario && x.Rule == rule); if (scenarioRuleSet == null) { scenarioRuleSet = new ScenarioRuleSet(); rule.ScenarioRules.Add(scenarioRuleSet); scenario.ScenarioRuleSet.Add(scenarioRuleSet); _context.ScenarioRuleSets.Add(scenarioRuleSet); } } var objectiveList = new List <Objective>(); foreach (var objectiveData in scenarioData.Objectives) { var objective = _context.Objectives.SingleOrDefault(x => x.Id == objectiveData.Id); if (objective == null) { objective = new Objective(); _context.Objectives.Add(objective); } objective.Name = objectiveData.Name; objective.Red = objectiveData.Color.R; objective.Green = objectiveData.Color.G; objective.Blue = objectiveData.Color.B; objectiveList.Add(objective); } for (int y = 0; y < GRID_SIZE; y++) { for (int x = 0; x < GRID_SIZE; x++) { var deploymentCell = _context.DeploymentMaps.SingleOrDefault(cell => cell.Scenario == scenario && cell.RowId == y && cell.ColumnId == x); if (deploymentCell == null) { deploymentCell = new MapDeployment() { RowId = y, ColumnId = x, Scenario = scenario, }; _context.DeploymentMaps.Add(deploymentCell); } deploymentCell.PlayerId = scenarioData.DeploymentMap[y][x]; var objectiveCell = _context.ObjectiveMaps.SingleOrDefault(cell => cell.Scenario == scenario && cell.RowId == y && cell.ColumnId == x); if (objectiveCell == null) { objectiveCell = new MapObjective() { RowId = y, ColumnId = x, Scenario = scenario, }; _context.ObjectiveMaps.Add(objectiveCell); } var objectiveIndex = scenarioData.ObjectiveMap[y][x]; if (!objectiveIndex.HasValue) { objectiveCell.ObjectiveId = null; } else { objectiveCell.Objective = objectiveList[objectiveIndex.Value]; } } } } if (Id.HasValue) { var removeScenarios = map.Scenarios.Where(x => !scenarioList.Select(y => y.Id).Contains(x.Id)); foreach (var removeScenario in removeScenarios) { removeScenario.DeploymentMap.Clear(); removeScenario.ScenarioRuleSet.Clear(); var removeObjectives = removeScenario.ObjectiveMap.Where(x => x.ObjectiveId.HasValue).Select(x => x.Objective); _context.Objectives.RemoveRange(removeObjectives); removeScenario.ObjectiveMap.Clear(); } _context.Scenarios.RemoveRange(removeScenarios); foreach (var scenario in map.Scenarios) { var scenarioData = scenarioList.Single(x => x.Id == scenario.Id); var removeRuleSets = scenario.ScenarioRuleSet.Where(x => !scenarioData.ScenarioRules.Any(y => y.Id == x.RuleId)); _context.ScenarioRuleSets.RemoveRange(removeRuleSets); var removeObjectives = _context.Objectives.Where(x => !x.MapObjectives.Any()); _context.Objectives.RemoveRange(removeObjectives); } } _context.SaveChanges(); this.DialogResult = DialogResult.OK; this.Close(); }
public void AddRubbleType(MapTerrain terrain) { rubbleType.Add(terrain); possibleEmptyTypes.Add(terrain); }
/// <summary> /// Generate a PointGroup with points adjacent to another PointGroup. /// </summary> /// <param name="size"></param> /// <param name="distance"></param> /// <param name="angle"></param> /// <param name="startbox"></param> /// <returns>Adjacent point collection.</returns> public PointGroup GenerateAdjacentBox(int size, int distance, int angle, PointGroup startbox, MapTerrain mt) { PointGenerator pg = new PointGenerator(); double radangle = angle * Math.PI / 180; MapPoint mp = pg.GenerateAdjacentPoint(startbox.GetAverage(), distance, angle, mt); return(GenerateBox(mp.X - size / 2, mp.Y - size / 2, mp.X + size / 2, mp.Y + size / 2, startbox.Count, mt)); }
public RandomEncounterQuery(MapTerrain terrain, RandomEncounterType type) { Terrain = terrain; Type = type; }
private void UpdateTile(TileProp tileToUpdate, MapTerrain newTerrain) { tileToUpdate.terrain = newTerrain; tileToUpdate.SpriteSync(); }
public void AddWallType(MapTerrain terrain) { wallType.Add(terrain); }
public void SetOpenSquareTerrainType(MapTerrain type) { openTerrainType.Add(type); }
/// <summary> /// Generates a chain that deviates slightly by a supplied angle /// </summary> /// <param name="x1">X Start</param> /// <param name="y1">Y Start</param> /// <param name="points">Number of points to draw.</param> /// <param name="dist">Maximum distance of point.</param> /// <param name="startangle">Angle to start in</param> /// <param name="anglebound">+- angle to deviate from.</param> /// <returns>generated PointGroup</returns> public PointGroup GenerateChain(int x1, int y1, int points, int dist, int startangle, int anglebound, MapTerrain mt) { PointGenerator pg = new PointGenerator(); PointGroup mtc = new PointGroup(); mtc.Add(new MapPoint(x1, y1, mt)); for (int i = 1; i < points; i++) { mtc.Add(pg.GenerateAdjacentPoint((MapPoint)mtc[mtc.Count - 1], rand.Next(1, dist), rand.Next(-anglebound, anglebound), mt)); } return(mtc); }
public TerrainFlipTrigger(MapTerrain terrainToFlipTo, string triggerID) { Triggered = false; flipToTerrain = terrainToFlipTo; this.triggerID = triggerID; }
private void DrawConnectingCorriderBetweenChildren(Map baseMap) { Random rand = MapGeneratorBSP.rand; if (split == SplitType.Horizontal) { //We are guaranteed that rays from the split into the left and right child will not hit an obstruction //(from any y) //However, routing a L shaped corridor between the rays is only guaranteed to be possible down the edge of the BSP tile //So after finding start and end Y from projected ray we just guess an L and check that it works before doing //Cast rays from the split into the left child //Look for a corridor or accessable room int leftY; int leftX = -1; do { //Random y coord leftY = y + rand.Next(height); //Don't go quite to the left extent (x) - the 2 look ahead will fix this for (int i = x + actualSplit - 1; i > x; i--) { //Look ahead 2 MapTerrain terrainNext = baseMap.mapSquares[i, leftY].Terrain; MapTerrain terrainNext2 = baseMap.mapSquares[i - 1, leftY].Terrain; //A corridor is OK if (terrainNext == MapTerrain.Corridor) { leftX = i; break; } //A wall with empty or corridor behind it is OK else if (terrainNext == MapTerrain.Wall && terrainNext2 != MapTerrain.Wall) { leftX = i; break; } //A corridor 'seen coming' we can short cut to else if (terrainNext2 == MapTerrain.Corridor) { leftX = i - 1; break; } //A 1-thick wall is OK else if (terrainNext == MapTerrain.Wall && terrainNext2 == MapTerrain.Wall) { //No good break; } } } while (leftX == -1); //Cast ray into right child int rightY; int rightX = -1; do { //Random y coord rightY = y + rand.Next(height); //Don't go quite to the right extent (x) - the 2 look ahead will fix this for (int i = x + actualSplit; i < x + width - 1; i++) { //Look ahead 2 MapTerrain terrainNext = baseMap.mapSquares[i, rightY].Terrain; MapTerrain terrainNext2 = baseMap.mapSquares[i + 1, rightY].Terrain; //Any corridor is OK if (terrainNext == MapTerrain.Corridor) { rightX = i; break; } //A wall with empty or corridor behind it is OK else if (terrainNext == MapTerrain.Wall && terrainNext2 != MapTerrain.Wall) { rightX = i; break; } //A corridor 'seen coming' we can short cut too else if (terrainNext2 == MapTerrain.Corridor) { rightX = i + 1; break; } //A 1-thick wall is OK else if (terrainNext == MapTerrain.Wall && terrainNext2 == MapTerrain.Wall) { //No good break; } } } while (rightX == -1); //Screen.Instance.DrawMapDebugHighlight(baseMap, leftX, leftY, rightX, rightY); //Now route a L corridor from (leftX, leftY) to (rightX, rightY) //The L bend can occur within X: leftSafeX -> rightSafeX List <Point> corridorRoute = new List <Point>(rightX - leftX + Math.Abs(rightY - leftY)); bool notValidPath = false; //Keep trying until we get a valid path (at least one is guaranteed) do { corridorRoute.Clear(); notValidPath = false; //L bend set randonly int lBendX = leftX + 1 + rand.Next(rightX - leftX); for (int i = leftX; i <= lBendX; i++) { corridorRoute.Add(new Point(i, leftY)); } int startY; int endY; if (leftY > rightY) { //down startY = rightY; endY = leftY; } else { startY = leftY; endY = rightY; } for (int j = startY + 1; j < endY; j++) { corridorRoute.Add(new Point(lBendX, j)); } for (int i = lBendX; i <= rightX; i++) { corridorRoute.Add(new Point(i, rightY)); } //Check this path for validity //Look for walls but ignore the first and last squares for (int i = 1; i < corridorRoute.Count - 1; i++) { if (baseMap.mapSquares[corridorRoute[i].x, corridorRoute[i].y].Terrain == MapTerrain.Wall) { notValidPath = true; break; } } } while (notValidPath); //We now have a valid path so draw it foreach (Point sq in corridorRoute) { baseMap.mapSquares[sq.x, sq.y].Terrain = MapTerrain.Corridor; baseMap.mapSquares[sq.x, sq.y].SetOpen(); } } else { //Vertical //We are guaranteed that rays from the split into the left and right child will not hit an obstruction //(from any y) //However, routing a L shaped corridor between the rays is only guaranteed to be possible down the edge of the BSP tile //So after finding start and end Y from projected ray we just guess an L and check that it works before doing //Cast rays from the split into the left child //Look for a corridor or accessable room int leftX; int leftY = -1; do { //Random x coord leftX = x + rand.Next(width); //Don't go quite to the left extent (y) - the 2 look ahead will fix this for (int i = y + actualSplit - 1; i > y; i--) { //Look ahead 2 MapTerrain terrainNext = baseMap.mapSquares[leftX, i].Terrain; MapTerrain terrainNext2 = baseMap.mapSquares[leftX, i - 1].Terrain; //Any corridor is OK if (terrainNext == MapTerrain.Corridor) { leftY = i; break; } //A wall with empty or corridor behind it is OK else if (terrainNext == MapTerrain.Wall && terrainNext2 != MapTerrain.Wall) { leftY = i; break; } //A corridor 'seen coming' we can short cut too else if (terrainNext2 == MapTerrain.Corridor) { leftY = i - 1; break; } //A 1-thick wall is OK else if (terrainNext == MapTerrain.Wall && terrainNext2 == MapTerrain.Wall) { //No good break; } } } while (leftY == -1); //Cast ray into right child int rightX; int rightY = -1; do { //Random y coord rightX = x + rand.Next(width); //Don't go quite to the right extent (x) - the 2 look ahead will fix this for (int i = y + actualSplit; i < y + height - 1; i++) { //Look ahead 2 MapTerrain terrainNext = baseMap.mapSquares[rightX, i].Terrain; MapTerrain terrainNext2 = baseMap.mapSquares[rightX, i + 1].Terrain; //Any corridor is OK if (terrainNext == MapTerrain.Corridor) { rightY = i; break; } //A wall with empty or corridor behind it is OK else if (terrainNext == MapTerrain.Wall && terrainNext2 != MapTerrain.Wall) { rightY = i; break; } //A corridor 'seen coming' we can short cut too else if (terrainNext2 == MapTerrain.Corridor) { rightY = i + 1; break; } //A 1-thick wall is OK else if (terrainNext == MapTerrain.Wall && terrainNext2 == MapTerrain.Wall) { //No good break; } } } while (rightY == -1); //Now route a L corridor from (leftX, leftY) to (rightX, rightY) //The L bend can occur within X: leftSafeX -> rightSafeX List <Point> corridorRoute = new List <Point>(Math.Abs(rightX - leftX) + rightY - leftY); bool notValidPath = false; //Keep trying until we get a valid path (at least one is guaranteed) do { corridorRoute.Clear(); notValidPath = false; //L bend set randonly int lBendY = leftY + 1 + rand.Next(rightY - leftY); for (int i = leftY; i <= lBendY; i++) { corridorRoute.Add(new Point(leftX, i)); } int startX; int endX; if (leftX > rightX) { //down startX = rightX; endX = leftX; } else { startX = leftX; endX = rightX; } for (int j = startX + 1; j < endX; j++) { corridorRoute.Add(new Point(j, lBendY)); } for (int i = lBendY; i <= rightY; i++) { corridorRoute.Add(new Point(rightX, i)); } //Check this path for validity //Look for walls but ignore the first and last squares for (int i = 1; i < corridorRoute.Count - 1; i++) { if (baseMap.mapSquares[corridorRoute[i].x, corridorRoute[i].y].Terrain == MapTerrain.Wall) { notValidPath = true; break; } } } while (notValidPath); //We now have a valid path so draw it foreach (Point sq in corridorRoute) { baseMap.mapSquares[sq.x, sq.y].Terrain = MapTerrain.Corridor; baseMap.mapSquares[sq.x, sq.y].SetOpen(); } } }
/// <summary> /// Generate random points within a box /// </summary> /// <param name="minx">Minimum X Bound</param> /// <param name="miny">Minimum Y Bound</param> /// <param name="maxx">Maximum X Bound</param> /// <param name="maxy">Maximum Y Bound</param> /// <param name="points">Number of points to draw.</param> /// <returns>generated MapPointGroup</returns> public PointGroup GenerateBox(int minx, int miny, int maxx, int maxy, int points, MapTerrain mt) { PointGenerator pg = new PointGenerator(); PointGroup mpc = new PointGroup(); for (int i = 0; i < points; i++) { mpc.Add(pg.GeneratePoint(minx, miny, maxx, maxy, mt)); } return(mpc); }
private void MouseLeaveEventHandler(object sender, MouseEventArgs e) { MapTerrain.RefreshGrid(); Cursor = Cursors.Arrow; }
public override bool CheckAction(bool isMove, Point deltaMove, bool otherMoveSuccess) { Player player = Game.Dungeon.Player; Dungeon dungeon = Game.Dungeon; //First move is pushing off against a wall //Second move is jumping over 0 or more creatures Point locationAfterMove = player.LocationMap + deltaMove; //Not a move or attack = reset if (!isMove) { moveCounter = 0; return(false); } //First move if (moveCounter == 0) { //Must be non-walkable to push off bool pushTerrainWalkable = dungeon.Levels[player.LocationLevel].mapSquares[locationAfterMove.x, locationAfterMove.y].Walkable; if (pushTerrainWalkable) { moveCounter = 0; return(false); } //Is wall //Success moveCounter = 1; //Need to remember the direction of the first push, since we can only vault opposite this xDelta = locationAfterMove.x - player.LocationMap.x; yDelta = locationAfterMove.y - player.LocationMap.y; LogFile.Log.LogEntryDebug("Vault backstab stage 1", LogDebugLevel.Medium); return(true); } //Second move if (moveCounter == 1) { //Only implementing this for player for now! //Check that this direction opposes the initial push int secondXDelta = locationAfterMove.x - player.LocationMap.x; int secondYDelta = locationAfterMove.y - player.LocationMap.y; if (secondXDelta != -xDelta || secondYDelta != -yDelta) { //Reset moveCounter = 0; return(false); } //OK, going in right direction //Need to check what's ahead of the player //Empty squares, can jump 2 Map thisMap = dungeon.Levels[player.LocationLevel]; //We run forward until we find a square to jump to //If we run off the map or can't find a good square, we abort and the move is cancelled //First empty square int loopCounter = 1; do { int squareX = player.LocationMap.x + secondXDelta * loopCounter; int squareY = player.LocationMap.y + secondYDelta * loopCounter; //Off the map if (squareX < 0 || squareX > thisMap.width) { NoWhereToJumpFail(); return(false); } if (squareY < 0 || squareY > thisMap.height) { NoWhereToJumpFail(); return(false); } MapTerrain squareTerrain = thisMap.mapSquares[squareX, squareY].Terrain; SquareContents squareContents = dungeon.MapSquareContents(player.LocationLevel, new Point(squareX, squareY)); //Into a wall if (!thisMap.mapSquares[squareX, squareY].Walkable) { NoWhereToJumpFail(); return(false); } //Adjacent square, must be a monster if (loopCounter == 1 && squareContents.monster == null) { NoMonsterToVaultFail(); return(false); } //Is there no monster here? If so, this is our destination if (squareContents.monster == null) { squareToMoveTo = new Point(squareX, squareY); moveCounter = 2; break; } //Monster here? Keep looping until we hit an empty or something bad loopCounter++; } while (true); LogFile.Log.LogEntryDebug("Vault backstab stage 2", LogDebugLevel.Medium); return(true); } //Third move, has to be attack in the opposite direction to the vault (i.e. same as original push) if (moveCounter == 2) { //Check direction is correct int secondXDelta = locationAfterMove.x - player.LocationMap.x; int secondYDelta = locationAfterMove.y - player.LocationMap.y; if (secondXDelta != xDelta || secondYDelta != yDelta) { //Reset moveCounter = 0; return(false); } //Check there is a monster to attack SquareContents squareContents = dungeon.MapSquareContents(player.LocationLevel, new Point(locationAfterMove.x, locationAfterMove.y)); //Is there a monster here? If so, we will attack it if (squareContents.monster != null && !squareContents.monster.Charmed) { target = squareContents.monster; moveCounter = 3; return(true); } else { //This implies the monster is really fast and going elsewhere which I guess is possible LogFile.Log.LogEntryDebug("VaultBackstab failed due to no-one to stab!", LogDebugLevel.Medium); moveCounter = 0; return(false); } } LogFile.Log.LogEntryDebug("Vault backstab move counter wrong", LogDebugLevel.Medium); return(false); }
public void SetClosedSquareTerrainType(MapTerrain type) { closedTerrainType.Add(type); }
public static void OverrideTerrainChar(MapTerrain terrain, char c) { TerrainChars[terrain] = c; }
public Tile(MapTerrain terrain, int x, int y) { terrain_ = terrain; x_ = x; y_ = y; }
public void Add(MapTerrain t) { terrain.Add(IntVector2.RoundFrom(t.transform.position), t); }