Beispiel #1
0
    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
    }
Beispiel #2
0
    public MapTerrain TerrainAt(IntVector2 iv2)
    {
        MapTerrain t = null;

        terrain.TryGetValue(iv2, out t);
        return(t);
    }
Beispiel #3
0
        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);
                    }
                }
            }
        }
Beispiel #6
0
        /// <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);
            }
        }
Beispiel #7
0
 /// <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));
        }
Beispiel #9
0
 /// <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);
         }
     }
 }
Beispiel #10
0
    bool BlockedFlightAt(IntVector2 t)
    {
        MapTerrain mt = Obstructions.Instance.TerrainAt(t);

        if (mt && mt.wall)
        {
            return(true);
        }
        return(false);
    }
Beispiel #11
0
    /// <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);
    }
Beispiel #12
0
        /// <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);
        }
Beispiel #13
0
    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);
    }
Beispiel #14
0
        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);
            }
        }
Beispiel #15
0
        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);
        }
Beispiel #16
0
 public MapPoint(int x, int y, MapTerrain mt)
 {
     X = x; Y = y; Terrain = mt;
 }
Beispiel #17
0
        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);
 }
Beispiel #19
0
        /// <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);
 }
Beispiel #23
0
 public void SetOpenSquareTerrainType(MapTerrain type)
 {
     openTerrainType.Add(type);
 }
Beispiel #24
0
        /// <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;
 }
Beispiel #26
0
        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();
                }
            }
        }
Beispiel #27
0
        /// <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);
        }
Beispiel #28
0
 private void MouseLeaveEventHandler(object sender, MouseEventArgs e)
 {
     MapTerrain.RefreshGrid();
     Cursor = Cursors.Arrow;
 }
 public void SetOpenSquareTerrainType(MapTerrain type)
 {
     openTerrainType.Add(type);
 }
Beispiel #30
0
        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);
 }
Beispiel #32
0
 public static void OverrideTerrainChar(MapTerrain terrain, char c)
 {
     TerrainChars[terrain] = c;
 }
Beispiel #33
0
 public Tile(MapTerrain terrain, int x, int y)
 {
     terrain_ = terrain;
     x_       = x;
     y_       = y;
 }
Beispiel #34
0
 public void Add(MapTerrain t)
 {
     terrain.Add(IntVector2.RoundFrom(t.transform.position), t);
 }
Beispiel #35
0
 public void SetClosedSquareTerrainType(MapTerrain type)
 {
     closedTerrainType.Add(type);
 }
 public static void OverrideTerrainChar(MapTerrain terrain, char c)
 {
     TerrainChars[terrain] = c;
 }