Advertisement
buttonpushertv

Buttonpusher's Version of Freeze's Speedfactor Initiative Script

Jul 1st, 2022
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.23 KB | None | 0 0
  1. /*
  2. * this macro rolls initiative by using the rules for the optional rule "Speed factor initiative", available in the Dungeon Master's Guide at page 270
  3. * select the tokens for which you want to roll initiative and click the macro.
  4. * Alternatively, if you have an actor assigned and no token selected, the macro will roll initiative for your assigned actor
  5. * the macro does not roll initiative for actors not in combat
  6. * requires DnD5e Game System
  7. * created by Gabro#4634, with the invaluable help of Freeze#2689
  8. */
  9.  
  10. Hooks.on("updateCombat", async (combat, changed) => {
  11. if (!("round" in changed)) {
  12. return;
  13. }
  14. //List of actions with their relative bonuses
  15. const actions = {
  16. "Medium Action (+0)" : +0,
  17. "Melee, Heavy Weapon (-2)" : -2,
  18. "Melee, Light or Finesse Weapon (+2)" : +2,
  19. "Unarmed Strike (+2)" : +2,
  20. "Melee, Two-Handed Weapon (-2)" : -2,
  21. "Ranged, Loading Weapon (-5)" : -5,
  22. "Spellcasting, 1st level (-1)" : -1,
  23. "Spellcasting, 2nd level (-2)" : -2,
  24. "Spellcasting, 3rd level (-3)" : -3,
  25. "Spellcasting, 4th level (-4)" : -4,
  26. "Spellcasting, 5th level (-5)" : -5,
  27. "Spellcasting, 6th level (-6)" : -6,
  28. "Spellcasting, 7th level (-7)" : -7,
  29. "Spellcasting, 8th level (-8)" : -8,
  30. "Spellcasting, 9th level (-9)" : -9,
  31. //optional rules as suggested by AngryDM
  32. //(https://theangrygm.com/fine-i-wrote-about-speed-factor-initiative-in-dd-5e/)
  33. //remove them if you don't want them
  34. "Very Slow Action (-5)" : -5,
  35. "Slow Action (-2)" : -2,
  36. "Fast Action (+2)" : +2,
  37. "Very Fast Action (+5)" : +5
  38. }
  39.  
  40. // this option, as it is, disables the possibility to modify the box relative to the size and dex initiative bonus. If you want to modify them, change it to:
  41. // var disableTexts = ''
  42. const disableTexts = '';
  43.  
  44.  
  45. // list of sizes present in 5e, optionally it's possible to modify the bonuses (but not the size names "tiny", "sm", etc)
  46. const sizes = {
  47. "tiny" : +5,
  48. "sm" : +2,
  49. "med" : +0,
  50. "lg" : -2,
  51. "huge" : -5,
  52. "grg" : -8
  53. };
  54.  
  55. let options = new Array ()
  56. for (let key in actions) {
  57. options.push(key)
  58. }
  59.  
  60.  
  61. if(!game.user.isGM) {
  62. let data = [
  63. {type : `text`, label : `Base modifier : `, options : `${game.user.character.data.data.attributes.init.total}` },
  64. {type : `text`, label : `Size modifier : `, options : `${sizes[game.user.character.data.data.traits.size]}` },
  65. {type : `select`, label : `Action : `, options},
  66. {type: `text`, label: `Note:`, options: ""},
  67. ];
  68. let rv = await quick_dialog({data}, game.user.character.name);
  69. rollInit(game.user.character.getActiveTokens()[0], rv)
  70. }
  71. else {
  72. let combatants = combat.combatants.filter(c => !c.actor.hasPlayerOwner);
  73. for(let combatant of combatants) {
  74. let combActor = game.actors.get(combatant.data.actorId)
  75. let combToken = canvas.tokens.get(combatant.data.tokenId)
  76. let data = [
  77. {type : `text`, label : `Base modifier : `, options : `${combActor.data.data.attributes.init.total}` },
  78. {type : `text`, label : `Size modifier : `, options : `${sizes[combActor.data.data.traits.size]}` },
  79. {type : `select`, label : `Action : `, options},
  80. {type: `text`, label: `Note:`, options: ""},
  81. ];
  82. let rv = await quick_dialog({data}, combToken.name);
  83. await rollInit(combToken, rv)
  84. }
  85. }
  86.  
  87. async function quick_dialog({data, title = `Select your action for `} = {}, name)
  88. {
  89. data = data instanceof Array ? data : [data];
  90.  
  91. let value = await new Promise((resolve) => {
  92. let content = `
  93. <table style="width:100%">
  94. ${data.map(({type, label, options}, i)=> {
  95. if(type.toLowerCase() === `select`)
  96. {
  97. return `<tr><th style="width:50%"><label>${label}</label></th><td style="width:50%"><select id="${i}qd">${options.map((e,i)=> `<option value="${e}">${e}</option>`).join(``)}</td></tr>`;
  98. }else{
  99. return `<tr><th style="width:50%"><label>${label}</label></th><td style="width:50%"><input type="${type}" ${disableTexts} id="${i}qd" value="${options instanceof Array ? options[0] : options}"/></td></tr>`;
  100. }
  101. }).join(``)}
  102. </table>`;
  103.  
  104. new Dialog({
  105. title : title + name,
  106. content,
  107. buttons : {
  108. Ok : {
  109. label : `Roll Initiative!`,
  110. callback : (html) => {
  111. resolve(Array(data.length).fill().map((e,i)=>{
  112. let {type} = data[i];
  113. if(type.toLowerCase() === `select`)
  114. {
  115. return html.find(`select#${i}qd`).val();
  116. }else{
  117. return html.find(`input#${i}qd`)[0].value;
  118. }
  119. }));
  120. }
  121. }
  122. }
  123. }).render(true);
  124. });
  125. console.log(value);
  126. return value;
  127. }
  128.  
  129. async function rollInit(selectedToken, initBonus){
  130. let combatant = selectedToken.combatant;
  131. let formula = ''
  132. if (selectedToken.actor.data.flags != null && selectedToken.actor.data.flags.dnd5e != null && selectedToken.actor.data.flags.dnd5e.initiativeAdv){
  133. formula = '2d20kh + @dexBonus + @sizemod + @init'
  134. } else {
  135. formula = '1d20 + @dexBonus + @sizemod + @init'
  136. }
  137. let r = await new Roll(formula, {dexBonus : initBonus[0], sizemod: initBonus[1], init: actions[initBonus[2]]}).roll()
  138. if(!game.user.isGM) {
  139. await r.toMessage({flavor : `${combatant.name} chooses ${initBonus[2]} and rolls for Initiative! <br>NOTE: ${initBonus[3]}`}, {rollMode: CONST.DICE_ROLL_MODES.PUBLIC});
  140. }
  141. else {
  142. if (selectedToken.document._actor.type = 'npc'){
  143. isNPC = true
  144. } else {
  145. isNPC = false
  146. }
  147. await r.toMessage({flavor : `${combatant.name} chooses ${initBonus[2]} and rolls for Initiative! <br>NOTE: ${initBonus[3]}`}, {rollMode: isNPC ? CONST.DICE_ROLL_MODES.PRIVATE : CONST.DICE_ROLL_MODES.PUBLIC});
  148. }
  149. });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement