Example #1
0
        public MapTileSet GetClosed3Sides(MapTileSet input)
        {
            var r = new MapTileSet();

            foreach (MapTile t in input)
            {
                int sum = 0;
                if (t.OneNorth() == null || t.OneNorth().clear == false)
                {
                    sum++;
                }
                if (t.OneSouth() == null || t.OneSouth().clear == false)
                {
                    sum++;
                }
                if (t.OneEast() == null || t.OneEast().clear == false)
                {
                    sum++;
                }
                if (t.OneWest() == null || t.OneWest().clear == false)
                {
                    sum++;
                }
                if (sum >= 3)
                {
                    r.Add(t);
                }
            }
            return(r);
        }
Example #2
0
        private static void Glowinator(Color glowCol, MapTileSet done, MapTile from, double amt)
        {
            MapTileSet surround = from.GetPossibleMoves(Dir.AllAround);

            while (amt > 0.1)
            {
                MapTileSet newSurround = new MapTileSet();
                foreach (MapTile t in surround)
                {
                    if (t.clear && !done.Contains(t))
                    {
                        t.backCol = GlowColOffset(t.backCol, glowCol, amt);
                        done.Add(t);

                        MapTileSet more = t.GetPossibleMoves(Dir.AllAround);
                        foreach (MapTile m in more)
                        {
                            newSurround.Add(m);
                        }
                    }
                }
                surround = newSurround;
                amt     -= 0.1;
            }
        }
Example #3
0
        internal void FilterNavHazards(MapTileSet maybeTiles)
        {
            // filter tiles containing wall
            maybeTiles = maybeTiles.Where(t => t.clear).ToMapTileSet();

            // don't move directly onto player
            maybeTiles = maybeTiles.Where(t => t.loc != Refs.p.loc).ToMapTileSet();

            // or right next to the player!
            Loc     playerLoc  = Refs.p.loc;
            MapTile playerTile = Refs.m.TileByLoc(playerLoc);

            var grabRange = playerTile.GetPossibleMoves(Dir.Cardinals);

            foreach (MapTile g in grabRange)
            {
                maybeTiles = maybeTiles.Where(t => t.loc != g.loc).ToMapTileSet();
            }

            // don't move directly onto another cubi
            foreach (Cubi c in Refs.h.roster)
            {
                maybeTiles = maybeTiles.Where(t => t.loc != c.loc).ToMapTileSet();
            }

            // and don't move directly onto a pent!
            foreach (Loc pent in Refs.m.pents)
            {
                maybeTiles = maybeTiles.Where(t => t.loc != pent).ToMapTileSet();
            }
        }
Example #4
0
        private static void AddGlow(Loc l, Color glowCol)
        {
            // todo what about overlapping glows?
            MapTileSet done = new MapTileSet();

            MapTile source = Refs.m.TileByLoc(l);

            source.backCol = GlowColOffset(source.backCol, glowCol, 0.5);
            done.Add(source);
            Glowinator(glowCol, done, source, 0.25);
        }
Example #5
0
        public static void SplurtNectar(MapTile here, int myIndex)
        {
            MapTileSet splurtArea = here.GetPossibleMoves(Dir.AllAround);

            foreach (MapTile t in splurtArea)
            {
                if (t.clear)
                {
                    t.nectarLevel[myIndex]++;
                }
            }
        }
Example #6
0
 public MapTileSet TileList()
 {
     if (cachedTileList == null)
     {
         cachedTileList = new MapTileSet();
         foreach (MapTile t in tiles)
         {
             cachedTileList.Add(t);
         }
     }
     return(cachedTileList);
 }
Example #7
0
        // for use with KnightMoves(), DodgeMoves(), LeapMoves()
        public MapTileSet GetPossibleMoves(HashSet <Loc> options)
        {
            var result = new MapTileSet();

            foreach (Loc p in options)
            {
                Loc newloc = Loc.AddPts(loc, p);
                if (Refs.m.ValidLoc(newloc) && Refs.m.ClearLoc(newloc))
                {
                    result.Add(Refs.m.TileByLoc(newloc));
                }
            }
            return(result);
        }
Example #8
0
        private static FlowTileSet PlayerNectarTiles(FlowMap f)
        {
            // tiles containing player nectar are targets too
            var allTiles    = Refs.m.TileList();
            var nectarTiles = new MapTileSet();

            foreach (MapTile t in allTiles)
            {
                if (t.nectarLevel[0] > 0)                 // 0 for player
                {
                    nectarTiles.Add(t);
                }
            }
            return(ConvertTiles.FlowSquaresFromTileSet(nectarTiles, f));
        }
Example #9
0
        /// map generator specific tools
        // has cached data sets that should only be used at mapgen time!

        public MapTileSet GetNextTo(MapTile t)
        {
            var x = new MapTileSet()
            {
                t.OneNorth(), t.OneSouth(), t.OneEast(), t.OneWest()
            };

            x.RemoveWhere(i => i == null);
            // leave border intact
            x.RemoveWhere(i => i.loc.X == 0);
            x.RemoveWhere(i => i.loc.Y == 0);
            x.RemoveWhere(i => i.loc.X == xLen - 1);
            x.RemoveWhere(i => i.loc.Y == yLen - 1);
            return(x);
        }
Example #10
0
        internal void MakeClearArea(Loc point1, Loc point2)
        {
            // todo note clears the area inside, not including the boundary
            MapTileSet workingList = TileList();

            workingList = workingList.Where(t =>
                                            t.loc.X > point1.X &&
                                            t.loc.X < point2.X).ToMapTileSet();

            workingList = workingList.Where(t =>
                                            t.loc.Y > point1.Y &&
                                            t.loc.Y < point2.Y).ToMapTileSet();

            foreach (MapTile t in workingList)
            {
                t.clear = true;
            }
        }
Example #11
0
        private static FlowTileSet SetUpInitialRing(int distance, FlowMap f)
        {
            // we'll try to flow to a set distance from the player by
            //    making a ring of target squares and working from there
            var allTiles = Refs.m.TileList();
            var ring     = new MapTileSet();

            foreach (MapTile t in allTiles)
            {
                double c = Loc.Distance(Refs.p.loc, t.loc);
                if (c > distance - 1 && c < distance + 1)
                {
                    ring.Add(t);
                }
            }

            return(ConvertTiles.FlowSquaresFromTileSet(ring, f));
        }
Example #12
0
        }         // end healwalls

        internal void SpreadNectar()
        {
            // todo : see final nectar spreading goals txt

            foreach (MapTile t in tiles)
            {
                if (t.clear && (t.TotalNectar() > 8 || t.StackedNectar()))
                {
                    //Console.WriteLine("Nectar heavy tile (drips>8) detected, spreading...");
                    MapTileSet spreadArea = t.GetPossibleMoves(Dir.AllAround);
                    spreadArea = spreadArea.Where(x => x.clear).ToMapTileSet();
                    spreadArea = spreadArea.Where(x => !x.StackedNectar()).ToMapTileSet();
                    spreadArea = spreadArea.Where(x => x.TotalNectar() <= t.TotalNectar()).ToMapTileSet();

                    int lightestLevel = -1;
                    int lightestAmt   = 99;
                    for (int nLoop = 0; nLoop < t.nectarLevel.Length; nLoop++)
                    {
                        if ((t.nectarLevel[nLoop] > 0) && (t.nectarLevel[nLoop] < lightestAmt))
                        {
                            lightestAmt   = t.nectarLevel[nLoop];
                            lightestLevel = nLoop;
                        }
                    }

                    // todo : note this will bias spread direction but okay for now
                    foreach (MapTile spreadTo in spreadArea)
                    {
                        if ((spreadTo.nectarLevel[lightestLevel] < t.nectarLevel[lightestLevel]) &&
                            (t.nectarLevel[lightestLevel] > 0))
                        {
                            spreadTo.nectarLevel[lightestLevel]++;
                            t.nectarLevel[lightestLevel]--;
                        }
                    }
                }
            }
        }
Example #13
0
        /// player-throwing-pillow trajectory logic

        private void ThrowPillowMain(Loc vector)
        {
            Refs.mf.Announce("You throw a pillow!", myAlign, myColor);

            // can't throw without pillow!
            if (heldPillows <= 0)
            {
                return;
            }
            else
            {
                heldPillows--; UpdateInventory();
            }

            // determine release point of throw
            // todo check for hit on very first tile -- where to put pillow?
            Loc     startloc    = Loc.AddPts(this.loc, vector);
            MapTile activeTile  = Refs.m.TileByLoc(startloc);
            string  pillowGlyph = "O";

            // if the next tile now is a lover, extra spank stun!
            // todo consolidate long and short throws
            string moveClear = CheckClearForThrown(vector, activeTile);

            if (moveClear == "cubi")
            {
                MapTile victimTile = Refs.m.TileByLoc(Loc.AddPts(activeTile.loc, vector));
                Cubi    victim     = Refs.m.CubiAt(victimTile.loc);

                Refs.mf.Announce("POINT BLANK PILLOW SPANK!", myAlign, myColor);
                victim.Spanked += 5;
                Refs.mf.Announce("oww! *moan*", victim.myAlign, victim.myColor);
            }

            while (moveClear == "clear")
            {
                // blip activeTile with pillow symbol
                AnimatePillow(activeTile, pillowGlyph);

                // is the next tile clear?
                moveClear = CheckClearForThrown(vector, activeTile);

                // nope, it has a cubi in.
                if (moveClear == "cubi")
                {
                    MapTile victimTile = Refs.m.TileByLoc(Loc.AddPts(activeTile.loc, vector));
                    Cubi    victim     = Refs.m.CubiAt(victimTile.loc);

                    MapTileSet escapes = new MapTileSet();

                    if (IsVertical(vector))
                    {
                        escapes = victimTile.GetPossibleMoves(Dir.DodgeVertical);
                    }
                    else
                    {
                        escapes = victimTile.GetPossibleMoves(Dir.DodgeHorizontal);
                    }

                    if (escapes.Count > 0)
                    {
                        victim.loc = MainMap.RandomFromList(escapes).loc;
                        Refs.mf.Announce("Nyahhh missed me!", victim.myAlign, victim.myColor);
                        moveClear = "clear";
                    }
                    else
                    {
                        victim.Spanked += 5;
                        Refs.mf.Announce("Owwwww!", victim.myAlign, victim.myColor);
                    }
                }

                // just a wall. stop here.
                if (moveClear == "wall")
                {
                    Refs.mf.Announce("You didn't hit anything interesting.", myAlign, myColor);
                }

                // it's clear, so move activeTile up and iterate
                if (moveClear == "clear")
                {
                    activeTile = Refs.m.TileByLoc(Loc.AddPts(vector, activeTile.loc));
                }
            }
            // leave pillow on ground to form new obstruction
            activeTile.clear = false;
            Refs.m.HealWalls();

            Refs.mf.UpdateMap();
        }
Example #14
0
 public void InitClearTilesCache() => clearCache = TileList().Where(t => t.clear).ToMapTileSet();
Example #15
0
 public void DoneWithClearTileCache() => clearCache = null;
Example #16
0
        /// player-throwing-a-cubi trajectory logic

        private void ThrowCubiMain(Loc vector)
        {
            // todo lots of duplication here
            Player p          = Refs.p;
            Cubi   cubiThrown = Harem.GetId(p.heldCubiId);

            Refs.mf.Announce("You throw " + cubiThrown.name + " through the air!", myAlign, myColor);
            Refs.mf.Announce("*flap* *flap* *flap*", cubiThrown.myAlign, cubiThrown.myColor);
            cubiThrown.beingCarried = false;
            p.heldCubiId            = 0;

            // determine release point of throw
            // todo check for hit on very first tile
            Loc     startloc   = Loc.AddPts(loc, vector);
            MapTile activeTile = Refs.m.TileByLoc(startloc);

            // if very first tile is a holding pent, they can fly right over
            Loc zero = new Loc(0, 0);

            if (CheckClearForThrown(zero, activeTile) == "pent")
            {
                // oops you threw from too close
                Refs.mf.Announce("*desperate flapping* That was close, just made it over!", cubiThrown.myAlign, cubiThrown.myColor);
            }

            // if the next tile is another cubi, throw short
            // todo consolidate long and short throws
            // todo need to prevent throwing a cubi while ones already directly next to you
            string moveClear = CheckClearForThrown(vector, activeTile);

            if (moveClear == "cubi")
            {
                MapTile victimTile = Refs.m.TileByLoc(Loc.AddPts(activeTile.loc, vector));
                Cubi    victim     = Refs.m.CubiAt(victimTile.loc);

                Refs.mf.Announce("Owf!", cubiThrown.myAlign, cubiThrown.myColor);
                victim.Spanked += 5;

                Refs.mf.Announce("Oof too!", cubiThrown.myAlign, cubiThrown.myColor);
                cubiThrown.Spanked += 5;                 // and a good time was had by both
            }
            else if (moveClear == "pent")
            {
                // we just overflew a pent so consider her flight path clear for now
                moveClear = "clear";
            }

            // todo refresh player square so she's not superimposed on player square

            while (moveClear == "clear")
            {
                // blip activeTile with cubi symbol
                cubiThrown.loc = activeTile.loc;
                AnimateMobile(activeTile, cubiThrown);

                // is the next tile clear?
                moveClear = CheckClearForThrown(vector, activeTile);

                // nope, it has a cubi in.
                if (moveClear == "cubi")
                {
                    MapTile victimTile = Refs.m.TileByLoc(Loc.AddPts(activeTile.loc, vector));
                    Cubi    victim     = Refs.m.CubiAt(victimTile.loc);

                    MapTileSet escapes = new MapTileSet();

                    if (IsVertical(vector))
                    {
                        escapes = victimTile.GetPossibleMoves(Dir.DodgeVertical);
                    }
                    else
                    {
                        escapes = victimTile.GetPossibleMoves(Dir.DodgeHorizontal);
                    }

                    if (escapes.Count > 0)
                    {
                        victim.loc = MainMap.RandomFromList(escapes).loc;
                        Refs.mf.Announce("Nyahhh missed me!", victim.myAlign, victim.myColor);
                        moveClear = "clear";
                    }
                    else
                    {
                        victim.Spanked += 5;
                        Refs.mf.Announce("Owwwww!", victim.myAlign, victim.myColor);
                    }

                    // if it had a cubi, it could have moved revealing a holding pent
                    // so let's scan again
                    moveClear = CheckClearForThrown(vector, activeTile);
                }

                if (moveClear == "pent")
                {
                    // move one more tile
                    activeTile = Refs.m.TileByLoc(Loc.AddPts(vector, activeTile.loc));

                    Refs.mf.Announce("Eep! I'm caught!", cubiThrown.myAlign, cubiThrown.myColor);
                }

                // just a wall. stop here.
                if (moveClear == "wall")
                {
                    Refs.mf.Announce("You didn't hit anything interesting.", myAlign, myColor);
                }

                // it's clear, so move activeTile up and iterate
                if (moveClear == "clear")
                {
                    activeTile = Refs.m.TileByLoc(Loc.AddPts(vector, activeTile.loc));
                }
            }

            // deposit cubi here
            cubiThrown.loc = activeTile.loc;

            Refs.mf.UpdateMap();
        }
Example #17
0
 public static MapTileSet FilterOutClear(MapTileSet ts)
 {
     return(ts.Where(t => !t.clear).ToMapTileSet());
 }
Example #18
0
        // returns number of round passed, 0 for free actions, 1 for normal moves.
        public int HandlePlayerInput(PreviewKeyDownEventArgs e)
        {
            // for convenience
            MapTile here = Refs.m.TileByLoc(loc);

            // debugging nectar report
            Console.Write("Nectar here is ");
            foreach (int i in here.nectarLevel)
            {
                Console.Write(i + ", ");
            }
            Console.Write(".");

            if (e.KeyCode == Keys.F && heldCubiId != 0)
            {
                return(BoinkHeld());
            }

            if (e.KeyCode == Keys.C && heldCubiId != 0)
            {
                return(CaneHeld());
            }

            Loc lastPos = loc;

            // visualise flows. hotkeys are just pretend this is where we really do it
            if (e.KeyCode == Keys.D0)
            {
                viewFlow = 0; return(0);
            }
            if (e.KeyCode == Keys.D1)
            {
                viewFlow = 1; return(0);
            }
            if (e.KeyCode == Keys.D2)
            {
                viewFlow = 2; return(0);
            }
            if (e.KeyCode == Keys.D3)
            {
                viewFlow = 3; return(0);
            }
            if (e.KeyCode == Keys.D4)
            {
                viewFlow = 4; return(0);
            }

            int timepass = 1;

            if (e.KeyCode == Keys.Space)
            {
                return(1);                // allow waiting at any time
            }

            if (placemode || e.Shift)
            {
                timepass = 0;                 // place / pickup is a free action for now
                switch (e.KeyCode)
                {
                case Keys.Down:
                case Keys.S: ActionSouth(); FinishMode(); break;

                case Keys.Right:
                case Keys.D: ActionEast(); FinishMode(); break;

                case Keys.Up:
                case Keys.W: ActionNorth(); FinishMode(); break;

                case Keys.Left:
                case Keys.A: ActionWest(); FinishMode(); break;

                case Keys.Escape: CancelModes(); break;

                default: break;
                }
            }
            else if (throwmode || e.Control)
            {
                timepass = 0;                 // throw is a free action for now
                switch (e.KeyCode)
                {
                case Keys.Down:
                case Keys.S: ThrowSouth(); FinishMode(); break;

                case Keys.Right:
                case Keys.D: ThrowEast(); FinishMode(); break;

                case Keys.Up:
                case Keys.W: ThrowNorth(); FinishMode(); break;

                case Keys.Left:
                case Keys.A: ThrowWest(); FinishMode(); break;

                case Keys.Escape: CancelModes(); break;

                default: break;
                }
            }
            else
            {
                timepass = 1;
                switch (e.KeyCode)
                {
                // moves cost 1 turn
                case Keys.Down:
                case Keys.S: RunSouth(); break;

                case Keys.Right:
                case Keys.D: RunEast(); break;

                case Keys.Up:
                case Keys.W: RunNorth(); break;

                case Keys.Left:
                case Keys.A: RunWest(); break;

                // mode changes are free actions
                case Keys.T: SetThrowMode(); timepass = 0; break;

                case Keys.P: SetPlaceMode(); timepass = 0; break;

                case Keys.Escape: CancelModes(); timepass = 0; break;

                default: timepass = 0; break;
                }
            }

            // save our current location for next turn
            lastMove = Loc.SubPts(loc, lastPos);

            // starting at 1 skips player nectar processing for now
            for (int nLoop = 1; nLoop < here.nectarLevel.Length; nLoop++)
            {
                if (here.nectarLevel[nLoop] > 0)
                {
                    horny += here.nectarLevel[nLoop];
                    here.nectarLevel[nLoop] = 0;
                }
            }

            if (horny > 15)             // having fun
            {
                Refs.mf.Announce("Awwww yeah! *splurt*", myAlign, myColor);
                timepass += 5;
                MainMap.SplurtNectar(here, myIndex: 0);
                horny = 0;
            }

            if (!victory)
            {
                // we're duplicating this location scanning code a lot...
                // but this will be useful if we ever move jails so I'll leave it

                // get list of capture tiles
                MapTileSet jails = new MapTileSet();
                foreach (Loc l in Refs.m.pents)
                {
                    jails.Add(Refs.m.TileByLoc(l));
                }

                // get list of cubi locations
                MapTileSet breaker = new MapTileSet();
                foreach (Cubi c in Refs.h.roster)
                {
                    breaker.Add(Refs.m.TileByLoc(c.loc));
                }

                // IntersectWith to get occupied jails
                jails.IntersectWith(breaker);

                // if jails filled = total jails, we won!
                if (jails.Count == Refs.m.pents.Count)
                {
                    victory = true;
                    Refs.mf.Announce("Gotcha all! And in only " + turnCounter + " turns!", myAlign, myColor);
                }
            }

            return(timepass);
        }
Example #19
0
 public static MapTileSet Tunnelable(MapTileSet ts)
 {
     return(ts.Where(t => t.noTunnel == false).ToMapTileSet());
 }