/*
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 crate::{Gamedata, ItemIndex, Recipe, RecipeIndex, TileIndex};
impl Gamedata {
pub fn tile_name(&self, index: TileIndex) -> &str {
&self.tile_names[index.0]
}
pub fn item_name(&self, index: ItemIndex) -> &str {
&self.item_names[index.0]
}
pub fn recipe(&self, index: RecipeIndex) -> &Recipe {
&self.recipes[index.0]
}
pub fn get_tile_by_name(&self, name: &str) -> Option {
self.tile_names
.iter()
.position(|t| t == name)
.map(TileIndex)
}
pub fn get_item_by_name(&self, name: &str) -> Option {
self.item_names
.iter()
.position(|t| t == name)
.map(ItemIndex)
}
pub fn recipes(&self) -> impl Iterator- {
self.recipes
.iter()
.enumerate()
.map(|(i, e)| (RecipeIndex(i), e))
}
}
impl Recipe {
pub fn tile(&self) -> Option {
match self {
Recipe::Passive { tile, .. } => *tile,
Recipe::Active { tile, .. } => *tile,
Recipe::Instant { tile, .. } => *tile,
}
}
pub fn speed(&self) -> Option {
match self {
Recipe::Passive { speed, .. } => Some(*speed),
Recipe::Active { speed, .. } => Some(*speed),
_ => None,
}
}
pub fn revert_speed(&self) -> Option {
match self {
Recipe::Passive { revert_speed, .. } => *revert_speed,
_ => None,
}
}
pub fn warn(&self) -> bool {
match self {
Recipe::Passive { warn, .. } => *warn,
_ => false,
}
}
pub fn inputs(&self) -> Vec {
match self {
Recipe::Passive { input, .. } => vec![*input],
Recipe::Active { input, .. } => vec![*input],
Recipe::Instant { inputs, .. } => inputs.iter().flat_map(|e| e.to_owned()).collect(),
}
}
pub fn outputs(&self) -> Vec {
match self {
Recipe::Passive { output, .. } => output.iter().copied().collect(),
Recipe::Active { outputs, .. } => outputs.iter().flat_map(|e| e.to_owned()).collect(),
Recipe::Instant { outputs, .. } => outputs.iter().flat_map(|e| e.to_owned()).collect(),
}
}
pub fn supports_tile(&self, tile: Option) -> bool {
if let Some(tile_constraint) = self.tile() {
if let Some(tile) = tile {
tile == tile_constraint
} else {
false
}
} else {
true
}
}
}
mod display {
use crate::*;
use std::fmt::Display;
impl Display for ItemLocation {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ItemLocation::Tile(pos) => write!(f, "tile({}, {})", pos.x, pos.y),
ItemLocation::Player(player, hand) => write!(f, "{player}-{hand}"),
}
}
}
impl Display for Hand {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "hand#{}", self.0)
}
}
impl Display for PlayerID {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "player#{}", self.0)
}
}
impl Display for TileIndex {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "tile#{}", self.0)
}
}
impl Display for ItemIndex {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "item#{}", self.0)
}
}
impl Display for RecipeIndex {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "recipe#{}", self.0)
}
}
}
mod enum_is {
use crate::*;
impl PlayerClass {
pub fn is_cheflike(&self) -> bool {
matches!(self, Self::Bot | Self::Chef)
}
}
impl ItemLocation {
pub fn is_tile(&self) -> bool {
matches!(self, Self::Tile(..))
}
pub fn is_player(&self) -> bool {
matches!(self, Self::Player(..))
}
}
}
pub mod deser {
use crate::*;
use serde::Deserializer;
use std::collections::BTreeMap;
pub(crate) fn deser_i64<'de, D: Deserializer<'de>>(deserializer: D) -> Result {
let x = f64::deserialize(deserializer)?;
Ok(x.trunc() as i64)
}
pub(crate) fn deser_i32<'de, D: Deserializer<'de>>(deserializer: D) -> Result {
let x = f64::deserialize(deserializer)?;
Ok(x.trunc() as i32)
}
pub(crate) fn deser_usize<'de, D: Deserializer<'de>>(
deserializer: D,
) -> Result {
let x = f64::deserialize(deserializer)?;
Ok(x.trunc() as usize)
}
pub(crate) fn deser_tile_index_map<'de, D: Deserializer<'de>>(
deserializer: D,
) -> Result>, D::Error> {
let x = BTreeMap::>::deserialize(deserializer)?;
Ok(x.into_iter()
.map(|(k, v)| (TileIndex(k.parse().ok().unwrap_or_default()), v))
.collect())
}
}