diff --git a/static/app.js b/static/app.js index f1d6d5c..0477786 100644 --- a/static/app.js +++ b/static/app.js @@ -617,18 +617,19 @@ function actionCard(a) { if (a.special === "drill") { const s = S.favours.sergeant, boost = s.boost; extra = !s.needed ? `
Only while a raid is coming.
` - : `
${skillOf("combat").icon} +${+me.drill_per_action.toFixed(2)} drill · ${fmt(s.points)} / ${fmt(s.needed)} points, worth ${fmt(s.defence)} of ${fmt(s.cap)} defence${boost ? ` ×2 drill and XP for the next ${fmt(boost)}` : ""}
`; + : `
${skillOf("combat").icon} +${+me.drill_per_action.toFixed(2)} drill · ${fmt(s.points)} / ${fmt(s.needed)} points, worth ${fmt(s.defence)} of ${fmt(s.cap)} defence
+ ${boostBar(s.points, s.needed, boost, "Drill sergeant: this stretch drills twice as fast")}`; } if (a.special === "recon") { const boost = S.favours.informant.boost; const ev = S.upcoming, full = ev && ev.recon >= ev.recon_full; extra = full ? `
Fully scouted: XP only.
` - : `
${skillOf("reconnaissance").icon} +${+me.recon_gain[a.id].toFixed(2)} recon${boost ? ` ×2 recon and XP for the next ${fmt(boost)}` : ""}
`; + : `
${skillOf("reconnaissance").icon} +${+me.recon_gain[a.id].toFixed(2)} recon
+ ${ev?.recon_full ? boostBar(ev.recon, ev.recon_full, boost, "Informant: this stretch scouts twice as fast") : ""}`; } const temple = S.city.buildings.temple?.level || 0; if (a.special === "labour") { - const boost = S.favours.builders.boost; - extra = `
${skillOf("construction").icon} +${me.labour_per_action} labour per action${boost ? ` ×2 labour and XP for the next ${fmt(boost)}` : ""}
`; + extra = `
${skillOf("construction").icon} +${me.labour_per_action} labour per action
`; } if (a.special === "bury") extra = `
${skillOf("prayer").icon} +${a.pp + temple} prayer points
`; if (a.special === "offer") extra = `
${C.buildings.temple.icon} +${+(a.devotion * (1 + 0.25 * temple)).toFixed(1)} devotion
`; @@ -782,6 +783,14 @@ function town() { return html; } +// Progress towards a goal favour can boost. Favour doubles the next `boost` points players put +// in, so the striped stretch behind the bar (twice the boost) is where work counts double. +function boostBar(done, total, boost, tip) { + const pct = (x) => Math.min(100, x / total * 100); + return `
${boost + ? `` : ""}
`; +} + // The building site: labour so far, who is helping, and ways to speed it up. function siteBanner() { const city = S.city, work = city.construction, me = S.me; @@ -790,9 +799,6 @@ function siteBanner() { const hire = S.favours.builders; const working = me.action?.id === "labour"; const builders = S.players.filter((p) => p.skill === "construction" && p.doing === "Work on the building site").map((p) => esc(p.name)); - // A master builder doubles the next `boost` labour players put in: that stretch of the bar fills twice as fast. - const done = Math.min(100, work.labour / work.needed * 100); - const boosted = Math.min(100, (work.labour + 2 * hire.boost) / work.needed * 100); return ``; } @@ -929,9 +934,8 @@ function pips(level) { function reconText(ev) { const points = `${fmt(ev.recon)} / ${fmt(ev.recon_full)} points`; if (ev.intel >= 3) return `${points} · complete`; - const boost = S.favours.informant.boost ? ` · informant: ×2 for the next ${fmt(S.favours.informant.boost)}` : ""; - if (ev.recon_next <= 0) return `${points} · next level opens closer to the threat${boost}`; - return `${points} · ${fmt(ev.recon_next)} to the next level${boost}`; + if (ev.recon_next <= 0) return `${points} · next level opens closer to the threat`; + return `${points} · ${fmt(ev.recon_next)} to the next level`; } function council() { @@ -950,7 +954,8 @@ function council() { ${ev.trait ? `Scouts say${esc(ev.trait)}` : ""} ${ev.camp ? `Their campFound · sabotage it in Combat${ev.sabotage ? ` (-${ev.sabotage}% so far)` : ""}` : ""} Reconnaissance${reconText(ev)} - `; + + ${ev.recon_full && ev.intel < 3 ? boostBar(ev.recon, ev.recon_full, S.favours.informant.boost, "Informant: this stretch scouts twice as fast") : ""}`; if (threat) { const strength = ev.strength ?? (ev.range ? `${ev.range[0]}–${ev.range[1]}` : "?"); html += `
Our defence${fmt(city.defence.total)}
vs
Raiders${strength}
`; diff --git a/static/styles.css b/static/styles.css index 46bbc7a..d3bb07d 100644 --- a/static/styles.css +++ b/static/styles.css @@ -142,9 +142,9 @@ main { padding: 24px; max-width: 1200px; width: 100%; } .bar.xp > span { background: var(--xp); } .bar.gold > span { background: var(--gold); } .bar.thick { height: 12px; } -.site-bar { position: relative; } -.site-bar > span { position: relative; z-index: 1; } -.site-bar > span.boost { position: absolute; left: 0; top: 0; z-index: 0; +.boost-bar { position: relative; margin-top: 8px; } +.boost-bar > span { position: relative; z-index: 1; } +.boost-bar > span.boost { position: absolute; left: 0; top: 0; z-index: 0; background: repeating-linear-gradient(-45deg, color-mix(in srgb, var(--gold) 45%, transparent) 0 6px, color-mix(in srgb, var(--gold) 20%, transparent) 6px 12px); } .btn { @@ -432,4 +432,3 @@ button.sheet-skill:hover { background: var(--panel-2); } .credit a { color: var(--muted); } .btn.working { color: var(--good); border-color: rgba(92, 191, 106, .5); background: rgba(92, 191, 106, .1); cursor: default; } .banner-ico { font-size: 22px; display: flex; } -.boosted { color: var(--gold); font-weight: 600; }