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); };