Skip to main content
Skip to main content

AIConveyorBelt

AIConveyorBelt

Description

Specialization for extending conveyor belts with AI functionality

Functions

actionEventChangeAngle

Description

Definition

actionEventChangeAngle()

Arguments

anyself
anyactionName
anyinputValue
anycallbackState
anyisAnalog

Code

function AIConveyorBelt.actionEventChangeAngle( self , actionName, inputValue, callbackState, isAnalog)
local spec = self.spec_aiConveyorBelt
local newAngle = spec.currentAngle + spec.stepSize
if newAngle > spec.maxAngle then
newAngle = spec.minAngle
end

self:setAIConveyorBeltAngle(newAngle)
end

getAINeedsTrafficCollisionBox

Description

Definition

getAINeedsTrafficCollisionBox()

Arguments

anysuperFunc

Code

function AIConveyorBelt:getAINeedsTrafficCollisionBox(superFunc)
return false
end

getCanBeSelected

Description

Definition

getCanBeSelected()

Arguments

anysuperFunc

Code

function AIConveyorBelt:getCanBeSelected(superFunc)
return true
end

getCanStartAIVehicle

Description

Definition

getCanStartAIVehicle()

Arguments

anysuperFunc

Code

function AIConveyorBelt:getCanStartAIVehicle(superFunc)
if not superFunc( self ) then
return false
end

return self.spec_aiConveyorBelt.isAllowed
end

getCanStartFieldWork

Description

Definition

getCanStartFieldWork()

Code

function AIConveyorBelt:getCanStartFieldWork()
return self:getCanStartAIVehicle()
end

getDirectionAndSpeedToTargetAngle

Description

Definition

getDirectionAndSpeedToTargetAngle()

Arguments

anydirection
anyminAngle
anymaxAngle

Code

function AIConveyorBelt:getDirectionAndSpeedToTargetAngle(direction, minAngle, maxAngle)
local dx, _, dz = localDirectionToWorld( self.components[ 1 ].node, 0 , 0 , 1 )
local yRot = MathUtil.getYRotationFromDirection(dx, dz)

local angleDifference
if direction > 0 then
if yRot > maxAngle then
return - 1 , 0
end
angleDifference = maxAngle - yRot
elseif direction < 0 then
if yRot < minAngle then
return 1 , 0
end
angleDifference = yRot - minAngle
else
angleDifference = 0
end

local speed = math.clamp( math.deg(angleDifference) / 2.5 , 0.1 , 1 ) * direction

return direction, speed
end

getHasStartableAIJob

Description

Definition

getHasStartableAIJob()

Arguments

anysuperFunc

Code

function AIConveyorBelt:getHasStartableAIJob(superFunc)
return true
end

getStartableAIJob

Description

Definition

getStartableAIJob()

Arguments

anysuperFunc

Code

function AIConveyorBelt:getStartableAIJob(superFunc)

if self:getCanStartFieldWork() then
local spec = self.spec_aiConveyorBelt
local conveyorJob = spec.conveyorJob
conveyorJob:applyCurrentState( self , g_currentMission, g_localPlayer.farmId, false )
conveyorJob:setValues()
local success = conveyorJob:validate( false )
if success then
return conveyorJob
end
end

return nil
end

initSpecialization

Description

Definition

initSpecialization()

Code

function AIConveyorBelt.initSpecialization()
local schema = Vehicle.xmlSchema
schema:setXMLSpecializationType( "AIConveyorBelt" )

schema:register(XMLValueType.FLOAT, "vehicle.ai.conveyorBelt#minAngle" , "Min angle" , 5 )
schema:register(XMLValueType.FLOAT, "vehicle.ai.conveyorBelt#maxAngle" , "Max angle" , 45 )
schema:register(XMLValueType.FLOAT, "vehicle.ai.conveyorBelt#stepSize" , "Step size" , 5 )
schema:register(XMLValueType.FLOAT, "vehicle.ai.conveyorBelt#speed" , "Speed" , 1 )
schema:register(XMLValueType.INT, "vehicle.ai.conveyorBelt#direction" , "Direction" , - 1 )

schema:setXMLSpecializationType()

local schemaSavegame = Vehicle.xmlSchemaSavegame
schemaSavegame:register(XMLValueType.FLOAT, "vehicles.vehicle(?).aiConveyorBelt#currentAngle" , "Current angle" , 45 )
end

onAIFieldWorkerStart

Description

Definition

onAIFieldWorkerStart()

Code

function AIConveyorBelt:onAIFieldWorkerStart()
local spec = self.spec_aiConveyorBelt

local dx, _, dz = localDirectionToWorld( self.components[ 1 ].node, 0 , 0 , 1 )
local yRot = MathUtil.getYRotationFromDirection(dx, dz)

spec.minTargetWorldYRot = yRot - math.rad(spec.currentAngle) / 2
spec.maxTargetWorldYRot = yRot + math.rad(spec.currentAngle) / 2
spec.currentDirection = 1
end

onLoad

Description

Called on loading

Definition

onLoad(table savegame)

Arguments

tablesavegamesavegame

Code

function AIConveyorBelt:onLoad(savegame)
local spec = self.spec_aiConveyorBelt

spec.isAllowed = self.xmlFile:hasProperty( "vehicle.ai.conveyorBelt" )

spec.minAngle = self.xmlFile:getValue( "vehicle.ai.conveyorBelt#minAngle" , 5 )
spec.maxAngle = self.xmlFile:getValue( "vehicle.ai.conveyorBelt#maxAngle" , 45 )
spec.stepSize = self.xmlFile:getValue( "vehicle.ai.conveyorBelt#stepSize" , 5 )
spec.currentAngle = spec.maxAngle

spec.minTargetWorldYRot = 0
spec.maxTargetWorldYRot = 0
spec.currentDirection = 0
spec.currentSpeed = 0

spec.conveyorJob = g_currentMission.aiJobTypeManager:createJob(AIJobType.CONVEYOR)

spec.speed = self.xmlFile:getValue( "vehicle.ai.conveyorBelt#speed" , 1 )
spec.direction = self.xmlFile:getValue( "vehicle.ai.conveyorBelt#direction" , - 1 )

if not self.isServer then
SpecializationUtil.removeEventListener( self , "onUpdate" , AIConveyorBelt )
end
if not self.isClient then
SpecializationUtil.removeEventListener( self , "onUpdateTick" , AIConveyorBelt )
end
end

onPostLoad

Description

Definition

onPostLoad()

Arguments

anysavegame

Code

function AIConveyorBelt:onPostLoad(savegame)
local spec = self.spec_aiConveyorBelt
if savegame ~ = nil and not savegame.resetVehicles then
spec.currentAngle = savegame.xmlFile:getValue(savegame.key .. ".aiConveyorBelt#currentAngle" , spec.currentAngle)
end
end

onReadStream

Description

Called on client side on join

Definition

onReadStream(integer streamId, Connection connection)

Arguments

integerstreamIdstreamId
Connectionconnectionconnection

Code

function AIConveyorBelt:onReadStream(streamId, connection)
self:setAIConveyorBeltAngle(streamReadInt8(streamId), true )
end

onRegisterActionEvents

Description

Definition

onRegisterActionEvents()

Arguments

anyisActiveForInput
anyisActiveForInputIgnoreSelection

Code

function AIConveyorBelt:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection)
if self.isClient then
local spec = self.spec_aiConveyorBelt
self:clearActionEventsTable(spec.actionEvents)

if isActiveForInputIgnoreSelection and spec.isAllowed then
local _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.IMPLEMENT_EXTRA3, self , AIConveyorBelt.actionEventChangeAngle, false , true , false , true , nil )
g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_NORMAL)
end
end
end

onUpdate

Description

Called on update

Definition

onUpdate(float dt, boolean isActiveForInput, boolean isSelected, )

Arguments

floatdttime since last call in ms
booleanisActiveForInputtrue if vehicle is active for input
booleanisSelectedtrue if vehicle is selected
anyisSelected

Code

function AIConveyorBelt:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
if self:getIsAIActive() then
local spec = self.spec_aiConveyorBelt
spec.currentDirection, spec.currentSpeed = self:getDirectionAndSpeedToTargetAngle(spec.currentDirection, spec.minTargetWorldYRot, spec.maxTargetWorldYRot)

self:getMotor():setSpeedLimit( math.abs(spec.currentSpeed * spec.speed))
WheelsUtil.updateWheelsPhysics( self , dt, spec.currentSpeed * spec.speed * spec.direction, spec.currentDirection * spec.direction, false , true )
end
end

onUpdateTick

Description

Called on updateTick

Definition

onUpdateTick(float dt, boolean isActiveForInput, boolean isSelected, )

Arguments

floatdttime since last call in ms
booleanisActiveForInputtrue if vehicle is active for input
booleanisSelectedtrue if vehicle is selected
anyisSelected

Code

function AIConveyorBelt:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
local spec = self.spec_aiConveyorBelt
local actionEvent = spec.actionEvents[InputAction.IMPLEMENT_EXTRA3]
if actionEvent ~ = nil then
g_inputBinding:setActionEventActive(actionEvent.actionEventId, isActiveForInputIgnoreSelection)
if isActiveForInputIgnoreSelection then
g_inputBinding:setActionEventText(actionEvent.actionEventId, string.format(g_i18n:getText( "action_conveyorBeltChangeAngle" ), string.format( "%.0f" , spec.currentAngle)))
end
end
end

onWriteStream

Description

Called on server side on join

Definition

onWriteStream(integer streamId, Connection connection)

Arguments

integerstreamIdstreamId
Connectionconnectionconnection

Code

function AIConveyorBelt:onWriteStream(streamId, connection)
streamWriteInt8(streamId, self.spec_aiConveyorBelt.currentAngle)
end

prerequisitesPresent

Description

Checks if all prerequisite specializations are loaded

Definition

prerequisitesPresent(table specializations)

Arguments

tablespecializationsspecializations

Return Values

tablehasPrerequisitetrue if all prerequisite specializations are loaded

Code

function AIConveyorBelt.prerequisitesPresent(specializations)
return SpecializationUtil.hasSpecialization( AIFieldWorker , specializations) and SpecializationUtil.hasSpecialization( Motorized , specializations)
end

registerEventListeners

Description

Definition

registerEventListeners()

Arguments

anyvehicleType

Code

function AIConveyorBelt.registerEventListeners(vehicleType)
SpecializationUtil.registerEventListener(vehicleType, "onLoad" , AIConveyorBelt )
SpecializationUtil.registerEventListener(vehicleType, "onPostLoad" , AIConveyorBelt )
SpecializationUtil.registerEventListener(vehicleType, "onReadStream" , AIConveyorBelt )
SpecializationUtil.registerEventListener(vehicleType, "onWriteStream" , AIConveyorBelt )
SpecializationUtil.registerEventListener(vehicleType, "onUpdate" , AIConveyorBelt )
SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick" , AIConveyorBelt )
SpecializationUtil.registerEventListener(vehicleType, "onAIFieldWorkerStart" , AIConveyorBelt )
SpecializationUtil.registerEventListener(vehicleType, "onRegisterActionEvents" , AIConveyorBelt )
end

registerFunctions

Description

Definition

registerFunctions()

Arguments

anyvehicleType

Code

function AIConveyorBelt.registerFunctions(vehicleType)
SpecializationUtil.registerFunction(vehicleType, "setAIConveyorBeltAngle" , AIConveyorBelt.setAIConveyorBeltAngle)
SpecializationUtil.registerFunction(vehicleType, "getDirectionAndSpeedToTargetAngle" , AIConveyorBelt.getDirectionAndSpeedToTargetAngle)
end

registerOverwrittenFunctions

Description

Definition

registerOverwrittenFunctions()

Arguments

anyvehicleType

Code

function AIConveyorBelt.registerOverwrittenFunctions(vehicleType)
SpecializationUtil.registerOverwrittenFunction(vehicleType, "getStartableAIJob" , AIConveyorBelt.getStartableAIJob)
SpecializationUtil.registerOverwrittenFunction(vehicleType, "getHasStartableAIJob" , AIConveyorBelt.getHasStartableAIJob)
SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanStartFieldWork" , AIConveyorBelt.getCanStartFieldWork)
SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanStartAIVehicle" , AIConveyorBelt.getCanStartAIVehicle)
SpecializationUtil.registerOverwrittenFunction(vehicleType, "getCanBeSelected" , AIConveyorBelt.getCanBeSelected)
SpecializationUtil.registerOverwrittenFunction(vehicleType, "getAINeedsTrafficCollisionBox" , AIConveyorBelt.getAINeedsTrafficCollisionBox)
end

saveToXMLFile

Description

Definition

saveToXMLFile()

Arguments

anyxmlFile
anykey
anyusedModNames

Code

function AIConveyorBelt:saveToXMLFile(xmlFile, key, usedModNames)
local spec = self.spec_aiConveyorBelt
xmlFile:setValue(key .. "#currentAngle" , spec.currentAngle)
end

setAIConveyorBeltAngle

Description

Definition

setAIConveyorBeltAngle()

Arguments

anyangle
anynoEventSend

Code

function AIConveyorBelt:setAIConveyorBeltAngle(angle, noEventSend)
if noEventSend = = nil or noEventSend = = false then
if g_server ~ = nil then
g_server:broadcastEvent( AIConveyorBeltSetAngleEvent.new( self , angle), nil , nil , self )
else
g_client:getServerConnection():sendEvent( AIConveyorBeltSetAngleEvent.new( self , angle))
end
end

self.spec_aiConveyorBelt.currentAngle = angle
end