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.
 
 
 

169 regels
4.5 KiB

  1. let spells = require('../../config/spells');
  2. let spellsConfig = require('../../config/spellsConfig');
  3. let configTypes = require('../config/types');
  4. const qualityGenerator = require('./quality');
  5. const qualityCount = qualityGenerator.qualities.length;
  6. const buildRolls = (item, blueprint, { random: spellProperties, negativeStats = [] }, quality) => {
  7. //We randomise the order so a random property gets to 'pick first'
  8. // otherwise it's easier for earlier properties to use more of the valuePool
  9. const propKeys = Object
  10. .keys(spellProperties)
  11. .sort((a, b) => Math.random() - Math.random());
  12. const propCount = propKeys.length;
  13. const maxRoll = (quality + 1) / qualityCount;
  14. const minSum = (quality / qualityCount) * propCount;
  15. let runningTotal = 0;
  16. const result = {};
  17. for (let i = 0; i < propCount; i++) {
  18. const minRoll = Math.max(0, minSum - runningTotal - ((propCount - (i + 1)) * maxRoll));
  19. let roll = minRoll + (Math.random() * (maxRoll - minRoll));
  20. runningTotal += roll;
  21. const prop = propKeys[i];
  22. const isNegative = negativeStats.includes(prop);
  23. if (isNegative)
  24. roll = 1 - roll;
  25. const scaledRoll = roll * (item.level / consts.maxLevel);
  26. result[prop] = scaledRoll;
  27. }
  28. return result;
  29. };
  30. const buildValues = item => {
  31. //Weapons have item.spell, runes just have item
  32. const spell = item.spell ? item.spell : item;
  33. const { name, type, rolls } = spell;
  34. const useName = (name || type).toLowerCase();
  35. const randomSpec = spellsConfig.spells[useName].random;
  36. const result = {};
  37. Object.entries(rolls).forEach(entry => {
  38. const [ property, roll ] = entry;
  39. const range = randomSpec[property];
  40. const isInt = property.indexOf('i_') === 0;
  41. let useProperty = property;
  42. const minRange = range[0];
  43. const maxRange = range[1];
  44. let val = minRange + ((maxRange - minRange) * roll);
  45. if (isInt) {
  46. useProperty = property.substr(2);
  47. val = Math.round(val);
  48. } else
  49. val = ~~(val * 100) / 100;
  50. val = Math.max(range[0], Math.min(range[1], val));
  51. result[useProperty] = val;
  52. });
  53. return result;
  54. };
  55. module.exports = {
  56. generate: function (item, blueprint) {
  57. blueprint = blueprint || {};
  58. let spellQuality = blueprint ? blueprint.spellQuality : '';
  59. let spellName = blueprint.spellName;
  60. if (!spellName) {
  61. let spellList = Object.keys(spellsConfig.spells).filter(s => !spellsConfig.spells[s].auto && !spellsConfig.spells[s].noDrop);
  62. spellName = spellList[~~(Math.random() * spellList.length)];
  63. }
  64. let spell = extend({}, spellsConfig.spells[spellName], blueprint.spellConfig);
  65. let spellAesthetic = spells.spells.find(s => s.name.toLowerCase() === spellName) || {};
  66. if (!item.slot) {
  67. let sprite = [10, 0];
  68. let statType = spell.statType;
  69. if (statType === 'dex')
  70. sprite = [10, 1];
  71. else if (statType === 'str')
  72. sprite = [10, 2];
  73. else if (statType instanceof Array) {
  74. if ((statType.indexOf('dex') > -1) && (statType.indexOf('int') > -1))
  75. sprite = [10, 3];
  76. else if ((statType.indexOf('str') > -1) && (statType.indexOf('int') > -1))
  77. sprite = [10, 4];
  78. }
  79. item.name = 'Rune of ' + spellAesthetic.name;
  80. item.ability = true;
  81. item.sprite = sprite;
  82. } else if (spellQuality === 'basic')
  83. item.stats = {};
  84. if (blueprint.spellConfig)
  85. spellAesthetic = extend({}, spellAesthetic, blueprint.spellConfig);
  86. item.spell = {
  87. name: spellAesthetic.name || 'Weapon Damage',
  88. type: spellAesthetic.type || spellName,
  89. rolls: {},
  90. values: {}
  91. };
  92. if (blueprint.spellConfig)
  93. extend(item.spell, blueprint.spellConfig);
  94. if (item.type) {
  95. let typeConfig = configTypes.types[item.slot][item.type];
  96. if (typeConfig)
  97. extend(spell, typeConfig.spellConfig);
  98. }
  99. //If the item has a slot, we need to generate a new quality for the rune
  100. let quality = item.quality;
  101. if (item.slot) {
  102. const tempItem = {};
  103. const tempBlueprint = extend(blueprint);
  104. delete tempBlueprint.quality;
  105. tempBlueprint.quality = blueprint.spellQuality;
  106. qualityGenerator.generate(tempItem, tempBlueprint);
  107. quality = tempItem.quality;
  108. item.spell.quality = quality;
  109. }
  110. const rolls = buildRolls(item, blueprint, spell, quality);
  111. item.spell.rolls = rolls;
  112. const values = buildValues(item);
  113. item.spell.values = values;
  114. if (blueprint.spellProperties) {
  115. item.spell.properties = {};
  116. for (let p in blueprint.spellProperties)
  117. item.spell.properties[p] = blueprint.spellProperties[p];
  118. }
  119. if (item.range) {
  120. item.spell.properties = item.spell.properties || {};
  121. item.spell.properties.range = item.range;
  122. }
  123. },
  124. buildValues
  125. };