feat: v0.12.0 — contracts → packages: load/fly/abandon gameplay (ATR 72-600 capacity 6, manual flight to any airport, time-scaled abandon penalty 15–60%), one-time DB migration preserving wallet/clock; new endpoints /api/packages/:id/load|abandon + /api/planes/:planeId/fly
This commit is contained in:
+12
-6
@@ -11,7 +11,9 @@ export const planes = sqliteTable('planes', {
|
||||
fuel: real('fuel').notNull(),
|
||||
maxFuel: real('max_fuel').notNull(),
|
||||
locationIcao: text('location_icao').notNull(),
|
||||
contractId: text('contract_id'),
|
||||
// Current flight destination (v0.12.0) — set by fly, cleared on arrival. The
|
||||
// plane's origin is always its locationIcao while flying.
|
||||
destIcao: text('dest_icao'),
|
||||
lat: real('lat').notNull(),
|
||||
lon: real('lon').notNull(),
|
||||
// Sim-clock departure time of the current flight (null when available). While
|
||||
@@ -20,7 +22,11 @@ export const planes = sqliteTable('planes', {
|
||||
departureSimTime: integer('departure_sim_time'),
|
||||
});
|
||||
|
||||
export const contracts = sqliteTable('contracts', {
|
||||
// Cargo packages (v0.12.0) replace the old contracts table end-to-end: a package
|
||||
// is one cargo unit origin → dest with a reward and deadline. 'loaded' = bound to
|
||||
// a plane's slot; it stays bound ('expired') or pays out ('delivered') when the
|
||||
// plane arrives at its destination airport.
|
||||
export const packages = sqliteTable('packages', {
|
||||
id: text('id').primaryKey().notNull(),
|
||||
originIcao: text('origin_icao').notNull(),
|
||||
destIcao: text('dest_icao').notNull(),
|
||||
@@ -28,9 +34,9 @@ export const contracts = sqliteTable('contracts', {
|
||||
cargoType: text('cargo_type').notNull(),
|
||||
cargoCount: integer('cargo_count').notNull(),
|
||||
deadlineSimTime: integer('deadline_sim_time').notNull(),
|
||||
// 'expired' = an open contract whose deadline passed (v0.7.0). Accepted/
|
||||
// in-flight contracts never expire — they complete.
|
||||
status: text('status', { enum: ['open', 'accepted', 'completed', 'expired'] }).notNull(),
|
||||
// 'expired' = an open OR loaded package whose deadline passed on a tick. Loaded
|
||||
// expired packages keep occupying their slot, deliver no reward, and abandon free.
|
||||
status: text('status', { enum: ['open', 'loaded', 'delivered', 'expired', 'abandoned'] }).notNull(),
|
||||
planeId: text('plane_id'),
|
||||
createdSimTime: integer('created_sim_time').notNull(),
|
||||
});
|
||||
@@ -50,6 +56,6 @@ export const simState = sqliteTable('sim_state', {
|
||||
});
|
||||
|
||||
export type PlaneRow = typeof planes.$inferSelect;
|
||||
export type ContractRow = typeof contracts.$inferSelect;
|
||||
export type PackageRow = typeof packages.$inferSelect;
|
||||
export type AccountRow = typeof account.$inferSelect;
|
||||
export type SimStateRow = typeof simState.$inferSelect;
|
||||
|
||||
Reference in New Issue
Block a user