~starkingdoms/starkingdoms

0b02e9a2538d1e04c61d7322664c69bf0fe73628 — ghostlyzsh 1 year, 8 months ago fb42a28
energy is implemented (i hope)
M server/src/component.rs => server/src/component.rs +2 -0
@@ 90,6 90,8 @@ pub struct Player {
    pub input: Input,
    pub selected: Option<Entity>,
    pub save_eligibility: bool,
    pub energy_capacity: u32,
    pub energy: u32,
}

#[derive(Bundle)]

M server/src/main.rs => server/src/main.rs +84 -44
@@ 20,7 20,6 @@
static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;

use std::net::IpAddr;
use std::num::NonZeroUsize;

use crate::mathutil::rot2d;
use crate::ws::{StkTungsteniteServerConfig, StkTungsteniteServerPlugin, WsEvent};


@@ 32,11 31,11 @@ use bevy::{
    time::TimePlugin,
};
use bevy_rapier2d::prelude::*;
use component::Input;
use component::*;
use hmac::{Hmac, Mac};
use jwt::VerifyWithKey;
use packet::*;
use part::{HEARTY_CAPACITY, HEARTY_THRUST_ENERGY, LANDING_THRUSTER_CAPACITY, LANDING_THRUSTER_ENERGY, LANDING_THRUSTER_FORCE};
use rand::Rng;
use serde::{Deserialize, Serialize};
use sha2::Sha256;


@@ 51,6 50,7 @@ pub mod macros;
pub mod mathutil;
pub mod packet;
pub mod ws;
pub mod part;

const CLIENT_SCALE: f32 = 50.0;



@@ 65,17 65,6 @@ const MARS_MASS: f32 = EARTH_MASS / 8.;
const GRAVITY: f32 = 0.0002;
const PART_HALF_SIZE: f32 = 25.0;

const HEARTY_THRUSTER_FORCE: f32 = 0.3;
const LANDING_THRUSTER_FORCE: f32 = 5.;

const HEARTY_MASS: f32 = 1.0;
const CARGO_MASS: f32 = 0.5;
const HUB_MASS: f32 = 1.0;
const LANDING_THRUSTER_MASS: f32 = 0.9;

// maybe make this only cargo modules later
const FREE_MODULE_CAP: usize = 30;

struct StkPluginGroup;

#[cfg(debug_assertions)]


@@ 148,6 137,7 @@ fn main() {
        .add_systems(FixedUpdate, module_spawn)
        .add_systems(Update, on_message)
        .add_systems(Update, on_close)
        .add_systems(FixedUpdate, send_player_energy)
        .add_systems(FixedUpdate, on_position_change)
        .add_systems(
            FixedUpdate,


@@ 226,7 216,7 @@ fn module_spawn(
    mut packet_send: EventWriter<WsEvent>,
) {
    if module_timer.0.tick(time.delta()).just_finished() {
        if part_query.iter().count() < FREE_MODULE_CAP {
        if part_query.iter().count() < part::FREE_MODULE_CAP {
            let angle: f32 = {
                let mut rng = rand::thread_rng();
                rng.gen::<f32>() * std::f32::consts::PI * 2.


@@ 248,7 238,7 @@ fn module_spawn(
                })
                .insert(AdditionalMassProperties::MassProperties(MassProperties {
                    local_center_of_mass: vec2(0.0, 0.0),
                    mass: CARGO_MASS,
                    mass: part::CARGO_MASS,
                    principal_inertia: 7.5,
                }))
                .insert(ExternalForce::default())


@@ 382,13 372,15 @@ fn on_message(
                            input: component::Input::default(),
                            selected: None,
                            save_eligibility: false,
                            energy_capacity: part::HEARTY_CAPACITY,
                            energy: part::HEARTY_CAPACITY,
                        },
                    ));
                    entity_id
                        .insert(Collider::cuboid(0.5, 0.5))
                        .insert(AdditionalMassProperties::MassProperties(MassProperties {
                            local_center_of_mass: vec2(0.0, 0.0),
                            mass: HEARTY_MASS,
                            mass: part::HEARTY_MASS,
                            principal_inertia: 7.5,
                        }))
                        .insert(ExternalImpulse {


@@ 421,6 413,7 @@ fn on_message(
                                savefile.children,
                                &mut attached_query,
                                &mut part_query,
                                &mut player_query,
                            );
                            attach.children = children;
                        } else {


@@ 670,6 663,7 @@ fn on_message(
                                    &mut commands,
                                    entity,
                                    select,
                                    entity,
                                    &mut attached_query,
                                    &mut part_query,
                                    &mut player_query,


@@ 793,6 787,17 @@ fn load_savefile(
        ),
        (Without<PlanetType>, Without<Player>, Without<Attach>),
    >,
    player_query: &mut Query<
        (
            Entity,
            &mut Player,
            &Transform,
            &Velocity,
            &mut Attach,
            &mut PartFlags,
        ),
        Without<PlanetType>,
    >,
) -> [Option<Entity>; 4] {
    let mut ret = [None, None, None, None];
    for (i, child) in children.iter().enumerate() {


@@ 851,6 856,7 @@ fn load_savefile(
                    child.children.clone(),
                    attached_query,
                    part_query,
                    player_query,
                )
            } else {
                [None, None, None, None]


@@ 895,15 901,7 @@ fn load_savefile(
                })
                .insert(AdditionalMassProperties::MassProperties(MassProperties {
                    local_center_of_mass: vec2(0.0, 0.0),
                    mass: if part_type == PartType::Cargo {
                        CARGO_MASS
                    } else if part_type == PartType::Hub {
                        HUB_MASS
                    } else if part_type == PartType::LandingThruster {
                        LANDING_THRUSTER_MASS
                    } else {
                        1.
                    },
                    mass: mass!(part_type),
                    principal_inertia: 7.5,
                }))
                .insert(ExternalForce::default())


@@ 973,6 971,8 @@ fn load_savefile(
                    children: [None, None, Some(suspension_id), None],
                });
            }
            let mut player = player_query.get_mut(player_id).unwrap();
            player.1.energy_capacity += capacity!(part_type);
        }
    }
    ret


@@ 1094,6 1094,7 @@ fn attach_on_module_tree(
    commands: &mut Commands,
    this: Entity,
    select: Entity,
    player_id: Entity,
    attached_query: &mut Query<
        (
            Entity,


@@ 1147,6 1148,7 @@ fn attach_on_module_tree(
                commands,
                *this,
                select,
                player_id,
                attached_query,
                part_query,
                player_query,


@@ 1266,6 1268,7 @@ fn attach_on_module_tree(
        module_entity.insert(CanAttach(15));
        attach.children[attachment_slot] = Some(module.0);
        module.5.attached = true;
        player_query.get_mut(player_id).unwrap().1.energy_capacity += capacity!(*module.1);
        if *module.1 == PartType::LandingThruster {
            let loose_attach = module.4.unwrap().clone();
            let mut transform = part_query


@@ 1284,7 1287,7 @@ fn convert_modules(
    mut commands: Commands,
    rapier_context: Res<RapierContext>,
    planet_query: Query<(Entity, &PlanetType, &Children)>,
    player_query: Query<&Attach, With<Player>>,
    mut player_query: Query<(&Attach, &mut Player)>,
    mut attached_query: Query<
        (
            Entity,


@@ 1337,15 1340,17 @@ fn convert_modules(
                } else {
                    continue;
                };
                let player_attach = player_query.get(player_entity).unwrap();
                convert_modules_recursive(
                let mut player = player_query.get_mut(player_entity).unwrap();
                let increase_capacity_by = convert_modules_recursive(
                    &mut commands,
                    *planet_type,
                    player_attach.clone(),
                    player.0.clone(),
                    &mut attached_query,
                    &mut collider_query,
                    &mut packet_send,
                );
                player.1.energy_capacity += increase_capacity_by;
                player.1.energy = player.1.energy_capacity;
            }
        }
    }


@@ 1372,7 1377,8 @@ fn convert_modules_recursive(
        (Without<Player>, Without<Attach>),
    >,
    packet_send: &mut EventWriter<WsEvent>,
) {
) -> u32 {
    let mut increase_capacity_by = 0;
    for child in attach.children.iter().flatten() {
        let (
            module_entity,


@@ 1389,7 1395,7 @@ fn convert_modules_recursive(
                    *part_type = PartType::Hub;
                    *mass_prop = AdditionalMassProperties::MassProperties(MassProperties {
                        local_center_of_mass: Vec2::new(0.0, 0.0),
                        mass: HUB_MASS,
                        mass: part::HUB_MASS,
                        principal_inertia: 7.5,
                    });
                    let (mut collider, mut transform, _) =


@@ 1404,6 1410,9 @@ fn convert_modules_recursive(
                        .get_entity(module_entity)
                        .unwrap()
                        .insert(CanAttach(15));

                    increase_capacity_by += part::HUB_CAPACITY;

                    let packet = Packet::DespawnPart { id: child.index() };

                    packet_send.send(WsEvent::Broadcast {


@@ 1427,7 1436,7 @@ fn convert_modules_recursive(
                    *part_type = PartType::LandingThruster;
                    *mass_prop = AdditionalMassProperties::MassProperties(MassProperties {
                        local_center_of_mass: Vec2::new(0.0, 0.0),
                        mass: LANDING_THRUSTER_MASS,
                        mass: part::LANDING_THRUSTER_MASS,
                        principal_inertia: 7.5,
                    });
                    let (mut collider, mut transform, _) =


@@ 1470,6 1479,8 @@ fn convert_modules_recursive(
                        });
                    attach.children[2] = Some(suspension.id());

                    increase_capacity_by += part::LANDING_THRUSTER_CAPACITY;

                    let packet = Packet::DespawnPart { id: child.index() };

                    packet_send.send(WsEvent::Broadcast {


@@ 1506,7 1517,7 @@ fn convert_modules_recursive(
            }
        }
        if *part_type != PartType::LandingThruster {
            convert_modules_recursive(
            increase_capacity_by += convert_modules_recursive(
                commands,
                planet_type,
                attach.clone(),


@@ 1516,6 1527,7 @@ fn convert_modules_recursive(
            );
        }
    }
    increase_capacity_by
}

fn break_modules(


@@ 1691,6 1703,17 @@ fn despawn_module_tree(
    }
}

fn send_player_energy(
    player_query: Query<&Player>,
    mut packet_send: EventWriter<WsEvent>,
) {
    for player in &player_query {
        let packet = Packet::EnergyUpdate { amount: player.energy, max: player.energy_capacity };

        packet_send.send(WsEvent::Send { to: player.addr, message: packet.into() });
    }
}

fn on_position_change(
    mut commands: Commands,
    part_query: Query<(Entity, &PartType, &Transform, &PartFlags), Changed<Transform>>,


@@ 1768,7 1791,7 @@ fn player_input_update(
        Without<Player>,
    >,
) {
    for (_, player, attach, mut forces, transform) in &mut player_and_body_query {
    for (_, mut player, attach, mut forces, transform) in &mut player_and_body_query {
        //forces.torque = 0.0;
        //forces.force = Vec2::ZERO;
        if !(player.input.up || player.input.down || player.input.right || player.input.left) {


@@ 1818,11 1841,12 @@ fn player_input_update(
        ];

        for (force_multiplier, x_offset, y_offset) in thrusters {
            if force_multiplier != 0.0 {
            if force_multiplier != 0.0 && player.energy >= HEARTY_THRUST_ENERGY {
                player.energy -= HEARTY_THRUST_ENERGY;
                let thruster_pos_uncast = vec2(x_offset, y_offset);
                let thruster_pos_cast =
                    rot2d(thruster_pos_uncast, rot) + transform.translation.xy();
                let thruster_force = force_multiplier * HEARTY_THRUSTER_FORCE;
                let thruster_force = force_multiplier * part::HEARTY_THRUSTER_FORCE;
                let thruster_vec = vec2(-thruster_force * rot.sin(), thruster_force * rot.cos());
                let thruster_force = ExternalForce::at_point(
                    thruster_vec,


@@ 1833,23 1857,29 @@ fn player_input_update(
                forces.torque += thruster_force.torque;
            }
        }
        search_thrusters(
            player.input,
            attach.clone(),
            *transform,
            &mut attached_query,
        );
        // change to support other thruster types later
        if player.energy >= LANDING_THRUSTER_ENERGY {
            search_thrusters(
                player.input,
                attach.clone(),
                *transform,
                &mut player.energy,
                &mut attached_query,
            );
        }
    }
}
fn search_thrusters(
    input: Input,
    attach: Attach,
    p_transform: Transform,
    energy: &mut u32,
    attached_query: &mut Query<
        (&Attach, &PartType, &mut ExternalForce, &Transform),
        Without<Player>,
    >,
) {
    let mut lose_energy = 0;
    let p_angle = p_transform.rotation.to_euler(EulerRot::ZYX).0;
    for child in attach.children.iter().flatten() {
        let (attach, part_type, mut force, transform) = attached_query.get_mut(*child).unwrap();


@@ 1867,7 1897,7 @@ fn search_thrusters(

        let mut force_mult = 0.;
        if *part_type == PartType::LandingThruster {
            force_mult = LANDING_THRUSTER_FORCE;
            force_mult = part::LANDING_THRUSTER_FORCE;
        }
        if input.up && 3. * PI / 4. < relative_angle && relative_angle < 5. * PI / 4. {
            let thruster_force = ExternalForce::at_point(


@@ 1877,6 1907,7 @@ fn search_thrusters(
            );
            force.force += thruster_force.force;
            force.torque += thruster_force.torque;
            *energy -= LANDING_THRUSTER_ENERGY;
        }
        if input.down
            && ((0. < relative_angle && relative_angle < PI / 4.)


@@ 1889,6 1920,7 @@ fn search_thrusters(
            );
            force.force += thruster_force.force;
            force.torque += thruster_force.torque;
            *energy -= LANDING_THRUSTER_ENERGY;
        }
        if input.left {
            if 3. * PI / 4. < relative_angle


@@ 1902,6 1934,7 @@ fn search_thrusters(
                );
                force.force += thruster_force.force;
                force.torque += thruster_force.torque;
                *energy -= LANDING_THRUSTER_ENERGY;
            }
            if ((0. < relative_angle && relative_angle < PI / 4.)
                || (7. * PI / 4. < relative_angle && relative_angle < 2. * PI))


@@ 1914,6 1947,7 @@ fn search_thrusters(
                );
                force.force += thruster_force.force;
                force.torque += thruster_force.torque;
                *energy -= LANDING_THRUSTER_ENERGY;
            }
            if PI / 4. < relative_angle && relative_angle < 3. * PI / 4. {
                if relative_pos.y < -0.48 {


@@ 1924,6 1958,7 @@ fn search_thrusters(
                    );
                    force.force += thruster_force.force;
                    force.torque += thruster_force.torque;
                    *energy -= LANDING_THRUSTER_ENERGY;
                }
                if -0.48 < relative_pos.y && relative_pos.y < 0.48 {
                    let thruster_force = ExternalForce::at_point(


@@ 1933,6 1968,7 @@ fn search_thrusters(
                    );
                    force.force += thruster_force.force;
                    force.torque += thruster_force.torque;
                    *energy -= LANDING_THRUSTER_ENERGY;
                }
            }
            if 5. * PI / 4. < relative_angle && relative_angle < 7. * PI / 4. {


@@ 1944,6 1980,7 @@ fn search_thrusters(
                    );
                    force.force += thruster_force.force;
                    force.torque += thruster_force.torque;
                    *energy -= LANDING_THRUSTER_ENERGY;
                }
                if -0.48 < relative_pos.y && relative_pos.y < 0.48 {
                    let thruster_force = ExternalForce::at_point(


@@ 1953,12 1990,15 @@ fn search_thrusters(
                    );
                    force.force += thruster_force.force;
                    force.torque += thruster_force.torque;
                    *energy -= LANDING_THRUSTER_ENERGY;
                }
            }
        }

        if *part_type != PartType::LandingThruster {
            search_thrusters(input, attach.clone(), p_transform, attached_query);
            if *energy >= LANDING_THRUSTER_ENERGY {
                search_thrusters(input, attach.clone(), p_transform, energy, attached_query);
            }
        }
    }
}

M server/src/packet.rs => server/src/packet.rs +4 -0
@@ 138,6 138,10 @@ pub enum Packet {
    SaveData {
        payload: String,
    },
    EnergyUpdate {
        amount: u32,
        max: u32,
    },
}

impl From<Packet> for Message {

A server/src/part.rs => server/src/part.rs +51 -0
@@ 0,0 1,51 @@
pub const HEARTY_THRUSTER_FORCE: f32 = 0.3;
pub const LANDING_THRUSTER_FORCE: f32 = 5.;

pub const HEARTY_MASS: f32 = 1.0;
pub const CARGO_MASS: f32 = 0.5;
pub const HUB_MASS: f32 = 1.0;
pub const LANDING_THRUSTER_MASS: f32 = 0.9;

// maybe make this only cargo modules later
pub const FREE_MODULE_CAP: usize = 30;

// energy capacity
pub const HEARTY_CAPACITY: u32 = 2000;
pub const LANDING_THRUSTER_CAPACITY: u32 = 1000;
pub const HUB_CAPACITY: u32 = 3000;

// energy/tick
pub const HEARTY_THRUST_ENERGY: u32 = 1;
pub const LANDING_THRUSTER_ENERGY: u32 = 3;

#[macro_export]
macro_rules! mass {
    ($p:expr) => {
        if $p == crate::component::PartType::Hearty {
            crate::part::HEARTY_MASS
        } else if $p == crate::component::PartType::Cargo {
            crate::part::CARGO_MASS
        } else if $p == crate::component::PartType::Hub {
            crate::part::HUB_MASS
        } else if $p == crate::component::PartType::LandingThruster {
            crate::part::LANDING_THRUSTER_MASS
        } else {
            1.
        }
    };
}

#[macro_export]
macro_rules! capacity {
    ($p:expr) => {
        if $p == crate::component::PartType::Hearty {
            crate::part::HEARTY_CAPACITY
        } else if $p == crate::component::PartType::Hub {
            crate::part::HUB_CAPACITY
        } else if $p == crate::component::PartType::LandingThruster {
            crate::part::LANDING_THRUSTER_CAPACITY
        } else {
            0
        }
    };
}

M starkingdoms-client/src/hub.ts => starkingdoms-client/src/hub.ts +8 -0
@@ 1,6 1,7 @@
import createDebug from "debug";
import type {
  DespawnPartPacket,
  EnergyUpdatePacket,
  MessagePacket,
  Packet,
  PartPositionsPacket,


@@ 44,6 45,7 @@ export async function hub_connect(
  velocity: HTMLSpanElement,
  x_pos: HTMLSpanElement,
  y_pos: HTMLSpanElement,
  energy: HTMLDivElement,
): Promise<ClientHub | null> {
  logger("connecting to client hub at " + url);



@@ 53,6 55,7 @@ export async function hub_connect(

  let ws = new WebSocket(url);

  let energy_bar_max_width = energy.offsetWidth;
  ws.onerror = (e) => {
    console.error(e);
    throw e;


@@ 331,6 334,11 @@ export async function hub_connect(
        );
        window.localStorage.setItem("save", p.payload);
        chatbox.addMessage("server-message", "[Save] Game saved successfully!");
      } else if (packet.t == PacketType.EnergyUpdate) {
        let p = <EnergyUpdatePacket>packet.c;
        console.log(p.amount + "/" + p.max);
        let percent_energy = p.amount / p.max;
        energy.style.width = energy_bar_max_width * percent_energy + "px";
      } else {
        logger(`unrecognized packet type ${packet.t}`);
      }

M starkingdoms-client/src/pages/Play.svelte => starkingdoms-client/src/pages/Play.svelte +3 -1
@@ 18,6 18,7 @@
  let velocity;
  let x_pos;
  let y_pos;
  let energy;

  //let antialiasing: boolean = false;



@@ 85,6 86,7 @@
      velocity,
      x_pos,
      y_pos,
      energy,
    );
  });
</script>


@@ 156,7 158,7 @@
        <tr>
          <td class="hud-d"><strong>Energy:</strong></td>
          <td colspan="2" id="energy-bg" style="height:100%;width:100%;padding:0;box-sizing:border-box;border: 0.125em solid rgb(var(--text));border-radius: 0.5em;overflow:hidden;">
            <div id="energy" style="height:22px;background-color:#Af8f4f;"></div>
            <div id="energy" style="height:22px;background-color:#Af8f4f;" bind:this={energy}></div>
          </td>
        </tr>
      </tbody>

M starkingdoms-client/src/protocol.ts => starkingdoms-client/src/protocol.ts +8 -1
@@ 95,6 95,10 @@ export interface SaveEligibilityPacket {
export interface SaveDataPacket {
  payload: string;
}
export interface EnergyUpdatePacket {
  amount: number;
  max: number;
}

export enum PacketType {
  // serverbound


@@ 114,6 118,7 @@ export enum PacketType {
  Message = "Message",
  SaveEligibility = "SaveEligibility",
  SaveData = "SaveData",
  EnergyUpdate = "EnergyUpdate",
}

export interface Packet {


@@ 133,7 138,8 @@ export interface Packet {
    | PlayerMouseInputPacket
    | RequestSavePacket
    | SaveEligibilityPacket
    | SaveDataPacket;
    | SaveDataPacket
    | EnergyUpdatePacket;
}

export const SERVERBOUND = [


@@ 154,6 160,7 @@ export const CLIENTBOUND = [
  PacketType.Message,
  PacketType.SaveEligibility,
  PacketType.SaveData,
  PacketType.EnergyUpdate,
];

export enum Direction {