| 94 | } |
| 95 | |
| 96 | void MonkeyControl(short itemNumber) |
| 97 | { |
| 98 | if (!CreatureActive(itemNumber)) |
| 99 | return; |
| 100 | |
| 101 | auto* item = &g_Level.Items[itemNumber]; |
| 102 | auto* creature = GetCreatureInfo(item); |
| 103 | |
| 104 | short angle = 0; |
| 105 | short tilt = 0; |
| 106 | auto extraHeadRot = EulerAngles::Identity; |
| 107 | auto extraTorsoRot = EulerAngles::Identity; |
| 108 | |
| 109 | if (item->HitPoints <= 0) |
| 110 | { |
| 111 | if (item->Animation.ActiveState != MONKEY_STATE_DEATH) |
| 112 | { |
| 113 | SetAnimation(item, MONKEY_ANIM_DEATH); |
| 114 | item->MeshBits = ALL_JOINT_BITS; |
| 115 | } |
| 116 | } |
| 117 | else |
| 118 | { |
| 119 | GetAITarget(creature); |
| 120 | |
| 121 | if (creature->HurtByLara) |
| 122 | creature->Enemy = LaraItem; |
| 123 | else |
| 124 | { |
| 125 | creature->Enemy = nullptr; |
| 126 | int minDistance = INT_MAX; |
| 127 | |
| 128 | for (auto creatureIndex : ActiveCreatures) |
| 129 | { |
| 130 | auto* currentCreature = GetCreatureInfo(&g_Level.Items[creatureIndex]); |
| 131 | |
| 132 | if (currentCreature->ItemNumber == NO_VALUE || currentCreature->ItemNumber == itemNumber) |
| 133 | continue; |
| 134 | |
| 135 | auto* target = &g_Level.Items[currentCreature->ItemNumber]; |
| 136 | if (target->ObjectNumber == ID_LARA || target->ObjectNumber == ID_MONKEY) |
| 137 | continue; |
| 138 | |
| 139 | if (target->ObjectNumber == ID_SMALLMEDI_ITEM) |
| 140 | { |
| 141 | int x = target->Pose.Position.x - item->Pose.Position.x; |
| 142 | int z = target->Pose.Position.z - item->Pose.Position.z; |
| 143 | int distance = pow(x, 2) + pow(z, 2); |
| 144 | |
| 145 | if (distance < minDistance) |
| 146 | { |
| 147 | creature->Enemy = target; |
| 148 | minDistance = distance; |
| 149 | } |
| 150 | } |
| 151 | } |
| 152 | } |
| 153 |
nothing calls this directly
no test coverage detected