2021-09-16 05:06:03 +03:00
# include "framework.h"
2021-12-22 16:23:57 +03:00
# include "Game/animation.h"
2021-12-24 03:32:19 +03:00
2021-12-22 16:23:57 +03:00
# include "Game/camera.h"
# include "Game/control/flipeffect.h"
# include "Game/collision/collide_room.h"
2021-12-24 03:32:19 +03:00
# include "Game/items.h"
# include "Game/Lara/lara.h"
2022-02-12 00:25:05 +11:00
# include "Game/Lara/lara_helpers.h"
2022-02-08 01:26:59 +11:00
# include "Objects/Generic/Object/rope.h"
2021-12-24 03:32:19 +03:00
# include "Renderer/Renderer11.h"
# include "Sound/sound.h"
# include "Specific/level.h"
# include "Specific/setup.h"
2021-09-25 11:27:47 +02:00
2022-02-08 01:26:59 +11:00
using namespace TEN : : Entities : : Generic ;
2021-09-16 05:06:03 +03:00
using TEN : : Renderer : : g_Renderer ;
BOUNDING_BOX InterpolatedBounds ;
2022-02-08 01:26:59 +11:00
void AnimateLara ( ITEM_INFO * item )
{
2022-02-28 21:02:19 +11:00
auto * lara = GetLaraInfo ( item ) ;
2022-02-08 01:26:59 +11:00
2022-02-09 16:55:46 +11:00
item - > FrameNumber + + ;
2022-02-08 01:26:59 +11:00
2022-02-09 16:55:46 +11:00
auto * anim = & g_Level . Anims [ item - > AnimNumber ] ;
2022-02-08 01:26:59 +11:00
if ( anim - > numberChanges > 0 & & GetChange ( item , anim ) )
{
2022-02-09 16:55:46 +11:00
anim = & g_Level . Anims [ item - > AnimNumber ] ;
item - > ActiveState = anim - > ActiveState ;
2022-02-08 01:26:59 +11:00
}
2022-02-09 16:55:46 +11:00
if ( item - > FrameNumber > anim - > frameEnd )
2022-02-08 01:26:59 +11:00
{
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 , cmd [ 0 ] , cmd [ 1 ] , cmd [ 2 ] ) ;
UpdateItemRoom ( item , - LARA_HEIGHT / 2 , - cmd [ 0 ] , - cmd [ 2 ] ) ;
cmd + = 3 ;
break ;
case COMMAND_JUMP_VELOCITY :
2022-02-09 13:20:57 +11:00
item - > VerticalVelocity = * ( cmd + + ) ;
item - > Velocity = * ( cmd + + ) ;
item - > Airborne = true ;
2022-02-28 21:02:19 +11:00
if ( lara - > Control . CalculatedJumpVelocity )
2022-02-08 01:26:59 +11:00
{
2022-02-28 21:02:19 +11:00
item - > VerticalVelocity = lara - > Control . CalculatedJumpVelocity ;
lara - > Control . CalculatedJumpVelocity = 0 ;
2022-02-08 01:26:59 +11:00
}
break ;
case COMMAND_ATTACK_READY :
2022-02-28 21:02:19 +11:00
if ( lara - > Control . HandStatus ! = HandStatus : : Special )
lara - > Control . HandStatus = HandStatus : : Free ;
2022-02-08 01:26:59 +11:00
break ;
case COMMAND_SOUND_FX :
case COMMAND_EFFECT :
cmd + = 2 ;
break ;
default :
break ;
}
}
}
2022-02-09 16:55:46 +11:00
item - > AnimNumber = anim - > jumpAnimNum ;
item - > FrameNumber = anim - > jumpFrameNum ;
2022-02-08 01:26:59 +11:00
2022-02-09 16:55:46 +11:00
anim = & g_Level . Anims [ item - > AnimNumber ] ;
item - > ActiveState = anim - > ActiveState ;
2022-02-08 01:26:59 +11:00
}
if ( anim - > numberCommands > 0 )
{
short * cmd = & g_Level . Commands [ anim - > commandIndex ] ;
int flags ;
int effectID = 0 ;
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 :
2022-02-09 16:55:46 +11:00
if ( item - > FrameNumber ! = * cmd )
2022-02-08 01:26:59 +11:00
{
cmd + = 2 ;
break ;
}
flags = cmd [ 1 ] & 0xC000 ;
if ( flags = = ( int ) SOUND_PLAYCONDITION : : LandAndWater | |
2022-02-28 21:02:19 +11:00
( flags = = ( int ) SOUND_PLAYCONDITION : : Land & & ( lara - > WaterSurfaceDist > = 0 | | lara - > WaterSurfaceDist = = NO_HEIGHT ) ) | |
( flags = = ( int ) SOUND_PLAYCONDITION : : Water & & lara - > WaterSurfaceDist < 0 & & lara - > WaterSurfaceDist ! = NO_HEIGHT & & ! TestEnvironment ( ENV_FLAG_SWAMP , item ) ) )
2022-02-08 01:26:59 +11:00
{
2022-02-09 16:55:46 +11:00
SoundEffect ( cmd [ 1 ] & 0x3FFF , & item - > Position , 2 ) ;
2022-02-08 01:26:59 +11:00
}
cmd + = 2 ;
break ;
case COMMAND_EFFECT :
2022-02-09 16:55:46 +11:00
if ( item - > FrameNumber ! = * cmd )
2022-02-08 01:26:59 +11:00
{
cmd + = 2 ;
break ;
}
effectID = cmd [ 1 ] & 0x3FFF ;
DoFlipEffect ( effectID , item ) ;
cmd + = 2 ;
break ;
default :
break ;
}
}
}
int lateral = anim - > Xvelocity ;
if ( anim - > Xacceleration )
2022-02-09 16:55:46 +11:00
lateral + = anim - > Xacceleration * ( item - > FrameNumber - anim - > frameBase ) ;
2022-03-08 18:22:14 +11:00
item - > LateralVelocity = lateral > > = 16 ;
2022-02-08 01:26:59 +11:00
2022-02-09 13:20:57 +11:00
if ( item - > Airborne )
2022-02-08 01:26:59 +11:00
{
if ( TestEnvironment ( ENV_FLAG_SWAMP , item ) )
{
2022-02-09 13:20:57 +11:00
item - > Velocity - = item - > Velocity > > 3 ;
if ( abs ( item - > Velocity ) < 8 )
2022-02-08 01:26:59 +11:00
{
2022-02-09 13:20:57 +11:00
item - > Velocity = 0 ;
item - > Airborne = false ;
2022-02-08 01:26:59 +11:00
}
2022-02-09 13:20:57 +11:00
if ( item - > VerticalVelocity > 128 )
item - > VerticalVelocity / = 2 ;
item - > VerticalVelocity - = item - > VerticalVelocity / 4 ;
if ( item - > VerticalVelocity < 4 )
item - > VerticalVelocity = 4 ;
2022-02-09 16:55:46 +11:00
item - > Position . yPos + = item - > VerticalVelocity ;
2022-02-08 01:26:59 +11:00
}
else
{
2022-02-09 16:55:46 +11:00
int velocity = ( anim - > velocity + anim - > acceleration * ( item - > FrameNumber - anim - > frameBase - 1 ) ) ;
2022-02-09 13:20:57 +11:00
item - > Velocity - = velocity > > 16 ;
item - > Velocity + = ( velocity + anim - > acceleration ) > > 16 ;
item - > VerticalVelocity + = ( item - > VerticalVelocity > = 128 ? 1 : GRAVITY ) ;
2022-02-09 16:55:46 +11:00
item - > Position . yPos + = item - > VerticalVelocity ;
2022-02-08 01:26:59 +11:00
}
}
else
{
int velocity ;
2022-02-28 21:02:19 +11:00
if ( lara - > Control . WaterStatus = = WaterStatus : : Wade & & TestEnvironment ( ENV_FLAG_SWAMP , item ) )
2022-02-08 01:26:59 +11:00
{
velocity = ( anim - > velocity > > 1 ) ;
if ( anim - > acceleration )
2022-02-09 16:55:46 +11:00
velocity + = ( anim - > acceleration * ( item - > FrameNumber - anim - > frameBase ) ) > > 2 ;
2022-02-08 01:26:59 +11:00
}
else
{
velocity = anim - > velocity ;
if ( anim - > acceleration )
2022-02-09 16:55:46 +11:00
velocity + = anim - > acceleration * ( item - > FrameNumber - anim - > frameBase ) ;
2022-02-08 01:26:59 +11:00
}
2022-02-09 13:20:57 +11:00
item - > Velocity = velocity > > 16 ;
2022-02-08 01:26:59 +11:00
}
2022-03-09 13:03:21 +11:00
// TEMP
2022-03-08 18:22:14 +11:00
item - > Velocity + = lara - > ExtraVelocity . x ;
item - > VerticalVelocity + = lara - > ExtraVelocity . y ;
item - > LateralVelocity + = lara - > ExtraVelocity . z ;
2022-03-09 17:04:19 +11:00
if ( lara - > Control . Rope . Ptr ! = - 1 )
2022-02-08 01:26:59 +11:00
DelAlignLaraToRope ( item ) ;
2022-02-28 21:02:19 +11:00
if ( ! lara - > Control . IsMoving )
2022-03-08 18:22:14 +11:00
MoveItem ( item , lara - > Control . MoveAngle , item - > Velocity , item - > LateralVelocity ) ;
2022-02-08 01:26:59 +11:00
2022-03-09 13:03:21 +11:00
// TEMP
lara - > ExtraVelocity = PHD_VECTOR ( ) ;
2022-02-08 01:26:59 +11:00
// Update matrices
g_Renderer . updateLaraAnimations ( true ) ;
}
2021-09-16 05:06:03 +03:00
void AnimateItem ( ITEM_INFO * item )
{
2022-02-09 16:55:46 +11:00
item - > TouchBits = 0 ;
item - > HitStatus = false ;
2021-09-16 05:06:03 +03:00
2022-02-09 16:55:46 +11:00
item - > FrameNumber + + ;
2021-09-16 05:06:03 +03:00
2022-02-09 16:55:46 +11:00
auto * anim = & g_Level . Anims [ item - > AnimNumber ] ;
2021-09-16 05:06:03 +03:00
if ( anim - > numberChanges > 0 & & GetChange ( item , anim ) )
{
2022-02-09 16:55:46 +11:00
anim = & g_Level . Anims [ item - > AnimNumber ] ;
2021-09-16 05:06:03 +03:00
2022-02-09 16:55:46 +11:00
item - > ActiveState = anim - > ActiveState ;
if ( item - > RequiredState = = item - > ActiveState )
item - > RequiredState = 0 ;
2021-09-16 05:06:03 +03:00
}
2022-02-09 16:55:46 +11:00
if ( item - > FrameNumber > anim - > frameEnd )
2021-09-16 05:06:03 +03:00
{
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 , cmd [ 0 ] , cmd [ 1 ] , cmd [ 2 ] ) ;
cmd + = 3 ;
break ;
case COMMAND_JUMP_VELOCITY :
2022-02-09 13:20:57 +11:00
item - > VerticalVelocity = * ( cmd + + ) ;
item - > Velocity = * ( cmd + + ) ;
item - > Airborne = true ;
2021-09-16 05:06:03 +03:00
break ;
case COMMAND_DEACTIVATE :
2022-02-09 16:55:46 +11:00
if ( Objects [ item - > ObjectNumber ] . intelligent & & ! item - > AfterDeath )
item - > AfterDeath = 1 ;
2022-03-09 13:03:21 +11:00
2022-02-09 16:55:46 +11:00
item - > Status = ITEM_DEACTIVATED ;
2021-09-16 05:06:03 +03:00
break ;
2022-02-08 01:26:59 +11:00
2021-09-16 05:06:03 +03:00
case COMMAND_SOUND_FX :
case COMMAND_EFFECT :
cmd + = 2 ;
break ;
default :
break ;
}
}
}
2022-02-09 16:55:46 +11:00
item - > AnimNumber = anim - > jumpAnimNum ;
item - > FrameNumber = anim - > jumpFrameNum ;
2021-09-16 05:06:03 +03:00
2022-02-09 16:55:46 +11:00
anim = & g_Level . Anims [ item - > AnimNumber ] ;
if ( item - > ActiveState ! = anim - > ActiveState )
2021-09-16 05:06:03 +03:00
{
2022-02-09 16:55:46 +11:00
item - > ActiveState = anim - > ActiveState ;
item - > TargetState = anim - > ActiveState ;
2021-09-16 05:06:03 +03:00
}
2022-02-09 16:55:46 +11:00
if ( item - > RequiredState = = item - > ActiveState )
item - > RequiredState = 0 ;
2021-09-16 05:06:03 +03:00
}
if ( anim - > numberCommands > 0 )
{
short * cmd = & g_Level . Commands [ anim - > commandIndex ] ;
int flags ;
int effectID = 0 ;
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 :
2022-02-09 16:55:46 +11:00
if ( item - > FrameNumber ! = * cmd )
2021-09-16 05:06:03 +03:00
{
cmd + = 2 ;
break ;
}
flags = cmd [ 1 ] & 0xC000 ;
2022-02-09 16:55:46 +11:00
if ( ! Objects [ item - > ObjectNumber ] . waterCreature )
2021-09-16 05:06:03 +03:00
{
2022-02-09 16:55:46 +11:00
if ( item - > RoomNumber = = NO_ROOM )
2021-09-16 05:06:03 +03:00
{
2022-02-09 16:55:46 +11:00
item - > Position . xPos = LaraItem - > Position . xPos ;
item - > Position . yPos = LaraItem - > Position . yPos - 762 ;
item - > Position . zPos = LaraItem - > Position . zPos ;
2021-09-16 05:06:03 +03:00
2022-02-09 16:55:46 +11:00
SoundEffect ( cmd [ 1 ] & 0x3FFF , & item - > Position , 2 ) ;
2021-09-16 05:06:03 +03:00
}
2022-02-04 22:18:55 +11:00
else if ( TestEnvironment ( ENV_FLAG_WATER , item ) )
2021-09-16 05:06:03 +03:00
{
2022-02-09 16:55:46 +11:00
if ( ! flags | | flags = = ( int ) SOUND_PLAYCONDITION : : Water & & ( TestEnvironment ( ENV_FLAG_WATER , Camera . pos . roomNumber ) | | Objects [ item - > ObjectNumber ] . intelligent ) )
SoundEffect ( cmd [ 1 ] & 0x3FFF , & item - > Position , 2 ) ;
2021-09-16 05:06:03 +03:00
}
2022-02-04 22:18:55 +11:00
else if ( ! flags | | flags = = ( int ) SOUND_PLAYCONDITION : : Land & & ! TestEnvironment ( ENV_FLAG_WATER , Camera . pos . roomNumber ) )
2022-02-09 16:55:46 +11:00
SoundEffect ( cmd [ 1 ] & 0x3FFF , & item - > Position , 2 ) ;
2021-09-16 05:06:03 +03:00
}
else
{
2022-02-04 22:18:55 +11:00
if ( TestEnvironment ( ENV_FLAG_WATER , item ) )
2022-02-09 16:55:46 +11:00
SoundEffect ( cmd [ 1 ] & 0x3FFF , & item - > Position , 1 ) ;
2021-09-16 05:06:03 +03:00
else
2022-02-09 16:55:46 +11:00
SoundEffect ( cmd [ 1 ] & 0x3FFF , & item - > Position , 0 ) ;
2021-09-16 05:06:03 +03:00
}
2022-02-08 01:26:59 +11:00
2021-09-16 05:06:03 +03:00
break ;
case COMMAND_EFFECT :
2022-02-09 16:55:46 +11:00
if ( item - > FrameNumber ! = * cmd )
2021-09-16 05:06:03 +03:00
{
cmd + = 2 ;
break ;
}
effectID = cmd [ 1 ] & 0x3FFF ;
DoFlipEffect ( effectID , item ) ;
cmd + = 2 ;
break ;
default :
break ;
}
}
}
int lateral = 0 ;
2022-02-09 13:20:57 +11:00
if ( item - > Airborne )
2021-09-16 05:06:03 +03:00
{
2022-02-09 13:20:57 +11:00
item - > VerticalVelocity + = ( item - > VerticalVelocity > = 128 ? 1 : 6 ) ;
2022-02-09 16:55:46 +11:00
item - > Position . yPos + = item - > VerticalVelocity ;
2021-09-16 05:06:03 +03:00
}
else
{
int velocity = anim - > velocity ;
if ( anim - > acceleration )
2022-02-09 16:55:46 +11:00
velocity + = anim - > acceleration * ( item - > FrameNumber - anim - > frameBase ) ;
2022-02-08 01:26:59 +11:00
2022-02-09 13:20:57 +11:00
item - > Velocity = velocity > > 16 ;
2021-09-16 05:06:03 +03:00
lateral = anim - > Xvelocity ;
if ( anim - > Xacceleration )
2022-02-09 16:55:46 +11:00
lateral + = anim - > Xacceleration * ( item - > FrameNumber - anim - > frameBase ) ;
2021-09-16 05:06:03 +03:00
lateral > > = 16 ;
}
2022-02-09 16:55:46 +11:00
MoveItem ( item , item - > Position . yRot , item - > Velocity , lateral ) ;
2021-09-16 05:06:03 +03:00
2022-02-08 01:26:59 +11:00
// Update matrices.
2021-09-16 05:06:03 +03:00
short itemNumber = item - g_Level . Items . data ( ) ;
g_Renderer . updateItemAnimations ( itemNumber , true ) ;
}
void TranslateItem ( ITEM_INFO * item , int x , int y , int z )
{
2022-02-09 16:55:46 +11:00
float c = phd_cos ( item - > Position . yRot ) ;
float s = phd_sin ( item - > Position . yRot ) ;
2021-09-16 05:06:03 +03:00
2022-02-09 16:55:46 +11:00
item - > Position . xPos + = roundf ( c * x + s * z ) ;
item - > Position . yPos + = y ;
item - > Position . zPos + = roundf ( - s * x + c * z ) ;
2021-09-16 05:06:03 +03:00
}
2021-12-13 16:12:33 +11:00
bool GetChange ( ITEM_INFO * item , ANIM_STRUCT * anim )
2021-09-16 05:06:03 +03:00
{
2022-02-09 16:55:46 +11:00
if ( item - > ActiveState = = item - > TargetState )
2021-12-13 16:12:33 +11:00
return false ;
2021-09-16 05:06:03 +03:00
if ( anim - > numberChanges < = 0 )
2021-12-13 16:12:33 +11:00
return false ;
2021-09-16 05:06:03 +03:00
for ( int i = 0 ; i < anim - > numberChanges ; i + + )
{
2022-02-08 01:26:59 +11:00
auto * change = & g_Level . Changes [ anim - > changeIndex + i ] ;
2022-02-09 16:55:46 +11:00
if ( change - > TargetState = = item - > TargetState )
2021-09-16 05:06:03 +03:00
{
for ( int j = 0 ; j < change - > numberRanges ; j + + )
{
2022-02-08 01:26:59 +11:00
auto * range = & g_Level . Ranges [ change - > rangeIndex + j ] ;
2022-02-09 16:55:46 +11:00
if ( item - > FrameNumber > = range - > startFrame & & item - > FrameNumber < = range - > endFrame )
2021-09-16 05:06:03 +03:00
{
2022-02-09 16:55:46 +11:00
item - > AnimNumber = range - > linkAnimNum ;
item - > FrameNumber = range - > linkFrameNum ;
2021-12-13 16:12:33 +11:00
return true ;
2021-09-16 05:06:03 +03:00
}
}
}
}
2021-12-13 16:12:33 +11:00
return false ;
2021-09-16 05:06:03 +03:00
}
BOUNDING_BOX * GetBoundsAccurate ( ITEM_INFO * item )
{
int rate = 0 ;
ANIM_FRAME * framePtr [ 2 ] ;
int frac = GetFrame ( item , framePtr , & rate ) ;
if ( frac = = 0 )
return & framePtr [ 0 ] - > boundingBox ;
else
{
InterpolatedBounds . X1 = framePtr [ 0 ] - > boundingBox . X1 + ( framePtr [ 1 ] - > boundingBox . X1 - framePtr [ 0 ] - > boundingBox . X1 ) * frac / rate ;
InterpolatedBounds . X2 = framePtr [ 0 ] - > boundingBox . X2 + ( framePtr [ 1 ] - > boundingBox . X2 - framePtr [ 0 ] - > boundingBox . X2 ) * frac / rate ;
InterpolatedBounds . Y1 = framePtr [ 0 ] - > boundingBox . Y1 + ( framePtr [ 1 ] - > boundingBox . Y1 - framePtr [ 0 ] - > boundingBox . Y1 ) * frac / rate ;
InterpolatedBounds . Y2 = framePtr [ 0 ] - > boundingBox . Y2 + ( framePtr [ 1 ] - > boundingBox . Y2 - framePtr [ 0 ] - > boundingBox . Y2 ) * frac / rate ;
InterpolatedBounds . Z1 = framePtr [ 0 ] - > boundingBox . Z1 + ( framePtr [ 1 ] - > boundingBox . Z1 - framePtr [ 0 ] - > boundingBox . Z1 ) * frac / rate ;
InterpolatedBounds . Z2 = framePtr [ 0 ] - > boundingBox . Z2 + ( framePtr [ 1 ] - > boundingBox . Z2 - framePtr [ 0 ] - > boundingBox . Z2 ) * frac / rate ;
return & InterpolatedBounds ;
}
}
ANIM_FRAME * GetBestFrame ( ITEM_INFO * item )
{
int rate = 0 ;
ANIM_FRAME * framePtr [ 2 ] ;
int frac = GetFrame ( item , framePtr , & rate ) ;
if ( frac < = ( rate > > 1 ) )
return framePtr [ 0 ] ;
else
return framePtr [ 1 ] ;
}
int GetFrame ( ITEM_INFO * item , ANIM_FRAME * framePtr [ ] , int * rate )
{
2022-02-09 16:55:46 +11:00
int frame = item - > FrameNumber ;
auto * anim = & g_Level . Anims [ item - > AnimNumber ] ;
2021-09-16 05:06:03 +03:00
framePtr [ 0 ] = framePtr [ 1 ] = & g_Level . Frames [ anim - > framePtr ] ;
2022-02-08 01:26:59 +11:00
int rate2 = * rate = anim - > interpolation & 0x00ff ;
frame - = anim - > frameBase ;
int first = frame / rate2 ;
int interpolation = frame % rate2 ;
framePtr [ 0 ] + = first ; // Get frame pointers...
framePtr [ 1 ] = framePtr [ 0 ] + 1 ; // and store away.
if ( interpolation = = 0 )
return 0 ;
// Clamp key frame to end if need be.
int second = first * rate2 + rate2 ;
if ( second > anim - > frameEnd )
* rate = anim - > frameEnd - ( second - rate2 ) ;
return interpolation ;
2021-09-16 05:06:03 +03:00
}
2022-02-03 19:29:07 +11:00
int GetCurrentRelativeFrameNumber ( ITEM_INFO * item )
2021-12-21 20:43:37 +03:00
{
2022-02-09 16:55:46 +11:00
return item - > FrameNumber - GetFrameNumber ( item , 0 ) ;
2021-12-21 20:43:37 +03:00
}
2021-12-22 12:17:59 +03:00
int GetFrameNumber ( ITEM_INFO * item , int frameToStart )
2021-11-10 02:41:59 +03:00
{
2022-02-09 16:55:46 +11:00
return GetFrameNumber ( item - > ObjectNumber , item - > AnimNumber , frameToStart ) ;
2021-11-10 02:41:59 +03:00
}
2021-12-22 12:17:59 +03:00
int GetFrameNumber ( int objectID , int animNumber , int frameToStart )
2021-11-10 02:41:59 +03:00
{
2022-02-08 01:26:59 +11:00
return ( g_Level . Anims [ Objects [ objectID ] . animIndex + animNumber ] . frameBase + frameToStart ) ;
2021-11-10 02:41:59 +03:00
}
2021-12-22 12:17:59 +03:00
int GetFrameCount ( int animNumber )
2021-11-29 18:09:34 +03:00
{
if ( animNumber < 0 | | g_Level . Anims . size ( ) < = animNumber )
return 0 ;
2021-12-21 20:43:37 +03:00
int end = g_Level . Anims [ animNumber ] . frameEnd ;
int base = g_Level . Anims [ animNumber ] . frameBase ;
return ( end - base ) ;
2021-11-29 18:09:34 +03:00
}
2021-12-10 11:04:28 +03:00
int GetNextAnimState ( ITEM_INFO * item )
{
2022-02-09 16:55:46 +11:00
return GetNextAnimState ( item - > ObjectNumber , item - > AnimNumber ) ;
2021-12-10 11:04:28 +03:00
}
2021-12-22 12:17:59 +03:00
int GetNextAnimState ( int objectID , int animNumber )
2021-12-10 11:04:28 +03:00
{
auto nextAnim = g_Level . Anims [ Objects [ objectID ] . animIndex + animNumber ] . jumpAnimNum ;
2022-02-09 16:55:46 +11:00
return g_Level . Anims [ Objects [ objectID ] . animIndex + nextAnim ] . ActiveState ;
2021-12-10 11:04:28 +03:00
}
2021-11-29 18:09:34 +03:00
2021-12-22 12:17:59 +03:00
void SetAnimation ( ITEM_INFO * item , int animIndex , int frameToStart )
2021-11-10 02:41:59 +03:00
{
2022-02-09 16:55:46 +11:00
auto index = Objects [ item - > ObjectNumber ] . animIndex + animIndex ;
2021-11-10 02:41:59 +03:00
if ( index < 0 | | index > = g_Level . Anims . size ( ) )
{
2022-02-09 16:55:46 +11:00
TENLog ( std : : string ( " Attempt to set nonexistent animation " ) + std : : to_string ( animIndex ) + std : : string ( " for object " ) + std : : to_string ( item - > ObjectNumber ) , LogLevel : : Warning ) ;
2021-11-10 02:41:59 +03:00
return ;
}
2022-02-09 16:55:46 +11:00
if ( item - > AnimNumber = = animIndex )
2021-12-01 16:11:18 +03:00
return ;
2022-02-09 16:55:46 +11:00
item - > AnimNumber = index ;
item - > FrameNumber = g_Level . Anims [ index ] . frameBase + frameToStart ;
item - > ActiveState = g_Level . Anims [ index ] . ActiveState ;
item - > TargetState = item - > ActiveState ;
2021-11-10 02:41:59 +03:00
}
2021-12-22 12:17:59 +03:00
bool TestLastFrame ( ITEM_INFO * item , int animNumber )
2021-11-10 02:41:59 +03:00
{
2021-11-30 03:24:50 +03:00
if ( animNumber < 0 )
2022-02-09 16:55:46 +11:00
animNumber = item - > AnimNumber ;
2021-11-30 03:24:50 +03:00
2022-02-09 16:55:46 +11:00
if ( item - > AnimNumber ! = animNumber )
2021-11-10 02:41:59 +03:00
return false ;
2022-02-08 01:26:59 +11:00
auto * anim = & g_Level . Anims [ animNumber ] ;
2022-02-09 16:55:46 +11:00
return ( item - > FrameNumber > = anim - > frameEnd ) ;
2021-11-10 02:41:59 +03:00
}
2021-09-16 05:06:03 +03:00
void DrawAnimatingItem ( ITEM_INFO * item )
{
// TODO: to refactor
// Empty stub because actually we disable items drawing when drawRoutine pointer is NULL in OBJECT_INFO
}
2022-02-08 01:26:59 +11:00
void GetLaraJointPosition ( PHD_VECTOR * pos , int laraMeshIndex )
2021-09-16 05:06:03 +03:00
{
2022-02-08 01:26:59 +11:00
if ( laraMeshIndex > = NUM_LARA_MESHES )
laraMeshIndex = LM_HEAD ;
2021-09-16 05:06:03 +03:00
2022-02-08 01:26:59 +11:00
auto pos2 = Vector3 ( pos - > x , pos - > y , pos - > z ) ;
g_Renderer . getLaraAbsBonePosition ( & pos2 , laraMeshIndex ) ;
2021-09-16 05:06:03 +03:00
2022-02-08 01:26:59 +11:00
pos - > x = pos2 . x ;
pos - > y = pos2 . y ;
pos - > z = pos2 . z ;
2021-09-16 05:06:03 +03:00
}
void ClampRotation ( PHD_3DPOS * pos , short angle , short rot )
{
if ( angle < = rot )
{
if ( angle > = - rot )
pos - > yRot + = angle ;
else
pos - > yRot - = rot ;
}
else
pos - > yRot + = rot ;
2021-11-14 14:56:26 +11:00
}