From f8c5eac2fbbd75cf0a75880b8447f8a165290b11 Mon Sep 17 00:00:00 2001 From: DemiPixel Date: Thu, 10 Dec 2015 08:29:07 -0800 Subject: [PATCH 1/5] Begin implementing effects --- src/lib/plugins/commands.js | 2 + src/lib/plugins/effects.js | 83 +++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 src/lib/plugins/effects.js diff --git a/src/lib/plugins/commands.js b/src/lib/plugins/commands.js index 41d44ce..9fb3258 100644 --- a/src/lib/plugins/commands.js +++ b/src/lib/plugins/commands.js @@ -121,6 +121,8 @@ module.exports.player=function(player, serv) { else setTimeout(() => {throw err;}, 0); } } + + player.selectorString = (str) => serv.selectorString(str, player.position.scaled(1/32), player.world); }; module.exports.entity = function(entity, serv) { diff --git a/src/lib/plugins/effects.js b/src/lib/plugins/effects.js new file mode 100644 index 0000000..93a5dd2 --- /dev/null +++ b/src/lib/plugins/effects.js @@ -0,0 +1,83 @@ + +module.exports.entity = function(entity, serv) { + entity.effects = {}; + for (var i = 1; i <= 23; i++) { // 23 in 1.8, 27 in 1.9 + entity.effects[i] = null; // Just so we know it's a real potion and not undefined/not existant + } + + entity.sendEffect = (effectId, {amplifier=0,duration=30*20,particles=true,whitelist,blacklist=[]}={}) => { + if (!whitelist) whitelist = serv.getNearby(entity); + var sendTo = whitelist.filter(p => blacklist.indexOf(p) == -1); + var data = { + entityId: entity.id, + effectId: effectId, + amplifier: amplifier, + duration: duration, + hideParticles: !particles + }; + console.log(data); + serv._writeArray('entity_effect', data, sendTo); + }; + + entity.sendRemoveEffect = (effectId, {whitelist,blacklist=[]}={}) => { + if (!whitelist) whitelist = serv.getNearby(entity); + var sendTo = whitelist.filter(p => blacklist.indexOf(p) == -1); + serv._writeArray('remove_entity_effect', { + entityId: entity.id, + effectId: effectId + }, sendTo); + }; + + entity.addEffect = (effectId, opt={}) => { + var amp = typeof opt.amplifier == 'undefined' ? 0 : opt.amplifier; + if (!entity.effects[effectId] || opt.override || amp < entity.effects[effectId].amplifier) { + entity.effects[effectId] = { + amplifier: opt.amplifier || 0, + duration: opt.duration || 30*20, + particles: opt.particles || true, + }; + entity.sendEffect(effectId, opt); + return true; + } else return false; + } + + entity.removeEffect = (effectId, opt) => { + entity.effects[effectId] = null; + entity.sendRemoveEffect(effectId, opt); + }; +}; + +module.exports.player = function(player, serv) { + player.commands.add({ + base: 'effect', + info: 'Give player an effect', + usage: '/effect [seconds] [amplifier] [hideParticles]', + parse(str) { + return str.match(/(.+?) (\d+)(?: (\d+))?(?: (\d+))?(?: (true|false))?|.*? clear/) || false; + }, + action(params) { + var targets = player.selectorString(params[1]); + if (params[2] == 'clear') { + targets.forEach(e => Object.keys(e.effects).forEach(effectId => { + if (e.effects[effectId] != null) e.removeEffect(effectId); + })); + } else { + targets.forEach(e => { + var effId = parseInt(params[2]); + if (e.effects[effId]) { + e.removeEffect(effId); + } + e.addEffect(effId, { + amplifier: parseInt(params[4]) || 0, + duration: parseInt(params[3]) * 20 || 30 * 20, + particles: params[5] != 'true' // hidesParticles vs particles (i.e. "showParticles") + }); + }); + } + var chatSelect = (targets.length == 1 ? (targets[0].type == 'player' ? targets[0].username : 'entity') : 'entities'); + if (params[2] == 'clear') player.chat('Remove all effects from ' + chatSelect + '.' ); + else player.chat('Gave ' + chatSelect + ' effect ' + params[2] + '(' + (params[4] || 0) + ') for ' + + (parseInt(params[3]) || 30) + ' seconds'); + } + }); +} \ No newline at end of file From 0092af247e86564dbf8acc5e7426584e68e74ac5 Mon Sep 17 00:00:00 2001 From: DemiPixel Date: Thu, 10 Dec 2015 14:16:58 -0800 Subject: [PATCH 2/5] Start of implementing player abilities --- src/lib/plugins/effects.js | 1 + src/lib/plugins/login.js | 1 + src/lib/plugins/updatePositions.js | 12 ++++++++++++ 3 files changed, 14 insertions(+) diff --git a/src/lib/plugins/effects.js b/src/lib/plugins/effects.js index 93a5dd2..ad35f0a 100644 --- a/src/lib/plugins/effects.js +++ b/src/lib/plugins/effects.js @@ -7,6 +7,7 @@ module.exports.entity = function(entity, serv) { entity.sendEffect = (effectId, {amplifier=0,duration=30*20,particles=true,whitelist,blacklist=[]}={}) => { if (!whitelist) whitelist = serv.getNearby(entity); + if (entity.type == 'player' && [1].indexOf(effectId) != -1) entity.sendAbilities(); var sendTo = whitelist.filter(p => blacklist.indexOf(p) == -1); var data = { entityId: entity.id, diff --git a/src/lib/plugins/login.js b/src/lib/plugins/login.js index 8b158eb..880b58c 100644 --- a/src/lib/plugins/login.js +++ b/src/lib/plugins/login.js @@ -173,5 +173,6 @@ module.exports.player=function(player,serv) await player.waitPlayerLogin(); player.sendRestMap(); sendChunkWhenMove(); + player.sendAbilities(); }; }; \ No newline at end of file diff --git a/src/lib/plugins/updatePositions.js b/src/lib/plugins/updatePositions.js index 55fe0af..3a63266 100644 --- a/src/lib/plugins/updatePositions.js +++ b/src/lib/plugins/updatePositions.js @@ -67,6 +67,18 @@ module.exports.player=function(player) var notCancelled = await player.sendPosition(position.scaled(32).floored(), false, true); if (notCancelled) player.sendSelfPosition(); } + + player.sendAbilities = () => { + var f = (+(player.gameMode == 1)*1) + (+(player.gameMode == 1 || player.gameMode == 3)*2) + (+(player.gameMode == 1 || player.gamemode == 3)*4); + var walkingSpeed = 1.0 + ((player.effects[1] != null ? (player.effects[1].amplifier + 1) : 0) * 0.2) + var flyingSpeed = 0.2; + console.log(walkingSpeed, flyingSpeed); + player._client.write('abilities', { + flags: f, + walkingSpeed: walkingSpeed, + flyingSpeed: flyingSpeed + }); + } }; module.exports.entity=function(entity,serv){ From 0adfc20a1f555f7db20e13d269162fe51b1c8ccb Mon Sep 17 00:00:00 2001 From: DemiPixel Date: Fri, 11 Dec 2015 01:03:21 -0800 Subject: [PATCH 3/5] Continuing attempt to implement abilities --- doc/API.md | 2 +- src/lib/plugins/chest.js | 9 ++++---- src/lib/plugins/commands.js | 2 -- src/lib/plugins/communication.js | 3 +++ src/lib/plugins/login.js | 3 ++- src/lib/plugins/physics.js | 35 +++++++++++++++++++++++++++++- src/lib/plugins/updatePositions.js | 26 ++++++---------------- 7 files changed, 52 insertions(+), 28 deletions(-) diff --git a/doc/API.md b/doc/API.md index ea64af8..9bdea62 100644 --- a/doc/API.md +++ b/doc/API.md @@ -840,7 +840,7 @@ Emitted when a player places a block - position: Position they're attempting to place the block - id: Id of block being placed - damage: Data of block being placed -- reference (u): Reference block that was placed on +- reference (u): Reference block (position) that was placed on - direction (u): Direction vector from reference to position - playSound: Which sound to play (Default: true) - sound: Sound to play (Default: default sound for that material) diff --git a/src/lib/plugins/chest.js b/src/lib/plugins/chest.js index 18a91b7..c3072a8 100644 --- a/src/lib/plugins/chest.js +++ b/src/lib/plugins/chest.js @@ -2,13 +2,13 @@ var Vec3 = require("vec3").Vec3; module.exports.player=function(player) { - player._client.on('block_place', async ({location} = {}) => { - var referencePosition=new Vec3(location.x,location.y,location.z); + player.on('placeBlock_cancel', async (opt, cancel) => { if (player.crouching) return; try { - var id = await player.world.getBlockType(referencePosition); - var blockAbove = await player.world.getBlockType(referencePosition.clone().add(new Vec3(0, 1, 0))); + var id = await player.world.getBlockType(opt.reference); + var blockAbove = await player.world.getBlockType(opt.reference.plus(new Vec3(0, 1, 0))); if (id == 54) { + opt.playSound = false; if (blockAbove) { return; } @@ -18,6 +18,7 @@ module.exports.player=function(player) windowTitle: JSON.stringify("Chest"), slotCount: 9 * 3 + 8 // 3 rows, make nicer later }); + cancel(); } } catch(err) { diff --git a/src/lib/plugins/commands.js b/src/lib/plugins/commands.js index 9fb3258..41d44ce 100644 --- a/src/lib/plugins/commands.js +++ b/src/lib/plugins/commands.js @@ -121,8 +121,6 @@ module.exports.player=function(player, serv) { else setTimeout(() => {throw err;}, 0); } } - - player.selectorString = (str) => serv.selectorString(str, player.position.scaled(1/32), player.world); }; module.exports.entity = function(entity, serv) { diff --git a/src/lib/plugins/communication.js b/src/lib/plugins/communication.js index 7df5fc0..f5871a4 100644 --- a/src/lib/plugins/communication.js +++ b/src/lib/plugins/communication.js @@ -48,4 +48,7 @@ module.exports.entity=function(entity,serv) entity._writeOthersNearby = (packetName, packetFields) => serv._writeArray(packetName, packetFields, entity.getNearbyPlayers()); + + entity._writeNearby = (packetName, packetFields) => + serv._writeArray(packetName, packetFields, entity.getNearbyPlayers().concat(entity.type == 'player' ? [entity] : [])); }; \ No newline at end of file diff --git a/src/lib/plugins/login.js b/src/lib/plugins/login.js index 880b58c..9898f4d 100644 --- a/src/lib/plugins/login.js +++ b/src/lib/plugins/login.js @@ -94,6 +94,7 @@ module.exports.player=function(player,serv) gamemode: player.gameMode }] }); + player.sendAbilities(); }; function fillTabList() @@ -161,6 +162,7 @@ module.exports.player=function(player,serv) player.sendSpawnPosition(); player.sendSelfPosition(); player.updateHealth(player.health); + player.sendAbilities(); updateTime(); @@ -173,6 +175,5 @@ module.exports.player=function(player,serv) await player.waitPlayerLogin(); player.sendRestMap(); sendChunkWhenMove(); - player.sendAbilities(); }; }; \ No newline at end of file diff --git a/src/lib/plugins/physics.js b/src/lib/plugins/physics.js index 1a1a70d..076ed84 100644 --- a/src/lib/plugins/physics.js +++ b/src/lib/plugins/physics.js @@ -37,6 +37,22 @@ module.exports.entity=function(entity){ return { position: newPos, onGround: yBlock} }; + entity.sendVelocity = (vel, maxVel) => { + var velocity = vel.scaled(32).floored(); // Make fixed point + var maxVelocity = maxVel.scaled(32).floored(); + var scaledVelocity = velocity.scaled(8000/32/20).floored(); // from fixed-position/second to unit => 1/8000 blocks per tick + entity._writeNearby('entity_velocity', { + entityId: entity.id, + velocityX: scaledVelocity.x, + velocityY: scaledVelocity.y, + velocityZ: scaledVelocity.z + }); + if (entity.type != 'player') { + if (maxVelocity) entity.velocity = addVelocityWithMax(entity.velocity, velocity, maxVelocity); + else entity.velocity.add(velocity); + } + }; + function getMoveAmount(dir, block, entity, delta, sizeSigned) { if (block) { @@ -70,4 +86,21 @@ module.exports.entity=function(entity){ function clamp(a, b, c) { return Math.max(a, Math.min(b, c)); } -}; \ No newline at end of file +}; + +module.exports.player = function(player, serv) { + player.commands.add({ + base: 'velocity', + info: 'Push velocity on player(s)', + usage: '/velocity ', + op: true, + parse(str) { + return str.match(/(.+?) (\d+) (\d+) (\d+)/) || false; + }, + action(params) { + var selector = player.selectorString(params[1]); + var vec = new Vec3(parseInt(params[2]), parseInt(params[3]), parseInt(params[4])); + selector.forEach(e => e.sendVelocity(vec, vec.scaled(5))); + } + }) +} \ No newline at end of file diff --git a/src/lib/plugins/updatePositions.js b/src/lib/plugins/updatePositions.js index 3a63266..686f4d0 100644 --- a/src/lib/plugins/updatePositions.js +++ b/src/lib/plugins/updatePositions.js @@ -69,9 +69,13 @@ module.exports.player=function(player) } player.sendAbilities = () => { - var f = (+(player.gameMode == 1)*1) + (+(player.gameMode == 1 || player.gameMode == 3)*2) + (+(player.gameMode == 1 || player.gamemode == 3)*4); - var walkingSpeed = 1.0 + ((player.effects[1] != null ? (player.effects[1].amplifier + 1) : 0) * 0.2) - var flyingSpeed = 0.2; + var godmode = player.gameMode == 1 || player.gameMode == 3; + var canFly = player.gameMode == 1 || player.gameMode == 3; + var isFlying = !player.onGround && canFly; + var creativeMode = player.gameMode == 1; + var f = (+godmode*8) + (+canFly*4) + (+isFlying*2) + (+creativeMode*1); + var walkingSpeed = 4.3/20 * (1 + (player.effects[1] != null ? (player.effects[1].amplifier + 1) : 0) * 0.2) + var flyingSpeed = 1.0/20; console.log(walkingSpeed, flyingSpeed); player._client.write('abilities', { flags: f, @@ -116,22 +120,6 @@ module.exports.entity=function(entity,serv){ }); }; - entity.sendVelocity = (vel, maxVel) => { - var velocity = vel.scaled(32).floored(); // Make fixed point - var maxVelocity = maxVel.scaled(32).floored(); - var scaledVelocity = velocity.scaled(8000/32/20).floored(); // from fixed-position/second to unit => 1/8000 blocks per tick - entity._writeOthersNearby('entity_velocity', { - entityId: entity.id, - velocityX: scaledVelocity.x, - velocityY: scaledVelocity.y, - velocityZ: scaledVelocity.z - }); - if (entity.type != 'player') { - if (maxVelocity) entity.velocity = addVelocityWithMax(entity.velocity, velocity, maxVelocity); - else entity.velocity.add(velocity); - } - }; - entity.teleport = (pos) => { // Overwritten in players inject above entity.sendPosition(pos.scaled(32), false, true); } From 7d062ad169f77626e1393b740ccaa3f93bc0a869 Mon Sep 17 00:00:00 2001 From: DemiPixel Date: Sun, 13 Dec 2015 16:19:50 -0800 Subject: [PATCH 4/5] Make effects ends, screw player abilities --- src/lib/plugins/effects.js | 9 ++++++++- src/lib/plugins/updatePositions.js | 12 ++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/lib/plugins/effects.js b/src/lib/plugins/effects.js index ad35f0a..007a2da 100644 --- a/src/lib/plugins/effects.js +++ b/src/lib/plugins/effects.js @@ -16,7 +16,6 @@ module.exports.entity = function(entity, serv) { duration: duration, hideParticles: !particles }; - console.log(data); serv._writeArray('entity_effect', data, sendTo); }; @@ -36,6 +35,7 @@ module.exports.entity = function(entity, serv) { amplifier: opt.amplifier || 0, duration: opt.duration || 30*20, particles: opt.particles || true, + end: Date.now() + (opt.duration || 30*20)*1000/20 // 1000/20 == convert from ticks to milliseconds }; entity.sendEffect(effectId, opt); return true; @@ -46,6 +46,13 @@ module.exports.entity = function(entity, serv) { entity.effects[effectId] = null; entity.sendRemoveEffect(effectId, opt); }; + + serv.on('tick', () => { + Object.keys(entity.effects).forEach(effectId => { + var e = entity.effects[effectId]; + if (e && e.end <= Date.now()) entity.removeEffect(effectId); + }); + }); }; module.exports.player = function(player, serv) { diff --git a/src/lib/plugins/updatePositions.js b/src/lib/plugins/updatePositions.js index 686f4d0..10e04e5 100644 --- a/src/lib/plugins/updatePositions.js +++ b/src/lib/plugins/updatePositions.js @@ -68,20 +68,20 @@ module.exports.player=function(player) if (notCancelled) player.sendSelfPosition(); } - player.sendAbilities = () => { + player.sendAbilities = () => { // TODO: Fix all of this... var godmode = player.gameMode == 1 || player.gameMode == 3; var canFly = player.gameMode == 1 || player.gameMode == 3; var isFlying = !player.onGround && canFly; var creativeMode = player.gameMode == 1; var f = (+godmode*8) + (+canFly*4) + (+isFlying*2) + (+creativeMode*1); - var walkingSpeed = 4.3/20 * (1 + (player.effects[1] != null ? (player.effects[1].amplifier + 1) : 0) * 0.2) - var flyingSpeed = 1.0/20; - console.log(walkingSpeed, flyingSpeed); - player._client.write('abilities', { + var walkingSpeed = 0.2 * (1 + (player.effects[1] != null ? (player.effects[1].amplifier + 1) : 0) * 0.2) + var flyingSpeed = 0.1; + /*console.log(walkingSpeed, flyingSpeed); + player._client.write('abilities', { // FIIIIXXXXXXX flags: f, walkingSpeed: walkingSpeed, flyingSpeed: flyingSpeed - }); + });*/ } }; From d269b0a49d6979b81d94e443eb4dce061a54741c Mon Sep 17 00:00:00 2001 From: DemiPixel Date: Sun, 13 Dec 2015 19:35:13 -0800 Subject: [PATCH 5/5] Fix a few things for FX --- src/lib/plugins/physics.js | 13 ++++++++++++- src/lib/plugins/pvp.js | 2 +- src/lib/plugins/updatePositions.js | 11 ----------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/lib/plugins/physics.js b/src/lib/plugins/physics.js index 076ed84..90d4b85 100644 --- a/src/lib/plugins/physics.js +++ b/src/lib/plugins/physics.js @@ -86,6 +86,17 @@ module.exports.entity=function(entity){ function clamp(a, b, c) { return Math.max(a, Math.min(b, c)); } + + function addVelocityWithMax(current, newVel, max) { + var x, y, z; + if (current.x > max.x || current.x < -max.x) x = current.x; + else x = Math.max(-max.x, Math.min(max.x, current.x + newVel.x)); + if (current.y > max.y || current.y < -max.y) y = current.y; + else y = Math.max(-max.y, Math.min(max.y, current.y + newVel.y)); + if (current.z > max.z || current.z < -max.z) z = current.z; + else z = Math.max(-max.z, Math.min(max.z, current.z + newVel.z)); + return new Vec3(x, y, z); + } }; module.exports.player = function(player, serv) { @@ -102,5 +113,5 @@ module.exports.player = function(player, serv) { var vec = new Vec3(parseInt(params[2]), parseInt(params[3]), parseInt(params[4])); selector.forEach(e => e.sendVelocity(vec, vec.scaled(5))); } - }) + }); } \ No newline at end of file diff --git a/src/lib/plugins/pvp.js b/src/lib/plugins/pvp.js index b713845..0dcfa61 100644 --- a/src/lib/plugins/pvp.js +++ b/src/lib/plugins/pvp.js @@ -45,7 +45,7 @@ module.exports.player=function(player,serv) return str || false; }, action(sel) { - var arr = serv.selectorString(sel, player.position.scaled(1/32), player.world); + var arr = player.selectorString(sel); if (arr.length==0) throw new UserError('Could not find player'); arr.map(entity => entity.takeDamage({damage:20})); diff --git a/src/lib/plugins/updatePositions.js b/src/lib/plugins/updatePositions.js index 10e04e5..1157bf6 100644 --- a/src/lib/plugins/updatePositions.js +++ b/src/lib/plugins/updatePositions.js @@ -123,15 +123,4 @@ module.exports.entity=function(entity,serv){ entity.teleport = (pos) => { // Overwritten in players inject above entity.sendPosition(pos.scaled(32), false, true); } - - function addVelocityWithMax(current, newVel, max) { - var x, y, z; - if (current.x > max.x || current.x < -max.x) x = current.x; - else x = Math.max(-max.x, Math.min(max.x, current.x + newVel.x)); - if (current.y > max.y || current.y < -max.y) y = current.y; - else y = Math.max(-max.y, Math.min(max.y, current.y + newVel.y)); - if (current.z > max.z || current.z < -max.z) z = current.z; - else z = Math.max(-max.z, Math.min(max.z, current.z + newVel.z)); - return new Vec3(x, y, z); - } };