implement infinite world, fix #43, fix #52, progress on #47

This commit is contained in:
Romain Beaumont 2015-10-08 22:50:04 +02:00
parent a79181b27e
commit d3a20e4399
4 changed files with 88 additions and 27 deletions

View file

@ -34,10 +34,11 @@
"prismarine-block": "0.1.0", "prismarine-block": "0.1.0",
"prismarine-chunk": "0.2.1", "prismarine-chunk": "0.2.1",
"prismarine-entity": "0.1.0", "prismarine-entity": "0.1.0",
"prismarine-world": "0.1.0", "prismarine-world": "0.2.0",
"request-promise": "^0.4.3", "request-promise": "^0.4.3",
"requireindex": "~1.0.0", "requireindex": "~1.0.0",
"vec3": "0.1.3" "vec3": "0.1.3",
"spiralloop": "1.0.2"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

View file

@ -1,4 +1,6 @@
var Entity=require("prismarine-entity"); var Entity=require("prismarine-entity");
var spiralloop = require('spiralloop');
var Vec3=require("vec3");
module.exports=inject; module.exports=inject;
@ -17,9 +19,11 @@ function inject(serv,player)
player.entity.player=player; player.entity.player=player;
player.entity.health = 20; player.entity.health = 20;
player.entity.food = 20; player.entity.food = 20;
player.view=8;
player.username=player._client.username; player.username=player._client.username;
serv.players.push(player); serv.players.push(player);
serv.uuidToPlayer[player._client.uuid] = player; serv.uuidToPlayer[player._client.uuid] = player;
player.loadedChunks={};
} }
function sendLogin() function sendLogin()
@ -34,20 +38,78 @@ function inject(serv,player)
reducedDebugInfo: false, reducedDebugInfo: false,
maxPlayers: serv._server.maxPlayers maxPlayers: serv._server.maxPlayers
}); });
player.entity.position=player.spawnPoint.scaled(32);
} }
function spiral(arr)
{
var t=[];
spiralloop(arr,function(x,z){
t.push([x,z]);
});
return t;
}
function sendChunk(chunkX,chunkZ,column)
{
player._client.write('map_chunk', {
x: chunkX,
z: chunkZ,
groundUp: true,
bitMap: 0xffff,
chunkData: column.dump()
});
return Promise.resolve();
}
function sendChunksAroundPlayer(view)
{
player.lastPositionChunkUpdated=player.entity.position;
var playerChunkX=Math.floor(player.entity.position.x/16/32);
var playerChunkZ=Math.floor(player.entity.position.z/16/32);
return spiral([view*2,view*2])
.map(t => ({
chunkX:playerChunkX+t[0]-view,
chunkZ:playerChunkZ+t[1]-view
}))
.filter(({chunkX,chunkZ}) => {
var key=chunkX+","+chunkZ;
var loaded=player.loadedChunks[key];
if(!loaded) player.loadedChunks[key]=1;
return !loaded;
})
.reduce((acc,{chunkX,chunkZ})=>
acc
//.then(() => sleep(10))
.then(() => serv.world.getColumn(chunkX,chunkZ))
.then((column) => sendChunk(chunkX,chunkZ,column))
,Promise.resolve());
}
function sendMap() function sendMap()
{ {
serv.world.getColumns().forEach(function(column){ var initialChunks=sendChunksAroundPlayer(2);
player._client.write('map_chunk', { player.sendingChunks=true;
x: column.chunkX, sendChunksAroundPlayer(player.view).then(() => player.sendingChunks=false);
z: column.chunkZ,
groundUp: true, player.on("positionChanged",function(){
bitMap: 0xffff, if(!player.sendingChunks && player.entity.position.distanceTo(player.lastPositionChunkUpdated)>16*32)
chunkData: column.column.dump() {
}); player.sendingChunks=true;
sendChunksAroundPlayer(player.view).then(() => player.sendingChunks=false);
}
}); });
return initialChunks;
} }
function sleep(ms = 0) {
return new Promise(r => setTimeout(r, ms));
}
function sendSpawnPosition() function sendSpawnPosition()
{ {
console.log("setting spawn at "+player.spawnPoint); console.log("setting spawn at "+player.spawnPoint);
@ -161,7 +223,7 @@ function inject(serv,player)
player.emit("connected"); player.emit("connected");
} }
function login() async function login()
{ {
if (serv.uuidToPlayer[player._client.uuid]) { if (serv.uuidToPlayer[player._client.uuid]) {
player._client.end("You are already connected"); player._client.end("You are already connected");
@ -174,7 +236,7 @@ function inject(serv,player)
addPlayer(); addPlayer();
sendLogin(); sendLogin();
sendMap(); await sendMap();
sendSpawnPosition(); sendSpawnPosition();
sendInitialPosition(); sendInitialPosition();
@ -189,7 +251,6 @@ function inject(serv,player)
announceJoin(); announceJoin();
} }
player.setGameMode=setGameMode; player.setGameMode=setGameMode;
player.login=login; player.login=login;
player.sendInitialPosition=sendInitialPosition; player.sendInitialPosition=sendInitialPosition;

View file

@ -4,7 +4,7 @@ module.exports=inject;
function toFixedPosition(p) function toFixedPosition(p)
{ {
return new vec3(Math.floor(p.x*32),Math.floor(p.y*32),Math.floor(p.z*32)) return p.scaled(32);
} }
function inject(serv,player) function inject(serv,player)
@ -80,5 +80,6 @@ function inject(serv,player)
} }
player.entity.position = newPosition; player.entity.position = newPosition;
player.entity.onGround = onGround; player.entity.onGround = onGround;
player.emit("positionChanged");
} }
} }

View file

@ -6,22 +6,20 @@ module.exports=inject;
function inject(serv) { function inject(serv) {
serv.world=new World(); function generateSimpleChunk(chunkX, chunkZ) {
var chunk=new Chunk();
for(var chunkX=-1;chunkX<2;chunkX++) for (var x = 0; x < 16;x++) {
{ for (var z = 0; z < 16; z++) {
for(var chunkZ=-1;chunkZ<2;chunkZ++) chunk.setBlockType(new Vec3(x, 50, z), 2);
{ for (var y = 0; y < 256; y++) {
var chunk=new Chunk(); chunk.setSkyLight(new Vec3(x, y, z), 15);
for (var x = 0; x < 16;x++) {
for (var z = 0; z < 16; z++) {
chunk.setBlockType(new Vec3(x, 50, z), 2);
for (var y = 0; y < 256; y++) {
chunk.setSkyLight(new Vec3(x, y, z), 15);
}
} }
} }
serv.world.setColumn(chunkX,chunkZ,chunk);
} }
return chunk;
} }
serv.world=new World(generateSimpleChunk);
} }