2019-11-14 20:15:29 +01:00
|
|
|
#include "people.h"
|
|
|
|
#include "..\Global\global.h"
|
|
|
|
#include "effects.h"
|
|
|
|
#include "effect2.h"
|
|
|
|
#include "draw.h"
|
|
|
|
#include "control.h"
|
|
|
|
#include "sphere.h"
|
|
|
|
#include "debris.h"
|
2020-04-23 19:22:01 +02:00
|
|
|
#include "lara.h"
|
2020-04-24 19:15:05 +02:00
|
|
|
#include "sound.h"
|
2019-11-14 20:15:29 +01:00
|
|
|
#include "box.h"
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
int ShotLara(ITEM_INFO* item, AI_INFO* info, BITE_INFO* gun, short extra_rotation, int damage)
|
2019-11-14 20:15:29 +01:00
|
|
|
{
|
|
|
|
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
|
|
|
|
ITEM_INFO* enemy = creature->enemy;
|
|
|
|
|
2019-11-27 15:12:35 +01:00
|
|
|
int hit = 0;
|
|
|
|
int targetable = 0;
|
2019-11-14 20:15:29 +01:00
|
|
|
|
|
|
|
if (info->distance <= SQUARE(8192) && Targetable(item, info))
|
|
|
|
{
|
2019-11-27 15:12:35 +01:00
|
|
|
int distance = SIN(info->enemyFacing) * enemy->speed >> W2V_SHIFT * SQUARE(8192) / 300;
|
2019-11-14 20:15:29 +01:00
|
|
|
distance = info->distance + SQUARE(distance);
|
|
|
|
if (distance <= SQUARE(8192))
|
|
|
|
{
|
2019-11-27 15:12:35 +01:00
|
|
|
int random = (SQUARE(8192) - info->distance) / (SQUARE(8192) / 0x5000) + 8192;
|
2019-11-14 20:15:29 +01:00
|
|
|
hit = (GetRandomControl() < random);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
hit = 0;
|
|
|
|
}
|
|
|
|
targetable = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
hit = 0;
|
|
|
|
targetable = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (damage)
|
|
|
|
{
|
|
|
|
if (enemy == LaraItem)
|
|
|
|
{
|
|
|
|
if (hit)
|
|
|
|
{
|
|
|
|
CreatureEffect(item, gun, &GunHit);
|
|
|
|
LaraItem->hitPoints -= damage;
|
|
|
|
LaraItem->hitStatus = true;
|
|
|
|
}
|
|
|
|
else if (targetable)
|
|
|
|
{
|
|
|
|
CreatureEffect(item, gun, &GunMiss);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CreatureEffect(item, gun, &GunShot);
|
|
|
|
if (hit)
|
|
|
|
{
|
|
|
|
enemy->hitStatus = true;
|
|
|
|
enemy->hitPoints += damage / -10;
|
|
|
|
|
2019-11-27 15:12:35 +01:00
|
|
|
int random = GetRandomControl() & 0xF;
|
2019-11-14 20:15:29 +01:00
|
|
|
if (random > 14)
|
|
|
|
random = 0;
|
|
|
|
|
|
|
|
PHD_VECTOR pos;
|
|
|
|
pos.x = 0;
|
|
|
|
pos.y = 0;
|
|
|
|
pos.z = 0;
|
|
|
|
|
|
|
|
GetJointAbsPosition(enemy, &pos, random);
|
|
|
|
DoBloodSplat(pos.x, pos.y, pos.z, (GetRandomControl() & 3) + 4, enemy->pos.yRot, enemy->roomNumber);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: smash objects
|
|
|
|
|
|
|
|
return targetable;
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
short GunMiss(int x, int y, int z, short speed, short yrot, short roomNumber)
|
2019-11-14 20:15:29 +01:00
|
|
|
{
|
|
|
|
GAME_VECTOR pos;
|
|
|
|
|
|
|
|
pos.x = LaraItem->pos.xPos + ((GetRandomControl() - 0x4000) << 9) / 0x7FFF;
|
|
|
|
pos.y = LaraItem->floor;
|
|
|
|
pos.z = LaraItem->pos.zPos + ((GetRandomControl() - 0x4000) << 9) / 0x7FFF;
|
|
|
|
pos.roomNumber = LaraItem->roomNumber;
|
|
|
|
|
2019-12-22 00:20:10 +01:00
|
|
|
Richochet((PHD_3DPOS*)&pos);
|
2019-11-14 20:15:29 +01:00
|
|
|
|
|
|
|
return GunShot(x, y, z, speed, yrot, roomNumber);
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
short GunHit(int x, int y, int z, short speed, short yrot, short roomNumber)
|
2019-11-14 20:15:29 +01:00
|
|
|
{
|
|
|
|
PHD_VECTOR pos;
|
|
|
|
|
|
|
|
pos.x = 0;
|
|
|
|
pos.y = 0;
|
|
|
|
pos.z = 0;
|
|
|
|
|
2020-04-20 07:14:54 +02:00
|
|
|
GetLaraJointPosition(&pos, (25 * GetRandomControl()) >> 15);
|
2019-11-14 20:15:29 +01:00
|
|
|
|
|
|
|
DoBloodSplat(pos.x, pos.y, pos.z, (GetRandomControl() & 3) + 3, LaraItem->pos.yRot, LaraItem->roomNumber);
|
|
|
|
SoundEffect(SFX_LARA_INJURY_RND, &LaraItem->pos, 0);
|
|
|
|
|
|
|
|
return GunShot(x, y, z, speed, yrot, roomNumber);
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
short GunShot(int x, int y, int z, short speed, short yrot, short roomNumber)
|
2019-11-14 20:15:29 +01:00
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
int Targetable(ITEM_INFO* item, AI_INFO* info)
|
2019-11-14 20:15:29 +01:00
|
|
|
{
|
|
|
|
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
|
|
|
|
ITEM_INFO* enemy = creature->enemy;
|
|
|
|
|
2020-01-09 09:32:52 +01:00
|
|
|
if (enemy != NULL && enemy->hitPoints > 0 && enemy->data != NULL && info->ahead && info->distance < SQUARE(8192))
|
2019-11-14 20:15:29 +01:00
|
|
|
{
|
|
|
|
GAME_VECTOR start, target;
|
|
|
|
|
2019-11-27 15:12:35 +01:00
|
|
|
short* bounds = GetBestFrame(item);
|
2019-11-14 20:15:29 +01:00
|
|
|
|
|
|
|
start.x = item->pos.xPos;
|
|
|
|
if (item->objectNumber == ID_SNIPER)
|
|
|
|
start.y = item->pos.yPos - 768;
|
|
|
|
else
|
|
|
|
start.y = item->pos.yPos + ((bounds[3] + 3 * bounds[2]) >> 2);
|
|
|
|
start.z = item->pos.zPos;
|
|
|
|
start.roomNumber = item->roomNumber;
|
|
|
|
|
|
|
|
bounds = GetBestFrame(enemy);
|
|
|
|
|
|
|
|
target.x = enemy->pos.xPos;
|
|
|
|
target.y = enemy->pos.yPos + ((bounds[3] + 3 * bounds[2]) >> 2);
|
|
|
|
target.z = enemy->pos.zPos;
|
|
|
|
|
|
|
|
return LOS(&start, &target);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
int TargetVisible(ITEM_INFO* item, AI_INFO* info)
|
2019-11-14 20:15:29 +01:00
|
|
|
{
|
|
|
|
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
|
|
|
|
ITEM_INFO* enemy = creature->enemy;
|
|
|
|
|
|
|
|
if (enemy != NULL)
|
|
|
|
{
|
2019-11-27 15:12:35 +01:00
|
|
|
short angle = info->angle - creature->jointRotation[2];
|
2019-11-14 20:15:29 +01:00
|
|
|
if (enemy->hitPoints != 0 && angle > -ANGLE(45) && angle < ANGLE(45) && info->distance < SQUARE(8192))
|
|
|
|
{
|
|
|
|
GAME_VECTOR start;
|
|
|
|
start.x = item->pos.xPos;
|
|
|
|
start.y = item->pos.yPos - 768;
|
|
|
|
start.z = item->pos.zPos;
|
|
|
|
start.roomNumber = item->roomNumber;
|
|
|
|
|
|
|
|
GAME_VECTOR target;
|
|
|
|
target.x = enemy->pos.xPos;
|
2019-11-27 15:12:35 +01:00
|
|
|
short* bounds = GetBestFrame(enemy);
|
2019-11-14 20:15:29 +01:00
|
|
|
target.y = enemy->pos.yPos + ((((bounds[2] << 1) + bounds[2]) + bounds[3]) >> 2);
|
|
|
|
target.z = enemy->pos.zPos;
|
|
|
|
|
|
|
|
return LOS(&start, &target);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|