travelling and other shit
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
use std::io::{stdin,stdout,Write};
|
||||
use std::io::{stdin,stdout,Write};
|
||||
use crate::Command;
|
||||
|
||||
pub fn input() -> String{
|
||||
let mut s=String::new();
|
||||
@@ -14,3 +15,10 @@ pub fn input() -> String{
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
pub fn clear_screen()
|
||||
{
|
||||
Command::new("clear")
|
||||
.status()
|
||||
.expect("Failed to clear screen");
|
||||
}
|
||||
|
69
src/main.rs
69
src/main.rs
@@ -8,10 +8,13 @@ mod output_map; // output_map.rs
|
||||
mod save; // save.rs
|
||||
mod initialise; // initialise.rs, creates a new character
|
||||
mod function; // function.rs, for misc functions
|
||||
mod process_input; // process_input.rs
|
||||
|
||||
const HELP_STRING: &str = "'help' = output's this help text
|
||||
'travel' = travel to a given location
|
||||
";
|
||||
pub enum GameAction {
|
||||
Continue,
|
||||
Exit,
|
||||
Error,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
struct Coordinates {
|
||||
@@ -33,67 +36,61 @@ struct Player {
|
||||
inventory: Vec<(String, u64)>,
|
||||
}
|
||||
|
||||
fn clear_screen()
|
||||
{
|
||||
Command::new("clear")
|
||||
.status()
|
||||
.expect("Failed to clear screen");
|
||||
}
|
||||
const DEBUG_MODE: bool = false;
|
||||
|
||||
fn main()
|
||||
{
|
||||
let debug_mode: bool = true;
|
||||
let save_file_path: &str = "data/save.json";
|
||||
let (screen_width, screen_height) = termion::terminal_size().unwrap();
|
||||
let distance_you_can_see: [i16; 2] =
|
||||
[
|
||||
(screen_width as f32 / 2.0) as i16,
|
||||
(screen_height as f32 / 2.0) as i16
|
||||
];
|
||||
if debug_mode
|
||||
{
|
||||
println!("Screen Width: {}, Screen Height: {}", screen_width, screen_height);
|
||||
}
|
||||
let player: Player;
|
||||
|
||||
if let Ok(save_file_contents) = fs::read_to_string(save_file_path) // Load save file
|
||||
{
|
||||
if let Ok(player) = serde_json::from_str::<Player>(save_file_contents.as_str())
|
||||
if let Ok(mut player) = serde_json::from_str::<Player>(save_file_contents.as_str())
|
||||
{
|
||||
if debug_mode == true
|
||||
if DEBUG_MODE == true
|
||||
{
|
||||
println!("{:?}", player);
|
||||
}
|
||||
if let Ok((ground_map, above_map)) = parse_map::parse_map(&player.coordinates) // Call the parse map function from parse_map.rs
|
||||
{ // Parse the map file into a vector
|
||||
if DEBUG_MODE == false
|
||||
{
|
||||
function::clear_screen;
|
||||
}
|
||||
output_map::output_map // Call output_map fuctino from output_map.rs
|
||||
(
|
||||
&ground_map,
|
||||
&above_map,
|
||||
&player.coordinates,
|
||||
&distance_you_can_see
|
||||
); // Output the map
|
||||
'game_loop: loop
|
||||
{
|
||||
if debug_mode == false
|
||||
{
|
||||
clear_screen()
|
||||
}
|
||||
print!("> ");
|
||||
let user_input: String = function::input();
|
||||
if user_input == "help"
|
||||
let result = process_input::process_input
|
||||
(
|
||||
user_input,
|
||||
&mut player,
|
||||
&ground_map,
|
||||
&above_map,
|
||||
);
|
||||
|
||||
if let Err(e) = save::save(&save_file_path, &player)
|
||||
{
|
||||
print!("\n{}\n", HELP_STRING);
|
||||
eprintln!("Error saving game: {}",e);
|
||||
continue;
|
||||
}
|
||||
else if user_input == "exit" || user_input == "quit"
|
||||
match result
|
||||
{
|
||||
if let Err(e) = save::save(&save_file_path, &player)
|
||||
GameAction::Exit =>
|
||||
{
|
||||
eprintln!("Error saving game: {}",e);
|
||||
continue;
|
||||
}
|
||||
print!("Exiting...\n");
|
||||
break 'game_loop;
|
||||
println!("Exitting...");
|
||||
break 'game_loop;
|
||||
},
|
||||
_ =>
|
||||
{
|
||||
continue 'game_loop;
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -2,15 +2,26 @@ use colored::Colorize; // For coloring the output
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::Coordinates;
|
||||
use crate::DEBUG_MODE;
|
||||
|
||||
|
||||
// Output the map based on map vector
|
||||
pub fn output_map(
|
||||
ground_map: &Vec<Vec<char>>,
|
||||
above_map: &Vec<Vec<char>>,
|
||||
player_coordinates: &Coordinates,
|
||||
distance_you_can_see: &[i16; 2]
|
||||
)
|
||||
{
|
||||
let (screen_width, screen_height) = termion::terminal_size().unwrap();
|
||||
let distance_you_can_see: [i16; 2] =
|
||||
[
|
||||
(screen_width as f32 / 2.0) as i16,
|
||||
(screen_height as f32 / 2.0) as i16
|
||||
];
|
||||
if DEBUG_MODE == true
|
||||
{
|
||||
println!("Screen Width: {}, Screen Height: {}", screen_width, screen_height);
|
||||
}
|
||||
let blocks: HashMap<char, [u8; 3]> =
|
||||
[
|
||||
('X', [255,0, 0]), // Null
|
||||
@@ -31,18 +42,18 @@ pub fn output_map(
|
||||
.iter().cloned().collect();
|
||||
|
||||
// Loop over array and print each block
|
||||
for i in player_coordinates.z - distance_you_can_see[1]..player_coordinates.z + distance_you_can_see[1]
|
||||
for z in player_coordinates.z - distance_you_can_see[1]..player_coordinates.z + distance_you_can_see[1]
|
||||
{
|
||||
if i >= 0 && i < ground_map.len() as i16
|
||||
if z >= 0 && z < ground_map.len() as i16
|
||||
{
|
||||
for j in player_coordinates.x - distance_you_can_see[0]..player_coordinates.x+distance_you_can_see[0]
|
||||
for x in player_coordinates.x - distance_you_can_see[0]..player_coordinates.x+distance_you_can_see[0]
|
||||
{
|
||||
if j >= 0 && j < ground_map[i as usize].len() as i16
|
||||
if x >= 0 && x < ground_map[z as usize].len() as i16
|
||||
{
|
||||
let character: char = ground_map[i as usize][j as usize];
|
||||
let above_character: char = above_map[i as usize][j as usize];
|
||||
let character: char = ground_map[z as usize][x as usize];
|
||||
let above_character: char = above_map[z as usize][x as usize];
|
||||
// Check if the character is at the current coordinates
|
||||
if i == player_coordinates.z && j == player_coordinates.x
|
||||
if z == player_coordinates.z && x == player_coordinates.x
|
||||
{
|
||||
print!
|
||||
(
|
||||
|
126
src/process_input.rs
Normal file
126
src/process_input.rs
Normal file
@@ -0,0 +1,126 @@
|
||||
use std::fs;
|
||||
use crate::GameAction;
|
||||
use crate::Player;
|
||||
use crate::DEBUG_MODE;
|
||||
use crate::output_map;
|
||||
use crate::function;
|
||||
|
||||
pub fn process_input
|
||||
(
|
||||
user_input: String,
|
||||
player: &mut Player,
|
||||
ground_map: &Vec<Vec<char>>,
|
||||
above_map: &Vec<Vec<char>>,
|
||||
) -> GameAction
|
||||
{
|
||||
// Split commands up, so "help && travel 5" > [["help"], ["travel", "5]]
|
||||
let mut commands: Vec<Vec<&str>> = Vec::new();
|
||||
if user_input != ""
|
||||
{
|
||||
let split_user_input: Vec<&str> = user_input.split("&&").collect();
|
||||
for whole_command in &split_user_input
|
||||
{
|
||||
let mut split_command: Vec<&str> = whole_command.split(" ").collect();
|
||||
if split_command[0] == ""
|
||||
{
|
||||
split_command.remove(0);
|
||||
}
|
||||
if split_command.last().unwrap() == &""
|
||||
{
|
||||
split_command.remove(split_command.len()-1);
|
||||
}
|
||||
commands.push(split_command);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
println!("No command");
|
||||
}
|
||||
|
||||
// Loop over each command
|
||||
for command in commands
|
||||
{
|
||||
match command[0].to_lowercase().as_str()
|
||||
{
|
||||
"help"|"h" =>
|
||||
if let Ok(help_text) = fs::read_to_string("data/help.txt") // Output text from help file
|
||||
{
|
||||
println!("\n{}", help_text);
|
||||
},
|
||||
"exit"|"quit"|"q" =>
|
||||
{
|
||||
return GameAction::Exit;
|
||||
},
|
||||
"map"|"world" =>
|
||||
{
|
||||
output_map::output_map // Call output_map fuctino from output_map.rs
|
||||
(
|
||||
&ground_map,
|
||||
&above_map,
|
||||
&player.coordinates,
|
||||
); // Output the map
|
||||
},
|
||||
"clear"|"cls" =>
|
||||
{
|
||||
function::clear_screen();
|
||||
},
|
||||
"travel"|"move"|"go" =>
|
||||
{
|
||||
let mut magnitude: usize = 1;
|
||||
let mut vector: &str = "";
|
||||
if command.len() == 3
|
||||
{
|
||||
if let Ok(number) = command[1].parse::<usize>()
|
||||
{
|
||||
magnitude = number;
|
||||
vector = command[2];
|
||||
}
|
||||
else if let Ok(number) = command[2].parse::<usize>()
|
||||
{
|
||||
magnitude = number;
|
||||
vector = command[1];
|
||||
}
|
||||
}
|
||||
else if command.len() == 2
|
||||
{
|
||||
vector = command[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
println!("Invalid travel command");
|
||||
return GameAction::Error;
|
||||
};
|
||||
if DEBUG_MODE == true
|
||||
{
|
||||
println!("{}, {} blocks", vector, magnitude);
|
||||
}
|
||||
for _block in 0..magnitude
|
||||
{
|
||||
match vector
|
||||
{
|
||||
"north"|"n"|"up" |"u" => player.coordinates.z -= 1,
|
||||
"east" |"e"|"right"|"r" => player.coordinates.x += 1,
|
||||
"south"|"s"|"down" |"d" => player.coordinates.z += 1,
|
||||
"west" |"w"|"left" |"l" => player.coordinates.x -= 1,
|
||||
_ => {println!("Invalid travel direction"); break;},
|
||||
}
|
||||
if above_map[player.coordinates.z as usize][player.coordinates.x as usize] != ' '
|
||||
{
|
||||
println!("Bumped into something!");
|
||||
match vector
|
||||
{
|
||||
"north"|"n"|"up" |"u" => player.coordinates.z += 1,
|
||||
"east" |"e"|"right"|"r" => player.coordinates.x -= 1,
|
||||
"south"|"s"|"down" |"d" => player.coordinates.z -= 1,
|
||||
"west" |"w"|"left" |"l" => player.coordinates.x += 1,
|
||||
_ => println!("Invalid travel direction"),
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => println!("Invalid Input"),
|
||||
}
|
||||
}
|
||||
GameAction::Continue
|
||||
}
|
@@ -12,9 +12,9 @@ pub fn save(
|
||||
let player_json = serde_json::to_string_pretty(&player).unwrap();
|
||||
|
||||
|
||||
println!("Saving...");
|
||||
//println!("Saving...");
|
||||
let mut save_file = File::create(save_file_path)?;
|
||||
save_file.write_all(player_json.as_bytes())?;
|
||||
println!("Saved...");
|
||||
//println!("Saved...");
|
||||
Ok(())
|
||||
}
|
||||
|
Reference in New Issue
Block a user