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

extern TYPE_CreatureCollision CreatureCollision;
extern TYPE_InitialiseCreature InitialiseCreature;
extern TYPE2_GetFloor GetFloor_2;
extern TYPE_GetCeiling GetCeiling;
extern TYPE_CreatureActive CreatureActive;
extern TYPE_GetHeight GetHeight;
extern TYPE2_GetJointAbsPosition GetJointAbsPosition_2;
extern TYPE_TriggerDynamic TriggerDynamic;
extern TYPE_GetAITarget GetAITarget;
extern TYPE_CreatureAIInfo CreatureAIInfo;
extern TYPE_phd_atan phd_atan;
extern TYPE_GetCreatureMood GetCreatureMood;
extern TYPE_CreatureMood CreatureMood;
extern TYPE_CreatureTurn CreatureTurn;
extern TYPE_TargetVisible TargetVisible;
extern TYPE_AlertAllGuards AlertAllGuards;
extern TYPE2_GetBestFrame GetBestFrame_2;
extern TYPE2_LOS LOS_2;
extern TYPE_AIGuard AIGuard;
extern TYPE_Targetable Targetable;
extern TYPE_ShotLara ShotLara;
extern TYPE_GetRandomControl GetRandomControl;
extern TYPE_CreatureJoint CreatureJoint;
extern TYPE_TestTriggers TestTriggers;
extern TYPE_CreatureAnimation CreatureAnimation;
extern TYPE_CreatureVault CreatureVault;

static BITE_INFO* sas_gun;

void CtrlTR5_Sas(short item_number)
{
	ITEM_INFO* item;
	ITEM_INFO* enemy_bak;
	FLOOR_INFO* floor;
	CREATURE_INFO* sas;
	StrMovePosition pos;
	GAMEVECTOR start;
	GAMEVECTOR target;
	AI_INFO sasAI;
	AI_INFO lara_info;
	AI_INFO laraAI;
	StrBoxCollisione* bounds;
	long Xoffset, Zoffset, x, y, z, nearheight, midheight, farheight, dx, dz;
	short first, room_number, jump_ahead, long_jump_ahead, angle, head, torso_x, torso_y, los, frame, base, dmg1, dmg2;

	if (!CreatureActive(item_number))
		return;

	item = &Ptr_VetItems[item_number];
	sas = (CREATURE_INFO*)item->data;
	sas_gun = &EnemyBite[Ptr_VetObjects[item->object_number].bit_offset];
	angle = 0;
	head = 0;
	torso_x = 0;
	torso_y = 0;
    dmg1 = Utils.getObjectAttribute(tsu_slots[item->object_number], ATT_DMG1);
    dmg2 = Utils.getObjectAttribute(tsu_slots[item->object_number], ATT_DMG2);
	first = MapToFirst(tsu_slots[item->object_number], SLOTS_NUMBER);
	room_number = item->room_number;
	Xoffset = 870 * phd_sin_tr2(item->pos.y_rot) >> 14;
	Zoffset = 870 * phd_cos_tr2(item->pos.y_rot) >> 14;
	x = item->pos.x_pos + Xoffset;
	y = item->pos.y_pos;
	z = item->pos.z_pos + Zoffset;
	floor = GetFloor_2(x, y, z, &room_number);
	nearheight = GetHeight(floor, x, y, z);
	room_number = item->room_number;
	x += Xoffset;
	z += Zoffset;
	floor = GetFloor_2(x, y, z, &room_number);
	midheight = GetHeight(floor, x, y, z);
	room_number = item->room_number;
	x += Xoffset;
	z += Zoffset;
	floor = GetFloor_2(x, y, z, &room_number);
	farheight = GetHeight(floor, x, y, z);

	if (item->box_number == LaraItem->box_number || y >= nearheight - 384 || y >= midheight + 256 || y <= midheight - 256)
		jump_ahead = 0;
	else
		jump_ahead = 1;

	if (item->box_number == LaraItem->box_number || y >= nearheight - 384 || y >= midheight - 384 || y >= farheight + 256 || y <= farheight - 256)
		long_jump_ahead = 0;
	else
		long_jump_ahead = 1;

	if (item->current_anim_state == 17 && !item->hit_status && LaraItem->speed < 40 && !Lara.isFlagsEnabled(FLF_HAS_FIRED))
		sas->alerted = 0;

	if (item->ai_bits)
		GetAITarget(sas);
	else
		sas->enemy = LaraItem;

	CreatureAIInfo(item, &sasAI);
	lara_info.angle = sasAI.angle;
	lara_info.distance = sasAI.distance;

	if (sas->enemy == LaraItem)
	{
		laraAI.angle = sasAI.angle;
		laraAI.distance = sasAI.distance;
	}
	else
	{
		dx = LaraItem->pos.x_pos - item->pos.x_pos;
		dz = LaraItem->pos.z_pos - item->pos.z_pos;
		laraAI.angle = (short)(phd_atan(dz, dx) - item->pos.y_rot);
		laraAI.distance = ABS(dx) <= 32000 && ABS(dz) <= 32000 ? SQUARE(dz) + SQUARE(dx) : 0x7FFFFFFF;
	}

	if (item->hit_points <= 0)
	{
		if (item->current_anim_state != 8 && item->current_anim_state != 6)
		{
			if (lara_info.angle >= 12288 || lara_info.angle <= -12288)
			{
				item->current_anim_state = 8;
				item->anim_number = Ptr_VetObjects[item->object_number].anim_index + 16;
				item->pos.y_rot += lara_info.angle + 32768;
			}
			else
			{
				item->current_anim_state = 6;
				item->anim_number = Ptr_VetObjects[item->object_number].anim_index + 11;
				item->pos.y_rot += lara_info.angle;
			}

			item->frame_number = Ptr_VetAnimations[item->anim_number].frame_base;
		}
	}
	else
	{
		GetCreatureMood(item, &sasAI, VIOLENT);

		if (first == TR5_VCI_WORKER1)
		{
			if (item->hit_points < Ptr_VetObjects[item->object_number].hit_points)
				sas->mood = MOOD_ESCAPE;
			else if (sas->enemy == LaraItem)
				sas->mood = MOOD_BORED;
		}

		CreatureMood(item, &sasAI, VIOLENT);
		angle = CreatureTurn(item, sas->maximum_turn);
		enemy_bak = sas->enemy;
		sas->enemy = LaraItem;

		if ((laraAI.distance < 0x400000 && LaraItem->speed > 20) || item->hit_status || TargetVisible(item, &laraAI))
		{
			if (first != TR5_VCI_WORKER1)
			{
				if (ABS(item->pos.y_pos - LaraItem->pos.y_pos) < 1280)
					AlertAllGuards(item_number);
			}
		}

		sas->enemy = enemy_bak;
		bounds = GetBestFrame_2(enemy_bak);
		start.x = item->pos.x_pos;
		start.y = item->pos.y_pos - 384;
		start.z = item->pos.z_pos;
		start.room_number = item->room_number;
		target.x = enemy_bak->pos.x_pos;
		target.y = enemy_bak->pos.y_pos + ((bounds->MaxY + 3 * bounds->MinY) >> 2);
		target.z = enemy_bak->pos.z_pos;
		los = (item->ocb_bits & 15) != 10 && !LOS_2(&start, &target);
		sas->maximum_turn = 0;

		switch (item->current_anim_state)
		{
		case 1:
			head = lara_info.angle;
			sas->LOT.is_jumping = 0;
			sas->flags = 0;

			if (sasAI.ahead && !(item->ai_bits & SAI_GUARD))
			{
				torso_y = sasAI.angle >> 1;
				torso_x = sasAI.x_angle;
			}

			if (first == TR5_VCI_WORKER1 && item == Lara.getTarget())
				item->goal_anim_state = 39;
			else if (item->required_anim_state)
				item->goal_anim_state = item->required_anim_state;
			else if (item->ai_bits & SAI_GUARD)
			{
				if (item->ai_bits & SAI_MODIFY)
					head = 0;
				else
					head = AIGuard(sas);

				if (item->reserved_1 >= 1)
				{
					item->reserved_1--;

					if (item->reserved_1 < 1)
						item->ai_bits &= ~SAI_GUARD;
				}
			}
			else if (sas->enemy == LaraItem && (lara_info.angle > 20480 || lara_info.angle < -20480) && first != TR5_VCI_WORKER1)
				item->goal_anim_state = 2;
			else if (item->ai_bits & SAI_PATROL1)
				item->goal_anim_state = 5;
			else if (item->ai_bits & SAI_AMBUSH)
				item->goal_anim_state = 7;
			else if (!Targetable(item, &sasAI) || first == TR5_VCI_WORKER1)
			{
				if (jump_ahead || long_jump_ahead)
				{
					sas->maximum_turn = 0;
					item->anim_number = Ptr_VetObjects[item->object_number].anim_index + 41;
					item->frame_number = Ptr_VetAnimations[item->anim_number].frame_base;
					item->current_anim_state = 26;

					if (!long_jump_ahead)
						item->goal_anim_state = 27;
					else
						item->goal_anim_state = 28;

					sas->LOT.is_jumping = 1;
				}
				else if (los)
					item->goal_anim_state = 31;
				else if (sas->mood == MOOD_BORED)
					item->goal_anim_state = 1;
				else if (sasAI.distance < 0x900000 || item->ai_bits & SAI_FOLLOW)
					item->goal_anim_state = 5;
				else
					item->goal_anim_state = 7;
			}
			else
			{
				if (sasAI.distance < 0x1000000 || sasAI.src_zone != sasAI.target_zone)
					item->goal_anim_state = 4;
				else
					item->goal_anim_state = 5;
			}

			break;

		case 2:
			sas->flags = 0;

			if (sasAI.angle >= 0)
				item->pos.y_rot -= 364;
			else
				item->pos.y_rot += 364;

			if (item->frame_number == Ptr_VetAnimations[item->anim_number].frame_end)
				item->pos.y_rot += 32768;

			break;

		case 3:
		case 35:
			torso_y = lara_info.angle >> 1;
			head = lara_info.angle >> 1;

			if (ABS(sasAI.angle) >= 364)
			{
				if (sasAI.angle >= 0)
					item->pos.y_rot += 364;
				else
					item->pos.y_rot -= 364;
			}
			else
				item->pos.y_rot += sasAI.angle;

			frame = item->frame_number;
			base = Ptr_VetAnimations[item->anim_number].frame_base;

			if (item->current_anim_state == 35 && sas->flags && frame < base + 10 && (frame - base) & 1)
				sas->flags = 0;

			if (!sas->flags)
			{
				sas->flags = 1;
				item->fired_weapon = 2;
				ShotLara(item, &sasAI, sas_gun, lara_info.angle >> 1, DOUBLE_VALUE_ANIM(item->current_anim_state, 3, DOUBLE_VALUE_ITEM(dmg1, 60), DOUBLE_VALUE_ITEM(dmg2, 10)));
			}

			break;

		case 4:
			sas->flags = 0;
			torso_y = lara_info.angle >> 1;
			head = lara_info.angle >> 1;

			if (sasAI.ahead)
				torso_x = sasAI.x_angle;

			if (ABS(sasAI.angle) >= 364)
			{
				if (sasAI.angle >= 0)
					item->pos.y_rot += 364;
				else
					item->pos.y_rot -= 364;
			}
			else
				item->pos.y_rot += sasAI.angle;

			if (!Targetable(item, &sasAI))
				item->goal_anim_state = 1;
			else if (first == TR5_GUARD_FOUR1)
				item->goal_anim_state = 3;
			else
				item->goal_anim_state = 35;

			break;

		case 5:
			sas->LOT.is_jumping = 0;
			sas->maximum_turn = 910;

			if (!Targetable(item, &sasAI) || sasAI.distance >= 0x1000000 && sasAI.src_zone == sasAI.target_zone ||
				first == TR5_VCI_WORKER1 || item->ai_bits & (SAI_AMBUSH | SAI_PATROL1))
			{
				if (jump_ahead || long_jump_ahead)
				{
					sas->maximum_turn = 0;
					item->anim_number = Ptr_VetObjects[item->object_number].anim_index + 41;
					item->frame_number = Ptr_VetAnimations[item->anim_number].frame_base;
					item->current_anim_state = 26;

					if (!long_jump_ahead)
						item->goal_anim_state = 27;
					else
						item->goal_anim_state = 28;

					sas->LOT.is_jumping = 1;
				}
				else if (sasAI.distance < 0x100000)
					item->goal_anim_state = 1;
				else if (los && !item->ai_bits)
					item->goal_anim_state = 1;
				else if (sasAI.distance > 0x900000 && !(item->ai_bits & SAI_PATROL1))
					item->goal_anim_state = 7;	
			}
			else
				item->goal_anim_state = 4;

			break;

		case 7:
			sas->LOT.is_jumping = 0;
			sas->maximum_turn = 1820;

			if (!Targetable(item, &sasAI) || sasAI.distance >= 0x1000000 && sasAI.src_zone == sasAI.target_zone || first == TR5_VCI_WORKER1)
			{
				if (jump_ahead || long_jump_ahead)
				{
					sas->maximum_turn = 0;
					item->anim_number = Ptr_VetObjects[item->object_number].anim_index + 50;
					item->frame_number = Ptr_VetAnimations[item->anim_number].frame_base;
					item->current_anim_state = 26;

					if (!long_jump_ahead)
						item->goal_anim_state = 27;
					else
						item->goal_anim_state = 28;

					sas->LOT.is_jumping = 1;
				}
				else if (los)
					item->goal_anim_state = 1;
				else if (sasAI.distance < 0x900000)
					item->goal_anim_state = 5;
			}
			else
				item->goal_anim_state = 4;

			break;

		case 14:
			head = lara_info.angle;

			if (item->pos.y_pos >= item->floor - 512)
				item->goal_anim_state = 4;

			if (ABS(sasAI.angle) >= 364)
			{
				if (sasAI.angle >= 0)
					item->pos.y_rot += 364;
				else
					item->pos.y_rot -= 364;
			}
			else
				item->pos.y_rot += sasAI.angle;

			break;

		case 15:
			head = AIGuard(sas);

			if (sas->alerted)
				item->goal_anim_state = 16;

			break;

		case 16:
		case 18:
			frame = item->frame_number;
			base = Ptr_VetAnimations[item->anim_number].frame_base;

			if (frame == base + 44)
				item->meshswap_meshbits = 0;
			else if (frame == Ptr_VetAnimations[item->anim_number].frame_end)
				item->pos.y_rot -= 16384;

			break;

		case 17:
			head = 0;

			if (sas->alerted)
				item->goal_anim_state = 18;

			break;

		case 19:
			head = AIGuard(sas);

			if (sas->alerted)
				item->goal_anim_state = 1;

			break;

		case 31:

			if ((item->ocb_bits & 15) != 8 || !los || item->hit_status)
				item->goal_anim_state = 30;

			//same thing as 39 and 36

		case 30:
			sas->LOT.is_jumping = 0;
			sas->maximum_turn = 910;

			if (jump_ahead || long_jump_ahead || sasAI.distance < 0x100000 || !los || item->hit_status)
				item->goal_anim_state = 1;

			break;

		case 37:
			frame = item->frame_number;
			base = Ptr_VetAnimations[item->anim_number].frame_base;

			if (frame == base)
				item->meshswap_meshbits = 1024;
			else if (frame == Ptr_VetAnimations[item->anim_number].frame_end)
			{
				item->required_anim_state = 5;
				item->meshswap_meshbits = 0;
			}

			break;

		case 38:

			if ((first != TR5_VCI_WORKER1 || item != Lara.getTarget()) &&
				(item->ai_bits & SAI_GUARD && (GetRandomControl() & 0x7F || item->reserved_1 >= 10) || (item->ocb_bits & 15) == 9))
			{
				if (item->ai_bits & SAI_GUARD)
				{
					head = AIGuard(sas);

					if (item->reserved_1 >= 1)
					{
						item->reserved_1--;

						if (item->reserved_1 < 1)
							item->ai_bits &= ~SAI_GUARD;
					}
				}
			}
			else
				item->goal_anim_state = 1;

			break;

		case 39:

			if (item != Lara.getTarget() && !(GetRandomControl() & 0x3F))
			{
				if ((item->ocb_bits & 15) == 9)
					item->required_anim_state = 38;

				item->goal_anim_state = 1;
			}

			break;
		}
	}

	if (item->fired_weapon)
	{
		pos.RelX = sas_gun->x;
		pos.RelY = sas_gun->y;
		pos.RelZ = sas_gun->z;
		GetJointAbsPosition_2(item, &pos, sas_gun->mesh_num);
		TriggerDynamic(pos.RelX, pos.RelY, pos.RelZ, (item->fired_weapon << 1) + 10, 192, 128, 32);
	}

	CreatureJoint(item, 0, torso_y);
	CreatureJoint(item, 1, torso_x);
	CreatureJoint(item, 2, head);

	if (sas->reached_goal && sas->enemy && sas->enemy->object_number == SLOT_AI_PATROL1)
	{
		if ((sas->enemy->flags & 0x1E) == 4)
		{
			item->goal_anim_state = 1;
			item->required_anim_state = 37;
		}
		else if ((sas->enemy->flags & 0x1E) == 16)
		{
			item->goal_anim_state = 1;
			item->required_anim_state = 38;
			item->reserved_1 = 300;
			item->ai_bits |= SAI_GUARD;
		}
		else if ((sas->enemy->flags & 0x1E) == 20)
		{
			item->goal_anim_state = 1;
			item->required_anim_state = 36;
		}
		else
		{
			item->required_anim_state = 5;

			if (sas->enemy->flags & 2)
				item->reserved_4 = item->reserved_3 - 1;

			if (sas->enemy->flags & 8)
			{
				item->required_anim_state = 1;
				item->reserved_1 = 300;
				item->ai_bits |= SAI_GUARD;
			}
		}

		room_number = sas->enemy->room_number;
		floor = GetFloor_2(sas->enemy->pos.x_pos, sas->enemy->pos.y_pos, sas->enemy->pos.z_pos, &room_number);
		GetHeight(floor, sas->enemy->pos.x_pos, sas->enemy->pos.y_pos, sas->enemy->pos.z_pos);
		TestTriggers(trigger_index, 1, 0);
		item->reserved_4++;
		sas->reached_goal = 0;
		sas->enemy = 0;
	}

	if ((item->current_anim_state >= 20 || item->current_anim_state == 6 || item->current_anim_state == 8) && item->current_anim_state != 30)
		CreatureAnimation(item_number, angle, 0);
	else
	{
		switch (CreatureVault(item_number, angle, 0, 256))
		{
		case -4:
			sas->maximum_turn = 0;
			item->anim_number = Ptr_VetObjects[item->object_number].anim_index + 38;
			item->current_anim_state = 23;
			item->frame_number = Ptr_VetAnimations[item->anim_number].frame_base;
			break;

		case -3:
			sas->maximum_turn = 0;
			item->anim_number = Ptr_VetObjects[item->object_number].anim_index + 39;
			item->current_anim_state = 24;
			item->frame_number = Ptr_VetAnimations[item->anim_number].frame_base;
			break;

		case -2:
			sas->maximum_turn = 0;
			item->anim_number = Ptr_VetObjects[item->object_number].anim_index + 40;
			item->current_anim_state = 25;
			item->frame_number = Ptr_VetAnimations[item->anim_number].frame_base;
			break;

		case 2:
			sas->maximum_turn = 0;
			item->anim_number = Ptr_VetObjects[item->object_number].anim_index + 35;
			item->current_anim_state = 20;
			item->frame_number = Ptr_VetAnimations[item->anim_number].frame_base;
			break;

		case 3:
			sas->maximum_turn = 0;
			item->anim_number = Ptr_VetObjects[item->object_number].anim_index + 36;
			item->current_anim_state = 21;
			item->frame_number = Ptr_VetAnimations[item->anim_number].frame_base;
			break;

		case 4:
			sas->maximum_turn = 0;
			item->anim_number = Ptr_VetObjects[item->object_number].anim_index + 37;
			item->current_anim_state = 22;
			item->frame_number = Ptr_VetAnimations[item->anim_number].frame_base;
			break;
		}
	}
}

void InitTR5_Sas(short item_number)
{
	ITEM_INFO* item;
	FLOOR_INFO* floor;
	short anim_index, room_num;

	item = &Ptr_VetItems[item_number];
	InitialiseCreature(item_number);
	anim_index = Ptr_VetObjects[item->object_number].anim_index;

	switch (item->ocb_bits & 15)
	{
	case 0:
	case 10:
		item->anim_number = anim_index;
		item->goal_anim_state = 1;
		break;

	case 1:
		item->goal_anim_state = 11;
		item->anim_number = anim_index + 23;
		break;

	case 2:
		item->goal_anim_state = 13;
		item->anim_number = anim_index + 25;
		item->status -= STS_INVISIBLE;
		break;

	case 3:
		item->anim_number = anim_index + 28;
		item->goal_anim_state = 15;
		item->meshswap_meshbits = 9216;
		break;

	case 4:
		item->goal_anim_state = 17;
		item->anim_number = anim_index + 30;
		item->meshswap_meshbits = 8192;
		break;

	case 5:
		item->anim_number = anim_index + 26;
		item->goal_anim_state = 14;
		room_num = item->room_number;
		floor = GetFloor_2(item->pos.x_pos, item->pos.y_pos, item->pos.z_pos, &room_num);
		item->pos.y_pos = GetCeiling(floor, item->pos.x_pos, item->pos.y_pos, item->pos.z_pos) - 2048;
		break;

	case 6:
		item->goal_anim_state = 19;
		item->anim_number = anim_index + 32;
		break;

	case 7:
	case 9:
		item->goal_anim_state = 38;
		item->anim_number = anim_index + 59;
		break;

	case 8:
		item->goal_anim_state = 31;
		item->anim_number = anim_index + 46;
		break;

	case 11:
		item->goal_anim_state = 7;
		item->anim_number = anim_index + 12;
		break;
	}

	item->frame_number = Ptr_VetAnimations[item->anim_number].frame_base;
	item->current_anim_state = item->goal_anim_state;
}

void InitialiseTR5_BlueGuard()
{
    for (int index = 0; index < SLOTS_NUMBER; ++index)
    {
        tomb[TR5_GUARD_FOUR1 + index].set_name("Blue Guard");
        tomb[TR5_GUARD_FOUR1 + index].initialise(TR5_GUARD_FOUR1 + index, FUNCTION_ZONE_BEFORE | FUNCTION_SHADOW, QUERY_GUNFLASH | QUERY_HEADSHOT | QUERY_PATROL | QUERY_PATROL2 | QUERY_VAULT);
        tomb[TR5_GUARD_FOUR1 + index].set_shadow_size(128);
        tomb[TR5_GUARD_FOUR1 + index].set_func_initialise(InitTR5_Sas);
        tomb[TR5_GUARD_FOUR1 + index].set_func_collide(CreatureCollision);
        tomb[TR5_GUARD_FOUR1 + index].set_func_control(CtrlTR5_Sas);
        tomb[TR5_GUARD_FOUR1 + index].set_bitoffset(TROFF_SAS1);
        tomb[TR5_GUARD_FOUR1 + index].set_func_draw(DrawAnimatingItemCustom, NULL);
        tomb[TR5_GUARD_FOUR1 + index].set_health(24);
        tomb[TR5_GUARD_FOUR1 + index].set_radius_and_pivot(102, 50);
        tomb[TR5_GUARD_FOUR1 + index].set_hit_effect(HIT_BLOOD);
        tomb[TR5_GUARD_FOUR1 + index].set_creature(TRUE);
        tomb[TR5_GUARD_FOUR1 + index].set_rotation_meshtree(6, ROT_X | ROT_Y);
        tomb[TR5_GUARD_FOUR1 + index].set_rotation_meshtree(13, ROT_X | ROT_Y);
        tomb[TR5_GUARD_FOUR1 + index].set_explodable_meshbits(0x4000);
        tomb[TR5_GUARD_FOUR1 + index].set_meshswap(10);
        tomb[TR5_GUARD_FOUR1 + index].set_meshswap(13);
        tomb[TR5_GUARD_FOUR1 + index].set_save(TRUE, TRUE, TRUE, TRUE, TRUE);
    }
}

void InitialiseTR5_Swat()
{
    for (int index = 0; index < SLOTS_NUMBER; ++index)
    {
        tomb[TR5_GUARD_TWO1 + index].set_name("Swat");
        tomb[TR5_GUARD_TWO1 + index].initialise(TR5_GUARD_TWO1 + index, FUNCTION_SHADOW, QUERY_GUNFLASH | QUERY_HEADSHOT | QUERY_PATROL | QUERY_PATROL2);
        tomb[TR5_GUARD_TWO1 + index].set_shadow_size(128);
        tomb[TR5_GUARD_TWO1 + index].set_func_initialise(InitTR5_Sas);
        tomb[TR5_GUARD_TWO1 + index].set_func_collide(CreatureCollision);
        tomb[TR5_GUARD_TWO1 + index].set_func_control(CtrlTR5_Sas);
        tomb[TR5_GUARD_TWO1 + index].set_bitoffset(TROFF_SAS2);
        tomb[TR5_GUARD_TWO1 + index].set_func_draw(DrawAnimatingItemCustom, NULL);
        tomb[TR5_GUARD_TWO1 + index].set_health(24);
        tomb[TR5_GUARD_TWO1 + index].set_radius_and_pivot(102, 50);
        tomb[TR5_GUARD_TWO1 + index].set_hit_effect(HIT_BLOOD);
        tomb[TR5_GUARD_TWO1 + index].set_creature(TRUE);
        tomb[TR5_GUARD_TWO1 + index].set_rotation_meshtree(6, ROT_X | ROT_Y);
        tomb[TR5_GUARD_TWO1 + index].set_rotation_meshtree(13, ROT_X | ROT_Y);
        tomb[TR5_GUARD_TWO1 + index].set_explodable_meshbits(0x4000);
        tomb[TR5_GUARD_TWO1 + index].set_meshswap(10);
        tomb[TR5_GUARD_TWO1 + index].set_meshswap(13);
        tomb[TR5_GUARD_TWO1 + index].set_save(TRUE, TRUE, TRUE, TRUE, TRUE);
    }
}

void InitialiseTR5_SwatPlus()
{
    for (int index = 0; index < SLOTS_NUMBER; ++index)
    {
        tomb[TR5_GUARD_THREE1 + index].set_name("Swat Plus");
        tomb[TR5_GUARD_THREE1 + index].initialise(TR5_GUARD_THREE1 + index, FUNCTION_SHADOW, QUERY_GUNFLASH | QUERY_HEADSHOT | QUERY_PATROL | QUERY_PATROL2);
        tomb[TR5_GUARD_THREE1 + index].set_shadow_size(128);
        tomb[TR5_GUARD_THREE1 + index].set_func_initialise(InitTR5_Sas);
        tomb[TR5_GUARD_THREE1 + index].set_func_collide(CreatureCollision);
        tomb[TR5_GUARD_THREE1 + index].set_func_control(CtrlTR5_Sas);
        tomb[TR5_GUARD_THREE1 + index].set_bitoffset(TROFF_SAS2);
        tomb[TR5_GUARD_THREE1 + index].set_func_draw(DrawAnimatingItemCustom, NULL);
        tomb[TR5_GUARD_THREE1 + index].set_health(24);
        tomb[TR5_GUARD_THREE1 + index].set_radius_and_pivot(102, 50);
        tomb[TR5_GUARD_THREE1 + index].set_hit_effect(HIT_BLOOD);
        tomb[TR5_GUARD_THREE1 + index].set_creature(TRUE);
        tomb[TR5_GUARD_THREE1 + index].set_rotation_meshtree(6, ROT_X | ROT_Y);
        tomb[TR5_GUARD_THREE1 + index].set_rotation_meshtree(13, ROT_X | ROT_Y);
        tomb[TR5_GUARD_THREE1 + index].set_explodable_meshbits(0x4000);
        tomb[TR5_GUARD_THREE1 + index].set_meshswap(10);
        tomb[TR5_GUARD_THREE1 + index].set_meshswap(13);
        tomb[TR5_GUARD_THREE1 + index].set_save(TRUE, TRUE, TRUE, TRUE, TRUE);
    }
}

void InitialiseTR5_Mafia()
{
    for (int index = 0; index < SLOTS_NUMBER; ++index)
    {
        tomb[TR5_ARMED_BADDY_ONE1 + index].set_name("Mafia");
        tomb[TR5_ARMED_BADDY_ONE1 + index].initialise(TR5_ARMED_BADDY_ONE1 + index, FUNCTION_SHADOW, QUERY_GUNFLASH | QUERY_HEADSHOT | QUERY_PATROL | QUERY_PATROL2);
        tomb[TR5_ARMED_BADDY_ONE1 + index].set_shadow_size(128);
        tomb[TR5_ARMED_BADDY_ONE1 + index].set_func_initialise(InitTR5_Sas);
        tomb[TR5_ARMED_BADDY_ONE1 + index].set_func_collide(CreatureCollision);
        tomb[TR5_ARMED_BADDY_ONE1 + index].set_func_control(CtrlTR5_Sas);
        tomb[TR5_ARMED_BADDY_ONE1 + index].set_bitoffset(TROFF_SAS2);
        tomb[TR5_ARMED_BADDY_ONE1 + index].set_func_draw(DrawAnimatingItemCustom, NULL);
        tomb[TR5_ARMED_BADDY_ONE1 + index].set_health(24);
        tomb[TR5_ARMED_BADDY_ONE1 + index].set_radius_and_pivot(102, 50);
        tomb[TR5_ARMED_BADDY_ONE1 + index].set_hit_effect(HIT_BLOOD);
        tomb[TR5_ARMED_BADDY_ONE1 + index].set_creature(TRUE);
        tomb[TR5_ARMED_BADDY_ONE1 + index].set_rotation_meshtree(6, ROT_X | ROT_Y);
        tomb[TR5_ARMED_BADDY_ONE1 + index].set_rotation_meshtree(13, ROT_X | ROT_Y);
        tomb[TR5_ARMED_BADDY_ONE1 + index].set_explodable_meshbits(0x4000);
        tomb[TR5_ARMED_BADDY_ONE1 + index].set_meshswap(10);
        tomb[TR5_ARMED_BADDY_ONE1 + index].set_meshswap(13);
        tomb[TR5_ARMED_BADDY_ONE1 + index].set_save(TRUE, TRUE, TRUE, TRUE, TRUE);
    }
}

void InitialiseTR5_Scientist()
{
    for (int index = 0; index < SLOTS_NUMBER; ++index)
    {
        tomb[TR5_VCI_WORKER1 + index].set_name("Scientist");
        tomb[TR5_VCI_WORKER1 + index].initialise(TR5_VCI_WORKER1 + index, FUNCTION_SHADOW, QUERY_HEADSHOT | QUERY_PATROL | QUERY_PATROL2);
        tomb[TR5_VCI_WORKER1 + index].set_shadow_size(128);
        tomb[TR5_VCI_WORKER1 + index].set_func_initialise(InitTR5_Sas);
        tomb[TR5_VCI_WORKER1 + index].set_func_collide(CreatureCollision);
        tomb[TR5_VCI_WORKER1 + index].set_func_control(CtrlTR5_Sas);
        tomb[TR5_VCI_WORKER1 + index].set_func_draw(DrawAnimatingItemCustom, NULL);
        tomb[TR5_VCI_WORKER1 + index].set_health(24);
        tomb[TR5_VCI_WORKER1 + index].set_radius_and_pivot(102, 50);
        tomb[TR5_VCI_WORKER1 + index].set_hit_effect(HIT_BLOOD);
        tomb[TR5_VCI_WORKER1 + index].set_creature(TRUE);
        tomb[TR5_VCI_WORKER1 + index].set_rotation_meshtree(6, ROT_X | ROT_Y);
        tomb[TR5_VCI_WORKER1 + index].set_rotation_meshtree(13, ROT_X | ROT_Y);
        tomb[TR5_VCI_WORKER1 + index].set_explodable_meshbits(0x4000);
        tomb[TR5_VCI_WORKER1 + index].set_meshswap(10);
        tomb[TR5_VCI_WORKER1 + index].set_meshswap(13);
        tomb[TR5_VCI_WORKER1 + index].set_save(TRUE, TRUE, TRUE, TRUE, TRUE);
    }
}
