diff --git a/macro_convert/Cargo.toml b/macro_convert/Cargo.toml
index f7f6c336..05ddda0d 100644
--- a/macro_convert/Cargo.toml
+++ b/macro_convert/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "macro_convert"
-version = "0.2.0"
+version = "0.3.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
diff --git a/macro_convert/src/lib.rs b/macro_convert/src/lib.rs
index 3c3cac7e..7c22a4a5 100644
--- a/macro_convert/src/lib.rs
+++ b/macro_convert/src/lib.rs
@@ -26,7 +26,6 @@ fn handle_enum(name: &Ident, data: &DataEnum) -> TokenStream2 {
let default: Ident = get_default(data);
return quote! {
- use std::fmt;
#[automatically_derived]
impl #name {
@@ -36,8 +35,8 @@ fn handle_enum(name: &Ident, data: &DataEnum) -> TokenStream2 {
}
#[automatically_derived]
- impl fmt::Display for #name {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ impl std::fmt::Display for #name {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
diff --git a/macro_core/Cargo.toml b/macro_core/Cargo.toml
index 432e5ae7..7fca3dfd 100644
--- a/macro_core/Cargo.toml
+++ b/macro_core/Cargo.toml
@@ -1,4 +1,4 @@
[package]
name = "macro_core"
-version = "0.2.0"
+version = "0.3.0"
edition = "2021"
diff --git a/macro_ui/Cargo.toml b/macro_ui/Cargo.toml
index 866e9a29..292a582e 100644
--- a/macro_ui/Cargo.toml
+++ b/macro_ui/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "macro_ui"
-version = "0.2.0"
+version = "0.3.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
diff --git a/macro_ui/src/lib.rs b/macro_ui/src/lib.rs
index bfe63185..c71ac865 100644
--- a/macro_ui/src/lib.rs
+++ b/macro_ui/src/lib.rs
@@ -39,8 +39,8 @@ fn handle_enum(name: &Ident, data: &DataEnum) -> TokenStream2 {
if is_simple_enum(data) {
return quote! {
#[automatically_derived]
- impl UI for #name {
- fn visit(visitor: &mut dyn UiVisitor, spaces: &str, _in_tuple: bool) {
+ impl macro_core::visitor::UI for #name {
+ fn visit(visitor: &mut dyn macro_core::visitor::UiVisitor, spaces: &str, _in_tuple: bool) {
println!("{}Add simple enum {} with path '{}'!", spaces, stringify!(#name), visitor.get_path());
visitor.add_simple_enum(&[#(stringify!(#variants).to_string()),*]);
}
@@ -48,9 +48,9 @@ fn handle_enum(name: &Ident, data: &DataEnum) -> TokenStream2 {
#[automatically_derived]
impl #name {
- pub fn parse<'a>(parser: &'a dyn UiParser<'a>, path: &str, spaces: &str) -> #name {
+ pub fn parse<'a>(parser: &'a dyn macro_core::parser::UiParser<'a>, path: &str, spaces: &str) -> #name {
println!("{}Parse simple enum {} with path '{}'", spaces, stringify!(#name), path);
- get_enum(parser, path)
+ macro_core::parser::get_enum(parser, path)
}
}
};
@@ -61,8 +61,8 @@ fn handle_enum(name: &Ident, data: &DataEnum) -> TokenStream2 {
quote! {
#[automatically_derived]
- impl UI for #name {
- fn visit(visitor: &mut dyn UiVisitor, spaces: &str, _in_tuple: bool) {
+ impl macro_core::visitor::UI for #name {
+ fn visit(visitor: &mut dyn macro_core::visitor::UiVisitor, spaces: &str, _in_tuple: bool) {
println!("{}Create Viewer for enum {} with path '{}'!", spaces, stringify!(#name), visitor.get_path());
visitor.enter_enum(&[#(stringify!(#variants).to_string()),*]);
let inner_spaces = format!(" {}", spaces);
@@ -74,7 +74,7 @@ fn handle_enum(name: &Ident, data: &DataEnum) -> TokenStream2 {
#[automatically_derived]
impl #name {
- pub fn parse<'a>(parser: &'a dyn UiParser<'a>, path: &str, spaces: &str) -> #name {
+ pub fn parse<'a>(parser: &'a dyn macro_core::parser::UiParser<'a>, path: &str, spaces: &str) -> #name {
println!("{}Parse complex enum {} with path '{}'", spaces, stringify!(#name), path);
let t = parser.get_str(&format!("{}.type", path)).unwrap_or("");
println!("{}type '{}'", spaces, t);
@@ -96,8 +96,8 @@ fn handle_struct(name: &Ident, fields: &FieldsNamed) -> TokenStream2 {
quote! {
#[automatically_derived]
- impl UI for #name {
- fn visit(visitor: &mut dyn UiVisitor, spaces: &str, in_tuple: bool) {
+ impl macro_core::visitor::UI for #name {
+ fn visit(visitor: &mut dyn macro_core::visitor::UiVisitor, spaces: &str, in_tuple: bool) {
println!("{}Create Viewer for struct {} with path '{}' & in_tuple={}!", spaces, stringify!(#name), visitor.get_path(), in_tuple);
visitor.enter_struct(in_tuple);
let inner_spaces = format!(" {}", spaces);
@@ -109,7 +109,7 @@ fn handle_struct(name: &Ident, fields: &FieldsNamed) -> TokenStream2 {
#[automatically_derived]
impl #name {
- pub fn parse<'a>(parser: &'a dyn UiParser<'a>, path: &str, spaces: &str) -> #name {
+ pub fn parse<'a>(parser: &'a dyn macro_core::parser::UiParser<'a>, path: &str, spaces: &str) -> #name {
println!("{}Parse struct {} with path '{}'", spaces, stringify!(#name), path);
Self {
#parsed_fields
diff --git a/macro_ui/tests/parse_test.rs b/macro_ui/tests/parse_test.rs
index e22180fd..72dbc6ba 100644
--- a/macro_ui/tests/parse_test.rs
+++ b/macro_ui/tests/parse_test.rs
@@ -1,7 +1,5 @@
use macro_convert::Convert;
-use macro_core::parser::get_enum;
-use macro_core::parser::{MockParser, UiParser};
-use macro_core::visitor::{UiVisitor, UI};
+use macro_core::parser::MockParser;
use macro_ui::ui;
use std::collections::HashMap;
diff --git a/resources/characters/characters.yaml b/resources/characters/characters.yaml
index 118e3c5e..0db48347 100644
--- a/resources/characters/characters.yaml
+++ b/resources/characters/characters.yaml
@@ -9,6 +9,11 @@
skin:
type: NormalSkin
color: Fair
+ clothing:
+ type: Simple
+ pants:
+ style: Regular
+ color: Blue
head:
ears:
type: Normal
@@ -66,6 +71,8 @@
skin:
type: Scales
color: Red
+ clothing:
+ type: None
head:
ears:
type: Normal
@@ -152,6 +159,11 @@
skin:
type: ExoticSkin
color: White
+ clothing:
+ type: Simple
+ pants:
+ style: Balloon
+ color: Red
head:
ears:
type: Normal
@@ -206,6 +218,11 @@
skin:
type: ExoticSkin
color: Green
+ clothing:
+ type: Simple
+ pants:
+ style: Regular
+ color: Purple
head:
ears:
type: None
@@ -248,6 +265,11 @@
skin:
type: NormalSkin
color: Light
+ clothing:
+ type: Simple
+ pants:
+ style: Regular
+ color: Gray
head:
ears:
type: Normal
diff --git a/resources/templates/appearance_edit.html.tera b/resources/templates/appearance_edit.html.tera
index b925fea0..00f7aef6 100644
--- a/resources/templates/appearance_edit.html.tera
+++ b/resources/templates/appearance_edit.html.tera
@@ -437,6 +437,25 @@
{% endif %}
+
+ Clothing: {{ macros::add_select(name="appearance.body.clothing.type", options=[ "None","Simple" ], selected=appearance.body.clothing.type, update=true) }}
+
+ {% if appearance.body.clothing.type == "None" %}
+ {% elif appearance.body.clothing.type == "Simple" %}
+ -
+ Pants
+
+ -
+ Style: {{ macros::add_select(name="appearance.body.clothing.pants.style", options=[ "Balloon","Bermuda","HotPants","Regular","Shorts" ], selected=appearance.body.clothing.pants.style, update=true) }}
+
+ -
+ Color: {{ macros::add_select(name="appearance.body.clothing.pants.color", options=[ "Aqua","Black","Blue","Fuchsia","Gray","Green","Lime","Maroon","Navy","Olive","Orange","Purple","Red","SaddleBrown","Silver","Teal","White","Yellow" ], selected=appearance.body.clothing.pants.color, update=true) }}
+
+
+
+ {% endif %}
+
+
diff --git a/resources/templates/character.html.tera b/resources/templates/character.html.tera
index c2d69a4e..4f5888e1 100644
--- a/resources/templates/character.html.tera
+++ b/resources/templates/character.html.tera
@@ -438,6 +438,25 @@
{% endif %}
+
+ Clothing: {{ appearance.body.clothing.type }}
+
+ {% if appearance.body.clothing.type == "None" %}
+ {% elif appearance.body.clothing.type == "Simple" %}
+ -
+ Pants
+
+ -
+ Style: {{ appearance.body.clothing.pants.style }}
+
+ -
+ Color: {{ appearance.body.clothing.pants.color }}
+
+
+
+ {% endif %}
+
+
diff --git a/rpg_tools_core/Cargo.toml b/rpg_tools_core/Cargo.toml
index 72a3d5bb..57c52130 100644
--- a/rpg_tools_core/Cargo.toml
+++ b/rpg_tools_core/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "rpg_tools_core"
-version = "0.2.0"
+version = "0.3.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
diff --git a/rpg_tools_core/src/model/character/appearance/beard/full.rs b/rpg_tools_core/src/model/character/appearance/beard/full.rs
index 0359227f..26b2da50 100644
--- a/rpg_tools_core/src/model/character/appearance/beard/full.rs
+++ b/rpg_tools_core/src/model/character/appearance/beard/full.rs
@@ -1,6 +1,4 @@
use macro_convert::Convert;
-use macro_core::parser::{get_enum, UiParser};
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/character/appearance/beard/goatee.rs b/rpg_tools_core/src/model/character/appearance/beard/goatee.rs
index 99c2e21c..36648e40 100644
--- a/rpg_tools_core/src/model/character/appearance/beard/goatee.rs
+++ b/rpg_tools_core/src/model/character/appearance/beard/goatee.rs
@@ -1,6 +1,4 @@
use macro_convert::Convert;
-use macro_core::parser::{get_enum, UiParser};
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/character/appearance/beard/mod.rs b/rpg_tools_core/src/model/character/appearance/beard/mod.rs
index c3f259b7..c790bed8 100644
--- a/rpg_tools_core/src/model/character/appearance/beard/mod.rs
+++ b/rpg_tools_core/src/model/character/appearance/beard/mod.rs
@@ -3,8 +3,6 @@ use crate::model::character::appearance::beard::goatee::GoateeStyle;
use crate::model::character::appearance::beard::moustache::MoustacheStyle;
use crate::model::color::Color;
use crate::model::length::Length;
-use macro_core::parser::UiParser;
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/character/appearance/beard/moustache.rs b/rpg_tools_core/src/model/character/appearance/beard/moustache.rs
index 0de5ae6a..6c445754 100644
--- a/rpg_tools_core/src/model/character/appearance/beard/moustache.rs
+++ b/rpg_tools_core/src/model/character/appearance/beard/moustache.rs
@@ -1,6 +1,4 @@
use macro_convert::Convert;
-use macro_core::parser::{get_enum, UiParser};
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/character/appearance/body.rs b/rpg_tools_core/src/model/character/appearance/body.rs
index c0dcdee2..8c3e41b5 100644
--- a/rpg_tools_core/src/model/character/appearance/body.rs
+++ b/rpg_tools_core/src/model/character/appearance/body.rs
@@ -1,8 +1,7 @@
use crate::model::character::appearance::skin::Skin;
+use crate::model::equipment::appearance::Clothing;
use crate::model::width::Width;
use macro_convert::Convert;
-use macro_core::parser::{get_enum, UiParser};
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
@@ -13,6 +12,7 @@ pub struct Body {
/// How wide is the body?
pub width: Width,
pub skin: Skin,
+ pub clothing: Clothing,
}
impl Default for Body {
@@ -27,6 +27,7 @@ impl Body {
shape: BodyShape::Rectangle,
width: Width::Average,
skin,
+ clothing: Clothing::None,
}
}
}
diff --git a/rpg_tools_core/src/model/character/appearance/ear/mod.rs b/rpg_tools_core/src/model/character/appearance/ear/mod.rs
index 53204e47..09567485 100644
--- a/rpg_tools_core/src/model/character/appearance/ear/mod.rs
+++ b/rpg_tools_core/src/model/character/appearance/ear/mod.rs
@@ -1,7 +1,5 @@
use crate::model::character::appearance::ear::shape::EarShape;
use crate::model::size::Size;
-use macro_core::parser::UiParser;
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/character/appearance/ear/shape.rs b/rpg_tools_core/src/model/character/appearance/ear/shape.rs
index e9980a75..36caf07a 100644
--- a/rpg_tools_core/src/model/character/appearance/ear/shape.rs
+++ b/rpg_tools_core/src/model/character/appearance/ear/shape.rs
@@ -1,6 +1,4 @@
use macro_convert::Convert;
-use macro_core::parser::{get_enum, UiParser};
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/character/appearance/eye/brow/mod.rs b/rpg_tools_core/src/model/character/appearance/eye/brow/mod.rs
index 25be3f5b..75e6c08e 100644
--- a/rpg_tools_core/src/model/character/appearance/eye/brow/mod.rs
+++ b/rpg_tools_core/src/model/character/appearance/eye/brow/mod.rs
@@ -2,8 +2,6 @@ use crate::model::character::appearance::eye::brow::shape::EyebrowShape;
use crate::model::character::appearance::eye::brow::style::EyebrowStyle;
use crate::model::color::Color;
use crate::model::width::Width;
-use macro_core::parser::UiParser;
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/character/appearance/eye/brow/shape.rs b/rpg_tools_core/src/model/character/appearance/eye/brow/shape.rs
index 4a8b5964..ce39a52d 100644
--- a/rpg_tools_core/src/model/character/appearance/eye/brow/shape.rs
+++ b/rpg_tools_core/src/model/character/appearance/eye/brow/shape.rs
@@ -1,6 +1,4 @@
use macro_convert::Convert;
-use macro_core::parser::{get_enum, UiParser};
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/character/appearance/eye/brow/style.rs b/rpg_tools_core/src/model/character/appearance/eye/brow/style.rs
index e507455b..419c5717 100644
--- a/rpg_tools_core/src/model/character/appearance/eye/brow/style.rs
+++ b/rpg_tools_core/src/model/character/appearance/eye/brow/style.rs
@@ -1,6 +1,4 @@
use macro_convert::Convert;
-use macro_core::parser::{get_enum, UiParser};
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/character/appearance/eye/mod.rs b/rpg_tools_core/src/model/character/appearance/eye/mod.rs
index 22d81352..8581b48b 100644
--- a/rpg_tools_core/src/model/character/appearance/eye/mod.rs
+++ b/rpg_tools_core/src/model/character/appearance/eye/mod.rs
@@ -3,8 +3,6 @@ use crate::model::character::appearance::eye::pupil::PupilShape;
use crate::model::character::appearance::eye::shape::EyeShape;
use crate::model::color::Color;
use crate::model::size::Size;
-use macro_core::parser::UiParser;
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/character/appearance/eye/pupil.rs b/rpg_tools_core/src/model/character/appearance/eye/pupil.rs
index 6524c676..88fb5325 100644
--- a/rpg_tools_core/src/model/character/appearance/eye/pupil.rs
+++ b/rpg_tools_core/src/model/character/appearance/eye/pupil.rs
@@ -1,6 +1,4 @@
use macro_convert::Convert;
-use macro_core::parser::{get_enum, UiParser};
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/character/appearance/eye/shape.rs b/rpg_tools_core/src/model/character/appearance/eye/shape.rs
index 4c328f2e..66cb0ed1 100644
--- a/rpg_tools_core/src/model/character/appearance/eye/shape.rs
+++ b/rpg_tools_core/src/model/character/appearance/eye/shape.rs
@@ -1,6 +1,4 @@
use macro_convert::Convert;
-use macro_core::parser::{get_enum, UiParser};
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/character/appearance/hair/bun.rs b/rpg_tools_core/src/model/character/appearance/hair/bun.rs
index 872979fa..e511259b 100644
--- a/rpg_tools_core/src/model/character/appearance/hair/bun.rs
+++ b/rpg_tools_core/src/model/character/appearance/hair/bun.rs
@@ -1,6 +1,4 @@
use macro_convert::Convert;
-use macro_core::parser::{get_enum, UiParser};
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/character/appearance/hair/hairline.rs b/rpg_tools_core/src/model/character/appearance/hair/hairline.rs
index f2c1ecd0..213ece3e 100644
--- a/rpg_tools_core/src/model/character/appearance/hair/hairline.rs
+++ b/rpg_tools_core/src/model/character/appearance/hair/hairline.rs
@@ -1,8 +1,5 @@
use crate::model::size::Size;
use macro_convert::Convert;
-use macro_core::parser::get_enum;
-use macro_core::parser::UiParser;
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/character/appearance/hair/long.rs b/rpg_tools_core/src/model/character/appearance/hair/long.rs
index a05d3817..c32716a6 100644
--- a/rpg_tools_core/src/model/character/appearance/hair/long.rs
+++ b/rpg_tools_core/src/model/character/appearance/hair/long.rs
@@ -1,6 +1,4 @@
use macro_convert::Convert;
-use macro_core::parser::{get_enum, UiParser};
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/character/appearance/hair/mod.rs b/rpg_tools_core/src/model/character/appearance/hair/mod.rs
index 8419a53a..68e059da 100644
--- a/rpg_tools_core/src/model/character/appearance/hair/mod.rs
+++ b/rpg_tools_core/src/model/character/appearance/hair/mod.rs
@@ -6,8 +6,6 @@ use crate::model::character::appearance::hair::short::ShortHair;
use crate::model::color::Color;
use crate::model::length::Length;
use crate::model::size::Size;
-use macro_core::parser::UiParser;
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/character/appearance/hair/ponytail/mod.rs b/rpg_tools_core/src/model/character/appearance/hair/ponytail/mod.rs
index 2aaf5501..9ee498b3 100644
--- a/rpg_tools_core/src/model/character/appearance/hair/ponytail/mod.rs
+++ b/rpg_tools_core/src/model/character/appearance/hair/ponytail/mod.rs
@@ -3,8 +3,6 @@ use crate::model::character::appearance::hair::ponytail::position::PonytailPosit
use crate::model::character::appearance::hair::ponytail::style::PonytailStyle;
use crate::model::color::Color;
use crate::model::length::Length;
-use macro_core::parser::UiParser;
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/character/appearance/hair/ponytail/position.rs b/rpg_tools_core/src/model/character/appearance/hair/ponytail/position.rs
index a00d7629..a70ff845 100644
--- a/rpg_tools_core/src/model/character/appearance/hair/ponytail/position.rs
+++ b/rpg_tools_core/src/model/character/appearance/hair/ponytail/position.rs
@@ -1,6 +1,4 @@
use macro_convert::Convert;
-use macro_core::parser::{get_enum, UiParser};
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/character/appearance/hair/ponytail/style.rs b/rpg_tools_core/src/model/character/appearance/hair/ponytail/style.rs
index 427fe801..e62fd330 100644
--- a/rpg_tools_core/src/model/character/appearance/hair/ponytail/style.rs
+++ b/rpg_tools_core/src/model/character/appearance/hair/ponytail/style.rs
@@ -1,6 +1,4 @@
use macro_convert::Convert;
-use macro_core::parser::{get_enum, UiParser};
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/character/appearance/hair/short.rs b/rpg_tools_core/src/model/character/appearance/hair/short.rs
index 3dda5939..4cf51f9d 100644
--- a/rpg_tools_core/src/model/character/appearance/hair/short.rs
+++ b/rpg_tools_core/src/model/character/appearance/hair/short.rs
@@ -1,7 +1,5 @@
use crate::model::side::Side;
use crate::model::size::Size;
-use macro_core::parser::UiParser;
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/character/appearance/head.rs b/rpg_tools_core/src/model/character/appearance/head.rs
index be627a38..bfd422d7 100644
--- a/rpg_tools_core/src/model/character/appearance/head.rs
+++ b/rpg_tools_core/src/model/character/appearance/head.rs
@@ -4,8 +4,6 @@ use crate::model::character::appearance::hair::Hair;
use crate::model::character::appearance::mouth::Mouth;
use crate::model::character::appearance::skin::Skin;
use macro_convert::Convert;
-use macro_core::parser::{get_enum, UiParser};
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/character/appearance/mod.rs b/rpg_tools_core/src/model/character/appearance/mod.rs
index 56713ff4..373cb313 100644
--- a/rpg_tools_core/src/model/character/appearance/mod.rs
+++ b/rpg_tools_core/src/model/character/appearance/mod.rs
@@ -1,8 +1,6 @@
use crate::model::character::appearance::body::Body;
use crate::model::character::appearance::head::Head;
use crate::model::length::Length;
-use macro_core::parser::UiParser;
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/character/appearance/mouth.rs b/rpg_tools_core/src/model/character/appearance/mouth.rs
index 4b36a340..6f9ec0fb 100644
--- a/rpg_tools_core/src/model/character/appearance/mouth.rs
+++ b/rpg_tools_core/src/model/character/appearance/mouth.rs
@@ -2,8 +2,6 @@ use crate::model::character::appearance::beard::Beard;
use crate::model::color::Color;
use crate::model::size::Size;
use macro_convert::Convert;
-use macro_core::parser::{get_enum, UiParser};
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/character/appearance/skin.rs b/rpg_tools_core/src/model/character/appearance/skin.rs
index 7d8cd314..ca39f0ff 100644
--- a/rpg_tools_core/src/model/character/appearance/skin.rs
+++ b/rpg_tools_core/src/model/character/appearance/skin.rs
@@ -1,7 +1,5 @@
use crate::model::color::Color;
use macro_convert::Convert;
-use macro_core::parser::{get_enum, UiParser};
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
@@ -16,7 +14,7 @@ pub enum Skin {
impl Default for Skin {
fn default() -> Self {
- Self::ExoticSkin { color: Color::Aqua }
+ Skin::normal(SkinColor::default())
}
}
diff --git a/rpg_tools_core/src/model/color.rs b/rpg_tools_core/src/model/color.rs
index c8f8ec19..aba030d0 100644
--- a/rpg_tools_core/src/model/color.rs
+++ b/rpg_tools_core/src/model/color.rs
@@ -1,6 +1,4 @@
use macro_convert::Convert;
-use macro_core::parser::{get_enum, UiParser};
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/equipment/appearance/mod.rs b/rpg_tools_core/src/model/equipment/appearance/mod.rs
new file mode 100644
index 00000000..03c3a92f
--- /dev/null
+++ b/rpg_tools_core/src/model/equipment/appearance/mod.rs
@@ -0,0 +1,15 @@
+use crate::model::equipment::appearance::pants::Pants;
+use macro_ui::ui;
+use serde::{Deserialize, Serialize};
+
+pub mod pants;
+
+#[derive(ui, Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(tag = "type")]
+pub enum Clothing {
+ #[default]
+ None,
+ Simple {
+ pants: Pants,
+ },
+}
diff --git a/rpg_tools_core/src/model/equipment/appearance/pants.rs b/rpg_tools_core/src/model/equipment/appearance/pants.rs
new file mode 100644
index 00000000..599776b3
--- /dev/null
+++ b/rpg_tools_core/src/model/equipment/appearance/pants.rs
@@ -0,0 +1,22 @@
+use crate::model::color::Color;
+use macro_convert::Convert;
+use macro_ui::ui;
+use serde::{Deserialize, Serialize};
+
+/// Clothing for the lower body.
+#[derive(ui, Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
+pub struct Pants {
+ pub style: PantsStyle,
+ pub color: Color,
+}
+
+/// What style of pants?
+#[derive(Convert, ui, Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
+pub enum PantsStyle {
+ Balloon,
+ Bermuda,
+ HotPants,
+ #[default]
+ Regular,
+ Shorts,
+}
diff --git a/rpg_tools_core/src/model/equipment/mod.rs b/rpg_tools_core/src/model/equipment/mod.rs
new file mode 100644
index 00000000..2126bcfa
--- /dev/null
+++ b/rpg_tools_core/src/model/equipment/mod.rs
@@ -0,0 +1 @@
+pub mod appearance;
diff --git a/rpg_tools_core/src/model/length.rs b/rpg_tools_core/src/model/length.rs
index 6ec476e8..a1c61ec2 100644
--- a/rpg_tools_core/src/model/length.rs
+++ b/rpg_tools_core/src/model/length.rs
@@ -1,5 +1,3 @@
-use macro_core::parser::UiParser;
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/mod.rs b/rpg_tools_core/src/model/mod.rs
index 5911d2fa..9e56bab2 100644
--- a/rpg_tools_core/src/model/mod.rs
+++ b/rpg_tools_core/src/model/mod.rs
@@ -1,5 +1,6 @@
pub mod character;
pub mod color;
+pub mod equipment;
pub mod length;
pub mod side;
pub mod size;
diff --git a/rpg_tools_core/src/model/side.rs b/rpg_tools_core/src/model/side.rs
index a878d645..508777af 100644
--- a/rpg_tools_core/src/model/side.rs
+++ b/rpg_tools_core/src/model/side.rs
@@ -1,6 +1,4 @@
use macro_convert::Convert;
-use macro_core::parser::{get_enum, UiParser};
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/size.rs b/rpg_tools_core/src/model/size.rs
index fcd44b0d..070c1840 100644
--- a/rpg_tools_core/src/model/size.rs
+++ b/rpg_tools_core/src/model/size.rs
@@ -1,6 +1,4 @@
use macro_convert::Convert;
-use macro_core::parser::{get_enum, UiParser};
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_core/src/model/width.rs b/rpg_tools_core/src/model/width.rs
index 9674b6c1..a1b3fecd 100644
--- a/rpg_tools_core/src/model/width.rs
+++ b/rpg_tools_core/src/model/width.rs
@@ -1,6 +1,4 @@
use macro_convert::Convert;
-use macro_core::parser::{get_enum, UiParser};
-use macro_core::visitor::{UiVisitor, UI};
use macro_ui::ui;
use serde::{Deserialize, Serialize};
diff --git a/rpg_tools_editor/Cargo.toml b/rpg_tools_editor/Cargo.toml
index 2e97ad03..a9daf3ed 100644
--- a/rpg_tools_editor/Cargo.toml
+++ b/rpg_tools_editor/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "rpg_tools_editor"
-version = "0.2.0"
+version = "0.3.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
diff --git a/rpg_tools_rendering/Cargo.toml b/rpg_tools_rendering/Cargo.toml
index 4eb9d473..b181e9e0 100644
--- a/rpg_tools_rendering/Cargo.toml
+++ b/rpg_tools_rendering/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "rpg_tools_rendering"
-version = "0.2.0"
+version = "0.3.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
diff --git a/rpg_tools_rendering/examples/beards_full.rs b/rpg_tools_rendering/examples/beards_full.rs
index f54306ef..c1db5235 100644
--- a/rpg_tools_rendering/examples/beards_full.rs
+++ b/rpg_tools_rendering/examples/beards_full.rs
@@ -18,6 +18,7 @@ use rpg_tools_core::model::character::appearance::mouth::{Mouth, SpecialTeeth, T
use rpg_tools_core::model::character::appearance::skin::{Skin, SkinColor};
use rpg_tools_core::model::character::appearance::Appearance;
use rpg_tools_core::model::color::Color;
+use rpg_tools_core::model::equipment::appearance::Clothing;
use rpg_tools_core::model::length::Length;
use rpg_tools_core::model::size::Size::Medium;
use rpg_tools_core::model::width::Width;
@@ -56,6 +57,7 @@ fn create_appearance(height: Length, beard: &Beard, face: &HeadShape) -> Appeara
shape: BodyShape::Rectangle,
width: Width::Average,
skin: Skin::normal(SkinColor::Light),
+ clothing: Clothing::None,
},
Head {
ears: Ears::Normal {
diff --git a/rpg_tools_rendering/examples/body.rs b/rpg_tools_rendering/examples/body.rs
index 8d5e6831..99b394e4 100644
--- a/rpg_tools_rendering/examples/body.rs
+++ b/rpg_tools_rendering/examples/body.rs
@@ -2,44 +2,30 @@ extern crate rpg_tools_core;
extern crate rpg_tools_rendering;
use crate::utils::render::render_2_sets;
-use rpg_tools_core::model::character::appearance::body::BodyShape::*;
use rpg_tools_core::model::character::appearance::body::{Body, BodyShape};
-use rpg_tools_core::model::character::appearance::ear::Ears;
-use rpg_tools_core::model::character::appearance::eye::Eyes;
-use rpg_tools_core::model::character::appearance::hair::Hair;
-use rpg_tools_core::model::character::appearance::head::{Head, HeadShape};
-use rpg_tools_core::model::character::appearance::mouth::Mouth;
-use rpg_tools_core::model::character::appearance::skin::{Skin, SkinColor};
+use rpg_tools_core::model::character::appearance::head::Head;
use rpg_tools_core::model::character::appearance::Appearance;
use rpg_tools_core::model::length::Length;
use rpg_tools_core::model::width::Width;
-use rpg_tools_core::model::width::Width::*;
pub mod utils;
fn main() {
- let rows = vec![Thin, Average, Wide];
- let columns = vec![Fat, Hourglass, Muscular, Rectangle];
+ let rows = Width::get_all();
+ let columns = BodyShape::get_all();
render_2_sets("bodies.svg", rows, columns, create_appearance, false);
}
fn create_appearance(height: Length, width: &Width, shape: &BodyShape) -> Appearance {
- let skin = Skin::normal(SkinColor::Light);
Appearance::humanoid(
Body {
shape: *shape,
width: *width,
- skin,
- },
- Head {
- ears: Ears::None,
- eyes: Eyes::None,
- hair: Hair::None,
- mouth: Mouth::None,
- shape: HeadShape::Oval,
- skin,
+ skin: Default::default(),
+ clothing: Default::default(),
},
+ Head::default(),
height,
)
}
diff --git a/rpg_tools_rendering/examples/eyebrows.rs b/rpg_tools_rendering/examples/eyebrows.rs
index b75f97a3..29ea7e40 100644
--- a/rpg_tools_rendering/examples/eyebrows.rs
+++ b/rpg_tools_rendering/examples/eyebrows.rs
@@ -22,17 +22,16 @@ use rpg_tools_core::model::color::Color;
use rpg_tools_core::model::length::Length;
use rpg_tools_core::model::size::Size::Medium;
use rpg_tools_core::model::width::Width;
-use std::vec;
pub mod utils;
fn main() {
let mut options = Vec::new();
- for is_unibrow in vec![false, true] {
+ for is_unibrow in &[false, true] {
for style in EyebrowStyle::get_all() {
for width in Width::get_all() {
- options.push((is_unibrow, style, width));
+ options.push((*is_unibrow, style, width));
}
}
}
diff --git a/rpg_tools_rendering/examples/eyes.rs b/rpg_tools_rendering/examples/eyes.rs
index c25d51d8..320ace95 100644
--- a/rpg_tools_rendering/examples/eyes.rs
+++ b/rpg_tools_rendering/examples/eyes.rs
@@ -52,7 +52,7 @@ fn create_appearance(height: Length, eyes: &Eyes, face: &HeadShape) -> Appearanc
Appearance::head(
Head {
ears: Ears::None,
- eyes: eyes.clone(),
+ eyes: *eyes,
hair: Hair::None,
mouth: Mouth::None,
shape: *face,
diff --git a/rpg_tools_rendering/examples/pants.rs b/rpg_tools_rendering/examples/pants.rs
new file mode 100644
index 00000000..a4756a2a
--- /dev/null
+++ b/rpg_tools_rendering/examples/pants.rs
@@ -0,0 +1,50 @@
+extern crate rpg_tools_core;
+extern crate rpg_tools_rendering;
+
+use crate::utils::render::render_2_sets;
+use rpg_tools_core::model::character::appearance::body::{Body, BodyShape};
+use rpg_tools_core::model::character::appearance::head::Head;
+use rpg_tools_core::model::character::appearance::Appearance;
+use rpg_tools_core::model::color::Color;
+use rpg_tools_core::model::equipment::appearance::pants::{Pants, PantsStyle};
+use rpg_tools_core::model::equipment::appearance::Clothing;
+use rpg_tools_core::model::length::Length;
+use rpg_tools_core::model::width::Width;
+
+pub mod utils;
+
+fn main() {
+ let mut pants = vec![];
+
+ for style in PantsStyle::get_all() {
+ pants.push(create(style))
+ }
+
+ render_2_sets(
+ "pants.svg",
+ pants,
+ BodyShape::get_all(),
+ create_appearance,
+ false,
+ );
+}
+
+fn create(style: PantsStyle) -> Pants {
+ Pants {
+ style,
+ color: Color::Blue,
+ }
+}
+
+fn create_appearance(height: Length, pants: &Pants, shape: &BodyShape) -> Appearance {
+ Appearance::humanoid(
+ Body {
+ shape: *shape,
+ width: Width::default(),
+ skin: Default::default(),
+ clothing: Clothing::Simple { pants: *pants },
+ },
+ Head::default(),
+ height,
+ )
+}
diff --git a/rpg_tools_rendering/src/rendering/body/torso.rs b/rpg_tools_rendering/src/rendering/body/torso.rs
index 82da57fe..0b7ac964 100644
--- a/rpg_tools_rendering/src/rendering/body/torso.rs
+++ b/rpg_tools_rendering/src/rendering/body/torso.rs
@@ -4,7 +4,7 @@ use crate::renderer::{RenderOptions, Renderer};
use crate::rendering::config::body::torso::TorsoConfig;
use crate::rendering::config::body::BodyConfig;
use crate::rendering::config::RenderConfig;
-use rpg_tools_core::model::character::appearance::body::{Body, BodyShape};
+use rpg_tools_core::model::character::appearance::body::Body;
pub fn render_torso(
renderer: &mut dyn Renderer,
@@ -14,12 +14,11 @@ pub fn render_torso(
options: &RenderOptions,
) {
let torso_aabb = config.body.get_torso_aabb(body, aabb);
- let polygon = match body.shape {
- BodyShape::Fat => create_torso(&torso_aabb, &config.body, &config.body.fat),
- BodyShape::Hourglass => create_torso(&torso_aabb, &config.body, &config.body.hourglass),
- BodyShape::Muscular => create_torso(&torso_aabb, &config.body, &config.body.muscular),
- BodyShape::Rectangle => create_torso(&torso_aabb, &config.body, &config.body.rectangle),
- };
+ let polygon = create_torso(
+ &torso_aabb,
+ &config.body,
+ config.body.get_torso_config(body.shape),
+ );
renderer.render_rounded_polygon(&polygon, options);
}
diff --git a/rpg_tools_rendering/src/rendering/character.rs b/rpg_tools_rendering/src/rendering/character.rs
index 6a0b843b..5bd885f3 100644
--- a/rpg_tools_rendering/src/rendering/character.rs
+++ b/rpg_tools_rendering/src/rendering/character.rs
@@ -4,6 +4,7 @@ use crate::renderer::Renderer;
use crate::rendering::body::{calculate_head_aabb, render_body};
use crate::rendering::config::RenderConfig;
use crate::rendering::ear::render_ears;
+use crate::rendering::equipment::render_clothing;
use crate::rendering::eye::render_eyes;
use crate::rendering::hair::{
render_hair_back, render_hair_before_head_from_front, render_hair_behind_head_from_front,
@@ -38,6 +39,7 @@ pub fn render_character_from_front(
let head_aabb = calculate_head_aabb(config, &inner);
render_head_behind_body_from_front(renderer, config, head, &head_aabb);
render_body(renderer, config, &inner, body);
+ render_clothing(renderer, config, &inner, body);
render_head_before_body_from_front(renderer, config, head, &head_aabb);
}
}
@@ -57,6 +59,7 @@ pub fn render_character_from_back(
}
Appearance::Humanoid { body, head, .. } => {
render_body(renderer, config, &inner, &body);
+ render_clothing(renderer, config, &inner, &body);
let head_aabb = calculate_head_aabb(config, &inner);
render_head_from_back(renderer, config, &head, &head_aabb);
}
diff --git a/rpg_tools_rendering/src/rendering/config/body/mod.rs b/rpg_tools_rendering/src/rendering/config/body/mod.rs
index 16f28be7..8f8ba2b7 100644
--- a/rpg_tools_rendering/src/rendering/config/body/mod.rs
+++ b/rpg_tools_rendering/src/rendering/config/body/mod.rs
@@ -35,7 +35,7 @@ impl BodyConfig {
}
pub fn get_leg_width(&self, body: &Body) -> f32 {
- self.width_leg * self.get_width_factor(body)
+ self.width_leg * self.get_width_factor(body) * self.get_torso_config(body.shape).legs_width
}
pub fn get_width_factor(&self, body: &Body) -> f32 {
@@ -54,6 +54,7 @@ impl BodyConfig {
/// The aabb of both legs is limited to the smaller width of shoulders or hip to match *Fat* & *Muscular* [`body shapes`](BodyShape).
pub fn get_legs_width(&self, body: &Body) -> f32 {
self.get_shoulder_width(body).min(self.get_hip_width(body))
+ * self.get_torso_config(body.shape).legs_width
}
pub fn get_shoulder_width(&self, body: &Body) -> f32 {
@@ -78,12 +79,16 @@ impl BodyConfig {
self.get_shoulder_width(body).max(self.get_hip_width(body))
}
+ pub fn get_torso_bottom(&self) -> f32 {
+ self.y_torso + self.height_torso
+ }
+
pub fn get_arm_y(&self) -> f32 {
self.y_torso + 0.05
}
pub fn get_leg_y(&self) -> f32 {
- self.y_torso + self.height_torso - 0.05
+ self.get_torso_bottom() - 0.05
}
pub fn get_fat_offset_factor(&self, body: &Body) -> f32 {
@@ -99,6 +104,21 @@ impl BodyConfig {
}
pub fn get_foot_radius(&self, body: &Body, aabb: &AABB) -> u32 {
- aabb.convert_to_height(self.foot_factor * self.get_width_factor(body))
+ aabb.convert_to_height(self.get_foot_radius_factor(body))
+ }
+
+ pub fn get_foot_radius_factor(&self, body: &Body) -> f32 {
+ self.foot_factor
+ * self.get_width_factor(body)
+ * self.get_torso_config(body.shape).legs_width
+ }
+
+ pub fn get_torso_config(&self, shape: BodyShape) -> &TorsoConfig {
+ match shape {
+ BodyShape::Fat => &self.fat,
+ BodyShape::Hourglass => &self.hourglass,
+ BodyShape::Muscular => &self.muscular,
+ BodyShape::Rectangle => &self.rectangle,
+ }
}
}
diff --git a/rpg_tools_rendering/src/rendering/config/body/torso.rs b/rpg_tools_rendering/src/rendering/config/body/torso.rs
index 17a1a1a9..ed08fb70 100644
--- a/rpg_tools_rendering/src/rendering/config/body/torso.rs
+++ b/rpg_tools_rendering/src/rendering/config/body/torso.rs
@@ -4,4 +4,5 @@ pub struct TorsoConfig {
pub shoulder_width: f32,
pub waist_width: f32,
pub hip_width: f32,
+ pub legs_width: f32,
}
diff --git a/rpg_tools_rendering/src/rendering/config/equipment/mod.rs b/rpg_tools_rendering/src/rendering/config/equipment/mod.rs
new file mode 100644
index 00000000..9cb84244
--- /dev/null
+++ b/rpg_tools_rendering/src/rendering/config/equipment/mod.rs
@@ -0,0 +1 @@
+pub mod pants;
diff --git a/rpg_tools_rendering/src/rendering/config/equipment/pants.rs b/rpg_tools_rendering/src/rendering/config/equipment/pants.rs
new file mode 100644
index 00000000..c53b0b49
--- /dev/null
+++ b/rpg_tools_rendering/src/rendering/config/equipment/pants.rs
@@ -0,0 +1,35 @@
+use crate::rendering::config::body::BodyConfig;
+use rpg_tools_core::model::character::appearance::body::Body;
+
+/// The rendering config of the [`pants`](Pants).
+#[derive(Debug, PartialEq)]
+pub struct PantsConfig {
+ pub height_bermuda: f32,
+ pub height_shorts: f32,
+ pub offset_center: f32,
+ pub offset_bottom: f32,
+ pub width_padding: f32,
+ pub balloon_padding: f32,
+}
+
+impl PantsConfig {
+ /// Returns the width of pants and the space between the individuals pants.
+ pub fn get_widths(&self, config: &BodyConfig, body: &Body) -> (f32, f32) {
+ let legs_width = config.get_legs_width(body);
+ let padding = legs_width * self.width_padding;
+ let pants_width = legs_width + padding;
+ let pant_width = config.get_leg_width(body) + padding;
+ let inner_width = pants_width - 2.0 * pant_width;
+
+ (pants_width, inner_width)
+ }
+
+ pub fn get_hip_width(&self, config: &BodyConfig, body: &Body) -> f32 {
+ let torso = config.get_torso_config(body.shape);
+ torso.hip_width * (1.0 + self.width_padding)
+ }
+
+ pub fn get_bottom_y(&self, config: &BodyConfig, body: &Body) -> f32 {
+ 1.0 - config.get_foot_radius_factor(body) - self.offset_bottom
+ }
+}
diff --git a/rpg_tools_rendering/src/rendering/config/example.rs b/rpg_tools_rendering/src/rendering/config/example.rs
index 2709d1b3..4f51fd2a 100644
--- a/rpg_tools_rendering/src/rendering/config/example.rs
+++ b/rpg_tools_rendering/src/rendering/config/example.rs
@@ -5,6 +5,7 @@ use crate::renderer::RenderOptions;
use crate::rendering::config::body::torso::TorsoConfig;
use crate::rendering::config::body::BodyConfig;
use crate::rendering::config::ear::EarConfig;
+use crate::rendering::config::equipment::pants::PantsConfig;
use crate::rendering::config::eye::eyebrow::EyebrowConfig;
use crate::rendering::config::eye::EyeConfig;
use crate::rendering::config::hair::hairline::HairlineConfig;
@@ -50,21 +51,25 @@ pub fn create_config() -> RenderConfig {
shoulder_width: 0.64,
waist_width: 0.82,
hip_width: 1.0,
+ legs_width: 1.0,
},
hourglass: TorsoConfig {
shoulder_width: 1.0,
waist_width: 0.7,
hip_width: 1.0,
+ legs_width: 0.85,
},
muscular: TorsoConfig {
shoulder_width: 1.0,
waist_width: 0.82,
hip_width: 0.64,
+ legs_width: 1.0,
},
rectangle: TorsoConfig {
shoulder_width: 1.0,
waist_width: 1.0,
hip_width: 1.0,
+ legs_width: 0.9,
},
width_arm: 0.1,
width_leg: 0.14,
@@ -114,6 +119,14 @@ pub fn create_config() -> RenderConfig {
ear: create_ear_config(),
eye: create_eye_config(),
mouth: create_mouth_config(),
+ pants: PantsConfig {
+ height_bermuda: 0.5,
+ height_shorts: 0.3,
+ offset_center: 0.03,
+ offset_bottom: 0.01,
+ width_padding: 0.05,
+ balloon_padding: 0.2,
+ },
}
}
diff --git a/rpg_tools_rendering/src/rendering/config/mod.rs b/rpg_tools_rendering/src/rendering/config/mod.rs
index 2ff63f37..b04bbf93 100644
--- a/rpg_tools_rendering/src/rendering/config/mod.rs
+++ b/rpg_tools_rendering/src/rendering/config/mod.rs
@@ -2,6 +2,7 @@ use crate::renderer::color::WebColor;
use crate::renderer::RenderOptions;
use crate::rendering::config::body::BodyConfig;
use crate::rendering::config::ear::EarConfig;
+use crate::rendering::config::equipment::pants::PantsConfig;
use crate::rendering::config::eye::EyeConfig;
use crate::rendering::config::hair::HairConfig;
use crate::rendering::config::head::HeadConfig;
@@ -12,6 +13,7 @@ use rpg_tools_core::model::color::Color;
pub mod body;
pub mod ear;
+pub mod equipment;
pub mod example;
pub mod eye;
pub mod hair;
@@ -27,11 +29,12 @@ pub struct RenderConfig {
pub line_width: u32,
pub thin_line_width: u32,
pub body: BodyConfig,
- pub hair: HairConfig,
- pub head: HeadConfig,
pub ear: EarConfig,
pub eye: EyeConfig,
+ pub hair: HairConfig,
+ pub head: HeadConfig,
pub mouth: MouthConfig,
+ pub pants: PantsConfig,
}
impl RenderConfig {
diff --git a/rpg_tools_rendering/src/rendering/equipment/mod.rs b/rpg_tools_rendering/src/rendering/equipment/mod.rs
new file mode 100644
index 00000000..86545cba
--- /dev/null
+++ b/rpg_tools_rendering/src/rendering/equipment/mod.rs
@@ -0,0 +1,19 @@
+use crate::math::aabb2d::AABB;
+use crate::renderer::Renderer;
+use crate::rendering::config::RenderConfig;
+use crate::rendering::equipment::pants::render_pants;
+use rpg_tools_core::model::character::appearance::body::Body;
+use rpg_tools_core::model::equipment::appearance::Clothing;
+
+pub mod pants;
+
+pub fn render_clothing(
+ renderer: &mut dyn Renderer,
+ config: &RenderConfig,
+ aabb: &AABB,
+ body: &Body,
+) {
+ if let Clothing::Simple { pants } = &body.clothing {
+ render_pants(renderer, config, aabb, body, pants)
+ }
+}
diff --git a/rpg_tools_rendering/src/rendering/equipment/pants.rs b/rpg_tools_rendering/src/rendering/equipment/pants.rs
new file mode 100644
index 00000000..e18fb44e
--- /dev/null
+++ b/rpg_tools_rendering/src/rendering/equipment/pants.rs
@@ -0,0 +1,104 @@
+use crate::math::aabb2d::AABB;
+use crate::math::polygon2d::builder::Polygon2dBuilder;
+use crate::math::polygon2d::Polygon2d;
+use crate::renderer::Renderer;
+use crate::rendering::config::RenderConfig;
+use rpg_tools_core::model::character::appearance::body::Body;
+use rpg_tools_core::model::equipment::appearance::pants::{Pants, PantsStyle};
+
+pub fn render_pants(
+ renderer: &mut dyn Renderer,
+ config: &RenderConfig,
+ aabb: &AABB,
+ body: &Body,
+ pants: &Pants,
+) {
+ let options = config.get_options(pants.color);
+ let polygon = match pants.style {
+ PantsStyle::Balloon => get_balloon(config, aabb, body),
+ PantsStyle::Bermuda => get_bermuda(config, aabb, body),
+ PantsStyle::HotPants => get_hot_pants(config, aabb, body),
+ PantsStyle::Regular => get_regular_pants(config, aabb, body),
+ PantsStyle::Shorts => get_shorts(config, aabb, body),
+ };
+
+ renderer.render_rounded_polygon(&polygon, &options);
+}
+
+fn get_balloon(config: &RenderConfig, aabb: &AABB, body: &Body) -> Polygon2d {
+ let bottom_y = config.pants.get_bottom_y(&config.body, body);
+ get_pants(config, aabb, body, bottom_y, true)
+}
+
+fn get_bermuda(config: &RenderConfig, aabb: &AABB, body: &Body) -> Polygon2d {
+ get_shorter_pants(config, aabb, body, config.pants.height_bermuda)
+}
+
+fn get_hot_pants(config: &RenderConfig, aabb: &AABB, body: &Body) -> Polygon2d {
+ get_base(config, aabb, body).build()
+}
+
+fn get_regular_pants(config: &RenderConfig, aabb: &AABB, body: &Body) -> Polygon2d {
+ let bottom_y = config.pants.get_bottom_y(&config.body, body);
+ get_pants(config, aabb, body, bottom_y, false)
+}
+
+fn get_shorts(config: &RenderConfig, aabb: &AABB, body: &Body) -> Polygon2d {
+ get_shorter_pants(config, aabb, body, config.pants.height_shorts)
+}
+
+fn get_shorter_pants(config: &RenderConfig, aabb: &AABB, body: &Body, factor: f32) -> Polygon2d {
+ let top_y = config.body.get_torso_bottom();
+ let full_bottom_y = config.pants.get_bottom_y(&config.body, body);
+ let bottom_y = interpolate(top_y, full_bottom_y, factor);
+ get_pants(config, aabb, body, bottom_y, false)
+}
+
+fn get_pants(
+ config: &RenderConfig,
+ aabb: &AABB,
+ body: &Body,
+ bottom_y: f32,
+ is_balloon: bool,
+) -> Polygon2d {
+ let mut builder = get_base(config, aabb, body);
+ let (pants_width, inner_width) = config.pants.get_widths(&config.body, body);
+ let top_y = config.body.get_torso_bottom();
+ let mid_y = (top_y + bottom_y) * 0.5;
+
+ builder.add_mirrored_points(aabb, pants_width, mid_y, false);
+
+ if is_balloon {
+ let balloon_extra = pants_width * config.pants.balloon_padding;
+ builder.add_mirrored_points(aabb, pants_width + balloon_extra, bottom_y, false);
+ builder.add_mirrored_points(aabb, inner_width - balloon_extra, bottom_y, false);
+ } else {
+ builder.add_mirrored_points(aabb, pants_width, bottom_y, true);
+ builder.add_mirrored_points(aabb, inner_width, bottom_y, true);
+ }
+
+ builder.add_mirrored_points(aabb, inner_width, mid_y, false);
+ builder.add_point(aabb.get_point(0.5, top_y), false);
+
+ builder.build()
+}
+
+fn get_base(config: &RenderConfig, aabb: &AABB, body: &Body) -> Polygon2dBuilder {
+ let torso_aabb = config.body.get_torso_aabb(body, aabb);
+ let hip_width = config.pants.get_hip_width(&config.body, body);
+ let top_y = config.body.y_lower;
+ let center_y = top_y + config.pants.offset_center;
+ let mut builder = Polygon2dBuilder::new();
+
+ // center curves downwards
+ builder.add_point(torso_aabb.get_point(0.5, center_y), false);
+ // rectangle forming the base of the pants
+ builder.add_mirrored_points(&torso_aabb, hip_width, top_y, true);
+ builder.add_mirrored_points(&torso_aabb, hip_width, 1.0, false);
+
+ builder
+}
+
+fn interpolate(start: f32, end: f32, factor: f32) -> f32 {
+ start * (1.0 - factor) + end * factor
+}
diff --git a/rpg_tools_rendering/src/rendering/mod.rs b/rpg_tools_rendering/src/rendering/mod.rs
index c7b65de8..8a0073fa 100644
--- a/rpg_tools_rendering/src/rendering/mod.rs
+++ b/rpg_tools_rendering/src/rendering/mod.rs
@@ -8,6 +8,7 @@ pub mod body;
pub mod character;
pub mod config;
pub mod ear;
+pub mod equipment;
pub mod eye;
pub mod hair;
pub mod head;