1
0
mirror of https://git.ngram.ca/OpenJam/rc-servers synced 2026-08-23 23:08:52 +00:00
Files
ojrc/rc_core/src/data/campaign.rs
2025-03-30 16:22:25 -04:00

302 lines
11 KiB
Rust

use polariton::operation::Typed;
pub struct CampaignsGameParameters {
pub campaigns: Vec<CampaignParameters>,
}
impl CampaignsGameParameters {
fn dump(&self, writer: &mut dyn std::io::Write) -> std::io::Result<usize> {
writer.write_all(&(self.campaigns.len() as i32).to_le_bytes())?;
let mut total_len = 4;
for campaign in self.campaigns.iter() {
total_len += campaign.dump(writer)?;
}
Ok(total_len)
}
pub fn as_transmissible<C>(&self) -> Typed<C> {
let mut buf = Vec::new();
self.dump(&mut std::io::Cursor::new(&mut buf)).unwrap();
Typed::Bytes(buf.into())
}
}
pub struct CampaignParameters {
pub id: String,
pub excluded_cubes: Vec<u32>, // encoded to hex strings
pub categories: Vec<super::weapon_list::ItemCategory>,
pub min_cpu: i32,
pub max_cpu: i32,
pub name: String,
pub description: String,
pub image: String,
pub rules: Vec<String>,
pub parameters: Vec<Vec<String>>,
pub difficulties: Vec<CampaignDifficultyData>,
pub completed: Vec<CampaignCompletionData>,
pub map: String,
}
impl CampaignParameters {
fn dump(&self, writer: &mut dyn std::io::Write) -> std::io::Result<usize> {
let mut total_len = super::write_str_for_binreader(&self.id, writer)?;
writer.write_all(&(self.excluded_cubes.len() as i32).to_le_bytes())?;
total_len += 4;
for excluded_cube in self.excluded_cubes.iter() {
let s = super::cube_id_to_str(*excluded_cube);
total_len += super::write_str_for_binreader(&s, writer)?;
}
writer.write_all(&(self.categories.len() as i32).to_le_bytes())?;
total_len += 4;
for cat in self.categories.iter() {
total_len += super::write_str_for_binreader(cat.as_str(), writer)?;
}
writer.write_all(&self.min_cpu.to_le_bytes())?;
writer.write_all(&self.max_cpu.to_le_bytes())?;
total_len += 8;
total_len += super::write_str_for_binreader(&self.name, writer)?;
total_len += super::write_str_for_binreader(&self.description, writer)?;
total_len += super::write_str_for_binreader(&self.image, writer)?;
writer.write_all(&(self.rules.len() as i32).to_le_bytes())?;
total_len += 4;
for rule in self.rules.iter() {
total_len += super::write_str_for_binreader(rule, writer)?;
}
writer.write_all(&(self.parameters.len() as i32).to_le_bytes())?;
total_len += 4;
for param_vec in self.parameters.iter() {
writer.write_all(&(param_vec.len() as i32).to_le_bytes())?;
total_len += 4;
for param in param_vec.iter() {
total_len += super::write_str_for_binreader(param, writer)?;
}
}
writer.write_all(&(self.difficulties.len() as i32).to_le_bytes())?;
total_len += 4;
for difficulty in self.difficulties.iter() {
writer.write_all(&(CampaignDifficultyData::WRITE_BYTES_LEN as i32).to_le_bytes())?;
total_len += 4 + difficulty.dump(writer)?;
}
writer.write_all(&(self.completed.len() as i32).to_le_bytes())?;
total_len += 4;
for completion in self.completed.iter() {
total_len += completion.dump(writer)?;
}
total_len += super::write_str_for_binreader(&self.map, writer)?;
Ok(total_len)
}
}
pub struct CampaignDifficultyData {
pub level: i32,
pub lives: i32,
pub auto_heal: bool,
pub single_wave_bonus: i32,
pub initial_health_boost: f32,
pub health_boost_wave_increase: f32,
pub initial_damage_boost: f32,
pub damage_boost_wave_increase: f32,
}
impl CampaignDifficultyData {
const WRITE_BYTES_LEN: usize = 29;
fn dump(&self, writer: &mut dyn std::io::Write) -> std::io::Result<usize> {
writer.write_all(&self.level.to_le_bytes())?;
writer.write_all(&self.lives.to_le_bytes())?;
writer.write_all(&[self.auto_heal as u8])?;
writer.write_all(&self.single_wave_bonus.to_le_bytes())?;
writer.write_all(&self.initial_health_boost.to_le_bytes())?;
writer.write_all(&self.health_boost_wave_increase.to_le_bytes())?;
writer.write_all(&self.initial_damage_boost.to_le_bytes())?;
writer.write_all(&self.damage_boost_wave_increase.to_le_bytes())?;
Ok(Self::WRITE_BYTES_LEN)
}
}
pub struct CampaignCompletionData {
pub index: i32,
pub wave: i32,
pub difficulty: bool,
}
impl CampaignCompletionData {
const WRITE_BYTES_LEN: usize = 9;
fn dump(&self, writer: &mut dyn std::io::Write) -> std::io::Result<usize> {
writer.write_all(&self.index.to_le_bytes())?;
writer.write_all(&self.wave.to_le_bytes())?;
writer.write_all(&[self.difficulty as u8])?;
Ok(Self::WRITE_BYTES_LEN)
}
}
pub struct LiveCampaignWaves {
pub waves: Vec<WavesData>,
}
impl LiveCampaignWaves {
pub fn as_transmissible<C>(&self) -> Typed<C> {
Typed::HashMap(self.waves.iter().flat_map(|waves| waves.as_transmissible_key_val()).collect::<Vec<_>>().into())
}
}
pub struct WavesData {
pub id: String,
pub waves: Vec<WaveData>,
pub campaign_type: CampaignType,
}
impl WavesData {
pub fn as_transmissible_key_val<C>(&self) -> [(Typed<C>, Typed<C>); 3] {
[
(Typed::Str(format!("wavesNumberInCurrentCampaign_{}", self.id).into()), Typed::Int(self.waves.len() as _)),
(Typed::Str(self.id.clone().into()), Typed::HashMap(self.waves.iter().enumerate().flat_map(|(i, wave)| wave.as_transmissible_key_val(i)).collect::<Vec<_>>().into())),
(Typed::Str(format!("campaignType_{}", self.id).into()), Typed::Int(self.campaign_type as _)),
]
}
}
pub struct WaveData {
pub robots_in_wave: Vec<WaveRobotData>,
}
impl WaveData {
pub fn as_transmissible_key_val<C>(&self, index: usize) -> [(Typed<C>, Typed<C>); 2] {
[
(Typed::Str(format!("numberOfDifferentRobotsInCurrentWave_{}", index).into()), Typed::Int(self.robots_in_wave.len() as _)),
(Typed::Int(index as _), Typed::HashMap(self.robots_in_wave.iter().enumerate().map(|(i, robot)| (Typed::Int(i as _), robot.as_transmissible())).collect::<Vec<_>>().into())),
]
}
}
pub struct WaveRobotData {
pub name: String,
pub weapon: String,
pub movement: String,
pub rank: String,
pub count: i32,
}
impl WaveRobotData {
pub fn as_transmissible<C>(&self) -> Typed<C> {
Typed::HashMap(vec![
(Typed::Str("RobotName".into()), Typed::Str(self.name.clone().into())),
(Typed::Str("RobotWeapon".into()), Typed::Str(self.weapon.clone().into())),
(Typed::Str("RobotMovementPart".into()), Typed::Str(self.movement.clone().into())),
(Typed::Str("RobotRank".into()), Typed::Str(self.rank.clone().into())),
(Typed::Str("RobotCount".into()), Typed::Int(self.count)),
].into())
}
}
#[repr(u8)]
#[derive(Debug, Clone, Copy)]
pub enum CampaignType {
TimedElimination = 0,
Survival = 1,
Elimination = 2,
}
pub struct GameModeVersionParameters {
pub current_version: i32,
pub is_locked: std::collections::HashMap<String, bool>,
}
impl GameModeVersionParameters {
pub fn as_transmissible<C>(&self) -> Typed<C> {
Typed::HashMap(vec![
(Typed::Str("CurrentVersionNumber".into()), Typed::Int(self.current_version)),
(Typed::Str("LockedCampaignsInfo".into()), Typed::HashMap(self.is_locked.iter().map(|(key, val)| (Typed::Str(key.into()), Typed::Bool(*val))).collect::<Vec<_>>().into())),
].into())
}
}
pub struct CampaignWavesDifficultyData {
pub difficulty: CampaignDifficultyData,
pub waves: Vec<CompleteWaveData>,
}
impl CampaignWavesDifficultyData {
pub fn as_transmissible<C>(&self) -> Typed<C> {
let mut buf = Vec::new();
self.dump(&mut std::io::Cursor::new(&mut buf)).unwrap();
Typed::Bytes(buf.into())
}
fn dump(&self, writer: &mut dyn std::io::Write) -> std::io::Result<usize> {
writer.write_all(&(CampaignDifficultyData::WRITE_BYTES_LEN as i32).to_le_bytes())?;
self.difficulty.dump(writer)?;
writer.write_all(&(self.waves.len() as i32).to_le_bytes())?;
let mut waves_total_len = 4;
for wave in self.waves.iter() {
waves_total_len += wave.dump(writer)?;
}
Ok(4 + CampaignDifficultyData::WRITE_BYTES_LEN + waves_total_len)
}
}
pub struct CompleteWaveData {
pub player_spawn_location: i32,
pub robots_in_wave: Vec<CompleteWaveRobotData>,
pub kill_target: i32,
pub time_min: i32,
pub time_max: i32,
}
impl CompleteWaveData {
fn dump(&self, writer: &mut dyn std::io::Write) -> std::io::Result<usize> {
writer.write_all(&self.player_spawn_location.to_le_bytes())?;
writer.write_all(&(self.robots_in_wave.len() as i32).to_le_bytes())?;
let mut robots_total_len = 4;
for robot in self.robots_in_wave.iter() {
robots_total_len += robot.dump(writer)?;
}
writer.write_all(&self.kill_target.to_le_bytes())?;
writer.write_all(&self.time_min.to_le_bytes())?;
writer.write_all(&self.time_max.to_le_bytes())?;
Ok(16 + robots_total_len)
}
}
pub struct CompleteWaveRobotData {
pub name: String,
pub robot_data: Vec<u8>,
pub colour_data: Vec<u8>,
pub time_to_spawn: i32,
pub kills_to_spawn: i32,
pub time_to_despawn: i32,
pub kills_to_despawn: i32,
pub initial_robot_amount: i32,
pub periodic_robot_amount: i32,
pub spawn_interval: i32,
pub min_robot_amount: i32,
pub max_robot_amount: i32,
pub is_boss: bool,
pub is_kill_requirement: bool,
}
impl CompleteWaveRobotData {
fn dump(&self, writer: &mut dyn std::io::Write) -> std::io::Result<usize> {
let mut total_len = super::write_str_for_binreader(&self.name, writer)?;
writer.write_all(&(self.robot_data.len() as i32).to_le_bytes())?;
total_len += 4;
writer.write_all(&self.robot_data)?;
total_len += self.robot_data.len();
writer.write_all(&(self.colour_data.len() as i32).to_le_bytes())?;
total_len += 4;
writer.write_all(&self.colour_data)?;
total_len += self.colour_data.len();
writer.write_all(&self.time_to_spawn.to_le_bytes())?;
writer.write_all(&self.kills_to_spawn.to_le_bytes())?;
writer.write_all(&self.time_to_despawn.to_le_bytes())?;
writer.write_all(&self.kills_to_despawn.to_le_bytes())?;
writer.write_all(&self.initial_robot_amount.to_le_bytes())?;
writer.write_all(&self.periodic_robot_amount.to_le_bytes())?;
writer.write_all(&self.spawn_interval.to_le_bytes())?;
writer.write_all(&self.min_robot_amount.to_le_bytes())?;
writer.write_all(&self.max_robot_amount.to_le_bytes())?;
writer.write_all(&[self.is_boss as u8])?;
writer.write_all(&[self.is_kill_requirement as u8])?;
Ok(total_len)
}
}