mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Only NPCs speak when hit. Farm animal alignment changed from NPC to Tame
This commit is contained in:

committed by
Pfauenauge90
parent
3cea76b82f
commit
78a06550d0
@ -402,7 +402,7 @@ Willpower
|
|||||||
"AAAHHH! I'm under attack! Help!",
|
"AAAHHH! I'm under attack! Help!",
|
||||||
"Help! We're under attack!",
|
"Help! We're under attack!",
|
||||||
"Help! Murderer!",
|
"Help! Murderer!",
|
||||||
"Help! There's a murder on the loose!",
|
"Help! There's a murderer on the loose!",
|
||||||
"Help! They're trying to kill me!",
|
"Help! They're trying to kill me!",
|
||||||
"Guards, I'm under attack!",
|
"Guards, I'm under attack!",
|
||||||
"Guards! I'm under attack!",
|
"Guards! I'm under attack!",
|
||||||
|
@ -5,9 +5,15 @@ use vek::*;
|
|||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
pub enum Alignment {
|
pub enum Alignment {
|
||||||
|
/// Wild animals and gentle giants
|
||||||
Wild,
|
Wild,
|
||||||
|
/// Dungeon cultists and bandits
|
||||||
Enemy,
|
Enemy,
|
||||||
|
/// Friendly folk in villages
|
||||||
Npc,
|
Npc,
|
||||||
|
/// Farm animals and pets of villagers
|
||||||
|
Tame,
|
||||||
|
/// Pets you've tamed with a collar
|
||||||
Owned(EcsEntity),
|
Owned(EcsEntity),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,6 +33,10 @@ impl Alignment {
|
|||||||
match (self, other) {
|
match (self, other) {
|
||||||
(Alignment::Enemy, Alignment::Enemy) => true,
|
(Alignment::Enemy, Alignment::Enemy) => true,
|
||||||
(Alignment::Owned(a), Alignment::Owned(b)) if a == b => true,
|
(Alignment::Owned(a), Alignment::Owned(b)) if a == b => true,
|
||||||
|
(Alignment::Npc, Alignment::Npc) => true,
|
||||||
|
(Alignment::Npc, Alignment::Tame) => true,
|
||||||
|
(Alignment::Tame, Alignment::Npc) => true,
|
||||||
|
(Alignment::Tame, Alignment::Tame) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -40,6 +50,9 @@ impl Component for Alignment {
|
|||||||
pub struct Agent {
|
pub struct Agent {
|
||||||
pub patrol_origin: Option<Vec3<f32>>,
|
pub patrol_origin: Option<Vec3<f32>>,
|
||||||
pub activity: Activity,
|
pub activity: Activity,
|
||||||
|
/// Does the agent talk when e.g. hit by the player
|
||||||
|
// TODO move speech patterns into a Behavior component
|
||||||
|
pub can_speak: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Agent {
|
impl Agent {
|
||||||
@ -47,6 +60,15 @@ impl Agent {
|
|||||||
self.patrol_origin = Some(origin);
|
self.patrol_origin = Some(origin);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new(origin: Vec3<f32>, can_speak: bool) -> Self {
|
||||||
|
let patrol_origin = Some(origin);
|
||||||
|
Agent {
|
||||||
|
patrol_origin,
|
||||||
|
can_speak,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Component for Agent {
|
impl Component for Agent {
|
||||||
|
@ -378,27 +378,32 @@ impl<'a> System<'a> for Sys {
|
|||||||
// last!) ---
|
// last!) ---
|
||||||
|
|
||||||
// Attack a target that's attacking us
|
// Attack a target that's attacking us
|
||||||
if let Some(stats) = stats.get(entity) {
|
if let Some(my_stats) = stats.get(entity) {
|
||||||
// Only if the attack was recent
|
// Only if the attack was recent
|
||||||
if stats.health.last_change.0 < 5.0 {
|
if my_stats.health.last_change.0 < 5.0 {
|
||||||
if let comp::HealthSource::Attack { by }
|
if let comp::HealthSource::Attack { by }
|
||||||
| comp::HealthSource::Projectile { owner: Some(by) } =
|
| comp::HealthSource::Projectile { owner: Some(by) } =
|
||||||
stats.health.last_change.1.cause
|
my_stats.health.last_change.1.cause
|
||||||
{
|
{
|
||||||
if !agent.activity.is_attack() {
|
if !agent.activity.is_attack() {
|
||||||
if let Some(attacker) = uid_allocator.retrieve_entity_internal(by.id())
|
if let Some(attacker) = uid_allocator.retrieve_entity_internal(by.id())
|
||||||
{
|
{
|
||||||
let message = "npc.speech.villager_under_attack".to_string();
|
if stats.get(attacker).map_or(false, |a| !a.is_dead) {
|
||||||
let bubble = SpeechBubble::npc_new(message, *time);
|
if agent.can_speak {
|
||||||
let _ = speech_bubbles.insert(entity, bubble);
|
let message =
|
||||||
|
"npc.speech.villager_under_attack".to_string();
|
||||||
|
let bubble = SpeechBubble::npc_new(message, *time);
|
||||||
|
let _ = speech_bubbles.insert(entity, bubble);
|
||||||
|
}
|
||||||
|
|
||||||
agent.activity = Activity::Attack {
|
agent.activity = Activity::Attack {
|
||||||
target: attacker,
|
target: attacker,
|
||||||
chaser: Chaser::default(),
|
chaser: Chaser::default(),
|
||||||
time: time.0,
|
time: time.0,
|
||||||
been_close: false,
|
been_close: false,
|
||||||
powerup: 0.0,
|
powerup: 0.0,
|
||||||
};
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -329,6 +329,8 @@ impl<'a> System<'a> for Sys {
|
|||||||
.health
|
.health
|
||||||
.set_to(stats.health.maximum(), comp::HealthSource::Revive);
|
.set_to(stats.health.maximum(), comp::HealthSource::Revive);
|
||||||
|
|
||||||
|
let can_speak = alignment == comp::Alignment::Npc;
|
||||||
|
|
||||||
// TODO: This code sets an appropriate base_damage for the enemy. This doesn't
|
// TODO: This code sets an appropriate base_damage for the enemy. This doesn't
|
||||||
// work because the damage is now saved in an ability
|
// work because the damage is now saved in an ability
|
||||||
/*
|
/*
|
||||||
@ -344,7 +346,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
loadout,
|
loadout,
|
||||||
body,
|
body,
|
||||||
alignment,
|
alignment,
|
||||||
agent: comp::Agent::default().with_patrol_origin(entity.pos),
|
agent: comp::Agent::new(entity.pos, can_speak),
|
||||||
scale: comp::Scale(scale),
|
scale: comp::Scale(scale),
|
||||||
drop_item: entity.loot_drop,
|
drop_item: entity.loot_drop,
|
||||||
})
|
})
|
||||||
|
@ -784,8 +784,8 @@ impl Settlement {
|
|||||||
if matches!(sample.plot, Some(Plot::Town))
|
if matches!(sample.plot, Some(Plot::Town))
|
||||||
&& RandomField::new(self.seed).chance(Vec3::from(wpos2d), 1.0 / (50.0 * 50.0))
|
&& RandomField::new(self.seed).chance(Vec3::from(wpos2d), 1.0 / (50.0 * 50.0))
|
||||||
{
|
{
|
||||||
|
let is_human: bool;
|
||||||
let entity = EntityInfo::at(entity_wpos)
|
let entity = EntityInfo::at(entity_wpos)
|
||||||
.with_alignment(comp::Alignment::Npc)
|
|
||||||
.with_body(match rng.gen_range(0, 4) {
|
.with_body(match rng.gen_range(0, 4) {
|
||||||
0 => {
|
0 => {
|
||||||
let species = match rng.gen_range(0, 3) {
|
let species = match rng.gen_range(0, 3) {
|
||||||
@ -793,7 +793,7 @@ impl Settlement {
|
|||||||
1 => quadruped_small::Species::Sheep,
|
1 => quadruped_small::Species::Sheep,
|
||||||
_ => quadruped_small::Species::Cat,
|
_ => quadruped_small::Species::Cat,
|
||||||
};
|
};
|
||||||
|
is_human = false;
|
||||||
comp::Body::QuadrupedSmall(quadruped_small::Body::random_with(
|
comp::Body::QuadrupedSmall(quadruped_small::Body::random_with(
|
||||||
rng, &species,
|
rng, &species,
|
||||||
))
|
))
|
||||||
@ -805,14 +805,22 @@ impl Settlement {
|
|||||||
2 => bird_medium::Species::Goose,
|
2 => bird_medium::Species::Goose,
|
||||||
_ => bird_medium::Species::Peacock,
|
_ => bird_medium::Species::Peacock,
|
||||||
};
|
};
|
||||||
|
is_human = false;
|
||||||
comp::Body::BirdMedium(bird_medium::Body::random_with(
|
comp::Body::BirdMedium(bird_medium::Body::random_with(
|
||||||
rng, &species,
|
rng, &species,
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
_ => comp::Body::Humanoid(humanoid::Body::random()),
|
_ => {
|
||||||
|
is_human = true;
|
||||||
|
comp::Body::Humanoid(humanoid::Body::random())
|
||||||
|
},
|
||||||
})
|
})
|
||||||
.do_if(rng.gen(), |entity| {
|
.with_alignment(if is_human {
|
||||||
|
comp::Alignment::Npc
|
||||||
|
} else {
|
||||||
|
comp::Alignment::Tame
|
||||||
|
})
|
||||||
|
.do_if(is_human && rng.gen(), |entity| {
|
||||||
entity.with_main_tool(assets::load_expect_cloned(
|
entity.with_main_tool(assets::load_expect_cloned(
|
||||||
match rng.gen_range(0, 7) {
|
match rng.gen_range(0, 7) {
|
||||||
0 => "common.items.weapons.tool.broom",
|
0 => "common.items.weapons.tool.broom",
|
||||||
|
Reference in New Issue
Block a user