use ggez::{Context, GameResult};
use ggez::graphics::{self, DrawParam};
use crate::core::resources::Resources;
use crate::ui::grid::{GRID_START_X, GRID_START_Y, GRID_CELL_HEIGHT, GRID_CELL_WIDTH};
use crate::entities::sun::Sun;
use crate::entities::pea::Pea;
pub mod peashooter;
pub mod sunflower;
pub mod wallnut;
pub mod plant_trait;
pub mod plant_factory;
pub use plant_factory::{PlantType, PlantFactory};
pub struct Plant {
pub grid_x: usize,
pub grid_y: usize,
pub health: i32,
max_health: i32,
animation_frame: usize,
animation_timer: u64,
cooldown_timer: u64,
pub is_dead: bool,
plant_impl: Box<dyn plant_trait::PlantTrait>,
plant_type: PlantType,
}
impl Plant {
pub fn new(plant_type: PlantType, grid_x: usize, grid_y: usize) -> Self {
let plant_impl = PlantFactory::create_plant(plant_type);
let health = plant_impl.get_initial_health();
Plant {
grid_x,
grid_y,
health,
max_health: health, animation_frame: 0,
animation_timer: 0,
cooldown_timer: 0,
is_dead: false,
plant_impl,
plant_type,
}
}
pub fn update(&mut self, dt: u64, suns: &mut Vec<Sun>, peas: &mut Vec<Pea>) {
if self.is_dead {
return; }
self.animation_timer += dt;
if self.animation_timer > 100 { let frame_count = self.plant_impl.get_frame_count();
if frame_count > 0 {
self.animation_frame = (self.animation_frame + 1) % frame_count;
}
self.animation_timer = 0;
}
let cooldown = self.plant_impl.get_cooldown();
if cooldown > 0 {
self.cooldown_timer += dt;
if self.cooldown_timer >= cooldown {
self.cooldown_timer = 0;
self.plant_impl.update_action(self.grid_x, self.grid_y, suns, peas);
}
}
self.plant_impl.special_effect(self.grid_x, self.grid_y);
}
pub fn draw(&self, ctx: &mut Context, resources: &Resources) -> GameResult {
let x = GRID_START_X + (self.grid_x as f32) * GRID_CELL_WIDTH + GRID_CELL_WIDTH / 4.0;
let y = GRID_START_Y + (self.grid_y as f32) * GRID_CELL_HEIGHT + GRID_CELL_HEIGHT / 4.0;
let image = self.plant_impl.get_current_frame_image(resources, self.animation_frame);
graphics::draw(
ctx,
image,
DrawParam::default()
.dest([x, y])
.scale([0.8, 0.8]),
)
}
pub fn take_damage(&mut self, damage: i32) -> bool {
self.health -= damage;
if self.health <= 0 {
self.is_dead = true;
return true; }
false }
pub fn get_damage_state(&self) -> usize {
self.plant_impl.get_damage_state()
}
pub fn get_plant_type(&self) -> PlantType {
self.plant_type
}
}