2019-12-20 11:23:03 +01:00
|
|
|
#include "../newobjects.h"
|
|
|
|
#include "../../Game/items.h"
|
2019-12-24 08:51:54 +01:00
|
|
|
#include "../../Game/sphere.h"
|
|
|
|
#include "../../Game/Box.h"
|
|
|
|
#include "../../Game/effect2.h"
|
|
|
|
#include "../../Game/people.h"
|
|
|
|
#include "../../Game/draw.h"
|
|
|
|
|
|
|
|
BITE_INFO swatGun = { 0x50, 0xC8, 0x0D, 0 };
|
2019-12-20 11:23:03 +01:00
|
|
|
|
|
|
|
void InitialiseGuard(short itemNum)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item, *item2;
|
|
|
|
short anim;
|
|
|
|
short roomItemNumber;
|
|
|
|
|
|
|
|
item = &Items[itemNum];
|
|
|
|
ClearItem(itemNum);
|
|
|
|
anim = Objects[ID_SWAT].animIndex;
|
|
|
|
if (!Objects[ID_SWAT].loaded)
|
|
|
|
anim = Objects[ID_BLUE_GUARD].animIndex;
|
|
|
|
|
|
|
|
switch (item->triggerFlags)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
case 10:
|
|
|
|
item->animNumber = anim;
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
item->goalAnimState = 11;
|
|
|
|
item->animNumber = anim + 23;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
item->goalAnimState = 13;
|
|
|
|
item->animNumber = anim + 25;
|
|
|
|
// TODO: item->flags2 ^= (item->flags2 ^ ((item->flags2 & 0xFE) + 2)) & 6;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
item->goalAnimState = 15;
|
|
|
|
item->animNumber = anim + 28;
|
|
|
|
*item->pad2 = 9216;
|
|
|
|
roomItemNumber = Rooms[item->roomNumber].itemNumber;
|
|
|
|
if (roomItemNumber != NO_ITEM)
|
|
|
|
{
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
item2 = &Items[roomItemNumber];
|
|
|
|
if (item2->objectNumber >= ID_ANIMATING1 && item2->objectNumber <= ID_ANIMATING15 && item2->roomNumber == item->roomNumber && item2->triggerFlags == 3)
|
|
|
|
break;
|
|
|
|
roomItemNumber = item2->nextItem;
|
|
|
|
if (roomItemNumber == NO_ITEM)
|
|
|
|
{
|
|
|
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
|
|
item->currentAnimState = item->goalAnimState;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
item2->meshBits = -5;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
item->goalAnimState = 17;
|
|
|
|
*item->pad2 = 8192;
|
|
|
|
item->animNumber = anim + 30;
|
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
FLOOR_INFO *floor;
|
|
|
|
short roomNumber;
|
|
|
|
|
|
|
|
item->animNumber = anim + 26;
|
|
|
|
item->goalAnimState = 14;
|
|
|
|
roomNumber = item->roomNumber;
|
|
|
|
floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
|
|
|
|
GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
|
|
|
|
item->pos.yPos = GetCeiling(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos) - SECTOR(2);
|
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
item->goalAnimState = 19;
|
|
|
|
item->animNumber = anim + 32;
|
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
case 9:
|
|
|
|
item->goalAnimState = 38;
|
|
|
|
item->animNumber = anim + 59;
|
|
|
|
item->pos.xPos -= SIN(item->pos.yRot); // 4 * not exist there ??
|
|
|
|
item->pos.zPos -= COS(item->pos.yRot); // 4 * not exist there ??
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
item->goalAnimState = 31;
|
|
|
|
item->animNumber = anim + 46;
|
|
|
|
break;
|
|
|
|
case 11:
|
|
|
|
item->goalAnimState = 7;
|
|
|
|
item->animNumber = anim + 12;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void InitialiseGuardM16(short itemNum)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item;
|
|
|
|
|
|
|
|
item = &Items[itemNum];
|
|
|
|
ClearItem(itemNum);
|
|
|
|
item->animNumber = Objects[item->objectNumber].animIndex;
|
|
|
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
item->currentAnimState = 1;
|
|
|
|
item->pos.yPos += STEP_SIZE*2;
|
|
|
|
item->pos.xPos += SIN(item->pos.yRot);
|
|
|
|
item->pos.zPos += COS(item->pos.yRot);
|
|
|
|
}
|
|
|
|
|
|
|
|
void InitialiseGuardLaser(short itemNum)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item;
|
|
|
|
|
|
|
|
item = &Items[itemNum];
|
|
|
|
ClearItem(itemNum);
|
|
|
|
item->animNumber = Objects[item->objectNumber].animIndex + 6;
|
|
|
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
item->currentAnimState = 1;
|
2019-12-24 08:51:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
void ControlGuard(short itemNum)
|
|
|
|
{
|
|
|
|
if (!CreatureActive(itemNum))
|
|
|
|
return;
|
|
|
|
|
|
|
|
int animIndex = 0;
|
|
|
|
if (Objects[ID_SWAT].loaded)
|
|
|
|
animIndex= Objects[ID_SWAT].animIndex;
|
|
|
|
else
|
|
|
|
animIndex = Objects[ID_BLUE_GUARD].animIndex;
|
|
|
|
|
|
|
|
HIWORD(v2) = HIWORD(items);
|
|
|
|
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
|
|
|
|
|
|
|
|
LOWORD(v2) = item->roomNumber;
|
|
|
|
|
|
|
|
short angle = 0;
|
|
|
|
short joint2 = 0;
|
|
|
|
short joint1 = 0;
|
|
|
|
short joint0 = 0;
|
|
|
|
|
|
|
|
int x = item->pos.xPos;
|
|
|
|
int z = item->pos.zPos;
|
|
|
|
|
|
|
|
int dx = 870 * SIN(item->pos.yRot) >> W2V_SHIFT;
|
|
|
|
int dz = 870 * COS(item->pos.yRot) >> W2V_SHIFT;
|
|
|
|
|
|
|
|
x += dx;
|
|
|
|
z += dz;
|
|
|
|
|
|
|
|
short roomNumber = item->roomNumber;
|
|
|
|
FLOOR_INFO* floor = GetFloor(x, item->pos.yPos, z, &roomNumber);
|
|
|
|
int height1 = GetFloorHeight(floor, x, item->pos.yPos, z);
|
|
|
|
|
|
|
|
x += dx;
|
|
|
|
z += dz;
|
|
|
|
|
|
|
|
roomNumber = item->roomNumber;
|
|
|
|
floor = GetFloor(x, item->pos.yPos, z, &roomNumber);
|
|
|
|
int height2 = GetFloorHeight(floor, x, item->pos.yPos, z);
|
|
|
|
|
|
|
|
x += dx;
|
|
|
|
z += dz;
|
|
|
|
|
|
|
|
roomNumber = item->roomNumber;
|
|
|
|
floor = GetFloor(x, item->pos.yPos, z, &roomNumber);
|
|
|
|
int height3 = GetFloorHeight(floor, x, item->pos.yPos, z);
|
|
|
|
|
|
|
|
bool canJump1block;
|
|
|
|
if (item->boxNumber == LaraItem->boxNumber
|
|
|
|
|| item->pos.yPos >= height1 - 384
|
|
|
|
|| item->pos.yPos >= height2 + 256
|
|
|
|
|| item->pos.yPos <= height2 - 256)
|
|
|
|
canJump1block = false;
|
|
|
|
else
|
|
|
|
canJump1block = true;
|
|
|
|
|
|
|
|
bool canJump2blocks;
|
|
|
|
if (item->boxNumber == LaraItem->boxNumber
|
|
|
|
|| item->pos.yPos >= height1 - 384
|
|
|
|
|| item->pos.yPos >= height2 - 384
|
|
|
|
|| item->pos.yPos >= height3 + 256
|
|
|
|
|| item->pos.yPos <= height3 - 256)
|
|
|
|
canJump2blocks = false;
|
|
|
|
else
|
|
|
|
canJump2blocks = true;
|
|
|
|
|
|
|
|
if (item->firedWeapon)
|
|
|
|
{
|
|
|
|
PHD_VECTOR pos;
|
|
|
|
pos.x = swatGun.x;
|
|
|
|
pos.y = swatGun.y;
|
|
|
|
pos.z = swatGun.z;
|
|
|
|
GetJointAbsPosition(item, &pos, swatGun.meshNum);
|
|
|
|
TriggerDynamicLight(pos.x, pos.y, pos.z, 2 * item->firedWeapon + 10, 192, 128, 32);
|
|
|
|
item->firedWeapon--;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (item->aiBits)
|
|
|
|
GetAITarget(creature);
|
|
|
|
else
|
|
|
|
creature->enemy = LaraItem;
|
|
|
|
|
|
|
|
AI_INFO info;
|
|
|
|
AI_INFO laraInfo;
|
|
|
|
|
|
|
|
CreatureAIInfo(item, &info);
|
|
|
|
|
|
|
|
if (creature->enemy == LaraItem)
|
|
|
|
{
|
|
|
|
laraInfo.angle = info.angle;
|
|
|
|
laraInfo.distance = info.distance;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int dx = LaraItem->pos.xPos - item->pos.xPos;
|
|
|
|
int dz = LaraItem->pos.zPos - item->pos.zPos;
|
|
|
|
|
|
|
|
laraInfo.angle = ATAN(dz, dx) - item->pos.yRot;
|
|
|
|
laraInfo.distance = SQUARE(dx) + SQUARE(dz);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (item->hitPoints <= 0)
|
|
|
|
{
|
|
|
|
if (item->currentAnimState != 8 && item->currentAnimState != 6)
|
|
|
|
{
|
|
|
|
if (laraInfo.angle >= 12288 || laraInfo.angle <= -12288)
|
|
|
|
{
|
|
|
|
item->currentAnimState = 8;
|
|
|
|
item->animNumber = animIndex + 16;;
|
|
|
|
item->pos.yRot += laraInfo.angle + -ANGLE(180);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->currentAnimState = 6;
|
|
|
|
item->animNumber = animIndex + 11;
|
|
|
|
item->pos.yRot += laraInfo.angle;
|
|
|
|
}
|
|
|
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GetCreatureMood(item, &info, creature->enemy != LaraItem);
|
|
|
|
|
|
|
|
if (item->objectNumber == ID_SCIENTIST)
|
|
|
|
{
|
|
|
|
if (item->hitPoints >= Objects[ID_SCIENTIST].hitPoints)
|
|
|
|
{
|
|
|
|
if (creature->enemy == LaraItem)
|
|
|
|
creature->mood = BORED_MOOD;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
creature->mood = ESCAPE_MOOD;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Rooms[item->roomNumber].flags & ENV_FLAG_NO_LENSFLARE) // CHECK
|
|
|
|
{
|
|
|
|
if (item->objectNumber == ID_SWAT_PLUS)
|
|
|
|
{
|
|
|
|
item->itemFlags[0]++;
|
|
|
|
if (item->itemFlags[0] > 60 && !(GetRandomControl() & 0xF))
|
|
|
|
{
|
|
|
|
SoundEffect(SFX_BIO_BREATHE_OUT, &item->pos, 0);
|
|
|
|
item->itemFlags[0] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!(GlobalCounter & 7))
|
|
|
|
item->hitPoints--;
|
|
|
|
creature->mood = ESCAPE_MOOD;
|
|
|
|
if (item->hitPoints <= 0)
|
|
|
|
{
|
|
|
|
item->currentAnimState = 8;
|
|
|
|
item->animNumber = animIndex + 16;
|
|
|
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CreatureMood(item, &info, creature->enemy != LaraItem);
|
|
|
|
|
|
|
|
ITEM_INFO* enemy = creature->enemy;
|
|
|
|
angle = CreatureTurn(item, creature->maximumTurn);
|
|
|
|
creature->enemy = LaraItem;
|
|
|
|
|
|
|
|
if (laraInfo.distance < 0x400000 && LaraItem->speed > 20
|
|
|
|
|| item->hitStatus
|
|
|
|
|| TargetVisible(item, &laraInfo))
|
|
|
|
{
|
|
|
|
if (!(item->aiBits & FOLLOW) && item->objectNumber != ID_SCIENTIST && abs(item->pos.yPos - LaraItem->pos.yPos) < 1280)
|
|
|
|
{
|
|
|
|
creature->enemy = LaraItem;
|
|
|
|
AlertAllGuards(itemNum);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
creature->enemy = enemy;
|
|
|
|
|
|
|
|
GAME_VECTOR src;
|
|
|
|
src.x = item->pos.xPos;
|
|
|
|
src.y = item->pos.yPos - 384;
|
|
|
|
src.z = item->pos.zPos;
|
|
|
|
|
|
|
|
short* frame = GetBestFrame(LaraItem);
|
|
|
|
|
|
|
|
GAME_VECTOR dest;
|
|
|
|
dest.x = LaraItem->pos.xPos;
|
|
|
|
dest.y = LaraItem->pos.yPos + ((frame[3] + 3 * frame[2]) >> 2);
|
|
|
|
dest.z = LaraItem->pos.zPos;
|
|
|
|
|
|
|
|
bool los = !LOS(&src, &dest) && item->triggerFlags != 10;
|
|
|
|
|
|
|
|
creature->maximumTurn = 0;
|
|
|
|
|
|
|
|
switch (item->currentAnimState)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
creature->LOT.isJumping = false;
|
|
|
|
joint2 = laraInfo.angle;
|
|
|
|
creature->flags = 0;
|
|
|
|
|
|
|
|
if (info.ahead)
|
|
|
|
{
|
|
|
|
if (!(item->aiBits & FOLLOW))
|
|
|
|
{
|
|
|
|
joint0 = info.angle >> 1;
|
|
|
|
joint1 = info.xAngle;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (item->objectNumber == ID_SCIENTIST && item == Lara.target)
|
|
|
|
{
|
|
|
|
item->goalAnimState = 39;
|
|
|
|
}
|
|
|
|
else if (item->requiredAnimState)
|
|
|
|
{
|
|
|
|
item->goalAnimState = item->requiredAnimState;
|
|
|
|
}
|
|
|
|
else if (item->aiBits & GUARD)
|
|
|
|
{
|
|
|
|
if (item->aiBits & MODIFY)
|
|
|
|
joint2 = 0;
|
|
|
|
else
|
|
|
|
joint2 = AIGuard(creature);
|
|
|
|
|
|
|
|
if (item->aiBits & PATROL1)
|
|
|
|
{
|
|
|
|
item->triggerFlags--;
|
|
|
|
if (item->triggerFlags < 1)
|
|
|
|
item->aiBits &= ~GUARD;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (creature->enemy == LaraItem && (laraInfo.angle > 20480 || laraInfo.angle < -20480) && item->objectNumber != ID_SCIENTIST)
|
|
|
|
{
|
|
|
|
item->goalAnimState = 2;
|
|
|
|
}
|
|
|
|
else if (item->aiBits & PATROL1)
|
|
|
|
{
|
|
|
|
item->goalAnimState = 5;
|
|
|
|
}
|
|
|
|
else if (item->aiBits & AMBUSH)
|
|
|
|
{
|
|
|
|
item->goalAnimState = 7;
|
|
|
|
}
|
|
|
|
else if (Targetable(item, &info) && item->objectNumber != ID_SCIENTIST)
|
|
|
|
{
|
|
|
|
if (info.distance >= 0x1000000 && info.zoneNumber == info.enemyZone)
|
|
|
|
{
|
|
|
|
if (!(item->aiBits & MODIFY))
|
|
|
|
item->goalAnimState = 5;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
item->goalAnimState = 4;
|
|
|
|
}
|
|
|
|
else if (canJump1block || canJump2blocks)
|
|
|
|
{
|
|
|
|
creature->maximumTurn = 0;
|
|
|
|
item->animNumber = animIndex + 41;
|
|
|
|
item->currentAnimState = 26;
|
|
|
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
|
|
if (canJump1block)
|
|
|
|
item->goalAnimState = 27;
|
|
|
|
else
|
|
|
|
item->goalAnimState = 28;
|
|
|
|
creature->LOT.isJumping = true;
|
|
|
|
}
|
|
|
|
else if (los)
|
|
|
|
{
|
|
|
|
item->goalAnimState = 31;
|
|
|
|
}
|
|
|
|
else if (creature->mood)
|
|
|
|
{
|
|
|
|
if (info.distance < 0x900000 || item->aiBits & FOLLOW)
|
|
|
|
{
|
|
|
|
item->goalAnimState = 5;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
item->goalAnimState = 7;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (item->triggerFlags == 11)
|
|
|
|
item->triggerFlags = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
creature->flags = 0;
|
|
|
|
if (info.angle >= 0)
|
|
|
|
item->pos.yRot -= ANGLE(2);
|
|
|
|
else
|
|
|
|
item->pos.yRot += ANGLE(2);
|
|
|
|
if (item->frameNumber == Anims[item->animNumber].frameEnd)
|
|
|
|
item->pos.yRot += -ANGLE(180);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
case 35:
|
|
|
|
joint0 = laraInfo.angle >> 1;
|
|
|
|
joint2 = laraInfo.angle >> 1;
|
|
|
|
if (info.ahead)
|
|
|
|
joint1 = info.xAngle;
|
|
|
|
if (abs(info.angle) >= ANGLE(2))
|
|
|
|
{
|
|
|
|
if (info.angle >= 0)
|
|
|
|
item->pos.yRot += ANGLE(2);
|
|
|
|
else
|
|
|
|
item->pos.yRot -= ANGLE(2);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->pos.yRot += info.angle;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (item->currentAnimState == 35)
|
|
|
|
{
|
|
|
|
if (creature->flags)
|
|
|
|
{
|
|
|
|
if (item->frameNumber < Anims[item->animNumber].frameBase + 10
|
|
|
|
&& (item->frameNumber - Anims[item->animNumber].frameBase) & 1)
|
|
|
|
creature->flags = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!creature->flags)
|
|
|
|
{
|
|
|
|
creature->flags = 1;
|
|
|
|
item->firedWeapon = 2;
|
|
|
|
if (item->currentAnimState == 3)
|
|
|
|
ShotLara(item, &info, &swatGun, joint0, 30);
|
|
|
|
else
|
|
|
|
ShotLara(item, &info, &swatGun, joint0, 10);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
creature->flags = 0;
|
|
|
|
joint0 = laraInfo.angle >> 1;
|
|
|
|
joint2 = laraInfo.angle >> 1;
|
|
|
|
if (info.ahead)
|
|
|
|
joint1 = info.xAngle;
|
|
|
|
if (abs(info.angle) >= ANGLE(2))
|
|
|
|
{
|
|
|
|
if (info.angle >= 0)
|
|
|
|
item->pos.yRot += ANGLE(2);
|
|
|
|
else
|
|
|
|
item->pos.yRot -= ANGLE(2);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->pos.yRot += info.angle;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Targetable(item, &info))
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
else if (item->objectNumber == ID_BLUE_GUARD || item->objectNumber == ID_CRANE_GUY)
|
|
|
|
item->goalAnimState = 3;
|
|
|
|
else
|
|
|
|
item->goalAnimState = 35;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 5:
|
|
|
|
creature->LOT.isJumping = false;
|
|
|
|
creature->maximumTurn = ANGLE(5);
|
|
|
|
if (!Targetable(item, &info)
|
|
|
|
|| info.distance >= 0x1000000 && info.zoneNumber == info.enemyZone
|
|
|
|
|| item->objectNumber == ID_SCIENTIST
|
|
|
|
|| item->aiBits & AMBUSH || item->aiBits & PATROL1) // CHECK
|
|
|
|
{
|
|
|
|
if (canJump1block || canJump2blocks)
|
|
|
|
{
|
|
|
|
creature->maximumTurn = 0;
|
|
|
|
item->animNumber = animIndex + 41;
|
|
|
|
item->currentAnimState = 26;
|
|
|
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
|
|
if (canJump1block)
|
|
|
|
item->goalAnimState = 27;
|
|
|
|
else
|
|
|
|
item->goalAnimState = 28;
|
|
|
|
creature->LOT.isJumping = true;
|
|
|
|
}
|
|
|
|
else if (info.distance >= 0x100000)
|
|
|
|
{
|
|
|
|
if (!los || item->aiBits)
|
|
|
|
{
|
|
|
|
if (info.distance > 0x900000)
|
|
|
|
{
|
|
|
|
if (!(item->InDrawRoom))
|
|
|
|
item->goalAnimState = 7;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->goalAnimState = 4;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 7:
|
|
|
|
creature->LOT.isJumping = false;
|
|
|
|
creature->maximumTurn = ANGLE(10);
|
|
|
|
if (Targetable(item, &info) && (info.distance < 0x1000000 || info.enemyZone == info.zoneNumber) && item->objectNumber != ID_SCIENTIST)
|
|
|
|
{
|
|
|
|
item->goalAnimState = 4;
|
|
|
|
}
|
|
|
|
else if (v119 || v117)
|
|
|
|
{
|
|
|
|
v64 = animIndex;
|
|
|
|
creature->maximumTurn = 0;
|
|
|
|
v57 = v117 == 0;
|
|
|
|
item->animNumber = v64 + 50;
|
|
|
|
v65 = Anims[(v64 + 50)].frameBase;
|
|
|
|
item->currentAnimState = 26;
|
|
|
|
item->frameNumber = v65;
|
|
|
|
if (v57)
|
|
|
|
item->goalAnimState = 27;
|
|
|
|
else
|
|
|
|
item->goalAnimState = 28;
|
|
|
|
LOBYTE(creature->LOT.flags) |= 8u;
|
|
|
|
}
|
|
|
|
else if (v45)
|
|
|
|
{
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
}
|
|
|
|
else if (info.distance < &unk_900000)
|
|
|
|
{
|
|
|
|
item->goalAnimState = 5;
|
|
|
|
}
|
|
|
|
if (item->triggerFlags == 11)
|
|
|
|
{
|
|
|
|
LOBYTE(creature->LOT.flags) |= 8u;
|
|
|
|
creature->maximumTurn = 0;
|
|
|
|
}
|
|
|
|
goto LABEL_255;
|
|
|
|
case 14:
|
|
|
|
v68 = item->pos.yPos;
|
|
|
|
joint2 = laraInfo.angle;
|
|
|
|
v69 = item->floor;
|
|
|
|
if (v68 <= item->floor - 2048 || item->triggerFlags != 5)
|
|
|
|
{
|
|
|
|
if (v68 >= v69 - 512)
|
|
|
|
item->goalAnimState = 4;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LOWORD(v69) = item->roomNumber;
|
|
|
|
item->triggerFlags = 0;
|
|
|
|
*a4 = v69;
|
|
|
|
v70 = GetFloor(*v42, item->pos.yPos, item->pos.zPos, a4);
|
|
|
|
GetHeight(v70, *v42, item->pos.yPos, item->pos.zPos);
|
|
|
|
TestTriggers(trigger_index, 1, 0);
|
|
|
|
SoundEffect(340, &item->pos, 0);
|
|
|
|
}
|
|
|
|
if (abs(info.angle) >= 364)
|
|
|
|
{
|
|
|
|
if ((info.angle & 0x8000u) == 0)
|
|
|
|
item->pos.yRot += 364;
|
|
|
|
else
|
|
|
|
item->pos.yRot -= 364;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->pos.yRot += info.angle;
|
|
|
|
}
|
|
|
|
goto LABEL_255;
|
|
|
|
case 15:
|
|
|
|
LOWORD(v72) = AIGuard(creature);
|
|
|
|
joint2 = v72;
|
|
|
|
if (creature->bitfield & 1)
|
|
|
|
item->goalAnimState = 16;
|
|
|
|
goto LABEL_255;
|
|
|
|
case 16:
|
|
|
|
case 18:
|
|
|
|
v74 = Anims[item->animNumber].frameBase;
|
|
|
|
v75 = item->frameNumber;
|
|
|
|
if (v75 == v74)
|
|
|
|
goto LABEL_254;
|
|
|
|
if (v75 == v74 + 44)
|
|
|
|
{
|
|
|
|
v76 = item->roomNumber;
|
|
|
|
*item->pad2 = 0;
|
|
|
|
v77 = room[v76].item_number;
|
|
|
|
if (v77 == -1)
|
|
|
|
goto LABEL_255;
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
v78 = v77;
|
|
|
|
v79 = items[v78].object_number;
|
|
|
|
v80 = &items[v78];
|
|
|
|
if (v79 >= 416 && v79 <= 444 && v80->roomNumber == v76)
|
|
|
|
{
|
|
|
|
v81 = v80->triggerFlags;
|
|
|
|
if (v81 > 2 && v81 < 5)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
v77 = v80->next_item;
|
|
|
|
if (v77 == -1)
|
|
|
|
goto LABEL_255;
|
|
|
|
}
|
|
|
|
v80->mesh_bits = -3;
|
|
|
|
}
|
|
|
|
else if (v75 == Anims[item->animNumber].frame_end)
|
|
|
|
{
|
|
|
|
item->pos.yRot -= 0x4000;
|
|
|
|
}
|
|
|
|
goto LABEL_255;
|
|
|
|
case 17:
|
|
|
|
v71 = item->_bf15ea;
|
|
|
|
joint2 = 0;
|
|
|
|
if (!(v71 & 0x10) && LaraItem->speed < 40 && !(*(&lara + 69) & 0x10))
|
|
|
|
creature->bitfield &= 0xFFFEu;
|
|
|
|
if (creature->bitfield & 1)
|
|
|
|
item->goalAnimState = 18;
|
|
|
|
goto LABEL_255;
|
|
|
|
case 19:
|
|
|
|
LOWORD(v73) = AIGuard(creature);
|
|
|
|
joint2 = v73;
|
|
|
|
if (creature->bitfield & 1)
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
goto LABEL_255;
|
|
|
|
case 30:
|
|
|
|
goto LABEL_176;
|
|
|
|
case 31:
|
|
|
|
if (item->triggerFlags != 8 || !v45 || item->_bf15ea & 0x10)
|
|
|
|
item->goalAnimState = 30;
|
|
|
|
LABEL_176:
|
|
|
|
creature->LOT.flags &= 0xFFF7u;
|
|
|
|
v57 = v119 == 0;
|
|
|
|
creature->maximumTurn = 910;
|
|
|
|
if (!v57 || v117 || info.distance < 0x100000 || !v45 || item->_bf15ea & 0x10)
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
goto LABEL_255;
|
|
|
|
case 36:
|
|
|
|
goto LABEL_253;
|
|
|
|
case 37:
|
|
|
|
v82 = 0;
|
|
|
|
for (i = room[item->roomNumber].item_number; i != -1; i = v82->next_item)
|
|
|
|
{
|
|
|
|
v82 = &items[i];
|
|
|
|
if (items[i].object_number == 249)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
v84 = item->frameNumber;
|
|
|
|
v85 = &Anims[item->animNumber];
|
|
|
|
creature2 = v85;
|
|
|
|
LOWORD(v85) = HIWORD(v85->aiTarget.floor);
|
|
|
|
if (v84 == v85)
|
|
|
|
{
|
|
|
|
v86 = v82->pos.yRot;
|
|
|
|
v82->mesh_bits = 0x1FFF;
|
|
|
|
item->pos.yRot = v86;
|
|
|
|
item->pos.xPos = v82->pos.xPos - 256;
|
|
|
|
v87 = v82->pos.zPos;
|
|
|
|
*item->pad2 = 1024;
|
|
|
|
item->pos.zPos = v87 + 128;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
v85 = v85;
|
|
|
|
v88 = v84;
|
|
|
|
if (v84 == v85 + 32)
|
|
|
|
{
|
|
|
|
v82->mesh_bits = 16381;
|
|
|
|
}
|
|
|
|
else if (v84 == v85->aiTarget.item_flags)
|
|
|
|
{
|
|
|
|
v82->mesh_bits = 278461;
|
|
|
|
}
|
|
|
|
else if (v84 == &v85->aiTarget.pad_ex_light[16])
|
|
|
|
{
|
|
|
|
v82->mesh_bits = 802621;
|
|
|
|
}
|
|
|
|
else if (v84 == (&v85->aiTarget.draw_room + 1))
|
|
|
|
{
|
|
|
|
v82->mesh_bits = 819001;
|
|
|
|
}
|
|
|
|
else if (v84 == &v85->aiTarget.pad1[30])
|
|
|
|
{
|
|
|
|
v82->mesh_bits = 17592121;
|
|
|
|
}
|
|
|
|
else if (v84 == LOWORD(creature2->aiTarget.touch_bits))
|
|
|
|
{
|
|
|
|
v82->mesh_bits = 0x1FFF;
|
|
|
|
LOWORD(v88) = item->roomNumber;
|
|
|
|
*a4 = v88;
|
|
|
|
v89 = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, a4);
|
|
|
|
GetHeight(v89, item->pos.xPos, item->pos.yPos, item->pos.zPos);
|
|
|
|
TestTriggers(trigger_index, 1, 0);
|
|
|
|
item->requriedAnimState = 5;
|
|
|
|
*item->pad2 = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
goto LABEL_255;
|
|
|
|
case 38:
|
|
|
|
if ((v120 != 69 || item != lara.target)
|
|
|
|
&& (GetRandomControl() & 0x7F || (v90 = item->triggerFlags, v90 >= 10) || v90 == 9))
|
|
|
|
{
|
|
|
|
v91 = item->_bf15ea;
|
|
|
|
if (v91 & 0x200)
|
|
|
|
{
|
|
|
|
LOWORD(v92) = AIGuard(creature);
|
|
|
|
joint2 = v92;
|
|
|
|
v93 = item->_bf15ea;
|
|
|
|
if (v93 & 0x800)
|
|
|
|
{
|
|
|
|
if (--item->triggerFlags < 1)
|
|
|
|
{
|
|
|
|
BYTE1(v93) = BYTE1(v93) & 0xC9 | 8;
|
|
|
|
item->_bf15ea = v93;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LABEL_242:
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
}
|
|
|
|
goto LABEL_255;
|
|
|
|
case 39:
|
|
|
|
if (item != lara.target && !(GetRandomControl() & 0x3F))
|
|
|
|
{
|
|
|
|
v94 = item->triggerFlags;
|
|
|
|
if (v94 == 7 || v94 == 9)
|
|
|
|
item->requriedAnimState = 38;
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
}
|
|
|
|
LABEL_253:
|
|
|
|
HIWORD(v44) = HIWORD(anims);
|
|
|
|
if (item->frameNumber == Anims[item->animNumber].frameBase + 39)
|
|
|
|
{
|
|
|
|
LABEL_254:
|
|
|
|
LOWORD(v44) = item->roomNumber;
|
|
|
|
*a4 = v44;
|
|
|
|
v95 = GetFloor(*v42, item->pos.yPos, item->pos.zPos, a4);
|
|
|
|
GetHeight(v95, *v42, item->pos.yPos, item->pos.zPos);
|
|
|
|
TestTriggers(trigger_index, 1, 0);
|
|
|
|
}
|
|
|
|
goto LABEL_255;
|
|
|
|
default:
|
|
|
|
goto LABEL_255;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
LABEL_255:
|
|
|
|
CreatureJoint(item, 0, joint0);
|
|
|
|
CreatureJoint(item, 1, joint1);
|
|
|
|
CreatureJoint(item, 2, joint2);
|
|
|
|
if (!(creature->bitfield & 8))
|
|
|
|
goto LABEL_269;
|
|
|
|
v97 = creature->enemy;
|
|
|
|
if (!v97)
|
|
|
|
goto LABEL_269;
|
|
|
|
v98 = v97->flags;
|
|
|
|
if (v98 != 4)
|
|
|
|
{
|
|
|
|
if (v98 & 0x10)
|
|
|
|
{
|
|
|
|
v99 = item->_bf15ea;
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
item->requriedAnimState = 38;
|
|
|
|
item->triggerFlags = 300;
|
|
|
|
BYTE1(v99) &= 0xCBu;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (v98 & 0x20)
|
|
|
|
{
|
|
|
|
v100 = item->_bf15ea;
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
item->requriedAnimState = 36;
|
|
|
|
BYTE1(v100) = BYTE1(v100) & 0xC9 | 8;
|
|
|
|
item->_bf15ea = v100;
|
|
|
|
goto LABEL_268;
|
|
|
|
}
|
|
|
|
LOWORD(v96) = v97->roomNumber;
|
|
|
|
*a4 = v96;
|
|
|
|
v101 = GetFloor(creature->enemy->pos.xPos, creature->enemy->pos.yPos, creature->enemy->pos.zPos, a4);
|
|
|
|
GetHeight(v101, creature->enemy->pos.xPos, creature->enemy->pos.yPos, creature->enemy->pos.zPos);
|
|
|
|
TestTriggers(trigger_index, 1, 0);
|
|
|
|
item->requriedAnimState = 5;
|
|
|
|
if (creature->enemy->flags & 2)
|
|
|
|
item->item_flags[3] = item->pad2[6] - 1;
|
|
|
|
if (!(creature->enemy->flags & 8))
|
|
|
|
goto LABEL_268;
|
|
|
|
v99 = item->_bf15ea;
|
|
|
|
item->requriedAnimState = 1;
|
|
|
|
item->triggerFlags = 300;
|
|
|
|
}
|
|
|
|
BYTE1(v99) |= 0xAu;
|
|
|
|
item->_bf15ea = v99;
|
|
|
|
goto LABEL_268;
|
|
|
|
}
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
item->requriedAnimState = 37;
|
|
|
|
LABEL_268:
|
|
|
|
++item->item_flags[3];
|
|
|
|
creature->bitfield &= 0xFFF7u;
|
|
|
|
creature->enemy = 0;
|
|
|
|
LABEL_269:
|
|
|
|
v102 = item->currentAnimState;
|
|
|
|
if ((v102 >= 20 || v102 == 6 || v102 == 8) && v102 != 30)
|
|
|
|
{
|
|
|
|
CreatureAnimation(itemNum, angle, 0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (CreatureVault(itemNum, angle, 2, 256) + 4)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
v113 = animIndex;
|
|
|
|
creature->maximumTurn = 0;
|
|
|
|
item->animNumber = v113 + 38;
|
|
|
|
v114 = Anims[(v113 + 38)].frameBase;
|
|
|
|
item->currentAnimState = 23;
|
|
|
|
item->frameNumber = v114;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
v111 = animIndex;
|
|
|
|
creature->maximumTurn = 0;
|
|
|
|
v111 += 39;
|
|
|
|
item->animNumber = v111;
|
|
|
|
v112 = Anims[v111].frameBase;
|
|
|
|
item->currentAnimState = 24;
|
|
|
|
item->frameNumber = v112;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
v109 = animIndex;
|
|
|
|
creature->maximumTurn = 0;
|
|
|
|
item->animNumber = v109 + 40;
|
|
|
|
v110 = Anims[(v109 + 40)].frameBase;
|
|
|
|
item->currentAnimState = 25;
|
|
|
|
item->frameNumber = v110;
|
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
v103 = animIndex;
|
|
|
|
creature->maximumTurn = 0;
|
|
|
|
item->animNumber = v103 + 35;
|
|
|
|
v104 = Anims[(v103 + 35)].frameBase;
|
|
|
|
item->currentAnimState = 20;
|
|
|
|
item->frameNumber = v104;
|
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
v105 = animIndex;
|
|
|
|
creature->maximumTurn = 0;
|
|
|
|
v105 += 36;
|
|
|
|
item->animNumber = v105;
|
|
|
|
v106 = Anims[v105].frameBase;
|
|
|
|
item->currentAnimState = 21;
|
|
|
|
item->frameNumber = v106;
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
v107 = animIndex;
|
|
|
|
creature->maximumTurn = 0;
|
|
|
|
item->animNumber = v107 + 37;
|
|
|
|
v108 = Anims[(v107 + 37)].frameBase;
|
|
|
|
item->currentAnimState = 22;
|
|
|
|
item->frameNumber = v108;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}*/
|