· 5 years ago · Feb 06, 2021, 12:08 AM
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 */
109if(!log) {
110 log = function(input) {
111 console.log(input);
112 }
113}
114
115if (!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 */
123var Charsheet = Charsheet || {};
124
125on('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
135Charsheet.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
159if (!Date.now) {
160 Date.now = function now() {
161 return new Date().getTime();
162 };
163}
164/* End Sheet Character Sheet Auto Creator */
165
166function 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*/
1260var eote = {};
1261
1262eote.init = function () {
1263 eote.setCharacterDefaults();
1264 eote.createGMDicePool();
1265 eote.events();
1266 convertTokensToTags(suggestionEngine.suggestions, eote.defaults.graphics.SymbolicReplacement);
1267 attemptRegisterGMObj();
1268};
1269
1270
1271eote.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
1401var GMSheet = eote.defaults.GMSheet;
1402var suggestionEngine = new SuggestionEngine();
1403
1404function 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
1409eote.defaults.graphics.SymbolicReplacement.success = buildReplacementObject("success", eote.defaults.graphics.SYMBOLS.S, eote.defaults.graphics.SIZE.SMALL);
1410eote.defaults.graphics.SymbolicReplacement.advantage = buildReplacementObject("advantage", eote.defaults.graphics.SYMBOLS.A, eote.defaults.graphics.SIZE.SMALL);
1411eote.defaults.graphics.SymbolicReplacement.triumph = buildReplacementObject("triumph", eote.defaults.graphics.SYMBOLS.TRIUMPH, eote.defaults.graphics.SIZE.SMALL);
1412eote.defaults.graphics.SymbolicReplacement.failure = buildReplacementObject("failure", eote.defaults.graphics.SYMBOLS.F, eote.defaults.graphics.SIZE.SMALL);
1413eote.defaults.graphics.SymbolicReplacement.threat = buildReplacementObject("threat", eote.defaults.graphics.SYMBOLS.T, eote.defaults.graphics.SIZE.SMALL);
1414eote.defaults.graphics.SymbolicReplacement.despair = buildReplacementObject("despair", eote.defaults.graphics.SYMBOLS.DESPAIR, eote.defaults.graphics.SIZE.SMALL);
1415
1416// dice icons
1417eote.defaults.graphics.SymbolicReplacement.ability = buildReplacementObject("ability", eote.defaults.graphics.ABILITY.BLANK, eote.defaults.graphics.SIZE.SMALL);
1418eote.defaults.graphics.SymbolicReplacement.boost = buildReplacementObject("boost", eote.defaults.graphics.BOOST.BLANK, eote.defaults.graphics.SIZE.SMALL);
1419eote.defaults.graphics.SymbolicReplacement.proficiency = buildReplacementObject("proficiency", eote.defaults.graphics.PROFICIENCY.BLANK, eote.defaults.graphics.SIZE.SMALL);
1420eote.defaults.graphics.SymbolicReplacement.difficulty = buildReplacementObject("difficulty", eote.defaults.graphics.DIFFICULTY.BLANK, eote.defaults.graphics.SIZE.SMALL);
1421eote.defaults.graphics.SymbolicReplacement.setback = buildReplacementObject("setback", eote.defaults.graphics.SETBACK.BLANK, eote.defaults.graphics.SIZE.SMALL);
1422eote.defaults.graphics.SymbolicReplacement.challenge = buildReplacementObject("challenge", eote.defaults.graphics.CHALLENGE.BLANK, eote.defaults.graphics.SIZE.SMALL);
1423
1424function 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
1447eote.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
1476eote.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
1490eote.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
1508eote.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
1531eote.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
1592eote.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
1655eote.process = {};
1656
1657eote.process.logger = function (functionName, cmd) {
1658 if (eote.defaults.globalVars.debugScript) {
1659 log(functionName + ' : ' + cmd);
1660 }
1661};
1662
1663eote.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
1868eote.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
1896eote.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
1909eote.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
1935eote.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
1956eote.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
1989eote.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
2009eote.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
2078eote.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
2184eote.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
2204eote.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
2246eote.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
2374eote.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
2442eote.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};
2882eote.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
2973eote.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
3004eote.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
3037eote.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
3099eote.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
3126eote.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
3201eote.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
3249eote.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
3311eote.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
3353eote.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
3400eote.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
3414eote.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
3452eote.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
3550eote.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
3740eote.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
4528eote.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.
4546function 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
4570on('ready', function() {
4571 eote.init();
4572});
4573