diff options
Diffstat (limited to 'server/src/interaction.rs')
| -rw-r--r-- | server/src/interaction.rs | 227 | 
1 files changed, 91 insertions, 136 deletions
| diff --git a/server/src/interaction.rs b/server/src/interaction.rs index aa216410..75cd0c84 100644 --- a/server/src/interaction.rs +++ b/server/src/interaction.rs @@ -1,11 +1,9 @@  use crate::{ -    data::{Action, Gamedata}, +    data::Gamedata,      game::{Involvement, Item, Player, Tile},      protocol::{ItemIndex, TileIndex},  }; -use log::{debug, info};  use serde::{Deserialize, Serialize}; -use std::collections::BTreeSet;  #[derive(Debug, Clone, Serialize, Deserialize)]  pub enum Recipe { @@ -36,32 +34,47 @@ impl Recipe {              Recipe::Instant { tile, .. } => *tile,          }      } +    pub fn duration(&self) -> Option<f32> { +        match self { +            Recipe::Passive { duration, .. } => Some(*duration), +            Recipe::Active { duration, .. } => Some(*duration), +            _ => None, +        } +    } +    pub fn supports_tile(&self, tile: TileIndex) -> bool { +        if let Some(tile_constraint) = self.tile() { +            if tile != tile_constraint { +                false +            } else { +                true +            } +        } else { +            true +        } +    } +} + +pub enum InteractEffect { +    Put, +    Take, +    Produce,  } -pub fn interact(data: &Gamedata, edge: bool, tile: &mut Tile, player: &mut Player) { +pub fn interact( +    data: &Gamedata, +    edge: bool, +    tile: &mut Tile, +    player: &mut Player, +) -> Option<InteractEffect> {      if !edge { -        return; +        return None;      }      for recipe in &data.recipes { -        if let Some(tile_constraint) = recipe.tile() { -            if tile.kind != tile_constraint { -                continue; -            } +        if !recipe.supports_tile(tile.kind) { +            continue;          }          match recipe { -            Recipe::Passive { -                duration, -                input, -                output, -                .. -            } => todo!(), -            Recipe::Active { -                duration, -                input: inputs, -                outputs, -                .. -            } => todo!(),              Recipe::Instant {                  inputs, outputs, ..              } => { @@ -72,125 +85,67 @@ pub fn interact(data: &Gamedata, edge: bool, tile: &mut Tile, player: &mut Playe                  if ok {                      player.item = outputs[0].map(|kind| Item { kind, active: None });                      tile.item = outputs[1].map(|kind| Item { kind, active: None }); +                    return Some(InteractEffect::Produce);                  }              } +            _ => (),          }      } -} -// if !edge { -//     debug!("falling edge"); -//     if let Some(ac) = active { -//         if matches!(data.recipes[ac.recipe].action, Action::Active(_)) { -//             debug!("workers--"); -//             ac.working -= 1; -//         } -//     } -//     return; -// } - -// if hand.is_none() { -//     debug!("rising edge"); -//     if let Some(active) = active { -//         if matches!(data.recipes[active.recipe].action, Action::Active(_)) { -//             debug!("workers++"); -//             active.working += 1; -//         } -//     } -// } -// if active.is_none() && !items.is_empty() && hand.is_none() { -//     out(Take(items.len() - 1)); -//     return; -// } - -// if active.is_none() { -//     if let Some(hi) = hand { -//         if allowed.contains(&hi) { -//             out(Put); -//             items.push(hi); -//             hand = None; -//         } -//     } -// } - -// if hand.is_none() && active.is_none() { -//     'rloop: for (ri, r) in data.recipes.iter().enumerate() { -//         if tile != r.tile { -//             continue; -//         } -//         let mut inputs = r.inputs.clone(); -//         for i in &items { -//             debug!("take {i:?} {inputs:?}"); -//             let Some(pos) = inputs.iter().position(|e| e == i) else { -//                 continue 'rloop; -//             }; -//             inputs.remove(pos); -//         } -//         debug!("end {inputs:?}"); -//         if !inputs.is_empty() { -//             continue; -//         } +    if tile.item.is_none() { +        if let Some(item) = player.item.take() { +            tile.item = Some(item); +            return Some(InteractEffect::Put); +        } +    } +    if player.item.is_none() { +        if let Some(item) = tile.item.take() { +            player.item = Some(item); +            return Some(InteractEffect::Take); +        } +    } -//         match r.action { -//             Action::Passive(_) => { -//                 info!("use passive recipe {ri}"); -//                 *active = Some(Involvement { -//                     recipe: ri, -//                     progress: 0., -//                     working: 1, -//                 }); -//                 break 'rloop; -//             } -//             Action::Active(_) => { -//                 info!("use active recipe {ri}"); -//                 *active = Some(Involvement { -//                     recipe: ri, -//                     progress: 0., -//                     working: 1, -//                 }); -//                 break 'rloop; -//             } -//             Action::Instant => { -//                 info!("use instant recipe {ri}"); -//                 for _ in 0..items.len() { -//                     out(Consume(0)) -//                 } -//                 for i in &r.outputs { -//                     out(Produce(*i)); -//                 } -//                 if !r.outputs.is_empty() { -//                     out(Take(r.outputs.len() - 1)); -//                 } -//                 items.clear(); -//                 break 'rloop; -//             } -//             Action::Never => (), -//         } -//     } -// } +    None +} -// pub fn tick_tile( -//     dt: f32, -//     data: &Gamedata, -//     _tile: TileIndex, -//     active: &mut Option<Involvement>, -//     items: Vec<ItemIndex>, -//     mut out: impl FnMut(Out), -// ) { -//     if let Some(a) = active { -//         let r = &data.recipes[a.recipe]; -//         a.progress += a.working as f32 * dt / r.action.duration(); -//         if a.progress >= 1. { -//             for _ in 0..items.len() { -//                 out(Consume(0)) -//             } -//             for i in &r.outputs { -//                 out(Produce(*i)); -//             } -//             out(SetActive(None)); -//             active.take(); -//         } else { -//             out(SetActive(Some(a.progress))); -//         } -//     } -// } +pub enum TickEffect { +    Progress, +    Produce, +} +pub fn tick_tile(dt: f32, data: &Gamedata, tile: &mut Tile) -> Option<TickEffect> { +    if let Some(item) = &mut tile.item { +        if let Some(a) = &mut item.active { +            let r = &data.recipes[a.recipe]; +            if r.supports_tile(tile.kind) { +                a.progress += a.working as f32 * dt / r.duration().unwrap(); +                if a.progress >= 1. { +                    let Recipe::Passive { output, .. } = &data.recipes[a.recipe] else { +                        unreachable!() +                    }; +                    tile.item = output.map(|kind| Item { kind, active: None }); +                    return Some(TickEffect::Produce); +                } +                return Some(TickEffect::Progress); +            } +        } else { +            for (ri, recipe) in data.recipes.iter().enumerate() { +                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); +        } +    } +    None +} | 
