mirror of
https://github.com/litruv/lit.ruv.wtf.git
synced 2026-07-24 02:36:02 +10:00
feat: add game command functionality and update quick commands for Number Match game
This commit is contained in:
@@ -867,6 +867,9 @@ export function updateQuickCommands(mode) {
|
|||||||
<button class="quick-cmd" onclick="runChatCommand('/samsay')" title="SAM speech">/samsay</button>
|
<button class="quick-cmd" onclick="runChatCommand('/samsay')" title="SAM speech">/samsay</button>
|
||||||
<button class="quick-cmd" onclick="runChatCommand('/quit')" title="Exit chat">/quit</button>
|
<button class="quick-cmd" onclick="runChatCommand('/quit')" title="Exit chat">/quit</button>
|
||||||
`;
|
`;
|
||||||
|
} else if (mode === 'game') {
|
||||||
|
if (statusLeft) statusLeft.textContent = 'Number Match';
|
||||||
|
container.innerHTML = '';
|
||||||
} else {
|
} else {
|
||||||
if (statusLeft) statusLeft.textContent = 'Ready';
|
if (statusLeft) statusLeft.textContent = 'Ready';
|
||||||
container.innerHTML = `
|
container.innerHTML = `
|
||||||
@@ -878,6 +881,17 @@ export function updateQuickCommands(mode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run a game command from a button click
|
||||||
|
* @param {string} command - The game command to submit
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
export function runGameCommand(command) {
|
||||||
|
if (!inlineInput || !submitInlineInput) return;
|
||||||
|
inlineInput.value = command;
|
||||||
|
submitInlineInput();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run a chat command from button click
|
* Run a chat command from button click
|
||||||
* @param {string} command - The chat command to run
|
* @param {string} command - The chat command to run
|
||||||
|
|||||||
@@ -552,9 +552,9 @@ export const gameMode = {
|
|||||||
*/
|
*/
|
||||||
function getBoardLineCount(game) {
|
function getBoardLineCount(game) {
|
||||||
const rows = Math.ceil(game.getTiles().length / game.width);
|
const rows = Math.ceil(game.getTiles().length / game.width);
|
||||||
// header + top border + rows + bottom border + empty + status + message
|
// header + top border + rows + blank lines between rows + bottom border + empty + status + message + controls
|
||||||
// (prompt uses write not writeln, so doesn't add a line)
|
// (prompt uses write not writeln, so doesn't add a line)
|
||||||
return 1 + 1 + rows + 1 + 1 + 1 + 1;
|
return 1 + 1 + rows + Math.max(0, rows - 1) + 1 + 1 + 1 + 1 + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -603,6 +603,9 @@ function renderBoard(term, game, selectedIndex, message = '') {
|
|||||||
|
|
||||||
line += '│';
|
line += '│';
|
||||||
term.writeln(line);
|
term.writeln(line);
|
||||||
|
if (row < rows - 1) {
|
||||||
|
term.writeln(` │${' '.repeat(width)}│`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bottom border
|
// Bottom border
|
||||||
@@ -617,6 +620,9 @@ function renderBoard(term, game, selectedIndex, message = '') {
|
|||||||
const msgText = message || '';
|
const msgText = message || '';
|
||||||
term.writeln(` ${msgText}`.padEnd(50));
|
term.writeln(` ${msgText}`.padEnd(50));
|
||||||
|
|
||||||
|
// Clickable controls line
|
||||||
|
term.writeln(' \x1b[90m[ \x1b[36madd\x1b[90m ] [ \x1b[36mhint\x1b[90m ] [ \x1b[36mnew\x1b[90m ] [ \x1b[36mquit\x1b[90m ]\x1b[0m');
|
||||||
|
|
||||||
// Prompt
|
// Prompt
|
||||||
term.write('\x1b[33mgame>\x1b[0m ');
|
term.write('\x1b[33mgame>\x1b[0m ');
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import {
|
|||||||
exitChatMode,
|
exitChatMode,
|
||||||
updateQuickCommands,
|
updateQuickCommands,
|
||||||
runChatCommand,
|
runChatCommand,
|
||||||
|
runGameCommand,
|
||||||
renderChatPrompt,
|
renderChatPrompt,
|
||||||
sendChatMessage
|
sendChatMessage
|
||||||
} from './matrix-client.js';
|
} from './matrix-client.js';
|
||||||
@@ -300,6 +301,7 @@ term.registerLinkProvider({
|
|||||||
|
|
||||||
// Find all command names that match our known commands
|
// Find all command names that match our known commands
|
||||||
const commandNames = ['help', 'about', 'clear', 'echo', 'date', 'whoami', 'history', 'color', 'banner', 'bluesky', 'chat', 'github', 'contact', 'privacy', 'numbermatch'];
|
const commandNames = ['help', 'about', 'clear', 'echo', 'date', 'whoami', 'history', 'color', 'banner', 'bluesky', 'chat', 'github', 'contact', 'privacy', 'numbermatch'];
|
||||||
|
const gameCommandNames = ['add', 'hint', 'new', 'quit'];
|
||||||
|
|
||||||
// When in game mode, detect clickable tile numbers on board lines
|
// When in game mode, detect clickable tile numbers on board lines
|
||||||
if (gameMode.active && lineText.includes('│')) {
|
if (gameMode.active && lineText.includes('│')) {
|
||||||
@@ -366,6 +368,33 @@ term.registerLinkProvider({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// When in game mode, register add/hint/new/quit as clickable words on the controls line
|
||||||
|
if (gameMode.active) {
|
||||||
|
gameCommandNames.forEach(cmd => {
|
||||||
|
let startIndex = 0;
|
||||||
|
while (true) {
|
||||||
|
const index = lineText.indexOf(cmd, startIndex);
|
||||||
|
if (index === -1) break;
|
||||||
|
const charBefore = index > 0 ? lineText[index - 1] : ' ';
|
||||||
|
const charAfter = index + cmd.length < lineText.length ? lineText[index + cmd.length] : ' ';
|
||||||
|
if (/[\s\[]/.test(charBefore) && /[\s\]]/.test(charAfter)) {
|
||||||
|
const capturedCmd = cmd;
|
||||||
|
links.push({
|
||||||
|
range: {
|
||||||
|
start: { x: index + 1, y: bufferLineNumber },
|
||||||
|
end: { x: index + cmd.length + 1, y: bufferLineNumber }
|
||||||
|
},
|
||||||
|
text: cmd,
|
||||||
|
activate: () => {
|
||||||
|
if (window.runGameCommand) window.runGameCommand(capturedCmd);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
startIndex = index + 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
callback(links.length > 0 ? links : undefined);
|
callback(links.length > 0 ? links : undefined);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -521,7 +550,10 @@ const commands = {
|
|||||||
},
|
},
|
||||||
numbermatch: {
|
numbermatch: {
|
||||||
description: numbermatchCmd.description,
|
description: numbermatchCmd.description,
|
||||||
execute: (args) => numbermatchCmd.execute(term, writeClickable, VERSION, args, commandHistory)
|
execute: (args) => {
|
||||||
|
numbermatchCmd.execute(term, writeClickable, VERSION, args, commandHistory);
|
||||||
|
updateQuickCommands('game');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
samsay: {
|
samsay: {
|
||||||
description: samsayCmd.description,
|
description: samsayCmd.description,
|
||||||
@@ -1228,6 +1260,7 @@ async function submitInlineInput() {
|
|||||||
term.write(rawValue + '\r\n');
|
term.write(rawValue + '\r\n');
|
||||||
const continueGame = processGameInput(term, cmd);
|
const continueGame = processGameInput(term, cmd);
|
||||||
if (!continueGame) {
|
if (!continueGame) {
|
||||||
|
updateQuickCommands('terminal');
|
||||||
writePrompt();
|
writePrompt();
|
||||||
}
|
}
|
||||||
setTimeout(() => positionInlineInput(), 10);
|
setTimeout(() => positionInlineInput(), 10);
|
||||||
@@ -1317,8 +1350,9 @@ async function init() {
|
|||||||
welcomeBannerMinimal
|
welcomeBannerMinimal
|
||||||
});
|
});
|
||||||
|
|
||||||
// Expose chat command for onclick handlers
|
// Expose chat and game command handlers for onclick buttons
|
||||||
window.runChatCommand = runChatCommand;
|
window.runChatCommand = runChatCommand;
|
||||||
|
window.runGameCommand = runGameCommand;
|
||||||
|
|
||||||
// Display welcome banner with clickable commands
|
// Display welcome banner with clickable commands
|
||||||
const cols = term.cols;
|
const cols = term.cols;
|
||||||
|
|||||||
Reference in New Issue
Block a user