diff options
| author | metamuffin <metamuffin@disroot.org> | 2024-06-18 19:36:36 +0200 | 
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2024-06-23 19:21:22 +0200 | 
| commit | 48934ff63ee14d4759eda36512af87361dd915dd (patch) | |
| tree | f7a80115eacfee7b6871040a87f5fb0087098ea8 /server/src/interaction.rs | |
| parent | 6ec47d729509db83eaeb6a9d855ce2483d70f227 (diff) | |
| download | hurrycurry-48934ff63ee14d4759eda36512af87361dd915dd.tar hurrycurry-48934ff63ee14d4759eda36512af87361dd915dd.tar.bz2 hurrycurry-48934ff63ee14d4759eda36512af87361dd915dd.tar.zst | |
remodel game.
Diffstat (limited to 'server/src/interaction.rs')
| -rw-r--r-- | server/src/interaction.rs | 302 | 
1 files changed, 174 insertions, 128 deletions
| diff --git a/server/src/interaction.rs b/server/src/interaction.rs index 11409b10..aa216410 100644 --- a/server/src/interaction.rs +++ b/server/src/interaction.rs @@ -1,150 +1,196 @@  use crate::{ -    game::ActiveRecipe, +    data::{Action, Gamedata}, +    game::{Involvement, Item, Player, Tile},      protocol::{ItemIndex, TileIndex}, -    recipes::{Action, Gamedata},  };  use log::{debug, info}; +use serde::{Deserialize, Serialize};  use std::collections::BTreeSet; -use Out::*; -pub enum Out { -    Take(usize), -    Put, -    Produce(ItemIndex), -    Consume(usize), -    SetActive(Option<f32>), +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Recipe { +    Passive { +        duration: f32, +        tile: Option<TileIndex>, +        input: ItemIndex, +        output: Option<ItemIndex>, +    }, +    Active { +        duration: f32, +        tile: Option<TileIndex>, +        input: ItemIndex, +        outputs: [Option<ItemIndex>; 2], +    }, +    Instant { +        tile: Option<TileIndex>, +        inputs: [Option<ItemIndex>; 2], +        outputs: [Option<ItemIndex>; 2], +    },  } -pub fn interact( -    data: &Gamedata, -    edge: bool, -    tile: TileIndex, -    active: &mut Option<ActiveRecipe>, -    mut items: Vec<ItemIndex>, -    mut hand: Option<ItemIndex>, -    mut out: impl FnMut(Out), -) { -    let mut allowed = BTreeSet::new(); -    for r in &data.recipes { -        if r.tile == tile { -            allowed.extend(r.inputs.clone()) -        } -    } -    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; -            } +impl Recipe { +    pub fn tile(&self) -> Option<TileIndex> { +        match self { +            Recipe::Passive { tile, .. } => *tile, +            Recipe::Active { tile, .. } => *tile, +            Recipe::Instant { tile, .. } => *tile,          }      } +} -    if active.is_none() && !items.is_empty() && hand.is_none() { -        out(Take(items.len() - 1)); +pub fn interact(data: &Gamedata, edge: bool, tile: &mut Tile, player: &mut Player) { +    if !edge {          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() { +    for recipe in &data.recipes { +        if let Some(tile_constraint) = recipe.tile() { +            if tile.kind != tile_constraint {                  continue;              } - -            match r.action { -                Action::Passive(_) => { -                    info!("use passive recipe {ri}"); -                    *active = Some(ActiveRecipe { -                        recipe: ri, -                        progress: 0., -                        working: 1, -                    }); -                    break 'rloop; -                } -                Action::Active(_) => { -                    info!("use active recipe {ri}"); -                    *active = Some(ActiveRecipe { -                        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; +        } +        match recipe { +            Recipe::Passive { +                duration, +                input, +                output, +                .. +            } => todo!(), +            Recipe::Active { +                duration, +                input: inputs, +                outputs, +                .. +            } => todo!(), +            Recipe::Instant { +                inputs, outputs, .. +            } => { +                let on_tile = tile.item.as_ref().map(|i| i.kind); +                let in_hand = player.item.as_ref().map(|i| i.kind); +                let ok = (inputs[0] == on_tile && inputs[1] == in_hand) +                    || (inputs[1] == on_tile && inputs[0] == in_hand); +                if ok { +                    player.item = outputs[0].map(|kind| Item { kind, active: None }); +                    tile.item = outputs[1].map(|kind| Item { kind, active: None });                  } -                Action::Never => (),              }          }      }  } +// 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; +// } -pub fn tick_tile( -    dt: f32, -    data: &Gamedata, -    _tile: TileIndex, -    active: &mut Option<ActiveRecipe>, -    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))); -        } -    } -} +// 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; +//         } + +//         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 => (), +//         } +//     } +// } + +// 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))); +//         } +//     } +// } | 
