diff --git a/assets/voxygen/i18n/en.ron b/assets/voxygen/i18n/en.ron index a499419b08..d02cfc6b74 100644 --- a/assets/voxygen/i18n/en.ron +++ b/assets/voxygen/i18n/en.ron @@ -357,7 +357,7 @@ magically infused items?"#, "hud.spell": "Spells", - "hud.free_look_indicator": "Free look active", + "hud.free_look_indicator": "Free look active. Press {key} to disable.", "hud.auto_walk_indicator": "Auto walk active", /// End HUD section @@ -482,7 +482,7 @@ Protection "You can type /group or /g to only chat with players in your current group.", "To send private messages type /tell followed by a player name and your message.", "NPCs with the same level can have a different difficulty.", - "Look at the ground for food, chests and other loot!", + "Keep an eye out for food, chests and other loot spread all around the world!", "Inventory filled with food? Try crafting better food from it!", "Wondering what's there to do? Dungeons are marked with brown spots on the map!", "Don't forget to adjust the graphics for your system. Press 'N' to open the settings.", diff --git a/assets/voxygen/voxel/sprite/rocks/rock-0.vox b/assets/voxygen/voxel/sprite/rocks/rock-0.vox index bd0c85c9be..062fafca92 100644 --- a/assets/voxygen/voxel/sprite/rocks/rock-0.vox +++ b/assets/voxygen/voxel/sprite/rocks/rock-0.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:219f3cfd7e310284e17397a59441cfc79d27281ca09bea8a4740eee4173dab89 -size 1336 +oid sha256:2dc006d7dfc9adda49c235d03a7b80a7bf4ae1adc98b54d1311afc9047f6ae99 +size 1328 diff --git a/assets/voxygen/voxel/sprite/rocks/rock-1.vox b/assets/voxygen/voxel/sprite/rocks/rock-1.vox index ca13137003..4e2e1b8afe 100644 --- a/assets/voxygen/voxel/sprite/rocks/rock-1.vox +++ b/assets/voxygen/voxel/sprite/rocks/rock-1.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2c9365b3ddee1c873a9dbbe0a9e5c86280561562e14cda6540235d9d58bc58d0 -size 1936 +oid sha256:c999ddcf716d52cb7304fccbb15e5d5446f8f67eea04732273f2afc650f9775a +size 1916 diff --git a/assets/voxygen/voxel/sprite/rocks/rock-2.vox b/assets/voxygen/voxel/sprite/rocks/rock-2.vox index 42466dd089..5af72d4a4b 100644 --- a/assets/voxygen/voxel/sprite/rocks/rock-2.vox +++ b/assets/voxygen/voxel/sprite/rocks/rock-2.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:64e5992e0833d6f22ffb833e83ee967b1edb55d52414d45ce3afada7b0fc8e82 -size 1368 +oid sha256:80f106402224ca6fc0d38614afe86d1f7365690fbe5a55d1bbef791d4e0e2c7a +size 1356 diff --git a/common/src/comp/agent.rs b/common/src/comp/agent.rs index 22322b6df0..95b703b0dd 100644 --- a/common/src/comp/agent.rs +++ b/common/src/comp/agent.rs @@ -1,8 +1,11 @@ -use crate::{comp::Body, path::Chaser, sync::Uid}; +use crate::{ + comp::{critter, humanoid, quadruped_low, quadruped_medium, quadruped_small, Body}, + path::Chaser, + sync::Uid, +}; use specs::{Component, Entity as EcsEntity}; use specs_idvs::IdvStorage; use vek::*; - #[derive(Copy, Clone, Debug, PartialEq)] pub enum Alignment { /// Wild animals and gentle giants @@ -15,6 +18,8 @@ pub enum Alignment { Tame, /// Pets you've tamed with a collar Owned(Uid), + /// Passive objects like training dummies + Passive, } impl Alignment { @@ -22,8 +27,13 @@ impl Alignment { pub fn hostile_towards(self, other: Alignment) -> bool { match (self, other) { (Alignment::Enemy, Alignment::Enemy) => false, - (Alignment::Enemy, _) => true, + (Alignment::Enemy, Alignment::Wild) => false, + (Alignment::Enemy, Alignment::Tame) => true, + (Alignment::Wild, Alignment::Enemy) => false, + (Alignment::Wild, Alignment::Wild) => false, + (Alignment::Npc, Alignment::Wild) => true, (_, Alignment::Enemy) => true, + (Alignment::Enemy, _) => true, _ => false, } } @@ -35,8 +45,11 @@ impl Alignment { (Alignment::Owned(a), Alignment::Owned(b)) if a == b => true, (Alignment::Npc, Alignment::Npc) => true, (Alignment::Npc, Alignment::Tame) => true, + (Alignment::Enemy, Alignment::Wild) => true, + (Alignment::Wild, Alignment::Enemy) => true, (Alignment::Tame, Alignment::Npc) => true, (Alignment::Tame, Alignment::Tame) => true, + (_, Alignment::Passive) => true, _ => false, } } @@ -53,25 +66,73 @@ impl Component for Alignment { #[derive(Clone, Debug, Default)] pub struct Psyche { - pub aggro: f32, // 0.0 = always flees, 1.0 = always attacks + pub aggro: f32, // 0.0 = always flees, 1.0 = always attacks, 0.5 = flee at 50% health } - +#[allow(unreachable_patterns)] impl<'a> From<&'a Body> for Psyche { fn from(body: &'a Body) -> Self { Self { aggro: match body { - Body::Humanoid(_) => 0.5, - Body::QuadrupedSmall(_) => 0.35, - Body::QuadrupedMedium(_) => 0.5, - Body::QuadrupedLow(_) => 0.65, + Body::Humanoid(humanoid) => match humanoid.species { + humanoid::Species::Danari => 0.9, + humanoid::Species::Dwarf => 0.9, + humanoid::Species::Elf => 0.95, + humanoid::Species::Human => 0.95, + humanoid::Species::Orc => 1.0, + humanoid::Species::Undead => 1.0, + _ => 1.0, + }, + Body::QuadrupedSmall(quadruped_small) => match quadruped_small.species { + quadruped_small::Species::Pig => 0.8, + quadruped_small::Species::Fox => 0.4, + quadruped_small::Species::Sheep => 0.7, + quadruped_small::Species::Boar => 1.0, + quadruped_small::Species::Jackalope => 0.4, + quadruped_small::Species::Skunk => 0.8, + quadruped_small::Species::Cat => 0.2, + quadruped_small::Species::Batfox => 0.7, + quadruped_small::Species::Raccoon => 0.4, + quadruped_small::Species::Quokka => 0.7, + quadruped_small::Species::Dodarock => 0.9, + quadruped_small::Species::Holladon => 1.0, + quadruped_small::Species::Hyena => 0.4, + quadruped_small::Species::Rabbit => 0.1, + quadruped_small::Species::Truffler => 0.8, + quadruped_small::Species::Frog => 0.6, + _ => 1.0, + }, + Body::QuadrupedMedium(quadruped_medium) => match quadruped_medium.species { + quadruped_medium::Species::Tuskram => 0.8, + quadruped_medium::Species::Frostfang => 0.9, + quadruped_medium::Species::Mouflon => 0.8, + quadruped_medium::Species::Catoblepas => 0.8, + _ => 1.0, + }, + Body::QuadrupedLow(quadruped_low) => match quadruped_low.species { + quadruped_low::Species::Crocodile => 1.0, + quadruped_low::Species::Alligator => 1.0, + quadruped_low::Species::Salamander => 0.8, + quadruped_low::Species::Monitor => 0.9, + quadruped_low::Species::Asp => 0.9, + quadruped_low::Species::Tortoise => 1.0, + quadruped_low::Species::Rocksnapper => 1.0, + quadruped_low::Species::Pangolin => 0.6, + quadruped_low::Species::Maneater => 1.0, + _ => 1.0, + }, Body::BirdMedium(_) => 1.0, - Body::BirdSmall(_) => 0.2, + Body::BirdSmall(_) => 0.4, Body::FishMedium(_) => 0.15, Body::FishSmall(_) => 0.0, Body::BipedLarge(_) => 1.0, - Body::Object(_) => 0.0, + Body::Object(_) => 1.0, Body::Golem(_) => 1.0, - Body::Critter(_) => 0.1, + Body::Critter(critter) => match critter.species { + critter::Species::Axolotl => 1.0, + critter::Species::Turtle => 1.0, + critter::Species::Fungome => 1.0, + _ => 0.4, + }, Body::Dragon(_) => 1.0, }, } diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 2d15bc6921..20612e6a65 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -624,6 +624,7 @@ fn handle_spawn( Some(comp::group::NPC) }, comp::Alignment::Owned(_) => unreachable!(), + _ => None, } { let _ = server.state.ecs().write_storage().insert(new_entity, group); diff --git a/server/src/events/entity_creation.rs b/server/src/events/entity_creation.rs index 206136aadc..9c89743450 100644 --- a/server/src/events/entity_creation.rs +++ b/server/src/events/entity_creation.rs @@ -44,6 +44,7 @@ pub fn handle_create_npc( Alignment::Npc | Alignment::Tame => Some(group::NPC), // TODO: handle Alignment::Owned(_) => None, + _ => None, }; let entity = server diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index 202aa2dc2b..ddf529cb09 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -2109,20 +2109,36 @@ impl Hud { } // Free look indicator - if self.show.free_look { - Text::new(&self.voxygen_i18n.get("hud.free_look_indicator")) + if let Some(freelook_key) = global_state + .settings + .controls + .get_binding(GameInput::FreeLook) + { + if self.show.free_look { + Text::new( + &self + .voxygen_i18n + .get("hud.free_look_indicator") + .replace("{key}", freelook_key.to_string().as_str()), + ) .color(TEXT_BG) - .mid_top_with_margin_on(ui_widgets.window, 100.0) + .mid_top_with_margin_on(ui_widgets.window, 130.0) .font_id(self.fonts.cyri.conrod_id) .font_size(self.fonts.cyri.scale(20)) .set(self.ids.free_look_bg, ui_widgets); - Text::new(&self.voxygen_i18n.get("hud.free_look_indicator")) + Text::new( + &self + .voxygen_i18n + .get("hud.free_look_indicator") + .replace("{key}", freelook_key.to_string().as_str()), + ) .color(KILL_COLOR) .top_left_with_margins_on(self.ids.free_look_bg, -1.0, -1.0) .font_id(self.fonts.cyri.conrod_id) .font_size(self.fonts.cyri.scale(20)) .set(self.ids.free_look_txt, ui_widgets); - } + } + }; // Auto walk indicator if self.show.auto_walk { diff --git a/world/src/layer/mod.rs b/world/src/layer/mod.rs index c56a75f03a..f636b7bdc3 100644 --- a/world/src/layer/mod.rs +++ b/world/src/layer/mod.rs @@ -61,20 +61,20 @@ pub fn apply_scatter_to<'a>( ) }), (Twigs, false, |c| { - ((c.tree_density - 0.5).max(0.0) * 0.001, None) + ((c.tree_density - 0.5).max(0.0) * 0.00001, None) }), (Stones, false, |c| { - ((c.rockiness - 0.5).max(0.0) * 0.0008, None) + ((c.rockiness - 0.5).max(0.0) * 0.00001, None) }), (ShortGrass, false, |c| { ( - close(c.temp, 0.3, 0.4).min(close(c.humidity, 0.6, 0.35)) * 0.05, + close(c.temp, 0.3, 0.4).min(close(c.humidity, 0.6, 0.35)) * 0.09, Some((48.0, 0.4)), ) }), (Mushroom, false, |c| { ( - close(c.temp, 0.3, 0.4).min(close(c.humidity, 0.6, 0.35)) * 0.04, + close(c.temp, 0.3, 0.4).min(close(c.humidity, 0.6, 0.35)) * 0.00001, None, ) }), @@ -375,56 +375,45 @@ pub fn apply_caves_supplement<'a>( let difficulty = cave_depth / 200.0; // Scatter things in caves - if RandomField::new(index.seed).chance(wpos2d.into(), 0.00005 * difficulty) + if RandomField::new(index.seed).chance(wpos2d.into(), 0.000005 * difficulty) && cave_base < surface_z as i32 - 40 { + let is_hostile: bool; let entity = EntityInfo::at(Vec3::new( wpos2d.x as f32, wpos2d.y as f32, cave_base as f32, )) - .with_alignment(comp::Alignment::Enemy) .with_body(match rng.gen_range(0, 6) { 0 => { - let species = match rng.gen_range(0, 2) { + is_hostile = false; + let species = match rng.gen_range(0, 4) { 0 => comp::quadruped_small::Species::Truffler, - _ => comp::quadruped_small::Species::Hyena, + 1 => comp::quadruped_small::Species::Dodarock, + 2 => comp::quadruped_small::Species::Holladon, + _ => comp::quadruped_small::Species::Batfox, }; comp::quadruped_small::Body::random_with(rng, &species).into() }, 1 => { - let species = match rng.gen_range(0, 3) { + is_hostile = false; + let species = match rng.gen_range(0, 5) { 0 => comp::quadruped_medium::Species::Tarasque, - 1 => comp::quadruped_medium::Species::Frostfang, _ => comp::quadruped_medium::Species::Bonerattler, }; comp::quadruped_medium::Body::random_with(rng, &species).into() }, 2 => { - let species = match rng.gen_range(0, 3) { - 0 => comp::quadruped_low::Species::Maneater, + is_hostile = false; + let species = match rng.gen_range(0, 4) { 1 => comp::quadruped_low::Species::Rocksnapper, _ => comp::quadruped_low::Species::Salamander, }; comp::quadruped_low::Body::random_with(rng, &species).into() }, 3 => { - let species = match rng.gen_range(0, 3) { - 0 => comp::critter::Species::Fungome, - 1 => comp::critter::Species::Axolotl, - _ => comp::critter::Species::Rat, - }; - comp::critter::Body::random_with(rng, &species).into() - }, - 4 => { - #[allow(clippy::match_single_binding)] - let species = match rng.gen_range(0, 1) { - _ => comp::golem::Species::StoneGolem, - }; - comp::golem::Body::random_with(rng, &species).into() - }, - _ => { - let species = match rng.gen_range(0, 4) { + is_hostile = true; + let species = match rng.gen_range(0, 8) { 0 => comp::biped_large::Species::Ogre, 1 => comp::biped_large::Species::Cyclops, 2 => comp::biped_large::Species::Wendigo, @@ -432,6 +421,19 @@ pub fn apply_caves_supplement<'a>( }; comp::biped_large::Body::random_with(rng, &species).into() }, + _ => { + is_hostile = false; + let species = match rng.gen_range(0, 5) { + 0 => comp::critter::Species::Fungome, + _ => comp::critter::Species::Rat, + }; + comp::critter::Body::random_with(rng, &species).into() + }, + }) + .with_alignment(if is_hostile { + comp::Alignment::Enemy + } else { + comp::Alignment::Wild }) .with_automatic_name(); diff --git a/world/src/lib.rs b/world/src/lib.rs index 6a1a6e954d..ec171f4608 100644 --- a/world/src/lib.rs +++ b/world/src/lib.rs @@ -237,7 +237,10 @@ impl World { && !sim_chunk.is_underwater() { let entity = EntityInfo::at(gen_entity_pos()) - .with_alignment(comp::Alignment::Wild) + .with_alignment(match rng.gen_range(0, 10) { + 0 => comp::Alignment::Enemy, + _ => comp::Alignment::Wild, + }) .do_if(rng.gen_range(0, 8) == 0, |e| e.into_giant()) .with_body(match rng.gen_range(0, 5) { 0 => comp::Body::QuadrupedMedium(quadruped_medium::Body::random()), diff --git a/world/src/site/dungeon/mod.rs b/world/src/site/dungeon/mod.rs index 4b3fe2f8a7..92fff69a80 100644 --- a/world/src/site/dungeon/mod.rs +++ b/world/src/site/dungeon/mod.rs @@ -473,10 +473,10 @@ impl Floor { .with_automatic_name() .with_main_tool(assets::load_expect_cloned(match rng.gen_range(0, 6) { 0 => "common.items.weapons.axe.starter_axe", - 1 => "common.items.weapons.sword.starter_sword", + 1 => "common.items.weapons.sword.cultist_purp_2h-0", 2 => "common.items.weapons.sword.short_sword_0", - 3 => "common.items.weapons.hammer.hammer_1", - 4 => "common.items.weapons.staff.starter_staff", + 3 => "common.items.weapons.hammer.cultist_purp_2h-0", + 4 => "common.items.weapons.staff.cultist_staff", _ => "common.items.weapons.bow.starter_bow", })); @@ -545,7 +545,7 @@ impl Floor { "common.items.weapons.sword.greatsword_2h_fine-1", ), 10 => comp::Item::expect_from_asset( - "common.items.weapons.sword.greatsword_2h_fine-2", + "common.items.weapons.hammer.cultist_purp_2h-0", ), 11 => comp::Item::expect_from_asset( "common.items.weapons.sword.cultist_purp_2h-0", diff --git a/world/src/site/settlement/mod.rs b/world/src/site/settlement/mod.rs index 50d22b3c52..8f6dcf6ed9 100644 --- a/world/src/site/settlement/mod.rs +++ b/world/src/site/settlement/mod.rs @@ -897,7 +897,7 @@ impl Settlement { }) .with_agency(!is_dummy) .with_alignment(if is_dummy { - comp::Alignment::Wild + comp::Alignment::Passive } else if is_human { comp::Alignment::Npc } else {