mirror of
https://github.com/danbulant/flying-squid
synced 2026-06-18 14:01:13 +00:00
implement portal detection and use it when flint and steel is used
currently places cactus instead of nether block because nether block seems to require the multi block change packet lot of tests are already there, but some more need to be added, it seems some cases don't work (when the portal have edges it seems)
This commit is contained in:
parent
3e8e49bf4c
commit
539b9c1314
5 changed files with 271 additions and 3 deletions
|
|
@ -24,6 +24,8 @@
|
|||
"dependencies": {
|
||||
"babel-runtime": "^5.4.4",
|
||||
"emit-then": "^1.0.2",
|
||||
"event-promise": "0.0.1",
|
||||
"flatmap": "0.0.3",
|
||||
"minecraft-data": "0.7.0",
|
||||
"minecraft-protocol": "0.16.3",
|
||||
"mkdirp": "0.5.1",
|
||||
|
|
@ -38,11 +40,11 @@
|
|||
"prismarine-world": "0.3.3",
|
||||
"prismarine-world-sync": "0.1.0",
|
||||
"random-seed": "^0.2.0",
|
||||
"range": "0.0.3",
|
||||
"request-promise": "^0.4.3",
|
||||
"requireindex": "~1.0.0",
|
||||
"spiralloop": "1.0.2",
|
||||
"vec3": "0.1.3",
|
||||
"event-promise": "0.0.1"
|
||||
"vec3": "0.1.3"
|
||||
},
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ module.exports = {
|
|||
version:require("./lib/version"),
|
||||
generations:require("./lib/generations"),
|
||||
experience:require("./lib/experience"),
|
||||
UserError:require("./lib/user_error")
|
||||
UserError:require("./lib/user_error"),
|
||||
portal_detector:require('./lib/portal_detector')
|
||||
};
|
||||
|
||||
function createMCServer(options) {
|
||||
|
|
|
|||
30
src/lib/plugins/useItem.js
Normal file
30
src/lib/plugins/useItem.js
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
var items=require("minecraft-data")(require("flying-squid").version).items;
|
||||
var Vec3 = require("vec3").Vec3;
|
||||
var {detectFrame,getAir}=require("flying-squid").portal_detector;
|
||||
|
||||
module.exports.player=function(player,serv)
|
||||
{
|
||||
player._client.on("block_place",({direction,heldItem,location} = {}) => {
|
||||
if (direction == -1 || heldItem.blockId == -1 || !items[heldItem.blockId]) return;
|
||||
var referencePosition = new Vec3(location.x, location.y, location.z);
|
||||
var directionVector = directionToVector[direction];
|
||||
var position = referencePosition.plus(directionVector);
|
||||
|
||||
var item= items[heldItem.blockId];
|
||||
if(item.name=="flint_and_steel")
|
||||
player.use_flint_and_steel(referencePosition,directionVector);
|
||||
});
|
||||
|
||||
player.use_flint_and_steel=async (referencePosition,direction) => {
|
||||
let block=await player.world.getBlock(referencePosition);
|
||||
if(block.name=="obsidian")
|
||||
{
|
||||
var frames=await detectFrame(player.world,referencePosition,direction);
|
||||
if(frames.length==0)
|
||||
return;
|
||||
var air=getAir(frames[0]);
|
||||
air.forEach(pos => player.setBlock(pos,81,0))
|
||||
}
|
||||
};
|
||||
};
|
||||
var directionToVector=[new Vec3(0,-1,0),new Vec3(0,1,0),new Vec3(0,0,-1),new Vec3(0,0,1),new Vec3(-1,0,0),new Vec3(1,0,0)];
|
||||
87
src/lib/portal_detector.js
Normal file
87
src/lib/portal_detector.js
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
var Vec3 = require("vec3").Vec3;
|
||||
var assert = require('assert');
|
||||
var flatMap = require('flatmap');
|
||||
var range = require('range').range;
|
||||
|
||||
module.exports={detectFrame,findPotentialLines,findBorder,getAir};
|
||||
|
||||
async function findLineInDirection(world,startingPoint,type,direction,directionV)
|
||||
{
|
||||
var line=[];
|
||||
var point=startingPoint;
|
||||
while((await world.getBlock(point)).name==type && (await world.getBlockType(point.plus(directionV)))==0)
|
||||
{
|
||||
line.push(point);
|
||||
point=point.plus(direction);
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
async function findLine(world,startingPoint,type,direction,directionV)
|
||||
{
|
||||
var firstSegment=(await findLineInDirection(world,startingPoint.plus(direction.scaled(-1)),type,direction.scaled(-1),directionV)).reverse();
|
||||
var secondSegment=await findLineInDirection(world,startingPoint,type,direction,directionV);
|
||||
return firstSegment.concat(secondSegment);
|
||||
}
|
||||
|
||||
|
||||
async function findPotentialLines(world,startingPoint,directionV)
|
||||
{
|
||||
var firstLineDirection=directionV.y!=0 ? [new Vec3(1,0,0),new Vec3(0,0,1)] :
|
||||
[new Vec3(0,1,0)];
|
||||
return (await Promise.all(firstLineDirection
|
||||
.map(async d => ({direction:d,line:(await findLine(world,startingPoint,'obsidian',d,directionV))}))))
|
||||
.filter(line => (line.line.length>=3 && line.direction.y!=0) ||
|
||||
(line.line.length>=2 && line.direction.y==0));
|
||||
}
|
||||
|
||||
function positiveOrder(line,direction)
|
||||
{
|
||||
if(direction.x==-1 || direction.y==-1 || direction.z==-1)
|
||||
return line.reverse();
|
||||
return line;
|
||||
}
|
||||
|
||||
async function findBorder(world,{line,direction},directionV)
|
||||
{
|
||||
var bottom=line;
|
||||
if(bottom.length==0)
|
||||
return [];
|
||||
var left=await findLineInDirection(world,bottom[0].plus(direction.scaled(-1).plus(directionV)),'obsidian',directionV,direction);
|
||||
var right=await findLineInDirection(world,bottom[line.length-1].plus(direction).plus(directionV),'obsidian',
|
||||
directionV,direction);
|
||||
if(left.length!=right.length)
|
||||
return null;
|
||||
var top=await findLineInDirection(world,left[left.length-1].plus(direction).plus(directionV),'obsidian',
|
||||
direction,directionV);
|
||||
if(bottom.length!=top.length)
|
||||
return null;
|
||||
left=positiveOrder(left,directionV);
|
||||
right=positiveOrder(right,directionV);
|
||||
top=positiveOrder(top,direction);
|
||||
|
||||
|
||||
if(direction.y!=0)
|
||||
[bottom,left,right,top]=[left,bottom,top,right];
|
||||
|
||||
[bottom,top]=directionV.y<0 ? [top,bottom] : [bottom,top];
|
||||
var horDir=direction.x!=0 || directionV.x!=0 ? 'x' :'z';
|
||||
[left,right]=direction[horDir]<0 || directionV[horDir]<0 ? [right,left] : [left,right];
|
||||
|
||||
return [bottom,left,right,top];
|
||||
}
|
||||
|
||||
async function detectFrame(world,startingPoint,directionV)
|
||||
{
|
||||
let potentialLines=await findPotentialLines(world,startingPoint,directionV);
|
||||
|
||||
return (await Promise.all(potentialLines
|
||||
.map(line => findBorder(world,line,directionV))))
|
||||
.filter(border => border!=null);
|
||||
}
|
||||
|
||||
function getAir(border)
|
||||
{
|
||||
var [bottom,,,top]=border;
|
||||
return flatMap(bottom,pos => range(1,top[0].y-bottom[0].y).map(i => pos.offset(0,i,0)));
|
||||
}
|
||||
148
test/portal_detector.js
Normal file
148
test/portal_detector.js
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
var {detectFrame,findPotentialLines,findBorder,getAir}=require("flying-squid").portal_detector;
|
||||
var World = require('prismarine-world');
|
||||
var Chunk = require('prismarine-chunk')(require("flying-squid").version);
|
||||
var Vec3 = require("vec3").Vec3;
|
||||
var assert = require('assert');
|
||||
|
||||
|
||||
describe("Detect portal", function() {
|
||||
|
||||
|
||||
|
||||
var bottom=[new Vec3(3, 1, 1), new Vec3(4, 1, 1)];
|
||||
var left=[new Vec3(2, 2, 1), new Vec3(2, 3, 1), new Vec3(2, 4, 1)];
|
||||
var right=[new Vec3(5, 2, 1), new Vec3(5, 3, 1), new Vec3(5, 4, 1)];
|
||||
var top=[new Vec3(3, 5, 1), new Vec3(4, 5, 1)];
|
||||
var expectedBorder=[
|
||||
bottom,
|
||||
left,
|
||||
right,
|
||||
top
|
||||
];
|
||||
var air=[new Vec3(3, 2, 1),new Vec3(3, 3, 1),new Vec3(3, 4, 1),new Vec3(4, 2, 1),new Vec3(4, 3, 1),new Vec3(4, 4, 1)];
|
||||
|
||||
var world;
|
||||
before(function(){
|
||||
world=new World();
|
||||
var chunk=new Chunk();
|
||||
|
||||
expectedBorder.forEach(border => border.forEach(pos => chunk.setBlockType(pos,49)));
|
||||
air.forEach(pos => chunk.setBlockType(pos,0));
|
||||
|
||||
return world.setColumn(0,0,chunk);
|
||||
});
|
||||
|
||||
|
||||
describe("detect potential first lines",function(){
|
||||
it("detect potential first lines from bottom left", async function() {
|
||||
let potentialLines=await findPotentialLines(world,bottom[0],new Vec3(0,1,0));
|
||||
assert.deepEqual(potentialLines,[
|
||||
{
|
||||
"direction": new Vec3(1,0,0),
|
||||
"line": bottom
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it("detect potential first lines from bottom right", async function() {
|
||||
let potentialLines=await findPotentialLines(world,bottom[bottom.length-1],new Vec3(0,1,0));
|
||||
assert.deepEqual(potentialLines,[
|
||||
{
|
||||
"direction": new Vec3(1,0,0),
|
||||
"line": bottom
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
|
||||
it("detect potential first lines from top left", async function() {
|
||||
let potentialLines=await findPotentialLines(world,top[0],new Vec3(0,-1,0));
|
||||
assert.deepEqual(potentialLines,[
|
||||
{
|
||||
"direction": new Vec3(1,0,0),
|
||||
"line": top
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it("detect potential first lines from top right", async function() {
|
||||
let potentialLines=await findPotentialLines(world,top[top.length-1],new Vec3(0,-1,0));
|
||||
assert.deepEqual(potentialLines,[
|
||||
{
|
||||
"direction": new Vec3(1,0,0),
|
||||
"line": top
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it("detect potential first lines from left top", async function() {
|
||||
let potentialLines=await findPotentialLines(world,left[left.length-1],new Vec3(1,0,0));
|
||||
assert.deepEqual(potentialLines,[
|
||||
{
|
||||
"direction": new Vec3(0,1,0),
|
||||
"line": left
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it("detect potential first lines from right bottom", async function() {
|
||||
let potentialLines=await findPotentialLines(world,right[0],new Vec3(-1,0,0));
|
||||
assert.deepEqual(potentialLines,[
|
||||
{
|
||||
"direction": new Vec3(0,1,0),
|
||||
"line": right
|
||||
}
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe("find borders",function() {
|
||||
it("find borders from bottom", async function () {
|
||||
var border = await findBorder(world, {
|
||||
"direction": new Vec3(1, 0, 0),
|
||||
"line": bottom
|
||||
}, new Vec3(0, 1, 0));
|
||||
assert.deepEqual(border, expectedBorder)
|
||||
});
|
||||
|
||||
it("find borders from top", async function () {
|
||||
var border = await findBorder(world, {
|
||||
"direction": new Vec3(1, 0, 0),
|
||||
"line": top
|
||||
}, new Vec3(0, -1, 0));
|
||||
assert.deepEqual(border, expectedBorder)
|
||||
});
|
||||
|
||||
it("find borders from left", async function () {
|
||||
var border = await findBorder(world, {
|
||||
"direction": new Vec3(0, 1, 0),
|
||||
"line": left
|
||||
}, new Vec3(1, 0, 0));
|
||||
assert.deepEqual(border, expectedBorder)
|
||||
});
|
||||
it("find borders from right", async function () {
|
||||
var border = await findBorder(world, {
|
||||
"direction": new Vec3(0, 1, 0),
|
||||
"line": right
|
||||
}, new Vec3(-1, 0, 0));
|
||||
assert.deepEqual(border, expectedBorder)
|
||||
});
|
||||
});
|
||||
|
||||
describe("detect portals",function(){
|
||||
it("detect portals from bottom left",async function() {
|
||||
var portals=await detectFrame(world,bottom[0],new Vec3(0,1,0));
|
||||
assert.deepEqual(portals,[expectedBorder])
|
||||
});
|
||||
it("detect portals from right top",async function() {
|
||||
var portals=await detectFrame(world,right[right.length-1],new Vec3(-1,0,0));
|
||||
assert.deepEqual(portals,[expectedBorder])
|
||||
})
|
||||
});
|
||||
|
||||
it("get air",function(){
|
||||
var foundAir=getAir(expectedBorder);
|
||||
assert.deepEqual(foundAir,air);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue