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.
 
 
 

220 lines
4.2 KiB

  1. const mobBuilder = require('./mobBuilder');
  2. const animations = require('../config/animations');
  3. const scheduler = require('../misc/scheduler');
  4. module.exports = {
  5. list: [],
  6. mobTypes: {},
  7. init: function (msg) {
  8. this.objects = msg.objects;
  9. this.syncer = msg.syncer;
  10. this.zoneConfig = msg.zoneConfig;
  11. },
  12. reset: function () {
  13. this.list = [];
  14. this.mobTypes = {};
  15. },
  16. register: function (blueprint, cdMax) {
  17. const spawner = extend({
  18. cdMax: cdMax || 171,
  19. cron: blueprint.cron,
  20. lifetime: blueprint.lifetime,
  21. blueprint: blueprint,
  22. amountLeft: blueprint.amount || -1
  23. });
  24. this.list.push(spawner);
  25. if (blueprint.layerName !== 'mobs')
  26. return;
  27. const name = blueprint.name.toLowerCase();
  28. if (!this.mobTypes[name])
  29. this.mobTypes[name] = 1;
  30. else
  31. this.mobTypes[name]++;
  32. spawner.zonePrint = extend({}, this.zoneConfig.mobs.default, this.zoneConfig.mobs[name] || {});
  33. },
  34. spawn: function (spawner) {
  35. if (spawner.amountLeft === 0)
  36. return;
  37. const blueprint = spawner.blueprint;
  38. const obj = this.objects.buildObjects([blueprint]);
  39. let customSpawn = false;
  40. const sheetName = blueprint.sheetName;
  41. if ((sheetName) && (blueprint.sheetName.indexOf('/'))) {
  42. const spawnAnimation = _.getDeepProperty(animations, ['mobs', sheetName, blueprint.cell, 'spawn']);
  43. if (spawnAnimation) {
  44. customSpawn = true;
  45. this.syncer.queue('onGetObject', {
  46. id: obj.id,
  47. components: [spawnAnimation]
  48. }, -1);
  49. }
  50. }
  51. if (!customSpawn) {
  52. this.syncer.queue('onGetObject', {
  53. x: obj.x,
  54. y: obj.y,
  55. components: [{
  56. type: 'attackAnimation',
  57. row: 0,
  58. col: 4
  59. }]
  60. }, -1);
  61. }
  62. if (spawner.amountLeft !== -1)
  63. spawner.amountLeft--;
  64. return obj;
  65. },
  66. update: function () {
  67. const spawners = this.list;
  68. let count = spawners.length;
  69. for (let i = 0; i < count; i++) {
  70. const l = spawners[i];
  71. if (l.destroyed) {
  72. spawners.splice(i, 1);
  73. i--;
  74. count--;
  75. continue;
  76. }
  77. if (l.lifetime && l.mob) {
  78. if (!l.age)
  79. l.age = 1;
  80. else
  81. l.age++;
  82. if (l.age >= l.lifetime) {
  83. this.syncer.queue('onGetObject', {
  84. x: l.mob.x,
  85. y: l.mob.y,
  86. components: [{
  87. type: 'attackAnimation',
  88. row: 0,
  89. col: 4
  90. }]
  91. }, -1);
  92. l.mob.destroyed = true;
  93. }
  94. }
  95. if (!l.cron) {
  96. if (l.cd > 0)
  97. l.cd--;
  98. else if (l.mob && l.mob.destroyed)
  99. l.cd = l.cdMax;
  100. }
  101. if (l.mob && l.mob.destroyed) {
  102. delete l.age;
  103. delete l.mob;
  104. }
  105. const cronInfo = {
  106. cron: l.cron,
  107. lastRun: l.lastRun
  108. };
  109. const doSpawn = (
  110. (
  111. !l.cron &&
  112. !l.cd
  113. ) || (
  114. l.cron &&
  115. !l.mob &&
  116. scheduler.shouldRun(cronInfo)
  117. )
  118. );
  119. if (doSpawn) {
  120. if (!l.cron)
  121. l.cd = -1;
  122. else
  123. l.lastRun = cronInfo.lastRun;
  124. const mob = this.spawn(l);
  125. if (!mob)
  126. continue;
  127. const name = (l.blueprint.objZoneName || l.blueprint.name).toLowerCase();
  128. if (l.blueprint.layerName === 'mobs')
  129. this.setupMob(mob, l.zonePrint);
  130. else {
  131. const blueprint = extend({}, this.zoneConfig.objects.default, this.zoneConfig.objects[name] || {});
  132. this.setupObj(mob, blueprint);
  133. }
  134. if (l.blueprint.objZoneName)
  135. mob.objZoneName = l.blueprint.objZoneName;
  136. l.mob = mob;
  137. }
  138. }
  139. },
  140. setupMob: function (mob, blueprint) {
  141. let type = 'regular';
  142. if (blueprint.rare.count > 0) {
  143. const rareCount = this.list.filter(l => (
  144. (l.mob) &&
  145. (!l.mob.destroyed) &&
  146. (l.mob.isRare) &&
  147. (l.mob.baseName === mob.name)
  148. ));
  149. if (rareCount.length < blueprint.rare.count) {
  150. const roll = Math.random() * 100;
  151. if (roll < blueprint.rare.chance)
  152. type = 'rare';
  153. }
  154. }
  155. this.setupObj(mob, blueprint);
  156. mobBuilder.build(mob, blueprint, type, this.zoneConfig.name);
  157. },
  158. setupObj: function (obj, blueprint) {
  159. const cpns = blueprint.components;
  160. if (!cpns)
  161. return;
  162. for (let c in cpns) {
  163. const cpn = cpns[c];
  164. let cType = c.replace('cpn', '');
  165. cType = cType[0].toLowerCase() + cType.substr(1);
  166. const builtCpn = obj.addComponent(cType, cpn);
  167. if (cpn.simplify)
  168. builtCpn.simplify = cpn.simplify.bind(builtCpn);
  169. }
  170. },
  171. destroySpawnerForObject: function (obj) {
  172. const spawner = this.list.find(l => l.mob === obj);
  173. if (spawner)
  174. spawner.destroyed = true;
  175. }
  176. };