Expose mission trade salvage and repair progression
This commit is contained in:
parent
acb5126389
commit
2c4cb471ab
@ -24,6 +24,7 @@ overlay.innerHTML = `
|
|||||||
<span>CARGO <strong data-dock="cargo">0/0</strong></span>
|
<span>CARGO <strong data-dock="cargo">0/0</strong></span>
|
||||||
<span>SALVAGE <strong data-dock="salvage">0</strong></span>
|
<span>SALVAGE <strong data-dock="salvage">0</strong></span>
|
||||||
<span>MISSION <strong data-dock="mission">NONE</strong></span>
|
<span>MISSION <strong data-dock="mission">NONE</strong></span>
|
||||||
|
<span>WANTED <strong data-dock="wanted">0</strong></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<nav class="dock-nav" aria-label="Dock services">
|
<nav class="dock-nav" aria-label="Dock services">
|
||||||
@ -46,6 +47,13 @@ overlay.innerHTML = `
|
|||||||
<strong>SHIPYARD</strong>
|
<strong>SHIPYARD</strong>
|
||||||
<span>Upgrade the Sparrow and manage recovered salvage.</span>
|
<span>Upgrade the Sparrow and manage recovered salvage.</span>
|
||||||
</button>
|
</button>
|
||||||
|
<div class="dock-repair-strip">
|
||||||
|
<div>
|
||||||
|
<strong>HULL SERVICE</strong>
|
||||||
|
<span data-dock="repair-status">Hull already at full strength.</span>
|
||||||
|
</div>
|
||||||
|
<button type="button" data-action="repair-hull">REPAIR</button>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="dock-panel" data-panel="missions" hidden>
|
<section class="dock-panel" data-panel="missions" hidden>
|
||||||
@ -166,6 +174,32 @@ style.textContent = `
|
|||||||
}
|
}
|
||||||
.dock-service strong { display:block; margin-bottom:8px; color:#fff1bc; font-size:22px; }
|
.dock-service strong { display:block; margin-bottom:8px; color:#fff1bc; font-size:22px; }
|
||||||
.dock-service span { color:#aac0c6; font:600 12px/1.45 system-ui,sans-serif; }
|
.dock-service span { color:#aac0c6; font:600 12px/1.45 system-ui,sans-serif; }
|
||||||
|
.dock-repair-strip {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
display:flex;
|
||||||
|
align-items:center;
|
||||||
|
justify-content:space-between;
|
||||||
|
gap:12px;
|
||||||
|
padding:12px 14px;
|
||||||
|
border:1px solid rgba(194, 142, 61, .46);
|
||||||
|
border-radius:10px;
|
||||||
|
background:rgba(4, 28, 35, .9);
|
||||||
|
}
|
||||||
|
.dock-repair-strip > div { display:grid; gap:3px; }
|
||||||
|
.dock-repair-strip strong { color:#fff0bd; font-size:14px; }
|
||||||
|
.dock-repair-strip span { color:#9fb5bb; font:600 10px/1.3 system-ui,sans-serif; }
|
||||||
|
.dock-repair-strip button {
|
||||||
|
min-width:110px;
|
||||||
|
min-height:42px;
|
||||||
|
padding:7px 12px;
|
||||||
|
border:1px solid #9a6a2b;
|
||||||
|
border-radius:8px;
|
||||||
|
background:#103b3d;
|
||||||
|
color:#f5dda0;
|
||||||
|
font:700 10px/1 system-ui,sans-serif;
|
||||||
|
touch-action:manipulation;
|
||||||
|
}
|
||||||
|
.dock-repair-strip button:disabled { opacity:.36; }
|
||||||
.dock-panel { display: grid; gap: 10px; }
|
.dock-panel { display: grid; gap: 10px; }
|
||||||
.dock-section-head { display:flex; align-items:center; justify-content:space-between; gap:10px; }
|
.dock-section-head { display:flex; align-items:center; justify-content:space-between; gap:10px; }
|
||||||
.dock-section-head > div { display:grid; gap:2px; }
|
.dock-section-head > div { display:grid; gap:2px; }
|
||||||
@ -309,7 +343,13 @@ const renderMarket = (state) => {
|
|||||||
strong.textContent = item.name;
|
strong.textContent = item.name;
|
||||||
const tag = document.createElement('small');
|
const tag = document.createElement('small');
|
||||||
tag.className = 'dock-tag';
|
tag.className = 'dock-tag';
|
||||||
tag.textContent = item.exported ? 'LOCAL EXPORT' : item.imported ? 'HIGH DEMAND' : 'MARKET';
|
tag.textContent = item.shortage > 0.5
|
||||||
|
? `SHORTAGE +${Math.round(item.shortage * 8)}%`
|
||||||
|
: item.exported
|
||||||
|
? 'LOCAL EXPORT'
|
||||||
|
: item.imported
|
||||||
|
? 'HIGH DEMAND'
|
||||||
|
: 'MARKET';
|
||||||
name.append(strong, tag);
|
name.append(strong, tag);
|
||||||
const buy = document.createElement('span');
|
const buy = document.createElement('span');
|
||||||
buy.className = 'dock-price';
|
buy.className = 'dock-price';
|
||||||
@ -317,13 +357,20 @@ const renderMarket = (state) => {
|
|||||||
const sell = document.createElement('span');
|
const sell = document.createElement('span');
|
||||||
sell.className = 'dock-price';
|
sell.className = 'dock-price';
|
||||||
sell.textContent = `SELL ¢${item.sellPrice} • HOLD ${item.held || 0}`;
|
sell.textContent = `SELL ¢${item.sellPrice} • HOLD ${item.held || 0}`;
|
||||||
|
const hint = document.createElement('p');
|
||||||
|
const opportunity = item.opportunity;
|
||||||
|
hint.textContent = opportunity
|
||||||
|
? opportunity.margin > 0
|
||||||
|
? `BEST KNOWN: ${opportunity.portName} • SELL ¢${opportunity.sellPrice} • +¢${opportunity.margin}/UNIT`
|
||||||
|
: `BEST KNOWN: ${opportunity.portName} • no positive margin`
|
||||||
|
: 'No known destination price.';
|
||||||
const actions = document.createElement('div');
|
const actions = document.createElement('div');
|
||||||
actions.className = 'dock-card-actions';
|
actions.className = 'dock-card-actions';
|
||||||
actions.append(
|
actions.append(
|
||||||
actionButton('BUY 1', 'buy-trade-good', { goodId: item.goodId }, !item.canBuy),
|
actionButton('BUY 1', 'buy-trade-good', { goodId: item.goodId }, !item.canBuy),
|
||||||
actionButton('SELL 1', 'sell-trade-good', { goodId: item.goodId }, !item.canSell),
|
actionButton('SELL 1', 'sell-trade-good', { goodId: item.goodId }, !item.canSell),
|
||||||
);
|
);
|
||||||
card.append(name, buy, sell, actions);
|
card.append(name, buy, sell, hint, actions);
|
||||||
fields['market-list'].append(card);
|
fields['market-list'].append(card);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -338,6 +385,19 @@ const render = (state) => {
|
|||||||
fields.cargo.textContent = `${dock.cargoUsed || 0}/${dock.cargoCapacity || 0}`;
|
fields.cargo.textContent = `${dock.cargoUsed || 0}/${dock.cargoCapacity || 0}`;
|
||||||
fields.salvage.textContent = state.progression?.inventoryCount || 0;
|
fields.salvage.textContent = state.progression?.inventoryCount || 0;
|
||||||
fields.mission.textContent = dock.activeMission ? dock.activeMission.type.toUpperCase() : 'NONE';
|
fields.mission.textContent = dock.activeMission ? dock.activeMission.type.toUpperCase() : 'NONE';
|
||||||
|
fields.wanted.textContent = dock.wanted || 0;
|
||||||
|
|
||||||
|
const repairButton = overlay.querySelector('[data-action="repair-hull"]');
|
||||||
|
const repair = dock.repair;
|
||||||
|
if (repair) {
|
||||||
|
fields['repair-status'].textContent = repair.missing > 0
|
||||||
|
? `Repair ${repair.missing} hull for ¢${repair.cost}.`
|
||||||
|
: 'Hull already at full strength.';
|
||||||
|
repairButton.disabled = repair.missing <= 0
|
||||||
|
|| (state.progression?.credits || 0) < repair.cost;
|
||||||
|
repairButton.textContent = repair.missing > 0 ? `REPAIR ¢${repair.cost}` : 'FULL HULL';
|
||||||
|
}
|
||||||
|
|
||||||
fields.message.textContent = String(state.status || '').replace(/\n/g, ' ');
|
fields.message.textContent = String(state.status || '').replace(/\n/g, ' ');
|
||||||
renderMission(state);
|
renderMission(state);
|
||||||
renderMarket(state);
|
renderMarket(state);
|
||||||
@ -360,6 +420,8 @@ for (const button of overlay.querySelectorAll('[data-dock-tab]')) {
|
|||||||
for (const button of overlay.querySelectorAll('[data-action="open-shipyard"]')) {
|
for (const button of overlay.querySelectorAll('[data-action="open-shipyard"]')) {
|
||||||
button.addEventListener('click', () => dispatchAction('open-shipyard'));
|
button.addEventListener('click', () => dispatchAction('open-shipyard'));
|
||||||
}
|
}
|
||||||
|
overlay.querySelector('[data-action="repair-hull"]')
|
||||||
|
.addEventListener('click', () => dispatchAction('repair-hull'));
|
||||||
overlay.querySelector('.dock-leave').addEventListener('click', () => dispatchAction('close-dock'));
|
overlay.querySelector('.dock-leave').addEventListener('click', () => dispatchAction('close-dock'));
|
||||||
overlay.querySelector('.dock-backdrop').addEventListener('click', () => dispatchAction('close-dock'));
|
overlay.querySelector('.dock-backdrop').addEventListener('click', () => dispatchAction('close-dock'));
|
||||||
|
|
||||||
|
|||||||
@ -326,6 +326,42 @@ if (!isDesktopPointer.matches) {
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.steam-objective {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: 20.5%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
align-items: center;
|
||||||
|
gap: 7px;
|
||||||
|
max-width: 78%;
|
||||||
|
padding: 5px 9px;
|
||||||
|
border: 1px solid rgba(201, 146, 60, .58);
|
||||||
|
border-radius: 999px;
|
||||||
|
background: rgba(5, 22, 28, .82);
|
||||||
|
color: #f7dfa1;
|
||||||
|
font: 700 clamp(9px, 2.45vw, 12px)/1.1 system-ui, sans-serif;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
box-shadow: 0 2px 10px rgba(0,0,0,.28);
|
||||||
|
}
|
||||||
|
|
||||||
|
.steam-objective.visible { display: flex; }
|
||||||
|
|
||||||
|
.steam-objective-arrow {
|
||||||
|
display: inline-block;
|
||||||
|
color: #ffe08c;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 1;
|
||||||
|
transform-origin: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.steam-objective-text {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
#mobile-controls.controller-active #drag-stick {
|
#mobile-controls.controller-active #drag-stick {
|
||||||
left: 1%;
|
left: 1%;
|
||||||
bottom: max(8px, env(safe-area-inset-bottom));
|
bottom: max(8px, env(safe-area-inset-bottom));
|
||||||
@ -697,6 +733,14 @@ if (!isDesktopPointer.matches) {
|
|||||||
status.dataset.steam = 'status';
|
status.dataset.steam = 'status';
|
||||||
hud.appendChild(status);
|
hud.appendChild(status);
|
||||||
|
|
||||||
|
const objective = document.createElement('div');
|
||||||
|
objective.className = 'steam-objective';
|
||||||
|
objective.innerHTML = `
|
||||||
|
<span class="steam-objective-arrow" data-steam="objective-arrow">↑</span>
|
||||||
|
<span class="steam-objective-text" data-steam="objective-text"></span>
|
||||||
|
`;
|
||||||
|
hud.appendChild(objective);
|
||||||
|
|
||||||
const fields = Object.fromEntries(
|
const fields = Object.fromEntries(
|
||||||
[...hud.querySelectorAll('[data-steam]')].map((el) => [el.dataset.steam, el]),
|
[...hud.querySelectorAll('[data-steam]')].map((el) => [el.dataset.steam, el]),
|
||||||
);
|
);
|
||||||
@ -800,6 +844,21 @@ if (!isDesktopPointer.matches) {
|
|||||||
fields['port-reload'].style.transform = `scaleX(${clamp01(state.reload?.port ?? 1)})`;
|
fields['port-reload'].style.transform = `scaleX(${clamp01(state.reload?.port ?? 1)})`;
|
||||||
fields['starboard-reload'].style.transform = `scaleX(${clamp01(state.reload?.starboard ?? 1)})`;
|
fields['starboard-reload'].style.transform = `scaleX(${clamp01(state.reload?.starboard ?? 1)})`;
|
||||||
|
|
||||||
|
const mission = state.objective || null;
|
||||||
|
objective.classList.toggle('visible', Boolean(mission));
|
||||||
|
if (mission?.type === 'delivery') {
|
||||||
|
fields['objective-arrow'].hidden = false;
|
||||||
|
fields['objective-arrow'].style.transform = `rotate(${mission.relativeBearing || 0}deg)`;
|
||||||
|
fields['objective-text'].textContent =
|
||||||
|
`${mission.label} • ${Math.round(mission.distance || 0)}m`;
|
||||||
|
} else if (mission?.type === 'bounty') {
|
||||||
|
fields['objective-arrow'].hidden = true;
|
||||||
|
fields['objective-text'].textContent = mission.progressText || 'PIRATE BOUNTY';
|
||||||
|
} else {
|
||||||
|
fields['objective-arrow'].hidden = true;
|
||||||
|
fields['objective-text'].textContent = '';
|
||||||
|
}
|
||||||
|
|
||||||
const progression = state.progression || {};
|
const progression = state.progression || {};
|
||||||
if (buyButton) {
|
if (buyButton) {
|
||||||
buyButton.hidden = !progression.docked;
|
buyButton.hidden = !progression.docked;
|
||||||
|
|||||||
@ -79,12 +79,14 @@ overlay.innerHTML = `
|
|||||||
<footer class="shipyard-footer">
|
<footer class="shipyard-footer">
|
||||||
<div class="shipyard-salvage-panel">
|
<div class="shipyard-salvage-panel">
|
||||||
<div class="shipyard-salvage-copy">
|
<div class="shipyard-salvage-copy">
|
||||||
<strong>SALVAGE HOLD</strong>
|
<strong>SALVAGE HOLD <span data-shipyard="salvage-index">0/0</span></strong>
|
||||||
<span data-shipyard="salvage-name">EMPTY</span>
|
<span data-shipyard="salvage-name">EMPTY</span>
|
||||||
<span data-shipyard="salvage-meta">Pirate wrecks repair hull immediately.</span>
|
<span data-shipyard="salvage-meta">Pirate wrecks repair hull immediately.</span>
|
||||||
<span data-shipyard="salvage-effect">Recovered modules are stored here to fit or scrap.</span>
|
<span data-shipyard="salvage-effect">Recovered modules are stored here to fit or scrap.</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="shipyard-salvage-actions">
|
<div class="shipyard-salvage-actions">
|
||||||
|
<button class="shipyard-salvage" type="button" data-shipyard="prev">◀ PREV</button>
|
||||||
|
<button class="shipyard-salvage" type="button" data-shipyard="next">NEXT ▶</button>
|
||||||
<button class="shipyard-salvage" type="button" data-shipyard="fit">FIT MODULE</button>
|
<button class="shipyard-salvage" type="button" data-shipyard="fit">FIT MODULE</button>
|
||||||
<button class="shipyard-salvage shipyard-scrap" type="button" data-shipyard="scrap">SCRAP MODULE</button>
|
<button class="shipyard-salvage shipyard-scrap" type="button" data-shipyard="scrap">SCRAP MODULE</button>
|
||||||
</div>
|
</div>
|
||||||
@ -477,9 +479,12 @@ const fields = Object.fromEntries(
|
|||||||
const closeButton = overlay.querySelector('.shipyard-close');
|
const closeButton = overlay.querySelector('.shipyard-close');
|
||||||
const fitButton = overlay.querySelector('[data-shipyard="fit"]');
|
const fitButton = overlay.querySelector('[data-shipyard="fit"]');
|
||||||
const scrapButton = overlay.querySelector('[data-shipyard="scrap"]');
|
const scrapButton = overlay.querySelector('[data-shipyard="scrap"]');
|
||||||
|
const prevButton = overlay.querySelector('[data-shipyard="prev"]');
|
||||||
|
const nextButton = overlay.querySelector('[data-shipyard="next"]');
|
||||||
const upgradeButtons = [...overlay.querySelectorAll('.shipyard-upgrade-button')];
|
const upgradeButtons = [...overlay.querySelectorAll('.shipyard-upgrade-button')];
|
||||||
|
|
||||||
let latestState = null;
|
let latestState = null;
|
||||||
|
let selectedSalvageIndex = 0;
|
||||||
|
|
||||||
const render = (state) => {
|
const render = (state) => {
|
||||||
if (!state?.progression) return;
|
if (!state?.progression) return;
|
||||||
@ -538,13 +543,24 @@ const render = (state) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const salvage = progression.salvageItem;
|
const salvageItems = progression.salvageItems || [];
|
||||||
|
selectedSalvageIndex = salvageItems.length
|
||||||
|
? Math.min(selectedSalvageIndex, salvageItems.length - 1)
|
||||||
|
: 0;
|
||||||
|
const salvage = salvageItems[selectedSalvageIndex] || null;
|
||||||
|
fields['salvage-index'].textContent = salvageItems.length
|
||||||
|
? `${selectedSalvageIndex + 1}/${salvageItems.length}`
|
||||||
|
: '0/0';
|
||||||
|
prevButton.disabled = salvageItems.length <= 1;
|
||||||
|
nextButton.disabled = salvageItems.length <= 1;
|
||||||
|
|
||||||
if (salvage) {
|
if (salvage) {
|
||||||
|
const effectiveness = Math.round(55 + salvage.condition * 45);
|
||||||
fields['salvage-name'].textContent = salvage.name;
|
fields['salvage-name'].textContent = salvage.name;
|
||||||
fields['salvage-meta'].textContent =
|
fields['salvage-meta'].textContent =
|
||||||
`${String(salvage.slot || 'module').toUpperCase()} • ${salvage.conditionPercent}% CONDITION`;
|
`${String(salvage.slot || 'module').toUpperCase()} • ${salvage.conditionPercent}% CONDITION • ${effectiveness}% EFFECT`;
|
||||||
fields['salvage-effect'].textContent =
|
fields['salvage-effect'].textContent =
|
||||||
`${salvage.effectSummary || 'Recovered equipment'} • Fit it or convert it to scrap.`;
|
`${salvage.effectSummary || 'Recovered equipment'} • Fit this module or convert it to scrap.`;
|
||||||
fitButton.disabled = false;
|
fitButton.disabled = false;
|
||||||
fitButton.textContent = 'FIT MODULE';
|
fitButton.textContent = 'FIT MODULE';
|
||||||
scrapButton.disabled = false;
|
scrapButton.disabled = false;
|
||||||
@ -592,22 +608,37 @@ for (const button of upgradeButtons) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prevButton.addEventListener('click', () => {
|
||||||
|
const items = latestState?.progression?.salvageItems || [];
|
||||||
|
if (items.length <= 1) return;
|
||||||
|
selectedSalvageIndex = (selectedSalvageIndex - 1 + items.length) % items.length;
|
||||||
|
render(latestState);
|
||||||
|
});
|
||||||
|
|
||||||
|
nextButton.addEventListener('click', () => {
|
||||||
|
const items = latestState?.progression?.salvageItems || [];
|
||||||
|
if (items.length <= 1) return;
|
||||||
|
selectedSalvageIndex = (selectedSalvageIndex + 1) % items.length;
|
||||||
|
render(latestState);
|
||||||
|
});
|
||||||
|
|
||||||
fitButton.addEventListener('click', () => {
|
fitButton.addEventListener('click', () => {
|
||||||
if (fitButton.disabled) return;
|
if (fitButton.disabled) return;
|
||||||
dispatchAction('fit-salvage');
|
dispatchAction('fit-salvage', { inventoryIndex: selectedSalvageIndex });
|
||||||
});
|
});
|
||||||
|
|
||||||
scrapButton.addEventListener('click', () => {
|
scrapButton.addEventListener('click', () => {
|
||||||
if (scrapButton.disabled) return;
|
if (scrapButton.disabled) return;
|
||||||
dispatchAction('scrap-salvage');
|
dispatchAction('scrap-salvage', { inventoryIndex: selectedSalvageIndex });
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener('airship:shipyard-open', (event) => show(event.detail));
|
window.addEventListener('airship:shipyard-open', (event) => show(event.detail));
|
||||||
window.addEventListener('airship:shipyard-state', (event) => render(event.detail));
|
window.addEventListener('airship:shipyard-state', (event) => render(event.detail));
|
||||||
window.addEventListener('airship:shipyard-close', hide);
|
window.addEventListener('airship:shipyard-close', hide);
|
||||||
window.addEventListener('airship:hud-state', (event) => {
|
window.addEventListener('airship:hud-state', (event) => {
|
||||||
|
// Shipyard buttons must remain stable during touch gestures.
|
||||||
|
// Explicit shipyard-state events redraw after purchases/fits/scraps.
|
||||||
latestState = event.detail;
|
latestState = event.detail;
|
||||||
if (!overlay.hidden) render(event.detail);
|
|
||||||
});
|
});
|
||||||
window.addEventListener('keydown', (event) => {
|
window.addEventListener('keydown', (event) => {
|
||||||
if (event.key === 'Escape' && !overlay.hidden) {
|
if (event.key === 'Escape' && !overlay.hidden) {
|
||||||
|
|||||||
@ -285,6 +285,9 @@ test('mobile controls enter a dock hub before shipyard, trade, or missions', asy
|
|||||||
assert.match(dockUi, /panel\.setAttribute\('aria-hidden'/);
|
assert.match(dockUi, /panel\.setAttribute\('aria-hidden'/);
|
||||||
assert.match(dockUi, /dispatchAction\('open-shipyard'\)/);
|
assert.match(dockUi, /dispatchAction\('open-shipyard'\)/);
|
||||||
assert.match(hud, /buyButton\.textContent = badges\.length/);
|
assert.match(hud, /buyButton\.textContent = badges\.length/);
|
||||||
|
assert.match(hud, /steam-objective/);
|
||||||
|
assert.match(hud, /objective-arrow/);
|
||||||
|
assert.match(hud, /mission\.relativeBearing/);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('shipyard overlay uses supplied component art and explicit module purchases', async () => {
|
test('shipyard overlay uses supplied component art and explicit module purchases', async () => {
|
||||||
@ -306,6 +309,13 @@ test('shipyard overlay uses supplied component art and explicit module purchases
|
|||||||
assert.match(shipyard, /CURRENT:/);
|
assert.match(shipyard, /CURRENT:/);
|
||||||
assert.match(shipyard, /NEXT:/);
|
assert.match(shipyard, /NEXT:/);
|
||||||
assert.match(shipyard, /dispatchAction\('scrap-salvage'\)/);
|
assert.match(shipyard, /dispatchAction\('scrap-salvage'\)/);
|
||||||
|
assert.match(shipyard, /selectedSalvageIndex/);
|
||||||
|
assert.match(shipyard, /inventoryIndex: selectedSalvageIndex/);
|
||||||
|
assert.match(shipyard, /salvageItems/);
|
||||||
|
assert.doesNotMatch(
|
||||||
|
shipyard,
|
||||||
|
/airship:hud-state'[\s\S]{0,180}if \(!overlay\.hidden\) render\(event\.detail\)/,
|
||||||
|
);
|
||||||
assert.match(shipyard, /Pirate wrecks repair hull immediately on pickup/);
|
assert.match(shipyard, /Pirate wrecks repair hull immediately on pickup/);
|
||||||
assert.doesNotMatch(shipyard, /data-shipyard="active"/);
|
assert.doesNotMatch(shipyard, /data-shipyard="active"/);
|
||||||
assert.match(shipyard, /min-height: calc\(100dvh - 8px\)/);
|
assert.match(shipyard, /min-height: calc\(100dvh - 8px\)/);
|
||||||
@ -344,6 +354,9 @@ test('dock trade and missions are driven by generated port economy state', async
|
|||||||
assert.match(dockUi, /sell-trade-good/);
|
assert.match(dockUi, /sell-trade-good/);
|
||||||
assert.match(dockUi, /accept-mission/);
|
assert.match(dockUi, /accept-mission/);
|
||||||
assert.match(dockUi, /complete-mission/);
|
assert.match(dockUi, /complete-mission/);
|
||||||
|
assert.match(dockUi, /repair-hull/);
|
||||||
|
assert.match(dockUi, /BEST KNOWN:/);
|
||||||
|
assert.match(dockUi, /data-dock="wanted"/);
|
||||||
assert.match(dockUi, /airship:dock-state/);
|
assert.match(dockUi, /airship:dock-state/);
|
||||||
assert.match(dockUi, /latestState = event\.detail/);
|
assert.match(dockUi, /latestState = event\.detail/);
|
||||||
assert.doesNotMatch(
|
assert.doesNotMatch(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user