veloren_rtsim/data/
airship.rs1use common::{
2 rtsim::{NpcId, SiteId},
3 util::Dir,
4};
5use std::cmp::Ordering;
6use vek::*;
7use world::{civ::airship_travel::Airships, index::Index, util::DHashMap};
8
9pub type AirshipRouteId = u32;
11#[derive(Clone, Default)]
12pub struct AirshipSim {
13 pub assigned_routes: DHashMap<NpcId, AirshipRouteId>,
16 pub route_pilots: DHashMap<AirshipRouteId, Vec<NpcId>>,
19}
20
21const AIRSHIP_DEBUG: bool = false;
22
23macro_rules! debug_airships {
24 ($($arg:tt)*) => {
25 if AIRSHIP_DEBUG {
26 tracing::debug!($($arg)*);
27 }
28 }
29}
30
31impl AirshipSim {
32 pub fn register_airship_captain(
36 &mut self,
37 docking_pos: Vec3<f32>,
38 captain_id: NpcId,
39 airship_id: NpcId,
40 index: &Index,
41 airships: &Airships,
42 ) -> Option<Vec3<f32>> {
43 if let Some((route_id, approach_index)) =
46 airships.airship_route_for_docking_pos(docking_pos)
47 && let Some(route) = airships.routes.get(&route_id)
48 {
49 let site0_name = index.sites.get(route.sites[0]).name().to_string();
50 let site1_name = index.sites.get(route.sites[1]).name().to_string();
51 debug_airships!(
52 "Registering airship {:?}/{:?} for docking position {:?}, site0:{}, site1:{}",
53 airship_id,
54 captain_id,
55 docking_pos,
56 site0_name,
57 site1_name
58 );
59
60 self.assigned_routes.insert(captain_id, route_id);
61 let approach = &route.approaches[approach_index];
62 let airship_wpos = approach
63 .approach_final_pos
64 .with_z(approach.airship_pos.z + approach.height);
65 debug_airships!(
66 "Airship {:?}/{:?}, approach index:{}, initial wpos:{:?}",
67 airship_id,
68 captain_id,
69 approach_index,
70 airship_wpos
71 );
72 Some(airship_wpos)
73 } else {
74 tracing::warn!(
77 "Failed to register airship captain {:?} for docking position {:?}",
78 captain_id,
79 docking_pos
80 );
81 None
82 }
83 }
84
85 pub fn configure_route_pilots(&mut self, airships: &Airships) {
88 self.route_pilots
93 .extend(airships.routes.iter().map(|(route_id, _)| {
94 (
95 *route_id,
96 self.assigned_routes
97 .iter()
98 .filter(|(_, assigned_route_id)| **assigned_route_id == *route_id)
99 .map(|(pilot_id, _)| *pilot_id)
100 .collect(),
101 )
102 }));
103 debug_airships!("Route pilots: {:?}", self.route_pilots);
104 }
105}
106
107#[derive(Debug)]
108pub struct AirshipSpawningLocation {
109 pub pos: Vec3<f32>,
110 pub dir: Dir,
111 pub center: Vec2<i32>,
112 pub docking_pos: Vec3<i32>,
113 pub site_id: SiteId,
114 pub site_name: String,
115}
116
117impl PartialEq for AirshipSpawningLocation {
118 fn eq(&self, other: &Self) -> bool {
119 self.center == other.center
120 && self.docking_pos == other.docking_pos
121 && self.site_id == other.site_id
122 }
123}
124
125impl Eq for AirshipSpawningLocation {}
126
127impl Ord for AirshipSpawningLocation {
128 fn cmp(&self, other: &Self) -> Ordering {
129 self.site_id
130 .cmp(&other.site_id)
131 .then_with(|| self.docking_pos.cmp(&other.docking_pos))
132 }
133}
134
135impl PartialOrd for AirshipSpawningLocation {
136 fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }
137}