GT.js 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. This script replicates the functionality of the GT-statement in QSP.
  3. In QSP, you can have several jumps in a row after each user-input without a hazzle.
  4. That's not the case in SugarCube.
  5. Since the first passage doesn't stop rendering when the second one is called the output is scrambled.
  6. For the user, that usually looks like a black- or whitescreen.
  7. To solve this issue, gt-commands are only excecuted once a passage is completely rendered.
  8. To achieve that, they get queued in `pendingGTs` and called on the `:passageend`-event.
  9. */
  10. /**
  11. * Indicates the number of currently running gt-commands.
  12. * Gets reset to 0 on the `:passageend`-event.
  13. * Since multiple running gt-events are to be avoided, a number bigger than 1 indicates a bug.
  14. * @type {number}
  15. */
  16. let gtExecutionCounter = 0;
  17. /**
  18. * The queued gt-events (FIFO). One entry is the array of arguments the gt-command has to be executed with.
  19. * @type {(string|number)[]}
  20. */
  21. const pendingGTs = [];
  22. /** Execute the next gt-command from `pendingGTs` if the queue is not empty. */
  23. const executeNextPendingGT = ()=>{
  24. if(!pendingGTs.length)
  25. return;
  26. const nextPendingGT = pendingGTs.shift();
  27. setup.qsp_gt(...nextPendingGT);
  28. }
  29. $(document).on(':passageend', function (ev) {
  30. gtExecutionCounter = 0;
  31. executeNextPendingGT();
  32. });
  33. setup.qsp_gt = function(...args){
  34. if(++gtExecutionCounter > 1){
  35. pendingGTs.push(args);
  36. return;
  37. }
  38. const _recursion_limit = 5;
  39. setup.recursionCounterGT ??= [0,0];
  40. const recursionInterval = Math.floor(Date.now() / 500);
  41. if(setup.recursionCounterGT[0] < recursionInterval)
  42. setup.recursionCounterGT = [recursionInterval,0];
  43. setup.recursionCounterGT[1] += 1;
  44. if(setup.recursionCounterGT[1] > _recursion_limit){
  45. console.error('Recursion limit reached in GT: (args, here)',args,State.variables.here);
  46. return;
  47. }
  48. let destination = '';
  49. let destinationArgs = [];
  50. if(typeof args[0] == 'string'){
  51. destination = args[0];
  52. destinationArgs = args.slice(1);
  53. }else if(Array.isArray(args[0])){
  54. destination = args[0][0];
  55. destinationArgs = args[0].slice(1);
  56. }else{
  57. console.error(`Argument not reckognized in setup.gt()`,args[0]);
  58. }
  59. State.variables.ARGSstack = [destinationArgs];
  60. console.log("GT",args,destination,destinationArgs,State.variables.ARGSstack);
  61. Engine.play(destination.toLowerCase());
  62. }
  63. Macro.add('gt', {
  64. skipArgs : false,
  65. handler : function () {
  66. try{
  67. setup.qsp_gt(...this.args);
  68. }
  69. catch (ex) {
  70. return this.error('ERROR in gt-widget: ' + ex.message);
  71. }
  72. }
  73. });