Drill the militia; drill sergeant replaces rallying
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
fd66b69401
commit
1c80bd80f7
6 changed files with 102 additions and 31 deletions
|
|
@ -487,12 +487,17 @@ function actionCard(a) {
|
|||
}
|
||||
io += Object.entries(a.outputs).map(([id, q]) => itemChip(id, q)).join("");
|
||||
let extra = "";
|
||||
if (a.skill === "combat") {
|
||||
if ("difficulty" in a) {
|
||||
const chance = Math.min(0.97, Math.max(0.15, 0.5 + (me.power - a.difficulty) * 0.04));
|
||||
extra = `<div class="small">Win chance <b>${Math.round(chance * 100)}%</b> · about <b>${me.fight_damage[a.id]}</b> damage a fight${a.gold ? ` · ${a.gold} gold` : ""}</div>`;
|
||||
if (a.drops) io += a.drops.map(([id, q, odds]) => `<span class="item-chip" title="${esc(item(id).name)}: ${Math.round(odds * 100)}% chance">${item(id).icon} ${q} <span class="have">${Math.round(odds * 100)}%</span></span>`).join("");
|
||||
if (a.special === "sabotage") extra += `<div class="small muted">Each win weakens the coming raid by 3%, up to 30%.</div>`;
|
||||
}
|
||||
if (a.special === "drill") {
|
||||
const s = S.favours.sergeant, boost = s.boost;
|
||||
extra = `<div class="small makes">${skillOf("combat").icon} +${me.drill_per_action} defence for the coming raid · ${fmt(s.drilled)} / ${fmt(s.cap)} drilled${boost ? ` <b class="boosted">×2 defence and XP for the next ${fmt(boost)}</b>` : ""}</div>
|
||||
<div class="small muted">More per session every 20 combat levels. The militia can take up to half a defence per townsperson.</div>`;
|
||||
}
|
||||
if (a.special === "recon") {
|
||||
const boost = S.favours.informant.boost;
|
||||
extra = `<div class="small makes">${skillOf("reconnaissance").icon} +${+me.recon_gain[a.id].toFixed(2)} recon on the coming threat${boost ? ` <b class="boosted">×2 recon and XP for the next ${fmt(boost)}</b>` : ""}</div>`;
|
||||
|
|
@ -519,7 +524,7 @@ function actionCard(a) {
|
|||
<div class="foot">
|
||||
<span class="why">${!active && why ? esc(why) : ""}</span>
|
||||
${active ? `<button class="btn danger" data-stop>Stop</button>`
|
||||
: `<span class="btns"><button class="btn" data-once="${a.id}" ${why ? "disabled" : ""} title="Do this once, then go back to what you were doing">${a.skill === "combat" ? "Fight once" : Object.keys(a.outputs).length ? "Make one" : "Once"}</button>
|
||||
: `<span class="btns"><button class="btn" data-once="${a.id}" ${why ? "disabled" : ""} title="Do this once, then go back to what you were doing">${"difficulty" in a ? "Fight once" : Object.keys(a.outputs).length ? "Make one" : "Once"}</button>
|
||||
<button class="btn primary" data-start="${a.id}" ${why ? "disabled" : ""}>Start</button></span>`}
|
||||
</div>
|
||||
</div>`;
|
||||
|
|
@ -617,7 +622,7 @@ function favourPanel() {
|
|||
return `<div class="panel"><h2>Favour with the council</h2>
|
||||
<p class="favour">${FAVOUR} ${fmt(me.favour)} favour · ${fmt(me.donated)} given in total</p>
|
||||
<div class="btns"><button class="btn" data-perk="bank_slot" ${me.favour < me.perk_costs.bank_slot ? "disabled" : ""}>+1 bank slot (${fmt(me.perk_costs.bank_slot)} favour)</button></div>
|
||||
<p class="small muted">Favour can also hire builders, pay informants and rally the militia: see <button class="linkish" data-nav="council">Council & threats</button>.</p></div>`;
|
||||
<p class="small muted">Favour can also hire master builders, informants and drill sergeants: see <button class="linkish" data-nav="council">Council & threats</button>.</p></div>`;
|
||||
}
|
||||
|
||||
// --- town -----------------------------------------------------------------
|
||||
|
|
@ -857,13 +862,13 @@ function favourSpends() {
|
|||
return `<div class="panel"><h2>Spend favour on the city · you have ${FAVOUR} ${fmt(me.favour)}</h2>
|
||||
${option("builders", "🏗️", "Hire a master builder", f.builders.why ? esc(f.builders.why) + "." : `The next ${f.builders.labour} labour anyone puts into the site counts double, with double Construction XP${f.builders.boost ? ` (${fmt(f.builders.boost)} still to use)` : ""}. Costs more each time on the same site.`)}
|
||||
${option("informant", "🕵️", "Pay an informant", f.informant.why ? esc(f.informant.why) + "." : `Leads for the scouts: the next ${f.informant.recon} reconnaissance on the coming threat counts double, with double XP${f.informant.boost ? ` (${fmt(f.informant.boost)} still to use)` : ""}. Costs more each time for the same threat.`)}
|
||||
${option("militia", "📯", "Rally the militia", f.militia.why ? esc(f.militia.why) + "." : `+10 defence for the coming raid${f.militia.rallied ? ` (+${f.militia.rallied} so far)` : ""}. Costs more each time.`)}
|
||||
${option("sergeant", "📯", "Hire a drill sergeant", f.sergeant.why ? esc(f.sergeant.why) + "." : `The next ${f.sergeant.drill} defence fighters drill into the militia counts double, with double combat XP${f.sergeant.boost ? ` (${fmt(f.sergeant.boost)} still to use)` : ""}. Costs more each time for the same threat.`)}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
function raidPrep(ev) {
|
||||
const city = S.city, me = S.me, d = city.defence;
|
||||
const names = { mercenaries: "Hired sellswords", ward: "Divine ward (temple)", rallied: "Rallied militia (favour)", townsfolk: "Townsfolk with pitchforks", walls: "Walls", militia: "Militia (barracks)", weapons: "Swords in the armoury", shields: "Shields in the armoury", arrows: "Arrows", garrison: "Garrison" };
|
||||
const names = { mercenaries: "Hired sellswords", ward: "Divine ward (temple)", rallied: "Rallied militia (favour)", drilled: "Drilled militia", townsfolk: "Townsfolk with pitchforks", walls: "Walls", militia: "Militia (barracks)", weapons: "Swords in the armoury", shields: "Shields in the armoury", arrows: "Arrows", garrison: "Garrison" };
|
||||
const reqs = (ev.requests || []).map((r) => {
|
||||
const mine = me.bank[r.item] || 0;
|
||||
return `<div class="req"><span>${item(r.item).icon}</span><span>${esc(r.label)} <span class="muted small">${fmt(r.have)} / ${fmt(r.want)}</span></span>
|
||||
|
|
@ -874,7 +879,7 @@ function raidPrep(ev) {
|
|||
<div class="panel"><h2>Council requests</h2>${reqs}
|
||||
<p class="small muted">Arrows, swords and shields in the stockpile arm the defenders: one sword and shield each, best first. Every fight uses up arrows and breaks some of the gear, more when it's close. Food keeps them fighting.</p></div>
|
||||
<div class="panel"><h2>Defence</h2>
|
||||
<table class="parts">${Object.entries(d.parts).map(([k, v]) => `<tr><td>${names[k]}</td><td>${fmt(v)}</td></tr>`).join("")}
|
||||
<table class="parts">${Object.entries(d.parts).filter(([k, v]) => k !== "rallied" || v).map(([k, v]) => `<tr><td>${names[k]}</td><td>${fmt(v)}</td></tr>`).join("")}
|
||||
${d.starving ? `<tr><td class="bad">Hungry (×0.8)</td><td></td></tr>` : ""}</table>
|
||||
<h2 style="margin-top:16px">Garrison</h2>
|
||||
<p class="small">${d.garrison.length ? d.garrison.map((g) => `${esc(g.name)} (${g.power})`).join(", ") : `<span class="muted">Nobody has signed up yet.</span>`}</p>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue