Convert static position to PHD_3DPOS, fix crossbow bolt shatter, read/write proper shatter type

This commit is contained in:
Lwmte 2021-09-10 13:49:45 +03:00
parent 2f3af7e3ea
commit f8d9edeb81
22 changed files with 189 additions and 200 deletions

View file

@ -262,10 +262,10 @@ void ControlHarpoonBolt(short itemNumber)
currentMesh->hitPoints -= Weapons[WEAPON_CROSSBOW].damage; currentMesh->hitPoints -= Weapons[WEAPON_CROSSBOW].damage;
if (currentMesh->hitPoints <= 0) if (currentMesh->hitPoints <= 0)
{ {
TriggerExplosionSparks(currentMesh->x, currentMesh->y, currentMesh->z, 3, -2, 0, item->roomNumber); TriggerExplosionSparks(currentMesh->pos.xPos, currentMesh->pos.yPos, currentMesh->pos.zPos, 3, -2, 0, item->roomNumber);
auto pos = PHD_3DPOS(currentMesh->x, currentMesh->y - 128, currentMesh->z, 0, currentMesh->yRot, 0); auto pos = PHD_3DPOS(currentMesh->pos.xPos, currentMesh->pos.yPos - 128, currentMesh->pos.zPos, 0, currentMesh->pos.yRot, 0);
TriggerShockwave(&pos, 40, 176, 64, 0, 96, 128, 16, 0, 0); TriggerShockwave(&pos, 40, 176, 64, 0, 96, 128, 16, 0, 0);
ShatterObject((SHATTER_ITEM*)item, NULL, -128, item->roomNumber, 0); // TODO: this wont work !! ShatterObject(NULL, currentMesh, -128, item->roomNumber, 0);
SmashedMeshRoom[SmashedMeshCount] = item->roomNumber; SmashedMeshRoom[SmashedMeshCount] = item->roomNumber;
SmashedMesh[SmashedMeshCount] = currentMesh; SmashedMesh[SmashedMeshCount] = currentMesh;
SmashedMeshCount++; SmashedMeshCount++;
@ -701,10 +701,10 @@ void ControlGrenade(short itemNumber)
currentMesh->hitPoints -= Weapons[WEAPON_GRENADE_LAUNCHER].damage; currentMesh->hitPoints -= Weapons[WEAPON_GRENADE_LAUNCHER].damage;
if (currentMesh->hitPoints <= 0) if (currentMesh->hitPoints <= 0)
{ {
TriggerExplosionSparks(currentMesh->x, currentMesh->y, currentMesh->z, 3, -2, 0, item->roomNumber); TriggerExplosionSparks(currentMesh->pos.xPos, currentMesh->pos.yPos, currentMesh->pos.zPos, 3, -2, 0, item->roomNumber);
auto pos = PHD_3DPOS(currentMesh->x, currentMesh->y - 128, currentMesh->z, 0, currentMesh->yRot, 0); auto pos = PHD_3DPOS(currentMesh->pos.xPos, currentMesh->pos.yPos - 128, currentMesh->pos.zPos, 0, currentMesh->pos.yRot, 0);
TriggerShockwave(&pos, 40, 176, 64, 0, 96, 128, 16, 0, 0); TriggerShockwave(&pos, 40, 176, 64, 0, 96, 128, 16, 0, 0);
ShatterObject((SHATTER_ITEM*)item, NULL, -128, item->roomNumber, 0); // TODO: this wont work !! ShatterObject(NULL, currentMesh, -128, item->roomNumber, 0);
SmashedMeshRoom[SmashedMeshCount] = item->roomNumber; SmashedMeshRoom[SmashedMeshCount] = item->roomNumber;
SmashedMesh[SmashedMeshCount] = currentMesh; SmashedMesh[SmashedMeshCount] = currentMesh;
SmashedMeshCount++; SmashedMeshCount++;
@ -944,8 +944,8 @@ void ControlRocket(short itemNumber)
currentMesh->hitPoints -= Weapons[WEAPON_ROCKET_LAUNCHER].damage; currentMesh->hitPoints -= Weapons[WEAPON_ROCKET_LAUNCHER].damage;
if (currentMesh->hitPoints <= 0) if (currentMesh->hitPoints <= 0)
{ {
TriggerExplosionSparks(currentMesh->x, currentMesh->y, currentMesh->z, 3, -2, 0, item->roomNumber); TriggerExplosionSparks(currentMesh->pos.xPos, currentMesh->pos.yPos, currentMesh->pos.zPos, 3, -2, 0, item->roomNumber);
auto pos = PHD_3DPOS(currentMesh->x, currentMesh->y - 128, currentMesh->z, 0, currentMesh->yRot, 0); auto pos = PHD_3DPOS(currentMesh->pos.xPos, currentMesh->pos.yPos - 128, currentMesh->pos.zPos, 0, currentMesh->pos.yRot, 0);
TriggerShockwave(&pos, 40, 176, 64, 0, 96, 128, 16, 0, 0); TriggerShockwave(&pos, 40, 176, 64, 0, 96, 128, 16, 0, 0);
ShatterObject((SHATTER_ITEM*)item, NULL, -128, item->roomNumber, 0); // TODO: this wont work !! ShatterObject((SHATTER_ITEM*)item, NULL, -128, item->roomNumber, 0); // TODO: this wont work !!
SmashedMeshRoom[SmashedMeshCount] = item->roomNumber; SmashedMeshRoom[SmashedMeshCount] = item->roomNumber;
@ -1374,103 +1374,98 @@ void ControlCrossbowBolt(short itemNumber)
foundCollidedObjects = true; foundCollidedObjects = true;
if (item->itemFlags[0] != CROSSBOW_POISON || explode) // If explosive ammos selected and item hit, then blast everything
if (item->itemFlags[0] == CROSSBOW_EXPLODE)
explode = true;
if (CollidedItems[0])
{ {
if (CollidedItems[0]) ITEM_INFO* currentItem = CollidedItems[0];
int k = 0;
do
{ {
// If explosive ammos selected and item hit, then blast everything OBJECT_INFO* currentObj = &Objects[currentItem->objectNumber];
if (item->itemFlags[0] == CROSSBOW_EXPLODE)
explode = true;
ITEM_INFO* currentItem = CollidedItems[0]; if ((currentObj->intelligent && currentObj->collision && currentItem->status == ITEM_ACTIVE && !currentObj->undead)
|| (currentItem->objectNumber == ID_LARA && explode)
int k = 0; || (currentItem->flags & 0x40 &&
do (Objects[currentItem->objectNumber].explodableMeshbits || currentItem == LaraItem)))
{ {
OBJECT_INFO* currentObj = &Objects[currentItem->objectNumber]; if (explode)
if ((currentObj->intelligent && currentObj->collision && currentItem->status == ITEM_ACTIVE && !currentObj->undead)
|| (currentItem->objectNumber == ID_LARA && explode)
|| (currentItem->flags & 0x40 &&
(Objects[currentItem->objectNumber].explodableMeshbits || currentItem == LaraItem)))
{ {
if (explode) // All active intelligent creatures explode, if their HP is <= 0
{ // Explosion is handled by CreatureDie()
// All active intelligent creatures explode, if their HP is <= 0 // Also Lara can be damaged
// Explosion is handled by CreatureDie() // HitTarget() is called inside this
// Also Lara can be damaged DoExplosiveDamageOnBaddie(currentItem, item, WEAPON_CROSSBOW);
// HitTarget() is called inside this
DoExplosiveDamageOnBaddie(currentItem, item, WEAPON_CROSSBOW);
}
else if (currentItem->objectNumber != ID_LARA)
{
// Normal hit
HitTarget(currentItem, (GAME_VECTOR*)& item->pos, Weapons[WEAPON_CROSSBOW].damage << item->itemFlags[0], 0);
// Poisoned ammos
if (item->itemFlags[0] == CROSSBOW_POISON)
currentItem->poisoned = true;
}
} }
else if (currentItem->objectNumber >= ID_SMASH_OBJECT1 && currentItem->objectNumber <= ID_SMASH_OBJECT8) else if (currentItem->objectNumber != ID_LARA)
{ {
// Smash objects are legacy objects from TRC, let's make them explode in the legacy way // Normal hit
TriggerExplosionSparks(currentItem->pos.xPos, currentItem->pos.yPos, currentItem->pos.zPos, 3, -2, 0, currentItem->roomNumber); HitTarget(currentItem, (GAME_VECTOR*)& item->pos, Weapons[WEAPON_CROSSBOW].damage << item->itemFlags[0], 0);
auto pos = PHD_3DPOS(currentItem->pos.xPos, currentItem->pos.yPos - 128, currentItem->pos.zPos);
TriggerShockwave(&pos, 48, 304, 96, 0, 96, 128, 24, 0, 0); // Poisoned ammos
if (item->itemFlags[0] == CROSSBOW_POISON)
currentItem->poisoned = true;
}
}
else if (currentItem->objectNumber >= ID_SMASH_OBJECT1 && currentItem->objectNumber <= ID_SMASH_OBJECT8)
{
// Smash objects are legacy objects from TRC, let's make them explode in the legacy way
if (explode)
ExplodeItemNode(currentItem, 0, 0, 128); ExplodeItemNode(currentItem, 0, 0, 128);
short currentItemNumber = (currentItem - CollidedItems[0]);
SmashObject(currentItemNumber);
KillItem(currentItemNumber);
}
// TODO_LUA: we need to handle it with an event like OnDestroy
/*else if (currentObj->hitEffect == HIT_SPECIAL)
{
// Some objects need a custom behaviour
//HitSpecial(item, currentItem, 1);
}*/
// All other items (like puzzles) don't explode short currentItemNumber = (currentItem - CollidedItems[0]);
SmashObject(currentItemNumber);
KillItem(currentItemNumber);
}
k++; // TODO_LUA: we need to handle it with an event like OnDestroy
currentItem = CollidedItems[k]; /*else if (currentObj->hitEffect == HIT_SPECIAL)
} while (currentItem);
}
if (CollidedMeshes[0])
{
MESH_INFO* currentMesh = CollidedMeshes[0];
int k = 0;
do
{ {
STATIC_INFO* s = &StaticObjects[currentMesh->staticNumber]; // Some objects need a custom behaviour
if (s->shatterType != SHT_NONE) //HitSpecial(item, currentItem, 1);
{ }*/
currentMesh->hitPoints -= Weapons[WEAPON_CROSSBOW].damage;
if (currentMesh->hitPoints <= 0)
{
TriggerExplosionSparks(currentMesh->x, currentMesh->y, currentMesh->z, 3, -2, 0, item->roomNumber);
auto pos = PHD_3DPOS(currentMesh->x, currentMesh->y - 128, currentMesh->z, 0, currentMesh->yRot, 0);
TriggerShockwave(&pos, 40, 176, 64, 0, 96, 128, 16, 0, 0);
ShatterObject((SHATTER_ITEM*)item, NULL, -128, item->roomNumber, 0); // TODO: this wont work !!
SmashedMeshRoom[SmashedMeshCount] = item->roomNumber;
SmashedMesh[SmashedMeshCount] = currentMesh;
SmashedMeshCount++;
currentMesh->flags &= ~StaticMeshFlags::SM_VISIBLE;
}
}
k++; // All other items (like puzzles) don't explode
currentMesh = CollidedMeshes[k];
} while (currentMesh); k++;
} currentItem = CollidedItems[k];
break; } while (currentItem);
} }
if (CollidedMeshes[0])
{
MESH_INFO* currentMesh = CollidedMeshes[0];
int k = 0;
do
{
STATIC_INFO* s = &StaticObjects[currentMesh->staticNumber];
if (s->shatterType != SHT_NONE)
{
currentMesh->hitPoints -= Weapons[WEAPON_CROSSBOW].damage;
if (currentMesh->hitPoints <= 0)
{
ShatterObject(NULL, currentMesh, -128, item->roomNumber, 0);
SmashedMeshRoom[SmashedMeshCount] = item->roomNumber;
SmashedMesh[SmashedMeshCount] = currentMesh;
SmashedMeshCount++;
currentMesh->flags &= ~StaticMeshFlags::SM_VISIBLE;
}
}
k++;
currentMesh = CollidedMeshes[k];
} while (currentMesh);
}
break;
explode = true; explode = true;
radius = CROSSBOW_EXPLODE_RADIUS; radius = CROSSBOW_EXPLODE_RADIUS;
}; };

View file

@ -831,7 +831,7 @@ void FixedCamera(ITEM_INFO* item)
else if (objLos < 0) else if (objLos < 0)
{ {
MESH_INFO* mesh = CollidedMeshes[0]; MESH_INFO* mesh = CollidedMeshes[0];
if (mesh->staticNumber >= 50 && mesh->staticNumber < 58) if (StaticObjects[mesh->staticNumber].shatterType != SHT_NONE)
{ {
ShatterObject(0, mesh, 128, to.roomNumber, 0); ShatterObject(0, mesh, 128, to.roomNumber, 0);
mesh->flags &= ~StaticMeshFlags::SM_VISIBLE; mesh->flags &= ~StaticMeshFlags::SM_VISIBLE;

View file

@ -48,14 +48,14 @@ int GetCollidedObjects(ITEM_INFO* collidingItem, int radius, int onlyVisible, IT
if (mesh->flags & StaticMeshFlags::SM_VISIBLE) if (mesh->flags & StaticMeshFlags::SM_VISIBLE)
{ {
if (collidingItem->pos.yPos + radius + STEP_SIZE/2 >= mesh->y + staticMesh->collisionBox.Y1) if (collidingItem->pos.yPos + radius + STEP_SIZE/2 >= mesh->pos.yPos + staticMesh->collisionBox.Y1)
{ {
if (collidingItem->pos.yPos <= mesh->y + staticMesh->collisionBox.Y2) if (collidingItem->pos.yPos <= mesh->pos.yPos + staticMesh->collisionBox.Y2)
{ {
s = phd_sin(mesh->yRot); s = phd_sin(mesh->pos.yRot);
c = phd_cos(mesh->yRot); c = phd_cos(mesh->pos.yRot);
rx = (collidingItem->pos.xPos - mesh->x) * c - s * (collidingItem->pos.zPos - mesh->z); rx = (collidingItem->pos.xPos - mesh->pos.xPos) * c - s * (collidingItem->pos.zPos - mesh->pos.zPos);
rz = (collidingItem->pos.zPos - mesh->z) * c + s * (collidingItem->pos.xPos - mesh->x); rz = (collidingItem->pos.zPos - mesh->pos.zPos) * c + s * (collidingItem->pos.xPos - mesh->pos.xPos);
if (radius + rx + STEP_SIZE/2 >= staticMesh->collisionBox.X1 && rx - radius - STEP_SIZE/2 <= staticMesh->collisionBox.X2) if (radius + rx + STEP_SIZE/2 >= staticMesh->collisionBox.X1 && rx - radius - STEP_SIZE/2 <= staticMesh->collisionBox.X2)
{ {
@ -194,18 +194,16 @@ void CollideSolidStatics(ITEM_INFO* item, COLL_INFO* coll)
// Only process meshes which are visible and solid // Only process meshes which are visible and solid
if ((mesh->flags & StaticMeshFlags::SM_VISIBLE) && (mesh->flags & StaticMeshFlags::SM_SOLID)) if ((mesh->flags & StaticMeshFlags::SM_VISIBLE) && (mesh->flags & StaticMeshFlags::SM_SOLID))
{ {
int x = abs(item->pos.xPos - mesh->x); int x = abs(item->pos.xPos - mesh->pos.xPos);
int y = abs(item->pos.yPos - mesh->y); int y = abs(item->pos.yPos - mesh->pos.yPos);
int z = abs(item->pos.zPos - mesh->z); int z = abs(item->pos.zPos - mesh->pos.zPos);
if (x < COLLISION_CHECK_DISTANCE && if (x < COLLISION_CHECK_DISTANCE &&
y < COLLISION_CHECK_DISTANCE && y < COLLISION_CHECK_DISTANCE &&
z < COLLISION_CHECK_DISTANCE) z < COLLISION_CHECK_DISTANCE)
{ {
auto stInfo = StaticObjects[mesh->staticNumber]; auto stInfo = StaticObjects[mesh->staticNumber];
auto stPos = PHD_3DPOS(mesh->x, mesh->y, mesh->z, 0, mesh->yRot, 0); if (CollideSolidBounds(item, stInfo.collisionBox, mesh->pos, coll))
if (CollideSolidBounds(item, stInfo.collisionBox, stPos, coll))
coll->HitStatic = true; coll->HitStatic = true;
} }
} }
@ -612,31 +610,25 @@ int FindGridShift(int x, int z)
int TestBoundsCollideStatic(ITEM_INFO* item, MESH_INFO* mesh, int radius) int TestBoundsCollideStatic(ITEM_INFO* item, MESH_INFO* mesh, int radius)
{ {
PHD_3DPOS pos;
pos.xPos = mesh->x;
pos.yPos = mesh->y;
pos.zPos = mesh->z;
pos.yRot = mesh->yRot;
auto bounds = StaticObjects[mesh->staticNumber].collisionBox; auto bounds = StaticObjects[mesh->staticNumber].collisionBox;
if (!(bounds.Z2 != 0 || bounds.Z1 != 0 || bounds.X1 != 0 || bounds.X2 != 0 || bounds.Y1 != 0 || bounds.Y2 != 0)) if (!(bounds.Z2 != 0 || bounds.Z1 != 0 || bounds.X1 != 0 || bounds.X2 != 0 || bounds.Y1 != 0 || bounds.Y2 != 0))
return false; return false;
ANIM_FRAME* frame = GetBestFrame(LaraItem); ANIM_FRAME* frame = GetBestFrame(LaraItem);
if (pos.yPos + bounds.Y2 <= LaraItem->pos.yPos + frame->boundingBox.Y1) if (mesh->pos.yPos + bounds.Y2 <= LaraItem->pos.yPos + frame->boundingBox.Y1)
return false; return false;
if (pos.yPos + bounds.Y1 >= LaraItem->pos.yPos + frame->boundingBox.Y2) if (mesh->pos.yPos + bounds.Y1 >= LaraItem->pos.yPos + frame->boundingBox.Y2)
return false; return false;
float c, s; float c, s;
int x, z, dx, dz; int x, z, dx, dz;
c = phd_cos(pos.yRot); c = phd_cos(mesh->pos.yRot);
s = phd_sin(pos.yRot); s = phd_sin(mesh->pos.yRot);
x = LaraItem->pos.xPos - pos.xPos; x = LaraItem->pos.xPos - mesh->pos.xPos;
z = LaraItem->pos.zPos - pos.zPos; z = LaraItem->pos.zPos - mesh->pos.zPos;
dx = c * x - s * z; dx = c * x - s * z;
dz = c * z + s * x; dz = c * z + s * x;
@ -655,19 +647,13 @@ int TestBoundsCollideStatic(ITEM_INFO* item, MESH_INFO* mesh, int radius)
int ItemPushStatic(ITEM_INFO* l, MESH_INFO* mesh, COLL_INFO* coll) // previously ItemPushLaraStatic int ItemPushStatic(ITEM_INFO* l, MESH_INFO* mesh, COLL_INFO* coll) // previously ItemPushLaraStatic
{ {
PHD_3DPOS pos;
pos.xPos = mesh->x;
pos.yPos = mesh->y;
pos.zPos = mesh->z;
pos.yRot = mesh->yRot;
auto bounds = StaticObjects[mesh->staticNumber].collisionBox; auto bounds = StaticObjects[mesh->staticNumber].collisionBox;
auto c = phd_cos(pos.yRot); auto c = phd_cos(mesh->pos.yRot);
auto s = phd_sin(pos.yRot); auto s = phd_sin(mesh->pos.yRot);
auto dx = l->pos.xPos - pos.xPos; auto dx = l->pos.xPos - mesh->pos.xPos;
auto dz = l->pos.zPos - pos.zPos; auto dz = l->pos.zPos - mesh->pos.zPos;
auto rx = c * dx - s * dz; auto rx = c * dx - s * dz;
auto rz = c * dz + s * dx; auto rz = c * dz + s * dx;
auto minX = bounds.X1 - coll->Setup.Radius; auto minX = bounds.X1 - coll->Setup.Radius;
@ -697,8 +683,8 @@ int ItemPushStatic(ITEM_INFO* l, MESH_INFO* mesh, COLL_INFO* coll) // previously
else else
rz -= bottom; rz -= bottom;
l->pos.xPos = pos.xPos + c * rx + s * rz; l->pos.xPos = mesh->pos.xPos + c * rx + s * rz;
l->pos.zPos = pos.zPos + c * rz - s * rx; l->pos.zPos = mesh->pos.zPos + c * rz - s * rx;
coll->Setup.BadHeightUp = NO_BAD_POS; coll->Setup.BadHeightUp = NO_BAD_POS;
coll->Setup.BadHeightDown = -STEPUP_HEIGHT; coll->Setup.BadHeightDown = -STEPUP_HEIGHT;
@ -2794,9 +2780,9 @@ void DoObjectCollision(ITEM_INFO* l, COLL_INFO* coll) // previously LaraBaddieCo
// Only process meshes which are visible and non-solid // Only process meshes which are visible and non-solid
if ((mesh->flags & StaticMeshFlags::SM_VISIBLE) && !(mesh->flags & StaticMeshFlags::SM_SOLID)) if ((mesh->flags & StaticMeshFlags::SM_VISIBLE) && !(mesh->flags & StaticMeshFlags::SM_SOLID))
{ {
int x = abs(l->pos.xPos - mesh->x); int x = abs(l->pos.xPos - mesh->pos.xPos);
int y = abs(l->pos.yPos - mesh->y); int y = abs(l->pos.yPos - mesh->pos.yPos);
int z = abs(l->pos.zPos - mesh->z); int z = abs(l->pos.zPos - mesh->pos.zPos);
if (x < COLLISION_CHECK_DISTANCE && if (x < COLLISION_CHECK_DISTANCE &&
y < COLLISION_CHECK_DISTANCE && y < COLLISION_CHECK_DISTANCE &&

View file

@ -477,14 +477,14 @@ GAME_STATUS ControlPhase(int numFrames, int demoMode)
SmashedMeshCount--; SmashedMeshCount--;
FLOOR_INFO *floor = GetFloor( FLOOR_INFO *floor = GetFloor(
SmashedMesh[SmashedMeshCount]->x, SmashedMesh[SmashedMeshCount]->pos.xPos,
SmashedMesh[SmashedMeshCount]->y, SmashedMesh[SmashedMeshCount]->pos.yPos,
SmashedMesh[SmashedMeshCount]->z, SmashedMesh[SmashedMeshCount]->pos.zPos,
&SmashedMeshRoom[SmashedMeshCount]); &SmashedMeshRoom[SmashedMeshCount]);
TestTriggers(SmashedMesh[SmashedMeshCount]->x, TestTriggers(SmashedMesh[SmashedMeshCount]->pos.xPos,
SmashedMesh[SmashedMeshCount]->y, SmashedMesh[SmashedMeshCount]->pos.yPos,
SmashedMesh[SmashedMeshCount]->z, SmashedMesh[SmashedMeshCount]->pos.zPos,
SmashedMeshRoom[SmashedMeshCount], true, 0); SmashedMeshRoom[SmashedMeshCount], true, 0);
floor->stopper = false; floor->stopper = false;
@ -1558,10 +1558,10 @@ int GetTargetOnLOS(GAME_VECTOR *src, GAME_VECTOR *dest, int DrawTarget, int firi
{ {
if (itemNumber < 0) if (itemNumber < 0)
{ {
if (mesh->staticNumber >= 50 && mesh->staticNumber < 58) if (StaticObjects[mesh->staticNumber].shatterType != SHT_NONE)
{ {
ShatterImpactData.impactDirection = direction; ShatterImpactData.impactDirection = direction;
ShatterImpactData.impactLocation = Vector3(mesh->x, mesh->y, mesh->z); ShatterImpactData.impactLocation = Vector3(mesh->pos.xPos, mesh->pos.yPos, mesh->pos.zPos);
ShatterObject(NULL, mesh, 128, target.roomNumber, 0); ShatterObject(NULL, mesh, 128, target.roomNumber, 0);
SmashedMeshRoom[SmashedMeshCount] = target.roomNumber; SmashedMeshRoom[SmashedMeshCount] = target.roomNumber;
SmashedMesh[SmashedMeshCount] = mesh; SmashedMesh[SmashedMeshCount] = mesh;
@ -1762,10 +1762,10 @@ int ObjectOnLOS2(GAME_VECTOR *start, GAME_VECTOR *end, PHD_VECTOR *vec, MESH_INF
if (meshp->flags & StaticMeshFlags::SM_VISIBLE) if (meshp->flags & StaticMeshFlags::SM_VISIBLE)
{ {
pos.xPos = meshp->x; pos.xPos = meshp->pos.xPos;
pos.yPos = meshp->y; pos.yPos = meshp->pos.yPos;
pos.zPos = meshp->z; pos.zPos = meshp->pos.zPos;
pos.yRot = meshp->yRot; pos.yRot = meshp->pos.yRot;
if (DoRayBox(start, end, &StaticObjects[meshp->staticNumber].collisionBox, &pos, vec, -1 - meshp->staticNumber)) if (DoRayBox(start, end, &StaticObjects[meshp->staticNumber].collisionBox, &pos, vec, -1 - meshp->staticNumber))
{ {

View file

@ -98,8 +98,7 @@ namespace TEN::Control::Volumes
void TestVolumes(short roomNumber, MESH_INFO* mesh) void TestVolumes(short roomNumber, MESH_INFO* mesh)
{ {
STATIC_INFO* sinfo = &StaticObjects[mesh->staticNumber]; STATIC_INFO* sinfo = &StaticObjects[mesh->staticNumber];
auto pos = PHD_3DPOS(mesh->x, mesh->y, mesh->z, mesh->yRot, 0, 0); auto bbox = TO_DX_BBOX(&mesh->pos, &sinfo->collisionBox);
auto bbox = TO_DX_BBOX(&pos, &sinfo->collisionBox);
TestVolumes(roomNumber, bbox, TriggerVolumeActivators::STATICS); TestVolumes(roomNumber, bbox, TriggerVolumeActivators::STATICS);
} }

View file

@ -37,8 +37,8 @@ void ShatterObject(SHATTER_ITEM* item, MESH_INFO* mesh, int num,short roomNumber
if (mesh) { if (mesh) {
isStatic = false; isStatic = false;
meshPtr = &g_Level.Meshes[StaticObjects[mesh->staticNumber].meshNumber]; meshPtr = &g_Level.Meshes[StaticObjects[mesh->staticNumber].meshNumber];
yRot = mesh->yRot; yRot = mesh->pos.yRot;
pos = Vector3(mesh->x, mesh->y, mesh->z); pos = Vector3(mesh->pos.xPos, mesh->pos.yPos, mesh->pos.zPos);
} }
else { else {
isStatic = true; isStatic = true;

View file

@ -828,7 +828,7 @@ BOUNDING_BOX* FindPlinth(ITEM_INFO* item)
MESH_INFO* mesh = &room->mesh[i]; MESH_INFO* mesh = &room->mesh[i];
if (mesh->flags & StaticMeshFlags::SM_VISIBLE) if (mesh->flags & StaticMeshFlags::SM_VISIBLE)
{ {
if (item->pos.xPos == mesh->x && item->pos.zPos == mesh->z) if (item->pos.xPos == mesh->pos.xPos && item->pos.zPos == mesh->pos.zPos)
{ {
BOUNDING_BOX* frame = (BOUNDING_BOX*)GetBestFrame(item); BOUNDING_BOX* frame = (BOUNDING_BOX*)GetBestFrame(item);
STATIC_INFO* s = &StaticObjects[mesh->staticNumber]; STATIC_INFO* s = &StaticObjects[mesh->staticNumber];

View file

@ -2,6 +2,7 @@
#include <framework.h> #include <framework.h>
#include <newtypes.h> #include <newtypes.h>
#include "floordata.h" #include "floordata.h"
#include "Specific\phd_global.h"
struct ANIM_FRAME; struct ANIM_FRAME;
@ -38,10 +39,7 @@ struct ROOM_LIGHT
struct MESH_INFO struct MESH_INFO
{ {
int x; PHD_3DPOS pos;
int y;
int z;
short yRot;
short staticNumber; short staticNumber;
short flags; short flags;
Vector4 color; Vector4 color;

View file

@ -809,14 +809,14 @@ bool SaveGame::readGameStatusChunks(ChunkId* chunkId, int maxSize, int arg)
if (!flags) if (!flags)
{ {
FLOOR_INFO* floor = GetFloor(g_Level.Rooms[roomIndex].mesh[staticIndex].x, FLOOR_INFO* floor = GetFloor(g_Level.Rooms[roomIndex].mesh[staticIndex].pos.xPos,
g_Level.Rooms[roomIndex].mesh[staticIndex].y, g_Level.Rooms[roomIndex].mesh[staticIndex].pos.yPos,
g_Level.Rooms[roomIndex].mesh[staticIndex].z, g_Level.Rooms[roomIndex].mesh[staticIndex].pos.zPos,
&roomIndex); &roomIndex);
TestTriggers(g_Level.Rooms[roomIndex].mesh[staticIndex].x, TestTriggers(g_Level.Rooms[roomIndex].mesh[staticIndex].pos.xPos,
g_Level.Rooms[roomIndex].mesh[staticIndex].y, g_Level.Rooms[roomIndex].mesh[staticIndex].pos.yPos,
g_Level.Rooms[roomIndex].mesh[staticIndex].z, roomIndex, true, NULL); g_Level.Rooms[roomIndex].mesh[staticIndex].pos.zPos, roomIndex, true, NULL);
floor->stopper = false; floor->stopper = false;
} }

View file

@ -174,9 +174,9 @@ void KnightTemplarControl(short itemNumber)
{ {
MESH_INFO* mesh = &room->mesh[i]; MESH_INFO* mesh = &room->mesh[i];
if (floor(pos.x) == floor(mesh->x) && if (floor(pos.x) == floor(mesh->pos.xPos) &&
floor(pos.z) == floor(mesh->z) && floor(pos.z) == floor(mesh->pos.zPos) &&
mesh->staticNumber >= 50) StaticObjects[mesh->staticNumber].shatterType != SHT_NONE)
{ {
ShatterObject(NULL, mesh, -64, LaraItem->roomNumber, 0); ShatterObject(NULL, mesh, -64, LaraItem->roomNumber, 0);
SoundEffect(SFX_TR4_HIT_ROCK, &item->pos, 0); SoundEffect(SFX_TR4_HIT_ROCK, &item->pos, 0);

View file

@ -643,7 +643,9 @@ namespace TEN::Entities::TR4
for (int i = 0; i < room->mesh.size(); i++) for (int i = 0; i < room->mesh.size(); i++)
{ {
MESH_INFO* staticMesh = &room->mesh[i]; MESH_INFO* staticMesh = &room->mesh[i];
if (abs(pos.x - staticMesh->x) < 1024 && abs(pos.z - staticMesh->z) < 1024 && staticMesh->staticNumber >= 50) if (abs(pos.x - staticMesh->pos.xPos) < 1024 &&
abs(pos.z - staticMesh->pos.zPos) < 1024 &&
StaticObjects[staticMesh->staticNumber].shatterType != SHT_NONE)
{ {
ShatterObject(0, staticMesh, -128, LaraItem->roomNumber, 0); ShatterObject(0, staticMesh, -128, LaraItem->roomNumber, 0);
SoundEffect(SFX_TR4_HIT_ROCK, &item->pos, 0); SoundEffect(SFX_TR4_HIT_ROCK, &item->pos, 0);

View file

@ -62,7 +62,9 @@ void SphinxControl(short itemNumber)
{ {
MESH_INFO* mesh = &room->mesh[i]; MESH_INFO* mesh = &room->mesh[i];
if (((mesh->z / 1024) == (z / 1024)) && ((mesh->x / 1024) == (x / 1024)) && mesh->staticNumber >= 50) if (((mesh->pos.zPos / 1024) == (z / 1024)) &&
((mesh->pos.xPos / 1024) == (x / 1024)) &&
StaticObjects[mesh->staticNumber].shatterType != SHT_NONE)
{ {
ShatterObject(NULL, mesh, -64, item->roomNumber, 0); ShatterObject(NULL, mesh, -64, item->roomNumber, 0);
SoundEffect(SFX_TR4_HIT_ROCK, &item->pos, 0); SoundEffect(SFX_TR4_HIT_ROCK, &item->pos, 0);

View file

@ -321,11 +321,11 @@ void ControlGladiator(short itemNumber)
{ {
mesh = &r->mesh[i]; mesh = &r->mesh[i];
if (!((pos.z ^ mesh->z) & 0xFFFFFC00)) if (!((pos.z ^ mesh->pos.zPos) & 0xFFFFFC00))
{ {
if (!((pos.x ^ mesh->x) & 0xFFFFFC00)) if (!((pos.x ^ mesh->pos.xPos) & 0xFFFFFC00))
{ {
if (mesh->staticNumber >= 50 && mesh->staticNumber <= 59) if (StaticObjects[mesh->staticNumber].shatterType != SHT_NONE)
{ {
ShatterObject(0, mesh, -64, LaraItem->roomNumber, 0); ShatterObject(0, mesh, -64, LaraItem->roomNumber, 0);
//SoundEffect(ShatterSounds[gfCurrentLevel - 5][*(v28 + 18)], v28, 0); //SoundEffect(ShatterSounds[gfCurrentLevel - 5][*(v28 + 18)], v28, 0);

View file

@ -105,12 +105,12 @@ void ControlGunShip(short itemNumber)
if (objOnLos < 0 && GetRandomControl() & 1) if (objOnLos < 0 && GetRandomControl() & 1)
{ {
if (hitMesh->staticNumber >= 50 && hitMesh->staticNumber < 59) if (StaticObjects[hitMesh->staticNumber].shatterType != SHT_NONE)
{ {
ShatterObject(0, hitMesh, 64, end.roomNumber, 0); ShatterObject(0, hitMesh, 64, end.roomNumber, 0);
hitMesh->flags &= ~StaticMeshFlags::SM_VISIBLE; hitMesh->flags &= ~StaticMeshFlags::SM_VISIBLE;
TestTriggers(hitMesh->x, hitMesh->y, hitMesh->z, end.roomNumber, true, NULL); TestTriggers(hitMesh->pos.xPos, hitMesh->pos.yPos, hitMesh->pos.zPos, end.roomNumber, true, NULL);
SoundEffect(GetShatterSound(hitMesh->staticNumber), (PHD_3DPOS*)hitMesh, 0); SoundEffect(GetShatterSound(hitMesh->staticNumber), &hitMesh->pos, 0);
} }
TriggerRicochetSpark((GAME_VECTOR*)&hitPos, 2 * GetRandomControl(), 3, 0); TriggerRicochetSpark((GAME_VECTOR*)&hitPos, 2 * GetRandomControl(), 3, 0);

View file

@ -609,9 +609,9 @@ void RomanStatueControl(short itemNumber)
{ {
mesh = &room->mesh[i]; mesh = &room->mesh[i];
if (!((mesh->z ^ pos.z) & 0xFFFFFC00) && !((mesh->x ^ pos.x) & 0xFFFFFC00)) if (!((mesh->pos.zPos ^ pos.z) & 0xFFFFFC00) && !((mesh->pos.xPos ^ pos.x) & 0xFFFFFC00))
{ {
if (mesh->staticNumber >= 50 && mesh->staticNumber <= 59) if (StaticObjects[mesh->staticNumber].shatterType != SHT_NONE)
{ {
ShatterObject(0, mesh, -64, LaraItem->roomNumber, 0); ShatterObject(0, mesh, -64, LaraItem->roomNumber, 0);
SoundEffect(GetShatterSound(mesh->staticNumber), (PHD_3DPOS*)mesh, 0); SoundEffect(GetShatterSound(mesh->staticNumber), (PHD_3DPOS*)mesh, 0);

View file

@ -139,13 +139,13 @@ void ExplosionControl(short itemNumber)
i = 0; i = 0;
while (CollidedMeshes[i]) while (CollidedMeshes[i])
{ {
if (CollidedMeshes[i]->staticNumber >= 50 && CollidedMeshes[i]->staticNumber < 58) if (StaticObjects[CollidedMeshes[i]->staticNumber].shatterType != SHT_NONE)
{ {
TriggerExplosionSparks(CollidedMeshes[i]->x, CollidedMeshes[i]->y, CollidedMeshes[i]->z, 3, -2, 0, item->roomNumber); TriggerExplosionSparks(CollidedMeshes[i]->pos.xPos, CollidedMeshes[i]->pos.yPos, CollidedMeshes[i]->pos.zPos, 3, -2, 0, item->roomNumber);
CollidedMeshes[i]->y -= 128; CollidedMeshes[i]->pos.yPos -= 128;
TriggerShockwave((PHD_3DPOS *) &CollidedMeshes[i]->x, 40, 176, 64, 0, 96, 128, 16, 0, 0); TriggerShockwave(&CollidedMeshes[i]->pos, 40, 176, 64, 0, 96, 128, 16, 0, 0);
CollidedMeshes[i]->y += 128; CollidedMeshes[i]->pos.yPos += 128;
SoundEffect(GetShatterSound(CollidedMeshes[i]->staticNumber), (PHD_3DPOS *) &CollidedMeshes[i]->x, 0); SoundEffect(GetShatterSound(CollidedMeshes[i]->staticNumber), &CollidedMeshes[i]->pos, 0);
ShatterObject(NULL, CollidedMeshes[i], -128, item->roomNumber, 0); ShatterObject(NULL, CollidedMeshes[i], -128, item->roomNumber, 0);
SmashedMeshRoom[SmashedMeshCount] = item->roomNumber; SmashedMeshRoom[SmashedMeshCount] = item->roomNumber;
SmashedMesh[SmashedMeshCount] = CollidedMeshes[i]; SmashedMesh[SmashedMeshCount] = CollidedMeshes[i];

View file

@ -3178,8 +3178,8 @@ namespace TEN::Renderer
{ {
RendererMesh *mesh = staticObj.ObjectMeshes[0]; RendererMesh *mesh = staticObj.ObjectMeshes[0];
m_stStatic.World = (Matrix::CreateRotationY(TO_RAD(msh->yRot)) * Matrix::CreateTranslation(msh->x, msh->y, msh->z)); m_stStatic.World = (Matrix::CreateRotationY(TO_RAD(msh->pos.yRot)) * Matrix::CreateTranslation(msh->pos.xPos, msh->pos.yPos, msh->pos.zPos));
m_stStatic.Position = Vector4(msh->x,msh->y,msh->z,1); m_stStatic.Position = Vector4(msh->pos.xPos, msh->pos.yPos, msh->pos.zPos, 1);
m_stStatic.Color = msh->color; m_stStatic.Color = msh->color;
m_cbStatic.updateData(m_stStatic, m_context.Get()); m_cbStatic.updateData(m_stStatic, m_context.Get());
m_context->VSSetConstantBuffers(1, 1, m_cbStatic.get()); m_context->VSSetConstantBuffers(1, 1, m_cbStatic.get());

View file

@ -89,12 +89,12 @@ namespace TEN::Renderer
STATIC_INFO* sinfo = &StaticObjects[mesh->staticNumber]; STATIC_INFO* sinfo = &StaticObjects[mesh->staticNumber];
Vector3 min = Vector3(sinfo->visibilityBox.X1, sinfo->visibilityBox.Y1, sinfo->visibilityBox.Z1); Vector3 min = Vector3(sinfo->visibilityBox.X1, sinfo->visibilityBox.Y1, sinfo->visibilityBox.Z1);
Vector3 max = Vector3(sinfo->visibilityBox.X2, sinfo->visibilityBox.Y2, sinfo->visibilityBox.Z2); Vector3 max = Vector3(sinfo->visibilityBox.X2, sinfo->visibilityBox.Y2, sinfo->visibilityBox.Z2);
min += Vector3(mesh->x, mesh->y, mesh->z); min += Vector3(mesh->pos.xPos, mesh->pos.yPos, mesh->pos.zPos);
max += Vector3(mesh->x, mesh->y, mesh->z); max += Vector3(mesh->pos.xPos, mesh->pos.yPos, mesh->pos.zPos);
if (!renderView.camera.frustum.AABBInFrustum(min, max)) if (!renderView.camera.frustum.AABBInFrustum(min, max))
continue; continue;
Matrix rotation = Matrix::CreateRotationY(TO_RAD(mesh->yRot)); Matrix rotation = Matrix::CreateRotationY(TO_RAD(mesh->pos.yRot));
Vector3 translation = Vector3(mesh->x, mesh->y, mesh->z); Vector3 translation = Vector3(mesh->pos.xPos, mesh->pos.yPos, mesh->pos.zPos);
newStatic->Mesh = mesh; newStatic->Mesh = mesh;
newStatic->RoomIndex = roomNumber; newStatic->RoomIndex = roomNumber;
newStatic->World = rotation * Matrix::CreateTranslation(translation); newStatic->World = rotation * Matrix::CreateTranslation(translation);

View file

@ -63,24 +63,24 @@ void GameScriptMeshInfo::Register(sol::state* state)
GameScriptPosition GameScriptMeshInfo::GetPos() const GameScriptPosition GameScriptMeshInfo::GetPos() const
{ {
return GameScriptPosition{ m_mesh.x, m_mesh.y, m_mesh.z }; return GameScriptPosition{ m_mesh.pos.xPos, m_mesh.pos.yPos, m_mesh.pos.zPos };
} }
void GameScriptMeshInfo::SetPos(GameScriptPosition const& pos) void GameScriptMeshInfo::SetPos(GameScriptPosition const& pos)
{ {
m_mesh.x = pos.x; m_mesh.pos.xPos = pos.x;
m_mesh.y = pos.y; m_mesh.pos.yPos = pos.y;
m_mesh.z = pos.z; m_mesh.pos.zPos = pos.z;
} }
int GameScriptMeshInfo::GetRot() const int GameScriptMeshInfo::GetRot() const
{ {
return m_mesh.yRot; return m_mesh.pos.yRot;
} }
void GameScriptMeshInfo::SetRot(int yRot) void GameScriptMeshInfo::SetRot(int yRot)
{ {
m_mesh.yRot = yRot; m_mesh.pos.yRot = yRot;
} }
std::string GameScriptMeshInfo::GetName() const std::string GameScriptMeshInfo::GetName() const

View file

@ -739,7 +739,9 @@ void SayNo()
int GetShatterSound(int shatterID) int GetShatterSound(int shatterID)
{ {
// TODO: Add scripted procedure to get shatter sound here. auto fxID = StaticObjects[shatterID].shatterSound;
if (fxID != -1)
return fxID;
if (shatterID < 3) if (shatterID < 3)
return SFX_TR5_SMASH_WOOD; return SFX_TR5_SMASH_WOOD;

View file

@ -137,7 +137,7 @@ int LoadItems()
{ {
for (const auto& mesh : r.mesh) for (const auto& mesh : r.mesh)
{ {
FLOOR_INFO* floor = &r.floor[((mesh.z - r.z) / 1024) + r.xSize * ((mesh.x - r.x) / 1024)]; FLOOR_INFO* floor = &r.floor[((mesh.pos.zPos - r.z) / 1024) + r.xSize * ((mesh.pos.xPos - r.x) / 1024)];
if (floor->box == NO_BOX) if (floor->box == NO_BOX)
continue; continue;
@ -146,7 +146,7 @@ int LoadItems()
{ {
int fl = floor->floor * 4; int fl = floor->floor * 4;
STATIC_INFO* st = &StaticObjects[mesh.staticNumber]; STATIC_INFO* st = &StaticObjects[mesh.staticNumber];
if (fl <= mesh.y - st->collisionBox.Y2 + 512 && fl < mesh.y - st->collisionBox.Y1) if (fl <= mesh.pos.yPos - st->collisionBox.Y2 + 512 && fl < mesh.pos.yPos - st->collisionBox.Y1)
{ {
if (st->collisionBox.X1 == 0 || st->collisionBox.X2 == 0 || if (st->collisionBox.X1 == 0 || st->collisionBox.X2 == 0 ||
st->collisionBox.Z1 == 0 || st->collisionBox.Z2 == 0 || st->collisionBox.Z1 == 0 || st->collisionBox.Z2 == 0 ||
@ -358,7 +358,6 @@ void LoadObjects()
StaticObjects[meshID].flags = (short)ReadInt16(); StaticObjects[meshID].flags = (short)ReadInt16();
StaticObjects[meshID].shatterType = (short)ReadInt16(); StaticObjects[meshID].shatterType = (short)ReadInt16();
StaticObjects[meshID].shatterDamage = (short)ReadInt16();
StaticObjects[meshID].shatterSound = (short)ReadInt16(); StaticObjects[meshID].shatterSound = (short)ReadInt16();
} }
@ -722,10 +721,12 @@ void ReadRooms()
for (int j = 0; j < numStatics; j++) for (int j = 0; j < numStatics; j++)
{ {
auto & mesh = room.mesh.emplace_back(); auto & mesh = room.mesh.emplace_back();
mesh.x = ReadInt32(); mesh.pos.xPos = ReadInt32();
mesh.y = ReadInt32(); mesh.pos.yPos = ReadInt32();
mesh.z = ReadInt32(); mesh.pos.zPos = ReadInt32();
mesh.yRot = ReadUInt16(); mesh.pos.xRot = 0;
mesh.pos.yRot = ReadUInt16();
mesh.pos.zRot = 0;
mesh.flags = ReadUInt16(); mesh.flags = ReadUInt16();
Vector3 rgb = ReadVector3(); Vector3 rgb = ReadVector3();
float a = ReadFloat(); float a = ReadFloat();

View file

@ -5,6 +5,7 @@
struct ITEM_INFO; struct ITEM_INFO;
struct COLL_INFO; struct COLL_INFO;
enum ZoneType : char; enum ZoneType : char;
enum HitEffectEnum enum HitEffectEnum
{ {
HIT_NONE, HIT_NONE,
@ -15,6 +16,13 @@ enum HitEffectEnum
MAX_HIT_EFFECT MAX_HIT_EFFECT
}; };
enum ShatterType
{
SHT_NONE,
SHT_FRAGMENT,
SHT_EXPLODE
};
struct OBJECT_INFO struct OBJECT_INFO
{ {
short nmeshes; short nmeshes;
@ -65,7 +73,6 @@ struct STATIC_INFO
BOUNDING_BOX visibilityBox; BOUNDING_BOX visibilityBox;
BOUNDING_BOX collisionBox; BOUNDING_BOX collisionBox;
int shatterType; int shatterType;
int shatterDamage;
int shatterSound; int shatterSound;
}; };
@ -74,9 +81,6 @@ constexpr auto SF_NO_COLLISION = 0x01;
constexpr auto SF_SHATTERABLE = 0x02; constexpr auto SF_SHATTERABLE = 0x02;
constexpr auto GRAVITY = 6; constexpr auto GRAVITY = 6;
constexpr auto SWAMP_GRAVITY = 2; constexpr auto SWAMP_GRAVITY = 2;
constexpr auto SHT_NONE = 0;
constexpr auto SHT_EXPLODE = 1;
constexpr auto SHT_FRAGMENT = 2;
extern OBJECT_INFO Objects[ID_NUMBER_OBJECTS]; extern OBJECT_INFO Objects[ID_NUMBER_OBJECTS];
extern STATIC_INFO StaticObjects[MAX_STATICS]; extern STATIC_INFO StaticObjects[MAX_STATICS];