| 479 | } |
| 480 | |
| 481 | void Object::destroy(RenderCallback* renderCallback) { |
| 482 | bool doSmash = m_health.get() <= 0 || configValue("smashOnBreak", m_config->smashOnBreak).toBool(); |
| 483 | |
| 484 | if (isMaster()) { |
| 485 | m_scriptComponent.invoke("die", m_health.get() <= 0); |
| 486 | |
| 487 | try { |
| 488 | if (doSmash) { |
| 489 | auto smashDropPool = configValue("smashDropPool", "").toString(); |
| 490 | if (!smashDropPool.empty()) { |
| 491 | for (auto const& treasureItem : Root::singleton().treasureDatabase()->createTreasure(smashDropPool, world()->threatLevel())) |
| 492 | world()->addEntity(ItemDrop::createRandomizedDrop(treasureItem, position())); |
| 493 | } else if (!m_config->smashDropOptions.empty()) { |
| 494 | List<ItemDescriptor> drops; |
| 495 | auto dropOption = Random::randFrom(m_config->smashDropOptions); |
| 496 | for (auto o : dropOption) |
| 497 | world()->addEntity(ItemDrop::createRandomizedDrop(o, position())); |
| 498 | } |
| 499 | } else { |
| 500 | auto breakDropPool = configValue("breakDropPool", "").toString(); |
| 501 | if (!breakDropPool.empty()) { |
| 502 | for (auto const& treasureItem : Root::singleton().treasureDatabase()->createTreasure(breakDropPool, world()->threatLevel())) |
| 503 | world()->addEntity(ItemDrop::createRandomizedDrop(treasureItem, position())); |
| 504 | } else if (!m_config->breakDropOptions.empty()) { |
| 505 | List<ItemDescriptor> drops; |
| 506 | auto dropOption = Random::randFrom(m_config->breakDropOptions); |
| 507 | for (auto o : dropOption) |
| 508 | world()->addEntity(ItemDrop::createRandomizedDrop(o, position())); |
| 509 | } else if (m_config->hasObjectItem) { |
| 510 | ItemDescriptor objectItem(m_config->name, 1); |
| 511 | if (configValue("retainObjectParametersInItem", m_config->retainObjectParametersInItem).optBool().value()) { |
| 512 | auto parameters = m_parameters.baseMap(); |
| 513 | parameters.remove("owner"); |
| 514 | parameters["scriptStorage"] = m_scriptComponent.getScriptStorage(); |
| 515 | objectItem = objectItem.applyParameters(parameters); |
| 516 | } |
| 517 | world()->addEntity(ItemDrop::createRandomizedDrop(objectItem, position())); |
| 518 | } |
| 519 | } |
| 520 | } catch (StarException const& e) { |
| 521 | Logger::warn("Invalid dropID in entity death. {}", outputException(e, false)); |
| 522 | } |
| 523 | } |
| 524 | |
| 525 | if (renderCallback && doSmash && !m_config->smashSoundOptions.empty()) { |
| 526 | auto audio = make_shared<AudioInstance>(*Root::singleton().assets()->audio(Random::randFrom(m_config->smashSoundOptions))); |
| 527 | renderCallback->addAudios({std::move(audio)}, position()); |
| 528 | } |
| 529 | |
| 530 | if (renderCallback && doSmash && !m_config->smashParticles.empty()) { |
| 531 | auto& root = Root::singleton(); |
| 532 | List<Particle> particles; |
| 533 | for (auto const& config : m_config->smashParticles) { |
| 534 | auto creator = root.particleDatabase()->particleCreator(config.get("particle"), m_config->path); |
| 535 | unsigned count = config.getUInt("count", 1); |
| 536 | Vec2F offset = jsonToVec2F(config.get("offset", JsonArray{0, 0})); |
| 537 | bool flip = config.getBool("flip", false); |
| 538 | for (unsigned i = 0; i < count; ++i) { |
nothing calls this directly
no test coverage detected