init
This commit is contained in:
1
platforms/cli/.gitignore
vendored
Normal file
1
platforms/cli/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/target
|
||||
8
platforms/cli/Cargo.toml
Normal file
8
platforms/cli/Cargo.toml
Normal file
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "cli"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
default-run = "cli"
|
||||
|
||||
[dependencies]
|
||||
game-core = { path = "../../game-core" }
|
||||
23
platforms/cli/src/disk_loader.rs
Normal file
23
platforms/cli/src/disk_loader.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
use game_core::assets::AssetLoader;
|
||||
|
||||
pub struct DiskLoader;
|
||||
|
||||
impl AssetLoader for DiskLoader {
|
||||
fn load_chunk(&mut self, offset: u32, length: usize, dest: &mut [u8]) -> Result<usize, ()> {
|
||||
// In a real implementation, this would read from disk.
|
||||
// For this example, we'll just fill the buffer with dummy data.
|
||||
let dummy_data = vec![0u8; length];
|
||||
dest[..length].copy_from_slice(&dummy_data);
|
||||
Ok(length)
|
||||
}
|
||||
|
||||
fn load_map(&mut self, map_id: u8, buffer: &mut [u8]) -> Result<usize, ()> {
|
||||
let map_data = [
|
||||
5, 5, 2, 2, 2, 2, 2, 2, 1, 1, 4, 2, 2, 1, 3, 1, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2,
|
||||
];
|
||||
|
||||
let len = map_data.len();
|
||||
buffer[..len].copy_from_slice(&map_data);
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
93
platforms/cli/src/main.rs
Normal file
93
platforms/cli/src/main.rs
Normal file
@@ -0,0 +1,93 @@
|
||||
use std::io::{self, Write};
|
||||
|
||||
use game_core::{input::InputEvent, render::RenderRequest, state::Game, types::Direction};
|
||||
|
||||
use crate::disk_loader::DiskLoader;
|
||||
|
||||
mod disk_loader;
|
||||
|
||||
fn main() {
|
||||
let mut game = Game::new();
|
||||
let mut loader = DiskLoader;
|
||||
|
||||
loop {
|
||||
let mut input_str = String::new();
|
||||
print!("> ");
|
||||
io::stdout().flush().unwrap();
|
||||
io::stdin().read_line(&mut input_str).unwrap();
|
||||
|
||||
let input = match input_str.trim() {
|
||||
"w" => InputEvent::Move(Direction::North),
|
||||
"s" => InputEvent::Move(Direction::South),
|
||||
"a" => InputEvent::Move(Direction::West),
|
||||
"d" => InputEvent::Move(Direction::East),
|
||||
"e" => InputEvent::Action,
|
||||
_ => InputEvent::None,
|
||||
};
|
||||
|
||||
let render = game.tick(input, &mut loader);
|
||||
|
||||
print!("{}[2J", 27 as char); // Clear screen
|
||||
match render {
|
||||
RenderRequest::MainMenu => {
|
||||
println!("Welcome to the Twillight Island! Press 'e' to start.")
|
||||
}
|
||||
RenderRequest::CharacterCreation { prompt, .. } => {
|
||||
println!("Creating Char: {}", prompt)
|
||||
}
|
||||
RenderRequest::Exploration {
|
||||
tiles,
|
||||
width,
|
||||
player_idx,
|
||||
message,
|
||||
} => {
|
||||
println!("STATUS: {}", message);
|
||||
let w = width as usize;
|
||||
// skip header (2 bytes)
|
||||
let map_tiles = &tiles[2..];
|
||||
|
||||
for (i, &tile_byte) in map_tiles.iter().enumerate() {
|
||||
if i % w == 0 {
|
||||
println!();
|
||||
}
|
||||
|
||||
if i == player_idx {
|
||||
print!("@");
|
||||
} else {
|
||||
let char = match tile_byte {
|
||||
1 => '.', // Grass
|
||||
2 => '~', // Water
|
||||
3 => '#', // Wall
|
||||
4 => 'E', // Enemy
|
||||
_ => ' ',
|
||||
};
|
||||
print!("{}", char);
|
||||
}
|
||||
}
|
||||
println!();
|
||||
}
|
||||
RenderRequest::Combat {
|
||||
player_stats,
|
||||
enemy_stats,
|
||||
log,
|
||||
} => {
|
||||
println!("COMBAT!");
|
||||
println!(
|
||||
"Player HP: {}/{}",
|
||||
player_stats.hp_current, player_stats.hp_max
|
||||
);
|
||||
println!(
|
||||
"Enemy HP: {}/{}",
|
||||
enemy_stats.hp_current, enemy_stats.hp_max
|
||||
);
|
||||
println!("{}", log);
|
||||
}
|
||||
RenderRequest::Dialogue { text, options } => {
|
||||
println!("{}", text);
|
||||
for (i, option) in options.iter().enumerate() {
|
||||
println!("{}: {}", i + 1, option);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user