scratch extesion: pointerlock by rssaromeo

none

  1. // ==UserScript==
  2. // @name scratch extesion: pointerlock by rssaromeo
  3. // @version 4
  4. // @description none
  5. // @run-at document-start
  6. // @author rssaromeo
  7. // @license GPLv3
  8. // @match *://*/*
  9. // @include *
  10. // @tag lib
  11. // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAA8dJREFUeF7Vm/1x1DAQxW1aoIU0QGjlUgLUABVADaSE1EJo4BqAGWo4Zi8RoxP78fZDtsl/Gduy3m/frmRJty4T/h5+P1wmNLs8vX1aq9sta3CWaElwFYwSAFuLb1AqIKQA7CV8dEUGRBhARPz521lN4buPd+EUj0JwA/AItwRbaiNAvCBcAFDxWeEjGC8IDwQYgCW+WrTkDhQGCgECcBTxDUolBBOAJn6rqGfcYDlBBVAh/vnT89/+33+9t+qe+zriBg2CCKBCPKnpAdD/KITHzz9uYHz48i41hEoQWABV4jkACIRRPD1jAaB7LDdwEFwAIjk/OqCFUXNCFIAFAQKARN9jTwmA5AROPOoAZJQYIdw4ABFPL/F0UgPAQchEvy8SWjr0ECAAo/UlAK0Dfb5aAHoIHrDWcOEGgEZfc8DYKQKBAGgQqqLvSYWrAzziW+OWC3oY7y/2AtH3lR+RkeqvucFyggoAqfooCAsCByArHhkV0gC8juBAzIq+lQpUDNeI/TXLRRwxK/oWALouAkDsXwFCaoOcgk6brRFBS4VpADyjxSigT5MqCFIxZAFko98LomFQynEt+v21mRA2AdDEoCC4QlkBgXPBpgCyILIQDgOAQKBuoHuragIEoDL/qfPcVNgjnptRZpwwQvgnBY4MoMHIDJG7A5Ci32yOuiMKYVcAlvje7igI7/fCfwPAO2KgIHYD4Ik+N0GqcsShAFifyCMIFAI9JzliFwDZ6EdBcBBMAPSyyqFQ+hbwRr9B6OcA1qf3CACaCFUDkDoZASBNgNDF1MMAqBTfp4e1X7E5gMrok9DMFFhaFNl8QSQS/Yq1AdeCSEUdiESfIozsI0ScIAI4/TxdFmZJfn2zLudH/VSXd01Qiv4oqBqCtjdwlX76dXrZuViXZaUNilcg0eEQjb4WyUoIEoDrsjjplpbGKwFEFjWqIIQBRGqBFv1I7mYhQFtjmgu8EKo3OKVVpbH+cHAt8a9Z/9JUxQ4ROiPTiqd0zXKCB4D7fADqghnR74F4jtsg0b9xQHtRxgmzAXDp4Ik8Pa8ekcmmgjUXj1ife6Y5QSqqWtUf23OdEkNToUpopB3U+q3t6QclIyKiz3jFszUAqQXtnuhEKSpQei5yQNJ0gFUPjgIhI151gMcJe9QGSzhX8TkHmcflUSdsCaFKPOQArxNmpQYiGo167wTIAVEIFa5AhUfEuxzQU7N+QqNVeWvk8Ahu77F+FaL1x+WAKgiVw2BGfNgBRwCRFQ7NA9BIZVICfUd/X5X4EgeMAmbBqBTd9/kPiqWdQ5N12vYAAAAASUVORK5CYII=
  12. // @grant none
  13. // @namespace https://greasyfork.org/users/1184528
  14. // ==/UserScript==
  15. ;(async () => {
  16. await loadlib("libloader").waitforlib("scratchextesnsionmanager")
  17. const {
  18. newext,
  19. newmenu,
  20. newblock,
  21. bt,
  22. inp,
  23. gettarget,
  24. totype,
  25. scratch_math,
  26. projectid,
  27. canvas,
  28. scratchvar,
  29. scratchlist,
  30. } = loadlib("scratchextesnsionmanager")
  31. var a = loadlib("newallfuncs")
  32. var vm
  33. loadlib("libloader")
  34. .waitforlib("scratch")
  35. .then(() => (vm = loadlib("scratch").vm))
  36.  
  37. var mousepos = {}
  38. var pointerlock_active = false
  39. newext(
  40. "pointerlock",
  41. "rssaromeo",
  42. class {
  43. setpointerlock({ on }) {
  44. on = totype(on, "bool")
  45. if (on) pointerlock_active = true
  46. else {
  47. pointerlock_active = false
  48. document.exitPointerLock()
  49. }
  50. }
  51. getpointerlockengaged() {
  52. return !!document.pointerLockElement
  53. }
  54. getpointerlockstate() {
  55. if (!!document.pointerLockElement) return "active"
  56. if (pointerlock_active) return "waiting"
  57. return "dissabled"
  58. }
  59. pointerlock_mousex() {
  60. return mousepos.totalx
  61. }
  62. pointerlock_mousey() {
  63. return mousepos.totaly
  64. }
  65. pointerlock_deltax() {
  66. return mousepos.x
  67. }
  68. pointerlock_deltay() {
  69. return mousepos.y
  70. }
  71. pointerlock_resettotalpos() {
  72. mousepos = { x: 0, y: 0, totalx: 0, totaly: 0 }
  73. }
  74. },
  75. [
  76. newblock(
  77. bt.ret,
  78. "getpointerlockstate",
  79. "get pointerlock state"
  80. ),
  81. newblock(
  82. bt.bool,
  83. "getpointerlockengaged",
  84. "is pointerlock engaged?"
  85. ),
  86. newblock(bt.ret, "pointerlock_deltax", "pointerlock: delta x"),
  87. newblock(bt.ret, "pointerlock_mousex", "pointerlock: mouse x"),
  88. newblock(bt.ret, "pointerlock_deltay", "pointerlock: delta y"),
  89. newblock(bt.ret, "pointerlock_mousey", "pointerlock: mouse y"),
  90. newblock(
  91. bt.cmd,
  92. "pointerlock_resettotalpos",
  93. "pointerlock: reset mouse position to 0,0"
  94. ),
  95. newblock(bt.cmd, "setpointerlock", "set pointerlock [on]", [
  96. newmenu("setpointerlock", { items: ["true", "false"] }),
  97. ]),
  98. ],
  99. "50dd50",
  100. "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAA8dJREFUeF7Vm/1x1DAQxW1aoIU0QGjlUgLUABVADaSE1EJo4BqAGWo4Zi8RoxP78fZDtsl/Gduy3m/frmRJty4T/h5+P1wmNLs8vX1aq9sta3CWaElwFYwSAFuLb1AqIKQA7CV8dEUGRBhARPz521lN4buPd+EUj0JwA/AItwRbaiNAvCBcAFDxWeEjGC8IDwQYgCW+WrTkDhQGCgECcBTxDUolBBOAJn6rqGfcYDlBBVAh/vnT89/+33+9t+qe+zriBg2CCKBCPKnpAdD/KITHzz9uYHz48i41hEoQWABV4jkACIRRPD1jAaB7LDdwEFwAIjk/OqCFUXNCFIAFAQKARN9jTwmA5AROPOoAZJQYIdw4ABFPL/F0UgPAQchEvy8SWjr0ECAAo/UlAK0Dfb5aAHoIHrDWcOEGgEZfc8DYKQKBAGgQqqLvSYWrAzziW+OWC3oY7y/2AtH3lR+RkeqvucFyggoAqfooCAsCByArHhkV0gC8juBAzIq+lQpUDNeI/TXLRRwxK/oWALouAkDsXwFCaoOcgk6brRFBS4VpADyjxSigT5MqCFIxZAFko98LomFQynEt+v21mRA2AdDEoCC4QlkBgXPBpgCyILIQDgOAQKBuoHuragIEoDL/qfPcVNgjnptRZpwwQvgnBY4MoMHIDJG7A5Ci32yOuiMKYVcAlvje7igI7/fCfwPAO2KgIHYD4Ik+N0GqcsShAFifyCMIFAI9JzliFwDZ6EdBcBBMAPSyyqFQ+hbwRr9B6OcA1qf3CACaCFUDkDoZASBNgNDF1MMAqBTfp4e1X7E5gMrok9DMFFhaFNl8QSQS/Yq1AdeCSEUdiESfIozsI0ScIAI4/TxdFmZJfn2zLudH/VSXd01Qiv4oqBqCtjdwlX76dXrZuViXZaUNilcg0eEQjb4WyUoIEoDrsjjplpbGKwFEFjWqIIQBRGqBFv1I7mYhQFtjmgu8EKo3OKVVpbH+cHAt8a9Z/9JUxQ4ROiPTiqd0zXKCB4D7fADqghnR74F4jtsg0b9xQHtRxgmzAXDp4Ik8Pa8ekcmmgjUXj1ife6Y5QSqqWtUf23OdEkNToUpopB3U+q3t6QclIyKiz3jFszUAqQXtnuhEKSpQei5yQNJ0gFUPjgIhI151gMcJe9QGSzhX8TkHmcflUSdsCaFKPOQArxNmpQYiGo167wTIAVEIFa5AhUfEuxzQU7N+QqNVeWvk8Ahu77F+FaL1x+WAKgiVw2BGfNgBRwCRFQ7NA9BIZVICfUd/X5X4EgeMAmbBqBTd9/kPiqWdQ5N12vYAAAAASUVORK5CYII="
  101. )
  102.  
  103. await a.waituntil(canvas)
  104. window.onblur = () => {
  105. mousestate = {
  106. left: false,
  107. center: false,
  108. right: false,
  109. }
  110. }
  111. canvas().oncontextmenu = (e) => e.preventDefault()
  112.  
  113. canvas().onmousemove = (e) => {
  114. if (pointerlock_active && !!document.pointerLockElement) {
  115. mousepos.x = e.movementX
  116. mousepos.y = -e.movementY
  117. // if (Math.abs(mousepos.x) < 5) mousepos.x = 0
  118. // if (Math.abs(mousepos.y) < 5) mousepos.y = 0
  119. mousepos.totalx ??= 0
  120. mousepos.totaly ??= 0
  121. mousepos.totalx += mousepos.x
  122. mousepos.totaly += mousepos.y
  123. mousepos.justmoved = 1
  124. // scratchvar("__mousex", mousepos.x)
  125. // scratchvar("__mousey", mousepos.y)
  126. }
  127. }
  128. /*newfunc("vm.runtime._step", () => {
  129. if (!pointerlock_active && !document.pointerLockElement) {
  130. // mousepos.x = vm.runtime.ioDevices.mouse._scratchX
  131. // mousepos.y = vm.runtime.ioDevices.mouse._scratchY
  132. // scratchvar("__mousex", mousepos.x)
  133. // scratchvar("__mousey", mousepos.y)
  134. }
  135. if (!mousepos.justmoved) {
  136. mousepos.x = 0
  137. mousepos.y = 0
  138. }
  139. mousepos.justmoved = 0
  140. })*/
  141. // document.onpointerlockchange = () => {
  142. // scratchvar("__pointerlock", !!document.pointerLockElement)
  143. // }
  144.  
  145. canvas().addEventListener("click", async () => {
  146. if (pointerlock_active)
  147. await canvas().requestPointerLock({
  148. unadjustedMovement: true,
  149. })
  150. mousepos.x = 0
  151. mousepos.y = 0
  152. })
  153.  
  154. function newfunc(func1, func2) {
  155. eval(`var a = ${func1}
  156. var s = ${func2}
  157. ${func1} = function (...args) {
  158. try{
  159. s(arguments)
  160. }
  161. catch(e){console.error("${func1.replaceAll('"', '\\"')}", e)}
  162. return a.call(this, ...args)
  163. }`)
  164. }
  165. })()