Files
ojrc/rc_core/src/persist/combat.rs
T

531 lines
18 KiB
Rust
Raw Normal View History

2025-03-15 17:21:18 -04:00
use std::collections::HashMap;
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct BattleConfig {
pub regen: AutoRegenHealth,
pub votes: HashMap<Vote, Vec<VoteThreshold>>,
#[serde(default = "default_game_modes")]
pub games: GameModes,
#[serde(default = "default_campaigns")]
2025-05-30 23:03:02 -04:00
pub singleplayer: super::SingleplayerConfig,
#[serde(default = "default_rotation")]
pub rotation: GameEventSequence,
#[serde(default = "default_multiplayer")]
pub multiplayer: super::MultiplayerConfig,
2025-07-26 11:47:05 -04:00
#[serde(default = "default_maps")]
pub maps: super::MapsConfig,
2025-08-17 15:03:30 -04:00
#[serde(default = "default_energy")]
pub energy: EnergyConfig,
2025-03-15 17:21:18 -04:00
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct AutoRegenHealth {
pub wait_for_heal_s: f32,
pub wait_full_heal_s: f32,
pub sound_start_s: f32,
pub auto_heal: bool,
}
2025-09-03 22:33:26 -04:00
impl std::convert::From<AutoRegenHealth> for crate::data::auto_regen::AutoRegenHealthConfig {
fn from(val: AutoRegenHealth) -> Self {
2025-03-15 17:21:18 -04:00
crate::data::auto_regen::AutoRegenHealthConfig {
2025-09-03 22:33:26 -04:00
seconds_to_wait_for_heal: val.wait_for_heal_s,
seconds_to_full_heal: val.wait_full_heal_s,
threshold_to_start_sound: val.sound_start_s,
enable_auto_heal: val.auto_heal,
2025-03-15 17:21:18 -04:00
}
}
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct VoteThreshold {
pub name: String,
pub localised_name: String,
pub color: String,
pub votes_required: i32,
}
2025-09-03 22:33:26 -04:00
impl std::convert::From<VoteThreshold> for crate::data::voting::VoteThresholdData {
fn from(val: VoteThreshold) -> Self {
2025-03-15 17:21:18 -04:00
crate::data::voting::VoteThresholdData {
2025-09-03 22:33:26 -04:00
name: val.name,
localised_name: val.localised_name,
color: val.color,
votes_required: val.votes_required,
2025-03-15 17:21:18 -04:00
}
}
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Hash)]
pub enum Vote {
BestPlayed,
BestLooking,
}
2025-09-03 22:33:26 -04:00
impl std::convert::From<Vote> for crate::data::voting::Vote {
fn from(val: Vote) -> Self {
match val {
Vote::BestPlayed => crate::data::voting::Vote::BestPlayed,
Vote::BestLooking => crate::data::voting::Vote::BestLooking,
2025-03-15 17:21:18 -04:00
}
}
}
#[derive(Serialize, Deserialize, Clone, Debug, Copy)]
pub struct GameMode {
pub respawn_heal_duration: f32,
pub respawn_full_heal_duration: f32,
pub kill_limit: i32,
pub game_time_m: i32,
}
2025-09-03 22:33:26 -04:00
impl std::convert::From<GameMode> for crate::data::game_mode::GameModeConfig {
fn from(val: GameMode) -> Self {
crate::data::game_mode::GameModeConfig {
2025-09-03 22:33:26 -04:00
respawn_heal_duration: val.respawn_heal_duration,
respawn_full_heal_duration: val.respawn_full_heal_duration,
kill_limit: val.kill_limit,
game_time_minutes: val.game_time_m,
}
}
}
#[derive(Serialize, Deserialize, Clone, Debug, Copy)]
pub struct GameModes {
pub battle_arena: GameMode,
pub elimination: GameMode,
pub pit: GameMode,
pub team_deathmatch: GameMode,
}
2025-09-03 22:33:26 -04:00
impl std::convert::From<GameModes> for crate::data::game_mode::GameModeConfigs {
fn from(val: GameModes) -> Self {
crate::data::game_mode::GameModeConfigs {
2025-09-03 22:33:26 -04:00
battle_arena: val.battle_arena.into(),
elimination: val.elimination.into(),
the_pit: val.pit.into(),
team_deathmatch: val.team_deathmatch.into(),
}
}
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct GameEventSequence {
pub strategy: GameRotationStrategy,
pub modes: Vec<GameEvents>,
}
#[derive(Serialize, Deserialize, Clone, Debug, Copy)]
pub enum GameRotationStrategy {
Sequence,
Random,
}
impl GameRotationStrategy {
pub fn into_conf(self) -> crate::persist::config::GameRotationStrategy {
match self {
Self::Sequence => crate::persist::config::GameRotationStrategy::Sequence,
Self::Random => crate::persist::config::GameRotationStrategy::Random,
}
}
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct GameEvents {
pub singleplayer: GameEvent,
pub multiplayer: GameEvent,
pub duration_s: u64, // seconds
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct GameEvent {
pub map: GameMap,
pub visibility: GameVisibility,
pub mode: GameType,
pub auto_heal: bool,
}
impl GameEvent {
2025-07-26 11:47:05 -04:00
pub(super) fn into_conf(self) -> crate::persist::config::GameEvent {
crate::persist::config::GameEvent {
map: self.map.into_conf(),
visibility: self.visibility.into_conf(),
mode: self.mode.into_conf(),
auto_heal: self.auto_heal,
}
}
}
2025-07-26 11:47:05 -04:00
#[derive(Serialize, Deserialize, Clone, Debug, Copy, Hash, Eq, PartialEq)]
pub enum GameMap {
#[serde(alias = "Hellion", alias = "HellionCrater")]
Mars1,
#[serde(alias = "Tihonium", alias = "TihoniumCanyon")]
Mars2,
#[serde(alias = "Tharsis", alias = "TharsisRift")]
Mars3,
#[serde(alias = "Gliese", alias = "GlieseLake")]
Neptune1,
#[serde(alias = "Ophiuchus", alias = "OphiuchusValley")]
Neptune2,
#[serde(alias = "Spitzer", alias = "SpitzerDam")]
Neptune3,
#[serde(alias = "Birmingham", alias = "BirminghamPowerStation")]
Earth1,
#[serde(alias = "Vanguard", alias = "VanguardsEnd")]
Earth2,
}
impl GameMap {
2025-07-26 11:47:05 -04:00
pub(super) fn into_conf(self) -> crate::persist::config::GameMap {
match self {
Self::Mars1 => crate::persist::config::GameMap::Mars1,
Self::Mars2 => crate::persist::config::GameMap::Mars2,
Self::Mars3 => crate::persist::config::GameMap::Mars3,
Self::Neptune1 => crate::persist::config::GameMap::Neptune1,
Self::Neptune2 => crate::persist::config::GameMap::Neptune2,
Self::Neptune3 => crate::persist::config::GameMap::Neptune3,
Self::Earth1 => crate::persist::config::GameMap::Earth1,
Self::Earth2 => crate::persist::config::GameMap::Earth2,
}
}
}
#[derive(Serialize, Deserialize, Clone, Debug, Copy)]
pub enum GameVisibility {
Good,
Poor,
Bad,
}
impl GameVisibility {
fn into_conf(self) -> crate::persist::config::GameVisibility {
match self {
Self::Good => crate::persist::config::GameVisibility::Good,
Self::Poor => crate::persist::config::GameVisibility::Poor,
Self::Bad => crate::persist::config::GameVisibility::Bad,
}
}
}
#[derive(Serialize, Deserialize, Clone, Debug, Copy)]
pub enum GameType {
BattleArena,
SuddenDeath,
Pit,
TestMode,
SinglePlayer,
TeamDeathmatch,
Campaign,
}
impl GameType {
fn into_conf(self) -> crate::persist::config::GameType {
match self {
Self::BattleArena => crate::persist::config::GameType::BattleArena,
Self::SuddenDeath => crate::persist::config::GameType::SuddenDeath,
Self::Pit => crate::persist::config::GameType::Pit,
Self::TestMode => crate::persist::config::GameType::TestMode,
Self::SinglePlayer => crate::persist::config::GameType::SinglePlayer,
Self::TeamDeathmatch => crate::persist::config::GameType::TeamDeathmatch,
Self::Campaign => crate::persist::config::GameType::Campaign,
}
}
}
2025-08-17 15:03:30 -04:00
#[derive(Serialize, Deserialize, Clone, Debug, Copy)]
pub struct EnergyConfig {
pub refill_rate_per_s: f32,
pub total: u32,
}
fn default_game_modes() -> GameModes {
GameModes {
battle_arena: GameMode {
respawn_heal_duration: 10.0,
respawn_full_heal_duration: 0.5,
kill_limit: 0,
2025-09-06 19:13:47 -04:00
game_time_m: 20,
},
elimination: GameMode {
respawn_heal_duration: 10.0,
respawn_full_heal_duration: 0.5,
kill_limit: 10,
game_time_m: 10,
},
pit: GameMode {
respawn_heal_duration: 20.0,
respawn_full_heal_duration: 20.0,
kill_limit: 15,
game_time_m: 15,
},
team_deathmatch: GameMode {
respawn_heal_duration: 10.0,
respawn_full_heal_duration: 0.5,
kill_limit: 10,
game_time_m: 10,
},
}
}
2025-05-30 23:03:02 -04:00
pub(super) fn default_campaigns() -> super::SingleplayerConfig {
super::SingleplayerConfig {
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,
2025-09-03 22:33:26 -04:00
time_max: 60,
}
],
}
2025-05-30 23:03:02 -04:00
],
vehicles: vec![
super::PrefabVehicle {
name: Some("Config your singleplayer!".to_owned()),
2025-06-02 20:08:25 -04:00
username: "NGnius?".to_owned(),
id: super::PrefabId::Database { garage: 1 },
2025-05-30 23:03:02 -04:00
},
super::PrefabVehicle {
name: Some("Config your singleplayer!".to_owned()),
username: "NGram!".to_owned(),
2025-06-02 20:08:25 -04:00
id: super::PrefabId::Database { garage: 1 },
2025-05-30 23:03:02 -04:00
},
super::PrefabVehicle {
name: Some("Config your singleplayer!".to_owned()),
2025-06-02 20:08:25 -04:00
username: "NGniusness*".to_owned(),
id: super::PrefabId::Database { garage: 1 },
},
super::PrefabVehicle {
name: Some("Config your singleplayer!".to_owned()),
username: "NG~".to_owned(),
id: super::PrefabId::Database { garage: 1 },
2025-05-30 23:03:02 -04:00
},
],
2025-06-02 20:08:25 -04:00
max_teammates: 0,
max_enemies: 5,
}
}
fn default_rotation() -> GameEventSequence {
GameEventSequence {
strategy: GameRotationStrategy::Sequence,
modes: vec![
GameEvents {
singleplayer: GameEvent {
map: GameMap::Earth1,
visibility: GameVisibility::Good,
mode: GameType::BattleArena,
auto_heal: true,
},
multiplayer: GameEvent {
2025-09-08 21:36:02 -04:00
map: GameMap::Neptune3,
visibility: GameVisibility::Good,
mode: GameType::BattleArena,
auto_heal: true,
},
duration_s: 5*60, // 5 minutes
}
/*GameEvents {
singleplayer: GameEvent {
map: GameMap::Neptune1,
visibility: GameVisibility::Good,
mode: GameType::SuddenDeath,
auto_heal: true,
},
multiplayer: GameEvent {
2025-07-27 11:21:44 -04:00
map: GameMap::Earth1,
visibility: GameVisibility::Poor,
2025-07-06 17:36:52 -04:00
mode: GameType::SuddenDeath,
auto_heal: true,
},
duration_s: 5*60, // 5 minutes
},
GameEvents {
singleplayer: GameEvent {
map: GameMap::Neptune2,
visibility: GameVisibility::Good,
mode: GameType::SuddenDeath,
auto_heal: true,
},
multiplayer: GameEvent {
2025-07-27 11:21:44 -04:00
map: GameMap::Earth2,
visibility: GameVisibility::Good,
2025-07-06 17:36:52 -04:00
mode: GameType::SuddenDeath,
auto_heal: true,
},
duration_s: 5*60,
},
GameEvents {
singleplayer: GameEvent {
map: GameMap::Neptune3,
visibility: GameVisibility::Good,
mode: GameType::SuddenDeath,
auto_heal: true,
},
multiplayer: GameEvent {
2025-07-27 11:21:44 -04:00
map: GameMap::Mars1,
visibility: GameVisibility::Poor,
2025-07-06 17:36:52 -04:00
mode: GameType::SuddenDeath,
auto_heal: true,
},
duration_s: 5*60,
},
GameEvents {
singleplayer: GameEvent {
map: GameMap::Mars1,
visibility: GameVisibility::Good,
mode: GameType::SuddenDeath,
auto_heal: true,
},
multiplayer: GameEvent {
2025-07-27 11:21:44 -04:00
map: GameMap::Mars2,
visibility: GameVisibility::Good,
2025-07-06 17:36:52 -04:00
mode: GameType::SuddenDeath,
auto_heal: true,
},
duration_s: 5*60,
},
GameEvents {
singleplayer: GameEvent {
map: GameMap::Mars2,
visibility: GameVisibility::Good,
mode: GameType::SuddenDeath,
auto_heal: true,
},
multiplayer: GameEvent {
2025-07-27 11:21:44 -04:00
map: GameMap::Mars3,
visibility: GameVisibility::Poor,
2025-07-06 17:36:52 -04:00
mode: GameType::SuddenDeath,
auto_heal: true,
},
duration_s: 5*60,
},
GameEvents {
singleplayer: GameEvent {
map: GameMap::Mars3,
visibility: GameVisibility::Good,
mode: GameType::SuddenDeath,
auto_heal: true,
},
multiplayer: GameEvent {
2025-07-27 11:21:44 -04:00
map: GameMap::Neptune1,
visibility: GameVisibility::Good,
2025-07-06 17:36:52 -04:00
mode: GameType::SuddenDeath,
auto_heal: true,
},
duration_s: 5*60,
},
GameEvents {
singleplayer: GameEvent {
map: GameMap::Earth1,
visibility: GameVisibility::Good,
mode: GameType::SuddenDeath,
auto_heal: true,
},
multiplayer: GameEvent {
2025-07-27 11:21:44 -04:00
map: GameMap::Neptune2,
visibility: GameVisibility::Poor,
2025-07-06 17:36:52 -04:00
mode: GameType::SuddenDeath,
auto_heal: true,
},
duration_s: 5*60,
},
GameEvents {
singleplayer: GameEvent {
map: GameMap::Earth2,
visibility: GameVisibility::Good,
mode: GameType::SuddenDeath,
auto_heal: true,
},
multiplayer: GameEvent {
2025-07-27 11:21:44 -04:00
map: GameMap::Neptune3,
visibility: GameVisibility::Good,
2025-07-06 17:36:52 -04:00
mode: GameType::SuddenDeath,
auto_heal: true,
},
duration_s: 5*60,
},*/
]
}
}
fn default_multiplayer() -> super::MultiplayerConfig {
super::MultiplayerConfig {
2025-08-03 18:15:09 -04:00
players_per_game: 2,
enabled: true,
network: super::multiplayer::default_net_conf(),
2025-08-16 21:32:14 -04:00
fakes: super::multiplayer::default_fake_users(),
battle_arena: super::multiplayer::default_ba_conf(),
}
}
2025-07-26 11:47:05 -04:00
fn default_maps() -> super::MapsConfig {
super::MapsConfig {
map: super::maps::default_map(),
}
}
2025-08-17 15:03:30 -04:00
fn default_energy() -> EnergyConfig {
EnergyConfig {
refill_rate_per_s: 0.1, // should take 10s to refill
total: 12_550,
}
}