diff --git a/source/base/StarMixer.cpp b/source/base/StarMixer.cpp index c38d17e..2ec6b9e 100644 --- a/source/base/StarMixer.cpp +++ b/source/base/StarMixer.cpp @@ -172,6 +172,8 @@ Mixer::Mixer(unsigned sampleRate, unsigned channels) { m_groupVolumes[MixerGroup::Effects] = {1.0f, 1.0f, 0}; m_groupVolumes[MixerGroup::Music] = {1.0f, 1.0f, 0}; m_groupVolumes[MixerGroup::Cinematic] = {1.0f, 1.0f, 0}; + + m_speed = 1.0f; } unsigned Mixer::sampleRate() const { @@ -203,6 +205,10 @@ bool Mixer::hasEffect(String const& effectName) { return m_effects.contains(effectName); } +void Mixer::setSpeed(float speed) { + m_speed = speed; +} + void Mixer::setVolume(float volume, float rampTime) { MutexLocker locker(m_mutex); m_volume.target = volume; @@ -259,6 +265,8 @@ void Mixer::read(int16_t* outBuffer, size_t frameCount, ExtraMixFunction extraMi for (size_t i = 0; i < bufferSize; ++i) outBuffer[i] = 0; + float speed = m_speed; + { MutexLocker locker(m_queueMutex); // Mix all active sounds @@ -288,6 +296,9 @@ void Mixer::read(int16_t* outBuffer, size_t frameCount, ExtraMixFunction extraMi ? approach(audioInstance->m_pitchMultiplierTarget, audioInstance->m_pitchMultiplier, audioInstance->m_pitchMultiplierVelocity * time) : audioInstance->m_pitchMultiplier; + if (audioInstance->m_mixerGroup == MixerGroup::Effects) + pitchMultiplier *= speed; + if (audioStopVolEnd == 0.0f && audioInstance->m_stopping) finished = true; @@ -461,7 +472,7 @@ void Mixer::setGroupVolume(MixerGroup group, float targetValue, float rampTime) } } -void Mixer::update(PositionalAttenuationFunction positionalAttenuationFunction) { +void Mixer::update(float dt, PositionalAttenuationFunction positionalAttenuationFunction) { { MutexLocker locker(m_queueMutex); eraseWhere(m_audios, [&](auto& p) { diff --git a/source/base/StarMixer.hpp b/source/base/StarMixer.hpp index d369cfb..f87f5be 100644 --- a/source/base/StarMixer.hpp +++ b/source/base/StarMixer.hpp @@ -115,6 +115,9 @@ public: StringList currentEffects(); bool hasEffect(String const& effectName); + // Global speed + void setSpeed(float speed); + // Global volume void setVolume(float volume, float rampTime); @@ -131,7 +134,7 @@ public: // Call within the main loop of the program using Mixer, calculates // positional attenuation of audio and does cleanup. - void update(PositionalAttenuationFunction positionalAttenuationFunction = {}); + void update(float dt, PositionalAttenuationFunction positionalAttenuationFunction = {}); private: struct EffectInfo { @@ -161,6 +164,7 @@ private: List m_mixBuffer; Map m_groupVolumes; + atomic m_speed; }; } diff --git a/source/client/StarClientApplication.cpp b/source/client/StarClientApplication.cpp index 33327fa..5e317cf 100644 --- a/source/client/StarClientApplication.cpp +++ b/source/client/StarClientApplication.cpp @@ -346,6 +346,7 @@ void ClientApplication::processInput(InputEvent const& event) { } void ClientApplication::update() { + float dt = WorldTimestep * GlobalTimescale; if (m_state >= MainAppState::Title) { if (auto p2pNetworkingService = appController()->p2pNetworkingService()) { if (auto join = p2pNetworkingService->pullPendingJoin()) { @@ -361,21 +362,21 @@ void ClientApplication::update() { } if (!m_errorScreen->accepted()) - m_errorScreen->update(); + m_errorScreen->update(dt); if (m_state == MainAppState::Mods) - updateMods(); + updateMods(dt); else if (m_state == MainAppState::ModsWarning) - updateModsWarning(); + updateModsWarning(dt); if (m_state == MainAppState::Splash) - updateSplash(); + updateSplash(dt); else if (m_state == MainAppState::Error) - updateError(); + updateError(dt); else if (m_state == MainAppState::Title) - updateTitle(); + updateTitle(dt); else if (m_state > MainAppState::Title) - updateRunning(); + updateRunning(dt); // Swallow leftover encoded voice data if we aren't in-game to allow mic read to continue for settings. if (m_state <= MainAppState::Title) { @@ -647,8 +648,8 @@ void ClientApplication::setError(String const& error, std::exception const& e) { changeState(MainAppState::Title); } -void ClientApplication::updateMods() { - m_cinematicOverlay->update(); +void ClientApplication::updateMods(float dt) { + m_cinematicOverlay->update(dt); auto ugcService = appController()->userGeneratedContentService(); if (ugcService) { if (ugcService->triggerContentDownload()) { @@ -686,27 +687,28 @@ void ClientApplication::updateMods() { } } -void ClientApplication::updateModsWarning() { +void ClientApplication::updateModsWarning(float dt) { if (m_errorScreen->accepted()) changeState(MainAppState::Splash); } -void ClientApplication::updateSplash() { - m_cinematicOverlay->update(); +void ClientApplication::updateSplash(float dt) { + m_cinematicOverlay->update(dt); if (!m_rootLoader.isRunning() && (m_cinematicOverlay->completable() || m_cinematicOverlay->completed())) changeState(MainAppState::Title); } -void ClientApplication::updateError() { +void ClientApplication::updateError(float dt) { if (m_errorScreen->accepted()) changeState(MainAppState::Title); } -void ClientApplication::updateTitle() { - m_cinematicOverlay->update(); +void ClientApplication::updateTitle(float dt) { + m_cinematicOverlay->update(dt); - m_titleScreen->update(); - m_mainMixer->update(); + m_titleScreen->update(dt); + m_mainMixer->update(dt); + m_mainMixer->setSpeed(GlobalTimescale); appController()->setAcceptingTextInput(m_titleScreen->textInputActive()); @@ -752,7 +754,7 @@ void ClientApplication::updateTitle() { } } -void ClientApplication::updateRunning() { +void ClientApplication::updateRunning(float dt) { try { auto p2pNetworkingService = appController()->p2pNetworkingService(); bool clientIPJoinable = m_root->configuration()->get("clientIPJoinable").toBool(); @@ -869,12 +871,13 @@ void ClientApplication::updateRunning() { voiceData.setByteOrder(ByteOrder::LittleEndian); //voiceData.writeBytes(VoiceBroadcastPrefix.utf8Bytes()); transmitting with SE compat for now bool needstoSendVoice = m_voice->send(voiceData, 5000); - m_universeClient->update(); + m_universeClient->update(dt); if (checkDisconnection()) return; if (auto worldClient = m_universeClient->worldClient()) { + m_worldPainter->update(dt); auto& broadcastCallback = worldClient->broadcastCallback(); if (!broadcastCallback) { broadcastCallback = [&](PlayerPtr player, StringView broadcast) -> bool { @@ -909,12 +912,12 @@ void ClientApplication::updateRunning() { } worldClient->setInteractiveHighlightMode(isActionTaken(InterfaceAction::ShowLabels)); } + updateCamera(dt); - updateCamera(); - - m_cinematicOverlay->update(); - m_mainInterface->update(); - m_mainMixer->update(m_cinematicOverlay->muteSfx(), m_cinematicOverlay->muteMusic()); + m_cinematicOverlay->update(dt); + m_mainInterface->update(dt); + m_mainMixer->update(dt, m_cinematicOverlay->muteSfx(), m_cinematicOverlay->muteMusic()); + m_mainMixer->setSpeed(GlobalTimescale); bool inputActive = m_mainInterface->textInputActive(); appController()->setAcceptingTextInput(inputActive); @@ -970,12 +973,12 @@ bool ClientApplication::isActionTakenEdge(InterfaceAction action) const { return false; } -void ClientApplication::updateCamera() { +void ClientApplication::updateCamera(float dt) { if (!m_universeClient->worldClient()) return; WorldCamera& camera = m_worldPainter->camera(); - camera.update(WorldTimestep); + camera.update(dt); if (m_mainInterface->fixedCamera()) return; diff --git a/source/client/StarClientApplication.hpp b/source/client/StarClientApplication.hpp index 4ee837e..9e56227 100644 --- a/source/client/StarClientApplication.hpp +++ b/source/client/StarClientApplication.hpp @@ -58,17 +58,17 @@ private: void setError(String const& error); void setError(String const& error, std::exception const& e); - void updateMods(); - void updateModsWarning(); - void updateSplash(); - void updateError(); - void updateTitle(); - void updateRunning(); + void updateMods(float dt); + void updateModsWarning(float dt); + void updateSplash(float dt); + void updateError(float dt); + void updateTitle(float dt); + void updateRunning(float dt); bool isActionTaken(InterfaceAction action) const; bool isActionTakenEdge(InterfaceAction action) const; - void updateCamera(); + void updateCamera(float dt); RootUPtr m_root; ThreadFunction m_rootLoader; diff --git a/source/frontend/StarActionBar.cpp b/source/frontend/StarActionBar.cpp index 5ccff7b..82eb7d2 100644 --- a/source/frontend/StarActionBar.cpp +++ b/source/frontend/StarActionBar.cpp @@ -173,7 +173,7 @@ bool ActionBar::sendEvent(InputEvent const& event) { return false; } -void ActionBar::update() { +void ActionBar::update(float dt) { auto inventory = m_player->inventory(); auto abl = inventory->selectedActionBarLocation(); if (abl.is()) { diff --git a/source/frontend/StarActionBar.hpp b/source/frontend/StarActionBar.hpp index 2239bda..883b364 100644 --- a/source/frontend/StarActionBar.hpp +++ b/source/frontend/StarActionBar.hpp @@ -22,7 +22,7 @@ public: PanePtr createTooltip(Vec2I const& screenPosition) override; bool sendEvent(InputEvent const& event) override; - void update() override; + void update(float dt) override; Maybe cursorOverride(Vec2I const& screenPosition) override; diff --git a/source/frontend/StarAiInterface.cpp b/source/frontend/StarAiInterface.cpp index d9a543a..599b829 100644 --- a/source/frontend/StarAiInterface.cpp +++ b/source/frontend/StarAiInterface.cpp @@ -98,21 +98,21 @@ AiInterface::AiInterface(UniverseClientPtr client, CinematicPtr cinematic, MainI m_defaultRecruitDescription = assets->json("/interface/ai/ai.config:defaultRecruitDescription").toString(); } -void AiInterface::update() { +void AiInterface::update(float dt) { if (!m_client->playerOnOwnShip()) dismiss(); - Pane::update(); + Pane::update(dt); m_showCrewButton->setVisibility(m_currentPage == AiPages::StatusPage); m_showMissionsButton->setVisibility(m_currentPage == AiPages::StatusPage); m_backButton->setVisibility(m_currentPage != AiPages::StatusPage); - m_staticAnimation.update(WorldTimestep); - m_scanlineAnimation.update(WorldTimestep); + m_staticAnimation.update(dt); + m_scanlineAnimation.update(dt); if (m_currentSpeech) { - m_textLength += m_currentSpeech->speedModifier * m_aiDatabase->charactersPerSecond() * WorldTimestep; + m_textLength += m_currentSpeech->speedModifier * m_aiDatabase->charactersPerSecond() * dt; m_currentTextWidget->setText(m_currentSpeech->text); m_currentTextWidget->setTextCharLimit(min(m_textMaxLength, floor(m_textLength))); @@ -129,10 +129,10 @@ void AiInterface::update() { if (m_chatterSound) m_chatterSound->stop(); } - m_faceAnimation.second.update(WorldTimestep * m_currentSpeech->speedModifier); + m_faceAnimation.second.update(dt * m_currentSpeech->speedModifier); } else { setFaceAnimation("idle"); - m_faceAnimation.second.update(WorldTimestep); + m_faceAnimation.second.update(dt); if (m_chatterSound) m_chatterSound->stop(); } diff --git a/source/frontend/StarAiInterface.hpp b/source/frontend/StarAiInterface.hpp index 0b5e713..7a4a229 100644 --- a/source/frontend/StarAiInterface.hpp +++ b/source/frontend/StarAiInterface.hpp @@ -34,7 +34,7 @@ class AiInterface : public Pane { public: AiInterface(UniverseClientPtr client, CinematicPtr cinematic, MainInterfacePaneManager* paneManager); - void update() override; + void update(float dt) override; void displayed() override; void dismissed() override; diff --git a/source/frontend/StarBaseScriptPane.cpp b/source/frontend/StarBaseScriptPane.cpp index 0254e46..90d253c 100644 --- a/source/frontend/StarBaseScriptPane.cpp +++ b/source/frontend/StarBaseScriptPane.cpp @@ -71,8 +71,8 @@ void BaseScriptPane::dismissed() { m_script.uninit(); } -void BaseScriptPane::tick() { - Pane::tick(); +void BaseScriptPane::tick(float dt) { + Pane::tick(dt); for (auto p : m_canvasClickCallbacks) { for (auto const& clickEvent : p.first->pullClickEvents()) @@ -83,7 +83,7 @@ void BaseScriptPane::tick() { m_script.invoke(p.second, (int)keyEvent.key, keyEvent.keyDown); } - m_script.update(m_script.updateDt()); + m_script.update(m_script.updateDt(dt)); } bool BaseScriptPane::sendEvent(InputEvent const& event) { diff --git a/source/frontend/StarBaseScriptPane.hpp b/source/frontend/StarBaseScriptPane.hpp index b5aa502..4a47a4a 100644 --- a/source/frontend/StarBaseScriptPane.hpp +++ b/source/frontend/StarBaseScriptPane.hpp @@ -22,7 +22,7 @@ public: void displayed() override; void dismissed() override; - void tick() override; + void tick(float dt) override; bool sendEvent(InputEvent const& event) override; diff --git a/source/frontend/StarCharCreation.cpp b/source/frontend/StarCharCreation.cpp index d873a72..440902c 100644 --- a/source/frontend/StarCharCreation.cpp +++ b/source/frontend/StarCharCreation.cpp @@ -183,13 +183,13 @@ void CharCreationPane::randomize() { changed(); } -void CharCreationPane::tick() { - Pane::tick(); +void CharCreationPane::tick(float dt) { + Pane::tick(dt); if (!active()) return; if (!m_previewPlayer) return; - m_previewPlayer->animatePortrait(); + m_previewPlayer->animatePortrait(dt); } bool CharCreationPane::sendEvent(InputEvent const& event) { diff --git a/source/frontend/StarCharCreation.hpp b/source/frontend/StarCharCreation.hpp index 272ea71..7a52f4f 100644 --- a/source/frontend/StarCharCreation.hpp +++ b/source/frontend/StarCharCreation.hpp @@ -23,7 +23,7 @@ public: void randomize(); void randomizeName(); - virtual void tick() override; + virtual void tick(float dt) override; virtual bool sendEvent(InputEvent const& event) override; virtual PanePtr createTooltip(Vec2I const&) override; diff --git a/source/frontend/StarChat.cpp b/source/frontend/StarChat.cpp index 7b75f2d..72c1409 100644 --- a/source/frontend/StarChat.cpp +++ b/source/frontend/StarChat.cpp @@ -95,8 +95,8 @@ Chat::Chat(UniverseClientPtr client) : m_client(client) { updateSize(); } -void Chat::update() { - Pane::update(); +void Chat::update(float dt) { + Pane::update(dt); auto team = m_client->teamClient()->currentTeam(); for (auto button : fetchChild("filterGroup")->buttons()) { diff --git a/source/frontend/StarChat.hpp b/source/frontend/StarChat.hpp index e88a797..7d9d127 100644 --- a/source/frontend/StarChat.hpp +++ b/source/frontend/StarChat.hpp @@ -26,7 +26,7 @@ public: virtual void renderImpl() override; virtual void hide() override; - virtual void update() override; + virtual void update(float dt) override; void addLine(String const& text, bool showPane = true); void addMessages(List const& messages, bool showPane = true); diff --git a/source/frontend/StarChatBubbleManager.cpp b/source/frontend/StarChatBubbleManager.cpp index b9077fe..166eba0 100644 --- a/source/frontend/StarChatBubbleManager.cpp +++ b/source/frontend/StarChatBubbleManager.cpp @@ -86,9 +86,9 @@ void ChatBubbleManager::setCamera(WorldCamera const& camera) { } } -void ChatBubbleManager::update(WorldClientPtr world) { - m_bubbles.forEach([this, &world](BubbleState& bubbleState, Bubble& bubble) { - bubble.age += WorldTimestep; +void ChatBubbleManager::update(float dt, WorldClientPtr world) { + m_bubbles.forEach([this, dt, &world](BubbleState& bubbleState, Bubble& bubble) { + bubble.age += dt; if (auto entity = world->get(bubble.entity)) { bubble.onscreen = m_camera.worldGeometry().rectIntersectsRect( m_camera.worldScreenRect(), entity->metaBoundBox().translated(entity->position())); @@ -97,7 +97,7 @@ void ChatBubbleManager::update(WorldClientPtr world) { }); for (auto& portraitBubble : m_portraitBubbles) { - portraitBubble.age += WorldTimestep; + portraitBubble.age += dt; if (auto entity = world->entity(portraitBubble.entity)) { portraitBubble.onscreen = m_camera.worldGeometry().rectIntersectsRect(m_camera.worldScreenRect(), entity->metaBoundBox().translated(entity->position())); if (auto chatter = as(entity)) @@ -125,7 +125,7 @@ void ChatBubbleManager::update(WorldClientPtr world) { return false; }); - m_bubbles.update(); + m_bubbles.update(dt); } uint8_t ChatBubbleManager::calcDistanceFadeAlpha(Vec2F bubbleScreenPosition, StoredFunctionPtr fadeFunction) const { diff --git a/source/frontend/StarChatBubbleManager.hpp b/source/frontend/StarChatBubbleManager.hpp index b23037a..9d8a867 100644 --- a/source/frontend/StarChatBubbleManager.hpp +++ b/source/frontend/StarChatBubbleManager.hpp @@ -22,7 +22,7 @@ public: void addChatActions(List chatActions, bool silent = false); - void update(WorldClientPtr world); + void update(float dt, WorldClientPtr world); void render(); private: diff --git a/source/frontend/StarChatBubbleSeparation.hpp b/source/frontend/StarChatBubbleSeparation.hpp index 756db27..4bbf018 100644 --- a/source/frontend/StarChatBubbleSeparation.hpp +++ b/source/frontend/StarChatBubbleSeparation.hpp @@ -52,7 +52,7 @@ public: List filtered(function func); void forEach(function func); - void update(); + void update(float dt); void clear(); bool empty() const; @@ -170,7 +170,7 @@ void BubbleSeparator::forEach(function func) { } template -void BubbleSeparator::update() { +void BubbleSeparator::update(float dt) { m_bubbles.exec([this](Bubble& bubble) { Vec2F delta = bubble.seperatedOffset - bubble.currentOffset; bubble.currentOffset += m_tweenFactor * delta; diff --git a/source/frontend/StarCinematic.cpp b/source/frontend/StarCinematic.cpp index bf39bd0..40fc8d1 100644 --- a/source/frontend/StarCinematic.cpp +++ b/source/frontend/StarCinematic.cpp @@ -103,7 +103,7 @@ void Cinematic::setPlayer(PlayerPtr player) { m_player = player; } -void Cinematic::update() { +void Cinematic::update(float dt) { m_currentTimeSkip = {}; for (auto timeSkip : m_timeSkips) { if (currentTimecode() >= timeSkip.availableTime && currentTimecode() < timeSkip.skipToTime) diff --git a/source/frontend/StarCinematic.hpp b/source/frontend/StarCinematic.hpp index 0939369..96f40e7 100644 --- a/source/frontend/StarCinematic.hpp +++ b/source/frontend/StarCinematic.hpp @@ -22,7 +22,7 @@ public: void setPlayer(PlayerPtr player); - void update(); + void update(float dt); void render(); bool completed() const; diff --git a/source/frontend/StarCodexInterface.cpp b/source/frontend/StarCodexInterface.cpp index aca0930..dcd82f3 100644 --- a/source/frontend/StarCodexInterface.cpp +++ b/source/frontend/StarCodexInterface.cpp @@ -50,7 +50,7 @@ void CodexInterface::show() { updateCodexList(); } -void CodexInterface::tick() { +void CodexInterface::tick(float dt) { updateCodexList(); } diff --git a/source/frontend/StarCodexInterface.hpp b/source/frontend/StarCodexInterface.hpp index 0f4b549..bd8e103 100644 --- a/source/frontend/StarCodexInterface.hpp +++ b/source/frontend/StarCodexInterface.hpp @@ -21,7 +21,7 @@ public: CodexInterface(PlayerPtr player); virtual void show() override; - virtual void tick() override; + virtual void tick(float dt) override; void showTitles(); void showSelectedContents(); diff --git a/source/frontend/StarContainerInterface.cpp b/source/frontend/StarContainerInterface.cpp index 5a69fda..6540dfb 100644 --- a/source/frontend/StarContainerInterface.cpp +++ b/source/frontend/StarContainerInterface.cpp @@ -258,11 +258,11 @@ void ContainerPane::burn() { m_containerInteractor->burnContainer(); } -void ContainerPane::update() { - Pane::update(); +void ContainerPane::update(float dt) { + Pane::update(dt); if (m_script) - m_script->update(m_script->updateDt()); + m_script->update(m_script->updateDt(dt)); m_itemBag->clearItems(); diff --git a/source/frontend/StarContainerInterface.hpp b/source/frontend/StarContainerInterface.hpp index dee1e07..811be89 100644 --- a/source/frontend/StarContainerInterface.hpp +++ b/source/frontend/StarContainerInterface.hpp @@ -27,7 +27,7 @@ public: bool giveContainerResult(ContainerResult result); protected: - void update() override; + void update(float dt) override; private: enum class ExpectingSwap { diff --git a/source/frontend/StarCraftingInterface.cpp b/source/frontend/StarCraftingInterface.cpp index df0100a..5ad25ce 100644 --- a/source/frontend/StarCraftingInterface.cpp +++ b/source/frontend/StarCraftingInterface.cpp @@ -226,7 +226,7 @@ size_t CraftingPane::itemCount(List const& store, ItemDescriptor const& return itemDb->getCountOfItem(store, item); } -void CraftingPane::update() { +void CraftingPane::update(float dt) { // shut down if we can't reach the table anymore. if (m_sourceEntityId != NullEntityId) { auto sourceEntity = as(m_worldClient->entity(m_sourceEntityId)); @@ -296,7 +296,7 @@ void CraftingPane::update() { setLabel("lblPlayerMoney", toString((int)m_player->currency("money"))); - Pane::update(); + Pane::update(dt); } void CraftingPane::updateCraftButtons() { diff --git a/source/frontend/StarCraftingInterface.hpp b/source/frontend/StarCraftingInterface.hpp index 282729a..33c1e32 100644 --- a/source/frontend/StarCraftingInterface.hpp +++ b/source/frontend/StarCraftingInterface.hpp @@ -34,7 +34,7 @@ private: List determineRecipes(); - virtual void update() override; + virtual void update(float dt) override; void updateCraftButtons(); void updateAvailableRecipes(); bool consumeIngredients(ItemRecipe& recipe, int count); diff --git a/source/frontend/StarErrorScreen.cpp b/source/frontend/StarErrorScreen.cpp index 9162e5b..1dc5f12 100644 --- a/source/frontend/StarErrorScreen.cpp +++ b/source/frontend/StarErrorScreen.cpp @@ -70,12 +70,12 @@ bool ErrorScreen::handleInputEvent(InputEvent const& event) { return m_paneManager->sendInputEvent(event); } -void ErrorScreen::update() { - m_paneManager->update(); +void ErrorScreen::update(float dt) { + m_paneManager->update(dt); + m_cursor.update(dt); } void ErrorScreen::renderCursor() { - m_cursor.update(WorldTimestep); Vec2I cursorPos = m_cursorScreenPos; Vec2I cursorSize = m_cursor.size(); Vec2I cursorOffset = m_cursor.offset(); diff --git a/source/frontend/StarErrorScreen.hpp b/source/frontend/StarErrorScreen.hpp index eb1f73e..e16d6f4 100644 --- a/source/frontend/StarErrorScreen.hpp +++ b/source/frontend/StarErrorScreen.hpp @@ -26,7 +26,7 @@ public: void render(bool useBackdrop = false); bool handleInputEvent(InputEvent const& event); - void update(); + void update(float dt); private: void renderCursor(); diff --git a/source/frontend/StarInventory.cpp b/source/frontend/StarInventory.cpp index 850eedf..bcc2c15 100644 --- a/source/frontend/StarInventory.cpp +++ b/source/frontend/StarInventory.cpp @@ -236,7 +236,7 @@ bool InventoryPane::containsNewItems() const { return false; } -void InventoryPane::update() { +void InventoryPane::update(float dt) { auto inventory = m_player->inventory(); auto context = Widget::context(); @@ -255,7 +255,7 @@ void InventoryPane::update() { m_trashSlot->setItem(inventory->itemsAt(TrashSlot())); m_trashSlot->showLinkIndicator(customBarItems.contains(m_trashSlot->item())); if (auto trashItem = m_trashSlot->item()) { - if (m_trashBurn.tick() && trashItem->count() > 0) { + if (m_trashBurn.tick(dt) && trashItem->count() > 0) { m_player->statistics()->recordEvent("trashItem", JsonObject{ {"itemName", trashItem->name()}, {"count", trashItem->count()}, diff --git a/source/frontend/StarInventory.hpp b/source/frontend/StarInventory.hpp index 035045c..cb5deed 100644 --- a/source/frontend/StarInventory.hpp +++ b/source/frontend/StarInventory.hpp @@ -35,7 +35,7 @@ public: bool containsNewItems() const; protected: - virtual void update() override; + virtual void update(float dt) override; void selectTab(String const& selected); private: diff --git a/source/frontend/StarMainInterface.cpp b/source/frontend/StarMainInterface.cpp index 0dc3a01..526ab99 100644 --- a/source/frontend/StarMainInterface.cpp +++ b/source/frontend/StarMainInterface.cpp @@ -520,8 +520,9 @@ void MainInterface::handleInteractAction(InteractAction interactAction) { } } -void MainInterface::update() { - m_paneManager.update(); +void MainInterface::update(float dt) { + m_paneManager.update(dt); + m_cursor.update(dt); m_questLogInterface->pollDialog(&m_paneManager); @@ -544,7 +545,7 @@ void MainInterface::update() { // update mouseover target EntityId newMouseOverTarget = NullEntityId; - m_stickyTargetingTimer.tick(); + m_stickyTargetingTimer.tick(dt); auto mouseoverEntities = m_client->worldClient()->query(RectF::withCenter(cursorWorldPos, Vec2F(1, 1)), [=](shared_ptr const& entity) { return entity != player && entity->damageBar() == DamageBarType::Default @@ -578,10 +579,10 @@ void MainInterface::update() { if (damageBarEntity && damageBarEntity->damageBar() == DamageBarType::Special) { float targetHealth = damageBarEntity->health() / damageBarEntity->maxHealth(); float fillSpeed = 1.0f / Root::singleton().assets()->json("/interface.config:specialDamageBar.fillTime").toFloat(); - if (abs(targetHealth - m_specialDamageBarValue) < fillSpeed * WorldTimestep) + if (abs(targetHealth - m_specialDamageBarValue) < fillSpeed * dt) m_specialDamageBarValue = targetHealth; else - m_specialDamageBarValue += copysign(1.0f, targetHealth - m_specialDamageBarValue) * fillSpeed * WorldTimestep; + m_specialDamageBarValue += copysign(1.0f, targetHealth - m_specialDamageBarValue) * fillSpeed * dt; } else { m_specialDamageBarTarget = NullEntityId; } @@ -696,7 +697,7 @@ void MainInterface::update() { for (auto it = m_messages.begin(); it != m_messages.end();) { auto& message = *it; - message->cooldown -= WorldTimestep; + message->cooldown -= dt; if (message->cooldown < 0) it = m_messages.erase(it); else @@ -713,7 +714,7 @@ void MainInterface::update() { auto worldId = m_client->playerWorld(); if (worldId.is()) { - if (m_planetNameTimer.tick()) + if (m_planetNameTimer.tick(dt)) m_paneManager.dismissRegisteredPane(MainInterfacePanes::PlanetText); else m_paneManager.displayRegisteredPane(MainInterfacePanes::PlanetText); @@ -755,8 +756,8 @@ void MainInterface::update() { updateCursor(); - m_nameplatePainter->update(m_client->worldClient(), m_worldPainter->camera(), m_client->worldClient()->interactiveHighlightMode()); - m_questIndicatorPainter->update(m_client->worldClient(), m_worldPainter->camera()); + m_nameplatePainter->update(dt, m_client->worldClient(), m_worldPainter->camera(), m_client->worldClient()->interactiveHighlightMode()); + m_questIndicatorPainter->update(dt, m_client->worldClient(), m_worldPainter->camera()); m_chatBubbleManager->setCamera(m_worldPainter->camera()); if (auto worldClient = m_client->worldClient()) { @@ -781,7 +782,7 @@ void MainInterface::update() { } m_chatBubbleManager->addChatActions(chatActions); - m_chatBubbleManager->update(worldClient); + m_chatBubbleManager->update(dt, worldClient); } if (auto container = m_client->worldClient()->get(m_containerInteractor->openContainerId())) { @@ -803,7 +804,7 @@ void MainInterface::update() { pair.second->setSize(Vec2I(m_guiContext->windowSize())); else pair.second->setSize(Vec2I(m_guiContext->windowInterfaceSize())); - pair.second->update(); + pair.second->update(dt); } } @@ -1427,8 +1428,6 @@ void MainInterface::renderCursor() { if (m_cinematicOverlay && !m_cinematicOverlay->completed()) return m_guiContext->applicationController()->setCursorVisible(false); - m_cursor.update(WorldTimestep); - Vec2I cursorPos = m_cursorScreenPos; Vec2I cursorSize = m_cursor.size(); Vec2I cursorOffset = m_cursor.offset(); diff --git a/source/frontend/StarMainInterface.hpp b/source/frontend/StarMainInterface.hpp index 9cf2342..ddc4d3d 100644 --- a/source/frontend/StarMainInterface.hpp +++ b/source/frontend/StarMainInterface.hpp @@ -91,7 +91,7 @@ public: void handleInteractAction(InteractAction interactAction); // Handles incoming client messages, aims main player, etc. - void update(); + void update(float dt); // Render things e.g. quest indicators that should be drawn in the world // behind interface e.g. chat bubbles diff --git a/source/frontend/StarMainMixer.cpp b/source/frontend/StarMainMixer.cpp index d4a2e73..219daa2 100644 --- a/source/frontend/StarMainMixer.cpp +++ b/source/frontend/StarMainMixer.cpp @@ -23,7 +23,7 @@ void MainMixer::setWorldPainter(WorldPainterPtr worldPainter) { m_worldPainter = move(worldPainter); } -void MainMixer::update(bool muteSfx, bool muteMusic) { +void MainMixer::update(float dt, bool muteSfx, bool muteMusic) { auto assets = Root::singleton().assets(); auto updateGroupVolume = [&](MixerGroup group, bool muted, String const& settingName) { @@ -111,9 +111,9 @@ void MainMixer::update(bool muteSfx, bool muteMusic) { }; if (Voice* voice = Voice::singletonPtr()) - voice->update(attenuationFunction); + voice->update(dt, attenuationFunction); - m_mixer->update(attenuationFunction); + m_mixer->update(dt, attenuationFunction); } else { if (m_mixer->hasEffect("lowpass")) @@ -122,9 +122,9 @@ void MainMixer::update(bool muteSfx, bool muteMusic) { m_mixer->removeEffect("echo", 0); if (Voice* voice = Voice::singletonPtr()) - voice->update(); + voice->update(dt); - m_mixer->update(); + m_mixer->update(dt); } } @@ -132,6 +132,10 @@ MixerPtr MainMixer::mixer() const { return m_mixer; } +void MainMixer::setSpeed(float speed) { + m_mixer->setSpeed(max(speed, 0.0f)); +} + void MainMixer::setVolume(float volume, float rampTime) { m_mixer->setVolume(volume, rampTime); } diff --git a/source/frontend/StarMainMixer.hpp b/source/frontend/StarMainMixer.hpp index 2582a2f..9e5ba3f 100644 --- a/source/frontend/StarMainMixer.hpp +++ b/source/frontend/StarMainMixer.hpp @@ -17,10 +17,11 @@ public: void setUniverseClient(UniverseClientPtr universeClient); void setWorldPainter(WorldPainterPtr worldPainter); - void update(bool muteSfx = false, bool muteMusic = false); + void update(float dt, bool muteSfx = false, bool muteMusic = false); MixerPtr mixer() const; + void setSpeed(float speed); void setVolume(float volume, float rampTime = 0.0f); void read(int16_t* sampleData, size_t frameCount, Mixer::ExtraMixFunction = {}); diff --git a/source/frontend/StarMerchantInterface.cpp b/source/frontend/StarMerchantInterface.cpp index c4b1047..8e3ad3a 100644 --- a/source/frontend/StarMerchantInterface.cpp +++ b/source/frontend/StarMerchantInterface.cpp @@ -138,8 +138,8 @@ PanePtr MerchantPane::createTooltip(Vec2I const& screenPosition) { return {}; } -void MerchantPane::update() { - Pane::update(); +void MerchantPane::update(float dt) { + Pane::update(dt); if (!m_worldClient->playerCanReachEntity(m_sourceEntityId)) dismiss(); diff --git a/source/frontend/StarMerchantInterface.hpp b/source/frontend/StarMerchantInterface.hpp index a4ac0c8..d123c9b 100644 --- a/source/frontend/StarMerchantInterface.hpp +++ b/source/frontend/StarMerchantInterface.hpp @@ -30,7 +30,7 @@ public: ItemPtr addItems(ItemPtr const& items); protected: - void update() override; + void update(float dt) override; private: void swapSlot(); diff --git a/source/frontend/StarModsMenu.cpp b/source/frontend/StarModsMenu.cpp index eeceb72..039a94a 100644 --- a/source/frontend/StarModsMenu.cpp +++ b/source/frontend/StarModsMenu.cpp @@ -51,8 +51,8 @@ ModsMenu::ModsMenu() { copyLinkLabel->setVisibility(!hasDesktopService); } -void ModsMenu::update() { - Pane::update(); +void ModsMenu::update(float dt) { + Pane::update(dt); size_t selectedItem = m_modList->selectedItem(); if (selectedItem == NPos) { diff --git a/source/frontend/StarModsMenu.hpp b/source/frontend/StarModsMenu.hpp index a9e8739..e73ac23 100644 --- a/source/frontend/StarModsMenu.hpp +++ b/source/frontend/StarModsMenu.hpp @@ -13,7 +13,7 @@ class ModsMenu : public Pane { public: ModsMenu(); - void update() override; + void update(float dt) override; private: static String bestModName(JsonObject const& metadata, String const& sourcePath); diff --git a/source/frontend/StarNameplatePainter.cpp b/source/frontend/StarNameplatePainter.cpp index 06ffabb..c6bfe8a 100644 --- a/source/frontend/StarNameplatePainter.cpp +++ b/source/frontend/StarNameplatePainter.cpp @@ -28,7 +28,7 @@ NameplatePainter::NameplatePainter() { m_nametags.setMovementThreshold(nametagConfig.getFloat("movementThreshold")); } -void NameplatePainter::update(WorldClientPtr const& world, WorldCamera const& camera, bool inspectionMode) { +void NameplatePainter::update(float dt, WorldClientPtr const& world, WorldCamera const& camera, bool inspectionMode) { m_camera = camera; Set foundEntities; @@ -70,7 +70,7 @@ void NameplatePainter::update(WorldClientPtr const& world, WorldCamera const& ca }); m_entitiesWithNametags = move(foundEntities); - m_nametags.update(); + m_nametags.update(dt); } void NameplatePainter::render() { diff --git a/source/frontend/StarNameplatePainter.hpp b/source/frontend/StarNameplatePainter.hpp index 08c7827..7c3aeb4 100644 --- a/source/frontend/StarNameplatePainter.hpp +++ b/source/frontend/StarNameplatePainter.hpp @@ -15,7 +15,7 @@ class NameplatePainter { public: NameplatePainter(); - void update(WorldClientPtr const& world, WorldCamera const& camera, bool inspectionMode); + void update(float dt, WorldClientPtr const& world, WorldCamera const& camera, bool inspectionMode); void render(); private: diff --git a/source/frontend/StarQuestIndicatorPainter.cpp b/source/frontend/StarQuestIndicatorPainter.cpp index d144021..cad4ace 100644 --- a/source/frontend/StarQuestIndicatorPainter.cpp +++ b/source/frontend/StarQuestIndicatorPainter.cpp @@ -16,7 +16,7 @@ AnimationPtr indicatorAnimation(String indicatorPath) { return make_shared(assets->json(indicatorPath), indicatorPath); } -void QuestIndicatorPainter::update(WorldClientPtr const& world, WorldCamera const& camera) { +void QuestIndicatorPainter::update(float dt, WorldClientPtr const& world, WorldCamera const& camera) { m_camera = camera; Set foundIndicators; @@ -30,7 +30,7 @@ void QuestIndicatorPainter::update(WorldClientPtr const& world, WorldCamera cons if (auto currentIndicator = m_indicators.ptr(entity->entityId())) { currentIndicator->screenPos = screenPos; if (currentIndicator->indicatorName == indicator->indicatorImage) { - currentIndicator->animation->update(WorldTimestep); + currentIndicator->animation->update(dt); } else { currentIndicator->indicatorName = indicator->indicatorImage; currentIndicator->animation = indicatorAnimation(indicator->indicatorImage); diff --git a/source/frontend/StarQuestIndicatorPainter.hpp b/source/frontend/StarQuestIndicatorPainter.hpp index 311680d..c222ac4 100644 --- a/source/frontend/StarQuestIndicatorPainter.hpp +++ b/source/frontend/StarQuestIndicatorPainter.hpp @@ -13,7 +13,7 @@ class QuestIndicatorPainter { public: QuestIndicatorPainter(UniverseClientPtr const& client); - void update(WorldClientPtr const& world, WorldCamera const& camera); + void update(float dt, WorldClientPtr const& world, WorldCamera const& camera); void render(); private: diff --git a/source/frontend/StarQuestInterface.cpp b/source/frontend/StarQuestInterface.cpp index 324cbd8..d9f0b1b 100644 --- a/source/frontend/StarQuestInterface.cpp +++ b/source/frontend/StarQuestInterface.cpp @@ -93,12 +93,12 @@ void QuestLogInterface::pollDialog(PaneManager* paneManager) { void QuestLogInterface::displayed() { Pane::displayed(); - tick(); + tick(0); fetchData(); } -void QuestLogInterface::tick() { - Pane::tick(); +void QuestLogInterface::tick(float dt) { + Pane::tick(dt); auto selected = getSelected(); if (selected && m_manager->hasQuest(selected->data().toString())) { auto quest = m_manager->getQuest(selected->data().toString()); @@ -284,7 +284,7 @@ void QuestLogInterface::showQuests(List quests) { } auto verticalLayout = fetchChild("scrollArea.verticalLayout"); - verticalLayout->update(); + verticalLayout->update(0); } QuestPane::QuestPane(QuestPtr const& quest, PlayerPtr player) : Pane(), m_quest(quest), m_player(move(player)) {} diff --git a/source/frontend/StarQuestInterface.hpp b/source/frontend/StarQuestInterface.hpp index d7d68e8..366d4ac 100644 --- a/source/frontend/StarQuestInterface.hpp +++ b/source/frontend/StarQuestInterface.hpp @@ -19,7 +19,7 @@ public: virtual ~QuestLogInterface() {} virtual void displayed() override; - virtual void tick() override; + virtual void tick(float dt) override; virtual PanePtr createTooltip(Vec2I const& screenPosition) override; void fetchData(); diff --git a/source/frontend/StarQuestTracker.cpp b/source/frontend/StarQuestTracker.cpp index cb603b4..747852a 100644 --- a/source/frontend/StarQuestTracker.cpp +++ b/source/frontend/StarQuestTracker.cpp @@ -71,7 +71,7 @@ bool QuestTrackerPane::sendEvent(InputEvent const& event) { return false; } -void QuestTrackerPane::update() { +void QuestTrackerPane::update(float dt) { if (m_currentQuest) { if (auto objectiveList = m_currentQuest->objectiveList()) { if (objectiveList->size() == 0) { @@ -172,7 +172,7 @@ void QuestTrackerPane::update() { } } - Pane::update(); + Pane::update(dt); } void QuestTrackerPane::setQuest(QuestPtr const& quest) { diff --git a/source/frontend/StarQuestTracker.hpp b/source/frontend/StarQuestTracker.hpp index 226b520..4fbeb7a 100644 --- a/source/frontend/StarQuestTracker.hpp +++ b/source/frontend/StarQuestTracker.hpp @@ -16,7 +16,7 @@ public: QuestTrackerPane(); bool sendEvent(InputEvent const& event) override; - void update() override; + void update(float dt) override; void setQuest(QuestPtr const& quest); diff --git a/source/frontend/StarRadioMessagePopup.cpp b/source/frontend/StarRadioMessagePopup.cpp index f7c9061..503f2d1 100644 --- a/source/frontend/StarRadioMessagePopup.cpp +++ b/source/frontend/StarRadioMessagePopup.cpp @@ -44,9 +44,9 @@ RadioMessagePopup::RadioMessagePopup() { enterStage(PopupStage::Hidden); } -void RadioMessagePopup::update() { +void RadioMessagePopup::update(float dt) { if (messageActive()) { - if (m_stageTimer.tick()) + if (m_stageTimer.tick(dt)) nextPopupStage(); if (m_popupStage == PopupStage::AnimateIn) { @@ -65,11 +65,11 @@ void RadioMessagePopup::update() { setBG("", strf("{}:{}", m_animateOutImage, frame), ""); } - m_slideTimer = min(m_slideTimer + WorldTimestep, m_slideTime); + m_slideTimer = min(m_slideTimer + dt, m_slideTime); updateAnchorOffset(); } - Pane::update(); + Pane::update(dt); } void RadioMessagePopup::dismissed() { diff --git a/source/frontend/StarRadioMessagePopup.hpp b/source/frontend/StarRadioMessagePopup.hpp index 11c18d5..d1d6c11 100644 --- a/source/frontend/StarRadioMessagePopup.hpp +++ b/source/frontend/StarRadioMessagePopup.hpp @@ -16,7 +16,7 @@ class RadioMessagePopup : public Pane { public: RadioMessagePopup(); - void update() override; + void update(float dt) override; void dismissed() override; bool messageActive(); diff --git a/source/frontend/StarScriptPane.cpp b/source/frontend/StarScriptPane.cpp index 3de3c26..2cd74a5 100644 --- a/source/frontend/StarScriptPane.cpp +++ b/source/frontend/StarScriptPane.cpp @@ -47,11 +47,11 @@ void ScriptPane::dismissed() { m_script.removeCallbacks("world"); } -void ScriptPane::tick() { +void ScriptPane::tick(float dt) { if (m_sourceEntityId != NullEntityId && !m_client->worldClient()->playerCanReachEntity(m_sourceEntityId)) dismiss(); - BaseScriptPane::tick(); + BaseScriptPane::tick(dt); } PanePtr ScriptPane::createTooltip(Vec2I const& screenPosition) { diff --git a/source/frontend/StarScriptPane.hpp b/source/frontend/StarScriptPane.hpp index 229ebbb..e7ed2ae 100644 --- a/source/frontend/StarScriptPane.hpp +++ b/source/frontend/StarScriptPane.hpp @@ -16,7 +16,7 @@ public: void displayed() override; void dismissed() override; - void tick() override; + void tick(float dt) override; PanePtr createTooltip(Vec2I const& screenPosition) override; diff --git a/source/frontend/StarStatusPane.cpp b/source/frontend/StarStatusPane.cpp index e325a88..d1bedbb 100644 --- a/source/frontend/StarStatusPane.cpp +++ b/source/frontend/StarStatusPane.cpp @@ -58,8 +58,8 @@ void StatusPane::renderImpl() { } } -void StatusPane::update() { - Pane::update(); +void StatusPane::update(float dt) { + Pane::update(dt); auto assets = Root::singleton().assets(); auto interfaceScale = m_guiContext->interfaceScale(); diff --git a/source/frontend/StarStatusPane.hpp b/source/frontend/StarStatusPane.hpp index 54a87a3..5deba33 100644 --- a/source/frontend/StarStatusPane.hpp +++ b/source/frontend/StarStatusPane.hpp @@ -18,7 +18,7 @@ public: protected: virtual void renderImpl() override; - virtual void update() override; + virtual void update(float dt) override; private: struct StatusEffectIndicator { diff --git a/source/frontend/StarTeamBar.cpp b/source/frontend/StarTeamBar.cpp index 06b3ee7..192edfa 100644 --- a/source/frontend/StarTeamBar.cpp +++ b/source/frontend/StarTeamBar.cpp @@ -80,8 +80,8 @@ void TeamBar::acceptInvitation(Uuid const& inviterUuid) { m_client->teamClient()->acceptInvitation(inviterUuid); } -void TeamBar::update() { - Pane::update(); +void TeamBar::update(float dt) { + Pane::update(dt); updatePlayerResources(); @@ -338,7 +338,7 @@ void TeamMemberMenu::open(Uuid memberUuid, Vec2I position) { Pane::show(); } -void TeamMemberMenu::update() { +void TeamMemberMenu::update(float dt) { auto stillValid = false; auto members = m_owner->m_client->teamClient()->members(); for (auto member : members) { @@ -355,7 +355,7 @@ void TeamMemberMenu::update() { updateWidgets(); - Pane::update(); + Pane::update(dt); } void TeamMemberMenu::updateWidgets() { diff --git a/source/frontend/StarTeamBar.hpp b/source/frontend/StarTeamBar.hpp index 8273ab6..9ebbb50 100644 --- a/source/frontend/StarTeamBar.hpp +++ b/source/frontend/StarTeamBar.hpp @@ -52,7 +52,7 @@ public: void open(Uuid memberUuid, Vec2I position); - virtual void update() override; + virtual void update(float dt) override; private: void updateWidgets(); @@ -77,7 +77,7 @@ public: void acceptInvitation(Uuid const& inviterUuid); protected: - virtual void update() override; + virtual void update(float dt) override; private: void updatePlayerResources(); diff --git a/source/frontend/StarTeleportDialog.cpp b/source/frontend/StarTeleportDialog.cpp index 76f0310..01c6a69 100644 --- a/source/frontend/StarTeleportDialog.cpp +++ b/source/frontend/StarTeleportDialog.cpp @@ -120,7 +120,7 @@ TeleportDialog::TeleportDialog(UniverseClientPtr client, fetchChild("btnTeleport")->setEnabled(destList->selectedItem() != NPos); } -void TeleportDialog::tick() { +void TeleportDialog::tick(float dt) { if (!m_client->worldClient()->playerCanReachEntity(m_sourceEntityId)) dismiss(); } diff --git a/source/frontend/StarTeleportDialog.hpp b/source/frontend/StarTeleportDialog.hpp index 445f73a..3dea84d 100644 --- a/source/frontend/StarTeleportDialog.hpp +++ b/source/frontend/StarTeleportDialog.hpp @@ -19,7 +19,7 @@ public: EntityId sourceEntityId, TeleportBookmark currentLocation); - void tick() override; + void tick(float dt) override; void selectDestination(); void teleport(); diff --git a/source/frontend/StarTitleScreen.cpp b/source/frontend/StarTitleScreen.cpp index 842efc9..f9f16bd 100644 --- a/source/frontend/StarTitleScreen.cpp +++ b/source/frontend/StarTitleScreen.cpp @@ -114,15 +114,17 @@ bool TitleScreen::handleInputEvent(InputEvent const& event) { return m_paneManager.sendInputEvent(event); } -void TitleScreen::update() { +void TitleScreen::update(float dt) { + m_cursor.update(dt); + for (auto p : m_rightAnchoredButtons) p.first->setPosition(Vec2I(m_guiContext->windowWidth() / m_guiContext->interfaceScale(), 0) + p.second); m_mainMenu->determineSizeFromChildren(); - m_skyBackdrop->update(); - m_environmentPainter->update(); + m_skyBackdrop->update(dt); + m_environmentPainter->update(dt); - m_paneManager.update(); + m_paneManager.update(dt); if (!finishedState()) { if (auto audioSample = m_musicTrackManager.updateAmbient(m_musicTrack, m_skyBackdrop->isDayTime())) { @@ -423,7 +425,6 @@ void TitleScreen::back() { void TitleScreen::renderCursor() { auto assets = Root::singleton().assets(); - m_cursor.update(WorldTimestep); Vec2I cursorPos = m_cursorScreenPos; Vec2I cursorSize = m_cursor.size(); Vec2I cursorOffset = m_cursor.offset(); diff --git a/source/frontend/StarTitleScreen.hpp b/source/frontend/StarTitleScreen.hpp index 5ce000d..87ce0c8 100644 --- a/source/frontend/StarTitleScreen.hpp +++ b/source/frontend/StarTitleScreen.hpp @@ -47,7 +47,7 @@ public: void render(); bool handleInputEvent(InputEvent const& event); - void update(); + void update(float dt); bool textInputActive() const; diff --git a/source/frontend/StarVoice.cpp b/source/frontend/StarVoice.cpp index 82205bd..d72bc57 100644 --- a/source/frontend/StarVoice.cpp +++ b/source/frontend/StarVoice.cpp @@ -420,7 +420,7 @@ void Voice::mix(int16_t* buffer, size_t frameCount, unsigned channels) { } } -void Voice::update(PositionalAttenuationFunction positionalAttenuationFunction) { +void Voice::update(float dt, PositionalAttenuationFunction positionalAttenuationFunction) { for (auto& entry : m_speakers) { if (SpeakerPtr& speaker = entry.second) { if (positionalAttenuationFunction) { diff --git a/source/frontend/StarVoice.hpp b/source/frontend/StarVoice.hpp index 95046af..f776cb7 100644 --- a/source/frontend/StarVoice.hpp +++ b/source/frontend/StarVoice.hpp @@ -136,7 +136,7 @@ public: void mix(int16_t* buffer, size_t frames, unsigned channels); typedef function PositionalAttenuationFunction; - void update(PositionalAttenuationFunction positionalAttenuationFunction = {}); + void update(float dt, PositionalAttenuationFunction positionalAttenuationFunction = {}); void setDeviceName(Maybe device); StringList availableDevices(); diff --git a/source/frontend/StarWireInterface.cpp b/source/frontend/StarWireInterface.cpp index 1cec9e8..61506fe 100644 --- a/source/frontend/StarWireInterface.cpp +++ b/source/frontend/StarWireInterface.cpp @@ -35,7 +35,7 @@ void WirePane::reset() { m_connecting = false; } -void WirePane::update() { +void WirePane::update(float dt) { if (!active()) return; if (!m_worldClient->inWorld()) { diff --git a/source/frontend/StarWireInterface.hpp b/source/frontend/StarWireInterface.hpp index 6c124a7..f1c44d2 100644 --- a/source/frontend/StarWireInterface.hpp +++ b/source/frontend/StarWireInterface.hpp @@ -16,7 +16,7 @@ public: WirePane(WorldClientPtr worldClient, PlayerPtr player, WorldPainterPtr worldPainter); virtual ~WirePane() {} - virtual void update() override; + virtual void update(float dt) override; virtual bool sendEvent(InputEvent const& event) override; virtual SwingResult swing(WorldGeometry const& geometry, Vec2F position, FireMode mode) override; diff --git a/source/game/StarActorMovementController.cpp b/source/game/StarActorMovementController.cpp index 9dc9ef8..4f574c4 100644 --- a/source/game/StarActorMovementController.cpp +++ b/source/game/StarActorMovementController.cpp @@ -720,7 +720,7 @@ void ActorMovementController::clearControls() { m_controlModifiers = ActorMovementModifiers(); } -void ActorMovementController::tickMaster() { +void ActorMovementController::tickMaster(float dt) { EntityAnchorConstPtr newAnchor; if (auto anchorState = m_anchorState.get()) { if (auto anchorableEntity = as(world()->entity(anchorState->entityId))) @@ -743,8 +743,8 @@ void ActorMovementController::tickMaster() { m_groundMovement.set(false); m_liquidMovement.set(false); - setVelocity((m_entityAnchor->position - MovementController::position()) / WorldTimestep); - MovementController::tickMaster(); + setVelocity((m_entityAnchor->position - MovementController::position()) / dt); + MovementController::tickMaster(dt); setPosition(m_entityAnchor->position); } else { auto activeParameters = m_baseParameters.merge(m_controlParameters); @@ -775,7 +775,7 @@ void ActorMovementController::tickMaster() { if (appliedForceRegion()) { m_pathController->reset(); } else if (!m_pathController->pathfinding()) { - m_pathMoveResult = m_pathController->move(*this, activeParameters, activeModifiers, m_controlPathMove->second, WorldTimestep) + m_pathMoveResult = m_pathController->move(*this, activeParameters, activeModifiers, m_controlPathMove->second, dt) .apply([this](bool result) { return pair(m_controlPathMove->first, result); }); auto action = m_pathController->curAction(); @@ -811,7 +811,7 @@ void ActorMovementController::tickMaster() { // MovementController still handles updating liquid percentage and updating force regions updateLiquidPercentage(); - updateForceRegions(); + updateForceRegions(dt); // onGround flag needs to be manually set, won't be set by MovementController::tickMaster setOnGround(onGround); clearControls(); @@ -894,7 +894,7 @@ void ActorMovementController::tickMaster() { float minGroundSustain = *activeParameters.groundMovementMinimumSustain; float maxGroundSustain = *activeParameters.groundMovementMaximumSustain; float groundCheckDistance = *activeParameters.groundMovementCheckDistance; - m_groundMovementSustainTimer.tick(); + m_groundMovementSustainTimer.tick(dt); if (onGround()) { m_groundMovementSustainTimer = GameTimer(maxGroundSustain); } else if (!m_groundMovementSustainTimer.ready() && groundCheckDistance > 0.0f && maxGroundSustain - m_groundMovementSustainTimer.timer > minGroundSustain) { @@ -933,15 +933,15 @@ void ActorMovementController::tickMaster() { m_groundMovementSustainTimer = GameTimer(0); } else if (holdJump) { - m_reJumpTimer.tick(); + m_reJumpTimer.tick(dt); if (m_jumpHoldTimer) - m_jumpHoldTimer->tick(); + m_jumpHoldTimer->tick(dt); approachYVelocity(*jumpProfile.jumpSpeed * jumpModifier, *jumpProfile.jumpControlForce * jumpModifier); } else { m_jumping.set(false); - m_reJumpTimer.tick(); + m_reJumpTimer.tick(dt); } if (m_controlMove == Direction::Left) { @@ -1003,7 +1003,7 @@ void ActorMovementController::tickMaster() { bool falling = (yVelocity() < *activeParameters.fallStatusSpeedMin) && !m_groundMovement.get(); m_falling.set(falling); - MovementController::tickMaster(); + MovementController::tickMaster(dt); m_lastControlJump = m_controlJump; m_lastControlDown = m_controlDown; @@ -1017,8 +1017,8 @@ void ActorMovementController::tickMaster() { clearControls(); } -void ActorMovementController::tickSlave() { - MovementController::tickSlave(); +void ActorMovementController::tickSlave(float dt) { + MovementController::tickSlave(dt); m_entityAnchor.reset(); if (auto anchorState = m_anchorState.get()) { @@ -1309,7 +1309,7 @@ Maybe PathController::move(ActorMovementController& movementController, Ac float angleFactor = movementController.velocity().normalized() * delta.normalized(); float speedAlongAngle = angleFactor * movementController.velocity().magnitude(); auto acc = parameters.airForce.value(0.0) / movementController.mass(); - sourceVelocity = delta.normalized() * fmin(parameters.flySpeed.value(0.0), speedAlongAngle + acc * WorldTimestep); + sourceVelocity = delta.normalized() * fmin(parameters.flySpeed.value(0.0), speedAlongAngle + acc * dt); targetVelocity = sourceVelocity; } break; diff --git a/source/game/StarActorMovementController.hpp b/source/game/StarActorMovementController.hpp index 38cc6a0..79ba426 100644 --- a/source/game/StarActorMovementController.hpp +++ b/source/game/StarActorMovementController.hpp @@ -245,11 +245,11 @@ public: // Clears all control data. void clearControls(); - // Integrates the ActorMovementController one WorldTimestep and applies all + // Integrates the ActorMovementController and applies all // the control data and clears it for the next step. - void tickMaster(); + void tickMaster(float dt); - void tickSlave(); + void tickSlave(float dt); private: diff --git a/source/game/StarDamageManager.cpp b/source/game/StarDamageManager.cpp index eaaa82a..8c95a4f 100644 --- a/source/game/StarDamageManager.cpp +++ b/source/game/StarDamageManager.cpp @@ -58,7 +58,7 @@ DataStream& operator>>(DataStream& ds, RemoteDamageNotification& damageNotificat DamageManager::DamageManager(World* world, ConnectionId connectionId) : m_world(world), m_connectionId(connectionId) {} -void DamageManager::update() { +void DamageManager::update(float dt) { float const DefaultDamageTimeout = 1.0f; auto damageIt = makeSMutableMapIterator(m_recentEntityDamages); @@ -67,7 +67,7 @@ void DamageManager::update() { auto eventIt = makeSMutableIterator(events); while (eventIt.hasNext()) { auto& event = eventIt.next(); - event.timeout -= WorldTimestep; + event.timeout -= dt; auto entityIdTimeoutGroup = event.timeoutGroup.maybe(); if (event.timeout <= 0.0f || (entityIdTimeoutGroup && !m_world->entity(*entityIdTimeoutGroup))) eventIt.remove(); diff --git a/source/game/StarDamageManager.hpp b/source/game/StarDamageManager.hpp index 71fb932..0488657 100644 --- a/source/game/StarDamageManager.hpp +++ b/source/game/StarDamageManager.hpp @@ -48,7 +48,7 @@ public: // Notify entities that they have caused damage, apply damage to master // entities, produce damage notifications, and run down damage timeouts. - void update(); + void update(float dt); // Incoming RemoteHitRequest and RemoteDamageRequest must have the // destinationConnection equal to the DamageManager's connectionId diff --git a/source/game/StarEffectEmitter.cpp b/source/game/StarEffectEmitter.cpp index 0712a06..1443172 100644 --- a/source/game/StarEffectEmitter.cpp +++ b/source/game/StarEffectEmitter.cpp @@ -30,7 +30,7 @@ void EffectEmitter::setBaseVelocity(Vec2F const& velocity) { m_baseVelocity = velocity; } -void EffectEmitter::tick(EntityMode mode) { +void EffectEmitter::tick(float dt, EntityMode mode) { if (mode == EntityMode::Master) { m_activeSources.set(move(m_newSources)); m_newSources.clear(); @@ -42,7 +42,7 @@ void EffectEmitter::tick(EntityMode mode) { eraseWhere(m_sources, [](EffectSourcePtr const& source) { return source->expired(); }); for (auto& ps : m_sources) - ps->tick(); + ps->tick(dt); Set> current; for (auto& ps : m_sources) { diff --git a/source/game/StarEffectEmitter.hpp b/source/game/StarEffectEmitter.hpp index 5daf809..e457720 100644 --- a/source/game/StarEffectEmitter.hpp +++ b/source/game/StarEffectEmitter.hpp @@ -19,7 +19,7 @@ public: void setDirection(Direction direction); void setBaseVelocity(Vec2F const& velocity); - void tick(EntityMode mode); + void tick(float dt, EntityMode mode); void reset(); void render(RenderCallback* renderCallback); diff --git a/source/game/StarEffectSourceDatabase.cpp b/source/game/StarEffectSourceDatabase.cpp index 5ef83de..fe65a2a 100644 --- a/source/game/StarEffectSourceDatabase.cpp +++ b/source/game/StarEffectSourceDatabase.cpp @@ -72,8 +72,8 @@ void EffectSource::stop() { m_stop = true; } -void EffectSource::tick() { - m_timer -= WorldTimestep; +void EffectSource::tick(float dt) { + m_timer -= dt; if ((m_timer <= 0) && m_loops) { m_timer = m_loopDuration + m_durationVariance * Random::randf(-0.5f, 0.5f); m_loopTick = true; diff --git a/source/game/StarEffectSourceDatabase.hpp b/source/game/StarEffectSourceDatabase.hpp index 57e1b20..874471e 100644 --- a/source/game/StarEffectSourceDatabase.hpp +++ b/source/game/StarEffectSourceDatabase.hpp @@ -17,7 +17,7 @@ class EffectSource { public: EffectSource(String const& kind, String suggestedSpawnLocation, Json const& definition); String const& kind() const; - void tick(); + void tick(float dt); bool expired() const; void stop(); List particles(); diff --git a/source/game/StarGameTypes.cpp b/source/game/StarGameTypes.cpp index e1069d5..584d3c3 100644 --- a/source/game/StarGameTypes.cpp +++ b/source/game/StarGameTypes.cpp @@ -2,9 +2,8 @@ namespace Star { +float GlobalTimescale = 1.0f; float WorldTimestep = 1.0f / 60.0f; - -// This is used to correct interpolation. It must match the timestep of the server you are connected to. float ServerWorldTimestep = 1.0f / 60.0f; EnumMap const DirectionNames{ diff --git a/source/game/StarGameTypes.hpp b/source/game/StarGameTypes.hpp index ab8dd63..c8ec287 100644 --- a/source/game/StarGameTypes.hpp +++ b/source/game/StarGameTypes.hpp @@ -93,6 +93,7 @@ extern EnumMap const RarityNames; // distance (one tile). unsigned const TilePixels = 8; +extern float GlobalTimescale; extern float WorldTimestep; extern float ServerWorldTimestep; float const SystemWorldTimestep = 1.0f / 20.0f; diff --git a/source/game/StarItemDrop.cpp b/source/game/StarItemDrop.cpp index 8bc0e56..15ca927 100644 --- a/source/game/StarItemDrop.cpp +++ b/source/game/StarItemDrop.cpp @@ -176,7 +176,7 @@ RectF ItemDrop::collisionArea() const { return m_boundBox; } -void ItemDrop::update(uint64_t) { +void ItemDrop::update(float dt, uint64_t) { if (isMaster()) { if (m_owningEntity.get() != NullEntityId) { auto owningEntity = world()->entity(m_owningEntity.get()); @@ -228,9 +228,9 @@ void ItemDrop::update(uint64_t) { m_movementController.applyParameters(parameters); } - m_movementController.tickMaster(); + m_movementController.tickMaster(dt); - m_intangibleTimer.tick(WorldTimestep); + m_intangibleTimer.tick(dt); m_dropAge.update(world()->epochTime()); m_ageItemsTimer.update(world()->epochTime()); @@ -252,7 +252,7 @@ void ItemDrop::update(uint64_t) { } else { m_netGroup.tickNetInterpolation(WorldTimestep); Root::singleton().itemDatabase()->loadItem(m_itemDescriptor.get(), m_item); - m_movementController.tickSlave(); + m_movementController.tickSlave(dt); } } diff --git a/source/game/StarItemDrop.hpp b/source/game/StarItemDrop.hpp index f5fbb5b..035a07d 100644 --- a/source/game/StarItemDrop.hpp +++ b/source/game/StarItemDrop.hpp @@ -52,7 +52,7 @@ public: RectF collisionArea() const override; - void update(uint64_t currentStep) override; + void update(float dt, uint64_t currentStep) override; bool shouldDestroy() const override; diff --git a/source/game/StarMonster.cpp b/source/game/StarMonster.cpp index 59084dd..9d5bc7a 100644 --- a/source/game/StarMonster.cpp +++ b/source/game/StarMonster.cpp @@ -441,41 +441,43 @@ void Monster::damagedOther(DamageNotification const& damage) { m_statusController->damagedOther(damage); } -void Monster::update(uint64_t) { +void Monster::update(float dt, uint64_t) { if (!inWorld()) return; + m_movementController->setTimestep(dt); + if (isMaster()) { m_networkedAnimator.setFlipped((m_movementController->facingDirection() == Direction::Left) != m_monsterVariant.reversed); if (m_knockedOut) { - m_knockoutTimer -= WorldTimestep; + m_knockoutTimer -= dt; } else { if (m_scriptComponent.updateReady()) m_physicsForces.set({}); - m_scriptComponent.update(m_scriptComponent.updateDt()); + m_scriptComponent.update(m_scriptComponent.updateDt(dt)); if (shouldDie()) knockout(); } - m_movementController->tickMaster(); + m_movementController->tickMaster(dt); - m_statusController->tickMaster(); - updateStatus(); + m_statusController->tickMaster(dt); + updateStatus(dt); } else { m_netGroup.tickNetInterpolation(WorldTimestep); - m_statusController->tickSlave(); - updateStatus(); + m_statusController->tickSlave(dt); + updateStatus(dt); - m_movementController->tickSlave(); + m_movementController->tickSlave(dt); } if (world()->isServer()) { - m_networkedAnimator.update(WorldTimestep, nullptr); + m_networkedAnimator.update(dt, nullptr); } else { - m_networkedAnimator.update(WorldTimestep, &m_networkedAnimatorDynamicTarget); + m_networkedAnimator.update(dt, &m_networkedAnimatorDynamicTarget); m_networkedAnimatorDynamicTarget.updatePosition(position()); m_scriptedAnimator.update(); @@ -543,12 +545,12 @@ Vec2F Monster::getAbsolutePosition(Vec2F relativePosition) const { return m_movementController->position() + relativePosition; } -void Monster::updateStatus() { +void Monster::updateStatus(float dt) { m_effectEmitter.setSourcePosition("normal", position()); m_effectEmitter.setSourcePosition("mouth", position() + mouthOffset()); m_effectEmitter.setSourcePosition("feet", position() + feetOffset()); m_effectEmitter.setDirection(m_movementController->facingDirection()); - m_effectEmitter.tick(*entityMode()); + m_effectEmitter.tick(dt, *entityMode()); } LuaCallbacks Monster::makeMonsterCallbacks() { diff --git a/source/game/StarMonster.hpp b/source/game/StarMonster.hpp index 06ca26e..807197e 100644 --- a/source/game/StarMonster.hpp +++ b/source/game/StarMonster.hpp @@ -88,7 +88,7 @@ public: bool shouldDestroy() const override; void destroy(RenderCallback* renderCallback) override; - void update(uint64_t currentStep) override; + void update(float dt, uint64_t currentStep) override; void render(RenderCallback* renderCallback) override; @@ -137,7 +137,7 @@ public: private: Vec2F getAbsolutePosition(Vec2F relativePosition) const; - void updateStatus(); + void updateStatus(float dt); LuaCallbacks makeMonsterCallbacks(); void addChatMessage(String const& message, String const& portrait = ""); diff --git a/source/game/StarMovementController.cpp b/source/game/StarMovementController.cpp index 9f2d66c..facf3c5 100644 --- a/source/game/StarMovementController.cpp +++ b/source/game/StarMovementController.cpp @@ -169,7 +169,9 @@ DataStream& operator<<(DataStream& ds, MovementParameters const& movementParamet MovementController::MovementController(MovementParameters const& parameters) { m_resting = false; - + + m_timeStep = WorldTimestep; + m_liquidPercentage = 0.0f; m_liquidId = EmptyLiquidId; @@ -392,15 +394,15 @@ void MovementController::rotate(float rotationRate) { return; m_resting = false; - m_rotation.set(fmod(rotation() + rotationRate * WorldTimestep, 2 * Constants::pi)); + m_rotation.set(fmod(rotation() + rotationRate * m_timeStep, 2 * Constants::pi)); } void MovementController::accelerate(Vec2F const& acceleration) { - setVelocity(velocity() + acceleration * WorldTimestep); + setVelocity(velocity() + acceleration * m_timeStep); } void MovementController::force(Vec2F const& force) { - setVelocity(velocity() + force / mass() * WorldTimestep); + setVelocity(velocity() + force / mass() * m_timeStep); } void MovementController::approachVelocity(Vec2F const& targetVelocity, float maxControlForce) { @@ -414,7 +416,7 @@ void MovementController::approachVelocity(Vec2F const& targetVelocity, float max if (diffMagnitude == 0.0f) return; - float maximumAcceleration = maxControlForce / mass() * WorldTimestep; + float maximumAcceleration = maxControlForce / mass() * m_timeStep; float clampedMagnitude = clamp(diffMagnitude, 0.0f, maximumAcceleration); setVelocity(velocity() + diff * (clampedMagnitude / diffMagnitude)); @@ -437,7 +439,7 @@ void MovementController::approachVelocityAlongAngle(float angle, float targetVel if (positiveOnly && diff < 0) return; - float maximumAcceleration = maxControlForce / mass() * WorldTimestep; + float maximumAcceleration = maxControlForce / mass() * m_timeStep; float diffMagnitude = std::fabs(diff); float clampedMagnitude = clamp(diffMagnitude, 0.0f, maximumAcceleration); @@ -464,7 +466,12 @@ void MovementController::uninit() { updatePositionInterpolators(); } -void MovementController::tickMaster() { +void MovementController::setTimestep(float dt) { + m_timeStep = dt; +} + +void MovementController::tickMaster(float dt) { + setTimestep(dt); auto geometry = world()->geometry(); m_zeroG.set(!*m_parameters.gravityEnabled || *m_parameters.gravityMultiplier == 0 || world()->gravity(position()) == 0); @@ -478,7 +485,7 @@ void MovementController::tickMaster() { if (surfaceCollision) { Vec2F surfacePositionDelta = geometry.diff(surfaceCollision->position, m_surfaceMovingCollisionPosition); setPosition(position() + surfacePositionDelta); - Vec2F newSurfaceVelocity = surfacePositionDelta / WorldTimestep; + Vec2F newSurfaceVelocity = surfacePositionDelta / dt; setVelocity(velocity() - m_surfaceVelocity + newSurfaceVelocity); m_surfaceVelocity = newSurfaceVelocity; } else { @@ -496,7 +503,7 @@ void MovementController::tickMaster() { // don't integrate velocity when resting Vec2F relativeVelocity = m_resting ? Vec2F() : velocity(); - Vec2F originalMovement = relativeVelocity * WorldTimestep; + Vec2F originalMovement = relativeVelocity * dt; if (surfaceCollision) relativeVelocity -= m_surfaceVelocity; @@ -507,7 +514,7 @@ void MovementController::tickMaster() { unsigned steps; float maxMovementPerStep = *m_parameters.maxMovementPerStep; if (maxMovementPerStep > 0.0f) - steps = std::floor(vmag(relativeVelocity) * WorldTimestep / maxMovementPerStep) + 1; + steps = std::floor(vmag(relativeVelocity) * dt / maxMovementPerStep) + 1; else steps = 1; @@ -516,8 +523,8 @@ void MovementController::tickMaster() { steps = 0; for (unsigned i = 0; i < steps; ++i) { - float dt = WorldTimestep / steps; - Vec2F movement = relativeVelocity * dt; + float dtSteps = dt / steps; + Vec2F movement = relativeVelocity * dtSteps; if (!*m_parameters.collisionEnabled || collisionPoly().isNull()) { setPosition(position() + movement); @@ -546,7 +553,7 @@ void MovementController::tickMaster() { queryBounds.combine(queryBounds.translated(movement)); queryCollisions(queryBounds); auto result = collisionMove(m_workingCollisions, body, movement, ignorePlatforms, *m_parameters.enableSurfaceSlopeCorrection && !zeroG(), - maximumCorrection, maximumPlatformCorrection, bodyCenter); + maximumCorrection, maximumPlatformCorrection, bodyCenter, dtSteps); setPosition(position() + result.movement); @@ -572,7 +579,7 @@ void MovementController::tickMaster() { if (*m_parameters.stickyCollision && result.collisionKind != CollisionKind::Slippery) { // When sticking, cancel all velocity and apply stickyForce in the // opposite of the direction of collision correction. - relativeVelocity = -normCorrection * *m_parameters.stickyForce / mass() * dt; + relativeVelocity = -normCorrection * *m_parameters.stickyForce / mass() * dtSteps; m_stickingDirection.set(-normCorrection.angle()); break; } else { @@ -597,14 +604,14 @@ void MovementController::tickMaster() { // independently). if (relativeVelocity[0] < 0 && correction[0] > 0) - relativeVelocity[0] = min(0.0f, relativeVelocity[0] + correction[0] / WorldTimestep); + relativeVelocity[0] = min(0.0f, relativeVelocity[0] + correction[0] / dt); else if (relativeVelocity[0] > 0 && correction[0] < 0) - relativeVelocity[0] = max(0.0f, relativeVelocity[0] + correction[0] / WorldTimestep); + relativeVelocity[0] = max(0.0f, relativeVelocity[0] + correction[0] / dt); if (relativeVelocity[1] < 0 && correction[1] > 0) - relativeVelocity[1] = min(0.0f, relativeVelocity[1] + correction[1] / WorldTimestep); + relativeVelocity[1] = min(0.0f, relativeVelocity[1] + correction[1] / dt); else if (relativeVelocity[1] > 0 && correction[1] < 0) - relativeVelocity[1] = max(0.0f, relativeVelocity[1] + correction[1] / WorldTimestep); + relativeVelocity[1] = max(0.0f, relativeVelocity[1] + correction[1] / dt); } } } @@ -641,7 +648,7 @@ void MovementController::tickMaster() { float buoyancy = *m_parameters.liquidBuoyancy * m_liquidPercentage + *m_parameters.airBuoyancy * (1.0f - liquidPercentage()); float gravity = world()->gravity(position()) * *m_parameters.gravityMultiplier * (1.0f - buoyancy); Vec2F environmentVelocity; - environmentVelocity[1] -= gravity * WorldTimestep; + environmentVelocity[1] -= gravity * dt; if (onGround() && *m_parameters.slopeSlidingFactor != 0 && m_surfaceSlope[1] != 0) environmentVelocity += -m_surfaceSlope * (m_surfaceSlope[0] * m_surfaceSlope[1]) * *m_parameters.slopeSlidingFactor; @@ -673,16 +680,17 @@ void MovementController::tickMaster() { // but it is applied here as a multiplicitave factor from [0, 1] so it does // not induce oscillation at very high friction and so it cannot be // negative. - float frictionFactor = clamp(friction / mass() * WorldTimestep, 0.0f, 1.0f); + float frictionFactor = clamp(friction / mass() * dt, 0.0f, 1.0f); newVelocity = lerp(frictionFactor, newVelocity, refVel); } setVelocity(newVelocity); - updateForceRegions(); + updateForceRegions(dt); } -void MovementController::tickSlave() { +void MovementController::tickSlave(float dt) { + setTimestep(dt); if (auto movingCollisionId = m_surfaceMovingCollision.get()) { if (auto physicsEntity = world()->get(movingCollisionId->physicsEntityId)) { if (auto collision = physicsEntity->movingCollision(movingCollisionId->collisionIndex)) { @@ -724,7 +732,7 @@ void MovementController::forEachMovingCollision(RectF const& region, functiongeometry(); auto pos = position(); auto body = collisionBody(); @@ -841,11 +849,12 @@ CollisionKind MovementController::maxOrNullCollision(CollisionKind a, CollisionK } MovementController::CollisionResult MovementController::collisionMove(List& collisionPolys, PolyF const& body, Vec2F const& movement, - bool ignorePlatforms, bool enableSurfaceSlopeCorrection, float maximumCorrection, float maximumPlatformCorrection, Vec2F sortCenter) { + bool ignorePlatforms, bool enableSurfaceSlopeCorrection, float maximumCorrection, float maximumPlatformCorrection, Vec2F sortCenter, float dt) { unsigned const MaximumSeparationLoops = 3; float const SlideAngle = Constants::pi / 3; float const SlideCorrectionLimit = 0.2f; - float const SeparationTolerance = 0.001f; + float separationTolerance = 0.001f * (dt * 60.f); + maximumPlatformCorrection *= (dt * 60.f); if (body.isNull()) return {movement, Vec2F(), {}, false, false, Vec2F(1, 0), CollisionKind::None}; @@ -861,7 +870,7 @@ MovementController::CollisionResult MovementController::collisionMove(List SeparationTolerance; + result.onGround = result.correction[1] > separationTolerance; result.surfaceMovingCollisionId = surfaceMovingCollisionId; result.collisionKind = maxCollided; result.groundSlope = Vec2F(1, 0); @@ -944,7 +953,7 @@ MovementController::CollisionResult MovementController::collisionMove(List cp.sortPosition[1]) { - if (vmagSquared(bodyVertex - nearPoint) <= square(SeparationTolerance)) { + if (vmagSquared(bodyVertex - nearPoint) <= square(separationTolerance)) { maxSideHorizontalOverlap = thisSideHorizontalOverlap; result.groundSlope = side.diff().normalized(); if (result.groundSlope[0] < 0) @@ -981,8 +990,6 @@ MovementController::CollisionResult MovementController::collisionMove(List& collisionPolys, PolyF const& poly, bool ignorePlatforms, float maximumPlatformCorrection, Vec2F const& sortCenter, bool upward, float separationTolerance) { - maximumPlatformCorrection *= WorldTimestep * 60.0f; - CollisionSeparation separation = {}; separation.collisionKind = CollisionKind::None; bool intersects = false; diff --git a/source/game/StarMovementController.hpp b/source/game/StarMovementController.hpp index a60b0c9..f13e3e5 100644 --- a/source/game/StarMovementController.hpp +++ b/source/game/StarMovementController.hpp @@ -180,13 +180,16 @@ public: void init(World* world); void uninit(); + // Stores dt value for Lua calls. + void setTimestep(float dt); + // Integrates the ActorMovementController one WorldTimestep and applies all // forces. - void tickMaster(); + void tickMaster(float dt); // Does not integrate, only tracks master state and updates non-networked // fields based on local data - void tickSlave(); + void tickSlave(float dt); void setIgnorePhysicsEntities(Set ignorePhysicsEntities); // iterate over all physics entity collision polys in the region, iteration stops if the callback returns false @@ -194,7 +197,7 @@ public: protected: // forces the movement controller onGround status, used when manually controlling movement outside the movement controller - void updateForceRegions(); + void updateForceRegions(float dt); void updateLiquidPercentage(); void setOnGround(bool onGround); @@ -239,7 +242,7 @@ private: static CollisionKind maxOrNullCollision(CollisionKind a, CollisionKind b); static CollisionResult collisionMove(List& collisionPolys, PolyF const& body, Vec2F const& movement, - bool ignorePlatforms, bool enableSurfaceSlopeCorrection, float maximumCorrection, float maximumPlatformCorrection, Vec2F sortCenter); + bool ignorePlatforms, bool enableSurfaceSlopeCorrection, float maximumCorrection, float maximumPlatformCorrection, Vec2F sortCenter, float dt); static CollisionSeparation collisionSeparate(List& collisionPolys, PolyF const& poly, bool ignorePlatforms, float maximumPlatformCorrection, Vec2F const& sortCenter, bool upward, float separationTolerance); @@ -287,6 +290,7 @@ private: bool m_resting; int m_restTicks; + float m_timeStep; List m_workingCollisions; List m_collisionBuffers; diff --git a/source/game/StarNpc.cpp b/source/game/StarNpc.cpp index 1d8a80b..b5fb690 100644 --- a/source/game/StarNpc.cpp +++ b/source/game/StarNpc.cpp @@ -345,12 +345,14 @@ void Npc::damagedOther(DamageNotification const& damage) { m_statusController->damagedOther(damage); } -void Npc::update(uint64_t) { +void Npc::update(float dt, uint64_t) { if (!inWorld()) return; + m_movementController->setTimestep(dt); + if (isMaster()) { - m_scriptComponent.update(m_scriptComponent.updateDt()); + m_scriptComponent.update(m_scriptComponent.updateDt(dt)); if (inConflictingLoungeAnchor()) m_movementController->resetAnchorState(); @@ -385,10 +387,10 @@ void Npc::update(uint64_t) { m_statusController->setPersistentEffects("armor", m_armor->statusEffects()); m_statusController->setPersistentEffects("tools", m_tools->statusEffects()); - m_movementController->tickMaster(); - m_statusController->tickMaster(); + m_movementController->tickMaster(dt); + m_statusController->tickMaster(dt); - tickShared(); + tickShared(dt); if (!is(m_movementController->entityAnchor())) { if (m_movementController->groundMovement()) { @@ -413,9 +415,9 @@ void Npc::update(uint64_t) { } } - if (m_emoteCooldownTimer.tick()) + if (m_emoteCooldownTimer.tick(dt)) m_emoteState = HumanoidEmote::Idle; - if (m_danceCooldownTimer.tick()) + if (m_danceCooldownTimer.tick(dt)) m_dance = {}; if (m_chatMessageUpdated) { @@ -425,7 +427,7 @@ void Npc::update(uint64_t) { m_chatMessageUpdated = false; } - if (m_blinkCooldownTimer.tick()) { + if (m_blinkCooldownTimer.tick(dt)) { m_blinkCooldownTimer = GameTimer(Random::randf(m_blinkInterval[0], m_blinkInterval[1])); if (m_emoteState == HumanoidEmote::Idle) addEmote(HumanoidEmote::Blink); @@ -436,10 +438,10 @@ void Npc::update(uint64_t) { } else { m_netGroup.tickNetInterpolation(WorldTimestep); - m_movementController->tickSlave(); - m_statusController->tickSlave(); + m_movementController->tickSlave(dt); + m_statusController->tickSlave(dt); - tickShared(); + tickShared(dt); } if (world()->isClient()) @@ -534,7 +536,7 @@ Vec2F Npc::getAbsolutePosition(Vec2F relativePosition) const { return m_movementController->position() + relativePosition; } -void Npc::tickShared() { +void Npc::tickShared(float dt) { if (m_hitDamageNotificationLimiter) m_hitDamageNotificationLimiter--; @@ -547,7 +549,7 @@ void Npc::tickShared() { m_effectEmitter->setSourcePosition("backArmor", backArmorOffset() + position()); m_effectEmitter->setDirection(m_humanoid.facingDirection()); - m_effectEmitter->tick(*entityMode()); + m_effectEmitter->tick(dt, *entityMode()); m_humanoid.setMovingBackwards(m_movementController->movingDirection() != m_movementController->facingDirection()); m_humanoid.setFacingDirection(m_movementController->facingDirection()); @@ -575,12 +577,12 @@ void Npc::tickShared() { m_armor->setupHumanoidClothingDrawables(m_humanoid, false); m_tools->suppressItems(!canUseTool()); - m_tools->tick(m_shifting.get(), {}); + m_tools->tick(dt, m_shifting.get(), {}); if (auto overrideDirection = m_tools->setupHumanoidHandItems(m_humanoid, position(), aimPosition())) m_movementController->controlFace(*overrideDirection); - m_humanoid.animate(WorldTimestep); + m_humanoid.animate(dt); } LuaCallbacks Npc::makeNpcCallbacks() { diff --git a/source/game/StarNpc.hpp b/source/game/StarNpc.hpp index 7c6c5a9..b4fc21e 100644 --- a/source/game/StarNpc.hpp +++ b/source/game/StarNpc.hpp @@ -90,7 +90,7 @@ public: bool shouldDestroy() const override; void destroy(RenderCallback* renderCallback) override; - void update(uint64_t currentVersion) override; + void update(float dt, uint64_t currentVersion) override; void render(RenderCallback* renderCallback) override; @@ -177,7 +177,7 @@ public: private: Vec2F getAbsolutePosition(Vec2F relativePosition) const; - void tickShared(); + void tickShared(float dt); LuaCallbacks makeNpcCallbacks(); void setupNetStates(); diff --git a/source/game/StarObject.cpp b/source/game/StarObject.cpp index 1b55ac0..be0000d 100644 --- a/source/game/StarObject.cpp +++ b/source/game/StarObject.cpp @@ -352,12 +352,12 @@ List Object::roots() const { return {}; } -void Object::update(uint64_t) { +void Object::update(float dt, uint64_t) { if (!inWorld()) return; if (isMaster()) { - m_tileDamageStatus->recover(m_config->tileDamageParameters, WorldTimestep); + m_tileDamageStatus->recover(m_config->tileDamageParameters, dt); if (m_liquidCheckTimer.wrapTick()) checkLiquidBroken(); @@ -369,24 +369,24 @@ void Object::update(uint64_t) { setImageKey("frame", toString(frame)); } - m_animationTimer = std::fmod(m_animationTimer + WorldTimestep, orientation->animationCycle); + m_animationTimer = std::fmod(m_animationTimer + dt, orientation->animationCycle); } - m_networkedAnimator->update(WorldTimestep, nullptr); + m_networkedAnimator->update(dt, nullptr); m_networkedAnimator->setFlipped(direction() == Direction::Left, m_animationCenterLine); - m_scriptComponent.update(m_scriptComponent.updateDt()); + m_scriptComponent.update(m_scriptComponent.updateDt(dt)); } else { - m_networkedAnimator->update(WorldTimestep, &m_networkedAnimatorDynamicTarget); + m_networkedAnimator->update(dt, &m_networkedAnimatorDynamicTarget); m_networkedAnimatorDynamicTarget.updatePosition(position() + m_animationPosition); } if (m_lightFlickering) - m_lightFlickering->update(WorldTimestep); + m_lightFlickering->update(dt); for (auto& timer : m_emissionTimers) - timer.tick(); + timer.tick(dt); if (world()->isClient()) m_scriptedAnimator.update(); diff --git a/source/game/StarObject.hpp b/source/game/StarObject.hpp index e45a612..9b59c50 100644 --- a/source/game/StarObject.hpp +++ b/source/game/StarObject.hpp @@ -62,7 +62,7 @@ public: virtual bool shouldDestroy() const override; virtual void destroy(RenderCallback* renderCallback) override; - virtual void update(uint64_t currentStep) override; + virtual void update(float dt, uint64_t currentStep) override; virtual void render(RenderCallback* renderCallback) override; diff --git a/source/game/StarPlant.cpp b/source/game/StarPlant.cpp index 4690722..d0c6efe 100644 --- a/source/game/StarPlant.cpp +++ b/source/game/StarPlant.cpp @@ -718,18 +718,18 @@ float Plant::branchRotation(float xPos, float rotoffset) const { return copysign(0.00117f, m_windLevel) * (std::sin(m_windTime + rotoffset + xPos / 10.0f) * intensity - intensity / 300.0f); } -void Plant::update(uint64_t) { - m_windTime += WorldTimestep; +void Plant::update(float dt, uint64_t) { + m_windTime += dt; m_windTime = std::fmod(m_windTime, 628.32f); m_windLevel = world()->windLevel(Vec2F(m_tilePosition)); if (isMaster()) { if (m_tileDamageStatus.damaged()) - m_tileDamageStatus.recover(m_tileDamageParameters, WorldTimestep); + m_tileDamageStatus.recover(m_tileDamageParameters, dt); } else { if (m_tileDamageStatus.damaged() && !m_tileDamageStatus.damageProtected()) { float damageEffectPercentage = m_tileDamageStatus.damageEffectPercentage(); - m_windTime += damageEffectPercentage * 10 * WorldTimestep; + m_windTime += damageEffectPercentage * 10 * dt; m_windLevel += damageEffectPercentage * 20; } diff --git a/source/game/StarPlant.hpp b/source/game/StarPlant.hpp index 046610f..f0938c9 100644 --- a/source/game/StarPlant.hpp +++ b/source/game/StarPlant.hpp @@ -96,7 +96,7 @@ public: // Root blocks for this plant. List roots() const override; - void update(uint64_t currentStep) override; + void update(float dt, uint64_t currentStep) override; void render(RenderCallback* renderCallback) override; diff --git a/source/game/StarPlantDrop.cpp b/source/game/StarPlantDrop.cpp index 1fc085f..2ca16a0 100644 --- a/source/game/StarPlantDrop.cpp +++ b/source/game/StarPlantDrop.cpp @@ -176,9 +176,10 @@ RectF PlantDrop::collisionRect() const { return shape.boundBox(); } -void PlantDrop::update(uint64_t) { - m_time -= WorldTimestep; +void PlantDrop::update(float dt, uint64_t) { + m_time -= dt; + m_movementController.setTimestep(dt); if (isMaster()) { if (m_spawnedDropEffects && !m_spawnedDrops.get()) m_spawnedDropEffects = false; // false positive assumption over already having done the effect @@ -187,7 +188,7 @@ void PlantDrop::update(uint64_t) { m_firstTick = false; // think up a better curve then sin - auto rotationAcceleration = 0.01f * world()->gravity(position()) * copysign(1.0f, m_rotationRate) * WorldTimestep; + auto rotationAcceleration = 0.01f * world()->gravity(position()) * copysign(1.0f, m_rotationRate) * dt; if (abs(m_movementController.rotation()) > m_rotationCap) m_rotationRate -= rotationAcceleration; else if (std::fabs(m_movementController.rotation()) < m_rotationFallThreshold) @@ -203,7 +204,7 @@ void PlantDrop::update(uint64_t) { parameters.gravityEnabled = std::fabs(m_movementController.rotation()) >= m_rotationFallThreshold; m_movementController.applyParameters(parameters); - m_movementController.tickMaster(); + m_movementController.tickMaster(dt); if (m_movementController.onGround()) m_time = 0; } @@ -243,7 +244,7 @@ void PlantDrop::update(uint64_t) { if (m_spawnedDrops.get()) m_firstTick = false; - m_movementController.tickSlave(); + m_movementController.tickSlave(dt); } } diff --git a/source/game/StarPlantDrop.hpp b/source/game/StarPlantDrop.hpp index a11b732..d01e1bb 100644 --- a/source/game/StarPlantDrop.hpp +++ b/source/game/StarPlantDrop.hpp @@ -44,7 +44,7 @@ public: RectF collisionRect() const; - void update(uint64_t currentStep) override; + void update(float dt, uint64_t currentStep) override; void render(RenderCallback* renderCallback) override; diff --git a/source/game/StarPlayer.cpp b/source/game/StarPlayer.cpp index 2fa98df..54af56f 100644 --- a/source/game/StarPlayer.cpp +++ b/source/game/StarPlayer.cpp @@ -153,6 +153,7 @@ Player::Player(PlayerConfigPtr config, Uuid uuid) { m_statusController->resetAllResources(); m_landingNoisePending = false; + m_footstepPending = false; setKeepAlive(true); @@ -776,10 +777,12 @@ Maybe Player::receiveMessage(ConnectionId fromConnection, String const& me return {}; } -void Player::update(uint64_t) { +void Player::update(float dt, uint64_t) { + m_movementController->setTimestep(dt); + if (isMaster()) { if (m_emoteCooldownTimer) { - m_emoteCooldownTimer -= WorldTimestep; + m_emoteCooldownTimer -= dt; if (m_emoteCooldownTimer <= 0) { m_emoteCooldownTimer = 0; m_emoteState = HumanoidEmote::Idle; @@ -793,7 +796,7 @@ void Player::update(uint64_t) { m_chatMessageUpdated = false; } - m_blinkCooldownTimer -= WorldTimestep; + m_blinkCooldownTimer -= dt; if (m_blinkCooldownTimer <= 0) { m_blinkCooldownTimer = Random::randf(m_blinkInterval[0], m_blinkInterval[1]); auto loungeAnchor = as(m_movementController->entityAnchor()); @@ -801,13 +804,13 @@ void Player::update(uint64_t) { addEmote(HumanoidEmote::Blink); } - m_lastDamagedOtherTimer += WorldTimestep; + m_lastDamagedOtherTimer += dt; if (m_movementController->zeroG()) m_movementController->controlParameters(m_zeroGMovementParameters); if (isTeleporting()) { - m_teleportTimer -= WorldTimestep; + m_teleportTimer -= dt; if (m_teleportTimer <= 0 && m_state == State::TeleportIn) { m_state = State::Idle; m_effectsAnimator->burstParticleEmitter(m_teleportAnimationType + "Burst"); @@ -817,9 +820,9 @@ void Player::update(uint64_t) { if (!isTeleporting()) { processControls(); - m_questManager->update(); - m_companions->update(); - m_deployment->update(); + m_questManager->update(dt); + m_companions->update(dt); + m_deployment->update(dt); bool edgeTriggeredUse = take(m_edgeTriggeredUse); @@ -871,12 +874,12 @@ void Player::update(uint64_t) { m_tools->effects(*m_effectEmitter); - m_movementController->tickMaster(); + m_movementController->tickMaster(dt); - m_techController->tickMaster(); + m_techController->tickMaster(dt); for (auto& p : m_genericScriptContexts) - p.second->update(WorldTimestep * p.second->updateDelta()); + p.second->update(p.second->updateDt(dt)); if (edgeTriggeredUse) { auto anchor = as(m_movementController->entityAnchor()); @@ -896,7 +899,7 @@ void Player::update(uint64_t) { m_techController->setLoadedTech(m_techs->equippedTechs().values()); if (!isDead()) - m_statusController->tickMaster(); + m_statusController->tickMaster(dt); if (!modeConfig().hunger) m_statusController->resetResource("food"); @@ -909,7 +912,7 @@ void Player::update(uint64_t) { m_statusController->setPersistentEffects("hunger", {}); for (auto& pair : m_delayedRadioMessages) { - if (pair.first.tick()) + if (pair.first.tick(dt)) queueRadioMessage(pair.second); } m_delayedRadioMessages.filter([](pair& pair) { return !pair.first.ready(); }); @@ -924,7 +927,7 @@ void Player::update(uint64_t) { m_log->addPlayTime(WorldTimestep); - if (m_ageItemsTimer.wrapTick(WorldTimestep)) { + if (m_ageItemsTimer.wrapTick(dt)) { auto itemDatabase = Root::singleton().itemDatabase(); m_inventory->forEveryItem([&](InventorySlot const&, ItemPtr& item) { itemDatabase->ageItem(item, m_ageItemsTimer.time); @@ -948,9 +951,9 @@ void Player::update(uint64_t) { } else { m_netGroup.tickNetInterpolation(WorldTimestep); - m_movementController->tickSlave(); - m_techController->tickSlave(); - m_statusController->tickSlave(); + m_movementController->tickSlave(dt); + m_techController->tickSlave(dt); + m_statusController->tickSlave(dt); } m_humanoid->setMovingBackwards(false); @@ -967,7 +970,7 @@ void Player::update(uint64_t) { m_armor->setupHumanoidClothingDrawables(*m_humanoid, forceNude()); m_tools->suppressItems(!canUseTool()); - m_tools->tick(m_shifting, m_pendingMoves); + m_tools->tick(dt, m_shifting, m_pendingMoves); if (auto overrideFacingDirection = m_tools->setupHumanoidHandItems(*m_humanoid, position(), aimPosition())) m_movementController->controlFace(*overrideFacingDirection); @@ -976,17 +979,22 @@ void Player::update(uint64_t) { if (m_movementController->facingDirection() == Direction::Left) m_effectsAnimator->scaleTransformationGroup("flip", Vec2F(-1, 1)); - + if (m_state == State::Walk || m_state == State::Run) { + if ((m_footstepTimer += dt) > m_config->footstepTiming) { + m_footstepPending = true; + m_footstepTimer = 0.0; + } + } if (isClient) { - m_effectsAnimator->update(WorldTimestep, &m_effectsAnimatorDynamicTarget); + m_effectsAnimator->update(dt, &m_effectsAnimatorDynamicTarget); m_effectsAnimatorDynamicTarget.updatePosition(position() + m_techController->parentOffset()); } else { - m_effectsAnimator->update(WorldTimestep, nullptr); + m_effectsAnimator->update(dt, nullptr); } if (!isTeleporting()) - processStateChanges(); + processStateChanges(dt); m_damageSources = m_tools->damageSources(); for (auto& damageSource : m_damageSources) { @@ -1009,7 +1017,7 @@ void Player::update(uint64_t) { m_effectEmitter->setDirection(facingDirection()); - m_effectEmitter->tick(*entityMode()); + m_effectEmitter->tick(dt, *entityMode()); m_humanoid->setFacingDirection(m_movementController->facingDirection()); m_humanoid->setMovingBackwards(m_movementController->facingDirection() != m_movementController->movingDirection()); @@ -1049,19 +1057,16 @@ void Player::render(RenderCallback* renderCallback) { renderCallback->addAudio(move(landingNoise)); } - if (m_state == State::Walk || m_state == State::Run) { - m_footstepTimer += WorldTimestep; - if (m_footstepTimer > m_config->footstepTiming) { - auto stepNoise = make_shared(*footstepAudio); - stepNoise->setPosition(position() + feetOffset()); - stepNoise->setVolume(1 - Random::randf(0, m_footstepVolumeVariance)); - renderCallback->addAudio(move(stepNoise)); - m_footstepTimer = 0.0; - } + if (m_footstepPending) { + auto stepNoise = make_shared(*footstepAudio); + stepNoise->setPosition(position() + feetOffset()); + stepNoise->setVolume(1 - Random::randf(0, m_footstepVolumeVariance)); + renderCallback->addAudio(move(stepNoise)); } } else { m_footstepTimer = m_config->footstepTiming; } + m_footstepPending = false; m_landingNoisePending = false; renderCallback->addAudios(m_effectsAnimatorDynamicTarget.pullNewAudios()); @@ -1653,7 +1658,7 @@ void Player::processControls() { stopLounging(); } -void Player::processStateChanges() { +void Player::processStateChanges(float dt) { if (isMaster()) { // Set the current player state based on what movement controller tells us @@ -1713,7 +1718,7 @@ void Player::processStateChanges() { } } - m_humanoid->animate(WorldTimestep); + m_humanoid->animate(dt); if (auto techState = m_techController->parentState()) { if (techState == TechController::ParentState::Stand) { @@ -2260,10 +2265,10 @@ bool Player::invisible() const { return m_statusController->statPositive("invisible"); } -void Player::animatePortrait() { - m_humanoid->animate(WorldTimestep); +void Player::animatePortrait(float dt) { + m_humanoid->animate(dt); if (m_emoteCooldownTimer) { - m_emoteCooldownTimer -= WorldTimestep; + m_emoteCooldownTimer -= dt; if (m_emoteCooldownTimer <= 0) { m_emoteCooldownTimer = 0; m_emoteState = HumanoidEmote::Idle; diff --git a/source/game/StarPlayer.hpp b/source/game/StarPlayer.hpp index d534e03..7bc0a73 100644 --- a/source/game/StarPlayer.hpp +++ b/source/game/StarPlayer.hpp @@ -182,7 +182,7 @@ public: Maybe receiveMessage(ConnectionId sendingConnection, String const& message, JsonArray const& args = {}) override; - void update(uint64_t currentStep) override; + void update(float dt, uint64_t currentStep) override; void render(RenderCallback* renderCallback) override; @@ -404,7 +404,7 @@ public: bool invisible() const; - void animatePortrait(); + void animatePortrait(float dt); bool isOutside(); @@ -494,7 +494,7 @@ private: void processControls(); // state changes and effect animations (master and slave) that happen AFTER movement/tech controller updates - void processStateChanges(); + void processStateChanges(float dt); void getNetStates(bool initial); void setNetStates(); @@ -504,7 +504,7 @@ private: List particles(); String getFootstepSound(Vec2I const& sensor) const; - void tickShared(); + void tickShared(float dt); HumanoidEmote detectEmotes(String const& chatter); @@ -544,6 +544,7 @@ private: float m_footstepVolumeVariance; float m_landingVolume; bool m_landingNoisePending; + bool m_footstepPending; String m_teleportAnimationType; NetworkedAnimatorPtr m_effectsAnimator; diff --git a/source/game/StarPlayerCompanions.cpp b/source/game/StarPlayerCompanions.cpp index ef59ef0..796225e 100644 --- a/source/game/StarPlayerCompanions.cpp +++ b/source/game/StarPlayerCompanions.cpp @@ -114,8 +114,8 @@ Maybe PlayerCompanions::receiveMessage(String const& message, bool localMe return m_scriptComponent.handleMessage(message, localMessage, args); } -void PlayerCompanions::update() { - m_scriptComponent.update(m_scriptComponent.updateDt()); +void PlayerCompanions::update(float dt) { + m_scriptComponent.update(m_scriptComponent.updateDt(dt)); } LuaCallbacks PlayerCompanions::makeCompanionsCallbacks() { diff --git a/source/game/StarPlayerCompanions.hpp b/source/game/StarPlayerCompanions.hpp index 5a52e05..dd1d66d 100644 --- a/source/game/StarPlayerCompanions.hpp +++ b/source/game/StarPlayerCompanions.hpp @@ -48,7 +48,7 @@ public: void dismissCompanion(String const& category, Uuid const& podUuid); Maybe receiveMessage(String const& message, bool localMessage, JsonArray const& args = {}); - void update(); + void update(float dt); private: LuaCallbacks makeCompanionsCallbacks(); diff --git a/source/game/StarPlayerDeployment.cpp b/source/game/StarPlayerDeployment.cpp index 4565074..6b13f87 100644 --- a/source/game/StarPlayerDeployment.cpp +++ b/source/game/StarPlayerDeployment.cpp @@ -80,8 +80,8 @@ Maybe PlayerDeployment::receiveMessage(String const& message, bool localMe return m_scriptComponent.handleMessage(message, localMessage, args); } -void PlayerDeployment::update() { - m_scriptComponent.update(m_scriptComponent.updateDt()); +void PlayerDeployment::update(float dt) { + m_scriptComponent.update(m_scriptComponent.updateDt(dt)); } void PlayerDeployment::render(RenderCallback* renderCallback, Vec2F const& position) { diff --git a/source/game/StarPlayerDeployment.hpp b/source/game/StarPlayerDeployment.hpp index e9c9462..7c0602d 100644 --- a/source/game/StarPlayerDeployment.hpp +++ b/source/game/StarPlayerDeployment.hpp @@ -28,7 +28,7 @@ public: void teleportOut(); Maybe receiveMessage(String const& message, bool localMessage, JsonArray const& args = {}); - void update(); + void update(float dt); void render(RenderCallback* renderCallback, Vec2F const& position); diff --git a/source/game/StarProjectile.cpp b/source/game/StarProjectile.cpp index 89f3766..fa01480 100644 --- a/source/game/StarProjectile.cpp +++ b/source/game/StarProjectile.cpp @@ -250,9 +250,11 @@ void Projectile::hitOther(EntityId entity, DamageRequest const&) { m_scriptComponent.invoke("hit", entity); } -void Projectile::update(uint64_t) { +void Projectile::update(float dt, uint64_t) { + m_movementController->setTimestep(dt); + if (isMaster()) { - m_timeToLive -= WorldTimestep; + m_timeToLive -= dt; if (m_timeToLive < 0) m_timeToLive = 0; @@ -261,17 +263,17 @@ void Projectile::update(uint64_t) { if (m_referenceVelocity) m_movementController->setVelocity(m_movementController->velocity() - *m_referenceVelocity); - m_scriptComponent.update(m_scriptComponent.updateDt()); + m_scriptComponent.update(m_scriptComponent.updateDt(dt)); m_movementController->accelerate(m_movementController->velocity().normalized() * m_acceleration); if (m_referenceVelocity) m_movementController->setVelocity(m_movementController->velocity() + *m_referenceVelocity); - m_movementController->tickMaster(); + m_movementController->tickMaster(dt); m_travelLine.min() = m_travelLine.max(); m_travelLine.max() = m_movementController->position(); - tickShared(); + tickShared(dt); if (m_trackSourceEntity) { if (auto sourceEntity = world()->entity(m_sourceEntity)) { @@ -335,13 +337,13 @@ void Projectile::update(uint64_t) { } } else { m_netGroup.tickNetInterpolation(WorldTimestep); - m_movementController->tickSlave(); + m_movementController->tickSlave(dt); m_travelLine.min() = m_travelLine.max(); m_travelLine.max() = m_movementController->position(); - m_timeToLive -= WorldTimestep; + m_timeToLive -= dt; - tickShared(); + tickShared(dt); } if (world()->isClient()) @@ -853,19 +855,19 @@ void Projectile::processAction(Json const& action) { } } -void Projectile::tickShared() { +void Projectile::tickShared(float dt) { if (!m_config->orientationLocked && !m_movementController->stickingDirection()) { auto apparentVelocity = m_movementController->velocity() - m_referenceVelocity.value(); if (apparentVelocity != Vec2F()) m_movementController->setRotation(apparentVelocity.angle()); } - m_animationTimer += WorldTimestep; + m_animationTimer += dt; setFrame(getFrame()); m_effectEmitter->setSourcePosition("normal", position()); m_effectEmitter->setDirection(getAngleSide(m_movementController->rotation(), true).second); - m_effectEmitter->tick(*entityMode()); + m_effectEmitter->tick(dt, *entityMode()); if (m_collisionEvent.pullOccurred()) { for (auto const& action : m_parameters.getArray("actionOnCollide", m_config->actionOnCollide)) @@ -879,7 +881,7 @@ void Projectile::tickShared() { if (get<0>(periodicAction).wrapTick()) processAction(get<2>(periodicAction)); } else { - if (get<0>(periodicAction).tick()) { + if (get<0>(periodicAction).tick(dt)) { processAction(get<2>(periodicAction)); periodicActionIt.remove(); } diff --git a/source/game/StarProjectile.hpp b/source/game/StarProjectile.hpp index 7a36dfe..01225ad 100644 --- a/source/game/StarProjectile.hpp +++ b/source/game/StarProjectile.hpp @@ -56,7 +56,7 @@ public: List damageSources() const override; void hitOther(EntityId targetEntityId, DamageRequest const& dr) override; - void update(uint64_t currentStep) override; + void update(float dt, uint64_t currentStep) override; void render(RenderCallback* renderCallback) override; void renderLightSources(RenderCallback* renderCallback) override; @@ -117,7 +117,7 @@ private: String drawableFrame(); void processAction(Json const& action); - void tickShared(); + void tickShared(float dt); void setup(); diff --git a/source/game/StarQuestManager.cpp b/source/game/StarQuestManager.cpp index 0807c03..6ea4689 100644 --- a/source/game/StarQuestManager.cpp +++ b/source/game/StarQuestManager.cpp @@ -342,7 +342,7 @@ Maybe QuestManager::receiveMessage(String const& message, bool localMessag return result; } -void QuestManager::update() { +void QuestManager::update(float dt) { startInitialQuests(); if (m_trackedQuestId && !isActive(*m_trackedQuestId)) @@ -381,7 +381,7 @@ void QuestManager::update() { } } - serverQuests().exec([](QuestPtr const& quest) { quest->update(); }); + serverQuests().exec([dt](QuestPtr const& quest) { quest->update(dt); }); } List QuestManager::serverQuests() const { diff --git a/source/game/StarQuestManager.hpp b/source/game/StarQuestManager.hpp index 33eb34d..0dec97e 100644 --- a/source/game/StarQuestManager.hpp +++ b/source/game/StarQuestManager.hpp @@ -58,7 +58,7 @@ public: StringSet interestingObjects(); Maybe receiveMessage(String const& message, bool localMessage, JsonArray const& args = {}); - void update(); + void update(float dt); private: List serverQuests() const; diff --git a/source/game/StarQuests.cpp b/source/game/StarQuests.cpp index 8b320b9..d3c07c5 100644 --- a/source/game/StarQuests.cpp +++ b/source/game/StarQuests.cpp @@ -216,10 +216,10 @@ Maybe Quest::receiveMessage(String const& message, bool localMessage, Json return m_scriptComponent.handleMessage(message, localMessage, args); } -void Quest::update() { +void Quest::update(float dt) { if (!m_inited) return; - m_scriptComponent.update(m_scriptComponent.updateDt()); + m_scriptComponent.update(m_scriptComponent.updateDt(dt)); } void Quest::offer() { diff --git a/source/game/StarQuests.hpp b/source/game/StarQuests.hpp index 0bd86fc..fd17f5d 100644 --- a/source/game/StarQuests.hpp +++ b/source/game/StarQuests.hpp @@ -46,7 +46,7 @@ public: void uninit(); Maybe receiveMessage(String const& message, bool localMessage, JsonArray const& args = {}); - void update(); + void update(float dt); void offer(); void declineOffer(); diff --git a/source/game/StarSky.cpp b/source/game/StarSky.cpp index 3266b0f..05e6207 100644 --- a/source/game/StarSky.cpp +++ b/source/game/StarSky.cpp @@ -115,8 +115,7 @@ void Sky::stateUpdate() { m_lastWarpPhase = m_warpPhase; } -void Sky::update() { - double dt = WorldTimestep; +void Sky::update(double dt) { if (m_referenceClock) { m_time = m_referenceClock->time(); if (!m_clockTrackingTime) { diff --git a/source/game/StarSky.hpp b/source/game/StarSky.hpp index c7d4bf6..1921a3a 100644 --- a/source/game/StarSky.hpp +++ b/source/game/StarSky.hpp @@ -36,7 +36,7 @@ public: // handles flying and warp state transitions void stateUpdate(); - void update(); + void update(double dt); void setType(SkyType type); SkyType type() const; diff --git a/source/game/StarSpawner.cpp b/source/game/StarSpawner.cpp index 4c54ed4..f64ccfe 100644 --- a/source/game/StarSpawner.cpp +++ b/source/game/StarSpawner.cpp @@ -73,7 +73,7 @@ void Spawner::activateEmptyRegion(RectF region) { m_activeSpawnCells[cell] = m_spawnCellLifetime; } -void Spawner::update() { +void Spawner::update(float dt) { if (!m_facade) return; @@ -82,10 +82,9 @@ void Spawner::update() { activateRegion(window.padded(m_windowActivationBorder)); } - eraseWhere(m_activeSpawnCells, [](auto& p) { - p.second -= WorldTimestep; - return p.second < 0.0f; - }); + eraseWhere(m_activeSpawnCells, [dt](auto& p) { + return (p.second -= dt) < 0.0f; + }); eraseWhere(m_spawnedEntities, [this](EntityId entityId) { auto entity = m_facade->getEntity(entityId); diff --git a/source/game/StarSpawner.hpp b/source/game/StarSpawner.hpp index 709ccdc..b04382a 100644 --- a/source/game/StarSpawner.hpp +++ b/source/game/StarSpawner.hpp @@ -60,7 +60,7 @@ public: // nothing if they are already active. void activateEmptyRegion(RectF region); - void update(); + void update(float dt); private: struct SpawnCellDebugInfo { diff --git a/source/game/StarStagehand.cpp b/source/game/StarStagehand.cpp index dad09a2..06fa9ae 100644 --- a/source/game/StarStagehand.cpp +++ b/source/game/StarStagehand.cpp @@ -85,12 +85,12 @@ void Stagehand::readNetState(ByteArray data, float) { m_netGroup.readNetState(move(data)); } -void Stagehand::update(uint64_t) { +void Stagehand::update(float dt, uint64_t) { if (!inWorld()) return; if (isMaster() && m_scripted) - m_scriptComponent.update(m_scriptComponent.updateDt()); + m_scriptComponent.update(m_scriptComponent.updateDt(dt)); if (world()->isClient()) { auto boundBox = metaBoundBox().translated(position()); diff --git a/source/game/StarStagehand.hpp b/source/game/StarStagehand.hpp index 6b28dad..d6ce68d 100644 --- a/source/game/StarStagehand.hpp +++ b/source/game/StarStagehand.hpp @@ -35,7 +35,7 @@ public: pair writeNetState(uint64_t fromVersion = 0) override; void readNetState(ByteArray data, float interpolationTime = 0.0f) override; - void update(uint64_t currentStep) override; + void update(float dt, uint64_t currentStep) override; bool shouldDestroy() const override; diff --git a/source/game/StarStatCollection.cpp b/source/game/StarStatCollection.cpp index 4717824..9f5e1f3 100644 --- a/source/game/StarStatCollection.cpp +++ b/source/game/StarStatCollection.cpp @@ -153,11 +153,11 @@ void StatCollection::clearStatModifiers() { m_stats.clearStatModifiers(); } -void StatCollection::tickMaster() { - m_stats.update(WorldTimestep); +void StatCollection::tickMaster(float dt) { + m_stats.update(dt); } -void StatCollection::tickSlave() { +void StatCollection::tickSlave(float dt) { m_stats.update(0.0f); } diff --git a/source/game/StarStatCollection.hpp b/source/game/StarStatCollection.hpp index 7094273..c535ef1 100644 --- a/source/game/StarStatCollection.hpp +++ b/source/game/StarStatCollection.hpp @@ -49,8 +49,8 @@ public: void removeStatModifierGroup(StatModifierGroupId modifierGroupId); void clearStatModifiers(); - void tickMaster(); - void tickSlave(); + void tickMaster(float dt); + void tickSlave(float dt); private: void netElementsNeedLoad(bool full) override; diff --git a/source/game/StarStatusController.cpp b/source/game/StarStatusController.cpp index 44f0afc..ba0930c 100644 --- a/source/game/StarStatusController.cpp +++ b/source/game/StarStatusController.cpp @@ -452,8 +452,8 @@ void StatusController::blankNetDelta(float interpolationTime) { m_netGroup.blankNetDelta(interpolationTime); } -void StatusController::tickMaster() { - m_statCollection.tickMaster(); +void StatusController::tickMaster(float dt) { + m_statCollection.tickMaster(dt); m_recentHitsGiven.tick(1); m_recentDamageGiven.tick(1); @@ -492,12 +492,12 @@ void StatusController::tickMaster() { addEphemeralEffects(m_parentEntity->world()->weatherStatusEffects(m_parentEntity->position()).transformed(jsonToEphemeralStatusEffect)); } - m_primaryScript.update(m_primaryScript.updateDt()); + m_primaryScript.update(m_primaryScript.updateDt(dt)); for (auto& p : m_uniqueEffects) { - p.second.script.update(p.second.script.updateDt()); + p.second.script.update(p.second.script.updateDt(dt)); auto metadata = m_uniqueEffectMetadata.getNetElement(p.second.metadataId); if (metadata->duration) - *metadata->duration -= WorldTimestep; + *metadata->duration -= dt; } for (auto const& key : m_uniqueEffects.keys()) { @@ -516,12 +516,12 @@ void StatusController::tickMaster() { m_parentDirectives.set(move(parentDirectives)); - updateAnimators(); + updateAnimators(dt); } -void StatusController::tickSlave() { - m_statCollection.tickSlave(); - updateAnimators(); +void StatusController::tickSlave(float dt) { + m_statCollection.tickSlave(dt); + updateAnimators(dt); } const DirectivesGroup& StatusController::parentDirectives() const { @@ -637,12 +637,12 @@ void StatusController::UniqueEffectMetadata::netElementsNeedStore() { durationNetState.set(duration ? *duration : -1.0f); } -void StatusController::updateAnimators() { +void StatusController::updateAnimators(float dt) { for (auto const& animator : m_effectAnimators.netElements()) { if (m_parentEntity->world()->isServer()) { - animator->animator.update(WorldTimestep, nullptr); + animator->animator.update(dt, nullptr); } else { - animator->animator.update(WorldTimestep, &animator->dynamicTarget); + animator->animator.update(dt, &animator->dynamicTarget); animator->dynamicTarget.updatePosition(m_movementController->position()); } } diff --git a/source/game/StarStatusController.hpp b/source/game/StarStatusController.hpp index 4e9839f..94d636a 100644 --- a/source/game/StarStatusController.hpp +++ b/source/game/StarStatusController.hpp @@ -115,8 +115,8 @@ public: void readNetDelta(DataStream& ds, float interpolationTime = 0.0) override; void blankNetDelta(float interpolationTime) override; - void tickMaster(); - void tickSlave(); + void tickMaster(float dt); + void tickSlave(float dt); const DirectivesGroup& parentDirectives() const; List drawables() const; @@ -187,7 +187,7 @@ private: EffectAnimatorGroup::ElementId animatorId; }; - void updateAnimators(); + void updateAnimators(float dt); void updatePersistentUniqueEffects(); float defaultUniqueEffectDuration(UniqueStatusEffect const& name) const; diff --git a/source/game/StarSystemWorldClient.cpp b/source/game/StarSystemWorldClient.cpp index 9be0980..d4f8c15 100644 --- a/source/game/StarSystemWorldClient.cpp +++ b/source/game/StarSystemWorldClient.cpp @@ -41,11 +41,11 @@ bool SystemWorldClient::flying() const { return true; } -void SystemWorldClient::update() { +void SystemWorldClient::update(float dt) { if (!m_ship) return; - m_ship->clientUpdate(WorldTimestep); + m_ship->clientUpdate(dt); auto location = m_ship->systemLocation(); if (auto uuid = location.maybe()) { @@ -66,9 +66,9 @@ void SystemWorldClient::update() { } for (auto p : m_clientShips) - p.second->clientUpdate(WorldTimestep); + p.second->clientUpdate(dt); for (auto p : m_objects) - p.second->clientUpdate(WorldTimestep); + p.second->clientUpdate(dt); if (currentSystem().isNull()) { m_objects.clear(); diff --git a/source/game/StarSystemWorldClient.hpp b/source/game/StarSystemWorldClient.hpp index 74ef6c0..1ec059a 100644 --- a/source/game/StarSystemWorldClient.hpp +++ b/source/game/StarSystemWorldClient.hpp @@ -25,7 +25,7 @@ public: SystemLocation shipDestination() const; bool flying() const; - void update(); + void update(float dt); List objects() const override; SystemObjectPtr getObject(Uuid const& uuid) const override; diff --git a/source/game/StarSystemWorldServer.cpp b/source/game/StarSystemWorldServer.cpp index ca1b828..f430bcb 100644 --- a/source/game/StarSystemWorldServer.cpp +++ b/source/game/StarSystemWorldServer.cpp @@ -208,12 +208,12 @@ bool SystemWorldServer::addObject(SystemObjectPtr object, bool doRangeCheck) { return true; } -void SystemWorldServer::update() { +void SystemWorldServer::update(float dt) { for (auto p : m_ships) - p.second->serverUpdate(this, SystemWorldTimestep); + p.second->serverUpdate(this, dt); for (auto p : m_objects) { - p.second->serverUpdate(this, SystemWorldTimestep); + p.second->serverUpdate(this, dt); // don't destroy objects that still have players at them if (p.second->shouldDestroy() && shipsAtLocation(p.first).size() == 0) diff --git a/source/game/StarSystemWorldServer.hpp b/source/game/StarSystemWorldServer.hpp index 97ed5ac..f1bc30f 100644 --- a/source/game/StarSystemWorldServer.hpp +++ b/source/game/StarSystemWorldServer.hpp @@ -37,7 +37,7 @@ public: void removeObject(Uuid objectUuid); bool addObject(SystemObjectPtr object, bool doRangeCheck = false); - void update(); + void update(float dt); List objects() const override; SystemObjectPtr getObject(Uuid const& uuid) const override; diff --git a/source/game/StarSystemWorldServerThread.cpp b/source/game/StarSystemWorldServerThread.cpp index 83210a2..fb5cea5 100644 --- a/source/game/StarSystemWorldServerThread.cpp +++ b/source/game/StarSystemWorldServerThread.cpp @@ -89,7 +89,7 @@ void SystemWorldServerThread::update() { p.second(m_systemWorld->clientShip(p.first).get()); if (!m_pause || *m_pause == false) - m_systemWorld->update(); + m_systemWorld->update(SystemWorldTimestep); m_triggerStorage = m_systemWorld->triggeredStorage(); // important to set destinations before getting locations diff --git a/source/game/StarTechController.cpp b/source/game/StarTechController.cpp index 8f0c7d7..4295fb7 100644 --- a/source/game/StarTechController.cpp +++ b/source/game/StarTechController.cpp @@ -190,7 +190,7 @@ void TechController::setAimPosition(Vec2F const& aimPosition) { m_aimPosition = aimPosition; } -void TechController::tickMaster() { +void TechController::tickMaster(float dt) { // if there's no gravity, fly instead of walking if (m_movementController->zeroG()) { if (m_moveRight || m_moveLeft || m_moveUp || m_moveDown) { @@ -235,16 +235,16 @@ void TechController::tickMaster() { {"special3", m_moveSpecial3} }; - module.scriptComponent.update(JsonObject{{"moves", moves}, {"dt", WorldTimestep}}); + module.scriptComponent.update(JsonObject{{"moves", moves}, {"dt", dt}}); } resetMoves(); - updateAnimators(); + updateAnimators(dt); } -void TechController::tickSlave() { +void TechController::tickSlave(float dt) { resetMoves(); - updateAnimators(); + updateAnimators(dt); } Maybe TechController::parentState() const { @@ -467,15 +467,15 @@ void TechController::resetMoves() { m_moveSpecial3 = false; } -void TechController::updateAnimators() { +void TechController::updateAnimators(float dt) { for (auto const& module : m_techModules) m_techAnimators.getNetElement(module.animatorId)->setVisible(module.visible); for (auto const& animator : m_techAnimators.netElements()) { if (m_parentEntity->world()->isServer() || !animator->isVisible()) { - animator->animator.update(WorldTimestep, nullptr); + animator->animator.update(dt, nullptr); } else { - animator->animator.update(WorldTimestep, &animator->dynamicTarget); + animator->animator.update(dt, &animator->dynamicTarget); animator->dynamicTarget.updatePosition(m_movementController->position()); } } diff --git a/source/game/StarTechController.hpp b/source/game/StarTechController.hpp index 584cf5d..03fa61f 100644 --- a/source/game/StarTechController.hpp +++ b/source/game/StarTechController.hpp @@ -64,8 +64,8 @@ public: void setAimPosition(Vec2F const& aimPosition); - void tickMaster(); - void tickSlave(); + void tickMaster(float dt); + void tickSlave(float dt); Maybe parentState() const; DirectivesGroup const& parentDirectives() const; @@ -133,7 +133,7 @@ private: void initializeModules(); void resetMoves(); - void updateAnimators(); + void updateAnimators(float dt); LuaCallbacks makeTechCallbacks(TechModule& techModule); diff --git a/source/game/StarToolUser.cpp b/source/game/StarToolUser.cpp index 6c0cdf2..e0e32a8 100644 --- a/source/game/StarToolUser.cpp +++ b/source/game/StarToolUser.cpp @@ -38,10 +38,11 @@ ToolUser::ToolUser() addNetElement(&m_primaryItemActiveNetState); addNetElement(&m_altItemActiveNetState); - m_primaryFireTimerNetState.setFixedPointBase(WorldTimestep); - m_altFireTimerNetState.setFixedPointBase(WorldTimestep); - m_primaryTimeFiringNetState.setFixedPointBase(WorldTimestep); - m_altTimeFiringNetState.setFixedPointBase(WorldTimestep); + float fixedPointBase = 1.f / 60.f; + m_primaryFireTimerNetState.setFixedPointBase(fixedPointBase); + m_altFireTimerNetState.setFixedPointBase(fixedPointBase); + m_primaryTimeFiringNetState.setFixedPointBase(fixedPointBase); + m_altTimeFiringNetState.setFixedPointBase(fixedPointBase); auto interpolateTimer = [](double offset, double min, double max) -> double { if (max > min) @@ -369,7 +370,7 @@ bool ToolUser::queryShieldHit(DamageSource const& source) const { return false; } -void ToolUser::tick(bool shifting, HashSet const& moves) { +void ToolUser::tick(float dt, bool shifting, HashSet const& moves) { if (auto toolUserItem = as(m_primaryHandItem.get())) { FireMode fireMode = FireMode::None; if (!m_suppress.get()) { @@ -378,7 +379,7 @@ void ToolUser::tick(bool shifting, HashSet const& moves) { else if (m_fireAlt && m_primaryHandItem.get()->twoHanded()) fireMode = FireMode::Alt; } - toolUserItem->update(fireMode, shifting, moves); + toolUserItem->update(dt, fireMode, shifting, moves); } if (!m_primaryHandItem.get() || !m_primaryHandItem.get()->twoHanded()) { @@ -386,7 +387,7 @@ void ToolUser::tick(bool shifting, HashSet const& moves) { FireMode fireMode = FireMode::None; if (!m_suppress.get() && m_fireAlt) fireMode = FireMode::Primary; - toolUserItem->update(fireMode, shifting, moves); + toolUserItem->update(dt, fireMode, shifting, moves); } } diff --git a/source/game/StarToolUser.hpp b/source/game/StarToolUser.hpp index 186a480..eeec920 100644 --- a/source/game/StarToolUser.hpp +++ b/source/game/StarToolUser.hpp @@ -54,7 +54,7 @@ public: Vec2F handPosition(ToolHand hand, Humanoid const& humanoid, Vec2F const& handOffset) const; bool queryShieldHit(DamageSource const& source) const; - void tick(bool shifting, HashSet const& moves); + void tick(float dt, bool shifting, HashSet const& moves); void beginPrimaryFire(); void beginAltFire(); diff --git a/source/game/StarUniverseClient.cpp b/source/game/StarUniverseClient.cpp index 35a74b0..3adc95d 100644 --- a/source/game/StarUniverseClient.cpp +++ b/source/game/StarUniverseClient.cpp @@ -170,7 +170,7 @@ SystemWorldClientPtr UniverseClient::systemWorldClient() const { return m_systemWorldClient; } -void UniverseClient::update() { +void UniverseClient::update(float dt) { auto assets = Root::singleton().assets(); if (!isConnected()) @@ -182,7 +182,7 @@ void UniverseClient::update() { } if (m_pendingWarp) { - if ((m_warping && !m_mainPlayer->isTeleportingOut()) || (!m_warping && m_warpDelay.tick())) { + if ((m_warping && !m_mainPlayer->isTeleportingOut()) || (!m_warping && m_warpDelay.tick(dt))) { m_connection->pushSingle(make_shared(take(m_pendingWarp), m_mainPlayer->isDeploying())); m_warpDelay.reset(); if (m_warping) { @@ -222,14 +222,14 @@ void UniverseClient::update() { m_statistics->update(); if (!m_pause) { - m_worldClient->update(); + m_worldClient->update(dt); for (auto& p : m_scriptContexts) p.second->update(); } m_connection->push(m_worldClient->getOutgoingPackets()); if (!m_pause) - m_systemWorldClient->update(); + m_systemWorldClient->update(dt); m_connection->push(m_systemWorldClient->pullOutgoingPackets()); m_teamClient->update(); @@ -260,7 +260,7 @@ void UniverseClient::update() { m_respawning = false; } } else { - if (m_respawnTimer.tick()) { + if (m_respawnTimer.tick(dt)) { String cinematic = assets->json("/client.config:respawnCinematic").toString(); cinematic = cinematic.replaceTags(StringMap{ {"species", m_mainPlayer->species()}, diff --git a/source/game/StarUniverseClient.hpp b/source/game/StarUniverseClient.hpp index daad481..9fda492 100644 --- a/source/game/StarUniverseClient.hpp +++ b/source/game/StarUniverseClient.hpp @@ -53,7 +53,7 @@ public: // Updates internal world client in addition to handling universe level // commands. - void update(); + void update(float dt); Maybe beamUpRule() const; bool canBeamUp() const; diff --git a/source/game/StarVehicle.cpp b/source/game/StarVehicle.cpp index 5747507..89820b2 100644 --- a/source/game/StarVehicle.cpp +++ b/source/game/StarVehicle.cpp @@ -258,19 +258,19 @@ void Vehicle::disableInterpolation() { m_netGroup.disableNetInterpolation(); } -void Vehicle::update(uint64_t) { +void Vehicle::update(float dt, uint64_t) { setTeam(m_damageTeam.get()); if (world()->isClient()) { - m_networkedAnimator.update(WorldTimestep, &m_networkedAnimatorDynamicTarget); + m_networkedAnimator.update(dt, &m_networkedAnimatorDynamicTarget); m_networkedAnimatorDynamicTarget.updatePosition(position()); } else { - m_networkedAnimator.update(WorldTimestep, nullptr); + m_networkedAnimator.update(dt, nullptr); } if (isMaster()) { - m_movementController.tickMaster(); - m_scriptComponent.update(m_scriptComponent.updateDt()); + m_movementController.tickMaster(dt); + m_scriptComponent.update(m_scriptComponent.updateDt(dt)); eraseWhere(m_aliveMasterConnections, [](auto& p) { return p.second.tick(WorldTimestep); @@ -287,7 +287,7 @@ void Vehicle::update(uint64_t) { } else { m_netGroup.tickNetInterpolation(WorldTimestep); - m_movementController.tickSlave(); + m_movementController.tickSlave(dt); bool heartbeat = m_slaveHeartbeatTimer.wrapTick(); diff --git a/source/game/StarVehicle.hpp b/source/game/StarVehicle.hpp index f5bc2b5..d397426 100644 --- a/source/game/StarVehicle.hpp +++ b/source/game/StarVehicle.hpp @@ -51,7 +51,7 @@ public: void enableInterpolation(float extrapolationHint) override; void disableInterpolation() override; - void update(uint64_t currentStep) override; + void update(float dt, uint64_t currentStep) override; void render(RenderCallback* renderer) override; diff --git a/source/game/StarWeather.cpp b/source/game/StarWeather.cpp index 14120ad..010893a 100644 --- a/source/game/StarWeather.cpp +++ b/source/game/StarWeather.cpp @@ -60,10 +60,9 @@ pair ServerWeather::writeUpdate(uint64_t fromVersion) { return m_netGroup.writeNetState(fromVersion); } -void ServerWeather::update() { - spawnWeatherProjectiles(WorldTimestep); +void ServerWeather::update(double dt) { + spawnWeatherProjectiles(dt); - double dt = WorldTimestep; if (m_referenceClock) { double clockTime = m_referenceClock->time(); if (!m_clockTrackingTime) { @@ -275,8 +274,8 @@ void ClientWeather::setVisibleRegion(RectI visibleRegion) { m_visibleRegion = visibleRegion; } -void ClientWeather::update() { - m_currentTime += WorldTimestep; +void ClientWeather::update(double dt) { + m_currentTime += dt; if (m_currentWeatherIndex == NPos) { m_currentWeatherType = {}; @@ -288,7 +287,7 @@ void ClientWeather::update() { } if (m_currentWeatherType) - spawnWeatherParticles(RectF(m_visibleRegion), WorldTimestep); + spawnWeatherParticles(RectF(m_visibleRegion), dt); } float ClientWeather::wind() const { diff --git a/source/game/StarWeather.hpp b/source/game/StarWeather.hpp index dc9888d..4db0fff 100644 --- a/source/game/StarWeather.hpp +++ b/source/game/StarWeather.hpp @@ -32,7 +32,7 @@ public: pair writeUpdate(uint64_t fromVersion = 0); - void update(); + void update(double dt); float wind() const; float weatherIntensity() const; @@ -85,7 +85,7 @@ public: void setVisibleRegion(RectI visibleRegion); - void update(); + void update(double dt); float wind() const; float weatherIntensity() const; diff --git a/source/game/StarWorldClient.cpp b/source/game/StarWorldClient.cpp index 091d66e..d6e6020 100644 --- a/source/game/StarWorldClient.cpp +++ b/source/game/StarWorldClient.cpp @@ -947,7 +947,7 @@ void WorldClient::setLuaCallbacks(String const& groupName, LuaCallbacks const& c m_luaRoot->addCallbacks(groupName, callbacks); } -void WorldClient::update() { +void WorldClient::update(float dt) { if (!inWorld()) return; @@ -989,7 +989,7 @@ void WorldClient::update() { List toRemove; List clientPresenceEntities{m_mainPlayer->entityId()}; m_entityMap->updateAllEntities([&](EntityPtr const& entity) { - entity->update(m_currentStep); + entity->update(dt, m_currentStep); if (entity->shouldDestroy() && entity->entityMode() == EntityMode::Master) toRemove.append(entity->entityId()); @@ -1002,16 +1002,16 @@ void WorldClient::update() { m_clientState.setPlayer(m_mainPlayer->entityId()); m_clientState.setClientPresenceEntities(move(clientPresenceEntities)); - m_damageManager->update(); + m_damageManager->update(dt); handleDamageNotifications(); m_sky->setAltitude(m_clientState.windowCenter()[1]); - m_sky->update(); + m_sky->update(dt); RectI particleRegion = m_clientState.window().padded(m_clientConfig.getInt("particleRegionPadding")); m_weather.setVisibleRegion(particleRegion); - m_weather.update(); + m_weather.update(dt); if (!m_mainPlayer->isDead()) { // Clear m_requestedDrops every so often in case of entity id reuse or @@ -1038,7 +1038,7 @@ void WorldClient::update() { sparkDamagedBlocks(); m_particles->addParticles(m_weather.pullNewParticles()); - m_particles->update(WorldTimestep, RectF(particleRegion), m_weather.wind()); + m_particles->update(dt, RectF(particleRegion), m_weather.wind()); if (auto audioSample = m_ambientSounds.updateAmbient(currentAmbientNoises(), m_sky->isDayTime())) m_samples.append(audioSample); diff --git a/source/game/StarWorldClient.hpp b/source/game/StarWorldClient.hpp index 436c2df..34efc1c 100644 --- a/source/game/StarWorldClient.hpp +++ b/source/game/StarWorldClient.hpp @@ -138,7 +138,7 @@ public: void centerClientWindowOnPlayer(); RectI clientWindow() const; - void update(); + void update(float dt); // borderTiles here should extend the client window for border tile // calculations. It is not necessary on the light array. void render(WorldRenderData& renderData, unsigned borderTiles); diff --git a/source/game/StarWorldServer.cpp b/source/game/StarWorldServer.cpp index ebd853a..3c5fbfe 100644 --- a/source/game/StarWorldServer.cpp +++ b/source/game/StarWorldServer.cpp @@ -523,7 +523,7 @@ void WorldServer::setFidelity(WorldServerFidelity fidelity) { m_fidelityConfig = m_serverConfig.get("fidelitySettings").get(WorldServerFidelityNames.getRight(m_fidelity)); } -void WorldServer::update() { +void WorldServer::update(float dt) { ++m_currentStep; for (auto const& pair : m_clientInfo) pair.second->interpolationTracker.update(m_currentStep); @@ -539,7 +539,7 @@ void WorldServer::update() { for (auto const& action : triggeredActions) action(this); - m_spawner.update(); + m_spawner.update(dt); bool doBreakChecks = m_tileEntityBreakCheckTimer.wrapTick(m_currentStep) && m_needsGlobalBreakCheck; if (doBreakChecks) @@ -547,7 +547,7 @@ void WorldServer::update() { List toRemove; m_entityMap->updateAllEntities([&](EntityPtr const& entity) { - entity->update(m_currentStep); + entity->update(dt, m_currentStep); if (auto tileEntity = as(entity)) { // Only do break checks on objects if all sectors the object touches @@ -564,11 +564,11 @@ void WorldServer::update() { return a->entityType() < b->entityType(); }); - updateDamage(); + updateDamage(dt); if (shouldRunThisStep("wiringUpdate")) m_wireProcessor->process(); - m_sky->update(); + m_sky->update(dt); List clientWindows; List clientMonitoringRegions; @@ -579,7 +579,7 @@ void WorldServer::update() { } m_weather.setClientVisibleRegions(clientWindows); - m_weather.update(); + m_weather.update(dt); for (auto projectile : m_weather.pullNewProjectiles()) addEntity(move(projectile)); @@ -1782,8 +1782,8 @@ void WorldServer::queueUpdatePackets(ConnectionId clientId) { clientInfo->outgoingPackets.append(move(p.second)); } -void WorldServer::updateDamage() { - m_damageManager->update(); +void WorldServer::updateDamage(float dt) { + m_damageManager->update(dt); // Do nothing with damage notifications at the moment. m_damageManager->pullPendingNotifications(); diff --git a/source/game/StarWorldServer.hpp b/source/game/StarWorldServer.hpp index 40dd7c1..66a21d3 100644 --- a/source/game/StarWorldServer.hpp +++ b/source/game/StarWorldServer.hpp @@ -106,7 +106,7 @@ public: WorldServerFidelity fidelity() const; void setFidelity(WorldServerFidelity fidelity); - void update(); + void update(float dt); ConnectionId connection() const override; WorldGeometry geometry() const override; @@ -292,7 +292,7 @@ private: // Queues pending (step based) updates to the given player void queueUpdatePackets(ConnectionId clientId); - void updateDamage(); + void updateDamage(float dt); void updateDamagedBlocks(float dt); diff --git a/source/game/StarWorldServerThread.cpp b/source/game/StarWorldServerThread.cpp index c31ae84..e06221e 100644 --- a/source/game/StarWorldServerThread.cpp +++ b/source/game/StarWorldServerThread.cpp @@ -191,7 +191,7 @@ void WorldServerThread::run() { double storageInterval = root.assets()->json("/universe_server.config:worldStorageInterval").toDouble() / 1000.0; Timer storageTimer = Timer::withTime(storageInterval); - TickRateApproacher tickApproacher(1.0 / WorldTimestep, updateMeasureWindow); + TickRateApproacher tickApproacher(1.0 / ServerWorldTimestep, updateMeasureWindow); double fidelityScore = 0.0; WorldServerFidelity automaticFidelity = WorldServerFidelity::Medium; @@ -251,9 +251,10 @@ void WorldServerThread::update(WorldServerFidelity fidelity) { } } + float dt = ServerWorldTimestep * GlobalTimescale; m_worldServer->setFidelity(fidelity); if (!m_pause || *m_pause == false) - m_worldServer->update(); + m_worldServer->update(dt); for (auto& clientId : unerroredClientIds) { auto outgoingPackets = m_worldServer->getOutgoingPackets(clientId); diff --git a/source/game/interfaces/StarBeamItem.cpp b/source/game/interfaces/StarBeamItem.cpp index 66e29c1..2bf8e02 100644 --- a/source/game/interfaces/StarBeamItem.cpp +++ b/source/game/interfaces/StarBeamItem.cpp @@ -57,9 +57,9 @@ void BeamItem::init(ToolUserEntity* owner, ToolHand hand) { throw ItemException("BeamItem::init: Beam Gun not init'd properly, or user not recognized as Tool User."); } -void BeamItem::update(FireMode, bool, HashSet const&) { +void BeamItem::update(float dt, FireMode, bool, HashSet const&) { if (m_particleGenerateCooldown >= 0) - m_particleGenerateCooldown -= WorldTimestep; + m_particleGenerateCooldown -= dt; if (!initialized()) throw ItemException("BeamItem::update: Beam Gun not init'd properly, or user not recognized as Tool User."); diff --git a/source/game/interfaces/StarBeamItem.hpp b/source/game/interfaces/StarBeamItem.hpp index aeb5d93..7c7cfae 100644 --- a/source/game/interfaces/StarBeamItem.hpp +++ b/source/game/interfaces/StarBeamItem.hpp @@ -22,7 +22,7 @@ public: virtual ~BeamItem() = default; virtual void init(ToolUserEntity* owner, ToolHand hand) override; - virtual void update(FireMode fireMode, bool shifting, HashSet const& moves) override; + virtual void update(float dt, FireMode fireMode, bool shifting, HashSet const& moves) override; virtual List nonRotatedDrawables() const override; diff --git a/source/game/interfaces/StarEntity.cpp b/source/game/interfaces/StarEntity.cpp index 67887c9..801a0d8 100644 --- a/source/game/interfaces/StarEntity.cpp +++ b/source/game/interfaces/StarEntity.cpp @@ -111,7 +111,7 @@ Maybe Entity::receiveMessage(ConnectionId, String const&, JsonArray const& return {}; } -void Entity::update(uint64_t) {} +void Entity::update(float dt, uint64_t) {} void Entity::render(RenderCallback*) {} diff --git a/source/game/interfaces/StarEntity.hpp b/source/game/interfaces/StarEntity.hpp index ad297a9..e55fed8 100644 --- a/source/game/interfaces/StarEntity.hpp +++ b/source/game/interfaces/StarEntity.hpp @@ -149,7 +149,7 @@ public: // This will only ever be called on master entities. virtual Maybe receiveMessage(ConnectionId sendingConnection, String const& message, JsonArray const& args); - virtual void update(uint64_t currentStep); + virtual void update(float dt, uint64_t currentStep); virtual void render(RenderCallback* renderer); diff --git a/source/game/interfaces/StarFireableItem.cpp b/source/game/interfaces/StarFireableItem.cpp index e39d77e..1b16779 100644 --- a/source/game/interfaces/StarFireableItem.cpp +++ b/source/game/interfaces/StarFireableItem.cpp @@ -165,15 +165,15 @@ bool FireableItem::windup() const { return fireTimer() > cooldownTime(); } -void FireableItem::update(FireMode fireMode, bool shifting, HashSet const&) { +void FireableItem::update(float dt, FireMode fireMode, bool shifting, HashSet const&) { if (m_scriptComponent) - m_scriptComponent->invoke("update", WorldTimestep, FireModeNames.getRight(fireMode), shifting); + m_scriptComponent->invoke("update", dt, FireModeNames.getRight(fireMode), shifting); if (m_attemptedFire) { if (m_startTimingFire) { - m_timeFiring += WorldTimestep; + m_timeFiring += dt; if (m_scriptComponent) - m_scriptComponent->invoke("continueFire", WorldTimestep); + m_scriptComponent->invoke("continueFire", dt); } } else { m_timeFiring = 0.0f; @@ -183,7 +183,7 @@ void FireableItem::update(FireMode fireMode, bool shifting, HashSet 0.0f) { - setFireTimer(fireTimer() - WorldTimestep); + setFireTimer(fireTimer() - dt); if (fireTimer() < 0.0f) { setFireTimer(0.0f); m_inUse = false; diff --git a/source/game/interfaces/StarFireableItem.hpp b/source/game/interfaces/StarFireableItem.hpp index 1b2c058..4616bad 100644 --- a/source/game/interfaces/StarFireableItem.hpp +++ b/source/game/interfaces/StarFireableItem.hpp @@ -42,7 +42,7 @@ public: virtual void init(ToolUserEntity* owner, ToolHand hand) override; virtual void uninit() override; - virtual void update(FireMode fireMode, bool shifting, HashSet const& moves) override; + virtual void update(float dt, FireMode fireMode, bool shifting, HashSet const& moves) override; virtual List statusEffects() const override; diff --git a/source/game/interfaces/StarToolUserItem.cpp b/source/game/interfaces/StarToolUserItem.cpp index e9354a1..104b513 100644 --- a/source/game/interfaces/StarToolUserItem.cpp +++ b/source/game/interfaces/StarToolUserItem.cpp @@ -14,7 +14,7 @@ void ToolUserItem::uninit() { m_hand = {}; } -void ToolUserItem::update(FireMode, bool, HashSet const&) {} +void ToolUserItem::update(float dt, FireMode, bool, HashSet const&) {} bool ToolUserItem::initialized() const { return (bool)m_owner; diff --git a/source/game/interfaces/StarToolUserItem.hpp b/source/game/interfaces/StarToolUserItem.hpp index 9113ab0..a4318a9 100644 --- a/source/game/interfaces/StarToolUserItem.hpp +++ b/source/game/interfaces/StarToolUserItem.hpp @@ -23,7 +23,7 @@ public: virtual void uninit(); // Default implementation does nothing - virtual void update(FireMode fireMode, bool shifting, HashSet const& moves); + virtual void update(float dt, FireMode fireMode, bool shifting, HashSet const& moves); // Default implementations return empty list virtual List damageSources() const; diff --git a/source/game/items/StarActiveItem.cpp b/source/game/items/StarActiveItem.cpp index 9e7ed3f..49e82be 100644 --- a/source/game/items/StarActiveItem.cpp +++ b/source/game/items/StarActiveItem.cpp @@ -119,7 +119,7 @@ void ActiveItem::uninit() { m_activeAudio.clear(); } -void ActiveItem::update(FireMode fireMode, bool shifting, HashSet const& moves) { +void ActiveItem::update(float dt, FireMode fireMode, bool shifting, HashSet const& moves) { StringMap moveMap; for (auto m : moves) moveMap[MoveControlTypeNames.getRight(m)] = true; @@ -130,7 +130,7 @@ void ActiveItem::update(FireMode fireMode, bool shifting, HashSetisClient(); if (isClient) { - m_itemAnimator.update(WorldTimestep, &m_itemAnimatorDynamicTarget); - m_scriptedAnimator.update(m_scriptedAnimator.updateDt()); + m_itemAnimator.update(dt, &m_itemAnimatorDynamicTarget); + m_scriptedAnimator.update(m_scriptedAnimator.updateDt(dt)); } else { - m_itemAnimator.update(WorldTimestep, nullptr); + m_itemAnimator.update(dt, nullptr); } eraseWhere(m_activeAudio, [this](pair const& a) { diff --git a/source/game/items/StarActiveItem.hpp b/source/game/items/StarActiveItem.hpp index 61c0e70..130b378 100644 --- a/source/game/items/StarActiveItem.hpp +++ b/source/game/items/StarActiveItem.hpp @@ -30,7 +30,7 @@ public: void init(ToolUserEntity* owner, ToolHand hand) override; void uninit() override; - void update(FireMode fireMode, bool shifting, HashSet const& moves) override; + void update(float dt, FireMode fireMode, bool shifting, HashSet const& moves) override; List damageSources() const override; List shieldPolys() const override; diff --git a/source/game/items/StarConsumableItem.cpp b/source/game/items/StarConsumableItem.cpp index 53729b1..83a06b9 100644 --- a/source/game/items/StarConsumableItem.cpp +++ b/source/game/items/StarConsumableItem.cpp @@ -35,8 +35,8 @@ List ConsumableItem::drawables() const { return drawables; } -void ConsumableItem::update(FireMode fireMode, bool shifting, HashSet const& moves) { - SwingableItem::update(fireMode, shifting, moves); +void ConsumableItem::update(float dt, FireMode fireMode, bool shifting, HashSet const& moves) { + SwingableItem::update(dt, fireMode, shifting, moves); if (entityMode() == EntityMode::Master) { if (m_consuming) diff --git a/source/game/items/StarConsumableItem.hpp b/source/game/items/StarConsumableItem.hpp index 0596b61..b0d0721 100644 --- a/source/game/items/StarConsumableItem.hpp +++ b/source/game/items/StarConsumableItem.hpp @@ -15,7 +15,7 @@ public: List drawables() const override; - void update(FireMode fireMode, bool shifting, HashSet const& moves) override; + void update(float dt, FireMode fireMode, bool shifting, HashSet const& moves) override; void fire(FireMode mode, bool shifting, bool edgeTriggered) override; void fireTriggered() override; void uninit() override; diff --git a/source/game/items/StarInspectionTool.cpp b/source/game/items/StarInspectionTool.cpp index dc16f64..f6936da 100644 --- a/source/game/items/StarInspectionTool.cpp +++ b/source/game/items/StarInspectionTool.cpp @@ -31,7 +31,7 @@ ItemPtr InspectionTool::clone() const { return make_shared(*this); } -void InspectionTool::update(FireMode fireMode, bool, HashSet const&) { +void InspectionTool::update(float dt, FireMode fireMode, bool, HashSet const&) { m_currentAngle = world()->geometry().diff(owner()->aimPosition(), owner()->position()).angle(); m_currentPosition = owner()->position() + owner()->handPosition(hand(), m_lightPosition - m_handPosition); SpatialLogger::logPoint("world", m_currentPosition, {0, 0, 255, 255}); diff --git a/source/game/items/StarInspectionTool.hpp b/source/game/items/StarInspectionTool.hpp index f50935c..7fa7fb2 100644 --- a/source/game/items/StarInspectionTool.hpp +++ b/source/game/items/StarInspectionTool.hpp @@ -27,7 +27,7 @@ public: ItemPtr clone() const override; - void update(FireMode fireMode, bool shifting, HashSet const& moves) override; + void update(float dt, FireMode fireMode, bool shifting, HashSet const& moves) override; List drawables() const override; diff --git a/source/game/items/StarInstrumentItem.cpp b/source/game/items/StarInstrumentItem.cpp index 159212a..f93bca7 100644 --- a/source/game/items/StarInstrumentItem.cpp +++ b/source/game/items/StarInstrumentItem.cpp @@ -42,7 +42,7 @@ StringSet InstrumentItem::effectSources() const { return m_inactiveEffectSources; } -void InstrumentItem::update(FireMode, bool, HashSet const&) { +void InstrumentItem::update(float dt, FireMode, bool, HashSet const&) { if (entityMode() == EntityMode::Master) { if (active()) { m_activeCooldown--; diff --git a/source/game/items/StarInstrumentItem.hpp b/source/game/items/StarInstrumentItem.hpp index 861f681..c57a0ad 100644 --- a/source/game/items/StarInstrumentItem.hpp +++ b/source/game/items/StarInstrumentItem.hpp @@ -29,7 +29,7 @@ public: List statusEffects() const override; StringSet effectSources() const override; - void update(FireMode fireMode, bool shifting, HashSet const& moves) override; + void update(float dt, FireMode fireMode, bool shifting, HashSet const& moves) override; bool active() const override; void setActive(bool active) override; diff --git a/source/game/items/StarLiquidItem.cpp b/source/game/items/StarLiquidItem.cpp index c29f58e..08e202f 100644 --- a/source/game/items/StarLiquidItem.cpp +++ b/source/game/items/StarLiquidItem.cpp @@ -30,9 +30,9 @@ void LiquidItem::init(ToolUserEntity* owner, ToolHand hand) { BeamItem::init(owner, hand); } -void LiquidItem::update(FireMode fireMode, bool shifting, HashSet const& moves) { - FireableItem::update(fireMode, shifting, moves); - BeamItem::update(fireMode, shifting, moves); +void LiquidItem::update(float dt, FireMode fireMode, bool shifting, HashSet const& moves) { + FireableItem::update(dt, fireMode, shifting, moves); + BeamItem::update(dt, fireMode, shifting, moves); if (shifting || !multiplaceEnabled()) setEnd(BeamItem::EndType::Tile); else diff --git a/source/game/items/StarLiquidItem.hpp b/source/game/items/StarLiquidItem.hpp index 35178e8..7550226 100644 --- a/source/game/items/StarLiquidItem.hpp +++ b/source/game/items/StarLiquidItem.hpp @@ -18,7 +18,7 @@ public: ItemPtr clone() const override; void init(ToolUserEntity* owner, ToolHand hand) override; - void update(FireMode fireMode, bool shifting, HashSet const& moves) override; + void update(float dt, FireMode fireMode, bool shifting, HashSet const& moves) override; List nonRotatedDrawables() const override; diff --git a/source/game/items/StarMaterialItem.cpp b/source/game/items/StarMaterialItem.cpp index 73ef1d1..48b5c57 100644 --- a/source/game/items/StarMaterialItem.cpp +++ b/source/game/items/StarMaterialItem.cpp @@ -44,9 +44,9 @@ void MaterialItem::init(ToolUserEntity* owner, ToolHand hand) { BeamItem::init(owner, hand); } -void MaterialItem::update(FireMode fireMode, bool shifting, HashSet const& moves) { - FireableItem::update(fireMode, shifting, moves); - BeamItem::update(fireMode, shifting, moves); +void MaterialItem::update(float dt, FireMode fireMode, bool shifting, HashSet const& moves) { + FireableItem::update(dt, fireMode, shifting, moves); + BeamItem::update(dt, fireMode, shifting, moves); if (shifting || !multiplaceEnabled()) setEnd(BeamItem::EndType::Tile); else diff --git a/source/game/items/StarMaterialItem.hpp b/source/game/items/StarMaterialItem.hpp index 0fe7b03..ed92896 100644 --- a/source/game/items/StarMaterialItem.hpp +++ b/source/game/items/StarMaterialItem.hpp @@ -18,7 +18,7 @@ public: ItemPtr clone() const override; void init(ToolUserEntity* owner, ToolHand hand) override; - void update(FireMode fireMode, bool shifting, HashSet const& moves) override; + void update(float dt, FireMode fireMode, bool shifting, HashSet const& moves) override; List nonRotatedDrawables() const override; diff --git a/source/game/items/StarObjectItem.cpp b/source/game/items/StarObjectItem.cpp index 58547fb..5da5a5a 100644 --- a/source/game/items/StarObjectItem.cpp +++ b/source/game/items/StarObjectItem.cpp @@ -28,9 +28,9 @@ void ObjectItem::init(ToolUserEntity* owner, ToolHand hand) { BeamItem::init(owner, hand); } -void ObjectItem::update(FireMode fireMode, bool shifting, HashSet const& moves) { - FireableItem::update(fireMode, shifting, moves); - BeamItem::update(fireMode, shifting, moves); +void ObjectItem::update(float dt, FireMode fireMode, bool shifting, HashSet const& moves) { + FireableItem::update(dt, fireMode, shifting, moves); + BeamItem::update(dt, fireMode, shifting, moves); setEnd(BeamItem::EndType::Object); m_shifting = shifting; } diff --git a/source/game/items/StarObjectItem.hpp b/source/game/items/StarObjectItem.hpp index 4e3043c..f45d3d6 100644 --- a/source/game/items/StarObjectItem.hpp +++ b/source/game/items/StarObjectItem.hpp @@ -17,7 +17,7 @@ public: ItemPtr clone() const override; void init(ToolUserEntity* owner, ToolHand hand) override; - void update(FireMode fireMode, bool shifting, HashSet const& moves) override; + void update(float dt, FireMode fireMode, bool shifting, HashSet const& moves) override; List nonRotatedDrawables() const override; diff --git a/source/game/items/StarTools.cpp b/source/game/items/StarTools.cpp index 178809d..2e0d994 100644 --- a/source/game/items/StarTools.cpp +++ b/source/game/items/StarTools.cpp @@ -118,11 +118,11 @@ void MiningTool::fire(FireMode mode, bool shifting, bool edgeTriggered) { } } -void MiningTool::update(FireMode mode, bool shifting, HashSet const& moves) { - SwingableItem::update(mode, shifting, moves); +void MiningTool::update(float dt, FireMode mode, bool shifting, HashSet const& moves) { + SwingableItem::update(dt, mode, shifting, moves); if (!ready() && !coolingDown()) - m_frameTiming = std::fmod((m_frameTiming + WorldTimestep), m_frameCycle); + m_frameTiming = std::fmod((m_frameTiming + dt), m_frameCycle); else m_frameTiming = 0; } @@ -200,11 +200,11 @@ void HarvestingTool::fire(FireMode mode, bool shifting, bool edgeTriggered) { } } -void HarvestingTool::update(FireMode fireMode, bool shifting, HashSet const& moves) { - SwingableItem::update(fireMode, shifting, moves); +void HarvestingTool::update(float dt, FireMode fireMode, bool shifting, HashSet const& moves) { + SwingableItem::update(dt, fireMode, shifting, moves); if (!ready() && !coolingDown()) - m_frameTiming = std::fmod((m_frameTiming + WorldTimestep), m_frameCycle); + m_frameTiming = std::fmod((m_frameTiming + dt), m_frameCycle); else m_frameTiming = 0; } @@ -269,9 +269,9 @@ void WireTool::init(ToolUserEntity* owner, ToolHand hand) { m_wireConnector = 0; } -void WireTool::update(FireMode fireMode, bool shifting, HashSet const& moves) { - FireableItem::update(fireMode, shifting, moves); - BeamItem::update(fireMode, shifting, moves); +void WireTool::update(float dt, FireMode fireMode, bool shifting, HashSet const& moves) { + FireableItem::update(dt, fireMode, shifting, moves); + BeamItem::update(dt, fireMode, shifting, moves); } List WireTool::drawables() const { @@ -378,9 +378,9 @@ void BeamMiningTool::init(ToolUserEntity* owner, ToolHand hand) { BeamItem::init(owner, hand); } -void BeamMiningTool::update(FireMode fireMode, bool shifting, HashSet const& moves) { - FireableItem::update(fireMode, shifting, moves); - BeamItem::update(fireMode, shifting, moves); +void BeamMiningTool::update(float dt, FireMode fireMode, bool shifting, HashSet const& moves) { + FireableItem::update(dt, fireMode, shifting, moves); + BeamItem::update(dt, fireMode, shifting, moves); } List BeamMiningTool::statusEffects() const { @@ -567,11 +567,11 @@ void TillingTool::fire(FireMode mode, bool shifting, bool edgeTriggered) { } } -void TillingTool::update(FireMode fireMode, bool shifting, HashSet const& moves) { - SwingableItem::update(fireMode, shifting, moves); +void TillingTool::update(float dt, FireMode fireMode, bool shifting, HashSet const& moves) { + SwingableItem::update(dt, fireMode, shifting, moves); if (!ready() && !coolingDown()) - m_frameTiming = std::fmod((m_frameTiming + WorldTimestep), m_frameCycle); + m_frameTiming = std::fmod((m_frameTiming + dt), m_frameCycle); else m_frameTiming = 0; } @@ -620,9 +620,9 @@ void PaintingBeamTool::setEnd(EndType type) { m_endType = EndType::Object; } -void PaintingBeamTool::update(FireMode fireMode, bool shifting, HashSet const& moves) { - BeamItem::update(fireMode, shifting, moves); - FireableItem::update(fireMode, shifting, moves); +void PaintingBeamTool::update(float dt, FireMode fireMode, bool shifting, HashSet const& moves) { + BeamItem::update(dt, fireMode, shifting, moves); + FireableItem::update(dt, fireMode, shifting, moves); } List PaintingBeamTool::preview(bool shifting) const { diff --git a/source/game/items/StarTools.hpp b/source/game/items/StarTools.hpp index cd2441b..fbe79a0 100644 --- a/source/game/items/StarTools.hpp +++ b/source/game/items/StarTools.hpp @@ -34,7 +34,7 @@ public: // In pixels, offset from image center Vec2F handPosition() const override; void fire(FireMode mode, bool shifting, bool edgeTriggered) override; - void update(FireMode fireMode, bool shifting, HashSet const& moves) override; + void update(float dt, FireMode fireMode, bool shifting, HashSet const& moves) override; float durabilityStatus() override; @@ -72,7 +72,7 @@ public: // In pixels, offset from image center Vec2F handPosition() const override; void fire(FireMode mode, bool shifting, bool edgeTriggered) override; - void update(FireMode fireMode, bool shifting, HashSet const& moves) override; + void update(float dt, FireMode fireMode, bool shifting, HashSet const& moves) override; float getAngle(float aimAngle) override; private: @@ -117,7 +117,7 @@ public: ItemPtr clone() const override; void init(ToolUserEntity* owner, ToolHand hand) override; - void update(FireMode fireMode, bool shifting, HashSet const& moves) override; + void update(float dt, FireMode fireMode, bool shifting, HashSet const& moves) override; List drawables() const override; List nonRotatedDrawables() const override; @@ -157,7 +157,7 @@ public: float getAngle(float angle) override; void init(ToolUserEntity* owner, ToolHand hand) override; - void update(FireMode fireMode, bool shifting, HashSet const& moves) override; + void update(float dt, FireMode fireMode, bool shifting, HashSet const& moves) override; List statusEffects() const override; @@ -186,7 +186,7 @@ public: // In pixels, offset from image center Vec2F handPosition() const override; void fire(FireMode mode, bool shifting, bool edgeTriggered) override; - void update(FireMode fireMode, bool shifting, HashSet const& moves) override; + void update(float dt, FireMode fireMode, bool shifting, HashSet const& moves) override; float getAngle(float aimAngle) override; private: @@ -218,7 +218,7 @@ public: List drawables() const override; void setEnd(EndType type) override; - void update(FireMode fireMode, bool shifting, HashSet const& moves) override; + void update(float dt, FireMode fireMode, bool shifting, HashSet const& moves) override; List preview(bool shifting) const override; void init(ToolUserEntity* owner, ToolHand hand) override; List nonRotatedDrawables() const override; diff --git a/source/game/objects/StarContainerObject.cpp b/source/game/objects/StarContainerObject.cpp index d013a3b..f666902 100644 --- a/source/game/objects/StarContainerObject.cpp +++ b/source/game/objects/StarContainerObject.cpp @@ -64,15 +64,15 @@ void ContainerObject::init(World* world, EntityId entityId, EntityMode mode) { } } -void ContainerObject::update(uint64_t currentStep) { - Object::update(currentStep); +void ContainerObject::update(float dt, uint64_t currentStep) { + Object::update(dt, currentStep); if (isMaster()) { for (auto const& drop : take(m_lostItems)) world()->addEntity(ItemDrop::createRandomizedDrop(drop, position())); if (m_crafting.get()) - tickCrafting(); + tickCrafting(dt); if (m_autoCloseCooldown > 0) { m_autoCloseCooldown -= 1; @@ -453,7 +453,7 @@ ItemRecipe ContainerObject::recipeForMaterials(List const& inputItems) return itemDatabase->parseRecipe(*result); } -void ContainerObject::tickCrafting() { +void ContainerObject::tickCrafting(float dt) { if (!m_crafting.get()) return; @@ -477,7 +477,7 @@ void ContainerObject::tickCrafting() { return; } if (m_goalRecipe.duration > 0) - m_craftingProgress.set(m_craftingProgress.get() + WorldTimestep / m_goalRecipe.duration); + m_craftingProgress.set(m_craftingProgress.get() + dt / m_goalRecipe.duration); else m_craftingProgress.set(1.0f); if (m_craftingProgress.get() >= 1.0f) { diff --git a/source/game/objects/StarContainerObject.hpp b/source/game/objects/StarContainerObject.hpp index b6033ea..482e502 100644 --- a/source/game/objects/StarContainerObject.hpp +++ b/source/game/objects/StarContainerObject.hpp @@ -17,7 +17,7 @@ public: void init(World* world, EntityId entityId, EntityMode mode) override; - void update(uint64_t currentStep) override; + void update(float dt, uint64_t currentStep) override; void render(RenderCallback* renderCallback) override; void destroy(RenderCallback* renderCallback) override; @@ -62,7 +62,7 @@ private: typedef std::function ContainerCallback; ItemRecipe recipeForMaterials(List const& inputItems); - void tickCrafting(); + void tickCrafting(float dt); ItemPtr doAddItems(ItemPtr const& items); ItemPtr doStackItems(ItemPtr const& items); diff --git a/source/game/objects/StarFarmableObject.cpp b/source/game/objects/StarFarmableObject.cpp index d8855bf..8504b64 100644 --- a/source/game/objects/StarFarmableObject.cpp +++ b/source/game/objects/StarFarmableObject.cpp @@ -33,8 +33,8 @@ FarmableObject::FarmableObject(ObjectConfigConstPtr config, Json const& paramete m_consumeSoilMoisture = configValue("consumeSoilMoisture", true).toBool(); } -void FarmableObject::update(uint64_t currentStep) { - Object::update(currentStep); +void FarmableObject::update(float dt, uint64_t currentStep) { + Object::update(dt, currentStep); if (isMaster()) { if (m_nextStageTime == 0) { diff --git a/source/game/objects/StarFarmableObject.hpp b/source/game/objects/StarFarmableObject.hpp index f70aa35..b3768bf 100644 --- a/source/game/objects/StarFarmableObject.hpp +++ b/source/game/objects/StarFarmableObject.hpp @@ -9,7 +9,7 @@ class FarmableObject : public Object { public: FarmableObject(ObjectConfigConstPtr config, Json const& parameters); - void update(uint64_t currentStep) override; + void update(float dt, uint64_t currentStep) override; bool damageTiles(List const& position, Vec2F const& sourcePosition, TileDamage const& tileDamage) override; InteractAction interact(InteractRequest const& request) override; diff --git a/source/game/objects/StarPhysicsObject.cpp b/source/game/objects/StarPhysicsObject.cpp index 7824333..6b667a5 100644 --- a/source/game/objects/StarPhysicsObject.cpp +++ b/source/game/objects/StarPhysicsObject.cpp @@ -76,8 +76,8 @@ void PhysicsObject::uninit() { Object::uninit(); } -void PhysicsObject::update(uint64_t currentStep) { - Object::update(currentStep); +void PhysicsObject::update(float dt, uint64_t currentStep) { + Object::update(dt, currentStep); if (isSlave()) m_netGroup.tickNetInterpolation(WorldTimestep); } diff --git a/source/game/objects/StarPhysicsObject.hpp b/source/game/objects/StarPhysicsObject.hpp index 7f582b8..98fd4b3 100644 --- a/source/game/objects/StarPhysicsObject.hpp +++ b/source/game/objects/StarPhysicsObject.hpp @@ -16,7 +16,7 @@ public: void init(World* world, EntityId entityId, EntityMode mode) override; void uninit() override; - void update(uint64_t currentStep) override; + void update(float dt, uint64_t currentStep) override; RectF metaBoundBox() const override; diff --git a/source/game/scripting/StarInputLuaBindings.cpp b/source/game/scripting/StarInputLuaBindings.cpp index 9f58a40..df2e3e5 100644 --- a/source/game/scripting/StarInputLuaBindings.cpp +++ b/source/game/scripting/StarInputLuaBindings.cpp @@ -13,7 +13,7 @@ LuaCallbacks LuaBindings::makeInputCallbacks() { callbacks.registerCallbackWithSignature("bindHeld", bind(mem_fn(&Input::bindHeld), input, _1, _2)); callbacks.registerCallbackWithSignature, String, String>("bindUp", bind(mem_fn(&Input::bindUp), input, _1, _2)); - callbacks.registerCallback("keyDown", [input](String const& keyName, Maybe& const modNames) -> Maybe { + callbacks.registerCallback("keyDown", [input](String const& keyName, Maybe const& modNames) -> Maybe { Key key = KeyNames.getLeft(keyName); Maybe mod; if (modNames) { diff --git a/source/game/scripting/StarLuaComponents.hpp b/source/game/scripting/StarLuaComponents.hpp index bc00309..7e30c39 100644 --- a/source/game/scripting/StarLuaComponents.hpp +++ b/source/game/scripting/StarLuaComponents.hpp @@ -130,6 +130,7 @@ public: LuaUpdatableComponent(); unsigned updateDelta() const; + float updateDt(float dt) const; float updateDt() const; void setUpdateDelta(unsigned updateDelta); @@ -142,6 +143,7 @@ public: private: Periodic m_updatePeriodic; + mutable float m_lastDt; }; // Wraps a basic lua component so that world callbacks are added on init, and @@ -253,10 +255,17 @@ unsigned LuaUpdatableComponent::updateDelta() const { } template -float LuaUpdatableComponent::updateDt() const { - return m_updatePeriodic.stepCount() * WorldTimestep; +float LuaUpdatableComponent::updateDt(float dt) const { + m_lastDt = dt; + return m_updatePeriodic.stepCount() * dt; } +template +float LuaUpdatableComponent::updateDt() const { + return m_updatePeriodic.stepCount() * m_lastDt; +} + + template void LuaUpdatableComponent::setUpdateDelta(unsigned updateDelta) { m_updatePeriodic.setStepCount(updateDelta); diff --git a/source/rendering/StarEnvironmentPainter.cpp b/source/rendering/StarEnvironmentPainter.cpp index aa2763b..816281b 100644 --- a/source/rendering/StarEnvironmentPainter.cpp +++ b/source/rendering/StarEnvironmentPainter.cpp @@ -29,16 +29,13 @@ EnvironmentPainter::EnvironmentPainter(RendererPtr renderer) { m_renderer = move(renderer); m_textureGroup = make_shared(m_renderer->createTextureGroup(TextureGroupSize::Large)); m_timer = 0; - m_lastTime = 0; m_rayPerlin = PerlinF(1, RayPerlinFrequency, RayPerlinAmplitude, 0, 2.0f, 2.0f, Random::randu64()); } -void EnvironmentPainter::update() { +void EnvironmentPainter::update(float dt) { // Allows the rays to change alpha with time. - int64_t currentTime = Time::monotonicMilliseconds(); - m_timer += (currentTime - m_lastTime) / 1000.0; + m_timer += dt; m_timer = std::fmod(m_timer, Constants::pi * 100000.0); - m_lastTime = currentTime; } void EnvironmentPainter::renderStars(float pixelRatio, Vec2F const& screenSize, SkyRenderData const& sky) { diff --git a/source/rendering/StarEnvironmentPainter.hpp b/source/rendering/StarEnvironmentPainter.hpp index 3a90b69..4b9fdb8 100644 --- a/source/rendering/StarEnvironmentPainter.hpp +++ b/source/rendering/StarEnvironmentPainter.hpp @@ -17,7 +17,7 @@ class EnvironmentPainter { public: EnvironmentPainter(RendererPtr renderer); - void update(); + void update(float dt); void renderStars(float pixelRatio, Vec2F const& screenSize, SkyRenderData const& sky); void renderDebrisFields(float pixelRatio, Vec2F const& screenSize, SkyRenderData const& sky); @@ -67,7 +67,6 @@ private: AssetTextureGroupPtr m_textureGroup; double m_timer; - int64_t m_lastTime; PerlinF m_rayPerlin; uint64_t m_starsHash; diff --git a/source/rendering/StarWorldPainter.cpp b/source/rendering/StarWorldPainter.cpp index e033ee1..d89cfe1 100644 --- a/source/rendering/StarWorldPainter.cpp +++ b/source/rendering/StarWorldPainter.cpp @@ -45,14 +45,16 @@ WorldCamera& WorldPainter::camera() { return m_camera; } +void WorldPainter::update(float dt) { + m_environmentPainter->update(dt); +} + void WorldPainter::render(WorldRenderData& renderData, function lightWaiter) { m_camera.setScreenSize(m_renderer->screenSize()); m_camera.setTargetPixelRatio(Root::singleton().configuration()->get("zoomLevel").toFloat()); m_assets = Root::singleton().assets(); - m_environmentPainter->update(); - m_tilePainter->setup(m_camera, renderData); // Stars, Debris Fields, Sky, and Orbiters diff --git a/source/rendering/StarWorldPainter.hpp b/source/rendering/StarWorldPainter.hpp index 0ae6a7d..ce7f1d8 100644 --- a/source/rendering/StarWorldPainter.hpp +++ b/source/rendering/StarWorldPainter.hpp @@ -23,6 +23,7 @@ public: WorldCamera& camera(); + void update(float dt); void render(WorldRenderData& renderData, function lightWaiter); void adjustLighting(WorldRenderData& renderData); diff --git a/source/server/main.cpp b/source/server/main.cpp index 08b55dd..ad16988 100644 --- a/source/server/main.cpp +++ b/source/server/main.cpp @@ -50,7 +50,7 @@ int main(int argc, char** argv) { float updateRate = 1.0f / WorldTimestep; if (auto jUpdateRate = configuration->get("updateRate")) { updateRate = jUpdateRate.toFloat(); - WorldTimestep = 1.0f / updateRate; + ServerWorldTimestep = WorldTimestep = 1.0f / updateRate; Logger::info("Configured tickrate is {:4.2f}hz", updateRate); } diff --git a/source/windowing/StarFlowLayout.cpp b/source/windowing/StarFlowLayout.cpp index 714d159..604e1d0 100644 --- a/source/windowing/StarFlowLayout.cpp +++ b/source/windowing/StarFlowLayout.cpp @@ -4,8 +4,8 @@ namespace Star { FlowLayout::FlowLayout() : m_wrap(true) {} -void FlowLayout::update() { - Layout::update(); +void FlowLayout::update(float dt) { + Layout::update(dt); int consumedWidth = 0; int rowHeight = 0; diff --git a/source/windowing/StarFlowLayout.hpp b/source/windowing/StarFlowLayout.hpp index ef20e9a..86127c6 100644 --- a/source/windowing/StarFlowLayout.hpp +++ b/source/windowing/StarFlowLayout.hpp @@ -11,7 +11,7 @@ STAR_CLASS(FlowLayout); class FlowLayout : public Layout { public: FlowLayout(); - virtual void update() override; + virtual void update(float dt) override; void setSpacing(Vec2I const& spacing); void setWrapping(bool wrap); diff --git a/source/windowing/StarFuelWidget.cpp b/source/windowing/StarFuelWidget.cpp index af51cb2..d7028f8 100644 --- a/source/windowing/StarFuelWidget.cpp +++ b/source/windowing/StarFuelWidget.cpp @@ -21,9 +21,8 @@ FuelWidget::FuelWidget() { disableScissoring(); } -void FuelWidget::update() { - m_pingTimeout -= WorldTimestep; - if (m_pingTimeout < 0) +void FuelWidget::update(float dt) { + if ((m_pingTimeout -= dt) < 0) m_pingTimeout = 0; } diff --git a/source/windowing/StarFuelWidget.hpp b/source/windowing/StarFuelWidget.hpp index 8d3482a..3a7f506 100644 --- a/source/windowing/StarFuelWidget.hpp +++ b/source/windowing/StarFuelWidget.hpp @@ -12,7 +12,7 @@ public: FuelWidget(); virtual ~FuelWidget() {} - virtual void update(); + virtual void update(float dt); void setCurrentFuelLevel(float amount); void setMaxFuelLevel(float amount); diff --git a/source/windowing/StarItemSlotWidget.cpp b/source/windowing/StarItemSlotWidget.cpp index cc9ff50..4d67175 100644 --- a/source/windowing/StarItemSlotWidget.cpp +++ b/source/windowing/StarItemSlotWidget.cpp @@ -56,8 +56,12 @@ ItemSlotWidget::ItemSlotWidget(ItemPtr const& item, String const& backingImage) disableScissoring(); } -void ItemSlotWidget::update() { - Widget::update(); +void ItemSlotWidget::update(float dt) { + if (m_item) + m_newItemIndicator.update(dt); + if (m_highlightEnabled) + m_highlightAnimation.update(dt); + Widget::update(dt); } bool ItemSlotWidget::sendEvent(InputEvent const& event) { @@ -159,7 +163,6 @@ void ItemSlotWidget::renderImpl() { for (auto i : iconDrawables) context()->drawInterfaceDrawable(i, Vec2F(screenPosition() + size() / 2)); - m_newItemIndicator.update(WorldTimestep); if (!m_newItemIndicator.isComplete()) context()->drawInterfaceDrawable(m_newItemIndicator.drawable(1.0), Vec2F(screenPosition() + size() / 2), Color::White.toRgba()); @@ -195,7 +198,6 @@ void ItemSlotWidget::renderImpl() { } if (m_highlightEnabled) { - m_highlightAnimation.update(WorldTimestep); context()->drawInterfaceDrawable(m_highlightAnimation.drawable(1.0), Vec2F(screenPosition() + size() / 2), Color::White.toRgba()); } diff --git a/source/windowing/StarItemSlotWidget.hpp b/source/windowing/StarItemSlotWidget.hpp index 31df876..2e1b69a 100644 --- a/source/windowing/StarItemSlotWidget.hpp +++ b/source/windowing/StarItemSlotWidget.hpp @@ -16,7 +16,7 @@ class ItemSlotWidget : public Widget { public: ItemSlotWidget(ItemPtr const& item, String const& backingImage); - virtual void update() override; + virtual void update(float dt) override; bool sendEvent(InputEvent const& event) override; void setCallback(WidgetCallbackFunc callback); void setRightClickCallback(WidgetCallbackFunc callback); diff --git a/source/windowing/StarLayout.cpp b/source/windowing/StarLayout.cpp index fb8a8fd..b404f12 100644 --- a/source/windowing/StarLayout.cpp +++ b/source/windowing/StarLayout.cpp @@ -6,8 +6,8 @@ Layout::Layout() { markAsContainer(); } -void Layout::update() { - Widget::update(); +void Layout::update(float dt) { + Widget::update(dt); } } diff --git a/source/windowing/StarLayout.hpp b/source/windowing/StarLayout.hpp index f199891..6fc68da 100644 --- a/source/windowing/StarLayout.hpp +++ b/source/windowing/StarLayout.hpp @@ -8,7 +8,7 @@ namespace Star { class Layout : public Widget { public: Layout(); - virtual void update() override; + virtual void update(float dt) override; }; } diff --git a/source/windowing/StarPane.cpp b/source/windowing/StarPane.cpp index 04739cb..cac12a1 100644 --- a/source/windowing/StarPane.cpp +++ b/source/windowing/StarPane.cpp @@ -191,10 +191,10 @@ Pane* Pane::window() { return this; } -void Pane::update() { +void Pane::update(float dt) { if (m_visible) { for (auto const& widget : m_members) { - widget->update(); + widget->update(dt); if ((m_focusWidget == widget) != widget->hasFocus()) { m_focusWidget.reset(); widget->blur(); @@ -203,7 +203,7 @@ void Pane::update() { } } -void Pane::tick() { +void Pane::tick(float dt) { m_playingSounds.filter([](pair const& p) { return p.second->finished() == false; }); diff --git a/source/windowing/StarPane.hpp b/source/windowing/StarPane.hpp index 7a466b4..3a20ce0 100644 --- a/source/windowing/StarPane.hpp +++ b/source/windowing/StarPane.hpp @@ -52,8 +52,8 @@ public: virtual void removeFocus(Widget const* focus); virtual void removeFocus(); - virtual void update(); - virtual void tick(); + virtual void update(float dt); + virtual void tick(float dt); bool dragActive() const; Vec2I dragMouseOrigin() const; diff --git a/source/windowing/StarPaneManager.cpp b/source/windowing/StarPaneManager.cpp index ff0341f..f34c786 100644 --- a/source/windowing/StarPaneManager.cpp +++ b/source/windowing/StarPaneManager.cpp @@ -244,7 +244,7 @@ void PaneManager::render() { m_prevInterfaceScale = m_context->interfaceScale(); } -void PaneManager::update() { +void PaneManager::update(float dt) { m_tooltipShowTimer -= WorldTimestep; if (m_tooltipShowTimer < 0 && !m_activeTooltip) { if (auto parentPane = getPaneAt(m_tooltipLastMousePos)) { @@ -287,9 +287,9 @@ void PaneManager::update() { for (auto const& layerPair : reverseIterate(m_displayedPanes)) { for (auto const& panePair : reverseIterate(layerPair.second)) { - panePair.first->tick(); + panePair.first->tick(dt); if (panePair.first->active()) - panePair.first->update(); + panePair.first->update(dt); } } } diff --git a/source/windowing/StarPaneManager.hpp b/source/windowing/StarPaneManager.hpp index cdc6901..8adf772 100644 --- a/source/windowing/StarPaneManager.hpp +++ b/source/windowing/StarPaneManager.hpp @@ -72,7 +72,7 @@ public: bool sendInputEvent(InputEvent const& event); void render(); - void update(); + void update(float dt); private: Vec2I windowSize() const; diff --git a/source/windowing/StarScrollArea.cpp b/source/windowing/StarScrollArea.cpp index d9f537a..4cd2ba6 100644 --- a/source/windowing/StarScrollArea.cpp +++ b/source/windowing/StarScrollArea.cpp @@ -384,7 +384,7 @@ bool ScrollArea::sendEvent(InputEvent const& event) { return true; } -void ScrollArea::update() { +void ScrollArea::update(float dt) { if (!m_visible) return; diff --git a/source/windowing/StarScrollArea.hpp b/source/windowing/StarScrollArea.hpp index 5e7cb7a..1500744 100644 --- a/source/windowing/StarScrollArea.hpp +++ b/source/windowing/StarScrollArea.hpp @@ -100,7 +100,7 @@ public: void setVerticalScroll(bool vertical); virtual bool sendEvent(InputEvent const& event) override; - virtual void update() override; + virtual void update(float dt) override; protected: void drawChildren() override; diff --git a/source/windowing/StarSliderBar.cpp b/source/windowing/StarSliderBar.cpp index e25ed4f..209c325 100644 --- a/source/windowing/StarSliderBar.cpp +++ b/source/windowing/StarSliderBar.cpp @@ -126,7 +126,7 @@ void SliderBarWidget::setCallback(WidgetCallbackFunc callback) { m_callback = callback; } -void SliderBarWidget::update() { +void SliderBarWidget::update(float dt) { float gridLow = m_grid->position()[0]; float gridHigh = gridLow + m_grid->size()[0]; @@ -145,7 +145,7 @@ void SliderBarWidget::update() { m_updateJog = false; } - Widget::update(); + Widget::update(dt); } bool SliderBarWidget::sendEvent(InputEvent const& event) { diff --git a/source/windowing/StarSliderBar.hpp b/source/windowing/StarSliderBar.hpp index ec298c6..9555331 100644 --- a/source/windowing/StarSliderBar.hpp +++ b/source/windowing/StarSliderBar.hpp @@ -24,7 +24,7 @@ public: void setCallback(WidgetCallbackFunc callback); - virtual void update() override; + virtual void update(float dt) override; virtual bool sendEvent(InputEvent const& event) override; diff --git a/source/windowing/StarTextBoxWidget.cpp b/source/windowing/StarTextBoxWidget.cpp index bc64d37..28d8f8b 100644 --- a/source/windowing/StarTextBoxWidget.cpp +++ b/source/windowing/StarTextBoxWidget.cpp @@ -124,8 +124,8 @@ int TextBoxWidget::getCursorOffset() { // horizontal only } } -void TextBoxWidget::update() { - Widget::update(); +void TextBoxWidget::update(float dt) { + Widget::update(dt); if (m_repeatCode != SpecialRepeatKeyCodes::None) { if (Time::monotonicMilliseconds() >= m_repeatKeyThreshold) { m_repeatKeyThreshold += 50; diff --git a/source/windowing/StarTextBoxWidget.hpp b/source/windowing/StarTextBoxWidget.hpp index b075e6b..a2ed8f7 100644 --- a/source/windowing/StarTextBoxWidget.hpp +++ b/source/windowing/StarTextBoxWidget.hpp @@ -12,7 +12,7 @@ class TextBoxWidget : public Widget { public: TextBoxWidget(String const& startingText, String const& hint, WidgetCallbackFunc callback); - virtual void update() override; + virtual void update(float dt) override; String getText() const; bool setText(String const& text, bool callback = true); diff --git a/source/windowing/StarVerticalLayout.cpp b/source/windowing/StarVerticalLayout.cpp index d421a29..412fce0 100644 --- a/source/windowing/StarVerticalLayout.cpp +++ b/source/windowing/StarVerticalLayout.cpp @@ -9,7 +9,7 @@ VerticalLayout::VerticalLayout(VerticalAnchor verticalAnchor, int verticalSpacin disableScissoring(); } -void VerticalLayout::update() { +void VerticalLayout::update(float dt) { m_size = Vec2I(0, 0); if (m_members.empty()) @@ -64,22 +64,22 @@ RectI VerticalLayout::relativeBoundRect() const { void VerticalLayout::setHorizontalAnchor(HorizontalAnchor horizontalAnchor) { m_horizontalAnchor = horizontalAnchor; - update(); + update(0); } void VerticalLayout::setVerticalAnchor(VerticalAnchor verticalAnchor) { m_verticalAnchor = verticalAnchor; - update(); + update(0); } void VerticalLayout::setVerticalSpacing(int verticalSpacing) { m_verticalSpacing = verticalSpacing; - update(); + update(0); } void VerticalLayout::setFillDown(bool fillDown) { m_fillDown = fillDown; - update(); + update(0); } RectI VerticalLayout::contentBoundRect() const { diff --git a/source/windowing/StarVerticalLayout.hpp b/source/windowing/StarVerticalLayout.hpp index 70be40b..b46ce17 100644 --- a/source/windowing/StarVerticalLayout.hpp +++ b/source/windowing/StarVerticalLayout.hpp @@ -11,7 +11,7 @@ class VerticalLayout : public Layout { public: VerticalLayout(VerticalAnchor verticalAnchor = VerticalAnchor::TopAnchor, int verticalSpacing = 0); - void update() override; + void update(float dt) override; Vec2I size() const override; RectI relativeBoundRect() const override; diff --git a/source/windowing/StarWidget.cpp b/source/windowing/StarWidget.cpp index 518b922..48b945f 100644 --- a/source/windowing/StarWidget.cpp +++ b/source/windowing/StarWidget.cpp @@ -20,9 +20,9 @@ Widget::~Widget() { removeAllChildren(); } -void Widget::update() { - for (auto widget : m_members) - widget->update(); +void Widget::update(float dt) { + for (auto& widget : m_members) + widget->update(dt); } GuiContext* Widget::context() const { diff --git a/source/windowing/StarWidget.hpp b/source/windowing/StarWidget.hpp index 84fada5..a9ea4ac 100644 --- a/source/windowing/StarWidget.hpp +++ b/source/windowing/StarWidget.hpp @@ -30,7 +30,7 @@ public: Widget& operator=(Widget const&) = delete; virtual void render(RectI const& region) final; - virtual void update(); + virtual void update(float dt); GuiContext* context() const; diff --git a/source/windowing/StarWidgetParsing.cpp b/source/windowing/StarWidgetParsing.cpp index 9afb825..b45294b 100644 --- a/source/windowing/StarWidgetParsing.cpp +++ b/source/windowing/StarWidgetParsing.cpp @@ -694,7 +694,7 @@ WidgetConstructResult WidgetParser::layoutHandler(String const& name, Json const common(widget, config); if (config.contains("children")) constructImpl(config.get("children"), widget.get()); - widget->update(); + widget->update(0); return WidgetConstructResult(widget, name, config.getFloat("zlevel", 0)); }