Improve summit terrain, mobile HUD and multiplayer night equipment

Add the Blender flashlight asset with a 600 lm beam and reduced bloom, shared-mode self badge, and compact phone controls. Relocate the summit marker, blend terrain seams, widen walking routes, and align local server configuration on port 2027.
This commit is contained in:
2026-10-31 23:14:44 +09:00
parent 18dfb63350
commit eb49ea4b84
40 changed files with 402 additions and 64 deletions
+28
View File
@@ -5,6 +5,34 @@ import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { createRainGearState } from '../src/controls/rainGear.ts';
import { createEmoteState } from '../src/controls/emotes.ts';
import { createSheep } from '../src/scene/sheep.ts';
import { createFlashlight } from '../src/scene/flashlight.ts';
import { FLASHLIGHT } from '../src/constants/flashlight.ts';
import { Vector3 } from 'three';
test('authored flashlight stays in the left grip and uses lumen power only when switched on', async () => {
const [model, umbrella, raincoat, torch] = await Promise.all(['red-sheep', 'umbrella', 'raincoat', 'flashlight'].map(asset));
const sheep = createSheep(model, { umbrella, raincoat, flashlight: torch });
const beam = createFlashlight(sheep.group);
assert.equal(torch.parent, model.getObjectByName('ArmLeft'));
assert.equal(torch.visible, false);
assert.equal(beam.light.visible, false);
assert.equal(beam.light.intensity, FLASHLIGHT.lumens / (2 * Math.PI * (1 - Math.cos(FLASHLIGHT.halfAngle))));
sheep.setEquipment(true, false, false, true);
sheep.pose('idle', 0, true, 1);
beam.update(true);
assert.equal(torch.visible, true);
const direction = new Vector3().subVectors(beam.light.target.position, beam.light.position).normalize();
assert.ok(direction.z > .9 && direction.y < 0, 'beam points forward and slightly down');
const before = beam.light.position.clone();
sheep.group.position.x += 3;
beam.update(true);
assert.ok(Math.abs(beam.light.position.x-before.x-3) < .001);
sheep.setEquipment(false, false, false, false);
beam.update(false);
assert.equal(torch.visible, false);
assert.equal(beam.light.visible, false);
beam.dispose(); sheep.dispose();
});
test('rain equipment is independent of emotes, remains in snow, and clears in dry weather', () => {
const gear = createRainGearState();