Ejemplo n.º 1
0
        public override void Apply(T map)
        {
            Grid.LocTest checkGround = (Loc testLoc) =>
            {
                if (!Collision.InBounds(map.Width, map.Height, testLoc))
                {
                    return(false);
                }
                return(map.Tiles[testLoc.X][testLoc.Y].TileEquivalent(map.RoomTerrain) && !map.HasTileEffect(testLoc));
            };
            Grid.LocTest checkBlock = (Loc testLoc) =>
            {
                if (!Collision.InBounds(map.Width, map.Height, testLoc))
                {
                    return(false);
                }
                return(map.Tiles[testLoc.X][testLoc.Y].TileEquivalent(map.WallTerrain));
            };

            List <LocRay4> rays = Detection.DetectWalls(((IViewPlaceableGenContext <MapGenEntrance>)map).GetLoc(0), new Rect(0, 0, map.Width, map.Height), checkBlock, checkGround);

            EffectTile    effect = new EffectTile(LockedTile, true);
            TileListState state  = new TileListState();

            effect.TileStates.Set(state);

            List <Loc> freeTiles = new List <Loc>();
            LocRay4?   ray       = PlaceRoom(map, rays, effect, freeTiles);

            if (ray != null)
            {
                PlaceEntities(map, freeTiles);
            }
        }
        private void fillStroke(CanvasStroke <EffectTile> stroke)
        {
            if (!Collision.InBounds(ZoneManager.Instance.CurrentMap.Width, ZoneManager.Instance.CurrentMap.Height, stroke.CoveredRect.Start))
            {
                return;
            }

            EffectTile tile = ZoneManager.Instance.CurrentMap.Tiles[stroke.CoveredRect.Start.X][stroke.CoveredRect.Start.Y].Effect;

            Dictionary <Loc, EffectTile> brush = new Dictionary <Loc, EffectTile>();
            EffectTile brushTile = stroke.GetBrush(stroke.CoveredRect.Start);

            RogueElements.Grid.FloodFill(new Rect(0, 0, ZoneManager.Instance.CurrentMap.Width, ZoneManager.Instance.CurrentMap.Height),
                                         (Loc testLoc) =>
            {
                if (brush.ContainsKey(testLoc))
                {
                    return(true);
                }
                return(tile.ID != ZoneManager.Instance.CurrentMap.Tiles[testLoc.X][testLoc.Y].Effect.ID);
            },
                                         (Loc testLoc) =>
            {
                return(true);
            },
                                         (Loc testLoc) =>
            {
                brush[testLoc] = new EffectTile(brushTile, testLoc);
            },
                                         stroke.CoveredRect.Start);

            DiagManager.Instance.DevEditor.MapEditor.Edits.Apply(new DrawTileUndo(brush));
        }
Ejemplo n.º 3
0
        public override void DrawOnMap(T map)
        {
            if (this.Draw.Width != this.Tiles.Length || this.Draw.Height != this.Tiles[0].Length)
            {
                this.DrawMapDefault(map);
                return;
            }

            base.DrawOnMap(map);

            //create new bosses from the spawns, adjusting their locations
            MobSpawnState mobSpawnState = new MobSpawnState();

            foreach (MobSpawn spawn in Bosses)
            {
                MobSpawn    newSpawn = spawn.Copy();
                MobSpawnLoc setLoc   = null;
                foreach (MobSpawnExtra extra in newSpawn.SpawnFeatures)
                {
                    MobSpawnLoc extraLoc = extra as MobSpawnLoc;
                    if (extraLoc != null)
                    {
                        setLoc = extraLoc;
                        break;
                    }
                }

                if (setLoc != null)
                {
                    setLoc.Loc = setLoc.Loc + this.Draw.Start;
                }
                else
                {
                    setLoc = new MobSpawnLoc(this.Draw.Center);
                    newSpawn.SpawnFeatures.Add(setLoc);
                }
                mobSpawnState.Spawns.Add(newSpawn);
            }

            ////place the boss bounds here
            //CheckIntrudeBoundsEvent trapZone = new CheckIntrudeBoundsEvent();
            //trapZone.Bounds = new Rect(Trigger.Start + new Loc(this.Draw.Start), Trigger.Size);
            //{
            //    LockdownMapEvent lockdown = new LockdownMapEvent();
            //    lockdown.Bounds = new Rect(this.Draw.Start - new Loc(1), this.Draw.Size + new Loc(2));
            //    trapZone.Effects.Add(lockdown);
            //    trapZone.Effects.Add(new BossSpawnEvent(this.Draw, mobSpawns.ToArray()));
            //}
            //map.CheckEvents.Add(trapZone);


            EffectTile newEffect = new EffectTile(TriggerTile, true, Trigger + this.Draw.Start);

            newEffect.TileStates.Set(mobSpawnState);
            newEffect.TileStates.Set(new BoundsState(new Rect(this.Draw.Start - new Loc(1), this.Draw.Size + new Loc(2))));
            newEffect.TileStates.Set(new SongState(Song));
            ((IPlaceableGenContext <EffectTile>)map).PlaceItem(Trigger + this.Draw.Start, newEffect);
        }
Ejemplo n.º 4
0
    public float CalculateCost(Node currentNode, Node targetNode, Character character)
    {
        float cost = currentNode.CostSoFar + _basicCost;

        if (targetNode.HasEffect)
        {
            EffectTile effect = targetNode.GetEffect();
            if (effect.Type == EffectTileType.Damage)
            {
                /*
                 * maxHealth - damage
                 * > 80% = +30
                 * 50-80% = +50
                 * 0-50% = +100
                 */
                float hpPercent = (character.Properties.CurrentHealth - effect.Value) / character.Properties.Health;
                if (hpPercent > 0.8f)
                {
                    cost += 30;
                }
                else if (hpPercent < 0.5f)
                {
                    cost += 50;
                }
                else
                {
                    cost += 100;
                }
            }
            else if (effect.Type == EffectTileType.Heal)
            {
                /*
                 * cost reduce based on current character's health
                 * 100% = 0
                 * >80% = -2
                 * 50-80% = -4
                 * <50% = -6
                 */
                if (character.Properties.CurrentHealth != character.Properties.Health)
                {
                    float hpPercent = character.Properties.CurrentHealth / character.Properties.Health;
                    if (hpPercent > 0.8f)
                    {
                        cost -= 2;
                    }
                    else if (hpPercent < 0.5f)
                    {
                        cost -= 6;
                    }
                    else
                    {
                        cost -= 4;
                    }
                }
            }
        }
        return(cost);
    }
Ejemplo n.º 5
0
        protected override void PlaceBorders(T map, Dictionary <Loc, SealType> sealList)
        {
            List <Loc> keyList  = new List <Loc>();
            List <Loc> lockList = new List <Loc>();

            foreach (Loc loc in sealList.Keys)
            {
                switch (sealList[loc])
                {
                //lay down the blocks
                case SealType.Blocked:
                    map.Tiles[loc.X][loc.Y] = (Tile)map.UnbreakableTerrain.Copy();
                    break;

                case SealType.Locked:
                    lockList.Add(loc);
                    break;

                case SealType.Key:
                    keyList.Add(loc);
                    break;
                }
            }


            //choose the key tile
            int keyIndex = map.Rand.Next(keyList.Count - 1);
            Loc keyLoc   = keyList[keyIndex];

            keyList.RemoveAt(keyIndex);


            lockList.AddRange(keyList);

            //seal the tiles that are gated
            foreach (Loc loc in lockList)
            {
                map.Tiles[loc.X][loc.Y] = (Tile)map.UnbreakableTerrain.Copy();
                EffectTile newEffect = new EffectTile(LockedTile, true, loc);
                ((IPlaceableGenContext <EffectTile>)map).PlaceItem(loc, newEffect);
            }

            //finally, seal with a locked door
            {
                map.Tiles[keyLoc.X][keyLoc.Y] = (Tile)map.UnbreakableTerrain.Copy();
                EffectTile    newEffect = new EffectTile(KeyTile, true, keyLoc);
                TileListState state     = new TileListState();
                state.Tiles = lockList;
                newEffect.TileStates.Set(state);
                ((IPlaceableGenContext <EffectTile>)map).PlaceItem(keyLoc, newEffect);
            }
        }
        private void eyedropTile(Loc loc)
        {
            if (!Collision.InBounds(ZoneManager.Instance.CurrentMap.Width, ZoneManager.Instance.CurrentMap.Height, loc))
            {
                return;
            }

            EffectTile effectTile = ZoneManager.Instance.CurrentMap.Tiles[loc.X][loc.Y].Effect;

            if (effectTile.ID > -1)
            {
                setBrush(effectTile);
            }
        }
        private void setBrush(EffectTile brush)
        {
            ChosenTile  = brush.ID;
            ChosenOwner = (int)brush.Owner;
            IsDanger    = brush.Danger;
            IsRevealed  = brush.Revealed;

            List <TileState> states = new List <TileState>();

            foreach (TileState state in brush.TileStates)
            {
                states.Add(state);
            }
            TileStates.LoadFromList(states);
        }
        private EffectTile getBrush()
        {
            EffectTile brush = new EffectTile(ChosenTile, IsRevealed);

            brush.Danger = IsDanger;
            brush.Owner  = (EffectTile.TileOwner)ChosenOwner;

            List <TileState> states = TileStates.GetList <List <TileState> >();

            for (int ii = 0; ii < states.Count; ii++)
            {
                brush.TileStates.Set(states[ii]);
            }
            return(brush);
        }
        public void ProcessInput(InputManager input)
        {
            bool inWindow = Collision.InBounds(GraphicsManager.WindowWidth, GraphicsManager.WindowHeight, input.MouseLoc);

            Loc tileCoords = DungeonEditScene.Instance.ScreenCoordsToMapCoords(input.MouseLoc);

            switch (TileMode)
            {
            case TileEditMode.Draw:
            {
                EffectTile brush = getBrush();
                CanvasStroke <EffectTile> .ProcessCanvasInput(input, tileCoords, inWindow,
                                                              () => new DrawStroke <EffectTile>(tileCoords, brush),
                                                              () => new DrawStroke <EffectTile>(tileCoords, new EffectTile()),
                                                              paintStroke, ref DungeonEditScene.Instance.TileInProgress);
            }
            break;

            case TileEditMode.Rectangle:
            {
                EffectTile brush = getBrush();
                CanvasStroke <EffectTile> .ProcessCanvasInput(input, tileCoords, inWindow,
                                                              () => new RectStroke <EffectTile>(tileCoords, brush),
                                                              () => new RectStroke <EffectTile>(tileCoords, new EffectTile()),
                                                              paintStroke, ref DungeonEditScene.Instance.TileInProgress);
            }
            break;

            case TileEditMode.Fill:
            {
                EffectTile brush = getBrush();
                CanvasStroke <EffectTile> .ProcessCanvasInput(input, tileCoords, inWindow,
                                                              () => new FillStroke <EffectTile>(tileCoords, brush),
                                                              () => new FillStroke <EffectTile>(tileCoords, new EffectTile()),
                                                              fillStroke, ref DungeonEditScene.Instance.TileInProgress);
            }
            break;

            case TileEditMode.Eyedrop:
            {
                if (input[FrameInput.InputType.LeftMouse])
                {
                    eyedropTile(tileCoords);
                }
            }
            break;
            }
        }
        private void paintStroke(CanvasStroke <EffectTile> stroke)
        {
            Dictionary <Loc, EffectTile> brush = new Dictionary <Loc, EffectTile>();

            foreach (Loc loc in stroke.GetLocs())
            {
                if (!Collision.InBounds(ZoneManager.Instance.CurrentMap.Width, ZoneManager.Instance.CurrentMap.Height, loc))
                {
                    continue;
                }

                brush[loc] = new EffectTile(stroke.GetBrush(loc), loc);
            }

            DiagManager.Instance.DevEditor.MapEditor.Edits.Apply(new DrawTileUndo(brush));
        }
Ejemplo n.º 11
0
 public bool RemoveEffect(EffectTile effect)
 {
     if (HasEffect)
     {
         foreach (var gameobject in ObjectsOnTile)
         {
             EffectTile oldEffect;
             bool       ok = gameobject.TryGetComponent <EffectTile>(out oldEffect);
             if (ok && oldEffect == effect)
             {
                 ObjectsOnTile.Remove(oldEffect.gameObject);
                 oldEffect.EndEffect();
                 break;
             }
         }
         HasEffect = false;
         return(true);
     }
     return(false);
 }
Ejemplo n.º 12
0
        protected void PlaceEntities(T map, List <Loc> freeTiles)
        {
            List <EffectTile> tileTreasures = TileTreasures.GetSpawns(map);

            for (int kk = 0; kk < tileTreasures.Count && freeTiles.Count > 0; kk++)
            {
                int randIndex = map.Rand.Next(freeTiles.Count);

                EffectTile spawnedTrap = tileTreasures[kk];
                ((IPlaceableGenContext <EffectTile>)map).PlaceItem(freeTiles[randIndex], spawnedTrap);
                freeTiles.RemoveAt(randIndex);
            }

            List <MapItem> treasures = Treasures.GetSpawns(map);

            for (int kk = 0; kk < treasures.Count && freeTiles.Count > 0; kk++)
            {
                int randIndex = map.Rand.Next(freeTiles.Count);

                MapItem item = new MapItem(treasures[kk]);
                ((IPlaceableGenContext <MapItem>)map).PlaceItem(freeTiles[randIndex], item);

                freeTiles.RemoveAt(randIndex);
            }

            List <MobSpawn> guardTypes = GuardTypes.GetSpawns(map);

            for (int kk = 0; kk < guardTypes.Count && freeTiles.Count > 0; kk++)
            {
                int randIndex = map.Rand.Next(freeTiles.Count);

                MonsterTeam team    = new MonsterTeam();
                Character   newChar = guardTypes[kk].Spawn(team, map);
                newChar.CharLoc = freeTiles[randIndex];
                map.MapTeams.Add(newChar.MemberTeam);

                freeTiles.RemoveAt(randIndex);
            }
        }
Ejemplo n.º 13
0
    public bool AddEffect(EffectTile effect)
    {
        //if tile already has effect when find it and rewrite
        if (HasEffect)
        {
            foreach (var gameobject in ObjectsOnTile)
            {
                EffectTile oldEffect;
                bool       ok = gameobject.TryGetComponent <EffectTile>(out oldEffect);
                if (ok)
                {
                    ObjectsOnTile.Remove(oldEffect.gameObject);
                    oldEffect.EndEffect();
                }
            }
        }

        ObjectsOnTile.Add(effect.gameObject);
        HasEffect = true;
        effect.StartEffect();
        return(true);
    }
Ejemplo n.º 14
0
 public MapGenExit()
 {
     Tile = new EffectTile();
 }
Ejemplo n.º 15
0
 void IPlaceableGenContext <EffectTile> .PlaceItem(Loc loc, EffectTile item)
 {
     Map.Tiles[loc.X][loc.Y].Effect = new EffectTile(item);
 }
Ejemplo n.º 16
0
        public override void Apply(T map)
        {
            Grid.LocTest checkBlock = (Loc testLoc) =>
            {
                return(!map.Tiles[testLoc.X][testLoc.Y].TileEquivalent(map.RoomTerrain) || map.HasTileEffect(testLoc));
            };

            //choose a room to put the chest in
            //do not choose a room that would cause disconnection of the floor
            List <int> possibleRooms = new List <int>();

            for (int ii = 0; ii < map.RoomPlan.RoomCount; ii++)
            {
                FloorRoomPlan testPlan = map.RoomPlan.GetRoomPlan(ii);
                //if (map.RoomPlan.IsChokePoint(new RoomHallIndex(ii, false)))
                //    continue;
                if (!BaseRoomFilter.PassesAllFilters(testPlan, this.Filters))
                {
                    continue;
                }

                //also do not choose a room that contains the end stairs
                IViewPlaceableGenContext <MapGenExit> exitMap = (IViewPlaceableGenContext <MapGenExit>)map;
                if (Collision.InBounds(testPlan.RoomGen.Draw, exitMap.GetLoc(0)))
                {
                    continue;
                }

                possibleRooms.Add(ii);
            }

            if (possibleRooms.Count == 0)
            {
                return;
            }

            List <Loc> freeTiles = new List <Loc>();
            IRoomGen   room      = null;

            while (possibleRooms.Count > 0)
            {
                int chosenRoom = map.Rand.Next(possibleRooms.Count);
                room = map.RoomPlan.GetRoom(possibleRooms[chosenRoom]);

                //get all places that the chest is eligible
                freeTiles = Grid.FindTilesInBox(room.Draw.Start, room.Draw.Size, (Loc testLoc) =>
                {
                    if (map.Tiles[testLoc.X][testLoc.Y].TileEquivalent(map.RoomTerrain) && !map.HasTileEffect(testLoc) &&
                        map.Tiles[testLoc.X][testLoc.Y + 1].TileEquivalent(map.RoomTerrain) && !map.HasTileEffect(new Loc(testLoc.X, testLoc.Y + 1)) &&
                        !map.PostProcGrid[testLoc.X][testLoc.Y].Status[(int)PostProcType.Panel] &&
                        !map.PostProcGrid[testLoc.X][testLoc.Y].Status[(int)PostProcType.Item])
                    {
                        if (Grid.GetForkDirs(testLoc, checkBlock, checkBlock).Count < 2)
                        {
                            foreach (MapItem item in map.Items)
                            {
                                if (item.TileLoc == testLoc)
                                {
                                    return(false);
                                }
                            }
                            foreach (Team team in map.AllyTeams)
                            {
                                foreach (Character testChar in team.EnumerateChars())
                                {
                                    if (testChar.CharLoc == testLoc)
                                    {
                                        return(false);
                                    }
                                }
                            }
                            foreach (Team team in map.MapTeams)
                            {
                                foreach (Character testChar in team.EnumerateChars())
                                {
                                    if (testChar.CharLoc == testLoc)
                                    {
                                        return(false);
                                    }
                                }
                            }
                            return(true);
                        }
                    }
                    return(false);
                });
                if (freeTiles.Count > 0)
                {
                    break;
                }
                possibleRooms.RemoveAt(chosenRoom);
            }

            //can't find any free tile in any room, return
            if (freeTiles.Count == 0)
            {
                return;
            }

            if (!ItemThemes.CanPick)
            {
                return;
            }
            //choose which item theme to work with
            ItemTheme chosenItemTheme = ItemThemes.Pick(map.Rand);

            //the item spawn list in this class dictates the items available for spawning
            //it will be queried for items that match the theme selected
            List <MapItem> chosenItems = chosenItemTheme.GenerateItems(map, Items);

            if (chosenItems.Count == 0)
            {
                return;
            }

            int randIndex = map.Rand.Next(freeTiles.Count);
            Loc loc       = freeTiles[randIndex];


            EffectTile spawnedChest = new EffectTile(37, true);

            if (Ambush && MobThemes.CanPick)
            {
                spawnedChest.Danger = true;
                //the mob theme will be selected randomly
                MobTheme chosenMobTheme = MobThemes.Pick(map.Rand);

                //the mobs in this class are the ones that would be available when the game wants to spawn things outside of the floor's spawn list
                //it will be queried for monsters that match the theme provided
                List <MobSpawn> chosenMobs = chosenMobTheme.GenerateMobs(map, Mobs);


                MobSpawnState mobSpawn = new MobSpawnState();
                foreach (MobSpawn mob in chosenMobs)
                {
                    MobSpawn copyMob = mob.Copy();
                    if (map.Rand.Next(ALT_COLOR_ODDS) == 0)
                    {
                        copyMob.BaseForm.Skin = 1;
                    }
                    mobSpawn.Spawns.Add(copyMob);
                }
                spawnedChest.TileStates.Set(mobSpawn);
            }

            ItemSpawnState itemSpawn = new ItemSpawnState();

            itemSpawn.Spawns = chosenItems;
            spawnedChest.TileStates.Set(itemSpawn);

            Rect wallBounds = new Rect(room.Draw.X - 1, room.Draw.Y - 1, room.Draw.Size.X + 2, room.Draw.Size.Y + 2);

            spawnedChest.TileStates.Set(new BoundsState(wallBounds));

            ((IPlaceableGenContext <EffectTile>)map).PlaceItem(loc, spawnedChest);
            map.PostProcGrid[loc.X][loc.Y].Status[(int)PostProcType.Panel] = true;
            map.PostProcGrid[loc.X][loc.Y].Status[(int)PostProcType.Item]  = true;

            GenContextDebug.DebugProgress("Placed Chest");
        }
Ejemplo n.º 17
0
        public override void Apply(T map)
        {
            //TODO: move magic numbers out of here
            EffectTile spawnedChest = new EffectTile(44, true);

            List <Loc> freeTiles = ((IPlaceableGenContext <EffectTile>)map).GetAllFreeTiles();

            int randIndex = map.Rand.Next(freeTiles.Count);
            Loc chosenLoc = freeTiles[randIndex];

            ((IPlaceableGenContext <EffectTile>)map).PlaceItem(chosenLoc, spawnedChest);

            //also put a monster house here
            RandRange       amount     = new RandRange(7, 13);
            int             mobCount   = amount.Pick(map.Rand);
            List <MobSpawn> chosenMobs = new List <MobSpawn>();

            if (map.TeamSpawns.Count > 0)
            {
                for (int ii = 0; ii < mobCount; ii++)
                {
                    List <MobSpawn> exampleList = map.TeamSpawns.Pick(map.Rand).ChooseSpawns(map.Rand);
                    if (exampleList.Count > 0)
                    {
                        chosenMobs.AddRange(exampleList);
                    }
                    if (chosenMobs.Count >= mobCount)
                    {
                        break;
                    }
                }
            }

            if (chosenMobs.Count > 0)
            {
                Rect bounds = new Rect(chosenLoc - new Loc(4), new Loc(9));
                bounds = Rect.Intersect(bounds, new Rect(0, 0, map.Width, map.Height));

                for (int xx = bounds.X; xx < bounds.End.X; xx++)
                {
                    for (int yy = bounds.Y; yy < bounds.End.Y; yy++)
                    {
                        if ((xx == bounds.X || xx == bounds.End.X - 1) && (yy == bounds.Y || yy == bounds.End.Y - 1))
                        {
                            continue;
                        }

                        if (map.GetTile(new Loc(xx, yy)).TileEquivalent(map.WallTerrain))
                        {
                            map.SetTile(new Loc(xx, yy), map.RoomTerrain.Copy());
                        }
                    }
                }

                //cover the room in a check that holds all of the monsters, and covers the room's bounds
                CheckIntrudeBoundsEvent check = new CheckIntrudeBoundsEvent();
                check.Bounds = bounds;
                {
                    MonsterHouseMapEvent house = new MonsterHouseMapEvent();
                    house.Bounds = check.Bounds;
                    foreach (MobSpawn mob in chosenMobs)
                    {
                        house.Mobs.Add(mob.Copy());
                    }
                    check.Effects.Add(house);
                }

                int       intrudeStatus = 33;
                MapStatus status        = new MapStatus(intrudeStatus);
                status.LoadFromData();
                MapCheckState checkState = status.StatusStates.GetWithDefault <MapCheckState>();
                checkState.CheckEvents.Add(check);
                map.Map.Status.Add(intrudeStatus, status);
            }
        }
Ejemplo n.º 18
0
        protected override void PlaceBorders(T map, Dictionary <Loc, SealType> sealList)
        {
            Rect?bossRect = null;

            for (int ii = 0; ii < map.RoomPlan.RoomCount; ii++)
            {
                FloorRoomPlan plan = map.RoomPlan.GetRoomPlan(ii);
                if (!BaseRoomFilter.PassesAllFilters(plan, this.BossFilters))
                {
                    continue;
                }
                bossRect = plan.RoomGen.Draw;
                break;
            }

            //if there's no way to open the door, there cannot be a door; give the player the treasure unguarded
            if (bossRect == null)
            {
                return;
            }

            EffectTile bossEffect = null;

            for (int xx = bossRect.Value.Start.X; xx < bossRect.Value.End.X; xx++)
            {
                for (int yy = bossRect.Value.Start.Y; yy < bossRect.Value.End.Y; yy++)
                {
                    if (map.Tiles[xx][yy].Effect.ID == BossTile)
                    {
                        bossEffect = map.Tiles[xx][yy].Effect;
                        break;
                    }
                }
                if (bossEffect != null)
                {
                    break;
                }
            }

            if (bossEffect == null)
            {
                return;
            }


            List <Loc> lockList = new List <Loc>();

            foreach (Loc loc in sealList.Keys)
            {
                switch (sealList[loc])
                {
                case SealType.Blocked:
                    map.Tiles[loc.X][loc.Y] = (Tile)map.UnbreakableTerrain.Copy();
                    break;

                default:
                    lockList.Add(loc);
                    break;
                }
            }

            foreach (Loc loc in lockList)
            {
                map.Tiles[loc.X][loc.Y] = (Tile)map.UnbreakableTerrain.Copy();
                EffectTile newEffect = new EffectTile(SealedTile, true, loc);
                ((IPlaceableGenContext <EffectTile>)map).PlaceItem(loc, newEffect);
            }

            ResultEventState resultEvent = new ResultEventState();

            resultEvent.ResultEvents.Add(new OpenVaultEvent(lockList));

            bossEffect.TileStates.Set(resultEvent);
        }
Ejemplo n.º 19
0
        public override void Apply(T map)
        {
            if (Spawns.Count > 0)
            {
                List <Loc> freeTiles = new List <Loc>();
                //get all places that traps are eligible
                for (int ii = 0; ii < map.RoomPlan.RoomCount; ii++)
                {
                    IRoomGen room = map.RoomPlan.GetRoom(ii);

                    List <Loc> tiles = ((IPlaceableGenContext <EffectTile>)map).GetFreeTiles(room.Draw);

                    freeTiles.AddRange(tiles);
                }

                // add tile
                if (freeTiles.Count > 0)
                {
                    int        randIndex   = ((IGenContext)map).Rand.Next(freeTiles.Count);
                    Loc        loc         = freeTiles[randIndex];
                    EffectTile spawnedTrap = Spawns.Pick(((IGenContext)map).Rand);
                    map.PlaceItem(loc, spawnedTrap);
                    freeTiles.RemoveAt(randIndex);

                    if (GuardSpawns.Count > 0)
                    {
                        for (int ii = 0; ii < 10; ii++)
                        {
                            Team newTeam = GuardSpawns.Pick(((IGenContext)map).Rand).Spawn(map);
                            if (newTeam == null)
                            {
                                continue;
                            }
                            //spawn guards

                            Grid.LocTest checkSpawnOpen = (Loc testLoc) =>
                            {
                                return(((IGroupPlaceableGenContext <Team>)map).CanPlaceItem(testLoc));
                            };
                            Grid.LocTest checkSpawnBlock = (Loc testLoc) =>
                            {
                                return(map.TileBlocked(testLoc));
                            };
                            Grid.LocTest checkDiagSpawnBlock = (Loc testLoc) =>
                            {
                                return(map.TileBlocked(testLoc, true));
                            };

                            List <Loc> resultLocs = new List <Loc>();
                            foreach (Loc resultLoc in Grid.FindClosestConnectedTiles(new Loc(), new Loc(map.Width, map.Height),
                                                                                     checkSpawnOpen, checkSpawnBlock, checkDiagSpawnBlock, loc, newTeam.MemberGuestCount))
                            {
                                resultLocs.Add(resultLoc);
                            }

                            if (resultLocs.Count >= newTeam.MemberGuestCount)
                            {
                                Loc[] locs = new Loc[newTeam.MemberGuestCount];
                                for (int jj = 0; jj < locs.Length; jj++)
                                {
                                    locs[jj] = resultLocs[jj];
                                }
                                map.PlaceItems(newTeam, locs);
                                break;
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 20
0
 protected MapGenExit(MapGenExit other)
 {
     Loc  = other.Loc;
     Tile = (EffectTile)other.Tile.Copy();
 }
Ejemplo n.º 21
0
    public void RemoveEffect(EffectTile effect)
    {
        Vector3Int coords = GetTilemapCoordsFromWorld(PathfindingMap, effect.transform.position);

        _graph.GetNode(coords).RemoveEffect(effect);
    }
Ejemplo n.º 22
0
        public override void Apply(T map)
        {
            //choose a room to cram all the items in
            List <int> possibleRooms = new List <int>();

            for (int ii = 0; ii < map.RoomPlan.RoomCount; ii++)
            {
                FloorRoomPlan testPlan = map.RoomPlan.GetRoomPlan(ii);
                if (!BaseRoomFilter.PassesAllFilters(testPlan, this.Filters))
                {
                    continue;
                }

                //also do not choose a room that contains the start or end
                IViewPlaceableGenContext <MapGenEntrance> entranceMap = map;
                if (Collision.InBounds(testPlan.RoomGen.Draw, entranceMap.GetLoc(0)))
                {
                    continue;
                }
                IViewPlaceableGenContext <MapGenExit> exitMap = map;
                if (Collision.InBounds(testPlan.RoomGen.Draw, exitMap.GetLoc(0)))
                {
                    continue;
                }

                possibleRooms.Add(ii);
            }

            FloorRoomPlan roomPlan  = null;
            Rect          limitRect = Rect.Empty;

            while (possibleRooms.Count > 0)
            {
                int chosenRoom = map.Rand.Next(possibleRooms.Count);
                roomPlan = map.RoomPlan.GetRoomPlan(possibleRooms[chosenRoom]);

                bool[][] eligibilityGrid = new bool[roomPlan.RoomGen.Draw.Width][];
                for (int xx = 0; xx < roomPlan.RoomGen.Draw.Width; xx++)
                {
                    eligibilityGrid[xx] = new bool[roomPlan.RoomGen.Draw.Height];
                    for (int yy = 0; yy < roomPlan.RoomGen.Draw.Height; yy++)
                    {
                        bool eligible = true;
                        Loc  testLoc  = roomPlan.RoomGen.Draw.Start + new Loc(xx, yy);
                        if (map.Tiles[testLoc.X][testLoc.Y].TileEquivalent(map.RoomTerrain) && !map.HasTileEffect(testLoc) &&
                            map.Tiles[testLoc.X][testLoc.Y + 1].TileEquivalent(map.RoomTerrain) && !map.HasTileEffect(new Loc(testLoc.X, testLoc.Y + 1)) &&
                            !map.PostProcGrid[testLoc.X][testLoc.Y].Status[(int)PostProcType.Panel] &&
                            !map.PostProcGrid[testLoc.X][testLoc.Y].Status[(int)PostProcType.Item])
                        {
                            foreach (MapItem item in map.Items)
                            {
                                if (item.TileLoc == testLoc)
                                {
                                    eligible = false;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            eligible = false;
                        }
                        eligibilityGrid[xx][yy] = eligible;
                    }
                }

                List <Rect> candRects = Detection.DetectNLargestRects(eligibilityGrid, 1);
                if (candRects.Count > 0)
                {
                    limitRect = new Rect(roomPlan.RoomGen.Draw.Start + candRects[0].Start, candRects[0].Size);
                    if (limitRect.Size.X >= MIN_SHOP_SIZE && limitRect.Size.Y >= MIN_SHOP_SIZE)
                    {
                        break;
                    }
                }
                possibleRooms.RemoveAt(chosenRoom);
            }

            if (limitRect.Size.X < MIN_SHOP_SIZE || limitRect.Size.Y < MIN_SHOP_SIZE)
            {
                return;
            }

            //randomly roll an actual rectangle within the saferect bounds: between 3x3 and the limit
            Loc  rectSize  = new Loc(map.Rand.Next(MIN_SHOP_SIZE, limitRect.Width + 1), map.Rand.Next(MIN_SHOP_SIZE, limitRect.Height + 1));
            Loc  rectStart = new Loc(limitRect.X + map.Rand.Next(limitRect.Width - rectSize.X + 1), limitRect.Y + map.Rand.Next(limitRect.Height - rectSize.Y + 1));
            Rect safeRect  = new Rect(rectStart, rectSize);

            // place the mat of the shop
            List <Loc> itemTiles = new List <Loc>();

            for (int xx = safeRect.X; xx < safeRect.End.X; xx++)
            {
                for (int yy = safeRect.Y; yy < safeRect.End.Y; yy++)
                {
                    Loc matLoc = new Loc(xx, yy);
                    itemTiles.Add(matLoc);
                    EffectTile effect = new EffectTile(45, true, matLoc);
                    ((IPlaceableGenContext <EffectTile>)map).PlaceItem(matLoc, effect);
                    map.PostProcGrid[matLoc.X][matLoc.Y].Status[(int)PostProcType.Panel] = true;
                    map.PostProcGrid[matLoc.X][matLoc.Y].Status[(int)PostProcType.Item]  = true;
                }
            }

            // place the map status for checking shop items and spawning security guards
            {
                MapStatus status = new MapStatus(SecurityStatus);
                status.LoadFromData();
                ShopSecurityState securityState = new ShopSecurityState();
                for (int ii = 0; ii < Mobs.Count; ii++)
                {
                    securityState.Security.Add(Mobs.GetSpawn(ii).Copy(), Mobs.GetSpawnRate(ii));
                }
                status.StatusStates.Set(securityState);
                status.StatusStates.Set(new MapIndexState(Personality));
                map.Map.Status.Add(SecurityStatus, status);
            }

            // place the mob running the shop
            {
                ExplorerTeam newTeam = new ExplorerTeam();
                newTeam.SetRank(1);
                Character shopkeeper = StartMob.Spawn(newTeam, map);
                Loc       randLoc    = itemTiles[map.Rand.Next(itemTiles.Count)];
                ((IGroupPlaceableGenContext <TeamSpawn>)map).PlaceItems(new TeamSpawn(newTeam, true), new Loc[] { randLoc });
            }

            //choose which item theme to work with
            ItemTheme chosenItemTheme = ItemThemes.Pick(map.Rand);

            //the item spawn list in this class dictates the items available for spawning
            //it will be queried for items that match the theme selected
            List <MapItem> chosenItems = chosenItemTheme.GenerateItems(map, Items);

            //place the items
            for (int ii = 0; ii < chosenItems.Count; ii++)
            {
                if (itemTiles.Count > 0)
                {
                    MapItem item      = new MapItem(chosenItems[ii]);
                    int     randIndex = map.Rand.Next(itemTiles.Count);
                    ((IPlaceableGenContext <MapItem>)map).PlaceItem(itemTiles[randIndex], item);
                    itemTiles.RemoveAt(randIndex);
                }
            }

            //prevent the room from being chosen for anything else
            roomPlan.Components.Set(new NoEventRoom());
        }
Ejemplo n.º 23
0
 public MapGenExit(EffectTile tile)
 {
     Tile = tile;
 }
Ejemplo n.º 24
0
 public MapGenExit(Loc loc, EffectTile tile)
 {
     Loc  = loc;
     Tile = tile;
 }
Ejemplo n.º 25
0
        protected override void PostDraw(SpriteBatch spriteBatch)
        {
            Matrix matrix = Matrix.CreateScale(new Vector3(drawScale, drawScale, 1));

            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null, null, matrix);

            if (AutoTileInProgress != null)
            {
                for (int jj = viewTileRect.Y; jj < viewTileRect.End.Y; jj++)
                {
                    for (int ii = viewTileRect.X; ii < viewTileRect.End.X; ii++)
                    {
                        Loc testLoc = new Loc(ii, jj);
                        if (Collision.InBounds(ZoneManager.Instance.CurrentMap.Width, ZoneManager.Instance.CurrentMap.Height, testLoc) &&
                            AutoTileInProgress.IncludesLoc(testLoc))
                        {
                            AutoTile brush = AutoTileInProgress.GetBrush(testLoc);
                            if (brush.IsEmpty())
                            {
                                GraphicsManager.Pixel.Draw(spriteBatch, new Rectangle(ii * GraphicsManager.TileSize - ViewRect.X, jj * GraphicsManager.TileSize - ViewRect.Y, GraphicsManager.TileSize, GraphicsManager.TileSize), null, Color.Black);
                            }
                            else
                            {
                                brush.Draw(spriteBatch, new Loc(ii * GraphicsManager.TileSize, jj * GraphicsManager.TileSize) - ViewRect.Start);
                            }
                        }
                    }
                }
            }

            //draw the blocks

            for (int jj = viewTileRect.Y; jj < viewTileRect.End.Y; jj++)
            {
                for (int ii = viewTileRect.X; ii < viewTileRect.End.X; ii++)
                {
                    Loc testLoc = new Loc(ii, jj);
                    if (Collision.InBounds(ZoneManager.Instance.CurrentMap.Width, ZoneManager.Instance.CurrentMap.Height, testLoc))
                    {
                        TerrainTile tile = ZoneManager.Instance.CurrentMap.Tiles[ii][jj].Data;
                        if (TerrainInProgress != null && TerrainInProgress.IncludesLoc(testLoc))
                        {
                            tile = TerrainInProgress.GetBrush(testLoc);
                            if (tile.TileTex.IsEmpty())
                            {
                                GraphicsManager.Pixel.Draw(spriteBatch, new Rectangle(ii * GraphicsManager.TileSize - ViewRect.X, jj * GraphicsManager.TileSize - ViewRect.Y, GraphicsManager.TileSize, GraphicsManager.TileSize), null, Color.Black);
                            }
                            else
                            {
                                tile.TileTex.Draw(spriteBatch, new Loc(ii * GraphicsManager.TileSize, jj * GraphicsManager.TileSize) - ViewRect.Start);
                            }
                        }

                        if (ShowTerrain)
                        {
                            TerrainData data  = tile.GetData();
                            Color       color = Color.Transparent;
                            switch (data.BlockType)
                            {
                            case TerrainData.Mobility.Block:
                                color = Color.Red;
                                break;

                            case TerrainData.Mobility.Water:
                                color = Color.Blue;
                                break;

                            case TerrainData.Mobility.Lava:
                                color = Color.Orange;
                                break;

                            case TerrainData.Mobility.Abyss:
                                color = Color.Black;
                                break;

                            case TerrainData.Mobility.Impassable:
                                color = Color.White;
                                break;
                            }
                            if (color != Color.Transparent)
                            {
                                GraphicsManager.Pixel.Draw(spriteBatch, new Rectangle(ii * GraphicsManager.TileSize - ViewRect.X, jj * GraphicsManager.TileSize - ViewRect.Y, GraphicsManager.TileSize, GraphicsManager.TileSize), null, color * 0.5f);
                            }
                        }
                    }
                }
            }
            if (ShowEntrances)
            {
                foreach (LocRay8 entrance in ZoneManager.Instance.CurrentMap.EntryPoints)
                {
                    Color showColor = Color.OrangeRed;
                    GraphicsManager.Pixel.Draw(spriteBatch, new Rectangle(entrance.Loc.X * GraphicsManager.TileSize - ViewRect.X, entrance.Loc.Y * GraphicsManager.TileSize - ViewRect.Y, GraphicsManager.TileSize, GraphicsManager.TileSize), null, showColor * 0.75f);
                }
            }

            if (TileInProgress != null)
            {
                for (int jj = viewTileRect.Y; jj < viewTileRect.End.Y; jj++)
                {
                    for (int ii = viewTileRect.X; ii < viewTileRect.End.X; ii++)
                    {
                        Loc testLoc = new Loc(ii, jj);
                        if (Collision.InBounds(ZoneManager.Instance.CurrentMap.Width, ZoneManager.Instance.CurrentMap.Height, testLoc) &&
                            TileInProgress.IncludesLoc(testLoc))
                        {
                            EffectTile tile = TileInProgress.GetBrush(testLoc);
                            if (tile.ID < 0)
                            {
                                GraphicsManager.Pixel.Draw(spriteBatch, new Rectangle(ii * GraphicsManager.TileSize - ViewRect.X, jj * GraphicsManager.TileSize - ViewRect.Y, GraphicsManager.TileSize, GraphicsManager.TileSize), null, Color.Black);
                            }
                            else
                            {
                                TileData entry = DataManager.Instance.GetTile(tile.ID);
                                if (entry.Anim.AnimIndex != "")
                                {
                                    DirSheet sheet   = GraphicsManager.GetObject(entry.Anim.AnimIndex);
                                    Loc      drawLoc = new Loc(ii * GraphicsManager.TileSize, jj * GraphicsManager.TileSize) - ViewRect.Start + new Loc(GraphicsManager.TileSize / 2) - new Loc(sheet.Width, sheet.Height) / 2;
                                    sheet.DrawDir(spriteBatch, drawLoc.ToVector2(), entry.Anim.GetCurrentFrame(GraphicsManager.TotalFrameTick, sheet.TotalFrames),
                                                  entry.Anim.GetDrawDir(Dir8.None), Color.White);
                                }
                                else
                                {
                                    GraphicsManager.Pixel.Draw(spriteBatch, new Rectangle(ii * GraphicsManager.TileSize - ViewRect.X, jj * GraphicsManager.TileSize - ViewRect.Y, GraphicsManager.TileSize, GraphicsManager.TileSize), null, Color.White);
                                }
                            }
                        }
                    }
                }
            }

            spriteBatch.End();
        }
Ejemplo n.º 26
0
        public override void Apply(T map)
        {
            //first get all free tiles suitable for the switch
            List <Loc> freeSwitchTiles = ((IPlaceableGenContext <EffectTile>)map).GetAllFreeTiles();

            if (freeSwitchTiles.Count == 0)
            {
                return;
            }

            Grid.LocTest checkGround = (Loc testLoc) =>
            {
                if (!Collision.InBounds(map.Width, map.Height, testLoc))
                {
                    return(false);
                }
                return(map.Tiles[testLoc.X][testLoc.Y].TileEquivalent(map.RoomTerrain) && !map.HasTileEffect(testLoc));
            };
            Grid.LocTest checkBlock = (Loc testLoc) =>
            {
                if (!Collision.InBounds(map.Width, map.Height, testLoc))
                {
                    return(false);
                }
                return(map.Tiles[testLoc.X][testLoc.Y].TileEquivalent(map.WallTerrain));
            };

            List <LocRay4> rays = Detection.DetectWalls(((IViewPlaceableGenContext <MapGenEntrance>)map).GetLoc(0), new Rect(0, 0, map.Width, map.Height), checkBlock, checkGround);

            EffectTile effect = new EffectTile(SealedTile, true);

            List <Loc>     freeTiles        = new List <Loc>();
            List <LocRay4> createdEntrances = new List <LocRay4>();

            int amount = EntranceCount.Pick(map.Rand);

            for (int ii = 0; ii < amount; ii++)
            {
                LocRay4?ray = PlaceRoom(map, rays, effect, freeTiles);

                if (ray != null)
                {
                    createdEntrances.Add(ray.Value);
                }
            }

            if (createdEntrances.Count > 0)
            {
                PlaceEntities(map, freeTiles);

                EffectTile switchTile = new EffectTile(SwitchTile, true);

                if (TimeLimit)
                {
                    switchTile.Danger = true;
                }

                TileListState state = new TileListState();
                for (int mm = 0; mm < createdEntrances.Count; mm++)
                {
                    state.Tiles.Add(new Loc(createdEntrances[mm].Loc));
                }
                switchTile.TileStates.Set(state);

                int randIndex = map.Rand.Next(freeSwitchTiles.Count);

                ((IPlaceableGenContext <EffectTile>)map).PlaceItem(freeSwitchTiles[randIndex], switchTile);
            }
        }
Ejemplo n.º 27
0
        public override void DrawOnMap(T map)
        {
            Loc caveSize = ProposeSize(((IGenContext)map).Rand);

            if (caveSize.X != Draw.Width || caveSize.Y != Draw.Height)
            {
                DrawMapDefault(map);
                return;
            }

            //place room in a space that fits
            List <Loc> freeTiles = new List <Loc>();
            Loc        caveStart = Draw.Start + new Loc(2, 1);

            for (int x = 0; x < caveSize.X - 4; x++)
            {
                for (int y = 0; y < caveSize.Y - 4; y++)
                {
                    map.SetTile(new Loc(caveStart.X + x, caveStart.Y + y), map.RoomTerrain.Copy());
                    freeTiles.Add(new Loc(caveStart.X + x, caveStart.Y + y));
                }
            }
            //place tile treasures
            List <EffectTile> tileTreasures = TileTreasures.GetSpawns(map);

            for (int ii = 0; ii < tileTreasures.Count; ii++)
            {
                int        randIndex = ((IGenContext)map).Rand.Next(freeTiles.Count);
                EffectTile tile      = new EffectTile(tileTreasures[ii]);
                map.PlaceItem(freeTiles[randIndex], tile);
                freeTiles.RemoveAt(randIndex);
            }
            //place item treasures
            List <MapItem> treasures = Treasures.GetSpawns(map);

            for (int ii = 0; ii < treasures.Count; ii++)
            {
                int     randIndex = ((IGenContext)map).Rand.Next(freeTiles.Count);
                MapItem item      = treasures[ii];
                map.PlaceItem(freeTiles[randIndex], item);
                freeTiles.RemoveAt(randIndex);
            }

            //open the passage to the treasure room
            Loc tunnel = new Loc(caveStart.X + (caveSize.X - 4) / 2, caveStart.Y + caveSize.Y - 4);

            map.SetTile(tunnel, map.RoomTerrain.Copy());

            //dig the room into the treasure room
            for (int xx = 0; xx < 3; xx++)
            {
                for (int yy = 0; yy < 2; yy++)
                {
                    map.SetTile(new Loc(tunnel.X - 1 + xx, tunnel.Y + 1 + yy), map.RoomTerrain.Copy());
                }
            }


            //place monsters and items
            MonsterTeam team    = new MonsterTeam();
            Character   newChar = GuardTypes.Pick(((IGenContext)map).Rand).Spawn(team, map);

            map.PlaceItems(new TeamSpawn(team, false), new Loc[1] {
                tunnel
            });


            //dig tunnels within this room to hook up to the incoming demands
            foreach (Dir4 dir in DirExt.VALID_DIR4)
            {
                if (dir == Dir4.Up)
                {//if approached from the top, it must be either left or right.  Dig to that side and then dig up.
                    List <IntRange> upReq = RoomSideReqs[dir];
                    bool            left  = false;
                    bool            right = false;
                    for (int ii = 0; ii < upReq.Count; ii++)
                    {
                        bool hasLeft  = upReq[ii].Contains(Draw.Start.X) && BorderToFulfill[Dir4.Up][0];
                        bool hasRight = upReq[ii].Contains(Draw.End.X - 1) && BorderToFulfill[Dir4.Up][Draw.Width - 1];
                        if (hasLeft && hasRight)
                        {
                            if (((IGenContext)map).Rand.Next(2) == 0)
                            {
                                left = true;
                            }
                            else
                            {
                                right = true;
                            }
                        }
                        else
                        {
                            left  |= hasLeft;
                            right |= hasRight;
                        }
                    }
                    if (left)
                    {
                        DigAtBorder(map, Dir4.Left, Draw.End.Y - 1);
                        DigAtBorder(map, Dir4.Up, Draw.Start.X);
                    }
                    if (right)
                    {
                        DigAtBorder(map, Dir4.Right, Draw.End.Y - 1);
                        DigAtBorder(map, Dir4.Up, Draw.End.X - 1);
                    }
                }
                else if (dir == Dir4.Down)
                {//if approached from bottom, do nothing; we already fulfill every possibility
                }
                else
                {//if approached from the sides, dig at the bottommost Y of the room, because that was the only tile allowed.
                    if (RoomSideReqs[dir].Count > 0)
                    {
                        DigAtBorder(map, dir, Draw.End.Y - 1);
                    }
                }
            }

            for (int x = 0; x < Draw.Width; x++)
            {
                for (int y = 0; y < Draw.Height - 1; y++)
                {
                    Loc checkLoc = new Loc(Draw.X + x, Draw.Y + y);
                    if (!map.GetTile(checkLoc).TileEquivalent(map.RoomTerrain))
                    {
                        map.SetTile(checkLoc, map.UnbreakableTerrain.Copy());
                    }
                }
            }


            SetRoomBorders(map);
        }
Ejemplo n.º 28
0
        protected LocRay4?PlaceRoom(T map, List <LocRay4> rays, EffectTile sealingTile, List <Loc> freeTiles)
        {
            Grid.LocTest checkBlockForPlace = (Loc testLoc) =>
            {
                if (!Collision.InBounds(map.Width, map.Height, testLoc))
                {
                    return(false);
                }
                return(!map.Tiles[testLoc.X][testLoc.Y].TileEquivalent(map.RoomTerrain) && !map.Tiles[testLoc.X][testLoc.Y].TileEquivalent(map.UnbreakableTerrain));
            };
            //try X times to dig a passage
            for (int ii = 0; ii < 500 && rays.Count > 0; ii++)
            {
                int     rayIndex = map.Rand.Next(rays.Count);
                LocRay4 ray      = rays[rayIndex];
                rays.RemoveAt(rayIndex);

                Loc   rayDirLoc = ray.Dir.GetLoc();
                Axis4 axis      = ray.Dir.ToAxis();
                Axis4 orth      = axis == Axis4.Horiz ? Axis4.Vert : Axis4.Horiz;

                int  minLength = Math.Max(1, HallLength.Min);
                Rect hallBound = new Rect(ray.Loc + DirExt.AddAngles(ray.Dir, Dir4.Left).GetLoc(), new Loc(1));
                hallBound = Rect.IncludeLoc(hallBound, ray.Loc + rayDirLoc * (minLength - 1) + DirExt.AddAngles(ray.Dir, Dir4.Right).GetLoc());

                //make sure the MIN hall can tunnel unimpeded
                if (!CanPlaceRect(map, hallBound, checkBlockForPlace))
                {
                    continue;
                }

                for (int jj = 0; jj < 100; jj++)
                {
                    //plan the room
                    RoomGen <T> plan = GenericRooms.Pick(map.Rand).Copy();
                    Loc         size = plan.ProposeSize(map.Rand);
                    plan.PrepareSize(map.Rand, size);
                    //attempt to place the bounds somewhere, anywhere, within the limitations that the room itself provides
                    List <int> candidateOpenings = new List <int>();
                    int        planLength        = plan.GetBorderLength(ray.Dir.Reverse());
                    for (int kk = 0; kk < planLength; kk++)
                    {
                        if (plan.GetFulfillableBorder(ray.Dir.Reverse(), kk))
                        {
                            candidateOpenings.Add(kk);
                        }
                    }

                    //as well as continue extending the hall until we hit a walkable.
                    int tunnelLen  = Math.Max(1, HallLength.Pick(map.Rand));
                    Loc roomLoc    = ray.Loc + rayDirLoc * tunnelLen;
                    int perpOffset = candidateOpenings[map.Rand.Next(candidateOpenings.Count)];
                    roomLoc += orth.CreateLoc(-perpOffset, 0);
                    if (rayDirLoc.GetScalar(axis) < 0)//move back the top-left of the entrance
                    {
                        roomLoc += rayDirLoc * (size.GetScalar(axis) - 1);
                    }

                    Rect roomTestBound = new Rect(roomLoc, size);
                    roomTestBound.Inflate(1, 1);
                    //make a rect for the rest of the hall
                    Rect hallExtBound = new Rect(ray.Loc + rayDirLoc * minLength + DirExt.AddAngles(ray.Dir, Dir4.Left).GetLoc(), new Loc(1));
                    hallExtBound = Rect.IncludeLoc(hallBound, ray.Loc + rayDirLoc * (tunnelLen - 1) + DirExt.AddAngles(ray.Dir, Dir4.Right).GetLoc());
                    //now that we've chosen our position, let's test it
                    if (!CanPlaceRect(map, roomTestBound, checkBlockForPlace) || !CanPlaceRect(map, hallExtBound, checkBlockForPlace)) // also test that the CHOSEN hallway can be properly sealed
                    {
                        continue;                                                                                                      //invalid location, try another place
                    }
                    else
                    {
                        plan.SetLoc(roomLoc);

                        plan.ReceiveBorderRange(new IntRange(perpOffset, perpOffset + 1) + roomLoc.GetScalar(orth), ray.Dir.Reverse());
                        //draw the room
                        plan.DrawOnMap(map);

                        //surround the room with bounds
                        for (int xx = roomTestBound.X; xx < roomTestBound.Right; xx++)
                        {
                            map.Tiles[xx][roomTestBound.Y]         = (Tile)map.UnbreakableTerrain.Copy();
                            map.Tiles[xx][roomTestBound.End.Y - 1] = (Tile)map.UnbreakableTerrain.Copy();
                        }
                        for (int yy = roomTestBound.Y + 1; yy < roomTestBound.Bottom - 1; yy++)
                        {
                            map.Tiles[roomTestBound.X][yy]         = (Tile)map.UnbreakableTerrain.Copy();
                            map.Tiles[roomTestBound.End.X - 1][yy] = (Tile)map.UnbreakableTerrain.Copy();
                        }

                        //spawn tiles, items, foes
                        List <Loc> addedTiles = ((IPlaceableGenContext <MapItem>)map).GetFreeTiles(plan.Draw);
                        freeTiles.AddRange(addedTiles);


                        //tunnel to the room
                        Loc loc = ray.Loc;
                        for (int tt = 0; tt < tunnelLen; tt++)
                        {
                            //make walkable
                            map.Tiles[loc.X][loc.Y] = (Tile)map.RoomTerrain.Copy();

                            //make left side unbreakable
                            Loc lLoc = loc + DirExt.AddAngles(ray.Dir, Dir4.Left).GetLoc();
                            map.Tiles[lLoc.X][lLoc.Y] = (Tile)map.UnbreakableTerrain.Copy();

                            //make right side unbreakable
                            Loc rLoc = loc + DirExt.AddAngles(ray.Dir, Dir4.Right).GetLoc();
                            map.Tiles[rLoc.X][rLoc.Y] = (Tile)map.UnbreakableTerrain.Copy();

                            loc += rayDirLoc;
                        }

                        //finally, seal with a locked door
                        map.Tiles[ray.Loc.X][ray.Loc.Y] = (Tile)map.UnbreakableTerrain.Copy();
                        EffectTile newEffect = new EffectTile(sealingTile, ray.Loc);
                        ((IPlaceableGenContext <EffectTile>)map).PlaceItem(ray.Loc, newEffect);

                        return(ray);
                    }
                }
            }

            //DiagManager.Instance.LogInfo("Couldn't place sealed detour!");

            return(null);
        }
Ejemplo n.º 29
0
        protected override void PlaceBorders(T map, Dictionary <Loc, SealType> sealList)
        {
            List <Loc> freeSwitchTiles = new List <Loc>();

            for (int ii = 0; ii < map.RoomPlan.RoomCount; ii++)
            {
                FloorRoomPlan plan = map.RoomPlan.GetRoomPlan(ii);
                if (!BaseRoomFilter.PassesAllFilters(plan, this.SwitchFilters))
                {
                    continue;
                }
                freeSwitchTiles.AddRange(((IPlaceableGenContext <EffectTile>)map).GetFreeTiles(plan.RoomGen.Draw));
            }
            for (int ii = 0; ii < map.RoomPlan.HallCount; ii++)
            {
                FloorHallPlan plan = map.RoomPlan.GetHallPlan(ii);
                if (!BaseRoomFilter.PassesAllFilters(plan, this.SwitchFilters))
                {
                    continue;
                }
                freeSwitchTiles.AddRange(((IPlaceableGenContext <EffectTile>)map).GetFreeTiles(plan.RoomGen.Draw));
            }

            //if there's no way to open the door, there cannot be a door; give the player the treasure unguarded
            if (freeSwitchTiles.Count == 0)
            {
                return;
            }

            List <Loc> lockList = new List <Loc>();

            foreach (Loc loc in sealList.Keys)
            {
                switch (sealList[loc])
                {
                case SealType.Blocked:
                    map.Tiles[loc.X][loc.Y] = (Tile)map.UnbreakableTerrain.Copy();
                    break;

                default:
                    lockList.Add(loc);
                    break;
                }
            }

            foreach (Loc loc in lockList)
            {
                map.Tiles[loc.X][loc.Y] = (Tile)map.UnbreakableTerrain.Copy();
                EffectTile newEffect = new EffectTile(SealedTile, true, loc);
                ((IPlaceableGenContext <EffectTile>)map).PlaceItem(loc, newEffect);
            }


            EffectTile switchTile = new EffectTile(SwitchTile, true);

            if (TimeLimit)
            {
                switchTile.Danger = true;
            }

            TileListState state = new TileListState();

            state.Tiles = lockList;
            switchTile.TileStates.Set(state);

            int randIndex = map.Rand.Next(freeSwitchTiles.Count);

            ((IPlaceableGenContext <EffectTile>)map).PlaceItem(freeSwitchTiles[randIndex], switchTile);
        }