use proc_macro::TokenStream;
use quote::quote;
use syn::DeriveInput;
pub fn impl_unit(ast: &DeriveInput) -> TokenStream {
let name = &ast.ident;
let stream = quote! {
mod __impl_unit {
use super::#name;
use crate::infrastructure::building::BuildingId;
use crate::infrastructure::requirements::InfrastructureRequirements;
use crate::military::unit::{Unit, UnitBox, UnitChunk, UnitId, UnitKind};
use crate::military::unit::stats::prelude::*;
use crate::ranking::score::Score;
use crate::world::config::WorldConfig;
impl #name {
pub fn new_boxed() -> UnitBox {
UnitBox::new(Box::new(Self))
}
}
impl Unit for #name {
fn id(&self) -> UnitId {
Self::ID
}
fn kind(&self) -> UnitKind {
Self::KIND
}
fn building(&self) -> BuildingId {
Self::BUILDING
}
fn score(&self) -> Score {
Self::SCORE
}
fn stats(&self) -> &UnitStats {
&Self::STATS
}
fn attack(&self) -> Power {
Self::STATS.attack()
}
fn infantry_defense(&self) -> Power {
Self::STATS.infantry_defense()
}
fn cavalry_defense(&self) -> Power {
Self::STATS.cavalry_defense()
}
fn ranged_defense(&self) -> Power {
Self::STATS.ranged_defense()
}
fn ranged_debuff(&self) -> RangedDebuff {
Self::STATS.ranged_debuff()
}
fn speed(&self, config: &WorldConfig) -> Speed {
let base_speed = f64::from(Self::STATS.base_speed());
Speed::new((base_speed * config.unit_speed()).max(0.1))
}
fn haul(&self) -> Haul {
Self::STATS.haul()
}
fn chunk(&self) -> &UnitChunk {
&Self::CHUNK
}
fn infrastructure_requirements(&self) -> &InfrastructureRequirements {
&Self::INFRASTRUCTURE_REQUIREMENTS
}
}
impl From<#name> for UnitId {
fn from(_: #name) -> UnitId {
#name::ID
}
}
}
};
stream.into()
}