content/hifi-content/clement/production/chess/chessPiece.js
2022-02-13 22:19:19 +01:00

192 lines
6.6 KiB
JavaScript

//
// playChess.js
// examples
//
// Created by Clement Brisset on 11/08/2014
// Copyright 2014 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
(function() {
this.NUM_TILES = 10;
ChessGame = { KING: 0, QUEEN: 1, BISHOP: 2, KNIGHT: 3, ROOK: 4, PAWN: 5 }
this.entityID = null;
this.boardID = null;
this.sound = null;
this.boardProperties = null;
this.pieceProperties = null;
this.startingTile;
this.grabs = 0;
// Loads the drop sound
this.loadSound = function() {
this.sound = SoundCache.getSound("https://s3-us-west-1.amazonaws.com/hifi-content/clement/production/chess/ChessPieceSound.wav");
}
// Play drop sound
this.playSound = function() {
if (this.sound && this.sound.downloaded) {
Audio.playSound(this.sound, { position: this.pieceProperties.position, volume: 1.0 });
}
}
this.pullProperties = function() {
this.pieceProperties = Entities.getEntityProperties(this.entityID);
this.boardProperties = Entities.getEntityProperties(this.boardID);
}
// Returns whether pos is inside the grid or not
this.isOutsideGrid = function(pos) {
return !(pos.i > -5 && pos.j > -5 && pos.i < 4 && pos.j < 4);
}
// Returns the tile coordinate
this.getIndexPosition = function(position) {
var relative = Vec3.subtract(position, this.boardProperties.position);
relative = Vec3.multiplyQbyV(Quat.inverse(this.boardProperties.rotation), relative);
var tileSize = this.boardProperties.dimensions.x / this.NUM_TILES;
var pos = {
i: Math.floor(relative.x / tileSize),
j: Math.floor(relative.z / tileSize)
};
var yStart = this.boardProperties.dimensions.y / 2.0 - tileSize / 2.0;
var yEnd = this.boardProperties.dimensions.y / 2.0 + tileSize;
if (relative.y < yStart || relative.y > yEnd || this.isOutsideGrid(pos)) {
// Simulate out of board position
var isWhite = (this.pieceProperties.textures === "");
if (isWhite) {
return { i: 5, j: -1 };
} else {
return { i: -6, j: 0 };
}
}
return pos;
}
// Returns the world position
this.getAbsolutePosition = function(pos) {
var position = this.tilePosition(pos.i, pos.j);
return Vec3.sum(this.boardProperties.position, Vec3.multiplyQbyV(this.boardProperties.rotation, position));
}
this.tilePosition = function(i, j) {
var CENTER_OFFSET = 0.5;
var tileSize = this.boardProperties.dimensions.x / this.NUM_TILES;
var relativePosition = {
x: (i + CENTER_OFFSET) * tileSize,
y: this.boardProperties.dimensions.y / 2.0,
z: (j + CENTER_OFFSET) * tileSize
};
return relativePosition;
}
// Snap piece to the center of the tile it is on
this.snapToGrid = function() {
var pos = this.getIndexPosition(this.pieceProperties.position);
var finalPos = this.getAbsolutePosition((this.isOutsideGrid(pos)) ? this.startingTile : pos);
var finalRot = this.boardProperties.rotation;
if (this.pieceProperties.textures === "") {
finalRot = Quat.multiply(finalRot, Quat.fromPitchYawRollDegrees(0, 180, 0));
}
Entities.editEntity(this.entityID, { position: finalPos, rotation: finalRot });
}
this.moveDeadPiece = function() {
var tileSize = this.boardProperties.dimensions.x / this.NUM_TILES;
var myPos = this.getIndexPosition(this.pieceProperties.position);
var others = Entities.findEntities(this.pieceProperties.position, tileSize);
for (var i = 0; i < others.length; i++) {
var pieceID = others[i];
if (pieceID != this.entityID) {
var properties = Entities.getEntityProperties(pieceID);
if (properties.type !== "Model" ||
properties.parentID !== this.boardID ||
properties.script !== this.pieceProperties.script) {
continue;
}
var type = (properties.modelURL.search("chess/King.fbx") !== -1) ? 4 :
(properties.modelURL.search("chess/Queen.fbx") !== -1) ? 3 :
(properties.modelURL.search("chess/Rook.fbx") !== -1) ? 2 :
(properties.modelURL.search("chess/Knight.fbx") !== -1) ? 1 :
(properties.modelURL.search("chess/Bishop.fbx") !== -1) ? 0 :
(properties.modelURL.search("chess/Pawn.fbx") !== -1) ? -1 : -2;
if (type == -2) {
continue;
}
var isWhite = (properties.textures === "");
var piecePos = this.getIndexPosition(properties.position);
if (myPos.i === piecePos.i && myPos.j === piecePos.j && type !== -2) {
var position = this.getAbsolutePosition(isWhite ? { i: 4, j: 3 - type } : { i: -5, j: type - 4 });
Entities.editEntity(pieceID, {
position: position
});
break;
}
}
}
}
this.requestParentID = function() {
var that = this;
Script.setTimeout(function() {
that.getParentID();
}, 10);
}
this.getParentID = function() {
this.boardID = Entities.getEntityProperties(this.entityID, ["parentID"]).parentID;
try {
var url = Entities.getEntityProperties(this.boardID, ["modelURL"]).modelURL;
if (url.search("chess/Board.fbx") === -1) {
throw "Error";
}
} catch(e) {
this.requestParentID();
}
}
this.preload = function(entityID) {
// Piece ID
this.entityID = entityID;
this.loadSound();
this.requestParentID();
}
this.startGrab = function() {
if (++this.grabs !== 1) {
return;
}
this.pullProperties();
this.startingTile = this.getIndexPosition(this.pieceProperties.position);
}
this.startNearGrab = this.startGrab;
this.startDistanceGrab = this.startGrab;
this.releaseGrab = function() {
if (--this.grabs !== 0) {
return;
}
this.pullProperties();
this.snapToGrid();
this.moveDeadPiece();
this.playSound();
};
})