overte-thingvellir/script-archive/entityScripts/chessPiece.js
2016-04-26 11:18:22 -07:00

196 lines
7.6 KiB
JavaScript

(function(){
this.FIRST_TILE = null; // Global position of the first tile (1a)
this.TILE_SIZE = null; // Size of one tile
this.wantDebug = false;
this.active = false;
this.entityID = null;
this.properties = null;
this.boardID = null;
this.boardUserData = null;
this.sound = null;
this.startingTile = null;
this.pieces = new Array();
// All callbacks start by updating the properties
this.updateProperties = function(entityID) {
// Piece ID
if (this.entityID === null) {
this.entityID = entityID;
}
// Piece Properties
this.properties = Entities.getEntityProperties(this.entityID);
// Board ID
if (this.boardID === null) {
// Read user data string and update boardID
var userData = JSON.parse(this.properties.userData);
this.boardID = userData.boardID;
}
// Board User Data
this.updateUserData();
}
// Get an entity's user data
this.getEntityUserData = function(entityID) {
var properties = Entities.getEntityProperties(entityID);
if (properties && properties.userData){
return JSON.parse(properties.userData);
} else {
print("No user data found.");
return null;
}
}
// Updates user data related objects
this.updateUserData = function() {
// Get board's user data
if (this.boardID !== null) {
this.boardUserData = this.getEntityUserData(this.boardID);
if (!(this.boardUserData &&
this.boardUserData.firstTile &&
this.boardUserData.tileSize)) {
print("Incomplete boardUserData " + this.boardID);
} else {
this.FIRST_TILE = this.boardUserData.firstTile;
this.TILE_SIZE = this.boardUserData.tileSize;
this.active = true;
}
} else {
print("Missing boardID:" + JSON.stringify(this.boardID));
}
}
// Returns whether pos is inside the grid or not
this.isOutsideGrid = function(pos) {
return !(pos.i >= 0 && pos.j >= 0 && pos.i < 8 && pos.j < 8);
}
// Returns the tile coordinate
this.getIndexPosition = function(position) {
var halfTile = this.TILE_SIZE / 2.0;
var corner = Vec3.sum(this.FIRST_TILE, { x: -halfTile, y: 0.0, z: -halfTile });
var relative = Vec3.subtract(position, corner);
return {
i: Math.floor(relative.x / this.TILE_SIZE),
j: Math.floor(relative.z / this.TILE_SIZE)
}
}
// Returns the world position
this.getAbsolutePosition = function(pos, halfHeight) {
var relative = {
x: pos.i * this.TILE_SIZE,
y: halfHeight,
z: pos.j * this.TILE_SIZE
}
return Vec3.sum(this.FIRST_TILE, relative);
}
// Pr, Vr are respectively the Ray's Point of origin and Vector director
// Pp, Np are respectively the Plane's Point of origin and Normal vector
this.rayPlaneIntersection = function(Pr, Vr, Pp, Np) {
var d = -Vec3.dot(Pp, Np);
var t = -(Vec3.dot(Pr, Np) + d) / Vec3.dot(Vr, Np);
return Vec3.sum(Pr, Vec3.multiply(t, Vr));
}
// Download sound if needed
this.maybeDownloadSound = function() {
if (this.sound === null) {
this.sound = SoundCache.getSound("http://public.highfidelity.io/sounds/Footsteps/FootstepW3Left-12db.wav");
}
}
// Play drop sound
this.playSound = function() {
if (this.sound && this.sound.downloaded) {
Audio.playSound(this.sound, { position: this.properties.position });
}
}
// updates the piece position based on mouse input
this.updatePosition = function(mouseEvent) {
var pickRay = Camera.computePickRay(mouseEvent.x, mouseEvent.y)
var upVector = { x: 0, y: 1, z: 0 };
var intersection = this.rayPlaneIntersection(pickRay.origin, pickRay.direction,
this.properties.position, upVector);
// if piece outside grid then send it back to the starting tile
if (this.isOutsideGrid(this.getIndexPosition(intersection))) {
intersection = this.getAbsolutePosition(this.startingTile, this.properties.dimensions.y / 2.0);
}
Entities.editEntity(this.entityID, { position: intersection });
}
// Snap piece to the center of the tile it is on
this.snapToGrid = function() {
var pos = this.getIndexPosition(this.properties.position);
var finalPos = this.getAbsolutePosition((this.isOutsideGrid(pos)) ? this.startingTile : pos,
this.properties.dimensions.y / 2.0);
Entities.editEntity(this.entityID, { position: finalPos });
}
this.moveDeadPiece = function() {
var myPos = this.getIndexPosition(this.properties.position);
var others = Entities.findEntities(this.properties.position, this.properties.dimensions.y);
for (var i = 0; i < others.length; i++) {
var pieceID = others[i];
if (pieceID != this.entityID) {
var properties = Entities.getEntityProperties(pieceID);
var isWhite = properties.modelURL.search("White") !== -1;
var type = (properties.modelURL.search("King") !== -1) ? 4 :
(properties.modelURL.search("Queen") !== -1) ? 3 :
(properties.modelURL.search("Rook") !== -1) ? 2 :
(properties.modelURL.search("Knight") !== -1) ? 1 :
(properties.modelURL.search("Bishop") !== -1) ? 0 :
(properties.modelURL.search("Pawn") !== -1) ? -1 : -2;
var piecePos = this.getIndexPosition(properties.position);
if (myPos.i === piecePos.i && myPos.j === piecePos.j && type !== -2) {
var position = this.getAbsolutePosition((isWhite) ? { i: type, j: -1 } : { i: 7 - type, j: 8 },
properties.dimensions.y / 2.0);
Entities.editEntity(pieceID, {
position: position
});
break;
}
}
}
}
this.grab = function(mouseEvent) {
if (this.active) {
this.startingTile = this.getIndexPosition(this.properties.position);
this.updatePosition(mouseEvent);
}
}
this.move = function(mouseEvent) {
if (this.active) {
this.updatePosition(mouseEvent);
}
}
this.release = function(mouseEvent) {
if (this.active) {
this.updatePosition(mouseEvent);
this.snapToGrid();
this.moveDeadPiece();
this.playSound();
}
}
this.preload = function(entityID) {
this.updateProperties(entityID); // All callbacks start by updating the properties
this.maybeDownloadSound();
}
this.clickDownOnEntity = function(entityID, mouseEvent) {
this.preload(entityID); // TODO : remove
this.updateProperties(entityID); // All callbacks start by updating the properties
this.grab(mouseEvent);
};
this.holdingClickOnEntity = function(entityID, mouseEvent) {
this.updateProperties(entityID); // All callbacks start by updating the properties
this.move(mouseEvent);
};
this.clickReleaseOnEntity = function(entityID, mouseEvent) {
this.updateProperties(entityID); // All callbacks start by updating the properties
this.release(mouseEvent);
};
})