mirror of
https://git.ngram.ca/OpenJam/rc-servers
synced 2026-08-23 23:08:52 +00:00
Rotate players and reactors to face center of map by default
This commit is contained in:
@@ -1450,6 +1450,7 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn send_sync_events(connection: UserSender, _player_id: u8, players: Vec<std::sync::Arc<oj_rc_core::persist::user::PlayerDescriptor>>, extra_packets: Vec<super::RlnlPacket>, map: std::sync::Arc<oj_rc_core::persist::config::MapConfig>) -> std::io::Result<()> {
|
async fn send_sync_events(connection: UserSender, _player_id: u8, players: Vec<std::sync::Arc<oj_rc_core::persist::user::PlayerDescriptor>>, extra_packets: Vec<super::RlnlPacket>, map: std::sync::Arc<oj_rc_core::persist::config::MapConfig>) -> std::io::Result<()> {
|
||||||
|
let map_center = super::modes::calculate_center(map.spawns.values().flat_map(|x| x.iter()));
|
||||||
let num_players = players.len() as u8;
|
let num_players = players.len() as u8;
|
||||||
let sender = connection.rlnl();
|
let sender = connection.rlnl();
|
||||||
sender.send_empty(
|
sender.send_empty(
|
||||||
@@ -1518,7 +1519,7 @@ impl <L: super::CustomGameLogic> GenericGamemodeEngine<L> {
|
|||||||
&rlnl::events::sync::SpawnPoint {
|
&rlnl::events::sync::SpawnPoint {
|
||||||
pos: rlnl::types::PosQuatPair {
|
pos: rlnl::types::PosQuatPair {
|
||||||
pos: rlnl::types::CompressedVec3::from((spawn.x, spawn.y, spawn.z)),
|
pos: rlnl::types::CompressedVec3::from((spawn.x, spawn.y, spawn.z)),
|
||||||
rot: rlnl::types::CompressedQuat { x: 0, y: 0, z: 0 },
|
rot: super::modes::looking_at_point(spawn, &map_center),
|
||||||
},
|
},
|
||||||
owner: player.player_id,
|
owner: player.player_id,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1124,6 +1124,7 @@ pub struct BattleArenaLogic {
|
|||||||
crystals: std::sync::Arc<Vec<oj_rc_core::cubes::CubeLocationInfo>>,
|
crystals: std::sync::Arc<Vec<oj_rc_core::cubes::CubeLocationInfo>>,
|
||||||
config: oj_rc_core::data::battle_arena_config::BattleArenaData,
|
config: oj_rc_core::data::battle_arena_config::BattleArenaData,
|
||||||
can_drop_shields: bool,
|
can_drop_shields: bool,
|
||||||
|
map_center: oj_rc_core::persist::config::Point,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BattleArenaLogic {
|
impl BattleArenaLogic {
|
||||||
@@ -1151,6 +1152,7 @@ impl BattleArenaLogic {
|
|||||||
can_drop_shields: super_conf.descriptor.overrides.as_ref()
|
can_drop_shields: super_conf.descriptor.overrides.as_ref()
|
||||||
.map(|overrides| overrides.base_shields_go_down)
|
.map(|overrides| overrides.base_shields_go_down)
|
||||||
.unwrap_or(true),
|
.unwrap_or(true),
|
||||||
|
map_center: super::calculate_center(super_conf.map.spawns.values().flat_map(|x| x.iter())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1300,6 +1302,7 @@ impl BattleArenaLogic {
|
|||||||
respawn_timestamp,
|
respawn_timestamp,
|
||||||
connections,
|
connections,
|
||||||
spawn_point,
|
spawn_point,
|
||||||
|
Some(self.map_center.clone()),
|
||||||
player_id,
|
player_id,
|
||||||
player_desc.machine.is_alive.clone(),
|
player_desc.machine.is_alive.clone(),
|
||||||
));
|
));
|
||||||
@@ -1458,12 +1461,34 @@ impl CustomGameLogic for BattleArenaLogic {
|
|||||||
property: literustlib::packet::Property::ReliableOrdered,
|
property: literustlib::packet::Property::ReliableOrdered,
|
||||||
data: Box::new(rlnl::events::sync::GetTeamBase {
|
data: Box::new(rlnl::events::sync::GetTeamBase {
|
||||||
base_1: rlnl::types::PosQuatPair {
|
base_1: rlnl::types::PosQuatPair {
|
||||||
pos: generic.map_config.bases.get(&0).map(|(s, _)| (s.center.x, s.center.y, s.center.z)).unwrap_or((0.0, 0.0, 0.0)).into(),
|
pos: generic.map_config.bases.get(&0)
|
||||||
rot: (0.0, 0.0, 0.0, 0.0).into(),
|
.map(|(s, _)| (s.center.x, s.center.y, s.center.z))
|
||||||
|
.unwrap_or((0.0, 0.0, 0.0)).into(),
|
||||||
|
rot: generic.map_config.bases.get(&0)
|
||||||
|
.map(|(s, _)| {
|
||||||
|
let loc = oj_rc_core::persist::config::Point {
|
||||||
|
x: s.center.x,
|
||||||
|
y: s.center.y,
|
||||||
|
z: s.center.z,
|
||||||
|
};
|
||||||
|
super::looking_at_point(&loc, &self.map_center)
|
||||||
|
})
|
||||||
|
.unwrap_or((0.0, 0.0, 0.0, 0.0).into()),
|
||||||
},
|
},
|
||||||
base_2: rlnl::types::PosQuatPair {
|
base_2: rlnl::types::PosQuatPair {
|
||||||
pos: generic.map_config.bases.get(&1).map(|(s, _)| (s.center.x, s.center.y, s.center.z)).unwrap_or((0.0, 0.0, 0.0)).into(),
|
pos: generic.map_config.bases.get(&1)
|
||||||
rot: (0.0, 0.0, 0.0, 0.0).into(),
|
.map(|(s, _)| (s.center.x, s.center.y, s.center.z))
|
||||||
|
.unwrap_or((0.0, 0.0, 0.0)).into(),
|
||||||
|
rot: generic.map_config.bases.get(&1)
|
||||||
|
.map(|(s, _)| {
|
||||||
|
let loc = oj_rc_core::persist::config::Point {
|
||||||
|
x: s.center.x,
|
||||||
|
y: s.center.y,
|
||||||
|
z: s.center.z,
|
||||||
|
};
|
||||||
|
super::looking_at_point(&loc, &self.map_center)
|
||||||
|
})
|
||||||
|
.unwrap_or((0.0, 0.0, 0.0, 0.0).into()),
|
||||||
},
|
},
|
||||||
protonium_cube_health: self.config.protonium_health as i32,
|
protonium_cube_health: self.config.protonium_health as i32,
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -16,13 +16,14 @@ pub use team_death_match::TeamDeathMatchLogic;
|
|||||||
|
|
||||||
pub(super) mod trackers;
|
pub(super) mod trackers;
|
||||||
|
|
||||||
async fn respawn_player_after(after: chrono::DateTime<chrono::Utc>, players: Vec<crate::matches::generic::UserSender>, spawn: oj_rc_core::persist::config::Point, player_id: u8, alive_flag: std::sync::Arc<std::sync::atomic::AtomicBool>) {
|
async fn respawn_player_after(after: chrono::DateTime<chrono::Utc>, players: Vec<crate::matches::generic::UserSender>, spawn: oj_rc_core::persist::config::Point, looking_at: Option<oj_rc_core::persist::config::Point>, player_id: u8, alive_flag: std::sync::Arc<std::sync::atomic::AtomicBool>) {
|
||||||
let sleep_dur = after.signed_duration_since(chrono::Utc::now()).to_std().expect("Respawn duration too long to sleep");
|
let sleep_dur = after.signed_duration_since(chrono::Utc::now()).to_std().expect("Respawn duration too long to sleep");
|
||||||
tokio::time::sleep(sleep_dur).await;
|
tokio::time::sleep(sleep_dur).await;
|
||||||
let spawn_payload = rlnl::events::sync::SpawnPoint {
|
let spawn_payload = rlnl::events::sync::SpawnPoint {
|
||||||
pos: rlnl::types::PosQuatPair {
|
pos: rlnl::types::PosQuatPair {
|
||||||
pos: rlnl::types::CompressedVec3::from((spawn.x, spawn.y, spawn.z)),
|
pos: rlnl::types::CompressedVec3::from((spawn.x, spawn.y, spawn.z)),
|
||||||
rot: rlnl::types::CompressedQuat { x: 0, y: 0, z: 0 },
|
rot: looking_at.map(|at| looking_at_point(&spawn, &at))
|
||||||
|
.unwrap_or(rlnl::types::CompressedQuat { x: 0, y: 0, z: 0 }),
|
||||||
},
|
},
|
||||||
owner: player_id,
|
owner: player_id,
|
||||||
};
|
};
|
||||||
@@ -38,3 +39,26 @@ async fn respawn_player_after(after: chrono::DateTime<chrono::Utc>, players: Vec
|
|||||||
}
|
}
|
||||||
alive_flag.store(true, std::sync::atomic::Ordering::Relaxed);
|
alive_flag.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn looking_at_point(loc: &oj_rc_core::persist::config::Point, at: &oj_rc_core::persist::config::Point) -> rlnl::types::CompressedQuat<4> {
|
||||||
|
let unit_quat = num_quaternion::UnitQuaternion::from_two_vectors(&[0.0, 0.0, 1.0], &[at.x - loc.x, 0.0, at.z - loc.z]);
|
||||||
|
let actual_quat = unit_quat.as_quaternion();
|
||||||
|
rlnl::types::CompressedQuat::from((actual_quat.w, actual_quat.x, actual_quat.y, actual_quat.z))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn calculate_center<'a>(points: impl Iterator<Item = &'a oj_rc_core::persist::config::Point>) -> oj_rc_core::persist::config::Point {
|
||||||
|
let mut tally = (0.0_f64, 0.0_f64, 0.0_f64);
|
||||||
|
let mut total = 0;
|
||||||
|
for point in points {
|
||||||
|
total += 1;
|
||||||
|
tally.0 += point.x as f64;
|
||||||
|
tally.1 += point.y as f64;
|
||||||
|
tally.2 += point.z as f64;
|
||||||
|
}
|
||||||
|
oj_rc_core::persist::config::Point {
|
||||||
|
x: (tally.0 / total as f64) as _,
|
||||||
|
y: (tally.1 / total as f64) as _,
|
||||||
|
z: (tally.2 / total as f64) as _,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -160,6 +160,7 @@ pub struct PitLogic {
|
|||||||
settings: std::sync::Arc<oj_rc_core::persist::config::PitSettings>,
|
settings: std::sync::Arc<oj_rc_core::persist::config::PitSettings>,
|
||||||
timer_task: tokio::sync::Mutex<Option<tokio::task::JoinHandle<()>>>,
|
timer_task: tokio::sync::Mutex<Option<tokio::task::JoinHandle<()>>>,
|
||||||
initial_spawns: Vec<(u8, oj_rc_core::persist::config::Point)>, // (player_id, spawn_point)
|
initial_spawns: Vec<(u8, oj_rc_core::persist::config::Point)>, // (player_id, spawn_point)
|
||||||
|
map_center: oj_rc_core::persist::config::Point,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PitLogic {
|
impl PitLogic {
|
||||||
@@ -172,6 +173,7 @@ impl PitLogic {
|
|||||||
timer_task: tokio::sync::Mutex::new(None),
|
timer_task: tokio::sync::Mutex::new(None),
|
||||||
settings: pit_settings,
|
settings: pit_settings,
|
||||||
initial_spawns: Self::generate_first_spawns(map, players),
|
initial_spawns: Self::generate_first_spawns(map, players),
|
||||||
|
map_center: super::calculate_center(map.pit_spawns.iter()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,7 +340,7 @@ impl PitLogic {
|
|||||||
data: Box::new(rlnl::events::sync::SpawnPoint {
|
data: Box::new(rlnl::events::sync::SpawnPoint {
|
||||||
pos: rlnl::types::PosQuatPair {
|
pos: rlnl::types::PosQuatPair {
|
||||||
pos: rlnl::types::CompressedVec3::from((spawn_point.x, spawn_point.y, spawn_point.z)),
|
pos: rlnl::types::CompressedVec3::from((spawn_point.x, spawn_point.y, spawn_point.z)),
|
||||||
rot: rlnl::types::CompressedQuat { x: 0, y: 0, z: 0 },
|
rot: super::looking_at_point(spawn_point, &self.map_center),
|
||||||
},
|
},
|
||||||
owner: *player_id,
|
owner: *player_id,
|
||||||
})
|
})
|
||||||
@@ -370,6 +372,7 @@ impl PitLogic {
|
|||||||
respawn_timestamp,
|
respawn_timestamp,
|
||||||
connections,
|
connections,
|
||||||
spawn_point,
|
spawn_point,
|
||||||
|
Some(self.map_center.clone()),
|
||||||
player_id,
|
player_id,
|
||||||
player_desc.machine.is_alive.clone(),
|
player_desc.machine.is_alive.clone(),
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -212,10 +212,11 @@ pub struct TeamDeathMatchLogic {
|
|||||||
score_tracking: ScoreTracker,
|
score_tracking: ScoreTracker,
|
||||||
player_tracking: PlayerTracker,
|
player_tracking: PlayerTracker,
|
||||||
surrender_tracking: super::trackers::SurrenderGameTracker,
|
surrender_tracking: super::trackers::SurrenderGameTracker,
|
||||||
|
map_center: oj_rc_core::persist::config::Point,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TeamDeathMatchLogic {
|
impl TeamDeathMatchLogic {
|
||||||
pub fn new(config: &oj_rc_core::data::game_mode::GameModeConfig, _map: &oj_rc_core::persist::config::MapConfig, players: &[oj_rc_core::persist::user::PlayerDescriptor], tdm_settings: std::sync::Arc<oj_rc_core::persist::config::TeamDeathMatchSettings>) -> Self {
|
pub fn new(config: &oj_rc_core::data::game_mode::GameModeConfig, map: &oj_rc_core::persist::config::MapConfig, players: &[oj_rc_core::persist::user::PlayerDescriptor], tdm_settings: std::sync::Arc<oj_rc_core::persist::config::TeamDeathMatchSettings>) -> Self {
|
||||||
let self_destruct_is_kill = tdm_settings.self_destruct_is_kill;
|
let self_destruct_is_kill = tdm_settings.self_destruct_is_kill;
|
||||||
TeamDeathMatchLogic {
|
TeamDeathMatchLogic {
|
||||||
respawn_heal_duration: config.respawn_heal_duration,
|
respawn_heal_duration: config.respawn_heal_duration,
|
||||||
@@ -226,6 +227,7 @@ impl TeamDeathMatchLogic {
|
|||||||
score_tracking: ScoreTracker::new(players, self_destruct_is_kill),
|
score_tracking: ScoreTracker::new(players, self_destruct_is_kill),
|
||||||
player_tracking: PlayerTracker::new(players),
|
player_tracking: PlayerTracker::new(players),
|
||||||
surrender_tracking: super::trackers::SurrenderGameTracker::new(),
|
surrender_tracking: super::trackers::SurrenderGameTracker::new(),
|
||||||
|
map_center: super::calculate_center(map.spawns.values().flat_map(|x| x.iter())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,6 +311,7 @@ impl TeamDeathMatchLogic {
|
|||||||
respawn_timestamp,
|
respawn_timestamp,
|
||||||
connections,
|
connections,
|
||||||
spawn_point,
|
spawn_point,
|
||||||
|
Some(self.map_center.clone()),
|
||||||
player_id,
|
player_id,
|
||||||
player_desc.machine.is_alive.clone(),
|
player_desc.machine.is_alive.clone(),
|
||||||
));
|
));
|
||||||
|
|||||||
Reference in New Issue
Block a user