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

extern TYPE_InitialiseCreature InitialiseCreature;
extern TYPE_CreatureCollision CreatureCollision;
extern TYPE_CreateEffect CreateEffect;
extern TYPE_CreatureActive CreatureActive;
extern TYPE_CreatureAIInfo CreatureAIInfo;
extern TYPE2_GetJointAbsPosition GetJointAbsPosition_2;
extern TYPE2_GetBoundsAccurate GetBoundsAccurate_2;
extern TYPE_GetCreatureMood GetCreatureMood;
extern TYPE_CreatureMood CreatureMood;
extern TYPE_CreatureTurn CreatureTurn;
extern TYPE_Targetable Targetable;
extern TYPE_GetRandomControl GetRandomControl;
extern TYPE_CreatureEffect CreatureEffect;
extern TYPE2_DoBloodSplat DoBloodSplat_2;
extern TYPE_CreatureJoint CreatureJoint;
extern TYPE_CreatureAnimation CreatureAnimation;
extern TYPE_SoundEffect SoundEffect;
extern TYPE_ExplodingDeath ExplodingDeath;
extern TYPE_DisableBaddieAI DisableBaddieAI;
extern TYPE_KillItem KillItem;

#define CENTAUR_PART_DAMAGE 100
#define CENTAUR_REAR_DAMAGE 200
#define CENTAUR_TOUCH 0x30199
#define CENTAUR_DIE_ANIM 8
#define CENTAUR_TURN (ONE_DEGREE * 4) // = 728
#define CENTAUR_REAR_CHANCE 96
#define CENTAUR_REAR_RANGE SQUARE(WALL_L * 3 / 2) // = 2359296
#define CENTAUR_HITPOINTS 120
#define CENTAUR_RADIUS (WALL_L / 3) // = 341
#define CENTAUR_SMARTNESS 0x7FFF

#define ROCKET_SPEED 220

static BITE_INFO CentaurRocket = { 11, 415, 41, 13 };
static BITE_INFO CentaurRear = { 50, 30, 0, 5 };
static short CentaurMutantSlot;

enum CENTAUR_ANIM {
    CENTAUR_EMPTY = 0,
    CENTAUR_STOP = 1,
    CENTAUR_SHOOT = 2,
    CENTAUR_RUN = 3,
    CENTAUR_AIM = 4,
    CENTAUR_DEATH = 5,
    CENTAUR_WARNING = 6,
};

static short RocketGun(int x, int y, int z, short speed, short y_rot, short room_num)
{
    short fx_num = CreateEffect(room_num);
    if (fx_num != NO_ITEM) {
        FX_INFO* fx = &Ptr_VetEffects[fx_num];
        fx->room_number = room_num;
        fx->pos.x_pos = x;
        fx->pos.y_pos = y;
        fx->pos.z_pos = z;
        fx->pos.x_rot = 0;
        fx->pos.y_rot = y_rot;
        fx->pos.z_rot = 0;
        fx->object_number = Utils.getObjects(Utils.getLinks(tsu_slots[CentaurMutantSlot], LNK_OBJECT1));
        fx->frame_number = 0;
        fx->speed = ROCKET_SPEED;
        fx->shade = 4096;
        Utils.ShootAtLara(fx);
    }
	return fx_num;
}

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

    ITEM_INFO* item = &Ptr_VetItems[item_num];
    CREATURE_INFO* centaur = (CREATURE_INFO*) item->data;
    short head = 0;
    short neck = 0;
    short angle = 0;
    short dmg1 = Utils.getObjectAttribute(tsu_slots[item->object_number], ATT_DMG1);
    short snd1 = Utils.getObjectProperty(tsu_slots[item->object_number], PTY_SND1);

    if (item->hit_points <= 0) {
        if (item->current_anim_state != CENTAUR_DEATH) {
            item->current_anim_state = CENTAUR_DEATH;
            item->anim_number =
                Ptr_VetObjects[item->object_number].anim_index + CENTAUR_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;
			StrMovePosition pos;
			pos.RelX = CentaurRocket.x;
			pos.RelY = CentaurRocket.y;
			pos.RelZ = CentaurRocket.z;
			GetJointAbsPosition_2(item, &pos, CentaurRocket.mesh_num);
			int z = pos.RelZ - LaraItem->pos.z_pos;
			int x = pos.RelX - LaraItem->pos.x_pos;
			if (ABS(x) <= 32000 && ABS(z) <= 32000) {
				int dist = phd_sqrt_tr2(SQUARE(z) + SQUARE(x));
				short* bounds = GetBoundsAccurate_2(LaraItem);
				int y = LaraItem->pos.y_pos - pos.RelY + bounds[3] + 3 * (bounds[2] - bounds[3]) / 4;
				neck = -phd_atan_tr2(dist, y);
			}
        }

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

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

        switch (item->current_anim_state) {
        case CENTAUR_STOP:
			centaur->maximum_turn = 0;
            if (item->required_anim_state) {
                item->goal_anim_state = item->required_anim_state;
            } else if (info.bite && info.distance < CENTAUR_REAR_RANGE) {
                item->goal_anim_state = CENTAUR_RUN;
            } else if (Targetable(item, &info)) {
                item->goal_anim_state = CENTAUR_AIM;
            } else {
                item->goal_anim_state = CENTAUR_RUN;
            }
            break;

        case CENTAUR_RUN:
			centaur->maximum_turn = CENTAUR_TURN;
            if (info.bite && info.distance < CENTAUR_REAR_RANGE) {
                item->required_anim_state = CENTAUR_WARNING;
                item->goal_anim_state = CENTAUR_STOP;
            } else if (Targetable(item, &info)) {
                item->required_anim_state = CENTAUR_AIM;
                item->goal_anim_state = CENTAUR_STOP;
            } else if (GetRandomControl() < CENTAUR_REAR_CHANCE) {
                item->required_anim_state = CENTAUR_WARNING;
                item->goal_anim_state = CENTAUR_STOP;
            }
            break;

        case CENTAUR_AIM:
			centaur->maximum_turn = 0;
            if (item->required_anim_state) {
                item->goal_anim_state = item->required_anim_state;
            } else if (Targetable(item, &info)) {
                item->goal_anim_state = CENTAUR_SHOOT;
            } else {
                item->goal_anim_state = CENTAUR_STOP;
            }
            break;

        case CENTAUR_SHOOT:
            if (item->required_anim_state == CENTAUR_EMPTY) {
                item->required_anim_state = CENTAUR_AIM;
				CentaurMutantSlot = item->object_number;
                CreatureEffect(item, &CentaurRocket, RocketGun);
            }
            break;

        case CENTAUR_WARNING:
            if (item->required_anim_state == CENTAUR_EMPTY
                && (item->touch_bits & CENTAUR_TOUCH)) {
                CreatureEffect(item, &CentaurRear, DoBloodSplat_2);
                LaraItem->hit_points -= DOUBLE_VALUE_ITEM(dmg1, CENTAUR_REAR_DAMAGE);
                LaraItem->hit_status = 1;
                item->required_anim_state = CENTAUR_STOP;
            }
            break;
        }
    }

    CreatureJoint(item, 0, head);
    CreatureJoint(item, 1, neck);
    CreatureAnimation(item_num, angle, 0);

    if (item->status == STS_DESACTIVATED) {
		if (snd1 != NO_ITEM)
            SoundEffect(snd1, &item->pos, 0);
        ExplodingDeath(item_num, -1, 769);
        DisableBaddieAI(item_num);
        KillItem(item_num);
    }
}

void InitialiseTR1_Centaur()
{
    for (int index = 0; index < SLOTS_NUMBER; ++index)
    {
        short dependency = Utils.getLinks(TR1_CENTAUR_MUTANT1 + index, LNK_OBJECT1);
        if (dependency >= 0 && dependency < TR_OBJECTS_NUMBER && MapToFirst(dependency, SLOTS_NUMBER) == TR1_MUTANT_GRENADE1 && tomb[dependency].get_object())
		{
			tomb[TR1_CENTAUR_MUTANT1 + index].set_name("Centaur");
			tomb[TR1_CENTAUR_MUTANT1 + index].initialise(TR1_CENTAUR_MUTANT1 + index, FUNCTION_SHADOW, 0);
			tomb[TR1_CENTAUR_MUTANT1 + index].set_shadow_size(85);
			tomb[TR1_CENTAUR_MUTANT1 + index].set_func_initialise(InitialiseCreature);
			tomb[TR1_CENTAUR_MUTANT1 + index].set_func_collide(CreatureCollision);
			tomb[TR1_CENTAUR_MUTANT1 + index].set_func_control(CtrlTR1_Centaur);
			tomb[TR1_CENTAUR_MUTANT1 + index].set_func_draw(DrawAnimatingItemCustom, NULL);
			tomb[TR1_CENTAUR_MUTANT1 + index].set_health(CENTAUR_HITPOINTS);
			tomb[TR1_CENTAUR_MUTANT1 + index].set_radius_and_pivot(CENTAUR_RADIUS, 400);
			tomb[TR1_CENTAUR_MUTANT1 + index].set_hit_effect(HIT_BLOOD);
			tomb[TR1_CENTAUR_MUTANT1 + index].set_creature(TRUE);
			tomb[TR1_CENTAUR_MUTANT1 + index].set_rotation_meshtree(10, ROT_X | ROT_Y);
			tomb[TR1_CENTAUR_MUTANT1 + index].set_save(TRUE, TRUE, TRUE, FALSE, TRUE);
		}
    }
}
