diff options
author | metamuffin <metamuffin@disroot.org> | 2025-09-30 01:19:01 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-09-30 01:19:09 +0200 |
commit | 5033c326094edc1ff4234b994e95d987cb937fc4 (patch) | |
tree | 5fa426a77109722df163c15ce8d647170cd8fcea /server/src/interaction.rs | |
parent | 727752b87bbe7146adb0f9e9e27d6e64b785ec2f (diff) | |
download | hurrycurry-5033c326094edc1ff4234b994e95d987cb937fc4.tar hurrycurry-5033c326094edc1ff4234b994e95d987cb937fc4.tar.bz2 hurrycurry-5033c326094edc1ff4234b994e95d987cb937fc4.tar.zst |
Implement tile placeable items for server-side (#433)
Diffstat (limited to 'server/src/interaction.rs')
-rw-r--r-- | server/src/interaction.rs | 179 |
1 files changed, 92 insertions, 87 deletions
diff --git a/server/src/interaction.rs b/server/src/interaction.rs index 624d9893..8f591db1 100644 --- a/server/src/interaction.rs +++ b/server/src/interaction.rs @@ -15,8 +15,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */ -use crate::data::index::GamedataIndex; -use hurrycurry_client_lib::{Involvement, Item}; +use hurrycurry_client_lib::{gamedata_index::GamedataIndex, Involvement, Item}; use hurrycurry_protocol::{Gamedata, ItemLocation, PacketC, PlayerID, Recipe, Score, TileIndex}; use log::info; use std::collections::VecDeque; @@ -36,11 +35,11 @@ pub fn interact( automated: bool, packet_out: &mut VecDeque<PacketC>, ) { - let interactable = automated - || tile - .map(|tile| data.is_tile_interactable(tile)) - .unwrap_or(true); - if interactable && other.is_none() { + // let interactable = automated + // || tile + // .map(|tile| data.is_tile_interactable(tile)) + // .unwrap_or(true); + if other.is_none() { if let Some(item) = this { if let Some(active) = &mut item.active { let recipe = &data.recipe(active.recipe); @@ -85,96 +84,102 @@ pub fn interact( if !edge { return; } - if interactable { - for (ri, recipe) in data.recipes() { - if !recipe.supports_tile(tile) { - continue; - } - match recipe { - Recipe::Active { input, speed, .. } => { - if other.is_none() { - if let Some(item) = this { - if item.kind == *input && item.active.is_none() { - info!("start active recipe {ri:?}"); - item.active = Some(Involvement { - player, - recipe: ri, - speed: *speed, - position: 0., - warn: false, - }); - } + for (ri, recipe) in data.recipes() { + if !recipe.supports_tile(tile) { + continue; + } + match recipe { + Recipe::Active { input, speed, .. } => { + if other.is_none() { + if let Some(item) = this { + if item.kind == *input && item.active.is_none() { + info!("start active recipe {ri:?}"); + item.active = Some(Involvement { + player, + recipe: ri, + speed: *speed, + position: 0., + warn: false, + }); } } - if this.is_none() { - if let Some(item) = &other { - if item.kind == *input && item.active.is_none() { - let mut item = other.take().unwrap(); - info!("start active recipe {ri:?}"); - item.active = Some(Involvement { - player, - recipe: ri, - speed: *speed, - position: 0., - warn: false, - }); - *this = Some(item); - score.active_recipes += 1; - packet_out.push_back(PacketC::MoveItem { - from: other_loc, - to: this_loc, - }); - packet_out.push_back(PacketC::SetProgress { - player, - item: this_loc, - position: 0., - speed: *speed, - warn: false, - }); - return; - } + } + if this.is_none() { + if let Some(item) = &other { + if item.kind == *input && item.active.is_none() { + let mut item = other.take().unwrap(); + info!("start active recipe {ri:?}"); + item.active = Some(Involvement { + player, + recipe: ri, + speed: *speed, + position: 0., + warn: false, + }); + *this = Some(item); + score.active_recipes += 1; + packet_out.push_back(PacketC::MoveItem { + from: other_loc, + to: this_loc, + }); + packet_out.push_back(PacketC::SetProgress { + player, + item: this_loc, + position: 0., + speed: *speed, + warn: false, + }); + return; } } } - Recipe::Instant { - inputs, - outputs, - points: pd, - .. - } => { - let on_tile = this.as_ref().map(|i| i.kind); - let in_hand = other.as_ref().map(|i| i.kind); - let ok = inputs[0] == on_tile && inputs[1] == in_hand; - let ok_rev = inputs[1] == on_tile && inputs[0] == in_hand; - if ok || ok_rev { - info!("instant recipe {ri:?} reversed={ok_rev}"); - let ok_rev = ok_rev as usize; - let this_had_item = this.is_some(); - let other_had_item = other.is_some(); - *other = outputs[1 - ok_rev].map(|kind| Item { kind, active: None }); - *this = outputs[ok_rev].map(|kind| Item { kind, active: None }); - score.points += pd; - score.instant_recipes += 1; - *score_changed = true; - produce( - this_had_item, - other_had_item, - this, - this_loc, - other, - other_loc, - score_changed, - packet_out, - ); - return; - } + } + Recipe::Instant { + inputs, + outputs, + points: pd, + .. + } => { + let on_tile = this.as_ref().map(|i| i.kind); + let in_hand = other.as_ref().map(|i| i.kind); + let ok = inputs[0] == on_tile && inputs[1] == in_hand; + let ok_rev = inputs[1] == on_tile && inputs[0] == in_hand; + if ok || ok_rev { + info!("instant recipe {ri:?} reversed={ok_rev}"); + let ok_rev = ok_rev as usize; + let this_had_item = this.is_some(); + let other_had_item = other.is_some(); + *other = outputs[1 - ok_rev].map(|kind| Item { kind, active: None }); + *this = outputs[ok_rev].map(|kind| Item { kind, active: None }); + score.points += pd; + score.instant_recipes += 1; + *score_changed = true; + produce( + this_had_item, + other_had_item, + this, + this_loc, + other, + other_loc, + score_changed, + packet_out, + ); + return; } - _ => (), } + _ => (), } } - if interactable && this.is_none() { + let can_place = tile.map_or(true, |tile| { + other.as_ref().map_or(false, |other| { + data.tile_placeable_items + .get(&tile) + .map_or(true, |pl| pl.contains(&other.kind)) + }) + }); + + if can_place && this.is_none() { if let Some(item) = other.take() { *this = Some(item); packet_out.push_back(PacketC::MoveItem { |