// ==UserScript==
// @name Internet Roadtrip: Dark Souls Location Popup
// @namespace http://tampermonkey.net/
// @version 1.1.2
// @author joawatte19
// @description Show Dark Souls style location name popup on https://neal.fun/internet-roadtrip/
// @match https://neal.fun/internet-roadtrip/
// @license MIT
// @grant none
// @run-at document-end
// @require https://cdn.jsdelivr.net/npm/[email protected]
// ==/UserScript==
(async () => {
if (!IRF?.isInternetRoadtrip) return;
const container = await IRF.vdom.container;
const originalUpdateData = container.methods.updateData;
let lastLoc = {};
container.state.updateData = new Proxy(originalUpdateData, {
apply: (target, thisArg, args) => {
const result = Reflect.apply(target, thisArg, args);
const loc = container.state.currentLocation;
const fields = ["neighborhood", "county", "state", "country"];
let changedField = null;
for (const field of fields) {
if (loc?.[field] && loc[field] !== lastLoc[field]) {
changedField = field;
break;
}
}
const changedValue = changedField ? loc[changedField] : null;
lastLoc = { ...loc };
if (changedValue) {
showPopup(changedValue);
}
return result;
}
});
function showPopup(text) {
const existing = document.getElementById("ds-location-popup");
if (existing) existing.remove();
const overlay = document.createElement("div");
overlay.id = "ds-overlay";
Object.assign(overlay.style, {
position: "fixed",
top: "0",
left: "0",
width: "100vw",
height: "100vh",
backgroundColor: "#000",
opacity: "0",
zIndex: 9998,
pointerEvents: "none",
transition: "opacity 1.2s ease-in-out",
});
document.body.appendChild(overlay);
requestAnimationFrame(() => {
overlay.style.opacity = "0.4";
});
const popup = document.createElement("div");
popup.id = "ds-location-popup";
popup.textContent = text;
Object.assign(popup.style, {
position: "fixed",
top: "40%",
left: "50%",
transform: "translate(-50%, -50%) scale(0.95)",
color: "#e3e2e0",
fontFamily: "adobe-garamond-pro, Georgia, serif",
fontSize: "4rem",
whiteSpace: "nowrap",
maxWidth: "90vw",
userSelect: "none",
zIndex: 9999,
opacity: "0",
textAlign: "center",
lineHeight: "1.2",
textShadow: "0 0 8px rgba(0,0,0,0.6), 0 0 2px #ccc",
transition: "opacity 1.2s ease-in-out, transform 1.2s ease-in-out",
pointerEvents: "none",
padding: "1rem",
paddingBottom: "0.05rem",
borderBottom: "4px solid rgba(227,226,224,0.5)",
});
document.body.appendChild(popup);
// play sound
const audio = new Audio("https://media.vocaroo.com/mp3/1f7euqkLrXJs");
audio.volume = 0.8;
audio.play().catch(() => {});
// fade in
requestAnimationFrame(() => {
popup.style.opacity = "1";
popup.style.transform = "translate(-50%, -50%) scale(1)";
});
// fade out
setTimeout(() => {
popup.style.opacity = "0";
popup.style.transform = "translate(-50%, -50%) scale(1.05)";
overlay.style.opacity = "0";
setTimeout(() => {
popup.remove();
overlay.remove();
}, 1500);
}, 3000);
}
// manual trigger with console
window.showDSLocationPopup = () => {
const loc = container.state.currentLocation;
if (!loc) {
console.warn("No location data available.");
return;
}
const fields = ["neighborhood", "county", "state", "country"];
for (const field of fields) {
if (loc[field]) {
showPopup(loc[field]);
break;
}
}
};
})();