veloren_rtsim/rule/
replenish_resources.rs

1use crate::{RtState, Rule, RuleError, event::OnTick};
2use rand::prelude::*;
3
4pub struct ReplenishResources;
5
6/// Take 1 hour to replenish resources entirely. Makes farming unviable, but
7/// probably still poorly balanced.
8// TODO: Different rates for different resources?
9// TODO: Non-renewable resources?
10pub const REPLENISH_TIME: f32 = 60.0 * 60.0;
11/// How many chunks should be replenished per tick?
12// TODO: It should be possible to optimise this be remembering the last
13// modification time for each chunk, then lazily projecting forward using a
14// closed-form solution to the replenishment to calculate resources in a lazy
15// manner.
16pub const REPLENISH_PER_TICK: usize = 8192;
17
18impl Rule for ReplenishResources {
19    fn start(rtstate: &mut RtState) -> Result<Self, RuleError> {
20        rtstate.bind::<Self, OnTick>(|ctx| {
21            let world_size = ctx.world.sim().get_size();
22            let mut data = ctx.state.data_mut();
23
24            // How much should be replenished for each chosen chunk to hit our target
25            // replenishment rate?
26            let replenish_amount = world_size.product() as f32
27                * ctx.event.dt
28                * (1.0 / REPLENISH_TIME / REPLENISH_PER_TICK as f32);
29            for _ in 0..REPLENISH_PER_TICK {
30                let key = world_size.map(|e| thread_rng().gen_range(0..e as i32));
31
32                let mut res = data.nature.get_chunk_resources(key);
33                for (_, res) in &mut res {
34                    *res = (*res + replenish_amount).clamp(0.0, 1.0);
35                }
36                data.nature.set_chunk_resources(key, res);
37            }
38        });
39
40        Ok(Self)
41    }
42}