parity with frhd, and a suggestion
-
I was messing around with Triip's "Gate III" track in the editor, which uses some fancy portal technique to essentially lock an area of the track behind a portal, and I noticed that in fr.app editor it's broken, while in the frhd editor it works normally. Is this a difference in game physics?
As a related suggestion, could portals be visually connected in the editor by a line (like when you are placing them), even after they are placed? This would help keep track of which portals link to each other and where they go.
-
I haven't had any luck getting the track to break on freerider.app, it is possible that it is a mod that is causing it?
as for anything teleports, @Pie42 is the authority on that, so possibly he'll whip something up. but feel free to use this userscript in the meantime:
// ==UserScript== // @name Teleport Matcher // @version 0.1 // @description Connects teleports in FRHD. // @author 1s3k3b // @match https://freerider.app/* // @grant none // ==/UserScript== let lastHref; setInterval(() => { if (window.location.href !== lastHref) { lastHref = window.location.href; const i = setInterval(() => { if (!GameManager.game) return; clearInterval(i); const { canvas, currentScene: scene } = GameManager.game; const ctx = canvas.getContext('2d'); const toScreen = x => scene.track.physicsLines[0].p1.__proto__.toScreen.apply(x, [scene]); createjs.Ticker.on('tick', () => scene.track.powerups.map(x => { if (!x.otherPortal) return; const pos = toScreen(x); const other = toScreen(x.otherPortal); ctx.beginPath(); ctx.strokeStyle = '#e56af0'; ctx.lineWidth = scene.camera.zoom * 2; ctx.moveTo(pos.x, pos.y); ctx.lineTo(other.x, other.y); ctx.stroke(); })); }); } }); -
I haven't had any luck getting the track to break on freerider.app, it is possible that it is a mod that is causing it?
as for anything teleports, @Pie42 is the authority on that, so possibly he'll whip something up. but feel free to use this userscript in the meantime:
// ==UserScript== // @name Teleport Matcher // @version 0.1 // @description Connects teleports in FRHD. // @author 1s3k3b // @match https://freerider.app/* // @grant none // ==/UserScript== let lastHref; setInterval(() => { if (window.location.href !== lastHref) { lastHref = window.location.href; const i = setInterval(() => { if (!GameManager.game) return; clearInterval(i); const { canvas, currentScene: scene } = GameManager.game; const ctx = canvas.getContext('2d'); const toScreen = x => scene.track.physicsLines[0].p1.__proto__.toScreen.apply(x, [scene]); createjs.Ticker.on('tick', () => scene.track.powerups.map(x => { if (!x.otherPortal) return; const pos = toScreen(x); const other = toScreen(x.otherPortal); ctx.beginPath(); ctx.strokeStyle = '#e56af0'; ctx.lineWidth = scene.camera.zoom * 2; ctx.moveTo(pos.x, pos.y); ctx.lineTo(other.x, other.y); ctx.stroke(); })); }); } }); -
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)