mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Deny any interaction received during hostile_tree
This commit is contained in:
parent
0f3eb6cb3f
commit
8862258f61
@ -98,6 +98,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Combat music now loops and ends properly
|
- Combat music now loops and ends properly
|
||||||
- Modular weapons now have a selling price
|
- Modular weapons now have a selling price
|
||||||
- Closing a subwindow now only regrabs the cursor if no other subwindow requires it.
|
- Closing a subwindow now only regrabs the cursor if no other subwindow requires it.
|
||||||
|
- Fixed npc not handling interactions while fighting (especially merchants in trade)
|
||||||
|
|
||||||
## [0.12.0] - 2022-02-19
|
## [0.12.0] - 2022-02-19
|
||||||
|
|
||||||
|
@ -94,6 +94,10 @@
|
|||||||
"Trade? Like I got anything that may interest you.",
|
"Trade? Like I got anything that may interest you.",
|
||||||
"My house is mine, I won't trade it for anything.",
|
"My house is mine, I won't trade it for anything.",
|
||||||
],
|
],
|
||||||
|
"npc.speech.villager_busy": [
|
||||||
|
"Sorry, I can't speak with you right now.",
|
||||||
|
"We'll talk later, I'm busy."
|
||||||
|
],
|
||||||
"npc.speech.merchant_advertisement": [
|
"npc.speech.merchant_advertisement": [
|
||||||
"Can I interest you in a trade?",
|
"Can I interest you in a trade?",
|
||||||
"Do you want to trade with me?",
|
"Do you want to trade with me?",
|
||||||
@ -117,6 +121,10 @@
|
|||||||
"Maybe another time, have a good day!",
|
"Maybe another time, have a good day!",
|
||||||
"Too bad, maybe next time, then!"
|
"Too bad, maybe next time, then!"
|
||||||
],
|
],
|
||||||
|
"npc.speech.merchant_trade_cancelled_hostile": [
|
||||||
|
"Sorry to cut it short, we have a problem to solve here!",
|
||||||
|
"We'll trade later, I need to take care of this first!"
|
||||||
|
],
|
||||||
"npc.speech.villager_cultist_alarm": [
|
"npc.speech.villager_cultist_alarm": [
|
||||||
"Lookout! There is a cultist on the loose!",
|
"Lookout! There is a cultist on the loose!",
|
||||||
"To arms! The cultists are attacking!",
|
"To arms! The cultists are attacking!",
|
||||||
|
@ -94,6 +94,10 @@
|
|||||||
"Échanger? Comme-si j'avais quoi que ce soit qui pourrait t'intéresser.",
|
"Échanger? Comme-si j'avais quoi que ce soit qui pourrait t'intéresser.",
|
||||||
"Ma maison est à moi, je ne l'échangerai pour rien au monde.",
|
"Ma maison est à moi, je ne l'échangerai pour rien au monde.",
|
||||||
],
|
],
|
||||||
|
"npc.speech.villager_busy": [
|
||||||
|
"Désolé, je ne peux pas vous parler pour le moment.",
|
||||||
|
"On verra ça plus tard, je suis occupé."
|
||||||
|
],
|
||||||
"npc.speech.merchant_advertisement": [
|
"npc.speech.merchant_advertisement": [
|
||||||
"Puis-je t'intéresser par un échange ?",
|
"Puis-je t'intéresser par un échange ?",
|
||||||
"Veux-tu échanger avec moi?",
|
"Veux-tu échanger avec moi?",
|
||||||
@ -117,6 +121,10 @@
|
|||||||
"Peut-être une autre fois, bonne journée!",
|
"Peut-être une autre fois, bonne journée!",
|
||||||
"Mince, peut-être une autre fois alors!"
|
"Mince, peut-être une autre fois alors!"
|
||||||
],
|
],
|
||||||
|
"npc.speech.merchant_trade_cancelled_hostile": [
|
||||||
|
"On va devoir arrêter là pour l'instant, on a un problème à régler !",
|
||||||
|
"On finira cet échange une prochaine fois, il y a une urgence par ici !"
|
||||||
|
],
|
||||||
"npc.speech.villager_cultist_alarm": [
|
"npc.speech.villager_cultist_alarm": [
|
||||||
"Regarde! Il y a un cultiste errant!",
|
"Regarde! Il y a un cultiste errant!",
|
||||||
"Aux armes! Les cultistes attaquent!",
|
"Aux armes! Les cultistes attaquent!",
|
||||||
|
@ -353,13 +353,41 @@ impl<'a> System<'a> for Sys {
|
|||||||
&mut rng,
|
&mut rng,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
data.idle_tree(
|
data.idle_tree(agent, controller, &read_data, &mut rng);
|
||||||
|
}
|
||||||
|
if agent.allowed_to_speak()
|
||||||
|
&& data.recv_interaction(
|
||||||
agent,
|
agent,
|
||||||
controller,
|
controller,
|
||||||
&read_data,
|
&read_data,
|
||||||
&mut event_emitter,
|
&mut event_emitter,
|
||||||
&mut rng,
|
)
|
||||||
);
|
{
|
||||||
|
agent.timer.start(read_data.time.0, TimerAction::Interact);
|
||||||
|
}
|
||||||
|
// Interact if incoming messages
|
||||||
|
if !agent.inbox.is_empty() {
|
||||||
|
if matches!(
|
||||||
|
agent.inbox.front(),
|
||||||
|
Some(AgentEvent::ServerSound(_)) | Some(AgentEvent::Hurt)
|
||||||
|
) {
|
||||||
|
let sound = agent.inbox.pop_front();
|
||||||
|
match sound {
|
||||||
|
Some(AgentEvent::ServerSound(sound)) => {
|
||||||
|
agent.sounds_heard.push(sound);
|
||||||
|
},
|
||||||
|
Some(AgentEvent::Hurt) => {
|
||||||
|
// Hurt utterances at random upon receiving damage
|
||||||
|
if rng.gen::<f32>() < 0.4 {
|
||||||
|
controller.push_utterance(UtteranceKind::Hurt);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//Note: this should be unreachable
|
||||||
|
Some(_) | None => return,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
agent.action_state.timer = 0.1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,6 +432,7 @@ impl<'a> AgentData<'a> {
|
|||||||
let Target {
|
let Target {
|
||||||
target, hostile, ..
|
target, hostile, ..
|
||||||
} = target_info;
|
} = target_info;
|
||||||
|
|
||||||
if let Some(tgt_health) = read_data.healths.get(target) {
|
if let Some(tgt_health) = read_data.healths.get(target) {
|
||||||
// If target is dead, forget them
|
// If target is dead, forget them
|
||||||
if tgt_health.is_dead {
|
if tgt_health.is_dead {
|
||||||
@ -413,17 +442,18 @@ impl<'a> AgentData<'a> {
|
|||||||
agent.target = None;
|
agent.target = None;
|
||||||
// Else, if target is hostile, hostile tree
|
// Else, if target is hostile, hostile tree
|
||||||
} else if hostile {
|
} else if hostile {
|
||||||
|
self.cancel_interaction(agent, controller, event_emitter);
|
||||||
self.hostile_tree(agent, controller, read_data, event_emitter, rng);
|
self.hostile_tree(agent, controller, read_data, event_emitter, rng);
|
||||||
// Else, if owned, act as pet to them
|
// Else, if owned, act as pet to them
|
||||||
} else if let Some(Alignment::Owned(uid)) = self.alignment {
|
} else if let Some(Alignment::Owned(uid)) = self.alignment {
|
||||||
if read_data.uids.get(target) == Some(uid) {
|
if read_data.uids.get(target) == Some(uid) {
|
||||||
self.react_as_pet(agent, controller, read_data, event_emitter, target, rng);
|
self.react_as_pet(agent, controller, read_data, target, rng);
|
||||||
} else {
|
} else {
|
||||||
agent.target = None;
|
agent.target = None;
|
||||||
self.idle_tree(agent, controller, read_data, event_emitter, rng);
|
self.idle_tree(agent, controller, read_data, rng);
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
self.idle_tree(agent, controller, read_data, event_emitter, rng);
|
self.idle_tree(agent, controller, read_data, rng);
|
||||||
}
|
}
|
||||||
} else if matches!(read_data.bodies.get(target), Some(Body::ItemDrop(_))) {
|
} else if matches!(read_data.bodies.get(target), Some(Body::ItemDrop(_))) {
|
||||||
if let Some(tgt_pos) = read_data.positions.get(target) {
|
if let Some(tgt_pos) = read_data.positions.get(target) {
|
||||||
@ -452,7 +482,7 @@ impl<'a> AgentData<'a> {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
agent.target = None;
|
agent.target = None;
|
||||||
self.idle_tree(agent, controller, read_data, event_emitter, rng);
|
self.idle_tree(agent, controller, read_data, rng);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,7 +491,6 @@ impl<'a> AgentData<'a> {
|
|||||||
agent: &mut Agent,
|
agent: &mut Agent,
|
||||||
controller: &mut Controller,
|
controller: &mut Controller,
|
||||||
read_data: &ReadData,
|
read_data: &ReadData,
|
||||||
event_emitter: &mut Emitter<'_, ServerEvent>,
|
|
||||||
target: EcsEntity,
|
target: EcsEntity,
|
||||||
rng: &mut impl Rng,
|
rng: &mut impl Rng,
|
||||||
) {
|
) {
|
||||||
@ -485,7 +514,7 @@ impl<'a> AgentData<'a> {
|
|||||||
self.attack_target_attacker(agent, read_data, controller, rng);
|
self.attack_target_attacker(agent, read_data, controller, rng);
|
||||||
// Otherwise, just idle
|
// Otherwise, just idle
|
||||||
} else {
|
} else {
|
||||||
self.idle_tree(agent, controller, read_data, event_emitter, rng);
|
self.idle_tree(agent, controller, read_data, rng);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -495,7 +524,6 @@ impl<'a> AgentData<'a> {
|
|||||||
agent: &mut Agent,
|
agent: &mut Agent,
|
||||||
controller: &mut Controller,
|
controller: &mut Controller,
|
||||||
read_data: &ReadData,
|
read_data: &ReadData,
|
||||||
event_emitter: &mut Emitter<'_, ServerEvent>,
|
|
||||||
rng: &mut impl Rng,
|
rng: &mut impl Rng,
|
||||||
) {
|
) {
|
||||||
// TODO: Awareness currently doesn't influence anything.
|
// TODO: Awareness currently doesn't influence anything.
|
||||||
@ -510,37 +538,6 @@ impl<'a> AgentData<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Interact if incoming messages
|
|
||||||
if !agent.inbox.is_empty() {
|
|
||||||
if matches!(
|
|
||||||
agent.inbox.front(),
|
|
||||||
Some(AgentEvent::ServerSound(_)) | Some(AgentEvent::Hurt)
|
|
||||||
) {
|
|
||||||
let sound = agent.inbox.pop_front();
|
|
||||||
match sound {
|
|
||||||
Some(AgentEvent::ServerSound(sound)) => {
|
|
||||||
agent.sounds_heard.push(sound);
|
|
||||||
},
|
|
||||||
Some(AgentEvent::Hurt) => {
|
|
||||||
// Hurt utterances at random upon receiving damage
|
|
||||||
if rng.gen::<f32>() < 0.4 {
|
|
||||||
controller.push_utterance(UtteranceKind::Hurt);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
//Note: this should be unreachable
|
|
||||||
Some(_) | None => return,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
agent.action_state.timer = 0.1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we receive a new interaction, start the interaction timer
|
|
||||||
if agent.allowed_to_speak()
|
|
||||||
&& self.recv_interaction(agent, controller, read_data, event_emitter)
|
|
||||||
{
|
|
||||||
agent.timer.start(read_data.time.0, TimerAction::Interact);
|
|
||||||
}
|
|
||||||
|
|
||||||
let timeout = if agent.behavior.is(BehaviorState::TRADING) {
|
let timeout = if agent.behavior.is(BehaviorState::TRADING) {
|
||||||
TRADE_INTERACTION_TIME
|
TRADE_INTERACTION_TIME
|
||||||
@ -587,11 +584,12 @@ impl<'a> AgentData<'a> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(AgentEvent::Hurt) = agent.inbox.pop_front() {
|
if matches!(agent.inbox.front(), Some(AgentEvent::Hurt)) {
|
||||||
// Hurt utterances at random upon receiving damage
|
// Hurt utterances at random upon receiving damage
|
||||||
if rng.gen::<f32>() < 0.4 {
|
if rng.gen::<f32>() < 0.4 {
|
||||||
controller.push_utterance(UtteranceKind::Hurt);
|
controller.push_utterance(UtteranceKind::Hurt);
|
||||||
}
|
}
|
||||||
|
agent.inbox.pop_front();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(Target {
|
if let Some(Target {
|
||||||
@ -979,6 +977,81 @@ impl<'a> AgentData<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// deny any interaction whenever possible
|
||||||
|
fn cancel_interaction(
|
||||||
|
&self,
|
||||||
|
agent: &mut Agent,
|
||||||
|
controller: &mut Controller,
|
||||||
|
event_emitter: &mut Emitter<'_, ServerEvent>,
|
||||||
|
) -> bool {
|
||||||
|
if let Some(msg) = agent.inbox.front() {
|
||||||
|
let used = match msg {
|
||||||
|
AgentEvent::Talk(..) | AgentEvent::TradeAccepted(_) => {
|
||||||
|
self.chat_npc_if_allowed_to_speak(
|
||||||
|
"npc.speech.villager_busy",
|
||||||
|
agent,
|
||||||
|
event_emitter,
|
||||||
|
);
|
||||||
|
true
|
||||||
|
},
|
||||||
|
AgentEvent::TradeInvite(_) => {
|
||||||
|
controller.push_invite_response(InviteResponse::Decline);
|
||||||
|
if agent.behavior.can_trade() {
|
||||||
|
self.chat_npc_if_allowed_to_speak(
|
||||||
|
"npc.speech.merchant_busy",
|
||||||
|
agent,
|
||||||
|
event_emitter,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
self.chat_npc_if_allowed_to_speak(
|
||||||
|
"npc.speech.villager_busy",
|
||||||
|
agent,
|
||||||
|
event_emitter,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
true
|
||||||
|
},
|
||||||
|
AgentEvent::FinishedTrade(result) => {
|
||||||
|
// copy pasted from recv_interaction
|
||||||
|
// because the trade is not cancellable in this state
|
||||||
|
if agent.behavior.is(BehaviorState::TRADING) {
|
||||||
|
match result {
|
||||||
|
TradeResult::Completed => {
|
||||||
|
self.chat_npc(
|
||||||
|
"npc.speech.merchant_trade_successful",
|
||||||
|
event_emitter,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
self.chat_npc("npc.speech.merchant_trade_declined", event_emitter);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
agent.behavior.unset(BehaviorState::TRADING);
|
||||||
|
}
|
||||||
|
true
|
||||||
|
},
|
||||||
|
AgentEvent::UpdatePendingTrade(boxval) => {
|
||||||
|
// immediately cancel the trade
|
||||||
|
let (tradeid, _pending, _prices, _inventories) = &**boxval;
|
||||||
|
agent.behavior.unset(BehaviorState::TRADING);
|
||||||
|
event_emitter.emit(ServerEvent::ProcessTradeAction(
|
||||||
|
*self.entity,
|
||||||
|
*tradeid,
|
||||||
|
TradeAction::Decline,
|
||||||
|
));
|
||||||
|
self.chat_npc("npc.speech.merchant_trade_cancelled_hostile", event_emitter);
|
||||||
|
true
|
||||||
|
},
|
||||||
|
AgentEvent::ServerSound(_) | AgentEvent::Hurt => false,
|
||||||
|
};
|
||||||
|
if used {
|
||||||
|
agent.inbox.pop_front();
|
||||||
|
}
|
||||||
|
return used;
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
fn recv_interaction(
|
fn recv_interaction(
|
||||||
&self,
|
&self,
|
||||||
agent: &mut Agent,
|
agent: &mut Agent,
|
||||||
@ -1000,8 +1073,8 @@ impl<'a> AgentData<'a> {
|
|||||||
// }
|
// }
|
||||||
agent.action_state.timer += read_data.dt.0;
|
agent.action_state.timer += read_data.dt.0;
|
||||||
|
|
||||||
let msg = agent.inbox.pop_front();
|
let msg = agent.inbox.front();
|
||||||
match msg {
|
let used = match msg {
|
||||||
Some(AgentEvent::Talk(by, subject)) => {
|
Some(AgentEvent::Talk(by, subject)) => {
|
||||||
if agent.allowed_to_speak() {
|
if agent.allowed_to_speak() {
|
||||||
if let Some(target) = get_entity_by_id(by.id(), read_data) {
|
if let Some(target) = get_entity_by_id(by.id(), read_data) {
|
||||||
@ -1083,7 +1156,7 @@ impl<'a> AgentData<'a> {
|
|||||||
self.chat_npc(msg, event_emitter);
|
self.chat_npc(msg, event_emitter);
|
||||||
} else if agent.behavior.can_trade() {
|
} else if agent.behavior.can_trade() {
|
||||||
if !agent.behavior.is(BehaviorState::TRADING) {
|
if !agent.behavior.is(BehaviorState::TRADING) {
|
||||||
controller.push_initiate_invite(by, InviteKind::Trade);
|
controller.push_initiate_invite(*by, InviteKind::Trade);
|
||||||
self.chat_npc(
|
self.chat_npc(
|
||||||
"npc.speech.merchant_advertisement",
|
"npc.speech.merchant_advertisement",
|
||||||
event_emitter,
|
event_emitter,
|
||||||
@ -1169,7 +1242,7 @@ impl<'a> AgentData<'a> {
|
|||||||
Subject::Trade => {
|
Subject::Trade => {
|
||||||
if agent.behavior.can_trade() {
|
if agent.behavior.can_trade() {
|
||||||
if !agent.behavior.is(BehaviorState::TRADING) {
|
if !agent.behavior.is(BehaviorState::TRADING) {
|
||||||
controller.push_initiate_invite(by, InviteKind::Trade);
|
controller.push_initiate_invite(*by, InviteKind::Trade);
|
||||||
self.chat_npc(
|
self.chat_npc(
|
||||||
"npc.speech.merchant_advertisement",
|
"npc.speech.merchant_advertisement",
|
||||||
event_emitter,
|
event_emitter,
|
||||||
@ -1292,6 +1365,7 @@ impl<'a> AgentData<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
true
|
||||||
},
|
},
|
||||||
Some(AgentEvent::TradeInvite(with)) => {
|
Some(AgentEvent::TradeInvite(with)) => {
|
||||||
if agent.behavior.can_trade() {
|
if agent.behavior.can_trade() {
|
||||||
@ -1323,6 +1397,7 @@ impl<'a> AgentData<'a> {
|
|||||||
event_emitter,
|
event_emitter,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
true
|
||||||
},
|
},
|
||||||
Some(AgentEvent::TradeAccepted(with)) => {
|
Some(AgentEvent::TradeAccepted(with)) => {
|
||||||
if !agent.behavior.is(BehaviorState::TRADING) {
|
if !agent.behavior.is(BehaviorState::TRADING) {
|
||||||
@ -1332,6 +1407,7 @@ impl<'a> AgentData<'a> {
|
|||||||
agent.behavior.set(BehaviorState::TRADING);
|
agent.behavior.set(BehaviorState::TRADING);
|
||||||
agent.behavior.set(BehaviorState::TRADING_ISSUER);
|
agent.behavior.set(BehaviorState::TRADING_ISSUER);
|
||||||
}
|
}
|
||||||
|
true
|
||||||
},
|
},
|
||||||
Some(AgentEvent::FinishedTrade(result)) => {
|
Some(AgentEvent::FinishedTrade(result)) => {
|
||||||
if agent.behavior.is(BehaviorState::TRADING) {
|
if agent.behavior.is(BehaviorState::TRADING) {
|
||||||
@ -1345,18 +1421,18 @@ impl<'a> AgentData<'a> {
|
|||||||
}
|
}
|
||||||
agent.behavior.unset(BehaviorState::TRADING);
|
agent.behavior.unset(BehaviorState::TRADING);
|
||||||
}
|
}
|
||||||
|
true
|
||||||
},
|
},
|
||||||
Some(AgentEvent::UpdatePendingTrade(boxval)) => {
|
Some(AgentEvent::UpdatePendingTrade(boxval)) => {
|
||||||
let (tradeid, pending, prices, inventories) = *boxval;
|
let (tradeid, pending, prices, inventories) = &**boxval;
|
||||||
if agent.behavior.is(BehaviorState::TRADING) {
|
if agent.behavior.is(BehaviorState::TRADING) {
|
||||||
let who: usize = if agent.behavior.is(BehaviorState::TRADING_ISSUER) {
|
let who: usize = if agent.behavior.is(BehaviorState::TRADING_ISSUER) {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
1
|
1
|
||||||
};
|
};
|
||||||
let balance0: f32 =
|
let balance0: f32 = prices.balance(&pending.offers, inventories, 1 - who, true);
|
||||||
prices.balance(&pending.offers, &inventories, 1 - who, true);
|
let balance1: f32 = prices.balance(&pending.offers, inventories, who, false);
|
||||||
let balance1: f32 = prices.balance(&pending.offers, &inventories, who, false);
|
|
||||||
if balance0 >= balance1 {
|
if balance0 >= balance1 {
|
||||||
// If the trade is favourable to us, only send an accept message if we're
|
// If the trade is favourable to us, only send an accept message if we're
|
||||||
// not already accepting (since otherwise, spam-clicking the accept button
|
// not already accepting (since otherwise, spam-clicking the accept button
|
||||||
@ -1366,7 +1442,7 @@ impl<'a> AgentData<'a> {
|
|||||||
if !pending.accept_flags[who] && !pending.is_empty_trade() {
|
if !pending.accept_flags[who] && !pending.is_empty_trade() {
|
||||||
event_emitter.emit(ServerEvent::ProcessTradeAction(
|
event_emitter.emit(ServerEvent::ProcessTradeAction(
|
||||||
*self.entity,
|
*self.entity,
|
||||||
tradeid,
|
*tradeid,
|
||||||
TradeAction::Accept(pending.phase),
|
TradeAction::Accept(pending.phase),
|
||||||
));
|
));
|
||||||
tracing::trace!(?tradeid, ?balance0, ?balance1, "Accept Pending Trade");
|
tracing::trace!(?tradeid, ?balance0, ?balance1, "Accept Pending Trade");
|
||||||
@ -1399,18 +1475,22 @@ impl<'a> AgentData<'a> {
|
|||||||
agent.behavior.unset(BehaviorState::TRADING);
|
agent.behavior.unset(BehaviorState::TRADING);
|
||||||
event_emitter.emit(ServerEvent::ProcessTradeAction(
|
event_emitter.emit(ServerEvent::ProcessTradeAction(
|
||||||
*self.entity,
|
*self.entity,
|
||||||
tradeid,
|
*tradeid,
|
||||||
TradeAction::Decline,
|
TradeAction::Decline,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
true
|
||||||
},
|
},
|
||||||
Some(AgentEvent::ServerSound(_)) => {},
|
Some(AgentEvent::ServerSound(_)) => false,
|
||||||
Some(AgentEvent::Hurt) => {},
|
Some(AgentEvent::Hurt) => false,
|
||||||
None => return false,
|
None => false,
|
||||||
|
};
|
||||||
|
if used {
|
||||||
|
agent.inbox.pop_front();
|
||||||
}
|
}
|
||||||
true
|
used
|
||||||
}
|
}
|
||||||
|
|
||||||
fn look_toward(
|
fn look_toward(
|
||||||
|
Loading…
Reference in New Issue
Block a user