mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Use Behavior::CanTrade instead of Agent::trade_for_site + addressed comments
This commit is contained in:
parent
51ef3547a1
commit
211ab02897
@ -2,7 +2,7 @@ use crate::{
|
||||
comp::{humanoid, quadruped_low, quadruped_medium, quadruped_small, Body},
|
||||
path::Chaser,
|
||||
rtsim::RtSimController,
|
||||
trade::{PendingTrade, ReducedInventory, SiteId, SitePrices, TradeId, TradeResult},
|
||||
trade::{PendingTrade, ReducedInventory, SitePrices, TradeId, TradeResult},
|
||||
uid::Uid,
|
||||
};
|
||||
use specs::{Component, Entity as EcsEntity};
|
||||
@ -212,7 +212,6 @@ pub struct Agent {
|
||||
pub chaser: Chaser,
|
||||
/// Does the agent talk when e.g. hit by the player
|
||||
// TODO move speech patterns into a Behavior component
|
||||
pub trade_for_site: Option<SiteId>,
|
||||
pub psyche: Psyche,
|
||||
pub inbox: VecDeque<AgentEvent>,
|
||||
pub action_timer: f32,
|
||||
@ -233,15 +232,9 @@ impl Agent {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
patrol_origin: Option<Vec3<f32>>,
|
||||
trade_for_site: Option<SiteId>,
|
||||
body: &Body,
|
||||
no_flee: bool,
|
||||
) -> Self {
|
||||
pub fn new(patrol_origin: Option<Vec3<f32>>, body: &Body, no_flee: bool) -> Self {
|
||||
Agent {
|
||||
patrol_origin,
|
||||
trade_for_site,
|
||||
psyche: if no_flee {
|
||||
Psyche { aggro: 1.0 }
|
||||
} else {
|
||||
|
@ -2,7 +2,13 @@ use specs::Component;
|
||||
use specs_idvs::IdvStorage;
|
||||
use std::mem;
|
||||
|
||||
/// Behavior Component
|
||||
use crate::trade::SiteId;
|
||||
|
||||
/// # 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, Clone, Debug)]
|
||||
pub struct Behavior {
|
||||
tags: Vec<BehaviorTag>,
|
||||
@ -14,7 +20,7 @@ pub enum BehaviorTag {
|
||||
/// The entity is allowed to speak
|
||||
CanSpeak,
|
||||
/// The entity is able to trade
|
||||
CanTrade,
|
||||
CanTrade(Option<SiteId>),
|
||||
|
||||
/// The entity is currently trading
|
||||
IsTrading,
|
||||
@ -23,13 +29,10 @@ pub enum BehaviorTag {
|
||||
}
|
||||
|
||||
impl Behavior {
|
||||
pub fn new(can_speak: bool, can_trade: bool) -> Self {
|
||||
pub fn new(behavior_tags: &[BehaviorTag]) -> Self {
|
||||
let mut behavior = Self::default();
|
||||
if can_speak {
|
||||
behavior.add_tag(BehaviorTag::CanSpeak);
|
||||
}
|
||||
if can_trade {
|
||||
behavior.add_tag(BehaviorTag::CanTrade);
|
||||
for tag in behavior_tags.iter() {
|
||||
behavior.add_tag(tag.clone())
|
||||
}
|
||||
behavior
|
||||
}
|
||||
@ -56,7 +59,9 @@ impl Behavior {
|
||||
|
||||
/// Check if the Behavior possess a specific tag
|
||||
pub fn has_tag(&self, tag: &BehaviorTag) -> bool {
|
||||
self.tags.iter().any(|behavior_tag| behavior_tag == tag)
|
||||
self.tags
|
||||
.iter()
|
||||
.any(|behavior_tag| mem::discriminant(behavior_tag) == mem::discriminant(tag))
|
||||
}
|
||||
|
||||
/// Get a specific tag by variant
|
||||
|
@ -2,7 +2,7 @@ use crate::{
|
||||
comp::{
|
||||
self,
|
||||
inventory::loadout_builder::{LoadoutBuilder, LoadoutConfig},
|
||||
Behavior, CharacterState, StateUpdate,
|
||||
Behavior, BehaviorTag, CharacterState, StateUpdate,
|
||||
},
|
||||
event::{LocalEvent, ServerEvent},
|
||||
outcome::Outcome,
|
||||
@ -104,8 +104,8 @@ impl CharacterBehavior for Data {
|
||||
poise: comp::Poise::new(body),
|
||||
loadout,
|
||||
body,
|
||||
agent: Some(comp::Agent::new(None, None, &body, true)),
|
||||
behavior: Some(Behavior::new(true, false)),
|
||||
agent: Some(comp::Agent::new(None, &body, true)),
|
||||
behavior: Some(Behavior::new(&[BehaviorTag::CanSpeak])),
|
||||
alignment: comp::Alignment::Owned(*data.uid),
|
||||
scale: self
|
||||
.static_data
|
||||
|
@ -15,7 +15,7 @@ use common::{
|
||||
buff::{BuffCategory, BuffData, BuffKind, BuffSource},
|
||||
inventory::item::MaterialStatManifest,
|
||||
invite::InviteKind,
|
||||
ChatType, Inventory, Item, LightEmitter, WaypointArea,
|
||||
BehaviorTag, ChatType, Inventory, Item, LightEmitter, WaypointArea,
|
||||
},
|
||||
effect::Effect,
|
||||
event::{EventBus, ServerEvent},
|
||||
@ -1075,7 +1075,7 @@ fn handle_spawn_airship(
|
||||
});
|
||||
if let Some(pos) = destination {
|
||||
builder = builder.with(comp::Agent::with_destination(pos));
|
||||
builder = builder.with(comp::Behavior::new(true, false))
|
||||
builder = builder.with(comp::Behavior::new(&[BehaviorTag::CanSpeak]))
|
||||
}
|
||||
builder.build();
|
||||
|
||||
|
@ -6,7 +6,7 @@ use common::{
|
||||
agent::{Agent, AgentEvent},
|
||||
group::GroupManager,
|
||||
invite::{Invite, InviteKind, InviteResponse, PendingInvites},
|
||||
ChatType,
|
||||
Behavior, ChatType,
|
||||
},
|
||||
trade::Trades,
|
||||
uid::Uid,
|
||||
@ -167,6 +167,7 @@ pub fn handle_invite_accept(server: &mut Server, entity: specs::Entity) {
|
||||
let clients = state.ecs().read_storage::<Client>();
|
||||
let uids = state.ecs().read_storage::<Uid>();
|
||||
let mut agents = state.ecs().write_storage::<Agent>();
|
||||
let behaviors = state.ecs().read_storage::<Behavior>();
|
||||
let mut invites = state.ecs().write_storage::<Invite>();
|
||||
if let Some((inviter, kind)) = invites.remove(entity).and_then(|invite| {
|
||||
let Invite { inviter, kind } = invite;
|
||||
@ -223,10 +224,10 @@ pub fn handle_invite_accept(server: &mut Server, entity: specs::Entity) {
|
||||
.inbox
|
||||
.push_front(AgentEvent::TradeAccepted(invitee_uid));
|
||||
}
|
||||
let pricing = agents
|
||||
let pricing = behaviors
|
||||
.get(inviter)
|
||||
.and_then(|a| index.get_site_prices(a))
|
||||
.or_else(|| agents.get(entity).and_then(|a| index.get_site_prices(a)));
|
||||
.and_then(|b| index.get_site_prices(b))
|
||||
.or_else(|| behaviors.get(entity).and_then(|b| index.get_site_prices(b)));
|
||||
clients.get(inviter).map(|c| {
|
||||
c.send(ServerGeneral::UpdatePendingTrade(
|
||||
id,
|
||||
|
@ -3,6 +3,7 @@ use common::{
|
||||
comp::{
|
||||
agent::{Agent, AgentEvent},
|
||||
inventory::{item::MaterialStatManifest, Inventory},
|
||||
Behavior,
|
||||
},
|
||||
trade::{PendingTrade, ReducedInventory, TradeAction, TradeId, TradeResult, Trades},
|
||||
};
|
||||
@ -28,12 +29,13 @@ fn notify_agent_simple(
|
||||
|
||||
fn notify_agent_prices(
|
||||
mut agents: specs::WriteStorage<Agent>,
|
||||
behaviors: specs::ReadStorage<Behavior>,
|
||||
index: &IndexOwned,
|
||||
entity: EcsEntity,
|
||||
event: AgentEvent,
|
||||
) {
|
||||
if let Some(agent) = agents.get_mut(entity) {
|
||||
let prices = index.get_site_prices(agent);
|
||||
if let (Some(agent), Some(behavior)) = (agents.get_mut(entity), behaviors.get(entity)) {
|
||||
let prices = index.get_site_prices(behavior);
|
||||
if let AgentEvent::UpdatePendingTrade(boxval) = event {
|
||||
// Box<(tid, pend, _, inventories)>) = event {
|
||||
agent
|
||||
@ -104,6 +106,7 @@ pub fn handle_process_trade_action(
|
||||
let mut inventories: [Option<ReducedInventory>; 2] = [None, None];
|
||||
let mut prices = None;
|
||||
let agents = server.state.ecs().read_storage::<Agent>();
|
||||
let behaviors = server.state.ecs().read_storage::<Behavior>();
|
||||
// sadly there is no map and collect on arrays
|
||||
for i in 0..2 {
|
||||
// parties.len()) {
|
||||
@ -118,7 +121,9 @@ pub fn handle_process_trade_action(
|
||||
// Get price info from the first Agent in the trade (currently, an
|
||||
// Agent will never initiate a trade with another agent though)
|
||||
prices = prices.or_else(|| {
|
||||
agents.get(e).and_then(|a| server.index.get_site_prices(a))
|
||||
behaviors
|
||||
.get(e)
|
||||
.and_then(|b| server.index.get_site_prices(b))
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -135,6 +140,7 @@ pub fn handle_process_trade_action(
|
||||
);
|
||||
notify_agent_prices(
|
||||
server.state.ecs().write_storage::<Agent>(),
|
||||
server.state.ecs().read_storage::<Behavior>(),
|
||||
&server.index,
|
||||
e,
|
||||
AgentEvent::UpdatePendingTrade(Box::new((
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
use super::*;
|
||||
use common::{
|
||||
comp::{self, inventory::loadout_builder::LoadoutBuilder, Behavior},
|
||||
comp::{self, inventory::loadout_builder::LoadoutBuilder, Behavior, BehaviorTag},
|
||||
event::{EventBus, ServerEvent},
|
||||
resources::{DeltaTime, Time},
|
||||
terrain::TerrainGrid,
|
||||
@ -103,9 +103,9 @@ impl<'a> System<'a> for Sys {
|
||||
.map(|e| e as f32)
|
||||
+ Vec3::new(0.5, 0.5, body.flying_height());
|
||||
let pos = comp::Pos(spawn_pos);
|
||||
let agent = Some(comp::Agent::new(None, None, &body, false));
|
||||
let agent = Some(comp::Agent::new(None, &body, false));
|
||||
let behavior = if matches!(body, comp::Body::Humanoid(_)) {
|
||||
Some(Behavior::new(true, false))
|
||||
Some(Behavior::new(&[BehaviorTag::CanSpeak]))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -935,7 +935,7 @@ impl<'a> AgentData<'a> {
|
||||
event_emitter.emit(ServerEvent::Chat(
|
||||
UnresolvedChatMsg::npc(*self.uid, msg),
|
||||
));
|
||||
} else if self.behavior.has_tag(&BehaviorTag::CanTrade) {
|
||||
} else if self.behavior.has_tag(&BehaviorTag::CanTrade(None)) {
|
||||
let msg = "npc.speech.merchant_advertisement".to_string();
|
||||
event_emitter.emit(ServerEvent::Chat(
|
||||
UnresolvedChatMsg::npc(*self.uid, msg),
|
||||
@ -948,7 +948,7 @@ impl<'a> AgentData<'a> {
|
||||
}
|
||||
},
|
||||
Subject::Trade => {
|
||||
if self.behavior.has_tag(&BehaviorTag::CanTrade) {
|
||||
if self.behavior.has_tag(&BehaviorTag::CanTrade(None)) {
|
||||
if !self.behavior.has_tag(&BehaviorTag::IsTrading) {
|
||||
controller.events.push(ControlEvent::InitiateInvite(
|
||||
by,
|
||||
@ -1097,7 +1097,7 @@ impl<'a> AgentData<'a> {
|
||||
}
|
||||
},
|
||||
Some(AgentEvent::TradeInvite(with)) => {
|
||||
if self.behavior.has_tag(&BehaviorTag::CanTrade) {
|
||||
if self.behavior.has_tag(&BehaviorTag::CanTrade(None)) {
|
||||
if !self.behavior.has_tag(&BehaviorTag::IsTrading) {
|
||||
// stand still and looking towards the trading player
|
||||
controller.actions.push(ControlAction::Stand);
|
||||
|
@ -2,7 +2,9 @@ use crate::{
|
||||
chunk_generator::ChunkGenerator, client::Client, presence::Presence, rtsim::RtSim, Tick,
|
||||
};
|
||||
use common::{
|
||||
comp::{self, bird_medium, inventory::loadout_builder::LoadoutConfig, Alignment, Pos},
|
||||
comp::{
|
||||
self, bird_medium, inventory::loadout_builder::LoadoutConfig, Alignment, BehaviorTag, Pos,
|
||||
},
|
||||
event::{EventBus, ServerEvent},
|
||||
generation::get_npc_name,
|
||||
npc::NPC_NAMES,
|
||||
@ -191,7 +193,6 @@ impl<'a> System<'a> for Sys {
|
||||
agent: if entity.has_agency {
|
||||
Some(comp::Agent::new(
|
||||
Some(entity.pos),
|
||||
trade_for_site,
|
||||
&body,
|
||||
matches!(
|
||||
loadout_config,
|
||||
@ -202,7 +203,14 @@ impl<'a> System<'a> for Sys {
|
||||
None
|
||||
},
|
||||
behavior: if entity.has_agency {
|
||||
Some(comp::Behavior::new(can_speak, trade_for_site.is_some()))
|
||||
let mut behavior_tags = vec![];
|
||||
if can_speak {
|
||||
behavior_tags.push(BehaviorTag::CanSpeak);
|
||||
}
|
||||
if trade_for_site.is_some() {
|
||||
behavior_tags.push(BehaviorTag::CanTrade(trade_for_site));
|
||||
}
|
||||
Some(comp::Behavior::new(&behavior_tags))
|
||||
} else {
|
||||
None
|
||||
},
|
||||
|
@ -4,7 +4,7 @@ use crate::{
|
||||
};
|
||||
use common::{
|
||||
assets::{AssetExt, AssetHandle},
|
||||
comp::Agent,
|
||||
comp::{Behavior, BehaviorTag},
|
||||
store::Store,
|
||||
trade::SitePrices,
|
||||
};
|
||||
@ -72,13 +72,17 @@ impl Index {
|
||||
|
||||
pub fn colors(&self) -> AssetHandle<Arc<Colors>> { self.colors }
|
||||
|
||||
pub fn get_site_prices(&self, agent: &Agent) -> Option<SitePrices> {
|
||||
agent
|
||||
.trade_for_site
|
||||
.map(|i| self.sites.recreate_id(i))
|
||||
.flatten()
|
||||
.map(|i| self.sites.get(i))
|
||||
.map(|s| s.economy.get_site_prices())
|
||||
pub fn get_site_prices(&self, behavior: &Behavior) -> Option<SitePrices> {
|
||||
if let Some(BehaviorTag::CanTrade(site_id)) = behavior.get_tag(BehaviorTag::CanTrade(None))
|
||||
{
|
||||
site_id
|
||||
.map(|i| self.sites.recreate_id(i))
|
||||
.flatten()
|
||||
.map(|i| self.sites.get(i))
|
||||
.map(|s| s.economy.get_site_prices())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user