mirror of
https://git.ngram.ca/OpenJam/rc-servers
synced 2026-08-23 23:08:52 +00:00
Use resolvable vehicles in campaign mode instead of raw cube data
This commit is contained in:
130
rc_core/src/persist/config/campaign.rs
Normal file
130
rc_core/src/persist/config/campaign.rs
Normal file
@@ -0,0 +1,130 @@
|
||||
use polariton::operation::Typed;
|
||||
|
||||
pub(super) struct CompleteCampaignData {
|
||||
pub(super) difficulty_map: std::collections::HashMap<i32, crate::persist::CampaignDifficulty>,
|
||||
pub(super) waves: Vec<crate::persist::Wave>,
|
||||
}
|
||||
|
||||
pub struct CompleteCampaignProvider {
|
||||
map: std::collections::HashMap<String, CompleteCampaignData>,
|
||||
}
|
||||
|
||||
impl CompleteCampaignProvider {
|
||||
pub(super) fn new(map: std::collections::HashMap<String, CompleteCampaignData>) -> Self {
|
||||
Self { map }
|
||||
}
|
||||
|
||||
pub async fn get<C>(
|
||||
&self,
|
||||
id: &str,
|
||||
difficulty: &i32,
|
||||
user: &dyn crate::persist::user::CommonUser,
|
||||
factory: &dyn oj_rc_factory::VehicleFactoryAdapter,
|
||||
weapon_order: &crate::cubes::WeaponListParser,
|
||||
cpu_counter: &crate::cubes::CpuListParser,
|
||||
) -> Result<Typed<C>, i16> {
|
||||
if let Some(campaign) = self.map.get(id) {
|
||||
if let Some(difficulty_conf) = campaign.difficulty_map.get(difficulty) {
|
||||
let mut waves = Vec::with_capacity(campaign.waves.len());
|
||||
for wave in campaign.waves.iter() {
|
||||
let mut vehicles = Vec::with_capacity(wave.robots_in_wave.len());
|
||||
for vehicle in wave.robots_in_wave.iter() {
|
||||
let resolved = user.resolve_config_vehicle(&vehicle.vehicle.into_conf(), factory, weapon_order, cpu_counter).await?;
|
||||
vehicles.push(crate::data::campaign::CompleteWaveRobotData {
|
||||
name: resolved.robot_name,
|
||||
robot_data: resolved.robot_map,
|
||||
colour_data: resolved.colour_map,
|
||||
time_to_spawn: vehicle.time_to_spawn,
|
||||
kills_to_spawn: vehicle.kills_to_spawn,
|
||||
time_to_despawn: vehicle.time_to_despawn,
|
||||
kills_to_despawn: vehicle.kills_to_despawn,
|
||||
initial_robot_amount: vehicle.initial_robot_amount,
|
||||
periodic_robot_amount: vehicle.periodic_robot_amount,
|
||||
spawn_interval: vehicle.spawn_interval,
|
||||
min_robot_amount: vehicle.min_robot_amount,
|
||||
max_robot_amount: vehicle.max_robot_amount,
|
||||
is_boss: vehicle.is_boss,
|
||||
is_kill_requirement: vehicle.is_kill_requirement,
|
||||
});
|
||||
}
|
||||
waves.push(crate::data::campaign::CompleteWaveData {
|
||||
player_spawn_location: wave.player_spawn_location,
|
||||
robots_in_wave: vehicles,
|
||||
kill_target: wave.kill_target,
|
||||
time_min: wave.time_min,
|
||||
time_max: wave.time_max,
|
||||
});
|
||||
}
|
||||
let details_data = crate::data::campaign::CampaignWavesDifficultyData {
|
||||
difficulty: difficulty_conf.clone().into(),
|
||||
waves,
|
||||
};
|
||||
Ok(details_data.as_transmissible())
|
||||
} else {
|
||||
log::warn!("Couldn't find difficulty {} in campaign `{}`", difficulty, id);
|
||||
Err(crate::data::error_codes::WebServicesError::DatabaseError as i16)
|
||||
}
|
||||
} else {
|
||||
log::warn!("Couldn't find campaign {} (ignoring difficulty {})", id, difficulty);
|
||||
Err(crate::data::error_codes::WebServicesError::DatabaseError as i16)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CampaignResolver {
|
||||
pub(super) singleplayer: crate::persist::SingleplayerConfig,
|
||||
}
|
||||
|
||||
impl CampaignResolver {
|
||||
pub fn campaigns_parameters<C>(&self) -> Typed<C> {
|
||||
self.singleplayer.clone().into_campaign_params().as_transmissible()
|
||||
}
|
||||
|
||||
pub async fn campaign_waves<C>(
|
||||
&self,
|
||||
user: &dyn crate::persist::user::CommonUser,
|
||||
factory: &dyn oj_rc_factory::VehicleFactoryAdapter,
|
||||
weapon_order: &crate::cubes::WeaponListParser,
|
||||
cpu_counter: &crate::cubes::CpuListParser,
|
||||
) -> Result<Typed<C>, polariton_server::operations::SimpleOpError> {
|
||||
let mut campaigns = Vec::with_capacity(self.singleplayer.campaigns.len());
|
||||
for campaign in self.singleplayer.campaigns.iter() {
|
||||
let mut waves = Vec::with_capacity(campaign.waves.len());
|
||||
for wave in campaign.waves.iter() {
|
||||
let mut vehicles = Vec::with_capacity(wave.robots_in_wave.len());
|
||||
for robot in wave.robots_in_wave.iter() {
|
||||
let resolved = user.resolve_config_vehicle(&robot.vehicle.into_conf(), factory, weapon_order, cpu_counter).await?;
|
||||
vehicles.push(crate::data::campaign::WaveRobotData {
|
||||
name: resolved.robot_name,
|
||||
weapon: robot.weapon.clone(),
|
||||
movement: robot.movement.clone(),
|
||||
rank: robot.rank.clone(),
|
||||
count: robot.count,
|
||||
});
|
||||
}
|
||||
waves.push(crate::data::campaign::WaveData {
|
||||
robots_in_wave: vehicles,
|
||||
});
|
||||
}
|
||||
campaigns.push(crate::data::campaign::WavesData {
|
||||
id: campaign.id.clone(),
|
||||
waves,
|
||||
campaign_type: campaign.campaign_type.into(),
|
||||
});
|
||||
}
|
||||
Ok(crate::data::campaign::LiveCampaignWaves {
|
||||
waves: campaigns,
|
||||
}.as_transmissible())
|
||||
}
|
||||
|
||||
pub fn campaign_version<C>(&self) -> Typed<C> {
|
||||
let mut locked_map = std::collections::HashMap::with_capacity(self.singleplayer.campaigns.len());
|
||||
for campaign in self.singleplayer.campaigns.iter() {
|
||||
locked_map.insert(campaign.id.clone(), true);
|
||||
}
|
||||
crate::data::campaign::GameModeVersionParameters {
|
||||
current_version: 0,
|
||||
is_locked: locked_map,
|
||||
}.as_transmissible()
|
||||
}
|
||||
}
|
||||
@@ -244,43 +244,27 @@ impl <C: Clone + Send> super::ConfigProvider<C> for CubeConfig {
|
||||
game_mode_data.as_transmissible()
|
||||
}
|
||||
|
||||
fn campaigns_parameters(&self) -> Typed<C> {
|
||||
self.battle.singleplayer.clone().into_campaign_params().as_transmissible()
|
||||
}
|
||||
|
||||
fn campaign_waves(&self) -> Typed<C> {
|
||||
self.battle.singleplayer.clone().into_waves().as_transmissible()
|
||||
}
|
||||
|
||||
fn campaign_version(&self) -> Typed<C> {
|
||||
let mut locked_map = std::collections::HashMap::with_capacity(self.battle.singleplayer.campaigns.len());
|
||||
for campaign in self.battle.singleplayer.campaigns.iter() {
|
||||
locked_map.insert(campaign.id.clone(), true);
|
||||
}
|
||||
crate::data::campaign::GameModeVersionParameters {
|
||||
current_version: 0,
|
||||
is_locked: locked_map,
|
||||
}.as_transmissible()
|
||||
}
|
||||
|
||||
fn campaign_details(&self) -> super::CompleteCampaignProvider {
|
||||
let mut map = std::collections::HashMap::with_capacity(self.battle.singleplayer.campaigns.len());
|
||||
for campaign in self.battle.singleplayer.campaigns.iter() {
|
||||
//let waves_data: Vec<crate::data::campaign::CompleteWaveData> = campaign.waves.iter().map(|x| x.clone().into()).collect();
|
||||
let mut difficulty_map = std::collections::HashMap::with_capacity(campaign.difficulties.len());
|
||||
for difficulty in campaign.difficulties.iter() {
|
||||
let difficulty_data: crate::data::campaign::CampaignDifficultyData = difficulty.clone().into();
|
||||
let complete_campaign = crate::data::campaign::CampaignWavesDifficultyData {
|
||||
difficulty: difficulty_data,
|
||||
waves: campaign.waves.iter().map(|x| x.clone().into()).collect(),
|
||||
};
|
||||
difficulty_map.insert(difficulty.level, complete_campaign);
|
||||
difficulty_map.insert(difficulty.level, difficulty.to_owned());
|
||||
}
|
||||
map.insert(campaign.id.clone(), difficulty_map);
|
||||
map.insert(campaign.id.clone(), super::campaign::CompleteCampaignData {
|
||||
difficulty_map,
|
||||
waves: campaign.waves.clone(),
|
||||
});
|
||||
}
|
||||
super::CompleteCampaignProvider::new(map)
|
||||
}
|
||||
|
||||
fn campaigns(&self) -> super::CampaignResolver {
|
||||
super::CampaignResolver {
|
||||
singleplayer: self.battle.singleplayer.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn client_config(&self) -> Typed<C> {
|
||||
let conf_data: crate::data::client_config::GameplaySettings = self.settings.gameplay.clone().into();
|
||||
Typed::Dict(Dict {
|
||||
|
||||
@@ -2,11 +2,14 @@ mod cubes_json;
|
||||
pub use cubes_json::CubeConfig;
|
||||
|
||||
mod traits;
|
||||
pub use traits::{ConfigProvider, CompleteCampaignProvider, DevMessageProvider, ServerConfig, GarageUpgrades, GarageUpgradeIncrement, ChatSystemConfig, GameEventSequence, GameEvents, GameRotationStrategy, GameEvent, GameMap, GameVisibility, GameType, SingleplayerConfig, VehicleInfo, VehicleDescriptor, QueueChangeMode, Point, Sphere, MapConfig, LinksConfig, FakePlayer, ClientEmulator, EnergyConfig, BattleArenaResolver, PitSettings, PitWinCondition, TeamDeathMatchSettings};
|
||||
pub use traits::{ConfigProvider, DevMessageProvider, ServerConfig, GarageUpgrades, GarageUpgradeIncrement, ChatSystemConfig, GameEventSequence, GameEvents, GameRotationStrategy, GameEvent, GameMap, GameVisibility, GameType, SingleplayerConfig, VehicleInfo, VehicleDescriptor, QueueChangeMode, Point, Sphere, MapConfig, LinksConfig, FakePlayer, ClientEmulator, EnergyConfig, BattleArenaResolver, PitSettings, PitWinCondition, TeamDeathMatchSettings};
|
||||
|
||||
mod validation;
|
||||
pub use validation::{SelfValidator, ValidationInfo, ValidationMessage};
|
||||
|
||||
mod campaign;
|
||||
pub use campaign::{CampaignResolver, CompleteCampaignProvider};
|
||||
|
||||
pub type ConfigImpl = CubeConfig;
|
||||
|
||||
fn __must_impl<T: ConfigProvider<()>>() {}
|
||||
|
||||
@@ -12,10 +12,8 @@ pub trait ConfigProvider<C: Clone> {
|
||||
fn regen_config(&self) -> Typed<C>;
|
||||
fn after_battle_vote_config(&self) -> Typed<C>;
|
||||
fn game_mode_config(&self) -> Typed<C>;
|
||||
fn campaigns_parameters(&self) -> Typed<C>;
|
||||
fn campaign_waves(&self) -> Typed<C>;
|
||||
fn campaign_version(&self) -> Typed<C>;
|
||||
fn campaign_details(&self) -> CompleteCampaignProvider;
|
||||
fn campaign_details(&self) -> super::CompleteCampaignProvider;
|
||||
fn campaigns(&self) -> super::CampaignResolver;
|
||||
fn client_config(&self) -> Typed<C>;
|
||||
fn login_messages(&self) -> DevMessageProvider<C>;
|
||||
fn public_channels(&self) -> Typed<C>;
|
||||
@@ -40,30 +38,6 @@ pub trait ConfigProvider<C: Clone> {
|
||||
fn tdm_settings(&self) -> TeamDeathMatchSettings;
|
||||
}
|
||||
|
||||
pub struct CompleteCampaignProvider {
|
||||
map: std::collections::HashMap<String, std::collections::HashMap<i32, crate::data::campaign::CampaignWavesDifficultyData>>,
|
||||
}
|
||||
|
||||
impl CompleteCampaignProvider {
|
||||
pub fn new(map: std::collections::HashMap<String, std::collections::HashMap<i32, crate::data::campaign::CampaignWavesDifficultyData>>) -> Self {
|
||||
Self { map }
|
||||
}
|
||||
|
||||
pub fn get<C>(&self, id: &str, difficulty: &i32) -> Result<Typed<C>, i16> {
|
||||
if let Some(campaign) = self.map.get(id) {
|
||||
if let Some(details) = campaign.get(difficulty) {
|
||||
Ok(details.as_transmissible())
|
||||
} else {
|
||||
log::warn!("Couldn't find difficulty {} in campaign `{}`", difficulty, id);
|
||||
Err(crate::data::error_codes::WebServicesError::DatabaseError as i16)
|
||||
}
|
||||
} else {
|
||||
log::warn!("Couldn't find campaign {} (ignoring difficulty {})", id, difficulty);
|
||||
Err(crate::data::error_codes::WebServicesError::DatabaseError as i16)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DevMessageProvider<C: Clone> {
|
||||
messages: Vec<TypedDevMessage<C>>,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user