PageRenderTime 45ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 2ms

/Poing2/frmBaseBlock.cs

http://github.com/BCProgramming/BASeBlock
C# | 6177 lines | 3673 code | 1651 blank | 853 comment | 589 complexity | 39e75fa9d13489553b0b7ee172863e7d MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /*
  2. * BASeCamp BASeBlock
  3. Copyright (c) 2011, Michael Burgwin
  4. All rights reserved.
  5. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
  6. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  7. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  8. Neither the name of BASeCamp Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
  9. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  10. * */
  11. using System;
  12. using System.Collections.Generic;
  13. using System.ComponentModel;
  14. using System.Data;
  15. using System.Diagnostics;
  16. using System.Drawing;
  17. using System.Drawing.Drawing2D;
  18. using System.Drawing.Imaging;
  19. using System.IO;
  20. using System.Linq;
  21. using System.Runtime.InteropServices;
  22. using System.Runtime.Serialization;
  23. using System.Runtime.Serialization.Formatters.Binary;
  24. using System.Text;
  25. using System.Threading;
  26. using System.Windows.Forms;
  27. using System.Security;
  28. //using System.Windows.Media;
  29. using BASeCamp.BASeBlock.Blocks;
  30. using BASeCamp.BASeBlock.Cheats;
  31. using BASeCamp.BASeBlock.Events;
  32. using BASeCamp.BASeBlock.GameObjects;
  33. using BASeCamp.BASeBlock.GameObjects.Orbs;
  34. using BASeCamp.BASeBlock.PaddleBehaviours;
  35. using BASeCamp.BASeBlock.Particles;
  36. using BASeCamp.Configuration;
  37. using BASeCamp.BASeBlock.GameStates;
  38. using BASeCamp.BASeBlock.HighScores;
  39. using BASeCamp.Updating;
  40. using BASeCamp.Licensing;
  41. using Brush=System.Drawing.Brush;
  42. using Color=System.Drawing.Color;
  43. using Pen=System.Drawing.Pen;
  44. using ThreadState=System.Threading.ThreadState;
  45. using Timer = System.Threading.Timer;
  46. namespace BASeCamp.BASeBlock
  47. {
  48. public partial class frmBaseBlock : Form,iGameClient ,iManagerCallback
  49. {
  50. [DllImport("user32.dll")]
  51. public static extern int SendMessage(IntPtr hWnd, Int32 wMsg, bool wParam, Int32 lParam);
  52. public IGameState ActiveState { get { return gamerunstate;} set { gamerunstate = value;}}
  53. private const int WM_SETREDRAW = 11;
  54. public int[][] GameOverMatrix = new int[][]
  55. {
  56. new int[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
  57. new int[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
  58. new int[]{0,1,1,1,1,1,1,0,0,0,1,1,0,0,0,1,1,1,0,0,1,1,1,0,1,1,1,1,1,1,},
  59. new int[]{0,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,0,0,1,1,1,0,1,1,1,1,1,1,},
  60. new int[]{0,1,1,0,0,0,0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,0,0,0,},
  61. new int[]{0,1,1,0,1,1,1,0,1,1,0,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,1,1,0,0,},
  62. new int[]{0,1,1,0,1,1,1,0,1,1,1,1,1,1,0,1,1,0,0,0,0,1,1,0,1,1,1,1,0,0,},
  63. new int[]{0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,0,0,1,1,0,1,1,0,0,0,0,},
  64. new int[]{0,1,1,1,1,1,1,0,1,1,0,0,1,1,0,1,1,0,0,0,0,1,1,0,1,1,1,1,1,1,},
  65. new int[]{0,1,1,1,1,1,1,0,1,1,0,0,1,1,0,1,1,0,0,0,0,1,1,0,1,1,1,1,1,1,},
  66. new int[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
  67. new int[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
  68. new int[]{0,1,1,1,1,1,1,0,1,1,0,0,1,1,0,0,1,1,1,1,1,1,0,0,1,1,1,1,0,0,},
  69. new int[]{0,1,1,1,1,1,1,0,1,1,0,0,1,1,0,0,1,1,1,1,1,1,0,0,1,1,1,1,1,0,},
  70. new int[]{0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,1,1,0,0,1,1,},
  71. new int[]{0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,0,1,1,1,1,0,0,0,0,1,1,0,0,1,1,},
  72. new int[]{0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,0,1,1,1,1,0,0,0,0,1,1,1,1,1,0,},
  73. new int[]{0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,1,1,1,1,1,1,},
  74. new int[]{0,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,1,1,1,1,1,1,0,0,1,1,0,0,1,1,},
  75. new int[]{0,1,1,1,1,1,1,0,0,0,1,1,0,0,0,0,1,1,1,1,1,1,0,0,1,1,0,0,1,1,},
  76. new int[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
  77. new int[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
  78. new int[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
  79. new int[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
  80. new int[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,},
  81. };
  82. private int MaxParticles = 800;
  83. public class MenuModeMenuItem
  84. {
  85. public class MenuItemStyleData
  86. {
  87. //private Color _BackColor = Color.White;
  88. //private Color _ForeColor = Color.Black;
  89. private Brush _Background = new SolidBrush(Color.White);
  90. private Brush _Foreground = new SolidBrush(Color.Black);
  91. private Pen _BoxBorder = new Pen(Color.Black);
  92. public Brush Background { get { return _Background; } set { _Background = value; } }
  93. public Brush Foreground { get { return _Foreground; } set { _Foreground = value; } }
  94. public Pen BoxBorder { get { return _BoxBorder; } set { _BoxBorder = value; } }
  95. private Color _BackColor, _ForeColor;
  96. public Color BackColor
  97. {
  98. get { return _BackColor; }
  99. set
  100. {
  101. _BackColor = value;
  102. _Background = new SolidBrush(_BackColor);
  103. }
  104. }
  105. public Color ForeColor
  106. {
  107. get { return _ForeColor; }
  108. set
  109. {
  110. _ForeColor = value;
  111. _Foreground = new SolidBrush(_ForeColor);
  112. }
  113. }
  114. private Font _ItemFont = new Font("Arial", 14);
  115. public Font ItemFont { get { return _ItemFont; } set { _ItemFont = value; } }
  116. public MenuItemStyleData()
  117. {
  118. }
  119. public MenuItemStyleData(Color pBackColor, Color pForeColor,Font pItemFont)
  120. {
  121. BackColor = pBackColor;
  122. ForeColor = pForeColor;
  123. ItemFont = pItemFont;
  124. }
  125. }
  126. public delegate void MenuItemEvent(MenuModeMenuItem sender);
  127. public delegate void MenuItemPrePaintEvent(MenuModeMenuItem sender, RectangleF drawarea);
  128. public event MenuItemEvent MenuItemSelect;
  129. public event MenuItemEvent MenuItemUnselect;
  130. public event MenuItemEvent MenuItemChosen;
  131. public event MenuItemPrePaintEvent MenuItemPrePaint;
  132. public void InvokeItemPrePaint(RectangleF drawarea)
  133. {
  134. var temp = MenuItemPrePaint;
  135. if (temp != null) temp.Invoke(this,drawarea);
  136. }
  137. public void InvokeItemSelect()
  138. {
  139. var temp = MenuItemSelect;
  140. if (temp != null) temp.Invoke(this);
  141. }
  142. public void InvokeItemUnselect()
  143. {
  144. var temp = MenuItemUnselect;
  145. if (temp != null) temp.Invoke(this);
  146. }
  147. public void InvokeItemChosen()
  148. {
  149. var temp = MenuItemChosen;
  150. if (temp != null) temp.Invoke(this);
  151. }
  152. private Object _Tag = null;
  153. public Object Tag { get { return _Tag; } set { _Tag = value; } }
  154. private String _Text;
  155. private MenuModeMenuItem.MenuItemStyleData Style = new MenuModeMenuItem.MenuItemStyleData(Color.White,Color.Black,new Font("Arial",14));
  156. private MenuModeMenuItem.MenuItemStyleData SelStyle = new MenuModeMenuItem.MenuItemStyleData(Color.Black,Color.Yellow,new Font("Arial",14,FontStyle.Bold)) ;
  157. private bool _Selected=false;
  158. public bool Selected { get { return _Selected; } set { _Selected = value; } }
  159. public MenuModeMenuItem.MenuItemStyleData OurStyle { get {
  160. return Selected?SelStyle:Style;
  161. } }
  162. public delegate void ItemActionProc(MenuModeMenuItem sender);
  163. private ItemActionProc _Action;
  164. public ItemActionProc Action { get { return _Action; } set { _Action = value; } }
  165. private static Graphics useg = null;
  166. private static bool ginitialized;
  167. public SizeF MeasureItem()
  168. {
  169. if (!ginitialized)
  170. {
  171. Bitmap useb = new Bitmap(1, 1);
  172. useg = Graphics.FromImage(useb);
  173. }
  174. SizeF gotsize = useg.MeasureString(_Text, OurStyle.ItemFont);
  175. return new SizeF(gotsize.Width*1.5f,gotsize.Height);
  176. }
  177. public MenuModeMenuItem(String Text,ItemActionProc MenuAction)
  178. {
  179. _Text=Text;
  180. _Action = MenuAction;
  181. SelStyle.BoxBorder = new Pen(Color.Red, 3);
  182. Style.BoxBorder = new Pen(Color.White, 1);
  183. }
  184. public String Text { get { return _Text; } set { _Text = value; } }
  185. public void Draw(Graphics g, RectangleF drawArea)
  186. {
  187. MenuModeMenuItem.MenuItemStyleData usestyle = OurStyle;
  188. InvokeItemPrePaint(drawArea);
  189. g.FillRectangle(usestyle.Background, drawArea);
  190. StringFormat useformat = new StringFormat();
  191. useformat.Alignment=StringAlignment.Center;
  192. g.DrawRectangle(usestyle.BoxBorder, drawArea.ToRectangle());
  193. g.DrawString(_Text, OurStyle.ItemFont, usestyle.Foreground , drawArea,useformat);
  194. }
  195. }
  196. public class MenuModeData
  197. {
  198. //list of menu items.
  199. private String _MenuMusic = "credit";
  200. private String _MenuTitle = "MENU";
  201. private Font _TitleFont = new Font("Arabia", 18);
  202. public String MenuTitle { get { return _MenuTitle; } set { _MenuTitle = value; } }
  203. public String MenuMusic { get { return _MenuMusic; } set { _MenuMusic = value; } }
  204. public LinkedList<MenuModeMenuItem> items = new LinkedList<MenuModeMenuItem>();
  205. private MenuModeMenuItem _SelectedItem = null;
  206. //accessor which "unselects" (untoggles) the currently selected items selected state when a new one is assigned, and sets the new one.
  207. public MenuModeMenuItem SelectedItem
  208. {
  209. get {return _SelectedItem; }
  210. set {
  211. if (_SelectedItem != null)
  212. {
  213. _SelectedItem.Selected=false;
  214. }
  215. _SelectedItem=value;
  216. _SelectedItem.Selected = true;
  217. }
  218. }
  219. public MenuModeData(IEnumerable<MenuModeMenuItem> pitems, MenuModeMenuItem.MenuItemEvent SelectEvent, MenuModeMenuItem.MenuItemEvent UnselectEvent, MenuModeMenuItem.MenuItemEvent ChosenEvent)
  220. {
  221. foreach (var loopit in pitems)
  222. {
  223. var itemadd = loopit;
  224. itemadd.MenuItemSelect += SelectEvent;
  225. itemadd.MenuItemUnselect += UnselectEvent;
  226. itemadd.MenuItemChosen += ChosenEvent;
  227. items.AddLast(itemadd);
  228. }
  229. }
  230. public void MenuAction(MenuModeMenuItem sender)
  231. {
  232. }
  233. public MenuModeMenuItem HitTest(BCBlockGameState gstate,PointF testpoint)
  234. {
  235. //like the draw routine, we need to acquire the calculated sizes. We just don't draw.
  236. //calculations. First, get a SizeF from each menu item...
  237. List<SizeF> allsizes = (from n in items select n.MeasureItem()).ToList();
  238. //get maximum width...
  239. float totalheight = 0;
  240. foreach (var loopsize in allsizes)
  241. {
  242. totalheight += loopsize.Height;
  243. }
  244. float maxwidth = (from n in allsizes orderby n.Width descending select n).First().Width;
  245. //center the rectangle maxwidth,totalheight in the gamearea.
  246. RectangleF EntireSizeRect = BCBlockGameState.CenterRect(gstate.GameArea,
  247. new SizeF(maxwidth, totalheight));
  248. //title rect will be centered above the entiresize rect. First, we need to measure the title...
  249. SizeF titlesize = BCBlockGameState.MeasureString(_MenuTitle, _TitleFont);
  250. if (titlesize.Width < EntireSizeRect.Width)
  251. {
  252. titlesize = new SizeF(EntireSizeRect.Width, titlesize.Height);
  253. }
  254. PointF TopCenter = new PointF(EntireSizeRect.Left + EntireSizeRect.Width / 2, EntireSizeRect.Top);
  255. RectangleF TitleRect = new RectangleF(TopCenter.X - titlesize.Width / 2, TopCenter.Y - titlesize.Height,
  256. titlesize.Width, titlesize.Height);
  257. //EntireSizeRect = new RectangleF(EntireSizeRect.Left - 20, EntireSizeRect.Top - 20, EntireSizeRect.Width + 20, EntireSizeRect.Height + 20);
  258. float currx = EntireSizeRect.Left;
  259. float currY = EntireSizeRect.Top;
  260. //go through each one and calculate it's rectangle, then see if the given position is inside it.
  261. float selectedY = 0;
  262. MenuModeMenuItem selecteditemuse = null;
  263. foreach (var loopitem in items)
  264. {
  265. var loopiheight = loopitem.MeasureItem();
  266. loopitem.Selected = loopitem == SelectedItem;
  267. {
  268. currY += loopiheight.Height;
  269. RectangleF testrect = new RectangleF(new PointF(currx, currY),
  270. new SizeF(maxwidth, loopiheight.Height));
  271. if (testrect.Contains(testpoint))
  272. {
  273. return loopitem;
  274. }
  275. }
  276. }
  277. return null; //no hit...
  278. }
  279. public void Draw(Graphics g, BCBlockGameState gstate)
  280. {
  281. //calculations. First, get a SizeF from each menu item...
  282. List<SizeF> allsizes = (from n in items select n.MeasureItem()).ToList();
  283. //get maximum width...
  284. float totalheight = 0;
  285. foreach (var loopsize in allsizes)
  286. {
  287. totalheight += loopsize.Height;
  288. }
  289. float maxwidth = (from n in allsizes orderby n.Width descending select n).First().Width;
  290. //center the rectangle maxwidth,totalheight in the gamearea.
  291. RectangleF EntireSizeRect = BCBlockGameState.CenterRect(gstate.GameArea,
  292. new SizeF(maxwidth, totalheight));
  293. //title rect will be centered above the entiresize rect. First, we need to measure the title...
  294. SizeF titlesize = BCBlockGameState.MeasureString(_MenuTitle, _TitleFont);
  295. if (titlesize.Width < EntireSizeRect.Width)
  296. {
  297. titlesize = new SizeF(EntireSizeRect.Width, titlesize.Height);
  298. }
  299. PointF TopCenter = new PointF(EntireSizeRect.Left + EntireSizeRect.Width/2, EntireSizeRect.Top);
  300. RectangleF TitleRect = new RectangleF(TopCenter.X - titlesize.Width/2, TopCenter.Y - titlesize.Height,
  301. titlesize.Width, titlesize.Height);
  302. //draw the title.
  303. g.FillRectangle(new SolidBrush(Color.Green), TitleRect);
  304. g.DrawRectangle(new Pen(Color.Yellow, 3), TitleRect.ToRectangle());
  305. g.DrawString(_MenuTitle, _TitleFont, new SolidBrush(Color.White), TitleRect);
  306. //EntireSizeRect = new RectangleF(EntireSizeRect.Left - 20, EntireSizeRect.Top - 20, EntireSizeRect.Width + 20, EntireSizeRect.Height + 20);
  307. float currx = EntireSizeRect.Left;
  308. float currY = EntireSizeRect.Top;
  309. //go through each one and draw it.
  310. float selectedY = 0;
  311. MenuModeMenuItem selecteditemuse = null;
  312. foreach (var loopitem in items)
  313. {
  314. var loopiheight = loopitem.MeasureItem();
  315. //defer drawing if selected item for last... save info when we encounter it, and then use that info after the loop.
  316. loopitem.Selected = loopitem == SelectedItem;
  317. {
  318. if (loopitem.Selected)
  319. {
  320. selectedY = currY;
  321. selecteditemuse = loopitem;
  322. }
  323. else
  324. {
  325. loopitem.Draw(g,
  326. new RectangleF(new PointF(currx, currY),
  327. new SizeF(maxwidth, loopiheight.Height)));
  328. }
  329. currY += loopiheight.Height;
  330. }
  331. }
  332. //draw the selected item...
  333. if (selecteditemuse != null)
  334. {
  335. selecteditemuse.Draw(g,new RectangleF(new PointF(currx,selectedY),new SizeF(maxwidth,selecteditemuse.MeasureItem().Height)));
  336. }
  337. }
  338. public MenuModeData(String[] MenuItems,MenuModeMenuItem.MenuItemEvent SelectEvent,MenuModeMenuItem.MenuItemEvent UnselectEvent,MenuModeMenuItem.MenuItemEvent ChosenEvent,MenuModeMenuItem.MenuItemPrePaintEvent prepaint )
  339. {
  340. //constructor that accepts a bunch of strings, and the event assignments.
  341. foreach (String loopit in MenuItems)
  342. {
  343. var itemadd = new MenuModeMenuItem(loopit, MenuAction);
  344. itemadd.MenuItemSelect += SelectEvent;
  345. itemadd.MenuItemUnselect += UnselectEvent;
  346. itemadd.MenuItemChosen += ChosenEvent;
  347. itemadd.MenuItemPrePaint += prepaint;
  348. items.AddLast(itemadd);
  349. }
  350. }
  351. }
  352. private String GameOverHiScores = "";
  353. private DateTime lastscoreshow;
  354. private int Nextshowhiscore = 1; //next hi score to be shown by the "Game Over" screen...
  355. private Graphics pcgraph;
  356. //private Image GameAreaImage; //used during level complete tally...
  357. private Bitmap BackBufferBitmap;
  358. private Graphics backBufferCanvas;
  359. private List<String> RecentCheats = new List<string>();
  360. private int currentcheatsel = 0; //<<index into the list of the currently "selected" cheat; only really valid for a single
  361. private int currentcheatcharpos = 0; //position within cheat string, will be changable via arrow keys, home, end, etc.
  362. //"session" of the cheat "window".
  363. public bool DemoMode=false; //if true, refuses player interactions.
  364. public struct Tallyscreendata
  365. {
  366. public String TallyScreenString;
  367. public Image TallyImage;
  368. }
  369. private MenuModeData menudata;
  370. private Tallyscreendata tallydata;
  371. private IGameState statebeforepause;
  372. public Rectangle AvailableClientArea = new Rectangle(0, 0, 493, 427); //default client area. the HUD is drawn to the right this.
  373. private IGameState _gamerunstate = new StateNotRunning();
  374. public IGameState gamerunstate { get {
  375. return _gamerunstate; }
  376. set {
  377. _gamerunstate = value; Debug.Print("Game run state set to " + value.GetType().Name +" Stack:" + new StackTrace().ToString());
  378. }
  379. }
  380. public Thread GameThread=null;
  381. public Random mrandom = BCBlockGameState.rgen;
  382. public int mScoreatlevelstart = 0;
  383. public TimeSpan mLevelTime;
  384. public int LevelDeathCount = 0;
  385. public DateTime mLevelIntroStartTime;
  386. public TimeSpan mLevelParTime;
  387. public BCBlockGameState mGameState;
  388. public LevelSet mPlayingSet;
  389. public int mPlayingLevel;
  390. private Queue<PlayMessageData> LevelMessageQueue = null;
  391. public bool ShowDebugInfo=false;
  392. public LevelSet GetPlayingSet()
  393. {
  394. return mPlayingSet;
  395. }
  396. public static void SuspendDrawing(Control parent)
  397. {
  398. parent.Invoke((MethodInvoker)(()=>SendMessage(parent.Handle, WM_SETREDRAW, false, 0)));
  399. }
  400. public static void ResumeDrawing(Control parent)
  401. {
  402. parent.Invoke((MethodInvoker)(() => SendMessage(parent.Handle, WM_SETREDRAW, true, 0)));
  403. //parent.Refresh();
  404. }
  405. public Level mPlayingLevelobj
  406. {
  407. get
  408. {
  409. return mPlayingSet.Levels[mPlayingLevel - 1];
  410. }
  411. }
  412. //draws in several layers
  413. //the background layer...
  414. private Bitmap backgroundbitmap;
  415. private Graphics BackgroundBuffer;
  416. private Random mRandom = new Random();
  417. //and the "block" layer...
  418. private Bitmap BlockDrawBitmap;
  419. private Graphics BlockDrawBuffer;
  420. private bool sidebarbgdrawn=false;
  421. //decided that the moving blocks will be on a separate layer from the standard blocks.
  422. private Bitmap MovingBlockBitmap;
  423. private Graphics MovingBlockBuffer;
  424. private Bitmap SidebarBitmap;
  425. private Graphics sidebarGraphics;
  426. private Image SidebarImage;
  427. //private Bitmap backgroundpic = new Bitmap("D:\\banner2.png");
  428. private int drawbackgroundoffset = 0;
  429. /// <summary>
  430. /// set in GameProc and queried in the Paint() routine to determine wether nonanimated blocks need to be redrawn.
  431. /// </summary>
  432. private bool mredrawblocks=true;
  433. /// <summary>
  434. /// set in GameProc and queried in the Paint() routine to determine wether nonanimated blocks need to be redrawn.
  435. /// </summary>
  436. ///
  437. ///<summary>
  438. ///also set in GameProc for consumption in the paint() routine; previously I was performing the LINQ to create this (the blocks that return true for "requiresPerformFrame" were in one, ones that returned false in another).
  439. ///although I don't know how LINQ is implemented internally I hazard a guess and say that repetition is not a good thing, so I graduated
  440. ///some collections to form-level locals.
  441. /// </summary>
  442. private List<Block> staticblocks;
  443. private List<Block> AnimatedBlocks;
  444. private bool mRedrawAnimated=true;
  445. private bool gamethreadsuspended=false;
  446. private int gamepauseamount=0;
  447. //the ball and paddle are drawn to the Picturebox graphics object in the Paint routine.
  448. private Color getrandomcolor()
  449. {
  450. Func<int> randomint = new Func<int>(()=>((int)(mrandom.NextDouble()*255)));
  451. return Color.FromArgb(randomint(),randomint(),randomint(),randomint());
  452. }
  453. public void ReplaceBlocks(Func<Block, Block> replacefunc)
  454. {
  455. LinkedList<Block> newblocks = new LinkedList<Block>();
  456. Block createdblock;
  457. foreach (Block loopblock in mGameState.Blocks)
  458. {
  459. if (!loopblock.BlockRectangle.IsEmpty)
  460. {
  461. createdblock = replacefunc(loopblock);
  462. createdblock.BlockTriggers = loopblock.BlockTriggers;
  463. createdblock.BlockEvents = loopblock.BlockEvents;
  464. foreach (BlockTrigger bt in createdblock.BlockTriggers)
  465. {
  466. bt.OwnerBlock = createdblock;
  467. }
  468. foreach (BlockEvent be in createdblock.BlockEvents)
  469. {
  470. be.OwnerBlock = createdblock;
  471. }
  472. if (createdblock != null)
  473. newblocks.AddLast(createdblock);
  474. }
  475. }
  476. mGameState.Blocks.Clear();
  477. mGameState.Blocks.AddRangeAfter(newblocks);
  478. staticblocks = (from bsel in mGameState.Blocks where !bsel.RequiresPerformFrame() select bsel).ToList();
  479. AnimatedBlocks = (from bsel in mGameState.Blocks where bsel.RequiresPerformFrame() select bsel).ToList();
  480. mredrawblocks = true;
  481. mRedrawAnimated = true;
  482. //invoke redraw
  483. PicGame.Invoke((MethodInvoker)(() => PicGame.Invalidate()));
  484. }
  485. public void UpdateBlocks()
  486. {
  487. staticblocks = (from bsel in mGameState.Blocks where !bsel.RequiresPerformFrame() select bsel).ToList();
  488. AnimatedBlocks = (from bsel in mGameState.Blocks where bsel.RequiresPerformFrame() select bsel).ToList();
  489. mredrawblocks = true;
  490. mRedrawAnimated = true;
  491. }
  492. public static int ScoreRevealDelayTime = 500;
  493. private Color RandomColor()
  494. {
  495. return Color.FromArgb((int)(mrandom.NextDouble() * 128 + 128), (int)(mrandom.NextDouble() * 255), (int)(mrandom.NextDouble() * 255), (int)(mrandom.NextDouble() * 255));
  496. }
  497. private LevelSet CreateDefaultLevelSet()
  498. {
  499. iLevelSetBuilder defaultbuilder = new DefaultLevelBuilder();
  500. LevelSet returnset = defaultbuilder.BuildLevelSet(AvailableClientArea,this);
  501. //returnset.Save(@"D:\textoutxaml.xaml");
  502. return returnset;
  503. }
  504. private Level CreateDefaultLeveltestray(int levelnumber)
  505. {
  506. Level returnlevel = new Level();
  507. //returnlevel.levelballs.Add(new cBall(new PointF(PicGame.ClientSize.Width / 2, PicGame.ClientSize.Height - 50), new PointF(-2f, -2f)));
  508. returnlevel.LevelName = "Level " + levelnumber.ToString();
  509. returnlevel.MusicName = "ENDLESSCHALLENGE";
  510. returnlevel.levelballs.Add(new cBall(new PointF(30, 30), new PointF(2, 2)));
  511. /*
  512. for (int i = 0; i < PicGame.Width; i += 32)
  513. {
  514. returnlevel.levelblocks.Add(new RayBlock(new RectangleF(i, 50, 32, 16)));
  515. }
  516. */
  517. //returnlevel.levelblocks.Add(new RayBlock(new RectangleF(0,2,PicGame.Width,32)));
  518. for (int i = 0; i < PicGame.Width / 2; i += 32)
  519. {
  520. returnlevel.levelblocks.Add(new BoundedMovingBlock(new RayBlock(new RectangleF(PicGame.Width/2-(i/2), i, 32, 16)),
  521. new PointF(2 + (float)(mRandom.NextDouble() * 3), 0)));
  522. returnlevel.levelblocks.Add(new BoundedMovingBlock(new RayBlock(new RectangleF(PicGame.Width / 2 + (i / 2), i, 32, 16)),
  523. new PointF(2+ (float)(mRandom.NextDouble()*3), 0)));
  524. }
  525. returnlevel.levelblocks.Add(new NormalBlock(new RectangleF(PicGame.Width/2,5,32,16),new SolidBrush(Color.Red),new Pen(Color.Yellow)));
  526. return returnlevel;
  527. }
  528. private BCBlockGameState InitGameState(LevelSet useset, int startlevel)
  529. {
  530. BCBlockGameState newstate = new BCBlockGameState(this,PicGame,AvailableClientArea);
  531. BCBlockGameState.MainGameState = newstate;
  532. if(useset.Levels.Count < startlevel)
  533. throw new ArgumentException("Specified Level, " + startlevel.ToString() + " not found in given levelset, which contains " + useset.Levels.Count.ToString() + " Levels.");
  534. Level levelcopy = useset.Levels[startlevel-1];
  535. foreach(cBall levelball in levelcopy.levelballs)
  536. {
  537. newstate.Balls.AddLast(new cBall(levelball));
  538. }
  539. //newstate.Balls.Add(new cBall(newstate,new PointF(PicGame.ClientSize.Width/2,PicGame.ClientSize.Height-50),new PointF(-4f,-4f)));
  540. newstate.OnBallHitBottom += new BCBlockGameState.BallHitBottomProcedure(newstate_OnBallHitBottom);
  541. foreach(Block levelblock in levelcopy.levelblocks)
  542. {
  543. newstate.Blocks.AddLast((Block)levelblock.Clone());
  544. }
  545. /*
  546. for (int x = 0; x < PicGame.Width; x += 32)
  547. {
  548. for (int y = 0; y < PicGame.Height / 2; y += 16)
  549. {
  550. if (mrandom.NextDouble() > 0.1)
  551. newstate.Blocks.Add(new NormalBlock(newstate, new RectangleF(x, y, 32, 16), new SolidBrush(RandomColor()), new Pen(Color.Black, 1)));
  552. else
  553. newstate.Blocks.Add(new BombBlock(newstate, new RectangleF(x, y, 32, 16)));
  554. }
  555. }
  556. * */
  557. return newstate;
  558. }
  559. private PointF MidPoint(RectangleF ofrect)
  560. {
  561. return new PointF(ofrect.Left + (ofrect.Width / 2), ofrect.Top + (ofrect.Height / 2));
  562. }
  563. private IEnumerable<RectangleF> BlocksFromMatrix(int[][] Matrixuse)
  564. {
  565. //15/26, also zero.
  566. float usewidth = AvailableClientArea.Width / Matrixuse[0].Length;
  567. float useheight = AvailableClientArea.Height / Matrixuse.Length;
  568. for (int x = 0; x < Matrixuse.Length; x++)
  569. {
  570. for (int y = 0; y < Matrixuse[x].Length; y++)
  571. {
  572. //if it is a black pixel..
  573. if (Matrixuse[x][y]==1)
  574. {
  575. //add a new rectangle...
  576. yield return new RectangleF(y*usewidth,x*useheight,usewidth,useheight);
  577. }
  578. }
  579. }
  580. }
  581. private LevelSet CreateGameOverSet()
  582. {
  583. LevelSet returnset = new LevelSet();
  584. for (int i = 0; i < mPlayingSet.Levels.Count; i++)
  585. {
  586. Level golevel = new Level();
  587. golevel.levelballs.Add(new cBall(new PointF(15, 15), new PointF(2, 2)));
  588. golevel.SidebarTextColor = Color.Black;
  589. //now, we add the blocks.
  590. //a square of blocks, 10 blocks wide and 15 blocks high, centered around the middle.
  591. SizeF middleblocksize = new SizeF(32*10, 16*15);
  592. RectangleF middlecentered = GetCenteredRect(middleblocksize, AvailableClientArea);
  593. GraphicsPath usepath = new GraphicsPath();
  594. IEnumerable<RectangleF> userects = BlocksFromMatrix(GameOverMatrix); //known to work
  595. foreach (RectangleF createblockrect in userects)
  596. {
  597. Block addthisblock;
  598. if (BCBlockGameState.rgen.NextDouble() > 0.1f)
  599. addthisblock = new InvincibleBlock(createblockrect);
  600. else
  601. {
  602. addthisblock = new NormalBlock(createblockrect);
  603. }
  604. golevel.levelblocks.Add(addthisblock);
  605. }
  606. golevel.levelblocks.Add(new NormalBlock(new RectangleF(-300, -300, 32, 16)));
  607. //add the top line...
  608. /* for (int x = 0; x < middleblocksize.Width; x += 32)
  609. {
  610. Block newblock = new InvincibleBlock(new RectangleF(middlecentered.Left + x, middlecentered.Top, 32, 16));
  611. golevel.levelblocks.Add(newblock);
  612. }
  613. //add the line on the left...
  614. for (int y = 16; y < middleblocksize.Height; y += 16)
  615. {
  616. Block newblock = new InvincibleBlock(new RectangleF(middlecentered.Left, middlecentered.Top + y, 32, 16));
  617. golevel.levelblocks.Add(newblock);
  618. }
  619. */
  620. returnset.Levels.Add(golevel);
  621. }
  622. return returnset;
  623. }
  624. bool HiscoreCheck()
  625. {
  626. String PlayerName = BCBlockGameState.Settings.PlayerName;
  627. int position = 0;
  628. // gamethread should be aborted. If it isn't- we do it.
  629. if ((GameThread!=null) && (GameThread.IsAlive) && GameThread != Thread.CurrentThread)
  630. {
  631. //abort it.
  632. GameThread.Abort();
  633. GameThread=null;
  634. }
  635. if ((position = mPlayingSet.HighScores.Eligible(PlayerName,(int)mGameState.GameScore)) > 0)
  636. {
  637. //score made! woop!
  638. HighScoreEntryMode(position,PlayerName);
  639. return true;
  640. }
  641. return false;
  642. }
  643. void GameOver()
  644. {
  645. if (GameThread != null && GameThread!=Thread.CurrentThread)
  646. GameThread.Abort();
  647. bool gotscore=false;
  648. BCBlockGameState.Soundman.StopMusic();
  649. //TODO: here is where we would "submit" the score to the HighScore management system... but ONLY if demo mode is off!
  650. //create the game over level.
  651. if (DemoMode == false)
  652. {
  653. gotscore=HiscoreCheck();
  654. }
  655. //if they didn't get a hi score, forcegameover().... otherwise, game over will be called after they enter their name.
  656. if(!gotscore) forcegameover();
  657. }
  658. private int HighScoreNamesMaxLength = 0;
  659. private int HighScoreScoresMaxLength = 0;
  660. private int HighScoresMaxSeparators = 0;
  661. private LevelSet restartset = null;
  662. private void forcegameover()
  663. {
  664. gamerunstate = new StateLevelOutroGameOver();
  665. LevelSet mGoverSet = CreateGameOverSet();
  666. DemoMode = true;
  667. ActualPlaySet = mPlayingSet;
  668. Nextshowhiscore = 0;
  669. GameOverHiScores = "Top - " + ActualPlaySet.SetName;
  670. //calculate maximum length of names and scores.
  671. HighScoreNamesMaxLength = Math.Min(ActualPlaySet.HighScores.GetScores().Max((w) => w.Name.Length),20);
  672. HighScoreScoresMaxLength = ActualPlaySet.HighScores.GetScores().Max((w) => w.Score.ToString().Length);
  673. HighScoresMaxSeparators= Math.Max(HighScoreNamesMaxLength+1,9);
  674. //cache the current set...
  675. restartset = mPlayingSet;
  676. tallydata.TallyImage = BCBlockGameState.Imageman.getImageRandom(mPlayingLevelobj.GameOverPicKey);
  677. PlayLevel(mGameState, mGoverSet.Levels[0]);
  678. gamerunstate = new StateLevelOutroGameOver();
  679. }
  680. protected iActiveSoundObject ds;
  681. private void ExplodePaddle()
  682. {
  683. if(mGameState.PlayerPaddle==null) return;
  684. Random rg = BCBlockGameState.rgen;
  685. Rectangle paddlerect = mGameState.PlayerPaddle.Getrect();
  686. for (int i = 0; i < 120; i++)
  687. {
  688. //todo: fix so this isn't called repeatedly because there is a ball outside...
  689. //(add another ball somewhere else, invisible, maybe?)
  690. int minvalue = Math.Min(paddlerect.Left, paddlerect.Right);
  691. int maxvalue = Math.Max(paddlerect.Left, paddlerect.Right);
  692. Point randomspot = new Point(rg.Next(minvalue, maxvalue), rg.Next(paddlerect.Top, paddlerect.Bottom));
  693. PointF rspot = randomspot.ToPointF();
  694. Particle dp = null;
  695. //Type[] particletypes = new Type[] { typeof(DustParticle),typeof(FireParticle),typeof(PolyDebris)};
  696. int rnum = rg.Next(1, 3);
  697. if (rnum == 1)
  698. dp = new DustParticle(rspot);
  699. else
  700. {
  701. PolyDebris pd = new PolyDebris(rspot, (rg.NextDouble()*4)-2, Color.YellowGreen);
  702. pd.PenColor=Color.YellowGreen;
  703. pd.BrushColor=Color.YellowGreen;
  704. dp = pd;
  705. }
  706. mGameState.Particles.Add(dp);
  707. }
  708. //use Level death sound...
  709. //BCBlockGameState.Soundman.SetMusicVolume(0.0f);
  710. BCBlockGameState.Soundman.PauseMusic(true);
  711. BCBlockGameState.Soundman.Driver.OnSoundStop += new OnSoundStopDelegate(DeathMusicStop);
  712. ds = BCBlockGameState.Soundman.PlaySound(mPlayingLevelobj.DeathSound);
  713. mGameState.PlayerPaddle.InvokeOnDeath();
  714. mGameState.PlayerPaddle = null;
  715. }
  716. void DeathMusicStop(iActiveSoundObject objstop)
  717. {
  718. if (objstop == ds)
  719. {
  720. //remove this method...
  721. BCBlockGameState.Soundman.Driver.OnSoundStop -= DeathMusicStop;
  722. //reset the volume, too.
  723. try
  724. {
  725. BCBlockGameState.Soundman.PauseMusic(false); //unpause...
  726. //BCBlockGameState.Soundman.GetPlayingMusic_Active().setVolume(1.0f);
  727. }
  728. catch
  729. {
  730. //ignored...
  731. }
  732. }
  733. }
  734. private DateTime DeathStart;
  735. void LifeLost()
  736. {
  737. //we cant lose a life if we are already "dying"
  738. Dorefreshstats = true;
  739. if(gamerunstate is StateDeath) return;
  740. //change state to be death, and put a bunch of explodey particles all over.
  741. if (mGameState.PlayerPaddle != null)
  742. {
  743. Rectangle paddlerect = mGameState.PlayerPaddle.Getrect();
  744. /* foreach (cBall createball in mGameState.Balls)
  745. {
  746. createball.Velocity = new PointF(0, 0);
  747. createball.Location = new PointF(-50, paddlerect.Bottom);
  748. createball.Radius = 05f;
  749. createball.DrawColor = Color.Blue;
  750. }
  751. */
  752. LevelDeathCount++;
  753. //cut macguffins in half and explode from the paddle.
  754. mGameState.MacGuffins /= 2;
  755. PointF SpawnGuffLocation = new PointF((float)mGameState.PlayerPaddle.Getrect().CenterPoint().X, mGameState.PlayerPaddle.Getrect().Top - 16);
  756. for (int i = 0; i < mGameState.MacGuffins; i++)
  757. {
  758. //choose a random velocity. between PI and PI*2; this will be upwards-only.
  759. double useangle = Math.PI + (BCBlockGameState.rgen.NextDouble()*Math.PI);
  760. PointF RandomSpeed = BCBlockGameState.GetRandomVelocity(3, 5, useangle);
  761. MacGuffinOrb mgo = new MacGuffinOrb(SpawnGuffLocation);
  762. mgo.MacGuffinValue = BCBlockGameState.rgen.Next(0, 6);
  763. mgo.Velocity = RandomSpeed;
  764. mGameState.GameObjects.AddLast(mgo);
  765. }
  766. ExplodePaddle();
  767. }
  768. //remove all gamecharacter objects.
  769. List<GameCharacter> removethese = new List<GameCharacter>(from m in mGameState.GameObjects where m is GameCharacter select (GameCharacter)m);
  770. foreach (GameCharacter gchar in removethese)
  771. {
  772. mGameState.GameObjects.Remove(gchar);
  773. }
  774. gamerunstate = new StateDeath();
  775. DeathStart=DateTime.Now;
  776. }
  777. void PostLifeLost()
  778. {
  779. Dorefreshstats = true;
  780. if (mPlayingSet != null)
  781. {
  782. mPlayingSet.Statistics.Deaths++;
  783. }
  784. mGameState.playerLives--;
  785. //lblLives.Invoke(((MethodInvoker)(() => lblLives.Text = mGameState.playerLives.ToString())));
  786. gamethreadsuspended = true;
  787. //Thread.Sleep(500);
  788. gamethreadsuspended = false;
  789. gamerunstate = new StateRunning();
  790. if (mGameState.playerLives <= 0)
  791. {
  792. GameOver();
  793. }
  794. else
  795. {
  796. //reinitialize the balls from the "stored" levelset...
  797. if (mGameState.PlayerPaddle != null)
  798. {
  799. lock (mGameState.PlayerPaddle) //lock it to prevent race condition.
  800. {
  801. //added June 24th 2011- Destroy() routine needs to be called when reinstantiating the paddle, otherwise
  802. //the "old" paddle, and it's behaviours, will still have active hooks to any events they hooked.
  803. foreach (var loopbeh in mGameState.PlayerPaddle.Behaviours)
  804. {
  805. loopbeh.UnHook();
  806. }
  807. mGameState.PlayerPaddle.Behaviours.Clear();
  808. }
  809. }
  810. mGameState.PlayerPaddle = new Paddle(mGameState, new Size(48, 15), new PointF(mGameState.GameArea.Width / 2, mGameState.TargetObject.Height - 35), BCBlockGameState.Imageman.getLoadedImage("paddle"));
  811. mGameState.PlayerPaddle.OnHPChange+=PlayerPaddle_OnHPChange;
  812. mGameState.PlayerPaddle.OnEnergyChange +=PlayerPaddle_OnEnergyChange;
  813. foreach (cBall loopball in mPlayingSet.Levels[mPlayingLevel - 1].levelballs)
  814. {
  815. mGameState.Balls.AddLast((cBall)loopball.Clone());
  816. }
  817. //iterate through the levels blocks as well and see which ones we need to respawn...
  818. foreach (Block iterateblock in mPlayingSet.Levels[mPlayingLevel - 1].levelblocks)
  819. {
  820. if (iterateblock.AutoRespawn)
  821. {
  822. mGameState.Blocks.AddLast((Block)iterateblock.Clone());
  823. }
  824. }
  825. }
  826. }
  827. public void ForceDeath()
  828. {
  829. LifeLost();
  830. }
  831. void newstate_OnBallHitBottom(cBall ball)
  832. {
  833. }
  834. private Bitmap IntroSequenceBitmap;
  835. private Graphics IntroSequenceGraphic;
  836. public float CurrentFPS { get; set; }
  837. public void PlayLevel(BCBlockGameState stateobject, Level playthislevel)
  838. {
  839. Debug.Print("PlayLevel Entered...");
  840. //first, terminate the game thread, if it is running...
  841. bool ongamethread = (GameThread == Thread.CurrentThread);
  842. if (GameThread != null && GameThread != Thread.CurrentThread)
  843. {
  844. Debug.Print("GameThread is running; Aborting...");
  845. GameThread.Abort();
  846. }
  847. Debug.Print("Stopping playing music...");
  848. BCBlockGameState.Soundman.StopMusic();
  849. //next, we copy the balls and blocks from playthislevel...
  850. //clear any existing balls or blocks...
  851. //stateobject.Balls.Clear();
  852. //stateobject.Blocks.Clear();
  853. Debug.Print("Clearing current game state variables...");
  854. stateobject.GameObjects.Clear();
  855. stateobject.Particles.Clear();
  856. stateobject.Balls = new LinkedList<cBall>();
  857. stateobject.Blocks = new LinkedList<Block>();
  858. stateobject.RemoveBalls.Clear();
  859. Debug.Print("Cloning level data to current state...");
  860. foreach (cBall copyball in playthislevel.levelballs)
  861. {
  862. stateobject.Balls.AddLast((cBall) copyball.Clone());
  863. }
  864. foreach (Block copyblock in playthislevel.levelblocks)
  865. {
  866. stateobject.Blocks.AddLast((Block) copyblock.Clone());
  867. }
  868. if (stateobject.PlayerPaddle != null)
  869. {
  870. lock (stateobject.PlayerPaddle) //lock it to prevent race condition.
  871. {
  872. //added June 24th 2011- Destroy() routine needs to be called when reinstantiating the paddle, otherwise
  873. //the "old" paddle, and it's behaviours, will still have active hooks to any events they hooked.
  874. foreach (var loopbeh in stateobject.PlayerPaddle.Behaviours)
  875. {
  876. loopbeh.UnHook();
  877. }
  878. stateobject.PlayerPaddle.Behaviours.Clear();
  879. }
  880. stateobject.PlayerPaddle.OnHPChange += PlayerPaddle_OnHPChange;
  881. stateobject.PlayerPaddle.OnEnergyChange += PlayerPaddle_OnEnergyChange;
  882. }
  883. //LevelMessageQueue = new Queue<PlayMessageData>(playthislevel.MessageQueue.Clone());
  884. LevelMessageQueue = playthislevel.CreateMessageQueue();
  885. Debug.Print("Level contains " + stateobject.Balls.Count.ToString() + " balls and " +
  886. stateobject.Blocks.Count.ToString() + " blocks.");
  887. Debug.Print("Playing level music...");
  888. PlayLevelMusic(playthislevel, true);
  889. //change sidebarimage if the Level has one to use.
  890. //the sidebarimage in the Level will be a key. if it's not null or empty, load the Image from the Image manager.
  891. SideBarImageCanvas = null; //nullify so PaintSideBarStats will redraw it.
  892. if (!String.IsNullOrEmpty(playthislevel.SidebarImageKey))
  893. {
  894. SidebarImage = BCBlockGameState.Imageman.getLoadedImage(playthislevel.SidebarImageKey);
  895. }
  896. else
  897. {
  898. SidebarImage = BCBlockGameState.Imageman.getLoadedImage("sidebarbg");
  899. }
  900. //create the bitmap of the introduction text.
  901. #region create introduction bitmap
  902. Debug.Print("Creating Intro sequence bitmap...");
  903. //mGameState.BackgroundDraw = new BackgroundColourImageDrawer(playthislevel);
  904. mGameState.PlayingLevel = playthislevel;
  905. mGameState.BackgroundDraw=playthislevel.Background;
  906. //CreateIntroBitmap(playthislevel, out IntroSequenceBitmap, out IntroSequenceGraphic);
  907. playthislevel.CreateIntroBitmap(out IntroSequenceBitmap, out IntroSequenceGraphic);
  908. #endregion
  909. //initialize textanimator.
  910. //IntroAnimator = new TextAnimationManager(playthislevel.LevelName, getLinearCharAnimator,new PointF(AvailableClientArea.Width/2,AvailableClientArea.Height/2 ));
  911. if (playthislevel.NoPaddle)
  912. {
  913. mGameState.PlayerPaddle=null;
  914. }
  915. Dorefreshstats = true;
  916. gamerunstate = new StateLevelIntro();
  917. mScoreatlevelstart = (int)mGameState.GameScore;
  918. mLevelParTime = playthislevel.CalculateParTime();
  919. mLevelIntroStartTime = DateTime.Now;
  920. mLevelTime = new TimeSpan(0);
  921. LevelDeathCount = 0;
  922. mRedrawAnimated=true;
  923. mredrawblocks=true;
  924. //initialize the AnimatedBlocks and StaticBlocks collections, otherwise we still won't
  925. //get them to draw.
  926. staticblocks = (from n in mGameState.Blocks where !n.RequiresPerformFrame() select n).ToList();
  927. AnimatedBlocks = (from n in mGameState.Blocks where n.RequiresPerformFrame() select n).ToList();
  928. if (!ongamethread)
  929. {
  930. Debug.Print("Not on game thread, creating new gamethread...");
  931. GameThread = new Thread(gameproc);
  932. GameThread.Start();
  933. }
  934. else
  935. {
  936. Debug.Print("on game thread, aborting and instantiating anew...");
  937. //I R IDIOT. I was trying to fix another issue and changed this to use "Invoke" rather then BeginInvoke, which of course broke because it has to terminate <this> thread...
  938. this.BeginInvoke((MethodInvoker)(()=>
  939. {
  940. Debug.Print("creating new thread...");
  941. Thread GameThreadx = new Thread(gameproc);
  942. Debug.Print("Starting new thread...");
  943. GameThreadx.Start();
  944. Debug.Print("Aborting old thread...");
  945. GameThread.Abort();
  946. GameThread=GameThreadx;
  947. }));
  948. Debug.Print("new thread is ID " + GameThread.ManagedThreadId);
  949. }
  950. }
  951. void PlayerPaddle_OnEnergyChange(Object sender,PaddleElementChangeEventArgs<float> earg )
  952. {
  953. Dorefreshstats = true;
  954. }
  955. void PlayerPaddle_OnHPChange(Object Sender,PaddleElementChangeEventArgs<float> earg )
  956. {
  957. if (mGameState.PlayerPaddle == null) { earg.Cancel = true; return; } //PlayerPaddle could be destroyed easily by the gameproc thread while the paddle's HP is being reduced.
  958. var lset = mGameState.ClientObject.GetPlayingSet();
  959. if (lset != null)
  960. {
  961. var difference = earg.NewValue - earg.OldValue;
  962. //negative==damage, positive is healing.
  963. if (Math.Sign(difference) == -1)
  964. lset.Statistics.TotalDamage += Math.Abs(difference);
  965. else
  966. lset.Statistics.TotalHealed += Math.Abs(difference);
  967. }
  968. if (mGameState.PlayerPaddle.HP <= 0)
  969. {
  970. ExplodePaddle();
  971. //mGameState.PlayerPaddle = null;
  972. }
  973. Dorefreshstats = true;
  974. }
  975. /// <summary>
  976. /// determines whether the status bitmap needs to be redrawn and then pasted into the backbuffer.
  977. /// </summary>
  978. private bool _Dorefreshstats = true;
  979. public bool Dorefreshstats { get { return _Dorefreshstats; } set { _Dorefreshstats = value; } }
  980. private void PlayLevelMusic(Level playthislevel,bool playintromusic)
  981. {
  982. String playthissound = "";
  983. String usesound;
  984. iSoundSourceObject grabsound;
  985. if(!playintromusic)
  986. usesound = playthislevel.MusicName;
  987. else
  988. {
  989. usesound = playthislevel.IntroMusicName;
  990. }
  991. if (BCBlockGameState.Soundman.HasSound(usesound))
  992. {
  993. playthissound = usesound;
  994. }
  995. else if ((playthissound=BCBlockGameState.Soundman.getRandomSound(usesound)) != "")
  996. {
  997. }
  998. else if (BCBlockGameState.Soundman.HasSound(Path.GetFileNameWithoutExtension(usesound)))
  999. {
  1000. playthissound = Path.GetFileNameWithoutExtension(usesound);
  1001. }
  1002. else if (File.Exists(playthislevel.MusicName))
  1003. {
  1004. playthissound = BCBlockGameState.Soundman.AddSound(usesound);
  1005. }
  1006. if (BCBlockGameState.Soundman.GetPlayingMusic() != null) BCBlockGameState.Soundman.StopMusic();
  1007. var soundresult = BCBlockGameState.Soundman.PlayMusic(playthissound,true);
  1008. if (playintromusic)
  1009. {
  1010. if (playthislevel.ShowNameLength.Ticks == 0)
  1011. {
  1012. /*
  1013. Are you FUCKING KIDDING ME? WHY THE FUCKING HELL IS THIS FUCKING BROKEN? IT WORKED A FUCKIN YEAR AGO...
  1014. * This is a load of god-damned fucking bullshit is what it is. Commented this piece of shit out and now it just sets it to 5 fucking seconds, because FUCK YOU BASS.NET YOU GIGANTIC PILE OF FUCKING GARBAGE.
  1015. *
  1016. */
  1017. playthislevel.ShowNameLength = new TimeSpan(0,0,5);
  1018. //playthislevel.ShowNameLength = BCBlockGameState.TimeSpanFromFloat(soundresult.Source.getLength());
  1019. }
  1020. }
  1021. }
  1022. void Driver_OnSoundStop(iActiveSoundObject objstop)
  1023. {
  1024. playintrodone = true;
  1025. BCBlockGameState.Soundman.Driver.OnSoundStop -= Driver_OnSoundStop;
  1026. }
  1027. private bool playintrodone = false;
  1028. private iActiveSoundObject PlayingIntroSound = null;
  1029. public void StartGame(LevelSet startwith,int startlevel)
  1030. {
  1031. //additions.... accept level argument, or class representing level, etc.
  1032. gamethreadsuspended=false;
  1033. RightClickRestart = false; //Do not restart on right-click
  1034. restartset=null;
  1035. sidebarbgdrawn = false;
  1036. if (GameThread != null && GameThread != Thread.CurrentThread)
  1037. {
  1038. GameThread.Abort();
  1039. }
  1040. if(startwith==null)
  1041. mPlayingSet = CreateDefaultLevelSet();
  1042. else
  1043. mPlayingSet = startwith;
  1044. //mGameState.GameScore = 0;
  1045. mPlayingLevel = startlevel;
  1046. // mGameState = InitGameState(startwith,startlevel);
  1047. mGameState = new BCBlockGameState(this,PicGame,AvailableClientArea);
  1048. BCBlockGameState.MainGameState = mGameState;
  1049. mGameState.OnBallHitBottom += new BCBlockGameState.BallHitBottomProcedure(mGameState_OnBallHitBottom);
  1050. mGameState.LevelComplete += new BCBlockGameState.LevelCompleteProc(mGameState_LevelComplete);
  1051. mGameState.ScoreUpdate += new BCBlockGameState.ScoreUpdateRoutine(mGameState_ScoreUpdate);
  1052. mGameState.NumCompletionsChanged += new Action(mGameState_NumCompletionsChanged);
  1053. cNewSoundManager.Callback = this;
  1054. PlayLevel(mGameState, mPlayingSet.Levels.First());
  1055. //BCBlockGameState.Soundman.PlayMusic("endlesschallenge",1.0f);
  1056. //GameThread = new Thread(gameproc);
  1057. //GameThread.Start();
  1058. }
  1059. void mGameState_NumCompletionsChanged()
  1060. {
  1061. Dorefreshstats = true;
  1062. }
  1063. void mGameState_ScoreUpdate(ref long oldscore, ref long newscore)
  1064. {
  1065. //lblScore.Invoke((MethodInvoker)(()=>lblScore.Text=newscore.ToString()));
  1066. if (DemoMode)
  1067. {
  1068. //ignore all updates to the score.
  1069. newscore=oldscore;
  1070. }
  1071. if (Math.Sign(newscore - oldscore) == 1)
  1072. {
  1073. //positive, so increment add score statistic.
  1074. mGameState.ClientObject.GetPlayingSet().Statistics.TotalScore += (int)(newscore - oldscore);
  1075. }
  1076. else if (Math.Sign(newscore - oldscore) == -1)
  1077. {
  1078. mGameState.ClientObject.GetPlayingSet().Statistics.TotalNegativeScore += (int)Math.Abs(newscore - oldscore);
  1079. }
  1080. Debug.Print("ScoreUpdate: oldscore=" + oldscore + " newscore=" + newscore);
  1081. Dorefreshstats = true;
  1082. }
  1083. public void DelayInvoke(TimeSpan Delaytime, BCBlockGameState.DelayedInvokeRoutine routinefunc, object[] parameters)
  1084. {
  1085. if (mGameState != null)
  1086. {
  1087. mGameState.DelayInvoke(mLevelTime + Delaytime, routinefunc, parameters);
  1088. }
  1089. }
  1090. void mGameState_LevelComplete()
  1091. {
  1092. Debug.Print("Level Complete");
  1093. if(gamerunstate is StateLevelOutroGameOver) return;
  1094. // lblLevel.Invoke((MethodInvoker)(() => lblLevel.Text = currlevel.ToString()));
  1095. // PlayLevel(mGameState, mPlayingSet.Levels[currlevel-1]);
  1096. mPlayingSet.Statistics.LevelsCompleted++;
  1097. tallydata.TallyImage = BCBlockGameState.Imageman.getImageRandom(mPlayingLevelobj.TallyPicKey);
  1098. gamerunstate = new StateLevelOutro();
  1099. }
  1100. void mGameState_OnBallHitBottom(cBall ball)
  1101. {
  1102. mGameState.Balls.Remove(ball);
  1103. balldeath(ball);
  1104. }
  1105. int getNonTempBallCount()
  1106. {
  1107. return (mGameState.Balls.Count((w) => !w.isTempBall));
  1108. }
  1109. void balldeath(cBall balldie)
  1110. {
  1111. // mGameState.removeballs.Add(balldie);
  1112. if ((mGameState.Balls.Count )<= 0)
  1113. {
  1114. Debug.Print("Life Lost");
  1115. LifeLost();
  1116. }
  1117. }
  1118. private DateTime LastDateTime=DateTime.Now;
  1119. private bool AccelerateCountdown = false;
  1120. private void CountDown(ref int sourcevalue, ref int destvalue, int amount)
  1121. {
  1122. //CountDown: removes amount from sourcevalue and adds it to destvalue.
  1123. if (AccelerateCountdown) amount *= 500;
  1124. if (sourcevalue < amount)
  1125. {
  1126. destvalue += sourcevalue;
  1127. sourcevalue = 0;
  1128. }
  1129. else
  1130. {
  1131. destvalue+=amount;
  1132. sourcevalue-=amount;
  1133. }
  1134. }
  1135. public int GetTimeBonus(TimeSpan LevelTime, TimeSpan ParTime)
  1136. {
  1137. int buildresult = ((int)((ParTime - LevelTime).TotalSeconds)) * (5 * mPlayingLevel);
  1138. int testvalue = (int)Math.Floor(LevelTime.TotalHours*100);
  1139. if (CPrimes.IsPrime(testvalue))
  1140. {
  1141. buildresult += LevelTime.Seconds*25;
  1142. }
  1143. return buildresult;
  1144. }
  1145. //currently unused...
  1146. //private static GameRunStateConstants[] LoopingStates = new GameRunStateConstants[] { GameRunStateConstants.Game_Menu, GameRunStateConstants.Game_Paused, GameRunStateConstants.Game_ValueInput };
  1147. public TimeSpan Deathtime = new TimeSpan(0,0,0,2);
  1148. public TextAnimationManager IntroAnimator;
  1149. private bool CancelGameThread = false;
  1150. private bool RightClickRestart = false; //true to allow rightclick to restart game. false otherwise.
  1151. //more a special-case variable used for the gameover screen.
  1152. public TimeSpan GetLevelTime()
  1153. {
  1154. return mLevelTime;
  1155. }
  1156. public void gameproc()
  1157. {
  1158. const int framedelay = 0;
  1159. List<cBall> ballsadded = new List<cBall>();
  1160. Debug.Print("gameproc entered.");
  1161. CancelGameThread = false;
  1162. while (!CancelGameThread)
  1163. {
  1164. //PaintSideBarstats();
  1165. mGameState.HandleDelayInvoke(mLevelTime);
  1166. mGameState.ProcessMessages();
  1167. while (gamethreadsuspended)
  1168. {
  1169. Application.DoEvents();
  1170. Thread.Sleep(100);
  1171. }
  1172. List<BCBlockGameState.NextFrameStartup> reenqueue = new List<BCBlockGameState.NextFrameStartup>();
  1173. bool noerrorloop = false;
  1174. while (!noerrorloop)
  1175. {
  1176. try
  1177. {
  1178. while (mGameState.NextFrameCalls.Any())
  1179. {
  1180. //dequeue next item and call it's function
  1181. var deqobj = mGameState.NextFrameCalls.Dequeue();
  1182. if(deqobj!=null) //pranksters!
  1183. if (deqobj.NextFrame(deqobj, mGameState))
  1184. reenqueue.Add(deqobj);
  1185. }
  1186. noerrorloop = true;
  1187. }
  1188. catch (InvalidOperationException exx)
  1189. {
  1190. noerrorloop = false;
  1191. }
  1192. }
  1193. foreach (BCBlockGameState.NextFrameStartup readd in reenqueue)
  1194. {
  1195. mGameState.NextFrameCalls.Enqueue(readd);
  1196. }
  1197. while (gamepauseamount > 0)
  1198. {
  1199. gamepauseamount--;
  1200. Application.DoEvents();
  1201. }
  1202. try
  1203. {
  1204. if (gamerunstate is StateDeath)
  1205. {
  1206. //has the time expired? if so call the post-death routine...
  1207. if (DateTime.Now - DeathStart > Deathtime)
  1208. PostLifeLost();
  1209. }
  1210. while (gamerunstate.IsLoopingState)
  1211. {
  1212. while (gamerunstate is StateMenu)
  1213. {
  1214. Application.DoEvents();
  1215. Thread.Sleep(5);
  1216. PicGame.Invoke((MethodInvoker) (() =>
  1217. {
  1218. PicGame.Invalidate();
  1219. PicGame.Update();
  1220. }))
  1221. ;
  1222. }
  1223. while (gamerunstate is StatePaused)
  1224. {
  1225. Thread.Sleep(100);
  1226. Application.DoEvents();
  1227. PicGame.Invoke((MethodInvoker)(() =>
  1228. {
  1229. PicGame.Invalidate();
  1230. PicGame.Update();
  1231. }))
  1232. ;
  1233. }
  1234. #region Cheat Input
  1235. while (gamerunstate is StateValueInput)
  1236. {
  1237. var result = gamerunstate.Run(mGameState);
  1238. if (result != null) gamerunstate = result;
  1239. }
  1240. //debugging code. Seems the Game_Menu setting doesn't play friendly with the other stuff. TSSK TSSK.
  1241. if (gamerunstate is StateMenu)
  1242. {
  1243. Debug.Print("Menu");
  1244. }
  1245. #endregion
  1246. }
  1247. //const int levelintroticks=500;
  1248. int elapsedintroticks = 0;
  1249. int elapsedoutroticks = 0;
  1250. DateTime startlevelintroloop = DateTime.Now;
  1251. bool foundanimated = false;
  1252. #region LevelIntro
  1253. while (gamerunstate is StateLevelIntro)
  1254. {
  1255. //TODO: there is a bug somewhere; AnimatedBlocks are not drawn properly during the intro sequence. (usually, they show up as normal blocks instead for some reason).
  1256. //addendum to the above: now they no longer draw at all during the intro sequence.
  1257. //do nothing but "wait" for a specific period.
  1258. //elapsedintroticks++;
  1259. //Debug.Print("elapsedintroticks:" + elapsedintroticks.ToString() + "gamerunstate:" + gamerunstate.ToString());
  1260. //tweak: if shownamelength is negative, then when we had played the music using PlayLevelMusic the routine
  1261. //will have hooked the sound stop event; we use that to determine when to end, since it also sets a flag.
  1262. if(((DateTime.Now-startlevelintroloop)>mPlayingSet.Levels[mPlayingLevel-1].ShowNameLength)
  1263. || (mPlayingSet.Levels[mPlayingLevel - 1].ShowNameLength.Ticks == 0 && playintrodone))
  1264. {
  1265. elapsedintroticks = 0;
  1266. //play the Level Music.
  1267. mLevelTime=new TimeSpan(0);
  1268. LastDateTime = DateTime.Now;
  1269. PlayLevelMusic(mPlayingSet.Levels[mPlayingLevel - 1], false);
  1270. gamerunstate = new StateRunning();
  1271. }
  1272. foreach (Block LoopBlock in mGameState.Blocks)
  1273. {
  1274. if (LoopBlock is AnimatedBlock)
  1275. {
  1276. foundanimated = true;
  1277. if ((LoopBlock).PerformFrame(mGameState)) mredrawblocks = true;
  1278. }
  1279. }
  1280. // IntroAnimator.PerformFrame();
  1281. PicGame.Invoke((MethodInvoker)(() =>
  1282. {
  1283. //if(mredrawblocks)
  1284. PicGame.Invalidate();
  1285. PicGame.Update();
  1286. }));
  1287. mredrawblocks=false;
  1288. }
  1289. #endregion
  1290. //int elapsedoutroticks = 0;
  1291. //otherwise we are in the gameover or level outtro...
  1292. #region Leveloutro and outro gameover
  1293. DateTime startleveloutroloop = DateTime.Now;
  1294. int Countdownlevelscore=(int)mGameState.GameScore-mScoreatlevelstart;
  1295. //the level score counts down, and is added to our initial level score (mScoreAtlevelstart)
  1296. int Addupgamescore=mScoreatlevelstart;
  1297. //game score that goes from scoreatlevelstart to CountDownlevelscore
  1298. //int countdownbonusscore=250*(mPlayingLevel+1);
  1299. int countdownbonusscore = GetTimeBonus(mLevelTime, mLevelParTime);
  1300. //also, bonus for each ball in play. (why the heck not...)
  1301. countdownbonusscore += (mGameState.Balls.Count * 50);
  1302. //and add some score for macguffins
  1303. //1 + (x/500)
  1304. countdownbonusscore += (int)((countdownbonusscore * (1 + ((float)mGameState.MacGuffins / 500))));
  1305. countdownbonusscore = (int)(countdownbonusscore * mGameState.ScoreMultiplier);
  1306. //string tallykey = BCBlockGameState.Soundman.getRandomSound("TALLYTICK");
  1307. String tallykey="";
  1308. lock (mPlayingSet)
  1309. {
  1310. if (!(mPlayingLevel - 1 > mPlayingSet.Levels.Count))
  1311. tallykey = mPlayingSet.Levels[0].TallyTickSound;
  1312. else
  1313. tallykey = mPlayingSet.Levels[mPlayingLevel - 1].TallyTickSound;
  1314. }
  1315. int totalbonus = countdownbonusscore;
  1316. TimeSpan aSecond=new TimeSpan(0,0,0,2);
  1317. //bonus score is added after.
  1318. String writeString="";
  1319. bool playingrollsound = false;
  1320. bool tallyfinished=false;
  1321. int scoredecrement;
  1322. scoredecrement = Countdownlevelscore / 100;
  1323. if (scoredecrement == 0) scoredecrement = 1;
  1324. DateTime finishtallytime = DateTime.Now.AddDays(1);
  1325. bool doGameOver = gamerunstate is StateLevelOutroGameOver;
  1326. if (doGameOver)
  1327. countdownbonusscore = (int)(Countdownlevelscore * -0.4);
  1328. while (gamerunstate is StateLevelOutro || gamerunstate is StateLevelOutroGameOver)
  1329. {
  1330. //note: we wait a full second before we start the "counting"...
  1331. if (!playingrollsound)
  1332. {
  1333. if (doGameOver)
  1334. {
  1335. //bugfix: when we get here, turns out the GameOver LevelSet had already been initialized. Or something.
  1336. BCBlockGameState.Soundman.PlayMusic(mPlayingSet.Levels[0].GameOverMusic,1.0f,false);
  1337. }
  1338. else
  1339. //musicobj = BCBlockGameState.Soundman.PlayMusic("TALLY", 1.0f, false);
  1340. BCBlockGameState.Soundman.PlayMusic(mPlayingSet.Levels[mPlayingLevel - 1].TallyMusicName, 1.0f, false);
  1341. }
  1342. playingrollsound = true;
  1343. if((DateTime.Now - startleveloutroloop) > (aSecond))
  1344. {
  1345. //ok, good. perform a single "frame" of countdown.
  1346. //if our levelcountdown is non-zero, take some off of it, and add it to countdowngamescore.
  1347. if(Countdownlevelscore>0)
  1348. {
  1349. CountDown(ref Countdownlevelscore,ref Addupgamescore,scoredecrement);
  1350. BCBlockGameState.Soundman.PlaySound(tallykey, 0.9f);
  1351. }
  1352. else if(countdownbonusscore!=0)
  1353. {
  1354. CountDown(ref countdownbonusscore,ref Addupgamescore,Math.Sign(countdownbonusscore)*50);
  1355. BCBlockGameState.Soundman.PlaySound(tallykey, 0.9f);
  1356. }
  1357. else if(!tallyfinished)
  1358. {
  1359. finishtallytime=DateTime.Now;
  1360. tallyfinished=true;
  1361. }
  1362. }
  1363. if((DateTime.Now-finishtallytime)>=(aSecond+aSecond))
  1364. {
  1365. if (doGameOver)
  1366. {
  1367. }
  1368. else
  1369. {
  1370. mGameState.GameScore += totalbonus;
  1371. BlockDrawBuffer.Clear(Color.Transparent);
  1372. int gotnext = mPlayingSet.Levels[mPlayingLevel - 1].NextLevel;
  1373. int currlevel;
  1374. if(gotnext==0)
  1375. currlevel= mPlayingLevel + 1;
  1376. else
  1377. currlevel=gotnext;
  1378. if (currlevel > mPlayingSet.Levels.Count())
  1379. {
  1380. //MessageBox.Show("You have defeated all levels...");
  1381. //a "completion" occurs when any level is finished that tries to go to a level higher then the number of levels.
  1382. mGameState.NumCompletions++;
  1383. sidebarbgdrawn = false;
  1384. gamerunstate= new StateRunning();
  1385. currlevel = 1;
  1386. }
  1387. //currlevel = 1;
  1388. mPlayingLevel = currlevel;
  1389. long usescore = mGameState.GameScore;
  1390. mGameState.invokescoreupdate(ref usescore,ref usescore);
  1391. PlayLevel(mGameState, mPlayingSet.Levels[mPlayingLevel-1]);
  1392. }
  1393. }
  1394. if (doGameOver)
  1395. {
  1396. if (KeyboardInfo.IsPressed(Keys.LButton))
  1397. {
  1398. lastscoreshow = DateTime.Now - new TimeSpan(0, 0, 0, 0, ScoreRevealDelayTime+1);
  1399. }
  1400. //the game over screen will also show the high scores of that set.
  1401. //it does this on it's own, but we need to initialize the string...
  1402. //if the time has elapsed..
  1403. if ((DateTime.Now - lastscoreshow).TotalMilliseconds > ScoreRevealDelayTime)
  1404. {
  1405. //add the next score entry to the string...
  1406. if (Nextshowhiscore <= 9)
  1407. {
  1408. var nextentry = ActualPlaySet.HighScores.Scores.ElementAt(ActualPlaySet.HighScores.Scores.Count- Nextshowhiscore-1).Value;
  1409. int useseparators = HighScoresMaxSeparators - nextentry.Name.Length;
  1410. String usespaces = (Nextshowhiscore+1==HighScorePos)?"**":" ";
  1411. String usename = nextentry.Name;
  1412. if (usename.Length > 22) usename = usename.Substring(0, 20) + ">>";
  1413. String nextshow = String.Format("{0:00}",Nextshowhiscore+1) + ":" + usespaces + usename + Repeat(".",useseparators+4) + nextentry.Score;
  1414. GameOverHiScores += "\n" + nextshow;
  1415. BCBlockGameState.Soundman.PlaySound("revel");
  1416. //GameOverHiScores
  1417. lastscoreshow = DateTime.Now;
  1418. Nextshowhiscore++;
  1419. }
  1420. else if (Nextshowhiscore == 10)
  1421. {
  1422. //show a blank...
  1423. GameOverHiScores += "\n" + Repeat(".", HighScoresMaxSeparators+1);
  1424. BCBlockGameState.Soundman.PlaySound("revel");
  1425. lastscoreshow = DateTime.Now;
  1426. Nextshowhiscore++;
  1427. }
  1428. else if (Nextshowhiscore == 11)
  1429. {
  1430. GameOverHiScores += "\nPress Button B";
  1431. BCBlockGameState.Soundman.PlaySound("revel");
  1432. lastscoreshow = DateTime.Now;
  1433. Nextshowhiscore++;
  1434. }
  1435. else if (Nextshowhiscore == 12)
  1436. {
  1437. GameOverHiScores += "\nTo Play Again.";
  1438. BCBlockGameState.Soundman.PlaySound("revel");
  1439. CancelGameThread = true;
  1440. RightClickRestart = true;
  1441. //Special code:
  1442. //we want to STOP the gameproc, since it's job is essential done at this point.
  1443. BeginInvoke((MethodInvoker)(() => { PicGame.Invalidate(); PicGame.Update(); GameThread.Abort(); }));
  1444. Nextshowhiscore++;
  1445. }
  1446. }
  1447. //Yield.
  1448. Thread.Sleep(10);
  1449. writeString = " GAME OVER \n";
  1450. writeString += "LEVEL: " + mPlayingLevel.ToString() + "\n" +
  1451. "SCORE: " + mGameState.GameScore.ToString();
  1452. }
  1453. else
  1454. {
  1455. writeString = mGameState.PlayingLevel.ClearTitle;
  1456. writeString += "LEVEL: " + Countdownlevelscore.ToString() + "\n" +
  1457. "TIME: " + FormatLevelTime(mLevelTime) + "\n" +
  1458. "PAR TIME: " + FormatLevelTime(mLevelParTime) + "\n" +
  1459. "BONUS: " + countdownbonusscore + "\n" +
  1460. "TOTAL: " + Addupgamescore + "\n";
  1461. }
  1462. tallydata.TallyScreenString=writeString;
  1463. //Debug.Print("elapsedintroticks:" + elapsedintroticks.ToString() + "gamerunstate:" + gamerunstate.ToString());
  1464. AnimateParticles();
  1465. RefreshFrames();
  1466. }
  1467. #endregion
  1468. //Thread.Sleep(framedelay);
  1469. //while ((DateTime.Now - LastDateTime).Milliseconds < 3)
  1470. //{
  1471. //}
  1472. Thread.Sleep(0);
  1473. bool blocksaffected = false;
  1474. List<Block> blocksfromperformframe;
  1475. //go through all balls...
  1476. if (mGameState.Balls != null)
  1477. {
  1478. //purge balls beyond our limit.
  1479. if (mPlayingLevelobj.MaxBalls > 0 && mGameState.Balls.Count() > mPlayingLevelobj.MaxBalls)
  1480. {
  1481. while (mGameState.Balls.Count() > mPlayingLevelobj.MaxBalls)
  1482. mGameState.Balls.RemoveLast();
  1483. }
  1484. cBall continueball = null;
  1485. cBall lastball = null;
  1486. ballsadded.Clear();
  1487. restartloop:
  1488. try
  1489. {
  1490. //initially start with the assumption that no blocks will need to be redrawn.
  1491. if (mGameState.Balls.Count == 0)
  1492. {
  1493. LifeLost();
  1494. }
  1495. mredrawblocks = false;
  1496. //foreach (cBall loopball in mGameState.Balls)
  1497. // for(LinkedListNode<cBall> loopballnode = mGameState.Balls.First;
  1498. // loopballnode!=null;loopballnode=loopballnode.Next)
  1499. // for(LinkedListNode<cBall> loopballnode = mGameState.Balls.Last;
  1500. // loopballnode!=null;loopballnode=loopballnode.Previous)
  1501. cBall lowestBall=null;
  1502. //naturally, we iterate through every ball.
  1503. //testing: now clones the gamestate balls list...
  1504. if (mGameState.ShootBalls.Count > 0)
  1505. {
  1506. lock (mGameState.Balls)
  1507. {
  1508. mGameState.Balls.AddRangeAfter(mGameState.ShootBalls);
  1509. }
  1510. mGameState.ShootBalls.Clear();
  1511. }
  1512. LinkedList<cBall> cloneballs = mGameState.Balls;
  1513. lock (mGameState.Balls)
  1514. {
  1515. //cloneballs = new LinkedList<cBall>(mGameState.Balls);
  1516. foreach (cBall loopball in mGameState.Balls)
  1517. {
  1518. //cBall loopball = loopballnode.Value;
  1519. if (loopball != null)
  1520. {
  1521. //cBall loopball = mGameState.Balls[i];
  1522. if (lowestBall == null || loopball.Location.Y > lowestBall.Location.Y)
  1523. {
  1524. if ((Math.Sign(loopball.Velocity.Y)) > 0)
  1525. lowestBall = loopball;
  1526. //used by demo mode (and possibly later by other stuff) stores the lowest ball that is coming towards the paddle. (well, actually, it's the lowest ball that
  1527. //is going downwards.
  1528. }
  1529. if (continueball == null || continueball == loopball)
  1530. {
  1531. continueball = null;
  1532. //make sure the ball is set to call us back if an impact occurs.
  1533. if (!loopball.hasBallImpact())
  1534. loopball.BallImpact += loopball_BallImpact;
  1535. List<cBall> ballsremove = new List<cBall>();
  1536. //Hey ball, can you move a single frame and give us back some info on the blocks
  1537. //that you affected? thanks.
  1538. blocksfromperformframe = loopball.PerformFrame(mGameState, ref ballsadded,
  1539. ref ballsremove);
  1540. //Blocksfromperformframe is now a collection of Blocks that were affected by this frame.
  1541. foreach (cBall loopremball in ballsremove)
  1542. {
  1543. // mGameState.Balls.Remove(loopremball);
  1544. //kill each ball in the removing collection.
  1545. balldeath(loopremball);
  1546. }
  1547. //mredrawblocks = mredrawblocks || (blocksfromperformframe.Count() > 0);
  1548. mredrawblocks = mredrawblocks ||
  1549. (blocksfromperformframe.Any((w) => !(w.RequiresPerformFrame())));
  1550. mRedrawAnimated = mredrawblocks ||
  1551. (blocksfromperformframe.Any((w) => (w.RequiresPerformFrame())));
  1552. //mredrawblocks=true;
  1553. }
  1554. lastball = loopball;
  1555. }
  1556. }
  1557. }
  1558. Func<Block, bool> checkfrozen= ((a) => {
  1559. if (a is AnimatedBlock)
  1560. if (((AnimatedBlock)a).Frozen)
  1561. return true; //it's frozen.
  1562. return false;
  1563. });
  1564. //now, use LINQ to grab all Animated blocks Blocks that require animation.
  1565. #region block animation
  1566. var result = from x in mGameState.Blocks where x.RequiresPerformFrame() select x;
  1567. AnimatedBlocks = result.ToList();
  1568. staticblocks =(from x in mGameState.Blocks where !x.RequiresPerformFrame() select x).ToList();
  1569. foreach (Block loopblock in result)
  1570. {
  1571. /*if (loopblock is DemonBlock)
  1572. {
  1573. Debug.Print("break");
  1574. }*/
  1575. //FIX: changed order so that performframe is called regardless.
  1576. bool hc=false;
  1577. hc = loopblock.PerformFrame(mGameState) || loopblock.hasChanged;
  1578. if(hc) mRedrawAnimated=true;
  1579. }
  1580. #endregion
  1581. //combo check.
  1582. if (mGameState.ComboCount > 1 && mGameState.ComboFinishTime!=null)
  1583. {
  1584. Font fontuse = new Font("Arial", 28);
  1585. //mGameState.ComboCountDown--;
  1586. //Debug.Print("ComboCountdown:" + mGameState.ComboCountDown);
  1587. int clamped = BCBlockGameState.ClampValue(mGameState.ComboCount-1, 0, BCBlockGameState.ComboNames.Length - 1);
  1588. if (mGameState.ComboFinishTime.Value < DateTime.Now)
  1589. {
  1590. mGameState.ComboFinishTime = null;
  1591. string endquote = " chained)";
  1592. if((mGameState.ComboCount - 1)==1) endquote = " chain)";
  1593. string combotext = BCBlockGameState.ComboNames[clamped] + " \nCombo!" + "(" + (mGameState.ComboCount - 1) + endquote;
  1594. SizeF calcsize = BCBlockGameState.MeasureString(combotext, fontuse);
  1595. PointF initialpos = new PointF(mGameState.GameArea.Width / 2,
  1596. mGameState.GameArea.Height);
  1597. Brush drawbrush = new SolidBrush(BCBlockGameState.ComboFillColour[clamped]);
  1598. Pen drawpen = new Pen(BCBlockGameState.ComboPenColour[clamped]);
  1599. Block.PopupText(mGameState, combotext, fontuse, drawbrush, drawpen, 500, new PointF(0, -1.05f), initialpos);
  1600. BCBlockGameState.Soundman.PlaySound(BCBlockGameState.ComboNames[clamped],2.0f);
  1601. mGameState.ComboCount = 0;
  1602. }
  1603. }
  1604. Block.HandleEffects(mGameState);
  1605. #region particle animation
  1606. AnimateParticles();
  1607. #endregion
  1608. //Changeup: now inspect to see if we need to add a message.
  1609. //the latest message will be
  1610. //mPlayingLevelobj.MessageQueue.Peek()
  1611. //grab topmost...
  1612. if (LevelMessageQueue!=null && LevelMessageQueue.Count>0)
  1613. {
  1614. var topmostmessage = LevelMessageQueue.Peek();
  1615. if (topmostmessage.TotalMS < (mLevelTime).TotalMilliseconds)
  1616. {
  1617. LevelMessageQueue.Dequeue();
  1618. topmostmessage.Invoke(mGameState);
  1619. //enqueue a new item, add the length of the playing music to the timeindex...
  1620. float accumlength = BCBlockGameState.Soundman.GetPlayingMusic().getLength();
  1621. accumlength += topmostmessage.TimeIndex;
  1622. //create a new Message...
  1623. var clonedmess = (PlayMessageData)topmostmessage.Clone();
  1624. clonedmess.TimeIndex = accumlength;
  1625. LevelMessageQueue.Enqueue(clonedmess);
  1626. }
  1627. }
  1628. AnimateGameObjects();
  1629. if (DemoMode)
  1630. {
  1631. //reposition the paddle to be in the path of the lowest ball. we cached that earlier.
  1632. if (lowestBall != null)
  1633. {
  1634. if(mGameState.PlayerPaddle!=null)
  1635. mGameState.PlayerPaddle.Position = new PointF(lowestBall.Location.X,
  1636. mGameState.PlayerPaddle.Position.Y);
  1637. }
  1638. }
  1639. int gotcount = mGameState.Blocks.Count((w) => (w.MustDestroy() == true));
  1640. if (gotcount == 0)
  1641. {
  1642. //LifeLost();
  1643. mGameState.invokeLevelComplete();
  1644. }
  1645. }
  1646. catch (Exception e)
  1647. {
  1648. Trace.WriteLine("Exception in loop :(" + e.Message + " Stack:{" + e.StackTrace + "}");
  1649. continueball = lastball;
  1650. //goto restartloop;
  1651. }
  1652. foreach (cBall addthis in ballsadded)
  1653. {
  1654. mGameState.Balls.AddLast(addthis);
  1655. }
  1656. foreach (cBall removethis in mGameState.RemoveBalls)
  1657. {
  1658. mGameState.Balls.Remove(removethis);
  1659. }
  1660. mGameState.RemoveBalls.Clear();
  1661. try
  1662. {
  1663. // mredrawblocks = mredrawblocks || mGameState.Blocks.Any((w) => (w.hasChanged&&((w is AnimatedBlock))));
  1664. PicGame.Invalidate();
  1665. PicGame.Invoke((MethodInvoker)(() => { PicGame.Invalidate(); PicGame.Update(); }));
  1666. //Application.DoEvents();
  1667. }
  1668. catch
  1669. {
  1670. }
  1671. }
  1672. }
  1673. catch (ThreadAbortException e)
  1674. {
  1675. Debug.Print("GameProc thread aborted");
  1676. }
  1677. if (mGameState.Blocks.Count == 0)
  1678. {
  1679. mGameState.invokeLevelComplete();
  1680. }
  1681. if ((gamerunstate is StateRunning) && (LastDateTime.Ticks > 0))
  1682. {
  1683. if (TotalPauseTime != null)
  1684. {
  1685. //totalpausetime is initialized when the game is unpaused, and will contain the total time the game was paused.
  1686. //don't add anything to the leveltime, and reinitialize LastDateTime.
  1687. TotalPauseTime=null;
  1688. }
  1689. else
  1690. {
  1691. mLevelTime += (DateTime.Now - LastDateTime);
  1692. }
  1693. }
  1694. LastDateTime = DateTime.Now;
  1695. }
  1696. }
  1697. private void RefreshFrames()
  1698. {
  1699. PicGame.Invoke((MethodInvoker)(() =>
  1700. {
  1701. PicGame.Invalidate();
  1702. PicGame.Update();
  1703. }));
  1704. }
  1705. private String FormatLevelTime(TimeSpan LevelTime)
  1706. {
  1707. if(LevelTime.Hours >0)
  1708. return new DateTime(LevelTime.Ticks).ToString("hh:mm:ss.ff");
  1709. else
  1710. return new DateTime(LevelTime.Ticks).ToString("mm:ss.ff");
  1711. }
  1712. private void AnimateGameObjects()
  1713. {
  1714. List<GameObject> lAddObjects = new List<GameObject>();
  1715. List<GameObject> lremoveObjects = new List<GameObject>();
  1716. //bugfix: seems that issues will be abound if collections are modified during the loop (duh).
  1717. //but mostly because execution leaves this procedure entirely, leaving the gameobjects to add and gameobjects to remove collections untransferred.
  1718. GameObject lastinstance = null;
  1719. try
  1720. {
  1721. lock (mGameState.GameObjects)
  1722. {
  1723. foreach (GameObject loopgobject in mGameState.GameObjects)
  1724. {
  1725. if (loopgobject.Frozen) continue; //frozen objects can't move...
  1726. lastinstance = loopgobject;
  1727. if (loopgobject is SpinShot)
  1728. {
  1729. Debug.Print("test");
  1730. }
  1731. if (loopgobject.PerformFrame(mGameState))
  1732. {
  1733. lremoveObjects.Add(loopgobject);
  1734. }
  1735. }
  1736. if (mGameState.Forcerefresh)
  1737. {
  1738. mredrawblocks = true;
  1739. mGameState.Forcerefresh = false;
  1740. }
  1741. }
  1742. }
  1743. catch (InvalidOperationException eex)
  1744. {
  1745. //unused catch handler.
  1746. Debug.Print("InvalidOperationException Caught in AnimateGameObjects-" + eex.ToString());
  1747. }
  1748. //add the added objects...
  1749. lock (mGameState.GameObjects)
  1750. {
  1751. foreach (GameObject addthisobject in lAddObjects)
  1752. mGameState.GameObjects.AddLast(addthisobject);
  1753. foreach (GameObject removethisobject in lremoveObjects)
  1754. {
  1755. if (removethisobject is GameEnemy)
  1756. {
  1757. GameEnemy caste = removethisobject as GameEnemy;
  1758. List<GameObject> addtemp= new List<GameObject>();
  1759. List<GameObject> removetemp = new List<GameObject>();
  1760. caste.InvokeOnDeath(mGameState, ref addtemp, ref removetemp);
  1761. }
  1762. mGameState.GameObjects.Remove(removethisobject);
  1763. }
  1764. }
  1765. }
  1766. private int particlelimit = Int32.Parse(BCBlockGameState.GameSettings["game"]["maxparticles","1500"].Value);
  1767. private List<Particle> mremoveparticles = new List<Particle>();
  1768. private void AnimateParticles()
  1769. {
  1770. mremoveparticles.Clear();
  1771. lock (mGameState.Particles)
  1772. {
  1773. /*
  1774. if (mGameState.Particles.Count > particlelimit)
  1775. {
  1776. //if above the particle limit, remove the "oldest" ones. This is more a guess then anything, we just remove the ones at the start until we are below the limit.
  1777. int numremove = particlelimit - mGameState.Particles.Count;
  1778. if (numremove > 0) mGameState.Particles.RemoveRange(0, numremove); //tada...
  1779. }
  1780. */
  1781. int totalparticles = mGameState.Particles.Count((w)=>!w.Important);
  1782. foreach (Particle loopparticle in mGameState.Particles)
  1783. {
  1784. if(loopparticle!=null)
  1785. if (loopparticle.PerformFrame(mGameState) || totalparticles > MaxParticles)
  1786. {
  1787. mremoveparticles.Add(loopparticle);
  1788. totalparticles--;
  1789. }
  1790. }
  1791. foreach (Particle removeparticle in mremoveparticles)
  1792. mGameState.Particles.Remove(removeparticle);
  1793. }
  1794. }
  1795. public String Repeat(String repeatthis, int count)
  1796. {
  1797. count = Math.Abs(count);
  1798. if (String.IsNullOrEmpty(repeatthis)) return "";
  1799. StringBuilder buildresult = new StringBuilder(repeatthis.Length * count);
  1800. for (int i = 0; i < count; i++)
  1801. {
  1802. buildresult.Append(repeatthis);
  1803. }
  1804. return buildresult.ToString();
  1805. }
  1806. void loopball_BallImpact(cBall ballimpact)
  1807. {
  1808. if ((ballimpact.numImpacts> 0) && ballimpact.isTempBall)
  1809. {
  1810. if (mGameState.Balls.Count() == 1 && mGameState.Balls.Contains(ballimpact))
  1811. {
  1812. //we are the last ball, promote to a true ball.
  1813. ballimpact.isTempBall= false;
  1814. }
  1815. try
  1816. {
  1817. // mGameState.Balls.Remove(ballimpact);
  1818. mGameState.RemoveBalls.Add(ballimpact);
  1819. }
  1820. catch
  1821. {
  1822. }
  1823. }
  1824. //throw new NotImplementedException();
  1825. }
  1826. public frmBaseBlock()
  1827. {
  1828. InitializeComponent();
  1829. }
  1830. const int WM_DWMCOMPOSITIONCHANGED = 0x031E;
  1831. protected override void WndProc(ref Message m)
  1832. {
  1833. if (m.Msg == WM_DWMCOMPOSITIONCHANGED)
  1834. {
  1835. //set the paint handler based on the current Composition state.
  1836. setPaintHandler();
  1837. }
  1838. base.WndProc(ref m);
  1839. }
  1840. GameControllerManager gcm = null;
  1841. private void frmPoing_Load(object sender, EventArgs e)
  1842. {
  1843. setPaintHandler();
  1844. SidebarImage = BCBlockGameState.Imageman.getLoadedImage("sidebarbg");
  1845. ButtonDown += frmBaseBlock_ButtonDown;
  1846. ButtonUp += frmBaseBlock_ButtonUp;
  1847. ClientSize = new Size(704, 427+menuStrip1.Height+6);
  1848. StandardSize = new Rectangle(0,0,ClientSize.Width,ClientSize.Height);
  1849. PicGame.Location = new Point(0, menuStrip1.Bottom);
  1850. ClientSize = new Size(PicGame.Size.Width,PicGame.Size.Height+menuStrip1.Height);
  1851. //background is the full size of picgame, so that it can hold the sidebar bmp.
  1852. BackBufferBitmap = new Bitmap(PicGame.Width, PicGame.Height);
  1853. backgroundbitmap = new Bitmap(PicGame.Width, PicGame.Height, PixelFormat.Format32bppArgb);
  1854. BlockDrawBitmap = new Bitmap(AvailableClientArea.Width, AvailableClientArea.Height,PixelFormat.Format32bppArgb);
  1855. MovingBlockBitmap = new Bitmap(AvailableClientArea.Width, AvailableClientArea.Height, PixelFormat.Format32bppArgb);
  1856. backBufferCanvas = Graphics.FromImage(BackBufferBitmap);
  1857. BackgroundBuffer = Graphics.FromImage(backgroundbitmap);
  1858. BlockDrawBuffer = Graphics.FromImage(BlockDrawBitmap);
  1859. MovingBlockBuffer = Graphics.FromImage(MovingBlockBitmap);
  1860. backBufferCanvas.PixelOffsetMode = PixelOffsetMode.HighSpeed;
  1861. backBufferCanvas.CompositingQuality = CompositingQuality.HighSpeed;
  1862. BackgroundBuffer.CompositingQuality = CompositingQuality.HighSpeed;
  1863. BlockDrawBuffer.CompositingQuality = CompositingQuality.AssumeLinear;
  1864. MovingBlockBuffer.CompositingQuality = CompositingQuality.HighSpeed;
  1865. //System.Collections.Generic.L
  1866. SidebarBitmap = new Bitmap(SidebarImage);
  1867. //MessageBox.Show(SidebarBitmap.Size.ToString());
  1868. sidebarGraphics = Graphics.FromImage(SidebarBitmap);
  1869. BackgroundBuffer.Clear(Color.Transparent);
  1870. BlockDrawBuffer.Clear(Color.Transparent);
  1871. BCBlockGameState.setMenuRenderer(BCBlockGameState.GameSettings);
  1872. //initialize Game Controller Manager.
  1873. gcm = new GameControllerManager(BCBlockGameState.MTypeManager[typeof(iGameInput)].ManagedTypes,this);
  1874. DoAutoLoad(Environment.CommandLine);
  1875. }
  1876. void ResizeForm()
  1877. {
  1878. Rectangle WorkingArea = Screen.FromHandle(this.Handle).WorkingArea;
  1879. Size WorkSize = WorkingArea.Size;
  1880. int i = 1;
  1881. Size useSize = Size;
  1882. while(true)
  1883. {
  1884. Size testsize = new Size(Width*i,Height*i);
  1885. //if the testing size is too big, break.
  1886. if (testsize.Width > WorkSize.Width || testsize.Height > WorkSize.Height) break;
  1887. useSize = testsize;
  1888. i++;
  1889. }
  1890. Size = useSize;
  1891. }
  1892. void frmBaseBlock_ButtonUp(object sender, ButtonEventArgs<bool> e)
  1893. {
  1894. //x |= Time.Past;
  1895. currentlypressed &= ~e.Button;
  1896. }
  1897. void frmBaseBlock_ButtonDown(object sender, ButtonEventArgs<bool> e)
  1898. {
  1899. currentlypressed |= e.Button;
  1900. }
  1901. private Graphics SideBarImageCanvas;
  1902. private Bitmap SideBarImageBitmap;
  1903. // private void PaintSideBar(Graphics g)
  1904. // {
  1905. // }
  1906. private void PaintSideBarstats()
  1907. {
  1908. //TODO: current implementation is somewhat less than optimal.
  1909. //sidebar is painted every frame. ideally, we would only paint a new sidebar image to the backbuffer when necessary, and any other frame would be restricted to only
  1910. //painting within the client area via clipping.
  1911. //rects defined on the sidebar
  1912. //Level name/title rect:
  1913. //(13,12)-(197,57)
  1914. //score/lives etc rect:
  1915. // (13,80)-(197,243)
  1916. //(13,390)-(197,415) //extra info rect (url probably, or copyright, etc.)
  1917. //PaintSideBar(g);
  1918. //task, if necessary, redraw the sidebar.
  1919. //if (!sidebarbgdrawn)
  1920. //{
  1921. //if no sidebar image or canvas is defined, create it.
  1922. //the idea is, the sidebar stuff is stored in it's own "bitmap" which is refreshed when necessary, but otherwise we simply Draw that
  1923. //sidebar image verbatim.
  1924. //SideBarImage is the actual "image"...
  1925. if (SideBarImageCanvas == null)
  1926. {
  1927. SideBarImageBitmap = new Bitmap(BackBufferBitmap.Width-AvailableClientArea.Width,BackBufferBitmap.Height);
  1928. SideBarImageCanvas = Graphics.FromImage(SideBarImageBitmap);
  1929. }
  1930. SideBarImageCanvas.Clear(Color.Transparent);
  1931. // if (!sidebarbgdrawn)
  1932. // {
  1933. //BackgroundBuffer.DrawImageUnscaled(SidebarImage, AvailableClientArea.Width, 0,50,PicGame.Height);
  1934. //MessageBox.Show(SidebarImage.Size.ToString());
  1935. //backBufferCanvas.CompositingQuality = CompositingQuality.HighQuality;
  1936. //SideBarImageCanvas.DrawImage(SidebarImage, AvailableClientArea.Width, 0, PicGame.ClientRectangle.Width - AvailableClientArea.Width, PicGame.Height);
  1937. ImageAttributes sidebardrawattr = new ImageAttributes();
  1938. if (mGameState != null)
  1939. {
  1940. ColorMatrix getmatrix = mGameState.PlayingLevel.SidebarColorMatrixValues;
  1941. sidebardrawattr.SetColorMatrix(getmatrix);
  1942. }
  1943. //SideBarImageCanvas.DrawImage(SidebarImage, 0, 0, SideBarImageBitmap.Width, SideBarImageBitmap.Height);
  1944. SideBarImageCanvas.DrawImage(SidebarImage, new Rectangle(0, 0, SideBarImageBitmap.Width, SideBarImageBitmap.Height),0,0,
  1945. SidebarImage.Width,SidebarImage.Height,GraphicsUnit.Pixel,sidebardrawattr);
  1946. //and here is where we "colourize" the used background. This could be a level setting. Than again, so could the sidebar image
  1947. //itself, come to think of it.
  1948. //SideBarImageCanvas.FillRectangle(new SolidBrush(Color.FromArgb(128, Color.Blue)), 0, 0, SideBarImageBitmap.Width, SideBarImageBitmap.Height);
  1949. //backBufferCanvas.CompositingQuality = CompositingQuality.HighSpeed;
  1950. //12,212
  1951. // }
  1952. //}
  1953. if (mGameState == null) return; //TODO: make it show something different when there is no levelset loaded.
  1954. Rectangle titlerect = new Rectangle(13, 12, 197 - 13, 57 - 12);
  1955. Rectangle scorelivesrect = new Rectangle(13,80,197-13,243-80);
  1956. Rectangle extrainforect = new Rectangle(13,390,197-13,415-390);
  1957. Color usetextcolor = mPlayingSet.Levels[mPlayingLevel - 1].SidebarTextColor;
  1958. //titlerect.Offset(AvailableClientArea.Width, 0);
  1959. //scorelivesrect.Offset(AvailableClientArea.Width, 0);
  1960. //extrainforect.Offset(AvailableClientArea.Width, 0);
  1961. //TODO: use a INI file setting for the font.
  1962. Font usetitlefont = BCBlockGameState.GetScaledFont(new Font("Arabia", 16),28);
  1963. //try
  1964. //{
  1965. if (mPlayingSet != null)
  1966. {
  1967. if (mPlayingLevel - 1 < mPlayingSet.Levels.Count)
  1968. SideBarImageCanvas.DrawString(
  1969. mPlayingSet.Levels[mPlayingLevel - 1].LevelName + "(" + mPlayingLevel.ToString() + " of " +
  1970. (mPlayingSet.Levels.Count).ToString() + ")",
  1971. usetitlefont, new SolidBrush(usetextcolor), titlerect);
  1972. }
  1973. //}
  1974. //catch (Exception)
  1975. //{
  1976. //
  1977. //}
  1978. String scorelivesstring = "Score:" + mGameState.GameScore.ToString() + "\n" +
  1979. "Lives:" + mGameState.playerLives.ToString() + "\n" +
  1980. "Multiplier:" + mGameState.ScoreMultiplier;
  1981. //+"Time:" + FormatLevelTime(mLevelTime) + "\n";
  1982. SideBarImageCanvas.DrawString(scorelivesstring
  1983. , BCBlockGameState.GetScaledFont(new Font("Arial", 16, FontStyle.Bold),28), new SolidBrush(usetextcolor), scorelivesrect);
  1984. //draw HP:
  1985. //draw in rect:
  1986. //(10,215)-(197,245) of the sidebar.
  1987. #region drawHPbar
  1988. const int MeterX = 10;
  1989. const int MeterY = 171;
  1990. Rectangle HPrect = new Rectangle(MeterX,MeterY,180,32);
  1991. float useHP=0;
  1992. if (mGameState.PlayerPaddle != null)
  1993. {
  1994. useHP = mGameState.PlayerPaddle.HP;
  1995. }
  1996. Rectangle HPmeterrect = new Rectangle(10, MeterY, (int)((useHP * ((float)HPrect.Width / 100))),HPrect.Height);
  1997. //HPrect.Offset(AvailableClientArea.Width, 0);
  1998. //HPmeterrect.Offset(AvailableClientArea.Width, 0);
  1999. //now, create the brushes we will use:
  2000. if (useHP > 0)
  2001. {
  2002. Brush meterbackground = new LinearGradientBrush(HPrect, Color.FromArgb(128, Color.Gray),
  2003. Color.FromArgb(15, Color.White),
  2004. LinearGradientMode.Horizontal);
  2005. Brush meterforeground = new LinearGradientBrush(HPmeterrect, Color.Blue, Color.Green,
  2006. LinearGradientMode.Horizontal);
  2007. String MeterString = useHP.ToString();
  2008. DrawMeter(SideBarImageCanvas, HPrect, HPmeterrect, meterbackground, meterforeground, "HP:" + MeterString);
  2009. }
  2010. #endregion
  2011. //draw energy Bar. Draw in rect:
  2012. //(10,215)-(197,245)
  2013. #region DrawEnergyBar
  2014. float useEnergy = 0;
  2015. if (mGameState.PlayerPaddle != null)
  2016. {
  2017. useEnergy = mGameState.PlayerPaddle.Energy;
  2018. if (useEnergy > 0)
  2019. {
  2020. Rectangle Energyrect = new Rectangle(10, 210, 180, 32);
  2021. Rectangle Energymeterrect = new Rectangle(10, 210, (int)((useEnergy * ((float)Energyrect.Width / 100))), Energyrect.Height);
  2022. //Energyrect.Offset(AvailableClientArea.Width, 0);
  2023. //Energymeterrect.Offset(AvailableClientArea.Width, 0);
  2024. Brush EnergyMeterBackground = new LinearGradientBrush(Energyrect, Color.FromArgb(128, Color.Gray),
  2025. Color.FromArgb(15, Color.White),
  2026. LinearGradientMode.Horizontal);
  2027. Brush EnergyMeterForeground = new LinearGradientBrush(Energymeterrect, Color.Red, Color.Yellow,
  2028. LinearGradientMode.Horizontal);
  2029. // DrawMeter(g, HPrect, HPmeterrect, EnergyMeterBackground, EnergyMeterForeground, "Energy:" + useEnergy.ToString());
  2030. DrawMeter(SideBarImageCanvas, Energyrect, Energymeterrect, EnergyMeterBackground, EnergyMeterForeground, "Energy:" + useEnergy.ToString());
  2031. }
  2032. }
  2033. #endregion
  2034. //start drawing the stars at position 12,212, in increments of 33 pixels.)
  2035. if (mGameState != null)
  2036. // Debug.Print("Numcompletions=" + mGameState.NumCompletions.ToString());
  2037. {
  2038. if ((mGameState.NumCompletions < 4))
  2039. {
  2040. for (int i = 0; i < mGameState.NumCompletions; i++)
  2041. {
  2042. //BackgroundBuffer.DrawImage(BCBlockGameState.Imageman.getLoadedImage("STAR"),
  2043. // AvailableClientArea.Right + 12 + (33 * i), AvailableClientArea.Top + 212, 32, 32);
  2044. //Debug.Print("Drawing star at " + AvailableClientArea.Width.ToString() + "+ 12 + (33 *" + i + ")");
  2045. /*
  2046. BackgroundBuffer.DrawLine(new Pen(Color.Black),0, 0, AvailableClientArea.Width + 12 + (33 * i), 212);
  2047. BackgroundBuffer.DrawImage(BCBlockGameState.Imageman.getLoadedImage("STAR"),
  2048. AvailableClientArea.Width + 12 + (33 * i), 212, 32, 32);
  2049. */
  2050. //g.DrawLine(new Pen(Color.Black), 0, 0, AvailableClientArea.Width + 12 + (33 * i), 212);
  2051. SideBarImageCanvas.DrawImage(BCBlockGameState.Imageman.getLoadedImage("STAR"),
  2052. AvailableClientArea.Width + 12 + (33 * i), 212, 32, 32);
  2053. }
  2054. }
  2055. else
  2056. {
  2057. //if more than 4 completions, show <star> * <number>
  2058. //draw the star...
  2059. SideBarImageCanvas.DrawImage(BCBlockGameState.Imageman.getLoadedImage("STAR"), AvailableClientArea.Width + 12, 212, 32, 32);
  2060. //SizeF sizeuse = mGameState.CompletionsFontsize;
  2061. GraphicsPath usegp = new GraphicsPath();
  2062. Font usefont = mGameState.CompletionsFont;
  2063. PointF cptextorigin = new PointF(AvailableClientArea.Width+12+35,212);
  2064. usegp.AddString(mGameState.NumCompletionsText,usefont.FontFamily,(int)usefont.Style,usefont.Size,cptextorigin,StringFormat.GenericTypographic);
  2065. SideBarImageCanvas.FillPath(new SolidBrush(usetextcolor), usegp);
  2066. }
  2067. //39,335 is where we draw the MacGuffin Count.
  2068. Image MacGuffinPic = BCBlockGameState.GetSphereImage(Color.Blue);
  2069. //paint it at 39,335; 16x16:
  2070. SideBarImageCanvas.DrawImage(MacGuffinPic, 39, 340, 16, 16);
  2071. //paint x <Count>
  2072. const int normalsize = 32;
  2073. const int expandedsize = 48;
  2074. TimeSpan Expandtime = mGameState.MacGuffinExpandTime;
  2075. //choose a size between normalsize and expandedsize based on the last macguffin time.
  2076. int usesize;
  2077. TimeSpan sincelast = DateTime.Now - mGameState.LastMacGuffinTime;
  2078. if (sincelast.TotalMilliseconds > Expandtime.TotalMilliseconds)
  2079. usesize = normalsize;
  2080. else
  2081. {
  2082. usesize = expandedsize - (int)((sincelast.TotalMilliseconds / Expandtime.TotalMilliseconds) * (expandedsize - normalsize));
  2083. }
  2084. Point uselocation = new Point(60, 362 - usesize);
  2085. Font macguffinfont= BCBlockGameState.GetScaledFont(new Font("Consolas", DPIHelper.ScaleFontSize(16,SideBarImageCanvas)), usesize);
  2086. SideBarImageCanvas.DrawString("x " + mGameState.MacGuffins.ToString(), macguffinfont, new SolidBrush(usetextcolor), uselocation.X, uselocation.Y);
  2087. // PicGame.Invalidate();
  2088. // sidebarbgdrawn = true;
  2089. }
  2090. //extra code to draw active power ups. This will be done by seeing first if there is a valid paddle (not null)
  2091. //and then by grabbing the images for all it's behaviours- again, ignoring null values for getIcon().
  2092. //starting at 9,250...
  2093. if (mGameState.PlayerPaddle != null)
  2094. {
  2095. //LINQ ftw again...
  2096. var geticons =(from qq in mGameState.PlayerPaddle.Behaviours where qq.GetIcon()!=null select qq.GetIcon());
  2097. int initialX = 32;
  2098. int pbX = initialX, pbY = 260;
  2099. Size behdrawsize = new Size(32, 16);
  2100. foreach (Image loopimage in geticons)
  2101. {
  2102. SideBarImageCanvas.DrawImage(loopimage, new Rectangle(new Point(pbX, pbY), behdrawsize));
  2103. pbX += behdrawsize.Width + 2;
  2104. if (pbX > initialX+160)
  2105. {
  2106. pbX = initialX;
  2107. pbY += behdrawsize.Height + 2;
  2108. }
  2109. }
  2110. //tada....
  2111. }
  2112. SideBarImageCanvas.DrawString("Copyright 2009-2011 BASeCamp Corporation. Ver:" + getappversion(),
  2113. new Font(BCBlockGameState.GetMonospaceFont(), 8), new SolidBrush(usetextcolor), extrainforect);
  2114. }
  2115. private void DrawMeter(Graphics g, Rectangle HPrect, Rectangle HPmeterrect, Brush meterbackground, Brush meterforeground, string MeterString)
  2116. {
  2117. g.FillRectangle(meterbackground, HPrect);
  2118. g.FillRectangle(meterforeground, HPmeterrect);
  2119. StringFormat newformat = new StringFormat(StringFormatFlags.NoWrap);
  2120. newformat.Alignment = StringAlignment.Center;
  2121. g.DrawString(MeterString, BCBlockGameState.GetScaledFont(new Font(BCBlockGameState.GetMonospaceFont(), 14, FontStyle.Bold),32), new SolidBrush(Color.Black),
  2122. HPrect, newformat);
  2123. }
  2124. private string getappversion()
  2125. {
  2126. return Application.ProductVersion;
  2127. }
  2128. private void DrawBackgroundFrame()
  2129. {
  2130. //used to draw a changing background.
  2131. if (mGameState.BackgroundDraw.RequiresPerformFrame()) mGameState.BackgroundDraw.PerformFrame(mGameState);
  2132. BackgroundBuffer.SetClip(AvailableClientArea);
  2133. mGameState.BackgroundDraw.DrawBackground(mGameState, BackgroundBuffer,PicGame.ClientRectangle, false);
  2134. }
  2135. private Font usefont = new Font(BCBlockGameState.GetMonospaceFont(),24);
  2136. private CharacterAnimator getLinearCharAnimator(PointF position, String fromstring, int index)
  2137. {
  2138. Graphics g = Graphics.FromImage(new Bitmap(1,1));
  2139. String lensubstr = fromstring.Substring(0, index);
  2140. SizeF stringsize = g.MeasureString(lensubstr, usefont);
  2141. PointF useendpos = new PointF(position.X+stringsize.Width,position.Y);
  2142. PointF usestartpos = new PointF(useendpos.X,useendpos.Y+50);
  2143. return new LinearCharacterAnimator(fromstring[index],usestartpos,useendpos,new TimeSpan(0,0,5));
  2144. }
  2145. public Region BlockRegion = null;
  2146. public LevelSet ActualPlaySet;
  2147. public void setPaintHandler()
  2148. {
  2149. PicGame.Paint += PicGame_PaintNonDWM;
  2150. /*
  2151. if (BCBlockGameState.hasDWM())
  2152. {
  2153. PicGame.Paint -= PicGame_PaintNonDWM;
  2154. PicGame.Paint -= PicGame_PaintDWM;
  2155. PicGame.Paint += PicGame_PaintDWM;
  2156. }
  2157. else
  2158. {
  2159. PicGame.Paint -= PicGame_PaintDWM;
  2160. PicGame.Paint -= PicGame_PaintDWM;
  2161. PicGame.Paint += PicGame_PaintNonDWM;
  2162. }
  2163. */
  2164. }
  2165. private Bitmap nonDWMBuffer = null;
  2166. private Graphics nonDWMBufferg = null;
  2167. private void PicGame_PaintNonDWM(object sender, PaintEventArgs e)
  2168. {
  2169. //NON-DWM painting- create a bitmap, call he DWM paint and paint on it, and blit that to the object.
  2170. if (nonDWMBuffer == null)
  2171. {
  2172. nonDWMBuffer = new Bitmap((int)PicGame.ClientSize.Width, (int)PicGame.ClientSize.Height);
  2173. nonDWMBufferg = Graphics.FromImage(nonDWMBuffer);
  2174. }
  2175. nonDWMBufferg.Clear(Color.Transparent);
  2176. //PaintEventArgs passargs = new PaintEventArgs(nonDWMBufferg, e.ClipRectangle);
  2177. PaintEventArgs passargs = new PaintEventArgs(nonDWMBufferg,PicGame.ClientRectangle);
  2178. //delegate to the "DWM" paint routine...
  2179. PicGame_PaintDWM(sender, passargs);
  2180. //now we blit nonDWMBuffer to e.Graphics...
  2181. var PrevMode = e.Graphics.CompositingMode;
  2182. var PrevQuality = e.Graphics.CompositingQuality;
  2183. e.Graphics.CompositingMode = CompositingMode.SourceCopy;
  2184. e.Graphics.CompositingQuality = CompositingQuality.HighSpeed;
  2185. e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
  2186. e.Graphics.DrawImage(nonDWMBuffer, 0, 0,PicGame.ClientSize.Width,PicGame.ClientSize.Height);
  2187. e.Graphics.CompositingMode = PrevMode;
  2188. e.Graphics.CompositingQuality = PrevQuality;
  2189. }
  2190. Rectangle StandardSize = new Rectangle(0, 0, 940, 526);
  2191. private static Font LoadingFont = BCBlockGameState.GetScaledFont(new Font("Arial", 72), 80);
  2192. private void PicGame_PaintDWM(object sender, PaintEventArgs e)
  2193. {
  2194. //if (mGameState!=null && mGameState.lastframeimage == null) mGameState.lastframeimage = new Bitmap(PicGame.ClientSize.Width, PicGame.ClientSize.Height, e.Graphics);
  2195. String LoadingText="Please Wait...";
  2196. e.Graphics.PageUnit = GraphicsUnit.Pixel;
  2197. e.Graphics.PixelOffsetMode = PixelOffsetMode.HighSpeed;
  2198. if (gamerunstate is StateLoading)
  2199. {
  2200. Rectangle usearea = StandardSize;
  2201. e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
  2202. Image useimage = BCBlockGameState.Imageman.getLoadedImage("LOADINGBG");
  2203. /*
  2204. LinearGradientBrush lgb = new LinearGradientBrush(usearea, Color.Green, Color.Blue, LinearGradientMode.Horizontal);
  2205. e.Graphics.FillRectangle(lgb, usearea);
  2206. * */
  2207. e.Graphics.DrawImage(useimage, 0, 0,StandardSize.Width,StandardSize.Height);
  2208. Size gotsize = TextRenderer.MeasureText(LoadingText, LoadingFont);
  2209. Point drawhere = new Point(usearea.Width / 2 - gotsize.Width / 2, usearea.Height / 2 - gotsize.Height / 2);
  2210. GraphicsPath gp = new GraphicsPath();
  2211. gp.AddString(LoadingText, LoadingFont, drawhere, StringFormat.GenericDefault);
  2212. e.Graphics.FillPath(new SolidBrush(Color.White), gp);
  2213. e.Graphics.DrawPath(new Pen(Color.Black),gp);
  2214. return;
  2215. }
  2216. if(mGameState!=null)
  2217. e.Graphics.TranslateTransform(mGameState.Translation.X, mGameState.Translation.Y);
  2218. bool blocksdrawn=false;
  2219. DateTime LastPaint=DateTime.Now;
  2220. //clear...
  2221. bool foundanimated = false;
  2222. try
  2223. {
  2224. //Graphics g = e.Graphics;
  2225. Graphics g = backBufferCanvas;
  2226. if (Dorefreshstats)
  2227. {
  2228. //Dorefreshstats is set when the score, lives, or level is changed.
  2229. Dorefreshstats = false; //set to false- the point of this is to prevent having to draw the status info every single frame!
  2230. g.Clear(Color.White);
  2231. //clear the entire thing.
  2232. //redraw the status:
  2233. PaintSideBarstats();
  2234. //draw it to the backbuffer. clear the clip first, so we can draw outside any defined clip:
  2235. g.SetClip(new Rectangle(Point.Empty,BackBufferBitmap.Size)); //use clip that is the entire size.
  2236. //draw the image of the sidebar to the backbuffer (g is the backbuffer)
  2237. g.DrawImageUnscaled(SideBarImageBitmap, AvailableClientArea.Width, 0);
  2238. //re set the clip,
  2239. g.SetClip(AvailableClientArea);
  2240. }
  2241. else
  2242. {
  2243. g.SetClip(AvailableClientArea);
  2244. g.Clear(Color.Transparent);
  2245. }
  2246. //g.SmoothingMode = SmoothingMode.HighSpeed;
  2247. //Graphics g = backBufferCanvas;
  2248. //g.Clear(Color.White);
  2249. if (mGameState == null)
  2250. return;
  2251. // lock (mGameState)
  2252. // {
  2253. //BackgroundBuffer.Clear(Color.Transparent);
  2254. //foundanimated = (from Block w in mGameState.Blocks where (w.RequiresPerformFrame()) select w).Count() > 0;
  2255. //foundanimated = mGameState.Blocks.Any((w) => w.RequiresPerformFrame());
  2256. if(gamerunstate is StateMenu)
  2257. {
  2258. DrawShade(g, Color.FromArgb(75, Color.Blue));
  2259. menudata.Draw(g, mGameState);
  2260. if (mGameState.PlayerPaddle != null)
  2261. mGameState.PlayerPaddle.Draw(g);
  2262. }
  2263. else if (gamerunstate is StatePaused)
  2264. {
  2265. DrawShade(g, Color.FromArgb(75, Color.Blue));
  2266. PaintPause(g);
  2267. /*
  2268. String measureme = "PAUSED";
  2269. //draw a white box near the center...
  2270. //RectangleF Inputboxcoordsf = new RectangleF(PicGame.ClientRectangle.Width/4,PicGame.ClientRectangle.Height/4,PicGame.ClientRectangle.Width/2,PicGame.ClientRectangle.Height/2);
  2271. Font pausedinputfont = new Font("Arial Black", 38);
  2272. SizeF InputboxSize;
  2273. InputboxSize = g.MeasureString(measureme, pausedinputfont);
  2274. RectangleF centered = BCBlockGameState.CenterRect(mGameState.GameArea, InputboxSize);
  2275. g.DrawString("PAUSED", pausedinputfont, new SolidBrush(Color.Yellow), centered);
  2276. */
  2277. if (mGameState.PlayerPaddle != null)
  2278. mGameState.PlayerPaddle.Draw(g);
  2279. }
  2280. #region cheat/value entry
  2281. else if (gamerunstate is StateValueInput)
  2282. {
  2283. gamerunstate.DrawFrame(mGameState,g,PicGame.ClientSize);
  2284. }
  2285. #endregion
  2286. else
  2287. {
  2288. if (BlockRegion != null) BlockRegion.Dispose();
  2289. BlockRegion = new Region();
  2290. //Debug.Print("redrawblocks=" + mredrawblocks.ToString());
  2291. blocksdrawn = mredrawblocks;
  2292. #region draw static blocks
  2293. if (mredrawblocks)
  2294. {
  2295. BlockDrawBuffer.Clear(Color.Transparent);
  2296. if (staticblocks != null)
  2297. {
  2298. foreach (Block drawblock in staticblocks)
  2299. {
  2300. BlockRegion.Intersect(drawblock.BlockRectangle);
  2301. drawblock.Draw(BlockDrawBuffer);
  2302. }
  2303. }
  2304. else
  2305. {
  2306. Debug.Print("staticblocks was null");
  2307. }
  2308. }
  2309. #endregion
  2310. //now the animated blocks.
  2311. /*
  2312. if (mredrawblocks)
  2313. {
  2314. BlockDrawBuffer.Clear(Color.Transparent);
  2315. if (mGameState.Blocks != null)
  2316. {
  2317. foreach (Block drawblock in mGameState.Blocks)
  2318. {
  2319. if (!(drawblock.RequiresPerformFrame()))
  2320. drawblock.Draw(BlockDrawBuffer);
  2321. else
  2322. foundanimated = true;
  2323. }
  2324. }
  2325. }*/
  2326. if (mRedrawAnimated)
  2327. {
  2328. MovingBlockBuffer.Clear(Color.Transparent);
  2329. if (AnimatedBlocks != null)
  2330. {
  2331. foreach (Block drawblock in AnimatedBlocks)
  2332. {
  2333. BlockRegion.Intersect(drawblock.BlockRectangle);
  2334. drawblock.Draw(MovingBlockBuffer);
  2335. }
  2336. }
  2337. else
  2338. {
  2339. Debug.Print("AnimatedBlocks=null for some reason.");
  2340. }
  2341. }
  2342. if (foundanimated || mRedrawAnimated)
  2343. {
  2344. var queryblocks = from Block w in mGameState.Blocks where (w.RequiresPerformFrame()) select w;
  2345. MovingBlockBuffer.Clear(Color.Transparent);
  2346. Block lastblock = null;
  2347. reloopit:
  2348. try
  2349. {
  2350. foreach (Block drawblock in queryblocks)
  2351. {
  2352. lastblock = drawblock;
  2353. drawblock.Draw(MovingBlockBuffer);
  2354. }
  2355. }
  2356. catch (Exception pz)
  2357. {
  2358. Trace.WriteLine(pz.StackTrace);
  2359. //messy... but it works.
  2360. goto reloopit;
  2361. }
  2362. }
  2363. g.DrawImageUnscaled(backgroundbitmap, 0, 0);
  2364. //PaintSideBarstats(e.Graphics);
  2365. g.SetClip(AvailableClientArea);
  2366. DrawBackgroundFrame();
  2367. g.DrawImageUnscaled(BlockDrawBitmap, 0, 0);
  2368. //Debug.Print("foundanimated=" + foundanimated.ToString());
  2369. if (foundanimated || mRedrawAnimated)
  2370. {
  2371. g.DrawImageUnscaled(MovingBlockBitmap, 0, 0);
  2372. }
  2373. if (mGameState.Balls != null)
  2374. {
  2375. mGameState.Balls.Remove((cBall)null);
  2376. }
  2377. lock (mGameState.Particles)
  2378. {
  2379. foreach (Particle loopparticle in mGameState.Particles)
  2380. {
  2381. if(loopparticle!=null)
  2382. loopparticle.Draw(g);
  2383. }
  2384. }
  2385. foreach (GameObject loopgameobject in mGameState.GameObjects)
  2386. {
  2387. if(loopgameobject!=null)
  2388. loopgameobject.Draw(g);
  2389. }
  2390. foreach (cBall drawball in mGameState.Balls)
  2391. {
  2392. if (drawball != null)
  2393. drawball.Draw(g);
  2394. }
  2395. if (mGameState.PlayerPaddle != null)
  2396. mGameState.PlayerPaddle.Draw(g);
  2397. if (DemoMode)
  2398. {
  2399. #region gameoverdraw
  2400. if (gamerunstate is StateLevelOutroGameOver)
  2401. {
  2402. //Font GameOverFont = new Font("Arial", 28);
  2403. Font GameOverFont = BCBlockGameState.GetScaledFont(new Font("Arial", 28), 72);
  2404. SizeF valueSize = g.MeasureString(tallydata.TallyScreenString, GameOverFont);
  2405. g.FillRectangle(new SolidBrush(Color.FromArgb(128, Color.Gray)), AvailableClientArea);
  2406. RectangleF middlerect = GetCenteredRect(valueSize, AvailableClientArea);
  2407. /*if (ActualPlaySet != null)
  2408. {
  2409. middlerect = new RectangleF(middlerect.Left, AvailableClientArea.Height - middlerect.Height, AvailableClientArea.Width, AvailableClientArea.Height);
  2410. }
  2411. */
  2412. RectangleF expandedrect = middlerect;
  2413. expandedrect.Inflate(10, 10);
  2414. var sf = new StringFormat();
  2415. sf.Alignment = StringAlignment.Near;
  2416. /*
  2417. Color FirstColor = Color.FromArgb(200, Color.White);
  2418. Color SecondColor = Color.FromArgb(125, Color.Green);
  2419. Brush fillbrush = new LinearGradientBrush(middlerect, FirstColor, SecondColor, 0f);
  2420. g.FillRectangle(new SolidBrush(Color.FromArgb(128, Color.Black)), expandedrect);
  2421. g.FillRectangle(fillbrush, middlerect);
  2422. GraphicsPath textpath = new GraphicsPath();
  2423. textpath.AddString(tallydata.TallyScreenString, GameOverFont.FontFamily, (int)GameOverFont.Style, GameOverFont.Size, middlerect, sf);
  2424. g.FillPath(new TextureBrush(BCBlockGameState.Imageman.getLoadedImage("Invincible"), WrapMode.Tile), textpath);
  2425. g.DrawPath(new Pen(Color.Black), textpath);
  2426. // g.DrawString(tallydata.TallyScreenString, GameOverFont, new SolidBrush(Color.Black), middlerect);
  2427. */
  2428. //draw the top high scores and their names, as well.
  2429. //the relevant set was cached as "ActualPlaySet"...
  2430. if (ActualPlaySet != null)
  2431. {
  2432. //start from the top.
  2433. //draw GameOverHiScores
  2434. //HighScoreNamesMaxLength is maximum length of name
  2435. //HighScoreScoresMaxLength is maximum length of score.
  2436. //HighScoremaxSeparators is max separators to use. (periods, usually)
  2437. //Font hiscorefont = new Font("Courier New", 18);
  2438. Font hiscorefont = BCBlockGameState.GetScaledFont(new Font("Courier New", 18), 28);
  2439. using (GraphicsPath usepath = new GraphicsPath())
  2440. {
  2441. SizeF measuredsize = g.MeasureString(GameOverHiScores, hiscorefont);
  2442. PointF topscoresorigin = new PointF(AvailableClientArea.Width / 2 - (measuredsize.Width / 2), 16);
  2443. Rectangle scoresbox = new Rectangle(new Point((int)topscoresorigin.X, (int)topscoresorigin.Y), new Size((int)measuredsize.Width, (int)measuredsize.Height));
  2444. //draw a box to "surround" the top scores.
  2445. g.FillRectangle(new SolidBrush(Color.FromArgb(210, Color.YellowGreen)), scoresbox);
  2446. g.DrawRectangle(new Pen(Color.Black, 3), scoresbox);
  2447. GraphicsPath shadowed = (GraphicsPath)usepath.Clone();
  2448. usepath.AddString(GameOverHiScores, hiscorefont.FontFamily, (int)hiscorefont.Style, hiscorefont.Size, topscoresorigin, sf);
  2449. shadowed.AddString(GameOverHiScores, hiscorefont.FontFamily, (int)hiscorefont.Style, hiscorefont.Size, new PointF(topscoresorigin.X+3,topscoresorigin.Y+3), sf);
  2450. SmoothingMode cachedmode = g.SmoothingMode;
  2451. g.SmoothingMode = SmoothingMode.HighQuality;
  2452. g.FillPath(new SolidBrush(Color.FromArgb(128, Color.Black)), shadowed);
  2453. g.DrawPath(new Pen(Color.Black), usepath);
  2454. g.FillPath(new SolidBrush(Color.Black), usepath);
  2455. g.SmoothingMode = cachedmode;
  2456. }
  2457. //g.DrawPath(new Pen(Color.Black), usepath);
  2458. }
  2459. }
  2460. #endregion
  2461. else if ((DateTime.Now.Second % 2) == 0)
  2462. {
  2463. Font DemoModeFont = BCBlockGameState.GetScaledFont(new Font("Arial", 18),24);
  2464. SizeF valuesize = g.MeasureString("DEMO MODE", DemoModeFont);
  2465. g.DrawString("DEMO MODE", DemoModeFont, new SolidBrush(Color.Red), AvailableClientArea.Right - valuesize.Width, AvailableClientArea.Bottom - valuesize.Height);
  2466. }
  2467. }
  2468. //draw some info in the lower right corner.
  2469. }
  2470. String InfoString = "";
  2471. TimeSpan timediff = DateTime.Now - LastPaint;
  2472. if (timediff.Milliseconds > 0)
  2473. {
  2474. CurrentFPS = (1000 / timediff.Milliseconds);
  2475. InfoString = "FPS:" + CurrentFPS.ToString() + "\n";
  2476. }
  2477. if (ShowDebugInfo)
  2478. {
  2479. InfoString += "Blocks Drawn:" + (blocksdrawn ? mGameState.Blocks.Count() : 0).ToString() + "\n" +
  2480. "Balls:" + mGameState.Balls.Count.ToString() + "\n" +
  2481. "Particles:" + mGameState.Particles.Count.ToString() + "\n" +
  2482. "GameObjects:" + mGameState.GameObjects.Count.ToString() + "\n" +
  2483. "SpeedMult:" + mGameState.SpeedMultiplier.ToString() + "\n" +
  2484. "Lives:" + mGameState.playerLives + "\n" +
  2485. "Score:" + mGameState.GameScore + "\n" +
  2486. "Level:" + mPlayingLevel + "\n" +
  2487. "Elapsed:" + mLevelTime.ToString() + "\n" +
  2488. "Mem Alloc:" + System.GC.GetTotalMemory(false);
  2489. }
  2490. if (!String.IsNullOrEmpty(InfoString))
  2491. {
  2492. Font InfoTextFont = BCBlockGameState.GetScaledFont(new Font(BCBlockGameState.GetMonospaceFont(), DPIHelper.ScaleFontSize(10,e.Graphics)),15,e.Graphics);
  2493. SizeF stattextsize = g.MeasureString(InfoString, InfoTextFont);
  2494. g.DrawString(InfoString, InfoTextFont, new SolidBrush(Color.FromArgb(240, Color.Black)), 0,
  2495. PicGame.Height - stattextsize.Height);
  2496. }
  2497. if (gamerunstate is StateLevelIntro)
  2498. {
  2499. Level playinglevel = mPlayingSet.Levels[mPlayingLevel - 1];
  2500. //also draw the levels name...
  2501. g.DrawImageUnscaled(backgroundbitmap, 0, 0);
  2502. g.Clip = new Region();
  2503. // PaintSideBarstats(e.Graphics);
  2504. g.SetClip(AvailableClientArea);
  2505. DrawBackgroundFrame();
  2506. g.DrawImageUnscaled(BlockDrawBitmap, 0, 0);
  2507. String drawlevelname = playinglevel.LevelName;
  2508. Color mFillColor = playinglevel.LevelNameIntroTextFillColor;
  2509. Color mStrokeColor = playinglevel.LevelNameIntroTextPenColor;
  2510. Font drawlevelfont = playinglevel.LevelnameIntroFont;
  2511. GraphicsPath usepath = new GraphicsPath();
  2512. Rectangle drawintrorect = BCBlockGameState.CenterRect(AvailableClientArea, IntroSequenceBitmap.Size);
  2513. //Debug.Print("Drawing intro rect:" + drawintrorect.ToString() + " within available area:" + AvailableClientArea.ToString() + " bitmap size is:" + IntroSequenceBitmap.Size.ToString());
  2514. g.DrawImageUnscaled(IntroSequenceBitmap, drawintrorect.Left, drawintrorect.Top);
  2515. TimeSpan Timeremaining = playinglevel.ShowNameLength - (DateTime.Now - mLevelIntroStartTime);
  2516. var oldq = g.CompositingQuality;
  2517. var olds = g.SmoothingMode;
  2518. g.CompositingQuality = CompositingQuality.HighQuality;
  2519. g.SmoothingMode = SmoothingMode.HighQuality;
  2520. g.DrawStringCenter("Ready in " + Timeremaining.Seconds,
  2521. BCBlockGameState.GetScaledFont(new Font("Arial", 24),45,e.Graphics),
  2522. new SolidBrush(Color.Blue), new Pen(Color.YellowGreen), AvailableClientArea, new Point(0, 48));
  2523. g.CompositingQuality = oldq;
  2524. g.SmoothingMode = olds;
  2525. //g.DrawString(Timeremaining.Seconds,new Font("Arial",24),new SolidBrush
  2526. // IntroAnimator.Draw(g);
  2527. // usepath.AddString(drawlevelname,drawlevelfont.FontFamily,(int)drawlevelfont.Style,drawlevelfont.Size,GetCenteredRect(g.MeasureString(drawlevelname, drawlevelfont),AvailableClientArea),StringFormat.GenericDefault);
  2528. //g.FillPath(new SolidBrush(mFillColor), usepath);
  2529. //g.DrawPath(new Pen(mStrokeColor, 1),usepath);
  2530. //g.DrawString(drawlevelname, drawlevelfont, new SolidBrush(mDrawColor), , AvailableClientArea));
  2531. }
  2532. else if (gamerunstate is StateLevelOutro)
  2533. {
  2534. //again, might be preferable to use a selectable font?
  2535. System.Drawing.Font tallyfont = new Font(BCBlockGameState.GetMonospaceFont(), DPIHelper.ScaleFontSize(32,g));
  2536. RectangleF centered = GetCenteredRect(g.MeasureString(tallydata.TallyScreenString, tallyfont), AvailableClientArea);
  2537. RectangleF boxdraw = centered;
  2538. boxdraw.Inflate(5, 5);
  2539. Color ColorA = Color.FromArgb(200, Color.White), ColorB = Color.FromArgb(128, Color.Gray);
  2540. //TODO: change This section so that it displays an Alpha Image instead of a boring white box.
  2541. //g.FillRectangle(new System.Drawing.Drawing2D.LinearGradientBrush(boxdraw,ColorA, ColorB, (float)(Math.PI * 2 * BCBlockGameState.rgen.NextDouble())), boxdraw);
  2542. //g.DrawRectangle(new Pen(Color.Black, 3), boxdraw.Left,boxdraw.Top,boxdraw.Width,boxdraw.Height);
  2543. g.DrawImage(tallydata.TallyImage, boxdraw.Left, boxdraw.Top, boxdraw.Width, boxdraw.Height);
  2544. g.DrawString(tallydata.TallyScreenString, tallyfont, new SolidBrush(Color.Black), centered);
  2545. }
  2546. mGameState.PaintMessages(g,AvailableClientArea);
  2547. //if(mGameState!=null) mGameState.lastframeimage = new Bitmap(PicGame.ClientSize.Width, PicGame.ClientSize.Height, e.Graphics);
  2548. //pcgraph = PicGame.CreateGraphics();
  2549. }
  2550. catch (Exception q)
  2551. {
  2552. Trace.WriteLine("Exception: Type:" + q.GetType().ToString() + " trace:" + q.StackTrace + " message:" + q.Message);
  2553. }
  2554. finally
  2555. {
  2556. //here is where we have any image post-processing.
  2557. PostProcess(ref BackBufferBitmap,ref backBufferCanvas);
  2558. lock (backBufferCanvas)
  2559. {
  2560. // PaintSideBar(e.Graphics);
  2561. //if (SideBarImageBitmap!= null)
  2562. //{
  2563. //}
  2564. e.Graphics.DrawImageUnscaled(BackBufferBitmap, 0, 0);
  2565. LastPaint = DateTime.Now;
  2566. if (dosaveshot)
  2567. {
  2568. dosaveshot = false;
  2569. SaveScreenshot(BackBufferBitmap);
  2570. }
  2571. }
  2572. }
  2573. }
  2574. private ImageAttributes ProcessColourizer=null;
  2575. Image _CachedPause = null;
  2576. Level _Cachedforlevel = null;
  2577. private void PaintPause(Graphics g)
  2578. {
  2579. String usepausekey = "paused";
  2580. if (mPlayingLevelobj != null) usepausekey = mPlayingLevelobj.PauseImageKey;
  2581. //if we need to, redraw the CachedPause object. we do this because
  2582. //it could involve ImageAttributes which we can ideally avoid drawing every frame.
  2583. if (_CachedPause == null || _Cachedforlevel != mPlayingLevelobj)
  2584. {
  2585. Image createimage = BCBlockGameState.Imageman.getLoadedImage(usepausekey);
  2586. //create the bitmap to cache. Scale it now (this is the "header" image)
  2587. _CachedPause = new Bitmap((int)(createimage.Width * mPlayingLevelobj.PauseImageScale.Width) ,
  2588. (int)( createimage.Height * mPlayingLevelobj.PauseImageScale.Height));
  2589. Graphics Colorized = Graphics.FromImage(_CachedPause);
  2590. ImageAttributes pauseattributes = new ImageAttributes();
  2591. pauseattributes.SetColorMatrix(mPlayingLevelobj.PauseColorMatrixValues);
  2592. Colorized.DrawImage(createimage,
  2593. new Rectangle(0, 0, _CachedPause.Width, _CachedPause.Height),
  2594. 0, 0, createimage.Width, createimage.Height, GraphicsUnit.Pixel, pauseattributes);
  2595. Colorized.Dispose(); //finished with the graphics object.
  2596. }
  2597. //_Cachedpause: we want to use that, add on enough height for the pause text we generate, and paint the new image.
  2598. String pausedatastring = "Score:" + mGameState.GameScore + Environment.NewLine +
  2599. "Time:" + String.Format("{0:00}:{1:00}.{2:00}", Math.Floor(mLevelTime.TotalMinutes), mLevelTime.Seconds, mLevelTime.Milliseconds);
  2600. SizeF measured = BCBlockGameState.MeasureString(pausedatastring,mPlayingLevelobj.PauseFont);
  2601. Image drawpausedimage = new Bitmap((int)(Math.Max(_CachedPause.Width, measured.Width + 30)), (int)(_CachedPause.Height + measured.Height + 20));
  2602. Graphics DrawPause = Graphics.FromImage(drawpausedimage);
  2603. DrawPause.Clear(Color.Transparent);
  2604. //draw the image. Center it if the width is larger.
  2605. PointF drawimageorigin = PointF.Empty;
  2606. if (drawpausedimage.Width > _CachedPause.Width)
  2607. {
  2608. drawimageorigin = new PointF(drawpausedimage.Width / 2 - (_CachedPause.Width / 2), 0);
  2609. }
  2610. //draw the image at the proper coordinates...
  2611. DrawPause.DrawImage(_CachedPause,drawimageorigin);
  2612. //we'll want to draw the text at offset 15,imageheight+10
  2613. //create the graphics path to use for that...
  2614. GraphicsPath TextDraw = new GraphicsPath();
  2615. TextDraw.AddString(pausedatastring, mPlayingLevelobj.PauseFont, new Point(15, _CachedPause.Height+ 10), StringFormat.GenericDefault);
  2616. //paint in drawPause context...
  2617. DrawPause.FillPath(new SolidBrush(mPlayingLevelobj.PauseTextColor), TextDraw);
  2618. //dispose the objects used.
  2619. TextDraw.Dispose();
  2620. DrawPause.Dispose();
  2621. Size useimagesize = new Size((int)(drawpausedimage.Width),
  2622. (int)(drawpausedimage.Height));
  2623. RectangleF centered = BCBlockGameState.CenterRect(mGameState.GameArea, useimagesize);
  2624. CompositingQuality prevquality = g.CompositingQuality;
  2625. g.CompositingQuality = CompositingQuality.AssumeLinear;
  2626. g.DrawImage(drawpausedimage, centered);
  2627. g.CompositingQuality = prevquality;
  2628. }
  2629. int postprocessframe = 0;
  2630. private void PostProcess(ref Bitmap processit,ref Graphics useg)
  2631. {
  2632. if(mGameState==null) return;
  2633. postprocessframe++;
  2634. if (postprocessframe > 50000) postprocessframe = 0;
  2635. if(mGameState.PlayerPaddle!=null)
  2636. {
  2637. if (mGameState.PlayerPaddle.HP < Paddle.dangerzone)
  2638. {
  2639. //removed....
  2640. /*
  2641. if (ProcessColourizer == null) ProcessColourizer = new ImageAttributes();
  2642. ProcessColourizer.SetColorMatrix(ColorMatrices.GetColourizer((float)Math.Sin(1.0f + (double)(postprocessframe/5)), 1.0f, 1.0f, 1.0f));
  2643. useg.DrawImage(processit, new Rectangle(0, 0, processit.Width, processit.Height), 0, 0, processit.Width, processit.Height, GraphicsUnit.Pixel,
  2644. ProcessColourizer);
  2645. */
  2646. }
  2647. }
  2648. if(gamerunstate is StateDeath)
  2649. {
  2650. //grayscale...
  2651. if (ProcessColourizer == null)
  2652. {
  2653. ProcessColourizer = new ImageAttributes();
  2654. ProcessColourizer.SetColorMatrix(ColorMatrices.GrayScale());
  2655. }
  2656. useg.DrawImage(processit, new Rectangle(0, 0, processit.Width, processit.Height), 0, 0, processit.Width, processit.Height, GraphicsUnit.Pixel,
  2657. ProcessColourizer);
  2658. }
  2659. }
  2660. // private Color UseTitleColour = Color.Blue;
  2661. private void SaveScreenshot(Image shotsave)
  2662. {
  2663. //save location:
  2664. //%APPDATA$\BASeBlock\Screenshots\
  2665. String Screenshotfolder = Path.Combine(BCBlockGameState.AppDataFolder, "Screenshots");
  2666. if (!Directory.Exists(Screenshotfolder))
  2667. {
  2668. Directory.CreateDirectory(Screenshotfolder);
  2669. }
  2670. //build the path name.
  2671. // String screenshotname = String.Format("{0:MM-dd-mmzzz}.png", DateTime.Now);
  2672. String screenshotname = DateTime.Now.Year.ToString() + "-" +
  2673. DateTime.Now.Month.ToString() + "-" +
  2674. DateTime.Now.Day.ToString() + " " +
  2675. DateTime.Now.Hour.ToString() + "-" +
  2676. DateTime.Now.Minute.ToString() + "-" +
  2677. DateTime.Now.Second.ToString() + "-" +
  2678. DateTime.Now.Millisecond.ToString() + ".png";
  2679. String shotfile = Path.Combine(Screenshotfolder, screenshotname);
  2680. shotsave.Save(shotfile);
  2681. mGameState.EnqueueMessage("Saved screenshot to \"" + Path.GetFileName(shotfile) + "\"");
  2682. }
  2683. public void DrawShade(Graphics g,Color usecolor)
  2684. {
  2685. g.DrawImageUnscaled(backgroundbitmap, 0, 0);
  2686. g.SetClip(AvailableClientArea);
  2687. DrawBackgroundFrame();
  2688. g.DrawImageUnscaled(BlockDrawBitmap, 0, 0);
  2689. g.DrawImageUnscaled(MovingBlockBitmap, 0, 0);
  2690. g.FillRectangle(new SolidBrush(usecolor), PicGame.ClientRectangle);
  2691. }
  2692. private RectangleF GetCenteredRect(SizeF sizeF, Rectangle rectangle)
  2693. {
  2694. return new RectangleF(new PointF((rectangle.Width/2)-sizeF.Width/2,(rectangle.Height/2)-sizeF.Height/2),sizeF);
  2695. }
  2696. private void button1_Click(object sender, EventArgs e)
  2697. {
  2698. }
  2699. private void PicGame_Click(object sender, EventArgs e)
  2700. {
  2701. }
  2702. private void frmPoing_Activated(object sender, EventArgs e)
  2703. {
  2704. gamethreadsuspended = false;
  2705. UnpauseGame();
  2706. Debug.Print("Form Activated: gamerunstate set to " + gamerunstate.GetType().Name);
  2707. }
  2708. private void frmPoing_Deactivate(object sender, EventArgs e)
  2709. {
  2710. PauseGame();
  2711. Debug.Print("Form Deactivated: gamerunstate set to Paused.");
  2712. gamethreadsuspended = true;
  2713. }
  2714. private DateTime PausedStartTime; //DateTime when the game was paused...
  2715. private TimeSpan? TotalPauseTime;
  2716. private void PauseGame_old()
  2717. {
  2718. if (mGameState == null) return;
  2719. if (!(gamerunstate is StateRunning)) return;
  2720. //remove any present PauseBehaviours.
  2721. //if paused behaviours are present, that means that the balls actual speed is "cached" in the paused ballbehaviour,
  2722. //so we force it to revert...
  2723. Debug.Print("Pausing....");
  2724. //first, if there is a stickypaddlebehaviour present in the playerpaddle, release all the balls.
  2725. if (mGameState.PlayerPaddle != null)
  2726. {
  2727. //if(mGameState.PlayerPaddle.Behaviours.Any((w)=>w is PaddleBehaviours.StickyBehaviour
  2728. foreach (PaddleBehaviours.StickyBehaviour releasefrom in (from n in mGameState.PlayerPaddle.Behaviours where n is PaddleBehaviours.StickyBehaviour select (PaddleBehaviours.StickyBehaviour)n))
  2729. {
  2730. releasefrom.ReleaseAllBalls();
  2731. }
  2732. }
  2733. List<iBallBehaviour> removelist = new List<iBallBehaviour>();
  2734. var clonecol = mGameState.Balls.ShallowClone();
  2735. //clone the collection, so that changes to .Balls don't cause an exception. The actual cBall objects
  2736. //will be the same, however.
  2737. foreach (cBall behaviourball in (from n in clonecol where n.hasBehaviour(typeof(PausedBallBehaviour)) select n))
  2738. {
  2739. removelist.Clear();
  2740. foreach (PausedBallBehaviour pausedbehave in (from n in behaviourball.Behaviours where n is PausedBallBehaviour select (PausedBallBehaviour)n))
  2741. {
  2742. pausedbehave.Forcerevert();
  2743. //pausedbehave.SetSpeed();
  2744. }
  2745. //behaviourball.Behaviours.RemoveAll((w) => w is PausedBallBehaviour);
  2746. }
  2747. BCBlockGameState.Soundman.PauseMusic(true);
  2748. BCBlockGameState.Soundman.PlaySound(mPlayingLevelobj.PauseSound);
  2749. statebeforepause=gamerunstate;
  2750. PausedStartTime=DateTime.Now;
  2751. gamerunstate = new StatePaused();
  2752. //suspend the game thread...
  2753. }
  2754. private void PauseGame()
  2755. {
  2756. if (mGameState == null) return;
  2757. if (!(gamerunstate is StateRunning)) return;
  2758. //remove any present PauseBehaviours.
  2759. //if paused behaviours are present, that means that the balls actual speed is "cached" in the paused ballbehaviour,
  2760. //so we force it to revert...
  2761. Debug.Print("Pausing....");
  2762. //first, if there is a stickypaddlebehaviour present in the playerpaddle, release all the balls.
  2763. if (mGameState.PlayerPaddle != null)
  2764. {
  2765. //if(mGameState.PlayerPaddle.Behaviours.Any((w)=>w is PaddleBehaviours.StickyBehaviour
  2766. foreach (PaddleBehaviours.StickyBehaviour releasefrom in (from n in mGameState.PlayerPaddle.Behaviours where n is PaddleBehaviours.StickyBehaviour select (PaddleBehaviours.StickyBehaviour)n))
  2767. {
  2768. releasefrom.ReleaseAllBalls();
  2769. }
  2770. }
  2771. List<iBallBehaviour> removelist = new List<iBallBehaviour>();
  2772. LinkedList<cBall> clonecol;
  2773. lock (mGameState.Balls)
  2774. {
  2775. clonecol = mGameState.Balls.ShallowClone();
  2776. }
  2777. //clone the collection, so that changes to .Balls don't cause an exception. The actual cBall objects
  2778. //will be the same, however.
  2779. foreach (cBall behaviourball in (from n in clonecol where n.hasBehaviour(typeof(PausedBallBehaviour)) select n))
  2780. {
  2781. removelist.Clear();
  2782. foreach (PausedBallBehaviour pausedbehave in (from n in behaviourball.Behaviours where n is PausedBallBehaviour select (PausedBallBehaviour)n))
  2783. {
  2784. if(pausedbehave.cachedSpeed.X!=0 && pausedbehave.cachedSpeed.Y!=0)
  2785. pausedbehave.Forcerevert();
  2786. //pausedbehave.SetSpeed();
  2787. }
  2788. //behaviourball.Behaviours.RemoveAll((w) => w is PausedBallBehaviour);
  2789. }
  2790. // if (unpauseCompletionTimer == null)
  2791. //if the unpauseCompletionTimer is not null, then the game was paused while it was in action.
  2792. //we need to dispose it so that when it's timer goes off it doesn't reactivate the enemies while the ball and whatnot are still frozen.
  2793. if (unpauseCompletionTimer != null)
  2794. {
  2795. unpauseCompletionTimer.Dispose();
  2796. unpauseCompletionTimer = null;
  2797. }
  2798. BCBlockGameState.Soundman.PauseMusic(true);
  2799. BCBlockGameState.Soundman.PlaySound(mPlayingLevelobj.PauseSound);
  2800. statebeforepause = gamerunstate;
  2801. PausedStartTime = DateTime.Now;
  2802. gamerunstate = new StatePaused();
  2803. //suspend the game thread...
  2804. }
  2805. private void UnpauseGame()
  2806. {
  2807. //cBall loopball;
  2808. if (mGameState == null) return;
  2809. if(!(gamerunstate is StatePaused) ) return;
  2810. Debug.Print("Unpausing....");
  2811. //remove all PausedBallBehaviours from all balls, first.
  2812. //first, make a shallow clone of mGameState.Balls.
  2813. var copyballs = mGameState.Balls.ShallowClone();
  2814. foreach(cBall iterate in (from r in mGameState.Balls where r.hasBehaviour(typeof(PausedBallBehaviour)) select r))
  2815. {
  2816. //first, revert...
  2817. foreach (PausedBallBehaviour pbbb in (from beh in iterate.Behaviours where beh is PausedBallBehaviour select beh as PausedBallBehaviour))
  2818. {
  2819. pbbb.Forcerevert(); //force it to revert the speed.
  2820. List<String> p;
  2821. }
  2822. }
  2823. foreach(cBall loopball in mGameState.Balls)
  2824. {
  2825. loopball.Behaviours.Add(new PausedBallBehaviour(PausedBallBehaviour.GetDefaultTimeout,true));
  2826. //set the ball's speed to zero.
  2827. }
  2828. //freeze all gameobjects...
  2829. lock (mGameState.GameObjects)
  2830. {
  2831. foreach (GameObject loopobject in mGameState.GameObjects)
  2832. {
  2833. loopobject.Frozen = true;
  2834. }
  2835. }
  2836. //initialize the timer, as well, for unfreezing.
  2837. if (unpauseCompletionTimer == null) unpauseCompletionTimer
  2838. = new Timer(UnfreezePauseTimer, null, PausedBallBehaviour.GetDefaultTimeout, new TimeSpan(0, 0, 0, 0, -1));
  2839. BCBlockGameState.Soundman.PauseMusic(false);
  2840. // BCBlockGameState.Soundman.PlaySound("Pause");
  2841. //we want to unpause.
  2842. //however, we will need to change the "time the game started". Since I cannot think of a reason the time would need to be accurate (representing when the game started)
  2843. //this will have the time that the game had been paused added to it.
  2844. TotalPauseTime = DateTime.Now-PausedStartTime;
  2845. gamerunstate = statebeforepause;
  2846. }
  2847. public void FreezeAnimatedBlocks()
  2848. {
  2849. foreach (AnimatedBlock ab in (from m in mGameState.Blocks where m is AnimatedBlock select m))
  2850. {
  2851. ab.Frozen = true;
  2852. }
  2853. }
  2854. public void UnfreezeAnimatedBlocks()
  2855. {
  2856. foreach (AnimatedBlock ab in (from m in mGameState.Blocks where m is AnimatedBlock select m))
  2857. ab.Frozen = false;
  2858. }
  2859. /// <summary>
  2860. /// timer created/set in unpause, used to unfreeze gameobjects when PausedBallBehaviours "release".
  2861. /// </summary>
  2862. private System.Threading.Timer unpauseCompletionTimer = null;
  2863. private void UnfreezePauseTimer(Object parameter)
  2864. {
  2865. //unfreeze all gameobjects.
  2866. lock (mGameState.GameObjects)
  2867. {
  2868. foreach (GameObject iterate in mGameState.GameObjects)
  2869. {
  2870. iterate.Frozen = false;
  2871. }
  2872. }
  2873. if(unpauseCompletionTimer!=null) unpauseCompletionTimer.Dispose();
  2874. unpauseCompletionTimer = null;
  2875. }
  2876. private void frmPoing_FormClosed(object sender, FormClosedEventArgs e)
  2877. {
  2878. if(GameThread!=null&&GameThread.IsAlive)
  2879. GameThread.Abort();
  2880. gamerunstate = new StateNotRunning();
  2881. Application.Exit();
  2882. }
  2883. private PointF ScalePosition(PointF DisplayPos)
  2884. {
  2885. float useX = ((float)DisplayPos.X / (float)PicGame.ClientSize.Width) * (float)StandardSize.Width;
  2886. float useY = ((float)DisplayPos.Y / (float)PicGame.ClientSize.Height) * (float)StandardSize.Height;
  2887. return new PointF(useX, useY);
  2888. }
  2889. private void PicGame_MouseMove(object sender, MouseEventArgs e)
  2890. {
  2891. PointF ClickedPos = ScalePosition(new PointF(e.X, e.Y));
  2892. //if we're not running... don't care...
  2893. if (gamerunstate is StateMenu)
  2894. {
  2895. var hitmenu = menudata.HitTest(mGameState, ClickedPos);
  2896. if (hitmenu != null)
  2897. {
  2898. hitmenu.Selected = true;
  2899. }
  2900. }
  2901. if(!(gamerunstate is StateRunning)) return;
  2902. if (!DemoMode)
  2903. {
  2904. FireMoveAbsolute(ClickedPos);
  2905. InvokeOnMove(ClickedPos);
  2906. }
  2907. //add light particles, for testing.
  2908. /*
  2909. Random rg = BCBlockGameState.rgen;
  2910. for (int i = 0; i < 5; i++)
  2911. {
  2912. PointF ourpoint = new PointF((float) (e.X+rg.NextDouble()*3f-1.5f),(float) (e.Y+rg.NextDouble()*3f-1.5f));
  2913. LightOrb lo = new LightOrb(ourpoint, new HSLColor(rg.NextDouble()*255, 240, 120), 15);
  2914. lo.Velocity = BCBlockGameState.GetRandomVelocity(1, 4);
  2915. lo.VelocityDecay = new PointF(0.95f, 0.95f);
  2916. mGameState.Particles.Add(lo);
  2917. }
  2918. */
  2919. }
  2920. private void newGameToolStripMenuItem_Click(object sender, EventArgs e)
  2921. {
  2922. //StartGame(CreateDefaultLevelSet(),1);
  2923. }
  2924. private Dictionary<Keys, ButtonConstants> GameKeyLookup = null;
  2925. private Dictionary<Keys,ButtonConstants> InitKeyLookup()
  2926. {
  2927. var gotsection = BCBlockGameState.GameSettings["keys"];
  2928. Dictionary<Keys, ButtonConstants> returndictionary = new Dictionary<Keys, ButtonConstants>();
  2929. returndictionary.Add(Keys.Up, ButtonConstants.Button_Up);
  2930. returndictionary.Add(Keys.Down, ButtonConstants.Button_Down);
  2931. returndictionary.Add(Keys.Left, ButtonConstants.Button_Left);
  2932. returndictionary.Add(Keys.Right, ButtonConstants.Button_Right);
  2933. returndictionary.Add(Keys.Space, ButtonConstants.Button_D);
  2934. returndictionary.Add(Keys.W, ButtonConstants.Button_E);
  2935. returndictionary.Add(Keys.A, ButtonConstants.Button_F);
  2936. returndictionary.Add(Keys.S, ButtonConstants.Button_G);
  2937. returndictionary.Add(Keys.D, ButtonConstants.Button_H);
  2938. returndictionary.Add(Keys.ShiftKey, ButtonConstants.Button_Shift);
  2939. foreach (var iteratevalue in gotsection.getValues())
  2940. {
  2941. //ButtonConstant=Keys Constant
  2942. ButtonConstants checkname;
  2943. Debug.Print("Looking for Enumeration value " + iteratevalue.Name);
  2944. if (Enum.TryParse(iteratevalue.Name, true, out checkname))
  2945. {
  2946. Debug.Print("Enumeration found " + checkname.ToString() + " to match " + iteratevalue.Name);
  2947. //if the parse succeeds...
  2948. //we need to do the same for the value with the Keys Enumeration.
  2949. Keys checkvalue;
  2950. if (Enum.TryParse(iteratevalue.Value, true, out checkvalue))
  2951. {
  2952. //we have a name, and a value. Add it to the Dictionary.
  2953. returndictionary[checkvalue] = checkname;
  2954. }
  2955. }
  2956. }
  2957. return returndictionary;
  2958. }
  2959. private ButtonConstants KeyToGameButton(Keys key)
  2960. {
  2961. if (GameKeyLookup == null)
  2962. {
  2963. //look in the keys section.
  2964. GameKeyLookup = InitKeyLookup();
  2965. }
  2966. if(GameKeyLookup.ContainsKey(key))
  2967. return GameKeyLookup[key];
  2968. return ButtonConstants.Button_None;
  2969. /*
  2970. switch (key)
  2971. {
  2972. case Keys.Up:
  2973. return ButtonConstants.Button_Up;
  2974. case Keys.Down:
  2975. return ButtonConstants.Button_Down;
  2976. case Keys.Right:
  2977. return ButtonConstants.Button_Right;
  2978. case Keys.Left:
  2979. return ButtonConstants.Button_Left;
  2980. case Keys.Space:
  2981. return ButtonConstants.Button_D;
  2982. case Keys.W:
  2983. return ButtonConstants.Button_E;
  2984. case Keys.A:
  2985. return ButtonConstants.Button_F;
  2986. case Keys.S:
  2987. return ButtonConstants.Button_G;
  2988. case Keys.D:
  2989. return ButtonConstants.Button_H;
  2990. //Button_E = 256, //maps to "W" key (up)
  2991. //Button_F = 512, //maps to "A" key (Left)
  2992. //Button_G = 1024, //maps to "S" key (Down)
  2993. //Button_H=2048, //maps to "D" key (Right)*/
  2994. }
  2995. private ButtonConstants MouseButtonToGameButton(MouseButtons mousebut)
  2996. {
  2997. switch (mousebut)
  2998. {
  2999. case MouseButtons.Left:
  3000. return ButtonConstants.Button_A;
  3001. case MouseButtons.Right:
  3002. return ButtonConstants.Button_B;
  3003. case MouseButtons.Middle:
  3004. return ButtonConstants.Button_C;
  3005. }
  3006. return 0;
  3007. }
  3008. private void PicGame_MouseDown(object sender, MouseEventArgs e)
  3009. {
  3010. PointF clickpos = ScalePosition(new PointF(e.X, e.Y));
  3011. AccelerateCountdown = true;
  3012. if (gamerunstate is StateMenu)
  3013. {
  3014. var hitmenu = menudata.HitTest(mGameState, clickpos);
  3015. if (hitmenu != null)
  3016. {
  3017. hitmenu.InvokeItemChosen();
  3018. }
  3019. }
  3020. if (!(gamerunstate is StateRunning)) return;
  3021. if (SpawnItemType != null)
  3022. {
  3023. GameObject addobject = (GameObject)Activator.CreateInstance(SpawnItemType, new object[]{clickpos, new SizeF(16, 16)}); //new Shell(e.Location, new SizeF(16, 16));
  3024. mGameState.GameObjects.AddLast(addobject);
  3025. }
  3026. FireButtonDown(new ButtonEventArgs<bool>(MouseButtonToGameButton(e.Button)));
  3027. //mGameState.GameObjects.AddLast(new Laser(new PointF(mGameState.PlayerPaddle.Position.X,mGameState.PlayerPaddle.Getrect().Top),mGameState));
  3028. }
  3029. private void PicGame_MouseClick(object sender, MouseEventArgs e)
  3030. {
  3031. PointF clickpos = ScalePosition(new PointF(e.X, e.Y));
  3032. //
  3033. //quick test of the AnimatedSprite class...
  3034. //AnimatedSprite testsprite = new AnimatedSprite(new PointF(e.X-8, e.Y-8), BCBlockGameState.Imageman.getImageFrames("testdebris"), 0, 5,3);
  3035. //add it in there
  3036. if (hitscanner)
  3037. {
  3038. HitscanBullet hsb = new HitscanBullet(clickpos, new PointF(0, -2));
  3039. hsb.Penetrate = false;
  3040. mGameState.NextFrameCalls.Enqueue(new BCBlockGameState.NextFrameStartup(() => mGameState.GameObjects.AddLast(hsb)));
  3041. }
  3042. // mGameState.GameObjects.AddLast(testsprite);
  3043. if (RightClickRestart && e.Button == MouseButtons.Right)
  3044. {
  3045. RightClickRestart = false;
  3046. mPlayingSet = restartset;
  3047. DemoMode = false;
  3048. //PlayLevel(mGameState, restartset.Levels[0]);
  3049. mPlayingLevel = 1;
  3050. StartGame(restartset, 1);
  3051. return;
  3052. }
  3053. if (DemoMode) return;
  3054. if (mGameState == null) return;
  3055. if (AvailableClientArea.Contains(e.Location))
  3056. {
  3057. lock (mGameState)
  3058. {
  3059. if (BCBlockGameState.CheatSet(BCBlockGameState.BBlockCheatMode.Cheats_Ballability))
  3060. {
  3061. cBall addme = new cBall(clickpos, new PointF(1, 1));
  3062. mGameState.Balls.AddLast(addme);
  3063. }
  3064. else
  3065. {
  3066. //add our silly test enemy
  3067. // mGameState.GameObjects.AddLast(new SillyFace(new PointF(e.Location.X, e.Location.Y)));
  3068. //if(KeyboardInfo.GetKeyState(Keys.ShiftKey).IsPressed)
  3069. // mGameState.GameObjects.AddLast(new MegamanTest(new PointF(e.Location.X, e.Location.Y)));
  3070. //mGameState.GameObjects.AddLast(new ChomperEnemy(new PointF(e.Location.X,e.Location.Y),15));
  3071. //mGameState.GameObjects.AddLast(new EyeGuy(new PointF(e.Location.X, e.Location.Y),new SizeF(32,32)));
  3072. }
  3073. }
  3074. }
  3075. }
  3076. private bool AltPressed=false,ControlPressed=false,ShiftPressed=false;
  3077. private void CheatInputRoutine(ref String InputText)
  3078. {
  3079. RecentCheats.Add(InputText);
  3080. if (ProcessCheat(InputText))
  3081. BCBlockGameState.Soundman.PlaySound("right", 1.0f);
  3082. else
  3083. BCBlockGameState.Soundman.PlaySound("wrong", 1.0f);
  3084. if ((!ControlPressed) && gamerunstate is StateValueInput) gamerunstate = new StateRunning();
  3085. }
  3086. private void CheatEntryMode()
  3087. {
  3088. gamerunstate = new StateValueInput(new ValueInputData(CheatInputRoutine, "Enter Cheat Code", null, ValueInputPaintTypeConstants.paint_Pre, null), new ValueInputTextData() { Text = "", SelStart = 0 });
  3089. }
  3090. private void HiScoreGameProc()
  3091. {
  3092. Debug.Print("HiScoreGameProc");
  3093. if ((DateTime.Now - lastHSProc).TotalMilliseconds >= 150)
  3094. {
  3095. if (!(ActiveState is StateValueInput)) return;
  3096. StateValueInput svi = (StateValueInput)ActiveState;
  3097. currentHue = (currentHue+1)%240;
  3098. lastHSProc = DateTime.Now;
  3099. svi.TitleColour = new HSLColor(((float)currentHue), 240f, 120f);
  3100. }
  3101. }
  3102. private DateTime lastHSProc=DateTime.Now;
  3103. private int currentHue = 0;
  3104. private void HiScorePaint(Graphics g, ValueInputData inputdata, ValueInputTextData CurrentTextData)
  3105. {
  3106. Debug.Print("HiScorePaint currenthue=" + currentHue);
  3107. Color paintcolor = new HSLColor(((float)currentHue), 240f, 120f);
  3108. //g.FillRectangle(new SolidBrush(Color.FromArgb(128, paintcolor)), 0, 0, mGameState.GameArea.Width, mGameState.GameArea.Height);
  3109. Brush usebrush = new SolidBrush(Color.FromArgb(180, paintcolor));
  3110. var ga = mGameState.GameArea;
  3111. g.FillRectangle(usebrush, 0, 0, 16, ga.Height);
  3112. g.FillRectangle(usebrush, 16, 0,ga.Width, 16);
  3113. g.FillRectangle(usebrush, ga.Width - 16, 16, 16, ga.Height);
  3114. g.FillRectangle(usebrush, 16, ga.Height - 16, ga.Width, 16);
  3115. }
  3116. private void HighScoreEntryMode(int Position,String sDefaultText,int sDefaultPosition = -1)
  3117. {
  3118. if (sDefaultPosition == -1) sDefaultPosition = sDefaultText.Length;
  3119. //stop the music...
  3120. var inputdata = new ValueInputData(HiscoreEntryCompletion, "High Score!(" + Position + ") Enter Your Name:",HiScorePaint,ValueInputPaintTypeConstants.paint_Post,HiScoreGameProc);
  3121. var DefaultSetting = new ValueInputTextData() { Text = sDefaultText, SelStart=sDefaultPosition };
  3122. BCBlockGameState.Soundman.StopMusic();
  3123. BCBlockGameState.Soundman.PlaySound("win", false);
  3124. gamerunstate = new StateValueInput(inputdata,DefaultSetting);
  3125. HighScorePos = Position;
  3126. EnterHiScore=mGameState.GameScore;
  3127. }
  3128. private int HighScorePos = 0;
  3129. private long EnterHiScore = 0;
  3130. private void HiscoreEntryCompletion(ref String hiscoreEntered)
  3131. {
  3132. String PlayerName = BCBlockGameState.Settings.PlayerName;
  3133. Debug.Print("HiScoreEntryCompletion: " + hiscoreEntered + " Score:" + EnterHiScore);
  3134. Debug.Print("Highscore applied to LevelSet:" + mPlayingSet.SetName);
  3135. var scoreentry = mPlayingSet.HighScores.Submit(hiscoreEntered, (int)mGameState.GameScore);
  3136. //don't show highscores...
  3137. //frmhighscores hscores = new frmhighscores(mPlayingSet.HighScores, "BASeBlock High Scores (" + mPlayingSet.SetName + ")");
  3138. //this.Invoke((MethodInvoker)(() => { hscores.ShowDialog(this); }));
  3139. forcegameover();
  3140. gamerunstate = new StateLevelOutroGameOver();
  3141. }
  3142. private void frmBaseBlock_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
  3143. {
  3144. if (gamerunstate is StateLevelOutroGameOver)
  3145. {
  3146. if(ControlPressed && AltPressed && e.KeyCode==Keys.H)
  3147. {
  3148. //Erase the high scores for ActualPlaySet.
  3149. //ActualPlaySet
  3150. BCBlockGameState.Soundman.PlaySound("GREN");
  3151. ActualPlaySet.HighScores.FillWithProxyData();
  3152. mPlayingSet = ActualPlaySet;
  3153. forcegameover();
  3154. }
  3155. }
  3156. if(DemoMode) return;
  3157. AltPressed = e.Alt;
  3158. ControlPressed = e.Control;
  3159. ShiftPressed=e.Shift;
  3160. if (gamerunstate is StateRunning)
  3161. {
  3162. if (e.Alt && e.Control && e.KeyCode == Keys.C)
  3163. {
  3164. //pause the game thread...
  3165. currentcheatsel = RecentCheats.Count + 1;
  3166. CheatEntryMode();
  3167. }
  3168. else if (e.Alt && e.Control && e.KeyCode == Keys.K)
  3169. {
  3170. //SUICIDE
  3171. ProcessCheat("kill");
  3172. }
  3173. else if (e.KeyCode == Keys.Pause)
  3174. {
  3175. //pause the game.
  3176. //gamerunstate=GameRunStateConstants.Game_Paused;
  3177. PauseGame();
  3178. }
  3179. }
  3180. else if (gamerunstate is StatePaused)
  3181. {
  3182. if (e.KeyCode == Keys.Pause)
  3183. {
  3184. //Unpause the game.
  3185. //gamerunstate = GameRunStateConstants.Game_Running;
  3186. UnpauseGame();
  3187. }
  3188. }
  3189. else if (gamerunstate is StateValueInput)
  3190. {
  3191. //valid keys during cheat input- up and down to scroll through previous entries.
  3192. StateValueInput InputState = (StateValueInput)ActiveState;
  3193. if(e.KeyCode == Keys.Up || e.KeyCode== Keys.Down)
  3194. {
  3195. switch (e.KeyCode)
  3196. {
  3197. case Keys.Up:
  3198. currentcheatsel--;
  3199. if (currentcheatsel < 0) currentcheatsel = 0;
  3200. break;
  3201. case Keys.Down:
  3202. currentcheatsel++;
  3203. if (currentcheatsel > RecentCheats.Count) currentcheatsel = RecentCheats.Count;
  3204. break;
  3205. }
  3206. if (RecentCheats.Count > 0)
  3207. {
  3208. currentcheatsel = BCBlockGameState.ClampValue(currentcheatsel, 0, RecentCheats.Count - 1);
  3209. String usetext = RecentCheats[currentcheatsel];
  3210. InputState.CurrentValue.Text = usetext;
  3211. InputState.CurrentValue.SelStart = usetext.Length;
  3212. }
  3213. }
  3214. else if (e.KeyCode == Keys.Left || e.KeyCode == Keys.Right)
  3215. {
  3216. switch (e.KeyCode)
  3217. {
  3218. case Keys.Left:
  3219. //left arrow
  3220. //move back one position, unless the current position is already zero.
  3221. //play shootfail in that case.
  3222. if (InputState.CurrentValue.SelStart <= 0)
  3223. BCBlockGameState.Soundman.PlaySound("SHOOTFAIL", 1.0f);
  3224. else
  3225. {
  3226. InputState.CurrentValue.SelStart--; //move back one.
  3227. }
  3228. break;
  3229. case Keys.Right:
  3230. //right arrow
  3231. if (InputState.CurrentValue.SelStart >= InputState.CurrentValue.Text.Length)
  3232. BCBlockGameState.Soundman.PlaySound("SHOOTFAIL", 1.0f);
  3233. else
  3234. InputState.CurrentValue.SelStart++;
  3235. break;
  3236. }
  3237. }
  3238. }
  3239. }
  3240. private void frmBaseBlock_KeyPress(object sender, KeyPressEventArgs e)
  3241. {
  3242. if(DemoMode) return;
  3243. if (gamerunstate is StateValueInput)
  3244. {
  3245. StateValueInput InputState = (StateValueInput)ActiveState;
  3246. if (((int) e.KeyChar) == 8)
  3247. {
  3248. //backspace...
  3249. Debug.Print("Backspace pressed.");
  3250. if (InputState.CurrentValue.Text.Length > 0 && InputState.CurrentValue.SelStart > 0) //idiot check. (can't remove a char from an empty string...)
  3251. //delete the character behind the selection.
  3252. if (InputState.CurrentValue.SelStart < InputState.CurrentValue.Text.Length)
  3253. InputState.CurrentValue.Text = InputState.CurrentValue.Text.Substring(0, InputState.CurrentValue.SelStart - 1) + InputState.CurrentValue.Text.Substring(InputState.CurrentValue.SelStart + 1);
  3254. else
  3255. InputState.CurrentValue.Text = InputState.CurrentValue.Text.Substring(0, InputState.CurrentValue.Text.Length - 1);
  3256. InputState.CurrentValue.SelStart--; //move selection back one.
  3257. }
  3258. else if ((((int)e.KeyChar) == 13)||(((int)e.KeyChar) == 10))
  3259. {
  3260. //MessageBox.Show("here we would process " + VInput.Text + " as a cheat.");
  3261. //VInput.Text = "";
  3262. /*
  3263. RecentCheats.Add(VInput.Text);
  3264. if (ProcessCheat(VInput.Text))
  3265. BCBlockGameState.Soundman.PlaySound("right",1.0f);
  3266. else
  3267. BCBlockGameState.Soundman.PlaySound("wrong", 1.0f);
  3268. VInput.Text = "";
  3269. * */
  3270. InputState.InputData.CompletionRoutine(ref InputState.CurrentValue.Text);
  3271. //if(!ControlPressed) gamerunstate = GameRunStateConstants.Game_Running;
  3272. }
  3273. else
  3274. {
  3275. if (InputState.CurrentValue.SelStart < 0) InputState.CurrentValue.SelStart = 0;
  3276. if (InputState.CurrentValue.SelStart > InputState.CurrentValue.Text.Length) InputState.CurrentValue.SelStart = InputState.CurrentValue.Text.Length;
  3277. //insert at appropriate position.
  3278. InputState.CurrentValue.Text = InputState.CurrentValue.Text.Substring(0, InputState.CurrentValue.SelStart) + e.KeyChar.ToString() + InputState.CurrentValue.Text.Substring(InputState.CurrentValue.SelStart);
  3279. //VInput.Text += e.KeyChar;
  3280. Debug.Print("VInput.Text=" + InputState.CurrentValue.Text + " char pressed was code " + ((int)e.KeyChar).ToString());
  3281. //increment position as well.
  3282. InputState.CurrentValue.SelStart++;
  3283. }
  3284. }
  3285. }
  3286. private int findstringindex(String[] arraylook, String searchfor,out String Parameter)
  3287. {
  3288. Parameter="";
  3289. for (int i = 0; i < arraylook.Length; i++)
  3290. {
  3291. //if(arraylook[i].Equals(searchfor,StringComparison.OrdinalIgnoreCase))
  3292. if (searchfor.StartsWith(arraylook[i], StringComparison.OrdinalIgnoreCase))
  3293. {
  3294. Parameter = searchfor.Substring(arraylook[i].Length).Trim();
  3295. return i;
  3296. }
  3297. }
  3298. return -1;
  3299. }
  3300. private bool ProcessCheat(IEnumerable<string> cheats)
  3301. {
  3302. bool retval=false;
  3303. foreach (String Processme in cheats)
  3304. {
  3305. retval = retval || ProcessCheat(Processme);
  3306. }
  3307. return retval;
  3308. }
  3309. private bool ProcessCheat(String cheattext)
  3310. {
  3311. //same recursive definition for semicolons as well.
  3312. if (cheattext.Contains(";"))
  3313. {
  3314. return ProcessCheat(cheattext.Split(';'));
  3315. }
  3316. String[] splitcheat = cheattext.Split(' ');
  3317. Cheat acquirecheat = Cheat.GetCheat(splitcheat[0]);
  3318. if (acquirecheat == null)
  3319. {
  3320. return OldProcessCheat(cheattext);
  3321. }
  3322. //remove the first element from the string array.
  3323. splitcheat = new List<String>(splitcheat.Skip(1)).ToArray();
  3324. //call the cheat we acquired.
  3325. return acquirecheat.ApplyCheat(mGameState,splitcheat.Length, splitcheat);
  3326. }
  3327. //the old cheat routine.
  3328. private bool OldProcessCheat(String cheattext)
  3329. {
  3330. if (cheattext.Contains(";"))
  3331. {
  3332. ProcessCheat(cheattext.Split(';'));
  3333. }
  3334. String[] Cheatcodes = new string[] {"The Null Cheat","Thats a paddlin","playmusic","getmewet","bombsaway",
  3335. "imbored","speedmeup","itgrewonme","ifeelthepower","powerhascorruptedme","saveset","openset","lonely",
  3336. "removeblocks","replaceblocks","whatisthepoint","terminated","gimmeastar","flushing meadows","nibbles.bas",
  3337. "testtrigger","astickysituation","warpto","spawnpowerup","message","onetotransport","suzieq","kerplode","makenoise","showscores","points",
  3338. "setspeed","kill","spawner","fbomb","doskey","macguffins","namco","changeblock","settempo",
  3339. "dumpclasses","hitscan","changebg","bouncer","dumpgameobjects","eyeboss","dnkroz","dumpstats","firework"};
  3340. String paramgot;
  3341. int cheatcode = findstringindex(Cheatcodes, cheattext,out paramgot);
  3342. try
  3343. {
  3344. switch (cheatcode)
  3345. {
  3346. case 0:
  3347. break;
  3348. case 1:
  3349. //mGameState.PlayerPaddle.PaddleSize.Width *= 1.1;
  3350. mGameState.PlayerPaddle.PaddleSize = new SizeF(mGameState.PlayerPaddle.PaddleSize.Width * 1.5f, mGameState.PlayerPaddle.PaddleSize.Height);
  3351. break;
  3352. case 2:
  3353. try
  3354. {
  3355. BCBlockGameState.Soundman.PlayMusic(paramgot, 1.0f, true);
  3356. }
  3357. catch
  3358. {
  3359. return false;
  3360. }
  3361. break;
  3362. case 3:
  3363. //getmewet
  3364. //replace all blocks in the arena with a water block.
  3365. /*List<Block> newblocks = new List<Block>();
  3366. foreach (Block loopblock in mGameState.Blocks)
  3367. {
  3368. if(!loopblock.BlockRectangle.IsEmpty)
  3369. newblocks.AddLast(new WaterBlock(loopblock.BlockRectangle));
  3370. }
  3371. mGameState.Blocks=newblocks;
  3372. */
  3373. ReplaceBlocks((w) => new WaterBlock(w.BlockRectangle));
  3374. break;
  3375. case 4:
  3376. //Bombsaway, replae all blocks in arena with bomb blocks.
  3377. ReplaceBlocks((w) => new BombBlock(w.BlockRectangle));
  3378. break;
  3379. case 5:
  3380. //imbored
  3381. mGameState.invokeLevelComplete();
  3382. break;
  3383. case 6:
  3384. //speedmeup
  3385. ReplaceBlocks((w) => new SpeedBallBlock(w.BlockRectangle));
  3386. break;
  3387. case 7:
  3388. //itgrewonme
  3389. ReplaceBlocks((w) => new GrowBlock(w.BlockRectangle));
  3390. break;
  3391. case 8:
  3392. //give all balls the powerball behaviour.
  3393. foreach (cBall loopball in mGameState.Balls)
  3394. {
  3395. if (!loopball.hasBehaviour(typeof(PowerBallBehaviour)))
  3396. loopball.Behaviours.Add(new PowerBallBehaviour());
  3397. }
  3398. break;
  3399. case 9:
  3400. //remove all powerballbehaviours from all balls.
  3401. //powerhascorruptedme
  3402. foreach (cBall loopball in mGameState.Balls)
  3403. {
  3404. if (loopball.hasBehaviour(typeof(PowerBallBehaviour)))
  3405. {
  3406. loopball.Behaviours.RemoveAll((w) => w.GetType() == typeof(PowerBallBehaviour));
  3407. }
  3408. }
  3409. break;
  3410. case 10: //saveset
  3411. //SaveCurrentSet();
  3412. break;
  3413. case 11:
  3414. //openset
  3415. // OpenCurrentSet();
  3416. break;
  3417. case 12:
  3418. bool returnblock = false;
  3419. ReplaceBlocks((w) =>
  3420. {
  3421. if (returnblock) return null;
  3422. returnblock = true;
  3423. mGameState.Balls.AddLast(new cBall(new PointF(w.BlockRectangle.Left, w.BlockRectangle.Top), new PointF(2, 2)));
  3424. return w;
  3425. });
  3426. break;
  3427. case 13:
  3428. //removeblocks; use paramgot and remove all blocks that are of that typename.
  3429. String removetype = paramgot.Trim();
  3430. if (removetype.Length > 0)
  3431. {
  3432. //here is the issue: we want them to be able to simply say "Waterblock" or "StrongBlock" rather then "BASeBlock.WaterBlock"... first, see if they provided a "qualified" name...
  3433. ReplaceBlocks((w) =>
  3434. {
  3435. if (w.GetType().Name.Equals(removetype, StringComparison.OrdinalIgnoreCase))
  3436. return null;
  3437. else
  3438. return w;
  3439. });
  3440. }
  3441. break;
  3442. case 14:
  3443. //replaceblocks
  3444. String[] splitit = paramgot.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
  3445. try
  3446. {
  3447. String findtype = splitit[0];
  3448. string replacetype = splitit[1];
  3449. Type replaceT = BCBlockGameState.FindClass(replacetype);
  3450. if (findtype.Length > 0 && replacetype.Length > 0 && replaceT != null)
  3451. {
  3452. ReplaceBlocks((w) =>
  3453. {
  3454. if (w.GetType().Name.Equals(findtype,
  3455. StringComparison.OrdinalIgnoreCase))
  3456. return
  3457. (Block)
  3458. Activator.CreateInstance(replaceT,
  3459. new Object[] { w.BlockRectangle });
  3460. else
  3461. return w;
  3462. });
  3463. }
  3464. else
  3465. {
  3466. return false;
  3467. }
  3468. }
  3469. catch (Exception q)
  3470. {
  3471. Debug.Print("Unexpected exception:" + q.Message);
  3472. }
  3473. break;
  3474. case 15:
  3475. //whatisthepoint.
  3476. //mGameState.Balls.Clear();
  3477. mGameState.playerLives = 0;
  3478. foreach (cBall loopball in mGameState.Balls)
  3479. {
  3480. loopball.Location = new PointF(AvailableClientArea.Width / 2, AvailableClientArea.Height);
  3481. loopball.Velocity = new PointF(0, 5);
  3482. }
  3483. //GameOver();
  3484. break;
  3485. case 16:
  3486. //terminated... add terminator powerup to paddle.
  3487. if (mGameState.PlayerPaddle != null)
  3488. {
  3489. if (mGameState.PlayerPaddle.Behaviours.Any((w) => w.GetType() == typeof(PaddleBehaviours.TerminatorBehaviour)))
  3490. {
  3491. ((PaddleBehaviours.TerminatorBehaviour)mGameState.PlayerPaddle.Behaviours.First((w) => w.GetType() == typeof(PaddleBehaviours.TerminatorBehaviour))).PowerLevel++;
  3492. }
  3493. mGameState.PlayerPaddle.Behaviours.Add(new PaddleBehaviours.TerminatorBehaviour(mGameState));
  3494. }
  3495. break;
  3496. case 17:
  3497. //gimmeastar
  3498. Debug.Print("Star given." + mGameState.NumCompletions++.ToString());
  3499. mGameState.NumCompletions++;
  3500. sidebarbgdrawn = false; //make it redraw...
  3501. break;
  3502. case 18:
  3503. BCBlockGameState.Soundman.PlaySound("TFLUSH", 1.5f);
  3504. break;
  3505. case 19:
  3506. //nibbles.bas
  3507. String snaketype = paramgot.Trim();
  3508. Type snakeblocktype;
  3509. if (!String.IsNullOrEmpty(snaketype))
  3510. {
  3511. snakeblocktype = BCBlockGameState.FindClass(snaketype);
  3512. if (snakeblocktype == null)
  3513. {
  3514. return false;
  3515. }
  3516. }
  3517. else
  3518. {
  3519. snakeblocktype = typeof(NormalBlock);
  3520. }
  3521. mGameState.GameObjects.AddLast(new SnakeEnemy(new PointF(AvailableClientArea.Width / 2, AvailableClientArea.Height / 2), 100, snakeblocktype));
  3522. break;
  3523. case 20:
  3524. StringBuilder resstring = new StringBuilder();
  3525. foreach (Block loopblock in mGameState.Blocks)
  3526. {
  3527. if (loopblock.BlockTriggers.Count != 0)
  3528. {
  3529. resstring.AppendLine("Block with Trigger, Value=" + loopblock.BlockTriggers.Count());
  3530. }
  3531. }
  3532. MessageBox.Show("Triggers:" + resstring.ToString());
  3533. break;
  3534. case 21: //astickysituation
  3535. if (mGameState.PlayerPaddle != null)
  3536. {
  3537. mGameState.PlayerPaddle.Behaviours.Add(new PaddleBehaviours.StickyBehaviour(mGameState));
  3538. }
  3539. break;
  3540. case 22:
  3541. //warpto
  3542. int gotlevelindex = -1;
  3543. paramgot = paramgot.ToUpper();
  3544. if (!(Int32.TryParse(paramgot, out gotlevelindex)))
  3545. {
  3546. foreach (Level uselevel in (from j in mPlayingSet.Levels where j.LevelName.ToUpper() == paramgot select j))
  3547. {
  3548. gotlevelindex = mPlayingSet.Levels.IndexOf(uselevel);
  3549. }
  3550. }
  3551. if (gotlevelindex != 0)
  3552. {
  3553. gotlevelindex = BCBlockGameState.ClampValue(gotlevelindex, 0, mPlayingSet.Levels.Count);
  3554. PlayLevel(mGameState, mPlayingSet.Levels[gotlevelindex]);
  3555. }
  3556. break;
  3557. case 23:
  3558. //spawnpowerup: paramgot will be the name of the powerup to instantiate.
  3559. //plop it in the middle, also.
  3560. Type spawntype = BCBlockGameState.FindClass(paramgot.Trim());
  3561. if (spawntype == null) return false;
  3562. //use spawntype to create a powerup. Location (PointF) and Size (SizeF)
  3563. PointF centpoint = mGameState.GameArea.CenterPoint();
  3564. GamePowerUp createpowerup = Activator.CreateInstance(spawntype, new Object[] { centpoint, new SizeF(16, 8) }) as GamePowerUp;
  3565. //check for null... again...
  3566. if (createpowerup == null) return false;
  3567. //otherwise, Add it
  3568. mGameState.GameObjects.AddLast(createpowerup);
  3569. break;
  3570. case 24:
  3571. //message
  3572. mGameState.EnqueueMessage(paramgot);
  3573. break;
  3574. case 25:
  3575. //onetotransport
  3576. Debug.Print("One To Transport!");
  3577. String[] Levelnames = (from n in mPlayingSet.Levels select n.LevelName).ToArray();
  3578. Level[] thelevels = (from n in mPlayingSet.Levels select n).ToArray();
  3579. EnterMenu(Levelnames,warpchosen, thelevels);
  3580. break;
  3581. case 26:
  3582. //suzieq
  3583. mGameState.EnqueueMessage("Suzie Q has entered the game.");
  3584. mGameState.GameObjects.AddLast(new EyeGuy(new PointF(AvailableClientArea.Width / 2, AvailableClientArea.Height / 2)));
  3585. break;
  3586. case 27:
  3587. //kerplode
  3588. if (!String.IsNullOrEmpty(paramgot))
  3589. {
  3590. String[] splitvalues = paramgot.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
  3591. Type[] grabentry = (from m in splitvalues select BCBlockGameState.FindClass(m)).ToArray();
  3592. mGameState.KerploderFind = grabentry[0];
  3593. if (grabentry.Length > 1)
  3594. mGameState.KerploderReplace = grabentry[1];
  3595. }
  3596. else
  3597. {
  3598. mGameState.KerploderReplace = mGameState.KerploderFind = null;
  3599. }
  3600. if ((BCBlockGameState.CheatMode & BCBlockGameState.BBlockCheatMode.Cheats_kerploder) == BCBlockGameState.BBlockCheatMode.Cheats_kerploder)
  3601. {
  3602. //remove
  3603. //BCBlockGameState.BBlockCheatMode.Cheats_kerploder
  3604. BCBlockGameState.CheatMode &= ~BCBlockGameState.BBlockCheatMode.Cheats_kerploder;
  3605. mGameState.EnqueueMessage("kerploder disabled.");
  3606. }
  3607. else
  3608. {
  3609. BCBlockGameState.CheatMode |= BCBlockGameState.BBlockCheatMode.Cheats_kerploder;
  3610. mGameState.EnqueueMessage("kerploder enabled.");
  3611. }
  3612. break;
  3613. case 28:
  3614. //makenoise
  3615. String soundemit = paramgot;
  3616. var gotsound = BCBlockGameState.Soundman.PlaySound(soundemit);
  3617. if (gotsound == null) return false;
  3618. break;
  3619. case 29:
  3620. //showscores, paramgot is name of set, or use current set if none specified.
  3621. String showscoreforset = mPlayingSet.SetName;
  3622. if (paramgot != "")
  3623. {
  3624. showscoreforset = paramgot;
  3625. }
  3626. //grab it
  3627. var grabscoreset = BCBlockGameState.Scoreman.getScoreForSetName(showscoreforset);
  3628. break;
  3629. case 30:
  3630. //points
  3631. float multiplier = 1.0f;
  3632. float.TryParse(paramgot, out multiplier);
  3633. mGameState.GameScore += (long)(5000 * multiplier);
  3634. break;
  3635. case 31:
  3636. //setspeed X Y
  3637. try
  3638. {
  3639. String[] splittered = paramgot.Split(' ');
  3640. float useX = float.Parse(splittered[0]);
  3641. float useY = float.Parse(splittered[1]);
  3642. foreach (cBall loopball in mGameState.Balls)
  3643. {
  3644. loopball.Velocity = new PointF(useX, useY);
  3645. }
  3646. break;
  3647. }
  3648. catch
  3649. {
  3650. return false;
  3651. }
  3652. case 32:
  3653. //kill
  3654. //have a little showmanship. make a small explosion at each ball.
  3655. lock (mGameState.GameObjects)
  3656. {
  3657. foreach (cBall loopball in mGameState.Balls)
  3658. {
  3659. ExplosionEffect ee = new ExplosionEffect(loopball.Location, 16);
  3660. mGameState.GameObjects.AddLast(ee);
  3661. }
  3662. }
  3663. mGameState.Balls.Clear();
  3664. break;
  3665. case 33:
  3666. //spawner <classname>
  3667. String classnamestr = paramgot.Trim();
  3668. Type getclass = BCBlockGameState.FindClass(classnamestr);
  3669. SpawnItemType = getclass;
  3670. break;
  3671. case 34:
  3672. //fbomb: spawn a frustratorball.
  3673. FrustratorBall fb = new FrustratorBall(new PointF(mGameState.GameArea.Width / 2, mGameState.GameArea.Height - 64), new PointF(2, 2));
  3674. mGameState.Balls.AddLast(fb);
  3675. break;
  3676. case 35:
  3677. //doskey
  3678. String populatefrom = paramgot.Trim();
  3679. DirectoryInfo di = new DirectoryInfo(populatefrom);
  3680. foreach (FileInfo fi in di.GetFiles())
  3681. {
  3682. if (fi.Extension.ToUpper() == ".MP3" || fi.Extension.ToUpper() == ".OGG")
  3683. {
  3684. RecentCheats.Add("PLAYMUSIC " + fi.FullName);
  3685. }
  3686. }
  3687. break;
  3688. case 36:
  3689. //MacGuffins
  3690. //spawn a LOT of macguffins.
  3691. //from the middle of the level-
  3692. PointF SpawnPosition = new PointF(mGameState.GameArea.Width / 2, mGameState.GameArea.Height / 2);
  3693. for (int i = 0; i < 500; i++)
  3694. {
  3695. MacGuffinOrb mgo = new MacGuffinOrb(SpawnPosition);
  3696. mgo.MacGuffinValue = BCBlockGameState.rgen.Next(0, 6);
  3697. mGameState.GameObjects.AddLast(mgo);
  3698. }
  3699. mGameState.EnqueueMessage("MACGUFFINS FOR ALL!");
  3700. break;
  3701. case 37:
  3702. //namco
  3703. ChomperEnemy co = new ChomperEnemy(new PointF(mGameState.GameArea.Width / 2, mGameState.GameArea.Height / 2), 16);
  3704. mGameState.GameObjects.AddLast(co);
  3705. break;
  3706. case 38:
  3707. //changeblock
  3708. //syntax: changeblock <number> <newtype>
  3709. //changes the given block into the new type. the number should correspond to the number that DebugHelper gives, which
  3710. //is it's location in the linkedlist.
  3711. //first: parse the parameters.
  3712. lock (mGameState.Blocks)
  3713. {
  3714. String[] changeparameters = paramgot.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
  3715. int blockindex = int.Parse(changeparameters[0]);
  3716. //we use Parse rather than tryparse, since the exception will do what we would want in that case anyway (return false).
  3717. //retrieve the block type the replace it with.
  3718. String newblocktypestring = changeparameters[1].Trim();
  3719. //get the actual type...
  3720. Type newblocktype = BCBlockGameState.FindClass(newblocktypestring);
  3721. if (newblocktype == null)
  3722. {
  3723. mGameState.EnqueueMessage("Type \"" + newblocktypestring + "\" not valid.");
  3724. return false; //if block type was not valid, return false.
  3725. }
  3726. //otherwise, we now find the appropriate indexed block.
  3727. //if the given index exceeds the bounds, show a message and return false.
  3728. if (blockindex > mGameState.Blocks.Count - 1)
  3729. {
  3730. mGameState.EnqueueMessage("Index " + blockindex + " exceeds number of blocks.");
  3731. }
  3732. Block replaceblock = mGameState.Blocks.ElementAt(blockindex);
  3733. //now, construct the replacement block...
  3734. Block replacewith = (Block)Activator.CreateInstance(newblocktype, replaceblock.BlockRectangle);
  3735. //out with the old...
  3736. //and in with the new!
  3737. mGameState.Blocks.AddAfter(mGameState.Blocks.Find(replaceblock),replacewith);
  3738. mGameState.Blocks.Remove(replaceblock);
  3739. //set flag to refresh, as well.
  3740. mGameState.Forcerefresh = true;
  3741. }
  3742. break;
  3743. case 39:
  3744. //settempo
  3745. float useparam = float.Parse(paramgot);
  3746. var acquire = BCBlockGameState.Soundman.GetPlayingMusic_Active();
  3747. if (acquire != null)
  3748. Debug.Print("Set Tempo to " + useparam);
  3749. acquire.Tempo = useparam;
  3750. break;
  3751. case 40:
  3752. //dumpclasses.
  3753. dumpclasses(paramgot);
  3754. break;
  3755. case 41:
  3756. //hitscan
  3757. hitscanner = !hitscanner;
  3758. break;
  3759. case 42:
  3760. //changebg
  3761. String usename = paramgot;
  3762. if (BCBlockGameState.Imageman.HasImage(usename))
  3763. {
  3764. //if so, change to that as the background image.
  3765. var newbg = new BackgroundColourImageDrawer(usename);
  3766. newbg.RotateOrigin=PointF.Empty;
  3767. newbg.RotateSpeed=0;
  3768. newbg.MoveVelocity = PointF.Empty;
  3769. mGameState.NextFrameCalls.Enqueue(new BCBlockGameState.NextFrameStartup(() =>
  3770. {
  3771. mGameState.BackgroundDraw = newbg;
  3772. mGameState.Forcerefresh = true;
  3773. Dorefreshstats = true;
  3774. mRedrawAnimated = true;
  3775. mredrawblocks = true;
  3776. }));
  3777. }
  3778. else if (File.Exists(usename))
  3779. {
  3780. String newitem = BCBlockGameState.Imageman.AddFromFile(usename);
  3781. var newbg = new BackgroundColourImageDrawer(newitem);
  3782. mGameState.NextFrameCalls.Enqueue(new BCBlockGameState.NextFrameStartup(() =>
  3783. {
  3784. mGameState.BackgroundDraw = newbg;
  3785. mGameState.Forcerefresh = true;
  3786. Dorefreshstats = true;
  3787. mRedrawAnimated = true;
  3788. mredrawblocks = true;
  3789. }));
  3790. }
  3791. break;
  3792. case 43:
  3793. mGameState.GameObjects.AddLast(new BouncerGuy(new PointF(AvailableClientArea.Width / 2, AvailableClientArea.Height / 2)));
  3794. break;
  3795. case 44:
  3796. if (File.Exists(paramgot)) File.Delete(paramgot);
  3797. StreamWriter sw = new StreamWriter(paramgot);
  3798. foreach (var iterate in mGameState.GameObjects)
  3799. {
  3800. sw.WriteLine("Type:" + iterate.GetType().Name + ". " + iterate);
  3801. }
  3802. mGameState.EnqueueMessage("GameObject data dumped to \"" + paramgot + "\"");
  3803. sw.Close();
  3804. break;
  3805. case 45:
  3806. //eyeboss
  3807. //EyeGuy eyeboss = EyeGuy.CreateBoss(mGameState.GameArea.CenterPoint(),mGameState);
  3808. EyeGuy eyeboss = (EyeGuy)GameEnemy.CreateBoss<EyeGuy>(mGameState.GameArea.CenterPoint(), mGameState);
  3809. mGameState.GameObjects.AddLast(eyeboss);
  3810. break;
  3811. case 46:
  3812. //dnkroz
  3813. if (mGameState.PlayerPaddle != null)
  3814. mGameState.PlayerPaddle.Behaviours.Add(new InvinciblePaddleBehaviour());
  3815. break;
  3816. case 47:
  3817. //dumpstats
  3818. String targetfile = paramgot;
  3819. if (mPlayingSet != null)
  3820. {
  3821. using (sw = new StreamWriter(targetfile))
  3822. {
  3823. sw.WriteLine(BCBlockGameState.Statman.ToString());
  3824. }
  3825. }
  3826. mGameState.EnqueueMessage("Dumped statistics to \"" + targetfile + "\"");
  3827. break;
  3828. case 48:
  3829. //firework
  3830. DustTrail dt = new DustTrail(new PointF(mGameState.GameArea.Width / 2, mGameState.GameArea.Height), new PointF(0, -3), new TimeSpan(0, 0, 0, 2),
  3831. new FireworkEffect(typeof(MacGuffinOrb), new PointF(0, 0), 25, 20, 50, new SizeF(8, 8)));
  3832. mGameState.GameObjects.AddLast(dt);
  3833. break;
  3834. }
  3835. }
  3836. catch (Exception exx)
  3837. {
  3838. //log it.
  3839. Debug.Print(exx.ToString());
  3840. return false;
  3841. }
  3842. return (cheatcode != -1);
  3843. }
  3844. int incspawn = 0;
  3845. private bool hitscanner = false;
  3846. private Type SpawnItemType = null;
  3847. private void gameToolStripMenuItem_Click(object sender, EventArgs e)
  3848. {
  3849. }
  3850. private void dumpclasses(String targetfile)
  3851. {
  3852. int TypeCount = 0, totalcount = 0;
  3853. if (File.Exists(targetfile))
  3854. {
  3855. mGameState.EnqueueMessage("Target file already exists.");
  3856. return;
  3857. }
  3858. //otherwise, dump the data from out type manager.
  3859. using (StreamWriter sw = new StreamWriter(new FileStream(targetfile,FileMode.CreateNew)))
  3860. {
  3861. sw.WriteLine("BASeBlock Version " + BCBlockGameState.GetExecutingVersion() + " Class Dump\n\n");
  3862. foreach (var iterate in BCBlockGameState.MTypeManager.loadeddata)
  3863. {
  3864. TypeCount++;
  3865. sw.WriteLine("Type:" + iterate.Key.FullName);
  3866. foreach (Type iteratetype in iterate.Value.ManagedTypes)
  3867. {
  3868. sw.WriteLine("\tImplemented/Derived Class:" + iteratetype.FullName);
  3869. totalcount++;
  3870. }
  3871. sw.WriteLine();
  3872. }
  3873. sw.WriteLine(TypeCount.ToString() + " Types; Total of " + totalcount + " Implementations/derivations.");
  3874. sw.WriteLine("---END OF FILE--");
  3875. }
  3876. mGameState.EnqueueMessage("Types dumped to " + targetfile);
  3877. }
  3878. private void gameToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
  3879. {
  3880. demoModeToolStripMenuItem.Checked=DemoMode;
  3881. stopGameToolStripMenuItem.Enabled = (GameThread != null && GameThread.IsAlive && !(gamerunstate is StateNotRunning));
  3882. }
  3883. private void demoModeToolStripMenuItem_Click(object sender, EventArgs e)
  3884. {
  3885. DemoMode=!DemoMode;
  3886. }
  3887. #region iGameClient Members
  3888. public void RefreshDisplay()
  3889. {
  3890. PicGame.Invoke((MethodInvoker)(() =>
  3891. {
  3892. PicGame.Invalidate();
  3893. PicGame.Update();
  3894. }));
  3895. }
  3896. public Bitmap getBackgroundBitmap()
  3897. {
  3898. return backgroundbitmap;
  3899. }
  3900. public Bitmap getCanvasBitmap()
  3901. {
  3902. return mGameState.lastframeimage;
  3903. }
  3904. #endregion
  3905. #region iGameClient Members
  3906. #endregion
  3907. #region iGameClient Members
  3908. public Level getcurrentLevel()
  3909. {
  3910. return mPlayingSet.Levels[mPlayingLevel-1];
  3911. }
  3912. #endregion
  3913. #region iGameClient Members
  3914. public event EventHandler<ButtonEventArgs<bool>> ButtonDown;
  3915. public event EventHandler<ButtonEventArgs<bool>> ButtonUp;
  3916. public event EventHandler<MouseEventArgs<bool>> OnMove;
  3917. public event Func<PointF, bool> MoveAbsolute;
  3918. public void FireButtonDown(ButtonEventArgs<bool> callwith )
  3919. {
  3920. var temp = ButtonDown;
  3921. if (temp != null)
  3922. temp.Invoke(this,callwith);
  3923. }
  3924. public void FireButtonUp(ButtonEventArgs<bool> callwith )
  3925. {
  3926. var temp = ButtonUp;
  3927. if (temp != null)
  3928. temp.Invoke(this,callwith);
  3929. }
  3930. public void FireMoveAbsolute(PointF pointmove)
  3931. {
  3932. Func<PointF, bool> temp = MoveAbsolute;
  3933. if (temp != null)
  3934. temp.Invoke(pointmove);
  3935. }
  3936. public void MoveRelative(float Amount)
  3937. {
  3938. //get current paddle position.
  3939. if(mGameState==null) return;
  3940. if (mGameState.PlayerPaddle == null) return;
  3941. PointF Paddlespot = mGameState.PlayerPaddle.Position;
  3942. PointF newpos = new PointF(Paddlespot.X+Amount,Paddlespot.Y);
  3943. FireMoveAbsolute(newpos);
  3944. }
  3945. #endregion
  3946. private void PicGame_MouseUp(object sender, MouseEventArgs e)
  3947. {
  3948. AccelerateCountdown = false;
  3949. if (!(gamerunstate is StateRunning)) return;
  3950. if(((BCBlockGameState.CheatMode & BCBlockGameState.BBlockCheatMode.Cheats_kerploder) == BCBlockGameState.BBlockCheatMode.Cheats_kerploder))
  3951. {
  3952. //spawn a kerplodey thing.
  3953. if (mGameState.KerploderFind != null || mGameState.KerploderReplace != null)
  3954. {
  3955. BlockChangeEffect bce = new BlockChangeEffect(e.Location, 16, 64, mGameState.KerploderFind, mGameState.KerploderReplace);
  3956. mGameState.GameObjects.AddLast(bce);
  3957. }
  3958. else if (e.Button == MouseButtons.Left)
  3959. {
  3960. ExplosionEffect ee = new ExplosionEffect(e.Location);
  3961. mGameState.GameObjects.AddLast(ee);
  3962. }
  3963. else if (e.Button == MouseButtons.Right)
  3964. {
  3965. CreationEffect ee = new CreationEffect(new SizeF(33,16), e.Location,64);
  3966. mGameState.GameObjects.AddLast(ee);
  3967. }
  3968. }
  3969. FireButtonUp(new ButtonEventArgs<bool>(MouseButtonToGameButton(e.Button)));
  3970. }
  3971. private cNewSoundManager newmanager;
  3972. private void testNewSoundEngineToolStripMenuItem_Click(object sender, EventArgs e)
  3973. {
  3974. /*if(newmanager==null)
  3975. newmanager = new cNewSoundManager(new BASSDriver(),BCBlockGameState.GameSettings["folders"]["sound"].Value);
  3976. //newmanager.PlayMusic("ENDLESSCHALLENGE");
  3977. newmanager.PlayMusic("COMICAL4");
  3978. newmanager.GetSound("BBOUNCE").Play(false);
  3979. */
  3980. BCBlockGameState.Soundman.PlayMusic("COMICAL4");
  3981. }
  3982. private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
  3983. {
  3984. }
  3985. private void exitToolStripMenuItem_Click(object sender, EventArgs e)
  3986. {
  3987. //quit
  3988. //first, if a game is in progress, ask for confirmation.
  3989. if (mGameState != null)
  3990. {
  3991. if (!(gamerunstate is StateNotRunning) && !(gamerunstate is StateLevelOutroGameOver))
  3992. {
  3993. //pause the gameproc thread while we ask; do this by changing gamerunstate...
  3994. statebeforepause = gamerunstate;
  3995. gamerunstate = new StatePaused();
  3996. if (MessageBox.Show("There is a Game in Progress. Quit Anyway?", "Exit Game", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
  3997. {
  3998. //they said yes... abort the thread.
  3999. //high scores will not be checked when quitting.
  4000. GameThread.Abort();
  4001. }
  4002. else
  4003. {
  4004. //they decided not to quit.
  4005. return;
  4006. }
  4007. }
  4008. }
  4009. Debug.Print(Application.OpenForms.Count + " Open Forms:");
  4010. foreach (var formiterate in Application.OpenForms)
  4011. {
  4012. Debug.Print((formiterate as Form).Name);
  4013. }
  4014. Application.Exit();
  4015. }
  4016. private void highScoresToolStripMenuItem_Click(object sender, EventArgs e)
  4017. {
  4018. //testing: show net highscores for item 3;
  4019. if (mPlayingSet == null)
  4020. {
  4021. frmhighscores scoreform = new frmhighscores("BASeBlock");
  4022. scoreform.Show(this);
  4023. }
  4024. else
  4025. {
  4026. IHighScoreList scoreobject = mPlayingSet.HighScores;
  4027. frmhighscores scoreform = new frmhighscores(scoreobject,
  4028. "BASeBlock");
  4029. scoreform.Show(this);
  4030. }
  4031. }
  4032. private void saveToolStripMenuItem_Click(object sender, EventArgs e)
  4033. {
  4034. // SaveCurrentSet();
  4035. }
  4036. /*
  4037. private void SaveCurrentSet()
  4038. {
  4039. SaveFileDialog sfd = new SaveFileDialog();
  4040. sfd.Title = "Save LevelSet";
  4041. sfd.Filter = "BASeBlock Level Set File (*.LSF)|*.LSF|All Files(*.*)|*.*";
  4042. DialogResult result = sfd.ShowDialog(this);
  4043. if (result == DialogResult.Cancel)
  4044. {
  4045. return;
  4046. }
  4047. else
  4048. {
  4049. //file was selected to save to.
  4050. mPlayingSet.Save(sfd.FileName);
  4051. }
  4052. }
  4053. */
  4054. private void openToolStripMenuItem_Click(object sender, EventArgs e)
  4055. {
  4056. // OpenCurrentSet();
  4057. }
  4058. /*
  4059. private void OpenCurrentSet()
  4060. {
  4061. OpenFileDialog ofd = new OpenFileDialog();
  4062. ofd.Title = "Open Levelset";
  4063. ofd.Filter = "BASeBlock Level Set File (*.LSF)|*.LSF|All Files(*.*)|*.*";
  4064. DialogResult result = ofd.ShowDialog(this);
  4065. if(result==DialogResult.Cancel)
  4066. return;
  4067. else
  4068. {
  4069. mPlayingSet = BASeBlock.LevelSet.FromFile(ofd.FileName);
  4070. }
  4071. }
  4072. */
  4073. private bool HasAttribute(Type typecheck, Type checkforattribute)
  4074. {
  4075. return (System.Attribute.GetCustomAttributes(typecheck).Any((p) => p.GetType() == checkforattribute));
  4076. }
  4077. private void newGameToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
  4078. {
  4079. //add a new entry for each item in BCBlockGameState.Levelman
  4080. //clear current entries.
  4081. ToolStripMenuItem mitem = (ToolStripMenuItem)sender;
  4082. mitem.DropDownItems.Clear();
  4083. Debug.Print("KeyboardInfo.GetAsyncKeyState((int)Keys.ShiftKey)=" + KeyboardInfo.GetAsyncKeyState((int)Keys.ShiftKey));
  4084. foreach (Type iteratetype in BCBlockGameState.Levelman.ManagedTypes)
  4085. {
  4086. //attempt to create an instance...
  4087. if( (!(HasAttribute(iteratetype,typeof(InvisibleBuilderAttribute))) || KeyboardInfo.GetAsyncKeyState((int)Keys.ShiftKey)<0))
  4088. {
  4089. iLevelSetBuilder newinstance;
  4090. try
  4091. {
  4092. newinstance = (iLevelSetBuilder) Activator.CreateInstance(iteratetype);
  4093. }
  4094. catch
  4095. {
  4096. newinstance = null;
  4097. }
  4098. //add a new dropdown...
  4099. if (newinstance != null)
  4100. {
  4101. var newdropdown = mitem.DropDownItems.Add(newinstance.getName());
  4102. newdropdown.Tag = newinstance;
  4103. newdropdown.Click += new EventHandler(newdropdown_Click);
  4104. }
  4105. }
  4106. }
  4107. }
  4108. private void DoAutoLoad(String cmd)
  4109. {
  4110. //BCBlockGameState.Levelman.ManagedTypes
  4111. //check for /load
  4112. }
  4113. void newdropdown_Click(object sender, EventArgs e)
  4114. {
  4115. //MessageBox.Show("Create levelset from " + ((iLevelSetBuilder)((ToolStripMenuItem)sender).Tag).getName());
  4116. iLevelSetBuilder usebuilder = ((iLevelSetBuilder)((ToolStripMenuItem)sender).Tag);
  4117. gamerunstate = new StateLoading();
  4118. PicGame.Invalidate();
  4119. PicGame.Update();
  4120. LevelSet lsetuse = usebuilder.BuildLevelSet(AvailableClientArea,this);
  4121. if (lsetuse == null)
  4122. {
  4123. return;
  4124. }
  4125. else
  4126. {
  4127. gamerunstate = new StateNotRunning();
  4128. DemoMode = false;
  4129. StartGame(lsetuse, 1);
  4130. }
  4131. //throw new NotImplementedException();
  4132. }
  4133. #region iGameClient Members
  4134. bool iGameClient.DemoMode
  4135. {
  4136. get
  4137. {
  4138. return this.DemoMode;
  4139. }
  4140. }
  4141. private Bitmap measurebitmap= new Bitmap(1,1);
  4142. private Graphics measuregraphics=null;
  4143. public SizeF MeasureString(String stringmeasure, Font fontuse)
  4144. {
  4145. //this can be accessed cross-thread, so we lock it in both locations.
  4146. if (measuregraphics == null)
  4147. measuregraphics = Graphics.FromImage(measurebitmap);
  4148. return measuregraphics.MeasureString(stringmeasure, fontuse);
  4149. }
  4150. #endregion
  4151. private void checkForUpdatesToolStripMenuItem_Click(object sender, EventArgs e)
  4152. {
  4153. new frmUpdates().Show();
  4154. }
  4155. private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
  4156. {
  4157. if (gamerunstate is StateRunning)
  4158. gamerunstate = new StatePaused();
  4159. SplashScreen showscreen = new SplashScreen(true);
  4160. showscreen.Show();
  4161. showscreen.Focus();
  4162. }
  4163. private ButtonConstants currentlypressed;
  4164. public ButtonConstants getPressedButtons()
  4165. {
  4166. return currentlypressed;
  4167. }
  4168. public void InvokeButtonDown(ButtonEventArgs<bool> callwith )
  4169. {
  4170. ButtonDown.Invoke(this,callwith);
  4171. }
  4172. public void InvokeButtonUp(ButtonEventArgs<bool> callwith )
  4173. {
  4174. ButtonUp.Invoke(this,callwith);
  4175. }
  4176. public void InvokeMoveAbsolute(PointF newlocation)
  4177. {
  4178. MoveAbsolute.Invoke(newlocation);
  4179. }
  4180. public void InvokeOnMove(PointF pPosition)
  4181. {
  4182. MouseEventArgs<bool> me = new MouseEventArgs<bool>(0, pPosition);
  4183. var copied = OnMove;
  4184. if(copied==null) return;
  4185. copied(this, me);
  4186. }
  4187. private frmEditor editform;
  4188. private void editorToolStripMenuItem_Click(object sender, EventArgs e)
  4189. {
  4190. if (editform==null||!editform.Visible)
  4191. editform = new frmEditor();
  4192. editform.Show(this);
  4193. }
  4194. private void stopGameToolStripMenuItem_Click(object sender, EventArgs e)
  4195. {
  4196. if(GameThread==null) return;
  4197. gamerunstate = new StatePaused();
  4198. //ask...
  4199. if (MessageBox.Show(this, "Are you sure you want to stop this game?", "Stop Game", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
  4200. {
  4201. return;
  4202. }
  4203. gamerunstate = new StateNotRunning();
  4204. //kill the gamethread
  4205. GameThread.Abort();
  4206. BCBlockGameState.Soundman.StopMusic();
  4207. PicGame.Invalidate();
  4208. PicGame.Update();
  4209. OpenFileDialog ofd = new OpenFileDialog();
  4210. }
  4211. private void ghostToolStripMenuItem_Click(object sender, EventArgs e)
  4212. {
  4213. }
  4214. private DebugHelper HelperDebugObject = null;
  4215. private bool dosaveshot = false;
  4216. private Dictionary<cBall, PointF> savedF7speeds = null;
  4217. private void frmBaseBlock_KeyDown(object sender, KeyEventArgs e)
  4218. {
  4219. if (gamerunstate is StateValueInput)
  4220. {
  4221. StateValueInput InputState = (StateValueInput)gamerunstate;
  4222. if (e.KeyCode == Keys.Escape)
  4223. {
  4224. InputState.CurrentValue.SelStart = 0;
  4225. InputState.CurrentValue.Text = "";
  4226. }
  4227. }
  4228. if (e.KeyCode == Keys.F12)
  4229. {
  4230. if (!(gamerunstate is StateNotRunning))
  4231. {
  4232. dosaveshot=true;
  4233. }
  4234. }
  4235. else if (e.KeyCode == Keys.F7)
  4236. {
  4237. if (gamerunstate is StateRunning)
  4238. {
  4239. if (savedF7speeds != null)
  4240. {
  4241. mGameState.EnqueueMessage("Ball speeds reverted.");
  4242. foreach (var iterate in savedF7speeds)
  4243. {
  4244. iterate.Key.Velocity = iterate.Value;
  4245. }
  4246. savedF7speeds=null;
  4247. }
  4248. else
  4249. {
  4250. mGameState.EnqueueMessage("Ball speeds stopped.");
  4251. savedF7speeds=new Dictionary<cBall, PointF>();
  4252. foreach (cBall stationit in mGameState.Balls)
  4253. {
  4254. savedF7speeds.Add(stationit, stationit.Velocity);
  4255. stationit.Velocity = new PointF(0, 0);
  4256. }
  4257. }
  4258. }
  4259. }
  4260. if(gamerunstate is StateMenu)
  4261. {
  4262. if (menudata.SelectedItem == null)
  4263. {
  4264. //if no selection, select the first item.
  4265. menudata.SelectedItem = menudata.items.First();
  4266. }
  4267. else
  4268. {
  4269. var currentnode = menudata.items.Find(menudata.SelectedItem);
  4270. if (e.KeyCode == Keys.Enter)
  4271. {
  4272. menudata.SelectedItem.InvokeItemChosen();
  4273. ExitMenu();
  4274. }
  4275. else if (e.KeyCode == Keys.Escape)
  4276. {
  4277. ExitMenu();
  4278. }
  4279. else if (e.KeyCode == Keys.Up || e.KeyCode == Keys.Down || e.KeyCode == Keys.Right ||
  4280. e.KeyCode == Keys.Left)
  4281. {
  4282. menudata.SelectedItem.InvokeItemUnselect();
  4283. if (e.KeyCode == Keys.Up)
  4284. {
  4285. //select the previous item.
  4286. BCBlockGameState.Soundman.PlaySound("MENU_SELECT");
  4287. if (currentnode.Previous == null)
  4288. {
  4289. //BCBlockGameState.Soundman.PlaySound("WRONG");
  4290. //no previous item to select. remain unchanged...
  4291. menudata.SelectedItem = currentnode.List.Last.Value;
  4292. }
  4293. else
  4294. {
  4295. //currentnode = currentnode.Previous.Value;
  4296. menudata.SelectedItem = currentnode.Previous.Value;
  4297. }
  4298. }
  4299. else if (e.KeyCode == Keys.Down)
  4300. {
  4301. BCBlockGameState.Soundman.PlaySound("RIGHT");
  4302. if (currentnode.Next == null)
  4303. menudata.SelectedItem = currentnode.List.First.Value;
  4304. else
  4305. {
  4306. menudata.SelectedItem = currentnode.Next.Value;
  4307. }
  4308. }
  4309. menudata.SelectedItem.InvokeItemSelect();
  4310. }
  4311. }
  4312. }
  4313. else if (e.KeyCode == Keys.F4)
  4314. {
  4315. if (gamerunstate is StateRunning)
  4316. {
  4317. menudata = new MenuModeData(new String[] { "Item1", "Item2", "Item3", "Item4" },menuitems_MenuItemSelect,menuitems_MenuItemUnselect,menuitems_MenuItemChosen,menuitems_MenuItemPrePaint);
  4318. //gamerunstate = GameRunStateConstants.Game_Menu;
  4319. EnterMenu();
  4320. }
  4321. }
  4322. else if (e.KeyCode == Keys.F3)
  4323. {
  4324. if (KeyboardInfo.IsPressed(Keys.ShiftKey))
  4325. {
  4326. //remove debug helper if present.
  4327. if (HelperDebugObject != null)
  4328. {
  4329. mGameState.NextFrameCalls.Enqueue(new BCBlockGameState.NextFrameStartup(() => mGameState.GameObjects.Remove(HelperDebugObject)));
  4330. //mGameState.GameObjects.Remove(HelperDebugObject);
  4331. HelperDebugObject = null;
  4332. }
  4333. else
  4334. {
  4335. HelperDebugObject = new DebugHelper();
  4336. mGameState.NextFrameCalls.Enqueue(new BCBlockGameState.NextFrameStartup(() => mGameState.GameObjects.AddLast(HelperDebugObject)));
  4337. //mGameState.GameObjects.AddLast(HelperDebugObject);
  4338. }
  4339. }
  4340. else
  4341. {
  4342. ShowDebugInfo = !ShowDebugInfo;
  4343. }
  4344. }
  4345. else
  4346. {
  4347. if(gamerunstate is StateRunning)
  4348. FireButtonDown(new ButtonEventArgs<bool>(KeyToGameButton(e.KeyCode)));
  4349. }
  4350. }
  4351. private void ExitMenu()
  4352. {
  4353. //throw new NotImplementedException();
  4354. //reverse appropriate actions taken in EnterMenu.
  4355. //BCBlockGameState.Soundman.PopMusic();
  4356. if (gamerunstate is StateMenu)
  4357. {
  4358. BCBlockGameState.Soundman.StopTemporaryMusic(menudata.MenuMusic);
  4359. gamerunstate = new StateRunning();
  4360. }
  4361. }
  4362. iActiveSoundObject menumusic=null;
  4363. private void EnterMenu(String[] menuoptions, MenuModeMenuItem.MenuItemEvent chosenroutine, Object[] menutags)
  4364. {
  4365. menudata = new MenuModeData(menuoptions, menuitems_MenuItemSelect, menuitems_MenuItemUnselect, chosenroutine, menuitems_MenuItemPrePaint);
  4366. int currindex = 0;
  4367. foreach (var loopitem in menudata.items)
  4368. {
  4369. loopitem.Tag = menutags[currindex];
  4370. loopitem.MenuItemPrePaint += menuitems_MenuItemPrePaint;
  4371. currindex++;
  4372. }
  4373. EnterMenu();
  4374. }
  4375. private void EnterMenu(String[] menuoptions,Object[] menutags)
  4376. {
  4377. //recreate the menu based on the given options...
  4378. menudata = new MenuModeData(menuoptions, menuitems_MenuItemSelect, menuitems_MenuItemUnselect, menuitems_MenuItemChosen, menuitems_MenuItemPrePaint);
  4379. int currindex = 0;
  4380. foreach (var loopitem in menudata.items)
  4381. {
  4382. loopitem.Tag = menutags[currindex];
  4383. loopitem.MenuItemPrePaint += menuitems_MenuItemPrePaint;
  4384. currindex++;
  4385. }
  4386. //now, call the "base" EnterMenu routine, which will pause the music, play the appropriate menu music, and change the runstate to show the menu.
  4387. EnterMenu();
  4388. }
  4389. private void EnterMenu()
  4390. {
  4391. //Play the menu music.
  4392. //pause, and cache the current music...
  4393. BCBlockGameState.Soundman.PauseMusic(true);
  4394. ////menumusic = BCBlockGameState.Soundman.PushMusic("CREDITS", 1.0f, true);
  4395. menumusic = BCBlockGameState.Soundman.PlayTemporaryMusic("CREDITSONG", 1.0f, true);
  4396. gamerunstate = new StateMenu();
  4397. //Enter the menu: play the relevant sound, pause current music, and play menu music. Then set menu mode.
  4398. //throw new NotImplementedException();
  4399. }
  4400. private Brush _DefUnSelBrush = null, _DefSelBrush = null;
  4401. void menuitems_MenuItemPrePaint(MenuModeMenuItem sender, RectangleF drawarea)
  4402. {
  4403. if (!sender.Selected)
  4404. {
  4405. if (_DefUnSelBrush == null)
  4406. {
  4407. _DefUnSelBrush = new LinearGradientBrush(new PointF(0, 0), new PointF(0, drawarea.Height), Color.White, Color.Gray);
  4408. }
  4409. sender.OurStyle.Background = _DefUnSelBrush;
  4410. }
  4411. else
  4412. {
  4413. if (_DefSelBrush == null)
  4414. {
  4415. _DefSelBrush = new LinearGradientBrush(new PointF(0, 0), new PointF(0, drawarea.Height), Color.Yellow, Color.Green);
  4416. }
  4417. sender.OurStyle.Background = _DefSelBrush;
  4418. }
  4419. }
  4420. //Menu Mode item event handling.
  4421. void menuitems_MenuItemUnselect(MenuModeMenuItem sender)
  4422. {
  4423. Debug.Print("MenuItemUnselected, text=" + sender.Text);
  4424. //throw new NotImplementedException();
  4425. }
  4426. void menuitems_MenuItemSelect(MenuModeMenuItem sender)
  4427. {
  4428. Debug.Print("MenuItemSelected, text=" + sender.Text);
  4429. //throw new NotImplementedException();
  4430. }
  4431. void warpchosen(MenuModeMenuItem sender)
  4432. {
  4433. mPlayingLevel = mPlayingSet.Levels.IndexOf((Level)sender.Tag)+1; //haha...
  4434. PlayLevel(mGameState, (Level)sender.Tag);
  4435. }
  4436. void menuitems_MenuItemChosen(MenuModeMenuItem sender)
  4437. {
  4438. Debug.Print("MenuItemChosen, text=" + sender.Text);
  4439. //throw new NotImplementedException();
  4440. //exit menu mode.
  4441. gamerunstate = new StateRunning();
  4442. }
  4443. private void frmBaseBlock_KeyUp(object sender, KeyEventArgs e)
  4444. {
  4445. if(gamerunstate is StateRunning)
  4446. FireButtonUp(new ButtonEventArgs<bool>(KeyToGameButton(e.KeyCode)));
  4447. }
  4448. private void BrowserToolStripItem_Click(object sender, EventArgs e)
  4449. {
  4450. frmLevelBrowser fbrowser = new frmLevelBrowser();
  4451. fbrowser.ShowDialog();
  4452. }
  4453. private void keyToolStripMenuItem_Click(object sender, EventArgs e)
  4454. {
  4455. String[] Names = new string[] {"Michael Burgwin","BC_Programmer","BC_Programming","John Doe"};
  4456. String[] Organizations = new string[] {"BASeCamp Corporation","BASeCamp Software Solutions","Microsoft","The Free Software Foundation"};
  4457. String[] ApplicationNames = new string[] {"BASeBlock","BCSearch","Gravgame","BCJobClock"};
  4458. using (FileStream writekeydata = new FileStream("D:\\keyout.txt", FileMode.Create))
  4459. {
  4460. StreamWriter writerobj = new StreamWriter(writekeydata);
  4461. foreach (String UserName in Names)
  4462. foreach (String Organization in Organizations)
  4463. foreach (String Appname in ApplicationNames)
  4464. {
  4465. String generatedkey = LicensedFeatureData.SecureStringstr(LicensedFeatureData.GenKey(UserName, Organization, Appname));
  4466. writerobj.WriteLine("Name:" + UserName);
  4467. writerobj.WriteLine("Organization:" + UserName);
  4468. writerobj.WriteLine("Application:" + UserName);
  4469. writerobj.WriteLine("GeneratedKey:" + generatedkey);
  4470. writerobj.WriteLine();
  4471. }
  4472. writerobj.Close();
  4473. }
  4474. }
  4475. public void ShowMessage(string message)
  4476. {
  4477. if(mGameState!=null)
  4478. mGameState.EnqueueMessage(message);
  4479. }
  4480. public void FlagError(String ErrorDescription, Exception AttachedException)
  4481. {
  4482. //
  4483. }
  4484. public void UpdateProgress(float ProgressPercentage)
  4485. {
  4486. //throw new NotImplementedException();
  4487. }
  4488. }
  4489. }