From a9c3474b1cc3ad1b337bc1dcf4f8531d8538093d Mon Sep 17 00:00:00 2001 From: Stranger1992 <84292688+Stranger1992@users.noreply.github.com> Date: Tue, 13 Aug 2024 23:19:11 +0100 Subject: [PATCH 01/17] Update CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78d54106a..2edef0e20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,10 +36,11 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Enhanced raptor behaviour and handling. - OCB 0: Classic behaviour - OCB 1: Can jump up/down up to 4 steps and jump across gaps up to 2 blocks wide. - - You must use the download version found on the TombEngine website. + - You must use this version: https://github.com/TombEngine/Resources/raw/main/Wad2%20Objects/Enemies/TEN_Raptor.wad2 * Added TR3 seal mutant. - OCB 0: Normal enemy behaviour. (TR3 RX-Tech mines level) - OCB 1: Trap like behaviour. (TR3 Antarctica level) + - You must use this version: https://github.com/TombEngine/Resources/raw/main/Wad2%20Objects/Enemies/TEN_Seal_Mutant.wad2 * Add new sound conditions: Quicksand and Underwater. - Quicksand - sound effect plays when a moveable is in quicksand. - Underwater - sound plays when the camera is submerged. From 4258b27c0c574d24374d06cf3d014c086dca96b5 Mon Sep 17 00:00:00 2001 From: Stranger1992 <84292688+Stranger1992@users.noreply.github.com> Date: Wed, 14 Aug 2024 00:52:48 +0100 Subject: [PATCH 02/17] Changelog typos --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2edef0e20..674b3fdee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,9 +30,9 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): ### Features/Amendments * Changed Rome Hammer to not hurt player whilst deactivated. * Changed Statue with blade damage, from 20 to 200. -* Enhaced Rolling Spindle detection to avoid them going down through pits. -* Enhaced Sentry Guns, with a new ItemFlags[3], to contain the ID of the inventory item that deactivates the sentry guns ( by default PUZZLE_ITEM5 ) -* Enhaced Dart Emitter, with a new ItemFlags[0], to contain the number of frames between shots ( by default 32 in dart emitter, and 24 in homing dar emitter ). +* Enhanced Rolling Spindle detection to avoid them going down through pits. +* Enhanced Sentry Guns, with a new ItemFlags[3], to contain the ID of the inventory item that deactivates the sentry guns ( by default PUZZLE_ITEM5 ) +* Enhanced Dart Emitter, with a new ItemFlags[0], to contain the number of frames between shots ( by default 32 in dart emitter, and 24 in homing dar emitter ). * Enhanced raptor behaviour and handling. - OCB 0: Classic behaviour - OCB 1: Can jump up/down up to 4 steps and jump across gaps up to 2 blocks wide. From 079a2bfc001dada523b401d1aae98cc60c24981e Mon Sep 17 00:00:00 2001 From: Sezz Date: Wed, 14 Aug 2024 16:09:42 +1000 Subject: [PATCH 03/17] Correct config --- TombEngine/Specific/configuration.cpp | 4 ++-- TombEngine/Specific/configuration.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/TombEngine/Specific/configuration.cpp b/TombEngine/Specific/configuration.cpp index 93945202f..07aaba43a 100644 --- a/TombEngine/Specific/configuration.cpp +++ b/TombEngine/Specific/configuration.cpp @@ -257,7 +257,7 @@ bool SaveConfiguration() // Set Input keys. if (SetDWORDRegKey(inputKey, REGKEY_MOUSE_SENSITIVITY, g_Configuration.MouseSensitivity) != ERROR_SUCCESS || - SetDWORDRegKey(inputKey, REGKEY_ENABLE_MENU_OPTION_LOOPING, (int)g_Configuration.MenuOptionLoopingMode) != ERROR_SUCCESS) + SetDWORDRegKey(inputKey, REGKEY_MENU_OPTION_LOOPING_MODE, (int)g_Configuration.MenuOptionLoopingMode) != ERROR_SUCCESS) { RegCloseKey(rootKey); RegCloseKey(graphicsKey); @@ -451,7 +451,7 @@ bool LoadConfiguration() if (RegOpenKeyExA(rootKey, REGKEY_INPUT, 0, KEY_READ, &inputKey) == ERROR_SUCCESS) { if (GetDWORDRegKey(inputKey, REGKEY_MOUSE_SENSITIVITY, &mouseSensitivity, GameConfiguration::DEFAULT_MOUSE_SENSITIVITY) != ERROR_SUCCESS || - GetDWORDRegKey(inputKey, REGKEY_ENABLE_MENU_OPTION_LOOPING, &menuOptionLoopingMode, (DWORD)MenuOptionLoopingMode::SaveLoadOnly) != ERROR_SUCCESS) + GetDWORDRegKey(inputKey, REGKEY_MENU_OPTION_LOOPING_MODE, &menuOptionLoopingMode, (DWORD)MenuOptionLoopingMode::SaveLoadOnly) != ERROR_SUCCESS) { RegCloseKey(rootKey); RegCloseKey(graphicsKey); diff --git a/TombEngine/Specific/configuration.h b/TombEngine/Specific/configuration.h index 0ab9c10ee..fadfc60ae 100644 --- a/TombEngine/Specific/configuration.h +++ b/TombEngine/Specific/configuration.h @@ -45,8 +45,8 @@ constexpr auto REGKEY_ENABLE_THUMBSTICK_CAMERA = "EnableThumbstickCamera"; // Input keys -constexpr auto REGKEY_MOUSE_SENSITIVITY = "MouseSensitivity"; -constexpr auto REGKEY_ENABLE_MENU_OPTION_LOOPING = "EnableMenuOptionLooping"; +constexpr auto REGKEY_MOUSE_SENSITIVITY = "MouseSensitivity"; +constexpr auto REGKEY_MENU_OPTION_LOOPING_MODE = "MenuOptionLoopingMode"; enum class MenuOptionLoopingMode { From dcfdae10da61fce00bc48f088277273e7a6d6b1d Mon Sep 17 00:00:00 2001 From: Sezz Date: Wed, 14 Aug 2024 17:50:19 +1000 Subject: [PATCH 04/17] lara -> player in GUI --- TombEngine/Game/GuiObjects.cpp | 498 ++++++++++++++++----------------- TombEngine/Game/gui.cpp | 246 ++++++++-------- 2 files changed, 372 insertions(+), 372 deletions(-) diff --git a/TombEngine/Game/GuiObjects.cpp b/TombEngine/Game/GuiObjects.cpp index 62cccff81..0967e3a00 100644 --- a/TombEngine/Game/GuiObjects.cpp +++ b/TombEngine/Game/GuiObjects.cpp @@ -331,21 +331,21 @@ namespace TEN::Gui void CombineRevolverLasersight(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); if (flag) { - lara->Inventory.HasLasersight = true; - lara->Weapons[(int)LaraWeaponType::Revolver].HasLasersight = false; + player.Inventory.HasLasersight = true; + player.Weapons[(int)LaraWeaponType::Revolver].HasLasersight = false; } else { - lara->Inventory.HasLasersight = false; - lara->Weapons[(int)LaraWeaponType::Revolver].HasLasersight = true; + player.Inventory.HasLasersight = false; + player.Weapons[(int)LaraWeaponType::Revolver].HasLasersight = true; } - if (lara->Control.HandStatus != HandStatus::Free && - lara->Control.Weapon.GunType == LaraWeaponType::Revolver) + if (player.Control.HandStatus != HandStatus::Free && + player.Control.Weapon.GunType == LaraWeaponType::Revolver) { UndrawPistolMesh(*item, LaraWeaponType::Revolver, true); DrawPistolMeshes(*item, LaraWeaponType::Revolver); @@ -354,21 +354,21 @@ namespace TEN::Gui void CombineCrossbowLasersight(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); if (flag) { - lara->Inventory.HasLasersight = true; - lara->Weapons[(int)LaraWeaponType::Crossbow].HasLasersight = false; + player.Inventory.HasLasersight = true; + player.Weapons[(int)LaraWeaponType::Crossbow].HasLasersight = false; } else { - lara->Inventory.HasLasersight = false; - lara->Weapons[(int)LaraWeaponType::Crossbow].HasLasersight = true; + player.Inventory.HasLasersight = false; + player.Weapons[(int)LaraWeaponType::Crossbow].HasLasersight = true; } - if (lara->Control.HandStatus != HandStatus::Free && - lara->Control.Weapon.GunType == LaraWeaponType::Crossbow) + if (player.Control.HandStatus != HandStatus::Free && + player.Control.Weapon.GunType == LaraWeaponType::Crossbow) { UndrawShotgunMeshes(*item, LaraWeaponType::Crossbow); DrawShotgunMeshes(*item, LaraWeaponType::Crossbow); @@ -377,21 +377,21 @@ namespace TEN::Gui void CombineHKLasersight(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); if (flag) { - lara->Inventory.HasLasersight = true; - lara->Weapons[(int)LaraWeaponType::HK].HasLasersight = false; + player.Inventory.HasLasersight = true; + player.Weapons[(int)LaraWeaponType::HK].HasLasersight = false; } else { - lara->Inventory.HasLasersight = false; - lara->Weapons[(int)LaraWeaponType::HK].HasLasersight = true; + player.Inventory.HasLasersight = false; + player.Weapons[(int)LaraWeaponType::HK].HasLasersight = true; } - if (lara->Control.HandStatus != HandStatus::Free && - lara->Control.Weapon.GunType == LaraWeaponType::HK) + if (player.Control.HandStatus != HandStatus::Free && + player.Control.Weapon.GunType == LaraWeaponType::HK) { UndrawShotgunMeshes(*item, LaraWeaponType::HK); DrawShotgunMeshes(*item, LaraWeaponType::HK); @@ -400,514 +400,514 @@ namespace TEN::Gui void CombinePuzzleItem1(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.PuzzlesCombo[0] = false; - lara->Inventory.PuzzlesCombo[1] = false; - lara->Inventory.Puzzles[0] = true; + player.Inventory.PuzzlesCombo[0] = false; + player.Inventory.PuzzlesCombo[1] = false; + player.Inventory.Puzzles[0] = true; } void CombinePuzzleItem2(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.PuzzlesCombo[2] = false; - lara->Inventory.PuzzlesCombo[3] = false; - lara->Inventory.Puzzles[1] = true; + player.Inventory.PuzzlesCombo[2] = false; + player.Inventory.PuzzlesCombo[3] = false; + player.Inventory.Puzzles[1] = true; } void CombinePuzzleItem3(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.PuzzlesCombo[4] = false; - lara->Inventory.PuzzlesCombo[5] = false; - lara->Inventory.Puzzles[2] = true; + player.Inventory.PuzzlesCombo[4] = false; + player.Inventory.PuzzlesCombo[5] = false; + player.Inventory.Puzzles[2] = true; } void CombinePuzzleItem4(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.PuzzlesCombo[6] = false; - lara->Inventory.PuzzlesCombo[7] = false; - lara->Inventory.Puzzles[3] = true; + player.Inventory.PuzzlesCombo[6] = false; + player.Inventory.PuzzlesCombo[7] = false; + player.Inventory.Puzzles[3] = true; } void CombinePuzzleItem5(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.PuzzlesCombo[8] = false; - lara->Inventory.PuzzlesCombo[9] = false; - lara->Inventory.Puzzles[4] = true; + player.Inventory.PuzzlesCombo[8] = false; + player.Inventory.PuzzlesCombo[9] = false; + player.Inventory.Puzzles[4] = true; } void CombinePuzzleItem6(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.PuzzlesCombo[10] = false; - lara->Inventory.PuzzlesCombo[11] = false; - lara->Inventory.Puzzles[5] = true; + player.Inventory.PuzzlesCombo[10] = false; + player.Inventory.PuzzlesCombo[11] = false; + player.Inventory.Puzzles[5] = true; } void CombinePuzzleItem7(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.PuzzlesCombo[12] = false; - lara->Inventory.PuzzlesCombo[13] = false; - lara->Inventory.Puzzles[6] = true; + player.Inventory.PuzzlesCombo[12] = false; + player.Inventory.PuzzlesCombo[13] = false; + player.Inventory.Puzzles[6] = true; } void CombinePuzzleItem8(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.PuzzlesCombo[14] = false; - lara->Inventory.PuzzlesCombo[15] = false; - lara->Inventory.Puzzles[7] = true; + player.Inventory.PuzzlesCombo[14] = false; + player.Inventory.PuzzlesCombo[15] = false; + player.Inventory.Puzzles[7] = true; } void CombinePuzzleItem9(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.PuzzlesCombo[16] = false; - lara->Inventory.PuzzlesCombo[17] = false; - lara->Inventory.Puzzles[8] = true; + player.Inventory.PuzzlesCombo[16] = false; + player.Inventory.PuzzlesCombo[17] = false; + player.Inventory.Puzzles[8] = true; } void CombinePuzzleItem10(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.PuzzlesCombo[18] = false; - lara->Inventory.PuzzlesCombo[19] = false; - lara->Inventory.Puzzles[9] = true; + player.Inventory.PuzzlesCombo[18] = false; + player.Inventory.PuzzlesCombo[19] = false; + player.Inventory.Puzzles[9] = true; } void CombinePuzzleItem11(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.PuzzlesCombo[20] = false; - lara->Inventory.PuzzlesCombo[21] = false; - lara->Inventory.Puzzles[10] = true; + player.Inventory.PuzzlesCombo[20] = false; + player.Inventory.PuzzlesCombo[21] = false; + player.Inventory.Puzzles[10] = true; } void CombinePuzzleItem12(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.PuzzlesCombo[22] = false; - lara->Inventory.PuzzlesCombo[23] = false; - lara->Inventory.Puzzles[11] = true; + player.Inventory.PuzzlesCombo[22] = false; + player.Inventory.PuzzlesCombo[23] = false; + player.Inventory.Puzzles[11] = true; } void CombinePuzzleItem13(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.PuzzlesCombo[24] = false; - lara->Inventory.PuzzlesCombo[25] = false; - lara->Inventory.Puzzles[12] = true; + player.Inventory.PuzzlesCombo[24] = false; + player.Inventory.PuzzlesCombo[25] = false; + player.Inventory.Puzzles[12] = true; } void CombinePuzzleItem14(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.PuzzlesCombo[26] = false; - lara->Inventory.PuzzlesCombo[27] = false; - lara->Inventory.Puzzles[13] = true; + player.Inventory.PuzzlesCombo[26] = false; + player.Inventory.PuzzlesCombo[27] = false; + player.Inventory.Puzzles[13] = true; } void CombinePuzzleItem15(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.PuzzlesCombo[28] = false; - lara->Inventory.PuzzlesCombo[29] = false; - lara->Inventory.Puzzles[14] = true; + player.Inventory.PuzzlesCombo[28] = false; + player.Inventory.PuzzlesCombo[29] = false; + player.Inventory.Puzzles[14] = true; } void CombinePuzzleItem16(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.PuzzlesCombo[30] = false; - lara->Inventory.PuzzlesCombo[31] = false; - lara->Inventory.Puzzles[15] = true; + player.Inventory.PuzzlesCombo[30] = false; + player.Inventory.PuzzlesCombo[31] = false; + player.Inventory.Puzzles[15] = true; } void CombineKeyItem1(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Keys[0] = true; - lara->Inventory.KeysCombo[0] = false; - lara->Inventory.KeysCombo[1] = false; + player.Inventory.Keys[0] = true; + player.Inventory.KeysCombo[0] = false; + player.Inventory.KeysCombo[1] = false; } void CombineKeyItem2(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Keys[1] = true; - lara->Inventory.KeysCombo[2] = false; - lara->Inventory.KeysCombo[3] = false; + player.Inventory.Keys[1] = true; + player.Inventory.KeysCombo[2] = false; + player.Inventory.KeysCombo[3] = false; } void CombineKeyItem3(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Keys[2] = true; - lara->Inventory.KeysCombo[4] = false; - lara->Inventory.KeysCombo[5] = false; + player.Inventory.Keys[2] = true; + player.Inventory.KeysCombo[4] = false; + player.Inventory.KeysCombo[5] = false; } void CombineKeyItem4(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Keys[3] = true; - lara->Inventory.KeysCombo[6] = false; - lara->Inventory.KeysCombo[7] = false; + player.Inventory.Keys[3] = true; + player.Inventory.KeysCombo[6] = false; + player.Inventory.KeysCombo[7] = false; } void CombineKeyItem5(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Keys[4] = true; - lara->Inventory.KeysCombo[8] = false; - lara->Inventory.KeysCombo[9] = false; + player.Inventory.Keys[4] = true; + player.Inventory.KeysCombo[8] = false; + player.Inventory.KeysCombo[9] = false; } void CombineKeyItem6(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Keys[5] = true; - lara->Inventory.KeysCombo[10] = false; - lara->Inventory.KeysCombo[11] = false; + player.Inventory.Keys[5] = true; + player.Inventory.KeysCombo[10] = false; + player.Inventory.KeysCombo[11] = false; } void CombineKeyItem7(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Keys[6] = true; - lara->Inventory.KeysCombo[12] = false; - lara->Inventory.KeysCombo[13] = false; + player.Inventory.Keys[6] = true; + player.Inventory.KeysCombo[12] = false; + player.Inventory.KeysCombo[13] = false; } void CombineKeyItem8(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Keys[7] = true; - lara->Inventory.KeysCombo[14] = false; - lara->Inventory.KeysCombo[15] = false; + player.Inventory.Keys[7] = true; + player.Inventory.KeysCombo[14] = false; + player.Inventory.KeysCombo[15] = false; } void CombineKeyItem9(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Keys[8] = true; - lara->Inventory.KeysCombo[16] = false; - lara->Inventory.KeysCombo[17] = false; + player.Inventory.Keys[8] = true; + player.Inventory.KeysCombo[16] = false; + player.Inventory.KeysCombo[17] = false; } void CombineKeyItem10(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Keys[9] = true; - lara->Inventory.KeysCombo[18] = false; - lara->Inventory.KeysCombo[19] = false; + player.Inventory.Keys[9] = true; + player.Inventory.KeysCombo[18] = false; + player.Inventory.KeysCombo[19] = false; } void CombineKeyItem11(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Keys[10] = true; - lara->Inventory.KeysCombo[20] = false; - lara->Inventory.KeysCombo[21] = false; + player.Inventory.Keys[10] = true; + player.Inventory.KeysCombo[20] = false; + player.Inventory.KeysCombo[21] = false; } void CombineKeyItem12(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Keys[11] = true; - lara->Inventory.KeysCombo[22] = false; - lara->Inventory.KeysCombo[23] = false; + player.Inventory.Keys[11] = true; + player.Inventory.KeysCombo[22] = false; + player.Inventory.KeysCombo[23] = false; } void CombineKeyItem13(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Keys[12] = true; - lara->Inventory.KeysCombo[24] = false; - lara->Inventory.KeysCombo[25] = false; + player.Inventory.Keys[12] = true; + player.Inventory.KeysCombo[24] = false; + player.Inventory.KeysCombo[25] = false; } void CombineKeyItem14(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Keys[13] = true; - lara->Inventory.KeysCombo[26] = false; - lara->Inventory.KeysCombo[27] = false; + player.Inventory.Keys[13] = true; + player.Inventory.KeysCombo[26] = false; + player.Inventory.KeysCombo[27] = false; } void CombineKeyItem15(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Keys[14] = true; - lara->Inventory.KeysCombo[28] = false; - lara->Inventory.KeysCombo[29] = false; + player.Inventory.Keys[14] = true; + player.Inventory.KeysCombo[28] = false; + player.Inventory.KeysCombo[29] = false; } void CombineKeyItem16(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Keys[15] = true; - lara->Inventory.KeysCombo[30] = false; - lara->Inventory.KeysCombo[31] = false; + player.Inventory.Keys[15] = true; + player.Inventory.KeysCombo[30] = false; + player.Inventory.KeysCombo[31] = false; } void CombinePickupItem1(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Pickups[0] = true; - lara->Inventory.PickupsCombo[0] = false; - lara->Inventory.PickupsCombo[1] = false; + player.Inventory.Pickups[0] = true; + player.Inventory.PickupsCombo[0] = false; + player.Inventory.PickupsCombo[1] = false; } void CombinePickupItem2(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Pickups[1] = true; - lara->Inventory.PickupsCombo[2] = false; - lara->Inventory.PickupsCombo[3] = false; + player.Inventory.Pickups[1] = true; + player.Inventory.PickupsCombo[2] = false; + player.Inventory.PickupsCombo[3] = false; } void CombinePickupItem3(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Pickups[2] = true; - lara->Inventory.PickupsCombo[4] = false; - lara->Inventory.PickupsCombo[5] = false; + player.Inventory.Pickups[2] = true; + player.Inventory.PickupsCombo[4] = false; + player.Inventory.PickupsCombo[5] = false; } void CombinePickupItem4(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Pickups[3] = true; - lara->Inventory.PickupsCombo[6] = false; - lara->Inventory.PickupsCombo[7] = false; + player.Inventory.Pickups[3] = true; + player.Inventory.PickupsCombo[6] = false; + player.Inventory.PickupsCombo[7] = false; } void CombinePickupItem5(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Pickups[4] = true; - lara->Inventory.PickupsCombo[8] = false; - lara->Inventory.PickupsCombo[9] = false; + player.Inventory.Pickups[4] = true; + player.Inventory.PickupsCombo[8] = false; + player.Inventory.PickupsCombo[9] = false; } void CombinePickupItem6(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Pickups[5] = true; - lara->Inventory.PickupsCombo[10] = false; - lara->Inventory.PickupsCombo[11] = false; + player.Inventory.Pickups[5] = true; + player.Inventory.PickupsCombo[10] = false; + player.Inventory.PickupsCombo[11] = false; } void CombinePickupItem7(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Pickups[6] = true; - lara->Inventory.PickupsCombo[12] = false; - lara->Inventory.PickupsCombo[13] = false; + player.Inventory.Pickups[6] = true; + player.Inventory.PickupsCombo[12] = false; + player.Inventory.PickupsCombo[13] = false; } void CombinePickupItem8(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Pickups[7] = true; - lara->Inventory.PickupsCombo[14] = false; - lara->Inventory.PickupsCombo[15] = false; + player.Inventory.Pickups[7] = true; + player.Inventory.PickupsCombo[14] = false; + player.Inventory.PickupsCombo[15] = false; } void CombinePickupItem9(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Pickups[8] = true; - lara->Inventory.PickupsCombo[16] = false; - lara->Inventory.PickupsCombo[17] = false; + player.Inventory.Pickups[8] = true; + player.Inventory.PickupsCombo[16] = false; + player.Inventory.PickupsCombo[17] = false; } void CombinePickupItem10(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Pickups[9] = true; - lara->Inventory.PickupsCombo[18] = false; - lara->Inventory.PickupsCombo[19] = false; + player.Inventory.Pickups[9] = true; + player.Inventory.PickupsCombo[18] = false; + player.Inventory.PickupsCombo[19] = false; } void CombinePickupItem11(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Pickups[10] = true; - lara->Inventory.PickupsCombo[20] = false; - lara->Inventory.PickupsCombo[21] = false; + player.Inventory.Pickups[10] = true; + player.Inventory.PickupsCombo[20] = false; + player.Inventory.PickupsCombo[21] = false; } void CombinePickupItem12(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Pickups[11] = true; - lara->Inventory.PickupsCombo[22] = false; - lara->Inventory.PickupsCombo[23] = false; + player.Inventory.Pickups[11] = true; + player.Inventory.PickupsCombo[22] = false; + player.Inventory.PickupsCombo[23] = false; } void CombinePickupItem13(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Pickups[12] = true; - lara->Inventory.PickupsCombo[24] = false; - lara->Inventory.PickupsCombo[25] = false; + player.Inventory.Pickups[12] = true; + player.Inventory.PickupsCombo[24] = false; + player.Inventory.PickupsCombo[25] = false; } void CombinePickupItem14(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Pickups[13] = true; - lara->Inventory.PickupsCombo[26] = false; - lara->Inventory.PickupsCombo[27] = false; + player.Inventory.Pickups[13] = true; + player.Inventory.PickupsCombo[26] = false; + player.Inventory.PickupsCombo[27] = false; } void CombinePickupItem15(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Pickups[14] = true; - lara->Inventory.PickupsCombo[28] = false; - lara->Inventory.PickupsCombo[29] = false; + player.Inventory.Pickups[14] = true; + player.Inventory.PickupsCombo[28] = false; + player.Inventory.PickupsCombo[29] = false; } void CombinePickupItem16(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Pickups[15] = true; - lara->Inventory.PickupsCombo[30] = false; - lara->Inventory.PickupsCombo[31] = false; + player.Inventory.Pickups[15] = true; + player.Inventory.PickupsCombo[30] = false; + player.Inventory.PickupsCombo[31] = false; } void CombineExamine1(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Examines[0] = true; - lara->Inventory.ExaminesCombo[0] = false; - lara->Inventory.ExaminesCombo[1] = false; + player.Inventory.Examines[0] = true; + player.Inventory.ExaminesCombo[0] = false; + player.Inventory.ExaminesCombo[1] = false; } void CombineExamine2(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Examines[1] = true; - lara->Inventory.ExaminesCombo[2] = false; - lara->Inventory.ExaminesCombo[3] = false; + player.Inventory.Examines[1] = true; + player.Inventory.ExaminesCombo[2] = false; + player.Inventory.ExaminesCombo[3] = false; } void CombineExamine3(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Examines[2] = true; - lara->Inventory.ExaminesCombo[4] = false; - lara->Inventory.ExaminesCombo[5] = false; + player.Inventory.Examines[2] = true; + player.Inventory.ExaminesCombo[4] = false; + player.Inventory.ExaminesCombo[5] = false; } void CombineExamine4(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Examines[3] = true; - lara->Inventory.ExaminesCombo[6] = false; - lara->Inventory.ExaminesCombo[7] = false; + player.Inventory.Examines[3] = true; + player.Inventory.ExaminesCombo[6] = false; + player.Inventory.ExaminesCombo[7] = false; } void CombineExamine5(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Examines[4] = true; - lara->Inventory.ExaminesCombo[8] = false; - lara->Inventory.ExaminesCombo[9] = false; + player.Inventory.Examines[4] = true; + player.Inventory.ExaminesCombo[8] = false; + player.Inventory.ExaminesCombo[9] = false; } void CombineExamine6(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Examines[5] = true; - lara->Inventory.ExaminesCombo[10] = false; - lara->Inventory.ExaminesCombo[11] = false; + player.Inventory.Examines[5] = true; + player.Inventory.ExaminesCombo[10] = false; + player.Inventory.ExaminesCombo[11] = false; } void CombineExamine7(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Examines[6] = true; - lara->Inventory.ExaminesCombo[12] = false; - lara->Inventory.ExaminesCombo[13] = false; + player.Inventory.Examines[6] = true; + player.Inventory.ExaminesCombo[12] = false; + player.Inventory.ExaminesCombo[13] = false; } void CombineExamine8(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.Examines[7] = true; - lara->Inventory.ExaminesCombo[14] = false; - lara->Inventory.ExaminesCombo[15] = false; + player.Inventory.Examines[7] = true; + player.Inventory.ExaminesCombo[14] = false; + player.Inventory.ExaminesCombo[15] = false; } void CombineClockWorkBeetle(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - lara->Inventory.BeetleComponents |= BEETLECOMP_FLAG_BEETLE; // Get beetle. - lara->Inventory.BeetleComponents &= BEETLECOMP_FLAG_COMBO_1; // Remove combo 1. - lara->Inventory.BeetleComponents &= BEETLECOMP_FLAG_COMBO_2; // Remove combo 2. + player.Inventory.BeetleComponents |= BEETLECOMP_FLAG_BEETLE; // Get beetle. + player.Inventory.BeetleComponents &= BEETLECOMP_FLAG_COMBO_1; // Remove combo 1. + player.Inventory.BeetleComponents &= BEETLECOMP_FLAG_COMBO_2; // Remove combo 2. } } diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp index 72b675237..819c3f453 100644 --- a/TombEngine/Game/gui.cpp +++ b/TombEngine/Game/gui.cpp @@ -1503,7 +1503,7 @@ namespace TEN::Gui void GuiController::ConstructObjectList(ItemInfo* item) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); Rings[(int)RingTypes::Inventory].NumObjectsInList = 0; @@ -1519,19 +1519,19 @@ namespace TEN::Gui if (g_GameFlow->GetLevel(CurrentLevel)->GetLaraType() != LaraType::Young) { - if (lara->Weapons[(int)LaraWeaponType::Pistol].Present) + if (player.Weapons[(int)LaraWeaponType::Pistol].Present) InsertObjectIntoList(INV_OBJECT_PISTOLS); else if (Ammo.AmountPistolsAmmo) InsertObjectIntoList(INV_OBJECT_PISTOLS_AMMO); - if (lara->Weapons[(int)LaraWeaponType::Uzi].Present) + if (player.Weapons[(int)LaraWeaponType::Uzi].Present) InsertObjectIntoList(INV_OBJECT_UZIS); else if (Ammo.AmountUziAmmo) InsertObjectIntoList(INV_OBJECT_UZI_AMMO); - if (lara->Weapons[(int)LaraWeaponType::Revolver].Present) + if (player.Weapons[(int)LaraWeaponType::Revolver].Present) { - if (lara->Weapons[(int)LaraWeaponType::Revolver].HasLasersight) + if (player.Weapons[(int)LaraWeaponType::Revolver].HasLasersight) InsertObjectIntoList(INV_OBJECT_REVOLVER_LASER); else InsertObjectIntoList(INV_OBJECT_REVOLVER); @@ -1539,11 +1539,11 @@ namespace TEN::Gui else if (Ammo.AmountRevolverAmmo) InsertObjectIntoList(INV_OBJECT_REVOLVER_AMMO); - if (lara->Weapons[(int)LaraWeaponType::Shotgun].Present) + if (player.Weapons[(int)LaraWeaponType::Shotgun].Present) { InsertObjectIntoList(INV_OBJECT_SHOTGUN); - if (lara->Weapons[(int)LaraWeaponType::Shotgun].SelectedAmmo == WeaponAmmoType::Ammo2) + if (player.Weapons[(int)LaraWeaponType::Shotgun].SelectedAmmo == WeaponAmmoType::Ammo2) Ammo.CurrentShotGunAmmoType = 1; } else @@ -1555,33 +1555,33 @@ namespace TEN::Gui InsertObjectIntoList(INV_OBJECT_SHOTGUN_AMMO_2); } - if (lara->Weapons[(int)LaraWeaponType::HK].Present) + if (player.Weapons[(int)LaraWeaponType::HK].Present) { - if (lara->Weapons[(int)LaraWeaponType::HK].HasLasersight) + if (player.Weapons[(int)LaraWeaponType::HK].HasLasersight) InsertObjectIntoList(INV_OBJECT_HK_LASERSIGHT); else InsertObjectIntoList(INV_OBJECT_HK); - if (lara->Weapons[(int)LaraWeaponType::HK].WeaponMode == LaraWeaponTypeCarried::WTYPE_AMMO_2) + if (player.Weapons[(int)LaraWeaponType::HK].WeaponMode == LaraWeaponTypeCarried::WTYPE_AMMO_2) Ammo.CurrentHKAmmoType = 1; - if (lara->Weapons[(int)LaraWeaponType::HK].WeaponMode == LaraWeaponTypeCarried::WTYPE_AMMO_3) + if (player.Weapons[(int)LaraWeaponType::HK].WeaponMode == LaraWeaponTypeCarried::WTYPE_AMMO_3) Ammo.CurrentHKAmmoType = 2; } else if (Ammo.AmountHKAmmo1) InsertObjectIntoList(INV_OBJECT_HK_AMMO); - if (lara->Weapons[(int)LaraWeaponType::Crossbow].Present) + if (player.Weapons[(int)LaraWeaponType::Crossbow].Present) { - if (lara->Weapons[(int)LaraWeaponType::Crossbow].HasLasersight) + if (player.Weapons[(int)LaraWeaponType::Crossbow].HasLasersight) InsertObjectIntoList(INV_OBJECT_CROSSBOW_LASER); else InsertObjectIntoList(INV_OBJECT_CROSSBOW); - if (lara->Weapons[(int)LaraWeaponType::Crossbow].SelectedAmmo == WeaponAmmoType::Ammo2) + if (player.Weapons[(int)LaraWeaponType::Crossbow].SelectedAmmo == WeaponAmmoType::Ammo2) Ammo.CurrentCrossBowAmmoType = 1; - if (lara->Weapons[(int)LaraWeaponType::Crossbow].SelectedAmmo == WeaponAmmoType::Ammo3) + if (player.Weapons[(int)LaraWeaponType::Crossbow].SelectedAmmo == WeaponAmmoType::Ammo3) Ammo.CurrentCrossBowAmmoType = 2; } else @@ -1596,14 +1596,14 @@ namespace TEN::Gui InsertObjectIntoList(INV_OBJECT_CROSSBOW_AMMO_3); } - if (lara->Weapons[(int)LaraWeaponType::GrenadeLauncher].Present) + if (player.Weapons[(int)LaraWeaponType::GrenadeLauncher].Present) { InsertObjectIntoList(INV_OBJECT_GRENADE_LAUNCHER); - if (lara->Weapons[(int)LaraWeaponType::GrenadeLauncher].SelectedAmmo == WeaponAmmoType::Ammo2) + if (player.Weapons[(int)LaraWeaponType::GrenadeLauncher].SelectedAmmo == WeaponAmmoType::Ammo2) Ammo.CurrentGrenadeGunAmmoType = 1; - if (lara->Weapons[(int)LaraWeaponType::GrenadeLauncher].SelectedAmmo == WeaponAmmoType::Ammo3) + if (player.Weapons[(int)LaraWeaponType::GrenadeLauncher].SelectedAmmo == WeaponAmmoType::Ammo3) Ammo.CurrentGrenadeGunAmmoType = 2; } else @@ -1618,107 +1618,107 @@ namespace TEN::Gui InsertObjectIntoList(INV_OBJECT_GRENADE_AMMO_3); } - if (lara->Weapons[(int)LaraWeaponType::RocketLauncher].Present) + if (player.Weapons[(int)LaraWeaponType::RocketLauncher].Present) InsertObjectIntoList(INV_OBJECT_ROCKET_LAUNCHER); else if (Ammo.AmountRocketsAmmo) InsertObjectIntoList(INV_OBJECT_ROCKET_AMMO); - if (lara->Weapons[(int)LaraWeaponType::HarpoonGun].Present) + if (player.Weapons[(int)LaraWeaponType::HarpoonGun].Present) InsertObjectIntoList(INV_OBJECT_HARPOON_GUN); else if (Ammo.AmountHarpoonAmmo) InsertObjectIntoList(INV_OBJECT_HARPOON_AMMO); - if (lara->Inventory.HasLasersight) + if (player.Inventory.HasLasersight) InsertObjectIntoList(INV_OBJECT_LASERSIGHT); - if (lara->Inventory.HasSilencer) + if (player.Inventory.HasSilencer) InsertObjectIntoList(INV_OBJECT_SILENCER); - if (lara->Inventory.HasBinoculars) + if (player.Inventory.HasBinoculars) InsertObjectIntoList(INV_OBJECT_BINOCULARS); - if (lara->Inventory.TotalFlares) + if (player.Inventory.TotalFlares) InsertObjectIntoList(INV_OBJECT_FLARES); } InsertObjectIntoList(INV_OBJECT_TIMEX);//every level has the timex? what's a good way to check?! - if (lara->Inventory.TotalSmallMedipacks) + if (player.Inventory.TotalSmallMedipacks) InsertObjectIntoList(INV_OBJECT_SMALL_MEDIPACK); - if (lara->Inventory.TotalLargeMedipacks) + if (player.Inventory.TotalLargeMedipacks) InsertObjectIntoList(INV_OBJECT_LARGE_MEDIPACK); - if (lara->Inventory.HasCrowbar) + if (player.Inventory.HasCrowbar) InsertObjectIntoList(INV_OBJECT_CROWBAR); - if (lara->Inventory.BeetleComponents) + if (player.Inventory.BeetleComponents) { - if (lara->Inventory.BeetleComponents & BEETLECOMP_FLAG_BEETLE) + if (player.Inventory.BeetleComponents & BEETLECOMP_FLAG_BEETLE) InsertObjectIntoList(INV_OBJECT_BEETLE); - if (lara->Inventory.BeetleComponents & BEETLECOMP_FLAG_COMBO_1) + if (player.Inventory.BeetleComponents & BEETLECOMP_FLAG_COMBO_1) InsertObjectIntoList(INV_OBJECT_BEETLE_PART1); - if (lara->Inventory.BeetleComponents & BEETLECOMP_FLAG_COMBO_2) + if (player.Inventory.BeetleComponents & BEETLECOMP_FLAG_COMBO_2) InsertObjectIntoList(INV_OBJECT_BEETLE_PART2); } - if (lara->Inventory.SmallWaterskin) - InsertObjectIntoList((lara->Inventory.SmallWaterskin - 1) + INV_OBJECT_SMALL_WATERSKIN_EMPTY); + if (player.Inventory.SmallWaterskin) + InsertObjectIntoList((player.Inventory.SmallWaterskin - 1) + INV_OBJECT_SMALL_WATERSKIN_EMPTY); - if (lara->Inventory.BigWaterskin) - InsertObjectIntoList((lara->Inventory.BigWaterskin - 1) + INV_OBJECT_BIG_WATERSKIN_EMPTY); + if (player.Inventory.BigWaterskin) + InsertObjectIntoList((player.Inventory.BigWaterskin - 1) + INV_OBJECT_BIG_WATERSKIN_EMPTY); for (int i = 0; i < NUM_PUZZLES; i++) { - if (lara->Inventory.Puzzles[i]) + if (player.Inventory.Puzzles[i]) InsertObjectIntoList(INV_OBJECT_PUZZLE1 + i); } for (int i = 0; i < NUM_PUZZLE_PIECES; i++) { - if (lara->Inventory.PuzzlesCombo[i]) + if (player.Inventory.PuzzlesCombo[i]) InsertObjectIntoList(INV_OBJECT_PUZZLE1_COMBO1 + i); } for (int i = 0; i < NUM_KEYS; i++) { - if (lara->Inventory.Keys[i]) + if (player.Inventory.Keys[i]) InsertObjectIntoList(INV_OBJECT_KEY1 + i); } for (int i = 0; i < NUM_KEY_PIECES; i++) { - if (lara->Inventory.KeysCombo[i]) + if (player.Inventory.KeysCombo[i]) InsertObjectIntoList(INV_OBJECT_KEY1_COMBO1 + i); } for (int i = 0; i < NUM_PICKUPS; i++) { - if (lara->Inventory.Pickups[i]) + if (player.Inventory.Pickups[i]) InsertObjectIntoList(INV_OBJECT_PICKUP1 + i); } for (int i = 0; i < NUM_PICKUPS_PIECES; i++) { - if (lara->Inventory.PickupsCombo[i]) + if (player.Inventory.PickupsCombo[i]) InsertObjectIntoList(INV_OBJECT_PICKUP1_COMBO1 + i); } for (int i = 0; i < NUM_EXAMINES; i++) { - if (lara->Inventory.Examines[i]) + if (player.Inventory.Examines[i]) InsertObjectIntoList(INV_OBJECT_EXAMINE1 + i); } for (int i = 0; i < NUM_EXAMINES_PIECES; i++) { - if (lara->Inventory.ExaminesCombo[i]) + if (player.Inventory.ExaminesCombo[i]) InsertObjectIntoList(INV_OBJECT_EXAMINE1_COMBO1 + i); } - if (lara->Inventory.Diary.Present) + if (player.Inventory.Diary.Present) InsertObjectIntoList(INV_OBJECT_DIARY); if (g_GameFlow->IsLoadSaveEnabled()) @@ -1739,7 +1739,7 @@ namespace TEN::Gui void GuiController::ConstructCombineObjectList(ItemInfo* item) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); Rings[(int)RingTypes::Ammo].NumObjectsInList = 0; @@ -1748,73 +1748,73 @@ namespace TEN::Gui if (!(g_GameFlow->GetLevel(CurrentLevel)->GetLaraType() == LaraType::Young)) { - if (lara->Weapons[(int)LaraWeaponType::Revolver].Present) + if (player.Weapons[(int)LaraWeaponType::Revolver].Present) { - if (lara->Weapons[(int)LaraWeaponType::Revolver].HasLasersight) + if (player.Weapons[(int)LaraWeaponType::Revolver].HasLasersight) InsertObjectIntoList_v2(INV_OBJECT_REVOLVER_LASER); else InsertObjectIntoList_v2(INV_OBJECT_REVOLVER); } - if (lara->Weapons[(int)LaraWeaponType::HK].Present) + if (player.Weapons[(int)LaraWeaponType::HK].Present) { - if (lara->Weapons[(int)LaraWeaponType::HK].HasLasersight) + if (player.Weapons[(int)LaraWeaponType::HK].HasLasersight) InsertObjectIntoList_v2(INV_OBJECT_HK_LASERSIGHT); else InsertObjectIntoList_v2(INV_OBJECT_HK); } - if (lara->Weapons[(int)LaraWeaponType::Crossbow].Present) + if (player.Weapons[(int)LaraWeaponType::Crossbow].Present) { - if (lara->Weapons[(int)LaraWeaponType::Crossbow].HasLasersight) + if (player.Weapons[(int)LaraWeaponType::Crossbow].HasLasersight) InsertObjectIntoList_v2(INV_OBJECT_CROSSBOW_LASER); else InsertObjectIntoList_v2(INV_OBJECT_CROSSBOW); } - if (lara->Inventory.HasLasersight) + if (player.Inventory.HasLasersight) InsertObjectIntoList_v2(INV_OBJECT_LASERSIGHT); - if (lara->Inventory.HasSilencer) + if (player.Inventory.HasSilencer) InsertObjectIntoList_v2(INV_OBJECT_SILENCER); } - if (lara->Inventory.BeetleComponents) + if (player.Inventory.BeetleComponents) { - if (lara->Inventory.BeetleComponents & 2) + if (player.Inventory.BeetleComponents & 2) InsertObjectIntoList_v2(INV_OBJECT_BEETLE_PART1); - if (lara->Inventory.BeetleComponents & 4) + if (player.Inventory.BeetleComponents & 4) InsertObjectIntoList_v2(INV_OBJECT_BEETLE_PART2); } - if (lara->Inventory.SmallWaterskin) - InsertObjectIntoList_v2(lara->Inventory.SmallWaterskin - 1 + INV_OBJECT_SMALL_WATERSKIN_EMPTY); + if (player.Inventory.SmallWaterskin) + InsertObjectIntoList_v2(player.Inventory.SmallWaterskin - 1 + INV_OBJECT_SMALL_WATERSKIN_EMPTY); - if (lara->Inventory.BigWaterskin) - InsertObjectIntoList_v2(lara->Inventory.BigWaterskin - 1 + INV_OBJECT_BIG_WATERSKIN_EMPTY); + if (player.Inventory.BigWaterskin) + InsertObjectIntoList_v2(player.Inventory.BigWaterskin - 1 + INV_OBJECT_BIG_WATERSKIN_EMPTY); for (int i = 0; i < NUM_PUZZLE_PIECES; i++) { - if (lara->Inventory.PuzzlesCombo[i]) + if (player.Inventory.PuzzlesCombo[i]) InsertObjectIntoList_v2(INV_OBJECT_PUZZLE1_COMBO1 + i); } for (int i = 0; i < NUM_KEY_PIECES; i++) { - if (lara->Inventory.KeysCombo[i]) + if (player.Inventory.KeysCombo[i]) InsertObjectIntoList_v2(INV_OBJECT_KEY1_COMBO1 + i); } for (int i = 0; i < NUM_PICKUPS_PIECES; i++) { - if (lara->Inventory.PickupsCombo[i]) + if (player.Inventory.PickupsCombo[i]) InsertObjectIntoList_v2(INV_OBJECT_PICKUP1_COMBO1 + i); } for (int i = 0; i < NUM_EXAMINES_PIECES; i++) { - if (lara->Inventory.ExaminesCombo[i]) + if (player.Inventory.ExaminesCombo[i]) InsertObjectIntoList_v2(INV_OBJECT_EXAMINE1_COMBO1 + i); } @@ -1832,45 +1832,45 @@ namespace TEN::Gui void GuiController::InitializeInventory(ItemInfo* item) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); AlterFOV(ANGLE(DEFAULT_FOV), false); - lara->Inventory.IsBusy = false; + player.Inventory.IsBusy = false; InventoryItemChosen = NO_VALUE; ItemUsed = false; - if (lara->Weapons[(int)LaraWeaponType::Shotgun].Ammo[0].HasInfinite()) + if (player.Weapons[(int)LaraWeaponType::Shotgun].Ammo[0].HasInfinite()) { Ammo.AmountShotGunAmmo1 = -1; } else { - Ammo.AmountShotGunAmmo1 = lara->Weapons[(int)LaraWeaponType::Shotgun].Ammo[0].GetCount() / 6; + Ammo.AmountShotGunAmmo1 = player.Weapons[(int)LaraWeaponType::Shotgun].Ammo[0].GetCount() / 6; } - if (lara->Weapons[(int)LaraWeaponType::Shotgun].Ammo[1].HasInfinite()) + if (player.Weapons[(int)LaraWeaponType::Shotgun].Ammo[1].HasInfinite()) { Ammo.AmountShotGunAmmo2 = -1; } else { - Ammo.AmountShotGunAmmo2 = lara->Weapons[(int)LaraWeaponType::Shotgun].Ammo[1].GetCount() / 6; + Ammo.AmountShotGunAmmo2 = player.Weapons[(int)LaraWeaponType::Shotgun].Ammo[1].GetCount() / 6; } - Ammo.AmountShotGunAmmo1 = lara->Weapons[(int)LaraWeaponType::Shotgun].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : lara->Weapons[(int)LaraWeaponType::Shotgun].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); - Ammo.AmountShotGunAmmo2 = lara->Weapons[(int)LaraWeaponType::Shotgun].Ammo[(int)WeaponAmmoType::Ammo2].HasInfinite() ? -1 : lara->Weapons[(int)LaraWeaponType::Shotgun].Ammo[(int)WeaponAmmoType::Ammo2].GetCount(); - Ammo.AmountHKAmmo1 = lara->Weapons[(int)LaraWeaponType::HK].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : lara->Weapons[(int)LaraWeaponType::HK].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); - Ammo.AmountCrossBowAmmo1 = lara->Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : lara->Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); - Ammo.AmountCrossBowAmmo2 = lara->Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo2].HasInfinite() ? -1 : lara->Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo2].GetCount(); - Ammo.AmountCrossBowAmmo3 = lara->Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo3].HasInfinite() ? -1 : lara->Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo3].GetCount(); - Ammo.AmountUziAmmo = lara->Weapons[(int)LaraWeaponType::Uzi].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : lara->Weapons[(int)LaraWeaponType::Uzi].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); - Ammo.AmountRevolverAmmo = lara->Weapons[(int)LaraWeaponType::Revolver].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : lara->Weapons[(int)LaraWeaponType::Revolver].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); - Ammo.AmountPistolsAmmo = lara->Weapons[(int)LaraWeaponType::Pistol].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : lara->Weapons[(int)LaraWeaponType::Pistol].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); - Ammo.AmountRocketsAmmo = lara->Weapons[(int)LaraWeaponType::RocketLauncher].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : lara->Weapons[(int)LaraWeaponType::RocketLauncher].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); - Ammo.AmountHarpoonAmmo = lara->Weapons[(int)LaraWeaponType::HarpoonGun].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite()? -1 : lara->Weapons[(int)LaraWeaponType::HarpoonGun].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); - Ammo.AmountGrenadeAmmo1 = lara->Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : lara->Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); - Ammo.AmountGrenadeAmmo2 = lara->Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo2].HasInfinite() ? -1 : lara->Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo2].GetCount(); - Ammo.AmountGrenadeAmmo3 = lara->Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo3].HasInfinite() ? -1 : lara->Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo3].GetCount(); + Ammo.AmountShotGunAmmo1 = player.Weapons[(int)LaraWeaponType::Shotgun].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : player.Weapons[(int)LaraWeaponType::Shotgun].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); + Ammo.AmountShotGunAmmo2 = player.Weapons[(int)LaraWeaponType::Shotgun].Ammo[(int)WeaponAmmoType::Ammo2].HasInfinite() ? -1 : player.Weapons[(int)LaraWeaponType::Shotgun].Ammo[(int)WeaponAmmoType::Ammo2].GetCount(); + Ammo.AmountHKAmmo1 = player.Weapons[(int)LaraWeaponType::HK].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : player.Weapons[(int)LaraWeaponType::HK].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); + Ammo.AmountCrossBowAmmo1 = player.Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : player.Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); + Ammo.AmountCrossBowAmmo2 = player.Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo2].HasInfinite() ? -1 : player.Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo2].GetCount(); + Ammo.AmountCrossBowAmmo3 = player.Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo3].HasInfinite() ? -1 : player.Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo3].GetCount(); + Ammo.AmountUziAmmo = player.Weapons[(int)LaraWeaponType::Uzi].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : player.Weapons[(int)LaraWeaponType::Uzi].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); + Ammo.AmountRevolverAmmo = player.Weapons[(int)LaraWeaponType::Revolver].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : player.Weapons[(int)LaraWeaponType::Revolver].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); + Ammo.AmountPistolsAmmo = player.Weapons[(int)LaraWeaponType::Pistol].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : player.Weapons[(int)LaraWeaponType::Pistol].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); + Ammo.AmountRocketsAmmo = player.Weapons[(int)LaraWeaponType::RocketLauncher].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : player.Weapons[(int)LaraWeaponType::RocketLauncher].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); + Ammo.AmountHarpoonAmmo = player.Weapons[(int)LaraWeaponType::HarpoonGun].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite()? -1 : player.Weapons[(int)LaraWeaponType::HarpoonGun].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); + Ammo.AmountGrenadeAmmo1 = player.Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : player.Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); + Ammo.AmountGrenadeAmmo2 = player.Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo2].HasInfinite() ? -1 : player.Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo2].GetCount(); + Ammo.AmountGrenadeAmmo3 = player.Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo3].HasInfinite() ? -1 : player.Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo3].GetCount(); ConstructObjectList(item); if (EnterInventory == NO_VALUE) @@ -2243,7 +2243,7 @@ namespace TEN::Gui void GuiController::DoInventory(ItemInfo* item) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); auto& invRing = Rings[(int)RingTypes::Inventory]; auto& ammoRing = Rings[(int)RingTypes::Ammo]; @@ -2546,7 +2546,7 @@ namespace TEN::Gui case MenuType::Diary: SetInventoryMode(InventoryMode::Diary); - lara->Inventory.Diary.CurrentPage = 1; + player.Inventory.Diary.CurrentPage = 1; break; } } @@ -2574,51 +2574,51 @@ namespace TEN::Gui // Update the selected ammo of weapons that require it, and only these. void GuiController::UpdateWeaponStatus(ItemInfo* item) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - if (lara->Weapons[(int)LaraWeaponType::Shotgun].Present) + if (player.Weapons[(int)LaraWeaponType::Shotgun].Present) { if (Ammo.CurrentShotGunAmmoType) - lara->Weapons[(int)LaraWeaponType::Shotgun].SelectedAmmo = WeaponAmmoType::Ammo2; + player.Weapons[(int)LaraWeaponType::Shotgun].SelectedAmmo = WeaponAmmoType::Ammo2; else - lara->Weapons[(int)LaraWeaponType::Shotgun].SelectedAmmo = WeaponAmmoType::Ammo1; + player.Weapons[(int)LaraWeaponType::Shotgun].SelectedAmmo = WeaponAmmoType::Ammo1; } - if (lara->Weapons[(int)LaraWeaponType::Crossbow].Present) + if (player.Weapons[(int)LaraWeaponType::Crossbow].Present) { - lara->Weapons[(int)LaraWeaponType::Crossbow].SelectedAmmo = WeaponAmmoType::Ammo1; + player.Weapons[(int)LaraWeaponType::Crossbow].SelectedAmmo = WeaponAmmoType::Ammo1; if (Ammo.CurrentCrossBowAmmoType == 1) - lara->Weapons[(int)LaraWeaponType::Crossbow].SelectedAmmo = WeaponAmmoType::Ammo2; + player.Weapons[(int)LaraWeaponType::Crossbow].SelectedAmmo = WeaponAmmoType::Ammo2; else if (Ammo.CurrentCrossBowAmmoType == 2) - lara->Weapons[(int)LaraWeaponType::Crossbow].SelectedAmmo = WeaponAmmoType::Ammo3; + player.Weapons[(int)LaraWeaponType::Crossbow].SelectedAmmo = WeaponAmmoType::Ammo3; } - if (lara->Weapons[(int)LaraWeaponType::HK].Present) + if (player.Weapons[(int)LaraWeaponType::HK].Present) { - lara->Weapons[(int)LaraWeaponType::HK].WeaponMode = LaraWeaponTypeCarried::WTYPE_AMMO_1; - lara->Weapons[(int)LaraWeaponType::HK].SelectedAmmo = WeaponAmmoType::Ammo1; + player.Weapons[(int)LaraWeaponType::HK].WeaponMode = LaraWeaponTypeCarried::WTYPE_AMMO_1; + player.Weapons[(int)LaraWeaponType::HK].SelectedAmmo = WeaponAmmoType::Ammo1; if (Ammo.CurrentHKAmmoType == 1) { - lara->Weapons[(int)LaraWeaponType::HK].WeaponMode = LaraWeaponTypeCarried::WTYPE_AMMO_2; - lara->Weapons[(int)LaraWeaponType::HK].SelectedAmmo = WeaponAmmoType::Ammo1; + player.Weapons[(int)LaraWeaponType::HK].WeaponMode = LaraWeaponTypeCarried::WTYPE_AMMO_2; + player.Weapons[(int)LaraWeaponType::HK].SelectedAmmo = WeaponAmmoType::Ammo1; } else if (Ammo.CurrentHKAmmoType == 2) { - lara->Weapons[(int)LaraWeaponType::HK].WeaponMode = LaraWeaponTypeCarried::WTYPE_AMMO_3; - lara->Weapons[(int)LaraWeaponType::HK].SelectedAmmo = WeaponAmmoType::Ammo1; + player.Weapons[(int)LaraWeaponType::HK].WeaponMode = LaraWeaponTypeCarried::WTYPE_AMMO_3; + player.Weapons[(int)LaraWeaponType::HK].SelectedAmmo = WeaponAmmoType::Ammo1; } } - if (lara->Weapons[(int)LaraWeaponType::GrenadeLauncher].Present) + if (player.Weapons[(int)LaraWeaponType::GrenadeLauncher].Present) { - lara->Weapons[(int)LaraWeaponType::GrenadeLauncher].SelectedAmmo = WeaponAmmoType::Ammo1; + player.Weapons[(int)LaraWeaponType::GrenadeLauncher].SelectedAmmo = WeaponAmmoType::Ammo1; if (Ammo.CurrentGrenadeGunAmmoType == 1) - lara->Weapons[(int)LaraWeaponType::GrenadeLauncher].SelectedAmmo = WeaponAmmoType::Ammo2; + player.Weapons[(int)LaraWeaponType::GrenadeLauncher].SelectedAmmo = WeaponAmmoType::Ammo2; else if (Ammo.CurrentGrenadeGunAmmoType == 2) - lara->Weapons[(int)LaraWeaponType::GrenadeLauncher].SelectedAmmo = WeaponAmmoType::Ammo3; + player.Weapons[(int)LaraWeaponType::GrenadeLauncher].SelectedAmmo = WeaponAmmoType::Ammo3; } } @@ -3182,11 +3182,11 @@ namespace TEN::Gui bool GuiController::CallInventory(ItemInfo* item, bool resetMode) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); bool doLoad = false; - lara->Inventory.OldBusy = lara->Inventory.IsBusy; + player.Inventory.OldBusy = player.Inventory.IsBusy; g_Renderer.DumpGameScene(); PauseAllSounds(SoundPauseMode::Inventory); @@ -3286,7 +3286,7 @@ namespace TEN::Gui AlterFOV(LastFOV); ResumeAllSounds(SoundPauseMode::Inventory); - lara->Inventory.IsBusy = lara->Inventory.OldBusy; + player.Inventory.IsBusy = player.Inventory.OldBusy; SetInventoryMode(InventoryMode::None); return doLoad; @@ -3341,21 +3341,21 @@ namespace TEN::Gui void GuiController::DoDiary(ItemInfo* item) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); SetInventoryMode(InventoryMode::Diary); if (GuiIsPulsed(In::Right) && - lara->Inventory.Diary.CurrentPage < lara->Inventory.Diary.NumPages) + player.Inventory.Diary.CurrentPage < player.Inventory.Diary.NumPages) { - lara->Inventory.Diary.CurrentPage++; + player.Inventory.Diary.CurrentPage++; SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always); } if (GuiIsPulsed(In::Left) && - lara->Inventory.Diary.CurrentPage > 1) + player.Inventory.Diary.CurrentPage > 1) { - lara->Inventory.Diary.CurrentPage--; + player.Inventory.Diary.CurrentPage--; SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always); } @@ -3454,10 +3454,10 @@ namespace TEN::Gui bool GuiController::PerformWaterskinCombine(ItemInfo* item, bool flag) { - auto* lara = GetLaraInfo(item); + auto& player = GetLaraInfo(*item); - int smallLiters = lara->Inventory.SmallWaterskin - 1; // How many liters in the small one? - int bigLiters = lara->Inventory.BigWaterskin - 1; // How many liters in the big one? + int smallLiters = player.Inventory.SmallWaterskin - 1; // How many liters in the small one? + int bigLiters = player.Inventory.BigWaterskin - 1; // How many liters in the big one? int smallCapacity = 3 - smallLiters; // How many more liters can fit in the small one? int bigCapacity = 5 - bigLiters; // How many more liters can fit in the big one? @@ -3465,7 +3465,7 @@ namespace TEN::Gui if (flag) { // Big one isn't empty and the small one isn't full. - if (lara->Inventory.BigWaterskin != 1 && smallCapacity) + if (player.Inventory.BigWaterskin != 1 && smallCapacity) { i = bigLiters; @@ -3481,8 +3481,8 @@ namespace TEN::Gui i--; } while (i); - lara->Inventory.SmallWaterskin = smallLiters + 1; - lara->Inventory.BigWaterskin = bigLiters + 1; + player.Inventory.SmallWaterskin = smallLiters + 1; + player.Inventory.BigWaterskin = bigLiters + 1; CombineObject1 = (smallLiters + 1) + (INV_OBJECT_SMALL_WATERSKIN_EMPTY - 1); return true; } @@ -3490,9 +3490,9 @@ namespace TEN::Gui else { // Small one isn't empty and the big one isn't full. - if (lara->Inventory.SmallWaterskin != 1 && bigCapacity) + if (player.Inventory.SmallWaterskin != 1 && bigCapacity) { - i = lara->Inventory.SmallWaterskin - 1; + i = player.Inventory.SmallWaterskin - 1; do { @@ -3506,8 +3506,8 @@ namespace TEN::Gui i--; } while (i); - lara->Inventory.SmallWaterskin = smallLiters + 1; - lara->Inventory.BigWaterskin = bigLiters + 1; + player.Inventory.SmallWaterskin = smallLiters + 1; + player.Inventory.BigWaterskin = bigLiters + 1; CombineObject1 = (bigLiters + 1) + (INV_OBJECT_BIG_WATERSKIN_EMPTY - 1); return true; } From fcf32b1ad026c7c93356a6286e061f4ab3fd9fc0 Mon Sep 17 00:00:00 2001 From: TokyoSU <77746747+TokyoSU@users.noreply.github.com> Date: Thu, 15 Aug 2024 13:55:23 +0200 Subject: [PATCH 05/17] Fix young hair drawing. --- TombEngine/Game/effects/hair.cpp | 16 ++++++---------- TombEngine/Game/effects/hair.h | 1 + TombEngine/Renderer/RendererLara.cpp | 11 +---------- 3 files changed, 8 insertions(+), 20 deletions(-) diff --git a/TombEngine/Game/effects/hair.cpp b/TombEngine/Game/effects/hair.cpp index 70e3278c7..5567ded88 100644 --- a/TombEngine/Game/effects/hair.cpp +++ b/TombEngine/Game/effects/hair.cpp @@ -41,8 +41,8 @@ namespace TEN::Effects::Hair auto baseOrient = Geometry::ConvertDirectionToQuat(-Geometry::ConvertQuatToDirection(GetBoneOrientation(item, LM_HEAD))); // Set position of base segment. - auto basePos = worldMatrix.Translation(); - Segments[0].Position = basePos; + Segments[0].Position = worldMatrix.Translation(); + Segments[0].WorldMatrix = worldMatrix; if (!IsInitialized) { @@ -83,7 +83,7 @@ namespace TEN::Effects::Hair // TR3 UPV uses a hack which forces player water status to dry. // Therefore, cannot directly use water status value to determine enrironment. bool isOnLand = (player.Control.WaterStatus == WaterStatus::Dry && - (player.Context.Vehicle == -1 || g_Level.Items[player.Context.Vehicle].ObjectNumber != ID_UPV)); + (player.Context.Vehicle == NO_VALUE || g_Level.Items[player.Context.Vehicle].ObjectNumber != ID_UPV)); // Handle segment room collision. CollideSegmentWithRoom(segment, waterHeight, roomNumber, isOnLand); @@ -97,6 +97,7 @@ namespace TEN::Effects::Hair // Calculate world matrix. worldMatrix = Matrix::CreateTranslation(prevSegment.Position); worldMatrix = Matrix::CreateFromQuaternion(prevSegment.Orientation) * worldMatrix; + segment.WorldMatrix = worldMatrix; auto jointOffset = (i == (Segments.size() - 1)) ? GetJointOffset(ID_HAIR, (i - 1) - 1) : @@ -118,12 +119,12 @@ namespace TEN::Effects::Hair { // Left pigtail offset. case 0: - relOffset = Vector3(-52.0f, -48.0f, -50.0f); + relOffset = Vector3(-48.0f, -48.0f, -50.0f); break; // Right pigtail offset. case 1: - relOffset = Vector3(44.0f, -48.0f, -50.0f); + relOffset = Vector3(48.0f, -48.0f, -50.0f); break; } } @@ -346,11 +347,6 @@ namespace TEN::Effects::Hair void HairEffectController::Update(ItemInfo& item, bool isYoung) { for (int i = 0; i < Units.size(); i++) - { Units[i].Update(item, i); - - if (isYoung && i == 1) - Units[i].Update(item, i); - } } } diff --git a/TombEngine/Game/effects/hair.h b/TombEngine/Game/effects/hair.h index 8e0a842b6..814e3c1fc 100644 --- a/TombEngine/Game/effects/hair.h +++ b/TombEngine/Game/effects/hair.h @@ -15,6 +15,7 @@ namespace TEN::Effects::Hair Vector3 Position = Vector3::Zero; Vector3 Velocity = Vector3::Zero; Quaternion Orientation = Quaternion::Identity; + Matrix WorldMatrix = Matrix::Identity; }; public: diff --git a/TombEngine/Renderer/RendererLara.cpp b/TombEngine/Renderer/RendererLara.cpp index bccc49e04..80bddf428 100644 --- a/TombEngine/Renderer/RendererLara.cpp +++ b/TombEngine/Renderer/RendererLara.cpp @@ -333,10 +333,6 @@ void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, Render const auto& hairObject = *_moveableObjects[ID_HAIR]; - // TODO - bool isYoung = (g_GameFlow->GetLevel(CurrentLevel)->GetLaraType() == LaraType::Young); - - bool isHead = true; for (const auto& unit : HairEffect.Units) { if (!unit.IsEnabled) @@ -349,10 +345,7 @@ void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, Render for (int i = 0; i < unit.Segments.size(); i++) { - const auto& segment = unit.Segments[i]; - auto worldMatrix = Matrix::CreateFromQuaternion(segment.Orientation) * Matrix::CreateTranslation(segment.Position); - - _stItem.BonesMatrices[i + 1] = worldMatrix; + _stItem.BonesMatrices[i + 1] = unit.Segments[i].WorldMatrix; _stItem.BoneLightModes[i] = (int)LightMode::Dynamic; } @@ -363,8 +356,6 @@ void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, Render auto& rMesh = *hairObject.ObjectMeshes[i]; DrawMoveableMesh(itemToDraw, &rMesh, room, i, view, rendererPass); } - - isHead = false; } } From 6b18d46096c7bf27619800243b60cb7c27831d3f Mon Sep 17 00:00:00 2001 From: TokyoSU <77746747+TokyoSU@users.noreply.github.com> Date: Thu, 15 Aug 2024 14:08:47 +0200 Subject: [PATCH 06/17] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 674b3fdee..85a365f08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Fixed teeth spikes not triggering the player impale animation. * Fixed TR4 mine crash with OCB 1 when triggered. * Fixed cases where Atlantean mutant's bombs cause the game to crash. +* Fixed young hair drawing. ### Features/Amendments * Changed Rome Hammer to not hurt player whilst deactivated. From cce384d3de7f5f058dcdc906813dfaa1656c6421 Mon Sep 17 00:00:00 2001 From: Sezz Date: Thu, 15 Aug 2024 22:40:08 +1000 Subject: [PATCH 07/17] Remove unused parameter --- TombEngine/Game/Lara/lara.cpp | 2 +- TombEngine/Game/effects/hair.cpp | 10 ++++------ TombEngine/Game/effects/hair.h | 11 +++++++++-- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/TombEngine/Game/Lara/lara.cpp b/TombEngine/Game/Lara/lara.cpp index 053a5ce44..b8c65783b 100644 --- a/TombEngine/Game/Lara/lara.cpp +++ b/TombEngine/Game/Lara/lara.cpp @@ -640,7 +640,7 @@ void UpdateLara(ItemInfo* item, bool isTitle) g_Renderer.UpdateLaraAnimations(true); // Update player effects. - HairEffect.Update(*item, g_GameFlow->GetLevel(CurrentLevel)->GetLaraType() == LaraType::Young); + HairEffect.Update(*item); HandlePlayerWetnessDrips(*item); HandlePlayerDiveBubbles(*item); ProcessEffects(item); diff --git a/TombEngine/Game/effects/hair.cpp b/TombEngine/Game/effects/hair.cpp index 5567ded88..e0f0cd7da 100644 --- a/TombEngine/Game/effects/hair.cpp +++ b/TombEngine/Game/effects/hair.cpp @@ -85,10 +85,8 @@ namespace TEN::Effects::Hair bool isOnLand = (player.Control.WaterStatus == WaterStatus::Dry && (player.Context.Vehicle == NO_VALUE || g_Level.Items[player.Context.Vehicle].ObjectNumber != ID_UPV)); - // Handle segment room collision. + // Handle segment collision. CollideSegmentWithRoom(segment, waterHeight, roomNumber, isOnLand); - - // Handle segment sphere collision. CollideSegmentWithSpheres(segment, spheres); // Calculate orientation. @@ -318,7 +316,7 @@ namespace TEN::Effects::Hair void HairEffectController::Initialize() { - constexpr auto ORIENT_DEFAULT = EulerAngles(ANGLE(-90.0f), 0, 0); + constexpr auto DEFAULT_ORIENT = EulerAngles(ANGLE(-90.0f), 0, 0); bool isYoung = (g_GameFlow->GetLevel(CurrentLevel)->GetLaraType() == LaraType::Young); @@ -337,14 +335,14 @@ namespace TEN::Effects::Hair { segment.Position = GetJointOffset(ID_HAIR, 0); segment.Velocity = Vector3::Zero; - segment.Orientation = ORIENT_DEFAULT.ToQuaternion(); + segment.Orientation = DEFAULT_ORIENT.ToQuaternion(); } isHead = false; } } - void HairEffectController::Update(ItemInfo& item, bool isYoung) + void HairEffectController::Update(ItemInfo& item) { for (int i = 0; i < Units.size(); i++) Units[i].Update(item, i); diff --git a/TombEngine/Game/effects/hair.h b/TombEngine/Game/effects/hair.h index 814e3c1fc..be4baa049 100644 --- a/TombEngine/Game/effects/hair.h +++ b/TombEngine/Game/effects/hair.h @@ -8,6 +8,7 @@ namespace TEN::Effects::Hair { private: // Constants + static constexpr auto HAIR_GRAVITY = 10.0f; struct HairSegment @@ -15,20 +16,23 @@ namespace TEN::Effects::Hair Vector3 Position = Vector3::Zero; Vector3 Velocity = Vector3::Zero; Quaternion Orientation = Quaternion::Identity; - Matrix WorldMatrix = Matrix::Identity; + Matrix WorldMatrix = Matrix::Identity; }; public: // Members + bool IsEnabled = false; bool IsInitialized = false; std::vector Segments = {}; // Utilities + void Update(const ItemInfo& item, int hairUnitIndex); private: // Helpers + Vector3 GetRelBaseOffset(int hairUnitIndex, bool isYoung); Vector3 GetWaterProbeOffset(const ItemInfo& item); Quaternion GetSegmentOrientation(const Vector3& origin, const Vector3& target, const Quaternion& baseOrient); @@ -42,15 +46,18 @@ namespace TEN::Effects::Hair { private: // Constants + static constexpr auto UNIT_COUNT_MAX = 2; public: // Members + std::array Units = {}; // Utilities + void Initialize(); - void Update(ItemInfo& item, bool isYoung); + void Update(ItemInfo& item); }; extern HairEffectController HairEffect; From bea28104087c08296e4d1d02d4be843bc02ea6ba Mon Sep 17 00:00:00 2001 From: Sezz Date: Thu, 15 Aug 2024 22:44:35 +1000 Subject: [PATCH 08/17] Remove Ptr suffix; use const --- TombEngine/Game/effects/hair.cpp | 42 ++++++++++++++++---------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/TombEngine/Game/effects/hair.cpp b/TombEngine/Game/effects/hair.cpp index e0f0cd7da..d3d214dc4 100644 --- a/TombEngine/Game/effects/hair.cpp +++ b/TombEngine/Game/effects/hair.cpp @@ -197,21 +197,21 @@ namespace TEN::Effects::Hair spheres.reserve(SPHERE_COUNT); // Hips sphere. - auto* meshPtr = &g_Level.Meshes[item.Model.MeshIndex[LM_HIPS]]; - auto pos = GetJointPosition(item, LM_HIPS, Vector3i(meshPtr->sphere.Center)).ToVector3(); - spheres.push_back(BoundingSphere(pos, meshPtr->sphere.Radius)); + const auto* mesh = &g_Level.Meshes[item.Model.MeshIndex[LM_HIPS]]; + auto pos = GetJointPosition(item, LM_HIPS, Vector3i(mesh->sphere.Center)).ToVector3(); + spheres.push_back(BoundingSphere(pos, mesh->sphere.Radius)); // Torso sphere. - meshPtr = &g_Level.Meshes[item.Model.MeshIndex[LM_TORSO]]; - pos = GetJointPosition(item, LM_TORSO, Vector3i(meshPtr->sphere.Center) + TORSO_SPHERE_OFFSET).ToVector3(); - spheres.push_back(BoundingSphere(pos, meshPtr->sphere.Radius)); + mesh = &g_Level.Meshes[item.Model.MeshIndex[LM_TORSO]]; + pos = GetJointPosition(item, LM_TORSO, Vector3i(mesh->sphere.Center) + TORSO_SPHERE_OFFSET).ToVector3(); + spheres.push_back(BoundingSphere(pos, mesh->sphere.Radius)); if (isYoung) spheres.back().Radius = spheres.back().Radius - ((spheres.back().Radius / 4) + (spheres.back().Radius / 8)); // Head sphere. - meshPtr = &g_Level.Meshes[item.Model.MeshIndex[LM_HEAD]]; - pos = GetJointPosition(item, LM_HEAD, Vector3i(meshPtr->sphere.Center) + HEAD_SPHERE_OFFSET).ToVector3(); - spheres.push_back(BoundingSphere(pos, meshPtr->sphere.Radius)); + mesh = &g_Level.Meshes[item.Model.MeshIndex[LM_HEAD]]; + pos = GetJointPosition(item, LM_HEAD, Vector3i(mesh->sphere.Center) + HEAD_SPHERE_OFFSET).ToVector3(); + spheres.push_back(BoundingSphere(pos, mesh->sphere.Radius)); // Neck sphere. spheres.push_back(BoundingSphere( @@ -219,30 +219,30 @@ namespace TEN::Effects::Hair isYoung ? 0.0f : (spheres[2].Radius * 0.75f))); // Left arm sphere. - meshPtr = &g_Level.Meshes[item.Model.MeshIndex[LM_LINARM]]; - pos = GetJointPosition(item, LM_LINARM, Vector3i(meshPtr->sphere.Center)).ToVector3(); - spheres.push_back(BoundingSphere(pos, (meshPtr->sphere.Radius / 3) * 4)); + mesh = &g_Level.Meshes[item.Model.MeshIndex[LM_LINARM]]; + pos = GetJointPosition(item, LM_LINARM, Vector3i(mesh->sphere.Center)).ToVector3(); + spheres.push_back(BoundingSphere(pos, (mesh->sphere.Radius / 3) * 4)); // Right arm sphere. - meshPtr = &g_Level.Meshes[item.Model.MeshIndex[LM_RINARM]]; - pos = GetJointPosition(item, LM_RINARM, Vector3i(meshPtr->sphere.Center)).ToVector3(); - spheres.push_back(BoundingSphere(pos, (meshPtr->sphere.Radius / 3) * 4)); + mesh = &g_Level.Meshes[item.Model.MeshIndex[LM_RINARM]]; + pos = GetJointPosition(item, LM_RINARM, Vector3i(mesh->sphere.Center)).ToVector3(); + spheres.push_back(BoundingSphere(pos, (mesh->sphere.Radius / 3) * 4)); // Left holster sphere. - meshPtr = &g_Level.Meshes[item.Model.MeshIndex[LM_LTHIGH]]; - pos = GetJointPosition(item, LM_LTHIGH, Vector3i(meshPtr->sphere.Center)).ToVector3(); + mesh = &g_Level.Meshes[item.Model.MeshIndex[LM_LTHIGH]]; + pos = GetJointPosition(item, LM_LTHIGH, Vector3i(mesh->sphere.Center)).ToVector3(); spheres.push_back( BoundingSphere( pos + ((spheres[0].Center - pos) / 2), - meshPtr->sphere.Radius)); + mesh->sphere.Radius)); // Right holster sphere. - meshPtr = &g_Level.Meshes[item.Model.MeshIndex[LM_RTHIGH]]; - pos = GetJointPosition(item, LM_RTHIGH, Vector3i(meshPtr->sphere.Center)).ToVector3(); + mesh = &g_Level.Meshes[item.Model.MeshIndex[LM_RTHIGH]]; + pos = GetJointPosition(item, LM_RTHIGH, Vector3i(mesh->sphere.Center)).ToVector3(); spheres.push_back( BoundingSphere( pos + ((spheres[0].Center - pos) / 2), - meshPtr->sphere.Radius)); + mesh->sphere.Radius)); if (isYoung) spheres[1].Center = (spheres[1].Center + spheres[2].Center) / 2; From 2439e7cd46f25fc521dd9f4075125494f5bb7d83 Mon Sep 17 00:00:00 2001 From: Sezz Date: Thu, 15 Aug 2024 22:46:08 +1000 Subject: [PATCH 09/17] Minor cleanup --- TombEngine/Game/effects/hair.cpp | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/TombEngine/Game/effects/hair.cpp b/TombEngine/Game/effects/hair.cpp index d3d214dc4..5ca0c4c0e 100644 --- a/TombEngine/Game/effects/hair.cpp +++ b/TombEngine/Game/effects/hair.cpp @@ -174,13 +174,13 @@ namespace TEN::Effects::Hair Quaternion HairUnit::GetSegmentOrientation(const Vector3& origin, const Vector3& target, const Quaternion& baseOrient) { // Calculate absolute orientation. - auto absDirection = target - origin; - absDirection.Normalize(); - auto absOrient = Geometry::ConvertDirectionToQuat(absDirection); + auto absDir = target - origin; + absDir.Normalize(); + auto absOrient = Geometry::ConvertDirectionToQuat(absDir); // Calculate relative twist rotation. // TODO: Find accurate twist angle based on relation between absOrient and baseOrient. - auto twistAxisAngle = AxisAngle(absDirection, EulerAngles(baseOrient).y); + auto twistAxisAngle = AxisAngle(absDir, EulerAngles(baseOrient).y); auto twistRot = twistAxisAngle.ToQuaternion(); // Return ideal orientation. @@ -252,13 +252,12 @@ namespace TEN::Effects::Hair void HairUnit::CollideSegmentWithRoom(HairSegment& segment, int waterHeight, int roomNumber, bool isOnLand) { - constexpr auto VELOCITY_COEFF = 0.75f; + constexpr auto VEL_COEFF = 0.75f; auto pointColl = GetPointCollision(segment.Position, roomNumber); - int floorHeight = pointColl.GetFloorHeight(); Segments[0].Velocity = segment.Position; - segment.Position += segment.Velocity * VELOCITY_COEFF; + segment.Position += segment.Velocity * VEL_COEFF; // Land collision. if (isOnLand) @@ -276,7 +275,7 @@ namespace TEN::Effects::Hair segment.Position.y = waterHeight; } // Avoid clipping through floor. - else if (floorHeight > Segments[0].Position.y && segment.Position.y > floorHeight) + else if (pointColl.GetFloorHeight() > Segments[0].Position.y && segment.Position.y > pointColl.GetFloorHeight()) { segment.Position = Segments[0].Velocity; } @@ -288,9 +287,9 @@ namespace TEN::Effects::Hair { segment.Position.y = waterHeight; } - else if (segment.Position.y > floorHeight) + else if (segment.Position.y > pointColl.GetFloorHeight()) { - segment.Position.y = floorHeight; + segment.Position.y = pointColl.GetFloorHeight(); } } } @@ -299,17 +298,17 @@ namespace TEN::Effects::Hair { for (const auto& sphere : spheres) { - auto direction = segment.Position - sphere.Center; + auto dir = segment.Position - sphere.Center; - float distance = Vector3::Distance(segment.Position, sphere.Center); - if (distance < sphere.Radius) + float dist = Vector3::Distance(segment.Position, sphere.Center); + if (dist < sphere.Radius) { // Avoid division by zero. - if (distance == 0.0f) - distance = 1.0f; + if (dist == 0.0f) + dist = 1.0f; // Push segment away from sphere. - segment.Position = sphere.Center + (direction * (sphere.Radius / distance)); + segment.Position = sphere.Center + (dir * (sphere.Radius / dist)); } } } From e3c1ccf5c294b2b9236afd0255e62317fccd35b4 Mon Sep 17 00:00:00 2001 From: Sezz Date: Fri, 16 Aug 2024 02:12:41 +1000 Subject: [PATCH 10/17] Integrate GetWaterSurface(), GetWaterDepth() and GetWaterHeight() into PointCollisionData --- Documentation/doc/1 modules/Flow.html | 15 +- TombEngine/Game/Lara/lara_collide.cpp | 4 +- TombEngine/Game/Lara/lara_swim.cpp | 4 +- TombEngine/Game/Lara/lara_tests.cpp | 6 +- TombEngine/Game/collision/Point.cpp | 206 ++++++++++++++- TombEngine/Game/collision/collide_room.cpp | 242 +----------------- TombEngine/Game/collision/collide_room.h | 9 +- TombEngine/Game/control/box.cpp | 6 +- TombEngine/Game/effects/drip.cpp | 3 +- TombEngine/Game/effects/effects.cpp | 4 +- TombEngine/Game/effects/hair.cpp | 2 +- TombEngine/Game/effects/tomb4fx.cpp | 6 +- TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp | 7 +- TombEngine/Objects/TR2/Vehicles/speedboat.cpp | 10 +- TombEngine/Objects/TR3/Entity/FishSwarm.cpp | 5 +- .../Objects/TR3/Entity/tr3_scuba_diver.cpp | 32 ++- TombEngine/Objects/TR3/Object/corpse.cpp | 12 +- TombEngine/Objects/TR3/Vehicles/kayak.cpp | 10 +- .../Objects/TR3/Vehicles/rubber_boat.cpp | 8 +- TombEngine/Objects/TR3/Vehicles/upv.cpp | 12 +- .../Objects/TR4/Entity/tr4_crocodile.cpp | 4 +- .../Objects/TR5/Object/tr5_bodypart.cpp | 2 +- .../Objects/TR5/Object/tr5_rollingball.cpp | 13 +- TombEngine/Objects/Utils/VehicleHelpers.cpp | 11 +- 24 files changed, 287 insertions(+), 346 deletions(-) diff --git a/Documentation/doc/1 modules/Flow.html b/Documentation/doc/1 modules/Flow.html index 9f3a108d4..81fc6b1b0 100644 --- a/Documentation/doc/1 modules/Flow.html +++ b/Documentation/doc/1 modules/Flow.html @@ -141,7 +141,7 @@ scripts too.

- + @@ -371,7 +371,7 @@ Must be true or false EnableHomeLevel(enabled)
- Enable or disable Home Level entry in the main menu. + Enable or disable Home Level entry in the main menu. () @@ -379,7 +379,7 @@ Must be true or false
  • enabled bool - true or false. + True or false.
@@ -393,7 +393,7 @@ Must be true or false EnableLoadSave(enabled)
- Enable or disable saving and loading of savegames. + Enable or disable saving and loading of savegames. () @@ -401,7 +401,7 @@ Must be true or false
  • enabled bool - true or false. + True or false.
@@ -419,8 +419,7 @@ Must be true or false EnableFlyCheat(enabled)
- Enable or disable DOZY mode (fly cheat). -Must be true or false + Enable or disable the fly cheat. () @@ -428,7 +427,7 @@ Must be true or false
  • enabled bool - true or false + True or false.
diff --git a/TombEngine/Game/Lara/lara_collide.cpp b/TombEngine/Game/Lara/lara_collide.cpp index 2370e2339..377d0ee7b 100644 --- a/TombEngine/Game/Lara/lara_collide.cpp +++ b/TombEngine/Game/Lara/lara_collide.cpp @@ -497,13 +497,11 @@ void LaraSurfaceCollision(ItemInfo* item, CollisionInfo* coll) } auto pointColl = GetPointCollision(*item); - int waterHeight = GetWaterHeight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->RoomNumber); - if ((pointColl.GetFloorHeight() - item->Pose.Position.y) < SWIM_WATER_DEPTH) { TestPlayerWaterStepOut(item, coll); } - else if ((waterHeight - item->Pose.Position.y) <= -LARA_HEADROOM) + else if ((pointColl.GetWaterTopHeight() - item->Pose.Position.y) <= -LARA_HEADROOM) { SetLaraSwimDiveAnimation(item); } diff --git a/TombEngine/Game/Lara/lara_swim.cpp b/TombEngine/Game/Lara/lara_swim.cpp index 713a56e2a..c814159aa 100644 --- a/TombEngine/Game/Lara/lara_swim.cpp +++ b/TombEngine/Game/Lara/lara_swim.cpp @@ -3,6 +3,7 @@ #include "Game/animation.h" #include "Game/camera.h" +#include "Game/collision/Point.h" #include "Game/control/control.h" #include "Game/items.h" #include "Game/Lara/lara_collide.h" @@ -14,6 +15,7 @@ #include "Specific/level.h" #include "Specific/Input/Input.h" +using namespace TEN::Collision::Point; using namespace TEN::Input; // ----------------------------- @@ -187,7 +189,7 @@ void lara_col_underwater_death(ItemInfo* item, CollisionInfo* coll) item->HitPoints = -1; lara->Control.HandStatus = HandStatus::Busy; - int waterHeight = GetWaterHeight(item); + int waterHeight = GetPointCollision(*item).GetWaterTopHeight(); if (waterHeight < (item->Pose.Position.y - (CLICK(0.4f) - 2)) && waterHeight != NO_HEIGHT) { diff --git a/TombEngine/Game/Lara/lara_tests.cpp b/TombEngine/Game/Lara/lara_tests.cpp index a208daf54..cf6bafdcf 100644 --- a/TombEngine/Game/Lara/lara_tests.cpp +++ b/TombEngine/Game/Lara/lara_tests.cpp @@ -1087,15 +1087,13 @@ void TestLaraWaterDepth(ItemInfo* item, CollisionInfo* coll) auto& player = GetLaraInfo(*item); auto pointColl = GetPointCollision(*item); - int waterDepth = GetWaterDepth(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, pointColl.GetRoomNumber()); - if (waterDepth == NO_HEIGHT) + if (pointColl.GetWaterBottomHeight() == NO_HEIGHT) { item->Animation.Velocity.y = 0.0f; item->Pose.Position = coll->Setup.PrevPosition; } - - else if (waterDepth <= (LARA_HEIGHT - (LARA_HEADROOM / 2))) + else if (pointColl.GetWaterBottomHeight() <= (LARA_HEIGHT - (LARA_HEADROOM / 2))) { SetAnimation(item, LA_UNDERWATER_TO_STAND); ResetPlayerLean(item); diff --git a/TombEngine/Game/collision/Point.cpp b/TombEngine/Game/collision/Point.cpp index b7e49bdd2..652421c8c 100644 --- a/TombEngine/Game/collision/Point.cpp +++ b/TombEngine/Game/collision/Point.cpp @@ -177,9 +177,24 @@ namespace TEN::Collision::Point if (_waterSurfaceHeight.has_value()) return *_waterSurfaceHeight; - // Set water surface height. TODO: Calculate here. - _waterSurfaceHeight = GetWaterSurface(_position.x, _position.y, _position.z, _roomNumber); + auto* room = &g_Level.Rooms[_roomNumber]; + const auto* sector = Room::GetSector(room, _position.x - room->Position.x, _position.z - room->Position.z); + // Set water surface height. + bool isBelow = !TestEnvironment(ENV_FLAG_WATER, room); + while (sector->GetNextRoomNumber(_position, isBelow).has_value()) + { + room = &g_Level.Rooms[sector->GetNextRoomNumber(_position, isBelow).value_or(sector->RoomNumber)]; + if (isBelow == TestEnvironment(ENV_FLAG_WATER, room)) + { + _waterSurfaceHeight = sector->GetSurfaceHeight(_position.x, _position.z, isBelow); + return *_waterSurfaceHeight; + } + + sector = Room::GetSector(room, _position.x - room->Position.x, _position.z - room->Position.z); + } + + _waterSurfaceHeight = NO_HEIGHT; return *_waterSurfaceHeight; } @@ -188,10 +203,100 @@ namespace TEN::Collision::Point if (_waterBottomHeight.has_value()) return *_waterBottomHeight; - // Set water bottom height. TODO: Calculate here. - _waterBottomHeight = GetWaterDepth(_position.x, _position.y, _position.z, _roomNumber); + FloorInfo* sector = nullptr; + auto* room = &g_Level.Rooms[_roomNumber]; + short roomNumber = _roomNumber; - return *_waterBottomHeight; + int adjoiningRoomNumber = NO_VALUE; + do + { + int x = (_position.x - room->Position.x) / BLOCK(1); + int z = (_position.z - room->Position.z) / BLOCK(1); + + if (z <= 0) + { + z = 0; + if (x < 1) + { + x = 1; + } + else if (x > (room->XSize - 2)) + { + x = room->XSize - 2; + } + } + else if (z >= (room->ZSize - 1)) + { + z = room->ZSize - 1; + if (x < 1) + { + x = 1; + } + else if (x > (room->XSize - 2)) + { + x = room->XSize - 2; + } + } + else if (x < 0) + { + x = 0; + } + else if (x >= room->XSize) + { + x = room->XSize - 1; + } + + sector = &room->Sectors[z + (x * room->ZSize)]; + adjoiningRoomNumber = sector->SidePortalRoomNumber; + if (adjoiningRoomNumber != NO_VALUE) + { + roomNumber = adjoiningRoomNumber; + room = &g_Level.Rooms[adjoiningRoomNumber]; + } + } + while (adjoiningRoomNumber != NO_VALUE); + + // Set water bottom height. + if (TestEnvironment(ENV_FLAG_WATER, room) || TestEnvironment(ENV_FLAG_SWAMP, room)) + { + while (sector->GetNextRoomNumber(_position, false).value_or(NO_VALUE) != NO_VALUE) + { + room = &g_Level.Rooms[sector->GetNextRoomNumber(_position, false).value_or(sector->RoomNumber)]; + if (!TestEnvironment(ENV_FLAG_WATER, room) && !TestEnvironment(ENV_FLAG_SWAMP, room)) + { + int waterHeight = sector->GetSurfaceHeight(_position.x, _position.z, false); + int floorHeight = GetPointCollision(_position, sector->RoomNumber).GetBottomSector().GetSurfaceHeight(_position.x, _position.z, true); + + _waterBottomHeight = floorHeight - waterHeight; + return *_waterBottomHeight; + } + + sector = Room::GetSector(room, _position.x - room->Position.x, _position.z - room->Position.z); + } + + _waterBottomHeight = DEEP_WATER; + return *_waterBottomHeight; + } + else + { + while (sector->GetNextRoomNumber(_position, true).value_or(NO_VALUE) != NO_VALUE) + { + room = &g_Level.Rooms[sector->GetNextRoomNumber(_position, true).value_or(sector->RoomNumber)]; + if (TestEnvironment(ENV_FLAG_WATER, room) || TestEnvironment(ENV_FLAG_SWAMP, room)) + { + int waterHeight = sector->GetSurfaceHeight(_position.x, _position.z, true); + sector = GetFloor(_position.x, _position.y, _position.z, &roomNumber); + + _waterBottomHeight = GetPointCollision(_position, sector->RoomNumber).GetFloorHeight() - waterHeight; + return *_waterBottomHeight; + } + + sector = Room::GetSector(room, _position.x - room->Position.x, _position.z - room->Position.z); + } + + _waterBottomHeight = NO_HEIGHT; + return *_waterBottomHeight; + } } int PointCollisionData::GetWaterTopHeight() @@ -199,9 +304,96 @@ namespace TEN::Collision::Point if (_waterTopHeight.has_value()) return *_waterTopHeight; - // Set water top height. TODO: Calculate here. - _waterTopHeight = GetWaterHeight(_position.x, _position.y, _position.z, _roomNumber); + FloorInfo* sector = nullptr; + auto* room = &g_Level.Rooms[_roomNumber]; + int roomNumber = _roomNumber; + int adjoiningRoomNumber = NO_VALUE; + do + { + int x = (_position.x - room->Position.x) / BLOCK(1); + int z = (_position.z - room->Position.z) / BLOCK(1); + + if (z <= 0) + { + z = 0; + if (x < 1) + { + x = 1; + } + else if (x > (room->XSize - 2)) + { + x = room->XSize - 2; + } + } + else if (z >= (room->ZSize - 1)) + { + z = room->ZSize - 1; + if (x < 1) + { + x = 1; + } + else if (x > (room->XSize - 2)) + { + x = room->XSize - 2; + } + } + else if (x < 0) + { + x = 0; + } + else if (x >= room->XSize) + { + x = room->XSize - 1; + } + + sector = &room->Sectors[z + (x * room->ZSize)]; + adjoiningRoomNumber = sector->SidePortalRoomNumber; + + if (adjoiningRoomNumber != NO_VALUE) + { + roomNumber = adjoiningRoomNumber; + room = &g_Level.Rooms[adjoiningRoomNumber]; + } + } + while (adjoiningRoomNumber != NO_VALUE); + + if (sector->IsWall(_position.x, _position.z)) + { + _waterTopHeight = NO_HEIGHT; + return *_waterTopHeight; + } + + if (TestEnvironment(ENV_FLAG_WATER, room) || TestEnvironment(ENV_FLAG_SWAMP, room)) + { + while (sector->GetNextRoomNumber(_position, false).has_value()) + { + room = &g_Level.Rooms[sector->GetNextRoomNumber(_position, false).value_or(sector->RoomNumber)]; + if (!TestEnvironment(ENV_FLAG_WATER, room) && !TestEnvironment(ENV_FLAG_SWAMP, room)) + break; + + sector = Room::GetSector(room, _position.x - room->Position.x, _position.z - room->Position.z); + } + + _waterTopHeight = sector->GetSurfaceHeight(_position, false); + return *_waterTopHeight; + } + else if (sector->GetNextRoomNumber(_position, true).has_value()) + { + while (sector->GetNextRoomNumber(_position, true).has_value()) + { + room = &g_Level.Rooms[sector->GetNextRoomNumber(_position, true).value_or(sector->RoomNumber)]; + if (TestEnvironment(ENV_FLAG_WATER, room) || TestEnvironment(ENV_FLAG_SWAMP, room)) + break; + + sector = Room::GetSector(room, _position.x - room->Position.x, _position.z - room->Position.z); + } + + _waterTopHeight = sector->GetSurfaceHeight(_position, true); + return *_waterTopHeight; + } + + _waterTopHeight = NO_HEIGHT; return *_waterTopHeight; } diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp index d453e172e..a083624d0 100644 --- a/TombEngine/Game/collision/collide_room.cpp +++ b/TombEngine/Game/collision/collide_room.cpp @@ -1081,246 +1081,6 @@ int GetDistanceToFloor(int itemNumber, bool precise) return (minHeight + item.Pose.Position.y - height); } -int GetWaterSurface(int x, int y, int z, short roomNumber) -{ - auto* room = &g_Level.Rooms[roomNumber]; - auto* sector = GetSector(room, x - room->Position.x, z - room->Position.z); - - if (TestEnvironment(ENV_FLAG_WATER, room)) - { - while (sector->GetNextRoomNumber(Vector3i(x, y, z), false).has_value()) - { - room = &g_Level.Rooms[sector->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(sector->RoomNumber)]; - if (!TestEnvironment(ENV_FLAG_WATER, room)) - return (sector->GetSurfaceHeight(x, z, false)); - - sector = GetSector(room, x - room->Position.x, z - room->Position.z); - } - - return NO_HEIGHT; - } - else - { - while (sector->GetNextRoomNumber(Vector3i(x, y, z), true).has_value()) - { - room = &g_Level.Rooms[sector->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(sector->RoomNumber)]; - if (TestEnvironment(ENV_FLAG_WATER, room)) - return (sector->GetSurfaceHeight(x, z, true)); - - sector = GetSector(room, x - room->Position.x, z - room->Position.z); - } - } - - return NO_HEIGHT; -} - -int GetWaterSurface(ItemInfo* item) -{ - return GetWaterSurface(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->RoomNumber); -} - -int GetWaterDepth(int x, int y, int z, short roomNumber) -{ - FloorInfo* sector = nullptr; - auto* room = &g_Level.Rooms[roomNumber]; - - int adjoiningRoomNumber = NO_VALUE; - do - { - int xFloor = (x - room->Position.x) / BLOCK(1); - int zFloor = (z - room->Position.z) / BLOCK(1); - - if (zFloor <= 0) - { - zFloor = 0; - if (xFloor < 1) - { - xFloor = 1; - } - else if (xFloor > (room->XSize - 2)) - { - xFloor = room->XSize - 2; - } - } - else if (zFloor >= (room->ZSize - 1)) - { - zFloor = room->ZSize - 1; - if (xFloor < 1) - { - xFloor = 1; - } - else if (xFloor > (room->XSize - 2)) - { - xFloor = room->XSize - 2; - } - } - else if (xFloor < 0) - { - xFloor = 0; - } - else if (xFloor >= room->XSize) - { - xFloor = room->XSize - 1; - } - - sector = &room->Sectors[zFloor + (xFloor * room->ZSize)]; - adjoiningRoomNumber = sector->SidePortalRoomNumber; - if (adjoiningRoomNumber != NO_VALUE) - { - roomNumber = adjoiningRoomNumber; - room = &g_Level.Rooms[adjoiningRoomNumber]; - } - } - while (adjoiningRoomNumber != NO_VALUE); - - if (TestEnvironment(ENV_FLAG_WATER, room) || - TestEnvironment(ENV_FLAG_SWAMP, room)) - { - while (sector->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(NO_VALUE) != NO_VALUE) - { - room = &g_Level.Rooms[sector->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(sector->RoomNumber)]; - - if (!TestEnvironment(ENV_FLAG_WATER, room) && - !TestEnvironment(ENV_FLAG_SWAMP, room)) - { - int waterHeight = sector->GetSurfaceHeight(x, z, false); - int floorHeight = GetPointCollision(Vector3i(x, y, z), sector->RoomNumber).GetBottomSector().GetSurfaceHeight(x, z, true); - return (floorHeight - waterHeight); - } - - sector = GetSector(room, x - room->Position.x, z - room->Position.z); - } - - return DEEP_WATER; - } - else - { - while (sector->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(NO_VALUE) != NO_VALUE) - { - room = &g_Level.Rooms[sector->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(sector->RoomNumber)]; - - if (TestEnvironment(ENV_FLAG_WATER, room) || - TestEnvironment(ENV_FLAG_SWAMP, room)) - { - int waterHeight = sector->GetSurfaceHeight(x, z, true); - sector = GetFloor(x, y, z, &roomNumber); - return (GetFloorHeight(sector, x, y, z) - waterHeight); - } - - sector = GetSector(room, x - room->Position.x, z - room->Position.z); - } - - return NO_HEIGHT; - } -} - -int GetWaterDepth(ItemInfo* item) -{ - return GetWaterDepth(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->RoomNumber); -} - -int GetWaterHeight(int x, int y, int z, short roomNumber) -{ - FloorInfo* sector = nullptr; - auto* room = &g_Level.Rooms[roomNumber]; - - int adjoiningRoomNumber = NO_VALUE; - do - { - int xBlock = (x - room->Position.x) / BLOCK(1); - int zBlock = (z - room->Position.z) / BLOCK(1); - - if (zBlock <= 0) - { - zBlock = 0; - if (xBlock < 1) - { - xBlock = 1; - } - else if (xBlock > (room->XSize - 2)) - { - xBlock = room->XSize - 2; - } - } - else if (zBlock >= (room->ZSize - 1)) - { - zBlock = room->ZSize - 1; - if (xBlock < 1) - { - xBlock = 1; - } - else if (xBlock > (room->XSize - 2)) - { - xBlock = room->XSize - 2; - } - } - else if (xBlock < 0) - { - xBlock = 0; - } - else if (xBlock >= room->XSize) - { - xBlock = room->XSize - 1; - } - - sector = &room->Sectors[zBlock + (xBlock * room->ZSize)]; - adjoiningRoomNumber = sector->SidePortalRoomNumber; - - if (adjoiningRoomNumber != NO_VALUE) - { - roomNumber = adjoiningRoomNumber; - room = &g_Level.Rooms[adjoiningRoomNumber]; - } - } - while (adjoiningRoomNumber != NO_VALUE); - - if (sector->IsWall(x, z)) - return NO_HEIGHT; - - if (TestEnvironment(ENV_FLAG_WATER, room) || - TestEnvironment(ENV_FLAG_SWAMP, room)) - { - while (sector->GetNextRoomNumber(Vector3i(x, y, z), false).has_value()) - { - auto* room = &g_Level.Rooms[sector->GetNextRoomNumber(Vector3i(x, y, z), false).value_or(sector->RoomNumber)]; - - if (!TestEnvironment(ENV_FLAG_WATER, room) && - !TestEnvironment(ENV_FLAG_SWAMP, room)) - { - break; - } - - sector = GetSector(room, x - room->Position.x, z - room->Position.z); - } - - return sector->GetSurfaceHeight(Vector3i(x, y, z), false); - } - else if (sector->GetNextRoomNumber(Vector3i(x, y, z), true).has_value()) - { - while (sector->GetNextRoomNumber(Vector3i(x, y, z), true).has_value()) - { - auto* room2 = &g_Level.Rooms[sector->GetNextRoomNumber(Vector3i(x, y, z), true).value_or(sector->RoomNumber)]; - - if (TestEnvironment(ENV_FLAG_WATER, room2) || - TestEnvironment(ENV_FLAG_SWAMP, room2)) - { - break; - } - - sector = GetSector(room2, x - room2->Position.x, z - room2->Position.z); - } - - return sector->GetSurfaceHeight(Vector3i(x, y, z), true); - } - - return NO_HEIGHT; -} - -int GetWaterHeight(ItemInfo* item) -{ - return GetWaterHeight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->RoomNumber); -} - bool TestEnvironment(RoomEnvFlags environmentType, int x, int y, int z, int roomNumber) { return TestEnvironment(environmentType, GetPointCollision(Vector3i(x, y, z), roomNumber).GetRoomNumber()); @@ -1341,7 +1101,7 @@ bool TestEnvironment(RoomEnvFlags environmentType, int roomNumber) return TestEnvironment(environmentType, &g_Level.Rooms[roomNumber]); } -bool TestEnvironment(RoomEnvFlags environmentType, ROOM_INFO* room) +bool TestEnvironment(RoomEnvFlags environmentType, const ROOM_INFO* room) { return TestEnvironmentFlags(environmentType, room->flags); } diff --git a/TombEngine/Game/collision/collide_room.h b/TombEngine/Game/collision/collide_room.h index 1dc1c5ef2..41af7775f 100644 --- a/TombEngine/Game/collision/collide_room.h +++ b/TombEngine/Game/collision/collide_room.h @@ -137,13 +137,6 @@ int GetFloorHeight(FloorInfo* floor, int x, int y, int z); int GetCeiling(FloorInfo* floor, int x, int y, int z); int GetDistanceToFloor(int itemNumber, bool precise = true); -int GetWaterSurface(int x, int y, int z, short roomNumber); -int GetWaterSurface(ItemInfo* item); -int GetWaterDepth(int x, int y, int z, short roomNumber); -int GetWaterDepth(ItemInfo* item); -int GetWaterHeight(int x, int y, int z, short roomNumber); -int GetWaterHeight(ItemInfo* item); - int FindGridShift(int x, int z); void ShiftItem(ItemInfo* item, CollisionInfo* coll); void SnapItemToLedge(ItemInfo* item, CollisionInfo* coll, float offsetMultiplier = 0.0f, bool snapToAngle = true); @@ -157,5 +150,5 @@ bool TestEnvironment(RoomEnvFlags environmentType, int x, int y, int z, int room bool TestEnvironment(RoomEnvFlags environmentType, const Vector3i& pos, int roomNumber); bool TestEnvironment(RoomEnvFlags environmentType, const ItemInfo* item); bool TestEnvironment(RoomEnvFlags environmentType, int roomNumber); -bool TestEnvironment(RoomEnvFlags environmentType, ROOM_INFO* room); +bool TestEnvironment(RoomEnvFlags environmentType, const ROOM_INFO* room); bool TestEnvironmentFlags(RoomEnvFlags environmentType, int flags); diff --git a/TombEngine/Game/control/box.cpp b/TombEngine/Game/control/box.cpp index 6b765938f..20640dd0f 100644 --- a/TombEngine/Game/control/box.cpp +++ b/TombEngine/Game/control/box.cpp @@ -613,7 +613,7 @@ void CreatureUnderwater(ItemInfo* item, int depth) } else { - waterHeight = GetWaterHeight(item); + waterHeight = GetPointCollision(*item).GetWaterTopHeight(); } int y = waterHeight + waterLevel; @@ -647,7 +647,7 @@ void CreatureFloat(short itemNumber) item->Pose.Orientation.x = 0; int y = item->Pose.Position.y; - int waterLevel = GetWaterHeight(item); + int waterLevel = GetPointCollision(*item).GetWaterTopHeight(); if (waterLevel == NO_HEIGHT) return; @@ -794,7 +794,7 @@ void CreatureHealth(ItemInfo* item) TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, &g_Level.Rooms[item->RoomNumber])) { auto bounds = GameBoundingBox(item); - auto height = item->Pose.Position.y - GetWaterHeight(item); + auto height = item->Pose.Position.y - GetPointCollision(*item).GetWaterTopHeight(); if (abs(bounds.Y1 + bounds.Y2) < height) DoDamage(item, INT_MAX); diff --git a/TombEngine/Game/effects/drip.cpp b/TombEngine/Game/effects/drip.cpp index 08336ecfc..69e5370ab 100644 --- a/TombEngine/Game/effects/drip.cpp +++ b/TombEngine/Game/effects/drip.cpp @@ -130,9 +130,8 @@ namespace TEN::Effects::Drip // Spawn ripple on surface only. if (!TestEnvironment(ENV_FLAG_WATER, prevRoomNumber)) { - float waterHeight = GetWaterHeight(drip.Position.x, drip.Position.y, drip.Position.z, drip.RoomNumber); SpawnRipple( - Vector3(drip.Position.x, waterHeight - RIPPLE_HEIGHT_OFFSET, drip.Position.z), + Vector3(drip.Position.x, pointColl.GetWaterTopHeight() - RIPPLE_HEIGHT_OFFSET, drip.Position.z), pointColl.GetRoomNumber(), Random::GenerateFloat(RIPPLE_SIZE_WATER_MIN, RIPPLE_SIZE_WATER_MAX), (int)RippleFlags::SlowFade | (int)RippleFlags::LowOpacity); diff --git a/TombEngine/Game/effects/effects.cpp b/TombEngine/Game/effects/effects.cpp index 128c65022..a2b52a526 100644 --- a/TombEngine/Game/effects/effects.cpp +++ b/TombEngine/Game/effects/effects.cpp @@ -1308,7 +1308,7 @@ void Splash(ItemInfo* item) if (!TestEnvironment(ENV_FLAG_WATER, probedRoomNumber)) return; - int waterHeight = GetWaterHeight(item); + int waterHeight = GetPointCollision(*item).GetWaterTopHeight(); SplashSetup.x = item->Pose.Position.x; SplashSetup.y = waterHeight - 1; @@ -1940,7 +1940,7 @@ void ProcessEffects(ItemInfo* item) if (item->Effect.Type != EffectType::Sparks && item->Effect.Type != EffectType::Smoke) { const auto& bounds = GameBoundingBox(item); - int waterHeight = GetWaterHeight(item); + int waterHeight = GetPointCollision(*item).GetWaterTopHeight(); int itemLevel = item->Pose.Position.y + bounds.Y2 - (bounds.GetHeight() / 3); if (waterHeight != NO_HEIGHT && itemLevel > waterHeight) diff --git a/TombEngine/Game/effects/hair.cpp b/TombEngine/Game/effects/hair.cpp index 5ca0c4c0e..86262876f 100644 --- a/TombEngine/Game/effects/hair.cpp +++ b/TombEngine/Game/effects/hair.cpp @@ -69,7 +69,7 @@ namespace TEN::Effects::Hair // Get water height. auto pos = item.Pose.Position + Vector3i(GetWaterProbeOffset(item)); int roomNumber = item.RoomNumber; - int waterHeight = GetWaterHeight(pos.x, pos.y, pos.z, roomNumber); + int waterHeight = GetPointCollision(pos, roomNumber).GetWaterTopHeight(); // Get collision spheres. auto spheres = GetSpheres(item, isYoung); diff --git a/TombEngine/Game/effects/tomb4fx.cpp b/TombEngine/Game/effects/tomb4fx.cpp index f5bf359da..2e77628d8 100644 --- a/TombEngine/Game/effects/tomb4fx.cpp +++ b/TombEngine/Game/effects/tomb4fx.cpp @@ -5,6 +5,7 @@ #include "Game/animation.h" #include "Game/collision/collide_room.h" #include "Game/collision/floordata.h" +#include "Game/collision/Point.h" #include "Game/effects/effects.h" #include "Game/effects/Bubble.h" #include "Game/effects/debris.h" @@ -27,6 +28,7 @@ using namespace TEN::Effects::Environment; using namespace TEN::Effects::Ripple; using namespace TEN::Effects::Smoke; using namespace TEN::Collision::Floordata; +using namespace TEN::Collision::Point; using namespace TEN::Math; using TEN::Renderer::g_Renderer; @@ -1117,7 +1119,7 @@ void TriggerUnderwaterExplosion(ItemInfo* item, int flag) TriggerExplosionBubbles(x, y, z, item->RoomNumber); TriggerExplosionSparks(x, y, z, 2, -1, 1, item->RoomNumber); - int waterHeight = GetWaterHeight(x, y, z, item->RoomNumber); + int waterHeight = GetPointCollision(Vector3i(x, y, z), item->RoomNumber).GetWaterTopHeight(); if (waterHeight != NO_HEIGHT) SomeSparkEffect(x, waterHeight, z, 8); } @@ -1129,7 +1131,7 @@ void TriggerUnderwaterExplosion(ItemInfo* item, int flag) for (int i = 0; i < 3; i++) TriggerExplosionSparks(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, 2, -1, 1, item->RoomNumber); - int waterHeight = GetWaterHeight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->RoomNumber); + int waterHeight = GetPointCollision(*item).GetWaterTopHeight(); if (waterHeight != NO_HEIGHT) { int dy = item->Pose.Position.y - waterHeight; diff --git a/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp b/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp index cfd63dc11..97f53fb50 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp @@ -2,6 +2,7 @@ #include "Objects/TR1/Entity/tr1_big_rat.h" #include "Game/collision/collide_room.h" +#include "Game/collision/Point.h" #include "Game/control/box.h" #include "Game/control/control.h" #include "Game/effects/effects.h" @@ -13,6 +14,7 @@ #include "Math/Math.h" #include "Specific/level.h" +using namespace TEN::Collision::Point; using namespace TEN::Math; namespace TEN::Entities::Creatures::TR1 @@ -83,8 +85,7 @@ namespace TEN::Entities::Creatures::TR1 bool RatOnWater(ItemInfo* item) { - int waterDepth = GetWaterSurface(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->RoomNumber); - + int waterDepth = GetPointCollision(*item).GetWaterSurfaceHeight(); if (item->IsCreature()) { auto& creature = *GetCreatureInfo(item); @@ -240,7 +241,7 @@ namespace TEN::Entities::Creatures::TR1 if (RatOnWater(item)) { CreatureUnderwater(item, 0); - item->Pose.Position.y = GetWaterHeight(item) - BIG_RAT_WATER_SURFACE_OFFSET; + item->Pose.Position.y = GetPointCollision(*item).GetWaterTopHeight() - BIG_RAT_WATER_SURFACE_OFFSET; } else { diff --git a/TombEngine/Objects/TR2/Vehicles/speedboat.cpp b/TombEngine/Objects/TR2/Vehicles/speedboat.cpp index f0914c1b7..e9807e149 100644 --- a/TombEngine/Objects/TR2/Vehicles/speedboat.cpp +++ b/TombEngine/Objects/TR2/Vehicles/speedboat.cpp @@ -549,11 +549,11 @@ namespace TEN::Entities::Vehicles SpeedboatDoShift(speedboatItem, &f, &frontOld); } - auto probe = GetPointCollision(*speedboatItem); - auto height = GetWaterHeight(speedboatItem->Pose.Position.x, speedboatItem->Pose.Position.y - 5, speedboatItem->Pose.Position.z, probe.GetRoomNumber()); + auto pointColl = GetPointCollision(*speedboatItem); + auto height = GetPointCollision(Vector3i(speedboatItem->Pose.Position.x, speedboatItem->Pose.Position.y - 5, speedboatItem->Pose.Position.z), pointColl.GetRoomNumber()).GetWaterTopHeight(); if (height == NO_HEIGHT) - height = GetFloorHeight(&probe.GetSector(), speedboatItem->Pose.Position.x, speedboatItem->Pose.Position.y - 5, speedboatItem->Pose.Position.z); + height = GetFloorHeight(&pointColl.GetSector(), speedboatItem->Pose.Position.x, speedboatItem->Pose.Position.y - 5, speedboatItem->Pose.Position.z); if (height < (speedboatItem->Pose.Position.y - CLICK(0.5f))) SpeedboatDoShift(speedboatItem, (Vector3i*)&speedboatItem->Pose, &old); @@ -825,7 +825,7 @@ namespace TEN::Entities::Vehicles TestTriggers(speedboatItem, false); } - auto water = GetWaterHeight(speedboatItem->Pose.Position.x, speedboatItem->Pose.Position.y, speedboatItem->Pose.Position.z, probe.GetRoomNumber()); + auto water = GetPointCollision(Vector3i(speedboatItem->Pose.Position.x, speedboatItem->Pose.Position.y, speedboatItem->Pose.Position.z), probe.GetRoomNumber()).GetWaterTopHeight(); speedboat->Water = water; bool noTurn = true; @@ -968,7 +968,7 @@ namespace TEN::Entities::Vehicles TEN::Effects::TriggerSpeedboatFoam(speedboatItem, Vector3(0.0f, 0.0f, SPEEDBOAT_BACK)); } - int waterHeight = GetWaterHeight(speedboatItem); + int waterHeight = GetPointCollision(*speedboatItem).GetWaterTopHeight(); SpawnVehicleWake(*speedboatItem, SPEEDBOAT_WAKE_OFFSET, waterHeight); } } diff --git a/TombEngine/Objects/TR3/Entity/FishSwarm.cpp b/TombEngine/Objects/TR3/Entity/FishSwarm.cpp index e9d5fedd5..bcab64a3b 100644 --- a/TombEngine/Objects/TR3/Entity/FishSwarm.cpp +++ b/TombEngine/Objects/TR3/Entity/FishSwarm.cpp @@ -221,7 +221,6 @@ namespace TEN::Entities::Creatures::TR3 // Get point collision. auto pointColl = GetPointCollision(pos, item.RoomNumber); - int waterHeight = GetWaterHeight(pointColl.GetPosition().x, pointColl.GetPosition().y, pointColl.GetPosition().z, pointColl.GetRoomNumber()); // 1) Test for water room. if (!TestEnvironment(ENV_FLAG_WATER, pointColl.GetRoomNumber())) @@ -229,7 +228,7 @@ namespace TEN::Entities::Creatures::TR3 // 2) Assess point collision. if (pos.y >= (pointColl.GetFloorHeight() - BUFFER) || - pos.y <= (waterHeight + BUFFER) || + pos.y <= (pointColl.GetWaterTopHeight() + BUFFER) || pointColl.GetSector().IsWall(item.Pose.Position.x + BUFFER, item.Pose.Position.z + BUFFER) || pointColl.GetSector().IsWall(item.Pose.Position.x - BUFFER, item.Pose.Position.z - BUFFER)) { @@ -380,7 +379,7 @@ namespace TEN::Entities::Creatures::TR3 } // Clamp position to slightly below water surface. - int waterHeight = GetWaterHeight(fish.Position.x, fish.Position.y, fish.Position.z, fish.RoomNumber); + int waterHeight = pointColl.GetWaterTopHeight(); if (fish.Position.y < (waterHeight + WATER_SURFACE_OFFSET)) fish.Position.y = waterHeight + WATER_SURFACE_OFFSET; diff --git a/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp b/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp index 92b5c5a95..9f4baad45 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp @@ -130,11 +130,11 @@ namespace TEN::Entities::Creatures::TR3 } else { - AI_INFO AI; - CreatureAIInfo(item, &AI); + AI_INFO ai; + CreatureAIInfo(item, &ai); - GetCreatureMood(item, &AI, false); - CreatureMood(item, &AI, false); + GetCreatureMood(item, &ai, false); + CreatureMood(item, &ai, false); bool shoot = false; if (Lara.Control.WaterStatus == WaterStatus::Dry) @@ -143,23 +143,21 @@ namespace TEN::Entities::Creatures::TR3 item->Pose.Position.x, item->Pose.Position.y - CLICK(1), item->Pose.Position.z, - item->RoomNumber - ); + item->RoomNumber); auto target = GameVector( LaraItem->Pose.Position.x, LaraItem->Pose.Position.y - (LARA_HEIGHT - 150), - LaraItem->Pose.Position.z - ); + LaraItem->Pose.Position.z); shoot = LOS(&origin, &target); if (shoot) creature->Target = LaraItem->Pose.Position; - if (AI.angle < -ANGLE(45.0f) || AI.angle > ANGLE(45.0f)) + if (ai.angle < -ANGLE(45.0f) || ai.angle > ANGLE(45.0f)) shoot = false; } - else if (AI.angle > -ANGLE(45.0f) && AI.angle < ANGLE(45.0f)) + else if (ai.angle > -ANGLE(45.0f) && ai.angle < ANGLE(45.0f)) { auto origin = GameVector(item->Pose.Position, item->RoomNumber); auto target = GameVector(LaraItem->Pose.Position); @@ -168,7 +166,7 @@ namespace TEN::Entities::Creatures::TR3 } angle = CreatureTurn(item, creature->MaxTurn); - waterHeight = GetWaterSurface(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->RoomNumber) + BLOCK(0.5f); + waterHeight = GetPointCollision(*item).GetWaterSurfaceHeight() + BLOCK(0.5f); switch (item->Animation.ActiveState) { @@ -176,7 +174,7 @@ namespace TEN::Entities::Creatures::TR3 creature->MaxTurn = SCUBA_DIVER_SWIM_TURN_RATE_MAX; if (shoot) - neck = -AI.angle; + neck = -ai.angle; if (creature->Target.y < waterHeight && item->Pose.Position.y < (waterHeight + creature->LOT.Fly)) @@ -194,7 +192,7 @@ namespace TEN::Entities::Creatures::TR3 creature->Flags = 0; if (shoot) - neck = -AI.angle; + neck = -ai.angle; if (!shoot || creature->Mood == MoodType::Escape || (creature->Target.y < waterHeight && @@ -209,7 +207,7 @@ namespace TEN::Entities::Creatures::TR3 case SDIVER_STATE_SWIM_SHOOT: if (shoot) - neck = -AI.angle; + neck = -ai.angle; if (!creature->Flags) { @@ -224,7 +222,7 @@ namespace TEN::Entities::Creatures::TR3 creature->MaxTurn = SCUBA_DIVER_SWIM_TURN_RATE_MAX; if (shoot) - head = AI.angle; + head = ai.angle; if (creature->Target.y > waterHeight) item->Animation.TargetState = SDIVER_STATE_SWIM; @@ -239,7 +237,7 @@ namespace TEN::Entities::Creatures::TR3 creature->Flags = 0; if (shoot) - head = AI.angle; + head = ai.angle; if (!shoot || creature->Mood == MoodType::Escape || creature->Target.y > waterHeight) item->Animation.TargetState = SDIVER_STATE_TREAD_WATER_IDLE; @@ -250,7 +248,7 @@ namespace TEN::Entities::Creatures::TR3 case SDIVER_STATE_TREAD_WATER_SHOOT: if (shoot) - head = AI.angle; + head = ai.angle; if (!creature->Flags) { diff --git a/TombEngine/Objects/TR3/Object/corpse.cpp b/TombEngine/Objects/TR3/Object/corpse.cpp index c646f49f4..295792a8a 100644 --- a/TombEngine/Objects/TR3/Object/corpse.cpp +++ b/TombEngine/Objects/TR3/Object/corpse.cpp @@ -74,24 +74,24 @@ namespace TEN::Entities::TR3 bool isWater = TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, item.RoomNumber); float verticalVelCoeff = isWater ? 81.0f : 1.0f; - int roomNumber = GetPointCollision(item).GetRoomNumber(); - if (item.RoomNumber != roomNumber) + auto pointColl = GetPointCollision(item); + if (item.RoomNumber != pointColl.GetRoomNumber()) { - if (TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, roomNumber) && + if (TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, pointColl.GetRoomNumber()) && !TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, item.RoomNumber)) { - int waterHeight = GetWaterHeight(item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z, roomNumber); + int waterHeight = pointColl.GetWaterTopHeight(); SplashSetup.y = waterHeight - 1; SplashSetup.x = item.Pose.Position.x; SplashSetup.z = item.Pose.Position.z; SplashSetup.splashPower = item.Animation.Velocity.y * 4; SplashSetup.innerRadius = 160.0f; - SetupSplash(&SplashSetup, roomNumber); + SetupSplash(&SplashSetup, pointColl.GetRoomNumber()); item.Animation.Velocity.y = 0.0f; } - ItemNewRoom(itemNumber, roomNumber); + ItemNewRoom(itemNumber, pointColl.GetRoomNumber()); } auto pointColl = GetPointCollision(item); diff --git a/TombEngine/Objects/TR3/Vehicles/kayak.cpp b/TombEngine/Objects/TR3/Vehicles/kayak.cpp index 242998432..69d165de6 100644 --- a/TombEngine/Objects/TR3/Vehicles/kayak.cpp +++ b/TombEngine/Objects/TR3/Vehicles/kayak.cpp @@ -215,7 +215,7 @@ namespace TEN::Entities::Vehicles int z = kayakItem->Pose.Position.z + (zOffset * cosY) - (xOffset * sinY); int probedRoomNumber = GetPointCollision(Vector3i(x, kayakItem->Pose.Position.y, z), kayakItem->RoomNumber).GetRoomNumber(); - int waterHeight = GetWaterHeight(x, kayakItem->Pose.Position.y, z, probedRoomNumber); + int waterHeight = GetPointCollision(Vector3i(x, kayakItem->Pose.Position.y, z), probedRoomNumber).GetWaterTopHeight(); //if (waterHeight != NO_HEIGHT) // SetupRipple(x, kayakItem->Pose.Position.y, z, -2 - (GetRandomControl() & 1), 0, Objects[ID_KAYAK_PADDLE_TRAIL_SPRITE].meshIndex,TO_RAD(kayakItem->Pose.Orientation.y)); @@ -538,7 +538,7 @@ namespace TEN::Entities::Vehicles auto probe = GetPointCollision(*kayakItem); int probedRoomNum = probe.GetRoomNumber(); - height2 = GetWaterHeight(kayakItem->Pose.Position.x, kayakItem->Pose.Position.y, kayakItem->Pose.Position.z, probedRoomNum); + height2 = GetPointCollision(kayakItem->Pose.Position, probedRoomNum).GetWaterTopHeight(); if (height2 == NO_HEIGHT) height2 = probe.GetFloorHeight(); @@ -548,7 +548,7 @@ namespace TEN::Entities::Vehicles probe = GetPointCollision(*kayakItem); probedRoomNum = probe.GetRoomNumber(); - height2 = GetWaterHeight(kayakItem->Pose.Position.x, kayakItem->Pose.Position.y, kayakItem->Pose.Position.z, probedRoomNum); + height2 = GetPointCollision(kayakItem->Pose.Position, probedRoomNum).GetWaterTopHeight(); if (height2 == NO_HEIGHT) height2 = probe.GetFloorHeight(); @@ -1084,7 +1084,7 @@ namespace TEN::Entities::Vehicles TestTriggers(kayakItem, false); auto probe = GetPointCollision(*kayakItem); - int water = GetWaterHeight(kayakItem->Pose.Position.x, kayakItem->Pose.Position.y, kayakItem->Pose.Position.z, probe.GetRoomNumber()); + int water = GetPointCollision(kayakItem->Pose.Position, probe.GetRoomNumber()).GetWaterTopHeight(); kayak->WaterHeight = water; if (kayak->WaterHeight == NO_HEIGHT) @@ -1131,7 +1131,7 @@ namespace TEN::Entities::Vehicles if (kayak->TrueWater && (kayakItem->Animation.Velocity.z != 0.0f || lara->Context.WaterCurrentPull != Vector3i::Zero)) { - int waterHeight = GetWaterHeight(kayakItem); + int waterHeight = GetPointCollision(*kayakItem).GetWaterTopHeight(); SpawnVehicleWake(*kayakItem, KAYAK_WAKE_OFFSET, waterHeight); } diff --git a/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp b/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp index ef36e34c7..4d63e4247 100644 --- a/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp +++ b/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp @@ -423,7 +423,7 @@ namespace TEN::Entities::Vehicles short roomNumber = rBoatItem->RoomNumber; auto floor = GetFloor(rBoatItem->Pose.Position.x, rBoatItem->Pose.Position.y, rBoatItem->Pose.Position.z, &roomNumber); - int height = GetWaterHeight(rBoatItem->Pose.Position.x, rBoatItem->Pose.Position.y, rBoatItem->Pose.Position.z, roomNumber); + int height = GetPointCollision(rBoatItem->Pose.Position, roomNumber).GetWaterTopHeight(); if (height == NO_HEIGHT) height = GetFloorHeight(floor, rBoatItem->Pose.Position.x, rBoatItem->Pose.Position.y, rBoatItem->Pose.Position.z); @@ -827,7 +827,7 @@ namespace TEN::Entities::Vehicles } auto probe = GetPointCollision(*rBoatItem); - int water = GetWaterHeight(rBoatItem->Pose.Position.x, rBoatItem->Pose.Position.y, rBoatItem->Pose.Position.z, probe.GetRoomNumber()); + int water = GetPointCollision(rBoatItem->Pose.Position, probe.GetRoomNumber()).GetWaterTopHeight(); rBoat->Water = water; if (lara->Context.Vehicle == itemNumber && laraItem->HitPoints > 0) @@ -936,7 +936,7 @@ namespace TEN::Entities::Vehicles DoRubberBoatDismount(rBoatItem, laraItem); short probedRoomNumber = GetPointCollision(Vector3i(rBoatItem->Pose.Position.x, rBoatItem->Pose.Position.y + 128, rBoatItem->Pose.Position.z), rBoatItem->RoomNumber).GetRoomNumber(); - height = GetWaterHeight(rBoatItem->Pose.Position.x, rBoatItem->Pose.Position.y + 128, rBoatItem->Pose.Position.z, probedRoomNumber); + height = GetPointCollision(Vector3i(rBoatItem->Pose.Position.x, rBoatItem->Pose.Position.y + 128, rBoatItem->Pose.Position.z), probedRoomNumber).GetWaterTopHeight(); if (height > rBoatItem->Pose.Position.y + 32 || height == NO_HEIGHT) height = 0; else @@ -951,7 +951,7 @@ namespace TEN::Entities::Vehicles { TriggerRubberBoatMist(prop.x, prop.y, prop.z, abs(rBoatItem->Animation.Velocity.z), rBoatItem->Pose.Orientation.y + ANGLE(180.0f), 0); - int waterHeight = GetWaterHeight(rBoatItem); + int waterHeight = GetPointCollision(*rBoatItem).GetWaterTopHeight(); SpawnVehicleWake(*rBoatItem, RBOAT_WAKE_OFFSET, waterHeight); if ((GetRandomControl() & 1) == 0) diff --git a/TombEngine/Objects/TR3/Vehicles/upv.cpp b/TombEngine/Objects/TR3/Vehicles/upv.cpp index 2a5928033..dceac3961 100644 --- a/TombEngine/Objects/TR3/Vehicles/upv.cpp +++ b/TombEngine/Objects/TR3/Vehicles/upv.cpp @@ -731,8 +731,9 @@ namespace TEN::Entities::Vehicles UPV->Flags &= ~UPV_FLAG_CONTROL; int waterDepth, waterHeight, heightFromWater; - waterDepth = GetWaterSurface(laraItem); - waterHeight = GetWaterHeight(laraItem); + auto pointColl = GetPointCollision(*laraItem); + waterDepth = pointColl.GetWaterSurfaceHeight(); + waterHeight = pointColl.GetWaterTopHeight(); if (waterHeight != NO_HEIGHT) heightFromWater = laraItem->Pose.Position.y - waterHeight; @@ -871,8 +872,9 @@ namespace TEN::Entities::Vehicles TranslateItem(UPVItem, UPVItem->Pose.Orientation, UPVItem->Animation.Velocity.z); } - int newHeight = GetPointCollision(*UPVItem).GetFloorHeight(); - int waterHeight = GetWaterHeight(UPVItem); + auto pointColl = GetPointCollision(*UPVItem); + int newHeight = pointColl.GetFloorHeight(); + int waterHeight = pointColl.GetWaterTopHeight(); if ((newHeight - waterHeight) < UPV_HEIGHT || (newHeight < UPVItem->Pose.Position.y - UPV_HEIGHT / 2) || (newHeight == NO_HEIGHT) || (waterHeight == NO_HEIGHT)) @@ -943,7 +945,7 @@ namespace TEN::Entities::Vehicles if (UPV->Velocity || IsDirectionalActionHeld()) { - waterHeight = GetWaterHeight(UPVItem); + waterHeight = GetPointCollision(*UPVItem).GetWaterTopHeight(); SpawnVehicleWake(*UPVItem, UPV_WAKE_OFFSET, waterHeight, true); } diff --git a/TombEngine/Objects/TR4/Entity/tr4_crocodile.cpp b/TombEngine/Objects/TR4/Entity/tr4_crocodile.cpp index 22b35629a..8f3013e92 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_crocodile.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_crocodile.cpp @@ -3,6 +3,7 @@ #include "Game/animation.h" #include "Game/collision/collide_room.h" +#include "Game/collision/Point.h" #include "Game/control/box.h" #include "Game/control/control.h" #include "Game/effects/effects.h" @@ -15,6 +16,7 @@ #include "Math/Math.h" #include "Specific/level.h" +using namespace TEN::Collision::Point; using namespace TEN::Math; namespace TEN::Entities::TR4 @@ -90,7 +92,7 @@ namespace TEN::Entities::TR4 { auto* creature = GetCreatureInfo(item); - int waterDepth = GetWaterSurface(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->RoomNumber); + int waterDepth = GetPointCollision(*item).GetWaterSurfaceHeight(); if (waterDepth != NO_HEIGHT) { creature->LOT.Step = BLOCK(20); diff --git a/TombEngine/Objects/TR5/Object/tr5_bodypart.cpp b/TombEngine/Objects/TR5/Object/tr5_bodypart.cpp index dcb5e844d..e95d695c4 100644 --- a/TombEngine/Objects/TR5/Object/tr5_bodypart.cpp +++ b/TombEngine/Objects/TR5/Object/tr5_bodypart.cpp @@ -209,7 +209,7 @@ void ControlBodyPart(short fxNumber) if (TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, pointColl.GetRoomNumber()) && !TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, fx->roomNumber)) { - int waterHeight = GetWaterHeight(fx->pos.Position.x, fx->pos.Position.y, fx->pos.Position.z, pointColl.GetRoomNumber()); + int waterHeight = GetPointCollision(fx->pos.Position, pointColl.GetRoomNumber()).GetWaterTopHeight(); SplashSetup.y = waterHeight - 1; SplashSetup.x = fx->pos.Position.x; diff --git a/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp b/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp index 5b46ad3b0..f7e3b7211 100644 --- a/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp +++ b/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp @@ -259,23 +259,22 @@ void RollingBallControl(short itemNumber) } } - auto roomNumber = GetPointCollision(*item).GetRoomNumber(); - - if (item->RoomNumber != roomNumber) + auto pointColl = GetPointCollision(*item); + if (item->RoomNumber != pointColl.GetRoomNumber()) { - if (TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, roomNumber) && + if (TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, pointColl.GetRoomNumber()) && !TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, item->RoomNumber)) { - int waterHeight = GetWaterHeight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, roomNumber); + int waterHeight = pointColl.GetWaterTopHeight(); SplashSetup.y = waterHeight - 1; SplashSetup.x = item->Pose.Position.x; SplashSetup.z = item->Pose.Position.z; SplashSetup.splashPower = item->Animation.Velocity.y * 4; SplashSetup.innerRadius = 160; - SetupSplash(&SplashSetup, roomNumber); + SetupSplash(&SplashSetup, pointColl.GetRoomNumber()); } - ItemNewRoom(itemNumber, roomNumber); + ItemNewRoom(itemNumber, pointColl.GetRoomNumber()); } if (item->ItemFlags[0] > ROLLING_BALL_MAX_VELOCITY) diff --git a/TombEngine/Objects/Utils/VehicleHelpers.cpp b/TombEngine/Objects/Utils/VehicleHelpers.cpp index ae9a5b137..d2a121bb7 100644 --- a/TombEngine/Objects/Utils/VehicleHelpers.cpp +++ b/TombEngine/Objects/Utils/VehicleHelpers.cpp @@ -178,7 +178,7 @@ namespace TEN::Entities::Vehicles *pos = Vector3i(point); auto pointColl = GetPointCollision(*pos, vehicleItem->RoomNumber); - int height = GetWaterHeight(pos->x, pos->y, pos->z, pointColl.GetRoomNumber()); + int height = GetPointCollision(Vector3i(pos->x, pos->y, pos->z), pointColl.GetRoomNumber()).GetWaterTopHeight(); if (height == NO_HEIGHT) { @@ -218,7 +218,7 @@ namespace TEN::Entities::Vehicles if (TestEnvironment(ENV_FLAG_WATER, vehicleItem) || TestEnvironment(ENV_FLAG_SWAMP, vehicleItem)) { - auto waterDepth = (float)GetWaterDepth(vehicleItem); + int waterDepth = GetPointCollision(*vehicleItem).GetWaterBottomHeight(); // HACK: Sometimes quadbike test position may end up under non-portal ceiling block. // GetWaterDepth returns DEEP_WATER constant in that case, which is too large for our needs. @@ -239,11 +239,8 @@ namespace TEN::Entities::Vehicles if (isWater) { - int waterHeight = GetWaterHeight(vehicleItem); + int waterHeight = GetPointCollision(*vehicleItem).GetWaterTopHeight(); SpawnVehicleWake(*vehicleItem, wakeOffset, waterHeight); - - //SpawnStreamer(vehicleItem, -wakeOffset.x, waterHeight / 2, wakeOffset.z, 1, true, 5.0f, 50, 9.0f); - //SpawnStreamer(vehicleItem, wakeOffset.x, waterHeight / 2, wakeOffset.z, 2, true, 5.0f, 50, 9.0f); } } @@ -255,7 +252,7 @@ namespace TEN::Entities::Vehicles } else { - int waterHeight = vehicleItem->Pose.Position.y - GetWaterHeight(vehicleItem); + int waterHeight = vehicleItem->Pose.Position.y - GetPointCollision(*vehicleItem).GetWaterTopHeight(); if (waterDepth > VEHICLE_WATER_HEIGHT_MAX && waterHeight > VEHICLE_WATER_HEIGHT_MAX) { From 349d7e5cdd2e4ede8830f76c05135956f2c5858d Mon Sep 17 00:00:00 2001 From: TokyoSU <77746747+TokyoSU@users.noreply.github.com> Date: Thu, 15 Aug 2024 20:15:46 +0200 Subject: [PATCH 11/17] Fixed hair again (for good this time) --- TombEngine/Game/effects/hair.cpp | 52 +++++----- TombEngine/Game/effects/hair.h | 2 +- TombEngine/Objects/TR3/Object/corpse.cpp | 2 +- TombEngine/Objects/game_object_ids.h | 1 + TombEngine/Renderer/RendererCompatibility.cpp | 94 ++++++++++++++++--- TombEngine/Renderer/RendererLara.cpp | 38 ++++++-- .../Internal/TEN/Objects/ObjectIDs.h | 1 + 7 files changed, 148 insertions(+), 42 deletions(-) diff --git a/TombEngine/Game/effects/hair.cpp b/TombEngine/Game/effects/hair.cpp index 86262876f..77f9d60dc 100644 --- a/TombEngine/Game/effects/hair.cpp +++ b/TombEngine/Game/effects/hair.cpp @@ -23,7 +23,7 @@ namespace TEN::Effects::Hair { HairEffectController HairEffect = {}; - void HairUnit::Update(const ItemInfo& item, int hairUnitIndex) + void HairUnit::Update(const ItemInfo& item, GAME_OBJECT_ID objectNumber, int hairUnitIndex) { const auto& player = GetLaraInfo(item); @@ -53,7 +53,7 @@ namespace TEN::Effects::Hair auto& nextSegment = Segments[i + 1]; // NOTE: Joint offset determines segment length. - auto jointOffset = GetJointOffset(ID_HAIR, i); + auto jointOffset = GetJointOffset(objectNumber, i); worldMatrix = Matrix::CreateTranslation(segment.Position); worldMatrix = Matrix::CreateFromQuaternion(segment.Orientation) * worldMatrix; @@ -98,8 +98,8 @@ namespace TEN::Effects::Hair segment.WorldMatrix = worldMatrix; auto jointOffset = (i == (Segments.size() - 1)) ? - GetJointOffset(ID_HAIR, (i - 1) - 1) : - GetJointOffset(ID_HAIR, (i - 1)); + GetJointOffset(objectNumber, (i - 1) - 1) : + GetJointOffset(objectNumber, (i - 1)); worldMatrix = Matrix::CreateTranslation(jointOffset) * worldMatrix; segment.Position = worldMatrix.Translation(); @@ -320,30 +320,38 @@ namespace TEN::Effects::Hair bool isYoung = (g_GameFlow->GetLevel(CurrentLevel)->GetLaraType() == LaraType::Young); // Initialize hair units. - bool isHead = true; - for (auto& unit : Units) + auto& unit0 = Units[0]; + unit0.IsEnabled = Objects[ID_HAIR].loaded; + unit0.IsInitialized = false; + unit0.Segments.resize(Objects[ID_HAIR].nmeshes + 1); + // Initialize segments. + for (auto& segment : unit0.Segments) { - unit.IsEnabled = (!isHead || isYoung); - unit.IsInitialized = false; - - unsigned int segmentCount = Objects[ID_HAIR].nmeshes + 1; - unit.Segments.resize(segmentCount); + segment.Position = GetJointOffset(ID_HAIR, 0); + segment.Velocity = Vector3::Zero; + segment.Orientation = DEFAULT_ORIENT.ToQuaternion(); + } - // Initialize segments. - for (auto& segment : unit.Segments) - { - segment.Position = GetJointOffset(ID_HAIR, 0); - segment.Velocity = Vector3::Zero; - segment.Orientation = DEFAULT_ORIENT.ToQuaternion(); - } - - isHead = false; + auto& unit1 = Units[1]; + unit1.IsEnabled = Objects[ID_HAIR_2].loaded && isYoung; + unit1.IsInitialized = false; + unit1.Segments.resize(Objects[ID_HAIR_2].nmeshes + 1); + // Initialize segments. + for (auto& segment : unit1.Segments) + { + segment.Position = GetJointOffset(ID_HAIR_2, 0); + segment.Velocity = Vector3::Zero; + segment.Orientation = DEFAULT_ORIENT.ToQuaternion(); } } void HairEffectController::Update(ItemInfo& item) { - for (int i = 0; i < Units.size(); i++) - Units[i].Update(item, i); + auto& unit0 = Units[0]; + if (unit0.IsEnabled) + unit0.Update(item, ID_HAIR, 0); + auto& unit1 = Units[1]; + if (unit1.IsEnabled) + unit1.Update(item, ID_HAIR_2, 1); } } diff --git a/TombEngine/Game/effects/hair.h b/TombEngine/Game/effects/hair.h index be4baa049..6ae1bc9e7 100644 --- a/TombEngine/Game/effects/hair.h +++ b/TombEngine/Game/effects/hair.h @@ -28,7 +28,7 @@ namespace TEN::Effects::Hair // Utilities - void Update(const ItemInfo& item, int hairUnitIndex); + void Update(const ItemInfo& item, GAME_OBJECT_ID objectNumber, int hairUnitIndex); private: // Helpers diff --git a/TombEngine/Objects/TR3/Object/corpse.cpp b/TombEngine/Objects/TR3/Object/corpse.cpp index 295792a8a..d27b409ec 100644 --- a/TombEngine/Objects/TR3/Object/corpse.cpp +++ b/TombEngine/Objects/TR3/Object/corpse.cpp @@ -94,7 +94,7 @@ namespace TEN::Entities::TR3 ItemNewRoom(itemNumber, pointColl.GetRoomNumber()); } - auto pointColl = GetPointCollision(item); + pointColl = GetPointCollision(item); item.Animation.IsAirborne = true; if (pointColl.GetFloorHeight() < item.Pose.Position.y) diff --git a/TombEngine/Objects/game_object_ids.h b/TombEngine/Objects/game_object_ids.h index 21132980f..19aa5bd8f 100644 --- a/TombEngine/Objects/game_object_ids.h +++ b/TombEngine/Objects/game_object_ids.h @@ -41,6 +41,7 @@ enum GAME_OBJECT_ID : short ID_LARA_CROWBAR_ANIM, ID_LARA_TORCH_ANIM, ID_HAIR, + ID_HAIR_2, ID_SNOWMOBILE_LARA_ANIMS = 50, ID_SNOWMOBILE, diff --git a/TombEngine/Renderer/RendererCompatibility.cpp b/TombEngine/Renderer/RendererCompatibility.cpp index 9a0b17e5e..a4cca9f9c 100644 --- a/TombEngine/Renderer/RendererCompatibility.cpp +++ b/TombEngine/Renderer/RendererCompatibility.cpp @@ -516,7 +516,7 @@ namespace TEN::Renderer &moveable, &g_Level.Meshes[obj->meshIndex + j], j, MoveablesIds[i] == ID_LARA_SKIN_JOINTS, - MoveablesIds[i] == ID_HAIR, &lastVertex, &lastIndex); + MoveablesIds[i] == ID_HAIR || MoveablesIds[i] == ID_HAIR_2, &lastVertex, &lastIndex); moveable.ObjectMeshes.push_back(mesh); _meshes.push_back(mesh); @@ -709,7 +709,6 @@ namespace TEN::Renderer // HACK: Hardcoded hair base parent vertices. int parentVertices0[] = { 37, 39, 40, 38 }; // Single braid. int parentVertices1[] = { 79, 78, 76, 77 }; // Left pigtail. - int parentVertices2[] = { 68, 69, 70, 71 }; // Right pigtail. auto& skinObj = GetRendererObject(GAME_OBJECT_ID::ID_LARA_SKIN); auto* parentMesh = skinObj.ObjectMeshes[LM_HEAD]; @@ -724,8 +723,6 @@ namespace TEN::Renderer for (int v2 = 0; v2 < parentBucket->NumVertices; v2++) { auto* parentVertex = &_moveablesVertices[parentBucket->StartVertex + v2]; - - // TODO if (isYoung) { if (parentVertex->OriginalIndex == parentVertices1[currentVertex->OriginalIndex]) @@ -735,14 +732,11 @@ namespace TEN::Renderer currentVertex->Normal = parentVertex->Normal; } } - else + else if (parentVertex->OriginalIndex == parentVertices0[currentVertex->OriginalIndex]) { - if (parentVertex->OriginalIndex == parentVertices0[currentVertex->OriginalIndex]) - { - currentVertex->Bone = 0; - currentVertex->Position = parentVertex->Position; - currentVertex->Normal = parentVertex->Normal; - } + currentVertex->Bone = 0; + currentVertex->Position = parentVertex->Position; + currentVertex->Normal = parentVertex->Normal; } } } @@ -754,6 +748,84 @@ namespace TEN::Renderer auto* parentMesh = moveable.ObjectMeshes[j - 1]; auto* parentBone = moveable.LinearizedBones[j - 1]; + for (int b2 = 0; b2 < parentMesh->Buckets.size(); b2++) + { + auto* parentBucket = &parentMesh->Buckets[b2]; + for (int v2 = 0; v2 < parentBucket->NumVertices; v2++) + { + auto* parentVertex = &_moveablesVertices[parentBucket->StartVertex + v2]; + + int x1 = _moveablesVertices[currentBucket.StartVertex + v1].Position.x + currentBone->GlobalTranslation.x; + int y1 = _moveablesVertices[currentBucket.StartVertex + v1].Position.y + currentBone->GlobalTranslation.y; + int z1 = _moveablesVertices[currentBucket.StartVertex + v1].Position.z + currentBone->GlobalTranslation.z; + + int x2 = _moveablesVertices[parentBucket->StartVertex + v2].Position.x + parentBone->GlobalTranslation.x; + int y2 = _moveablesVertices[parentBucket->StartVertex + v2].Position.y + parentBone->GlobalTranslation.y; + int z2 = _moveablesVertices[parentBucket->StartVertex + v2].Position.z + parentBone->GlobalTranslation.z; + + if (abs(x1 - x2) < 2 && abs(y1 - y2) < 2 && abs(z1 - z2) < 2) + { + currentVertex->Bone = j; + currentVertex->Position = parentVertex->Position; + currentVertex->Normal = parentVertex->Normal; + currentVertex->AnimationFrameOffset = parentVertex->AnimationFrameOffset; + currentVertex->Tangent = parentVertex->Tangent; + break; + } + } + } + } + } + } + } + } + else if (MoveablesIds[i] == ID_HAIR_2 && isSkinPresent) + { + for (int j = 0; j < obj->nmeshes; j++) + { + auto* currentMesh = moveable.ObjectMeshes[j]; + auto* currentBone = moveable.LinearizedBones[j]; + + for (const auto& currentBucket : currentMesh->Buckets) + { + for (int v1 = 0; v1 < currentBucket.NumVertices; v1++) + { + auto* currentVertex = &_moveablesVertices[currentBucket.StartVertex + v1]; + currentVertex->Bone = j + 1; + + // Link mesh 0 to head. + if (j == 0) + { + bool isYoung = (g_GameFlow->GetLevel(CurrentLevel)->GetLaraType() == LaraType::Young); + + // HACK: Hardcoded hair base parent vertices. + int parentVertices2[] = { 68, 69, 70, 71 }; // Right pigtail. + + auto& skinObj = GetRendererObject(GAME_OBJECT_ID::ID_LARA_SKIN); + auto* parentMesh = skinObj.ObjectMeshes[LM_HEAD]; + auto* parentBone = skinObj.LinearizedBones[LM_HEAD]; + + for (int b2 = 0; b2 < parentMesh->Buckets.size(); b2++) + { + auto* parentBucket = &parentMesh->Buckets[b2]; + for (int v2 = 0; v2 < parentBucket->NumVertices; v2++) + { + auto* parentVertex = &_moveablesVertices[parentBucket->StartVertex + v2]; + if (isYoung && parentVertex->OriginalIndex == parentVertices2[currentVertex->OriginalIndex]) + { + currentVertex->Bone = 0; + currentVertex->Position = parentVertex->Position; + currentVertex->Normal = parentVertex->Normal; + } + } + } + } + // Link meshes > 0 to parent meshes. + else + { + auto* parentMesh = moveable.ObjectMeshes[j - 1]; + auto* parentBone = moveable.LinearizedBones[j - 1]; + for (int b2 = 0; b2 < parentMesh->Buckets.size(); b2++) { auto* parentBucket = &parentMesh->Buckets[b2]; diff --git a/TombEngine/Renderer/RendererLara.cpp b/TombEngine/Renderer/RendererLara.cpp index 80bddf428..d02e3dcce 100644 --- a/TombEngine/Renderer/RendererLara.cpp +++ b/TombEngine/Renderer/RendererLara.cpp @@ -332,20 +332,17 @@ void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, Render return; const auto& hairObject = *_moveableObjects[ID_HAIR]; - - for (const auto& unit : HairEffect.Units) + const auto& unit = HairEffect.Units[0]; + if (unit.IsEnabled) { - if (!unit.IsEnabled) - continue; - // First matrix is Lara's head matrix, then all hair unit segment matrices. // Bones are adjusted at load time to account for this. _stItem.World = Matrix::Identity; _stItem.BonesMatrices[0] = itemToDraw->AnimationTransforms[LM_HEAD] * _laraWorldMatrix; - for (int i = 0; i < unit.Segments.size(); i++) + for (int i = 1; i < unit.Segments.size(); i++) { - _stItem.BonesMatrices[i + 1] = unit.Segments[i].WorldMatrix; + _stItem.BonesMatrices[i] = unit.Segments[i].WorldMatrix; _stItem.BoneLightModes[i] = (int)LightMode::Dynamic; } @@ -357,6 +354,33 @@ void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, Render DrawMoveableMesh(itemToDraw, &rMesh, room, i, view, rendererPass); } } + + if (!Objects[ID_HAIR_2].loaded) + return; + + const auto& hair2Object = *_moveableObjects[ID_HAIR_2]; + const auto& unit2 = HairEffect.Units[1]; + if (unit2.IsEnabled) + { + // First matrix is Lara's head matrix, then all hair unit segment matrices. + // Bones are adjusted at load time to account for this. + _stItem.World = Matrix::Identity; + _stItem.BonesMatrices[0] = itemToDraw->AnimationTransforms[LM_HEAD] * _laraWorldMatrix; + + for (int i = 1; i < unit2.Segments.size(); i++) + { + _stItem.BonesMatrices[i] = unit2.Segments[i].WorldMatrix; + _stItem.BoneLightModes[i] = (int)LightMode::Dynamic; + } + + _cbItem.UpdateData(_stItem, _context.Get()); + + for (int i = 0; i < hair2Object.ObjectMeshes.size(); i++) + { + auto& rMesh = *hair2Object.ObjectMeshes[i]; + DrawMoveableMesh(itemToDraw, &rMesh, room, i, view, rendererPass); + } + } } void Renderer::DrawLaraJoints(RendererItem* itemToDraw, RendererRoom* room, RenderView& view, RendererPass rendererPass) diff --git a/TombEngine/Scripting/Internal/TEN/Objects/ObjectIDs.h b/TombEngine/Scripting/Internal/TEN/Objects/ObjectIDs.h index 6a9209f5d..46c526051 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/ObjectIDs.h +++ b/TombEngine/Scripting/Internal/TEN/Objects/ObjectIDs.h @@ -1231,6 +1231,7 @@ static const std::unordered_map kObjIDs { { "LARA_CROWBAR_ANIM", ID_LARA_CROWBAR_ANIM }, { "LARA_TORCH_ANIM", ID_LARA_TORCH_ANIM }, { "HAIR", ID_HAIR }, + { "HAIR_2", ID_HAIR_2 }, { "SNOWMOBILE_LARA_ANIMS", ID_SNOWMOBILE_LARA_ANIMS }, { "SNOWMOBILE", ID_SNOWMOBILE }, { "QUAD_LARA_ANIMS", ID_QUAD_LARA_ANIMS }, From e4b3124a68c95d05f1d2c65e6cef277612f048a6 Mon Sep 17 00:00:00 2001 From: Stranger1992 <84292688+Stranger1992@users.noreply.github.com> Date: Fri, 16 Aug 2024 00:09:13 +0100 Subject: [PATCH 12/17] Rename hair objects to distinguish between the two ID_HAIR -> SINGLE_BRAID_HAIR ID_HAIR2 -> DUAL_PIGTAIL_HAIR --- Documentation/doc/4 enums/Objects.ObjID.html | 3 ++- TombEngine/Game/effects/hair.cpp | 16 ++++++++-------- TombEngine/Objects/game_object_ids.h | 4 ++-- TombEngine/Renderer/RendererCompatibility.cpp | 6 +++--- TombEngine/Renderer/RendererLara.cpp | 8 ++++---- .../Scripting/Internal/TEN/Objects/ObjectIDs.h | 7 ++++--- 6 files changed, 23 insertions(+), 21 deletions(-) diff --git a/Documentation/doc/4 enums/Objects.ObjID.html b/Documentation/doc/4 enums/Objects.ObjID.html index 9068ee709..4328065c5 100644 --- a/Documentation/doc/4 enums/Objects.ObjID.html +++ b/Documentation/doc/4 enums/Objects.ObjID.html @@ -171,7 +171,8 @@ LARA_PETROL_MESH LARA_DIRT_MESH LARA_CROWBAR_ANIM LARA_TORCH_ANIM -HAIR +SINGLE_BRAID_HAIR +DUAL_PIGTAIL_HAIR SNOWMOBILE_LARA_ANIMS SNOWMOBILE QUAD_LARA_ANIMS diff --git a/TombEngine/Game/effects/hair.cpp b/TombEngine/Game/effects/hair.cpp index 77f9d60dc..7751c4a03 100644 --- a/TombEngine/Game/effects/hair.cpp +++ b/TombEngine/Game/effects/hair.cpp @@ -321,25 +321,25 @@ namespace TEN::Effects::Hair // Initialize hair units. auto& unit0 = Units[0]; - unit0.IsEnabled = Objects[ID_HAIR].loaded; + unit0.IsEnabled = Objects[ID_SINGLE_BRAID_HAIR].loaded; unit0.IsInitialized = false; - unit0.Segments.resize(Objects[ID_HAIR].nmeshes + 1); + unit0.Segments.resize(Objects[ID_SINGLE_BRAID_HAIR].nmeshes + 1); // Initialize segments. for (auto& segment : unit0.Segments) { - segment.Position = GetJointOffset(ID_HAIR, 0); + segment.Position = GetJointOffset(ID_SINGLE_BRAID_HAIR, 0); segment.Velocity = Vector3::Zero; segment.Orientation = DEFAULT_ORIENT.ToQuaternion(); } auto& unit1 = Units[1]; - unit1.IsEnabled = Objects[ID_HAIR_2].loaded && isYoung; + unit1.IsEnabled = Objects[ID_DUAL_PIGTAIL_HAIR].loaded && isYoung; unit1.IsInitialized = false; - unit1.Segments.resize(Objects[ID_HAIR_2].nmeshes + 1); + unit1.Segments.resize(Objects[ID_DUAL_PIGTAIL_HAIR].nmeshes + 1); // Initialize segments. for (auto& segment : unit1.Segments) { - segment.Position = GetJointOffset(ID_HAIR_2, 0); + segment.Position = GetJointOffset(ID_DUAL_PIGTAIL_HAIR, 0); segment.Velocity = Vector3::Zero; segment.Orientation = DEFAULT_ORIENT.ToQuaternion(); } @@ -349,9 +349,9 @@ namespace TEN::Effects::Hair { auto& unit0 = Units[0]; if (unit0.IsEnabled) - unit0.Update(item, ID_HAIR, 0); + unit0.Update(item, ID_SINGLE_BRAID_HAIR, 0); auto& unit1 = Units[1]; if (unit1.IsEnabled) - unit1.Update(item, ID_HAIR_2, 1); + unit1.Update(item, ID_DUAL_PIGTAIL_HAIR, 1); } } diff --git a/TombEngine/Objects/game_object_ids.h b/TombEngine/Objects/game_object_ids.h index 19aa5bd8f..f1574ccfa 100644 --- a/TombEngine/Objects/game_object_ids.h +++ b/TombEngine/Objects/game_object_ids.h @@ -40,8 +40,8 @@ enum GAME_OBJECT_ID : short ID_LARA_DIRT_MESH, ID_LARA_CROWBAR_ANIM, ID_LARA_TORCH_ANIM, - ID_HAIR, - ID_HAIR_2, + ID_SINGLE_BRAID_HAIR, + ID_DUAL_PIGTAIL_HAIR, ID_SNOWMOBILE_LARA_ANIMS = 50, ID_SNOWMOBILE, diff --git a/TombEngine/Renderer/RendererCompatibility.cpp b/TombEngine/Renderer/RendererCompatibility.cpp index a4cca9f9c..292251d69 100644 --- a/TombEngine/Renderer/RendererCompatibility.cpp +++ b/TombEngine/Renderer/RendererCompatibility.cpp @@ -516,7 +516,7 @@ namespace TEN::Renderer &moveable, &g_Level.Meshes[obj->meshIndex + j], j, MoveablesIds[i] == ID_LARA_SKIN_JOINTS, - MoveablesIds[i] == ID_HAIR || MoveablesIds[i] == ID_HAIR_2, &lastVertex, &lastIndex); + MoveablesIds[i] == ID_SINGLE_BRAID_HAIR || MoveablesIds[i] == ID_DUAL_PIGTAIL_HAIR, &lastVertex, &lastIndex); moveable.ObjectMeshes.push_back(mesh); _meshes.push_back(mesh); @@ -687,7 +687,7 @@ namespace TEN::Renderer } } } - else if (MoveablesIds[i] == ID_HAIR && isSkinPresent) + else if (MoveablesIds[i] == ID_SINGLE_BRAID_HAIR && isSkinPresent) { for (int j = 0; j < obj->nmeshes; j++) { @@ -779,7 +779,7 @@ namespace TEN::Renderer } } } - else if (MoveablesIds[i] == ID_HAIR_2 && isSkinPresent) + else if (MoveablesIds[i] == ID_DUAL_PIGTAIL_HAIR && isSkinPresent) { for (int j = 0; j < obj->nmeshes; j++) { diff --git a/TombEngine/Renderer/RendererLara.cpp b/TombEngine/Renderer/RendererLara.cpp index d02e3dcce..fca823525 100644 --- a/TombEngine/Renderer/RendererLara.cpp +++ b/TombEngine/Renderer/RendererLara.cpp @@ -328,10 +328,10 @@ void TEN::Renderer::Renderer::DrawLara(RenderView& view, RendererPass rendererPa void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, RenderView& view, RendererPass rendererPass) { - if (!Objects[ID_HAIR].loaded) + if (!Objects[ID_SINGLE_BRAID_HAIR].loaded) return; - const auto& hairObject = *_moveableObjects[ID_HAIR]; + const auto& hairObject = *_moveableObjects[ID_SINGLE_BRAID_HAIR]; const auto& unit = HairEffect.Units[0]; if (unit.IsEnabled) { @@ -355,10 +355,10 @@ void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, Render } } - if (!Objects[ID_HAIR_2].loaded) + if (!Objects[ID_DUAL_PIGTAIL_HAIR].loaded) return; - const auto& hair2Object = *_moveableObjects[ID_HAIR_2]; + const auto& hair2Object = *_moveableObjects[ID_DUAL_PIGTAIL_HAIR]; const auto& unit2 = HairEffect.Units[1]; if (unit2.IsEnabled) { diff --git a/TombEngine/Scripting/Internal/TEN/Objects/ObjectIDs.h b/TombEngine/Scripting/Internal/TEN/Objects/ObjectIDs.h index 46c526051..a9fd40d03 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/ObjectIDs.h +++ b/TombEngine/Scripting/Internal/TEN/Objects/ObjectIDs.h @@ -53,7 +53,8 @@ The following constants are inside ObjID. LARA_DIRT_MESH LARA_CROWBAR_ANIM LARA_TORCH_ANIM - HAIR + SINGLE_BRAID_HAIR + DUAL_PIGTAIL_HAIR SNOWMOBILE_LARA_ANIMS SNOWMOBILE QUAD_LARA_ANIMS @@ -1230,8 +1231,8 @@ static const std::unordered_map kObjIDs { { "LARA_DIRT_MESH", ID_LARA_DIRT_MESH }, { "LARA_CROWBAR_ANIM", ID_LARA_CROWBAR_ANIM }, { "LARA_TORCH_ANIM", ID_LARA_TORCH_ANIM }, - { "HAIR", ID_HAIR }, - { "HAIR_2", ID_HAIR_2 }, + { "SINGLE_BRAID_HAIR", ID_SINGLE_BRAID_HAIR }, + { "DUAL_PIGTAIL_HAIR", ID_DUAL_PIGTAIL_HAIR }, { "SNOWMOBILE_LARA_ANIMS", ID_SNOWMOBILE_LARA_ANIMS }, { "SNOWMOBILE", ID_SNOWMOBILE }, { "QUAD_LARA_ANIMS", ID_QUAD_LARA_ANIMS }, From 08d74d660891cb85eca208e6b6081bf4b89e8762 Mon Sep 17 00:00:00 2001 From: Sezz Date: Fri, 16 Aug 2024 15:48:36 +1000 Subject: [PATCH 13/17] Fix formatting --- TombEngine/Game/effects/hair.cpp | 69 +++++++++++++--------------- TombEngine/Game/effects/hair.h | 9 ++-- TombEngine/Renderer/RendererLara.cpp | 59 ++++++++---------------- 3 files changed, 58 insertions(+), 79 deletions(-) diff --git a/TombEngine/Game/effects/hair.cpp b/TombEngine/Game/effects/hair.cpp index 7751c4a03..d1137b60b 100644 --- a/TombEngine/Game/effects/hair.cpp +++ b/TombEngine/Game/effects/hair.cpp @@ -23,7 +23,7 @@ namespace TEN::Effects::Hair { HairEffectController HairEffect = {}; - void HairUnit::Update(const ItemInfo& item, GAME_OBJECT_ID objectNumber, int hairUnitIndex) + void HairUnit::Update(const ItemInfo& item, int hairUnitID) { const auto& player = GetLaraInfo(item); @@ -34,15 +34,14 @@ namespace TEN::Effects::Hair g_Renderer.GetBoneMatrix(item.Index, LM_HEAD, &worldMatrix); // Apply base offset to world matrix. - auto relOffset = GetRelBaseOffset(hairUnitIndex, isYoung); + auto relOffset = GetRelBaseOffset(hairUnitID, isYoung); worldMatrix = Matrix::CreateTranslation(relOffset) * worldMatrix; - + // Use player's head bone orientation as base. auto baseOrient = Geometry::ConvertDirectionToQuat(-Geometry::ConvertQuatToDirection(GetBoneOrientation(item, LM_HEAD))); // Set position of base segment. Segments[0].Position = worldMatrix.Translation(); - Segments[0].WorldMatrix = worldMatrix; if (!IsInitialized) { @@ -53,7 +52,7 @@ namespace TEN::Effects::Hair auto& nextSegment = Segments[i + 1]; // NOTE: Joint offset determines segment length. - auto jointOffset = GetJointOffset(objectNumber, i); + auto jointOffset = GetJointOffset(ObjectID, i); worldMatrix = Matrix::CreateTranslation(segment.Position); worldMatrix = Matrix::CreateFromQuaternion(segment.Orientation) * worldMatrix; @@ -95,11 +94,10 @@ namespace TEN::Effects::Hair // Calculate world matrix. worldMatrix = Matrix::CreateTranslation(prevSegment.Position); worldMatrix = Matrix::CreateFromQuaternion(prevSegment.Orientation) * worldMatrix; - segment.WorldMatrix = worldMatrix; auto jointOffset = (i == (Segments.size() - 1)) ? - GetJointOffset(objectNumber, (i - 1) - 1) : - GetJointOffset(objectNumber, (i - 1)); + GetJointOffset(ObjectID, (i - 1) - 1) : + GetJointOffset(ObjectID, (i - 1)); worldMatrix = Matrix::CreateTranslation(jointOffset) * worldMatrix; segment.Position = worldMatrix.Translation(); @@ -108,12 +106,12 @@ namespace TEN::Effects::Hair } } - Vector3 HairUnit::GetRelBaseOffset(int hairUnitIndex, bool isYoung) + Vector3 HairUnit::GetRelBaseOffset(int hairUnitID, bool isYoung) { auto relOffset = Vector3::Zero; if (isYoung) { - switch (hairUnitIndex) + switch (hairUnitID) { // Left pigtail offset. case 0: @@ -320,38 +318,37 @@ namespace TEN::Effects::Hair bool isYoung = (g_GameFlow->GetLevel(CurrentLevel)->GetLaraType() == LaraType::Young); // Initialize hair units. - auto& unit0 = Units[0]; - unit0.IsEnabled = Objects[ID_SINGLE_BRAID_HAIR].loaded; - unit0.IsInitialized = false; - unit0.Segments.resize(Objects[ID_SINGLE_BRAID_HAIR].nmeshes + 1); - // Initialize segments. - for (auto& segment : unit0.Segments) + for (int i = 0; i < Units.size(); i++) { - segment.Position = GetJointOffset(ID_SINGLE_BRAID_HAIR, 0); - segment.Velocity = Vector3::Zero; - segment.Orientation = DEFAULT_ORIENT.ToQuaternion(); - } + auto& unit = Units[i]; - auto& unit1 = Units[1]; - unit1.IsEnabled = Objects[ID_DUAL_PIGTAIL_HAIR].loaded && isYoung; - unit1.IsInitialized = false; - unit1.Segments.resize(Objects[ID_DUAL_PIGTAIL_HAIR].nmeshes + 1); - // Initialize segments. - for (auto& segment : unit1.Segments) - { - segment.Position = GetJointOffset(ID_DUAL_PIGTAIL_HAIR, 0); - segment.Velocity = Vector3::Zero; - segment.Orientation = DEFAULT_ORIENT.ToQuaternion(); + auto objectID = (i == 0) ? ID_SINGLE_BRAID_HAIR : ID_DUAL_PIGTAIL_HAIR; + const auto& object = Objects[objectID]; + + unit.IsEnabled = (object.loaded && (i == 0 || (i == 1 && isYoung))); + unit.IsInitialized = false; + unit.ObjectID = objectID; + unit.Segments.resize(object.nmeshes + 1); + + // Initialize segments. + for (auto& segment : unit.Segments) + { + segment.Position = GetJointOffset(objectID, 0); + segment.Velocity = Vector3::Zero; + segment.Orientation = DEFAULT_ORIENT.ToQuaternion(); + } } } void HairEffectController::Update(ItemInfo& item) { - auto& unit0 = Units[0]; - if (unit0.IsEnabled) - unit0.Update(item, ID_SINGLE_BRAID_HAIR, 0); - auto& unit1 = Units[1]; - if (unit1.IsEnabled) - unit1.Update(item, ID_DUAL_PIGTAIL_HAIR, 1); + for (int i = 0; i < Units.size(); i++) + { + auto& unit = Units[i]; + if (!unit.IsEnabled) + continue; + + unit.Update(item, i); + } } } diff --git a/TombEngine/Game/effects/hair.h b/TombEngine/Game/effects/hair.h index 6ae1bc9e7..c0a9a8b4b 100644 --- a/TombEngine/Game/effects/hair.h +++ b/TombEngine/Game/effects/hair.h @@ -1,5 +1,7 @@ #pragma once +#include "Objects/game_object_ids.h" + struct ItemInfo; namespace TEN::Effects::Hair @@ -16,7 +18,6 @@ namespace TEN::Effects::Hair Vector3 Position = Vector3::Zero; Vector3 Velocity = Vector3::Zero; Quaternion Orientation = Quaternion::Identity; - Matrix WorldMatrix = Matrix::Identity; }; public: @@ -24,16 +25,18 @@ namespace TEN::Effects::Hair bool IsEnabled = false; bool IsInitialized = false; + + GAME_OBJECT_ID ObjectID = GAME_OBJECT_ID::ID_NO_OBJECT; std::vector Segments = {}; // Utilities - void Update(const ItemInfo& item, GAME_OBJECT_ID objectNumber, int hairUnitIndex); + void Update(const ItemInfo& item, int hairUnitID); private: // Helpers - Vector3 GetRelBaseOffset(int hairUnitIndex, bool isYoung); + Vector3 GetRelBaseOffset(int hairUnitID, bool isYoung); Vector3 GetWaterProbeOffset(const ItemInfo& item); Quaternion GetSegmentOrientation(const Vector3& origin, const Vector3& target, const Quaternion& baseOrient); std::vector GetSpheres(const ItemInfo& item, bool isYoung); diff --git a/TombEngine/Renderer/RendererLara.cpp b/TombEngine/Renderer/RendererLara.cpp index fca823525..5a09c030e 100644 --- a/TombEngine/Renderer/RendererLara.cpp +++ b/TombEngine/Renderer/RendererLara.cpp @@ -328,57 +328,36 @@ void TEN::Renderer::Renderer::DrawLara(RenderView& view, RendererPass rendererPa void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, RenderView& view, RendererPass rendererPass) { - if (!Objects[ID_SINGLE_BRAID_HAIR].loaded) - return; - - const auto& hairObject = *_moveableObjects[ID_SINGLE_BRAID_HAIR]; - const auto& unit = HairEffect.Units[0]; - if (unit.IsEnabled) + for (int i = 0; i < HairEffect.Units.size(); i++) { - // First matrix is Lara's head matrix, then all hair unit segment matrices. - // Bones are adjusted at load time to account for this. + const auto& unit = HairEffect.Units[i]; + if (!unit.IsEnabled) + continue; + + const auto& object = Objects[unit.ObjectID]; + if (!object.loaded) + continue; + + const auto& rendererObject = *_moveableObjects[unit.ObjectID]; + _stItem.World = Matrix::Identity; _stItem.BonesMatrices[0] = itemToDraw->AnimationTransforms[LM_HEAD] * _laraWorldMatrix; - for (int i = 1; i < unit.Segments.size(); i++) + for (int i = 0; i < unit.Segments.size(); i++) { - _stItem.BonesMatrices[i] = unit.Segments[i].WorldMatrix; + const auto& segment = unit.Segments[i]; + auto worldMatrix = Matrix::CreateFromQuaternion(segment.Orientation) * Matrix::CreateTranslation(segment.Position); + + _stItem.BonesMatrices[i + 1] = worldMatrix; _stItem.BoneLightModes[i] = (int)LightMode::Dynamic; } _cbItem.UpdateData(_stItem, _context.Get()); - for (int i = 0; i < hairObject.ObjectMeshes.size(); i++) + for (int i = 0; i < rendererObject.ObjectMeshes.size(); i++) { - auto& rMesh = *hairObject.ObjectMeshes[i]; - DrawMoveableMesh(itemToDraw, &rMesh, room, i, view, rendererPass); - } - } - - if (!Objects[ID_DUAL_PIGTAIL_HAIR].loaded) - return; - - const auto& hair2Object = *_moveableObjects[ID_DUAL_PIGTAIL_HAIR]; - const auto& unit2 = HairEffect.Units[1]; - if (unit2.IsEnabled) - { - // First matrix is Lara's head matrix, then all hair unit segment matrices. - // Bones are adjusted at load time to account for this. - _stItem.World = Matrix::Identity; - _stItem.BonesMatrices[0] = itemToDraw->AnimationTransforms[LM_HEAD] * _laraWorldMatrix; - - for (int i = 1; i < unit2.Segments.size(); i++) - { - _stItem.BonesMatrices[i] = unit2.Segments[i].WorldMatrix; - _stItem.BoneLightModes[i] = (int)LightMode::Dynamic; - } - - _cbItem.UpdateData(_stItem, _context.Get()); - - for (int i = 0; i < hair2Object.ObjectMeshes.size(); i++) - { - auto& rMesh = *hair2Object.ObjectMeshes[i]; - DrawMoveableMesh(itemToDraw, &rMesh, room, i, view, rendererPass); + auto& rendererMesh = *rendererObject.ObjectMeshes[i]; + DrawMoveableMesh(itemToDraw, &rendererMesh, room, i, view, rendererPass); } } } From 5c834a09068bdf9e8481860839ae19feb9b04276 Mon Sep 17 00:00:00 2001 From: Sezz Date: Sat, 17 Aug 2024 22:11:36 +1000 Subject: [PATCH 14/17] Use `BoundingSphere` natively (#1339) * Use BoundingSphere natively; remove CreatureSpheres and LaraSpheres globals * Remove parameter from GetSpheres() * Remove useless includes; rename file; add namespace * Tabs * Change pointer argument to reference * Fix weapon crash * Rename function and return bool * Pass reference arguments * Rename parameter * Fix errors * Use Intersects() method * Define local constant * Rename function; use generic variable names * Update RendererHelper.cpp * Fix merge errors * Fix and further simplify item spheres * Fix weapon firing * Add GetSpheres() ItemInfo method * Fix GenericSphereBoxCollision() --- TombEngine/Game/Lara/lara_climb.cpp | 1 - TombEngine/Game/Lara/lara_fire.cpp | 51 ++++---- TombEngine/Game/collision/collide_item.cpp | 116 ++++++++---------- TombEngine/Game/collision/collide_item.h | 2 +- TombEngine/Game/collision/sphere.cpp | 101 ++++++--------- TombEngine/Game/collision/sphere.h | 31 +---- TombEngine/Game/control/box.cpp | 1 - TombEngine/Game/control/control.cpp | 1 - TombEngine/Game/control/los.cpp | 47 ++++--- TombEngine/Game/effects/debris.cpp | 23 ++-- TombEngine/Game/effects/debris.h | 9 +- TombEngine/Game/effects/hair.cpp | 1 - TombEngine/Game/items.cpp | 7 ++ TombEngine/Game/items.h | 8 ++ TombEngine/Game/people.cpp | 1 - TombEngine/Objects/Effects/enemy_missile.cpp | 4 +- TombEngine/Objects/Effects/flame_emitters.cpp | 1 - TombEngine/Objects/Effects/tr4_locusts.cpp | 1 - .../Objects/Effects/tr5_electricity.cpp | 1 - .../Objects/Generic/Doors/double_doors.cpp | 1 - .../Objects/Generic/Doors/generic_doors.cpp | 5 +- .../Generic/Doors/pushpull_kick_door.cpp | 1 - .../Objects/Generic/Doors/sequence_door.cpp | 1 - .../Objects/Generic/Doors/steel_door.cpp | 6 +- .../Objects/Generic/Doors/underwater_door.cpp | 1 - TombEngine/Objects/Generic/Object/objects.cpp | 1 - .../Objects/Generic/Object/polerope.cpp | 5 +- TombEngine/Objects/Generic/Object/rope.cpp | 1 - .../Objects/Generic/Switches/switch.cpp | 1 - .../Objects/Generic/Traps/falling_block.cpp | 7 +- TombEngine/Objects/TR2/Entity/Dragon.cpp | 1 - TombEngine/Objects/TR2/Entity/tr2_skidman.cpp | 5 +- TombEngine/Objects/TR2/Vehicles/skidoo.cpp | 1 - TombEngine/Objects/TR2/Vehicles/speedboat.cpp | 1 - TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp | 1 - .../Objects/TR3/Entity/tr3_tribesman.cpp | 1 - TombEngine/Objects/TR3/Object/corpse.cpp | 1 - TombEngine/Objects/TR3/Trap/train.cpp | 7 +- TombEngine/Objects/TR3/Vehicles/minecart.cpp | 3 +- .../Objects/TR3/Vehicles/rubber_boat.cpp | 1 - TombEngine/Objects/TR3/Vehicles/upv.cpp | 5 +- TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp | 22 ++-- .../Objects/TR4/Entity/tr4_horseman.cpp | 3 +- TombEngine/Objects/TR4/Entity/tr4_mutant.cpp | 1 - .../Objects/TR4/Object/tr4_element_puzzle.cpp | 6 +- TombEngine/Objects/TR4/Object/tr4_mapper.cpp | 3 +- TombEngine/Objects/TR4/Trap/SpikyCeiling.cpp | 6 +- TombEngine/Objects/TR4/Trap/SpikyWall.cpp | 5 +- TombEngine/Objects/TR4/Trap/SquishyBlock.cpp | 7 +- TombEngine/Objects/TR4/Trap/tr4_chain.cpp | 6 +- TombEngine/Objects/TR4/Trap/tr4_hammer.cpp | 1 - TombEngine/Objects/TR4/Trap/tr4_mine.cpp | 28 ++--- .../Objects/TR4/Trap/tr4_moving_blade.cpp | 1 - TombEngine/Objects/TR4/Trap/tr4_stargate.cpp | 9 +- TombEngine/Objects/TR5/Entity/AutoGun.cpp | 3 +- TombEngine/Objects/TR5/Object/tr5_missile.cpp | 5 +- .../Objects/TR5/Object/tr5_rollingball.cpp | 8 +- .../Objects/TR5/Trap/tr5_wreckingball.cpp | 1 - TombEngine/Objects/Utils/VehicleHelpers.cpp | 5 +- TombEngine/Renderer/Renderer.h | 3 +- TombEngine/Renderer/RendererFrame.cpp | 8 +- TombEngine/Renderer/RendererHelper.cpp | 66 ++++------ TombEngine/Renderer/RendererLara.cpp | 2 +- TombEngine/TombEngine.vcxproj | 4 +- 64 files changed, 295 insertions(+), 372 deletions(-) diff --git a/TombEngine/Game/Lara/lara_climb.cpp b/TombEngine/Game/Lara/lara_climb.cpp index 68917f419..44aaa2360 100644 --- a/TombEngine/Game/Lara/lara_climb.cpp +++ b/TombEngine/Game/Lara/lara_climb.cpp @@ -4,7 +4,6 @@ #include "Game/animation.h" #include "Game/camera.h" #include "Game/collision/Point.h" -#include "Game/collision/sphere.h" #include "Game/control/control.h" #include "Game/items.h" #include "Game/Lara/lara.h" diff --git a/TombEngine/Game/Lara/lara_fire.cpp b/TombEngine/Game/Lara/lara_fire.cpp index 5bac95a04..08a97f190 100644 --- a/TombEngine/Game/Lara/lara_fire.cpp +++ b/TombEngine/Game/Lara/lara_fire.cpp @@ -4,7 +4,7 @@ #include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h" #include "Game/animation.h" #include "Game/camera.h" -#include "Game/collision/sphere.h" +#include "Game/collision/Sphere.h" #include "Game/control/los.h" #include "Game/control/lot.h" #include "Game/effects/effects.h" @@ -31,6 +31,7 @@ #include "Specific/level.h" #include "Specific/trutils.h" +using namespace TEN::Collision::Sphere; using namespace TEN::Entities::Generic; using namespace TEN::Input; using namespace TEN::Math; @@ -842,32 +843,38 @@ FireWeaponType FireWeapon(LaraWeaponType weaponType, ItemInfo& targetEntity, Ite auto target = origin + (directionNorm * weapon.TargetDist); auto ray = Ray(origin, directionNorm); - int num = GetSpheres(&targetEntity, CreatureSpheres, SPHERES_SPACE_WORLD, Matrix::Identity); - int bestJointIndex = NO_VALUE; - float bestDistance = INFINITY; - for (int i = 0; i < num; i++) - { - auto sphere = BoundingSphere(Vector3(CreatureSpheres[i].x, CreatureSpheres[i].y, CreatureSpheres[i].z), CreatureSpheres[i].r); - float distance = 0.0f; - if (ray.Intersects(sphere, distance)) - { - if (distance < bestDistance) - { - bestDistance = distance; - bestJointIndex = i; - } - } - } - player.Control.Weapon.HasFired = true; player.Control.Weapon.Fired = true; - + auto vOrigin = GameVector(pos); short roomNumber = laraItem.RoomNumber; GetFloor(pos.x, pos.y, pos.z, &roomNumber); vOrigin.RoomNumber = roomNumber; - if (bestJointIndex < 0) + if (&targetEntity == nullptr) + { + auto vTarget = GameVector(target); + GetTargetOnLOS(&vOrigin, &vTarget, false, true); + return FireWeaponType::Miss; + } + + auto spheres = targetEntity.GetSpheres(); + int closestJointIndex = NO_VALUE; + float closestDist = INFINITY; + for (int i = 0; i < spheres.size(); i++) + { + float dist = 0.0f; + if (ray.Intersects(spheres[i], dist)) + { + if (dist < closestDist) + { + closestDist = dist; + closestJointIndex = i; + } + } + } + + if (closestJointIndex < 0) { auto vTarget = GameVector(target); GetTargetOnLOS(&vOrigin, &vTarget, false, true); @@ -876,13 +883,13 @@ FireWeaponType FireWeapon(LaraWeaponType weaponType, ItemInfo& targetEntity, Ite else { SaveGame::Statistics.Game.AmmoHits++; - target = origin + (directionNorm * bestDistance); + target = origin + (directionNorm * closestDist); auto vTarget = GameVector(target); // NOTE: It seems that entities hit by the player in the normal way must have GetTargetOnLOS return false. // It's strange, but this replicates original behaviour until we fully understand what is happening. if (!GetTargetOnLOS(&vOrigin, &vTarget, false, true)) - HitTarget(&laraItem, &targetEntity, &vTarget, weapon.Damage, false, bestJointIndex); + HitTarget(&laraItem, &targetEntity, &vTarget, weapon.Damage, false, closestJointIndex); return FireWeaponType::PossibleHit; } diff --git a/TombEngine/Game/collision/collide_item.cpp b/TombEngine/Game/collision/collide_item.cpp index bcefa102c..502d36654 100644 --- a/TombEngine/Game/collision/collide_item.cpp +++ b/TombEngine/Game/collision/collide_item.cpp @@ -6,7 +6,7 @@ #include "Game/collision/collide_room.h" #include "Game/collision/floordata.h" #include "Game/collision/Point.h" -#include "Game/collision/sphere.h" +#include "Game/collision/Sphere.h" #include "Game/effects/debris.h" #include "Game/effects/effects.h" #include "Game/effects/simple_particle.h" @@ -23,81 +23,73 @@ using namespace TEN::Collision::Floordata; using namespace TEN::Collision::Point; +using namespace TEN::Collision::Sphere; using namespace TEN::Math; constexpr auto ANIMATED_ALIGNMENT_FRAME_COUNT_THRESHOLD = 6; // Globals + GameBoundingBox GlobalCollisionBounds; -void GenericSphereBoxCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll) +void GenericSphereBoxCollision(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll) { - auto* item = &g_Level.Items[itemNumber]; + auto& item = g_Level.Items[itemNumber]; + if (item.Status == ITEM_INVISIBLE) + return; - if (item->Status != ITEM_INVISIBLE) + if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius)) + return; + + HandleItemSphereCollision(item, *playerItem); + if (!item.TouchBits.TestAny()) + return; + + short prevYOrient = item.Pose.Orientation.y; + item.Pose.Orientation.y = 0; + auto spheres = item.GetSpheres(); + item.Pose.Orientation.y = prevYOrient; + + int harmBits = *(int*)&item.ItemFlags[0]; // NOTE: Value spread across ItemFlags[0] and ItemFlags[1]. + + auto collidedBits = item.TouchBits; + if (item.ItemFlags[2] != 0) + collidedBits.Clear(0); + + coll->Setup.EnableObjectPush = (item.ItemFlags[4] == 0); + + // Handle push and damage. + for (int i = 0; i < spheres.size(); i++) { - if (TestBoundsCollide(item, laraItem, coll->Setup.Radius)) + if (collidedBits.Test(i)) { - int collidedBits = TestCollision(item, laraItem); - if (collidedBits) + const auto& sphere = spheres[i]; + + GlobalCollisionBounds.X1 = sphere.Center.x - sphere.Radius - item.Pose.Position.x; + GlobalCollisionBounds.X2 = sphere.Center.x + sphere.Radius - item.Pose.Position.x; + GlobalCollisionBounds.Y1 = sphere.Center.y - sphere.Radius - item.Pose.Position.y; + GlobalCollisionBounds.Y2 = sphere.Center.y + sphere.Radius - item.Pose.Position.y; + GlobalCollisionBounds.Z1 = sphere.Center.z - sphere.Radius - item.Pose.Position.z; + GlobalCollisionBounds.Z2 = sphere.Center.z + sphere.Radius - item.Pose.Position.z; + + auto pos = playerItem->Pose.Position; + if (ItemPushItem(&item, playerItem, coll, harmBits & 1, 3) && (harmBits & 1)) { - short prevYOrient = item->Pose.Orientation.y; + DoDamage(playerItem, item.ItemFlags[3]); - item->Pose.Orientation.y = 0; - GetSpheres(item, CreatureSpheres, SPHERES_SPACE_WORLD, Matrix::Identity); - item->Pose.Orientation.y = prevYOrient; - - int deadlyBits = *((int*)&item->ItemFlags[0]); - auto* sphere = &CreatureSpheres[0]; - - if (item->ItemFlags[2] != 0) - collidedBits &= ~1; - coll->Setup.EnableObjectPush = item->ItemFlags[4] == 0; - - while (collidedBits) + auto deltaPos = pos - playerItem->Pose.Position; + if (deltaPos != Vector3i::Zero) { - if (collidedBits & 1) - { - GlobalCollisionBounds.X1 = sphere->x - sphere->r - item->Pose.Position.x; - GlobalCollisionBounds.X2 = sphere->x + sphere->r - item->Pose.Position.x; - GlobalCollisionBounds.Y1 = sphere->y - sphere->r - item->Pose.Position.y; - GlobalCollisionBounds.Y2 = sphere->y + sphere->r - item->Pose.Position.y; - GlobalCollisionBounds.Z1 = sphere->z - sphere->r - item->Pose.Position.z; - GlobalCollisionBounds.Z2 = sphere->z + sphere->r - item->Pose.Position.z; - - int x = laraItem->Pose.Position.x; - int y = laraItem->Pose.Position.y; - int z = laraItem->Pose.Position.z; - - if (ItemPushItem(item, laraItem, coll, deadlyBits & 1, 3) && (deadlyBits & 1)) - { - DoDamage(laraItem, item->ItemFlags[3]); - - int dx = x - laraItem->Pose.Position.x; - int dy = y - laraItem->Pose.Position.y; - int dz = z - laraItem->Pose.Position.z; - - if (dx || dy || dz) - { - if (TriggerActive(item)) - TriggerLaraBlood(); - } - - if (!coll->Setup.EnableObjectPush) - { - laraItem->Pose.Position.x += dx; - laraItem->Pose.Position.y += dy; - laraItem->Pose.Position.z += dz; - } - } - } - - collidedBits >>= 1; - deadlyBits >>= 1; - sphere++; + if (TriggerActive(&item)) + TriggerLaraBlood(); } + + if (!coll->Setup.EnableObjectPush) + playerItem->Pose.Position += deltaPos; } } + + harmBits >>= 1; } } @@ -1958,7 +1950,7 @@ void ObjectCollision(const short itemNumber, ItemInfo* laraItem, CollisionInfo* if (TestBoundsCollide(item, laraItem, coll->Setup.Radius)) { - if (TestCollision(item, laraItem)) + if (HandleItemSphereCollision(*item, *laraItem)) { if (coll->Setup.EnableObjectPush) ItemPushItem(item, laraItem, coll, false, 1); @@ -1973,7 +1965,7 @@ void CreatureCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll if (!TestBoundsCollide(item, laraItem, coll->Setup.Radius)) return; - if (!TestCollision(item, laraItem)) + if (!HandleItemSphereCollision(*item, *laraItem)) return; bool doPlayerCollision = laraItem->IsLara(); @@ -2008,7 +2000,7 @@ void TrapCollision(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll) if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius)) return; - TestCollision(&item, playerItem); + HandleItemSphereCollision(item, *playerItem); } else if (item.Status != ITEM_INVISIBLE) { diff --git a/TombEngine/Game/collision/collide_item.h b/TombEngine/Game/collision/collide_item.h index 6c39f9abb..5c0a4f908 100644 --- a/TombEngine/Game/collision/collide_item.h +++ b/TombEngine/Game/collision/collide_item.h @@ -36,7 +36,7 @@ struct CollidedObjectData bool IsEmpty() const { return (Items.empty() && Statics.empty()); }; }; -void GenericSphereBoxCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll); +void GenericSphereBoxCollision(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll); CollidedObjectData GetCollidedObjects(ItemInfo& collidingItem, bool onlyVisible, bool ignorePlayer, float customRadius = 0.0f, ObjectCollectionMode mode = ObjectCollectionMode::All); bool TestWithGlobalCollisionBounds(ItemInfo* item, ItemInfo* laraItem, CollisionInfo* coll); void TestForObjectOnLedge(ItemInfo* item, CollisionInfo* coll); diff --git a/TombEngine/Game/collision/sphere.cpp b/TombEngine/Game/collision/sphere.cpp index 22ca14f86..fd20d15f8 100644 --- a/TombEngine/Game/collision/sphere.cpp +++ b/TombEngine/Game/collision/sphere.cpp @@ -1,5 +1,5 @@ #include "framework.h" -#include "Game/collision/sphere.h" +#include "Game/collision/Sphere.h" #include "Game/Lara/lara.h" #include "Game/items.h" @@ -8,85 +8,54 @@ #include "Math/Math.h" #include "Renderer/Renderer.h" +using namespace TEN::Math; using namespace TEN::Renderer; -SPHERE LaraSpheres[MAX_SPHERES]; -SPHERE CreatureSpheres[MAX_SPHERES]; - -int GetSpheres(ItemInfo* item, SPHERE* ptr, int worldSpace, Matrix local) +namespace TEN::Collision::Sphere { - if (item == nullptr) - return 0; - - BoundingSphere spheres[MAX_SPHERES]; - int num = g_Renderer.GetSpheres(item->Index, spheres, worldSpace, local); - - for (int i = 0; i < MAX_SPHERES; i++) + bool HandleItemSphereCollision(ItemInfo& item0, ItemInfo& item1) { - ptr[i].x = spheres[i].Center.x; - ptr[i].y = spheres[i].Center.y; - ptr[i].z = spheres[i].Center.z; - ptr[i].r = spheres[i].Radius; - } + auto spheres0 = item0.GetSpheres(); + auto spheres1 = item1.GetSpheres(); - return num; -} + item1.TouchBits.ClearAll(); -int TestCollision(ItemInfo* item, ItemInfo* laraItem) -{ - int flags = 0; - - int creatureSphereCount = GetSpheres(item, CreatureSpheres, SPHERES_SPACE_WORLD, Matrix::Identity); - int laraSphereCount = GetSpheres(laraItem, LaraSpheres, SPHERES_SPACE_WORLD, Matrix::Identity); - - laraItem->TouchBits = NO_JOINT_BITS; - - if (creatureSphereCount <= 0) - { - item->TouchBits = NO_JOINT_BITS; - return 0; - } - else - { - for (int i = 0; i < creatureSphereCount; i++) + if (spheres0.empty()) { - auto* ptr1 = &CreatureSpheres[i]; - - int x1 = item->Pose.Position.x + ptr1->x; - int y1 = item->Pose.Position.y + ptr1->y; - int z1 = item->Pose.Position.z + ptr1->z; - int r1 = ptr1->r; + item0.TouchBits.ClearAll(); + return false; + } - if (r1 > 0) + // Run through item 0 spheres. + bool isCollided = false; + for (int i = 0; i < spheres0.size(); i++) + { + // Get sphere 0. + const auto& sphere0 = spheres0[i]; + if (sphere0.Radius <= 0.0f) + continue; + + // Run through item 1 spheres. + for (int j = 0; j < spheres1.size(); j++) { - for (int j = 0; j < laraSphereCount; j++) - { - auto* ptr2 = &LaraSpheres[j]; + // Get sphere 1. + const auto& sphere1 = spheres1[j]; + if (sphere1.Radius <= 0.0f) + continue; - int x2 = item->Pose.Position.x + ptr2->x; - int y2 = item->Pose.Position.y + ptr2->y; - int z2 = item->Pose.Position.z + ptr2->z; - int r2 = ptr2->r; + // Test sphere collision. + if (!sphere0.Intersects(sphere1)) + continue; - if (r2 > 0) - { - int dx = x1 - x2; - int dy = y1 - y2; - int dz = z1 - z2; - int r = r1 + r2; + // Set touch bits. + item0.TouchBits.Set(i); + item1.TouchBits.Set(j); - if ((SQUARE(dx) + SQUARE(dy) + SQUARE(dz)) < SQUARE(r)) - { - item->TouchBits.Set(i); - laraItem->TouchBits.Set(j); - flags |= 1 << i; - break; - } - } - } + isCollided = true; + break; } } - return flags; + return isCollided; } } diff --git a/TombEngine/Game/collision/sphere.h b/TombEngine/Game/collision/sphere.h index d02c36198..30883d9be 100644 --- a/TombEngine/Game/collision/sphere.h +++ b/TombEngine/Game/collision/sphere.h @@ -1,31 +1,8 @@ #pragma once -#include "Game/items.h" -#define SPHERES_SPACE_LOCAL 0 -#define SPHERES_SPACE_WORLD 1 -#define SPHERES_SPACE_BONE_ORIGIN 2 -#define MAX_SPHERES 34 +struct ItemInfo; -struct SPHERE +namespace TEN::Collision::Sphere { - int x = 0; - int y = 0; - int z = 0; - int r = 0; - - SPHERE() {}; - - SPHERE(const Vector3& pos, float radius) - { - this->x = (int)round(pos.x); - this->y = (int)round(pos.y); - this->z = (int)round(pos.z); - this->r = (int)round(radius); - } -}; - -extern SPHERE LaraSpheres[MAX_SPHERES]; -extern SPHERE CreatureSpheres[MAX_SPHERES]; - -int TestCollision(ItemInfo* item, ItemInfo* laraItem); -int GetSpheres(ItemInfo* item, SPHERE* ptr, int worldSpace, Matrix local); + bool HandleItemSphereCollision(ItemInfo& item0, ItemInfo& item1); +} diff --git a/TombEngine/Game/control/box.cpp b/TombEngine/Game/control/box.cpp index 20640dd0f..a2b12fdc8 100644 --- a/TombEngine/Game/control/box.cpp +++ b/TombEngine/Game/control/box.cpp @@ -3,7 +3,6 @@ #include "Game/animation.h" #include "Game/camera.h" -#include "Game/collision/sphere.h" #include "Game/collision/collide_room.h" #include "Game/collision/Point.h" #include "Game/control/control.h" diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp index 5509c4383..75e8648d2 100644 --- a/TombEngine/Game/control/control.cpp +++ b/TombEngine/Game/control/control.cpp @@ -6,7 +6,6 @@ #include "Game/camera.h" #include "Game/collision/collide_room.h" -#include "Game/collision/sphere.h" #include "Game/control/flipeffect.h" #include "Game/control/lot.h" #include "Game/control/volume.h" diff --git a/TombEngine/Game/control/los.cpp b/TombEngine/Game/control/los.cpp index d527584ce..61fc6a5e6 100644 --- a/TombEngine/Game/control/los.cpp +++ b/TombEngine/Game/control/los.cpp @@ -3,6 +3,7 @@ #include "Game/animation.h" #include "Game/collision/collide_room.h" +#include "Game/collision/Sphere.h" #include "Game/effects/tomb4fx.h" #include "Game/effects/debris.h" #include "Game/items.h" @@ -18,6 +19,7 @@ #include "Sound/sound.h" #include "Specific/Input/Input.h" +using namespace TEN::Collision::Sphere; using namespace TEN::Math; using TEN::Renderer::g_Renderer; @@ -308,7 +310,7 @@ bool GetTargetOnLOS(GameVector* origin, GameVector* target, bool drawTarget, boo { item->MeshBits &= ~ShatterItem.bit; ShatterImpactData.impactDirection = dir; - ShatterImpactData.impactLocation = Vector3(ShatterItem.sphere.x, ShatterItem.sphere.y, ShatterItem.sphere.z); + ShatterImpactData.impactLocation = ShatterItem.sphere.Center; ShatterObject(&ShatterItem, 0, 128, target2.RoomNumber, 0); TriggerRicochetSpark(target2, LaraItem->Pose.Orientation.y, 3, 0); } @@ -323,20 +325,19 @@ bool GetTargetOnLOS(GameVector* origin, GameVector* target, bool drawTarget, boo { const auto& weapon = Weapons[(int)Lara.Control.Weapon.GunType]; - int num = GetSpheres(item, CreatureSpheres, SPHERES_SPACE_WORLD, Matrix::Identity); + auto spheres = item->GetSpheres(); auto ray = Ray(origin->ToVector3(), dir); float bestDistance = INFINITY; int bestJointIndex = NO_VALUE; - for (int i = 0; i < num; i++) + for (int i = 0; i < spheres.size(); i++) { - auto sphere = BoundingSphere(Vector3(CreatureSpheres[i].x, CreatureSpheres[i].y, CreatureSpheres[i].z), CreatureSpheres[i].r); - float distance = 0.0f; - if (ray.Intersects(sphere, distance)) + float dist = 0.0f; + if (ray.Intersects(spheres[i], dist)) { - if (distance < bestDistance) + if (dist < bestDistance) { - bestDistance = distance; + bestDistance = dist; bestJointIndex = i; } } @@ -500,27 +501,23 @@ static bool DoRayBox(const GameVector& origin, const GameVector& target, const G auto* item = &g_Level.Items[closestItemNumber]; auto* object = &Objects[item->ObjectNumber]; - // Get transformed mesh sphere. - GetSpheres(item, CreatureSpheres, SPHERES_SPACE_WORLD, Matrix::Identity); - SPHERE spheres[34]; - memcpy(spheres, CreatureSpheres, sizeof(SPHERE) * 34); - if (object->nmeshes <= 0) return false; meshIndex = object->meshIndex; + auto spheres = item->GetSpheres(); for (int i = 0; i < object->nmeshes; i++) { // If mesh is visible. if (item->MeshBits & (1 << i)) { - auto* sphere = &CreatureSpheres[i]; + const auto& sphere = spheres[i]; + // NOTE: Not worth doing what's commented below. *Rewrite completely.* // TODO: this approach is the correct one but, again, Core's math is a mystery and this test was meant // to fail deliberately in some way. I've so added again Core's legacy test for allowing the current game logic // but after more testing we should trash it in the future and restore the new way. - #if 0 // Create the bounding sphere and test it against the ray BoundingSphere sph = BoundingSphere(Vector3(sphere->x, sphere->y, sphere->z), sphere->r); @@ -551,9 +548,9 @@ static bool DoRayBox(const GameVector& origin, const GameVector& target, const G p[2].x = target.x; p[2].y = target.y; p[2].z = target.z; - p[3].x = sphere->x; - p[3].y = sphere->y; - p[3].z = sphere->z; + p[3].x = sphere.Center.x; + p[3].y = sphere.Center.y; + p[3].z = sphere.Center.z; int r0 = (p[3].x - p[1].x) * (p[2].x - p[1].x) + (p[3].y - p[1].y) * (p[2].y - p[1].y) + @@ -583,11 +580,11 @@ static bool DoRayBox(const GameVector& origin, const GameVector& target, const G int distance = dx + dy + dz; - if (distance < SQUARE(sphere->r)) + if (distance < SQUARE(sphere.Radius)) { - dx = SQUARE(sphere->x - origin.x); - dy = SQUARE(sphere->y - origin.y); - dz = SQUARE(sphere->z - origin.z); + dx = SQUARE(sphere.Center.x - origin.x); + dy = SQUARE(sphere.Center.y - origin.y); + dz = SQUARE(sphere.Center.z - origin.z); distance = dx + dy + dz; @@ -622,14 +619,12 @@ static bool DoRayBox(const GameVector& origin, const GameVector& target, const G { auto* item = &g_Level.Items[closestItemNumber]; - GetSpheres(item, CreatureSpheres, SPHERES_SPACE_WORLD | SPHERES_SPACE_BONE_ORIGIN, Matrix::Identity); + auto spheres = item->GetSpheres(); ShatterItem.yRot = item->Pose.Orientation.y; ShatterItem.meshIndex = meshIndex; ShatterItem.color = item->Model.Color; - ShatterItem.sphere.x = CreatureSpheres[sp].x; - ShatterItem.sphere.y = CreatureSpheres[sp].y; - ShatterItem.sphere.z = CreatureSpheres[sp].z; + ShatterItem.sphere.Center = spheres[sp].Center; ShatterItem.bit = bit; ShatterItem.flags = 0; } diff --git a/TombEngine/Game/effects/debris.cpp b/TombEngine/Game/effects/debris.cpp index 9d98a0ada..eae73d0cb 100644 --- a/TombEngine/Game/effects/debris.cpp +++ b/TombEngine/Game/effects/debris.cpp @@ -2,14 +2,15 @@ #include "Game/effects/debris.h" #include "Game/collision/collide_room.h" +#include "Game/collision/Sphere.h" #include "Game/effects/tomb4fx.h" #include "Game/Setup.h" #include "Specific/level.h" -#include "Math/Random.h" #include "Math/Math.h" +using namespace TEN::Collision::Sphere; +using namespace TEN::Math; using namespace TEN::Renderer; -using namespace TEN::Math::Random; ShatterImpactInfo ShatterImpactData; SHATTER_ITEM ShatterItem; @@ -26,17 +27,15 @@ bool ExplodeItemNode(ItemInfo* item, int node, int noXZVel, int bits) if (number == BODY_DO_EXPLOSION) number = -64; - GetSpheres(item, CreatureSpheres, SPHERES_SPACE_WORLD | SPHERES_SPACE_BONE_ORIGIN, Matrix::Identity); + auto spheres = item->GetSpheres(); ShatterItem.yRot = item->Pose.Orientation.y; ShatterItem.bit = 1 << node; ShatterItem.meshIndex = Objects[item->ObjectNumber].meshIndex + node; - ShatterItem.sphere.x = CreatureSpheres[node].x; - ShatterItem.sphere.y = CreatureSpheres[node].y; - ShatterItem.sphere.z = CreatureSpheres[node].z; + ShatterItem.sphere.Center = spheres[node].Center; ShatterItem.color = item->Model.Color; ShatterItem.flags = item->ObjectNumber == ID_CROSSBOW_BOLT ? 0x400 : 0; ShatterImpactData.impactDirection = Vector3(0, -1, 0); - ShatterImpactData.impactLocation = { (float)ShatterItem.sphere.x, (float)ShatterItem.sphere.y, (float)ShatterItem.sphere.z }; + ShatterImpactData.impactLocation = ShatterItem.sphere.Center; ShatterObject(&ShatterItem, NULL, number, item->RoomNumber, noXZVel); item->MeshBits &= ~ShatterItem.bit; @@ -88,7 +87,7 @@ void ShatterObject(SHATTER_ITEM* item, MESH_INFO* mesh, int num, short roomNumbe isStatic = false; meshIndex = item->meshIndex; yRot = item->yRot; - pos = Vector3(item->sphere.x, item->sphere.y, item->sphere.z); + pos = item->sphere.Center; scale = 1.0f; } @@ -177,8 +176,8 @@ void ShatterObject(SHATTER_ITEM* item, MESH_INFO* mesh, int num, short roomNumbe fragment->restitution = 0.6f; fragment->friction = 0.6f; fragment->linearDrag = .99f; - fragment->angularVelocity = Vector3(GenerateFloat(-1, 1) * 0.39, GenerateFloat(-1, 1) * 0.39, GenerateFloat(-1, 1) * 0.39); - fragment->angularDrag = GenerateFloat(0.9f, 0.999f); + fragment->angularVelocity = Vector3(Random::GenerateFloat(-1, 1) * 0.39, Random::GenerateFloat(-1, 1) * 0.39, Random::GenerateFloat(-1, 1) * 0.39); + fragment->angularDrag = Random::GenerateFloat(0.9f, 0.999f); fragment->velocity = CalculateFragmentImpactVelocity(fragment->worldPosition, ShatterImpactData.impactDirection, ShatterImpactData.impactLocation); fragment->roomNumber = roomNumber; fragment->numBounces = 0; @@ -196,10 +195,10 @@ Vector3 CalculateFragmentImpactVelocity(const Vector3& fragmentWorldPosition, co radiusNormVec.Normalize(); float radiusStrenght = 1-((fragmentWorldPosition - impactLocation).Length() / 1024); radiusStrenght = fmax(radiusStrenght, 0); - Vector3 radiusRandomVector = Vector3(GenerateFloat(-0.2f, 0.2f), GenerateFloat(-0.2f, 0.2f), GenerateFloat(-0.2f, 0.2f)) + radiusNormVec; + Vector3 radiusRandomVector = Vector3(Random::GenerateFloat(-0.2f, 0.2f), Random::GenerateFloat(-0.2f, 0.2f), Random::GenerateFloat(-0.2f, 0.2f)) + radiusNormVec; radiusRandomVector.Normalize(); Vector3 radiusVelocity = radiusRandomVector * radiusStrenght*40; - Vector3 impactDirectionVelocity = (impactDirection + Vector3(GenerateFloat(-0.2f, 0.2f), GenerateFloat(-0.2f, 0.2f), GenerateFloat(-0.2f, 0.2f))) * 80 ; + Vector3 impactDirectionVelocity = (impactDirection + Vector3(Random::GenerateFloat(-0.2f, 0.2f), Random::GenerateFloat(-0.2f, 0.2f), Random::GenerateFloat(-0.2f, 0.2f))) * 80 ; return radiusVelocity + impactDirectionVelocity; } diff --git a/TombEngine/Game/effects/debris.h b/TombEngine/Game/effects/debris.h index 1c2df5372..bd9faf9cf 100644 --- a/TombEngine/Game/effects/debris.h +++ b/TombEngine/Game/effects/debris.h @@ -1,9 +1,8 @@ #pragma once -#include "Game/collision/sphere.h" -#include "Specific/newtypes.h" -#include "Specific/level.h" -#include "Renderer/Renderer.h" #include "Renderer/Graphics/Vertices/Vertex.h" +#include "Renderer/Renderer.h" +#include "Specific/level.h" +#include "Specific/newtypes.h" constexpr int MAX_DEBRIS = 2048; @@ -26,7 +25,7 @@ struct ITEM_LIGHT struct SHATTER_ITEM { - SPHERE sphere; + BoundingSphere sphere; ITEM_LIGHT* il; int meshIndex; Vector4 color; diff --git a/TombEngine/Game/effects/hair.cpp b/TombEngine/Game/effects/hair.cpp index d1137b60b..abe1bc940 100644 --- a/TombEngine/Game/effects/hair.cpp +++ b/TombEngine/Game/effects/hair.cpp @@ -4,7 +4,6 @@ #include "Game/animation.h" #include "Game/collision/collide_room.h" #include "Game/collision/Point.h" -#include "Game/collision/sphere.h" #include "Game/control/control.h" #include "Game/effects/weather.h" #include "Game/items.h" diff --git a/TombEngine/Game/items.cpp b/TombEngine/Game/items.cpp index 2c9ffd758..120d63343 100644 --- a/TombEngine/Game/items.cpp +++ b/TombEngine/Game/items.cpp @@ -17,6 +17,7 @@ #include "Objects/Generic/Object/BridgeObject.h" #include "Objects/Generic/Object/Pushable/PushableInfo.h" #include "Objects/Generic/Object/Pushable/PushableObject.h" +#include "Renderer/Renderer.h" #include "Scripting/Include/Objects/ScriptInterfaceObjectsHandler.h" #include "Scripting/Include/ScriptInterfaceGame.h" #include "Scripting/Internal/TEN/Objects/ObjectIDs.h" @@ -35,6 +36,7 @@ using namespace TEN::Entities::Generic; using namespace TEN::Input; using namespace TEN::Math; using namespace TEN::Utils; +using TEN::Renderer::g_Renderer; constexpr auto ITEM_DEATH_TIMEOUT = 4 * FPS; @@ -182,6 +184,11 @@ bool ItemInfo::IsBridge() const return Contains(BRIDGE_OBJECT_IDS, ObjectNumber); } +std::vector ItemInfo::GetSpheres() const +{ + return g_Renderer.GetSpheres(Index); +} + bool TestState(int refState, const std::vector& stateList) { for (const auto& state : stateList) diff --git a/TombEngine/Game/items.h b/TombEngine/Game/items.h index cda9aafee..d375bffad 100644 --- a/TombEngine/Game/items.h +++ b/TombEngine/Game/items.h @@ -150,11 +150,13 @@ struct ItemInfo short CarriedItem = 0; // OCB utilities + bool TestOcb(short ocbFlags) const; void RemoveOcb(short ocbFlags); void ClearAllOcb(); // ItemFlags utilities + bool TestFlags(int id, short flags) const; // ItemFlags[id] & flags bool TestFlagField(int id, short flags) const; // ItemFlags[id] == flags short GetFlagField(int id) const; // ItemFlags[id] @@ -162,6 +164,7 @@ struct ItemInfo void ClearFlags(int id, short flags); // ItemFlags[id] &= ~flags // Model utilities + bool TestMeshSwapFlags(unsigned int flags); bool TestMeshSwapFlags(const std::vector& flags); void SetMeshSwapFlags(unsigned int flags, bool clear = false); @@ -169,9 +172,14 @@ struct ItemInfo void ResetModelToDefault(); // Inquirers + bool IsLara() const; bool IsCreature() const; bool IsBridge() const; + + // Getters + + std::vector GetSpheres() const; }; bool TestState(int refState, const std::vector& stateList); diff --git a/TombEngine/Game/people.cpp b/TombEngine/Game/people.cpp index ff9c24d7e..5b9b1e943 100644 --- a/TombEngine/Game/people.cpp +++ b/TombEngine/Game/people.cpp @@ -3,7 +3,6 @@ #include "Game/animation.h" #include "Game/control/los.h" -#include "Game/collision/sphere.h" #include "Game/effects/effects.h" #include "Game/effects/debris.h" #include "Game/itemdata/creature_info.h" diff --git a/TombEngine/Objects/Effects/enemy_missile.cpp b/TombEngine/Objects/Effects/enemy_missile.cpp index 286b3b43b..2ab48ec11 100644 --- a/TombEngine/Objects/Effects/enemy_missile.cpp +++ b/TombEngine/Objects/Effects/enemy_missile.cpp @@ -121,9 +121,7 @@ namespace TEN::Entities::Effects ShatterItem.yRot = fx->pos.Orientation.y; ShatterItem.meshIndex = fx->frameNumber; ShatterItem.color = Vector4::One; - ShatterItem.sphere.x = fx->pos.Position.x; - ShatterItem.sphere.y = fx->pos.Position.y; - ShatterItem.sphere.z = fx->pos.Position.z; + ShatterItem.sphere.Center = fx->pos.Position.ToVector3(); ShatterItem.bit = 0; ShatterItem.flags = fx->flag2 & 0x400; ShatterObject(&ShatterItem, 0, param2, fx->roomNumber, param1); diff --git a/TombEngine/Objects/Effects/flame_emitters.cpp b/TombEngine/Objects/Effects/flame_emitters.cpp index d0040a6f7..725afb751 100644 --- a/TombEngine/Objects/Effects/flame_emitters.cpp +++ b/TombEngine/Objects/Effects/flame_emitters.cpp @@ -5,7 +5,6 @@ #include "Game/collision/collide_item.h" #include "Game/collision/collide_room.h" #include "Game/collision/Point.h" -#include "Game/collision/sphere.h" #include "Game/effects/effects.h" #include "Game/effects/Electricity.h" #include "Game/effects/item_fx.h" diff --git a/TombEngine/Objects/Effects/tr4_locusts.cpp b/TombEngine/Objects/Effects/tr4_locusts.cpp index e828ce78b..1ca7f581b 100644 --- a/TombEngine/Objects/Effects/tr4_locusts.cpp +++ b/TombEngine/Objects/Effects/tr4_locusts.cpp @@ -3,7 +3,6 @@ #include "Game/animation.h" #include "Game/collision/collide_item.h" -#include "Game/collision/sphere.h" #include "Game/effects/tomb4fx.h" #include "Game/items.h" #include "Game/Lara/lara.h" diff --git a/TombEngine/Objects/Effects/tr5_electricity.cpp b/TombEngine/Objects/Effects/tr5_electricity.cpp index 1e79cb09f..b93bd1a34 100644 --- a/TombEngine/Objects/Effects/tr5_electricity.cpp +++ b/TombEngine/Objects/Effects/tr5_electricity.cpp @@ -5,7 +5,6 @@ #include "Game/collision/collide_item.h" #include "Game/collision/collide_room.h" #include "Game/collision/Point.h" -#include "Game/collision/sphere.h" #include "Game/control/control.h" #include "Game/effects/effects.h" #include "Game/effects/item_fx.h" diff --git a/TombEngine/Objects/Generic/Doors/double_doors.cpp b/TombEngine/Objects/Generic/Doors/double_doors.cpp index 9e605f320..8a20011c6 100644 --- a/TombEngine/Objects/Generic/Doors/double_doors.cpp +++ b/TombEngine/Objects/Generic/Doors/double_doors.cpp @@ -10,7 +10,6 @@ #include "Game/pickup/pickup.h" #include "Sound/sound.h" #include "Game/animation.h" -#include "Game/collision/sphere.h" #include "Game/Lara/lara.h" #include "Game/Lara/lara_helpers.h" #include "Game/Lara/lara_struct.h" diff --git a/TombEngine/Objects/Generic/Doors/generic_doors.cpp b/TombEngine/Objects/Generic/Doors/generic_doors.cpp index cc1016f63..ebb460372 100644 --- a/TombEngine/Objects/Generic/Doors/generic_doors.cpp +++ b/TombEngine/Objects/Generic/Doors/generic_doors.cpp @@ -10,7 +10,7 @@ #include "Game/pickup/pickup.h" #include "Sound/sound.h" #include "Game/animation.h" -#include "Game/collision/sphere.h" +#include "Game/collision/Sphere.h" #include "Objects/Generic/Switches/cog_switch.h" #include "Objects/objectslist.h" #include "Game/Lara/lara.h" @@ -24,6 +24,7 @@ #include "Game/itemdata/itemdata.h" using namespace TEN::Collision::Room; +using namespace TEN::Collision::Sphere; using namespace TEN::Gui; using namespace TEN::Input; @@ -247,7 +248,7 @@ namespace TEN::Entities::Doors if (TestBoundsCollide(doorItem, laraItem, coll->Setup.Radius)) { - if (TestCollision(doorItem, laraItem)) + if (HandleItemSphereCollision(*doorItem, *laraItem)) { if (coll->Setup.EnableObjectPush) { diff --git a/TombEngine/Objects/Generic/Doors/pushpull_kick_door.cpp b/TombEngine/Objects/Generic/Doors/pushpull_kick_door.cpp index be3992325..5f13849ab 100644 --- a/TombEngine/Objects/Generic/Doors/pushpull_kick_door.cpp +++ b/TombEngine/Objects/Generic/Doors/pushpull_kick_door.cpp @@ -10,7 +10,6 @@ #include "Game/pickup/pickup.h" #include "Sound/sound.h" #include "Game/animation.h" -#include "Game/collision/sphere.h" #include "Game/Lara/lara_helpers.h" #include "Game/Lara/lara_struct.h" #include "Game/Lara/lara.h" diff --git a/TombEngine/Objects/Generic/Doors/sequence_door.cpp b/TombEngine/Objects/Generic/Doors/sequence_door.cpp index a83a24eb9..27133e958 100644 --- a/TombEngine/Objects/Generic/Doors/sequence_door.cpp +++ b/TombEngine/Objects/Generic/Doors/sequence_door.cpp @@ -10,7 +10,6 @@ #include "Game/pickup/pickup.h" #include "Sound/sound.h" #include "Game/animation.h" -#include "Game/collision/sphere.h" #include "Game/Lara/lara_struct.h" #include "Game/Lara/lara.h" #include "Math/Math.h" diff --git a/TombEngine/Objects/Generic/Doors/steel_door.cpp b/TombEngine/Objects/Generic/Doors/steel_door.cpp index 42077147b..e0024d854 100644 --- a/TombEngine/Objects/Generic/Doors/steel_door.cpp +++ b/TombEngine/Objects/Generic/Doors/steel_door.cpp @@ -10,7 +10,7 @@ #include "Game/pickup/pickup.h" #include "Sound/sound.h" #include "Game/animation.h" -#include "Game/collision/sphere.h" +#include "Game/collision/Sphere.h" #include "Game/Lara/lara_struct.h" #include "Game/Lara/lara.h" #include "Math/Math.h" @@ -19,6 +19,8 @@ #include "Game/collision/collide_room.h" #include "Game/collision/collide_item.h" +using namespace TEN::Collision::Sphere; + namespace TEN::Entities::Doors { void InitializeSteelDoor(short itemNumber) @@ -37,7 +39,7 @@ namespace TEN::Entities::Doors { if (TestBoundsCollide(doorItem, laraItem, coll->Setup.Radius)) { - if (TestCollision(doorItem, laraItem)) + if (HandleItemSphereCollision(*doorItem, *laraItem)) { if (coll->Setup.EnableObjectPush) ItemPushItem(doorItem, laraItem, coll, 0, 1); diff --git a/TombEngine/Objects/Generic/Doors/underwater_door.cpp b/TombEngine/Objects/Generic/Doors/underwater_door.cpp index e93b308bd..c6a7aac4f 100644 --- a/TombEngine/Objects/Generic/Doors/underwater_door.cpp +++ b/TombEngine/Objects/Generic/Doors/underwater_door.cpp @@ -3,7 +3,6 @@ #include "Game/animation.h" #include "Game/collision/collide_item.h" -#include "Game/collision/sphere.h" #include "Game/control/box.h" #include "Game/control/control.h" #include "Game/control/lot.h" diff --git a/TombEngine/Objects/Generic/Object/objects.cpp b/TombEngine/Objects/Generic/Object/objects.cpp index 5207da4f0..3a109f9b0 100644 --- a/TombEngine/Objects/Generic/Object/objects.cpp +++ b/TombEngine/Objects/Generic/Object/objects.cpp @@ -3,7 +3,6 @@ #include "Game/animation.h" #include "Game/collision/collide_item.h" -#include "Game/collision/sphere.h" #include "Game/control/control.h" #include "Game/effects/effects.h" #include "Game/items.h" diff --git a/TombEngine/Objects/Generic/Object/polerope.cpp b/TombEngine/Objects/Generic/Object/polerope.cpp index e8f5faf11..ff5826d1b 100644 --- a/TombEngine/Objects/Generic/Object/polerope.cpp +++ b/TombEngine/Objects/Generic/Object/polerope.cpp @@ -2,7 +2,7 @@ #include "Objects/Generic/Object/polerope.h" #include "Game/collision/collide_item.h" -#include "Game/collision/sphere.h" +#include "Game/collision/Sphere.h" #include "Game/control/box.h" #include "Game/control/control.h" #include "Game/control/lot.h" @@ -15,6 +15,7 @@ #include "Specific/Input/Input.h" #include "Specific/level.h" +using namespace TEN::Collision::Sphere; using namespace TEN::Input; using namespace TEN::Math; @@ -119,7 +120,7 @@ namespace TEN::Entities::Generic // Test bounds collision. if (TestBoundsCollide(&poleItem, laraItem, LARA_RADIUS + (int)round(abs(laraItem->Animation.Velocity.z)))) { - if (TestCollision(&poleItem, laraItem)) + if (HandleItemSphereCollision(poleItem, *laraItem)) { // Temporarily reorient pole. short yOrient = poleItem.Pose.Orientation.y; diff --git a/TombEngine/Objects/Generic/Object/rope.cpp b/TombEngine/Objects/Generic/Object/rope.cpp index ce4b64671..4f1c4fd8e 100644 --- a/TombEngine/Objects/Generic/Object/rope.cpp +++ b/TombEngine/Objects/Generic/Object/rope.cpp @@ -10,7 +10,6 @@ #include "Game/Lara/lara.h" #include "Math/Math.h" #include "Game/collision/collide_room.h" -#include "Game/collision/sphere.h" #include "Objects/Generic/Object/rope.h" #include "Sound/sound.h" #include "Game/camera.h" diff --git a/TombEngine/Objects/Generic/Switches/switch.cpp b/TombEngine/Objects/Generic/Switches/switch.cpp index 19b2dc1c1..4a2ca8962 100644 --- a/TombEngine/Objects/Generic/Switches/switch.cpp +++ b/TombEngine/Objects/Generic/Switches/switch.cpp @@ -3,7 +3,6 @@ #include "Game/animation.h" #include "Game/camera.h" -#include "Game/collision/sphere.h" #include "Game/control/lot.h" #include "Game/effects/debris.h" #include "Game/items.h" diff --git a/TombEngine/Objects/Generic/Traps/falling_block.cpp b/TombEngine/Objects/Generic/Traps/falling_block.cpp index ce6994747..61ed241e1 100644 --- a/TombEngine/Objects/Generic/Traps/falling_block.cpp +++ b/TombEngine/Objects/Generic/Traps/falling_block.cpp @@ -152,12 +152,11 @@ namespace TEN::Entities::Generic ShatterItem.yRot = item->Pose.Orientation.y; ShatterItem.meshIndex = Objects[item->ObjectNumber].meshIndex; ShatterItem.color = item->Model.Color; - ShatterItem.sphere.x = item->Pose.Position.x; - ShatterItem.sphere.y = item->Pose.Position.y - CLICK(1); // So debris won't spawn below floor - ShatterItem.sphere.z = item->Pose.Position.z; + ShatterItem.sphere.Center = item->Pose.Position.ToVector3(); + ShatterItem.sphere.Center.y -= CLICK(1); // Prevent debris from spawning below floor. ShatterItem.bit = 0; ShatterImpactData.impactDirection = Vector3(0, -(float)item->ItemFlags[1] / (float)FALLINGBLOCK_MAX_SPEED, 0); - ShatterImpactData.impactLocation = { (float)ShatterItem.sphere.x, (float)ShatterItem.sphere.y, (float)ShatterItem.sphere.z }; + ShatterImpactData.impactLocation = ShatterItem.sphere.Center; ShatterObject(&ShatterItem, nullptr, 0, item->RoomNumber, false); SoundEffect(SFX_TR4_ROCK_FALL_LAND, &item->Pose); diff --git a/TombEngine/Objects/TR2/Entity/Dragon.cpp b/TombEngine/Objects/TR2/Entity/Dragon.cpp index e4dc52f49..90e90a51c 100644 --- a/TombEngine/Objects/TR2/Entity/Dragon.cpp +++ b/TombEngine/Objects/TR2/Entity/Dragon.cpp @@ -4,7 +4,6 @@ #include "Game/camera.h" #include "Game/collision/collide_item.h" #include "Game/collision/Point.h" -#include "Game/collision/sphere.h" #include "Game/control/lot.h" #include "Game/effects/effects.h" #include "Game/effects/tomb4fx.h" diff --git a/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp b/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp index 17c95d586..bb34b1716 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp @@ -4,7 +4,7 @@ #include "Game/animation.h" #include "Game/items.h" #include "Game/collision/collide_item.h" -#include "Game/collision/sphere.h" +#include "Game/collision/Sphere.h" #include "Game/control/box.h" #include "Game/control/lot.h" #include "Game/effects/smoke.h" @@ -19,6 +19,7 @@ #include "Sound/sound.h" #include "Specific/level.h" +using namespace TEN::Collision::Sphere; using namespace TEN::Effects::Smoke; namespace TEN::Entities::Creatures::TR2 @@ -96,7 +97,7 @@ namespace TEN::Entities::Creatures::TR2 if (!TestBoundsCollide(&item, laraItem, coll->Setup.Radius)) return; - if (!TestCollision(&item, laraItem)) + if (!HandleItemSphereCollision(item, *laraItem)) return; if (coll->Setup.EnableObjectPush) diff --git a/TombEngine/Objects/TR2/Vehicles/skidoo.cpp b/TombEngine/Objects/TR2/Vehicles/skidoo.cpp index 0032ae11b..d13a21f71 100644 --- a/TombEngine/Objects/TR2/Vehicles/skidoo.cpp +++ b/TombEngine/Objects/TR2/Vehicles/skidoo.cpp @@ -5,7 +5,6 @@ #include "Game/camera.h" #include "Game/collision/collide_item.h" #include "Game/collision/Point.h" -#include "Game/collision/sphere.h" #include "Game/effects/effects.h" #include "Game/effects/simple_particle.h" #include "Game/effects/tomb4fx.h" diff --git a/TombEngine/Objects/TR2/Vehicles/speedboat.cpp b/TombEngine/Objects/TR2/Vehicles/speedboat.cpp index e9807e149..7b7310172 100644 --- a/TombEngine/Objects/TR2/Vehicles/speedboat.cpp +++ b/TombEngine/Objects/TR2/Vehicles/speedboat.cpp @@ -5,7 +5,6 @@ #include "Game/camera.h" #include "Game/collision/collide_item.h" #include "Game/collision/Point.h" -#include "Game/collision/sphere.h" #include "Game/effects/effects.h" #include "Game/effects/simple_particle.h" #include "Game/items.h" diff --git a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp index 31c011d34..00e6e74e5 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp @@ -6,7 +6,6 @@ #include "Game/collision/Point.h" #include "Game/control/box.h" #include "Game/control/lot.h" -#include "Game/collision/sphere.h" #include "Game/effects/effects.h" #include "Game/itemdata/creature_info.h" #include "Game/items.h" diff --git a/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp b/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp index f32925ff2..06bf326d6 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp @@ -2,7 +2,6 @@ #include "Objects/TR3/Entity/tr3_tribesman.h" #include "Game/animation.h" -#include "Game/collision/sphere.h" #include "Game/control/box.h" #include "Game/effects/effects.h" #include "Game/itemdata/creature_info.h" diff --git a/TombEngine/Objects/TR3/Object/corpse.cpp b/TombEngine/Objects/TR3/Object/corpse.cpp index d27b409ec..cba3931ea 100644 --- a/TombEngine/Objects/TR3/Object/corpse.cpp +++ b/TombEngine/Objects/TR3/Object/corpse.cpp @@ -9,7 +9,6 @@ #include "Game/collision/collide_room.h" #include "Game/collision/Point.h" #include "Game/collision/floordata.h" -#include "Game/collision/sphere.h" #include "Game/effects/effects.h" #include "Game/effects/Ripple.h" #include "Game/items.h" diff --git a/TombEngine/Objects/TR3/Trap/train.cpp b/TombEngine/Objects/TR3/Trap/train.cpp index aee8a2e81..94d29c5ce 100644 --- a/TombEngine/Objects/TR3/Trap/train.cpp +++ b/TombEngine/Objects/TR3/Trap/train.cpp @@ -8,7 +8,7 @@ #include "Game/collision/collide_item.h" #include "Game/collision/Point.h" #include "Game/collision/floordata.h" -#include "Game/collision/sphere.h" +#include "Game/collision/Sphere.h" #include "Game/effects/effects.h" #include "Game/items.h" #include "Game/Lara/lara.h" @@ -18,6 +18,7 @@ #include "Specific/level.h" using namespace TEN::Collision::Point; +using namespace TEN::Collision::Sphere; namespace TEN::Entities::Traps { @@ -108,8 +109,8 @@ namespace TEN::Entities::Traps if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius)) return; - if (!TestCollision(&item, playerItem)) - return; + if (!HandleItemSphereCollision(item, *playerItem)) + return; SoundEffect(SFX_TR4_LARA_GENERAL_DEATH, &playerItem->Pose, SoundEnvironment::Always); SoundEffect(SFX_TR4_LARA_HIGH_FALL_DEATH, &playerItem->Pose, SoundEnvironment::Always); diff --git a/TombEngine/Objects/TR3/Vehicles/minecart.cpp b/TombEngine/Objects/TR3/Vehicles/minecart.cpp index 118374c04..c0d4e8e88 100644 --- a/TombEngine/Objects/TR3/Vehicles/minecart.cpp +++ b/TombEngine/Objects/TR3/Vehicles/minecart.cpp @@ -3,9 +3,9 @@ #include "Game/animation.h" #include "Game/camera.h" -#include "Game/collision/sphere.h" #include "Game/collision/collide_item.h" #include "Game/collision/Point.h" +#include "Game/collision/Sphere.h" #include "Game/effects/effects.h" #include "Game/effects/spark.h" #include "Game/effects/tomb4fx.h" @@ -22,6 +22,7 @@ #include "Specific/level.h" using namespace TEN::Collision::Point; +using namespace TEN::Collision::Sphere; using namespace TEN::Effects::Spark; using namespace TEN::Input; using namespace TEN::Math; diff --git a/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp b/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp index 4d63e4247..1b52158e4 100644 --- a/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp +++ b/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp @@ -5,7 +5,6 @@ #include "Game/camera.h" #include "Game/collision/collide_item.h" #include "Game/collision/Point.h" -#include "Game/collision/sphere.h" #include "Game/effects/Bubble.h" #include "Game/effects/effects.h" #include "Game/items.h" diff --git a/TombEngine/Objects/TR3/Vehicles/upv.cpp b/TombEngine/Objects/TR3/Vehicles/upv.cpp index dceac3961..d80b3c98b 100644 --- a/TombEngine/Objects/TR3/Vehicles/upv.cpp +++ b/TombEngine/Objects/TR3/Vehicles/upv.cpp @@ -3,10 +3,10 @@ #include "Game/animation.h" #include "Game/camera.h" -#include "Game/collision/sphere.h" #include "Game/collision/collide_item.h" #include "Game/collision/collide_room.h" #include "Game/collision/Point.h" +#include "Game/collision/Sphere.h" #include "Game/control/box.h" #include "Game/control/los.h" #include "Game/effects/Bubble.h" @@ -28,6 +28,7 @@ #include "Specific/Input/Input.h" using namespace TEN::Collision::Point; +using namespace TEN::Collision::Sphere; using namespace TEN::Effects::Bubble; using namespace TEN::Effects::Streamer; using namespace TEN::Input; @@ -185,7 +186,7 @@ namespace TEN::Entities::Vehicles if (mountType == VehicleMountType::None) { // HACK: Collision in water behaves differently? @Sezz 2022.06.28 - if (TestBoundsCollide(UPVItem, laraItem, coll->Setup.Radius) && TestCollision(UPVItem, laraItem)) + if (TestBoundsCollide(UPVItem, laraItem, coll->Setup.Radius) && HandleItemSphereCollision(*UPVItem, *laraItem)) ItemPushItem(UPVItem, laraItem, coll, false, 0); } else diff --git a/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp b/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp index a2754fb84..71284ef93 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp @@ -1,7 +1,7 @@ #include "framework.h" #include "Objects/TR4/Entity/tr4_ahmet.h" -#include "Game/collision/sphere.h" +#include "Game/collision/Sphere.h" #include "Game/control/box.h" #include "Game/control/control.h" #include "Game/control/lot.h" @@ -17,6 +17,7 @@ #include "Sound/sound.h" #include "Specific/level.h" +using namespace TEN::Collision::Sphere; using namespace TEN::Effects::Environment; using namespace TEN::Math; @@ -80,26 +81,21 @@ namespace TEN::Entities::TR4 static void TriggerAhmetDeathEffect(ItemInfo* item) { - // HACK: Using CreatureSpheres here in release mode results in total mess-up - // of LaraSpheres, which in-game appears as a ghostly Lara fire silhouette. - // Later, both CreatureSpheres and LaraSpheres globals should be eradicated. - - static SPHERE spheres[MAX_SPHERES] = {}; - if (!(Wibble & 7)) { - int meshCount = GetSpheres(item, spheres, SPHERES_SPACE_WORLD, Matrix::Identity); - auto sphere = &spheres[(Wibble / 8) & 1]; - for (int i = meshCount; i > 0; i--, sphere += 2) - TriggerFireFlame(sphere->x, sphere->y, sphere->z, FlameType::Medium); + auto spheres = item->GetSpheres(); + const auto* spherePtr = &spheres[(Wibble / 8) & 1]; + + // TODO + for (int i = (int)spheres.size(); i > 0; i--, spherePtr += 2) + TriggerFireFlame(spherePtr->Center.x, spherePtr->Center.y, spherePtr->Center.z, FlameType::Medium); } TriggerDynamicLight( item->Pose.Position.x, item->Pose.Position.y - CLICK(1), item->Pose.Position.z, - 13, (GetRandomControl() & 0x3F) - 64, (GetRandomControl() & 0x1F) + 96, 0 - ); + 13, (GetRandomControl() & 0x3F) - 64, (GetRandomControl() & 0x1F) + 96, 0); SoundEffect(SFX_TR4_LOOP_FOR_SMALL_FIRES, &item->Pose); } diff --git a/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp b/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp index c486535a6..b0815a528 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp @@ -4,7 +4,6 @@ #include "Game/animation.h" #include "Game/collision/collide_room.h" #include "Game/collision/Point.h" -#include "Game/collision/sphere.h" #include "Game/control/box.h" #include "Game/control/control.h" #include "Game/effects/debris.h" @@ -354,7 +353,7 @@ namespace TEN::Entities::TR4 SoundEffect(SFX_TR4_HORSEMAN_TAKEHIT, &item->Pose); SoundEffect(SFX_TR4_HORSE_RICOCHET, &item->Pose); - auto pos = GetJointPosition(item, SPHERES_SPACE_WORLD, Vector3i(0, -128, 80)); + auto pos = GetJointPosition(item, 0, Vector3i(0, -128, 80)); HorsemanSparks(&pos, item->Pose.Orientation.y, 7); } else if (Random::TestProbability(1 / 8.0f)) diff --git a/TombEngine/Objects/TR4/Entity/tr4_mutant.cpp b/TombEngine/Objects/TR4/Entity/tr4_mutant.cpp index 41cc2809d..3db6fd88a 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_mutant.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_mutant.cpp @@ -2,7 +2,6 @@ #include "Objects/TR4/Entity/tr4_mutant.h" #include "Game/animation.h" -#include "Game/collision/sphere.h" #include "Game/control/control.h" #include "Game/effects/effects.h" #include "Game/itemdata/creature_info.h" diff --git a/TombEngine/Objects/TR4/Object/tr4_element_puzzle.cpp b/TombEngine/Objects/TR4/Object/tr4_element_puzzle.cpp index 5bb0117ff..4ef807d66 100644 --- a/TombEngine/Objects/TR4/Object/tr4_element_puzzle.cpp +++ b/TombEngine/Objects/TR4/Object/tr4_element_puzzle.cpp @@ -1,12 +1,13 @@ #include "framework.h" #include "tr4_element_puzzle.h" + #include "Specific/level.h" +#include "Game/Collision/Sphere.h" #include "Game/control/control.h" #include "Sound/sound.h" #include "Game/animation.h" #include "Game/Lara/lara.h" #include "Game/Lara/lara_helpers.h" -#include "Game/collision/sphere.h" #include "Game/effects/effects.h" #include "Game/effects/tomb4fx.h" #include "Specific/Input/Input.h" @@ -15,6 +16,7 @@ #include "Game/collision/collide_item.h" #include "Game/items.h" +using namespace TEN::Collision::Sphere; using namespace TEN::Input; using namespace TEN::Entities::Switches; @@ -149,7 +151,7 @@ namespace TEN::Entities::TR4 if (TestBoundsCollide(item, laraItem, coll->Setup.Radius)) { - if (TestCollision(item, laraItem)) + if (HandleItemSphereCollision(*item, *laraItem)) { if (coll->Setup.EnableObjectPush) ItemPushItem(item, laraItem, coll, false, 0); diff --git a/TombEngine/Objects/TR4/Object/tr4_mapper.cpp b/TombEngine/Objects/TR4/Object/tr4_mapper.cpp index faf2fe1f0..27d8f26fa 100644 --- a/TombEngine/Objects/TR4/Object/tr4_mapper.cpp +++ b/TombEngine/Objects/TR4/Object/tr4_mapper.cpp @@ -7,7 +7,6 @@ #include "Sound/sound.h" #include "Game/animation.h" #include "Game/Lara/lara.h" -#include "Game/collision/sphere.h" #include "Game/effects/effects.h" #include "Game/items.h" #include "Renderer/RendererEnums.h" @@ -34,7 +33,7 @@ namespace TEN::Entities::TR4 item->MeshBits |= 2; - auto pos = GetJointPosition(item, SPHERES_SPACE_WORLD); + auto pos = GetJointPosition(item, 0); byte color = (GetRandomControl() & 0x1F) + 192; TriggerDynamicLight(pos.x, pos.y, pos.z, (GetRandomControl() & 3) + 16, color, color, 0); diff --git a/TombEngine/Objects/TR4/Trap/SpikyCeiling.cpp b/TombEngine/Objects/TR4/Trap/SpikyCeiling.cpp index ac0bc9a2d..6db8d0843 100644 --- a/TombEngine/Objects/TR4/Trap/SpikyCeiling.cpp +++ b/TombEngine/Objects/TR4/Trap/SpikyCeiling.cpp @@ -5,7 +5,7 @@ #include "Game/collision/collide_item.h" #include "Game/collision/collide_room.h" #include "Game/collision/Point.h" -#include "Game/collision/sphere.h" +#include "Game/collision/Sphere.h" #include "Game/control/control.h" #include "Game/effects/effects.h" #include "Game/items.h" @@ -13,7 +13,7 @@ #include "Sound/sound.h" #include "Specific/level.h" -using namespace TEN::Collision::Point; +using namespace TEN::Collision::Sphere; namespace TEN::Entities::Traps { @@ -80,7 +80,7 @@ namespace TEN::Entities::Traps if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius)) return; - TestCollision(&item, playerItem); + HandleItemSphereCollision(item, *playerItem); } else if (item.Status != ITEM_INVISIBLE) { diff --git a/TombEngine/Objects/TR4/Trap/SpikyWall.cpp b/TombEngine/Objects/TR4/Trap/SpikyWall.cpp index 7f707153f..225b5efe1 100644 --- a/TombEngine/Objects/TR4/Trap/SpikyWall.cpp +++ b/TombEngine/Objects/TR4/Trap/SpikyWall.cpp @@ -4,7 +4,7 @@ #include "Game/collision/collide_item.h" #include "Game/collision/collide_room.h" #include "Game/collision/Point.h" -#include "Game/collision/sphere.h" +#include "Game/collision/Sphere.h" #include "Game/control/control.h" #include "Game/effects/debris.h" #include "Game/effects/effects.h" @@ -16,6 +16,7 @@ #include "Specific/level.h" using namespace TEN::Collision::Point; +using namespace TEN::Collision::Sphere; using namespace TEN::Math; // NOTES: @@ -131,7 +132,7 @@ namespace TEN::Entities::Traps if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius)) return; - TestCollision(&item, playerItem); + HandleItemSphereCollision(item, *playerItem); } else if (item.Status != ITEM_INVISIBLE) { diff --git a/TombEngine/Objects/TR4/Trap/SquishyBlock.cpp b/TombEngine/Objects/TR4/Trap/SquishyBlock.cpp index b46ff97a3..0a025cd1a 100644 --- a/TombEngine/Objects/TR4/Trap/SquishyBlock.cpp +++ b/TombEngine/Objects/TR4/Trap/SquishyBlock.cpp @@ -6,7 +6,7 @@ #include "Game/collision/collide_item.h" #include "Game/collision/collide_room.h" #include "Game/collision/Point.h" -#include "Game/collision/sphere.h" +#include "Game/collision/Sphere.h" #include "Game/control/control.h" #include "Game/effects/effects.h" #include "Game/items.h" @@ -17,6 +17,7 @@ #include "Specific/level.h" using namespace TEN::Collision::Point; +using namespace TEN::Collision::Sphere; // NOTES: // item.ItemFlags[0]: use dynamic motion. @@ -175,7 +176,7 @@ namespace TEN::Entities::Traps if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius)) return; - if (!TestCollision(&item, playerItem)) + if (!HandleItemSphereCollision(item, *playerItem)) return; if (!ItemPushItem(&item, playerItem, coll, false, 1)) @@ -201,7 +202,7 @@ namespace TEN::Entities::Traps if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius)) return; - if (!TestCollision(&item, playerItem)) + if (!HandleItemSphereCollision(item, *playerItem)) return; if ((item.Animation.FrameNumber - GetAnimData(item).frameBase) <= FALLING_BLOCK_IMPACT_FRAME) diff --git a/TombEngine/Objects/TR4/Trap/tr4_chain.cpp b/TombEngine/Objects/TR4/Trap/tr4_chain.cpp index d6f650447..e58a2c0a3 100644 --- a/TombEngine/Objects/TR4/Trap/tr4_chain.cpp +++ b/TombEngine/Objects/TR4/Trap/tr4_chain.cpp @@ -19,7 +19,7 @@ namespace TEN::Entities::Traps if (TriggerActive(&item)) { - *((int*)&item.ItemFlags[0]) = 0x787E; + *(int*)&item.ItemFlags[0] = 0x787E; AnimateItem(&item); return; } @@ -30,12 +30,12 @@ namespace TEN::Entities::Traps if (TriggerActive(&item)) { - *((int*)&item.ItemFlags[0]) = 0x780; + *(int*)&item.ItemFlags[0] = 0x780; AnimateItem(&item); return; } } - *((int*)&item.ItemFlags[0]) = 0; + *(int*)&item.ItemFlags[0] = 0; } } diff --git a/TombEngine/Objects/TR4/Trap/tr4_hammer.cpp b/TombEngine/Objects/TR4/Trap/tr4_hammer.cpp index 773134cf9..526dfab17 100644 --- a/TombEngine/Objects/TR4/Trap/tr4_hammer.cpp +++ b/TombEngine/Objects/TR4/Trap/tr4_hammer.cpp @@ -2,7 +2,6 @@ #include "Objects/TR4/Trap/tr4_hammer.h" #include "Game/animation.h" -#include "Game/collision/sphere.h" #include "Game/control/control.h" #include "Game/effects/debris.h" #include "Game/effects/effects.h" diff --git a/TombEngine/Objects/TR4/Trap/tr4_mine.cpp b/TombEngine/Objects/TR4/Trap/tr4_mine.cpp index 5601c2c8e..63266999b 100644 --- a/TombEngine/Objects/TR4/Trap/tr4_mine.cpp +++ b/TombEngine/Objects/TR4/Trap/tr4_mine.cpp @@ -2,7 +2,7 @@ #include "Objects/TR4/Trap/tr4_mine.h" #include "Game/collision/collide_item.h" -#include "Game/collision/sphere.h" +#include "Game/collision/Sphere.h" #include "Game/effects/debris.h" #include "Game/effects/effects.h" #include "Game/effects/tomb4fx.h" @@ -12,6 +12,7 @@ #include "Sound/sound.h" #include "Specific/level.h" +using namespace TEN::Collision::Sphere; using namespace TEN::Effects::Environment; namespace TEN::Entities::Traps @@ -28,30 +29,29 @@ namespace TEN::Entities::Traps { auto& item = g_Level.Items[itemNumber]; - int sphereCount = GetSpheres(&item, CreatureSpheres, SPHERES_SPACE_WORLD, Matrix::Identity); + auto spheres = item.GetSpheres(); if (item.ItemFlags[0] >= 150) { SoundEffect(SFX_TR4_EXPLOSION1, &item.Pose); SoundEffect(SFX_TR4_EXPLOSION2, &item.Pose); SoundEffect(SFX_TR4_EXPLOSION1, &item.Pose, SoundEnvironment::Land, 0.7f, 0.5f); - if (sphereCount > 0) + if (!spheres.empty()) { - for (int i = 0; i < sphereCount; i++) + for (int i = 0; i < spheres.size(); i++) { + // TODO: Hardcoding. if (i >= 7 && i != 9) { - auto& sphere = CreatureSpheres[i]; + const auto& sphere = spheres[i]; - auto pose = Pose(Vector3i(sphere.x, sphere.y, sphere.z)); - - TriggerExplosionSparks(sphere.x, sphere.y, sphere.z, 3, -2, 0, -item.RoomNumber); - TriggerExplosionSparks(sphere.x, sphere.y, sphere.z, 3, -1, 0, -item.RoomNumber); - TriggerShockwave(&pose, 48, 304, (GetRandomControl() & 0x1F) + 112, 0, 96, 128, 32, EulerAngles(ANGLE(11.25f), 0, 0), 0, true, false, false, (int)ShockwaveStyle::Normal); + TriggerExplosionSparks(sphere.Center.x, sphere.Center.y, sphere.Center.z, 3, -2, 0, -item.RoomNumber); + TriggerExplosionSparks(sphere.Center.x, sphere.Center.y, sphere.Center.z, 3, -1, 0, -item.RoomNumber); + TriggerShockwave(&Pose(Vector3i(sphere.Center)), 48, 304, (GetRandomControl() & 0x1F) + 112, 0, 96, 128, 32, EulerAngles(2048, 0.0f, 0.0f), 0, true, false, false, (int)ShockwaveStyle::Normal); } } - for (int i = 0; i < sphereCount; i++) + for (int i = 0; i < spheres.size(); i++) ExplodeItemNode(&item, i, 0, -128); } @@ -80,12 +80,12 @@ namespace TEN::Entities::Traps if (fade > 255) fade = 0; - for (int i = 0; i < sphereCount; i++) + for (int i = 0; i < spheres.size(); i++) { if (i == 0 || i > 5) { - auto& sphere = CreatureSpheres[i]; - AddFire(sphere.x, sphere.y, sphere.z, item.RoomNumber, 0.25f, fade); + const auto& sphere = spheres[i]; + AddFire(sphere.Center.x, sphere.Center.y, sphere.Center.z, item.RoomNumber, 0.25f, fade); } } diff --git a/TombEngine/Objects/TR4/Trap/tr4_moving_blade.cpp b/TombEngine/Objects/TR4/Trap/tr4_moving_blade.cpp index 48064341d..652f10943 100644 --- a/TombEngine/Objects/TR4/Trap/tr4_moving_blade.cpp +++ b/TombEngine/Objects/TR4/Trap/tr4_moving_blade.cpp @@ -3,7 +3,6 @@ #include "Game/animation.h" #include "Game/control/control.h" -#include "Game/collision/sphere.h" #include "Game/effects/effects.h" #include "Game/items.h" #include "Game/Lara/lara.h" diff --git a/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp b/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp index 4e2956f2e..606015596 100644 --- a/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp +++ b/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp @@ -4,7 +4,7 @@ #include "Game/animation.h" #include "Game/collision/collide_item.h" #include "Game/collision/collide_room.h" -#include "Game/collision/sphere.h" +#include "Game/collision/Sphere.h" #include "Game/control/control.h" #include "Game/effects/effects.h" #include "Game/items.h" @@ -12,6 +12,8 @@ #include "Sound/sound.h" #include "Specific/level.h" +using namespace TEN::Collision::Sphere; + namespace TEN::Entities::Traps { constexpr auto STARGATE_HARM_DAMAGE = 100; @@ -61,12 +63,13 @@ namespace TEN::Entities::Traps if (!TestBoundsCollide(item, laraItem, coll->Setup.Radius)) return; - if (TestCollision(item, laraItem) && + if (HandleItemSphereCollision(*item, *laraItem) && TriggerActive(item) && item->Animation.FrameNumber > GetAnimData(item).frameBase + 20 && // Hardcoded frame range. item->Animation.FrameNumber < GetAnimData(item).frameBase + 60) { // Blades deal damage cumulatively. + auto spheres = item->GetSpheres(); for (int i = 0; i < StargateHarmJoints.size(); i++) { if (item->TouchBits.Test(StargateHarmJoints[i])) @@ -74,7 +77,7 @@ namespace TEN::Entities::Traps DoDamage(laraItem, STARGATE_HARM_DAMAGE); DoBloodSplat( (GetRandomControl() & 0x3F) + laraItem->Pose.Position.x - 32, - (GetRandomControl() & 0x1F) + CreatureSpheres[i].y - 16, + (GetRandomControl() & 0x1F) + spheres[i].Center.y - 16, (GetRandomControl() & 0x3F) + laraItem->Pose.Position.z - 32, (GetRandomControl() & 3) + 2, GetRandomControl() * 2, diff --git a/TombEngine/Objects/TR5/Entity/AutoGun.cpp b/TombEngine/Objects/TR5/Entity/AutoGun.cpp index 6ed1cb87c..03c1b9d3b 100644 --- a/TombEngine/Objects/TR5/Entity/AutoGun.cpp +++ b/TombEngine/Objects/TR5/Entity/AutoGun.cpp @@ -2,7 +2,7 @@ #include "Objects/TR5/Entity/AutoGun.h" #include "Game/animation.h" -#include "Game/collision/sphere.h" +#include "Game/collision/Sphere.h" #include "Game/control/los.h" #include "Game/effects/effects.h" #include "Game/effects/tomb4fx.h" @@ -14,6 +14,7 @@ #include "Sound/sound.h" #include "Specific/level.h" +using namespace TEN::Collision::Sphere; using namespace TEN::Math; // NOTES: diff --git a/TombEngine/Objects/TR5/Object/tr5_missile.cpp b/TombEngine/Objects/TR5/Object/tr5_missile.cpp index 838dd04fd..8bcffe8d7 100644 --- a/TombEngine/Objects/TR5/Object/tr5_missile.cpp +++ b/TombEngine/Objects/TR5/Object/tr5_missile.cpp @@ -3,7 +3,6 @@ #include "Game/items.h" #include "Game/collision/collide_room.h" #include "Game/collision/Point.h" -#include "Game/collision/sphere.h" #include "Game/effects/tomb4fx.h" #include "Game/effects/effects.h" #include "Specific/level.h" @@ -210,9 +209,7 @@ void ExplodeFX(FX_INFO* fx, int noXZVel, int bits) ShatterItem.yRot = fx->pos.Orientation.y; ShatterItem.meshIndex = fx->frameNumber; ShatterItem.color = Vector4::One; - ShatterItem.sphere.x = fx->pos.Position.x; - ShatterItem.sphere.y = fx->pos.Position.y; - ShatterItem.sphere.z = fx->pos.Position.z; + ShatterItem.sphere.Center = fx->pos.Position.ToVector3(); ShatterItem.bit = 0; ShatterItem.flags = fx->flag2 & 0x1400; diff --git a/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp b/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp index f7e3b7211..82f200631 100644 --- a/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp +++ b/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp @@ -5,7 +5,7 @@ #include "Game/camera.h" #include "Game/collision/collide_item.h" #include "Game/collision/Point.h" -#include "Game/collision/sphere.h" +#include "Game/collision/Sphere.h" #include "Game/control/control.h" #include "Game/effects/effects.h" #include "Game/items.h" @@ -18,6 +18,8 @@ using namespace TEN::Collision::Point; +using namespace TEN::Collision::Sphere; + constexpr auto ROLLING_BALL_MAX_VELOCITY = BLOCK(3); void RollingBallCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll) @@ -25,7 +27,7 @@ void RollingBallCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* c auto* ballItem = &g_Level.Items[itemNumber]; if (!TestBoundsCollide(ballItem, laraItem, coll->Setup.Radius) || - !TestCollision(ballItem, laraItem)) + !HandleItemSphereCollision(*ballItem, *laraItem)) { return; } @@ -322,7 +324,7 @@ void ClassicRollingBallCollision(short itemNum, ItemInfo* lara, CollisionInfo* c if (!TestBoundsCollide(item, lara, coll->Setup.Radius)) return; - if (!TestCollision(item, lara)) + if (!HandleItemSphereCollision(*item, *lara)) return; if (lara->Animation.IsAirborne) diff --git a/TombEngine/Objects/TR5/Trap/tr5_wreckingball.cpp b/TombEngine/Objects/TR5/Trap/tr5_wreckingball.cpp index 6774daacc..55909c4ca 100644 --- a/TombEngine/Objects/TR5/Trap/tr5_wreckingball.cpp +++ b/TombEngine/Objects/TR5/Trap/tr5_wreckingball.cpp @@ -5,7 +5,6 @@ #include "Game/camera.h" #include "Game/collision/collide_item.h" #include "Game/collision/collide_room.h" -#include "Game/collision/sphere.h" #include "Game/effects/effects.h" #include "Game/effects/tomb4fx.h" #include "Game/effects/weather.h" diff --git a/TombEngine/Objects/Utils/VehicleHelpers.cpp b/TombEngine/Objects/Utils/VehicleHelpers.cpp index d2a121bb7..3f0244684 100644 --- a/TombEngine/Objects/Utils/VehicleHelpers.cpp +++ b/TombEngine/Objects/Utils/VehicleHelpers.cpp @@ -3,7 +3,7 @@ #include "Game/collision/collide_item.h" #include "Game/collision/Point.h" -#include "Game/collision/sphere.h" +#include "Game/collision/Sphere.h" #include "Game/effects/simple_particle.h" #include "Game/effects/Streamer.h" #include "Game/effects/tomb4fx.h" @@ -17,6 +17,7 @@ #include "Specific/Input/Input.h" using namespace TEN::Collision::Point; +using namespace TEN::Collision::Sphere; using namespace TEN::Effects::Streamer; using namespace TEN::Hud; using namespace TEN::Input; @@ -56,7 +57,7 @@ namespace TEN::Entities::Vehicles return VehicleMountType::None; // Assess object collision. - if (!TestBoundsCollide(vehicleItem, laraItem, coll->Setup.Radius) || !TestCollision(vehicleItem, laraItem)) + if (!TestBoundsCollide(vehicleItem, laraItem, coll->Setup.Radius) || !HandleItemSphereCollision(*vehicleItem, *laraItem)) return VehicleMountType::None; bool hasInputAction = IsHeld(In::Action); diff --git a/TombEngine/Renderer/Renderer.h b/TombEngine/Renderer/Renderer.h index db408b8a5..d93bc635a 100644 --- a/TombEngine/Renderer/Renderer.h +++ b/TombEngine/Renderer/Renderer.h @@ -68,6 +68,7 @@ #include "Graphics/Vertices/PostProcessVertex.h" enum GAME_OBJECT_ID : short; +enum class SphereSpaceType; class EulerAngles; struct AnimFrameInterpData; struct CAMERA_INFO; @@ -628,7 +629,7 @@ namespace TEN::Renderer void FlipRooms(short roomNumber1, short roomNumber2); void UpdateLaraAnimations(bool force); void UpdateItemAnimations(int itemNumber, bool force); - int GetSpheres(short itemNumber, BoundingSphere* ptr, char worldSpace, Matrix local); + std::vector GetSpheres(int itemNumber); void GetBoneMatrix(short itemNumber, int jointIndex, Matrix* outMatrix); void DrawObjectIn2DSpace(int objectNumber, Vector2 pos2D, EulerAngles orient, float scale1, float opacity = 1.0f, int meshBits = NO_JOINT_BITS); void SetLoadingScreen(std::wstring& fileName); diff --git a/TombEngine/Renderer/RendererFrame.cpp b/TombEngine/Renderer/RendererFrame.cpp index 525a4631f..c746d528f 100644 --- a/TombEngine/Renderer/RendererFrame.cpp +++ b/TombEngine/Renderer/RendererFrame.cpp @@ -4,7 +4,7 @@ #include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h" #include "Game/animation.h" #include "Game/camera.h" -#include "Game/collision/sphere.h" +#include "Game/collision/Sphere.h" #include "Game/effects/effects.h" #include "Game/items.h" #include "Game/Lara/lara.h" @@ -14,6 +14,7 @@ #include "Specific/level.h" #include "Renderer/RenderView.h" +using namespace TEN::Collision::Sphere; using namespace TEN::Math; namespace TEN::Renderer @@ -361,11 +362,10 @@ namespace TEN::Renderer if (obj.ShadowType == ShadowMode::None) { // Get all spheres and check if frustum intersects any of them. - static BoundingSphere spheres[MAX_BONES]; - int cnt = GetSpheres(itemNum, spheres, SPHERES_SPACE_WORLD, Matrix::Identity); + auto spheres = GetSpheres(itemNum); bool inFrustum = false; - for (int i = 0; !inFrustum, i < cnt; i++) + for (int i = 0; !inFrustum, i < spheres.size(); i++) // Blow up sphere radius by half for cases of too small calculated spheres. if (renderView.Camera.Frustum.SphereInFrustum(spheres[i].Center, spheres[i].Radius * 1.5f)) inFrustum = true; diff --git a/TombEngine/Renderer/RendererHelper.cpp b/TombEngine/Renderer/RendererHelper.cpp index 490a0b48d..85d17338b 100644 --- a/TombEngine/Renderer/RendererHelper.cpp +++ b/TombEngine/Renderer/RendererHelper.cpp @@ -9,7 +9,7 @@ #include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h" #include "Game/animation.h" #include "Game/camera.h" -#include "Game/collision/sphere.h" +#include "Game/collision/Sphere.h" #include "Game/control/control.h" #include "Game/itemdata/creature_info.h" #include "Game/items.h" @@ -34,6 +34,7 @@ #include "Specific/level.h" #include "Specific/trutils.h" +using namespace TEN::Collision::Sphere; using namespace TEN::Math; extern GameConfiguration g_Configuration; @@ -408,17 +409,16 @@ namespace TEN::Renderer return _meshes[meshIndex]; } - int Renderer::GetSpheres(short itemNumber, BoundingSphere* spheres, char worldSpace, Matrix local) + std::vector Renderer::GetSpheres(int itemNumber) { - auto* itemToDraw = &_items[itemNumber]; - auto* nativeItem = &g_Level.Items[itemNumber]; + auto& itemToDraw = _items[itemNumber]; + itemToDraw.ItemNumber = itemNumber; - itemToDraw->ItemNumber = itemNumber; + const auto* nativeItem = &g_Level.Items[itemNumber]; + if (nativeItem == nullptr) + return {}; - if (!nativeItem) - return 0; - - if (!itemToDraw->DoneAnimations) + if (!itemToDraw.DoneAnimations) { if (itemNumber == LaraItem->Index) { @@ -430,38 +430,26 @@ namespace TEN::Renderer } } - auto world = Matrix::Identity; - if (worldSpace & SPHERES_SPACE_WORLD) + auto translationMatrix = Matrix::CreateTranslation(nativeItem->Pose.Position.ToVector3()); + auto rotMatrix = nativeItem->Pose.Orientation.ToRotationMatrix(); + auto worldMatrix = rotMatrix * translationMatrix; + + const auto& moveable = GetRendererObject(nativeItem->ObjectNumber); + + // Collect spheres. + auto spheres = std::vector{}; + for (int i = 0; i < moveable.ObjectMeshes.size(); i++) { - world = Matrix::CreateTranslation(nativeItem->Pose.Position.x, nativeItem->Pose.Position.y, nativeItem->Pose.Position.z) * local; + const auto& mesh = *moveable.ObjectMeshes[i]; + + const auto& translationMatrix = itemToDraw.AnimationTransforms[i]; + auto pos = Vector3::Transform(mesh.Sphere.Center, translationMatrix * worldMatrix); + + auto sphere = BoundingSphere(pos, mesh.Sphere.Radius); + spheres.push_back(sphere); } - else - { - world = Matrix::Identity * local; - } - - world = nativeItem->Pose.Orientation.ToRotationMatrix() * world; - - auto& moveable = GetRendererObject(nativeItem->ObjectNumber); - - for (int i = 0; i< moveable.ObjectMeshes.size();i++) - { - auto mesh = moveable.ObjectMeshes[i]; - - auto pos = (Vector3)mesh->Sphere.Center; - if (worldSpace & SPHERES_SPACE_BONE_ORIGIN) - pos += moveable.LinearizedBones[i]->Translation; - - spheres[i].Center = Vector3::Transform(pos, (itemToDraw->AnimationTransforms[i] * world)); - spheres[i].Radius = mesh->Sphere.Radius; - - // Spheres debug - // auto v1 = Vector3(spheres[i].Center.x - spheres[i].Radius, spheres[i].Center.y, spheres[i].Center.z); - // auto v2 = Vector3(spheres[i].Center.x + spheres[i].Radius, spheres[i].Center.y, spheres[i].Center.z); - // AddDebugLine(v1, v2, Vector4::One); - } - - return (int)moveable.ObjectMeshes.size(); + + return spheres; } void Renderer::GetBoneMatrix(short itemNumber, int jointIndex, Matrix* outMatrix) diff --git a/TombEngine/Renderer/RendererLara.cpp b/TombEngine/Renderer/RendererLara.cpp index 5a09c030e..e72079083 100644 --- a/TombEngine/Renderer/RendererLara.cpp +++ b/TombEngine/Renderer/RendererLara.cpp @@ -9,7 +9,7 @@ #include "Game/control/control.h" #include "Game/spotcam.h" #include "Game/camera.h" -#include "Game/collision/sphere.h" +#include "Game/collision/Sphere.h" #include "Game/Setup.h" #include "Math/Math.h" #include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h" diff --git a/TombEngine/TombEngine.vcxproj b/TombEngine/TombEngine.vcxproj index aa6f981f4..cbe3d8e1b 100644 --- a/TombEngine/TombEngine.vcxproj +++ b/TombEngine/TombEngine.vcxproj @@ -340,6 +340,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)" + @@ -377,7 +378,6 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)" - @@ -862,7 +862,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)" - + From f85769f3ca22bb89c562603db86aefd70b22a7b7 Mon Sep 17 00:00:00 2001 From: TokyoSU <77746747+TokyoSU@users.noreply.github.com> Date: Sat, 17 Aug 2024 19:10:04 +0200 Subject: [PATCH 15/17] Update RendererCompatibility.cpp --- TombEngine/Renderer/RendererCompatibility.cpp | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/TombEngine/Renderer/RendererCompatibility.cpp b/TombEngine/Renderer/RendererCompatibility.cpp index 292251d69..79e93a3f6 100644 --- a/TombEngine/Renderer/RendererCompatibility.cpp +++ b/TombEngine/Renderer/RendererCompatibility.cpp @@ -723,14 +723,11 @@ namespace TEN::Renderer for (int v2 = 0; v2 < parentBucket->NumVertices; v2++) { auto* parentVertex = &_moveablesVertices[parentBucket->StartVertex + v2]; - if (isYoung) + if (isYoung && parentVertex->OriginalIndex == parentVertices1[currentVertex->OriginalIndex]) { - if (parentVertex->OriginalIndex == parentVertices1[currentVertex->OriginalIndex]) - { - currentVertex->Bone = 0; - currentVertex->Position = parentVertex->Position; - currentVertex->Normal = parentVertex->Normal; - } + currentVertex->Bone = 0; + currentVertex->Position = parentVertex->Position; + currentVertex->Normal = parentVertex->Normal; } else if (parentVertex->OriginalIndex == parentVertices0[currentVertex->OriginalIndex]) { @@ -805,17 +802,20 @@ namespace TEN::Renderer auto* parentMesh = skinObj.ObjectMeshes[LM_HEAD]; auto* parentBone = skinObj.LinearizedBones[LM_HEAD]; - for (int b2 = 0; b2 < parentMesh->Buckets.size(); b2++) + if (currentVertex->OriginalIndex < 4) { - auto* parentBucket = &parentMesh->Buckets[b2]; - for (int v2 = 0; v2 < parentBucket->NumVertices; v2++) + for (int b2 = 0; b2 < parentMesh->Buckets.size(); b2++) { - auto* parentVertex = &_moveablesVertices[parentBucket->StartVertex + v2]; - if (isYoung && parentVertex->OriginalIndex == parentVertices2[currentVertex->OriginalIndex]) + auto* parentBucket = &parentMesh->Buckets[b2]; + for (int v2 = 0; v2 < parentBucket->NumVertices; v2++) { - currentVertex->Bone = 0; - currentVertex->Position = parentVertex->Position; - currentVertex->Normal = parentVertex->Normal; + auto* parentVertex = &_moveablesVertices[parentBucket->StartVertex + v2]; + if (isYoung && parentVertex->OriginalIndex == parentVertices2[currentVertex->OriginalIndex]) + { + currentVertex->Bone = 0; + currentVertex->Position = parentVertex->Position; + currentVertex->Normal = parentVertex->Normal; + } } } } From 806c052ff560353a979af84f865f2e2ac3e922bc Mon Sep 17 00:00:00 2001 From: Sezz Date: Sun, 18 Aug 2024 22:58:50 +1000 Subject: [PATCH 16/17] Fix GetBoneOrientation() --- TombEngine/Game/animation.cpp | 13 ++----- TombEngine/Game/effects/hair.cpp | 2 +- TombEngine/Renderer/Renderer.h | 6 ++- TombEngine/Renderer/RendererHelper.cpp | 38 +++++++++++++------ TombEngine/Renderer/Structures/RendererItem.h | 8 ++-- 5 files changed, 38 insertions(+), 29 deletions(-) diff --git a/TombEngine/Game/animation.cpp b/TombEngine/Game/animation.cpp index 0db8e490f..f4fb1869a 100644 --- a/TombEngine/Game/animation.cpp +++ b/TombEngine/Game/animation.cpp @@ -711,7 +711,7 @@ void ClampRotation(Pose& outPose, short angle, short rotation) Vector3i GetJointPosition(const ItemInfo& item, int jointIndex, const Vector3i& relOffset) { // Use matrices done in renderer to transform relative offset. - return Vector3i(g_Renderer.GetAbsEntityBonePosition(item.Index, jointIndex, relOffset.ToVector3())); + return Vector3i(g_Renderer.GetMoveableBonePosition(item.Index, jointIndex, relOffset.ToVector3())); } Vector3i GetJointPosition(ItemInfo* item, int jointIndex, const Vector3i& relOffset) @@ -737,16 +737,9 @@ Vector3 GetJointOffset(GAME_OBJECT_ID objectID, int jointIndex) return Vector3(*(bonePtr + 1), *(bonePtr + 2), *(bonePtr + 3)); } -Quaternion GetBoneOrientation(const ItemInfo& item, int boneIndex) +Quaternion GetBoneOrientation(const ItemInfo& item, int boneID) { - static const auto REF_DIRECTION = Vector3::UnitZ; - - auto origin = g_Renderer.GetAbsEntityBonePosition(item.Index, boneIndex); - auto target = g_Renderer.GetAbsEntityBonePosition(item.Index, boneIndex, REF_DIRECTION); - - auto direction = target - origin; - direction.Normalize(); - return Geometry::ConvertDirectionToQuat(direction); + return g_Renderer.GetMoveableBoneOrientation(item.Index, boneID); } // NOTE: Will not work for bones at ends of hierarchies. diff --git a/TombEngine/Game/effects/hair.cpp b/TombEngine/Game/effects/hair.cpp index abe1bc940..33cf2dd46 100644 --- a/TombEngine/Game/effects/hair.cpp +++ b/TombEngine/Game/effects/hair.cpp @@ -37,7 +37,7 @@ namespace TEN::Effects::Hair worldMatrix = Matrix::CreateTranslation(relOffset) * worldMatrix; // Use player's head bone orientation as base. - auto baseOrient = Geometry::ConvertDirectionToQuat(-Geometry::ConvertQuatToDirection(GetBoneOrientation(item, LM_HEAD))); + auto baseOrient = Geometry::ConvertDirectionToQuat(-Geometry::ConvertQuatToDirection(GetBoneOrientation(item, LM_HEAD))) * item.Pose.Orientation.ToQuaternion(); // Set position of base segment. Segments[0].Position = worldMatrix.Translation(); diff --git a/TombEngine/Renderer/Renderer.h b/TombEngine/Renderer/Renderer.h index d93bc635a..c4ecdcdb4 100644 --- a/TombEngine/Renderer/Renderer.h +++ b/TombEngine/Renderer/Renderer.h @@ -638,9 +638,11 @@ namespace TEN::Renderer Vector2i GetScreenResolution() const; std::optional Get2DPosition(const Vector3& pos) const; - Vector3 GetAbsEntityBonePosition(int itemNumber, int jointIndex, const Vector3& relOffset = Vector3::Zero); std::pair GetRay(const Vector2& pos) const; - + + Vector3 GetMoveableBonePosition(int itemNumber, int boneID, const Vector3& relOffset = Vector3::Zero); + Quaternion GetMoveableBoneOrientation(int itemNumber, int boneID); + void AddDisplaySprite(const RendererSprite& sprite, const Vector2& pos2D, short orient, const Vector2& size, const Vector4& color, int priority, BlendMode blendMode, const Vector2& aspectCorrection, RenderView& renderView); void CollectDisplaySprites(RenderView& renderView); diff --git a/TombEngine/Renderer/RendererHelper.cpp b/TombEngine/Renderer/RendererHelper.cpp index 85d17338b..c34040661 100644 --- a/TombEngine/Renderer/RendererHelper.cpp +++ b/TombEngine/Renderer/RendererHelper.cpp @@ -95,6 +95,10 @@ namespace TEN::Renderer rotMatrix = Matrix::CreateFromQuaternion(quat3); } + // Store bone orientation on current frame. + if (rItem != nullptr) + rItem->BoneOrientations[bonePtr->Index] = Quaternion::CreateFromRotationMatrix(rotMatrix); + auto tMatrix = (bonePtr == rObject.Skeleton) ? Matrix::CreateTranslation(offset0) : Matrix::Identity; auto extraRotMatrix = Matrix::CreateFromQuaternion(bonePtr->ExtraRotation); @@ -549,30 +553,40 @@ namespace TEN::Renderer return std::pair(nearPoint, farPoint); } - Vector3 Renderer::GetAbsEntityBonePosition(int itemNumber, int jointIndex, const Vector3& relOffset) + Vector3 Renderer::GetMoveableBonePosition(int itemNumber, int boneID, const Vector3& relOffset) { auto* rendererItem = &_items[itemNumber]; - rendererItem->ItemNumber = itemNumber; - if (!rendererItem) + if (rendererItem == nullptr) return Vector3::Zero; if (!rendererItem->DoneAnimations) - { - if (itemNumber == LaraItem->Index) - UpdateLaraAnimations(false); - else - UpdateItemAnimations(itemNumber, false); - } + (itemNumber == LaraItem->Index) ? UpdateLaraAnimations(false) : UpdateItemAnimations(itemNumber, false); - if (jointIndex >= MAX_BONES) - jointIndex = 0; + if (boneID >= MAX_BONES) + boneID = 0; - auto world = rendererItem->AnimationTransforms[jointIndex] * rendererItem->World; + auto world = rendererItem->AnimationTransforms[boneID] * rendererItem->World; return Vector3::Transform(relOffset, world); } + Quaternion Renderer::GetMoveableBoneOrientation(int itemNumber, int boneID) + { + const auto* rendererItem = &_items[itemNumber]; + + if (rendererItem == nullptr) + return Quaternion::Identity; + + if (!rendererItem->DoneAnimations) + (itemNumber == LaraItem->Index) ? UpdateLaraAnimations(false) : UpdateItemAnimations(itemNumber, false); + + if (boneID >= MAX_BONES) + boneID = 0; + + return rendererItem->BoneOrientations[boneID]; + } + void Renderer::SaveScreenshot() { char buffer[64]; diff --git a/TombEngine/Renderer/Structures/RendererItem.h b/TombEngine/Renderer/Structures/RendererItem.h index 48780aa27..b4c974e22 100644 --- a/TombEngine/Renderer/Structures/RendererItem.h +++ b/TombEngine/Renderer/Structures/RendererItem.h @@ -1,13 +1,11 @@ #pragma once -#include + +#include "Game/room.h" #include "Renderer/RendererEnums.h" #include "Renderer/Structures/RendererLight.h" -#include "Game/room.h" namespace TEN::Renderer::Structures { - using namespace DirectX::SimpleMath; - struct RendererItem { int ItemNumber; @@ -20,6 +18,8 @@ namespace TEN::Renderer::Structures Matrix Scale; Matrix AnimationTransforms[MAX_BONES]; + Quaternion BoneOrientations[MAX_BONES]; + int RoomNumber = NO_VALUE; int PrevRoomNumber = NO_VALUE; Vector4 Color; From 60b9055d0adf90b02bc0c57ebfded36f7d70dcba Mon Sep 17 00:00:00 2001 From: Sezz Date: Tue, 27 Aug 2024 19:17:57 +1000 Subject: [PATCH 17/17] Add F12 as alternative to PrtSc for screenshots --- CHANGELOG.md | 1 + TombEngine/Specific/Input/Input.cpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85a365f08..4917c3c69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Added option to enable or disable menu option looping. * Menu scrolling using held inputs will stop at the last option until a new input is made. * Added the ability to display "Lara's Home" entry in the main menu. +* Added F12 as alternative to PrtSc for screenshots. ### Lua API changes * Added Inventory.GetUsedItem(), Inventory.SetUsedItem() and Inventory.ClearUsedItem() functions. diff --git a/TombEngine/Specific/Input/Input.cpp b/TombEngine/Specific/Input/Input.cpp index 80b8cd0b6..1365e4fc7 100644 --- a/TombEngine/Specific/Input/Input.cpp +++ b/TombEngine/Specific/Input/Input.cpp @@ -632,9 +632,9 @@ namespace TEN::Input { // Save screenshot. static bool dbScreenshot = true; - if (KeyMap[KC_SYSRQ] && dbScreenshot) + if ((KeyMap[KC_SYSRQ] || KeyMap[KC_F12]) && dbScreenshot) g_Renderer.SaveScreenshot(); - dbScreenshot = !KeyMap[KC_SYSRQ]; + dbScreenshot = !(KeyMap[KC_SYSRQ] || KeyMap[KC_F12]); // Toggle fullscreen. static bool dbFullscreen = true;
EnableFlyCheat(enabled)Enable or disable DOZY mode (fly cheat).Enable or disable the fly cheat.
EnablePointFilter(enabled)