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

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

enum BIRD_MONSTER_STATE {
    ST_BIRDY_EMPTY,
    ST_BIRDY_WAIT,
    ST_BIRDY_WALK,
    ST_BIRDY_AIM1,
    ST_BIRDY_PUNCH1,
    ST_BIRDY_AIM2,
    ST_BIRDY_PUNCH2,
    ST_BIRDY_PUNCHR,
    ST_BIRDY_WAIT2,
    ST_BIRDY_DEATH,
    ST_BIRDY_AIM3,
    ST_BIRDY_PUNCH3
};

#define HP_BIRD_MONSTER (200)
#define BIRDY_PUNCH_DAMAGE (200)
#define BIRDY_DIE_ANIM (20)
#define BIRDY_WALK_TURN (ONE_DEGREE*4)
#define BIRDY_ATTACK1_RANGE SQUARE(WALL_L)
#define BIRDY_ATTACK1_ANGLE (ONE_DEGREE*45)
#define BIRDY_ATTACK2_RANGE SQUARE(WALL_L*2)
#define BIRDY_TOUCHL (0x0C0000)
#define BIRDY_TOUCHR (0x600000)

static BITE_INFO birdy_biteL = { 0, 224, 0, 19 };
static BITE_INFO birdy_biteR = { 0, 224, 0, 22 };

void CtrlTR2_BirdMonster(short ItemIndex)
{
    if (!CreatureActive(ItemIndex))
        return;

    ITEM_INFO* item;
    CREATURE_INFO* monster;
    AI_INFO info;
    short angle, head;
    short dmg1, dmg2, dmg3, dmg4, dmg;

    item = &Ptr_VetItems[ItemIndex];
    monster = (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);
    dmg3 = Utils.getObjectAttribute(tsu_slots[item->object_number], ATT_DMG3);
    dmg4 = Utils.getObjectAttribute(tsu_slots[item->object_number], ATT_DMG4);

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

        if (info.ahead)
            head = info.angle;

        GetCreatureMood(item, &info, VIOLENT);
        CreatureMood(item, &info, VIOLENT);
        angle = CreatureTurn(item, monster->maximum_turn);

        switch (item->current_anim_state)
        {
            case ST_BIRDY_WAIT:
                monster->maximum_turn = 0;

                if (info.ahead && info.distance < BIRDY_ATTACK1_RANGE && ABS(info.angle) < BIRDY_ATTACK1_ANGLE)
                {
                    if (GetRandomControl() < 0x4000)
                        item->goal_anim_state = ST_BIRDY_AIM1;
                    else
                        item->goal_anim_state = ST_BIRDY_AIM3;
                }
                else if (info.ahead && (monster->mood == MOOD_BORED || monster->mood == MOOD_STALK))
                {
                    item->goal_anim_state = ST_BIRDY_WAIT2;
                }
                else
                {
                    item->goal_anim_state = ST_BIRDY_WALK;
                }
                break;
            case ST_BIRDY_WAIT2:
                if (monster->mood != MOOD_BORED || !info.ahead)
                    item->goal_anim_state = ST_BIRDY_WAIT;
                break;
            case ST_BIRDY_WALK:
                monster->maximum_turn = BIRDY_WALK_TURN;

                if (info.ahead && info.distance < BIRDY_ATTACK2_RANGE)
                    item->goal_anim_state = ST_BIRDY_AIM2;
                else if ((monster->mood == MOOD_BORED || monster->mood == MOOD_STALK) && info.ahead)
                    item->goal_anim_state = ST_BIRDY_WAIT;
                break;
            case ST_BIRDY_AIM1:
                monster->flags = 0;

                if (info.ahead && info.distance < BIRDY_ATTACK1_RANGE && ABS(info.angle) < BIRDY_ATTACK1_ANGLE)
                    item->goal_anim_state = ST_BIRDY_PUNCH1;
                else
                    item->goal_anim_state = ST_BIRDY_WAIT;
                break;
            case ST_BIRDY_AIM2:
                monster->flags = 0;

                if (info.ahead && info.distance < BIRDY_ATTACK2_RANGE)
                    item->goal_anim_state = ST_BIRDY_PUNCH2;
                else
                    item->goal_anim_state = ST_BIRDY_WALK;
                break;
            case ST_BIRDY_AIM3:
                monster->flags = 0;

                if (info.ahead && info.distance < BIRDY_ATTACK1_RANGE && ABS(info.angle) < BIRDY_ATTACK1_ANGLE)
                    item->goal_anim_state = ST_BIRDY_PUNCH3;
                else
                    item->goal_anim_state = ST_BIRDY_WAIT;
                break;
            case ST_BIRDY_PUNCH1:
            case ST_BIRDY_PUNCH2:
            case ST_BIRDY_PUNCH3:
            case ST_BIRDY_PUNCHR:
				if (item->current_anim_state == ST_BIRDY_PUNCH1)
					dmg = dmg1;
				else if (item->current_anim_state == ST_BIRDY_PUNCH2)
					dmg = dmg2;
				else if (item->current_anim_state == ST_BIRDY_PUNCH3)
					dmg = dmg3;
				else
					dmg = dmg4;
                if (!(monster->flags & 1) && (item->touch_bits & BIRDY_TOUCHR))
                {
                    CreatureEffect(item, &birdy_biteR, DoBloodSplat_2);
                    LaraItem->hit_points -= DOUBLE_VALUE_ITEM(dmg, BIRDY_PUNCH_DAMAGE);
                    LaraItem->hit_status = 1;
                    monster->flags |= 1;
                }

                if (!(monster->flags & 2) && (item->touch_bits & BIRDY_TOUCHL))
                {
                    CreatureEffect(item, &birdy_biteL, DoBloodSplat_2);
                    LaraItem->hit_points -= DOUBLE_VALUE_ITEM(dmg, BIRDY_PUNCH_DAMAGE);
                    LaraItem->hit_status = 1;
                    monster->flags |= 2;
                }
                break;
        }
    }

    CreatureJoint(item, 0, head);
    CreatureAnimation(ItemIndex, angle, 0);
}

void InitTR2_BirdMonster(short ItemIndex)
{
    InitialiseCreature(ItemIndex);
}

void InitialiseTR2_MonsterBird()
{
    for (int index = 0; index < SLOTS_NUMBER; ++index)
    {
        tomb[TR2_BIRD_MONSTER1 + index].set_name("Monster Bird");
        tomb[TR2_BIRD_MONSTER1 + index].initialise(TR2_BIRD_MONSTER1 + index, FUNCTION_ZONE_BEFORE, 0);
        tomb[TR2_BIRD_MONSTER1 + index].set_shadow_size(0);
        tomb[TR2_BIRD_MONSTER1 + index].set_func_initialise(InitTR2_BirdMonster);
        tomb[TR2_BIRD_MONSTER1 + index].set_func_collide(CreatureCollision);
        tomb[TR2_BIRD_MONSTER1 + index].set_func_control(CtrlTR2_BirdMonster);
        tomb[TR2_BIRD_MONSTER1 + index].set_func_draw(DrawAnimatingItemCustom, NULL);
        tomb[TR2_BIRD_MONSTER1 + index].set_health(HP_BIRD_MONSTER);
        tomb[TR2_BIRD_MONSTER1 + index].set_radius_and_pivot(341, 0);
        tomb[TR2_BIRD_MONSTER1 + index].set_hit_effect(HIT_BLOOD);
        tomb[TR2_BIRD_MONSTER1 + index].set_creature(TRUE);
        tomb[TR2_BIRD_MONSTER1 + index].set_rotation_meshtree(14, ROT_Y);
        tomb[TR2_BIRD_MONSTER1 + index].set_save(TRUE, TRUE, TRUE, FALSE, TRUE);
    }
}