選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

door.js 4.5 KiB

5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
5年前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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. };