From a372783a82e61c883e8a33a1f8e784d1c257c2cf Mon Sep 17 00:00:00 2001 From: Moritz Baron Date: Tue, 11 Jun 2024 21:24:52 +0200 Subject: [PATCH] bugfixes --- .../mods/ImmersiveTravelAddonWorld/main.lua | 5 +- .../mods/ImmersiveTravel/GTrackingManager.lua | 4 +- .../Statemachine/ai/CAiState.lua | 4 +- .../Statemachine/ai/PlayerTravelState.lua | 52 ++++++++++++------- .../locomotion/CLocomotionState.lua | 2 - .../ImmersiveTravel/Vehicles/CVehicle.lua | 34 ++++++++++-- 6 files changed, 70 insertions(+), 31 deletions(-) diff --git a/Immersive Travel Addon - World/MWSE/mods/ImmersiveTravelAddonWorld/main.lua b/Immersive Travel Addon - World/MWSE/mods/ImmersiveTravelAddonWorld/main.lua index 1ee5707..ef8ed89 100644 --- a/Immersive Travel Addon - World/MWSE/mods/ImmersiveTravelAddonWorld/main.lua +++ b/Immersive Travel Addon - World/MWSE/mods/ImmersiveTravelAddonWorld/main.lua @@ -174,7 +174,10 @@ local function cellChangedCallback(e) -- delete all vehicles for id, s in pairs(GTrackingManager.getInstance().trackingList) do local vehicle = s ---@cast vehicle CVehicle - vehicle.markForDelete = true + -- only mark vehicles that are in onspline ai state + if vehicle.aiStateMachine and vehicle:isOnSpline() then + vehicle.markForDelete = true + end end return diff --git a/ImmersiveTravel/00 Core/MWSE/mods/ImmersiveTravel/GTrackingManager.lua b/ImmersiveTravel/00 Core/MWSE/mods/ImmersiveTravel/GTrackingManager.lua index 4e95777..5c99ef7 100644 --- a/ImmersiveTravel/00 Core/MWSE/mods/ImmersiveTravel/GTrackingManager.lua +++ b/ImmersiveTravel/00 Core/MWSE/mods/ImmersiveTravel/GTrackingManager.lua @@ -231,14 +231,14 @@ function TrackingManager:doCull() -- only cull vehicles that are in onspline ai state if vehicle.aiStateMachine and vehicle.aiStateMachine.currentState.name == CAiState.ONSPLINE then if not vehicle:GetRootBone() then - log:warn("No root bone %s", s:Id()) + log:debug("doCull No root bone %s", s:Id()) table.insert(toremove, s) goto continue end local d = tes3.player.position:distance(vehicle.last_position) if d > self.cullRadius * 8192 then - log:debug("Culled out of distance %s", s:Id()) + log:debug("doCull Culled out of distance %s", s:Id()) table.insert(toremove, s) goto continue end diff --git a/ImmersiveTravel/00 Core/MWSE/mods/ImmersiveTravel/Statemachine/ai/CAiState.lua b/ImmersiveTravel/00 Core/MWSE/mods/ImmersiveTravel/Statemachine/ai/CAiState.lua index d9fc913..140882d 100644 --- a/ImmersiveTravel/00 Core/MWSE/mods/ImmersiveTravel/Statemachine/ai/CAiState.lua +++ b/ImmersiveTravel/00 Core/MWSE/mods/ImmersiveTravel/Statemachine/ai/CAiState.lua @@ -30,7 +30,7 @@ end ---@return boolean function CAiState.ToNone(ctx) local vehicle = ctx.scriptedObject ---@cast vehicle CVehicle - return not vehicle.routeId and not vehicle.playerRegistered and not vehicle:isPlayerInGuideSlot() + return not vehicle.routeId and not vehicle:isPlayerInGuideSlot() end ---transition to ONSPLINE state if routeId is not nil @@ -38,7 +38,7 @@ end ---@return boolean? function CAiState.ToOnSpline(ctx) local vehicle = ctx.scriptedObject ---@cast vehicle CVehicle - return vehicle.routeId and not vehicle.playerRegistered and not vehicle:isPlayerInGuideSlot() + return vehicle.routeId and not vehicle:isPlayerInGuideSlot() and not vehicle.playerRegistered end ---transition to player steer state if player is in guide slot diff --git a/ImmersiveTravel/00 Core/MWSE/mods/ImmersiveTravel/Statemachine/ai/PlayerTravelState.lua b/ImmersiveTravel/00 Core/MWSE/mods/ImmersiveTravel/Statemachine/ai/PlayerTravelState.lua index 97d82af..12c2190 100644 --- a/ImmersiveTravel/00 Core/MWSE/mods/ImmersiveTravel/Statemachine/ai/PlayerTravelState.lua +++ b/ImmersiveTravel/00 Core/MWSE/mods/ImmersiveTravel/Statemachine/ai/PlayerTravelState.lua @@ -112,6 +112,21 @@ local function uiShowRestMenuCallback(e) -- then to destination -- this pushes the AI statemachine vehicle.routeId = nil + + timer.start({ + type = timer.simulate, + duration = 1, + callback = (function() + tes3.fadeIn() + + lib.teleportToClosestMarker() + + vehicle:EndPlayerTravel() + + vehicle:Delete() + GPlayerVehicleManager.getInstance().trackedVehicle = nil + end) + }) end end) }) @@ -212,10 +227,26 @@ function PlayerTravelState:update(dt, scriptedObject) local spline = GRoutesManager.getInstance().routes[vehicle.routeId] if spline == nil then vehicle.routeId = nil - end - if vehicle.splineIndex > #spline then + elseif vehicle.splineIndex > #spline then -- reached end of route vehicle.routeId = nil + + tes3.fadeOut() + + timer.start({ + type = timer.simulate, + duration = 1, + callback = (function() + tes3.fadeIn() + + lib.teleportToClosestMarker() + + vehicle:EndPlayerTravel() + + vehicle:Delete() + GPlayerVehicleManager.getInstance().trackedVehicle = nil + end) + }) end -- handle player leaving vehicle @@ -238,23 +269,6 @@ function PlayerTravelState:exit(scriptedObject) event.unregister(tes3.event.activate, activateCallback) event.unregister(tes3.event.keyDown, keyDownCallback) event.unregister(tes3.event.uiShowRestMenu, uiShowRestMenuCallback) - - tes3.fadeOut() - - timer.start({ - type = timer.simulate, - duration = 1, - callback = (function() - tes3.fadeIn() - - lib.teleportToClosestMarker() - - vehicle:EndPlayerTravel() - - vehicle:Delete() - GPlayerVehicleManager.getInstance().trackedVehicle = nil - end) - }) end return PlayerTravelState diff --git a/ImmersiveTravel/00 Core/MWSE/mods/ImmersiveTravel/Statemachine/locomotion/CLocomotionState.lua b/ImmersiveTravel/00 Core/MWSE/mods/ImmersiveTravel/Statemachine/locomotion/CLocomotionState.lua index 1f9280e..c9faf1f 100644 --- a/ImmersiveTravel/00 Core/MWSE/mods/ImmersiveTravel/Statemachine/locomotion/CLocomotionState.lua +++ b/ImmersiveTravel/00 Core/MWSE/mods/ImmersiveTravel/Statemachine/locomotion/CLocomotionState.lua @@ -243,8 +243,6 @@ local function CalculatePositions(vehicle, nextPos) virtualpos = rootBone.worldTransform * tes3vector3.new(-1204, 1024, nextPos.z) end end - else - lib.log:debug("CalculatePositions %s: rootBone is nil", vehicle:Id()) end -- calculate diffs diff --git a/ImmersiveTravel/00 Core/MWSE/mods/ImmersiveTravel/Vehicles/CVehicle.lua b/ImmersiveTravel/00 Core/MWSE/mods/ImmersiveTravel/Vehicles/CVehicle.lua index ffe6bb8..18cff37 100644 --- a/ImmersiveTravel/00 Core/MWSE/mods/ImmersiveTravel/Vehicles/CVehicle.lua +++ b/ImmersiveTravel/00 Core/MWSE/mods/ImmersiveTravel/Vehicles/CVehicle.lua @@ -155,6 +155,11 @@ end --#region CVehicle methods +function CVehicle:isOnSpline() + return self.aiStateMachine and self.aiStateMachine.currentState and + self.aiStateMachine.currentState.name == CAiState.ONSPLINE +end + --- StartPlayerSteer is called when the player starts steering function CVehicle:StartPlayerSteer() log:trace("StartPlayerSteer %s", self.id) @@ -222,6 +227,9 @@ end ---@param routeId string function CVehicle:StartPlayerTravel(guideId, routeId) log:debug("StartPlayerTravel %s", self.id) + log:debug("AI state: %s", self.aiStateMachine.currentState.name) + + self:Attach() -- these push the AI statemachine self.playerRegistered = true @@ -375,11 +383,23 @@ end -- player is within the surface of the mount ---@return boolean function CVehicle:isPlayerInMountBounds() + if not self.referenceHandle:valid() then + return false + end + + if not self.referenceHandle:getObject() then + return false + end + local mount = self.referenceHandle:getObject() + local bbox = mount.object.boundingBox + + if not bbox then + return false + end local inside = true local volumeHeight = 200 - local bbox = mount.object.boundingBox local pos = tes3.player.position local surfaceOffset = self.slots[1].position.z @@ -434,7 +454,7 @@ end function CVehicle:UpdateSlots(dt) local rootBone = self:GetRootBone() if rootBone == nil then - log:warn("UpdateSlots %s: rootBone is nil", self:Id()) + log:debug("UpdateSlots %s: rootBone is nil", self:Id()) return end @@ -554,12 +574,12 @@ function CVehicle:UpdateSlots(dt) if self.clutter then for index, clutter in ipairs(self.clutter) do if clutter.handle == nil then - log:warn("UpdateSlots %s: clutter handle is nil", self:Id()) + log:debug("UpdateSlots %s: clutter handle is nil", self:Id()) end if clutter.handle and clutter.handle:valid() then if not clutter.handle:valid() then - log:warn("UpdateSlots %s: clutter handle is invalid", self:Id()) + log:debug("UpdateSlots %s: clutter handle is invalid", self:Id()) end clutter.handle:getObject().position = rootBone.worldTransform * @@ -638,8 +658,12 @@ end -- update player collision ---@param rootBone niNode? function CVehicle:UpdatePlayerCollision(rootBone) + local isInTravelState = self.aiStateMachine.currentState.name == CAiState.PLAYERTRAVEL + local isInSteerState = self.aiStateMachine.currentState.name == CAiState.ONSPLINE + local playerCanFreeMove = isInSteerState or (isInTravelState and GPlayerVehicleManager.getInstance().free_movement) + -- check if player is in freemovement mode - if rootBone and tes3.player.tempData.itpsl then + if self.hasFreeMovement and playerCanFreeMove and rootBone and tes3.player.tempData.itpsl then -- this is needed to enable collisions :todd: tes3.dataHandler:updateCollisionGroupsForActiveCells {} self.referenceHandle:getObject().sceneNode:update()