Roll

Faire des jets avec prise en compte des stats via des compétences

当前为 2022-07-16 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Roll
  3. // @namespace InGame
  4. // @author Odul, MockingJay
  5. // @match https://www.dreadcast.net/Main
  6. // @version 1.2
  7. // @grant none
  8. // @description Faire des jets avec prise en compte des stats via des compétences
  9. // ==/UserScript==
  10.  
  11. // Alias de commandes, utiliser le format suivant:
  12. // alias: "commande",
  13. const aliases = {
  14. for: "force",
  15. agi: "agilite",
  16. res: "resistance",
  17. per: "perception",
  18. fur: "furtivite",
  19. fufu: "furtivite",
  20. info: "informatique",
  21. inf: "informatique",
  22. med: "medecine",
  23. inge: "ingenierie",
  24. ing: "ingenierie",
  25. }
  26.  
  27. // Pour ajouter des formules personnalisées:
  28. // - Le nom doit être en minuscules, sans accents si espaces, underscores autorisés
  29. // - Les coefficients sont dans l'ordre: force, agilité, résistance, perception, furtivité, informatique, médecine, ingénierie
  30. const formulas = {
  31. force: [1, 0, 0, 0, 0, 0, 0, 0],
  32. agilite: [0, 1, 0, 0, 0, 0, 0, 0],
  33. resistance: [0, 0, 1, 0, 0, 0, 0, 0],
  34. perception: [0, 0, 0, 1, 0, 0, 0, 0],
  35. furtivite: [0, 0, 0, 0, 1, 0, 0, 0],
  36. informatique: [0, 0, 0, 0, 0, 1, 0, 0],
  37. medecine: [0, 0, 0, 0, 0, 0, 1, 0],
  38. ingenierie: [0, 0, 0, 0, 0, 0, 0, 1],
  39. dpasse: [1, 2, 0, 1, 0, 0, 0, 0],
  40. drecep: [1, 1, 0, 2, 0, 0, 0, 0],
  41. dplaque: [3, 1, 0, 0, 0, 0, 0, 0],
  42. dfeinte: [1, 1, 0, 1, 0, 0, 0, 0],
  43. dinter: [0, 1, 0, 1, 0, 0, 0, 0],
  44. dtir: [1, 1, 0, 0, 0, 0, 0, 0],
  45. darret: [1, 0, 0, 3, 0, 0, 0, 0],
  46. hack: [0, 1, 0, 0, 0, 16, 0, 3],
  47. programmation: [0, 0, 0, 0, 0, 9, 0, 1],
  48. diag_meca: [0, 0, 0, 2, 0, 1, 0, 2],
  49. cablage: [0, 0, 0, 0, 0, 3, 0, 7],
  50. assemblage: [0, 0, 0, 1, 0, 0, 0, 4],
  51. desassemblage: [1, 0, 0, 0, 0, 0, 0, 4],
  52. reparation: [1, 0, 0, 0, 0, 0, 0, 4],
  53. soudure: [1, 0, 0, 3, 0, 0, 0, 6],
  54. crochetage: [0, 1, 0, 0, 0, 0, 0, 3],
  55. desamorcer: [0, 1, 0, 3, 0, 0, 0, 16],
  56. diag_medical: [0, 0, 0, 1, 0, 0, 4, 0],
  57. chirurgie: [0, 1, 0, 1, 0, 0, 3, 0],
  58. massage_cardiaque: [3, 0, 0, 0, 0, 0, 7, 0],
  59. perfusion: [0, 1, 0, 2, 0, 0, 2, 0],
  60. desinfecter: [0, 3, 0, 0, 0, 0, 2, 0],
  61. garot: [1, 0, 0, 0, 0, 0, 1, 0],
  62. tir: [0, 1, 0, 4, 0, 0, 0, 0],
  63. parade: [0, 4, 0, 1, 0, 0, 0, 0],
  64. esquive: [1, 9, 0, 0, 0, 0, 0, 0],
  65. liberation: [4, 5, 0, 0, 0, 0, 0, 1],
  66. immobilisation: [1, 0, 1, 0, 0, 0, 0, 0],
  67. equilibre: [0, 4, 1, 0, 0, 0, 0, 0],
  68. volonte: [4, 2, 9, 1, 1, 1, 1, 1],
  69. blessure: [0, 1, 9, 0, 0, 0, 0, 0],
  70. enfoncer: [7, 0, 3, 0, 0, 0, 0, 0],
  71. mensonge: [0, 3, 0, 0, 5, 0, 2, 0],
  72. dmensonge: [0, 3, 0, 5, 0, 0, 2, 0],
  73. maquillage: [0, 8, 0, 2, 0, 0, 0, 0],
  74. musique: [0, 3, 0, 2, 0, 0, 0, 0],
  75. accorder: [0, 0, 0, 2, 0, 0, 0, 3],
  76. fee_lation: [0, 6, 0, 1, 0, 0, 4, 0],
  77. orgasme: [0, 1, 1, 0, 0, 0, 0, 0],
  78. skype: [0, 0, 0, 0, 0, 0, 2, 0],
  79. fee_niasse: [0, 1, 1, 0, 0, 0, 0, 0],
  80. overflow: [1, 1, 1, 1, 1, 1, 1, 1],
  81. }
  82.  
  83. // CORE FNS //
  84.  
  85. const getStats = function() {
  86. let stats = [];
  87.  
  88. for (let i = 1; i <= 8; i++) {
  89. stats.push(parseInt($('#statistiques .infos .stat_' + i + '_entier').text()));
  90. }
  91.  
  92. return stats;
  93. }
  94.  
  95. const computeValue = function(skillName){
  96. if (!formulas[skillName]) {
  97. return null;
  98. }
  99.  
  100. const stats = getStats();
  101. const totalWeight = formulas[skillName].reduce(((total, weight) => total + weight), 0);
  102. const skillPoints = stats.reduce(((total, stat, i) => total + stat * formulas[skillName][i]), 0);
  103.  
  104. return 100 - Math.floor((skillPoints / totalWeight) / 6);
  105. }
  106.  
  107. const retrieveValue = function(facesde, comp, diff)
  108. {
  109. const ligne = $("#chatContent > .msg.hrp > em").last().text();
  110.  
  111. if (!ligne) {
  112. return;
  113. }
  114.  
  115. if (ligne.includes($("txt_pseudo").text() + " lance 1 dé de " + facesde + " et fait")) {
  116. let result = parseInt(ligne.substring(ligne.indexOf("et fait") + 7).trim()) + (100 - facesde);
  117. let threshold = 0;
  118.  
  119. switch(diff) {
  120. case "f":
  121. case "facile":
  122. threshold = 25;
  123. diff = "facile";
  124. break;
  125. case "m":
  126. case "moyen":
  127. threshold = 50;
  128. diff = "moyen";
  129. break;
  130. case "d":
  131. case "difficile":
  132. threshold = 75;
  133. diff = "difficile";
  134. break;
  135. default:
  136. threshold = parseInt(diff) || 0;
  137. }
  138.  
  139. let textResult = "";
  140.  
  141. if (!threshold) {
  142. textResult += "/me [couleur=jaune]fait "+ result +" à son jet de " + comp + "[/couleur]";
  143. }
  144. else if (["facile", "moyen", "difficile"].includes(diff)) {
  145. textResult += result >= threshold ?
  146. "/me [couleur=vert]réussit[/couleur] " :
  147. "/me [couleur=rouge]rate[/couleur] ";
  148. textResult += "[couleur=jaune]un jet " + diff + " de " + comp + " et fait " + result + "[/couleur]";
  149. }
  150. else {
  151. textResult += result >= threshold ?
  152. "/me [couleur=vert]réussit[/couleur] " :
  153. "/me [couleur=rouge]rate[/couleur] ";
  154. textResult += "[couleur=jaune]un jet de " + comp + " en faisant " + result + " contre un seuil de " + threshold + "[/couleur]";
  155. }
  156.  
  157. $("#chatForm .text_chat").val(textResult);
  158. nav.getChat().send();
  159. }
  160.  
  161. }
  162.  
  163. const jetDes = function(e) {
  164. let value = $("#chatForm .text_chat").val();
  165.  
  166. if (!value.match(/^\/roll [a-zA-Z]+/)) {
  167. return; // Ne traiter que l'envoi de /roll avec commande (ignore également les XdY)
  168. }
  169.  
  170. value = value.replace(/[àâ]/g, "a").replace(/[éèê]/g, "e").replace(/[î]/g, "i").replace(/[ô]/g, "o").replace(/[ûù]/g, "u");
  171. // Essayer d'ignorer les accents
  172.  
  173. let comp = value.trim().split(" ")[1].toLowerCase();
  174. const diff = value.trim().split(" ")[2];
  175.  
  176. comp = aliases[comp] || comp;
  177. const facesde = computeValue(comp);
  178.  
  179. if (facesde) {
  180. value = '/roll 1d' + facesde;
  181. setTimeout(function() {
  182. retrieveValue(facesde, comp, diff)
  183. }, 500);
  184. }
  185. else {
  186. e.preventDefault(); // Empêche l'envoi d'un roll mal écrit
  187. }
  188.  
  189. $("#chatForm .text_chat").val(value);
  190. }
  191.  
  192. // GUI //
  193.  
  194. $("body").append(`<style>
  195. #rollPanel {
  196. position: absolute;
  197. right: -220px;
  198. bottom: 20px;
  199. z-index: 999999;
  200. display: flex;
  201. }
  202.  
  203. #rollPanel button, #rollPanel input, #rollPanel select {
  204. background-color: #8ab6e4;
  205. }
  206.  
  207. #rollToggle {
  208. background-color: #6ea0d3;
  209. height: fit-content;
  210. }
  211.  
  212. #rollToggle button {
  213. height: 50px;
  214. width: 50px;
  215. }
  216.  
  217. #rollOptions {
  218. background-color: #6ea0d3;
  219. padding: 10px;
  220. width: 200px;
  221. }
  222.  
  223. #rollOptions label, #rollHasThreshold {
  224. vertical-align: middle;
  225. }
  226.  
  227. #rollType, #rollThreshold, .rollPresetDiff {
  228. height: 30px;
  229. }
  230.  
  231. .rollPresetDiff {
  232. flex: 1;
  233. }
  234.  
  235. #rollType {
  236. max-width: 160px;
  237. }
  238.  
  239. #rollThreshold {
  240. -moz-appearance: textfield;
  241. text-align: center;
  242. }
  243.  
  244. #rollThreshold::-webkit-outer-spin-button,
  245. #rollThreshold::-webkit-inner-spin-button {
  246. -webkit-appearance: none;
  247. margin: 0;
  248. }
  249.  
  250. #rollPresetDiffs {
  251. display: flex;
  252. }
  253.  
  254. #rollSubmit {
  255. width: 100%;
  256. height: 40px;
  257. font-size: 18px;
  258. }
  259. </style>`);
  260.  
  261. $("body").append(`
  262. <div id="rollPanel">
  263. <div id="rollToggle">
  264. <button>&lt; Roll</button>
  265. </div>
  266. <div id="rollOptions">
  267. <label for="rollType">Test:</label>
  268.  
  269. <select name="rollType" id="rollType">
  270. <option value="">Standard (1d100)</option>
  271. </select>
  272.  
  273. <br><br>
  274.  
  275. <input type="checkbox" name="rollHasThreshold" id="rollHasThreshold">
  276. <label for="rollHasThreshold">Seuil de réussite</label>
  277. <input type="number" name="rollThreshold" id="rollThreshold" min="0" max="100" value="0" disabled>
  278.  
  279. <br><br>
  280.  
  281. <div id="rollPresetDiffs">
  282. <button id="rollSetEasy" class="rollPresetDiff" value="25" disabled>Facile</button>
  283. <button id="rollSetMedium" class="rollPresetDiff" value="50" disabled>Moyen</button>
  284. <button id="rollSetHard" class="rollPresetDiff" value="75" disabled>Difficile</button>
  285. </div>
  286.  
  287. <br>
  288.  
  289. <button id="rollSubmit">Lancer</button>
  290. </div>
  291. </div>
  292. `);
  293.  
  294. for (let formula in formulas) {
  295. $("#rollType").append(`<option value="${formula}">${formula}</option>`);
  296. }
  297.  
  298. let showGUI = false;
  299.  
  300. $("#rollToggle button").click(function() {
  301. if (showGUI) {
  302. $("#rollPanel").css("right", "-220px");
  303. $("#rollToggle button").text("< Roll");
  304. showGUI = false;
  305. }
  306. else {
  307. $("#rollPanel").css("right", "0px");
  308. $("#rollToggle button").text("> Roll");
  309. showGUI = true;
  310. }
  311. });
  312.  
  313. $("#rollHasThreshold").change(function() {
  314. if ($("#rollHasThreshold").attr("checked")) {
  315. $(".rollPresetDiff, #rollThreshold").prop("disabled", false);
  316. $("#rollThreshold").select();
  317. }
  318. else {
  319. $(".rollPresetDiff, #rollThreshold").prop("disabled", true);
  320. }
  321. });
  322.  
  323. $(".rollPresetDiff").click(function() {
  324. $("#rollThreshold").val($(this).attr("value")).select();
  325. });
  326.  
  327. $("#rollSubmit").click(function() {
  328.  
  329. const rollType = $("#rollType").val();
  330. let roll = "/roll ";
  331.  
  332. if (!rollType) {
  333. roll += "1d100";
  334. } else {
  335. roll += rollType;
  336. if ($("#rollHasThreshold").attr("checked")) {
  337. roll += " ";
  338. const threshold = parseInt($("#rollThreshold").val());
  339. switch (threshold) {
  340. case 25:
  341. roll += "f";
  342. break;
  343. case 50:
  344. roll += "m";
  345. break;
  346. case 75:
  347. roll += "d";
  348. break;
  349. default:
  350. roll += threshold;
  351. }
  352. }
  353. }
  354.  
  355. $("#chatForm .text_chat").val(roll);
  356. $("#chatForm .text_valider").click();
  357.  
  358. $("#rollPanel").css("right", "-220px");
  359. $("#rollToggle button").text("< Roll");
  360. showGUI = false;
  361. });
  362.  
  363.  
  364. // MAIN //
  365.  
  366. document.addEventListener('keypress', (e) => {
  367. if (e.keyCode == 13) {
  368. jetDes(e);
  369. }
  370. }, false);
  371.  
  372. $("#chatForm .text_valider").click(jetDes);
  373.  
  374. console.log("Script Roll - Actif.");