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); 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; Lara.torsoYrot = Lara.headYrot;
} }
@ -1009,7 +1009,7 @@ void LookUpDown()
Lara.headXrot += ANGLE(2.0f); 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; Lara.torsoXrot = Lara.headXrot;
} }

View file

@ -57,10 +57,10 @@ void FireHarpoon()
PHD_VECTOR jointPos; PHD_VECTOR jointPos;
jointPos.x = -2; jointPos.x = -2;
jointPos.y = 0; jointPos.y = 273 + 100;
jointPos.z = 77; jointPos.z = 77;
GetLaraJointPosition(&jointPos, LM_LHAND); GetLaraJointPosition(&jointPos, LM_RHAND);
FLOOR_INFO* floor = GetFloor(jointPos.x, jointPos.y, jointPos.z, &item->roomNumber); FLOOR_INFO* floor = GetFloor(jointPos.x, jointPos.y, jointPos.z, &item->roomNumber);
int height = GetFloorHeight(floor, jointPos.x, jointPos.y, jointPos.z); int height = GetFloorHeight(floor, jointPos.x, jointPos.y, jointPos.z);
@ -81,19 +81,6 @@ void FireHarpoon()
InitialiseItem(itemNumber); 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.xRot = Lara.leftArm.xRot + LaraItem->pos.xRot;
item->pos.zRot = 0; item->pos.zRot = 0;
item->pos.yRot = Lara.leftArm.yRot + LaraItem->pos.yRot; item->pos.yRot = Lara.leftArm.yRot + LaraItem->pos.yRot;
@ -120,101 +107,15 @@ void FireHarpoon()
void ControlHarpoonBolt(short itemNumber) 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 oldX = item->pos.xPos;
int oldY = item->pos.yPos; int oldY = item->pos.yPos;
int oldZ = item->pos.zPos; 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; 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->pos.yPos >= item->floor || item->pos.yPos <= GetCeiling(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos))
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->hitPoints == HARPOON_TIME) if (item->hitPoints == HARPOON_TIME)
{ {
@ -223,15 +124,14 @@ void ControlHarpoonBolt(short itemNumber)
if (item->hitPoints >= 192) 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--;
} }
item->hitPoints--; item->hitPoints--;
if (item->hitPoints <= 0) if (!item->hitPoints)
{ {
KillItem(itemNumber); KillItem(itemNumber);
item->afterDeath = 0;
return; return;
} }
item->speed = item->fallspeed = 0; item->speed = item->fallspeed = 0;
@ -239,39 +139,23 @@ void ControlHarpoonBolt(short itemNumber)
else else
{ {
item->pos.zRot += ANGLE(35); 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); item->pos.xRot -= (ANGLE(1));
if (item->pos.xRot < -16384) if (item->pos.xRot < -ANGLE(90))
item->pos.xRot = -16384; item->pos.xRot = -ANGLE(90);
item->fallspeed = (short)(-HARPOON_SPEED * phd_sin(item->pos.xRot) >> W2V_SHIFT); item->fallspeed = (short)(-HARPOON_SPEED * phd_sin(item->pos.xRot) >> W2V_SHIFT);
item->speed = (short)(HARPOON_SPEED * phd_cos(item->pos.xRot) >> W2V_SHIFT); item->speed = (short)(HARPOON_SPEED * phd_cos(item->pos.xRot) >> W2V_SHIFT);
} }
else else
{ {
// Create bubbles
if ((Wibble & 15) == 0) if ((Wibble & 15) == 0)
CreateBubble((PHD_VECTOR*)&item->pos, item->roomNumber, 0, 0,BUBBLE_FLAG_CLUMP | BUBBLE_FLAG_HIGH_AMPLITUDE, 0, 0, 0); // CHECK CreateBubble((PHD_VECTOR*)&item->pos, item->roomNumber, 2, 8);
//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->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); 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; bool aboveWater = false;
@ -291,7 +175,7 @@ void ControlHarpoonBolt(short itemNumber)
// Create bubbles // Create bubbles
if ((Wibble & 15) == 0) if ((Wibble & 15) == 0)
CreateBubble((PHD_VECTOR*)& item->pos, item->roomNumber, 0, 0, BUBBLE_FLAG_CLUMP | BUBBLE_FLAG_HIGH_AMPLITUDE, 0, 0, 0); // CHECK 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->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); item->speed = (short)((HARPOON_SPEED >> 1) * phd_cos(item->pos.xRot) >> W2V_SHIFT);
aboveWater = false; aboveWater = false;

View file

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

View file

@ -32,7 +32,6 @@ namespace T5M{
void UpdateSmokeParticles(); void UpdateSmokeParticles();
void TriggerFlareSmoke(const DirectX::SimpleMath::Vector3& pos, DirectX::SimpleMath::Vector3& direction, int age, int room); 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); 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() const float frand()
{ {
float result = float((float)rand() / RAND_MAX); float result = float(static_cast<float>(rand()) / RAND_MAX);
return result; return result;
} }
@ -1339,6 +1339,24 @@ const float lerp(float v0, float v1, float t)
return (1 - t) * v0 + t * v1; 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 // FIXME: game code still expects << 2 >> W2V_SHIFT so we multiply by 16384.0f
int phd_sin(short a) int phd_sin(short a)
{ {

View file

@ -45,6 +45,8 @@ int phd_cos(short a);
const float frand(); const float frand();
const float frandMinMax(float min, float max); const float frandMinMax(float min, float max);
const float lerp(float v0, float v1, float t); 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 mGetAngle(int x1, int y1, int x2, int y2);
int phd_atan(int dz, int dx); int phd_atan(int dz, int dx);
void phd_GetVectorAngles(int x, int y, int z, short* angles); void phd_GetVectorAngles(int x, int y, int z, short* angles);