Add attacker selection from enemies list

Allow selecting an attacker from the bestiary/enemies list to
automatically populate BS and WS values. This enables using player
characters (added as enemies) as attackers in combat rolls.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
This commit is contained in:
2026-03-01 18:08:29 +01:00
co-authored by Claude Opus 4.5
parent 4130ab7766
commit 96d471b2f8
+30
View File
@@ -334,6 +334,7 @@ function DeathwatchRoller() {
const [enemiesLoading,setEnemiesLoading] = useState(false)
const [enemiesError,setEnemiesError] = useState(null)
const [enemyName,setEnemyName] = useState('Custom/None')
const [attackerName,setAttackerName] = useState('Custom/None')
// Load enemies from database API
async function loadEnemiesFromAPI() {
@@ -536,6 +537,29 @@ function DeathwatchRoller() {
else setDefenderModifier(0)
}
function onSelectAttacker(name) {
setAttackerName(name)
const e = enemies.find(x=>x.name===name)
if (!e || name === "Custom/None") return
// Extract WS/BS from enemy
function findNumeric(o, keys) {
if (!o || typeof o !== "object") return undefined
for (const k of keys) {
if (typeof o[k] === "number") return o[k]
const lower = k.toLowerCase()
for (const ok of Object.keys(o)) {
if (ok.toLowerCase() === lower && typeof o[ok] === "number") return o[ok]
}
}
return undefined
}
const char = e.characteristics || (e.tabInfo && e.tabInfo.characteristics) || {}
const wsVal = findNumeric(e, ["ws", "Ws", "WS"]) ?? findNumeric(char, ["ws"])
const bsVal = findNumeric(e, ["bs", "Bs", "BS"]) ?? findNumeric(char, ["bs"])
if (typeof wsVal === "number") setWS(wsVal)
if (typeof bsVal === "number") setBS(bsVal)
}
function importFromJSONText(txt) {
try {
const arr = JSON.parse(txt)
@@ -1111,6 +1135,12 @@ function DeathwatchRoller() {
<Tooltip text="Toughness Bonus">TB</Tooltip> / <Tooltip text="Armour Rating">AR</Tooltip> / <Tooltip text="Wounds">W</Tooltip> {enemies.length} enemies loaded
</div>
</div>
<div>
<label className="text-xs uppercase opacity-70">Attacker (from enemies)</label>
<select className="w-full rounded-xl border border-slate-600 bg-slate-800 px-3 py-2" value={attackerName} onChange={e=>onSelectAttacker(e.target.value)}>
{enemies.map(en => (<option key={"atk-"+en.name} value={en.name}>{en.name}{en.name==="Custom/None" ? "" : ` (WS ${en.ws??"-"} / BS ${en.bs??"-"})`}</option>))}
</select>
</div>
<div>
<label className="text-xs uppercase opacity-70">
<Tooltip text="Ballistic Skill - Used for ranged attacks">Attacker's BS</Tooltip>