diff options
-rw-r--r-- | play.css | 7 | ||||
-rw-r--r-- | play.js | 88 | ||||
-rw-r--r-- | rules.js | 195 |
3 files changed, 192 insertions, 98 deletions
@@ -236,6 +236,13 @@ body.p2 #Galatia_NPG { display: block } .legion.action { box-shadow: 0 0 0 1px #434343, 0 0 0 4px red; } .militia.action { box-shadow: 0 0 0 1px #434343, 0 0 0 4px red; } +.alamanni.action { box-shadow: 0 0 0 1px #393204, 0 0 0 4px white; } +.franks.action { box-shadow: 0 0 0 1px #1d323a, 0 0 0 4px white; } +.goths.action { box-shadow: 0 0 0 1px #002759, 0 0 0 4px white; } +.nomads.action { box-shadow: 0 0 0 1px #610700, 0 0 0 4px white; } +.sassanids.action { box-shadow: 0 0 0 1px #2f0042, 0 0 0 4px white; } +.rival_emperor.action { box-shadow: 0 0 0 1px #323214, 0 0 0 4px white; } + .red.selected { box-shadow: 0 0 0 1px #680000, 0 0 0 4px yellow; } .blue.selected { box-shadow: 0 0 0 1px #113854, 0 0 0 4px yellow; } .yellow.selected { box-shadow: 0 0 0 1px #553a00, 0 0 0 4px yellow; } @@ -594,26 +594,11 @@ function register_action(target, action, id) { } function on_click_action(evt, target) { - if (evt.button === 0) { - /* - if (typeof target.my_stack === "number") { - evt.stopPropagation() - if (focus_stack(target.my_stack)) - if (!send_action(target.my_action, target.my_id)) - blur_stack() - } else { - */ + if (evt.button === 0) if (send_action(target.my_action, target.my_id)) evt.stopPropagation() - //} - } } -document.getElementById("map").addEventListener("mousedown", function (evt) { - if (evt.button === 0) - blur_stack() -}) - function create_building(region, className, xoff, yoff) { let [ x, y, w, h ] = LAYOUT_SUPPORT[region] let e = create_thing({ className }) @@ -712,36 +697,13 @@ function on_init() { } let stack_count = new Array(21).fill(0) -let stack_focus = -1 -let stack_cache = [] - -function focus_stack(id) { - if (stack_focus !== id) { - // if (view.selected_general === undefined) send_action("general", id) - stack_focus = id - on_update() - let stack = stack_cache[id] - return stack && stack.length <= 1 - } - return true -} - -function blur_stack() { - if (stack_focus >= 0) { - stack_focus = -1 - on_update() - } -} function layout_stack(id, list, region, in_capital) { let [ x, y, w, h ] = LAYOUT_XY[region] - let dx = 6 - let dy = 6 + let dx = 8 + let dy = 8 let z = 1 - if (id >= 0) - stack_cache[id] = list - x += w >> 1 y += h >> 1 @@ -772,7 +734,8 @@ function layout_stack(id, list, region, in_capital) { dy = 16 } - for (let item of list) { + for (let i = list.length - 1; i >= 0; --i) { + let item = list[i] item.style.left = x + "px" item.style.top = y + "px" item.style.zIndex = z @@ -812,9 +775,6 @@ function layout_governor_unavailable(e, color, ix) { function on_update() { let player_count = view.legacy.length - for (let i = 0; i < 24; ++i) - stack_cache[i] = null - ui.body.classList.toggle("p2", player_count === 2) ui.body.classList.toggle("p3", player_count === 3) ui.body.classList.toggle("p4", player_count === 4) @@ -949,10 +909,10 @@ function on_update() { active_barbarians.push(ui.barbarians[id]) } } - if (active_barbarians.length > 0) - layout_stack(-1, active_barbarians, region, false) if (inactive_barbarians.length > 0) layout_stack(-1, inactive_barbarians, region, false) + if (active_barbarians.length > 0) + layout_stack(-1, active_barbarians, region, false) } } @@ -975,7 +935,7 @@ function on_update() { let mcastra = has_militia_castra(region) if (mcastra) { show(ui.mcastra[region]) - layout_stack(-1, [ ui.militia[region], ui.mcastra[region] ], region, true) + layout_stack(-1, [ ui.mcastra[region], ui.militia[region] ], region, true) } else { hide(ui.mcastra[region]) layout_stack(-1, [ ui.militia[region] ], region, true) @@ -1007,32 +967,32 @@ function on_update() { if (region < 21) { let stack = [] - if (has_militia(region) && inside) - stack.push(ui.militia[region]) - - for (let tribe = 0; tribe < TRIBE_COUNT[player_count]; ++tribe) { - for (let id = first_barbarian[tribe]; id <= last_barbarian[tribe]; ++id) { - let loc = get_barbarian_location(id) - if (loc === army) - stack.push(ui.barbarians[id]) - } + if (castra) { + show(ui.castra[pi][ai]) + stack.push(ui.castra[pi][ai]) + } else { + hide(ui.castra[pi][ai]) } + stack.push(e) + for (let i = 0; i < 33; ++i) { let loc = get_legion_location(i) if (loc === army) stack.push(ui.legions[i]) } - stack.push(e) - - if (castra) { - show(ui.castra[pi][ai]) - stack.push(ui.castra[pi][ai]) - } else { - hide(ui.castra[pi][ai]) + for (let tribe = 0; tribe < TRIBE_COUNT[player_count]; ++tribe) { + for (let id = first_barbarian[tribe]; id <= last_barbarian[tribe]; ++id) { + let loc = get_barbarian_location(id) + if (loc === army) + stack.push(ui.barbarians[id]) + } } + if (has_militia(region) && inside) + stack.push(ui.militia[region]) + if (inside) layout_stack(pi * 6 + ai, stack, region, true) else @@ -2,6 +2,76 @@ // TODO: barbarian leaders -> barbarian list +/* +TODO +---- + +[x] crisis ira deorum +[x] crisis barbarians +[ ] crisis pax deorum + +[ ] tribute +[ ] foederati +[ ] mobs + +[ ] disperse mob + +[ ] combat victory +[ ] combat retreat out of capital +[ ] combat retreat barbarians to homeland +[ ] combat advance into capital +[ ] combat flanking maneuver + +[ ] quaestor + [ ] place + [ ] remove at start + [ ] remove when replaced + +[ ] castra + [ ] place + [ ] remove at start + [ ] remove when move/attack + [ ] take hits in battle + +[ ] support check + +[ ] gain legacy + [ ] emperor + [ ] provinces + [ ] improvements + +[ ] end turn + [ ] grow mobs + [ ] flip barbarians + +[ ] praetorian guard +[ ] damnatio memoriae + +[ ] pretender + [ ] place + [ ] expand + [ ] scoring effects + [ ] occupation effects + +[ ] game end + +[ ] rival emperors + [ ] emperor turns + [ ] combat + [ ] support check + [ ] combat bonus + [ ] buy/trash bonus + +[ ] barbarian leaders + [ ] invasion + [ ] combat bonus + [ ] combat effect + [ ] buy/trash bonus + +[ ] other events + +*/ + var game var view const states = {} @@ -127,6 +197,7 @@ const GOTHS = 2 const NOMADS = 3 const SASSANIDS = 4 +const TRIBE_COUNT = [ 0, 5, 3, 4, 5 ] const BARBARIAN_COUNT = [ 0, 50, 30, 40, 50 ] const first_barbarian = [ 0, 10, 20, 30, 40 ] const last_barbarian = [ 9, 19, 29, 39, 49 ] @@ -686,12 +757,6 @@ function find_inactive_barbarian_at_home(tribe) { return -1 } -function activate_one_barbarian(tribe) { - let i = find_inactive_barbarian_at_home(tribe) - if (i >= 0) - set_barbarian_active(i) -} - function count_barbarians_in_province(tribe, where) { let n = 0 for (let id = first_barbarian[tribe]; id <= last_barbarian[tribe]; ++id) @@ -879,8 +944,6 @@ function goto_crisis() { let sum = game.dice[0] + game.dice[1] - return goto_take_actions() // XXX - if (sum === 2) return goto_ira_deorum() if (sum === 12) @@ -897,14 +960,36 @@ function goto_crisis() { function goto_ira_deorum() { logi("Ira Deorum") - activate_one_barbarian(ALAMANNI) - activate_one_barbarian(FRANKS) - activate_one_barbarian(GOTHS) - if (game.legacy.length > 3) - activate_one_barbarian(NOMADS) - if (game.legacy.length > 2) - activate_one_barbarian(SASSANIDS) - goto_take_actions() + + game.count = 0 + let tribe_count = BARBARIAN_COUNT[get_player_count()] + for (let tribe = 0; tribe < tribe_count; ++tribe) + if (find_inactive_barbarian_at_home(tribe) >= 0) + game.count |= (1 << tribe) + + game.state = "ira_deorum" + if (game.count === 0) + goto_take_actions() +} + +states.ira_deorum = { + prompt() { + prompt("Ira Deorum: Activate one Barbarian in each tribe's homeland.") + let tribe_count = BARBARIAN_COUNT[get_player_count()] + for (let tribe = 0; tribe < tribe_count; ++tribe) + if (game.count & (1 << tribe)) + gen_action_barbarian(find_inactive_barbarian_at_home(tribe)) + }, + barbarian(id) { + let tribe = get_barbarian_tribe(id) + game.count &= ~(1 << tribe) + + log("Activated " + BARBARIAN_NAME[tribe]) + set_barbarian_active(id) + + if (game.count === 0) + goto_take_actions() + }, } function goto_pax_deorum() { @@ -921,7 +1006,31 @@ function goto_event() { function goto_barbarian_crisis(tribe) { logi(BARBARIAN_NAME[tribe]) - activate_one_barbarian(tribe) + + game.crisis = tribe + + if (find_inactive_barbarian_at_home(tribe) >= 0) + game.state = "barbarian_crisis" + else + roll_barbarian_crisis() +} + +states.barbarian_crisis = { + prompt() { + let tribe = game.crisis + prompt(BARBARIAN_NAME[tribe] + " Crisis!") + gen_action_barbarian(find_inactive_barbarian_at_home(tribe)) + }, + barbarian(id) { + let tribe = game.crisis + log("Activated " + BARBARIAN_NAME[tribe]) + set_barbarian_active(id) + roll_barbarian_crisis() + }, +} + +function roll_barbarian_crisis() { + let tribe = game.crisis let black = game.dice[2] = roll_die() let white = game.dice[3] = roll_die() @@ -929,39 +1038,57 @@ function goto_barbarian_crisis(tribe) { logi(`B${black} W${white}`) if (black <= count_active_barbarians_at_home(tribe)) - goto_barbarian_invasion(tribe, black, white) + goto_barbarian_invasion() else goto_take_actions() } -function invade_with_active_barbarian(tribe, where) { - // TODO: move leaders first - let id = find_active_barbarian_at_home(tribe) - if (id >= 0) - set_barbarian_location(id, where) -} - function goto_barbarian_invasion(tribe, black, white) { logi("Invasion!") + game.count = game.dice[2] + game.state = "barbarian_invasion" +} + +states.barbarian_invasion = { + prompt() { + let tribe = game.crisis + prompt(BARBARIAN_NAME[tribe] + " Invasion!") + gen_action_barbarian(find_active_barbarian_at_home(tribe)) + }, + barbarian(id) { + if (invade_with_barbarian(id) || --game.count === 0) + goto_take_actions() + }, +} + +function invade_with_barbarian(id) { + let tribe = game.crisis + let white = game.dice[3] let path = null for (let list of BARBARIAN_INVASION[tribe]) if (white >= list[0] && white <= list[1]) path = list[2] - let k = 0 - for (let i = 0; i < black;) { - let n = count_barbarians_in_province(tribe, path[k]) + for (let i = 0; i < path.length; ++i) { + let n = count_barbarians_in_province(tribe, path[i]) if (n < 3) { - invade_with_active_barbarian(tribe, path[k]) - ++i - } else { - if (++k > path.length) - break + invade_with_barbarian_counter(id, path, path[i]) + return false } } - goto_take_actions() + return true +} + +function invade_with_barbarian_counter(id, path, where) { + set_barbarian_location(id, where) + for (let loc of path) { + if (has_limes(loc)) + set_barbarian_inactive(id) + if (loc === where) + break + } } // === TAKE ACTIONS === |