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:
parent
3cea76b82f
commit
78a06550d0
@ -402,7 +402,7 @@ Willpower
|
||||
"AAAHHH! I'm under attack! Help!",
|
||||
"Help! We're under attack!",
|
||||
"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!",
|
||||
"Guards, I'm under attack!",
|
||||
"Guards! I'm under attack!",
|
||||
|
@ -5,9 +5,15 @@ use vek::*;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum Alignment {
|
||||
/// Wild animals and gentle giants
|
||||
Wild,
|
||||
/// Dungeon cultists and bandits
|
||||
Enemy,
|
||||
/// Friendly folk in villages
|
||||
Npc,
|
||||
/// Farm animals and pets of villagers
|
||||
Tame,
|
||||
/// Pets you've tamed with a collar
|
||||
Owned(EcsEntity),
|
||||
}
|
||||
|
||||
@ -27,6 +33,10 @@ impl Alignment {
|
||||
match (self, other) {
|
||||
(Alignment::Enemy, Alignment::Enemy) => 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,
|
||||
}
|
||||
}
|
||||
@ -40,6 +50,9 @@ impl Component for Alignment {
|
||||
pub struct Agent {
|
||||
pub patrol_origin: Option<Vec3<f32>>,
|
||||
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 {
|
||||
@ -47,6 +60,15 @@ impl Agent {
|
||||
self.patrol_origin = Some(origin);
|
||||
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 {
|
||||
|
@ -378,27 +378,32 @@ impl<'a> System<'a> for Sys {
|
||||
// last!) ---
|
||||
|
||||
// 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
|
||||
if stats.health.last_change.0 < 5.0 {
|
||||
if my_stats.health.last_change.0 < 5.0 {
|
||||
if let comp::HealthSource::Attack { 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 let Some(attacker) = uid_allocator.retrieve_entity_internal(by.id())
|
||||
{
|
||||
let message = "npc.speech.villager_under_attack".to_string();
|
||||
let bubble = SpeechBubble::npc_new(message, *time);
|
||||
let _ = speech_bubbles.insert(entity, bubble);
|
||||
if stats.get(attacker).map_or(false, |a| !a.is_dead) {
|
||||
if agent.can_speak {
|
||||
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 {
|
||||
target: attacker,
|
||||
chaser: Chaser::default(),
|
||||
time: time.0,
|
||||
been_close: false,
|
||||
powerup: 0.0,
|
||||
};
|
||||
agent.activity = Activity::Attack {
|
||||
target: attacker,
|
||||
chaser: Chaser::default(),
|
||||
time: time.0,
|
||||
been_close: false,
|
||||
powerup: 0.0,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -329,6 +329,8 @@ impl<'a> System<'a> for Sys {
|
||||
.health
|
||||
.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
|
||||
// work because the damage is now saved in an ability
|
||||
/*
|
||||
@ -344,7 +346,7 @@ impl<'a> System<'a> for Sys {
|
||||
loadout,
|
||||
body,
|
||||
alignment,
|
||||
agent: comp::Agent::default().with_patrol_origin(entity.pos),
|
||||
agent: comp::Agent::new(entity.pos, can_speak),
|
||||
scale: comp::Scale(scale),
|
||||
drop_item: entity.loot_drop,
|
||||
})
|
||||
|
@ -784,8 +784,8 @@ impl Settlement {
|
||||
if matches!(sample.plot, Some(Plot::Town))
|
||||
&& RandomField::new(self.seed).chance(Vec3::from(wpos2d), 1.0 / (50.0 * 50.0))
|
||||
{
|
||||
let is_human: bool;
|
||||
let entity = EntityInfo::at(entity_wpos)
|
||||
.with_alignment(comp::Alignment::Npc)
|
||||
.with_body(match rng.gen_range(0, 4) {
|
||||
0 => {
|
||||
let species = match rng.gen_range(0, 3) {
|
||||
@ -793,7 +793,7 @@ impl Settlement {
|
||||
1 => quadruped_small::Species::Sheep,
|
||||
_ => quadruped_small::Species::Cat,
|
||||
};
|
||||
|
||||
is_human = false;
|
||||
comp::Body::QuadrupedSmall(quadruped_small::Body::random_with(
|
||||
rng, &species,
|
||||
))
|
||||
@ -805,14 +805,22 @@ impl Settlement {
|
||||
2 => bird_medium::Species::Goose,
|
||||
_ => bird_medium::Species::Peacock,
|
||||
};
|
||||
|
||||
is_human = false;
|
||||
comp::Body::BirdMedium(bird_medium::Body::random_with(
|
||||
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(
|
||||
match rng.gen_range(0, 7) {
|
||||
0 => "common.items.weapons.tool.broom",
|
||||
|
Loading…
Reference in New Issue
Block a user