public static void RemoveMouseover() { if (mouselook_current_target != null) { if (mouselook_current_desc_area != Rectangle.Empty) { int h = mouselook_current_desc_area.Height; int w = mouselook_current_desc_area.Width; Screen.UpdateGLBuffer(Global.MAP_OFFSET_ROWS, Global.MAP_OFFSET_COLS + mouselook_current_desc_area.Left, Global.MAP_OFFSET_ROWS + h - 1, Global.MAP_OFFSET_COLS + mouselook_current_desc_area.Right - 1); mouselook_current_desc_area = Rectangle.Empty; } mouselook_current_target = null; Screen.CursorVisible = true; // This should be safe, so long as mouseovers only appear while waiting for the player's move. } if (mouse_path != null) { foreach (pos p in mouse_path) { int i = p.row; int j = p.col; colorchar cch = Screen.MapChar(i, j); //I tried doing this with a single call to UpdateVertexArray. It was slow. Screen.gl.UpdateOtherSingleVertex(Screen.textSurface, U.Get1DIndex(i + Global.MAP_OFFSET_ROWS, j + Global.MAP_OFFSET_COLS, Global.SCREEN_W), (int)cch.c, 0, cch.color.GetFloatValues(), cch.bgcolor.GetFloatValues()); //Game.gl.UpdateVertexArray(i+Global.MAP_OFFSET_ROWS,j+Global.MAP_OFFSET_COLS,GLGame.text_surface,0,(int)cch.c,cch.color.GetFloatValues(),cch.bgcolor.GetFloatValues()); } mouse_path = null; } }
public static void AnimateProjectile(List <Tile> list, colorchar ch, int duration) { Game.Console.CursorVisible = false; list.RemoveAt(0); foreach (Tile t in list) { AnimateMapCell(t.row, t.col, ch, duration); } Game.Console.CursorVisible = true; }
public static async void AnimateCell(int r, int c, colorchar ch, int duration) { colorchar prev = memory[r, c]; WriteChar(r, c, ch); await Task.Delay(duration); WriteChar(r, c, prev); }
public static void WriteMapString(int r, int c, colorstring cs) { if (cs.Length() > 0) { r += Global.MAP_OFFSET_ROWS; c += Global.MAP_OFFSET_COLS; int cpos = c; foreach (cstr s1 in cs.strings) { cstr s = new cstr(s1.s, s1.color, s1.bgcolor); if (cpos - Global.MAP_OFFSET_COLS + s.s.Length > Global.COLS) { s.s = s.s.Substring(0, Global.COLS - (cpos - Global.MAP_OFFSET_COLS)); } s.color = ResolveColor(s.color); s.bgcolor = ResolveColor(s.bgcolor); colorchar cch = new colorchar(' ', s.color, s.bgcolor); /* cch.color = s.color; * cch.bgcolor = s.bgcolor;*/ ConsoleColor co = GetColor(s.color); if (ForegroundColor != co) { ForegroundColor = co; } co = GetColor(s.bgcolor); if (BackgroundColor != co) { BackgroundColor = co; } int i = 0; bool changed = false; for (int ii = 0; ii < s.s.Length; ii++) { cch.c = s.s.CharAt(ii); if (!memory[r, cpos + i].Equals(cch)) { memory[r, cpos + i] = cch; changed = true; } ++i; } if (changed) { Game.Console.SetCursorPosition(cpos, r); Game.Console.Write(s.s); } cpos += s.s.Length; } /*if(cpos-Global.MAP_OFFSET_COLS < Global.COLS){ * WriteString(r,cpos,"".PadRight(Global.COLS-(cpos-Global.MAP_OFFSET_COLS))); * }*/ } }
public static colorchar[,] GetCurrentRect(int row, int col, int height, int width) { colorchar[,] result = new colorchar[height, width]; for (int i = 0; i < height; ++i) { for (int j = 0; j < width; ++j) { result[i, j] = Char(row + i, col + j); } } return(result); }
public static colorchar[,] GetCurrentMap() { colorchar[,] result = new colorchar[Global.ROWS, Global.COLS]; for (int i = 0; i < Global.ROWS; ++i) { for (int j = 0; j < Global.COLS; ++j) { result[i, j] = MapChar(i, j); } } return(result); }
public static colorchar[,] GetCurrentScreen() { colorchar[,] result = new colorchar[Global.SCREEN_H, Global.SCREEN_W]; for (int i = 0; i < Global.SCREEN_H; ++i) { for (int j = 0; j < Global.SCREEN_W; ++j) { result[i, j] = Char(i, j); } } return(result); }
public static void WriteMapString(int r, int c, cstr s) { if (Global.COLS - c > s.s.Length) { //s.s = s.s.Substring(0); //don't move down to the next line } else { s.s = s.s.Substring(0, Global.COLS - c); } if (s.s.Length > 0) { r += Global.MAP_OFFSET_ROWS; c += Global.MAP_OFFSET_COLS; s.color = ResolveColor(s.color); s.bgcolor = ResolveColor(s.bgcolor); colorchar cch = new colorchar(' ', s.color, s.bgcolor); /*cch.color = s.color; * cch.bgcolor = s.bgcolor;*/ ConsoleColor co = GetColor(s.color); if (ForegroundColor != co) { ForegroundColor = co; } co = GetColor(s.bgcolor); if (BackgroundColor != co) { BackgroundColor = co; } int i = 0; bool changed = false; for (int ii = 0; ii < s.s.Length; ii++) { cch.c = s.s.CharAt(ii); if (!memory[r, c + i].Equals(cch)) { memory[r, c + i] = cch; changed = true; } ++i; } if (changed) { Game.Console.SetCursorPosition(c, r); Game.Console.Write(s.s); } } }
public static void WriteString(int r, int c, colorstring cs) { if (cs.Length() > 0) { int pos = c; foreach (cstr s1 in cs.strings) { cstr s = new cstr(s1.s, s1.color, s1.bgcolor); if (s.s.Length + pos > Global.SCREEN_W) { s.s = s.s.Substring(0, Global.SCREEN_W - pos); } s.color = ResolveColor(s.color); s.bgcolor = ResolveColor(s.bgcolor); colorchar cch = new colorchar(' ', s.color, s.bgcolor); /*cch.color = s.color; * cch.bgcolor = s.bgcolor;*/ ConsoleColor co = GetColor(s.color); if (ForegroundColor != co) { ForegroundColor = co; } co = GetColor(s.bgcolor); if (BackgroundColor != co) { BackgroundColor = co; } int i = 0; bool changed = false; for (int ii = 0; ii < s.s.Length; ii++) { cch.c = s.s.CharAt(ii); if (!memory[r, pos + i].Equals(cch)) { memory[r, pos + i] = cch; changed = true; } ++i; } if (changed) { Game.Console.SetCursorPosition(pos, r); Game.Console.Write(s.s); } pos += s.s.Length; } } }
public static async void AnimateBoltBeam(List <Tile> list, Color color, int duration) { Game.Console.CursorVisible = false; colorchar ch = new colorchar("!", color, Color.Black); //ch.color = color; //ch.bgcolor = Color.Black; //ch.c="!"; switch (list[0].DirectionOf(list[list.Count - 1])) { case 7: case 3: ch.c = "\\"; break; case 8: case 2: ch.c = "|"; break; case 9: case 1: ch.c = "/"; break; case 4: case 6: ch.c = "-"; break; } list.RemoveAt(0); List <colorchar> memlist = new List <colorchar>(); foreach (Tile t in list) { memlist.Add(MapChar(t.row, t.col)); WriteMapChar(t.row, t.col, ch); await Task.Delay(duration); } int i = 0; foreach (Tile t in list) { WriteMapChar(t.row, t.col, memlist[i++]); } Game.Console.CursorVisible = true; }
} //changed from r+1,c static Screen() { memory = new colorchar[Global.SCREEN_H, Global.SCREEN_W]; for (int i = 0; i < Global.SCREEN_H; ++i) { for (int j = 0; j < Global.SCREEN_W; ++j) { memory[i, j] = new colorchar(" ", Color.Black, Color.Black); /* memory[i,j].c = " "; * memory[i,j].color = Color.Black; * memory[i,j].bgcolor = Color.Black;*/ } } BackgroundColor = Game.Console.BackgroundColor; ForegroundColor = Game.Console.ForegroundColor; }
public static async void AnimateExplosion(PhysicalObject obj, int radius, colorchar ch, int duration, bool single_frame) { Game.Console.CursorVisible = false; colorchar[,] prev = new colorchar[radius * 2 + 1, radius *2 + 1]; for (int i = 0; i <= radius * 2; ++i) { for (int j = 0; j <= radius * 2; ++j) { if (MapBoundsCheck(obj.row - radius + i, obj.col - radius + j)) { prev[i, j] = MapChar(obj.row - radius + i, obj.col - radius + j); } } } if (!single_frame) { for (int i = 0; i <= radius; ++i) { foreach (Tile t in obj.TilesAtDistance(i)) { WriteMapChar(t.row, t.col, ch); } await Task.Delay(duration); } } else { foreach (Tile t in obj.TilesWithinDistance(radius)) { WriteMapChar(t.row, t.col, ch); } await Task.Delay(duration); } for (int i = 0; i <= radius * 2; ++i) { for (int j = 0; j <= radius * 2; ++j) { if (MapBoundsCheck(obj.row - radius + i, obj.col - radius + j)) { WriteMapChar(obj.row - radius + i, obj.col - radius + j, prev[i, j]); } } } Game.Console.CursorVisible = true; }
public static void DrawMapBorder(colorchar ch) { for (int i = 0; i < Global.ROWS; i += Global.ROWS - 1) { for (int j = 0; j < Global.COLS; ++j) { WriteMapChar(i, j, ch); } } for (int j = 0; j < Global.COLS; j += Global.COLS - 1) { for (int i = 0; i < Global.ROWS; ++i) { WriteMapChar(i, j, ch); } } ResetColors(); }
public static void WriteStatsString(int r, int c, cstr s) { if (12 - c > s.s.Length) { //s.s = s.s.Substring(0); //don't move down to the next line - 12 is the width of the stats area } else { s.s = s.s.Substring(0, 12 - c); } if (s.s.Length > 0) { //++r; //was ++r s.color = ResolveColor(s.color); s.bgcolor = ResolveColor(s.bgcolor); colorchar cch = new colorchar(' ', s.color, s.bgcolor); /*cch.color = s.color; * cch.bgcolor = s.bgcolor;*/ ConsoleColor co = GetColor(s.color); if (ForegroundColor != co) { ForegroundColor = co; } co = GetColor(s.bgcolor); if (BackgroundColor != co) { BackgroundColor = co; } int i = 0; for (int ii = 0; ii < s.s.Length; ii++) { cch.c = s.s.CharAt(ii); if (!memory[r, c + i].Equals(cch)) { memory[r, c + i] = cch; } ++i; } Game.Console.SetCursorPosition(c, r); Game.Console.Write(s.s); } }
public static async void AnimateBeam(List <Tile> list, colorchar ch, int duration) { Game.Console.CursorVisible = false; list.RemoveAt(0); List <colorchar> memlist = new List <colorchar>(); foreach (Tile t in list) { memlist.Add(MapChar(t.row, t.col)); WriteMapChar(t.row, t.col, ch); await Task.Delay(duration); } int i = 0; foreach (Tile t in list) { WriteMapChar(t.row, t.col, memlist[i++]); } Game.Console.CursorVisible = true; }
public static void RemoveHighlight() { if (Highlighted != null) { colorchar[,] highlight = new colorchar[Highlighted.height, Highlighted.width]; int hh = Highlighted.height; int hw = Highlighted.width; int hr = Highlighted.row; int hc = Highlighted.col; for (int i = 0; i < hh; ++i) { for (int j = 0; j < hw; ++j) { highlight[i, j] = Screen.Char(i + hr, j + hc); } } Screen.UpdateGLBuffer(Highlighted.row, Highlighted.col, highlight); Highlighted = null; } }
public static async void AnimateMapCells(List <pos> cells, colorchar ch, int duration) { List <colorchar> prev = new List <colorchar>(); int idx = 0; foreach (pos p in cells) { prev.Add(MapChar(p.row, p.col)); WriteMapChar(p.row, p.col, ch); ++idx; } await Task.Delay(duration); idx = 0; foreach (pos p in cells) { WriteMapChar(p.row, p.col, prev[idx]); ++idx; } }
public static void WriteChar(int r, int c, colorchar ch) { if (!memory[r, c].Equals(ch)) { ch.color = ResolveColor(ch.color); ch.bgcolor = ResolveColor(ch.bgcolor); memory[r, c] = ch; ConsoleColor co = GetColor(ch.color); if (co != ForegroundColor) { ForegroundColor = co; } co = GetColor(ch.bgcolor); if (co != Game.Console.BackgroundColor || (Global.LINUX && ch.c == " " && ch.color == Color.Black)) //voodoo here. not sure why this is needed. (possible Mono bug) { BackgroundColor = co; } Game.Console.SetCursorPosition(c, r); Game.Console.Write(ch.c); } }
public static void MapDrawWithStrings(colorchar[,] array, int row, int col, int height, int width) { cstr s = new cstr("", Color.Black, Color.Black); //s.s = ""; //s.bgcolor = Color.Black; //s.color = Color.Black; int current_c = col; for (int i = row; i < row + height; ++i) { s.s = ""; current_c = col; for (int j = col; j < col + width; ++j) { colorchar ch = array[i, j]; if (Screen.ResolveColor(ch.color) != s.color) { if (s.s.Length > 0) { Screen.WriteMapString(i, current_c, s); s.s = ""; s.s += ch.c; s.color = ch.color; current_c = j; } else { s.s += ch.c; s.color = ch.color; } } else { s.s += ch.c; } } Screen.WriteMapString(i, current_c, s); } }
public static void AnimateBoltProjectile(List <Tile> list, Color color, int duration) { Game.Console.CursorVisible = false; colorchar ch = new colorchar('!', color, Color.Black); //ch.color = color; //ch.bgcolor = Color.Black; //ch.c='!'; switch (list[0].DirectionOf(list[list.Count - 1])) { case 7: case 3: ch.c = "\\"; break; case 8: case 2: ch.c = "|"; break; case 9: case 1: ch.c = "/"; break; case 4: case 6: ch.c = "-"; break; } list.RemoveAt(0); foreach (Tile t in list) { AnimateMapCell(t.row, t.col, ch, duration); } Game.Console.CursorVisible = true; }
public static void AnimateBoltProjectile(List<Tile> list,Color color,int duration){ Game.Console.CursorVisible = false; colorchar ch = new colorchar('!', color, Color.Black); //ch.color = color; //ch.bgcolor = Color.Black; //ch.c='!'; switch(list[0].DirectionOf(list[list.Count-1])){ case 7: case 3: ch.c = "\\"; break; case 8: case 2: ch.c = "|"; break; case 9: case 1: ch.c = "/"; break; case 4: case 6: ch.c = "-"; break; } list.RemoveAt(0); foreach(Tile t in list){ AnimateMapCell(t.row,t.col,ch,duration); } Game.Console.CursorVisible = true; }
public static void AnimateProjectile(List<Tile> list,colorchar ch){ AnimateProjectile(list,ch,50); }
public static void AnimateMapCells(List<pos> cells,colorchar ch){ AnimateMapCells(cells,ch,50); }
public static void AnimateMapCell(int r,int c,colorchar ch){ AnimateMapCell(r,c,ch,50); }
public static void MapDrawWithStrings(colorchar[,] array,int row,int col,int height,int width){ cstr s = new cstr("", Color.Black, Color.Black); //s.s = ""; //s.bgcolor = Color.Black; //s.color = Color.Black; int current_c = col; for(int i=row;i<row+height;++i){ s.s = ""; current_c = col; for(int j=col;j<col+width;++j){ colorchar ch = array[i,j]; if(Screen.ResolveColor(ch.color) != s.color){ if(s.s.Length > 0){ Screen.WriteMapString(i,current_c,s); s.s = ""; s.s += ch.c; s.color = ch.color; current_c = j; } else{ s.s += ch.c; s.color = ch.color; } } else{ s.s += ch.c; } } Screen.WriteMapString(i,current_c,s); } }
public static void WriteStatsChar(int r,int c,colorchar ch){ WriteChar(r,c,ch); } //was r+1,c
public static async void AnimateBeam(List<Tile> list,colorchar ch,int duration){ Game.Console.CursorVisible = false; list.RemoveAt(0); List<colorchar> memlist = new List<colorchar>(); foreach(Tile t in list){ memlist.Add(MapChar(t.row,t.col)); WriteMapChar(t.row, t.col, ch); await Task.Delay(duration); } int i = 0; foreach(Tile t in list){ WriteMapChar(t.row,t.col,memlist[i++]); } Game.Console.CursorVisible = true; }
public static void AnimateExplosion(PhysicalObject obj, int radius, colorchar ch, bool single_frame) { AnimateExplosion(obj, radius, ch, 50, single_frame); }
public bool Equals(colorchar tgt) { return(tgt != null && color == tgt.color && bgcolor == tgt.bgcolor && c == tgt.c); }
public static void AnimateProjectile(List <Tile> list, colorchar ch) { AnimateProjectile(list, ch, 50); }
public static void AnimateMapCells(List <pos> cells, colorchar ch) { AnimateMapCells(cells, ch, 50); }
public static void AnimateExplosion(PhysicalObject obj,int radius,colorchar ch,int duration){ AnimateExplosion(obj,radius,ch,duration,false); }
public static async void AnimateBoltBeam(List<Tile> list,Color color,int duration){ Game.Console.CursorVisible = false; colorchar ch = new colorchar("!", color, Color.Black); //ch.color = color; //ch.bgcolor = Color.Black; //ch.c="!"; switch(list[0].DirectionOf(list[list.Count-1])){ case 7: case 3: ch.c = "\\"; break; case 8: case 2: ch.c = "|"; break; case 9: case 1: ch.c = "/"; break; case 4: case 6: ch.c = "-"; break; } list.RemoveAt(0); List<colorchar> memlist = new List<colorchar>(); foreach(Tile t in list){ memlist.Add(MapChar(t.row,t.col)); WriteMapChar(t.row, t.col, ch); await Task.Delay(duration); } int i = 0; foreach(Tile t in list){ WriteMapChar(t.row,t.col,memlist[i++]); } Game.Console.CursorVisible = true; }
public static void AnimateExplosion(PhysicalObject obj, int radius, colorchar ch, int duration) { AnimateExplosion(obj, radius, ch, duration, false); }
public static void AnimateMapCell(int r, int c, colorchar ch, int duration) { AnimateCell(r + Global.MAP_OFFSET_ROWS, c + Global.MAP_OFFSET_COLS, ch, duration); }
public static void WriteStatsChar(int r, int c, colorchar ch) { WriteChar(r, c, ch); } //was r+1,c
public static void WriteStatsString(int r,int c,cstr s){ if(12 - c > s.s.Length){ //s.s = s.s.Substring(0); //don't move down to the next line - 12 is the width of the stats area } else{ s.s = s.s.Substring(0,12 - c); } if(s.s.Length > 0){ //++r; //was ++r s.color = ResolveColor(s.color); s.bgcolor = ResolveColor(s.bgcolor); colorchar cch = new colorchar(' ', s.color, s.bgcolor); /*cch.color = s.color; cch.bgcolor = s.bgcolor;*/ ConsoleColor co = GetColor(s.color); if(ForegroundColor != co){ ForegroundColor = co; } co = GetColor(s.bgcolor); if(BackgroundColor != co){ BackgroundColor = co; } int i = 0; for (int ii = 0; ii < s.s.Length; ii++) { cch.c = s.s.CharAt(ii); if(!memory[r,c+i].Equals(cch)){ memory[r,c+i] = cch; } ++i; } Game.Console.SetCursorPosition(c,r); Game.Console.Write(s.s); } }
public bool Equals(colorchar tgt) { return (tgt != null && color == tgt.color && bgcolor == tgt.bgcolor && c == tgt.c); }
public static async void AnimateCell(int r,int c,colorchar ch,int duration){ colorchar prev = memory[r,c]; WriteChar(r,c,ch); await Task.Delay(duration); WriteChar(r,c,prev); }
void MouseMoveHandler(object sender,MouseMoveEventArgs args) { if(MouseUI.IgnoreMouseMovement){ return; } int row; int col; if(FullScreen){ row = (int)(args.Y - ClientRectangle.Height * ((1.0f - screen_multiplier_h)*0.5f)) / cell_h; //todo: give this its own var? col = (int)(args.X - ClientRectangle.Width * ((1.0f - screen_multiplier_w)*0.5f)) / cell_w; } else{ row = args.Y / cell_h; col = args.X / cell_w; } switch(MouseUI.Mode){ case MouseMode.Targeting: { int map_row = row - Global.MAP_OFFSET_ROWS; int map_col = col - Global.MAP_OFFSET_COLS; Button b = MouseUI.GetButton(row,col); if(MouseUI.Highlighted != null && MouseUI.Highlighted != b){ MouseUI.RemoveHighlight(); } if(args.XDelta == 0 && args.YDelta == 0){ return; //don't re-highlight immediately after a click } if(b != null){ if(b != MouseUI.Highlighted){ MouseUI.Highlighted = b; colorchar[,] array = new colorchar[b.height,b.width]; for(int i=0;i<b.height;++i){ for(int j=0;j<b.width;++j){ array[i,j] = Screen.Char(i + b.row,j + b.col); array[i,j].bgcolor = Color.Blue; } } Screen.UpdateGLBuffer(b.row,b.col,array); } } else{ if(!Input.KeyPressed){ if(!MouseUI.mouselook_objects.BoundsCheck(row,col)){ //UI.MapCursor = new pos(-1,-1); Input.KeyPressed = true; ConsoleKey key = ConsoleKey.F22; Input.LastKey = new ConsoleKeyInfo(Input.GetChar(key,false),key,false,false,false); } else{ if(map_row >= 0 && map_row < Global.ROWS && map_col >= 0 && map_col < Global.COLS){ if(map_row != UI.MapCursor.row || map_col != UI.MapCursor.col){ UI.MapCursor = new pos(map_row,map_col); Input.KeyPressed = true; ConsoleKey key = ConsoleKey.F21; Input.LastKey = new ConsoleKeyInfo(Input.GetChar(key,false),key,false,false,false); } } else{ PhysicalObject o = MouseUI.mouselook_objects[row,col]; if(o != null){ if(!o.p.Equals(UI.MapCursor)){ UI.SetMapCursor(o.p,map_col < 0); Input.KeyPressed = true; ConsoleKey key = ConsoleKey.F21; Input.LastKey = new ConsoleKeyInfo(Input.GetChar(key,false),key,false,false,false); } } else{ // off the map, and not hovering over a status bar object if(map_row != UI.MapCursor.row || map_col != UI.MapCursor.col){ //UI.MapCursor = new pos(map_row,map_col); Input.KeyPressed = true; ConsoleKey key = ConsoleKey.F22; Input.LastKey = new ConsoleKeyInfo(Input.GetChar(key,false),key,false,false,false); } } } } } /*if(!Input.KeyPressed && (map_row != UI.MapCursor.row || map_col != UI.MapCursor.col) && !KeyIsDown(Key.LControl) && !KeyIsDown(Key.RControl)){ UI.MapCursor = new pos(map_row,map_col); Input.KeyPressed = true; if(map_row >= 0 && map_row < Global.ROWS && map_col >= 0 && map_col < Global.COLS){ ConsoleKey key = ConsoleKey.F21; Input.LastKey = new ConsoleKeyInfo(Input.GetChar(key,false),key,false,false,false); } else{ ConsoleKey key = ConsoleKey.F22; Input.LastKey = new ConsoleKeyInfo(Input.GetChar(key,false),key,false,false,false); } }*/ } break; } case MouseMode.Directional: { int map_row = row - Global.MAP_OFFSET_ROWS; int map_col = col - Global.MAP_OFFSET_COLS; if(map_row >= 0 && map_row < Global.ROWS && map_col >= 0 && map_col < Global.COLS){ int dir = Actor.player.DirectionOf(new pos(map_row,map_col)); pos p = Actor.player.p.PosInDir(dir); Button dir_b = MouseUI.GetButton(Global.MAP_OFFSET_ROWS + p.row,Global.MAP_OFFSET_COLS + p.col); if(MouseUI.Highlighted != null && MouseUI.Highlighted != dir_b){ MouseUI.RemoveHighlight(); } if(dir_b != null && dir_b != MouseUI.Highlighted){ MouseUI.Highlighted = dir_b; colorchar[,] array = new colorchar[1,1]; array[0,0] = Screen.Char(Global.MAP_OFFSET_ROWS + p.row,Global.MAP_OFFSET_COLS + p.col); array[0,0].bgcolor = Color.Blue; Screen.UpdateGLBuffer(dir_b.row,dir_b.col,array); } } else{ if(MouseUI.Highlighted != null){ MouseUI.RemoveHighlight(); } } break; } default: { Button b = MouseUI.GetButton(row,col); if(MouseUI.Highlighted != null && MouseUI.Highlighted != b){ MouseUI.RemoveHighlight(); } if(args.XDelta == 0 && args.YDelta == 0){ return; //don't re-highlight immediately after a click } if(b != null && b != MouseUI.Highlighted){ MouseUI.Highlighted = b; colorchar[,] array = new colorchar[b.height,b.width]; for(int i=0;i<b.height;++i){ for(int j=0;j<b.width;++j){ array[i,j] = Screen.Char(i + b.row,j + b.col); array[i,j].bgcolor = Color.Blue; } } Screen.UpdateGLBuffer(b.row,b.col,array); } else{ if(MouseUI.Mode == MouseMode.Map){ if(!MouseUI.mouselook_objects.BoundsCheck(row,col)){ UI.MapCursor = new pos(-1,-1); break; } PhysicalObject o = MouseUI.mouselook_objects[row,col]; int map_row = row - Global.MAP_OFFSET_ROWS; int map_col = col - Global.MAP_OFFSET_COLS; if(MouseUI.VisiblePath && o == null){ if(map_row >= 0 && map_row < Global.ROWS && map_col >= 0 && map_col < Global.COLS){ o = Actor.M.tile[map_row,map_col]; } } if(MouseUI.mouselook_current_target != null && (o == null || !o.p.Equals(MouseUI.mouselook_current_target.p))){ MouseUI.RemoveMouseover(); } if(o == null){ UI.MapCursor = new pos(-1,-1); } else{ if(MouseUI.mouselook_current_target == null || !o.p.Equals(MouseUI.mouselook_current_target.p)){ UI.SetMapCursor(o.p,map_col < 0); MouseUI.mouselook_current_target = o; bool description_on_right = false; int max_length = MouseUI.MaxDescriptionBoxLength; if(o.col <= 32){ description_on_right = true; } List<colorstring> desc_box = null; Actor a = o as Actor; if(a != null){ desc_box = Actor.MonsterDescriptionBox(a,true,max_length); } else{ Item i = o as Item; if(i != null){ desc_box = UI.ItemDescriptionBox(i,true,true,max_length); } } if(desc_box != null){ int h = desc_box.Count; int w = desc_box[0].Length(); MouseUI.mouselook_current_desc_area = new System.Drawing.Rectangle(description_on_right? Global.COLS - w : 0,0,w,h); int player_r = Actor.player.row; int player_c = Actor.player.col; colorchar[,] array = new colorchar[h,w]; if(description_on_right){ for(int i=0;i<h;++i){ for(int j=0;j<w;++j){ array[i,j] = desc_box[i][j]; if(i == player_r && j + Global.COLS - w == player_c){ Screen.CursorVisible = false; player_r = -1; //to prevent further attempts to set CV to false } } } Screen.UpdateGLBuffer(Global.MAP_OFFSET_ROWS,Global.MAP_OFFSET_COLS + Global.COLS - w,array); } else{ for(int i=0;i<h;++i){ for(int j=0;j<w;++j){ array[i,j] = desc_box[i][j]; if(i == player_r && j == player_c){ Screen.CursorVisible = false; player_r = -1; } } } Screen.UpdateGLBuffer(Global.MAP_OFFSET_ROWS,Global.MAP_OFFSET_COLS,array); } } if(MouseUI.VisiblePath){ if(o != Actor.player && o.p.Equals(Actor.player.p)){ MouseUI.mouse_path = new List<pos>{o.p}; } else{ MouseUI.mouse_path = Actor.player.GetPlayerTravelPath(o.p); if(MouseUI.mouse_path.Count == 0){ foreach(Tile t in Actor.M.TilesByDistance(o.row,o.col,true,true)){ if(t.passable){ MouseUI.mouse_path = Actor.player.GetPlayerTravelPath(t.p); break; } } } } pos box_start = new pos(0,0); int box_h = -1; int box_w = -1; if(desc_box != null){ box_h = desc_box.Count; box_w = desc_box[0].Length(); if(description_on_right){ box_start = new pos(0,Global.COLS - box_w); } } foreach(pos p in MouseUI.mouse_path){ if(desc_box != null && p.row < box_start.row + box_h && p.row >= box_start.row && p.col < box_start.col + box_w && p.col >= box_start.col){ continue; } colorchar cch = Screen.MapChar(p.row,p.col); cch.bgcolor = Color.DarkGreen; if(cch.color == Color.DarkGreen){ cch.color = Color.Black; } //Game.gl.UpdateVertexArray(p.row+Global.MAP_OFFSET_ROWS,p.col+Global.MAP_OFFSET_COLS,text_surface,0,(int)cch.c); Game.gl.UpdateVertexArray(p.row+Global.MAP_OFFSET_ROWS,p.col+Global.MAP_OFFSET_COLS,text_surface,0,(int)cch.c,cch.color.GetFloatValues(),cch.bgcolor.GetFloatValues()); } if(MouseUI.mouse_path != null && MouseUI.mouse_path.Count == 0){ MouseUI.mouse_path = null; } } } } } } break; } } }
public static void AnimateMapCell(int r,int c,colorchar ch,int duration){ AnimateCell(r+Global.MAP_OFFSET_ROWS,c+Global.MAP_OFFSET_COLS,ch,duration); }
void MouseMoveHandler(object sender, MouseMoveEventArgs args) { if (MouseUI.IgnoreMouseMovement) { return; } int row; int col; if (FullScreen) { row = (int)(args.Y - ClientRectangle.Height * ((1.0f - screen_multiplier_h) * 0.5f)) / cell_h; //todo: give this its own var? col = (int)(args.X - ClientRectangle.Width * ((1.0f - screen_multiplier_w) * 0.5f)) / cell_w; } else { row = args.Y / cell_h; col = args.X / cell_w; } switch (MouseUI.Mode) { case MouseMode.Targeting: { int map_row = row - Global.MAP_OFFSET_ROWS; int map_col = col - Global.MAP_OFFSET_COLS; Button b = MouseUI.GetButton(row, col); if (MouseUI.Highlighted != null && MouseUI.Highlighted != b) { MouseUI.RemoveHighlight(); } if (args.XDelta == 0 && args.YDelta == 0) { return; //don't re-highlight immediately after a click } if (b != null) { if (b != MouseUI.Highlighted) { MouseUI.Highlighted = b; colorchar[,] array = new colorchar[b.height, b.width]; for (int i = 0; i < b.height; ++i) { for (int j = 0; j < b.width; ++j) { array[i, j] = Screen.Char(i + b.row, j + b.col); array[i, j].bgcolor = Color.Blue; } } Screen.UpdateGLBuffer(b.row, b.col, array); } } else { if (!Global.KeyPressed && (row != MouseUI.LastRow || col != MouseUI.LastCol) && !KeyIsDown(Key.LControl) && !KeyIsDown(Key.RControl)) { MouseUI.LastRow = row; MouseUI.LastCol = col; Global.KeyPressed = true; if (map_row >= 0 && map_row < Global.ROWS && map_col >= 0 && map_col < Global.COLS) { ConsoleKey key = ConsoleKey.F1; Global.LastKey = new ConsoleKeyInfo(Global.GetChar(key, false), key, false, false, false); } else { ConsoleKey key = ConsoleKey.F2; Global.LastKey = new ConsoleKeyInfo(Global.GetChar(key, false), key, false, false, false); } } } break; } case MouseMode.Directional: { int map_row = row - Global.MAP_OFFSET_ROWS; int map_col = col - Global.MAP_OFFSET_COLS; if (map_row >= 0 && map_row < Global.ROWS && map_col >= 0 && map_col < Global.COLS) { int dir = Actor.player.DirectionOf(new pos(map_row, map_col)); pos p = Actor.player.p.PosInDir(dir); Button dir_b = MouseUI.GetButton(Global.MAP_OFFSET_ROWS + p.row, Global.MAP_OFFSET_COLS + p.col); if (MouseUI.Highlighted != null && MouseUI.Highlighted != dir_b) { MouseUI.RemoveHighlight(); } if (dir_b != null && dir_b != MouseUI.Highlighted) { MouseUI.Highlighted = dir_b; colorchar[,] array = new colorchar[1, 1]; array[0, 0] = Screen.Char(Global.MAP_OFFSET_ROWS + p.row, Global.MAP_OFFSET_COLS + p.col); array[0, 0].bgcolor = Color.Blue; Screen.UpdateGLBuffer(dir_b.row, dir_b.col, array); } } else { if (MouseUI.Highlighted != null) { MouseUI.RemoveHighlight(); } } break; } default: { Button b = MouseUI.GetButton(row, col); if (MouseUI.Highlighted != null && MouseUI.Highlighted != b) { MouseUI.RemoveHighlight(); } if (args.XDelta == 0 && args.YDelta == 0) { return; //don't re-highlight immediately after a click } if (b != null && b != MouseUI.Highlighted) { MouseUI.Highlighted = b; colorchar[,] array = new colorchar[b.height, b.width]; for (int i = 0; i < b.height; ++i) { for (int j = 0; j < b.width; ++j) { array[i, j] = Screen.Char(i + b.row, j + b.col); array[i, j].bgcolor = Color.Blue; } } Screen.UpdateGLBuffer(b.row, b.col, array); /*for(int i=b.row;i<b.row+b.height;++i){ * for(int j=b.col;j<b.col+b.width;++j){ * colorchar cch = Screen.Char(i,j); * cch.bgcolor = Color.Blue; * UpdateVertexArray(i,j,cch.c,ConvertColor(cch.color),ConvertColor(cch.bgcolor)); * } * }*/ } else { if (MouseUI.Mode == MouseMode.Map) { int map_row = row - Global.MAP_OFFSET_ROWS; int map_col = col - Global.MAP_OFFSET_COLS; PhysicalObject o = null; if (map_row >= 0 && map_row < Global.ROWS && map_col >= 0 && map_col < Global.COLS) { o = MouseUI.mouselook_objects[map_row, map_col]; if (MouseUI.VisiblePath && o == null) { o = Actor.M.tile[map_row, map_col]; } } if (MouseUI.mouselook_current_target != null && MouseUI.mouselook_current_target != o) { MouseUI.RemoveMouseover(); } if (o != null && o != MouseUI.mouselook_current_target) { MouseUI.mouselook_current_target = o; bool description_on_right = false; /*int max_length = 29; * if(map_col - 6 < max_length){ * max_length = map_col - 6; * } * if(max_length < 20){ * description_on_right = true; * max_length = 29; * }*/ int max_length = MouseUI.MaxDescriptionBoxLength; if (map_col <= 32) { description_on_right = true; } List <colorstring> desc_box = null; Actor a = o as Actor; if (a != null) { desc_box = Actor.MonsterDescriptionBox(a, true, max_length); } else { Item i = o as Item; if (i != null) { desc_box = Actor.ItemDescriptionBox(i, true, true, max_length); } } if (desc_box != null) { int h = desc_box.Count; int w = desc_box[0].Length(); int player_r = Actor.player.row; int player_c = Actor.player.col; colorchar[,] array = new colorchar[h, w]; if (description_on_right) { for (int i = 0; i < h; ++i) { for (int j = 0; j < w; ++j) { array[i, j] = desc_box[i][j]; if (i == player_r && j + Global.COLS - w == player_c) { Screen.CursorVisible = false; player_r = -1; //to prevent further attempts to set CV to false } } } Screen.UpdateGLBuffer(Global.MAP_OFFSET_ROWS, Global.MAP_OFFSET_COLS + Global.COLS - w, array); } else { for (int i = 0; i < h; ++i) { for (int j = 0; j < w; ++j) { array[i, j] = desc_box[i][j]; if (i == player_r && j == player_c) { Screen.CursorVisible = false; player_r = -1; } } } Screen.UpdateGLBuffer(Global.MAP_OFFSET_ROWS, Global.MAP_OFFSET_COLS, array); } } if (MouseUI.VisiblePath) { MouseUI.mouse_path = Actor.player.GetPath(o.row, o.col, -1, true, true, Actor.UnknownTilePathingPreference.UnknownTilesAreOpen); if (MouseUI.mouse_path.Count == 0) { foreach (Tile t in Actor.M.TilesByDistance(o.row, o.col, true, true)) { if (t.passable) { MouseUI.mouse_path = Actor.player.GetPath(t.row, t.col, -1, true, true, Actor.UnknownTilePathingPreference.UnknownTilesAreOpen); break; } } } pos box_start = new pos(0, 0); int box_h = -1; int box_w = -1; if (desc_box != null) { box_h = desc_box.Count; box_w = desc_box[0].Length(); if (description_on_right) { box_start = new pos(0, Global.COLS - box_w); } } foreach (pos p in MouseUI.mouse_path) { if (desc_box != null && p.row < box_start.row + box_h && p.row >= box_start.row && p.col < box_start.col + box_w && p.col >= box_start.col) { continue; } colorchar cch = Screen.MapChar(p.row, p.col); cch.bgcolor = Color.DarkGreen; if (cch.color == Color.DarkGreen) { cch.color = Color.Black; } //Game.gl.UpdateVertexArray(p.row+Global.MAP_OFFSET_ROWS,p.col+Global.MAP_OFFSET_COLS,text_surface,0,(int)cch.c); Game.gl.UpdateVertexArray(p.row + Global.MAP_OFFSET_ROWS, p.col + Global.MAP_OFFSET_COLS, text_surface, 0, (int)cch.c, cch.color.GetFloatValues(), cch.bgcolor.GetFloatValues()); } if (MouseUI.mouse_path != null && MouseUI.mouse_path.Count == 0) { MouseUI.mouse_path = null; } } } } } break; } } }
public static async void AnimateMapCells(List<pos> cells,colorchar ch,int duration){ List<colorchar> prev = new List<colorchar>(); int idx = 0; foreach(pos p in cells){ prev.Add(MapChar(p.row,p.col)); WriteMapChar(p.row,p.col,ch); ++idx; } await Task.Delay(duration); idx = 0; foreach(pos p in cells){ WriteMapChar(p.row,p.col,prev[idx]); ++idx; } }
public static void WriteArray(int r,int c,colorchar[,] array){ int h = array.GetLength(0); int w = array.GetLength(1); for(int i=0;i<h;++i){ for(int j=0;j<w;++j){ WriteChar(i+r,j+c,array[i,j]); } } }
public static void AnimateProjectile(List<Tile> list,colorchar ch,int duration){ Game.Console.CursorVisible = false; list.RemoveAt(0); foreach(Tile t in list){ AnimateMapCell(t.row,t.col,ch,duration); } Game.Console.CursorVisible = true; }
public static void WriteString(int r,int c,colorstring cs){ if(cs.Length() > 0){ int pos = c; foreach(cstr s1 in cs.strings){ cstr s = new cstr(s1.s,s1.color,s1.bgcolor); if(s.s.Length + pos > Global.SCREEN_W){ s.s = s.s.Substring(0,Global.SCREEN_W - pos); } s.color = ResolveColor(s.color); s.bgcolor = ResolveColor(s.bgcolor); colorchar cch = new colorchar(' ', s.color, s.bgcolor); /*cch.color = s.color; cch.bgcolor = s.bgcolor;*/ ConsoleColor co = GetColor(s.color); if(ForegroundColor != co){ ForegroundColor = co; } co = GetColor(s.bgcolor); if(BackgroundColor != co){ BackgroundColor = co; } int i = 0; bool changed = false; for (int ii = 0; ii < s.s.Length; ii++) { cch.c = s.s.CharAt(ii); if(!memory[r,pos+i].Equals(cch)){ memory[r,pos+i] = cch; changed = true; } ++i; } if(changed){ Game.Console.SetCursorPosition(pos,r); Game.Console.Write(s.s); } pos += s.s.Length; } } }
public static void AnimateExplosion(PhysicalObject obj,int radius,colorchar ch,bool single_frame){ AnimateExplosion(obj,radius,ch,50,single_frame); }
public static void WriteMapChar(int r,int c,colorchar ch){ WriteChar(r+Global.MAP_OFFSET_ROWS,c+Global.MAP_OFFSET_COLS,ch); }
public static async void AnimateExplosion(PhysicalObject obj,int radius,colorchar ch,int duration,bool single_frame){ Game.Console.CursorVisible = false; colorchar[,] prev = new colorchar[radius*2+1,radius*2+1]; for(int i=0;i<=radius*2;++i){ for(int j=0;j<=radius*2;++j){ if(MapBoundsCheck(obj.row-radius+i,obj.col-radius+j)){ prev[i,j] = MapChar(obj.row-radius+i,obj.col-radius+j); } } } if(!single_frame){ for(int i=0;i<=radius;++i){ foreach(Tile t in obj.TilesAtDistance(i)){ WriteMapChar(t.row,t.col,ch); } await Task.Delay(duration); } } else{ foreach(Tile t in obj.TilesWithinDistance(radius)){ WriteMapChar(t.row,t.col,ch); } await Task.Delay(duration); } for(int i=0;i<=radius*2;++i){ for(int j=0;j<=radius*2;++j){ if(MapBoundsCheck(obj.row-radius+i,obj.col-radius+j)){ WriteMapChar(obj.row-radius+i,obj.col-radius+j,prev[i,j]); } } } Game.Console.CursorVisible = true; }
public static void WriteMapString(int r,int c,cstr s){ if(Global.COLS - c > s.s.Length){ //s.s = s.s.Substring(0); //don't move down to the next line } else{ s.s = s.s.Substring(0,Global.COLS - c); } if(s.s.Length > 0){ r += Global.MAP_OFFSET_ROWS; c += Global.MAP_OFFSET_COLS; s.color = ResolveColor(s.color); s.bgcolor = ResolveColor(s.bgcolor); colorchar cch = new colorchar(' ', s.color, s.bgcolor); /*cch.color = s.color; cch.bgcolor = s.bgcolor;*/ ConsoleColor co = GetColor(s.color); if(ForegroundColor != co){ ForegroundColor = co; } co = GetColor(s.bgcolor); if(BackgroundColor != co){ BackgroundColor = co; } int i = 0; bool changed = false; for (int ii = 0; ii < s.s.Length; ii++) { cch.c = s.s.CharAt(ii); if(!memory[r,c+i].Equals(cch)){ memory[r,c+i] = cch; changed = true; } ++i; } if(changed){ Game.Console.SetCursorPosition(c,r); Game.Console.Write(s.s); } } }
public static void AnimateBeam(List<Tile> list,colorchar ch){ AnimateBeam(list,ch,50); }
public static void WriteMapString(int r,int c,colorstring cs){ if(cs.Length() > 0){ r += Global.MAP_OFFSET_ROWS; c += Global.MAP_OFFSET_COLS; int cpos = c; foreach(cstr s1 in cs.strings){ cstr s = new cstr(s1.s,s1.color,s1.bgcolor); if(cpos-Global.MAP_OFFSET_COLS + s.s.Length > Global.COLS){ s.s = s.s.Substring(0,Global.COLS-(cpos-Global.MAP_OFFSET_COLS)); } s.color = ResolveColor(s.color); s.bgcolor = ResolveColor(s.bgcolor); colorchar cch = new colorchar(' ', s.color, s.bgcolor); /* cch.color = s.color; cch.bgcolor = s.bgcolor;*/ ConsoleColor co = GetColor(s.color); if(ForegroundColor != co){ ForegroundColor = co; } co = GetColor(s.bgcolor); if(BackgroundColor != co){ BackgroundColor = co; } int i = 0; bool changed = false; for (int ii = 0; ii < s.s.Length; ii++) { cch.c = s.s.CharAt(ii); if(!memory[r,cpos+i].Equals(cch)){ memory[r,cpos+i] = cch; changed = true; } ++i; } if(changed){ Game.Console.SetCursorPosition(cpos,r); Game.Console.Write(s.s); } cpos += s.s.Length; } /*if(cpos-Global.MAP_OFFSET_COLS < Global.COLS){ WriteString(r,cpos,"".PadRight(Global.COLS-(cpos-Global.MAP_OFFSET_COLS))); }*/ } }
public static void AnimateStorm(pos origin,int radius,int num_frames,int num_per_frame,colorchar ch){ for(int i=0;i<num_frames;++i){ List<pos> cells = new List<pos>(); List<pos> nearby = origin.PositionsWithinDistance(radius); for(int j=0;j<num_per_frame;++j){ cells.Add(nearby.RemoveRandom()); } Screen.AnimateMapCells(cells,ch); } }
public static void AnimateMapCell(int r, int c, colorchar ch) { AnimateMapCell(r, c, ch, 50); }
public static void DrawMapBorder(colorchar ch){ for(int i=0;i<Global.ROWS;i+=Global.ROWS-1){ for(int j=0;j<Global.COLS;++j){ WriteMapChar(i,j,ch); } } for(int j=0;j<Global.COLS;j+=Global.COLS-1){ for(int i=0;i<Global.ROWS;++i){ WriteMapChar(i,j,ch); } } ResetColors(); }
public static colorchar[,] GetCurrentMap(){ colorchar[,] result = new colorchar[Global.ROWS,Global.COLS]; for(int i=0;i<Global.ROWS;++i){ for(int j=0;j<Global.COLS;++j){ result[i,j] = MapChar(i,j); } } return result; }
public static bool Telekinesis(bool cast, Actor user, Tile t) { bool wand = !cast; if (t == null) { return(false); } if (t != null) { if (wand && user == player && !Item.identified[ConsumableType.TELEKINESIS]) { Item.identified[ConsumableType.TELEKINESIS] = true; B.Add("(It was a wand of telekinesis!) "); B.Print(true); } List <Tile> ai_line = null; if (user != player && t == player.tile()) { var fires = user.TilesWithinDistance(12).Where(x => x.passable && x.actor() == null && x.Is(FeatureType.FIRE) && user.CanSee(x) && player.HasBresenhamLineWithCondition(x, false, y => y.passable && y.actor() == null)); if (fires.Count > 0) { ai_line = player.GetBestExtendedLineOfEffect(fires.Random()); } else { if (wand) { ai_line = player.GetBestExtendedLineOfEffect(user); } else { ai_line = player.GetBestExtendedLineOfEffect(player.TileInDirection(Global.RandomDirection())); } } } Actor a = t.actor(); if (a == null && t.inv == null && !t.Is(FeatureType.GRENADE) && t.Is(FeatureType.TROLL_CORPSE, FeatureType.TROLL_BLOODWITCH_CORPSE)) { ActorType troll_type = t.Is(FeatureType.TROLL_CORPSE)? ActorType.TROLL : ActorType.TROLL_BLOODWITCH; FeatureType troll_corpse = t.Is(FeatureType.TROLL_CORPSE)? FeatureType.TROLL_CORPSE : FeatureType.TROLL_BLOODWITCH_CORPSE; Event troll_event = Q.FindTargetedEvent(t, EventType.REGENERATING_FROM_DEATH); troll_event.dead = true; Actor troll = Actor.Create(troll_type, t.row, t.col); foreach (Event e in Q.list) { if (e.target == troll && e.type == EventType.MOVE) { e.tiebreaker = troll_event.tiebreaker; e.dead = true; break; } } Actor.tiebreakers[troll_event.tiebreaker] = troll; troll.symbol = '%'; troll.attrs[AttrType.CORPSE] = 1; troll.Name = new Name(troll.GetName(Possessive) + " corpse"); troll.curhp = troll_event.value; troll.attrs[AttrType.PERMANENT_DAMAGE] = troll_event.secondary_value; troll.attrs[AttrType.NO_ITEM]++; t.features.Remove(troll_corpse); a = troll; } if (a != null) { string msg = "Throw " + a.GetName(true, The) + " in which direction? "; if (a == player) { msg = "Throw yourself in which direction? "; } List <Tile> line = null; if (user == player) { TargetInfo info = a.GetTarget(false, 12, 0, false, true, false, msg); if (info != null) { line = info.extended_line; } } else { line = ai_line; } if (line != null) { if (line.Count == 1 && line[0].actor() == user) { if (wand) { return(true); } return(false); } if (cast) { B.Add(user.GetName(false, The, Verb("cast")) + " telekinesis. ", user); user.MakeNoise(6); //should match spellVolume, hack if (a.type == ActorType.ALASI_BATTLEMAGE && !a.HasSpell(SpellType.TELEKINESIS)) { a.curmp += Spell.Tier(SpellType.TELEKINESIS); if (a.curmp > a.maxmp) { a.curmp = a.maxmp; } a.GainSpell(SpellType.TELEKINESIS); B.Add("Runes on " + a.GetName(false, The, Possessive) + " armor align themselves with the spell. ", a); } } if (a == user && a == player) { B.Add("You throw yourself forward. "); } else { if (line.Count == 1) { B.Add(user.GetName(true, The, Verb("throw")) + " " + a.GetName(true, The) + " into the ceiling. ", user, a); } else { B.Add(user.GetName(true, The, Verb("throw")) + " " + a.GetName(true, The) + ". ", user, a); } } B.DisplayContents(); user.attrs[AttrType.SELF_TK_NO_DAMAGE] = 1; a.attrs[AttrType.TELEKINETICALLY_THROWN] = 1; a.attrs[AttrType.TURN_INTO_CORPSE]++; if (line.Count == 1) { a.TakeDamage(DamageType.NORMAL, DamageClass.PHYSICAL, R.Roll(3, 6), user, "colliding with the ceiling"); a.CollideWith(a.tile()); } else { a.tile().KnockObjectBack(a, line, 12, user); } a.attrs[AttrType.TELEKINETICALLY_THROWN] = 0; user.attrs[AttrType.SELF_TK_NO_DAMAGE] = 0; if (a.curhp <= 0 && a.HasAttr(AttrType.REGENERATES_FROM_DEATH)) { a.attrs[AttrType.TURN_INTO_CORPSE] = 0; a.attrs[AttrType.CORPSE] = 0; a.attrs[AttrType.FROZEN] = 0; a.attrs[AttrType.INVULNERABLE] = 0; a.attrs[AttrType.SHIELDED] = 0; a.attrs[AttrType.BLOCKING] = 0; a.curhp = 1; //this is all pretty hacky - perhaps I should relocate the regenerating corpse through other means. a.TakeDamage(DamageType.NORMAL, DamageClass.NO_TYPE, 500, null); } else { a.CorpseCleanup(); } } else { if (wand) { return(true); } return(false); } } else { bool blast_fungus = false; if (t.type == TileType.BLAST_FUNGUS && !t.Is(FeatureType.GRENADE, FeatureType.WEB, FeatureType.FORASECT_EGG, FeatureType.BONES)) { blast_fungus = true; } if (t.inv != null || blast_fungus) { Item i = t.inv; string itemname = ""; if (blast_fungus) { itemname = "the blast fungus"; } else { itemname = i.GetName(true, The, Extra); } string msg = "Throw " + itemname + " in which direction? "; List <Tile> line = null; if (user == player) { TargetInfo info = t.GetTarget(false, 12, 0, false, true, false, msg); if (info != null) { line = info.extended_line; } } else { line = ai_line; } if (line != null) { if (line.Count > 13) { line = line.ToCount(13); //for range 12 } if (cast) { B.Add(user.GetName(false, The, Verb("cast")) + " telekinesis. ", user); user.MakeNoise(6); //should match spellVolume } if (blast_fungus) { B.Add("The blast fungus is pulled from the floor. ", t); B.Add("Its fuse ignites! ", t); t.Toggle(null); i = Item.Create(ConsumableType.BLAST_FUNGUS, t.row, t.col); if (i != null) { i.other_data = 3; i.revealed_by_light = true; Q.Add(new Event(i, 100, EventType.BLAST_FUNGUS)); Screen.AnimateMapCell(t.row, t.col, new colorchar('3', Color.Red), 100); } } if (line.Count == 1) { B.Add(user.GetName(true, The, Verb("throw")) + " " + itemname + " into the ceiling. ", user, t); } else { B.Add(user.GetName(true, The, Verb("throw")) + " " + itemname + ". ", user, t); } B.DisplayContents(); if (i.quantity > 1) { i.quantity--; bool revealed = i.revealed_by_light; i = new Item(i, -1, -1); i.revealed_by_light = revealed; } else { t.inv = null; Screen.WriteMapChar(t.row, t.col, M.VisibleColorChar(t.row, t.col)); } bool trigger_traps = false; Tile t2 = line.LastBeforeSolidTile(); Actor first = user.FirstActorInLine(line); if (t2 == line.LastOrDefault() && first == null) { trigger_traps = true; } if (first != null) { t2 = first.tile(); } line = line.ToFirstSolidTileOrActor(); //if(line.Count > 0){ // line.RemoveAt(line.Count - 1); //} if (line.Count > 0) { line.RemoveAt(line.Count - 1); } { Tile first_unseen = null; foreach (Tile tile2 in line) { if (!tile2.seen) { first_unseen = tile2; break; } } if (first_unseen != null) { line = line.To(first_unseen); if (line.Count > 0) { line.RemoveAt(line.Count - 1); } } } if (line.Count > 0) //or > 1 ? { user.AnimateProjectile(line, i.symbol, i.color); } if (first == user) { B.Add(user.GetName(false, The, Verb("catch")) + " it! ", user); if (user.inv.Count < Global.MAX_INVENTORY_SIZE) { user.GetItem(i); } else { B.Add("Your pack is too full to fit anything else. "); i.ignored = true; user.tile().GetItem(i); } } else { if (first != null) { B.Add("It hits " + first.GetName(The) + ". ", first); } if (i.IsBreakable()) { B.Add($"{i.GetName(true,The,Extra,Verb("break"))}! ", t2); if (i.ItemClass == ConsumableClass.ORB) { i.Use(null, new List <Tile> { t2 }); } else { i.CheckForMimic(); } t2.MakeNoise(4); } else { t2.GetItem(i); } t2.MakeNoise(2); } if (first != null && first != user && first != player) { first.player_visibility_duration = -1; first.attrs[AttrType.PLAYER_NOTICED]++; } else { if (trigger_traps && t2.IsTrap()) { t2.TriggerTrap(); } } } else { if (wand) { return(true); } return(false); } } else { if (!t.Is(FeatureType.GRENADE) && (t.Is(TileType.DOOR_C, TileType.DOOR_O, TileType.POISON_BULB) || t.Is(FeatureType.WEB, FeatureType.FORASECT_EGG, FeatureType.BONES))) { if (cast) { B.Add(user.GetName(false, The, Verb("cast")) + " telekinesis. ", user); user.MakeNoise(6); //should match spellVolume } if (t.Is(TileType.DOOR_C)) { B.Add("The door slams open. ", t); t.Toggle(null); } else { if (t.Is(TileType.DOOR_O)) { B.Add("The door slams open. ", t); t.Toggle(null); } } if (t.Is(TileType.POISON_BULB)) { t.Bump(0); } if (t.Is(FeatureType.WEB)) { B.Add("The web is destroyed. ", t); t.RemoveFeature(FeatureType.WEB); } if (t.Is(FeatureType.FORASECT_EGG)) { B.Add("The egg is destroyed. ", t); t.RemoveFeature(FeatureType.FORASECT_EGG); //todo: forasect pathing? } if (t.Is(FeatureType.BONES)) { B.Add("The bones are scattered. ", t); t.RemoveFeature(FeatureType.BONES); } } else { bool grenade = t.Is(FeatureType.GRENADE); bool barrel = t.Is(TileType.BARREL); bool flaming_barrel = barrel && t.IsBurning(); bool torch = t.Is(TileType.STANDING_TORCH); string feature_name = ""; int impact_damage_dice = 3; colorchar vis = new colorchar(t.symbol, t.color); switch (t.type) { case TileType.CRACKED_WALL: feature_name = "cracked wall"; break; case TileType.RUBBLE: feature_name = "pile of rubble"; break; case TileType.STATUE: feature_name = "statue"; break; } if (grenade) { impact_damage_dice = 0; feature_name = "grenade"; vis.c = ','; vis.color = Color.Red; } if (flaming_barrel) { feature_name = "flaming barrel of oil"; } if (barrel) { feature_name = "barrel"; } if (torch) { feature_name = "torch"; } if (feature_name == "") { if (wand) { if (user == player) { B.Add("The wand grabs at empty space. ", t); } return(true); } return(false); } string msg = "Throw the " + feature_name + " in which direction? "; bool passable_hack = !t.passable; if (passable_hack) { t.passable = true; } List <Tile> line = null; if (user == player) { TargetInfo info = t.GetTarget(false, 12, 0, false, true, false, msg); if (info != null) { line = info.extended_line; } } else { line = ai_line; } if (passable_hack) { t.passable = false; } if (line != null) { if (cast) { B.Add(user.GetName(false, The, Verb("cast")) + " telekinesis. ", user); user.MakeNoise(6); //should match spellVolume } if (line.Count == 1) { B.Add(user.GetName(true, The, Verb("throw")) + " the " + feature_name + " into the ceiling. ", user, t); } else { B.Add(user.GetName(true, The, Verb("throw")) + " the " + feature_name + ". ", user, t); } B.DisplayContents(); user.attrs[AttrType.SELF_TK_NO_DAMAGE] = 1; switch (t.type) { case TileType.CRACKED_WALL: case TileType.RUBBLE: case TileType.STATUE: case TileType.BARREL: case TileType.STANDING_TORCH: if (flaming_barrel) { t.RemoveFeature(FeatureType.FIRE); } t.Toggle(null, TileType.FLOOR); foreach (Tile neighbor in t.TilesAtDistance(1)) { neighbor.solid_rock = false; } break; } if (grenade) { t.RemoveFeature(FeatureType.GRENADE); Event e = Q.FindTargetedEvent(t, EventType.GRENADE); if (e != null) { e.dead = true; } } Screen.WriteMapChar(t.row, t.col, M.VisibleColorChar(t.row, t.col)); colorchar[,] mem = Screen.GetCurrentMap(); int current_row = t.row; int current_col = t.col; // int knockback_strength = 12; if (line.Count == 1) { knockback_strength = 0; } int i = 0; while (true) { Tile t2 = line[i]; if (t2 == t) { break; } ++i; } line.RemoveRange(0, i + 1); while (knockback_strength > 0) //if the knockback strength is greater than 1, you're passing *over* at least one tile. { Tile t2 = line[0]; line.RemoveAt(0); if (!t2.passable) { if (t2.Is(TileType.CRACKED_WALL, TileType.DOOR_C, TileType.HIDDEN_DOOR) && impact_damage_dice > 0) { string tilename = t2.GetName(true, The); if (t2.type == TileType.HIDDEN_DOOR) { tilename = "a hidden door"; t2.Toggle(null); } B.Add("The " + feature_name + " flies into " + tilename + ". ", t2); t2.Toggle(null); Screen.WriteMapChar(current_row, current_col, mem[current_row, current_col]); } else { B.Add("The " + feature_name + " flies into " + t2.GetName(true, The) + ". ", t2); if (impact_damage_dice > 0) { t2.Bump(M.tile[current_row, current_col].DirectionOf(t2)); } Screen.WriteMapChar(current_row, current_col, mem[current_row, current_col]); } knockback_strength = 0; break; } else { if (t2.actor() != null) { B.Add("The " + feature_name + " flies into " + t2.actor().GetName(true, The) + ". ", t2); if (t2.actor().type != ActorType.SPORE_POD && !t2.actor().HasAttr(AttrType.SELF_TK_NO_DAMAGE)) { t2.actor().TakeDamage(DamageType.NORMAL, DamageClass.PHYSICAL, R.Roll(impact_damage_dice, 6), user, "colliding with a " + feature_name); } knockback_strength = 0; Screen.WriteMapChar(t2.row, t2.col, vis); Screen.WriteMapChar(current_row, current_col, mem[current_row, current_col]); current_row = t2.row; current_col = t2.col; break; } else { if (t2.Is(FeatureType.WEB)) //unless perhaps grenades should get stuck and explode in the web? { t2.RemoveFeature(FeatureType.WEB); } Screen.WriteMapChar(t2.row, t2.col, vis); Screen.WriteMapChar(current_row, current_col, mem[current_row, current_col]); current_row = t2.row; current_col = t2.col; Screen.GLUpdate(); Thread.Sleep(20); } } //M.Draw(); knockback_strength--; } Tile current = M.tile[current_row, current_col]; if (grenade) { B.Add("The grenade explodes! ", current); current.ApplyExplosion(1, user, "an exploding grenade"); } if (barrel) { B.Add("The barrel smashes! ", current); List <Tile> cone = current.TilesWithinDistance(1).Where(x => x.passable); List <Tile> added = new List <Tile>(); foreach (Tile t3 in cone) { foreach (int dir in U.FourDirections) { if (R.CoinFlip() && t3.TileInDirection(dir).passable) { added.AddUnique(t3.TileInDirection(dir)); } } } cone.AddRange(added); foreach (Tile t3 in cone) { t3.AddFeature(FeatureType.OIL); if (t3.actor() != null && !t3.actor().HasAttr(AttrType.OIL_COVERED, AttrType.SLIMED)) { if (t3.actor().IsBurning()) { t3.actor().ApplyBurning(); } else { t3.actor().attrs[AttrType.OIL_COVERED] = 1; B.Add(t3.actor().GetName(false, The, Are) + " covered in oil. ", t3.actor()); if (t3.actor() == player) { Help.TutorialTip(TutorialTopic.Oiled); } } } } if (flaming_barrel) { current.ApplyEffect(DamageType.FIRE); } } if (torch) { current.AddFeature(FeatureType.FIRE); } user.attrs[AttrType.SELF_TK_NO_DAMAGE] = 0; } else { if (wand) { return(true); } return(false); } } } } } else { return(false); } return(true); }
public static colorchar[,] GetCurrentRect(int row,int col,int height,int width){ colorchar[,] result = new colorchar[height,width]; for(int i=0;i<height;++i){ for(int j=0;j<width;++j){ result[i,j] = Char(row+i,col+j); } } return result; }
public static bool Telekinesis(bool cast,Actor user,Tile t) { bool wand = !cast; if(t == null){ return false; } if(t != null){ if(wand && user == player && !Item.identified[ConsumableType.TELEKINESIS]){ Item.identified[ConsumableType.TELEKINESIS] = true; B.Add("(It was a wand of telekinesis!) "); B.PrintAll(); } List<Tile> ai_line = null; if(user != player && t == player.tile()){ var fires = user.TilesWithinDistance(12).Where(x=>x.passable && x.actor() == null && x.Is(FeatureType.FIRE) && user.CanSee(x) && player.HasBresenhamLineWithCondition(x,false,y=>y.passable && y.actor() == null)); if(fires.Count > 0){ ai_line = player.GetBestExtendedLineOfEffect(fires.Random()); } else{ if(wand){ ai_line = player.GetBestExtendedLineOfEffect(user); } else{ ai_line = player.GetBestExtendedLineOfEffect(player.TileInDirection(Global.RandomDirection())); } } } Actor a = t.actor(); if(a == null && t.inv == null && !t.Is(FeatureType.GRENADE) && t.Is(FeatureType.TROLL_CORPSE,FeatureType.TROLL_BLOODWITCH_CORPSE)){ ActorType troll_type = t.Is(FeatureType.TROLL_CORPSE)? ActorType.TROLL : ActorType.TROLL_BLOODWITCH; FeatureType troll_corpse = t.Is(FeatureType.TROLL_CORPSE)? FeatureType.TROLL_CORPSE : FeatureType.TROLL_BLOODWITCH_CORPSE; Event troll_event = Q.FindTargetedEvent(t,EventType.REGENERATING_FROM_DEATH); troll_event.dead = true; Actor troll = Actor.Create(troll_type,t.row,t.col); foreach(Event e in Q.list){ if(e.target == troll && e.type == EventType.MOVE){ e.tiebreaker = troll_event.tiebreaker; e.dead = true; break; } } Actor.tiebreakers[troll_event.tiebreaker] = troll; troll.symbol = '%'; troll.attrs[AttrType.CORPSE] = 1; troll.SetName(troll.name + "'s corpse"); troll.curhp = troll_event.value; troll.attrs[AttrType.PERMANENT_DAMAGE] = troll_event.secondary_value; troll.attrs[AttrType.NO_ITEM]++; t.features.Remove(troll_corpse); a = troll; } if(a != null){ string msg = "Throw " + a.TheName(true) + " in which direction? "; if(a == player){ msg = "Throw yourself in which direction? "; } List<Tile> line = null; if(user == player){ TargetInfo info = a.GetTarget(false,12,0,false,true,false,msg); if(info != null){ line = info.extended_line; } } else{ line = ai_line; } if(line != null){ if(line.Count == 1 && line[0].actor() == user){ if(wand){ return true; } return false; } if(cast){ B.Add(user.You("cast") + " telekinesis. ",user); if(a.type == ActorType.ALASI_BATTLEMAGE && !a.HasSpell(SpellType.TELEKINESIS)){ a.curmp += Spell.Tier(SpellType.TELEKINESIS); if(a.curmp > a.maxmp){ a.curmp = a.maxmp; } a.GainSpell(SpellType.TELEKINESIS); B.Add("Runes on " + a.Your() + " armor align themselves with the spell. ",a); } } if(a == user && a == player){ B.Add("You throw yourself forward. "); } else{ if(line.Count == 1){ B.Add(user.YouVisible("throw") + " " + a.TheName(true) + " into the ceiling. ",user,a); } else{ B.Add(user.YouVisible("throw") + " " + a.TheName(true) + ". ",user,a); } } B.DisplayNow(); user.attrs[AttrType.SELF_TK_NO_DAMAGE] = 1; a.attrs[AttrType.TELEKINETICALLY_THROWN] = 1; a.attrs[AttrType.TURN_INTO_CORPSE]++; if(line.Count == 1){ a.TakeDamage(DamageType.NORMAL,DamageClass.PHYSICAL,R.Roll(3,6),user,"colliding with the ceiling"); a.CollideWith(a.tile()); } else{ a.tile().KnockObjectBack(a,line,12,user); } a.attrs[AttrType.TELEKINETICALLY_THROWN] = 0; user.attrs[AttrType.SELF_TK_NO_DAMAGE] = 0; if(a.curhp <= 0 && a.HasAttr(AttrType.REGENERATES_FROM_DEATH)){ a.attrs[AttrType.TURN_INTO_CORPSE] = 0; a.attrs[AttrType.CORPSE] = 0; a.attrs[AttrType.FROZEN] = 0; a.attrs[AttrType.INVULNERABLE] = 0; a.attrs[AttrType.SHIELDED] = 0; a.attrs[AttrType.BLOCKING] = 0; a.curhp = 1; //this is all pretty hacky - perhaps I should relocate the regenerating corpse through other means. a.TakeDamage(DamageType.NORMAL,DamageClass.NO_TYPE,500,null); } else{ a.CorpseCleanup(); } } else{ if(wand){ return true; } return false; } } else{ bool blast_fungus = false; if(t.type == TileType.BLAST_FUNGUS && !t.Is(FeatureType.GRENADE,FeatureType.WEB,FeatureType.FORASECT_EGG,FeatureType.BONES)){ blast_fungus = true; } if(t.inv != null || blast_fungus){ Item i = t.inv; string itemname = ""; if(blast_fungus){ itemname = "the blast fungus"; } else{ itemname = i.TheName(true); if(i.quantity > 1){ itemname = "the " + i.SingularName(); } } string msg = "Throw " + itemname + " in which direction? "; List<Tile> line = null; if(user == player){ TargetInfo info = t.GetTarget(false,12,0,false,true,false,msg); if(info != null){ line = info.extended_line; } } else{ line = ai_line; } if(line != null){ if(line.Count > 13){ line = line.ToCount(13); //for range 12 } if(cast){ B.Add(user.You("cast") + " telekinesis. ",user); } if(blast_fungus){ B.Add("The blast fungus is pulled from the floor. ",t); B.Add("Its fuse ignites! ",t); t.Toggle(null); i = Item.Create(ConsumableType.BLAST_FUNGUS,t.row,t.col); if(i != null){ i.other_data = 3; i.revealed_by_light = true; Q.Add(new Event(i,100,EventType.BLAST_FUNGUS)); Screen.AnimateMapCell(t.row,t.col,new colorchar('3',Color.Red),100); } } if(line.Count == 1){ B.Add(user.YouVisible("throw") + " " + itemname + " into the ceiling. ",user,t); } else{ B.Add(user.YouVisible("throw") + " " + itemname + ". ",user,t); } B.DisplayNow(); if(i.quantity > 1){ i.quantity--; bool revealed = i.revealed_by_light; i = new Item(i,-1,-1); i.revealed_by_light = revealed; } else{ t.inv = null; Screen.WriteMapChar(t.row,t.col,M.VisibleColorChar(t.row,t.col)); } bool trigger_traps = false; Tile t2 = line.LastBeforeSolidTile(); Actor first = user.FirstActorInLine(line); if(t2 == line.LastOrDefault() && first == null){ trigger_traps = true; } if(first != null){ t2 = first.tile(); } line = line.ToFirstSolidTileOrActor(); //if(line.Count > 0){ // line.RemoveAt(line.Count - 1); //} if(line.Count > 0){ line.RemoveAt(line.Count - 1); } { Tile first_unseen = null; foreach(Tile tile2 in line){ if(!tile2.seen){ first_unseen = tile2; break; } } if(first_unseen != null){ line = line.To(first_unseen); if(line.Count > 0){ line.RemoveAt(line.Count - 1); } } } if(line.Count > 0){ //or > 1 ? user.AnimateProjectile(line,i.symbol,i.color); } if(first == user){ B.Add(user.You("catch",true) + " it! ",user); if(user.inv.Count < Global.MAX_INVENTORY_SIZE){ user.GetItem(i); } else{ B.Add("Your pack is too full to fit anything else. "); i.ignored = true; user.tile().GetItem(i); } } else{ if(first != null){ B.Add("It hits " + first.the_name + ". ",first); } if(i.IsBreakable()){ if(i.quantity > 1){ B.Add(i.TheName(true) + " break! ",t2); } else{ B.Add(i.TheName(true) + " breaks! ",t2); } if(i.NameOfItemType() == "orb"){ i.Use(null,new List<Tile>{t2}); } else{ i.CheckForMimic(); } } else{ t2.GetItem(i); } t2.MakeNoise(2); } if(first != null && first != user && first != player){ first.player_visibility_duration = -1; first.attrs[AttrType.PLAYER_NOTICED]++; } else{ if(trigger_traps && t2.IsTrap()){ t2.TriggerTrap(); } } } else{ if(wand){ return true; } return false; } } else{ if(!t.Is(FeatureType.GRENADE) && (t.Is(TileType.DOOR_C,TileType.DOOR_O,TileType.POISON_BULB) || t.Is(FeatureType.WEB,FeatureType.FORASECT_EGG,FeatureType.BONES))){ if(cast){ B.Add(user.You("cast") + " telekinesis. ",user); } if(t.Is(TileType.DOOR_C)){ B.Add("The door slams open. ",t); t.Toggle(null); } else{ if(t.Is(TileType.DOOR_O)){ B.Add("The door slams open. ",t); t.Toggle(null); } } if(t.Is(TileType.POISON_BULB)){ t.Bump(0); } if(t.Is(FeatureType.WEB)){ B.Add("The web is destroyed. ",t); t.RemoveFeature(FeatureType.WEB); } if(t.Is(FeatureType.FORASECT_EGG)){ B.Add("The egg is destroyed. ",t); t.RemoveFeature(FeatureType.FORASECT_EGG); //todo: forasect pathing? } if(t.Is(FeatureType.BONES)){ B.Add("The bones are scattered. ",t); t.RemoveFeature(FeatureType.BONES); } } else{ bool grenade = t.Is(FeatureType.GRENADE); bool barrel = t.Is(TileType.BARREL); bool flaming_barrel = barrel && t.IsBurning(); bool torch = t.Is(TileType.STANDING_TORCH); string feature_name = ""; int impact_damage_dice = 3; colorchar vis = new colorchar(t.symbol,t.color); switch(t.type){ case TileType.CRACKED_WALL: feature_name = "cracked wall"; break; case TileType.RUBBLE: feature_name = "pile of rubble"; break; case TileType.STATUE: feature_name = "statue"; break; } if(grenade){ impact_damage_dice = 0; feature_name = "grenade"; vis.c = ','; vis.color = Color.Red; } if(flaming_barrel){ feature_name = "flaming barrel of oil"; } if(barrel){ feature_name = "barrel"; } if(torch){ feature_name = "torch"; } if(feature_name == ""){ if(wand){ if(user == player){ B.Add("The wand grabs at empty space. ",t); } return true; } return false; } string msg = "Throw the " + feature_name + " in which direction? "; bool passable_hack = !t.passable; if(passable_hack){ t.passable = true; } List<Tile> line = null; if(user == player){ TargetInfo info = t.GetTarget(false,12,0,false,true,false,msg); if(info != null){ line = info.extended_line; } } else{ line = ai_line; } if(passable_hack){ t.passable = false; } if(line != null){ if(cast){ B.Add(user.You("cast") + " telekinesis. ",user); } if(line.Count == 1){ B.Add(user.YouVisible("throw") + " the " + feature_name + " into the ceiling. ",user,t); } else{ B.Add(user.YouVisible("throw") + " the " + feature_name + ". ",user,t); } B.DisplayNow(); user.attrs[AttrType.SELF_TK_NO_DAMAGE] = 1; switch(t.type){ case TileType.CRACKED_WALL: case TileType.RUBBLE: case TileType.STATUE: case TileType.BARREL: case TileType.STANDING_TORCH: if(flaming_barrel){ t.RemoveFeature(FeatureType.FIRE); } t.Toggle(null,TileType.FLOOR); foreach(Tile neighbor in t.TilesAtDistance(1)){ neighbor.solid_rock = false; } break; } if(grenade){ t.RemoveFeature(FeatureType.GRENADE); Event e = Q.FindTargetedEvent(t,EventType.GRENADE); if(e != null){ e.dead = true; } } Screen.WriteMapChar(t.row,t.col,M.VisibleColorChar(t.row,t.col)); colorchar[,] mem = Screen.GetCurrentMap(); int current_row = t.row; int current_col = t.col; // int knockback_strength = 12; if(line.Count == 1){ knockback_strength = 0; } int i=0; while(true){ Tile t2 = line[i]; if(t2 == t){ break; } ++i; } line.RemoveRange(0,i+1); while(knockback_strength > 0){ //if the knockback strength is greater than 1, you're passing *over* at least one tile. Tile t2 = line[0]; line.RemoveAt(0); if(!t2.passable){ if(t2.Is(TileType.CRACKED_WALL,TileType.DOOR_C,TileType.HIDDEN_DOOR) && impact_damage_dice > 0){ string tilename = t2.TheName(true); if(t2.type == TileType.HIDDEN_DOOR){ tilename = "a hidden door"; t2.Toggle(null); } B.Add("The " + feature_name + " flies into " + tilename + ". ",t2); t2.Toggle(null); Screen.WriteMapChar(current_row,current_col,mem[current_row,current_col]); } else{ B.Add("The " + feature_name + " flies into " + t2.TheName(true) + ". ",t2); if(impact_damage_dice > 0){ t2.Bump(M.tile[current_row,current_col].DirectionOf(t2)); } Screen.WriteMapChar(current_row,current_col,mem[current_row,current_col]); } knockback_strength = 0; break; } else{ if(t2.actor() != null){ B.Add("The " + feature_name + " flies into " + t2.actor().TheName(true) + ". ",t2); if(t2.actor().type != ActorType.SPORE_POD && !t2.actor().HasAttr(AttrType.SELF_TK_NO_DAMAGE)){ t2.actor().TakeDamage(DamageType.NORMAL,DamageClass.PHYSICAL,R.Roll(impact_damage_dice,6),user,"colliding with a " + feature_name); } knockback_strength = 0; Screen.WriteMapChar(t2.row,t2.col,vis); Screen.WriteMapChar(current_row,current_col,mem[current_row,current_col]); current_row = t2.row; current_col = t2.col; break; } else{ if(t2.Is(FeatureType.WEB)){ //unless perhaps grenades should get stuck and explode in the web? t2.RemoveFeature(FeatureType.WEB); } Screen.WriteMapChar(t2.row,t2.col,vis); Screen.WriteMapChar(current_row,current_col,mem[current_row,current_col]); current_row = t2.row; current_col = t2.col; Game.GLUpdate(); Thread.Sleep(20); } } //M.Draw(); knockback_strength--; } Tile current = M.tile[current_row,current_col]; if(grenade){ B.Add("The grenade explodes! ",current); current.ApplyExplosion(1,user,"an exploding grenade"); } if(barrel){ B.Add("The barrel smashes! ",current); List<Tile> cone = current.TilesWithinDistance(1).Where(x=>x.passable); List<Tile> added = new List<Tile>(); foreach(Tile t3 in cone){ foreach(int dir in U.FourDirections){ if(R.CoinFlip() && t3.TileInDirection(dir).passable){ added.AddUnique(t3.TileInDirection(dir)); } } } cone.AddRange(added); foreach(Tile t3 in cone){ t3.AddFeature(FeatureType.OIL); if(t3.actor() != null && !t3.actor().HasAttr(AttrType.OIL_COVERED,AttrType.SLIMED)){ if(t3.actor().IsBurning()){ t3.actor().ApplyBurning(); } else{ t3.actor().attrs[AttrType.OIL_COVERED] = 1; B.Add(t3.actor().YouAre() + " covered in oil. ",t3.actor()); if(t3.actor() == player){ Help.TutorialTip(TutorialTopic.Oiled); } } } } if(flaming_barrel){ current.ApplyEffect(DamageType.FIRE); } } if(torch){ current.AddFeature(FeatureType.FIRE); } user.attrs[AttrType.SELF_TK_NO_DAMAGE] = 0; } else{ if(wand){ return true; } return false; } } } } } else{ return false; } return true; }
public static void WriteChar(int r,int c,colorchar ch){ if(!memory[r,c].Equals(ch)){ ch.color = ResolveColor(ch.color); ch.bgcolor = ResolveColor(ch.bgcolor); memory[r,c] = ch; ConsoleColor co = GetColor(ch.color); if(co != ForegroundColor){ ForegroundColor = co; } co = GetColor(ch.bgcolor); if(co != Game.Console.BackgroundColor || (Global.LINUX && ch.c == " " && ch.color == Color.Black)){//voodoo here. not sure why this is needed. (possible Mono bug) BackgroundColor = co; } Game.Console.SetCursorPosition(c,r); Game.Console.Write(ch.c); } }