the thing with stacked portals is that their behavior depends entirely on the order they're in within the track, which is why i mostly only generate tracks with them. this also means that a variety of features have the potential to mess with their function, including the select tool, layers, and possibly even erasing and undoing, but it isn't guaranteed. if you can remember exactly what you were doing when they stopped working, i'll look into fixing it, but it's a pretty difficult problem to solve. in the meantime, here's a script i made when looking at computer by seasnails, but that doesn't work quite as well for stacked portals:
// ==UserScript==
// @name double-click portals
// @version 0.1
// @description
// @author Pie42
// @match https://www.freeriderhd.com/t/*
// @match https://www.freeriderhd.com/create
// @match https://freerider.app/*
// @grant none
// ==/UserScript==
function main() {
let canvas = GameManager.game.canvas;
console.log('double click active ', canvas);
canvas.addEventListener('dblclick', (e) => {
let position = GameManager.game.currentScene.mouse.touch.real,
sectors = GameManager.game.currentScene.track.sectors.physicsSectors,
sectorPos = position.factor(1 / GameSettings.physicsSectorSize || 300),
found = false;
sectorPos.x = Math.floor(sectorPos.x - 0.5);
sectorPos.y = Math.floor(sectorPos.y - 0.5);
//console.log(sectorPos, 'sectorPos');
for (let xOffset = 0; xOffset < 2; xOffset++) {
if (!sectors[sectorPos.x + xOffset]) continue;
for (let yOffset = 0; yOffset < 2; yOffset++) {
let currentSector = sectors[sectorPos.x + xOffset][sectorPos.y + yOffset];
if (!currentSector) continue;
let teleporters = currentSector.powerups?.teleports,
teleporter;
if (!teleporters) continue;
for (let i of teleporters) {
//console.log(i, position, Math.hypot((i.x - position.x) ** 2, (i.y - position.y) ** 2) ** 2);
if (Math.hypot(i.x - position.x, i.y - position.y) ** 2 < 1000) {
teleporter = i;
break;
}
}
if (!teleporter) continue;
let camera = GameManager.game.currentScene.camera;
let dCamera = camera.position.sub(teleporter).add(teleporter.otherPortal);
console.log(dCamera);
camera.position = dCamera;
camera.playerFocus = false;
found = true;
break;
}
if (found) break;
}
console.log('double clicked!');
});
}
let track = undefined;
window.setInterval(function () {
if (window?.$ && $("#track-data")?.data?.("t_id") != track || +location.href.match(/\/(\d+)/)?.[1] != track) {
track = window?.$?.("#track-data")?.data?.("t_id") || +location.href.match(/\/(\d+)/)?.[1];
console.log(track);
function rInterval() {
window.clearInterval(v)
}
var v = window.setInterval(function() {
if (GameManager != undefined && GameManager.game != undefined) {
rInterval();
main();
}
}, 250)
}
}, 500)