ooshbin

SWFFG modified Initiative

Feb 5th, 2021
189
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.  Current Version: 6.4.3
  3.  Last updated: 03.15.2018
  4.  Character Sheet and Script Maintained by: Samuel T.
  5.  Older Verions: https://github.com/dayst/StarWarsEdgeOfTheEmpire_Dice
  6.  Credits:
  7.  Original creator: Konrad J.
  8.  Helped with Dice specs: Alicia G. and Blake the Lake
  9.  Dice graphics hosted by Alicia G. at galacticcampaigns.com
  10.  Dice graphics borrowed from the awesome google+ hangouts EotE Dice App
  11.  Basic Character Sheet and Advanced Dice Roller: Steve Day
  12.  GM Sheet Campaign Details design inspiration: www.reddit.com/user/JohnSquiggleton
  13.  Sheet Autocreator: www.reddit.com/user/lowdownfool
  14.  New Tab Labels: Steve D., GM Knowledge Rhino, and Loki
  15.  Skill Description by: Gribble - https://dl.dropboxusercontent.com/u/9077657/SW-EotE-Reference-Sheets.pdf
  16.  Critical Descriptions by: Gribble - https://dl.dropboxusercontent.com/u/9077657/SW-EotE-Reference-Sheets.pdf
  17.  Debugger: Arron
  18.  Basic Roll Templates for basic rolls: Josh A.
  19.  Initiative Roller: Andrew H.
  20.  Opposed Roller: Tom F.
  21.  Method to hide depreciated Vehicle Tabs: Phil B.
  22.  Work done by GM Knowledge Rhino:
  23.  Group Tab
  24.  Companion Tab
  25.  GM Resources
  26.  Redesign of Vehicle Tab
  27.  Riding Beast Display
  28.  Roll Template Code Fixes
  29.  Roll Templates integrated with all Rolls
  30.  Overencumbrance roll notification
  31.  Work done by Samuel T.:
  32.  Versions 4.0.10.0 - 6.3.0 b5
  33.  SuggestionEngine
  34.  NPC Sheet
  35.  Initiative fix
  36.  Label generation fix
  37.  Semantic Versioning
  38.  Consolidated the Dice Pool and Destiny Sections
  39.  Collapsing sections
  40.  Optgroups for dropdowns
  41.  API Chat Commands
  42.  Dice Downgrade fix by Bast L.
  43.  Settings:
  44.  Log
  45.  * default: 'on' and 'single'
  46.  * Description: Sets the visual output in the chat window for the dice rolls
  47.  * Command: !eed log on|off|multi|single
  48.  Graphics
  49.  * default: 'on' and 'm'
  50.  * Description: Sets chat window dice output as graphic, small, medium, or large if "on" or as text if "off"
  51.  * Command: !eed graphics on|off|s|m|l
  52.  Test
  53.  * Description: Output every side of every die to the chat window
  54.  * !eed test
  55.  Debug
  56.  * default: 'off'
  57.  * DescriptionL Sets the logging level of the script in the API console.  If you are having issues with the
  58.  * script rolling incorrect dice, turn on debug logging and post the result in the forums. No need to restart the
  59.  * script with this command.
  60.  * Command: !eed debug on|off
  61.  GM Sheet Settings:
  62.  SuggestionDisplay
  63.  * Description: Sets the state of the skill_suggestion_setting_display status on the DicePool
  64.  * Command: !eed suggestionDisplay none|whisper|always
  65.  Fear
  66.  * Description: Sets the state of the Fear check status on the DicePool
  67.  * Command: !eed fear on|off
  68.  Roll:
  69.  Label
  70.  * default: null
  71.  * Description: set the skill name of the roll
  72.  * Command: !eed label(Name of Skill)
  73.  Initiative
  74.  * default: false
  75.  * Description: Set NPC/PC initiative true
  76.  * Command: !eed npcinit or pcinit and #b #g #y #blk #p #r #w
  77.  Skill
  78.  * default:
  79.  * Description: create the ability and proficiency dice for a skill check
  80.  * Command: !eed skill(char_value|skill_value)
  81.  Opposed
  82.  * default:
  83.  * Description: create the difficulty and challenge dice for an opposed skill check
  84.  * Command: !eed opposed(char_value|skill_value|[NPC minion group size]|[Is skill a minion skill])
  85.  Dice
  86.  * default:
  87.  * Description: Loop thru the dice and adds or subtracts them from the dice object
  88.  * Command: !eed #g #y #b #blk #r #p #w #s #a
  89.  Upgrade
  90.  * default:
  91.  * Description: upgrades ability and difficulty dice
  92.  * Command: !eed upgrade(ability|#) or upgrade(difficulty|#)
  93.  Downgrade
  94.  * default:
  95.  * Description: downgrades proficiency and challenge dice
  96.  * Command: !eed downgrade(proficiency|#) or downgrade(challenge|#)
  97.  Destiny
  98.  * default:
  99.  * Description: Rolls 1w die and adds the result to the destiny pool
  100.  * Command: !eed #w destiny doRoll
  101.  Other:
  102.  Charsheet
  103.  * default:
  104.  * Description: Generates a blank character sheet and automatically makes it viewable and editable by the person calling the script.
  105.  * Command: !charsheet
  106.  */
  107.  
  108. /* Define functions that may not always exist */
  109. if(!log) {
  110.     log = function(input) {
  111.         console.log(input);
  112.     }
  113. }
  114.  
  115. if (!sendChat) {
  116.     sendChat = function (sender, msg) {
  117.         log(sender + " says " + msg);
  118.     }
  119. }
  120. /* End special function definitions*/
  121.  
  122. /* Begin Sheet Character Sheet Auto Creator */
  123. var Charsheet = Charsheet || {};
  124.  
  125. on('chat:message', function (msg) {
  126.     // Exit if not an api command
  127.     if (msg.type != "api") {
  128.         return;
  129.     }
  130.     if (msg.content.indexOf('!charsheet') != -1) {
  131.         Charsheet.Generate(msg);
  132.     }
  133. });
  134.  
  135. Charsheet.Generate = function (msg) {
  136.     var player = msg.who;
  137.     var character_name = msg.who + Date.now();
  138.  
  139.     var character = createObj('character', {
  140.         name: character_name,
  141.         inplayerjournals: msg.playerid,
  142.         controlledby: msg.playerid
  143.     });
  144.     /* Create attributes */
  145.     createObj('attribute', {
  146.         name: 'player_name',
  147.         current: player,
  148.         _characterid: character.id
  149.     });
  150.     createObj('attribute', {
  151.         name: 'name',
  152.         current: character_name,
  153.         _characterid: character.id
  154.     });
  155.     sendChat("Dice System", "/w " + msg.who + " a blank character sheet was created for you named \"" + character_name);
  156.     sendChat("GM", "/w " + "gm " + "A blank character sheet was created for " + msg.who)
  157. };
  158.  
  159. if (!Date.now) {
  160.     Date.now = function now() {
  161.         return new Date().getTime();
  162.     };
  163. }
  164. /* End Sheet Character Sheet Auto Creator */
  165.  
  166. function SuggestionEngine () {
  167.     var that = this;
  168.  
  169.     var flags = {
  170.         displayOption: null,
  171.         generalSuggesting: true,
  172.         combatSuggesting: true,
  173.         combatType: null,
  174.         isFearCheck: false
  175.     };
  176.  
  177.     function convertToBoolean (value) {
  178.         // will trap the following properly: false, true, "false", "true", 0, 1, "", and undefined
  179.         //noinspection RedundantConditionalExpressionJS
  180.         return !value || value == 1 || value === 'true'
  181.     }
  182.  
  183.     this.suggestions = {
  184.         special: {
  185.             fear: {
  186.                 allowedSkills: [
  187.                     "Cool",
  188.                     "Discipline"
  189.                 ],
  190.                 success: [
  191.                     {
  192.                         text: "The character avoids any fear effects, except those triggered by threats",
  193.                         required: 1
  194.                     }
  195.                 ],
  196.                 advantage: [
  197.                     {text: "Gain $BOOST$ on the character's first check.", required: 1},
  198.                     {
  199.                         text: "If spending multiple $ADVANTAGE$, grant $BOOST$ to an additional player's first check.",
  200.                         required: 2
  201.                     }
  202.                 ],
  203.                 triumph: [
  204.                     {
  205.                         text: "Can be spent to cancel all previous penalties from fear checks, or",
  206.                         required: 1
  207.                     },
  208.                     {
  209.                         text: "Spent to ensure the character need not make any additional fear checks during the encounter, no matter the source.",
  210.                         required: 1
  211.                     }
  212.                 ],
  213.                 failure: [
  214.                     {
  215.                         text: "The character adds $SETBACK$ to each action he takes during the encounter.",
  216.                         required: 1
  217.                     }
  218.                 ],
  219.                 threat: [
  220.                     {
  221.                         text: "The character suffers a number of strain equal to the number of $FAILURE$.",
  222.                         required: 1
  223.                     },
  224.                     {
  225.                         text: "If the check generates $THREAT$$THREAT$$THREAT$+, the character can be staggered for his first turn, instead.",
  226.                         required: 3
  227.                     }
  228.                 ],
  229.                 despair: [
  230.                     {
  231.                         text: "The character is incredibly frightened and increases the difficulty of all checks until the end of the encounter by one.",
  232.                         required: 1
  233.                     }
  234.                 ]
  235.             }
  236.         },
  237.         general: {
  238.             Astrogation: {
  239.                 success: [
  240.                     {
  241.                         text: "Better target for the destination, e.g.: place vessel directly into orbit around target planet.",
  242.                         required: 1
  243.                     },
  244.                     {text: "Reduce time spent calculating.", required: 1}
  245.                 ],
  246.                 advantage: [
  247.                     {text: "Reduce travel time.", required: 1},
  248.                     {text: "Identify convenient stopovers to resupply or conduct additional business.", required: 1}
  249.                 ],
  250.                 triumph: [
  251.                     {text: "Complete calculations in minimum time.", required: 1},
  252.                     {text: "Greatly reduce travel time.", required: 1},
  253.                     {text: "Reveal highly valuable but previously unknown information.", required: 1}
  254.                 ],
  255.                 threat: [
  256.                     {text: "Decrease accuracy of hyperspace jump.", required: 1},
  257.                     {text: "Increase travel time.", required: 1},
  258.                     {text: "Miss relevant details when analyzing hyperspace routes or galactic maps.", required: 1}
  259.                 ],
  260.                 despair: [
  261.                     {text: "Greatly decrease accuracy of hyperspace jump.", required: 1},
  262.                     {text: "Greatly increase travel time.", required: 1},
  263.                     {
  264.                         text: "Miss large amounts of relevant details when analyzing hyperspace routes or galactic maps.",
  265.                         required: 1
  266.                     },
  267.                     {
  268.                         text: "Trigger something truly awful happening, such as jumping out of hyperspace in the path of an asteroid.",
  269.                         required: 1
  270.                     }
  271.                 ]
  272.             },
  273.             Athletics: {
  274.                 success: [
  275.                     {text: "Reduce time required.", required: 1},
  276.                     {text: "Increase distance travelled.", required: 1}
  277.                 ],
  278.                 advantage: [
  279.                     {
  280.                         text: "Generate bonus on other physical checks performed later or by allies that turn.",
  281.                         required: 1
  282.                     },
  283.                     {
  284.                         text: "Spend $ADVANTAGE$$ADVANTAGE$ to grant additional maneuver during turn to move or perform physical activity.",
  285.                         required: 2
  286.                     }
  287.                 ],
  288.                 triumph: [
  289.                     {text: "Perform the check with truly impressive results.", required: 1}
  290.                 ],
  291.                 threat: [
  292.                     {text: "Small amounts cause strain.", required: 1},
  293.                     {
  294.                         text: "Larger amounts may cause character to fall prone, or even suffer a wound from sprains and bruises.",
  295.                         required: 1
  296.                     }
  297.                 ],
  298.                 despair: [
  299.                     {
  300.                         text: "Inflict a Critical Injury, which the GM can choose to be thematic or roll randomly.",
  301.                         required: 1
  302.                     }
  303.                 ]
  304.             },
  305.             Charm: {
  306.                 success: [
  307.                     {
  308.                         text: "Gain an extra scene in which target is willing to support you for each additional success.",
  309.                         required: 1
  310.                     }
  311.                 ],
  312.                 advantage: [
  313.                     {text: "Affect unexpected subjects beyond the original target.", required: 1}
  314.                 ],
  315.                 triumph: [
  316.                     {text: "Have target NPC become recurring character who remains predisposed to assist.", required: 1}
  317.                 ],
  318.                 threat: [
  319.                     {text: "Reduce the number of people able to influence", required: 1},
  320.                     {text: "Turn those affected negatively against character.", required: 1}
  321.                 ],
  322.                 despair: [
  323.                     {text: "Turn NPC against character and make into a minor recurring adversary.", required: 1}
  324.                 ]
  325.             },
  326.             Coercion: {
  327.                 success: [
  328.                     {text: "Spend 2 extra successes to inflict one strain on target. ", required: 2}
  329.                 ],
  330.                 advantage: [
  331.                     {text: "Affect unexpected subjects beyond the original target.", required: 1}
  332.                 ],
  333.                 triumph: [
  334.                     {text: "Shift allegiance of target.", required: 1}
  335.                 ],
  336.                 threat: [
  337.                     {text: "Target has building resentment towards character.", required: 1}
  338.                 ],
  339.                 despair: [
  340.                     {text: "Reveal something about goals and motivations to target.", required: 1}
  341.                 ]
  342.             },
  343.             Computers: {
  344.                 success: [
  345.                     {text: "Reduce time required.", required: 1}
  346.                 ],
  347.                 advantage: [
  348.                     {text: "Uncover additional information about the system.", required: 1}
  349.                 ],
  350.                 triumph: [
  351.                     {
  352.                         text: "Obfuscate actions taken, add a $CHALLENGE$ to any check to detect or identify the characters actions.",
  353.                         required: 1
  354.                     }
  355.                 ],
  356.                 threat: [
  357.                     {
  358.                         text: "The character does a poor job of concealing his presence in the system. Security systems are alerted, and add $BOOST$ to the check of any NPC attempting to discover evidence of his actions.",
  359.                         required: 1
  360.                     }
  361.                 ],
  362.                 despair: [
  363.                     {
  364.                         text: "Leave behind trace information of your own system in the system being sliced. Add $BOOST$ to the check of any NPC using the target system to slice the character's system.",
  365.                         required: 1
  366.                     }
  367.                 ]
  368.             },
  369.             Cool: {
  370.                 advantage: [
  371.                     {text: "Gain an additional insight into the situation at hand.", required: 1}
  372.                 ],
  373.                 triumph: [
  374.                     {text: "Heal 3 strain.", required: 1}
  375.                 ],
  376.                 threat: [
  377.                     {text: "Miss a vital detail or event.", required: 1}
  378.                 ],
  379.                 despair: [
  380.                     {text: "The character is overwhelmed by the chaos and is stunned for one round.", required: 1}
  381.                 ]
  382.             },
  383.             Coordination: {
  384.                 success: [
  385.                     {text: "Reduce time required.", required: 1},
  386.                     {text: "Increase distance travelled by 25%, (maximum 100% increase).", required: 1}
  387.                 ],
  388.                 advantage: [
  389.                     {text: "Spend $ADVANTAGE$$ADVANTAGE$ to grant additional maneuver during turn.", required: 2}
  390.                 ],
  391.                 triumph: [
  392.                     {text: "Perform the check with truly impressive results.", required: 1}
  393.                 ],
  394.                 threat: [
  395.                     {text: "Lose free maneuver for one round.", required: 1}
  396.                 ],
  397.                 despair: [
  398.                     {text: "Suffer a wound", required: 1},
  399.                     {text: "Lose a vital piece of equipment.", required: 1}
  400.                 ]
  401.             },
  402.             Deception: {
  403.                 success: [
  404.                     {text: "Extend duration of Deceit action.", required: 1}
  405.                 ],
  406.                 advantage: [
  407.                     {text: "Increase the value of any goods or services gained through the action.", required: 1}
  408.                 ],
  409.                 triumph: [
  410.                     {
  411.                         text: "Fool the target into believing the character is trustworthy - future Deceit checks against target do not require an opposed check.",
  412.                         required: 1
  413.                     }
  414.                 ],
  415.                 threat: [
  416.                     {text: "Give away a portion of the lie, making target suspicious.", required: 1}
  417.                 ],
  418.                 despair: [
  419.                     {
  420.                         text: "Target realises he has been lied to and spreads word of his deceit to harm his reputation or uses the situation to his advantage.",
  421.                         required: 1
  422.                     }
  423.                 ]
  424.             },
  425.             Discipline: {
  426.                 success: [
  427.                     {text: "Downgrade difficulty of the dice pool for next action (max. 1).", required: 1}
  428.                 ],
  429.                 advantage: [
  430.                     {text: "Gain an additional insight into the situation at hand.", required: 1}
  431.                 ],
  432.                 triumph: [
  433.                     {
  434.                         text: "Add $BOOST$ to any Discipline checks made by allies during the following round.",
  435.                         required: 1
  436.                     }
  437.                 ],
  438.                 threat: [
  439.                     {
  440.                         text: "Undermine the characters resolve, perhaps inflicting a penalty on further actions in distressing circumstances.",
  441.                         required: 1
  442.                     }
  443.                 ],
  444.                 despair: [
  445.                     {
  446.                         text: "The character is overwhelmed entirely and is unable to perform more than one maneuver next round.",
  447.                         required: 1
  448.                     }
  449.                 ]
  450.             },
  451.             Leadership: {
  452.                 success: [
  453.                     {text: "Extend target's support for additional scenes.", required: 1},
  454.                     {text: "Increase efficiency or effectiveness of target during ordered actions.", required: 1}
  455.                 ],
  456.                 advantage: [
  457.                     {text: "Affect bystanders in addition to target.", required: 1}
  458.                 ],
  459.                 triumph: [
  460.                     {
  461.                         text: "Have target NPC become recurring character who decides to faithfully follow the acting character.",
  462.                         required: 1
  463.                     }
  464.                 ],
  465.                 threat: [
  466.                     {
  467.                         text: "Decrease the efficiency of ordered actions, causing them to take longer or be done poorly.",
  468.                         required: 1
  469.                     }
  470.                 ],
  471.                 despair: [
  472.                     {
  473.                         text: "Undermine the character's authority, damaging the characters ability to command target or those who witnessed the attempt.",
  474.                         required: 1
  475.                     },
  476.                     {
  477.                         text: "With multiple $DESPAIR$ the target may become a recurring thorn in the character's side,refusing future orders or turning others against the character.",
  478.                         required: 2
  479.                     }
  480.                 ]
  481.             },
  482.             Mechanics: {
  483.                 success: [
  484.                     {text: "Reduce time required by 10-20%", required: 1}
  485.                 ],
  486.                 advantage: [
  487.                     {
  488.                         text: "Grant $BOOST$ on checks when using repaired item, or even the Superior quality, for a session.",
  489.                         required: 1
  490.                     }
  491.                 ],
  492.                 triumph: [
  493.                     {text: "Give device additional single use function.", required: 1}
  494.                 ],
  495.                 threat: [
  496.                     {
  497.                         text: "Particularly shoddy repairs or temporary measures, the GM may spend $THREAT$ to cause the target object or system to malfunction shortly after check completed.",
  498.                         required: 1
  499.                     }
  500.                 ],
  501.                 despair: [
  502.                     {text: "Cause further harm to target object or system.", required: 1},
  503.                     {text: "Cause other components of target to malfunction.", required: 1}
  504.                 ]
  505.             },
  506.             Medicine: {
  507.                 success: [
  508.                     {text: "Target recovers one additional wound.", required: 1},
  509.                     {text: "Reduce healing time by one hour.", required: 1}
  510.                 ],
  511.                 advantage: [
  512.                     {text: "Eliminate one strain from target.", required: 1}
  513.                 ],
  514.                 triumph: [
  515.                     {
  516.                         text: "Heal additional wounds while attempting to heal Critical Injury, or vice versa.",
  517.                         required: 1
  518.                     }
  519.                 ],
  520.                 threat: [
  521.                     {text: "Inflict strain on the target due to shock of procedure.", required: 1},
  522.                     {text: "Increase time procedure takes.", required: 1}
  523.                 ],
  524.                 despair: [
  525.                     {text: "A truly terrible accident, perhaps inflicting further wounds on target.", required: 1}
  526.                 ]
  527.             },
  528.             Negotiation: {
  529.                 success: [
  530.                     {text: "Increase acting character's profit by 5%.", required: 1},
  531.                     {text: "Modify scope of agreement.", required: 1}
  532.                 ],
  533.                 advantage: [
  534.                     {
  535.                         text: "Earn unrelated boons from target, concessions if failed or extra perks if passed.",
  536.                         required: 1
  537.                     }
  538.                 ],
  539.                 triumph: [
  540.                     {text: "Have target NPC become regular client or specialist vendor.", required: 1}
  541.                 ],
  542.  
  543.                 threat: [
  544.                     {text: "Increase cost of goods purchased.", required: 1},
  545.                     {text: "Decrease value of goods sold.", required: 1},
  546.                     {text: "Shorten contracts negotiated.", required: 1}
  547.                 ],
  548.                 despair: [
  549.                     {
  550.                         text: "Seriously sabotage goals during the interaction, perhaps receive counterfeit goods or payment, or agree to terms entirely beyond scope of negotiation.",
  551.                         required: 1
  552.                     }
  553.                 ]
  554.             },
  555.             Perception: {
  556.                 success: [
  557.                     {text: "Reveal additional details.", required: 1}
  558.                 ],
  559.                 advantage: [
  560.                     {text: "Recall additional information associated with object noticed.", required: 1}
  561.                 ],
  562.                 triumph: [
  563.                     {
  564.                         text: "Notice details that can be useful later to gain $BOOST$ on future interactions with noticed object.",
  565.                         required: 1
  566.                     }
  567.                 ],
  568.                 threat: [
  569.                     {text: "Conceal a vital detail about situation or environment.", required: 1}
  570.                 ],
  571.                 despair: [
  572.                     {text: "Obtain false information about surroundings or target.", required: 1}
  573.                 ]
  574.             },
  575.             PilotingPlanetary: {
  576.                 success: [
  577.                     {text: "Gain insights into situation.", required: 1},
  578.                     {text: "Deduce way to modify vehicle to make it more effective in future.", required: 1}
  579.                 ],
  580.                 advantage: [
  581.                     {
  582.                         text: "Reveal vulnerability in opponent's piloting style or vehicle, giving benefit in later rounds.",
  583.                         required: 1
  584.                     }
  585.                 ],
  586.                 triumph: [
  587.                     {text: "Grant additional maneuver while continuing to pilot vehicle.", required: 1}
  588.                 ],
  589.                 threat: [
  590.                     {
  591.                         text: "Spend $THREAT$$THREAT$ to give opponents $BOOST$ on checks against character and vehicle due to momentary malfunction in system.",
  592.                         required: 2
  593.                     }
  594.                 ],
  595.                 despair: [
  596.                     {
  597.                         text: "Deal damage to vehicle as character strains systems throughout vehicle during check.",
  598.                         required: 1
  599.                     }
  600.                 ]
  601.             },
  602.             PilotingSpace: {
  603.                 success: [
  604.                     {text: "Gain insights into situation.", required: 1},
  605.                     {text: "Deduce way to modify vehicle to make it more effective in future.", required: 1}
  606.                 ],
  607.                 advantage: [
  608.                     {
  609.                         text: "Reveal vulnerability in opponent's piloting style or vehicle, giving benefit in later rounds.",
  610.                         required: 1
  611.                     }
  612.                 ],
  613.                 triumph: [
  614.                     {text: "Grant additional maneuver while continuing to pilot vehicle.", required: 1}
  615.                 ],
  616.                 threat: [
  617.                     {
  618.                         text: "Spend $THREAT$$THREAT$ to give opponents $BOOST$ on checks against character and vehicle due to momentary malfunction in system.",
  619.                         required: 2
  620.                     }
  621.                 ],
  622.                 despair: [
  623.                     {
  624.                         text: "Deal damage to vehicle as character strains systems throughout vehicle during check.",
  625.                         required: 1
  626.                     }
  627.                 ]
  628.             },
  629.             Resilience: {
  630.                 success: [
  631.                     {text: "Extend effects of the success to increase time between checks.", required: 1}
  632.                 ],
  633.                 advantage: [
  634.                     {text: "Identify way to reduce difficulty of future checks against same threat.", required: 1}
  635.                 ],
  636.                 triumph: [
  637.                     {text: "Recover 3 strain.", required: 1}
  638.                 ],
  639.                 threat: [
  640.                     {text: "Overburden the character, inflicting penalties on subsequent checks.", required: 1}
  641.                 ],
  642.                 despair: [
  643.                     {
  644.                         text: "Inflict a wound or minor Critical Injury on character, as they succumb to harsh conditions.",
  645.                         required: 1
  646.                     }
  647.                 ]
  648.             },
  649.             Skulduggery: {
  650.                 success: [
  651.                     {text: "Gain additional insights about nature of opposition.", required: 1}
  652.                 ],
  653.                 advantage: [
  654.                     {text: "Identify additional potential target.", required: 1}
  655.                 ],
  656.                 triumph: [
  657.                     {text: "Earn an unexpected boon.", required: 1}
  658.                 ],
  659.                 threat: [
  660.                     {
  661.                         text: "Opportunity to catch character immediately after act, number of $THREAT$ determine immediacy of discovery and ensuing danger.",
  662.                         required: 1
  663.                     }
  664.                 ],
  665.                 despair: [
  666.                     {text: "Leave behind evidence of larceny.", required: 1}
  667.                 ]
  668.             },
  669.             Stealth: {
  670.                 success: [
  671.                     {text: "Assist allied character infiltrating at same time.", required: 1}
  672.                 ],
  673.                 advantage: [
  674.                     {text: "Decrease time taken to perform action while hidden.", required: 1}
  675.                 ],
  676.                 triumph: [
  677.                     {text: "Identify way to completely distract opponent for duration of scene.", required: 1}
  678.                 ],
  679.                 threat: [
  680.                     {text: "Increase time taken to perform action while hidden by 20%.", required: 1}
  681.                 ],
  682.                 despair: [
  683.                     {text: "Leave behind evidence of passing, concerning identity and possibly motive.", required: 1}
  684.                 ]
  685.             },
  686.             Streetwise: {
  687.                 success: [
  688.                     {text: "Reduce time or funds required to obtain item, information or service.", required: 1}
  689.                 ],
  690.                 advantage: [
  691.                     {text: "Reveal additional rumours or alternative sources.", required: 1}
  692.                 ],
  693.                 triumph: [
  694.                     {text: "Gain semi-permanent contact on street.", required: 1}
  695.                 ],
  696.                 threat: [
  697.                     {text: "Seed gathered information with minor falsehoods.", required: 1}
  698.                 ],
  699.                 despair: [
  700.                     {text: "Character lets slip details about self or information sought.", required: 1}
  701.                 ]
  702.             },
  703.             Survival: {
  704.                 success: [
  705.                     {text: "Assist other character in surviving.", required: 1},
  706.                     {text: "Stockpile goods to increase time between checks.", required: 1}
  707.                 ],
  708.                 advantage: [
  709.                     {text: "Gain insight into environment to make future checks simpler.", required: 1},
  710.                     {
  711.                         text: "When tracking, learn significant detail about target, such as number, species or how recently tracks were made.",
  712.                         required: 1
  713.                     }
  714.                 ],
  715.                 triumph: [
  716.                     {
  717.                         text: "When handling domesticated animal, predispose animal towards character earning loyal companion.",
  718.                         required: 1
  719.                     },
  720.                     {text: "When tracking, learn vital clue about target.", required: 1}
  721.                 ],
  722.                 threat: [
  723.                     {text: "Spend vital resources (food, fuel, etc.) during check.", required: 1}
  724.                 ],
  725.                 despair: [
  726.                     {text: "Inflict wounds, Critical Injuries or large amounts of strain on character.", required: 1}
  727.                 ]
  728.             },
  729.             Vigilance: {
  730.                 success: [
  731.                     {text: "Character is particularly well prepared.", required: 1}
  732.                 ],
  733.                 advantage: [
  734.                     {text: "Notice key environmental factor.", required: 1}
  735.                 ],
  736.                 triumph: [
  737.                     {text: "Gain extra maneuver during first round of combat.", required: 1}
  738.                 ],
  739.                 threat: [
  740.                     {text: "Miss key piece of information about situation or environment.", required: 1}
  741.                 ],
  742.                 despair: [
  743.                     {
  744.                         text: "The character is unable to perform more than one maneuver during first round of combat.",
  745.                         required: 1
  746.                     }
  747.                 ]
  748.             }
  749.         },
  750.         combat: {
  751.             /*TODO continue working on the combat skill suggestions*/
  752.             personal: {
  753.                 AllowedSkills: [
  754.                     "RangedLight",
  755.                     "RangedHeavy",
  756.                     "Melee",
  757.                     "Brawl",
  758.                     "Lightsaber",
  759.                     "Gunnery"
  760.                 ],
  761.                 '1advantage1triumph': [
  762.                     {text: "Recover 1 strain", advantage: 1, triumph: 1},
  763.                     {text: "Add $BOOST$ to the next allied active character's next check.", advantage: 1, triumph: 1},
  764.                     {text: "Notice a single important point in the ongoing conflict.", advantage: 1, triumph: 1},
  765.                     {
  766.                         text: "Inflict a Critical Injury with a successful attack that deals damage past soak. ($ADVANTAGE$ cost may vary)",
  767.                         advantage: 1,
  768.                         triumph: 1,
  769.                         crit: true
  770.                     }
  771.                 ],
  772.                 '2advantage1triumph': [
  773.                     {text: "Activate a weapon quality ($ADVANTAGE$ cost may vary)", advantage: 2, triumph: 1},
  774.                     {
  775.                         text: "Perform an immediate free maneuver that does not exceed the two maneuver per turn limit",
  776.                         advantage: 2,
  777.                         triumph: 1
  778.                     },
  779.                     {text: "Add $SETBACK$ to the targeted character's next check.", advantage: 2, triumph: 1},
  780.                     {
  781.                         text: "Add $BOOST$ to any allied character's next check, including that of the active character.",
  782.                         advantage: 2,
  783.                         triumph: 1
  784.                     }
  785.                 ],
  786.                 '3advantage1triumph': [
  787.                     {
  788.                         text: "Negate the targeted enemy's defensive bonuses until the end of turn",
  789.                         advantage: 3,
  790.                         triumph: 1
  791.                     },
  792.                     {
  793.                         text: "Ignore penalizing environmental effects until the end of the active character's next turn.",
  794.                         advantage: 3,
  795.                         triumph: 1
  796.                     },
  797.                     {
  798.                         text: "When dealing damage to a target, have the attack disable the opponent or one piece of gear rather than dealing wounds or strain.",
  799.                         advantage: 3,
  800.                         triumph: 1
  801.                     },
  802.                     {
  803.                         text: "Gain +1 melee or ranged defense until the end of the active character's next turn",
  804.                         advantage: 3,
  805.                         triumph: 1
  806.                     },
  807.                     {
  808.                         text: "Force the target to drop a melee or ranged weapon they are wielding.",
  809.                         advantage: 3,
  810.                         triumph: 1
  811.                     }
  812.                 ],
  813.                 '1triumph': [
  814.                     {text: "Upgrade the difficulty of the targeted character's next check.", triumph: 1},
  815.                     {
  816.                         text: "Upgrade any allied character's next check, including that of the current active character.",
  817.                         triumph: 1
  818.                     },
  819.                     {text: "Do something vital, such as shooting the controls to the nearby blast doors.", triumph: 1}
  820.                 ],
  821.                 '2triumph': [
  822.                     {
  823.                         text: "When dealing damage to a target, had the attack destroyed a piece of equipment the target is using.",
  824.                         triumph: 2
  825.                     }
  826.                 ],
  827.                 '1threat1despair': [
  828.                     {text: "The active character suffers 1 strain", threat: 1, despair: 1},
  829.                     {text: "The active character looses the benefits of a prior maneuver", threat: 1, despair: 1}
  830.                 ],
  831.                 '2threat1despair': [
  832.                     {text: "An opponent may immediately perform one free maneuver.", threat: 2, despair: 1},
  833.                     {text: "Add $BOOST$ to the targeted character's next check", threat: 2, despair: 1},
  834.                     {
  835.                         text: "The active character or an allied character suffers a $SETBACK$ on their next action.",
  836.                         threat: 2,
  837.                         despair: 1
  838.                     }
  839.                 ],
  840.                 '3threat1despair': [
  841.                     {text: "The active character falls prone.", threat: 3, despair: 1},
  842.                     {
  843.                         text: "The active character grants the enemy a significant advantage in the ongoing encounter.",
  844.                         threat: 3,
  845.                         despair: 1
  846.                     }
  847.                 ],
  848.                 '1despair': [
  849.                     {text: "The character's ranged weapon immediately runs out of ammunition.", despair: 1},
  850.                     {
  851.                         text: "Upgrade the difficulty of an allied character's next check, including the active character.",
  852.                         despair: 1
  853.                     },
  854.                     {text: "The tool or melee weapon the character is using becomes damaged.", despair: 1}
  855.                 ]
  856.             },
  857.             vehicle: {
  858.                 AllowedSkills: [
  859.                     "RangedHeavy",
  860.                     "Gunnery",
  861.                     "PilotingSpace",
  862.                     "PilotingPlanetary"
  863.  
  864.                 ],
  865.                 '1advantage1triumph': [
  866.                     {
  867.                         text: "Add $BOOST$ to the next allied active character's Piloting, Gunnery, Computers, or Mechanics check.",
  868.                         advantage: 1,
  869.                         triumph: 1
  870.                     },
  871.                     {text: "Notice a single important point in the ongoing conflict.", advantage: 1, triumph: 1},
  872.                     {
  873.                         text: "Inflict a Critical Hit with successful attack that deals damage past armor ($ADVANTAGE$ cost may vary)",
  874.                         advantage: 1,
  875.                         triumph: 1,
  876.                         crit: true
  877.                     }
  878.                 ],
  879.                 '2advantage1triumph': [
  880.                     {text: "Activate a weapon quality ($ADVANTAGE$ cost may vary", advantage: 2, triumph: 1},
  881.                     {
  882.                         text: "Perform an immediate free maneuver, provided the active character has not already performed two maneuvers in that turn.",
  883.                         advantage: 2,
  884.                         triumph: 1
  885.                     },
  886.                     {
  887.                         text: "Add $SETBACK$ to the targeted character's next Piloting or Gunnery check.",
  888.                         advantage: 2,
  889.                         triumph: 1
  890.                     },
  891.                     {
  892.                         text: "Add $BOOST$ to any allied character's next Piloting, Gunnery, Computers or Mechanics check, including the active character,",
  893.                         advantage: 2,
  894.                         triumph: 1
  895.                     }
  896.                 ],
  897.                 '3advantage1triumph': [
  898.                     {
  899.                         text: "When dealing damage to an opposing vehicle or ship, have the shot temporarily damage a component of the attacker's choice rather than deal hull damage or system strain.",
  900.                         advantage: 3,
  901.                         triumph: 1
  902.                     },
  903.                     {
  904.                         text: "Ignore penalizing terrain or stellar phenomena until the end of the active character's next turn.",
  905.                         advantage: 3,
  906.                         triumph: 1
  907.                     },
  908.                     {
  909.                         text: "If piloting the ship, perform one free Pilot Only maneuver (provided it does not break the limit of maximum number of Pilot Only maneuvers in a turn).",
  910.                         advantage: 3,
  911.                         triumph: 1
  912.                     },
  913.                     {
  914.                         text: "Force the target ship or vehicle to veer off, breaking any Aim or Stay on Target maneuvers.",
  915.                         advantage: 3,
  916.                         triumph: 1
  917.                     }
  918.                 ],
  919.                 '1triumph': [
  920.                     {
  921.                         text: "Upgrade the difficulty of the targeted character's next Piloting or Gunnery check.",
  922.                         triumph: 1
  923.                     },
  924.                     {
  925.                         text: "Upgrade any allied character's next Piloting, Gunnery, Computers or Mechanics check.",
  926.                         triumph: 1
  927.                     }
  928.                 ],
  929.                 '2triumph': [
  930.                     {text: "Destroy an important component when dealing damage.", triumph: 2}
  931.                 ],
  932.                 '1threat1despair': [
  933.                     {
  934.                         text: "If piloting a ship, sudden maneuvers force the ship to slow down by 1 point of speed.",
  935.                         threat: 1,
  936.                         despair: 1
  937.                     },
  938.                     {text: "The active character looses the benefits of a prior maneuver.", threat: 1, despair: 1},
  939.                     {
  940.                         text: "The character's active ship suffers 1 system strain. (This option may be selected multiple times)",
  941.                         threat: 1,
  942.                         despair: 1
  943.                     }
  944.                 ],
  945.                 '2threat1despair': [
  946.                     {text: "An opponent may immediately perform one free maneuver.", threat: 2, despair: 1},
  947.                     {
  948.                         text: "Add $BOOST$ to the targeted character's next Piloting or Gunnery Check",
  949.                         threat: 2,
  950.                         despair: 1
  951.                     },
  952.                     {
  953.                         text: "The active character or allied character suffers $SETBACK$ on their next action.",
  954.                         threat: 2,
  955.                         despair: 1
  956.                     }
  957.                 ],
  958.                 '3threat1despair': [
  959.                     {
  960.                         text: "The initiative currently being used drops below the last slot in the round.",
  961.                         threat: 3,
  962.                         despair: 1
  963.                     },
  964.                     {text: "The enemy gains a significant advantage in the ongoing encounter.", threat: 3, despair: 1},
  965.                     {
  966.                         text: "The primary weapon system of the active character's ship (or weapon the character is manning if acting as a gunner) suffers a Component Critical Hit.",
  967.                         despair: 1
  968.                     }
  969.                 ],
  970.                 '1despair': [
  971.                     {
  972.                         text: "Upgrade the difficulty of an allied character's next Gunnery, Piloting, computers or Mechanics check.",
  973.                         despair: 1
  974.                     },
  975.                     {
  976.                         text: "The active character's ship suffers a minor collision either with one of their opponents within close range or with the terrain around them.",
  977.                         despair: 1
  978.                     },
  979.                     {
  980.                         text: "The active character's ship suffers a major collision either with one of their opponents within close range or with the terrain around them.",
  981.                         despair: 1,
  982.                         failed: true
  983.                     }
  984.                 ]
  985.             }
  986.         }
  987.     };
  988.  
  989.     this.enum = {
  990.         types: {
  991.             general: {number:0, text:"general"},
  992.             combat: {number:1, text:"combat"}
  993.         },
  994.         displayOptions: {
  995.             none: {number:0, text:"none"},          // Suggestions are not displayed
  996.             whisper: {number:1, text:"whisper"},    // Suggestions are whispered to the GM
  997.             always: {number:2, text:"always"}       // Suggestions are included in the dice roll result
  998.         },
  999.         combatType: {
  1000.             personal: {number:0, text:"personal"},
  1001.             vehicle: {number:1, text:"vehicle"}
  1002.         }
  1003.     };
  1004.  
  1005.     this.setDisplayOption = function (input) {
  1006.         if (input == null || input === "")
  1007.             return;
  1008.  
  1009.         var flag = null;
  1010.         if (flag = that.enum.isValidInput(input, that.enum.displayOptions))
  1011.             flags.displayOption = flag;
  1012.     };
  1013.  
  1014.     this.getDisplayOption = function () {
  1015.         return flags.displayOption;
  1016.     };
  1017.  
  1018.     this.setGeneralSuggestions = function (input) {
  1019.         if (input == null || input === "")
  1020.             return;
  1021.         log("input="+input);
  1022.  
  1023.         flags.generalSuggesting = convertToBoolean(input);
  1024.         log("flags.generalSuggesting="+flags.generalSuggesting);
  1025.     };
  1026.  
  1027.     this.getGeneralSuggesting = function () {
  1028.         return flags.generalSuggesting;
  1029.     };
  1030.  
  1031.     this.setCombatSuggestions = function (input) {
  1032.         if (input == null || input === "")
  1033.             return;
  1034.         log("input="+input);
  1035.         flags.combatSuggesting = convertToBoolean(input);
  1036.         log("flags.combatSuggesting="+flags.combatSuggesting);
  1037.     };
  1038.  
  1039.     this.getCombatSuggesting = function () {
  1040.         return flags.combatSuggesting;
  1041.     };
  1042.  
  1043.     this.setIsFearCheck = function (input) {
  1044.         if (input == null || input === "")
  1045.             return;
  1046.  
  1047.         flags.isFearCheck = convertToBoolean(input);
  1048.     };
  1049.  
  1050.     this.getIsFearCheck = function () {
  1051.         return flags.isFearCheck;
  1052.     };
  1053.  
  1054.     this.setCombatType = function (input) {
  1055.         if (input == null || input === "") {
  1056.             flags.combatType = null;
  1057.             return;
  1058.         }
  1059.  
  1060.         var flag = null;
  1061.         if (flag = that.enum.isValidInput(input, that.enum.combatType))
  1062.             flags.combatType = flag;
  1063.     };
  1064.  
  1065.     this.getCombatType = function () {
  1066.         return flags.combatType;
  1067.     };
  1068.  
  1069.     this.enum.isValidInput = function (input, enumToUse) {
  1070.         if (input == null || input === "" || !enumToUse)
  1071.             return;
  1072.  
  1073.         var retVal = null;
  1074.  
  1075.         Object.keys(enumToUse).some(function(key) {
  1076.             var object = enumToUse[key];
  1077.  
  1078.             if (input == object || input === object.text || input === object.number) {
  1079.                 return retVal = object;
  1080.             }
  1081.         });
  1082.  
  1083.         return retVal;
  1084.     };
  1085.  
  1086.     this.enum.mapTextToNumber = function (input, enumToUse) {
  1087.         if (input == null || input === "")
  1088.             return;
  1089.  
  1090.         var flag = null;
  1091.         if (flag = that.enum.isValidInput(input, enumToUse))
  1092.             return flag.number;
  1093.     };
  1094.  
  1095.     this.enum.mapNumberToText = function (input, enumToUse) {
  1096.         if (input == null || input === "")
  1097.             return;
  1098.  
  1099.         var flag = null;
  1100.         if (flag = that.enum.isValidInput(input, enumToUse))
  1101.             return flag.text;
  1102.     };
  1103.  
  1104.  
  1105.     /* Suggestion Handling */
  1106.     function addSkillSuggestionsFromArray (diceObj, array, key, rollResultForSymbol, suggestionsType) {
  1107.         for (var i = 0; i < array.length; i++) {
  1108.             if (array[i].required <= rollResultForSymbol) {
  1109.                 suggestionsType[key] += "<li>" + array[i].text + "</li>";
  1110.                 diceObj.vars.suggestions.suggestionsExist = true;
  1111.             }
  1112.         }
  1113.         return diceObj;
  1114.     }
  1115.  
  1116.     function buildSuggestionSet (suggestionSet, symbol, rollResultForSymbol, suggestionJSON) {
  1117.         if (suggestionSet == null)
  1118.             suggestionSet = new Set();
  1119.  
  1120.         var item = {};
  1121.         for (var i = 0; i < suggestionJSON.length; i++) {
  1122.             item = suggestionJSON[i];
  1123.             if (item.hasOwnProperty(symbol) && item[symbol] <= rollResultForSymbol) {
  1124.                 suggestionSet.add(item.text);
  1125.             }
  1126.         }
  1127.  
  1128.         return suggestionSet;
  1129.     }
  1130.  
  1131.     function buildCombatSuggestions (diceObj, symbol, rollResultForSymbol, suggestionJSON) {
  1132.         var suggestionSet = null;
  1133.         var spendingSuggestions = diceObj.vars.suggestions;
  1134.         Object.keys(suggestionJSON).forEach(function(property) {
  1135.             if (property === "AllowedSkills")
  1136.                 return;
  1137.  
  1138.             suggestionSet = spendingSuggestions.combat[property];
  1139.             suggestionSet = buildSuggestionSet(suggestionSet, symbol, rollResultForSymbol, suggestionJSON[property]);
  1140.  
  1141.             if (suggestionSet.size > 0) {
  1142.                 spendingSuggestions.suggestionsExist = true;
  1143.                 spendingSuggestions.combat[property] = suggestionSet;
  1144.             }
  1145.         });
  1146.  
  1147.         return diceObj;
  1148.     }
  1149.  
  1150.     function buildRollTemplateItem (key, value) {
  1151.         return "{{" + key + "=<ul>" + value + "</ul>}}";
  1152.     }
  1153.  
  1154.     function generateSuggestions (diceObj, symbol, rollResultForSymbol) {
  1155.         var skillName = diceObj.vars.skillName;
  1156.  
  1157.         var combatType = flags.combatType;
  1158.         if (flags.combatSuggesting && combatType) {
  1159.             var combatSkills = that.suggestions.combat;
  1160.             var personal = that.enum.combatType.personal;
  1161.             var vehicle = that.enum.combatType.vehicle;
  1162.             if (combatType == personal)
  1163.             {
  1164.                 diceObj = buildCombatSuggestions(diceObj, symbol, rollResultForSymbol, combatSkills.personal);
  1165.             }
  1166.             else if (combatType == vehicle)
  1167.             {
  1168.                 diceObj = buildCombatSuggestions(diceObj, symbol, rollResultForSymbol, combatSkills.vehicle);
  1169.             }
  1170.         } else if (flags.generalSuggesting) {
  1171.             var generalSkills = that.suggestions.general;
  1172.             if (generalSkills.hasOwnProperty(skillName)) {
  1173.                 var skill = generalSkills[skillName];
  1174.                 var fearJSON = (diceObj.vars.isFearCheck ? that.suggestions.special.fear : null);
  1175.  
  1176.                 if (skill.hasOwnProperty(symbol)) {
  1177.                     diceObj = addSkillSuggestionsFromArray(diceObj, skill[symbol], symbol, rollResultForSymbol, diceObj.vars.suggestions.general);
  1178.                 }
  1179.  
  1180.                 if (fearJSON && fearJSON.allowedSkills.indexOf(skillName)) {
  1181.                     diceObj = addSkillSuggestionsFromArray(diceObj, fearJSON[symbol], symbol, rollResultForSymbol, diceObj.vars.suggestions.general);
  1182.                 }
  1183.             }
  1184.         }
  1185.         return diceObj;
  1186.     }
  1187.  
  1188.     this.processSuggestions = function(diceObj) {
  1189.         if (flags.displayOption === that.enum.displayOptions.none)
  1190.             return diceObj;
  1191.  
  1192.         diceObj.vars.suggestions = {
  1193.             general: {
  1194.                 success: "",
  1195.                 advantage: "",
  1196.                 triumph: "",
  1197.                 failure: "",
  1198.                 threat: "",
  1199.                 despair: ""
  1200.             },
  1201.             combat: {
  1202.                 '1advantage1triumph': null,
  1203.                 '2advantage1triumph': null,
  1204.                 '3advantage1triumph': null,
  1205.                 '1triumph': null,
  1206.                 '2triumph': null,
  1207.                 '1threat1despair': null,
  1208.                 '2threat1despair': null,
  1209.                 '3threat1despair': null,
  1210.                 '1despair': null,
  1211.                 '2despair': null
  1212.             },
  1213.             suggestionsExist: false
  1214.         };
  1215.  
  1216.  
  1217.         var failedCheck = !diceObj.totals.success > 0;
  1218.         Object.keys(diceObj.totals).forEach(function(key) {
  1219.             var rollResultForSymbol = diceObj.totals[key];
  1220.             if (rollResultForSymbol > 0) {
  1221.                 diceObj = generateSuggestions(diceObj, key, rollResultForSymbol, failedCheck);
  1222.             }
  1223.         });
  1224.  
  1225.         return diceObj;
  1226.     };
  1227.  
  1228.     this.buildSuggestionsRollTemplate = function (diceObj) {
  1229.         var suggestions = diceObj.vars.suggestions;
  1230.         var suggestionsRollTemplate = "";
  1231.  
  1232.         // display results shown to character owners and GM
  1233.         Object.keys(suggestions).forEach(function (property) {
  1234.             if (property === "suggestionsExist")
  1235.                 return;
  1236.  
  1237.             var propertyObject = suggestions[property];
  1238.             Object.keys(propertyObject).forEach(function(symbol) {
  1239.                 var object = propertyObject[symbol];
  1240.  
  1241.                 if (!object)
  1242.                     return;
  1243.  
  1244.                 if (typeof object === "string")
  1245.                     suggestionsRollTemplate += buildRollTemplateItem(symbol, object);
  1246.                 else if (object.size > 0) {
  1247.                     var suggestionList = "";
  1248.                     object.forEach(function (value) {
  1249.                         suggestionList += "<li>" + value + "</li>";
  1250.                     });
  1251.                     suggestionsRollTemplate += buildRollTemplateItem(symbol, suggestionList);
  1252.                 }
  1253.             });
  1254.         });
  1255.         return suggestionsRollTemplate;
  1256.     }
  1257. }
  1258.  
  1259. /*TODO refactor eote to be swrpg*/
  1260. var eote = {};
  1261.  
  1262. eote.init = function () {
  1263.     eote.setCharacterDefaults();
  1264.     eote.createGMDicePool();
  1265.     eote.events();
  1266.     convertTokensToTags(suggestionEngine.suggestions, eote.defaults.graphics.SymbolicReplacement);
  1267.     attemptRegisterGMObj();
  1268. };
  1269.  
  1270.  
  1271. eote.defaults = {
  1272.     globalVars: {
  1273.         diceLogChat: true,
  1274.         diceGraphicsChat: true,
  1275.         diceGraphicsChatSize: 30,//medium size
  1276.         diceTextResult: "",
  1277.         diceTextResultLog: "",
  1278.         diceGraphicResult: "",
  1279.         diceGraphicResultLog: "",
  1280.         diceTestEnabled: false,
  1281.         diceLogRolledOnOneLine: true,
  1282.         scriptDebug: false
  1283.     },
  1284.     '-DicePoolID': '',
  1285.     GMSheet: {
  1286.         obj: null,
  1287.         name: "-DicePool"
  1288.     },
  1289.     character: {
  1290.         attributes: [
  1291.             /* Don't need to update characterID
  1292.              *
  1293.              *{
  1294.              name : "characterID",
  1295.              current : "UPDATES TO CURRENT ID",
  1296.              max : "",
  1297.              update : false
  1298.              }*/
  1299.         ],
  1300.         abilities: []
  1301.     },
  1302.     graphics: {
  1303.         SIZE: {
  1304.             SMALL: 20,
  1305.             MEDIUM: 30,
  1306.             LARGE: 40
  1307.         },
  1308.         ABILITY: {
  1309.             BLANK: "http://i.imgur.com/g3hoJRG.png",
  1310.             A: "http://i.imgur.com/VG7HnFE.png",
  1311.             AA: "http://i.imgur.com/ynn0deR.png",
  1312.             S: "http://i.imgur.com/HnweiQT.png",
  1313.             SA: "http://i.imgur.com/iVXuNKP.png",
  1314.             SS: "http://i.imgur.com/IVDgDKo.png"
  1315.         },
  1316.         BOOST: {
  1317.             BLANK: "http://i.imgur.com/nlIAfJx.png",
  1318.             A: "http://i.imgur.com/d6X6QEs.png",
  1319.             AA: "http://i.imgur.com/EqMcrlF.png",
  1320.             S: "http://i.imgur.com/vrt51oP.png",
  1321.             SA: "http://i.imgur.com/r9xl3CP.png"
  1322.         },
  1323.         CHALLENGE: {
  1324.             BLANK: "http://i.imgur.com/GInMHEN.png",
  1325.             F: "http://i.imgur.com/zKdsTV9.png",
  1326.             FF: "http://i.imgur.com/QcZXdpS.png",
  1327.             FT: "http://i.imgur.com/wxV072J.png",
  1328.             T: "http://i.imgur.com/n2rgehM.png",
  1329.             TT: "http://i.imgur.com/SaWvZMV.png",
  1330.             DESPAIR: "http://i.imgur.com/5EppLES.png"
  1331.         },
  1332.         DIFFICULTY: {
  1333.             BLANK: "http://i.imgur.com/oxbKghK.png",
  1334.             F: "http://i.imgur.com/rujbVt9.png",
  1335.             FF: "http://i.imgur.com/VUj86X2.png",
  1336.             FT: "http://i.imgur.com/l8rUPCX.png",
  1337.             T: "http://i.imgur.com/2gLDiqq.png",
  1338.             TT: "http://i.imgur.com/4wqEJsa.png"
  1339.         },
  1340.         FORCE: {
  1341.             D: "http://i.imgur.com/8kBnDI1.png",
  1342.             DD: "http://i.imgur.com/eki6Bnc.png",
  1343.             L: "http://i.imgur.com/JCI7Mgm.png",
  1344.             LL: "http://i.imgur.com/Z58SAHI.png"
  1345.         },
  1346.         PROFICIENCY: {
  1347.             BLANK: "http://i.imgur.com/4bQ0dY8.png",
  1348.             A: "http://i.imgur.com/PU7pp3w.png",
  1349.             S: "http://i.imgur.com/jXGG6L1.png",
  1350.             SA: "http://i.imgur.com/oQMDNdm.png",
  1351.             SS: "http://i.imgur.com/UDW3jYZ.png",
  1352.             AA: "http://i.imgur.com/jUA6PVw.png",
  1353.             TRIUMPH: "http://i.imgur.com/7zrDoEN.png"
  1354.         },
  1355.         SETBACK: {
  1356.             BLANK: "http://i.imgur.com/n9W07Lp.png",
  1357.             F: "http://i.imgur.com/jMV5VOB.png",
  1358.             T: "http://i.imgur.com/TYgM9LP.png"
  1359.         },
  1360.         SYMBOLS: {
  1361.             A: "http://i.imgur.com/Gav94H2.png",
  1362.             S: "http://i.imgur.com/z79ieDp.png",
  1363.             T: "http://i.imgur.com/o8EQ4z6.png",
  1364.             F: "http://i.imgur.com/y2qABhW.png",
  1365.             TRIUMPH: "http://i.imgur.com/1lJCfnB.png",
  1366.             DESPAIR: "http://i.imgur.com/rOEJlCc.png",
  1367.             L: "http://i.imgur.com/j5bV12H.png",
  1368.             D: "http://i.imgur.com/AZ3lzVj.png"
  1369.         },
  1370.         SymbolicReplacement: {}
  1371.     },
  1372.     regex: {
  1373.         cmd: /!eed/,
  1374.         log: /log (on|multi|single|off)/,
  1375.         debug: /debug (on|off)/,
  1376.         graphics: /graphics (on|off|s|m|l)/,
  1377.         test: /test/,
  1378.         resetdice: /(resetgmdice|resetdice)/,
  1379.         initiative: /\bnpcinit|\bpcinit/,
  1380.         characterID: /characterID\((.*?)\)/,
  1381.         rollPlayer: /rollPlayer(\(.*?\))/,
  1382.         label: /label\((.*?)\)/,
  1383.         skill: /skill\((.*?)\)/g,
  1384.         fear: /fear (on|off)/,
  1385.         suggestionDisplay: /suggestionDisplay (none|whisper|always)/,
  1386.         opposed: /opposed\((.*?)\)/g,
  1387.         upgrade: /upgrade\((.*?)\)/g,
  1388.         downgrade: /downgrade\((.*?)\)/g,
  1389.         gmdice: /\(gmdice\)/,
  1390.         encum: /encum\((.*?)\)/g,
  1391.         dice: /(-?\d{1,2}blk)\b|(-?\d{1,2}b)\b|(-?\d{1,2}g)\b|(-?\d{1,2}y)\b|(-?\d{1,2}p)\b|(-?\d{1,2}r)\b|(-?\d{1,2}w)\b|(-?\d{1,2}a)\b|(-?\d{1,2}s)|(-?\d{1,2}t)\b|(-?\d{1,2}f)/g,
  1392.         crit: /crit\((.*?)\)/,
  1393.         critShip: /critship\((.*?)\)/,
  1394.         unusable: /unusableWeapon/,
  1395.         destiny: /destiny (useDark|useLight|registerPlayer|sendUpdate|doRoll|clearPool)/,
  1396.         combat: /combat\(personal|vehicle\)/
  1397.     },
  1398.     destinyListeners: []
  1399. };
  1400.  
  1401. var GMSheet = eote.defaults.GMSheet;
  1402. var suggestionEngine = new SuggestionEngine();
  1403.  
  1404. function buildReplacementObject (title, src, size) {
  1405.     return {matcher: new RegExp("\\$" + title.toUpperCase() + "\\$","g"), replacer: '<img src="' + src + '" title="' + title + '" height="' + size + '" width="' + size + '"/>'};
  1406. }
  1407.  
  1408. // dice symbols
  1409. eote.defaults.graphics.SymbolicReplacement.success = buildReplacementObject("success", eote.defaults.graphics.SYMBOLS.S, eote.defaults.graphics.SIZE.SMALL);
  1410. eote.defaults.graphics.SymbolicReplacement.advantage = buildReplacementObject("advantage", eote.defaults.graphics.SYMBOLS.A, eote.defaults.graphics.SIZE.SMALL);
  1411. eote.defaults.graphics.SymbolicReplacement.triumph = buildReplacementObject("triumph", eote.defaults.graphics.SYMBOLS.TRIUMPH, eote.defaults.graphics.SIZE.SMALL);
  1412. eote.defaults.graphics.SymbolicReplacement.failure = buildReplacementObject("failure", eote.defaults.graphics.SYMBOLS.F, eote.defaults.graphics.SIZE.SMALL);
  1413. eote.defaults.graphics.SymbolicReplacement.threat = buildReplacementObject("threat", eote.defaults.graphics.SYMBOLS.T, eote.defaults.graphics.SIZE.SMALL);
  1414. eote.defaults.graphics.SymbolicReplacement.despair = buildReplacementObject("despair", eote.defaults.graphics.SYMBOLS.DESPAIR, eote.defaults.graphics.SIZE.SMALL);
  1415.  
  1416. // dice icons
  1417. eote.defaults.graphics.SymbolicReplacement.ability = buildReplacementObject("ability", eote.defaults.graphics.ABILITY.BLANK, eote.defaults.graphics.SIZE.SMALL);
  1418. eote.defaults.graphics.SymbolicReplacement.boost = buildReplacementObject("boost", eote.defaults.graphics.BOOST.BLANK, eote.defaults.graphics.SIZE.SMALL);
  1419. eote.defaults.graphics.SymbolicReplacement.proficiency = buildReplacementObject("proficiency", eote.defaults.graphics.PROFICIENCY.BLANK, eote.defaults.graphics.SIZE.SMALL);
  1420. eote.defaults.graphics.SymbolicReplacement.difficulty = buildReplacementObject("difficulty", eote.defaults.graphics.DIFFICULTY.BLANK, eote.defaults.graphics.SIZE.SMALL);
  1421. eote.defaults.graphics.SymbolicReplacement.setback = buildReplacementObject("setback", eote.defaults.graphics.SETBACK.BLANK, eote.defaults.graphics.SIZE.SMALL);
  1422. eote.defaults.graphics.SymbolicReplacement.challenge = buildReplacementObject("challenge", eote.defaults.graphics.CHALLENGE.BLANK, eote.defaults.graphics.SIZE.SMALL);
  1423.  
  1424. function attemptRegisterGMObj() {
  1425.     var GMObj = GMSheet.obj;
  1426.  
  1427.     // if the GMObj is null then it means that this is the first time this version of the script is being run on this campaign.
  1428.     if (!GMObj) {
  1429.         GMObj = findObjs({
  1430.             _type: "character",
  1431.             name: GMSheet.name
  1432.         });
  1433.         if (GMObj.length > 0) {
  1434.             GMSheet.obj = GMObj[0];
  1435.             eote.process.logger("attemptRegisterGMObj", "Registering of GMObj successful");
  1436.         }
  1437.         else {
  1438.             var msg = "The character sheet called " + GMSheet.name + " was not found in your campaign.";
  1439.             eote.process.logger("attemptRegisterGMObj", msg);
  1440.             sendChat("System", "/w gm " + msg);
  1441.         }
  1442.     } else {
  1443.         eote.process.logger("attemptRegisterGMObj", "GMObj previously registered.");
  1444.     }
  1445. }
  1446.  
  1447. eote.createGMDicePool = function () {
  1448.  
  1449.     var charObj_DicePool = findObjs({ _type: "character", name: "-DicePool" })[0];
  1450.     var attrObj_DicePool = [
  1451.         {
  1452.             name: 'pcgm',
  1453.             current: 3,
  1454.             max: '',
  1455.             update: true
  1456.         },
  1457.         {
  1458.             name: 'gmdicepool',
  1459.             current: 2,
  1460.             max: '',
  1461.             update: true
  1462.         }
  1463.     ];
  1464.     //create character -DicePool
  1465.     if (!charObj_DicePool) {
  1466.         charObj_DicePool = createObj("character", {
  1467.             name: GMSheet.name,
  1468.             bio: "GM Dice Pool"
  1469.         });
  1470.     }
  1471.     eote.defaults['-DicePoolID'] = charObj_DicePool.id;
  1472.     GMSheet.obj = charObj_DicePool;
  1473.     eote.updateAddAttribute(charObj_DicePool, attrObj_DicePool);
  1474. };
  1475.  
  1476. eote.createObj = function () {//Create Object Fix - Firebase.set failed
  1477.     var obj = createObj.apply(this, arguments);
  1478.     var id = obj.id;
  1479.     var characterID = obj.get('characterid');
  1480.     var type = obj.get('type');
  1481.     if (obj && !obj.fbpath && obj.changed) {
  1482.         obj.fbpath = obj.changed._fbpath.replace(/([^\/]*\/){4}/, "/");
  1483.     } else if (obj && !obj.changed && type == 'attribute') { //fix for dynamic attribute after in character created in game
  1484.         obj.fbpath = '/char-attribs/char/' + characterID + '/' + id;
  1485.         // /char-attribs/char/characterID/attributeID
  1486.     }
  1487.     return obj;
  1488. };
  1489.  
  1490. eote.setCharacterDefaults = function (characterObj) {
  1491.  
  1492.     var charObj = [characterObj];
  1493.  
  1494.     if (!characterObj) {
  1495.         charObj = findObjs({ _type: "character" });
  1496.     }
  1497.     //add/update characterID field
  1498.     _.each(charObj, function (charObj) {
  1499.         //updates default attr:CharacterID to current character id
  1500.         //_.findWhere(eote.defaults.character.attributes, {'name':'characterID'}).current = charObj.id;
  1501.  
  1502.         //Attributes
  1503.         eote.updateAddAttribute(charObj, eote.defaults.character.attributes);//Update Add Attribute defaults
  1504.         //Abilities
  1505.     });
  1506. };
  1507.  
  1508. eote.updateListeners = function (attributes) {
  1509.  
  1510.     _.each(eote.defaults.destinyListeners, function (charID) {
  1511.  
  1512.         var charObj = findObjs({
  1513.             _type: "character",
  1514.             _id: charID
  1515.         });
  1516.         //add/update characterID field
  1517.         _.each(charObj, function (charObj) {
  1518.             //Attributes
  1519.             eote.updateAddAttribute(charObj, attributes); //Update Add Attribute defaults
  1520.         });
  1521.     });
  1522.     //Update GM
  1523.     var GMObj = findObjs({
  1524.         _type: "character",
  1525.         name: GMSheet.name
  1526.     });
  1527.     GMSheet.obj = GMSheet.obj || GMObj;
  1528.     eote.updateAddAttribute(GMObj, attributes);
  1529. };
  1530.  
  1531. eote.updateAddAttribute = function (charactersObj, updateAddAttributesObj) { // charactersObj = object or array objects, updateAddAttributesObj = object or array objects
  1532.     if (!charactersObj) {
  1533.         log("error: charactersObj passed into eote.updateAddAttribute is not set");
  1534.         return;
  1535.     }
  1536.  
  1537.     //check if object or array
  1538.     if (!_.isArray(charactersObj)) {
  1539.         charactersObj = [charactersObj];
  1540.     }
  1541.     if (!_.isArray(updateAddAttributesObj)) {
  1542.         updateAddAttributesObj = [updateAddAttributesObj];
  1543.     }
  1544.     _.each(charactersObj, function (characterObj) {//loop characters
  1545.  
  1546.         var characterName = '';
  1547.  
  1548.         if (characterObj.name) {
  1549.             characterName = characterObj.name;
  1550.         } else {
  1551.             characterName = characterObj.get('name');
  1552.         }
  1553.         //find attribute via character ID
  1554.         var characterAttributesObj = findObjs({ _type: "attribute", characterid: characterObj.id });
  1555.  
  1556.         if (updateAddAttributesObj.length != 0) {
  1557.  
  1558.             log('UPDATE/ADD ATTRIBUTES FOR:----------------------->' + characterName);
  1559.  
  1560.             _.each(updateAddAttributesObj, function (updateAddAttrObj) { //loop attributes to update / add
  1561.  
  1562.                 attr = _.find(characterAttributesObj, function (a) {
  1563.                     return (a.get('name') === updateAddAttrObj.name);
  1564.                 });
  1565.                 if (attr) {
  1566.                     if (updateAddAttrObj.update) {
  1567.                         log('Update Attr: ' + updateAddAttrObj.name);
  1568.                         attr.set({ current: updateAddAttrObj.current });
  1569.                         attr.set({ max: updateAddAttrObj.max ? updateAddAttrObj.max : '' });
  1570.                     }
  1571.                 } else {
  1572.                     // log('Add Attr: '+ updateAddAttrObj.name);
  1573.                     eote.createObj('attribute', {
  1574.                         characterid: characterObj.id,
  1575.                         name: updateAddAttrObj.name,
  1576.                         current: updateAddAttrObj.current,
  1577.                         max: updateAddAttrObj.max ? updateAddAttrObj.max : ''
  1578.                     });
  1579.                 }
  1580.             });
  1581.         }
  1582.     });
  1583. };
  1584.  
  1585. /* DICE PROCESS
  1586.  *
  1587.  * Matches the different regex commands and runs that dice processing step
  1588.  * The order of step should not be change or dice could be incorrectly rolled.
  1589.  * example: All dice needs to be 'upgraded" before it can be 'downgraded'
  1590.  * ---------------------------------------------------------------- */
  1591.  
  1592. eote.defaults.dice = function () {
  1593.     this.vars = {
  1594.         characterName: '',
  1595.         characterID: '',
  1596.         playerName: '',
  1597.         playerID: '',
  1598.         label: '',
  1599.         suggestions: {},
  1600.         skillName: '',
  1601.         isFearCheck: false,
  1602.         combatCheck: false
  1603.     };
  1604.     this.totals = {
  1605.         success: 0,
  1606.         failure: 0,
  1607.         advantage: 0,
  1608.         threat: 0,
  1609.         triumph: 0,
  1610.         despair: 0,
  1611.         light: 0,
  1612.         dark: 0
  1613.     };
  1614.     this.graphicsLog = {
  1615.         Boost: '',
  1616.         Ability: '',
  1617.         Proficiency: '',
  1618.         SetBack: '',
  1619.         Difficulty: '',
  1620.         Challenge: '',
  1621.         Force: '',
  1622.         Success: '',
  1623.         Advantage: '',
  1624.         Threat: '',
  1625.         Failure: ''
  1626.     };
  1627.     this.textLog = {
  1628.         Boost: '',
  1629.         Ability: '',
  1630.         Proficiency: '',
  1631.         SetBack: '',
  1632.         Difficulty: '',
  1633.         Challenge: '',
  1634.         Force: '',
  1635.         Success: '',
  1636.         Advantage: '',
  1637.         Threat: '',
  1638.         Failure: ''
  1639.     };
  1640.     this.count = {
  1641.         boost: 0,
  1642.         ability: 0,
  1643.         proficiency: 0,
  1644.         setback: 0,
  1645.         difficulty: 0,
  1646.         challenge: 0,
  1647.         force: 0,
  1648.         success: 0,
  1649.         advantage: 0,
  1650.         threat: 0,
  1651.         failure: 0
  1652.     }
  1653. };
  1654.  
  1655. eote.process = {};
  1656.  
  1657. eote.process.logger = function (functionName, cmd) {
  1658.     if (eote.defaults.globalVars.debugScript) {
  1659.         log(functionName + ' : ' + cmd);
  1660.     }
  1661. };
  1662.  
  1663. eote.process.setup = function (cmd, playerName, playerID, msg) {
  1664.  
  1665.     let selectedTokens = (msg.selected) ? msg.selected : null;
  1666.  
  1667.     if (!cmd.match(eote.defaults.regex.cmd)) { //check for api cmd !eed
  1668.         return false;
  1669.     }
  1670.     var debugMatch = cmd.match(eote.defaults.regex.debug);
  1671.     if (debugMatch) {
  1672.         eote.process.debug(debugMatch);
  1673.         return false;
  1674.     }
  1675.     var fearMatch = cmd.match(eote.defaults.regex.fear);
  1676.     if (fearMatch) {
  1677.         eote.process.fear(fearMatch);
  1678.         return false;
  1679.     }
  1680.  
  1681.     var suggestionDisplayMatch = cmd.match(eote.defaults.regex.suggestionDisplay);
  1682.     if (suggestionDisplayMatch) {
  1683.         eote.process.suggestionDisplay(suggestionDisplayMatch);
  1684.         return false;
  1685.     }
  1686.  
  1687.     eote.process.logger("eote.process.setup", "NEW ROLL");
  1688.     eote.process.logger("eote.process.setup", "Original Command: " + cmd);
  1689.  
  1690.     /* reset dice - test, might not need this */
  1691.     var diceObj = new eote.defaults.dice();
  1692.     diceObj.vars.playerName = playerName;
  1693.     diceObj.vars.playerID = playerID;
  1694.  
  1695.     /* Dice config
  1696.      * Description: Change dice roller default config
  1697.      * --------------------------------------------------------------*/
  1698.     var logMatch = cmd.match(eote.defaults.regex.log);
  1699.  
  1700.     if (logMatch) {
  1701.         eote.process.log(logMatch);
  1702.         return false; //Stop current roll and run test
  1703.     }
  1704.     var graphicsMatch = cmd.match(eote.defaults.regex.graphics);
  1705.  
  1706.     if (graphicsMatch) {
  1707.         eote.process.graphics(graphicsMatch);
  1708.         return false; //Stop current roll and run test
  1709.     }
  1710.     var testMatch = cmd.match(eote.defaults.regex.test);
  1711.  
  1712.     if (testMatch) {
  1713.         eote.process.test(testMatch);
  1714.         return false; //Stop current roll and run test
  1715.     }
  1716.     /* Roll information
  1717.      * Description: Set default dice roll information Character Name and Skill Label
  1718.      * --------------------------------------------------------------*/
  1719.  
  1720.     var rollPlayerMatch = cmd.match(eote.defaults.regex.rollPlayer);
  1721.  
  1722.     if (rollPlayerMatch) {
  1723.         diceObj = eote.process.rollPlayer(rollPlayerMatch, diceObj);
  1724.  
  1725.         if (!diceObj) {
  1726.             return false;
  1727.         }
  1728.     }
  1729.     var characterIDMatch = cmd.match(eote.defaults.regex.characterID);
  1730.  
  1731.     if (characterIDMatch) {
  1732.         diceObj = eote.process.characterID(characterIDMatch, diceObj);
  1733.         //Once Character ID is parsed, remove it from the cmd.
  1734.         //it is possible that the character ID could contain dice values
  1735.         //for ex. characterID(-JMBFmYX1i0L259bjb-X)  will add 59 blue dice to the pool
  1736.         cmd = cmd.replace(characterIDMatch[0], '');
  1737.         eote.process.logger("eote.process.setup.characterIDMatch", "New command: " + cmd);
  1738.     }
  1739.     var unusableMatch = cmd.match(eote.defaults.regex.unusable);
  1740.  
  1741.     if (unusableMatch) {
  1742.         eote.process.logger("eote.process.setup.unusableMatch", "Roll ended because of unusable weapon");
  1743.         sendChat(diceObj.vars.characterName, "&{template:base} {{title=" + diceObj.vars.characterName + "}} {{wide=Weapon is too damaged to be used. Try repairing it.}}");
  1744.         return false;
  1745.     }
  1746.     var labelMatch = cmd.match(eote.defaults.regex.label);
  1747.  
  1748.     if (labelMatch) {
  1749.         diceObj = eote.process.label(labelMatch, diceObj);
  1750.     }
  1751.     /* Dice rolls
  1752.      * Description: Create dice pool before running any custom roll
  1753.      * script commands that may need dice evaluated.
  1754.      * --------------------------------------------------------------*/
  1755.     var gmdiceMatch = cmd.match(eote.defaults.regex.gmdice);
  1756.  
  1757.     if (gmdiceMatch) {
  1758.         cmd = eote.process.gmdice(cmd); // update the cmd string to contain the gmdice
  1759.         eote.process.logger("eote.process.setup.gmDice", "New command: " + cmd);
  1760.     }
  1761.     var encumMatch = cmd.match(eote.defaults.regex.encum);
  1762.  
  1763.     if (encumMatch) {
  1764.         diceObj = eote.process.encum(encumMatch, diceObj);
  1765.         //eote.process.logger("eote.process.setup.encumMatch","New dice:" + diceObj);
  1766.     }
  1767.  
  1768.     var combatMatch = cmd.match(eote.defaults.regex.combat);
  1769.     if (combatMatch) {
  1770.         suggestionEngine.setCombatType(cmd[1]);
  1771.     } else {
  1772.         suggestionEngine.setCombatType(null);
  1773.     }
  1774.  
  1775.     var skillMatch = cmd.match(eote.defaults.regex.skill);
  1776.     if (skillMatch) {
  1777.         suggestionEngine.setIsFearCheck(getAttrByName(GMSheet.obj.id, "skill_suggestion_setting_fear"));
  1778.         var CombatSuggestions = getAttrByName(GMSheet.obj.id, "skill_suggestion_setting_combat");
  1779.         log("CombatSuggestions="+CombatSuggestions);
  1780.         suggestionEngine.setCombatSuggestions(getAttrByName(GMSheet.obj.id, "skill_suggestion_setting_combat"));
  1781.         var generalSuggestions = getAttrByName(GMSheet.obj.id, "skill_suggestion_setting_general");
  1782.         log("generalSuggestions="+generalSuggestions);
  1783.         suggestionEngine.setGeneralSuggestions(generalSuggestions);
  1784.         suggestionEngine.setIsFearCheck(getAttrByName(GMSheet.obj.id, "skill_suggestion_setting_fear"));
  1785.  
  1786.         suggestionEngine.setDisplayOption(getAttrByName(GMSheet.obj.id, "skill_suggestion_setting_display"));
  1787.         diceObj = eote.process.skill(skillMatch, diceObj);
  1788.     }
  1789.  
  1790.     var opposedMatch = cmd.match(eote.defaults.regex.opposed);
  1791.     if (opposedMatch) {
  1792.         diceObj = eote.process.opposed(opposedMatch, diceObj);
  1793.     }
  1794.  
  1795.     var diceMatch = cmd.match(eote.defaults.regex.dice);
  1796.     if (diceMatch) {
  1797.         diceObj = eote.process.setDice(diceMatch, diceObj);
  1798.     }
  1799.  
  1800.     var upgradeMatch = cmd.match(eote.defaults.regex.upgrade);
  1801.     if (upgradeMatch) {
  1802.         diceObj = eote.process.upgrade(upgradeMatch, diceObj);
  1803.     }
  1804.  
  1805.     var downgradeMatch = cmd.match(eote.defaults.regex.downgrade);
  1806.     if (downgradeMatch) {
  1807.         diceObj = eote.process.downgrade(downgradeMatch, diceObj);
  1808.     }
  1809.  
  1810.     /* Roll dice and update success / fail
  1811.      * ------------------------------------------------------------- */
  1812.     diceObj = eote.process.rollDice(diceObj);
  1813.  
  1814.     // process and display skill suggestions
  1815.     if (diceObj.vars.skillName != null || suggestionEngine.getCombatType() != null) {
  1816.         diceObj = suggestionEngine.processSuggestions(diceObj);
  1817.     }
  1818.  
  1819.     /* Custom rolls
  1820.      * Description: Custom dice components have their own message, results and
  1821.      * often will return false to not allow proceeding scripts to fire
  1822.      * --------------------------------------------------------------*/
  1823.     var resetdiceMatch = cmd.match(eote.defaults.regex.resetdice);
  1824.  
  1825.     if (resetdiceMatch) {
  1826.         eote.process.resetdice(resetdiceMatch, diceObj);
  1827.         return false;
  1828.     }
  1829.     var initiativeMatch = cmd.match(eote.defaults.regex.initiative);
  1830.  
  1831.     if (initiativeMatch) {
  1832.         eote.process.initiative(initiativeMatch, diceObj, selectedTokens);
  1833.         //return false;
  1834.     }
  1835.     var destinyMatch = cmd.match(eote.defaults.regex.destiny);
  1836.  
  1837.     if (destinyMatch) {
  1838.         eote.process.logger("eote.process.setup.destiny", "Destiny Point Command");
  1839.         var doRoll = eote.process.destiny(destinyMatch, diceObj);
  1840.         if (!doRoll) {
  1841.             return false;
  1842.         }
  1843.     }
  1844.     var critMatch = cmd.match(eote.defaults.regex.crit);
  1845.  
  1846.     if (critMatch) {
  1847.         eote.process.crit(critMatch, diceObj);
  1848.         return false;
  1849.     }
  1850.     var critShipMatch = cmd.match(eote.defaults.regex.critShip);
  1851.  
  1852.     if (critShipMatch) {
  1853.         eote.process.crit(critShipMatch, diceObj);
  1854.         return false;
  1855.     }
  1856.  
  1857.     /* Display dice output in chat window
  1858.      * ------------------------------------------------------------- */
  1859.     eote.process.diceOutput(diceObj, playerName, playerID);
  1860. };
  1861.  
  1862. /* DICE PROCESS FUNCTION
  1863.  *
  1864.  * ---------------------------------------------------------------- */
  1865.  
  1866.  
  1867.  
  1868. eote.process.log = function (cmd) {
  1869.  
  1870.     /* Log
  1871.      * default: 'on' and 'single'
  1872.      * Description: Sets the visual output in the chat window for the dice rolls
  1873.      * Command: !eed log on|off|multi|single
  1874.      * ---------------------------------------------------------------- */
  1875.  
  1876.      switch (cmd[1]) {
  1877.         case "on": //if 'on' outputs dice to chat window
  1878.             eote.defaults.globalVars.diceLogChat = true;
  1879.             sendChat("Dice System", 'Output rolled dice to chat window "On"');
  1880.             break;
  1881.         case "off": //if 'off' outputs only results to chat window
  1882.             eote.defaults.globalVars.diceLogChat = false;
  1883.             sendChat("Dice System", 'Output rolled dice to chat window "Off"');
  1884.             break;
  1885.         case "multi": //if 'multi' multiple sets dice per line
  1886.             eote.defaults.globalVars.diceLogRolledOnOneLine = false;
  1887.             sendChat("Dice System", 'Multiple line output "Off". NOTE: This setting can cause issues with the Roll Templates. Recommended setting is !eed log single');
  1888.             break;
  1889.         case "single": //if 'single' single set of dice per line
  1890.             eote.defaults.globalVars.diceLogRolledOnOneLine = true;
  1891.             sendChat("Dice System", 'Multiple line output "On"');
  1892.             break;
  1893.     }
  1894. };
  1895.  
  1896. eote.process.debug = function (cmd) {
  1897.     switch (cmd[1]) {
  1898.         case "on":
  1899.             eote.defaults.globalVars.debugScript = true;
  1900.             sendChat("Dice System", 'Debug Script "On"');
  1901.             break;
  1902.         case "off":
  1903.             eote.defaults.globalVars.debugScript = false;
  1904.             sendChat("Dice System", 'Debug Script "Off"');
  1905.             break;
  1906.     }
  1907. };
  1908.  
  1909. eote.process.fear = function (cmd) {
  1910.  
  1911.     /* Fear
  1912.      * Description: Sets the state of the Fear check status on the DicePool
  1913.      * Command: !eed fear on|off
  1914.      * ---------------------------------------------------------------- */
  1915.  
  1916.     var value = null;
  1917.     switch (cmd[1]) {
  1918.         case "off":
  1919.             value = 0;
  1920.             break;
  1921.         case "on":
  1922.             value = 1;
  1923.             break;
  1924.     }
  1925.  
  1926.     if (value != null) {
  1927.         eote.updateAddAttribute(GMSheet.obj, {
  1928.             name: "skill_suggestion_setting_fear",
  1929.             current: value,
  1930.             update: true
  1931.         });
  1932.     }
  1933. };
  1934.  
  1935. eote.process.suggestionDisplay = function (cmd) {
  1936.  
  1937.     /* SuggestionDisplay
  1938.      * Description: Sets the state of the skill_suggestion_setting_display check status on the DicePool
  1939.      * Command: !eed suggestionDisplay none|whisper|always
  1940.      * ---------------------------------------------------------------- */
  1941.  
  1942.     /*TODO fix why suggestionDisplay is no longer working*/
  1943.     var value = (suggestionEngine.enum.displayOptions.hasOwnProperty(cmd[1]) ? cmd[1] : null);
  1944.  
  1945.     if (value != null) {
  1946.         eote.updateAddAttribute(GMSheet.obj, {
  1947.             name: "skill_suggestion_setting_display",
  1948.             current: value,
  1949.             update: true
  1950.         });
  1951.     } else {
  1952.         sendChat("Error", "/w gm " + cmd[1] + " is not a valid argument for suggestionDisplay.");
  1953.     }
  1954. };
  1955.  
  1956. eote.process.graphics = function (cmd) {
  1957.  
  1958.     /* Graphics
  1959.      * default: 'on' and 'm'
  1960.      * Description: Sets chat window dice output as graphic, small, medium, or large if "on" or as text if "off"
  1961.      * Command: !eed graphics on|off|s|m|l
  1962.      * ---------------------------------------------------------------- */
  1963.  
  1964.     //log(cmd[1]);
  1965.     switch (cmd[1]) {
  1966.         case "on":
  1967.             eote.defaults.globalVars.diceGraphicsChat = true;
  1968.             sendChat("Dice System", 'Chat graphics "On"');
  1969.             break;
  1970.         case "off":
  1971.             eote.defaults.globalVars.diceGraphicsChat = false;
  1972.             sendChat("Dice System", 'Chat graphics "Off"');
  1973.             break;
  1974.         case "s":
  1975.             eote.defaults.globalVars.diceGraphicsChatSize = eote.defaults.graphics.SIZE.SMALL;
  1976.             sendChat("Dice System", 'Chat graphics size "Small"');
  1977.             break;
  1978.         case "m":
  1979.             eote.defaults.globalVars.diceGraphicsChatSize = eote.defaults.graphics.SIZE.MEDIUM;
  1980.             sendChat("Dice System", 'Chat graphics size "Medium"');
  1981.             break;
  1982.         case "l":
  1983.             eote.defaults.globalVars.diceGraphicsChatSize = eote.defaults.graphics.SIZE.LARGE;
  1984.             sendChat("Dice System", 'Chat graphics size "Large"');
  1985.             break;
  1986.     }
  1987. };
  1988.  
  1989. eote.process.test = function (cmd) {
  1990.  
  1991.     eote.process.logger("eote.process.test", cmd);
  1992.  
  1993.     //Set test vars to true
  1994.     eote.defaults.globalVars.diceTestEnabled = true;
  1995.     tmpLogChat = eote.defaults.globalVars.diceLogChat;
  1996.     tmpGraphicsChat = eote.defaults.globalVars.diceGraphicsChat;
  1997.     eote.defaults.globalVars.diceLogChat = true;
  1998.     eote.defaults.globalVars.diceGraphicsChat = true;
  1999.  
  2000.     //Roll dice
  2001.     eote.process.setup('!eed 1b 1g 1y 1blk 1p 1r 1w', 'GM', 'Dice Test');
  2002.  
  2003.     //After test reset vars back
  2004.     eote.defaults.globalVars.diceTestEnabled = false;
  2005.     eote.defaults.globalVars.diceLogChat = tmpLogChat;
  2006.     eote.defaults.globalVars.diceGraphicsChat = tmpGraphicsChat;
  2007. };
  2008.  
  2009. eote.process.rollPlayer = function (cmd, diceObj) {
  2010.     //Build cmd string
  2011.     //get characterID
  2012.     //get skills
  2013.     //get encum
  2014.     //remove rollPlayer(xxxx) from string
  2015.     var match = {
  2016.         skill: /skill:(.*?)[\|\)]/,
  2017.         encum: /encum/,
  2018.         character: /character:(.*?)[\|\)]/
  2019.     };
  2020.     var characterMatch = cmd[1].match(match.character);
  2021.  
  2022.     var companion = null;
  2023.     var character = null;
  2024.     if (characterMatch) {
  2025.         var charObj = findObjs({ _type: "character", name: characterMatch[1] });
  2026.  
  2027.         if (charObj.length > 0) {
  2028.             diceObj.vars.characterName = charObj[0].get('name');
  2029.             diceObj.vars.characterID = charObj[0].id;
  2030.         }
  2031.         else {
  2032.             sendChat("Alert", "Can't find character. Please update character, or npc, name field to match sheet character name and try again.");
  2033.             return false;
  2034.         }
  2035.     }
  2036.     else {
  2037.         sendChat("Alert", "Please update character, or npc, name field.");
  2038.         return false;
  2039.     }
  2040.     var encumMatch = cmd[1].match(match.encum);
  2041.     var attr_1 = null;
  2042.     var attr_2 = null;
  2043.     if (encumMatch) {
  2044.         //encumbrance
  2045.         attr_1 = getAttrByName(diceObj.vars.characterID, 'encumbrance', 'max');
  2046.         attr_2 = getAttrByName(diceObj.vars.characterID, 'encumbrance');
  2047.         var cmdEncum = ['encum(' + attr_1 + '|' + attr_2 + ')']; //["encum(3|5)"]
  2048.  
  2049.         diceObj = eote.process.encum(cmdEncum, diceObj);
  2050.     }
  2051.     var skillMatch = cmd[1].match(match.skill);
  2052.     if (eote.defaults.globalVars.debugScript) sendChat("Alert", "skillmatch=" + skillMatch.toString());
  2053.  
  2054.     if (skillMatch) {
  2055.  
  2056.         var attrArray = skillMatch[1].split(',');
  2057.         attr_1 = getAttrByName(diceObj.vars.characterID, attrArray[0]);
  2058.         attr_2 = getAttrByName(diceObj.vars.characterID, attrArray[1]);
  2059.  
  2060.         if (eote.defaults.globalVars.debugScript) {
  2061.             sendChat("Alert", "attr_1 = " + attr_1);
  2062.             sendChat("Alert", "attr_2 = " + attr_2);
  2063.         }
  2064.  
  2065.         var cmdSkill;
  2066.         if(!isNaN((parseFloat(attr_1)) && isFinite(attr_1))) { // is numeric
  2067.             cmdSkill = ['skill(' + attr_1 + '|' + attr_2 + ')']; //['skill(0|2)']
  2068.         } else {
  2069.             var attr_3 =  getAttrByName(diceObj.vars.characterID, attr_1.substr(2,attr_1.length-3));
  2070.             cmdSkill = ['skill(' + attr_3 + '|' + attr_2 + ')']; //['skill(0|2)']
  2071.         }
  2072.  
  2073.         diceObj = eote.process.skill(cmdSkill, diceObj);
  2074.     }
  2075.     return diceObj;
  2076. };
  2077.  
  2078. eote.process.destiny = function (cmd, diceObj) {
  2079.  
  2080.     var charObj_DicePool = findObjs({ _type: "character", name: "-DicePool" })[0];
  2081.     var doRoll = false;
  2082.  
  2083.     if (!charObj_DicePool) {
  2084.         sendChat("GM", "/w " + "gm The DicePool character sheet could not be found! Re-save this script and it should be recreated. In the future do not rename the -DicePool Character Sheet.");
  2085.         return doRoll;
  2086.     }
  2087.     //GM's Destiny Point Pool
  2088.     var currentLightSidePoints = findObjs({
  2089.         _characterid: charObj_DicePool.get("_id"),
  2090.         _type: "attribute",
  2091.         _name: "lightSidePoints"
  2092.     });
  2093.     var currentDarkSidePoints = findObjs({
  2094.         _characterid: charObj_DicePool.get("_id"),
  2095.         _type: "attribute",
  2096.         _name: "darkSidePoints"
  2097.     });
  2098.     if (!currentDarkSidePoints[0] || !currentLightSidePoints[0]) {
  2099.         sendChat("Dice System", "No Destiny Points Defined. The GM has been whispered with instructions to reset the Destiny Pool.");
  2100.         sendChat("GM", "/w " + "gm The Destiny Pool system needs to be (or has been) reset. To fix this functionality, go to the -DicePool Character Sheet and add 1 dark side and 1 light side destiny point, then click the Force Player Update button. This should clear up the issue.");
  2101.         return doRoll;
  2102.     }
  2103.     var darkSide = parseInt(currentDarkSidePoints[0].get("current"));
  2104.     var lightSide = parseInt(currentLightSidePoints[0].get("current"));
  2105.  
  2106.     var displayPool = '';
  2107.     //noinspection FallThroughInSwitchStatementJS
  2108.     switch (cmd[1]) {
  2109.         case "useDark":
  2110.             if (darkSide > 0) {
  2111.                 darkSide = darkSide - 1;
  2112.                 lightSide = lightSide + 1;
  2113.  
  2114.                 displayPool = '/direct &{template:base} {{title=' + 'The GM flips a Dark Side Destiny Point' + '}}';
  2115.                 displayPool = displayPool + '{{Dark Side points remaining=' + darkSide + '}}';
  2116.                 displayPool = displayPool + '{{New Light Side total=' + lightSide + '}}';
  2117.  
  2118.                 sendChat('Dice System', displayPool);
  2119.             }
  2120.             else {
  2121.                 sendChat("GM", "/w " + "gm There are no Dark Side points left in the Destiny Pool. Encourage your Players to use a Light Side Point." );
  2122.                 return doRoll;
  2123.             }
  2124.             break;
  2125.         case "useLight":
  2126.             if (lightSide > 0) {
  2127.                 lightSide = lightSide - 1;
  2128.                 darkSide = darkSide + 1;
  2129.  
  2130.                 displayPool = '/direct &{template:base} {{title=' + diceObj.vars.characterName + ' flips a Light Side Destiny Point' + '}}';
  2131.                 displayPool = displayPool + '{{New Dark Side total=' + darkSide + '}}';
  2132.                 displayPool = displayPool + '{{Light Side points remaining=' + lightSide + '}}';
  2133.  
  2134.                 sendChat('Dice System', displayPool);
  2135.             }
  2136.             else {
  2137.                 sendChat("Dice System", "/w " + diceObj.vars.characterName + " There are no Light Side points left in the Destiny Pool. Suggest to your GM to use a Dark Side point to make one available.");
  2138.                 return doRoll;
  2139.             }
  2140.             break;
  2141.         case "doRoll":
  2142.             sendChat(diceObj.vars.characterName, '/direct Rolling a Destiny Point.');
  2143.             doRoll = true;
  2144.         // falls through on purpose (I think) to sync automatically when destiny point is rolled
  2145.         case "registerPlayer":
  2146.             if (!doRoll) {
  2147.                 sendChat("Dice System", "/w " + diceObj.vars.characterName + '&{template:base} {{title=Syncing your Destiny Pool to the GM\'s}}')
  2148.             }
  2149.             darkSide = darkSide + diceObj.totals.dark;
  2150.             lightSide = lightSide + diceObj.totals.light;
  2151.  
  2152.             //Register
  2153.             if (eote.defaults.destinyListeners.indexOf(diceObj.vars.characterID) == -1) {
  2154.                 eote.defaults.destinyListeners.push(diceObj.vars.characterID);
  2155.             }
  2156.             break;
  2157.         case "sendUpdate":
  2158.             sendChat("Dice System", "Updating Players Destiny Pools");
  2159.             break;
  2160.         case "clearPool":
  2161.             sendChat("Dice System", '&{template:base} {{title=The GM cleared the Destiny Pool}}');
  2162.             lightSide = 0;
  2163.             darkSide = 0;
  2164.             break;
  2165.     }
  2166.     var newDestPool = [
  2167.         {
  2168.             name: 'lightSidePoints',
  2169.             current: lightSide,
  2170.             max: '',
  2171.             update: true
  2172.         },
  2173.         {
  2174.             name: 'darkSidePoints',
  2175.             current: darkSide,
  2176.             max: '',
  2177.             update: true
  2178.         }
  2179.     ];
  2180.     eote.updateListeners(newDestPool);
  2181.     return doRoll;
  2182. };
  2183.  
  2184. eote.process.characterID = function (cmd, diceObj) {
  2185.  
  2186.     /* CharacterId
  2187.      * default: null
  2188.      * Description: looks up the characters name based on character ID
  2189.      * Command: !eed characterID(##########)
  2190.      * ---------------------------------------------------------------- */
  2191.  
  2192.     eote.process.logger("eote.process.characterID", cmd);
  2193.  
  2194.     var characterID = cmd[1];
  2195.  
  2196.     if (characterID) {
  2197.  
  2198.         diceObj.vars.characterName = getObj("character", characterID).get('name');
  2199.         diceObj.vars.characterID = characterID;
  2200.     }
  2201.     return diceObj;
  2202. };
  2203.  
  2204. eote.process.label = function (cmd, diceObj) {
  2205.  
  2206.     /* Label
  2207.      * default: null
  2208.      * Description: set the skill name of the roll
  2209.      * Command: !eed label(Name of Skill)
  2210.      * ---------------------------------------------------------------- */
  2211.     //log(cmd);
  2212.  
  2213.     var label = cmd[1];
  2214.  
  2215.     if (label) {
  2216.  
  2217.         var labelStr = '';
  2218.         var labelArray = label.split('|');
  2219.  
  2220.         _.each(labelArray, function (labelVal) {
  2221.             var labelArray = labelVal.split(':');
  2222.             var label = labelArray[0];
  2223.             var message = labelArray[1];
  2224.             var labelTest = label.toLowerCase();
  2225.  
  2226.             switch (labelTest) {
  2227.                 case 'skill':
  2228.                     labelStr = '{{title='+labelStr + message + '}}';
  2229.                     break;
  2230.                 case 'dice':
  2231.                     labelStr = '{{title='+labelStr + message + '}}';
  2232.                     break;
  2233.                 case 'weapon':
  2234.                     labelStr = '{{title='+labelStr + message + '}}';
  2235.                     break;
  2236.                 default:
  2237.                     labelStr = labelStr + '{{' + label + '=' + message + '}}';
  2238.             }
  2239.  
  2240.         });
  2241.         diceObj.vars.label = labelStr;
  2242.     }
  2243.     return diceObj;
  2244. };
  2245.  
  2246. eote.process.resetdice = function (cmd, diceObj) {
  2247.  
  2248.     var characterObj = [{ name: diceObj.vars.characterName, id: diceObj.vars.characterID }];
  2249.     eote.process.logger("eote.process.resetdice", cmd);
  2250.     var resetdice = [];
  2251.  
  2252.     if (cmd[1] == 'resetdice') {
  2253.         resetdice = [
  2254.             {
  2255.                 name: "b",
  2256.                 current: 0,
  2257.                 update: true
  2258.             },
  2259.             {
  2260.                 name: "g",
  2261.                 current: 0,
  2262.                 update: true
  2263.             },
  2264.             {
  2265.                 name: "y",
  2266.                 current: 0,
  2267.                 update: true
  2268.             },
  2269.             {
  2270.                 name: "blk",
  2271.                 current: 0,
  2272.                 update: true
  2273.             },
  2274.             {
  2275.                 name: "r",
  2276.                 current: 0,
  2277.                 update: true
  2278.             },
  2279.             {
  2280.                 name: "p",
  2281.                 current: 0,
  2282.                 update: true
  2283.             },
  2284.             {
  2285.                 name: "w",
  2286.                 current: 0,
  2287.                 update: true
  2288.             },
  2289.             {
  2290.                 name: "upgradeAbility",
  2291.                 current: 0,
  2292.                 update: true
  2293.             },
  2294.             {
  2295.                 name: "downgradeProficiency",
  2296.                 current: 0,
  2297.                 update: true
  2298.             },
  2299.             {
  2300.                 name: "upgradeDifficulty",
  2301.                 current: 0,
  2302.                 update: true
  2303.             },
  2304.             {
  2305.                 name: "downgradeChallenge",
  2306.                 current: 0,
  2307.                 update: true
  2308.             }
  2309.         ]
  2310.     }
  2311.  
  2312.     if (cmd[1] == 'resetgmdice') {
  2313.         resetdice = [
  2314.             {
  2315.                 name: "bgm",
  2316.                 current: 0,
  2317.                 update: true
  2318.             },
  2319.             {
  2320.                 name: "ggm",
  2321.                 current: 0,
  2322.                 update: true
  2323.             },
  2324.             {
  2325.                 name: "ygm",
  2326.                 current: 0,
  2327.                 update: true
  2328.             },
  2329.             {
  2330.                 name: "blkgm",
  2331.                 current: 0,
  2332.                 update: true
  2333.             },
  2334.             {
  2335.                 name: "rgm",
  2336.                 current: 0,
  2337.                 update: true
  2338.             },
  2339.             {
  2340.                 name: "pgm",
  2341.                 current: 0,
  2342.                 update: true
  2343.             },
  2344.             {
  2345.                 name: "wgm",
  2346.                 current: 0,
  2347.                 update: true
  2348.             },
  2349.             {
  2350.                 name: "upgradeAbilitygm",
  2351.                 current: 0,
  2352.                 update: true
  2353.             },
  2354.             {
  2355.                 name: "downgradeProficiencygm",
  2356.                 current: 0,
  2357.                 update: true
  2358.             },
  2359.             {
  2360.                 name: "upgradeDifficultygm",
  2361.                 current: 0,
  2362.                 update: true
  2363.             },
  2364.             {
  2365.                 name: "downgradeChallengegm",
  2366.                 current: 0,
  2367.                 update: true
  2368.             }
  2369.         ]
  2370.     }
  2371.     eote.updateAddAttribute(characterObj, resetdice);
  2372. };
  2373.  
  2374. eote.process.initiative = function (cmd, diceObj, selectedTokens) {
  2375.  
  2376.     /* initiative
  2377.      * default: false
  2378.      * Description: Set NPC/PC initiative true
  2379.      * Command: !eed npcinit or pcinit
  2380.      * ---------------------------------------------------------------- */
  2381.  
  2382.     var type = '';
  2383.     var NumSuccess = diceObj.totals.success;
  2384.     var NumAdvantage = diceObj.totals.advantage;
  2385.     var turnorder;
  2386.  
  2387.     eote.process.logger("eote.process.initiative.diceObj", diceObj);
  2388.     eote.process.logger("eote.process.initiative.NumSuccess", NumSuccess);
  2389.     eote.process.logger("eote.process.initiativeNumAdvantage", NumAdvantage);
  2390.  
  2391.     if (Campaign().get("turnorder") == "") turnorder = []; //NOTE: We check to make sure that the turnorder isn't just an empty string first. If it is treat it like an empty array.
  2392.     else turnorder = JSON.parse(Campaign().get("turnorder"));
  2393.  
  2394.     if (cmd[0] == 'pcinit') {
  2395.         type = 'PC';
  2396.     }
  2397.  
  2398.     if (cmd[0] == 'npcinit') {
  2399.         type = 'NPC';
  2400.     }
  2401.     /* === CUSTOM INITIATIVE EDITS === */
  2402.     let selectedTok = selectedTokens ? selectedTokens[0] : null;
  2403.     log(`Selection: ${selectedTokens}`);
  2404.     let token = (selectedTok) ? getObj('graphic', selectedTok._id) : null;
  2405.     let initName = (token) ? token.get('name') : (diceObj.vars.characterName) ? diceObj.vars.characterName : type;
  2406.     let initId = (token) ? token.id : '-1';
  2407.  
  2408.     //Add a new custom entry to the end of the turn order.
  2409.     turnorder.push({
  2410.         id: initId,
  2411.         pr: NumSuccess + ":" + NumAdvantage,
  2412.         custom: initName
  2413.     });
  2414.     /* === END OF EDITS === */
  2415.     turnorder.sort(function (x, y) {
  2416.         // verify that x or y contains a colon, if it doesn't put it below
  2417.         if (x.toString().indexOf(":") < 1 || y.toString().indexOf(":") < 1) {
  2418.             return 1;
  2419.         } else {
  2420.             var a = x.pr.split(":");
  2421.             var b = y.pr.split(":");
  2422.  
  2423.             if (b[0] - a[0] != 0) {//First rank on successes
  2424.                 return b[0] - a[0];
  2425.             } else if (b[1] - a[1] != 0) {//Then rank on Advantage
  2426.                 return b[1] - a[1];
  2427.             } else { //If they are still tied, PC goes first
  2428.  
  2429.                 if (x.custom == y.custom) {
  2430.                     return 0;
  2431.                 } else if (x.custom == "NPC") {
  2432.                     return 1;
  2433.                 } else {
  2434.                     return -1;
  2435.                 }
  2436.             }
  2437.         }
  2438.     });
  2439.     Campaign().set("turnorder", JSON.stringify(turnorder));
  2440. };
  2441.  
  2442. eote.process.crit = function (cmd, diceObj) {
  2443.  
  2444.     /* Crit
  2445.      * default:
  2446.      * Description: Rolls critical injury table
  2447.      * Command: !eed crit(roll) crit(roll|#) crit(heal|#)
  2448.      * ---------------------------------------------------------------- */
  2449.  
  2450.     eote.process.logger("eote.process.crit", "");
  2451.  
  2452.     var characterObj = [{ name: diceObj.vars.characterName, id: diceObj.vars.characterID }];
  2453.     var critTableLifeform = [
  2454.         {
  2455.             percent: '1 to 5',
  2456.             severity: 1,
  2457.             name: 'Minor Nick',
  2458.             Result: 'Suffer 1 strain.'
  2459.         },
  2460.         {
  2461.             percent: '6 to 10',
  2462.             severity: 1,
  2463.             name: 'Slowed Down',
  2464.             Result: 'May only act during last allied Initiative slot on next turn.'
  2465.         },
  2466.         {
  2467.             percent: '11 to 15',
  2468.             severity: 1,
  2469.             name: 'Sudden Jolt',
  2470.             Result: 'May only act during last hero Initiative slot on next turn.'
  2471.         },
  2472.         {
  2473.             percent: '16 to 20',
  2474.             severity: 1,
  2475.             name: 'Distracted',
  2476.             Result: 'Cannot perform free maneuver on next turn.'
  2477.         },
  2478.         {
  2479.             percent: '21 to 25',
  2480.             severity: 1,
  2481.             name: 'Off-Balance',
  2482.             Result: 'Add 1 Setback die to next skill check.'
  2483.         },
  2484.         {
  2485.             percent: '26 to 30',
  2486.             severity: 1,
  2487.             name: 'Discouraging Wound',
  2488.             Result: 'Flip one light destiny to dark.'
  2489.         },
  2490.         {
  2491.             percent: '31 to 35',
  2492.             severity: 1,
  2493.             name: 'Stunned',
  2494.             Result: 'Staggered, cannot perform action on next turn.'
  2495.         },
  2496.         {
  2497.             percent: '36 to 40',
  2498.             severity: 1,
  2499.             name: 'Stinger',
  2500.             Result: 'Increase difficulty of next check by 1 Difficulty die.'
  2501.         },
  2502.         //----------------------------- Severity 2
  2503.         {
  2504.             percent: '41 to 45',
  2505.             severity: 2,
  2506.             name: 'Bowled Over',
  2507.             Result: 'Knocked prone and suffer 1 strain.'
  2508.         },
  2509.         {
  2510.             percent: '46 to 50',
  2511.             severity: 2,
  2512.             name: 'Head Ringer',
  2513.             Result: 'Increase difficulty of all Intellect and Cunning checks by 1 Difficulty die until end of encounter.'
  2514.         },
  2515.         {
  2516.             percent: '51 to 55',
  2517.             severity: 2,
  2518.             name: 'Fearsome Wound',
  2519.             Result: 'Increase difficulty of all Presence and Willpower checks by 1 Difficulty die until end of encounter.'
  2520.         },
  2521.         {
  2522.             percent: '56 to 60',
  2523.             severity: 2,
  2524.             name: 'Agonizing Wound',
  2525.             Result: 'Increase difficulty of all Brawn and Agility checks by 1 Difficulty die until end of encounter.'
  2526.         },
  2527.         {
  2528.             percent: '61 to 65',
  2529.             severity: 2,
  2530.             name: 'Slightly Dazed',
  2531.             Result: 'Add 1 Setback die to all skill checks until end of encounter.'
  2532.         },
  2533.         {
  2534.             percent: '66 to 70',
  2535.             severity: 2,
  2536.             name: 'Scattered Senses',
  2537.             Result: 'Remove all Boost dice from all skill checks until end of encounter.'
  2538.         },
  2539.         {
  2540.             percent: '71 to 75',
  2541.             severity: 2,
  2542.             name: 'Hamstrung',
  2543.             Result: 'Lose free maneuver until end of encounter.'
  2544.         },
  2545.         {
  2546.             percent: '76 to 80',
  2547.             severity: 2,
  2548.             name: 'Staggered',
  2549.             Result: 'Attacker may immediately attempt another free attack against you using same dice pool as original attack.'
  2550.         },
  2551.         {
  2552.             percent: '81 to 85',
  2553.             severity: 2,
  2554.             name: 'Winded',
  2555.             Result: 'Cannot voluntarily suffer strain to activate abilities or gain additional maneuvers until end of encounter.'
  2556.         },
  2557.         {
  2558.             percent: '86 to 90',
  2559.             severity: 2,
  2560.             name: 'Compromised',
  2561.             Result: 'Increase difficulty of all skill checks by 1 Difficulty die until end of encounter.'
  2562.         },
  2563.         //---------------------------------------- Severity 3
  2564.         {
  2565.             percent: '91 to 95',
  2566.             severity: 3,
  2567.             name: 'At the Brink',
  2568.             Result: 'Suffer 1 strain each time you perform an action.'
  2569.         },
  2570.         {
  2571.             percent: '96 to 100',
  2572.             severity: 3,
  2573.             name: 'Crippled',
  2574.             Result: 'Limb crippled until healed or replaced. Increase difficulty of all checks that use that limb by 1 Difficulty die.'
  2575.         },
  2576.         {
  2577.             percent: '101 to 105',
  2578.             severity: 3,
  2579.             name: 'Maimed',
  2580.             Result: 'Limb permanently lost. Unless you have a cybernetic replacement, cannot perform actions that use that limb. Add 1 Setback to all other actions.'
  2581.         },
  2582.         {
  2583.             percent: '106 to 110',
  2584.             severity: 3,
  2585.             name: 'Horrific Injury',
  2586.             Result: 'Roll 1d10 to determine one wounded characteristic -- roll results(1-3 = Brawn, 4-6 = Agility, 7 = Intellect, 8 = Cunning, 9 = Presence, 10 = Willpower. Until Healed, treat characteristic as one point lower.'
  2587.         },
  2588.         {
  2589.             percent: '111 to 115',
  2590.             severity: 3,
  2591.             name: 'Temporarily Lame',
  2592.             Result: 'Until healed, may not perform more than one maneuver each turn.'
  2593.         },
  2594.         {
  2595.             percent: '116 to 120',
  2596.             severity: 3,
  2597.             name: 'Blinded',
  2598.             Result: 'Can no longer see. Upgrade the difficulty of Perception and Vigilance checks three times, and all other checks twice.'
  2599.         },
  2600.         {
  2601.             percent: '121 to 125',
  2602.             severity: 3,
  2603.             name: 'Knocked Senseless',
  2604.             Result: 'You can no longer upgrade dice for checks.'
  2605.         },
  2606.         //---------------------------------------- Severity 4
  2607.         {
  2608.             percent: '126 to 130',
  2609.             severity: 4,
  2610.             name: 'Gruesome Injury',
  2611.             Result: 'Roll 1d10 to determine one wounded characteristic -- roll results(1-3 = Brawn, 4-6 = Agility, 7 = Intellect, 8 = Cunning, 9 = Presence, 10 = Willpower. Characteristic is permanently one point lower.'
  2612.         },
  2613.         {
  2614.             percent: '131 to 140',
  2615.             severity: 4,
  2616.             name: 'Bleeding Out',
  2617.             Result: 'Suffer 1 wound and 1 strain every round at the beginning of turn. For every 5 wounds suffered beyond wound threshold, suffer one additional Critical Injury (ignore the details for any result below this result).'
  2618.         },
  2619.         {
  2620.             percent: '141 to 150',
  2621.             severity: 4,
  2622.             name: 'The End is Nigh',
  2623.             Result: 'Die after the last Initiative slot during the next round.'
  2624.         },
  2625.         {
  2626.             percent: '151',
  2627.             severity: 4,
  2628.             name: 'Dead',
  2629.             Result: 'Complete, absolute death.'
  2630.         }
  2631.     ];
  2632.     var critTableMachine = [
  2633.         {
  2634.             percent: '1 to 9',
  2635.             severity: 1,
  2636.             name: 'Mechanical Stress',
  2637.             Result: 'Ship or vehicle suffers 1 system strain.'
  2638.         },
  2639.         {
  2640.             percent: '10 to 18',
  2641.             severity: 1,
  2642.             name: 'Jostled',
  2643.             Result: 'All crew members suffer 1 strain.'
  2644.         },
  2645.         {
  2646.             percent: '19 to 27',
  2647.             severity: 1,
  2648.             name: 'Losing Power to Shields',
  2649.             Result: 'Decrease defense in affected defense zone by 1 until repaired. If ship or vehicle has no defense, suffer 1 system strain.'
  2650.         },
  2651.         {
  2652.             percent: '28 to 36',
  2653.             severity: 1,
  2654.             name: 'Knocked Off Course',
  2655.             Result: 'On next turn, pilot cannot execute any maneuvers. Instead, must make a Piloting check to regain bearings and resume course. Difficulty depends on current speed.'
  2656.         },
  2657.         {
  2658.             percent: '37 to 45',
  2659.             severity: 1,
  2660.             name: 'Tailspin',
  2661.             Result: 'All firing from ship or vehicle suffers 2 setback dice until end of pilot\'s next turn.'
  2662.         },
  2663.         {
  2664.             percent: '46 to 54',
  2665.             severity: 1,
  2666.             name: 'Component Hit',
  2667.             Result: 'One component of the attacker\'s choice is knocked offline, and is rendered inoperable until the end of the following round. See page 245 CRB for Small/Large Vehicle and Ship Component tables. '
  2668.         },
  2669.         // --------------- severity : 2
  2670.         {
  2671.             percent: '55 to 63',
  2672.             severity: 2,
  2673.             name: 'Shields Failing',
  2674.             Result: 'Decrease defense in all defense zones by 1 until repaired. If ship or vehicle has no defense, suffer 2 system strain.'
  2675.         },
  2676.         {
  2677.             percent: '64 to 72',
  2678.             severity: 2,
  2679.             name: 'Hyperdrive or Navicomputer Failure',
  2680.             Result: 'Cannot make any jump to hyperspace until repaired. If ship or vehicle has no hyperdrive, navigation systems fail leaving it unable to tell where it is or is going.'
  2681.         },
  2682.         {
  2683.             percent: '73 to 81',
  2684.             severity: 2,
  2685.             name: 'Power Fluctuations',
  2686.             Result: 'Pilot cannot voluntarily inflict system strain on the ship until repaired.'
  2687.         },
  2688.         // --------------- severity : 3
  2689.         {
  2690.             percent: '82 to 90',
  2691.             severity: 3,
  2692.             name: 'Shields Down',
  2693.             Result: 'Decrease defense in affected defense zone to 0 and all other defense zones by 1 point until repaired. If ship or vehicle has no defense, suffer 4 system strain.'
  2694.         },
  2695.         {
  2696.             percent: '91 to 99',
  2697.             severity: 3,
  2698.             name: 'Engine Damaged',
  2699.             Result: 'Ship or vehicle\'s maximum speed reduced by 1, to a minimum of 1, until repaired.'
  2700.         },
  2701.         {
  2702.             percent: '100 to 108',
  2703.             severity: 3,
  2704.             name: 'Shield Overload',
  2705.             Result: 'Decrease defense in all defense zones to 0 until repaired. In addition, suffer 2 system strain. Cannot be repaired until end of encounter. If ship or vehicle has no defense, reduce armor by 1 until repaired.'
  2706.         },
  2707.         {
  2708.             percent: '109 to 117',
  2709.             severity: 3,
  2710.             name: 'Engines Down',
  2711.             Result: 'Ship or vehicle\'s maximum speed reduced to 0. In addition, ship or vehicle cannot execute maneuvers until repaired. Ship continues on course at current speed and cannot be stopped or course changed until repaired.'
  2712.         },
  2713.         {
  2714.             percent: '118 to 126',
  2715.             severity: 3,
  2716.             name: 'Major System Failure',
  2717.             Result: 'One component of the attacker\'s choice is heavily damages, and is inoperable until the critical hit is repaired. See page 245 CRB for Small/Large Vehicle and Ship Component tables. '
  2718.         },
  2719.         // --------------- severity : 4
  2720.         {
  2721.             percent: '127 to 133',
  2722.             severity: 4,
  2723.             name: 'Major Hull Breach',
  2724.             Result: 'Ships and vehicles of silhouette 4 and smaller depressurize in a number of rounds equal to silhouette. Ships of silhouette 5 and larger don\'t completely depressurize, but parts do (specifics at GM discretion). Ships and vehicles operating in atmosphere instead suffer a Destabilized Critical.'
  2725.         },
  2726.         {
  2727.             percent: '134 to 138',
  2728.             severity: 4,
  2729.             name: 'Destabilised',
  2730.             Result: 'Reduce ship or vehicle\'s hull integrity threshold and system strain threshold to half original values until repaired.'
  2731.         },
  2732.         {
  2733.             percent: '139 to 144',
  2734.             severity: 4,
  2735.             name: 'Fire!',
  2736.             Result: 'Fire rages through ship or vehicle and it immediately takes 2 system strain. Fire can be extinguished with appropriate skill, Vigilance or Cool checks at GM\'s discretion. Takes one round per two silhouette to put out.'
  2737.         },
  2738.         {
  2739.             percent: '145 to 153',
  2740.             severity: 4,
  2741.             name: 'Breaking Up',
  2742.             Result: 'At the end of next round, ship is completely destroyed. Anyone aboard has one round to reach escape pod or bail out before they are lost.'
  2743.         },
  2744.         {
  2745.             percent: '154+',
  2746.             severity: 4,
  2747.             name: 'Vaporized',
  2748.             Result: 'The ship or Vehicle is completely destroyed.'
  2749.         }
  2750.     ];
  2751.     var critRoll = function (addCritNum, type) {
  2752.         var openSlot = false;
  2753.         var diceRoll = '';
  2754.         var critMod = '';
  2755.         var rollTotal = '';
  2756.         var rollOffset = parseInt(getAttrByName(diceObj.vars.characterID, type + '-critAddOffset'));
  2757.         rollOffset = rollOffset ? rollOffset : 0;
  2758.         var totalcrits = parseInt(getAttrByName(diceObj.vars.characterID, type + '-critTotal'));
  2759.         if(!totalcrits){
  2760.             totalcrits = 0;
  2761.         }
  2762.  
  2763.         //roll random
  2764.         if (!addCritNum) {
  2765.             diceRoll = randomInteger(100);
  2766.             critMod = (totalcrits * 10);
  2767.             rollTotal = diceRoll + critMod + rollOffset;
  2768.             rollTotal = rollTotal < 1 ? 1 : rollTotal;
  2769.             eote.process.logger("critRoll", "diceRoll: " + diceRoll);
  2770.             eote.process.logger("critRoll", "critMod: " + critMod);
  2771.             eote.process.logger("critRoll", "rollTotal " + rollTotal);
  2772.         } else {
  2773.             rollTotal = parseInt(addCritNum);
  2774.         }
  2775.         //find crit in critical table
  2776.         if(type=="character" || type=="npc" || type == "companion" || type=="beast"){
  2777.             critTable = critTableLifeform;
  2778.         }
  2779.         if(type=="starship" || type=="vehicle"){
  2780.             critTable = critTableMachine;
  2781.         }
  2782.         for (var key in critTable) {
  2783.             var percent = critTable[key].percent.split(' to ');
  2784.             var low = parseInt(percent[0]);
  2785.             var high = percent[1] ? parseInt(percent[1]) : 1000;
  2786.  
  2787.             if ((rollTotal >= low) && (rollTotal <= high)) {
  2788.  
  2789.                 critAttrs = [
  2790.                     {
  2791.                         name: type + '-critTotal',
  2792.                         current: totalcrits+1,
  2793.                         max: '',
  2794.                         update: true
  2795.                     },
  2796.                 ];
  2797.                 critAttrs2 = [
  2798.                     {
  2799.                         name: type + '-critName',
  2800.                         current: critTable[key].name,
  2801.                         max: '',
  2802.                         update: true
  2803.                     },
  2804.                     {
  2805.                         name: type + '-critSeverity' ,
  2806.                         current: critTable[key].severity,
  2807.                         max: '',
  2808.                         update: true
  2809.                     },
  2810.                     {
  2811.                         name: type + '-critRange',
  2812.                         current: critTable[key].percent,
  2813.                         max: '',
  2814.                         update: true
  2815.                     },
  2816.                     {
  2817.                         name: type + '-critSummary',
  2818.                         current: critTable[key].Result,
  2819.                         max: '',
  2820.                         update: true
  2821.                     },
  2822.                 ];
  2823.                 var chat = '/direct &{template:base} {{title='+type.charAt(0).toUpperCase()+type.slice(1)+' Critical}} ';
  2824.                 chat = chat + '{{subtitle=' + diceObj.vars.characterName + '}}';
  2825.                 chat = chat + '{{Previous Criticals=' + totalcrits + ' x 10}}';
  2826.                 if (rollOffset) {
  2827.                     chat = chat + '{{Dice Roll Offset=' + rollOffset + '}}';
  2828.                 }
  2829.                 chat = chat + '{{Dice Roll=' + diceRoll + '}}';
  2830.                 chat = chat + '{{Total=' + rollTotal + '}}';
  2831.                 chat = chat + '{{wide=<b>' + critTable[key].name + '</b><br>';
  2832.                 chat = chat + critTable[key].Result + '<br>}}';
  2833.  
  2834.                 sendChat(diceObj.vars.characterName, chat);
  2835.             }
  2836.         }
  2837.         eote.updateAddAttribute(characterObj, critAttrs);
  2838.         eote.process.createRepeatingCrit(type,characterObj,critAttrs2);
  2839.     };
  2840.     var critHeal = function (critID, type) {
  2841.         log(critID);
  2842.         log(type);
  2843.         var rowid = critID;
  2844.         var regex = new RegExp('^repeating_.*?_' + rowid + '_.*?$');
  2845.         var attrsInRow = filterObjs(function(obj) {
  2846.             if (obj.get('type') !== 'attribute' || obj.get('characterid') !== diceObj.vars.characterID) return false;
  2847.             return regex.test(obj.get('name'));
  2848.         });
  2849.         _.each(attrsInRow, function (attribute) {//loop characters
  2850.             attribute.remove();
  2851.         });
  2852.         var totalcrits = parseInt(getAttrByName(diceObj.vars.characterID, type + '-critTotal'));
  2853.         critAttrs = [
  2854.             {
  2855.                 name: type + '-critTotal',
  2856.                 current: totalcrits-1,
  2857.                 max: '',
  2858.                 update: true
  2859.             },
  2860.  
  2861.         ];
  2862.         eote.updateAddAttribute(characterObj, critAttrs);
  2863.     };
  2864.     var critArray = cmd[1].split('|');
  2865.     var command = critArray[0];
  2866.     var type = critArray[1] ? critArray[1] : null;
  2867.     var input = critArray[2] ? critArray[2] : null;
  2868.  
  2869.     if (type == null) {
  2870.         sendChat("Alert", "Type not supplied. Needs character, companion or beast");
  2871.         return;
  2872.     }
  2873.  
  2874.     if (command == 'heal') {
  2875.         critHeal(input, type);
  2876.     } else if (command == 'add') {
  2877.         critRoll(input, type);
  2878.     } else { // crit(roll)
  2879.         critRoll(null, type);
  2880.     }
  2881. };
  2882. eote.process.createRepeatingCrit = function(type,charactersObj,critAttrs) {
  2883.     eote.process.logger("repeating","repeating");
  2884.     eote.process.logger("type",type);
  2885.     eote.process.logger("critAttrs",critAttrs);
  2886.     var newId = eote.process.generateRowID();
  2887.    //check if object or array
  2888.     if (!_.isArray(charactersObj)) {
  2889.         charactersObj = [charactersObj];
  2890.     }
  2891.     if (!_.isArray(critAttrs)) {
  2892.         critAttrs = [critAttrs];
  2893.     }
  2894.     var characterId = "";
  2895.     _.each(charactersObj, function (characterObj) {//loop characters
  2896.  
  2897.         var characterName = '';
  2898.  
  2899.         if (characterObj.name) {
  2900.             characterName = characterObj.name;
  2901.         } else {
  2902.             characterName = characterObj.get('name');
  2903.         }
  2904.         characterId = characterObj.id;
  2905.         //find attribute via character ID
  2906.         var characterAttributesObj = findObjs({ _type: "attribute", characterid: characterObj.id });
  2907.  
  2908.         if (critAttrs.length != 0) {
  2909.  
  2910.             log('UPDATE/ADD ATTRIBUTES FOR:----------------------->' + characterName);
  2911.  
  2912.             _.each(critAttrs, function (critAttr) { //loop attributes to update / add
  2913.  
  2914.                 attr = _.find(characterAttributesObj, function (a) {
  2915.                     return (a.get('name') === critAttr.name);
  2916.                 });
  2917.                 if (attr) {
  2918.                     if (critAttr.update) {
  2919.                         log('Update Attr: ' + critAttr.name);
  2920.                         attr.set({ current: critAttr.current });
  2921.                         attr.set({ max: critAttr.max ? critAttr.max : '' });
  2922.                     }
  2923.                 } else {
  2924.                      log('Add Attr: '+ critAttr.name);
  2925.                      log( 'Value: '+ critAttr.current);
  2926.                     eote.createObj('attribute', {
  2927.                         characterid: characterObj.id,
  2928.                         name: "repeating_crit"+type+"_" + newId + "_" + critAttr.name,
  2929.                         current: critAttr.current,
  2930.                         max: critAttr.max ? critAttr.max : ''
  2931.                     });
  2932.                 }
  2933.             });
  2934.         }
  2935.     });
  2936.     eote.createObj('attribute', {
  2937.         characterid: characterId,
  2938.         name: "repeating_crit"+type+"_" + newId + "_"+type+"-critId",
  2939.         current: newId
  2940.     });
  2941.  
  2942. };
  2943.  
  2944.  
  2945.  
  2946.  eote.process.generateRowID = function () {
  2947.     "use strict";
  2948.     var a = 0, b = [];
  2949.     var c = (new Date()).getTime() + 0, d = c === a;
  2950.     a = c;
  2951.     for (var e = new Array(8), f = 7; 0 <= f; f--) {
  2952.         e[f] = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".charAt(c % 64);
  2953.         c = Math.floor(c / 64);
  2954.     }
  2955.     c = e.join("");
  2956.     if (d) {
  2957.         for (f = 11; 0 <= f && 63 === b[f]; f--) {
  2958.             b[f] = 0;
  2959.         }
  2960.         b[f]++;
  2961.     } else {
  2962.         for (f = 0; 12 > f; f++) {
  2963.             b[f] = Math.floor(64 * Math.random());
  2964.         }
  2965.     }
  2966.     for (f = 0; 12 > f; f++){
  2967.         c += "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".charAt(b[f]);
  2968.     }
  2969.     return c.replace(/_/g, "Z");
  2970.  };
  2971.  
  2972.  
  2973. eote.process.gmdice = function (cmd) {
  2974.  
  2975.     /* gmdice
  2976.      * default:
  2977.      * Description: Update CMD string to include -DicePool dice
  2978.      * Command: (gmdice)
  2979.      * ---------------------------------------------------------------- */
  2980.  
  2981.     //var charObj = findObjs({ _type: "character", name: "-DicePool" });
  2982.     var charID = eote.defaults['-DicePoolID'];//charObj[0].id;
  2983.  
  2984.     var g = getAttrByName(charID, 'ggm');
  2985.     var y = getAttrByName(charID, 'ygm');
  2986.     var p = getAttrByName(charID, 'pgm');
  2987.     var r = getAttrByName(charID, 'rgm');
  2988.     var b = getAttrByName(charID, 'bgm');
  2989.     var blk = getAttrByName(charID, 'blkgm');
  2990.     var w = getAttrByName(charID, 'wgm');
  2991.     var upAbility = getAttrByName(charID, 'upgradeAbilitygm');
  2992.     var upDifficulty = getAttrByName(charID, 'upgradeDifficultygm');
  2993.     var downProficiency = getAttrByName(charID, 'downgradeProficiencygm');
  2994.     var downChallenge = getAttrByName(charID, 'downgradeChallengegm');
  2995.  
  2996.     var gmdiceCMD = g + 'g ' + y + 'y ' + p + 'p ' + r + 'r ' + b + 'b ' + blk + 'blk ' + w + 'w upgrade(ability|' + upAbility + ') downgrade(proficiency|' + downProficiency + ') upgrade(difficulty|' + upDifficulty + ') downgrade(challenge|' + downChallenge + ')';
  2997.  
  2998.     eote.process.logger("eote.process.gmDice.charID", charID);
  2999.     cmd = cmd.replace('(gmdice)', gmdiceCMD);
  3000.     //log(cmd);
  3001.     return cmd;
  3002. };
  3003.  
  3004. eote.process.encum = function (cmd, diceObj) {
  3005.  
  3006.     /* Encumberment
  3007.      * default:
  3008.      * Description: If the current encum is great than threshold add 1 setback per unit over current encum
  3009.      * Command: !eed encum(encum_current|encum_threshold)
  3010.      * ---------------------------------------------------------------- */
  3011.  
  3012.     eote.process.logger("eote.process.encum", cmd);
  3013.  
  3014.     _.each(cmd, function (encum) {
  3015.  
  3016.         var diceArray = encum.match(/\((.*?)\|(.*?)\)/);
  3017.  
  3018.         if (diceArray && diceArray[1] && diceArray[2]) {
  3019.  
  3020.             var num1 = eote.process.math(diceArray[1]);
  3021.             var num2 = eote.process.math(diceArray[2]);
  3022.             var setbackDice = diceObj.count.setback;
  3023.  
  3024.             if (num2 > num1) {
  3025.                 diceObj.count.setback = setbackDice + (num2 - num1);
  3026.                 eote.process.logger("eote.process.encum.NewSetbackTotal", diceObj.count.setback + "blk");
  3027.                 //sendChat("Dice System", "/w " + diceObj.vars.characterName + " **Overencumbered** " + diceObj.count.setback + " Setbacks added");
  3028.             }
  3029.             else {
  3030.                 eote.process.logger("eote.process.encum", "No New Setback");
  3031.             }
  3032.         }
  3033.     });
  3034.     return diceObj;
  3035. };
  3036.  
  3037. eote.process.skill = function (cmd, diceObj) {
  3038.  
  3039.     /* Skill
  3040.      * default:
  3041.      * Description: create the ability and proficiency dice for a skill check
  3042.      * Command: !eed skill(char_value|skill_value|[NPC minion group size]|[Is minion skill])
  3043.      * ---------------------------------------------------------------- */
  3044.  
  3045.     eote.process.logger("eote.process.skill", cmd);
  3046.  
  3047.     _.each(cmd, function (skill) {
  3048.         var matchers = {
  3049.             matchNPCGroupWSkillName: /\((.*?)\|(.*?)\|(.*?)\|(.*?)\|(.*?)\)/,
  3050.             matchNPCGroupWOSkillName: /\((.*?)\|(.*?)\|(.*?)\|(.*?)\)/,
  3051.             matchRegSkillWSkillName: /\((.*?)\|(.*?)\|(.*?)\)/,
  3052.             matchRegSkillWOSkillName: /\((.*?)\|(.*?)\)/
  3053.         };
  3054.         var diceArray = null;
  3055.         Object.keys(matchers).some(function(key) {
  3056.             if ((diceArray = skill.match(matchers[key])) != null) {
  3057.                 return true;
  3058.             }
  3059.         });
  3060.  
  3061.         if (diceArray && diceArray[1] && diceArray[2]) {
  3062.             var num1 = eote.process.math(diceArray[1]);
  3063.             if (diceArray[3] && diceArray[4] && diceArray[4] === "1") {
  3064.                 num1 += (eote.process.math(diceArray[3]) - 1);
  3065.             }
  3066.             var num2 = eote.process.math(diceArray[2]);
  3067.             var totalAbil = Math.abs(num1 - num2);
  3068.             var totalProf = (num1 < num2 ? num1 : num2);
  3069.             var abilityDice = diceObj.count.ability;
  3070.             var proficiencyDice = diceObj.count.proficiency;
  3071.  
  3072.             diceObj.count.ability = abilityDice + totalAbil;
  3073.             diceObj.count.proficiency = proficiencyDice + totalProf;
  3074.  
  3075.             // check for skill name
  3076.             if (diceArray[5] || diceArray[3] && !diceArray[4]) {
  3077.                 var name = (diceArray[5] ? diceArray[5] : diceArray[3]);
  3078.  
  3079.                 /*  remove all non-letter characters to bring the name in line with the JSON properties
  3080.                  *  in order to have the closest chance in getting a match.
  3081.                  *
  3082.                  *  does not guarantee a match.
  3083.                  */
  3084.                 name = name.replace(/[^A-Za-z]/g, "");
  3085.  
  3086.                 diceObj.vars.skillName = name;
  3087.             } else {
  3088.                 diceObj.vars.skillName = null;
  3089.             }
  3090.  
  3091.             eote.process.logger("eote.process.skill.abilityTotal", diceObj.count.ability + "g");
  3092.             eote.process.logger("eote.process.skill.proficiencyTotal", diceObj.count.proficiency + "y");
  3093.         }
  3094.  
  3095.     });
  3096.     return diceObj;
  3097. };
  3098.  
  3099. eote.process.opposed = function (cmd, diceObj) {
  3100.     /*Opposed
  3101.      * default:
  3102.      * Description: create the difficulty and challenge dice for an opposed skill check
  3103.      * Command: !eed opposed(char_value|skill_value)
  3104.      * ---------------------------------------------------------------- */
  3105.  
  3106.     eote.process.logger("eote.process.opposed", cmd);
  3107.  
  3108.     _.each(cmd, function (opposed) {
  3109.  
  3110.         var diceArray = opposed.match(/\((.*?)\|(.*?)\)/);
  3111.  
  3112.         if (diceArray && diceArray[1] && diceArray[2]) {
  3113.             var num1 = eote.process.math(diceArray[1]);
  3114.             var num2 = eote.process.math(diceArray[2]);
  3115.             var totalOppDiff = Math.abs(num1 - num2);
  3116.             var totalOppChal = (num1 < num2 ? num1 : num2);
  3117.             var opposeddifficultyDice = diceObj.count.difficulty;
  3118.             var opposedchallengeDice = diceObj.count.challenge;
  3119.             diceObj.count.difficulty = opposeddifficultyDice + totalOppDiff;
  3120.             diceObj.count.challenge = opposedchallengeDice + totalOppChal;
  3121.         }
  3122.     });
  3123.     return diceObj;
  3124. };
  3125.  
  3126. eote.process.setDice = function (cmd, diceObj) {
  3127.  
  3128.     /* setDice
  3129.      * default:
  3130.      * Description: Loop thru the dice and adds or subtracts them from the dice object
  3131.      * Command: !eed g# y# b# blk# r# p# w# or g#+# or g#-#
  3132.      * ---------------------------------------------------------------- */
  3133.  
  3134.     eote.process.logger("eote.process.setDice", cmd);
  3135.  
  3136.     _.each(cmd, function (dice) {
  3137.  
  3138.         var diceArray = dice.match(/(-?\d{1,2})(\w{1,3})/);
  3139.  
  3140.         if (diceArray && diceArray[1] && diceArray[2]) {
  3141.  
  3142.             var diceQty = eote.process.math(diceArray[1]);
  3143.             diceQty = (isNaN(diceQty) ? 0 : diceQty);
  3144.  
  3145.             var abilityDice = diceObj.count.ability;
  3146.             var proficiencyDice = diceObj.count.proficiency;
  3147.             var difficultyDice = diceObj.count.difficulty;
  3148.             var challengeDice = diceObj.count.challenge;
  3149.             var boostDice = diceObj.count.boost;
  3150.             var setbackDice = diceObj.count.setback;
  3151.             var forceDice = diceObj.count.force;
  3152.             var success = diceObj.count.success;
  3153.             var advantage = diceObj.count.advantage;
  3154.             var threat = diceObj.count.threat;
  3155.             var failure = diceObj.count.failure;
  3156.  
  3157.             switch (diceArray[2]) {
  3158.                 case 'b':
  3159.                     diceObj.count.boost = boostDice + diceQty;
  3160.                     break;
  3161.                 case 'g':
  3162.                     diceObj.count.ability = abilityDice + diceQty;
  3163.                     break;
  3164.                 case 'y':
  3165.                     diceObj.count.proficiency = proficiencyDice + diceQty;
  3166.                     break;
  3167.                 case 'blk':
  3168.                     diceObj.count.setback = setbackDice + diceQty;
  3169.                     break;
  3170.                 case 'p':
  3171.                     diceObj.count.difficulty = difficultyDice + diceQty;
  3172.                     break;
  3173.                 case 'r':
  3174.                     diceObj.count.challenge = challengeDice + diceQty;
  3175.                     break;
  3176.                 case 'w':
  3177.                     diceObj.count.force = forceDice + diceQty;
  3178.                     break;
  3179.                 case 's':
  3180.                     diceObj.count.success = success + diceQty;
  3181.                     break;
  3182.                 case 'a':
  3183.                     diceObj.count.advantage = advantage + diceQty;
  3184.                     break;
  3185.                 case 't':
  3186.                     diceObj.count.threat = threat + diceQty;
  3187.                     break;
  3188.                 case 'f':
  3189.                     diceObj.count.failure = failure + diceQty;
  3190.                     break;
  3191.             }
  3192.         }
  3193.     });
  3194.     diceObj = eote.process.checkNegative(diceObj);
  3195.  
  3196.     eote.process.logger("eote.process.setDice.DiceToRoll", diceObj.count.boost + "b," + diceObj.count.ability + "g," + diceObj.count.proficiency + "y," + diceObj.count.setback + "blk," + diceObj.count.difficulty + "p," + diceObj.count.challenge + "r," + diceObj.count.force + "w," + diceObj.count.advantage + "a," + diceObj.count.threat + "t," + diceObj.count.failure + "f");
  3197.  
  3198.     return diceObj;
  3199. };
  3200.  
  3201. eote.process.checkNegative = function (diceObj) {
  3202.     if (diceObj.count.boost < 0) {
  3203.         eote.process.logger("eote.process.checkNegative.boost", "Setting count to 0 for being negative.");
  3204.         diceObj.count.boost = 0;
  3205.     }
  3206.     if (diceObj.count.ability < 0) {
  3207.         eote.process.logger("eote.process.checkNegative.ability", "Setting count to 0 for being negative.");
  3208.         diceObj.count.ability = 0;
  3209.     }
  3210.     if (diceObj.count.proficiency < 0) {
  3211.         eote.process.logger("eote.process.checkNegative.proficiency", "Setting count to 0 for being negative.");
  3212.         diceObj.count.proficiency = 0;
  3213.     }
  3214.     if (diceObj.count.setback < 0) {
  3215.         eote.process.logger("eote.process.checkNegative.setback", "Setting count to 0 for being negative.");
  3216.         diceObj.count.setback = 0;
  3217.     }
  3218.     if (diceObj.count.difficulty < 0) {
  3219.         eote.process.logger("eote.process.checkNegative.difficulty", "Setting count to 0 for being negative.");
  3220.         diceObj.count.difficulty = 0;
  3221.     }
  3222.     if (diceObj.count.challenge < 0) {
  3223.         eote.process.logger("eote.process.checkNegative.challenge", "Setting count to 0 for being negative.");
  3224.         diceObj.count.challenge = 0;
  3225.     }
  3226.     if (diceObj.count.force < 0) {
  3227.         eote.process.logger("eote.process.checkNegative.force", "Setting count to 0 for being negative.");
  3228.         diceObj.count.force = 0;
  3229.     }
  3230.     if (diceObj.count.success < 0) {
  3231.         eote.process.logger("eote.process.checkNegative.success", "Setting count to 0 for being negative.");
  3232.         diceObj.count.success = 0;
  3233.     }
  3234.     if (diceObj.count.advantage < 0) {
  3235.         eote.process.logger("eote.process.checkNegative.advantage", "Setting count to 0 for being negative.");
  3236.         diceObj.count.advantage = 0;
  3237.     }
  3238.     if (diceObj.count.threat < 0) {
  3239.         eote.process.logger("eote.process.checkNegative.threat", "Setting count to 0 for being negative.");
  3240.         diceObj.count.threat = 0;
  3241.     }
  3242.     if (diceObj.count.failure < 0) {
  3243.         eote.process.logger("eote.process.checkNegative.failure", "Setting count to 0 for being negative.");
  3244.         diceObj.count.failure = 0;
  3245.     }
  3246.     return diceObj;
  3247. };
  3248.  
  3249. eote.process.upgrade = function (cmd, diceObj) {
  3250.  
  3251.     /* Upgrade
  3252.      * default:
  3253.      * Description: upgrades ability and difficulty dice
  3254.      * Command: !eed upgrade(ability|#) or upgrade(difficulty|#)
  3255.      * ---------------------------------------------------------------- */
  3256.  
  3257.     eote.process.logger("eote.process.upgrade", cmd);
  3258.  
  3259.     _.each(cmd, function (dice) {
  3260.  
  3261.         var diceArray = dice.match(/\((.*?)\|(.*?)\)/);
  3262.  
  3263.         if (diceArray && diceArray[1] && diceArray[2]) {
  3264.  
  3265.             var type = diceArray[1];
  3266.             var upgradeVal = eote.process.math(diceArray[2]);
  3267.             var abilityDice = diceObj.count.ability;
  3268.             var proficiencyDice = diceObj.count.proficiency;
  3269.             var difficultyDice = diceObj.count.difficulty;
  3270.             var challengeDice = diceObj.count.challenge;
  3271.  
  3272.             switch (type) {
  3273.                 case 'ability':
  3274.  
  3275.                     var totalProf = (upgradeVal < abilityDice ? upgradeVal : abilityDice);
  3276.                     var totalAbil = Math.abs(upgradeVal - abilityDice);
  3277.  
  3278.                     if (upgradeVal > abilityDice) {
  3279.                         totalProf = totalProf + Math.floor(totalAbil / 2);
  3280.                         totalAbil = totalAbil % 2;
  3281.                     }
  3282.                     diceObj.count.ability = totalAbil;
  3283.                     diceObj.count.proficiency = proficiencyDice + totalProf;
  3284.  
  3285.                     eote.process.logger("eote.process.upgrade.abilityTotal", diceObj.count.ability + "g");
  3286.                     eote.process.logger("eote.process.upgrade.proficiencyTotal", diceObj.count.proficiency + "y");
  3287.  
  3288.                     break;
  3289.                 case 'difficulty':
  3290.  
  3291.                     var totalChall = (upgradeVal < difficultyDice ? upgradeVal : difficultyDice);
  3292.                     var totalDiff = Math.abs(upgradeVal - difficultyDice);
  3293.  
  3294.                     if (upgradeVal > difficultyDice) {
  3295.                         totalChall = totalChall + Math.floor(totalDiff / 2);
  3296.                         totalDiff = totalDiff % 2;
  3297.                     }
  3298.                     diceObj.count.difficulty = totalDiff;
  3299.                     diceObj.count.challenge = challengeDice + totalChall;
  3300.  
  3301.                     eote.process.logger("eote.process.upgrade.difficultyTotal", diceObj.count.difficulty + "p");
  3302.                     eote.process.logger("eote.process.upgrade.challengeTotal", diceObj.count.challenge + "r");
  3303.  
  3304.                     break;
  3305.             }
  3306.         }
  3307.     });
  3308.     return diceObj;
  3309. };
  3310.  
  3311. eote.process.downgrade = function (cmd, diceObj) {
  3312.  
  3313.     /* Downgrade
  3314.      * default:
  3315.      * Description: downgrades proficiency and challenge dice
  3316.      * Command: !eed downgrade(proficiency|#) or downgrade(challenge|#)
  3317.      * ---------------------------------------------------------------- */
  3318.  
  3319.     eote.process.logger("eote.process.downgrade", cmd);
  3320.  
  3321.     _.each(cmd, function (dice) {
  3322.  
  3323.         var diceArray = dice.match(/\((.*?)\|(.*?)\)/);
  3324.  
  3325.         if (diceArray && diceArray[1] && diceArray[2]) {
  3326.  
  3327.             var type = diceArray[1];
  3328.             var downgradeVal = eote.process.math(diceArray[2]);
  3329.             var abilityDice = diceObj.count.ability;
  3330.             var proficiencyDice = diceObj.count.proficiency;
  3331.             var difficultyDice = diceObj.count.difficulty;
  3332.             var challengeDice = diceObj.count.challenge;
  3333.  
  3334.             switch (type) {
  3335.                 case 'proficiency':
  3336.                     abilityDice += Math.min(proficiencyDice, downgradeVal);
  3337.                     proficiencyDice = Math.max(0, proficiencyDice - downgradeVal);
  3338.                     diceObj.count.ability = abilityDice;
  3339.                     diceObj.count.proficiency = proficiencyDice;
  3340.                     break;
  3341.                 case 'challenge':
  3342.                     difficultyDice += Math.min(challengeDice, downgradeVal);
  3343.                     challengeDice = Math.max(0, challengeDice - downgradeVal);
  3344.                     diceObj.count.difficulty = difficultyDice;
  3345.                     diceObj.count.challenge = challengeDice;
  3346.                     break;
  3347.             }
  3348.         }
  3349.     });
  3350.     return diceObj;
  3351. };
  3352.  
  3353. eote.process.math = function (expr) {
  3354.  
  3355.     /* Math
  3356.      * Returns: Number
  3357.      * Description: Evaluates a mathematical expression (as a string) and return the result
  3358.      * ---------------------------------------------------------------- */
  3359.  
  3360.     var chars = expr.split("");
  3361.     var n = [], op = [], index = 0, oplast = true;
  3362.  
  3363.     n[index] = "";
  3364.  
  3365.     // Parse the expression
  3366.     for (var c = 0; c < chars.length; c++) {
  3367.  
  3368.         if (isNaN(parseInt(chars[c])) && chars[c] !== "." && !oplast) {
  3369.             op[index] = chars[c];
  3370.             index++;
  3371.             n[index] = "";
  3372.             oplast = true;
  3373.         } else {
  3374.             n[index] += chars[c];
  3375.             oplast = false;
  3376.         }
  3377.     }
  3378.     // Calculate the expression
  3379.     expr = parseFloat(n[0]);
  3380.     for (var o = 0; o < op.length; o++) {
  3381.         var num = parseFloat(n[o + 1]);
  3382.         switch (op[o]) {
  3383.             case "+":
  3384.                 expr = expr + num;
  3385.                 break;
  3386.             case "-":
  3387.                 expr = expr - num;
  3388.                 break;
  3389.             case "*":
  3390.                 expr = expr * num;
  3391.                 break;
  3392.             case "/":
  3393.                 expr = expr / num;
  3394.                 break;
  3395.         }
  3396.     }
  3397.     return expr;
  3398. };
  3399.  
  3400. eote.process.addDiceValues = function (diceTotalObj, diceResult) {
  3401.  
  3402.     diceTotalObj.success = diceTotalObj.success + diceResult.success;
  3403.     diceTotalObj.failure = diceTotalObj.failure + diceResult.failure;
  3404.     diceTotalObj.advantage = diceTotalObj.advantage + diceResult.advantage;
  3405.     diceTotalObj.threat = diceTotalObj.threat + diceResult.threat;
  3406.     diceTotalObj.triumph = diceTotalObj.triumph + diceResult.triumph;
  3407.     diceTotalObj.despair = diceTotalObj.despair + diceResult.despair;
  3408.     diceTotalObj.light = diceTotalObj.light + diceResult.light;
  3409.     diceTotalObj.dark = diceTotalObj.dark + diceResult.dark;
  3410.  
  3411.     return diceTotalObj;
  3412. };
  3413.  
  3414. eote.process.totalDiceValues = function (diceTotalObj) {
  3415.  
  3416.     var diceTS = {
  3417.         success: 0,
  3418.         failure: 0,
  3419.         advantage: 0,
  3420.         threat: 0,
  3421.         triumph: 0,
  3422.         despair: 0,
  3423.         light: 0,
  3424.         dark: 0,
  3425.         diceGraphicsLog: "",
  3426.         diceTextLog: ""
  3427.     };
  3428.     var i = 0;
  3429.  
  3430.     i = diceTotalObj.success - diceTotalObj.failure;
  3431.  
  3432.     if (i >= 0) {
  3433.         diceTS.success = i;
  3434.     } else {
  3435.         diceTS.failure = Math.abs(i);
  3436.     }
  3437.     i = diceTotalObj.advantage - diceTotalObj.threat;
  3438.  
  3439.     if (i >= 0) {
  3440.         diceTS.advantage = i;
  3441.     } else {
  3442.         diceTS.threat = Math.abs(i);
  3443.     }
  3444.     diceTS.triumph = diceTotalObj.triumph;
  3445.     diceTS.despair = diceTotalObj.despair;
  3446.     diceTS.light = diceTotalObj.light;
  3447.     diceTS.dark = diceTotalObj.dark;
  3448.  
  3449.     return diceTS;
  3450. };
  3451.  
  3452. eote.process.rollDice = function (diceObj) {
  3453.  
  3454.     results = {
  3455.         success: 0,
  3456.         failure: 0,
  3457.         advantage: 0,
  3458.         threat: 0,
  3459.         triumph: 0,
  3460.         despair: 0,
  3461.         light: 0,
  3462.         dark: 0,
  3463.         diceGraphicsLog: '',
  3464.         diceTextLog: ''
  3465.     };
  3466.     eote.process.logger("eote.process.rollDice.FinalDiceToRoll", diceObj.count.boost + "b," + diceObj.count.ability + "g," + diceObj.count.proficiency + "y," + diceObj.count.setback + "blk," + diceObj.count.difficulty + "p," + diceObj.count.challenge + "r," + diceObj.count.force + "w," + diceObj.count.advantage + "a," + diceObj.count.threat + "t," + diceObj.count.failure + "f");
  3467.  
  3468.     //Blue "Boost" die (d6)
  3469.     if (diceObj.count.boost > 0) {
  3470.         results = eote.roll.boost(diceObj.count.boost);
  3471.         diceObj.graphicsLog.Boost = results.diceGraphicsLog;
  3472.         diceObj.textLog.Boost = results.diceTextLog;
  3473.         diceObj.totals = eote.process.addDiceValues(diceObj.totals, results);
  3474.     }
  3475.     //Green "Ability" die (d8)
  3476.     if (diceObj.count.ability > 0) {
  3477.         results = eote.roll.ability(diceObj.count.ability);
  3478.         diceObj.graphicsLog.Ability = results.diceGraphicsLog;
  3479.         diceObj.textLog.Ability = results.diceTextLog;
  3480.         diceObj.totals = eote.process.addDiceValues(diceObj.totals, results);
  3481.     }
  3482.     //Yellow "Proficiency" die (d12)
  3483.     if (diceObj.count.proficiency > 0) {
  3484.         results = eote.roll.proficiency(diceObj.count.proficiency);
  3485.         diceObj.graphicsLog.Proficiency = results.diceGraphicsLog;
  3486.         diceObj.textLog.Proficiency = results.diceTextLog;
  3487.         diceObj.totals = eote.process.addDiceValues(diceObj.totals, results);
  3488.     }
  3489.     //Black "SetBack" die (d6)
  3490.     if (diceObj.count.setback > 0) {
  3491.         results = eote.roll.setback(diceObj.count.setback);
  3492.         diceObj.graphicsLog.SetBack = results.diceGraphicsLog;
  3493.         diceObj.textLog.SetBack = results.diceTextLog;
  3494.         diceObj.totals = eote.process.addDiceValues(diceObj.totals, results);
  3495.     }
  3496.     //Purple "Difficulty" die (d8)
  3497.     if (diceObj.count.difficulty > 0) {
  3498.         results = eote.roll.difficulty(diceObj.count.difficulty);
  3499.         diceObj.graphicsLog.Difficulty = results.diceGraphicsLog;
  3500.         diceObj.textLog.Difficulty = results.diceTextLog;
  3501.         diceObj.totals = eote.process.addDiceValues(diceObj.totals, results);
  3502.     }
  3503.     //Red "Challenge" die (d12)
  3504.     if (diceObj.count.challenge > 0) {
  3505.         results = eote.roll.challenge(diceObj.count.challenge);
  3506.         diceObj.graphicsLog.Challenge = results.diceGraphicsLog;
  3507.         diceObj.textLog.Challenge = results.diceTextLog;
  3508.         diceObj.totals = eote.process.addDiceValues(diceObj.totals, results);
  3509.     }
  3510.     //White "Force" die (d12)
  3511.     if (diceObj.count.force > 0) {
  3512.         results = eote.roll.force(diceObj.count.force);
  3513.         diceObj.graphicsLog.Force = results.diceGraphicsLog;
  3514.         diceObj.textLog.Force = results.diceTextLog;
  3515.         diceObj.totals = eote.process.addDiceValues(diceObj.totals, results);
  3516.     }
  3517.     // Free Successes (from skills)
  3518.     if (diceObj.count.success > 0) {
  3519.         results = eote.roll.success(diceObj.count.success);
  3520.         diceObj.graphicsLog.Success = results.diceGraphicsLog;
  3521.         diceObj.textLog.Success = results.diceTextLog;
  3522.         diceObj.totals = eote.process.addDiceValues(diceObj.totals, results);
  3523.     }
  3524.     // Free Advantage (from skills)
  3525.     if (diceObj.count.advantage > 0) {
  3526.         results = eote.roll.advantage(diceObj.count.advantage);
  3527.         diceObj.graphicsLog.Advantage = results.diceGraphicsLog;
  3528.         diceObj.textLog.Advantage = results.diceTextLog;
  3529.         diceObj.totals = eote.process.addDiceValues(diceObj.totals, results);
  3530.     }
  3531.     //Free Threat (from skills)
  3532.     if (diceObj.count.threat > 0) {
  3533.         results = eote.roll.threat(diceObj.count.threat);
  3534.         diceObj.graphicsLog.Threat = results.diceGraphicsLog;
  3535.         diceObj.textLog.Threat = results.diceTextLog;
  3536.         diceObj.totals = eote.process.addDiceValues(diceObj.totals, results);
  3537.     }
  3538.     // Free Failure (from skills)
  3539.     if (diceObj.count.failure > 0) {
  3540.         results = eote.roll.failure(diceObj.count.failure);
  3541.         diceObj.graphicsLog.Failure = results.diceGraphicsLog;
  3542.         diceObj.textLog.Failure = results.diceTextLog;
  3543.         diceObj.totals = eote.process.addDiceValues(diceObj.totals, results);
  3544.     }
  3545.     //finds the sum of each dice attribute
  3546.     diceObj.totals = eote.process.totalDiceValues(diceObj.totals);
  3547.     return diceObj;
  3548. };
  3549.  
  3550. eote.process.diceOutput = function (diceObj, playerName, playerID) {
  3551.  
  3552.     //log(diceObj);
  3553.     var s1 = '<img src="';
  3554.     var s2 = '" title="';
  3555.     var s3 = '" height="';
  3556.     var s4 = '" width="';
  3557.     var s5 = '"/>';
  3558.     var chatGlobal = '';
  3559.     var diceGraphicsResults = "";
  3560.     var diceGraphicsRolled = "";
  3561.     var diceTextRolled = "";
  3562.     var diceTextResults = "";
  3563.  
  3564.     diceTextResults = "[";
  3565.     if (diceObj.totals.success > 0) {
  3566.         diceTextResults = diceTextResults + " Success:" + diceObj.totals.success;
  3567.         for (i = 1; i <= diceObj.totals.success; i++) {
  3568.             diceGraphicsResults = diceGraphicsResults + s1 + eote.defaults.graphics.SYMBOLS.S + s2 + "Success" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3569.         }
  3570.     }
  3571.     if (diceObj.totals.failure > 0) {
  3572.         diceTextResults = diceTextResults + " Fail:" + diceObj.totals.failure;
  3573.         for (i = 1; i <= diceObj.totals.failure; i++) {
  3574.             diceGraphicsResults = diceGraphicsResults + s1 + eote.defaults.graphics.SYMBOLS.F + s2 + "Failure" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3575.         }
  3576.     }
  3577.     if (diceObj.totals.advantage > 0) {
  3578.         diceTextResults = diceTextResults + " Advant:" + diceObj.totals.advantage;
  3579.         for (i = 1; i <= diceObj.totals.advantage; i++) {
  3580.             diceGraphicsResults = diceGraphicsResults + s1 + eote.defaults.graphics.SYMBOLS.A + s2 + "Advantage" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3581.         }
  3582.     }
  3583.     if (diceObj.totals.threat > 0) {
  3584.         diceTextResults = diceTextResults + " Threat:" + diceObj.totals.threat;
  3585.         for (i = 1; i <= diceObj.totals.threat; i++) {
  3586.             diceGraphicsResults = diceGraphicsResults + s1 + eote.defaults.graphics.SYMBOLS.T + s2 + "Threat" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3587.         }
  3588.     }
  3589.     if (diceObj.totals.triumph > 0) {
  3590.         diceTextResults = diceTextResults + " Triumph:" + diceObj.totals.triumph;
  3591.         for (i = 1; i <= diceObj.totals.triumph; i++) {
  3592.             diceGraphicsResults = diceGraphicsResults + s1 + eote.defaults.graphics.SYMBOLS.TRIUMPH + s2 + "Triumph" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3593.         }
  3594.     }
  3595.     if (diceObj.totals.despair > 0) {
  3596.         diceTextResults = diceTextResults + " Despair:" + diceObj.totals.despair;
  3597.         for (i = 1; i <= diceObj.totals.despair; i++) {
  3598.             diceGraphicsResults = diceGraphicsResults + s1 + eote.defaults.graphics.SYMBOLS.DESPAIR + s2 + "Despair" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3599.         }
  3600.     }
  3601.     if (diceObj.totals.light > 0) {
  3602.         diceTextResults = diceTextResults + " Light:" + diceObj.totals.light;
  3603.  
  3604.         for (i = 1; i <= diceObj.totals.light; i++) {
  3605.             diceGraphicsResults = diceGraphicsResults + s1 + eote.defaults.graphics.SYMBOLS.L + s2 + "Light" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3606.         }
  3607.     }
  3608.     if (diceObj.totals.dark > 0) {
  3609.         diceTextResults = diceTextResults + " Dark:" + diceObj.totals.dark;
  3610.         for (i = 1; i <= diceObj.totals.dark; i++) {
  3611.             diceGraphicsResults = diceGraphicsResults + s1 + eote.defaults.graphics.SYMBOLS.D + s2 + "Dark" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3612.         }
  3613.     }
  3614.     diceTextResults = diceTextResults + "]";
  3615.     //------------------------------------>
  3616.     if (eote.defaults.globalVars.diceTestEnabled === true) {
  3617.         characterPlayer = 'TEST';
  3618.     } else if (diceObj.vars.characterName) {
  3619.         characterPlayer = diceObj.vars.characterName;
  3620.     } else {
  3621.         characterPlayer = playerName;
  3622.     }
  3623.  
  3624.     var templateName = (diceObj.vars.suggestions.suggestionsExist
  3625.     && suggestionEngine.getDisplayOption() == suggestionEngine.enum.displayOptions.always ? "suggestion" : "base");
  3626.  
  3627.     /*Dice roll images work just fine when whispered*/
  3628.     var label = diceObj.vars.label;
  3629.     if (eote.defaults.globalVars.diceTestEnabled === true) {
  3630.         chatGlobal = "/direct <br>6b 8g 12y 6blk 8p 12r 12w <br>";
  3631.     } else if (label) {
  3632.         chatGlobal = "/direct &{template:" + templateName +"} " + diceObj.vars.label + "{{subtitle=" + characterPlayer + "}}";
  3633.     } else {
  3634.         chatGlobal = "/direct &{template:" + templateName +"} {{title=" + characterPlayer + "}}";
  3635.     }
  3636.     //------------------------------------>
  3637.     if (eote.defaults.globalVars.diceLogChat === true) {
  3638.         if (eote.defaults.globalVars.diceLogRolledOnOneLine === true) {
  3639.  
  3640.             diceGraphicsRolled = diceObj.graphicsLog.Boost + diceObj.graphicsLog.Ability + diceObj.graphicsLog.Proficiency + diceObj.graphicsLog.SetBack + diceObj.graphicsLog.Difficulty + diceObj.graphicsLog.Challenge + diceObj.graphicsLog.Force + diceObj.graphicsLog.Success + diceObj.graphicsLog.Advantage + diceObj.graphicsLog.Failure + diceObj.graphicsLog.Threat;
  3641.  
  3642.             if (diceObj.textLog.Boost != "") diceTextRolled = diceTextRolled + "Boost:" + diceObj.textLog.Boost;
  3643.             if (diceObj.textLog.Ability != "") diceTextRolled = diceTextRolled + "Ability:" + diceObj.textLog.Ability;
  3644.             if (diceObj.textLog.Proficiency != "") diceTextRolled = diceTextRolled + "Proficiency:" + diceObj.textLog.Proficiency;
  3645.             if (diceObj.textLog.SetBack != "") diceTextRolled = diceTextRolled + "SetBack:" + diceObj.textLog.SetBack;
  3646.             if (diceObj.textLog.Difficulty != "") diceTextRolled = diceTextRolled + "Difficulty:" + diceObj.textLog.Difficulty;
  3647.             if (diceObj.textLog.Challenge != "") diceTextRolled = diceTextRolled + "Challenge:" + diceObj.textLog.Challenge;
  3648.             if (diceObj.textLog.Force != "") diceTextRolled = diceTextRolled + "Force:" + diceObj.textLog.Force;
  3649.             if (diceObj.textLog.Success != "") diceTextRolled = diceTextRolled + "Success:" + diceObj.textLog.Success;
  3650.             if (diceObj.textLog.Advantage != "") diceTextRolled = diceTextRolled + "Advantage:" + diceObj.textLog.Advantage;
  3651.             if (diceObj.textLog.Failure != "") diceTextRolled = diceGraphicsRolled + "Failure:" + diceObj.textLog.Failure;
  3652.             if (diceObj.textLog.Threat != "") diceTextRolled = diceGraphicsRolled + "Threat:" + diceObj.textLog.Threat;
  3653.  
  3654.             if (eote.defaults.globalVars.diceGraphicsChat === true) {
  3655.                 chatGlobal = chatGlobal + '{{roll=' + diceGraphicsRolled + '}}';
  3656.             } else {
  3657.                 sendChat("", diceTextRolled);
  3658.             }
  3659.         } else {
  3660.  
  3661.             if (eote.defaults.globalVars.diceGraphicsChat === true) {
  3662.  
  3663.                 if (diceObj.vars.label) {
  3664.                     sendChat(characterPlayer, "/direct " + diceObj.vars.label + '<br>');
  3665.                 }
  3666.                 if (diceObj.graphicsLog.Boost != "") sendChat("", "/direct " + diceObj.graphicsLog.Boost);
  3667.                 if (diceObj.graphicsLog.Ability != "") sendChat("", "/direct " + diceObj.graphicsLog.Ability);
  3668.                 if (diceObj.graphicsLog.Proficiency != "") sendChat("", "/direct " + diceObj.graphicsLog.Proficiency);
  3669.                 if (diceObj.graphicsLog.SetBack != "") sendChat("", "/direct " + diceObj.graphicsLog.SetBack);
  3670.                 if (diceObj.graphicsLog.Difficulty != "") sendChat("", "/direct " + diceObj.graphicsLog.Difficulty);
  3671.                 if (diceObj.graphicsLog.Challenge != "") sendChat("", "/direct " + diceObj.graphicsLog.Challenge);
  3672.                 if (diceObj.graphicsLog.Force != "") sendChat("", "/direct " + diceObj.graphicsLog.Force);
  3673.                 if (diceObj.graphicsLog.Success != "") sendChat("", "/direct " + diceObj.graphicsLog.Success);
  3674.                 if (diceObj.graphicsLog.Advantage != "") sendChat("", "/direct " + diceObj.graphicsLog.Advantage);
  3675.                 if (diceObj.graphicsLog.Failure != "") sendChat("", "/direct " + diceObj.graphicsLog.Failure);
  3676.                 if (diceObj.graphicsLog.Threat != "") sendChat("", "/direct " + diceObj.graphicsLog.Threat);
  3677.             } else {
  3678.                 if (diceObj.vars.label) {
  3679.                     sendChat(characterPlayer, "/direct " + diceObj.vars.label + '<br>');
  3680.                 }
  3681.                 if (diceObj.textLog.Boost != "") sendChat("", "Boost:" + diceObj.textLog.Boost);
  3682.                 if (diceObj.textLog.Ability != "") sendChat("", "Ability:" + diceObj.textLog.Ability);
  3683.                 if (diceObj.textLog.Proficiency != "") sendChat("", "Proficiency:" + diceObj.textLog.Proficiency);
  3684.                 if (diceObj.textLog.SetBack != "") sendChat("", "SetBack:" + diceObj.textLog.SetBack);
  3685.                 if (diceObj.textLog.Difficulty != "") sendChat("", "Difficulty:" + diceObj.textLog.Difficulty);
  3686.                 if (diceObj.textLog.Challenge != "") sendChat("", "Challenge:" + diceObj.textLog.Challenge);
  3687.                 if (diceObj.textLog.Force != "") sendChat("", "Force:" + diceObj.textLog.Force);
  3688.                 if (diceObj.textLog.Success != "") sendChat("", "Success:" + diceObj.textLog.Success);
  3689.                 if (diceObj.textLog.Advantage != "") sendChat("", "Advantage:" + diceObj.textLog.Advantage);
  3690.                 if (diceObj.textLog.Failure != "") sendChat("", "Failure:" + diceObj.textLog.Failure);
  3691.                 if (diceObj.textLog.Threat != "") sendChat("", "Threat:" + diceObj.textLog.Threat);
  3692.             }
  3693.         }
  3694.     }
  3695.  
  3696.     var suggestions = suggestionEngine.buildSuggestionsRollTemplate(diceObj);
  3697.     var suggestionStatus = suggestionEngine.enum.displayOptions;
  3698.     var suggestionsFlag = suggestionEngine.getDisplayOption();
  3699.     var suggestionsExist = diceObj.vars.suggestions.suggestionsExist;
  3700.  
  3701.     if (suggestionsExist) {
  3702.         switch (suggestionsFlag) {
  3703.             case suggestionStatus.none:
  3704.                 // not really needed since the other checks won't allow a status of none to do anything
  3705.                 // but this prevents the default from yelling at you.
  3706.                 suggestions = null;
  3707.                 break;
  3708.             case suggestionStatus.whisper:
  3709.                 suggestions = "&{template:base} {{title=Skill Suggestions}} " + suggestions;
  3710.                 break;
  3711.             case suggestionStatus.always:
  3712.                 suggestions = " {{suggestionsExist=true}} " + suggestions;
  3713.                 break;
  3714.             case null:
  3715.               var msg = "No display option determined! Please set the display option on the " + eote.defaults.GMSheet.name;
  3716.               log(msg);
  3717.               sendChat("System", "/w gm " + msg);
  3718.             break;
  3719.             default:
  3720.                 // this should never be entered
  3721.                 log("Report Me! A suggestionFlag of '"+ suggestionsFlag +"' is not handled properly!");
  3722.         }
  3723.     }
  3724.  
  3725.     if (eote.defaults.globalVars.diceGraphicsChat === true) {
  3726.         chatGlobal = chatGlobal + '{{results=' + diceGraphicsResults + '}}';
  3727.         if (suggestions && suggestionsFlag == suggestionStatus.always)
  3728.             chatGlobal += " " + suggestions;
  3729.         sendChat(characterPlayer, chatGlobal);
  3730.     } else {
  3731.         sendChat("Roll", diceTextResults);
  3732.     }
  3733.  
  3734.     if (suggestions && suggestionsFlag == suggestionStatus.whisper) {
  3735.         sendChat("System", "/w gm " + suggestions);
  3736.     }
  3737.     eote.process.logger("eote.process.rollResult", diceTextResults);
  3738. };
  3739.  
  3740. eote.roll = {
  3741.  
  3742.     boost: function (diceQty) {
  3743.         //Blue "Boost" die (d6)
  3744.         //1 Blank
  3745.         //2 Blank
  3746.         //3 Success
  3747.         //4 Advantage
  3748.         //5 Advantage + Advantage
  3749.         //6 Success + Advantage
  3750.         var roll = 0;
  3751.         var diceResult = {
  3752.             success: 0,
  3753.             failure: 0,
  3754.             advantage: 0,
  3755.             threat: 0,
  3756.             triumph: 0,
  3757.             despair: 0,
  3758.             light: 0,
  3759.             dark: 0,
  3760.             diceGraphicsLog: "",
  3761.             diceTextLog: ""
  3762.         };
  3763.         var i = 0;
  3764.         var s1 = '<img src="';
  3765.         var s2 = '" title="';
  3766.         var s3 = '" height="';
  3767.         var s4 = '" width="';
  3768.         var s5 = '"/>';
  3769.  
  3770.         if (eote.defaults.globalVars.diceTestEnabled === true) {
  3771.             diceQty = 6;
  3772.         }
  3773.         for (i = 1; i <= diceQty; i++) {
  3774.             if (eote.defaults.globalVars.diceTestEnabled === true) {
  3775.                 roll = roll + 1;
  3776.             } else {
  3777.                 roll = randomInteger(6);
  3778.             }
  3779.             switch (roll) {
  3780.                 case 1:
  3781.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Blank)";
  3782.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.BOOST.BLANK + s2 + "Boost Blank" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3783.                     break;
  3784.                 case 2:
  3785.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Blank)";
  3786.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.BOOST.BLANK + s2 + "Boost Blank" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3787.                     break;
  3788.                 case 3:
  3789.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Success)";
  3790.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.BOOST.S + s2 + "Boost Success" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3791.                     diceResult.success = diceResult.success + 1;
  3792.                     break;
  3793.                 case 4:
  3794.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Advantage)";
  3795.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.BOOST.A + s2 + "Boost Advantage" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3796.                     diceResult.advantage = diceResult.advantage + 1;
  3797.                     break;
  3798.                 case 5:
  3799.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Advantage x2)";
  3800.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.BOOST.AA + s2 + "Boost Advantage x2" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3801.                     diceResult.advantage = diceResult.advantage + 2;
  3802.                     break;
  3803.                 case 6:
  3804.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Success + Advantage)";
  3805.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.BOOST.SA + s2 + "Boost Success + Advantage" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3806.                     diceResult.success = diceResult.success + 1;
  3807.                     diceResult.advantage = diceResult.advantage + 1;
  3808.                     break;
  3809.             }
  3810.         }
  3811.         return diceResult;
  3812.     },
  3813.     ability: function (diceQty) {
  3814.         //Green "Ability" die (d8)
  3815.         //1 Blank
  3816.         //2 Success
  3817.         //3 Success
  3818.         //4 Advantage
  3819.         //5 Advantage
  3820.         //6 Success + Advantage
  3821.         //7 Advantage + Advantage
  3822.         //8 Success + Success
  3823.         var roll = 0;
  3824.         var diceTextLog = "";
  3825.         var diceGraphicsLog = "";
  3826.         var diceResult = {
  3827.             success: 0,
  3828.             failure: 0,
  3829.             advantage: 0,
  3830.             threat: 0,
  3831.             triumph: 0,
  3832.             despair: 0,
  3833.             light: 0,
  3834.             dark: 0,
  3835.             diceGraphicsLog: "",
  3836.             diceTextLog: ""
  3837.         };
  3838.         var i = 0;
  3839.         var s1 = '<img src="';
  3840.         var s2 = '" title="';
  3841.         var s3 = '" height="';
  3842.         var s4 = '" width="';
  3843.         var s5 = '"/>';
  3844.  
  3845.         if (eote.defaults.globalVars.diceTestEnabled === true) {
  3846.             diceQty = 8;
  3847.         }
  3848.         for (i = 1; i <= diceQty; i++) {
  3849.             if (eote.defaults.globalVars.diceTestEnabled === true) {
  3850.                 roll = roll + 1;
  3851.             }
  3852.             else {
  3853.                 roll = randomInteger(8);
  3854.             }
  3855.             switch (roll) {
  3856.                 case 1:
  3857.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Blank)";
  3858.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.ABILITY.BLANK + s2 + "Ability Blank" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3859.                     break;
  3860.                 case 2:
  3861.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Success)";
  3862.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.ABILITY.S + s2 + "Ability Success" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3863.                     diceResult.success = diceResult.success + 1;
  3864.                     break;
  3865.                 case 3:
  3866.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Success)";
  3867.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.ABILITY.S + s2 + "Ability Success" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3868.                     diceResult.success = diceResult.success + 1;
  3869.                     break;
  3870.                 case 4:
  3871.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Advantage)";
  3872.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.ABILITY.A + s2 + "Ability Advantage" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3873.                     diceResult.advantage = diceResult.advantage + 1;
  3874.                     break;
  3875.                 case 5:
  3876.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Advantage)";
  3877.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.ABILITY.A + s2 + "Ability Advantage" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3878.                     diceResult.advantage = diceResult.advantage + 1;
  3879.                     break;
  3880.                 case 6:
  3881.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Success + Advantage)";
  3882.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.ABILITY.SA + s2 + "Ability Success + Advantage" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3883.                     diceResult.success = diceResult.success + 1;
  3884.                     diceResult.advantage = diceResult.advantage + 1;
  3885.                     break;
  3886.                 case 7:
  3887.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Advantage x2)";
  3888.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.ABILITY.AA + s2 + "Ability Advantage x2" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3889.                     diceResult.advantage = diceResult.advantage + 2;
  3890.                     break;
  3891.                 case 8:
  3892.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Success x2)";
  3893.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.ABILITY.SS + s2 + "Ability Success x2" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3894.                     diceResult.success = diceResult.success + 2;
  3895.                     break;
  3896.             }
  3897.         }
  3898.         return diceResult;
  3899.     },
  3900.     proficiency: function (diceQty) {
  3901.         //Yellow "Proficiency" die (d12)
  3902.         //1 Blank
  3903.         //2 Triumph
  3904.         //3 Success
  3905.         //4 Success
  3906.         //5 Advantage
  3907.         //6 Success + Advantage
  3908.         //7 Success + Advantage
  3909.         //8 Success + Advantage
  3910.         //9 Success + Success
  3911.         //10 Success + Success
  3912.         //11 Advantage + Advantage
  3913.         //12 Advantage + Advantage
  3914.         var roll = 0;
  3915.         var diceTextLog = "";
  3916.         var diceGraphicsLog = "";
  3917.         var diceResult = {
  3918.             success: 0,
  3919.             failure: 0,
  3920.             advantage: 0,
  3921.             threat: 0,
  3922.             triumph: 0,
  3923.             despair: 0,
  3924.             light: 0,
  3925.             dark: 0,
  3926.             diceGraphicsLog: "",
  3927.             diceTextLog: ""
  3928.         };
  3929.         var i = 0;
  3930.         var s1 = '<img src="';
  3931.         var s2 = '" title="';
  3932.         var s3 = '" height="';
  3933.         var s4 = '" width="';
  3934.         var s5 = '"/>';
  3935.  
  3936.         if (eote.defaults.globalVars.diceTestEnabled === true) {
  3937.             diceQty = 12;
  3938.         }
  3939.         for (i = 1; i <= diceQty; i++) {
  3940.             if (eote.defaults.globalVars.diceTestEnabled === true) {
  3941.                 roll = roll + 1;
  3942.             }
  3943.             else {
  3944.                 roll = randomInteger(12);
  3945.             }
  3946.             switch (roll) {
  3947.                 case 1:
  3948.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Blank)";
  3949.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.PROFICIENCY.BLANK + s2 + "Proficiency Blank" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3950.                     break;
  3951.                 case 2:
  3952.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Triumph(+Success))";
  3953.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.PROFICIENCY.TRIUMPH + s2 + "Proficiency Triumph(+Success)" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3954.                     diceResult.triumph = diceResult.triumph + 1;
  3955.                     diceResult.success = diceResult.success + 1;
  3956.                     break;
  3957.                 case 3:
  3958.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Success)";
  3959.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.PROFICIENCY.S + s2 + "Proficiency Success" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3960.                     diceResult.success = diceResult.success + 1;
  3961.                     break;
  3962.                 case 4:
  3963.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Success)";
  3964.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.PROFICIENCY.S + s2 + "Proficiency Success" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3965.                     diceResult.success = diceResult.success + 1;
  3966.                     break;
  3967.                 case 5:
  3968.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Advantage)";
  3969.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.PROFICIENCY.A + s2 + "Proficiency Advantage" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3970.                     diceResult.advantage = diceResult.advantage + 1;
  3971.                     break;
  3972.                 case 6:
  3973.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Success + Advantage)";
  3974.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.PROFICIENCY.SA + s2 + "Proficiency Success + Advantage" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3975.                     diceResult.success = diceResult.success + 1;
  3976.                     diceResult.advantage = diceResult.advantage + 1;
  3977.                     break;
  3978.                 case 7:
  3979.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Success + Advantage)";
  3980.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.PROFICIENCY.SA + s2 + "Proficiency Success + Advantage" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3981.                     diceResult.success = diceResult.success + 1;
  3982.                     diceResult.advantage = diceResult.advantage + 1;
  3983.                     break;
  3984.                 case 8:
  3985.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Success + Advantage)";
  3986.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.PROFICIENCY.SA + s2 + "Proficiency Success + Advantage" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3987.                     diceResult.success = diceResult.success + 1;
  3988.                     diceResult.advantage = diceResult.advantage + 1;
  3989.                     break;
  3990.                 case 9:
  3991.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Success x2)";
  3992.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.PROFICIENCY.SS + s2 + "Proficiency Success x2" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3993.                     diceResult.success = diceResult.success + 2;
  3994.                     break;
  3995.                 case 10:
  3996.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Success x2)";
  3997.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.PROFICIENCY.SS + s2 + "Proficiency Success x2" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  3998.                     diceResult.success = diceResult.success + 2;
  3999.                     break;
  4000.                 case 11:
  4001.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Advantage x2)";
  4002.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.PROFICIENCY.AA + s2 + "Proficiency Advantage x2" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4003.                     diceResult.advantage = diceResult.advantage + 2;
  4004.                     break;
  4005.                 case 12:
  4006.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Advantage x2)";
  4007.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.PROFICIENCY.AA + s2 + "Proficiency Advantage x2" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4008.                     diceResult.advantage = diceResult.advantage + 2;
  4009.                     break;
  4010.             }
  4011.         }
  4012.         return diceResult;
  4013.     },
  4014.     setback: function (diceQty) {
  4015.         //Black "Setback" die (d6)
  4016.         //1 Blank
  4017.         //2 Blank
  4018.         //3 Failure
  4019.         //4 Failure
  4020.         //5 Threat
  4021.         //6 Threat
  4022.         var roll = 0;
  4023.         var diceTextLog = "";
  4024.         var diceGraphicsLog = "";
  4025.         var diceResult = {
  4026.             success: 0,
  4027.             failure: 0,
  4028.             advantage: 0,
  4029.             threat: 0,
  4030.             triumph: 0,
  4031.             despair: 0,
  4032.             light: 0,
  4033.             dark: 0,
  4034.             diceGraphicsLog: "",
  4035.             diceTextLog: ""
  4036.         };
  4037.         var i = 0;
  4038.         var s1 = '<img src="';
  4039.         var s2 = '" title="';
  4040.         var s3 = '" height="';
  4041.         var s4 = '" width="';
  4042.         var s5 = '"/>';
  4043.  
  4044.         if (eote.defaults.globalVars.diceTestEnabled === true) {
  4045.             diceQty = 6;
  4046.         }
  4047.         for (i = 1; i <= diceQty; i++) {
  4048.             if (eote.defaults.globalVars.diceTestEnabled === true) {
  4049.                 roll = roll + 1;
  4050.             }
  4051.             else {
  4052.                 roll = randomInteger(6);
  4053.             }
  4054.             switch (roll) {
  4055.                 case 1:
  4056.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Blank)";
  4057.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.SETBACK.BLANK + s2 + "Setback Blank" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4058.                     break;
  4059.                 case 2:
  4060.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Blank)";
  4061.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.SETBACK.BLANK + s2 + "Setback Blank" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4062.                     break;
  4063.                 case 3:
  4064.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Failure)";
  4065.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.SETBACK.F + s2 + "Setback Failure" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4066.                     diceResult.failure = diceResult.failure + 1;
  4067.                     break;
  4068.                 case 4:
  4069.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Failure)";
  4070.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.SETBACK.F + s2 + "Setback Failure" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4071.                     diceResult.failure = diceResult.failure + 1;
  4072.                     break;
  4073.                 case 5:
  4074.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Threat)";
  4075.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.SETBACK.T + s2 + "Setback Threat" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4076.                     diceResult.threat = diceResult.threat + 1;
  4077.                     break;
  4078.                 case 6:
  4079.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Threat)";
  4080.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.SETBACK.T + s2 + "Setback Threat" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4081.                     diceResult.threat = diceResult.threat + 1;
  4082.                     break;
  4083.             }
  4084.         }
  4085.         return diceResult;
  4086.     },
  4087.     difficulty: function (diceQty) {
  4088.         //Purple "Difficulty" die (d8)
  4089.         //1 Blank
  4090.         //2 Failure
  4091.         //3 Threat
  4092.         //4 Threat
  4093.         //5 Threat
  4094.         //6 Failure + Failure
  4095.         //7 Failure + Threat
  4096.         //8 Threat + Threat
  4097.         var roll = 0;
  4098.         var diceTextLog = "";
  4099.         var diceGraphicsLog = "";
  4100.         var diceResult = {
  4101.             success: 0,
  4102.             failure: 0,
  4103.             advantage: 0,
  4104.             threat: 0,
  4105.             triumph: 0,
  4106.             despair: 0,
  4107.             light: 0,
  4108.             dark: 0,
  4109.             diceGraphicsLog: "",
  4110.             diceTextLog: ""
  4111.         };
  4112.         var i = 0;
  4113.         var s1 = '<img src="';
  4114.         var s2 = '" title="';
  4115.         var s3 = '" height="';
  4116.         var s4 = '" width="';
  4117.         var s5 = '"/>';
  4118.  
  4119.         if (eote.defaults.globalVars.diceTestEnabled === true) {
  4120.             diceQty = 8;
  4121.         }
  4122.         for (i = 1; i <= diceQty; i++) {
  4123.             if (eote.defaults.globalVars.diceTestEnabled === true) {
  4124.                 roll = roll + 1;
  4125.             }
  4126.             else {
  4127.                 roll = randomInteger(8);
  4128.             }
  4129.             switch (roll) {
  4130.                 case 1:
  4131.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Blank)";
  4132.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.DIFFICULTY.BLANK + s2 + "Difficulty Blank" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4133.                     break;
  4134.                 case 2:
  4135.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Failure)";
  4136.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.DIFFICULTY.F + s2 + "Difficulty Failure" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4137.                     diceResult.failure = diceResult.failure + 1;
  4138.                     break;
  4139.                 case 3:
  4140.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Threat)";
  4141.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.DIFFICULTY.T + s2 + "Difficulty Threat" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4142.                     diceResult.threat = diceResult.threat + 1;
  4143.                     break;
  4144.                 case 4:
  4145.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Threat)";
  4146.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.DIFFICULTY.T + s2 + "Difficulty Threat" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4147.                     diceResult.threat = diceResult.threat + 1;
  4148.                     break;
  4149.                 case 5:
  4150.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Threat)";
  4151.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.DIFFICULTY.T + s2 + "Difficulty Threat" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4152.                     diceResult.threat = diceResult.threat + 1;
  4153.                     break;
  4154.                 case 6:
  4155.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Failure x2)";
  4156.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.DIFFICULTY.FF + s2 + "Difficulty Failure x2" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4157.                     diceResult.failure = diceResult.failure + 2;
  4158.                     break;
  4159.                 case 7:
  4160.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Failure + Threat)";
  4161.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.DIFFICULTY.FT + s2 + "Difficulty Failure + Threat" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4162.                     diceResult.failure = diceResult.failure + 1;
  4163.                     diceResult.threat = diceResult.threat + 1;
  4164.                     break;
  4165.                 case 8:
  4166.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Threat x2)";
  4167.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.DIFFICULTY.TT + s2 + "Difficulty Threat x2" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4168.                     diceResult.threat = diceResult.threat + 2;
  4169.                     break;
  4170.             }
  4171.         }
  4172.         return diceResult;
  4173.     },
  4174.     challenge: function (diceQty) {
  4175.         //Red "Challenge" die (d12)
  4176.         //1 Blank
  4177.         //2 Despair
  4178.         //3 Failure
  4179.         //4 Failure
  4180.         //5 Threat
  4181.         //6 Threat
  4182.         //7 Failure + Failure
  4183.         //8 Failure + Failure
  4184.         //9 Threat + Threat
  4185.         //10 Threat + Threat
  4186.         //11 Failure + Threat
  4187.         //12 Failure + Threat
  4188.         var roll = 0;
  4189.         var diceTextLog = "";
  4190.         var diceGraphicsLog = "";
  4191.         var diceResult = {
  4192.             success: 0,
  4193.             failure: 0,
  4194.             advantage: 0,
  4195.             threat: 0,
  4196.             triumph: 0,
  4197.             despair: 0,
  4198.             light: 0,
  4199.             dark: 0,
  4200.             diceGraphicsLog: "",
  4201.             diceTextLog: ""
  4202.         };
  4203.         var i = 0;
  4204.         var s1 = '<img src="';
  4205.         var s2 = '" title="';
  4206.         var s3 = '" height="';
  4207.         var s4 = '" width="';
  4208.         var s5 = '"/>';
  4209.  
  4210.         if (eote.defaults.globalVars.diceTestEnabled === true) {
  4211.             diceQty = 12;
  4212.         }
  4213.         for (i = 1; i <= diceQty; i++) {
  4214.             if (eote.defaults.globalVars.diceTestEnabled === true) {
  4215.                 roll = roll + 1;
  4216.             }
  4217.             else {
  4218.                 roll = randomInteger(12);
  4219.             }
  4220.             switch (roll) {
  4221.                 case 1:
  4222.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Blank)";
  4223.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.CHALLENGE.BLANK + s2 + "Challenge Blank" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4224.                     break;
  4225.                 case 2:
  4226.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Despair)";
  4227.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.CHALLENGE.DESPAIR + s2 + "Challenge Despair" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4228.                     diceResult.despair = diceResult.despair + 1;
  4229.                     diceResult.failure = diceResult.failure + 1;
  4230.                     break;
  4231.                 case 3:
  4232.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Failure)";
  4233.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.CHALLENGE.F + s2 + "Challenge Failure" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4234.                     diceResult.failure = diceResult.failure + 1;
  4235.                     break;
  4236.                 case 4:
  4237.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Failure)";
  4238.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.CHALLENGE.F + s2 + "Challenge Failure" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4239.                     diceResult.failure = diceResult.failure + 1;
  4240.                     break;
  4241.                 case 5:
  4242.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Threat)";
  4243.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.CHALLENGE.T + s2 + "Challenge Threat" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4244.                     diceResult.threat = diceResult.threat + 1;
  4245.                     break;
  4246.                 case 6:
  4247.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Threat)";
  4248.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.CHALLENGE.T + s2 + "Challenge Threat" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4249.                     diceResult.threat = diceResult.threat + 1;
  4250.                     break;
  4251.                 case 7:
  4252.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Failure x2)";
  4253.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.CHALLENGE.FF + s2 + "Challenge Failure x2" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4254.                     diceResult.failure = diceResult.failure + 2;
  4255.                     break;
  4256.                 case 8:
  4257.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Failure x2)";
  4258.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.CHALLENGE.FF + s2 + "Challenge Failure x2" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4259.                     diceResult.failure = diceResult.failure + 2;
  4260.                     break;
  4261.                 case 9:
  4262.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Threat x2)";
  4263.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.CHALLENGE.TT + s2 + "Challenge Threat x2" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4264.                     diceResult.threat = diceResult.threat + 2;
  4265.                     break;
  4266.                 case 10:
  4267.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Threat x2)";
  4268.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.CHALLENGE.TT + s2 + "Challenge Threat x2" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4269.                     diceResult.threat = diceResult.threat + 2;
  4270.                     break;
  4271.                 case 11:
  4272.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Failure + Threat)";
  4273.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.CHALLENGE.FT + s2 + "Challenge Failure + Threat" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4274.                     diceResult.failure = diceResult.failure + 1;
  4275.                     diceResult.threat = diceResult.threat + 1;
  4276.                     break;
  4277.                 case 12:
  4278.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Failure + Threat)";
  4279.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.CHALLENGE.FT + s2 + "Challenge Failure + Threat" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4280.                     diceResult.failure = diceResult.failure + 1;
  4281.                     diceResult.threat = diceResult.threat + 1;
  4282.                     break;
  4283.             }
  4284.         }
  4285.         return diceResult;
  4286.     },
  4287.     force: function (diceQty) {
  4288.         //White "Force" die (d12)
  4289.         //1 Light
  4290.         //2 Light
  4291.         //3 Light + Light
  4292.         //4 Light + Light
  4293.         //5 Light + Light
  4294.         //6 Dark
  4295.         //7 Dark
  4296.         //8 Dark
  4297.         //9 Dark
  4298.         //10 Dark
  4299.         //11 Dark
  4300.         //12 Dark + Dark
  4301.         var roll = 0;
  4302.         var diceTextLog = "";
  4303.         var diceGraphicsLog = "";
  4304.         var diceResult = {
  4305.             success: 0,
  4306.             failure: 0,
  4307.             advantage: 0,
  4308.             threat: 0,
  4309.             triumph: 0,
  4310.             despair: 0,
  4311.             light: 0,
  4312.             dark: 0,
  4313.             diceGraphicsLog: "",
  4314.             diceTextLog: ""
  4315.         };
  4316.         var i = 0;
  4317.         var s1 = '<img src="';
  4318.         var s2 = '" title="';
  4319.         var s3 = '" height="';
  4320.         var s4 = '" width="';
  4321.         var s5 = '"/>';
  4322.  
  4323.         if (eote.defaults.globalVars.diceTestEnabled === true) {
  4324.             diceQty = 12;
  4325.         }
  4326.         for (i = 1; i <= diceQty; i++) {
  4327.             if (eote.defaults.globalVars.diceTestEnabled === true) {
  4328.                 roll = roll + 1;
  4329.             }
  4330.             else {
  4331.                 roll = randomInteger(12);
  4332.             }
  4333.             switch (roll) {
  4334.                 case 1:
  4335.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Light)";
  4336.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.FORCE.L + s2 + "Force Light" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4337.                     diceResult.light = diceResult.light + 1;
  4338.                     break;
  4339.                 case 2:
  4340.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Light)";
  4341.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.FORCE.L + s2 + "Force Light" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4342.                     diceResult.light = diceResult.light + 1;
  4343.                     break;
  4344.                 case 3:
  4345.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Light x2)";
  4346.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.FORCE.LL + s2 + "Force Light x2" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4347.                     diceResult.light = diceResult.light + 2;
  4348.                     break;
  4349.                 case 4:
  4350.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Light x2)";
  4351.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.FORCE.LL + s2 + "Force Light x2" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4352.                     diceResult.light = diceResult.light + 2;
  4353.                     break;
  4354.                 case 5:
  4355.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Light x2)";
  4356.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.FORCE.LL + s2 + "Force Light x2" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4357.                     diceResult.light = diceResult.light + 2;
  4358.                     break;
  4359.                 case 6:
  4360.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Dark)";
  4361.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.FORCE.D + s2 + "Force Dark" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4362.                     diceResult.dark = diceResult.dark + 1;
  4363.                     break;
  4364.                 case 7:
  4365.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Dark)";
  4366.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.FORCE.D + s2 + "Force Dark" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4367.                     diceResult.dark = diceResult.dark + 1;
  4368.                     break;
  4369.                 case 8:
  4370.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Dark)";
  4371.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.FORCE.D + s2 + "Force Dark" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4372.                     diceResult.dark = diceResult.dark + 1;
  4373.                     break;
  4374.                 case 9:
  4375.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Dark)";
  4376.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.FORCE.D + s2 + "Force Dark" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4377.                     diceResult.dark = diceResult.dark + 1;
  4378.                     break;
  4379.                 case 10:
  4380.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Dark)";
  4381.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.FORCE.D + s2 + "Force Dark" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4382.                     diceResult.dark = diceResult.dark + 1;
  4383.                     break;
  4384.                 case 11:
  4385.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Dark)";
  4386.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.FORCE.D + s2 + "Force Dark" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4387.                     diceResult.dark = diceResult.dark + 1;
  4388.                     break;
  4389.                 case 12:
  4390.                     diceResult.diceTextLog = diceResult.diceTextLog + "(Dark x2)";
  4391.                     diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.FORCE.DD + s2 + "Force Dark x2" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4392.                     diceResult.dark = diceResult.dark + 2;
  4393.                     break;
  4394.             }
  4395.         }
  4396.         return diceResult;
  4397.     },
  4398.     success: function (diceQty) {
  4399.         //Free Success
  4400.         var i = 0;
  4401.         var s1 = '<img src="';
  4402.         var s2 = '" title="';
  4403.         var s3 = '" height="';
  4404.         var s4 = '" width="';
  4405.         var s5 = '"/>';
  4406.  
  4407.         var roll = 0;
  4408.         var diceTextLog = "";
  4409.         var diceGraphicsLog = "";
  4410.  
  4411.         var diceResult = {
  4412.             success: 0,
  4413.             failure: 0,
  4414.             advantage: 0,
  4415.             threat: 0,
  4416.             triumph: 0,
  4417.             despair: 0,
  4418.             light: 0,
  4419.             dark: 0,
  4420.             diceGraphicsLog: "",
  4421.             diceTextLog: ""
  4422.         };
  4423.         diceResult.diceTextLog = diceTextLog + "(Success x" + diceQty + ")";
  4424.         diceResult.success = diceResult.success + diceQty;
  4425.         for (i = 0; i < diceQty; i++) {
  4426.             diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.SYMBOLS.S + s2 + "Success" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4427.         }
  4428.         return diceResult;
  4429.     },
  4430.     advantage: function (diceQty) {
  4431.         //Free Advantage
  4432.         var i = 0;
  4433.         var s1 = '<img src="';
  4434.         var s2 = '" title="';
  4435.         var s3 = '" height="';
  4436.         var s4 = '" width="';
  4437.         var s5 = '"/>';
  4438.  
  4439.         var roll = 0;
  4440.         var diceTextLog = "";
  4441.         var diceGraphicsLog = "";
  4442.  
  4443.         var diceResult = {
  4444.             success: 0,
  4445.             failure: 0,
  4446.             advantage: 0,
  4447.             threat: 0,
  4448.             triumph: 0,
  4449.             despair: 0,
  4450.             light: 0,
  4451.             dark: 0,
  4452.             diceGraphicsLog: "",
  4453.             diceTextLog: ""
  4454.         };
  4455.         diceResult.diceTextLog = diceTextLog + "(Advantage x" + diceQty + ")";
  4456.         diceResult.advantage = diceResult.advantage + diceQty;
  4457.         for (i = 0; i < diceQty; i++) {
  4458.             diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.SYMBOLS.A + s2 + "Advantage" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4459.         }
  4460.         return diceResult;
  4461.     },
  4462.     threat: function (diceQty) {
  4463.         //Free threat
  4464.         var i = 0;
  4465.         var s1 = '<img src="';
  4466.         var s2 = '" title="';
  4467.         var s3 = '" height="';
  4468.         var s4 = '" width="';
  4469.         var s5 = '"/>';
  4470.  
  4471.         var roll = 0;
  4472.         var diceTextLog = "";
  4473.         var diceGraphicsLog = "";
  4474.  
  4475.         var diceResult = {
  4476.             success: 0,
  4477.             failure: 0,
  4478.             advantage: 0,
  4479.             threat: 0,
  4480.             triumph: 0,
  4481.             despair: 0,
  4482.             light: 0,
  4483.             dark: 0,
  4484.             diceGraphicsLog: "",
  4485.             diceTextLog: ""
  4486.         };
  4487.         diceResult.diceTextLog = diceTextLog + "(Threat x" + diceQty + ")";
  4488.         diceResult.threat = diceResult.threat + diceQty;
  4489.         for (i = 0; i < diceQty; i++) {
  4490.             diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.SYMBOLS.T + s2 + "Threat" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4491.         }
  4492.         return diceResult;
  4493.     },
  4494.     failure: function (diceQty) {
  4495.         //Free Failure
  4496.         var i = 0;
  4497.         var s1 = '<img src="';
  4498.         var s2 = '" title="';
  4499.         var s3 = '" height="';
  4500.         var s4 = '" width="';
  4501.         var s5 = '"/>';
  4502.  
  4503.         var roll = 0;
  4504.         var diceTextLog = "";
  4505.         var diceGraphicsLog = "";
  4506.  
  4507.         var diceResult = {
  4508.             success: 0,
  4509.             failure: 0,
  4510.             advantage: 0,
  4511.             threat: 0,
  4512.             triumph: 0,
  4513.             despair: 0,
  4514.             light: 0,
  4515.             dark: 0,
  4516.             diceGraphicsLog: "",
  4517.             diceTextLog: ""
  4518.         };
  4519.         diceResult.diceTextLog = diceTextLog + "(Failure x" + diceQty + ")";
  4520.         diceResult.failure = diceResult.failure + diceQty;
  4521.         for (i = 0; i < diceQty; i++) {
  4522.             diceResult.diceGraphicsLog = diceResult.diceGraphicsLog + s1 + eote.defaults.graphics.SYMBOLS.F + s2 + "Success" + s3 + eote.defaults.globalVars.diceGraphicsChatSize + s4 + eote.defaults.globalVars.diceGraphicsChatSize + s5;
  4523.         }
  4524.         return diceResult;
  4525.     }
  4526. };
  4527.  
  4528. eote.events = function () {
  4529.  
  4530.     //event listener Add character defaults to new characters
  4531.     on("add:character", function (characterObj) {
  4532.         eote.setCharacterDefaults(characterObj);
  4533.     });
  4534.     on("chat:message", function (msg) {
  4535.  
  4536.         if (msg.type != 'api') {
  4537.             return;
  4538.         }
  4539.         eote.process.setup(msg.content, msg.who, msg.playerid, msg);
  4540.         //selectedTokens = (msg.selected) ? msg.selected : null;
  4541.     });
  4542. };
  4543.  
  4544. // this only runs once per initialization of the script in order to prevent this process from running too frequently
  4545. // this converts any $\w$ token that matches a defined list of tokens into a html image tag.
  4546. function convertTokensToTags(skillSuggestions, symReplace) {
  4547.     Object.keys(skillSuggestions).forEach(function(categoryKey) {
  4548.         var category = skillSuggestions[categoryKey];
  4549.         Object.keys(category).forEach(function(categoryElemKey) {
  4550.             var categoryElem = category[categoryElemKey];
  4551.             Object.keys(categoryElem).forEach(function(symbolKey) {
  4552.                 var item = categoryElem[symbolKey];
  4553.                 for (var i = 0; i < item.length; i++)
  4554.                 {
  4555.                     var itemElem = item[i];
  4556.                     if (typeof itemElem == "object") {
  4557.                         if (itemElem.text.indexOf("$") > 0) {
  4558.                             Object.keys(symReplace).forEach(function (symReplaceKey) {
  4559.                                 itemElem.text = itemElem.text.replace(symReplace[symReplaceKey].matcher, symReplace[symReplaceKey].replacer);
  4560.                             });
  4561.                         }
  4562.                     }
  4563.                 }
  4564.             });
  4565.         });
  4566.     });
  4567.     log("Finished converting tokens to tags");
  4568. }
  4569.  
  4570. on('ready', function() {
  4571.     eote.init();
  4572. });
  4573.  
Add Comment
Please, Sign In to add comment