This commit is contained in:
MontyTRC89 2020-08-17 06:53:20 +02:00
commit fc9f23d5cf
6 changed files with 54 additions and 150 deletions

View file

@ -980,7 +980,7 @@ void LookLeftRight()
Lara.headYrot += ANGLE(2.0f);
}
}
if (Lara.gunStatus != LG_HANDS_BUSY && !Lara.leftArm.lock && !Lara.rightArm.lock)
if (Lara.gunStatus != LG_HANDS_BUSY && Lara.Vehicle == NO_ITEM && !Lara.leftArm.lock && !Lara.rightArm.lock)
Lara.torsoYrot = Lara.headYrot;
}
@ -1009,7 +1009,7 @@ void LookUpDown()
Lara.headXrot += ANGLE(2.0f);
}
}
if (Lara.gunStatus != LG_HANDS_BUSY && !Lara.leftArm.lock && !Lara.rightArm.lock)
if (Lara.gunStatus != LG_HANDS_BUSY && Lara.Vehicle == NO_ITEM && !Lara.leftArm.lock && !Lara.rightArm.lock)
Lara.torsoXrot = Lara.headXrot;
}

View file

@ -57,10 +57,10 @@ void FireHarpoon()
PHD_VECTOR jointPos;
jointPos.x = -2;
jointPos.y = 0;
jointPos.y = 273 + 100;
jointPos.z = 77;
GetLaraJointPosition(&jointPos, LM_LHAND);
GetLaraJointPosition(&jointPos, LM_RHAND);
FLOOR_INFO* floor = GetFloor(jointPos.x, jointPos.y, jointPos.z, &item->roomNumber);
int height = GetFloorHeight(floor, jointPos.x, jointPos.y, jointPos.z);
@ -81,19 +81,6 @@ void FireHarpoon()
InitialiseItem(itemNumber);
/*if (Lara.target != nullptr)
{
find_target_point(Lara.target, &pos);
item->pos.yRot = phd_atan(pos.z - item->pos.zPos, pos.x - item->pos.xPos);
int distance = sqrt(SQUARE(pos.z - item->pos.zPos) + SQUARE(pos.x - item->pos.xPos));
item->pos.xRot = -phd_atan(distance, pos.y - item->pos.yPos);
}
else
{
item->pos.xRot = LaraItem->pos.xRot + Lara.torsoXrot;
item->pos.yRot = LaraItem->pos.yRot + Lara.torsoYrot;
}*/
item->pos.xRot = Lara.leftArm.xRot + LaraItem->pos.xRot;
item->pos.zRot = 0;
item->pos.yRot = Lara.leftArm.yRot + LaraItem->pos.yRot;
@ -120,101 +107,15 @@ void FireHarpoon()
void ControlHarpoonBolt(short itemNumber)
{
/*ITEM_INFO* item = &g_Level.Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNumber];
// Store position for later
// Store old position for later
int oldX = item->pos.xPos;
int oldY = item->pos.yPos;
int oldZ = item->pos.zPos;
short oldRoom = item->roomNumber;
// Update position
item->pos.xPos += item->speed * phd_sin(item->pos.yRot) >> W2V_SHIFT;
item->pos.yPos += item->fallspeed;
item->pos.zPos += item->speed * phd_cos(item->pos.yRot) >> W2V_SHIFT;
short roomNumber = item->roomNumber;
FLOOR_INFO* floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
item->floor = GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
// Has harpoon changed room?
if (item->roomNumber != roomNumber)
ItemNewRoom(itemNumber, roomNumber);
// First check if the harpoon has it an item
short targetItemNumber = 0;
ITEM_INFO* target;
for (targetItemNumber = g_Level.Rooms[item->roomNumber].itemNumber; targetItemNumber != NO_ITEM; targetItemNumber = target->nextItem)
{
target = &g_Level.Items[targetItemNumber];
if (target == LaraItem || !target->collidable)
continue;
if (target->status != ITEM_INVISIBLE && Objects[target->objectNumber].collision)
{
// check against bounds of target for collision
BOUNDING_BOX* bounds = (BOUNDING_BOX*)GetBestFrame(target);
if (item->pos.yPos < target->pos.yPos + bounds->Y1 || item->pos.yPos > target->pos.yPos + bounds->Y2)
continue;
// get vector from target to bolt and check against x,z bounds
short c = phd_cos(target->pos.yRot);
short s = phd_sin(target->pos.yRot);
int x = item->pos.xPos - target->pos.xPos;
int z = item->pos.zPos - target->pos.zPos;
int rx = (c * x - s * z) >> W2V_SHIFT;
int ox = oldX - target->pos.xPos;
int oz = oldZ - target->pos.zPos;
int sx = (c * ox - s * oz) >> W2V_SHIFT;
if ((rx < bounds->X1 && sx < bounds->X1) || (rx > bounds->X2 && sx > bounds->X2))
continue;
int rz = (c * z + s * x) >> W2V_SHIFT;
int sz = (c * oz + s * ox) >> W2V_SHIFT;
if ((rz < bounds->Z1 && sz < bounds->Z1) || (rz > bounds->Z2 && sz > bounds->Z2))
continue;
// TODO:
if (target->objectNumber == SMASH_OBJECT1 && CurrentLevel != LV_CRASH)
{
SmashWindow(targetItemNumber);
}
else if (target->objectNumber == SMASH_WINDOW ||
target->objectNumber == SMASH_OBJECT2 ||
target->objectNumber == SMASH_OBJECT3)
{
SmashWindow(targetItemNumber);
}
else if (target->objectNumber == CARCASS || target->objectNumber == EXTRAFX6)
{
if (item->status != ACTIVE)
{
item->status = ACTIVE;
AddActiveItem(targetItemNumber);
}
}
else if (target->objectNumber != SMASH_OBJECT1)
{
if (Objects[target->objectNumber].intelligent)
{
DoLotsOfBlood(item->pos.xPos, item->pos.yPos, item->pos.zPos, 0, 0, item->roomNumber, 3);
HitTarget(target, NULL, Weapons[WEAPON_HARPOON_GUN].damage << item->itemFlags[0], 0);
Savegame.Level.AmmoHits++;
Savegame.Game.AmmoHits++;
}
KillItem(itemNumber);
item->afterDeath = 0;
return;
}
}
// Has harpoon hit a wall?
if (item->pos.yPos >= item->floor || item->pos.yPos <= GetCeiling(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos))
/*if (item->pos.yPos >= item->floor || item->pos.yPos <= GetCeiling(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos))
{
if (item->hitPoints == HARPOON_TIME)
{
@ -223,15 +124,14 @@ void ControlHarpoonBolt(short itemNumber)
if (item->hitPoints >= 192)
{
item->pos.xRot = item->currentAnimState + ((((rcossin_tbl[((item->hitPoints - 192) << 9) & 4095] >> 1) - 1024)*(item->hitPoints - 192)) >> 6);
item->pos.xRot = item->currentAnimState + ((((phd_sin(item->hitPoints * 2048) / 8) - 1024) * (item->hitPoints - 192)) / 64);
item->hitPoints--;
}
item->hitPoints--;
if (item->hitPoints <= 0)
if (!item->hitPoints)
{
KillItem(itemNumber);
item->afterDeath = 0;
return;
}
item->speed = item->fallspeed = 0;
@ -239,39 +139,23 @@ void ControlHarpoonBolt(short itemNumber)
else
{
item->pos.zRot += ANGLE(35);
if (!(g_Level.Rooms[item->roomNumber].flags & 1))
if (!(g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_WATER))
{
item->pos.xRot -= ANGLE(1);
if (item->pos.xRot < -16384)
item->pos.xRot = -16384;
item->pos.xRot -= (ANGLE(1));
if (item->pos.xRot < -ANGLE(90))
item->pos.xRot = -ANGLE(90);
item->fallspeed = (short)(-HARPOON_SPEED * phd_sin(item->pos.xRot) >> W2V_SHIFT);
item->speed = (short)(HARPOON_SPEED * phd_cos(item->pos.xRot) >> W2V_SHIFT);
}
else
{
// Create bubbles
if ((Wibble & 15) == 0)
CreateBubble((PHD_VECTOR*)&item->pos, item->roomNumber, 0, 0,BUBBLE_FLAG_CLUMP | BUBBLE_FLAG_HIGH_AMPLITUDE, 0, 0, 0); // CHECK
//TriggerRocketSmoke(item->pos.xPos, item->pos.yPos, item->pos.zPos, 64);
CreateBubble((PHD_VECTOR*)&item->pos, item->roomNumber, 2, 8);
TriggerRocketSmoke(item->pos.xPos, item->pos.yPos, item->pos.zPos, 64);
item->fallspeed = (short)(-(HARPOON_SPEED >> 1) * phd_sin(item->pos.xRot) >> W2V_SHIFT);
item->speed = (short)((HARPOON_SPEED >> 1) * phd_cos(item->pos.xRot) >> W2V_SHIFT);
}
}
roomNumber = item->roomNumber;
floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
if (item->roomNumber != roomNumber)
ItemNewRoom(itemNumber, roomNumber);*/
ITEM_INFO* item = &g_Level.Items[itemNumber];
// Store old position for later
int oldX = item->pos.xPos;
int oldY = item->pos.yPos;
int oldZ = item->pos.zPos;
short roomNumber = item->roomNumber;
}*/
bool aboveWater = false;
@ -291,7 +175,7 @@ void ControlHarpoonBolt(short itemNumber)
// Create bubbles
if ((Wibble & 15) == 0)
CreateBubble((PHD_VECTOR*)& item->pos, item->roomNumber, 0, 0, BUBBLE_FLAG_CLUMP | BUBBLE_FLAG_HIGH_AMPLITUDE, 0, 0, 0); // CHECK
//TriggerRocketSmoke(item->pos.xPos, item->pos.yPos, item->pos.zPos, 64);
TriggerRocketSmoke(item->pos.xPos, item->pos.yPos, item->pos.zPos, 64);
item->fallspeed = (short)(-(HARPOON_SPEED >> 1) * phd_sin(item->pos.xRot) >> W2V_SHIFT);
item->speed = (short)((HARPOON_SPEED >> 1) * phd_cos(item->pos.xRot) >> W2V_SHIFT);
aboveWater = false;

View file

@ -10,7 +10,14 @@ namespace T5M {
namespace Effects {
namespace Smoke {
std::array<SmokeParticle, 128> SmokeParticles;
SmokeParticle& getFreeSmokeParticle()
{
for(int i = 0; i < SmokeParticles.size(); i++){
if(!SmokeParticles[i].active)
return SmokeParticles[i];
}
return SmokeParticles[0];
}
void UpdateSmokeParticles()
{
for (int i = 0; i < SmokeParticles.size(); i++) {
@ -70,23 +77,15 @@ namespace T5M {
s.room = room;
}
SmokeParticle& getFreeSmokeParticle()
{
for (int i = 0; i < SmokeParticles.size(); i++) {
if (!SmokeParticles[i].active)
return SmokeParticles[i];
}
return SmokeParticles[0];
}
void TriggerGunSmokeParticles(int x, int y, int z, short xv, short yv, short zv, byte initial, int weaponType, byte count)
{
SmokeParticle& s = getFreeSmokeParticle();
s = {};
s.active = true;
s.position = Vector3(x, y, z);
Vector3(xv, yv, zv).Normalize(s.velocity);
s.velocity *= frand() * 24 + 16;
Vector3 dir = Vector3(xv, yv, zv);
dir.Normalize();
s.velocity = dir;
s.gravity = -.1f;
s.affectedByWind = g_Level.Rooms[LaraItem->roomNumber].flags & ENV_FLAG_WIND;
s.sourceColor = Vector4(.4, .4, .4, 1);
@ -98,9 +97,10 @@ namespace T5M {
s.sourceSize = size *2;
s.destinationSize = size * 8;
s.terminalVelocity = 0;
s.friction = 0.90f;
s.friction = 0.88f;
s.life = frand() * 30 + 60;
s.velocity = getRandomVectorInCone(s.velocity, 10);
s.velocity *= frand() * 14 + 16;
}
else
{
@ -111,13 +111,14 @@ namespace T5M {
s.terminalVelocity = 0;
s.friction = 0.97f;
s.life = frand() * 20 + 42;
s.velocity *= frand() * 24 + 16;
}
s.position = Vector3(x, y, z);
s.position += Vector3(frandMinMax(-8, 8), frandMinMax(-8, 8), frandMinMax(-8, 8));
s.angularVelocity = frandMinMax(-PI / 4, PI / 4);
s.angularDrag = 0.8f;
s.angularDrag = 0.95f;
s.room = LaraItem->roomNumber;
}

View file

@ -32,7 +32,6 @@ namespace T5M{
void UpdateSmokeParticles();
void TriggerFlareSmoke(const DirectX::SimpleMath::Vector3& pos, DirectX::SimpleMath::Vector3& direction, int age, int room);
SmokeParticle& getFreeSmokeParticle();
void TriggerGunSmokeParticles(int x, int y, int z, short xv, short yv, short zv, byte initial, int weaponType, byte count);
}

View file

@ -1325,7 +1325,7 @@ float TO_RAD(short angle)
const float frand()
{
float result = float((float)rand() / RAND_MAX);
float result = float(static_cast<float>(rand()) / RAND_MAX);
return result;
}
@ -1339,6 +1339,24 @@ const float lerp(float v0, float v1, float t)
return (1 - t) * v0 + t * v1;
}
const Vector3 getRandomVector()
{
Vector3 v = {frandMinMax(-1,1),frandMinMax(-1,1),frandMinMax(-1,1)};
v.Normalize();
return v;
}
const Vector3 getRandomVectorInCone(const Vector3& direction, const float angleDegrees)
{
float x = frandMinMax(-angleDegrees, angleDegrees) * RADIAN;
float y = frandMinMax(-angleDegrees, angleDegrees) * RADIAN;
float z = frandMinMax(-angleDegrees, angleDegrees) * RADIAN;
Matrix m = Matrix::CreateRotationX(x)* Matrix::CreateRotationY(y) * Matrix::CreateRotationZ(z);
Vector3 result = direction.TransformNormal(direction, m);
result.Normalize();
return result;
}
// FIXME: game code still expects << 2 >> W2V_SHIFT so we multiply by 16384.0f
int phd_sin(short a)
{

View file

@ -45,6 +45,8 @@ int phd_cos(short a);
const float frand();
const float frandMinMax(float min, float max);
const float lerp(float v0, float v1, float t);
const Vector3 getRandomVector();
const Vector3 getRandomVectorInCone(const Vector3& direction,const float angleDegrees);
int mGetAngle(int x1, int y1, int x2, int y2);
int phd_atan(int dz, int dx);
void phd_GetVectorAngles(int x, int y, int z, short* angles);