diff --git a/TR5Main/Game/Lara/lara_one_gun.cpp b/TR5Main/Game/Lara/lara_one_gun.cpp index 2628b6940..3e2f9e9d8 100644 --- a/TR5Main/Game/Lara/lara_one_gun.cpp +++ b/TR5Main/Game/Lara/lara_one_gun.cpp @@ -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; }; diff --git a/TR5Main/Game/camera.cpp b/TR5Main/Game/camera.cpp index ee557dd1f..ec1e6ac57 100644 --- a/TR5Main/Game/camera.cpp +++ b/TR5Main/Game/camera.cpp @@ -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; diff --git a/TR5Main/Game/collide.cpp b/TR5Main/Game/collide.cpp index fda567f51..5a5c10c1f 100644 --- a/TR5Main/Game/collide.cpp +++ b/TR5Main/Game/collide.cpp @@ -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 && diff --git a/TR5Main/Game/control.cpp b/TR5Main/Game/control.cpp index 6915e651c..c3cacfa24 100644 --- a/TR5Main/Game/control.cpp +++ b/TR5Main/Game/control.cpp @@ -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)) { diff --git a/TR5Main/Game/control/volume.cpp b/TR5Main/Game/control/volume.cpp index f2ff10e2d..e0db7d014 100644 --- a/TR5Main/Game/control/volume.cpp +++ b/TR5Main/Game/control/volume.cpp @@ -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); } diff --git a/TR5Main/Game/effects/debris.cpp b/TR5Main/Game/effects/debris.cpp index 1fd714380..1fa4a3bcc 100644 --- a/TR5Main/Game/effects/debris.cpp +++ b/TR5Main/Game/effects/debris.cpp @@ -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; diff --git a/TR5Main/Game/pickup/pickup.cpp b/TR5Main/Game/pickup/pickup.cpp index 37f4268e6..b7b1fdc6b 100644 --- a/TR5Main/Game/pickup/pickup.cpp +++ b/TR5Main/Game/pickup/pickup.cpp @@ -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]; diff --git a/TR5Main/Game/room.h b/TR5Main/Game/room.h index a2f75d279..12f865af7 100644 --- a/TR5Main/Game/room.h +++ b/TR5Main/Game/room.h @@ -2,6 +2,7 @@ #include #include #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; diff --git a/TR5Main/Game/savegame.cpp b/TR5Main/Game/savegame.cpp index 1aa0d54fb..407af2a25 100644 --- a/TR5Main/Game/savegame.cpp +++ b/TR5Main/Game/savegame.cpp @@ -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; } diff --git a/TR5Main/Objects/TR4/Entity/tr4_knighttemplar.cpp b/TR5Main/Objects/TR4/Entity/tr4_knighttemplar.cpp index b0b9fdccd..3c33af873 100644 --- a/TR5Main/Objects/TR4/Entity/tr4_knighttemplar.cpp +++ b/TR5Main/Objects/TR4/Entity/tr4_knighttemplar.cpp @@ -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); diff --git a/TR5Main/Objects/TR4/Entity/tr4_skeleton.cpp b/TR5Main/Objects/TR4/Entity/tr4_skeleton.cpp index c8ccaa7e3..02f9ac50d 100644 --- a/TR5Main/Objects/TR4/Entity/tr4_skeleton.cpp +++ b/TR5Main/Objects/TR4/Entity/tr4_skeleton.cpp @@ -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); diff --git a/TR5Main/Objects/TR4/Entity/tr4_sphinx.cpp b/TR5Main/Objects/TR4/Entity/tr4_sphinx.cpp index 95f4c87d8..5c5e85984 100644 --- a/TR5Main/Objects/TR4/Entity/tr4_sphinx.cpp +++ b/TR5Main/Objects/TR4/Entity/tr4_sphinx.cpp @@ -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); diff --git a/TR5Main/Objects/TR5/Entity/tr5_gladiator.cpp b/TR5Main/Objects/TR5/Entity/tr5_gladiator.cpp index 1d6f31ed7..c0e19f276 100644 --- a/TR5Main/Objects/TR5/Entity/tr5_gladiator.cpp +++ b/TR5Main/Objects/TR5/Entity/tr5_gladiator.cpp @@ -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); diff --git a/TR5Main/Objects/TR5/Entity/tr5_gunship.cpp b/TR5Main/Objects/TR5/Entity/tr5_gunship.cpp index 843e5c460..dfe8a2683 100644 --- a/TR5Main/Objects/TR5/Entity/tr5_gunship.cpp +++ b/TR5Main/Objects/TR5/Entity/tr5_gunship.cpp @@ -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); diff --git a/TR5Main/Objects/TR5/Entity/tr5_roman_statue.cpp b/TR5Main/Objects/TR5/Entity/tr5_roman_statue.cpp index a120729ce..57443140c 100644 --- a/TR5Main/Objects/TR5/Entity/tr5_roman_statue.cpp +++ b/TR5Main/Objects/TR5/Entity/tr5_roman_statue.cpp @@ -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); diff --git a/TR5Main/Objects/TR5/Trap/tr5_explosion.cpp b/TR5Main/Objects/TR5/Trap/tr5_explosion.cpp index 4a47e19dc..2cebf235c 100644 --- a/TR5Main/Objects/TR5/Trap/tr5_explosion.cpp +++ b/TR5Main/Objects/TR5/Trap/tr5_explosion.cpp @@ -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]; diff --git a/TR5Main/Renderer/Renderer11Draw.cpp b/TR5Main/Renderer/Renderer11Draw.cpp index dc508ac6a..6b62fa34f 100644 --- a/TR5Main/Renderer/Renderer11Draw.cpp +++ b/TR5Main/Renderer/Renderer11Draw.cpp @@ -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()); diff --git a/TR5Main/Renderer/Renderer11Frame.cpp b/TR5Main/Renderer/Renderer11Frame.cpp index c1e046cfd..63a82c538 100644 --- a/TR5Main/Renderer/Renderer11Frame.cpp +++ b/TR5Main/Renderer/Renderer11Frame.cpp @@ -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); diff --git a/TR5Main/Scripting/GameScriptMeshInfo.cpp b/TR5Main/Scripting/GameScriptMeshInfo.cpp index e632a87eb..297414823 100644 --- a/TR5Main/Scripting/GameScriptMeshInfo.cpp +++ b/TR5Main/Scripting/GameScriptMeshInfo.cpp @@ -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 diff --git a/TR5Main/Sound/sound.cpp b/TR5Main/Sound/sound.cpp index d33f982fa..4f8992f6b 100644 --- a/TR5Main/Sound/sound.cpp +++ b/TR5Main/Sound/sound.cpp @@ -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; diff --git a/TR5Main/Specific/level.cpp b/TR5Main/Specific/level.cpp index d0384968b..b45548569 100644 --- a/TR5Main/Specific/level.cpp +++ b/TR5Main/Specific/level.cpp @@ -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(); diff --git a/TR5Main/Specific/setup.h b/TR5Main/Specific/setup.h index 65da7677a..edd750c84 100644 --- a/TR5Main/Specific/setup.h +++ b/TR5Main/Specific/setup.h @@ -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];