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.
 
 
 

203 lines
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. targetId: this.obj.id,
  69. cpn: 'door',
  70. method: 'unlock'
  71. }
  72. });
  73. },
  74. enterArea: function (obj) {
  75. if (!obj.player)
  76. return;
  77. let canAction = true;
  78. let msg = 'Press U to open this door';
  79. if (this.closed) {
  80. if (this.locked && !this.canActorUnlockThis(obj)) {
  81. canAction = false;
  82. msg = 'You don\'t have the key to unlock this door';
  83. }
  84. } else
  85. msg = 'Press U to close this door';
  86. if (canAction) {
  87. obj.syncer.setArray(true, 'serverActions', 'addActions', {
  88. key: 'u',
  89. name: this.closed ? 'open door' : 'close door',
  90. action: {
  91. targetId: this.obj.id,
  92. cpn: 'door',
  93. method: 'unlock'
  94. }
  95. });
  96. }
  97. this.obj.instance.syncer.queue('onGetAnnouncement', {
  98. src: this.obj.id,
  99. msg: msg
  100. }, [obj.serverId]);
  101. },
  102. unlock: function (msg) {
  103. if (!msg.sourceId)
  104. return;
  105. let obj = this.obj.instance.objects.objects.find(o => o.serverId === msg.sourceId);
  106. if ((!obj) || (!obj.player))
  107. return;
  108. let thisObj = this.obj;
  109. if ((Math.abs(thisObj.x - obj.x) > 1) || (Math.abs(thisObj.y - obj.y) > 1))
  110. return;
  111. else if ((thisObj.x === obj.x) && (thisObj.y === obj.y))
  112. return;
  113. let syncO = thisObj.syncer.o;
  114. if ((this.locked) && (this.closed)) {
  115. if (this.autoClose)
  116. this.autoCloseCd = this.autoClose;
  117. const canUnlock = this.canActorUnlockThis(obj);
  118. if (!canUnlock)
  119. return;
  120. const key = obj.inventory.items.find(i => i.keyId === this.key);
  121. if (key && (key.singleUse || this.destroyKey)) {
  122. obj.inventory.destroyItem(key.id, 1);
  123. const message = `The ${key.name} disintegrates on use`;
  124. obj.social.notifySelf({ message });
  125. }
  126. this.obj.instance.syncer.queue('onDoorUnlock', null, [obj.serverId]);
  127. }
  128. if (this.closed) {
  129. thisObj.cell = this.openSprite;
  130. syncO.cell = this.openSprite;
  131. this.obj.instance.physics.setCollision(thisObj.x, thisObj.y, false);
  132. this.obj.instance.objects.notifyCollisionChange(thisObj.x, thisObj.y, false);
  133. this.closed = false;
  134. this.enterArea(obj);
  135. this.obj.instance.syncer.queue('onDoorOpen', null, [obj.serverId]);
  136. } else {
  137. thisObj.cell = this.closedSprite;
  138. syncO.cell = this.closedSprite;
  139. this.obj.instance.physics.setCollision(thisObj.x, thisObj.y, true);
  140. this.obj.instance.objects.notifyCollisionChange(thisObj.x, thisObj.y, true);
  141. this.closed = true;
  142. this.enterArea(obj);
  143. this.obj.instance.syncer.queue('onDoorClose', null, [obj.serverId]);
  144. }
  145. },
  146. update: function () {
  147. if (!this.autoCloseCd)
  148. return;
  149. this.autoCloseCd--;
  150. if (this.autoCloseCd === 0) {
  151. this.obj.cell = this.closedSprite;
  152. this.obj.syncer.o.cell = this.closedSprite;
  153. this.obj.instance.physics.setCollision(this.obj.x, this.obj.y, true);
  154. this.closed = true;
  155. }
  156. },
  157. destroy: function () {
  158. this.obj.instance.physics.setCollision(this.obj.x, this.obj.y, false);
  159. this.obj.instance.objects.notifyCollisionChange(this.obj.x, this.obj.y, false);
  160. }
  161. };