Old ngn4 website
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

256 lines
6.5 KiB

  1. var fs = require('fs');
  2. var path = require('path');
  3. var data = require('./data/combatant.json')
  4. var list = {
  5. uses: 0,
  6. content: []
  7. }
  8. var weaponLists = null;
  9. function getSpeciesList(set, category, species) {
  10. if(typeof(species) !== 'undefined') {
  11. var spList = species.split(',');
  12. var selections = [];
  13. for(var i = 0; i < spList.length; ++i) {
  14. var spName = category + '/' + spList[i];
  15. var gen = set.getGenerator(spName);
  16. if(gen != null) {
  17. selections.push(gen);
  18. }
  19. }
  20. if(selections.length > 0) {
  21. return selections;
  22. }
  23. }
  24. if(--list.uses >= 0) {
  25. return list.content;
  26. }
  27. list.content = [];
  28. var keys = Object.keys(set.generators);
  29. for(var i = 0; i < keys.length; ++i) {
  30. var key = keys[i];
  31. if(key.indexOf(category + '/') == 0) {
  32. var enabled = set.getMeta(key, 'combatant.enabled', false)
  33. var chance = set.getMeta(key, 'combatant.chance', 1.00);
  34. if(enabled == false) {
  35. continue;
  36. }
  37. if(chance <= 0.999 && Math.random() >= chance) {
  38. continue;
  39. }
  40. list.content.push(set.getGenerator(key));
  41. }
  42. }
  43. if(list.content.length > 0) {
  44. list.uses = 32;
  45. return list.content;
  46. } else {
  47. return null;
  48. }
  49. }
  50. function getWeapons(set, fullId) {
  51. var weapons = data[fullId.split('/')[0]].weapons;
  52. var types = Object.keys(weapons);
  53. var hasWeapon = false;
  54. var result = {};
  55. if(weaponLists == null) {
  56. weaponLists = {};
  57. for(var i = 0; i < types.length; ++i) {
  58. var type = types[i];
  59. var weaponNames = Object.keys(weapons[type]);
  60. var entry = {total: 0, items: []};
  61. for(var j = 0; j < weaponNames.length; ++j) {
  62. entry.total += weapons[type][weaponNames[j]].chance;
  63. entry.items.push({name: weaponNames[j], data: weapons[type][weaponNames[j]]});
  64. }
  65. weaponLists[type] = entry;
  66. }
  67. }
  68. while(!hasWeapon) {
  69. for(var i = 0; i < types.length; ++i) {
  70. var type = types[i];
  71. var chance = set.getMeta(fullId, 'combatant.weapon.' + type + '.chance', 0.5);
  72. var weightList = weaponLists[type];
  73. result[type] = null;
  74. if(Math.random() < chance) {
  75. var r = Math.random() * weightList.total;
  76. for(var j = 0; j < weightList.items.length; ++j) {
  77. var item = weightList.items[j];
  78. r -= item.data.chance;
  79. if(r <= 0) {
  80. result[type] = item;
  81. hasWeapon = true;
  82. break;
  83. }
  84. }
  85. }
  86. }
  87. }
  88. return result;
  89. }
  90. function getItems(category)
  91. {
  92. var items = data[category].items;
  93. var keys = Object.keys(items);
  94. var result = [];
  95. for(var i = 0; i < keys.length; ++i) {
  96. var key = keys[i];
  97. var item = items[key];
  98. var amount = 0;
  99. if(Math.random() < item.chance) {
  100. amount = 1;
  101. while(amount < item.max) {
  102. if(Math.random() < item.more) {
  103. ++amount;
  104. } else {
  105. break;
  106. }
  107. }
  108. }
  109. if(amount > 0) {
  110. result.push({name: key, amount: amount});
  111. }
  112. }
  113. return result;
  114. }
  115. function getAbiltiies(set, fullId) {
  116. var abilities = data[fullId.split('/')[0]].abilities;
  117. var abilityTypes = Object.keys(abilities);
  118. var sentinelPenalty = set.getMeta(fullId, 'combatant.ability.penalty.sentinel', 0.10);
  119. var sentinel = false;
  120. var result = [];
  121. for(var i = 0; i < abilityTypes.length; ++i) {
  122. var abilityType = abilityTypes[i];
  123. var abilityChances = abilities[abilityType];
  124. if(Math.random() > set.getMeta(fullId, 'combatant.ability.chance.' + abilityType, 0.10)) {
  125. continue;
  126. }
  127. var initialPenalty = set.getMeta(fullId, 'combatant.ability.penalty.initial.' + abilityType, 0.10);
  128. var incrementalPenalty = set.getMeta(fullId, 'combatant.ability.penalty.increment.' + abilityType, 0.10);
  129. var keys = Object.keys(abilityChances);
  130. for(var j = 0; j < keys.length; ++j) {
  131. var key = keys[j];
  132. var penalty = initialPenalty + (incrementalPenalty * result.length) + (sentinel ? sentinelPenalty : 0)
  133. if(Math.random() < abilityChances[key] - penalty) {
  134. result.push(key);
  135. }
  136. }
  137. sentinel = true;
  138. }
  139. return result;
  140. }
  141. function makeSoldier(req, res, set) {
  142. var category = req.params.cat;
  143. var species = req.params.species;
  144. var agent = req.headers['user-agent'];
  145. var selections = [];
  146. var result = {};
  147. // Validate input
  148. if(!data.hasOwnProperty(req.params.cat)) {
  149. res.status(404);
  150. res.send('ERROR 404: No combatant-generator data available for this category!\n');
  151. return;
  152. }
  153. // Get generator to use
  154. var spList = getSpeciesList(set, category, species);
  155. if(spList == null || spList.length == 0) {
  156. res.status(500);
  157. res.send('ERROR 500: Somehow ended up with no species to pick from. That is not supposed to happen. D:\n');
  158. return;
  159. }
  160. var gen = spList[Math.floor(Math.random() * spList.length)];
  161. // Determine gender randomly. If it discrimates, blame Math.random!
  162. if(gen.genders.length > 1) {
  163. result.gender = gen.genders[Math.floor(Math.random() * gen.genders.length)];
  164. } else {
  165. result.gender = null;
  166. }
  167. result.name = gen.generate('full_name', result.gender);
  168. result.species = gen.name;
  169. result.weapons = getWeapons(set, category + '/' + gen.id, req.query.hasOwnProperty('v'));
  170. result.abilities = getAbiltiies(set, category + '/' + gen.id, req.query.hasOwnProperty('v'));
  171. result.items = getItems(category);
  172. if(agent.indexOf('curl/') != -1 || req.query.hasOwnProperty('t')) {
  173. var text = result.name + " - " + result.species;
  174. if(result.gender != null) {
  175. text += ' ' + result.gender;
  176. }
  177. if(result.abilities.length > 0) {
  178. text += '\n\t' + result.abilities.join(', ');
  179. }
  180. if(result.weapons.primary != null) {
  181. var wp = result.weapons.primary;
  182. text += '\n\t' + wp.name + ' ' + wp.data.ammo + '/' + wp.data.ammo;
  183. }
  184. if(result.weapons.secondary != null) {
  185. var wp = result.weapons.secondary;
  186. text += '\n\t' + wp.name + ' ' + wp.data.ammo + '/' + wp.data.ammo;
  187. }
  188. for(var i = 0; i < result.items.length; ++i) {
  189. text += '\n\t' + result.items[i].name + ' x' + result.items[i].amount;
  190. }
  191. res.status(200);
  192. res.header("Content-Type", "text/plain; charset=utf-8");
  193. res.end(text + '\n');
  194. } else {
  195. res.status(200);
  196. res.header("Content-Type", "application/json; charset=utf-8");
  197. res.end(JSON.stringify(result));
  198. }
  199. }
  200. module.exports = function(set, app, data, scriptMethods) {
  201. app.get('/c/:cat', function(req, res) {makeSoldier(req, res, set)});
  202. app.get('/c/:cat/:species', function(req, res) {makeSoldier(req, res, set)});
  203. }