diff --git a/AIDriver.lua b/AIDriver.lua index 6894aff99..469dbfe3a 100644 --- a/AIDriver.lua +++ b/AIDriver.lua @@ -2201,17 +2201,11 @@ function AIDriver:isFuelLevelOk() end function AIDriver:isValidFillType(fillType) - return not self:isValidFuelType(self.vehicle, fillType) and fillType ~= FillType.DEF and fillType ~= FillType.AIR + return AIDriverUtil.isValidFillType(self.vehicle,fillType) end function AIDriver:isValidFuelType(object,fillType,fillUnitIndex) - if object.getConsumerFillUnitIndex then - local index = object:getConsumerFillUnitIndex(fillType) - if fillUnitIndex ~= nil then - return fillUnitIndex and fillUnitIndex == index - end - return index - end + return AIDriverUtil.isValidFuelType(object,fillType,fillUnitIndex) end function AIDriver:getFuelLevelPercentage() diff --git a/AIDriverUtil.lua b/AIDriverUtil.lua index a157959a9..61c4ba622 100644 --- a/AIDriverUtil.lua +++ b/AIDriverUtil.lua @@ -387,6 +387,68 @@ function AIDriverUtil.getFillTypeFromFillUnit(fillUnit) end end +--- Gets the complete fill level and capacity without fuel, +---@param object table +---@return number totalFillLevel +---@return number totalCapacity +function AIDriverUtil.getTotalFillLevelAndCapacity(object) + + local fillLevelInfo = {} + AIDriverUtil.getAllFillLevels(object, fillLevelInfo) + + local totalFillLevel = 0 + local totalCapacity = 0 + for fillType,data in pairs(fillLevelInfo) do + if AIDriverUtil.isValidFillType(object,fillType) then + totalFillLevel = totalFillLevel + data.fillLevel + totalCapacity = totalCapacity + data.capacity + end + end + return totalFillLevel,totalCapacity +end + +--- Gets the total fill level percentage. +---@param object table +function AIDriverUtil.getTotalFillLevelPercentage(object) + local fillLevel,capacity = AIDriverUtil.getTotalFillLevelAndCapacity(object) + return 100*fillLevel/capacity +end + +function AIDriverUtil.getTotalFillLevelAndCapacityForObject(object) + local totalFillLevel = 0 + local totalCapacity = 0 + if object.getFillUnits then + for index,fillUnit in pairs(object:getFillUnits()) do + local fillType = AIDriverUtil.getFillTypeFromFillUnit(fillUnit) + if AIDriverUtil.isValidFillType(object,fillType) then + totalFillLevel = totalFillLevel + fillUnit.fillLevel + totalCapacity = totalCapacity + fillUnit.capacity + end + end + end + return totalFillLevel,totalCapacity +end + +---@param object table +---@param fillType number +function AIDriverUtil.isValidFillType(object,fillType) + return not AIDriverUtil.isValidFuelType(object, fillType) and fillType ~= FillType.DEF and fillType ~= FillType.AIR +end + +--- Is the fill type fuel ? +---@param object table +---@param fillType number +---@param fillUnitIndex number +function AIDriverUtil.isValidFuelType(object,fillType,fillUnitIndex) + if object.getConsumerFillUnitIndex then + local index = object:getConsumerFillUnitIndex(fillType) + if fillUnitIndex ~= nil then + return fillUnitIndex and fillUnitIndex == index + end + return index + end +end + --- Gets the fill level of an mixerWagon for a fill type. ---@param object table ---@param fillType number diff --git a/BunkerSiloAIDriver.lua b/BunkerSiloAIDriver.lua index baa52c605..a87c155e1 100644 --- a/BunkerSiloAIDriver.lua +++ b/BunkerSiloAIDriver.lua @@ -272,14 +272,29 @@ function BunkerSiloAIDriver:beforeDriveIntoSilo() end --- Gets the best target for driving into the silo. +--- Always starts at the right side and then drives to the left/right side. function BunkerSiloAIDriver:getBestTarget() if not self.lastDrivenColumn then - self:siloDebug("Starting a new approach at column 1.") - return {line=1,column=1},1 + local column = math.ceil(self.bunkerSiloManager:getNumberOfColumns()/2) + self:siloDebug("Starting a new approach in the middle at column %d",column) + self.lastDrivenColumnRight = true + return {line=1,column=column},1 else local numColumns = self.bunkerSiloManager:getNumberOfColumns() - local nextColumn = self.lastDrivenColumn+1 - if nextColumn > numColumns then nextColumn = 1 end + local nextColumn + if self.lastDrivenColumnRight then + nextColumn = self.lastDrivenColumn+1 + if nextColumn > numColumns then + nextColumn = math.floor(self.bunkerSiloManager:getNumberOfColumns()/2) + self.lastDrivenColumnRight = false + end + else + nextColumn = self.lastDrivenColumn-1 + if nextColumn <= 0 then + nextColumn = math.ceil(self.bunkerSiloManager:getNumberOfColumns()/2) + self.lastDrivenColumnRight = true + end + end self:siloDebug("Starting at column: %d, last column: %d",nextColumn,self.lastDrivenColumn) return {line=1,column=nextColumn},1 end @@ -301,6 +316,7 @@ end function BunkerSiloAIDriver:deleteBestTarget() self.lastDrivenColumn = nil self.bestTarget = nil + self.lastDrivenColumnRight = not self.lastDrivenColumnRight end --- Deletes the best target, but saves the last driven column. diff --git a/CompactingAIDriver.lua b/CompactingAIDriver.lua index 670e3212f..2d5097318 100644 --- a/CompactingAIDriver.lua +++ b/CompactingAIDriver.lua @@ -103,7 +103,7 @@ function CompactingAIDriver:foundUnloaderInRadius(r,setWaiting) local x,y,z = getTranslation(self.relevantWaypointNode.node) DebugUtil.drawDebugCircle(x,y+2,z, r, math.ceil(r/2)) end - local onlyStopFilledDrivers = self.settings.levelCompactSiloTyp:get() + for _, vehicle in pairs(g_currentMission.vehicles) do if vehicle ~= self.vehicle then local d = calcDistanceFrom(self.relevantWaypointNode.node, vehicle.rootNode) @@ -111,13 +111,7 @@ function CompactingAIDriver:foundUnloaderInRadius(r,setWaiting) local autodriveSpec = vehicle.spec_autodrive if courseplay:isAIDriverActive(vehicle) and vehicle.cp.driver.triggerHandler:isAllowedToUnloadAtBunkerSilo() then --CombineUnloadAIDriver,GrainTransportAIDriver,UnloadableFieldworkAIDriver - local isOkayToStop = true - if onlyStopFilledDrivers then - if vehicle.cp.totalFillLevel < 0.02 then - isOkayToStop = false - end - end - + local isOkayToStop = self:isTheUnloaderAllowedToStop(vehicle) if setWaiting and isOkayToStop then vehicle.cp.driver:hold() vehicle.cp.driver:setInfoText("WAITING_FOR_LEVELCOMPACTAIDRIVER") @@ -129,12 +123,14 @@ function CompactingAIDriver:foundUnloaderInRadius(r,setWaiting) self:debugSparse("found cp driver : %s",nameNum(vehicle)) return isOkayToStop elseif autodriveSpec and autodriveSpec.HoldDriving and vehicle.ad.stateModule and vehicle.ad.stateModule:isActive() then - --autodrive - if setWaiting then + --- Autodrive + local isOkayToStop = self:isTheUnloaderAllowedToStop(vehicle) + if setWaiting and isOkayToStop then autodriveSpec:HoldDriving(vehicle) end + self:debugSparse("found autodrive driver : %s",nameNum(vehicle)) - return true + return isOkayToStop elseif vehicle.getIsEntered and (vehicle:getIsEntered() or vehicle:getIsControlled()) and (AIDriverUtil.hasImplementWithSpecialization(vehicle, Trailer) or vehicle.spec_trailer) then --Player controlled vehicle if self.settings.levelCompactSearchOnlyAutomatedDriver:is(false) then @@ -148,6 +144,17 @@ function CompactingAIDriver:foundUnloaderInRadius(r,setWaiting) end end +function CompactingAIDriver:isTheUnloaderAllowedToStop(unloader) + local onlyStopFilledDrivers = self.settings.levelCompactSiloTyp:get() + if onlyStopFilledDrivers then + local totalFillLevel = AIDriverUtil.getTotalFillLevelAndCapacity(unloader) + if totalFillLevel < 0.02 then + return false + end + end + return true +end + function CompactingAIDriver:beforeDriveIntoSilo() self:lowerImplements() BunkerSiloAIDriver.beforeDriveIntoSilo(self) diff --git a/ShovelAIDriver.lua b/ShovelAIDriver.lua index f8923d41f..807bcfe97 100644 --- a/ShovelAIDriver.lua +++ b/ShovelAIDriver.lua @@ -451,14 +451,22 @@ end --- Raycast callback for searching of trailers/triggers near the shovelEmptyPoint (first wait point). function ShovelAIDriver:searchForUnloadingObjectRaycastCallback(transformId, x, y, z, distance, nx, ny, nz, subShapeIndex, hitShapeId) local object = g_currentMission:getNodeObject(transformId) - --has the target already been hit ? - + local unloadTriggers = Triggers.getUnloadingTriggers() + local baleUnloadTriggers = Triggers.getBaleUnloadTriggers() + local trigger = unloadTriggers[transformId] or baleUnloadTriggers[transformId] + + --- Has the target already been hit ? if not self:isWaitingForTrailer() then return end if object then --is object a vehicle, trailer,... if object:isa(Vehicle) then + --check if the vehicle is stopped + local rootVehicle = object:getRootVehicle() + if not AIDriverUtil.isStopped(rootVehicle) then + return + end --object supports filltype, bassicly trailer and so on if object.getFillUnitSupportsToolType then for fillUnitIndex,fillUnit in pairs(object:getFillUnits()) do @@ -471,13 +479,6 @@ function ShovelAIDriver:searchForUnloadingObjectRaycastCallback(transformId, x, self:shovelDebug("allowedToFillByShovel") if supportedFillType then --valid trailer/ fillableObject found - - --check if the vehicle is stopped - local rootVehicle = object:getRootVehicle() - if not AIDriverUtil.isStopped(rootVehicle) then - return - end - --- local exactFillRootNode = object:getFillUnitExactFillRootNode(fillUnitIndex) or object.rootNode self:shovelDebug("supportedFillType") self:shovelDebug("Trailer found!") @@ -494,29 +495,17 @@ function ShovelAIDriver:searchForUnloadingObjectRaycastCallback(transformId, x, self:shovelDebug("FillUnit not found!") end return - --UnloadTrigger found - elseif object:isa(UnloadTrigger) then - -- DebugUtil.printTableRecursively(object, " ", 0, 2) + elseif trigger then self:shovelDebug("UnloadTrigger found!") - local fillUnitIndex = object:getFillUnitIndexFromNode(hitShapeId) - self:setupDrivingToUnloadingTriggerCourse(object) - return - --some diffrent object which is valid - elseif object.getFillUnitIndexFromNode ~= nil then - -- DebugUtil.printTableRecursively(object, " ", 0, 2) - local fillUnitIndex = object:getFillUnitIndexFromNode(hitShapeId) - if fillUnitIndex ~= nil then + if trigger.getIsFillTypeAllowed and trigger.getIsToolTypeAllowed then local fillType = self.shovel:getDischargeFillType(self.currentDischargeNode) - if object:getFillUnitSupportsFillType(fillUnitIndex, fillType) then - self:shovelDebug("Trigger found!") - self:setupDrivingToUnloadingTriggerCourse(object) - else - self:shovelDebug("fillType not supported!") + if trigger:getIsFillTypeAllowed(fillType) and trigger:getIsToolTypeAllowed(ToolType.DISCHARGEABLE) then + self:shovelDebug("UnloadTrigger is valid!") + self:setupDrivingToUnloadingTriggerCourse(trigger) end - else - self:shovelDebug("no fillUnitIndex found!") end end + else self:shovelDebug("Nothing found!") return diff --git a/triggers.lua b/triggers.lua index d24adf28c..05560fd5f 100644 --- a/triggers.lua +++ b/triggers.lua @@ -533,6 +533,13 @@ function Triggers.getFillTriggers() return Triggers.fillTriggers end +function Triggers.getUnloadingTriggers() + return Triggers.unloadingTriggers +end + +function Triggers.getBaleUnloadTriggers() + return Triggers.baleUnloadingTriggers +end ---Add all relevant triggers on create and remove them on delete. function Triggers.addLoadingTrigger(trigger,superFunc,...)