mirror of
https://git.ngram.ca/OpenJam/rc-servers
synced 2026-08-23 23:08:52 +00:00
Fix dominating message, fix fake player loading, mess around with reactor crystals
This commit is contained in:
16
Cargo.lock
generated
16
Cargo.lock
generated
@@ -2424,6 +2424,22 @@ dependencies = [
|
||||
"zip",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oj_factory_api"
|
||||
version = "1.1.0"
|
||||
dependencies = [
|
||||
"actix-web",
|
||||
"base64",
|
||||
"clap",
|
||||
"env_logger",
|
||||
"git-version",
|
||||
"libfj",
|
||||
"log",
|
||||
"oj_rc_core",
|
||||
"oj_rc_factory",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oj_polariton_auth"
|
||||
version = "1.1.0"
|
||||
|
||||
@@ -12264,7 +12264,8 @@
|
||||
"active": true,
|
||||
"protonium": true,
|
||||
"visibility": "None",
|
||||
"ignore_in_weapon_list": true
|
||||
"ignore_in_weapon_list": true,
|
||||
"health": 10000
|
||||
},
|
||||
"spriteName": "CubeThumb_LightChassis_Cube",
|
||||
"nameStrKey": "strProtoniumCrystalName",
|
||||
|
||||
@@ -42,33 +42,41 @@ impl CubeLocationsParser {
|
||||
}
|
||||
}
|
||||
|
||||
fn locations_sorted_by_distance_from_point(cubes: &[super::parser::Cube], point: (u8, u8, u8), locations_of_id: u32) -> Vec<CubeLocationInfo> {
|
||||
let target_x = point.0 as f32;
|
||||
let target_y = point.1 as f32;
|
||||
let target_z = point.2 as f32;
|
||||
let mut relevant_cubes: Vec<(f32, CubeLocationInfo)> = cubes.into_iter()
|
||||
.filter(|x| x.id == locations_of_id)
|
||||
.map(|cube| {
|
||||
let distance = (
|
||||
(cube.x as f32 - target_x).powi(2)
|
||||
+ (cube.y as f32 - target_y).powi(2)
|
||||
+ (cube.z as f32 - target_z).powi(2)
|
||||
).sqrt();
|
||||
(distance, CubeLocationInfo {
|
||||
x: cube.x,
|
||||
y: cube.y,
|
||||
z: cube.z,
|
||||
extras: cube.orientation,
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
relevant_cubes.sort_by_key(|(distance, _)| (distance * 1_000_000.0) as i64);
|
||||
relevant_cubes.into_iter()
|
||||
.map(|(_, cube)| cube)
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn locations_of_by_distance_to_first(&self, r: &mut dyn std::io::Read, locations_of_id: u32, distance_to_id: u32) -> Vec<CubeLocationInfo> {
|
||||
match super::parser::Cube::parse_list(r) {
|
||||
Ok(cubes) => {
|
||||
if let Some(target) = cubes.iter().find(|x| x.id == distance_to_id) {
|
||||
let target_x = target.x as f32;
|
||||
let target_y = target.y as f32;
|
||||
let target_z = target.z as f32;
|
||||
let mut relevant_cubes: Vec<(f32, CubeLocationInfo)> = cubes.into_iter()
|
||||
.filter(|x| x.id == locations_of_id)
|
||||
.map(|cube| {
|
||||
let distance = (
|
||||
(cube.x as f32 - target_x).powi(2)
|
||||
+ (cube.y as f32 - target_y).powi(2)
|
||||
+ (cube.z as f32 - target_z).powi(2)
|
||||
).sqrt();
|
||||
(distance, CubeLocationInfo {
|
||||
x: cube.x,
|
||||
y: cube.y,
|
||||
z: cube.z,
|
||||
extras: cube.orientation,
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
relevant_cubes.sort_by_key(|(distance, _)| (distance * 1_000_000.0) as i64);
|
||||
relevant_cubes.into_iter()
|
||||
.map(|(_, cube)| cube)
|
||||
.collect()
|
||||
Self::locations_sorted_by_distance_from_point(
|
||||
&cubes,
|
||||
(target.x, target.y, target.z),
|
||||
locations_of_id,
|
||||
)
|
||||
} else {
|
||||
log::warn!("No cube with id {} to calculate distance", distance_to_id);
|
||||
cubes.into_iter()
|
||||
@@ -89,4 +97,20 @@ impl CubeLocationsParser {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn locations_of_by_distance_from(&self, r: &mut dyn std::io::Read, locations_of_id: u32, from: (u8, u8, u8)) -> Vec<CubeLocationInfo> {
|
||||
match super::parser::Cube::parse_list(r) {
|
||||
Ok(cubes) => {
|
||||
Self::locations_sorted_by_distance_from_point(
|
||||
&cubes,
|
||||
from,
|
||||
locations_of_id,
|
||||
)
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Failed to parse cube data to find cube locations: {}", e);
|
||||
Vec::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,7 +336,7 @@ fn default_game_modes() -> GameModes {
|
||||
respawn_heal_duration: 10.0,
|
||||
respawn_full_heal_duration: 0.5,
|
||||
kill_limit: 0,
|
||||
game_time_m: 2,
|
||||
game_time_m: 20,
|
||||
},
|
||||
elimination: GameMode {
|
||||
respawn_heal_duration: 10.0,
|
||||
@@ -622,6 +622,7 @@ fn default_multiplayer() -> super::MultiplayerConfig {
|
||||
autostart_after_s: 180,
|
||||
network: super::multiplayer::default_net_conf(),
|
||||
fakes: super::multiplayer::default_fake_users(),
|
||||
filler: super::multiplayer::default_filler_users(),
|
||||
battle_arena: super::multiplayer::default_ba_conf(),
|
||||
pit_config: super::multiplayer::default_pit_conf(),
|
||||
team_death_match: super::multiplayer::default_tdm_conf(),
|
||||
|
||||
@@ -488,6 +488,14 @@ impl <C: Clone + Send> super::ConfigProvider<C> for CubeConfig {
|
||||
}).collect()
|
||||
}
|
||||
|
||||
fn filler_players(&self) -> Vec<super::FakePlayer> {
|
||||
self.battle.multiplayer.filler.iter().map(|player| super::FakePlayer {
|
||||
team: player.team,
|
||||
vehicle: player.vehicle.into_conf(),
|
||||
implementation: player.implementation.clone().to_config(),
|
||||
}).collect()
|
||||
}
|
||||
|
||||
fn energy(&self) -> super::EnergyConfig {
|
||||
super::EnergyConfig {
|
||||
refill_rate: self.battle.energy.refill_rate_per_s,
|
||||
|
||||
@@ -34,6 +34,7 @@ pub trait ConfigProvider<C: Clone> {
|
||||
fn maps(&self) -> std::collections::HashMap<GameMap, MapConfig>;
|
||||
fn url_links(&self) -> LinksConfig;
|
||||
fn fake_players(&self) -> Vec<FakePlayer>;
|
||||
fn filler_players(&self) -> Vec<FakePlayer>;
|
||||
fn energy(&self) -> EnergyConfig;
|
||||
fn ba_settings(&self) -> BattleArenaResolver;
|
||||
fn pit_settings(&self) -> PitSettings;
|
||||
|
||||
@@ -9,6 +9,8 @@ pub struct MultiplayerConfig {
|
||||
pub network: NetworkConf,
|
||||
#[serde(default = "default_fake_users")]
|
||||
pub fakes: Vec<FakePlayerConf>,
|
||||
#[serde(default = "default_filler_users")]
|
||||
pub filler: Vec<FakePlayerConf>,
|
||||
#[serde(default = "default_ba_conf")]
|
||||
pub battle_arena: BattleArenaConfig,
|
||||
#[serde(default = "default_pit_conf")]
|
||||
@@ -166,6 +168,10 @@ pub(super) fn default_fake_users() -> Vec<FakePlayerConf> {
|
||||
]
|
||||
}
|
||||
|
||||
pub(super) fn default_filler_users() -> Vec<FakePlayerConf> {
|
||||
default_fake_users()
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[serde(tag = "impl")]
|
||||
pub enum ClientEmulation {
|
||||
@@ -242,7 +248,7 @@ fn default_ba_base() -> super::garage::PrefabVehicle {
|
||||
}
|
||||
|
||||
fn default_crystal_health() -> u32 {
|
||||
1_000
|
||||
10_000
|
||||
}
|
||||
|
||||
fn default_respawn_time() -> u64 {
|
||||
|
||||
@@ -8,6 +8,7 @@ pub struct AccountProvider {
|
||||
cubes: std::sync::Arc<Vec<u32>>,
|
||||
garage_upgrades: std::sync::Arc<crate::persist::config::GarageUpgrades>,
|
||||
fake_players: std::sync::Arc<Vec<crate::persist::config::FakePlayer>>,
|
||||
filler_players: std::sync::Arc<Vec<crate::persist::config::FakePlayer>>,
|
||||
auto_signups: bool,
|
||||
cdn: std::sync::Arc<String>,
|
||||
auth: std::sync::Arc<String>,
|
||||
@@ -30,6 +31,7 @@ impl AccountProvider {
|
||||
cubes: std::sync::Arc::new(<crate::persist::config::ConfigImpl as ConfigProvider<()>>::ids(conf)),
|
||||
garage_upgrades: std::sync::Arc::new(<crate::persist::config::ConfigImpl as ConfigProvider<()>>::garage_upgrades(conf)),
|
||||
fake_players: std::sync::Arc::new(<crate::persist::config::ConfigImpl as ConfigProvider<()>>::fake_players(conf)),
|
||||
filler_players: std::sync::Arc::new(<crate::persist::config::ConfigImpl as ConfigProvider<()>>::filler_players(conf)),
|
||||
auto_signups: server_settings.auto_signup,
|
||||
cdn: std::sync::Arc::new(server_settings.cdn_url),
|
||||
auth: std::sync::Arc::new(server_settings.auth_url),
|
||||
@@ -113,6 +115,7 @@ impl <C: Clone + Send> super::UserProvider<C> for AccountProvider {
|
||||
cubes: self.cubes.clone(),
|
||||
garage_upgrades: self.garage_upgrades.clone(),
|
||||
fake_players: self.fake_players.clone(),
|
||||
filler_players: self.filler_players.clone(),
|
||||
cdn: self.cdn.clone(),
|
||||
auth: self.auth.clone(),
|
||||
intercom: self.intercom.clone(),
|
||||
@@ -151,6 +154,7 @@ impl <C: Clone + Send> super::UserProvider<C> for AccountProvider {
|
||||
cubes: self.cubes.clone(),
|
||||
garage_upgrades: self.garage_upgrades.clone(),
|
||||
fake_players: self.fake_players.clone(),
|
||||
filler_players: self.filler_players.clone(),
|
||||
cdn: self.cdn.clone(),
|
||||
auth: self.auth.clone(),
|
||||
intercom: self.intercom.clone(),
|
||||
@@ -316,6 +320,7 @@ pub(super) struct UserData {
|
||||
pub(super) cubes: std::sync::Arc<Vec<u32>>,
|
||||
pub(super) garage_upgrades: std::sync::Arc<crate::persist::config::GarageUpgrades>,
|
||||
pub(super) fake_players: std::sync::Arc<Vec<crate::persist::config::FakePlayer>>,
|
||||
pub(super) filler_players: std::sync::Arc<Vec<crate::persist::config::FakePlayer>>,
|
||||
pub(super) cdn: std::sync::Arc<String>,
|
||||
pub(super) auth: std::sync::Arc<String>,
|
||||
pub(super) intercom: std::sync::Arc<String>,
|
||||
|
||||
@@ -58,6 +58,7 @@ impl super::LobbyUser for UserData {
|
||||
cpu_counter: &crate::cubes::CpuListParser,
|
||||
weapon_lister: &crate::cubes::WeaponListParser,
|
||||
chooser: &TeamChooser,
|
||||
missing_players: usize,
|
||||
) -> Result<super::FakePlayers, polariton_server::operations::SimpleOpError> {
|
||||
let now = chrono::Utc::now().timestamp();
|
||||
let guid = crate::persist::user::str_to_i64(&game.guid)
|
||||
@@ -73,7 +74,8 @@ impl super::LobbyUser for UserData {
|
||||
oj_rc_database::schema::multiplayer_game::GameType::Standard
|
||||
};
|
||||
|
||||
let fake_players = self.generate_fake_players_data(guid, &players, factory, cpu_counter, weapon_lister, chooser).await?;
|
||||
let forced_fake_players = self.generate_forced_fake_players_data(guid, &players, factory, cpu_counter, weapon_lister, chooser).await?;
|
||||
let filler_players = self.generate_filler_players_data(guid, &players, factory, cpu_counter, weapon_lister, chooser, missing_players).await?;
|
||||
|
||||
let game_dbo = oj_rc_database::schema::multiplayer_game::ActiveModel {
|
||||
id: oj_rc_database::sea_orm::ActiveValue::NotSet,
|
||||
@@ -95,6 +97,7 @@ impl super::LobbyUser for UserData {
|
||||
})?;
|
||||
|
||||
let players_len = players.len();
|
||||
let forced_fake_players_len = forced_fake_players.len();
|
||||
|
||||
let players: Vec<oj_rc_database::schema::multiplayer_game_player::ActiveModel> = players.into_iter()
|
||||
.enumerate()
|
||||
@@ -113,7 +116,7 @@ impl super::LobbyUser for UserData {
|
||||
variant: oj_rc_database::sea_orm::ActiveValue::Set(oj_rc_database::schema::multiplayer_game_player::ClientType::Client),
|
||||
}
|
||||
})
|
||||
.chain(fake_players.iter()
|
||||
.chain(forced_fake_players.iter()
|
||||
.enumerate()
|
||||
.map(|(i, (fake, variant))| {
|
||||
oj_rc_database::schema::multiplayer_game_player::ActiveModel {
|
||||
@@ -131,6 +134,24 @@ impl super::LobbyUser for UserData {
|
||||
}
|
||||
})
|
||||
)
|
||||
.chain(filler_players.iter()
|
||||
.enumerate()
|
||||
.map(|(i, (fake, variant))| {
|
||||
oj_rc_database::schema::multiplayer_game_player::ActiveModel {
|
||||
id: oj_rc_database::sea_orm::ActiveValue::NotSet,
|
||||
user_id: oj_rc_database::sea_orm::ActiveValue::Set(None), // if ClientAI, they will be assigned to a user during game loading
|
||||
game_id: oj_rc_database::sea_orm::ActiveValue::Set(game_dbo.id),
|
||||
creation_time: oj_rc_database::sea_orm::ActiveValue::Set(now),
|
||||
player_id: oj_rc_database::sea_orm::ActiveValue::Set(((i + players_len + forced_fake_players_len) as u8) as _),
|
||||
team: oj_rc_database::sea_orm::ActiveValue::Set(fake.team),
|
||||
group: oj_rc_database::sea_orm::ActiveValue::Set(None),
|
||||
is_claimed: oj_rc_database::sea_orm::ActiveValue::Set(true),
|
||||
public_id: oj_rc_database::sea_orm::ActiveValue::Set(fake.name.clone()),
|
||||
display_name: oj_rc_database::sea_orm::ActiveValue::Set(fake.display_name.clone()),
|
||||
variant: oj_rc_database::sea_orm::ActiveValue::Set(fake_impl_to_db(variant)),
|
||||
}
|
||||
})
|
||||
)
|
||||
.collect();
|
||||
self.db.insert_players(players).await.map_err(|e| {
|
||||
log::error!("Failed to create game players for {} through user_id {}: {}", game.guid, self.account.id, e);
|
||||
@@ -140,6 +161,8 @@ impl super::LobbyUser for UserData {
|
||||
)
|
||||
})?;
|
||||
|
||||
Ok(super::FakePlayers { players: fake_players })
|
||||
Ok(super::FakePlayers {
|
||||
players: forced_fake_players.into_iter().chain(filler_players).collect(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,10 +17,11 @@ impl UserData {
|
||||
cpu_counter: &crate::cubes::CpuListParser,
|
||||
weapon_lister: &crate::cubes::WeaponListParser,
|
||||
chooser: &super::TeamChooser,
|
||||
fake_players: &[crate::persist::config::FakePlayer],
|
||||
) -> Result<Vec<(crate::data::player_data::PlayerData, crate::persist::config::ClientEmulator)>, polariton_server::operations::SimpleOpError> {
|
||||
let mut fakes = Vec::with_capacity(self.fake_players.len());
|
||||
let mut fakes = Vec::with_capacity(fake_players.len());
|
||||
let mut fake_i = real_players.len();
|
||||
for fake in self.fake_players.iter() {
|
||||
for fake in fake_players.iter() {
|
||||
let vehicle = self.resolve_vehicle(&fake.vehicle, factory, weapon_lister, cpu_counter).await?;
|
||||
let out = (
|
||||
crate::data::player_data::PlayerData {
|
||||
@@ -55,6 +56,47 @@ impl UserData {
|
||||
}
|
||||
Ok(fakes)
|
||||
}
|
||||
|
||||
pub(super) async fn generate_forced_fake_players_data(
|
||||
&self,
|
||||
guid: i64,
|
||||
real_players: &[super::PlayerLobbyDescriptor],
|
||||
factory: &dyn oj_rc_factory::VehicleFactoryAdapter,
|
||||
cpu_counter: &crate::cubes::CpuListParser,
|
||||
weapon_lister: &crate::cubes::WeaponListParser,
|
||||
chooser: &super::TeamChooser,
|
||||
) -> Result<Vec<(crate::data::player_data::PlayerData, crate::persist::config::ClientEmulator)>, polariton_server::operations::SimpleOpError> {
|
||||
self.generate_fake_players_data(
|
||||
guid,
|
||||
real_players,
|
||||
factory,
|
||||
cpu_counter,
|
||||
weapon_lister,
|
||||
chooser,
|
||||
&self.fake_players,
|
||||
).await
|
||||
}
|
||||
|
||||
pub(super) async fn generate_filler_players_data(
|
||||
&self,
|
||||
guid: i64,
|
||||
real_players: &[super::PlayerLobbyDescriptor],
|
||||
factory: &dyn oj_rc_factory::VehicleFactoryAdapter,
|
||||
cpu_counter: &crate::cubes::CpuListParser,
|
||||
weapon_lister: &crate::cubes::WeaponListParser,
|
||||
chooser: &super::TeamChooser,
|
||||
count: usize,
|
||||
) -> Result<Vec<(crate::data::player_data::PlayerData, crate::persist::config::ClientEmulator)>, polariton_server::operations::SimpleOpError> {
|
||||
self.generate_fake_players_data(
|
||||
guid,
|
||||
real_players,
|
||||
factory,
|
||||
cpu_counter,
|
||||
weapon_lister,
|
||||
chooser,
|
||||
&self.filler_players[0..count],
|
||||
).await
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
|
||||
@@ -265,7 +265,7 @@ pub trait LobbyUser {
|
||||
fn user_id(&self) -> i32;
|
||||
async fn player_data(&self, cpu_counter: &crate::cubes::CpuListParser) -> Result<crate::data::player_data::PlayerData, polariton_server::operations::SimpleOpError>;
|
||||
async fn team_chooser(&self, game: &GameDescriptor) -> super::TeamChooser;
|
||||
async fn start_game(&self, game: GameDescriptor, players: Vec<PlayerLobbyDescriptor>, factory: &dyn oj_rc_factory::VehicleFactoryAdapter, cpu_counter: &crate::cubes::CpuListParser, weapon_lister: &crate::cubes::WeaponListParser, team_chooser: &super::TeamChooser) -> Result<FakePlayers, polariton_server::operations::SimpleOpError>;
|
||||
async fn start_game(&self, game: GameDescriptor, players: Vec<PlayerLobbyDescriptor>, factory: &dyn oj_rc_factory::VehicleFactoryAdapter, cpu_counter: &crate::cubes::CpuListParser, weapon_lister: &crate::cubes::WeaponListParser, team_chooser: &super::TeamChooser, missing_players: usize) -> Result<FakePlayers, polariton_server::operations::SimpleOpError>;
|
||||
}
|
||||
|
||||
pub struct FakePlayers {
|
||||
|
||||
@@ -217,11 +217,12 @@ impl QueueHandler {
|
||||
display_name: x.player.display_name.clone(),
|
||||
}).collect();
|
||||
|
||||
match user.start_game(game_desc, player_descs, factory.as_ref(), &cpu_counter, &weapon_guesser, &team_picker).await {
|
||||
let missing = users_per_game.saturating_sub(players.len());
|
||||
|
||||
match user.start_game(game_desc, player_descs, factory.as_ref(), &cpu_counter, &weapon_guesser, &team_picker, missing).await {
|
||||
Ok(fakes) => {
|
||||
let missing = users_per_game.saturating_sub(players.len());
|
||||
let player_datas = players.iter().map(|x| x.player.clone())
|
||||
.chain(fakes.players.into_iter().take(missing).map(|(desc, _emu)| desc),)
|
||||
.chain(fakes.players.into_iter().map(|(desc, _emu)| desc),)
|
||||
.collect();
|
||||
let enter_battle_ev = crate::events::battle_enter::BattleEnter {
|
||||
host: hostname.clone(),
|
||||
|
||||
@@ -721,7 +721,7 @@ struct BaseTickInfo {
|
||||
}
|
||||
|
||||
impl BaseTracker {
|
||||
const DOMINATING_MULT: f32 = 10.0;
|
||||
const DOMINATING_MULT: f32 = 4.0;
|
||||
|
||||
fn new<'a>(bases_iter: impl std::iter::Iterator<Item=&'a u8>, crystals: &[oj_rc_core::cubes::CubeLocationInfo], ba_config: &oj_rc_core::data::battle_arena_config::BattleArenaData) -> Self {
|
||||
let mut bases = std::collections::HashMap::new();
|
||||
@@ -735,19 +735,40 @@ impl BaseTracker {
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_partial_base_heal(&self, crystals: &[oj_rc_core::cubes::CubeLocationInfo], crystal_health: u32, base_id: u8, base: &BaseInfo, old_index: usize, new_index: usize) -> rlnl::events::HealedCubes {
|
||||
//let base = self.bases.get(&base_id).unwrap();
|
||||
let target_crystals = &crystals[old_index..new_index];
|
||||
for crystal_i in old_index..new_index {
|
||||
base.crystals_healths[crystal_i].store(u8::MAX, std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
rlnl::events::HealedCubes {
|
||||
healed_machine: base_id as u16,
|
||||
type_performing_healing: rlnl::types::TargetType::TeamBase,
|
||||
target_type: rlnl::types::TargetType::TeamBase,
|
||||
num_healed_cubes: target_crystals.len() as _,
|
||||
hit_cubes: target_crystals
|
||||
.iter()
|
||||
.map(|loc| rlnl::types::HitCubeInfo {
|
||||
pos: rlnl::types::Byte3 { x: loc.x, y: loc.y, z: loc.z, },
|
||||
damage: crystal_health as i32,
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn tick(&self, tick_info: &PointTickInfo, crystals: &[oj_rc_core::cubes::CubeLocationInfo], generic: &crate::matches::GenericGamemodeEngine<BattleArenaLogic>, capture_points_count: usize, crystal_health: u32, ba_config: &oj_rc_core::data::battle_arena_config::BattleArenaData) -> BaseTickInfo {
|
||||
let multiplier = if let Some(dominant_team) = tick_info.dominating {
|
||||
if !self.dominating.swap(true, std::sync::atomic::Ordering::Relaxed) {
|
||||
log::info!("Team {} is now dominating game {}", dominant_team, generic.game_guid());
|
||||
// FIXME this doesn't seem to trigger the announcement client-side
|
||||
generic.broadcast(
|
||||
rlnl::event_code::NetworkEvent::CapturePointNotification,
|
||||
literustlib::packet::Property::ReliableOrdered,
|
||||
&rlnl::events::ingame::CapturePointNotification {
|
||||
notification: rlnl::types::CapturePointNotificationType::Dominating,
|
||||
id: dominant_team,
|
||||
defending_team: dominant_team as i8,
|
||||
attacking_team: (((dominant_team as usize) + 1) % generic.map_config.bases.len()) as i8
|
||||
id: u8::MAX, // ignored?
|
||||
attacking_team: dominant_team as i8,
|
||||
defending_team: -1, // ignored?
|
||||
//defending_team: (((dominant_team as usize) + 1) % generic.map_config.bases.len()) as i8
|
||||
},
|
||||
true
|
||||
).await;
|
||||
@@ -795,7 +816,8 @@ impl BaseTracker {
|
||||
],
|
||||
}
|
||||
} else {
|
||||
let target_crystals = &crystals[old_index..new_index];
|
||||
self.apply_partial_base_heal(crystals, crystal_health, *base_id, tracked_base, old_index, new_index)
|
||||
/*let target_crystals = &crystals[old_index..new_index];
|
||||
for crystal_i in old_index..new_index {
|
||||
tracked_base.crystals_healths[crystal_i].store(u8::MAX, std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
@@ -811,7 +833,7 @@ impl BaseTracker {
|
||||
damage: crystal_health as i32,
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
}*/
|
||||
};
|
||||
|
||||
generic.broadcast(
|
||||
@@ -974,6 +996,7 @@ impl BattleArenaLogic {
|
||||
pub fn new(config: &oj_rc_core::data::game_mode::GameModeConfig, map: &oj_rc_core::persist::config::MapConfig, parsers: &oj_rc_core::cubes::CubeParsers, players: &[oj_rc_core::persist::user::PlayerDescriptor], ba_config: oj_rc_core::data::battle_arena_config::BattleArenaData) -> Self {
|
||||
let cube_parser = parsers.locations_of();
|
||||
let crystals = cube_parser.locations_of_by_distance_to_first(&mut std::io::Cursor::new(&ba_config.base_machine_map), Self::CRYSTAL_ID, Self::CLASP_ID);
|
||||
//let crystals = cube_parser.locations_of_by_distance_from(&mut std::io::Cursor::new(&ba_config.base_machine_map), Self::CRYSTAL_ID, (44, 255, 46));
|
||||
Self {
|
||||
respawn_full_heal_duration: config.respawn_full_heal_duration,
|
||||
respawn_heal_duration: config.respawn_heal_duration,
|
||||
@@ -1147,7 +1170,7 @@ impl BattleArenaLogic {
|
||||
}
|
||||
}
|
||||
|
||||
async fn do_team_base_stealing(&self, cube_damage: &rlnl::events::ingame::DestroyCubeNoEffect, generic: &crate::matches::GenericGamemodeEngine<Self>, actual_damage_data: impl FnOnce(Vec<rlnl::types::CubeState>) -> crate::matches::RlnlPacket) {
|
||||
async fn do_team_base_stealing(&self, cube_damage: &rlnl::events::ingame::DestroyCubeNoEffect, generic: &crate::matches::GenericGamemodeEngine<Self>, _actual_damage_data: impl FnOnce(Vec<rlnl::types::CubeState>) -> crate::matches::RlnlPacket) {
|
||||
let base_id = cube_damage.hit_machine_id as u8;
|
||||
let mut total_destroyed = 0;
|
||||
let mut valid_cubes = Vec::with_capacity(cube_damage.hit_cubes.len());
|
||||
@@ -1178,30 +1201,49 @@ impl BattleArenaLogic {
|
||||
},
|
||||
true,
|
||||
).await;*/
|
||||
let actual_damage_data = actual_damage_data(valid_cubes);
|
||||
generic.broadcast(
|
||||
//let actual_damage_data = actual_damage_data(valid_cubes);
|
||||
/*generic.broadcast(
|
||||
actual_damage_data.event,
|
||||
actual_damage_data.property,
|
||||
actual_damage_data.data.as_ref(),
|
||||
true,
|
||||
).await;
|
||||
generic.broadcast(
|
||||
).await;*/
|
||||
/*generic.broadcast(
|
||||
rlnl::event_code::NetworkEvent::SyncTeamBaseCubes,
|
||||
literustlib::packet::Property::ReliableOrdered,
|
||||
&base.generate_full_base_heal(base_id, self.config.protonium_health as u32, &self.crystals),
|
||||
true,
|
||||
).await;
|
||||
).await;*/
|
||||
}
|
||||
if total_destroyed != 0 {
|
||||
if let Some(team_id) = self.player_tracking.team(cube_damage.shooting_machine_id as u8).await {
|
||||
if let Some(base) = self.base_tracking.bases.get(&team_id) {
|
||||
//log::info!("Player {} stole {} crystals", cube_damage.shooting_machine_id, total_destroyed);
|
||||
base.cube_index.fetch_add(total_destroyed as f32, std::sync::atomic::Ordering::SeqCst);
|
||||
generic.broadcast(
|
||||
let total_destroyed_f32 = total_destroyed as f32;
|
||||
let old_float_index = base.cube_index.fetch_add(total_destroyed_f32, std::sync::atomic::Ordering::SeqCst);
|
||||
let new_float_index = old_float_index + total_destroyed_f32;
|
||||
let old_index = (old_float_index.ceil() as usize).clamp(0, self.crystals.len());
|
||||
let new_index = (new_float_index.ceil() as usize).clamp(0, self.crystals.len());
|
||||
let payload = self.base_tracking.apply_partial_base_heal(
|
||||
&self.crystals,
|
||||
self.config.protonium_health as u32,
|
||||
team_id,
|
||||
base,
|
||||
old_index,
|
||||
new_index,
|
||||
);
|
||||
/*generic.broadcast(
|
||||
rlnl::event_code::NetworkEvent::SyncTeamBaseCubes,
|
||||
literustlib::packet::Property::ReliableOrdered,
|
||||
&base.generate_full_base_heal(team_id, self.config.protonium_health as u32, &self.crystals),
|
||||
true,
|
||||
).await;*/
|
||||
|
||||
generic.broadcast(
|
||||
rlnl::event_code::NetworkEvent::SyncTeamBaseCubes,
|
||||
literustlib::packet::Property::ReliableOrdered,
|
||||
&payload,
|
||||
true,
|
||||
).await;
|
||||
}
|
||||
} else {
|
||||
@@ -1470,7 +1512,7 @@ impl CustomGameLogic for BattleArenaLogic {
|
||||
}
|
||||
};
|
||||
self.do_team_base_stealing(&pseudo, generic, actual_damage_data).await;
|
||||
false
|
||||
true
|
||||
},
|
||||
rlnl::types::TargetType::EqualizerCrystal => {
|
||||
self.do_equalizer_damage(&pseudo, generic).await;
|
||||
@@ -1502,7 +1544,7 @@ impl CustomGameLogic for BattleArenaLogic {
|
||||
}
|
||||
};
|
||||
self.do_team_base_stealing(cube_damage, generic, &actual_damage_data).await;
|
||||
false
|
||||
true
|
||||
},
|
||||
rlnl::types::TargetType::EqualizerCrystal => {
|
||||
self.do_equalizer_damage(cube_damage, generic).await;
|
||||
|
||||
Reference in New Issue
Block a user