mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-04-28 15:57:59 +03:00
Merge branch 'MontyTRC89:develop' into develop
This commit is contained in:
commit
bdea82d742
94 changed files with 1197 additions and 1242 deletions
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -26,20 +26,22 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
|
||||||
* Fixed teeth spikes not triggering the player impale animation.
|
* Fixed teeth spikes not triggering the player impale animation.
|
||||||
* Fixed TR4 mine crash with OCB 1 when triggered.
|
* Fixed TR4 mine crash with OCB 1 when triggered.
|
||||||
* Fixed cases where Atlantean mutant's bombs cause the game to crash.
|
* Fixed cases where Atlantean mutant's bombs cause the game to crash.
|
||||||
|
* Fixed young hair drawing.
|
||||||
|
|
||||||
### Features/Amendments
|
### Features/Amendments
|
||||||
* Changed Rome Hammer to not hurt player whilst deactivated.
|
* Changed Rome Hammer to not hurt player whilst deactivated.
|
||||||
* Changed Statue with blade damage, from 20 to 200.
|
* Changed Statue with blade damage, from 20 to 200.
|
||||||
* Enhaced Rolling Spindle detection to avoid them going down through pits.
|
* Enhanced 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 )
|
* 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 )
|
||||||
* 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 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.
|
* Enhanced raptor behaviour and handling.
|
||||||
- OCB 0: Classic behaviour
|
- OCB 0: Classic behaviour
|
||||||
- OCB 1: Can jump up/down up to 4 steps and jump across gaps up to 2 blocks wide.
|
- 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.
|
* Added TR3 seal mutant.
|
||||||
- OCB 0: Normal enemy behaviour. (TR3 RX-Tech mines level)
|
- OCB 0: Normal enemy behaviour. (TR3 RX-Tech mines level)
|
||||||
- OCB 1: Trap like behaviour. (TR3 Antarctica 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.
|
* Add new sound conditions: Quicksand and Underwater.
|
||||||
- Quicksand - sound effect plays when a moveable is in quicksand.
|
- Quicksand - sound effect plays when a moveable is in quicksand.
|
||||||
- Underwater - sound plays when the camera is submerged.
|
- Underwater - sound plays when the camera is submerged.
|
||||||
|
@ -47,6 +49,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
|
||||||
* Added option to enable or disable menu option looping.
|
* 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.
|
* 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 the ability to display "Lara's Home" entry in the main menu.
|
||||||
|
* Added F12 as alternative to PrtSc for screenshots.
|
||||||
|
|
||||||
### Lua API changes
|
### Lua API changes
|
||||||
* Added Inventory.GetUsedItem(), Inventory.SetUsedItem() and Inventory.ClearUsedItem() functions.
|
* Added Inventory.GetUsedItem(), Inventory.SetUsedItem() and Inventory.ClearUsedItem() functions.
|
||||||
|
|
|
@ -141,7 +141,7 @@ scripts too.</p>
|
||||||
<table class="function_list">
|
<table class="function_list">
|
||||||
<tr>
|
<tr>
|
||||||
<td class="name" ><a href="#EnableFlyCheat">EnableFlyCheat(enabled)</a></td>
|
<td class="name" ><a href="#EnableFlyCheat">EnableFlyCheat(enabled)</a></td>
|
||||||
<td class="summary">Enable or disable DOZY mode (fly cheat).</td>
|
<td class="summary">Enable or disable the fly cheat.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="name" ><a href="#EnablePointFilter">EnablePointFilter(enabled)</a></td>
|
<td class="name" ><a href="#EnablePointFilter">EnablePointFilter(enabled)</a></td>
|
||||||
|
@ -371,7 +371,7 @@ Must be true or false
|
||||||
<strong>EnableHomeLevel(enabled)</strong>
|
<strong>EnableHomeLevel(enabled)</strong>
|
||||||
</dt>
|
</dt>
|
||||||
<dd>
|
<dd>
|
||||||
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
|
||||||
<ul>
|
<ul>
|
||||||
<li><span class="parameter">enabled</span>
|
<li><span class="parameter">enabled</span>
|
||||||
<span class="types"><span class="type">bool</span></span>
|
<span class="types"><span class="type">bool</span></span>
|
||||||
true or false.
|
True or false.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -393,7 +393,7 @@ Must be true or false
|
||||||
<strong>EnableLoadSave(enabled)</strong>
|
<strong>EnableLoadSave(enabled)</strong>
|
||||||
</dt>
|
</dt>
|
||||||
<dd>
|
<dd>
|
||||||
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
|
||||||
<ul>
|
<ul>
|
||||||
<li><span class="parameter">enabled</span>
|
<li><span class="parameter">enabled</span>
|
||||||
<span class="types"><span class="type">bool</span></span>
|
<span class="types"><span class="type">bool</span></span>
|
||||||
true or false.
|
True or false.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -419,8 +419,7 @@ Must be true or false
|
||||||
<strong>EnableFlyCheat(enabled)</strong>
|
<strong>EnableFlyCheat(enabled)</strong>
|
||||||
</dt>
|
</dt>
|
||||||
<dd>
|
<dd>
|
||||||
Enable or disable DOZY mode (fly cheat).
|
Enable or disable the fly cheat. ()
|
||||||
Must be true or false
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -428,7 +427,7 @@ Must be true or false
|
||||||
<ul>
|
<ul>
|
||||||
<li><span class="parameter">enabled</span>
|
<li><span class="parameter">enabled</span>
|
||||||
<span class="types"><span class="type">bool</span></span>
|
<span class="types"><span class="type">bool</span></span>
|
||||||
true or false
|
True or false.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
|
@ -171,7 +171,8 @@ LARA_PETROL_MESH
|
||||||
LARA_DIRT_MESH
|
LARA_DIRT_MESH
|
||||||
LARA_CROWBAR_ANIM
|
LARA_CROWBAR_ANIM
|
||||||
LARA_TORCH_ANIM
|
LARA_TORCH_ANIM
|
||||||
HAIR
|
SINGLE_BRAID_HAIR
|
||||||
|
DUAL_PIGTAIL_HAIR
|
||||||
SNOWMOBILE_LARA_ANIMS
|
SNOWMOBILE_LARA_ANIMS
|
||||||
SNOWMOBILE
|
SNOWMOBILE
|
||||||
QUAD_LARA_ANIMS
|
QUAD_LARA_ANIMS
|
||||||
|
|
|
@ -331,21 +331,21 @@ namespace TEN::Gui
|
||||||
|
|
||||||
void CombineRevolverLasersight(ItemInfo* item, bool flag)
|
void CombineRevolverLasersight(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
if (flag)
|
if (flag)
|
||||||
{
|
{
|
||||||
lara->Inventory.HasLasersight = true;
|
player.Inventory.HasLasersight = true;
|
||||||
lara->Weapons[(int)LaraWeaponType::Revolver].HasLasersight = false;
|
player.Weapons[(int)LaraWeaponType::Revolver].HasLasersight = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lara->Inventory.HasLasersight = false;
|
player.Inventory.HasLasersight = false;
|
||||||
lara->Weapons[(int)LaraWeaponType::Revolver].HasLasersight = true;
|
player.Weapons[(int)LaraWeaponType::Revolver].HasLasersight = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lara->Control.HandStatus != HandStatus::Free &&
|
if (player.Control.HandStatus != HandStatus::Free &&
|
||||||
lara->Control.Weapon.GunType == LaraWeaponType::Revolver)
|
player.Control.Weapon.GunType == LaraWeaponType::Revolver)
|
||||||
{
|
{
|
||||||
UndrawPistolMesh(*item, LaraWeaponType::Revolver, true);
|
UndrawPistolMesh(*item, LaraWeaponType::Revolver, true);
|
||||||
DrawPistolMeshes(*item, LaraWeaponType::Revolver);
|
DrawPistolMeshes(*item, LaraWeaponType::Revolver);
|
||||||
|
@ -354,21 +354,21 @@ namespace TEN::Gui
|
||||||
|
|
||||||
void CombineCrossbowLasersight(ItemInfo* item, bool flag)
|
void CombineCrossbowLasersight(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
if (flag)
|
if (flag)
|
||||||
{
|
{
|
||||||
lara->Inventory.HasLasersight = true;
|
player.Inventory.HasLasersight = true;
|
||||||
lara->Weapons[(int)LaraWeaponType::Crossbow].HasLasersight = false;
|
player.Weapons[(int)LaraWeaponType::Crossbow].HasLasersight = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lara->Inventory.HasLasersight = false;
|
player.Inventory.HasLasersight = false;
|
||||||
lara->Weapons[(int)LaraWeaponType::Crossbow].HasLasersight = true;
|
player.Weapons[(int)LaraWeaponType::Crossbow].HasLasersight = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lara->Control.HandStatus != HandStatus::Free &&
|
if (player.Control.HandStatus != HandStatus::Free &&
|
||||||
lara->Control.Weapon.GunType == LaraWeaponType::Crossbow)
|
player.Control.Weapon.GunType == LaraWeaponType::Crossbow)
|
||||||
{
|
{
|
||||||
UndrawShotgunMeshes(*item, LaraWeaponType::Crossbow);
|
UndrawShotgunMeshes(*item, LaraWeaponType::Crossbow);
|
||||||
DrawShotgunMeshes(*item, LaraWeaponType::Crossbow);
|
DrawShotgunMeshes(*item, LaraWeaponType::Crossbow);
|
||||||
|
@ -377,21 +377,21 @@ namespace TEN::Gui
|
||||||
|
|
||||||
void CombineHKLasersight(ItemInfo* item, bool flag)
|
void CombineHKLasersight(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
if (flag)
|
if (flag)
|
||||||
{
|
{
|
||||||
lara->Inventory.HasLasersight = true;
|
player.Inventory.HasLasersight = true;
|
||||||
lara->Weapons[(int)LaraWeaponType::HK].HasLasersight = false;
|
player.Weapons[(int)LaraWeaponType::HK].HasLasersight = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lara->Inventory.HasLasersight = false;
|
player.Inventory.HasLasersight = false;
|
||||||
lara->Weapons[(int)LaraWeaponType::HK].HasLasersight = true;
|
player.Weapons[(int)LaraWeaponType::HK].HasLasersight = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lara->Control.HandStatus != HandStatus::Free &&
|
if (player.Control.HandStatus != HandStatus::Free &&
|
||||||
lara->Control.Weapon.GunType == LaraWeaponType::HK)
|
player.Control.Weapon.GunType == LaraWeaponType::HK)
|
||||||
{
|
{
|
||||||
UndrawShotgunMeshes(*item, LaraWeaponType::HK);
|
UndrawShotgunMeshes(*item, LaraWeaponType::HK);
|
||||||
DrawShotgunMeshes(*item, LaraWeaponType::HK);
|
DrawShotgunMeshes(*item, LaraWeaponType::HK);
|
||||||
|
@ -400,514 +400,514 @@ namespace TEN::Gui
|
||||||
|
|
||||||
void CombinePuzzleItem1(ItemInfo* item, bool flag)
|
void CombinePuzzleItem1(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.PuzzlesCombo[0] = false;
|
player.Inventory.PuzzlesCombo[0] = false;
|
||||||
lara->Inventory.PuzzlesCombo[1] = false;
|
player.Inventory.PuzzlesCombo[1] = false;
|
||||||
lara->Inventory.Puzzles[0] = true;
|
player.Inventory.Puzzles[0] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePuzzleItem2(ItemInfo* item, bool flag)
|
void CombinePuzzleItem2(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.PuzzlesCombo[2] = false;
|
player.Inventory.PuzzlesCombo[2] = false;
|
||||||
lara->Inventory.PuzzlesCombo[3] = false;
|
player.Inventory.PuzzlesCombo[3] = false;
|
||||||
lara->Inventory.Puzzles[1] = true;
|
player.Inventory.Puzzles[1] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePuzzleItem3(ItemInfo* item, bool flag)
|
void CombinePuzzleItem3(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.PuzzlesCombo[4] = false;
|
player.Inventory.PuzzlesCombo[4] = false;
|
||||||
lara->Inventory.PuzzlesCombo[5] = false;
|
player.Inventory.PuzzlesCombo[5] = false;
|
||||||
lara->Inventory.Puzzles[2] = true;
|
player.Inventory.Puzzles[2] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePuzzleItem4(ItemInfo* item, bool flag)
|
void CombinePuzzleItem4(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.PuzzlesCombo[6] = false;
|
player.Inventory.PuzzlesCombo[6] = false;
|
||||||
lara->Inventory.PuzzlesCombo[7] = false;
|
player.Inventory.PuzzlesCombo[7] = false;
|
||||||
lara->Inventory.Puzzles[3] = true;
|
player.Inventory.Puzzles[3] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePuzzleItem5(ItemInfo* item, bool flag)
|
void CombinePuzzleItem5(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.PuzzlesCombo[8] = false;
|
player.Inventory.PuzzlesCombo[8] = false;
|
||||||
lara->Inventory.PuzzlesCombo[9] = false;
|
player.Inventory.PuzzlesCombo[9] = false;
|
||||||
lara->Inventory.Puzzles[4] = true;
|
player.Inventory.Puzzles[4] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePuzzleItem6(ItemInfo* item, bool flag)
|
void CombinePuzzleItem6(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.PuzzlesCombo[10] = false;
|
player.Inventory.PuzzlesCombo[10] = false;
|
||||||
lara->Inventory.PuzzlesCombo[11] = false;
|
player.Inventory.PuzzlesCombo[11] = false;
|
||||||
lara->Inventory.Puzzles[5] = true;
|
player.Inventory.Puzzles[5] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePuzzleItem7(ItemInfo* item, bool flag)
|
void CombinePuzzleItem7(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.PuzzlesCombo[12] = false;
|
player.Inventory.PuzzlesCombo[12] = false;
|
||||||
lara->Inventory.PuzzlesCombo[13] = false;
|
player.Inventory.PuzzlesCombo[13] = false;
|
||||||
lara->Inventory.Puzzles[6] = true;
|
player.Inventory.Puzzles[6] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePuzzleItem8(ItemInfo* item, bool flag)
|
void CombinePuzzleItem8(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.PuzzlesCombo[14] = false;
|
player.Inventory.PuzzlesCombo[14] = false;
|
||||||
lara->Inventory.PuzzlesCombo[15] = false;
|
player.Inventory.PuzzlesCombo[15] = false;
|
||||||
lara->Inventory.Puzzles[7] = true;
|
player.Inventory.Puzzles[7] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePuzzleItem9(ItemInfo* item, bool flag)
|
void CombinePuzzleItem9(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.PuzzlesCombo[16] = false;
|
player.Inventory.PuzzlesCombo[16] = false;
|
||||||
lara->Inventory.PuzzlesCombo[17] = false;
|
player.Inventory.PuzzlesCombo[17] = false;
|
||||||
lara->Inventory.Puzzles[8] = true;
|
player.Inventory.Puzzles[8] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePuzzleItem10(ItemInfo* item, bool flag)
|
void CombinePuzzleItem10(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.PuzzlesCombo[18] = false;
|
player.Inventory.PuzzlesCombo[18] = false;
|
||||||
lara->Inventory.PuzzlesCombo[19] = false;
|
player.Inventory.PuzzlesCombo[19] = false;
|
||||||
lara->Inventory.Puzzles[9] = true;
|
player.Inventory.Puzzles[9] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePuzzleItem11(ItemInfo* item, bool flag)
|
void CombinePuzzleItem11(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.PuzzlesCombo[20] = false;
|
player.Inventory.PuzzlesCombo[20] = false;
|
||||||
lara->Inventory.PuzzlesCombo[21] = false;
|
player.Inventory.PuzzlesCombo[21] = false;
|
||||||
lara->Inventory.Puzzles[10] = true;
|
player.Inventory.Puzzles[10] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePuzzleItem12(ItemInfo* item, bool flag)
|
void CombinePuzzleItem12(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.PuzzlesCombo[22] = false;
|
player.Inventory.PuzzlesCombo[22] = false;
|
||||||
lara->Inventory.PuzzlesCombo[23] = false;
|
player.Inventory.PuzzlesCombo[23] = false;
|
||||||
lara->Inventory.Puzzles[11] = true;
|
player.Inventory.Puzzles[11] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePuzzleItem13(ItemInfo* item, bool flag)
|
void CombinePuzzleItem13(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.PuzzlesCombo[24] = false;
|
player.Inventory.PuzzlesCombo[24] = false;
|
||||||
lara->Inventory.PuzzlesCombo[25] = false;
|
player.Inventory.PuzzlesCombo[25] = false;
|
||||||
lara->Inventory.Puzzles[12] = true;
|
player.Inventory.Puzzles[12] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePuzzleItem14(ItemInfo* item, bool flag)
|
void CombinePuzzleItem14(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.PuzzlesCombo[26] = false;
|
player.Inventory.PuzzlesCombo[26] = false;
|
||||||
lara->Inventory.PuzzlesCombo[27] = false;
|
player.Inventory.PuzzlesCombo[27] = false;
|
||||||
lara->Inventory.Puzzles[13] = true;
|
player.Inventory.Puzzles[13] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePuzzleItem15(ItemInfo* item, bool flag)
|
void CombinePuzzleItem15(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.PuzzlesCombo[28] = false;
|
player.Inventory.PuzzlesCombo[28] = false;
|
||||||
lara->Inventory.PuzzlesCombo[29] = false;
|
player.Inventory.PuzzlesCombo[29] = false;
|
||||||
lara->Inventory.Puzzles[14] = true;
|
player.Inventory.Puzzles[14] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePuzzleItem16(ItemInfo* item, bool flag)
|
void CombinePuzzleItem16(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.PuzzlesCombo[30] = false;
|
player.Inventory.PuzzlesCombo[30] = false;
|
||||||
lara->Inventory.PuzzlesCombo[31] = false;
|
player.Inventory.PuzzlesCombo[31] = false;
|
||||||
lara->Inventory.Puzzles[15] = true;
|
player.Inventory.Puzzles[15] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineKeyItem1(ItemInfo* item, bool flag)
|
void CombineKeyItem1(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Keys[0] = true;
|
player.Inventory.Keys[0] = true;
|
||||||
lara->Inventory.KeysCombo[0] = false;
|
player.Inventory.KeysCombo[0] = false;
|
||||||
lara->Inventory.KeysCombo[1] = false;
|
player.Inventory.KeysCombo[1] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineKeyItem2(ItemInfo* item, bool flag)
|
void CombineKeyItem2(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Keys[1] = true;
|
player.Inventory.Keys[1] = true;
|
||||||
lara->Inventory.KeysCombo[2] = false;
|
player.Inventory.KeysCombo[2] = false;
|
||||||
lara->Inventory.KeysCombo[3] = false;
|
player.Inventory.KeysCombo[3] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineKeyItem3(ItemInfo* item, bool flag)
|
void CombineKeyItem3(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Keys[2] = true;
|
player.Inventory.Keys[2] = true;
|
||||||
lara->Inventory.KeysCombo[4] = false;
|
player.Inventory.KeysCombo[4] = false;
|
||||||
lara->Inventory.KeysCombo[5] = false;
|
player.Inventory.KeysCombo[5] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineKeyItem4(ItemInfo* item, bool flag)
|
void CombineKeyItem4(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Keys[3] = true;
|
player.Inventory.Keys[3] = true;
|
||||||
lara->Inventory.KeysCombo[6] = false;
|
player.Inventory.KeysCombo[6] = false;
|
||||||
lara->Inventory.KeysCombo[7] = false;
|
player.Inventory.KeysCombo[7] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineKeyItem5(ItemInfo* item, bool flag)
|
void CombineKeyItem5(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Keys[4] = true;
|
player.Inventory.Keys[4] = true;
|
||||||
lara->Inventory.KeysCombo[8] = false;
|
player.Inventory.KeysCombo[8] = false;
|
||||||
lara->Inventory.KeysCombo[9] = false;
|
player.Inventory.KeysCombo[9] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineKeyItem6(ItemInfo* item, bool flag)
|
void CombineKeyItem6(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Keys[5] = true;
|
player.Inventory.Keys[5] = true;
|
||||||
lara->Inventory.KeysCombo[10] = false;
|
player.Inventory.KeysCombo[10] = false;
|
||||||
lara->Inventory.KeysCombo[11] = false;
|
player.Inventory.KeysCombo[11] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineKeyItem7(ItemInfo* item, bool flag)
|
void CombineKeyItem7(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Keys[6] = true;
|
player.Inventory.Keys[6] = true;
|
||||||
lara->Inventory.KeysCombo[12] = false;
|
player.Inventory.KeysCombo[12] = false;
|
||||||
lara->Inventory.KeysCombo[13] = false;
|
player.Inventory.KeysCombo[13] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineKeyItem8(ItemInfo* item, bool flag)
|
void CombineKeyItem8(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Keys[7] = true;
|
player.Inventory.Keys[7] = true;
|
||||||
lara->Inventory.KeysCombo[14] = false;
|
player.Inventory.KeysCombo[14] = false;
|
||||||
lara->Inventory.KeysCombo[15] = false;
|
player.Inventory.KeysCombo[15] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineKeyItem9(ItemInfo* item, bool flag)
|
void CombineKeyItem9(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Keys[8] = true;
|
player.Inventory.Keys[8] = true;
|
||||||
lara->Inventory.KeysCombo[16] = false;
|
player.Inventory.KeysCombo[16] = false;
|
||||||
lara->Inventory.KeysCombo[17] = false;
|
player.Inventory.KeysCombo[17] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineKeyItem10(ItemInfo* item, bool flag)
|
void CombineKeyItem10(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Keys[9] = true;
|
player.Inventory.Keys[9] = true;
|
||||||
lara->Inventory.KeysCombo[18] = false;
|
player.Inventory.KeysCombo[18] = false;
|
||||||
lara->Inventory.KeysCombo[19] = false;
|
player.Inventory.KeysCombo[19] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineKeyItem11(ItemInfo* item, bool flag)
|
void CombineKeyItem11(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Keys[10] = true;
|
player.Inventory.Keys[10] = true;
|
||||||
lara->Inventory.KeysCombo[20] = false;
|
player.Inventory.KeysCombo[20] = false;
|
||||||
lara->Inventory.KeysCombo[21] = false;
|
player.Inventory.KeysCombo[21] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineKeyItem12(ItemInfo* item, bool flag)
|
void CombineKeyItem12(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Keys[11] = true;
|
player.Inventory.Keys[11] = true;
|
||||||
lara->Inventory.KeysCombo[22] = false;
|
player.Inventory.KeysCombo[22] = false;
|
||||||
lara->Inventory.KeysCombo[23] = false;
|
player.Inventory.KeysCombo[23] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineKeyItem13(ItemInfo* item, bool flag)
|
void CombineKeyItem13(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Keys[12] = true;
|
player.Inventory.Keys[12] = true;
|
||||||
lara->Inventory.KeysCombo[24] = false;
|
player.Inventory.KeysCombo[24] = false;
|
||||||
lara->Inventory.KeysCombo[25] = false;
|
player.Inventory.KeysCombo[25] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineKeyItem14(ItemInfo* item, bool flag)
|
void CombineKeyItem14(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Keys[13] = true;
|
player.Inventory.Keys[13] = true;
|
||||||
lara->Inventory.KeysCombo[26] = false;
|
player.Inventory.KeysCombo[26] = false;
|
||||||
lara->Inventory.KeysCombo[27] = false;
|
player.Inventory.KeysCombo[27] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineKeyItem15(ItemInfo* item, bool flag)
|
void CombineKeyItem15(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Keys[14] = true;
|
player.Inventory.Keys[14] = true;
|
||||||
lara->Inventory.KeysCombo[28] = false;
|
player.Inventory.KeysCombo[28] = false;
|
||||||
lara->Inventory.KeysCombo[29] = false;
|
player.Inventory.KeysCombo[29] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineKeyItem16(ItemInfo* item, bool flag)
|
void CombineKeyItem16(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Keys[15] = true;
|
player.Inventory.Keys[15] = true;
|
||||||
lara->Inventory.KeysCombo[30] = false;
|
player.Inventory.KeysCombo[30] = false;
|
||||||
lara->Inventory.KeysCombo[31] = false;
|
player.Inventory.KeysCombo[31] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePickupItem1(ItemInfo* item, bool flag)
|
void CombinePickupItem1(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Pickups[0] = true;
|
player.Inventory.Pickups[0] = true;
|
||||||
lara->Inventory.PickupsCombo[0] = false;
|
player.Inventory.PickupsCombo[0] = false;
|
||||||
lara->Inventory.PickupsCombo[1] = false;
|
player.Inventory.PickupsCombo[1] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePickupItem2(ItemInfo* item, bool flag)
|
void CombinePickupItem2(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Pickups[1] = true;
|
player.Inventory.Pickups[1] = true;
|
||||||
lara->Inventory.PickupsCombo[2] = false;
|
player.Inventory.PickupsCombo[2] = false;
|
||||||
lara->Inventory.PickupsCombo[3] = false;
|
player.Inventory.PickupsCombo[3] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePickupItem3(ItemInfo* item, bool flag)
|
void CombinePickupItem3(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Pickups[2] = true;
|
player.Inventory.Pickups[2] = true;
|
||||||
lara->Inventory.PickupsCombo[4] = false;
|
player.Inventory.PickupsCombo[4] = false;
|
||||||
lara->Inventory.PickupsCombo[5] = false;
|
player.Inventory.PickupsCombo[5] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePickupItem4(ItemInfo* item, bool flag)
|
void CombinePickupItem4(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Pickups[3] = true;
|
player.Inventory.Pickups[3] = true;
|
||||||
lara->Inventory.PickupsCombo[6] = false;
|
player.Inventory.PickupsCombo[6] = false;
|
||||||
lara->Inventory.PickupsCombo[7] = false;
|
player.Inventory.PickupsCombo[7] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePickupItem5(ItemInfo* item, bool flag)
|
void CombinePickupItem5(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Pickups[4] = true;
|
player.Inventory.Pickups[4] = true;
|
||||||
lara->Inventory.PickupsCombo[8] = false;
|
player.Inventory.PickupsCombo[8] = false;
|
||||||
lara->Inventory.PickupsCombo[9] = false;
|
player.Inventory.PickupsCombo[9] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePickupItem6(ItemInfo* item, bool flag)
|
void CombinePickupItem6(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Pickups[5] = true;
|
player.Inventory.Pickups[5] = true;
|
||||||
lara->Inventory.PickupsCombo[10] = false;
|
player.Inventory.PickupsCombo[10] = false;
|
||||||
lara->Inventory.PickupsCombo[11] = false;
|
player.Inventory.PickupsCombo[11] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePickupItem7(ItemInfo* item, bool flag)
|
void CombinePickupItem7(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Pickups[6] = true;
|
player.Inventory.Pickups[6] = true;
|
||||||
lara->Inventory.PickupsCombo[12] = false;
|
player.Inventory.PickupsCombo[12] = false;
|
||||||
lara->Inventory.PickupsCombo[13] = false;
|
player.Inventory.PickupsCombo[13] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePickupItem8(ItemInfo* item, bool flag)
|
void CombinePickupItem8(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Pickups[7] = true;
|
player.Inventory.Pickups[7] = true;
|
||||||
lara->Inventory.PickupsCombo[14] = false;
|
player.Inventory.PickupsCombo[14] = false;
|
||||||
lara->Inventory.PickupsCombo[15] = false;
|
player.Inventory.PickupsCombo[15] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePickupItem9(ItemInfo* item, bool flag)
|
void CombinePickupItem9(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Pickups[8] = true;
|
player.Inventory.Pickups[8] = true;
|
||||||
lara->Inventory.PickupsCombo[16] = false;
|
player.Inventory.PickupsCombo[16] = false;
|
||||||
lara->Inventory.PickupsCombo[17] = false;
|
player.Inventory.PickupsCombo[17] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePickupItem10(ItemInfo* item, bool flag)
|
void CombinePickupItem10(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Pickups[9] = true;
|
player.Inventory.Pickups[9] = true;
|
||||||
lara->Inventory.PickupsCombo[18] = false;
|
player.Inventory.PickupsCombo[18] = false;
|
||||||
lara->Inventory.PickupsCombo[19] = false;
|
player.Inventory.PickupsCombo[19] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePickupItem11(ItemInfo* item, bool flag)
|
void CombinePickupItem11(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Pickups[10] = true;
|
player.Inventory.Pickups[10] = true;
|
||||||
lara->Inventory.PickupsCombo[20] = false;
|
player.Inventory.PickupsCombo[20] = false;
|
||||||
lara->Inventory.PickupsCombo[21] = false;
|
player.Inventory.PickupsCombo[21] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePickupItem12(ItemInfo* item, bool flag)
|
void CombinePickupItem12(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Pickups[11] = true;
|
player.Inventory.Pickups[11] = true;
|
||||||
lara->Inventory.PickupsCombo[22] = false;
|
player.Inventory.PickupsCombo[22] = false;
|
||||||
lara->Inventory.PickupsCombo[23] = false;
|
player.Inventory.PickupsCombo[23] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePickupItem13(ItemInfo* item, bool flag)
|
void CombinePickupItem13(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Pickups[12] = true;
|
player.Inventory.Pickups[12] = true;
|
||||||
lara->Inventory.PickupsCombo[24] = false;
|
player.Inventory.PickupsCombo[24] = false;
|
||||||
lara->Inventory.PickupsCombo[25] = false;
|
player.Inventory.PickupsCombo[25] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePickupItem14(ItemInfo* item, bool flag)
|
void CombinePickupItem14(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Pickups[13] = true;
|
player.Inventory.Pickups[13] = true;
|
||||||
lara->Inventory.PickupsCombo[26] = false;
|
player.Inventory.PickupsCombo[26] = false;
|
||||||
lara->Inventory.PickupsCombo[27] = false;
|
player.Inventory.PickupsCombo[27] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePickupItem15(ItemInfo* item, bool flag)
|
void CombinePickupItem15(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Pickups[14] = true;
|
player.Inventory.Pickups[14] = true;
|
||||||
lara->Inventory.PickupsCombo[28] = false;
|
player.Inventory.PickupsCombo[28] = false;
|
||||||
lara->Inventory.PickupsCombo[29] = false;
|
player.Inventory.PickupsCombo[29] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombinePickupItem16(ItemInfo* item, bool flag)
|
void CombinePickupItem16(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Pickups[15] = true;
|
player.Inventory.Pickups[15] = true;
|
||||||
lara->Inventory.PickupsCombo[30] = false;
|
player.Inventory.PickupsCombo[30] = false;
|
||||||
lara->Inventory.PickupsCombo[31] = false;
|
player.Inventory.PickupsCombo[31] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineExamine1(ItemInfo* item, bool flag)
|
void CombineExamine1(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Examines[0] = true;
|
player.Inventory.Examines[0] = true;
|
||||||
lara->Inventory.ExaminesCombo[0] = false;
|
player.Inventory.ExaminesCombo[0] = false;
|
||||||
lara->Inventory.ExaminesCombo[1] = false;
|
player.Inventory.ExaminesCombo[1] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineExamine2(ItemInfo* item, bool flag)
|
void CombineExamine2(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Examines[1] = true;
|
player.Inventory.Examines[1] = true;
|
||||||
lara->Inventory.ExaminesCombo[2] = false;
|
player.Inventory.ExaminesCombo[2] = false;
|
||||||
lara->Inventory.ExaminesCombo[3] = false;
|
player.Inventory.ExaminesCombo[3] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineExamine3(ItemInfo* item, bool flag)
|
void CombineExamine3(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Examines[2] = true;
|
player.Inventory.Examines[2] = true;
|
||||||
lara->Inventory.ExaminesCombo[4] = false;
|
player.Inventory.ExaminesCombo[4] = false;
|
||||||
lara->Inventory.ExaminesCombo[5] = false;
|
player.Inventory.ExaminesCombo[5] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineExamine4(ItemInfo* item, bool flag)
|
void CombineExamine4(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Examines[3] = true;
|
player.Inventory.Examines[3] = true;
|
||||||
lara->Inventory.ExaminesCombo[6] = false;
|
player.Inventory.ExaminesCombo[6] = false;
|
||||||
lara->Inventory.ExaminesCombo[7] = false;
|
player.Inventory.ExaminesCombo[7] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineExamine5(ItemInfo* item, bool flag)
|
void CombineExamine5(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Examines[4] = true;
|
player.Inventory.Examines[4] = true;
|
||||||
lara->Inventory.ExaminesCombo[8] = false;
|
player.Inventory.ExaminesCombo[8] = false;
|
||||||
lara->Inventory.ExaminesCombo[9] = false;
|
player.Inventory.ExaminesCombo[9] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineExamine6(ItemInfo* item, bool flag)
|
void CombineExamine6(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Examines[5] = true;
|
player.Inventory.Examines[5] = true;
|
||||||
lara->Inventory.ExaminesCombo[10] = false;
|
player.Inventory.ExaminesCombo[10] = false;
|
||||||
lara->Inventory.ExaminesCombo[11] = false;
|
player.Inventory.ExaminesCombo[11] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineExamine7(ItemInfo* item, bool flag)
|
void CombineExamine7(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Examines[6] = true;
|
player.Inventory.Examines[6] = true;
|
||||||
lara->Inventory.ExaminesCombo[12] = false;
|
player.Inventory.ExaminesCombo[12] = false;
|
||||||
lara->Inventory.ExaminesCombo[13] = false;
|
player.Inventory.ExaminesCombo[13] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineExamine8(ItemInfo* item, bool flag)
|
void CombineExamine8(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.Examines[7] = true;
|
player.Inventory.Examines[7] = true;
|
||||||
lara->Inventory.ExaminesCombo[14] = false;
|
player.Inventory.ExaminesCombo[14] = false;
|
||||||
lara->Inventory.ExaminesCombo[15] = false;
|
player.Inventory.ExaminesCombo[15] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CombineClockWorkBeetle(ItemInfo* item, bool flag)
|
void CombineClockWorkBeetle(ItemInfo* item, bool flag)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
lara->Inventory.BeetleComponents |= BEETLECOMP_FLAG_BEETLE; // Get beetle.
|
player.Inventory.BeetleComponents |= BEETLECOMP_FLAG_BEETLE; // Get beetle.
|
||||||
lara->Inventory.BeetleComponents &= BEETLECOMP_FLAG_COMBO_1; // Remove combo 1.
|
player.Inventory.BeetleComponents &= BEETLECOMP_FLAG_COMBO_1; // Remove combo 1.
|
||||||
lara->Inventory.BeetleComponents &= BEETLECOMP_FLAG_COMBO_2; // Remove combo 2.
|
player.Inventory.BeetleComponents &= BEETLECOMP_FLAG_COMBO_2; // Remove combo 2.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -640,7 +640,7 @@ void UpdateLara(ItemInfo* item, bool isTitle)
|
||||||
g_Renderer.UpdateLaraAnimations(true);
|
g_Renderer.UpdateLaraAnimations(true);
|
||||||
|
|
||||||
// Update player effects.
|
// Update player effects.
|
||||||
HairEffect.Update(*item, g_GameFlow->GetLevel(CurrentLevel)->GetLaraType() == LaraType::Young);
|
HairEffect.Update(*item);
|
||||||
HandlePlayerWetnessDrips(*item);
|
HandlePlayerWetnessDrips(*item);
|
||||||
HandlePlayerDiveBubbles(*item);
|
HandlePlayerDiveBubbles(*item);
|
||||||
ProcessEffects(item);
|
ProcessEffects(item);
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/camera.h"
|
#include "Game/camera.h"
|
||||||
#include "Game/collision/Point.h"
|
#include "Game/collision/Point.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/control/control.h"
|
#include "Game/control/control.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
#include "Game/Lara/lara.h"
|
#include "Game/Lara/lara.h"
|
||||||
|
|
|
@ -497,13 +497,11 @@ void LaraSurfaceCollision(ItemInfo* item, CollisionInfo* coll)
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pointColl = GetPointCollision(*item);
|
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)
|
if ((pointColl.GetFloorHeight() - item->Pose.Position.y) < SWIM_WATER_DEPTH)
|
||||||
{
|
{
|
||||||
TestPlayerWaterStepOut(item, coll);
|
TestPlayerWaterStepOut(item, coll);
|
||||||
}
|
}
|
||||||
else if ((waterHeight - item->Pose.Position.y) <= -LARA_HEADROOM)
|
else if ((pointColl.GetWaterTopHeight() - item->Pose.Position.y) <= -LARA_HEADROOM)
|
||||||
{
|
{
|
||||||
SetLaraSwimDiveAnimation(item);
|
SetLaraSwimDiveAnimation(item);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
|
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/camera.h"
|
#include "Game/camera.h"
|
||||||
#include "Game/collision/sphere.h"
|
#include "Game/collision/Sphere.h"
|
||||||
#include "Game/control/los.h"
|
#include "Game/control/los.h"
|
||||||
#include "Game/control/lot.h"
|
#include "Game/control/lot.h"
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
|
@ -31,6 +31,7 @@
|
||||||
#include "Specific/level.h"
|
#include "Specific/level.h"
|
||||||
#include "Specific/trutils.h"
|
#include "Specific/trutils.h"
|
||||||
|
|
||||||
|
using namespace TEN::Collision::Sphere;
|
||||||
using namespace TEN::Entities::Generic;
|
using namespace TEN::Entities::Generic;
|
||||||
using namespace TEN::Input;
|
using namespace TEN::Input;
|
||||||
using namespace TEN::Math;
|
using namespace TEN::Math;
|
||||||
|
@ -842,23 +843,6 @@ FireWeaponType FireWeapon(LaraWeaponType weaponType, ItemInfo& targetEntity, Ite
|
||||||
auto target = origin + (directionNorm * weapon.TargetDist);
|
auto target = origin + (directionNorm * weapon.TargetDist);
|
||||||
auto ray = Ray(origin, directionNorm);
|
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.HasFired = true;
|
||||||
player.Control.Weapon.Fired = true;
|
player.Control.Weapon.Fired = true;
|
||||||
|
|
||||||
|
@ -867,7 +851,30 @@ FireWeaponType FireWeapon(LaraWeaponType weaponType, ItemInfo& targetEntity, Ite
|
||||||
GetFloor(pos.x, pos.y, pos.z, &roomNumber);
|
GetFloor(pos.x, pos.y, pos.z, &roomNumber);
|
||||||
vOrigin.RoomNumber = 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);
|
auto vTarget = GameVector(target);
|
||||||
GetTargetOnLOS(&vOrigin, &vTarget, false, true);
|
GetTargetOnLOS(&vOrigin, &vTarget, false, true);
|
||||||
|
@ -876,13 +883,13 @@ FireWeaponType FireWeapon(LaraWeaponType weaponType, ItemInfo& targetEntity, Ite
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SaveGame::Statistics.Game.AmmoHits++;
|
SaveGame::Statistics.Game.AmmoHits++;
|
||||||
target = origin + (directionNorm * bestDistance);
|
target = origin + (directionNorm * closestDist);
|
||||||
auto vTarget = GameVector(target);
|
auto vTarget = GameVector(target);
|
||||||
|
|
||||||
// NOTE: It seems that entities hit by the player in the normal way must have GetTargetOnLOS return false.
|
// 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.
|
// It's strange, but this replicates original behaviour until we fully understand what is happening.
|
||||||
if (!GetTargetOnLOS(&vOrigin, &vTarget, false, true))
|
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;
|
return FireWeaponType::PossibleHit;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/camera.h"
|
#include "Game/camera.h"
|
||||||
|
#include "Game/collision/Point.h"
|
||||||
#include "Game/control/control.h"
|
#include "Game/control/control.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
#include "Game/Lara/lara_collide.h"
|
#include "Game/Lara/lara_collide.h"
|
||||||
|
@ -14,6 +15,7 @@
|
||||||
#include "Specific/level.h"
|
#include "Specific/level.h"
|
||||||
#include "Specific/Input/Input.h"
|
#include "Specific/Input/Input.h"
|
||||||
|
|
||||||
|
using namespace TEN::Collision::Point;
|
||||||
using namespace TEN::Input;
|
using namespace TEN::Input;
|
||||||
|
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
|
@ -187,7 +189,7 @@ void lara_col_underwater_death(ItemInfo* item, CollisionInfo* coll)
|
||||||
item->HitPoints = -1;
|
item->HitPoints = -1;
|
||||||
lara->Control.HandStatus = HandStatus::Busy;
|
lara->Control.HandStatus = HandStatus::Busy;
|
||||||
|
|
||||||
int waterHeight = GetWaterHeight(item);
|
int waterHeight = GetPointCollision(*item).GetWaterTopHeight();
|
||||||
if (waterHeight < (item->Pose.Position.y - (CLICK(0.4f) - 2)) &&
|
if (waterHeight < (item->Pose.Position.y - (CLICK(0.4f) - 2)) &&
|
||||||
waterHeight != NO_HEIGHT)
|
waterHeight != NO_HEIGHT)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1087,15 +1087,13 @@ void TestLaraWaterDepth(ItemInfo* item, CollisionInfo* coll)
|
||||||
auto& player = GetLaraInfo(*item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
auto pointColl = GetPointCollision(*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->Animation.Velocity.y = 0.0f;
|
||||||
item->Pose.Position = coll->Setup.PrevPosition;
|
item->Pose.Position = coll->Setup.PrevPosition;
|
||||||
}
|
}
|
||||||
|
else if (pointColl.GetWaterBottomHeight() <= (LARA_HEIGHT - (LARA_HEADROOM / 2)))
|
||||||
else if (waterDepth <= (LARA_HEIGHT - (LARA_HEADROOM / 2)))
|
|
||||||
{
|
{
|
||||||
SetAnimation(item, LA_UNDERWATER_TO_STAND);
|
SetAnimation(item, LA_UNDERWATER_TO_STAND);
|
||||||
ResetPlayerLean(item);
|
ResetPlayerLean(item);
|
||||||
|
|
|
@ -711,7 +711,7 @@ void ClampRotation(Pose& outPose, short angle, short rotation)
|
||||||
Vector3i GetJointPosition(const ItemInfo& item, int jointIndex, const Vector3i& relOffset)
|
Vector3i GetJointPosition(const ItemInfo& item, int jointIndex, const Vector3i& relOffset)
|
||||||
{
|
{
|
||||||
// Use matrices done in renderer to transform relative offset.
|
// 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)
|
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));
|
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;
|
return g_Renderer.GetMoveableBoneOrientation(item.Index, boneID);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Will not work for bones at ends of hierarchies.
|
// NOTE: Will not work for bones at ends of hierarchies.
|
||||||
|
|
|
@ -177,9 +177,24 @@ namespace TEN::Collision::Point
|
||||||
if (_waterSurfaceHeight.has_value())
|
if (_waterSurfaceHeight.has_value())
|
||||||
return *_waterSurfaceHeight;
|
return *_waterSurfaceHeight;
|
||||||
|
|
||||||
// Set water surface height. TODO: Calculate here.
|
auto* room = &g_Level.Rooms[_roomNumber];
|
||||||
_waterSurfaceHeight = GetWaterSurface(_position.x, _position.y, _position.z, _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;
|
return *_waterSurfaceHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,20 +203,197 @@ namespace TEN::Collision::Point
|
||||||
if (_waterBottomHeight.has_value())
|
if (_waterBottomHeight.has_value())
|
||||||
return *_waterBottomHeight;
|
return *_waterBottomHeight;
|
||||||
|
|
||||||
// Set water bottom height. TODO: Calculate here.
|
FloorInfo* sector = nullptr;
|
||||||
_waterBottomHeight = GetWaterDepth(_position.x, _position.y, _position.z, _roomNumber);
|
auto* room = &g_Level.Rooms[_roomNumber];
|
||||||
|
short 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);
|
||||||
|
|
||||||
|
// 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;
|
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()
|
int PointCollisionData::GetWaterTopHeight()
|
||||||
{
|
{
|
||||||
if (_waterTopHeight.has_value())
|
if (_waterTopHeight.has_value())
|
||||||
return *_waterTopHeight;
|
return *_waterTopHeight;
|
||||||
|
|
||||||
// Set water top height. TODO: Calculate here.
|
FloorInfo* sector = nullptr;
|
||||||
_waterTopHeight = GetWaterHeight(_position.x, _position.y, _position.z, _roomNumber);
|
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;
|
return *_waterTopHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include "Game/collision/collide_room.h"
|
#include "Game/collision/collide_room.h"
|
||||||
#include "Game/collision/floordata.h"
|
#include "Game/collision/floordata.h"
|
||||||
#include "Game/collision/Point.h"
|
#include "Game/collision/Point.h"
|
||||||
#include "Game/collision/sphere.h"
|
#include "Game/collision/Sphere.h"
|
||||||
#include "Game/effects/debris.h"
|
#include "Game/effects/debris.h"
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/effects/simple_particle.h"
|
#include "Game/effects/simple_particle.h"
|
||||||
|
@ -23,81 +23,73 @@
|
||||||
|
|
||||||
using namespace TEN::Collision::Floordata;
|
using namespace TEN::Collision::Floordata;
|
||||||
using namespace TEN::Collision::Point;
|
using namespace TEN::Collision::Point;
|
||||||
|
using namespace TEN::Collision::Sphere;
|
||||||
using namespace TEN::Math;
|
using namespace TEN::Math;
|
||||||
|
|
||||||
constexpr auto ANIMATED_ALIGNMENT_FRAME_COUNT_THRESHOLD = 6;
|
constexpr auto ANIMATED_ALIGNMENT_FRAME_COUNT_THRESHOLD = 6;
|
||||||
|
|
||||||
// Globals
|
// Globals
|
||||||
|
|
||||||
GameBoundingBox GlobalCollisionBounds;
|
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);
|
const auto& sphere = spheres[i];
|
||||||
if (collidedBits)
|
|
||||||
|
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;
|
auto deltaPos = pos - playerItem->Pose.Position;
|
||||||
GetSpheres(item, CreatureSpheres, SPHERES_SPACE_WORLD, Matrix::Identity);
|
if (deltaPos != Vector3i::Zero)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
if (collidedBits & 1)
|
if (TriggerActive(&item))
|
||||||
{
|
|
||||||
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();
|
TriggerLaraBlood();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!coll->Setup.EnableObjectPush)
|
if (!coll->Setup.EnableObjectPush)
|
||||||
{
|
playerItem->Pose.Position += deltaPos;
|
||||||
laraItem->Pose.Position.x += dx;
|
|
||||||
laraItem->Pose.Position.y += dy;
|
|
||||||
laraItem->Pose.Position.z += dz;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
collidedBits >>= 1;
|
harmBits >>= 1;
|
||||||
deadlyBits >>= 1;
|
|
||||||
sphere++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1958,7 +1950,7 @@ void ObjectCollision(const short itemNumber, ItemInfo* laraItem, CollisionInfo*
|
||||||
|
|
||||||
if (TestBoundsCollide(item, laraItem, coll->Setup.Radius))
|
if (TestBoundsCollide(item, laraItem, coll->Setup.Radius))
|
||||||
{
|
{
|
||||||
if (TestCollision(item, laraItem))
|
if (HandleItemSphereCollision(*item, *laraItem))
|
||||||
{
|
{
|
||||||
if (coll->Setup.EnableObjectPush)
|
if (coll->Setup.EnableObjectPush)
|
||||||
ItemPushItem(item, laraItem, coll, false, 1);
|
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))
|
if (!TestBoundsCollide(item, laraItem, coll->Setup.Radius))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!TestCollision(item, laraItem))
|
if (!HandleItemSphereCollision(*item, *laraItem))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool doPlayerCollision = laraItem->IsLara();
|
bool doPlayerCollision = laraItem->IsLara();
|
||||||
|
@ -2008,7 +2000,7 @@ void TrapCollision(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll)
|
||||||
if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius))
|
if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TestCollision(&item, playerItem);
|
HandleItemSphereCollision(item, *playerItem);
|
||||||
}
|
}
|
||||||
else if (item.Status != ITEM_INVISIBLE)
|
else if (item.Status != ITEM_INVISIBLE)
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,7 +36,7 @@ struct CollidedObjectData
|
||||||
bool IsEmpty() const { return (Items.empty() && Statics.empty()); };
|
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);
|
CollidedObjectData GetCollidedObjects(ItemInfo& collidingItem, bool onlyVisible, bool ignorePlayer, float customRadius = 0.0f, ObjectCollectionMode mode = ObjectCollectionMode::All);
|
||||||
bool TestWithGlobalCollisionBounds(ItemInfo* item, ItemInfo* laraItem, CollisionInfo* coll);
|
bool TestWithGlobalCollisionBounds(ItemInfo* item, ItemInfo* laraItem, CollisionInfo* coll);
|
||||||
void TestForObjectOnLedge(ItemInfo* item, CollisionInfo* coll);
|
void TestForObjectOnLedge(ItemInfo* item, CollisionInfo* coll);
|
||||||
|
|
|
@ -1081,246 +1081,6 @@ int GetDistanceToFloor(int itemNumber, bool precise)
|
||||||
return (minHeight + item.Pose.Position.y - height);
|
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)
|
bool TestEnvironment(RoomEnvFlags environmentType, int x, int y, int z, int roomNumber)
|
||||||
{
|
{
|
||||||
return TestEnvironment(environmentType, GetPointCollision(Vector3i(x, y, z), roomNumber).GetRoomNumber());
|
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]);
|
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);
|
return TestEnvironmentFlags(environmentType, room->flags);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 GetCeiling(FloorInfo* floor, int x, int y, int z);
|
||||||
int GetDistanceToFloor(int itemNumber, bool precise = true);
|
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);
|
int FindGridShift(int x, int z);
|
||||||
void ShiftItem(ItemInfo* item, CollisionInfo* coll);
|
void ShiftItem(ItemInfo* item, CollisionInfo* coll);
|
||||||
void SnapItemToLedge(ItemInfo* item, CollisionInfo* coll, float offsetMultiplier = 0.0f, bool snapToAngle = true);
|
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 Vector3i& pos, int roomNumber);
|
||||||
bool TestEnvironment(RoomEnvFlags environmentType, const ItemInfo* item);
|
bool TestEnvironment(RoomEnvFlags environmentType, const ItemInfo* item);
|
||||||
bool TestEnvironment(RoomEnvFlags environmentType, int roomNumber);
|
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);
|
bool TestEnvironmentFlags(RoomEnvFlags environmentType, int flags);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include "framework.h"
|
#include "framework.h"
|
||||||
#include "Game/collision/sphere.h"
|
#include "Game/collision/Sphere.h"
|
||||||
|
|
||||||
#include "Game/Lara/lara.h"
|
#include "Game/Lara/lara.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
|
@ -8,85 +8,54 @@
|
||||||
#include "Math/Math.h"
|
#include "Math/Math.h"
|
||||||
#include "Renderer/Renderer.h"
|
#include "Renderer/Renderer.h"
|
||||||
|
|
||||||
|
using namespace TEN::Math;
|
||||||
using namespace TEN::Renderer;
|
using namespace TEN::Renderer;
|
||||||
|
|
||||||
SPHERE LaraSpheres[MAX_SPHERES];
|
namespace TEN::Collision::Sphere
|
||||||
SPHERE CreatureSpheres[MAX_SPHERES];
|
|
||||||
|
|
||||||
int GetSpheres(ItemInfo* item, SPHERE* ptr, int worldSpace, Matrix local)
|
|
||||||
{
|
{
|
||||||
if (item == nullptr)
|
bool HandleItemSphereCollision(ItemInfo& item0, ItemInfo& item1)
|
||||||
return 0;
|
|
||||||
|
|
||||||
BoundingSphere spheres[MAX_SPHERES];
|
|
||||||
int num = g_Renderer.GetSpheres(item->Index, spheres, worldSpace, local);
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_SPHERES; i++)
|
|
||||||
{
|
{
|
||||||
ptr[i].x = spheres[i].Center.x;
|
auto spheres0 = item0.GetSpheres();
|
||||||
ptr[i].y = spheres[i].Center.y;
|
auto spheres1 = item1.GetSpheres();
|
||||||
ptr[i].z = spheres[i].Center.z;
|
|
||||||
ptr[i].r = spheres[i].Radius;
|
item1.TouchBits.ClearAll();
|
||||||
|
|
||||||
|
if (spheres0.empty())
|
||||||
|
{
|
||||||
|
item0.TouchBits.ClearAll();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return num;
|
// Run through item 0 spheres.
|
||||||
}
|
bool isCollided = false;
|
||||||
|
for (int i = 0; i < spheres0.size(); i++)
|
||||||
int TestCollision(ItemInfo* item, ItemInfo* laraItem)
|
|
||||||
{
|
{
|
||||||
int flags = 0;
|
// Get sphere 0.
|
||||||
|
const auto& sphere0 = spheres0[i];
|
||||||
|
if (sphere0.Radius <= 0.0f)
|
||||||
|
continue;
|
||||||
|
|
||||||
int creatureSphereCount = GetSpheres(item, CreatureSpheres, SPHERES_SPACE_WORLD, Matrix::Identity);
|
// Run through item 1 spheres.
|
||||||
int laraSphereCount = GetSpheres(laraItem, LaraSpheres, SPHERES_SPACE_WORLD, Matrix::Identity);
|
for (int j = 0; j < spheres1.size(); j++)
|
||||||
|
|
||||||
laraItem->TouchBits = NO_JOINT_BITS;
|
|
||||||
|
|
||||||
if (creatureSphereCount <= 0)
|
|
||||||
{
|
{
|
||||||
item->TouchBits = NO_JOINT_BITS;
|
// Get sphere 1.
|
||||||
return 0;
|
const auto& sphere1 = spheres1[j];
|
||||||
}
|
if (sphere1.Radius <= 0.0f)
|
||||||
else
|
continue;
|
||||||
{
|
|
||||||
for (int i = 0; i < creatureSphereCount; i++)
|
|
||||||
{
|
|
||||||
auto* ptr1 = &CreatureSpheres[i];
|
|
||||||
|
|
||||||
int x1 = item->Pose.Position.x + ptr1->x;
|
// Test sphere collision.
|
||||||
int y1 = item->Pose.Position.y + ptr1->y;
|
if (!sphere0.Intersects(sphere1))
|
||||||
int z1 = item->Pose.Position.z + ptr1->z;
|
continue;
|
||||||
int r1 = ptr1->r;
|
|
||||||
|
|
||||||
if (r1 > 0)
|
// Set touch bits.
|
||||||
{
|
item0.TouchBits.Set(i);
|
||||||
for (int j = 0; j < laraSphereCount; j++)
|
item1.TouchBits.Set(j);
|
||||||
{
|
|
||||||
auto* ptr2 = &LaraSpheres[j];
|
|
||||||
|
|
||||||
int x2 = item->Pose.Position.x + ptr2->x;
|
isCollided = true;
|
||||||
int y2 = item->Pose.Position.y + ptr2->y;
|
|
||||||
int z2 = item->Pose.Position.z + ptr2->z;
|
|
||||||
int r2 = ptr2->r;
|
|
||||||
|
|
||||||
if (r2 > 0)
|
|
||||||
{
|
|
||||||
int dx = x1 - x2;
|
|
||||||
int dy = y1 - y2;
|
|
||||||
int dz = z1 - z2;
|
|
||||||
int r = r1 + r2;
|
|
||||||
|
|
||||||
if ((SQUARE(dx) + SQUARE(dy) + SQUARE(dz)) < SQUARE(r))
|
|
||||||
{
|
|
||||||
item->TouchBits.Set(i);
|
|
||||||
laraItem->TouchBits.Set(j);
|
|
||||||
flags |= 1 << i;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return flags;
|
return isCollided;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "Game/items.h"
|
|
||||||
|
|
||||||
#define SPHERES_SPACE_LOCAL 0
|
struct ItemInfo;
|
||||||
#define SPHERES_SPACE_WORLD 1
|
|
||||||
#define SPHERES_SPACE_BONE_ORIGIN 2
|
|
||||||
#define MAX_SPHERES 34
|
|
||||||
|
|
||||||
struct SPHERE
|
namespace TEN::Collision::Sphere
|
||||||
{
|
{
|
||||||
int x = 0;
|
bool HandleItemSphereCollision(ItemInfo& item0, ItemInfo& item1);
|
||||||
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);
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/camera.h"
|
#include "Game/camera.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/collision/collide_room.h"
|
#include "Game/collision/collide_room.h"
|
||||||
#include "Game/collision/Point.h"
|
#include "Game/collision/Point.h"
|
||||||
#include "Game/control/control.h"
|
#include "Game/control/control.h"
|
||||||
|
@ -613,7 +612,7 @@ void CreatureUnderwater(ItemInfo* item, int depth)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
waterHeight = GetWaterHeight(item);
|
waterHeight = GetPointCollision(*item).GetWaterTopHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
int y = waterHeight + waterLevel;
|
int y = waterHeight + waterLevel;
|
||||||
|
@ -647,7 +646,7 @@ void CreatureFloat(short itemNumber)
|
||||||
item->Pose.Orientation.x = 0;
|
item->Pose.Orientation.x = 0;
|
||||||
|
|
||||||
int y = item->Pose.Position.y;
|
int y = item->Pose.Position.y;
|
||||||
int waterLevel = GetWaterHeight(item);
|
int waterLevel = GetPointCollision(*item).GetWaterTopHeight();
|
||||||
if (waterLevel == NO_HEIGHT)
|
if (waterLevel == NO_HEIGHT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -794,7 +793,7 @@ void CreatureHealth(ItemInfo* item)
|
||||||
TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, &g_Level.Rooms[item->RoomNumber]))
|
TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, &g_Level.Rooms[item->RoomNumber]))
|
||||||
{
|
{
|
||||||
auto bounds = GameBoundingBox(item);
|
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)
|
if (abs(bounds.Y1 + bounds.Y2) < height)
|
||||||
DoDamage(item, INT_MAX);
|
DoDamage(item, INT_MAX);
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
#include "Game/camera.h"
|
#include "Game/camera.h"
|
||||||
#include "Game/collision/collide_room.h"
|
#include "Game/collision/collide_room.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/control/flipeffect.h"
|
#include "Game/control/flipeffect.h"
|
||||||
#include "Game/control/lot.h"
|
#include "Game/control/lot.h"
|
||||||
#include "Game/control/volume.h"
|
#include "Game/control/volume.h"
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/collision/collide_room.h"
|
#include "Game/collision/collide_room.h"
|
||||||
|
#include "Game/collision/Sphere.h"
|
||||||
#include "Game/effects/tomb4fx.h"
|
#include "Game/effects/tomb4fx.h"
|
||||||
#include "Game/effects/debris.h"
|
#include "Game/effects/debris.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
|
@ -18,6 +19,7 @@
|
||||||
#include "Sound/sound.h"
|
#include "Sound/sound.h"
|
||||||
#include "Specific/Input/Input.h"
|
#include "Specific/Input/Input.h"
|
||||||
|
|
||||||
|
using namespace TEN::Collision::Sphere;
|
||||||
using namespace TEN::Math;
|
using namespace TEN::Math;
|
||||||
using TEN::Renderer::g_Renderer;
|
using TEN::Renderer::g_Renderer;
|
||||||
|
|
||||||
|
@ -308,7 +310,7 @@ bool GetTargetOnLOS(GameVector* origin, GameVector* target, bool drawTarget, boo
|
||||||
{
|
{
|
||||||
item->MeshBits &= ~ShatterItem.bit;
|
item->MeshBits &= ~ShatterItem.bit;
|
||||||
ShatterImpactData.impactDirection = dir;
|
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);
|
ShatterObject(&ShatterItem, 0, 128, target2.RoomNumber, 0);
|
||||||
TriggerRicochetSpark(target2, LaraItem->Pose.Orientation.y, 3, 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];
|
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);
|
auto ray = Ray(origin->ToVector3(), dir);
|
||||||
float bestDistance = INFINITY;
|
float bestDistance = INFINITY;
|
||||||
int bestJointIndex = NO_VALUE;
|
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 dist = 0.0f;
|
||||||
float distance = 0.0f;
|
if (ray.Intersects(spheres[i], dist))
|
||||||
if (ray.Intersects(sphere, distance))
|
|
||||||
{
|
{
|
||||||
if (distance < bestDistance)
|
if (dist < bestDistance)
|
||||||
{
|
{
|
||||||
bestDistance = distance;
|
bestDistance = dist;
|
||||||
bestJointIndex = i;
|
bestJointIndex = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -500,27 +501,23 @@ static bool DoRayBox(const GameVector& origin, const GameVector& target, const G
|
||||||
auto* item = &g_Level.Items[closestItemNumber];
|
auto* item = &g_Level.Items[closestItemNumber];
|
||||||
auto* object = &Objects[item->ObjectNumber];
|
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)
|
if (object->nmeshes <= 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
meshIndex = object->meshIndex;
|
meshIndex = object->meshIndex;
|
||||||
|
|
||||||
|
auto spheres = item->GetSpheres();
|
||||||
for (int i = 0; i < object->nmeshes; i++)
|
for (int i = 0; i < object->nmeshes; i++)
|
||||||
{
|
{
|
||||||
// If mesh is visible.
|
// If mesh is visible.
|
||||||
if (item->MeshBits & (1 << i))
|
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
|
// 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
|
// 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.
|
// but after more testing we should trash it in the future and restore the new way.
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// Create the bounding sphere and test it against the ray
|
// Create the bounding sphere and test it against the ray
|
||||||
BoundingSphere sph = BoundingSphere(Vector3(sphere->x, sphere->y, sphere->z), sphere->r);
|
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].x = target.x;
|
||||||
p[2].y = target.y;
|
p[2].y = target.y;
|
||||||
p[2].z = target.z;
|
p[2].z = target.z;
|
||||||
p[3].x = sphere->x;
|
p[3].x = sphere.Center.x;
|
||||||
p[3].y = sphere->y;
|
p[3].y = sphere.Center.y;
|
||||||
p[3].z = sphere->z;
|
p[3].z = sphere.Center.z;
|
||||||
|
|
||||||
int r0 = (p[3].x - p[1].x) * (p[2].x - p[1].x) +
|
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) +
|
(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;
|
int distance = dx + dy + dz;
|
||||||
|
|
||||||
if (distance < SQUARE(sphere->r))
|
if (distance < SQUARE(sphere.Radius))
|
||||||
{
|
{
|
||||||
dx = SQUARE(sphere->x - origin.x);
|
dx = SQUARE(sphere.Center.x - origin.x);
|
||||||
dy = SQUARE(sphere->y - origin.y);
|
dy = SQUARE(sphere.Center.y - origin.y);
|
||||||
dz = SQUARE(sphere->z - origin.z);
|
dz = SQUARE(sphere.Center.z - origin.z);
|
||||||
|
|
||||||
distance = dx + dy + dz;
|
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];
|
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.yRot = item->Pose.Orientation.y;
|
||||||
ShatterItem.meshIndex = meshIndex;
|
ShatterItem.meshIndex = meshIndex;
|
||||||
ShatterItem.color = item->Model.Color;
|
ShatterItem.color = item->Model.Color;
|
||||||
ShatterItem.sphere.x = CreatureSpheres[sp].x;
|
ShatterItem.sphere.Center = spheres[sp].Center;
|
||||||
ShatterItem.sphere.y = CreatureSpheres[sp].y;
|
|
||||||
ShatterItem.sphere.z = CreatureSpheres[sp].z;
|
|
||||||
ShatterItem.bit = bit;
|
ShatterItem.bit = bit;
|
||||||
ShatterItem.flags = 0;
|
ShatterItem.flags = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,15 @@
|
||||||
#include "Game/effects/debris.h"
|
#include "Game/effects/debris.h"
|
||||||
|
|
||||||
#include "Game/collision/collide_room.h"
|
#include "Game/collision/collide_room.h"
|
||||||
|
#include "Game/collision/Sphere.h"
|
||||||
#include "Game/effects/tomb4fx.h"
|
#include "Game/effects/tomb4fx.h"
|
||||||
#include "Game/Setup.h"
|
#include "Game/Setup.h"
|
||||||
#include "Specific/level.h"
|
#include "Specific/level.h"
|
||||||
#include "Math/Random.h"
|
|
||||||
#include "Math/Math.h"
|
#include "Math/Math.h"
|
||||||
|
|
||||||
|
using namespace TEN::Collision::Sphere;
|
||||||
|
using namespace TEN::Math;
|
||||||
using namespace TEN::Renderer;
|
using namespace TEN::Renderer;
|
||||||
using namespace TEN::Math::Random;
|
|
||||||
|
|
||||||
ShatterImpactInfo ShatterImpactData;
|
ShatterImpactInfo ShatterImpactData;
|
||||||
SHATTER_ITEM ShatterItem;
|
SHATTER_ITEM ShatterItem;
|
||||||
|
@ -26,17 +27,15 @@ bool ExplodeItemNode(ItemInfo* item, int node, int noXZVel, int bits)
|
||||||
if (number == BODY_DO_EXPLOSION)
|
if (number == BODY_DO_EXPLOSION)
|
||||||
number = -64;
|
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.yRot = item->Pose.Orientation.y;
|
||||||
ShatterItem.bit = 1 << node;
|
ShatterItem.bit = 1 << node;
|
||||||
ShatterItem.meshIndex = Objects[item->ObjectNumber].meshIndex + node;
|
ShatterItem.meshIndex = Objects[item->ObjectNumber].meshIndex + node;
|
||||||
ShatterItem.sphere.x = CreatureSpheres[node].x;
|
ShatterItem.sphere.Center = spheres[node].Center;
|
||||||
ShatterItem.sphere.y = CreatureSpheres[node].y;
|
|
||||||
ShatterItem.sphere.z = CreatureSpheres[node].z;
|
|
||||||
ShatterItem.color = item->Model.Color;
|
ShatterItem.color = item->Model.Color;
|
||||||
ShatterItem.flags = item->ObjectNumber == ID_CROSSBOW_BOLT ? 0x400 : 0;
|
ShatterItem.flags = item->ObjectNumber == ID_CROSSBOW_BOLT ? 0x400 : 0;
|
||||||
ShatterImpactData.impactDirection = Vector3(0, -1, 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);
|
ShatterObject(&ShatterItem, NULL, number, item->RoomNumber, noXZVel);
|
||||||
item->MeshBits &= ~ShatterItem.bit;
|
item->MeshBits &= ~ShatterItem.bit;
|
||||||
|
|
||||||
|
@ -88,7 +87,7 @@ void ShatterObject(SHATTER_ITEM* item, MESH_INFO* mesh, int num, short roomNumbe
|
||||||
isStatic = false;
|
isStatic = false;
|
||||||
meshIndex = item->meshIndex;
|
meshIndex = item->meshIndex;
|
||||||
yRot = item->yRot;
|
yRot = item->yRot;
|
||||||
pos = Vector3(item->sphere.x, item->sphere.y, item->sphere.z);
|
pos = item->sphere.Center;
|
||||||
scale = 1.0f;
|
scale = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,8 +176,8 @@ void ShatterObject(SHATTER_ITEM* item, MESH_INFO* mesh, int num, short roomNumbe
|
||||||
fragment->restitution = 0.6f;
|
fragment->restitution = 0.6f;
|
||||||
fragment->friction = 0.6f;
|
fragment->friction = 0.6f;
|
||||||
fragment->linearDrag = .99f;
|
fragment->linearDrag = .99f;
|
||||||
fragment->angularVelocity = Vector3(GenerateFloat(-1, 1) * 0.39, GenerateFloat(-1, 1) * 0.39, GenerateFloat(-1, 1) * 0.39);
|
fragment->angularVelocity = Vector3(Random::GenerateFloat(-1, 1) * 0.39, Random::GenerateFloat(-1, 1) * 0.39, Random::GenerateFloat(-1, 1) * 0.39);
|
||||||
fragment->angularDrag = GenerateFloat(0.9f, 0.999f);
|
fragment->angularDrag = Random::GenerateFloat(0.9f, 0.999f);
|
||||||
fragment->velocity = CalculateFragmentImpactVelocity(fragment->worldPosition, ShatterImpactData.impactDirection, ShatterImpactData.impactLocation);
|
fragment->velocity = CalculateFragmentImpactVelocity(fragment->worldPosition, ShatterImpactData.impactDirection, ShatterImpactData.impactLocation);
|
||||||
fragment->roomNumber = roomNumber;
|
fragment->roomNumber = roomNumber;
|
||||||
fragment->numBounces = 0;
|
fragment->numBounces = 0;
|
||||||
|
@ -196,10 +195,10 @@ Vector3 CalculateFragmentImpactVelocity(const Vector3& fragmentWorldPosition, co
|
||||||
radiusNormVec.Normalize();
|
radiusNormVec.Normalize();
|
||||||
float radiusStrenght = 1-((fragmentWorldPosition - impactLocation).Length() / 1024);
|
float radiusStrenght = 1-((fragmentWorldPosition - impactLocation).Length() / 1024);
|
||||||
radiusStrenght = fmax(radiusStrenght, 0);
|
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();
|
radiusRandomVector.Normalize();
|
||||||
Vector3 radiusVelocity = radiusRandomVector * radiusStrenght*40;
|
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;
|
return radiusVelocity + impactDirectionVelocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
#pragma once
|
#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/Graphics/Vertices/Vertex.h"
|
||||||
|
#include "Renderer/Renderer.h"
|
||||||
|
#include "Specific/level.h"
|
||||||
|
#include "Specific/newtypes.h"
|
||||||
|
|
||||||
constexpr int MAX_DEBRIS = 2048;
|
constexpr int MAX_DEBRIS = 2048;
|
||||||
|
|
||||||
|
@ -26,7 +25,7 @@ struct ITEM_LIGHT
|
||||||
|
|
||||||
struct SHATTER_ITEM
|
struct SHATTER_ITEM
|
||||||
{
|
{
|
||||||
SPHERE sphere;
|
BoundingSphere sphere;
|
||||||
ITEM_LIGHT* il;
|
ITEM_LIGHT* il;
|
||||||
int meshIndex;
|
int meshIndex;
|
||||||
Vector4 color;
|
Vector4 color;
|
||||||
|
|
|
@ -130,9 +130,8 @@ namespace TEN::Effects::Drip
|
||||||
// Spawn ripple on surface only.
|
// Spawn ripple on surface only.
|
||||||
if (!TestEnvironment(ENV_FLAG_WATER, prevRoomNumber))
|
if (!TestEnvironment(ENV_FLAG_WATER, prevRoomNumber))
|
||||||
{
|
{
|
||||||
float waterHeight = GetWaterHeight(drip.Position.x, drip.Position.y, drip.Position.z, drip.RoomNumber);
|
|
||||||
SpawnRipple(
|
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(),
|
pointColl.GetRoomNumber(),
|
||||||
Random::GenerateFloat(RIPPLE_SIZE_WATER_MIN, RIPPLE_SIZE_WATER_MAX),
|
Random::GenerateFloat(RIPPLE_SIZE_WATER_MIN, RIPPLE_SIZE_WATER_MAX),
|
||||||
(int)RippleFlags::SlowFade | (int)RippleFlags::LowOpacity);
|
(int)RippleFlags::SlowFade | (int)RippleFlags::LowOpacity);
|
||||||
|
|
|
@ -1308,7 +1308,7 @@ void Splash(ItemInfo* item)
|
||||||
if (!TestEnvironment(ENV_FLAG_WATER, probedRoomNumber))
|
if (!TestEnvironment(ENV_FLAG_WATER, probedRoomNumber))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int waterHeight = GetWaterHeight(item);
|
int waterHeight = GetPointCollision(*item).GetWaterTopHeight();
|
||||||
|
|
||||||
SplashSetup.x = item->Pose.Position.x;
|
SplashSetup.x = item->Pose.Position.x;
|
||||||
SplashSetup.y = waterHeight - 1;
|
SplashSetup.y = waterHeight - 1;
|
||||||
|
@ -1940,7 +1940,7 @@ void ProcessEffects(ItemInfo* item)
|
||||||
if (item->Effect.Type != EffectType::Sparks && item->Effect.Type != EffectType::Smoke)
|
if (item->Effect.Type != EffectType::Sparks && item->Effect.Type != EffectType::Smoke)
|
||||||
{
|
{
|
||||||
const auto& bounds = GameBoundingBox(item);
|
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);
|
int itemLevel = item->Pose.Position.y + bounds.Y2 - (bounds.GetHeight() / 3);
|
||||||
|
|
||||||
if (waterHeight != NO_HEIGHT && itemLevel > waterHeight)
|
if (waterHeight != NO_HEIGHT && itemLevel > waterHeight)
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/collision/collide_room.h"
|
#include "Game/collision/collide_room.h"
|
||||||
#include "Game/collision/Point.h"
|
#include "Game/collision/Point.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/control/control.h"
|
#include "Game/control/control.h"
|
||||||
#include "Game/effects/weather.h"
|
#include "Game/effects/weather.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
|
@ -23,7 +22,7 @@ namespace TEN::Effects::Hair
|
||||||
{
|
{
|
||||||
HairEffectController HairEffect = {};
|
HairEffectController HairEffect = {};
|
||||||
|
|
||||||
void HairUnit::Update(const ItemInfo& item, int hairUnitIndex)
|
void HairUnit::Update(const ItemInfo& item, int hairUnitID)
|
||||||
{
|
{
|
||||||
const auto& player = GetLaraInfo(item);
|
const auto& player = GetLaraInfo(item);
|
||||||
|
|
||||||
|
@ -34,15 +33,14 @@ namespace TEN::Effects::Hair
|
||||||
g_Renderer.GetBoneMatrix(item.Index, LM_HEAD, &worldMatrix);
|
g_Renderer.GetBoneMatrix(item.Index, LM_HEAD, &worldMatrix);
|
||||||
|
|
||||||
// Apply base offset to world matrix.
|
// Apply base offset to world matrix.
|
||||||
auto relOffset = GetRelBaseOffset(hairUnitIndex, isYoung);
|
auto relOffset = GetRelBaseOffset(hairUnitID, isYoung);
|
||||||
worldMatrix = Matrix::CreateTranslation(relOffset) * worldMatrix;
|
worldMatrix = Matrix::CreateTranslation(relOffset) * worldMatrix;
|
||||||
|
|
||||||
// Use player's head bone orientation as base.
|
// 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.
|
// Set position of base segment.
|
||||||
auto basePos = worldMatrix.Translation();
|
Segments[0].Position = worldMatrix.Translation();
|
||||||
Segments[0].Position = basePos;
|
|
||||||
|
|
||||||
if (!IsInitialized)
|
if (!IsInitialized)
|
||||||
{
|
{
|
||||||
|
@ -53,7 +51,7 @@ namespace TEN::Effects::Hair
|
||||||
auto& nextSegment = Segments[i + 1];
|
auto& nextSegment = Segments[i + 1];
|
||||||
|
|
||||||
// NOTE: Joint offset determines segment length.
|
// NOTE: Joint offset determines segment length.
|
||||||
auto jointOffset = GetJointOffset(ID_HAIR, i);
|
auto jointOffset = GetJointOffset(ObjectID, i);
|
||||||
|
|
||||||
worldMatrix = Matrix::CreateTranslation(segment.Position);
|
worldMatrix = Matrix::CreateTranslation(segment.Position);
|
||||||
worldMatrix = Matrix::CreateFromQuaternion(segment.Orientation) * worldMatrix;
|
worldMatrix = Matrix::CreateFromQuaternion(segment.Orientation) * worldMatrix;
|
||||||
|
@ -69,7 +67,7 @@ namespace TEN::Effects::Hair
|
||||||
// Get water height.
|
// Get water height.
|
||||||
auto pos = item.Pose.Position + Vector3i(GetWaterProbeOffset(item));
|
auto pos = item.Pose.Position + Vector3i(GetWaterProbeOffset(item));
|
||||||
int roomNumber = item.RoomNumber;
|
int roomNumber = item.RoomNumber;
|
||||||
int waterHeight = GetWaterHeight(pos.x, pos.y, pos.z, roomNumber);
|
int waterHeight = GetPointCollision(pos, roomNumber).GetWaterTopHeight();
|
||||||
|
|
||||||
// Get collision spheres.
|
// Get collision spheres.
|
||||||
auto spheres = GetSpheres(item, isYoung);
|
auto spheres = GetSpheres(item, isYoung);
|
||||||
|
@ -83,12 +81,10 @@ namespace TEN::Effects::Hair
|
||||||
// TR3 UPV uses a hack which forces player water status to dry.
|
// TR3 UPV uses a hack which forces player water status to dry.
|
||||||
// Therefore, cannot directly use water status value to determine enrironment.
|
// Therefore, cannot directly use water status value to determine enrironment.
|
||||||
bool isOnLand = (player.Control.WaterStatus == WaterStatus::Dry &&
|
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.
|
// Handle segment collision.
|
||||||
CollideSegmentWithRoom(segment, waterHeight, roomNumber, isOnLand);
|
CollideSegmentWithRoom(segment, waterHeight, roomNumber, isOnLand);
|
||||||
|
|
||||||
// Handle segment sphere collision.
|
|
||||||
CollideSegmentWithSpheres(segment, spheres);
|
CollideSegmentWithSpheres(segment, spheres);
|
||||||
|
|
||||||
// Calculate orientation.
|
// Calculate orientation.
|
||||||
|
@ -99,8 +95,8 @@ namespace TEN::Effects::Hair
|
||||||
worldMatrix = Matrix::CreateFromQuaternion(prevSegment.Orientation) * worldMatrix;
|
worldMatrix = Matrix::CreateFromQuaternion(prevSegment.Orientation) * worldMatrix;
|
||||||
|
|
||||||
auto jointOffset = (i == (Segments.size() - 1)) ?
|
auto jointOffset = (i == (Segments.size() - 1)) ?
|
||||||
GetJointOffset(ID_HAIR, (i - 1) - 1) :
|
GetJointOffset(ObjectID, (i - 1) - 1) :
|
||||||
GetJointOffset(ID_HAIR, (i - 1));
|
GetJointOffset(ObjectID, (i - 1));
|
||||||
worldMatrix = Matrix::CreateTranslation(jointOffset) * worldMatrix;
|
worldMatrix = Matrix::CreateTranslation(jointOffset) * worldMatrix;
|
||||||
|
|
||||||
segment.Position = worldMatrix.Translation();
|
segment.Position = worldMatrix.Translation();
|
||||||
|
@ -109,21 +105,21 @@ namespace TEN::Effects::Hair
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 HairUnit::GetRelBaseOffset(int hairUnitIndex, bool isYoung)
|
Vector3 HairUnit::GetRelBaseOffset(int hairUnitID, bool isYoung)
|
||||||
{
|
{
|
||||||
auto relOffset = Vector3::Zero;
|
auto relOffset = Vector3::Zero;
|
||||||
if (isYoung)
|
if (isYoung)
|
||||||
{
|
{
|
||||||
switch (hairUnitIndex)
|
switch (hairUnitID)
|
||||||
{
|
{
|
||||||
// Left pigtail offset.
|
// Left pigtail offset.
|
||||||
case 0:
|
case 0:
|
||||||
relOffset = Vector3(-52.0f, -48.0f, -50.0f);
|
relOffset = Vector3(-48.0f, -48.0f, -50.0f);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Right pigtail offset.
|
// Right pigtail offset.
|
||||||
case 1:
|
case 1:
|
||||||
relOffset = Vector3(44.0f, -48.0f, -50.0f);
|
relOffset = Vector3(48.0f, -48.0f, -50.0f);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -175,13 +171,13 @@ namespace TEN::Effects::Hair
|
||||||
Quaternion HairUnit::GetSegmentOrientation(const Vector3& origin, const Vector3& target, const Quaternion& baseOrient)
|
Quaternion HairUnit::GetSegmentOrientation(const Vector3& origin, const Vector3& target, const Quaternion& baseOrient)
|
||||||
{
|
{
|
||||||
// Calculate absolute orientation.
|
// Calculate absolute orientation.
|
||||||
auto absDirection = target - origin;
|
auto absDir = target - origin;
|
||||||
absDirection.Normalize();
|
absDir.Normalize();
|
||||||
auto absOrient = Geometry::ConvertDirectionToQuat(absDirection);
|
auto absOrient = Geometry::ConvertDirectionToQuat(absDir);
|
||||||
|
|
||||||
// Calculate relative twist rotation.
|
// Calculate relative twist rotation.
|
||||||
// TODO: Find accurate twist angle based on relation between absOrient and baseOrient.
|
// 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();
|
auto twistRot = twistAxisAngle.ToQuaternion();
|
||||||
|
|
||||||
// Return ideal orientation.
|
// Return ideal orientation.
|
||||||
|
@ -198,21 +194,21 @@ namespace TEN::Effects::Hair
|
||||||
spheres.reserve(SPHERE_COUNT);
|
spheres.reserve(SPHERE_COUNT);
|
||||||
|
|
||||||
// Hips sphere.
|
// Hips sphere.
|
||||||
auto* meshPtr = &g_Level.Meshes[item.Model.MeshIndex[LM_HIPS]];
|
const auto* mesh = &g_Level.Meshes[item.Model.MeshIndex[LM_HIPS]];
|
||||||
auto pos = GetJointPosition(item, LM_HIPS, Vector3i(meshPtr->sphere.Center)).ToVector3();
|
auto pos = GetJointPosition(item, LM_HIPS, Vector3i(mesh->sphere.Center)).ToVector3();
|
||||||
spheres.push_back(BoundingSphere(pos, meshPtr->sphere.Radius));
|
spheres.push_back(BoundingSphere(pos, mesh->sphere.Radius));
|
||||||
|
|
||||||
// Torso sphere.
|
// Torso sphere.
|
||||||
meshPtr = &g_Level.Meshes[item.Model.MeshIndex[LM_TORSO]];
|
mesh = &g_Level.Meshes[item.Model.MeshIndex[LM_TORSO]];
|
||||||
pos = GetJointPosition(item, LM_TORSO, Vector3i(meshPtr->sphere.Center) + TORSO_SPHERE_OFFSET).ToVector3();
|
pos = GetJointPosition(item, LM_TORSO, Vector3i(mesh->sphere.Center) + TORSO_SPHERE_OFFSET).ToVector3();
|
||||||
spheres.push_back(BoundingSphere(pos, meshPtr->sphere.Radius));
|
spheres.push_back(BoundingSphere(pos, mesh->sphere.Radius));
|
||||||
if (isYoung)
|
if (isYoung)
|
||||||
spheres.back().Radius = spheres.back().Radius - ((spheres.back().Radius / 4) + (spheres.back().Radius / 8));
|
spheres.back().Radius = spheres.back().Radius - ((spheres.back().Radius / 4) + (spheres.back().Radius / 8));
|
||||||
|
|
||||||
// Head sphere.
|
// Head sphere.
|
||||||
meshPtr = &g_Level.Meshes[item.Model.MeshIndex[LM_HEAD]];
|
mesh = &g_Level.Meshes[item.Model.MeshIndex[LM_HEAD]];
|
||||||
pos = GetJointPosition(item, LM_HEAD, Vector3i(meshPtr->sphere.Center) + HEAD_SPHERE_OFFSET).ToVector3();
|
pos = GetJointPosition(item, LM_HEAD, Vector3i(mesh->sphere.Center) + HEAD_SPHERE_OFFSET).ToVector3();
|
||||||
spheres.push_back(BoundingSphere(pos, meshPtr->sphere.Radius));
|
spheres.push_back(BoundingSphere(pos, mesh->sphere.Radius));
|
||||||
|
|
||||||
// Neck sphere.
|
// Neck sphere.
|
||||||
spheres.push_back(BoundingSphere(
|
spheres.push_back(BoundingSphere(
|
||||||
|
@ -220,30 +216,30 @@ namespace TEN::Effects::Hair
|
||||||
isYoung ? 0.0f : (spheres[2].Radius * 0.75f)));
|
isYoung ? 0.0f : (spheres[2].Radius * 0.75f)));
|
||||||
|
|
||||||
// Left arm sphere.
|
// Left arm sphere.
|
||||||
meshPtr = &g_Level.Meshes[item.Model.MeshIndex[LM_LINARM]];
|
mesh = &g_Level.Meshes[item.Model.MeshIndex[LM_LINARM]];
|
||||||
pos = GetJointPosition(item, LM_LINARM, Vector3i(meshPtr->sphere.Center)).ToVector3();
|
pos = GetJointPosition(item, LM_LINARM, Vector3i(mesh->sphere.Center)).ToVector3();
|
||||||
spheres.push_back(BoundingSphere(pos, (meshPtr->sphere.Radius / 3) * 4));
|
spheres.push_back(BoundingSphere(pos, (mesh->sphere.Radius / 3) * 4));
|
||||||
|
|
||||||
// Right arm sphere.
|
// Right arm sphere.
|
||||||
meshPtr = &g_Level.Meshes[item.Model.MeshIndex[LM_RINARM]];
|
mesh = &g_Level.Meshes[item.Model.MeshIndex[LM_RINARM]];
|
||||||
pos = GetJointPosition(item, LM_RINARM, Vector3i(meshPtr->sphere.Center)).ToVector3();
|
pos = GetJointPosition(item, LM_RINARM, Vector3i(mesh->sphere.Center)).ToVector3();
|
||||||
spheres.push_back(BoundingSphere(pos, (meshPtr->sphere.Radius / 3) * 4));
|
spheres.push_back(BoundingSphere(pos, (mesh->sphere.Radius / 3) * 4));
|
||||||
|
|
||||||
// Left holster sphere.
|
// Left holster sphere.
|
||||||
meshPtr = &g_Level.Meshes[item.Model.MeshIndex[LM_LTHIGH]];
|
mesh = &g_Level.Meshes[item.Model.MeshIndex[LM_LTHIGH]];
|
||||||
pos = GetJointPosition(item, LM_LTHIGH, Vector3i(meshPtr->sphere.Center)).ToVector3();
|
pos = GetJointPosition(item, LM_LTHIGH, Vector3i(mesh->sphere.Center)).ToVector3();
|
||||||
spheres.push_back(
|
spheres.push_back(
|
||||||
BoundingSphere(
|
BoundingSphere(
|
||||||
pos + ((spheres[0].Center - pos) / 2),
|
pos + ((spheres[0].Center - pos) / 2),
|
||||||
meshPtr->sphere.Radius));
|
mesh->sphere.Radius));
|
||||||
|
|
||||||
// Right holster sphere.
|
// Right holster sphere.
|
||||||
meshPtr = &g_Level.Meshes[item.Model.MeshIndex[LM_RTHIGH]];
|
mesh = &g_Level.Meshes[item.Model.MeshIndex[LM_RTHIGH]];
|
||||||
pos = GetJointPosition(item, LM_RTHIGH, Vector3i(meshPtr->sphere.Center)).ToVector3();
|
pos = GetJointPosition(item, LM_RTHIGH, Vector3i(mesh->sphere.Center)).ToVector3();
|
||||||
spheres.push_back(
|
spheres.push_back(
|
||||||
BoundingSphere(
|
BoundingSphere(
|
||||||
pos + ((spheres[0].Center - pos) / 2),
|
pos + ((spheres[0].Center - pos) / 2),
|
||||||
meshPtr->sphere.Radius));
|
mesh->sphere.Radius));
|
||||||
|
|
||||||
if (isYoung)
|
if (isYoung)
|
||||||
spheres[1].Center = (spheres[1].Center + spheres[2].Center) / 2;
|
spheres[1].Center = (spheres[1].Center + spheres[2].Center) / 2;
|
||||||
|
@ -253,13 +249,12 @@ namespace TEN::Effects::Hair
|
||||||
|
|
||||||
void HairUnit::CollideSegmentWithRoom(HairSegment& segment, int waterHeight, int roomNumber, bool isOnLand)
|
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);
|
auto pointColl = GetPointCollision(segment.Position, roomNumber);
|
||||||
int floorHeight = pointColl.GetFloorHeight();
|
|
||||||
|
|
||||||
Segments[0].Velocity = segment.Position;
|
Segments[0].Velocity = segment.Position;
|
||||||
segment.Position += segment.Velocity * VELOCITY_COEFF;
|
segment.Position += segment.Velocity * VEL_COEFF;
|
||||||
|
|
||||||
// Land collision.
|
// Land collision.
|
||||||
if (isOnLand)
|
if (isOnLand)
|
||||||
|
@ -277,7 +272,7 @@ namespace TEN::Effects::Hair
|
||||||
segment.Position.y = waterHeight;
|
segment.Position.y = waterHeight;
|
||||||
}
|
}
|
||||||
// Avoid clipping through floor.
|
// 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;
|
segment.Position = Segments[0].Velocity;
|
||||||
}
|
}
|
||||||
|
@ -289,9 +284,9 @@ namespace TEN::Effects::Hair
|
||||||
{
|
{
|
||||||
segment.Position.y = waterHeight;
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -300,57 +295,59 @@ namespace TEN::Effects::Hair
|
||||||
{
|
{
|
||||||
for (const auto& sphere : spheres)
|
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);
|
float dist = Vector3::Distance(segment.Position, sphere.Center);
|
||||||
if (distance < sphere.Radius)
|
if (dist < sphere.Radius)
|
||||||
{
|
{
|
||||||
// Avoid division by zero.
|
// Avoid division by zero.
|
||||||
if (distance == 0.0f)
|
if (dist == 0.0f)
|
||||||
distance = 1.0f;
|
dist = 1.0f;
|
||||||
|
|
||||||
// Push segment away from sphere.
|
// Push segment away from sphere.
|
||||||
segment.Position = sphere.Center + (direction * (sphere.Radius / distance));
|
segment.Position = sphere.Center + (dir * (sphere.Radius / dist));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HairEffectController::Initialize()
|
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);
|
bool isYoung = (g_GameFlow->GetLevel(CurrentLevel)->GetLaraType() == LaraType::Young);
|
||||||
|
|
||||||
// Initialize hair units.
|
// Initialize hair units.
|
||||||
bool isHead = true;
|
for (int i = 0; i < Units.size(); i++)
|
||||||
for (auto& unit : Units)
|
|
||||||
{
|
{
|
||||||
unit.IsEnabled = (!isHead || isYoung);
|
auto& unit = Units[i];
|
||||||
unit.IsInitialized = false;
|
|
||||||
|
|
||||||
unsigned int segmentCount = Objects[ID_HAIR].nmeshes + 1;
|
auto objectID = (i == 0) ? ID_SINGLE_BRAID_HAIR : ID_DUAL_PIGTAIL_HAIR;
|
||||||
unit.Segments.resize(segmentCount);
|
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.
|
// Initialize segments.
|
||||||
for (auto& segment : unit.Segments)
|
for (auto& segment : unit.Segments)
|
||||||
{
|
{
|
||||||
segment.Position = GetJointOffset(ID_HAIR, 0);
|
segment.Position = GetJointOffset(objectID, 0);
|
||||||
segment.Velocity = Vector3::Zero;
|
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++)
|
for (int i = 0; i < Units.size(); i++)
|
||||||
{
|
{
|
||||||
Units[i].Update(item, i);
|
auto& unit = Units[i];
|
||||||
|
if (!unit.IsEnabled)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (isYoung && i == 1)
|
unit.Update(item, i);
|
||||||
Units[i].Update(item, i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Objects/game_object_ids.h"
|
||||||
|
|
||||||
struct ItemInfo;
|
struct ItemInfo;
|
||||||
|
|
||||||
namespace TEN::Effects::Hair
|
namespace TEN::Effects::Hair
|
||||||
|
@ -8,6 +10,7 @@ namespace TEN::Effects::Hair
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// Constants
|
// Constants
|
||||||
|
|
||||||
static constexpr auto HAIR_GRAVITY = 10.0f;
|
static constexpr auto HAIR_GRAVITY = 10.0f;
|
||||||
|
|
||||||
struct HairSegment
|
struct HairSegment
|
||||||
|
@ -19,16 +22,21 @@ namespace TEN::Effects::Hair
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Members
|
// Members
|
||||||
|
|
||||||
bool IsEnabled = false;
|
bool IsEnabled = false;
|
||||||
bool IsInitialized = false;
|
bool IsInitialized = false;
|
||||||
|
|
||||||
|
GAME_OBJECT_ID ObjectID = GAME_OBJECT_ID::ID_NO_OBJECT;
|
||||||
std::vector<HairSegment> Segments = {};
|
std::vector<HairSegment> Segments = {};
|
||||||
|
|
||||||
// Utilities
|
// Utilities
|
||||||
void Update(const ItemInfo& item, int hairUnitIndex);
|
|
||||||
|
void Update(const ItemInfo& item, int hairUnitID);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Helpers
|
// Helpers
|
||||||
Vector3 GetRelBaseOffset(int hairUnitIndex, bool isYoung);
|
|
||||||
|
Vector3 GetRelBaseOffset(int hairUnitID, bool isYoung);
|
||||||
Vector3 GetWaterProbeOffset(const ItemInfo& item);
|
Vector3 GetWaterProbeOffset(const ItemInfo& item);
|
||||||
Quaternion GetSegmentOrientation(const Vector3& origin, const Vector3& target, const Quaternion& baseOrient);
|
Quaternion GetSegmentOrientation(const Vector3& origin, const Vector3& target, const Quaternion& baseOrient);
|
||||||
std::vector<BoundingSphere> GetSpheres(const ItemInfo& item, bool isYoung);
|
std::vector<BoundingSphere> GetSpheres(const ItemInfo& item, bool isYoung);
|
||||||
|
@ -41,15 +49,18 @@ namespace TEN::Effects::Hair
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// Constants
|
// Constants
|
||||||
|
|
||||||
static constexpr auto UNIT_COUNT_MAX = 2;
|
static constexpr auto UNIT_COUNT_MAX = 2;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Members
|
// Members
|
||||||
|
|
||||||
std::array<HairUnit, UNIT_COUNT_MAX> Units = {};
|
std::array<HairUnit, UNIT_COUNT_MAX> Units = {};
|
||||||
|
|
||||||
// Utilities
|
// Utilities
|
||||||
|
|
||||||
void Initialize();
|
void Initialize();
|
||||||
void Update(ItemInfo& item, bool isYoung);
|
void Update(ItemInfo& item);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern HairEffectController HairEffect;
|
extern HairEffectController HairEffect;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/collision/collide_room.h"
|
#include "Game/collision/collide_room.h"
|
||||||
#include "Game/collision/floordata.h"
|
#include "Game/collision/floordata.h"
|
||||||
|
#include "Game/collision/Point.h"
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/effects/Bubble.h"
|
#include "Game/effects/Bubble.h"
|
||||||
#include "Game/effects/debris.h"
|
#include "Game/effects/debris.h"
|
||||||
|
@ -27,6 +28,7 @@ using namespace TEN::Effects::Environment;
|
||||||
using namespace TEN::Effects::Ripple;
|
using namespace TEN::Effects::Ripple;
|
||||||
using namespace TEN::Effects::Smoke;
|
using namespace TEN::Effects::Smoke;
|
||||||
using namespace TEN::Collision::Floordata;
|
using namespace TEN::Collision::Floordata;
|
||||||
|
using namespace TEN::Collision::Point;
|
||||||
using namespace TEN::Math;
|
using namespace TEN::Math;
|
||||||
using TEN::Renderer::g_Renderer;
|
using TEN::Renderer::g_Renderer;
|
||||||
|
|
||||||
|
@ -1117,7 +1119,7 @@ void TriggerUnderwaterExplosion(ItemInfo* item, int flag)
|
||||||
TriggerExplosionBubbles(x, y, z, item->RoomNumber);
|
TriggerExplosionBubbles(x, y, z, item->RoomNumber);
|
||||||
TriggerExplosionSparks(x, y, z, 2, -1, 1, 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)
|
if (waterHeight != NO_HEIGHT)
|
||||||
SomeSparkEffect(x, waterHeight, z, 8);
|
SomeSparkEffect(x, waterHeight, z, 8);
|
||||||
}
|
}
|
||||||
|
@ -1129,7 +1131,7 @@ void TriggerUnderwaterExplosion(ItemInfo* item, int flag)
|
||||||
for (int i = 0; i < 3; i++)
|
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);
|
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)
|
if (waterHeight != NO_HEIGHT)
|
||||||
{
|
{
|
||||||
int dy = item->Pose.Position.y - waterHeight;
|
int dy = item->Pose.Position.y - waterHeight;
|
||||||
|
|
|
@ -1503,7 +1503,7 @@ namespace TEN::Gui
|
||||||
|
|
||||||
void GuiController::ConstructObjectList(ItemInfo* item)
|
void GuiController::ConstructObjectList(ItemInfo* item)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
Rings[(int)RingTypes::Inventory].NumObjectsInList = 0;
|
Rings[(int)RingTypes::Inventory].NumObjectsInList = 0;
|
||||||
|
|
||||||
|
@ -1519,19 +1519,19 @@ namespace TEN::Gui
|
||||||
|
|
||||||
if (g_GameFlow->GetLevel(CurrentLevel)->GetLaraType() != LaraType::Young)
|
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);
|
InsertObjectIntoList(INV_OBJECT_PISTOLS);
|
||||||
else if (Ammo.AmountPistolsAmmo)
|
else if (Ammo.AmountPistolsAmmo)
|
||||||
InsertObjectIntoList(INV_OBJECT_PISTOLS_AMMO);
|
InsertObjectIntoList(INV_OBJECT_PISTOLS_AMMO);
|
||||||
|
|
||||||
if (lara->Weapons[(int)LaraWeaponType::Uzi].Present)
|
if (player.Weapons[(int)LaraWeaponType::Uzi].Present)
|
||||||
InsertObjectIntoList(INV_OBJECT_UZIS);
|
InsertObjectIntoList(INV_OBJECT_UZIS);
|
||||||
else if (Ammo.AmountUziAmmo)
|
else if (Ammo.AmountUziAmmo)
|
||||||
InsertObjectIntoList(INV_OBJECT_UZI_AMMO);
|
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);
|
InsertObjectIntoList(INV_OBJECT_REVOLVER_LASER);
|
||||||
else
|
else
|
||||||
InsertObjectIntoList(INV_OBJECT_REVOLVER);
|
InsertObjectIntoList(INV_OBJECT_REVOLVER);
|
||||||
|
@ -1539,11 +1539,11 @@ namespace TEN::Gui
|
||||||
else if (Ammo.AmountRevolverAmmo)
|
else if (Ammo.AmountRevolverAmmo)
|
||||||
InsertObjectIntoList(INV_OBJECT_REVOLVER_AMMO);
|
InsertObjectIntoList(INV_OBJECT_REVOLVER_AMMO);
|
||||||
|
|
||||||
if (lara->Weapons[(int)LaraWeaponType::Shotgun].Present)
|
if (player.Weapons[(int)LaraWeaponType::Shotgun].Present)
|
||||||
{
|
{
|
||||||
InsertObjectIntoList(INV_OBJECT_SHOTGUN);
|
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;
|
Ammo.CurrentShotGunAmmoType = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1555,33 +1555,33 @@ namespace TEN::Gui
|
||||||
InsertObjectIntoList(INV_OBJECT_SHOTGUN_AMMO_2);
|
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);
|
InsertObjectIntoList(INV_OBJECT_HK_LASERSIGHT);
|
||||||
else
|
else
|
||||||
InsertObjectIntoList(INV_OBJECT_HK);
|
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;
|
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;
|
Ammo.CurrentHKAmmoType = 2;
|
||||||
}
|
}
|
||||||
else if (Ammo.AmountHKAmmo1)
|
else if (Ammo.AmountHKAmmo1)
|
||||||
InsertObjectIntoList(INV_OBJECT_HK_AMMO);
|
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);
|
InsertObjectIntoList(INV_OBJECT_CROSSBOW_LASER);
|
||||||
else
|
else
|
||||||
InsertObjectIntoList(INV_OBJECT_CROSSBOW);
|
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;
|
Ammo.CurrentCrossBowAmmoType = 1;
|
||||||
|
|
||||||
if (lara->Weapons[(int)LaraWeaponType::Crossbow].SelectedAmmo == WeaponAmmoType::Ammo3)
|
if (player.Weapons[(int)LaraWeaponType::Crossbow].SelectedAmmo == WeaponAmmoType::Ammo3)
|
||||||
Ammo.CurrentCrossBowAmmoType = 2;
|
Ammo.CurrentCrossBowAmmoType = 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1596,14 +1596,14 @@ namespace TEN::Gui
|
||||||
InsertObjectIntoList(INV_OBJECT_CROSSBOW_AMMO_3);
|
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);
|
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;
|
Ammo.CurrentGrenadeGunAmmoType = 1;
|
||||||
|
|
||||||
if (lara->Weapons[(int)LaraWeaponType::GrenadeLauncher].SelectedAmmo == WeaponAmmoType::Ammo3)
|
if (player.Weapons[(int)LaraWeaponType::GrenadeLauncher].SelectedAmmo == WeaponAmmoType::Ammo3)
|
||||||
Ammo.CurrentGrenadeGunAmmoType = 2;
|
Ammo.CurrentGrenadeGunAmmoType = 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1618,107 +1618,107 @@ namespace TEN::Gui
|
||||||
InsertObjectIntoList(INV_OBJECT_GRENADE_AMMO_3);
|
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);
|
InsertObjectIntoList(INV_OBJECT_ROCKET_LAUNCHER);
|
||||||
else if (Ammo.AmountRocketsAmmo)
|
else if (Ammo.AmountRocketsAmmo)
|
||||||
InsertObjectIntoList(INV_OBJECT_ROCKET_AMMO);
|
InsertObjectIntoList(INV_OBJECT_ROCKET_AMMO);
|
||||||
|
|
||||||
if (lara->Weapons[(int)LaraWeaponType::HarpoonGun].Present)
|
if (player.Weapons[(int)LaraWeaponType::HarpoonGun].Present)
|
||||||
InsertObjectIntoList(INV_OBJECT_HARPOON_GUN);
|
InsertObjectIntoList(INV_OBJECT_HARPOON_GUN);
|
||||||
else if (Ammo.AmountHarpoonAmmo)
|
else if (Ammo.AmountHarpoonAmmo)
|
||||||
InsertObjectIntoList(INV_OBJECT_HARPOON_AMMO);
|
InsertObjectIntoList(INV_OBJECT_HARPOON_AMMO);
|
||||||
|
|
||||||
if (lara->Inventory.HasLasersight)
|
if (player.Inventory.HasLasersight)
|
||||||
InsertObjectIntoList(INV_OBJECT_LASERSIGHT);
|
InsertObjectIntoList(INV_OBJECT_LASERSIGHT);
|
||||||
|
|
||||||
if (lara->Inventory.HasSilencer)
|
if (player.Inventory.HasSilencer)
|
||||||
InsertObjectIntoList(INV_OBJECT_SILENCER);
|
InsertObjectIntoList(INV_OBJECT_SILENCER);
|
||||||
|
|
||||||
if (lara->Inventory.HasBinoculars)
|
if (player.Inventory.HasBinoculars)
|
||||||
InsertObjectIntoList(INV_OBJECT_BINOCULARS);
|
InsertObjectIntoList(INV_OBJECT_BINOCULARS);
|
||||||
|
|
||||||
if (lara->Inventory.TotalFlares)
|
if (player.Inventory.TotalFlares)
|
||||||
InsertObjectIntoList(INV_OBJECT_FLARES);
|
InsertObjectIntoList(INV_OBJECT_FLARES);
|
||||||
}
|
}
|
||||||
|
|
||||||
InsertObjectIntoList(INV_OBJECT_TIMEX);//every level has the timex? what's a good way to check?!
|
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);
|
InsertObjectIntoList(INV_OBJECT_SMALL_MEDIPACK);
|
||||||
|
|
||||||
if (lara->Inventory.TotalLargeMedipacks)
|
if (player.Inventory.TotalLargeMedipacks)
|
||||||
InsertObjectIntoList(INV_OBJECT_LARGE_MEDIPACK);
|
InsertObjectIntoList(INV_OBJECT_LARGE_MEDIPACK);
|
||||||
|
|
||||||
if (lara->Inventory.HasCrowbar)
|
if (player.Inventory.HasCrowbar)
|
||||||
InsertObjectIntoList(INV_OBJECT_CROWBAR);
|
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);
|
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);
|
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);
|
InsertObjectIntoList(INV_OBJECT_BEETLE_PART2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lara->Inventory.SmallWaterskin)
|
if (player.Inventory.SmallWaterskin)
|
||||||
InsertObjectIntoList((lara->Inventory.SmallWaterskin - 1) + INV_OBJECT_SMALL_WATERSKIN_EMPTY);
|
InsertObjectIntoList((player.Inventory.SmallWaterskin - 1) + INV_OBJECT_SMALL_WATERSKIN_EMPTY);
|
||||||
|
|
||||||
if (lara->Inventory.BigWaterskin)
|
if (player.Inventory.BigWaterskin)
|
||||||
InsertObjectIntoList((lara->Inventory.BigWaterskin - 1) + INV_OBJECT_BIG_WATERSKIN_EMPTY);
|
InsertObjectIntoList((player.Inventory.BigWaterskin - 1) + INV_OBJECT_BIG_WATERSKIN_EMPTY);
|
||||||
|
|
||||||
for (int i = 0; i < NUM_PUZZLES; i++)
|
for (int i = 0; i < NUM_PUZZLES; i++)
|
||||||
{
|
{
|
||||||
if (lara->Inventory.Puzzles[i])
|
if (player.Inventory.Puzzles[i])
|
||||||
InsertObjectIntoList(INV_OBJECT_PUZZLE1 + i);
|
InsertObjectIntoList(INV_OBJECT_PUZZLE1 + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < NUM_PUZZLE_PIECES; 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);
|
InsertObjectIntoList(INV_OBJECT_PUZZLE1_COMBO1 + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < NUM_KEYS; i++)
|
for (int i = 0; i < NUM_KEYS; i++)
|
||||||
{
|
{
|
||||||
if (lara->Inventory.Keys[i])
|
if (player.Inventory.Keys[i])
|
||||||
InsertObjectIntoList(INV_OBJECT_KEY1 + i);
|
InsertObjectIntoList(INV_OBJECT_KEY1 + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < NUM_KEY_PIECES; 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);
|
InsertObjectIntoList(INV_OBJECT_KEY1_COMBO1 + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < NUM_PICKUPS; i++)
|
for (int i = 0; i < NUM_PICKUPS; i++)
|
||||||
{
|
{
|
||||||
if (lara->Inventory.Pickups[i])
|
if (player.Inventory.Pickups[i])
|
||||||
InsertObjectIntoList(INV_OBJECT_PICKUP1 + i);
|
InsertObjectIntoList(INV_OBJECT_PICKUP1 + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < NUM_PICKUPS_PIECES; 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);
|
InsertObjectIntoList(INV_OBJECT_PICKUP1_COMBO1 + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < NUM_EXAMINES; i++)
|
for (int i = 0; i < NUM_EXAMINES; i++)
|
||||||
{
|
{
|
||||||
if (lara->Inventory.Examines[i])
|
if (player.Inventory.Examines[i])
|
||||||
InsertObjectIntoList(INV_OBJECT_EXAMINE1 + i);
|
InsertObjectIntoList(INV_OBJECT_EXAMINE1 + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < NUM_EXAMINES_PIECES; 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);
|
InsertObjectIntoList(INV_OBJECT_EXAMINE1_COMBO1 + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lara->Inventory.Diary.Present)
|
if (player.Inventory.Diary.Present)
|
||||||
InsertObjectIntoList(INV_OBJECT_DIARY);
|
InsertObjectIntoList(INV_OBJECT_DIARY);
|
||||||
|
|
||||||
if (g_GameFlow->IsLoadSaveEnabled())
|
if (g_GameFlow->IsLoadSaveEnabled())
|
||||||
|
@ -1739,7 +1739,7 @@ namespace TEN::Gui
|
||||||
|
|
||||||
void GuiController::ConstructCombineObjectList(ItemInfo* item)
|
void GuiController::ConstructCombineObjectList(ItemInfo* item)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
Rings[(int)RingTypes::Ammo].NumObjectsInList = 0;
|
Rings[(int)RingTypes::Ammo].NumObjectsInList = 0;
|
||||||
|
|
||||||
|
@ -1748,73 +1748,73 @@ namespace TEN::Gui
|
||||||
|
|
||||||
if (!(g_GameFlow->GetLevel(CurrentLevel)->GetLaraType() == LaraType::Young))
|
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);
|
InsertObjectIntoList_v2(INV_OBJECT_REVOLVER_LASER);
|
||||||
else
|
else
|
||||||
InsertObjectIntoList_v2(INV_OBJECT_REVOLVER);
|
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);
|
InsertObjectIntoList_v2(INV_OBJECT_HK_LASERSIGHT);
|
||||||
else
|
else
|
||||||
InsertObjectIntoList_v2(INV_OBJECT_HK);
|
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);
|
InsertObjectIntoList_v2(INV_OBJECT_CROSSBOW_LASER);
|
||||||
else
|
else
|
||||||
InsertObjectIntoList_v2(INV_OBJECT_CROSSBOW);
|
InsertObjectIntoList_v2(INV_OBJECT_CROSSBOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lara->Inventory.HasLasersight)
|
if (player.Inventory.HasLasersight)
|
||||||
InsertObjectIntoList_v2(INV_OBJECT_LASERSIGHT);
|
InsertObjectIntoList_v2(INV_OBJECT_LASERSIGHT);
|
||||||
|
|
||||||
if (lara->Inventory.HasSilencer)
|
if (player.Inventory.HasSilencer)
|
||||||
InsertObjectIntoList_v2(INV_OBJECT_SILENCER);
|
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);
|
InsertObjectIntoList_v2(INV_OBJECT_BEETLE_PART1);
|
||||||
|
|
||||||
if (lara->Inventory.BeetleComponents & 4)
|
if (player.Inventory.BeetleComponents & 4)
|
||||||
InsertObjectIntoList_v2(INV_OBJECT_BEETLE_PART2);
|
InsertObjectIntoList_v2(INV_OBJECT_BEETLE_PART2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lara->Inventory.SmallWaterskin)
|
if (player.Inventory.SmallWaterskin)
|
||||||
InsertObjectIntoList_v2(lara->Inventory.SmallWaterskin - 1 + INV_OBJECT_SMALL_WATERSKIN_EMPTY);
|
InsertObjectIntoList_v2(player.Inventory.SmallWaterskin - 1 + INV_OBJECT_SMALL_WATERSKIN_EMPTY);
|
||||||
|
|
||||||
if (lara->Inventory.BigWaterskin)
|
if (player.Inventory.BigWaterskin)
|
||||||
InsertObjectIntoList_v2(lara->Inventory.BigWaterskin - 1 + INV_OBJECT_BIG_WATERSKIN_EMPTY);
|
InsertObjectIntoList_v2(player.Inventory.BigWaterskin - 1 + INV_OBJECT_BIG_WATERSKIN_EMPTY);
|
||||||
|
|
||||||
for (int i = 0; i < NUM_PUZZLE_PIECES; i++)
|
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);
|
InsertObjectIntoList_v2(INV_OBJECT_PUZZLE1_COMBO1 + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < NUM_KEY_PIECES; 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);
|
InsertObjectIntoList_v2(INV_OBJECT_KEY1_COMBO1 + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < NUM_PICKUPS_PIECES; 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);
|
InsertObjectIntoList_v2(INV_OBJECT_PICKUP1_COMBO1 + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < NUM_EXAMINES_PIECES; 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);
|
InsertObjectIntoList_v2(INV_OBJECT_EXAMINE1_COMBO1 + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1832,45 +1832,45 @@ namespace TEN::Gui
|
||||||
|
|
||||||
void GuiController::InitializeInventory(ItemInfo* item)
|
void GuiController::InitializeInventory(ItemInfo* item)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
AlterFOV(ANGLE(DEFAULT_FOV), false);
|
AlterFOV(ANGLE(DEFAULT_FOV), false);
|
||||||
lara->Inventory.IsBusy = false;
|
player.Inventory.IsBusy = false;
|
||||||
InventoryItemChosen = NO_VALUE;
|
InventoryItemChosen = NO_VALUE;
|
||||||
ItemUsed = false;
|
ItemUsed = false;
|
||||||
|
|
||||||
if (lara->Weapons[(int)LaraWeaponType::Shotgun].Ammo[0].HasInfinite())
|
if (player.Weapons[(int)LaraWeaponType::Shotgun].Ammo[0].HasInfinite())
|
||||||
{
|
{
|
||||||
Ammo.AmountShotGunAmmo1 = -1;
|
Ammo.AmountShotGunAmmo1 = -1;
|
||||||
}
|
}
|
||||||
else
|
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;
|
Ammo.AmountShotGunAmmo2 = -1;
|
||||||
}
|
}
|
||||||
else
|
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.AmountShotGunAmmo1 = player.Weapons[(int)LaraWeaponType::Shotgun].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : player.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.AmountShotGunAmmo2 = player.Weapons[(int)LaraWeaponType::Shotgun].Ammo[(int)WeaponAmmoType::Ammo2].HasInfinite() ? -1 : player.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.AmountHKAmmo1 = player.Weapons[(int)LaraWeaponType::HK].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : player.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.AmountCrossBowAmmo1 = player.Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : player.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.AmountCrossBowAmmo2 = player.Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo2].HasInfinite() ? -1 : player.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.AmountCrossBowAmmo3 = player.Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo3].HasInfinite() ? -1 : player.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.AmountUziAmmo = player.Weapons[(int)LaraWeaponType::Uzi].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : player.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.AmountRevolverAmmo = player.Weapons[(int)LaraWeaponType::Revolver].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : player.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.AmountPistolsAmmo = player.Weapons[(int)LaraWeaponType::Pistol].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : player.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.AmountRocketsAmmo = player.Weapons[(int)LaraWeaponType::RocketLauncher].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : player.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.AmountHarpoonAmmo = player.Weapons[(int)LaraWeaponType::HarpoonGun].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite()? -1 : player.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.AmountGrenadeAmmo1 = player.Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : player.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.AmountGrenadeAmmo2 = player.Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo2].HasInfinite() ? -1 : player.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.AmountGrenadeAmmo3 = player.Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo3].HasInfinite() ? -1 : player.Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo3].GetCount();
|
||||||
ConstructObjectList(item);
|
ConstructObjectList(item);
|
||||||
|
|
||||||
if (EnterInventory == NO_VALUE)
|
if (EnterInventory == NO_VALUE)
|
||||||
|
@ -2243,7 +2243,7 @@ namespace TEN::Gui
|
||||||
|
|
||||||
void GuiController::DoInventory(ItemInfo* item)
|
void GuiController::DoInventory(ItemInfo* item)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
auto& invRing = Rings[(int)RingTypes::Inventory];
|
auto& invRing = Rings[(int)RingTypes::Inventory];
|
||||||
auto& ammoRing = Rings[(int)RingTypes::Ammo];
|
auto& ammoRing = Rings[(int)RingTypes::Ammo];
|
||||||
|
|
||||||
|
@ -2546,7 +2546,7 @@ namespace TEN::Gui
|
||||||
|
|
||||||
case MenuType::Diary:
|
case MenuType::Diary:
|
||||||
SetInventoryMode(InventoryMode::Diary);
|
SetInventoryMode(InventoryMode::Diary);
|
||||||
lara->Inventory.Diary.CurrentPage = 1;
|
player.Inventory.Diary.CurrentPage = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2574,51 +2574,51 @@ namespace TEN::Gui
|
||||||
// Update the selected ammo of weapons that require it, and only these.
|
// Update the selected ammo of weapons that require it, and only these.
|
||||||
void GuiController::UpdateWeaponStatus(ItemInfo* item)
|
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)
|
if (Ammo.CurrentShotGunAmmoType)
|
||||||
lara->Weapons[(int)LaraWeaponType::Shotgun].SelectedAmmo = WeaponAmmoType::Ammo2;
|
player.Weapons[(int)LaraWeaponType::Shotgun].SelectedAmmo = WeaponAmmoType::Ammo2;
|
||||||
else
|
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)
|
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)
|
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;
|
player.Weapons[(int)LaraWeaponType::HK].WeaponMode = LaraWeaponTypeCarried::WTYPE_AMMO_1;
|
||||||
lara->Weapons[(int)LaraWeaponType::HK].SelectedAmmo = WeaponAmmoType::Ammo1;
|
player.Weapons[(int)LaraWeaponType::HK].SelectedAmmo = WeaponAmmoType::Ammo1;
|
||||||
|
|
||||||
if (Ammo.CurrentHKAmmoType == 1)
|
if (Ammo.CurrentHKAmmoType == 1)
|
||||||
{
|
{
|
||||||
lara->Weapons[(int)LaraWeaponType::HK].WeaponMode = LaraWeaponTypeCarried::WTYPE_AMMO_2;
|
player.Weapons[(int)LaraWeaponType::HK].WeaponMode = LaraWeaponTypeCarried::WTYPE_AMMO_2;
|
||||||
lara->Weapons[(int)LaraWeaponType::HK].SelectedAmmo = WeaponAmmoType::Ammo1;
|
player.Weapons[(int)LaraWeaponType::HK].SelectedAmmo = WeaponAmmoType::Ammo1;
|
||||||
}
|
}
|
||||||
else if (Ammo.CurrentHKAmmoType == 2)
|
else if (Ammo.CurrentHKAmmoType == 2)
|
||||||
{
|
{
|
||||||
lara->Weapons[(int)LaraWeaponType::HK].WeaponMode = LaraWeaponTypeCarried::WTYPE_AMMO_3;
|
player.Weapons[(int)LaraWeaponType::HK].WeaponMode = LaraWeaponTypeCarried::WTYPE_AMMO_3;
|
||||||
lara->Weapons[(int)LaraWeaponType::HK].SelectedAmmo = WeaponAmmoType::Ammo1;
|
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)
|
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)
|
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)
|
bool GuiController::CallInventory(ItemInfo* item, bool resetMode)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
bool doLoad = false;
|
bool doLoad = false;
|
||||||
|
|
||||||
lara->Inventory.OldBusy = lara->Inventory.IsBusy;
|
player.Inventory.OldBusy = player.Inventory.IsBusy;
|
||||||
|
|
||||||
g_Renderer.DumpGameScene();
|
g_Renderer.DumpGameScene();
|
||||||
PauseAllSounds(SoundPauseMode::Inventory);
|
PauseAllSounds(SoundPauseMode::Inventory);
|
||||||
|
@ -3286,7 +3286,7 @@ namespace TEN::Gui
|
||||||
AlterFOV(LastFOV);
|
AlterFOV(LastFOV);
|
||||||
ResumeAllSounds(SoundPauseMode::Inventory);
|
ResumeAllSounds(SoundPauseMode::Inventory);
|
||||||
|
|
||||||
lara->Inventory.IsBusy = lara->Inventory.OldBusy;
|
player.Inventory.IsBusy = player.Inventory.OldBusy;
|
||||||
SetInventoryMode(InventoryMode::None);
|
SetInventoryMode(InventoryMode::None);
|
||||||
|
|
||||||
return doLoad;
|
return doLoad;
|
||||||
|
@ -3341,21 +3341,21 @@ namespace TEN::Gui
|
||||||
|
|
||||||
void GuiController::DoDiary(ItemInfo* item)
|
void GuiController::DoDiary(ItemInfo* item)
|
||||||
{
|
{
|
||||||
auto* lara = GetLaraInfo(item);
|
auto& player = GetLaraInfo(*item);
|
||||||
|
|
||||||
SetInventoryMode(InventoryMode::Diary);
|
SetInventoryMode(InventoryMode::Diary);
|
||||||
|
|
||||||
if (GuiIsPulsed(In::Right) &&
|
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);
|
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GuiIsPulsed(In::Left) &&
|
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);
|
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3454,10 +3454,10 @@ namespace TEN::Gui
|
||||||
|
|
||||||
bool GuiController::PerformWaterskinCombine(ItemInfo* item, bool flag)
|
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 smallLiters = player.Inventory.SmallWaterskin - 1; // How many liters in the small one?
|
||||||
int bigLiters = lara->Inventory.BigWaterskin - 1; // How many liters in the big 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 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?
|
int bigCapacity = 5 - bigLiters; // How many more liters can fit in the big one?
|
||||||
|
|
||||||
|
@ -3465,7 +3465,7 @@ namespace TEN::Gui
|
||||||
if (flag)
|
if (flag)
|
||||||
{
|
{
|
||||||
// Big one isn't empty and the small one isn't full.
|
// 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;
|
i = bigLiters;
|
||||||
|
|
||||||
|
@ -3481,8 +3481,8 @@ namespace TEN::Gui
|
||||||
i--;
|
i--;
|
||||||
} while (i);
|
} while (i);
|
||||||
|
|
||||||
lara->Inventory.SmallWaterskin = smallLiters + 1;
|
player.Inventory.SmallWaterskin = smallLiters + 1;
|
||||||
lara->Inventory.BigWaterskin = bigLiters + 1;
|
player.Inventory.BigWaterskin = bigLiters + 1;
|
||||||
CombineObject1 = (smallLiters + 1) + (INV_OBJECT_SMALL_WATERSKIN_EMPTY - 1);
|
CombineObject1 = (smallLiters + 1) + (INV_OBJECT_SMALL_WATERSKIN_EMPTY - 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -3490,9 +3490,9 @@ namespace TEN::Gui
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Small one isn't empty and the big one isn't full.
|
// 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
|
do
|
||||||
{
|
{
|
||||||
|
@ -3506,8 +3506,8 @@ namespace TEN::Gui
|
||||||
i--;
|
i--;
|
||||||
} while (i);
|
} while (i);
|
||||||
|
|
||||||
lara->Inventory.SmallWaterskin = smallLiters + 1;
|
player.Inventory.SmallWaterskin = smallLiters + 1;
|
||||||
lara->Inventory.BigWaterskin = bigLiters + 1;
|
player.Inventory.BigWaterskin = bigLiters + 1;
|
||||||
CombineObject1 = (bigLiters + 1) + (INV_OBJECT_BIG_WATERSKIN_EMPTY - 1);
|
CombineObject1 = (bigLiters + 1) + (INV_OBJECT_BIG_WATERSKIN_EMPTY - 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "Objects/Generic/Object/BridgeObject.h"
|
#include "Objects/Generic/Object/BridgeObject.h"
|
||||||
#include "Objects/Generic/Object/Pushable/PushableInfo.h"
|
#include "Objects/Generic/Object/Pushable/PushableInfo.h"
|
||||||
#include "Objects/Generic/Object/Pushable/PushableObject.h"
|
#include "Objects/Generic/Object/Pushable/PushableObject.h"
|
||||||
|
#include "Renderer/Renderer.h"
|
||||||
#include "Scripting/Include/Objects/ScriptInterfaceObjectsHandler.h"
|
#include "Scripting/Include/Objects/ScriptInterfaceObjectsHandler.h"
|
||||||
#include "Scripting/Include/ScriptInterfaceGame.h"
|
#include "Scripting/Include/ScriptInterfaceGame.h"
|
||||||
#include "Scripting/Internal/TEN/Objects/ObjectIDs.h"
|
#include "Scripting/Internal/TEN/Objects/ObjectIDs.h"
|
||||||
|
@ -35,6 +36,7 @@ using namespace TEN::Entities::Generic;
|
||||||
using namespace TEN::Input;
|
using namespace TEN::Input;
|
||||||
using namespace TEN::Math;
|
using namespace TEN::Math;
|
||||||
using namespace TEN::Utils;
|
using namespace TEN::Utils;
|
||||||
|
using TEN::Renderer::g_Renderer;
|
||||||
|
|
||||||
constexpr auto ITEM_DEATH_TIMEOUT = 4 * FPS;
|
constexpr auto ITEM_DEATH_TIMEOUT = 4 * FPS;
|
||||||
|
|
||||||
|
@ -182,6 +184,11 @@ bool ItemInfo::IsBridge() const
|
||||||
return Contains(BRIDGE_OBJECT_IDS, ObjectNumber);
|
return Contains(BRIDGE_OBJECT_IDS, ObjectNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<BoundingSphere> ItemInfo::GetSpheres() const
|
||||||
|
{
|
||||||
|
return g_Renderer.GetSpheres(Index);
|
||||||
|
}
|
||||||
|
|
||||||
bool TestState(int refState, const std::vector<int>& stateList)
|
bool TestState(int refState, const std::vector<int>& stateList)
|
||||||
{
|
{
|
||||||
for (const auto& state : stateList)
|
for (const auto& state : stateList)
|
||||||
|
|
|
@ -150,11 +150,13 @@ struct ItemInfo
|
||||||
short CarriedItem = 0;
|
short CarriedItem = 0;
|
||||||
|
|
||||||
// OCB utilities
|
// OCB utilities
|
||||||
|
|
||||||
bool TestOcb(short ocbFlags) const;
|
bool TestOcb(short ocbFlags) const;
|
||||||
void RemoveOcb(short ocbFlags);
|
void RemoveOcb(short ocbFlags);
|
||||||
void ClearAllOcb();
|
void ClearAllOcb();
|
||||||
|
|
||||||
// ItemFlags utilities
|
// ItemFlags utilities
|
||||||
|
|
||||||
bool TestFlags(int id, short flags) const; // ItemFlags[id] & flags
|
bool TestFlags(int id, short flags) const; // ItemFlags[id] & flags
|
||||||
bool TestFlagField(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]
|
short GetFlagField(int id) const; // ItemFlags[id]
|
||||||
|
@ -162,6 +164,7 @@ struct ItemInfo
|
||||||
void ClearFlags(int id, short flags); // ItemFlags[id] &= ~flags
|
void ClearFlags(int id, short flags); // ItemFlags[id] &= ~flags
|
||||||
|
|
||||||
// Model utilities
|
// Model utilities
|
||||||
|
|
||||||
bool TestMeshSwapFlags(unsigned int flags);
|
bool TestMeshSwapFlags(unsigned int flags);
|
||||||
bool TestMeshSwapFlags(const std::vector<unsigned int>& flags);
|
bool TestMeshSwapFlags(const std::vector<unsigned int>& flags);
|
||||||
void SetMeshSwapFlags(unsigned int flags, bool clear = false);
|
void SetMeshSwapFlags(unsigned int flags, bool clear = false);
|
||||||
|
@ -169,9 +172,14 @@ struct ItemInfo
|
||||||
void ResetModelToDefault();
|
void ResetModelToDefault();
|
||||||
|
|
||||||
// Inquirers
|
// Inquirers
|
||||||
|
|
||||||
bool IsLara() const;
|
bool IsLara() const;
|
||||||
bool IsCreature() const;
|
bool IsCreature() const;
|
||||||
bool IsBridge() const;
|
bool IsBridge() const;
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
|
||||||
|
std::vector<BoundingSphere> GetSpheres() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool TestState(int refState, const std::vector<int>& stateList);
|
bool TestState(int refState, const std::vector<int>& stateList);
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/control/los.h"
|
#include "Game/control/los.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/effects/debris.h"
|
#include "Game/effects/debris.h"
|
||||||
#include "Game/itemdata/creature_info.h"
|
#include "Game/itemdata/creature_info.h"
|
||||||
|
|
|
@ -121,9 +121,7 @@ namespace TEN::Entities::Effects
|
||||||
ShatterItem.yRot = fx->pos.Orientation.y;
|
ShatterItem.yRot = fx->pos.Orientation.y;
|
||||||
ShatterItem.meshIndex = fx->frameNumber;
|
ShatterItem.meshIndex = fx->frameNumber;
|
||||||
ShatterItem.color = Vector4::One;
|
ShatterItem.color = Vector4::One;
|
||||||
ShatterItem.sphere.x = fx->pos.Position.x;
|
ShatterItem.sphere.Center = fx->pos.Position.ToVector3();
|
||||||
ShatterItem.sphere.y = fx->pos.Position.y;
|
|
||||||
ShatterItem.sphere.z = fx->pos.Position.z;
|
|
||||||
ShatterItem.bit = 0;
|
ShatterItem.bit = 0;
|
||||||
ShatterItem.flags = fx->flag2 & 0x400;
|
ShatterItem.flags = fx->flag2 & 0x400;
|
||||||
ShatterObject(&ShatterItem, 0, param2, fx->roomNumber, param1);
|
ShatterObject(&ShatterItem, 0, param2, fx->roomNumber, param1);
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include "Game/collision/collide_item.h"
|
#include "Game/collision/collide_item.h"
|
||||||
#include "Game/collision/collide_room.h"
|
#include "Game/collision/collide_room.h"
|
||||||
#include "Game/collision/Point.h"
|
#include "Game/collision/Point.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/effects/Electricity.h"
|
#include "Game/effects/Electricity.h"
|
||||||
#include "Game/effects/item_fx.h"
|
#include "Game/effects/item_fx.h"
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/collision/collide_item.h"
|
#include "Game/collision/collide_item.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/effects/tomb4fx.h"
|
#include "Game/effects/tomb4fx.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
#include "Game/Lara/lara.h"
|
#include "Game/Lara/lara.h"
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include "Game/collision/collide_item.h"
|
#include "Game/collision/collide_item.h"
|
||||||
#include "Game/collision/collide_room.h"
|
#include "Game/collision/collide_room.h"
|
||||||
#include "Game/collision/Point.h"
|
#include "Game/collision/Point.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/control/control.h"
|
#include "Game/control/control.h"
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/effects/item_fx.h"
|
#include "Game/effects/item_fx.h"
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include "Game/pickup/pickup.h"
|
#include "Game/pickup/pickup.h"
|
||||||
#include "Sound/sound.h"
|
#include "Sound/sound.h"
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/Lara/lara.h"
|
#include "Game/Lara/lara.h"
|
||||||
#include "Game/Lara/lara_helpers.h"
|
#include "Game/Lara/lara_helpers.h"
|
||||||
#include "Game/Lara/lara_struct.h"
|
#include "Game/Lara/lara_struct.h"
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "Game/pickup/pickup.h"
|
#include "Game/pickup/pickup.h"
|
||||||
#include "Sound/sound.h"
|
#include "Sound/sound.h"
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/collision/sphere.h"
|
#include "Game/collision/Sphere.h"
|
||||||
#include "Objects/Generic/Switches/cog_switch.h"
|
#include "Objects/Generic/Switches/cog_switch.h"
|
||||||
#include "Objects/objectslist.h"
|
#include "Objects/objectslist.h"
|
||||||
#include "Game/Lara/lara.h"
|
#include "Game/Lara/lara.h"
|
||||||
|
@ -24,6 +24,7 @@
|
||||||
#include "Game/itemdata/itemdata.h"
|
#include "Game/itemdata/itemdata.h"
|
||||||
|
|
||||||
using namespace TEN::Collision::Room;
|
using namespace TEN::Collision::Room;
|
||||||
|
using namespace TEN::Collision::Sphere;
|
||||||
using namespace TEN::Gui;
|
using namespace TEN::Gui;
|
||||||
using namespace TEN::Input;
|
using namespace TEN::Input;
|
||||||
|
|
||||||
|
@ -247,7 +248,7 @@ namespace TEN::Entities::Doors
|
||||||
|
|
||||||
if (TestBoundsCollide(doorItem, laraItem, coll->Setup.Radius))
|
if (TestBoundsCollide(doorItem, laraItem, coll->Setup.Radius))
|
||||||
{
|
{
|
||||||
if (TestCollision(doorItem, laraItem))
|
if (HandleItemSphereCollision(*doorItem, *laraItem))
|
||||||
{
|
{
|
||||||
if (coll->Setup.EnableObjectPush)
|
if (coll->Setup.EnableObjectPush)
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include "Game/pickup/pickup.h"
|
#include "Game/pickup/pickup.h"
|
||||||
#include "Sound/sound.h"
|
#include "Sound/sound.h"
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/Lara/lara_helpers.h"
|
#include "Game/Lara/lara_helpers.h"
|
||||||
#include "Game/Lara/lara_struct.h"
|
#include "Game/Lara/lara_struct.h"
|
||||||
#include "Game/Lara/lara.h"
|
#include "Game/Lara/lara.h"
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include "Game/pickup/pickup.h"
|
#include "Game/pickup/pickup.h"
|
||||||
#include "Sound/sound.h"
|
#include "Sound/sound.h"
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/Lara/lara_struct.h"
|
#include "Game/Lara/lara_struct.h"
|
||||||
#include "Game/Lara/lara.h"
|
#include "Game/Lara/lara.h"
|
||||||
#include "Math/Math.h"
|
#include "Math/Math.h"
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "Game/pickup/pickup.h"
|
#include "Game/pickup/pickup.h"
|
||||||
#include "Sound/sound.h"
|
#include "Sound/sound.h"
|
||||||
#include "Game/animation.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_struct.h"
|
||||||
#include "Game/Lara/lara.h"
|
#include "Game/Lara/lara.h"
|
||||||
#include "Math/Math.h"
|
#include "Math/Math.h"
|
||||||
|
@ -19,6 +19,8 @@
|
||||||
#include "Game/collision/collide_room.h"
|
#include "Game/collision/collide_room.h"
|
||||||
#include "Game/collision/collide_item.h"
|
#include "Game/collision/collide_item.h"
|
||||||
|
|
||||||
|
using namespace TEN::Collision::Sphere;
|
||||||
|
|
||||||
namespace TEN::Entities::Doors
|
namespace TEN::Entities::Doors
|
||||||
{
|
{
|
||||||
void InitializeSteelDoor(short itemNumber)
|
void InitializeSteelDoor(short itemNumber)
|
||||||
|
@ -37,7 +39,7 @@ namespace TEN::Entities::Doors
|
||||||
{
|
{
|
||||||
if (TestBoundsCollide(doorItem, laraItem, coll->Setup.Radius))
|
if (TestBoundsCollide(doorItem, laraItem, coll->Setup.Radius))
|
||||||
{
|
{
|
||||||
if (TestCollision(doorItem, laraItem))
|
if (HandleItemSphereCollision(*doorItem, *laraItem))
|
||||||
{
|
{
|
||||||
if (coll->Setup.EnableObjectPush)
|
if (coll->Setup.EnableObjectPush)
|
||||||
ItemPushItem(doorItem, laraItem, coll, 0, 1);
|
ItemPushItem(doorItem, laraItem, coll, 0, 1);
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/collision/collide_item.h"
|
#include "Game/collision/collide_item.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/control/box.h"
|
#include "Game/control/box.h"
|
||||||
#include "Game/control/control.h"
|
#include "Game/control/control.h"
|
||||||
#include "Game/control/lot.h"
|
#include "Game/control/lot.h"
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/collision/collide_item.h"
|
#include "Game/collision/collide_item.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/control/control.h"
|
#include "Game/control/control.h"
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include "Objects/Generic/Object/polerope.h"
|
#include "Objects/Generic/Object/polerope.h"
|
||||||
|
|
||||||
#include "Game/collision/collide_item.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/box.h"
|
||||||
#include "Game/control/control.h"
|
#include "Game/control/control.h"
|
||||||
#include "Game/control/lot.h"
|
#include "Game/control/lot.h"
|
||||||
|
@ -15,6 +15,7 @@
|
||||||
#include "Specific/Input/Input.h"
|
#include "Specific/Input/Input.h"
|
||||||
#include "Specific/level.h"
|
#include "Specific/level.h"
|
||||||
|
|
||||||
|
using namespace TEN::Collision::Sphere;
|
||||||
using namespace TEN::Input;
|
using namespace TEN::Input;
|
||||||
using namespace TEN::Math;
|
using namespace TEN::Math;
|
||||||
|
|
||||||
|
@ -119,7 +120,7 @@ namespace TEN::Entities::Generic
|
||||||
// Test bounds collision.
|
// Test bounds collision.
|
||||||
if (TestBoundsCollide(&poleItem, laraItem, LARA_RADIUS + (int)round(abs(laraItem->Animation.Velocity.z))))
|
if (TestBoundsCollide(&poleItem, laraItem, LARA_RADIUS + (int)round(abs(laraItem->Animation.Velocity.z))))
|
||||||
{
|
{
|
||||||
if (TestCollision(&poleItem, laraItem))
|
if (HandleItemSphereCollision(poleItem, *laraItem))
|
||||||
{
|
{
|
||||||
// Temporarily reorient pole.
|
// Temporarily reorient pole.
|
||||||
short yOrient = poleItem.Pose.Orientation.y;
|
short yOrient = poleItem.Pose.Orientation.y;
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include "Game/Lara/lara.h"
|
#include "Game/Lara/lara.h"
|
||||||
#include "Math/Math.h"
|
#include "Math/Math.h"
|
||||||
#include "Game/collision/collide_room.h"
|
#include "Game/collision/collide_room.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Objects/Generic/Object/rope.h"
|
#include "Objects/Generic/Object/rope.h"
|
||||||
#include "Sound/sound.h"
|
#include "Sound/sound.h"
|
||||||
#include "Game/camera.h"
|
#include "Game/camera.h"
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/camera.h"
|
#include "Game/camera.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/control/lot.h"
|
#include "Game/control/lot.h"
|
||||||
#include "Game/effects/debris.h"
|
#include "Game/effects/debris.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
|
|
|
@ -152,12 +152,11 @@ namespace TEN::Entities::Generic
|
||||||
ShatterItem.yRot = item->Pose.Orientation.y;
|
ShatterItem.yRot = item->Pose.Orientation.y;
|
||||||
ShatterItem.meshIndex = Objects[item->ObjectNumber].meshIndex;
|
ShatterItem.meshIndex = Objects[item->ObjectNumber].meshIndex;
|
||||||
ShatterItem.color = item->Model.Color;
|
ShatterItem.color = item->Model.Color;
|
||||||
ShatterItem.sphere.x = item->Pose.Position.x;
|
ShatterItem.sphere.Center = item->Pose.Position.ToVector3();
|
||||||
ShatterItem.sphere.y = item->Pose.Position.y - CLICK(1); // So debris won't spawn below floor
|
ShatterItem.sphere.Center.y -= CLICK(1); // Prevent debris from spawning below floor.
|
||||||
ShatterItem.sphere.z = item->Pose.Position.z;
|
|
||||||
ShatterItem.bit = 0;
|
ShatterItem.bit = 0;
|
||||||
ShatterImpactData.impactDirection = Vector3(0, -(float)item->ItemFlags[1] / (float)FALLINGBLOCK_MAX_SPEED, 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);
|
ShatterObject(&ShatterItem, nullptr, 0, item->RoomNumber, false);
|
||||||
|
|
||||||
SoundEffect(SFX_TR4_ROCK_FALL_LAND, &item->Pose);
|
SoundEffect(SFX_TR4_ROCK_FALL_LAND, &item->Pose);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "Objects/TR1/Entity/tr1_big_rat.h"
|
#include "Objects/TR1/Entity/tr1_big_rat.h"
|
||||||
|
|
||||||
#include "Game/collision/collide_room.h"
|
#include "Game/collision/collide_room.h"
|
||||||
|
#include "Game/collision/Point.h"
|
||||||
#include "Game/control/box.h"
|
#include "Game/control/box.h"
|
||||||
#include "Game/control/control.h"
|
#include "Game/control/control.h"
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
|
@ -13,6 +14,7 @@
|
||||||
#include "Math/Math.h"
|
#include "Math/Math.h"
|
||||||
#include "Specific/level.h"
|
#include "Specific/level.h"
|
||||||
|
|
||||||
|
using namespace TEN::Collision::Point;
|
||||||
using namespace TEN::Math;
|
using namespace TEN::Math;
|
||||||
|
|
||||||
namespace TEN::Entities::Creatures::TR1
|
namespace TEN::Entities::Creatures::TR1
|
||||||
|
@ -83,8 +85,7 @@ namespace TEN::Entities::Creatures::TR1
|
||||||
|
|
||||||
bool RatOnWater(ItemInfo* item)
|
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())
|
if (item->IsCreature())
|
||||||
{
|
{
|
||||||
auto& creature = *GetCreatureInfo(item);
|
auto& creature = *GetCreatureInfo(item);
|
||||||
|
@ -240,7 +241,7 @@ namespace TEN::Entities::Creatures::TR1
|
||||||
if (RatOnWater(item))
|
if (RatOnWater(item))
|
||||||
{
|
{
|
||||||
CreatureUnderwater(item, 0);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#include "Game/camera.h"
|
#include "Game/camera.h"
|
||||||
#include "Game/collision/collide_item.h"
|
#include "Game/collision/collide_item.h"
|
||||||
#include "Game/collision/Point.h"
|
#include "Game/collision/Point.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/control/lot.h"
|
#include "Game/control/lot.h"
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/effects/tomb4fx.h"
|
#include "Game/effects/tomb4fx.h"
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
#include "Game/collision/collide_item.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/box.h"
|
||||||
#include "Game/control/lot.h"
|
#include "Game/control/lot.h"
|
||||||
#include "Game/effects/smoke.h"
|
#include "Game/effects/smoke.h"
|
||||||
|
@ -19,6 +19,7 @@
|
||||||
#include "Sound/sound.h"
|
#include "Sound/sound.h"
|
||||||
#include "Specific/level.h"
|
#include "Specific/level.h"
|
||||||
|
|
||||||
|
using namespace TEN::Collision::Sphere;
|
||||||
using namespace TEN::Effects::Smoke;
|
using namespace TEN::Effects::Smoke;
|
||||||
|
|
||||||
namespace TEN::Entities::Creatures::TR2
|
namespace TEN::Entities::Creatures::TR2
|
||||||
|
@ -96,7 +97,7 @@ namespace TEN::Entities::Creatures::TR2
|
||||||
if (!TestBoundsCollide(&item, laraItem, coll->Setup.Radius))
|
if (!TestBoundsCollide(&item, laraItem, coll->Setup.Radius))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!TestCollision(&item, laraItem))
|
if (!HandleItemSphereCollision(item, *laraItem))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (coll->Setup.EnableObjectPush)
|
if (coll->Setup.EnableObjectPush)
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include "Game/camera.h"
|
#include "Game/camera.h"
|
||||||
#include "Game/collision/collide_item.h"
|
#include "Game/collision/collide_item.h"
|
||||||
#include "Game/collision/Point.h"
|
#include "Game/collision/Point.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/effects/simple_particle.h"
|
#include "Game/effects/simple_particle.h"
|
||||||
#include "Game/effects/tomb4fx.h"
|
#include "Game/effects/tomb4fx.h"
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include "Game/camera.h"
|
#include "Game/camera.h"
|
||||||
#include "Game/collision/collide_item.h"
|
#include "Game/collision/collide_item.h"
|
||||||
#include "Game/collision/Point.h"
|
#include "Game/collision/Point.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/effects/simple_particle.h"
|
#include "Game/effects/simple_particle.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
|
@ -549,11 +548,11 @@ namespace TEN::Entities::Vehicles
|
||||||
SpeedboatDoShift(speedboatItem, &f, &frontOld);
|
SpeedboatDoShift(speedboatItem, &f, &frontOld);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto probe = GetPointCollision(*speedboatItem);
|
auto pointColl = GetPointCollision(*speedboatItem);
|
||||||
auto height = GetWaterHeight(speedboatItem->Pose.Position.x, speedboatItem->Pose.Position.y - 5, speedboatItem->Pose.Position.z, probe.GetRoomNumber());
|
auto height = GetPointCollision(Vector3i(speedboatItem->Pose.Position.x, speedboatItem->Pose.Position.y - 5, speedboatItem->Pose.Position.z), pointColl.GetRoomNumber()).GetWaterTopHeight();
|
||||||
|
|
||||||
if (height == NO_HEIGHT)
|
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)))
|
if (height < (speedboatItem->Pose.Position.y - CLICK(0.5f)))
|
||||||
SpeedboatDoShift(speedboatItem, (Vector3i*)&speedboatItem->Pose, &old);
|
SpeedboatDoShift(speedboatItem, (Vector3i*)&speedboatItem->Pose, &old);
|
||||||
|
@ -825,7 +824,7 @@ namespace TEN::Entities::Vehicles
|
||||||
TestTriggers(speedboatItem, false);
|
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;
|
speedboat->Water = water;
|
||||||
|
|
||||||
bool noTurn = true;
|
bool noTurn = true;
|
||||||
|
@ -968,7 +967,7 @@ namespace TEN::Entities::Vehicles
|
||||||
TEN::Effects::TriggerSpeedboatFoam(speedboatItem, Vector3(0.0f, 0.0f, SPEEDBOAT_BACK));
|
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);
|
SpawnVehicleWake(*speedboatItem, SPEEDBOAT_WAKE_OFFSET, waterHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,7 +221,6 @@ namespace TEN::Entities::Creatures::TR3
|
||||||
|
|
||||||
// Get point collision.
|
// Get point collision.
|
||||||
auto pointColl = GetPointCollision(pos, item.RoomNumber);
|
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.
|
// 1) Test for water room.
|
||||||
if (!TestEnvironment(ENV_FLAG_WATER, pointColl.GetRoomNumber()))
|
if (!TestEnvironment(ENV_FLAG_WATER, pointColl.GetRoomNumber()))
|
||||||
|
@ -229,7 +228,7 @@ namespace TEN::Entities::Creatures::TR3
|
||||||
|
|
||||||
// 2) Assess point collision.
|
// 2) Assess point collision.
|
||||||
if (pos.y >= (pointColl.GetFloorHeight() - BUFFER) ||
|
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) ||
|
||||||
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.
|
// 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))
|
if (fish.Position.y < (waterHeight + WATER_SURFACE_OFFSET))
|
||||||
fish.Position.y = waterHeight + WATER_SURFACE_OFFSET;
|
fish.Position.y = waterHeight + WATER_SURFACE_OFFSET;
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include "Game/collision/Point.h"
|
#include "Game/collision/Point.h"
|
||||||
#include "Game/control/box.h"
|
#include "Game/control/box.h"
|
||||||
#include "Game/control/lot.h"
|
#include "Game/control/lot.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/itemdata/creature_info.h"
|
#include "Game/itemdata/creature_info.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
|
|
|
@ -130,11 +130,11 @@ namespace TEN::Entities::Creatures::TR3
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AI_INFO AI;
|
AI_INFO ai;
|
||||||
CreatureAIInfo(item, &AI);
|
CreatureAIInfo(item, &ai);
|
||||||
|
|
||||||
GetCreatureMood(item, &AI, false);
|
GetCreatureMood(item, &ai, false);
|
||||||
CreatureMood(item, &AI, false);
|
CreatureMood(item, &ai, false);
|
||||||
|
|
||||||
bool shoot = false;
|
bool shoot = false;
|
||||||
if (Lara.Control.WaterStatus == WaterStatus::Dry)
|
if (Lara.Control.WaterStatus == WaterStatus::Dry)
|
||||||
|
@ -143,23 +143,21 @@ namespace TEN::Entities::Creatures::TR3
|
||||||
item->Pose.Position.x,
|
item->Pose.Position.x,
|
||||||
item->Pose.Position.y - CLICK(1),
|
item->Pose.Position.y - CLICK(1),
|
||||||
item->Pose.Position.z,
|
item->Pose.Position.z,
|
||||||
item->RoomNumber
|
item->RoomNumber);
|
||||||
);
|
|
||||||
auto target = GameVector(
|
auto target = GameVector(
|
||||||
LaraItem->Pose.Position.x,
|
LaraItem->Pose.Position.x,
|
||||||
LaraItem->Pose.Position.y - (LARA_HEIGHT - 150),
|
LaraItem->Pose.Position.y - (LARA_HEIGHT - 150),
|
||||||
LaraItem->Pose.Position.z
|
LaraItem->Pose.Position.z);
|
||||||
);
|
|
||||||
|
|
||||||
shoot = LOS(&origin, &target);
|
shoot = LOS(&origin, &target);
|
||||||
|
|
||||||
if (shoot)
|
if (shoot)
|
||||||
creature->Target = LaraItem->Pose.Position;
|
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;
|
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 origin = GameVector(item->Pose.Position, item->RoomNumber);
|
||||||
auto target = GameVector(LaraItem->Pose.Position);
|
auto target = GameVector(LaraItem->Pose.Position);
|
||||||
|
@ -168,7 +166,7 @@ namespace TEN::Entities::Creatures::TR3
|
||||||
}
|
}
|
||||||
|
|
||||||
angle = CreatureTurn(item, creature->MaxTurn);
|
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)
|
switch (item->Animation.ActiveState)
|
||||||
{
|
{
|
||||||
|
@ -176,7 +174,7 @@ namespace TEN::Entities::Creatures::TR3
|
||||||
creature->MaxTurn = SCUBA_DIVER_SWIM_TURN_RATE_MAX;
|
creature->MaxTurn = SCUBA_DIVER_SWIM_TURN_RATE_MAX;
|
||||||
|
|
||||||
if (shoot)
|
if (shoot)
|
||||||
neck = -AI.angle;
|
neck = -ai.angle;
|
||||||
|
|
||||||
if (creature->Target.y < waterHeight &&
|
if (creature->Target.y < waterHeight &&
|
||||||
item->Pose.Position.y < (waterHeight + creature->LOT.Fly))
|
item->Pose.Position.y < (waterHeight + creature->LOT.Fly))
|
||||||
|
@ -194,7 +192,7 @@ namespace TEN::Entities::Creatures::TR3
|
||||||
creature->Flags = 0;
|
creature->Flags = 0;
|
||||||
|
|
||||||
if (shoot)
|
if (shoot)
|
||||||
neck = -AI.angle;
|
neck = -ai.angle;
|
||||||
|
|
||||||
if (!shoot || creature->Mood == MoodType::Escape ||
|
if (!shoot || creature->Mood == MoodType::Escape ||
|
||||||
(creature->Target.y < waterHeight &&
|
(creature->Target.y < waterHeight &&
|
||||||
|
@ -209,7 +207,7 @@ namespace TEN::Entities::Creatures::TR3
|
||||||
|
|
||||||
case SDIVER_STATE_SWIM_SHOOT:
|
case SDIVER_STATE_SWIM_SHOOT:
|
||||||
if (shoot)
|
if (shoot)
|
||||||
neck = -AI.angle;
|
neck = -ai.angle;
|
||||||
|
|
||||||
if (!creature->Flags)
|
if (!creature->Flags)
|
||||||
{
|
{
|
||||||
|
@ -224,7 +222,7 @@ namespace TEN::Entities::Creatures::TR3
|
||||||
creature->MaxTurn = SCUBA_DIVER_SWIM_TURN_RATE_MAX;
|
creature->MaxTurn = SCUBA_DIVER_SWIM_TURN_RATE_MAX;
|
||||||
|
|
||||||
if (shoot)
|
if (shoot)
|
||||||
head = AI.angle;
|
head = ai.angle;
|
||||||
|
|
||||||
if (creature->Target.y > waterHeight)
|
if (creature->Target.y > waterHeight)
|
||||||
item->Animation.TargetState = SDIVER_STATE_SWIM;
|
item->Animation.TargetState = SDIVER_STATE_SWIM;
|
||||||
|
@ -239,7 +237,7 @@ namespace TEN::Entities::Creatures::TR3
|
||||||
creature->Flags = 0;
|
creature->Flags = 0;
|
||||||
|
|
||||||
if (shoot)
|
if (shoot)
|
||||||
head = AI.angle;
|
head = ai.angle;
|
||||||
|
|
||||||
if (!shoot || creature->Mood == MoodType::Escape || creature->Target.y > waterHeight)
|
if (!shoot || creature->Mood == MoodType::Escape || creature->Target.y > waterHeight)
|
||||||
item->Animation.TargetState = SDIVER_STATE_TREAD_WATER_IDLE;
|
item->Animation.TargetState = SDIVER_STATE_TREAD_WATER_IDLE;
|
||||||
|
@ -250,7 +248,7 @@ namespace TEN::Entities::Creatures::TR3
|
||||||
|
|
||||||
case SDIVER_STATE_TREAD_WATER_SHOOT:
|
case SDIVER_STATE_TREAD_WATER_SHOOT:
|
||||||
if (shoot)
|
if (shoot)
|
||||||
head = AI.angle;
|
head = ai.angle;
|
||||||
|
|
||||||
if (!creature->Flags)
|
if (!creature->Flags)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#include "Objects/TR3/Entity/tr3_tribesman.h"
|
#include "Objects/TR3/Entity/tr3_tribesman.h"
|
||||||
|
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/control/box.h"
|
#include "Game/control/box.h"
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/itemdata/creature_info.h"
|
#include "Game/itemdata/creature_info.h"
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include "Game/collision/collide_room.h"
|
#include "Game/collision/collide_room.h"
|
||||||
#include "Game/collision/Point.h"
|
#include "Game/collision/Point.h"
|
||||||
#include "Game/collision/floordata.h"
|
#include "Game/collision/floordata.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/effects/Ripple.h"
|
#include "Game/effects/Ripple.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
|
@ -74,27 +73,27 @@ namespace TEN::Entities::TR3
|
||||||
bool isWater = TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, item.RoomNumber);
|
bool isWater = TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, item.RoomNumber);
|
||||||
float verticalVelCoeff = isWater ? 81.0f : 1.0f;
|
float verticalVelCoeff = isWater ? 81.0f : 1.0f;
|
||||||
|
|
||||||
int roomNumber = GetPointCollision(item).GetRoomNumber();
|
auto pointColl = GetPointCollision(item);
|
||||||
if (item.RoomNumber != roomNumber)
|
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))
|
!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.y = waterHeight - 1;
|
||||||
SplashSetup.x = item.Pose.Position.x;
|
SplashSetup.x = item.Pose.Position.x;
|
||||||
SplashSetup.z = item.Pose.Position.z;
|
SplashSetup.z = item.Pose.Position.z;
|
||||||
SplashSetup.splashPower = item.Animation.Velocity.y * 4;
|
SplashSetup.splashPower = item.Animation.Velocity.y * 4;
|
||||||
SplashSetup.innerRadius = 160.0f;
|
SplashSetup.innerRadius = 160.0f;
|
||||||
|
|
||||||
SetupSplash(&SplashSetup, roomNumber);
|
SetupSplash(&SplashSetup, pointColl.GetRoomNumber());
|
||||||
item.Animation.Velocity.y = 0.0f;
|
item.Animation.Velocity.y = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemNewRoom(itemNumber, roomNumber);
|
ItemNewRoom(itemNumber, pointColl.GetRoomNumber());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pointColl = GetPointCollision(item);
|
pointColl = GetPointCollision(item);
|
||||||
item.Animation.IsAirborne = true;
|
item.Animation.IsAirborne = true;
|
||||||
|
|
||||||
if (pointColl.GetFloorHeight() < item.Pose.Position.y)
|
if (pointColl.GetFloorHeight() < item.Pose.Position.y)
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "Game/collision/collide_item.h"
|
#include "Game/collision/collide_item.h"
|
||||||
#include "Game/collision/Point.h"
|
#include "Game/collision/Point.h"
|
||||||
#include "Game/collision/floordata.h"
|
#include "Game/collision/floordata.h"
|
||||||
#include "Game/collision/sphere.h"
|
#include "Game/collision/Sphere.h"
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
#include "Game/Lara/lara.h"
|
#include "Game/Lara/lara.h"
|
||||||
|
@ -18,6 +18,7 @@
|
||||||
#include "Specific/level.h"
|
#include "Specific/level.h"
|
||||||
|
|
||||||
using namespace TEN::Collision::Point;
|
using namespace TEN::Collision::Point;
|
||||||
|
using namespace TEN::Collision::Sphere;
|
||||||
|
|
||||||
namespace TEN::Entities::Traps
|
namespace TEN::Entities::Traps
|
||||||
{
|
{
|
||||||
|
@ -108,7 +109,7 @@ namespace TEN::Entities::Traps
|
||||||
if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius))
|
if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!TestCollision(&item, playerItem))
|
if (!HandleItemSphereCollision(item, *playerItem))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SoundEffect(SFX_TR4_LARA_GENERAL_DEATH, &playerItem->Pose, SoundEnvironment::Always);
|
SoundEffect(SFX_TR4_LARA_GENERAL_DEATH, &playerItem->Pose, SoundEnvironment::Always);
|
||||||
|
|
|
@ -215,7 +215,7 @@ namespace TEN::Entities::Vehicles
|
||||||
int z = kayakItem->Pose.Position.z + (zOffset * cosY) - (xOffset * sinY);
|
int z = kayakItem->Pose.Position.z + (zOffset * cosY) - (xOffset * sinY);
|
||||||
|
|
||||||
int probedRoomNumber = GetPointCollision(Vector3i(x, kayakItem->Pose.Position.y, z), kayakItem->RoomNumber).GetRoomNumber();
|
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)
|
//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));
|
// 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);
|
auto probe = GetPointCollision(*kayakItem);
|
||||||
int probedRoomNum = probe.GetRoomNumber();
|
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)
|
if (height2 == NO_HEIGHT)
|
||||||
height2 = probe.GetFloorHeight();
|
height2 = probe.GetFloorHeight();
|
||||||
|
|
||||||
|
@ -548,7 +548,7 @@ namespace TEN::Entities::Vehicles
|
||||||
probe = GetPointCollision(*kayakItem);
|
probe = GetPointCollision(*kayakItem);
|
||||||
probedRoomNum = probe.GetRoomNumber();
|
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)
|
if (height2 == NO_HEIGHT)
|
||||||
height2 = probe.GetFloorHeight();
|
height2 = probe.GetFloorHeight();
|
||||||
|
|
||||||
|
@ -1084,7 +1084,7 @@ namespace TEN::Entities::Vehicles
|
||||||
TestTriggers(kayakItem, false);
|
TestTriggers(kayakItem, false);
|
||||||
|
|
||||||
auto probe = GetPointCollision(*kayakItem);
|
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;
|
kayak->WaterHeight = water;
|
||||||
|
|
||||||
if (kayak->WaterHeight == NO_HEIGHT)
|
if (kayak->WaterHeight == NO_HEIGHT)
|
||||||
|
@ -1131,7 +1131,7 @@ namespace TEN::Entities::Vehicles
|
||||||
if (kayak->TrueWater &&
|
if (kayak->TrueWater &&
|
||||||
(kayakItem->Animation.Velocity.z != 0.0f || lara->Context.WaterCurrentPull != Vector3i::Zero))
|
(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);
|
SpawnVehicleWake(*kayakItem, KAYAK_WAKE_OFFSET, waterHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
|
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/camera.h"
|
#include "Game/camera.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/collision/collide_item.h"
|
#include "Game/collision/collide_item.h"
|
||||||
#include "Game/collision/Point.h"
|
#include "Game/collision/Point.h"
|
||||||
|
#include "Game/collision/Sphere.h"
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/effects/spark.h"
|
#include "Game/effects/spark.h"
|
||||||
#include "Game/effects/tomb4fx.h"
|
#include "Game/effects/tomb4fx.h"
|
||||||
|
@ -22,6 +22,7 @@
|
||||||
#include "Specific/level.h"
|
#include "Specific/level.h"
|
||||||
|
|
||||||
using namespace TEN::Collision::Point;
|
using namespace TEN::Collision::Point;
|
||||||
|
using namespace TEN::Collision::Sphere;
|
||||||
using namespace TEN::Effects::Spark;
|
using namespace TEN::Effects::Spark;
|
||||||
using namespace TEN::Input;
|
using namespace TEN::Input;
|
||||||
using namespace TEN::Math;
|
using namespace TEN::Math;
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include "Game/camera.h"
|
#include "Game/camera.h"
|
||||||
#include "Game/collision/collide_item.h"
|
#include "Game/collision/collide_item.h"
|
||||||
#include "Game/collision/Point.h"
|
#include "Game/collision/Point.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/effects/Bubble.h"
|
#include "Game/effects/Bubble.h"
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
|
@ -423,7 +422,7 @@ namespace TEN::Entities::Vehicles
|
||||||
|
|
||||||
short roomNumber = rBoatItem->RoomNumber;
|
short roomNumber = rBoatItem->RoomNumber;
|
||||||
auto floor = GetFloor(rBoatItem->Pose.Position.x, rBoatItem->Pose.Position.y, rBoatItem->Pose.Position.z, &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)
|
if (height == NO_HEIGHT)
|
||||||
height = GetFloorHeight(floor, rBoatItem->Pose.Position.x, rBoatItem->Pose.Position.y, rBoatItem->Pose.Position.z);
|
height = GetFloorHeight(floor, rBoatItem->Pose.Position.x, rBoatItem->Pose.Position.y, rBoatItem->Pose.Position.z);
|
||||||
|
@ -827,7 +826,7 @@ namespace TEN::Entities::Vehicles
|
||||||
}
|
}
|
||||||
|
|
||||||
auto probe = GetPointCollision(*rBoatItem);
|
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;
|
rBoat->Water = water;
|
||||||
|
|
||||||
if (lara->Context.Vehicle == itemNumber && laraItem->HitPoints > 0)
|
if (lara->Context.Vehicle == itemNumber && laraItem->HitPoints > 0)
|
||||||
|
@ -936,7 +935,7 @@ namespace TEN::Entities::Vehicles
|
||||||
DoRubberBoatDismount(rBoatItem, laraItem);
|
DoRubberBoatDismount(rBoatItem, laraItem);
|
||||||
|
|
||||||
short probedRoomNumber = GetPointCollision(Vector3i(rBoatItem->Pose.Position.x, rBoatItem->Pose.Position.y + 128, rBoatItem->Pose.Position.z), rBoatItem->RoomNumber).GetRoomNumber();
|
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)
|
if (height > rBoatItem->Pose.Position.y + 32 || height == NO_HEIGHT)
|
||||||
height = 0;
|
height = 0;
|
||||||
else
|
else
|
||||||
|
@ -951,7 +950,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);
|
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);
|
SpawnVehicleWake(*rBoatItem, RBOAT_WAKE_OFFSET, waterHeight);
|
||||||
|
|
||||||
if ((GetRandomControl() & 1) == 0)
|
if ((GetRandomControl() & 1) == 0)
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
|
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/camera.h"
|
#include "Game/camera.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/collision/collide_item.h"
|
#include "Game/collision/collide_item.h"
|
||||||
#include "Game/collision/collide_room.h"
|
#include "Game/collision/collide_room.h"
|
||||||
#include "Game/collision/Point.h"
|
#include "Game/collision/Point.h"
|
||||||
|
#include "Game/collision/Sphere.h"
|
||||||
#include "Game/control/box.h"
|
#include "Game/control/box.h"
|
||||||
#include "Game/control/los.h"
|
#include "Game/control/los.h"
|
||||||
#include "Game/effects/Bubble.h"
|
#include "Game/effects/Bubble.h"
|
||||||
|
@ -28,6 +28,7 @@
|
||||||
#include "Specific/Input/Input.h"
|
#include "Specific/Input/Input.h"
|
||||||
|
|
||||||
using namespace TEN::Collision::Point;
|
using namespace TEN::Collision::Point;
|
||||||
|
using namespace TEN::Collision::Sphere;
|
||||||
using namespace TEN::Effects::Bubble;
|
using namespace TEN::Effects::Bubble;
|
||||||
using namespace TEN::Effects::Streamer;
|
using namespace TEN::Effects::Streamer;
|
||||||
using namespace TEN::Input;
|
using namespace TEN::Input;
|
||||||
|
@ -185,7 +186,7 @@ namespace TEN::Entities::Vehicles
|
||||||
if (mountType == VehicleMountType::None)
|
if (mountType == VehicleMountType::None)
|
||||||
{
|
{
|
||||||
// HACK: Collision in water behaves differently? @Sezz 2022.06.28
|
// 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);
|
ItemPushItem(UPVItem, laraItem, coll, false, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -731,8 +732,9 @@ namespace TEN::Entities::Vehicles
|
||||||
UPV->Flags &= ~UPV_FLAG_CONTROL;
|
UPV->Flags &= ~UPV_FLAG_CONTROL;
|
||||||
int waterDepth, waterHeight, heightFromWater;
|
int waterDepth, waterHeight, heightFromWater;
|
||||||
|
|
||||||
waterDepth = GetWaterSurface(laraItem);
|
auto pointColl = GetPointCollision(*laraItem);
|
||||||
waterHeight = GetWaterHeight(laraItem);
|
waterDepth = pointColl.GetWaterSurfaceHeight();
|
||||||
|
waterHeight = pointColl.GetWaterTopHeight();
|
||||||
|
|
||||||
if (waterHeight != NO_HEIGHT)
|
if (waterHeight != NO_HEIGHT)
|
||||||
heightFromWater = laraItem->Pose.Position.y - waterHeight;
|
heightFromWater = laraItem->Pose.Position.y - waterHeight;
|
||||||
|
@ -871,8 +873,9 @@ namespace TEN::Entities::Vehicles
|
||||||
TranslateItem(UPVItem, UPVItem->Pose.Orientation, UPVItem->Animation.Velocity.z);
|
TranslateItem(UPVItem, UPVItem->Pose.Orientation, UPVItem->Animation.Velocity.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
int newHeight = GetPointCollision(*UPVItem).GetFloorHeight();
|
auto pointColl = GetPointCollision(*UPVItem);
|
||||||
int waterHeight = GetWaterHeight(UPVItem);
|
int newHeight = pointColl.GetFloorHeight();
|
||||||
|
int waterHeight = pointColl.GetWaterTopHeight();
|
||||||
|
|
||||||
if ((newHeight - waterHeight) < UPV_HEIGHT || (newHeight < UPVItem->Pose.Position.y - UPV_HEIGHT / 2) ||
|
if ((newHeight - waterHeight) < UPV_HEIGHT || (newHeight < UPVItem->Pose.Position.y - UPV_HEIGHT / 2) ||
|
||||||
(newHeight == NO_HEIGHT) || (waterHeight == NO_HEIGHT))
|
(newHeight == NO_HEIGHT) || (waterHeight == NO_HEIGHT))
|
||||||
|
@ -943,7 +946,7 @@ namespace TEN::Entities::Vehicles
|
||||||
|
|
||||||
if (UPV->Velocity || IsDirectionalActionHeld())
|
if (UPV->Velocity || IsDirectionalActionHeld())
|
||||||
{
|
{
|
||||||
waterHeight = GetWaterHeight(UPVItem);
|
waterHeight = GetPointCollision(*UPVItem).GetWaterTopHeight();
|
||||||
SpawnVehicleWake(*UPVItem, UPV_WAKE_OFFSET, waterHeight, true);
|
SpawnVehicleWake(*UPVItem, UPV_WAKE_OFFSET, waterHeight, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "framework.h"
|
#include "framework.h"
|
||||||
#include "Objects/TR4/Entity/tr4_ahmet.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/box.h"
|
||||||
#include "Game/control/control.h"
|
#include "Game/control/control.h"
|
||||||
#include "Game/control/lot.h"
|
#include "Game/control/lot.h"
|
||||||
|
@ -17,6 +17,7 @@
|
||||||
#include "Sound/sound.h"
|
#include "Sound/sound.h"
|
||||||
#include "Specific/level.h"
|
#include "Specific/level.h"
|
||||||
|
|
||||||
|
using namespace TEN::Collision::Sphere;
|
||||||
using namespace TEN::Effects::Environment;
|
using namespace TEN::Effects::Environment;
|
||||||
using namespace TEN::Math;
|
using namespace TEN::Math;
|
||||||
|
|
||||||
|
@ -80,26 +81,21 @@ namespace TEN::Entities::TR4
|
||||||
|
|
||||||
static void TriggerAhmetDeathEffect(ItemInfo* item)
|
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))
|
if (!(Wibble & 7))
|
||||||
{
|
{
|
||||||
int meshCount = GetSpheres(item, spheres, SPHERES_SPACE_WORLD, Matrix::Identity);
|
auto spheres = item->GetSpheres();
|
||||||
auto sphere = &spheres[(Wibble / 8) & 1];
|
const auto* spherePtr = &spheres[(Wibble / 8) & 1];
|
||||||
for (int i = meshCount; i > 0; i--, sphere += 2)
|
|
||||||
TriggerFireFlame(sphere->x, sphere->y, sphere->z, FlameType::Medium);
|
// 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(
|
TriggerDynamicLight(
|
||||||
item->Pose.Position.x,
|
item->Pose.Position.x,
|
||||||
item->Pose.Position.y - CLICK(1),
|
item->Pose.Position.y - CLICK(1),
|
||||||
item->Pose.Position.z,
|
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);
|
SoundEffect(SFX_TR4_LOOP_FOR_SMALL_FIRES, &item->Pose);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/collision/collide_room.h"
|
#include "Game/collision/collide_room.h"
|
||||||
|
#include "Game/collision/Point.h"
|
||||||
#include "Game/control/box.h"
|
#include "Game/control/box.h"
|
||||||
#include "Game/control/control.h"
|
#include "Game/control/control.h"
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
|
@ -15,6 +16,7 @@
|
||||||
#include "Math/Math.h"
|
#include "Math/Math.h"
|
||||||
#include "Specific/level.h"
|
#include "Specific/level.h"
|
||||||
|
|
||||||
|
using namespace TEN::Collision::Point;
|
||||||
using namespace TEN::Math;
|
using namespace TEN::Math;
|
||||||
|
|
||||||
namespace TEN::Entities::TR4
|
namespace TEN::Entities::TR4
|
||||||
|
@ -90,7 +92,7 @@ namespace TEN::Entities::TR4
|
||||||
{
|
{
|
||||||
auto* creature = GetCreatureInfo(item);
|
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)
|
if (waterDepth != NO_HEIGHT)
|
||||||
{
|
{
|
||||||
creature->LOT.Step = BLOCK(20);
|
creature->LOT.Step = BLOCK(20);
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/collision/collide_room.h"
|
#include "Game/collision/collide_room.h"
|
||||||
#include "Game/collision/Point.h"
|
#include "Game/collision/Point.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/control/box.h"
|
#include "Game/control/box.h"
|
||||||
#include "Game/control/control.h"
|
#include "Game/control/control.h"
|
||||||
#include "Game/effects/debris.h"
|
#include "Game/effects/debris.h"
|
||||||
|
@ -354,7 +353,7 @@ namespace TEN::Entities::TR4
|
||||||
SoundEffect(SFX_TR4_HORSEMAN_TAKEHIT, &item->Pose);
|
SoundEffect(SFX_TR4_HORSEMAN_TAKEHIT, &item->Pose);
|
||||||
SoundEffect(SFX_TR4_HORSE_RICOCHET, &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);
|
HorsemanSparks(&pos, item->Pose.Orientation.y, 7);
|
||||||
}
|
}
|
||||||
else if (Random::TestProbability(1 / 8.0f))
|
else if (Random::TestProbability(1 / 8.0f))
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#include "Objects/TR4/Entity/tr4_mutant.h"
|
#include "Objects/TR4/Entity/tr4_mutant.h"
|
||||||
|
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/control/control.h"
|
#include "Game/control/control.h"
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/itemdata/creature_info.h"
|
#include "Game/itemdata/creature_info.h"
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
#include "framework.h"
|
#include "framework.h"
|
||||||
#include "tr4_element_puzzle.h"
|
#include "tr4_element_puzzle.h"
|
||||||
|
|
||||||
#include "Specific/level.h"
|
#include "Specific/level.h"
|
||||||
|
#include "Game/Collision/Sphere.h"
|
||||||
#include "Game/control/control.h"
|
#include "Game/control/control.h"
|
||||||
#include "Sound/sound.h"
|
#include "Sound/sound.h"
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/Lara/lara.h"
|
#include "Game/Lara/lara.h"
|
||||||
#include "Game/Lara/lara_helpers.h"
|
#include "Game/Lara/lara_helpers.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/effects/tomb4fx.h"
|
#include "Game/effects/tomb4fx.h"
|
||||||
#include "Specific/Input/Input.h"
|
#include "Specific/Input/Input.h"
|
||||||
|
@ -15,6 +16,7 @@
|
||||||
#include "Game/collision/collide_item.h"
|
#include "Game/collision/collide_item.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
|
|
||||||
|
using namespace TEN::Collision::Sphere;
|
||||||
using namespace TEN::Input;
|
using namespace TEN::Input;
|
||||||
using namespace TEN::Entities::Switches;
|
using namespace TEN::Entities::Switches;
|
||||||
|
|
||||||
|
@ -149,7 +151,7 @@ namespace TEN::Entities::TR4
|
||||||
|
|
||||||
if (TestBoundsCollide(item, laraItem, coll->Setup.Radius))
|
if (TestBoundsCollide(item, laraItem, coll->Setup.Radius))
|
||||||
{
|
{
|
||||||
if (TestCollision(item, laraItem))
|
if (HandleItemSphereCollision(*item, *laraItem))
|
||||||
{
|
{
|
||||||
if (coll->Setup.EnableObjectPush)
|
if (coll->Setup.EnableObjectPush)
|
||||||
ItemPushItem(item, laraItem, coll, false, 0);
|
ItemPushItem(item, laraItem, coll, false, 0);
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#include "Sound/sound.h"
|
#include "Sound/sound.h"
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/Lara/lara.h"
|
#include "Game/Lara/lara.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
#include "Renderer/RendererEnums.h"
|
#include "Renderer/RendererEnums.h"
|
||||||
|
@ -34,7 +33,7 @@ namespace TEN::Entities::TR4
|
||||||
|
|
||||||
item->MeshBits |= 2;
|
item->MeshBits |= 2;
|
||||||
|
|
||||||
auto pos = GetJointPosition(item, SPHERES_SPACE_WORLD);
|
auto pos = GetJointPosition(item, 0);
|
||||||
byte color = (GetRandomControl() & 0x1F) + 192;
|
byte color = (GetRandomControl() & 0x1F) + 192;
|
||||||
TriggerDynamicLight(pos.x, pos.y, pos.z, (GetRandomControl() & 3) + 16, color, color, 0);
|
TriggerDynamicLight(pos.x, pos.y, pos.z, (GetRandomControl() & 3) + 16, color, color, 0);
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include "Game/collision/collide_item.h"
|
#include "Game/collision/collide_item.h"
|
||||||
#include "Game/collision/collide_room.h"
|
#include "Game/collision/collide_room.h"
|
||||||
#include "Game/collision/Point.h"
|
#include "Game/collision/Point.h"
|
||||||
#include "Game/collision/sphere.h"
|
#include "Game/collision/Sphere.h"
|
||||||
#include "Game/control/control.h"
|
#include "Game/control/control.h"
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
#include "Sound/sound.h"
|
#include "Sound/sound.h"
|
||||||
#include "Specific/level.h"
|
#include "Specific/level.h"
|
||||||
|
|
||||||
using namespace TEN::Collision::Point;
|
using namespace TEN::Collision::Sphere;
|
||||||
|
|
||||||
namespace TEN::Entities::Traps
|
namespace TEN::Entities::Traps
|
||||||
{
|
{
|
||||||
|
@ -80,7 +80,7 @@ namespace TEN::Entities::Traps
|
||||||
if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius))
|
if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TestCollision(&item, playerItem);
|
HandleItemSphereCollision(item, *playerItem);
|
||||||
}
|
}
|
||||||
else if (item.Status != ITEM_INVISIBLE)
|
else if (item.Status != ITEM_INVISIBLE)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include "Game/collision/collide_item.h"
|
#include "Game/collision/collide_item.h"
|
||||||
#include "Game/collision/collide_room.h"
|
#include "Game/collision/collide_room.h"
|
||||||
#include "Game/collision/Point.h"
|
#include "Game/collision/Point.h"
|
||||||
#include "Game/collision/sphere.h"
|
#include "Game/collision/Sphere.h"
|
||||||
#include "Game/control/control.h"
|
#include "Game/control/control.h"
|
||||||
#include "Game/effects/debris.h"
|
#include "Game/effects/debris.h"
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
|
@ -16,6 +16,7 @@
|
||||||
#include "Specific/level.h"
|
#include "Specific/level.h"
|
||||||
|
|
||||||
using namespace TEN::Collision::Point;
|
using namespace TEN::Collision::Point;
|
||||||
|
using namespace TEN::Collision::Sphere;
|
||||||
using namespace TEN::Math;
|
using namespace TEN::Math;
|
||||||
|
|
||||||
// NOTES:
|
// NOTES:
|
||||||
|
@ -131,7 +132,7 @@ namespace TEN::Entities::Traps
|
||||||
if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius))
|
if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TestCollision(&item, playerItem);
|
HandleItemSphereCollision(item, *playerItem);
|
||||||
}
|
}
|
||||||
else if (item.Status != ITEM_INVISIBLE)
|
else if (item.Status != ITEM_INVISIBLE)
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include "Game/collision/collide_item.h"
|
#include "Game/collision/collide_item.h"
|
||||||
#include "Game/collision/collide_room.h"
|
#include "Game/collision/collide_room.h"
|
||||||
#include "Game/collision/Point.h"
|
#include "Game/collision/Point.h"
|
||||||
#include "Game/collision/sphere.h"
|
#include "Game/collision/Sphere.h"
|
||||||
#include "Game/control/control.h"
|
#include "Game/control/control.h"
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
|
@ -17,6 +17,7 @@
|
||||||
#include "Specific/level.h"
|
#include "Specific/level.h"
|
||||||
|
|
||||||
using namespace TEN::Collision::Point;
|
using namespace TEN::Collision::Point;
|
||||||
|
using namespace TEN::Collision::Sphere;
|
||||||
|
|
||||||
// NOTES:
|
// NOTES:
|
||||||
// item.ItemFlags[0]: use dynamic motion.
|
// item.ItemFlags[0]: use dynamic motion.
|
||||||
|
@ -175,7 +176,7 @@ namespace TEN::Entities::Traps
|
||||||
if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius))
|
if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!TestCollision(&item, playerItem))
|
if (!HandleItemSphereCollision(item, *playerItem))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!ItemPushItem(&item, playerItem, coll, false, 1))
|
if (!ItemPushItem(&item, playerItem, coll, false, 1))
|
||||||
|
@ -201,7 +202,7 @@ namespace TEN::Entities::Traps
|
||||||
if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius))
|
if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!TestCollision(&item, playerItem))
|
if (!HandleItemSphereCollision(item, *playerItem))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((item.Animation.FrameNumber - GetAnimData(item).frameBase) <= FALLING_BLOCK_IMPACT_FRAME)
|
if ((item.Animation.FrameNumber - GetAnimData(item).frameBase) <= FALLING_BLOCK_IMPACT_FRAME)
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace TEN::Entities::Traps
|
||||||
|
|
||||||
if (TriggerActive(&item))
|
if (TriggerActive(&item))
|
||||||
{
|
{
|
||||||
*((int*)&item.ItemFlags[0]) = 0x787E;
|
*(int*)&item.ItemFlags[0] = 0x787E;
|
||||||
AnimateItem(&item);
|
AnimateItem(&item);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -30,12 +30,12 @@ namespace TEN::Entities::Traps
|
||||||
|
|
||||||
if (TriggerActive(&item))
|
if (TriggerActive(&item))
|
||||||
{
|
{
|
||||||
*((int*)&item.ItemFlags[0]) = 0x780;
|
*(int*)&item.ItemFlags[0] = 0x780;
|
||||||
AnimateItem(&item);
|
AnimateItem(&item);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*((int*)&item.ItemFlags[0]) = 0;
|
*(int*)&item.ItemFlags[0] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#include "Objects/TR4/Trap/tr4_hammer.h"
|
#include "Objects/TR4/Trap/tr4_hammer.h"
|
||||||
|
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/control/control.h"
|
#include "Game/control/control.h"
|
||||||
#include "Game/effects/debris.h"
|
#include "Game/effects/debris.h"
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include "Objects/TR4/Trap/tr4_mine.h"
|
#include "Objects/TR4/Trap/tr4_mine.h"
|
||||||
|
|
||||||
#include "Game/collision/collide_item.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/debris.h"
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/effects/tomb4fx.h"
|
#include "Game/effects/tomb4fx.h"
|
||||||
|
@ -12,6 +12,7 @@
|
||||||
#include "Sound/sound.h"
|
#include "Sound/sound.h"
|
||||||
#include "Specific/level.h"
|
#include "Specific/level.h"
|
||||||
|
|
||||||
|
using namespace TEN::Collision::Sphere;
|
||||||
using namespace TEN::Effects::Environment;
|
using namespace TEN::Effects::Environment;
|
||||||
|
|
||||||
namespace TEN::Entities::Traps
|
namespace TEN::Entities::Traps
|
||||||
|
@ -28,30 +29,29 @@ namespace TEN::Entities::Traps
|
||||||
{
|
{
|
||||||
auto& item = g_Level.Items[itemNumber];
|
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)
|
if (item.ItemFlags[0] >= 150)
|
||||||
{
|
{
|
||||||
SoundEffect(SFX_TR4_EXPLOSION1, &item.Pose);
|
SoundEffect(SFX_TR4_EXPLOSION1, &item.Pose);
|
||||||
SoundEffect(SFX_TR4_EXPLOSION2, &item.Pose);
|
SoundEffect(SFX_TR4_EXPLOSION2, &item.Pose);
|
||||||
SoundEffect(SFX_TR4_EXPLOSION1, &item.Pose, SoundEnvironment::Land, 0.7f, 0.5f);
|
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)
|
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.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);
|
||||||
TriggerExplosionSparks(sphere.x, sphere.y, sphere.z, 3, -2, 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);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < sphereCount; i++)
|
for (int i = 0; i < spheres.size(); i++)
|
||||||
ExplodeItemNode(&item, i, 0, -128);
|
ExplodeItemNode(&item, i, 0, -128);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,12 +80,12 @@ namespace TEN::Entities::Traps
|
||||||
if (fade > 255)
|
if (fade > 255)
|
||||||
fade = 0;
|
fade = 0;
|
||||||
|
|
||||||
for (int i = 0; i < sphereCount; i++)
|
for (int i = 0; i < spheres.size(); i++)
|
||||||
{
|
{
|
||||||
if (i == 0 || i > 5)
|
if (i == 0 || i > 5)
|
||||||
{
|
{
|
||||||
auto& sphere = CreatureSpheres[i];
|
const auto& sphere = spheres[i];
|
||||||
AddFire(sphere.x, sphere.y, sphere.z, item.RoomNumber, 0.25f, fade);
|
AddFire(sphere.Center.x, sphere.Center.y, sphere.Center.z, item.RoomNumber, 0.25f, fade);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/control/control.h"
|
#include "Game/control/control.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
#include "Game/Lara/lara.h"
|
#include "Game/Lara/lara.h"
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/collision/collide_item.h"
|
#include "Game/collision/collide_item.h"
|
||||||
#include "Game/collision/collide_room.h"
|
#include "Game/collision/collide_room.h"
|
||||||
#include "Game/collision/sphere.h"
|
#include "Game/collision/Sphere.h"
|
||||||
#include "Game/control/control.h"
|
#include "Game/control/control.h"
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
|
@ -12,6 +12,8 @@
|
||||||
#include "Sound/sound.h"
|
#include "Sound/sound.h"
|
||||||
#include "Specific/level.h"
|
#include "Specific/level.h"
|
||||||
|
|
||||||
|
using namespace TEN::Collision::Sphere;
|
||||||
|
|
||||||
namespace TEN::Entities::Traps
|
namespace TEN::Entities::Traps
|
||||||
{
|
{
|
||||||
constexpr auto STARGATE_HARM_DAMAGE = 100;
|
constexpr auto STARGATE_HARM_DAMAGE = 100;
|
||||||
|
@ -61,12 +63,13 @@ namespace TEN::Entities::Traps
|
||||||
if (!TestBoundsCollide(item, laraItem, coll->Setup.Radius))
|
if (!TestBoundsCollide(item, laraItem, coll->Setup.Radius))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (TestCollision(item, laraItem) &&
|
if (HandleItemSphereCollision(*item, *laraItem) &&
|
||||||
TriggerActive(item) &&
|
TriggerActive(item) &&
|
||||||
item->Animation.FrameNumber > GetAnimData(item).frameBase + 20 && // Hardcoded frame range.
|
item->Animation.FrameNumber > GetAnimData(item).frameBase + 20 && // Hardcoded frame range.
|
||||||
item->Animation.FrameNumber < GetAnimData(item).frameBase + 60)
|
item->Animation.FrameNumber < GetAnimData(item).frameBase + 60)
|
||||||
{
|
{
|
||||||
// Blades deal damage cumulatively.
|
// Blades deal damage cumulatively.
|
||||||
|
auto spheres = item->GetSpheres();
|
||||||
for (int i = 0; i < StargateHarmJoints.size(); i++)
|
for (int i = 0; i < StargateHarmJoints.size(); i++)
|
||||||
{
|
{
|
||||||
if (item->TouchBits.Test(StargateHarmJoints[i]))
|
if (item->TouchBits.Test(StargateHarmJoints[i]))
|
||||||
|
@ -74,7 +77,7 @@ namespace TEN::Entities::Traps
|
||||||
DoDamage(laraItem, STARGATE_HARM_DAMAGE);
|
DoDamage(laraItem, STARGATE_HARM_DAMAGE);
|
||||||
DoBloodSplat(
|
DoBloodSplat(
|
||||||
(GetRandomControl() & 0x3F) + laraItem->Pose.Position.x - 32,
|
(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() & 0x3F) + laraItem->Pose.Position.z - 32,
|
||||||
(GetRandomControl() & 3) + 2,
|
(GetRandomControl() & 3) + 2,
|
||||||
GetRandomControl() * 2,
|
GetRandomControl() * 2,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include "Objects/TR5/Entity/AutoGun.h"
|
#include "Objects/TR5/Entity/AutoGun.h"
|
||||||
|
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/collision/sphere.h"
|
#include "Game/collision/Sphere.h"
|
||||||
#include "Game/control/los.h"
|
#include "Game/control/los.h"
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/effects/tomb4fx.h"
|
#include "Game/effects/tomb4fx.h"
|
||||||
|
@ -14,6 +14,7 @@
|
||||||
#include "Sound/sound.h"
|
#include "Sound/sound.h"
|
||||||
#include "Specific/level.h"
|
#include "Specific/level.h"
|
||||||
|
|
||||||
|
using namespace TEN::Collision::Sphere;
|
||||||
using namespace TEN::Math;
|
using namespace TEN::Math;
|
||||||
|
|
||||||
// NOTES:
|
// NOTES:
|
||||||
|
|
|
@ -209,7 +209,7 @@ void ControlBodyPart(short fxNumber)
|
||||||
if (TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, pointColl.GetRoomNumber()) &&
|
if (TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, pointColl.GetRoomNumber()) &&
|
||||||
!TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, fx->roomNumber))
|
!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.y = waterHeight - 1;
|
||||||
SplashSetup.x = fx->pos.Position.x;
|
SplashSetup.x = fx->pos.Position.x;
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
#include "Game/collision/collide_room.h"
|
#include "Game/collision/collide_room.h"
|
||||||
#include "Game/collision/Point.h"
|
#include "Game/collision/Point.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/effects/tomb4fx.h"
|
#include "Game/effects/tomb4fx.h"
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Specific/level.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.yRot = fx->pos.Orientation.y;
|
||||||
ShatterItem.meshIndex = fx->frameNumber;
|
ShatterItem.meshIndex = fx->frameNumber;
|
||||||
ShatterItem.color = Vector4::One;
|
ShatterItem.color = Vector4::One;
|
||||||
ShatterItem.sphere.x = fx->pos.Position.x;
|
ShatterItem.sphere.Center = fx->pos.Position.ToVector3();
|
||||||
ShatterItem.sphere.y = fx->pos.Position.y;
|
|
||||||
ShatterItem.sphere.z = fx->pos.Position.z;
|
|
||||||
ShatterItem.bit = 0;
|
ShatterItem.bit = 0;
|
||||||
ShatterItem.flags = fx->flag2 & 0x1400;
|
ShatterItem.flags = fx->flag2 & 0x1400;
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include "Game/camera.h"
|
#include "Game/camera.h"
|
||||||
#include "Game/collision/collide_item.h"
|
#include "Game/collision/collide_item.h"
|
||||||
#include "Game/collision/Point.h"
|
#include "Game/collision/Point.h"
|
||||||
#include "Game/collision/sphere.h"
|
#include "Game/collision/Sphere.h"
|
||||||
#include "Game/control/control.h"
|
#include "Game/control/control.h"
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
using namespace TEN::Collision::Point;
|
using namespace TEN::Collision::Point;
|
||||||
|
|
||||||
|
using namespace TEN::Collision::Sphere;
|
||||||
|
|
||||||
constexpr auto ROLLING_BALL_MAX_VELOCITY = BLOCK(3);
|
constexpr auto ROLLING_BALL_MAX_VELOCITY = BLOCK(3);
|
||||||
|
|
||||||
void RollingBallCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
|
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];
|
auto* ballItem = &g_Level.Items[itemNumber];
|
||||||
|
|
||||||
if (!TestBoundsCollide(ballItem, laraItem, coll->Setup.Radius) ||
|
if (!TestBoundsCollide(ballItem, laraItem, coll->Setup.Radius) ||
|
||||||
!TestCollision(ballItem, laraItem))
|
!HandleItemSphereCollision(*ballItem, *laraItem))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -259,23 +261,22 @@ void RollingBallControl(short itemNumber)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto roomNumber = GetPointCollision(*item).GetRoomNumber();
|
auto pointColl = GetPointCollision(*item);
|
||||||
|
if (item->RoomNumber != pointColl.GetRoomNumber())
|
||||||
if (item->RoomNumber != roomNumber)
|
|
||||||
{
|
{
|
||||||
if (TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, roomNumber) &&
|
if (TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, pointColl.GetRoomNumber()) &&
|
||||||
!TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, item->RoomNumber))
|
!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.y = waterHeight - 1;
|
||||||
SplashSetup.x = item->Pose.Position.x;
|
SplashSetup.x = item->Pose.Position.x;
|
||||||
SplashSetup.z = item->Pose.Position.z;
|
SplashSetup.z = item->Pose.Position.z;
|
||||||
SplashSetup.splashPower = item->Animation.Velocity.y * 4;
|
SplashSetup.splashPower = item->Animation.Velocity.y * 4;
|
||||||
SplashSetup.innerRadius = 160;
|
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)
|
if (item->ItemFlags[0] > ROLLING_BALL_MAX_VELOCITY)
|
||||||
|
@ -323,7 +324,7 @@ void ClassicRollingBallCollision(short itemNum, ItemInfo* lara, CollisionInfo* c
|
||||||
if (!TestBoundsCollide(item, lara, coll->Setup.Radius))
|
if (!TestBoundsCollide(item, lara, coll->Setup.Radius))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!TestCollision(item, lara))
|
if (!HandleItemSphereCollision(*item, *lara))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (lara->Animation.IsAirborne)
|
if (lara->Animation.IsAirborne)
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include "Game/camera.h"
|
#include "Game/camera.h"
|
||||||
#include "Game/collision/collide_item.h"
|
#include "Game/collision/collide_item.h"
|
||||||
#include "Game/collision/collide_room.h"
|
#include "Game/collision/collide_room.h"
|
||||||
#include "Game/collision/sphere.h"
|
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/effects/tomb4fx.h"
|
#include "Game/effects/tomb4fx.h"
|
||||||
#include "Game/effects/weather.h"
|
#include "Game/effects/weather.h"
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "Game/collision/collide_item.h"
|
#include "Game/collision/collide_item.h"
|
||||||
#include "Game/collision/Point.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/simple_particle.h"
|
||||||
#include "Game/effects/Streamer.h"
|
#include "Game/effects/Streamer.h"
|
||||||
#include "Game/effects/tomb4fx.h"
|
#include "Game/effects/tomb4fx.h"
|
||||||
|
@ -17,6 +17,7 @@
|
||||||
#include "Specific/Input/Input.h"
|
#include "Specific/Input/Input.h"
|
||||||
|
|
||||||
using namespace TEN::Collision::Point;
|
using namespace TEN::Collision::Point;
|
||||||
|
using namespace TEN::Collision::Sphere;
|
||||||
using namespace TEN::Effects::Streamer;
|
using namespace TEN::Effects::Streamer;
|
||||||
using namespace TEN::Hud;
|
using namespace TEN::Hud;
|
||||||
using namespace TEN::Input;
|
using namespace TEN::Input;
|
||||||
|
@ -56,7 +57,7 @@ namespace TEN::Entities::Vehicles
|
||||||
return VehicleMountType::None;
|
return VehicleMountType::None;
|
||||||
|
|
||||||
// Assess object collision.
|
// 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;
|
return VehicleMountType::None;
|
||||||
|
|
||||||
bool hasInputAction = IsHeld(In::Action);
|
bool hasInputAction = IsHeld(In::Action);
|
||||||
|
@ -178,7 +179,7 @@ namespace TEN::Entities::Vehicles
|
||||||
*pos = Vector3i(point);
|
*pos = Vector3i(point);
|
||||||
|
|
||||||
auto pointColl = GetPointCollision(*pos, vehicleItem->RoomNumber);
|
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)
|
if (height == NO_HEIGHT)
|
||||||
{
|
{
|
||||||
|
@ -218,7 +219,7 @@ namespace TEN::Entities::Vehicles
|
||||||
if (TestEnvironment(ENV_FLAG_WATER, vehicleItem) ||
|
if (TestEnvironment(ENV_FLAG_WATER, vehicleItem) ||
|
||||||
TestEnvironment(ENV_FLAG_SWAMP, 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.
|
// 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.
|
// GetWaterDepth returns DEEP_WATER constant in that case, which is too large for our needs.
|
||||||
|
@ -239,11 +240,8 @@ namespace TEN::Entities::Vehicles
|
||||||
|
|
||||||
if (isWater)
|
if (isWater)
|
||||||
{
|
{
|
||||||
int waterHeight = GetWaterHeight(vehicleItem);
|
int waterHeight = GetPointCollision(*vehicleItem).GetWaterTopHeight();
|
||||||
SpawnVehicleWake(*vehicleItem, wakeOffset, waterHeight);
|
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 +253,7 @@ namespace TEN::Entities::Vehicles
|
||||||
}
|
}
|
||||||
else
|
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)
|
if (waterDepth > VEHICLE_WATER_HEIGHT_MAX && waterHeight > VEHICLE_WATER_HEIGHT_MAX)
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,7 +40,8 @@ enum GAME_OBJECT_ID : short
|
||||||
ID_LARA_DIRT_MESH,
|
ID_LARA_DIRT_MESH,
|
||||||
ID_LARA_CROWBAR_ANIM,
|
ID_LARA_CROWBAR_ANIM,
|
||||||
ID_LARA_TORCH_ANIM,
|
ID_LARA_TORCH_ANIM,
|
||||||
ID_HAIR,
|
ID_SINGLE_BRAID_HAIR,
|
||||||
|
ID_DUAL_PIGTAIL_HAIR,
|
||||||
|
|
||||||
ID_SNOWMOBILE_LARA_ANIMS = 50,
|
ID_SNOWMOBILE_LARA_ANIMS = 50,
|
||||||
ID_SNOWMOBILE,
|
ID_SNOWMOBILE,
|
||||||
|
|
|
@ -68,6 +68,7 @@
|
||||||
#include "Graphics/Vertices/PostProcessVertex.h"
|
#include "Graphics/Vertices/PostProcessVertex.h"
|
||||||
|
|
||||||
enum GAME_OBJECT_ID : short;
|
enum GAME_OBJECT_ID : short;
|
||||||
|
enum class SphereSpaceType;
|
||||||
class EulerAngles;
|
class EulerAngles;
|
||||||
struct AnimFrameInterpData;
|
struct AnimFrameInterpData;
|
||||||
struct CAMERA_INFO;
|
struct CAMERA_INFO;
|
||||||
|
@ -628,7 +629,7 @@ namespace TEN::Renderer
|
||||||
void FlipRooms(short roomNumber1, short roomNumber2);
|
void FlipRooms(short roomNumber1, short roomNumber2);
|
||||||
void UpdateLaraAnimations(bool force);
|
void UpdateLaraAnimations(bool force);
|
||||||
void UpdateItemAnimations(int itemNumber, bool force);
|
void UpdateItemAnimations(int itemNumber, bool force);
|
||||||
int GetSpheres(short itemNumber, BoundingSphere* ptr, char worldSpace, Matrix local);
|
std::vector<BoundingSphere> GetSpheres(int itemNumber);
|
||||||
void GetBoneMatrix(short itemNumber, int jointIndex, Matrix* outMatrix);
|
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 DrawObjectIn2DSpace(int objectNumber, Vector2 pos2D, EulerAngles orient, float scale1, float opacity = 1.0f, int meshBits = NO_JOINT_BITS);
|
||||||
void SetLoadingScreen(std::wstring& fileName);
|
void SetLoadingScreen(std::wstring& fileName);
|
||||||
|
@ -637,9 +638,11 @@ namespace TEN::Renderer
|
||||||
|
|
||||||
Vector2i GetScreenResolution() const;
|
Vector2i GetScreenResolution() const;
|
||||||
std::optional<Vector2> Get2DPosition(const Vector3& pos) const;
|
std::optional<Vector2> Get2DPosition(const Vector3& pos) const;
|
||||||
Vector3 GetAbsEntityBonePosition(int itemNumber, int jointIndex, const Vector3& relOffset = Vector3::Zero);
|
|
||||||
std::pair<Vector3, Vector3> GetRay(const Vector2& pos) const;
|
std::pair<Vector3, Vector3> 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,
|
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);
|
int priority, BlendMode blendMode, const Vector2& aspectCorrection, RenderView& renderView);
|
||||||
void CollectDisplaySprites(RenderView& renderView);
|
void CollectDisplaySprites(RenderView& renderView);
|
||||||
|
|
|
@ -516,7 +516,7 @@ namespace TEN::Renderer
|
||||||
&moveable,
|
&moveable,
|
||||||
&g_Level.Meshes[obj->meshIndex + j],
|
&g_Level.Meshes[obj->meshIndex + j],
|
||||||
j, MoveablesIds[i] == ID_LARA_SKIN_JOINTS,
|
j, MoveablesIds[i] == ID_LARA_SKIN_JOINTS,
|
||||||
MoveablesIds[i] == ID_HAIR, &lastVertex, &lastIndex);
|
MoveablesIds[i] == ID_SINGLE_BRAID_HAIR || MoveablesIds[i] == ID_DUAL_PIGTAIL_HAIR, &lastVertex, &lastIndex);
|
||||||
|
|
||||||
moveable.ObjectMeshes.push_back(mesh);
|
moveable.ObjectMeshes.push_back(mesh);
|
||||||
_meshes.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++)
|
for (int j = 0; j < obj->nmeshes; j++)
|
||||||
{
|
{
|
||||||
|
@ -709,7 +709,6 @@ namespace TEN::Renderer
|
||||||
// HACK: Hardcoded hair base parent vertices.
|
// HACK: Hardcoded hair base parent vertices.
|
||||||
int parentVertices0[] = { 37, 39, 40, 38 }; // Single braid.
|
int parentVertices0[] = { 37, 39, 40, 38 }; // Single braid.
|
||||||
int parentVertices1[] = { 79, 78, 76, 77 }; // Left pigtail.
|
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& skinObj = GetRendererObject(GAME_OBJECT_ID::ID_LARA_SKIN);
|
||||||
auto* parentMesh = skinObj.ObjectMeshes[LM_HEAD];
|
auto* parentMesh = skinObj.ObjectMeshes[LM_HEAD];
|
||||||
|
@ -724,20 +723,94 @@ namespace TEN::Renderer
|
||||||
for (int v2 = 0; v2 < parentBucket->NumVertices; v2++)
|
for (int v2 = 0; v2 < parentBucket->NumVertices; v2++)
|
||||||
{
|
{
|
||||||
auto* parentVertex = &_moveablesVertices[parentBucket->StartVertex + v2];
|
auto* parentVertex = &_moveablesVertices[parentBucket->StartVertex + v2];
|
||||||
|
if (isYoung && parentVertex->OriginalIndex == parentVertices1[currentVertex->OriginalIndex])
|
||||||
// TODO
|
|
||||||
if (isYoung)
|
|
||||||
{
|
{
|
||||||
if (parentVertex->OriginalIndex == parentVertices1[currentVertex->OriginalIndex])
|
currentVertex->Bone = 0;
|
||||||
|
currentVertex->Position = parentVertex->Position;
|
||||||
|
currentVertex->Normal = parentVertex->Normal;
|
||||||
|
}
|
||||||
|
else if (parentVertex->OriginalIndex == parentVertices0[currentVertex->OriginalIndex])
|
||||||
{
|
{
|
||||||
currentVertex->Bone = 0;
|
currentVertex->Bone = 0;
|
||||||
currentVertex->Position = parentVertex->Position;
|
currentVertex->Position = parentVertex->Position;
|
||||||
currentVertex->Normal = parentVertex->Normal;
|
currentVertex->Normal = parentVertex->Normal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Link meshes > 0 to parent meshes.
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (parentVertex->OriginalIndex == parentVertices0[currentVertex->OriginalIndex])
|
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_DUAL_PIGTAIL_HAIR && 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];
|
||||||
|
|
||||||
|
if (currentVertex->OriginalIndex < 4)
|
||||||
|
{
|
||||||
|
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->Bone = 0;
|
||||||
currentVertex->Position = parentVertex->Position;
|
currentVertex->Position = parentVertex->Position;
|
||||||
|
@ -747,7 +820,6 @@ namespace TEN::Renderer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Link meshes > 0 to parent meshes.
|
// Link meshes > 0 to parent meshes.
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
|
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/camera.h"
|
#include "Game/camera.h"
|
||||||
#include "Game/collision/sphere.h"
|
#include "Game/collision/Sphere.h"
|
||||||
#include "Game/effects/effects.h"
|
#include "Game/effects/effects.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
#include "Game/Lara/lara.h"
|
#include "Game/Lara/lara.h"
|
||||||
|
@ -14,6 +14,7 @@
|
||||||
#include "Specific/level.h"
|
#include "Specific/level.h"
|
||||||
#include "Renderer/RenderView.h"
|
#include "Renderer/RenderView.h"
|
||||||
|
|
||||||
|
using namespace TEN::Collision::Sphere;
|
||||||
using namespace TEN::Math;
|
using namespace TEN::Math;
|
||||||
|
|
||||||
namespace TEN::Renderer
|
namespace TEN::Renderer
|
||||||
|
@ -361,11 +362,10 @@ namespace TEN::Renderer
|
||||||
if (obj.ShadowType == ShadowMode::None)
|
if (obj.ShadowType == ShadowMode::None)
|
||||||
{
|
{
|
||||||
// Get all spheres and check if frustum intersects any of them.
|
// Get all spheres and check if frustum intersects any of them.
|
||||||
static BoundingSphere spheres[MAX_BONES];
|
auto spheres = GetSpheres(itemNum);
|
||||||
int cnt = GetSpheres(itemNum, spheres, SPHERES_SPACE_WORLD, Matrix::Identity);
|
|
||||||
|
|
||||||
bool inFrustum = false;
|
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.
|
// 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))
|
if (renderView.Camera.Frustum.SphereInFrustum(spheres[i].Center, spheres[i].Radius * 1.5f))
|
||||||
inFrustum = true;
|
inFrustum = true;
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
|
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
|
||||||
#include "Game/animation.h"
|
#include "Game/animation.h"
|
||||||
#include "Game/camera.h"
|
#include "Game/camera.h"
|
||||||
#include "Game/collision/sphere.h"
|
#include "Game/collision/Sphere.h"
|
||||||
#include "Game/control/control.h"
|
#include "Game/control/control.h"
|
||||||
#include "Game/itemdata/creature_info.h"
|
#include "Game/itemdata/creature_info.h"
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
|
@ -34,6 +34,7 @@
|
||||||
#include "Specific/level.h"
|
#include "Specific/level.h"
|
||||||
#include "Specific/trutils.h"
|
#include "Specific/trutils.h"
|
||||||
|
|
||||||
|
using namespace TEN::Collision::Sphere;
|
||||||
using namespace TEN::Math;
|
using namespace TEN::Math;
|
||||||
|
|
||||||
extern GameConfiguration g_Configuration;
|
extern GameConfiguration g_Configuration;
|
||||||
|
@ -94,6 +95,10 @@ namespace TEN::Renderer
|
||||||
rotMatrix = Matrix::CreateFromQuaternion(quat3);
|
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 tMatrix = (bonePtr == rObject.Skeleton) ? Matrix::CreateTranslation(offset0) : Matrix::Identity;
|
||||||
|
|
||||||
auto extraRotMatrix = Matrix::CreateFromQuaternion(bonePtr->ExtraRotation);
|
auto extraRotMatrix = Matrix::CreateFromQuaternion(bonePtr->ExtraRotation);
|
||||||
|
@ -408,17 +413,16 @@ namespace TEN::Renderer
|
||||||
return _meshes[meshIndex];
|
return _meshes[meshIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
int Renderer::GetSpheres(short itemNumber, BoundingSphere* spheres, char worldSpace, Matrix local)
|
std::vector<BoundingSphere> Renderer::GetSpheres(int itemNumber)
|
||||||
{
|
{
|
||||||
auto* itemToDraw = &_items[itemNumber];
|
auto& itemToDraw = _items[itemNumber];
|
||||||
auto* nativeItem = &g_Level.Items[itemNumber];
|
itemToDraw.ItemNumber = itemNumber;
|
||||||
|
|
||||||
itemToDraw->ItemNumber = itemNumber;
|
const auto* nativeItem = &g_Level.Items[itemNumber];
|
||||||
|
if (nativeItem == nullptr)
|
||||||
|
return {};
|
||||||
|
|
||||||
if (!nativeItem)
|
if (!itemToDraw.DoneAnimations)
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!itemToDraw->DoneAnimations)
|
|
||||||
{
|
{
|
||||||
if (itemNumber == LaraItem->Index)
|
if (itemNumber == LaraItem->Index)
|
||||||
{
|
{
|
||||||
|
@ -430,38 +434,26 @@ namespace TEN::Renderer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto world = Matrix::Identity;
|
auto translationMatrix = Matrix::CreateTranslation(nativeItem->Pose.Position.ToVector3());
|
||||||
if (worldSpace & SPHERES_SPACE_WORLD)
|
auto rotMatrix = nativeItem->Pose.Orientation.ToRotationMatrix();
|
||||||
{
|
auto worldMatrix = rotMatrix * translationMatrix;
|
||||||
world = Matrix::CreateTranslation(nativeItem->Pose.Position.x, nativeItem->Pose.Position.y, nativeItem->Pose.Position.z) * local;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
world = Matrix::Identity * local;
|
|
||||||
}
|
|
||||||
|
|
||||||
world = nativeItem->Pose.Orientation.ToRotationMatrix() * world;
|
const auto& moveable = GetRendererObject(nativeItem->ObjectNumber);
|
||||||
|
|
||||||
auto& moveable = GetRendererObject(nativeItem->ObjectNumber);
|
|
||||||
|
|
||||||
|
// Collect spheres.
|
||||||
|
auto spheres = std::vector<BoundingSphere>{};
|
||||||
for (int i = 0; i < moveable.ObjectMeshes.size(); i++)
|
for (int i = 0; i < moveable.ObjectMeshes.size(); i++)
|
||||||
{
|
{
|
||||||
auto mesh = moveable.ObjectMeshes[i];
|
const auto& mesh = *moveable.ObjectMeshes[i];
|
||||||
|
|
||||||
auto pos = (Vector3)mesh->Sphere.Center;
|
const auto& translationMatrix = itemToDraw.AnimationTransforms[i];
|
||||||
if (worldSpace & SPHERES_SPACE_BONE_ORIGIN)
|
auto pos = Vector3::Transform(mesh.Sphere.Center, translationMatrix * worldMatrix);
|
||||||
pos += moveable.LinearizedBones[i]->Translation;
|
|
||||||
|
|
||||||
spheres[i].Center = Vector3::Transform(pos, (itemToDraw->AnimationTransforms[i] * world));
|
auto sphere = BoundingSphere(pos, mesh.Sphere.Radius);
|
||||||
spheres[i].Radius = mesh->Sphere.Radius;
|
spheres.push_back(sphere);
|
||||||
|
|
||||||
// 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)
|
void Renderer::GetBoneMatrix(short itemNumber, int jointIndex, Matrix* outMatrix)
|
||||||
|
@ -561,28 +553,38 @@ namespace TEN::Renderer
|
||||||
return std::pair<Vector3, Vector3>(nearPoint, farPoint);
|
return std::pair<Vector3, Vector3>(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];
|
auto* rendererItem = &_items[itemNumber];
|
||||||
|
|
||||||
rendererItem->ItemNumber = itemNumber;
|
rendererItem->ItemNumber = itemNumber;
|
||||||
|
|
||||||
if (!rendererItem)
|
if (rendererItem == nullptr)
|
||||||
return Vector3::Zero;
|
return Vector3::Zero;
|
||||||
|
|
||||||
if (!rendererItem->DoneAnimations)
|
if (!rendererItem->DoneAnimations)
|
||||||
{
|
(itemNumber == LaraItem->Index) ? UpdateLaraAnimations(false) : UpdateItemAnimations(itemNumber, false);
|
||||||
if (itemNumber == LaraItem->Index)
|
|
||||||
UpdateLaraAnimations(false);
|
if (boneID >= MAX_BONES)
|
||||||
else
|
boneID = 0;
|
||||||
UpdateItemAnimations(itemNumber, false);
|
|
||||||
|
auto world = rendererItem->AnimationTransforms[boneID] * rendererItem->World;
|
||||||
|
return Vector3::Transform(relOffset, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (jointIndex >= MAX_BONES)
|
Quaternion Renderer::GetMoveableBoneOrientation(int itemNumber, int boneID)
|
||||||
jointIndex = 0;
|
{
|
||||||
|
const auto* rendererItem = &_items[itemNumber];
|
||||||
|
|
||||||
auto world = rendererItem->AnimationTransforms[jointIndex] * rendererItem->World;
|
if (rendererItem == nullptr)
|
||||||
return Vector3::Transform(relOffset, world);
|
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()
|
void Renderer::SaveScreenshot()
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "Game/control/control.h"
|
#include "Game/control/control.h"
|
||||||
#include "Game/spotcam.h"
|
#include "Game/spotcam.h"
|
||||||
#include "Game/camera.h"
|
#include "Game/camera.h"
|
||||||
#include "Game/collision/sphere.h"
|
#include "Game/collision/Sphere.h"
|
||||||
#include "Game/Setup.h"
|
#include "Game/Setup.h"
|
||||||
#include "Math/Math.h"
|
#include "Math/Math.h"
|
||||||
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
|
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
|
||||||
|
@ -328,22 +328,18 @@ void TEN::Renderer::Renderer::DrawLara(RenderView& view, RendererPass rendererPa
|
||||||
|
|
||||||
void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, RenderView& view, RendererPass rendererPass)
|
void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, RenderView& view, RendererPass rendererPass)
|
||||||
{
|
{
|
||||||
if (!Objects[ID_HAIR].loaded)
|
for (int i = 0; i < HairEffect.Units.size(); i++)
|
||||||
return;
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
|
const auto& unit = HairEffect.Units[i];
|
||||||
if (!unit.IsEnabled)
|
if (!unit.IsEnabled)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// First matrix is Lara's head matrix, then all hair unit segment matrices.
|
const auto& object = Objects[unit.ObjectID];
|
||||||
// Bones are adjusted at load time to account for this.
|
if (!object.loaded)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const auto& rendererObject = *_moveableObjects[unit.ObjectID];
|
||||||
|
|
||||||
_stItem.World = Matrix::Identity;
|
_stItem.World = Matrix::Identity;
|
||||||
_stItem.BonesMatrices[0] = itemToDraw->AnimationTransforms[LM_HEAD] * _laraWorldMatrix;
|
_stItem.BonesMatrices[0] = itemToDraw->AnimationTransforms[LM_HEAD] * _laraWorldMatrix;
|
||||||
|
|
||||||
|
@ -358,13 +354,11 @@ void Renderer::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, Render
|
||||||
|
|
||||||
_cbItem.UpdateData(_stItem, _context.Get());
|
_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];
|
auto& rendererMesh = *rendererObject.ObjectMeshes[i];
|
||||||
DrawMoveableMesh(itemToDraw, &rMesh, room, i, view, rendererPass);
|
DrawMoveableMesh(itemToDraw, &rendererMesh, room, i, view, rendererPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
isHead = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <SimpleMath.h>
|
|
||||||
|
#include "Game/room.h"
|
||||||
#include "Renderer/RendererEnums.h"
|
#include "Renderer/RendererEnums.h"
|
||||||
#include "Renderer/Structures/RendererLight.h"
|
#include "Renderer/Structures/RendererLight.h"
|
||||||
#include "Game/room.h"
|
|
||||||
|
|
||||||
namespace TEN::Renderer::Structures
|
namespace TEN::Renderer::Structures
|
||||||
{
|
{
|
||||||
using namespace DirectX::SimpleMath;
|
|
||||||
|
|
||||||
struct RendererItem
|
struct RendererItem
|
||||||
{
|
{
|
||||||
int ItemNumber;
|
int ItemNumber;
|
||||||
|
@ -20,6 +18,8 @@ namespace TEN::Renderer::Structures
|
||||||
Matrix Scale;
|
Matrix Scale;
|
||||||
Matrix AnimationTransforms[MAX_BONES];
|
Matrix AnimationTransforms[MAX_BONES];
|
||||||
|
|
||||||
|
Quaternion BoneOrientations[MAX_BONES];
|
||||||
|
|
||||||
int RoomNumber = NO_VALUE;
|
int RoomNumber = NO_VALUE;
|
||||||
int PrevRoomNumber = NO_VALUE;
|
int PrevRoomNumber = NO_VALUE;
|
||||||
Vector4 Color;
|
Vector4 Color;
|
||||||
|
|
|
@ -53,7 +53,8 @@ The following constants are inside ObjID.
|
||||||
LARA_DIRT_MESH
|
LARA_DIRT_MESH
|
||||||
LARA_CROWBAR_ANIM
|
LARA_CROWBAR_ANIM
|
||||||
LARA_TORCH_ANIM
|
LARA_TORCH_ANIM
|
||||||
HAIR
|
SINGLE_BRAID_HAIR
|
||||||
|
DUAL_PIGTAIL_HAIR
|
||||||
SNOWMOBILE_LARA_ANIMS
|
SNOWMOBILE_LARA_ANIMS
|
||||||
SNOWMOBILE
|
SNOWMOBILE
|
||||||
QUAD_LARA_ANIMS
|
QUAD_LARA_ANIMS
|
||||||
|
@ -1230,7 +1231,8 @@ static const std::unordered_map<std::string, GAME_OBJECT_ID> kObjIDs {
|
||||||
{ "LARA_DIRT_MESH", ID_LARA_DIRT_MESH },
|
{ "LARA_DIRT_MESH", ID_LARA_DIRT_MESH },
|
||||||
{ "LARA_CROWBAR_ANIM", ID_LARA_CROWBAR_ANIM },
|
{ "LARA_CROWBAR_ANIM", ID_LARA_CROWBAR_ANIM },
|
||||||
{ "LARA_TORCH_ANIM", ID_LARA_TORCH_ANIM },
|
{ "LARA_TORCH_ANIM", ID_LARA_TORCH_ANIM },
|
||||||
{ "HAIR", ID_HAIR },
|
{ "SINGLE_BRAID_HAIR", ID_SINGLE_BRAID_HAIR },
|
||||||
|
{ "DUAL_PIGTAIL_HAIR", ID_DUAL_PIGTAIL_HAIR },
|
||||||
{ "SNOWMOBILE_LARA_ANIMS", ID_SNOWMOBILE_LARA_ANIMS },
|
{ "SNOWMOBILE_LARA_ANIMS", ID_SNOWMOBILE_LARA_ANIMS },
|
||||||
{ "SNOWMOBILE", ID_SNOWMOBILE },
|
{ "SNOWMOBILE", ID_SNOWMOBILE },
|
||||||
{ "QUAD_LARA_ANIMS", ID_QUAD_LARA_ANIMS },
|
{ "QUAD_LARA_ANIMS", ID_QUAD_LARA_ANIMS },
|
||||||
|
|
|
@ -632,9 +632,9 @@ namespace TEN::Input
|
||||||
{
|
{
|
||||||
// Save screenshot.
|
// Save screenshot.
|
||||||
static bool dbScreenshot = true;
|
static bool dbScreenshot = true;
|
||||||
if (KeyMap[KC_SYSRQ] && dbScreenshot)
|
if ((KeyMap[KC_SYSRQ] || KeyMap[KC_F12]) && dbScreenshot)
|
||||||
g_Renderer.SaveScreenshot();
|
g_Renderer.SaveScreenshot();
|
||||||
dbScreenshot = !KeyMap[KC_SYSRQ];
|
dbScreenshot = !(KeyMap[KC_SYSRQ] || KeyMap[KC_F12]);
|
||||||
|
|
||||||
// Toggle fullscreen.
|
// Toggle fullscreen.
|
||||||
static bool dbFullscreen = true;
|
static bool dbFullscreen = true;
|
||||||
|
|
|
@ -257,7 +257,7 @@ bool SaveConfiguration()
|
||||||
|
|
||||||
// Set Input keys.
|
// Set Input keys.
|
||||||
if (SetDWORDRegKey(inputKey, REGKEY_MOUSE_SENSITIVITY, g_Configuration.MouseSensitivity) != ERROR_SUCCESS ||
|
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(rootKey);
|
||||||
RegCloseKey(graphicsKey);
|
RegCloseKey(graphicsKey);
|
||||||
|
@ -451,7 +451,7 @@ bool LoadConfiguration()
|
||||||
if (RegOpenKeyExA(rootKey, REGKEY_INPUT, 0, KEY_READ, &inputKey) == ERROR_SUCCESS)
|
if (RegOpenKeyExA(rootKey, REGKEY_INPUT, 0, KEY_READ, &inputKey) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
if (GetDWORDRegKey(inputKey, REGKEY_MOUSE_SENSITIVITY, &mouseSensitivity, GameConfiguration::DEFAULT_MOUSE_SENSITIVITY) != 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(rootKey);
|
||||||
RegCloseKey(graphicsKey);
|
RegCloseKey(graphicsKey);
|
||||||
|
|
|
@ -46,7 +46,7 @@ constexpr auto REGKEY_ENABLE_THUMBSTICK_CAMERA = "EnableThumbstickCamera";
|
||||||
// Input keys
|
// Input keys
|
||||||
|
|
||||||
constexpr auto REGKEY_MOUSE_SENSITIVITY = "MouseSensitivity";
|
constexpr auto REGKEY_MOUSE_SENSITIVITY = "MouseSensitivity";
|
||||||
constexpr auto REGKEY_ENABLE_MENU_OPTION_LOOPING = "EnableMenuOptionLooping";
|
constexpr auto REGKEY_MENU_OPTION_LOOPING_MODE = "MenuOptionLoopingMode";
|
||||||
|
|
||||||
enum class MenuOptionLoopingMode
|
enum class MenuOptionLoopingMode
|
||||||
{
|
{
|
||||||
|
|
|
@ -340,6 +340,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"</Command>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Game\collision\Point.h" />
|
<ClInclude Include="Game\collision\Point.h" />
|
||||||
|
<ClInclude Include="Game\collision\Sphere.h" />
|
||||||
<ClInclude Include="Game\Debug\Debug.h" />
|
<ClInclude Include="Game\Debug\Debug.h" />
|
||||||
<ClInclude Include="Game\effects\Bubble.h" />
|
<ClInclude Include="Game\effects\Bubble.h" />
|
||||||
<ClInclude Include="Game\effects\DisplaySprite.h" />
|
<ClInclude Include="Game\effects\DisplaySprite.h" />
|
||||||
|
@ -377,7 +378,6 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"</Command>
|
||||||
<ClInclude Include="Game\collision\collide_item.h" />
|
<ClInclude Include="Game\collision\collide_item.h" />
|
||||||
<ClInclude Include="Game\collision\collide_room.h" />
|
<ClInclude Include="Game\collision\collide_room.h" />
|
||||||
<ClInclude Include="Game\collision\floordata.h" />
|
<ClInclude Include="Game\collision\floordata.h" />
|
||||||
<ClInclude Include="Game\collision\sphere.h" />
|
|
||||||
<ClInclude Include="Game\control\box.h" />
|
<ClInclude Include="Game\control\box.h" />
|
||||||
<ClInclude Include="Game\control\control.h" />
|
<ClInclude Include="Game\control\control.h" />
|
||||||
<ClInclude Include="Game\control\flipeffect.h" />
|
<ClInclude Include="Game\control\flipeffect.h" />
|
||||||
|
@ -862,7 +862,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"</Command>
|
||||||
<ClCompile Include="Game\collision\collide_room.cpp" />
|
<ClCompile Include="Game\collision\collide_room.cpp" />
|
||||||
<ClCompile Include="Game\collision\floordata.cpp" />
|
<ClCompile Include="Game\collision\floordata.cpp" />
|
||||||
<ClCompile Include="Game\collision\Point.cpp" />
|
<ClCompile Include="Game\collision\Point.cpp" />
|
||||||
<ClCompile Include="Game\collision\sphere.cpp" />
|
<ClCompile Include="Game\collision\Sphere.cpp" />
|
||||||
<ClCompile Include="Game\control\box.cpp" />
|
<ClCompile Include="Game\control\box.cpp" />
|
||||||
<ClCompile Include="Game\control\control.cpp" />
|
<ClCompile Include="Game\control\control.cpp" />
|
||||||
<ClCompile Include="Game\control\flipeffect.cpp" />
|
<ClCompile Include="Game\control\flipeffect.cpp" />
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue