Client is approx 5% done
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
/server/target
|
/server/target
|
||||||
|
/client/target
|
||||||
*.swp
|
*.swp
|
||||||
.venv
|
.venv
|
||||||
.~*
|
.~*
|
||||||
|
|||||||
Generated
+2059
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
|||||||
|
[package]
|
||||||
|
name = "happening-client"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
macroquad = "0.4.15"
|
||||||
|
phf = {version="0.13.1",features=["macros"]}
|
||||||
|
reqwest = {version="0.13.3",features=["blocking","json"]}
|
||||||
|
serde = {version="1.0.228",features=["derive"]}
|
||||||
|
serde_json = "1.0.149"
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
use macroquad::prelude::*;
|
||||||
|
use reqwest::*;
|
||||||
|
use reqwest::blocking;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use phf::phf_map;
|
||||||
|
use std::{thread, time::Duration};
|
||||||
|
use serde::
|
||||||
|
{
|
||||||
|
Serialize,
|
||||||
|
Deserialize,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone, Default)]
|
||||||
|
pub struct Data {
|
||||||
|
pub action_type: String,
|
||||||
|
pub content: String,
|
||||||
|
pub character: String,
|
||||||
|
pub choices: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone, Default)]
|
||||||
|
#[serde(default)]
|
||||||
|
pub struct Character
|
||||||
|
{
|
||||||
|
name: String,
|
||||||
|
gender: String,
|
||||||
|
eye_color: Colour,
|
||||||
|
hair_color: Colour,
|
||||||
|
skin_color: Colour,
|
||||||
|
pronoun_subject: String,
|
||||||
|
pronoun_object: String,
|
||||||
|
pronoun_deppos: String,
|
||||||
|
pronoun_indpos: String,
|
||||||
|
pronoun_reflex: String,
|
||||||
|
head_shape: String,
|
||||||
|
hair_style: String,
|
||||||
|
torso_shape: String,
|
||||||
|
arm_shape: String,
|
||||||
|
leg_shape: String,
|
||||||
|
clothing: Clothing,
|
||||||
|
}
|
||||||
|
#[derive(Debug,Deserialize,Serialize,Clone,Default)]
|
||||||
|
#[serde(default)]
|
||||||
|
pub struct Clothing
|
||||||
|
{
|
||||||
|
top: String,
|
||||||
|
bottom: String,
|
||||||
|
shoes: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug,Deserialize,Serialize,Clone,Default)]
|
||||||
|
#[serde(default)]
|
||||||
|
pub struct Colour
|
||||||
|
{
|
||||||
|
red: u8,
|
||||||
|
green: u8,
|
||||||
|
blue: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static POSITIONS: phf::Map<&'static str, [f32;2]> = phf_map! [
|
||||||
|
"fl" => [0.0,500.0],
|
||||||
|
"bl" => [0.0,0.0],
|
||||||
|
"fr" => [500.0,500.0],
|
||||||
|
"br" => [500.0,0.0],
|
||||||
|
];
|
||||||
|
|
||||||
|
#[macroquad::main("happening")]
|
||||||
|
async fn main()
|
||||||
|
{
|
||||||
|
let mut characters: HashMap<String, (Character, Texture2D)> = HashMap::new();
|
||||||
|
let mut textures: Vec<(Texture2D, f32, f32, Color)> = Vec::new();
|
||||||
|
loop
|
||||||
|
{
|
||||||
|
clear_background(RED);
|
||||||
|
// Get the next character
|
||||||
|
let data = next_happening();
|
||||||
|
let character_name: &str = data.character.as_str();
|
||||||
|
// Add the character to the HashMap if it's not already
|
||||||
|
if character_name != "" && !characters.contains_key(character_name)
|
||||||
|
{
|
||||||
|
let new_character = get_character(character_name).await;
|
||||||
|
characters.insert(character_name.to_string(), new_character);
|
||||||
|
}
|
||||||
|
// Matchbox for all the commands
|
||||||
|
match data.action_type.to_lowercase().as_str()
|
||||||
|
{
|
||||||
|
"output" =>
|
||||||
|
{
|
||||||
|
println!("SAYING");
|
||||||
|
draw_text(characters[character_name].0.name.clone(), 50.0,20.0,40.0,WHITE);
|
||||||
|
draw_text(data.content.as_str(), 50.0,40.0,30.0,WHITE);
|
||||||
|
},
|
||||||
|
"to" =>
|
||||||
|
{
|
||||||
|
let position = POSITIONS.get(&data.content).cloned().unwrap();
|
||||||
|
let texture = &characters[character_name].1;
|
||||||
|
textures.push((texture.clone(), position[0], position[1], WHITE)); // Heavy
|
||||||
|
}
|
||||||
|
_ => println!("Unknown action"),
|
||||||
|
}
|
||||||
|
for (texture, x, y, colour) in &textures
|
||||||
|
{
|
||||||
|
draw_texture(&texture, *x, *y, *colour);
|
||||||
|
}
|
||||||
|
thread::sleep(Duration::from_millis(1000));
|
||||||
|
next_frame().await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next_happening()
|
||||||
|
-> Data
|
||||||
|
{
|
||||||
|
let data: Data = reqwest::blocking::get(format!("http://127.0.0.1:20264/happening")).unwrap().json().unwrap();
|
||||||
|
println!("{data:?}");
|
||||||
|
data
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_character(name: &str)
|
||||||
|
-> (Character, Texture2D)
|
||||||
|
{
|
||||||
|
let character: Character = reqwest::blocking::get(format!("http://127.0.0.1:20264/character/{name}")).unwrap().json().unwrap();
|
||||||
|
println!("{character:?}");
|
||||||
|
let skin_colour = character.skin_color.clone();
|
||||||
|
let skin: Color = Color::from_rgba(skin_colour.red,skin_colour.green,skin_colour.blue,255);
|
||||||
|
let hair_colour = character.hair_color.clone();
|
||||||
|
let hair: Color = Color::from_rgba(hair_colour.red,hair_colour.green,hair_colour.blue,255);
|
||||||
|
let head_path: String = format!("../images/head/{}.png",character.head_shape);
|
||||||
|
let head: Texture2D = change_colour(&mut load_image(head_path.as_str()).await.unwrap(), &skin, &hair);
|
||||||
|
(character, head)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn change_colour(image: &mut Image, skin: &Color, hair: &Color)
|
||||||
|
-> Texture2D
|
||||||
|
{
|
||||||
|
let target = Color::from_rgba(255,0,255,255);
|
||||||
|
for y in 0..image.height() {
|
||||||
|
for x in 0..image.width() {
|
||||||
|
let pixel = image.get_pixel(x as u32, y as u32);
|
||||||
|
if pixel == target {
|
||||||
|
image.set_pixel(x as u32, y as u32, *skin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let target = Color::from_rgba(0,255,255,255);
|
||||||
|
for y in 0..image.height() {
|
||||||
|
for x in 0..image.width() {
|
||||||
|
let pixel = image.get_pixel(x as u32, y as u32);
|
||||||
|
if pixel == target {
|
||||||
|
image.set_pixel(x as u32, y as u32, *hair);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Texture2D::from_image(&image)
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 981 B |
Binary file not shown.
|
After Width: | Height: | Size: 1011 B |
+1
-2
@@ -43,8 +43,6 @@ pub async fn api_process
|
|||||||
let tx_filter1 = warp::any().map(move || tx.clone());
|
let tx_filter1 = warp::any().map(move || tx.clone());
|
||||||
let tx_filter2 = tx_filter1.clone();
|
let tx_filter2 = tx_filter1.clone();
|
||||||
|
|
||||||
info!("Running server");
|
|
||||||
|
|
||||||
// The server route is loaded at address:port/happening
|
// The server route is loaded at address:port/happening
|
||||||
let main = warp::path("happening")
|
let main = warp::path("happening")
|
||||||
.and(warp::get())
|
.and(warp::get())
|
||||||
@@ -109,6 +107,7 @@ pub async fn api_process
|
|||||||
|
|
||||||
let routes = main.or(characters).or(choice).or(input);
|
let routes = main.or(characters).or(choice).or(input);
|
||||||
// Start the server
|
// Start the server
|
||||||
|
info!("Running server");
|
||||||
warp::serve(routes)
|
warp::serve(routes)
|
||||||
.run(([127, 0, 0, 1],config::API_PORT))
|
.run(([127, 0, 0, 1],config::API_PORT))
|
||||||
.await;
|
.await;
|
||||||
|
|||||||
+1
-2
@@ -121,8 +121,7 @@ async fn main()
|
|||||||
Ok(()) =>
|
Ok(()) =>
|
||||||
{
|
{
|
||||||
api::modify_data(&happening_stack, "end".to_string(), String::new(), String::new(), vec![]);
|
api::modify_data(&happening_stack, "end".to_string(), String::new(), String::new(), vec![]);
|
||||||
// TODO fix quitting instantly
|
let _ = rx.recv();
|
||||||
let _ = rx.recv(); // Wait for the client to respond
|
|
||||||
info!("Program exited successfully");
|
info!("Program exited successfully");
|
||||||
exit(0);
|
exit(0);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ def main():
|
|||||||
continue
|
continue
|
||||||
case "end":
|
case "end":
|
||||||
print("Exitting successfully")
|
print("Exitting successfully")
|
||||||
|
requests.post("127.0.0.1:20264", json=0);
|
||||||
os._exit(0)
|
os._exit(0)
|
||||||
except:
|
except:
|
||||||
print("Server not up or cannot be reached")
|
print("Server not up or cannot be reached")
|
||||||
Reference in New Issue
Block a user