content/hifi-content/lincoln/pinSetterEntity.js
2022-02-14 02:04:11 +01:00

324 lines
12 KiB
JavaScript

// PinSetterEntity.js
// Copyright 2016 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() {
var _this;
var BOWLING_ALLEY_PREFIX_URL = 'http://hifi-content.s3.amazonaws.com/caitlyn/production/bowlingAlley/';
var IMPORT_URL_PINSET = BOWLING_ALLEY_PREFIX_URL + 'bpins4.svo.json';
var IMPORT_URL_BALL = BOWLING_ALLEY_PREFIX_URL + 'bowlingBall.svo.json';
var BELL_SOUND_URL = BOWLING_ALLEY_PREFIX_URL + 'bell.wav';
var RETURN_SOUND_URL = BOWLING_ALLEY_PREFIX_URL + 'caitlynMeeks_ball%20return%20mechanism.wav';
var SECONDS_IN_HOUR = 3600;
var MAX_EQUIPMENT_LIFETIME = SECONDS_IN_HOUR;
var SECOND_BALL_WAIT_MILLISECONDS = 2000;
var TRIANGLE_NUMBER_OF_PINS = 4;
var TRIANGLE_WIDTH = 1;
var PIN_DIMENSIONS = {
x: 0.1638,
y: 0.3971,
z: 0.1638
};
var BOWLING_BALLS = [
{
name: 'Bowling ball - Salmon',
density: 5000,
dimensions: {
x: 0.245,
y: 0.245,
z: 0.245
}
},
{
name: 'Bowling ball - Purple',
density: 6000,
dimensions: {
x: 0.265,
y: 0.265,
z: 0.265
},
textures: JSON.stringify({
file4: BOWLING_ALLEY_PREFIX_URL + 'bowlingball_Base_Color_purple.png',
file5: BOWLING_ALLEY_PREFIX_URL + 'ball_salmon.fbx/../../../../Downloads/bowlingball.fbm/bowlingball_Roughness.png'
})
},
{
name: 'Bowling ball - Yellow',
density: 4000,
dimensions: {
x: 0.205,
y: 0.205,
z: 0.205
},
textures: JSON.stringify({
file4: BOWLING_ALLEY_PREFIX_URL + 'bowlingball_Base_Color_yellow.png',
file5: BOWLING_ALLEY_PREFIX_URL + 'ball_salmon.fbx/../../../../Downloads/bowlingball.fbm/bowlingball_Roughness.png'
})
},
{
name: 'Bowling ball - Blue',
density: 5500,
dimensions: {
x: 0.255,
y: 0.255,
z: 0.255
},
textures: JSON.stringify({
file4: BOWLING_ALLEY_PREFIX_URL + 'bowlingball_Base_Color_blue.png',
file5: BOWLING_ALLEY_PREFIX_URL + 'ball_salmon.fbx/../../../../Downloads/bowlingball.fbm/bowlingball_Roughness.png'
})
}
];
// See https://en.wikipedia.org/wiki/Triangular_number for Triangle numbers (T1 = 1, T2 = 3, T3 = 6 ... etc)
var getPinPositions = function(maxWidth, triangleNumber) {
var pinPositions = [];
var gapSpace = maxWidth / triangleNumber;
for (var row = 0; row < triangleNumber; row++) {
var rowPins = triangleNumber - row;
for (var rowPinIndex = 0; rowPinIndex < rowPins; rowPinIndex++) {
pinPositions.push({
x: (-((rowPins - 1) / 2) + rowPinIndex) * gapSpace,
z: row * gapSpace
})
}
}
return pinPositions;
};
var returnSound, ringSound;
// Creates an entity and returns a mixed object of the creation properties and the assigned entityID
var createEntity = function(entityProperties, parent) {
if (parent.rotation !== undefined) {
if (entityProperties.rotation !== undefined) {
entityProperties.rotation = Quat.multiply(parent.rotation, entityProperties.rotation);
} else {
entityProperties.rotation = parent.rotation;
}
}
if (parent.position !== undefined) {
var localPosition = (parent.rotation !== undefined) ? Vec3.multiplyQbyV(parent.rotation, entityProperties.position) : entityProperties.position;
entityProperties.position = Vec3.sum(localPosition, parent.position);
}
if (parent.id !== undefined) {
entityProperties.parentID = parent.id;
}
entityProperties.id = Entities.addEntity(entityProperties);
return entityProperties;
};
var createPin = function (transform, extraProperties, bowlingAlley) {
var entityProperties = {
compoundShapeURL: BOWLING_ALLEY_PREFIX_URL + 'bowlingpin_hull.obj',
dimensions: PIN_DIMENSIONS,
dynamic: true,
gravity: {
x: 0,
y: -9.8,
z: 0
},
modelURL: BOWLING_ALLEY_PREFIX_URL + 'bowlingpin.fbx',
name: 'Bowling Pin',
shapeType: 'compound',
type: 'Model',
userData: JSON.stringify({
isBowlingPin: true,
bowlingAlley: bowlingAlley,
grabbableKey: {
grabbable: false
}
}),
script: 'https://hifi-content.s3.amazonaws.com/lincoln/bowlingPinEntity.js',
lifetime: MAX_EQUIPMENT_LIFETIME
};
for (var key in extraProperties) {
if (extraProperties.hasOwnProperty(key)) {
entityProperties[key] = extraProperties[key];
}
}
return createEntity(entityProperties, transform);
};
var createBall = function (transform, extraProperties, bowlingAlley) {
var entityProperties = {
angularDamping: 0.3,
collisionsWillMove: 1,
damping: 0.01,
density: 5000,
dimensions: {
x: 0.245,
y: 0.245,
z: 0.245
},
angularVelocity: {
w: -0.12123292684555054,
x: 0.97888147830963135,
y: -0.075059115886688232,
z: -0.14644080400466919
},
velocity: Vec3.multiplyQbyV(transform.rotation, {
x: 0,
y: 0,
z: 1,
}),
collidesWith: 'static,dynamic,kinematic',
dynamic: true,
friction: 0.1,
gravity: {
x: 0,
y: -9.8,
z: 0
},
modelURL: BOWLING_ALLEY_PREFIX_URL + 'ball_salmon.fbx',
restitution: 0.2,
rotation: {
w: -0.12123292684555054,
x: 0.97888147830963135,
y: -0.075059115886688232,
z: -0.14644080400466919
},
shapeType: 'sphere',
type: 'Model',
userData: JSON.stringify({
isBowlingBall: true,
bowlingAlley: bowlingAlley,
grabbableKey: {
grabbable: true
}
}),
script: 'http://mpassets.highfidelity.com/f01af088-7410-40e2-a331-310e9a0d068e-v1/bowlingBallEntity.js',
lifetime: MAX_EQUIPMENT_LIFETIME
};
for (var key in extraProperties) {
if (extraProperties.hasOwnProperty(key)) {
entityProperties[key] = extraProperties[key];
}
}
Audio.playSound(returnSound, {
position: transform.position,
volume: 0.5
});
return createEntity(entityProperties, transform);
};
function ResetButton() {
_this = this;
}
ResetButton.prototype = {
entityID: null,
resetConsoleID: null,
bowlingAlleyID: null,
preload: function(entityID) {
print('preload(' + entityID + ')');
_this.entityID = entityID;
_this.resetConsoleID = Entities.getEntityProperties(_this.entityID, ['parentID']).parentID;
_this.bowlingAlleyID = Entities.getEntityProperties(_this.resetConsoleID, ['parentID']).parentID; // get the bowling alley's parent ID
ringSound = SoundCache.getSound(BELL_SOUND_URL);
returnSound = SoundCache.getSound(RETURN_SOUND_URL);
},
unload: function() {
// this would remove the pins when someone random is leaving (not what we intend)
// _this.clearPins();
},
clearPins: function() {
Entities.findEntities(MyAvatar.position, 1000).forEach(function(entity) {
try {
var userData = JSON.parse(Entities.getEntityProperties(entity, ['userData']).userData);
if (userData.isBowlingPin && userData.bowlingAlley === _this.bowlingAlleyID) {
print("Found pin, deleting it: " + entity);
Entities.deleteEntity(entity);
}
} catch(e) {}
});
},
createRandomBallInRetractor: function() {
var entProperties = Entities.getEntityProperties(_this.bowlingAlleyID, ['position', 'rotation']);
var jointIndex = Entities.getJointIndex(_this.bowlingAlleyID, 'ballLocatorJoint');
var jointLocInObjectFrame = Entities.getAbsoluteJointTranslationInObjectFrame(_this.bowlingAlleyID, jointIndex);
var jointLocInWorld = Vec3.sum(entProperties.position, Vec3.multiplyQbyV(entProperties.rotation, jointLocInObjectFrame));
createBall({
position: jointLocInWorld,
rotation: entProperties.rotation
}, BOWLING_BALLS[Math.floor(BOWLING_BALLS.length * Math.random())], _this.bowlingAlleyID);
},
clearBalls: function() {
Entities.findEntities(MyAvatar.position, 1000).forEach(function(entity) {
try {
var userData = JSON.parse(Entities.getEntityProperties(entity, ['userData']).userData);
if (userData.isBowlingBall && userData.bowlingAlley === _this.bowlingAlleyID) {
print("Found ball, deleting it: " + entity);
Entities.deleteEntity(entity);
}
} catch(e) {}
});
},
doTheRez: function() {
//print("START BOWLING RESET TRIGGER");
// Reset pins
var entProperties = Entities.getEntityProperties(_this.bowlingAlleyID);
var jointNames = Entities.getJointNames(_this.bowlingAlleyID);
//print("Joint Names " + jointNames);
var jointIndex = Entities.getJointIndex(_this.bowlingAlleyID, 'pinLocatorJoint');
//print("JOINT INDEX IS " + jointIndex);
var jointLocInObjectFrame = Entities.getAbsoluteJointTranslationInObjectFrame(_this.bowlingAlleyID, jointIndex);
var jointLocInWorld = Vec3.sum(entProperties.position, Vec3.multiplyQbyV(entProperties.rotation, jointLocInObjectFrame));
//print("LOCATION IS " + JSON.stringify(jointLocInWorld));
_this.clearPins();
//print("ADDING NEW PINS");
var pinHeightOffset = {y: PIN_DIMENSIONS.y / 2};
getPinPositions(TRIANGLE_WIDTH, TRIANGLE_NUMBER_OF_PINS).forEach(function(pinPosition) {
createPin({
position: Vec3.sum(jointLocInWorld, pinHeightOffset),
rotation: entProperties.rotation
}, {
position: pinPosition
}, _this.bowlingAlleyID);
});
//print("PINS ADDED");
// Add new ball
_this.createRandomBallInRetractor();
Script.setTimeout(function() {
_this.createRandomBallInRetractor();
}, SECOND_BALL_WAIT_MILLISECONDS);
//Clipboard.importEntities(IMPORT_URL_BALL);
//Clipboard.pasteEntities(jointLocInWorld);
//print("BALL ADDED");
// Completion sound
Audio.playSound(ringSound, {
position: Entities.getEntityProperties(_this.entityID, ['position']).position,
volume: 0.5
});
},
startNearTrigger: function(entityID) {
_this.doTheRez();
},
clickReleaseOnEntity: function(entityID, mouseEvent) {
if (mouseEvent.isLeftButton) {
_this.doTheRez();
}
}
};
return new ResetButton();
});