278 lines
7.3 KiB
JavaScript
278 lines
7.3 KiB
JavaScript
// Unit archetypes. `military` units fight, capture cities and may enter an
|
|
// enemy military unit's tile. `attack` is the damage dealt per combat round and
|
|
// `defense` the damage absorbed per round; a defender's defense is doubled (the
|
|
// 100% defensive bonus). `range` is how many tiles away the unit can strike
|
|
// (1 is melee).
|
|
|
|
export const PROTO_UNITS = [
|
|
{
|
|
id: "modern_infantry",
|
|
population: 1_000,
|
|
name: "Modern infantry",
|
|
maxHp: 500,
|
|
cost: 100_000_000,
|
|
moveable: true,
|
|
speed: 0.5,
|
|
military: true,
|
|
// Marks the unit for the infantry research effects (weapons, body armour).
|
|
infantry: true,
|
|
attack: 100,
|
|
defense: 40,
|
|
range: 1,
|
|
requiresBuilding: "barracks",
|
|
traversableTerrains: ["Land"],
|
|
icon: "icon_modern_infantry.svg",
|
|
},
|
|
{
|
|
id: "worker",
|
|
name: "Worker",
|
|
maxHp: 100,
|
|
cost: 0,
|
|
moveable: true,
|
|
speed: 0.5,
|
|
military: false,
|
|
attack: 0,
|
|
defense: 0,
|
|
range: 1,
|
|
traversableTerrains: ["Land"],
|
|
icon: "icon_settler.svg",
|
|
},
|
|
{
|
|
id: "artillery",
|
|
materialUpkeep: { steel: 2, energy: 2000, hightech: 0 },
|
|
name: "Artillery",
|
|
maxHp: 400,
|
|
cost: 300_000_000,
|
|
moveable: true,
|
|
speed: 0.25,
|
|
military: true,
|
|
// Marks the unit for the artillery research effect.
|
|
artillery: true,
|
|
attack: 250,
|
|
// Barely armoured: nearly every hit gets through.
|
|
defense: 5,
|
|
// Outranges infantry, so melee units cannot strike back from two tiles.
|
|
range: 2,
|
|
traversableTerrains: ["Land"],
|
|
icon: "icon_artillery.svg",
|
|
},
|
|
{
|
|
id: "jet_fighter",
|
|
materialUpkeep: { steel: 5, energy: 5000, hightech: 1 },
|
|
advanced: true,
|
|
name: "Jet fighter",
|
|
maxHp: 300,
|
|
cost: 400_000_000,
|
|
moveable: true,
|
|
speed: 5,
|
|
military: true,
|
|
attack: 300,
|
|
defense: 20,
|
|
range: 1,
|
|
traversableTerrains: ["Land", "Sea", "Ice"],
|
|
// Aircraft only operate near a friendly airport: `enduranceHours` is how
|
|
// long they may stay aloft and `missionRange` the furthest they may be
|
|
// ordered from home. Both are per-type so a future plane can differ. The
|
|
// fighter's 25-tile strike reach needs ten hours aloft for the round trip;
|
|
// `missionRange` is the looser ceiling.
|
|
air: true,
|
|
enduranceHours: 10,
|
|
missionRange: 80,
|
|
requiresBuilding: "airport",
|
|
icon: "icon_jet_fighter.svg",
|
|
},
|
|
{
|
|
id: "bomber",
|
|
materialUpkeep: { steel: 8, energy: 8000, hightech: 2 },
|
|
advanced: true,
|
|
name: "Bomber",
|
|
maxHp: 350,
|
|
cost: 500_000_000,
|
|
moveable: true,
|
|
speed: 5,
|
|
military: true,
|
|
attack: 450,
|
|
defense: 10,
|
|
// A bomber strikes from `range` tiles away and never joins the melee.
|
|
range: 0,
|
|
traversableTerrains: ["Land", "Sea", "Ice"],
|
|
// The bomber's 50-tile strike reach needs twenty hours aloft for the round
|
|
// trip; `missionRange` is the looser ceiling.
|
|
air: true,
|
|
enduranceHours: 20,
|
|
missionRange: 100,
|
|
strike: true,
|
|
requiresBuilding: "airport",
|
|
icon: "icon_bomber.svg",
|
|
},
|
|
{
|
|
id: "battleship",
|
|
advanced: true,
|
|
name: "Battleship",
|
|
maxHp: 800,
|
|
cost: 600_000_000,
|
|
moveable: true,
|
|
speed: 0.5,
|
|
military: true,
|
|
attack: 400,
|
|
defense: 120,
|
|
range: 2,
|
|
naval: true,
|
|
traversableTerrains: ["Sea"],
|
|
requiresBuilding: "shipyard",
|
|
icon: "icon_battleship.svg",
|
|
},
|
|
{
|
|
id: "submarine",
|
|
advanced: true,
|
|
materialUpkeep: { steel: 4, energy: 4000, hightech: 1 },
|
|
name: "Submarine",
|
|
maxHp: 400,
|
|
cost: 350_000_000,
|
|
moveable: true,
|
|
speed: 0.5,
|
|
military: true,
|
|
attack: 350,
|
|
defense: 60,
|
|
// Strikes from two tiles out like a warship.
|
|
range: 2,
|
|
naval: true,
|
|
// Hidden from every other nation unless one of its naval units is on the
|
|
// submarine's tile or directly beside it (see `_hiddenEnemyUnits`).
|
|
submarine: true,
|
|
traversableTerrains: ["Sea"],
|
|
requiresBuilding: "shipyard",
|
|
icon: "icon_submarine.svg",
|
|
},
|
|
{
|
|
id: "mobile_radar",
|
|
advanced: true,
|
|
name: "Mobile radar",
|
|
maxHp: 200,
|
|
cost: 50_000_000,
|
|
moveable: true,
|
|
speed: 0.5,
|
|
military: false,
|
|
attack: 0,
|
|
defense: 0,
|
|
range: 0,
|
|
// Watches four tiles out, cannot fight, is taken by any unit that walks
|
|
// onto it, and a lone one is destroyed outright by a single ranged hit.
|
|
vision: 4,
|
|
capturable: true,
|
|
destroyedByRangedAlone: true,
|
|
traversableTerrains: ["Land"],
|
|
icon: "icon_radar.svg",
|
|
},
|
|
{
|
|
id: "spy",
|
|
advanced: true,
|
|
name: "Spy",
|
|
maxHp: 100,
|
|
cost: 250_000_000,
|
|
// Mostly a high-tech bill: a spy is equipment and networks, not steel.
|
|
materialUpkeep: { steel: 0, energy: 2_000, hightech: 3 },
|
|
moveable: true,
|
|
speed: 0.5,
|
|
military: false,
|
|
attack: 0,
|
|
defense: 0,
|
|
// A spy fights nothing and strikes nothing; it watches one tile out.
|
|
range: 0,
|
|
vision: 1,
|
|
// Hidden from every other nation by default (see `_hiddenEnemyUnits`), and
|
|
// free to slip through foreign territory (see `_canUnitEnter`).
|
|
spy: true,
|
|
traversableTerrains: ["Land"],
|
|
requiresTechnology: "intelligence_agencies",
|
|
icon: "icon_spy.svg",
|
|
},
|
|
{
|
|
id: "launch",
|
|
name: "Launch",
|
|
maxHp: 150,
|
|
cost: 20_000_000,
|
|
moveable: true,
|
|
speed: 0.5,
|
|
military: false,
|
|
attack: 0,
|
|
defense: 0,
|
|
range: 0,
|
|
// Transports one infantry unit and is defenceless on its own.
|
|
transportCapacity: 1,
|
|
transportKind: "infantry",
|
|
capturable: true,
|
|
naval: true,
|
|
traversableTerrains: ["Sea"],
|
|
requiresBuilding: "port",
|
|
icon: "icon_launch.svg",
|
|
},
|
|
{
|
|
id: "missile",
|
|
name: "Missile",
|
|
maxHp: 100,
|
|
cost: 150_000_000,
|
|
materialUpkeep: { steel: 2, energy: 2000, hightech: 1 },
|
|
// Missiles are fired, not marched: `moveable: false` keeps them out of every
|
|
// movement order, and `oneUse` means the rocket is gone once launched.
|
|
moveable: false,
|
|
oneUse: true,
|
|
speed: 10,
|
|
military: true,
|
|
attack: 900,
|
|
defense: 0,
|
|
// An intercontinental ballistic missile of the theatre: 30 tiles of reach.
|
|
range: 30,
|
|
// A missile flies like a strike aircraft but needs no airfield; a nuclear
|
|
// payload additionally needs the nuclear-weapons research.
|
|
strike: true,
|
|
missile: true,
|
|
traversableTerrains: ["Land", "Sea", "Ice"],
|
|
icon: "icon_missile.svg",
|
|
},
|
|
{
|
|
id: "icbm",
|
|
name: "ICBM",
|
|
maxHp: 100,
|
|
cost: 800_000_000,
|
|
materialUpkeep: { steel: 4, energy: 4000, hightech: 2 },
|
|
moveable: false,
|
|
oneUse: true,
|
|
speed: 10,
|
|
military: true,
|
|
attack: 900,
|
|
defense: 0,
|
|
// A global rocket: `globalRange` lifts the 30-tile ceiling so it may be
|
|
// aimed at any tile on the map.
|
|
range: 0,
|
|
globalRange: true,
|
|
strike: true,
|
|
missile: true,
|
|
// Nuclear by design, and gated behind both the bomb and the orbit that
|
|
// carries it.
|
|
nuclear: true,
|
|
requiresTechnologies: ["nuclear_weapons", "space_program"],
|
|
traversableTerrains: ["Land", "Sea", "Ice"],
|
|
icon: "icon_icbm.svg",
|
|
},
|
|
];
|
|
|
|
// Only units in this list can be trained from the city screen.
|
|
export const TRAINABLE_UNIT_IDS = [
|
|
"modern_infantry",
|
|
"artillery",
|
|
"jet_fighter",
|
|
"bomber",
|
|
"battleship",
|
|
"submarine",
|
|
"mobile_radar",
|
|
"spy",
|
|
"launch",
|
|
"missile",
|
|
"icbm",
|
|
];
|
|
|
|
export function protoUnitById(id) {
|
|
return PROTO_UNITS.find((u) => u.id === id) || null;
|
|
}
|