public void WarnPlayers(string SafePieces) { if (SafePieces == "") { SafeTileDelegate += AllTiles[0].SetSafe; DangerTileDelegate += AllTiles[0].SpawnDanger; return; } string[] SafeChar = SafePieces.Split(':'); List <int> SafeIndices = new List <int>(); foreach (string val in SafeChar) { int.TryParse(val, out int intValue); SafeIndices.Add(intValue); } for (int i = 0; i < AllTiles.Count; i++) { if (SafeIndices.Contains(i)) { continue; } // if a safe index is detected, move to the next index; AllTiles[i].SetDanger(); // otherwise, alert the player that something bad will happen. SafeTileDelegate += AllTiles[i].SetSafe; DangerTileDelegate += AllTiles[i].SpawnDanger; } }
public void SpawnDanger() { if (DangerTileDelegate != null) { DangerTileDelegate.Invoke(); } DangerTileDelegate = null; }
public void SetTilesSafe() { if (SafeTileDelegate == null) { return; } // no tiles to set safe SafeTileDelegate.Invoke(); SafeTileDelegate = null; }
/// <summary> /// Run over all available tiles that are a available, and for each tile call a delegate. /// Note that the available tiles are not in a rectangular grid at all, and might even contain holes. /// </summary> /// <param name="tileDelegate">The function to call for each tile</param> public void DoForAllTiles(TileDelegate tileDelegate) { foreach (int TileX in worldTileRanges.Keys) { for (int i = 0; i < worldTileRanges[TileX].Count; i += 2) { int TileZstart = worldTileRanges[TileX][i]; int TileZstop = worldTileRanges[TileX][i + 1]; for (int TileZ = TileZstart; TileZ <= TileZstop; TileZ++) { tileDelegate(TileX, TileZ); } } } }
public List<Tile> NeighborsBetweenWithCondition(int r,int c,TileDelegate condition) { //list of tiles next to this one that are between you and it del Clamp = x => x<-1? -1 : x>1? 1 : x; //clamps to a value between -1 and 1 int dy = r - row; int dx = c - col; List<Tile> result = new List<Tile>(); if(dy == 0 && dx == 0){ return result; //return the empty set } int newrow = row+Clamp(dy); int newcol = col+Clamp(dx); if(condition(M.tile[newrow,newcol])){ result.Add(M.tile[newrow,newcol]); } if(Math.Abs(dy) < Math.Abs(dx) && dy != 0){ newrow -= Clamp(dy); if(condition(M.tile[newrow,newcol])){ result.Add(M.tile[newrow,newcol]); } } if(Math.Abs(dx) < Math.Abs(dy) && dx != 0){ newcol -= Clamp(dx); if(condition(M.tile[newrow,newcol])){ result.Add(M.tile[newrow,newcol]); } } return result; }
public bool HasBresenhamLineWithCondition(PhysicalObject o,bool allow_checking_neighbors,TileDelegate condition) { return HasBresenhamLineWithCondition(o.row,o.col,allow_checking_neighbors,condition); }
public bool HasBresenhamLineWithCondition(int r,int c,bool allow_checking_neighbors,TileDelegate condition) { if(allow_checking_neighbors){ if(HasBresenhamLineWithCondition(r,c,false,condition)){ return true; } if(!condition(M.tile[r,c])){ foreach(Tile t in M.tile[r,c].NeighborsBetweenWithCondition(row,col,condition)){ if(HasBresenhamLineWithCondition(t.row,t.col,false,condition)){ return true; } } } return false; } int y1 = row; int x1 = col; int y2 = r; int x2 = c; int dx = Math.Abs(x2-x1); int dy = Math.Abs(y2-y1); int er = 0; bool a_blocked = false; bool b_blocked = false; if(dy == 0){ if(x1<x2){ ++x1; //incrementing once before checking opacity lets you see out of solid tiles for(;x1<x2;++x1){ //right if(!condition(M.tile[y1,x1])){ return false; } } } else{ --x1; for(;x1>x2;--x1){ //left if(!condition(M.tile[y1,x1])){ return false; } } } return true; } if(dx == 0){ if(y1>y2){ --y1; for(;y1>y2;--y1){ //up if(!condition(M.tile[y1,x1])){ return false; } } } else{ ++y1; for(;y1<y2;++y1){ //down if(!condition(M.tile[y1,x1])){ return false; } } } return true; } if(y1+x1==y2+x2){ //slope is -1 if(x1<x2){ ++x1; --y1; for(;x1<x2;++x1){ //up-right if(!condition(M.tile[y1,x1])){ return false; } --y1; } } else{ --x1; ++y1; for(;x1>x2;--x1){ //down-left if(!condition(M.tile[y1,x1])){ return false; } ++y1; } } return true; } if(y1-x1==y2-x2){ //slope is 1 if(x1<x2){ ++x1; ++y1; for(;x1<x2;++x1){ //down-right if(!condition(M.tile[y1,x1])){ return false; } ++y1; } } else{ --x1; --y1; for(;x1>x2;--x1){ //up-left if(!condition(M.tile[y1,x1])){ return false; } --y1; } } return true; } if(y1<y2){ //down if(x1<x2){ //right if(dx>dy){ //slope less than 1 ++x1; er += dy; if(er<<1 > dx){ ++y1; er -= dx; } for(;x1<x2;++x1){ if(!condition(M.tile[y1,x1])){ if(er<<1 != dx || b_blocked){ return false; } a_blocked = true; } if(er<<1 == dx){ ++y1; if(!condition(M.tile[y1,x1])){ if(er<<1 != dx || a_blocked){ return false; } b_blocked = true; } er -= dx; } er += dy; if(er<<1 > dx){ ++y1; er -= dx; } } return true; } else{ //slope greater than 1 ++y1; er += dx; if(er<<1 > dy){ ++x1; er -= dy; } for(;y1<y2;++y1){ if(!condition(M.tile[y1,x1])){ if(er<<1 != dy || b_blocked){ return false; } a_blocked = true; } if(er<<1 == dy){ ++x1; if(!condition(M.tile[y1,x1])){ if(er<<1 != dy || a_blocked){ return false; } b_blocked = true; } er -= dy; } er += dx; if(er<<1 > dy){ ++x1; er -= dy; } } return true; } } else{ //left if(dx>dy){ //slope less than 1 --x1; er += dy; if(er<<1 > dx){ ++y1; er -= dx; } for(;x1>x2;--x1){ if(!condition(M.tile[y1,x1])){ if(er<<1 != dx || b_blocked){ return false; } a_blocked = true; } if(er<<1 == dx){ ++y1; if(!condition(M.tile[y1,x1])){ if(er<<1 != dx || a_blocked){ return false; } b_blocked = true; } er -= dx; } er += dy; if(er<<1 > dx){ ++y1; er -= dx; } } return true; } else{ //slope greater than 1 ++y1; er += dx; if(er<<1 > dy){ --x1; er -= dy; } for(;y1<y2;++y1){ if(!condition(M.tile[y1,x1])){ if(er<<1 != dy || b_blocked){ return false; } a_blocked = true; } if(er<<1 == dy){ --x1; if(!condition(M.tile[y1,x1])){ if(er<<1 != dy || a_blocked){ return false; } b_blocked = true; } er -= dy; } er += dx; if(er<<1 > dy){ --x1; er -= dy; } } return true; } } } else{ //up if(x1<x2){ //right if(dx>dy){ //slope less than 1 ++x1; er += dy; if(er<<1 > dx){ --y1; er -= dx; } for(;x1<x2;++x1){ if(!condition(M.tile[y1,x1])){ if(er<<1 != dx || b_blocked){ return false; } a_blocked = true; } if(er<<1 == dx){ --y1; if(!condition(M.tile[y1,x1])){ if(er<<1 != dx || a_blocked){ return false; } b_blocked = true; } er -= dx; } er += dy; if(er<<1 > dx){ --y1; er -= dx; } } return true; } else{ //slope greater than 1 --y1; er += dx; if(er<<1 > dy){ ++x1; er -= dy; } for(;y1>y2;--y1){ if(!condition(M.tile[y1,x1])){ if(er<<1 != dy || b_blocked){ return false; } a_blocked = true; } if(er<<1 == dy){ ++x1; if(!condition(M.tile[y1,x1])){ if(er<<1 != dy || a_blocked){ return false; } b_blocked = true; } er -= dy; } er += dx; if(er<<1 > dy){ ++x1; er -= dy; } } return true; } } else{ //left if(dx>dy){ //slope less than 1 --x1; er += dy; if(er<<1 > dx){ --y1; er -= dx; } for(;x1>x2;--x1){ if(!condition(M.tile[y1,x1])){ if(er<<1 != dx || b_blocked){ return false; } a_blocked = true; } if(er<<1 == dx){ --y1; if(!condition(M.tile[y1,x1])){ if(er<<1 != dx || a_blocked){ return false; } b_blocked = true; } er -= dx; } er += dy; if(er<<1 > dx){ --y1; er -= dx; } } return true; } else{ //slope greater than 1 --y1; er += dx; if(er<<1 > dy){ --x1; er -= dy; } for(;y1>y2;--y1){ if(!condition(M.tile[y1,x1])){ if(er<<1 != dy || b_blocked){ return false; } a_blocked = true; } if(er<<1 == dy){ --x1; if(!condition(M.tile[y1,x1])){ if(er<<1 != dy || a_blocked){ return false; } b_blocked = true; } er -= dy; } er += dx; if(er<<1 > dy){ --x1; er -= dy; } } return true; } } } }
public static void Targeting_ShowLine(Tile tc,int radius,colorchar[,] mem,List<Tile> line,List<Tile> oldline,ref bool blocked,TileDelegate is_blocking) { foreach(Tile t in line){ if(t.row != player.row || t.col != player.col || tc.actor() != player){ colorchar cch = mem[t.row,t.col]; if(t.row == tc.row && t.col == tc.col){ if(!blocked){ cch.bgcolor = Color.Green; if(Global.LINUX && !Screen.GLMode){ //no bright bg in terminals cch.bgcolor = Color.DarkGreen; } if(cch.color == cch.bgcolor){ cch.color = Color.Black; } Screen.WriteMapChar(t.row,t.col,cch); } else{ cch.bgcolor = Color.Red; if(Global.LINUX && !Screen.GLMode){ cch.bgcolor = Color.DarkRed; } if(cch.color == cch.bgcolor){ cch.color = Color.Black; } Screen.WriteMapChar(t.row,t.col,cch); } } else{ if(!blocked){ cch.bgcolor = Color.DarkGreen; if(cch.color == cch.bgcolor){ cch.color = Color.Black; } Screen.WriteMapChar(t.row,t.col,cch); } else{ cch.bgcolor = Color.DarkRed; if(cch.color == cch.bgcolor){ cch.color = Color.Black; } Screen.WriteMapChar(t.row,t.col,cch); } } if(is_blocking(t)){ blocked = true; } } oldline.Remove(t); } if(radius > 0){ foreach(Tile t in tc.TilesWithinDistance(radius,true)){ if(!line.Contains(t)){ colorchar cch = mem[t.row,t.col]; if(blocked){ cch.bgcolor = Color.DarkRed; } else{ cch.bgcolor = Color.DarkGreen; } if(cch.color == cch.bgcolor){ cch.color = Color.Black; } Screen.WriteMapChar(t.row,t.col,cch); oldline.Remove(t); } } } }
void LoopY(int y, TileDelegate tileMethod) { Loop(tileMethod, new Rect(0,y,tileMatrix.x, 1)); }
void LoopX(int x, TileDelegate tileMethod) { Loop(tileMethod, new Rect(x,0,1, tileMatrix.y)); }
void Loop(TileDelegate tileMethod) { Loop(tileMethod, new Rect(0,0,tileMatrix.x, tileMatrix.y)); }
void Loop(TileDelegate tileMethod, Rect r) { for (int x=(int)r.xMin; x<(int)r.xMax; x++) for (int y=(int)r.yMin; y<(int)r.yMax; y++) tileMethod(new IVector2(x,y)); }