Advertisement
Guest User

Untitled

a guest
Jun 19th, 2018
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (function (root, factory) {
  2.     if(typeof define === 'function' && define.amd) {
  3.         // AMD. Register as an anonymous module.
  4.         define(['lodash'], factory);
  5.     } else if(typeof exports === 'object') {
  6.         // Node, CommonJS-like
  7.         module.exports = factory(require('lodash'));
  8.     } else if(typeof setup === 'object') {
  9.         // SugarCube globals
  10.         setup.Skills = factory(root._);
  11.     } else {
  12.         // Browser globals
  13.         root.Skills = factory(root._);
  14.     }
  15. }(typeof self !== 'undefined' ? self : this, function(_) {
  16.     var _autoFail = { roll: -50, result: -50, critical: false, fumble: false, success: false, failure: true };
  17.     var _skills = {};
  18.    
  19.     var calcModdedValue = function(base, mod) {
  20.         if(!_.isFinite(base)) {
  21.             return undefined;
  22.         }
  23.         if(_.isUndefined(mod)) {
  24.             return {value: base, mod: {add: 0, mult: 0, baseAdd: 0, baseMult: 0}};
  25.         }
  26.         var unifiedMod = Object.values(mod).reduce(function(result, m) {
  27.             if(_.isFinite(m)) {
  28.                 result.add += m;
  29.             } else {
  30.                 result.add += m.add || 0;
  31.                 result.mult += m.mult || 0;
  32.                 result.baseAdd += m.baseAdd || 0;
  33.                 result.baseMult += m.baseMult || 0;
  34.             }
  35.             return result;
  36.         }, {add: 0, mult: 0, baseAdd: 0, baseMult: 0});
  37.         return {
  38.             value: (base * (1 + unifiedMod.baseMult) + unifiedMod.baseAdd) * (1 + unifiedMod.mult) + unifiedMod.add,
  39.             mod: unifiedMod,
  40.         };
  41.     };
  42.    
  43.     var Skill = function(skill, attribute, options) {
  44.         options = options || {};
  45.         this.id = skill;
  46.         this.attribute = attribute;
  47.         this.options = Object.assign({}, options);
  48.        
  49.         this.tags = options.tags || [];
  50.         delete this.options.tags;
  51.         this.hasTag = (t => this.tags.includes(t));
  52.         this.hasAnyTag = (ts => this.tags.includesAny(ts));
  53.     };
  54.    
  55.     var Skills = {
  56.         init: function(character) {
  57.             if(!_.isObject(character)) {
  58.                 return;
  59.             }
  60.             character.attributes = character.attributes || {};
  61.             character.skills = character.skills || {};
  62.         },
  63.         define: function(skill, attribute, options) {
  64.             if(_.isString(skill) && _.isString(attribute)) {
  65.                 return _skills[skill] = new Skill(skill, attribute, options);
  66.             }
  67.         },
  68.         byId: function(skill) {
  69.             return _skills[skill];
  70.         },
  71.         get all() {
  72.             return Object.values(_skills);
  73.         },
  74.         raw: function(character, skill) {
  75.             if(skill instanceof Skill) {
  76.                 skill = skill.id;
  77.             }
  78.             if(!_.isObject(character) || !_.isString(skill) || !_.isObject(character.skills)) {
  79.                 return undefined;
  80.             }
  81.             if(!_.isFinite(character.skills[skill])) {
  82.                 return undefined;
  83.             }
  84.             var baseValue = character.skills[skill];
  85.             var result = { baseValue: character.skills[skill] };
  86.             return Object.assign(result, calcModdedValue(result.baseValue, character.skills[skill + "Mods"]));
  87.         },
  88.         get: function(character, skill) {
  89.             var raw = this.raw(character, skill);
  90.             return raw ? raw.value : undefined;
  91.         },
  92.         has: function(character, skill) {
  93.             return !_.isUndefined(this.raw(character, skill));
  94.         },
  95.         getAll: function(character) {
  96.             if(!_.isObject(character) || !_.isObject(character.skills)) {
  97.                 return {};
  98.             }
  99.             var result = Object.keys(character).filter(s => !s.endsWith('Mods'));
  100.             return _.fromPairs(result.map(s => [s, this.get(character, s)]));
  101.         },
  102.         addMod: function(character, mod, value) {
  103.             if(!_.isObject(character) || !_.isString(mod) || !_.isObject(value)) {
  104.                 return;
  105.             }
  106.             this.init(character);
  107.             Object.keys(value).forEach(function(skill) {
  108.                 var key = skill + "Mods";
  109.                 character.skills[key] = character.skills[key] || {};
  110.                 character.skills[key][mod] = value[skill];
  111.             });
  112.         },
  113.         removeMod: function(character, mod) {
  114.             if(!_.isObject(character) || !_.isString(mod) || !_.isObject(character.skills)) {
  115.                 return;
  116.             }
  117.             Object.keys(character.skills).filter(k => k.endsWith("Mods"))
  118.                 .forEach(k => { delete character.skills[k][mod]; });
  119.         },
  120.         check: function(character, skill, mod) {
  121.             if(!_.isObject(character) && !_.isFinite(character)) {
  122.                 return _.clone(this._autoFail);
  123.             }
  124.             var skillLevel = Number(character); /* NaN if character is an object */
  125.             if(_.isObject(character) && _.isString(skill)) {
  126.                 /* We are called with character, skill and optional modificator */
  127.                 skillLevel = this.get(character, skill) + (mod || 0);
  128.             }
  129.             if(!_.isFinite(skillLevel)) {
  130.                 return _.clone(this._autoFail);
  131.             }
  132.             /* Generating a Gaussian random variable using Box-Muller transform */
  133.             var u = 1 - Math.random();
  134.             var v = 1 - Math.random();
  135.             var roll = 50 + Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v) * 25;
  136.             var rawCritLimit = Math.min(0, skillLevel);
  137.             var rawFumbleLimit = Math.max(100, skillLevel);
  138.             var rawResult = skillLevel - roll;
  139.             return {
  140.                 roll: roll,
  141.                 result: rawResult,
  142.                 critical: (roll <= rawCritLimit || rawResult >= 80),
  143.                 fumble: (roll >= rawFumbleLimit || rawResult <= -80),
  144.                 success: (roll <= rawCritLimit || rawResult >= 0),
  145.                 failure: (roll >= rawFumbleLimit || rawResult < 0)
  146.             };
  147.         },
  148.     };
  149.    
  150.     return Skills;
  151. }));
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement