#include <StdAfx.h>
#include "morey_eel.h"
#include "phd_math.h"
#include "utility.h"
#include "Class/TRClass.h"

extern TYPE2_AnimateItem AnimateItem_2;
extern TYPE_phd_atan phd_atan;
extern TYPE_phd_sqrt phd_sqrt;
extern TYPE2_DoBloodSplat DoBloodSplat_2;
extern TYPE_CreatureEffect CreatureEffect;
extern TYPE_CreatureCollision CreatureCollision;
extern TYPE_DrawAnimatingItem DrawAnimatingItem;

#define HP_MOREYBLACK (20)
#define BIGEEL_DAMAGE 500
#define BIGEEL_ANGLE 1820
#define BIGEEL_RANGE 6144
#define BIGEEL_MOVE 102
#define BIGEEL_LENGTH 2560
#define BIGEEL_SLIDE (BIGEEL_RANGE - BIGEEL_LENGTH)
#define BIGEEL_DIE_ANIM 2
#define BIGEEL_TOUCH 0x180

#define HP_MOREYYELLOW (5)
#define EEL_DAMAGE 50
#define EEL_ANGLE 1820
#define EEL_RANGE 2048
#define EEL_MOVE 102
#define EEL_TURN 91
#define EEL_LENGTH 512
#define EEL_SLIDE (EEL_RANGE - EEL_LENGTH)
#define EEL_DIE_ANIM 3

enum EEL_STATE
{
    BIGEEL_EMPTY,
    BIGEEL_ATTACK,
    BIGEEL_STOP,
    BIGEEL_DEATH
};

BITE_INFO bigeel_bite = { 7, 157, 333, 7 };

void CtrlTR2_MoreyEelBlack(short item_number)
{
    ITEM_INFO* item;
    sint16 angle;
    sint32 distance, x, z, pos;
    short dmg1;

    item = &Ptr_VetItems[item_number];
    pos = item->reserved_4;
    item->pos.z_pos -= pos * phd_cos_tr2(item->pos.y_rot) >> W2V_SHIFT;
    item->pos.x_pos -= pos * phd_sin_tr2(item->pos.y_rot) >> W2V_SHIFT;
    dmg1 = Utils.getObjectAttribute(tsu_slots[item->object_number], ATT_DMG1);

    if (item->hit_points <= 0)
    {
        /* Move eel out to fully extended for death */
        if (pos < BIGEEL_SLIDE)
            pos += BIGEEL_MOVE;

        if (item->current_anim_state != BIGEEL_DEATH)
        {
            item->anim_number = Ptr_VetObjects[item->object_number].anim_index + BIGEEL_DIE_ANIM;
            item->frame_number = Ptr_VetAnimations[item->anim_number].frame_base;
            item->current_anim_state = BIGEEL_DEATH;
        }
    }
    else
    {
        /* Relative squared distance and facing information */
        z = LaraItem->pos.z_pos - item->pos.z_pos;
        x = LaraItem->pos.x_pos - item->pos.x_pos;

        angle = phd_atan(z, x) - item->pos.y_rot;
        distance = ABS(x) <= BIGEEL_RANGE && ABS(z) <= BIGEEL_RANGE ? phd_sqrt(SQUARE(z) + SQUARE(x)) : 0x7FFFFFFF;

        switch (item->current_anim_state)
        {
            case BIGEEL_STOP:
                /* Move eel in if he is sticking out */
                if (pos > 0)
                    pos -= BIGEEL_MOVE;

                /* Is Lara in range of the eel */
                if (distance <= BIGEEL_RANGE && ABS(angle) < BIGEEL_ANGLE)
                    item->goal_anim_state = BIGEEL_ATTACK;
                break;

            case BIGEEL_ATTACK:
                if (pos < (distance - BIGEEL_LENGTH))
                    pos += BIGEEL_MOVE;

                if (!item->required_anim_state && (item->touch_bits & BIGEEL_TOUCH))
                {
                    LaraItem->hit_status = 1;
                    LaraItem->hit_points -= DOUBLE_VALUE_ITEM(dmg1, BIGEEL_DAMAGE);
                    CreatureEffect(item, &bigeel_bite, DoBloodSplat_2);
                    item->required_anim_state = BIGEEL_STOP;
                }
                break;
        }
    }

    /* Move the position of the eel */
    item->pos.z_pos += pos * phd_cos_tr2(item->pos.y_rot) >> W2V_SHIFT;
    item->pos.x_pos += pos * phd_sin_tr2(item->pos.y_rot) >> W2V_SHIFT;
    item->reserved_4 = pos;

    AnimateItem_2(item);
}

void CtrlTR2_MoreyEelYellow(short item_number)
{
    ITEM_INFO* item;
    sint16 angle;
    uint16 quadrant;
    sint32 distance, x, z, pos;
    short dmg1;

    item = &Ptr_VetItems[item_number];
    pos = item->reserved_4;
    item->pos.z_pos -= (pos * phd_cos_tr2(item->pos.y_rot)) >> W2V_SHIFT;
    item->pos.x_pos -= (pos * phd_sin_tr2(item->pos.y_rot)) >> W2V_SHIFT;
    dmg1 = Utils.getObjectAttribute(tsu_slots[item->object_number], ATT_DMG1);

    if (item->hit_points <= 0)
    {
        /* Move eel out to fully extended for death */
        if (pos < EEL_SLIDE)
            pos += EEL_MOVE;

        if (item->current_anim_state != BIGEEL_DEATH)
        {
            item->anim_number = Ptr_VetObjects[item->object_number].anim_index + EEL_DIE_ANIM;
            item->frame_number = Ptr_VetAnimations[item->anim_number].frame_base;
            item->current_anim_state = BIGEEL_DEATH;
        }
    }
    else
    {
        /* Relative squared distance and facing information */
        z = LaraItem->pos.z_pos - item->pos.z_pos;
        x = LaraItem->pos.x_pos - item->pos.x_pos;

        /* Get quadrant angle, and angle from that that Lara is at */
        quadrant = (item->pos.y_rot + 0x2000) & 0xC000;
        angle = phd_atan(z, x);
        distance = ABS(x) <= EEL_RANGE && ABS(z) <= EEL_RANGE ? phd_sqrt(SQUARE(z) + SQUARE(x)) : 0x7FFFFFFF;

        switch (item->current_anim_state)
        {
            case BIGEEL_STOP:
                /* Move eel in if he is sticking out */
                if (pos > 0)
                    pos -= EEL_MOVE;

                /* Is Lara in range of the eel */
                if (distance <= EEL_RANGE && ABS((sint16) (angle - quadrant)) < EEL_ANGLE)
                    item->goal_anim_state = BIGEEL_ATTACK;
                break;

            case BIGEEL_ATTACK:
                if (pos < (distance - EEL_LENGTH))
                    pos += EEL_MOVE;

                if (angle < (sint16) (item->pos.y_rot - EEL_TURN))
                    item->pos.y_rot -= EEL_TURN;
                else if (angle > (sint16) (item->pos.y_rot + EEL_TURN))
                    item->pos.y_rot += EEL_TURN;

                if (!item->required_anim_state && (item->touch_bits & BIGEEL_TOUCH))
                {
                    LaraItem->hit_status = 1;
                    LaraItem->hit_points -= DOUBLE_VALUE_ITEM(dmg1, EEL_DAMAGE);
                    CreatureEffect(item, &bigeel_bite, DoBloodSplat_2);
                    item->required_anim_state = BIGEEL_STOP;
                }
                break;
        }
    }

    /* Move the position of the eel */
    item->pos.z_pos += (pos * phd_cos_tr2(item->pos.y_rot)) >> W2V_SHIFT;
    item->pos.x_pos += (pos * phd_sin_tr2(item->pos.y_rot)) >> W2V_SHIFT;
    item->reserved_4 = pos;

    AnimateItem_2(item);
}

void InitialiseTR2_MoreyEelBlack()
{
    for (int index = 0; index < SLOTS_NUMBER; ++index)
    {
        tomb[TR2_BLACK_MORAY_EEL1 + index].set_name("Morey Eel Black");
        tomb[TR2_BLACK_MORAY_EEL1 + index].initialise(TR2_BLACK_MORAY_EEL1 + index, 0, 0);
        tomb[TR2_BLACK_MORAY_EEL1 + index].set_shadow_size(0);
        tomb[TR2_BLACK_MORAY_EEL1 + index].set_func_collide(CreatureCollision);
        tomb[TR2_BLACK_MORAY_EEL1 + index].set_func_control(CtrlTR2_MoreyEelBlack);
        tomb[TR2_BLACK_MORAY_EEL1 + index].set_func_draw(DrawAnimatingItemCustom, NULL);
        tomb[TR2_BLACK_MORAY_EEL1 + index].set_health(HP_MOREYBLACK);
        tomb[TR2_BLACK_MORAY_EEL1 + index].set_radius_and_pivot(0, 0);
        tomb[TR2_BLACK_MORAY_EEL1 + index].set_water_creature(TRUE);
        tomb[TR2_BLACK_MORAY_EEL1 + index].set_hit_effect(HIT_BLOOD);
        tomb[TR2_BLACK_MORAY_EEL1 + index].set_save(TRUE, TRUE, TRUE, FALSE, TRUE);
    }
}

void InitialiseTR2_MoreyEelYellow()
{
    for (int index = 0; index < SLOTS_NUMBER; ++index)
    {
        tomb[TR2_YELLOW_MORAY_EEL1 + index].set_name("Morey Eel Yellow");
        tomb[TR2_YELLOW_MORAY_EEL1 + index].initialise(TR2_YELLOW_MORAY_EEL1 + index, 0, 0);
        tomb[TR2_YELLOW_MORAY_EEL1 + index].set_shadow_size(0);
        tomb[TR2_YELLOW_MORAY_EEL1 + index].set_func_collide(CreatureCollision);
        tomb[TR2_YELLOW_MORAY_EEL1 + index].set_func_control(CtrlTR2_MoreyEelYellow);
        tomb[TR2_YELLOW_MORAY_EEL1 + index].set_func_draw(DrawAnimatingItemCustom, NULL);
        tomb[TR2_YELLOW_MORAY_EEL1 + index].set_health(HP_MOREYYELLOW);
        tomb[TR2_YELLOW_MORAY_EEL1 + index].set_radius_and_pivot(0, 0);
        tomb[TR2_YELLOW_MORAY_EEL1 + index].set_water_creature(TRUE);
        tomb[TR2_YELLOW_MORAY_EEL1 + index].set_hit_effect(HIT_BLOOD);
        tomb[TR2_YELLOW_MORAY_EEL1 + index].set_save(TRUE, TRUE, TRUE, FALSE, TRUE);
    }
}