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-chunk": "0.2.1",
"prismarine-entity": "0.1.0",
"prismarine-world": "0.1.0",
"prismarine-world": "0.2.0",
"request-promise": "^0.4.3",
"requireindex": "~1.0.0",
"vec3": "0.1.3"
"vec3": "0.1.3",
"spiralloop": "1.0.2"
},
"repository": {
"type": "git",

View file

@ -1,4 +1,6 @@
var Entity=require("prismarine-entity");
var spiralloop = require('spiralloop');
var Vec3=require("vec3");
module.exports=inject;
@ -17,9 +19,11 @@ function inject(serv,player)
player.entity.player=player;
player.entity.health = 20;
player.entity.food = 20;
player.view=8;
player.username=player._client.username;
serv.players.push(player);
serv.uuidToPlayer[player._client.uuid] = player;
player.loadedChunks={};
}
function sendLogin()
@ -34,20 +38,78 @@ function inject(serv,player)
reducedDebugInfo: false,
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()
{
serv.world.getColumns().forEach(function(column){
player._client.write('map_chunk', {
x: column.chunkX,
z: column.chunkZ,
groundUp: true,
bitMap: 0xffff,
chunkData: column.column.dump()
});
var initialChunks=sendChunksAroundPlayer(2);
player.sendingChunks=true;
sendChunksAroundPlayer(player.view).then(() => player.sendingChunks=false);
player.on("positionChanged",function(){
if(!player.sendingChunks && player.entity.position.distanceTo(player.lastPositionChunkUpdated)>16*32)
{
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()
{
console.log("setting spawn at "+player.spawnPoint);
@ -161,7 +223,7 @@ function inject(serv,player)
player.emit("connected");
}
function login()
async function login()
{
if (serv.uuidToPlayer[player._client.uuid]) {
player._client.end("You are already connected");
@ -174,7 +236,7 @@ function inject(serv,player)
addPlayer();
sendLogin();
sendMap();
await sendMap();
sendSpawnPosition();
sendInitialPosition();
@ -189,7 +251,6 @@ function inject(serv,player)
announceJoin();
}
player.setGameMode=setGameMode;
player.login=login;
player.sendInitialPosition=sendInitialPosition;

View file

@ -4,7 +4,7 @@ module.exports=inject;
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)
@ -80,5 +80,6 @@ function inject(serv,player)
}
player.entity.position = newPosition;
player.entity.onGround = onGround;
player.emit("positionChanged");
}
}

View file

@ -6,22 +6,20 @@ module.exports=inject;
function inject(serv) {
serv.world=new World();
function generateSimpleChunk(chunkX, chunkZ) {
var chunk=new Chunk();
for(var chunkX=-1;chunkX<2;chunkX++)
{
for(var chunkZ=-1;chunkZ<2;chunkZ++)
{
var chunk=new Chunk();
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);
}
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);
}