Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 

207 linhas
4.5 KiB

  1. const eventEmitter = require('../misc/events');
  2. module.exports = {
  3. type: 'door',
  4. locked: false,
  5. closed: true,
  6. key: null,
  7. autoCloseCd: 0,
  8. autoClose: null,
  9. destroyKey: false,
  10. openSprite: 157,
  11. closedSprite: 156,
  12. init: function (blueprint) {
  13. this.locked = blueprint.locked;
  14. this.key = blueprint.key;
  15. this.destroyKey = blueprint.destroyKey;
  16. this.autoClose = blueprint.autoClose;
  17. if (blueprint.openSprite)
  18. this.openSprite = blueprint.openSprite;
  19. if (blueprint.closedSprite)
  20. this.closedSprite = blueprint.closedSprite;
  21. if (this.closed) {
  22. this.obj.instance.physics.setCollision(this.obj.x, this.obj.y, true);
  23. this.obj.instance.objects.notifyCollisionChange(this.obj.x, this.obj.y, true);
  24. }
  25. this.obj.instance.objects.buildObjects([{
  26. properties: {
  27. x: this.obj.x - 1,
  28. y: this.obj.y - 1,
  29. width: 3,
  30. height: 3,
  31. cpnNotice: {
  32. actions: {
  33. enter: {
  34. cpn: 'door',
  35. method: 'enterArea',
  36. targetId: this.obj.id,
  37. args: []
  38. },
  39. exit: {
  40. cpn: 'door',
  41. method: 'exitArea',
  42. targetId: this.obj.id,
  43. args: []
  44. }
  45. }
  46. }
  47. }
  48. }]);
  49. },
  50. canActorUnlockThis: function (obj) {
  51. const actorHasKey = obj.inventory.items.some(({ keyId }) => keyId === this.key);
  52. if (actorHasKey)
  53. return true;
  54. const unlockEventMsg = {
  55. source: obj,
  56. target: this,
  57. canUnlock: false
  58. };
  59. eventEmitter.emit('onBeforeUnlockObject', unlockEventMsg);
  60. return unlockEventMsg.canUnlock;
  61. },
  62. exitArea: function (obj) {
  63. if (!obj.player)
  64. return;
  65. obj.syncer.setArray(true, 'serverActions', 'removeActions', {
  66. key: 'u',
  67. action: {
  68. cpn: 'door',
  69. method: 'unlock',
  70. data: {
  71. targetId: this.obj.id
  72. }
  73. }
  74. });
  75. },
  76. enterArea: function (obj) {
  77. if (!obj.player)
  78. return;
  79. let canAction = true;
  80. let msg = 'Press U to open this door';
  81. if (this.closed) {
  82. if (this.locked && !this.canActorUnlockThis(obj)) {
  83. canAction = false;
  84. msg = 'You don\'t have the key to unlock this door';
  85. }
  86. } else
  87. msg = 'Press U to close this door';
  88. if (canAction) {
  89. obj.syncer.setArray(true, 'serverActions', 'addActions', {
  90. key: 'u',
  91. name: this.closed ? 'open door' : 'close door',
  92. action: {
  93. cpn: 'door',
  94. method: 'unlock',
  95. data: {
  96. targetId: this.obj.id
  97. }
  98. }
  99. });
  100. }
  101. this.obj.instance.syncer.queue('onGetAnnouncement', {
  102. src: this.obj.id,
  103. msg: msg
  104. }, [obj.serverId]);
  105. },
  106. unlock: function (msg) {
  107. if (!msg.sourceId)
  108. return;
  109. let obj = this.obj.instance.objects.objects.find(o => o.serverId === msg.sourceId);
  110. if ((!obj) || (!obj.player))
  111. return;
  112. let thisObj = this.obj;
  113. if ((Math.abs(thisObj.x - obj.x) > 1) || (Math.abs(thisObj.y - obj.y) > 1))
  114. return;
  115. else if ((thisObj.x === obj.x) && (thisObj.y === obj.y))
  116. return;
  117. let syncO = thisObj.syncer.o;
  118. if ((this.locked) && (this.closed)) {
  119. if (this.autoClose)
  120. this.autoCloseCd = this.autoClose;
  121. const canUnlock = this.canActorUnlockThis(obj);
  122. if (!canUnlock)
  123. return;
  124. const key = obj.inventory.items.find(i => i.keyId === this.key);
  125. if (key && (key.singleUse || this.destroyKey)) {
  126. obj.inventory.destroyItem({ itemId: key.id }, 1);
  127. const message = `The ${key.name} disintegrates on use`;
  128. obj.social.notifySelf({ message });
  129. }
  130. this.obj.instance.syncer.queue('onDoorUnlock', null, [obj.serverId]);
  131. }
  132. if (this.closed) {
  133. thisObj.cell = this.openSprite;
  134. syncO.cell = this.openSprite;
  135. this.obj.instance.physics.setCollision(thisObj.x, thisObj.y, false);
  136. this.obj.instance.objects.notifyCollisionChange(thisObj.x, thisObj.y, false);
  137. this.closed = false;
  138. this.enterArea(obj);
  139. this.obj.instance.syncer.queue('onDoorOpen', null, [obj.serverId]);
  140. } else {
  141. thisObj.cell = this.closedSprite;
  142. syncO.cell = this.closedSprite;
  143. this.obj.instance.physics.setCollision(thisObj.x, thisObj.y, true);
  144. this.obj.instance.objects.notifyCollisionChange(thisObj.x, thisObj.y, true);
  145. this.closed = true;
  146. this.enterArea(obj);
  147. this.obj.instance.syncer.queue('onDoorClose', null, [obj.serverId]);
  148. }
  149. },
  150. update: function () {
  151. if (!this.autoCloseCd)
  152. return;
  153. this.autoCloseCd--;
  154. if (this.autoCloseCd === 0) {
  155. this.obj.cell = this.closedSprite;
  156. this.obj.syncer.o.cell = this.closedSprite;
  157. this.obj.instance.physics.setCollision(this.obj.x, this.obj.y, true);
  158. this.closed = true;
  159. }
  160. },
  161. destroy: function () {
  162. this.obj.instance.physics.setCollision(this.obj.x, this.obj.y, false);
  163. this.obj.instance.objects.notifyCollisionChange(this.obj.x, this.obj.y, false);
  164. }
  165. };