Move Behavior to Agent's Component

This commit is contained in:
Vincent Foulon 2021-04-07 22:11:29 +02:00
parent dbee13f9be
commit a30cbaf735
3 changed files with 95 additions and 98 deletions

View File

@ -2,7 +2,7 @@ use crate::{
comp::{humanoid, quadruped_low, quadruped_medium, quadruped_small, Body}, comp::{humanoid, quadruped_low, quadruped_medium, quadruped_small, Body},
path::Chaser, path::Chaser,
rtsim::RtSimController, rtsim::RtSimController,
trade::{PendingTrade, ReducedInventory, SitePrices, TradeId, TradeResult}, trade::{PendingTrade, ReducedInventory, SiteId, SitePrices, TradeId, TradeResult},
uid::Uid, uid::Uid,
}; };
use specs::{Component, Entity as EcsEntity}; use specs::{Component, Entity as EcsEntity};
@ -10,7 +10,7 @@ use specs_idvs::IdvStorage;
use std::collections::VecDeque; use std::collections::VecDeque;
use vek::*; use vek::*;
use super::{dialogue::Subject, Behavior}; use super::dialogue::Subject;
pub const DEFAULT_INTERACTION_TIME: f32 = 3.0; pub const DEFAULT_INTERACTION_TIME: f32 = 3.0;
pub const TRADE_INTERACTION_TIME: f32 = 300.0; pub const TRADE_INTERACTION_TIME: f32 = 300.0;
@ -98,6 +98,69 @@ impl Component for Alignment {
type Storage = IdvStorage<Self>; type Storage = IdvStorage<Self>;
} }
bitflags::bitflags! {
#[derive(Default)]
pub struct BehaviorCapability: u8 {
const SPEAK = 0b00000001;
const TRADE = 0b00000010;
}
}
bitflags::bitflags! {
#[derive(Default)]
pub struct BehaviorState: u8 {
const TRADING = 0b00000001;
const TRADING_ISSUER = 0b00000010;
}
}
/// # 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.
/// Behaviors Tags can be added and removed as the Entity lives, to update its
/// state when needed
#[derive(Default, Copy, Clone, Debug)]
pub struct Behavior {
capabilities: BehaviorCapability,
state: BehaviorState,
pub trade_site: Option<SiteId>,
}
impl From<BehaviorCapability> for Behavior {
fn from(capabilities: BehaviorCapability) -> Self {
Behavior {
capabilities,
state: BehaviorState::default(),
trade_site: None,
}
}
}
impl Behavior {
/// Set capabilities to the Behavior
pub fn allow(&mut self, capabilities: BehaviorCapability) {
self.capabilities.set(capabilities, true)
}
/// Unset capabilities to the Behavior
pub fn deny(&mut self, capabilities: BehaviorCapability) {
self.capabilities.set(capabilities, false)
}
/// Check if the Behavior is able to do something
pub fn can(&self, capabilities: BehaviorCapability) -> bool {
self.capabilities.contains(capabilities)
}
/// Set a state to the Behavior
pub fn set(&mut self, state: BehaviorState) { self.state.set(state, true) }
/// Unset a state to the Behavior
pub fn unset(&mut self, state: BehaviorState) { self.state.set(state, false) }
/// Check if the Behavior has a specific state
pub fn is(&self, state: BehaviorState) -> bool { self.state.contains(state) }
}
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct Psyche { pub struct Psyche {
pub aggro: f32, // 0.0 = always flees, 1.0 = always attacks, 0.5 = flee at 50% health pub aggro: f32, // 0.0 = always flees, 1.0 = always attacks, 0.5 = flee at 50% health
@ -254,3 +317,32 @@ impl Agent {
impl Component for Agent { impl Component for Agent {
type Storage = IdvStorage<Self>; type Storage = IdvStorage<Self>;
} }
#[cfg(test)]
mod tests {
use super::{Behavior, BehaviorCapability, BehaviorState};
/// Test to verify that Behavior is working correctly at its most basic
/// usages
#[test]
pub fn behavior_basic() {
let mut b = Behavior::default();
// test capabilities
assert!(!b.can(BehaviorCapability::SPEAK));
b.allow(BehaviorCapability::SPEAK);
assert!(b.can(BehaviorCapability::SPEAK));
b.deny(BehaviorCapability::SPEAK);
assert!(!b.can(BehaviorCapability::SPEAK));
// test states
assert!(!b.is(BehaviorState::TRADING));
b.set(BehaviorState::TRADING);
assert!(b.is(BehaviorState::TRADING));
b.unset(BehaviorState::TRADING);
assert!(!b.is(BehaviorState::TRADING));
// test `from`
let b = Behavior::from(BehaviorCapability::SPEAK | BehaviorCapability::TRADE);
assert!(b.can(BehaviorCapability::SPEAK));
assert!(b.can(BehaviorCapability::TRADE));
assert!(b.can(BehaviorCapability::SPEAK | BehaviorCapability::TRADE));
}
}

View File

@ -1,93 +0,0 @@
use crate::trade::SiteId;
bitflags::bitflags! {
#[derive(Default)]
pub struct BehaviorCapability: u8 {
const SPEAK = 0b00000001;
const TRADE = 0b00000010;
}
}
bitflags::bitflags! {
#[derive(Default)]
pub struct BehaviorState: u8 {
const TRADING = 0b00000001;
const TRADING_ISSUER = 0b00000010;
}
}
/// # 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.
/// Behaviors Tags can be added and removed as the Entity lives, to update its
/// state when needed
#[derive(Default, Copy, Clone, Debug)]
pub struct Behavior {
capabilities: BehaviorCapability,
state: BehaviorState,
pub trade_site: Option<SiteId>,
}
impl From<BehaviorCapability> for Behavior {
fn from(capabilities: BehaviorCapability) -> Self {
Behavior {
capabilities,
state: BehaviorState::default(),
trade_site: None,
}
}
}
impl Behavior {
/// Set capabilities to the Behavior
pub fn allow(&mut self, capabilities: BehaviorCapability) {
self.capabilities.set(capabilities, true)
}
/// Unset capabilities to the Behavior
pub fn deny(&mut self, capabilities: BehaviorCapability) {
self.capabilities.set(capabilities, false)
}
/// Check if the Behavior is able to do something
pub fn can(&self, capabilities: BehaviorCapability) -> bool {
self.capabilities.contains(capabilities)
}
/// Set a state to the Behavior
pub fn set(&mut self, state: BehaviorState) { self.state.set(state, true) }
/// Unset a state to the Behavior
pub fn unset(&mut self, state: BehaviorState) { self.state.set(state, false) }
/// Check if the Behavior has a specific state
pub fn is(&self, state: BehaviorState) -> bool { self.state.contains(state) }
}
#[cfg(test)]
mod tests {
use super::{Behavior, BehaviorCapability, BehaviorState};
/// Test to verify that Behavior is working correctly at its most basic
/// usages
#[test]
pub fn basic() {
let mut b = Behavior::default();
// test capabilities
assert!(!b.can(BehaviorCapability::SPEAK));
b.allow(BehaviorCapability::SPEAK);
assert!(b.can(BehaviorCapability::SPEAK));
b.deny(BehaviorCapability::SPEAK);
assert!(!b.can(BehaviorCapability::SPEAK));
// test states
assert!(!b.is(BehaviorState::TRADING));
b.set(BehaviorState::TRADING);
assert!(b.is(BehaviorState::TRADING));
b.unset(BehaviorState::TRADING);
assert!(!b.is(BehaviorState::TRADING));
// test `from`
let b = Behavior::from(BehaviorCapability::SPEAK | BehaviorCapability::TRADE);
assert!(b.can(BehaviorCapability::SPEAK));
assert!(b.can(BehaviorCapability::TRADE));
assert!(b.can(BehaviorCapability::SPEAK | BehaviorCapability::TRADE));
}
}

View File

@ -3,7 +3,6 @@
#[cfg(not(target_arch = "wasm32"))] pub mod agent; #[cfg(not(target_arch = "wasm32"))] pub mod agent;
#[cfg(not(target_arch = "wasm32"))] pub mod aura; #[cfg(not(target_arch = "wasm32"))] pub mod aura;
#[cfg(not(target_arch = "wasm32"))] pub mod beam; #[cfg(not(target_arch = "wasm32"))] pub mod beam;
pub mod behavior;
#[cfg(not(target_arch = "wasm32"))] pub mod body; #[cfg(not(target_arch = "wasm32"))] pub mod body;
pub mod buff; pub mod buff;
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
@ -46,10 +45,9 @@ pub mod visual;
pub use self::{ pub use self::{
ability::{CharacterAbility, CharacterAbilityType}, ability::{CharacterAbility, CharacterAbilityType},
admin::Admin, admin::Admin,
agent::{Agent, Alignment}, agent::{Agent, Alignment, Behavior, BehaviorCapability, BehaviorState},
aura::{Aura, AuraChange, AuraKind, Auras}, aura::{Aura, AuraChange, AuraKind, Auras},
beam::{Beam, BeamSegment}, beam::{Beam, BeamSegment},
behavior::{Behavior, BehaviorCapability, BehaviorState},
body::{ body::{
biped_large, biped_small, bird_medium, bird_small, dragon, fish_medium, fish_small, golem, biped_large, biped_small, bird_medium, bird_small, dragon, fish_medium, fish_small, golem,
humanoid, object, quadruped_low, quadruped_medium, quadruped_small, ship, theropod, humanoid, object, quadruped_low, quadruped_medium, quadruped_small, ship, theropod,