|
| 1 | +import { logger } from '@runejs/core'; |
| 2 | + |
| 3 | +import { filestore, world } from '@engine/game-server'; |
| 4 | +import { Position } from '@engine/world/position'; |
| 5 | +import { getVarbitMorphIndex } from '@engine/util/varbits'; |
| 6 | +import { PacketData } from '@engine/net/inbound-packets'; |
| 7 | +import { Player, Rights } from '@engine/world/actor/player/player'; |
| 8 | + |
| 9 | + |
| 10 | +interface ObjectInteractionData { |
| 11 | + objectId: number; |
| 12 | + x: number; |
| 13 | + y: number; |
| 14 | +} |
| 15 | + |
| 16 | +type objectInteractionPacket = (packet: PacketData) => ObjectInteractionData; |
| 17 | + |
| 18 | + |
| 19 | +const option1: objectInteractionPacket = packet => { |
| 20 | + const { buffer } = packet; |
| 21 | + const objectId = buffer.get('short', 'u'); |
| 22 | + const y = buffer.get('short', 'u'); |
| 23 | + const x = buffer.get('short', 'u', 'le'); |
| 24 | + return { objectId, x, y }; |
| 25 | +}; |
| 26 | + |
| 27 | +const option2: objectInteractionPacket = packet => { |
| 28 | + const { buffer } = packet; |
| 29 | + const x = buffer.get('short', 'u', 'le'); |
| 30 | + const y = buffer.get('short', 'u', 'le'); |
| 31 | + const objectId = buffer.get('short', 'u', 'le'); |
| 32 | + return { objectId, x, y }; |
| 33 | +}; |
| 34 | + |
| 35 | +const option3: objectInteractionPacket = packet => { |
| 36 | + const { buffer } = packet; |
| 37 | + const y = buffer.get('short', 'u'); |
| 38 | + const objectId = buffer.get('short', 'u'); |
| 39 | + const x = buffer.get('short', 'u'); |
| 40 | + return { objectId, x, y }; |
| 41 | +}; |
| 42 | + |
| 43 | +const option4: objectInteractionPacket = packet => { |
| 44 | + const { buffer } = packet; |
| 45 | + const x = buffer.get('short', 'u', 'le'); |
| 46 | + const objectId = buffer.get('short', 'u', 'le'); |
| 47 | + const y = buffer.get('short', 'u', 'le'); |
| 48 | + return { objectId, x, y }; |
| 49 | +}; |
| 50 | + |
| 51 | +const option5: objectInteractionPacket = packet => { |
| 52 | + const { buffer } = packet; |
| 53 | + const objectId = buffer.get('short', 'u'); |
| 54 | + const y = buffer.get('short', 'u', 'le'); |
| 55 | + const x = buffer.get('short', 'u', 'le'); |
| 56 | + return { objectId, x, y }; |
| 57 | +}; |
| 58 | + |
| 59 | + |
| 60 | +const objectInteractionPackets: { [key: number]: { packetDef: objectInteractionPacket, index: number } } = { |
| 61 | + 30: { packetDef: option1, index: 0 }, |
| 62 | + 164: { packetDef: option2, index: 1 }, |
| 63 | + 183: { packetDef: option3, index: 2 }, |
| 64 | + 229: { packetDef: option4, index: 3 }, |
| 65 | + 62: { packetDef: option5, index: 4 }, |
| 66 | +}; |
| 67 | + |
| 68 | + |
| 69 | +const objectInteractionPacket = (player: Player, packet: PacketData) => { |
| 70 | + const { packetId } = packet; |
| 71 | + |
| 72 | + const { objectId, x, y } = objectInteractionPackets[packetId].packetDef(packet); |
| 73 | + const level = player.position.level; |
| 74 | + const objectPosition = new Position(x, y, level); |
| 75 | + const { object: landscapeObject, cacheOriginal } = world.findObjectAtLocation(player, objectId, objectPosition); |
| 76 | + if(!landscapeObject) { |
| 77 | + if(player.rights === Rights.ADMIN) { |
| 78 | + player.sendMessage(`Custom object ${objectId} @[${objectPosition.key}]`); |
| 79 | + } |
| 80 | + return; |
| 81 | + } |
| 82 | + |
| 83 | + let objectConfig = filestore.configStore.objectStore.getObject(objectId); |
| 84 | + if (objectConfig.configChangeDest) { |
| 85 | + let morphIndex = -1; |
| 86 | + if(objectConfig.varbitId === -1) { |
| 87 | + if(objectConfig.configId !== -1) { |
| 88 | + morphIndex = player.metadata['configs'] && player.metadata['configs'][objectConfig.configId] ? |
| 89 | + player.metadata['configs'][objectConfig.configId] : 0; |
| 90 | + } |
| 91 | + } else { |
| 92 | + morphIndex = getVarbitMorphIndex(objectConfig.varbitId, player.metadata['configs']); |
| 93 | + } |
| 94 | + if(morphIndex !== -1) { |
| 95 | + objectConfig = filestore.configStore.objectStore.getObject(objectConfig.configChangeDest[morphIndex]); |
| 96 | + } |
| 97 | + } |
| 98 | + |
| 99 | + const actionIdx = objectInteractionPackets[packetId].index; |
| 100 | + let optionName = `action-${actionIdx + 1}`; |
| 101 | + if(objectConfig.options && objectConfig.options.length >= actionIdx) { |
| 102 | + if(!objectConfig.options[actionIdx]) { |
| 103 | + // Invalid action |
| 104 | + logger.error(`1: Invalid object ${objectId} option ${actionIdx + 1}, options: ${JSON.stringify(objectConfig.options)}`); |
| 105 | + return; |
| 106 | + } |
| 107 | + |
| 108 | + optionName = objectConfig.options[actionIdx]; |
| 109 | + } else { |
| 110 | + // Invalid action |
| 111 | + logger.error(`2: Invalid object ${objectId} option ${actionIdx + 1}, options: ${JSON.stringify(objectConfig.options)}`); |
| 112 | + return; |
| 113 | + } |
| 114 | + |
| 115 | + player.actionPipeline.call('object_interaction', player, landscapeObject, objectConfig, objectPosition, optionName.toLowerCase(), cacheOriginal); |
| 116 | +}; |
| 117 | + |
| 118 | + |
| 119 | +export default Object.keys(objectInteractionPackets).map(opcode => ({ |
| 120 | + opcode: parseInt(opcode, 10), |
| 121 | + size: 6, |
| 122 | + handler: objectInteractionPacket |
| 123 | +})); |
0 commit comments