main.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. if(module) {
  2. var class_list = require('./classes.js');
  3. }
  4. function abilityToMod(ab) {
  5. return Math.floor((Math.max(ab, 0) - 10) / 2);
  6. }
  7. /*
  8. var points = { 8: 0, 9: 1, 10: 2, 11: 3, 12: 4, 13: 5, 14: 7, 15: 9, };
  9. function p(a) { return points[a] }
  10. var o = {};
  11. for(var a = 8; a <= 15; a++) {
  12. for(var b = 8; b <= 15; b++) {
  13. for(var c = 8; c <= 15; c++) {
  14. for(var d = 8; d <= 15; d++) {
  15. for(var e = 8; e <= 15; e++) {
  16. for(var f = 8; f <= 15; f++) {
  17. var sum = p(a) + p(b) + p(c) + p(d) + p(e) + p(f);
  18. if(sum == 27) {
  19. var x = [a,b,c,d,e,f];
  20. o[x.join('-')] = x;
  21. }
  22. } } } } } }
  23. for(var z in o) {
  24. console.log(JSON.stringify(o[z])+',');
  25. }
  26. */
  27. function has_prof_for_armor(prof, armor) {
  28. if(!(prof instanceof Array)) return false;
  29. for(var p of prof) {
  30. if(p == 'heavy armor' && armor.category == 'heavy') return true;
  31. if(p == 'medium armor' && armor.category == 'medium') return true;
  32. if(p == 'light armor' && armor.category == 'light') return true;
  33. if(p == armor.name) return true;
  34. }
  35. return false;
  36. }
  37. function get_armor_for_proficiencies(prof) {
  38. var out = {};
  39. for(var i in prof) {
  40. var p = prof[i];
  41. if(p == 'heavy armor') {
  42. for(var j in armor_list) {
  43. if(armor_list[j].category == "heavy") out[j] = armor_list[j];
  44. }
  45. }
  46. else if(p == 'medium armor') {
  47. for(var j in armor_list) {
  48. if(armor_list[j].category == "medium") out[j] = armor_list[j];
  49. }
  50. }
  51. else if(p == 'light armor') {
  52. for(var j in armor_list) {
  53. if(armor_list[j].category == "light") out[j] = armor_list[j];
  54. }
  55. }
  56. else {
  57. out[p] = armor_list[p];
  58. }
  59. }
  60. return out;
  61. }
  62. function Player(class_name, moral_alignment, practical_alignment) {
  63. this.moral_alignment = moral_alignment; // good, neutral, evil
  64. this.practical_alignment = practical_alignment; // lawful, neutral, chaotic
  65. this.class_name = class_name;
  66. this.class_subname = '';
  67. this.class_data = class_list[class_name];
  68. this.class_details = {};
  69. this.spell_attack = 0;
  70. this.spell_save = 0;
  71. this.level = 0;
  72. this.proficiency = {
  73. armor: {},
  74. weapon: {},
  75. tool: {},
  76. };
  77. this.abilities = {
  78. str: 0,
  79. dex: 0,
  80. con: 0,
  81. int: 0,
  82. wis: 0,
  83. cha: 0,
  84. };
  85. this.saving_throws = {
  86. str: 0,
  87. dex: 0,
  88. con: 0,
  89. int: 0,
  90. wis: 0,
  91. cha: 0,
  92. };
  93. this.items = {};
  94. this.attunements = 0;
  95. return this;
  96. }
  97. Player.prototype.setAbilities = function(ab) {
  98. this.abilities = {
  99. str: ab[0],
  100. dex: ab[1],
  101. con: ab[2],
  102. int: ab[3],
  103. wis: ab[4],
  104. cha: ab[5],
  105. };
  106. }
  107. Player.prototype.damage_with_weapon = function(w, hands) {
  108. var [dice, t] = w.damage.split(' ');
  109. var [n, d] = dice.split('d');
  110. var is_versatile = w.attrs.indexOf('versatile') !== -1;
  111. var is_finesse = w.attrs.indexOf('finesse') !== -1;
  112. return {
  113. dice: [{n: n, d: d}],
  114. fixed: this.abilities.str,
  115. type: t,
  116. max: n * d + this.abilities.str,
  117. };
  118. }
  119. Player.prototype.is_proficient_with_weapon = function(item) {
  120. }
  121. Player.prototype.can_attune_item = function(item) {
  122. if(item.requires_attunement === false) return true;
  123. if(item.requires_attunement === true) {
  124. if(this.attunements < 3) return true;
  125. }
  126. // for(var i in item.requires_attunement) {
  127. //
  128. // }
  129. }
  130. Player.prototype.test = function(test) {
  131. if(typeof test.prop == 'string') {
  132. return this[test.prop] == test.val;
  133. }
  134. // ability scores
  135. if(typeof test.ability == 'string') {
  136. if(test.min) {
  137. if(this.abilities[test.ability] < test.min) return false;
  138. }
  139. if(test.max) {
  140. if(this.abilities[test.ability] > test.max) return false;
  141. }
  142. if(test.eq) {
  143. if(this.abilities[test.ability] != test.eq) return false;
  144. }
  145. return true;
  146. }
  147. // class
  148. if(typeof test.class_name == 'string') {
  149. if(this.class_name != test.class_name) return false;
  150. if(test.sub && this.class_subname != test.sub) return false;
  151. return true;
  152. }
  153. // proficiency
  154. if(typeof test.prof == 'string') {
  155. var x = test.prof.split(":");
  156. if(this.proficiency[x[0]][x[1]] === true) return true;
  157. return false;
  158. }
  159. console.log("unknown test", test);
  160. return false;
  161. }
  162. function parseCoinString(a) {
  163. var x = a.split(' ');
  164. var c = 0;
  165. var s = 0;
  166. var g = 0;
  167. var p = 0;
  168. if(x[1] == 'cp') c += x[0];
  169. if(x[1] == 'sp') s += x[0];
  170. if(x[1] == 'gp') g += x[0];
  171. if(x[1] == 'pp') p += x[0];
  172. // fuck electrum
  173. if(x[1] == 'ep') s += x[0] * 5;
  174. return {c: c, s: s, g: g, p: p, total: c + s*10 + g*100 + p*1000};
  175. }
  176. function mulCoins(a, b) {
  177. var num, coin;
  178. if(typeof b == 'object') {
  179. num = a|0;
  180. coin = b;
  181. }
  182. else {
  183. num = b|0;
  184. coin = a;
  185. }
  186. return {
  187. c: coin.c * num,
  188. s: coin.s * num,
  189. g: coin.g * num,
  190. p: coin.p * num,
  191. total: coin.total * num,
  192. };
  193. }
  194. function addCoins(a, b) {
  195. if(typeof a == 'string') a = parseCoinString(a);
  196. if(typeof b == 'string') b = parseCoinString(b);
  197. return {
  198. c: a.c + b.c,
  199. s: a.s + b.s,
  200. g: a.g + b.g,
  201. p: a.p + b.p,
  202. total: a.total + b.total,
  203. };
  204. }
  205. function minimizeCoins(a, no_platinum) {
  206. // TODO: handle fractionals or negatives
  207. if(Math.log10(a.c) > 1) {
  208. a.s += Math.floor(a.c / 10);
  209. a.c = a.c % 10;
  210. }
  211. if(Math.log10(a.s) > 1) {
  212. a.g += Math.floor(a.s / 10);
  213. a.s = a.s % 10;
  214. }
  215. if(no_platinum !== true) {
  216. if(Math.log10(a.g) > 1) {
  217. a.p += Math.floor(a.g / 10);
  218. a.g = a.g % 10;
  219. }
  220. }
  221. // total does not change
  222. return a;
  223. }
  224. function newCoins(c,s,g,p) {
  225. return {c: c, s: s, g: g, p: p, total: c + s*10 + g*100 + p*1000};
  226. }
  227. function printCoins(a) {
  228. var s = [];
  229. if(a.p > 0) s.push(a.p + ' pp');
  230. if(a.g > 0) s.push(a.g + ' gp');
  231. if(a.s > 0) s.push(a.s + ' sp');
  232. if(a.c > 0) s.push(a.c + ' cp');
  233. return s.join(', ');
  234. }
  235. if(module && module.exports) {
  236. module.exports = {
  237. Player: Player,
  238. }
  239. }