lua.d 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035
  1. // quantumde1 developed software, licensed under BSD-0-Clause license.
  2. module scripts.lua;
  3. import bindbc.lua;
  4. import raylib;
  5. import variables;
  6. import graphics.effects;
  7. import std.conv;
  8. import system.abstraction;
  9. import system.config;
  10. import std.string;
  11. import std.algorithm;
  12. import graphics.engine;
  13. import graphics.playback;
  14. import std.file;
  15. import graphics.collision;
  16. /*
  17. * This module provides Lua bindings for various engine functionalities.
  18. * Functions are built on top of engine built-in functions for execution from scripts.
  19. * Not all engine functions usable for scripting are yet implemented.
  20. */
  21. /* text window */
  22. extern (C) nothrow int luaL_dialogBox(lua_State* L)
  23. {
  24. showDialog = true;
  25. // parse table with text pages
  26. luaL_checktype(L, 1, LUA_TTABLE);
  27. int textTableLength = cast(int) lua_objlen(L, 1);
  28. messageGlobal = new string[](textTableLength);
  29. foreach (i; 0..textTableLength) {
  30. lua_rawgeti(L, 1, i + 1);
  31. messageGlobal[i] = luaL_checkstring(L, -1).to!string;
  32. lua_pop(L, 1);
  33. }
  34. //parse table with choices
  35. luaL_checktype(L, 2, LUA_TTABLE);
  36. int choicesLength = cast(int) lua_objlen(L, 2);
  37. choices = new string[choicesLength];
  38. foreach (i; 0..choicesLength)
  39. {
  40. lua_rawgeti(L, 2, i + 1);
  41. choices[i] = luaL_checkstring(L, -1).to!string;
  42. lua_pop(L, 1);
  43. }
  44. //if provided, get page on which choices must be shown
  45. if (lua_gettop(L) >= 3) {
  46. choicePage = cast(int)luaL_checkinteger(L, 3);
  47. }
  48. if (lua_gettop(L) >= 4 && !lua_istable(L, 4)) {
  49. typingSpeed = cast(float) luaL_checknumber(L, 4);
  50. }
  51. return 0;
  52. }
  53. extern (C) nothrow int luaL_getAnswerValue(lua_State* L)
  54. {
  55. lua_pushinteger(L, selectedChoice);
  56. return 1;
  57. }
  58. extern (C) nothrow int luaL_isDialogExecuted(lua_State *L) {
  59. lua_pushboolean(L, showDialog);
  60. return 1;
  61. }
  62. /* background drawing and loading */
  63. extern (C) nothrow int luaL_loadBackground(lua_State* L)
  64. {
  65. try
  66. {
  67. int count = cast(int)luaL_checkinteger(L, 2);
  68. if (count >= backgroundTextures.length) {
  69. backgroundTextures.length = count + 1;
  70. }
  71. if (backgroundTextures[count].texture.id != 0) {
  72. UnloadTexture(backgroundTextures[count].texture);
  73. }
  74. char* filename = cast(char*)luaL_checkstring(L, 1);
  75. backgroundTextures[count].texture = LoadTexture(filename);
  76. SetTextureFilter(backgroundTextures[count].texture, TextureFilter.TEXTURE_FILTER_BILINEAR);
  77. }
  78. catch (Exception e)
  79. {
  80. debugWriteln(e.msg);
  81. }
  82. return 0;
  83. }
  84. extern (C) nothrow int luaL_drawBackground(lua_State* L)
  85. {
  86. try
  87. {
  88. int count = cast(int)luaL_checkinteger(L, 4);
  89. debugWriteln(backgroundTextures[count]);
  90. backgroundTextures[count].height = backgroundTextures[count].texture.height;
  91. if (backgroundTextures.length < count) {
  92. backgroundTextures.length = backgroundTextures.length;
  93. }
  94. backgroundTextures[count].width = backgroundTextures[count].texture.width;
  95. backgroundTextures[count].x = luaL_checknumber(L, 1);
  96. backgroundTextures[count].y = luaL_checknumber(L, 2);
  97. backgroundTextures[count].scale = luaL_checknumber(L, 3) * scale;
  98. backgroundTextures[count].drawTexture = true;
  99. debugWriteln(backgroundTextures[count]);
  100. }
  101. catch (Exception e)
  102. {
  103. debugWriteln(e.msg);
  104. }
  105. return 0;
  106. }
  107. extern (C) nothrow int luaL_stopDrawBackground(lua_State* L)
  108. {
  109. try
  110. {
  111. int count = cast(int)luaL_checkinteger(L, 1);
  112. if (count >= backgroundTextures.length) {
  113. debugWriteln("stop draw not loaded background unavailable");
  114. } else {
  115. backgroundTextures[count].drawTexture = false;
  116. }
  117. }
  118. catch (Exception e)
  119. {
  120. debugWriteln(e.msg);
  121. }
  122. return 0;
  123. }
  124. extern (C) nothrow int luaL_unloadBackground(lua_State* L)
  125. {
  126. int count = cast(int)luaL_checkinteger(L, 1);
  127. if (count >= backgroundTextures.length) {
  128. debugWriteln("Unloading non-loaded background unavailable");
  129. } else {
  130. backgroundTextures[count].drawTexture = false;
  131. UnloadTexture(backgroundTextures[count].texture);
  132. }
  133. return 0;
  134. }
  135. /* character textures */
  136. extern (C) nothrow int luaL_loadCharacter(lua_State *L) {
  137. try
  138. {
  139. int count = cast(int) luaL_checkinteger(L, 2);
  140. if (count >= characterTextures.length) {
  141. characterTextures.length = count + 1;
  142. }
  143. if (characterTextures.length < characterTextures.length) {
  144. characterTextures.length = characterTextures.length;
  145. }
  146. if (count < characterTextures.length && characterTextures[count].texture.id != 0) {
  147. UnloadTexture(characterTextures[count].texture);
  148. }
  149. characterTextures[count].texture = LoadTexture(luaL_checkstring(L, 1));
  150. SetTextureFilter(characterTextures[count].texture, TextureFilter.TEXTURE_FILTER_BILINEAR);
  151. characterTextures[count].width = characterTextures[count].texture.width;
  152. characterTextures[count].height = characterTextures[count].texture.height;
  153. characterTextures[count].drawTexture = false;
  154. }
  155. catch (Exception e) {
  156. debugWriteln(e.msg);
  157. }
  158. return 0;
  159. }
  160. extern (C) nothrow int luaL_drawCharacter(lua_State* L)
  161. {
  162. try {
  163. //configuring needed parameters in characterTextures like coordinates, scale and drawTexture(its a boolean value which checks need this texture to be drawn or not)
  164. int count = to!int(luaL_checkinteger(L, 4));
  165. characterTextures[count].scale = luaL_checknumber(L, 3) * scale;
  166. characterTextures[count].y = cast(int) luaL_checknumber(L, 2);
  167. characterTextures[count].x = cast(int) luaL_checknumber(L, 1);
  168. characterTextures[count].drawTexture = true;
  169. characterTextures[count].justDrawn = true;
  170. if (lua_gettop(L) == 5) {
  171. lua_getfield(L, 5, "r");
  172. characterTextures[count].color.r = cast(ubyte)lua_tointeger(L, -1);
  173. lua_pop(L, 1);
  174. lua_getfield(L, 5, "g");
  175. characterTextures[count].color.g = cast(ubyte)lua_tointeger(L, -1);
  176. lua_pop(L, 1);
  177. lua_getfield(L, 5, "b");
  178. characterTextures[count].color.b = cast(ubyte)lua_tointeger(L, -1);
  179. lua_pop(L, 1);
  180. lua_getfield(L, 5, "a");
  181. //if empty, reset to default
  182. if (!lua_isnil(L, -1)) {
  183. characterTextures[count].color.a = cast(ubyte)lua_tointeger(L, -1);
  184. }
  185. lua_pop(L, 1);
  186. } else {
  187. characterTextures[count].color = Colors.WHITE;
  188. }
  189. debugWriteln("Count: ", count, " drawTexture cond: ", characterTextures[count].drawTexture);
  190. debugWriteln("arguments count: ", lua_gettop(L));
  191. } catch (Exception e) {
  192. debugWriteln(e.msg);
  193. }
  194. return 0;
  195. }
  196. extern (C) nothrow int luaL_stopDrawCharacter(lua_State* L)
  197. {
  198. int count = cast(int) luaL_checkinteger(L, 1);
  199. if (count >= characterTextures.length) {
  200. debugWriteln("error stop draw not loaded character");
  201. } else {
  202. characterTextures[count].drawTexture = false;
  203. }
  204. return 0;
  205. }
  206. extern (C) nothrow int luaL_unloadCharacter(lua_State *L) {
  207. int count = cast(int) luaL_checkinteger(L, 1);
  208. if (count >= characterTextures.length) {
  209. debugWriteln("error unloading not loaded character");
  210. } else {
  211. characterTextures[count].drawTexture = false;
  212. UnloadTexture(characterTextures[count].texture);
  213. }
  214. return 0;
  215. }
  216. /* music and video */
  217. extern (C) nothrow int luaL_loadMusic(lua_State* L)
  218. {
  219. try
  220. {
  221. char* musicPath = cast(char*)luaL_checkstring(L, 1);
  222. music = LoadMusicStream(musicPath);
  223. }
  224. catch (Exception e)
  225. {
  226. debugWriteln(e.msg);
  227. }
  228. return 0;
  229. }
  230. extern (C) nothrow int luaL_playMusic(lua_State* L)
  231. {
  232. PlayMusicStream(music);
  233. return 0;
  234. }
  235. extern (C) nothrow int luaL_stopMusic(lua_State* L)
  236. {
  237. StopMusicStream(music);
  238. return 0;
  239. }
  240. extern (C) nothrow int luaL_unloadMusic(lua_State* L)
  241. {
  242. UnloadMusicStream(music);
  243. music = Music();
  244. return 0;
  245. }
  246. extern (C) nothrow int luaL_setMusicVolume(lua_State *L) {
  247. SetMusicVolume(music, luaL_checknumber(L, 1));
  248. return 0;
  249. }
  250. extern (C) nothrow int luaL_playSfx(lua_State *L) {
  251. try {
  252. playSfx(to!string(luaL_checkstring(L, 1)));
  253. } catch (Exception e) {
  254. debugWriteln(e.msg);
  255. }
  256. return 0;
  257. }
  258. extern (C) nothrow int luaL_stopSfx(lua_State *L) {
  259. StopSound(sfx);
  260. return 0;
  261. }
  262. extern (C) nothrow int luaL_playVideo(lua_State* L)
  263. {
  264. try
  265. {
  266. videoFinished = false;
  267. playVideo(luaL_checkstring(L, 1).to!string);
  268. }
  269. catch (Exception e)
  270. {
  271. debugWriteln(e.msg);
  272. }
  273. return 0;
  274. }
  275. /* ui animations */
  276. extern (C) nothrow int luaL_loadUIAnimation(lua_State *L) {
  277. try {
  278. //loads from uifx folder HPFF files, in which png textures are stored
  279. framesUI = loadAnimationFramesUI(to!string(luaL_checkstring(L, 1)), to!string(luaL_checkstring(L, 2)));
  280. if (lua_gettop(L) == 3) {
  281. frameDuration = luaL_checknumber(L, 3);
  282. debug debugWriteln("frameDuration: ", frameDuration);
  283. }
  284. } catch (Exception e) {
  285. debugWriteln(e.msg);
  286. }
  287. return 0;
  288. }
  289. extern (C) nothrow int luaL_playUIAnimation(lua_State *L) {
  290. debug debugWriteln("Animation UI start");
  291. try {
  292. if (lua_gettop(L) == 0) playAnimation = true;
  293. else {
  294. debugWriteln("animationAlpha before reconfig: ", animationAlpha);
  295. animationAlpha = luaL_checkinteger(L, 1).to!ubyte;
  296. debugWriteln("animationAlpha after reconfig: ", animationAlpha);
  297. playAnimation = true;
  298. }
  299. } catch (Exception e) {
  300. debugWriteln(e.msg);
  301. }
  302. return 0;
  303. }
  304. extern (C) nothrow int luaL_stopUIAnimation(lua_State *L) {
  305. playAnimation = false;
  306. debug debugWriteln("Animation UI stop");
  307. frameDuration = 0.016f;
  308. currentFrame = 0;
  309. return 0;
  310. }
  311. extern (C) nothrow int luaL_unloadUIAnimation(lua_State *L) {
  312. try {
  313. for (int i = 0; i < framesUI.length; i++) {
  314. UnloadTexture(framesUI[i]);
  315. }
  316. } catch (Exception e) {
  317. debugWriteln(e.msg);
  318. }
  319. return 0;
  320. }
  321. extern (C) nothrow int luaL_setDialogBoxBackground(lua_State *L) {
  322. string filename = luaL_checkstring(L, 1).to!string;
  323. debug debugWriteln("Set dialog background to: ", filename);
  324. UnloadTexture(dialogBackgroundTex);
  325. dialogBackgroundTex = Texture2D();
  326. dialogBackgroundTex = LoadTexture(filename.toStringz());
  327. return 0;
  328. }
  329. extern (C) nothrow int luaL_setDialogBoxEndIndicatorTexture(lua_State *L) {
  330. char* filename = cast(char*)luaL_checkstring(L, 1);
  331. UnloadTexture(circle);
  332. circle = Texture2D();
  333. circle = LoadTexture(filename);
  334. return 0;
  335. }
  336. /* system */
  337. extern (C) nothrow int luaL_getScreenWidth(lua_State* L)
  338. {
  339. lua_pushinteger(L, GetScreenWidth());
  340. return 1;
  341. }
  342. extern (C) nothrow int luaL_getScreenHeight(lua_State* L)
  343. {
  344. lua_pushinteger(L, GetScreenHeight());
  345. return 1;
  346. }
  347. extern (C) nothrow int luaL_unloadFont(lua_State *L) {
  348. UnloadFont(textFont);
  349. return 0;
  350. }
  351. extern (C) nothrow int luaL_loadFont(lua_State* L)
  352. {
  353. const char* x = luaL_checkstring(L, 1);
  354. debugWriteln("Setting custom font: ", x.to!string);
  355. int[512] codepoints = 0;
  356. //configuring both cyrillic and latin fonts if available
  357. foreach (i; 0 .. 95)
  358. {
  359. codepoints[i] = 32 + i;
  360. }
  361. foreach (i; 0 .. 255)
  362. {
  363. codepoints[96 + i] = 0x400 + i;
  364. }
  365. int fontSize = max(10, cast(int)(40 * scale));
  366. textFont = LoadFontEx(x, fontSize, null, 0);
  367. return 0;
  368. }
  369. extern (C) nothrow int luaL_getTime(lua_State* L)
  370. {
  371. //getTime() returns current time.
  372. lua_pushnumber(L, GetTime());
  373. return 1;
  374. }
  375. extern (C) nothrow int luaL_getDeltaTime(lua_State* L)
  376. {
  377. //getDeltaTime
  378. lua_pushnumber(L, GetFrameTime());
  379. return 1;
  380. }
  381. float lastKeyPressTime = 0.0;
  382. immutable float keyPressCooldown = 0.2;
  383. extern (C) nothrow int luaL_isKeyPressed(lua_State* L)
  384. {
  385. try
  386. {
  387. int keyCode = cast(int)luaL_checkinteger(L, 1);
  388. bool isPressed = IsKeyPressed(keyCode).to!bool;
  389. double currentTime = GetTime();
  390. if (isPressed && (currentTime - lastKeyPressTime) < keyPressCooldown)
  391. {
  392. lua_pushboolean(L, false);
  393. }
  394. else if (isPressed)
  395. {
  396. lastKeyPressTime = currentTime;
  397. lua_pushboolean(L, true);
  398. }
  399. else
  400. {
  401. lua_pushboolean(L, false);
  402. }
  403. return 1;
  404. }
  405. catch (Exception e)
  406. {
  407. debugWriteln(e.msg);
  408. lua_pushboolean(L, false);
  409. return 1;
  410. }
  411. }
  412. extern (C) nothrow int luaL_isKeyDown(lua_State *L) {
  413. return IsKeyDown(cast(int)luaL_checkinteger(L, 1));
  414. }
  415. extern (C) nothrow int luaL_isMouseButtonPressed(lua_State* L)
  416. {
  417. try
  418. {
  419. int keyCode = cast(int)luaL_checkinteger(L, 1);
  420. bool isPressed = IsMouseButtonPressed(keyCode);
  421. double currentTime = GetTime();
  422. if (isPressed && (currentTime - lastKeyPressTime) < keyPressCooldown)
  423. {
  424. lua_pushboolean(L, false);
  425. }
  426. else if (isPressed)
  427. {
  428. lastKeyPressTime = currentTime;
  429. lua_pushboolean(L, true);
  430. }
  431. else
  432. {
  433. lua_pushboolean(L, false);
  434. }
  435. return 1;
  436. }
  437. catch (Exception e)
  438. {
  439. debugWriteln(e.msg);
  440. lua_pushboolean(L, false);
  441. return 1;
  442. }
  443. }
  444. extern (C) nothrow int luaL_isMouseButtonDown(lua_State* L)
  445. {
  446. try
  447. {
  448. int keyCode = cast(int)luaL_checkinteger(L, 1);
  449. bool isPressed = IsMouseButtonDown(keyCode);
  450. double currentTime = GetTime();
  451. if (isPressed && (currentTime - lastKeyPressTime) < keyPressCooldown)
  452. {
  453. lua_pushboolean(L, false);
  454. }
  455. else if (isPressed)
  456. {
  457. lastKeyPressTime = currentTime;
  458. lua_pushboolean(L, true);
  459. }
  460. else
  461. {
  462. lua_pushboolean(L, false);
  463. }
  464. return 1;
  465. }
  466. catch (Exception e)
  467. {
  468. debugWriteln(e.msg);
  469. lua_pushboolean(L, false);
  470. return 1;
  471. }
  472. }
  473. extern (C) nothrow int luaL_getMouseX(lua_State *L) {
  474. lua_pushnumber(L, GetMousePosition.x);
  475. return 1;
  476. }
  477. extern (C) nothrow int luaL_getMouseY(lua_State *L) {
  478. lua_pushnumber(L, GetMousePosition.y);
  479. return 1;
  480. }
  481. extern (C) nothrow int luaL_loadScript(lua_State* L)
  482. {
  483. try
  484. {
  485. luaExec = luaL_checkstring(L, 1).to!string;
  486. }
  487. catch (Exception e)
  488. {
  489. debugWriteln(e.msg);
  490. }
  491. luaReload = true;
  492. return 0;
  493. }
  494. extern (C) nothrow int luaL_setGameState(lua_State *L) {
  495. currentGameState = cast(int)luaL_checkinteger(L, 1);
  496. return 0;
  497. }
  498. extern (C) nothrow int luaL_setCamera(lua_State *L) {
  499. camera.position = Vector3(
  500. luaL_checknumber(L, 1),
  501. luaL_checknumber(L, 2),
  502. luaL_checknumber(L, 3)
  503. );
  504. camera.target = Vector3(
  505. luaL_checknumber(L, 4),
  506. luaL_checknumber(L, 5),
  507. luaL_checknumber(L, 6)
  508. );
  509. return 0;
  510. }
  511. ModelAnimation *modelAnimations;
  512. int animationCurrentFrame = 0;
  513. int animsCount = 0;
  514. extern (C) nothrow int luaL_loadModelAnimations(lua_State *L) {
  515. modelAnimations = LoadModelAnimations(luaL_checkstring(L, 1), &animsCount);
  516. return 0;
  517. }
  518. extern (C) nothrow int luaL_updateModelAnimation(lua_State *L) {
  519. ModelAnimation anim = modelAnimations[cast(int)luaL_checkinteger(L, 2)];
  520. int speedMultipler;
  521. if (lua_gettop(L) == 3) {
  522. speedMultipler = cast(int)luaL_checkinteger(L, 3);
  523. } else {
  524. speedMultipler = 1;
  525. }
  526. animationCurrentFrame = (animationCurrentFrame + speedMultipler)%anim.frameCount;
  527. Model *model = cast(Model*)luaL_checkudata(L, 1, "Model");
  528. UpdateModelAnimation(*model, anim, animationCurrentFrame);
  529. return 0;
  530. }
  531. extern (C) nothrow int luaL_resetModelAnimation(lua_State *L) {
  532. animationCurrentFrame = 0;
  533. return 0;
  534. }
  535. extern (C) nothrow int luaL_placeCollision(lua_State *L) {
  536. try {
  537. placeOBB(
  538. cast(int)luaL_checkinteger(L, 1),
  539. Vector3(
  540. luaL_checknumber(L, 2),
  541. luaL_checknumber(L, 3),
  542. luaL_checknumber(L, 4)
  543. ),
  544. Vector3(
  545. luaL_checknumber(L, 5),
  546. luaL_checknumber(L, 6),
  547. luaL_checknumber(L, 7)
  548. ),
  549. Vector3(
  550. luaL_checknumber(L, 8),
  551. luaL_checknumber(L, 9),
  552. luaL_checknumber(L, 10)
  553. ),
  554. );
  555. } catch (Exception e) {
  556. debugWriteln("Error placing obb: ", e.msg);
  557. }
  558. return 0;
  559. }
  560. extern (C) nothrow int luaL_moveCollision(lua_State *L) {
  561. collisions[cast(int)luaL_checkinteger(L, 1)].center = Vector3(
  562. luaL_checknumber(L, 2),
  563. luaL_checknumber(L, 3),
  564. luaL_checknumber(L, 4)
  565. );
  566. return 0;
  567. }
  568. extern (C) nothrow int luaL_removeCollision(lua_State *L) {
  569. collisions = collisions[0 .. cast(int)luaL_checkinteger(L, 1)] ~ collisions[cast(int)luaL_checkinteger(L, 1) .. $];
  570. return 0;
  571. }
  572. extern (C) nothrow int luaL_setPlayerCollisionIndex(lua_State *L) {
  573. playerCollisionIndex = cast(int)luaL_checkinteger(L, 1);
  574. return 0;
  575. }
  576. extern (C) nothrow int luaL_drawCollisionWires(lua_State *L) {
  577. try {
  578. for (int i = 0; i < collisions.length; i++) {
  579. drawWireframe(collisions[i], Colors.RED);
  580. }
  581. } catch (Exception e) {
  582. }
  583. return 0;
  584. }
  585. extern (C) nothrow int luaL_checkCollision(lua_State *L) {
  586. try {
  587. for (int i = 0; i < collisions.length; i++) {
  588. debugWriteln("collision index check: ", i);
  589. bool collided = checkCollisionOBBvsOBB(collisions[playerCollisionIndex], collisions[i]);
  590. if (collided == true) {
  591. lua_pushboolean(L, true);
  592. }
  593. else lua_pushboolean(L, false);
  594. }
  595. } catch (Exception e) {
  596. }
  597. return 1;
  598. }
  599. extern (C) nothrow int luaL_checkCollisionIndex(lua_State *L) {
  600. try {
  601. bool collided = checkCollisionOBBvsOBB(collisions[cast(int)luaL_checkinteger(L, 1)], collisions[cast(int)luaL_checkinteger(L, 2)]);
  602. if (collided == true) {
  603. lua_pushboolean(L, true);
  604. }
  605. else lua_pushboolean(L, false);
  606. } catch (Exception e) {
  607. }
  608. return 1;
  609. }
  610. /* raylib direct bindings for graphics */
  611. /* basic */
  612. extern (C) nothrow int luaL_loadTexture(lua_State *L) {
  613. const char* fileName = luaL_checkstring(L, 1);
  614. Texture2D texture = LoadTexture(fileName);
  615. Texture2D* texturePtr = cast(Texture2D*)lua_newuserdata(L, Texture2D.sizeof);
  616. *texturePtr = texture;
  617. if (luaL_newmetatable(L, "Texture")) {
  618. lua_pushcfunction(L, &luaL_textureGC);
  619. lua_setfield(L, -2, "__gc");
  620. }
  621. SetTextureFilter(texture, TextureFilter.TEXTURE_FILTER_BILINEAR);
  622. lua_setmetatable(L, -2);
  623. return 1;
  624. }
  625. extern (C) nothrow int luaL_textureGC(lua_State *L) {
  626. Texture2D* texture = cast(Texture2D*)luaL_checkudata(L, 1, "Texture");
  627. UnloadTexture(*texture);
  628. return 0;
  629. }
  630. extern (C) nothrow int luaL_unloadTexture(lua_State *L) {
  631. Texture2D* texture = cast(Texture2D*)luaL_checkudata(L, 1, "Texture");
  632. UnloadTexture(*texture);
  633. return 0;
  634. }
  635. extern (C) nothrow int luaL_drawTexture(lua_State *L) {
  636. Texture2D* texture = cast(Texture2D*)luaL_checkudata(L, 1, "Texture");
  637. int x = cast(int)luaL_checkinteger(L, 2);
  638. int y = cast(int)luaL_checkinteger(L, 3);
  639. Color color = Colors.WHITE;
  640. if (lua_gettop(L) >= 4 && lua_istable(L, 4)) {
  641. lua_getfield(L, 4, "r");
  642. color.r = cast(ubyte)lua_tointeger(L, -1);
  643. lua_pop(L, 1);
  644. lua_getfield(L, 4, "g");
  645. color.g = cast(ubyte)lua_tointeger(L, -1);
  646. lua_pop(L, 1);
  647. lua_getfield(L, 4, "b");
  648. color.b = cast(ubyte)lua_tointeger(L, -1);
  649. lua_pop(L, 1);
  650. lua_getfield(L, 4, "a");
  651. color.a = cast(ubyte)lua_tointeger(L, -1);
  652. lua_pop(L, 1);
  653. }
  654. DrawTextureEx(*texture, Vector2(x, y), 0.0f, scale, color);
  655. return 0;
  656. }
  657. extern (C) nothrow int luaL_getTextureWidth(lua_State *L) {
  658. Texture2D* texture = cast(Texture2D*)luaL_checkudata(L, 1, "Texture");
  659. lua_pushnumber(L, texture.width*variables.scale);
  660. return 1;
  661. }
  662. extern (C) nothrow int luaL_getTextureHeight(lua_State *L) {
  663. Texture2D* texture = cast(Texture2D*)luaL_checkudata(L, 1, "Texture");
  664. lua_pushnumber(L, texture.height*variables.scale);
  665. return 1;
  666. }
  667. extern (C) nothrow int luaL_drawText(lua_State *L) {
  668. const char* text = luaL_checkstring(L, 1);
  669. int x = cast(int)luaL_checkinteger(L, 2);
  670. int y = cast(int)luaL_checkinteger(L, 3);
  671. int fontSize = cast(int)luaL_optinteger(L, 4, 20);
  672. Color color = Colors.WHITE;
  673. if (lua_istable(L, 5)) {
  674. lua_getfield(L, 5, "r");
  675. color.r = cast(ubyte)lua_tointeger(L, -1);
  676. lua_pop(L, 1);
  677. lua_getfield(L, 5, "g");
  678. color.g = cast(ubyte)lua_tointeger(L, -1);
  679. lua_pop(L, 1);
  680. lua_getfield(L, 5, "b");
  681. color.b = cast(ubyte)lua_tointeger(L, -1);
  682. lua_pop(L, 1);
  683. lua_getfield(L, 5, "a");
  684. color.a = cast(ubyte)lua_tointeger(L, -1);
  685. lua_pop(L, 1);
  686. }
  687. DrawTextEx(textFont, text, Vector2(x, y), fontSize, 1.0f, color);
  688. return 0;
  689. }
  690. extern (C) nothrow int luaL_measureTextX(lua_State *L) {
  691. lua_pushinteger(L, cast(int)MeasureTextEx(textFont, luaL_checkstring(L, 1), cast(int)luaL_checkinteger(L, 2), 1.0f).x);
  692. return 1;
  693. }
  694. extern (C) nothrow int luaL_measureTextY(lua_State *L) {
  695. lua_pushinteger(L, cast(int)MeasureTextEx(textFont, luaL_checkstring(L, 1), cast(int)luaL_checkinteger(L, 2), 1.0f).y);
  696. return 1;
  697. }
  698. /* extended */
  699. extern (C) nothrow int luaL_drawTextureEx(lua_State *L) {
  700. Texture2D* texture = cast(Texture2D*)luaL_checkudata(L, 1, "Texture");
  701. float x = luaL_checknumber(L, 2);
  702. float y = luaL_checknumber(L, 3);
  703. float rotation = luaL_optnumber(L, 4, 0);
  704. float scale = luaL_optnumber(L, 5, 1);
  705. Color color = Colors.WHITE;
  706. if (lua_istable(L, 6)) {
  707. lua_getfield(L, 6, "r");
  708. color.r = cast(ubyte)lua_tointeger(L, -1);
  709. lua_pop(L, 1);
  710. lua_getfield(L, 6, "g");
  711. color.g = cast(ubyte)lua_tointeger(L, -1);
  712. lua_pop(L, 1);
  713. lua_getfield(L, 6, "b");
  714. color.b = cast(ubyte)lua_tointeger(L, -1);
  715. lua_pop(L, 1);
  716. lua_getfield(L, 6, "a");
  717. color.a = cast(ubyte)lua_tointeger(L, -1);
  718. lua_pop(L, 1);
  719. }
  720. DrawTextureEx(*texture, Vector2(x, y), rotation, scale*variables.scale, color);
  721. return 0;
  722. }
  723. extern (C) nothrow int luaL_drawRect(lua_State *L) {
  724. DrawRectangle(cast(int)luaL_checkinteger(L, 1), cast(int)luaL_checkinteger(L, 2), cast(int)luaL_checkinteger(L, 3), cast(int)luaL_checkinteger(L, 4), Colors.WHITE);
  725. return 0;
  726. }
  727. extern (C) nothrow int luaL_loadModel(lua_State *L) {
  728. const char* fileName = luaL_checkstring(L, 1);
  729. Model model = LoadModel(fileName);
  730. Model* modelPtr = cast(Model*)lua_newuserdata(L, Model.sizeof);
  731. *modelPtr = model;
  732. if (luaL_newmetatable(L, "Model")) {
  733. lua_pushcfunction(L, &luaL_textureGC);
  734. lua_setfield(L, -2, "__gc");
  735. }
  736. lua_setmetatable(L, -2);
  737. return 1;
  738. }
  739. extern (C) nothrow int luaL_drawModel(lua_State *L) {
  740. Model* model = cast(Model*)luaL_checkudata(L, 1, "Model");
  741. float x = luaL_checknumber(L, 2);
  742. float y = luaL_checknumber(L, 3);
  743. float z = luaL_checknumber(L, 4);
  744. float rotation = luaL_optnumber(L, 5, 0);
  745. float scale = luaL_optnumber(L, 6, 1);
  746. Color color = Colors.WHITE;
  747. if (lua_istable(L, 6)) {
  748. lua_getfield(L, 6, "r");
  749. color.r = cast(ubyte)lua_tointeger(L, -1);
  750. lua_pop(L, 1);
  751. lua_getfield(L, 6, "g");
  752. color.g = cast(ubyte)lua_tointeger(L, -1);
  753. lua_pop(L, 1);
  754. lua_getfield(L, 6, "b");
  755. color.b = cast(ubyte)lua_tointeger(L, -1);
  756. lua_pop(L, 1);
  757. lua_getfield(L, 6, "a");
  758. color.a = cast(ubyte)lua_tointeger(L, -1);
  759. lua_pop(L, 1);
  760. }
  761. DrawModelEx(
  762. *model,
  763. Vector3(x, y, z),
  764. Vector3(0.0f, 1.0f, 0.0f),
  765. rotation,
  766. Vector3(scale, scale, scale),
  767. color
  768. );
  769. return 0;
  770. }
  771. extern (C) nothrow int luaL_showCursor(lua_State *L) {
  772. ShowCursor();
  773. return 0;
  774. }
  775. extern (C) nothrow int luaL_hideCursor(lua_State *L) {
  776. HideCursor();
  777. return 0;
  778. }
  779. extern (C) nothrow int luaL_setMousePosition(lua_State *L) {
  780. SetMousePosition(cast(int)luaL_checkinteger(L, 1), cast(int)luaL_checkinteger(L, 2));
  781. return 0;
  782. }
  783. extern (C) nothrow int luaL_drawFPS(lua_State *L) {
  784. DrawFPS(cast(int)luaL_checkinteger(L, 1), cast(int)luaL_checkinteger(L, 2));
  785. return 0;
  786. }
  787. /* Register functions */
  788. extern (C) nothrow void luaL_loader(lua_State* L)
  789. {
  790. lua_register(L, "dialogBox", &luaL_dialogBox);
  791. lua_register(L, "isDialogExecuted", &luaL_isDialogExecuted);
  792. lua_register(L, "getAnswerValue", &luaL_getAnswerValue);
  793. lua_register(L, "loadAnimationUI", &luaL_loadUIAnimation);
  794. lua_register(L, "playAnimationUI", &luaL_playUIAnimation);
  795. lua_register(L, "stopAnimationUI", &luaL_stopUIAnimation);
  796. lua_register(L, "unloadAnimationUI", &luaL_unloadUIAnimation);
  797. lua_register(L, "setDialogBoxBackground", &luaL_setDialogBoxBackground);
  798. lua_register(L, "setDialogEndIndicator", &luaL_setDialogBoxEndIndicatorTexture);
  799. lua_register(L, "playVideo", &luaL_playVideo);
  800. lua_register(L, "loadMusic", &luaL_loadMusic);
  801. lua_register(L, "playMusic", &luaL_playMusic);
  802. lua_register(L, "stopMusic", &luaL_stopMusic);
  803. lua_register(L, "unloadMusic", &luaL_unloadMusic);
  804. lua_register(L, "setMusicVolume", &luaL_setMusicVolume);
  805. lua_register(L, "playSfx", &luaL_playSfx);
  806. lua_register(L, "stopSfx", &luaL_stopSfx);
  807. lua_register(L, "loadCharacter", &luaL_loadCharacter);
  808. lua_register(L, "drawCharacter", &luaL_drawCharacter);
  809. lua_register(L, "stopDrawCharacter", &luaL_stopDrawCharacter);
  810. lua_register(L, "unloadCharacter", &luaL_unloadCharacter);
  811. lua_register(L, "loadBackground", &luaL_loadBackground);
  812. lua_register(L, "drawBackground", &luaL_drawBackground);
  813. lua_register(L, "stopDrawBackground", &luaL_stopDrawBackground);
  814. lua_register(L, "unloadBackground", &luaL_unloadBackground);
  815. lua_register(L, "loadScript", &luaL_loadScript);
  816. lua_register(L, "getScreenHeight", &luaL_getScreenHeight);
  817. lua_register(L, "getScreenWidth", &luaL_getScreenWidth);
  818. lua_register(L, "isKeyPressed", &luaL_isKeyPressed);
  819. lua_register(L, "isKeyDown", &luaL_isKeyDown);
  820. lua_register(L, "isMouseButtonPressed", &luaL_isMouseButtonPressed);
  821. lua_register(L, "isMouseButtonDown", &luaL_isMouseButtonDown);
  822. lua_register(L, "getMouseX", &luaL_getMouseX);
  823. lua_register(L, "getMouseY", &luaL_getMouseY);
  824. lua_register(L, "setGameState", &luaL_setGameState);
  825. lua_register(L, "setCamera", &luaL_setCamera);
  826. lua_register(L, "loadModelAnimations", &luaL_loadModelAnimations);
  827. lua_register(L, "updateModelAnimation", &luaL_updateModelAnimation);
  828. lua_register(L, "resetModelAnimation", &luaL_resetModelAnimation);
  829. lua_register(L, "placeCollision", &luaL_placeCollision);
  830. lua_register(L, "moveCollision", &luaL_moveCollision);
  831. lua_register(L, "removeCollision", &luaL_removeCollision);
  832. lua_register(L, "playerCollisionIndex", &luaL_setPlayerCollisionIndex);
  833. lua_register(L, "drawCollision", &luaL_drawCollisionWires);
  834. lua_register(L, "checkAllCollision", &luaL_checkCollision);
  835. lua_register(L, "checkSpecificCollision", &luaL_checkCollisionIndex);
  836. //raylib direct bindings
  837. lua_register(L, "drawRectangle", &luaL_drawRect);
  838. lua_register(L, "unloadFont", &luaL_unloadFont);
  839. lua_register(L, "loadFont", &luaL_loadFont);
  840. lua_register(L, "getTime", &luaL_getTime);
  841. lua_register(L, "getDeltaTime", &luaL_getDeltaTime);
  842. lua_register(L, "loadTexture", &luaL_loadTexture);
  843. lua_register(L, "drawTexture", &luaL_drawTexture);
  844. lua_register(L, "drawTextureEx", &luaL_drawTextureEx);
  845. lua_register(L, "unloadTexture", &luaL_unloadTexture);
  846. lua_register(L, "drawText", &luaL_drawText);
  847. lua_register(L, "measureTextX", &luaL_measureTextX);
  848. lua_register(L, "measureTextY", &luaL_measureTextY);
  849. lua_register(L, "getTextureWidth", &luaL_getTextureWidth);
  850. lua_register(L, "getTextureHeight", &luaL_getTextureHeight);
  851. lua_register(L, "loadModel", &luaL_loadModel);
  852. lua_register(L, "drawModel", &luaL_drawModel);
  853. lua_register(L, "showCursor", &luaL_showCursor);
  854. lua_register(L, "hideCursor", &luaL_hideCursor);
  855. lua_register(L, "setMousePosition", &luaL_setMousePosition);
  856. lua_register(L, "drawFPS", &luaL_drawFPS);
  857. //compat
  858. lua_register(L, "setFont", &luaL_loadFont);
  859. debugWriteln("strict mode enabled");
  860. const char* strict_lua =
  861. `local mt = {
  862. __index = function(_, name)
  863. error("attempt to call undefined function: " .. tostring(name), 2)
  864. end
  865. }
  866. setmetatable(_G, mt)`;
  867. if (luaL_dostring(L, strict_lua) != LUA_OK) {
  868. debugWriteln("Failed to set strict mode: ", to!string(lua_tostring(L, -1)));
  869. lua_pop(L, 1); // Pop the error message
  870. }
  871. }
  872. int luaInit(string luaExec)
  873. {
  874. debugWriteln("loading Lua");
  875. L = luaL_newstate();
  876. luaL_openlibs(L);
  877. luaL_loader(L);
  878. debugWriteln("Executing next Lua file: ", luaExec);
  879. if (std.file.exists(luaExec) == false) {
  880. debugWriteln("Script file not found! Exiting.");
  881. return EngineExitCodes.EXIT_FILE_NOT_FOUND;
  882. }
  883. if (luaL_dofile(L, toStringz(luaExec)) != LUA_OK) {
  884. debugWriteln("Lua error: ", to!string(lua_tostring(L, -1)));
  885. return EngineExitCodes.EXIT_SCRIPT_ERROR;
  886. }
  887. return EngineExitCodes.EXIT_OK;
  888. }
  889. void luaEventLoop2D()
  890. {
  891. lua_getglobal(L, "EventLoop2D");
  892. if (lua_pcall(L, 0, 0, 0) != LUA_OK)
  893. {
  894. debug debugWriteln("Error in EventLoop2D: ", to!string(lua_tostring(L, -1)));
  895. }
  896. lua_pop(L, 0);
  897. }
  898. void luaEventLoop3D()
  899. {
  900. lua_getglobal(L, "EventLoop3D");
  901. if (lua_pcall(L, 0, 0, 0) != LUA_OK)
  902. {
  903. debug debugWriteln("Error in EventLoop3D: ", to!string(lua_tostring(L, -1)));
  904. }
  905. lua_pop(L, 0);
  906. }