diff --git a/assets/slot_ranges.json b/assets/slot_ranges.json new file mode 100644 index 000000000..5b296cc62 --- /dev/null +++ b/assets/slot_ranges.json @@ -0,0 +1 @@ +{"contents":[0],"container.0":[0],"container.1":[1],"container.2":[2],"container.3":[3],"container.4":[4],"container.5":[5],"container.6":[6],"container.7":[7],"container.8":[8],"container.9":[9],"container.10":[10],"container.11":[11],"container.12":[12],"container.13":[13],"container.14":[14],"container.15":[15],"container.16":[16],"container.17":[17],"container.18":[18],"container.19":[19],"container.20":[20],"container.21":[21],"container.22":[22],"container.23":[23],"container.24":[24],"container.25":[25],"container.26":[26],"container.27":[27],"container.28":[28],"container.29":[29],"container.30":[30],"container.31":[31],"container.32":[32],"container.33":[33],"container.34":[34],"container.35":[35],"container.36":[36],"container.37":[37],"container.38":[38],"container.39":[39],"container.40":[40],"container.41":[41],"container.42":[42],"container.43":[43],"container.44":[44],"container.45":[45],"container.46":[46],"container.47":[47],"container.48":[48],"container.49":[49],"container.50":[50],"container.51":[51],"container.52":[52],"container.53":[53],"container.*":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53],"hotbar.0":[0],"hotbar.1":[1],"hotbar.2":[2],"hotbar.3":[3],"hotbar.4":[4],"hotbar.5":[5],"hotbar.6":[6],"hotbar.7":[7],"hotbar.8":[8],"hotbar.*":[0,1,2,3,4,5,6,7,8],"inventory.0":[9],"inventory.1":[10],"inventory.2":[11],"inventory.3":[12],"inventory.4":[13],"inventory.5":[14],"inventory.6":[15],"inventory.7":[16],"inventory.8":[17],"inventory.9":[18],"inventory.10":[19],"inventory.11":[20],"inventory.12":[21],"inventory.13":[22],"inventory.14":[23],"inventory.15":[24],"inventory.16":[25],"inventory.17":[26],"inventory.18":[27],"inventory.19":[28],"inventory.20":[29],"inventory.21":[30],"inventory.22":[31],"inventory.23":[32],"inventory.24":[33],"inventory.25":[34],"inventory.26":[35],"inventory.*":[9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35],"enderchest.0":[200],"enderchest.1":[201],"enderchest.2":[202],"enderchest.3":[203],"enderchest.4":[204],"enderchest.5":[205],"enderchest.6":[206],"enderchest.7":[207],"enderchest.8":[208],"enderchest.9":[209],"enderchest.10":[210],"enderchest.11":[211],"enderchest.12":[212],"enderchest.13":[213],"enderchest.14":[214],"enderchest.15":[215],"enderchest.16":[216],"enderchest.17":[217],"enderchest.18":[218],"enderchest.19":[219],"enderchest.20":[220],"enderchest.21":[221],"enderchest.22":[222],"enderchest.23":[223],"enderchest.24":[224],"enderchest.25":[225],"enderchest.26":[226],"enderchest.*":[200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226],"mob.inventory.0":[300],"mob.inventory.1":[301],"mob.inventory.2":[302],"mob.inventory.3":[303],"mob.inventory.4":[304],"mob.inventory.5":[305],"mob.inventory.6":[306],"mob.inventory.7":[307],"mob.inventory.*":[300,301,302,303,304,305,306,307],"horse.0":[500],"horse.1":[501],"horse.2":[502],"horse.3":[503],"horse.4":[504],"horse.5":[505],"horse.6":[506],"horse.7":[507],"horse.8":[508],"horse.9":[509],"horse.10":[510],"horse.11":[511],"horse.12":[512],"horse.13":[513],"horse.14":[514],"horse.*":[500,501,502,503,504,505,506,507,508,509,510,511,512,513,514],"weapon":[98],"weapon.mainhand":[98],"weapon.offhand":[99],"weapon.*":[98,99],"armor.head":[103],"armor.chest":[102],"armor.legs":[101],"armor.feet":[100],"armor.body":[105],"armor.*":[103,102,101,100,105],"saddle":[106],"horse.chest":[499],"player.cursor":[499],"player.crafting.0":[500],"player.crafting.1":[501],"player.crafting.2":[502],"player.crafting.3":[503],"player.crafting.*":[500,501,502,503]} \ No newline at end of file diff --git a/pumpkin-codegen/src/slot_ranges.rs b/pumpkin-codegen/src/slot_ranges.rs new file mode 100644 index 000000000..d4a80b21b --- /dev/null +++ b/pumpkin-codegen/src/slot_ranges.rs @@ -0,0 +1,68 @@ +use proc_macro2::TokenStream; +use quote::quote; +use std::{collections::BTreeMap, fs}; +/// Generates the `TokenStream` for some slot range constants and a function to get one from the name of a range. +pub fn build() -> TokenStream { + let slot_ranges: BTreeMap> = + serde_json::from_str(&fs::read_to_string("../assets/slot_ranges.json").unwrap()) + .expect("Failed to parse slot_ranges.json"); + + let slot_range_match_tokens = slot_ranges + .iter() + .map(|(slot_range_name, range)| { + quote! { + #slot_range_name => Some(&[#(#range),*]), + } + }) + .collect::>(); + + let slot_range_tuples_tokens = slot_ranges + .iter() + .map(|(slot_range_name, range)| { + let range = &**range; + quote! { + (#slot_range_name, &[#(#range),*]) + } + }) + .collect::>(); + + let slot_range_all_names_tokens = slot_ranges + .iter() + .map(|(slot_range_name, _)| { + quote! { #slot_range_name } + }) + .collect::>(); + + let slot_range_single_slot_names_tokens = slot_ranges + .iter() + .filter(|(_, range)| range.len() == 1) + .map(|(slot_range_name, _)| { + quote! { #slot_range_name } + }) + .collect::>(); + + let slot_ranges_len = slot_ranges.len(); + let single_slot_names_len = slot_range_single_slot_names_tokens.len(); + + quote! { + pub const SLOT_RANGES: [(&str, &[usize]); #slot_ranges_len] = [ + #(#slot_range_tuples_tokens),* + ]; + + pub const SLOT_RANGE_ALL_NAMES: [&str; #slot_ranges_len] = [ + #(#slot_range_all_names_tokens),* + ]; + + pub const SLOT_RANGE_SINGLE_SLOT_NAMES: [&str; #single_slot_names_len] = [ + #(#slot_range_single_slot_names_tokens),* + ]; + + #[must_use] + pub fn get_slot_range(name: &str) -> Option<&'static [usize]> { + match name { + #(#slot_range_match_tokens)* + _ => None, + } + } + } +} diff --git a/pumpkin-data/Cargo.toml b/pumpkin-data/Cargo.toml index c196dbbe6..a0a06a5aa 100644 --- a/pumpkin-data/Cargo.toml +++ b/pumpkin-data/Cargo.toml @@ -45,6 +45,7 @@ default = [ "villager", "placed_feature", "configured_feature", + "slot_ranges" ] item = [] @@ -82,6 +83,7 @@ recipe_remainder = [] chunk_gen_settings = [] carver = [] villager = ["item", "sound"] +slot_ranges = [] noise_parameter = [] biome = [] diff --git a/pumpkin-data/src/generated/slot_ranges.rs b/pumpkin-data/src/generated/slot_ranges.rs new file mode 100644 index 000000000..847216e01 --- /dev/null +++ b/pumpkin-data/src/generated/slot_ranges.rs @@ -0,0 +1,734 @@ +/* This file is generated. Do not edit manually. */ +pub const SLOT_RANGES: [(&str, &[usize]); 165usize] = [ + ( + "armor.*", + &[103usize, 102usize, 101usize, 100usize, 105usize], + ), + ("armor.body", &[105usize]), + ("armor.chest", &[102usize]), + ("armor.feet", &[100usize]), + ("armor.head", &[103usize]), + ("armor.legs", &[101usize]), + ( + "container.*", + &[ + 0usize, 1usize, 2usize, 3usize, 4usize, 5usize, 6usize, 7usize, 8usize, 9usize, + 10usize, 11usize, 12usize, 13usize, 14usize, 15usize, 16usize, 17usize, 18usize, + 19usize, 20usize, 21usize, 22usize, 23usize, 24usize, 25usize, 26usize, 27usize, + 28usize, 29usize, 30usize, 31usize, 32usize, 33usize, 34usize, 35usize, 36usize, + 37usize, 38usize, 39usize, 40usize, 41usize, 42usize, 43usize, 44usize, 45usize, + 46usize, 47usize, 48usize, 49usize, 50usize, 51usize, 52usize, 53usize, + ], + ), + ("container.0", &[0usize]), + ("container.1", &[1usize]), + ("container.10", &[10usize]), + ("container.11", &[11usize]), + ("container.12", &[12usize]), + ("container.13", &[13usize]), + ("container.14", &[14usize]), + ("container.15", &[15usize]), + ("container.16", &[16usize]), + ("container.17", &[17usize]), + ("container.18", &[18usize]), + ("container.19", &[19usize]), + ("container.2", &[2usize]), + ("container.20", &[20usize]), + ("container.21", &[21usize]), + ("container.22", &[22usize]), + ("container.23", &[23usize]), + ("container.24", &[24usize]), + ("container.25", &[25usize]), + ("container.26", &[26usize]), + ("container.27", &[27usize]), + ("container.28", &[28usize]), + ("container.29", &[29usize]), + ("container.3", &[3usize]), + ("container.30", &[30usize]), + ("container.31", &[31usize]), + ("container.32", &[32usize]), + ("container.33", &[33usize]), + ("container.34", &[34usize]), + ("container.35", &[35usize]), + ("container.36", &[36usize]), + ("container.37", &[37usize]), + ("container.38", &[38usize]), + ("container.39", &[39usize]), + ("container.4", &[4usize]), + ("container.40", &[40usize]), + ("container.41", &[41usize]), + ("container.42", &[42usize]), + ("container.43", &[43usize]), + ("container.44", &[44usize]), + ("container.45", &[45usize]), + ("container.46", &[46usize]), + ("container.47", &[47usize]), + ("container.48", &[48usize]), + ("container.49", &[49usize]), + ("container.5", &[5usize]), + ("container.50", &[50usize]), + ("container.51", &[51usize]), + ("container.52", &[52usize]), + ("container.53", &[53usize]), + ("container.6", &[6usize]), + ("container.7", &[7usize]), + ("container.8", &[8usize]), + ("container.9", &[9usize]), + ("contents", &[0usize]), + ( + "enderchest.*", + &[ + 200usize, 201usize, 202usize, 203usize, 204usize, 205usize, 206usize, 207usize, + 208usize, 209usize, 210usize, 211usize, 212usize, 213usize, 214usize, 215usize, + 216usize, 217usize, 218usize, 219usize, 220usize, 221usize, 222usize, 223usize, + 224usize, 225usize, 226usize, + ], + ), + ("enderchest.0", &[200usize]), + ("enderchest.1", &[201usize]), + ("enderchest.10", &[210usize]), + ("enderchest.11", &[211usize]), + ("enderchest.12", &[212usize]), + ("enderchest.13", &[213usize]), + ("enderchest.14", &[214usize]), + ("enderchest.15", &[215usize]), + ("enderchest.16", &[216usize]), + ("enderchest.17", &[217usize]), + ("enderchest.18", &[218usize]), + ("enderchest.19", &[219usize]), + ("enderchest.2", &[202usize]), + ("enderchest.20", &[220usize]), + ("enderchest.21", &[221usize]), + ("enderchest.22", &[222usize]), + ("enderchest.23", &[223usize]), + ("enderchest.24", &[224usize]), + ("enderchest.25", &[225usize]), + ("enderchest.26", &[226usize]), + ("enderchest.3", &[203usize]), + ("enderchest.4", &[204usize]), + ("enderchest.5", &[205usize]), + ("enderchest.6", &[206usize]), + ("enderchest.7", &[207usize]), + ("enderchest.8", &[208usize]), + ("enderchest.9", &[209usize]), + ( + "horse.*", + &[ + 500usize, 501usize, 502usize, 503usize, 504usize, 505usize, 506usize, 507usize, + 508usize, 509usize, 510usize, 511usize, 512usize, 513usize, 514usize, + ], + ), + ("horse.0", &[500usize]), + ("horse.1", &[501usize]), + ("horse.10", &[510usize]), + ("horse.11", &[511usize]), + ("horse.12", &[512usize]), + ("horse.13", &[513usize]), + ("horse.14", &[514usize]), + ("horse.2", &[502usize]), + ("horse.3", &[503usize]), + ("horse.4", &[504usize]), + ("horse.5", &[505usize]), + ("horse.6", &[506usize]), + ("horse.7", &[507usize]), + ("horse.8", &[508usize]), + ("horse.9", &[509usize]), + ("horse.chest", &[499usize]), + ( + "hotbar.*", + &[ + 0usize, 1usize, 2usize, 3usize, 4usize, 5usize, 6usize, 7usize, 8usize, + ], + ), + ("hotbar.0", &[0usize]), + ("hotbar.1", &[1usize]), + ("hotbar.2", &[2usize]), + ("hotbar.3", &[3usize]), + ("hotbar.4", &[4usize]), + ("hotbar.5", &[5usize]), + ("hotbar.6", &[6usize]), + ("hotbar.7", &[7usize]), + ("hotbar.8", &[8usize]), + ( + "inventory.*", + &[ + 9usize, 10usize, 11usize, 12usize, 13usize, 14usize, 15usize, 16usize, 17usize, + 18usize, 19usize, 20usize, 21usize, 22usize, 23usize, 24usize, 25usize, 26usize, + 27usize, 28usize, 29usize, 30usize, 31usize, 32usize, 33usize, 34usize, 35usize, + ], + ), + ("inventory.0", &[9usize]), + ("inventory.1", &[10usize]), + ("inventory.10", &[19usize]), + ("inventory.11", &[20usize]), + ("inventory.12", &[21usize]), + ("inventory.13", &[22usize]), + ("inventory.14", &[23usize]), + ("inventory.15", &[24usize]), + ("inventory.16", &[25usize]), + ("inventory.17", &[26usize]), + ("inventory.18", &[27usize]), + ("inventory.19", &[28usize]), + ("inventory.2", &[11usize]), + ("inventory.20", &[29usize]), + ("inventory.21", &[30usize]), + ("inventory.22", &[31usize]), + ("inventory.23", &[32usize]), + ("inventory.24", &[33usize]), + ("inventory.25", &[34usize]), + ("inventory.26", &[35usize]), + ("inventory.3", &[12usize]), + ("inventory.4", &[13usize]), + ("inventory.5", &[14usize]), + ("inventory.6", &[15usize]), + ("inventory.7", &[16usize]), + ("inventory.8", &[17usize]), + ("inventory.9", &[18usize]), + ( + "mob.inventory.*", + &[ + 300usize, 301usize, 302usize, 303usize, 304usize, 305usize, 306usize, 307usize, + ], + ), + ("mob.inventory.0", &[300usize]), + ("mob.inventory.1", &[301usize]), + ("mob.inventory.2", &[302usize]), + ("mob.inventory.3", &[303usize]), + ("mob.inventory.4", &[304usize]), + ("mob.inventory.5", &[305usize]), + ("mob.inventory.6", &[306usize]), + ("mob.inventory.7", &[307usize]), + ( + "player.crafting.*", + &[500usize, 501usize, 502usize, 503usize], + ), + ("player.crafting.0", &[500usize]), + ("player.crafting.1", &[501usize]), + ("player.crafting.2", &[502usize]), + ("player.crafting.3", &[503usize]), + ("player.cursor", &[499usize]), + ("saddle", &[106usize]), + ("weapon", &[98usize]), + ("weapon.*", &[98usize, 99usize]), + ("weapon.mainhand", &[98usize]), + ("weapon.offhand", &[99usize]), +]; +pub const SLOT_RANGE_ALL_NAMES: [&str; 165usize] = [ + "armor.*", + "armor.body", + "armor.chest", + "armor.feet", + "armor.head", + "armor.legs", + "container.*", + "container.0", + "container.1", + "container.10", + "container.11", + "container.12", + "container.13", + "container.14", + "container.15", + "container.16", + "container.17", + "container.18", + "container.19", + "container.2", + "container.20", + "container.21", + "container.22", + "container.23", + "container.24", + "container.25", + "container.26", + "container.27", + "container.28", + "container.29", + "container.3", + "container.30", + "container.31", + "container.32", + "container.33", + "container.34", + "container.35", + "container.36", + "container.37", + "container.38", + "container.39", + "container.4", + "container.40", + "container.41", + "container.42", + "container.43", + "container.44", + "container.45", + "container.46", + "container.47", + "container.48", + "container.49", + "container.5", + "container.50", + "container.51", + "container.52", + "container.53", + "container.6", + "container.7", + "container.8", + "container.9", + "contents", + "enderchest.*", + "enderchest.0", + "enderchest.1", + "enderchest.10", + "enderchest.11", + "enderchest.12", + "enderchest.13", + "enderchest.14", + "enderchest.15", + "enderchest.16", + "enderchest.17", + "enderchest.18", + "enderchest.19", + "enderchest.2", + "enderchest.20", + "enderchest.21", + "enderchest.22", + "enderchest.23", + "enderchest.24", + "enderchest.25", + "enderchest.26", + "enderchest.3", + "enderchest.4", + "enderchest.5", + "enderchest.6", + "enderchest.7", + "enderchest.8", + "enderchest.9", + "horse.*", + "horse.0", + "horse.1", + "horse.10", + "horse.11", + "horse.12", + "horse.13", + "horse.14", + "horse.2", + "horse.3", + "horse.4", + "horse.5", + "horse.6", + "horse.7", + "horse.8", + "horse.9", + "horse.chest", + "hotbar.*", + "hotbar.0", + "hotbar.1", + "hotbar.2", + "hotbar.3", + "hotbar.4", + "hotbar.5", + "hotbar.6", + "hotbar.7", + "hotbar.8", + "inventory.*", + "inventory.0", + "inventory.1", + "inventory.10", + "inventory.11", + "inventory.12", + "inventory.13", + "inventory.14", + "inventory.15", + "inventory.16", + "inventory.17", + "inventory.18", + "inventory.19", + "inventory.2", + "inventory.20", + "inventory.21", + "inventory.22", + "inventory.23", + "inventory.24", + "inventory.25", + "inventory.26", + "inventory.3", + "inventory.4", + "inventory.5", + "inventory.6", + "inventory.7", + "inventory.8", + "inventory.9", + "mob.inventory.*", + "mob.inventory.0", + "mob.inventory.1", + "mob.inventory.2", + "mob.inventory.3", + "mob.inventory.4", + "mob.inventory.5", + "mob.inventory.6", + "mob.inventory.7", + "player.crafting.*", + "player.crafting.0", + "player.crafting.1", + "player.crafting.2", + "player.crafting.3", + "player.cursor", + "saddle", + "weapon", + "weapon.*", + "weapon.mainhand", + "weapon.offhand", +]; +pub const SLOT_RANGE_SINGLE_SLOT_NAMES: [&str; 156usize] = [ + "armor.body", + "armor.chest", + "armor.feet", + "armor.head", + "armor.legs", + "container.0", + "container.1", + "container.10", + "container.11", + "container.12", + "container.13", + "container.14", + "container.15", + "container.16", + "container.17", + "container.18", + "container.19", + "container.2", + "container.20", + "container.21", + "container.22", + "container.23", + "container.24", + "container.25", + "container.26", + "container.27", + "container.28", + "container.29", + "container.3", + "container.30", + "container.31", + "container.32", + "container.33", + "container.34", + "container.35", + "container.36", + "container.37", + "container.38", + "container.39", + "container.4", + "container.40", + "container.41", + "container.42", + "container.43", + "container.44", + "container.45", + "container.46", + "container.47", + "container.48", + "container.49", + "container.5", + "container.50", + "container.51", + "container.52", + "container.53", + "container.6", + "container.7", + "container.8", + "container.9", + "contents", + "enderchest.0", + "enderchest.1", + "enderchest.10", + "enderchest.11", + "enderchest.12", + "enderchest.13", + "enderchest.14", + "enderchest.15", + "enderchest.16", + "enderchest.17", + "enderchest.18", + "enderchest.19", + "enderchest.2", + "enderchest.20", + "enderchest.21", + "enderchest.22", + "enderchest.23", + "enderchest.24", + "enderchest.25", + "enderchest.26", + "enderchest.3", + "enderchest.4", + "enderchest.5", + "enderchest.6", + "enderchest.7", + "enderchest.8", + "enderchest.9", + "horse.0", + "horse.1", + "horse.10", + "horse.11", + "horse.12", + "horse.13", + "horse.14", + "horse.2", + "horse.3", + "horse.4", + "horse.5", + "horse.6", + "horse.7", + "horse.8", + "horse.9", + "horse.chest", + "hotbar.0", + "hotbar.1", + "hotbar.2", + "hotbar.3", + "hotbar.4", + "hotbar.5", + "hotbar.6", + "hotbar.7", + "hotbar.8", + "inventory.0", + "inventory.1", + "inventory.10", + "inventory.11", + "inventory.12", + "inventory.13", + "inventory.14", + "inventory.15", + "inventory.16", + "inventory.17", + "inventory.18", + "inventory.19", + "inventory.2", + "inventory.20", + "inventory.21", + "inventory.22", + "inventory.23", + "inventory.24", + "inventory.25", + "inventory.26", + "inventory.3", + "inventory.4", + "inventory.5", + "inventory.6", + "inventory.7", + "inventory.8", + "inventory.9", + "mob.inventory.0", + "mob.inventory.1", + "mob.inventory.2", + "mob.inventory.3", + "mob.inventory.4", + "mob.inventory.5", + "mob.inventory.6", + "mob.inventory.7", + "player.crafting.0", + "player.crafting.1", + "player.crafting.2", + "player.crafting.3", + "player.cursor", + "saddle", + "weapon", + "weapon.mainhand", + "weapon.offhand", +]; +#[must_use] +pub fn get_slot_range(name: &str) -> Option<&'static [usize]> { + match name { + "armor.*" => Some(&[103usize, 102usize, 101usize, 100usize, 105usize]), + "armor.body" => Some(&[105usize]), + "armor.chest" => Some(&[102usize]), + "armor.feet" => Some(&[100usize]), + "armor.head" => Some(&[103usize]), + "armor.legs" => Some(&[101usize]), + "container.*" => Some(&[ + 0usize, 1usize, 2usize, 3usize, 4usize, 5usize, 6usize, 7usize, 8usize, 9usize, + 10usize, 11usize, 12usize, 13usize, 14usize, 15usize, 16usize, 17usize, 18usize, + 19usize, 20usize, 21usize, 22usize, 23usize, 24usize, 25usize, 26usize, 27usize, + 28usize, 29usize, 30usize, 31usize, 32usize, 33usize, 34usize, 35usize, 36usize, + 37usize, 38usize, 39usize, 40usize, 41usize, 42usize, 43usize, 44usize, 45usize, + 46usize, 47usize, 48usize, 49usize, 50usize, 51usize, 52usize, 53usize, + ]), + "container.0" => Some(&[0usize]), + "container.1" => Some(&[1usize]), + "container.10" => Some(&[10usize]), + "container.11" => Some(&[11usize]), + "container.12" => Some(&[12usize]), + "container.13" => Some(&[13usize]), + "container.14" => Some(&[14usize]), + "container.15" => Some(&[15usize]), + "container.16" => Some(&[16usize]), + "container.17" => Some(&[17usize]), + "container.18" => Some(&[18usize]), + "container.19" => Some(&[19usize]), + "container.2" => Some(&[2usize]), + "container.20" => Some(&[20usize]), + "container.21" => Some(&[21usize]), + "container.22" => Some(&[22usize]), + "container.23" => Some(&[23usize]), + "container.24" => Some(&[24usize]), + "container.25" => Some(&[25usize]), + "container.26" => Some(&[26usize]), + "container.27" => Some(&[27usize]), + "container.28" => Some(&[28usize]), + "container.29" => Some(&[29usize]), + "container.3" => Some(&[3usize]), + "container.30" => Some(&[30usize]), + "container.31" => Some(&[31usize]), + "container.32" => Some(&[32usize]), + "container.33" => Some(&[33usize]), + "container.34" => Some(&[34usize]), + "container.35" => Some(&[35usize]), + "container.36" => Some(&[36usize]), + "container.37" => Some(&[37usize]), + "container.38" => Some(&[38usize]), + "container.39" => Some(&[39usize]), + "container.4" => Some(&[4usize]), + "container.40" => Some(&[40usize]), + "container.41" => Some(&[41usize]), + "container.42" => Some(&[42usize]), + "container.43" => Some(&[43usize]), + "container.44" => Some(&[44usize]), + "container.45" => Some(&[45usize]), + "container.46" => Some(&[46usize]), + "container.47" => Some(&[47usize]), + "container.48" => Some(&[48usize]), + "container.49" => Some(&[49usize]), + "container.5" => Some(&[5usize]), + "container.50" => Some(&[50usize]), + "container.51" => Some(&[51usize]), + "container.52" => Some(&[52usize]), + "container.53" => Some(&[53usize]), + "container.6" => Some(&[6usize]), + "container.7" => Some(&[7usize]), + "container.8" => Some(&[8usize]), + "container.9" => Some(&[9usize]), + "contents" => Some(&[0usize]), + "enderchest.*" => Some(&[ + 200usize, 201usize, 202usize, 203usize, 204usize, 205usize, 206usize, 207usize, + 208usize, 209usize, 210usize, 211usize, 212usize, 213usize, 214usize, 215usize, + 216usize, 217usize, 218usize, 219usize, 220usize, 221usize, 222usize, 223usize, + 224usize, 225usize, 226usize, + ]), + "enderchest.0" => Some(&[200usize]), + "enderchest.1" => Some(&[201usize]), + "enderchest.10" => Some(&[210usize]), + "enderchest.11" => Some(&[211usize]), + "enderchest.12" => Some(&[212usize]), + "enderchest.13" => Some(&[213usize]), + "enderchest.14" => Some(&[214usize]), + "enderchest.15" => Some(&[215usize]), + "enderchest.16" => Some(&[216usize]), + "enderchest.17" => Some(&[217usize]), + "enderchest.18" => Some(&[218usize]), + "enderchest.19" => Some(&[219usize]), + "enderchest.2" => Some(&[202usize]), + "enderchest.20" => Some(&[220usize]), + "enderchest.21" => Some(&[221usize]), + "enderchest.22" => Some(&[222usize]), + "enderchest.23" => Some(&[223usize]), + "enderchest.24" => Some(&[224usize]), + "enderchest.25" => Some(&[225usize]), + "enderchest.26" => Some(&[226usize]), + "enderchest.3" => Some(&[203usize]), + "enderchest.4" => Some(&[204usize]), + "enderchest.5" => Some(&[205usize]), + "enderchest.6" => Some(&[206usize]), + "enderchest.7" => Some(&[207usize]), + "enderchest.8" => Some(&[208usize]), + "enderchest.9" => Some(&[209usize]), + "horse.*" => Some(&[ + 500usize, 501usize, 502usize, 503usize, 504usize, 505usize, 506usize, 507usize, + 508usize, 509usize, 510usize, 511usize, 512usize, 513usize, 514usize, + ]), + "horse.0" => Some(&[500usize]), + "horse.1" => Some(&[501usize]), + "horse.10" => Some(&[510usize]), + "horse.11" => Some(&[511usize]), + "horse.12" => Some(&[512usize]), + "horse.13" => Some(&[513usize]), + "horse.14" => Some(&[514usize]), + "horse.2" => Some(&[502usize]), + "horse.3" => Some(&[503usize]), + "horse.4" => Some(&[504usize]), + "horse.5" => Some(&[505usize]), + "horse.6" => Some(&[506usize]), + "horse.7" => Some(&[507usize]), + "horse.8" => Some(&[508usize]), + "horse.9" => Some(&[509usize]), + "horse.chest" => Some(&[499usize]), + "hotbar.*" => Some(&[ + 0usize, 1usize, 2usize, 3usize, 4usize, 5usize, 6usize, 7usize, 8usize, + ]), + "hotbar.0" => Some(&[0usize]), + "hotbar.1" => Some(&[1usize]), + "hotbar.2" => Some(&[2usize]), + "hotbar.3" => Some(&[3usize]), + "hotbar.4" => Some(&[4usize]), + "hotbar.5" => Some(&[5usize]), + "hotbar.6" => Some(&[6usize]), + "hotbar.7" => Some(&[7usize]), + "hotbar.8" => Some(&[8usize]), + "inventory.*" => Some(&[ + 9usize, 10usize, 11usize, 12usize, 13usize, 14usize, 15usize, 16usize, 17usize, + 18usize, 19usize, 20usize, 21usize, 22usize, 23usize, 24usize, 25usize, 26usize, + 27usize, 28usize, 29usize, 30usize, 31usize, 32usize, 33usize, 34usize, 35usize, + ]), + "inventory.0" => Some(&[9usize]), + "inventory.1" => Some(&[10usize]), + "inventory.10" => Some(&[19usize]), + "inventory.11" => Some(&[20usize]), + "inventory.12" => Some(&[21usize]), + "inventory.13" => Some(&[22usize]), + "inventory.14" => Some(&[23usize]), + "inventory.15" => Some(&[24usize]), + "inventory.16" => Some(&[25usize]), + "inventory.17" => Some(&[26usize]), + "inventory.18" => Some(&[27usize]), + "inventory.19" => Some(&[28usize]), + "inventory.2" => Some(&[11usize]), + "inventory.20" => Some(&[29usize]), + "inventory.21" => Some(&[30usize]), + "inventory.22" => Some(&[31usize]), + "inventory.23" => Some(&[32usize]), + "inventory.24" => Some(&[33usize]), + "inventory.25" => Some(&[34usize]), + "inventory.26" => Some(&[35usize]), + "inventory.3" => Some(&[12usize]), + "inventory.4" => Some(&[13usize]), + "inventory.5" => Some(&[14usize]), + "inventory.6" => Some(&[15usize]), + "inventory.7" => Some(&[16usize]), + "inventory.8" => Some(&[17usize]), + "inventory.9" => Some(&[18usize]), + "mob.inventory.*" => Some(&[ + 300usize, 301usize, 302usize, 303usize, 304usize, 305usize, 306usize, 307usize, + ]), + "mob.inventory.0" => Some(&[300usize]), + "mob.inventory.1" => Some(&[301usize]), + "mob.inventory.2" => Some(&[302usize]), + "mob.inventory.3" => Some(&[303usize]), + "mob.inventory.4" => Some(&[304usize]), + "mob.inventory.5" => Some(&[305usize]), + "mob.inventory.6" => Some(&[306usize]), + "mob.inventory.7" => Some(&[307usize]), + "player.crafting.*" => Some(&[500usize, 501usize, 502usize, 503usize]), + "player.crafting.0" => Some(&[500usize]), + "player.crafting.1" => Some(&[501usize]), + "player.crafting.2" => Some(&[502usize]), + "player.crafting.3" => Some(&[503usize]), + "player.cursor" => Some(&[499usize]), + "saddle" => Some(&[106usize]), + "weapon" => Some(&[98usize]), + "weapon.*" => Some(&[98usize, 99usize]), + "weapon.mainhand" => Some(&[98usize]), + "weapon.offhand" => Some(&[99usize]), + _ => None, + } +} diff --git a/pumpkin-data/src/lib.rs b/pumpkin-data/src/lib.rs index c68e48605..b91f23ec8 100644 --- a/pumpkin-data/src/lib.rs +++ b/pumpkin-data/src/lib.rs @@ -318,3 +318,8 @@ pub mod carver; #[rustfmt::skip] #[path = "generated/villager.rs"] pub mod villager; + +#[cfg(feature = "slot_ranges")] +#[rustfmt::skip] +#[path = "generated/slot_ranges.rs"] +pub mod slot_ranges; diff --git a/pumpkin/src/command/argument_types/mod.rs b/pumpkin/src/command/argument_types/mod.rs index f210d9ff8..9cc3c9430 100644 --- a/pumpkin/src/command/argument_types/mod.rs +++ b/pumpkin/src/command/argument_types/mod.rs @@ -226,5 +226,6 @@ pub mod game_profile; pub mod identifier; pub mod nbt; pub mod range; +pub mod slot; pub mod time; pub mod uuid; diff --git a/pumpkin/src/command/argument_types/slot.rs b/pumpkin/src/command/argument_types/slot.rs new file mode 100644 index 000000000..cdc6473d5 --- /dev/null +++ b/pumpkin/src/command/argument_types/slot.rs @@ -0,0 +1,100 @@ +use crate::command::argument_types::argument_type::{ArgumentType, JavaClientArgumentType}; +use crate::command::context::command_context::CommandContext; +use crate::command::errors::command_syntax_error::CommandSyntaxError; +use crate::command::errors::error_types::CommandErrorType; +use crate::command::string_reader::StringReader; +use crate::command::suggestion::suggestions::{Suggestions, SuggestionsBuilder}; +use pumpkin_data::slot_ranges::{ + SLOT_RANGE_ALL_NAMES, SLOT_RANGE_SINGLE_SLOT_NAMES, get_slot_range, +}; +use pumpkin_data::translation; +use pumpkin_util::text::TextComponent; +use std::pin::Pin; + +pub const UNKNOWN_SLOT_ERROR_TYPE: CommandErrorType<1> = CommandErrorType::new( + translation::java::SLOT_UNKNOWN, + translation::java::SLOT_UNKNOWN, +); + +pub const ONLY_SINGLE_SLOT_ALLOWED_ERROR_TYPE: CommandErrorType<1> = CommandErrorType::new( + translation::java::SLOT_ONLY_SINGLE_ALLOWED, + translation::java::SLOT_ONLY_SINGLE_ALLOWED, +); + +pub struct SlotArgumentType; + +impl ArgumentType for SlotArgumentType { + type Item = usize; + + fn parse(&self, reader: &mut StringReader) -> Result { + let start = reader.cursor(); + reader.read_until_space(); + let name = &reader.string()[start..reader.cursor()]; + + match get_slot_range(name) { + Some([slot]) => Ok(*slot), + Some(_) => Err(ONLY_SINGLE_SLOT_ALLOWED_ERROR_TYPE + .create(reader, TextComponent::text(name.to_string()))), + None => { + Err(UNKNOWN_SLOT_ERROR_TYPE.create(reader, TextComponent::text(name.to_string()))) + } + } + } + + fn client_side_parser(&'_ self) -> JavaClientArgumentType<'_> { + JavaClientArgumentType::ItemSlot + } + + fn list_suggestions<'a>( + &'a self, + _context: &'a CommandContext, + builder: SuggestionsBuilder, + ) -> Pin + Send + 'a>> { + Box::pin(async move { + builder + .filter_and_suggest(&SLOT_RANGE_SINGLE_SLOT_NAMES) + .build() + }) + } + + fn examples(&self) -> Vec { + examples!("weapon", "container.2", "enderchest.0") + } +} + +impl_copy_get!(SlotArgumentType, usize); + +pub struct SlotsArgumentType; + +impl ArgumentType for SlotsArgumentType { + type Item = &'static [usize]; + + fn parse(&self, reader: &mut StringReader) -> Result { + let start = reader.cursor(); + reader.read_until_space(); + let name = &reader.string()[start..reader.cursor()]; + + get_slot_range(name).ok_or_else(|| { + let text = name.to_string(); + UNKNOWN_SLOT_ERROR_TYPE.create(reader, TextComponent::text(text)) + }) + } + + fn client_side_parser(&'_ self) -> JavaClientArgumentType<'_> { + JavaClientArgumentType::ItemSlots + } + + fn list_suggestions<'a>( + &'a self, + _context: &'a CommandContext, + builder: SuggestionsBuilder, + ) -> Pin + Send + 'a>> { + Box::pin(async move { builder.filter_and_suggest(&SLOT_RANGE_ALL_NAMES).build() }) + } + + fn examples(&self) -> Vec { + examples!("weapon", "container.2", "enderchest.*") + } +} + +impl_copy_get!(SlotsArgumentType, &'static [usize]); diff --git a/pumpkin/src/command/string_reader.rs b/pumpkin/src/command/string_reader.rs index 9e666ac95..b77655670 100644 --- a/pumpkin/src/command/string_reader.rs +++ b/pumpkin/src/command/string_reader.rs @@ -328,6 +328,13 @@ impl<'a> StringReader<'a> { } } + /// Keeps skipping characters in the reader until a space or the end of the string is encountered. + pub fn read_until_space(&mut self) { + while !matches!(self.peek(), None | Some(' ')) { + self.skip(); + } + } + /// Converts this reader into a `'static` form, which /// is useful for snapshotting the reader. #[must_use]