diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/src/game.rs | 26 | ||||
-rw-r--r-- | server/src/interaction.rs | 64 |
2 files changed, 78 insertions, 12 deletions
diff --git a/server/src/game.rs b/server/src/game.rs index 46bc0569..35502d3c 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -33,7 +33,7 @@ pub struct Tile { pub struct Player { pub name: String, pub position: Vec2, - pub interacting: bool, + pub interacting: Option<IVec2>, pub item: Option<Item>, } @@ -98,7 +98,7 @@ impl Game { Player { item: None, position: self.data.spawn, - interacting: false, + interacting: None, name: name.clone(), }, ); @@ -113,8 +113,17 @@ impl Game { .players .remove(&player) .ok_or(anyhow!("player does not exist"))?; - if let Some(_id) = p.item { - // TODO place on ground + if let Some(item) = p.item { + let pos = p.position.floor().as_ivec2(); + if let Some(tile) = self.tiles.get_mut(&pos) { + if tile.item.is_none() { + self.packet_out.push_back(PacketC::ProduceItem { + tile: pos, + item: item.kind, + }); + tile.item = Some(item); + } + } } self.packet_out .push_back(PacketC::RemovePlayer { id: player }) @@ -140,8 +149,11 @@ impl Game { .get_mut(&pos) .ok_or(anyhow!("tile does not exist"))?; - if edge == player.interacting { - bail!("already (not) interacting") + if edge && player.interacting.is_some() { + bail!("already interacting") + } + if !edge && player.interacting != Some(pos) { + bail!("already not interacting here") } let tile_had_item = tile.item.is_some(); @@ -190,7 +202,7 @@ impl Game { } } - player.interacting = edge; + player.interacting = if edge { Some(pos) } else { None }; } } Ok(()) diff --git a/server/src/interaction.rs b/server/src/interaction.rs index 75cd0c84..d43c71da 100644 --- a/server/src/interaction.rs +++ b/server/src/interaction.rs @@ -66,15 +66,69 @@ pub fn interact( tile: &mut Tile, player: &mut Player, ) -> Option<InteractEffect> { + if player.item.is_none() { + if let Some(item) = &mut tile.item { + if let Some(active) = &mut item.active { + let recipe = &data.recipes[active.recipe]; + if recipe.supports_tile(tile.kind) { + if let Recipe::Active { outputs, .. } = recipe { + if edge { + active.working += 1; + } else { + active.working -= 1; + if active.progress >= 1. { + 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 { return None; } - for recipe in &data.recipes { + for (ri, recipe) in data.recipes.iter().enumerate() { if !recipe.supports_tile(tile.kind) { continue; } match recipe { + Recipe::Active { input, .. } => { + if player.item.is_none() { + if let Some(item) = &mut tile.item { + if item.kind == *input { + if item.active.is_none() { + item.active = Some(Involvement { + recipe: ri, + working: 1, + progress: 0., + }); + } + } + } + } + if tile.item.is_none() { + if let Some(item) = &player.item { + if item.kind == *input { + let mut item = player.item.take().unwrap(); + if let Some(active) = &mut item.active { + active.working += 1; + } else { + item.active = Some(Involvement { + recipe: ri, + working: 1, + progress: 0., + }); + } + tile.item = Some(item); + return Some(InteractEffect::Put); + } + } + } + } Recipe::Instant { inputs, outputs, .. } => { @@ -119,11 +173,11 @@ pub fn tick_tile(dt: f32, data: &Gamedata, tile: &mut Tile) -> Option<TickEffect 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!() + if let Recipe::Passive { output, .. } = &data.recipes[a.recipe] { + tile.item = output.map(|kind| Item { kind, active: None }); + return Some(TickEffect::Produce); }; - tile.item = output.map(|kind| Item { kind, active: None }); - return Some(TickEffect::Produce); + a.progress = 1.; } return Some(TickEffect::Progress); } |