From 8572522a80357c33cee819713afadebd24d38e8a Mon Sep 17 00:00:00 2001 From: m00nwtchr Date: Tue, 23 Jul 2024 04:56:25 +0200 Subject: [PATCH] Revival/refactor --- .gitignore | 3 +- cofd/app/.prettierrc.json => .prettierrc.json | 0 Cargo.lock | 1187 +++++++++-------- Cargo.toml | 72 +- cofd/app/Cargo.toml | 60 - cofd/derive/Cargo.toml | 18 - cofd/derive/src/lib.rs | 679 ---------- cofd/lib/Cargo.toml | 19 - cofd/lib/data/gifts.ron | 1 - cofd/lib/data/merits_universal.ron | 691 ---------- cofd/lib/src/character/mod.rs | 1018 -------------- cofd/lib/src/character/modifier.rs | 450 ------- cofd/lib/src/character/traits.rs | 266 ---- cofd/lib/src/dice_pool.rs | 135 -- cofd/lib/src/lib.rs | 304 ----- cofd/lib/src/splat/ability.rs | 78 -- cofd/lib/src/splat/changeling.rs | 139 -- cofd/lib/src/splat/geist.rs | 87 -- cofd/lib/src/splat/mage.rs | 161 --- cofd/lib/src/splat/merits.rs | 429 ------ cofd/lib/src/splat/mod.rs | 302 ----- cofd/lib/src/splat/vampire.rs | 329 ----- cofd/lib/src/splat/werewolf.rs | 686 ---------- cofd/macros/Cargo.toml | 20 - cofd/macros/src/lib.rs | 149 --- cofd/util/Cargo.toml | 13 - cofd/util/src/lib.rs | 26 - cofd/util/src/scraper/mod.rs | 94 -- cofd/xtask/Cargo.toml | 24 - cofd/xtask/src/bin/gifts.rs | 68 - cofd/xtask/src/bin/merits.rs | 72 - cofd/xtask/src/bin/scraper.rs | 127 -- cofd/app/i18n.toml => i18n.toml | 0 {cofd/app/i18n => i18n}/en-GB/cofd_pc.ftl | 0 {cofd/app/i18n => i18n}/en-US/cofd_pc.ftl | 0 {cofd/app/i18n => i18n}/pl-PL/cofd_pc.ftl | 0 cofd/app/index.html => index.html | 2 +- {cofd/app/src => src}/component/attributes.rs | 0 {cofd/app/src => src}/component/forms.rs | 0 {cofd/app/src => src}/component/info.rs | 0 {cofd/app/src => src}/component/integrity.rs | 0 {cofd/app/src => src}/component/list.rs | 0 {cofd/app/src => src}/component/merits.rs | 0 {cofd/app/src => src}/component/mod.rs | 0 {cofd/app/src => src}/component/skills.rs | 0 {cofd/app/src => src}/component/traits.rs | 0 {cofd/app/src => src}/i18n.rs | 0 {cofd/app/src => src}/main.rs | 0 {cofd/app/src => src}/store.rs | 0 {cofd/app/src => src}/view/character_list.rs | 0 {cofd/app/src => src}/view/creator.rs | 0 {cofd/app/src => src}/view/equipment.rs | 0 {cofd/app/src => src}/view/mod.rs | 0 {cofd/app/src => src}/view/overview.rs | 0 {cofd/app/src => src}/view/splat_extras.rs | 0 {cofd/app/src => src}/widget/dots.rs | 0 {cofd/app/src => src}/widget/mod.rs | 0 {cofd/app/src => src}/widget/track.rs | 0 58 files changed, 655 insertions(+), 7054 deletions(-) rename cofd/app/.prettierrc.json => .prettierrc.json (100%) delete mode 100644 cofd/app/Cargo.toml delete mode 100644 cofd/derive/Cargo.toml delete mode 100644 cofd/derive/src/lib.rs delete mode 100644 cofd/lib/Cargo.toml delete mode 100644 cofd/lib/data/gifts.ron delete mode 100644 cofd/lib/data/merits_universal.ron delete mode 100644 cofd/lib/src/character/mod.rs delete mode 100644 cofd/lib/src/character/modifier.rs delete mode 100644 cofd/lib/src/character/traits.rs delete mode 100644 cofd/lib/src/dice_pool.rs delete mode 100644 cofd/lib/src/lib.rs delete mode 100644 cofd/lib/src/splat/ability.rs delete mode 100644 cofd/lib/src/splat/changeling.rs delete mode 100644 cofd/lib/src/splat/geist.rs delete mode 100644 cofd/lib/src/splat/mage.rs delete mode 100644 cofd/lib/src/splat/merits.rs delete mode 100644 cofd/lib/src/splat/mod.rs delete mode 100644 cofd/lib/src/splat/vampire.rs delete mode 100644 cofd/lib/src/splat/werewolf.rs delete mode 100644 cofd/macros/Cargo.toml delete mode 100644 cofd/macros/src/lib.rs delete mode 100644 cofd/util/Cargo.toml delete mode 100644 cofd/util/src/lib.rs delete mode 100644 cofd/util/src/scraper/mod.rs delete mode 100644 cofd/xtask/Cargo.toml delete mode 100644 cofd/xtask/src/bin/gifts.rs delete mode 100644 cofd/xtask/src/bin/merits.rs delete mode 100644 cofd/xtask/src/bin/scraper.rs rename cofd/app/i18n.toml => i18n.toml (100%) rename {cofd/app/i18n => i18n}/en-GB/cofd_pc.ftl (100%) rename {cofd/app/i18n => i18n}/en-US/cofd_pc.ftl (100%) rename {cofd/app/i18n => i18n}/pl-PL/cofd_pc.ftl (100%) rename cofd/app/index.html => index.html (95%) rename {cofd/app/src => src}/component/attributes.rs (100%) rename {cofd/app/src => src}/component/forms.rs (100%) rename {cofd/app/src => src}/component/info.rs (100%) rename {cofd/app/src => src}/component/integrity.rs (100%) rename {cofd/app/src => src}/component/list.rs (100%) rename {cofd/app/src => src}/component/merits.rs (100%) rename {cofd/app/src => src}/component/mod.rs (100%) rename {cofd/app/src => src}/component/skills.rs (100%) rename {cofd/app/src => src}/component/traits.rs (100%) rename {cofd/app/src => src}/i18n.rs (100%) rename {cofd/app/src => src}/main.rs (100%) rename {cofd/app/src => src}/store.rs (100%) rename {cofd/app/src => src}/view/character_list.rs (100%) rename {cofd/app/src => src}/view/creator.rs (100%) rename {cofd/app/src => src}/view/equipment.rs (100%) rename {cofd/app/src => src}/view/mod.rs (100%) rename {cofd/app/src => src}/view/overview.rs (100%) rename {cofd/app/src => src}/view/splat_extras.rs (100%) rename {cofd/app/src => src}/widget/dots.rs (100%) rename {cofd/app/src => src}/widget/mod.rs (100%) rename {cofd/app/src => src}/widget/track.rs (100%) diff --git a/.gitignore b/.gitignore index 51348fb..a803f50 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ /target -cofd/app/dist -cofd/lib/data/cache \ No newline at end of file +/dist \ No newline at end of file diff --git a/cofd/app/.prettierrc.json b/.prettierrc.json similarity index 100% rename from cofd/app/.prettierrc.json rename to .prettierrc.json diff --git a/Cargo.lock b/Cargo.lock index 5fd9e90..36bdfa0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,9 +10,9 @@ checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" [[package]] name = "ab_glyph" -version = "0.2.23" +version = "0.2.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80179d7dd5d7e8c285d67c4a1e652972a92de7475beddfb92028c76463b13225" +checksum = "79faae4620f45232f599d9bc7b290f88247a0834162c4495ab2f02d60004adfb" dependencies = [ "ab_glyph_rasterizer", "owned_ttf_parser", @@ -26,9 +26,9 @@ checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ "gimli", ] @@ -46,7 +46,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", - "getrandom 0.2.12", + "getrandom", "once_cell", "version_check", "zerocopy", @@ -54,9 +54,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -69,9 +69,15 @@ checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "android-tzdata" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" [[package]] name = "android_system_properties" @@ -84,9 +90,12 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.81" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +dependencies = [ + "backtrace", +] [[package]] name = "approx" @@ -99,15 +108,15 @@ dependencies = [ [[package]] name = "arc-swap" -version = "1.7.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b3d0060af21e8d11a926981cc00c6c1541aa91dd64b9f881985c3da1094425f" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" [[package]] name = "arrayref" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" [[package]] name = "arrayvec" @@ -132,15 +141,15 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ "addr2line", "cc", @@ -180,9 +189,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" dependencies = [ "serde", ] @@ -204,28 +213,28 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.15.4" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.14.3" +version = "1.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2ef034f05691a48569bd920a96c81b9d91bbad1ab5ac7c4616c1f6ef36cb79f" +checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4da9a32f3fed317401fa3c862968128267c3106685286e15d5aaa3d7389c2f60" +checksum = "1ee891b04274a59bd38b412188e24b849617b2e45a0fd8d057deb63e7403761b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.72", ] [[package]] @@ -236,9 +245,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" [[package]] name = "calloop" @@ -256,11 +265,11 @@ dependencies = [ [[package]] name = "calloop" -version = "0.12.4" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fba7adb4dd5aa98e5553510223000e7148f621165ec5f9acd7113f6ca4995298" +checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "log", "polling", "rustix", @@ -270,21 +279,21 @@ dependencies = [ [[package]] name = "calloop-wayland-source" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02" +checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" dependencies = [ - "calloop 0.12.4", + "calloop 0.13.0", "rustix", "wayland-backend", - "wayland-client 0.31.2", + "wayland-client 0.31.5", ] [[package]] name = "cc" -version = "1.0.90" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" [[package]] name = "cfg-if" @@ -298,6 +307,21 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets 0.52.6", +] + [[package]] name = "clipboard-win" version = "4.5.0" @@ -380,7 +404,7 @@ dependencies = [ "block", "cocoa-foundation", "core-foundation", - "core-graphics 0.23.1", + "core-graphics 0.23.2", "foreign-types 0.5.0", "libc", "objc", @@ -410,37 +434,56 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "codex-scraper" +version = "0.1.0" +source = "git+https://github.com/m00nwtchr/cofd-miner.git#2d7c0ee7b28453fd4a1fe6f99369fc9ac4cb6473" +dependencies = [ + "anyhow", + "cofd-schema 0.1.0 (git+https://github.com/m00nwtchr/cofd.git?rev=b06c28bd560eae54e77919c0ab6625fa9dcbf902)", + "convert_case", + "itertools 0.12.1", + "log", + "reqwest", + "ron 0.8.1", + "scraper", + "tokio", +] + [[package]] name = "cofd" -version = "1.0.0" +version = "0.1.0" +source = "git+https://github.com/m00nwtchr/cofd.git#a99f457e974f4184581604864e10274d591a3c6b" dependencies = [ "cofd-macros", "cofd-util", - "convert_case 0.6.0", + "convert_case", "erased-serde", - "ron", "serde", ] [[package]] name = "cofd-derive" -version = "1.0.0" +version = "0.1.0" +source = "git+https://github.com/m00nwtchr/cofd.git#a99f457e974f4184581604864e10274d591a3c6b" dependencies = [ - "convert_case 0.6.0", + "convert_case", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.72", ] [[package]] name = "cofd-macros" -version = "1.0.0" +version = "0.1.0" +source = "git+https://github.com/m00nwtchr/cofd.git#a99f457e974f4184581604864e10274d591a3c6b" dependencies = [ - "cofd-util", + "cofd-schema 0.1.0 (git+https://github.com/m00nwtchr/cofd.git)", + "convert_case", "proc-macro2", "quote", - "ron", - "syn 2.0.52", + "ron 0.9.0-alpha.0", + "syn 2.0.72", ] [[package]] @@ -450,6 +493,7 @@ dependencies = [ "anyhow", "cfg-if", "closure", + "codex-scraper", "cofd", "console_log", "directories", @@ -459,11 +503,11 @@ dependencies = [ "iced", "iced_lazy", "iced_native", - "itertools", + "itertools 0.10.5", "lazy_static", "log", "once_cell", - "ron", + "ron 0.9.0-alpha.0", "rust-embed", "serde", "unic-langid", @@ -471,32 +515,45 @@ dependencies = [ ] [[package]] -name = "cofd-util" -version = "1.0.0" +name = "cofd-schema" +version = "0.1.0" +source = "git+https://github.com/m00nwtchr/cofd.git?rev=b06c28bd560eae54e77919c0ab6625fa9dcbf902#b06c28bd560eae54e77919c0ab6625fa9dcbf902" dependencies = [ - "cofd-derive", + "chrono", + "derive_more", + "itertools 0.10.5", "serde", + "strum", + "thiserror", ] [[package]] -name = "cofd-xtask" -version = "1.0.0" +name = "cofd-schema" +version = "0.1.0" +source = "git+https://github.com/m00nwtchr/cofd.git#a99f457e974f4184581604864e10274d591a3c6b" dependencies = [ - "anyhow", - "cofd-util", - "convert_case 0.6.0", - "lazy_static", - "reqwest", - "ron", - "scraper", - "tokio", + "chrono", + "derive_more", + "itertools 0.13.0", + "serde", + "strum", + "thiserror", +] + +[[package]] +name = "cofd-util" +version = "0.1.0" +source = "git+https://github.com/m00nwtchr/cofd.git#a99f457e974f4184581604864e10274d591a3c6b" +dependencies = [ + "cofd-derive", + "serde", ] [[package]] name = "concurrent-queue" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ "crossbeam-utils", ] @@ -517,12 +574,6 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6051f239ecec86fde3410901ab7860d458d160371533842974fc61f96d15879b" -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - [[package]] name = "convert_case" version = "0.6.0" @@ -563,9 +614,9 @@ dependencies = [ [[package]] name = "core-graphics" -version = "0.23.1" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "970a29baf4110c26fedbc7f82107d42c23f7e88e404c4577ed73fe99ff85a212" +checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -592,7 +643,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9d2790b5c08465d49f8dc05c8bcae9fea467855947db39b0f8145c091aaced5" dependencies = [ "core-foundation", - "core-graphics 0.23.1", + "core-graphics 0.23.2", "foreign-types 0.5.0", "libc", ] @@ -608,18 +659,18 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.12" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" dependencies = [ "crossbeam-utils", ] @@ -645,9 +696,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crossfont" @@ -658,7 +709,7 @@ dependencies = [ "cocoa 0.25.0", "core-foundation", "core-foundation-sys", - "core-graphics 0.23.1", + "core-graphics 0.23.2", "core-text", "dwrote", "foreign-types 0.5.0", @@ -684,19 +735,15 @@ dependencies = [ [[package]] name = "cssparser" -version = "0.29.6" +version = "0.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93d03419cb5950ccfd3daf3ff1c7a36ace64609a1a8746d493df1ca0afde0fa" +checksum = "5b3df4f93e5fbbe73ec01ec8d3f68bba73107993a5b1e7519273c32db9b0d5be" dependencies = [ "cssparser-macros", "dtoa-short", "itoa", - "matches", - "phf 0.10.1", - "proc-macro2", - "quote", + "phf 0.11.2", "smallvec", - "syn 1.0.109", ] [[package]] @@ -706,7 +753,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.52", + "syn 2.0.72", ] [[package]] @@ -774,23 +821,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "lock_api", "once_cell", - "parking_lot_core 0.9.9", + "parking_lot_core 0.9.10", ] [[package]] name = "derive_more" -version = "0.99.17" +version = "0.99.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ - "convert_case 0.4.0", "proc-macro2", "quote", - "rustc_version", - "syn 1.0.109", + "syn 2.0.72", ] [[package]] @@ -832,13 +877,13 @@ checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" [[package]] name = "displaydoc" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.72", ] [[package]] @@ -847,14 +892,14 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" dependencies = [ - "libloading 0.8.3", + "libloading 0.8.5", ] [[package]] name = "downcast-rs" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "dtoa" @@ -864,9 +909,9 @@ checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" [[package]] name = "dtoa-short" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbaceec3c6e4211c79e7b1800fb9680527106beb2f9c51904a3210c03a448c74" +checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" dependencies = [ "dtoa", ] @@ -893,9 +938,9 @@ checksum = "3a68a4904193147e0a8dec3314640e6db742afd5f6e634f428a6af230d9b3591" [[package]] name = "either" -version = "1.10.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "encase" @@ -931,9 +976,9 @@ dependencies = [ [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] @@ -968,9 +1013,9 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -988,9 +1033,9 @@ dependencies = [ [[package]] name = "euclid" -version = "0.22.9" +version = "0.22.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f253bc5c813ca05792837a0ff4b3a580336b224512d48f7eda1d7dd9210787" +checksum = "e0f0eb73b934648cd7a4a61f1b15391cd95dab0b4da6e2e66c2a072c144b4a20" dependencies = [ "num-traits", ] @@ -1007,9 +1052,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "fdeflate" @@ -1031,9 +1076,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" dependencies = [ "crc32fast", "miniz_oxide", @@ -1041,9 +1086,9 @@ dependencies = [ [[package]] name = "fluent" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61f69378194459db76abd2ce3952b790db103ceb003008d3d50d97c41ff847a7" +checksum = "bb74634707bebd0ce645a981148e8fb8c7bccd4c33c652aeffd28bf2f96d555a" dependencies = [ "fluent-bundle", "unic-langid", @@ -1051,15 +1096,15 @@ dependencies = [ [[package]] name = "fluent-bundle" -version = "0.15.2" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e242c601dec9711505f6d5bbff5bedd4b61b2469f2e8bb8e57ee7c9747a87ffd" +checksum = "7fe0a21ee80050c678013f82edf4b705fe2f26f1f9877593d13198612503f493" dependencies = [ "fluent-langneg", "fluent-syntax", "intl-memoizer", "intl_pluralrules", - "rustc-hash", + "rustc-hash 1.1.0", "self_cell 0.10.3", "smallvec", "unic-langid", @@ -1076,9 +1121,9 @@ dependencies = [ [[package]] name = "fluent-syntax" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0abed97648395c902868fee9026de96483933faa54ea3b40d652f7dfe61ca78" +checksum = "2a530c4694a6a8d528794ee9bbd8ba0122e779629ac908d15ad5a7ae7763a33d" dependencies = [ "thiserror", ] @@ -1116,7 +1161,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.72", ] [[package]] @@ -1229,7 +1274,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.72", ] [[package]] @@ -1302,31 +1347,20 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", ] [[package]] name = "gimli" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "glam" @@ -1348,36 +1382,36 @@ dependencies = [ [[package]] name = "glyph_brush" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3676f482c536a985fca36ce320a5e5b8fafd7b260806742af1963b71c5dc38c" +checksum = "4ca26e3a8a43052ca015c0b1ce055035ff5bc47afddff5b01c7141e0c3e3a2a1" dependencies = [ "glyph_brush_draw_cache", "glyph_brush_layout", "ordered-float", - "rustc-hash", + "rustc-hash 2.0.0", "twox-hash", ] [[package]] name = "glyph_brush_draw_cache" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6010675390f6889e09a21e2c8b575b3ee25667ea8237a8d59423f73cb8c28610" +checksum = "4bb6c910def52365fef3f439a6b50a4d5c11b28eec4cf6c191f6dfea18e88d7f" dependencies = [ "ab_glyph", "crossbeam-channel", "crossbeam-deque", "linked-hash-map", "rayon", - "rustc-hash", + "rustc-hash 2.0.0", ] [[package]] name = "glyph_brush_layout" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc32c2334f00ca5ac3695c5009ae35da21da8c62d255b5b96d56e2597a637a38" +checksum = "7b1e288bfd2f6c0313f78bf5aa538356ad481a3bb97e9b7f93220ab0066c5992" dependencies = [ "ab_glyph", "approx", @@ -1409,9 +1443,9 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc11df1ace8e7e564511f53af41f3e42ddc95b56fd07b3f4445d2a6048bc682c" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "gpu-descriptor-types", - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] @@ -1420,7 +1454,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bf0b36e6f090b7e1d8a4b49c0cb81c1f8376f72198c65dd3ad9ff3556b8b78c" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", ] [[package]] @@ -1435,9 +1469,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.24" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", @@ -1445,7 +1479,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.2.5", + "indexmap 2.2.6", "slab", "tokio", "tokio-util", @@ -1460,20 +1494,32 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash", "allocator-api2", ] +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + [[package]] name = "hexf-parse" version = "0.2.1" @@ -1482,16 +1528,16 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" [[package]] name = "html5ever" -version = "0.26.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7" +checksum = "c13771afe0e6e846f1e67d038d4cb29998a6779f93c809212e4e9c32efd244d4" dependencies = [ "log", "mac", "markup5ever", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.72", ] [[package]] @@ -1518,9 +1564,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -1536,9 +1582,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.28" +version = "0.14.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" dependencies = [ "bytes", "futures-channel", @@ -1581,7 +1627,7 @@ dependencies = [ "serde", "serde_derive", "thiserror", - "toml 0.8.11", + "toml 0.8.15", "unic-langid", ] @@ -1600,7 +1646,7 @@ dependencies = [ "lazy_static", "locale_config", "log", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "rust-embed", "thiserror", "unic-langid", @@ -1625,7 +1671,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.52", + "syn 2.0.72", "unic-langid", ] @@ -1639,7 +1685,30 @@ dependencies = [ "i18n-config", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.72", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", ] [[package]] @@ -1797,19 +1866,19 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.5" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", "js-sys", @@ -1819,9 +1888,9 @@ dependencies = [ [[package]] name = "intl-memoizer" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c310433e4a310918d6ed9243542a6b83ec1183df95dff8f23f87bb88a264a66f" +checksum = "fe22e020fce238ae18a6d5d8c502ee76a52a6e880d99477657e6acc30ec57bda" dependencies = [ "type-map", "unic-langid", @@ -1848,7 +1917,7 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", "windows-sys 0.52.0", ] @@ -1862,11 +1931,29 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jni-sys" @@ -1896,15 +1983,15 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libloading" @@ -1918,23 +2005,22 @@ dependencies = [ [[package]] name = "libloading" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.52.4", + "windows-targets 0.52.6", ] [[package]] name = "libredox" -version = "0.0.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "libc", - "redox_syscall 0.4.1", ] [[package]] @@ -1945,9 +2031,9 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "locale_config" @@ -1964,9 +2050,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -1974,9 +2060,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "mac" @@ -1995,29 +2081,23 @@ dependencies = [ [[package]] name = "markup5ever" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016" +checksum = "16ce3abbeba692c8b8441d036ef91aea6df8da2c6b6e21c7e14d3c18e526be45" dependencies = [ "log", - "phf 0.10.1", - "phf_codegen 0.10.0", + "phf 0.11.2", + "phf_codegen 0.11.2", "string_cache", "string_cache_codegen", "tendril", ] -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memmap2" @@ -2068,9 +2148,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", "simd-adler32", @@ -2084,7 +2164,7 @@ checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "log", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys 0.48.0", ] @@ -2101,7 +2181,7 @@ dependencies = [ "indexmap 1.9.3", "log", "num-traits", - "rustc-hash", + "rustc-hash 1.1.0", "spirv", "termcolor", "thiserror", @@ -2110,11 +2190,10 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" dependencies = [ - "lazy_static", "libc", "log", "openssl", @@ -2159,7 +2238,7 @@ dependencies = [ "ndk-macro", "ndk-sys", "once_cell", - "parking_lot 0.12.1", + "parking_lot 0.12.3", ] [[package]] @@ -2186,9 +2265,9 @@ dependencies = [ [[package]] name = "new_debug_unreachable" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] name = "nix" @@ -2215,17 +2294,11 @@ dependencies = [ "memoffset", ] -[[package]] -name = "nodrop" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" - [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -2236,7 +2309,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", ] @@ -2302,9 +2375,9 @@ dependencies = [ [[package]] name = "object" -version = "0.32.2" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" dependencies = [ "memchr", ] @@ -2317,11 +2390,11 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "openssl" -version = "0.10.64" +version = "0.10.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "cfg-if", "foreign-types 0.3.2", "libc", @@ -2338,7 +2411,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.72", ] [[package]] @@ -2349,9 +2422,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.101" +version = "0.9.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dda2b0f344e78efc2facf7d195d098df0dd72151b26ab98da807afc26c198dff" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" dependencies = [ "cc", "libc", @@ -2367,9 +2440,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "ordered-float" -version = "4.2.0" +version = "4.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76df7075c7d4d01fdcb46c912dd17fba5b60c78ea480b475f2b6ab6f666584e" +checksum = "19ff2cf528c6c03d9ed653d6c4ce1dc0582dc4af309790ad92f07c1cd551b0be" dependencies = [ "num-traits", ] @@ -2400,9 +2473,9 @@ dependencies = [ [[package]] name = "owned_ttf_parser" -version = "0.20.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4586edfe4c648c71797a74c84bacb32b52b212eff5dfe2bb9f2c599844023e7" +checksum = "490d3a563d3122bf7c911a59b0add9389e5ec0f5f0c3ac6b91ff235a0e6a7f90" dependencies = [ "ttf-parser", ] @@ -2444,12 +2517,12 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", - "parking_lot_core 0.9.9", + "parking_lot_core 0.9.10", ] [[package]] @@ -2468,15 +2541,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.4.1", + "redox_syscall 0.5.3", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -2485,24 +2558,13 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" -[[package]] -name = "phf" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" -dependencies = [ - "phf_shared 0.8.0", -] - [[package]] name = "phf" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" dependencies = [ - "phf_macros 0.10.0", "phf_shared 0.10.0", - "proc-macro-hack", ] [[package]] @@ -2511,20 +2573,10 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ - "phf_macros 0.11.2", + "phf_macros", "phf_shared 0.11.2", ] -[[package]] -name = "phf_codegen" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" -dependencies = [ - "phf_generator 0.8.0", - "phf_shared 0.8.0", -] - [[package]] name = "phf_codegen" version = "0.10.0" @@ -2536,13 +2588,13 @@ dependencies = [ ] [[package]] -name = "phf_generator" -version = "0.8.0" +name = "phf_codegen" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" dependencies = [ - "phf_shared 0.8.0", - "rand 0.7.3", + "phf_generator 0.11.2", + "phf_shared 0.11.2", ] [[package]] @@ -2552,7 +2604,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" dependencies = [ "phf_shared 0.10.0", - "rand 0.8.5", + "rand", ] [[package]] @@ -2562,21 +2614,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" dependencies = [ "phf_shared 0.11.2", - "rand 0.8.5", -] - -[[package]] -name = "phf_macros" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" -dependencies = [ - "phf_generator 0.10.0", - "phf_shared 0.10.0", - "proc-macro-hack", - "proc-macro2", - "quote", - "syn 1.0.109", + "rand", ] [[package]] @@ -2589,16 +2627,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.52", -] - -[[package]] -name = "phf_shared" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" -dependencies = [ - "siphasher", + "syn 2.0.72", ] [[package]] @@ -2621,9 +2650,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -2652,12 +2681,13 @@ dependencies = [ [[package]] name = "polling" -version = "3.5.0" +version = "3.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24f040dee2588b4963afb4e420540439d126f73fdacf4a9c486a96d840bac3c9" +checksum = "a3ed00ed3fbf728b5816498ecd316d1716eecaced9c0c8d2c5a6740ca214985b" dependencies = [ "cfg-if", "concurrent-queue", + "hermit-abi 0.4.0", "pin-project-lite", "rustix", "tracing", @@ -2718,9 +2748,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -2733,36 +2763,22 @@ checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58" [[package]] name = "quick-xml" -version = "0.31.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" +checksum = "6f24d770aeca0eacb81ac29dfbc55ebcc09312fdd1f8bbecdc7e4a84e000e3b4" dependencies = [ "memchr", ] [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", - "rand_pcg", -] - [[package]] name = "rand" version = "0.8.5" @@ -2770,18 +2786,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", + "rand_chacha", + "rand_core", ] [[package]] @@ -2791,16 +2797,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", + "rand_core", ] [[package]] @@ -2809,25 +2806,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.12", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rand_pcg" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" -dependencies = [ - "rand_core 0.5.1", + "getrandom", ] [[package]] @@ -2863,9 +2842,9 @@ checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" [[package]] name = "rayon" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -2892,29 +2871,29 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", ] [[package]] name = "redox_users" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ - "getrandom 0.2.12", + "getrandom", "libredox", "thiserror", ] [[package]] name = "regex" -version = "1.10.3" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", @@ -2924,9 +2903,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", @@ -2935,9 +2914,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "renderdoc-sys" @@ -2947,9 +2926,9 @@ checksum = "f1382d1f0a252c4bf97dc20d979a2fdd05b024acd7c2ed0f7595d7817666a157" [[package]] name = "reqwest" -version = "0.11.26" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bf93c4af7a8bb7d879d51cebe797356ff10ae8516ace542b5182d9dcac10b2" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ "base64", "bytes", @@ -2992,11 +2971,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" dependencies = [ "base64", - "bitflags 2.4.2", + "bitflags 2.6.0", "serde", "serde_derive", ] +[[package]] +name = "ron" +version = "0.9.0-alpha.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c0bd893640cac34097a74f0c2389ddd54c62d6a3c635fa93cafe6b6bc19be6a" +dependencies = [ + "base64", + "bitflags 2.6.0", + "serde", + "serde_derive", + "unicode-ident", +] + [[package]] name = "rust-embed" version = "6.8.1" @@ -3017,7 +3009,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.52", + "syn 2.0.72", "walkdir", ] @@ -3033,9 +3025,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" @@ -3044,21 +3036,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] -name = "rustc_version" -version = "0.4.0" +name = "rustc-hash" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] +checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -3075,10 +3064,16 @@ dependencies = [ ] [[package]] -name = "ryu" +name = "rustversion" version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "safe_arch" @@ -3121,9 +3116,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "scraper" -version = "0.16.0" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59e25654b5e9fd557a67dbaab5a5d36b8c448d0561beb4c041b6dbb902eddfa6" +checksum = "761fb705fdf625482d2ed91d3f0559dcfeab2798fe2771c69560a774865d0802" dependencies = [ "ahash", "cssparser", @@ -3132,7 +3127,6 @@ dependencies = [ "html5ever", "once_cell", "selectors", - "smallvec", "tendril", ] @@ -3150,11 +3144,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.2" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "core-foundation", "core-foundation-sys", "libc", @@ -3163,9 +3157,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" dependencies = [ "core-foundation-sys", "libc", @@ -3173,17 +3167,18 @@ dependencies = [ [[package]] name = "selectors" -version = "0.24.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c37578180969d00692904465fb7f6b3d50b9a2b952b87c23d0e2e5cb5013416" +checksum = "4eb30575f3638fc8f6815f448d50cb1a2e255b0897985c8c59f4d37b72a07b06" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "cssparser", "derive_more", "fxhash", "log", - "phf 0.8.0", - "phf_codegen 0.8.0", + "new_debug_unreachable", + "phf 0.10.1", + "phf_codegen 0.10.0", "precomputed-hash", "servo_arc", "smallvec", @@ -3195,46 +3190,40 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e14e4d63b804dc0c7ec4a1e52bcb63f02c7ac94476755aa579edac21e01f915d" dependencies = [ - "self_cell 1.0.3", + "self_cell 1.0.4", ] [[package]] name = "self_cell" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58bf37232d3bb9a2c4e641ca2a11d83b5062066f88df7fed36c28772046d65ba" - -[[package]] -name = "semver" -version = "1.0.22" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "d369a96f978623eb3dc28807c4852d6cc617fed53da5d3c400feff1ef34a714a" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.72", ] [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ "itoa", "ryu", @@ -3243,9 +3232,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" dependencies = [ "serde", ] @@ -3285,11 +3274,10 @@ dependencies = [ [[package]] name = "servo_arc" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52aa42f8fdf0fed91e5ce7f23d8138441002fa31dca008acf47e6fd4721f741" +checksum = "d036d71a959e00c77a63538b90a6c2390969f9772b096ea837205c6bd0491a44" dependencies = [ - "nodrop", "stable_deref_trait", ] @@ -3304,15 +3292,6 @@ dependencies = [ "digest", ] -[[package]] -name = "signal-hook-registry" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" -dependencies = [ - "libc", -] - [[package]] name = "simd-adler32" version = "0.3.7" @@ -3345,9 +3324,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "smithay-client-toolkit" @@ -3370,12 +3349,12 @@ dependencies = [ [[package]] name = "smithay-client-toolkit" -version = "0.18.1" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "922fd3eeab3bd820d76537ce8f582b1cf951eceb5475c28500c7457d9d17f53a" +checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" dependencies = [ - "bitflags 2.4.2", - "calloop 0.12.4", + "bitflags 2.6.0", + "calloop 0.13.0", "calloop-wayland-source", "cursor-icon", "libc", @@ -3384,31 +3363,31 @@ dependencies = [ "rustix", "thiserror", "wayland-backend", - "wayland-client 0.31.2", + "wayland-client 0.31.5", "wayland-csd-frame", - "wayland-cursor 0.31.1", - "wayland-protocols 0.31.2", + "wayland-cursor 0.31.5", + "wayland-protocols 0.32.3", "wayland-protocols-wlr", - "wayland-scanner 0.31.1", + "wayland-scanner 0.31.4", "xkeysym", ] [[package]] name = "smithay-clipboard" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c091e7354ea8059d6ad99eace06dd13ddeedbb0ac72d40a9a6e7ff790525882d" +checksum = "cc8216eec463674a0e90f29e0ae41a4db573ec5b56b1c6c1c71615d249b6d846" dependencies = [ "libc", - "smithay-client-toolkit 0.18.1", + "smithay-client-toolkit 0.19.2", "wayland-backend", ] [[package]] name = "socket2" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", "windows-sys 0.52.0", @@ -3450,7 +3429,7 @@ checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" dependencies = [ "new_debug_unreachable", "once_cell", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "phf_shared 0.10.0", "precomputed-hash", "serde", @@ -3474,11 +3453,33 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.72", +] + [[package]] name = "svg_fmt" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83ba502a3265efb76efb89b0a2f7782ad6f2675015d4ce37e4b547dda42b499" +checksum = "20e16a0f46cf5fd675563ef54f26e83e20f2366bcf027bcb3cc3ed2b98aaf2ca" [[package]] name = "syn" @@ -3493,9 +3494,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.52" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ "proc-macro2", "quote", @@ -3563,22 +3564,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.58" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.72", ] [[package]] @@ -3608,18 +3609,18 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c02bf3c538ab32ba913408224323915f4ef9a6d61c0e85d493f355921c0ece" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ "displaydoc", ] [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -3632,18 +3633,15 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.36.0" +version = "1.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +checksum = "eb2caba9f80616f438e09748d5acda951967e1ea58508ef53d9c6402485a46df" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", - "parking_lot 0.12.1", "pin-project-lite", - "signal-hook-registry", "socket2", "tokio-macros", "windows-sys 0.48.0", @@ -3651,13 +3649,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.72", ] [[package]] @@ -3672,16 +3670,15 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] @@ -3695,21 +3692,21 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.11" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af06656561d28735e9c1cd63dfd57132c8155426aa6af24f36a00a351f88c48e" +checksum = "ac2caab0bf757388c6c0ae23b3293fdb463fee59434529014f85e3263b995c28" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.7", + "toml_edit 0.22.16", ] [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" dependencies = [ "serde", ] @@ -3720,22 +3717,22 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.2.5", + "indexmap 2.2.6", "toml_datetime", "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.22.7" +version = "0.22.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18769cd1cec395d70860ceb4d932812a0b4d06b1a4bb336745a4d21b9496e992" +checksum = "278f3d518e152219c994ce877758516bca5e118eaed6996192a774fb9fbf0788" dependencies = [ - "indexmap 2.2.5", + "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.5", + "winnow 0.6.15", ] [[package]] @@ -3771,9 +3768,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "ttf-parser" -version = "0.20.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4" +checksum = "8686b91785aff82828ed725225925b33b4fde44c4bb15876e5f7c832724c420a" [[package]] name = "twox-hash" @@ -3782,17 +3779,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ "cfg-if", - "rand 0.8.5", + "rand", "static_assertions", ] [[package]] name = "type-map" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d3364c5e96cb2ad1603037ab253ddd34d7fb72a58bdddf4b7350760fc69a46" +checksum = "deb68604048ff8fa93347f02441e4487594adc20bb8a084f9e564d2b827a0a9f" dependencies = [ - "rustc-hash", + "rustc-hash 1.1.0", ] [[package]] @@ -3803,9 +3800,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unic-langid" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "238722e6d794ed130f91f4ea33e01fcff4f188d92337a21297892521c72df516" +checksum = "23dd9d1e72a73b25e07123a80776aae3e7b0ec461ef94f9151eed6ec88005a44" dependencies = [ "unic-langid-impl", "unic-langid-macros", @@ -3813,9 +3810,9 @@ dependencies = [ [[package]] name = "unic-langid-impl" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bd55a2063fdea4ef1f8633243a7b0524cbeef1905ae04c31a1c9b9775c55bc6" +checksum = "0a5422c1f65949306c99240b81de9f3f15929f5a8bfe05bb44b034cc8bf593e5" dependencies = [ "serde", "tinystr", @@ -3823,9 +3820,9 @@ dependencies = [ [[package]] name = "unic-langid-macros" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c854cefb82ff2816410ce606acbad1b3af065140907b29be9229040752b83ec" +checksum = "0da1cd2c042d3c7569a1008806b02039e7a4a2bdf8f8e96bd3c792434a0e275e" dependencies = [ "proc-macro-hack", "tinystr", @@ -3835,13 +3832,13 @@ dependencies = [ [[package]] name = "unic-langid-macros-impl" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea2a4c80deb4fb3ca51f66b5e2dd91e3642bbce52234bcf22e41668281208e4" +checksum = "1ed7f4237ba393424195053097c1516bd4590dc82b84f2f97c5c69e12704555b" dependencies = [ "proc-macro-hack", "quote", - "syn 2.0.52", + "syn 2.0.72", "unic-langid-impl", ] @@ -3874,9 +3871,9 @@ checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "unicode-xid" @@ -3886,9 +3883,9 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "url" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -3938,12 +3935,6 @@ dependencies = [ "try-lock", ] -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -3971,7 +3962,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.72", "wasm-bindgen-shared", ] @@ -4005,7 +3996,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.72", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4033,16 +4024,16 @@ dependencies = [ [[package]] name = "wayland-backend" -version = "0.3.3" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d50fa61ce90d76474c87f5fc002828d81b32677340112b4ef08079a9d459a40" +checksum = "f90e11ce2ca99c97b940ee83edbae9da2d56a08f9ea8158550fd77fa31722993" dependencies = [ "cc", "downcast-rs", "rustix", "scoped-tls", "smallvec", - "wayland-sys 0.31.1", + "wayland-sys 0.31.4", ] [[package]] @@ -4063,14 +4054,14 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.31.2" +version = "0.31.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82fb96ee935c2cea6668ccb470fb7771f6215d1691746c2d896b447a00ad3f1f" +checksum = "7e321577a0a165911bdcfb39cf029302479d7527b517ee58ab0f6ad09edf0943" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "rustix", "wayland-backend", - "wayland-scanner 0.31.1", + "wayland-scanner 0.31.4", ] [[package]] @@ -4091,7 +4082,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "cursor-icon", "wayland-backend", ] @@ -4109,12 +4100,12 @@ dependencies = [ [[package]] name = "wayland-cursor" -version = "0.31.1" +version = "0.31.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71ce5fa868dd13d11a0d04c5e2e65726d0897be8de247c0c5a65886e283231ba" +checksum = "6ef9489a8df197ebf3a8ce8a7a7f0a2320035c3743f3c1bd0bdbccf07ce64f95" dependencies = [ "rustix", - "wayland-client 0.31.2", + "wayland-client 0.31.5", "xcursor", ] @@ -4132,27 +4123,27 @@ dependencies = [ [[package]] name = "wayland-protocols" -version = "0.31.2" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" +checksum = "62989625a776e827cc0f15d41444a3cea5205b963c3a25be48ae1b52d6b4daaa" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "wayland-backend", - "wayland-client 0.31.2", - "wayland-scanner 0.31.1", + "wayland-client 0.31.5", + "wayland-scanner 0.31.4", ] [[package]] name = "wayland-protocols-wlr" -version = "0.2.0" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" +checksum = "fd993de54a40a40fbe5601d9f1fbcaef0aebcc5fda447d7dc8f6dcbaae4f8953" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "wayland-backend", - "wayland-client 0.31.2", - "wayland-protocols 0.31.2", - "wayland-scanner 0.31.1", + "wayland-client 0.31.5", + "wayland-protocols 0.32.3", + "wayland-scanner 0.31.4", ] [[package]] @@ -4168,9 +4159,9 @@ dependencies = [ [[package]] name = "wayland-scanner" -version = "0.31.1" +version = "0.31.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63b3a62929287001986fb58c789dce9b67604a397c15c611ad9f747300b6c283" +checksum = "d7b56f89937f1cf2ee1f1259cf2936a17a1f45d8f0aa1019fae6d470d304cfa6" dependencies = [ "proc-macro2", "quick-xml", @@ -4190,9 +4181,9 @@ dependencies = [ [[package]] name = "wayland-sys" -version = "0.31.1" +version = "0.31.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15a0c8eaff5216d07f226cb7a549159267f3467b289d9a2e52fd3ef5aae2b7af" +checksum = "43676fe2daf68754ecf1d72026e4e6c15483198b5d24e888b74d3f22f887a148" dependencies = [ "dlib", "log", @@ -4220,7 +4211,7 @@ dependencies = [ "js-sys", "log", "naga", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "raw-window-handle 0.5.2", "smallvec", "static_assertions", @@ -4246,7 +4237,7 @@ dependencies = [ "fxhash", "log", "naga", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "profiling", "raw-window-handle 0.5.2", "smallvec", @@ -4282,7 +4273,7 @@ dependencies = [ "metal", "naga", "objc", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "profiling", "range-alloc", "raw-window-handle 0.5.2", @@ -4334,11 +4325,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -4361,6 +4352,15 @@ dependencies = [ "thiserror", ] +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.36.1" @@ -4389,7 +4389,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.6", ] [[package]] @@ -4409,17 +4409,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -4430,9 +4431,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -4448,9 +4449,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -4466,9 +4467,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -4484,9 +4491,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -4502,9 +4509,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -4514,9 +4521,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -4532,9 +4539,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winit" @@ -4555,7 +4562,7 @@ dependencies = [ "ndk-glue", "objc", "once_cell", - "parking_lot 0.12.1", + "parking_lot 0.12.3", "percent-encoding", "raw-window-handle 0.4.3", "raw-window-handle 0.5.2", @@ -4580,9 +4587,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.5" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" +checksum = "557404e450152cd6795bb558bca69e43c585055f4606e3bcae5894fc6dac9ba0" dependencies = [ "memchr", ] @@ -4619,9 +4626,9 @@ dependencies = [ [[package]] name = "x11rb" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8f25ead8c7e4cba123243a6367da5d3990e0d3affa708ea19dce96356bd9f1a" +checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" dependencies = [ "gethostname", "rustix", @@ -4630,15 +4637,15 @@ dependencies = [ [[package]] name = "x11rb-protocol" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e63e71c4b8bd9ffec2c963173a4dc4cbde9ee96961d4fcb4429db9929b606c34" +checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" [[package]] name = "xcursor" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a0ccd7b4a5345edfcd0c3535718a4e9ff7798ffc536bb5b5a0e26ff84732911" +checksum = "d491ee231a51ae64a5b762114c3ac2104b967aadba1de45c86ca42cf051513b7" [[package]] name = "xi-unicode" @@ -4648,32 +4655,32 @@ checksum = "a67300977d3dc3f8034dae89778f502b6ba20b269527b3223ba59c0cf393bb8a" [[package]] name = "xkeysym" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "054a8e68b76250b253f671d1268cb7f1ae089ec35e195b2efb2a4e9a836d0621" +checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" [[package]] name = "xml-rs" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" +checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193" [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.72", ] diff --git a/Cargo.toml b/Cargo.toml index 89a9d61..d0315da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,22 +1,10 @@ -[workspace] -members = [ "cofd/*" ] -default-members = [ "cofd/app" ] -resolver = "2" - -[workspace.package] +[package] +name = "cofd-pc" version = "1.0.0" authors = ["m00n"] edition = "2021" license = "MPL" - -[workspace.dependencies] -cofd = { path = "cofd/lib" } -cofd-derive = { path = "cofd/derive" } -cofd-macros = { path = "cofd/macros" } -cofd-util = { path = "cofd/util" } -cofd-xtask = { path = "cofd/xtask" } - -ron = "0.8" +publish = false [profile.dev] incremental = false @@ -41,4 +29,56 @@ opt-level = 0 overflow-checks = false incremental = false codegen-units = 1 -inherits = "test" \ No newline at end of file +inherits = "test" + +[dependencies] +iced = "0.8" +iced_lazy = "0.5" +iced_native = "0.9" +# iced_style = "0.5" +# iced = { git = "https://github.com/iced-rs/iced" } +# iced_lazy = { git = "https://github.com/iced-rs/iced" } +# iced_native = { git = "https://github.com/iced-rs/iced" } +# iced_aw = {version = "0.2", default-features = false, features = ["pure", "tabs"]} +# iced_aw = {git = "https://github.com/iced-rs/iced_aw", features = ["pure", "tabs"]} +# iced_aw = { git = "https://github.com/genusistimelord/iced_aw", features = ["tabs"] } +log = "0.4" + +cofd = { git = "https://github.com/m00nwtchr/cofd.git" } +codex-scraper = { git = "https://github.com/m00nwtchr/cofd-miner.git" } + +closure = "0.3" +lazy_static = "1" +cfg-if = "1" + +ron = "0.9.0-alpha.0" +serde = "1" + +itertools = "0.10" + + +i18n-embed = { version = "0.13", features = ["fluent-system"] } +i18n-embed-fl = "0.6" +rust-embed = "6" +unic-langid = { version = "0.9", features = ["macros"] } + +once_cell = "1.4" + +anyhow = "1" + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +i18n-embed = { version = "0.13", features = ["desktop-requester"] } +env_logger = "0.10" +directories = "5" + +[target.'cfg(target_arch = "wasm32")'.dependencies] +i18n-embed = { version = "0.13", features = ["web-sys-requester"] } +rust-embed = { version = "6", features = [ "debug-embed" ] } +console_log = "1" + +[target.'cfg(target_arch = "wasm32")'.dependencies.web-sys] +version = "0.3.60" +features = [ + 'Window', + 'Storage' +] \ No newline at end of file diff --git a/cofd/app/Cargo.toml b/cofd/app/Cargo.toml deleted file mode 100644 index d687367..0000000 --- a/cofd/app/Cargo.toml +++ /dev/null @@ -1,60 +0,0 @@ -[package] -name = "cofd-pc" -# version.workspace = true -version = "1.0.0" -authors.workspace = true -edition.workspace = true -license.workspace = true - -publish = false - -[dependencies] -iced = "0.8" -iced_lazy = "0.5" -iced_native = "0.9" -# iced_style = "0.5" -# iced = { git = "https://github.com/iced-rs/iced" } -# iced_lazy = { git = "https://github.com/iced-rs/iced" } -# iced_native = { git = "https://github.com/iced-rs/iced" } -# iced_aw = {version = "0.2", default-features = false, features = ["pure", "tabs"]} -# iced_aw = {git = "https://github.com/iced-rs/iced_aw", features = ["pure", "tabs"]} -# iced_aw = { git = "https://github.com/genusistimelord/iced_aw", features = ["tabs"] } -log = "0.4" - -closure = "0.3" -lazy_static = "1" -cfg-if = "1" - -ron = "0.8" -serde = "1" - -itertools = "0.10" - - -i18n-embed = { version = "0.13", features = ["fluent-system"] } -i18n-embed-fl = "0.6" -rust-embed = "6" -unic-langid = { version = "0.9", features = ["macros"] } - -once_cell = "1.4" - -anyhow = "1" - -cofd.workspace = true - -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] -i18n-embed = { version = "0.13", features = ["desktop-requester"] } -env_logger = "0.10" -directories = "5" - -[target.'cfg(target_arch = "wasm32")'.dependencies] -i18n-embed = { version = "0.13", features = ["web-sys-requester"] } -rust-embed = { version = "6", features = [ "debug-embed" ] } -console_log = "1" - -[target.'cfg(target_arch = "wasm32")'.dependencies.web-sys] -version = "0.3.60" -features = [ - 'Window', - 'Storage' -] \ No newline at end of file diff --git a/cofd/derive/Cargo.toml b/cofd/derive/Cargo.toml deleted file mode 100644 index 19b59cf..0000000 --- a/cofd/derive/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "cofd-derive" -version.workspace = true -authors.workspace = true -edition.workspace = true -license.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -proc-macro = true - -[dependencies] -proc-macro2 = "1" -quote = "1" -syn = "2" - -convert_case = "0.6" \ No newline at end of file diff --git a/cofd/derive/src/lib.rs b/cofd/derive/src/lib.rs deleted file mode 100644 index babde66..0000000 --- a/cofd/derive/src/lib.rs +++ /dev/null @@ -1,679 +0,0 @@ -#![feature(let_chains)] -use std::collections::HashMap; - -use proc_macro2::{Span, TokenStream}; -use quote::{quote, quote_spanned}; -use syn::{ - parse_macro_input, spanned::Spanned, Data, DeriveInput, Error, Fields, GenericArgument, - PathArguments, Type, Variant, -}; - -use convert_case::Casing; - -macro_rules! derive_error { - ($string: tt) => { - Error::new(Span::call_site(), $string) - .to_compile_error() - .into() - }; -} - -fn parse_args(variant: &Variant, map: &mut HashMap) -> syn::Result<()> { - for attr in &variant.attrs { - if attr.path().is_ident("splat") { - attr.parse_nested_meta(|meta| { - let val: syn::Expr = meta.value()?.parse()?; - - map.insert(meta.path.get_ident().unwrap().to_string(), quote! { #val }); - Ok(()) - })?; - break; - } - } - - Ok(()) -} - -fn variant_fields(variant: &Variant) -> TokenStream { - match &variant.fields { - Fields::Unnamed(_) => quote_spanned! {variant.span()=> (..) }, - Fields::Unit => quote_spanned! { variant.span()=> }, - Fields::Named(_) => quote_spanned! {variant.span()=> {..} }, - } -} - -type TokenStreams = (TokenStream, TokenStream, TokenStream, TokenStream); - -fn parse_variant_field( - variant: &Variant, - iter: &mut syn::punctuated::Iter, - stream: &mut TokenStreams, - xyz: XYZ, - impls: &mut TokenStream, - args: &mut HashMap, -) { - let variant_name = &variant.ident; - let variant_name_lower = variant_name.to_string().to_case(convert_case::Case::Snake); - if let Some(field) = iter.next() { - if field.attrs.iter().any(|attr| attr.path().is_ident("skip")) { - return; - } - - if let Type::Path(ty) = &field.ty { - if let Some(segment) = ty.path.segments.first() { - let mut type_ = None; - - let is_option = segment.ident.eq("Option"); - let is_vec = segment.ident.eq("Vec"); - - if let PathArguments::AngleBracketed(arguments) = &segment.arguments && - !arguments.args.is_empty() && - let Some(GenericArgument::Type(ty)) = arguments.args.first() - { if let Type::Path(ty) = ty { type_ = Some(ty); } } else { type_ = Some(ty); } - - if let Some(ty) = type_ { - let key = String::from(xyz.key()); - let name = xyz.name(); - - stream.0.extend(quote_spanned! { ty.span()=> - #[expand] - #variant_name(#ty), - }); - stream.1.extend(quote_spanned! { ty.span()=> - Self::#variant_name(..) => #ty::all().into_iter().map(Into::into).collect(), - }); - - let s = if is_option { - quote! { val.clone().map(Into::into) } - } else if is_vec { - quote! { val.first().clone().map(Into::into) } - } else { - quote! { Some(val.clone().into()) } - }; - - let fields = match xyz { - XYZ::X => quote! {(val, ..)}, - XYZ::Y => quote! {(_, val, ..)}, - XYZ::Z => quote! {(_, _, val, ..)}, - }; - - stream.2.extend(quote_spanned! { ty.span()=> - Self::#variant_name #fields => #s, - }); - - let set = if is_option { - quote! { - match splat { - Some(splat) => { - if let #name::#variant_name(splat) = splat { - *val = Some(splat) - } - }, - None => *val = None, - } - } - } else { - quote! { - if let Some(#name::#variant_name (splat)) = splat { - *val = splat - } - } - }; - - stream.3.extend(quote_spanned! { ty.span()=> - Self::#variant_name #fields => #set, - }); - - let lower = ty - .path - .get_ident() - .unwrap() - .to_string() - .to_case(convert_case::Case::Snake); - args.insert(key, quote! { #lower }); - impls.extend(quote_spanned! { ty.span()=> - impl From<#ty> for #name { - fn from(val: #ty) -> Self { - #name::#variant_name(val) - } - } - impl NameKey for #ty { - fn name_key(&self) -> String { - format!("{}.{}", #variant_name_lower, self.name()) - } - } - }); - } - } - } - } -} - -enum XYZ { - X, - Y, - Z, -} - -impl XYZ { - pub fn key(&self) -> &str { - match self { - XYZ::X => "xsplat", - XYZ::Y => "ysplat", - XYZ::Z => "zsplat", - } - } - pub fn name(&self) -> TokenStream { - match self { - XYZ::X => quote! { XSplat }, - XYZ::Y => quote! { YSplat }, - XYZ::Z => quote! { ZSplat }, - } - } -} - -#[proc_macro_derive(SplatEnum, attributes(splat, skip))] -pub fn derive_splat_enum(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let input = parse_macro_input!(input as DeriveInput); - - let name = &input.ident; - let data = &input.data; - - let mut xsplat = ( - TokenStream::new(), - TokenStream::new(), - TokenStream::new(), - TokenStream::new(), - ); - let mut ysplat = ( - TokenStream::new(), - TokenStream::new(), - TokenStream::new(), - TokenStream::new(), - ); - let mut zsplat = ( - TokenStream::new(), - TokenStream::new(), - TokenStream::new(), - TokenStream::new(), - ); - - let mut impls = TokenStream::new(); - - let mut variants_map = HashMap::new(); - let mut name_key_match_cases = TokenStream::new(); - - if let Data::Enum(data_enum) = data { - let mut args = HashMap::new(); - - for variant in &data_enum.variants { - let variant_name = &variant.ident; - let variant_name_lower = variant_name.to_string().to_case(convert_case::Case::Snake); - - args.clear(); - parse_args(variant, &mut args).unwrap(); - - let fields_in_variant = variant_fields(variant); - - if let Fields::Unnamed(fields) = &variant.fields { - let mut iter = fields.unnamed.iter(); - - parse_variant_field( - variant, - &mut iter, - &mut xsplat, - XYZ::X, - &mut impls, - &mut args, - ); - parse_variant_field( - variant, - &mut iter, - &mut ysplat, - XYZ::Y, - &mut impls, - &mut args, - ); - parse_variant_field( - variant, - &mut iter, - &mut zsplat, - XYZ::Z, - &mut impls, - &mut args, - ); - } - - let mut gen_match_arm = |key: &str, b: bool| { - if let Some(val) = args.get(key) { - let v = if b { - quote_spanned! { variant.span()=> Some(#val) } - } else { - quote_spanned! { variant.span()=> #val } - }; - - if !variants_map.contains_key(key) { - variants_map.insert(key.to_string(), TokenStream::new()); - } - variants_map - .get_mut(key) - .unwrap() - .extend(quote_spanned! {variant.span()=> - #name::#variant_name #fields_in_variant => #v, - }); - } - }; - - gen_match_arm("virtue_anchor", false); - gen_match_arm("vice_anchor", false); - - gen_match_arm("xsplat", true); - gen_match_arm("ysplat", true); - gen_match_arm("zsplat", true); - - gen_match_arm("ability", true); - gen_match_arm("abilities_finite", false); - - gen_match_arm("st", true); - gen_match_arm("alt_beats", true); - - gen_match_arm("fuel", true); - gen_match_arm("integrity", false); - - name_key_match_cases.extend(quote_spanned! {variant.span()=> - #name::#variant_name #fields_in_variant => String::from(#variant_name_lower), - }); - } - } else { - return derive_error!("SplatEnum is only implemented for enums"); - } - - let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); - - let mut funcs = TokenStream::new(); - let mut funcss = TokenStream::new(); - - let mut gen_func = |key: &str, name: &str, b: bool, default: Option<&str>| { - if let Some(val) = variants_map.get(key) { - let ident = syn::Ident::new(name, Span::call_site()); - let o = if b { - quote! { Option<&str> } - } else { - quote! { &str } - }; - - let def_match = if b { - quote! { None } - } else if let Some(default) = default { - quote! { #default } - } else { - quote! { "" } - }; - - funcs.extend(quote! { - pub fn #ident(&self) -> #o { - match self { - #val - _ => #def_match - } - } - }); - } - }; - - gen_func("virtue_anchor", "virtue_anchor", false, Some("virtue")); - gen_func("vice_anchor", "vice_anchor", false, Some("vice")); - - gen_func("xsplat", "xsplat_name", true, None); - gen_func("ysplat", "ysplat_name", true, None); - gen_func("zsplat", "zsplat_name", true, None); - - gen_func("ability", "ability_name", true, None); - if let Some(val) = variants_map.get("abilities_finite") { - funcss.extend(quote! { - pub fn are_abilities_finite(&self) -> bool { - match self { - #val - _ => true - } - } - }); - } - - gen_func("st", "supernatural_tolerance", true, None); - gen_func("alt_beats", "alternate_beats", true, None); - - gen_func("fuel", "fuel", true, None); - gen_func("integrity", "integrity", false, Some("integrity")); - - let (xsplats, xsplats_all, xsplat, set_xsplat) = xsplat; - let (ysplats, ysplats_all, ysplat, set_ysplat) = ysplat; - let (zsplats, zsplats_all, zsplat, set_zsplat) = zsplat; - - let expanded = quote! { - impl #impl_generics #name #ty_generics #where_clause { - #funcs - #funcss - - pub fn set_xsplat(&mut self, splat: Option) { - match self { - #set_xsplat - _ => {} - } - } - - pub fn set_ysplat(&mut self, splat: Option) { - match self { - #set_ysplat - _ => {} - } - } - - pub fn set_zsplat(&mut self, splat: Option) { - match self { - #set_zsplat - _ => {} - } - } - - pub fn xsplat(&self) -> Option { - match self { - #xsplat - _ => None, - } - } - pub fn ysplat(&self) -> Option { - match self { - #ysplat - _ => None, - } - } - pub fn zsplat(&self) -> Option { - match self { - #zsplat - _ => None, - } - } - - pub fn xsplats(&self) -> Vec { - match self { - #xsplats_all - _ => Vec::new(), - } - } - pub fn ysplats(&self) -> Vec { - match self { - #ysplats_all - _ => Vec::new(), - } - } - pub fn zsplats(&self) -> Vec { - match self { - #zsplats_all - _ => Vec::new(), - } - } - } - - impl #impl_generics NameKey for #name #ty_generics #where_clause { - fn name_key(&self) -> String { - match self { - #name_key_match_cases - } - } - } - - #[derive(Debug, Clone, PartialEq, Eq, VariantName, NameKey)] - pub enum XSplat { - #xsplats - } - #[derive(Debug, Clone, PartialEq, Eq, VariantName, NameKey)] - pub enum YSplat { - #ysplats - } - #[derive(Debug, Clone, PartialEq, Eq, VariantName, NameKey)] - pub enum ZSplat { - #zsplats - } - - #impls - }; - - proc_macro::TokenStream::from(expanded) -} - -#[proc_macro_derive(VariantName, attributes(expand))] -pub fn derive_variant_name(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let input = parse_macro_input!(input as DeriveInput); - - let name = &input.ident; - let data = &input.data; - - let mut name_fun_variants = TokenStream::new(); - - if let Data::Enum(data) = data { - for variant in &data.variants { - let variant_name = &variant.ident; - - let mut expand = false; - - for attr in &variant.attrs { - if attr.path().is_ident("expand") { - expand = true; - break; - } - } - - if variant_name.eq("_Custom") { - if let Fields::Unnamed(fields) = &variant.fields { - if let Some(field) = fields.unnamed.first() { - name_fun_variants.extend(quote_spanned! {field.span()=> - #name::#variant_name (name, ..) => name, - }); - } - } - } else { - let mut match_arm = TokenStream::new(); - - let fields_in_variant = if expand && variant.fields.len() == 1 { - quote_spanned! {variant.span()=> (val) } - } else { - variant_fields(variant) - }; - - let variant_name_lower = - variant_name.to_string().to_case(convert_case::Case::Snake); - - if expand { - if let Fields::Unnamed(fields) = &variant.fields && let Some(field) = fields.unnamed.first() && let Type::Path(ty) = &field.ty { - if ty.path.segments.first().unwrap().ident.eq("Option") { - match_arm.extend(quote_spanned! {ty.span()=> - match val { - Some(val) => VariantName::name(val), - None => #variant_name_lower - } - }); - } else { - match_arm.extend(quote_spanned! {ty.span()=> - VariantName::name(val) - }); - } - } - } else { - match_arm.extend(quote_spanned! {variant.span()=> #variant_name_lower }); - } - - name_fun_variants.extend(quote_spanned! {variant.span()=> - #name::#variant_name #fields_in_variant => #match_arm, - }); - } - } - } else { - return derive_error!("VariantName is only implemented for enums"); - } - - let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); - - let expanded = quote! { - impl #impl_generics cofd_util::VariantName for #name #ty_generics #where_clause { - fn name(&self) -> &str { - match self { - #name_fun_variants - } - } - } - }; - - proc_macro::TokenStream::from(expanded) -} - -#[proc_macro_derive(AllVariants, attributes(expand))] -pub fn derive_all_variants(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let input = parse_macro_input!(input as DeriveInput); - - let name = &input.ident; - let data = &input.data; - - let mut all_variants = TokenStream::new(); - let mut sub_enums = TokenStream::new(); - - let mut num: usize = 0; - - let mut flag = false; - - if let Data::Enum(data) = data { - for variant in &data.variants { - let variant_name = &variant.ident; - - if variant_name.eq("_Custom") { - continue; - } - - let mut flag1 = false; - - for attr in &variant.attrs { - if attr.path().is_ident("expand") { - flag1 = true; - flag = true; - break; - } - } - - let fields = match &variant.fields { - Fields::Unnamed(fields) => { - let mut field_tokens = TokenStream::new(); - - if !flag1 { - for field in &fields.unnamed { - field_tokens - .extend(quote_spanned! { field.span()=> Default::default(), }); - } - } else if let Some(field) = fields.unnamed.first() { - if let syn::Type::Path(ty) = &field.ty { - if let Some(segment) = ty.path.segments.first() { - if let PathArguments::AngleBracketed(arguments) = &segment.arguments - { - if let Some(GenericArgument::Type(ty2)) = arguments.args.first() - { - sub_enums.extend( - quote_spanned! { field.span()=> vec.extend(<#ty2 as AllVariants>::all().map(Into::into)); }, - ); - } - - if segment.ident.to_string().eq("Box") { - continue; - } else { - field_tokens.extend( - quote_spanned! { field.span()=> Default::default(), }, - ); - } - } else { - sub_enums.extend( - quote_spanned! { field.span()=> vec.extend(<#ty as AllVariants>::all().map(Into::into)); }, - ); - - continue; - } - } - } - } - quote_spanned! {variant.span()=> (#field_tokens) } - } - Fields::Unit => quote_spanned! { variant.span()=> }, - _ => continue, - }; - - all_variants.extend(quote_spanned! {variant.span()=> - #name::#variant_name #fields, - }); - num += 1; - } - } else { - return derive_error!("AllVariants is only implemented for enums"); - } - - let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); - - let mut all_vec = TokenStream::new(); - - if flag { - all_vec.extend(quote! { - impl #impl_generics #name #ty_generics #where_clause { - pub fn all() -> Vec<#name> { - let mut vec = std::vec::Vec::from(<#name as cofd_util::AllVariants>::all()); - #sub_enums - vec - } - } - }); - } - - let expanded = quote! { - impl #impl_generics cofd_util::AllVariants for #name #ty_generics #where_clause { - type T = #name; - const N: usize = #num; - fn all() -> [Self::T; Self::N] { - [ - #all_variants - ] - } - } - #all_vec - }; - - proc_macro::TokenStream::from(expanded) -} - -#[proc_macro_derive(NameKey, attributes(expand))] -pub fn derive_name_key(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let input = parse_macro_input!(input as DeriveInput); - - let name = &input.ident; - let data = &input.data; - - let mut match_cases = TokenStream::new(); - - if let Data::Enum(data) = data { - for variant in &data.variants { - let variant_name = &variant.ident; - - match_cases.extend(quote_spanned! {variant.span()=> - #name::#variant_name(val) => val.name_key(), - }); - } - } - - let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); - - let expanded = quote! { - impl #impl_generics NameKey for #name #ty_generics #where_clause { - fn name_key(&self) -> String { - match self { - #match_cases - } - } - } - }; - - proc_macro::TokenStream::from(expanded) -} diff --git a/cofd/lib/Cargo.toml b/cofd/lib/Cargo.toml deleted file mode 100644 index 20a9bc9..0000000 --- a/cofd/lib/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "cofd" -version.workspace = true -authors.workspace = true -edition.workspace = true -license.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -serde = { version = "1", features = ["derive"] } -erased-serde = "0.3" -convert_case = "0.6" - -cofd-util.workspace = true -cofd-macros.workspace = true - -[dev-dependencies] -ron.workspace = true \ No newline at end of file diff --git a/cofd/lib/data/gifts.ron b/cofd/lib/data/gifts.ron deleted file mode 100644 index a82f168..0000000 --- a/cofd/lib/data/gifts.ron +++ /dev/null @@ -1 +0,0 @@ -[(name:"Crescent",type:"Moon",facets:[Moon(name:"ShadowGaze",level:1),Moon(name:"SpiritWhispers",level:2),Moon(name:"ShadowHunter",level:3),Moon(name:"ShadowMasquerade",level:4),Moon(name:"Panopticon",level:5)]),(name:"Full",type:"Moon",facets:[Moon(name:"KillerInstinct",level:1),Moon(name:"WarriorsHide",level:2),Moon(name:"BloodyHandedHunter",level:3),Moon(name:"Butchery",level:4),Moon(name:"CrimsonSpasm",level:5)]),(name:"Gibbous",type:"Moon",facets:[Moon(name:"WarHowl",level:1),Moon(name:"VoiceOfGlory",level:2),Moon(name:"DreamHunter",level:3),Moon(name:"ThousandThroatHowl",level:4),Moon(name:"EndOfStory",level:5)]),(name:"Half",type:"Moon",facets:[Moon(name:"ScentBeneathTheSurface",level:1),Moon(name:"BindingOath",level:2),Moon(name:"SlyHunter",level:3),Moon(name:"TiesOfWordAndPromise",level:4),Moon(name:"TiesOfBloodAndBone",level:5)]),(name:"New",type:"Moon",facets:[Moon(name:"Eviscerate",level:1),Moon(name:"SlipAway",level:2),Moon(name:"RelentlessHunter",level:3),Moon(name:"DivideAndConquer",level:4),Moon(name:"Breach",level:5)]),(name:"Agony",type:"Shadow",facets:[Other(name:"Wrack",renown:"Cunning"),Other(name:"Stocicism",renown:"Glory"),Other(name:"PainMirror",renown:"Honor"),Other(name:"Catharsis",renown:"Purity"),Other(name:"Scourge",renown:"Wisdom")]),(name:"Blood",type:"Shadow",facets:[Other(name:"Seep",renown:"Cunning"),Other(name:"Purge",renown:"Glory"),Other(name:"Bind",renown:"Honor"),Other(name:"Bleed",renown:"Purity"),Other(name:"Clot",renown:"Wisdom")]),(name:"Death",type:"Shadow",facets:[Other(name:"ColdEmbrace",renown:"Cunning"),Other(name:"Barghest",renown:"Glory"),Other(name:"MementoMori",renown:"Honor"),Other(name:"BoneGnaw",renown:"Purity"),Other(name:"EyesOfTheDead",renown:"Wisdom")]),(name:"Disease",type:"Shadow",facets:[Other(name:"FesteringBite",renown:"Cunning"),Other(name:"RancidMaw",renown:"Glory"),Other(name:"LepersBell",renown:"Honor"),Other(name:"RabidFever",renown:"Purity"),Other(name:"PoxCauldron",renown:"Wisdom")]),(name:"Dominance",type:"Shadow",facets:[Other(name:"PrimalAllure",renown:"Cunning"),Other(name:"GloriousLunacy",renown:"Glory"),Other(name:"LayLowTheChallenger",renown:"Honor"),Other(name:"SnarlOfThePredator",renown:"Purity"),Other(name:"LeadTheLesserPack",renown:"Wisdom")]),(name:"Elementals",type:"Shadow",facets:[Other(name:"BreathOfAir",renown:"Cunning"),Other(name:"Catastrophe",renown:"Glory"),Other(name:"FleshOfEarth",renown:"Honor"),Other(name:"TongueOfFlame",renown:"Purity"),Other(name:"HeartOfWater",renown:"Wisdom")]),(name:"Evasion",type:"Shadow",facets:[Other(name:"FeetOfMist",renown:"Cunning"),Other(name:"FogOfWar",renown:"Glory"),Other(name:"DenyEverything",renown:"Honor"),Other(name:"HitAndRun",renown:"Purity"),Other(name:"ExitStrategy",renown:"Wisdom")]),(name:"Fervor",type:"Shadow",facets:[Other(name:"CrisisOfFaith",renown:"Cunning"),Other(name:"Fanaticism",renown:"Glory"),Other(name:"Affirmation",renown:"Honor"),Other(name:"Zeal",renown:"Purity"),Other(name:"FervidMission",renown:"Wisdom")]),(name:"Hunger",type:"Shadow",facets:[Other(name:"EaterOfNames",renown:"Cunning"),Other(name:"FamineHowl",renown:"Glory"),Other(name:"Gluttony",renown:"Honor"),Other(name:"WolfHunger",renown:"Purity"),Other(name:"RavenousMaw",renown:"Wisdom")]),(name:"Insight",type:"Shadow",facets:[Other(name:"PreyOnWeakness",renown:"Cunning"),Other(name:"ReadTheWorldsLoom",renown:"Glory"),Other(name:"EchoDream",renown:"Honor"),Other(name:"ScentTheUnnatural",renown:"Purity"),Other(name:"OneStepAhead",renown:"Wisdom")]),(name:"Inspiration",type:"Shadow",facets:[Other(name:"LunaticInspiration",renown:"Cunning"),Other(name:"FearlessHunter",renown:"Glory"),Other(name:"PackTriumphsTogether",renown:"Honor"),Other(name:"Unity",renown:"Purity"),Other(name:"StillSmallVoice",renown:"Wisdom")]),(name:"Knowledge",type:"Shadow",facets:[Other(name:"Needle",renown:"Cunning"),Other(name:"ThisStoryIsTrue",renown:"Glory"),Other(name:"KnowThyPrey",renown:"Honor"),Other(name:"LoreOfTheLand",renown:"Purity"),Other(name:"SiftTheSands",renown:"Wisdom")]),(name:"Nature",type:"Shadow",facets:[Other(name:"NaturesLure",renown:"Cunning"),Other(name:"BlackEarthRedHunger",renown:"Glory"),Other(name:"KnottedPaths",renown:"Honor"),Other(name:"PackKin",renown:"Purity"),Other(name:"BeastRide",renown:"Wisdom")]),(name:"Rage",type:"Shadow",facets:[Other(name:"InciteFury",renown:"Cunning"),Other(name:"BerserkersMight",renown:"Glory"),Other(name:"PerfectedRage",renown:"Honor"),Other(name:"Slaughterer",renown:"Purity"),Other(name:"RagingLunacy",renown:"Wisdom")]),(name:"Shaping",type:"Shadow",facets:[Other(name:"Moldywarp",renown:"Cunning"),Other(name:"ShieldBreaker",renown:"Glory"),Other(name:"EntropysToll",renown:"Honor"),Other(name:"PerfectionOfForm",renown:"Purity"),Other(name:"Sculpt",renown:"Wisdom")]),(name:"Stealth",type:"Shadow",facets:[Other(name:"ShadowPelt",renown:"Cunning"),Other(name:"PredatorsShadow",renown:"Glory"),Other(name:"PackStalksThePrey",renown:"Honor"),Other(name:"TheHunterWaits",renown:"Purity"),Other(name:"RunningSilent",renown:"Wisdom")]),(name:"Strength",type:"Shadow",facets:[Other(name:"Unchained",renown:"Cunning"),Other(name:"PredatorsUnmatchedPursuit",renown:"Glory"),Other(name:"CrushingBlow",renown:"Honor"),Other(name:"PrimalStrength",renown:"Purity"),Other(name:"RendingClaws",renown:"Wisdom")]),(name:"Technology",type:"Shadow",facets:[Other(name:"Garble",renown:"Cunning"),Other(name:"Unmake",renown:"Glory"),Other(name:"CommandArtifice",renown:"Honor"),Other(name:"Shutdown",renown:"Purity"),Other(name:"IronSlave",renown:"Wisdom")]),(name:"Warding",type:"Shadow",facets:[Other(name:"MazeWard",renown:"Cunning"),Other(name:"WardTheWolfsDen",renown:"Glory"),Other(name:"AllDoorsLocked",renown:"Honor"),Other(name:"PredatorsClaim",renown:"Purity"),Other(name:"BoundaryWard",renown:"Wisdom")]),(name:"Weather",type:"Shadow",facets:[Other(name:"CloakOfMistAndHaze",renown:"Cunning"),Other(name:"HeavensUnleashed",renown:"Glory"),Other(name:"HuntUnderIronSkies",renown:"Honor"),Other(name:"GraspOfHowlingWinds",renown:"Purity"),Other(name:"HuntOfFireAndIce",renown:"Wisdom")]),(name:"Change",type:"Wolf",facets:[Other(name:"SkinThief",renown:"Cunning"),Other(name:"GazeOfTheMoon",renown:"Glory"),Other(name:"LunasEmbrace",renown:"Honor"),Other(name:"TheFathersForm",renown:"Purity"),Other(name:"QuicksilverFlesh",renown:"Wisdom")]),(name:"Hunting",type:"Wolf",facets:[Other(name:"HonedSenses",renown:"Cunning"),Other(name:"CowThePrey",renown:"Glory"),Other(name:"BeastTalker",renown:"Honor"),Other(name:"TirelessHunter",renown:"Purity"),Other(name:"ImpossibleSpoor",renown:"Wisdom")]),(name:"Pack",type:"Wolf",facets:[Other(name:"ReflectedFacets",renown:"Cunning"),Other(name:"DownThePrey",renown:"Glory"),Other(name:"TotemsWrath",renown:"Honor"),Other(name:"MawOfMadness",renown:"Purity"),Other(name:"PackAwareness",renown:"Wisdom")])] \ No newline at end of file diff --git a/cofd/lib/data/merits_universal.ron b/cofd/lib/data/merits_universal.ron deleted file mode 100644 index ed6690a..0000000 --- a/cofd/lib/data/merits_universal.ron +++ /dev/null @@ -1,691 +0,0 @@ -[ - ( - name: "AreaOfExpertise", - cost: Number(1), - requirements: Some("Resolve ••"), - type_: Mental, - ), - ( - name: "CommonSense", - cost: Number(3), - requirements: None, - type_: Mental, - ), - ( - name: "DangerSense", - cost: Number(2), - requirements: None, - type_: Mental, - ), - ( - name: "DirectionSense", - cost: Number(1), - requirements: None, - type_: Mental, - ), - ( - name: "EideticMemory", - cost: Number(2), - requirements: None, - type_: Mental, - ), - ( - name: "EncyclopedicKnowledge", - cost: Number(2), - requirements: None, - type_: Mental, - ), - ( - name: "EyeForTheStrange", - cost: Number(2), - requirements: Some("Resolve ••, Occult •"), - type_: Mental, - ), - ( - name: "FastReflexes", - cost: Range(2, 4), - requirements: Some("Wits or Dexterity •••"), - type_: Mental, - ), - ( - name: "GoodTimeManagement", - cost: Number(1), - requirements: Some("Academics or Science ••"), - type_: Mental, - ), - ( - name: "HolisticAwareness", - cost: Number(1), - requirements: None, - type_: Mental, - ), - ( - name: "HumanPrey", - cost: Number(2), - requirements: None, - type_: Mental, - ), - ( - name: "Hypervigilance", - cost: Number(1), - requirements: None, - type_: Mental, - ), - ( - name: "Indomitable", - cost: Number(2), - requirements: Some("Resolve •••"), - type_: Mental, - ), - ( - name: "InterdisciplinarySpecialty", - cost: Number(1), - requirements: Some("Any Skill •••"), - type_: Mental, - ), - ( - name: "InvestigativeAide", - cost: Number(1), - requirements: Some("Any Skill •••"), - type_: Mental, - ), - ( - name: "InvestigativeProdigy", - cost: Range(2, 6), - requirements: Some("Wits •••, Investigation •••"), - type_: Mental, - ), - ( - name: "Language", - cost: Number(1), - requirements: None, - type_: Mental, - ), - ( - name: "Library", - cost: Range(2, 4), - requirements: None, - type_: Mental, - ), - ( - name: "AdvancedLibrary", - cost: Range(2, 6), - requirements: Some("Library •••, ≤ Safe Place"), - type_: Mental, - ), - ( - name: "LucidDreamer", - cost: Number(2), - requirements: Some("Resolve •••"), - type_: Mental, - ), - ( - name: "MeditativeMind", - cost: Vec([ - 1, - 2, - 4, - ]), - requirements: None, - type_: Mental, - ), - ( - name: "Multilingual", - cost: Number(1), - requirements: None, - type_: Mental, - ), - ( - name: "ObjectFetishism", - cost: Range(2, 6), - requirements: None, - type_: Mental, - ), - ( - name: "Patient", - cost: Number(1), - requirements: None, - type_: Mental, - ), - ( - name: "RenownedArtisan", - cost: Number(3), - requirements: Some("Crafts ••• with specialty"), - type_: Mental, - ), - ( - name: "Scarred", - cost: Number(1), - requirements: Some("Integrity ≤ 5"), - type_: Mental, - ), - ( - name: "ToleranceForBiology", - cost: Number(1), - requirements: Some("Resolve •••"), - type_: Mental, - ), - ( - name: "TrainedObserver", - cost: Vec([ - 1, - 3, - ]), - requirements: Some("Wits or Composure •••"), - type_: Mental, - ), - ( - name: "ViceRidden", - cost: Number(2), - requirements: Some("Vice"), - type_: Mental, - ), - ( - name: "Virtuous", - cost: Number(2), - requirements: Some("Virtue"), - type_: Mental, - ), - ( - name: "EsotericArmory", - cost: Range(2, 6), - requirements: None, - type_: Supernatural, - ), - ( - name: "Relic", - cost: Range(2, 6), - requirements: None, - type_: Supernatural, - ), - ( - name: "Sandglass", - cost: Number(2), - requirements: None, - type_: Supernatural, - ), - ( - name: "Vestige", - cost: Range(2, 6), - requirements: None, - type_: Supernatural, - ), - ( - name: "ArmedRestraint", - cost: Number(2), - requirements: Some("Staff Fighting •••"), - type_: Fightning, - ), - ( - name: "BodyAsWeapon", - cost: Number(2), - requirements: Some("Stamina •••, Brawl ••"), - type_: Fightning, - ), - ( - name: "BootParty", - cost: Number(2), - requirements: Some("Brawl ••"), - type_: Fightning, - ), - ( - name: "CheapShot", - cost: Number(2), - requirements: Some("Street Fighting •••, Subterfuge ••"), - type_: Fightning, - ), - ( - name: "ChokeHold", - cost: Number(2), - requirements: Some("Brawl ••"), - type_: Fightning, - ), - ( - name: "ClinchStrike", - cost: Number(1), - requirements: Some("Brawl ••"), - type_: Fightning, - ), - ( - name: "DefensiveCombat", - cost: Number(1), - requirements: Some("Brawl • or Weaponry •"), - type_: Fightning, - ), - ( - name: "FightingFinesse", - cost: Number(2), - requirements: Some("Dexterity •••"), - type_: Fightning, - ), - ( - name: "GroundAndPound", - cost: Number(3), - requirements: Some("Brawl ••"), - type_: Fightning, - ), - ( - name: "GroundFighter", - cost: Number(3), - requirements: Some("Wits •••, Dexterity •••, Brawl ••"), - type_: Fightning, - ), - ( - name: "Gunslinger", - cost: Vec([ - 1, - 3, - 5, - ]), - requirements: Some("Wits •••, Firearms •••, Firearms(Revolvers) specialty"), - type_: Fightning, - ), - ( - name: "Headbutt", - cost: Number(1), - requirements: Some("Brawl ••"), - type_: Fightning, - ), - ( - name: "IronChin", - cost: Vec([ - 2, - 4, - ]), - requirements: Some("Resolve •••, Stamina •••"), - type_: Fightning, - ), - ( - name: "IronSkin", - cost: Vec([ - 2, - 4, - ]), - requirements: Some("Martial Arts or Street Fighting ••, Stamina •••"), - type_: Fightning, - ), - ( - name: "KillerInstinct", - cost: Range(2, 4), - requirements: Some("Composure •••, Wits •••, Medicine •"), - type_: Fightning, - ), - ( - name: "LoadedForBear", - cost: Range(2, 3), - requirements: Some("Athletics •, Survival •"), - type_: Fightning, - ), - ( - name: "PhalanxFighter", - cost: Number(2), - requirements: Some("Weapon and Shield ••, Spear and Bayonet •"), - type_: Fightning, - ), - ( - name: "RetainWeapon", - cost: Number(2), - requirements: Some("Wits ••, Brawl ••"), - type_: Fightning, - ), - ( - name: "Shiv", - cost: Vec([ - 1, - 2, - ]), - requirements: Some("Street Fighting ••, Weaponry •"), - type_: Fightning, - ), - ( - name: "SubduingStrikes", - cost: Number(1), - requirements: Some("Weaponry ••"), - type_: Fightning, - ), - ( - name: "TransferManeuver", - cost: Range(2, 4), - requirements: Some("Intelligence ••, Wits •••, Brawl ••, Weaponry ••"), - type_: Fightning, - ), - ( - name: "TriggerDiscipline", - cost: Number(1), - requirements: Some("Wits ••, Firearms ••"), - type_: Fightning, - ), - ( - name: "TrunkSqueeze", - cost: Number(2), - requirements: Some("Brawl ••"), - type_: Fightning, - ), - ( - name: "Ambidextrous", - cost: Number(3), - requirements: None, - type_: Physical, - ), - ( - name: "AutomotiveGenius", - cost: Number(1), - requirements: Some("Crafts •••, Drive •, Science •"), - type_: Physical, - ), - ( - name: "CovertOperative", - cost: Number(1), - requirements: Some("Wits •••, Dexterity •••, Stealth ••"), - type_: Physical, - ), - ( - name: "CrackDriver", - cost: Vec([ - 2, - 3, - ]), - requirements: Some("Drive •••"), - type_: Physical, - ), - ( - name: "Demolisher", - cost: Range(2, 4), - requirements: Some("Strength or Intelligence •••"), - type_: Physical, - ), - ( - name: "DoubleJointed", - cost: Number(2), - requirements: Some("Dexterity •••"), - type_: Physical, - ), - ( - name: "FleetOfFoot", - cost: Range(2, 4), - requirements: Some("Athletics ••"), - type_: Physical, - ), - ( - name: "Freediving", - cost: Number(1), - requirements: Some("Athletics ••"), - type_: Physical, - ), - ( - name: "Giant", - cost: Number(3), - requirements: None, - type_: Physical, - ), - ( - name: "Hardy", - cost: Range(2, 4), - requirements: Some("Stamina •••"), - type_: Physical, - ), - ( - name: "Greyhound", - cost: Number(1), - requirements: Some("Athletics •••, Wits •••, Stamina •••"), - type_: Physical, - ), - ( - name: "IronSkin", - cost: Range(2, 3), - requirements: Some("Brawl ••, Stamina •••"), - type_: Physical, - ), - ( - name: "IronStamina", - cost: Range(2, 4), - requirements: Some("Stamina or Resolve •••"), - type_: Physical, - ), - ( - name: "QuickDraw", - cost: Number(1), - requirements: Some("Wits •••"), - type_: Physical, - ), - ( - name: "PunchDrunk", - cost: Number(2), - requirements: Some("Willpower ••••••"), - type_: Physical, - ), - ( - name: "Relentless", - cost: Number(1), - requirements: Some("Athletics ••, Stamina •••"), - type_: Physical, - ), - ( - name: "Roadkill", - cost: Number(3), - requirements: Some("Aggressive Driving ••"), - type_: Physical, - ), - ( - name: "SeizingTheEdge", - cost: Number(2), - requirements: Some("Wits •••, Composure •••"), - type_: Physical, - ), - ( - name: "SleightOfHand", - cost: Number(2), - requirements: Some("Larceny •••"), - type_: Physical, - ), - ( - name: "SmallFramed", - cost: Number(2), - requirements: None, - type_: Physical, - ), - ( - name: "Survivalist", - cost: Number(1), - requirements: Some("Survival •••, Iron Stamina •••"), - type_: Physical, - ), - ( - name: "AirOfMenace", - cost: Number(2), - requirements: Some("Intimidation ••"), - type_: Social, - ), - ( - name: "Allies", - cost: Range(2, 6), - requirements: None, - type_: Social, - ), - ( - name: "AlternateIdentity", - cost: Range(2, 4), - requirements: None, - type_: Social, - ), - ( - name: "Anonymity", - cost: Range(2, 6), - requirements: Some("No Fame"), - type_: Social, - ), - ( - name: "Barfly", - cost: Number(2), - requirements: Some("Socialize ••"), - type_: Social, - ), - ( - name: "ClosedBook", - cost: Range(2, 6), - requirements: Some("Manipulation •••, Resolve •••"), - type_: Social, - ), - ( - name: "CohesiveUnit", - cost: Range(2, 4), - requirements: Some("Presence •••"), - type_: Social, - ), - ( - name: "Contacts", - cost: Range(2, 6), - requirements: None, - type_: Social, - ), - ( - name: "Defender", - cost: Range(2, 4), - requirements: None, - type_: Social, - ), - ( - name: "Empath", - cost: Number(2), - requirements: Some("Empathy ••"), - type_: Social, - ), - ( - name: "Fame", - cost: Range(2, 4), - requirements: Some("No Anonymity"), - type_: Social, - ), - ( - name: "Fixer", - cost: Number(2), - requirements: Some("Contacts ••, Wits •••"), - type_: Social, - ), - ( - name: "HobbyistClique", - cost: Number(2), - requirements: Some("Any Skill ••"), - type_: Social, - ), - ( - name: "Inspiring", - cost: Number(3), - requirements: Some("Presence •••"), - type_: Social, - ), - ( - name: "IronWill", - cost: Number(2), - requirements: Some("Resolve ••••"), - type_: Social, - ), - ( - name: "Mentor", - cost: Range(2, 6), - requirements: None, - type_: Social, - ), - ( - name: "Peacemaker", - cost: Range(3, 4), - requirements: Some("Wits •••, Empathy •••"), - type_: Social, - ), - ( - name: "Pusher", - cost: Number(1), - requirements: Some("Persuasion ••"), - type_: Social, - ), - ( - name: "Resources", - cost: Range(2, 6), - requirements: None, - type_: Social, - ), - ( - name: "Retainer", - cost: Range(2, 6), - requirements: None, - type_: Social, - ), - ( - name: "SafePlace", - cost: Range(2, 6), - requirements: None, - type_: Social, - ), - ( - name: "SmallUnitTactics", - cost: Number(2), - requirements: Some("Presence •••"), - type_: Social, - ), - ( - name: "SpinDoctor", - cost: Number(1), - requirements: Some("Manipulation •••, Subterfuge ••"), - type_: Social, - ), - ( - name: "Staff", - cost: Range(2, 6), - requirements: None, - type_: Social, - ), - ( - name: "Status", - cost: Range(2, 6), - requirements: None, - type_: Social, - ), - ( - name: "StrikingLooks", - cost: Range(2, 3), - requirements: None, - type_: Social, - ), - ( - name: "SupportNetwork", - cost: Range(2, 6), - requirements: Some("Appropriate Social Merit"), - type_: Social, - ), - ( - name: "Sympathetic", - cost: Number(2), - requirements: None, - type_: Social, - ), - ( - name: "TableTurner", - cost: Number(1), - requirements: Some("Composure •••, Manipulation •••, Wits •••"), - type_: Social, - ), - ( - name: "TakesOneToKnowOne", - cost: Number(1), - requirements: Some("Vice"), - type_: Social, - ), - ( - name: "Taste", - cost: Number(1), - requirements: Some("Crafts ••"), - type_: Social, - ), - ( - name: "TrueFriend", - cost: Number(3), - requirements: None, - type_: Social, - ), - ( - name: "Untouchable", - cost: Number(1), - requirements: Some("Manipulation •••, Subterfuge ••"), - type_: Social, - ), -] \ No newline at end of file diff --git a/cofd/lib/src/character/mod.rs b/cofd/lib/src/character/mod.rs deleted file mode 100644 index bb46d47..0000000 --- a/cofd/lib/src/character/mod.rs +++ /dev/null @@ -1,1018 +0,0 @@ -use serde::{Deserialize, Serialize}; -use std::{ - cmp::{max, min}, - collections::HashMap, - ops::{Add, Index, Sub}, -}; - -use crate::splat::{ability::Ability, Merit, Splat}; -use crate::{dice_pool::DicePool, prelude::VariantName}; - -pub mod modifier; -pub mod traits; - -use modifier::*; -use traits::*; - -#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)] -pub fn add(a: u16, b: i16) -> u16 { - let res = i32::from(a) + i32::from(b); - - if res >= 255 { - u16::MAX - } else if res <= 0 { - u16::MIN - } else { - res as u16 - } -} - -#[derive(Default)] -pub struct CharacterBuilder { - splat: Splat, - info: CharacterInfo, - attributes: Attributes, - skills: Skills, - specialties: HashMap>, - merits: Vec<(Merit, u16)>, - - abilities: HashMap, - power: u16, - fuel: Option, - - flag: bool, -} - -impl CharacterBuilder { - #[must_use] - pub fn with_splat(mut self, splat: Splat) -> Self { - self.splat = splat; - self - } - - #[must_use] - pub fn with_info(mut self, info: CharacterInfo) -> Self { - self.info = info; - self - } - - #[must_use] - pub fn with_attributes(mut self, attributes: Attributes) -> Self { - self.attributes = attributes; - self - } - - #[must_use] - pub fn with_skills(mut self, skills: Skills) -> Self { - self.skills = skills; - self - } - - #[must_use] - pub fn with_specialties(mut self, skill: Skill, specialties: Vec) -> Self { - self.specialties.insert(skill, specialties); - self - } - - #[must_use] - pub fn with_abilities(mut self, abilities: [(Ability, u16); N]) -> Self { - self.abilities = HashMap::from(abilities); - - self.flag = true; - self - } - - #[must_use] - pub fn with_merits(mut self, merits: [(Merit, u16); N]) -> Self { - self.merits = Vec::from(merits); - self.flag = true; - self - } - - #[must_use] - pub fn with_st(mut self, st: u16) -> Self { - self.power = st; - self - } - - #[must_use] - pub fn with_fuel(mut self, fuel: u16) -> Self { - self.fuel = Some(fuel); - self - } - - #[must_use] - pub fn build(self) -> Character { - let power = if let Splat::Mortal = &self.splat { - 0 - } else if self.power > 0 { - self.power - } else { - 1 - }; - - let mut character = Character { - splat: self.splat, - info: self.info, - power, - _attributes: self.attributes, - skills: self.skills, - abilities: self.abilities, - merits: self.merits, - specialties: self.specialties, - ..Default::default() - }; - - if self.flag { - character.calc_mod_map(); - } - - character.fuel = self.fuel.unwrap_or_else(|| character.max_fuel()); - character.willpower = character.max_willpower(); - - if let Splat::Werewolf(Some(auspice), .., data) = &mut character.splat { - data.hunters_aspect = Some(auspice.get_hunters_aspect().clone()); - } - - character - } -} - -#[derive(Default, Debug, Clone)] -pub enum Wound { - #[default] - None, - Bashing, - Lethal, - Aggravated, -} - -impl Wound { - #[must_use] - pub fn inc(&self) -> Wound { - match self { - Wound::None => Wound::Bashing, - Wound::Bashing => Wound::Lethal, - Wound::Lethal => Wound::Aggravated, - Wound::Aggravated => Wound::Aggravated, - } - } - - #[must_use] - pub fn poke(&self) -> Wound { - if let Wound::Aggravated = self { - Wound::None - } else { - self.inc() - } - } - - pub fn poke_mut(&mut self) { - *self = self.poke(); - } -} - -#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -#[serde(default)] -pub struct Damage { - #[serde(skip_serializing_if = "is_zero")] - aggravated: u16, - #[serde(skip_serializing_if = "is_zero")] - lethal: u16, - #[serde(skip_serializing_if = "is_zero")] - bashing: u16, -} - -impl Damage { - pub fn new(bashing: u16, lethal: u16, aggravated: u16) -> Self { - Self { - aggravated, - lethal, - bashing, - } - } - - pub fn get(&self, wound: &Wound) -> u16 { - match wound { - Wound::None => 0, - Wound::Bashing => self.bashing, - Wound::Lethal => self.lethal, - Wound::Aggravated => self.aggravated, - } - } - - pub fn get_i(&self, i: usize) -> Wound { - // println!("{i}"); - if i < self.aggravated as usize { - Wound::Aggravated - } else if i >= self.aggravated as usize && i < (self.aggravated + self.lethal) as usize { - Wound::Lethal - } else if i >= (self.aggravated + self.lethal) as usize - && i < (self.aggravated + self.lethal + self.bashing) as usize - { - Wound::Bashing - } else { - Wound::None - } - } - - pub fn sum(&self) -> u16 { - self.bashing + self.lethal + self.aggravated - } - - pub fn dec(&mut self, wound: &Wound) { - match wound { - Wound::None => {} - Wound::Bashing => { - if self.bashing > 0 { - self.bashing -= 1; - } - } - Wound::Lethal => { - if self.lethal > 0 { - self.lethal -= 1; - } - } - Wound::Aggravated => { - if self.aggravated > 0 { - self.aggravated -= 1; - } - } - } - } - - pub fn inc(&mut self, wound: &Wound) { - match wound { - Wound::None => {} - Wound::Bashing => self.bashing += 1, - Wound::Lethal => self.lethal += 1, - Wound::Aggravated => self.aggravated += 1, - } - } - - pub fn poke(&mut self, wound: &Wound) { - match wound { - Wound::None => self.bashing += 1, - Wound::Bashing => { - if self.bashing > 0 { - self.bashing -= 1; - } - self.lethal += 1; - } - Wound::Lethal => { - if self.lethal > 0 { - self.lethal -= 1; - } - self.aggravated += 1; - } - Wound::Aggravated => { - if self.aggravated > 0 { - self.aggravated -= 1; - } - } - } - } -} - -pub fn defense_pool() -> DicePool { - DicePool::min(Attribute::Wits, Attribute::Dexterity) + Skill::Athletics -} - -pub fn is_empty_vec(vec: &Vec) -> bool { - vec.is_empty() -} - -#[allow(clippy::trivially_copy_pass_by_ref)] -pub fn is_five(n: &u16) -> bool { - *n == 5 -} - -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(default)] -pub struct Character { - pub splat: Splat, - - pub info: CharacterInfo, - - #[serde(rename = "attributes")] - _attributes: Attributes, - skills: Skills, - pub specialties: HashMap>, - - health: Damage, - - pub willpower: u16, - pub power: u16, - pub fuel: u16, - pub integrity: u16, - - #[serde(skip_serializing_if = "is_empty_vec")] - pub touchstones: Vec, - - // #[serde(skip)] - pub abilities: HashMap, - // #[serde(skip)] - pub merits: Vec<(Merit, u16)>, - - pub weapons: Vec, - - #[serde(skip_serializing_if = "is_five")] - pub base_size: u16, - base_armor: ArmorStruct, - pub beats: u16, - #[serde(skip_serializing_if = "is_zero")] - pub alternate_beats: u16, - - pub conditions: Vec, - pub aspirations: Vec, - - #[serde(skip)] - modifiers: Modifiers, -} - -impl Character { - pub fn builder() -> CharacterBuilder { - CharacterBuilder::default() - } - - pub fn add_ability(&mut self, ability: Ability, val: u16) { - self.abilities.insert(ability, val); - } - - pub fn has_ability(&self, key: &Ability) -> bool { - self.abilities.contains_key(key) - } - - pub fn remove_ability(&mut self, key: &Ability) -> Option { - self.abilities.remove(key) - } - - pub fn get_ability_value(&self, key: &Ability) -> Option<&u16> { - self.abilities.get(key) - } - - pub fn get_ability_value_mut(&mut self, key: &Ability) -> Option<&mut u16> { - self.abilities.get_mut(key) - } - - pub fn add_merit(&mut self, key: Merit) { - self.merits.push((key, 0)); - } - - pub fn remove_merit(&mut self, i: usize) -> (Merit, u16) { - self.merits.remove(i) - } - - pub fn get_merit(&self, i: usize) -> Option<&(Merit, u16)> { - self.merits.get(i) - } - - pub fn get_merit_mut(&mut self, i: usize) -> Option<&mut (Merit, u16)> { - self.merits.get_mut(i) - } - - pub fn get_trait(&self, trait_: &Trait) -> u16 { - match trait_ { - Trait::Speed => self.speed(), - Trait::Defense => self.defense(), - Trait::Initative => self.initative(), - Trait::Perception => self.perception(), - Trait::Health => self.max_health(), - Trait::Size => self.size(), - Trait::Beats => self.beats, - Trait::Armor(Some(armor)) => match armor { - Armor::General => self.armor().general, - Armor::Ballistic => self.armor().ballistic, - }, - Trait::Willpower => self.max_willpower(), - Trait::Power => self.power, - Trait::Fuel => self.fuel, - Trait::Integrity => self.integrity, - _ => 0, - } - } - - #[allow(clippy::too_many_lines)] - pub fn calc_mod_map(&self) { - self.modifiers.update(self); - } - - pub fn get_modifier(&self, target: impl Into) -> i16 { - self.modifiers.get_modifier(self, target) - } - - pub fn get_conditional_modifier( - &self, - target: impl Into, - condition: impl Into, - ) -> Option { - self.modifiers - .get_conditional_modifier(self, target, condition) - } - - pub fn get_pool(&self, target: impl Into) -> Option { - self.modifiers.get_pool(self, target) - } - - pub fn get_conditional_pool( - &self, - target: impl Into, - condition: impl Into, - ) -> Option { - self.modifiers.get_conditional_pool(target, condition) - } - - pub fn attributes(&self) -> Attributes { - Attributes { - intelligence: self._modified(Attribute::Intelligence), - wits: self._modified(Attribute::Wits), - resolve: self._modified(Attribute::Resolve), - strength: self._modified(Attribute::Strength), - dexterity: self._modified(Attribute::Dexterity), - stamina: self._modified(Attribute::Stamina), - presence: self._modified(Attribute::Presence), - manipulation: self._modified(Attribute::Manipulation), - composure: self._modified(Attribute::Composure), - } - } - pub fn base_attributes_mut(&mut self) -> &mut Attributes { - &mut self._attributes - } - pub fn base_attributes(&self) -> &Attributes { - &self._attributes - } - - pub fn _modified(&self, target: impl Into) -> u16 { - let target = &target.into(); - let base = match &target { - ModifierTarget::BaseAttribute(attr) | ModifierTarget::Attribute(attr) => { - *self._attributes.get(attr) - } - ModifierTarget::BaseSkill(skill) | ModifierTarget::Skill(skill) => { - self.skills.get(*skill) - } - _ => 0, - }; - - let modifier = match &target { - ModifierTarget::BaseAttribute(_) => 0, - ModifierTarget::BaseSkill(_) => 0, - _ => self.modifiers.get_modifier(self, target.clone()), - }; - let base_modifier = self.modifiers.get_modifier( - self, - match *target { - ModifierTarget::Attribute(attr) => ModifierTarget::BaseAttribute(attr), - ModifierTarget::Skill(skill) => ModifierTarget::BaseSkill(skill), - _ => target.clone(), - }, - ); - - if add(base, base_modifier) > 5 { - add(base, modifier) - } else { - add(base, base_modifier + modifier) - } - } - - pub fn skills(&self) -> Skills { - Skills { - academics: self._modified(Skill::Academics), - computer: self._modified(Skill::Computer), - crafts: self._modified(Skill::Crafts), - investigation: self._modified(Skill::Investigation), - medicine: self._modified(Skill::Medicine), - occult: self._modified(Skill::Occult), - politics: self._modified(Skill::Politics), - science: self._modified(Skill::Science), - - athletics: self._modified(Skill::Athletics), - brawl: self._modified(Skill::Brawl), - drive: self._modified(Skill::Drive), - firearms: self._modified(Skill::Firearms), - larceny: self._modified(Skill::Larceny), - stealth: self._modified(Skill::Stealth), - survival: self._modified(Skill::Survival), - weaponry: self._modified(Skill::Weaponry), - - animal_ken: self._modified(Skill::AnimalKen), - empathy: self._modified(Skill::Empathy), - expression: self._modified(Skill::Expression), - intimidation: self._modified(Skill::Intimidation), - persuasion: self._modified(Skill::Persuasion), - socialize: self._modified(Skill::Socialize), - streetwise: self._modified(Skill::Streetwise), - subterfuge: self._modified(Skill::Subterfuge), - } - } - pub fn base_skills(&self) -> &Skills { - &self.skills - } - pub fn base_skills_mut(&mut self) -> &mut Skills { - &mut self.skills - } - - pub fn max_health(&self) -> u16 { - let attributes = self.attributes(); - - add( - self.size() + attributes.stamina, - self.modifiers.get_modifier(self, Trait::Health), - ) - } - - pub fn health(&self) -> &Damage { - &self.health - } - - pub fn health_mut(&mut self) -> &mut Damage { - &mut self.health - } - - pub fn wound_penalty(&self) -> u16 { - let mh = self.max_health(); - match mh - min(self.health.sum(), mh) { - 2 => 1, - 1 => 2, - 0 => 3, - _ => 0, - } - } - - pub fn max_willpower(&self) -> u16 { - let attributes = self.attributes(); - - attributes.resolve + attributes.composure - } - - pub fn size(&self) -> u16 { - add( - self.base_size, - self.modifiers.get_modifier(self, Trait::Size), - ) - } - pub fn speed(&self) -> u16 { - let attributes = self.attributes(); - - add( - 5 + attributes.dexterity + attributes.strength, - self.modifiers.get_modifier(self, Trait::Speed), - ) - } - pub fn defense(&self) -> u16 { - max::(0, self.get_pool(Trait::Defense).unwrap().value(self)) as u16 - } - pub fn armor(&self) -> ArmorStruct { - ArmorStruct { - general: self.base_armor.general, - ballistic: self.base_armor.ballistic, - } - } - pub fn base_armor_mut(&mut self) -> &mut ArmorStruct { - &mut self.base_armor - } - pub fn initative(&self) -> u16 { - let attributes = self.attributes(); - - add( - attributes.dexterity + attributes.composure, - self.modifiers.get_modifier(self, Trait::Initative), - ) - } - pub fn perception(&self) -> u16 { - let attributes = self.attributes(); - - add( - attributes.wits + attributes.composure, - self.modifiers.get_modifier(self, Trait::Perception), - ) - } - pub fn experience(&self) -> u16 { - self.beats / 5 - } - pub fn alternate_experience(&self) -> u16 { - self.alternate_beats / 5 - } - - pub fn max_fuel(&self) -> u16 { - match self.power { - 0 => self.attributes().stamina, - 1..=4 => 10 + self.power - 1, - 5..=8 => 10 + (self.power - 4) * 5, - 9 => 50, - 10 => 75, - _ => 0, - } - } -} - -impl Default for Character { - fn default() -> Self { - Self { - splat: Default::default(), - info: Default::default(), - _attributes: Default::default(), - skills: Default::default(), - base_size: 5, - abilities: Default::default(), - merits: Default::default(), - health: Default::default(), - - modifiers: Default::default(), - - power: Default::default(), - integrity: 7, - fuel: Default::default(), - willpower: Default::default(), - beats: Default::default(), - alternate_beats: Default::default(), - base_armor: Default::default(), - specialties: Default::default(), - touchstones: Default::default(), - conditions: Default::default(), - aspirations: Default::default(), - weapons: Default::default(), - } - } -} - -fn is_empty(str: &String) -> bool { - str.is_empty() -} - -#[derive(Clone, Default, Serialize, Deserialize, Debug, PartialEq, Eq)] -#[serde(default)] -pub struct CharacterInfo { - #[serde(skip_serializing_if = "is_empty")] - pub name: String, - #[serde(skip_serializing_if = "is_empty")] - pub player: String, - - #[serde(skip_serializing_if = "is_empty")] - pub virtue_anchor: String, - #[serde(skip_serializing_if = "is_empty")] - pub vice_anchor: String, - - #[serde(skip_serializing_if = "is_empty")] - pub faction: String, - #[serde(skip_serializing_if = "is_empty")] - pub group_name: String, - - #[serde(skip_serializing_if = "is_empty")] - pub concept: String, - #[serde(skip_serializing_if = "is_empty")] - pub chronicle: String, - - #[serde(skip_serializing_if = "is_empty")] - pub age: String, - #[serde(skip_serializing_if = "is_empty")] - pub date_of_birth: String, - #[serde(skip_serializing_if = "is_empty")] - pub hair: String, - #[serde(skip_serializing_if = "is_empty")] - pub eyes: String, - #[serde(skip_serializing_if = "is_empty")] - pub race: String, - #[serde(skip_serializing_if = "is_empty")] - pub nationality: String, - #[serde(skip_serializing_if = "is_empty")] - pub height: String, - #[serde(skip_serializing_if = "is_empty")] - pub weight: String, - #[serde(skip_serializing_if = "is_empty")] - pub sex: String, - - #[serde(skip_serializing_if = "is_empty")] - pub other: String, -} - -#[derive(Debug, Clone, Copy, VariantName)] -pub enum InfoTrait { - Name, - Age, - Player, - VirtueAnchor, - ViceAnchor, - Concept, - Chronicle, - - Faction, - GroupName, - - DateOfBirth, - Hair, - Eyes, - Race, - Nationality, - Height, - Weight, - Sex, -} - -impl CharacterInfo { - pub fn get(&self, info: InfoTrait) -> &String { - match info { - InfoTrait::Name => &self.name, - InfoTrait::Age => &self.age, - InfoTrait::Player => &self.player, - InfoTrait::Concept => &self.concept, - InfoTrait::Chronicle => &self.chronicle, - InfoTrait::DateOfBirth => &self.date_of_birth, - InfoTrait::Hair => &self.hair, - InfoTrait::Eyes => &self.eyes, - InfoTrait::Race => &self.race, - InfoTrait::Nationality => &self.nationality, - InfoTrait::Height => &self.height, - InfoTrait::Weight => &self.weight, - InfoTrait::Sex => &self.sex, - InfoTrait::VirtueAnchor => &self.virtue_anchor, - InfoTrait::ViceAnchor => &self.vice_anchor, - InfoTrait::Faction => &self.faction, - InfoTrait::GroupName => &self.group_name, - } - } - - pub fn get_mut(&mut self, info: InfoTrait) -> &mut String { - match info { - InfoTrait::Name => &mut self.name, - InfoTrait::Age => &mut self.age, - InfoTrait::Player => &mut self.player, - InfoTrait::Concept => &mut self.concept, - InfoTrait::Chronicle => &mut self.chronicle, - InfoTrait::DateOfBirth => &mut self.date_of_birth, - InfoTrait::Hair => &mut self.hair, - InfoTrait::Eyes => &mut self.eyes, - InfoTrait::Race => &mut self.race, - InfoTrait::Nationality => &mut self.nationality, - InfoTrait::Height => &mut self.height, - InfoTrait::Weight => &mut self.weight, - InfoTrait::Sex => &mut self.sex, - InfoTrait::VirtueAnchor => &mut self.virtue_anchor, - InfoTrait::ViceAnchor => &mut self.vice_anchor, - InfoTrait::Faction => &mut self.faction, - InfoTrait::GroupName => &mut self.group_name, - } - } -} - -#[allow(clippy::trivially_copy_pass_by_ref)] -fn is_one(num: &u16) -> bool { - num.eq(&1) -} - -#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)] -#[serde(default)] -pub struct Attributes { - #[serde(skip_serializing_if = "is_one")] - pub intelligence: u16, - #[serde(skip_serializing_if = "is_one")] - pub wits: u16, - #[serde(skip_serializing_if = "is_one")] - pub resolve: u16, - - #[serde(skip_serializing_if = "is_one")] - pub strength: u16, - #[serde(skip_serializing_if = "is_one")] - pub dexterity: u16, - #[serde(skip_serializing_if = "is_one")] - pub stamina: u16, - - #[serde(skip_serializing_if = "is_one")] - pub presence: u16, - #[serde(skip_serializing_if = "is_one")] - pub manipulation: u16, - #[serde(skip_serializing_if = "is_one")] - pub composure: u16, -} - -impl Attributes { - pub fn get(&self, attr: &Attribute) -> &u16 { - match attr { - Attribute::Intelligence => &self.intelligence, - Attribute::Wits => &self.wits, - Attribute::Resolve => &self.resolve, - // - Attribute::Strength => &self.strength, - Attribute::Dexterity => &self.dexterity, - Attribute::Stamina => &self.stamina, - // - Attribute::Presence => &self.presence, - Attribute::Manipulation => &self.manipulation, - Attribute::Composure => &self.composure, - } - } - - pub fn get_mut(&mut self, attr: &Attribute) -> &mut u16 { - match attr { - Attribute::Intelligence => &mut self.intelligence, - Attribute::Wits => &mut self.wits, - Attribute::Resolve => &mut self.resolve, - // - Attribute::Strength => &mut self.strength, - Attribute::Dexterity => &mut self.dexterity, - Attribute::Stamina => &mut self.stamina, - // - Attribute::Presence => &mut self.presence, - Attribute::Manipulation => &mut self.manipulation, - Attribute::Composure => &mut self.composure, - } - } -} - -impl Default for Attributes { - fn default() -> Self { - Self { - intelligence: 1, - wits: 1, - resolve: 1, - strength: 1, - dexterity: 1, - stamina: 1, - presence: 1, - manipulation: 1, - composure: 1, - } - } -} - -impl Sub for Attributes { - type Output = Self; - - fn sub(self, rhs: Attributes) -> Self::Output { - Self { - intelligence: self.intelligence - rhs.intelligence, - wits: self.wits - rhs.wits, - resolve: self.resolve - rhs.resolve, - strength: self.strength - rhs.strength, - dexterity: self.dexterity - rhs.dexterity, - stamina: self.stamina - rhs.stamina, - presence: self.presence - rhs.presence, - manipulation: self.manipulation - rhs.manipulation, - composure: self.composure - rhs.composure, - } - } -} - -impl Add for Attributes { - type Output = Self; - - fn add(self, rhs: Self) -> Self::Output { - Self { - intelligence: self.intelligence + rhs.intelligence, - wits: self.wits + rhs.wits, - resolve: self.resolve + rhs.resolve, - strength: self.strength + rhs.strength, - dexterity: self.dexterity + rhs.dexterity, - stamina: self.stamina + rhs.stamina, - presence: self.presence + rhs.presence, - manipulation: self.manipulation + rhs.manipulation, - composure: self.composure + rhs.composure, - } - } -} - -#[allow(clippy::trivially_copy_pass_by_ref)] -fn is_zero(n: &u16) -> bool { - *n == 0 -} - -#[derive(Clone, Default, Serialize, Deserialize, Debug, PartialEq, Eq)] -#[serde(default)] -pub struct Skills { - #[serde(skip_serializing_if = "is_zero")] - pub academics: u16, - #[serde(skip_serializing_if = "is_zero")] - pub computer: u16, - #[serde(skip_serializing_if = "is_zero")] - pub crafts: u16, - #[serde(skip_serializing_if = "is_zero")] - pub investigation: u16, - #[serde(skip_serializing_if = "is_zero")] - pub medicine: u16, - #[serde(skip_serializing_if = "is_zero")] - pub occult: u16, - #[serde(skip_serializing_if = "is_zero")] - pub politics: u16, - #[serde(skip_serializing_if = "is_zero")] - pub science: u16, - - #[serde(skip_serializing_if = "is_zero")] - pub athletics: u16, - #[serde(skip_serializing_if = "is_zero")] - pub brawl: u16, - #[serde(skip_serializing_if = "is_zero")] - pub drive: u16, - #[serde(skip_serializing_if = "is_zero")] - pub firearms: u16, - #[serde(skip_serializing_if = "is_zero")] - pub larceny: u16, - #[serde(skip_serializing_if = "is_zero")] - pub stealth: u16, - #[serde(skip_serializing_if = "is_zero")] - pub survival: u16, - #[serde(skip_serializing_if = "is_zero")] - pub weaponry: u16, - - #[serde(skip_serializing_if = "is_zero")] - pub animal_ken: u16, - #[serde(skip_serializing_if = "is_zero")] - pub empathy: u16, - #[serde(skip_serializing_if = "is_zero")] - pub expression: u16, - #[serde(skip_serializing_if = "is_zero")] - pub intimidation: u16, - #[serde(skip_serializing_if = "is_zero")] - pub persuasion: u16, - #[serde(skip_serializing_if = "is_zero")] - pub socialize: u16, - #[serde(skip_serializing_if = "is_zero")] - pub streetwise: u16, - #[serde(skip_serializing_if = "is_zero")] - pub subterfuge: u16, -} - -impl Skills { - pub fn get(&self, skill: Skill) -> u16 { - match skill { - Skill::Academics => self.academics, - Skill::Computer => self.computer, - Skill::Crafts => self.crafts, - Skill::Investigation => self.investigation, - Skill::Medicine => self.medicine, - Skill::Occult => self.occult, - Skill::Politics => self.politics, - Skill::Science => self.science, - // - Skill::Athletics => self.athletics, - Skill::Brawl => self.brawl, - Skill::Drive => self.drive, - Skill::Firearms => self.firearms, - Skill::Larceny => self.larceny, - Skill::Stealth => self.stealth, - Skill::Survival => self.survival, - Skill::Weaponry => self.weaponry, - // - Skill::AnimalKen => self.animal_ken, - Skill::Empathy => self.empathy, - Skill::Expression => self.expression, - Skill::Intimidation => self.intimidation, - Skill::Persuasion => self.persuasion, - Skill::Socialize => self.socialize, - Skill::Streetwise => self.streetwise, - Skill::Subterfuge => self.subterfuge, - } - } - - pub fn get_mut(&mut self, skill: Skill) -> &mut u16 { - match skill { - Skill::Academics => &mut self.academics, - Skill::Computer => &mut self.computer, - Skill::Crafts => &mut self.crafts, - Skill::Investigation => &mut self.investigation, - Skill::Medicine => &mut self.medicine, - Skill::Occult => &mut self.occult, - Skill::Politics => &mut self.politics, - Skill::Science => &mut self.science, - // - Skill::Athletics => &mut self.athletics, - Skill::Brawl => &mut self.brawl, - Skill::Drive => &mut self.drive, - Skill::Firearms => &mut self.firearms, - Skill::Larceny => &mut self.larceny, - Skill::Stealth => &mut self.stealth, - Skill::Survival => &mut self.survival, - Skill::Weaponry => &mut self.weaponry, - // - Skill::AnimalKen => &mut self.animal_ken, - Skill::Empathy => &mut self.empathy, - Skill::Expression => &mut self.expression, - Skill::Intimidation => &mut self.intimidation, - Skill::Persuasion => &mut self.persuasion, - Skill::Socialize => &mut self.socialize, - Skill::Streetwise => &mut self.streetwise, - Skill::Subterfuge => &mut self.subterfuge, - } - } -} - -#[derive(Clone, Default, Debug, Serialize, Deserialize)] -pub struct ArmorStruct { - pub general: u16, - pub ballistic: u16, -} - -#[derive(Clone, Copy, Hash, Debug, Serialize, Deserialize, PartialEq, Eq)] -pub enum Armor { - General, - Ballistic, -} - -#[derive(Debug, Default, Clone, Serialize, Deserialize, Eq, PartialEq)] -pub struct Weapon { - pub name: String, - pub dice_pool: String, - pub damage: String, - pub range: String, - pub initative: i16, - pub size: u16, -} diff --git a/cofd/lib/src/character/modifier.rs b/cofd/lib/src/character/modifier.rs deleted file mode 100644 index 71ea785..0000000 --- a/cofd/lib/src/character/modifier.rs +++ /dev/null @@ -1,450 +0,0 @@ -use std::{ - collections::HashMap, - sync::{Arc, RwLock}, -}; - -use serde::{Deserialize, Serialize}; - -use super::{traits::*, Character}; -use crate::{ - dice_pool::DicePool, - splat::{ability::Ability, werewolf::Form, Splat}, -}; - -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct Modifier { - pub target: ModifierTarget, - pub value: ModifierValue, - pub op: ModifierOp, - pub condition: Option, -} - -impl Modifier { - pub fn new( - target: impl Into, - value: impl Into, - op: ModifierOp, - ) -> Self { - Self { - target: target.into(), - value: value.into(), - op, - condition: None, - } - } - - pub fn conditional( - target: impl Into, - value: impl Into, - op: ModifierOp, - condition: impl Into, - ) -> Self { - Self { - target: target.into(), - value: value.into(), - op, - condition: Some(condition.into()), - } - } - - pub fn val(&self) -> Option { - match self.value { - ModifierValue::Num(val) => Some(val), - ModifierValue::Skill(_) | ModifierValue::Ability(_) => None, - ModifierValue::DicePool(_) => unreachable!(), - } - } -} - -#[derive(PartialEq, Eq, Hash, Clone, Debug, Serialize, Deserialize)] -pub enum ModifierTarget { - BaseAttribute(Attribute), - BaseSkill(Skill), - Attribute(Attribute), - Skill(Skill), - Trait(Trait), -} - -impl From for ModifierTarget { - fn from(attr: Attribute) -> Self { - ModifierTarget::Attribute(attr) - } -} - -impl From for ModifierTarget { - fn from(value: Skill) -> Self { - ModifierTarget::Skill(value) - } -} - -impl From for ModifierTarget { - fn from(value: Trait) -> Self { - ModifierTarget::Trait(value) - } -} - -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum ModifierValue { - Num(i16), - Ability(Ability), - Skill(Skill), - DicePool(DicePool), -} - -impl ModifierValue { - pub fn value(&self, character: &Character) -> i16 { - match self { - ModifierValue::Num(value) => *value, - ModifierValue::Ability(ability) => { - *character.get_ability_value(ability).unwrap_or(&0) as i16 - } - ModifierValue::Skill(skill) => character.skills.get(*skill) as i16, - ModifierValue::DicePool(pool) => pool.value(character), - } - } -} - -impl From for ModifierValue { - fn from(value: i16) -> Self { - ModifierValue::Num(value) - } -} - -impl From for ModifierValue { - fn from(value: u16) -> Self { - ModifierValue::Num(value as i16) - } -} - -impl From for ModifierValue { - fn from(value: i32) -> Self { - ModifierValue::Num(value as i16) - } -} - -impl From for ModifierValue { - fn from(value: Ability) -> Self { - ModifierValue::Ability(value) - } -} - -impl From for ModifierValue { - fn from(value: Skill) -> Self { - ModifierValue::Skill(value) - } -} - -impl From for ModifierValue { - fn from(value: DicePool) -> Self { - ModifierValue::DicePool(value) - } -} - -#[derive(Clone, Debug, PartialEq, Eq, VariantName)] -pub enum ModifierOp { - Add, - Set, -} - -#[derive(Clone, Hash, Debug, PartialEq, Eq)] -pub enum Condition { - WerewolfForm(Form), -} - -impl Condition { - pub fn check(&self, character: &Character) -> bool { - match self { - Self::WerewolfForm(form) => { - if let Splat::Werewolf(.., data) = &character.splat { - form.eq(&data.form) - } else { - false - } - } - } - } -} - -impl From
for Condition { - fn from(value: Form) -> Self { - Condition::WerewolfForm(value) - } -} - -type ModMap = HashMap>; -type CondModMap = HashMap>>; - -#[derive(Debug, Default, Clone)] -pub struct Modifiers { - modifier_map: Arc>, - conditional_modifier_map: Arc>, -} - -fn push_or_init(map: &mut HashMap>, key: K, value: V) -where - K: Eq + std::hash::Hash, -{ - let vec = map.get_mut(&key); - - if let Some(vec) = vec { - vec.push(value); - } else { - map.insert(key, vec![value]); - } -} - -fn handle_modifier( - modifier: Modifier, - modifier_map: &mut ModMap, - conditional_modifier_map: &mut CondModMap, -) { - if let Some(condition) = modifier.condition { - let target_map = conditional_modifier_map.get_mut(&modifier.target); - - if let Some(target_map) = target_map { - push_or_init(target_map, condition, modifier.value); - } else { - conditional_modifier_map.insert( - modifier.target, - HashMap::from([(condition, vec![modifier.value])]), - ); - } - } else { - push_or_init(modifier_map, modifier.target, modifier.value); - } -} - -impl Modifiers { - #[allow(clippy::too_many_lines)] - pub fn update(&self, character: &Character) { - let mut conditional_modifier_map = self.conditional_modifier_map.write().unwrap(); - let mut modifier_map = self.modifier_map.write().unwrap(); - - modifier_map.clear(); - conditional_modifier_map.clear(); - - let mut modifiers: Vec = Vec::new(); - - modifiers.extend( - character - .abilities - .iter() - .flat_map(|(ability, val)| ability.get_modifiers(*val)), - ); - modifiers.extend( - character - .merits - .iter() - .flat_map(|(merit, val)| merit.get_modifiers(*val)), - ); - - match &character.splat { - Splat::Werewolf(auspice, .., data) => { - // modifiers.extend(data.form.get_modifiers()); - modifiers.extend(Form::modifiers()); - - if let Some(auspice) = auspice { - modifiers.extend( - auspice.get_moon_gift().get_modifiers( - *character - .get_ability_value(&auspice.get_renown().clone().into()) - .unwrap_or(&0), - ), - ); - - if let Some(skill_bonus) = data.skill_bonus { - if auspice.get_skills().contains(&skill_bonus) { - modifiers.push(Modifier::new( - ModifierTarget::BaseSkill(skill_bonus), - 1, - ModifierOp::Add, - )); - } - } - } - } - Splat::Mage(_, order, _, data) => { - // TODO: High Speech merit, Order Status merit - if order.is_some() { - modifiers.push(Modifier::new( - ModifierTarget::BaseSkill(Skill::Occult), - 1, - ModifierOp::Add, - )); - } - - if let Some(attr_bonus) = data.attr_bonus { - if attr_bonus.get_type() == AttributeType::Resistance { - modifiers.push(Modifier::new( - ModifierTarget::BaseAttribute(attr_bonus), - 1, - ModifierOp::Add, - )); - } - } - } - Splat::Vampire(clan, .., data) => { - if let Some(attr_bonus) = data.attr_bonus { - if clan.get_favored_attributes().contains(&attr_bonus) { - modifiers.push(Modifier::new( - ModifierTarget::BaseAttribute(attr_bonus), - 1, - ModifierOp::Add, - )); - } - } - } - Splat::Changeling(seeming, .., data) => { - if let Some(attr_bonus) = data.attr_bonus { - if seeming.get_favored_attributes().contains(&attr_bonus) { - modifiers.push(Modifier::new( - ModifierTarget::BaseAttribute(attr_bonus), - 1, - ModifierOp::Add, - )); - } - } - } - - _ => {} - } - - // let mut defense_skill = Skill::Athletics; - // let mut defense_attr = DicePool::min(Attribute::Wits, Attribute::Dexterity); - - for modifier in modifiers { - handle_modifier(modifier, &mut modifier_map, &mut conditional_modifier_map); - } - // character._defense_pool = defense_attr + defense_skill; - } - - pub fn get_modifier(&self, character: &Character, target: impl Into) -> i16 { - let target = &target.into(); - let mut count = 0; - - let modifier_map = self.modifier_map.read().unwrap(); - let conditional_modifier_map = self.conditional_modifier_map.read().unwrap(); - - if let Some(vec) = modifier_map.get(target) { - for value in vec { - count += value.value(character); - } - } - if let Some(vec) = conditional_modifier_map.get(target) { - for (cond, vec) in vec { - if cond.check(character) { - for value in vec { - count += value.value(character); - } - } - } - } - - count - } - - pub fn get_conditional_modifier( - &self, - character: &Character, - target: impl Into, - condition: impl Into, - ) -> Option { - let target = &target.into(); - let condition = &condition.into(); - - let conditional_modifier_map = self.conditional_modifier_map.read().unwrap(); - conditional_modifier_map - .get(target) - .and_then(|map2| map2.get(condition)) - .map(|vec| vec.iter().fold(0, |acc, e| acc + e.value(character))) - } - - pub fn get_pool( - &self, - character: &Character, - target: impl Into, - ) -> Option { - let modifier_map = self.modifier_map.read().unwrap(); - let conditional_modifier_map = self.conditional_modifier_map.read().unwrap(); - - let target = target.into(); - - match target { - ModifierTarget::Trait(Trait::Defense) => { - let mut defense_attribute = DicePool::min(Attribute::Wits, Attribute::Dexterity); - let mut defense_skill = Skill::Athletics; - - if let Some(vec) = modifier_map.get(&target) { - for value in vec { - if let ModifierValue::Skill(skill) = value { - defense_skill = *skill; - } else if let ModifierValue::DicePool(pool) = value { - defense_attribute = pool.clone(); - } - } - } - if let Some(vec) = conditional_modifier_map.get(&target) { - for (cond, vec) in vec { - if cond.check(character) { - for value in vec { - if let ModifierValue::Skill(skill) = value { - defense_skill = *skill; - } else if let ModifierValue::DicePool(pool) = value { - defense_attribute = pool.clone(); - } - } - } - } - } - - Some(defense_attribute + defense_skill) - } - _ => None, - } - } - - pub fn get_conditional_pool( - &self, - target: impl Into, - condition: impl Into, - ) -> Option { - let modifier_map = self.modifier_map.read().unwrap(); - let conditional_modifier_map = self.conditional_modifier_map.read().unwrap(); - - let target = target.into(); - let condition = condition.into(); - - match target { - ModifierTarget::Trait(Trait::Defense) => { - let mut defense_attribute = DicePool::min(Attribute::Wits, Attribute::Dexterity); - let mut defense_skill = Skill::Athletics; - - if let Some(vec) = modifier_map.get(&target) { - for value in vec { - if let ModifierValue::Skill(skill) = value { - defense_skill = *skill; - } else if let ModifierValue::DicePool(pool) = value { - defense_attribute = pool.clone(); - } - } - } - if let Some(vec) = conditional_modifier_map.get(&target) { - for (cond, vec) in vec { - if condition.eq(cond) { - for value in vec { - if let ModifierValue::Skill(skill) = value { - defense_skill = *skill; - } else if let ModifierValue::DicePool(pool) = value { - defense_attribute = pool.clone(); - } - } - } - } - } - - Some(defense_attribute + defense_skill) - } - _ => None, - } - } -} diff --git a/cofd/lib/src/character/traits.rs b/cofd/lib/src/character/traits.rs deleted file mode 100644 index 3842a70..0000000 --- a/cofd/lib/src/character/traits.rs +++ /dev/null @@ -1,266 +0,0 @@ -use serde::{Deserialize, Serialize}; - -use cofd_util::VariantName; - -use super::Armor; -use crate::splat::NameKey; - -#[derive(VariantName)] -pub enum TraitCategory { - Mental, - Physical, - Social, -} - -impl TraitCategory { - pub fn unskilled(&self) -> u16 { - match self { - TraitCategory::Mental => 3, - TraitCategory::Physical => 1, - TraitCategory::Social => 1, - } - } -} - -#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)] -pub enum AttributeType { - Power, - Finesse, - Resistance, -} - -pub enum AttributeCategory { - Type(AttributeType), - Trait(TraitCategory), -} - -#[derive( - PartialEq, Eq, Hash, Clone, Copy, Debug, Serialize, Deserialize, AllVariants, VariantName, -)] -pub enum Attribute { - Intelligence, - Wits, - Resolve, - - Strength, - Dexterity, - Stamina, - - Presence, - Manipulation, - Composure, -} - -impl Attribute { - pub fn mental() -> [Attribute; 3] { - [Self::Intelligence, Self::Wits, Self::Resolve] - } - - pub fn physical() -> [Attribute; 3] { - [Self::Strength, Self::Dexterity, Self::Stamina] - } - - pub fn social() -> [Attribute; 3] { - [Self::Presence, Self::Manipulation, Self::Composure] - } - - pub fn power() -> [Attribute; 3] { - [Self::Intelligence, Self::Strength, Self::Presence] - } - - pub fn finesse() -> [Attribute; 3] { - [Self::Wits, Self::Dexterity, Self::Manipulation] - } - - pub fn resistance() -> [Attribute; 3] { - [Self::Resolve, Self::Stamina, Self::Composure] - } - - pub fn get(cat: AttributeCategory) -> [Attribute; 3] { - match cat { - AttributeCategory::Type(_type) => match _type { - AttributeType::Power => Self::power(), - AttributeType::Finesse => Self::finesse(), - AttributeType::Resistance => Self::resistance(), - }, - AttributeCategory::Trait(_trait) => match _trait { - TraitCategory::Mental => Self::mental(), - TraitCategory::Physical => Self::physical(), - TraitCategory::Social => Self::social(), - }, - } - } - - pub fn get_attr(_trait: &TraitCategory, _type: &AttributeType) -> Attribute { - match _trait { - TraitCategory::Mental => match _type { - AttributeType::Power => Self::Intelligence, - AttributeType::Finesse => Self::Wits, - AttributeType::Resistance => Self::Resolve, - }, - TraitCategory::Physical => match _type { - AttributeType::Power => Self::Strength, - AttributeType::Finesse => Self::Dexterity, - AttributeType::Resistance => Self::Stamina, - }, - TraitCategory::Social => match _type { - AttributeType::Power => Self::Presence, - AttributeType::Finesse => Self::Manipulation, - AttributeType::Resistance => Self::Composure, - }, - } - } - - #[allow(clippy::trivially_copy_pass_by_ref)] - pub fn get_type(&self) -> AttributeType { - match self { - Attribute::Intelligence => AttributeType::Power, - Attribute::Wits => AttributeType::Finesse, - Attribute::Resolve => AttributeType::Resistance, - Attribute::Strength => AttributeType::Power, - Attribute::Dexterity => AttributeType::Finesse, - Attribute::Stamina => AttributeType::Resistance, - Attribute::Presence => AttributeType::Power, - Attribute::Manipulation => AttributeType::Finesse, - Attribute::Composure => AttributeType::Resistance, - } - } -} - -#[derive( - Clone, - Copy, - Debug, - Hash, - PartialEq, - PartialOrd, - Eq, - Ord, - Serialize, - Deserialize, - AllVariants, - VariantName, -)] -pub enum Skill { - Academics, - Computer, - Crafts, - Investigation, - Medicine, - Occult, - Politics, - Science, - - Athletics, - Brawl, - Drive, - Firearms, - Larceny, - Stealth, - Survival, - Weaponry, - - AnimalKen, - Empathy, - Expression, - Intimidation, - Persuasion, - Socialize, - Streetwise, - Subterfuge, -} - -impl Skill { - fn mental() -> [Skill; 8] { - [ - Self::Academics, - Self::Computer, - Self::Crafts, - Self::Investigation, - Self::Medicine, - Self::Occult, - Self::Politics, - Self::Science, - ] - } - - fn physical() -> [Skill; 8] { - [ - Self::Athletics, - Self::Brawl, - Self::Drive, - Self::Firearms, - Self::Larceny, - Self::Stealth, - Self::Survival, - Self::Weaponry, - ] - } - - fn social() -> [Skill; 8] { - [ - Self::AnimalKen, - Self::Empathy, - Self::Expression, - Self::Intimidation, - Self::Persuasion, - Self::Socialize, - Self::Streetwise, - Self::Subterfuge, - ] - } - - pub fn get(cat: &TraitCategory) -> [Skill; 8] { - match cat { - TraitCategory::Mental => Self::mental(), - TraitCategory::Physical => Self::physical(), - TraitCategory::Social => Self::social(), - } - } -} - -impl NameKey for Skill { - fn name_key(&self) -> String { - format!("skill.{}", self.name()) - } -} - -#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug, Serialize, Deserialize)] -pub enum Trait { - Speed, - Defense, - Initative, - Perception, - Health, - Size, - - Beats, - AlternateBeats, - - Armor(Option), - - Willpower, - Power, - Fuel, - Integrity, -} - -impl Trait { - pub fn name(&self) -> Option<&str> { - match self { - Trait::Speed => Some("speed"), - Trait::Defense => Some("defense"), - Trait::Initative => Some("initative"), - Trait::Perception => Some("perception"), - Trait::Health => Some("health"), - Trait::Size => Some("size"), - Trait::Beats => Some("beats"), - Trait::Armor(_) => Some("armor"), - Trait::Willpower => Some("willpower"), - Trait::Power => None, - Trait::Fuel => None, - Trait::Integrity => None, - Trait::AlternateBeats => None, - } - } -} diff --git a/cofd/lib/src/dice_pool.rs b/cofd/lib/src/dice_pool.rs deleted file mode 100644 index 4027812..0000000 --- a/cofd/lib/src/dice_pool.rs +++ /dev/null @@ -1,135 +0,0 @@ -use serde::{Deserialize, Serialize}; -use std::{ - cmp::{max, min}, - fmt::Display, - ops::{Add, Sub}, -}; - -use cofd_util::VariantName; - -use crate::{ - character::traits::Trait, - prelude::{Attribute, Character, Skill}, -}; - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -pub enum DicePool { - Mod(i16), - Attribute(Attribute), - Skill(Skill), - Trait(Trait), - - Min(Box, Box), - Max(Box, Box), - - Add(Box, Box), - Sub(Box, Box), -} - -impl DicePool { - pub fn value(&self, character: &Character) -> i16 { - match self { - Self::Mod(val) => *val, - Self::Attribute(attr) => *character.attributes().get(attr) as i16, - Self::Skill(skill) => character.skills().get(*skill) as i16, - Self::Trait(trait_) => character.get_trait(trait_) as i16, - Self::Add(p1, p2) => p1.value(character) + p2.value(character), - Self::Sub(p1, p2) => p1.value(character) - p2.value(character), - Self::Max(p1, p2) => max(p1.value(character), p2.value(character)), - Self::Min(p1, p2) => min(p1.value(character), p2.value(character)), - } - } - - pub fn min(p1: impl Into, p2: impl Into) -> DicePool { - DicePool::Min(Box::new(p1.into()), Box::new(p2.into())) - } - - pub fn max(p1: impl Into, p2: impl Into) -> DicePool { - DicePool::Max(Box::new(p1.into()), Box::new(p2.into())) - } -} - -impl Default for DicePool { - fn default() -> Self { - Self::Mod(0) - } -} - -impl Add for DicePool { - type Output = DicePool; - - fn add(self, rhs: Self) -> Self::Output { - DicePool::Add(Box::new(self), Box::new(rhs)) - } -} - -impl Sub for DicePool { - type Output = DicePool; - - fn sub(self, rhs: Self) -> Self::Output { - DicePool::Sub(Box::new(self), Box::new(rhs)) - } -} - -impl From for DicePool { - fn from(attr: Attribute) -> Self { - DicePool::Attribute(attr) - } -} - -impl From for DicePool { - fn from(skill: Skill) -> Self { - DicePool::Skill(skill) - } -} - -impl From for DicePool { - fn from(trait_: Trait) -> Self { - DicePool::Trait(trait_) - } -} - -impl From for DicePool { - fn from(val: i16) -> Self { - DicePool::Mod(val) - } -} - -impl Add for Attribute { - type Output = DicePool; - - fn add(self, rhs: Self) -> Self::Output { - DicePool::Attribute(self) + DicePool::Attribute(rhs) - } -} - -impl Add for Attribute { - type Output = DicePool; - - fn add(self, rhs: Skill) -> Self::Output { - DicePool::Attribute(self) + DicePool::Skill(rhs) - } -} - -impl Add for DicePool { - type Output = DicePool; - - fn add(self, rhs: Skill) -> Self::Output { - self + DicePool::Skill(rhs) - } -} - -impl Display for DicePool { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - DicePool::Mod(val) => val.fmt(f), - DicePool::Attribute(attr) => f.write_str(attr.name()), - DicePool::Skill(skill) => f.write_str(skill.name()), - DicePool::Trait(trait_) => f.write_str(trait_.name().unwrap()), - DicePool::Min(p1, p2) => f.write_fmt(format_args!("min({p1}, {p2})")), - DicePool::Max(p1, p2) => f.write_fmt(format_args!("max({p1}, {p2})")), - DicePool::Add(p1, p2) => f.write_fmt(format_args!("{p1} + {p2}")), - DicePool::Sub(p1, p2) => f.write_fmt(format_args!("{p1} - {p2}")), - } - } -} diff --git a/cofd/lib/src/lib.rs b/cofd/lib/src/lib.rs deleted file mode 100644 index a59975d..0000000 --- a/cofd/lib/src/lib.rs +++ /dev/null @@ -1,304 +0,0 @@ -#![feature(let_chains)] -#![deny(clippy::pedantic)] -#![allow( - clippy::must_use_candidate, - clippy::used_underscore_binding, - clippy::unused_self, - clippy::match_wildcard_for_single_variants, - clippy::module_name_repetitions, - clippy::wildcard_imports, - clippy::match_same_arms, - clippy::default_trait_access -)] - -pub mod character; -pub mod dice_pool; -pub mod splat; - -#[macro_use] -extern crate cofd_util; - -pub mod prelude { - pub use crate::character::{ - traits::{Attribute, Skill, Trait}, - Attributes, Character, Skills, - }; - pub use cofd_util::{AllVariants, VariantName}; -} - -#[cfg(test)] -mod tests { - use ron::ser::PrettyConfig; - - use crate::{ - character::CharacterInfo, - prelude::*, - splat::{ - mage::{Arcanum, MageData, MageMerit, Order, Path}, - vampire::{Bloodline, Clan, Covenant, Discipline, VampireMerit}, - werewolf::{Auspice, Form, Renown, Tribe, WerewolfMerit}, - Merit, Splat, - }, - }; - - #[test] - fn size() { - println!("{}", std::mem::size_of::()); - } - - #[test] - #[allow(clippy::too_many_lines)] - fn it_works() { - let vampire_character = Character::builder() - .with_splat(Splat::Vampire( - Clan::Ventrue, - Some(Covenant::OrdoDracul), - Some(Bloodline::_Custom( - "Dragolescu".to_string(), - Some([ - Discipline::Animalism, - Discipline::Dominate, - Discipline::Resilience, - Discipline::Auspex, - ]), - )), - Default::default(), - )) - .with_info(CharacterInfo { - name: String::from("Darren Webb"), - player: String::from("m00n"), - chronicle: String::from("Night Trains"), - virtue_anchor: String::from("Scholar"), - vice_anchor: String::from("Authoritarian"), - concept: String::from("Occult Journalist/Mastermind"), - ..Default::default() - }) - .with_attributes(Attributes { - intelligence: 3, - wits: 3, - resolve: 2, - strength: 1, - dexterity: 3, - stamina: 2, - presence: 3, - manipulation: 2, - composure: 3, - }) - .with_skills(Skills { - investigation: 2, - occult: 3, - politics: 2, - larceny: 3, - stealth: 1, - animal_ken: 1, - expression: 3, - intimidation: 1, - streetwise: 2, - subterfuge: 4, - ..Default::default() - }) - .with_specialties(Skill::Larceny, vec![String::from("Sleight of Hand")]) - .with_specialties(Skill::Streetwise, vec![String::from("Rumours")]) - .with_specialties(Skill::Subterfuge, vec![String::from("Detecting Lies")]) - .with_abilities([ - (Discipline::Animalism.into(), 1), - (Discipline::Dominate.into(), 2), - ( - Discipline::_Custom("Coil of the Voivode".to_string()).into(), - 2, - ), - ]) - .with_merits([ - (Merit::Status("Ordo Dracul".to_string()), 1), - (Merit::Status("City".to_string()), 1), - (VampireMerit::CacophonySavvy.into(), 3), - (Merit::FastTalking, 1), - ( - Merit::ProfessionalTraining( - String::new(), - Some([Skill::Expression, Skill::Occult]), - None, - ), - 2, - ), - // AbilityVal(Ability::Merit(Merit::Contacts(String::new())), 2), - (Merit::SafePlace(String::new()), 3), - (Merit::Resources, 3), - (VampireMerit::NestGuardian.into(), 1), - ]) - .build(); - - println!("{:?}", vampire_character); - println!("{:?}", vampire_character.attributes()); - - println!( - "{}", - ron::ser::to_string_pretty(&vampire_character, PrettyConfig::default()).unwrap() - ); - - assert_eq!(vampire_character.max_health(), 7); - assert_eq!(vampire_character.attributes().strength, 1); - assert_eq!(vampire_character.max_fuel(), 10); - - let mut werewolf_character = Character::builder() - .with_splat(Splat::Werewolf( - Some(Auspice::Rahu), - Some(Tribe::BloodTalons), - None, - Default::default(), - )) - .with_info(CharacterInfo { - name: String::from("Amos Gray"), - player: String::from("m00n"), - virtue_anchor: String::from("Destroyer"), - vice_anchor: String::from("Lone Wolf"), - ..Default::default() - }) - .with_attributes(Attributes { - intelligence: 1, - wits: 3, - resolve: 2, - strength: 3, - dexterity: 2, - stamina: 3, - presence: 3, - manipulation: 1, - composure: 3, - }) - .with_skills(Skills { - investigation: 2, - medicine: 2, - athletics: 2, - brawl: 4, - stealth: 2, - survival: 3, - expression: 3, - intimidation: 4, - ..Default::default() - }) - .with_specialties(Skill::Brawl, vec![String::from("Claws")]) - .with_specialties(Skill::Stealth, vec![String::from("Stalking")]) - .with_specialties(Skill::Intimidation, vec![String::from("Direct Threats")]) - .with_abilities([(Renown::Glory.into(), 1), (Renown::Purity.into(), 3)]) - .with_merits([ - (Merit::Giant, 3), - (Merit::TrainedObserver, 1), - (Merit::DefensiveCombat(true, Some(Skill::Brawl)), 1), - (WerewolfMerit::FavoredForm(Some(Form::Gauru)).into(), 2), - (WerewolfMerit::EfficientKiller.into(), 2), - (Merit::RelentlessAssault, 2), - (Merit::Language("First Tongue".to_owned()), 1), - (WerewolfMerit::Totem.into(), 1), - ]) - .build(); - - werewolf_character.power = 3; - - println!("{:?}", werewolf_character); - - assert_eq!(werewolf_character.max_fuel(), 12); - assert_eq!(werewolf_character.defense(), 6); - assert_eq!(werewolf_character.perception(), 7); - assert_eq!(werewolf_character.max_health(), 12); - - if let Splat::Werewolf(.., ww) = &mut werewolf_character.splat { - ww.form = Form::Gauru; - } - - assert_eq!(werewolf_character.perception(), 7); - - let t = std::time::Instant::now(); - werewolf_character.calc_mod_map(); - println!("{:?}", std::time::Instant::now().duration_since(t)); - - assert_eq!(werewolf_character.perception(), 9); - - let mut mage_character = Character::builder() - .with_splat(Splat::Mage( - Path::Mastigos, - Some(Order::Mysterium), - None, - Box::new(MageData { - attr_bonus: Some(Attribute::Intelligence), - obsessions: vec![], - rotes: vec![], - }), - )) - .with_info(CharacterInfo { - name: String::from("Polaris"), - player: String::from("m00n"), - virtue_anchor: String::from("Curious"), - vice_anchor: String::from("Greedy"), - concept: String::from("Astronomer"), - ..Default::default() - }) - .with_attributes(Attributes { - intelligence: 3, - wits: 3, - resolve: 5, - strength: 2, - dexterity: 3, - stamina: 2, - presence: 1, - manipulation: 2, - composure: 3, - }) - .with_skills(Skills { - academics: 2, - computer: 1, - crafts: 1, - investigation: 3, - occult: 3, - science: 2, - - larceny: 2, - stealth: 2, - - animal_ken: 1, - empathy: 2, - expression: 1, - subterfuge: 3, - ..Default::default() - }) - .with_specialties(Skill::Academics, vec![String::from("Research")]) - .with_specialties(Skill::AnimalKen, vec![String::from("Felines")]) - .with_specialties(Skill::Subterfuge, vec![String::from("Detecting Lies")]) - // TODO: Professional Training specialties - .with_specialties(Skill::Investigation, vec![String::from("Riddles")]) - .with_specialties(Skill::Science, vec![String::from("Astronomy")]) - .with_abilities([ - (Arcanum::Mind.into(), 1), - (Arcanum::Prime.into(), 2), - (Arcanum::Space.into(), 3), - ]) - .with_merits([ - (Merit::Status("Mysterium".to_string()), 1), - (MageMerit::HighSpeech.into(), 1), - ( - Merit::ProfessionalTraining( - "e".to_owned(), - Some([Skill::Investigation, Skill::Science]), - None, - ), - 3, - ), - (Merit::TrainedObserver, 1), - // - // - ]) - .build(); - - mage_character.calc_mod_map(); - - if let Splat::Mage(.., data) = &mut mage_character.splat { - data.attr_bonus = Some(Attribute::Resolve); - } - - mage_character.calc_mod_map(); - - assert_ne!(mage_character.attributes().resolve, 6); - - mage_character.base_attributes_mut().resolve = 4; - assert_eq!(mage_character.attributes().resolve, 5); - } -} diff --git a/cofd/lib/src/splat/ability.rs b/cofd/lib/src/splat/ability.rs deleted file mode 100644 index 3384cb1..0000000 --- a/cofd/lib/src/splat/ability.rs +++ /dev/null @@ -1,78 +0,0 @@ -use serde::{Deserialize, Serialize}; - -use cofd_util::VariantName; - -use super::{ - geist::Haunt, - mage::Arcanum, - vampire::Discipline, - werewolf::{MoonGift, Renown}, - Merit, NameKey, -}; -use crate::character::modifier::Modifier; - -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash, VariantName)] -pub enum Ability { - #[expand] - Merit(Merit), - #[expand] - Discipline(Discipline), - #[expand] - Renown(Renown), - #[expand] - MoonGift(MoonGift), - #[expand] - Arcanum(Arcanum), - #[expand] - Haunt(Haunt), -} - -impl Ability { - pub fn name_mut(&mut self) -> Option<&mut String> { - match self { - Ability::Merit(Merit::_Custom(name)) - | Ability::Discipline(Discipline::_Custom(name)) - | Ability::MoonGift(MoonGift::_Custom(name)) => Some(name), - _ => None, - } - } - - pub fn get_modifiers(&self, value: u16) -> Vec { - match self { - Ability::Merit(merit) => merit.get_modifiers(value), - Ability::Discipline(discipline) => discipline.get_modifiers(value), - Ability::MoonGift(moon_gift) => moon_gift.get_modifiers(value), - _ => vec![], - } - } - - pub fn is_custom(&self) -> bool { - matches!( - self, - Ability::Merit(Merit::_Custom(_)) - | Ability::Discipline(Discipline::_Custom(_)) - | Ability::MoonGift(MoonGift::_Custom(_)) - ) - } -} - -impl NameKey for Ability { - fn name_key(&self) -> String { - match self { - Ability::Merit(merit) => format!("merit.{}", merit.name()), - Ability::Discipline(discipline) => format!("vampire.{}", discipline.name()), - Ability::Renown(renown) => format!("werewolf.{}", renown.name()), - Ability::MoonGift(moon_gift) => moon_gift.name_key(), - Ability::Arcanum(arcanum) => arcanum.name_key(), - Ability::Haunt(haunt) => format!("geist.{}", haunt.name()), - } - } -} -// #[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize)] -// pub struct AbilityVal(pub Ability, pub u16); - -// impl AbilityVal { -// pub fn get_modifiers(&self) -> Vec { -// self.0.get_modifiers(self.1) -// } -// } diff --git a/cofd/lib/src/splat/changeling.rs b/cofd/lib/src/splat/changeling.rs deleted file mode 100644 index 14b76ba..0000000 --- a/cofd/lib/src/splat/changeling.rs +++ /dev/null @@ -1,139 +0,0 @@ -use serde::{Deserialize, Serialize}; - -use super::{Merit, NameKey, Splat}; -use crate::{ - character::{ - traits::{AttributeCategory, AttributeType}, - Character, Damage, - }, - prelude::*, -}; - -#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -#[serde(default)] -pub struct ChangelingData { - pub attr_bonus: Option, - pub regalia: Option, - pub frailties: Vec, - pub clarity: Damage, - pub contracts: Vec, -} - -impl ChangelingData { - pub fn max_clarity(&self, character: &Character) -> u16 { - let attributes = character.attributes(); - attributes.wits + attributes.composure - } -} - -#[derive( - Clone, Serialize, Deserialize, Debug, PartialEq, Eq, VariantName, AllVariants, Default, -)] -pub enum Seeming { - #[default] - Beast, - Darkling, - Elemental, - Fairest, - Ogre, - Wizened, - _Custom(String, Regalia, AttributeType), -} - -impl Seeming { - pub fn get_favored_regalia(&self) -> &Regalia { - match self { - Seeming::Beast => &Regalia::Steed, - Seeming::Darkling => &Regalia::Mirror, - Seeming::Elemental => &Regalia::Sword, - Seeming::Fairest => &Regalia::Crown, - Seeming::Ogre => &Regalia::Shield, - Seeming::Wizened => &Regalia::Jewels, - Seeming::_Custom(_, regalia, ..) => regalia, - } - } - - pub fn get_favored_attributes(&self) -> [Attribute; 3] { - Attribute::get(AttributeCategory::Type(match self { - Seeming::Beast => AttributeType::Resistance, - Seeming::Darkling => AttributeType::Finesse, - Seeming::Elemental => AttributeType::Resistance, - Seeming::Fairest => AttributeType::Power, - Seeming::Ogre => AttributeType::Power, - Seeming::Wizened => AttributeType::Finesse, - Seeming::_Custom(.., _type) => _type.clone(), - })) - } -} - -#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, VariantName, AllVariants)] -pub enum Court { - Spring, - Summer, - Autumn, - Winter, - _Custom(String), -} - -#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, VariantName, AllVariants)] -pub enum Kith { - Artist, - BrightOne, - Chatelane, - Gristlegrinder, - Helldiver, - Hunterheart, - Leechfinger, - Mirrorskin, - Nightsinger, - Notary, - Playmate, - Snowskin, - _Custom(String), -} - -#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, VariantName, AllVariants)] -pub enum Regalia { - Crown, - Jewels, - Mirror, - Shield, - Steed, - Sword, - _Custom(String), -} - -impl NameKey for Regalia { - fn name_key(&self) -> String { - format!("changeling.{}", self.name()) - } -} - -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash, AllVariants, VariantName)] -pub enum ChangelingMerit { - Mantle, -} - -impl ChangelingMerit { - pub fn is_available(&self, character: &Character) -> bool { - matches!(character.splat, Splat::Changeling(..)) - } -} - -impl From for Merit { - fn from(merit: ChangelingMerit) -> Self { - Merit::Changeling(merit) - } -} - -#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq, Eq)] -pub struct Contract { - pub name: String, - pub goblin: bool, - pub cost: String, - pub dice: String, - pub action: String, - pub duration: String, - pub loophole: String, - pub seeming_benefit: String, -} diff --git a/cofd/lib/src/splat/geist.rs b/cofd/lib/src/splat/geist.rs deleted file mode 100644 index be13d5a..0000000 --- a/cofd/lib/src/splat/geist.rs +++ /dev/null @@ -1,87 +0,0 @@ -use cofd_util::VariantName; -use serde::{Deserialize, Serialize}; - -use super::{ability::Ability, NameKey}; - -#[derive( - Debug, Clone, PartialEq, Eq, Serialize, Deserialize, AllVariants, VariantName, Default, -)] -pub enum Burden { - #[default] - Abiding, - Bereaved, - Hungry, - Kindly, - Vengeful, - _Custom(String, [Haunt; 3]), -} - -impl Burden { - pub fn get_favoured_haunts(&self) -> &[Haunt; 3] { - match self { - Self::Abiding => &[Haunt::Caul, Haunt::Memoria, Haunt::Tomb], - Self::Bereaved => &[Haunt::Curse, Haunt::Oracle, Haunt::Shroud], - Self::Hungry => &[Haunt::Boneyard, Haunt::Marionette, Haunt::Caul], - Self::Kindly => &[Haunt::Dirge, Haunt::Marionette, Haunt::Shroud], - Self::Vengeful => &[Haunt::Curse, Haunt::Memoria, Haunt::Rage], - Self::_Custom(_, haunts) => haunts, - } - } -} - -#[derive( - Debug, Clone, PartialEq, Eq, Serialize, Deserialize, AllVariants, VariantName, Default, -)] -pub enum Archetype { - #[default] - Furies, - Mourners, - Necropolitans, - Pilgrims, - Undertakers, - _Custom(String), -} - -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, AllVariants, VariantName)] -pub enum Haunt { - Boneyard, - Caul, - Curse, - Dirge, - Marionette, - Memoria, - Oracle, - Rage, - Shroud, - Tomb, - _Custom(String), -} - -impl From for Ability { - fn from(val: Haunt) -> Self { - Ability::Haunt(val) - } -} - -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, AllVariants, VariantName)] -pub enum Key { - Beasts, - Blood, - Chance, - ColdWind, - Disease, - GraveDirt, - PyreFlame, - Stillness, -} - -impl NameKey for Key { - fn name_key(&self) -> String { - format!("geist.{}", self.name()) - } -} - -#[derive(Clone, Default, Debug, Serialize, Deserialize, PartialEq, Eq)] -pub struct BoundData { - pub keys: Vec, -} diff --git a/cofd/lib/src/splat/mage.rs b/cofd/lib/src/splat/mage.rs deleted file mode 100644 index bb15605..0000000 --- a/cofd/lib/src/splat/mage.rs +++ /dev/null @@ -1,161 +0,0 @@ -use serde::{Deserialize, Serialize}; - -use cofd_util::{AllVariants, VariantName}; - -use super::{ability::Ability, Merit, NameKey, Splat}; -use crate::prelude::{Attribute, Character, Skill}; - -#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -#[serde(default)] -pub struct MageData { - pub attr_bonus: Option, - pub obsessions: Vec, - pub rotes: Vec, -} - -#[derive( - Clone, Serialize, Deserialize, Debug, PartialEq, Eq, VariantName, AllVariants, Default, -)] -pub enum Path { - #[default] - Acanthus, - Mastigos, - Moros, - Obrimos, - Thyrsus, - _Custom(String, [Arcanum; 2], Arcanum), -} - -impl Path { - fn get_ruling_arcana(&self) -> &[Arcanum; 2] { - match self { - Path::Acanthus => &[Arcanum::Time, Arcanum::Fate], - Path::Mastigos => &[Arcanum::Space, Arcanum::Mind], - Path::Moros => &[Arcanum::Matter, Arcanum::Death], - Path::Obrimos => &[Arcanum::Forces, Arcanum::Prime], - Path::Thyrsus => &[Arcanum::Life, Arcanum::Spirit], - Path::_Custom(_, ruling, _) => ruling, - } - } - fn get_inferior_arcanum(&self) -> &Arcanum { - match self { - Path::Acanthus => &Arcanum::Forces, - Path::Mastigos => &Arcanum::Matter, - Path::Moros => &Arcanum::Spirit, - Path::Obrimos => &Arcanum::Death, - Path::Thyrsus => &Arcanum::Mind, - Path::_Custom(_, _, inferior) => inferior, - } - } -} - -#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, AllVariants, VariantName)] -pub enum Order { - AdamantineArrow, - GuardiansOfTheVeil, - Mysterium, - SilverLadder, - FreeCouncil, - #[expand] - SeersOfTheThrone(Option), - _Custom(String, [Skill; 3]), -} - -#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, AllVariants, VariantName)] -pub enum Ministry { - Hegemony, - Panopticon, - Paternoster, - Praetorian, - _Custom(String, [Skill; 3]), -} - -impl Order { - pub fn get_rote_skills(&self) -> &[Skill; 3] { - match self { - Order::AdamantineArrow => &[Skill::Athletics, Skill::Intimidation, Skill::Medicine], - Order::GuardiansOfTheVeil => &[Skill::Investigation, Skill::Stealth, Skill::Subterfuge], - Order::Mysterium => &[Skill::Investigation, Skill::Occult, Skill::Survival], - Order::SilverLadder => &[Skill::Expression, Skill::Persuasion, Skill::Subterfuge], - Order::FreeCouncil => &[Skill::Crafts, Skill::Persuasion, Skill::Science], - Order::SeersOfTheThrone(ministry) => match ministry { - Some(ministry) => match ministry { - Ministry::Hegemony => &[Skill::Politics, Skill::Persuasion, Skill::Empathy], - Ministry::Panopticon => { - &[Skill::Investigation, Skill::Stealth, Skill::Subterfuge] - } - Ministry::Paternoster => &[Skill::Academics, Skill::Occult, Skill::Expression], - Ministry::Praetorian => { - &[Skill::Athletics, Skill::Larceny, Skill::Intimidation] - } - Ministry::_Custom(_, skills) => skills, - }, - None => &[Skill::Investigation, Skill::Occult, Skill::Persuasion], - }, - Order::_Custom(_, skills) => skills, - } - } -} - -impl From for Order { - fn from(ministry: Ministry) -> Self { - Order::SeersOfTheThrone(Some(ministry)) - } -} - -#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, AllVariants, VariantName)] -pub enum Legacy { - _Custom(String, Option), -} - -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, VariantName, AllVariants)] -pub enum Arcanum { - Death, - Fate, - Forces, - Life, - Matter, - Mind, - Prime, - Space, - Spirit, - Time, -} - -impl NameKey for Arcanum { - fn name_key(&self) -> String { - format!("mage.{}", self.name()) - } -} - -impl From for Ability { - fn from(val: Arcanum) -> Self { - Ability::Arcanum(val) - } -} - -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash, AllVariants, VariantName)] -pub enum MageMerit { - HighSpeech, -} - -impl MageMerit { - pub fn is_available(&self, character: &Character) -> bool { - matches!(character.splat, Splat::Mage(..)) - } -} - -impl From for Merit { - fn from(merit: MageMerit) -> Self { - Merit::Mage(merit) - } -} - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -pub struct Rote { - pub arcanum: Arcanum, - pub level: u16, - pub spell: String, - pub creator: String, - pub skill: Skill, -} diff --git a/cofd/lib/src/splat/merits.rs b/cofd/lib/src/splat/merits.rs deleted file mode 100644 index b8efff1..0000000 --- a/cofd/lib/src/splat/merits.rs +++ /dev/null @@ -1,429 +0,0 @@ -use serde::{Deserialize, Serialize}; - -use cofd_util::{AllVariants, VariantName}; - -use super::{ - ability::Ability, changeling::ChangelingMerit, mage::MageMerit, vampire::VampireMerit, - werewolf::WerewolfMerit, -}; -use crate::{ - character::modifier::{Modifier, ModifierOp, ModifierTarget, ModifierValue}, - prelude::{Attributes, Character, Skill, Skills, Trait}, -}; - -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash, AllVariants, VariantName)] -pub enum Merit { - // Mental Merits - AreaOfExpertise(String), - CommonSense, - DangerSense, - DirectionSense, - EideticMemory, - EncyclopedicKnowledge(String), - EyeForTheStrange, - FastReflexes, - GoodTimeManagement, - HolisticAwareness, - // HumanPrey, // DTR - // Hypervigilance, // DTR - Indomitable, - InterdisciplinarySpecialty(String, Option), - InvestigativeAide(Option), - InvestigativeProdigy, - Language(String), - Library(Option), - LibraryAdvanced(Vec), - // LucidDreamer, // CTL - MeditativeMind, - Multilingual(String, String), - ObjectFetishism(String), - Patient, - // RenownedArtisan(String) // MTC - Scarred(String), // TODO: Condition - ToleranceForBiology, - TrainedObserver, - ViceRidden(String), - Virtuous(String), - - // Physical Merits - Ambidextrous, - AutomotiveGenius, - CovertOperative, - CrackDriver, - Demolisher, - DoubleJointed, - FleetOfFoot, - Freediving, - Giant, - Hardy, - Greyhound, - // IronSkin, // BTP - IronStamina, - QuickDraw(String), - PunchDrunk, - Relentless, - Roadkill, - SeizingTheEdge, - SleightOfHand, - SmallFramed, - Survivalist, - - // Social Merits - AirOfMenace, - Allies(String), - AlternateIdentity(String), - Anonymity, - Barfly, - ClosedBook, - CohesiveUnit, - Contacts(Vec), - Defender, - Empath, - Fame, - Fixer, - HobbyistClique(String, Option), - Inspiring, - IronWill, - Mentor(String, Option<[Skill; 3]>), // TODO: Add Resources to list - Peacemaker, - Pusher, - Resources, - Retainer(String), - SafePlace(String), - SmallUnitTactics, - SpinDoctor, - Staff, - Status(String), - StrikingLooks(String), - SupportNetwork(String, Option>), // TODO: Restrict to social merits - Sympathetic, - TableTurner, - TakesOneToKnowOne, - Taste(String, Option), // TODO: Restrict to Crafts/Expression - TrueFriend(String), - Untouchable, - - // Style Merits - // Mental Styles - ProfessionalTraining { - profession: String, - skills: [Skill; 2], - skill: Option, - }, - // Physical Styles - AggresiveDriving, - DroneControl, - Falconry, - K9, - Parkour, - StuntDriver, - // Social Styles - Etiquette, - FastTalking, - // MysteryCultInitation(String, _, Merit, _, Merit, _) - // ScorpionCultInitation, // MTC - - // Fighting Merits - DefensiveCombat(bool, Option), // Brawl / Weaponry - - // Fighting Styles - // ArmedDefense, - // Avoidance, - // Berserker, - // Bowmanship, - // Boxing, - // BruteForce, - // ChainWeapons, - // CloseQuartersCombat, - // CombatArchery, - // DisablingTactics, - // Firefight, - // Grappling, - // HeavyWeapons, - // ImprovisedWeapons, - // KinoMutai, - // LightWeapons - // Marksmanship - // MaritalArts - // MountedCombat - // PoliceTactics - // PoweredProjectile - RelentlessAssault, - // SpearAndBayonet - // StaffFighting, - // StreetFighting, - // StrengthPerformance, // TODO: Give Giant? - // Systema, - // ThrownWepons, - // TwoWeaponFighting, - // UnarmedDefense, - // WeaponAndShield - #[expand] - Mage(MageMerit), - #[expand] - Vampire(VampireMerit), - #[expand] - Werewolf(WerewolfMerit), - #[expand] - Changeling(ChangelingMerit), - - _Custom(String), -} - -impl Merit { - pub fn mental() -> Vec { - vec![ - Self::AreaOfExpertise(String::new()), - Self::CommonSense, - Self::DangerSense, - Self::DirectionSense, - Self::EideticMemory, - Self::EncyclopedicKnowledge(String::new()), - Self::EyeForTheStrange, - Self::FastReflexes, - Self::GoodTimeManagement, - Self::HolisticAwareness, - // Self::HumanPrey, // DTR - // Self::Hypervigilance, // DTR - Self::Indomitable, - Self::InterdisciplinarySpecialty(String::new(), None), - Self::InvestigativeAide(None), - Self::InvestigativeProdigy, - Self::Language(String::new()), - Self::Library(None), - Self::LibraryAdvanced(vec![]), - // LucidDreamer, // CTL - Self::MeditativeMind, - Self::Multilingual(String::new(), String::new()), - Self::ObjectFetishism(String::new()), - Self::Patient, - // RenownedArtisan(String) // MTC - Self::Scarred(String::new()), - Self::ToleranceForBiology, - Self::TrainedObserver, - Self::ViceRidden(String::new()), - Self::Virtuous(String::new()), - ] - } - - pub fn physical() -> Vec { - vec![ - Self::Ambidextrous, - Self::AutomotiveGenius, - Self::CovertOperative, - Self::CrackDriver, - Self::Demolisher, - Self::DoubleJointed, - Self::FleetOfFoot, - Self::Freediving, - Self::Giant, - Self::Hardy, - Self::Greyhound, - // IronSkin, // BTP - Self::IronStamina, - Self::QuickDraw(String::new()), - Self::PunchDrunk, - Self::Relentless, - Self::Roadkill, - Self::SeizingTheEdge, - Self::SleightOfHand, - Self::SmallFramed, - Self::Survivalist, - ] - } - - pub fn social() -> Vec { - vec![ - Self::AirOfMenace, - Self::Allies(String::new()), - Self::AlternateIdentity(String::new()), - Self::Anonymity, - Self::Barfly, - Self::ClosedBook, - Self::CohesiveUnit, - Self::Contacts(vec![]), - Self::Defender, - Self::Empath, - Self::Fame, - Self::Fixer, - Self::HobbyistClique(String::new(), None), - Self::Inspiring, - Self::IronWill, - Self::Mentor(String::new(), None), - Self::Peacemaker, - Self::Pusher, - Self::Resources, - Self::Retainer(String::new()), - Self::SafePlace(String::new()), - Self::SmallUnitTactics, - Self::SpinDoctor, - Self::Staff, - Self::Status(String::new()), - Self::StrikingLooks(String::new()), - Self::SupportNetwork(String::new(), None), - Self::Sympathetic, - Self::TableTurner, - Self::TakesOneToKnowOne, - Self::Taste(String::new(), None), - Self::TrueFriend(String::new()), - Self::Untouchable, - ] - } - - pub fn get_modifiers(&self, value: u16) -> Vec { - match &self { - Merit::DefensiveCombat(true, Some(skill)) => { - vec![Modifier::new( - ModifierTarget::Trait(Trait::Defense), - ModifierValue::Skill(*skill), - ModifierOp::Set, - )] - } - Merit::Giant => { - if value == 3 { - vec![Modifier::new( - ModifierTarget::Trait(Trait::Size), - ModifierValue::Num(1), - ModifierOp::Add, - )] - } else { - vec![] - } - } - Merit::Werewolf(merit) => merit.get_modifiers(value), - _ => vec![], - } - } - - pub fn is_available( - &self, - character: &crate::prelude::Character, - attributes: &Attributes, - skills: &Skills, - ) -> bool { - match self { - Merit::_Custom(_) => true, - - Merit::AreaOfExpertise(_) => character.attributes().resolve > 1, - Merit::EyeForTheStrange => { - character.attributes().resolve > 1 && character.skills().occult > 0 - } - Merit::FastReflexes => { - let attr = character.attributes(); - attr.wits > 2 || attr.dexterity > 2 - } - Merit::GoodTimeManagement => { - let skills = character.skills(); - skills.academics > 1 || skills.science > 1 - } - Self::Indomitable => character.attributes().resolve > 2, - Self::InterdisciplinarySpecialty(_, Some(skill)) => character.skills().get(*skill) > 2, - Self::InvestigativeAide(Some(skill)) => character.skills().get(*skill) > 2, - Self::InvestigativeProdigy => { - character.attributes().wits > 2 && character.skills().investigation > 2 - } - // Self::LibraryAdvanced() // Library 3 + <= Safe Place - Self::Scarred(_) => character.integrity <= 5, - Self::ToleranceForBiology => character.attributes().resolve > 2, - Self::TrainedObserver => { - let attrs = character.attributes(); - attrs.wits > 2 || attrs.composure > 2 - } - Self::ViceRidden(_) if character.splat.vice_anchor() != "vice" => false, - Self::Virtuous(_) if character.splat.virtue_anchor() != "virtue" => false, - - // Self::Ambidextrous // Character creation only - Self::AutomotiveGenius => { - let skills = character.skills(); - skills.crafts > 2 && skills.drive > 0 && skills.science > 0 - } - Self::CovertOperative => { - let attr = character.attributes(); - attr.wits > 2 && attr.dexterity > 2 && character.skills().stealth > 1 - } - Self::CrackDriver => character.skills().drive > 2, - Self::Demolisher => { - let attr = character.attributes(); - attr.strength > 2 || attr.intelligence > 2 - } - Self::DoubleJointed => character.attributes().dexterity > 2, - Self::FleetOfFoot => character.skills().athletics > 1, - Self::Freediving => character.skills().athletics > 1, - // Self::Giant // Character Creation OR Strength Performance - Self::Hardy => character.attributes().stamina > 2, - Self::Greyhound => { - let attr = character.attributes(); - character.skills().athletics > 2 && attr.wits > 2 && attr.stamina > 2 - } - // IronSkin - Self::IronStamina => { - let attr = character.attributes(); - attr.stamina > 2 || attr.resolve > 2 - } - Self::QuickDraw(_) => character.attributes().wits > 2, - Self::PunchDrunk => character.max_willpower() > 5, - Self::Relentless => { - character.skills().athletics > 1 && character.attributes().stamina > 2 - } - // Self::Roadkill // Merit Dep Aggresive Driving 2 - Self::SeizingTheEdge => { - let attr = character.attributes(); - attr.wits > 2 && attr.composure > 2 - } - Self::SleightOfHand => character.skills().larceny > 2, - // Self::SmallFramed // Character Creation - // Self::Survivalist => character.skills().survival > 2 // Iron Stamina 3 dependency - Self::AirOfMenace => character.skills().intimidation > 1, - // Self::Anonymity // No Fame Merit - Self::Barfly => character.skills().socialize > 1, - Self::ClosedBook => { - let attr = character.attributes(); - attr.manipulation > 2 && attr.resolve > 2 - } - Self::CohesiveUnit => character.attributes().presence > 2, - Self::Empath => character.skills().empathy > 1, - // Self::Fame // No Anonimity Merit - // Self::Fixer => character.attributes().wits > 2 // Contacts 2 - Self::HobbyistClique(_, Some(skill)) => character.skills().get(*skill) > 1, - Self::Inspiring => character.attributes().presence > 2, - Self::IronWill => character.attributes().resolve > 3, - Self::Peacemaker => character.attributes().wits > 2 && character.skills().empathy > 2, - Self::Pusher => character.skills().persuasion > 1, - Self::SmallUnitTactics => character.attributes().presence > 2, - Self::SpinDoctor => { - character.attributes().manipulation > 2 && character.skills().subterfuge > 1 - } - Self::TableTurner => { - let attr = character.attributes(); - attr.composure > 2 && attr.manipulation > 2 && attr.wits > 2 - } - Self::TakesOneToKnowOne if character.splat.vice_anchor() != "vice" => false, - Self::Taste(_, _) => character.skills().crafts > 1, - Self::Untouchable => { - character.attributes().manipulation > 2 && character.skills().subterfuge > 1 - } - - Self::Mage(merit) => merit.is_available(character), - Self::Vampire(merit) => merit.is_available(character, attributes, skills), - Self::Werewolf(merit) => merit.is_available(character), - Self::Changeling(merit) => merit.is_available(character), - _ => true, - } - } -} - -impl NameKey for Merit { - fn name_key(&self) -> String { - format!("merits.{}", self.name()) - } -} - -impl From for Ability { - fn from(merit: Merit) -> Self { - Ability::Merit(merit) - } -} - -pub trait NameKey { - fn name_key(&self) -> String; -} diff --git a/cofd/lib/src/splat/mod.rs b/cofd/lib/src/splat/mod.rs deleted file mode 100644 index e11dfea..0000000 --- a/cofd/lib/src/splat/mod.rs +++ /dev/null @@ -1,302 +0,0 @@ -use serde::{Deserialize, Serialize}; - -use cofd_util::{AllVariants, NameKey, SplatEnum, VariantName}; - -use self::ability::Ability; -use crate::{ - character::modifier::{Modifier, ModifierOp, ModifierTarget, ModifierValue}, - character::traits::AttributeType, - prelude::{Attribute, Attributes, Character, Skill, Skills, Trait}, -}; - -pub mod ability; -pub mod merits; - -pub use merits::*; - -pub mod mage; -pub mod vampire; -pub mod werewolf; -// pub mod promethean; -pub mod changeling; -// pub mod hunter; -pub mod geist; -// pub mod mummy; -// pub mod demon; -// pub mod beast; -// pub mod deviant; - -use mage::*; -use vampire::*; -use werewolf::*; -// use promethean::*; -use changeling::*; -// use hunter::*; -use geist::*; -// use mummy::*; -// use demon::*; -// use beast::*; -// use deviant:*; - -#[derive( - Clone, - Default, - Serialize, - Deserialize, - Debug, - VariantName, - SplatEnum, - AllVariants, - PartialEq, - Eq, -)] -pub enum Splat { - #[default] - Mortal, - #[splat( - virtue_anchor = "mask", - vice_anchor = "dirge", - ability = "disciplines", - st = "blood_potency", - alt_beats = "blood", - fuel = "vitae", - integrity = "humanity", - abilities_finite = false - )] - Vampire(Clan, Option, Option, Box), - #[splat( - virtue_anchor = "blood", - vice_anchor = "bone", - ability = "renown", - st = "primal_urge", - fuel = "essence", - integrity = "harmony" - )] - Werewolf( - Option, - Option, - Option, - Box, - ), - #[splat( - ability = "arcana", - st = "gnosis", - alt_beats = "arcane", - fuel = "mana", - integrity = "wisdom" - )] - Mage(Path, Option, Option, Box), // TODO: Order = free order status, high speech merit - // Promethean(Lineage), - #[splat( - virtue_anchor = "thread", - vice_anchor = "needle", - ability = "disciplines", - st = "wyrd", - fuel = "glamour", - integrity = "clarity", - abilities_finite = false - )] - Changeling(Seeming, Option, Option, Box), - // Hunter(Tier), - #[splat( - virtue_anchor = "root", - vice_anchor = "bloom", - ability = "haunts", - st = "synergy", - fuel = "plasm", - integrity = "synergy", - abilities_finite = false - )] - Bound(Burden, Archetype, #[skip] BoundData), - // Mummy(Decree, Guild), - // Demon(Incarnation, Vec), - // Beast(Hunger), - // Deviant(Origin, Clade, Vec), -} - -impl Splat { - pub fn custom_xsplat(&self, name: String) -> Option { - match self { - Self::Mortal => None, - Self::Vampire(..) => Some( - Clan::_Custom( - name, - Box::new([ - Discipline::Animalism, - Discipline::Auspex, - Discipline::Celerity, - ]), - [Attribute::Composure, Attribute::Dexterity], - ) - .into(), - ), - Self::Werewolf(..) => Some( - Auspice::_Custom( - name, - [Skill::Academics, Skill::AnimalKen, Skill::Athletics], - Renown::Cunning, - MoonGift::_Custom(String::from("Custom")), - Box::new([ShadowGift::Death, ShadowGift::Dominance]), - HuntersAspect::Monstrous, - ) - .into(), - ), - Self::Mage(..) => { - Some(Path::_Custom(name, [Arcanum::Death, Arcanum::Fate], Arcanum::Forces).into()) - } - Self::Changeling(..) => { - Some(Seeming::_Custom(name, Regalia::Crown, AttributeType::Power).into()) - } - Self::Bound(..) => { - Some(Burden::_Custom(name, [Haunt::Boneyard, Haunt::Caul, Haunt::Curse]).into()) - } - } - } - - pub fn custom_ysplat(&self, name: String) -> Option { - match self { - Self::Mortal => None, - Self::Vampire(..) => Some(Covenant::_Custom(name).into()), - Self::Werewolf(..) => Some( - Tribe::_Custom( - name, - Renown::Cunning, - Box::new([ - ShadowGift::Death, - ShadowGift::Dominance, - ShadowGift::Elementals, - ]), - ) - .into(), - ), - Self::Mage(..) => Some( - Order::_Custom(name, [Skill::Academics, Skill::AnimalKen, Skill::Athletics]).into(), - ), - Self::Changeling(..) => Some(Court::_Custom(name).into()), - Self::Bound(..) => Some(Archetype::_Custom(name).into()), - } - } - - pub fn custom_zsplat(&self, name: String) -> Option { - match self { - Splat::Vampire(..) => Some(Bloodline::_Custom(name, None).into()), - Splat::Werewolf(..) => Some(Lodge::_Custom(name).into()), - Splat::Mage(..) => Some(Legacy::_Custom(name, None).into()), - Splat::Changeling(..) => Some(Kith::_Custom(name).into()), - _ => None, - } - } - - pub fn all_abilities(&self) -> Option> { - match self { - Splat::Vampire(..) => Some(Discipline::all().into_iter().map(Into::into).collect()), - Splat::Werewolf(..) => Some(Renown::all().into_iter().map(Into::into).collect()), - Splat::Mage(..) => Some(Arcanum::all().into_iter().map(Into::into).collect()), - Splat::Bound(..) => Some(Haunt::all().into_iter().map(Into::into).collect()), - _ => None, - } - } - - pub fn custom_ability(&self, name: String) -> Option { - match self { - Splat::Vampire(..) => Some(Discipline::_Custom(name).into()), - Splat::Werewolf(..) => Some(MoonGift::_Custom(name).into()), - Splat::Bound(..) => Some(Haunt::_Custom(name).into()), - _ => None, - } - } - - pub fn alternate_beats_optional(&self) -> bool { - match self { - Self::Mage(..) => false, - // Promethean - // Demon - _ => true, - } - } - - pub fn merits(&self) -> Vec { - match self { - Self::Mortal => Merit::all(), - Self::Vampire(..) => VampireMerit::all().map(Into::into).to_vec(), - Self::Werewolf(..) => WerewolfMerit::all().map(Into::into).to_vec(), - Self::Mage(..) => MageMerit::all().map(Into::into).to_vec(), - Self::Changeling(..) => ChangelingMerit::all().map(Into::into).to_vec(), - Self::Bound(..) => vec![], - } - } -} - -impl XSplat { - pub fn name_mut(&mut self) -> Option<&mut String> { - match self { - Self::Vampire(Clan::_Custom(name, ..)) - | Self::Werewolf(Auspice::_Custom(name, ..)) - | Self::Mage(Path::_Custom(name, ..)) - | Self::Changeling(Seeming::_Custom(name, ..)) - | Self::Bound(Burden::_Custom(name, ..)) => Some(name), - _ => None, - } - } - - pub fn is_custom(&self) -> bool { - matches!( - self, - Self::Vampire(Clan::_Custom(..)) - | Self::Werewolf(Auspice::_Custom(..)) - | Self::Mage(Path::_Custom(..)) - | Self::Changeling(Seeming::_Custom(..)) - | Self::Bound(Burden::_Custom(..)) - ) - } -} - -impl YSplat { - pub fn name_mut(&mut self) -> Option<&mut String> { - match self { - Self::Vampire(Covenant::_Custom(name)) - | Self::Werewolf(Tribe::_Custom(name, ..)) - | Self::Mage( - Order::_Custom(name, ..) - | Order::SeersOfTheThrone(Some(Ministry::_Custom(name, ..))), - ) - | Self::Changeling(Court::_Custom(name)) - | Self::Bound(Archetype::_Custom(name, ..)) => Some(name), - _ => None, - } - } - - pub fn is_custom(&self) -> bool { - matches!( - self, - YSplat::Vampire(Covenant::_Custom(..)) - | YSplat::Werewolf(Tribe::_Custom(..)) - | YSplat::Mage( - Order::_Custom(..) | Order::SeersOfTheThrone(Some(Ministry::_Custom(..))), - ) | YSplat::Changeling(Court::_Custom(..)) - | Self::Bound(Archetype::_Custom(..)) - ) - } -} - -impl ZSplat { - pub fn name_mut(&mut self) -> Option<&mut String> { - match self { - ZSplat::Vampire(Bloodline::_Custom(name, ..)) - | ZSplat::Werewolf(Lodge::_Custom(name)) - | ZSplat::Mage(Legacy::_Custom(name, ..)) - | ZSplat::Changeling(Kith::_Custom(name)) => Some(name), - _ => None, - } - } - - pub fn is_custom(&self) -> bool { - matches!( - self, - ZSplat::Vampire(Bloodline::_Custom(..)) - | ZSplat::Werewolf(Lodge::_Custom(..)) - | ZSplat::Mage(Legacy::_Custom(..)) - | ZSplat::Changeling(Kith::_Custom(..)) - ) - } -} diff --git a/cofd/lib/src/splat/vampire.rs b/cofd/lib/src/splat/vampire.rs deleted file mode 100644 index bfd153f..0000000 --- a/cofd/lib/src/splat/vampire.rs +++ /dev/null @@ -1,329 +0,0 @@ -use serde::{Deserialize, Serialize}; - -use cofd_util::VariantName; - -use super::{ability::Ability, Merit, Splat}; -use crate::{ - character::modifier::{Modifier, ModifierOp}, - dice_pool::DicePool, - prelude::{Attribute, Attributes, Skills, Trait}, -}; - -#[derive(Clone, Default, Serialize, Deserialize, Debug, PartialEq, Eq)] -#[serde(default)] -pub struct VampireData { - pub attr_bonus: Option, - pub banes: Vec, -} - -#[derive( - Clone, Serialize, Deserialize, Debug, PartialEq, Eq, VariantName, AllVariants, Default, -)] -pub enum Clan { - #[default] - Daeva, - Gangrel, - Mekhet, - Nosferatu, - Ventrue, - _Custom(String, Box<[Discipline; 3]>, [Attribute; 2]), -} - -impl Clan { - pub fn get_disciplines(&self) -> &[Discipline; 3] { - match self { - Clan::Daeva => &[Discipline::Celerity, Discipline::Majesty, Discipline::Vigor], - Clan::Gangrel => &[ - Discipline::Animalism, - Discipline::Protean, - Discipline::Resilience, - ], - Clan::Mekhet => &[ - Discipline::Auspex, - Discipline::Celerity, - Discipline::Obfuscate, - ], - Clan::Nosferatu => &[ - Discipline::Nightmare, - Discipline::Obfuscate, - Discipline::Vigor, - ], - Clan::Ventrue => &[ - Discipline::Animalism, - Discipline::Dominate, - Discipline::Resilience, - ], - Clan::_Custom(_, disciplines, _) => disciplines, - } - } - pub fn get_favored_attributes(&self) -> &[Attribute; 2] { - match self { - Clan::Daeva => &[Attribute::Dexterity, Attribute::Manipulation], - Clan::Gangrel => &[Attribute::Composure, Attribute::Stamina], - Clan::Mekhet => &[Attribute::Intelligence, Attribute::Wits], - Clan::Nosferatu => &[Attribute::Composure, Attribute::Strength], - Clan::Ventrue => &[Attribute::Presence, Attribute::Resolve], - Clan::_Custom(_, _, attributes) => attributes, - } - } -} - -#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, VariantName, AllVariants)] -pub enum Covenant { - CarthianMovement, - CircleOfTheCrone, - Invictus, - LanceaEtSanctum, - OrdoDracul, - _Custom(String), -} - -#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, AllVariants, VariantName)] -pub enum Bloodline { - _Custom(String, Option<[Discipline; 4]>), -} - -#[derive( - Clone, - Debug, - PartialEq, - PartialOrd, - Eq, - Ord, - Serialize, - Deserialize, - Hash, - VariantName, - AllVariants, -)] -pub enum Discipline { - Animalism, - Auspex, - Celerity, - Dominate, - Majesty, - Nightmare, - Obfuscate, - Protean, - Resilience, - Vigor, - _Custom(String), -} - -impl Discipline { - #[warn(clippy::cast_possible_wrap)] - pub fn get_modifiers(&self, value: u16) -> Vec { - match self { - Discipline::Celerity => { - vec![Modifier::new(Trait::Defense, value, ModifierOp::Add)] - } - Discipline::Resilience => { - vec![Modifier::new(Attribute::Stamina, value, ModifierOp::Add)] - } - Discipline::Vigor => vec![Modifier::new(Attribute::Strength, value, ModifierOp::Add)], - _ => vec![], - } - } -} - -impl From for Ability { - fn from(val: Discipline) -> Self { - Ability::Discipline(val) - } -} - -pub enum MaskDirge { - Authoritarian, - Child, - Competitor, - Conformist, - Conspirator, - Courtesan, - CultLeader, - Deviant, - Follower, - Guru, - Idealist, - Jester, - Junkie, - Martyr, - Masochist, - Monster, - Nomad, - Nurturer, - Perfectionist, - Penitent, - Questioner, - Rebel, - Scholar, - SocialChameleon, - Spy, - Survivor, - Visionary, - _Custom(String), -} - -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash, AllVariants, VariantName)] -pub enum VampireMerit { - AcuteSenses, - Atrocious, - Beloved, // TY - Bloodhound, - CallTheBeast, // TY - ClawsOfTheUnholy, - CloseFamily, - Cutthroat, - DistinguishedPalate, - DreamVisions, // Mekhet - Enticing, - FeedingGrounds(String), - HeartOfStone, // TY - Herd, - HoneyTrap, - KindredStatus(String), // Status? - KissOfTheSuccubus, - Lineage(String), - LingeringDreams, // DE2 - MajorDomo, // TY - MarriedByBlood, // TY - PackAlpha, - ReceptiveMind, // TY - RevenantImpostor, // HD - SaviorOfTheLost, // TY - SpecialTreat, // TY - SwarmForm, - Touchstone, - UndeadMenses, - UnnaturalAffinity, - UnsettlingGaze, - - CacophonySavvy, - Courtoisie, - Crusade, - DynastyMembership, - KindredDueling, - MobilizeOutrage, // SotC, Carthian - RidingTheWave, - RitesOfTheImpaled, // SotC, Ordo, Sworn - TempleGuardian, // SotC, Crone - - // Elder Merits, - - // Revenant Merits - - // Covenant Merits - - // Ordo Dracul - IndependentStudy, // SotC - SecretSocietyJunkie, - Sworn(String), - TwilightJudge, // SotC - - NestGuardian, -} - -impl VampireMerit { - pub fn is_available( - &self, - character: &crate::prelude::Character, - attributes: &Attributes, - skills: &Skills, - ) -> bool { - matches!(character.splat, Splat::Vampire(..)) - && match self { - // VampireMerit::Atrocious => todo!(), // Not Enticing or Cutthroat - VampireMerit::Bloodhound => attributes.wits >= 3, - VampireMerit::CallTheBeast => character.integrity < 5, - VampireMerit::ClawsOfTheUnholy => { - *character - .abilities - .get(&Discipline::Protean.into()) - .unwrap_or(&0) >= 4 - } - // VampireMerit::Cutthroat => todo!(), // Not Enticing or Atrocious - VampireMerit::DreamVisions => { - matches!(character.splat, Splat::Vampire(Clan::Mekhet, ..)) - } - // VampireMerit::Enticing => todo!(), // Not Cutthroat or Atrocious - // VampireMerit::FeedingGrounds(_) => todo!(), - // VampireMerit::HeartOfStone => todo!(), // Feeding Grounds - // VampireMerit::HoneyTrap => todo!(), // Not a Revenant - // VampireMerit::KindredStatus(_) => todo!(), - VampireMerit::KissOfTheSuccubus => { - matches!(character.splat, Splat::Vampire(Clan::Daeva, ..)) - } - // VampireMerit::Lineage(_) => todo!(), Clan Status - VampireMerit::LingeringDreams => { - matches!(character.splat, Splat::Vampire(Clan::Mekhet, ..)) - } // Dream Visions - VampireMerit::PackAlpha => { - matches!(character.splat, Splat::Vampire(Clan::Gangrel, ..)) - } - VampireMerit::ReceptiveMind => { - character.power >= 6 - && *character - .abilities - .get(&Discipline::Auspex.into()) - .unwrap_or(&0) >= 4 - } - VampireMerit::RevenantImpostor => { - attributes.manipulation >= 3 && skills.subterfuge >= 2 - } - VampireMerit::SwarmForm => { - *character - .abilities - .get(&Discipline::Protean.into()) - .unwrap_or(&0) >= 4 - } - VampireMerit::UnsettlingGaze => { - matches!(character.splat, Splat::Vampire(Clan::Nosferatu, ..)) - } - - // VampireMerit::CacophonySavvy => todo!(), // City Status - VampireMerit::Courtoisie => { - attributes.composure >= 3 && skills.socialize >= 2 && skills.weaponry >= 2 - } // Invictus Status - VampireMerit::Crusade => { - attributes.resolve >= 3 && skills.occult >= 2 && skills.weaponry >= 2 - } // Theban Sorcery 2 or Sorc Eunuch - // VampireMerit::DynastyMembership => todo!(), // Clan Status - VampireMerit::KindredDueling => attributes.composure >= 3 && skills.weaponry >= 2, - VampireMerit::MobilizeOutrage => { - character.max_willpower() >= 5 && skills.brawl >= 2 - } // Carthian Status - VampireMerit::RidingTheWave => attributes.composure >= 3 && attributes.resolve >= 3, - VampireMerit::RitesOfTheImpaled => { - attributes.resolve >= 3 && attributes.stamina >= 3 && skills.weaponry >= 2 - } // Sworn - VampireMerit::TempleGuardian => { - skills.athletics >= 2 && skills.brawl >= 2 && skills.weaponry >= 2 - } // Crone Status - // VampireMerit::IndependentStudy => todo!(), - // VampireMerit::SecretSocietyJunkie => todo!(), - // VampireMerit::Sworn(_) => todo!(), - // VampireMerit::TwilightJudge => todo!(), - // VampireMerit::NestGuardian => todo!(), - _ => true, - } - } - - pub fn get_modifiers(&self, value: u16) -> Vec { - Vec::new() - } -} - -impl From for Merit { - fn from(merit: VampireMerit) -> Self { - Merit::Vampire(merit) - } -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct Devotion { - name: String, - cost: String, - disciplines: Vec<(Discipline, u16)>, - dice_pool: DicePool, - book: String, - page: u16, -} diff --git a/cofd/lib/src/splat/werewolf.rs b/cofd/lib/src/splat/werewolf.rs deleted file mode 100644 index 8833c72..0000000 --- a/cofd/lib/src/splat/werewolf.rs +++ /dev/null @@ -1,686 +0,0 @@ -use serde::{Deserialize, Serialize}; -use std::collections::HashMap; - -use cofd_util::VariantName; - -use super::{ability::Ability, Merit, NameKey, Splat}; -use crate::{ - character::modifier::{Modifier, ModifierOp, ModifierTarget}, - dice_pool::DicePool, - prelude::*, -}; - -#[derive(Clone, Default, Debug, Serialize, Deserialize, PartialEq, Eq)] -pub struct KuruthTriggerSet { - pub passive: String, - pub common: String, - pub specific: String, -} - -#[derive(Clone, VariantName)] -pub enum KuruthTrigger { - Passive, - Common, - Specific, -} - -impl KuruthTrigger { - pub fn all(&self) -> [KuruthTrigger; 3] { - [Self::Passive, Self::Common, Self::Specific] - } -} - -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, AllVariants)] -pub enum KuruthTriggers { - Blood, - Moon, - TheOther, - Pack, - Territory, - Wound, - _Custom(KuruthTriggerSet), -} - -impl NameKey for KuruthTriggers { - fn name_key(&self) -> String { - if let Some(name) = self.name() { - format!("kuruth-triggers.{name}") - } else { - "custom".to_string() - } - } -} - -impl Default for KuruthTriggers { - fn default() -> Self { - Self::_Custom(Default::default()) - } -} - -impl KuruthTriggers { - pub fn name(&self) -> Option<&str> { - match self { - KuruthTriggers::Blood => Some("blood"), - KuruthTriggers::Moon => Some("moon"), - KuruthTriggers::TheOther => Some("the_other"), - KuruthTriggers::Pack => Some("pack"), - KuruthTriggers::Territory => Some("territory"), - KuruthTriggers::Wound => Some("wound"), - KuruthTriggers::_Custom(_) => None, - } - } - - pub fn get_triggers(&self) -> KuruthTriggerSet { - match self { - KuruthTriggers::Blood => KuruthTriggerSet { - passive: "Smelling human blood.".to_owned(), - common: "Tasting human blood.".to_owned(), - specific: "Swallowing human blood.".to_owned(), - }, - KuruthTriggers::Moon => KuruthTriggerSet { - passive: "Your auspice moon is in the sky.".to_owned(), - common: "You witness your auspice moon in the sky.".to_owned(), - specific: "Hear a wolf or werewolf howl when your auspice moon is in the sky." - .to_owned(), - }, - KuruthTriggers::TheOther => KuruthTriggerSet { - passive: "You come within 10 yards of a supernatural creature.".to_owned(), - common: "You witness a supernatural creature doing something obviously inhuman." - .to_owned(), - specific: "You are the target of a supernatural power.".to_owned(), - }, - KuruthTriggers::Pack => KuruthTriggerSet { - passive: "A pack member takes lethal damage.".to_owned(), - common: "Seeing someone attack a pack member.".to_owned(), - specific: "You cause lethal damage to a pack member.".to_owned(), - }, - KuruthTriggers::Territory => KuruthTriggerSet { - passive: "A werewolf you don't know enters your territory without permission." - .to_owned(), - common: "You see a werewolf you don't know in your territory.".to_owned(), - specific: - "A werewolf you don't know challenges your pack's ability to do its duty." - .to_owned(), - }, - KuruthTriggers::Wound => KuruthTriggerSet { - passive: "Being in the area of a Wound.".to_owned(), - common: "Interacting with a Wound-born spirit.".to_owned(), - specific: "Being attacked by a Wound-born spirit.".to_owned(), - }, - KuruthTriggers::_Custom(set) => set.clone(), - } - } -} - -#[derive(Clone, Default, Debug, Serialize, Deserialize, PartialEq, Eq)] -#[serde(default)] -pub struct WerewolfData { - pub skill_bonus: Option, - pub form: Form, - // pub moon_gifts: BTreeMap, - pub triggers: KuruthTriggers, - pub hunters_aspect: Option, - pub moon_gifts: HashMap, - pub shadow_gifts: Vec, - pub wolf_gifts: Vec, - pub rites: Vec, -} - -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, VariantName)] -pub enum HuntersAspect { - Monstrous, - Isolating, - Blissful, - Mystic, - Dominant, - - Fanatical, - Frenzied, - Agnoized, - Insidious, - Implacable, - Primal, - - _Custom(String), -} - -impl NameKey for HuntersAspect { - fn name_key(&self) -> String { - format!("werewolf.{}", self.name()) - } -} - -#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, VariantName, AllVariants)] -pub enum Auspice { - Cahalith, - Elodoth, - Irraka, - Ithaeur, - Rahu, - _Custom( - String, - [Skill; 3], - Renown, - MoonGift, - Box<[ShadowGift; 2]>, - HuntersAspect, - ), -} - -impl Auspice { - pub fn get_skills(&self) -> &[Skill; 3] { - match self { - Auspice::Cahalith => &[Skill::Crafts, Skill::Expression, Skill::Persuasion], - Auspice::Elodoth => &[Skill::Empathy, Skill::Investigation, Skill::Politics], - Auspice::Irraka => &[Skill::Larceny, Skill::Stealth, Skill::Subterfuge], - Auspice::Ithaeur => &[Skill::AnimalKen, Skill::Medicine, Skill::Occult], - Auspice::Rahu => &[Skill::Brawl, Skill::Intimidation, Skill::Survival], - Auspice::_Custom(_, skills, ..) => skills, - } - } - - pub fn get_renown(&self) -> &Renown { - match self { - Auspice::Cahalith => &Renown::Glory, - Auspice::Elodoth => &Renown::Honor, - Auspice::Irraka => &Renown::Cunning, - Auspice::Ithaeur => &Renown::Wisdom, - Auspice::Rahu => &Renown::Purity, - Auspice::_Custom(_, _, renown, ..) => renown, - } - } - - pub fn get_gifts(&self) -> &[ShadowGift; 2] { - match self { - Auspice::Cahalith => &[ShadowGift::Inspiration, ShadowGift::Knowledge], - Auspice::Elodoth => &[ShadowGift::Insight, ShadowGift::Warding], - Auspice::Irraka => &[ShadowGift::Evasion, ShadowGift::Stealth], - Auspice::Ithaeur => &[ShadowGift::Elementals, ShadowGift::Shaping], - Auspice::Rahu => &[ShadowGift::Dominance, ShadowGift::Strength], - Auspice::_Custom(.., gifts, _) => gifts, - } - } - - pub fn get_moon_gift(&self) -> &MoonGift { - match self { - Auspice::Cahalith => &MoonGift::Gibbous, - Auspice::Elodoth => &MoonGift::Half, - Auspice::Irraka => &MoonGift::New, - Auspice::Ithaeur => &MoonGift::Crescent, - Auspice::Rahu => &MoonGift::Full, - Auspice::_Custom(.., moon_gift, _, _) => moon_gift, - } - } - - pub fn get_hunters_aspect(&self) -> &HuntersAspect { - match self { - Auspice::Cahalith => &HuntersAspect::Monstrous, - Auspice::Elodoth => &HuntersAspect::Isolating, - Auspice::Irraka => &HuntersAspect::Blissful, - Auspice::Ithaeur => &HuntersAspect::Mystic, - Auspice::Rahu => &HuntersAspect::Dominant, - Auspice::_Custom(.., aspect) => aspect, - } - } -} - -#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, VariantName, AllVariants)] -pub enum PureTribe { - FireTouched, - IvoryClaws, - PredatorKings, - _Custom( - String, - Renown, - [Renown; 2], - [Skill; 3], - [HuntersAspect; 2], - Box<[ShadowGift; 4]>, - ), -} - -impl PureTribe { - pub fn get_secondary_renown(&self) -> &[Renown; 2] { - match self { - Self::FireTouched => &[Renown::Cunning, Renown::Glory], - Self::IvoryClaws => &[Renown::Glory, Renown::Honor], - Self::PredatorKings => &[Renown::Purity, Renown::Wisdom], - Self::_Custom(_, _, renown, ..) => renown, - } - } - - pub fn get_skills(&self) -> &[Skill; 3] { - match self { - Self::FireTouched => &[Skill::Expression, Skill::Occult, Skill::Subterfuge], - Self::IvoryClaws => &[Skill::Intimidation, Skill::Persuasion, Skill::Politics], - Self::PredatorKings => &[Skill::AnimalKen, Skill::Brawl, Skill::Crafts], - Self::_Custom(.., skills, _, _) => skills, - } - } - - pub fn get_hunters_aspects(&self) -> &[HuntersAspect; 2] { - match self { - Self::FireTouched => &[HuntersAspect::Fanatical, HuntersAspect::Frenzied], - Self::IvoryClaws => &[HuntersAspect::Agnoized, HuntersAspect::Insidious], - Self::PredatorKings => &[HuntersAspect::Implacable, HuntersAspect::Primal], - Self::_Custom(.., aspects, _) => aspects, - } - } -} - -impl From for Tribe { - fn from(pure: PureTribe) -> Self { - Tribe::Pure(pure) - } -} - -#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, AllVariants, VariantName)] -pub enum Tribe { - BloodTalons, - BoneShadows, - HuntersInDarkness, - IronMasters, - StormLords, - #[expand] - Pure(PureTribe), - _Custom(String, Renown, Box<[ShadowGift; 3]>), -} - -impl Tribe { - pub fn get_renown(&self) -> &Renown { - match self { - Self::BloodTalons => &Renown::Glory, - Self::BoneShadows => &Renown::Wisdom, - Self::HuntersInDarkness => &Renown::Purity, - Self::IronMasters => &Renown::Cunning, - Self::StormLords => &Renown::Honor, - // Tribe::GhostWolves => &None, - Self::Pure(tribe) => match tribe { - PureTribe::FireTouched => &Renown::Wisdom, - PureTribe::IvoryClaws => &Renown::Purity, - PureTribe::PredatorKings => &Renown::Glory, - PureTribe::_Custom(_, renown, ..) => renown, - }, - Self::_Custom(_, renown, _) => renown, - } - } - - pub fn get_gifts(&self) -> Vec { - match self { - Tribe::BloodTalons => vec![ - ShadowGift::Inspiration, - ShadowGift::Rage, - ShadowGift::Strength, - ], - Tribe::BoneShadows => vec![ - ShadowGift::Death, - ShadowGift::Elementals, - ShadowGift::Insight, - ], - Tribe::HuntersInDarkness => { - vec![ShadowGift::Nature, ShadowGift::Stealth, ShadowGift::Warding] - } - Tribe::IronMasters => vec![ - ShadowGift::Knowledge, - ShadowGift::Shaping, - ShadowGift::Technology, - ], - Tribe::StormLords => vec![ - ShadowGift::Evasion, - ShadowGift::Dominance, - ShadowGift::Weather, - ], - Tribe::Pure(tribe) => match tribe { - PureTribe::FireTouched => vec![ - ShadowGift::Disease, - ShadowGift::Fervor, - ShadowGift::Insight, - ShadowGift::Inspiration, - ], - PureTribe::IvoryClaws => vec![ - ShadowGift::Agony, - ShadowGift::Blood, - ShadowGift::Dominance, - ShadowGift::Warding, - ], - PureTribe::PredatorKings => vec![ - ShadowGift::Hunger, - ShadowGift::Nature, - ShadowGift::Rage, - ShadowGift::Strength, - ], - PureTribe::_Custom(.., gifts) => gifts.to_vec(), - }, - // Tribe::GhostWolves => &None, - Tribe::_Custom(.., gifts) => gifts.to_vec(), - } - } -} - -#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, AllVariants, VariantName)] -pub enum Lodge { - _Custom(String), -} - -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash, VariantName, AllVariants)] -pub enum Renown { - Purity, - Glory, - Honor, - Wisdom, - Cunning, -} - -impl From for Ability { - fn from(val: Renown) -> Self { - Ability::Renown(val) - } -} - -cofd_macros::gifts!(); - -#[derive(Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize)] -pub enum Gift { - Moon(MoonGift), - Shadow(ShadowGift), - Wolf(WolfGift), -} - -impl MoonGift { - pub fn get_modifiers(&self, value: u16) -> Vec { - match self { - // MoonGift::Crescent => vec![], - MoonGift::Full => { - if value > 2 { - vec![Modifier::new( - Trait::Health, - Ability::Renown(Renown::Purity), - ModifierOp::Add, - )] - } else { - vec![] - } - } - // MoonGift::Gibbous => vec![], - // MoonGift::Half => vec![], - // MoonGift::New => vec![], - // MoonGift::_Custom(_) => todo!(), - _ => vec![], - } - } -} - -impl NameKey for MoonGift { - fn name_key(&self) -> String { - format!("moon-gifts.{}", self.name()) - } -} - -impl From for Ability { - fn from(gift: MoonGift) -> Self { - Ability::MoonGift(gift) - } -} - -impl NameKey for ShadowGift { - fn name_key(&self) -> String { - format!("shadow-gifts.{}", self.name()) - } -} - -impl NameKey for WolfGift { - fn name_key(&self) -> String { - format!("wolf-gifts.{}", self.name()) - } -} - -#[derive( - Clone, - Debug, - Serialize, - Deserialize, - Default, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - VariantName, - AllVariants, -)] -pub enum Form { - #[default] - Hishu, - Dalu, - Gauru, - Urshul, - Urhan, -} - -impl Form { - #[allow(clippy::too_many_lines)] - pub fn get_modifiers(&self) -> Vec { - match self { - Form::Hishu => vec![Modifier::new(Trait::Perception, 1, ModifierOp::Add)], - Form::Dalu => vec![ - Modifier::new(Attribute::Strength, 1, ModifierOp::Add), - Modifier::new(Attribute::Stamina, 1, ModifierOp::Add), - Modifier::new(Attribute::Manipulation, -1, ModifierOp::Add), - Modifier::new(Trait::Size, 1, ModifierOp::Add), - Modifier::new(Trait::Perception, 2, ModifierOp::Add), - ], - Form::Gauru => vec![ - Modifier::new(Attribute::Strength, 3, ModifierOp::Add), - Modifier::new(Attribute::Dexterity, 1, ModifierOp::Add), - Modifier::new(Attribute::Stamina, 2, ModifierOp::Add), - Modifier::new(Trait::Size, 2, ModifierOp::Add), - Modifier::new(Trait::Perception, 3, ModifierOp::Add), - ], - Form::Urshul => vec![ - Modifier::new(Attribute::Strength, 2, ModifierOp::Add), - Modifier::new(Attribute::Dexterity, 2, ModifierOp::Add), - Modifier::new(Attribute::Stamina, 2, ModifierOp::Add), - Modifier::new(Attribute::Manipulation, -1, ModifierOp::Add), - Modifier::new(Trait::Size, 1, ModifierOp::Add), - Modifier::new(Trait::Speed, 3, ModifierOp::Add), - Modifier::new(Trait::Perception, 3, ModifierOp::Add), - ], - Form::Urhan => vec![ - Modifier::new(Attribute::Dexterity, 2, ModifierOp::Add), - Modifier::new(Attribute::Stamina, 1, ModifierOp::Add), - Modifier::new(Attribute::Manipulation, -1, ModifierOp::Add), - Modifier::new(Trait::Size, -1, ModifierOp::Add), - Modifier::new(Trait::Speed, 3, ModifierOp::Add), - Modifier::new(Trait::Perception, 4, ModifierOp::Add), - ], - } - } - - pub fn modifiers() -> Vec { - // match self { - vec![ - // - Modifier::conditional(Trait::Perception, 1, ModifierOp::Add, Form::Hishu), - // - Modifier::conditional(Attribute::Strength, 1, ModifierOp::Add, Form::Dalu), - Modifier::conditional(Attribute::Stamina, 1, ModifierOp::Add, Form::Dalu), - Modifier::conditional(Attribute::Manipulation, -1, ModifierOp::Add, Form::Dalu), - Modifier::conditional(Trait::Size, 1, ModifierOp::Add, Form::Dalu), - Modifier::conditional(Trait::Perception, 2, ModifierOp::Add, Form::Dalu), - // - Modifier::conditional(Attribute::Strength, 3, ModifierOp::Add, Form::Gauru), - Modifier::conditional(Attribute::Dexterity, 1, ModifierOp::Add, Form::Gauru), - Modifier::conditional(Attribute::Stamina, 2, ModifierOp::Add, Form::Gauru), - Modifier::conditional(Trait::Size, 2, ModifierOp::Add, Form::Gauru), - Modifier::conditional(Trait::Perception, 3, ModifierOp::Add, Form::Gauru), - // - Modifier::conditional(Attribute::Strength, 2, ModifierOp::Add, Form::Urshul), - Modifier::conditional(Attribute::Dexterity, 2, ModifierOp::Add, Form::Urshul), - Modifier::conditional(Attribute::Stamina, 2, ModifierOp::Add, Form::Urshul), - Modifier::conditional(Attribute::Manipulation, -1, ModifierOp::Add, Form::Urshul), - Modifier::conditional(Trait::Size, 1, ModifierOp::Add, Form::Urshul), - Modifier::conditional(Trait::Speed, 3, ModifierOp::Add, Form::Urshul), - Modifier::conditional(Trait::Perception, 3, ModifierOp::Add, Form::Urshul), - // - Modifier::conditional(Attribute::Dexterity, 2, ModifierOp::Add, Form::Urhan), - Modifier::conditional(Attribute::Stamina, 1, ModifierOp::Add, Form::Urhan), - Modifier::conditional(Attribute::Manipulation, -1, ModifierOp::Add, Form::Urhan), - Modifier::conditional(Trait::Size, -1, ModifierOp::Add, Form::Urhan), - Modifier::conditional(Trait::Speed, 3, ModifierOp::Add, Form::Urhan), - Modifier::conditional(Trait::Perception, 4, ModifierOp::Add, Form::Urhan), - ] - } -} - -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, VariantName)] -pub enum Rite { - SacredHunt, - _Custom(String), -} - -impl NameKey for Rite { - fn name_key(&self) -> String { - format!("werewolf.{}", self.name()) - } -} - -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash, AllVariants, VariantName)] -pub enum WerewolfMerit { - FavoredForm { - form: Form, - // - }, - EfficientKiller, - Totem, - - InstinctiveDefense, -} - -impl WerewolfMerit { - pub fn is_available(&self, character: &crate::prelude::Character) -> bool { - if matches!(character.splat, Splat::Werewolf(..)) { - match self { - Self::InstinctiveDefense => { - character.power >= 2 && character.skills().athletics >= 2 - } - _ => true, - } - } else { - false - } - } - - pub fn get_modifiers(&self, value: u16) -> Vec { - match self { - Self::InstinctiveDefense => { - if value == 2 { - vec![ - Modifier::conditional( - Trait::Defense, - DicePool::max(Attribute::Wits, Attribute::Dexterity), - ModifierOp::Set, - Form::Urhan, - ), - Modifier::conditional( - Trait::Defense, - DicePool::max(Attribute::Wits, Attribute::Dexterity), - ModifierOp::Set, - Form::Urshul, - ), - ] - } else { - vec![] - } - } - _ => vec![], - } - } -} - -impl From for Merit { - fn from(merit: WerewolfMerit) -> Self { - Merit::Werewolf(merit) - } -} - -pub fn get_form_trait(character: &Character, form: &Form, target: &ModifierTarget) -> i16 { - let Splat::Werewolf(.., data) = &character.splat else { - unreachable!() - }; - let active_form = &data.form; - - let value = match target { - ModifierTarget::BaseAttribute(_) - | ModifierTarget::BaseSkill(_) - | ModifierTarget::Skill(_) => unreachable!(), - ModifierTarget::Attribute(attr) => *character.attributes().get(&attr) as i16, - ModifierTarget::Trait(trait_) => character.get_trait(trait_) as i16, - }; - - if form.eq(active_form) { - value - } else { - let modifiers = match target { - ModifierTarget::Trait(trait_) => match trait_ { - Trait::Speed => { - form_modifier(character, form, &Attribute::Dexterity) - + form_modifier(character, form, &Attribute::Strength) - - form_modifier(character, active_form, &Attribute::Dexterity) - - form_modifier(character, active_form, &Attribute::Strength) - } - Trait::Initative => { - form_modifier(character, form, &Attribute::Dexterity) - + form_modifier(character, form, &Attribute::Composure) - - form_modifier(character, active_form, &Attribute::Dexterity) - - form_modifier(character, active_form, &Attribute::Composure) - } - Trait::Defense => { - // let active_form_pool = form_pool(character, active_form, target); - // let form_pool = form_pool(character, form, target); - - // let attributes = character.attributes(); - // println!("{active_form_pool} - {form_pool}"); - - // let attributes = character.attributes(); - // let dex = attributes.dexterity as i16 - // + form_modifier(character, form, &Attribute::Dexterity) - // - form_modifier(character, active_form, &Attribute::Dexterity); - // let wits = attributes.wits as i16 - // + form_modifier(character, form, &Attribute::Wits) - // - form_modifier(character, active_form, &Attribute::Wits); - - // TODO: uhh make defense display in forms work. - return value; // Active Form Defense - } - _ => 0, - }, - _ => 0, - }; - - let active_form_modifier = form_modifier(character, active_form, target); - let form_mod = form_modifier(character, form, target); - - // println!("{form:?} {target:?} = {value} - {active_form_modifier} + {form_mod}"); - value - active_form_modifier + form_mod + modifiers - } -} - -fn form_modifier( - character: &Character, - form: &Form, - target: &(impl Into + Clone), -) -> i16 { - character - .get_conditional_modifier((*target).clone(), form.clone()) - .unwrap_or(0) -} - -fn form_pool( - character: &Character, - form: &Form, - target: &(impl Into + Clone), -) -> DicePool { - character - .get_conditional_pool((*target).clone(), form.clone()) - .unwrap_or(DicePool::Mod(0)) -} diff --git a/cofd/macros/Cargo.toml b/cofd/macros/Cargo.toml deleted file mode 100644 index ad8e327..0000000 --- a/cofd/macros/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "cofd-macros" -version.workspace = true -authors.workspace = true -edition.workspace = true -license.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -proc-macro = true - -[dependencies] -cofd-util.workspace = true - -proc-macro2 = "1" -quote = "1" -syn = "2" - -ron.workspace = true \ No newline at end of file diff --git a/cofd/macros/src/lib.rs b/cofd/macros/src/lib.rs deleted file mode 100644 index ce63176..0000000 --- a/cofd/macros/src/lib.rs +++ /dev/null @@ -1,149 +0,0 @@ -#![feature(let_chains)] -use std::{env, fs, path::Path}; - -use proc_macro2::{Span, TokenStream}; -use quote::quote; -use syn::Error; - -use cofd_util::scraper::{Gift, Merit}; - -macro_rules! derive_error { - ($string: tt) => { - Error::new(Span::call_site(), $string) - .to_compile_error() - .into() - }; -} - -#[proc_macro] -pub fn gifts(_input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let path = Path::new(&env::var("CARGO_MANIFEST_DIR").expect("")) - .join("data") - .join("gifts.ron"); - - let Ok(str) = fs::read_to_string(path) else { - return derive_error!("Error reading gits.ron file"); - }; - - let vec: Vec = ron::from_str(&str).expect("Parsing error"); - - let mut moon_gift_variants = TokenStream::new(); - let mut shadow_gift_variants = TokenStream::new(); - let mut wolf_gift_variants = TokenStream::new(); - let mut facet_variants = TokenStream::new(); - - let mut shadow_gift_facets_variants = TokenStream::new(); - let mut wolf_gift_facets_variants = TokenStream::new(); - - for gift in vec { - if let Ok(name) = gift.name.parse::() { - let (ts, ts2) = match gift.type_.as_str() { - "Moon" => (&mut moon_gift_variants, None), - "Shadow" => ( - &mut shadow_gift_variants, - Some(&mut shadow_gift_facets_variants), - ), - "Wolf" => ( - &mut wolf_gift_variants, - Some(&mut wolf_gift_facets_variants), - ), - _ => return derive_error!("Unkown type"), - }; - - ts.extend(quote! { - #name, - }); - - let mut facets_arr = TokenStream::new(); - for facet in gift.facets { - if let Ok(facet_name) = facet.name().parse::() { - facet_variants.extend(quote! { - #facet_name, - }); - facets_arr.extend(quote! { - Facet::#facet_name, - }); - } - } - if let Some(ts2) = ts2 { - ts2.extend(quote! { - Self::#name => &[ - #facets_arr - ], - }); - } - } - } - - let expanded = quote! { - #[derive( - Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize, VariantName, AllVariants, Hash - )] - pub enum MoonGift { - #moon_gift_variants - _Custom(String) - } - - #[derive( - Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize, VariantName, AllVariants, - )] - pub enum ShadowGift { - #shadow_gift_variants - _Custom(String, [Facet; 5]) - } - - #[derive( - Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize, VariantName, AllVariants, - )] - pub enum WolfGift { - #wolf_gift_variants - _Custom(String, [Facet; 5]) - } - - #[derive( - Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize, VariantName, AllVariants, - )] - pub enum Facet { - #facet_variants - _Custom(String) - } - - impl ShadowGift { - pub fn get_facets(&self) -> &[Facet; 5] { - match self { - #shadow_gift_facets_variants - Self::_Custom(.., facets) => facets - } - } - } - - impl WolfGift { - pub fn get_facets(&self) -> &[Facet; 5] { - match self { - #wolf_gift_facets_variants - Self::_Custom(.., facets) => facets - } - } - } - }; - - proc_macro::TokenStream::from(expanded) -} - -#[proc_macro] -pub fn merits(_input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let path = Path::new(&env::var("CARGO_MANIFEST_DIR").expect("")) - .join("data") - .join("merits_universal.ron"); - - let Ok(str) = fs::read_to_string(path) else { - return derive_error!("Error reading merits_universal.ron file"); - }; - - let vec: Vec = ron::from_str(&str).expect("Parsing error"); - for merit in vec {} - - let expanded = quote! {}; - - proc_macro::TokenStream::from(expanded) -} diff --git a/cofd/util/Cargo.toml b/cofd/util/Cargo.toml deleted file mode 100644 index 261da1f..0000000 --- a/cofd/util/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "cofd-util" -version.workspace = true -authors.workspace = true -edition.workspace = true -license.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -cofd-derive.workspace = true - -serde = { version = "1", features = ["derive"] } \ No newline at end of file diff --git a/cofd/util/src/lib.rs b/cofd/util/src/lib.rs deleted file mode 100644 index 249a0c7..0000000 --- a/cofd/util/src/lib.rs +++ /dev/null @@ -1,26 +0,0 @@ -#![feature(generic_const_exprs)] - -pub mod scraper; - -extern crate cofd_derive; - -pub use cofd_derive::*; - -pub trait VariantName { - fn name(&self) -> &str; -} - -impl VariantName for Box -where - T: VariantName, -{ - fn name(&self) -> &str { - self.as_ref().name() - } -} - -pub trait AllVariants { - type T; - const N: usize; - fn all() -> [Self::T; Self::N]; -} diff --git a/cofd/util/src/scraper/mod.rs b/cofd/util/src/scraper/mod.rs deleted file mode 100644 index 6e4378e..0000000 --- a/cofd/util/src/scraper/mod.rs +++ /dev/null @@ -1,94 +0,0 @@ -use serde::{Deserialize, Serialize}; - -// pub enum Data { -// Gift(Gift), -// Facet(Facet), -// } - -#[derive(Debug, Serialize, Deserialize)] -pub struct Gift { - pub name: String, - #[serde(rename = "type")] - pub type_: String, - pub facets: Vec, -} - -impl Gift { - pub fn new(name: String, type_: String) -> Self { - Self { - name, - type_, - facets: vec![], - } - } -} - -#[derive(Debug, Serialize, Deserialize)] -pub enum Facet { - // Moon Gift - Moon { name: String, level: u16 }, - // Wolf/Shadow Gift - Other { name: String, renown: String }, - // // pub cost: String, - // // pub pool: String, - // // pub action: String, - // // pub duration: String, - // // pub description: String, - // // pub reference: String, -} - -impl Facet { - pub fn name(&self) -> &String { - match self { - Self::Moon { name, .. } => name, - Self::Other { name, .. } => name, - } - } -} - -#[derive(Debug, Serialize, Deserialize)] -pub enum MeritType { - Mental, - Physical, - Social, - Supernatural, - Fightning, -} - -#[derive(Debug, Serialize, Deserialize)] -pub enum MeritRating { - Number(u8), - Range(u8, u8), - Vec(Vec), -} - -// #[derive(Debug, Serialize, Deserialize)] -// pub enum Requirement { -// Attribute(String, u8), -// Skill(String, u8), -// } - -#[derive(Debug, Serialize, Deserialize)] -pub struct Merit { - name: String, - cost: MeritRating, - // requirements: Vec, - requirements: Option, - type_: MeritType, -} - -impl Merit { - pub fn new( - name: String, - cost: MeritRating, - requirements: Option, - type_: MeritType, - ) -> Self { - Self { - name, - cost, - requirements, - type_, - } - } -} diff --git a/cofd/xtask/Cargo.toml b/cofd/xtask/Cargo.toml deleted file mode 100644 index 4c28d34..0000000 --- a/cofd/xtask/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -name = "cofd-xtask" -version.workspace = true -authors.workspace = true -edition.workspace = true -license.workspace = true -publish = false - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -# cofd.workspace = true -cofd-util.workspace = true - -ron.workspace = true - -tokio = { version = "1", features = ["full"]} -reqwest = "0.11" -scraper = "0.16" - -convert_case = "0.6" - -anyhow = "1" -lazy_static = "1" \ No newline at end of file diff --git a/cofd/xtask/src/bin/gifts.rs b/cofd/xtask/src/bin/gifts.rs deleted file mode 100644 index 87c90e6..0000000 --- a/cofd/xtask/src/bin/gifts.rs +++ /dev/null @@ -1,68 +0,0 @@ -use std::collections::HashMap; - -use cofd_util::scraper::{Facet, Gift}; -use convert_case::Casing; - -pub fn parse_gifts(map: HashMap>>) -> Vec { - let mut gifts = Vec::new(); - - for (cat, vec) in map { - let mut gift = None; - for vec in vec { - if vec.len() == 1 { - if let Some(g) = gift { - gifts.push(g); - gift = None; - } - - if let Some(name) = vec.first() { - if !name.contains('(') { - gift = Some(Gift::new( - gift_name_to_id(name).to_string(), - cat.split(' ').next().unwrap().to_string(), - )); - } - } - } else if let Some(gift) = &mut gift { - let id = facet_name_to_id(&vec[0]); - - let str = vec[1].clone(); - - if str.contains('•') { - gift.facets.push(Facet::Moon { - name: id, - level: str.chars().count() as u16, - }); - } else { - gift.facets.push(Facet::Other { - name: id, - renown: str, - }); - } - } - } - if let Some(g) = gift { - gifts.push(g); - } - } - - gifts -} - -fn gift_name_to_id(name: &str) -> &str { - if name.contains("of") { - name.split(' ').last().unwrap() - } else { - let next = name.split(' ').next().unwrap(); - if next.contains('\'') { - next.strip_suffix("\'s").unwrap() - } else { - next - } - } -} - -fn facet_name_to_id(name: &str) -> String { - name.replace(['\'', ','], "") - .to_case(convert_case::Case::Pascal) -} diff --git a/cofd/xtask/src/bin/merits.rs b/cofd/xtask/src/bin/merits.rs deleted file mode 100644 index 55853fd..0000000 --- a/cofd/xtask/src/bin/merits.rs +++ /dev/null @@ -1,72 +0,0 @@ -use std::collections::HashMap; - -use cofd_util::scraper::{Merit, MeritType}; -use convert_case::{Case, Casing}; - -pub fn parse_merits(map: HashMap>>) -> Vec { - let mut merits = Vec::new(); - - for (cat, vec) in map { - for vec in vec { - let cost = vec[1].trim(); - let mut rating = cofd_util::scraper::MeritRating::Number(0); - - if cost.chars().all(|char| char.eq(&'•')) { - rating = cofd_util::scraper::MeritRating::Number( - cost.chars().count().try_into().unwrap(), - ); - } else if cost.contains("or") { - let cost = cost.replace("or", ","); - let mut vec: Vec = Vec::new(); - - for part in cost.split(',') { - let part = part.trim(); - if !part.is_empty() { - vec.push(part.chars().count().try_into().unwrap()); - } - } - - if !vec.is_empty() { - rating = cofd_util::scraper::MeritRating::Vec(vec); - } - } else if cost.contains("to") { - let mut split = cost.split("to"); - - let a = split.next().unwrap().chars().count(); - let b = split.next().unwrap().chars().count(); - - rating = cofd_util::scraper::MeritRating::Range( - a.try_into().unwrap(), - b.try_into().unwrap(), - ); - } - - let type_ = match cat.as_str() { - "Mental Merits" => MeritType::Mental, - "Social Merits" => MeritType::Social, - "Physical Merits" => MeritType::Physical, - "Fighting Merits" => MeritType::Fightning, - "Supernatural Merits" => MeritType::Supernatural, - _ => todo!(), - }; - - merits.push(Merit::new( - vec[0].to_case(Case::Pascal), - rating, - if vec[2].is_empty() { - None - } else { - Some(vec[2].clone()) - }, - type_, - )); - } - } - - merits -} - -// fn facet_name_to_id(name: &str) -> String { -// name.replace(['\'', ','], "") -// .to_case(convert_case::Case::Pascal) -// } diff --git a/cofd/xtask/src/bin/scraper.rs b/cofd/xtask/src/bin/scraper.rs deleted file mode 100644 index 2007813..0000000 --- a/cofd/xtask/src/bin/scraper.rs +++ /dev/null @@ -1,127 +0,0 @@ -#![feature(iter_array_chunks)] -use std::collections::HashMap; -use std::path::Path; -use std::{fs, path::PathBuf}; - -use lazy_static::lazy_static; -use reqwest::Url; -use ron::ser::PrettyConfig; -use scraper::{ElementRef, Html, Selector}; - -mod gifts; -mod merits; - -lazy_static! { - static ref PATH: PathBuf = - Path::new(&std::env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR env var")) - .join("..") - .join("lib") - .join("data"); -} - -enum PageType { - Gifts, - Merits, -} - -#[tokio::main] -async fn main() -> Result<(), Box> { - let urls = [ - ("https://codexofdarkness.com/wiki/Gifts", PageType::Gifts), - ( - "https://codexofdarkness.com/wiki/Merits,_Universal", - PageType::Merits, - ), - // ( - // "https://codexofdarkness.com/wiki/Merits,_Vampire", - // PageType::Merits, - // ), - ]; - - let mut handles = Vec::new(); - for (url, page) in urls { - handles.push(tokio::spawn(download(url.to_string(), page))); - } - - for handle in handles { - handle.await.unwrap()?; - } - - Ok(()) -} - -async fn download(url: String, page: PageType) -> anyhow::Result<()> { - let url = Url::parse(&url).expect("Invalid url"); - - let page_name = url - .path_segments() - .expect("Path segments") - .last() - .expect("Last path segment") - .to_string(); - - let path = PATH.join("cache"); - - if !path.exists() { - std::fs::create_dir_all(&path)?; - } - - let name = page_name.replace(',', ""); - let html_path = path.join(format!("{name}.html")); - - let text; - if !html_path.exists() { - println!("Downloading: {url}"); - - let resp = reqwest::get(url).await?; - text = resp.text().await?; - - fs::write(html_path, &text)?; - } else { - text = fs::read_to_string(html_path)?; - } - - parse(&name, &text, page)?; - - Ok(()) -} - -fn parse(page_name: &str, text: &str, page: PageType) -> anyhow::Result<()> { - let document = Html::parse_document(text); - - let selector = Selector::parse(".mw-parser-output > section, h2").unwrap(); - let table_sel = Selector::parse("table").unwrap(); - - let mut map = HashMap::new(); - for [header, section] in document.select(&selector).skip(1).array_chunks() { - let title = header.text().last().expect("Last text in header"); - let table = section.select(&table_sel).next().unwrap(); - - for tr in table - .children() - .last() - .unwrap() - .children() - .filter_map(ElementRef::wrap) - .skip(1) - { - let mut vec = Vec::new(); - for td in tr.children().filter_map(ElementRef::wrap) { - vec.push(td.inner_html().trim().to_string()); - } - - map.entry(title.to_string()).or_insert(Vec::new()).push(vec); - } - } - - let txt = match page { - PageType::Gifts => ron::ser::to_string(&gifts::parse_gifts(map))?, - PageType::Merits => { - ron::ser::to_string_pretty(&merits::parse_merits(map), PrettyConfig::default())? - } // _ => String::new(), - }; - - fs::write(PATH.join(format!("{}.ron", page_name.to_lowercase())), txt)?; - - Ok(()) -} diff --git a/cofd/app/i18n.toml b/i18n.toml similarity index 100% rename from cofd/app/i18n.toml rename to i18n.toml diff --git a/cofd/app/i18n/en-GB/cofd_pc.ftl b/i18n/en-GB/cofd_pc.ftl similarity index 100% rename from cofd/app/i18n/en-GB/cofd_pc.ftl rename to i18n/en-GB/cofd_pc.ftl diff --git a/cofd/app/i18n/en-US/cofd_pc.ftl b/i18n/en-US/cofd_pc.ftl similarity index 100% rename from cofd/app/i18n/en-US/cofd_pc.ftl rename to i18n/en-US/cofd_pc.ftl diff --git a/cofd/app/i18n/pl-PL/cofd_pc.ftl b/i18n/pl-PL/cofd_pc.ftl similarity index 100% rename from cofd/app/i18n/pl-PL/cofd_pc.ftl rename to i18n/pl-PL/cofd_pc.ftl diff --git a/cofd/app/index.html b/index.html similarity index 95% rename from cofd/app/index.html rename to index.html index 05d6988..db0618b 100644 --- a/cofd/app/index.html +++ b/index.html @@ -21,7 +21,7 @@ diff --git a/cofd/app/src/component/attributes.rs b/src/component/attributes.rs similarity index 100% rename from cofd/app/src/component/attributes.rs rename to src/component/attributes.rs diff --git a/cofd/app/src/component/forms.rs b/src/component/forms.rs similarity index 100% rename from cofd/app/src/component/forms.rs rename to src/component/forms.rs diff --git a/cofd/app/src/component/info.rs b/src/component/info.rs similarity index 100% rename from cofd/app/src/component/info.rs rename to src/component/info.rs diff --git a/cofd/app/src/component/integrity.rs b/src/component/integrity.rs similarity index 100% rename from cofd/app/src/component/integrity.rs rename to src/component/integrity.rs diff --git a/cofd/app/src/component/list.rs b/src/component/list.rs similarity index 100% rename from cofd/app/src/component/list.rs rename to src/component/list.rs diff --git a/cofd/app/src/component/merits.rs b/src/component/merits.rs similarity index 100% rename from cofd/app/src/component/merits.rs rename to src/component/merits.rs diff --git a/cofd/app/src/component/mod.rs b/src/component/mod.rs similarity index 100% rename from cofd/app/src/component/mod.rs rename to src/component/mod.rs diff --git a/cofd/app/src/component/skills.rs b/src/component/skills.rs similarity index 100% rename from cofd/app/src/component/skills.rs rename to src/component/skills.rs diff --git a/cofd/app/src/component/traits.rs b/src/component/traits.rs similarity index 100% rename from cofd/app/src/component/traits.rs rename to src/component/traits.rs diff --git a/cofd/app/src/i18n.rs b/src/i18n.rs similarity index 100% rename from cofd/app/src/i18n.rs rename to src/i18n.rs diff --git a/cofd/app/src/main.rs b/src/main.rs similarity index 100% rename from cofd/app/src/main.rs rename to src/main.rs diff --git a/cofd/app/src/store.rs b/src/store.rs similarity index 100% rename from cofd/app/src/store.rs rename to src/store.rs diff --git a/cofd/app/src/view/character_list.rs b/src/view/character_list.rs similarity index 100% rename from cofd/app/src/view/character_list.rs rename to src/view/character_list.rs diff --git a/cofd/app/src/view/creator.rs b/src/view/creator.rs similarity index 100% rename from cofd/app/src/view/creator.rs rename to src/view/creator.rs diff --git a/cofd/app/src/view/equipment.rs b/src/view/equipment.rs similarity index 100% rename from cofd/app/src/view/equipment.rs rename to src/view/equipment.rs diff --git a/cofd/app/src/view/mod.rs b/src/view/mod.rs similarity index 100% rename from cofd/app/src/view/mod.rs rename to src/view/mod.rs diff --git a/cofd/app/src/view/overview.rs b/src/view/overview.rs similarity index 100% rename from cofd/app/src/view/overview.rs rename to src/view/overview.rs diff --git a/cofd/app/src/view/splat_extras.rs b/src/view/splat_extras.rs similarity index 100% rename from cofd/app/src/view/splat_extras.rs rename to src/view/splat_extras.rs diff --git a/cofd/app/src/widget/dots.rs b/src/widget/dots.rs similarity index 100% rename from cofd/app/src/widget/dots.rs rename to src/widget/dots.rs diff --git a/cofd/app/src/widget/mod.rs b/src/widget/mod.rs similarity index 100% rename from cofd/app/src/widget/mod.rs rename to src/widget/mod.rs diff --git a/cofd/app/src/widget/track.rs b/src/widget/track.rs similarity index 100% rename from cofd/app/src/widget/track.rs rename to src/widget/track.rs