#include <StdAfx.h>
#include "mouse.h"
#include <trng_core.h>
#include "utility.h"
#include "Class/TRClass.h"

extern TYPE_CreatureActive CreatureActive;
extern TYPE_CreatureCollision CreatureCollision;
extern TYPE_InitialiseCreature InitialiseCreature;
extern TYPE_CreatureAnimation CreatureAnimation;
extern TYPE_CreatureAIInfo CreatureAIInfo;
extern TYPE_GetCreatureMood GetCreatureMood;
extern TYPE_CreatureMood CreatureMood;
extern TYPE_CreatureTilt CreatureTilt;
extern TYPE_CreatureTurn CreatureTurn;
extern TYPE_CreatureEffect CreatureEffect;
extern TYPE_CreatureJoint CreatureJoint;
extern TYPE2_DoBloodSplat DoBloodSplat_2;
extern TYPE_DrawAnimatingItem DrawAnimatingItem;
extern TYPE_GetRandomControl GetRandomControl;

#define HP_MOUSE (4)
#define MOUSE_DAMAGE 20
#define MOUSE_TOUCH (0x7F)
#define MOUSE_WAIT1_CHANCE 0x500
#define MOUSE_WAIT2_CHANCE (MOUSE_WAIT1_CHANCE + 0x500)
#define MOUSE_ATTACK_RANGE SQUARE(WALL_L/3)
#define MOUSE_IDLE_ANIM 4
#define MOUSE_DIE_ANIM 9
#define MOUSE_RUN_TURN (ONE_DEGREE*6)

static BITE_INFO mouse_bite = { 0, 0, 57, 2 };

enum MOUSE_STATE {
    ST_MOUSE_EMPTY,
    ST_MOUSE_RUN,
    ST_MOUSE_STOP,
    ST_MOUSE_WAIT1,
    ST_MOUSE_WAIT2,
    ST_MOUSE_ATTACK,
    ST_MOUSE_DEATH
};

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

    ITEM_INFO* item;
    CREATURE_INFO* rat;
    AI_INFO info;
    short angle, head_y;
    int random;
    short dmg1;

    item = &Ptr_VetItems[item_number];
    rat = (CREATURE_INFO*)item->data;
    angle = head_y = 0;
    random = GetRandomControl();
    dmg1 = Utils.getObjectAttribute(tsu_slots[item->object_number], ATT_DMG1);

    if (item->hit_points <= 0)
    {
        if (item->current_anim_state != ST_MOUSE_DEATH)
        {
            item->anim_number = Ptr_VetObjects[item->object_number].anim_index + MOUSE_DIE_ANIM;
            item->frame_number = Ptr_VetAnimations[item->anim_number].frame_base;
            item->current_anim_state = ST_MOUSE_DEATH;
        }
    }
    else
    {
        CreatureAIInfo(item, &info);
        
        if (info.ahead)
        {
            head_y = info.angle;
        }

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

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

        switch (item->current_anim_state)
        {
        case ST_MOUSE_WAIT2:
            if (rat->mood == MOOD_BORED || rat->mood == MOOD_STALK)
            {
                if (random < MOUSE_WAIT1_CHANCE)
                    item->required_anim_state = ST_MOUSE_WAIT1;
                else if (random > MOUSE_WAIT2_CHANCE)
                    item->required_anim_state = ST_MOUSE_RUN;
            }
            else if (info.distance < MOUSE_ATTACK_RANGE)
            {
                item->required_anim_state = ST_MOUSE_ATTACK;
            }
            else
            {
                item->required_anim_state = ST_MOUSE_RUN;
            }

            if (item->required_anim_state)
                item->goal_anim_state = ST_MOUSE_STOP;
            break;

        case ST_MOUSE_STOP:
            rat->maximum_turn = 0;

            if (item->required_anim_state)
                item->goal_anim_state = item->required_anim_state;
            break;

        case ST_MOUSE_RUN:
            rat->maximum_turn = MOUSE_RUN_TURN;

            if (rat->mood == MOOD_BORED || rat->mood == MOOD_STALK)
            {
                if (random < MOUSE_WAIT1_CHANCE)
                {
                    item->required_anim_state = ST_MOUSE_WAIT1;
                    item->goal_anim_state = ST_MOUSE_STOP;
                }
                else if (random < MOUSE_WAIT2_CHANCE)
                {
                    item->goal_anim_state = ST_MOUSE_STOP;
                }
            }
            else if (info.ahead && info.distance < MOUSE_ATTACK_RANGE)
                item->goal_anim_state = ST_MOUSE_STOP;
            break;

        case ST_MOUSE_ATTACK:
            rat->maximum_turn = MOUSE_RUN_TURN;

            if (!item->required_anim_state && (item->touch_bits & MOUSE_TOUCH))
            {
                CreatureEffect(item, &mouse_bite, DoBloodSplat_2);
                LaraItem->hit_points -= DOUBLE_VALUE_ITEM(dmg1, MOUSE_DAMAGE);
                LaraItem->hit_status = 1;
                item->required_anim_state = ST_MOUSE_STOP;
            }
            break;

        case ST_MOUSE_WAIT1:
            rat->maximum_turn = 0;

            if (random < MOUSE_WAIT1_CHANCE)
                item->goal_anim_state = ST_MOUSE_STOP;
            break;
        }
    }

    CreatureJoint(item, 0, head_y);
    CreatureAnimation(item_number, angle, 0);
}

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

void InitialiseTR2_Mouse()
{
    for (int index = 0; index < SLOTS_NUMBER; ++index)
    {
        tomb[TR2_RAT1 + index].initialise(TR2_RAT1 + index, FUNCTION_SHADOW, 0);
        tomb[TR2_RAT1 + index].set_name("Mouse (Rat ?)");
        tomb[TR2_RAT1 + index].set_shadow_size(128);
        tomb[TR2_RAT1 + index].set_func_initialise(InitTR2_Mouse);
        tomb[TR2_RAT1 + index].set_func_collide(CreatureCollision);
        tomb[TR2_RAT1 + index].set_func_control(CtrlTR2_Mouse);
        tomb[TR2_RAT1 + index].set_func_draw(DrawAnimatingItemCustom, NULL);
        tomb[TR2_RAT1 + index].set_health(HP_MOUSE);
        tomb[TR2_RAT1 + index].set_radius_and_pivot(102, 50);
        tomb[TR2_RAT1 + index].set_hit_effect(HIT_BLOOD);
        tomb[TR2_RAT1 + index].set_creature(TRUE);
        tomb[TR2_RAT1 + index].set_rotation_meshtree(3, ROT_Y);
        tomb[TR2_RAT1 + index].set_save(TRUE, TRUE, TRUE, FALSE, TRUE);
    }
}