Fixed statics not disappearing after shatter; Some refactoring for ID_MUMMY and ID_SKELETON; Fixed plinth pickup;

This commit is contained in:
MontyTRC89 2021-05-31 07:18:02 +02:00
parent 8a414c2c84
commit c6fb38d67f
6 changed files with 193 additions and 173 deletions

View file

@ -769,15 +769,19 @@ int TestLaraPosition(OBJECT_COLLISION_BOUNDS* bounds, ITEM_INFO* item, ITEM_INFO
return false;
if (zRotRel < bounds->rotZ1)
return false;
if (zRotRel > bounds->rotX2)
if (zRotRel > bounds->rotZ2)
return false;
Vector3 pos = Vector3(l->pos.xPos - item->pos.xPos, l->pos.yPos - item->pos.yPos, l->pos.zPos - item->pos.zPos);
// HACK: it seems that a minus sign is required here. I don't know why, but it just works (tm) but we must
x = l->pos.xPos - item->pos.xPos;
y = l->pos.yPos - item->pos.yPos;
z = l->pos.zPos - item->pos.zPos;
Vector3 pos = Vector3(x, y, z);
// HACK (REMOVED FOR NOW): it seems that a minus sign is required here. I don't know why, but it just works (tm) but we must
// do more tests
Matrix matrix = Matrix::CreateFromYawPitchRoll(
TO_RAD(-(item->pos.yRot)),
TO_RAD(item->pos.yRot),
TO_RAD(item->pos.xRot),
TO_RAD(item->pos.zRot)
);
@ -788,8 +792,7 @@ int TestLaraPosition(OBJECT_COLLISION_BOUNDS* bounds, ITEM_INFO* item, ITEM_INFO
ry = pos.y;
rz = pos.z;
if (rx < bounds->boundingBox.X1 || rx > bounds->boundingBox.X2
if (rx < bounds->boundingBox.X1 || rx > bounds->boundingBox.X2
|| ry < bounds->boundingBox.Y1 || ry > bounds->boundingBox.Y2
|| rz < bounds->boundingBox.Z1 || rz > bounds->boundingBox.Z2)
return false;

View file

@ -792,7 +792,7 @@ void PickupCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
PlinthPickUpBounds.boundingBox.X1 = plinth->X1;
PlinthPickUpBounds.boundingBox.X2 = plinth->X2;
PlinthPickUpBounds.boundingBox.Y2 = l->pos.yPos - item->pos.yPos + 100;
PlinthPickUpBounds.boundingBox.Z1 = plinth->Z2 + 320;
PlinthPickUpBounds.boundingBox.Z2 = plinth->Z2 + 320;
PlinthPickUpPosition.z = -200 - plinth->Z2;
if (TestLaraPosition(&PlinthPickUpBounds, item, l) && !Lara.isDucked)

View file

@ -98,13 +98,22 @@ void MummyControl(short itemNumber)
{
if (info.distance < SQUARE(3072))
{
if (item->currentAnimState != ANIMATION_MUMMY_STAND_TO_WALK_ARMS_UP && item->currentAnimState != ANIMATION_MUMMY_WALK_ARMS_UP_TO_WALK_LEFT && item->currentAnimState != ANIMATION_MUMMY_STAND_TO_WALK)
if (item->currentAnimState != ANIMATION_MUMMY_STAND_TO_WALK_ARMS_UP
&& item->currentAnimState != ANIMATION_MUMMY_WALK_ARMS_UP_TO_WALK_LEFT
&& item->currentAnimState != ANIMATION_MUMMY_STAND_TO_WALK)
{
if (GetRandomControl() & 3 || Lara.gunType != WEAPON_SHOTGUN && Lara.gunType != WEAPON_HK && Lara.gunType != WEAPON_REVOLVER)
if (GetRandomControl() & 3
|| Lara.gunType != WEAPON_SHOTGUN
&& Lara.gunType != WEAPON_HK
&& Lara.gunType != WEAPON_REVOLVER)
{
if (!(GetRandomControl() & 7) || Lara.gunType == WEAPON_SHOTGUN || Lara.gunType == WEAPON_HK || Lara.gunType == WEAPON_REVOLVER)
if (!(GetRandomControl() & 7)
|| Lara.gunType == WEAPON_SHOTGUN
|| Lara.gunType == WEAPON_HK
|| Lara.gunType == WEAPON_REVOLVER)
{
if (item->currentAnimState == STATE_MUMMY_WALK_ARMS_UP || item->currentAnimState == STATE_MUMMY_WALK_HIT)
if (item->currentAnimState == STATE_MUMMY_WALK_ARMS_UP
|| item->currentAnimState == STATE_MUMMY_WALK_HIT)
{
item->currentAnimState = STATE_MUMMY_ARMS_UP_PUSHED_BACK;
item->animNumber = Objects[item->objectNumber].animIndex + ANIMATION_MUMMY_ARMS_UP_PUSHED_BACK;
@ -126,175 +135,171 @@ void MummyControl(short itemNumber)
item->pos.yRot += info.angle;
creature->maximumTurn = 0;
}
CreatureTilt(item, 0);
CreatureJoint(item, 0, joint0);
CreatureJoint(item, 1, joint1);
CreatureJoint(item, 2, joint2);
CreatureAnimation(itemNumber, angle, 0);
return;
}
}
}
GetCreatureMood(item, &info, VIOLENT);
CreatureMood(item, &info, VIOLENT);
angle = CreatureTurn(item, creature->maximumTurn);
if (info.ahead)
else
{
joint0 = info.angle / 2;
joint2 = info.angle / 2;
joint1 = info.xAngle;
}
GetCreatureMood(item, &info, VIOLENT);
CreatureMood(item, &info, VIOLENT);
switch (item->currentAnimState)
{
case STATE_MUMMY_STOP:
creature->flags = 0;
creature->maximumTurn = 0;
angle = CreatureTurn(item, creature->maximumTurn);
if (info.distance <= SQUARE(512) || info.distance >= SQUARE(7168))
if (info.ahead)
{
if (info.distance - SQUARE(512) <= 0)
item->goalAnimState = 10;
else
{
item->goalAnimState = 1;
joint0 = 0;
joint1 = 0;
joint2 = 0;
if (item->triggerFlags > -100 && (item->triggerFlags & 0x8000) != 0)
item->triggerFlags++;
}
joint0 = info.angle / 2;
joint2 = info.angle / 2;
joint1 = info.xAngle;
}
else
item->goalAnimState = STATE_MUMMY_WALK;
break;
case STATE_MUMMY_WALK:
if (item->triggerFlags == 1)
switch (item->currentAnimState)
{
case STATE_MUMMY_STOP:
creature->flags = 0;
creature->maximumTurn = 0;
if (item->frameNumber == g_Level.Anims[item->animNumber].frameEnd)
item->triggerFlags = 0;
}
else
{
creature->maximumTurn = ANGLE(7);
if (info.distance >= SQUARE(3072))
if (info.distance <= SQUARE(512)
|| info.distance >= SQUARE(7168))
{
if (info.distance > SQUARE(7168))
if (info.distance - SQUARE(512) <= 0)
item->goalAnimState = STATE_MUMMY_HIT;
else
{
item->goalAnimState = STATE_MUMMY_STOP;
joint0 = 0;
joint1 = 0;
joint2 = 0;
if (item->triggerFlags > -100 && item->triggerFlags & 0x8000 < 0)
item->triggerFlags++;
}
}
else
{
item->goalAnimState = STATE_MUMMY_WALK_ARMS_UP;
}
}
break;
case STATE_MUMMY_WALK_ARMS_UP:
creature->flags = 0;
creature->maximumTurn = ANGLE(7);
if (info.distance < SQUARE(512))
{
item->goalAnimState = STATE_MUMMY_STOP;
item->goalAnimState = STATE_MUMMY_WALK;
break;
}
if (info.distance > SQUARE(3072) && info.distance < SQUARE(7168))
{
item->goalAnimState = STATE_MUMMY_WALK;
break;
}
if (info.distance <= SQUARE(682))
item->goalAnimState = STATE_MUMMY_WALK_HIT;
else if (info.distance > SQUARE(7168))
item->goalAnimState = STATE_MUMMY_STOP;
break;
case STATE_MUMMY_ARMS_CROSSED:
creature->maximumTurn = 0;
if (info.distance < SQUARE(1024) || item->triggerFlags > -1)
item->goalAnimState = STATE_MUMMY_WALK;
break;
case STATE_MUMMY_LYING_DOWN:
joint0 = 0;
joint1 = 0;
joint2 = 0;
creature->maximumTurn = 0;
item->hitPoints = 0;
if (info.distance < SQUARE(1024) || !(GetRandomControl() & 0x7F))
{
item->goalAnimState = STATE_MUMMY_GET_UP;
item->hitPoints = Objects[item->objectNumber].hitPoints;
}
break;
case STATE_MUMMY_WALK_HIT:
case STATE_MUMMY_HIT:
creature->maximumTurn = 0;
if (abs(info.angle) >= ANGLE(7))
{
if (info.angle >= 0)
case STATE_MUMMY_WALK:
if (item->triggerFlags == 1)
{
item->pos.yRot += ANGLE(7);
creature->maximumTurn = 0;
if (item->frameNumber == g_Level.Anims[item->animNumber].frameEnd)
item->triggerFlags = 0;
}
else
{
item->pos.yRot -= ANGLE(7);
}
}
else
{
item->pos.yRot += info.angle;
}
if (!creature->flags)
{
if (item->touchBits & 0x4800)
{
if (item->frameNumber > g_Level.Anims[item->animNumber].frameEnd + 13 && item->frameNumber < g_Level.Anims[item->animNumber].frameEnd + 22)
creature->maximumTurn = ANGLE(7);
if (info.distance >= SQUARE(3072))
{
LaraItem->hitPoints -= 100;
LaraItem->hitStatus = true;
if (item->animNumber == Objects[item->objectNumber].animIndex + ANIMATION_MUMMY_HIT_LEFT)
if (info.distance > SQUARE(7168))
{
CreatureEffect2(
item,
&mummyBite1,
5,
-1,
DoBloodSplat);
item->goalAnimState = STATE_MUMMY_STOP;
}
else
{
CreatureEffect2(
item,
&mummyBite2,
5,
-1,
DoBloodSplat);
}
creature->flags = 1;
}
else
{
item->goalAnimState = STATE_MUMMY_WALK_ARMS_UP;
}
}
break;
case STATE_MUMMY_WALK_ARMS_UP:
creature->flags = 0;
creature->maximumTurn = ANGLE(7);
if (info.distance < SQUARE(512))
{
item->goalAnimState = STATE_MUMMY_STOP;
break;
}
if (info.distance > SQUARE(3072) && info.distance < SQUARE(7168))
{
item->goalAnimState = STATE_MUMMY_WALK;
break;
}
if (info.distance <= SQUARE(682))
item->goalAnimState = STATE_MUMMY_WALK_HIT;
else if (info.distance > SQUARE(7168))
item->goalAnimState = STATE_MUMMY_STOP;
break;
case STATE_MUMMY_ARMS_CROSSED:
creature->maximumTurn = 0;
if (info.distance < SQUARE(1024) || item->triggerFlags > -1)
item->goalAnimState = STATE_MUMMY_WALK;
break;
case STATE_MUMMY_LYING_DOWN:
joint0 = 0;
joint1 = 0;
joint2 = 0;
creature->maximumTurn = 0;
item->hitPoints = 0;
if (info.distance < SQUARE(1024) || !(GetRandomControl() & 0x7F))
{
item->goalAnimState = STATE_MUMMY_GET_UP;
item->hitPoints = Objects[item->objectNumber].hitPoints;
}
break;
case STATE_MUMMY_WALK_HIT:
case STATE_MUMMY_HIT:
creature->maximumTurn = 0;
if (abs(info.angle) >= ANGLE(7))
{
if (info.angle >= 0)
{
item->pos.yRot += ANGLE(7);
}
else
{
item->pos.yRot -= ANGLE(7);
}
}
else
{
item->pos.yRot += info.angle;
}
if (!creature->flags)
{
if (item->touchBits & 0x4800)
{
if (item->frameNumber > g_Level.Anims[item->animNumber].frameEnd + 13 && item->frameNumber < g_Level.Anims[item->animNumber].frameEnd + 22)
{
LaraItem->hitPoints -= 100;
LaraItem->hitStatus = true;
if (item->animNumber == Objects[item->objectNumber].animIndex + ANIMATION_MUMMY_HIT_LEFT)
{
CreatureEffect2(
item,
&mummyBite1,
5,
-1,
DoBloodSplat);
}
else
{
CreatureEffect2(
item,
&mummyBite2,
5,
-1,
DoBloodSplat);
}
creature->flags = 1;
}
}
}
break;
default:
break;
}
break;
default:
break;
}
CreatureTilt(item, 0);
CreatureJoint(item, 0, joint0);
CreatureJoint(item, 1, joint1);
CreatureJoint(item, 2, joint2);
CreatureAnimation(itemNumber, angle, 0);
}

View file

@ -14,9 +14,17 @@
#include "tomb4fx.h"
#include "level.h"
#define STATE_SKELETON_UNDER_FLOOR 0
#define STATE_SKELETON_STOP 1
#define STATE_SKELETON_WALK 2
#define STATE_SKELETON_RUN 3
#define STATE_SKELETON_JUMP_LEFT 19
#define STATE_SKELETON_JUMP_RIGHT 20
#define STATE_SKELETON_JUMP_LIE_DOWN 25
BITE_INFO skeletonBite = { 0, -16, 200, 11 };
static void WakeUpSkeleton(ITEM_INFO* item)
void WakeUpSkeleton(ITEM_INFO* item)
{
short fxNum = CreateNewEffect(item->roomNumber);
if (fxNum != NO_ITEM)
@ -78,7 +86,7 @@ static void WakeUpSkeleton(ITEM_INFO* item)
void InitialiseSkeleton(short itemNumber)
{
ITEM_INFO* item = &g_Level.Items[itemNumber];
OBJECT_INFO* obj = &Objects[ID_SKELETON];
OBJECT_INFO* obj = &Objects[item->objectNumber];
ClearItem(itemNumber);
@ -92,22 +100,22 @@ void InitialiseSkeleton(short itemNumber)
break;
case 1:
item->goalAnimState = 20;
item->currentAnimState = 20;
item->goalAnimState = STATE_SKELETON_JUMP_RIGHT;
item->currentAnimState = STATE_SKELETON_JUMP_RIGHT;
item->animNumber = obj->animIndex + 37;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
break;
case 2:
item->goalAnimState = 19;
item->currentAnimState = 19;
item->goalAnimState = STATE_SKELETON_JUMP_LEFT;
item->currentAnimState = STATE_SKELETON_JUMP_LEFT;
item->animNumber = obj->animIndex + 34;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
break;
case 3:
item->goalAnimState = 25;
item->currentAnimState = 25;
item->goalAnimState = STATE_SKELETON_JUMP_LIE_DOWN;
item->currentAnimState = STATE_SKELETON_JUMP_LIE_DOWN;
item->animNumber = obj->animIndex;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->status = ITEM_DEACTIVATED;
@ -231,7 +239,7 @@ void SkeletonControl(short itemNumber)
dx = LaraItem->pos.xPos - item->pos.xPos;
dz = LaraItem->pos.zPos - item->pos.zPos;
laraInfo.angle = phd_atan(dz, dx) - item->pos.yRot;
laraInfo.distance = dx * dx + dz * dz;
laraInfo.distance = SQUARE(dx) + SQUARE(dz);
}
GetCreatureMood(item, &info, VIOLENT);
@ -245,7 +253,9 @@ void SkeletonControl(short itemNumber)
ITEM_INFO* tempEnemy = creature->enemy;
creature->enemy = LaraItem;
if (item->hitStatus || distance < SQUARE(1024) || TargetVisible(item, &laraInfo))
if (item->hitStatus
|| distance < SQUARE(1024)
|| TargetVisible(item, &laraInfo))
creature->alerted = true;
creature->enemy = tempEnemy;
@ -318,7 +328,7 @@ void SkeletonControl(short itemNumber)
switch (item->currentAnimState)
{
case 1:
case STATE_SKELETON_STOP:
if (!(GetRandomControl() & 0xF))
{
item->goalAnimState = 2;

View file

@ -297,7 +297,6 @@ static void StartBaddy(OBJECT_INFO* obj)
g_Level.Bones[obj->boneIndex + 28 * 4] |= ROT_Y;
g_Level.Bones[obj->boneIndex + 28 * 4] |= ROT_X;
//g_Level.Bones[obj->boneIndex + 72 * 4] |= ROT_Y;
}
obj = &Objects[ID_SKELETON];

View file

@ -83,20 +83,23 @@ namespace T5M::Renderer
for (int i = 0; i < numStatics; i++)
{
MESH_INFO *mesh = &r->mesh[i];
RendererStatic *newStatic = &room.Statics[i];
STATIC_INFO *sinfo = &StaticObjects[mesh->staticNumber];
Vector3 min = Vector3(sinfo->collisionBox.X1, sinfo->collisionBox.Y1, sinfo->collisionBox.Z1);
Vector3 max = Vector3(sinfo->collisionBox.X2, sinfo->collisionBox.Y2, sinfo->collisionBox.Z2);
min += Vector3(mesh->x, mesh->y, mesh->z);
max += Vector3(mesh->x, mesh->y, mesh->z);
if (!renderView.camera.frustum.AABBInFrustum(min, max))
continue;
Matrix rotation = Matrix::CreateRotationY(TO_RAD(mesh->yRot));
Vector3 translation = Vector3(mesh->x, mesh->y, mesh->z);
newStatic->Mesh = mesh;
newStatic->RoomIndex = roomNumber;
newStatic->World = rotation * Matrix::CreateTranslation(translation);
renderView.staticsToDraw.push_back(newStatic);
if (mesh->flags > 0)
{
RendererStatic* newStatic = &room.Statics[i];
STATIC_INFO* sinfo = &StaticObjects[mesh->staticNumber];
Vector3 min = Vector3(sinfo->collisionBox.X1, sinfo->collisionBox.Y1, sinfo->collisionBox.Z1);
Vector3 max = Vector3(sinfo->collisionBox.X2, sinfo->collisionBox.Y2, sinfo->collisionBox.Z2);
min += Vector3(mesh->x, mesh->y, mesh->z);
max += Vector3(mesh->x, mesh->y, mesh->z);
if (!renderView.camera.frustum.AABBInFrustum(min, max))
continue;
Matrix rotation = Matrix::CreateRotationY(TO_RAD(mesh->yRot));
Vector3 translation = Vector3(mesh->x, mesh->y, mesh->z);
newStatic->Mesh = mesh;
newStatic->RoomIndex = roomNumber;
newStatic->World = rotation * Matrix::CreateTranslation(translation);
renderView.staticsToDraw.push_back(newStatic);
}
}
}