* Applies damages to the given unit. * * @param unit The Unit to apply damages on. * @param damage The amount of damage to apply. * @param range ??. * @return True if and only if the unit has no hitpoints left. */
| 1528 | * @return True if and only if the unit has no hitpoints left. |
| 1529 | */ |
| 1530 | bool Unit_Damage(Unit *unit, uint16 damage, uint16 range) |
| 1531 | { |
| 1532 | const UnitInfo *ui; |
| 1533 | bool alive = false; |
| 1534 | uint8 houseID; |
| 1535 | |
| 1536 | if (unit == NULL || !unit->o.flags.s.allocated) return false; |
| 1537 | |
| 1538 | ui = &g_table_unitInfo[unit->o.type]; |
| 1539 | |
| 1540 | if (!ui->flags.isNormalUnit && unit->o.type != UNIT_SANDWORM) return false; |
| 1541 | |
| 1542 | if (unit->o.hitpoints != 0) alive = true; |
| 1543 | |
| 1544 | if (unit->o.hitpoints >= damage) { |
| 1545 | unit->o.hitpoints -= damage; |
| 1546 | } else { |
| 1547 | unit->o.hitpoints = 0; |
| 1548 | } |
| 1549 | |
| 1550 | Unit_Deviation_Decrease(unit, 0); |
| 1551 | |
| 1552 | houseID = Unit_GetHouseID(unit); |
| 1553 | |
| 1554 | if (unit->o.hitpoints == 0) { |
| 1555 | Unit_RemovePlayer(unit); |
| 1556 | |
| 1557 | if (unit->o.type == UNIT_HARVESTER) Map_FillCircleWithSpice(Tile_PackTile(unit->o.position), unit->amount / 32); |
| 1558 | |
| 1559 | if (unit->o.type == UNIT_SABOTEUR) { |
| 1560 | Sound_Output_Feedback(20); |
| 1561 | } else { |
| 1562 | if (!ui->o.flags.noMessageOnDeath && alive) { |
| 1563 | Sound_Output_Feedback((houseID == g_playerHouseID || g_campaignID > 3) ? houseID + 14 : 13); |
| 1564 | } |
| 1565 | } |
| 1566 | |
| 1567 | Unit_SetAction(unit, ACTION_DIE); |
| 1568 | return true; |
| 1569 | } |
| 1570 | |
| 1571 | if (range != 0) { |
| 1572 | Map_MakeExplosion((damage < 25) ? EXPLOSION_IMPACT_SMALL : EXPLOSION_IMPACT_MEDIUM, unit->o.position, 0, 0); |
| 1573 | } |
| 1574 | |
| 1575 | if (houseID != g_playerHouseID && unit->actionID == ACTION_AMBUSH && unit->o.type != UNIT_HARVESTER) { |
| 1576 | Unit_SetAction(unit, ACTION_ATTACK); |
| 1577 | } |
| 1578 | |
| 1579 | if (unit->o.hitpoints >= ui->o.hitpoints / 2) return false; |
| 1580 | |
| 1581 | if (unit->o.type == UNIT_SANDWORM) { |
| 1582 | Unit_SetAction(unit, ACTION_DIE); |
| 1583 | } |
| 1584 | |
| 1585 | if (unit->o.type == UNIT_TROOPERS || unit->o.type == UNIT_INFANTRY) { |
| 1586 | unit->o.type += 2; |
| 1587 | ui = &g_table_unitInfo[unit->o.type]; |
no test coverage detected