From 6be2ca3af26f7f22bc0fa4114e37343a55e13d59 Mon Sep 17 00:00:00 2001 From: Razer2015 Date: Wed, 7 Dec 2022 10:13:00 +0200 Subject: [PATCH] Experimental support for nomination only maps --- battlefox/src/mapmanager/pool.rs | 36 ++++++++++++++++++++++++++------ battlefox/src/mapvote.rs | 14 +++++++------ 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/battlefox/src/mapmanager/pool.rs b/battlefox/src/mapmanager/pool.rs index cf0cf94..8a2e888 100644 --- a/battlefox/src/mapmanager/pool.rs +++ b/battlefox/src/mapmanager/pool.rs @@ -9,11 +9,13 @@ use serde::{Deserialize, Serialize}; /// - map /// - game mode (Rush, Conquest, ...) /// - vehicles (None -> Adaptive based on vehicle_threshold, False -> No vehicles, True -> Vehicles) +/// - nom_only (None -> Can be nominated and can randomly show up, False -> Random + nomination, True -> Nomination only) #[derive(Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct MapInPool { pub map: Map, pub mode: GameMode, - pub vehicles: Option + pub vehicles: Option, + pub nom_only: Option, } impl Display for MapInPool { @@ -47,13 +49,14 @@ impl From> for MapPool { } } } -impl From)>> for MapPool { - fn from(pool: Vec<(Map, GameMode, Option)>) -> Self { +impl From, Option)>> for MapPool { + fn from(pool: Vec<(Map, GameMode, Option, Option)>) -> Self { Self { - pool: pool.iter().map(|(map, mode, vehicles)| MapInPool { + pool: pool.iter().map(|(map, mode, vehicles, nom_only)| MapInPool { map: *map, mode: mode.clone(), - vehicles: *vehicles + vehicles: *vehicles, + nom_only: *nom_only, }).collect() } } @@ -135,6 +138,18 @@ impl MapPool { } } + /// Returns a new pool, with only the maps that can be randomly drawn. + pub fn random_maps_only(&self) -> Self { + Self { + pool: self + .pool + .iter() + .filter(|mip| mip.nom_only.is_none() || !mip.nom_only.unwrap()) + .cloned() + .collect(), + } + } + pub fn to_set(&self) -> HashSet { self.pool.iter().cloned().collect() @@ -172,8 +187,9 @@ impl MapPool { /// Selects at most `n_max` maps from the pool at random. pub fn choose_random(&self, n_max: usize) -> Self { let mut rng = thread_rng(); + let random_maps_only = self.random_maps_only(); Self { - pool: self + pool: random_maps_only .pool .choose_multiple(&mut rng, n_max) .cloned() @@ -231,6 +247,7 @@ mod tests { map: Map::Metro, mode: GameMode::Rush, vehicles: None, + nom_only: None, }], }; @@ -240,11 +257,13 @@ mod tests { map: Map::Metro, mode: GameMode::Rush, vehicles: None, + nom_only: None, }, MapInPool { map: Map::Locker, mode: GameMode::Rush, vehicles: None, + nom_only: None, }, ], }; @@ -254,6 +273,7 @@ mod tests { map: Map::Locker, mode: GameMode::Rush, vehicles: None, + nom_only: None, }], }; @@ -269,11 +289,13 @@ mod tests { map: Map::Metro, mode: GameMode::Rush, vehicles: None, + nom_only: None, }, MapInPool { map: Map::Locker, mode: GameMode::Rush, vehicles: None, + nom_only: None, }, ], }; @@ -283,6 +305,7 @@ mod tests { map: Map::Metro, mode: GameMode::Rush, vehicles: None, + nom_only: None, }], }; @@ -291,6 +314,7 @@ mod tests { map: Map::Locker, mode: GameMode::Rush, vehicles: None, + nom_only: None, }], }; diff --git a/battlefox/src/mapvote.rs b/battlefox/src/mapvote.rs index 9713ea1..11afb9f 100644 --- a/battlefox/src/mapvote.rs +++ b/battlefox/src/mapvote.rs @@ -126,6 +126,7 @@ impl Inner { map, mode: GameMode::Rush, vehicles, + nom_only: None, }); self.update_matchers(true); } @@ -608,20 +609,20 @@ impl Mapvote { if let Some(inner) = &mut *lock { let not_in_popstate = prefs .iter() - .filter(|MapInPool { map, mode, vehicles}| !inner.popstate.pool.contains_map(*map)) + .filter(|MapInPool { map, mode, vehicles, nom_only}| !inner.popstate.pool.contains_map(*map)) .cloned() .collect::>(); // Remove maps which are forbidden by pop state. - prefs.retain(|MapInPool { map, mode, vehicles}| inner.popstate.pool.contains_map(*map)); + prefs.retain(|MapInPool { map, mode, vehicles, nom_only}| inner.popstate.pool.contains_map(*map)); let not_in_options = prefs .iter() - .filter(|MapInPool { map, mode, vehicles}| !inner.alternatives.contains_map(*map)) + .filter(|MapInPool { map, mode, vehicles, nom_only}| !inner.alternatives.contains_map(*map)) .cloned() .collect::>(); // the maps are in the popstate, but aren't up to be chosen right now. // Nomination possible. - prefs.retain(|MapInPool { map, mode, vehicles}| inner.alternatives.contains_map(*map)); + prefs.retain(|MapInPool { map, mode, vehicles, nom_only}| inner.alternatives.contains_map(*map)); let weight = match player.clone().cases() { Left(yesvip) => self.vip_vote_weight(), @@ -629,10 +630,11 @@ impl Mapvote { }; // now, attempt to deduplicate (Ballot:from_iter(..) does that for us) - let alts = prefs.iter().map(|MapInPool { map, mode, vehicles}| MapInPool { + let alts = prefs.iter().map(|MapInPool { map, mode, vehicles, nom_only}| MapInPool { map: *map, mode: mode.clone(), - vehicles: *vehicles + vehicles: *vehicles, + nom_only: *nom_only, }); let (ballot, soft_dups) = match Ballot::from_iter(weight, alts) { CheckBallotResult::Ok { ballot, soft_dups } => (ballot, soft_dups),