Only NPCs speak when hit. Farm animal alignment changed from NPC to Tame

This commit is contained in:
CapsizeGlimmer 2020-05-25 22:45:13 -04:00 committed by Pfauenauge90
parent 3cea76b82f
commit 78a06550d0
5 changed files with 57 additions and 20 deletions

View File

@ -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!",

View File

@ -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 {

View File

@ -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,
};
}
}
}
}

View File

@ -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,
})

View File

@ -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",