OWOT Toolbox

Useful tools for OWOT.

  1. // ==UserScript==
  2. // @name OWOT Toolbox
  3. // @namespace http://tampermonkey.net/
  4. // @version 2025-04-29
  5. // @description Useful tools for OWOT.
  6. // @author DefunctUser
  7. // @match https://ourworldoftext.com/*
  8. // @match https://*.ourworldoftext.com/*
  9. // @match https://test.ourworldoftext.com/*
  10. // @icon https://ourworldoftext.com/static/favicon.png
  11. // @grant none
  12. // @license GNU GPLv3
  13. // ==/UserScript==
  14.  
  15. (function() {
  16. 'use strict';
  17.  
  18. var version = "1.3.4";
  19. // Toolbox title
  20. menu.addEntry("<h2 style='background: linear-gradient(180deg, red,orange);-webkit-text-fill-color: transparent;-webkit-background-clip: text;background-clip: text;' id='tb-title'>OWOT<br>TOOLBOX</h2><h4>Version " + version + "</h4>")
  21. // Colors & rate-limit detection
  22. menu.addEntry( `${state.worldModel.color_text <= 0 ? "<div style='float: left; margin-left: 5px; margin-top: 6px; display: inline-block; border: 1px solid grey; background-color: #99ff66; width: 16px; height: 16px;'></div><span>Colors allowed</span>'" : "<div style='float: left; margin-left: 5px; margin-top: 6px; display: inline-block; border: 1px solid grey; background-color: #ff5050; width: 16px; height: 16px;''></div><span>Colors disallowed</span>"}`);
  23. /*
  24. if(state.worldModel.color_text>0){alert("WARNING\n========================\nColors are disabled on this world")}
  25. /* // Chars per second detection
  26. if(state.worldModel.char_rate[1]<513){
  27. if(state.worldModel.char_rate[1]<100){
  28. alert("WARNING\n========================\nThis world has a very low characters per second value.\nThis heavily affects all scripts.")
  29. } else {
  30. alert("!!!WARNING!!!\n========================\nThis world has a low characters per second value.\nThis affects all scripts.")
  31. }
  32. }
  33. /*
  34. if(state.worldModel.char_rate[1]>2000){
  35. alert("WARNING\n========================\nThis world has a high rate-limit ("+ state.worldModel.char_rate[0].toString() + " chars per " + state.worldModel.char_rate[1].toString() + "ms" + "). \nScripts will be slow.")
  36. }
  37. */
  38. // Automatic paste permission bypass.
  39. if(state.worldModel.feature_paste>0){
  40. (function(){Permissions.can_paste = function() {return true;};})();
  41. console.log("No pasting detected - Bypassed");
  42. }
  43. menu.addEntry(`<span>Rate limit: <b>${state.worldModel.char_rate[0].toString()} chars per ${state.worldModel.char_rate[1].toString()} ms</b></span>`);
  44. /* Instant Write (previously InstaPaste) v1.1
  45. Supports linebreaks.
  46. */
  47. function instapaste(str,col,loc) {
  48. var scriptloc = loc;
  49. var originalloc = loc;
  50. for(let i=0;i<str.length;i++){
  51. var char = str.charAt(i)
  52. var charsintostring = "-" + i+1
  53. if(char !== "°") {
  54. writeCharTo(char,0x000000,...scriptloc);
  55. scriptloc = coordinateAdd(...scriptloc,0,0,1,0);
  56. } else {
  57. originalloc = coordinateAdd(...originalloc,0,0,0,1)
  58. scriptloc = originalloc;
  59. console.log(originalloc + ", " + loc + ", " + scriptloc)
  60. }
  61. }
  62. }
  63. function aa(){
  64. var kk=prompt("what text to write?\nUse ° for linebreaks :)");
  65. instapaste(kk,0x000000,cursorCoords);
  66. }
  67. menu.addOption("Instant Write",aa)
  68.  
  69. // Fill Script
  70. var fillselection = new RegionSelection();
  71. var fillchar = " ";
  72. var fillcolor = 0x000000;
  73. var fillbcolor = null;
  74. var fillbold = false;
  75. var fillunder = false;
  76. var fillstrike = false;
  77. var fillitalic = false;
  78. var fillbcolorenabled = false;
  79. var filltargetenabled = false;
  80. var filltarget = 0x000000;
  81. // Fill settings modal
  82. // i = input
  83. var modalColorUnchanged = true;
  84. var fillmodal = new Modal();
  85. fillmodal.createForm();
  86. fillmodal.setFormTitle("Fill settings");
  87. // input values are accessed by [variable].input.value
  88. var ifillchar = fillmodal.addEntry("Fill char (leave empty to use it as a wiper)","text");
  89. var ifillcolor = fillmodal.addEntry("Color","color");
  90. var ifillbcolor = fillmodal.addEntry("Background color (if enabled below)","color");
  91. var ifilltarget = fillmodal.addEntry("Fill target (if enabled below)","color");
  92. fillmodal.createCheckboxField();
  93. // checkbox values are accessed by [variable].elm.firstChild.checked
  94. var ifillbold = fillmodal.addCheckbox("Bold text");
  95. var ifillitalic = fillmodal.addCheckbox("Italic text");
  96. var ifillunder = fillmodal.addCheckbox("Underline text");
  97. var ifillstrike = fillmodal.addCheckbox("Strikethrough text");
  98. var ifillbcolorenabled = fillmodal.addCheckbox("Enable background color");
  99. var ifilltargetenabled = fillmodal.addCheckbox("Enable fill target. If enabled, you can set the fill target to a color and only the chars with that color will get filled. Useful for erasing spam while keeping everything else intact.");
  100.  
  101. fillmodal.onOpen(function(){
  102. if(modalColorUnchanged) {
  103. ifillcolor.input.value = "000000";
  104. }
  105. });
  106. fillmodal.onSubmit(function(){
  107. if(ifillcolor.input.value !== "000000"){
  108. modalColorUnchanged = false;
  109. }
  110. fillchar = ifillchar.input.value.charAt(0); // only the first char will be saved
  111. if(fillchar == ""){
  112. fillchar = " ";
  113. };
  114. filltargetenabled = ifilltargetenabled.elm.firstChild.checked;
  115.  
  116. if(filltargetenabled == true){
  117. filltarget = parseInt(ifilltarget.input.value,16);
  118. };
  119. // 0x must be added so it is treated as a hex value because for some fucking reason the value from the input doesn't have that at the start
  120. if(ifillbcolorenabled.elm.firstChild.checked == true){
  121. fillbcolor = "0x" + ifillbcolor.input.value;
  122. } else {
  123. fillbcolor = null;
  124. };
  125. fillcolor = "0x" + ifillcolor.input.value;
  126. fillbold = ifillbold.elm.firstChild.checked;
  127. fillunder = ifillunder.elm.firstChild.checked;
  128. fillstrike = ifillstrike.elm.firstChild.checked;
  129. fillitalic = ifillitalic.elm.firstChild.checked;
  130. });
  131. // Main fill function
  132. fillselection.tiled = false;
  133. fillselection.onselection(function(coordA, coordB, regWidth, regHeight) {
  134. var charCoord = coordA;
  135. for(let yy = 0; yy < regHeight; yy++) {
  136. for(let xx = 0; xx < regWidth; xx++) {
  137. var charCol = getCharInfo(...charCoord).color;
  138. if(filltargetenabled == true){
  139. if(charCol == parseInt(filltarget,10)){
  140. writeCharTo(fillchar,fillcolor,...charCoord,true,true,fillbcolor,fillbold,fillitalic,fillunder,fillstrike);
  141. }
  142. } else {
  143. writeCharTo(fillchar,fillcolor,...charCoord,true,true,fillbcolor,fillbold,fillitalic,fillunder,fillstrike);
  144. }
  145. charCoord = coordinateAdd(...charCoord,0,0,1,0);
  146. }
  147. charCoord = coordinateAdd(...charCoord,0,0,-regWidth,1);
  148. }
  149. });
  150. w.on("keyDown", function(e) {
  151. if(checkKeyPress(e, "ALT+F")) {
  152. fillselection.startSelection();
  153. }
  154. });
  155. // Menu buttons
  156. menu.addOption("Fill Area\n(ALT+F)",function(){fillselection.startSelection();});
  157. console.log("Check the menu for the fill tool. You can use the shortcut ALT+B to enable it without clicking the menu button.");
  158. menu.addCheckboxOption("Fill Tiles",function(){fillselection.tiled = true;},function(){fillselection.tiled = false;},false);
  159. menu.addOption("Fill Settings",function(){fillmodal.open();});
  160.  
  161. // Stickman Script
  162. // Variable setup
  163. var col = 0x000000;
  164. var col_h = col;
  165. var col_la = col;
  166. var col_ra = col;
  167. var col_ll = col;
  168. var col_rl = col;
  169. var col_body = col;
  170. var loc = [];
  171. // Modals setup
  172. // Limb colors modal
  173. const colormodal2 = new Modal()
  174. colormodal2.createForm()
  175. colormodal2.setFormTitle("Stickman limb colors")
  176. var head = colormodal2.addEntry("Head color","color");
  177. var leftarm = colormodal2.addEntry("Left arm color","color");
  178. var rightarm = colormodal2.addEntry("Right arm color","color");
  179. var body = colormodal2.addEntry("Body color","color");
  180. var leftleg = colormodal2.addEntry("Left leg color","color");
  181. var rightleg = colormodal2.addEntry("Right leg color","color");
  182. colormodal2.onSubmit(function setColors() {
  183. col_h = parseInt(head.input.value,16);
  184. col_la = parseInt(leftarm.input.value,16)
  185. col_ra = parseInt(rightarm.input.value,16)
  186. col_ll = parseInt(leftleg.input.value,16)
  187. col_rl = parseInt(rightleg.input.value,16)
  188. col_body = parseInt(body.input.value,16)
  189. });
  190. // Single color modal
  191. const colormodal = new Modal();
  192. colormodal.createForm();
  193. var stickcolor = colormodal.addEntry("Stickman color","color");
  194. colormodal.setFormTitle("Stickman color. This will override any previously set limb colors.");
  195. colormodal.onSubmit(function setStickCol() {
  196. col = parseInt(stickcolor.input.value,16);
  197. console.log(stickcolor.input.value);
  198. col_h = col;
  199. col_la = col;
  200. col_ra = col;
  201. col_ll = col;
  202. col_rl = col;
  203. col_body = col;
  204. });
  205. col_h = col;
  206. col_la = col;
  207. col_ra = col;
  208. col_ll = col;
  209. col_rl = col;
  210. col_body = col;
  211. // Stickman paster function
  212. function stickman(){
  213. loc = cursorCoords;
  214. writeCharTo("O",col_h,...loc)// Head
  215. loc = coordinateAdd(...loc,0,0,-1,1)
  216. writeCharTo("/",col_la,...loc)// Left arm
  217. loc = coordinateAdd(...loc,0,0,1,0)
  218. writeCharTo("|",col_body,...loc)// Body
  219. loc = coordinateAdd(...loc,0,0,1,0)
  220. writeCharTo('\\',col_ra,...loc)//Right arm
  221. loc = coordinateAdd(...loc,0,0,-2,1)
  222. writeCharTo("/",col_ll,...loc)//Left leg
  223. loc = coordinateAdd(...loc,0,0,2,0)
  224. writeCharTo('\\',col_rl,...loc)//Right leg
  225. console.log(col_h + " " + col_la + " " + col_body + " " + col_ra + " " + col_ll + " " + col_rl);
  226. }
  227. // Menu options to access the modals
  228. menu.addOption("Add Stickman",()=>{stickman()});
  229. menu.addOption("Set Stickman Color",()=>{
  230. colormodal.open()
  231. });
  232. menu.addOption("Set Limb Colors",()=>{
  233. colormodal2.open()
  234. });
  235.  
  236. w.doAnnounce("OWOT Toolbox Loaded - v" + version + " - Enjoy :)");
  237. })();