From 0a33c9826871d7027c70b4472a4ad1c9b60ef7bd Mon Sep 17 00:00:00 2001 From: Avi Weinstock Date: Sun, 20 Jun 2021 19:45:49 -0400 Subject: [PATCH 1/2] Basic implementation of hat visuals. --- .../items/armor/misc/head/exclamation.ron | 17 ++++++++++ assets/voxygen/item_image_manifest.ron | 4 +++ .../voxel/armor/misc/head/exclamation.vox | 3 ++ .../voxel/humanoid_armor_head_manifest.ron | 12 +++++++ voxygen/src/scene/figure/cache.rs | 12 +++++++ voxygen/src/scene/figure/load.rs | 31 +++++++++++++++++-- 6 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 assets/common/items/armor/misc/head/exclamation.ron create mode 100644 assets/voxygen/voxel/armor/misc/head/exclamation.vox create mode 100644 assets/voxygen/voxel/humanoid_armor_head_manifest.ron diff --git a/assets/common/items/armor/misc/head/exclamation.ron b/assets/common/items/armor/misc/head/exclamation.ron new file mode 100644 index 0000000000..4e7da3c988 --- /dev/null +++ b/assets/common/items/armor/misc/head/exclamation.ron @@ -0,0 +1,17 @@ +ItemDef( + name: "Exclamation hat", + description: "You feel like bestowing quests.", + kind: Armor(( + kind: Head("Exclamation"), + stats: ( + protection: Normal(0.0), + poise_resilience: Normal(0.0), + energy_max: 0, + energy_reward: 0.0, + crit_power: 0.0, + stealth: 0.0, + ), + )), + quality: Common, + tags: [], +) diff --git a/assets/voxygen/item_image_manifest.ron b/assets/voxygen/item_image_manifest.ron index 925bf0e639..303028d56e 100644 --- a/assets/voxygen/item_image_manifest.ron +++ b/assets/voxygen/item_image_manifest.ron @@ -2194,6 +2194,10 @@ "voxel.armor.misc.head.assa_mask-0", (0.0, 0.0, 0.0), (-90.0, 180.0, 0.0), 1.0, ), + Armor(Head("Exclamation")): VoxTrans( + "voxel.armor.misc.head.exclamation", + (0.0, 15.0, 0.0), (-75.0, 135.0, 0.0), 3.0, + ), // Bags Armor(Bag("RedFace")): Png ( "element.items.item_bag_red_face", diff --git a/assets/voxygen/voxel/armor/misc/head/exclamation.vox b/assets/voxygen/voxel/armor/misc/head/exclamation.vox new file mode 100644 index 0000000000..5304297467 --- /dev/null +++ b/assets/voxygen/voxel/armor/misc/head/exclamation.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e6a3369c5a2fc3e75d6ecb07d8e282b877b50f999afb629ac2c6b69359658b8a +size 1208 diff --git a/assets/voxygen/voxel/humanoid_armor_head_manifest.ron b/assets/voxygen/voxel/humanoid_armor_head_manifest.ron new file mode 100644 index 0000000000..d72d13364c --- /dev/null +++ b/assets/voxygen/voxel/humanoid_armor_head_manifest.ron @@ -0,0 +1,12 @@ +(( + default: ( + vox_spec: ("armor.empty", (0.0, 0.0, 0.0)), + color: None + ), + map: { + "Exclamation": ( + vox_spec: ("armor.misc.head.exclamation", (-10.0, -10.0, 20.0)), + color: None + ), + } +)) diff --git a/voxygen/src/scene/figure/cache.rs b/voxygen/src/scene/figure/cache.rs index 0165122045..7f25fd606c 100644 --- a/voxygen/src/scene/figure/cache.rs +++ b/voxygen/src/scene/figure/cache.rs @@ -113,6 +113,7 @@ pub(super) struct CharacterCacheKey { pub glider: Option, pub hand: Option, pub foot: Option, + pub head: Option, } impl CharacterCacheKey { @@ -264,6 +265,17 @@ impl CharacterCacheKey { } else { None }, + head: if let Some(ItemKind::Armor(Armor { + kind: ArmorKind::Head(armor), + .. + })) = inventory + .equipped(EquipSlot::Armor(ArmorSlot::Head)) + .map(|i| i.kind()) + { + Some(armor.clone()) + } else { + None + }, } } } diff --git a/voxygen/src/scene/figure/load.rs b/voxygen/src/scene/figure/load.rs index 34736b6200..909ad3b823 100644 --- a/voxygen/src/scene/figure/load.rs +++ b/voxygen/src/scene/figure/load.rs @@ -234,7 +234,12 @@ struct HumHeadSubSpec { struct HumHeadSpec(HashMap<(Species, BodyType), HumHeadSubSpec>); impl HumHeadSpec { - fn mesh_head(&self, body: &Body, color_spec: &HumColorSpec) -> BoneMeshes { + fn mesh_head( + &self, + body: &Body, + color_spec: &HumColorSpec, + helmet: Option<(Segment, Vec3)>, + ) -> BoneMeshes { let spec = match self.0.get(&(body.species, body.body_type)) { Some(spec) => spec, None => { @@ -311,6 +316,7 @@ impl HumHeadSpec { .maybe_add(hair) .maybe_add(beard) .maybe_add(accessory) + .maybe_add(helmet) .unify(); ( @@ -373,9 +379,9 @@ make_vox_spec!( modular_components: HumModularComponentSpec = "voxygen.voxel.humanoid_modular_component_manifest", armor_lantern: HumArmorLanternSpec = "voxygen.voxel.humanoid_lantern_manifest", armor_glider: HumArmorGliderSpec = "voxygen.voxel.humanoid_glider_manifest", + armor_head: HumArmorHeadSpec = "voxygen.voxel.humanoid_armor_head_manifest", // TODO: Add these. - /* armor_head: HumArmorHeadSpec = "voxygen.voxel.humanoid_armor_head_manifest", - tabard: HumArmorTabardSpec = "voxygen.voxel.humanoid_armor_tabard_manifest", */ + /* tabard: HumArmorTabardSpec = "voxygen.voxel.humanoid_armor_tabard_manifest", */ }, |FigureKey { body, extra }, spec| { const DEFAULT_LOADOUT: super::cache::CharacterCacheKey = super::cache::CharacterCacheKey { @@ -385,6 +391,7 @@ make_vox_spec!( glider: None, hand: None, foot: None, + head: None, }; // TODO: This is bad code, maybe this method should return Option<_> @@ -403,6 +410,9 @@ make_vox_spec!( spec.head.read().0.mesh_head( body, color, + spec.armor_head.read().0.load_head( + loadout.head.as_deref() + ), ) }), third_person.map(|loadout| { @@ -957,6 +967,19 @@ impl HumArmorLanternSpec { } } impl HumArmorHeadSpec { + fn load_head(&self, head: Option<&str>) -> Option<(Segment, Vec3)> { + match self.0.map.get(head?) { + Some(spec) => Some(( + graceful_load_segment(&spec.vox_spec.0), + Vec3::::from(spec.vox_spec.1).as_(), + )), + None => { + warn!("No specification for this head: {:?}", head); + None + }, + } + } + /// FIXME: Either use this, or remove it. #[allow(dead_code)] fn mesh_head(&self, body: &Body, color_spec: &HumColorSpec, head: Option<&str>) -> BoneMeshes { @@ -2516,6 +2539,7 @@ make_vox_spec!( glider: None, hand: None, foot: None, + head: None, }; // TODO: This is bad code, maybe this method should return Option<_> @@ -3544,6 +3568,7 @@ make_vox_spec!( glider: None, hand: None, foot: None, + head: None, }; // TODO: This is bad code, maybe this method should return Option<_> From 13fc4de561f8a9d3816293806b7418ebe9afcfb9 Mon Sep 17 00:00:00 2001 From: Avi Weinstock Date: Fri, 16 Jul 2021 19:22:28 -0400 Subject: [PATCH 2/2] Add per-species head offsets. --- .../voxel/humanoid_armor_head_manifest.ron | 24 ++++++++- voxygen/src/scene/figure/load.rs | 49 ++----------------- 2 files changed, 26 insertions(+), 47 deletions(-) diff --git a/assets/voxygen/voxel/humanoid_armor_head_manifest.ron b/assets/voxygen/voxel/humanoid_armor_head_manifest.ron index d72d13364c..6307a9b106 100644 --- a/assets/voxygen/voxel/humanoid_armor_head_manifest.ron +++ b/assets/voxygen/voxel/humanoid_armor_head_manifest.ron @@ -4,9 +4,29 @@ color: None ), map: { - "Exclamation": ( + (Danari, "Exclamation"): ( vox_spec: ("armor.misc.head.exclamation", (-10.0, -10.0, 20.0)), color: None - ), + ), + (Dwarf, "Exclamation"): ( + vox_spec: ("armor.misc.head.exclamation", (-13.0, -10.0, 18.0)), + color: None + ), + (Human, "Exclamation"): ( + vox_spec: ("armor.misc.head.exclamation", (-12.0, -11.0, 18.0)), + color: None + ), + (Orc, "Exclamation"): ( + vox_spec: ("armor.misc.head.exclamation", (-11.0, -12.0, 18.0)), + color: None + ), + (Undead, "Exclamation"): ( + vox_spec: ("armor.misc.head.exclamation", (-14.0, -11.0, 18.0)), + color: None + ), + (Elf, "Exclamation"): ( + vox_spec: ("armor.misc.head.exclamation", (-11.0, -11.0, 18.0)), + color: None + ), } )) diff --git a/voxygen/src/scene/figure/load.rs b/voxygen/src/scene/figure/load.rs index 909ad3b823..dda604e939 100644 --- a/voxygen/src/scene/figure/load.rs +++ b/voxygen/src/scene/figure/load.rs @@ -359,7 +359,7 @@ struct HumArmorLanternSpec(ArmorVoxSpecMap); #[derive(Deserialize)] struct HumArmorGliderSpec(ArmorVoxSpecMap); #[derive(Deserialize)] -struct HumArmorHeadSpec(ArmorVoxSpecMap); +struct HumArmorHeadSpec(ArmorVoxSpecMap<(Species, String), ArmorVoxSpec>); #[derive(Deserialize)] struct HumArmorTabardSpec(ArmorVoxSpecMap); @@ -411,6 +411,7 @@ make_vox_spec!( body, color, spec.armor_head.read().0.load_head( + body, loadout.head.as_deref() ), ) @@ -967,8 +968,8 @@ impl HumArmorLanternSpec { } } impl HumArmorHeadSpec { - fn load_head(&self, head: Option<&str>) -> Option<(Segment, Vec3)> { - match self.0.map.get(head?) { + fn load_head(&self, body: &Body, head: Option<&str>) -> Option<(Segment, Vec3)> { + match self.0.map.get(&(body.species, head?.to_string())) { Some(spec) => Some(( graceful_load_segment(&spec.vox_spec.0), Vec3::::from(spec.vox_spec.1).as_(), @@ -979,48 +980,6 @@ impl HumArmorHeadSpec { }, } } - - /// FIXME: Either use this, or remove it. - #[allow(dead_code)] - fn mesh_head(&self, body: &Body, color_spec: &HumColorSpec, head: Option<&str>) -> BoneMeshes { - let spec = if let Some(head) = head { - match self.0.map.get(head) { - Some(spec) => spec, - None => { - error!(?head, "No head specification exists"); - return load_mesh("not_found", Vec3::new(-5.0, -3.5, 1.0)); - }, - } - } else { - &self.0.default - }; - - let color = |mat_segment| { - color_spec.color_segment( - mat_segment, - body.species.skin_color(body.skin), - color_spec.hair_color(body.species, body.hair_color), - body.species.eye_color(body.eye_color), - ) - }; - - let bare_head = graceful_load_mat_segment("armor.empty"); - - let mut head_armor = graceful_load_mat_segment(&spec.vox_spec.0); - - if let Some(color) = spec.color { - let head_color = Vec3::from(color); - head_armor = head_armor.map_rgb(|rgb| recolor_grey(rgb, Rgb::from(head_color))); - } - - let head = DynaUnionizer::new() - .add(color(bare_head), Vec3::new(0, 0, 0)) - .add(color(head_armor), Vec3::new(0, 0, 0)) - .unify() - .0; - - (head, Vec3::from(spec.vox_spec.1)) - } } impl HumArmorTabardSpec { /// FIXME: Either use this, or remove it.