mirror of
https://github.com/danbulant/flying-squid
synced 2026-07-05 19:20:54 +00:00
Finish basic implementation of selectors
This commit is contained in:
parent
843fa1ffa2
commit
e151d6958e
2 changed files with 111 additions and 17 deletions
|
|
@ -1,4 +1,6 @@
|
||||||
module.exports.player=function(player) {
|
var Vec3 = require("vec3").Vec3;
|
||||||
|
|
||||||
|
module.exports.player=function(player, serv) {
|
||||||
|
|
||||||
player.commands.add({
|
player.commands.add({
|
||||||
base: 'help',
|
base: 'help',
|
||||||
|
|
@ -73,6 +75,22 @@ module.exports.player=function(player) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
player.commands.add({
|
||||||
|
base: 'selector',
|
||||||
|
info: 'Get array from selector',
|
||||||
|
usage: '/selector <selector>',
|
||||||
|
op: true,
|
||||||
|
parse(str) {
|
||||||
|
return str || false;
|
||||||
|
},
|
||||||
|
action(sel) {
|
||||||
|
var arr = serv.selectorString(sel, player.position.scaled(1/32), player.world);
|
||||||
|
if (arr instanceof Error) return arr.toString();
|
||||||
|
else if (arr == null) return 'Could not find player';
|
||||||
|
else player.chat(JSON.stringify(arr.map(a => a.id)));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
player.handleCommand = async (str) => {
|
player.handleCommand = async (str) => {
|
||||||
try {
|
try {
|
||||||
|
|
@ -86,6 +104,28 @@ module.exports.player=function(player) {
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.server = function(serv) {
|
module.exports.server = function(serv) {
|
||||||
|
|
||||||
|
function shuffleArray(array) {
|
||||||
|
var currentIndex = array.length, temporaryValue, randomIndex ;
|
||||||
|
|
||||||
|
// While there remain elements to shuffle...
|
||||||
|
while (0 !== currentIndex) {
|
||||||
|
|
||||||
|
// Pick a remaining element...
|
||||||
|
randomIndex = Math.floor(Math.random() * currentIndex);
|
||||||
|
currentIndex -= 1;
|
||||||
|
|
||||||
|
// And swap it with the current element.
|
||||||
|
temporaryValue = array[currentIndex];
|
||||||
|
array[currentIndex] = array[randomIndex];
|
||||||
|
array[randomIndex] = temporaryValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
var notudf = i => typeof i != 'undefined';
|
||||||
|
|
||||||
serv.selector = (type, opt) => {
|
serv.selector = (type, opt) => {
|
||||||
if (['all', 'random', 'near', 'entity'].indexOf(type) == -1)
|
if (['all', 'random', 'near', 'entity'].indexOf(type) == -1)
|
||||||
return new Error('serv.selector(): type must be either [all, random, near, or entity]');
|
return new Error('serv.selector(): type must be either [all, random, near, or entity]');
|
||||||
|
|
@ -96,10 +136,11 @@ module.exports.server = function(serv) {
|
||||||
var pos = opt.pos;
|
var pos = opt.pos;
|
||||||
var sample;
|
var sample;
|
||||||
if (type == 'all') sample = serv.players;
|
if (type == 'all') sample = serv.players;
|
||||||
else if (type == 'random' || type == 'near') sample.players.filter(p => p.health != 0);
|
else if (type == 'random' || type == 'near') sample = serv.players.filter(p => p.health != 0);
|
||||||
else if (type == 'entity') sample = Object.keys(serv.entities).map(k => serv.entities[k]);
|
else if (type == 'entity') sample = Object.keys(serv.entities).map(k => serv.entities[k]);
|
||||||
|
|
||||||
var checkOption = (val, compare) => {
|
var checkOption = (val, compare) => {
|
||||||
|
if (!val) return true;
|
||||||
var not = val[0] == '!';
|
var not = val[0] == '!';
|
||||||
var v = val;
|
var v = val;
|
||||||
if (not) v = v.slice(1, v.length);
|
if (not) v = v.slice(1, v.length);
|
||||||
|
|
@ -108,29 +149,73 @@ module.exports.server = function(serv) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
sample.filter(s => {
|
var scores = {
|
||||||
if ((opt.radius && s.position.distanceTo(pos) > opt.radius) ||
|
max: [],
|
||||||
(opt.minRadius && s.position.distanceTo(pos) < opt.minRadius) ||
|
min: []
|
||||||
(opt.gameMode && s.gameMode != opt.gameMode) ||
|
};
|
||||||
(opt.level && s.level > opt.level) ||
|
|
||||||
(opt.minLevel && s.level < opt.minLevel) ||
|
Object.keys(opt).forEach(o => {
|
||||||
(opt.yaw && s.yaw > opt.yaw) ||
|
if (o.indexOf('score_') != 0) return;
|
||||||
(opt.minYaw && s.yaw < opt.minYaw) ||
|
var score = o.replace('score_', '');
|
||||||
(opt.pitch && s.pitch > opt.pitch) ||
|
if (score.indexOf('_min') == score.length - 1) {
|
||||||
(opt.minPitch && s.pitch < opt.minPitch))
|
scores.min.push({
|
||||||
|
score: score.replace('_min' ,''),
|
||||||
|
val: opt[o]
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
scores.max.push({
|
||||||
|
score: score,
|
||||||
|
val: opt[o]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
sample = sample.filter(s => {
|
||||||
|
if ((notudf(opt.radius) && s.position.scaled(1/32).distanceTo(pos) > opt.radius) ||
|
||||||
|
(notudf(opt.minRadius) && s.position.scaled(1/32).distanceTo(pos) < opt.minRadius) ||
|
||||||
|
(notudf(opt.gameMode) && s.gameMode != opt.gameMode) ||
|
||||||
|
(notudf(opt.level) && s.level > opt.level) ||
|
||||||
|
(notudf(opt.minLevel) && s.level < opt.minLevel) ||
|
||||||
|
(notudf(opt.yaw) && s.yaw > opt.yaw) ||
|
||||||
|
(notudf(opt.minYaw) && s.yaw < opt.minYaw) ||
|
||||||
|
(notudf(opt.pitch) && s.pitch > opt.pitch) ||
|
||||||
|
(notudf(opt.minPitch) && s.pitch < opt.minPitch))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!checkOption(opt.team, s.team)) return false;
|
if (!checkOption(opt.team, s.team)) return false;
|
||||||
if (!checkOption(opt.name, s.username)) return false;
|
if (!checkOption(opt.name, s.username)) return false;
|
||||||
if (!checkOption(opt.type, s.type)) return false; // "type" option of selector needs fixing
|
if (!checkOption(opt.type, s.type)) return false; // "type" option of selector needs fixing
|
||||||
|
|
||||||
|
var fail = false;
|
||||||
|
scores.max.forEach(m => {
|
||||||
|
if (fail) return;
|
||||||
|
if (!notudf(s.scores[m.score])) fail = true;
|
||||||
|
else if (s.scores[m] > m.val) fail = true;
|
||||||
|
});
|
||||||
|
if (fail) return false;
|
||||||
|
scores.min.forEach(m => {
|
||||||
|
if (fail) return;
|
||||||
|
if (!notudf(s.scores[m.score])) faii = true;
|
||||||
|
else if (s.scores[m] < m.val) fail = true;
|
||||||
|
});
|
||||||
|
if (fail) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (type == 'near') sample.sort((a,b) => a.position.distanceTo(opt.pos) > b.position.distanceTo(opt.pos));
|
||||||
|
else if (type == 'random') sample = shuffleArray(sample);
|
||||||
|
else sample = sample.reverse(); // Front = newest
|
||||||
|
|
||||||
|
if (count > 0) return sample.slice(0, count);
|
||||||
|
else return sample.slice(count); // Negative, returns from end
|
||||||
}
|
}
|
||||||
|
|
||||||
serv.selectorString = (str, pos) => {
|
serv.selectorString = (str, pos, world) => {
|
||||||
pos = pos.clone();
|
pos = pos.clone();
|
||||||
var player = serv.getPlayer(str);
|
var player = serv.getPlayer(str);
|
||||||
if (!player && str[0] != '@') return null;
|
if (!player && str[0] != '@') return null;
|
||||||
var match = str.match(/^@([a,r,p,e])(\[[^\]]+\])?$/);
|
var match = str.match(/^@([a,r,p,e])(?:\[([^\]]+)\])?$/);
|
||||||
if (match == null) return new Error('Invalid selector format');
|
if (match == null) return new Error('Invalid selector format');
|
||||||
var typeConversion = {
|
var typeConversion = {
|
||||||
a: 'all',
|
a: 'all',
|
||||||
|
|
@ -139,7 +224,7 @@ module.exports.server = function(serv) {
|
||||||
e: 'entity'
|
e: 'entity'
|
||||||
};
|
};
|
||||||
var type = typeConversion[match[1]];
|
var type = typeConversion[match[1]];
|
||||||
var opt = match[2].split(',');
|
var opt = match[2] ? match[2].split(',') : [];
|
||||||
var optPair = [];
|
var optPair = [];
|
||||||
var err;
|
var err;
|
||||||
opt.forEach(o => {
|
opt.forEach(o => {
|
||||||
|
|
@ -164,18 +249,26 @@ module.exports.server = function(serv) {
|
||||||
ry: 'pitch',
|
ry: 'pitch',
|
||||||
rym: 'minPitch'
|
rym: 'minPitch'
|
||||||
};
|
};
|
||||||
|
var convertInt = ['r', 'rm', 'm', 'c', 'l', 'lm', 'rx', 'rxm', 'ry', 'rym'];
|
||||||
|
|
||||||
var data = {
|
var data = {
|
||||||
pos: pos
|
pos: pos,
|
||||||
|
world: world,
|
||||||
|
scores: [],
|
||||||
|
minScores: []
|
||||||
};
|
};
|
||||||
|
|
||||||
optPair.forEach(({key,val}) => {
|
optPair.forEach(({key,val}) => {
|
||||||
if (['x', 'y', 'z'].indexOf(key) != -1) pos[key] = val;
|
if (['x', 'y', 'z'].indexOf(key) != -1) pos[key] = val;
|
||||||
|
else if (!optConversion[key]) {
|
||||||
|
data[key] = val;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
|
if (convertInt.indexOf(key) != -1) val = parseInt(val);
|
||||||
data[optConversion[key]] = val;
|
data[optConversion[key]] = val;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return serv.selector(data);
|
return serv.selector(type, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -182,6 +182,7 @@ module.exports.entity=function(entity,serv) {
|
||||||
entity.lastPositionPlayersUpdated = entity.position.clone();
|
entity.lastPositionPlayersUpdated = entity.position.clone();
|
||||||
entity.nearbyEntities = [];
|
entity.nearbyEntities = [];
|
||||||
entity.viewDistance = 150;
|
entity.viewDistance = 150;
|
||||||
|
entity.score = {};
|
||||||
|
|
||||||
entity.bornTime = Date.now();
|
entity.bornTime = Date.now();
|
||||||
serv.entities[entity.id] = entity;
|
serv.entities[entity.id] = entity;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue