mirror of
https://github.com/AleziaKurdis/Overte-community-apps.git
synced 2025-04-06 01:53:45 +02:00
This PR add the support of a flying Avatar per Avatar Bookmark. Instead to have a flying avatar defined for all avatar and all the time, this version will let you define a flying avatar for each bookmark where you need one. You can then have also some avatar without flying avatar linked to it if you want. or have very different flying avatar depending the avatar used.
236 lines
8 KiB
JavaScript
236 lines
8 KiB
JavaScript
//
|
|
// app-flyAvatar.js
|
|
//
|
|
// Created by Alezia Kurdis, December 16th 2023.
|
|
// Copyright 2023 Overte e.V.
|
|
//
|
|
// This automatically replace your avatar by a specific one as soon as you are flying.
|
|
//
|
|
// 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 jsMainFileName = "app-flyAvatar.js";
|
|
var ROOT = Script.resolvePath('').split(jsMainFileName)[0];
|
|
|
|
var APP_NAME = "FLY-AV";
|
|
var APP_URL = ROOT + "flyAvatar.html";
|
|
var APP_ICON_INACTIVE_ON = ROOT + "icon_inactive_on.png";
|
|
var APP_ICON_INACTIVE_OFF = ROOT + "icon_inactive_off.png";
|
|
var inactiveIcon = APP_ICON_INACTIVE_ON;
|
|
var APP_ICON_ACTIVE = ROOT + "icon_active.png"; // BLACK on
|
|
var ICON_CAPTION_COLOR = "#FFFFFF";
|
|
var appStatus = false;
|
|
var channel = "overte.application.more.flyAvatar";
|
|
var timestamp = 0;
|
|
var INTERCALL_DELAY = 200; //0.3 sec
|
|
var FLY_AVATAR_SETTING_KEY = "overte.application.more.flyAvatar.avatarUrl";
|
|
var FLY_AVATAR_SETTING_KEY_2 = "overte.application.more.flyAvatar.avatarUrl.2";
|
|
var FLY_AVATAR_SWITCH_SETTING_KEY = "overte.application.more.flyAvatar.switch";
|
|
var FLY_AVATAR_ORIGINAL_AVATAR_SETTING_KEY = "overte.application.more.flyAvatar.originalAvatarUrl";
|
|
var flyAvatarSwitch = true;
|
|
var flyAvatarUrl = []; //must be an array of {"avatarUrl": "", "flyAvatarUrl": ""}
|
|
var originalAvatarUrl = "";
|
|
var isFlying = false;
|
|
var UPDATE_TIMER_INTERVAL = 500; // 5 sec
|
|
var processTimer = 0;
|
|
|
|
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
|
|
|
tablet.screenChanged.connect(onScreenChanged);
|
|
|
|
var button = tablet.addButton({
|
|
text: APP_NAME,
|
|
icon: APP_ICON_INACTIVE_ON,
|
|
activeIcon: APP_ICON_ACTIVE,
|
|
captionColor: ICON_CAPTION_COLOR
|
|
});
|
|
|
|
|
|
function clicked(){
|
|
var colorCaption;
|
|
if (appStatus === true) {
|
|
tablet.webEventReceived.disconnect(onAppWebEventReceived);
|
|
tablet.gotoHomeScreen();
|
|
colorCaption = ICON_CAPTION_COLOR;
|
|
appStatus = false;
|
|
}else{
|
|
tablet.gotoWebScreen(APP_URL);
|
|
tablet.webEventReceived.connect(onAppWebEventReceived);
|
|
colorCaption = "#000000";
|
|
appStatus = true;
|
|
}
|
|
|
|
button.editProperties({
|
|
isActive: appStatus,
|
|
captionColor: colorCaption
|
|
});
|
|
}
|
|
|
|
button.clicked.connect(clicked);
|
|
|
|
function onAppWebEventReceived(message) {
|
|
if (typeof message === "string") {
|
|
var d = new Date();
|
|
var n = d.getTime();
|
|
var instruction = JSON.parse(message);
|
|
if (instruction.channel === channel) {
|
|
if (instruction.action === "REQUEST_INITIAL_DATA") {
|
|
sendCurrentFlyAvatarUrlToUI();
|
|
} else if (instruction.action === "UPDATE_URL") {
|
|
flyAvatarUrl = instruction.url;
|
|
flyAvatarSwitch = instruction.mainSwitch;
|
|
Settings.setValue( FLY_AVATAR_SETTING_KEY_2, flyAvatarUrl);
|
|
Settings.setValue( FLY_AVATAR_SWITCH_SETTING_KEY, flyAvatarSwitch);
|
|
updateAvatar();
|
|
if (flyAvatarSwitch) {
|
|
inactiveIcon = APP_ICON_INACTIVE_ON;
|
|
} else {
|
|
inactiveIcon = APP_ICON_INACTIVE_OFF;
|
|
}
|
|
button.editProperties({icon: inactiveIcon});
|
|
} else if (instruction.action === "SELF_UNINSTALL" && (n - timestamp) > INTERCALL_DELAY) {
|
|
d = new Date();
|
|
timestamp = d.getTime();
|
|
ScriptDiscoveryService.stopScript(Script.resolvePath(''), false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function getFlyAvatarOfAvatar(avatarUrl) {
|
|
let i;
|
|
let url = "";
|
|
if (flyAvatarUrl.length > 0) {
|
|
for (i = 0; i < flyAvatarUrl.length; i++) {
|
|
if (flyAvatarUrl[i].avatarUrl === avatarUrl) {
|
|
url = flyAvatarUrl[i].flyAvatarUrl;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return url;
|
|
}
|
|
|
|
function getIndexOfFlyAvatar(urlOfFlyAvatar) {
|
|
let i;
|
|
let index = -1;
|
|
if (flyAvatarUrl.length > 0) {
|
|
for (i = 0; i < flyAvatarUrl.length; i++) {
|
|
if (flyAvatarUrl[i].flyAvatarUrl === urlOfFlyAvatar) {
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return index;
|
|
}
|
|
|
|
function updateAvatar() {
|
|
if (MyAvatar.isFlying() && flyAvatarSwitch) {
|
|
let replacement = getFlyAvatarOfAvatar(originalAvatarUrl);
|
|
if (replacement !== "") {
|
|
MyAvatar.useFullAvatarURL(replacement);
|
|
}
|
|
} else {
|
|
let index = getIndexOfFlyAvatar(MyAvatar.skeletonModelURL);
|
|
if (index !== -1) {
|
|
MyAvatar.useFullAvatarURL(flyAvatarUrl[index].avatarUrl);
|
|
}
|
|
}
|
|
}
|
|
|
|
MyAvatar.skeletonModelURLChanged.connect(function () {
|
|
if (!MyAvatar.isFlying() && getIndexOfFlyAvatar(MyAvatar.skeletonModelURL) === -1) {
|
|
originalAvatarUrl = MyAvatar.skeletonModelURL;
|
|
Settings.setValue( FLY_AVATAR_ORIGINAL_AVATAR_SETTING_KEY, originalAvatarUrl);
|
|
}
|
|
});
|
|
|
|
function myTimer(deltaTime) {
|
|
var today = new Date();
|
|
if ((today.getTime() - processTimer) > UPDATE_TIMER_INTERVAL ) {
|
|
|
|
if (isFlying !== MyAvatar.isFlying()) {
|
|
updateAvatar();
|
|
isFlying = MyAvatar.isFlying();
|
|
}
|
|
|
|
today = new Date();
|
|
processTimer = today.getTime();
|
|
}
|
|
}
|
|
|
|
function sendCurrentFlyAvatarUrlToUI() {
|
|
var message = {
|
|
"channel": channel,
|
|
"action": "FLY-AVATAR-URL",
|
|
"url": flyAvatarUrl,
|
|
"bookmarks": AvatarBookmarks.getBookmarks(),
|
|
"mainSwitch": flyAvatarSwitch
|
|
};
|
|
tablet.emitScriptEvent(JSON.stringify(message));
|
|
}
|
|
|
|
function onScreenChanged(type, url) {
|
|
if (type === "Web" && url.indexOf(APP_URL) !== -1) {
|
|
colorCaption = "#000000";
|
|
appStatus = true;
|
|
} else {
|
|
colorCaption = ICON_CAPTION_COLOR;
|
|
appStatus = false;
|
|
}
|
|
|
|
button.editProperties({
|
|
isActive: appStatus,
|
|
captionColor: colorCaption
|
|
});
|
|
}
|
|
|
|
function isFlyAvatar(url) {
|
|
let i;
|
|
let isFlyAv = false;
|
|
if (flyAvatarUrl.length > 0) {
|
|
for (i = 0; i < flyAvatarUrl.length; i++) {
|
|
if (flyAvatarUrl[i].flyAvatarUrl === url) {
|
|
isFlyAv = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return isFlyAv;
|
|
}
|
|
|
|
function cleanup() {
|
|
|
|
if (appStatus) {
|
|
tablet.gotoHomeScreen();
|
|
tablet.webEventReceived.disconnect(onAppWebEventReceived);
|
|
}
|
|
|
|
tablet.screenChanged.disconnect(onScreenChanged);
|
|
tablet.removeButton(button);
|
|
Script.update.disconnect(myTimer);
|
|
}
|
|
|
|
Script.scriptEnding.connect(cleanup);
|
|
originalAvatarUrl = MyAvatar.skeletonModelURL;
|
|
if (Settings.getValue( FLY_AVATAR_SETTING_KEY, "" ) !== "") { //Clear Old Settings if present
|
|
Settings.setValue( FLY_AVATAR_SETTING_KEY, "");
|
|
}
|
|
flyAvatarUrl = Settings.getValue( FLY_AVATAR_SETTING_KEY_2, "" );
|
|
flyAvatarSwitch = Settings.getValue( FLY_AVATAR_SWITCH_SETTING_KEY, true );
|
|
if (isFlyAvatar(originalAvatarUrl)) {
|
|
var lastRecordedOriginalAvatar = Settings.getValue( FLY_AVATAR_ORIGINAL_AVATAR_SETTING_KEY, "" );
|
|
if (lastRecordedOriginalAvatar !== "") {
|
|
originalAvatarUrl = lastRecordedOriginalAvatar;
|
|
}
|
|
}
|
|
if (flyAvatarSwitch) {
|
|
inactiveIcon = APP_ICON_INACTIVE_ON;
|
|
} else {
|
|
inactiveIcon = APP_ICON_INACTIVE_OFF;
|
|
}
|
|
button.editProperties({icon: inactiveIcon});
|
|
Script.update.connect(myTimer);
|
|
}());
|