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.
 
 
 

207 lines
4.3 KiB

  1. let herbs = require('../config/herbs');
  2. const defaultGatherChance = {
  3. herb: 100,
  4. fish: 40
  5. };
  6. module.exports = {
  7. nodes: [],
  8. objects: null,
  9. syncer: null,
  10. zoneConfig: null,
  11. physics: null,
  12. map: null,
  13. cdMax: 171,
  14. init: function (instance) {
  15. Object.assign(this, {
  16. objects: instance.objects,
  17. syncer: instance.syncer,
  18. physics: instance.physics,
  19. map: instance.map,
  20. zoneConfig: instance.zoneConfig
  21. });
  22. },
  23. register: function (name, blueprint) {
  24. const exists = this.nodes.find(n => (n.blueprint.name === name));
  25. if (exists) {
  26. if (!exists.blueprint.positions) {
  27. exists.blueprint.positions = [{
  28. x: exists.blueprint.x,
  29. y: exists.blueprint.y,
  30. width: exists.blueprint.width,
  31. height: exists.blueprint.height
  32. }];
  33. }
  34. exists.blueprint.positions.push({
  35. x: blueprint.x,
  36. y: blueprint.y,
  37. width: blueprint.width,
  38. height: blueprint.height
  39. });
  40. return;
  41. }
  42. blueprint = extend({}, blueprint, herbs[name], {
  43. name: name
  44. });
  45. const max = blueprint.max;
  46. delete blueprint.max;
  47. const chance = blueprint.chance;
  48. delete blueprint.chance;
  49. const cdMax = blueprint.cdMax;
  50. delete blueprint.cdMax;
  51. blueprint.gatherChance = blueprint.gatherChance ?? defaultGatherChance[blueprint.type];
  52. this.nodes.push({
  53. cd: 0,
  54. max,
  55. chance,
  56. cdMax,
  57. blueprint,
  58. spawns: []
  59. });
  60. },
  61. getRandomSpawnPosition: function (node, blueprint) {
  62. //Get an accessible position
  63. let w = this.physics.width;
  64. let h = this.physics.height;
  65. let x = blueprint.x;
  66. let y = blueprint.y;
  67. let position = null;
  68. if (blueprint.type === 'herb' && !blueprint.positions) {
  69. x = ~~(Math.random() * w);
  70. y = ~~(Math.random() * h);
  71. if (this.physics.isTileBlocking(x, y))
  72. return false;
  73. let spawn = this.map.spawn[0];
  74. let path = this.physics.getPath(spawn, {
  75. x: x,
  76. y: y
  77. });
  78. let endTile = path[path.length - 1];
  79. if (!endTile)
  80. return false;
  81. else if ((endTile.x !== x) || (endTile.y !== y))
  82. return false;
  83. //Don't spawn in rooms or on objects/other resources
  84. let cell = this.physics.getCell(x, y);
  85. if (cell.length > 0)
  86. return false;
  87. position = { x, y };
  88. } else if (blueprint.positions) {
  89. //Find all possible positions in which a node hasn't spawned yet
  90. position = blueprint.positions.filter(f => !node.spawns.some(s => ((s.x === f.x) && (s.y === f.y))));
  91. if (position.length === 0)
  92. return false;
  93. position = position[~~(Math.random() * position.length)];
  94. }
  95. return position;
  96. },
  97. spawn: function (node) {
  98. let blueprint = node.blueprint;
  99. let position = this.getRandomSpawnPosition(node, blueprint);
  100. if (!position)
  101. return false;
  102. let quantity = 1;
  103. if (blueprint.quantity)
  104. quantity = blueprint.quantity[0] + ~~(Math.random() * (blueprint.quantity[1] - blueprint.quantity[0]));
  105. let zoneLevel = this.zoneConfig.level;
  106. zoneLevel = ~~(zoneLevel[0] + ((zoneLevel[1] - zoneLevel[0]) / 2));
  107. let objBlueprint = extend({}, blueprint, position);
  108. objBlueprint.properties = {
  109. cpnResourceNode: {
  110. nodeType: blueprint.type,
  111. ttl: blueprint.ttl,
  112. xp: zoneLevel * zoneLevel,
  113. blueprint: extend({}, blueprint),
  114. quantity: quantity
  115. }
  116. };
  117. let obj = this.objects.buildObjects([objBlueprint]);
  118. delete obj.ttl;
  119. if (blueprint.type === 'herb') {
  120. this.syncer.queue('onGetObject', {
  121. x: obj.x,
  122. y: obj.y,
  123. components: [{
  124. type: 'attackAnimation',
  125. row: 0,
  126. col: 4
  127. }]
  128. }, -1);
  129. }
  130. let inventory = obj.addComponent('inventory');
  131. obj.layerName = 'objects';
  132. node.spawns.push(obj);
  133. let item = {
  134. material: true,
  135. type: node.type || null,
  136. sprite: node.blueprint.itemSprite,
  137. name: node.blueprint.name,
  138. quantity: (blueprint.type !== 'fish') ? 1 : null,
  139. quality: 0
  140. };
  141. if (blueprint.itemSheet)
  142. item.spritesheet = blueprint.itemSheet;
  143. if (blueprint.type === 'fish')
  144. item.noStack = true;
  145. inventory.getItem(item);
  146. return true;
  147. },
  148. update: function () {
  149. let nodes = this.nodes;
  150. let nLen = nodes.length;
  151. for (let i = 0; i < nLen; i++) {
  152. let node = nodes[i];
  153. let spawns = node.spawns;
  154. spawns.spliceWhere(f => f.destroyed);
  155. if (spawns.length < node.max) {
  156. if (node.cd > 0)
  157. node.cd--;
  158. else if ((!node.chance || Math.random() < node.chance) && this.spawn(node))
  159. node.cd = node.cdMax || this.cdMax;
  160. }
  161. }
  162. }
  163. };