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

extern TYPE_InitialiseCreature InitialiseCreature;
extern TYPE_CreatureActive CreatureActive;
extern TYPE_CreatureAnimation CreatureAnimation;
extern TYPE_GetCreatureMood GetCreatureMood;
extern TYPE_CreatureMood CreatureMood;
extern TYPE_CreatureTurn CreatureTurn;
extern TYPE_CreatureAIInfo CreatureAIInfo;
extern TYPE_CreatureEffect CreatureEffect;
extern TYPE_CreatureCollision CreatureCollision;
extern TYPE_ExplodingDeath ExplodingDeath;
extern TYPE_DisableBaddieAI DisableBaddieAI;
extern TYPE_KillItem KillItem;
extern TYPE_SoundEffect SoundEffect;
extern TYPE_CreatureDie CreatureDie;
extern TYPE_GetRandomControl GetRandomControl;
extern TYPE2_DoBloodSplat DoBloodSplat_2;
extern TYPE_ItemNewRoom ItemNewRoom;
extern TYPE_DrawAnimatingItem DrawAnimatingItem;
extern TYPE2_GetJointAbsPosition GetJointAbsPosition_2;

#define HP_SPIDER (5)
#define HP_BIG_SPIDER (40)
#define SPIDER_DAMAGE (25)
#define BIG_SPIDER_DAMAGE (100)
#define SPIDER_TURN_SPEED (ONE_DEGREE * 8)
#define BIG_SPIDER_TURN_SPEED (ONE_DEGREE * 4)
#define SPIDER_MOVE_CHANCE (0x100)
#define BIG_SPIDER_MOVE_CHANCE (0x200)
#define SPIDER_ATTACK3_RANGE SQUARE(WALL_L/5)
#define SPIDER_ATTACK2_RANGE SQUARE(WALL_L/2)
#define BIG_SPIDER_ATTACK_RANGE SQUARE(STEP_L*3)+15
#define BIG_SPIDER_DEAD_ANIM 2

static BITE_INFO SpiderBite = { 0, 0, 41, 1 };

enum SPIDER_STATE {
    ST_SPIDER_EMPTY,
    ST_SPIDER_STOP,
    ST_SPIDER_WALK1,
    ST_SPIDER_WALK2,
    ST_SPIDER_ATTACK1,
    ST_SPIDER_ATTACK2,
    ST_SPIDER_ATTACK3,
    ST_SPIDER_DEAD
};

static void SpiderLeap(short item_number, short angle)
{
    ITEM_INFO* item = &Ptr_VetItems[item_number];
    OBJECT_INFO* slots = &Ptr_VetObjects[item->object_number];
    int CordX, CordY, CordZ;
    short Room;

    CordX = item->pos.x_pos;
    CordY = item->pos.y_pos;
    CordZ = item->pos.z_pos;
    Room = item->room_number;

    CreatureAnimation(item_number, angle, 0);

    /* is this move less than 1.5 STEP_L height, if so dont do leap */
    if (item->pos.y_pos > CordY - STEPUP_HEIGHT)
        return;

    /* else move spider back and do a jump instead ! */
    item->pos.x_pos = CordX;
    item->pos.y_pos = CordY;
    item->pos.z_pos = CordZ;
    if (item->room_number != Room)
        ItemNewRoom(item->room_number, Room);

    item->anim_number = slots->anim_index + 2;
    item->frame_number = Ptr_VetAnimations[item->anim_number].frame_base;
    item->current_anim_state = ST_SPIDER_ATTACK2;

    CreatureAnimation(item_number, angle, 0);
}

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

    ITEM_INFO* item;
    CREATURE_INFO* spider;
    AI_INFO info;
    short angle;
    short dmg1, dmg2, dmg3, snd1;

    item = &Ptr_VetItems[item_number];
    spider = (CREATURE_INFO*)item->data;
    angle = 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);
    snd1 = Utils.getObjectProperty(tsu_slots[item->object_number], PTY_SND1);

    if (item->hit_points <= 0)
    {
        ExplodingDeath(item_number, -1, 0);
        DisableBaddieAI(item_number);
        KillItem(item_number);
        item->status = STS_DESACTIVATED;
        if (snd1 != NO_ITEM)
            SoundEffect(snd1, &item->pos, 0);
    }
    else
    {
        CreatureAIInfo(item, &info);
        GetCreatureMood(item, &info, VIOLENT);
        CreatureMood(item, &info, VIOLENT);
        angle = CreatureTurn(item, SPIDER_TURN_SPEED);

        switch (item->current_anim_state)
        {
            case ST_SPIDER_STOP:
                spider->flags = 0;

                if (spider->mood == MOOD_BORED)
                {
                    if (GetRandomControl() < SPIDER_MOVE_CHANCE)
                        item->goal_anim_state = ST_SPIDER_WALK1;
                    else
                        break;
                }
                else if (info.ahead && item->touch_bits)
                {
                    item->goal_anim_state = ST_SPIDER_ATTACK1;
                }
                else if (spider->mood == MOOD_STALK)
                {
                    item->goal_anim_state = ST_SPIDER_WALK1;
                }
                else if (spider->mood == MOOD_ESCAPE || spider->mood == MOOD_ATTACK)
                {
                    item->goal_anim_state = ST_SPIDER_WALK2;
                }
                break;

            case ST_SPIDER_WALK1:
                if (spider->mood == MOOD_BORED)
                {
                    if (GetRandomControl() < SPIDER_MOVE_CHANCE)
                        item->goal_anim_state = ST_SPIDER_STOP;
                    else
                        break;
                }
                else if (spider->mood == MOOD_ESCAPE || spider->mood == MOOD_ATTACK)
                {
                    item->goal_anim_state = ST_SPIDER_WALK2;
                }
                break;

            case ST_SPIDER_WALK2:
                spider->flags = 0;

                if (spider->mood == MOOD_BORED || spider->mood == MOOD_STALK)
                    item->goal_anim_state = ST_SPIDER_WALK1;
                else if (info.ahead && item->touch_bits)
                    item->goal_anim_state = ST_SPIDER_STOP;
                else if (info.ahead && info.distance < SPIDER_ATTACK3_RANGE)
                    item->goal_anim_state = ST_SPIDER_ATTACK3;
                else if (info.ahead && info.distance < SPIDER_ATTACK2_RANGE)
                    item->goal_anim_state = ST_SPIDER_ATTACK2;
                break;

            case ST_SPIDER_ATTACK1:
            case ST_SPIDER_ATTACK2:
            case ST_SPIDER_ATTACK3:
                if (!spider->flags && item->touch_bits)
                {
                    CreatureEffect(item, &SpiderBite, DoBloodSplat_2);
					if (item->current_anim_state == ST_SPIDER_ATTACK1)
						LaraItem->hit_points -= DOUBLE_VALUE_ITEM(dmg1, SPIDER_DAMAGE);
					else if (item->current_anim_state == ST_SPIDER_ATTACK2)
						LaraItem->hit_points -= DOUBLE_VALUE_ITEM(dmg2, SPIDER_DAMAGE);
					else
						LaraItem->hit_points -= DOUBLE_VALUE_ITEM(dmg3, SPIDER_DAMAGE);
                    LaraItem->hit_status = 1;
                    spider->flags = 1;
                }
                break;
        }
    }
    
    SpiderLeap(item_number, angle);
}

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

    ITEM_INFO* item;
    CREATURE_INFO* spider;
    AI_INFO info;
    short angle;
    short dmg1;

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

    if (item->hit_points <= 0)
    {
        if (item->current_anim_state != ST_SPIDER_DEAD)
        {
            item->anim_number = Ptr_VetObjects[item->object_number].anim_index + BIG_SPIDER_DEAD_ANIM;
            item->frame_number = Ptr_VetAnimations[item->anim_number].frame_base;
            item->current_anim_state = ST_SPIDER_DEAD;
        }
    }
    else
    {
        CreatureAIInfo(item, &info);
        GetCreatureMood(item, &info, VIOLENT);
        CreatureMood(item, &info, VIOLENT);
        angle = CreatureTurn(item, BIG_SPIDER_TURN_SPEED);

        switch (item->current_anim_state)
        {
        case ST_SPIDER_STOP:
            spider->flags = 0;

            if (spider->mood == MOOD_BORED)
                break;

            if (info.ahead && item->touch_bits)
            {
                item->goal_anim_state = ST_SPIDER_ATTACK1;
            }
            else if (spider->mood == MOOD_STALK)
            {
                item->goal_anim_state = ST_SPIDER_WALK1;
            }
            else if (spider->mood == MOOD_ESCAPE || spider->mood == MOOD_ATTACK)
            {
                item->goal_anim_state = ST_SPIDER_WALK2;
            }
            break;

        case ST_SPIDER_WALK1:
            if (spider->mood == MOOD_BORED)
                break;

            if (info.ahead && item->touch_bits)
            {
                item->goal_anim_state = ST_SPIDER_STOP;
            }
            else if (spider->mood == MOOD_ESCAPE || spider->mood == MOOD_ATTACK)
            {
                item->goal_anim_state = ST_SPIDER_WALK2;
            }
            break;

        case ST_SPIDER_WALK2:
            spider->flags = 0;

            if (info.ahead && item->touch_bits)
                item->goal_anim_state = ST_SPIDER_STOP;
            else if (spider->mood == MOOD_BORED || spider->mood == MOOD_STALK)
                item->goal_anim_state = ST_SPIDER_WALK1;
            break;

        case ST_SPIDER_ATTACK1:
            if (!spider->flags && item->touch_bits)
            {
                CreatureEffect(item, &SpiderBite, DoBloodSplat_2);
                LaraItem->hit_points -= DOUBLE_VALUE_ITEM(dmg1, BIG_SPIDER_DAMAGE);
                LaraItem->hit_status = 1;
                spider->flags = 1;
            }
            break;
        }
    }

    CreatureAnimation(item_number, angle, 0);
}

void InitialiseTR2_Spider()
{
    for (int index = 0; index < SLOTS_NUMBER; ++index)
    {
        tomb[TR2_SPIDER1 + index].set_name("Spider");
        tomb[TR2_SPIDER1 + index].initialise(TR2_SPIDER1 + index, FUNCTION_ZONE_BEFORE | FUNCTION_SHADOW, 0);
        tomb[TR2_SPIDER1 + index].set_shadow_size(128);
        tomb[TR2_SPIDER1 + index].set_func_initialise(InitialiseCreature);
        tomb[TR2_SPIDER1 + index].set_func_collide(CreatureCollision);
        tomb[TR2_SPIDER1 + index].set_func_control(CtrlTR2_Spider);
        tomb[TR2_SPIDER1 + index].set_func_draw(DrawAnimatingItemCustom, NULL);
        tomb[TR2_SPIDER1 + index].set_health(HP_SPIDER);
        tomb[TR2_SPIDER1 + index].set_radius_and_pivot(102, 0);
        tomb[TR2_SPIDER1 + index].set_hit_effect(HIT_BLOOD);
        tomb[TR2_SPIDER1 + index].set_creature(TRUE);
        tomb[TR2_SPIDER1 + index].set_save(TRUE, TRUE, TRUE, FALSE, TRUE);
    }
}

void InitialiseTR2_SpiderBig()
{
    for (int index = 0; index < SLOTS_NUMBER; ++index)
    {
        tomb[TR2_GIANT_SPIDER1 + index].set_name("Big Spider");
        tomb[TR2_GIANT_SPIDER1 + index].initialise(TR2_GIANT_SPIDER1 + index, FUNCTION_SHADOW, 0);
        tomb[TR2_GIANT_SPIDER1 + index].set_shadow_size(128);
        tomb[TR2_GIANT_SPIDER1 + index].set_func_initialise(InitialiseCreature);
        tomb[TR2_GIANT_SPIDER1 + index].set_func_collide(CreatureCollision);
        tomb[TR2_GIANT_SPIDER1 + index].set_func_control(CtrlTR2_BigSpider);
        tomb[TR2_GIANT_SPIDER1 + index].set_func_draw(DrawAnimatingItemCustom, NULL);
        tomb[TR2_GIANT_SPIDER1 + index].set_health(HP_BIG_SPIDER);
        tomb[TR2_GIANT_SPIDER1 + index].set_radius_and_pivot(341, 0);
        tomb[TR2_GIANT_SPIDER1 + index].set_hit_effect(HIT_BLOOD);
        tomb[TR2_GIANT_SPIDER1 + index].set_creature(TRUE);
        tomb[TR2_GIANT_SPIDER1 + index].set_save(TRUE, TRUE, TRUE, FALSE, TRUE);
    }
}