Process a dying object for one frame
| 1432 | #define ELECTRICAL_DEATH_TIME 3.0 |
| 1433 | // Process a dying object for one frame |
| 1434 | void DoDyingFrame(object *objp) { |
| 1435 | // Make sure types & flags are right |
| 1436 | ASSERT(objp->flags & OF_DYING); |
| 1437 | ASSERT((objp->control_type == CT_DYING) || (objp->control_type == CT_DYING_AND_AI)); |
| 1438 | // Get death flags |
| 1439 | int death_flags = objp->ctype.dying_info.death_flags; |
| 1440 | // Update delay time |
| 1441 | objp->ctype.dying_info.delay_time -= Frametime; |
| 1442 | // Done dying? |
| 1443 | if (objp->ctype.dying_info.delay_time < 0) { |
| 1444 | // Kill the object for real |
| 1445 | DestroyObject(objp, 30, death_flags); |
| 1446 | // Add to score |
| 1447 | if ((objp->ctype.dying_info.killer_playernum != -1) && IS_GENERIC(objp->type)) |
| 1448 | PlayerScoreAdd(objp->ctype.dying_info.killer_playernum, Object_info[objp->id].score); |
| 1449 | // We're done |
| 1450 | return; |
| 1451 | } |
| 1452 | // If sparking death, do sparks |
| 1453 | if (death_flags & DF_DELAY_SPARKS) { |
| 1454 | float dying_norm = objp->ctype.dying_info.delay_time / ELECTRICAL_DEATH_TIME; |
| 1455 | dying_norm = std::min<float>(dying_norm, 1.0); |
| 1456 | // Do deform stuff |
| 1457 | objp->effect_info->type_flags |= EF_DEFORM; |
| 1458 | objp->effect_info->deform_time = 1.0; |
| 1459 | objp->effect_info->deform_range = (1.0 - dying_norm) * .2f; |
| 1460 | int dying_chance = (dying_norm * 10) + 1; |
| 1461 | // Create random electrical effect |
| 1462 | if (Gametime - objp->ctype.dying_info.last_spark_time > .01) { |
| 1463 | if ((ps_rand() % dying_chance) == 0) { |
| 1464 | int num_bolts = ((1.0 - dying_norm) * 5.0) + 3; |
| 1465 | CreateElectricalBolts(objp, num_bolts); |
| 1466 | } |
| 1467 | objp->ctype.dying_info.last_spark_time = Gametime; |
| 1468 | } |
| 1469 | } |
| 1470 | // If fireball death, do fireballs |
| 1471 | if (death_flags & DF_DELAY_FIREBALL) { |
| 1472 | vector velocity_norm = objp->mtype.phys_info.velocity; |
| 1473 | vm_NormalizeVector(&velocity_norm); |
| 1474 | vector pos = objp->pos - (velocity_norm * (objp->size / 2)); |
| 1475 | if (OBJECT_OUTSIDE(objp)) |
| 1476 | CreateFireball(&pos, BLACK_SMOKE_INDEX, objp->roomnum, VISUAL_FIREBALL); |
| 1477 | // Create an explosion that follows every now and then |
| 1478 | if ((Gametime - objp->ctype.dying_info.last_fireball_time > .01) && (ps_rand() % 3) == 0) { |
| 1479 | if (!(objp->flags & OF_POLYGON_OBJECT)) |
| 1480 | return; |
| 1481 | objp->ctype.dying_info.last_fireball_time = Gametime; |
| 1482 | vector dest; |
| 1483 | poly_model *pm = &Poly_models[objp->rtype.pobj_info.model_num]; |
| 1484 | bsp_info *sm = &pm->submodel[0]; |
| 1485 | int vertnum = ps_rand() % sm->nverts; |
| 1486 | GetPolyModelPointInWorld(&dest, &Poly_models[objp->rtype.pobj_info.model_num], &objp->pos, &objp->orient, 0, |
| 1487 | &sm->verts[vertnum]); |
| 1488 | int visnum = CreateFireball(&dest, GetRandomSmallExplosion(), objp->roomnum, VISUAL_FIREBALL); |
| 1489 | if (visnum >= 0) // DAJ this pervents a -1 array index |
| 1490 | { |
| 1491 | VisEffects[visnum].size += ((ps_rand() % 20) / 20.0) * 3.0; |
no test coverage detected