~starkingdoms/starkingdoms

ref: f8a7045d08bbed2a8f0b0d3c5e9291db0c09c355 starkingdoms/server/src/entity.rs -rw-r--r-- 3.5 KiB
f8a7045d — ghostlyzsh merged auth and entities, some planet stuff may be slightly broken 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
115
116
117
use std::{sync::atomic::AtomicU32, collections::HashMap, net::SocketAddr};

use nalgebra::Vector2;
use starkingdoms_protocol::planet::PlanetType;

use crate::{planet::Planet, SCALE, manager::{ClientHandlerMessage, Player}};

pub type EntityId = u32;
pub type Entities = HashMap<EntityId, Entity>;
static mut ENTITY_ID_COUNT: AtomicU32 = AtomicU32::new(0);
pub fn get_entity_id() -> EntityId {
    let last_entity_id = unsafe { &ENTITY_ID_COUNT };
    let id = last_entity_id.fetch_add(1, std::sync::atomic::Ordering::AcqRel);
    if id > 2_147_483_600 { panic!("No remaining entity ids") };
    id
}

pub struct EntityHandler {
    pub entities: Entities,
}

impl EntityHandler {
    pub fn new() -> EntityHandler {
        EntityHandler {
            entities: Entities::new()
        }
    }
    pub fn get_planets(&self) -> Vec<Planet> {
        let mut ids = Vec::new();
        for entity in self.entities.values() {
            if let Entity::Planet(planet) = entity {
                ids.push(planet.clone());
            }
        }
        ids
    }
    pub fn get_planet(&self, planet_type: PlanetType) -> Option<Planet> {
        let mut planets = self.get_planets();
        for i in 0..planets.len() {
            if planets[i].planet_type == planet_type {
                planets.remove(i);
            }
        }
        if planets.len() == 0 {
            return None;
        }
        Some(planets[0].clone())
    }

    pub fn get_players(&self) -> Vec<(SocketAddr, Player)> {
        let mut players = Vec::new();
        for entity in self.entities.values() {
            if let Entity::Player(player) = entity {
                players.push((player.addr, player.clone()));
            }
        }
        players
    }
    pub fn get_player_id(&self, addr: SocketAddr) -> Option<EntityId> {
        for (id, entity) in self.entities.iter() {
            if let Entity::Player(player) = entity {
                if player.addr == addr {
                    return Some(*id);
                }
            }
        }
        None
    }
    pub fn get_player(&self, addr: SocketAddr) -> Option<Player> {
        let mut players = self.get_players();
        for i in 0..players.len() {
            if players[i].0 != addr {
                players.remove(i);
            }
        }
        if players.len() == 0 {
            return None;
        }
        Some(players[0].clone().1)
    }

    pub fn gravity(&self, position: (f64, f64), mass: f64) -> (f64, f64) {
        let mut direction = Vector2::zeros();
        let planets = self.get_planets();
        for planet in planets.clone() {
            let planet_grav = planet.gravity(position, mass);
            direction.x += planet_grav.0;
            direction.y += planet_grav.1;
        }
        (direction.x, direction.y)
    }

    pub fn to_protocol(&self) -> ClientHandlerMessage {
        let mut planets = vec![];

        for planet in self.get_planets().clone() {
            // TODO: Adjust codegen to use f64
            planets.push(starkingdoms_protocol::planet::Planet {
                planet_type: planet.planet_type.into(),
                x: (planet.position.0 * SCALE) as f32,
                y: (planet.position.1 * SCALE) as f32,
                radius: planet.radius as f32, // DO NOT * SCALE
                special_fields: Default::default(),
            });
        }

        ClientHandlerMessage::PlanetData {
            planets
        }
    }
}

#[derive(Clone)]
pub enum Entity {
    Player(Player),
    Planet(Planet),
}