aboutsummaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/src/data.rs25
-rw-r--r--server/src/interaction.rs53
2 files changed, 43 insertions, 35 deletions
diff --git a/server/src/data.rs b/server/src/data.rs
index 2d942de4..a8b712b0 100644
--- a/server/src/data.rs
+++ b/server/src/data.rs
@@ -28,8 +28,8 @@ use std::{collections::HashMap, sync::RwLock};
pub enum Action {
#[default]
Never,
- Passive(f32),
- Active(f32),
+ Passive,
+ Active,
Instant,
}
@@ -45,6 +45,10 @@ pub struct RecipeDecl {
action: Action,
#[serde(default)]
warn: bool,
+ #[serde(default)]
+ revert_duration: Option<f32>,
+ #[serde(default)]
+ duration: Option<f32>,
}
#[derive(Debug, Clone, Deserialize)]
@@ -109,15 +113,16 @@ pub fn build_gamedata(
let tile = r.tile.map(|t| TileIndex(register(&tile_names, t)));
match r.action {
Action::Never => {}
- Action::Passive(duration) => recipes.push(Recipe::Passive {
- duration,
+ Action::Passive => recipes.push(Recipe::Passive {
+ duration: r.duration.expect("duration for passive missing"),
warn: r.warn,
tile,
+ revert_duration: r.revert_duration,
input: inputs.next().expect("passive recipe without input"),
output: outputs.next(),
}),
- Action::Active(duration) => recipes.push(Recipe::Active {
- duration,
+ Action::Active => recipes.push(Recipe::Active {
+ duration: r.duration.expect("duration for active missing"),
tile,
input: inputs.next().expect("active recipe without input"),
outputs: [outputs.next(), outputs.next()],
@@ -236,11 +241,3 @@ impl Gamedata {
.map(|(i, e)| (RecipeIndex(i), e))
}
}
-impl Action {
- pub fn duration(&self) -> f32 {
- match self {
- Action::Instant | Action::Never => 0.,
- Action::Passive(x) | Action::Active(x) => *x,
- }
- }
-}
diff --git a/server/src/interaction.rs b/server/src/interaction.rs
index 126026d6..938ab715 100644
--- a/server/src/interaction.rs
+++ b/server/src/interaction.rs
@@ -27,6 +27,7 @@ use serde::{Deserialize, Serialize};
pub enum Recipe {
Passive {
duration: f32,
+ revert_duration: Option<f32>,
tile: Option<TileIndex>,
input: ItemIndex,
output: Option<ItemIndex>,
@@ -60,6 +61,14 @@ impl Recipe {
_ => None,
}
}
+ pub fn revert_duration(&self) -> Option<f32> {
+ match self {
+ Recipe::Passive {
+ revert_duration, ..
+ } => *revert_duration,
+ _ => None,
+ }
+ }
pub fn warn(&self) -> bool {
match self {
Recipe::Passive { warn, .. } => *warn,
@@ -222,30 +231,32 @@ pub fn tick_tile(dt: f32, data: &Gamedata, tile: &mut Tile) -> Option<TickEffect
let r = &data.recipe(a.recipe);
if r.supports_tile(tile.kind) {
a.progress += a.working as f32 * dt / r.duration().unwrap();
- if a.progress >= 1. {
- if let Recipe::Passive { output, .. } = &data.recipe(a.recipe) {
- tile.item = output.map(|kind| Item { kind, active: None });
- return Some(TickEffect::Produce);
- };
- a.progress = 1.;
- }
- return Some(TickEffect::Progress(r.warn()));
+ } else if let Some(revert_duration) = r.revert_duration() {
+ a.progress -= dt / revert_duration;
+ }
+ if a.progress >= 1. {
+ if let Recipe::Passive { output, .. } = &data.recipe(a.recipe) {
+ tile.item = output.map(|kind| Item { kind, active: None });
+ return Some(TickEffect::Produce);
+ };
+ a.progress = 1.;
}
+ if a.progress < 0. {
+ item.active = None;
+ }
+ return Some(TickEffect::Progress(r.warn()));
} else {
for (ri, recipe) in data.recipes() {
- if let Some(tile_constraint) = recipe.tile() {
- if tile.kind != tile_constraint {
- continue;
- }
- }
- if let Recipe::Passive { input, .. } = recipe {
- if *input == item.kind {
- item.active = Some(Involvement {
- recipe: ri,
- progress: 0.,
- working: 1,
- });
- return Some(TickEffect::Progress(recipe.warn()));
+ if recipe.supports_tile(tile.kind) {
+ if let Recipe::Passive { input, .. } = recipe {
+ if *input == item.kind {
+ item.active = Some(Involvement {
+ recipe: ri,
+ progress: 0.,
+ working: 1,
+ });
+ return Some(TickEffect::Progress(recipe.warn()));
+ }
}
}
}