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.
 
 
 

206 lines
4.2 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. const nodeXp = this.zoneConfig.level[0] * 2;
  106. let objBlueprint = extend({}, blueprint, position);
  107. objBlueprint.properties = {
  108. cpnResourceNode: {
  109. nodeType: blueprint.type,
  110. ttl: blueprint.ttl,
  111. xp: nodeXp,
  112. blueprint: extend({}, blueprint),
  113. quantity: quantity
  114. }
  115. };
  116. let obj = this.objects.buildObjects([objBlueprint]);
  117. delete obj.ttl;
  118. if (blueprint.type === 'herb') {
  119. this.syncer.queue('onGetObject', {
  120. x: obj.x,
  121. y: obj.y,
  122. components: [{
  123. type: 'attackAnimation',
  124. row: 0,
  125. col: 4
  126. }]
  127. }, -1);
  128. }
  129. let inventory = obj.addComponent('inventory');
  130. obj.layerName = 'objects';
  131. node.spawns.push(obj);
  132. let item = {
  133. material: true,
  134. type: node.type || null,
  135. sprite: node.blueprint.itemSprite,
  136. name: node.blueprint.name,
  137. quantity: (blueprint.type !== 'fish') ? 1 : null,
  138. quality: 0
  139. };
  140. if (blueprint.itemSheet)
  141. item.spritesheet = blueprint.itemSheet;
  142. if (blueprint.type === 'fish')
  143. item.noStack = true;
  144. inventory.getItem(item);
  145. return true;
  146. },
  147. update: function () {
  148. let nodes = this.nodes;
  149. let nLen = nodes.length;
  150. for (let i = 0; i < nLen; i++) {
  151. let node = nodes[i];
  152. let spawns = node.spawns;
  153. spawns.spliceWhere(f => f.destroyed);
  154. if (spawns.length < node.max) {
  155. if (node.cd > 0)
  156. node.cd--;
  157. else if ((!node.chance || Math.random() < node.chance) && this.spawn(node))
  158. node.cd = node.cdMax || this.cdMax;
  159. }
  160. }
  161. }
  162. };