| 63 | } |
| 64 | |
| 65 | void Projectile::init(World* world, EntityId entityId, EntityMode mode) { |
| 66 | Entity::init(world, entityId, mode); |
| 67 | m_movementController->init(world); |
| 68 | m_movementController->setIgnorePhysicsEntities({entityId}); |
| 69 | |
| 70 | m_timeToLive = m_parameters.getFloat("timeToLive", m_config->timeToLive); |
| 71 | setSourceEntity(m_sourceEntity, m_trackSourceEntity); |
| 72 | |
| 73 | m_periodicActions.clear(); |
| 74 | if (m_parameters.contains("periodicActions")) { |
| 75 | for (auto const& c : m_parameters.getArray("periodicActions", {})) |
| 76 | m_periodicActions.append(make_tuple(GameTimer(c.getFloat("time")), c.getBool("repeat", true), c)); |
| 77 | } else { |
| 78 | for (auto const& periodicAction : m_config->periodicActions) |
| 79 | m_periodicActions.append(make_tuple(GameTimer(get<0>(periodicAction)), get<1>(periodicAction), get<2>(periodicAction))); |
| 80 | } |
| 81 | |
| 82 | if (isMaster()) { |
| 83 | if (!m_config->scripts.empty()) { |
| 84 | m_scriptComponent.setScripts(m_config->scripts); |
| 85 | m_scriptComponent.setUpdateDelta(m_parameters.getUInt("scriptDelta", m_config->config.getUInt("scriptDelta", 1))); |
| 86 | |
| 87 | m_scriptComponent.addCallbacks("projectile", makeProjectileCallbacks()); |
| 88 | m_scriptComponent.addCallbacks("config", LuaBindings::makeConfigCallbacks([this](String const& name, Json const& def) { |
| 89 | return m_parameters.query(name, m_config->config.query(name, def)); |
| 90 | })); |
| 91 | m_scriptComponent.addCallbacks("entity", LuaBindings::makeEntityCallbacks(this)); |
| 92 | m_scriptComponent.addCallbacks("mcontroller", LuaBindings::makeMovementControllerCallbacks(m_movementController.get())); |
| 93 | m_scriptComponent.init(world); |
| 94 | } |
| 95 | } |
| 96 | m_travelLine = Line2F(position(), position()); |
| 97 | |
| 98 | if (auto referenceVelocity = m_parameters.opt("referenceVelocity")) |
| 99 | setReferenceVelocity(referenceVelocity.apply(jsonToVec2F)); |
| 100 | |
| 101 | if (world->isClient() && !m_persistentAudioFile.empty()) { |
| 102 | m_persistentAudio = make_shared<AudioInstance>(*Root::singleton().assets()->audio(m_persistentAudioFile)); |
| 103 | m_persistentAudio->setLoops(-1); |
| 104 | m_persistentAudio->setPosition(position()); |
| 105 | m_pendingRenderables.append(m_persistentAudio); |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | void Projectile::uninit() { |
| 110 | if (m_persistentAudio) |
nothing calls this directly
no test coverage detected