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

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

#define LION_BITE_DAMAGE 250
#define LION_POUNCE_DAMAGE 150
#define LION_TOUCH 0x380066
#define LION_WALK_TURN (2 * ONE_DEGREE) // = 364
#define LION_RUN_TURN (5 * ONE_DEGREE) // = 910
#define LION_ROAR_CHANCE 128
#define LION_POUNCE_RANGE SQUARE(WALL_L) // = 1048576
#define LION_DIE_ANIM 7
#define LION_HITPOINTS 30
#define LION_RADIUS (WALL_L / 3) // = 341
#define LION_SMARTNESS 0x7FFF

#define LIONESS_HITPOINTS 25
#define LIONESS_RADIUS (WALL_L / 3) // = 341
#define LIONESS_SMARTNESS 0x2000

#define PUMA_DIE_ANIM 4
#define PUMA_HITPOINTS 45
#define PUMA_RADIUS (WALL_L / 3) // = 341
#define PUMA_SMARTNESS 0x2000

static BITE_INFO LionBite = { -2, -10, 132, 21 };

enum LION_ANIM {
    LION_EMPTY = 0,
    LION_STOP = 1,
    LION_WALK = 2,
    LION_RUN = 3,
    LION_ATTACK1 = 4,
    LION_DEATH = 5,
    LION_WARNING = 6,
    LION_ATTACK2 = 7,
};

void CtrlTR1_Lion(short item_num)
{
    if (!CreatureActive(item_num))
        return;

    ITEM_INFO* item = &Ptr_VetItems[item_num];
    CREATURE_INFO* lion = (CREATURE_INFO*) item->data;
    short head = 0;
    short angle = 0;
    short tilt = 0;
    short dmg1 = Utils.getObjectAttribute(tsu_slots[item->object_number], ATT_DMG1);
    short dmg2 = Utils.getObjectAttribute(tsu_slots[item->object_number], ATT_DMG2);
	short first = MapToFirst(tsu_slots[item->object_number], SLOTS_NUMBER);

    if (item->hit_points <= 0) {
        if (item->current_anim_state != LION_DEATH) {
            item->current_anim_state = LION_DEATH;
            item->anim_number = Ptr_VetObjects[item->object_number].anim_index
                + (short)(GetRandomControl() / 0x4000);
            if (first == TR1_PANTHER1) {
                item->anim_number += PUMA_DIE_ANIM;
            } else {
                item->anim_number += LION_DIE_ANIM;
            }
            item->frame_number = Ptr_VetAnimations[item->anim_number].frame_base;
        }
    } else {
        AI_INFO info;
        CreatureAIInfo(item, &info);

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

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

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

        if (first != TR1_PANTHER1) {
		    short snd1 = Utils.getObjectProperty(tsu_slots[item->object_number], PTY_SND1);
			if (item->hit_status && snd1 != NO_ITEM) {
				SoundEffect(snd1, &item->pos, 0);
			}
        }

        switch (item->current_anim_state) {
        case LION_STOP:
            lion->maximum_turn = 0;
            if (item->required_anim_state) {
                item->goal_anim_state = item->required_anim_state;
            } else if (lion->mood == MOOD_BORED) {
                item->goal_anim_state = LION_WALK;
            } else if (info.ahead && (item->touch_bits & LION_TOUCH)) {
                item->goal_anim_state = LION_ATTACK2;
            } else if (info.ahead && info.distance < LION_POUNCE_RANGE) {
                item->goal_anim_state = LION_ATTACK1;
            } else {
                item->goal_anim_state = LION_RUN;
            }
            break;

        case LION_WALK:
            lion->maximum_turn = LION_WALK_TURN;
            if (lion->mood != MOOD_BORED) {
                item->goal_anim_state = LION_STOP;
            } else if (GetRandomControl() < LION_ROAR_CHANCE) {
                item->required_anim_state = LION_WARNING;
                item->goal_anim_state = LION_STOP;
            }
            break;

        case LION_RUN:
            lion->maximum_turn = LION_RUN_TURN;
            tilt = angle;
            if (lion->mood == MOOD_BORED) {
                item->goal_anim_state = LION_STOP;
            } else if (info.ahead && info.distance < LION_POUNCE_RANGE) {
                item->goal_anim_state = LION_STOP;
            } else if ((item->touch_bits & LION_TOUCH) && info.ahead) {
                item->goal_anim_state = LION_STOP;
            } else if (
                lion->mood != MOOD_ESCAPE
                && GetRandomControl() < LION_ROAR_CHANCE) {
                item->required_anim_state = LION_WARNING;
                item->goal_anim_state = LION_STOP;
            }
            break;

        case LION_ATTACK1:
            lion->maximum_turn = LION_RUN_TURN;
            if (item->required_anim_state == LION_EMPTY
                && (item->touch_bits & LION_TOUCH)) {
                LaraItem->hit_points -= DOUBLE_VALUE_ITEM(dmg1, LION_POUNCE_DAMAGE);
                LaraItem->hit_status = 1;
                item->required_anim_state = LION_STOP;
            }
            break;

        case LION_ATTACK2:
            if (item->required_anim_state == LION_EMPTY
                && (item->touch_bits & LION_TOUCH)) {
                CreatureEffect(item, &LionBite, DoBloodSplat_2);
                LaraItem->hit_points -= DOUBLE_VALUE_ITEM(dmg2, LION_BITE_DAMAGE);
                LaraItem->hit_status = 1;
                item->required_anim_state = LION_STOP;
            }
            break;
        }
    }

    CreatureTilt(item, tilt);
    CreatureJoint(item, 0, head);
    CreatureAnimation(item_num, angle, tilt);
}

void InitialiseTR1_Lion()
{
    for (int index = 0; index < SLOTS_NUMBER; ++index)
    {
        tomb[TR1_LION_MALE1 + index].set_name("Lion");
        tomb[TR1_LION_MALE1 + index].initialise(TR1_LION_MALE1 + index, FUNCTION_ZONE_BEFORE | FUNCTION_SHADOW, 0);
        tomb[TR1_LION_MALE1 + index].set_shadow_size(128);
        tomb[TR1_LION_MALE1 + index].set_func_initialise(InitialiseCreature);
        tomb[TR1_LION_MALE1 + index].set_func_collide(CreatureCollision);
        tomb[TR1_LION_MALE1 + index].set_func_control(CtrlTR1_Lion);
        tomb[TR1_LION_MALE1 + index].set_func_draw(DrawAnimatingItemCustom, NULL);
        tomb[TR1_LION_MALE1 + index].set_health(LION_HITPOINTS);
        tomb[TR1_LION_MALE1 + index].set_radius_and_pivot(LION_RADIUS, 400);
        tomb[TR1_LION_MALE1 + index].set_hit_effect(HIT_BLOOD);
        tomb[TR1_LION_MALE1 + index].set_creature(TRUE);
        tomb[TR1_LION_MALE1 + index].set_rotation_meshtree(19, ROT_Y);
        tomb[TR1_LION_MALE1 + index].set_save(TRUE, TRUE, TRUE, FALSE, TRUE);
    }
}

void InitialiseTR1_Lioness()
{
    for (int index = 0; index < SLOTS_NUMBER; ++index)
    {
        tomb[TR1_LION_FEMALE1 + index].set_name("Lioness");
        tomb[TR1_LION_FEMALE1 + index].initialise(TR1_LION_FEMALE1 + index, FUNCTION_ZONE_BEFORE | FUNCTION_SHADOW, 0);
        tomb[TR1_LION_FEMALE1 + index].set_shadow_size(128);
        tomb[TR1_LION_FEMALE1 + index].set_func_initialise(InitialiseCreature);
        tomb[TR1_LION_FEMALE1 + index].set_func_collide(CreatureCollision);
        tomb[TR1_LION_FEMALE1 + index].set_func_control(CtrlTR1_Lion);
        tomb[TR1_LION_FEMALE1 + index].set_func_draw(DrawAnimatingItemCustom, NULL);
        tomb[TR1_LION_FEMALE1 + index].set_health(LIONESS_HITPOINTS);
        tomb[TR1_LION_FEMALE1 + index].set_radius_and_pivot(LION_RADIUS, 400);
        tomb[TR1_LION_FEMALE1 + index].set_hit_effect(HIT_BLOOD);
        tomb[TR1_LION_FEMALE1 + index].set_creature(TRUE);
        tomb[TR1_LION_FEMALE1 + index].set_rotation_meshtree(19, ROT_Y);
        tomb[TR1_LION_FEMALE1 + index].set_save(TRUE, TRUE, TRUE, FALSE, TRUE);
    }
}

void InitialiseTR1_Puma()
{
    for (int index = 0; index < SLOTS_NUMBER; ++index)
    {
        tomb[TR1_PANTHER1 + index].set_name("Puma");
        tomb[TR1_PANTHER1 + index].initialise(TR1_PANTHER1 + index, FUNCTION_ZONE_BEFORE | FUNCTION_SHADOW, 0);
        tomb[TR1_PANTHER1 + index].set_shadow_size(128);
        tomb[TR1_PANTHER1 + index].set_func_initialise(InitialiseCreature);
        tomb[TR1_PANTHER1 + index].set_func_collide(CreatureCollision);
        tomb[TR1_PANTHER1 + index].set_func_control(CtrlTR1_Lion);
        tomb[TR1_PANTHER1 + index].set_func_draw(DrawAnimatingItemCustom, NULL);
        tomb[TR1_PANTHER1 + index].set_health(PUMA_HITPOINTS);
        tomb[TR1_PANTHER1 + index].set_radius_and_pivot(LION_RADIUS, 400);
        tomb[TR1_PANTHER1 + index].set_hit_effect(HIT_BLOOD);
        tomb[TR1_PANTHER1 + index].set_creature(TRUE);
        tomb[TR1_PANTHER1 + index].set_rotation_meshtree(19, ROT_Y);
        tomb[TR1_PANTHER1 + index].set_save(TRUE, TRUE, TRUE, FALSE, TRUE);
    }
}
