mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 19:04:02 +00:00
feat(hud): Cyber HUD theme with GPU contact sonar (#706)
Add the opt-in Cyber HUD layout with coordinated map and cockpit panel styling, GPU-only contact sonar (rings, range, power, opacity, sector) with native-rendering fallback, and set_cyber_sonar voice controls. Sonar visual style inspired by kk376's tactical naval sonar (#214). Co-authored-by: Sameh Khamis <[email protected]> Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
74 files changed
+7320
-90
No files matched your search
@@ -9,6 +9,19 @@ function element(value = '') {
|
||||
return el;
|
||||
}
|
||||
|
||||
test('sonar on/off control cannot fire after disposal', () => {
|
||||
const sonarButton = element();
|
||||
const calls = [];
|
||||
const control = bindDisplayControls({
|
||||
elements: { sonarButton },
|
||||
actions: { toggleSonar: () => calls.push('toggle') },
|
||||
});
|
||||
sonarButton.dispatchEvent(new Event('click'));
|
||||
control.destroy();
|
||||
sonarButton.dispatchEvent(new Event('click'));
|
||||
assert.deepEqual(calls, ['toggle']);
|
||||
});
|
||||
|
||||
test('controls read current values without preventing native input behavior', () => {
|
||||
const bloomSlider = element('24');
|
||||
const hudLayout = element('tactical');
|
||||
@@ -54,6 +67,51 @@ test('destroyed and replaced controls cannot issue stale actions', () => {
|
||||
assert.equal(newCalls, 1);
|
||||
});
|
||||
|
||||
test('the Cyber sonar control is an optional owned display action', () => {
|
||||
const sonarButton = element();
|
||||
const sonarRingsSlider = element('9');
|
||||
const sonarRangeSlider = element('110');
|
||||
const sonarIntensitySlider = element('65');
|
||||
const sonarOpacitySlider = element('84');
|
||||
const sonarSectorSlider = element('32');
|
||||
const calls = [];
|
||||
const control = bindDisplayControls({
|
||||
elements: {
|
||||
sonarButton,
|
||||
sonarRingsSlider,
|
||||
sonarRangeSlider,
|
||||
sonarIntensitySlider,
|
||||
sonarOpacitySlider,
|
||||
sonarSectorSlider,
|
||||
},
|
||||
actions: {
|
||||
toggleSonar: () => calls.push('toggle'),
|
||||
setSonarRings: (value) => calls.push(['rings', value]),
|
||||
setSonarRange: (value) => calls.push(['range', value]),
|
||||
setSonarIntensity: (value) => calls.push(['intensity', value]),
|
||||
setSonarOpacity: (value) => calls.push(['opacity', value]),
|
||||
setSonarSector: (value) => calls.push(['sector', value]),
|
||||
},
|
||||
});
|
||||
sonarButton.dispatchEvent(new Event('click'));
|
||||
sonarRingsSlider.dispatchEvent(new Event('input'));
|
||||
sonarRangeSlider.dispatchEvent(new Event('input'));
|
||||
sonarIntensitySlider.dispatchEvent(new Event('input'));
|
||||
sonarOpacitySlider.dispatchEvent(new Event('input'));
|
||||
sonarSectorSlider.dispatchEvent(new Event('input'));
|
||||
assert.deepEqual(calls, [
|
||||
'toggle',
|
||||
['rings', 9],
|
||||
['range', 110],
|
||||
['intensity', 65],
|
||||
['opacity', 84],
|
||||
['sector', 32],
|
||||
]);
|
||||
control.destroy();
|
||||
sonarButton.dispatchEvent(new Event('click'));
|
||||
assert.equal(calls.length, 6);
|
||||
});
|
||||
|
||||
test('style, allocation and model choices retain their current data attributes', () => {
|
||||
const style = element();
|
||||
const allocation = element();
|
||||
|
||||
Reference in new issue
Block a user