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.
 
 
 

313 lines
6.9 KiB

  1. let qualityGenerator = require('../items/generators/quality');
  2. module.exports = {
  3. type: 'gatherer',
  4. nodes: [],
  5. gathering: null,
  6. gatheringTtl: 0,
  7. gatheringTtlMax: 7,
  8. defaultTtlMax: 7,
  9. simplify: function () {
  10. return {
  11. type: 'gatherer'
  12. };
  13. },
  14. gather: function () {
  15. if (this.gathering)
  16. return;
  17. let nodes = this.nodes;
  18. if (nodes.length === 0)
  19. return;
  20. let firstNode = nodes[0];
  21. this.gathering = firstNode;
  22. let ttlMax = firstNode.resourceNode.ttl || this.defaultTtlMax;
  23. if (firstNode.resourceNode.nodeType === 'fish') {
  24. let rod = this.obj.equipment.eq.tool;
  25. if (!rod) {
  26. process.send({
  27. method: 'events',
  28. data: {
  29. onGetAnnouncement: [{
  30. obj: {
  31. msg: 'You need a fishing rod to fish'
  32. },
  33. to: [this.obj.serverId]
  34. }]
  35. }
  36. });
  37. this.gathering = null;
  38. return;
  39. }
  40. rod = this.obj.inventory.findItem(rod);
  41. let statCatchSpeed = Math.min(150, this.obj.stats.values.catchSpeed);
  42. ttlMax *= (1 - (statCatchSpeed / 200));
  43. }
  44. this.gatheringTtlMax = ttlMax;
  45. this.gatheringTtl = this.gatheringTtlMax;
  46. },
  47. update: function () {
  48. let gathering = this.gathering;
  49. if (!gathering)
  50. return;
  51. if (gathering.destroyed) {
  52. this.gathering = null;
  53. this.gatheringTtl = 0;
  54. this.obj.syncer.set(false, 'gatherer', 'progress', 100);
  55. this.obj.syncer.set(true, 'gatherer', 'progress', 100);
  56. this.obj.syncer.set(true, 'gatherer', 'action', 'Fishing');
  57. return;
  58. }
  59. let isFish = (gathering.resourceNode.nodeType === 'fish');
  60. if (this.gatheringTtl > 0) {
  61. if ((this.gatheringTtl === this.gatheringTtlMax) && (gathering.width)) {
  62. ['x', 'y', 'width', 'height'].forEach(function (p) {
  63. this.obj.syncer.set(false, 'gatherer', p, gathering[p]);
  64. }, this);
  65. }
  66. this.gatheringTtl--;
  67. let progress = 100 - ~~((this.gatheringTtl / this.gatheringTtlMax) * 100);
  68. this.obj.syncer.set(true, 'gatherer', 'progress', progress);
  69. if (isFish)
  70. this.obj.syncer.set(true, 'gatherer', 'action', 'Fishing');
  71. return;
  72. }
  73. let resourceNode = gathering.resourceNode;
  74. let gatherResult = extend({
  75. obj: gathering
  76. }, {
  77. nodeType: resourceNode.nodeType,
  78. blueprint: resourceNode.blueprint,
  79. xp: resourceNode.xp,
  80. items: gathering.inventory.items
  81. });
  82. this.obj.instance.eventEmitter.emitNoSticky('beforeGatherResource', gatherResult, this.obj);
  83. this.obj.fireEvent('beforeGatherResource', gatherResult, this.obj);
  84. this.obj.syncer.set(false, 'gatherer', 'progress', 100);
  85. if (isFish) {
  86. let catchChance = 40 + this.obj.stats.values.catchChance;
  87. if (~~(Math.random() * 100) >= catchChance) {
  88. process.send({
  89. method: 'events',
  90. data: {
  91. onGetAnnouncement: [{
  92. obj: {
  93. msg: 'The fish got away'
  94. },
  95. to: [this.obj.serverId]
  96. }]
  97. }
  98. });
  99. this.gathering = null;
  100. return;
  101. }
  102. gatherResult.items.forEach(function (g) {
  103. delete g.quantity;
  104. qualityGenerator.generate(g, {
  105. //100 x 2.86 = 2000 (chance for a common)
  106. bonusMagicFind: this.obj.stats.values.fishRarity * 2.82
  107. });
  108. g.name = {
  109. 0: '',
  110. 1: 'Big ',
  111. 2: 'Giant ',
  112. 3: 'Trophy ',
  113. 4: 'Fabled '
  114. }[g.quality] + g.name;
  115. let statFishWeight = 1 + (this.obj.stats.values.fishWeight / 100);
  116. let weight = ~~((gatherResult.blueprint.baseWeight + g.quality + (Math.random() * statFishWeight)) * 100) / 100;
  117. g.stats = {
  118. weight: weight
  119. };
  120. g.worth = ~~(weight * 10);
  121. }, this);
  122. }
  123. if (isFish) {
  124. let itemChance = 1 + this.obj.stats.values.fishItems;
  125. if (~~(Math.random() * 100) < itemChance) {
  126. gatherResult.items = [{
  127. name: 'Cerulean Pearl',
  128. material: true,
  129. quantity: 1,
  130. quality: 3,
  131. sprite: [11, 9]
  132. }];
  133. }
  134. }
  135. let blueprint = gatherResult.blueprint;
  136. gatherResult.items.forEach(function (item, i) {
  137. delete item.pos;
  138. if (i === 0) {
  139. if (blueprint.itemName)
  140. item.name = blueprint.itemName;
  141. if (blueprint.itemAmount)
  142. item.quantity = ~~(Math.random() * blueprint.itemAmount[1]) + blueprint.itemAmount[0];
  143. }
  144. this.obj.inventory.getItem(item);
  145. if (item.material)
  146. this.obj.fireEvent('afterGatherResource', gatherResult);
  147. }, this);
  148. if (!gatherResult.noChangeAmount)
  149. resourceNode.gather();
  150. this.obj.stats.getXp(gatherResult.xp, this.obj, gatherResult.obj);
  151. if (gathering.destroyed) {
  152. if (isFish) {
  153. process.send({
  154. method: 'events',
  155. data: {
  156. onGetAnnouncement: [{
  157. obj: {
  158. msg: 'The school has been depleted'
  159. },
  160. to: [this.obj.serverId]
  161. }]
  162. }
  163. });
  164. }
  165. this.nodes.spliceWhere(n => (n === gathering));
  166. }
  167. this.gathering = null;
  168. },
  169. enter: function (node) {
  170. let gatherResult = extend({
  171. nodeName: node.name
  172. });
  173. this.obj.instance.eventEmitter.emitNoSticky('beforeEnterPool', gatherResult, this.obj);
  174. let nodeType = node.resourceNode.nodeType;
  175. let msg = `Press G to $ (${gatherResult.nodeName})`;
  176. msg = msg.replace('$', {
  177. herb: 'gather',
  178. fish: 'fish for'
  179. }[nodeType]);
  180. if (nodeType === 'fish') {
  181. if (!this.obj.equipment.eq.has('tool'))
  182. msg = 'You need a fishing rod to fish';
  183. }
  184. process.send({
  185. method: 'events',
  186. data: {
  187. onGetAnnouncement: [{
  188. obj: {
  189. msg: msg
  190. },
  191. to: [this.obj.serverId]
  192. }]
  193. }
  194. });
  195. this.nodes.spliceWhere(n => (n === node));
  196. this.nodes.push(node);
  197. },
  198. exit: function (node) {
  199. this.nodes.spliceWhere(n => (n === node));
  200. },
  201. events: {
  202. beforeRezone: function () {
  203. this.events.beforeMove.call(this);
  204. },
  205. beforeMove: function () {
  206. if (!this.gathering)
  207. return;
  208. ['x', 'y', 'width', 'height'].forEach(function (p) {
  209. this.obj.syncer.delete(false, 'gatherer', p);
  210. }, this);
  211. this.obj.syncer.set(true, 'gatherer', 'progress', 100);
  212. this.obj.syncer.set(false, 'gatherer', 'progress', 100);
  213. if (this.gathering.resourceNode.nodeType === 'fish')
  214. this.obj.syncer.set(true, 'gatherer', 'action', 'Fishing');
  215. this.gathering = null;
  216. },
  217. afterEquipItem: function (item) {
  218. let nodes = this.nodes;
  219. let nLen = nodes.length;
  220. for (let i = 0; i < nLen; i++) {
  221. let node = nodes[i];
  222. if (item.slot !== 'tool')
  223. continue;
  224. if (node.resourceNode.nodeType === 'fish') {
  225. if (!this.obj.equipment.eq.has('tool')) {
  226. process.send({
  227. method: 'events',
  228. data: {
  229. onGetAnnouncement: [{
  230. obj: {
  231. msg: 'You need a fishing rod to fish'
  232. },
  233. to: [this.obj.serverId]
  234. }]
  235. }
  236. });
  237. if (this.gathering === node) {
  238. if (this.gathering.resourceNode.nodeType === 'fish')
  239. this.obj.syncer.set(true, 'gatherer', 'action', 'Fishing');
  240. this.gathering = null;
  241. this.obj.syncer.set(true, 'gatherer', 'progress', 100);
  242. this.obj.syncer.set(false, 'gatherer', 'progress', 100);
  243. }
  244. }
  245. }
  246. }
  247. },
  248. afterUnequipItem: function (item) {
  249. this.events.afterEquipItem.call(this, item);
  250. }
  251. }
  252. };