#include <StdAfx.h>
#include "barracuda.h"
#include <trng_core.h>
#include "utility.h"
#include "Class/TRClass.h"
#include "Class/TRLara.h"
#include "TR3_Functions.h"

extern TYPE_CreatureActive CreatureActive;
extern TYPE_CreatureCollision CreatureCollision;
extern TYPE_InitialiseCreature InitialiseCreature;
extern TYPE_CreatureAnimation CreatureAnimation;
extern TYPE_CreatureJoint CreatureJoint;
extern TYPE_CreatureTilt CreatureTilt;
extern TYPE_CreatureAIInfo CreatureAIInfo;
extern TYPE_CreatureTurn CreatureTurn;
extern TYPE_CreatureMood CreatureMood;
extern TYPE_GetCreatureMood GetCreatureMood;
extern TYPE_DrawAnimatingItem DrawAnimatingItem;
extern TYPE_SoundEffect SoundEffect;
extern TYPE_GetRandomControl GetRandomControl;
extern TYPE_CreatureFloat CreatureFloat;
extern TYPE_CreatureUnderwater CreatureUnderwater;
extern TYPE2_AnimateItem AnimateItem_2;
extern TYPE_CreatureEffect CreatureEffect;
extern TYPE2_DoBloodSplat DoBloodSplat_2;
extern TYPE_GetWaterHeight GetWaterHeight;

#define HP_BARRACUDA (12)
#define FISH_DAMAGE (100)
#define FISH_TOUCH (0xE0)
#define FISH_SLOW_TURN (364)
#define FISH_FAST_TURN (728)
#define FISH_ATTACK1_RANGE (0x718E4)
#define FISH_ATTACK2_RANGE (0x1C639)
#define FISH_STAND_ANIM (11)
#define FISH_UNDERWATER_HEIGHT (WALL_L/4)
#define FISH_DEAD_ANIM (6)

static BITE_INFO fish_bite = { 2, -60, 121, 7 };

enum FISH_STATE {
    ST_FISH_EMPTY,
    ST_FISH_STOP,
    ST_FISH_SLOW,
    ST_FISH_FAST,
    ST_FISH_SHOOT1,
    ST_FISH_SHOOT2,
    ST_FISH_DEATH
};

void CtrlTR2_Barracuda(short item_number)
{
    if (!CreatureActive(item_number))
        return;

    ITEM_INFO* item;
    CREATURE_INFO* fish;
    AI_INFO info;
    short angle, head;
    short dmg1, dmg2;

    item = &Ptr_VetItems[item_number];
    fish = (CREATURE_INFO*)item->data;
    angle = head = 0;
    dmg1 = Utils.getObjectAttribute(tsu_slots[item->object_number], ATT_DMG1);
    dmg2 = Utils.getObjectAttribute(tsu_slots[item->object_number], ATT_DMG2);

    if (item->hit_points <= 0)
    {
        if (item->current_anim_state != ST_FISH_DEATH)
        {
            item->anim_number = Ptr_VetObjects[item->object_number].anim_index + FISH_DEAD_ANIM;
            item->frame_number = Ptr_VetAnimations[item->anim_number].frame_base;
            item->current_anim_state = ST_FISH_DEATH;
        }
        int wh = GetWaterHeight(item->pos.x_pos, item->pos.y_pos, item->pos.z_pos, item->room_number);
        if (wh != NO_HEIGHT)
	        CreatureFloat(item_number);
    }
    else
    {
        CreatureAIInfo(item, &info);

        if (!(Ptr_VetRoom[LaraItem->room_number].FlagsRoom & SUNDERWATER) && Lara.getWaterSurfaceDist() > -STEP_L)
            info.target_zone |= BLOCKED;

        GetCreatureMood(item, &info, VIOLENT);
        CreatureMood(item, &info, VIOLENT);

        angle = CreatureTurn(item, fish->maximum_turn);

        switch (item->current_anim_state)
        {
            case ST_FISH_STOP:
                fish->flags = 0;

                if (fish->mood != MOOD_BORED)
                {
                    if (info.ahead && info.distance < FISH_ATTACK1_RANGE)
                    {
                        item->goal_anim_state = ST_FISH_SHOOT1;
                    }
                    else if (fish->mood != MOOD_STALK)
                    {
                        item->goal_anim_state = ST_FISH_FAST;
                    }
                    else
                    {
                        item->goal_anim_state = ST_FISH_SLOW;
                    }
                }
                else
                {
                    item->goal_anim_state = ST_FISH_SLOW;
                }
                break;
            case ST_FISH_SLOW:
                fish->maximum_turn = FISH_SLOW_TURN;

                if (fish->mood != MOOD_BORED)
                {
                    if (info.ahead && (item->touch_bits & FISH_TOUCH))
                    {
                        item->goal_anim_state = ST_FISH_STOP;
                    }
                    else if (fish->mood != MOOD_STALK)
                    {
                        item->goal_anim_state = ST_FISH_FAST;
                    }
                }
                break;
            case ST_FISH_FAST:
                fish->maximum_turn = FISH_FAST_TURN;
                fish->flags = 0;

                if (fish->mood != MOOD_BORED)
                {
                    if (info.ahead && info.distance < FISH_ATTACK2_RANGE)
                    {
                        item->goal_anim_state = ST_FISH_SHOOT2;
                    }
                    else if (info.ahead && info.distance < FISH_ATTACK1_RANGE)
                    {
                        item->goal_anim_state = ST_FISH_STOP;
                    }
                    else if (fish->mood == MOOD_STALK)
                    {
                        item->goal_anim_state = ST_FISH_SLOW;
                    }
                }
                else
                {
                    item->goal_anim_state = ST_FISH_SLOW;
                }
                break;
            case ST_FISH_SHOOT1:
            case ST_FISH_SHOOT2:
                fish->maximum_turn = 0;

                if (!fish->flags && (item->touch_bits & FISH_TOUCH))
                {
                    LaraItem->hit_points -= DOUBLE_VALUE_ANIM(item->current_anim_state, ST_FISH_SHOOT1, DOUBLE_VALUE_ITEM(dmg1, FISH_DAMAGE), DOUBLE_VALUE_ITEM(dmg2, FISH_DAMAGE));
                    LaraItem->hit_status = 1;
                    CreatureEffect(item, &fish_bite, DoBloodSplat_2);
                    fish->flags = 1;
                }
                break;
        }

        CreatureJoint(item, 0, head);
        CreatureAnimation(item_number, angle, 0);
        CreatureUnderwater(item, FISH_UNDERWATER_HEIGHT);
    }
}

void InitTR2_Barracuda(short item_number)
{
    InitialiseCreature(item_number);
}

void InitialiseTR2_Barracuda()
{
    for (int index = 0; index < SLOTS_NUMBER; ++index)
    {
        tomb[TR2_BARRACUDA1 + index].set_name("Barracuda");
        tomb[TR2_BARRACUDA1 + index].initialise(TR2_BARRACUDA1 + index, FUNCTION_ZONE_BEFORE | FUNCTION_SHADOW, 0);
        tomb[TR2_BARRACUDA1 + index].set_shadow_size(128);
        tomb[TR2_BARRACUDA1 + index].set_func_initialise(InitTR2_Barracuda);
        tomb[TR2_BARRACUDA1 + index].set_func_collide(CreatureCollision);
        tomb[TR2_BARRACUDA1 + index].set_func_control(CtrlTR2_Barracuda);
        tomb[TR2_BARRACUDA1 + index].set_func_draw(DrawAnimatingItemCustom, NULL);
        tomb[TR2_BARRACUDA1 + index].set_health(HP_BARRACUDA);
        tomb[TR2_BARRACUDA1 + index].set_radius_and_pivot(204, 200);
        tomb[TR2_BARRACUDA1 + index].set_hit_effect(HIT_BLOOD);
        tomb[TR2_BARRACUDA1 + index].set_creature(TRUE);
        tomb[TR2_BARRACUDA1 + index].set_water_creature(TRUE); // Unlimited Air
        tomb[TR2_BARRACUDA1 + index].set_rotation_meshtree(6, ROT_Y);
        tomb[TR2_BARRACUDA1 + index].set_save(TRUE, TRUE, TRUE, FALSE, TRUE);
    }
}