~starkingdoms/starkingdoms

6b3599eccce0aeb36f457c69de06b87ee53f725e — core 8 months ago 2daf0b3
format
M crates/client/src/native/assets.rs => crates/client/src/native/assets.rs +7 -1
@@ 12,6 12,12 @@ pub struct ImgData {

#[derive(Resource)]
pub struct Assets {}
impl Default for Assets {
    fn default() -> Self {
        Self::new()
    }
}

impl Assets {
    pub fn new() -> Self {
        Assets {}


@@ 25,7 31,7 @@ impl Assets {
                ..Default::default()
            };
            let tree = usvg::Tree::from_data(&bytes, &opt)
                .expect(&format!("Couldn't parse svg {}", local_path));
                .unwrap_or_else(|_| panic!("Couldn't parse svg {}", local_path));
            let tree_size = tree.size().to_int_size();
            let size = usvg::Size::from_wh(200.0, 200.0).unwrap().to_int_size();
            assert!(size.width() > 0 && size.height() > 0);

M crates/client/src/networking/mod.rs => crates/client/src/networking/mod.rs +9 -15
@@ 20,7 20,7 @@ use starkingdoms_common::packet::{
    OpenCraftingUiPacket, PartPositionsPacket, PlanetPositionsPacket, PlayerLeavePacket,
    PlayerListPacket, SpawnPartPacket, SpawnPlayerPacket,
};
use starkingdoms_common::{packet::Packet, PartType, PlanetType};
use starkingdoms_common::{PartType, PlanetType};

pub mod websocket;



@@ 56,7 56,7 @@ pub fn process_packets(
    planet_types: &mut HashMap<PlanetType, (Entity, u32)>,
) {
    let mut recv_cursor = recv_packet_events.get_cursor();
    for recv in recv_cursor.read(&recv_packet_events) {
    for recv in recv_cursor.read(recv_packet_events) {
        match &recv.0 {
            LoginResponse(LoginResponsePacket { id }) => {
                let mut player_query = world.query_filtered::<Entity, With<Player>>();


@@ 156,7 156,7 @@ pub fn process_packets(
            }
            PlanetPositions(PlanetPositionsPacket { planets }) => {
                for (server_id, planet) in planets {
                    if !planet_types.contains_key(&planet.planet_type) {
                    planet_types.entry(planet.planet_type).or_insert_with(|| {
                        let entity = world.spawn(SpriteBundle {
                            transform: Transform {
                                translation: Translation3::new(


@@ 195,8 195,8 @@ pub fn process_packets(
                                .to_string(),
                            },
                        });
                        planet_types.insert(planet.planet_type, (entity.id(), *server_id));
                    }
                        (entity.id(), *server_id)
                    });
                }
            }
            EnergyUpdate(EnergyUpdatePacket { amount, max }) => {


@@ 229,11 229,8 @@ pub fn process_packets(
                        entity_to_remove = Some(entity);
                    }
                }
                match entity_to_remove {
                    Some(entity) => {
                        world.despawn(entity);
                    }
                    None => {}
                if let Some(entity) = entity_to_remove {
                    world.despawn(entity);
                }
            }
            DespawnPart(DespawnPartPacket { id }) => {


@@ 244,11 241,8 @@ pub fn process_packets(
                        entity_to_remove = Some(entity);
                    }
                }
                match entity_to_remove {
                    Some(entity) => {
                        world.despawn(entity);
                    }
                    None => {}
                if let Some(entity) = entity_to_remove {
                    world.despawn(entity);
                }
            }
            _ => {}

M crates/client/src/rendering/mod.rs => crates/client/src/rendering/mod.rs +3 -10
@@ 1,5 1,3 @@
use std::collections::HashMap;
use std::mem;
use std::mem::swap;
use std::num::NonZeroU32;
use std::sync::Arc;


@@ 8,8 6,6 @@ use bevy_ecs::entity::Entity;
use bevy_ecs::event::Events;
use bevy_ecs::query::With;
use bevy_ecs::world::World;
use egui_glow::EguiGlow;
use glow::{HasContext, PixelUnpackData};
#[cfg(not(target_arch = "wasm32"))]
use glutin::surface::{GlSurface, Surface, SwapInterval, WindowSurface};
#[cfg(not(target_arch = "wasm32"))]


@@ 21,14 17,12 @@ use glutin::{
};
#[cfg(not(target_arch = "wasm32"))]
use glutin_winit::{DisplayBuilder, GlWindow};
use nalgebra::{Scale3, Translation3, Vector3};
use nalgebra::Vector3;
use starkingdoms_common::packet::{ButtonType, Packet, PlayerInputPacket, PlayerMouseInputPacket};
use starkingdoms_common::PlanetType;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::{prelude::Closure, JsCast};
#[cfg(target_arch = "wasm32")]
use web_sys::{Event, HtmlCanvasElement};
use winit::dpi::PhysicalPosition;
use winit::event::{ElementState, MouseButton, MouseScrollDelta};
use winit::event_loop::ControlFlow;
use winit::keyboard::{KeyCode, PhysicalKey};


@@ 39,13 33,12 @@ use winit::{
    event_loop::ActiveEventLoop, raw_window_handle::HasWindowHandle, window::Window,
};

use crate::components::{Camera, Menu, Player, RecvPacket, SendPacket, Texture, Transform};
use crate::components::{Camera, Menu, RecvPacket, SendPacket};
use crate::networking::process_packets;
use crate::networking::websocket::Websocket;
use crate::platform::websocket::Ws;
use crate::rendering::renderer::{RenderCreateContext, Renderer};
use crate::rendering::MaybeRenderer::{Initialized, Initializing};
use crate::ui::{draw_ui, init_ui};
use assets::AssetLoader;

pub mod assets;


@@ 409,7 402,7 @@ impl ApplicationHandler for App {
        };
        let Some(window) = &self.window else { return };

        let mut ws = self
        let ws = self
            .world
            .get_resource_mut::<Ws>()
            .expect("Failed to get Ws resource");

M crates/client/src/rendering/renderer.rs => crates/client/src/rendering/renderer.rs +26 -30
@@ 5,7 5,6 @@ use bevy_ecs::entity::Entity;
use bevy_ecs::event::Events;
use bevy_ecs::prelude::With;
use bevy_ecs::world::World;
use egui::Window;
use egui_glow::EguiGlow;
use glow::PixelUnpackData;
use nalgebra::{Scale3, Translation3};


@@ 184,7 183,7 @@ impl Renderer {
        let mut sprite_query = world.query::<(&Transform, &mut Texture)>();

        let mut sprites = Vec::new();
        for (transform, texture) in sprite_query.iter(&world) {
        for (transform, texture) in sprite_query.iter(world) {
            sprites.push((transform, texture));
        }



@@ 202,34 201,31 @@ impl Renderer {

        if !self.textures.contains_key("starfield.svg") {
            let assets = world.resource::<crate::platform::assets::Assets>();
            match assets.get("starfield.svg") {
                Some(image) => {
                    let texture_object = gl
                        .create_texture()
                        .expect("Failed to create texture object");
                    gl.bind_texture(glow::TEXTURE_2D, Some(texture_object));
                    gl.tex_parameter_i32(
                        glow::TEXTURE_2D,
                        glow::TEXTURE_MIN_FILTER,
                        glow::LINEAR_MIPMAP_LINEAR as i32,
                    );
                    gl.tex_image_2d(
                        glow::TEXTURE_2D,
                        0,
                        glow::RGBA as i32,
                        image.width as i32,
                        image.height as i32,
                        0,
                        glow::RGBA,
                        glow::UNSIGNED_BYTE,
                        PixelUnpackData::Slice(Some(&image.bytes)),
                    );
                    gl.generate_mipmap(glow::TEXTURE_2D);

                    self.textures
                        .insert("starfield.svg".to_string(), texture_object);
                }
                None => {}
            if let Some(image) = assets.get("starfield.svg") {
                let texture_object = gl
                    .create_texture()
                    .expect("Failed to create texture object");
                gl.bind_texture(glow::TEXTURE_2D, Some(texture_object));
                gl.tex_parameter_i32(
                    glow::TEXTURE_2D,
                    glow::TEXTURE_MIN_FILTER,
                    glow::LINEAR_MIPMAP_LINEAR as i32,
                );
                gl.tex_image_2d(
                    glow::TEXTURE_2D,
                    0,
                    glow::RGBA as i32,
                    image.width as i32,
                    image.height as i32,
                    0,
                    glow::RGBA,
                    glow::UNSIGNED_BYTE,
                    PixelUnpackData::Slice(Some(&image.bytes)),
                );
                gl.generate_mipmap(glow::TEXTURE_2D);

                self.textures
                    .insert("starfield.svg".to_string(), texture_object);
            }
        }
        if self.textures.contains_key("starfield.svg") {

M crates/client/src/ui/mod.rs => crates/client/src/ui/mod.rs +2 -2
@@ 61,7 61,7 @@ pub fn draw_ui(

pub fn draw_status_bar(ctx: &egui::Context, world: &mut World) {
    let mut player = world.query_filtered::<&Transform, With<Player>>();
    let player_position = player.single(&world);
    let player_position = player.single(world);
    let player_resources = world.resource::<PlayerResources>();

    egui::Window::new("status_bar")


@@ 152,7 152,7 @@ pub fn draw_chat(
pub fn draw_crafting(ctx: &egui::Context, world: &mut World) {
    let mut menus = world.query_filtered::<(Entity, &Transform), With<Menu>>();
    let camera = world.resource::<Camera>();
    for (entity, menu) in menus.iter(&world) {
    for (entity, menu) in menus.iter(world) {
        egui::Window::new("Crafting")
            .id(format!("Crafting{}", entity.index()).into())
            .pivot(Align2::LEFT_BOTTOM)

M crates/kabel/src/codegen.rs => crates/kabel/src/codegen.rs +8 -8
@@ 628,7 628,7 @@ impl Codegen {
            .push(OpCode::LOAD.into());
        let loc = (self.vm.units[self.vm.unit_ptr].pool.len() - 1) as u8;
        self.vm.units[self.vm.unit_ptr].code.push(loc);
        if self.vm.units[self.vm.unit_ptr].lines.len() == 0
        if self.vm.units[self.vm.unit_ptr].lines.is_empty()
            || self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != block.end_line
        {
            self.vm.units[self.vm.unit_ptr]


@@ 737,7 737,7 @@ impl Codegen {
                    .push(OpCode::LOAD.into());
                let loc = (self.vm.units[self.vm.unit_ptr].pool.len() - 1) as u8;
                self.vm.units[self.vm.unit_ptr].code.push(loc);
                if self.vm.units[self.vm.unit_ptr].lines.len() == 0
                if self.vm.units[self.vm.unit_ptr].lines.is_empty()
                    || self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line
                {
                    self.vm.units[self.vm.unit_ptr]


@@ 750,13 750,13 @@ impl Codegen {
            Lit::Str(value) => {
                self.vm.units[self.vm.unit_ptr]
                    .pool
                    .push(Value::Str(value.into()));
                    .push(Value::Str(value));
                self.vm.units[self.vm.unit_ptr]
                    .code
                    .push(OpCode::LOAD.into());
                let loc = (self.vm.units[self.vm.unit_ptr].pool.len() - 1) as u8;
                self.vm.units[self.vm.unit_ptr].code.push(loc);
                if self.vm.units[self.vm.unit_ptr].lines.len() == 0
                if self.vm.units[self.vm.unit_ptr].lines.is_empty()
                    || self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line
                {
                    self.vm.units[self.vm.unit_ptr]


@@ 775,7 775,7 @@ impl Codegen {
                    .push(OpCode::LOAD.into());
                let loc = (self.vm.units[self.vm.unit_ptr].pool.len() - 1) as u8;
                self.vm.units[self.vm.unit_ptr].code.push(loc);
                if self.vm.units[self.vm.unit_ptr].lines.len() == 0
                if self.vm.units[self.vm.unit_ptr].lines.is_empty()
                    || self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line
                {
                    self.vm.units[self.vm.unit_ptr]


@@ 793,7 793,7 @@ impl Codegen {
                    .code
                    .push(OpCode::LIST.into());
                self.vm.units[self.vm.unit_ptr].code.push(exprs.len() as u8);
                if self.vm.units[self.vm.unit_ptr].lines.len() == 0
                if self.vm.units[self.vm.unit_ptr].lines.is_empty()
                    || self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line
                {
                    self.vm.units[self.vm.unit_ptr]


@@ 814,7 814,7 @@ impl Codegen {
                    println!("slot: {}", *slot);
                    self.vm.units[self.vm.unit_ptr].code.push(*slot);*/
                    self.vm.units[self.vm.unit_ptr].code.push(ptr as u8);
                    if self.vm.units[self.vm.unit_ptr].lines.len() == 0
                    if self.vm.units[self.vm.unit_ptr].lines.is_empty()
                        || self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line
                    {
                        self.vm.units[self.vm.unit_ptr]


@@ 837,7 837,7 @@ impl Codegen {
            .code
            .push(OpCode::CALL.into());
        self.vm.units[self.vm.unit_ptr].code.push(args.len() as u8);
        if self.vm.units[self.vm.unit_ptr].lines.len() == 0
        if self.vm.units[self.vm.unit_ptr].lines.is_empty()
            || self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line
        {
            self.vm.units[self.vm.unit_ptr]

M crates/kabel/src/lexer.rs => crates/kabel/src/lexer.rs +9 -9
@@ 258,7 258,7 @@ impl Lexer {
            '"' => {
                let mut contents = String::new();
                while self.read_char("File ended before closing quote")? != '"' {
                    contents.push(self.c as char);
                    contents.push(self.c);
                }
                self.output.push(token!(self, TokenType::Str(contents)));
                self.start = self.line_current;


@@ 275,9 275,9 @@ impl Lexer {
            }
            c => {
                if c.is_ascii_alphabetic() || c == '_' {
                    let mut content = (c as char).to_string();
                    let mut content = c.to_string();
                    while self.peek("").unwrap_or('%').is_ascii_alphanumeric() || self.c == '_' {
                        content.push(self.c as char);
                        content.push(self.c);
                        self.read_char("Kabel broke")?;
                    }
                    if self.keywords.contains_key(&content) {


@@ 288,16 288,16 @@ impl Lexer {
                    }
                    self.start = self.line_current;
                } else if c.is_ascii_digit() {
                    let mut number = (c as char).to_string();
                    let mut number = c.to_string();
                    while self.peek("").unwrap_or(' ').is_ascii_digit() {
                        number.push(self.c as char);
                        number.push(self.c);
                        self.read_char("Kabel broke")?;
                    }
                    if self.c == '.' {
                        number.push('.');
                        self.read_char("Kabel broke")?;
                        while self.peek("").unwrap_or(' ').is_ascii_digit() {
                            number.push(self.c as char);
                            number.push(self.c);
                            self.read_char("Kabel broke")?;
                        }
                    }


@@ 308,7 308,7 @@ impl Lexer {
                } else {
                    self.errors.push(KabelError::new(
                        ErrorKind::UnexpectedToken,
                        format!("Stray \"{0}\"", c as char),
                        format!("Stray \"{0}\"", { c }),
                        None,
                        self.line,
                        self.column,


@@ 337,7 337,7 @@ impl Lexer {
        self.current += 1;
        self.column += 1;
        self.line_current += 1;
        return Ok(self.c);
        Ok(self.c)
    }
    pub fn peek(&mut self, message: &str) -> Result<char, KabelError> {
        if self.current >= self.input.len() {


@@ 353,7 353,7 @@ impl Lexer {
            ));
        }
        self.c = self.input[self.current];
        return Ok(self.c);
        Ok(self.c)
    }
}


M crates/kabel/src/lib.rs => crates/kabel/src/lib.rs +3 -3
@@ 69,7 69,7 @@ pub fn compile(program: String) -> String {
    {
        output += &debug_token_array(lexer.output.clone());
    }
    if lexer.errors.len() != 0 || lexer.output.len() == 0 {
    if !lexer.errors.is_empty() || lexer.output.is_empty() {
        return output;
    }



@@ 88,7 88,7 @@ pub fn compile(program: String) -> String {
        output += &error.to_string();
        output += "\n";
    }
    if parser.errors.len() != 0 {
    if !parser.errors.is_empty() {
        return output;
    }
    #[cfg(feature = "timer")]


@@ 98,7 98,7 @@ pub fn compile(program: String) -> String {
        output += &error.to_string();
        output += "\n";
    }
    if analyzer.errors.len() != 0 {
    if !analyzer.errors.is_empty() {
        return output;
    }
    #[cfg(feature = "timer")]

M crates/kabel/src/main.rs => crates/kabel/src/main.rs +3 -3
@@ 24,7 24,7 @@ fn main() {
        output += "\n";
    }
    //output += &format!("{:?}", lexer.output);
    if lexer.errors.len() != 0 || lexer.output.len() == 0 {
    if !lexer.errors.is_empty() || lexer.output.is_empty() {
        println!("{}", output);
        return;
    }


@@ 36,7 36,7 @@ fn main() {
        output += &error.to_string();
        output += "\n";
    }
    if parser.errors.len() != 0 {
    if !parser.errors.is_empty() {
        println!("{}", output);
        return;
    }


@@ 48,7 48,7 @@ fn main() {
        output += &error.to_string();
        output += "\n";
    }
    if analyzer.errors.len() != 0 {
    if !analyzer.errors.is_empty() {
        println!("{}", output);
        return;
    }

M crates/kabel/src/name_resolution.rs => crates/kabel/src/name_resolution.rs +21 -24
@@ 409,29 409,26 @@ impl Resolver {
            }
            Lit(ref lit) => {
                let lit = lit.clone();
                match lit {
                    crate::ast::Lit::Ident(ref name) => {
                        let resolution = self.resolve_var(name);
                        if !resolution.0 {
                            self.errors.push(ast_error!(
                                self,
                                ErrorKind::OutOfScope,
                                ast,
                                "Variable \"{}\" not in scope",
                                name
                            ))
                        } else {
                            return AST {
                                kind: Lit(lit),
                                extensions: vec![Extension::Resolution(self.scope, resolution.1)],
                                start_line: ast.start_line,
                                end_line: ast.end_line,
                                start_column: ast.start_column,
                                end_column: ast.end_column,
                            };
                        }
                if let crate::ast::Lit::Ident(ref name) = lit {
                    let resolution = self.resolve_var(name);
                    if !resolution.0 {
                        self.errors.push(ast_error!(
                            self,
                            ErrorKind::OutOfScope,
                            ast,
                            "Variable \"{}\" not in scope",
                            name
                        ))
                    } else {
                        return AST {
                            kind: Lit(lit),
                            extensions: vec![Extension::Resolution(self.scope, resolution.1)],
                            start_line: ast.start_line,
                            end_line: ast.end_line,
                            start_column: ast.start_column,
                            end_column: ast.end_column,
                        };
                    }
                    _ => {}
                }
                ast_from_ast!(AST, Lit(lit), ast, ast)
            }


@@ 441,14 438,14 @@ impl Resolver {
                for arg in args {
                    n_args.push(self.visit(arg));
                }
                return AST {
                AST {
                    kind: Call(Box::new(ident), n_args),
                    extensions: Vec::new(),
                    start_line: ast.start_line,
                    end_line: ast.end_line,
                    start_column: ast.start_column,
                    end_column: ast.end_column,
                };
                }
            }
            /*Member(left, right) => {
                self.visit_member(*left, *right);

M crates/kabel/src/parser.rs => crates/kabel/src/parser.rs +56 -56
@@ 94,32 94,32 @@ impl Parser {
                let right_paren = self.read_token()?;
                if let TokenType::RightParen = right_paren.token_type {
                    let block = self.block()?;
                    return Ok(ast_from_token_ast!(
                    Ok(ast_from_token_ast!(
                        AST,
                        ASTType::Function(name!(name, ident), expressions, Box::new(block.clone())),
                        function_ident,
                        block
                    ));
                    ))
                } else {
                    return Err(unexpected_token!(
                    Err(unexpected_token!(
                        self,
                        "Expected ) but found {}",
                        right_paren
                    ));
                    ))
                }
            } else {
                return Err(unexpected_token!(
                Err(unexpected_token!(
                    self,
                    "Expected ( but found {}",
                    left_paren
                ));
                ))
            }
        } else {
            return Err(unexpected_token!(
            Err(unexpected_token!(
                self,
                "Expected identifier but found {}",
                ident
            ));
            ))
        }
    }



@@ 144,11 144,11 @@ impl Parser {
                semicolon
            ))
        } else {
            return Err(unexpected_token!(
            Err(unexpected_token!(
                self,
                "Expected ; but found {}",
                semicolon
            ));
            ))
        }
    }



@@ 171,25 171,25 @@ impl Parser {
            let right_paren = self.read_token()?;
            if let TokenType::RightParen = right_paren.token_type {
                let block = self.block()?;
                return Ok(ast_from_token_ast!(
                Ok(ast_from_token_ast!(
                    AST,
                    ASTType::While(Box::new(condition), Box::new(block.clone())),
                    while_ident,
                    block
                ));
                ))
            } else {
                return Err(unexpected_token!(
                Err(unexpected_token!(
                    self,
                    "Expected ) but found {}",
                    right_paren
                ));
                ))
            }
        } else {
            return Err(unexpected_token!(
            Err(unexpected_token!(
                self,
                "Expected ( but found {}",
                left_paren
            ));
            ))
        }
    }



@@ 234,7 234,7 @@ impl Parser {
                if let TokenType::RightParen = right_paren.token_type {
                    let block = self.block()?;
                    //return Ok(Self::build_for(for_ident, semicolon_2, expression1, expression2, expression3, block));
                    return Ok(ast_from_token_ast!(
                    Ok(ast_from_token_ast!(
                        AST,
                        ASTType::For(
                            Box::new(expression1),


@@ 244,27 244,27 @@ impl Parser {
                        ),
                        for_ident,
                        block
                    ));
                    ))
                } else {
                    return Err(unexpected_token!(
                    Err(unexpected_token!(
                        self,
                        "Expected ) but found {}",
                        right_paren
                    ));
                    ))
                }
            } else {
                return Err(unexpected_token!(
                Err(unexpected_token!(
                    self,
                    "Expected ; but found {}",
                    semicolon_2
                ));
                ))
            }
        } else {
            return Err(unexpected_token!(
            Err(unexpected_token!(
                self,
                "Expected ( but found {}",
                left_paren
            ));
            ))
        }
    }
    /*fn build_for(for_ident: Token, semicolon_2: Token, expression1: Option<AST>, expression2: Option<AST>, expression3: Option<AST>, block: AST) -> AST {


@@ 364,25 364,25 @@ impl Parser {
                        return Err(unexpected_token!(self, "Unexpected token {}", else_ident));
                    }
                }
                return Ok(ast_from_token_ast!(
                Ok(ast_from_token_ast!(
                    AST,
                    ASTType::If(Box::new(condition), Box::new(block.clone()), Box::new(None)),
                    if_ident,
                    block
                ));
                ))
            } else {
                return Err(unexpected_token!(
                Err(unexpected_token!(
                    self,
                    "Expected ) but found {}",
                    right_paren
                ));
                ))
            }
        } else {
            return Err(unexpected_token!(
            Err(unexpected_token!(
                self,
                "Expected ( but found {}",
                left_paren
            ));
            ))
        }
    }



@@ 394,18 394,18 @@ impl Parser {
                stmts.push(self.statement()?);
            }
            let right_brace = self.read_token()?;
            return Ok(ast_from_token!(
            Ok(ast_from_token!(
                AST,
                ASTType::Block(stmts),
                left_brace,
                right_brace
            ));
            ))
        } else {
            return Err(unexpected_token!(
            Err(unexpected_token!(
                self,
                "Expected {{ but found {}",
                left_brace
            ));
            ))
        }
    }



@@ 418,24 418,24 @@ impl Parser {
                let expr = self.expression()?;
                let semicolon = self.read_token()?;
                if let TokenType::Semicolon = semicolon.token_type {
                    return Ok(ast_from_token!(
                    Ok(ast_from_token!(
                        AST,
                        ASTType::Decl(name!(name, ident), Box::new(expr.clone())),
                        var,
                        semicolon
                    ));
                    ))
                } else {
                    return Err(unexpected_token!(self, "Expected ; but found {}", equal));
                    Err(unexpected_token!(self, "Expected ; but found {}", equal))
                }
            } else {
                return Err(unexpected_token!(self, "Expected = but found {}", equal));
                Err(unexpected_token!(self, "Expected = but found {}", equal))
            }
        } else {
            return Err(unexpected_token!(
            Err(unexpected_token!(
                self,
                "Expected identifier but found {}",
                ident
            ));
            ))
        }
    }



@@ 475,19 475,19 @@ impl Parser {
        }
        let semicolon = self.read_token()?;
        if let TokenType::Semicolon = semicolon.token_type {
            return Ok(ast_from_ast_token!(
            Ok(ast_from_ast_token!(
                AST,
                ASTType::Expr(Box::new(expression.clone())),
                expression,
                semicolon
            ));
            ))
        } else {
            self.current -= 1;
            return Err(unexpected_token!(
            Err(unexpected_token!(
                self,
                "Expected ; but found {}",
                semicolon
            ));
            ))
        }
    }



@@ 722,7 722,7 @@ impl Parser {
            return self.anonymous_function();
        }

        return self.anonymous_function();
        self.anonymous_function()
    }

    pub fn anonymous_function(&mut self) -> Result<AST, KabelError> {


@@ 823,7 823,7 @@ impl Parser {
                }
            }
        }
        return self.ternary();
        self.ternary()
    }

    pub fn ternary(&mut self) -> Result<AST, KabelError> {


@@ 1151,24 1151,24 @@ impl Parser {
                        return self.incdec(token);
                    }
                }
                return Ok(lit!(Ident, ident.clone(), token));
                Ok(lit!(Ident, ident.clone(), token))
            }
            TokenType::Num(num) => {
                return Ok(lit!(Num, num, token));
                Ok(lit!(Num, num, token))
            }
            TokenType::Str(string) => {
                return Ok(lit!(Str, string, token));
                Ok(lit!(Str, string, token))
            }
            TokenType::True => return Ok(lit!(Bool, true, token)),
            TokenType::False => return Ok(lit!(Bool, false, token)),
            TokenType::True => Ok(lit!(Bool, true, token)),
            TokenType::False => Ok(lit!(Bool, false, token)),
            TokenType::LeftParen => {
                return self.group(token);
                self.group(token)
            }
            TokenType::LeftSquare => {
                return self.array(token);
                self.array(token)
            }
            _ => {
                return Err(unexpected_token!(self, "Unexpected token {}", token));
                Err(unexpected_token!(self, "Unexpected token {}", token))
            }
        }
    }


@@ 1355,7 1355,7 @@ impl Parser {
        }
        self.token = self.input[self.current].clone();
        self.current += 1;
        return Ok(self.token.clone());
        Ok(self.token.clone())
    }
    pub fn peek(&mut self) -> Result<Token, KabelError> {
        if self.current >= self.input.len() {


@@ 1369,6 1369,6 @@ impl Parser {
                self.text[last_token.line].clone(),
            ));
        }
        return Ok(self.input[self.current].clone());
        Ok(self.input[self.current].clone())
    }
}

M crates/kabel/src/test.rs => crates/kabel/src/test.rs +3 -3
@@ 18,7 18,7 @@ fn test_lexer([program, out]: [&str; 2]) {
        output += &error.to_string();
        output += "\n";
    }
    if lexer.errors.len() != 0 || lexer.output.len() == 0 {
    if !lexer.errors.is_empty() || lexer.output.is_empty() {
        assert_eq!(output, out);
        return;
    }


@@ 35,7 35,7 @@ fn test_parser([program, out]: [&str; 2]) {
        output += &error.to_string();
        output += "\n";
    }
    if lexer.errors.len() != 0 || lexer.output.len() == 0 {
    if !lexer.errors.is_empty() || lexer.output.is_empty() {
        panic!("lexer error");
    }



@@ 45,7 45,7 @@ fn test_parser([program, out]: [&str; 2]) {
        output += &error.to_string();
        output += "\n";
    }
    if parser.errors.len() != 0 {
    if !parser.errors.is_empty() {
        assert_eq!(output, out);
        return;
    }

M crates/kabel/src/vm.rs => crates/kabel/src/vm.rs +3 -3
@@ 668,7 668,7 @@ impl VM {
                        self.stack
                            .insert(self.stack.len() - num_args as usize, Value::Fun(function));
                        self.ip = 0;
                        self.unit_ptr = function.unit_ptr as usize;
                        self.unit_ptr = function.unit_ptr;
                    } else {
                        return Err(vm_error!(
                            self,


@@ 749,7 749,7 @@ impl VM {
                    for _ in 0..times {
                        self.stack
                            .pop()
                            .expect(&format!("{}: Unable to pop stack", self.ip));
                            .unwrap_or_else(|| panic!("{}: Unable to pop stack", self.ip));
                    }
                }
                0xFE => {


@@ 837,7 837,7 @@ impl ToString for Value {
            List(v) => {
                let mut output = "".to_string();
                output += "[";
                for value in <Vec<Value>>::clone(&v).into_iter() {
                for value in <Vec<Value>>::clone(v).into_iter() {
                    output += &value.to_string();
                    output += ",";
                }

M crates/server/src/crafting/mining.rs => crates/server/src/crafting/mining.rs +2 -2
@@ 72,7 72,7 @@ pub fn find_storage(
                    continue;
                }
                return Some(entity);
            } else if attach.associated_player == None {
            } else if attach.associated_player.is_none() {
                // this is a player
                if storage.materials.values().sum::<u32>() > storage.capacity {
                    // cannot store more materials in a filled storage


@@ 82,5 82,5 @@ pub fn find_storage(
            }
        }
    }
    return None;
    None
}

M crates/server/src/module/mod.rs => crates/server/src/module/mod.rs +4 -4
@@ 63,7 63,7 @@ pub fn module_spawn(
        let packet = Packet::SpawnPart(SpawnPartPacket {
            id: entity.id().index(),
            part: Part {
                part_type: c_PartType::Chassis.into(),
                part_type: c_PartType::Chassis,
                transform: proto_transform!(transform),
                flags: proto_part_flags!(flags),
            },


@@ 511,7 511,7 @@ fn convert_modules_recursive(
                    let packet = Packet::SpawnPart(SpawnPartPacket {
                        id: child.index(),
                        part: Part {
                            part_type: c_PartType::Hub.into(),
                            part_type: c_PartType::Hub,
                            transform: proto_transform!(transform),
                            flags: proto_part_flags!(part_flags),
                        },


@@ 576,7 576,7 @@ fn convert_modules_recursive(
                    let packet = Packet::SpawnPart(SpawnPartPacket {
                        id: child.index(),
                        part: Part {
                            part_type: c_PartType::LandingThruster.into(),
                            part_type: c_PartType::LandingThruster,
                            transform: proto_transform!(transform),
                            flags: proto_part_flags!(part_flags),
                        },


@@ 589,7 589,7 @@ fn convert_modules_recursive(
                    let packet = Packet::SpawnPart(SpawnPartPacket {
                        id: suspension.id().index(),
                        part: Part {
                            part_type: c_PartType::LandingThrusterSuspension.into(),
                            part_type: c_PartType::LandingThrusterSuspension,
                            transform: proto_transform!(transform),
                            flags: proto_part_flags!(part_flags),
                        },

M crates/server/src/planet.rs => crates/server/src/planet.rs +1 -1
@@ 122,7 122,7 @@ pub fn spawn_planets(mut commands: Commands) {
                .insert(Sensor);
        })
        .insert(RigidBody::Fixed);
    let mars_pos = Transform::from_xyz(9142.0833, 0.0, 0.0);
    let mars_pos = Transform::from_xyz(9_142.083, 0.0, 0.0);
    commands
        .spawn(PlanetBundle {
            planet_type: PlanetType(c_PlanetType::Mars),

M crates/server/src/player/client_login.rs => crates/server/src/player/client_login.rs +1 -1
@@ 326,7 326,7 @@ pub fn packet_stream(
    parts.push((
        index,
        Part {
            part_type: c_PartType::Hearty.into(),
            part_type: c_PartType::Hearty,
            transform: proto_transform!(Transform::from_translation(transform.translation)
                .with_rotation(transform.rotation)),
            flags: ProtoPartFlags { attached: false },

M crates/server/src/player/player_mouse_input.rs => crates/server/src/player/player_mouse_input.rs +10 -12
@@ 189,18 189,16 @@ pub fn mouse_picking(
        let y = rel_x * angle.sin() + rel_y * angle.cos();
        let bound = [-0.5, 0.5, -0.5, 0.5]; // left, right, top, bottom

        if bound[0] < x && x < bound[1] && bound[2] < y && y < bound[3] {
            if *button == ButtonType::Right {
                send_events.push(WsEvent::Send {
                    to: q_player.addr,
                    message: Packet::OpenCraftingUi(OpenCraftingUiPacket { id: entity.index() })
                        .into_message(),
                });
                // toggle mining
                /*if let Ok(mut is_mining) = mining_query.get_mut(entity) {
                    is_mining.0 = !is_mining.0;
                }*/
            }
        if bound[0] < x && x < bound[1] && bound[2] < y && y < bound[3] && *button == ButtonType::Right {
            send_events.push(WsEvent::Send {
                to: q_player.addr,
                message: Packet::OpenCraftingUi(OpenCraftingUiPacket { id: entity.index() })
                    .into_message(),
            });
            // toggle mining
            /*if let Ok(mut is_mining) = mining_query.get_mut(entity) {
                is_mining.0 = !is_mining.0;
            }*/
        }
    }
}