veloren_rtsim/rule/
cleanup.rs1use crate::{RtState, Rule, RuleError, event::OnTick};
2use rand::prelude::*;
3use rand_chacha::ChaChaRng;
4
5const NPC_SENTIMENT_TICK_SKIP: u64 = 30;
7const NPC_CLEANUP_TICK_SKIP: u64 = 100;
8const FACTION_CLEANUP_TICK_SKIP: u64 = 30;
9const SITE_CLEANUP_TICK_SKIP: u64 = 30;
10
11pub struct CleanUp;
16
17impl Rule for CleanUp {
18 fn start(rtstate: &mut RtState) -> Result<Self, RuleError> {
19 rtstate.bind::<Self, OnTick>(|ctx| {
20 let data = &mut *ctx.state.data_mut();
21 let mut rng = ChaChaRng::from_seed(thread_rng().gen::<[u8; 32]>());
22
23 data.npcs
27 .iter_mut()
28 .filter(|(_, npc)| (npc.seed as u64 + ctx.event.tick) % NPC_SENTIMENT_TICK_SKIP == 0)
30 .for_each(|(_, npc)| npc.sentiments.decay(&mut rng, ctx.event.dt * NPC_SENTIMENT_TICK_SKIP as f32));
31
32 data.npcs
36 .retain(|npc_id, npc| if npc.is_dead() {
37 if let Some(home) = npc.home.and_then(|home| data.sites.get_mut(home)) {
39 home.population.remove(&npc_id);
40 }
41 tracing::debug!(?npc_id, "Cleaning up dead NPC");
42 false
43 } else {
44 true
45 });
46
47 data.npcs
49 .iter_mut()
50 .filter(|(_, npc)| (npc.seed as u64 + ctx.event.tick) % NPC_CLEANUP_TICK_SKIP == 0)
51 .for_each(|(_, npc)| npc.cleanup(&data.reports));
52
53 data.factions
55 .iter_mut()
56 .filter(|(_, faction)| (faction.seed as u64 + ctx.event.tick) % FACTION_CLEANUP_TICK_SKIP == 0)
57 .for_each(|(_, faction)| faction.cleanup());
58
59 data.sites
61 .iter_mut()
62 .filter(|(_, site)| (site.seed as u64 + ctx.event.tick) % SITE_CLEANUP_TICK_SKIP == 0)
63 .for_each(|(_, site)| site.cleanup(&data.reports));
64
65 data.reports.cleanup(data.time_of_day);
67 });
68
69 Ok(Self)
70 }
71}