diff --git a/TR5Main/Game/lara.cpp b/TR5Main/Game/lara.cpp index 7c119c792..f5ef20d4d 100644 --- a/TR5Main/Game/lara.cpp +++ b/TR5Main/Game/lara.cpp @@ -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; } diff --git a/TR5Main/Game/lara1gun.cpp b/TR5Main/Game/lara1gun.cpp index bcc2d27a2..bcc366a02 100644 --- a/TR5Main/Game/lara1gun.cpp +++ b/TR5Main/Game/lara1gun.cpp @@ -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; diff --git a/TR5Main/Game/smoke.cpp b/TR5Main/Game/smoke.cpp index d4e060949..9e7913db1 100644 --- a/TR5Main/Game/smoke.cpp +++ b/TR5Main/Game/smoke.cpp @@ -10,7 +10,14 @@ namespace T5M { namespace Effects { namespace Smoke { std::array 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; } diff --git a/TR5Main/Game/smoke.h b/TR5Main/Game/smoke.h index 879712e59..30cca65ce 100644 --- a/TR5Main/Game/smoke.h +++ b/TR5Main/Game/smoke.h @@ -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); } diff --git a/TR5Main/Game/trmath.cpp b/TR5Main/Game/trmath.cpp index d13766ffb..2f9c1aea7 100644 --- a/TR5Main/Game/trmath.cpp +++ b/TR5Main/Game/trmath.cpp @@ -1325,7 +1325,7 @@ float TO_RAD(short angle) const float frand() { - float result = float((float)rand() / RAND_MAX); + float result = float(static_cast(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) { diff --git a/TR5Main/Game/trmath.h b/TR5Main/Game/trmath.h index 69436b035..0bd2da3bd 100644 --- a/TR5Main/Game/trmath.h +++ b/TR5Main/Game/trmath.h @@ -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);