| 207 | } |
| 208 | |
| 209 | void WraithControl(short itemNumber) |
| 210 | { |
| 211 | auto& item = g_Level.Items[itemNumber]; |
| 212 | |
| 213 | SoundEffect(SFX_TR4_WRAITH_WHISPERS, &item.Pose); |
| 214 | |
| 215 | // HACK: HitPoints stores the wraith's target. NOTE: ``auto*`` makes some errors with wraith find its target in Release version. It works without ``*``. |
| 216 | auto target = item.ItemFlags[6] ? &g_Level.Items[item.ItemFlags[6]] : LaraItem; |
| 217 | |
| 218 | auto prevPos = item.Pose.Position; |
| 219 | int x, y, z, xl, yl, zl; |
| 220 | int dy; |
| 221 | int distance; |
| 222 | int distancePlayer; |
| 223 | |
| 224 | if (target->IsLara() || target->ObjectNumber == ID_WRAITH_TRAP) |
| 225 | { |
| 226 | x = target->Pose.Position.x - item.Pose.Position.x; |
| 227 | y = target->Pose.Position.y; |
| 228 | z = target->Pose.Position.z - item.Pose.Position.z; |
| 229 | distance = SQUARE(x) + SQUARE(z); |
| 230 | dy = abs((distance / BLOCK(8)) - BLOCK(0.5f)); |
| 231 | } |
| 232 | else |
| 233 | { |
| 234 | const auto& room = g_Level.Rooms[LaraItem->RoomNumber]; |
| 235 | |
| 236 | x = room.Position.x + room.XSize * BLOCK(1) / 2 - item.Pose.Position.x; |
| 237 | z = room.Position.z + room.ZSize * BLOCK(1) / 2 - item.Pose.Position.z; |
| 238 | |
| 239 | distance = SQUARE(x) + SQUARE(z); |
| 240 | dy = abs((distance / MAX_VISIBILITY_DISTANCE) - CLICK(1)); |
| 241 | //Prevent Wraiths to go below floor level |
| 242 | y = room.Position.y + ((room.TopHeight - room.BottomHeight) / 4); |
| 243 | } |
| 244 | |
| 245 | dy = y - item.Pose.Position.y - dy - CLICK(0.5f); |
| 246 | short angleH = phd_atan(z, x) - item.Pose.Orientation.y; |
| 247 | |
| 248 | short angleV = 0; |
| 249 | if (abs(x) <= abs(z)) |
| 250 | angleV = phd_atan(abs(x) + (abs(z)), dy); |
| 251 | else |
| 252 | angleV = phd_atan(abs(z) + (abs(x)), dy); |
| 253 | |
| 254 | angleV -= item.Pose.Orientation.x; |
| 255 | int velocity = (WRAITH_VELOCITY / item.Animation.Velocity.z) * 8; |
| 256 | |
| 257 | if (abs(angleH) < item.ItemFlags[2] && angleH > 0 == item.ItemFlags[2] > 0) |
| 258 | { |
| 259 | item.Pose.Orientation.y += angleH; |
| 260 | } |
| 261 | else if (angleH >= 0) |
| 262 | { |
| 263 | if (item.ItemFlags[2] <= 0) |
| 264 | { |
| 265 | item.ItemFlags[2] = 1; |
| 266 | } |
nothing calls this directly
no test coverage detected