mirror of
https://github.com/lubosz/overte.git
synced 2025-04-23 05:24:06 +02:00
Add ownership token tot tutorial
This commit is contained in:
parent
2bf13b9cf6
commit
a05f681704
2 changed files with 292 additions and 93 deletions
188
tutorial/ownershipToken.js
Normal file
188
tutorial/ownershipToken.js
Normal file
|
@ -0,0 +1,188 @@
|
|||
if (!Function.prototype.bind) {
|
||||
Function.prototype.bind = function(oThis) {
|
||||
if (typeof this !== 'function') {
|
||||
// closest thing possible to the ECMAScript 5
|
||||
// internal IsCallable function
|
||||
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
|
||||
}
|
||||
|
||||
var aArgs = Array.prototype.slice.call(arguments, 1),
|
||||
fToBind = this,
|
||||
fNOP = function() {},
|
||||
fBound = function() {
|
||||
return fToBind.apply(this instanceof fNOP
|
||||
? this
|
||||
: oThis,
|
||||
aArgs.concat(Array.prototype.slice.call(arguments)));
|
||||
};
|
||||
|
||||
if (this.prototype) {
|
||||
// Function.prototype doesn't have a prototype property
|
||||
fNOP.prototype = this.prototype;
|
||||
}
|
||||
fBound.prototype = new fNOP();
|
||||
|
||||
return fBound;
|
||||
};
|
||||
}
|
||||
|
||||
function getOption(options, key, defaultValue) {
|
||||
if (options.hasOwnProperty(key)) {
|
||||
return options[key];
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
var TOKEN_NAME_PREFIX = "ownership_token-";
|
||||
|
||||
function getOwnershipTokenID(parentEntityID) {
|
||||
var childEntityIDs = Entities.getChildrenIDs(parentEntityID);
|
||||
var ownerID = null;
|
||||
var ownerName = '';
|
||||
for (var i = 0; i < childEntityIDs.length; ++i) {
|
||||
var childID = childEntityIDs[i];
|
||||
var properties = Entities.getEntityProperties(childID, ['name', 'userData', 'lifetime', 'age']);
|
||||
var childName = properties.name;
|
||||
//debug("Owner lifetime: ", properties.lifetime, properties.age);
|
||||
if (properties.age > 0.5 && childName.indexOf(TOKEN_NAME_PREFIX) == 0) {
|
||||
if (ownerID === null || childName < ownerName) {
|
||||
ownerID = childID;
|
||||
ownerName = childName;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ownerID;
|
||||
}
|
||||
|
||||
function createOwnershipToken(name, parentEntityID) {
|
||||
return Entities.addEntity({
|
||||
type: "Box",
|
||||
name: TOKEN_NAME_PREFIX + name,
|
||||
visible: false,
|
||||
parentID: parentEntityID,
|
||||
locationPosition: { x: 0, y: 0, z: 0 },
|
||||
dimensions: { x: 100, y: 100, z: 100 },
|
||||
collisionless: true,
|
||||
lifetime: 5
|
||||
});
|
||||
}
|
||||
|
||||
var DEBUG = true;
|
||||
function debug() {
|
||||
if (DEBUG) {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
print.apply(this, args);
|
||||
}
|
||||
}
|
||||
|
||||
var TOKEN_STATE_DESTROYED = -1;
|
||||
var TOKEN_STATE_UNOWNED = 0;
|
||||
var TOKEN_STATE_REQUESTING_OWNERSHIP = 1;
|
||||
var TOKEN_STATE_OWNED = 2;
|
||||
|
||||
OwnershipToken = function(name, parentEntityID, options) {
|
||||
this.name = MyAvatar.sessionUUID + "-" + Math.floor(Math.random() * 10000000);
|
||||
this.name = Math.floor(Math.random() * 10000000);
|
||||
this.parentEntityID = parentEntityID;
|
||||
|
||||
// How often to check whether the token is available if we don't currently own it
|
||||
this.checkEverySeconds = getOption(options, 'checkEverySeconds', 1000);
|
||||
this.updateTokenLifetimeEvery = getOption(options, 'updateTokenLifetimeEvery', 2000);
|
||||
|
||||
//this.onRequestingOwnership = getOption(options, 'onRequestingOwnership', function() { });
|
||||
this.onGainedOwnership = getOption(options, 'onGainedOwnership', function() { });
|
||||
this.onLostOwnership = getOption(options, 'onLostOwnership', function() { });
|
||||
|
||||
this.ownershipTokenID = null;
|
||||
this.setState(TOKEN_STATE_UNOWNED);
|
||||
};
|
||||
|
||||
OwnershipToken.prototype = {
|
||||
destroy: function() {
|
||||
debug(this.name, "Destroying token");
|
||||
this.setState(TOKEN_STATE_DESTROYED);
|
||||
},
|
||||
|
||||
setState: function(newState) {
|
||||
if (this.state == newState) {
|
||||
debug(this.name, "Warning: Trying to set state to the current state");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.updateLifetimeID) {
|
||||
Script.clearInterval(this.updateLifetimeID);
|
||||
this.updateLifetimeID = null;
|
||||
}
|
||||
|
||||
if (this.checkOwnershipAvailableID) {
|
||||
Script.clearInterval(this.checkOwnershipAvailableID);
|
||||
this.checkOwnershipAvailableID = null;
|
||||
}
|
||||
|
||||
if (this.state == TOKEN_STATE_OWNED) {
|
||||
this.onLostOwnership(this);
|
||||
}
|
||||
|
||||
if (newState == TOKEN_STATE_UNOWNED) {
|
||||
this.checkOwnershipAvailableID = Script.setInterval(
|
||||
this.tryRequestingOwnership.bind(this), this.checkEverySeconds);
|
||||
|
||||
} else if (newState == TOKEN_STATE_REQUESTING_OWNERSHIP) {
|
||||
|
||||
} else if (newState == TOKEN_STATE_OWNED) {
|
||||
this.onGainedOwnership(this);
|
||||
this.updateLifetimeID = Script.setInterval(
|
||||
this.updateTokenLifetime.bind(this), this.updateTokenLifetimeEvery);
|
||||
} else if (newState == TOKEN_STATE_DESTROYED) {
|
||||
Entities.deleteEntity(this.ownershipTokenID);
|
||||
}
|
||||
|
||||
debug(this.name, "Info: Switching to state:", newState);
|
||||
this.state = newState;
|
||||
},
|
||||
updateTokenLifetime: function() {
|
||||
if (this.state != TOKEN_STATE_OWNED) {
|
||||
debug(this.name, "Error: Trying to update token while it is unowned");
|
||||
return;
|
||||
}
|
||||
|
||||
debug(this.name, "Updating entity lifetime");
|
||||
var age = Entities.getEntityProperties(this.ownershipTokenID, 'age').age;
|
||||
Entities.editEntity(this.ownershipTokenID, {
|
||||
lifetime: age + 5
|
||||
});
|
||||
},
|
||||
tryRequestingOwnership: function() {
|
||||
if (this.state == TOKEN_STATE_REQUESTING_OWNERSHIP || this.state == TOKEN_STATE_OWNED) {
|
||||
debug(this.name, "We already have or are requesting ownership");
|
||||
return;
|
||||
}
|
||||
|
||||
var ownerID = getOwnershipTokenID(this.parentEntityID);
|
||||
if (ownerID !== null) {
|
||||
// Already owned, return
|
||||
debug(this.name, "Token already owned by another client, return");
|
||||
return;
|
||||
}
|
||||
|
||||
this.ownershipTokenID = createOwnershipToken(this.name, this.parentEntityID);
|
||||
this.setState(TOKEN_STATE_REQUESTING_OWNERSHIP);
|
||||
|
||||
function checkOwnershipRequest() {
|
||||
var ownerID = getOwnershipTokenID(this.parentEntityID);
|
||||
if (ownerID == this.ownershipTokenID) {
|
||||
debug(this.name, "Info: Obtained ownership");
|
||||
this.setState(TOKEN_STATE_OWNED);
|
||||
} else {
|
||||
if (ownerID === null) {
|
||||
debug(this.name, "Warning: Checked ownership request and no tokens existed");
|
||||
}
|
||||
debug(this.name, "Info: Lost ownership request")
|
||||
this.ownershipTokenID = null;
|
||||
this.setState(TOKEN_STATE_UNOWNED);
|
||||
}
|
||||
}
|
||||
|
||||
Script.setTimeout(checkOwnershipRequest.bind(this), 2000);
|
||||
},
|
||||
};
|
|
@ -30,6 +30,7 @@ Script.include("entityData.js");
|
|||
|
||||
Script.include("viveHandsv2.js");
|
||||
Script.include("lighter/createButaneLighter.js");
|
||||
Script.include('ownershipToken.js');
|
||||
|
||||
var BASKET_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/Trach-Can-3.fbx";
|
||||
var BASKET_COLLIDER_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/Trash-Can-4.obj";
|
||||
|
@ -146,19 +147,19 @@ function spawnWithTag(entityData, transform, tag) {
|
|||
}
|
||||
|
||||
function deleteEntitiesWithTag(tag) {
|
||||
print("searching for...:", tag);
|
||||
print("searching for...:", tag);
|
||||
var entityIDs = findEntitiesWithTag(tag);
|
||||
for (var i = 0; i < entityIDs.length; ++i) {
|
||||
print("Deleteing:", entityIDs[i]);
|
||||
//print("Deleteing:", entityIDs[i]);
|
||||
Entities.deleteEntity(entityIDs[i]);
|
||||
}
|
||||
}
|
||||
function editEntitiesWithTag(tag, propertiesOrFn) {
|
||||
print("Editing:", tag);
|
||||
//print("Editing:", tag);
|
||||
var entityIDs = findEntitiesWithTag(tag);
|
||||
print("Editing...", entityIDs);
|
||||
//print("Editing...", entityIDs);
|
||||
for (var i = 0; i < entityIDs.length; ++i) {
|
||||
print("Editing...", entityIDs[i]);
|
||||
//print("Editing...", entityIDs[i]);
|
||||
if (isFunction(propertiesOrFn)) {
|
||||
Entities.editEntity(entityIDs[i], propertiesOrFn(entityIDs[i]));
|
||||
} else {
|
||||
|
@ -318,11 +319,11 @@ stepOrient.prototype = {
|
|||
}
|
||||
};
|
||||
|
||||
this.overlay = new StayInFrontOverlay("model", {
|
||||
url: "http://hifi-content.s3.amazonaws.com/alan/dev/Prompt-Cards/welcome.fbx?11",
|
||||
ignoreRayIntersection: true,
|
||||
visible: false
|
||||
}, 1.5, { x: 0, y: 0.3, z: 0 });
|
||||
// this.overlay = new StayInFrontOverlay("model", {
|
||||
// url: "http://hifi-content.s3.amazonaws.com/alan/dev/Prompt-Cards/welcome.fbx?11",
|
||||
// ignoreRayIntersection: true,
|
||||
// visible: false
|
||||
// }, 1.5, { x: 0, y: 0.3, z: 0 });
|
||||
|
||||
// Spawn content set
|
||||
//spawnWithTag(HandsAboveHeadData, defaultTransform, tag);
|
||||
|
@ -952,105 +953,115 @@ function hideEntitiesWithTag(tag) {
|
|||
});
|
||||
}
|
||||
|
||||
var STEPS;
|
||||
|
||||
var currentStepNum = -1;
|
||||
var currentStep = null;
|
||||
function startTutorial() {
|
||||
currentStepNum = -1;
|
||||
currentStep = null;
|
||||
STEPS = [
|
||||
new stepDisableControllers("step0"),
|
||||
new stepOrient("orient"),
|
||||
//new stepWelcome("welcome"),
|
||||
new stepRaiseAboveHead("raiseHands"),
|
||||
new stepNearGrab("nearGrab"),
|
||||
new stepFarGrab("farGrab"),
|
||||
new stepEquip("equip"),
|
||||
new stepTurnAround("turnAround"),
|
||||
new stepTeleport("teleport"),
|
||||
new stepFinish("finish"),
|
||||
];
|
||||
for (var i = 0; i < STEPS.length; ++i) {
|
||||
STEPS[i].cleanup();
|
||||
}
|
||||
location = "/tutorial_begin";
|
||||
//location = "/tutorial";
|
||||
MyAvatar.shouldRenderLocally = false;
|
||||
startNextStep();
|
||||
}
|
||||
TutorialManager = function() {
|
||||
var STEPS;
|
||||
|
||||
function startNextStep() {
|
||||
if (currentStep) {
|
||||
currentStep.cleanup();
|
||||
}
|
||||
var currentStepNum = -1;
|
||||
var currentStep = null;
|
||||
|
||||
++currentStepNum;
|
||||
|
||||
if (currentStepNum >= STEPS.length) {
|
||||
// Done
|
||||
print("DONE WITH TUTORIAL");
|
||||
this.startTutorial = function() {
|
||||
currentStepNum = -1;
|
||||
currentStep = null;
|
||||
STEPS = [
|
||||
new stepDisableControllers("step0"),
|
||||
new stepOrient("orient"),
|
||||
//new stepWelcome("welcome"),
|
||||
new stepRaiseAboveHead("raiseHands"),
|
||||
new stepNearGrab("nearGrab"),
|
||||
new stepFarGrab("farGrab"),
|
||||
new stepEquip("equip"),
|
||||
new stepTurnAround("turnAround"),
|
||||
new stepTeleport("teleport"),
|
||||
new stepFinish("finish"),
|
||||
];
|
||||
for (var i = 0; i < STEPS.length; ++i) {
|
||||
STEPS[i].cleanup();
|
||||
}
|
||||
location = "/tutorial_begin";
|
||||
//location = "/tutorial";
|
||||
MyAvatar.shouldRenderLocally = false;
|
||||
this.startNextStep();
|
||||
}
|
||||
|
||||
this.startNextStep = function() {
|
||||
if (currentStep) {
|
||||
currentStep.cleanup();
|
||||
}
|
||||
|
||||
++currentStepNum;
|
||||
|
||||
if (currentStepNum >= STEPS.length) {
|
||||
// Done
|
||||
print("DONE WITH TUTORIAL");
|
||||
currentStepNum = -1;
|
||||
currentStep = null;
|
||||
return false;
|
||||
} else {
|
||||
print("Starting step", currentStepNum);
|
||||
currentStep = STEPS[currentStepNum];
|
||||
currentStep.start(this.startNextStep);
|
||||
return true;
|
||||
}
|
||||
}.bind(this);
|
||||
this.restartStep = function() {
|
||||
if (currentStep) {
|
||||
currentStep.cleanup();
|
||||
currentStep.start(this.startNextStep);
|
||||
}
|
||||
}
|
||||
|
||||
this.stopTutorial = function() {
|
||||
if (currentStep) {
|
||||
currentStep.cleanup();
|
||||
}
|
||||
currentStepNum = -1;
|
||||
currentStep = null;
|
||||
return false;
|
||||
} else {
|
||||
print("Starting step", currentStepNum);
|
||||
currentStep = STEPS[currentStepNum];
|
||||
currentStep.start(startNextStep);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
function restartStep() {
|
||||
if (currentStep) {
|
||||
currentStep.cleanup();
|
||||
currentStep.start(startNextStep);
|
||||
}
|
||||
}
|
||||
|
||||
function skipTutorial() {
|
||||
}
|
||||
|
||||
function stopTutorial() {
|
||||
if (currentStep) {
|
||||
currentStep.cleanup();
|
||||
}
|
||||
currentStepNum = -1;
|
||||
currentStep = null;
|
||||
}
|
||||
|
||||
startTutorial();
|
||||
|
||||
Script.scriptEnding.connect(function() {
|
||||
Controller.enableMapping('handControllerPointer-click');
|
||||
});
|
||||
Controller.disableMapping('handControllerPointer-click');
|
||||
|
||||
//mapping.from([Controller.Standard.RY]).to(noop);
|
||||
//{ "from": "Vive.LeftApplicationMenu", "to": "Standard.LeftSecondaryThumb" },
|
||||
//mapping.from([Controller.Standard.RY]).when("Controller.Application.Grounded").to(noop);
|
||||
//mapping.from([Controller.Standard.RY]).when(Controller.Application.Grounded).to(noop);
|
||||
// var entityID = '{be3d10a3-262a-4827-b30c-ec025c4325dc}';
|
||||
// var token = new OwnershipToken(Math.random() * 100000, entityID, {
|
||||
// onGainedOwnership: function(token) {
|
||||
// //Script.setTimeout(function() { token.destroy() }, 15000);
|
||||
// Controller.keyReleaseEvent.connect(keyReleaseHandler);
|
||||
// startTutorial();
|
||||
// },
|
||||
// onLostOwnership: function(token) {
|
||||
// Controller.keyReleaseEvent.disconnect(keyReleaseHandler);
|
||||
// stopTutorial();
|
||||
// }
|
||||
// });
|
||||
|
||||
|
||||
Script.scriptEnding.connect(stopTutorial);
|
||||
|
||||
|
||||
|
||||
Controller.keyReleaseEvent.connect(function (event) {
|
||||
print(event.text);
|
||||
if (event.text == ",") {
|
||||
if (!startNextStep()) {
|
||||
startTutorial();
|
||||
}
|
||||
} else if (event.text == "F11") {
|
||||
restartStep();
|
||||
} else if (event.text == "F10") {
|
||||
MyAvatar.shouldRenderLocally = !MyAvatar.shouldRenderLocally;
|
||||
} else if (event.text == "r") {
|
||||
stopTutorial();
|
||||
startTutorial();
|
||||
}
|
||||
//tutorialManager = new TutorialManager();
|
||||
//tutorialManager.startTutorial();
|
||||
//Controller.keyReleaseEvent.connect(keyReleaseHandler);
|
||||
Script.scriptEnding.connect(function() {
|
||||
//token.destroy();
|
||||
//stopTutorial();
|
||||
});
|
||||
|
||||
// function keyReleaseHandler(event) {
|
||||
// print(event.text);
|
||||
// if (event.text == ",") {
|
||||
// if (!tutorialManager.startNextStep()) {
|
||||
// tutorialManager.startTutorial();
|
||||
// }
|
||||
// } else if (event.text == "F11") {
|
||||
// tutorialManager.restartStep();
|
||||
// } else if (event.text == "F10") {
|
||||
// MyAvatar.shouldRenderLocally = !MyAvatar.shouldRenderLocally;
|
||||
// } else if (event.text == "r") {
|
||||
// tutorialManager.stopTutorial();
|
||||
// tutorialManager.startTutorial();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Messages.sendLocalMessage('Controller-Display', JSON.stringify({
|
||||
// name: "menu",
|
||||
// visible: false,
|
||||
|
|
Loading…
Reference in a new issue