use bevy::{
ecs::message::{MessageReader, MessageWriter},
prelude::*,
};
use issun_core::mechanics::reputation::{ReputationConfig, ReputationInput};
use issun_core::mechanics::Mechanic;
use super::types::{
BevyEventEmitter, ReputationChangeRequested, ReputationConfigResource, ReputationEventWrapper,
ReputationValue,
};
pub fn reputation_system<M>(
mut requests: MessageReader<ReputationChangeRequested>,
config: Res<ReputationConfigResource>,
mut reputation_query: Query<&mut ReputationValue>,
mut reputation_events: MessageWriter<ReputationEventWrapper>,
) where
M: Mechanic<
Config = ReputationConfig,
State = issun_core::mechanics::reputation::ReputationState,
Input = ReputationInput,
Event = issun_core::mechanics::reputation::ReputationEvent,
> + Send
+ Sync
+ 'static,
{
for request in requests.read() {
let Ok(mut reputation) = reputation_query.get_mut(request.entity) else {
warn!(
"ReputationChangeRequested: entity {:?} does not exist or has no ReputationValue component",
request.entity
);
continue;
};
let mut state = reputation.to_reputation_state();
let input = ReputationInput {
delta: request.delta,
elapsed_time: request.elapsed_time,
};
let mut emitter = BevyEventEmitter::new(request.entity, &mut reputation_events);
M::step(&config.config, &mut state, input, &mut emitter);
reputation.from_reputation_state(&state);
}
}
pub fn log_reputation_events(mut reputation_events: MessageReader<ReputationEventWrapper>) {
for wrapper in reputation_events.read() {
match wrapper.event {
issun_core::mechanics::reputation::ReputationEvent::ValueChanged {
old_value,
new_value,
} => {
info!(
"Reputation changed for {:?}: {:.1} → {:.1}",
wrapper.entity, old_value, new_value
);
}
issun_core::mechanics::reputation::ReputationEvent::ReachedMinimum { min_value } => {
info!(
"Reputation reached minimum for {:?}: {:.1}",
wrapper.entity, min_value
);
}
issun_core::mechanics::reputation::ReputationEvent::ReachedMaximum { max_value } => {
info!(
"Reputation reached maximum for {:?}: {:.1}",
wrapper.entity, max_value
);
}
issun_core::mechanics::reputation::ReputationEvent::Clamped {
attempted_value,
clamped_value,
} => {
debug!(
"Reputation clamped for {:?}: {:.1} → {:.1}",
wrapper.entity, attempted_value, clamped_value
);
}
}
}
}