| 299 | } |
| 300 | |
| 301 | void PunaControl(short itemNumber) |
| 302 | { |
| 303 | if (!CreatureActive(itemNumber)) |
| 304 | return; |
| 305 | |
| 306 | auto& item = g_Level.Items[itemNumber]; |
| 307 | auto& object = Objects[item.ObjectNumber]; |
| 308 | auto& creature = *GetCreatureInfo(&item); |
| 309 | |
| 310 | static auto targetPos = Vector3i::Zero; |
| 311 | |
| 312 | auto headOrient = EulerAngles::Identity; |
| 313 | short headingAngle = 0; |
| 314 | short prevYOrient = 0; |
| 315 | |
| 316 | bool hasTurned = false; |
| 317 | bool isLizardActiveNearby = IsLizardActiveNearby(item); |
| 318 | |
| 319 | if (item.HitPoints <= 0) |
| 320 | { |
| 321 | if (item.Animation.ActiveState != PUNA_STATE_DEATH) |
| 322 | { |
| 323 | SetAnimation(item, PUNA_ANIM_DEATH); |
| 324 | SoundEffect(SFX_TR3_PUNA_BOSS_DEATH, &item.Pose); |
| 325 | item.ItemFlags[(int)BossItemFlags::DeathCount] = 1; |
| 326 | creature.MaxTurn = 0; |
| 327 | } |
| 328 | |
| 329 | auto deathCount = item.GetFlagField((int)BossItemFlags::DeathCount); |
| 330 | item.Pose.Orientation.z = (Random::GenerateInt() % deathCount) - (item.ItemFlags[(int)BossItemFlags::DeathCount] >> 1); |
| 331 | |
| 332 | if (deathCount < 2048) |
| 333 | item.ItemFlags[(int)BossItemFlags::DeathCount] += 32; |
| 334 | |
| 335 | int endFrameNumber = GetAnimData(object, PUNA_ANIM_DEATH).EndFrameNumber; |
| 336 | if (item.Animation.FrameNumber >= endFrameNumber) |
| 337 | { |
| 338 | // Avoid having the object stop working. |
| 339 | item.Animation.FrameNumber = endFrameNumber; |
| 340 | |
| 341 | if (item.GetFlagField((int)BossItemFlags::ExplodeCount) < PUNA_EXPLOSION_NUM_MAX) |
| 342 | item.ItemFlags[(int)BossItemFlags::ExplodeCount]++; |
| 343 | |
| 344 | if (item.ItemFlags[7] < PUNA_EXPLOSION_NUM_MAX) |
| 345 | item.ItemFlags[7]++; |
| 346 | |
| 347 | // Do explosion effect. |
| 348 | ExplodeBoss(item, PUNA_EXPLOSION_NUM_MAX, PUNA_EFFECT_COLOR, PUNA_EXPLOSION_MAIN_COLOR, PUNA_EXPLOSION_SECOND_COLOR); |
| 349 | return; |
| 350 | } |
| 351 | } |
| 352 | else |
| 353 | { |
| 354 | prevYOrient = item.Pose.Orientation.y; |
| 355 | |
| 356 | AI_INFO ai; |
| 357 | CreatureAIInfo(&item, &ai); |
| 358 | if (ai.ahead) |
nothing calls this directly
no test coverage detected