/crates/broanetco_game/src/texture.rs
Rust | 398 lines | 338 code | 30 blank | 30 comment | 16 complexity | 92dcce374aa4704b303960a1f7c7350f MD5 | raw file
- /*
- * Copyright 2018 Ricardo Luis Souza Ardissone
- *
- * This file is part of BroaNetCo.
- *
- * BroaNetCo is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * BroaNetCo 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with BroaNetCo. If not, see <http://www.gnu.org/licenses/>.
- */
- use std::iter;
- use std::path::PathBuf;
- use crate::map::*;
- use crate::replay::{ReplayLog, ReplayLoggerMessage};
- use crate::*;
- pub type NTDGroup<T> = (TextureParams, Vec<T>);
- #[allow(dead_code)]
- pub type NTDTGroup = NTDGroup<NamedTextureDataTransfer>;
- pub type MapNTDGroup<T> = Vec<T>;
- #[derive(Clone, Debug, Serialize, Deserialize, Default, Derivative)]
- #[derivative(Hash)]
- pub struct NamedTextureData<TE> {
- #[serde(skip_serializing)]
- #[serde(skip_deserializing)]
- #[derivative(Hash = "ignore")]
- pub texture_data: TE,
- // TODO: An alternative to this
- pub asset_path: NTDAssetPath,
- }
- /// Doesn't contain actual textures, just the asset name
- pub type NamedTextureDataTransfer = NamedTextureData<()>;
- impl<T> NamedTextureData<T> {
- pub const fn new_textured(asset_path: NTDAssetPath, texture_data: T) -> Self {
- Self {
- asset_path,
- texture_data,
- }
- }
- }
- impl NamedTextureDataTransfer {
- pub const fn new(asset_path: NTDAssetPath) -> Self {
- Self::new_textured(asset_path, ())
- }
- }
- /// Information about how the NTDGroup should be drawn
- #[derive(Copy, Clone, Debug, Serialize, Hash, Deserialize, Derivative)]
- #[derivative(Default)]
- pub enum TextureParams {
- #[derivative(Default)]
- /// Rotate the top of the image to the direction it is pointing to
- /// Draw entire image with scaling
- TopDown,
- /// Draw the entire image without rotation with scaling
- Simple,
- /// Treat the image as if from https://github.com/cosmo-ray/Universal-LPC-spritesheet
- LPC,
- }
- /// Where to find an image for texture
- #[derive(Clone, Debug, Serialize, Hash, Deserialize, Derivative)]
- #[derivative(Default)]
- pub enum NTDAssetPath {
- /// Simple image loaded from file
- #[derivative(Default)]
- Image(PathBuf),
- /// Layer of an xcf file
- #[cfg(feature = "xcf")]
- XcfLayer { layer: String, file_path: PathBuf },
- }
- pub type NTDT = NamedTextureDataTransfer;
- pub trait NTDTrait: TryIntoParams<(), NamedTextureDataTransfer> + Debug + Clone {}
- /// Try Into with parameters
- pub trait TryIntoParams<Params, Out> {
- type Error: Debug;
- fn try_into_params(self, params: &mut Params) -> Result<Out, Self::Error>;
- }
- /// Into with parameters
- pub trait IntoParams<Params, Out> {
- fn into_params(self, params: &mut Params) -> Out;
- }
- impl<Params, Out, T> IntoParams<Params, Out> for T
- where
- T: TryIntoParams<Params, Out, Error = Void>,
- {
- fn into_params(self, params: &mut Params) -> Out {
- self.try_into_params(params).unwrap()
- }
- }
- impl NTDTrait for NamedTextureDataTransfer {}
- impl TryIntoParams<(), NamedTextureDataTransfer> for NamedTextureDataTransfer {
- type Error = Void;
- fn try_into_params(self, (): &mut ()) -> Result<NamedTextureDataTransfer, Void> {
- Ok(self)
- }
- }
- fn it_ut<
- Params,
- IN: TryIntoParams<Params, OUT, Error = Error>,
- OUT,
- IT: iter::IntoIterator<Item = IN>,
- OUTIT: iter::FromIterator<OUT>,
- Error: Debug,
- >(
- iter: IT,
- params: &mut Params,
- ) -> Result<OUTIT, Error> {
- crate::util::iter_result_convert(iter, |x| x.try_into_params(params))
- }
- impl<Params, NTD: TryIntoParams<Params, NTDOut>, NTDOut> TryIntoParams<Params, GSInit<NTDOut>>
- for GSInit<NTD>
- {
- type Error = <NTD as TryIntoParams<Params, NTDOut>>::Error;
- fn try_into_params(self, params: &mut Params) -> Result<GSInit<NTDOut>, Self::Error> {
- use GSInit::*;
- Ok(match self {
- GGSA(vec) => GGSA(it_ut(vec, params)?),
- ReplayLog(log) => ReplayLog(Box::new(log.try_into_params(params)?)),
- })
- }
- }
- impl<Params, NTD: TryIntoParams<Params, NTDOut>, NTDOut>
- TryIntoParams<Params, ReplayLoggerMessage<NTDOut>> for ReplayLoggerMessage<NTD>
- {
- type Error = <NTD as TryIntoParams<Params, NTDOut>>::Error;
- fn try_into_params(
- self,
- params: &mut Params,
- ) -> Result<ReplayLoggerMessage<NTDOut>, Self::Error> {
- Ok(match self {
- Self::GSApply(gsa) => ReplayLoggerMessage::GSApply(gsa),
- Self::GodGSApply(ggsa) => {
- ReplayLoggerMessage::GodGSApply(ggsa.try_into_params(params)?)
- }
- })
- }
- }
- impl<Params, NTD: TryIntoParams<Params, NTDOut>, NTDOut> TryIntoParams<Params, ReplayLog<NTDOut>>
- for ReplayLog<NTD>
- {
- type Error = <NTD as TryIntoParams<Params, NTDOut>>::Error;
- fn try_into_params(self, params: &mut Params) -> Result<ReplayLog<NTDOut>, Self::Error> {
- Ok((self.0.try_into_params(params)?, it_ut(self.1, params)?))
- }
- }
- impl<Params, NTD: TryIntoParams<Params, NTDOut>, NTDOut> TryIntoParams<Params, MapElement<NTDOut>>
- for MapElement<NTD>
- {
- type Error = <NTD as TryIntoParams<Params, NTDOut>>::Error;
- fn try_into_params(self, params: &mut Params) -> Result<MapElement<NTDOut>, Self::Error> {
- let dissolved: (_, _, _, _, _, _, _, _, _, _) = self.into();
- let converted = (
- dissolved.0,
- dissolved.1,
- dissolved.2,
- dissolved.3,
- dissolved.4,
- dissolved.5,
- dissolved.6,
- dissolved.7,
- it_ut(dissolved.8, params)?,
- dissolved.9,
- );
- Ok(converted.into())
- }
- }
- impl<Params, TOut, TIn: TryIntoParams<Params, TOut>> TryIntoParams<Params, (MapLocation, TOut)>
- for (MapLocation, TIn)
- {
- type Error = <TIn as TryIntoParams<Params, TOut>>::Error;
- fn try_into_params(self, params: &mut Params) -> Result<(MapLocation, TOut), Self::Error> {
- Ok((self.0, self.1.try_into_params(params)?))
- }
- }
- impl<Params, T2, T: TryIntoParams<Params, T2>> TryIntoParams<Params, Option<T2>> for Option<T> {
- type Error = <T as TryIntoParams<Params, T2>>::Error;
- fn try_into_params(self, params: &mut Params) -> Result<Option<T2>, Self::Error> {
- self.map(|x| x.try_into_params(params)).transpose()
- }
- }
- impl<Params, NTD: TryIntoParams<Params, NTDOut>, NTDOut> TryIntoParams<Params, Map<NTDOut>>
- for Map<NTD>
- {
- type Error = <NTD as TryIntoParams<Params, NTDOut>>::Error;
- fn try_into_params(self, params: &mut Params) -> Result<Map<NTDOut>, Self::Error> {
- use toodee::TooDeeOps;
- let dissolved: (_, _, _) = self.into();
- let converted = (
- dissolved.0,
- dissolved.1,
- TooDee::from_vec(
- dissolved.2.num_cols(),
- dissolved.2.num_rows(),
- crate::util::iter_result_convert(dissolved.2, |x| x.try_into_params(params))?,
- ),
- );
- Ok(converted.into())
- }
- }
- impl<T, Params, NTD: TryIntoParams<Params, NTDOut>, NTDOut>
- TryIntoParams<Params, (Status<NTDOut>, T)> for (Status<NTD>, T)
- {
- type Error = <NTD as TryIntoParams<Params, NTDOut>>::Error;
- fn try_into_params(self, params: &mut Params) -> Result<(Status<NTDOut>, T), Self::Error> {
- Ok((self.0.try_into_params(params)?, self.1))
- }
- }
- impl<Params, NTD: TryIntoParams<Params, NTDOut>, NTDOut> TryIntoParams<Params, Status<NTDOut>>
- for Status<NTD>
- {
- type Error = <NTD as TryIntoParams<Params, NTDOut>>::Error;
- fn try_into_params(self, params: &mut Params) -> Result<Status<NTDOut>, Self::Error> {
- let dissolved: (_, _, _, _, _, _, _) = self.into();
- let (a, b) = dissolved.6;
- let converted = (
- dissolved.0,
- it_ut::<_, _, _, Vec<_>, Vec<_>, _>(dissolved.1.into(), params)?.into(),
- it_ut::<_, _, _, Vec<_>, Vec<_>, _>(dissolved.2.into(), params)?.into(),
- dissolved.3,
- dissolved.4,
- dissolved.5,
- (a, it_ut(b, params)?),
- );
- Ok(converted.into())
- }
- }
- impl<Params, NTD: TryIntoParams<Params, NTDOut>, NTDOut> TryIntoParams<Params, Combater<NTDOut>>
- for Combater<NTD>
- {
- type Error = <NTD as TryIntoParams<Params, NTDOut>>::Error;
- fn try_into_params(self, params: &mut Params) -> Result<Combater<NTDOut>, Self::Error> {
- let dissolved: (_, _, _, _, _, _, _, _, _, _) = self.into();
- let (a, b) = dissolved.7;
- let converted = (
- dissolved.0,
- it_ut(dissolved.1, params)?,
- dissolved.2,
- dissolved.3,
- dissolved.4,
- dissolved.5,
- dissolved.6,
- (a, it_ut(b, params)?),
- dissolved.8,
- dissolved.9,
- );
- Ok(converted.into())
- }
- }
- impl<Params, NTD: TryIntoParams<Params, NTDOut>, NTDOut> TryIntoParams<Params, Faction<NTDOut>>
- for Faction<NTD>
- {
- type Error = <NTD as TryIntoParams<Params, NTDOut>>::Error;
- fn try_into_params(self, params: &mut Params) -> Result<Faction<NTDOut>, Self::Error> {
- let dissolved: (_, _, _, _, _) = self.into();
- let converted = (
- dissolved.0,
- dissolved.1,
- dissolved.2,
- dissolved.3,
- dissolved.4.try_into_params(params)?,
- );
- Ok(converted.into())
- }
- }
- impl<Params, NTD: TryIntoParams<Params, NTDOut>, NTDOut> TryIntoParams<Params, GodGSApply<NTDOut>>
- for GodGSApply<NTD>
- {
- type Error = <NTD as TryIntoParams<Params, NTDOut>>::Error;
- fn try_into_params(self, params: &mut Params) -> Result<GodGSApply<NTDOut>, Self::Error> {
- use GodGSApply::*;
- Ok(match self {
- AddCombater(com) => AddCombater(com.try_into_params(params)?),
- AddFaction(faction) => AddFaction(faction.try_into_params(params)?),
- AddAIGameMaster(priority, aigm) => {
- AddAIGameMaster(priority, aigm.try_into_params(params)?)
- }
- SetMapElement { location, element } => SetMapElement {
- location,
- element: element.try_into_params(params)?,
- },
- GSApply(gsapply) => GSApply(gsapply),
- SetRNG(seed) => SetRNG(seed),
- SetPlayingID(id) => SetPlayingID(id),
- SetName(name) => SetName(name),
- SetTick(x) => SetTick(x),
- GSEffect(x) => GSEffect(x),
- })
- }
- }
- impl<Params, NTD: TryIntoParams<Params, NTDOut>, NTDOut> TryIntoParams<Params, AIGameMaster<NTDOut>>
- for AIGameMaster<NTD>
- {
- type Error = <NTD as TryIntoParams<Params, NTDOut>>::Error;
- fn try_into_params(self, params: &mut Params) -> Result<AIGameMaster<NTDOut>, Self::Error> {
- use AIGameMaster::*;
- Ok(match self {
- ExpandMapRangeCombater { range, element } => ExpandMapRangeCombater {
- range,
- element: element.try_into_params(params)?,
- },
- MapSpreader {
- interval,
- next_tick,
- spreader_name,
- odds,
- overtextures,
- new_element,
- range,
- } => MapSpreader {
- interval,
- next_tick,
- spreader_name,
- odds,
- overtextures,
- new_element: new_element.try_into_params(params)?,
- range,
- },
- Spawn {
- positions,
- combater,
- next_tick,
- interval,
- } => Spawn {
- positions,
- combater,
- next_tick,
- interval,
- },
- KingOfTheHill {
- valid_for,
- position,
- ticks,
- startcount,
- } => KingOfTheHill {
- valid_for,
- position,
- ticks,
- startcount,
- },
- CombaterEffectOnTerrain {
- map_element_name,
- effect,
- } => CombaterEffectOnTerrain {
- map_element_name,
- effect,
- },
- LastManStanding { valid_for } => LastManStanding { valid_for },
- Choice {
- tick,
- faction,
- text,
- choices,
- } => Choice {
- tick,
- faction,
- text,
- choices,
- },
- RevealMap { range } => RevealMap { range },
- })
- }
- }