| 1082 | |
| 1083 | |
| 1084 | void cWorld::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData) |
| 1085 | { |
| 1086 | if (cPluginManager::Get()->CallHookExploding(*this, a_ExplosionSize, a_CanCauseFire, a_BlockX, a_BlockY, a_BlockZ, a_Source, a_SourceData) || (a_ExplosionSize <= 0)) |
| 1087 | { |
| 1088 | return; |
| 1089 | } |
| 1090 | |
| 1091 | // TODO: Add damage to entities and implement block hardiness |
| 1092 | Vector3d explosion_pos = Vector3d(a_BlockX, a_BlockY, a_BlockZ); |
| 1093 | cVector3iArray BlocksAffected; |
| 1094 | m_ChunkMap->DoExplosionAt(a_ExplosionSize, a_BlockX, a_BlockY, a_BlockZ, BlocksAffected); |
| 1095 | BroadcastSoundEffect("random.explode", (int)floor(a_BlockX * 8), (int)floor(a_BlockY * 8), (int)floor(a_BlockZ * 8), 1.0f, 0.6f); |
| 1096 | { |
| 1097 | cCSLock Lock(m_CSPlayers); |
| 1098 | for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) |
| 1099 | { |
| 1100 | cClientHandle * ch = (*itr)->GetClientHandle(); |
| 1101 | if ((ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed()) |
| 1102 | { |
| 1103 | continue; |
| 1104 | } |
| 1105 | Vector3d distance_explosion = (*itr)->GetPosition() - explosion_pos; |
| 1106 | if (distance_explosion.SqrLength() < 4096.0) |
| 1107 | { |
| 1108 | double real_distance = std::max(0.004, sqrt(distance_explosion.SqrLength())); |
| 1109 | double power = a_ExplosionSize / real_distance; |
| 1110 | if (power <= 1) |
| 1111 | { |
| 1112 | power = 0; |
| 1113 | } |
| 1114 | distance_explosion.Normalize(); |
| 1115 | distance_explosion *= power; |
| 1116 | ch->SendExplosion(a_BlockX, a_BlockY, a_BlockZ, (float)a_ExplosionSize, BlocksAffected, distance_explosion); |
| 1117 | } |
| 1118 | } |
| 1119 | } |
| 1120 | cPluginManager::Get()->CallHookExploded(*this, a_ExplosionSize, a_CanCauseFire, a_BlockX, a_BlockY, a_BlockZ, a_Source, a_SourceData); |
| 1121 | } |
| 1122 | |
| 1123 | |
| 1124 |
no test coverage detected