mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-05-08 03:28:03 +03:00
Refactored Bat
- Latest bat code from TR4Main. - Fixed Semi-Always Not Attacking Lara (Collision). - Fixed Escape Mood (Bat can fly without attacking lara and can be killed easy like this !)
This commit is contained in:
parent
2c6a1a7480
commit
85e6941568
4 changed files with 178 additions and 149 deletions
|
@ -72,6 +72,22 @@ typedef struct BITE_INFO
|
||||||
int y;
|
int y;
|
||||||
int z;
|
int z;
|
||||||
int meshNum;
|
int meshNum;
|
||||||
|
|
||||||
|
BITE_INFO()
|
||||||
|
{
|
||||||
|
this->x = 0;
|
||||||
|
this->y = 0;
|
||||||
|
this->z = 0;
|
||||||
|
this->meshNum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BITE_INFO(int xpos, int ypos, int zpos, int meshNumber)
|
||||||
|
{
|
||||||
|
this->x = xpos;
|
||||||
|
this->y = ypos;
|
||||||
|
this->z = zpos;
|
||||||
|
this->meshNum = meshNumber;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct LOT_INFO
|
typedef struct LOT_INFO
|
||||||
|
|
|
@ -7,15 +7,15 @@
|
||||||
|
|
||||||
BITE_INFO EnemyBites[9] =
|
BITE_INFO EnemyBites[9] =
|
||||||
{
|
{
|
||||||
{ 0x14, 0xFFFFFFA1, 0xF0, 0xD },
|
{ 20, -95, 240, 13 },
|
||||||
{ 0x30, 0, 0xB4, 0xFFFFFFF5 },
|
{ 48, 0, 180, -11 },
|
||||||
{ 0xFFFFFFD0, 0, 0xB4, 0xE },
|
{ -48, 0, 180, 14 },
|
||||||
{ 0xFFFFFFC9, 5, 0xE1, 0xE },
|
{ -48, 5, 225, 14 },
|
||||||
{ 0xF, 0xFFFFFFC4, 0xC3, 0xD },
|
{ 15, -60, 195, 13 },
|
||||||
{ 0xFFFFFFE2, 0xFFFFFFBF, 0xFA, 0x12 },
|
{ -30, -65, 250, 18 },
|
||||||
{ 0, 0xFFFFFF92, 0x1E0, 0xD },
|
{ 0, -110, 480, 13 },
|
||||||
{ 0xFFFFFFEC, 0xFFFFFFB0, 0xBE, 0xFFFFFFF6 },
|
{ -20, -80, 190, -10 },
|
||||||
{ 0xA, 0xFFFFFFC4, 0xC8, 0xD }
|
{ 10, -60, 200, 13 }
|
||||||
};
|
};
|
||||||
|
|
||||||
int LightningCount;
|
int LightningCount;
|
||||||
|
|
|
@ -1,25 +1,56 @@
|
||||||
#include "framework.h"
|
#include "framework.h"
|
||||||
#include "tr4_bat.h"
|
#include "tr4_bat.h"
|
||||||
#include "box.h"
|
#include "box.h"
|
||||||
#include "effect.h"
|
#include "control.h"
|
||||||
#include "items.h"
|
#include "effect2.h"
|
||||||
#include "setup.h"
|
#include "misc.h"
|
||||||
#include "lot.h"
|
|
||||||
#include "level.h"
|
|
||||||
#include "lara.h"
|
#include "lara.h"
|
||||||
|
#include "lot.h"
|
||||||
|
#include "setup.h"
|
||||||
|
#include "trmath.h"
|
||||||
|
|
||||||
BITE_INFO batBite = { 0, 16, 45, 4 };
|
|
||||||
|
enum BAT_STATE
|
||||||
|
{
|
||||||
|
BAT_EMPTY,
|
||||||
|
BAT_START,
|
||||||
|
BAT_FLY,
|
||||||
|
BAT_ATK,
|
||||||
|
BAT_FALLING,
|
||||||
|
BAT_DEATH,
|
||||||
|
BAT_IDLE
|
||||||
|
};
|
||||||
|
|
||||||
|
enum BAT_ANIM
|
||||||
|
{
|
||||||
|
ANIM_BAT_START,
|
||||||
|
ANIM_BAT_FLY,
|
||||||
|
ANIM_BAT_ATK,
|
||||||
|
ANIM_BAT_FALLING,
|
||||||
|
ANIM_BAT_HIT_FLOOR,
|
||||||
|
ANIM_BAT_IDLE
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BAT_ANGLE ANGLE(20.0f)
|
||||||
|
constexpr auto BAT_ATTACK_RANGE = SQUARE(CLICK(1));
|
||||||
|
constexpr auto BAT_TARGETING_RANGE = SQUARE(SECTOR(5));
|
||||||
|
constexpr auto BAT_TARGET_YPOS = SQUARE(CLICK(2) / 18);
|
||||||
|
constexpr auto BAT_DAMAGE = 2;
|
||||||
|
static BITE_INFO batBite(0, 16, 45, 4);
|
||||||
|
|
||||||
|
static bool isBatCollideTarget(ITEM_INFO* item)
|
||||||
|
{
|
||||||
|
return item->touchBits >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
void InitialiseBat(short itemNumber)
|
void InitialiseBat(short itemNumber)
|
||||||
{
|
{
|
||||||
ITEM_INFO* item = &Items[itemNumber];
|
ITEM_INFO* item = &Items[itemNumber];
|
||||||
|
InitialiseCreature(itemNumber);
|
||||||
ClearItem(itemNumber);
|
item->animNumber = Objects[item->objectNumber].animIndex + ANIM_BAT_IDLE;
|
||||||
|
|
||||||
item->animNumber = Objects[ID_BAT].animIndex + 5;
|
|
||||||
item->frameNumber = Anims[item->animNumber].frameBase;
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
||||||
item->goalAnimState = 6;
|
item->goalAnimState = BAT_IDLE;
|
||||||
item->currentAnimState = 6;
|
item->currentAnimState = BAT_IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BatControl(short itemNumber)
|
void BatControl(short itemNumber)
|
||||||
|
@ -27,137 +58,119 @@ void BatControl(short itemNumber)
|
||||||
if (!CreatureActive(itemNumber))
|
if (!CreatureActive(itemNumber))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ITEM_INFO* item = &Items[itemNumber];
|
ITEM_INFO* item, *target;
|
||||||
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
|
CREATURE_INFO* bat, *slots;
|
||||||
short angle = 0;
|
AI_INFO info;
|
||||||
short head = 0;
|
int distance, bestdistance;
|
||||||
short neck = 0;
|
short angle;
|
||||||
short tilt = 0;
|
|
||||||
short joint0 = 0;
|
|
||||||
short joint1 = 0;
|
|
||||||
short joint2 = 0;
|
|
||||||
short joint3 = 0;
|
|
||||||
|
|
||||||
if (item->hitPoints > 0)
|
item = &Items[itemNumber];
|
||||||
{
|
bat = GetCreatureInfo(item);
|
||||||
int dx = LaraItem->pos.xPos - item->pos.xPos;
|
angle = 0;
|
||||||
int dz = LaraItem->pos.zPos - item->pos.zPos;
|
|
||||||
int laraDistance = dx * dx + dz * dz;
|
|
||||||
|
|
||||||
if (item->aiBits)
|
if (item->hitPoints <= 0)
|
||||||
{
|
{
|
||||||
GetAITarget(creature);
|
if (item->pos.yPos >= item->floor)
|
||||||
}
|
{
|
||||||
else
|
item->goalAnimState = BAT_DEATH;
|
||||||
{
|
item->pos.yPos = item->floor;
|
||||||
creature->enemy = LaraItem;
|
item->gravityStatus = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item->animNumber = Objects[item->objectNumber].animIndex + ANIM_BAT_FALLING;
|
||||||
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
||||||
|
item->goalAnimState = BAT_FALLING;
|
||||||
|
item->currentAnimState = BAT_FALLING;
|
||||||
|
item->speed = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (item->aiBits & ALL_AIOBJ)
|
||||||
|
{
|
||||||
|
GetAITarget(bat);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// check if voncroy are in range !
|
||||||
|
// take in account that the bat will always target voncroy if he exist and triggered !
|
||||||
|
// the bat will ignore lara completly !
|
||||||
|
bestdistance = MAXINT;
|
||||||
|
bat->enemy = LaraItem;
|
||||||
|
|
||||||
CREATURE_INFO* baddie = &BaddieSlots[0];
|
slots = &BaddieSlots[0];
|
||||||
CREATURE_INFO* found = &BaddieSlots[0];
|
for (int i = 0; i < NUM_SLOTS; i++, slots++)
|
||||||
int minDistance = 0x7FFFFFFF;
|
{
|
||||||
|
target = &Items[slots->itemNum];
|
||||||
|
if (target->objectNumber == ID_VON_CROY && target->status != ITEM_INVISIBLE)
|
||||||
|
{
|
||||||
|
int x, z;
|
||||||
|
x = target->pos.xPos - item->pos.xPos;
|
||||||
|
z = target->pos.zPos - item->pos.zPos;
|
||||||
|
distance = SQUARE(x) + SQUARE(z);
|
||||||
|
if (distance < bestdistance)
|
||||||
|
{
|
||||||
|
bat->enemy = target;
|
||||||
|
bestdistance = distance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < NUM_SLOTS; i++, baddie++)
|
CreatureAIInfo(item, &info);
|
||||||
{
|
GetCreatureMood(item, &info, TIMID);
|
||||||
if (baddie->itemNum == NO_ITEM || baddie->itemNum == itemNumber)
|
// note: this random dont exist in TR4 !
|
||||||
continue;
|
// this part set the bat in escape mood, but for too long !
|
||||||
|
// lara can escape and shot it easy ....
|
||||||
|
if (bat->flags && !(GetRandomControl() & 16))
|
||||||
|
bat->mood = ESCAPE_MOOD;
|
||||||
|
else if (bat->flags && GetRandomControl() & 24) // fine maybe ? the bat react more with "16" but this reaction is too fast !
|
||||||
|
bat->mood = STALK_MOOD;
|
||||||
|
CreatureMood(item, &info, TIMID);
|
||||||
|
angle = CreatureTurn(item, BAT_ANGLE);
|
||||||
|
|
||||||
ITEM_INFO* target = &Items[baddie->itemNum];
|
switch (item->currentAnimState)
|
||||||
if (target->objectNumber != ID_WILD_BOAR)
|
{
|
||||||
{
|
case BAT_IDLE:
|
||||||
int dx2 = target->pos.xPos - item->pos.xPos;
|
if (info.distance < BAT_TARGETING_RANGE || item->hitStatus || bat->hurtByLara)
|
||||||
int dz2 = target->pos.zPos - item->pos.zPos;
|
item->goalAnimState = BAT_START;
|
||||||
int distance = dx2 * dx2 + dz2 * dz2;
|
break;
|
||||||
|
case BAT_FLY:
|
||||||
|
if (info.distance < BAT_ATTACK_RANGE || !(GetRandomControl() & 0x3F))
|
||||||
|
bat->flags = 0;
|
||||||
|
|
||||||
if (distance < minDistance)
|
if (!bat->flags)
|
||||||
{
|
{
|
||||||
creature->enemy = target;
|
if (isBatCollideTarget(item) || bat->enemy != LaraItem)
|
||||||
minDistance = distance;
|
{
|
||||||
}
|
if (info.distance < BAT_ATTACK_RANGE
|
||||||
}
|
&& info.ahead && abs(item->pos.yPos - bat->enemy->pos.yPos) < BAT_TARGET_YPOS)
|
||||||
}
|
{
|
||||||
}
|
item->goalAnimState = BAT_ATK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BAT_ATK:
|
||||||
|
if (!bat->flags && (isBatCollideTarget(item) || bat->enemy != LaraItem) && info.distance < BAT_ATTACK_RANGE && info.ahead && abs(item->pos.yPos - bat->enemy->pos.yPos) < BAT_TARGET_YPOS)
|
||||||
|
{
|
||||||
|
CreatureEffect(item, &batBite, DoBloodSplat);
|
||||||
|
if (bat->enemy == LaraItem)
|
||||||
|
{
|
||||||
|
LaraItem->hitPoints -= BAT_DAMAGE;
|
||||||
|
LaraItem->hitStatus = TRUE;
|
||||||
|
}
|
||||||
|
bat->flags = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item->goalAnimState = BAT_FLY;
|
||||||
|
bat->mood = BORED_MOOD;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AI_INFO info;
|
CreatureAnimation(itemNumber, angle, 0);
|
||||||
CreatureAIInfo(item, &info);
|
|
||||||
|
|
||||||
GetCreatureMood(item, &info, TIMID);
|
|
||||||
//if (item->flags)
|
|
||||||
// creature->mood = ESCAPE_MOOD;
|
|
||||||
CreatureMood(item, &info, TIMID);
|
|
||||||
|
|
||||||
angle = CreatureTurn(item, ANGLE(20));
|
|
||||||
|
|
||||||
switch (item->currentAnimState)
|
|
||||||
{
|
|
||||||
case 2:
|
|
||||||
if (info.distance < SQUARE(256) || !(GetRandomControl() & 0x3F))
|
|
||||||
{
|
|
||||||
creature->flags = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!creature->flags)
|
|
||||||
{
|
|
||||||
if (item->touchBits || creature->enemy != LaraItem && info.distance < SQUARE(256) && info.ahead && abs(item->pos.yPos - creature->enemy->pos.yPos) < 896)
|
|
||||||
{
|
|
||||||
item->goalAnimState = 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
if (!creature->flags && (item->touchBits || creature->enemy != LaraItem && info.distance < SQUARE(256) && info.ahead && abs(item->pos.yPos - creature->enemy->pos.yPos) < 896))
|
|
||||||
{
|
|
||||||
CreatureEffect(item, &batBite, DoBloodSplat);
|
|
||||||
if (creature->enemy == LaraItem)
|
|
||||||
{
|
|
||||||
LaraItem->hitPoints -= 2;
|
|
||||||
LaraItem->hitStatus = true;
|
|
||||||
}
|
|
||||||
creature->flags = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
item->goalAnimState = 2;
|
|
||||||
creature->mood = BORED_MOOD;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 6:
|
|
||||||
if (info.distance < SQUARE(5120) ||
|
|
||||||
item->hitStatus ||
|
|
||||||
creature->hurtByLara)
|
|
||||||
{
|
|
||||||
item->goalAnimState = 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (item->currentAnimState == 3)
|
|
||||||
{
|
|
||||||
item->animNumber = Objects[ID_BAT].animIndex + 1;
|
|
||||||
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
||||||
item->goalAnimState = 2;
|
|
||||||
item->currentAnimState = 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (item->pos.yPos >= item->floor)
|
|
||||||
{
|
|
||||||
item->goalAnimState = 5;
|
|
||||||
item->pos.yPos = item->floor;
|
|
||||||
item->gravityStatus = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
item->gravityStatus = true;
|
|
||||||
item->animNumber = Objects[ID_BAT].animIndex + 3;
|
|
||||||
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
||||||
item->goalAnimState = 4;
|
|
||||||
item->currentAnimState = 4;
|
|
||||||
item->speed = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CreatureAnimation(itemNumber, angle, 0);
|
|
||||||
}
|
}
|
|
@ -11,8 +11,8 @@
|
||||||
#include "level.h"
|
#include "level.h"
|
||||||
#include "lara.h"
|
#include "lara.h"
|
||||||
|
|
||||||
BITE_INFO LionBite1 = { 0xFFFFFFFE, 0xFFFFFFF6, 0xFA, 0x15 };
|
BITE_INFO LionBite1 = { -2, -10, 250, 21 };
|
||||||
BITE_INFO LionBite2 = { 0xFFFFFFFE, 0xFFFFFFF6, 0x84, 0x15 };
|
BITE_INFO LionBite2 = { -2, -10, 132, 21 };
|
||||||
|
|
||||||
void InitialiseLion(short itemNum)
|
void InitialiseLion(short itemNum)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue