feat: add factory sample machines and robot pricing conversations
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
import { addPolygon, resolveCircle } from '../world/collision.js';
|
||||
import { createState } from '../economy/gameState.js';
|
||||
import { createPayment } from '../economy/payment.js';
|
||||
import { createVendingMachine } from '../models/vending.js';
|
||||
/**
|
||||
* Runs the place station operation for this subsystem.
|
||||
* @param {*} context - context.
|
||||
* @param {*} def - def.
|
||||
* @param {*} pos - pos.
|
||||
* @param {*} rot - rot.
|
||||
* @returns {*} Operation result, when applicable.
|
||||
*/
|
||||
export function placeStation(context, def, pos, rot) {
|
||||
const model = createVendingMachine(def);
|
||||
model.group.position.set(pos.x, 0, pos.z);
|
||||
model.group.rotation.y = rot;
|
||||
context.scene.add(model.group);
|
||||
addPolygon(
|
||||
context.collision,
|
||||
[
|
||||
[-1, -0.6],
|
||||
[1, -0.6],
|
||||
[1, 0.6],
|
||||
[-1, 0.6],
|
||||
].flatMap(([lx, lz]) => {
|
||||
const p = context.rotateLocal(lx, lz, rot);
|
||||
return [pos.x + p.x, pos.z + p.z];
|
||||
}),
|
||||
);
|
||||
const front = context.rotateLocal(0, 1.9, rot);
|
||||
return {
|
||||
def,
|
||||
model,
|
||||
x: pos.x,
|
||||
z: pos.z,
|
||||
rot,
|
||||
front: {
|
||||
x: pos.x + front.x,
|
||||
z: pos.z + front.z,
|
||||
},
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Updates reach circles from the active simulation.
|
||||
* @param {*} context - context.
|
||||
* @returns {*} Operation result, when applicable.
|
||||
*/
|
||||
export function updateReachCircles(context) {
|
||||
const radius = context.reachRadius(),
|
||||
objective = context.real.on ? context.objectiveStation() : null;
|
||||
for (const s of context.stations) {
|
||||
s.reach.visible = context.real.on;
|
||||
if (!context.real.on) continue;
|
||||
s.reach.scale.setScalar(radius);
|
||||
s.reach.material.color.set(s === objective ? '#f2c94c' : '#3ee0c9');
|
||||
}
|
||||
}
|
||||
// GPS test points only take part while real-world mode is on.
|
||||
/**
|
||||
* Runs the reset operation for this subsystem.
|
||||
* @param {*} context - context.
|
||||
* @returns {*} Operation result, when applicable.
|
||||
*/
|
||||
export function reset(context) {
|
||||
context.state = createState();
|
||||
context.payment = createPayment();
|
||||
// The family starts in the factory yard, facing the engineering office.
|
||||
const spot = resolveCircle(
|
||||
context.collision,
|
||||
context.factory.start.x,
|
||||
context.factory.start.z,
|
||||
1,
|
||||
);
|
||||
context.player = {
|
||||
x: spot.x,
|
||||
z: spot.z,
|
||||
heading: context.factory.start.heading,
|
||||
speed: 0,
|
||||
gait: 0,
|
||||
};
|
||||
context.factory.reset();
|
||||
for (const t of context.factory.talks) t.done = false;
|
||||
context.car = context.spawnCar();
|
||||
context.mode = 'walk';
|
||||
// Camera yaw: the camera sits at target + (sin yaw, cos yaw) * distance, so it looks along (-sin, -cos).
|
||||
context.cam = {
|
||||
yaw: Math.atan2(-Math.cos(context.player.heading), Math.sin(context.player.heading)),
|
||||
pitch: 0.32,
|
||||
distance: 5.5,
|
||||
lastMouse: -10,
|
||||
};
|
||||
context.waypoint = null;
|
||||
context.route = null;
|
||||
context.routeTimer = 0;
|
||||
context.deliveryTimer = 0;
|
||||
context.ended = false;
|
||||
context.hints = {
|
||||
closed: false,
|
||||
car: false,
|
||||
};
|
||||
Object.assign(context.guideState, {
|
||||
station: null,
|
||||
t: 0,
|
||||
greeted: new Set(),
|
||||
arrived: 0,
|
||||
});
|
||||
context.ui.patch('payment', {
|
||||
hidden: true,
|
||||
});
|
||||
for (const s of context.stations) {
|
||||
s.model.delivery.visible = s.model.card.visible = false;
|
||||
s.model.flap.rotation.x = 0;
|
||||
}
|
||||
for (const id of ['shop', 'map-dialog', 'end', 'showroom']) context.ui.close(id);
|
||||
context.keys.clear();
|
||||
context.refreshHUD();
|
||||
}
|
||||
|
||||
// ---------- Input ----------
|
||||
/**
|
||||
* Runs the start mission operation for this subsystem.
|
||||
* @param {*} context - context.
|
||||
* @returns {*} Operation result, when applicable.
|
||||
*/
|
||||
export function startMission(context) {
|
||||
context.ui.patch('briefing', {
|
||||
hidden: true,
|
||||
});
|
||||
context.ui.patch('hud', {
|
||||
hidden: false,
|
||||
});
|
||||
context.say(
|
||||
'robot',
|
||||
'سه نمونهٔ ۳۵، ۴۸ و ۶۰ کانال توی حیاط کنار ماشین هستند. دکمهٔ مدلهای کارخانه یا Q را بزن تا قیمت و امکاناتشان را بگویم.',
|
||||
'wink',
|
||||
);
|
||||
context.say('child', 'بابا، اینجا همون کارخونهایه که دستگاههای روبات مارکت رو میسازه؟');
|
||||
context.say(
|
||||
'father',
|
||||
'آره! سالن تولید اونوره؛ دستگاه وندینگ هم توی دفتر فنی مهندسیه. بریم ببینیم!',
|
||||
);
|
||||
context.say('child', 'اون وانت سفیده کیه داره میاد تو؟');
|
||||
context.say('father', 'آقای محمدیه، مدیر شرکت. بعداً بریم اتاقش سلام کنیم.');
|
||||
if (!context.isTouch && !context.real.on)
|
||||
context.canvas.requestPointerLock?.()?.catch?.(() => {});
|
||||
}
|
||||
Reference in New Issue
Block a user