mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-04-30 08:47:58 +03:00
272 lines
5.3 KiB
C++
272 lines
5.3 KiB
C++
#include "framework.h"
|
|
#include "tr1_bear.h"
|
|
#include "box.h"
|
|
#include "effects\effects.h"
|
|
#include "setup.h"
|
|
#include "level.h"
|
|
#include "control.h"
|
|
#include "lara.h"
|
|
#include "creature_info.h"
|
|
#include "control.h"
|
|
|
|
BITE_INFO bearBite = { 0, 96, 335, 14 };
|
|
|
|
enum bearStates{
|
|
BEAR_STROLL,
|
|
BEAR_STOP,
|
|
BEAR_WALK,
|
|
BEAR_RUN,
|
|
BEAR_REAR,
|
|
BEAR_ROAR,
|
|
BEAR_ATTACK1,
|
|
BEAR_ATTACK2,
|
|
BEAR_EAT,
|
|
BEAR_DEATH
|
|
};
|
|
#define TOUCH 0x2406C
|
|
|
|
|
|
#define ROAR_CHANCE 0x50
|
|
#define REAR_CHANCE 0x300
|
|
#define DROP_CHANCE 0x600
|
|
|
|
#define REAR_RANGE SQUARE(WALL_SIZE*2)
|
|
#define ATTACK_RANGE SQUARE(WALL_SIZE)
|
|
#define PAT_RANGE SQUARE(600)
|
|
|
|
#define RUN_TURN ANGLE(5)
|
|
#define WALK_TURN ANGLE(2)
|
|
|
|
#define EAT_RANGE SQUARE(WALL_SIZE*3/4)
|
|
|
|
|
|
#define CHARGE_DAMAGE 3
|
|
#define SLAM_DAMAGE 200
|
|
#define ATTACK_DAMAGE 200
|
|
#define PAT_DAMAGE 400
|
|
|
|
void BearControl(short itemNum)
|
|
{
|
|
if (!CreatureActive(itemNum))
|
|
return;
|
|
|
|
ITEM_INFO* item = &g_Level.Items[itemNum];
|
|
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
|
|
|
|
short head = 0;
|
|
short angle;
|
|
|
|
if (item->hitPoints <= 0)
|
|
{
|
|
angle = CreatureTurn(item, ANGLE(1));
|
|
|
|
switch (item->currentAnimState)
|
|
{
|
|
case BEAR_WALK:
|
|
{
|
|
item->goalAnimState = BEAR_REAR;
|
|
break;
|
|
}
|
|
case BEAR_RUN:
|
|
case BEAR_STROLL:
|
|
{
|
|
item->goalAnimState = BEAR_STOP;
|
|
break;
|
|
}
|
|
case BEAR_REAR:
|
|
{
|
|
creature->flags = 1;
|
|
item->goalAnimState = BEAR_DEATH;
|
|
break;
|
|
}
|
|
case BEAR_STOP:
|
|
{
|
|
creature->flags = 0;
|
|
item->goalAnimState = BEAR_DEATH;
|
|
break;
|
|
}
|
|
case BEAR_DEATH:
|
|
{
|
|
if (creature->flags && (item->touchBits & TOUCH))
|
|
{
|
|
LaraItem->hitPoints -= SLAM_DAMAGE;
|
|
LaraItem->hitStatus = 1;
|
|
creature->flags = 0;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
AI_INFO info;
|
|
CreatureAIInfo(item, &info);
|
|
|
|
if (info.ahead)
|
|
head = info.angle;
|
|
|
|
GetCreatureMood(item, &info, VIOLENT);
|
|
CreatureMood(item, &info, VIOLENT);
|
|
|
|
angle = CreatureTurn(item, creature->maximumTurn);
|
|
|
|
if (item->hitStatus)
|
|
creature->flags = 1;
|
|
|
|
const bool Laradead = (LaraItem->hitPoints <= 0);
|
|
|
|
switch (item->currentAnimState)
|
|
{
|
|
case BEAR_STOP:
|
|
if (Laradead)
|
|
{
|
|
if (info.bite && info.distance < EAT_RANGE)
|
|
{
|
|
item->goalAnimState = BEAR_EAT;
|
|
}
|
|
else
|
|
{
|
|
item->goalAnimState = BEAR_STROLL;
|
|
}
|
|
}
|
|
else if (item->requiredAnimState)
|
|
{
|
|
item->goalAnimState = item->requiredAnimState;
|
|
}
|
|
else if (creature->mood == BORED_MOOD)
|
|
{
|
|
item->goalAnimState = BEAR_STROLL;
|
|
}
|
|
else
|
|
{
|
|
item->goalAnimState = BEAR_RUN;
|
|
}
|
|
break;
|
|
|
|
case BEAR_STROLL:
|
|
creature->maximumTurn = WALK_TURN;
|
|
|
|
if (Laradead && (item->touchBits & TOUCH) && info.ahead)
|
|
{
|
|
item->goalAnimState = BEAR_STOP;
|
|
}
|
|
else if (creature->mood != BORED_MOOD)
|
|
{
|
|
item->goalAnimState = BEAR_STOP;
|
|
if (creature->mood == ESCAPE_MOOD)
|
|
{
|
|
item->requiredAnimState = BEAR_STROLL;
|
|
}
|
|
}
|
|
else if (GetRandomControl() < ROAR_CHANCE)
|
|
{
|
|
item->requiredAnimState = BEAR_ROAR;
|
|
item->goalAnimState = BEAR_STOP;
|
|
}
|
|
break;
|
|
|
|
case BEAR_RUN:
|
|
creature->maximumTurn = RUN_TURN;
|
|
|
|
if (item->touchBits & TOUCH)
|
|
{
|
|
LaraItem->hitPoints -= CHARGE_DAMAGE;
|
|
LaraItem->hitStatus = true;
|
|
}
|
|
|
|
if (creature->mood == BORED_MOOD || Laradead)
|
|
{
|
|
item->goalAnimState = BEAR_STOP;
|
|
}
|
|
else if (info.ahead && !item->requiredAnimState)
|
|
{
|
|
if (!creature->flags && info.distance < REAR_RANGE && GetRandomControl() < REAR_CHANCE)
|
|
{
|
|
item->requiredAnimState = BEAR_REAR;
|
|
item->goalAnimState = BEAR_STOP;
|
|
}
|
|
else if (info.distance < ATTACK_RANGE)
|
|
{
|
|
item->goalAnimState = BEAR_ATTACK1;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case BEAR_REAR:
|
|
if (creature->flags)
|
|
{
|
|
item->requiredAnimState = BEAR_STROLL;
|
|
item->goalAnimState = BEAR_STOP;
|
|
}
|
|
else if (item->requiredAnimState)
|
|
{
|
|
item->goalAnimState = item->requiredAnimState;
|
|
}
|
|
else if (creature->mood == BORED_MOOD || creature->mood == ESCAPE_MOOD)
|
|
{
|
|
item->goalAnimState = BEAR_STOP;
|
|
}
|
|
else if (info.bite && info.distance < PAT_RANGE)
|
|
{
|
|
item->goalAnimState = BEAR_ATTACK2;
|
|
}
|
|
else
|
|
{
|
|
item->goalAnimState = BEAR_WALK;
|
|
}
|
|
break;
|
|
|
|
case BEAR_WALK:
|
|
if (creature->flags)
|
|
{
|
|
item->requiredAnimState = BEAR_STROLL;
|
|
item->goalAnimState = BEAR_REAR;
|
|
}
|
|
else if (info.ahead && (item->touchBits & TOUCH))
|
|
{
|
|
item->goalAnimState = BEAR_REAR;
|
|
}
|
|
else if (creature->mood == ESCAPE_MOOD)
|
|
{
|
|
item->goalAnimState = BEAR_REAR;
|
|
item->requiredAnimState = BEAR_STROLL;
|
|
}
|
|
else if (creature->mood == BORED_MOOD || GetRandomControl() < ROAR_CHANCE)
|
|
{
|
|
item->requiredAnimState = BEAR_ROAR;
|
|
item->goalAnimState = BEAR_REAR;
|
|
}
|
|
else if (info.distance > REAR_RANGE || GetRandomControl() < DROP_CHANCE)
|
|
{
|
|
item->requiredAnimState = BEAR_STOP;
|
|
item->goalAnimState = BEAR_REAR;
|
|
}
|
|
break;
|
|
|
|
case BEAR_ATTACK2:
|
|
if (!item->requiredAnimState && (item->touchBits & TOUCH))
|
|
{
|
|
LaraItem->hitPoints -= PAT_DAMAGE;
|
|
LaraItem->hitStatus = true;
|
|
item->requiredAnimState = BEAR_REAR;
|
|
}
|
|
|
|
break;
|
|
|
|
case BEAR_ATTACK1:
|
|
if (!item->requiredAnimState && (item->touchBits & TOUCH))
|
|
{
|
|
CreatureEffect(item, &bearBite, DoBloodSplat);
|
|
LaraItem->hitPoints -= ATTACK_DAMAGE;
|
|
LaraItem->hitStatus = true;
|
|
item->requiredAnimState = BEAR_STOP;
|
|
}
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
CreatureJoint(item, 0, head);
|
|
CreatureAnimation(itemNum, angle, 0);
|
|
}
|