summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data.js2
-rw-r--r--play.js1
-rw-r--r--rules.js343
-rw-r--r--tools/gendata.js82
4 files changed, 381 insertions, 47 deletions
diff --git a/data.js b/data.js
index bdf3c4a..ca1dcbf 100644
--- a/data.js
+++ b/data.js
@@ -1,2 +1,2 @@
-const data = {"areas":[{"name":"Oran","type":1,"zone":"V","x":430.6,"y":588.8},{"name":"Algiers","type":1,"zone":"IV","x":1185.6,"y":346.8},{"name":"Constantine","type":1,"zone":"II","x":2066.6,"y":315.8},{"name":"France","type":3,"zone":null,"x":1605,"y":185.3,"w":266,"h":212.4},{"name":"Morocco","type":3,"zone":null,"x":109,"y":1765,"w":94,"h":94},{"name":"Tunisia","type":3,"zone":null,"x":2499.9,"y":1667.6,"w":94,"h":94},{"name":"Barika","type":0,"zone":"I","x":1708.1,"y":1117.9},{"name":"Batna","type":2,"zone":"I","x":2185.6,"y":1390.9},{"name":"Biskra","type":2,"zone":"I","x":1853.6,"y":1620.9},{"name":"Tebessa","type":0,"zone":"I","x":2299.6,"y":1120.9},{"name":"Setif","type":0,"zone":"II","x":1917.6,"y":800.8},{"name":"Souk Ahras","type":0,"zone":"II","x":2347.6,"y":848.9},{"name":"Phillippeville","type":0,"zone":"II","x":2200.6,"y":584.9},{"name":"Tizi Ouzou","type":0,"zone":"III","x":1473.6,"y":578.9},{"name":"Bordj Bou Arreridj","type":0,"zone":"III","x":1465.6,"y":832.9},{"name":"Bougie","type":0,"zone":"III","x":1703.6,"y":616.9},{"name":"Medea","type":0,"zone":"IV","x":1212,"y":727},{"name":"Orleansville","type":0,"zone":"IV","x":982,"y":780.2},{"name":"Mecheria","type":2,"zone":"V","x":234,"y":1485.7},{"name":"Tlemcen","type":0,"zone":"V","x":173,"y":1140.9},{"name":"Sidi Bel Abbes","type":0,"zone":"V","x":476,"y":1038},{"name":"Mostaganem","type":0,"zone":"V","x":741,"y":863.9},{"name":"Saida","type":2,"zone":"V","x":501,"y":1419.1},{"name":"Mascara","type":2,"zone":"V","x":785,"y":1302.9},{"name":"Ain Sefra","type":2,"zone":"V","x":752,"y":1670.9},{"name":"Laghouat","type":2,"zone":"V","x":1191,"y":1615.6},{"name":"Sidi Aissa","type":2,"zone":"VI","x":1385,"y":1186},{"name":"Ain Qussera","type":0,"zone":"VI","x":1070.6,"y":1235.6}],"zones":{"V":["Oran","Mecheria","Tlemcen","Sidi Bel Abbes","Mostaganem","Saida","Mascara","Ain Sefra","Laghouat"],"IV":["Algiers","Medea","Orleansville"],"II":["Constantine","Setif","Souk Ahras","Phillippeville"],"I":["Barika","Batna","Biskra","Tebessa"],"III":["Tizi Ouzou","Bordj Bou Arreridj","Bougie"],"VI":["Sidi Aissa","Ain Qussera"]}}
+const data = {"areas":[{"id":12,"name":"Oran","type":1,"zone":"V","x":430.6,"y":588.8},{"id":13,"name":"Algiers","type":1,"zone":"IV","x":1185.6,"y":346.8},{"id":14,"name":"Constantine","type":1,"zone":"II","x":2066.6,"y":315.8},{"id":9,"name":"France","type":3,"zone":null,"x":1605,"y":185.3,"w":266,"h":212.4},{"id":10,"name":"Morocco","type":3,"zone":null,"x":109,"y":1765,"w":94,"h":94},{"id":11,"name":"Tunisia","type":3,"zone":null,"x":2499.9,"y":1667.6,"w":94,"h":94},{"id":15,"name":"Barika","type":0,"zone":"I","x":1708.1,"y":1117.9},{"id":16,"name":"Batna","type":2,"zone":"I","x":2185.6,"y":1390.9},{"id":17,"name":"Biskra","type":2,"zone":"I","x":1853.6,"y":1620.9},{"id":18,"name":"Tebessa","type":0,"zone":"I","x":2299.6,"y":1120.9},{"id":19,"name":"Setif","type":0,"zone":"II","x":1917.6,"y":800.8},{"id":20,"name":"Souk Ahras","type":0,"zone":"II","x":2347.6,"y":848.9},{"id":21,"name":"Phillippeville","type":0,"zone":"II","x":2200.6,"y":584.9},{"id":22,"name":"Tizi Ouzou","type":0,"zone":"III","x":1473.6,"y":578.9},{"id":23,"name":"Bordj Bou Arreridj","type":0,"zone":"III","x":1465.6,"y":832.9},{"id":24,"name":"Bougie","type":0,"zone":"III","x":1703.6,"y":616.9},{"id":25,"name":"Medea","type":0,"zone":"IV","x":1212,"y":727},{"id":26,"name":"Orleansville","type":0,"zone":"IV","x":982,"y":780.2},{"id":27,"name":"Mecheria","type":2,"zone":"V","x":234,"y":1485.7},{"id":28,"name":"Tlemcen","type":0,"zone":"V","x":173,"y":1140.9},{"id":29,"name":"Sidi Bel Abbes","type":0,"zone":"V","x":476,"y":1038},{"id":30,"name":"Mostaganem","type":0,"zone":"V","x":741,"y":863.9},{"id":31,"name":"Saida","type":2,"zone":"V","x":501,"y":1419.1},{"id":32,"name":"Mascara","type":2,"zone":"V","x":785,"y":1302.9},{"id":33,"name":"Ain Sefra","type":2,"zone":"V","x":752,"y":1670.9},{"id":34,"name":"Laghouat","type":2,"zone":"V","x":1191,"y":1615.6},{"id":35,"name":"Sidi Aissa","type":2,"zone":"VI","x":1385,"y":1186},{"id":36,"name":"Ain Qussera","type":0,"zone":"VI","x":1070.6,"y":1235.6}],"zones":{"V":["Oran","Mecheria","Tlemcen","Sidi Bel Abbes","Mostaganem","Saida","Mascara","Ain Sefra","Laghouat"],"IV":["Algiers","Medea","Orleansville"],"II":["Constantine","Setif","Souk Ahras","Phillippeville"],"I":["Barika","Batna","Biskra","Tebessa"],"III":["Tizi Ouzou","Bordj Bou Arreridj","Bougie"],"VI":["Sidi Aissa","Ain Qussera"]},"locations":{"DEPLOY":1,"ELIMINATED":2,"I":3,"II":4,"III":5,"IV":6,"V":7,"VI":8,"France":9,"Morocco":10,"Tunisia":11,"Oran":12,"Algiers":13,"Constantine":14,"Barika":15,"Batna":16,"Biskra":17,"Tebessa":18,"Setif":19,"Souk Ahras":20,"Phillippeville":21,"Tizi Ouzou":22,"Bordj Bou Arreridj":23,"Bougie":24,"Medea":25,"Orleansville":26,"Mecheria":27,"Tlemcen":28,"Sidi Bel Abbes":29,"Mostaganem":30,"Saida":31,"Mascara":32,"Ain Sefra":33,"Laghouat":34,"Sidi Aissa":35,"Ain Qussera":36},"units":[{"side":1,"type":0,"class":"fr_xx_2"},{"side":1,"type":0,"class":"fr_xx_4"},{"side":1,"type":0,"class":"fr_xx_9"},{"side":1,"type":0,"class":"fr_xx_12"},{"side":1,"type":0,"class":"fr_xx_13"},{"side":1,"type":0,"class":"fr_xx_14"},{"side":1,"type":0,"class":"fr_xx_19"},{"side":1,"type":0,"class":"fr_xx_20"},{"side":1,"type":0,"class":"fr_xx_21"},{"side":1,"type":0,"class":"fr_xx_29"},{"side":1,"type":0,"class":"fr_xx_27"},{"side":1,"type":0,"class":"fr_xx_25"},{"side":1,"type":0,"class":"fr_xx_7"},{"side":1,"type":1,"class":"fr_x"},{"side":1,"type":1,"class":"fr_x"},{"side":1,"type":1,"class":"fr_x"},{"side":1,"type":1,"class":"fr_x"},{"side":1,"type":2,"class":"fr_elite_x_para"},{"side":1,"type":2,"class":"fr_elite_x_para"},{"side":1,"type":2,"class":"fr_elite_x_para"},{"side":1,"type":2,"class":"fr_elite_x_inf"},{"side":1,"type":2,"class":"fr_elite_x_marine"},{"side":1,"type":2,"class":"fr_elite_x_marine"},{"side":1,"type":2,"class":"fr_elite_x_marine"},{"side":1,"type":3,"class":"alg_x"},{"side":1,"type":3,"class":"alg_x"},{"side":1,"type":3,"class":"alg_x"},{"side":1,"type":3,"class":"alg_x"},{"side":1,"type":3,"class":"alg_x"},{"side":1,"type":3,"class":"alg_x"},{"side":1,"type":4,"class":"alg_police"},{"side":1,"type":4,"class":"alg_police"},{"side":1,"type":4,"class":"alg_police"},{"side":1,"type":4,"class":"alg_police"},{"side":1,"type":4,"class":"alg_police"},{"side":1,"type":4,"class":"alg_police"},{"side":1,"type":4,"class":"alg_police"},{"side":1,"type":4,"class":"alg_police"},{"side":1,"type":4,"class":"alg_police"},{"side":1,"type":4,"class":"alg_police"},{"side":0,"type":5,"class":"fln_failek"},{"side":0,"type":5,"class":"fln_failek"},{"side":0,"type":5,"class":"fln_failek"},{"side":0,"type":5,"class":"fln_failek"},{"side":0,"type":5,"class":"fln_failek"},{"side":0,"type":5,"class":"fln_failek"},{"side":0,"type":5,"class":"fln_failek"},{"side":0,"type":5,"class":"fln_failek"},{"side":0,"type":5,"class":"fln_failek"},{"side":0,"type":5,"class":"fln_failek"},{"side":0,"type":6,"class":"fln_band"},{"side":0,"type":6,"class":"fln_band"},{"side":0,"type":6,"class":"fln_band"},{"side":0,"type":6,"class":"fln_band"},{"side":0,"type":6,"class":"fln_band"},{"side":0,"type":6,"class":"fln_band"},{"side":0,"type":6,"class":"fln_band"},{"side":0,"type":6,"class":"fln_band"},{"side":0,"type":6,"class":"fln_band"},{"side":0,"type":6,"class":"fln_band"},{"side":0,"type":6,"class":"fln_band"},{"side":0,"type":6,"class":"fln_band"},{"side":0,"type":6,"class":"fln_band"},{"side":0,"type":6,"class":"fln_band"},{"side":0,"type":6,"class":"fln_band"},{"side":0,"type":6,"class":"fln_band"},{"side":0,"type":6,"class":"fln_band"},{"side":0,"type":6,"class":"fln_band"},{"side":0,"type":6,"class":"fln_band"},{"side":0,"type":6,"class":"fln_band"},{"side":0,"type":6,"class":"fln_band"},{"side":0,"type":6,"class":"fln_band"},{"side":0,"type":6,"class":"fln_band"},{"side":0,"type":6,"class":"fln_band"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":7,"class":"fln_cadre"},{"side":0,"type":8,"class":"fln_front"},{"side":0,"type":8,"class":"fln_front"},{"side":0,"type":8,"class":"fln_front"},{"side":0,"type":8,"class":"fln_front"},{"side":0,"type":8,"class":"fln_front"},{"side":0,"type":8,"class":"fln_front"},{"side":0,"type":8,"class":"fln_front"},{"side":0,"type":8,"class":"fln_front"},{"side":0,"type":8,"class":"fln_front"},{"side":0,"type":8,"class":"fln_front"},{"side":0,"type":8,"class":"fln_front"},{"side":0,"type":8,"class":"fln_front"},{"side":0,"type":8,"class":"fln_front"},{"side":0,"type":8,"class":"fln_front"},{"side":0,"type":8,"class":"fln_front"},{"side":0,"type":8,"class":"fln_front"}]}
if (typeof module !== 'undefined') module.exports = data
diff --git a/play.js b/play.js
index 1d8e41f..463b50b 100644
--- a/play.js
+++ b/play.js
@@ -140,6 +140,7 @@ function on_update() {
for (let e of action_register)
e.classList.toggle("action", is_action(e.my_action, e.my_id))
+ action_button("end_deployment", "End deployment")
action_button("roll", "Roll")
action_button("done", "Done")
action_button("undo", "Undo")
diff --git a/rules.js b/rules.js
index 64f47c9..4a4c44b 100644
--- a/rules.js
+++ b/rules.js
@@ -4,10 +4,200 @@ const FLN = "FLN"
const GOV = "Government"
const BOTH = "Both"
+const unit_count = 120
+
+const FR_XX = 0
+const FR_X = 1
+const EL_X = 2
+const AL_X = 3
+const POL = 4
+const FAILEK = 5
+const BAND = 6
+const CADRE = 7
+const FRONT = 8
+
+// Free deployment holding box
+const DEPLOY = 1
+const ELIMINATED = 2
+
var states = {}
var game = null
var view = null
+const {
+ areas, zones, locations, units
+} = require("./data.js")
+
+// === UNIT STATE ===
+
+// location (8 bits), dispersed (1 bit), airmobile (1 bit), neutralized (1 bit)
+
+function apply_select(u) {
+ if (game.selected === u)
+ game.selected = -1
+ else
+ game.selected = u
+}
+
+function pop_selected() {
+ let u = game.selected
+ game.selected = -1
+ return u
+}
+
+const UNIT_NEUTRALIZED_SHIFT = 0
+const UNIT_NEUTRALIZED_MASK = 1 << UNIT_NEUTRALIZED_SHIFT
+
+const UNIT_AIRMOBILE_SHIFT = 1
+const UNIT_AIRMOBILE_MASK = 1 << UNIT_AIRMOBILE_SHIFT
+
+const UNIT_DISPERSED_SHIFT = 2
+const UNIT_DISPERSED_MASK = 1 << UNIT_DISPERSED_SHIFT
+
+const UNIT_LOC_SHIFT = 3
+const UNIT_LOC_MASK = 255 << UNIT_LOC_SHIFT
+
+// neutralized
+
+function is_unit_neutralized(u) {
+ return (game.units[u] & UNIT_NEUTRALIZED_MASK) === UNIT_NEUTRALIZED_MASK
+}
+
+function is_unit_not_neutralized(u) {
+ return (game.units[u] & UNIT_NEUTRALIZED_MASK) !== UNIT_NEUTRALIZED_MASK
+}
+
+function set_unit_neutralized(u) {
+ game.units[u] |= UNIT_NEUTRALIZED_MASK
+}
+
+function clear_unit_neutralized(u) {
+ game.units[u] &= ~UNIT_NEUTRALIZED_MASK
+}
+
+// location
+
+function unit_loc(u) {
+ return (game.units[u] & UNIT_LOC_MASK) >> UNIT_LOC_SHIFT
+}
+
+function set_unit_loc(u, x) {
+ game.units[u] = (game.units[u] & ~UNIT_LOC_MASK) | (x << UNIT_LOC_SHIFT)
+}
+
+// airmobile
+
+function is_unit_airmobile(u) {
+ return (game.units[u] & UNIT_AIRMOBILE_MASK) === UNIT_AIRMOBILE_MASK
+}
+
+function is_unit_not_airmobile(u) {
+ return (game.units[u] & UNIT_AIRMOBILE_MASK) !== UNIT_AIRMOBILE_MASK
+}
+
+function set_unit_airmobile(u) {
+ game.units[u] |= UNIT_AIRMOBILE_MASK
+}
+
+function clear_unit_airmobile(u) {
+ game.units[u] &= ~UNIT_AIRMOBILE_MASK
+}
+
+// dispersed
+
+function is_unit_dispersed(u) {
+ return (game.units[u] & UNIT_DISPERSED_MASK) === UNIT_DISPERSED_MASK
+}
+
+function is_unit_not_dispersed(u) {
+ return (game.units[u] & UNIT_DISPERSED_MASK) !== UNIT_DISPERSED_MASK
+}
+
+function set_unit_dispersed(u) {
+ game.units[u] |= UNIT_DISPERSED_MASK
+}
+
+function clear_unit_dispersed(u) {
+ game.units[u] &= ~UNIT_DISPERSED_MASK
+}
+
+// moved
+
+function is_unit_moved(u) {
+ return set_has(game.moved, u)
+}
+
+function set_unit_moved(u) {
+ set_add(game.moved, u)
+}
+
+// fired
+
+function is_unit_fired(u) {
+ return set_has(game.fired, u)
+}
+
+function set_unit_fired(u) {
+ set_add(game.fired, u)
+}
+
+function eliminate_unit(u) {
+ game.units[u] = 0
+ set_unit_loc(u, ELIMINATED)
+}
+
+function is_unit_eliminated(u) {
+ return unit_loc(u) === ELIMINATED
+}
+
+// === UNIT DATA ===
+
+function find_free_unit_by_type(type) {
+ for (let u = 0; u < unit_count; ++u)
+ if (!game.units[u] && units[u].type === type)
+ return u
+ throw new Error("cannot find free unit of type: " + type)
+}
+
+// function find_unit(name) {
+// for (let u = 0; u < unit_count; ++u)
+// if (unit_name[u] === name)
+// return u
+// throw new Error("cannot find named block: " + name + unit_name)
+// }
+
+// function is_axis_unit(u) {
+// return u >= first_axis_unit && u <= last_axis_unit
+// }
+
+// function is_german_unit(u) {
+// return (u >= 14 && u <= 33)
+// }
+
+// function is_elite_unit(u) {
+// return unit_elite[u]
+// }
+
+// function is_artillery_unit(u) {
+// return unit_class[u] === ARTILLERY
+// }
+
+// function unit_cv(u) {
+// if (is_elite_unit(u))
+// return unit_steps(u) * 2
+// return unit_steps(u)
+// }
+
+// function unit_hp_per_step(u) {
+// return is_elite_unit(u) ? 2 : 1
+// }
+
+// function unit_hp(u) {
+// return unit_steps(u) * unit_hp_per_step(u)
+// }
+
+// === PUBLIC FUNCTIONS ===
+
exports.scenarios = [ "1954", "1958", "1960" ]
exports.roles = [ FLN, GOV ]
@@ -18,10 +208,6 @@ function gen_action(action, argument) {
view.actions[action].push(argument)
}
-function gen_action_token(token) {
- gen_action("token", token)
-}
-
exports.action = function (state, player, action, arg) {
game = state
let S = states[game.state]
@@ -40,6 +226,19 @@ exports.view = function(state, player) {
view = {
log: game.log,
prompt: null,
+ scenario: game.scenario,
+ current: game.current,
+
+ turn: game.turn,
+ fln_ap: game.fln_ap,
+ fln_psl: game.fln_psl,
+ gov_psl: game.gov_psl,
+ gov_air: game.gov_air,
+ gov_helo: game.gov_helo,
+ gov_naval: game.gov_naval,
+
+ is_morocco_tunisia_independent: game.is_morocco_tunisia_independent,
+ border_zone: game.border_zone,
}
if (game.state === "game_over") {
@@ -62,10 +261,10 @@ exports.view = function(state, player) {
exports.resign = function (state, player) {
game = state
if (game.state !== 'game_over') {
- if (player === FLN)
+ if (player === FLN_NAME)
goto_game_over(GOV, "FLN resigned.")
if (player === GOV)
- goto_game_over(FLN, "Government resigned.")
+ goto_game_over(FLN_NAME, "Government resigned.")
}
return game
}
@@ -110,6 +309,10 @@ exports.setup = function (seed, scenario, options) {
gov_helo: 0,
gov_naval: 0,
+ units: new Array(unit_count).fill(0),
+ moved: [],
+ fired: [],
+
is_morocco_tunisia_independent: false,
border_zone: 0,
@@ -123,48 +326,102 @@ exports.setup = function (seed, scenario, options) {
}
game.scenario = scenario
- log_h1("Scenario: " + scenario)
- load_scenario(game)
+ setup_scenario(scenario)
goto_scenario_setup()
return game
}
-function load_scenario(game) {
- switch (game.scenario) {
- case "1954":
- game.gov_psl = 65
- game.gov_air = 0
- game.gov_helo = 0
- game.gov_naval = 0
- game.fln_psl = 50
- game.fln_ap = roll_2d6()
- game.is_morocco_tunisia_independent = false
- break
- case "1958":
- game.gov_psl = 50
- game.gov_air = 6
- game.gov_helo = 4
- game.gov_naval = 2
- game.fln_psl = 60
- game.fln_ap = roll_2d6()
- game.is_morocco_tunisia_independent = true
- game.border_zone = -2
- break
- case "1960":
- game.gov_psl = 45
- game.gov_air = 7
- game.gov_helo = 5
- game.gov_naval = 3
- game.fln_psl = 45
- game.fln_ap = roll_2d6()
- game.is_morocco_tunisia_independent = true
- game.border_zone = -3
- break
+const SCENARIOS = {
+ "1954": {
+ gov_psl: 65,
+ gov_air: 0,
+ gov_helo: 0,
+ gov_naval: 0,
+ fln_psl: 50,
+ is_morocco_tunisia_independent: false
+ },
+ "1958": {
+ gov_psl: 50,
+ gov_air: 6,
+ gov_helo: 4,
+ gov_naval: 2,
+ fln_psl: 60,
+ is_morocco_tunisia_independent: true,
+ border_zone: -2
+ },
+ "1960": {
+ gov_psl: 45,
+ gov_air: 7,
+ gov_helo: 5,
+ gov_naval: 3,
+ fln_psl: 45,
+ is_morocco_tunisia_independent: true,
+ border_zone: -3
+ }
+}
+
+function setup_units(where, list) {
+ let loc = locations[where]
+ for (let u of list) {
+ u = find_free_unit_by_type(u)
+ set_unit_loc(u, loc)
}
}
+const SETUP = {
+ "1954" () {
+ setup_units("I", [FRONT, CADRE])
+ setup_units("II", [FR_X, AL_X, POL])
+ setup_units("II", [FRONT, CADRE, CADRE])
+ setup_units("III", [FRONT, CADRE])
+ setup_units("IV", [FR_X, AL_X, POL])
+ setup_units("IV", [CADRE])
+ setup_units("V", [FR_X, EL_X, AL_X, POL])
+ setup_units("V", [FRONT, CADRE, CADRE])
+ },
+ "1958" () {
+ setup_units("I", [FR_XX, FR_XX, FR_X])
+ setup_units("I", [FRONT, CADRE, CADRE, BAND, BAND])
+ setup_units("II", [FR_XX, FR_XX, FR_X, EL_X, EL_X, EL_X, AL_X, POL, POL])
+ setup_units("II", [FRONT, CADRE, CADRE, BAND, BAND])
+ setup_units("III", [FR_XX, FR_XX, AL_X, POL, POL])
+ setup_units("III", [FRONT, CADRE, CADRE, BAND, BAND])
+ setup_units("IV", [FR_XX, FR_XX, EL_X, EL_X, EL_X, AL_X, AL_X, POL, POL])
+ setup_units("IV", [FRONT, FRONT, CADRE, CADRE, BAND, BAND])
+ setup_units("V", [FR_XX, FR_XX, FR_XX, FR_X, EL_X, AL_X, POL, POL])
+ setup_units("V", [FRONT, CADRE, BAND])
+ setup_units("VI", [FRONT, CADRE, BAND])
+ setup_units("Morocco", [BAND])
+ setup_units("Tunisia", [BAND, BAND, BAND, BAND, FAILEK])
+ },
+ "1960" () {
+ setup_units("I", [FR_XX, FR_XX, AL_X])
+ setup_units("I", [CADRE, CADRE, BAND, BAND])
+ setup_units("II", [FR_XX, FR_XX, EL_X, EL_X, EL_X, EL_X, AL_X, AL_X, POL, POL])
+ setup_units("II", [FRONT, CADRE, CADRE, BAND, BAND])
+ setup_units("III", [FR_XX, FR_XX, FR_X, AL_X])
+ setup_units("III", [FRONT, FRONT, CADRE, CADRE, BAND, BAND])
+ setup_units("IV", [FR_XX, FR_XX, EL_X, EL_X, EL_X, AL_X, AL_X, POL, POL])
+ setup_units("IV", [FRONT, CADRE, BAND])
+ setup_units("V", [FR_XX, FR_XX, FR_XX, FR_XX, FR_XX, AL_X, POL, POL])
+ setup_units("V", [CADRE, BAND])
+ setup_units("Morocco", [BAND, BAND, BAND, BAND])
+ setup_units("Tunisia", [BAND, BAND, BAND, BAND, FAILEK, FAILEK, FAILEK])
+ }
+}
+
+function setup_scenario(scenario_name) {
+ log_h1("Scenario: " + scenario_name)
+
+ let scenario = SCENARIOS[scenario_name]
+ Object.assign(game, scenario)
+ game.fln_ap = roll_2d6()
+
+ SETUP[scenario_name]()
+}
+
function goto_scenario_setup() {
game.active = GOV
game.state = "scenario_setup"
@@ -178,10 +435,10 @@ states.scenario_setup = {
},
end_deployment() {
log(`Deployed`)
- let keys = Object.keys(game.summary).map(Number).sort((a,b)=>a-b)
- for (let x of keys)
- log(`>${game.summary[x]} at #${x}`)
- game.summary = null
+ // let keys = Object.keys(game.summary).map(Number).sort((a,b)=>a-b)
+ // for (let x of keys)
+ // log(`>${game.summary[x]} at #${x}`)
+ // game.summary = null
end_scenario_setup()
}
diff --git a/tools/gendata.js b/tools/gendata.js
index 11fd048..83b8493 100644
--- a/tools/gendata.js
+++ b/tools/gendata.js
@@ -9,12 +9,36 @@ const URBAN = 1
const REMOTE = 2
const COUNTRY = 3
-
let areas = []
let zones = {}
+let locations = {}
+let location_id = 0
+
+function def_location(name) {
+ locations[name] = ++location_id
+ return location_id
+}
+
+def_location("DEPLOY")
+def_location("ELIMINATED")
+def_location("I")
+def_location("II")
+def_location("III")
+def_location("IV")
+def_location("V")
+def_location("VI")
+def_location("France")
+def_location("Morocco")
+def_location("Tunisia")
function def_area(name, type, zone, x, y, w, h) {
- areas.push({name, type, zone, x, y, w, h})
+ let id = 0
+ if (name in locations) {
+ id = locations[name]
+ } else {
+ id = def_location(name)
+ }
+ areas.push({id, name, type, zone, x, y, w, h})
if (zone) {
if (!(zone in zones)) {
zones[zone] = []
@@ -59,8 +83,60 @@ def_area("Laghouat", REMOTE, "V", 1191, 1615.6)
def_area("Sidi Aissa", REMOTE, "VI", 1385, 1186)
def_area("Ain Qussera", RURAL, "VI", 1070.6, 1235.6)
-
data.areas = areas
data.zones = zones
+data.locations = locations
+
+let units = []
+
+const FLN = 0
+const GOV = 1
+
+const FR_XX = 0
+const FR_X = 1
+const EL_X = 2
+const AL_X = 3
+const POL = 4
+const FAILEK = 5
+const BAND = 6
+const CADRE = 7
+const FRONT = 8
+
+function def_unit(side, type, klass, count = 1) {
+ for (let i = 0; i < count; ++i) {
+ units.push({side, type, class: klass})
+ }
+}
+
+def_unit(GOV, FR_XX, "fr_xx_2")
+def_unit(GOV, FR_XX, "fr_xx_4")
+def_unit(GOV, FR_XX, "fr_xx_9")
+def_unit(GOV, FR_XX, "fr_xx_12")
+def_unit(GOV, FR_XX, "fr_xx_13")
+def_unit(GOV, FR_XX, "fr_xx_14")
+def_unit(GOV, FR_XX, "fr_xx_19")
+def_unit(GOV, FR_XX, "fr_xx_20")
+def_unit(GOV, FR_XX, "fr_xx_21")
+def_unit(GOV, FR_XX, "fr_xx_29")
+
+def_unit(GOV, FR_XX, "fr_xx_27")
+def_unit(GOV, FR_XX, "fr_xx_25")
+def_unit(GOV, FR_XX, "fr_xx_7")
+
+def_unit(GOV, FR_X, "fr_x", 4)
+def_unit(GOV, EL_X, "fr_elite_x_para", 3)
+def_unit(GOV, EL_X, "fr_elite_x_inf")
+def_unit(GOV, EL_X, "fr_elite_x_marine", 3)
+
+def_unit(GOV, AL_X, "alg_x", 6)
+def_unit(GOV, POL, "alg_police", 10)
+
+def_unit(FLN, FAILEK, "fln_failek", 10)
+def_unit(FLN, BAND, "fln_band", 24)
+def_unit(FLN, CADRE, "fln_cadre", 30)
+def_unit(FLN, FRONT, "fln_front", 16)
+
+console.log("unit_count =", units.length)
+data.units = units
fs.writeFileSync("data.js", "const data = " + JSON.stringify(data, 0, 0) + "\nif (typeof module !== 'undefined') module.exports = data\n")