2021-04-29 15:19:28 +02:00
|
|
|
#include "framework.h"
|
|
|
|
#include "tr4_hammerhead.h"
|
2021-09-19 23:41:26 +03:00
|
|
|
#include "control/box.h"
|
2021-09-25 16:00:30 +03:00
|
|
|
#include "effects/effects.h"
|
2021-04-29 15:19:28 +02:00
|
|
|
#include "items.h"
|
|
|
|
#include "setup.h"
|
|
|
|
#include "level.h"
|
|
|
|
#include "lara.h"
|
2021-09-16 05:06:03 +03:00
|
|
|
#include "animation.h"
|
|
|
|
#include "itemdata/creature_info.h"
|
2021-09-25 11:27:47 +02:00
|
|
|
|
2021-04-29 15:19:28 +02:00
|
|
|
#define STATE_HAMMERHEAD_STOP 0
|
|
|
|
#define STATE_HAMMERHEAD_SWIM_SLOW 1
|
|
|
|
#define STATE_HAMMERHEAD_SWIM_FAST 2
|
|
|
|
#define STATE_HAMMERHEAD_ATTACK 3
|
|
|
|
#define STATE_HAMMERHEAD_DEATH 5
|
2021-08-16 05:44:55 +02:00
|
|
|
#define STATE_HAMMERHEAD_KILL 6
|
2021-04-29 15:19:28 +02:00
|
|
|
|
|
|
|
BITE_INFO HammerheadAttack = { 0, 0, 0, 12 };
|
|
|
|
|
|
|
|
void InitialiseHammerhead(short itemNumber)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &g_Level.Items[itemNumber];
|
|
|
|
|
|
|
|
ClearItem(itemNumber);
|
|
|
|
|
|
|
|
item->animNumber = Objects[item->objectNumber].animIndex + 8;
|
|
|
|
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
|
|
|
item->goalAnimState = STATE_HAMMERHEAD_STOP;
|
|
|
|
item->currentAnimState = STATE_HAMMERHEAD_STOP;
|
|
|
|
}
|
|
|
|
|
|
|
|
void HammerheadControl(short itemNumber)
|
|
|
|
{
|
|
|
|
if (CreatureActive(itemNumber))
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &g_Level.Items[itemNumber];
|
|
|
|
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
|
|
|
|
|
|
|
|
if (item->hitPoints > 0)
|
|
|
|
{
|
|
|
|
if (item->aiBits)
|
|
|
|
GetAITarget(creature);
|
|
|
|
else if (creature->hurtByLara)
|
|
|
|
creature->enemy = LaraItem;
|
|
|
|
|
|
|
|
AI_INFO info;
|
|
|
|
CreatureAIInfo(item, &info);
|
|
|
|
|
|
|
|
if (creature->enemy != LaraItem)
|
|
|
|
{
|
|
|
|
phd_atan(LaraItem->pos.zPos - item->pos.zPos, LaraItem->pos.xPos - item->pos.xPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
GetCreatureMood(item, &info, VIOLENT);
|
|
|
|
CreatureMood(item, &info, VIOLENT);
|
|
|
|
|
|
|
|
short angle = CreatureTurn(item, creature->maximumTurn);
|
|
|
|
|
|
|
|
switch (item->currentAnimState)
|
|
|
|
{
|
|
|
|
case STATE_HAMMERHEAD_STOP:
|
2021-08-16 05:44:55 +02:00
|
|
|
item->goalAnimState = STATE_HAMMERHEAD_SWIM_SLOW;
|
2021-04-29 15:19:28 +02:00
|
|
|
creature->flags = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case STATE_HAMMERHEAD_SWIM_SLOW:
|
|
|
|
creature->maximumTurn = ANGLE(7);
|
|
|
|
if (info.distance <= SQUARE(1024))
|
|
|
|
{
|
|
|
|
if (info.distance < SQUARE(682))
|
|
|
|
{
|
|
|
|
item->goalAnimState = STATE_HAMMERHEAD_ATTACK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->goalAnimState = STATE_HAMMERHEAD_SWIM_FAST;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case STATE_HAMMERHEAD_SWIM_FAST:
|
|
|
|
if (info.distance < SQUARE(1024))
|
|
|
|
{
|
|
|
|
item->goalAnimState = STATE_HAMMERHEAD_SWIM_SLOW;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case STATE_HAMMERHEAD_ATTACK:
|
|
|
|
if (!creature->flags)
|
|
|
|
{
|
|
|
|
if (item->touchBits & 0x3400)
|
|
|
|
{
|
|
|
|
LaraItem->hitPoints -= 120;
|
|
|
|
LaraItem->hitStatus = true;
|
|
|
|
CreatureEffect(item, &HammerheadAttack, DoBloodSplat);
|
|
|
|
creature->flags = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
CreatureTilt(item, 0);
|
|
|
|
CreatureJoint(item, 0, -2 * angle);
|
|
|
|
CreatureJoint(item, 1, -2 * angle);
|
|
|
|
CreatureJoint(item, 2, -2 * angle);
|
|
|
|
CreatureJoint(item, 3, 2 * angle);
|
|
|
|
|
2021-08-16 05:44:55 +02:00
|
|
|
// NOTE: in TR2 shark there was a call to CreatureKill with special kill anim
|
|
|
|
// Hammerhead seems to not have it in original code but this check is still there as a leftover
|
|
|
|
if (item->currentAnimState == STATE_HAMMERHEAD_KILL)
|
2021-04-29 15:19:28 +02:00
|
|
|
{
|
|
|
|
AnimateItem(item);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CreatureAnimation(itemNumber, angle, 0);
|
|
|
|
CreatureUnderwater(item, 341);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->hitPoints = 0;
|
|
|
|
if (item->currentAnimState != STATE_HAMMERHEAD_DEATH)
|
|
|
|
{
|
|
|
|
item->animNumber = Objects[item->objectNumber].animIndex + 4;
|
|
|
|
item->currentAnimState = STATE_HAMMERHEAD_DEATH;
|
|
|
|
item->frameNumber = g_Level.Anims[item->frameNumber].frameBase;
|
|
|
|
}
|
|
|
|
|
|
|
|
CreatureFloat(itemNumber);
|
|
|
|
}
|
|
|
|
}
|
2021-08-31 17:37:15 +02:00
|
|
|
}
|