| 53 | } |
| 54 | |
| 55 | void LarsonControl(short itemNumber) |
| 56 | { |
| 57 | if (!CreatureActive(itemNumber)) |
| 58 | return; |
| 59 | |
| 60 | auto* item = &g_Level.Items[itemNumber]; |
| 61 | auto* creature = GetCreatureInfo(item); |
| 62 | |
| 63 | short angle = 0; |
| 64 | short tilt = 0; |
| 65 | short joint0 = 0; |
| 66 | short joint1 = 0; |
| 67 | short joint2 = 0; |
| 68 | |
| 69 | // When Larson's HP is below 40 and his OCB is not 0, he runs away and disappears. |
| 70 | if (item->HitPoints <= TR5_LARSON_MIN_HP && item->TriggerFlags) |
| 71 | { |
| 72 | item->HitPoints = TR5_LARSON_MIN_HP; |
| 73 | creature->Flags++; |
| 74 | } |
| 75 | |
| 76 | if (creature->MuzzleFlash[0].Delay != 0) |
| 77 | creature->MuzzleFlash[0].Delay--; |
| 78 | if (creature->MuzzleFlash[1].Delay != 0) |
| 79 | creature->MuzzleFlash[1].Delay--; |
| 80 | |
| 81 | if (item->HitPoints > 0) |
| 82 | { |
| 83 | // If Larson is in the process of escaping, force ambush AI flag on him. |
| 84 | if (creature->Flags) |
| 85 | item->AIBits |= AMBUSH; |
| 86 | |
| 87 | // HACK: Reset enemy if AI bits were unset, otherwise Larson will run around last used AI object. |
| 88 | if (!item->AIBits) |
| 89 | creature->Enemy = nullptr; |
| 90 | |
| 91 | AI_INFO AI; |
| 92 | GetAITarget(creature); |
| 93 | CreatureAIInfo(item, &AI); |
| 94 | |
| 95 | // HACK: Reset Lara enemy in case no AI_AMBUSH object is present. |
| 96 | // Technically it's illegal, but TEN code forces enemy to Lara after calling GetAITarget, resulting |
| 97 | // in Larson never running away. |
| 98 | if (item->AIBits & AMBUSH && creature->Enemy->ObjectNumber != GAME_OBJECT_ID::ID_AI_AMBUSH) |
| 99 | creature->Enemy = nullptr; |
| 100 | |
| 101 | if (AI.ahead) |
| 102 | joint2 = AI.angle; |
| 103 | |
| 104 | GetCreatureMood(item, &AI, true); |
| 105 | CreatureMood(item, &AI, true); |
| 106 | |
| 107 | if (!(item->AIBits & AMBUSH)) |
| 108 | { |
| 109 | // Set Larson to attack if player is moving fast enough and close enough, or if Larson was hit, |
| 110 | // or if player is directly visible. |
| 111 | if ((AI.distance < LARSON_ALERT_RANGE && creature->Enemy->Animation.Velocity.z > 20.0f) || |
| 112 | (TargetVisible(item, &AI) != 0) || |
nothing calls this directly
no test coverage detected