/*
Hurry Curry! - a game about cooking
Copyright (C) 2025 Hurry Curry! Contributors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, version 3 of the License only.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
*/
use super::{Entity, EntityContext};
use crate::interaction::interact;
use anyhow::{anyhow, bail, Result};
use hurrycurry_protocol::{glam::IVec2, ItemIndex, ItemLocation};
#[derive(Debug, Clone)]
pub struct Conveyor {
pub(super) from: IVec2,
pub(super) to: IVec2,
pub(super) filter_tile: Option,
pub(super) filter_item: Option,
pub(super) cooldown: f32,
pub(super) max_cooldown: f32,
}
impl Entity for Conveyor {
fn tick(&mut self, c: EntityContext) -> Result<()> {
let from = c
.game
.tiles
.get(&self.from)
.ok_or(anyhow!("conveyor from missing"))?;
if let Some(from_item) = from.item.as_ref() {
let filter = if let Some(t) = &self.filter_tile {
let filter_tile = c
.game
.tiles
.get(t)
.ok_or(anyhow!("conveyor filter missing"))?;
filter_tile.item.as_ref().map(|e| e.kind)
} else {
self.filter_item.as_ref().map(|i| *i)
};
if let Some(filter) = filter {
if from_item.kind != filter {
return Ok(());
}
}
self.cooldown += c.dt;
if self.cooldown < self.max_cooldown {
return Ok(());
}
self.cooldown = 0.;
if self.from == self.to {
bail!("conveyor does ends in itself")
}
let [Some(from), Some(to)] = c.game.tiles.get_disjoint_mut([&self.from, &self.to])
else {
bail!("at least one conveyor end not on map");
};
interact(
&c.game.data,
true,
Some(to.kind),
None,
&mut to.item,
ItemLocation::Tile(self.to),
&mut from.item,
ItemLocation::Tile(self.from),
&mut c.game.score,
c.score_changed,
true,
c.packet_out,
);
}
Ok(())
}
}