#include <StdAfx.h>
#include "winston.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_GetRandomDraw GetRandomDraw;
extern TYPE_ObjectCollision ObjectCollision;
extern TYPE_DrawAnimatingItem DrawAnimatingItem;
extern TYPE_SoundEffect SoundEffect;

#define WINSTON_WALK_TURN (ONE_DEGREE)
#define WINSTON_STOP_RANGE SQUARE(3*WALL_L/2)
#define WINSTON_TREMBLE_CHANCE 0x100

enum WINSTON_STATE {
    ST_WINSTON_EMPTY,
    ST_WINSTON_STOP,
    ST_WINSTON_WALK
};

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

    ITEM_INFO* item;
    CREATURE_INFO* winston;
    AI_INFO info;
    short angle;
    short snd1, snd2, snd3, snd4;

    item = &Ptr_VetItems[item_number];
    winston = (CREATURE_INFO*)item->data;
    angle = 0;
    snd1 = Utils.getObjectProperty(tsu_slots[item->object_number], PTY_SND1);
    snd2 = Utils.getObjectProperty(tsu_slots[item->object_number], PTY_SND2);
    snd3 = Utils.getObjectProperty(tsu_slots[item->object_number], PTY_SND3);
    snd4 = Utils.getObjectProperty(tsu_slots[item->object_number], PTY_SND4);

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

    item->hit_points = HP_CANT_BE_TARGETED;
    item->poisoned = false;

    if (item->current_anim_state == ST_WINSTON_STOP)
    {
        winston->maximum_turn = 0;
        if ((info.distance > WINSTON_STOP_RANGE || !info.ahead) && item->goal_anim_state != ST_WINSTON_WALK)
        {
            item->goal_anim_state = ST_WINSTON_WALK;
            if (snd2 != NO_ITEM)
                SoundEffect(snd2, &item->pos, 0);
        }
    }
    else
    {
        winston->maximum_turn = WINSTON_WALK_TURN;
        if (info.distance <= WINSTON_STOP_RANGE)
        {
            if (info.ahead)
            {
                item->goal_anim_state = ST_WINSTON_STOP;
                if (winston->flags & 1)
                    winston->flags &= 0xFFFE;
            }
            else if (!(winston->flags & 1))
            {
                if (snd1 != NO_ITEM)
                    SoundEffect(snd1, &item->pos, 0);
                if (snd4 != NO_ITEM)
                    SoundEffect(snd4, &item->pos, 0);
                winston->flags |= 1;
            }
        }
    }

    if (item->touch_bits && !(winston->flags & 2))
    {
        if (snd3 != NO_ITEM)
            SoundEffect(snd3, &item->pos, 0);
        if (snd4 != NO_ITEM)
            SoundEffect(snd4, &item->pos, 0);
        winston->flags |= 2;
    }
    else if (!item->touch_bits && winston->flags & 2)
    {
        winston->flags &= 0xFFFD;
    }

    if (GetRandomDraw() < WINSTON_TREMBLE_CHANCE && snd4 != NO_ITEM)
        SoundEffect(snd4, &item->pos, 0);

    CreatureAnimation(item_number, angle, 0);
}

void InitialiseTR2_Winston()
{
    for (int index = 0; index < SLOTS_NUMBER; ++index)
    {
        tomb[TR2_WINSTON1 + index].set_name("Winston");
        tomb[TR2_WINSTON1 + index].initialise(TR2_WINSTON1 + index, FUNCTION_SHADOW, 0);
        tomb[TR2_WINSTON1 + index].set_shadow_size(64);
        tomb[TR2_WINSTON1 + index].set_func_initialise(InitialiseCreature);
        tomb[TR2_WINSTON1 + index].set_func_collide(ObjectCollision);
        tomb[TR2_WINSTON1 + index].set_func_control(CtrlTR2_Winston);
        tomb[TR2_WINSTON1 + index].set_func_draw(DrawAnimatingItemCustom, NULL);
        tomb[TR2_WINSTON1 + index].set_health(HP_CANT_BE_TARGETED);
        tomb[TR2_WINSTON1 + index].set_radius_and_pivot(102, 0);
        tomb[TR2_WINSTON1 + index].set_hit_effect(HIT_NONE);
        tomb[TR2_WINSTON1 + index].set_creature(TRUE);
        tomb[TR2_WINSTON1 + index].set_save(TRUE, TRUE, TRUE, FALSE, TRUE);
    }
}