From 0684ff481f7026b392b39966b3e7969b4cb9681b Mon Sep 17 00:00:00 2001 From: DemiPixel Date: Sat, 7 Nov 2015 23:17:38 -0800 Subject: [PATCH] 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