Game.java 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871
  1. package me.hammerle.supersnuvi;
  2. import java.io.File;
  3. import java.util.ArrayList;
  4. import java.util.Arrays;
  5. import me.hammerle.snuviengine.api.ColorRenderer;
  6. import me.hammerle.snuviengine.api.Engine;
  7. import me.hammerle.snuviengine.api.FontRenderer;
  8. import me.hammerle.snuviengine.api.KeyBinding;
  9. import me.hammerle.snuviengine.api.Shader;
  10. import me.hammerle.snuviscript.code.SnuviParser;
  11. import me.hammerle.supersnuvi.entity.Entity;
  12. import me.hammerle.supersnuvi.entity.EntityBuilder;
  13. import me.hammerle.supersnuvi.entity.components.ai.PlatformController;
  14. import me.hammerle.supersnuvi.gamelogic.FileLevel;
  15. import me.hammerle.supersnuvi.gamelogic.Level;
  16. import me.hammerle.supersnuvi.gamelogic.StartScreenLevel;
  17. import me.hammerle.supersnuvi.rendering.LevelRenderer;
  18. import me.hammerle.supersnuvi.savegame.SimpleConfig;
  19. import me.hammerle.supersnuvi.snuviscript.SnuviLogger;
  20. import me.hammerle.supersnuvi.snuviscript.SnuviScheduler;
  21. import me.hammerle.supersnuvi.tiles.*;
  22. import me.hammerle.supersnuvi.util.SoundUtils;
  23. import me.hammerle.supersnuvi.util.Utils;
  24. public class Game extends Engine
  25. {
  26. public static final int MS_PER_TICK = 50;
  27. public static final float SECS_PER_TICK = MS_PER_TICK / 1000.0f;
  28. public static int getTicksForMillis(int millis)
  29. {
  30. return millis / MS_PER_TICK;
  31. }
  32. private static Game instance;
  33. public static Game get()
  34. {
  35. return instance;
  36. }
  37. // constants
  38. public static final NullTile FALLBACK_TILE = new NullTile();
  39. // tiles
  40. private final Tile[] registeredTiles = new Tile[75];
  41. // levels
  42. private Level currentLevel = null;
  43. private final Level[] levels;
  44. private int levelIndex = 0;
  45. private final StartScreenLevel startScreenLevel = new StartScreenLevel();
  46. // scripting
  47. private final SnuviLogger snuviLogger = new SnuviLogger();
  48. private final SnuviScheduler snuviScheduler = new SnuviScheduler();
  49. private final SnuviParser snuviParser = new SnuviParser(snuviLogger, snuviScheduler);
  50. // config and savegames
  51. private final SimpleConfig config = new SimpleConfig("options.txt", true);
  52. private final SimpleConfig[] saveSlots = new SimpleConfig[]
  53. {
  54. new SimpleConfig("slot1.txt", true),
  55. new SimpleConfig("slot2.txt", true),
  56. new SimpleConfig("slot3.txt", true)
  57. };
  58. private int screen = 0;
  59. private int startScreenIndex = 0;
  60. private int optionScreenIndex = 0;
  61. private int slotScreenIndex = 0;
  62. private boolean optionsDirty = false;
  63. // sound
  64. private boolean sound = config.getBoolean("sound", false);
  65. // renderer
  66. private final LevelRenderer levelRenderer = new LevelRenderer();
  67. // this dummy will be removed later
  68. private final Shader dummy = new Shader();
  69. public Game()
  70. {
  71. instance = this;
  72. registerTiles();
  73. addSnuviCommands();
  74. File[] files = new File("./levels").listFiles();
  75. Arrays.sort(files, (o1, o2) -> o1.compareTo(o2));
  76. ArrayList<FileLevel> levelList = new ArrayList<>();
  77. for(File file : files)
  78. {
  79. if(file.isFile() && file.getName().endsWith(".map"))
  80. {
  81. try
  82. {
  83. FileLevel l = new FileLevel(file);
  84. levelList.add(l);
  85. }
  86. catch(IllegalArgumentException ex)
  87. {
  88. //System.out.println(ex.getMessage());
  89. }
  90. }
  91. }
  92. levels = levelList.toArray(new FileLevel[levelList.size()]);
  93. }
  94. @Override
  95. public void init()
  96. {
  97. setMaxFps(60);
  98. setNanosPerTick(MS_PER_TICK * 1_000_000);
  99. }
  100. // -------------------------------------------------------------------------
  101. // tick, rendering
  102. // -------------------------------------------------------------------------
  103. @Override
  104. public void tick()
  105. {
  106. if(currentLevel != null)
  107. {
  108. SoundUtils.playSound(SoundUtils.Sound.SONG_1);
  109. SoundUtils.stopSound(SoundUtils.Sound.MENU_MUSIC);
  110. snuviScheduler.setActiveLevel(currentLevel);
  111. //if(Keys.TEST.isReleased())
  112. {
  113. currentLevel.tick();
  114. }
  115. snuviScheduler.tick(currentLevel);
  116. // doing that here to prevent concurent modification
  117. if(currentLevel.isFinished())
  118. {
  119. String base = "level." + currentLevel.getFileName();
  120. SimpleConfig sp = saveSlots[slotScreenIndex];
  121. // save success
  122. sp.set(base, true);
  123. // update time, if a new highscore was scored
  124. double time = sp.getDouble(base + ".time", Integer.MAX_VALUE);
  125. if(currentLevel.getTime() < time)
  126. {
  127. sp.set(base + ".time", currentLevel.getTime());
  128. }
  129. // update bottles, if a new highscore was scored
  130. int bottles = sp.getInt(base + ".bottles", 0);
  131. if(currentLevel.getCurrentBottles() > bottles)
  132. {
  133. sp.set(base + ".bottles", currentLevel.getCurrentBottles());
  134. }
  135. // final save
  136. sp.save();
  137. currentLevel.reset();
  138. currentLevel = null;
  139. return;
  140. }
  141. if(currentLevel.shouldReset())
  142. {
  143. currentLevel.reset();
  144. }
  145. if(Keys.ESCAPE.isReleased())
  146. {
  147. currentLevel = null;
  148. }
  149. }
  150. else
  151. {
  152. SoundUtils.playSound(SoundUtils.Sound.MENU_MUSIC);
  153. SoundUtils.stopSound(SoundUtils.Sound.SONG_1);
  154. startScreenLevel.tick();
  155. switch(screen)
  156. {
  157. case 0: // start screen
  158. {
  159. menuMove(() ->
  160. {
  161. // do nothing on escape in start screen
  162. }, () ->
  163. {
  164. switch(startScreenIndex)
  165. {
  166. case 0:
  167. screen = 1;
  168. break;
  169. case 1:
  170. screen = 2;
  171. break;
  172. case 2:
  173. stop();
  174. break;
  175. }
  176. }, () -> startScreenIndex++, () -> startScreenIndex--, () ->
  177. {
  178. if(startScreenIndex < 0)
  179. {
  180. startScreenIndex = 0;
  181. }
  182. else if(startScreenIndex >= 3)
  183. {
  184. startScreenIndex = 2;
  185. }
  186. });
  187. break;
  188. }
  189. case 1: // slot screen
  190. {
  191. menuMove(() ->
  192. {
  193. screen = 0;
  194. }, () ->
  195. {
  196. if(slotScreenIndex == 3)
  197. {
  198. screen = 0;
  199. return;
  200. }
  201. screen = 3;
  202. }, () -> slotScreenIndex++, () -> slotScreenIndex--, () ->
  203. {
  204. if(slotScreenIndex < 0)
  205. {
  206. slotScreenIndex = 0;
  207. }
  208. else if(slotScreenIndex >= 4)
  209. {
  210. slotScreenIndex = 3;
  211. }
  212. });
  213. break;
  214. }
  215. case 2: // option screen
  216. {
  217. menuMove(() ->
  218. {
  219. screen = 0;
  220. }, () ->
  221. {
  222. switch(optionScreenIndex)
  223. {
  224. case 0: // toggle sound
  225. sound = !sound;
  226. if(!sound)
  227. {
  228. SoundUtils.turnSoundOff();
  229. }
  230. optionsDirty = true;
  231. break;
  232. case 9: // save options
  233. Keys.write(config);
  234. config.set("sound", sound);
  235. config.save();
  236. optionsDirty = false;
  237. break;
  238. case 10: // go back
  239. screen = 0;
  240. break;
  241. default: // rebind keys
  242. Keys.rebind(Keys.get(optionScreenIndex - 1));
  243. optionsDirty = true;
  244. break;
  245. }
  246. }, () -> optionScreenIndex++, () -> optionScreenIndex--, () ->
  247. {
  248. if(optionScreenIndex < 0)
  249. {
  250. optionScreenIndex = 0;
  251. }
  252. int options = Keys.getAmount() + 3;
  253. if(optionScreenIndex >= options)
  254. {
  255. optionScreenIndex = options - 1;
  256. }
  257. });
  258. break;
  259. }
  260. case 3: // level choose screen
  261. {
  262. menuMove(() ->
  263. {
  264. screen = 1;
  265. }, () -> currentLevel = levels[levelIndex], () -> levelIndex++, () -> levelIndex--, () ->
  266. {
  267. if(levelIndex < 0)
  268. {
  269. levelIndex = 0;
  270. }
  271. else if(levelIndex >= levels.length)
  272. {
  273. levelIndex = levels.length - 1;
  274. }
  275. });
  276. break;
  277. }
  278. }
  279. }
  280. }
  281. private final static int COLOR_OVERLAY = 0x77808080;
  282. private final static int COLOR_OVERLAY2 = 0x77202020;
  283. private String getKeyName(KeyBinding key)
  284. {
  285. if(key.isRebinding())
  286. {
  287. return "[...]";
  288. }
  289. return key.getName();
  290. }
  291. @Override
  292. public void renderTick(float lag)
  293. {
  294. if(currentLevel != null)
  295. {
  296. levelRenderer.renderTick(dummy, lag, currentLevel);
  297. //currentLevel.renderTick(lag);
  298. return;
  299. }
  300. levelRenderer.renderTick(dummy, lag, startScreenLevel);
  301. Shader.translateTo(0.0f, 0.0f);
  302. Shader.updateMatrix();
  303. switch(screen)
  304. {
  305. case 0:
  306. {
  307. ColorRenderer cr = Shader.getColorRenderer();
  308. FontRenderer fr = Shader.getFontRenderer();
  309. float width = Shader.getViewWidth();
  310. float height = Shader.getViewHeight();
  311. float line = fr.getHeight();
  312. float left = width * 0.25f;
  313. float right = width * 0.75f;
  314. float top = (height - line * 7.0f) * 0.5f;
  315. float bottom = top + line * 7.0f;
  316. Shader.setTextureEnabled(false);
  317. Shader.setColorEnabled(true);
  318. // brown background
  319. //cr.drawRectangle(0, 0, width, height, COLOR_BROWN);
  320. Shader.setBlendingEnabled(true);
  321. cr.drawRectangle(left, top, right, bottom, COLOR_OVERLAY);
  322. float base = top + (3 + startScreenIndex) * line;
  323. cr.drawRectangle(left, base, right, base + line, COLOR_OVERLAY2);
  324. Shader.setBlendingEnabled(false);
  325. Shader.setTextureEnabled(true);
  326. float y = top + line;
  327. y = fr.drawString(left + line, y, "Super Snuvi");
  328. y += line;
  329. y = fr.drawString(left + line, y, "Start Game");
  330. y = fr.drawString(left + line, y, "Options");
  331. fr.drawString(left + line, y, "Exit Game");
  332. break;
  333. }
  334. case 1:
  335. {
  336. ColorRenderer cr = Shader.getColorRenderer();
  337. FontRenderer fr = Shader.getFontRenderer();
  338. float width = Shader.getViewWidth();
  339. float height = Shader.getViewHeight();
  340. float line = fr.getHeight();
  341. float left = width * 0.25f;
  342. float right = width * 0.75f;
  343. float top = (height - line * 8.0f) * 0.5f;
  344. float bottom = top + line * 8.0f;
  345. Shader.setTextureEnabled(false);
  346. Shader.setColorEnabled(true);
  347. // brown background
  348. //cr.drawRectangle(0, 0, width, height, COLOR_BROWN);
  349. Shader.setBlendingEnabled(true);
  350. cr.drawRectangle(left, top, right, bottom, COLOR_OVERLAY);
  351. float base = top + (3 + slotScreenIndex) * line;
  352. cr.drawRectangle(left, base, right, base + line, COLOR_OVERLAY2);
  353. Shader.setBlendingEnabled(false);
  354. Shader.setTextureEnabled(true);
  355. float y = top + line;
  356. y = fr.drawString(left + line, y, "Choose a Savegame");
  357. y += line;
  358. y = fr.drawString(left + line, y, "Slot 1");
  359. y = fr.drawString(left + line, y, "Slot 2");
  360. y = fr.drawString(left + line, y, "Slot 3");
  361. fr.drawString(left + line, y, "Back");
  362. break;
  363. }
  364. case 2:
  365. {
  366. ColorRenderer cr = Shader.getColorRenderer();
  367. FontRenderer fr = Shader.getFontRenderer();
  368. float width = Shader.getViewWidth();
  369. float height = Shader.getViewHeight();
  370. float line = fr.getHeight();
  371. float left = width * 0.2f;
  372. float right = width * 0.8f;
  373. float top = (height - line * 15.0f) * 0.5f;
  374. float bottom = top + line * 15.0f;
  375. Shader.setTextureEnabled(false);
  376. Shader.setColorEnabled(true);
  377. // brown background
  378. //cr.drawRectangle(0, 0, width, height, COLOR_BROWN);
  379. Shader.setBlendingEnabled(true);
  380. cr.drawRectangle(left, top, right, bottom, COLOR_OVERLAY);
  381. float base = top + (3 + optionScreenIndex) * line;
  382. cr.drawRectangle(left, base, right, base + line, COLOR_OVERLAY2);
  383. Shader.setBlendingEnabled(false);
  384. Shader.setTextureEnabled(true);
  385. left += line;
  386. float secLeft = right - line * 11;
  387. float y = top + line;
  388. y = fr.drawString(left, y, "Options");
  389. y += line;
  390. fr.drawString(left, y, "Sound");
  391. y = fr.drawString(secLeft, y, sound ? "yes" : "no");
  392. fr.drawString(left, y, "K: Up");
  393. y = fr.drawString(secLeft, y, getKeyName(Keys.UP));
  394. fr.drawString(left, y, "K: Down");
  395. y = fr.drawString(secLeft, y, getKeyName(Keys.DOWN));
  396. fr.drawString(left, y, "K: Left");
  397. y = fr.drawString(secLeft, y, getKeyName(Keys.LEFT));
  398. fr.drawString(left, y, "K: Right");
  399. y = fr.drawString(secLeft, y, getKeyName(Keys.RIGHT));
  400. fr.drawString(left, y, "K: Jump");
  401. y = fr.drawString(secLeft, y, getKeyName(Keys.JUMP));
  402. fr.drawString(left, y, "K: Run");
  403. y = fr.drawString(secLeft, y, getKeyName(Keys.RUN));
  404. fr.drawString(left, y, "K: Back");
  405. y = fr.drawString(secLeft, y, getKeyName(Keys.ESCAPE));
  406. fr.drawString(left, y, "K: Enter");
  407. y = fr.drawString(secLeft, y, getKeyName(Keys.ENTER));
  408. if(optionsDirty)
  409. {
  410. y = fr.drawString(left, y, true, "&cSave");
  411. }
  412. else
  413. {
  414. y = fr.drawString(left, y, true, "Save");
  415. }
  416. fr.drawString(left, y, true, "Back");
  417. break;
  418. }
  419. case 3:
  420. {
  421. ColorRenderer cr = Shader.getColorRenderer();
  422. FontRenderer fr = Shader.getFontRenderer();
  423. float width = Shader.getViewWidth();
  424. float height = Shader.getViewHeight();
  425. float line = fr.getHeight();
  426. int maxView = 7; // only for odd numbers
  427. int half = maxView / 2;
  428. float left = width * 0.2f;
  429. float right = width * 0.8f;
  430. float top = (height - line * (maxView + 4)) * 0.5f;
  431. float bottom = top + line * (maxView + 4);
  432. Shader.setTextureEnabled(false);
  433. Shader.setColorEnabled(true);
  434. // brown background
  435. //cr.drawRectangle(0, 0, width, height, COLOR_BROWN);
  436. Shader.setBlendingEnabled(true);
  437. cr.drawRectangle(left, top, right, bottom, COLOR_OVERLAY);
  438. int firstIndex;
  439. int lastIndex;
  440. int baseIndex;
  441. if(levelIndex <= half) // first half
  442. {
  443. firstIndex = 0;
  444. lastIndex = Math.min(levels.length, maxView);
  445. baseIndex = levelIndex;
  446. }
  447. else if(levelIndex >= levels.length - half) // last half
  448. {
  449. lastIndex = levels.length;
  450. firstIndex = Math.max(lastIndex - maxView, 0);
  451. if(levels.length <= maxView)
  452. {
  453. baseIndex = levelIndex;
  454. }
  455. else
  456. {
  457. baseIndex = levelIndex - (levels.length - half - 1) + half;
  458. }
  459. }
  460. else // middle
  461. {
  462. firstIndex = levelIndex - half;
  463. lastIndex = firstIndex + maxView;
  464. baseIndex = half;
  465. }
  466. float base = top + (3 + baseIndex) * line;
  467. cr.drawRectangle(left, base, right, base + line, COLOR_OVERLAY2);
  468. Shader.setBlendingEnabled(false);
  469. Shader.setTextureEnabled(true);
  470. left += line;
  471. float secLeft = right - line * 12;
  472. float thirdLeft = right - line * 6;
  473. float y = top + line;
  474. y = fr.drawString(left, y, "Choose a Level ...");
  475. y += line;
  476. if(firstIndex >= 1)
  477. {
  478. y = fr.drawString(left, y, "...");
  479. firstIndex++;
  480. }
  481. SimpleConfig sc = saveSlots[slotScreenIndex];
  482. for(int i = firstIndex; i < lastIndex - 1; i++)
  483. {
  484. Level l = levels[i];
  485. fr.drawString(left, y, l.getName());
  486. fr.drawString(secLeft, y, LevelRenderer.formatBottles(sc.getInt("level." + l.getFileName() + ".bottles", 0), l.getMaxBottles()));
  487. y = fr.drawString(thirdLeft, y, LevelRenderer.formatTime(sc.getFloat("level." + l.getFileName() + ".time", 0)));
  488. }
  489. if(lastIndex == levels.length)
  490. {
  491. Level l = levels[lastIndex - 1];
  492. fr.drawString(left, y, l.getName());
  493. fr.drawString(secLeft, y, LevelRenderer.formatBottles(sc.getInt("level." + l.getFileName() + ".bottles", 0), l.getMaxBottles()));
  494. fr.drawString(thirdLeft, y, LevelRenderer.formatTime(sc.getFloat("level." + l.getFileName() + ".time", 0)));
  495. }
  496. else
  497. {
  498. fr.drawString(left, y, "...");
  499. }
  500. break;
  501. }
  502. }
  503. }
  504. // -------------------------------------------------------------------------
  505. // config
  506. // -------------------------------------------------------------------------
  507. public boolean isSoundEnabled()
  508. {
  509. return sound;
  510. }
  511. // -------------------------------------------------------------------------
  512. // tile stuff
  513. // -------------------------------------------------------------------------
  514. private void registerTiles()
  515. {
  516. // dirt
  517. registeredTiles[0] = new BaseBoxTile(0.125f, 0.0f, 0.1875f, 0.0625f);
  518. // grass
  519. registeredTiles[1] = new BaseBoxTile(0.0625f, 0.0f, 0.125f, 0.0625f);
  520. // bottled soul
  521. registeredTiles[2] = new BottledSoulTile(1);
  522. registeredTiles[3] = new BottledSoulTile(2);
  523. registeredTiles[4] = new BottledSoulTile(3);
  524. // bounce shroom
  525. registeredTiles[5] = new TrampolinTile();
  526. // crumbling stones
  527. registeredTiles[6] = new CrumblingStoneTile();
  528. // spike trap
  529. registeredTiles[7] = new SpikeTile();
  530. // water
  531. for(int i = 0; i < 16; i++)
  532. {
  533. registeredTiles[8 + i] = new WaterTile(15 - i);
  534. }
  535. // snuvi start block
  536. registeredTiles[24] = new StartTile();
  537. // sky
  538. registeredTiles[25] = new BaseTile(0.0f, 0.0f, 0.0625f, 0.0625f);
  539. // slippery slime
  540. registeredTiles[26] = new SlipperyTile();
  541. // end level
  542. registeredTiles[27] = new GoalTile(0.25f, 0.125f, 0.3125f, 0.1875f);
  543. registeredTiles[28] = new GoalTile(0.25f, 0.0625f, 0.3125f, 0.125f);
  544. // thorns
  545. registeredTiles[29] = new KillTile(0.0f, 0.125f, 0.0625f, 0.1875f);
  546. registeredTiles[30] = new KillTile(0.0625f, 0.125f, 0.125f, 0.1875f);
  547. registeredTiles[31] = new KillTile(0.125f, 0.125f, 0.1875f, 0.1875f);
  548. // decoration shrooms
  549. registeredTiles[32] = new DecoShroomTile(0.0f, 0.21875f, 0.0625f, 0.25f);
  550. registeredTiles[33] = new DecoShroomTile(0.0f, 0.1875f, 0.0625f, 0.21875f);
  551. registeredTiles[34] = new DecoShroomTile(0.0625f, 0.21875f, 0.125f, 0.25f);
  552. registeredTiles[35] = new DecoShroomTile(0.0625f, 0.1875f, 0.125f, 0.21875f);
  553. // ramp
  554. registeredTiles[36] = new RampTile(0.375f, 0.0f, 0.4375f, 0.0625f, 0.0f, Tile.SIZE, Tile.SIZE, 0.0f);
  555. registeredTiles[37] = new RampTile(0.4375f, 0.0f, 0.5f, 0.0625f, 0.0f, Tile.SIZE, Tile.SIZE, Tile.SIZE * 0.5f);
  556. registeredTiles[38] = new RampTile(0.5f, 0.0f, 0.5625f, 0.0625f, 0.0f, Tile.SIZE * 0.5f, Tile.SIZE, 0.0f);
  557. registeredTiles[39] = new RampTile(0.375f, 0.0625f, 0.4375f, 0.125f, Tile.SIZE, Tile.SIZE, 0.0f, 0.0f);
  558. registeredTiles[40] = new RampTile(0.4375f, 0.0625f, 0.5f, 0.125f, Tile.SIZE, Tile.SIZE, 0.0f, Tile.SIZE * 0.5f);
  559. registeredTiles[41] = new RampTile(0.5f, 0.0625f, 0.5625f, 0.125f, Tile.SIZE, Tile.SIZE * 0.5f, 0.0f, 0.0f);
  560. // london stuff
  561. // street
  562. registeredTiles[42] = new BaseBoxTile(0.3125f, 0.125f, 0.375f, 0.1875f);
  563. // dirt
  564. registeredTiles[43] = new BaseBoxTile(0.375f, 0.125f, 0.4375f, 0.1875f);
  565. // background
  566. registeredTiles[44] = new BaseTile(0.3125f, 0.0625f, 0.375f, 0.125f);
  567. // street lamp
  568. for(int x = 0; x < 5; x++)
  569. {
  570. for(int y = 0; y < 5; y++)
  571. {
  572. registeredTiles[45 + 5 * y + x] = new BaseTile(0.0625f * x, 0.25f + 0.0625f * y, 0.0625f * (x + 1), 0.25f + 0.0625f * (y + 1));
  573. }
  574. }
  575. // !-Tile
  576. registeredTiles[70] = new HeadHitTile(0.5625f, 0.0f, 0.625f, 0.0625f);
  577. // ?-Tile
  578. registeredTiles[71] = new HeadHitOnceTile(0.625f, 0.0f, 0.6875f, 0.0625f, 0.6875f, 0.0f, 0.75f, 0.0625f);
  579. // button
  580. registeredTiles[72] = new InteractTile(0.75f, 0.0f, 0.8125f, 0.0625f);
  581. // wooden pressure plate
  582. registeredTiles[73] = new PressureTile(0.568359375f, 0.072265625f, 0.619140625f, 0.078125f);
  583. // stone pressure plate
  584. registeredTiles[74] = new PressureTile(0.568359375f, 0.087890625f, 0.619140625f, 0.09375f);
  585. }
  586. public Tile getTile(int id)
  587. {
  588. if(id < 0 || id >= registeredTiles.length || registeredTiles[id] == null)
  589. {
  590. return FALLBACK_TILE;
  591. }
  592. return registeredTiles[id];
  593. }
  594. public void resetTiles(FileLevel l)
  595. {
  596. for(Tile t : registeredTiles)
  597. {
  598. t.reset(l);
  599. }
  600. }
  601. public void tickTiles()
  602. {
  603. for(Tile t : registeredTiles)
  604. {
  605. t.tick();
  606. }
  607. }
  608. private void menuMove(Runnable esc, Runnable enter, Runnable down, Runnable up, Runnable end)
  609. {
  610. if(Keys.ESCAPE.isReleased())
  611. {
  612. esc.run();
  613. return;
  614. }
  615. if(Keys.ENTER.isReleased())
  616. {
  617. enter.run();
  618. return;
  619. }
  620. if(Keys.DOWN.getTime() > 4)
  621. {
  622. Keys.DOWN.setTime(0);
  623. down.run();
  624. }
  625. else if(Keys.UP.getTime() > 4)
  626. {
  627. Keys.UP.setTime(0);
  628. up.run();
  629. }
  630. else if(Keys.DOWN.isReleased())
  631. {
  632. down.run();
  633. }
  634. else if(Keys.UP.isReleased())
  635. {
  636. up.run();
  637. }
  638. end.run();
  639. }
  640. @Override
  641. public void onStop()
  642. {
  643. SoundUtils.closeSounds();
  644. }
  645. public SnuviParser getParser()
  646. {
  647. return snuviParser;
  648. }
  649. public Level getCurrentLevel()
  650. {
  651. return currentLevel;
  652. }
  653. public void setCurrentLevel(Level l)
  654. {
  655. snuviScheduler.setActiveLevel(l);
  656. currentLevel = l;
  657. }
  658. private void addSnuviCommands()
  659. {
  660. snuviParser.registerFunction("level.getname", (sc, in) -> currentLevel.getName());
  661. snuviParser.registerFunction("level.getwidth", (sc, in) -> (double) currentLevel.getData().getWidth());
  662. snuviParser.registerFunction("level.getheight", (sc, in) -> (double) currentLevel.getData().getHeight());
  663. snuviParser.registerFunction("level.getlayers", (sc, in) -> (double) currentLevel.getData().getLayers());
  664. snuviParser.registerFunction("level.getbackgroundindex", (sc, in) -> (double) currentLevel.getData().getBackgroundIndex());
  665. snuviParser.registerFunction("level.gettile", (sc, in) -> currentLevel.getData().getTile(in[0].getInt(sc), in[1].getInt(sc), in[2].getInt(sc)));
  666. snuviParser.registerFunction("level.settile", (sc, in) ->
  667. {
  668. int layer = in[0].getInt(sc);
  669. int x = in[1].getInt(sc);
  670. int y = in[2].getInt(sc);
  671. int tile = in[3].getInt(sc);
  672. currentLevel.getData().setTile(layer, x, y, tile);
  673. currentLevel.getTileUpdater().add(layer, x, y);
  674. Game.get().getTile(tile).reset(x, y, currentLevel);
  675. return Void.TYPE;
  676. });
  677. snuviParser.registerFunction("level.addmessage", (sc, in) ->
  678. {
  679. currentLevel.addMessage(in[0].getString(sc));
  680. return Void.TYPE;
  681. });
  682. snuviParser.registerFunction("level.finish", (sc, in) ->
  683. {
  684. currentLevel.finishLevel();
  685. return Void.TYPE;
  686. });
  687. snuviParser.registerFunction("tile.totilecoord", (sc, in) -> (double) Utils.toBlock(in[0].getFloat(sc)));
  688. snuviParser.registerFunction("tile.tolevelcoord", (sc, in) -> (double) Utils.toCoord(in[0].getInt(sc)));
  689. snuviParser.registerFunction("tile.scale", (sc, in) -> in[0].getDouble(sc) * Tile.SIZE_SCALE);
  690. snuviParser.registerFunction("entity.gethero", (sc, in) -> currentLevel.getHero());
  691. snuviParser.registerFunction("entity.getx", (sc, in) -> (double) ((Entity) in[0].get(sc)).getX());
  692. snuviParser.registerFunction("entity.gety", (sc, in) -> (double) ((Entity) in[0].get(sc)).getY());
  693. snuviParser.registerFunction("entity.teleport", (sc, in) ->
  694. {
  695. Entity ent = (Entity) in[0].get(sc);
  696. float x = in[1].getFloat(sc);
  697. float y = in[2].getFloat(sc);
  698. ent.setPosition(x, y);
  699. ent.setPosition(x, y);
  700. return Void.TYPE;
  701. });
  702. snuviParser.registerFunction("entity.getmotionx", (sc, in) -> (double) ((Entity) in[0].get(sc)).getOwnForceX());
  703. snuviParser.registerFunction("entity.getmotiony", (sc, in) -> (double) ((Entity) in[0].get(sc)).getOwnForceY());
  704. snuviParser.registerFunction("entity.setmotionx", (sc, in) ->
  705. {
  706. ((Entity) in[0].get(sc)).applyForce(in[1].getFloat(sc), 0.0f);
  707. return Void.TYPE;
  708. });
  709. snuviParser.registerFunction("entity.setmotiony", (sc, in) ->
  710. {
  711. ((Entity) in[0].get(sc)).applyForce(0.0f, in[1].getFloat(sc));
  712. return Void.TYPE;
  713. });
  714. snuviParser.registerFunction("entity.ishero", (sc, in) -> currentLevel.getHero() == in[0].get(sc));
  715. snuviParser.registerFunction("entity.gethealth", (sc, in) -> ((Entity) in[0].get(sc)).getHealth().getHealthPercent());
  716. snuviParser.registerFunction("entity.addhealth", (sc, in) ->
  717. {
  718. ((Entity) in[0].get(sc)).getHealth().addHealthPercent(in[1].getFloat(sc));
  719. return Void.TYPE;
  720. });
  721. snuviParser.registerFunction("entity.getenergy", (sc, in) -> ((Entity) in[0].get(sc)).getEnergy().getEnergyPercent());
  722. snuviParser.registerFunction("entity.addenergy", (sc, in) ->
  723. {
  724. ((Entity) in[0].get(sc)).getEnergy().addEnergyPercent(in[1].getFloat(sc));
  725. return Void.TYPE;
  726. });
  727. snuviParser.registerFunction("entity.spawn", (sc, in) ->
  728. {
  729. Entity ent = EntityBuilder.fromId(in[0].getInt(sc), currentLevel, in[1].getFloat(sc), in[2].getFloat(sc));
  730. if(ent != null)
  731. {
  732. currentLevel.spawnEntity(ent);
  733. }
  734. return ent;
  735. });
  736. snuviParser.registerFunction("entity.remove", (sc, in) ->
  737. {
  738. Entity ent = (Entity) in[0].get(sc);
  739. // move entity out of world so it is removed
  740. ent.setPosition(0.0f, Float.MAX_VALUE * 0.5f);
  741. return Void.TYPE;
  742. });
  743. snuviParser.registerFunction("entity.gettype", (sc, in) -> ((Entity) in[0].get(sc)).getType());
  744. snuviParser.registerFunction("platform.spawn", (sc, in) ->
  745. {
  746. Entity ent = EntityBuilder.buildPlatform(currentLevel, in[0].getInt(sc), in[1].getFloat(sc), in[2].getInt(sc));
  747. currentLevel.spawnEntity(ent);
  748. return ent;
  749. });
  750. snuviParser.registerFunction("platform.addmove", (sc, in) ->
  751. {
  752. PlatformController controller = (PlatformController) ((Entity) in[0].get(sc)).getController();
  753. controller.addMoveData(in[1].getFloat(sc), in[2].getFloat(sc), in[3].getFloat(sc) * Tile.SIZE_SCALE, in[4].getFloat(sc) * Tile.SIZE_SCALE, in[5].getInt(sc));
  754. return Void.TYPE;
  755. });
  756. snuviParser.registerFunction("platform.clear", (sc, in) ->
  757. {
  758. ((PlatformController) ((Entity) in[0].get(sc)).getController()).clearMoveData();
  759. return Void.TYPE;
  760. });
  761. snuviParser.registerFunction("light.setambient", (sc, in) ->
  762. {
  763. currentLevel.setAmbientLight(in[0].getFloat(sc), in[1].getFloat(sc), in[2].getFloat(sc));
  764. return Void.TYPE;
  765. });
  766. snuviParser.registerFunction("light.setcolor", (sc, in) ->
  767. {
  768. currentLevel.getLight(in[0].getInt(sc)).setColor(in[1].getFloat(sc), in[2].getFloat(sc), in[3].getFloat(sc));
  769. return Void.TYPE;
  770. });
  771. snuviParser.registerFunction("light.setposition", (sc, in) ->
  772. {
  773. currentLevel.getLight(in[0].getInt(sc)).setPosition(in[1].getFloat(sc), in[2].getFloat(sc));
  774. return Void.TYPE;
  775. });
  776. snuviParser.registerFunction("light.setpositionsmooth", (sc, in) ->
  777. {
  778. currentLevel.getLight(in[0].getInt(sc)).setPositionSmooth(in[1].getFloat(sc), in[2].getFloat(sc));
  779. return Void.TYPE;
  780. });
  781. snuviParser.registerFunction("light.setstrength", (sc, in) ->
  782. {
  783. currentLevel.getLight(in[0].getInt(sc)).setStrength(in[1].getFloat(sc));
  784. return Void.TYPE;
  785. });
  786. }
  787. }