Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 

1016 Zeilen
22 KiB

  1. define([
  2. 'items/generator',
  3. 'items/salvager',
  4. 'items/enchanter',
  5. 'objects/objects',
  6. 'config/classes',
  7. 'mtx/mtx',
  8. 'config/factions',
  9. 'misc/events',
  10. 'items/itemEffects'
  11. ], function (
  12. generator,
  13. salvager,
  14. enchanter,
  15. objects,
  16. classes,
  17. mtx,
  18. factions,
  19. events,
  20. itemEffects
  21. ) {
  22. return {
  23. type: 'inventory',
  24. inventorySize: 50,
  25. items: [],
  26. blueprint: null,
  27. init: function (blueprint, isTransfer) {
  28. var items = blueprint.items || [];
  29. var iLen = items.length;
  30. //Spells should be sorted so they're EQ'd in the right order
  31. items.sort(function (a, b) {
  32. var aId = (a.spellId != null) ? ~~a.spellId : 9999;
  33. var bId = (b.spellId != null) ? ~~b.spellId : 9999;
  34. return (aId - bId);
  35. });
  36. for (var i = 0; i < iLen; i++) {
  37. var item = items[i];
  38. if ((item.pos >= this.inventorySize) || (item.eq))
  39. delete item.pos;
  40. while (item.name.indexOf(`''`) > -1) {
  41. item.name = item.name.replace(`''`, `'`);
  42. }
  43. }
  44. this.hookItemEvents(items);
  45. for (var i = 0; i < iLen; i++) {
  46. var item = items[i];
  47. var pos = item.pos;
  48. var newItem = this.getItem(item, true, true);
  49. newItem.pos = pos;
  50. }
  51. if ((this.obj.player) && (!isTransfer) && (this.obj.stats.values.level == 1))
  52. this.getDefaultAbilities();
  53. delete blueprint.items;
  54. this.blueprint = blueprint;
  55. },
  56. transfer: function () {
  57. this.hookItemEvents();
  58. },
  59. hookItemEvents: function (items) {
  60. var items = items || this.items;
  61. var iLen = items.length;
  62. for (var i = 0; i < iLen; i++) {
  63. var item = items[i];
  64. if (item.effects) {
  65. item.effects.forEach(function (e) {
  66. if (e.mtx) {
  67. var mtxUrl = mtx.get(e.mtx);
  68. var mtxModule = require(mtxUrl);
  69. e.events = mtxModule.events;
  70. } else if (e.factionId) {
  71. var faction = factions.getFaction(e.factionId);
  72. var statGenerator = faction.uniqueStat;
  73. statGenerator.generate(item);
  74. } else {
  75. var effectUrl = itemEffects.get(e.type);
  76. var effectModule = require(effectUrl);
  77. e.events = effectModule.events;
  78. }
  79. });
  80. }
  81. if ((item.pos == null) && (!item.eq)) {
  82. var pos = i;
  83. for (var j = 0; j < iLen; j++) {
  84. if (!items.some(fj => (fj.pos == j))) {
  85. pos = j;
  86. break;
  87. }
  88. }
  89. item.pos = pos;
  90. } else if ((!item.eq) && (items.some(ii => ((ii != item) && (ii.pos == item.pos))))) {
  91. var pos = item.pos;
  92. for (var j = 0; j < iLen; j++) {
  93. if (!items.some(fi => ((fi != item) && (fi.pos == j)))) {
  94. pos = j;
  95. break;
  96. }
  97. }
  98. item.pos = pos;
  99. }
  100. }
  101. },
  102. //Client Actions
  103. enchantItem: function (msg) {
  104. var item = this.findItem(msg.itemId);
  105. if ((!item) || (!item.slot) || (item.eq) || (item.noAugment) || ((msg.action == 'scour') && (item.power == 0))) {
  106. this.resolveCallback(msg);
  107. return;
  108. }
  109. enchanter.enchant(this.obj, item, msg);
  110. },
  111. getEnchantMaterials: function (msg) {
  112. var result = [];
  113. var item = this.findItem(msg.itemId);
  114. if ((item) && (item.slot))
  115. result = enchanter.getEnchantMaterials(item, msg.action);
  116. this.resolveCallback(msg, result);
  117. },
  118. learnAbility: function (itemId, runeSlot) {
  119. if (itemId.itemId != null) {
  120. var msg = itemId;
  121. itemId = msg.itemId;
  122. runeSlot = msg.slot;
  123. }
  124. var item = this.findItem(itemId);
  125. if (!item)
  126. return;
  127. else if (!item.spell) {
  128. item.eq = false;
  129. return;
  130. }
  131. var learnMsg = {
  132. success: true,
  133. item: item
  134. };
  135. this.obj.fireEvent('beforeLearnAbility', learnMsg);
  136. if (!learnMsg.success) {
  137. this.obj.instance.syncer.queue('onGetMessages', {
  138. id: this.obj.id,
  139. messages: [{
  140. class: 'q0',
  141. message: learnMsg.msg || 'you cannot learn that ability',
  142. type: 'info'
  143. }]
  144. }, [this.obj.serverId]);
  145. return;
  146. }
  147. var spellbook = this.obj.spellbook;
  148. if ((item.slot == 'twoHanded') || (item.slot == 'oneHanded'))
  149. runeSlot = 0;
  150. else if (runeSlot == null) {
  151. runeSlot = 3;
  152. for (var i = 1; i <= 3; i++) {
  153. if (!this.items.some(j => (j.runeSlot == i))) {
  154. runeSlot = i;
  155. break;
  156. }
  157. }
  158. }
  159. var currentEq = this.items.find(i => (i.runeSlot == runeSlot));
  160. if (currentEq) {
  161. spellbook.removeSpellById(runeSlot);
  162. delete currentEq.eq;
  163. delete currentEq.runeSlot;
  164. this.setItemPosition(currentEq.id);
  165. this.obj.syncer.setArray(true, 'inventory', 'getItems', currentEq);
  166. }
  167. item.eq = true;
  168. item.runeSlot = runeSlot;
  169. delete item.pos;
  170. spellbook.addSpellFromRune(item.spell, runeSlot);
  171. this.obj.syncer.setArray(true, 'inventory', 'getItems', item);
  172. },
  173. activateMtx: function (itemId) {
  174. var item = this.findItem(itemId);
  175. if (!item)
  176. return;
  177. else if (item.type != 'mtx') {
  178. delete item.active;
  179. return;
  180. }
  181. item.active = !item.active;
  182. this.obj.syncer.setArray(true, 'inventory', 'getItems', item);
  183. },
  184. splitStack: function (msg) {
  185. var item = this.findItem(msg.itemId);
  186. if (!item)
  187. return;
  188. else if ((!item.quantity) || (item.quantity <= msg.stackSize) || (msg.stackSize < 1))
  189. return;
  190. var newItem = extend(true, {}, item);
  191. item.quantity -= msg.stackSize;
  192. newItem.quantity = msg.stackSize;
  193. this.getItem(newItem, true, true);
  194. this.obj.syncer.setArray(true, 'inventory', 'getItems', item);
  195. },
  196. combineStacks: function (msg) {
  197. var fromItem = this.findItem(msg.fromId);
  198. var toItem = this.findItem(msg.toId);
  199. if ((!fromItem) || (!toItem))
  200. return;
  201. else if ((!fromItem.quantity) || (!toItem.quantity))
  202. return;
  203. toItem.quantity += fromItem.quantity;
  204. this.obj.syncer.setArray(true, 'inventory', 'getItems', toItem);
  205. this.destroyItem(fromItem.id, null, true);
  206. },
  207. useItem: function (itemId) {
  208. var item = this.findItem(itemId);
  209. if (!item)
  210. return;
  211. if (item.cdMax) {
  212. if (item.cd) {
  213. process.send({
  214. method: 'events',
  215. data: {
  216. 'onGetAnnouncement': [{
  217. obj: {
  218. msg: 'That item is on cooldown'
  219. },
  220. to: [this.obj.serverId]
  221. }]
  222. }
  223. });
  224. return;
  225. }
  226. item.cd = item.cdMax;
  227. //Find similar items and put them on cooldown too
  228. this.items.forEach(function (i) {
  229. if ((i.name == item.name) && (i.cdMax == item.cdMax))
  230. i.cd = i.cdMax;
  231. });
  232. }
  233. var result = {};
  234. events.emit('onBeforeUseItem', this.obj, item, result);
  235. if (item.type == 'consumable') {
  236. if (item.uses) {
  237. item.uses--;
  238. this.obj.syncer.setArray(true, 'inventory', 'getItems', item);
  239. return;
  240. }
  241. this.destroyItem(itemId, 1);
  242. }
  243. },
  244. unlearnAbility: function (itemId) {
  245. if (itemId.itemId != null)
  246. itemId = itemId.itemId;
  247. var item = this.findItem(itemId);
  248. if (!item)
  249. return;
  250. else if (!item.spell) {
  251. item.eq = false;
  252. return;
  253. }
  254. var spellbook = this.obj.spellbook;
  255. spellbook.removeSpellById(item.runeSlot);
  256. delete item.eq;
  257. delete item.runeSlot;
  258. if (!item.slot)
  259. this.setItemPosition(itemId);
  260. this.obj.syncer.setArray(true, 'inventory', 'getItems', item);
  261. },
  262. stashItem: function (id) {
  263. var item = this.findItem(id);
  264. if ((!item) || (item.quest) || (item.noStash))
  265. return;
  266. delete item.pos;
  267. var stash = this.obj.stash;
  268. if (!stash.active)
  269. return;
  270. var clonedItem = extend(true, {}, item);
  271. this.destroyItem(id, null, true);
  272. stash.deposit(clonedItem);
  273. },
  274. salvageItem: function (id) {
  275. var item = this.findItem(id);
  276. if ((!item) || (item.material) || (item.quest) || (item.noSalvage) || (item.eq))
  277. return;
  278. var messages = [];
  279. var items = salvager.salvage(item);
  280. var iLen = items.length;
  281. if (!iLen)
  282. return;
  283. for (var i = 0; i < iLen; i++) {
  284. var material = items[i];
  285. this.getItem(material, true);
  286. messages.push({
  287. class: 'q' + material.quality,
  288. message: 'salvage (' + material.name + ' x' + material.quantity + ')'
  289. });
  290. }
  291. this.obj.instance.syncer.queue('onGetMessages', {
  292. id: this.obj.id,
  293. messages: messages
  294. }, [this.obj.serverId]);
  295. this.destroyItem(id);
  296. },
  297. destroyItem: function (id, amount, force) {
  298. var item = this.findItem(id);
  299. if ((!item) || ((item.noDestroy) && (!force)))
  300. return;
  301. amount = amount || item.quantity;
  302. if (item.eq)
  303. this.obj.equipment.unequip(id);
  304. if ((item.quantity) && (amount)) {
  305. item.quantity -= amount;
  306. if (item.quantity <= 0) {
  307. this.items.spliceWhere(i => i.id == id);
  308. this.obj.syncer.setArray(true, 'inventory', 'destroyItems', id);
  309. } else
  310. this.obj.syncer.setArray(true, 'inventory', 'getItems', item);
  311. } else {
  312. this.items.spliceWhere(i => i.id == id);
  313. this.obj.syncer.setArray(true, 'inventory', 'destroyItems', id);
  314. }
  315. this.obj.fireEvent('afterDestroyItem', item, amount);
  316. return item;
  317. },
  318. dropItem: function (id) {
  319. var item = this.findItem(id);
  320. if ((!item) || (item.noDrop) || (item.quest))
  321. return;
  322. delete item.pos;
  323. //Find close open position
  324. var x = this.obj.x;
  325. var y = this.obj.y;
  326. var dropCell = this.obj.instance.physics.getOpenCellInArea(x - 1, y - 1, x + 1, y + 1);
  327. if (!dropCell)
  328. return;
  329. if (item.eq)
  330. this.obj.equipment.unequip(id);
  331. this.items.spliceWhere(i => i.id == id);
  332. this.obj.syncer.setArray(true, 'inventory', 'destroyItems', id);
  333. this.createBag(dropCell.x, dropCell.y, [item]);
  334. },
  335. moveItem: function (msgs) {
  336. msgs.forEach(function (m) {
  337. var item = this.findItem(m.id);
  338. if (!item)
  339. return;
  340. item.pos = m.pos;
  341. }, this);
  342. },
  343. mailItem: function (msg) {
  344. var item = this.findItem(msg.itemId);
  345. if ((!item) || (item.noDrop) || (item.quest)) {
  346. this.resolveCallback(msg);
  347. return;
  348. }
  349. delete item.pos;
  350. var io = require('security/io');
  351. io.get({
  352. ent: msg.recipient,
  353. field: 'character',
  354. callback: this.onCheckCharExists.bind(this, msg, item)
  355. });
  356. },
  357. onCheckCharExists: function (msg, item, res) {
  358. if (!res) {
  359. this.resolveCallback(msg, 'Recipient does not exist');
  360. return;
  361. }
  362. this.obj.instance.mail.sendMail(msg.recipient, [extend(true, {}, item)]);
  363. this.destroyItem(item.id);
  364. this.resolveCallback(msg);
  365. },
  366. //Helpers
  367. setItemPosition: function (id) {
  368. var item = this.findItem(id);
  369. if (!item)
  370. return;
  371. var iSize = this.inventorySize;
  372. for (var i = 0; i < iSize; i++) {
  373. if (!this.items.some(j => (j.pos == i))) {
  374. item.pos = i;
  375. break;
  376. }
  377. }
  378. },
  379. resolveCallback: function (msg, result) {
  380. var callbackId = (msg.callbackId != null) ? msg.callbackId : msg;
  381. result = result || [];
  382. if (callbackId == null)
  383. return;
  384. this.obj.instance.syncer.queue('serverModule', {
  385. module: 'atlas',
  386. method: 'resolveCallback',
  387. msg: {
  388. id: callbackId,
  389. result: result
  390. }
  391. });
  392. },
  393. findItem: function (id) {
  394. if (id == null)
  395. return null;
  396. return this.items.find(i => i.id == id);
  397. },
  398. getDefaultAbilities: function () {
  399. var hasWeapon = this.items.some(function (i) {
  400. return (
  401. (i.spell) &&
  402. (i.spell.rolls) &&
  403. (i.spell.rolls.damage != null) &&
  404. ((i.slot == 'twoHanded') || (i.slot == 'oneHanded'))
  405. );
  406. });
  407. if (!hasWeapon) {
  408. var item = generator.generate({
  409. type: classes.weapons[this.obj.class],
  410. quality: 0,
  411. spellQuality: 'basic'
  412. });
  413. item.eq = true;
  414. item.noSalvage = true;
  415. this.getItem(item);
  416. }
  417. classes.spells[this.obj.class].forEach(function (spellName) {
  418. var hasSpell = this.items.some(function (i) {
  419. return (
  420. (i.spell) &&
  421. (i.spell.name.toLowerCase() == spellName)
  422. );
  423. });
  424. if (!hasSpell) {
  425. var item = generator.generate({
  426. spell: true,
  427. spellQuality: 'basic',
  428. spellName: spellName
  429. });
  430. item.eq = true;
  431. item.noSalvage = true;
  432. this.getItem(item);
  433. }
  434. }, this);
  435. },
  436. createBag: function (x, y, items, ownerId) {
  437. if (ownerId == null)
  438. ownerId = -1;
  439. var bagCell = 50;
  440. var topQuality = 0;
  441. var iLen = items.length;
  442. for (var i = 0; i < iLen; i++) {
  443. var quality = items[i].quality;
  444. items[i].fromMob = !!this.obj.mob;
  445. if (quality > topQuality)
  446. topQuality = quality;
  447. }
  448. if (topQuality == 0)
  449. bagCell = 50;
  450. else if (topQuality == 1)
  451. bagCell = 51;
  452. else if (topQuality == 2)
  453. bagCell = 128;
  454. else if (topQuality == 3)
  455. bagCell = 52;
  456. else
  457. bagCell = 53;
  458. var obj = this.obj.instance.objects.buildObjects([{
  459. sheetName: 'objects',
  460. cell: bagCell,
  461. x: x,
  462. y: y,
  463. properties: {
  464. cpnChest: {
  465. ownerId: ownerId,
  466. ttl: this.obj.instance.instanced ? -1 : 1710
  467. },
  468. cpnInventory: {
  469. items: extend(true, [], items)
  470. }
  471. }
  472. }]);
  473. return obj;
  474. },
  475. hasSpace: function () {
  476. if (this.inventorySize != -1) {
  477. var nonEqItems = this.items.filter(f => !f.eq).length;
  478. return (nonEqItems < this.inventorySize);
  479. } else
  480. return true;
  481. },
  482. getItem: function (item, hideMessage, noStack) {
  483. events.emit('onBeforeGetItem', item, this.obj);
  484. //We need to know if a mob dropped it for quest purposes
  485. var fromMob = item.fromMob;
  486. if (item.quality == null)
  487. item.quality = 0;
  488. //Players can't have fromMob items in their inventory but bags can (dropped by a mob)
  489. if (this.obj.player)
  490. delete item.fromMob;
  491. //Store the quantity to send to the player
  492. var quantity = item.quantity;
  493. var exists = false;
  494. if (((item.material) || (item.quest) || (item.quantity)) && (!item.noStack) && (!item.uses) && (!noStack)) {
  495. var existItem = this.items.find(i => (i.name == item.name));
  496. if (existItem) {
  497. exists = true;
  498. if (!existItem.quantity)
  499. existItem.quantity = 1;
  500. existItem.quantity += (item.quantity || 1);
  501. item = existItem;
  502. }
  503. }
  504. if (!exists)
  505. delete item.pos;
  506. //Get next id
  507. if (!exists) {
  508. var id = 0;
  509. var items = this.items;
  510. var iLen = items.length;
  511. if (!this.hasSpace()) {
  512. if (!hideMessage) {
  513. this.obj.instance.syncer.queue('onGetMessages', {
  514. id: this.obj.id,
  515. messages: [{
  516. class: 'q0',
  517. message: 'you bags are too full to loot any more items',
  518. type: 'info'
  519. }]
  520. }, [this.obj.serverId]);
  521. }
  522. return false;
  523. }
  524. for (var i = 0; i < iLen; i++) {
  525. var fItem = items[i];
  526. if (fItem.id >= id) {
  527. id = fItem.id + 1;
  528. }
  529. }
  530. item.id = id;
  531. if (item.eq)
  532. delete item.pos;
  533. if ((item.pos == null) && (!item.eq)) {
  534. var pos = iLen;
  535. for (var i = 0; i < iLen; i++) {
  536. if (!items.some(fi => (fi.pos == i))) {
  537. pos = i;
  538. break;
  539. }
  540. }
  541. item.pos = pos;
  542. }
  543. }
  544. if ((this.obj.player) && (!hideMessage)) {
  545. var messages = [];
  546. var msg = item.name;
  547. if (quantity)
  548. msg += ' x' + quantity;
  549. else if ((item.stats) && (item.stats.weight))
  550. msg += ` ${item.stats.weight}lb`;
  551. messages.push({
  552. class: 'q' + item.quality,
  553. message: 'loot: {' + msg + '}',
  554. item: item,
  555. type: 'loot'
  556. });
  557. this.obj.instance.syncer.queue('onGetDamage', {
  558. id: this.obj.id,
  559. event: true,
  560. text: 'loot'
  561. });
  562. this.obj.instance.syncer.queue('onGetMessages', {
  563. id: this.obj.id,
  564. messages: messages
  565. }, [this.obj.serverId]);
  566. }
  567. //TODO: Remove later, just for test
  568. if (item.stats) {
  569. var stats = Object.keys(item.stats);
  570. var sLen = stats.length
  571. for (var i = 0; i < sLen; i++) {
  572. var s = stats[i];
  573. var val = item.stats[s];
  574. if (s == 'maxHp') {
  575. delete item.stats[s];
  576. item.stats.hpMax = val;
  577. } else if (s == 'maxMana') {
  578. delete item.stats[s];
  579. item.stats.manaMax = val;
  580. }
  581. }
  582. }
  583. if (item.effects) {
  584. item.effects.forEach(function (e) {
  585. if (e.mtx) {
  586. var mtxUrl = mtx.get(e.mtx);
  587. var mtxModule = require(mtxUrl);
  588. e.events = mtxModule.events;
  589. } else if (e.type) {
  590. var effectUrl = itemEffects.get(e.type);
  591. var effectModule = require(effectUrl);
  592. e.text = effectModule.events.onGetText(item);
  593. e.events = effectModule.events;
  594. }
  595. });
  596. }
  597. if (!exists)
  598. this.items.push(item);
  599. if (item.eq) {
  600. if (item.ability)
  601. this.learnAbility(item.id, item.runeSlot);
  602. else
  603. this.obj.equipment.equip(item.id);
  604. } else {
  605. if (!item.effects)
  606. this.obj.syncer.setArray(true, 'inventory', 'getItems', item);
  607. else {
  608. var result = extend(true, {}, item);
  609. result.effects = result.effects.map(e => ({
  610. factionId: e.factionId,
  611. text: e.text,
  612. properties: e.properties
  613. }));
  614. var reputation = this.obj.reputation;
  615. //Don't do this check if we don't have a reputation cpn. That means this is most likely a bag
  616. if ((reputation) && (result.factions)) {
  617. result.factions = result.factions.map(function (f) {
  618. var faction = reputation.getBlueprint(f.id);
  619. var factionTier = reputation.getTier(f.id);
  620. var noEquip = null;
  621. if (factionTier < f.tier)
  622. noEquip = true;
  623. return {
  624. name: faction.name,
  625. tier: f.tier,
  626. tierName: ['Hated', 'Hostile', 'Unfriendly', 'Neutral', 'Friendly', 'Honored', 'Revered', 'Exalted'][f.tier],
  627. noEquip: noEquip
  628. };
  629. }, this);
  630. }
  631. this.obj.syncer.setArray(true, 'inventory', 'getItems', result);
  632. }
  633. }
  634. if (!hideMessage) {
  635. if (fromMob)
  636. this.obj.fireEvent('afterLootMobItem', item);
  637. }
  638. return item;
  639. },
  640. dropBag: function (ownerId, killSource) {
  641. if (!this.blueprint)
  642. return;
  643. //Only drop loot if this player is in the zone
  644. var playerObject = this.obj.instance.objects.find(o => o.serverId == ownerId);
  645. if (!playerObject)
  646. return;
  647. //Get player's spells' statTypes
  648. var stats = [];
  649. playerObject.spellbook.spells.forEach(function (s) {
  650. var spellStatType = s.statType;
  651. if (!(spellStatType instanceof Array))
  652. spellStatType = [spellStatType];
  653. spellStatType.forEach(function (ss) {
  654. if (stats.indexOf(ss) == -1)
  655. stats.push(ss);
  656. });
  657. });
  658. var items = this.items;
  659. var iLen = items.length;
  660. for (var i = 0; i < iLen; i++) {
  661. delete items[i].eq;
  662. delete items[i].pos;
  663. }
  664. var blueprint = this.blueprint;
  665. var savedItems = extend(true, [], this.items);
  666. var instancedItems = extend(true, [], this.items);
  667. this.items = [];
  668. if ((!blueprint.noRandom) || (blueprint.alsoRandom)) {
  669. var magicFind = (blueprint.magicFind || 0);
  670. var bonusMagicFind = killSource.stats.values.magicFind;
  671. var rolls = blueprint.rolls;
  672. var itemQuantity = killSource.stats.values.itemQuantity;
  673. rolls += ~~(itemQuantity / 100);
  674. if ((Math.random() * 100) < (itemQuantity % 100))
  675. rolls++;
  676. for (var i = 0; i < rolls; i++) {
  677. if (Math.random() * 100 >= (blueprint.chance || 35))
  678. continue;
  679. var itemBlueprint = {
  680. level: this.obj.stats.values.level,
  681. magicFind: magicFind,
  682. bonusMagicFind: bonusMagicFind
  683. };
  684. useItem = generator.generate(itemBlueprint);
  685. this.getItem(useItem);
  686. }
  687. }
  688. if (blueprint.noRandom) {
  689. var blueprints = blueprint.blueprints;
  690. for (var i = 0; i < blueprints.length; i++) {
  691. var drop = blueprints[i];
  692. if ((blueprint.chance) && (~~(Math.random() * 100) >= blueprint.chance))
  693. continue;
  694. else if ((drop.maxLevel) && (drop.maxLevel < killSource.stats.values.level))
  695. continue;
  696. else if ((drop.chance) && (~~(Math.random() * 100) >= drop.chance)) {
  697. continue;
  698. }
  699. drop.level = drop.level || this.obj.stats.values.level;
  700. drop.magicFind = magicFind;
  701. var item = drop;
  702. if ((!item.quest) && (item.type != 'key'))
  703. item = generator.generate(drop);
  704. if (!item.slot)
  705. delete item.level;
  706. this.getItem(item, true);
  707. }
  708. }
  709. playerObject.fireEvent('beforeTargetDeath', this.obj, this.items);
  710. events.emit('onBeforeDropBag', this.obj, this.items, killSource);
  711. if (this.items.length > 0)
  712. this.createBag(this.obj.x, this.obj.y, this.items, ownerId);
  713. this.items = savedItems;
  714. },
  715. giveItems: function (obj, hideMessage) {
  716. var objInventory = obj.inventory;
  717. var messages = [];
  718. var items = this.items;
  719. var iLen = items.length;
  720. for (var i = 0; i < iLen; i++) {
  721. var item = items[i];
  722. if (objInventory.getItem(item, hideMessage)) {
  723. items.splice(i, 1);
  724. i--;
  725. iLen--;
  726. } else
  727. return false;
  728. }
  729. return true;
  730. },
  731. rollItems: function (party) {
  732. var items = this.items;
  733. var iLen = items.length;
  734. for (var i = 0; i < iLen; i++) {
  735. var item = items[i];
  736. this.obj.instance.syncer.queue('serverModule', {
  737. module: 'lootRoller',
  738. method: 'enqueue',
  739. msg: {
  740. party: party,
  741. item: item
  742. }
  743. });
  744. }
  745. this.items = [];
  746. },
  747. fireEvent: function (event, args) {
  748. var items = this.items;
  749. var iLen = items.length;
  750. for (var i = 0; i < iLen; i++) {
  751. var item = items[i];
  752. if ((!item.eq) && (!item.active))
  753. continue;
  754. var effects = item.effects;
  755. if (!effects)
  756. continue;
  757. var eLen = effects.length;
  758. for (var j = 0; j < eLen; j++) {
  759. var effect = effects[j];
  760. var effectEvent = effect.events[event];
  761. if (!effectEvent)
  762. continue;
  763. effectEvent.apply(this.obj, [item, ...args]);
  764. }
  765. }
  766. },
  767. clear: function () {
  768. delete this.items;
  769. this.items = [];
  770. },
  771. save: function () {
  772. return {
  773. type: 'inventory',
  774. items: this.items
  775. };
  776. },
  777. simplify: function (self) {
  778. if (!self)
  779. return null;
  780. var reputation = this.obj.reputation;
  781. return {
  782. type: 'inventory',
  783. items: this.items
  784. .map(function (i) {
  785. var item = extend(true, {}, i);
  786. if (item.effects) {
  787. item.effects = item.effects.map(e => ({
  788. factionId: e.factionId,
  789. text: e.text,
  790. properties: e.properties,
  791. mtx: e.mtx,
  792. type: e.type,
  793. rolls: e.rolls
  794. }));
  795. }
  796. if (item.factions) {
  797. item.factions = item.factions.map(function (f) {
  798. var faction = reputation.getBlueprint(f.id);
  799. var factionTier = reputation.getTier(f.id);
  800. var noEquip = null;
  801. if (factionTier < f.tier)
  802. noEquip = true;
  803. if (!faction)
  804. console.log(f);
  805. return {
  806. id: f.id,
  807. name: faction.name,
  808. tier: f.tier,
  809. tierName: ['Hated', 'Hostile', 'Unfriendly', 'Neutral', 'Friendly', 'Honored', 'Revered', 'Exalted'][f.tier],
  810. noEquip: noEquip
  811. };
  812. }, this);
  813. }
  814. return item;
  815. })
  816. };
  817. },
  818. update: function () {
  819. var items = this.items;
  820. var iLen = items.length;
  821. for (var i = 0; i < iLen; i++) {
  822. var item = items[i];
  823. if (!item.cd)
  824. continue;
  825. item.cd--;
  826. this.obj.syncer.setArray(true, 'inventory', 'getItems', item);
  827. }
  828. }
  829. };
  830. });