phase 0.3
This commit is contained in:
commit
4a94bfc4e7
52 changed files with 11653 additions and 0 deletions
6
sql/migrations/001_add_service_times.sql
Normal file
6
sql/migrations/001_add_service_times.sql
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
-- Migration 001: add per-plane service bay timing
|
||||
-- Run once against an existing skyrama_clone database.
|
||||
|
||||
ALTER TABLE planes
|
||||
ADD COLUMN boarding_time_seconds INTEGER UNSIGNED NOT NULL DEFAULT 0,
|
||||
ADD COLUMN fueling_time_seconds INTEGER UNSIGNED NOT NULL DEFAULT 0;
|
||||
16
sql/migrations/003_sell_demolish_caps.sql
Normal file
16
sql/migrations/003_sell_demolish_caps.sql
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
-- Migration 003: sell planes, demolish buildings, per-type building caps
|
||||
-- Run once against an existing skyrama_clone database.
|
||||
|
||||
-- Stable purchase timestamp for the 5-minute full-refund sell window.
|
||||
-- (player_planes.updated_at bumps on every status change, so it can't be used.)
|
||||
ALTER TABLE player_planes
|
||||
ADD COLUMN purchased_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP AFTER updated_at;
|
||||
|
||||
-- Existing planes get NOW() from the default, so they immediately fall outside
|
||||
-- the 5-minute window and sell at the 50% rate (intended).
|
||||
|
||||
-- Per-type building caps. Raised by level-gated capacity upgrades
|
||||
-- (see internal/db CapUpgradeTiers). Base values match the schema defaults.
|
||||
ALTER TABLE airports
|
||||
ADD COLUMN storage_cap INTEGER UNSIGNED NOT NULL DEFAULT 3,
|
||||
ADD COLUMN operation_cap INTEGER UNSIGNED NOT NULL DEFAULT 2;
|
||||
33
sql/migrations/004_central_dispatch.sql
Normal file
33
sql/migrations/004_central_dispatch.sql
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
-- Migration 004: central-port dispatch + NPC factions + unload lifecycle
|
||||
-- Run once against an existing skyrama_clone database.
|
||||
-- Row seeding (NPC users, hub countries, central airports, factions) is done
|
||||
-- idempotently in Go by Client.EnsureStage0World() at startup, not here.
|
||||
|
||||
-- Central ports are system-owned (faction NPC) airports, one per continent.
|
||||
ALTER TABLE airports
|
||||
ADD COLUMN is_central BOOLEAN NOT NULL DEFAULT FALSE;
|
||||
|
||||
-- NPC faction-leader users: cannot log in (empty password_hash), hidden from
|
||||
-- login + user lists.
|
||||
ALTER TABLE users
|
||||
ADD COLUMN is_npc BOOLEAN NOT NULL DEFAULT FALSE;
|
||||
|
||||
-- Where a dispatched plane is flying to, plus a post-landing 'unloading' phase.
|
||||
ALTER TABLE player_planes
|
||||
MODIFY COLUMN status ENUM('idle','maintenance','boarding','taxiing','flying','unloading') NOT NULL DEFAULT 'idle',
|
||||
ADD COLUMN destination_airport_id INT UNSIGNED DEFAULT NULL,
|
||||
ADD FOREIGN KEY (destination_airport_id) REFERENCES airports(id);
|
||||
|
||||
-- One NPC faction per continent; owns that continent's central port.
|
||||
CREATE TABLE IF NOT EXISTS factions (
|
||||
id integer unsigned primary key auto_increment,
|
||||
name varchar(255) not null,
|
||||
continent ENUM('void','Africa','Antarctica','Asia','Europe','North America','Oceania','South America') NOT NULL UNIQUE,
|
||||
leader_name varchar(255) not null,
|
||||
background TEXT,
|
||||
user_id integer not null,
|
||||
central_airport_id integer unsigned not null,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
foreign key (user_id) references users(id),
|
||||
foreign key (central_airport_id) references airports(id)
|
||||
);
|
||||
382
sql/queries.sql
Normal file
382
sql/queries.sql
Normal file
|
|
@ -0,0 +1,382 @@
|
|||
-- ============================================================================
|
||||
-- 1. AUTHENTICATION & USERS
|
||||
-- ============================================================================
|
||||
|
||||
-- name: CreateUser :execresult
|
||||
INSERT INTO users (username, password_hash)
|
||||
VALUES (?, ?);
|
||||
|
||||
-- name: UpdateUserPasswordByUserName :exec
|
||||
UPDATE users
|
||||
SET password_hash = ?
|
||||
WHERE username = ?;
|
||||
|
||||
-- name: GetUserByUsername :one
|
||||
SELECT id, username, password_hash
|
||||
FROM users
|
||||
WHERE username = ? LIMIT 1;
|
||||
|
||||
-- name: GetUserIdByUsername :one
|
||||
SELECT id
|
||||
FROM users
|
||||
WHERE username = ? LIMIT 1;
|
||||
|
||||
-- name: DeleteUserByUsername :exec
|
||||
UPDATE users
|
||||
SET deleted_at = CURRENT_TIMESTAMP
|
||||
WHERE username = ?;
|
||||
|
||||
|
||||
-- name: DeleteAirportByUserName :exec
|
||||
UPDATE airports
|
||||
SET is_deleted = TRUE
|
||||
WHERE user_id = (SELECT id FROM users WHERE username = ?);
|
||||
|
||||
-- ============================================================================
|
||||
-- 2. AIRPORT CORE MANAGEMENT
|
||||
-- ============================================================================
|
||||
|
||||
-- airport row management
|
||||
|
||||
-- name: CreateAirportByUserName :execresult
|
||||
INSERT INTO airports (name, user_id, origin_country_id)
|
||||
VALUES (?, (SELECT id FROM users WHERE username = ?), ?);
|
||||
|
||||
|
||||
-- name: GetAirportByUserId :one
|
||||
SELECT id, name, user_id, origin_country_id, cash, current_passengers, max_passenger_capacity, current_fuel, max_fuel_capacity, is_available, player_level, experience_points, passenger_generation_rate, fuel_generation_rate, resources_last_updated_at, is_deleted
|
||||
FROM airports
|
||||
WHERE user_id = ? LIMIT 1;
|
||||
-- name: GetAirportByUserName :one
|
||||
SELECT id, name, user_id, origin_country_id, cash, current_passengers, max_passenger_capacity, current_fuel, max_fuel_capacity, is_available, player_level, experience_points ,passenger_generation_rate, fuel_generation_rate, resources_last_updated_at, is_deleted
|
||||
FROM airports
|
||||
WHERE user_id = (SELECT id FROM users WHERE username = ?) LIMIT 1;
|
||||
|
||||
|
||||
-- airport resource management
|
||||
|
||||
|
||||
-- name: UpdateAirportCurrencies :exec
|
||||
UPDATE airports
|
||||
SET cash = ?,
|
||||
current_passengers = ?,
|
||||
current_fuel = ?
|
||||
WHERE id = ?;
|
||||
|
||||
-- name: UpdateAirportResources :exec
|
||||
UPDATE airports
|
||||
SET
|
||||
current_fuel = LEAST(
|
||||
max_fuel_capacity,
|
||||
current_fuel + (fuel_generation_rate * (TIMESTAMPDIFF(SECOND, resources_last_updated_at, NOW()) DIV 60))
|
||||
),
|
||||
current_passengers = LEAST(
|
||||
max_passenger_capacity,
|
||||
current_passengers + (passenger_generation_rate * (TIMESTAMPDIFF(SECOND, resources_last_updated_at, NOW()) DIV 60))
|
||||
),
|
||||
resources_last_updated_at = resources_last_updated_at
|
||||
+ INTERVAL (TIMESTAMPDIFF(SECOND, resources_last_updated_at, NOW()) DIV 60) MINUTE
|
||||
WHERE id = ?;
|
||||
|
||||
-- name: UpdateAirportCash :exec
|
||||
UPDATE airports
|
||||
SET cash = ?
|
||||
WHERE id = ?;
|
||||
-- name: UpdateAirportpassengers :exec
|
||||
UPDATE airports
|
||||
SET current_passengers = ?
|
||||
WHERE id = ?;
|
||||
-- name: UpdateAirportFuel :exec
|
||||
UPDATE airports
|
||||
SET current_fuel = ?
|
||||
WHERE id = ?;
|
||||
-- name: UpdateAirportmaxPassengers :exec
|
||||
UPDATE airports
|
||||
SET max_passenger_capacity = ?
|
||||
WHERE id = ?;
|
||||
-- name: UpdateAirportMaxFuel :exec
|
||||
UPDATE airports
|
||||
SET max_fuel_capacity = ?
|
||||
WHERE id = ?;
|
||||
|
||||
-- name: UpdateAirportFuelRate :exec
|
||||
UPDATE airports
|
||||
SET fuel_generation_rate = ?
|
||||
WHERE id = ?;
|
||||
-- name: UpdateAirportPassengerRate :exec
|
||||
UPDATE airports
|
||||
SET passenger_generation_rate = ?
|
||||
WHERE id = ?;
|
||||
|
||||
-- name: UpdateAirportResourcesUpdated :exec
|
||||
update airports
|
||||
set resources_last_updated_at = ?
|
||||
where id = ?;
|
||||
|
||||
|
||||
-- name: updatePlayerExperience :exec
|
||||
UPDATE airports
|
||||
SET experience_points = ?
|
||||
WHERE id = ?;
|
||||
|
||||
-- name: updatePlayerLevel :exec
|
||||
UPDATE airports
|
||||
SET player_level = ?
|
||||
WHERE id = ?;
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- 3. country
|
||||
-- ============================================================================
|
||||
-- name: GetAllCountries :many
|
||||
SELECT id, name FROM countries;
|
||||
-- name: GetCountryById :one
|
||||
SELECT id, name FROM countries WHERE id = ?;
|
||||
-- name: GetCountryByName :one
|
||||
SELECT id, name FROM countries WHERE name = ?;
|
||||
|
||||
-- name: AddCountry :execresult
|
||||
INSERT INTO countries (name,continent,produce_1_id,produce_2_id,produce_3_id)
|
||||
VALUES (?, ?, ?, ?, ?);
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- 4. BUILDINGS & PRODUCTION ENGINE
|
||||
-- ============================================================================
|
||||
|
||||
-- name: Addproduct :execresult
|
||||
insert into products (name) values (?);
|
||||
|
||||
-- name: GetAllProducts :many
|
||||
select id, name from products;
|
||||
|
||||
-- name: GetProductById :one
|
||||
select id, name from products where id = ?;
|
||||
|
||||
|
||||
-- name: addStorageBuilding :execresult
|
||||
INSERT INTO buildings (name,min_level,construction_cost_cash,capacity,storage_type,storage_subtype)
|
||||
VALUES (?, ?, ?, ?, ?, ?);
|
||||
|
||||
-- name: addOperationalBuilding :execresult
|
||||
INSERT INTO buildings (name,min_level,construction_cost_cash,operation_type,operation_size)
|
||||
VALUES (?, ?, ?, ?, ?);
|
||||
|
||||
-- name: addPassiveProductionBuilding :execresult
|
||||
INSERT INTO buildings (name,min_level,construction_cost_cash,passive_type,passive_rate)
|
||||
VALUES (?, ?, ?, ?, ?);
|
||||
|
||||
-- name: addBuildingBasic :execresult
|
||||
INSERT INTO buildings (name,min_level,construction_cost_cash,building_type)
|
||||
VALUES (?, ?, ?,'none');
|
||||
-- name: UpdateBuildingAsStorage :execresult
|
||||
update buildings
|
||||
set
|
||||
building_type = 'storage'
|
||||
capacity = ?
|
||||
storage_type = ?
|
||||
storage_subtype= ?;
|
||||
|
||||
VALUES (?, ?, ?);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- name: AddBuildingToAirportByUsername :execresult
|
||||
INSERT INTO airport_buildings (airport_id, building_id)
|
||||
VALUES ((select id from airports where user_id = (select id from users where username = ?)), ?);
|
||||
|
||||
-- name: GetAirportBuildingsByUsername :many
|
||||
SELECT ab.id AS airport_building_id,b.building_type , b.*
|
||||
FROM airport_buildings ab
|
||||
JOIN buildings b ON ab.building_id = b.id
|
||||
WHERE ab.airport_id = (select id from airports where user_id = (select id from users where username = ?));
|
||||
|
||||
|
||||
|
||||
-- planes & fleet management
|
||||
|
||||
-- name: addPlane :execresult
|
||||
INSERT INTO planes (name, aircraft_size,operation_type,aircraft_type ,min_level, operation_cost_fuel, operation_cost_cash, max_passengers, travel_time_inSeconds,buying_cost_cash, completed_flight_experience, completed_flight_cash_reward, completed_flight_cargo_reward)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
|
||||
|
||||
|
||||
-- name: GetPlaneById :one
|
||||
SELECT * FROM planes WHERE id = ?;
|
||||
|
||||
-- name: GetAllPlanes :many
|
||||
SELECT * FROM planes;
|
||||
|
||||
-- name: GetPlanesByOperationType :many
|
||||
SELECT * FROM planes WHERE operation_type = ?;
|
||||
|
||||
-- name: GetPlanesByMinLevel :many
|
||||
SELECT * FROM planes WHERE min_level <= ?;
|
||||
|
||||
-- name: GetPlanesByAircraftSize :many
|
||||
SELECT * FROM planes WHERE aircraft_size = ?;
|
||||
|
||||
-- name: GetPlanesByAircraftType :many
|
||||
SELECT * FROM planes WHERE aircraft_type = ?;
|
||||
|
||||
-- name: addPlaneToAirportByUsername :execresult
|
||||
INSERT INTO player_planes (airport_id, plane_id, assigned_hangar_id, current_building_id, status)
|
||||
VALUES ((select id from airports where user_id = (select id from users where username = ?)), ?, ?, ?, 'idle');
|
||||
|
||||
-- name: GetPlayerPlanesByUsername :many
|
||||
SELECT pp.id AS player_plane_id, pp.*
|
||||
FROM player_planes pp
|
||||
JOIN planes p ON pp.plane_id = p.id
|
||||
WHERE pp.airport_id = (select id from airports where user_id = (select id from users where username = ?));
|
||||
|
||||
|
||||
-- name: FindAvailableInfrastructureForPlane :one
|
||||
SELECT ab.id
|
||||
FROM airport_buildings ab
|
||||
JOIN buildings b ON ab.building_id = b.id
|
||||
LEFT JOIN player_planes pp ON ab.id = pp.current_building_id
|
||||
WHERE ab.airport_id = (select id from airports where user_id = (select id from users where username = ?))
|
||||
AND b.operation_type = ? -- 'runway' or 'service' (service bay)
|
||||
AND b.operation_size = ? -- matches plane's aircraft_size requirement
|
||||
AND pp.id IS NULL -- Ensures no other plane is physically here right now
|
||||
LIMIT 1;
|
||||
|
||||
-- name: UpdatePlayerPlaneState :exec
|
||||
UPDATE player_planes
|
||||
SET current_building_id = ?,
|
||||
status = ?,
|
||||
flight_start_time = ?
|
||||
WHERE id = ?;
|
||||
|
||||
-- name: CheckHangarOccupancyByUsername :one
|
||||
SELECT COUNT(*) AS total_parked
|
||||
FROM player_planes pp
|
||||
JOIN airport_buildings ab ON pp.current_building_id = ab.id
|
||||
WHERE ab.airport_id = (select id from airports where user_id = (select id from users where username = ?))
|
||||
AND ab.building_id = ?; -- specific hangar
|
||||
|
||||
--
|
||||
-- name: CheckRunwayOccupancyByUsername :one
|
||||
SELECT COUNT(*) AS total_occupied
|
||||
FROM player_planes pp
|
||||
JOIN airport_buildings ab ON pp.current_building_id = ab.id
|
||||
WHERE ab.airport_id = (select id from airports where user_id = (select id from users where username = ?))
|
||||
AND ab.building_id = ?; -- specific runway
|
||||
|
||||
-- name: GetPlanesReadyToLandByUsername :many
|
||||
SELECT pp.id AS player_plane_id, pp.airport_id, pp.assigned_hangar_id,
|
||||
p.completed_flight_experience, p.completed_flight_cash_reward, p.completed_flight_cargo_reward, p.operation_type
|
||||
FROM player_planes pp
|
||||
JOIN planes p ON pp.plane_id = p.id
|
||||
WHERE pp.status = 'flying'
|
||||
AND DATE_ADD(pp.flight_start_time, INTERVAL p.travel_time_inSeconds SECOND) <= NOW()
|
||||
AND pp.airport_id = (select id from airports where user_id = (select id from users where username = ?));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- 5. FLEET & DYNAMIC INFRASTRUCTURE OPERATIONS
|
||||
-- ============================================================================
|
||||
|
||||
-- name: BuyPlaneForPlayer :execresult
|
||||
INSERT INTO player_planes (airport_id, plane_id, assigned_hangar_id, current_building_id, status)
|
||||
VALUES (?, ?, ?, ?, 'idle');
|
||||
|
||||
-- name: GetPlayerFleet :many
|
||||
SELECT pp.id AS player_plane_id, pp.status, pp.updated_at, pp.flight_start_time, pp.current_building_id, pp.assigned_hangar_id,p.*
|
||||
FROM player_planes pp
|
||||
JOIN planes p ON pp.plane_id = p.id
|
||||
WHERE pp.airport_id = ?;
|
||||
|
||||
-- name: FindAvailableInfrastructure :one
|
||||
SELECT ab.id
|
||||
FROM airport_buildings ab
|
||||
JOIN buildings b ON ab.building_id = b.id
|
||||
LEFT JOIN player_planes pp ON ab.id = pp.current_building_id
|
||||
WHERE ab.airport_id = ?
|
||||
AND b.operation_type = ? -- 'runway' or 'service' (service bay)
|
||||
AND b.operation_size = ? -- matches plane's aircraft_size requirement
|
||||
AND pp.id IS NULL -- Ensures no other plane is physically here right now
|
||||
LIMIT 1;
|
||||
|
||||
-- name: UpdatePlaneState :exec
|
||||
UPDATE player_planes
|
||||
SET current_building_id = ?,
|
||||
status = ?,
|
||||
|
||||
flight_start_time = ?
|
||||
WHERE id = ?;
|
||||
|
||||
-- name: CheckHangarOccupancy :one
|
||||
SELECT COUNT(*) AS total_parked
|
||||
FROM player_planes
|
||||
WHERE current_building_id = ?;
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- 6. TIME-BASED FLIGHT ENGINE
|
||||
-- ============================================================================
|
||||
|
||||
-- name: GetPlanesReadyToLand :many
|
||||
SELECT pp.id AS player_plane_id, pp.airport_id, pp.assigned_hangar_id,
|
||||
p.completed_flight_experience, p.completed_flight_cash_reward, p.completed_flight_cargo_reward, p.operation_type
|
||||
FROM player_planes pp
|
||||
JOIN planes p ON pp.plane_id = p.id
|
||||
WHERE pp.status = 'flying'
|
||||
AND DATE_ADD(pp.flight_start_time, INTERVAL p.travel_time_inSeconds SECOND) <= NOW();
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- 7. PROGRESSION CONTRACTS & ECONOMY LOGS
|
||||
-- ============================================================================
|
||||
|
||||
-- name: GetActiveContracts :many
|
||||
SELECT id, title, required_product_id, required_amount, current_amount_delivered, is_completed, expires_at
|
||||
FROM airport_contracts
|
||||
WHERE airport_id = ? AND is_completed = FALSE AND expires_at > NOW();
|
||||
|
||||
-- name: UpdateContractDelivery :exec
|
||||
UPDATE airport_contracts
|
||||
SET current_amount_delivered = current_amount_delivered + ?
|
||||
WHERE id = ? AND is_completed = FALSE;
|
||||
|
||||
-- name: CompleteContract :exec
|
||||
UPDATE airport_contracts
|
||||
SET is_completed = TRUE
|
||||
WHERE id = ?;
|
||||
|
||||
-- name: LogCurrencyTransaction :exec
|
||||
INSERT INTO currency_transaction_logs (airport_id, amount_changed, currency_type, reason)
|
||||
VALUES (?, ?, ?, ?);
|
||||
|
||||
-- name: LogCompletedFlightRoute :exec
|
||||
INSERT INTO completed_flight_routes_log (origin_airport_id, destination_airport_id, start_time, end_time)
|
||||
VALUES (?, ?, ?, NOW());
|
||||
|
||||
|
||||
-- name: AddRecipe :execresult
|
||||
INSERT INTO recipes (name, ingredient_1_id, ingredient_1_amount, ingredient_2_id, ingredient_2_amount, ingredient_3_id, ingredient_3_amount, product_id, yield_amount)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);
|
||||
|
||||
-- name: AddContract :execresult
|
||||
INSERT INTO airport_contracts (airport_id, title, required_product_id, required_amount, expires_at)
|
||||
VALUES (?, ?, ?, ?, ?);
|
||||
|
||||
-- name: AddCompleteBuilding :execresult
|
||||
INSERT INTO buildings (name, min_level, construction_cost_cash, building_type, capacity, storage_type, storage_subtype)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?);
|
||||
290
sql/schema.sql
Normal file
290
sql/schema.sql
Normal file
|
|
@ -0,0 +1,290 @@
|
|||
-- stages
|
||||
-- stage 0 : launch planes to country's base airport (accepts everyhing sendds nothing back)
|
||||
-- stage 1 : add NPCs and cargo planes and shop buildings.
|
||||
-- stage 2 : add player progression, building upgrades, effects and more complex recipes.
|
||||
-- stage 3 : TBD
|
||||
|
||||
|
||||
|
||||
-- good
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY AUTO_INCREMENT,
|
||||
username varchar(255) NOT NULL UNIQUE,
|
||||
password_hash TEXT NOT NULL,
|
||||
-- NPC users (central-port faction leaders) have is_npc=TRUE and an empty
|
||||
-- password_hash so they can never log in; excluded from login + user lists.
|
||||
is_npc BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at TIMESTAMP DEFAULT NULL
|
||||
);
|
||||
|
||||
-- product table act as a product identifier ie egg, milk, flour etc
|
||||
create table if not exists products (
|
||||
id smallint unsigned primary key auto_increment,
|
||||
name varchar(255) not null
|
||||
);
|
||||
|
||||
-- for stage 2 will not be used
|
||||
-- increasing speed (crafting,currency type generation etc)),
|
||||
CREATE table if not exists effects (
|
||||
id smallint unsigned primary key auto_increment,
|
||||
name varchar(255) not null
|
||||
);
|
||||
|
||||
-- used airport grouping and for contracts, each country has 3 produce they can export there will not be cap
|
||||
create table if not exists countries (
|
||||
id smallint unsigned primary key auto_increment,
|
||||
name varchar(255) not null,
|
||||
continent ENUM('void','Africa', 'Antarctica', 'Asia', 'Europe', 'North America', 'Oceania', 'South America') NOT NULL, -- universal enum
|
||||
produce_1_id smallint unsigned not null,
|
||||
produce_2_id smallint unsigned not null,
|
||||
produce_3_id smallint unsigned not null,
|
||||
foreign key (produce_1_id) references products(id),
|
||||
foreign key (produce_2_id) references products(id),
|
||||
foreign key (produce_3_id) references products(id)
|
||||
);
|
||||
|
||||
-- main table
|
||||
-- primary access table act as a player identifier, each player can only have one airport, but they can have multiple planes and buildings
|
||||
create table if not exists airports (
|
||||
id integer unsigned primary key auto_increment,
|
||||
name varchar(255) not null,
|
||||
user_id integer unique not null,
|
||||
origin_country_id smallint unsigned not null,
|
||||
-- resources
|
||||
cash bigint unsigned not null default 100,
|
||||
current_passengers INTEGER UNSIGNED NOT NULL DEFAULT 100,
|
||||
max_passenger_capacity INTEGER UNSIGNED NOT NULL DEFAULT 100,
|
||||
current_fuel INTEGER UNSIGNED NOT NULL DEFAULT 500,
|
||||
max_fuel_capacity INTEGER UNSIGNED NOT NULL DEFAULT 1000,
|
||||
-- resource generation
|
||||
fuel_generation_rate INT UNSIGNED NOT NULL DEFAULT 20,
|
||||
passenger_generation_rate INT UNSIGNED NOT NULL DEFAULT 5,
|
||||
resources_last_updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
-- progression
|
||||
is_available boolean not null default true, -- if true can be sent planes from anyone
|
||||
-- central ports are system-owned (faction NPC) airports, one per continent
|
||||
is_central boolean not null default false,
|
||||
player_level integer unsigned not null default 1,
|
||||
experience_points bigint unsigned not null default 0,
|
||||
-- per-type building caps (raised by level-gated capacity upgrades, see internal/db CapUpgradeTiers)
|
||||
storage_cap integer unsigned not null default 3,
|
||||
operation_cap integer unsigned not null default 2,
|
||||
is_deleted BOOLEAN DEFAULT FALSE,
|
||||
foreign key (origin_country_id) references countries(id),
|
||||
foreign key (user_id) references users(id),
|
||||
constraint chk_fuel_capacity CHECK (current_fuel <= max_fuel_capacity),
|
||||
constraint chk_positive_fuel CHECK (current_fuel >= 0),
|
||||
CONSTRAINT chk_passenger_capacity CHECK (current_passengers <= max_passenger_capacity),
|
||||
CONSTRAINT chk_positive_passenger CHECK (current_passengers >= 0)
|
||||
);
|
||||
|
||||
|
||||
-- one NPC faction per continent; owns that continent's central port. Lore /
|
||||
-- progression hook for later stages (major faction leaders).
|
||||
create table if not exists factions (
|
||||
id integer unsigned primary key auto_increment,
|
||||
name varchar(255) not null,
|
||||
continent ENUM('void','Africa', 'Antarctica', 'Asia', 'Europe', 'North America', 'Oceania', 'South America') NOT NULL UNIQUE,
|
||||
leader_name varchar(255) not null,
|
||||
background TEXT,
|
||||
user_id integer not null,
|
||||
central_airport_id integer unsigned not null,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
foreign key (user_id) references users(id),
|
||||
foreign key (central_airport_id) references airports(id)
|
||||
);
|
||||
|
||||
-- for stage 1, used as template for recipes.
|
||||
create table if not exists recipes (
|
||||
id integer unsigned primary key auto_increment,
|
||||
name varchar(255) not null,
|
||||
ingredient_1_id smallint unsigned ,
|
||||
ingredient_1_amount integer unsigned ,
|
||||
ingredient_2_id smallint unsigned,
|
||||
ingredient_2_amount integer unsigned ,
|
||||
ingredient_3_id smallint unsigned ,
|
||||
ingredient_3_amount integer unsigned ,
|
||||
product_id smallint unsigned not null,
|
||||
yield_amount integer unsigned not null,
|
||||
foreign key (ingredient_1_id) references products(id),
|
||||
foreign key (ingredient_2_id) references products(id),
|
||||
foreign key (ingredient_3_id) references products(id),
|
||||
foreign key (product_id) references products(id)
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- BUILDNGS
|
||||
|
||||
-- hangars fuel tanks etc
|
||||
CREATE table if not exists buildings (
|
||||
-- shared
|
||||
id integer unsigned primary key auto_increment,
|
||||
name varchar(255) not null,
|
||||
min_level integer unsigned not null DEfAULT 1,
|
||||
construction_cost_cash integer unsigned not null default 100,
|
||||
upgrade_tier TINYINT UNSIGNED DEFAULT 0,
|
||||
upgrade_cost_cash_to_uptier integer unsigned default null,
|
||||
building_type ENUM('none','storage', 'support', 'operation', 'passive', 'shop', 'production') not null default 'none',
|
||||
-- production specific
|
||||
-- storage
|
||||
capacity integer unsigned ,
|
||||
storage_type ENUM( 'fuel' , 'plane', 'product'),
|
||||
storage_subtype ENUM('none', 'airplane', 'helicopter', 'seaplane','spaceship'),
|
||||
-- support
|
||||
effect_id smallint unsigned,
|
||||
effect_value integer,
|
||||
-- operation
|
||||
operation_size enum('small','medium' ,'large', 'huge'),
|
||||
operation_type enum('runway', 'service', 'production'),
|
||||
|
||||
-- passive income
|
||||
passive_type enum('passengers', 'fuel'),
|
||||
passive_rate integer ,
|
||||
|
||||
foreign key (effect_id) references effects(id)
|
||||
|
||||
);
|
||||
|
||||
-- stage 1
|
||||
create table if not exists building_products (
|
||||
id integer unsigned primary key auto_increment,
|
||||
building_id integer unsigned not null,
|
||||
|
||||
recipe_id integer unsigned,
|
||||
storage_product integer unsigned ,
|
||||
storage_1 integer unsigned ,
|
||||
storage_2 integer unsigned ,
|
||||
storage_3 integer unsigned ,
|
||||
foreign key (building_id) references buildings(id),
|
||||
foreign key (recipe_id) references recipes(id)
|
||||
);
|
||||
|
||||
|
||||
-- many to many relation between airport and buildings
|
||||
create table if not exists airport_buildings (
|
||||
id integer unsigned primary key auto_increment,
|
||||
airport_id integer unsigned not null,
|
||||
building_id integer unsigned not null,
|
||||
-- shop specific
|
||||
recipe_id integer unsigned ,
|
||||
storage_product integer unsigned ,
|
||||
storage_1 integer unsigned ,
|
||||
storage_2 integer unsigned ,
|
||||
storage_3 integer unsigned ,
|
||||
level integer unsigned not null default 1,
|
||||
foreign key (airport_id) references airports(id) ,
|
||||
foreign key (building_id) references buildings(id)
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
-- planes
|
||||
-- template for planes
|
||||
create table if not exists planes (
|
||||
id integer unsigned primary key auto_increment,
|
||||
name varchar(255) not null,
|
||||
min_level integer unsigned not null default 1,
|
||||
operation_cost_fuel integer unsigned not null,
|
||||
operation_cost_cash integer unsigned not null DEFAULT 10,
|
||||
max_passengers integer unsigned,
|
||||
travel_time_inSeconds integer unsigned not null,
|
||||
operation_type enum('passenger', 'cargo') not null,
|
||||
aircraft_size enum('small', 'medium', 'large', 'huge') not null,
|
||||
aircraft_type enum('plane', 'helicopter', 'seaplane','spaceship') not null,
|
||||
buying_cost_cash integer unsigned not null DEFAULT 100,
|
||||
completed_flight_experience integer unsigned not null DEFAULT 20,
|
||||
completed_flight_cash_reward integer unsigned DEFAULT 50,
|
||||
completed_flight_cargo_reward integer unsigned DEFAULT null,
|
||||
boarding_time_seconds integer unsigned not null DEFAULT 0,
|
||||
fueling_time_seconds integer unsigned not null DEFAULT 0
|
||||
|
||||
);
|
||||
|
||||
-- actual planes owned by players, tracks location, status, assigned hangar etc
|
||||
CREATE TABLE IF NOT EXISTS player_planes (
|
||||
id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
|
||||
airport_id INT UNSIGNED NOT NULL,
|
||||
plane_id INTEGER UNSIGNED NOT NULL,
|
||||
|
||||
-- 1. assignment (Must always point to a hangar they own they move between suitable hangars)
|
||||
assigned_hangar_id INT UNSIGNED NOT NULL,
|
||||
|
||||
-- 2. Real-time physical location (stored, Service Bay, Runway, or NULL if flying)
|
||||
current_building_id INT UNSIGNED DEFAULT NULL,
|
||||
-- assigned_cargo_id INTEGER UNSIGNED DEFAULT NULL, -- stage 1 For cargo planes, track what they're carrying
|
||||
|
||||
status ENUM('idle', 'maintenance', 'boarding', 'taxiing', 'flying', 'unloading') NOT NULL DEFAULT 'idle',
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
-- fixed at purchase (no ON UPDATE) so the 5-min full-refund sell window is reliable
|
||||
purchased_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
flight_start_time TIMESTAMP NULL DEFAULT NULL,
|
||||
-- where a dispatched plane is flying to (a central port); NULL when idle/home
|
||||
destination_airport_id INT UNSIGNED DEFAULT NULL,
|
||||
|
||||
|
||||
FOREIGN KEY (airport_id) REFERENCES airports(id),
|
||||
FOREIGN KEY (plane_id) REFERENCES planes(id),
|
||||
FOREIGN KEY (assigned_hangar_id) REFERENCES airport_buildings(id),
|
||||
FOREIGN KEY (current_building_id) REFERENCES airport_buildings(id),
|
||||
FOREIGN KEY (destination_airport_id) REFERENCES airports(id)
|
||||
|
||||
);
|
||||
|
||||
-- stage 1
|
||||
CREATE TABLE IF NOT EXISTS airport_inventory (
|
||||
airport_id INTEGER unsigned NOT NULL,
|
||||
product_id SMALLINT UNSIGNED NOT NULL,
|
||||
quantity INTEGER UNSIGNED NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (airport_id, product_id),
|
||||
FOREIGN KEY (airport_id) REFERENCES airports(id),
|
||||
FOREIGN KEY (product_id) REFERENCES products(id)
|
||||
);
|
||||
|
||||
|
||||
-- stage ? tbd
|
||||
CREATE TABLE IF NOT EXISTS airport_contracts (
|
||||
id INTEGER UNSIGNED PRIMARY KEY AUTO_INCREMENT,
|
||||
airport_id INTEGER unsigned NOT NULL,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
|
||||
-- What they need to deliver
|
||||
required_product_id SMALLINT UNSIGNED NOT NULL,
|
||||
required_amount INTEGER UNSIGNED NOT NULL,
|
||||
current_amount_delivered INTEGER UNSIGNED NOT NULL DEFAULT 0,
|
||||
|
||||
|
||||
-- Status
|
||||
is_completed BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
|
||||
FOREIGN KEY (airport_id) REFERENCES airports(id),
|
||||
FOREIGN KEY (required_product_id) REFERENCES products(id)
|
||||
|
||||
);
|
||||
|
||||
|
||||
-- logs
|
||||
|
||||
create table if not exists completed_flight_routes_log (
|
||||
id integer unsigned primary key auto_increment,
|
||||
origin_airport_id integer unsigned not null,
|
||||
destination_airport_id integer unsigned not null,
|
||||
start_time timestamp not null default current_timestamp,
|
||||
end_time timestamp default null,
|
||||
foreign key (origin_airport_id) references airports(id),
|
||||
foreign key (destination_airport_id) references airports(id)
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS currency_transaction_logs (
|
||||
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
|
||||
airport_id INT UNSIGNED NOT NULL,
|
||||
amount_changed INT NOT NULL, -- Negative for buying, positive for earning
|
||||
currency_type ENUM('cash', 'fuel', 'passengers') NOT NULL,
|
||||
reason VARCHAR(255) NOT NULL, -- e.g., 'bought_plane_id_12', 'completed_flight_34'
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (airport_id) REFERENCES airports(id)
|
||||
);
|
||||
177
sql/seed_factions.sql
Normal file
177
sql/seed_factions.sql
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
-- Seed: central ports + NPC faction leaders (one per continent).
|
||||
-- Run ONCE, after migration 004_central_dispatch.sql, against skyrama_clone.
|
||||
-- Idempotent: every statement is guarded by WHERE NOT EXISTS, so re-running is a
|
||||
-- no-op. Order per continent: product -> hub country -> NPC user -> central
|
||||
-- airport -> faction. (Replaces the old Go Client.EnsureStage0World.)
|
||||
|
||||
-- Placeholder product so hub countries have a produce FK to point at.
|
||||
INSERT INTO products (name) SELECT 'Misc Cargo'
|
||||
WHERE NOT EXISTS (SELECT 1 FROM products);
|
||||
|
||||
-- ─── void → Orbital Concord / Cmdr. Vega Solaris ───────────────────────────────
|
||||
INSERT INTO countries (name,continent,produce_1_id,produce_2_id,produce_3_id)
|
||||
SELECT 'void Hub','void', p.id, p.id, p.id
|
||||
FROM (SELECT id FROM products ORDER BY id LIMIT 1) p
|
||||
WHERE NOT EXISTS (SELECT 1 FROM countries WHERE continent='void');
|
||||
INSERT INTO users (username,password_hash,is_npc)
|
||||
SELECT 'vega_solaris','',TRUE
|
||||
WHERE NOT EXISTS (SELECT 1 FROM users WHERE username='vega_solaris');
|
||||
INSERT INTO airports (name,user_id,origin_country_id,is_central)
|
||||
SELECT 'Orbital Spaceport', u.id, c.id, TRUE
|
||||
FROM (SELECT id FROM users WHERE username='vega_solaris') u,
|
||||
(SELECT id FROM countries WHERE continent='void' ORDER BY id LIMIT 1) c
|
||||
WHERE NOT EXISTS (SELECT 1 FROM airports WHERE user_id=(SELECT id FROM users WHERE username='vega_solaris'));
|
||||
INSERT INTO factions (name,continent,leader_name,background,user_id,central_airport_id)
|
||||
SELECT 'Orbital Concord','void','Cmdr. Vega Solaris',
|
||||
'Runs the only spaceport beyond the sky and keeps the orbital lanes clear for every flag.',
|
||||
u.id, a.id
|
||||
FROM (SELECT id FROM users WHERE username='vega_solaris') u,
|
||||
(SELECT id FROM airports WHERE user_id=(SELECT id FROM users WHERE username='vega_solaris')) a
|
||||
WHERE NOT EXISTS (SELECT 1 FROM factions WHERE continent='void');
|
||||
|
||||
-- ─── Africa → Savannah Pact / Amara Okonkwo ────────────────────────────────────
|
||||
INSERT INTO countries (name,continent,produce_1_id,produce_2_id,produce_3_id)
|
||||
SELECT 'Africa Hub','Africa', p.id, p.id, p.id
|
||||
FROM (SELECT id FROM products ORDER BY id LIMIT 1) p
|
||||
WHERE NOT EXISTS (SELECT 1 FROM countries WHERE continent='Africa');
|
||||
INSERT INTO users (username,password_hash,is_npc)
|
||||
SELECT 'amara_okonkwo','',TRUE
|
||||
WHERE NOT EXISTS (SELECT 1 FROM users WHERE username='amara_okonkwo');
|
||||
INSERT INTO airports (name,user_id,origin_country_id,is_central)
|
||||
SELECT 'Africa Central', u.id, c.id, TRUE
|
||||
FROM (SELECT id FROM users WHERE username='amara_okonkwo') u,
|
||||
(SELECT id FROM countries WHERE continent='Africa' ORDER BY id LIMIT 1) c
|
||||
WHERE NOT EXISTS (SELECT 1 FROM airports WHERE user_id=(SELECT id FROM users WHERE username='amara_okonkwo'));
|
||||
INSERT INTO factions (name,continent,leader_name,background,user_id,central_airport_id)
|
||||
SELECT 'Savannah Pact','Africa','Amara Okonkwo',
|
||||
'Unites the continent''s scattered bush-strip airfields under a single banner.',
|
||||
u.id, a.id
|
||||
FROM (SELECT id FROM users WHERE username='amara_okonkwo') u,
|
||||
(SELECT id FROM airports WHERE user_id=(SELECT id FROM users WHERE username='amara_okonkwo')) a
|
||||
WHERE NOT EXISTS (SELECT 1 FROM factions WHERE continent='Africa');
|
||||
|
||||
-- ─── Antarctica → Polar Frontier / Dr. Erik Frost ──────────────────────────────
|
||||
INSERT INTO countries (name,continent,produce_1_id,produce_2_id,produce_3_id)
|
||||
SELECT 'Antarctica Hub','Antarctica', p.id, p.id, p.id
|
||||
FROM (SELECT id FROM products ORDER BY id LIMIT 1) p
|
||||
WHERE NOT EXISTS (SELECT 1 FROM countries WHERE continent='Antarctica');
|
||||
INSERT INTO users (username,password_hash,is_npc)
|
||||
SELECT 'erik_frost','',TRUE
|
||||
WHERE NOT EXISTS (SELECT 1 FROM users WHERE username='erik_frost');
|
||||
INSERT INTO airports (name,user_id,origin_country_id,is_central)
|
||||
SELECT 'Antarctica Central', u.id, c.id, TRUE
|
||||
FROM (SELECT id FROM users WHERE username='erik_frost') u,
|
||||
(SELECT id FROM countries WHERE continent='Antarctica' ORDER BY id LIMIT 1) c
|
||||
WHERE NOT EXISTS (SELECT 1 FROM airports WHERE user_id=(SELECT id FROM users WHERE username='erik_frost'));
|
||||
INSERT INTO factions (name,continent,leader_name,background,user_id,central_airport_id)
|
||||
SELECT 'Polar Frontier','Antarctica','Dr. Erik Frost',
|
||||
'Keeps the ice runways open against the harshest weather on Earth.',
|
||||
u.id, a.id
|
||||
FROM (SELECT id FROM users WHERE username='erik_frost') u,
|
||||
(SELECT id FROM airports WHERE user_id=(SELECT id FROM users WHERE username='erik_frost')) a
|
||||
WHERE NOT EXISTS (SELECT 1 FROM factions WHERE continent='Antarctica');
|
||||
|
||||
-- ─── Asia → Monsoon Alliance / Mei-Lin Zhao ────────────────────────────────────
|
||||
INSERT INTO countries (name,continent,produce_1_id,produce_2_id,produce_3_id)
|
||||
SELECT 'Asia Hub','Asia', p.id, p.id, p.id
|
||||
FROM (SELECT id FROM products ORDER BY id LIMIT 1) p
|
||||
WHERE NOT EXISTS (SELECT 1 FROM countries WHERE continent='Asia');
|
||||
INSERT INTO users (username,password_hash,is_npc)
|
||||
SELECT 'meilin_zhao','',TRUE
|
||||
WHERE NOT EXISTS (SELECT 1 FROM users WHERE username='meilin_zhao');
|
||||
INSERT INTO airports (name,user_id,origin_country_id,is_central)
|
||||
SELECT 'Asia Central', u.id, c.id, TRUE
|
||||
FROM (SELECT id FROM users WHERE username='meilin_zhao') u,
|
||||
(SELECT id FROM countries WHERE continent='Asia' ORDER BY id LIMIT 1) c
|
||||
WHERE NOT EXISTS (SELECT 1 FROM airports WHERE user_id=(SELECT id FROM users WHERE username='meilin_zhao'));
|
||||
INSERT INTO factions (name,continent,leader_name,background,user_id,central_airport_id)
|
||||
SELECT 'Monsoon Alliance','Asia','Mei-Lin Zhao',
|
||||
'Commands the busiest and most fiercely contested skies on the planet.',
|
||||
u.id, a.id
|
||||
FROM (SELECT id FROM users WHERE username='meilin_zhao') u,
|
||||
(SELECT id FROM airports WHERE user_id=(SELECT id FROM users WHERE username='meilin_zhao')) a
|
||||
WHERE NOT EXISTS (SELECT 1 FROM factions WHERE continent='Asia');
|
||||
|
||||
-- ─── Europe → Continental Union / Lars Vandenberg ──────────────────────────────
|
||||
INSERT INTO countries (name,continent,produce_1_id,produce_2_id,produce_3_id)
|
||||
SELECT 'Europe Hub','Europe', p.id, p.id, p.id
|
||||
FROM (SELECT id FROM products ORDER BY id LIMIT 1) p
|
||||
WHERE NOT EXISTS (SELECT 1 FROM countries WHERE continent='Europe');
|
||||
INSERT INTO users (username,password_hash,is_npc)
|
||||
SELECT 'lars_vandenberg','',TRUE
|
||||
WHERE NOT EXISTS (SELECT 1 FROM users WHERE username='lars_vandenberg');
|
||||
INSERT INTO airports (name,user_id,origin_country_id,is_central)
|
||||
SELECT 'Europe Central', u.id, c.id, TRUE
|
||||
FROM (SELECT id FROM users WHERE username='lars_vandenberg') u,
|
||||
(SELECT id FROM countries WHERE continent='Europe' ORDER BY id LIMIT 1) c
|
||||
WHERE NOT EXISTS (SELECT 1 FROM airports WHERE user_id=(SELECT id FROM users WHERE username='lars_vandenberg'));
|
||||
INSERT INTO factions (name,continent,leader_name,background,user_id,central_airport_id)
|
||||
SELECT 'Continental Union','Europe','Lars Vandenberg',
|
||||
'Old-money hub baron who controls the western air corridors.',
|
||||
u.id, a.id
|
||||
FROM (SELECT id FROM users WHERE username='lars_vandenberg') u,
|
||||
(SELECT id FROM airports WHERE user_id=(SELECT id FROM users WHERE username='lars_vandenberg')) a
|
||||
WHERE NOT EXISTS (SELECT 1 FROM factions WHERE continent='Europe');
|
||||
|
||||
-- ─── North America → Liberty Air Coalition / Jack Sullivan ─────────────────────
|
||||
INSERT INTO countries (name,continent,produce_1_id,produce_2_id,produce_3_id)
|
||||
SELECT 'North America Hub','North America', p.id, p.id, p.id
|
||||
FROM (SELECT id FROM products ORDER BY id LIMIT 1) p
|
||||
WHERE NOT EXISTS (SELECT 1 FROM countries WHERE continent='North America');
|
||||
INSERT INTO users (username,password_hash,is_npc)
|
||||
SELECT 'jack_sullivan','',TRUE
|
||||
WHERE NOT EXISTS (SELECT 1 FROM users WHERE username='jack_sullivan');
|
||||
INSERT INTO airports (name,user_id,origin_country_id,is_central)
|
||||
SELECT 'North America Central', u.id, c.id, TRUE
|
||||
FROM (SELECT id FROM users WHERE username='jack_sullivan') u,
|
||||
(SELECT id FROM countries WHERE continent='North America' ORDER BY id LIMIT 1) c
|
||||
WHERE NOT EXISTS (SELECT 1 FROM airports WHERE user_id=(SELECT id FROM users WHERE username='jack_sullivan'));
|
||||
INSERT INTO factions (name,continent,leader_name,background,user_id,central_airport_id)
|
||||
SELECT 'Liberty Air Coalition','North America','Jack Sullivan',
|
||||
'Brash operator of the great transcontinental gateways.',
|
||||
u.id, a.id
|
||||
FROM (SELECT id FROM users WHERE username='jack_sullivan') u,
|
||||
(SELECT id FROM airports WHERE user_id=(SELECT id FROM users WHERE username='jack_sullivan')) a
|
||||
WHERE NOT EXISTS (SELECT 1 FROM factions WHERE continent='North America');
|
||||
|
||||
-- ─── Oceania → Coral Compass / Talia Reef ──────────────────────────────────────
|
||||
INSERT INTO countries (name,continent,produce_1_id,produce_2_id,produce_3_id)
|
||||
SELECT 'Oceania Hub','Oceania', p.id, p.id, p.id
|
||||
FROM (SELECT id FROM products ORDER BY id LIMIT 1) p
|
||||
WHERE NOT EXISTS (SELECT 1 FROM countries WHERE continent='Oceania');
|
||||
INSERT INTO users (username,password_hash,is_npc)
|
||||
SELECT 'talia_reef','',TRUE
|
||||
WHERE NOT EXISTS (SELECT 1 FROM users WHERE username='talia_reef');
|
||||
INSERT INTO airports (name,user_id,origin_country_id,is_central)
|
||||
SELECT 'Oceania Central', u.id, c.id, TRUE
|
||||
FROM (SELECT id FROM users WHERE username='talia_reef') u,
|
||||
(SELECT id FROM countries WHERE continent='Oceania' ORDER BY id LIMIT 1) c
|
||||
WHERE NOT EXISTS (SELECT 1 FROM airports WHERE user_id=(SELECT id FROM users WHERE username='talia_reef'));
|
||||
INSERT INTO factions (name,continent,leader_name,background,user_id,central_airport_id)
|
||||
SELECT 'Coral Compass','Oceania','Talia Reef',
|
||||
'Island-hopping seaplane magnate of the southern seas.',
|
||||
u.id, a.id
|
||||
FROM (SELECT id FROM users WHERE username='talia_reef') u,
|
||||
(SELECT id FROM airports WHERE user_id=(SELECT id FROM users WHERE username='talia_reef')) a
|
||||
WHERE NOT EXISTS (SELECT 1 FROM factions WHERE continent='Oceania');
|
||||
|
||||
-- ─── South America → Andean Wings / Mateo Rivera ───────────────────────────────
|
||||
INSERT INTO countries (name,continent,produce_1_id,produce_2_id,produce_3_id)
|
||||
SELECT 'South America Hub','South America', p.id, p.id, p.id
|
||||
FROM (SELECT id FROM products ORDER BY id LIMIT 1) p
|
||||
WHERE NOT EXISTS (SELECT 1 FROM countries WHERE continent='South America');
|
||||
INSERT INTO users (username,password_hash,is_npc)
|
||||
SELECT 'mateo_rivera','',TRUE
|
||||
WHERE NOT EXISTS (SELECT 1 FROM users WHERE username='mateo_rivera');
|
||||
INSERT INTO airports (name,user_id,origin_country_id,is_central)
|
||||
SELECT 'South America Central', u.id, c.id, TRUE
|
||||
FROM (SELECT id FROM users WHERE username='mateo_rivera') u,
|
||||
(SELECT id FROM countries WHERE continent='South America' ORDER BY id LIMIT 1) c
|
||||
WHERE NOT EXISTS (SELECT 1 FROM airports WHERE user_id=(SELECT id FROM users WHERE username='mateo_rivera'));
|
||||
INSERT INTO factions (name,continent,leader_name,background,user_id,central_airport_id)
|
||||
SELECT 'Andean Wings','South America','Mateo Rivera',
|
||||
'Flies the high mountain passes that nobody else dares.',
|
||||
u.id, a.id
|
||||
FROM (SELECT id FROM users WHERE username='mateo_rivera') u,
|
||||
(SELECT id FROM airports WHERE user_id=(SELECT id FROM users WHERE username='mateo_rivera')) a
|
||||
WHERE NOT EXISTS (SELECT 1 FROM factions WHERE continent='South America');
|
||||
Loading…
Add table
Add a link
Reference in a new issue