2024-11-23 18:10:33 +01:00
|
|
|
use std::collections::HashMap;
|
2024-11-23 17:09:42 +01:00
|
|
|
use std::fs;
|
|
|
|
|
2024-11-23 18:10:33 +01:00
|
|
|
use bevy::sprite::MaterialMesh2dBundle;
|
2024-11-23 16:24:16 +01:00
|
|
|
use bevy::{core_pipeline::smaa::SmaaSpecializedRenderPipelines, prelude::*};
|
2024-11-23 16:13:54 +01:00
|
|
|
use bevy::{prelude::*, scene::ScenePlugin};
|
2024-11-23 19:21:51 +01:00
|
|
|
// use bevy_editor_pls::EditorPlugin;
|
2024-11-23 18:10:33 +01:00
|
|
|
use bevy_rapier2d::prelude::{Collider, *};
|
|
|
|
use readformat::{readf, readf1};
|
2024-11-22 22:39:00 +01:00
|
|
|
|
2024-11-23 18:10:33 +01:00
|
|
|
use crate::game::WORLD_DEPTH;
|
2024-11-23 01:40:50 +01:00
|
|
|
use crate::AppState;
|
|
|
|
|
2024-11-23 18:33:27 +01:00
|
|
|
use super::player::PlayerSpawnOneshot;
|
2024-11-23 18:42:52 +01:00
|
|
|
use super::{PLAYER_DEPTH, PLAYER_SIZE_FRACTION};
|
2024-11-23 18:33:27 +01:00
|
|
|
|
2024-11-23 18:10:33 +01:00
|
|
|
#[derive(Component)]
|
|
|
|
struct Block;
|
|
|
|
|
2024-11-23 18:42:52 +01:00
|
|
|
#[derive(Resource, Default, Clone, Copy)]
|
2024-11-23 18:33:27 +01:00
|
|
|
pub struct PlayerCoords {
|
2024-11-23 18:22:41 +01:00
|
|
|
x: f32,
|
|
|
|
y: f32,
|
|
|
|
block_size: f32,
|
|
|
|
}
|
|
|
|
|
2024-11-23 19:00:54 +01:00
|
|
|
impl PlayerCoords {
|
|
|
|
pub fn get_collider(&self) -> Collider {
|
2024-11-23 20:19:49 +01:00
|
|
|
let size = 0.5;
|
2024-11-23 19:00:54 +01:00
|
|
|
|
2024-11-23 21:02:15 +01:00
|
|
|
Collider::round_cuboid(size, size, 1.5)
|
|
|
|
// Collider::cuboid(size, size)
|
2024-11-23 19:00:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-11-23 18:48:35 +01:00
|
|
|
impl From<PlayerCoords> for Transform {
|
|
|
|
fn from(val: PlayerCoords) -> Self {
|
|
|
|
let PlayerCoords { x, y, block_size } = val;
|
2024-11-23 18:42:52 +01:00
|
|
|
Transform {
|
|
|
|
translation: Vec3 {
|
|
|
|
x,
|
|
|
|
y,
|
|
|
|
z: PLAYER_DEPTH,
|
|
|
|
},
|
2024-11-23 18:48:35 +01:00
|
|
|
scale: Vec3::splat(val.block_size * PLAYER_SIZE_FRACTION),
|
2024-11-23 18:42:52 +01:00
|
|
|
..Default::default()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-11-22 22:39:00 +01:00
|
|
|
pub(super) fn scene_plugin(app: &mut App) {
|
2024-11-23 19:21:51 +01:00
|
|
|
// app.add_plugins(EditorPlugin::default());
|
2024-11-23 17:09:42 +01:00
|
|
|
// app.add_systems(, )
|
|
|
|
app.add_systems(Startup, (import_text_world,));
|
|
|
|
}
|
|
|
|
|
2024-11-23 18:10:33 +01:00
|
|
|
#[derive(Default)]
|
2024-11-23 17:15:27 +01:00
|
|
|
pub struct WorldInfo {
|
|
|
|
block_size: f32,
|
2024-11-23 18:10:33 +01:00
|
|
|
blocks: Vec<(String, String)>,
|
2024-11-23 17:15:27 +01:00
|
|
|
}
|
|
|
|
|
2024-11-23 18:10:33 +01:00
|
|
|
pub(super) fn import_text_world(
|
|
|
|
mut commands: Commands,
|
|
|
|
assets: Res<AssetServer>,
|
|
|
|
mut meshes: ResMut<Assets<Mesh>>,
|
|
|
|
mut materials: ResMut<Assets<ColorMaterial>>,
|
2024-11-23 18:33:27 +01:00
|
|
|
mut player_spawn_oneshot: Res<PlayerSpawnOneshot>,
|
2024-11-23 18:10:33 +01:00
|
|
|
) {
|
2024-11-23 17:15:27 +01:00
|
|
|
let world_string = fs::read_to_string("assets/world.txt").expect("need a world to load");
|
2024-11-23 19:29:35 +01:00
|
|
|
let [info_string, world_string] =
|
|
|
|
&readf("header\n{}\nbody\n{}", &world_string).expect("world does not have sections")[..]
|
2024-11-23 17:15:27 +01:00
|
|
|
else {
|
2024-11-23 18:10:33 +01:00
|
|
|
unreachable!()
|
2024-11-23 17:15:27 +01:00
|
|
|
};
|
|
|
|
|
2024-11-23 18:10:33 +01:00
|
|
|
let mut wi = WorldInfo::default();
|
2024-11-23 17:15:27 +01:00
|
|
|
for line in info_string.lines() {
|
2024-11-23 18:10:33 +01:00
|
|
|
let [name, val] = &readf(" {} = {}", line).expect("invalid line in info section")[..]
|
|
|
|
else {
|
|
|
|
unreachable!()
|
|
|
|
};
|
|
|
|
|
|
|
|
match name.as_str() {
|
|
|
|
"block-size" => wi.block_size = val.parse().unwrap(),
|
|
|
|
x if x.starts_with(".") => {
|
|
|
|
let x = readf1(".{}", x).unwrap();
|
|
|
|
wi.blocks.push((x, val.to_owned()));
|
|
|
|
}
|
|
|
|
x => panic!("invalid setting {x}"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (current_y, line) in world_string.lines().rev().enumerate() {
|
|
|
|
let mut i = 0;
|
|
|
|
// try to match every defined block
|
|
|
|
'a: while i < line.len() {
|
|
|
|
if line[i..].starts_with(" ") {
|
|
|
|
i += 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
for possible_block in wi.blocks.iter() {
|
|
|
|
if line[i..].starts_with(possible_block.0.as_str()) {
|
|
|
|
let len = possible_block.0.len();
|
|
|
|
|
|
|
|
let (tex, collider) = if let Some(s) = possible_block.1.strip_prefix("_") {
|
|
|
|
(s.to_owned(), false)
|
|
|
|
} else {
|
|
|
|
(possible_block.1.to_owned(), true)
|
|
|
|
};
|
|
|
|
|
|
|
|
let x = i as f32 * wi.block_size;
|
|
|
|
let y = current_y as f32 * wi.block_size;
|
2024-11-23 18:22:41 +01:00
|
|
|
if tex == "[player]" {
|
2024-11-23 18:33:27 +01:00
|
|
|
commands.insert_resource(PlayerCoords {
|
2024-11-23 18:22:41 +01:00
|
|
|
x,
|
|
|
|
y,
|
|
|
|
block_size: wi.block_size,
|
2024-11-23 18:33:27 +01:00
|
|
|
});
|
|
|
|
commands.run_system(player_spawn_oneshot.0);
|
2024-11-23 18:22:41 +01:00
|
|
|
} else {
|
|
|
|
spawn_block(
|
|
|
|
&mut commands,
|
|
|
|
&mut meshes,
|
|
|
|
&mut materials,
|
|
|
|
&assets,
|
|
|
|
tex,
|
|
|
|
(x, y, len, wi.block_size),
|
|
|
|
collider,
|
|
|
|
);
|
2024-11-23 18:10:33 +01:00
|
|
|
}
|
|
|
|
println!("spawned {possible_block:?} at {x}, {y}");
|
|
|
|
|
|
|
|
i += len;
|
|
|
|
continue 'a;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
panic!("unknown block in at {i},{current_y}");
|
|
|
|
}
|
2024-11-23 17:15:27 +01:00
|
|
|
}
|
2024-11-22 22:39:00 +01:00
|
|
|
}
|
2024-11-23 18:22:41 +01:00
|
|
|
|
|
|
|
fn spawn_block(
|
|
|
|
commands: &mut Commands,
|
|
|
|
meshes: &mut ResMut<Assets<Mesh>>,
|
|
|
|
materials: &mut ResMut<Assets<ColorMaterial>>,
|
|
|
|
assets: &Res<AssetServer>,
|
|
|
|
tex: String,
|
|
|
|
(x, y, len, block_size): (f32, f32, usize, f32),
|
|
|
|
collider: bool,
|
|
|
|
) {
|
|
|
|
let mut command = commands.spawn((
|
|
|
|
Block,
|
|
|
|
MaterialMesh2dBundle {
|
|
|
|
mesh: meshes
|
|
|
|
.add(Rectangle::new(block_size * len as f32, block_size))
|
|
|
|
.into(),
|
|
|
|
material: materials.add(assets.load(tex)),
|
|
|
|
transform: Transform::from_xyz(x, y, WORLD_DEPTH),
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
));
|
|
|
|
if collider {
|
|
|
|
command.insert((
|
|
|
|
RigidBody::Fixed,
|
|
|
|
Collider::cuboid(block_size / 2.0 * len as f32, block_size / 2.0),
|
|
|
|
Velocity::default(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|