From 573c0e420001f98ac7a8c9f6b3afd916309fff8b Mon Sep 17 00:00:00 2001 From: DemiPixel Date: Sat, 7 Nov 2015 17:49:52 -0800 Subject: [PATCH 1/8] Adding lots of cool stuff (spawnObject, entity physics, etc) --- src/lib/playerPlugins/digging.js | 8 ++- src/lib/playerPlugins/pvp.js | 2 +- src/lib/playerPlugins/updatePositions.js | 4 +- src/lib/serverPlugins/communication.js | 6 +- src/lib/serverPlugins/daycycle.js | 2 +- src/lib/serverPlugins/entities.js | 90 ++++++++++++++++++++++++ src/lib/serverPlugins/objects.js | 49 +++++++++++++ src/lib/serverPlugins/tick.js | 6 +- 8 files changed, 158 insertions(+), 9 deletions(-) create mode 100644 src/lib/serverPlugins/entities.js create mode 100644 src/lib/serverPlugins/objects.js diff --git a/src/lib/playerPlugins/digging.js b/src/lib/playerPlugins/digging.js index 56aa35a..2479e47 100644 --- a/src/lib/playerPlugins/digging.js +++ b/src/lib/playerPlugins/digging.js @@ -86,8 +86,14 @@ function inject(serv,player) } - function creativeDigging(location) + async function creativeDigging(location) { + var vec = Vec3(location.x, location.y, location.z); + var id = await player.world.getBlockType(vec); + serv.spawnObject(2, player.world, vec.clone().add(Vec3(0.5, 0.5, 0.5)), { + data: 0, + velocity: Vec3(Math.random()*4 - 2, Math.random()*2 + 2, Math.random()*4 - 2) + }); return player.changeBlock(location,0,0); } diff --git a/src/lib/playerPlugins/pvp.js b/src/lib/playerPlugins/pvp.js index aae4132..bf3e177 100644 --- a/src/lib/playerPlugins/pvp.js +++ b/src/lib/playerPlugins/pvp.js @@ -15,7 +15,7 @@ function inject(serv, player) function attackEntity(entityId) { var attackedPlayer = serv.entities[entityId].player; - if(attackedPlayer.gameMode!=0) return; + if(attackedPlayer.gameMode!=0 || !attackedPlayer) return; attackedPlayer.updateHealth(attackedPlayer.entity.health - 1); serv.playSound('game.player.hurt', player.world, attackedPlayer.entity.position.scaled(1/32)); diff --git a/src/lib/playerPlugins/updatePositions.js b/src/lib/playerPlugins/updatePositions.js index f0158e5..d9c6bb5 100644 --- a/src/lib/playerPlugins/updatePositions.js +++ b/src/lib/playerPlugins/updatePositions.js @@ -12,10 +12,10 @@ function inject(serv,player) // float (degrees) --> byte (1/256 "degrees") function conv(f){ - var b = (f % 360) * 256 / 360; + var b = Math.floor((f % 360) * 256 / 360); if (b < -128) b += 256; else if (b > 127) b -= 256; - return Math.floor(b); + return b; } function sendLook(yaw,pitch,onGround) { diff --git a/src/lib/serverPlugins/communication.js b/src/lib/serverPlugins/communication.js index efd1e08..dc2a9fc 100644 --- a/src/lib/serverPlugins/communication.js +++ b/src/lib/serverPlugins/communication.js @@ -11,8 +11,8 @@ function inject(serv,settings) serv._writeNearby= (packetName, packetFields, loc) => serv._writeArray(packetName, packetFields, serv.getNearby(loc)); - serv.getNearby= loc => serv.players.filter( player => - player.world == loc.world && - player.entity.position.distanceTo(loc.position) <= loc.radius + serv.getNearby= ({world,position,radius=8*16*32}) => serv.players.filter( player => + player.world == world && + player.entity.position.distanceTo(position) <= radius ); } \ No newline at end of file diff --git a/src/lib/serverPlugins/daycycle.js b/src/lib/serverPlugins/daycycle.js index 3f5788b..e5606fd 100644 --- a/src/lib/serverPlugins/daycycle.js +++ b/src/lib/serverPlugins/daycycle.js @@ -14,7 +14,7 @@ function inject(serv, settings) { serv.time = 0; - serv.on('tick', (count) => { + serv.on('tick', (delta,count) => { if (!serv.doDaylightCycle) return; if (count % 20 == 0) { serv.setTime((serv.time + 20) % 24000); // Vanilla only does it every second diff --git a/src/lib/serverPlugins/entities.js b/src/lib/serverPlugins/entities.js new file mode 100644 index 0000000..185ebba --- /dev/null +++ b/src/lib/serverPlugins/entities.js @@ -0,0 +1,90 @@ +var vec3 = require("vec3"); + +module.exports = inject; + +function inject(serv) { + serv.on('tick', function(delta) { + Promise.all( + Object.keys(serv.entities).map(async (id) => { + var entity = serv.entities[id]; + if (!entity.velocity || !entity.size) return; + if (entity.gravity) { + addGravity(entity, 'x', delta); + addGravity(entity, 'y', delta); + addGravity(entity, 'z', delta); + } + + var vSign = getSign(entity.velocity); + var sizeSigned = vec3(vSign.x * entity.size.x, vSign.y * entity.size.y, vSign.z * entity.size.z); + + var xVec = entity.position.offset(entity.velocity.x*delta + sizeSigned.x/2, 0, 0).scaled(1/32).floored(); + var yVec = entity.position.offset(0, entity.velocity.y*delta + sizeSigned.y/2, 0).scaled(1/32).floored(); + var zVec = entity.position.offset(0, 0, entity.velocity.z*delta + sizeSigned.z/2).scaled(1/32).floored(); + + //console.log(xVec, yVec, zVec); + //console.log(entity.velocity); + + // Get block for each (x/y/z)Vec, check to avoid duplicate getBlockTypes + var xBlock = (await entity.world.getBlockType(xVec)) != 0; + var yBlock = yVec.equals(xVec) ? xBlock : (await entity.world.getBlockType(yVec)) != 0; + var zBlock = zVec.equals(yVec) ? yBlock : (zVec.equals(xVec) ? xBlock : (await entity.world.getBlockType(zVec)) != 0); + + var old = entity.position.clone(); + + if (xBlock || yBlock || zBlock) { + entity.velocity.x = getFriction(entity.velocity.x, entity.friction.x, delta); + entity.velocity.z = getFriction(entity.velocity.x, entity.friction.x, delta); + } + + //console.log('afterfric',entity.velocity); + + entity.position.x += getMoveAmount('x', xBlock, entity, delta, sizeSigned.x); + entity.position.y += getMoveAmount('y', yBlock, entity, delta, sizeSigned.y); + entity.position.z += getMoveAmount('z', zBlock, entity, delta, sizeSigned.z); + + //console.log(entity.position, old); + + serv.emitParticle(23, serv.overworld, entity.position.scaled(1/32), { size: vec3(0, 0, 0) }); + }) + ).catch((err)=> setTimeout(() => {throw err;},0)); + }); + + serv.destroyEntity = entity => { + console.log('Destroying'); + serv._writeNearby('entity_destroy', { + entityIds: [entity.id] + }, entity.position); + delete serv.entities[entity.id]; + } +} + +function getMoveAmount(dir, block, entity, delta, sizeSigned) { + if (block) { + entity.velocity[dir] = 0; + return Math.floor(-1 * (entity.position[dir] + sizeSigned/2 - floorInDirection(entity.position[dir], -sizeSigned))); + } else { + return Math.floor(entity.velocity[dir] * delta); + } +} + +function getSign(vec) { + return vec3(Math.sign(vec.x), Math.sign(vec.y), Math.sign(vec.z)); +} + +function floorInDirection(a, b) { + return b < 0 ? Math.floor(a) : Math.ceil(a); +} + +function addGravity(entity, dir, delta) { + if (entity.velocity[dir] < entity.terminalvelocity[dir] && entity.velocity[dir] > -entity.terminalvelocity[dir]) { + entity.velocity[dir] = clamp(-entity.terminalvelocity[dir], entity.velocity[dir] + entity.gravity[dir] * delta, entity.terminalvelocity[dir]); + } +} + +function getFriction(vel, fric, delta) { + return vel > 0 ? Math.max(0, vel - fric*delta) : Math.min(0, vel + fric*delta); +} + +function clamp(a, b, c) { + return Math.max(a, Math.min(b, c)); +} \ No newline at end of file diff --git a/src/lib/serverPlugins/objects.js b/src/lib/serverPlugins/objects.js new file mode 100644 index 0000000..e238415 --- /dev/null +++ b/src/lib/serverPlugins/objects.js @@ -0,0 +1,49 @@ +var Entity=require("prismarine-entity"); +var vec3 = require("vec3"); + +module.exports = inject; + +function inject(serv) { + serv.spawnObject = (type, world, position, {pitch=0,yaw=0,velocity=vec3(0,0,0),data=0}={}) => { + serv.entityMaxId++; + var object = new Entity(serv.entityMaxId); + object.type = 'object'; + object.entityType = type; + object.data = data; + object.velocity = velocity.scaled(32).floored(); + object.pitch = pitch; + object.yaw = yaw; + object.world = world; + object.gravity = vec3(0, -20*32, 0); + object.terminalvelocity = vec3(27*32, 27*32, 27*32); + object.friction = vec3(0.91*32, 0, 0.91*32).floored(); + object.position = position.scaled(32).floored(); + object.size = vec3(0.25*32, 0.25*32, 0.25*32); // Hardcoded, will be dependent on type! + serv.entities[object.id] = object; + + var scaledVelocity = object.velocity.scaled(250/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 + } + }, { + world: world, + position: object.position + }); + + setTimeout(() => { + serv.destroyEntity(object); + }, 1000*10); + } +} \ No newline at end of file diff --git a/src/lib/serverPlugins/tick.js b/src/lib/serverPlugins/tick.js index 04e95ed..5ec0a6d 100644 --- a/src/lib/serverPlugins/tick.js +++ b/src/lib/serverPlugins/tick.js @@ -3,6 +3,7 @@ module.exports = inject; function inject(serv, settings) { serv.tickCount = 0; + serv.lastTickTime = 0; serv.setTickInterval = ticksPerSecond => { @@ -10,7 +11,10 @@ function inject(serv, settings) { serv.tickInterval = setInterval(() => { serv.tickCount++; - serv.emit('tick', serv.tickCount); + var time = (Date.now() - serv.lastTickTime) / 1000; + if (time > 100) time = 0; + serv.emit('tick', time, serv.tickCount); + serv.lastTickTime = Date.now(); }, 1000/ticksPerSecond); }; From 0684ff481f7026b392b39966b3e7969b4cb9681b Mon Sep 17 00:00:00 2001 From: DemiPixel Date: Sat, 7 Nov 2015 23:17:38 -0800 Subject: [PATCH 2/8] Added mobs, /spawn, fixed bugs, added many more --- package.json | 2 +- src/lib/playerPlugins/commands.js | 18 ++ src/lib/playerPlugins/digging.js | 7 +- src/lib/playerPlugins/pvp.js | 3 +- src/lib/playerPlugins/updatePositions.js | 2 +- src/lib/serverPlugins/entities.js | 216 +++++++++++++++++++---- src/lib/serverPlugins/objects.js | 49 ----- 7 files changed, 204 insertions(+), 93 deletions(-) delete mode 100644 src/lib/serverPlugins/objects.js diff --git a/package.json b/package.json index ad7e743..f1808f8 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "prismarine-block": "0.1.0", "prismarine-chunk": "0.2.1", "prismarine-entity": "0.1.0", - "prismarine-world": "0.3.1", + "prismarine-world": "0.3.3", "prismarine-world-sync": "0.1.0", "random-seed": "^0.2.0", "request-promise": "^0.4.3", diff --git a/src/lib/playerPlugins/commands.js b/src/lib/playerPlugins/commands.js index 9033db0..c86b68b 100644 --- a/src/lib/playerPlugins/commands.js +++ b/src/lib/playerPlugins/commands.js @@ -307,6 +307,24 @@ function inject(serv, player) { } }); + base.add({ + base: 'spawn', + info: 'Spawn an entity', + usage: '/spawn ', + parse(str) { + var results=str.match(/(\d+)/); + if (!results) return false; + return { + id: parseInt(results[1]) + } + }, + action({id}) { + serv.spawnMob(id, player.world, player.entity.position.scaled(1/32), { + velocity: Vec3((Math.random() - 0.5) * 5 + 5, Math.random()*10 + 10, (Math.random() - 0.5) * 5 + 5) + }); + } + }) + serv.commands = base; player.handleCommand = (str) => { diff --git a/src/lib/playerPlugins/digging.js b/src/lib/playerPlugins/digging.js index 2479e47..269285b 100644 --- a/src/lib/playerPlugins/digging.js +++ b/src/lib/playerPlugins/digging.js @@ -90,9 +90,12 @@ function inject(serv,player) { var vec = Vec3(location.x, location.y, location.z); var id = await player.world.getBlockType(vec); + var damage = await player.world.getBlockData(vec); + console.log('meh',id,damage); serv.spawnObject(2, player.world, vec.clone().add(Vec3(0.5, 0.5, 0.5)), { - data: 0, - velocity: Vec3(Math.random()*4 - 2, Math.random()*2 + 2, Math.random()*4 - 2) + velocity: Vec3(Math.random()*4 - 2, Math.random()*2 + 2 + 20, Math.random()*4 - 2), + itemId: id, + itemDamage: damage }); return player.changeBlock(location,0,0); } diff --git a/src/lib/playerPlugins/pvp.js b/src/lib/playerPlugins/pvp.js index bf3e177..01c875b 100644 --- a/src/lib/playerPlugins/pvp.js +++ b/src/lib/playerPlugins/pvp.js @@ -14,8 +14,9 @@ function inject(serv, player) function attackEntity(entityId) { + if (!serv.entities[entityId]) return; // ????? var attackedPlayer = serv.entities[entityId].player; - if(attackedPlayer.gameMode!=0 || !attackedPlayer) return; + if(!attackedPlayer || attackedPlayer.gameMode!=0) return; attackedPlayer.updateHealth(attackedPlayer.entity.health - 1); serv.playSound('game.player.hurt', player.world, attackedPlayer.entity.position.scaled(1/32)); diff --git a/src/lib/playerPlugins/updatePositions.js b/src/lib/playerPlugins/updatePositions.js index d9c6bb5..2a22ec7 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.minus(player.entity.position); + var diff = newPosition.scaled(1/32).scaled(32).minus(player.entity.position.scaled(1/32).scaled(32)); if(diff.abs().x>127 || diff.abs().y>127 || diff.abs().z>127) { player._writeOthersNearby('entity_teleport', { diff --git a/src/lib/serverPlugins/entities.js b/src/lib/serverPlugins/entities.js index 185ebba..65ec915 100644 --- a/src/lib/serverPlugins/entities.js +++ b/src/lib/serverPlugins/entities.js @@ -1,59 +1,197 @@ +var Entity=require("prismarine-entity"); +var blocks=require("minecraft-data")(require("../version")).blocks; +var mobs=require("minecraft-data")(require("../version")).entitiesByName; var vec3 = require("vec3"); module.exports = inject; function inject(serv) { + + serv.initEntity = (type, entityType, world, position) => { + serv.entityMaxId++; + var entity = new Entity(serv.entityMaxId); + console.log('Spawn entity',entity.id); + entity.type = type; + entity.entityType = entityType; + entity.world = world; + entity.position = position; + + entity.bornTime = Date.now(); + serv.entities[entity.id] = entity; + + 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) { + addGravity(entity, 'x', delta); + addGravity(entity, 'y', delta); + addGravity(entity, 'z', delta); + } + + var vSign = getSign(entity.velocity); + var sizeSigned = vec3(vSign.x * entity.size.x, vSign.y * entity.size.y, vSign.z * entity.size.z); + + var xVec = entity.position.offset(entity.velocity.x*delta + sizeSigned.x/2, 0, 0).scaled(1/32).floored(); + var yVec = entity.position.offset(0, entity.velocity.y*delta + sizeSigned.y/2, 0).scaled(1/32).floored(); + var zVec = entity.position.offset(0, 0, entity.velocity.z*delta + sizeSigned.z/2).scaled(1/32).floored(); + + //console.log(xVec, yVec, zVec); + //console.log(entity.velocity); + + // Get block for each (x/y/z)Vec, check to avoid duplicate getBlockTypes + var xBlock = blocks[await entity.world.getBlockType(xVec)].boundingBox == 'block'; + var yBlock = yVec.equals(xVec) ? xBlock : blocks[await entity.world.getBlockType(yVec)].boundingBox == 'block'; + var zBlock = zVec.equals(yVec) ? yBlock : (zVec.equals(xVec) ? xBlock : blocks[await entity.world.getBlockType(zVec)].boundingBox == 'block'); + + var old = entity.position.clone(); + + if (xBlock || yBlock || zBlock) { + entity.velocity.x = getFriction(entity.velocity.x, entity.friction.x, delta); + entity.velocity.z = getFriction(entity.velocity.x, entity.friction.x, delta); + } + + //console.log('afterfric',entity.velocity); + + var oldPos = entity.position.clone(); + + entity.position.x += getMoveAmount('x', xBlock, entity, delta, sizeSigned.x); + entity.position.y += getMoveAmount('y', yBlock, entity, delta, sizeSigned.y); + entity.position.z += getMoveAmount('z', zBlock, entity, delta, sizeSigned.z); + + //console.log(entity.position, old); + + 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); + if(diff.abs().x>127 || diff.abs().y>127 || diff.abs().z>127) + serv._writeNearby('entity_teleport', { + entityId: entity.id, + x: entity.position.x, + y: entity.position.y, + z: entity.position.z, + yaw: entity.yaw, + pitch: entity.pitch, + onGround: onGround + }); + else serv._writeNearby('rel_entity_move', { + entityId: entity.id, + dX: diff.x, + dY: diff.y, + dZ: diff.z, + onGround: onGround + }, entity); + } + + return entity; + } + + serv.spawnObject = (type, world, position, {pitch=0,yaw=0,velocity=vec3(0,0,0),data=1,itemId,itemDamage=0}={}) => { + var object = serv.initEntity('object', type, world, position.scaled(32).floored()); + object.data = data; + object.velocity = velocity.scaled(32).floored(); + object.pitch = pitch; + object.yaw = yaw; + object.gravity = vec3(0, -20*32, 0); + object.terminalvelocity = vec3(27*32, 27*32, 27*32); + object.friction = vec3(10*32, 0, 10*32).floored(); + 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); + + if (typeof itemId != 'undefined') { + console.log(itemId, itemDamage); + object.setMetadata([{ + "key": 10, + "type": 5, + "value": { + blockId: itemId, + itemDamage: itemDamage + } + }]); + } + } + + serv.spawnMob = (type, world, position, {pitch=0,yaw=0,headPitch=0,velocity=vec3(0,0,0),metadata=[]}={}) => { + var mob = serv.initEntity('mob', type, world, position.scaled(32).floored()); + mob.velocity = velocity.scaled(32).floored(); + mob.pitch = pitch; + mob.headPitch = headPitch; + mob.yaw = yaw; + mob.gravity = vec3(0, -20*32, 0); + mob.terminalvelocity = vec3(27*32, 27*32, 27*32); + mob.friction = vec3(10*32, 0, 10*32); + 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); + } + serv.on('tick', function(delta) { Promise.all( Object.keys(serv.entities).map(async (id) => { var entity = serv.entities[id]; + if (entity.deathTime && Date.now() - entity.bornTime >= entity.deathTime) { + entity.destroy(); + return; + } if (!entity.velocity || !entity.size) return; - if (entity.gravity) { - addGravity(entity, 'x', delta); - addGravity(entity, 'y', delta); - addGravity(entity, 'z', delta); - } - - var vSign = getSign(entity.velocity); - var sizeSigned = vec3(vSign.x * entity.size.x, vSign.y * entity.size.y, vSign.z * entity.size.z); - - var xVec = entity.position.offset(entity.velocity.x*delta + sizeSigned.x/2, 0, 0).scaled(1/32).floored(); - var yVec = entity.position.offset(0, entity.velocity.y*delta + sizeSigned.y/2, 0).scaled(1/32).floored(); - var zVec = entity.position.offset(0, 0, entity.velocity.z*delta + sizeSigned.z/2).scaled(1/32).floored(); - - //console.log(xVec, yVec, zVec); - //console.log(entity.velocity); - - // Get block for each (x/y/z)Vec, check to avoid duplicate getBlockTypes - var xBlock = (await entity.world.getBlockType(xVec)) != 0; - var yBlock = yVec.equals(xVec) ? xBlock : (await entity.world.getBlockType(yVec)) != 0; - var zBlock = zVec.equals(yVec) ? yBlock : (zVec.equals(xVec) ? xBlock : (await entity.world.getBlockType(zVec)) != 0); - - var old = entity.position.clone(); - - if (xBlock || yBlock || zBlock) { - entity.velocity.x = getFriction(entity.velocity.x, entity.friction.x, delta); - entity.velocity.z = getFriction(entity.velocity.x, entity.friction.x, delta); - } - - //console.log('afterfric',entity.velocity); - - entity.position.x += getMoveAmount('x', xBlock, entity, delta, sizeSigned.x); - entity.position.y += getMoveAmount('y', yBlock, entity, delta, sizeSigned.y); - entity.position.z += getMoveAmount('z', zBlock, entity, delta, sizeSigned.z); - - //console.log(entity.position, old); - - serv.emitParticle(23, serv.overworld, entity.position.scaled(1/32), { size: vec3(0, 0, 0) }); + var oldPosAndOnGround = await entity.calculatePhysics(delta); + if (entity.type == 'mob') entity.sendPosition(oldPosAndOnGround); }) ).catch((err)=> setTimeout(() => {throw err;},0)); }); serv.destroyEntity = entity => { - console.log('Destroying'); serv._writeNearby('entity_destroy', { entityIds: [entity.id] - }, entity.position); + }, { + position: entity.position, + world: entity.world + }); delete serv.entities[entity.id]; } } diff --git a/src/lib/serverPlugins/objects.js b/src/lib/serverPlugins/objects.js deleted file mode 100644 index e238415..0000000 --- a/src/lib/serverPlugins/objects.js +++ /dev/null @@ -1,49 +0,0 @@ -var Entity=require("prismarine-entity"); -var vec3 = require("vec3"); - -module.exports = inject; - -function inject(serv) { - serv.spawnObject = (type, world, position, {pitch=0,yaw=0,velocity=vec3(0,0,0),data=0}={}) => { - serv.entityMaxId++; - var object = new Entity(serv.entityMaxId); - object.type = 'object'; - object.entityType = type; - object.data = data; - object.velocity = velocity.scaled(32).floored(); - object.pitch = pitch; - object.yaw = yaw; - object.world = world; - object.gravity = vec3(0, -20*32, 0); - object.terminalvelocity = vec3(27*32, 27*32, 27*32); - object.friction = vec3(0.91*32, 0, 0.91*32).floored(); - object.position = position.scaled(32).floored(); - object.size = vec3(0.25*32, 0.25*32, 0.25*32); // Hardcoded, will be dependent on type! - serv.entities[object.id] = object; - - var scaledVelocity = object.velocity.scaled(250/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 - } - }, { - world: world, - position: object.position - }); - - setTimeout(() => { - serv.destroyEntity(object); - }, 1000*10); - } -} \ No newline at end of file From cc072e24642471b7ed3d2442003b6fd8812430eb Mon Sep 17 00:00:00 2001 From: DemiPixel Date: Sun, 8 Nov 2015 09:06:37 -0800 Subject: [PATCH 3/8] Add cool sounds, remove some debugging --- src/lib/playerPlugins/placeBlock.js | 16 +++++++++++++++- src/lib/serverPlugins/entities.js | 9 +-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/lib/playerPlugins/placeBlock.js b/src/lib/playerPlugins/placeBlock.js index 7f7ec42..26ed2e6 100644 --- a/src/lib/playerPlugins/placeBlock.js +++ b/src/lib/playerPlugins/placeBlock.js @@ -1,5 +1,16 @@ +var blocks=require("minecraft-data")(require("../version")).blocks; var vec3 = require("vec3"); +var materialToSound = { + undefined: 'stone', + 'rock': 'stone', + 'dirt': 'grass', + 'plant': 'grass', + 'wool': 'cloth', + 'web': 'cloth', + 'wood': 'wood' +} + module.exports=inject; function inject(serv,player) @@ -11,7 +22,10 @@ function inject(serv,player) var placedPosition=referencePosition.plus(directionVector); player.world.getBlockType(referencePosition).then((id) => { if([25].indexOf(id) != -1) return; - serv.playSound('random.click', player.world, placedPosition.clone().add(vec3(0.5, 0.5, 0.5))); + var sound = 'dig.' + (materialToSound[blocks[heldItem.blockId].material] || 'stone'); + serv.playSound(sound, player.world, placedPosition.clone().add(vec3(0.5, 0.5, 0.5)), { + pitch: 0.8 + }); if(heldItem.blockId!=323){ player.changeBlock(placedPosition,heldItem.blockId,heldItem.itemDamage); }else if(direction==1){ diff --git a/src/lib/serverPlugins/entities.js b/src/lib/serverPlugins/entities.js index 65ec915..4f37f9c 100644 --- a/src/lib/serverPlugins/entities.js +++ b/src/lib/serverPlugins/entities.js @@ -44,9 +44,6 @@ function inject(serv) { var yVec = entity.position.offset(0, entity.velocity.y*delta + sizeSigned.y/2, 0).scaled(1/32).floored(); var zVec = entity.position.offset(0, 0, entity.velocity.z*delta + sizeSigned.z/2).scaled(1/32).floored(); - //console.log(xVec, yVec, zVec); - //console.log(entity.velocity); - // Get block for each (x/y/z)Vec, check to avoid duplicate getBlockTypes var xBlock = blocks[await entity.world.getBlockType(xVec)].boundingBox == 'block'; var yBlock = yVec.equals(xVec) ? xBlock : blocks[await entity.world.getBlockType(yVec)].boundingBox == 'block'; @@ -59,17 +56,13 @@ function inject(serv) { entity.velocity.z = getFriction(entity.velocity.x, entity.friction.x, delta); } - //console.log('afterfric',entity.velocity); - var oldPos = entity.position.clone(); entity.position.x += getMoveAmount('x', xBlock, entity, delta, sizeSigned.x); entity.position.y += getMoveAmount('y', yBlock, entity, delta, sizeSigned.y); entity.position.z += getMoveAmount('z', zBlock, entity, delta, sizeSigned.z); - //console.log(entity.position, old); - - serv.emitParticle(30, serv.overworld, entity.position.scaled(1/32), { size: vec3(0, 0, 0) }); + //serv.emitParticle(30, serv.overworld, entity.position.scaled(1/32), { size: vec3(0, 0, 0) }); return { oldPos: oldPos, onGround: yBlock} } From 687b8b971fa315437a7dad98be98a58672d8068d Mon Sep 17 00:00:00 2001 From: DemiPixel Date: Sun, 8 Nov 2015 14:46:56 -0800 Subject: [PATCH 4/8] Remove debugging, fix flying blocks --- src/lib/playerPlugins/digging.js | 3 +-- src/lib/serverPlugins/entities.js | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/lib/playerPlugins/digging.js b/src/lib/playerPlugins/digging.js index 269285b..bc871e6 100644 --- a/src/lib/playerPlugins/digging.js +++ b/src/lib/playerPlugins/digging.js @@ -91,9 +91,8 @@ function inject(serv,player) var vec = Vec3(location.x, location.y, location.z); var id = await player.world.getBlockType(vec); var damage = await player.world.getBlockData(vec); - console.log('meh',id,damage); serv.spawnObject(2, player.world, vec.clone().add(Vec3(0.5, 0.5, 0.5)), { - velocity: Vec3(Math.random()*4 - 2, Math.random()*2 + 2 + 20, Math.random()*4 - 2), + velocity: Vec3(Math.random()*4 - 2, Math.random()*2 + 2, Math.random()*4 - 2), itemId: id, itemDamage: damage }); diff --git a/src/lib/serverPlugins/entities.js b/src/lib/serverPlugins/entities.js index 4f37f9c..6a318cf 100644 --- a/src/lib/serverPlugins/entities.js +++ b/src/lib/serverPlugins/entities.js @@ -10,7 +10,6 @@ function inject(serv) { serv.initEntity = (type, entityType, world, position) => { serv.entityMaxId++; var entity = new Entity(serv.entityMaxId); - console.log('Spawn entity',entity.id); entity.type = type; entity.entityType = entityType; entity.world = world; @@ -121,7 +120,6 @@ function inject(serv) { }, object); if (typeof itemId != 'undefined') { - console.log(itemId, itemDamage); object.setMetadata([{ "key": 10, "type": 5, From 9c61b7b009ecd0dd84578b4fb7c7bb015cd942ff Mon Sep 17 00:00:00 2001 From: DemiPixel Date: Mon, 9 Nov 2015 13:25:42 -0800 Subject: [PATCH 5/8] 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) { From f0c17d38b4f950f3f04af0315540a510fd56334e Mon Sep 17 00:00:00 2001 From: DemiPixel Date: Tue, 10 Nov 2015 21:12:53 -0800 Subject: [PATCH 6/8] Almost done with entities, needs some more finishing touches --- src/lib/playerPlugins/commands.js | 2 +- src/lib/playerPlugins/digging.js | 24 ++++++++++--------- src/lib/playerPlugins/world.js | 10 ++++++++ src/lib/serverPlugins/entities.js | 40 ++++++++++++++++++------------- 4 files changed, 47 insertions(+), 29 deletions(-) diff --git a/src/lib/playerPlugins/commands.js b/src/lib/playerPlugins/commands.js index c86b68b..81924dc 100644 --- a/src/lib/playerPlugins/commands.js +++ b/src/lib/playerPlugins/commands.js @@ -320,7 +320,7 @@ function inject(serv, player) { }, action({id}) { serv.spawnMob(id, player.world, player.entity.position.scaled(1/32), { - velocity: Vec3((Math.random() - 0.5) * 5 + 5, Math.random()*10 + 10, (Math.random() - 0.5) * 5 + 5) + velocity: Vec3((Math.random() - 0.5) * 10, Math.random()*10 + 10, (Math.random() - 0.5) * 10) }); } }) diff --git a/src/lib/playerPlugins/digging.js b/src/lib/playerPlugins/digging.js index bc871e6..1b7566b 100644 --- a/src/lib/playerPlugins/digging.js +++ b/src/lib/playerPlugins/digging.js @@ -70,12 +70,22 @@ function inject(serv,player) }); } - function completeDigging(location) + async function completeDigging(location) { clearInterval(animationInterval); var diggingTime=new Date()-startDiggingTime; - if(expectedDiggingTime-diggingTime<100) + if(expectedDiggingTime-diggingTime<100) { player.changeBlock(location,0,0); + // Drop block + var vec = Vec3(location.x, location.y, location.z); + var id = await player.world.getBlockType(vec); + var damage = await player.world.getBlockData(vec); + serv.spawnObject(2, player.world, vec.clone().add(Vec3(0.5, 0.5, 0.5)), { + velocity: Vec3(Math.random()*4 - 2, Math.random()*2 + 2, Math.random()*4 - 2), + itemId: id, + itemDamage: damage + }); + } else { player._client.write("block_change",{ @@ -86,16 +96,8 @@ function inject(serv,player) } - async function creativeDigging(location) + function creativeDigging(location) { - var vec = Vec3(location.x, location.y, location.z); - var id = await player.world.getBlockType(vec); - var damage = await player.world.getBlockData(vec); - serv.spawnObject(2, player.world, vec.clone().add(Vec3(0.5, 0.5, 0.5)), { - velocity: Vec3(Math.random()*4 - 2, Math.random()*2 + 2, Math.random()*4 - 2), - itemId: id, - itemDamage: damage - }); return player.changeBlock(location,0,0); } diff --git a/src/lib/playerPlugins/world.js b/src/lib/playerPlugins/world.js index acdd280..59c59ed 100644 --- a/src/lib/playerPlugins/world.js +++ b/src/lib/playerPlugins/world.js @@ -7,6 +7,16 @@ function inject(serv, player) { player.spawnEntity = entity => { player._client.write(entity.spawnPacketName, entity.getSpawnPacket()); + if (typeof entity.itemId != 'undefined') { + entity.setMetadata([{ + "key": 10, + "type": 5, + "value": { + blockId: entity.itemId, + itemDamage: entity.itemDamage + } + }]); + } }; player.sendChunk = (chunkX,chunkZ,column) => diff --git a/src/lib/serverPlugins/entities.js b/src/lib/serverPlugins/entities.js index 290a16b..74f8e9d 100644 --- a/src/lib/serverPlugins/entities.js +++ b/src/lib/serverPlugins/entities.js @@ -2,21 +2,27 @@ var Entity=require("prismarine-entity"); var blocks=require("minecraft-data")(require("../version")).blocks; var mobs=require("minecraft-data")(require("../version")).entitiesByName; var vec3 = require("vec3"); +var EventEmitter = require('events').EventEmitter; +var util = require('util'); module.exports = inject; function inject(serv) { + util.inherits(Entity, EventEmitter); + serv.initEntity = (type, entityType, world, position) => { serv.entityMaxId++; var entity = new Entity(serv.entityMaxId); + EventEmitter.call(entity); entity.type = type; entity.spawnPacketName = ''; entity.entityType = entityType; entity.world = world; entity.position = position; + entity.lastPositionPlayersUpdated = entity.position.clone(); entity.nearbyEntities = []; - entity.viewDistance = 15; + entity.viewDistance = 150; entity.bornTime = Date.now(); serv.entities[entity.id] = entity; @@ -25,6 +31,11 @@ function inject(serv) { else if (entity.type == 'object') entity.spawnPacketName = 'spawn_entity'; else if (entity.type == 'mob') entity.spawnPacketName = 'spawn_entity_living'; + entity.on("positionChanged",() => { + if(entity.position.distanceTo(entity.lastPositionPlayersUpdated)>2*32) + entity.updateAndSpawn(); + }); + entity.setMetadata = (data) => { serv._writeNearby('entity_metadata', { entityId: entity.id, @@ -74,6 +85,7 @@ function inject(serv) { entity.sendPosition = ({oldPos,onGround}) => { var diff = entity.position.minus(oldPos); + if(diff.abs().x>127 || diff.abs().y>127 || diff.abs().z>127) serv._writeNearby('entity_teleport', { entityId: entity.id, @@ -83,7 +95,7 @@ function inject(serv) { yaw: entity.yaw, pitch: entity.pitch, onGround: onGround - }); + }, entity); else serv._writeNearby('rel_entity_move', { entityId: entity.id, dX: diff.x, @@ -91,6 +103,8 @@ function inject(serv) { dZ: diff.z, onGround: onGround }, entity); + + entity.emit('positionChanged', oldPos); } entity.getSpawnPacket = () => { @@ -156,14 +170,14 @@ function inject(serv) { if (entity.type == 'player') { entity.player.despawnEntities(entitiesToRemove); entitiesToAdd.forEach(entity.player.spawnEntity); - entity.player.lastPositionPlayersUpdated=entity.position; + entity.player.lastPositionPlayersUpdated=entity.position.clone(); + } else { + entity.lastPositionPlayersUpdated=entity.position.clone(); } 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)); @@ -186,19 +200,10 @@ function inject(serv) { object.friction = vec3(10*32, 0, 10*32).floored(); object.size = vec3(0.25*32, 0.25*32, 0.25*32); // Hardcoded, will be dependent on type! object.deathTime = 60*1000; // 60 seconds + object.itemId = itemId; + object.itemDamage = itemDamage; object.updateAndSpawn(); - - if (typeof itemId != 'undefined') { - object.setMetadata([{ - "key": 10, - "type": 5, - "value": { - blockId: itemId, - itemDamage: itemDamage - } - }]); - } } serv.spawnMob = (type, world, position, {pitch=0,yaw=0,headPitch=0,velocity=vec3(0,0,0),metadata=[]}={}) => { @@ -226,7 +231,8 @@ function inject(serv) { } if (!entity.velocity || !entity.size) return; var oldPosAndOnGround = await entity.calculatePhysics(delta); - if (entity.type == 'mob') entity.sendPosition(oldPosAndOnGround); + if (!oldPosAndOnGround.oldPos.equals(vec3(0,0,0))) + if (entity.type == 'mob') entity.sendPosition(oldPosAndOnGround); }) ).catch((err)=> setTimeout(() => {throw err;},0)); }); From 47b6e00d5ed9625edf630503bc2261a91036f600 Mon Sep 17 00:00:00 2001 From: Romain Beaumont Date: Wed, 11 Nov 2015 11:37:06 +0100 Subject: [PATCH 7/8] fix block drop (use currentlyDugBlock instead of getting air) --- src/lib/playerPlugins/digging.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/lib/playerPlugins/digging.js b/src/lib/playerPlugins/digging.js index 1b7566b..e022820 100644 --- a/src/lib/playerPlugins/digging.js +++ b/src/lib/playerPlugins/digging.js @@ -77,13 +77,10 @@ function inject(serv,player) if(expectedDiggingTime-diggingTime<100) { player.changeBlock(location,0,0); // Drop block - var vec = Vec3(location.x, location.y, location.z); - var id = await player.world.getBlockType(vec); - var damage = await player.world.getBlockData(vec); - serv.spawnObject(2, player.world, vec.clone().add(Vec3(0.5, 0.5, 0.5)), { + serv.spawnObject(2, player.world, location.offset(0.5, 0.5, 0.5), { velocity: Vec3(Math.random()*4 - 2, Math.random()*2 + 2, Math.random()*4 - 2), - itemId: id, - itemDamage: damage + itemId: currentlyDugBlock.type, + itemDamage: currentlyDugBlock.metadata }); } else From 78149b646e8f06fef894076dc8b800757f8e1788 Mon Sep 17 00:00:00 2001 From: Romain Beaumont Date: Mon, 16 Nov 2015 19:50:33 +0100 Subject: [PATCH 8/8] fix changing world --- src/lib/playerPlugins/world.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/playerPlugins/world.js b/src/lib/playerPlugins/world.js index 59c59ed..73e5c51 100644 --- a/src/lib/playerPlugins/world.js +++ b/src/lib/playerPlugins/world.js @@ -107,7 +107,7 @@ function inject(serv, player) { }); player.entity.position=player.spawnPoint.toFixedPosition(); player.sendSpawnPosition(); - player.updateAndSpawnNearbyPlayers(); + player.entity.updateAndSpawn(); await player.sendMap();