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); }
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; } }
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(); } }
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); }
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]++; } } }
public MapTileSet TileList() { if (cachedTileList == null) { cachedTileList = new MapTileSet(); foreach (MapTile t in tiles) { cachedTileList.Add(t); } } return(cachedTileList); }
// 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); }
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)); }
/// 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); }
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; } }
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)); }
} // 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]--; } } } } }
/// 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(); }
public void InitClearTilesCache() => clearCache = TileList().Where(t => t.clear).ToMapTileSet();
public void DoneWithClearTileCache() => clearCache = null;
/// 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(); }
public static MapTileSet FilterOutClear(MapTileSet ts) { return(ts.Where(t => !t.clear).ToMapTileSet()); }
// 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); }
public static MapTileSet Tunnelable(MapTileSet ts) { return(ts.Where(t => t.noTunnel == false).ToMapTileSet()); }