~starkingdoms/starkingdoms

ref: aa7b7e7c779db0d1e60bd7068a84f5c66eec718b starkingdoms/server/src/timer.rs -rw-r--r-- 4.1 KiB
aa7b7e7c — ghostlyzsh merged 2 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use std::{time::Duration, sync::Arc};
use log::{error};
use nalgebra::vector;
use rapier2d_f64::prelude::{PhysicsPipeline};
use async_std::sync::RwLock;
use async_std::task::sleep;
use starkingdoms_protocol::player::Player;
use crate::{manager::{ClientHandlerMessage, ClientManager, PhysicsData}, SCALE, planet::Planets};

pub const ROTATIONAL_FORCE: f64 = 100.0;
pub const LATERAL_FORCE: f64 = 100.0;

pub async fn timer_main(mgr: ClientManager, physics_data: Arc<RwLock<PhysicsData>>, world_data: Arc<RwLock<Planets>>) {
    let mut pipeline = PhysicsPipeline::new();
    loop {
        sleep(Duration::from_millis(5)).await;

        physics_data.write().await.tick(&mut pipeline);

        let mut protocol_players = vec![];

        {
            for (player_id, player) in mgr.players.write().await.iter() {
                let mut physics_data = physics_data.write().await;
                let player_handle = player.handle;
                let player_body = physics_data.rigid_body_set.get_mut(player_handle).unwrap();
                let planets = world_data.read().await;
                let grav_force = planets.gravity((player_body.translation().x, player_body.translation().y), player_body.mass());
                player_body.add_force(vector![grav_force.0, grav_force.1], true);

                let mut torque = 0.0;

                if player.input.right {
                    torque += ROTATIONAL_FORCE;
                }
                if player.input.left {
                    torque -= ROTATIONAL_FORCE;
                }

                player_body.add_torque(torque, true);

                let mut lateral = vector![0.0, 0.0];

                if player.input.up {
                    lateral -= vector![0.0, LATERAL_FORCE];
                }
                if player.input.down {
                    lateral += vector![0.0, LATERAL_FORCE];
                }

                let rotation = player_body.rotation().clone().angle();

                let lateral_rotated = vector![
                    lateral.x * rotation.cos() - lateral.y * rotation.sin(),
                    lateral.x * rotation.sin() + lateral.y * rotation.cos()
                ];

                player_body.add_force(lateral_rotated, true);

                let translation = player_body.translation();

                let username;
                {
                    let usernames = mgr.usernames.read().await;
                    username = usernames.get(player_id).unwrap().clone();
                }

                // TODO: Figure out how to adjust codegen to use f64
                protocol_players.push(Player {
                    rotation: rotation as f32,
                    x: (translation.x * SCALE) as f32,
                    y: (translation.y * SCALE) as f32,
                    username,
                    special_fields: Default::default(),
                });
            }
        }

        let mut to_remove = vec![];

        let mut mgr_w = mgr.handlers.write().await;
        let mgr_r = mgr_w.clone();

        for (addr, client_thread) in mgr_r.iter() {
            match client_thread.tx.send(ClientHandlerMessage::Tick).await {
                Ok(_) => {
                    match client_thread.tx.send(ClientHandlerMessage::PlayersUpdate {players: protocol_players.clone()}).await {
                        Ok(_) => (),
                        Err(e) => {
                            error!("unable to send position packet: {}", e);
                        }
                    };

                    let world = world_data.read().await;
                    let planet_data = world.to_protocol();
                    match client_thread.tx.send(planet_data).await {
                        Ok(_) => (),
                        Err(e) => {
                            error!("unable to send earth packet: {}", e);
                        }
                    };
                }
                Err(e) => {
                    error!("unable to update a client thread: {}", e);
                    to_remove.push(addr);
                }
            }
        }

        for pending_removal in to_remove {
            mgr_w.remove(pending_removal);
        }
    }
}