diff --git a/lang/cs.lang b/lang/cs.lang index 46cbf9f..087f57a 100644 --- a/lang/cs.lang +++ b/lang/cs.lang @@ -724,6 +724,7 @@ net.error = {0} net.rooms = Otevřené zápasy net.no_rooms = Žádné otevřené zápasy. net.create = Vytvořit zápas +net.map_size = Mapa {0}x{1} · {2} hráči net.coop_mission = Kooperativní kampaň: mise {0} ({1}) net.coop_create = Kooperace net.coop_editor = Kampaň z editoru diff --git a/lang/da.lang b/lang/da.lang index d34481f..6295cf9 100644 --- a/lang/da.lang +++ b/lang/da.lang @@ -723,6 +723,7 @@ net.error = {0} net.rooms = Åbne kampe net.no_rooms = Ingen åbne kampe. net.create = Opret kamp +net.map_size = Kort {0}x{1} · {2} spillere net.coop_mission = Co-op-kampagne: mission {0} ({1}) net.coop_create = Co-op-kampagne net.coop_editor = Editor-kampagne diff --git a/lang/de.lang b/lang/de.lang index 7be0f8b..5c0073c 100644 --- a/lang/de.lang +++ b/lang/de.lang @@ -723,6 +723,7 @@ net.error = {0} net.rooms = Offene Partien net.no_rooms = Keine offenen Partien. net.create = Partie erstellen +net.map_size = Karte {0}x{1} · {2} Spieler net.coop_mission = Koop-Kampagne: Mission {0} ({1}) net.coop_create = Koop-Kampagne net.coop_editor = Editor-Kampagne diff --git a/lang/el.lang b/lang/el.lang index 4c4b2d4..c683c42 100644 --- a/lang/el.lang +++ b/lang/el.lang @@ -724,6 +724,7 @@ net.error = {0} net.rooms = Ανοιχτές αναμετρήσεις net.no_rooms = Καμία ανοιχτή αναμέτρηση. net.create = Νέα αναμέτρηση +net.map_size = Χάρτης {0}x{1} · {2} παίκτες net.coop_mission = Συνεργατική εκστρατεία: αποστολή {0} ({1}) net.coop_create = Συνεργατική εκστρ. net.coop_editor = Εκστρατεία επεξεργαστή diff --git a/lang/en.lang b/lang/en.lang index b4d2d12..333f90a 100644 --- a/lang/en.lang +++ b/lang/en.lang @@ -724,6 +724,7 @@ net.error = {0} net.rooms = Open matches net.no_rooms = No open matches. net.create = Create match +net.map_size = Map {0}x{1} · {2} players net.coop_mission = Co-op campaign: mission {0} ({1}) net.coop_create = Co-op campaign net.coop_editor = Editor campaign diff --git a/lang/es.lang b/lang/es.lang index 2665b51..486256b 100644 --- a/lang/es.lang +++ b/lang/es.lang @@ -724,6 +724,7 @@ net.error = {0} net.rooms = Partidas abiertas net.no_rooms = No hay partidas abiertas. net.create = Crear partida +net.map_size = Mapa {0}x{1} · {2} jugadores net.coop_mission = Campaña cooperativa: misión {0} ({1}) net.coop_create = Campaña coop. net.join = Unirse diff --git a/lang/fi.lang b/lang/fi.lang index db3de6a..15dad56 100644 --- a/lang/fi.lang +++ b/lang/fi.lang @@ -724,6 +724,7 @@ net.error = {0} net.rooms = Avoimet ottelut net.no_rooms = Ei avoimia otteluita. net.create = Luo ottelu +net.map_size = Kartta {0}x{1} · {2} pelaajaa net.coop_mission = Yhteiskampanja: tehtävä {0} ({1}) net.coop_create = Yhteiskampanja net.coop_editor = Editorikampanja diff --git a/lang/hr.lang b/lang/hr.lang index decefd7..f093f31 100644 --- a/lang/hr.lang +++ b/lang/hr.lang @@ -724,6 +724,7 @@ net.error = {0} net.rooms = Otvorene partije net.no_rooms = Nema otvorenih partija. net.create = Nova partija +net.map_size = Karta {0}x{1} · {2} igrača net.coop_mission = Co-op kampanja: misija {0} ({1}) net.coop_create = Co-op kampanja net.coop_editor = Kampanja uređivača diff --git a/lang/hu.lang b/lang/hu.lang index 0efa6be..d6fc524 100644 --- a/lang/hu.lang +++ b/lang/hu.lang @@ -724,6 +724,7 @@ net.error = {0} net.rooms = Nyitott meccsek net.no_rooms = Nincsenek nyitott meccsek. net.create = Új meccs +net.map_size = Térkép {0}x{1} · {2} játékos net.coop_mission = Kooperatív hadjárat: {0}. küldetés ({1}) net.coop_create = Koop hadjárat net.coop_editor = Saját hadjárat diff --git a/lang/it.lang b/lang/it.lang index 311d493..739a5f7 100644 --- a/lang/it.lang +++ b/lang/it.lang @@ -724,6 +724,7 @@ net.error = {0} net.rooms = Partite aperte net.no_rooms = Nessuna partita aperta. net.create = Crea partita +net.map_size = Mappa {0}x{1} · {2} giocatori net.coop_mission = Campagna co-op: missione {0} ({1}) net.coop_create = Campagna co-op net.join = Entra diff --git a/lang/nl.lang b/lang/nl.lang index f6b8871..1b5d7a8 100644 --- a/lang/nl.lang +++ b/lang/nl.lang @@ -724,6 +724,7 @@ net.error = {0} net.rooms = Open partijen net.no_rooms = Geen open partijen. net.create = Partij maken +net.map_size = Kaart {0}x{1} · {2} spelers net.coop_mission = Co-op-veldtocht: missie {0} ({1}) net.coop_create = Co-op-veldtocht net.coop_editor = Editorveldtocht diff --git a/lang/no.lang b/lang/no.lang index 965e014..492b8a5 100644 --- a/lang/no.lang +++ b/lang/no.lang @@ -723,6 +723,7 @@ net.error = {0} net.rooms = Åpne kamper net.no_rooms = Ingen åpne kamper. net.create = Opprett kamp +net.map_size = Kart {0}x{1} · {2} spillere net.coop_mission = Co-op-kampanje: oppdrag {0} ({1}) net.coop_create = Co-op-kampanje net.coop_editor = Editorkampanje diff --git a/lang/pt.lang b/lang/pt.lang index ebd8735..61cec49 100644 --- a/lang/pt.lang +++ b/lang/pt.lang @@ -724,6 +724,7 @@ net.error = {0} net.rooms = Partidas abertas net.no_rooms = Não há partidas abertas. net.create = Criar partida +net.map_size = Mapa {0}x{1} · {2} jogadores net.coop_mission = Campanha cooperativa: missão {0} ({1}) net.coop_create = Campanha coop. net.coop_editor = Campanha do editor diff --git a/lang/ro.lang b/lang/ro.lang index f310322..a14d010 100644 --- a/lang/ro.lang +++ b/lang/ro.lang @@ -724,6 +724,7 @@ net.error = {0} net.rooms = Meciuri deschise net.no_rooms = Niciun meci deschis. net.create = Creează meci +net.map_size = Hartă {0}x{1} · {2} jucători net.coop_mission = Campanie co-op: misiunea {0} ({1}) net.coop_create = Campanie co-op net.coop_editor = Campanie din editor diff --git a/lang/ru.lang b/lang/ru.lang index b0ce3b7..bf5b950 100644 --- a/lang/ru.lang +++ b/lang/ru.lang @@ -724,6 +724,7 @@ net.error = {0} net.rooms = Открытые матчи net.no_rooms = Нет открытых матчей. net.create = Создать матч +net.map_size = Карта {0}x{1} · {2} игроков net.coop_mission = Кооп-кампания: миссия {0} ({1}) net.coop_create = Кооп-кампания net.join = Войти diff --git a/lang/sk.lang b/lang/sk.lang index 7ec4e7e..a1150b5 100644 --- a/lang/sk.lang +++ b/lang/sk.lang @@ -724,6 +724,7 @@ net.error = {0} net.rooms = Otvorené zápasy net.no_rooms = Žiadne otvorené zápasy. net.create = Vytvoriť zápas +net.map_size = Mapa {0}x{1} · {2} hráči net.coop_mission = Kooperatívna kampaň: misia {0} ({1}) net.coop_create = Kooperácia net.coop_editor = Kampaň z editora diff --git a/lang/sr.lang b/lang/sr.lang index 89b385d..f506a76 100644 --- a/lang/sr.lang +++ b/lang/sr.lang @@ -724,6 +724,7 @@ net.error = {0} net.rooms = Отворене партије net.no_rooms = Нема отворених партија. net.create = Нова партија +net.map_size = Мапа {0}x{1} · {2} играча net.coop_mission = Ко-оп кампања: мисија {0} ({1}) net.coop_create = Ко-оп кампања net.coop_editor = Кампања уређивача diff --git a/lang/sv.lang b/lang/sv.lang index 2aab736..98dd8d4 100644 --- a/lang/sv.lang +++ b/lang/sv.lang @@ -724,6 +724,7 @@ net.error = {0} net.rooms = Öppna matcher net.no_rooms = Inga öppna matcher. net.create = Skapa match +net.map_size = Karta {0}x{1} · {2} spelare net.coop_mission = Co-op-kampanj: uppdrag {0} ({1}) net.coop_create = Co-op-kampanj net.coop_editor = Egen kampanj diff --git a/src/lobby.rs b/src/lobby.rs index adf2183..1c62cdd 100644 --- a/src/lobby.rs +++ b/src/lobby.rs @@ -673,6 +673,17 @@ fn teams_from(sides: &[u8], v: Option<&Value>) -> Vec<(u8, u8)> { sides.iter().copied().zip(teams).collect() } +// versus map sizes and how many master seats each one has +pub const MATCH_SIZES: [usize; 7] = [80, 96, 128, 160, 192, 224, 256]; + +pub fn seats_for(size: usize) -> &'static [u8] { + match size { + 0..=80 => &[0, 2], + 81..=96 => &[0, 2, 3], + _ => &[0, 2, 3, 4], + } +} + fn seats_from(v: Option<&Value>) -> Vec { v.and_then(|x| x.as_array()) .map(|arr| { diff --git a/src/main.rs b/src/main.rs index 02ec105..8e82730 100644 --- a/src/main.rs +++ b/src/main.rs @@ -358,7 +358,11 @@ fn account_action(a: MenuAction, cloud: &mut Cloud, menu: &mut Menu, app: &mut A } } MenuAction::MatchJoin(code) => app.client.join(&code), - MenuAction::MatchCreate => app.client.create_land(&[0, 2, 3, 4], app.settings.map_w, app.settings.map_h, app.settings.difficulty, app.settings.surface, app.settings.events), + MenuAction::MatchCreate => { + // the map size decides the number of master seats + let n = app.settings.match_size; + app.client.create_land(lobby::seats_for(n), n, n, app.settings.difficulty, app.settings.surface, app.settings.events) + } MenuAction::MatchCoopCreate(mission) => { let all = campaign::missions(); if let Some(d) = all.get(mission) { diff --git a/src/menu.rs b/src/menu.rs index 62e892e..0b73294 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -238,6 +238,7 @@ enum Btn { Tab(usize), Change(usize, i32), MapW(i32), + MatchSize(i32), Land, MapH(i32), Difficulty(i32), @@ -437,6 +438,7 @@ pub struct Menu { pub error: Option, // message on the login and account pages pub match_ui: MatchUi, // copied state of the multiplayer relay, shown on the Match page pub coop_mission: usize, // co-op campaign mission selected on the Match page + match_size: usize, // the versus map size (from the settings, for drawing) pub coop_editor: bool, // the Match page offers a campaign document instead of the built-in missions pub coop_league: bool, // ... and that document is the co-op campaign "League against the Lightwatch" league_doc: Option, // the co-op campaign, built the first time it is chosen @@ -497,6 +499,7 @@ impl Menu { error: None, match_ui: MatchUi::default(), coop_mission: crate::campaign::coop_mission_indexes().first().copied().unwrap_or(0), + match_size: 128, coop_editor: false, coop_league: false, league_doc: None, @@ -682,6 +685,12 @@ impl Menu { MenuAction::Consumed } Some(Btn::Start) => MenuAction::NewGame, + Some(Btn::MatchSize(d)) => { + let sizes = crate::lobby::MATCH_SIZES; + let k = sizes.iter().position(|&s| s >= settings.match_size).unwrap_or(2) as i32; + settings.match_size = sizes[(k + d).clamp(0, sizes.len() as i32 - 1) as usize]; + MenuAction::SettingsChanged + } Some(Btn::MapW(d)) => { settings.map_w = (settings.map_w as i32 + d * 32).clamp(MIN_SIZE as i32, MAX_SIZE as i32) as usize; MenuAction::SettingsChanged @@ -953,6 +962,7 @@ impl Menu { self.buttons.clear(); self.lang_opts.clear(); self.cur_lang = settings.language.clone(); + self.match_size = settings.match_size; let Some(page) = self.page else { self.lang_open = None; return; @@ -2053,6 +2063,19 @@ impl Menu { } } } + // a new versus match: the map size and with it the number of seats + if !ui.started && !ui.room_open() { + let n = self.match_size; + let seats = crate::lobby::seats_for(n).len(); + let r = Rect::new(ix, yy, 4.0 * CW(), CH() * 2.0); + button(gfx, r, "<", r.contains(vec2(mx, my)), FRAME); + self.buttons.push((r, Btn::MatchSize(-1))); + gfx.text(&trf("net.map_size", &[n.to_string(), n.to_string(), seats.to_string()]), ix + 5.0 * CW(), yy + CH() * 0.5, S(), TXT); + let r = Rect::new(ix + 30.0 * CW(), yy, 4.0 * CW(), CH() * 2.0); + button(gfx, r, ">", r.contains(vec2(mx, my)), FRAME); + self.buttons.push((r, Btn::MatchSize(1))); + yy += CH() * 2.4; + } self.field(gfx, ix, yy, w, &tr("net.join_hint"), 0, false); self.field(gfx, ix, yy + CH() * 2.4, w, &tr("net.chat"), 1, false); yy += CH() * 4.8; diff --git a/src/settings.rs b/src/settings.rs index 7d05be4..aab29dd 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -163,6 +163,7 @@ pub struct Settings { pub hints: bool, pub difficulty: u8, // rival masters in free games: 0 easy, 1 medium, 2 hard pub map_w: usize, // size of new maps (64..256) + pub match_size: usize, // versus matches: the map is match_size x match_size (see lobby::seats_for) pub map_h: usize, pub surface: bool, // new free games: the eastern half lies above ground (forest) pub events: bool, // random events in free games and versus matches @@ -201,6 +202,7 @@ impl Default for Settings { hints: true, difficulty: 1, map_w: 64, + match_size: 128, map_h: 64, surface: false, events: true,