#include <StdAfx.h>
#include "evil_lara.h"
#include <trng_core.h>
#include "utility.h"
#include "Class/TRClass.h"
#include "phd_math.h"
#include "Class/TRLara.h"

extern TYPE_InitialiseCreature InitialiseCreature;
extern TYPE_CreatureCollision CreatureCollision;
extern TYPE_CreatureActive CreatureActive;
extern TYPE2_GetFloor GetFloor_2;
extern TYPE_GetHeight GetHeight;
extern TYPE_ItemNewRoom ItemNewRoom;
extern TYPE2_AnimateItem AnimateItem_2;
extern TYPE_CreatureDie CreatureDie;

#define LARA_HITPOINTS 1000
#define AA_FASTFALL 32
#define AA_SPAZ_FORWARD 125
#define AA_SPAZ_BACK 126
#define AA_SPAZ_RIGHT 127
#define AA_SPAZ_LEFT 128
#define AA_DUCK_SPAZ_FORWARD 294
#define AA_DUCK_SPAZ_BACK 293
#define AA_DUCK_SPAZ_RIGHT 295
#define AA_DUCK_SPAZ_LEFT 296

void InitTR1_EvilLara(short item_num)
{
    InitialiseCreature(item_num);
    ITEM_INFO* item = &Ptr_VetItems[item_num];
	item->reserved_3 = item->pos.x_pos >> 2 & 0xFF00 | item->pos.z_pos >> 10 & 0xFF;
}

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

    ITEM_INFO* item = &Ptr_VetItems[item_num];
    CREATURE_INFO* evil = (CREATURE_INFO*) item->data;

    if (item->hit_points < LARA_HITPOINTS) {
        LaraItem->hit_points -= (LARA_HITPOINTS - item->hit_points) * 10;
        item->hit_points = LARA_HITPOINTS;
    }
    item->poisoned = false;

    if (!(item->reserved_4 & 1)) {
        int x = 2 * ((item->reserved_3 & 0xFF00) << 2) + 1023 - LaraItem->pos.x_pos;
        int y = LaraItem->pos.y_pos;
		int z = 2 * ((item->reserved_3 & 0xFF) << 10) + 1023 - LaraItem->pos.z_pos;

        short room_num = item->room_number;
        FLOOR_INFO* floor = GetFloor_2(x, y, z, &room_num);
        int h = GetHeight(floor, x, y, z);
        item->floor = h;

        room_num = LaraItem->room_number;
        floor = GetFloor_2(
            LaraItem->pos.x_pos, LaraItem->pos.y_pos, LaraItem->pos.z_pos, &room_num);
        int lh =
            GetHeight(floor, LaraItem->pos.x_pos, LaraItem->pos.y_pos, LaraItem->pos.z_pos);

        item->anim_number = LaraItem->anim_number;
        item->frame_number = LaraItem->frame_number;
        item->pos.x_pos = x;
        item->pos.y_pos = y;
        item->pos.z_pos = z;
        item->pos.x_rot = LaraItem->pos.x_rot;
        item->pos.y_rot = LaraItem->pos.y_rot - PHD_180;
        item->pos.z_rot = LaraItem->pos.z_rot;
		evil->joint_rotation[0] = Lara.getTorsoY();
		evil->joint_rotation[1] = Lara.getTorsoX();
		evil->joint_rotation[2] = Lara.getHeadY();
		evil->joint_rotation[3] = Lara.getHeadX();
		if (item->room_number != LaraItem->room_number)
            ItemNewRoom(item_num, LaraItem->room_number);

        if (h >= lh + WALL_L && !LaraItem->gravity_status) {
            item->current_anim_state = AS_FASTFALL;
            item->goal_anim_state = AS_FASTFALL;
            item->anim_number = AA_FASTFALL;
            item->frame_number = Ptr_VetAnimations[item->anim_number].frame_base;
            item->speed = 0;
            item->fallspeed = 0;
            item->gravity_status = 1;
            item->reserved_4 |= 1;
            item->pos.y_pos += 50;
			evil->joint_rotation[0] = 0;
			evil->joint_rotation[1] = 0;
			evil->joint_rotation[2] = 0;
			evil->joint_rotation[3] = 0;
        }
    } else {
        AnimateItem_2(item);
	    if (item->status == STS_DESACTIVATED) {
			CreatureDie(item_num, FALSE);
			return;
		}

        int x = item->pos.x_pos;
        int y = item->pos.y_pos;
        int z = item->pos.z_pos;

        short room_num = item->room_number;
        FLOOR_INFO* floor = GetFloor_2(x, y, z, &room_num);
        int h = GetHeight(floor, x, y, z);
        item->floor = h;

        if (item->pos.y_pos >= h) {
            item->pos.y_pos = h;
            item->gravity_status = 0;
            item->fallspeed = 0;
            item->goal_anim_state = AS_DEATH;
        }
    }
}

void DrawTR1_EvilLara(ITEM_INFO *item)
{
	if (item->reserved_4 & 2)
	{
		short anim_number = item->anim_number;
		short frame_number = item->frame_number;
		if (!(item->reserved_4 & 1) && Lara.getHitDirection() != -1)
		{
			switch (Lara.getHitDirection())
			{
			case DIR_NORTH:
				item->anim_number = Lara.isFlagsEnabled(FLF_IS_DUCKED) ? AA_DUCK_SPAZ_FORWARD : AA_SPAZ_FORWARD;
				break;
			case DIR_EAST:
				item->anim_number = Lara.isFlagsEnabled(FLF_IS_DUCKED) ? AA_DUCK_SPAZ_RIGHT : AA_SPAZ_RIGHT;
				break;
			case DIR_SOUTH:
				item->anim_number = Lara.isFlagsEnabled(FLF_IS_DUCKED) ? AA_DUCK_SPAZ_BACK : AA_SPAZ_BACK;
				break;
			default:
				item->anim_number = Lara.isFlagsEnabled(FLF_IS_DUCKED) ? AA_DUCK_SPAZ_LEFT : AA_SPAZ_LEFT;
				break;
			}
			item->frame_number = Ptr_VetAnimations[item->anim_number].frame_base + Lara.getPoseCount();
		}
		DrawAnimatingItemCustom(item);
		item->anim_number = anim_number;
		item->frame_number = frame_number;
	}
	else
	{
		item->reserved_4 |= 2;
	}
}

void InitialiseTR1_EvilLara()
{
    for (int index = 0; index < SLOTS_NUMBER; ++index)
    {
        tomb[TR1_LARA_EVIL_TWIN_MUTANT1 + index].set_name("Evil Lara");
        tomb[TR1_LARA_EVIL_TWIN_MUTANT1 + index].initialise(TR1_LARA_EVIL_TWIN_MUTANT1 + index, FUNCTION_SHADOW, QUERY_DEATH);
        tomb[TR1_LARA_EVIL_TWIN_MUTANT1 + index].set_shadow_size(160);
		tomb[TR1_LARA_EVIL_TWIN_MUTANT1 + index].set_func_initialise(InitTR1_EvilLara);
        tomb[TR1_LARA_EVIL_TWIN_MUTANT1 + index].set_func_collide(CreatureCollision);
        tomb[TR1_LARA_EVIL_TWIN_MUTANT1 + index].set_func_control(CtrlTR1_EvilLara);
        tomb[TR1_LARA_EVIL_TWIN_MUTANT1 + index].set_func_draw(DrawTR1_EvilLara, NULL);
        tomb[TR1_LARA_EVIL_TWIN_MUTANT1 + index].set_hit_effect(HIT_BLOOD);
        tomb[TR1_LARA_EVIL_TWIN_MUTANT1 + index].set_creature(TRUE);
		tomb[TR1_LARA_EVIL_TWIN_MUTANT1 + index].set_rotation_meshtree(6, ROT_X | ROT_Y);
		tomb[TR1_LARA_EVIL_TWIN_MUTANT1 + index].set_rotation_meshtree(13, ROT_X | ROT_Y);
        tomb[TR1_LARA_EVIL_TWIN_MUTANT1 + index].set_save(TRUE, TRUE, TRUE, FALSE, TRUE);

		OBJECT_INFO* object = tomb[TR1_LARA_EVIL_TWIN_MUTANT1 + index].get_object();
		if (object)
		{
			object->hit_points = LARA_HITPOINTS;
			object->frame_base = Ptr_VetObjects[SLOT_LARA].frame_base;
			object->anim_index = Ptr_VetObjects[SLOT_LARA].anim_index;
		}
    }
}
