Chasing sounds

This commit is contained in:
Joshua Barretto 2021-06-15 17:15:58 +01:00
parent a9229e3625
commit 559311e1b0
15 changed files with 86 additions and 11 deletions

View File

@ -831,5 +831,11 @@
],
threshold: 0.2,
),
Utterance(Angry, BipedLarge((species: Wendigo, body_type: Female))): (
files: [
"voxygen.audio.sfx.utterance.wendigo_angry",
],
threshold: 4.0,
),
}
)

BIN
assets/voxygen/audio/sfx/utterance/ogre_angry.ogg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/audio/sfx/utterance/ogre_angry2.ogg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/audio/sfx/utterance/ogre_angry3.ogg (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
assets/voxygen/audio/sfx/utterance/wendigo_angry.ogg (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -1,5 +1,5 @@
use crate::{
comp::{humanoid, quadruped_low, quadruped_medium, quadruped_small, ship, Body},
comp::{humanoid, quadruped_low, quadruped_medium, quadruped_small, ship, Body, UtteranceKind},
path::Chaser,
rtsim::RtSimController,
trade::{PendingTrade, ReducedInventory, SiteId, SitePrices, TradeId, TradeResult},
@ -96,7 +96,7 @@ bitflags::bitflags! {
/// # Behavior Component
/// This component allow an Entity to register one or more behavior tags.
/// These tags act as flags of what an Entity can do, or what it is doing.
/// These tags act as flags of what an Entity can do, or what it is doing.
/// Behaviors Tags can be added and removed as the Entity lives, to update its
/// state when needed
#[derive(Default, Copy, Clone, Debug)]
@ -117,7 +117,7 @@ impl From<BehaviorCapability> for Behavior {
}
impl Behavior {
/// Builder function
/// Builder function
/// Set capabilities if Option is Some
pub fn maybe_with_capabilities(
mut self,
@ -297,6 +297,7 @@ pub enum SoundKind {
Explosion,
Beam,
Shockwave,
Utterance(UtteranceKind, Body),
}
#[derive(Clone, Debug)]

View File

@ -96,6 +96,13 @@ pub enum GroupManip {
AssignLeader(Uid),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum UtteranceKind {
Calm,
Angry,
Surprised,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum ControlEvent {
//ToggleLantern,
@ -111,6 +118,7 @@ pub enum ControlEvent {
GroupManip(GroupManip),
RemoveBuff(BuffKind),
Respawn,
Utterance(UtteranceKind),
}
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]

View File

@ -67,7 +67,7 @@ pub use self::{
combo::Combo,
controller::{
Climb, ControlAction, ControlEvent, Controller, ControllerInputs, GroupManip, InputAttr,
InputKind, InventoryAction, InventoryEvent, InventoryManip, MountState, Mounting,
InputKind, InventoryAction, InventoryEvent, InventoryManip, MountState, Mounting, UtteranceKind,
},
energy::{Energy, EnergyChange, EnergySource},
fluid_dynamics::Fluid,

View File

@ -1,5 +1,5 @@
use crate::{comp, uid::Uid};
use comp::{beam, item::Reagent, poise::PoiseState, skills::SkillGroupKind};
use comp::{beam, item::Reagent, poise::PoiseState, skills::SkillGroupKind, UtteranceKind};
use hashbrown::HashSet;
use serde::{Deserialize, Serialize};
use vek::*;
@ -73,6 +73,11 @@ pub enum Outcome {
GroundSlam {
pos: Vec3<f32>,
},
Utterance {
pos: Vec3<f32>,
body: comp::Body,
kind: UtteranceKind,
},
}
impl Outcome {
@ -87,7 +92,8 @@ impl Outcome {
| Outcome::Damage { pos, .. }
| Outcome::Block { pos, .. }
| Outcome::PoiseChange { pos, .. }
| Outcome::GroundSlam { pos } => Some(*pos),
| Outcome::GroundSlam { pos }
| Outcome::Utterance { pos, .. } => Some(*pos),
Outcome::BreakBlock { pos, .. } => Some(pos.map(|e| e as f32 + 0.5)),
Outcome::ExpChange { .. } | Outcome::ComboChange { .. } => None,
}

View File

@ -1,5 +1,5 @@
use common::{
comp::{BuffChange, ControlEvent, Controller},
comp::{BuffChange, ControlEvent, Controller, Pos, Body, agent::{Sound, SoundKind}},
event::{EventBus, ServerEvent},
uid::UidAllocator,
};
@ -7,7 +7,7 @@ use common_ecs::{Job, Origin, Phase, System};
use specs::{
saveload::{Marker, MarkerAllocator},
shred::ResourceId,
Entities, Join, Read, SystemData, World, WriteStorage,
Entities, Join, Read, SystemData, World, WriteStorage, ReadStorage,
};
use vek::*;
@ -16,6 +16,8 @@ pub struct ReadData<'a> {
entities: Entities<'a>,
uid_allocator: Read<'a, UidAllocator>,
server_bus: Read<'a, EventBus<ServerEvent>>,
positions: ReadStorage<'a, Pos>,
bodies: ReadStorage<'a, Body>,
}
#[derive(Default)]
@ -92,6 +94,20 @@ impl<'a> System<'a> for Sys {
server_emitter.emit(ServerEvent::GroupManip(entity, manip))
},
ControlEvent::Respawn => server_emitter.emit(ServerEvent::Respawn(entity)),
ControlEvent::Utterance(kind) => {
if let (Some(pos), Some(body)) = (
read_data.positions.get(entity),
read_data.bodies.get(entity),
) {
let sound = Sound::new(
SoundKind::Utterance(kind, *body),
pos.0,
8.0, // TODO: Come up with a better way of determining this
1.0,
);
server_emitter.emit(ServerEvent::Sound { sound });
}
},
}
}
}

View File

@ -6,7 +6,7 @@ use common::{
assets,
comp::{
self,
agent::{AgentEvent, Sound, MAX_LISTEN_DIST},
agent::{AgentEvent, Sound, MAX_LISTEN_DIST, SoundKind},
dialogue::Subject,
inventory::slot::EquipSlot,
item,
@ -386,6 +386,7 @@ pub fn handle_sound(server: &mut Server, sound: &Sound) {
let positions = &ecs.read_storage::<comp::Pos>();
let agents = &mut ecs.write_storage::<comp::Agent>();
// TODO: Reduce the complexity of this problem by using spatial partitioning system
for (agent, agent_pos) in (agents, positions).join() {
// TODO: Use pathfinding for more dropoff around obstacles
let agent_dist_sqrd = agent_pos.0.distance_squared(sound.pos);
@ -402,5 +403,19 @@ pub fn handle_sound(server: &mut Server, sound: &Sound) {
.inbox
.push_back(AgentEvent::ServerSound(propagated_sound));
}
// Attempt to turn this sound into an outcome to be received by frontends.
if let Some(outcome) = match sound.kind {
SoundKind::Utterance(kind, body) => Some(Outcome::Utterance {
kind,
pos: sound.pos,
body,
}),
_ => None,
} {
ecs
.write_resource::<Vec<Outcome>>()
.push(outcome);
}
}
}

View File

@ -21,7 +21,7 @@ use common::{
Agent, Alignment, BehaviorCapability, BehaviorState, Body, CharacterAbility,
CharacterState, ControlAction, ControlEvent, Controller, Energy, Health, HealthChange,
InputKind, Inventory, InventoryAction, LightEmitter, MountState, Ori, PhysicsState, Pos,
Scale, SkillSet, Stats, UnresolvedChatMsg, Vel,
Scale, SkillSet, Stats, UnresolvedChatMsg, Vel, UtteranceKind,
},
consts::GRAVITY,
effect::{BuffEffect, Effect},
@ -1548,6 +1548,10 @@ impl<'a> AgentData<'a> {
.min_by_key(|(_, e_pos, _, _, _, _, _)| (e_pos.0.distance_squared(self.pos.0) * 100.0) as i32) // TODO choose target by more than just distance
.map(|(e, _, _, _, _, _, _)| e);
if agent.target.is_none() && target.is_some() {
controller.push_event(ControlEvent::Utterance(UtteranceKind::Angry));
}
agent.target = target.map(|target| Target {
target,
hostile: true,

View File

@ -96,6 +96,7 @@ use common::{
object,
poise::PoiseState,
Body, CharacterAbilityType, InventoryUpdateEvent,
UtteranceKind,
},
outcome::Outcome,
terrain::{BlockKind, TerrainChunk},
@ -182,6 +183,7 @@ pub enum SfxEvent {
FlameThrower,
PoiseChange(PoiseState),
GroundSlam,
Utterance(UtteranceKind, Body),
}
#[derive(Clone, Debug, PartialEq, Deserialize, Hash, Eq)]
@ -452,6 +454,10 @@ impl SfxMgr {
audio.emit_sfx(sfx_trigger_item, *pos, None, false);
},
},
Outcome::Utterance { pos, kind, body } => {
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::Utterance(*kind, *body));
audio.emit_sfx(sfx_trigger_item, *pos, None, false);
},
Outcome::ExpChange { .. }
| Outcome::ComboChange { .. }
| Outcome::SummonedCreature { .. } => {},

View File

@ -248,7 +248,8 @@ impl ParticleMgr {
| Outcome::SkillPointGain { .. }
| Outcome::ComboChange { .. }
| Outcome::Damage { .. }
| Outcome::PoiseChange { .. } => {},
| Outcome::PoiseChange { .. }
| Outcome::Utterance { .. } => {},
}
}