td

Artifact [c1f055e58c]
Login

Artifact [c1f055e58c]

Artifact c1f055e58c5350c6f5a385c91d29d63638ffb5ec404b22a3f0f3d994bc012455:


//! PoisonCoating — an on-hit weapon mod that requests a registry-backed poison status.

use macroquad::{
    color::{DARKBROWN, DARKGREEN, GRAY, GREEN, LIME, ORANGE, RED},
    shapes::draw_hexagon,
};

use crate::{
    animations::{
        AnimationClip, AnimationFrame, AnimationSet, DrawItem, FrameOutput, Shape, VisualPriority,
        lerp, visual_slots,
    },
    behavior::projectile::{BehaviorPriority, HitResponse, ProjectileBehavior},
    context::HitContext,
    enemy::Enemy,
    registry::{
        AnimationID, AnimationRef, ContentDefinition, ContentPack, StatusApplication, StatusID,
        StatusSpawn,
    },
    weapons::draw_proj,
    world::Projectile,
};

pub const POISON_PROJECTILE_END_ANIMATION: AnimationRef =
    AnimationRef::new("poison_projectile_end");

#[derive(Clone)]
pub struct PoisonCoating {
    status: StatusID,
    tier: u32,
    end_animation: AnimationID,
}

impl PoisonCoating {
    pub fn create(
        tier: u32,
        status: StatusID,
        end_animation: AnimationID,
    ) -> Box<dyn ProjectileBehavior> {
        Box::new(Self {
            status,
            tier,
            end_animation,
        })
    }
}

impl ProjectileBehavior for PoisonCoating {
    fn contribute_animations(&self, animations: &mut AnimationSet) {
        animations.insert(
            visual_slots::MOVEMENT,
            self.end_animation,
            VisualPriority::OVERRIDE,
        );
    }

    fn priority(&self) -> i32 {
        BehaviorPriority::DEFAULT
    }
    fn on_hit_enemy(
        &mut self,
        p: &mut Projectile,
        _e: &mut Enemy,
        c: &mut HitContext,
    ) -> HitResponse {
        c.status.push(StatusApplication {
            kind: self.status,
            spawn: StatusSpawn {
                tier: self.tier,
                source: p.source,
            },
        });
        HitResponse::PASS
    }
}

pub fn add_content(pack: &mut ContentPack) {
    pack.add_animation(ContentDefinition::direct(
        POISON_PROJECTILE_END_ANIMATION.name(),
        "Poison Projectile End",
        0,
        |_| AnimationClip {
            duration: 4.0,
            draw: draw_projectile_end,
        },
    ));
}

fn draw_projectile_end(frame: &AnimationFrame) -> crate::animations::FrameOutput {
    let rpulse = (frame.elapsed).sin();
    let pulse = 1.0 + (frame.elapsed * 10.0).sin() * 0.06;
    FrameOutput {
        items: vec![DrawItem {
            shape: Shape::Circle {
                pos: frame.pos,
                radius: frame.radius * pulse,
                color: DARKGREEN,
            },
            tint_color: DARKBROWN,
            tint_amount: rpulse,
            alpha: 1.0,
            scale: 1.0 * pulse,
        }],
    }
}