| 186 | } |
| 187 | |
| 188 | void City::handleProjectileHit(GameState &state, sp<Projectile> projectile, bool displayDoodad, |
| 189 | bool playSound, bool expired) |
| 190 | { |
| 191 | if (displayDoodad && projectile->doodadType) |
| 192 | { |
| 193 | placeDoodad(projectile->doodadType, projectile->position); |
| 194 | } |
| 195 | |
| 196 | if (playSound && projectile->impactSfx && (!expired || projectile->splitIntoTypesCity.empty())) |
| 197 | { |
| 198 | fw().soundBackend->playSample(projectile->impactSfx, projectile->position); |
| 199 | } |
| 200 | if (expired) |
| 201 | { |
| 202 | std::set<sp<Sample>> fireSounds; |
| 203 | for (auto &p : projectile->splitIntoTypesCity) |
| 204 | { |
| 205 | auto direction = (float)randBoundsInclusive(state.rng, 0, 628) / 100.0f; |
| 206 | auto velocity = glm::normalize( |
| 207 | VehicleType::directionToVector(VehicleType::getDirectionLarge(direction))); |
| 208 | velocity *= p->speed * PROJECTILE_VELOCITY_MULTIPLIER; |
| 209 | auto newProj = mksp<Projectile>( |
| 210 | p->guided ? Projectile::Type::Missile : Projectile::Type::Beam, |
| 211 | projectile->firerVehicle, projectile->trackedVehicle, projectile->targetPosition, |
| 212 | projectile->position, velocity, p->turn_rate, p->ttl, p->damage, 0, 0, p->tail_size, |
| 213 | p->projectile_sprites, p->impact_sfx, p->explosion_graphic, |
| 214 | state.city_common_image_list->projectileVoxelMap, p->stunTicks, p->splitIntoTypes, |
| 215 | projectile->manualFire); |
| 216 | map->addObjectToMap(newProj); |
| 217 | projectiles.insert(newProj); |
| 218 | if (p->fire_sfx) |
| 219 | { |
| 220 | fireSounds.insert(p->fire_sfx); |
| 221 | } |
| 222 | } |
| 223 | for (auto &s : fireSounds) |
| 224 | { |
| 225 | fw().soundBackend->playSample(s, projectile->position); |
| 226 | } |
| 227 | } |
| 228 | projectiles.erase(projectile); |
| 229 | } |
| 230 | |
| 231 | void City::update(GameState &state, unsigned int ticks) |
| 232 | { |
no test coverage detected