Code:
// Position object class
// x, y, z as coordinates
function Position(x, y, z)
{
if(typeof(x) == "undefined" || !x
|| typeof(y) == "undefined" || !y
|| typeof(z) == "undefined" || !z)
{
return new Error("Position: must define x, y, and z as coordinates.");
}
const X = Number(x);
const Y = Number(y);
const Z = Number(z);
// Setting the time: JavaScript returns milliseconds, but we only need to work in seconds (cuts down on calculation effort).
const Time = Math.floor(Date.now()/1000);
/* function Position.validate()
*
* Validates whether or not this position is acceptable within the constraints of the system.
*
* @param oldPos (Position) - the old position to check against
* @param opt (Object) - The options for the validation. Required:
* dim: whether to use 2 or 3 dimensions in the rate calculation.
* maxRate: the max rate, as units of distance per second
*/
this.validate = function(oldPos, opt) {
// First check if oldPos is a Position object, and opts have everything we need
if(!(oldPos instanceof Position))
{
console.error(new Error("Position.validate(): oldPos is not a position!"));
return false;
}
else
// Next check if opt is valid
if(typeof(opt) != "Object"
|| !('dimensions' in opt)
|| !opt.dimensions
|| !('maxRate' in opt)
|| !opt.maxRate)
{
console.error(new Error("Position.validate(): Some required options missing.");
return false;
}
else
{
var deltaX = Math.abs(X - oldPos.getX()),
deltaY = Math.abs(Y - oldPos.getY()),
deltaZ = Math.abs(Z - oldPos.getZ()),
deltaTime = Math.abs(Time - oldPos.getTime());
var deltaXY = Math.sqrt(deltaX^2 + deltaY^2);
var deltaXYZ = Math.sqrt(deltaXY^2 + deltaZ^2);
var rate = 0;
if(opt.dim <= 2)
{
rate = deltaXY/deltaTime;
}
else
if(opt.dim >= 3)
{
rate = deltaXYZ/deltaTime;
}
// Allowing some leniency for latency
if(rate > opt.maxRate*1.5)
{
return false;
}
else
{
return true;
}
}
}
this.getX = function()
{
return X;
}
this.getY = function()
{
return Y;
}
this.getZ = function()
{
return Z;
}
this.getTime = function()
{
return Time;
}
}
// On middleware call to register position, call this method:
Character.prototype.setPos = function(x, y, z)
{
var newPos = new Position(x, y, z);
if(newPos.validate(this.position, {"dim": 2, "maxRate": this.getMaxVelocity()}))
{
// Position is valid, so update it on the Character.
this.position = newPos;
}
else
{
// Position is invalid, so flag this character for scrutiny so the GMs can nuke their cheating arses from orbit.
this.flagForRMTReview();
}
}