mirror of
https://git.ngram.ca/OpenJam/rc-servers
synced 2026-08-23 23:08:52 +00:00
Get campaign mode working, fix health/damage config
This commit is contained in:
301
rc_services_room/src/data/campaign.rs
Normal file
301
rc_services_room/src/data/campaign.rs
Normal file
@@ -0,0 +1,301 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
@@ -127,3 +127,7 @@ impl ItemType {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn item_key(category: super::weapon_list::ItemCategory, tier: ItemTier) -> i32 {
|
||||
category.but_bigger() + (tier as i32)
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ pub mod lobby;
|
||||
pub mod error_codes;
|
||||
pub mod game_mode;
|
||||
pub mod score_multipliers;
|
||||
pub mod campaign;
|
||||
|
||||
pub(self) fn encode_7_bit_i32(mut src: i32) -> Vec<u8> {
|
||||
if src == 0 { return vec![0] }
|
||||
@@ -49,3 +50,7 @@ pub(self) fn write_str_for_binreader(s: &str, writer: &mut dyn std::io::Write) -
|
||||
total_len += writer.write(s_bytes)?;
|
||||
Ok(total_len)
|
||||
}
|
||||
|
||||
pub(self) fn cube_id_to_str(id: u32) -> String {
|
||||
hex::encode(id.to_be_bytes()).into()
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ pub struct ScoreMultipliersData {
|
||||
impl ScoreMultipliersData {
|
||||
fn dump(&self, writer: &mut dyn std::io::Write) -> std::io::Result<usize> {
|
||||
writer.write_all(&self.max_cpu.to_le_bytes())?;
|
||||
writer.write_all(&(self.stat_multipliers.len() as i32).to_le_bytes())?;
|
||||
for (key, val) in self.stat_multipliers.iter() {
|
||||
writer.write_all(&(*key as u32).to_le_bytes())?;
|
||||
writer.write_all(&val.base.to_le_bytes())?;
|
||||
@@ -25,7 +26,7 @@ impl ScoreMultipliersData {
|
||||
writer.write_all(&self.defeat_score.to_le_bytes())?;
|
||||
writer.write_all(&self.victory_score.to_le_bytes())?;
|
||||
writer.write_all(&self.max_score_ratio.to_le_bytes())?;
|
||||
Ok(28 + (12 * self.stat_multipliers.len()))
|
||||
Ok(32 + (12 * self.stat_multipliers.len()))
|
||||
}
|
||||
|
||||
pub fn as_transmissible<C>(&self) -> Typed<C> {
|
||||
|
||||
@@ -36,7 +36,7 @@ pub(super) fn all_customisations_provider() -> SimpleFunc<216, crate::UserTy, im
|
||||
id: "Spawn".to_string(),
|
||||
localised_name: "strSpawnFXWarpIn".to_string(),
|
||||
skin_scene_name: "Splash_Loading_Screen".to_string(),
|
||||
simulation_prefab: "Respawn_WarpIn".to_string(),
|
||||
simulation_prefab: "Spawn".to_string(),
|
||||
preview_image_name: "RC_Splash_Screen_01_Japanese".to_string(),
|
||||
is_default: true,
|
||||
}.as_transmissible(),
|
||||
@@ -44,7 +44,7 @@ pub(super) fn all_customisations_provider() -> SimpleFunc<216, crate::UserTy, im
|
||||
id: "Spawn_BlackHole".to_string(),
|
||||
localised_name: "strSpawnFXWarpIn".to_string(),
|
||||
skin_scene_name: "Splash_Loading_Screen".to_string(),
|
||||
simulation_prefab: "Respawn_WarpIn".to_string(),
|
||||
simulation_prefab: "Spawn_BlackHole".to_string(),
|
||||
preview_image_name: "RC_Splash_Screen_01_Japanese".to_string(),
|
||||
is_default: true,
|
||||
}.as_transmissible(),
|
||||
@@ -52,7 +52,7 @@ pub(super) fn all_customisations_provider() -> SimpleFunc<216, crate::UserTy, im
|
||||
id: "Spawn_Lander".to_string(),
|
||||
localised_name: "strSpawnFXWarpIn".to_string(),
|
||||
skin_scene_name: "Splash_Loading_Screen".to_string(),
|
||||
simulation_prefab: "Respawn_WarpIn".to_string(),
|
||||
simulation_prefab: "Spawn_Lander".to_string(),
|
||||
preview_image_name: "RC_Splash_Screen_01_Japanese".to_string(),
|
||||
is_default: true,
|
||||
}.as_transmissible(),
|
||||
@@ -60,7 +60,7 @@ pub(super) fn all_customisations_provider() -> SimpleFunc<216, crate::UserTy, im
|
||||
id: "Spawn_Lootcrate".to_string(),
|
||||
localised_name: "strSpawnFXWarpIn".to_string(),
|
||||
skin_scene_name: "Splash_Loading_Screen".to_string(),
|
||||
simulation_prefab: "Respawn_WarpIn".to_string(),
|
||||
simulation_prefab: "Spawn_Lootcrate".to_string(),
|
||||
preview_image_name: "RC_Splash_Screen_01_Japanese".to_string(),
|
||||
is_default: true,
|
||||
}.as_transmissible(),
|
||||
@@ -68,7 +68,7 @@ pub(super) fn all_customisations_provider() -> SimpleFunc<216, crate::UserTy, im
|
||||
id: "Spawn_Warp".to_string(),
|
||||
localised_name: "strSpawnFXWarpIn".to_string(),
|
||||
skin_scene_name: "Splash_Loading_Screen".to_string(),
|
||||
simulation_prefab: "Respawn_WarpIn".to_string(),
|
||||
simulation_prefab: "Spawn_Warp".to_string(),
|
||||
preview_image_name: "RC_Splash_Screen_01_Japanese".to_string(),
|
||||
is_default: true,
|
||||
}.as_transmissible(),
|
||||
@@ -76,7 +76,7 @@ pub(super) fn all_customisations_provider() -> SimpleFunc<216, crate::UserTy, im
|
||||
id: "Spawn_Present".to_string(),
|
||||
localised_name: "strSpawnFXWarpIn".to_string(),
|
||||
skin_scene_name: "Splash_Loading_Screen".to_string(),
|
||||
simulation_prefab: "Respawn_WarpIn".to_string(),
|
||||
simulation_prefab: "Spawn_Present".to_string(),
|
||||
preview_image_name: "RC_Splash_Screen_01_Japanese".to_string(),
|
||||
is_default: true,
|
||||
}.as_transmissible(),
|
||||
@@ -84,7 +84,7 @@ pub(super) fn all_customisations_provider() -> SimpleFunc<216, crate::UserTy, im
|
||||
id: "Spawn_EasterEgg".to_string(),
|
||||
localised_name: "strSpawnFXWarpIn".to_string(),
|
||||
skin_scene_name: "Splash_Loading_Screen".to_string(),
|
||||
simulation_prefab: "Respawn_WarpIn".to_string(),
|
||||
simulation_prefab: "Spawn_EasterEgg".to_string(),
|
||||
preview_image_name: "RC_Splash_Screen_01_Japanese".to_string(),
|
||||
is_default: true,
|
||||
}.as_transmissible(),
|
||||
@@ -98,7 +98,7 @@ pub(super) fn all_customisations_provider() -> SimpleFunc<216, crate::UserTy, im
|
||||
id: "Explosion".to_string(),
|
||||
localised_name: "strDeathFXEmergencyWarp".to_string(),
|
||||
skin_scene_name: "Splash_Loading_Screen".to_string(),
|
||||
simulation_prefab: "Death_WarpOut".to_string(),
|
||||
simulation_prefab: "Explosion".to_string(),
|
||||
preview_image_name: "RC_Splash_Screen_01_Japanese".to_string(),
|
||||
is_default: true,
|
||||
}.as_transmissible(),
|
||||
@@ -106,7 +106,7 @@ pub(super) fn all_customisations_provider() -> SimpleFunc<216, crate::UserTy, im
|
||||
id: "Explosion_Toon".to_string(),
|
||||
localised_name: "strDeathFXEmergencyWarp".to_string(),
|
||||
skin_scene_name: "Splash_Loading_Screen".to_string(),
|
||||
simulation_prefab: "Death_WarpOut".to_string(),
|
||||
simulation_prefab: "Explosion_Toon".to_string(),
|
||||
preview_image_name: "RC_Splash_Screen_01_Japanese".to_string(),
|
||||
is_default: true,
|
||||
}.as_transmissible(),
|
||||
@@ -114,7 +114,7 @@ pub(super) fn all_customisations_provider() -> SimpleFunc<216, crate::UserTy, im
|
||||
id: "Explosion_Feathers_Rainbow".to_string(),
|
||||
localised_name: "strDeathFXEmergencyWarp".to_string(),
|
||||
skin_scene_name: "Splash_Loading_Screen".to_string(),
|
||||
simulation_prefab: "Death_WarpOut".to_string(),
|
||||
simulation_prefab: "Explosion_Feathers_Rainbow".to_string(),
|
||||
preview_image_name: "RC_Splash_Screen_01_Japanese".to_string(),
|
||||
is_default: true,
|
||||
}.as_transmissible(),
|
||||
@@ -122,7 +122,7 @@ pub(super) fn all_customisations_provider() -> SimpleFunc<216, crate::UserTy, im
|
||||
id: "Explosion_Nuclear".to_string(),
|
||||
localised_name: "strDeathFXEmergencyWarp".to_string(),
|
||||
skin_scene_name: "Splash_Loading_Screen".to_string(),
|
||||
simulation_prefab: "Death_WarpOut".to_string(),
|
||||
simulation_prefab: "Explosion_Nuclear".to_string(),
|
||||
preview_image_name: "RC_Splash_Screen_01_Japanese".to_string(),
|
||||
is_default: true,
|
||||
}.as_transmissible(),
|
||||
@@ -130,7 +130,7 @@ pub(super) fn all_customisations_provider() -> SimpleFunc<216, crate::UserTy, im
|
||||
id: "Explosion_Warp".to_string(),
|
||||
localised_name: "strDeathFXEmergencyWarp".to_string(),
|
||||
skin_scene_name: "Splash_Loading_Screen".to_string(),
|
||||
simulation_prefab: "Death_WarpOut".to_string(),
|
||||
simulation_prefab: "Explosion_Warp".to_string(),
|
||||
preview_image_name: "RC_Splash_Screen_01_Japanese".to_string(),
|
||||
is_default: true,
|
||||
}.as_transmissible(),
|
||||
@@ -138,7 +138,7 @@ pub(super) fn all_customisations_provider() -> SimpleFunc<216, crate::UserTy, im
|
||||
id: "Explosion_BlackHole".to_string(),
|
||||
localised_name: "strDeathFXEmergencyWarp".to_string(),
|
||||
skin_scene_name: "Splash_Loading_Screen".to_string(),
|
||||
simulation_prefab: "Death_WarpOut".to_string(),
|
||||
simulation_prefab: "Explosion_BlackHole".to_string(),
|
||||
preview_image_name: "RC_Splash_Screen_01_Japanese".to_string(),
|
||||
is_default: true,
|
||||
}.as_transmissible(),
|
||||
@@ -146,7 +146,7 @@ pub(super) fn all_customisations_provider() -> SimpleFunc<216, crate::UserTy, im
|
||||
id: "Explosion_Firework".to_string(),
|
||||
localised_name: "strDeathFXEmergencyWarp".to_string(),
|
||||
skin_scene_name: "Splash_Loading_Screen".to_string(),
|
||||
simulation_prefab: "Death_WarpOut".to_string(),
|
||||
simulation_prefab: "Explosion_Firework".to_string(),
|
||||
preview_image_name: "RC_Splash_Screen_01_Japanese".to_string(),
|
||||
is_default: true,
|
||||
}.as_transmissible(),
|
||||
|
||||
@@ -13,14 +13,14 @@ pub(super) fn client_config_provider() -> SimpleFunc<34, crate::UserTy, impl (Fn
|
||||
val_ty: TypePrefix::HashMap, // hashtable
|
||||
items: vec![
|
||||
(Typed::Str("GameplaySettings".into()), GameplaySettings {
|
||||
show_tutorial_after_date: "2025-01-01".to_owned(),
|
||||
health_threshold: 10.0,
|
||||
show_tutorial_after_date: "2030-01-01".to_owned(),
|
||||
health_threshold: 0.20,
|
||||
microbot_sphere: 10.0,
|
||||
misfire_angle: 20.0,
|
||||
misfire_angle: 10.0,
|
||||
shield_dps: 100,
|
||||
shield_hps: 2_000,
|
||||
request_review_level: 10_000,
|
||||
critical_ratio: 10.0,
|
||||
critical_ratio: 5.0,
|
||||
cross_promo_image: "https://git.ngram.ca/assets/img/logo.png".to_owned(),
|
||||
cross_promo_link: "https://git.ngram.ca/OpenJam/servers".to_owned(),
|
||||
}.as_transmissible())
|
||||
|
||||
@@ -12,8 +12,8 @@ pub(super) fn cpu_config_provider() -> SimpleFunc<75, crate::UserTy, impl (Fn(Pa
|
||||
premium_for_life_cosmetic_gpu: 12,
|
||||
premium_cosmetic_cpu: 6,
|
||||
no_premium_cosmetic_cpu: 3,
|
||||
max_regular_health: 2_000_000,
|
||||
max_megabot_health: 200_000_000,
|
||||
max_regular_health: 200_000_000,
|
||||
max_megabot_health: 2_000_000_000,
|
||||
}.as_transmissible());
|
||||
Ok(params.into())
|
||||
})
|
||||
|
||||
@@ -14,9 +14,9 @@ pub(super) fn damage_boost_provider() -> SimpleFunc<163, crate::UserTy, impl (Fn
|
||||
items: vec![
|
||||
(Typed::Str("damageBoost".into()), DamageBoostData {
|
||||
damage_map: vec![
|
||||
(100, 1000.0),
|
||||
(1000, 100.0),
|
||||
(0, 1.0),
|
||||
(2000, 1.0),
|
||||
(10_000, 1.0),
|
||||
],
|
||||
}.as_transmissible())
|
||||
],
|
||||
|
||||
@@ -76,16 +76,3 @@ pub(super) fn garage_machine_save_provider() -> SimpleFunc<41, crate::UserTy, im
|
||||
})
|
||||
}
|
||||
|
||||
pub const DEFAULT_WEAPON_ORDER_PARAM_KEY: u8 = 138;
|
||||
|
||||
pub(super) fn weapon_order_provider() -> SimpleFunc<118, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
|
||||
SimpleFunc::new(|params, user: &crate::UserTy| {
|
||||
let mut params = params.to_dict();
|
||||
let lock = user.read().unwrap();
|
||||
let user_info = lock.user()?;
|
||||
let weapon_order = user_info.slot_by_id(user_info.selected_garage_slot() as i32)?.weapon_order;
|
||||
params.insert(DEFAULT_WEAPON_ORDER_PARAM_KEY, weapon_order);
|
||||
Ok(params.into())
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@ mod validate_machine;
|
||||
mod game_mode_config;
|
||||
mod score_multipliers_config;
|
||||
mod player_robot_rank;
|
||||
mod weapon_order;
|
||||
|
||||
use polariton_server::operations::OperationsHandler;
|
||||
|
||||
@@ -150,7 +151,7 @@ pub fn handler(init_ctx: &crate::InitConfig) -> OperationsHandler<crate::UserTy>
|
||||
.without_state(prebuilt_robots::garage_robot_data_provider())
|
||||
.without_state(prebuilt_colours::garage_colour_combo_provider())
|
||||
.without_state(robopass_preview_items::robopass_preview_provider())
|
||||
.without_state(singleplayer_campaigns::singleplayer_campaigns_provider())
|
||||
.without_state(singleplayer_campaigns::singleplayer_campaigns_provider(&init_ctx.cubes))
|
||||
.without_state(purchases::pending_purchases_provider())
|
||||
.without_state(building_xp_config::building_xp_config_provider())
|
||||
.without_state(weapon_rating_static::weapon_rating_provider())
|
||||
@@ -168,7 +169,7 @@ pub fn handler(init_ctx: &crate::InitConfig) -> OperationsHandler<crate::UserTy>
|
||||
.without_state(machine::garage_machine_save_provider())
|
||||
.without_state(polariton_server::operations::Ack::<32, _>::default()) // TODO handle SaveMachineColorRequest instead of ignoring it
|
||||
.without_state(polariton_server::operations::Ack::<45, _>::default()) // TODO handle UpdateThumbnailVersionRequest instead of ignoring it
|
||||
.without_state(machine::weapon_order_provider())
|
||||
.without_state(weapon_order::weapon_order_provider(&init_ctx.cubes))
|
||||
.without_state(regen_config::auto_regen_config_provider(&init_ctx.cubes))
|
||||
.without_state(pageantry::after_battle_vote_thresholds_provider(&init_ctx.cubes))
|
||||
.without_state(signup_time::user_signup_date_provider())
|
||||
@@ -176,4 +177,8 @@ pub fn handler(init_ctx: &crate::InitConfig) -> OperationsHandler<crate::UserTy>
|
||||
.without_state(game_mode_config::game_mode_config_provider(&init_ctx.cubes))
|
||||
.without_state(score_multipliers_config::tdm_ai_score_config_provider())
|
||||
.without_state(player_robot_rank::player_robot_rank_provider())
|
||||
.without_state(validate_machine::validate_campaign_robot_provider())
|
||||
.without_state(singleplayer_campaigns::singleplayer_complete_campaign_provider(&init_ctx.cubes))
|
||||
.without_state(polariton_server::operations::Ack::<78, _>::default()) // TODO handle SaveCampaignGameAwardsRequest instead of ignoring it
|
||||
.without_state(singleplayer_campaigns::singleplayer_save_complete_campaign_provider()) // TODO handle UpdatePlayerCompletedCampaignWaveRequest saving
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ pub(super) fn power_bar_provider() -> SimpleFunc<51, crate::UserTy, impl (Fn(Par
|
||||
SimpleFunc::new(|params, _| {
|
||||
let mut params = params.to_dict();
|
||||
params.insert(PARAM_KEY, Typed::HashMap(vec![
|
||||
(Typed::Str("refillRatePerSecond".into()), Typed::Float(1000.0)),
|
||||
(Typed::Str("powerForAllRobots".into()), Typed::Int(1_000_000 /* converted to u32 */)),
|
||||
(Typed::Str("refillRatePerSecond".into()), Typed::Float(1255.0)),
|
||||
(Typed::Str("powerForAllRobots".into()), Typed::Int(12_550 /* converted to u32 */)),
|
||||
].into()
|
||||
));
|
||||
Ok(params.into())
|
||||
|
||||
@@ -10,8 +10,8 @@ pub(super) fn bay_customisations_provider() -> SimpleFunc<218, crate::UserTy, im
|
||||
SimpleFunc::new(|params, _| {
|
||||
let mut params = params.to_dict();
|
||||
params.insert(BAY_SKIN_KEY, Typed::Str("RC_MothershipSkin_Neptune_01".into()));
|
||||
params.insert(SPAWN_EFFECT_KEY, Typed::Str("RE_todo_spawn_effect".into()));
|
||||
params.insert(DEATH_EFFECT_KEY, Typed::Str("RE_todo_death_effect".into()));
|
||||
params.insert(SPAWN_EFFECT_KEY, Typed::Str("Spawn_Warp".into()));
|
||||
params.insert(DEATH_EFFECT_KEY, Typed::Str("Explosion_Warp".into()));
|
||||
Ok(params.into())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,22 +1,65 @@
|
||||
use polariton_server::operations::SimpleFunc;
|
||||
use polariton_server::operations::{Immediate, SimpleFunc};
|
||||
use polariton::operation::{ParameterTable, Typed};
|
||||
|
||||
use crate::persist::config::ConfigProvider;
|
||||
|
||||
const CAMPAIGNS_BYTES_PARAM_KEY: u8 = 64; // list of bytes (serialised data)
|
||||
const CAMPAIGNS_WAVES_PARAM_KEY: u8 = 70; // hashtable
|
||||
const CAMPAIGNS_VERSIONS_PARAM_KEY: u8 = 69; // hashtable
|
||||
|
||||
pub(super) fn singleplayer_campaigns_provider() -> SimpleFunc<65, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
|
||||
SimpleFunc::new(|params, _| {
|
||||
pub(super) fn singleplayer_campaigns_provider(conf: &crate::persist::config::ConfigImpl) -> Immediate<65, crate::UserTy> {
|
||||
Immediate::new(|| {
|
||||
let mut params = std::collections::HashMap::new();
|
||||
params.insert(CAMPAIGNS_BYTES_PARAM_KEY, conf.campaigns_parameters()); // first 4 bytes are i32 for length of the rest
|
||||
//params.insert(CAMPAIGNS_BYTES_PARAM_KEY, Typed::Bytes(vec![0u8, 0u8, 0u8, 0u8].into())); // first 4 bytes are i32 for length of the rest
|
||||
params.insert(CAMPAIGNS_WAVES_PARAM_KEY, conf.campaign_waves());
|
||||
//params.insert(CAMPAIGNS_WAVES_PARAM_KEY, Typed::HashMap(vec![].into()));
|
||||
params.insert(CAMPAIGNS_VERSIONS_PARAM_KEY, conf.campaign_version());
|
||||
// params.insert(CAMPAIGNS_VERSIONS_PARAM_KEY, Typed::HashMap(vec![
|
||||
// (Typed::Str("CurrentVersionNumber".into()), Typed::Int(0)),
|
||||
// (Typed::Str("LockedCampaignsInfo".into()), Typed::HashMap(vec![
|
||||
// (Typed::Str("0".into()), Typed::Bool(false.into()))
|
||||
// ].into())),
|
||||
// ].into()));
|
||||
params.into()
|
||||
})
|
||||
}
|
||||
|
||||
const CAMPAIGN_ID_PARAM_KEY: u8 = 22; // string; in
|
||||
const CAMPAIGN_DIFFICULTY_PARAM_KEY: u8 = 23; // i32; in
|
||||
const CAMPAIGN_WAVES_PARAM_KEY: u8 = 75; // bytes; out
|
||||
|
||||
pub(super) fn singleplayer_complete_campaign_provider(conf: &crate::persist::config::ConfigImpl) -> SimpleFunc<64, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
|
||||
let campaign_details = <crate::persist::config::ConfigImpl as crate::persist::config::ConfigProvider<()>>::campaign_details(conf);
|
||||
SimpleFunc::new(move |params, _| {
|
||||
let mut params = params.to_dict();
|
||||
// TODO implement serialisation of Campaign[] properly
|
||||
params.insert(CAMPAIGNS_BYTES_PARAM_KEY, Typed::Bytes(vec![0u8, 0u8, 0u8, 0u8].into())); // first 4 bytes are i32 for length of the rest
|
||||
params.insert(CAMPAIGNS_WAVES_PARAM_KEY, Typed::HashMap(vec![].into()));
|
||||
params.insert(CAMPAIGNS_VERSIONS_PARAM_KEY, Typed::HashMap(vec![
|
||||
(Typed::Str("CurrentVersionNumber".into()), Typed::Int(0)),
|
||||
(Typed::Str("LockedCampaignsInfo".into()), Typed::HashMap(vec![
|
||||
(Typed::Str("0".into()), Typed::Bool(false.into()))
|
||||
].into())),
|
||||
].into()));
|
||||
if let Some(Typed::Str(campaign_id)) = params.get(&CAMPAIGN_ID_PARAM_KEY) {
|
||||
if let Some(Typed::Int(campaign_difficulty)) = params.get(&CAMPAIGN_DIFFICULTY_PARAM_KEY) {
|
||||
let complete_campaign = campaign_details.get(&campaign_id.string, campaign_difficulty)?;
|
||||
params.clear();
|
||||
params.insert(CAMPAIGN_WAVES_PARAM_KEY, complete_campaign);
|
||||
}
|
||||
}
|
||||
Ok(params.into())
|
||||
})
|
||||
}
|
||||
|
||||
const CAMPAIGN_WAVE_NUMBER_PARAM_KEYL: u8 = 73;
|
||||
|
||||
pub(super) fn singleplayer_save_complete_campaign_provider() -> SimpleFunc<68, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
|
||||
//let campaign_details = <crate::persist::config::ConfigImpl as crate::persist::config::ConfigProvider<()>>::campaign_details(conf);
|
||||
SimpleFunc::new(move |params, user: &crate::UserTy| {
|
||||
let mut params = params.to_dict();
|
||||
if let Some(Typed::Str(campaign_id)) = params.get(&CAMPAIGN_ID_PARAM_KEY) {
|
||||
if let Some(Typed::Int(campaign_difficulty)) = params.get(&CAMPAIGN_DIFFICULTY_PARAM_KEY) {
|
||||
if let Some(Typed::Int(wave_number)) = params.get(&CAMPAIGN_WAVE_NUMBER_PARAM_KEYL) {
|
||||
let user_lock = user.read().unwrap();
|
||||
log::info!("User {} completed campaign {} difficulty {} wave {}", user_lock.user()?.token().uuid, campaign_id.string, campaign_difficulty, wave_number);
|
||||
// TODO save wave as completed
|
||||
params.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(params.into())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -28,3 +28,19 @@ pub(super) fn validate_robot_provider() -> SimpleFunc<102, crate::UserTy, impl (
|
||||
Ok(params.into())
|
||||
})
|
||||
}
|
||||
|
||||
const CAMPAIGN_ID_PARAM_KEY: u8 = 22;
|
||||
|
||||
pub(super) fn validate_campaign_robot_provider() -> SimpleFunc<59, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
|
||||
SimpleFunc::new(|params, _user: &crate::UserTy| {
|
||||
let mut params = params.to_dict();
|
||||
if let Some(Typed::Str(campaign_id)) = params.get(&CAMPAIGN_ID_PARAM_KEY) {
|
||||
log::info!("Got campaign id {}", campaign_id.string);
|
||||
}
|
||||
// let lock = user.read().unwrap();
|
||||
// let user_info = lock.user()?;
|
||||
// TODO actually validate the vehicle
|
||||
params.insert(VALIDATE_ROBOT_RESULT_PARAM_KEY, Typed::Int(ValidateMachineResult::Ok as _)); // this is ignored
|
||||
Ok(params.into())
|
||||
})
|
||||
}
|
||||
|
||||
14
rc_services_room/src/operations/weapon_order.rs
Normal file
14
rc_services_room/src/operations/weapon_order.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
use polariton_server::operations::Immediate;
|
||||
|
||||
use crate::persist::config::ConfigProvider;
|
||||
|
||||
pub const DEFAULT_WEAPON_ORDER_PARAM_KEY: u8 = 138;
|
||||
|
||||
pub(super) fn weapon_order_provider(conf: &crate::persist::config::ConfigImpl) -> Immediate<118, crate::UserTy> {
|
||||
let weapon_orders = conf.weapon_keys();
|
||||
Immediate::new(|| {
|
||||
let mut params = std::collections::HashMap::with_capacity(1);
|
||||
params.insert(DEFAULT_WEAPON_ORDER_PARAM_KEY, weapon_orders.clone());
|
||||
params.into()
|
||||
})
|
||||
}
|
||||
@@ -8,6 +8,8 @@ pub struct BattleConfig {
|
||||
pub votes: HashMap<Vote, Vec<VoteThreshold>>,
|
||||
#[serde(default = "default_game_modes")]
|
||||
pub games: GameModes,
|
||||
#[serde(default = "default_campaigns")]
|
||||
pub singleplayer: super::Campaigns,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
@@ -129,3 +131,72 @@ fn default_game_modes() -> GameModes {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn default_campaigns() -> super::Campaigns {
|
||||
super::Campaigns {
|
||||
campaigns: vec![
|
||||
super::Campaign {
|
||||
id: "strCampaignModeBattle".to_owned(),
|
||||
excluded_cubes: Vec::default(),
|
||||
categories: vec![super::ItemCategory::Wheel],
|
||||
min_cpu: 0,
|
||||
max_cpu: 2_000,
|
||||
name: "strCampaignModeBattle".to_owned(),
|
||||
description: "strCampaignsDesc".to_owned(),
|
||||
image: "RE_singleplayer_campaign_image_asset_TODO".to_owned(),
|
||||
rules: Vec::default(),
|
||||
parameters: Vec::default(),
|
||||
difficulties: vec![
|
||||
super::CampaignDifficulty {
|
||||
level: 0,
|
||||
lives: 5,
|
||||
auto_heal: true,
|
||||
single_wave_bonus: 1_000,
|
||||
initial_health_boost: 0.0,
|
||||
health_boost_wave_increase: 0.0,
|
||||
initial_damage_boost: 0.0,
|
||||
damage_boost_wave_increase: 0.0,
|
||||
}
|
||||
],
|
||||
completed: vec![
|
||||
super::CampaignCompletion {
|
||||
wave: 0,
|
||||
difficulty: false,
|
||||
}
|
||||
],
|
||||
map: "RC_Planet_Neptune_03_BA".to_owned(),
|
||||
campaign_type: super::CampaignType::Elimination,
|
||||
waves: vec![
|
||||
super::Wave {
|
||||
player_spawn_location: 0,
|
||||
robots_in_wave: vec![
|
||||
super::WaveRobot {
|
||||
name: "strCampaignAnimalName".to_owned(),
|
||||
weapon: "strT5PlasmaGoldenName".to_owned(),
|
||||
movement: "strT5SteeringWheelGoldenName".to_owned(),
|
||||
rank: "strT0".to_owned(),
|
||||
count: 5,
|
||||
robot_data: super::VALID_ROBOT.into(),
|
||||
colour_data: super::VALID_COLOUR.into(),
|
||||
time_to_spawn: 1,
|
||||
kills_to_spawn: 0,
|
||||
time_to_despawn: 60,
|
||||
kills_to_despawn: 1,
|
||||
initial_robot_amount: 0,
|
||||
periodic_robot_amount: 3,
|
||||
spawn_interval: 1,
|
||||
min_robot_amount: 1,
|
||||
max_robot_amount: 5,
|
||||
is_boss: false,
|
||||
is_kill_requirement: true,
|
||||
}
|
||||
],
|
||||
kill_target: 1,
|
||||
time_min: 1,
|
||||
time_max: 1 * 60,
|
||||
}
|
||||
],
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,6 +125,18 @@ impl <C: Clone> super::ConfigProvider<C> for CubeConfig {
|
||||
Typed::ObjArr(weapon_upgrades.into())
|
||||
}
|
||||
|
||||
fn weapon_keys(&self) -> Typed<C> {
|
||||
let mut seen_keys = std::collections::HashSet::new();
|
||||
for cube in self.cubes.values() {
|
||||
if cube.weapon.is_some() {
|
||||
let key = crate::data::cube_list::item_key(cube.info.category.into(), cube.info.size.into());
|
||||
seen_keys.insert(key);
|
||||
}
|
||||
}
|
||||
let keys_vec: Vec<i32> = seen_keys.into_iter().collect();
|
||||
Typed::IntArr(keys_vec.into())
|
||||
}
|
||||
|
||||
fn tech_tree_nodes(&self, unlocked_cubes: &std::collections::HashSet<u32>) -> Typed<C> {
|
||||
let mut seen_cubes = std::collections::HashSet::with_capacity(self.cubes.len());
|
||||
let mut needed_cubes = std::collections::HashSet::with_capacity(self.cubes.len());
|
||||
@@ -182,4 +194,41 @@ impl <C: Clone> super::ConfigProvider<C> for CubeConfig {
|
||||
let game_mode_data: crate::data::game_mode::GameModeConfigs = self.battle.games.into();
|
||||
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);
|
||||
}
|
||||
map.insert(campaign.id.clone(), difficulty_map);
|
||||
}
|
||||
super::CompleteCampaignProvider::new(map)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ mod cubes_json;
|
||||
pub use cubes_json::CubeConfig;
|
||||
|
||||
mod traits;
|
||||
pub use traits::ConfigProvider;
|
||||
pub use traits::{ConfigProvider, CompleteCampaignProvider};
|
||||
|
||||
pub type ConfigImpl = CubeConfig;
|
||||
|
||||
|
||||
@@ -5,9 +5,38 @@ pub trait ConfigProvider<C> {
|
||||
fn movement_list(&self) -> Typed<C>;
|
||||
fn weapon_list(&self) -> Typed<C>;
|
||||
fn weapon_upgrade_list(&self) -> Typed<C>;
|
||||
fn weapon_keys(&self) -> Typed<C>;
|
||||
fn tech_tree_nodes(&self, unlocked_cubes: &std::collections::HashSet<u32>) -> Typed<C>;
|
||||
fn ids(&self) -> Vec<u32>;
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,3 +19,786 @@ pub use tech_tree::TechTreeData;
|
||||
|
||||
mod combat;
|
||||
pub use combat::BattleConfig;
|
||||
|
||||
mod singleplayer;
|
||||
pub use singleplayer::{Campaigns, Campaign, CampaignDifficulty, CampaignCompletion, CampaignType, Wave, WaveRobot};
|
||||
|
||||
// TODO put this in core lib
|
||||
|
||||
pub(self) const VALID_ROBOT: &[u8] = &[64,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
38,
|
||||
190,
|
||||
25,
|
||||
77,
|
||||
24,
|
||||
6,
|
||||
29,
|
||||
0,
|
||||
80,
|
||||
135,
|
||||
103,
|
||||
211,
|
||||
27,
|
||||
4,
|
||||
27,
|
||||
6,
|
||||
80,
|
||||
135,
|
||||
103,
|
||||
211,
|
||||
21,
|
||||
4,
|
||||
27,
|
||||
12,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
24,
|
||||
4,
|
||||
26,
|
||||
0,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
24,
|
||||
4,
|
||||
27,
|
||||
22,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
24,
|
||||
4,
|
||||
28,
|
||||
22,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
24,
|
||||
4,
|
||||
25,
|
||||
0,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
24,
|
||||
4,
|
||||
29,
|
||||
0,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
23,
|
||||
4,
|
||||
29,
|
||||
0,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
23,
|
||||
4,
|
||||
28,
|
||||
0,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
23,
|
||||
4,
|
||||
27,
|
||||
0,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
23,
|
||||
4,
|
||||
26,
|
||||
22,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
23,
|
||||
4,
|
||||
25,
|
||||
22,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
25,
|
||||
4,
|
||||
29,
|
||||
0,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
25,
|
||||
4,
|
||||
27,
|
||||
22,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
25,
|
||||
4,
|
||||
28,
|
||||
22,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
25,
|
||||
4,
|
||||
26,
|
||||
22,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
25,
|
||||
4,
|
||||
25,
|
||||
22,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
26,
|
||||
4,
|
||||
29,
|
||||
0,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
26,
|
||||
4,
|
||||
28,
|
||||
22,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
26,
|
||||
4,
|
||||
27,
|
||||
22,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
26,
|
||||
4,
|
||||
26,
|
||||
22,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
26,
|
||||
4,
|
||||
25,
|
||||
22,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
22,
|
||||
4,
|
||||
25,
|
||||
0,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
22,
|
||||
4,
|
||||
26,
|
||||
0,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
22,
|
||||
4,
|
||||
27,
|
||||
23,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
22,
|
||||
4,
|
||||
28,
|
||||
23,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
22,
|
||||
4,
|
||||
29,
|
||||
0,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
25,
|
||||
5,
|
||||
29,
|
||||
0,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
23,
|
||||
5,
|
||||
29,
|
||||
0,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
24,
|
||||
5,
|
||||
29,
|
||||
0,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
22,
|
||||
5,
|
||||
28,
|
||||
0,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
26,
|
||||
5,
|
||||
28,
|
||||
0,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
25,
|
||||
5,
|
||||
26,
|
||||
0,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
23,
|
||||
5,
|
||||
26,
|
||||
0,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
24,
|
||||
4,
|
||||
24,
|
||||
22,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
24,
|
||||
4,
|
||||
23,
|
||||
22,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
24,
|
||||
4,
|
||||
22,
|
||||
22,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
24,
|
||||
4,
|
||||
21,
|
||||
22,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
24,
|
||||
4,
|
||||
20,
|
||||
22,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
24,
|
||||
4,
|
||||
19,
|
||||
22,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
24,
|
||||
4,
|
||||
18,
|
||||
22,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
24,
|
||||
4,
|
||||
17,
|
||||
22,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
24,
|
||||
4,
|
||||
16,
|
||||
22,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
24,
|
||||
4,
|
||||
15,
|
||||
22,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
24,
|
||||
4,
|
||||
14,
|
||||
22,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
23,
|
||||
4,
|
||||
17,
|
||||
12,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
25,
|
||||
4,
|
||||
17,
|
||||
6,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
23,
|
||||
4,
|
||||
16,
|
||||
12,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
25,
|
||||
4,
|
||||
16,
|
||||
6,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
23,
|
||||
4,
|
||||
15,
|
||||
12,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
25,
|
||||
4,
|
||||
15,
|
||||
6,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
23,
|
||||
4,
|
||||
14,
|
||||
12,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
25,
|
||||
4,
|
||||
14,
|
||||
6,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
22,
|
||||
4,
|
||||
17,
|
||||
12,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
26,
|
||||
4,
|
||||
17,
|
||||
6,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
22,
|
||||
4,
|
||||
16,
|
||||
12,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
26,
|
||||
4,
|
||||
16,
|
||||
6,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
22,
|
||||
4,
|
||||
15,
|
||||
12,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
26,
|
||||
4,
|
||||
15,
|
||||
6,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
22,
|
||||
4,
|
||||
14,
|
||||
12,
|
||||
198,
|
||||
224,
|
||||
138,
|
||||
13,
|
||||
26,
|
||||
4,
|
||||
14,
|
||||
6,
|
||||
240,
|
||||
75,
|
||||
110,
|
||||
137,
|
||||
21,
|
||||
4,
|
||||
15,
|
||||
12,
|
||||
240,
|
||||
75,
|
||||
110,
|
||||
137,
|
||||
27,
|
||||
4,
|
||||
15,
|
||||
6];
|
||||
|
||||
pub(self) const VALID_COLOUR: &[u8] = &[64,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
24,
|
||||
6,
|
||||
29,
|
||||
0,
|
||||
27,
|
||||
4,
|
||||
27,
|
||||
0,
|
||||
21,
|
||||
4,
|
||||
27,
|
||||
0,
|
||||
24,
|
||||
4,
|
||||
26,
|
||||
0,
|
||||
24,
|
||||
4,
|
||||
27,
|
||||
0,
|
||||
24,
|
||||
4,
|
||||
28,
|
||||
0,
|
||||
24,
|
||||
4,
|
||||
25,
|
||||
0,
|
||||
24,
|
||||
4,
|
||||
29,
|
||||
0,
|
||||
23,
|
||||
4,
|
||||
29,
|
||||
0,
|
||||
23,
|
||||
4,
|
||||
28,
|
||||
0,
|
||||
23,
|
||||
4,
|
||||
27,
|
||||
0,
|
||||
23,
|
||||
4,
|
||||
26,
|
||||
0,
|
||||
23,
|
||||
4,
|
||||
25,
|
||||
0,
|
||||
25,
|
||||
4,
|
||||
29,
|
||||
0,
|
||||
25,
|
||||
4,
|
||||
27,
|
||||
0,
|
||||
25,
|
||||
4,
|
||||
28,
|
||||
0,
|
||||
25,
|
||||
4,
|
||||
26,
|
||||
0,
|
||||
25,
|
||||
4,
|
||||
25,
|
||||
0,
|
||||
26,
|
||||
4,
|
||||
29,
|
||||
0,
|
||||
26,
|
||||
4,
|
||||
28,
|
||||
0,
|
||||
26,
|
||||
4,
|
||||
27,
|
||||
0,
|
||||
26,
|
||||
4,
|
||||
26,
|
||||
0,
|
||||
26,
|
||||
4,
|
||||
25,
|
||||
0,
|
||||
22,
|
||||
4,
|
||||
25,
|
||||
0,
|
||||
22,
|
||||
4,
|
||||
26,
|
||||
0,
|
||||
22,
|
||||
4,
|
||||
27,
|
||||
0,
|
||||
22,
|
||||
4,
|
||||
28,
|
||||
0,
|
||||
22,
|
||||
4,
|
||||
29,
|
||||
1,
|
||||
25,
|
||||
5,
|
||||
29,
|
||||
1,
|
||||
23,
|
||||
5,
|
||||
29,
|
||||
1,
|
||||
24,
|
||||
5,
|
||||
29,
|
||||
1,
|
||||
22,
|
||||
5,
|
||||
28,
|
||||
1,
|
||||
26,
|
||||
5,
|
||||
28,
|
||||
1,
|
||||
25,
|
||||
5,
|
||||
26,
|
||||
1,
|
||||
23,
|
||||
5,
|
||||
26,
|
||||
0,
|
||||
24,
|
||||
4,
|
||||
24,
|
||||
0,
|
||||
24,
|
||||
4,
|
||||
23,
|
||||
0,
|
||||
24,
|
||||
4,
|
||||
22,
|
||||
0,
|
||||
24,
|
||||
4,
|
||||
21,
|
||||
0,
|
||||
24,
|
||||
4,
|
||||
20,
|
||||
0,
|
||||
24,
|
||||
4,
|
||||
19,
|
||||
0,
|
||||
24,
|
||||
4,
|
||||
18,
|
||||
0,
|
||||
24,
|
||||
4,
|
||||
17,
|
||||
0,
|
||||
24,
|
||||
4,
|
||||
16,
|
||||
0,
|
||||
24,
|
||||
4,
|
||||
15,
|
||||
0,
|
||||
24,
|
||||
4,
|
||||
14,
|
||||
0,
|
||||
23,
|
||||
4,
|
||||
17,
|
||||
0,
|
||||
25,
|
||||
4,
|
||||
17,
|
||||
0,
|
||||
23,
|
||||
4,
|
||||
16,
|
||||
0,
|
||||
25,
|
||||
4,
|
||||
16,
|
||||
0,
|
||||
23,
|
||||
4,
|
||||
15,
|
||||
0,
|
||||
25,
|
||||
4,
|
||||
15,
|
||||
0,
|
||||
23,
|
||||
4,
|
||||
14,
|
||||
0,
|
||||
25,
|
||||
4,
|
||||
14,
|
||||
0,
|
||||
22,
|
||||
4,
|
||||
17,
|
||||
0,
|
||||
26,
|
||||
4,
|
||||
17,
|
||||
0,
|
||||
22,
|
||||
4,
|
||||
16,
|
||||
0,
|
||||
26,
|
||||
4,
|
||||
16,
|
||||
0,
|
||||
22,
|
||||
4,
|
||||
15,
|
||||
0,
|
||||
26,
|
||||
4,
|
||||
15,
|
||||
0,
|
||||
22,
|
||||
4,
|
||||
14,
|
||||
0,
|
||||
26,
|
||||
4,
|
||||
14,
|
||||
0,
|
||||
21,
|
||||
4,
|
||||
15,
|
||||
0,
|
||||
27,
|
||||
4,
|
||||
15];
|
||||
|
||||
224
rc_services_room/src/persist/singleplayer.rs
Normal file
224
rc_services_room/src/persist/singleplayer.rs
Normal file
@@ -0,0 +1,224 @@
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct Campaigns {
|
||||
pub campaigns: Vec<Campaign>,
|
||||
}
|
||||
|
||||
impl Campaigns {
|
||||
pub fn into_campaign_params(self) -> crate::data::campaign::CampaignsGameParameters {
|
||||
crate::data::campaign::CampaignsGameParameters { campaigns: self.campaigns.into_iter().map(|x| x.into_campaign_params()).collect() }
|
||||
}
|
||||
|
||||
pub fn into_waves(self) -> crate::data::campaign::LiveCampaignWaves {
|
||||
crate::data::campaign::LiveCampaignWaves { waves: self.campaigns.into_iter().map(|x| x.into_waves()).collect() }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct Campaign {
|
||||
pub id: String,
|
||||
pub excluded_cubes: Vec<u32>, // encoded to hex strings
|
||||
pub categories: Vec<super::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<CampaignDifficulty>,
|
||||
pub completed: Vec<CampaignCompletion>,
|
||||
pub map: String,
|
||||
pub campaign_type: CampaignType,
|
||||
pub waves: Vec<Wave>,
|
||||
}
|
||||
|
||||
impl Campaign {
|
||||
pub fn into_campaign_params(self) -> crate::data::campaign::CampaignParameters {
|
||||
crate::data::campaign::CampaignParameters {
|
||||
id: self.id,
|
||||
excluded_cubes: self.excluded_cubes,
|
||||
categories: self.categories.into_iter().map(|x| x.into()).collect(),
|
||||
min_cpu: self.min_cpu,
|
||||
max_cpu: self.max_cpu,
|
||||
name: self.name,
|
||||
description: self.description,
|
||||
image: self.image,
|
||||
rules: self.rules,
|
||||
parameters: self.parameters,
|
||||
difficulties: self.difficulties.into_iter().map(|x| x.into()).collect(),
|
||||
completed: self.completed.into_iter().enumerate().map(|(i, x)| x.into_data(i as _)).collect(),
|
||||
map: self.map,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_waves(self) -> crate::data::campaign::WavesData {
|
||||
crate::data::campaign::WavesData {
|
||||
id: self.id,
|
||||
waves: self.waves.into_iter().map(|x| x.into()).collect(),
|
||||
campaign_type: self.campaign_type.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct CampaignDifficulty {
|
||||
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 std::convert::Into<crate::data::campaign::CampaignDifficultyData> for CampaignDifficulty {
|
||||
fn into(self) -> crate::data::campaign::CampaignDifficultyData {
|
||||
crate::data::campaign::CampaignDifficultyData {
|
||||
level: self.level,
|
||||
lives: self.lives,
|
||||
auto_heal: self.auto_heal,
|
||||
single_wave_bonus: self.single_wave_bonus,
|
||||
initial_health_boost: self.initial_health_boost,
|
||||
health_boost_wave_increase: self.health_boost_wave_increase,
|
||||
initial_damage_boost: self.initial_damage_boost,
|
||||
damage_boost_wave_increase: self.damage_boost_wave_increase,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct CampaignCompletion {
|
||||
pub wave: i32,
|
||||
pub difficulty: bool,
|
||||
}
|
||||
|
||||
impl CampaignCompletion {
|
||||
pub fn into_data(self, index: i32) -> crate::data::campaign::CampaignCompletionData {
|
||||
crate::data::campaign::CampaignCompletionData {
|
||||
index,
|
||||
wave: self.wave,
|
||||
difficulty: self.difficulty,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct Wave {
|
||||
#[serde(default)]
|
||||
pub player_spawn_location: i32,
|
||||
pub robots_in_wave: Vec<WaveRobot>,
|
||||
pub kill_target: i32,
|
||||
#[serde(default)]
|
||||
pub time_min: i32,
|
||||
pub time_max: i32,
|
||||
}
|
||||
|
||||
impl std::convert::Into<crate::data::campaign::WaveData> for Wave {
|
||||
fn into(self) -> crate::data::campaign::WaveData {
|
||||
crate::data::campaign::WaveData {
|
||||
robots_in_wave: self.robots_in_wave.into_iter().map(|x| x.into()).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::Into<crate::data::campaign::CompleteWaveData> for Wave {
|
||||
fn into(self) -> crate::data::campaign::CompleteWaveData {
|
||||
crate::data::campaign::CompleteWaveData {
|
||||
player_spawn_location: self.player_spawn_location,
|
||||
robots_in_wave: self.robots_in_wave.into_iter().map(|x| x.into()).collect(),
|
||||
kill_target: self.kill_target,
|
||||
time_min: self.time_min,
|
||||
time_max: self.time_max,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct WaveRobot { // times appear to be in seconds
|
||||
pub name: String,
|
||||
pub weapon: String,
|
||||
pub movement: String,
|
||||
pub rank: String,
|
||||
pub count: i32,
|
||||
pub robot_data: Vec<u8>,
|
||||
pub colour_data: Vec<u8>,
|
||||
#[serde(default)]
|
||||
pub time_to_spawn: i32,
|
||||
#[serde(default)]
|
||||
pub kills_to_spawn: i32,
|
||||
#[serde(default)]
|
||||
pub time_to_despawn: i32,
|
||||
#[serde(default)]
|
||||
pub kills_to_despawn: i32,
|
||||
#[serde(default = "default_1")]
|
||||
pub initial_robot_amount: i32,
|
||||
#[serde(default)]
|
||||
pub periodic_robot_amount: i32,
|
||||
#[serde(default = "default_1")]
|
||||
pub spawn_interval: i32,
|
||||
#[serde(default = "default_1")]
|
||||
pub min_robot_amount: i32,
|
||||
#[serde(default)]
|
||||
pub max_robot_amount: i32,
|
||||
#[serde(default)]
|
||||
pub is_boss: bool,
|
||||
#[serde(default)]
|
||||
pub is_kill_requirement: bool,
|
||||
}
|
||||
|
||||
fn default_1() -> i32 {
|
||||
1
|
||||
}
|
||||
|
||||
impl std::convert::Into<crate::data::campaign::WaveRobotData> for WaveRobot {
|
||||
fn into(self) -> crate::data::campaign::WaveRobotData {
|
||||
crate::data::campaign::WaveRobotData {
|
||||
name: self.name,
|
||||
weapon: self.weapon,
|
||||
movement: self.movement,
|
||||
rank: self.rank,
|
||||
count: self.count,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::Into<crate::data::campaign::CompleteWaveRobotData> for WaveRobot {
|
||||
fn into(self) -> crate::data::campaign::CompleteWaveRobotData {
|
||||
crate::data::campaign::CompleteWaveRobotData {
|
||||
name: self.name,
|
||||
robot_data: self.robot_data,
|
||||
colour_data: self.colour_data,
|
||||
time_to_spawn: self.time_to_spawn,
|
||||
kills_to_spawn: self.kills_to_spawn,
|
||||
time_to_despawn: self.time_to_despawn,
|
||||
kills_to_despawn: self.kills_to_despawn,
|
||||
initial_robot_amount: self.initial_robot_amount,
|
||||
periodic_robot_amount: self.periodic_robot_amount,
|
||||
spawn_interval: self.spawn_interval,
|
||||
min_robot_amount: self.min_robot_amount,
|
||||
max_robot_amount: self.max_robot_amount,
|
||||
is_boss: self.is_boss,
|
||||
is_kill_requirement: self.is_kill_requirement,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, Copy)]
|
||||
pub enum CampaignType {
|
||||
TimedElimination = 0,
|
||||
Survival = 1,
|
||||
Elimination = 2,
|
||||
}
|
||||
|
||||
impl std::convert::Into<crate::data::campaign::CampaignType> for CampaignType {
|
||||
fn into(self) -> crate::data::campaign::CampaignType {
|
||||
match self {
|
||||
Self::TimedElimination => crate::data::campaign::CampaignType::TimedElimination,
|
||||
Self::Survival => crate::data::campaign::CampaignType::Survival,
|
||||
Self::Elimination => crate::data::campaign::CampaignType::Elimination,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,18 +10,28 @@ pub struct WeaponData {
|
||||
pub base_inaccuracy: Option<f32>,
|
||||
pub base_air_inaccuracy: Option<f32>,
|
||||
pub movement_inaccuracy: Option<f32>,
|
||||
#[serde(alias="movement_max_threshold_speed")]
|
||||
pub movement_max_speed: Option<f32>,
|
||||
#[serde(alias="movement_min_threshold_speed")]
|
||||
pub movement_min_speed: Option<f32>,
|
||||
#[serde(alias="gun_rotation_threshold_slow")]
|
||||
pub gun_rotation_slow: Option<f32>,
|
||||
#[serde(alias="movement_inaccuracy_decay_time")]
|
||||
pub movement_inaccuracy_decay: Option<f32>,
|
||||
#[serde(alias="slow_rotation_inaccuracy_decay_time")]
|
||||
pub slow_rotation_decay: Option<f32>,
|
||||
#[serde(alias="quick_rotation_inaccuracy_decay_time")]
|
||||
pub quick_rotation_decay: Option<f32>,
|
||||
#[serde(alias="movement_inaccuracy_recovery_time")]
|
||||
pub movement_inaccuracy_recovery: Option<f32>,
|
||||
pub repeat_fire_inaccuracy_total_degrees: Option<f32>,
|
||||
#[serde(alias="repeat_fire_inaccuracy_decay_time")]
|
||||
pub repeat_fire_inaccuracy_decay: Option<f32>,
|
||||
#[serde(alias="repeat_fire_inaccuracy_recovery_time")]
|
||||
pub repeat_fire_innaccuracy_recovery: Option<f32>,
|
||||
pub fire_instant_accuracy_decay: Option<f32>, // degrees
|
||||
pub accuracy_non_recover_time: Option<f32>,
|
||||
#[serde(alias="accuracy_decay_time")]
|
||||
pub accuracy_decay: Option<f32>,
|
||||
pub damage_radius: Option<f32>,
|
||||
pub plasma_time_to_full_damage: Option<f32>,
|
||||
@@ -36,9 +46,12 @@ pub struct WeaponData {
|
||||
pub aeroflak_ground_clearance: Option<f32>,
|
||||
pub aeroflak_max_stacks: Option<i32>,
|
||||
pub aeroflak_damage_per_stack: Option<i32>,
|
||||
#[serde(alias="aeroflak_buff_time_to_expire")]
|
||||
pub aeroflak_stack_expire: Option<f32>,
|
||||
#[serde(alias="cooldown_between_shots")]
|
||||
pub shot_cooldown: Option<f32>,
|
||||
pub smart_rotation_cooldown: Option<f32>,
|
||||
#[serde(alias="smart_rotation_extra_cooldown_time")]
|
||||
pub smart_rotation_cooldown_extra: Option<f32>,
|
||||
pub smart_rotation_max_stacks: Option<f32>,
|
||||
pub spin_up_time: Option<f32>,
|
||||
|
||||
@@ -426,7 +426,7 @@ def main(asset_in, cubes=None, weapons=None, movement=None):
|
||||
"votes_required": 2,
|
||||
}
|
||||
],
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
last_tech_tree_id = 0
|
||||
|
||||
Reference in New Issue
Block a user