Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 

427 řádky
9.8 KiB

  1. define([
  2. 'items/generator',
  3. 'items/generators/stats',
  4. 'config/skins'
  5. ], function (
  6. generator,
  7. statGenerator,
  8. skins
  9. ) {
  10. return {
  11. type: 'trade',
  12. items: [],
  13. buyback: {},
  14. maxBuyback: 10,
  15. gold: 0,
  16. target: null,
  17. markup: {
  18. buy: 1,
  19. sell: 1
  20. },
  21. init: function (blueprint) {
  22. this.gold = blueprint.gold;
  23. (blueprint.forceItems || []).forEach(function (f, i) {
  24. var item = extend(true, {}, f);
  25. var id = 0;
  26. this.items.forEach(function (checkItem) {
  27. if (checkItem.id >= id)
  28. id = checkItem.id + 1;
  29. });
  30. if (item.type == 'skin') {
  31. var skinBlueprint = skins.getBlueprint(item.id);
  32. item.name = skinBlueprint.name;
  33. item.sprite = skinBlueprint.sprite;
  34. item.spritesheet = skinBlueprint.spritesheet;
  35. item.skinId = skinBlueprint.id;
  36. }
  37. item.id = id;
  38. this.items.push(item);
  39. }, this);
  40. if (!blueprint.items)
  41. return;
  42. this.markup = blueprint.markup;
  43. if (blueprint.faction) {
  44. this.obj.extendComponent('trade', 'factionVendor', blueprint);
  45. return;
  46. }
  47. var itemCount = blueprint.items.min + ~~(Math.random() * (blueprint.items.max - blueprint.items.min));
  48. for (var i = 0; i < itemCount; i++) {
  49. var level = 1;
  50. if (blueprint.level)
  51. level = blueprint.level.min + ~~(Math.random() * (blueprint.level.max - blueprint.level.min));
  52. var item = generator.generate({
  53. noSpell: true,
  54. level: level
  55. });
  56. var id = 0;
  57. this.items.forEach(function (checkItem) {
  58. if (checkItem.id >= id)
  59. id = checkItem.id + 1;
  60. });
  61. item.id = id;
  62. this.items.push(item);
  63. }
  64. },
  65. startBuy: function (msg) {
  66. var target = msg.target;
  67. if ((target == null) && (!msg.targetName))
  68. return false;
  69. if ((target != null) && (target.id == null))
  70. target = this.obj.instance.objects.objects.find(o => o.id == target);
  71. else if (msg.targetName)
  72. target = this.obj.instance.objects.objects.find(o => ((o.name) && (o.name.toLowerCase() == msg.targetName.toLowerCase())));
  73. this.target = null;
  74. if ((!target) || (!target.trade))
  75. return false;
  76. this.target = target;
  77. var itemList = target.trade.getItems(this.obj);
  78. var markup = target.trade.markup.sell;
  79. if (msg.action == 'buyback') {
  80. itemList = target.trade.buyback[this.obj.name] || [];
  81. markup = target.trade.markup.buy;
  82. }
  83. this.obj.syncer.set(true, 'trade', 'buyList', {
  84. markup: markup,
  85. items: itemList,
  86. buyback: (msg.action == 'buyback')
  87. });
  88. },
  89. buySell: function (msg) {
  90. if (msg.action == 'buy')
  91. this.buy(msg);
  92. else if (msg.action == 'sell')
  93. this.sell(msg);
  94. else if (msg.action == 'buyback')
  95. this.buyback(msg);
  96. },
  97. buy: function (msg) {
  98. var target = this.target;
  99. if (!target)
  100. return;
  101. var item = null
  102. var targetTrade = target.trade;
  103. var markup = targetTrade.markup.sell;
  104. if (msg.action == 'buyback') {
  105. item = targetTrade.findBuyback(msg.itemId, this.obj.name);
  106. markup = targetTrade.markup.buy;
  107. } else
  108. item = targetTrade.findItem(msg.itemId, this.obj.name);
  109. if (!item) {
  110. this.resolveCallback(msg);
  111. return;
  112. }
  113. var canAfford = false;
  114. if (item.worth.currency) {
  115. var currencyItem = this.obj.inventory.items.find(i => (i.name == item.worth.currency));
  116. canAfford = ((currencyItem) && (currencyItem.quantity >= item.worth.amount));
  117. } else
  118. canAfford = this.gold >= ~~(item.worth * markup);
  119. if (!canAfford) {
  120. this.obj.instance.syncer.queue('onGetMessages', {
  121. id: this.obj.id,
  122. messages: [{
  123. class: 'color-redA',
  124. message: `you can't afford that item`,
  125. type: 'info'
  126. }]
  127. }, [this.obj.serverId]);
  128. this.resolveCallback(msg);
  129. return;
  130. }
  131. if (!targetTrade.canBuy(msg.itemId, this.obj, msg.action)) {
  132. this.resolveCallback(msg);
  133. return;
  134. }
  135. if (item.type == 'skin') {
  136. var haveSkin = this.obj.auth.doesOwnSkin(item.skinId);
  137. if (haveSkin) {
  138. this.obj.instance.syncer.queue('onGetMessages', {
  139. id: this.obj.id,
  140. messages: [{
  141. class: 'color-redA',
  142. message: `you have already unlocked that skin`,
  143. type: 'info'
  144. }]
  145. }, [this.obj.serverId]);
  146. this.resolveCallback(msg);
  147. return;
  148. }
  149. }
  150. if (msg.action == 'buyback')
  151. targetTrade.removeBuyback(msg.itemId, this.obj.name);
  152. else if ((item.type != 'skin') && (!item.infinite))
  153. targetTrade.removeItem(msg.itemId, this.obj.name);
  154. if (item.worth.currency) {
  155. var currencyItem = this.obj.inventory.items.find(i => (i.name == item.worth.currency));
  156. this.obj.inventory.destroyItem(currencyItem.id, item.worth.amount, true);
  157. } else {
  158. targetTrade.gold += ~~(item.worth * markup);
  159. this.gold -= ~~(item.worth * markup);
  160. this.obj.syncer.set(true, 'trade', 'gold', this.gold);
  161. }
  162. if (item.type != 'skin') {
  163. if (!item.infinite)
  164. this.obj.syncer.setArray(true, 'trade', 'removeItems', item.id);
  165. var clonedItem = extend(true, {}, item);
  166. if (item.worth.currency)
  167. clonedItem.worth = 0;
  168. if ((item.stats) && (item.stats.stats)) {
  169. delete clonedItem.stats;
  170. statGenerator.generate(clonedItem, {});
  171. }
  172. delete clonedItem.infinite;
  173. if (clonedItem.generate) {
  174. clonedItem = generator.generate(clonedItem);
  175. delete clonedItem.generate;
  176. if (item.factions)
  177. clonedItem.factions = item.factions;
  178. }
  179. this.obj.inventory.getItem(clonedItem);
  180. } else {
  181. this.obj.auth.saveSkin(item.skinId);
  182. this.obj.instance.syncer.queue('onGetMessages', {
  183. id: this.obj.id,
  184. messages: [{
  185. class: 'color-greenB',
  186. message: 'Unlocked skin: ' + item.name,
  187. type: 'info'
  188. }]
  189. }, [this.obj.serverId]);
  190. }
  191. //Hack to always redraw the UI (to give items the red overlay if they can't be afforded)
  192. this.obj.syncer.setArray(true, 'trade', 'redraw', true);
  193. this.resolveCallback(msg);
  194. },
  195. buyback: function (msg) {
  196. msg.action = 'buyback';
  197. this.buy(msg);
  198. },
  199. sell: function (msg) {
  200. var target = this.target;
  201. if (!target)
  202. return;
  203. var targetTrade = target.trade;
  204. var item = this.obj.inventory.destroyItem(msg.itemId, 1);
  205. if (!item)
  206. return;
  207. var worth = ~~(item.worth * targetTrade.markup.buy);
  208. this.gold += worth;
  209. this.obj.syncer.set(true, 'trade', 'gold', this.gold);
  210. this.obj.syncer.setArray(true, 'trade', 'removeItems', item.id);
  211. var buyback = this.buyback;
  212. var name = this.obj.name;
  213. if (!buyback[name])
  214. buyback[name] = [];
  215. buyback[name].push(item);
  216. if (buyback[name].length > this.maxBuyback)
  217. buyback[name].splice(0, 1);
  218. },
  219. startSell: function (msg) {
  220. var target = msg.target;
  221. var targetName = (msg.targetName || '').toLowerCase();
  222. if ((target == null) && (!targetName))
  223. return false;
  224. if ((target != null) && (target.id == null))
  225. target = this.obj.instance.objects.objects.find(o => o.id == target);
  226. else if (targetName != null)
  227. target = this.obj.instance.objects.objects.find(o => ((o.name) && (o.name.toLowerCase() == targetName)));
  228. this.target = null;
  229. if ((!target) || (!target.trade))
  230. return false;
  231. this.target = target;
  232. var reputation = this.obj.reputation;
  233. var itemList = this.obj.inventory.items
  234. .filter(i => ((i.worth > 0) && (!i.eq)));
  235. itemList = extend(true, [], itemList);
  236. this.obj.syncer.set(true, 'trade', 'sellList', {
  237. markup: target.trade.markup.buy,
  238. items: itemList
  239. .map(function (i) {
  240. if (i.factions) {
  241. i.factions = i.factions.map(function (f) {
  242. var faction = reputation.getBlueprint(f.id);
  243. var factionTier = reputation.getTier(f.id);
  244. var noEquip = null;
  245. if (factionTier < f.tier)
  246. noEquip = true;
  247. return {
  248. name: faction.name,
  249. tier: f.tier,
  250. tierName: ['Hated', 'Hostile', 'Unfriendly', 'Neutral', 'Friendly', 'Honored', 'Revered', 'Exalted'][f.tier],
  251. noEquip: noEquip
  252. };
  253. }, this);
  254. }
  255. return i;
  256. })
  257. });
  258. },
  259. startBuyback: function (msg) {
  260. msg.action = 'buyback';
  261. this.startBuy(msg);
  262. },
  263. removeItem: function (itemId) {
  264. return this.items.spliceFirstWhere(i => i.id == itemId);
  265. },
  266. removeBuyback: function (itemId, name) {
  267. return (this.buyback[name] || []).spliceFirstWhere(i => i.id == itemId);
  268. },
  269. getItems: function (requestedBy) {
  270. var reputation = requestedBy.reputation;
  271. var items = this.items.map(function (i) {
  272. var item = extend(true, {}, i);
  273. if (item.factions) {
  274. item.factions = item.factions.map(function (f) {
  275. var faction = reputation.getBlueprint(f.id);
  276. var factionTier = reputation.getTier(f.id);
  277. var noEquip = null;
  278. if (factionTier < f.tier)
  279. noEquip = true;
  280. return {
  281. name: faction.name,
  282. tier: f.tier,
  283. tierName: ['Hated', 'Hostile', 'Unfriendly', 'Neutral', 'Friendly', 'Honored', 'Revered', 'Exalted'][f.tier],
  284. noEquip: noEquip
  285. };
  286. }, this);
  287. }
  288. return item;
  289. });
  290. return items;
  291. },
  292. canBuy: function (itemId, requestedBy, action) {
  293. return true;
  294. },
  295. findItem: function (itemId, sourceName) {
  296. return this.items.find(i => i.id == itemId);
  297. },
  298. findBuyback: function (itemId, sourceName) {
  299. return (this.buyback[sourceName] || []).find(i => i.id == itemId);
  300. },
  301. resolveCallback: function (msg, result) {
  302. var callbackId = (msg.callbackId != null) ? msg.callbackId : msg;
  303. result = result || [];
  304. if (callbackId == null)
  305. return;
  306. this.obj.instance.syncer.queue('serverModule', {
  307. module: 'atlas',
  308. method: 'resolveCallback',
  309. msg: {
  310. id: callbackId,
  311. result: result
  312. }
  313. });
  314. },
  315. simplify: function (self) {
  316. var result = {
  317. type: 'trade'
  318. };
  319. if (self)
  320. result.gold = this.gold;
  321. return result;
  322. },
  323. events: {
  324. beforeMove: function () {
  325. if (!this.target)
  326. return;
  327. this.obj.syncer.set(true, 'trade', 'closeTrade', true);
  328. this.target = null;
  329. }
  330. }
  331. };
  332. });