* Make an explosion on the given position, of a certain type. All units in the * neighbourhoud get an amount of damage related to their distance to the * explosion. * @param type The type of explosion. * @param position The position of the explosion. * @param hitpoints The amount of hitpoints to give people in the neighbourhoud. * @param unitOriginEncoded The unit that fired the bullet. *
| 401 | * @param unitOriginEncoded The unit that fired the bullet. |
| 402 | */ |
| 403 | void Map_MakeExplosion(uint16 type, tile32 position, uint16 hitpoints, uint16 unitOriginEncoded) |
| 404 | { |
| 405 | uint16 reactionDistance = (type == EXPLOSION_DEATH_HAND) ? 32 : 16; |
| 406 | uint16 positionPacked = Tile_PackTile(position); |
| 407 | |
| 408 | if (!s_debugNoExplosionDamage && hitpoints != 0) { |
| 409 | PoolFindStruct find; |
| 410 | find.houseID = HOUSE_INVALID; |
| 411 | find.index = 0xFFFF; |
| 412 | find.type = 0xFFFF; |
| 413 | |
| 414 | while (true) { |
| 415 | const UnitInfo *ui; |
| 416 | uint16 distance; |
| 417 | Team *t; |
| 418 | Unit *u; |
| 419 | Unit *us; |
| 420 | Unit *attack; |
| 421 | |
| 422 | u = Unit_Find(&find); |
| 423 | if (u == NULL) break; |
| 424 | |
| 425 | ui = &g_table_unitInfo[u->o.type]; |
| 426 | |
| 427 | distance = Tile_GetDistance(position, u->o.position) >> 4; |
| 428 | if (distance >= reactionDistance) continue; |
| 429 | |
| 430 | if (!(u->o.type == UNIT_SANDWORM && type == EXPLOSION_SANDWORM_SWALLOW) && u->o.type != UNIT_FRIGATE) { |
| 431 | Unit_Damage(u, hitpoints >> (distance >> 2), 0); |
| 432 | } |
| 433 | |
| 434 | if (u->o.houseID == g_playerHouseID) continue; |
| 435 | |
| 436 | us = Tools_Index_GetUnit(unitOriginEncoded); |
| 437 | if (us == NULL) continue; |
| 438 | if (us == u) continue; |
| 439 | if (House_AreAllied(Unit_GetHouseID(u), Unit_GetHouseID(us))) continue; |
| 440 | |
| 441 | t = Unit_GetTeam(u); |
| 442 | if (t != NULL) { |
| 443 | const UnitInfo *targetInfo; |
| 444 | Unit *target; |
| 445 | |
| 446 | if (t->action == TEAM_ACTION_STAGING) { |
| 447 | Unit_RemoveFromTeam(u); |
| 448 | Unit_SetAction(u, ACTION_HUNT); |
| 449 | continue; |
| 450 | } |
| 451 | |
| 452 | target = Tools_Index_GetUnit(t->target); |
| 453 | if (target == NULL) continue; |
| 454 | |
| 455 | targetInfo = &g_table_unitInfo[target->o.type]; |
| 456 | if (targetInfo->bulletType == UNIT_INVALID) t->target = unitOriginEncoded; |
| 457 | continue; |
| 458 | } |
| 459 | |
| 460 | if (u->o.type == UNIT_HARVESTER) { |
no test coverage detected