use bevy::{
ecs::message::{MessageReader, MessageWriter},
prelude::*,
};
use issun_core::mechanics::diplomacy::{DiplomacyConfig, DiplomacyInput};
use issun_core::mechanics::Mechanic;
use super::types::{
BevyDiplomacyEmitter, DiplomacyConfigResource, DiplomaticStance, NegotiationRequested,
NegotiationResult, Negotiator,
};
pub fn negotiation_system<M>(
mut requests: MessageReader<NegotiationRequested>,
config: Res<DiplomacyConfigResource>,
initiator_query: Query<&Negotiator>,
mut target_query: Query<&mut DiplomaticStance>,
mut result_writer: MessageWriter<NegotiationResult>,
) where
M: Mechanic<
Config = DiplomacyConfig,
State = issun_core::mechanics::diplomacy::DiplomacyState,
Input = DiplomacyInput,
Event = issun_core::mechanics::diplomacy::DiplomacyEvent,
> + Send
+ Sync
+ 'static,
{
for request in requests.read() {
let Ok(negotiator) = initiator_query.get(request.initiator) else {
warn!(
"NegotiationRequested: Initiator {:?} invalid",
request.initiator
);
continue;
};
let Ok(mut stance) = target_query.get_mut(request.target) else {
warn!("NegotiationRequested: Target {:?} invalid", request.target);
continue;
};
let mut state = stance.to_state();
let input = DiplomacyInput {
argument_strength: negotiator.persuasion,
argument_type: request.argument_type,
target_resistance: stance.resistance,
};
let mut emitter =
BevyDiplomacyEmitter::new(request.initiator, request.target, &mut result_writer);
M::step(&config.config, &mut state, input, &mut emitter);
stance.from_state(&state);
}
}
pub fn log_negotiation_events(mut events: MessageReader<NegotiationResult>) {
for result in events.read() {
info!(
"Negotiation {:?} -> {:?}: {:?}",
result.initiator, result.target, result.event
);
}
}