procrealms-client
Version:
A web/terminal hybrid client for Procedural Realms
207 lines (174 loc) • 4.45 kB
JavaScript
const Blessed = require('@dinchak/blessed')
const BattleStatus = require('./elements/battle_status')
const Conn = require('./conn')
const GameLog = require('./elements/game_log')
const Help = require('./elements/help')
const Input = require('./elements/input')
const InputCaret = require('./elements/input_caret')
const Log = require('./log')
const Login = require('./elements/login')
const QuickSlots = require('./elements/quick_slots')
const RoomStatus = require('./elements/room_status')
const State = require('./state')
const U = require('./utils')
let screen
let gameLog
let roomStatus
let battleStatus
let quickSlots
let inputCaret
let input
let help
let login
exports.init = function (program) {
screen = Blessed.screen({
fastCSR: true,
cursor: {
artificial: true,
shape: 'block',
color: 'yellow',
blink: true
},
program
})
gameLog = GameLog.create(screen)
roomStatus = RoomStatus.create(screen)
battleStatus = BattleStatus.create(screen)
quickSlots = QuickSlots.create(screen)
inputCaret = InputCaret.create(screen)
input = Input.create(screen)
help = Help.create(screen)
login = Login.create(screen)
screen.append(gameLog)
screen.append(roomStatus)
screen.append(battleStatus)
screen.append(quickSlots)
screen.append(inputCaret)
screen.append(input)
screen.append(help)
screen.append(login)
if (!U.inBrowser()) {
screen.key(['C-c'], function () {
Log.write('received ctrl-c, closing')
return process.exit(0)
})
}
screen.on('resize', function () {
Conn.send('terminal', { width: exports.getTerminalWidth(), height: exports.getTerminalHeight() })
screen.render()
})
screen.on('mouse', function () {
if (!input.focused && State.mode == 'input') {
exports.setCommandMode()
}
})
screen.on('keypress', function (ch, key) {
// exports.addLine(`UI.onKey() ch=${ch} key=${JSON.stringify(key)}`)
// hack to prevent double events in browser
if (key.isTrusted) {
return
}
if (State.mode == 'login') {
login.emit('keypress', ch, key)
screen.render()
return
}
if (State.mode == 'help') {
exports.addLine('hide help')
exports.hideHelp()
screen.render()
return
}
if (State.mode == 'command' || !input.focused) {
if (key.name == 'enter') {
exports.setInputMode()
return
}
quickSlots.emit('keypress', ch, key)
screen.render()
return
}
})
}
exports.draw = function () {
const { battle } = State.state
if (battle && battle.active) {
battleStatus.emit('resize')
battleStatus.show()
roomStatus.hide()
} else {
roomStatus.show()
battleStatus.hide()
}
screen.render()
}
exports.addLine = function (line) {
let autoScroll = true
if (gameLog.getScroll() != gameLog.getScrollHeight() - 1) {
autoScroll = false
}
// line += ` getScroll=${log.getScroll()}, getScrollHeight=${log.getScrollHeight()}, autoScroll=${autoScroll}`
gameLog.add(line)
if (autoScroll) {
gameLog.scrollTo(gameLog.getScrollHeight())
}
// allows scrolling with arrow keys
// console.log('focus game log')
if (State.mode == 'command') {
gameLog.focus()
}
}
exports.runCommand = function (cmd) {
exports.addLine(U.parseAnsi(`{{w> {{Y${cmd}`))
gameLog.scrollTo(gameLog.getScrollHeight())
Conn.send('cmd', cmd)
}
exports.setCommandMode = function () {
Log.write(`setCommandMode()`)
State.mode = 'command'
if (input.focused) {
screen.focusPop()
}
gameLog.focus()
screen.render()
}
exports.setInputMode = function () {
Log.write(`setInputMode()`)
State.mode = 'input'
if (!input.focused) {
Log.write(`input.focus()`)
input.focus()
}
Log.write(`input.readInput()`)
input.readInput()
screen.render()
}
exports.getTerminalWidth = function () {
return screen.width - 30
}
exports.getTerminalHeight = function () {
return screen.height - 2
}
exports.showHelp = function () {
State.mode = 'help'
help.show()
screen.render()
}
exports.hideHelp = function () {
State.mode = 'command'
help.hide()
screen.render()
}
exports.showLogin = function (loginStep) {
State.mode = 'login'
Login.setLoginStep(loginStep)
login.show()
screen.render()
}
exports.hideLogin = function () {
State.mode = 'command'
Login.setLoginStep('token')
login.hide()
screen.focusPop()
screen.render()
}