Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions PC_Steam_The_House_in_Fata_Morgana.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// ==UserScript==
// @name The House in Fata Morgana
// @version 1.0.0.0
// @author Musi
// @description Steam
// * NOVECT
//
// https://store.steampowered.com/app/303310/The_House_in_Fata_Morgana/
// ==/UserScript==

const __e = Process.enumerateModules()[0];
console.warn('[Known Issue] Some inner dialogue is picked up even when not displayed in game. Recommend ignoring this for spoiler reasons.');
(function () {
const mainHandler = trans.send(handler, '250+');
attach('DialogueHook', 'E8 33 DC E1 FF', 'edx');

let lastText = '';
let sentenceBuffer = '';

function handler(text) {
return text;
}

function cleanText(text) {
return text
.replace(/\[.*?\]/g, '') // remove [tags]
.replace(/@.*$/gm, '') // remove @ commands
.trim();
}

function endsWithPunctuation(text) {
// check if text ends with punctuation
return /[。!?…・]$/.test(text);
}

function hasJapaneseText(text) {
// check if text contains Japanese characters
return /[\u3040-\u30FF\u4E00-\u9FAF]/.test(text);
}

function attach(name, pattern, register) {
const results = Memory.scanSync(__e.base, __e.size, pattern);
if (results.length === 0) {
console.error(`[${name}] Hook not found!`);
return;
}
const address = results[0].address;
console.log(`[${name}] Found hook at ${address}`);
Interceptor.attach(address, function (args) {
const basePtr = this.context[register];

// early return if pointer is null
if (!basePtr || basePtr.isNull()) {
return;
}

const text = this.context[register].readUtf16String();

// early return if no text
if (!text || text.length === 0) {
return;
}

const cleaned = cleanText(text);

// only output japanese characters and no duplicates
if (cleaned.length > 0 && hasJapaneseText(cleaned) && cleaned !== lastText) {
lastText = cleaned;

if (sentenceBuffer.length > 0) {
sentenceBuffer += cleaned;
} else {
sentenceBuffer = cleaned;
}

if (endsWithPunctuation(cleaned)) {
mainHandler('\n' + sentenceBuffer + '\n');
sentenceBuffer = '';
}
}
});
}
})();