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;
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);
TriggerExplosionSparks(currentMesh->pos.xPos, currentMesh->pos.yPos, currentMesh->pos.zPos, 3, -2, 0, item->roomNumber);
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);
ShatterObject((SHATTER_ITEM*)item, NULL, -128, item->roomNumber, 0); // TODO: this wont work !!
ShatterObject(NULL, currentMesh, -128, item->roomNumber, 0);
SmashedMeshRoom[SmashedMeshCount] = item->roomNumber;
SmashedMesh[SmashedMeshCount] = currentMesh;
SmashedMeshCount++;
@ -701,10 +701,10 @@ void ControlGrenade(short itemNumber)
currentMesh->hitPoints -= Weapons[WEAPON_GRENADE_LAUNCHER].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);
TriggerExplosionSparks(currentMesh->pos.xPos, currentMesh->pos.yPos, currentMesh->pos.zPos, 3, -2, 0, item->roomNumber);
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);
ShatterObject((SHATTER_ITEM*)item, NULL, -128, item->roomNumber, 0); // TODO: this wont work !!
ShatterObject(NULL, currentMesh, -128, item->roomNumber, 0);
SmashedMeshRoom[SmashedMeshCount] = item->roomNumber;
SmashedMesh[SmashedMeshCount] = currentMesh;
SmashedMeshCount++;
@ -944,8 +944,8 @@ void ControlRocket(short itemNumber)
currentMesh->hitPoints -= Weapons[WEAPON_ROCKET_LAUNCHER].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);
TriggerExplosionSparks(currentMesh->pos.xPos, currentMesh->pos.yPos, currentMesh->pos.zPos, 3, -2, 0, item->roomNumber);
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);
ShatterObject((SHATTER_ITEM*)item, NULL, -128, item->roomNumber, 0); // TODO: this wont work !!
SmashedMeshRoom[SmashedMeshCount] = item->roomNumber;
@ -1374,103 +1374,98 @@ void ControlCrossbowBolt(short itemNumber)
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
if (item->itemFlags[0] == CROSSBOW_EXPLODE)
explode = true;
OBJECT_INFO* currentObj = &Objects[currentItem->objectNumber];
ITEM_INFO* currentItem = CollidedItems[0];
int k = 0;
do
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)))
{
OBJECT_INFO* currentObj = &Objects[currentItem->objectNumber];
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)
{
if (explode)
{
// All active intelligent creatures explode, if their HP is <= 0
// Explosion is handled by CreatureDie()
// Also Lara can be damaged
// 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;
}
// All active intelligent creatures explode, if their HP is <= 0
// Explosion is handled by CreatureDie()
// Also Lara can be damaged
// HitTarget() is called inside this
DoExplosiveDamageOnBaddie(currentItem, item, WEAPON_CROSSBOW);
}
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
TriggerExplosionSparks(currentItem->pos.xPos, currentItem->pos.yPos, currentItem->pos.zPos, 3, -2, 0, currentItem->roomNumber);
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);
// 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)
{
// Smash objects are legacy objects from TRC, let's make them explode in the legacy way
if (explode)
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++;
currentItem = CollidedItems[k];
} while (currentItem);
}
if (CollidedMeshes[0])
{
MESH_INFO* currentMesh = CollidedMeshes[0];
int k = 0;
do
// TODO_LUA: we need to handle it with an event like OnDestroy
/*else if (currentObj->hitEffect == HIT_SPECIAL)
{
STATIC_INFO* s = &StaticObjects[currentMesh->staticNumber];
if (s->shatterType != SHT_NONE)
{
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;
}
}
// Some objects need a custom behaviour
//HitSpecial(item, currentItem, 1);
}*/
k++;
currentMesh = CollidedMeshes[k];
// All other items (like puzzles) don't explode
} 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;
radius = CROSSBOW_EXPLODE_RADIUS;
};

View file

@ -831,7 +831,7 @@ void FixedCamera(ITEM_INFO* item)
else if (objLos < 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);
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 (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);
c = phd_cos(mesh->yRot);
rx = (collidingItem->pos.xPos - mesh->x) * c - s * (collidingItem->pos.zPos - mesh->z);
rz = (collidingItem->pos.zPos - mesh->z) * c + s * (collidingItem->pos.xPos - mesh->x);
s = phd_sin(mesh->pos.yRot);
c = phd_cos(mesh->pos.yRot);
rx = (collidingItem->pos.xPos - mesh->pos.xPos) * c - s * (collidingItem->pos.zPos - mesh->pos.zPos);
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)
{
@ -194,18 +194,16 @@ void CollideSolidStatics(ITEM_INFO* item, COLL_INFO* coll)
// Only process meshes which are visible and solid
if ((mesh->flags & StaticMeshFlags::SM_VISIBLE) && (mesh->flags & StaticMeshFlags::SM_SOLID))
{
int x = abs(item->pos.xPos - mesh->x);
int y = abs(item->pos.yPos - mesh->y);
int z = abs(item->pos.zPos - mesh->z);
int x = abs(item->pos.xPos - mesh->pos.xPos);
int y = abs(item->pos.yPos - mesh->pos.yPos);
int z = abs(item->pos.zPos - mesh->pos.zPos);
if (x < COLLISION_CHECK_DISTANCE &&
y < COLLISION_CHECK_DISTANCE &&
z < COLLISION_CHECK_DISTANCE)
{
auto stInfo = StaticObjects[mesh->staticNumber];
auto stPos = PHD_3DPOS(mesh->x, mesh->y, mesh->z, 0, mesh->yRot, 0);
if (CollideSolidBounds(item, stInfo.collisionBox, stPos, coll))
if (CollideSolidBounds(item, stInfo.collisionBox, mesh->pos, coll))
coll->HitStatic = true;
}
}
@ -612,31 +610,25 @@ int FindGridShift(int x, int z)
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;
if (!(bounds.Z2 != 0 || bounds.Z1 != 0 || bounds.X1 != 0 || bounds.X2 != 0 || bounds.Y1 != 0 || bounds.Y2 != 0))
return false;
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;
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;
float c, s;
int x, z, dx, dz;
c = phd_cos(pos.yRot);
s = phd_sin(pos.yRot);
x = LaraItem->pos.xPos - pos.xPos;
z = LaraItem->pos.zPos - pos.zPos;
c = phd_cos(mesh->pos.yRot);
s = phd_sin(mesh->pos.yRot);
x = LaraItem->pos.xPos - mesh->pos.xPos;
z = LaraItem->pos.zPos - mesh->pos.zPos;
dx = c * x - s * z;
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
{
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 c = phd_cos(pos.yRot);
auto s = phd_sin(pos.yRot);
auto c = phd_cos(mesh->pos.yRot);
auto s = phd_sin(mesh->pos.yRot);
auto dx = l->pos.xPos - pos.xPos;
auto dz = l->pos.zPos - pos.zPos;
auto dx = l->pos.xPos - mesh->pos.xPos;
auto dz = l->pos.zPos - mesh->pos.zPos;
auto rx = c * dx - s * dz;
auto rz = c * dz + s * dx;
auto minX = bounds.X1 - coll->Setup.Radius;
@ -697,8 +683,8 @@ int ItemPushStatic(ITEM_INFO* l, MESH_INFO* mesh, COLL_INFO* coll) // previously
else
rz -= bottom;
l->pos.xPos = pos.xPos + c * rx + s * rz;
l->pos.zPos = pos.zPos + c * rz - s * rx;
l->pos.xPos = mesh->pos.xPos + c * rx + s * rz;
l->pos.zPos = mesh->pos.zPos + c * rz - s * rx;
coll->Setup.BadHeightUp = NO_BAD_POS;
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
if ((mesh->flags & StaticMeshFlags::SM_VISIBLE) && !(mesh->flags & StaticMeshFlags::SM_SOLID))
{
int x = abs(l->pos.xPos - mesh->x);
int y = abs(l->pos.yPos - mesh->y);
int z = abs(l->pos.zPos - mesh->z);
int x = abs(l->pos.xPos - mesh->pos.xPos);
int y = abs(l->pos.yPos - mesh->pos.yPos);
int z = abs(l->pos.zPos - mesh->pos.zPos);
if (x < COLLISION_CHECK_DISTANCE &&
y < COLLISION_CHECK_DISTANCE &&

View file

@ -477,14 +477,14 @@ GAME_STATUS ControlPhase(int numFrames, int demoMode)
SmashedMeshCount--;
FLOOR_INFO *floor = GetFloor(
SmashedMesh[SmashedMeshCount]->x,
SmashedMesh[SmashedMeshCount]->y,
SmashedMesh[SmashedMeshCount]->z,
SmashedMesh[SmashedMeshCount]->pos.xPos,
SmashedMesh[SmashedMeshCount]->pos.yPos,
SmashedMesh[SmashedMeshCount]->pos.zPos,
&SmashedMeshRoom[SmashedMeshCount]);
TestTriggers(SmashedMesh[SmashedMeshCount]->x,
SmashedMesh[SmashedMeshCount]->y,
SmashedMesh[SmashedMeshCount]->z,
TestTriggers(SmashedMesh[SmashedMeshCount]->pos.xPos,
SmashedMesh[SmashedMeshCount]->pos.yPos,
SmashedMesh[SmashedMeshCount]->pos.zPos,
SmashedMeshRoom[SmashedMeshCount], true, 0);
floor->stopper = false;
@ -1558,10 +1558,10 @@ int GetTargetOnLOS(GAME_VECTOR *src, GAME_VECTOR *dest, int DrawTarget, int firi
{
if (itemNumber < 0)
{
if (mesh->staticNumber >= 50 && mesh->staticNumber < 58)
if (StaticObjects[mesh->staticNumber].shatterType != SHT_NONE)
{
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);
SmashedMeshRoom[SmashedMeshCount] = target.roomNumber;
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)
{
pos.xPos = meshp->x;
pos.yPos = meshp->y;
pos.zPos = meshp->z;
pos.yRot = meshp->yRot;
pos.xPos = meshp->pos.xPos;
pos.yPos = meshp->pos.yPos;
pos.zPos = meshp->pos.zPos;
pos.yRot = meshp->pos.yRot;
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)
{
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(&pos, &sinfo->collisionBox);
auto bbox = TO_DX_BBOX(&mesh->pos, &sinfo->collisionBox);
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) {
isStatic = false;
meshPtr = &g_Level.Meshes[StaticObjects[mesh->staticNumber].meshNumber];
yRot = mesh->yRot;
pos = Vector3(mesh->x, mesh->y, mesh->z);
yRot = mesh->pos.yRot;
pos = Vector3(mesh->pos.xPos, mesh->pos.yPos, mesh->pos.zPos);
}
else {
isStatic = true;

View file

@ -828,7 +828,7 @@ BOUNDING_BOX* FindPlinth(ITEM_INFO* item)
MESH_INFO* mesh = &room->mesh[i];
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);
STATIC_INFO* s = &StaticObjects[mesh->staticNumber];

View file

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

View file

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

View file

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

View file

@ -62,7 +62,9 @@ void SphinxControl(short itemNumber)
{
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);
SoundEffect(SFX_TR4_HIT_ROCK, &item->pos, 0);

View file

@ -321,11 +321,11 @@ void ControlGladiator(short itemNumber)
{
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);
//SoundEffect(ShatterSounds[gfCurrentLevel - 5][*(v28 + 18)], v28, 0);

View file

@ -105,12 +105,12 @@ void ControlGunShip(short itemNumber)
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);
hitMesh->flags &= ~StaticMeshFlags::SM_VISIBLE;
TestTriggers(hitMesh->x, hitMesh->y, hitMesh->z, end.roomNumber, true, NULL);
SoundEffect(GetShatterSound(hitMesh->staticNumber), (PHD_3DPOS*)hitMesh, 0);
TestTriggers(hitMesh->pos.xPos, hitMesh->pos.yPos, hitMesh->pos.zPos, end.roomNumber, true, NULL);
SoundEffect(GetShatterSound(hitMesh->staticNumber), &hitMesh->pos, 0);
}
TriggerRicochetSpark((GAME_VECTOR*)&hitPos, 2 * GetRandomControl(), 3, 0);

View file

@ -609,9 +609,9 @@ void RomanStatueControl(short itemNumber)
{
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);
SoundEffect(GetShatterSound(mesh->staticNumber), (PHD_3DPOS*)mesh, 0);

View file

@ -139,13 +139,13 @@ void ExplosionControl(short itemNumber)
i = 0;
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);
CollidedMeshes[i]->y -= 128;
TriggerShockwave((PHD_3DPOS *) &CollidedMeshes[i]->x, 40, 176, 64, 0, 96, 128, 16, 0, 0);
CollidedMeshes[i]->y += 128;
SoundEffect(GetShatterSound(CollidedMeshes[i]->staticNumber), (PHD_3DPOS *) &CollidedMeshes[i]->x, 0);
TriggerExplosionSparks(CollidedMeshes[i]->pos.xPos, CollidedMeshes[i]->pos.yPos, CollidedMeshes[i]->pos.zPos, 3, -2, 0, item->roomNumber);
CollidedMeshes[i]->pos.yPos -= 128;
TriggerShockwave(&CollidedMeshes[i]->pos, 40, 176, 64, 0, 96, 128, 16, 0, 0);
CollidedMeshes[i]->pos.yPos += 128;
SoundEffect(GetShatterSound(CollidedMeshes[i]->staticNumber), &CollidedMeshes[i]->pos, 0);
ShatterObject(NULL, CollidedMeshes[i], -128, item->roomNumber, 0);
SmashedMeshRoom[SmashedMeshCount] = item->roomNumber;
SmashedMesh[SmashedMeshCount] = CollidedMeshes[i];

View file

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

View file

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

View file

@ -63,24 +63,24 @@ void GameScriptMeshInfo::Register(sol::state* state)
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)
{
m_mesh.x = pos.x;
m_mesh.y = pos.y;
m_mesh.z = pos.z;
m_mesh.pos.xPos = pos.x;
m_mesh.pos.yPos = pos.y;
m_mesh.pos.zPos = pos.z;
}
int GameScriptMeshInfo::GetRot() const
{
return m_mesh.yRot;
return m_mesh.pos.yRot;
}
void GameScriptMeshInfo::SetRot(int yRot)
{
m_mesh.yRot = yRot;
m_mesh.pos.yRot = yRot;
}
std::string GameScriptMeshInfo::GetName() const

View file

@ -739,7 +739,9 @@ void SayNo()
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)
return SFX_TR5_SMASH_WOOD;

View file

@ -137,7 +137,7 @@ int LoadItems()
{
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)
continue;
@ -146,7 +146,7 @@ int LoadItems()
{
int fl = floor->floor * 4;
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 ||
st->collisionBox.Z1 == 0 || st->collisionBox.Z2 == 0 ||
@ -358,7 +358,6 @@ void LoadObjects()
StaticObjects[meshID].flags = (short)ReadInt16();
StaticObjects[meshID].shatterType = (short)ReadInt16();
StaticObjects[meshID].shatterDamage = (short)ReadInt16();
StaticObjects[meshID].shatterSound = (short)ReadInt16();
}
@ -722,10 +721,12 @@ void ReadRooms()
for (int j = 0; j < numStatics; j++)
{
auto & mesh = room.mesh.emplace_back();
mesh.x = ReadInt32();
mesh.y = ReadInt32();
mesh.z = ReadInt32();
mesh.yRot = ReadUInt16();
mesh.pos.xPos = ReadInt32();
mesh.pos.yPos = ReadInt32();
mesh.pos.zPos = ReadInt32();
mesh.pos.xRot = 0;
mesh.pos.yRot = ReadUInt16();
mesh.pos.zRot = 0;
mesh.flags = ReadUInt16();
Vector3 rgb = ReadVector3();
float a = ReadFloat();

View file

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