From 9c61b7b009ecd0dd84578b4fb7c7bb015cd942ff Mon Sep 17 00:00:00 2001 From: DemiPixel Date: Mon, 9 Nov 2015 13:25:42 -0800 Subject: [PATCH] Trying to work on sending entities, fair amount of broken stuff --- src/lib/playerPlugins/communication.js | 18 ++-- src/lib/playerPlugins/login.js | 29 +---- src/lib/playerPlugins/logout.js | 6 +- src/lib/playerPlugins/updatePositions.js | 2 +- src/lib/playerPlugins/world.js | 15 +-- src/lib/serverPlugins/communication.js | 7 ++ src/lib/serverPlugins/entities.js | 129 ++++++++++++++++------- 7 files changed, 122 insertions(+), 84 deletions(-) diff --git a/src/lib/playerPlugins/communication.js b/src/lib/playerPlugins/communication.js index 430f5fb..0138f41 100644 --- a/src/lib/playerPlugins/communication.js +++ b/src/lib/playerPlugins/communication.js @@ -8,15 +8,17 @@ function inject(serv,player) .forEach((otherPlayer) => otherPlayer._client.write(packetName, packetFields)); player._writeOthersNearby = (packetName, packetFields) => - serv._writeArray(packetName, packetFields, player.nearbyPlayers); + serv._writeArray(packetName, packetFields, player.nearbyPlayers()); player.getOthers = () => serv.players.filter((otherPlayer) => otherPlayer != player); - player.getNearby = () => serv - .getNearby({ - world: player.world, - position: player.entity.position, - radius: player.playerViewDistance*32 - }) - .filter((p) => p != player); + player.getNearbyPlayers = (radius=player.entity.viewDistance*32) => serv.getNearby({ + world: player.world, + position: player.position, + radius: radius + }); + + player.nearbyPlayers = (radius=player.entity.viewDistance*32) => player.entity.nearbyEntities + .filter(e => e.type == 'player') + .map(e => e.player); } \ No newline at end of file diff --git a/src/lib/playerPlugins/login.js b/src/lib/playerPlugins/login.js index 5e7f08c..41fc5bb 100644 --- a/src/lib/playerPlugins/login.js +++ b/src/lib/playerPlugins/login.js @@ -7,46 +7,25 @@ function inject(serv,player) { function addPlayer() { - serv.entityMaxId++; - player.entity=new Entity(serv.entityMaxId); - serv.entities[player.entity.id]=player.entity; + player.entity=serv.initEntity('player', null, serv.overworld, Vec3(0,0,0)); + player.entity.type = 'player'; player.entity.player=player; player.entity.health = 20; player.entity.food = 20; player.entity.crouching = false; // Needs added in prismarine-entity later - player.playerViewDistance = 150; player.view=10; player.world=serv.overworld; player.username=player._client.username; serv.players.push(player); serv.uuidToPlayer[player._client.uuid] = player; player.loadedChunks={}; - player.nearbyPlayers=[]; } - player.updateAndSpawnNearbyPlayers = () => - { - player.lastPositionPlayersUpdated=player.entity.position; - var updatedPlayers=player.getNearby(); - var playersToAdd=updatedPlayers.filter(p => player.nearbyPlayers.indexOf(p)==-1); - var playersToRemove=player.nearbyPlayers.filter(p => updatedPlayers.indexOf(p)==-1); - player.despawnPlayers(playersToRemove); - playersToAdd.forEach(player.spawnAPlayer); - - playersToRemove.forEach(p => p.despawnPlayers([player])); - playersToRemove.forEach(p => p.nearbyPlayers=p.getNearby()); - playersToAdd.forEach(p => p.spawnAPlayer(player)); - playersToAdd.forEach(p => p.nearbyPlayers=p.getNearby()); - - player.nearbyPlayers=updatedPlayers; - - }; - function sendPlayersWhenMove() { player.on("positionChanged",() => { if(player.entity.position.distanceTo(player.lastPositionPlayersUpdated)>2*32) - player.updateAndSpawnNearbyPlayers(); + player.entity.updateAndSpawn(); }); } @@ -167,7 +146,7 @@ function inject(serv,player) updateTime(); player.setGameMode(player.gameMode); fillTabList(); - player.updateAndSpawnNearbyPlayers(); + player.entity.updateAndSpawn(); announceJoin(); player.emit("spawned"); diff --git a/src/lib/playerPlugins/logout.js b/src/lib/playerPlugins/logout.js index 5ac9a68..99b6e6b 100644 --- a/src/lib/playerPlugins/logout.js +++ b/src/lib/playerPlugins/logout.js @@ -8,6 +8,10 @@ function inject(serv,player) }); }; + player.despawnEntities = entities => player._client.write('entity_destroy', { + 'entityIds': entities.map(e => e.id) + }); + player._client.on('end', () => { if(player.entity) { serv.broadcast(player.username + ' quit the game.', "yellow"); @@ -17,7 +21,7 @@ function inject(serv,player) UUID: player._client.uuid }] }); - player.nearbyPlayers.forEach(otherPlayer => otherPlayer.despawnPlayers([player])); + player.nearbyPlayers().forEach(otherPlayer => otherPlayer.despawnPlayers([player])); delete serv.entities[player.entity.id]; player.emit('disconnected'); var index = serv.players.indexOf(player); diff --git a/src/lib/playerPlugins/updatePositions.js b/src/lib/playerPlugins/updatePositions.js index 2a22ec7..d9c6bb5 100644 --- a/src/lib/playerPlugins/updatePositions.js +++ b/src/lib/playerPlugins/updatePositions.js @@ -47,7 +47,7 @@ function inject(serv,player) function sendRelativePositionChange(newPosition, onGround) { if (player.entity.position.distanceTo(new vec3(0, 0, 0)) != 0) { - var diff = newPosition.scaled(1/32).scaled(32).minus(player.entity.position.scaled(1/32).scaled(32)); + var diff = newPosition.minus(player.entity.position); if(diff.abs().x>127 || diff.abs().y>127 || diff.abs().z>127) { player._writeOthersNearby('entity_teleport', { diff --git a/src/lib/playerPlugins/world.js b/src/lib/playerPlugins/world.js index 6944826..acdd280 100644 --- a/src/lib/playerPlugins/world.js +++ b/src/lib/playerPlugins/world.js @@ -5,18 +5,8 @@ module.exports = inject; function inject(serv, player) { - player.spawnAPlayer = spawnedPlayer => { - player._client.write('named_entity_spawn', { - entityId: spawnedPlayer.entity.id, - playerUUID: spawnedPlayer._client.uuid, - x: spawnedPlayer.entity.position.x, - y: spawnedPlayer.entity.position.y, - z: spawnedPlayer.entity.position.z, - yaw: spawnedPlayer.entity.yaw, - pitch: spawnedPlayer.entity.pitch, - currentItem: 0, - metadata: spawnedPlayer.entity.metadata - }); + player.spawnEntity = entity => { + player._client.write(entity.spawnPacketName, entity.getSpawnPacket()); }; player.sendChunk = (chunkX,chunkZ,column) => @@ -96,6 +86,7 @@ function inject(serv, player) { if(player.world == world) return Promise.resolve(); opt = opt || {}; player.world = world; + player.entity.world = world; player.loadedChunks={}; if (typeof opt.gamemode != 'undefined') player.gameMode = opt.gamemode; player._client.write("respawn",{ diff --git a/src/lib/serverPlugins/communication.js b/src/lib/serverPlugins/communication.js index dc2a9fc..e58f414 100644 --- a/src/lib/serverPlugins/communication.js +++ b/src/lib/serverPlugins/communication.js @@ -15,4 +15,11 @@ function inject(serv,settings) player.world == world && player.entity.position.distanceTo(position) <= radius ); + + serv.getNearbyEntities= ({world,position,radius=8*16*32}) => Object.keys(serv.entities) + .map(eId => serv.entities[eId]) + .filter(entity => + entity.world == world && + entity.position.distanceTo(position) <= radius + ); } \ No newline at end of file diff --git a/src/lib/serverPlugins/entities.js b/src/lib/serverPlugins/entities.js index 6a318cf..290a16b 100644 --- a/src/lib/serverPlugins/entities.js +++ b/src/lib/serverPlugins/entities.js @@ -11,23 +11,30 @@ function inject(serv) { serv.entityMaxId++; var entity = new Entity(serv.entityMaxId); entity.type = type; + entity.spawnPacketName = ''; entity.entityType = entityType; entity.world = world; entity.position = position; + entity.nearbyEntities = []; + entity.viewDistance = 15; entity.bornTime = Date.now(); serv.entities[entity.id] = entity; + if (entity.type == 'player') entity.spawnPacketName = 'named_entity_spawn'; + else if (entity.type == 'object') entity.spawnPacketName = 'spawn_entity'; + else if (entity.type == 'mob') entity.spawnPacketName = 'spawn_entity_living'; + entity.setMetadata = (data) => { serv._writeNearby('entity_metadata', { entityId: entity.id, metadata: data }, entity); - } + }; entity.destroy = () => { serv.destroyEntity(entity); - } + }; entity.calculatePhysics = async (delta) => { if (entity.gravity) { @@ -63,7 +70,7 @@ function inject(serv) { //serv.emitParticle(30, serv.overworld, entity.position.scaled(1/32), { size: vec3(0, 0, 0) }); return { oldPos: oldPos, onGround: yBlock} - } + }; entity.sendPosition = ({oldPos,onGround}) => { var diff = entity.position.minus(oldPos); @@ -86,6 +93,85 @@ function inject(serv) { }, entity); } + entity.getSpawnPacket = () => { + var scaledVelocity = entity.velocity.scaled(8000/32/20).floored(); // from fixed-position/second to unit => 1/8000 blocks per tick + if (entity.type == 'player') { + return { + entityId: entity.id, + playerUUID: entity.player._client.uuid, + x: entity.position.x, + y: entity.position.y, + z: entity.position.z, + yaw: entity.yaw, + pitch: entity.pitch, + currentItem: 0, + metadata: entity.metadata + } + } else if (entity.type == 'object') { + return { + entityId: entity.id, + type: entity.entityType, + x: entity.position.x, + y: entity.position.y, + z: entity.position.z, + pitch: entity.pitch, + yaw: entity.yaw, + objectData: { + intField: entity.data, + velocityX: scaledVelocity.x, + velocityY: scaledVelocity.y, + velocityZ: scaledVelocity.z + } + } + } else if (entity.type == 'mob') { + return { + entityId: entity.id, + type: entity.entityType, + x: entity.position.x, + y: entity.position.y, + z: entity.position.z, + yaw: entity.yaw, + pitch: entity.pitch, + headPitch: entity.headPitch, + velocityX: scaledVelocity.x, + velocityY: scaledVelocity.y, + velocityZ: scaledVelocity.z, + metadata: entity.metadata + } + } + }; + + entity.getNearby = () => serv + .getNearbyEntities({ + world: entity.world, + position: entity.position, + radius: entity.viewDistance*32 + }) + .filter((e) => e != entity); + + entity.updateAndSpawn = () => { + var updatedEntities=entity.getNearby(); + var entitiesToAdd=updatedEntities.filter(e => entity.nearbyEntities.indexOf(e)==-1); + var entitiesToRemove=entity.nearbyEntities.filter(e => updatedEntities.indexOf(e)==-1); + if (entity.type == 'player') { + entity.player.despawnEntities(entitiesToRemove); + entitiesToAdd.forEach(entity.player.spawnEntity); + entity.player.lastPositionPlayersUpdated=entity.position; + } + + var playersToAdd = entitiesToAdd.filter(e => e.type == 'player').map(e => e.player); + var playersToRemove = entitiesToRemove.filter(e => e.type == 'player').map(e => e.player); + + console.log('players',playersToAdd.length,playersToRemove.length,'ents',entitiesToAdd.length,entitiesToRemove.length); + + playersToRemove.forEach(p => p.despawnEntities([entity])); + playersToRemove.forEach(p => p.entity.nearbyEntities=p.entity.getNearby()); + playersToAdd.forEach(p => p.spawnEntity(entity)); + playersToAdd.forEach(p => p.entity.nearbyEntities=p.entity.getNearby()); + + entity.nearbyEntities=updatedEntities; + }; + return entity; } @@ -101,23 +187,7 @@ function inject(serv) { object.size = vec3(0.25*32, 0.25*32, 0.25*32); // Hardcoded, will be dependent on type! object.deathTime = 60*1000; // 60 seconds - var scaledVelocity = object.velocity.scaled(8000/32/20).floored(); // from fixed-position/second to unit => 1/8000 blocks per tick - - serv._writeNearby('spawn_entity', { - entityId: object.id, - type: object.entityType, - x: object.position.x, - y: object.position.y, - z: object.position.z, - pitch: object.pitch, - yaw: object.yaw, - objectData: { - intField: data, - velocityX: scaledVelocity.x, - velocityY: scaledVelocity.y, - velocityZ: scaledVelocity.z - } - }, object); + object.updateAndSpawn(); if (typeof itemId != 'undefined') { object.setMetadata([{ @@ -128,7 +198,7 @@ function inject(serv) { itemDamage: itemDamage } }]); - } + } } serv.spawnMob = (type, world, position, {pitch=0,yaw=0,headPitch=0,velocity=vec3(0,0,0),metadata=[]}={}) => { @@ -143,22 +213,7 @@ function inject(serv) { mob.size = vec3(0.75, 1.75, 0.75); mob.metadata = metadata; - var scaledVelocity = mob.velocity.scaled(8000/32/20).floored(); - - serv._writeNearby('spawn_entity_living', { - entityId: mob.id, - type: mob.entityType, - x: mob.position.x, - y: mob.position.y, - z: mob.position.z, - yaw: mob.yaw, - pitch: mob.pitch, - headPitch: mob.headPitch, - velocityX: scaledVelocity.x, - velocityY: scaledVelocity.y, - velocityZ: scaledVelocity.z, - metadata: mob.metadata - }, mob); + mob.updateAndSpawn(); } serv.on('tick', function(delta) {