mirror of
https://git.ngram.ca/OpenJam/rc-servers
synced 2026-08-23 23:08:52 +00:00
Add customisable game mode sequence (mp and sp still broken) #16
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -3068,6 +3068,7 @@ dependencies = [
|
||||
"log",
|
||||
"polariton",
|
||||
"polariton_server",
|
||||
"rand 0.9.0",
|
||||
"rc_database",
|
||||
"rc_factory",
|
||||
"serde",
|
||||
|
||||
@@ -17,6 +17,7 @@ chrono = "0.4"
|
||||
polariton_server.workspace = true
|
||||
tokio = { version = "1.43", features = [ "net", "macros", "rt-multi-thread", "io-util", "time" ] }
|
||||
async-trait.workspace = true
|
||||
rand = { version = "0.9", features = [ "thread_rng" ] }
|
||||
|
||||
# auth
|
||||
libfj.workspace = true
|
||||
|
||||
@@ -39,3 +39,102 @@ impl GameModeConfigs {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub enum GameMap {
|
||||
Mars1,
|
||||
Mars2,
|
||||
Mars3,
|
||||
Neptune1,
|
||||
Neptune2,
|
||||
Neptune3,
|
||||
Earth1,
|
||||
Earth2,
|
||||
}
|
||||
|
||||
impl GameMap {
|
||||
#[inline]
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Mars1 => "RC_Planet_Mars_01_CTF",
|
||||
Self::Mars2 => "RC_Planet_Mars_02_BA",
|
||||
Self::Mars3 => "RC_Planet_Mars_03_BA",
|
||||
Self::Neptune1 => "RC_Planet_Neptune_01_CTF",
|
||||
Self::Neptune2 => "RC_Planet_Neptune_02_BA",
|
||||
Self::Neptune3 => "RC_Planet_Neptune_03_BA",
|
||||
Self::Earth1 => "RC_Planet_Earth_01_BA",
|
||||
Self::Earth2 => "RC_Planet_Earth_02_BA",
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_persist(map: crate::persist::config::GameMap) -> Self {
|
||||
match map {
|
||||
crate::persist::config::GameMap::Mars1 => Self::Mars1,
|
||||
crate::persist::config::GameMap::Mars2 => Self::Mars2,
|
||||
crate::persist::config::GameMap::Mars3 => Self::Mars3,
|
||||
crate::persist::config::GameMap::Neptune1 => Self::Neptune1,
|
||||
crate::persist::config::GameMap::Neptune2 => Self::Neptune2,
|
||||
crate::persist::config::GameMap::Neptune3 => Self::Neptune3,
|
||||
crate::persist::config::GameMap::Earth1 => Self::Earth1,
|
||||
crate::persist::config::GameMap::Earth2 => Self::Earth2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum GameMode {
|
||||
BattleArena = 0,
|
||||
SuddenDeath = 1,
|
||||
Pit = 2,
|
||||
TestMode = 3,
|
||||
SinglePlayer = 4,
|
||||
TeamDeathmatch = 5,
|
||||
Campaign = 6,
|
||||
}
|
||||
|
||||
impl GameMode {
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
GameMode::BattleArena => "BattleArena",
|
||||
GameMode::SuddenDeath => "SuddenDeath",
|
||||
GameMode::Pit => "Pit",
|
||||
GameMode::TestMode => "TestMode",
|
||||
GameMode::SinglePlayer => "SinglePlayerTDM",
|
||||
GameMode::TeamDeathmatch => "TeamDeathmatch",
|
||||
GameMode::Campaign => "Campaign",
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_persist(mode: crate::persist::config::GameType) -> Self {
|
||||
match mode {
|
||||
crate::persist::config::GameType::BattleArena => Self::BattleArena,
|
||||
crate::persist::config::GameType::SuddenDeath => Self::SuddenDeath,
|
||||
crate::persist::config::GameType::Pit => Self::Pit,
|
||||
crate::persist::config::GameType::TestMode => Self::TestMode,
|
||||
crate::persist::config::GameType::SinglePlayer => Self::SinglePlayer,
|
||||
crate::persist::config::GameType::TeamDeathmatch => Self::TeamDeathmatch,
|
||||
crate::persist::config::GameType::Campaign => Self::Campaign,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum MapVisibility {
|
||||
Good = 0,
|
||||
Poor = 1,
|
||||
Bad = 2, // VeryPoor
|
||||
}
|
||||
|
||||
impl MapVisibility {
|
||||
#[inline]
|
||||
pub fn from_persist(mode: crate::persist::config::GameVisibility) -> Self {
|
||||
match mode {
|
||||
crate::persist::config::GameVisibility::Good => Self::Good,
|
||||
crate::persist::config::GameVisibility::Poor => Self::Poor,
|
||||
crate::persist::config::GameVisibility::Bad => Self::Bad,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ pub struct BattleConfig {
|
||||
pub games: GameModes,
|
||||
#[serde(default = "default_campaigns")]
|
||||
pub singleplayer: super::Campaigns,
|
||||
#[serde(default = "default_rotation")]
|
||||
pub rotation: GameEventSequence,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
@@ -103,6 +105,124 @@ impl std::convert::Into<crate::data::game_mode::GameModeConfigs> for GameModes {
|
||||
}
|
||||
}
|
||||
|
||||
#[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 {
|
||||
pub 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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, Copy)]
|
||||
pub enum GameMap {
|
||||
// TODO put some more obvious aliases on these
|
||||
Mars1,
|
||||
Mars2,
|
||||
Mars3,
|
||||
Neptune1,
|
||||
Neptune2,
|
||||
Neptune3,
|
||||
Earth1,
|
||||
Earth2,
|
||||
}
|
||||
|
||||
impl GameMap {
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn default_game_modes() -> GameModes {
|
||||
GameModes {
|
||||
battle_arena: GameMode {
|
||||
@@ -200,3 +320,131 @@ fn default_campaigns() -> super::Campaigns {
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
fn default_rotation() -> GameEventSequence {
|
||||
GameEventSequence {
|
||||
strategy: GameRotationStrategy::Sequence,
|
||||
modes: vec![
|
||||
GameEvents {
|
||||
singleplayer: GameEvent {
|
||||
map: GameMap::Neptune1,
|
||||
visibility: GameVisibility::Good,
|
||||
mode: GameType::SuddenDeath,
|
||||
auto_heal: true,
|
||||
},
|
||||
multiplayer: GameEvent {
|
||||
map: GameMap::Neptune3,
|
||||
visibility: GameVisibility::Poor,
|
||||
mode: GameType::BattleArena,
|
||||
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 {
|
||||
map: GameMap::Mars1,
|
||||
visibility: GameVisibility::Poor,
|
||||
mode: GameType::Pit,
|
||||
auto_heal: true,
|
||||
},
|
||||
duration_s: 5*60,
|
||||
},
|
||||
GameEvents {
|
||||
singleplayer: GameEvent {
|
||||
map: GameMap::Neptune3,
|
||||
visibility: GameVisibility::Good,
|
||||
mode: GameType::SuddenDeath,
|
||||
auto_heal: true,
|
||||
},
|
||||
multiplayer: GameEvent {
|
||||
map: GameMap::Mars1,
|
||||
visibility: GameVisibility::Poor,
|
||||
mode: GameType::TestMode,
|
||||
auto_heal: true,
|
||||
},
|
||||
duration_s: 5*60,
|
||||
},
|
||||
GameEvents {
|
||||
singleplayer: GameEvent {
|
||||
map: GameMap::Mars1,
|
||||
visibility: GameVisibility::Good,
|
||||
mode: GameType::SuddenDeath,
|
||||
auto_heal: true,
|
||||
},
|
||||
multiplayer: GameEvent {
|
||||
map: GameMap::Neptune3,
|
||||
visibility: GameVisibility::Poor,
|
||||
mode: GameType::BattleArena,
|
||||
auto_heal: true,
|
||||
},
|
||||
duration_s: 5*60,
|
||||
},
|
||||
GameEvents {
|
||||
singleplayer: GameEvent {
|
||||
map: GameMap::Mars2,
|
||||
visibility: GameVisibility::Good,
|
||||
mode: GameType::SuddenDeath,
|
||||
auto_heal: true,
|
||||
},
|
||||
multiplayer: GameEvent {
|
||||
map: GameMap::Mars1,
|
||||
visibility: GameVisibility::Poor,
|
||||
mode: GameType::Pit,
|
||||
auto_heal: true,
|
||||
},
|
||||
duration_s: 5*60,
|
||||
},
|
||||
GameEvents {
|
||||
singleplayer: GameEvent {
|
||||
map: GameMap::Mars3,
|
||||
visibility: GameVisibility::Good,
|
||||
mode: GameType::SuddenDeath,
|
||||
auto_heal: true,
|
||||
},
|
||||
multiplayer: GameEvent {
|
||||
map: GameMap::Mars1,
|
||||
visibility: GameVisibility::Poor,
|
||||
mode: GameType::TestMode,
|
||||
auto_heal: true,
|
||||
},
|
||||
duration_s: 5*60,
|
||||
},
|
||||
GameEvents {
|
||||
singleplayer: GameEvent {
|
||||
map: GameMap::Earth1,
|
||||
visibility: GameVisibility::Good,
|
||||
mode: GameType::SuddenDeath,
|
||||
auto_heal: true,
|
||||
},
|
||||
multiplayer: GameEvent {
|
||||
map: GameMap::Mars1,
|
||||
visibility: GameVisibility::Poor,
|
||||
mode: GameType::Pit,
|
||||
auto_heal: true,
|
||||
},
|
||||
duration_s: 5*60,
|
||||
},
|
||||
GameEvents {
|
||||
singleplayer: GameEvent {
|
||||
map: GameMap::Earth2,
|
||||
visibility: GameVisibility::Good,
|
||||
mode: GameType::SuddenDeath,
|
||||
auto_heal: true,
|
||||
},
|
||||
multiplayer: GameEvent {
|
||||
map: GameMap::Mars1,
|
||||
visibility: GameVisibility::Poor,
|
||||
mode: GameType::TestMode,
|
||||
auto_heal: true,
|
||||
},
|
||||
duration_s: 5*60,
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,4 +288,19 @@ impl <C: Clone> super::ConfigProvider<C> for CubeConfig {
|
||||
commands: self.chat.commands.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
fn gamemode_events(&self) -> super::GameEventSequence {
|
||||
let strategy = self.battle.rotation.strategy.into_conf();
|
||||
let first = strategy.next(self.battle.rotation.modes.len() - 1, self.battle.rotation.modes.len());
|
||||
super::GameEventSequence {
|
||||
strategy: self.battle.rotation.strategy.into_conf(),
|
||||
modes: self.battle.rotation.modes.clone().into_iter().map(|event| super::GameEvents {
|
||||
singleplayer: event.singleplayer.into_conf(),
|
||||
multiplayer: event.multiplayer.into_conf(),
|
||||
duration: std::time::Duration::from_secs(event.duration_s),
|
||||
}).collect(),
|
||||
index: first,
|
||||
started: chrono::Utc::now().timestamp(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ mod cubes_json;
|
||||
pub use cubes_json::CubeConfig;
|
||||
|
||||
mod traits;
|
||||
pub use traits::{ConfigProvider, CompleteCampaignProvider, DevMessageProvider, ServerConfig, GarageUpgrades, GarageUpgradeIncrement, ChatSystemConfig};
|
||||
pub use traits::{ConfigProvider, CompleteCampaignProvider, DevMessageProvider, ServerConfig, GarageUpgrades, GarageUpgradeIncrement, ChatSystemConfig, GameEventSequence, GameEvents, GameRotationStrategy, GameEvent, GameMap, GameVisibility, GameType};
|
||||
|
||||
pub type ConfigImpl = CubeConfig;
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ pub trait ConfigProvider<C: Clone> {
|
||||
async fn factory(&self) -> Result<crate::factory::Factory, Box<dyn std::error::Error + 'static>>;
|
||||
fn cubes(&self) -> &'_ std::collections::HashMap<String, crate::persist::Cube>;
|
||||
fn chat_system_config(&self) -> ChatSystemConfig;
|
||||
fn gamemode_events(&self) -> GameEventSequence;
|
||||
}
|
||||
|
||||
pub struct CompleteCampaignProvider {
|
||||
@@ -128,3 +129,131 @@ pub struct ChatSystemConfig {
|
||||
pub command_channel: String,
|
||||
pub commands: Vec<crate::persist::ChatCommand>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct GameEventSequence {
|
||||
pub strategy: GameRotationStrategy,
|
||||
pub modes: Vec<GameEvents>,
|
||||
pub index: usize,
|
||||
pub started: i64,
|
||||
}
|
||||
|
||||
impl GameEventSequence {
|
||||
pub fn now(&mut self) -> GameEventTransmissible {
|
||||
let time_now = chrono::Utc::now().timestamp();
|
||||
let mut item_now = &self.modes[self.index];
|
||||
if time_now >= (item_now.duration.as_secs() as i64) + self.started {
|
||||
// needs refresh
|
||||
self.index = self.strategy.next(self.index, self.modes.len());
|
||||
item_now = &self.modes[self.index];
|
||||
self.started = time_now;
|
||||
}
|
||||
let remaining_ticks = ((item_now.duration.as_secs() as i64) - (time_now - self.started)) * 10_000_000;
|
||||
GameEventTransmissible {
|
||||
maps: Typed::Arr(polariton::operation::Arr {
|
||||
ty: polariton::serdes::TypePrefix::Str,
|
||||
items: vec![
|
||||
Typed::Str(crate::data::game_mode::GameMap::from_persist(item_now.singleplayer.map).as_str().into()),
|
||||
Typed::Str(crate::data::game_mode::GameMap::from_persist(item_now.multiplayer.map).as_str().into()),
|
||||
],
|
||||
}),
|
||||
visibilities: Typed::Arr(polariton::operation::Arr {
|
||||
ty: polariton::serdes::TypePrefix::Int,
|
||||
items: vec![
|
||||
Typed::Int(crate::data::game_mode::MapVisibility::from_persist(item_now.singleplayer.visibility) as _),
|
||||
Typed::Int(crate::data::game_mode::MapVisibility::from_persist(item_now.multiplayer.visibility) as _),
|
||||
],
|
||||
}),
|
||||
modes: Typed::Arr(polariton::operation::Arr {
|
||||
ty: polariton::serdes::TypePrefix::Int,
|
||||
items: vec![
|
||||
Typed::Int(crate::data::game_mode::GameMode::from_persist(item_now.singleplayer.mode) as _),
|
||||
Typed::Int(crate::data::game_mode::GameMode::from_persist(item_now.multiplayer.mode) as _),
|
||||
],
|
||||
}),
|
||||
auto_heals: Typed::Arr(polariton::operation::Arr {
|
||||
ty: polariton::serdes::TypePrefix::Bool,
|
||||
items: vec![
|
||||
Typed::Bool(item_now.singleplayer.auto_heal),
|
||||
Typed::Bool(item_now.multiplayer.auto_heal),
|
||||
],
|
||||
}),
|
||||
remaining_ticks: Typed::Long(remaining_ticks),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GameEventTransmissible {
|
||||
pub maps: Typed,
|
||||
pub visibilities: Typed,
|
||||
pub modes: Typed,
|
||||
pub auto_heals: Typed,
|
||||
pub remaining_ticks: Typed,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum GameRotationStrategy {
|
||||
Sequence,
|
||||
Random,
|
||||
}
|
||||
|
||||
impl GameRotationStrategy {
|
||||
pub(super) fn next(&self, last: usize, count: usize) -> usize {
|
||||
match self {
|
||||
Self::Sequence => (last+1) % count,
|
||||
Self::Random => {
|
||||
use rand::prelude::*;
|
||||
let mut rng = rand::rng();
|
||||
let num: u64 = rng.random();
|
||||
let num = num.clamp(0, usize::MAX as u64) as usize;
|
||||
num % count
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct GameEvents {
|
||||
pub singleplayer: GameEvent,
|
||||
pub multiplayer: GameEvent,
|
||||
pub duration: std::time::Duration,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct GameEvent {
|
||||
pub map: GameMap,
|
||||
pub visibility: GameVisibility,
|
||||
pub mode: GameType,
|
||||
pub auto_heal: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Copy)]
|
||||
pub enum GameMap {
|
||||
Mars1,
|
||||
Mars2,
|
||||
Mars3,
|
||||
Neptune1,
|
||||
Neptune2,
|
||||
Neptune3,
|
||||
Earth1,
|
||||
Earth2,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Copy)]
|
||||
pub enum GameVisibility {
|
||||
Good,
|
||||
Poor,
|
||||
Bad,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, Debug, Copy)]
|
||||
pub enum GameType {
|
||||
BattleArena,
|
||||
SuddenDeath,
|
||||
Pit,
|
||||
TestMode,
|
||||
SinglePlayer,
|
||||
TeamDeathmatch,
|
||||
Campaign,
|
||||
}
|
||||
|
||||
@@ -1,38 +1,6 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum GameMode {
|
||||
BattleArena = 0,
|
||||
SuddenDeath = 1,
|
||||
Pit = 2,
|
||||
TestMode = 3,
|
||||
SinglePlayer = 4,
|
||||
TeamDeathmatch = 5,
|
||||
Campaign = 6,
|
||||
}
|
||||
|
||||
impl GameMode {
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
GameMode::BattleArena => "BattleArena",
|
||||
GameMode::SuddenDeath => "SuddenDeath",
|
||||
GameMode::Pit => "Pit",
|
||||
GameMode::TestMode => "TestMode",
|
||||
GameMode::SinglePlayer => "SinglePlayerTDM",
|
||||
GameMode::TeamDeathmatch => "TeamDeathmatch",
|
||||
GameMode::Campaign => "Campaign",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum MapVisibility {
|
||||
Good = 0,
|
||||
Poor = 1,
|
||||
Bad = 2, // VeryPoor
|
||||
}
|
||||
pub use rc_core::data::game_mode::GameMode;
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Copy, Clone)]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use polariton_server::operations::SimpleFunc;
|
||||
use polariton::{operation::{Arr, ParameterTable, Typed}, serdes::TypePrefix};
|
||||
use polariton_server::operations::{Operation, OperationCode};
|
||||
//use polariton::{operation::{Arr, ParameterTable, Typed}, serdes::TypePrefix};
|
||||
|
||||
use crate::data::custom_games::*;
|
||||
const CODE: u8 = 24;
|
||||
|
||||
const MAP_NAMES_PARAM_KEY: u8 = 78;
|
||||
const VISIBILITY_PARAM_KEY: u8 = 66;
|
||||
@@ -20,38 +20,40 @@ RC_Planet_Mars_01_CTF
|
||||
RC_Planet_Neptune_01_CTF
|
||||
*/
|
||||
|
||||
pub(super) fn event_system_params_provider() -> SimpleFunc<24, crate::UserTy, impl (Fn(ParameterTable, &crate::UserTy) -> Result<ParameterTable, i16>) + Sync + Sync> {
|
||||
SimpleFunc::new(|params, _| {
|
||||
pub struct GameEventsParamsProvider {
|
||||
sequence: std::sync::Mutex<rc_core::persist::config::GameEventSequence>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl Operation<()> for GameEventsParamsProvider {
|
||||
type User = crate::UserTy;
|
||||
|
||||
async fn handle_async(&self, params: polariton::operation::ParameterTable<()>, _user: &Self::User) -> polariton::operation::OperationResponse<()> {
|
||||
let mut params = params.to_dict();
|
||||
params.insert(MAP_NAMES_PARAM_KEY, Typed::Arr(Arr {
|
||||
ty: TypePrefix::Str, // str
|
||||
items: vec![
|
||||
Typed::Str("RC_Planet_Neptune_03_BA".into()),
|
||||
Typed::Str("RC_Planet_Mars_02_BA".into()),
|
||||
],
|
||||
}));
|
||||
params.insert(VISIBILITY_PARAM_KEY, Typed::Arr(Arr {
|
||||
ty: TypePrefix::Int, // int
|
||||
items: vec![
|
||||
Typed::Int(MapVisibility::Good as _),
|
||||
Typed::Int(MapVisibility::Bad as _),
|
||||
],
|
||||
}));
|
||||
params.insert(MODE_PARAM_KEY, Typed::Arr(Arr {
|
||||
ty: TypePrefix::Int, // int
|
||||
items: vec![
|
||||
Typed::Int(GameMode::SinglePlayer as _),
|
||||
Typed::Int(GameMode::BattleArena as _),
|
||||
],
|
||||
}));
|
||||
params.insert(AUTO_HEAL_PARAM_KEY, Typed::Arr(Arr {
|
||||
ty: TypePrefix::Bool, // bool
|
||||
items: vec![
|
||||
Typed::Bool(true.into()),
|
||||
Typed::Bool(false.into()),
|
||||
],
|
||||
}));
|
||||
params.insert(REMAINING_TICKS_PARAM_KEY, Typed::Long(24 * 60 * 60 * 1_000_000 * 10 /* 24 hours in ticks (100ns units) */));
|
||||
Ok(params.into())
|
||||
})
|
||||
let current_mode = self.sequence.lock().unwrap().now();
|
||||
params.insert(MAP_NAMES_PARAM_KEY, current_mode.maps);
|
||||
params.insert(VISIBILITY_PARAM_KEY, current_mode.visibilities);
|
||||
params.insert(MODE_PARAM_KEY, current_mode.modes);
|
||||
params.insert(AUTO_HEAL_PARAM_KEY, current_mode.auto_heals);
|
||||
params.insert(REMAINING_TICKS_PARAM_KEY, current_mode.remaining_ticks);
|
||||
polariton::operation::OperationResponse {
|
||||
code: Self::op_code(),
|
||||
return_code: 0,
|
||||
message: polariton::operation::Typed::Null,
|
||||
params: params.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl OperationCode for GameEventsParamsProvider {
|
||||
fn op_code() -> u8 {
|
||||
CODE
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn event_system_params_provider(conf: &rc_core::ConfigImpl) -> GameEventsParamsProvider {
|
||||
let game_seq = <rc_core::ConfigImpl as rc_core::ConfigProvider<()>>::gamemode_events(conf);
|
||||
GameEventsParamsProvider {
|
||||
sequence: std::sync::Mutex::new(game_seq),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ pub fn handler(init_ctx: &crate::InitConfig) -> OperationsHandler<crate::UserTy>
|
||||
.add(custom_game_session::get_custom_session_provider())
|
||||
.add(user_xp::get_user_xp_provider())
|
||||
.add(garage_upgrades::garage_upgrades_provider(&init_ctx.cubes))
|
||||
.add(game_event_params::event_system_params_provider())
|
||||
.add(game_event_params::event_system_params_provider(&init_ctx.cubes))
|
||||
.add(garage_bay_uuid::garage_id_provider())
|
||||
.add(tech_tree_data::tech_tree_layout_provider(&init_ctx.cubes))
|
||||
.add(item_shop_bundles::item_bundle_provider())
|
||||
|
||||
Reference in New Issue
Block a user