2021-09-22 10:55:48 +02:00
# include "framework.h"
# include "Objects/Generic/Traps/dart_emitter.h"
2021-12-22 16:23:57 +03:00
# include "Specific/level.h"
2022-03-14 15:18:11 +11:00
# include "Game/collision/collide_room.h"
2021-12-22 16:23:57 +03:00
# include "Game/Lara/lara.h"
# include "Game/effects/effects.h"
# include "Game/items.h"
2021-09-25 16:00:30 +03:00
# include "Sound/sound.h"
2021-09-25 11:27:47 +02:00
2021-09-22 10:55:48 +02:00
namespace TEN : : Entities : : Traps
{
void DartControl ( short itemNumber )
{
2022-03-09 17:04:19 +11:00
auto * item = & g_Level . Items [ itemNumber ] ;
2021-09-22 10:55:48 +02:00
2022-02-09 16:55:46 +11:00
if ( item - > TouchBits )
2021-09-22 10:55:48 +02:00
{
2022-02-09 16:55:46 +11:00
LaraItem - > HitPoints - = 25 ;
LaraItem - > HitStatus = true ;
2022-03-09 17:04:19 +11:00
Lara . PoisonPotency + = 1 ; // Was 160 with the total poison potency later shifted right by 8 when applied to Lara's health. The effect was that each dart contributed a mere fraction to the potency. @Sezz 2022.03.09
2022-02-09 16:55:46 +11:00
DoBloodSplat ( item - > Position . xPos , item - > Position . yPos , item - > Position . zPos , ( GetRandomControl ( ) & 3 ) + 4 , LaraItem - > Position . yRot , LaraItem - > RoomNumber ) ;
2021-09-22 10:55:48 +02:00
KillItem ( itemNumber ) ;
}
else
{
2022-02-09 16:55:46 +11:00
int oldX = item - > Position . xPos ;
2022-03-09 17:04:19 +11:00
int oldZ = item - > Position . zPos - 1000 ;
2021-09-22 10:55:48 +02:00
2022-03-13 02:04:24 +11:00
int velocity = item - > Animation . Velocity * phd_cos ( item - > Position . xRot ) ;
2021-09-22 10:55:48 +02:00
2022-03-09 17:04:19 +11:00
item - > Position . xPos + = velocity * phd_sin ( item - > Position . yRot ) ;
2022-03-13 02:04:24 +11:00
item - > Position . yPos - = item - > Animation . Velocity * phd_sin ( item - > Position . xRot ) ;
2022-03-09 17:04:19 +11:00
item - > Position . zPos + = velocity * phd_cos ( item - > Position . yRot ) ;
2021-09-22 10:55:48 +02:00
2022-02-09 16:55:46 +11:00
short roomNumber = item - > RoomNumber ;
FLOOR_INFO * floor = GetFloor ( item - > Position . xPos , item - > Position . yPos , item - > Position . zPos , & roomNumber ) ;
2021-09-22 10:55:48 +02:00
2022-02-09 16:55:46 +11:00
if ( item - > RoomNumber ! = roomNumber )
2021-09-22 10:55:48 +02:00
ItemNewRoom ( itemNumber , roomNumber ) ;
2022-02-09 16:55:46 +11:00
int height = GetFloorHeight ( floor , item - > Position . xPos , item - > Position . yPos , item - > Position . zPos ) ;
item - > Floor = height ;
2021-09-22 10:55:48 +02:00
2022-02-09 16:55:46 +11:00
if ( item - > Position . yPos > = height )
2021-09-22 10:55:48 +02:00
{
for ( int i = 0 ; i < 4 ; i + + )
2022-02-09 16:55:46 +11:00
TriggerDartSmoke ( oldX , item - > Position . yPos , oldZ , 0 , 0 , true ) ;
2021-09-22 10:55:48 +02:00
KillItem ( itemNumber ) ;
}
}
}
void DartEmitterControl ( short itemNumber )
{
ITEM_INFO * item = & g_Level . Items [ itemNumber ] ;
2022-02-09 16:55:46 +11:00
if ( item - > Active )
2021-09-22 10:55:48 +02:00
{
2022-02-09 16:55:46 +11:00
if ( item - > Timer > 0 )
2021-09-22 10:55:48 +02:00
{
2022-02-09 16:55:46 +11:00
item - > Timer - - ;
2021-09-22 10:55:48 +02:00
return ;
}
else
2022-02-09 16:55:46 +11:00
item - > Timer = 24 ;
2021-09-22 10:55:48 +02:00
}
short dartItemNumber = CreateItem ( ) ;
if ( dartItemNumber ! = NO_ITEM )
{
ITEM_INFO * dartItem = & g_Level . Items [ dartItemNumber ] ;
2022-02-09 16:55:46 +11:00
dartItem - > ObjectNumber = ID_DARTS ;
dartItem - > RoomNumber = item - > RoomNumber ;
2021-09-22 10:55:48 +02:00
int x = 0 ;
int z = 0 ;
2022-02-09 16:55:46 +11:00
switch ( item - > Position . yRot )
2021-09-22 10:55:48 +02:00
{
case 0 :
z = WALL_SIZE / 2 ;
break ;
case 0x4000 :
x = WALL_SIZE / 2 ;
break ;
case - 0x8000 :
z = - WALL_SIZE / 2 ;
break ;
case - 0x4000 :
x = - WALL_SIZE / 2 ;
break ;
}
2022-02-09 16:55:46 +11:00
dartItem - > Position . xPos = x + item - > Position . xPos ;
dartItem - > Position . yPos = item - > Position . yPos - WALL_SIZE / 2 ;
dartItem - > Position . zPos = z + item - > Position . zPos ;
2021-09-22 10:55:48 +02:00
InitialiseItem ( dartItemNumber ) ;
2022-02-09 16:55:46 +11:00
dartItem - > Position . xRot = 0 ;
dartItem - > Position . yRot = item - > Position . yRot + - ANGLE ( 180 ) ;
2022-03-13 02:04:24 +11:00
dartItem - > Animation . Velocity = 256 ;
2021-09-22 10:55:48 +02:00
int xf = 0 ;
int zf = 0 ;
if ( x )
xf = abs ( 2 * x ) - 1 ;
else
zf = abs ( 2 * z ) - 1 ;
for ( int i = 0 ; i < 5 ; i + + )
{
int random = - GetRandomControl ( ) ;
int xv = 0 ;
int zv = 0 ;
if ( z > = 0 )
zv = zf & random ;
else
zv = - ( zf & random ) ;
if ( x > = 0 )
xv = xf & random ;
else
xv = - ( xf & random ) ;
2022-02-09 16:55:46 +11:00
TriggerDartSmoke ( dartItem - > Position . xPos , dartItem - > Position . yPos , dartItem - > Position . zPos , xv , zv , false ) ;
2021-09-22 10:55:48 +02:00
}
AddActiveItem ( dartItemNumber ) ;
2022-02-09 16:55:46 +11:00
dartItem - > Status = ITEM_ACTIVE ;
2021-09-22 10:55:48 +02:00
2022-02-09 16:55:46 +11:00
SoundEffect ( SFX_TR4_DART_SPITT , & dartItem - > Position , 0 ) ;
2021-09-22 10:55:48 +02:00
}
}
void TriggerDartSmoke ( int x , int y , int z , int xv , int zv , bool hit )
{
2022-02-09 16:55:46 +11:00
int dx = LaraItem - > Position . xPos - x ;
int dz = LaraItem - > Position . zPos - z ;
2021-09-22 10:55:48 +02:00
if ( dx < - 16384 | | dx > 16384 | | dz < - 16384 | | dz > 16384 )
return ;
SPARKS * spark = & Sparks [ GetFreeSpark ( ) ] ;
spark - > on = true ;
spark - > sR = 16 ;
spark - > sG = 8 ;
spark - > sB = 4 ;
spark - > dR = 64 ;
spark - > dG = 48 ;
spark - > dB = 32 ;
spark - > colFadeSpeed = 8 ;
spark - > fadeToBlack = 4 ;
2021-09-25 16:03:28 -05:00
spark - > transType = TransTypeEnum : : COLADD ;
2021-09-22 10:55:48 +02:00
spark - > life = spark - > sLife = ( GetRandomControl ( ) & 3 ) + 32 ;
spark - > x = x + ( ( GetRandomControl ( ) & 31 ) - 16 ) ;
spark - > y = y + ( ( GetRandomControl ( ) & 31 ) - 16 ) ;
spark - > z = z + ( ( GetRandomControl ( ) & 31 ) - 16 ) ;
if ( hit )
{
spark - > xVel = - xv + ( ( GetRandomControl ( ) & 255 ) - 128 ) ;
spark - > yVel = - ( GetRandomControl ( ) & 3 ) - 4 ;
spark - > zVel = - zv + ( ( GetRandomControl ( ) & 255 ) - 128 ) ;
spark - > friction = 3 ;
}
else
{
if ( xv )
spark - > xVel = - xv ;
else
spark - > xVel = ( ( GetRandomControl ( ) & 255 ) - 128 ) ;
spark - > yVel = - ( GetRandomControl ( ) & 3 ) - 4 ;
if ( zv )
spark - > zVel = - zv ;
else
spark - > zVel = ( ( GetRandomControl ( ) & 255 ) - 128 ) ;
spark - > friction = 3 ;
}
spark - > friction = 3 ;
if ( GetRandomControl ( ) & 1 )
{
spark - > flags = SP_EXPDEF | SP_ROTATE | SP_DEF | SP_SCALE ;
spark - > rotAng = GetRandomControl ( ) & 0xFFF ;
if ( GetRandomControl ( ) & 1 )
spark - > rotAdd = - 16 - ( GetRandomControl ( ) & 0xF ) ;
else
spark - > rotAdd = ( GetRandomControl ( ) & 0xF ) + 16 ;
}
else
{
spark - > flags = SP_EXPDEF | SP_DEF | SP_SCALE ;
}
spark - > scalar = 1 ;
int size = ( GetRandomControl ( ) & 63 ) + 72 ;
if ( hit )
{
size > > = 1 ;
spark - > size = spark - > sSize = size > > 2 ;
spark - > gravity = spark - > maxYvel = 0 ;
}
else
{
spark - > size = spark - > sSize = size > > 4 ;
spark - > gravity = - ( GetRandomControl ( ) & 3 ) - 4 ;
spark - > maxYvel = - ( GetRandomControl ( ) & 3 ) - 4 ;
}
spark - > dSize = size ;
}
}