| 2584 | } |
| 2585 | |
| 2586 | void Map::DoExplosionDamage( |
| 2587 | const m_Vec3& explosion_center, |
| 2588 | const float explosion_radius, |
| 2589 | const int base_damage, |
| 2590 | const EntityId explosion_owner_monster_id, |
| 2591 | const Time current_time ) |
| 2592 | { |
| 2593 | const auto distance_to_damage= |
| 2594 | [&] ( const float distance ) -> int |
| 2595 | { |
| 2596 | return std::round( float(base_damage) * ( 1.0f - distance / explosion_radius ) ); |
| 2597 | }; |
| 2598 | |
| 2599 | for( MonstersContainer::value_type& monster_value : monsters_ ) |
| 2600 | { |
| 2601 | MonsterBase& monster= *monster_value.second; |
| 2602 | const float monster_radius= |
| 2603 | monster.MonsterId() == 0u |
| 2604 | ? GameConstants::player_radius |
| 2605 | : game_resources_->monsters_description[ monster.MonsterId() ].w_radius; |
| 2606 | |
| 2607 | const m_Vec2 monster_z_minmax= monster.GetZMinMax(); |
| 2608 | |
| 2609 | const float distance= |
| 2610 | DistanceToCylinder( |
| 2611 | monster.Position().xy(), monster_radius, |
| 2612 | monster.Position().z + monster_z_minmax.x, monster.Position().z + monster_z_minmax.y, |
| 2613 | explosion_center ); |
| 2614 | |
| 2615 | if( distance > explosion_radius ) |
| 2616 | continue; |
| 2617 | |
| 2618 | const int damage= distance_to_damage(distance); |
| 2619 | if( damage > 0 ) |
| 2620 | monster.Hit( |
| 2621 | damage, ( monster.Position().xy() - explosion_center.xy() ), explosion_owner_monster_id, |
| 2622 | *this, |
| 2623 | monster_value.first, current_time ); |
| 2624 | } |
| 2625 | |
| 2626 | for( StaticModel& model : static_models_ ) |
| 2627 | { |
| 2628 | if( model.model_id >= map_data_->models_description.size() ) |
| 2629 | continue; |
| 2630 | |
| 2631 | const MapData::ModelDescription& description= map_data_->models_description[ model.model_id ]; |
| 2632 | if( description.radius <= 0.0f || description.blow_effect == 0 ) // Not explodable. |
| 2633 | continue; |
| 2634 | |
| 2635 | const Model& model_geometry= map_data_->models[ model.model_id ]; |
| 2636 | |
| 2637 | const float distance= |
| 2638 | DistanceToCylinder( |
| 2639 | model.pos.xy(), description.radius, |
| 2640 | model.pos.z + model_geometry.z_min, model.pos.z + model_geometry.z_max, |
| 2641 | explosion_center ); |
| 2642 | |
| 2643 | if( distance > explosion_radius ) |
nothing calls this directly
no test coverage detected