mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-04-28 15:57:59 +03:00
Merge branch 'master' into very_experimental_input_stuff
This commit is contained in:
commit
0fe92bfa82
30 changed files with 424 additions and 453 deletions
|
@ -1,8 +1,15 @@
|
|||
Version 1.0.3
|
||||
=============
|
||||
|
||||
* Fix dodgy weapon lock angle constraints.
|
||||
* Fix wrong shotgun ammo pickup amount.
|
||||
|
||||
|
||||
Version 1.0.2
|
||||
=============
|
||||
|
||||
* Removing Pistols with TakeItem and SetItemCount now works correctly.
|
||||
* Vec3s can now be saved and loaded in LevelVars and GameVars.
|
||||
* Fix removing Pistols with TakeItem and SetItemCount.
|
||||
* Allow saving and loading of Vec3s in LevelVars and GameVars.
|
||||
* Support volume triggers made with node editor.
|
||||
* Adjust max turn rate of idle state.
|
||||
* Align Lara on slopes when crouching, crawling, and dying.
|
||||
|
@ -27,28 +34,30 @@ Version 1.0.2
|
|||
|
||||
* Fix incorrect pole mounting.
|
||||
* Fix zeroed forward velocity upon landing.
|
||||
* Fix incorrect behaviour when falling on statics from the top after monkeyswing.
|
||||
* Fix missing animcommand calls on first animation frame.
|
||||
* Fix 1-frame turn rate delays.
|
||||
* Fix occasional leave event calls when moving closer to volumes.
|
||||
* Fix incorrect viewport size in windowed mode.
|
||||
* Fix late landing animation dispatch in rare cases.
|
||||
* Fix Lara's subway train death so that she no longer slides slowly after the animation has finished.
|
||||
* Fix incorrect velocity calculations for death animations.
|
||||
* Fix horseman's axe attack using his left foot as the damaging joint.
|
||||
* Fix stargate blades needlessly pushing the player around while hardly doing any damage.
|
||||
* Fix weapon hotkeys and add missing crossbow hotkey.
|
||||
|
||||
Lua API changes:
|
||||
|
||||
* Util.ShortenTENCalls no longer needs to be called; it is now automatic.
|
||||
* Util.ShortenTENCalls no longer needs to be called; it is now automatic for both level scripts and Gameflow.lua.
|
||||
* Flow.InvID has been removed; any function taking a pickup (e.g. GiveItem) now takes an Objects.ObjID instead.
|
||||
* Added Enable, Disable, GetActive, Get/SetSolid functions for static meshes.
|
||||
* Added FadeOutComplete, StopAudioTrack and StopAudioTracks functions.
|
||||
* Add Enable, Disable, GetActive, Get/SetSolid functions for static meshes.
|
||||
* Add FadeOutComplete, StopAudioTrack and StopAudioTracks functions.
|
||||
* Account for objects in HasLineOfSight tests.
|
||||
* Timer.lua, EventSequence.lua and Util.lua have been moved to a subfolder, Engine.
|
||||
* Move Timer.lua, EventSequence.lua and Util.lua to a subfolder named "Engine".
|
||||
* LevelFuncs can now contain tables as well as functions. These tables can contain functions and other tables, and so forth.
|
||||
* Moveable functions SetOnHit, SetOnKilled, SetOnCollidedWithObject and SetOnCollidedWithRoom no longer take strings, and instead take function objects themselves.
|
||||
* EventSequence and Timer no longer require you to call Timer.UpdateAll in OnControlPhase.
|
||||
* TEN.Logic.AddCallback and TEN.Logic.RemoveCallback have been added.
|
||||
* GiveItem, TakeItem, and SetItemCount have been reworked (e.g. SetItemCount with a value of -1 can give infinite ammo/consumables).
|
||||
* Don't require EventSequence and Timer to call Timer.UpdateAll in OnControlPhase.
|
||||
* Add TEN.Logic.AddCallback and TEN.Logic.RemoveCallback.
|
||||
* Rework GiveItem, TakeItem, and SetItemCount (e.g. SetItemCount with a value of -1 can give infinite ammo/consumables).
|
||||
|
||||
|
||||
Version 1.0.1
|
||||
=============
|
||||
|
|
|
@ -15,6 +15,8 @@ TombEngine (TEN) is a new, open-source engine which aims to abolish all limits,
|
|||
|
||||
TEN is based on the Tomb Raider: Chronicles engine of the classic era and continues to build upon and replace its systems to modernize ...
|
||||
|
||||
If you would like to participate in TEN discussion with other TEN devs whether it is contributing or bugs, then join this discord server: https://discord.gg/apjBW2NsVj and head to #tombengine channel.
|
||||
|
||||
# Compiling TombEngine
|
||||
To compile TEN, ensure you have installed:
|
||||
- Microsoft Visual Studio
|
||||
|
@ -75,9 +77,11 @@ We do not and have never worked for Core Design, Eidos Interactive, or Square En
|
|||
## Assets and Miscellaneous
|
||||
|
||||
### Animations
|
||||
- SrDanielPonces (Diagonal shimmy transitions)
|
||||
- SrDanielPonces (Diagonal shimmy transitions, backwards monkey swinging)
|
||||
- Krystian (Flexibility crawlspace, slope climbing animations)
|
||||
- Sezz (Additional Animations for player state refactoring)
|
||||
- Naotheia (Underwater puzzle placement, crouch 180° turn, crawl 180° turn, water surface 180° turn)
|
||||
- JoeyQuint (Standing 180° turn, monkey swing 180° turn)
|
||||
|
||||
### TombEngine Wiki tutorials
|
||||
- Kubsy (Lua Basics tutorial)
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
-- Place in this LUA script all the levels of your game
|
||||
-- Place in this Lua script all the levels of your game
|
||||
-- Title is mandatory and must be the first level.
|
||||
|
||||
-- Shorten some of the internal data types.
|
||||
|
||||
local Flow = TEN.Flow
|
||||
local Level = Flow.Level
|
||||
local Color = TEN.Color
|
||||
local Rotation = TEN.Rotation
|
||||
local InventoryItem = Flow.InventoryItem
|
||||
local ObjID = TEN.Objects.ObjID
|
||||
local RotationAxis = Flow.RotationAxis
|
||||
local ItemAction = Flow.ItemAction
|
||||
|
||||
-- Intro image is a splash screen which appears before actual loading screen.
|
||||
-- If you don't want it to appear, just remove this line.
|
||||
|
||||
|
|
|
@ -95,3 +95,4 @@ void LaraWaterSurface(ItemInfo* item, CollisionInfo* coll);
|
|||
void LaraUnderwater(ItemInfo* item, CollisionInfo* coll);
|
||||
void LaraCheat(ItemInfo* item, CollisionInfo* coll);
|
||||
void AnimateLara(ItemInfo* item);
|
||||
void PerformAnimCommands(ItemInfo* item, bool frameBased);
|
|
@ -51,6 +51,23 @@ bool LaraDeflectEdge(ItemInfo* item, CollisionInfo* coll)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool LaraDeflectTopSide(ItemInfo* item, CollisionInfo* coll)
|
||||
{
|
||||
// HACK: If we are falling down, collision is CT_CLAMP and
|
||||
// HitStatic flag is set, it means we've collided static from the top.
|
||||
|
||||
if (coll->CollisionType == CT_CLAMP &&
|
||||
coll->HitStatic && item->Animation.Velocity.y > 0.0f)
|
||||
{
|
||||
SetAnimation(item, LA_JUMP_WALL_SMASH_START, 1);
|
||||
Rumble(0.5f, 0.15f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LaraDeflectEdgeJump(ItemInfo* item, CollisionInfo* coll)
|
||||
{
|
||||
auto* lara = GetLaraInfo(item);
|
||||
|
@ -60,16 +77,21 @@ bool LaraDeflectEdgeJump(ItemInfo* item, CollisionInfo* coll)
|
|||
|
||||
if (coll->CollisionType == CT_FRONT || coll->CollisionType == CT_TOP_FRONT)
|
||||
{
|
||||
if (!lara->Control.CanClimbLadder || item->Animation.Velocity.z != 2)
|
||||
if (!lara->Control.CanClimbLadder || item->Animation.Velocity.z != 2.0f)
|
||||
{
|
||||
if (coll->Middle.Floor <= CLICK(1))
|
||||
{
|
||||
SetAnimation(item, LA_LAND);
|
||||
LaraSnapToHeight(item, coll);
|
||||
if (TestLaraSlide(item, coll))
|
||||
SetLaraSlideAnimation(item, coll);
|
||||
else
|
||||
{
|
||||
SetAnimation(item, LA_LAND);
|
||||
LaraSnapToHeight(item, coll);
|
||||
}
|
||||
}
|
||||
else if (abs(item->Animation.Velocity.z) > 47)
|
||||
// TODO: Demagic. This is Lara's running velocity. Jumps have a minimum of 50.
|
||||
else if (abs(item->Animation.Velocity.z) > 47.0f)
|
||||
{
|
||||
// TODO: Demagic. This is Lara's running velocity. Jumps have a minimum of 50.
|
||||
SetAnimation(item, LA_JUMP_WALL_SMASH_START, 1);
|
||||
Rumble(0.5f, 0.15f);
|
||||
}
|
||||
|
@ -77,8 +99,8 @@ bool LaraDeflectEdgeJump(ItemInfo* item, CollisionInfo* coll)
|
|||
item->Animation.Velocity.z /= 4;
|
||||
lara->Control.MoveAngle += ANGLE(180.0f);
|
||||
|
||||
if (item->Animation.Velocity.y <= 0)
|
||||
item->Animation.Velocity.y = 1;
|
||||
if (item->Animation.Velocity.y <= 0.0f)
|
||||
item->Animation.Velocity.y = 1.0f;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -96,19 +118,19 @@ bool LaraDeflectEdgeJump(ItemInfo* item, CollisionInfo* coll)
|
|||
|
||||
case CT_TOP:
|
||||
case CT_TOP_FRONT:
|
||||
if (item->Animation.Velocity.y <= 0)
|
||||
item->Animation.Velocity.y = 1;
|
||||
if (item->Animation.Velocity.y <= 0.0f)
|
||||
item->Animation.Velocity.y = 1.0f;
|
||||
|
||||
break;
|
||||
|
||||
case CT_CLAMP:
|
||||
item->Pose.Position.z += CLICK(1.5f) * phd_cos(item->Pose.Orientation.y + ANGLE(180.0f));
|
||||
item->Pose.Position.x += CLICK(1.5f) * phd_sin(item->Pose.Orientation.y + ANGLE(180.0f));
|
||||
item->Animation.Velocity.z = 0;
|
||||
coll->Middle.Floor = 0;
|
||||
item->Animation.Velocity.z = 0.0f;
|
||||
coll->Middle.Floor = 0.0f;
|
||||
|
||||
if (item->Animation.Velocity.y <= 0)
|
||||
item->Animation.Velocity.y = 16;
|
||||
if (item->Animation.Velocity.y <= 0.0f)
|
||||
item->Animation.Velocity.y = 16.0f;
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ constexpr auto DEFLECT_DIAGONAL_ANGLE_CRAWL = 5.0f;
|
|||
|
||||
bool LaraDeflectEdge(ItemInfo* item, CollisionInfo* coll);
|
||||
bool LaraDeflectEdgeJump(ItemInfo* item, CollisionInfo* coll);
|
||||
bool LaraDeflectTopSide(ItemInfo* item, CollisionInfo* coll);
|
||||
void LaraSlideEdgeJump(ItemInfo* item, CollisionInfo* coll);
|
||||
bool LaraDeflectEdgeCrawl(ItemInfo* item, CollisionInfo* coll);
|
||||
bool LaraDeflectEdgeMonkey(ItemInfo* item, CollisionInfo* coll);
|
||||
|
|
|
@ -58,7 +58,7 @@ WeaponInfo Weapons[(int)LaraWeaponType::NumWeapons] =
|
|||
|
||||
// Pistols
|
||||
{
|
||||
{ Vector3Shrt(ANGLE(-60.0f), ANGLE(-60.0f), 0), Vector3Shrt(ANGLE(60.0f), ANGLE(60.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-80.0f), ANGLE(-60.0f), 0), Vector3Shrt(ANGLE(80.0f), ANGLE(60.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-80.0f), ANGLE(-170.0f), 0), Vector3Shrt(ANGLE(80.0f), ANGLE(60.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-80.0f), ANGLE(-60.0f), 0), Vector3Shrt(ANGLE(80.0f), ANGLE(170.0f), 0) },
|
||||
ANGLE(10.0f),
|
||||
|
@ -75,7 +75,7 @@ WeaponInfo Weapons[(int)LaraWeaponType::NumWeapons] =
|
|||
|
||||
// Revolver
|
||||
{
|
||||
{ Vector3Shrt(ANGLE(-60.0f), ANGLE(-60.0f), 0), Vector3Shrt(ANGLE(60.0f), ANGLE(60.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-80.0f), ANGLE(-60.0f), 0), Vector3Shrt(ANGLE(80.0f), ANGLE(60.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-80.0f), ANGLE(-10.0f), 0), Vector3Shrt(ANGLE(80.0f), ANGLE(10.0f), 0) },
|
||||
{ Vector3Shrt::Zero, Vector3Shrt::Zero },
|
||||
ANGLE(10.0f),
|
||||
|
@ -92,7 +92,7 @@ WeaponInfo Weapons[(int)LaraWeaponType::NumWeapons] =
|
|||
|
||||
// Uzis
|
||||
{
|
||||
{ Vector3Shrt(ANGLE(-60.0f), ANGLE(-60.0f), 0), Vector3Shrt(ANGLE(60.0f), ANGLE(60.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-80.0f), ANGLE(-60.0f), 0), Vector3Shrt(ANGLE(80.0f), ANGLE(60.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-80.0f), ANGLE(-170.0f), 0), Vector3Shrt(ANGLE(80.0f), ANGLE(60.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-80.0f), ANGLE(-60.0f), 0), Vector3Shrt(ANGLE(80.0f), ANGLE(170.0f), 0) },
|
||||
ANGLE(10.0f),
|
||||
|
@ -109,9 +109,9 @@ WeaponInfo Weapons[(int)LaraWeaponType::NumWeapons] =
|
|||
|
||||
// Shotgun
|
||||
{
|
||||
{ Vector3Shrt(ANGLE(-55.0f), ANGLE(-60.0f), 0), Vector3Shrt(ANGLE(55.0f), ANGLE(60.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-65.0f), ANGLE(-80.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(80.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-65.0f), ANGLE(-80.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(80.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-70.0f), ANGLE(-60.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(60.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-70.0f), ANGLE(-80.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(80.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-70.0f), ANGLE(-80.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(80.0f), 0) },
|
||||
ANGLE(10.0f),
|
||||
0,
|
||||
500,
|
||||
|
@ -126,9 +126,9 @@ WeaponInfo Weapons[(int)LaraWeaponType::NumWeapons] =
|
|||
|
||||
// HK
|
||||
{
|
||||
{ Vector3Shrt(ANGLE(-55.0f), ANGLE(-60.0f), 0), Vector3Shrt(ANGLE(55.0f), ANGLE(60.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-65.0f), ANGLE(-80.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(80.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-65.0f), ANGLE(-80.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(80.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-70.0f), ANGLE(-60.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(60.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-70.0f), ANGLE(-80.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(80.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-70.0f), ANGLE(-80.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(80.0f), 0) },
|
||||
ANGLE(10.0f),
|
||||
ANGLE(4.0f),
|
||||
500,
|
||||
|
@ -143,9 +143,9 @@ WeaponInfo Weapons[(int)LaraWeaponType::NumWeapons] =
|
|||
|
||||
// Crossbow
|
||||
{
|
||||
{ Vector3Shrt(ANGLE(-55.0f), ANGLE(-60.0f), 0), Vector3Shrt(ANGLE(55.0f), ANGLE(60.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-65.0f), ANGLE(-80.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(80.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-65.0f), ANGLE(-80.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(80.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-70.0f), ANGLE(-60.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(60.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-70.0f), ANGLE(-80.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(80.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-70.0f), ANGLE(-80.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(80.0f), 0) },
|
||||
ANGLE(10.0f),
|
||||
ANGLE(8.0f),
|
||||
500,
|
||||
|
@ -194,9 +194,9 @@ WeaponInfo Weapons[(int)LaraWeaponType::NumWeapons] =
|
|||
|
||||
// Grenade launcher
|
||||
{
|
||||
{ Vector3Shrt(ANGLE(-55.0f), ANGLE(-60.0f), 0), Vector3Shrt(ANGLE(55.0f), ANGLE(60.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-65.0f), ANGLE(-80.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(80.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-65.0f), ANGLE(-80.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(80.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-70.0f), ANGLE(-60.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(60.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-70.0f), ANGLE(-80.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(80.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-70.0f), ANGLE(-80.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(80.0f), 0) },
|
||||
ANGLE(10.0f),
|
||||
ANGLE(8.0f),
|
||||
500,
|
||||
|
@ -211,7 +211,7 @@ WeaponInfo Weapons[(int)LaraWeaponType::NumWeapons] =
|
|||
|
||||
// Harpoon gun
|
||||
{
|
||||
{ Vector3Shrt(ANGLE(-65.0f), ANGLE(-60.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(60.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-75.0f), ANGLE(-60.0f), 0), Vector3Shrt(ANGLE(75.0f), ANGLE(60.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-75.0f), ANGLE(-20.0f), 0), Vector3Shrt(ANGLE(75.0f), ANGLE(20.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-75.0f), ANGLE(-80.0f), 0), Vector3Shrt(ANGLE(75.0f), ANGLE(80.0f), 0) },
|
||||
ANGLE(10.0f),
|
||||
|
@ -228,9 +228,9 @@ WeaponInfo Weapons[(int)LaraWeaponType::NumWeapons] =
|
|||
|
||||
// Rocket launcher
|
||||
{
|
||||
{ Vector3Shrt(ANGLE(-55.0f), ANGLE(-60.0f), 0), Vector3Shrt(ANGLE(55.0f), ANGLE(60.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-65.0f), ANGLE(-80.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(80.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-65.0f), ANGLE(-80.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(80.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-70.0f), ANGLE(-60.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(60.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-70.0f), ANGLE(-80.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(80.0f), 0) },
|
||||
{ Vector3Shrt(ANGLE(-70.0f), ANGLE(-80.0f), 0), Vector3Shrt(ANGLE(65.0f), ANGLE(80.0f), 0) },
|
||||
ANGLE(10.0f),
|
||||
ANGLE(8.0f),
|
||||
500,
|
||||
|
@ -981,10 +981,10 @@ void LaraTargetInfo(ItemInfo* laraItem, WeaponInfo* weaponInfo)
|
|||
|
||||
if (LOS(&origin, &target))
|
||||
{
|
||||
if (angles.x >= weaponInfo->LockAngles[0].x &&
|
||||
angles.y >= weaponInfo->LockAngles[0].y &&
|
||||
angles.x <= weaponInfo->LockAngles[1].x &&
|
||||
angles.y <= weaponInfo->LockAngles[1].y)
|
||||
if (angles.x >= weaponInfo->LockOrientConstraint.first.x &&
|
||||
angles.y >= weaponInfo->LockOrientConstraint.first.y &&
|
||||
angles.x <= weaponInfo->LockOrientConstraint.second.x &&
|
||||
angles.y <= weaponInfo->LockOrientConstraint.second.y)
|
||||
{
|
||||
lara->RightArm.Locked = true;
|
||||
lara->LeftArm.Locked = true;
|
||||
|
@ -993,10 +993,10 @@ void LaraTargetInfo(ItemInfo* laraItem, WeaponInfo* weaponInfo)
|
|||
{
|
||||
if (lara->LeftArm.Locked)
|
||||
{
|
||||
if (angles.x < weaponInfo->LeftAngles[0].x ||
|
||||
angles.y < weaponInfo->LeftAngles[0].y ||
|
||||
angles.x > weaponInfo->LeftAngles[1].x ||
|
||||
angles.y > weaponInfo->LeftAngles[1].y)
|
||||
if (angles.x < weaponInfo->LeftOrientConstraint.first.x ||
|
||||
angles.y < weaponInfo->LeftOrientConstraint.first.y ||
|
||||
angles.x > weaponInfo->LeftOrientConstraint.second.x ||
|
||||
angles.y > weaponInfo->LeftOrientConstraint.second.y)
|
||||
{
|
||||
lara->LeftArm.Locked = false;
|
||||
}
|
||||
|
@ -1004,10 +1004,10 @@ void LaraTargetInfo(ItemInfo* laraItem, WeaponInfo* weaponInfo)
|
|||
|
||||
if (lara->RightArm.Locked)
|
||||
{
|
||||
if (angles.x < weaponInfo->RightAngles[0].x ||
|
||||
angles.y < weaponInfo->RightAngles[0].y ||
|
||||
angles.x > weaponInfo->RightAngles[1].x ||
|
||||
angles.y > weaponInfo->RightAngles[1].y)
|
||||
if (angles.x < weaponInfo->RightOrientConstraint.first.x ||
|
||||
angles.y < weaponInfo->RightOrientConstraint.first.y ||
|
||||
angles.x > weaponInfo->RightOrientConstraint.second.x ||
|
||||
angles.y > weaponInfo->RightOrientConstraint.second.y)
|
||||
{
|
||||
lara->RightArm.Locked = false;
|
||||
}
|
||||
|
@ -1076,10 +1076,10 @@ void LaraGetNewTarget(ItemInfo* laraItem, WeaponInfo* weaponInfo)
|
|||
angles.x -= laraItem->Pose.Orientation.x + lara->ExtraTorsoRot.x;
|
||||
angles.y -= laraItem->Pose.Orientation.y + lara->ExtraTorsoRot.y;
|
||||
|
||||
if (angles.x >= weaponInfo->LockAngles[0].x &&
|
||||
angles.y >= weaponInfo->LockAngles[0].y &&
|
||||
angles.x <= weaponInfo->LockAngles[1].x &&
|
||||
angles.y <= weaponInfo->LockAngles[1].y)
|
||||
if (angles.x >= weaponInfo->LockOrientConstraint.first.x &&
|
||||
angles.y >= weaponInfo->LockOrientConstraint.first.y &&
|
||||
angles.x <= weaponInfo->LockOrientConstraint.second.x &&
|
||||
angles.y <= weaponInfo->LockOrientConstraint.second.y)
|
||||
{
|
||||
TargetList[targets] = item;
|
||||
++targets;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
#include "Game/Lara/lara.h"
|
||||
|
||||
using std::pair;
|
||||
|
||||
struct CollisionInfo;
|
||||
struct ItemInfo;
|
||||
struct Vector3Shrt;
|
||||
|
@ -16,9 +18,9 @@ enum class FireWeaponType
|
|||
|
||||
struct WeaponInfo
|
||||
{
|
||||
Vector3Shrt LockAngles[2];
|
||||
Vector3Shrt LeftAngles[2];
|
||||
Vector3Shrt RightAngles[2];
|
||||
pair<Vector3Shrt, Vector3Shrt> LockOrientConstraint = {};
|
||||
pair<Vector3Shrt, Vector3Shrt> LeftOrientConstraint = {};
|
||||
pair<Vector3Shrt, Vector3Shrt> RightOrientConstraint = {};
|
||||
|
||||
int AimSpeed;
|
||||
short ShotAccuracy;
|
||||
|
|
|
@ -639,6 +639,8 @@ void lara_col_jump_up(ItemInfo* item, CollisionInfo* coll)
|
|||
if (TestLaraHangJumpUp(item, coll))
|
||||
return;
|
||||
|
||||
LaraDeflectTopSide(item, coll);
|
||||
|
||||
if (coll->Middle.Ceiling >= 0 ||
|
||||
coll->CollisionType == CT_TOP ||
|
||||
coll->CollisionType == CT_TOP_FRONT ||
|
||||
|
|
|
@ -44,7 +44,7 @@ void AnimateShotgun(ItemInfo* laraItem, LaraWeaponType weaponType)
|
|||
|
||||
if (lara->LeftArm.GunSmoke > 0)
|
||||
{
|
||||
Vector3Int pos;
|
||||
auto pos = Vector3Int::Zero;
|
||||
if (weaponType == LaraWeaponType::HK)
|
||||
pos = Vector3Int(0, 228, 96);
|
||||
else if (weaponType == LaraWeaponType::Shotgun)
|
||||
|
@ -263,8 +263,8 @@ void ReadyShotgun(ItemInfo* laraItem, LaraWeaponType weaponType)
|
|||
auto* lara = GetLaraInfo(laraItem);
|
||||
|
||||
lara->Control.HandStatus = HandStatus::WeaponReady;
|
||||
lara->LeftArm.Orientation = Vector3Shrt();
|
||||
lara->RightArm.Orientation = Vector3Shrt();
|
||||
lara->LeftArm.Orientation = Vector3Shrt::Zero;
|
||||
lara->RightArm.Orientation = Vector3Shrt::Zero;
|
||||
lara->LeftArm.FrameNumber = 0;
|
||||
lara->RightArm.FrameNumber = 0;
|
||||
lara->LeftArm.Locked = false;
|
||||
|
@ -340,7 +340,7 @@ void DrawShotgun(ItemInfo* laraItem, LaraWeaponType weaponType)
|
|||
{
|
||||
auto* lara = GetLaraInfo(laraItem);
|
||||
|
||||
ItemInfo* item;
|
||||
ItemInfo* item = nullptr;
|
||||
|
||||
if (lara->Control.Weapon.WeaponItem == NO_ITEM)
|
||||
{
|
||||
|
@ -446,8 +446,8 @@ void FireHarpoon(ItemInfo* laraItem)
|
|||
{
|
||||
auto* lara = GetLaraInfo(laraItem);
|
||||
|
||||
auto& ammos = GetAmmo(laraItem, LaraWeaponType::HarpoonGun);
|
||||
if (!ammos)
|
||||
auto& ammo = GetAmmo(laraItem, LaraWeaponType::HarpoonGun);
|
||||
if (!ammo)
|
||||
return;
|
||||
|
||||
lara->Control.Weapon.HasFired = true;
|
||||
|
@ -456,8 +456,8 @@ void FireHarpoon(ItemInfo* laraItem)
|
|||
short itemNumber = CreateItem();
|
||||
if (itemNumber != NO_ITEM)
|
||||
{
|
||||
if (!ammos.HasInfinite())
|
||||
(ammos)--;
|
||||
if (!ammo.HasInfinite())
|
||||
ammo--;
|
||||
|
||||
auto* item = &g_Level.Items[itemNumber];
|
||||
|
||||
|
@ -651,7 +651,7 @@ void FireGrenade(ItemInfo* laraItem)
|
|||
int y = 0;
|
||||
int z = 0;
|
||||
|
||||
Ammo& ammo = GetAmmo(laraItem, LaraWeaponType::GrenadeLauncher);
|
||||
auto& ammo = GetAmmo(laraItem, LaraWeaponType::GrenadeLauncher);
|
||||
if (!ammo)
|
||||
return;
|
||||
|
||||
|
@ -718,7 +718,7 @@ void FireGrenade(ItemInfo* laraItem)
|
|||
AddActiveItem(itemNumber);
|
||||
|
||||
if (!ammo.HasInfinite())
|
||||
(ammo)--;
|
||||
ammo--;
|
||||
|
||||
item->ItemFlags[0] = (int)lara->Weapons[(int)LaraWeaponType::GrenadeLauncher].SelectedAmmo;
|
||||
|
||||
|
@ -817,16 +817,16 @@ void GrenadeControl(short itemNumber)
|
|||
{
|
||||
aboveWater = false;
|
||||
someFlag = false;
|
||||
item->Animation.Velocity.y += (5.0f - item->Animation.Velocity.y) / 2.0f;
|
||||
item->Animation.Velocity.z -= item->Animation.Velocity.z / 4.0f;
|
||||
item->Animation.Velocity.y += (5.0f - item->Animation.Velocity.y) / 2;
|
||||
item->Animation.Velocity.z -= item->Animation.Velocity.z / 4;
|
||||
|
||||
if (item->Animation.Velocity.z)
|
||||
{
|
||||
item->Pose.Orientation.z += (short((item->Animation.Velocity.z / 16.0f) + 3.0f) * ANGLE(1.0f));
|
||||
item->Pose.Orientation.z += (short((item->Animation.Velocity.z / 16) + 3.0f) * ANGLE(1.0f));
|
||||
if (item->Animation.RequiredState)
|
||||
item->Pose.Orientation.y += (short((item->Animation.Velocity.z / 4.0f) + 3.0f) * ANGLE(1.0f));
|
||||
item->Pose.Orientation.y += (short((item->Animation.Velocity.z / 4) + 3.0f) * ANGLE(1.0f));
|
||||
else
|
||||
item->Pose.Orientation.x += (short((item->Animation.Velocity.z / 4.0f) + 3.0f) * ANGLE(1.0f));
|
||||
item->Pose.Orientation.x += (short((item->Animation.Velocity.z / 4) + 3.0f) * ANGLE(1.0f));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -837,11 +837,11 @@ void GrenadeControl(short itemNumber)
|
|||
|
||||
if (item->Animation.Velocity.z)
|
||||
{
|
||||
item->Pose.Orientation.z += (short((item->Animation.Velocity.z / 4.0f) + 7.0f) * ANGLE(1.0f));
|
||||
item->Pose.Orientation.z += (short((item->Animation.Velocity.z / 4) + 7.0f) * ANGLE(1.0f));
|
||||
if (item->Animation.RequiredState)
|
||||
item->Pose.Orientation.y += (short((item->Animation.Velocity.z / 2.0f) + 7.0f) * ANGLE(1.0f));
|
||||
item->Pose.Orientation.y += (short((item->Animation.Velocity.z / 2) + 7.0f) * ANGLE(1.0f));
|
||||
else
|
||||
item->Pose.Orientation.x += (short((item->Animation.Velocity.z / 2.0f) + 7.0f) * ANGLE(1.0f));
|
||||
item->Pose.Orientation.x += (short((item->Animation.Velocity.z / 2) + 7.0f) * ANGLE(1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1057,7 +1057,7 @@ void GrenadeControl(short itemNumber)
|
|||
SoundEffect(SFX_TR4_EXPLOSION1, &item->Pose, SoundEnvironment::Land, 0.7f, 0.5f);
|
||||
SoundEffect(SFX_TR4_EXPLOSION2, &item->Pose);
|
||||
|
||||
// Setup the counter for spawned grenades in the case of flash and super grenades ammos
|
||||
// Setup the counter for spawned grenades in the case of flash and super grenades ammo
|
||||
if (item->ItemFlags[0] != (int)GrenadeType::Normal && item->ItemFlags[0] != (int)GrenadeType::Ultra)
|
||||
{
|
||||
item->MeshBits = 0;
|
||||
|
@ -1074,8 +1074,8 @@ void FireRocket(ItemInfo* laraItem)
|
|||
{
|
||||
auto* lara = GetLaraInfo(laraItem);
|
||||
|
||||
auto& ammos = GetAmmo(laraItem, LaraWeaponType::RocketLauncher);
|
||||
if (!ammos)
|
||||
auto& ammo = GetAmmo(laraItem, LaraWeaponType::RocketLauncher);
|
||||
if (!ammo)
|
||||
return;
|
||||
|
||||
lara->Control.Weapon.HasFired = true;
|
||||
|
@ -1087,8 +1087,8 @@ void FireRocket(ItemInfo* laraItem)
|
|||
item->ObjectNumber = ID_ROCKET;
|
||||
item->RoomNumber = laraItem->RoomNumber;
|
||||
|
||||
if (!ammos.HasInfinite())
|
||||
(ammos)--;
|
||||
if (!ammo.HasInfinite())
|
||||
ammo--;
|
||||
|
||||
auto jointPos = Vector3Int(0, 180, 72);
|
||||
GetLaraJointPosition(&jointPos, LM_RHAND);
|
||||
|
@ -1175,7 +1175,7 @@ void RocketControl(short itemNumber)
|
|||
item->Color = Vector4(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
|
||||
// Calculate offset in rocket direction for fire and smoke sparks
|
||||
Matrix world = Matrix::CreateFromYawPitchRoll(
|
||||
auto world = Matrix::CreateFromYawPitchRoll(
|
||||
TO_RAD(item->Pose.Orientation.y - ANGLE(180.0f)),
|
||||
TO_RAD(item->Pose.Orientation.x),
|
||||
TO_RAD(item->Pose.Orientation.z)
|
||||
|
@ -1354,8 +1354,8 @@ void FireCrossbow(ItemInfo* laraItem, PHD_3DPOS* pos)
|
|||
{
|
||||
auto* lara = GetLaraInfo(laraItem);
|
||||
|
||||
auto& ammos = GetAmmo(laraItem, LaraWeaponType::Crossbow);
|
||||
if (!ammos)
|
||||
auto& ammo = GetAmmo(laraItem, LaraWeaponType::Crossbow);
|
||||
if (!ammo)
|
||||
return;
|
||||
|
||||
lara->Control.Weapon.HasFired = true;
|
||||
|
@ -1367,8 +1367,8 @@ void FireCrossbow(ItemInfo* laraItem, PHD_3DPOS* pos)
|
|||
item->ObjectNumber = ID_CROSSBOW_BOLT;
|
||||
item->Color = Vector4(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
|
||||
if (!ammos.HasInfinite())
|
||||
(ammos)--;
|
||||
if (!ammo.HasInfinite())
|
||||
ammo--;
|
||||
|
||||
if (pos)
|
||||
{
|
||||
|
@ -1422,7 +1422,7 @@ void FireCrossbow(ItemInfo* laraItem, PHD_3DPOS* pos)
|
|||
}
|
||||
}
|
||||
|
||||
void FireCrossBowFromLaserSight(ItemInfo* laraItem, GameVector* src, GameVector* target)
|
||||
void FireCrossBowFromLaserSight(ItemInfo* laraItem, GameVector* origin, GameVector* target)
|
||||
{
|
||||
/* this part makes arrows fire at bad angles
|
||||
target->x &= ~1023;
|
||||
|
@ -1430,8 +1430,8 @@ void FireCrossBowFromLaserSight(ItemInfo* laraItem, GameVector* src, GameVector*
|
|||
target->x |= 512;
|
||||
target->z |= 512;*/
|
||||
|
||||
auto angles = GetVectorAngles(target->x - src->x, target->y - src->y, target->z - src->z);
|
||||
auto boltPose = PHD_3DPOS(src->x, src->y, src->z, angles);
|
||||
auto angles = GetVectorAngles(target->x - origin->x, target->y - origin->y, target->z - origin->z);
|
||||
auto boltPose = PHD_3DPOS(origin->x, origin->y, origin->z, angles);
|
||||
FireCrossbow(laraItem, &boltPose);
|
||||
}
|
||||
|
||||
|
@ -1440,13 +1440,13 @@ void CrossbowBoltControl(short itemNumber)
|
|||
auto* lara = GetLaraInfo(LaraItem);
|
||||
auto* item = &g_Level.Items[itemNumber];
|
||||
|
||||
// Store old position for later
|
||||
auto oldPos = item->Pose.Position;
|
||||
// Store previous position for later.
|
||||
auto prevPos = item->Pose.Position;
|
||||
|
||||
bool aboveWater = false;
|
||||
bool explode = false;
|
||||
|
||||
// Update speed and check if above water
|
||||
// Update speed and check if above water.
|
||||
if (TestEnvironment(ENV_FLAG_WATER, item))
|
||||
{
|
||||
auto bubblePos = item->Pose.Position;
|
||||
|
@ -1471,9 +1471,9 @@ void CrossbowBoltControl(short itemNumber)
|
|||
probe.Position.Ceiling > item->Pose.Position.y)
|
||||
{
|
||||
// I have hit a solid wall, this is the end for the bolt
|
||||
item->Pose.Position = oldPos;
|
||||
item->Pose.Position = prevPos;
|
||||
|
||||
// If ammos are normal, then just shatter the bolt and quit
|
||||
// If ammo is normal, simply shatter the bolt and exit.
|
||||
if (item->ItemFlags[0] != (int)CrossbowBoltType::Explosive)
|
||||
{
|
||||
ExplodeItemNode(item, 0, 0, BODY_EXPLODE);
|
||||
|
@ -1510,7 +1510,7 @@ void CrossbowBoltControl(short itemNumber)
|
|||
|
||||
foundCollidedObjects = true;
|
||||
|
||||
// If explosive ammos selected and item hit, then blast everything
|
||||
// If explosive ammo selected and item hit, then blast everything
|
||||
if (item->ItemFlags[0] == (int)CrossbowBoltType::Explosive)
|
||||
explode = true;
|
||||
|
||||
|
@ -1541,7 +1541,7 @@ void CrossbowBoltControl(short itemNumber)
|
|||
// Normal hit
|
||||
HitTarget(LaraItem, currentItem, (GameVector*)& item->Pose, Weapons[(int)LaraWeaponType::Crossbow].Damage << item->ItemFlags[0], 0);
|
||||
|
||||
// Poisoned ammos
|
||||
// Poisone ammo
|
||||
if (item->ItemFlags[0] == (int)CrossbowBoltType::Poison)
|
||||
{
|
||||
if (currentItem->Data.is<CreatureInfo>())
|
||||
|
@ -1624,10 +1624,10 @@ void CrossbowBoltControl(short itemNumber)
|
|||
{
|
||||
TriggerShockwave(&item->Pose, 48, 304, 96, 0, 96, 128, 24, 0, 0);
|
||||
item->Pose.Position.y += 128;
|
||||
TriggerExplosionSparks(oldPos.x, oldPos.y, oldPos.z, 3, -2, 0, item->RoomNumber);
|
||||
TriggerExplosionSparks(prevPos.x, prevPos.y, prevPos.z, 3, -2, 0, item->RoomNumber);
|
||||
|
||||
for (int j = 0; j < 2; j++)
|
||||
TriggerExplosionSparks(oldPos.x, oldPos.y, oldPos.z, 3, -1, 0, item->RoomNumber);
|
||||
TriggerExplosionSparks(prevPos.x, prevPos.y, prevPos.z, 3, -1, 0, item->RoomNumber);
|
||||
}
|
||||
|
||||
AlertNearbyGuards(item);
|
||||
|
@ -1702,7 +1702,7 @@ void RifleHandler(ItemInfo* laraItem, LaraWeaponType weaponType)
|
|||
lara->ExtraTorsoRot.y = lara->LeftArm.Orientation.y;
|
||||
|
||||
if (Camera.oldType != CameraType::Look && !BinocularRange)
|
||||
lara->ExtraHeadRot = { 0, 0, 0 };
|
||||
lara->ExtraHeadRot = Vector3Shrt::Zero;
|
||||
}
|
||||
|
||||
if (weaponType == LaraWeaponType::Revolver)
|
||||
|
@ -1718,9 +1718,7 @@ void RifleHandler(ItemInfo* laraItem, LaraWeaponType weaponType)
|
|||
pos.y = -64;
|
||||
GetLaraJointPosition(&pos, LM_RHAND);
|
||||
TriggerDynamicLight(
|
||||
pos.x,
|
||||
pos.y,
|
||||
pos.z,
|
||||
pos.x, pos.y, pos.z,
|
||||
12,
|
||||
(GetRandomControl() & 0x3F) + 192,
|
||||
(GetRandomControl() & 0x1F) + 128,
|
||||
|
|
|
@ -57,7 +57,7 @@ void FireRocket(ItemInfo* laraItem);
|
|||
void RocketControl(short itemNumber);
|
||||
void FireCrossbow(ItemInfo* laraItem, PHD_3DPOS* pos);
|
||||
void CrossbowBoltControl(short itemNumber);
|
||||
void FireCrossBowFromLaserSight(ItemInfo* laraItem, GameVector* src, GameVector* target);
|
||||
void FireCrossBowFromLaserSight(ItemInfo* laraItem, GameVector* origin, GameVector* target);
|
||||
|
||||
void FireHK(ItemInfo* laraItem, int mode);
|
||||
void RifleHandler(ItemInfo* laraItem, LaraWeaponType weaponType);
|
||||
|
|
|
@ -22,6 +22,8 @@ void AnimateLara(ItemInfo* item)
|
|||
{
|
||||
auto* lara = GetLaraInfo(item);
|
||||
|
||||
PerformAnimCommands(item, true);
|
||||
|
||||
item->Animation.FrameNumber++;
|
||||
|
||||
auto* anim = &g_Level.Anims[item->Animation.AnimNumber];
|
||||
|
@ -33,47 +35,7 @@ void AnimateLara(ItemInfo* item)
|
|||
|
||||
if (item->Animation.FrameNumber > anim->frameEnd)
|
||||
{
|
||||
if (anim->numberCommands > 0)
|
||||
{
|
||||
short* cmd = &g_Level.Commands[anim->commandIndex];
|
||||
for (int i = anim->numberCommands; i > 0; i--)
|
||||
{
|
||||
switch (*(cmd++))
|
||||
{
|
||||
case COMMAND_MOVE_ORIGIN:
|
||||
TranslateItem(item, item->Pose.Orientation.y, cmd[2], cmd[1], cmd[0]);
|
||||
UpdateItemRoom(item, -LARA_HEIGHT / 2, -cmd[0], -cmd[2]);
|
||||
cmd += 3;
|
||||
break;
|
||||
|
||||
case COMMAND_JUMP_VELOCITY:
|
||||
item->Animation.Velocity.y = *(cmd++);
|
||||
item->Animation.Velocity.z = *(cmd++);
|
||||
item->Animation.IsAirborne = true;
|
||||
if (lara->Control.CalculatedJumpVelocity)
|
||||
{
|
||||
item->Animation.Velocity.y = lara->Control.CalculatedJumpVelocity;
|
||||
lara->Control.CalculatedJumpVelocity = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case COMMAND_ATTACK_READY:
|
||||
if (lara->Control.HandStatus != HandStatus::Special)
|
||||
lara->Control.HandStatus = HandStatus::Free;
|
||||
|
||||
break;
|
||||
|
||||
case COMMAND_SOUND_FX:
|
||||
case COMMAND_EFFECT:
|
||||
cmd += 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
PerformAnimCommands(item, false);
|
||||
|
||||
item->Animation.AnimNumber = anim->jumpAnimNum;
|
||||
item->Animation.FrameNumber = anim->jumpFrameNum;
|
||||
|
@ -82,70 +44,8 @@ void AnimateLara(ItemInfo* item)
|
|||
item->Animation.ActiveState = anim->ActiveState;
|
||||
}
|
||||
|
||||
if (anim->numberCommands > 0)
|
||||
{
|
||||
short* cmd = &g_Level.Commands[anim->commandIndex];
|
||||
|
||||
for (int i = anim->numberCommands; i > 0; i--)
|
||||
{
|
||||
switch (*(cmd++))
|
||||
{
|
||||
case COMMAND_MOVE_ORIGIN:
|
||||
cmd += 3;
|
||||
break;
|
||||
|
||||
case COMMAND_JUMP_VELOCITY:
|
||||
cmd += 2;
|
||||
break;
|
||||
|
||||
case COMMAND_SOUND_FX:
|
||||
if (item->Animation.FrameNumber != *cmd)
|
||||
{
|
||||
cmd += 2;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool inWater = (cmd[1] & 0x8000) != 0;
|
||||
bool inDry = (cmd[1] & 0x4000) != 0;
|
||||
bool always = (inWater && inDry) || (!inWater && !inDry);
|
||||
|
||||
SoundEnvironment condition = SoundEnvironment::Always;
|
||||
if (inWater) condition = SoundEnvironment::Water;
|
||||
if (inDry) condition = SoundEnvironment::Land;
|
||||
if (always) condition = SoundEnvironment::Always;
|
||||
|
||||
if (condition == SoundEnvironment::Always ||
|
||||
(condition == SoundEnvironment::Land && (lara->WaterSurfaceDist >= -SHALLOW_WATER_START_LEVEL || lara->WaterSurfaceDist == NO_HEIGHT)) ||
|
||||
(condition == SoundEnvironment::Water && lara->WaterSurfaceDist < -SHALLOW_WATER_START_LEVEL && lara->WaterSurfaceDist != NO_HEIGHT && !TestEnvironment(ENV_FLAG_SWAMP, item)))
|
||||
{
|
||||
SoundEffect(cmd[1] & 0x3FFF, &item->Pose, SoundEnvironment::Always);
|
||||
}
|
||||
}
|
||||
|
||||
cmd += 2;
|
||||
break;
|
||||
|
||||
case COMMAND_EFFECT:
|
||||
if (item->Animation.FrameNumber != *cmd)
|
||||
{
|
||||
cmd += 2;
|
||||
break;
|
||||
}
|
||||
|
||||
DoFlipEffect((cmd[1] & 0x3FFF), item);
|
||||
|
||||
cmd += 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int frameCount = (anim->frameEnd - anim->frameBase) + 1;
|
||||
int frameCount = anim->frameEnd - anim->frameBase;
|
||||
frameCount = (frameCount > 0) ? frameCount : 1;
|
||||
int currentFrame = item->Animation.FrameNumber - anim->frameBase;
|
||||
|
||||
if (item->Animation.IsAirborne)
|
||||
|
@ -194,14 +94,142 @@ void AnimateLara(ItemInfo* item)
|
|||
g_Renderer.UpdateLaraAnimations(true);
|
||||
}
|
||||
|
||||
void PerformAnimCommands(ItemInfo* item, bool frameBased)
|
||||
{
|
||||
auto* anim = &g_Level.Anims[item->Animation.AnimNumber];
|
||||
|
||||
if (anim->numberCommands == 0)
|
||||
return;
|
||||
|
||||
short* cmd = &g_Level.Commands[anim->commandIndex];
|
||||
|
||||
for (int i = anim->numberCommands; i > 0; i--)
|
||||
{
|
||||
auto animCommand = (AnimCommandType)cmd[0];
|
||||
cmd++;
|
||||
|
||||
switch (animCommand)
|
||||
{
|
||||
case AnimCommandType::MoveOrigin:
|
||||
if (!frameBased)
|
||||
{
|
||||
TranslateItem(item, item->Pose.Orientation.y, cmd[2], cmd[1], cmd[0]);
|
||||
auto* bounds = GetBoundsAccurate(item);
|
||||
UpdateItemRoom(item, -bounds->Height() / 2, -cmd[0], -cmd[2]);
|
||||
}
|
||||
|
||||
cmd += 3;
|
||||
break;
|
||||
|
||||
case AnimCommandType::JumpVelocity:
|
||||
if (!frameBased)
|
||||
{
|
||||
item->Animation.Velocity.y = cmd[0];
|
||||
item->Animation.Velocity.z = cmd[1];
|
||||
item->Animation.IsAirborne = true;
|
||||
|
||||
if (item->IsLara())
|
||||
{
|
||||
auto* lara = GetLaraInfo(item);
|
||||
|
||||
if (lara->Control.CalculatedJumpVelocity)
|
||||
{
|
||||
item->Animation.Velocity.y = lara->Control.CalculatedJumpVelocity;
|
||||
lara->Control.CalculatedJumpVelocity = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmd += 2;
|
||||
break;
|
||||
|
||||
case AnimCommandType::Deactivate:
|
||||
if (!frameBased)
|
||||
{
|
||||
if (Objects[item->ObjectNumber].intelligent && !item->AfterDeath)
|
||||
item->AfterDeath = 1;
|
||||
|
||||
item->Status = ITEM_DEACTIVATED;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case AnimCommandType::AttackReady:
|
||||
if (!frameBased && item->IsLara())
|
||||
{
|
||||
auto* lara = GetLaraInfo(item);
|
||||
if (lara->Control.HandStatus != HandStatus::Special)
|
||||
lara->Control.HandStatus = HandStatus::Free;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case AnimCommandType::SoundEffect:
|
||||
if (frameBased && item->Animation.FrameNumber == cmd[0])
|
||||
{
|
||||
if (!Objects[item->ObjectNumber].waterCreature)
|
||||
{
|
||||
bool inWater = (cmd[1] & 0x8000) != 0;
|
||||
bool inDry = (cmd[1] & 0x4000) != 0;
|
||||
bool always = (inWater && inDry) || (!inWater && !inDry);
|
||||
|
||||
if (item->IsLara())
|
||||
{
|
||||
auto* lara = GetLaraInfo(item);
|
||||
|
||||
if (always ||
|
||||
(inDry && (lara->WaterSurfaceDist >= -SHALLOW_WATER_START_LEVEL || lara->WaterSurfaceDist == NO_HEIGHT)) ||
|
||||
(inWater && lara->WaterSurfaceDist < -SHALLOW_WATER_START_LEVEL && lara->WaterSurfaceDist != NO_HEIGHT && !TestEnvironment(ENV_FLAG_SWAMP, item)))
|
||||
{
|
||||
SoundEffect(cmd[1] & 0x3FFF, &item->Pose, SoundEnvironment::Always);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (item->RoomNumber == NO_ROOM)
|
||||
{
|
||||
SoundEffect(cmd[1] & 0x3FFF, &item->Pose, SoundEnvironment::Always);
|
||||
}
|
||||
else if (TestEnvironment(ENV_FLAG_WATER, item))
|
||||
{
|
||||
if (always || (inWater && TestEnvironment(ENV_FLAG_WATER, Camera.pos.roomNumber)))
|
||||
SoundEffect(cmd[1] & 0x3FFF, &item->Pose, SoundEnvironment::Always);
|
||||
}
|
||||
else if (always || (inDry && !TestEnvironment(ENV_FLAG_WATER, Camera.pos.roomNumber) && !TestEnvironment(ENV_FLAG_SWAMP, Camera.pos.roomNumber)))
|
||||
SoundEffect(cmd[1] & 0x3FFF, &item->Pose, SoundEnvironment::Always);
|
||||
}
|
||||
}
|
||||
else
|
||||
SoundEffect(cmd[1] & 0x3FFF, &item->Pose, TestEnvironment(ENV_FLAG_WATER, item) ? SoundEnvironment::Water : SoundEnvironment::Land);
|
||||
}
|
||||
|
||||
cmd += 2;
|
||||
break;
|
||||
|
||||
case AnimCommandType::Flipeffect:
|
||||
if (frameBased && item->Animation.FrameNumber == cmd[0])
|
||||
DoFlipEffect((cmd[1] & 0x3FFF), item);
|
||||
|
||||
cmd += 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AnimateItem(ItemInfo* item)
|
||||
{
|
||||
item->TouchBits = NO_JOINT_BITS;
|
||||
item->HitStatus = false;
|
||||
|
||||
PerformAnimCommands(item, true);
|
||||
|
||||
item->Animation.FrameNumber++;
|
||||
|
||||
auto* anim = &g_Level.Anims[item->Animation.AnimNumber];
|
||||
|
||||
if (anim->numberChanges > 0 && GetChange(item, anim))
|
||||
{
|
||||
anim = &g_Level.Anims[item->Animation.AnimNumber];
|
||||
|
@ -213,41 +241,7 @@ void AnimateItem(ItemInfo* item)
|
|||
|
||||
if (item->Animation.FrameNumber > anim->frameEnd)
|
||||
{
|
||||
if (anim->numberCommands > 0)
|
||||
{
|
||||
short* cmd = &g_Level.Commands[anim->commandIndex];
|
||||
for (int i = anim->numberCommands; i > 0; i--)
|
||||
{
|
||||
switch (*(cmd++))
|
||||
{
|
||||
case COMMAND_MOVE_ORIGIN:
|
||||
TranslateItem(item, item->Pose.Orientation.y, cmd[2], cmd[1], cmd[0]);
|
||||
cmd += 3;
|
||||
break;
|
||||
|
||||
case COMMAND_JUMP_VELOCITY:
|
||||
item->Animation.Velocity.y = *(cmd++);
|
||||
item->Animation.Velocity.z = *(cmd++);
|
||||
item->Animation.IsAirborne = true;
|
||||
break;
|
||||
|
||||
case COMMAND_DEACTIVATE:
|
||||
if (Objects[item->ObjectNumber].intelligent && !item->AfterDeath)
|
||||
item->AfterDeath = 1;
|
||||
|
||||
item->Status = ITEM_DEACTIVATED;
|
||||
break;
|
||||
|
||||
case COMMAND_SOUND_FX:
|
||||
case COMMAND_EFFECT:
|
||||
cmd += 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
PerformAnimCommands(item, false);
|
||||
|
||||
item->Animation.AnimNumber = anim->jumpAnimNum;
|
||||
item->Animation.FrameNumber = anim->jumpFrameNum;
|
||||
|
@ -263,77 +257,8 @@ void AnimateItem(ItemInfo* item)
|
|||
item->Animation.RequiredState = 0;
|
||||
}
|
||||
|
||||
if (anim->numberCommands > 0)
|
||||
{
|
||||
short* cmd = &g_Level.Commands[anim->commandIndex];
|
||||
|
||||
for (int i = anim->numberCommands; i > 0; i--)
|
||||
{
|
||||
switch (*(cmd++))
|
||||
{
|
||||
case COMMAND_MOVE_ORIGIN:
|
||||
cmd += 3;
|
||||
break;
|
||||
|
||||
case COMMAND_JUMP_VELOCITY:
|
||||
cmd += 2;
|
||||
break;
|
||||
|
||||
case COMMAND_SOUND_FX:
|
||||
if (item->Animation.FrameNumber != *cmd)
|
||||
{
|
||||
cmd += 2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!Objects[item->ObjectNumber].waterCreature)
|
||||
{
|
||||
bool inWater = (cmd[1] & 0x8000) != 0;
|
||||
bool inDry = (cmd[1] & 0x4000) != 0;
|
||||
bool always = (inWater && inDry) || (!inWater && !inDry);
|
||||
|
||||
if (item->RoomNumber == NO_ROOM)
|
||||
{
|
||||
item->Pose.Position.x = LaraItem->Pose.Position.x;
|
||||
item->Pose.Position.y = LaraItem->Pose.Position.y - 762;
|
||||
item->Pose.Position.z = LaraItem->Pose.Position.z;
|
||||
|
||||
SoundEffect(cmd[1] & 0x3FFF, &item->Pose, SoundEnvironment::Always);
|
||||
}
|
||||
else if (TestEnvironment(ENV_FLAG_WATER, item))
|
||||
{
|
||||
if (always || (inWater && TestEnvironment(ENV_FLAG_WATER, Camera.pos.roomNumber)))
|
||||
SoundEffect(cmd[1] & 0x3FFF, &item->Pose, SoundEnvironment::Always);
|
||||
}
|
||||
else if (always || (inDry && !TestEnvironment(ENV_FLAG_WATER, Camera.pos.roomNumber) && !TestEnvironment(ENV_FLAG_SWAMP, Camera.pos.roomNumber)))
|
||||
SoundEffect(cmd[1] & 0x3FFF, &item->Pose, SoundEnvironment::Always);
|
||||
}
|
||||
else
|
||||
{
|
||||
SoundEffect(cmd[1] & 0x3FFF, &item->Pose, TestEnvironment(ENV_FLAG_WATER, item) ? SoundEnvironment::Water : SoundEnvironment::Land);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case COMMAND_EFFECT:
|
||||
if (item->Animation.FrameNumber != *cmd)
|
||||
{
|
||||
cmd += 2;
|
||||
break;
|
||||
}
|
||||
|
||||
DoFlipEffect((cmd[1] & 0x3FFF), item);
|
||||
|
||||
cmd += 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int frameCount = (anim->frameEnd - anim->frameBase) + 1;
|
||||
int frameCount = anim->frameEnd - anim->frameBase;
|
||||
frameCount = (frameCount > 0) ? frameCount : 1;
|
||||
int currentFrame = item->Animation.FrameNumber - anim->frameBase;
|
||||
|
||||
if (item->Animation.IsAirborne)
|
||||
|
|
|
@ -50,15 +50,15 @@ struct ANIM_STRUCT
|
|||
int commandIndex;
|
||||
};
|
||||
|
||||
enum ANIMCOMMAND_TYPES
|
||||
enum class AnimCommandType
|
||||
{
|
||||
COMMAND_NULL = 0,
|
||||
COMMAND_MOVE_ORIGIN,
|
||||
COMMAND_JUMP_VELOCITY,
|
||||
COMMAND_ATTACK_READY,
|
||||
COMMAND_DEACTIVATE,
|
||||
COMMAND_SOUND_FX,
|
||||
COMMAND_EFFECT
|
||||
None = 0,
|
||||
MoveOrigin,
|
||||
JumpVelocity,
|
||||
AttackReady,
|
||||
Deactivate,
|
||||
SoundEffect,
|
||||
Flipeffect
|
||||
};
|
||||
|
||||
struct BoneMutator
|
||||
|
|
|
@ -20,10 +20,13 @@ HAIR_STRUCT Hairs[HAIR_MAX][HAIR_SEGMENTS + 1];
|
|||
|
||||
void InitialiseHair()
|
||||
{
|
||||
bool youngLara = g_GameFlow->GetLevel(CurrentLevel)->GetLaraType() == LaraType::Young;
|
||||
|
||||
for (int h = 0; h < HAIR_MAX; h++)
|
||||
{
|
||||
int* bone = &g_Level.Bones[Objects[ID_HAIR].boneIndex];
|
||||
|
||||
Hairs[h][0].enabled = (h == 0 || youngLara);
|
||||
Hairs[h][0].initialised = true;
|
||||
Hairs[h][0].pos.Orientation.y = 0;
|
||||
Hairs[h][0].pos.Orientation.x = -0x4000;
|
||||
|
|
|
@ -15,6 +15,7 @@ struct HAIR_STRUCT
|
|||
Vector3Int unknown;
|
||||
|
||||
bool initialised = false;
|
||||
bool enabled = false;
|
||||
};
|
||||
extern HAIR_STRUCT Hairs[HAIR_MAX][HAIR_SEGMENTS + 1];
|
||||
|
||||
|
|
|
@ -1481,7 +1481,9 @@ namespace TEN::Gui
|
|||
Ammo.AmountShotGunAmmo2 = -1;
|
||||
else
|
||||
Ammo.AmountShotGunAmmo2 = lara->Weapons[(int)LaraWeaponType::Shotgun].Ammo[1].GetCount() / 6;
|
||||
|
||||
|
||||
Ammo.AmountShotGunAmmo1 = Lara.Weapons[(int)LaraWeaponType::Shotgun].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : Lara.Weapons[(int)LaraWeaponType::Shotgun].Ammo[(int)WeaponAmmoType::Ammo1].GetCount();
|
||||
Ammo.AmountShotGunAmmo2 = Lara.Weapons[(int)LaraWeaponType::Shotgun].Ammo[(int)WeaponAmmoType::Ammo2].HasInfinite() ? -1 : Lara.Weapons[(int)LaraWeaponType::Shotgun].Ammo[(int)WeaponAmmoType::Ammo2].GetCount();
|
||||
Ammo.AmountHKAmmo1 = lara->Weapons[(int)LaraWeaponType::HK].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : lara->Weapons[(int)LaraWeaponType::HK].Ammo[(int)WeaponAmmoType::Ammo1].GetCount();
|
||||
Ammo.AmountCrossBowAmmo1 = lara->Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo1].HasInfinite() ? -1 : lara->Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo1].GetCount();
|
||||
Ammo.AmountCrossBowAmmo2 = lara->Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo2].HasInfinite() ? -1 : lara->Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo2].GetCount();
|
||||
|
@ -2572,13 +2574,11 @@ namespace TEN::Gui
|
|||
switch (InventoryObjectTable[Rings[ringIndex]->CurrentObjectList[n].InventoryItem].ObjectNumber)
|
||||
{
|
||||
case ID_SHOTGUN_AMMO1_ITEM:
|
||||
count = lara->Weapons[(int)LaraWeaponType::Shotgun].Ammo[(int)WeaponAmmoType::Ammo1].GetCount();
|
||||
numMeUp = count == -1 ? count : count / 6;
|
||||
numMeUp = lara->Weapons[(int)LaraWeaponType::Shotgun].Ammo[(int)WeaponAmmoType::Ammo1].GetCount();
|
||||
break;
|
||||
|
||||
case ID_SHOTGUN_AMMO2_ITEM:
|
||||
count = lara->Weapons[(int)LaraWeaponType::Shotgun].Ammo[(int)WeaponAmmoType::Ammo2].GetCount();
|
||||
numMeUp = count == -1 ? count : count / 6;
|
||||
nummeup = Lara.Weapons[(int)LaraWeaponType::Shotgun].Ammo[(int)WeaponAmmoType::Ammo2].GetCount();
|
||||
break;
|
||||
|
||||
case ID_HK_AMMO_ITEM:
|
||||
|
|
|
@ -636,15 +636,12 @@ int GlobalItemReplace(short search, GAME_OBJECT_ID replace)
|
|||
// Offset values may be used to account for the quirk of room traversal only being able to occur at portals.
|
||||
void UpdateItemRoom(ItemInfo* item, int height, int xOffset, int zOffset)
|
||||
{
|
||||
float sinY = phd_sin(item->Pose.Orientation.y);
|
||||
float cosY = phd_cos(item->Pose.Orientation.y);
|
||||
auto point = TranslateVector(item->Pose.Position, item->Pose.Orientation.y, zOffset, height, xOffset);
|
||||
|
||||
int x = (int)round(item->Pose.Position.x + ((cosY * xOffset) + (sinY * zOffset)));
|
||||
int y = height + item->Pose.Position.y;
|
||||
int z = (int)round(item->Pose.Position.z + ((-sinY * xOffset) + (cosY * zOffset)));
|
||||
|
||||
item->Location = GetRoom(item->Location, x, y, z);
|
||||
item->Floor = GetFloorHeight(item->Location, x, z).value_or(NO_HEIGHT);
|
||||
// Hacky L-shaped Location traversal.
|
||||
item->Location = GetRoom(item->Location, point.x, point.y, point.z);
|
||||
item->Location = GetRoom(item->Location, item->Pose.Position.x, point.y, item->Pose.Position.z);
|
||||
item->Floor = GetFloorHeight(item->Location, item->Pose.Position.x, item->Pose.Position.z).value_or(NO_HEIGHT);
|
||||
|
||||
if (item->RoomNumber != item->Location.roomNumber)
|
||||
ItemNewRoom(item->Index, item->Location.roomNumber);
|
||||
|
@ -673,7 +670,7 @@ ItemInfo* FindItem(int objectNumber)
|
|||
return item;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int FindItem(ItemInfo* item)
|
||||
|
|
|
@ -716,12 +716,12 @@ void RegeneratePickups()
|
|||
|
||||
for (int i = 0; i < NumRPickups; i++)
|
||||
{
|
||||
auto* item = &g_Level.Items[RPickups[i]];
|
||||
auto& item = g_Level.Items[RPickups[i]];
|
||||
|
||||
if (item->Status == ITEM_INVISIBLE)
|
||||
if (item.Status == ITEM_INVISIBLE)
|
||||
{
|
||||
short ammo = 0;
|
||||
switch (item->ObjectNumber)
|
||||
switch (item.ObjectNumber)
|
||||
{
|
||||
case ID_CROSSBOW_AMMO1_ITEM:
|
||||
ammo = lara->Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo1];
|
||||
|
@ -777,7 +777,7 @@ void RegeneratePickups()
|
|||
}
|
||||
|
||||
if (ammo == 0)
|
||||
item->Status = ITEM_NOT_ACTIVE;
|
||||
item.Status = ITEM_NOT_ACTIVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -792,7 +792,7 @@ void PickupControl(short itemNumber)
|
|||
switch (triggerFlags)
|
||||
{
|
||||
case 5:
|
||||
item->Animation.Velocity.y += 6;
|
||||
item->Animation.Velocity.y += 6.0f;
|
||||
item->Pose.Position.y += item->Animation.Velocity.y;
|
||||
|
||||
roomNumber = item->RoomNumber;
|
||||
|
@ -801,7 +801,7 @@ void PickupControl(short itemNumber)
|
|||
if (item->Pose.Position.y > item->ItemFlags[0])
|
||||
{
|
||||
item->Pose.Position.y = item->ItemFlags[0];
|
||||
if (item->Animation.Velocity.y <= 64)
|
||||
if (item->Animation.Velocity.y <= 64.0f)
|
||||
item->TriggerFlags &= 0xC0;
|
||||
else
|
||||
item->Animation.Velocity.y = -item->Animation.Velocity.y / 4;
|
||||
|
@ -846,7 +846,9 @@ BOUNDING_BOX* FindPlinth(ItemInfo* item)
|
|||
if (frame->X1 <= bbox->X2 && frame->X2 >= bbox->X1 &&
|
||||
frame->Z1 <= bbox->Z2 && frame->Z2 >= bbox->Z1 &&
|
||||
(bbox->X1 || bbox->X2))
|
||||
{
|
||||
return bbox;
|
||||
}
|
||||
}
|
||||
|
||||
if (room->itemNumber == NO_ITEM)
|
||||
|
|
|
@ -41,10 +41,10 @@ bool TryModifyingAmmo(LaraInfo& lara, GAME_OBJECT_ID objectID, std::optional<int
|
|||
if (-1 == arrayPos)
|
||||
return false;
|
||||
|
||||
AmmoPickupInfo info = kAmmo[arrayPos];
|
||||
auto ammoPickup = kAmmo[arrayPos];
|
||||
|
||||
auto& currentWeapon = lara.Weapons[(int)info.LaraWeaponType];
|
||||
auto& currentAmmo = currentWeapon.Ammo[(int)info.AmmoType];
|
||||
auto& currentWeapon = lara.Weapons[(int)ammoPickup.LaraWeaponType];
|
||||
auto& currentAmmo = currentWeapon.Ammo[(int)ammoPickup.AmmoType];
|
||||
|
||||
switch(modType)
|
||||
{
|
||||
|
@ -56,10 +56,11 @@ bool TryModifyingAmmo(LaraInfo& lara, GAME_OBJECT_ID objectID, std::optional<int
|
|||
default:
|
||||
if (!currentAmmo.HasInfinite())
|
||||
{
|
||||
int defaultModify = modType == ModificationType::Add ? info.Amount : -info.Amount;
|
||||
int newVal = int{ currentAmmo.GetCount() } + (amount.has_value() ? amount.value() : defaultModify);
|
||||
int defaultModify = modType == ModificationType::Add ? ammoPickup.Amount : -ammoPickup.Amount;
|
||||
int newVal = (int)currentAmmo.GetCount() + (amount.has_value() ? amount.value() : defaultModify);
|
||||
currentAmmo = std::max(0, newVal);
|
||||
}
|
||||
|
||||
break;
|
||||
};
|
||||
|
||||
|
|
|
@ -55,42 +55,41 @@ bool TryModifyWeapon(LaraInfo& lara, GAME_OBJECT_ID objectID, std::optional<int>
|
|||
if (-1 == arrayPos)
|
||||
return false;
|
||||
|
||||
WeaponPickupInfo info = kWeapons[arrayPos];
|
||||
auto weaponPickup = kWeapons[arrayPos];
|
||||
|
||||
// Set the SelectedAmmo type to WeaponAmmoType::Ammo1 (0) if adding the weapon for the first time.
|
||||
// Note that this refers to the index of the weapon's ammo array, and not the weapon's actual ammunition count.
|
||||
auto& currWeapon = lara.Weapons[(int)info.LaraWeaponType];
|
||||
auto& currentWeapon = lara.Weapons[(int)weaponPickup.LaraWeaponType];
|
||||
|
||||
if (!currWeapon.Present)
|
||||
currWeapon.SelectedAmmo = WeaponAmmoType::Ammo1;
|
||||
if (!currentWeapon.Present)
|
||||
currentWeapon.SelectedAmmo = WeaponAmmoType::Ammo1;
|
||||
|
||||
bool add = ModificationType::Add == type || ((ModificationType::Set == type) && count != 0);
|
||||
currWeapon.Present = add;
|
||||
currentWeapon.Present = add;
|
||||
|
||||
if(!add)
|
||||
{
|
||||
if (info.LaraWeaponType == lara.Control.Weapon.GunType || info.LaraWeaponType == lara.Control.Weapon.LastGunType)
|
||||
if (weaponPickup.LaraWeaponType == lara.Control.Weapon.GunType ||
|
||||
weaponPickup.LaraWeaponType == lara.Control.Weapon.LastGunType)
|
||||
{
|
||||
lara.Control.Weapon.RequestGunType = LaraWeaponType::None;
|
||||
|
||||
// If Lara has pistols and it's not the pistols we're removing, set them
|
||||
// as the "next weapon" so that Lara equips them next.
|
||||
if (LaraWeaponType::Pistol == info.LaraWeaponType || !lara.Weapons[(int)LaraWeaponType::Pistol].Present)
|
||||
{
|
||||
if (LaraWeaponType::Pistol == weaponPickup.LaraWeaponType || !lara.Weapons[(int)LaraWeaponType::Pistol].Present)
|
||||
lara.Control.Weapon.LastGunType = LaraWeaponType::None;
|
||||
}
|
||||
else
|
||||
{
|
||||
lara.Control.Weapon.LastGunType = LaraWeaponType::Pistol;
|
||||
}
|
||||
}
|
||||
|
||||
if (HolsterType::Hips == info.Holster && lara.Control.Weapon.HolsterInfo.LeftHolster == HolsterSlotForWeapon(info.LaraWeaponType))
|
||||
if (HolsterType::Hips == weaponPickup.Holster &&
|
||||
lara.Control.Weapon.HolsterInfo.LeftHolster == HolsterSlotForWeapon(weaponPickup.LaraWeaponType))
|
||||
{
|
||||
lara.Control.Weapon.HolsterInfo.LeftHolster = HolsterSlot::Empty;
|
||||
lara.Control.Weapon.HolsterInfo.RightHolster = HolsterSlot::Empty;
|
||||
}
|
||||
else if (HolsterType::Back == info.Holster && lara.Control.Weapon.HolsterInfo.BackHolster == HolsterSlotForWeapon(info.LaraWeaponType))
|
||||
else if (HolsterType::Back == weaponPickup.Holster &&
|
||||
lara.Control.Weapon.HolsterInfo.BackHolster == HolsterSlotForWeapon(weaponPickup.LaraWeaponType))
|
||||
{
|
||||
lara.Control.Weapon.HolsterInfo.BackHolster = HolsterSlot::Empty;
|
||||
}
|
||||
|
@ -99,7 +98,7 @@ bool TryModifyWeapon(LaraInfo& lara, GAME_OBJECT_ID objectID, std::optional<int>
|
|||
return true;
|
||||
}
|
||||
|
||||
// Adding a weapon will not give the player any ammo even if they already have the weapon
|
||||
// Adding a weapon will not give the player any ammo even if they already have the weapon.
|
||||
bool TryAddingWeapon(LaraInfo& lara, GAME_OBJECT_ID objectID)
|
||||
{
|
||||
return TryModifyWeapon(lara, objectID, 1, ModificationType::Add);
|
||||
|
@ -117,6 +116,6 @@ std::optional<bool> HasWeapon(LaraInfo& lara, GAME_OBJECT_ID objectID)
|
|||
if (-1 == arrPos)
|
||||
return std::nullopt;
|
||||
|
||||
WeaponPickupInfo info = kWeapons[arrPos];
|
||||
return lara.Weapons[(int)info.LaraWeaponType].Present;
|
||||
auto weaponPickup = kWeapons[arrPos];
|
||||
return lara.Weapons[(int)weaponPickup.LaraWeaponType].Present;
|
||||
}
|
||||
|
|
|
@ -138,15 +138,15 @@ namespace TEN::Entities::Switches
|
|||
break;
|
||||
}
|
||||
|
||||
if (switchItem->Animation.ActiveState == SWITCH_ON) /* Switch down */
|
||||
if (switchItem->Animation.ActiveState == SWITCH_OFF) /* Switch down */
|
||||
{
|
||||
SetAnimation(laraItem, offAnim);
|
||||
switchItem->Animation.TargetState = SWITCH_OFF;
|
||||
switchItem->Animation.TargetState = SWITCH_ON;
|
||||
}
|
||||
else /* Switch up */
|
||||
{
|
||||
SetAnimation(laraItem, onAnim);
|
||||
switchItem->Animation.TargetState = SWITCH_ON;
|
||||
switchItem->Animation.TargetState = SWITCH_OFF;
|
||||
}
|
||||
|
||||
ResetLaraFlex(laraItem);
|
||||
|
|
|
@ -42,21 +42,22 @@ namespace TEN::Entities::Creatures::TR3
|
|||
// TODO
|
||||
enum CivvyState
|
||||
{
|
||||
CIVVY_STATE_IDLE,
|
||||
CIVVY_STATE_WALK_FORWARD,
|
||||
CIVVY_PUNCH2,
|
||||
CIVVY_AIM2,
|
||||
CIVVY_WAIT,
|
||||
CIVVY_AIM1,
|
||||
CIVVY_AIM0,
|
||||
CIVVY_PUNCH1,
|
||||
CIVVY_PUNCH0,
|
||||
CIVVY_STATE_RUN_FORWARD,
|
||||
CIVVY_DEATH,
|
||||
CIVVY_CLIMB3,
|
||||
CIVVY_CLIMB1,
|
||||
CIVVY_CLIMB2,
|
||||
CIVVY_FALL3
|
||||
// No state 0.
|
||||
CIVVY_STATE_IDLE = 1,
|
||||
CIVVY_STATE_WALK_FORWARD = 2,
|
||||
CIVVY_PUNCH2 = 3,
|
||||
CIVVY_AIM2 = 4,
|
||||
CIVVY_WAIT = 5,
|
||||
CIVVY_AIM1 = 6,
|
||||
CIVVY_AIM0 = 7,
|
||||
CIVVY_PUNCH1 = 8,
|
||||
CIVVY_PUNCH0 = 9,
|
||||
CIVVY_STATE_RUN_FORWARD = 10,
|
||||
CIVVY_DEATH = 11,
|
||||
CIVVY_CLIMB3 = 12,
|
||||
CIVVY_CLIMB1 = 13,
|
||||
CIVVY_CLIMB2 = 14,
|
||||
CIVVY_FALL3 = 15
|
||||
};
|
||||
|
||||
// TODO
|
||||
|
|
|
@ -26,22 +26,23 @@ namespace TEN::Entities::Creatures::TR3
|
|||
|
||||
enum MPStickState
|
||||
{
|
||||
MPSTICK_STATE_STOP,
|
||||
MPSTICK_STATE_WALK,
|
||||
MPSTICK_STATE_PUNCH2,
|
||||
MPSTICK_STATE_AIM2,
|
||||
MPSTICK_STATE_WAIT,
|
||||
MPSTICK_STATE_AIM1,
|
||||
MPSTICK_STATE_AIM0,
|
||||
MPSTICK_STATE_PUNCH1,
|
||||
MPSTICK_STATE_PUNCH0,
|
||||
MPSTICK_STATE_RUN,
|
||||
MPSTICK_STATE_DEATH,
|
||||
MPSTICK_STATE_KICK,
|
||||
MPSTICK_STATE_CLIMB3,
|
||||
MPSTICK_STATE_CLIMB1,
|
||||
MPSTICK_STATE_CLIMB2,
|
||||
MPSTICK_STATE_FALL3
|
||||
// No state 0.
|
||||
MPSTICK_STATE_STOP = 1,
|
||||
MPSTICK_STATE_WALK = 2,
|
||||
MPSTICK_STATE_PUNCH2 = 3,
|
||||
MPSTICK_STATE_AIM2 = 4,
|
||||
MPSTICK_STATE_WAIT = 5,
|
||||
MPSTICK_STATE_AIM1 = 6,
|
||||
MPSTICK_STATE_AIM0 = 7,
|
||||
MPSTICK_STATE_PUNCH1 = 8,
|
||||
MPSTICK_STATE_PUNCH0 = 9,
|
||||
MPSTICK_STATE_RUN = 10,
|
||||
MPSTICK_STATE_DEATH = 11,
|
||||
MPSTICK_STATE_KICK = 12,
|
||||
MPSTICK_STATE_CLIMB3 = 13,
|
||||
MPSTICK_STATE_CLIMB1 = 14,
|
||||
MPSTICK_STATE_CLIMB2 = 15,
|
||||
MPSTICK_STATE_FALL3 = 16,
|
||||
};
|
||||
|
||||
// TODO
|
||||
|
|
|
@ -25,19 +25,19 @@ namespace TEN::Entities::Creatures::TR3
|
|||
|
||||
enum SophiaState
|
||||
{
|
||||
LONDONBOSS_EMPTY,
|
||||
LONDONBOSS_STAND,
|
||||
LONDONBOSS_WALK,
|
||||
LONDONBOSS_RUN,
|
||||
LONDONBOSS_SUMMON,
|
||||
LONDONBOSS_BIGZAP,
|
||||
LONDONBOSS_DEATH,
|
||||
LONDONBOSS_LAUGH,
|
||||
LONDONBOSS_LILZAP,
|
||||
LONDONBOSS_VAULT2,
|
||||
LONDONBOSS_VAULT3,
|
||||
LONDONBOSS_VAULT4,
|
||||
LONDONBOSS_GODOWN
|
||||
LONDONBOSS_EMPTY = 0,
|
||||
LONDONBOSS_STAND = 1,
|
||||
LONDONBOSS_WALK = 2,
|
||||
LONDONBOSS_RUN = 3,
|
||||
LONDONBOSS_SUMMON = 4,
|
||||
LONDONBOSS_BIGZAP = 5,
|
||||
LONDONBOSS_DEATH = 6,
|
||||
LONDONBOSS_LAUGH = 7,
|
||||
LONDONBOSS_LILZAP = 8,
|
||||
LONDONBOSS_VAULT2 = 9,
|
||||
LONDONBOSS_VAULT3 = 10,
|
||||
LONDONBOSS_VAULT4 = 11,
|
||||
LONDONBOSS_GODOWN = 12,
|
||||
};
|
||||
|
||||
// TODO
|
||||
|
|
|
@ -319,28 +319,34 @@ void TEN::Renderer::Renderer11::DrawLara(RenderView& view, bool transparent)
|
|||
{
|
||||
RendererObject& hairsObj = *m_moveableObjects[ID_HAIR];
|
||||
|
||||
// First matrix is Lara's head matrix, then all 6 hairs matrices. Bones are adjusted at load time for accounting this.
|
||||
m_stItem.World = Matrix::Identity;
|
||||
m_stItem.BonesMatrices[0] = laraObj.AnimationTransforms[LM_HEAD] * m_LaraWorldMatrix;
|
||||
|
||||
for (int i = 0; i < hairsObj.BindPoseTransforms.size(); i++)
|
||||
for (int h = 0; h < HAIR_MAX; h++)
|
||||
{
|
||||
auto* hairs = &Hairs[0][i];
|
||||
Matrix world = Matrix::CreateFromYawPitchRoll(TO_RAD(hairs->pos.Orientation.y), TO_RAD(hairs->pos.Orientation.x), 0) *
|
||||
Matrix::CreateTranslation(hairs->pos.Position.x, hairs->pos.Position.y, hairs->pos.Position.z);
|
||||
m_stItem.BonesMatrices[i + 1] = world;
|
||||
m_stItem.BoneLightModes[i] = LIGHT_MODES::LIGHT_MODE_DYNAMIC;
|
||||
if (!Hairs[h][0].enabled)
|
||||
continue;
|
||||
|
||||
// First matrix is Lara's head matrix, then all 6 hairs matrices. Bones are adjusted at load time for accounting this.
|
||||
m_stItem.World = Matrix::Identity;
|
||||
m_stItem.BonesMatrices[0] = laraObj.AnimationTransforms[LM_HEAD] * m_LaraWorldMatrix;
|
||||
|
||||
for (int i = 0; i < hairsObj.BindPoseTransforms.size(); i++)
|
||||
{
|
||||
auto* hairs = &Hairs[h][i];
|
||||
Matrix world = Matrix::CreateFromYawPitchRoll(TO_RAD(hairs->pos.Orientation.y), TO_RAD(hairs->pos.Orientation.x), 0) *
|
||||
Matrix::CreateTranslation(hairs->pos.Position.x, hairs->pos.Position.y, hairs->pos.Position.z);
|
||||
m_stItem.BonesMatrices[i + 1] = world;
|
||||
m_stItem.BoneLightModes[i] = LIGHT_MODES::LIGHT_MODE_DYNAMIC;
|
||||
}
|
||||
|
||||
m_cbItem.updateData(m_stItem, m_context.Get());
|
||||
BindConstantBufferVS(CB_ITEM, m_cbItem.get());
|
||||
BindConstantBufferPS(CB_ITEM, m_cbItem.get());
|
||||
|
||||
for (int k = 0; k < hairsObj.ObjectMeshes.size(); k++)
|
||||
{
|
||||
RendererMesh* mesh = hairsObj.ObjectMeshes[k];
|
||||
DrawMoveableMesh(item, mesh, room, k, transparent);
|
||||
}
|
||||
}
|
||||
|
||||
m_cbItem.updateData(m_stItem, m_context.Get());
|
||||
BindConstantBufferVS(CB_ITEM, m_cbItem.get());
|
||||
BindConstantBufferPS(CB_ITEM, m_cbItem.get());
|
||||
|
||||
for (int k = 0; k < hairsObj.ObjectMeshes.size(); k++)
|
||||
{
|
||||
RendererMesh* mesh = hairsObj.ObjectMeshes[k];
|
||||
DrawMoveableMesh(item, mesh, room, k, transparent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ public:
|
|||
virtual void OnControlPhase(float dt) = 0;
|
||||
virtual void OnSave() = 0;
|
||||
virtual void OnEnd() = 0;
|
||||
virtual void ShortenTENCalls() = 0;
|
||||
|
||||
virtual void FreeLevelScripts() = 0;
|
||||
virtual void ResetScripts(bool clearGameVars) = 0;
|
||||
|
|
|
@ -257,6 +257,7 @@ int FlowHandler::GetLevelNumber(std::string const& fileName)
|
|||
return i;
|
||||
}
|
||||
|
||||
TENLog("Specified level filename was not found in script. Level won't be loaded. Please edit level filename in gameflow.lua.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -310,7 +311,7 @@ bool FlowHandler::DoFlow()
|
|||
{
|
||||
// We start with the title level, if no other index is specified
|
||||
if (CurrentLevel == -1)
|
||||
CurrentLevel = 0;
|
||||
CurrentLevel = SystemNameHash = 0;
|
||||
|
||||
SelectedLevelForNewGame = 0;
|
||||
SelectedSaveGame = 0;
|
||||
|
|
|
@ -602,15 +602,14 @@ void LogicHandler::ShortenTENCalls()
|
|||
ShortenInner(TEN))";
|
||||
|
||||
ExecuteString(str);
|
||||
|
||||
m_shortenedCalls = true;
|
||||
}
|
||||
|
||||
void LogicHandler::ExecuteScriptFile(const std::string & luaFilename)
|
||||
{
|
||||
if (!m_shortenedCalls)
|
||||
{
|
||||
ShortenTENCalls();
|
||||
m_shortenedCalls = true;
|
||||
}
|
||||
|
||||
m_handler.ExecuteScript(luaFilename);
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ public:
|
|||
void RemoveCallback(CallbackPoint point, LevelFunc const & lf);
|
||||
|
||||
void ResetScripts(bool clearGameVars) override;
|
||||
void ShortenTENCalls();
|
||||
void ShortenTENCalls() override;
|
||||
|
||||
sol::object GetLevelFuncsMember(sol::table tab, std::string const& luaName);
|
||||
|
||||
|
|
|
@ -283,7 +283,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
|||
{
|
||||
g_GameFlow = ScriptInterfaceState::CreateFlow();
|
||||
g_GameScriptEntities = ScriptInterfaceState::CreateObjectsHandler();
|
||||
g_GameFlow->LoadFlowScript();
|
||||
g_GameStringsHandler = ScriptInterfaceState::CreateStringsHandler();
|
||||
|
||||
// This must be loaded last as it adds metafunctions to the global
|
||||
|
@ -293,6 +292,13 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
|||
// are added to a hierarchy in the REAL global table, not the fake
|
||||
// hidden one.
|
||||
g_GameScript = ScriptInterfaceState::CreateGame();
|
||||
|
||||
//todo Major hack. This should not be needed to leak outside of
|
||||
//LogicHandler internals. In a future version stuff from FlowHandler
|
||||
//should be moved to LogicHandler or vice versa to make this stuff
|
||||
//less fragile (squidshire, 16/09/22)
|
||||
g_GameScript->ShortenTENCalls();
|
||||
g_GameFlow->LoadFlowScript();
|
||||
}
|
||||
catch (TENScriptException const& e)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue