TODO: Make ControlMissile() not use LaraItem global. -- TokyoSU 5/8/2022
| 60 | |
| 61 | // TODO: Make ControlMissile() not use LaraItem global. -- TokyoSU 5/8/2022 |
| 62 | void ControlMissile(short fxNumber) |
| 63 | { |
| 64 | static const int hitRadius = 200; |
| 65 | |
| 66 | // TODO: Add fx.target (ItemInfo* target) to get the actual target (if it was really it). |
| 67 | auto& fx = EffectList[fxNumber]; |
| 68 | |
| 69 | auto isUnderwater = TestEnvironment(ENV_FLAG_WATER, fx.roomNumber); |
| 70 | auto soundFXType = isUnderwater ? SoundEnvironment::Underwater : SoundEnvironment::Land; |
| 71 | |
| 72 | // Make harpoon arch downwards if not underwater. |
| 73 | if (fx.objectNumber == ID_SCUBA_HARPOON && !isUnderwater && fx.pos.Orientation.x > ANGLE(-67.5f)) |
| 74 | fx.pos.Orientation.x -= ANGLE(1.0f); |
| 75 | |
| 76 | fx.pos.Translate(fx.pos.Orientation, fx.speed); |
| 77 | |
| 78 | auto pointColl = GetPointCollision(fx.pos.Position, fx.roomNumber); |
| 79 | auto hasHitPlayer = ItemNearLara(fx.pos.Position, hitRadius); |
| 80 | |
| 81 | // Check whether something was hit. |
| 82 | if (fx.pos.Position.y >= pointColl.GetFloorHeight() || |
| 83 | fx.pos.Position.y <= pointColl.GetCeilingHeight() || |
| 84 | pointColl.IsWall() || |
| 85 | hasHitPlayer) |
| 86 | { |
| 87 | if (fx.objectNumber == ID_KNIFETHROWER_KNIFE || |
| 88 | fx.objectNumber == ID_SCUBA_HARPOON || |
| 89 | fx.objectNumber == ID_PROJ_SHARD) |
| 90 | { |
| 91 | SoundEffect((fx.objectNumber == ID_SCUBA_HARPOON) ? SFX_TR4_WEAPON_RICOCHET : SFX_TR2_CIRCLE_BLADE_HIT, &fx.pos, soundFXType); |
| 92 | } |
| 93 | else if (fx.objectNumber == ID_PROJ_BOMB) |
| 94 | { |
| 95 | SpawnDecal(fx.pos.Position.ToVector3(), fx.roomNumber, DecalType::Explosion); |
| 96 | SoundEffect(SFX_TR1_ATLANTEAN_EXPLODE, &fx.pos, soundFXType); |
| 97 | TriggerExplosionSparks(fx.pos.Position.x, fx.pos.Position.y, fx.pos.Position.z, 3, -2, 0, fx.roomNumber); |
| 98 | TriggerExplosionSparks(fx.pos.Position.x, fx.pos.Position.y, fx.pos.Position.z, 3, -1, 0, fx.roomNumber); |
| 99 | TriggerShockwave(&fx.pos, 48, 304, (GetRandomControl() & 0x1F) + 112, 128, 32, 32, 32, EulerAngles(2048, 0.0f, 0.0f), 0, true, false, false, (int)ShockwaveStyle::Normal); |
| 100 | } |
| 101 | |
| 102 | if (hasHitPlayer) |
| 103 | { |
| 104 | if (fx.objectNumber == ID_KNIFETHROWER_KNIFE) |
| 105 | { |
| 106 | DoDamage(LaraItem, KNIFE_DAMAGE); |
| 107 | } |
| 108 | else if (fx.objectNumber == ID_SCUBA_HARPOON) |
| 109 | { |
| 110 | DoDamage(LaraItem, DIVER_HARPOON_DAMAGE); |
| 111 | } |
| 112 | else if (fx.objectNumber == ID_PROJ_BOMB) |
| 113 | { |
| 114 | DoDamage(LaraItem, MUTANT_BOMB_DAMAGE); |
| 115 | } |
| 116 | else if (fx.objectNumber == ID_PROJ_SHARD) |
| 117 | { |
| 118 | TriggerBlood(fx.pos.Position.x, fx.pos.Position.y, fx.pos.Position.z, 0, 10); |
| 119 | SoundEffect(SFX_TR4_BLOOD_LOOP, &fx.pos, soundFXType); |
nothing calls this directly
no test coverage detected