iv: fix route selection and otium den deduction in Forum.jsx

This commit is contained in:
otivm
2026-05-03 18:54:40 +00:00
parent e13b54a697
commit 7aed095f69

View File

@@ -2,6 +2,10 @@
// FORUM context screen. Replaces Ledger.jsx.
// Renders two divs directly into Shell's two-col layout grid.
// All game logic migrated from Ledger.jsx.
//
// Fixes from initial version:
// - isRouteUnlocked called with route.id (string), not route (object)
// - applyOtium result has 8 dn deducted to match server-side debit
import { useState, useEffect, useRef } from 'react'
import Section from '../components/Section.jsx'
@@ -27,7 +31,6 @@ export default function Forum({ state, onStateChange, onNewGame }) {
const [otium, setOtium] = useState(null)
const [message, setMessage] = useState('')
const [journal, setJournal] = useState(getSeenJournalEntries(state))
const [newEntryKey, setNewEntryKey] = useState(null)
const tickRef = useRef(null)
const msgRef = useRef(null)
@@ -48,11 +51,7 @@ export default function Forum({ state, onStateChange, onNewGame }) {
const newState = applyDispatch(state, dispatch.routeId)
const route = ROUTES.find(r => r.id === dispatch.routeId)
showMessage(`Galley returned. +${route.profit} denarii.`)
if (entry) {
setJournal(j => [entry, ...j])
setNewEntryKey(`${dispatch.routeId}-${newState.route_dispatches[dispatch.routeId]}`)
setTimeout(() => setNewEntryKey(null), 5000)
}
if (entry) setJournal(j => [entry, ...j])
setSelectedRoute(null)
onStateChange(newState)
}
@@ -61,8 +60,10 @@ export default function Forum({ state, onStateChange, onNewGame }) {
const elapsed = now - otium.startMs
if (elapsed >= OTIUM_DURATION_MS) {
setOtium(null)
const newState = applyOtium(state)
showMessage('Otium complete. Auctoritas recorded.')
// Apply otium aut gain, then deduct 8 dn to match server-side debit
const withAut = applyOtium(state)
const newState = { ...withAut, den: Math.max(0, withAut.den - OTIUM_CYCLE_TOTAL_DN) }
showMessage(`Otium complete. ${OTIUM_CYCLE_TOTAL_DN} dn. Auctoritas recorded.`)
onStateChange(newState)
}
}
@@ -74,6 +75,7 @@ export default function Forum({ state, onStateChange, onNewGame }) {
function handleSelectRoute(routeId) {
if (busy) return
// Fix: pass route.id string to isRouteUnlocked, not the route object
if (!isRouteUnlocked(state, routeId)) return
setSelectedRoute(prev => prev === routeId ? null : routeId)
}
@@ -103,19 +105,14 @@ export default function Forum({ state, onStateChange, onNewGame }) {
}
// Progress
let progressPct = 0, progressLabel = '', progressSub = ''
let progressPct = 0
if (dispatch) {
progressPct = Math.min(((Date.now()-dispatch.startMs)/dispatch.durationMs)*100, 100)
const route = ROUTES.find(r=>r.id===dispatch.routeId)
progressLabel = `${WAYPOINTS[route.from].name}${WAYPOINTS[route.to].name}`
progressSub = `${Math.round(progressPct)}%`
} else if (otium) {
progressPct = Math.min(((Date.now()-otium.startMs)/OTIUM_DURATION_MS)*100, 100)
progressLabel = 'resting...'
progressSub = `${Math.round(progressPct)}%`
}
// Section data
// Section data — active venture
const activeVentureItems = dispatch ? (() => {
const route = ROUTES.find(r => r.id === dispatch.routeId)
return [
@@ -130,8 +127,9 @@ export default function Forum({ state, onStateChange, onNewGame }) {
{ key: 'Cost', value: `${OTIUM_CYCLE_TOTAL_DN} dn`, cls: 'bad' },
] : [{ key: 'Status', value: 'No galley at sea', cls: '' }]
// Route list — fix: pass route.id to isRouteUnlocked
const routeItems = ROUTES.map(route => {
const unlocked = isRouteUnlocked(state, route)
const unlocked = isRouteUnlocked(state, route.id)
const vectura = Math.round(route.cost * 0.60 * 10) / 10
const portoria = Math.round(route.cost * 0.25 * 10) / 10
const other = Math.round((route.cost - vectura - portoria) * 10) / 10
@@ -145,7 +143,11 @@ export default function Forum({ state, onStateChange, onNewGame }) {
profit: route.profit,
vectura, portoria, other,
locked: !unlocked,
lock_reason: !unlocked ? (state.den<route.unlock_den ? `${route.unlock_den.toLocaleString()} dn` : `Auctoritas ${route.unlock_aut}`) : null,
lock_reason: !unlocked
? (state.den < route.unlock_den
? `${route.unlock_den.toLocaleString()} dn`
: `Auctoritas ${route.unlock_aut}`)
: null,
}
})
@@ -181,7 +183,6 @@ export default function Forum({ state, onStateChange, onNewGame }) {
background: 'var(--otivm-ink)', color: 'var(--otivm-parch)',
padding: '10px 18px', borderRadius: '3px',
fontSize: '0.8rem', fontStyle: 'italic', zIndex: 300,
gridColumn:'1/-1',
}}>
{message}
</div>