--
-- Combine
-- Lexion 600 EXCLUSIV
--
-- @author  Stefan Geiger
-- @date  30/11/08 | @edit date 12/05/09
-- @edit by: sven18koehler for Lexion 600
-- @edit by: shangri66
-- @cuttersound bugfix
-- @automatic gasmodes


-- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved.

Lexion600Combine2 = {};

function Lexion600Combine2.prerequisitesPresent(specializations)
    Vehicle.registerJointType("cutter");
	Vehicle.registerJointType("trailerLow");
	Vehicle.registerJointType("trailerCombine");
    return SpecializationUtil.hasSpecialization(Steerable, specializations);
end;

function Lexion600Combine2:load(xmlFile)

    self.allowGrainTankFruitType = Lexion600Combine2.allowGrainTankFruitType;
    self.emptyGrainTankIfLowFillLevel = Lexion600Combine2.emptyGrainTankIfLowFillLevel;
    self.setGrainTankFillLevel = SpecializationUtil.callSpecializationsFunction("setGrainTankFillLevel");
    self.startThreshing = SpecializationUtil.callSpecializationsFunction("startThreshing");
    self.stopThreshing = SpecializationUtil.callSpecializationsFunction("stopThreshing");
    self.openPipe = SpecializationUtil.callSpecializationsFunction("openPipe");
    self.closePipe = SpecializationUtil.callSpecializationsFunction("closePipe");
    self.findTrailerRaycastCallback = Lexion600Combine2.findTrailerRaycastCallback;

    local threshingStartSound = getXMLString(xmlFile, "vehicle.threshingStartSound#file");
    if threshingStartSound ~= nil and threshingStartSound ~= "" then
        threshingStartSound = Utils.getFilename(threshingStartSound, self.baseDirectory); 
        self.threshingStartSound = createSample("threshingStartSound");
        loadSample(self.threshingStartSound, threshingStartSound, false);
        self.threshingStartSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.threshingStartSound#pitchOffset"), 1);
        self.threshingStartSoundPitchScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.threshingStartSound#pitchScale"), 0);
        self.threshingStartSoundPitchMax = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.threshingStartSound#pitchMax"), 2.0);
    end;

    local threshingSound = getXMLString(xmlFile, "vehicle.threshingSound#file");
    if threshingSound ~= nil and threshingSound ~= "" then
        threshingSound = Utils.getFilename(threshingSound, self.baseDirectory); 
        self.threshingSound = createSample("threshingSound");
        loadSample(self.threshingSound, threshingSound, false);
        self.threshingSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.threshingSound#pitchOffset"), 1);
        self.threshingSoundPitchScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.threshingSound#pitchScale"), 0);
        self.threshingSoundPitchMax = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.threshingSound#pitchMax"), 2.0);
    end;

    local threshingStopSound = getXMLString(xmlFile, "vehicle.threshingStopSound#file");
    if threshingStopSound ~= nil and threshingStopSound ~= "" then
        threshingStopSound = Utils.getFilename(threshingStopSound, self.baseDirectory); 
        self.threshingStopSound = createSample("threshingStopSound");
        loadSample(self.threshingStopSound, threshingStopSound, false);
        self.threshingStopSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.threshingStopSound#pitchOffset"), 1);
        self.threshingStopSoundPitchScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.threshingStopSound#pitchScale"), 0);
        self.threshingStopSoundPitchMax = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.threshingStopSound#pitchMax"), 2.0);
    end;

    local pipeSound = getXMLString(xmlFile, "vehicle.pipeSound#file");
    if pipeSound ~= nil and pipeSound ~= "" then
        pipeSound = Utils.getFilename(pipeSound, self.baseDirectory); 
        self.pipeSound = createSample("pipeSound");
        loadSample(self.pipeSound, pipeSound, false);
        self.pipeSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.pipeSound#pitchOffset"), 1);
        self.pipeSoundPitchScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.pipeSound#pitchScale"), 0);
        self.pipeSoundPitchMax = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.pipeSound#pitchMax"), 2.0);
    end;
	
	local cutterSound = getXMLString(xmlFile, "vehicle.cutterSound#file");
    if cutterSound ~= nil and cutterSound ~= "" then
        cutterSound = Utils.getFilename(cutterSound, self.baseDirectory); 
        self.cutterSound = createSample("cutterSound");
        loadSample(self.cutterSound, cutterSound, false);
        self.cutterSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.cutterSound#pitchOffset"), 1);
        self.cutterSoundPitchScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.cutterSound#pitchScale"), 0);
        self.cutterSoundPitchMax = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.cutterSound#pitchMax"), 2.0);
    end;

    self.pipeParticleSystems = {};
    self.pipe = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.pipe#index"));
    if self.pipe ~= nil then

        self.pipeRaycastNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.pipe#raycastNodeIndex"));

        -- load the pipe particle system for each fruit type
        local i = 0;
        while true do
            local key = string.format("vehicle.pipeParticleSystems.pipeParticleSystem(%d)", i);
            local t = getXMLString(xmlFile, key .. "#type");
            if t == nil then
                break;
            end;

            local desc = FruitUtil.fruitTypes[t];
            if desc ~= nil then
                local currentPS = {};

                local particleNode = Utils.loadParticleSystem(xmlFile, currentPS, key, self.pipe, false, "$data/vehicles/particleSystems/wheatParticleSystem.i3d", self.baseDirectory);
                self.pipeParticleSystems[desc.index] = currentPS;
                if self.defaultPipeParticleSystem == nil then
                    self.defaultPipeParticleSystem = currentPS;
                end;

                if self.pipeRaycastNode == nil then
                    self.pipeRaycastNode = particleNode;
                end;
            end;
            i = i + 1;
        end;

        if self.pipeRaycastNode == nil then
            self.pipeRaycastNode = self.components[1].node;
        end;

    end;

    self.allowsThreshing = true;
	
    self.pipeLight = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.pipeLight#index"));
    self.grainTankCapacity = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.grainTankCapacity"), 200);
    self.grainTankUnloadingCapacity = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.grainTankUnloadingCapacity"), 10);
    self.grainTankCrowded = false;

    self.grainTankPlanes = {};
    local i = 0;
    while true do
        local key = string.format("vehicle.grainTankPlane.node(%d)", i);
        local t = getXMLString(xmlFile, key.."#type");
        local index = getXMLString(xmlFile, key.."#index");
        if t==nil or index==nil then
            break;
        end;

        local node = Utils.indexToObject(self.components, index);
        if node ~= nil then
            setVisibility(node, false);

            local entry = {};
            entry.node = node;
            local windowNode = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#windowIndex"));
            if windowNode ~= nil then
                entry.windowNode = windowNode;
                setVisibility(windowNode, false);
            end;

            if self.defaultGrainTankPlane == nil then
                self.defaultGrainTankPlane = entry;
            end;
            self.grainTankPlanes[t] = entry;
        end;
        i = i +1;
    end;
    if self.defaultGrainTankPlane==nil then
        self.grainTankPlanes = nil;
    end;

    self.grainTankPlaneMinY, self.grainTankPlaneMaxY = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.grainTankPlane#minMaxY"));
    if self.grainTankPlaneMinY == nil or self.grainTankPlaneMaxY == nil then
        local animCurve = AnimCurve:new(linearInterpolator4);
        local i = 0;
        while true do
            local key = string.format("vehicle.grainTankPlane.key(%d)", i);
            local t = getXMLFloat(xmlFile, key.."#time");
            local yValue = getXMLFloat(xmlFile, key.."#y");
            local scaleX,scaleY,scaleZ = Utils.getVectorFromString(getXMLString(xmlFile, key.."#scale"));
            if y == nil or scaleX == nil or scaleY == nil or scaleZ == nil then
                break;
            end;
            animCurve:addKeyframe({x=scaleX, y=scaleY, z=scaleZ, w=yValue, time = t});
            i = i +1;
        end;
        if i > 0 then
            self.grainTankPlaneAnimCurve = animCurve;
        end;
        self.grainTankPlaneMinY = 0;
        self.grainTankPlaneMaxY = 0;
    end;


    self.grainTankPlaneWindowMinY, self.grainTankPlaneWindowMaxY = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.grainTankPlane#windowMinMaxY"));
    if self.grainTankPlaneWindowMinY == nil or self.grainTankPlaneWindowMaxY == nil then
        local animCurve = AnimCurve:new(linearInterpolatorN);
        local i = 0;
        while true do
            local key = string.format("vehicle.grainTankPlane.windowKey(%d)", i);
            local t = getXMLFloat(xmlFile, key.."#time");
            local yValue = getXMLFloat(xmlFile, key.."#y");
            local visibility = getXMLBool(xmlFile, key.."#visibility");
            local scaleX,scaleY,scaleZ = Utils.getVectorFromString(getXMLString(xmlFile, key.."#scale"));
            if y == nil or scaleX == nil or scaleY == nil or scaleZ == nil or visibility == nil then
                break;
            end;
            animCurve:addKeyframe({v={scaleX, scaleY, scaleZ, yValue, }, time = t});
            i = i +1;
        end;
        if i > 0 then
            self.grainTankPlaneWindowAnimCurve = animCurve;
        end;
        self.grainTankPlaneWindowMinY = 0;
        self.grainTankPlaneWindowMaxY = 0;
    end;
    self.grainTankPlaneWindowStartY = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.grainTankPlane#windowStartY"), 0.0);


    self.chopperParticleSystemsRight = {};
	self.chopperNodeRight = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chopperParticleSystemsRight#node"));
    local i = 0;
    while true do
        local key = string.format("vehicle.chopperParticleSystemsRight.chopperParticleSystemRight(%d)", i);
        local t = getXMLString(xmlFile, key .. "#type");
        if t == nil then
            break;
        end;
        local desc = FruitUtil.fruitTypes[t];
        if desc ~= nil then
            local currentPS = {};

            local particleNode = Utils.loadParticleSystem(xmlFile, currentPS, key, self.chopperNodeRight, false, "$data/vehicles/particleSystems/threshingChopperParticleSystem.i3d", self.baseDirectory);
            self.chopperParticleSystemsRight[desc.index] = currentPS;
            if self.defaultChopperParticleSystemRight == nil then
                self.defaultChopperParticleSystemRight = currentPS;
            end;
        end;
        i = i + 1;
    end;
	self.chopperParticleSystemsLeft = {};
	self.chopperNodeLeft = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chopperParticleSystemsLeft#node"));
    local i = 0;
    while true do
        local key = string.format("vehicle.chopperParticleSystemsLeft.chopperParticleSystemLeft(%d)", i);
        local t = getXMLString(xmlFile, key .. "#type");
        if t == nil then
            break;
        end;
        local desc = FruitUtil.fruitTypes[t];
        if desc ~= nil then
            local currentPS = {};

            local particleNode = Utils.loadParticleSystem(xmlFile, currentPS, key, self.chopperNodeLeft, false, "$data/vehicles/particleSystems/threshingChopperParticleSystem.i3d", self.baseDirectory);
            self.chopperParticleSystemsLeft[desc.index] = currentPS;
            if self.defaultChopperParticleSystemLeft == nil then
                self.defaultChopperParticleSystemLeft = currentPS;
            end;
        end;
        i = i + 1;
    end;

    self.chopperToggleTime = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.chopperParticleSystemsRight#toggleTime"), 2500);
    self.chopperEnableTime = nil;
	self.chopperDisableTime = nil;
	self.grainTankToggleTime = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.grainTankParticleSystems#toggleTime"), 2500);
	self.grainTankEnableTime = nil;
	self.grainTankDisableTime = nil;
    
    self.strawParticleSystemsRight = {};
	self.strawNodeRight = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.strawParticleSystemsRight#node"));
    local i = 0;
    while true do
        local key = string.format("vehicle.strawParticleSystemsRight.strawParticleSystemRight(%d)", i);
        local t = getXMLString(xmlFile, key .. "#type");
        if t == nil then
            break;
        end;
        local desc = FruitUtil.fruitTypes[t];
        if desc ~= nil then
            local currentPS = {};

            local particleNode = Utils.loadParticleSystem(xmlFile, currentPS, key, self.strawNodeRight, false, "$data/vehicles/particleSystems/threshingStrawParticleSystem.i3d", self.baseDirectory);
            self.strawParticleSystemsRight[desc.index] = currentPS;
            if self.defaultStrawParticleSystemRight == nil then
                self.defaultStrawParticleSystemRight = currentPS;
            end;
        end;
        i = i + 1;
    end;
	self.strawParticleSystemsLeft = {};
	self.strawNodeLeft = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.strawParticleSystemsLeft#node"));
    local i = 0;
    while true do
        local key = string.format("vehicle.strawParticleSystemsLeft.strawParticleSystemLeft(%d)", i);
        local t = getXMLString(xmlFile, key .. "#type");
        if t == nil then
            break;
        end;
        local desc = FruitUtil.fruitTypes[t];
        if desc ~= nil then
            local currentPS = {};

            local particleNode = Utils.loadParticleSystem(xmlFile, currentPS, key, self.strawNodeLeft, false, "$data/vehicles/particleSystems/threshingStrawParticleSystem.i3d", self.baseDirectory);
            self.strawParticleSystemsLeft[desc.index] = currentPS;
            if self.defaultStrawParticleSystemLeft == nil then
                self.defaultStrawParticleSystemLeft = currentPS;
            end;
        end;
        i = i + 1;
    end;
	self.strawParticleSystemsMiddle = {};
    local i = 0;
    while true do
        local key = string.format("vehicle.strawParticleSystemsMiddle.strawParticleSystemMiddle(%d)", i);
        local t = getXMLString(xmlFile, key .. "#type");
        if t == nil then
            break;
        end;
        local desc = FruitUtil.fruitTypes[t];
        if desc ~= nil then
            local currentPS = {};

            local particleNode = Utils.loadParticleSystem(xmlFile, currentPS, key, self.components, false, "$data/vehicles/particleSystems/threshingStrawParticleSystem.i3d", self.baseDirectory);
            self.strawParticleSystemsMiddle[desc.index] = currentPS;
            if self.defaultStrawParticleSystemMiddle == nil then
                self.defaultStrawParticleSystemMiddle = currentPS;
            end;
        end;
        i = i + 1;
    end;
	self.grainTankParticleSystems = {};
	self.grainTankNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.grainTankParticleSystems#node"));
    local i = 0;
    while true do
        local key = string.format("vehicle.grainTankParticleSystems.grainTankParticleSystem(%d)", i);
        local t = getXMLString(xmlFile, key .. "#type");
        if t == nil then
            break;
        end;
        local desc = FruitUtil.fruitTypes[t];
        if desc ~= nil then
            local currentPS = {};
			
            local particleNode = Utils.loadParticleSystem(xmlFile, currentPS, key, self.grainTankNode, false, "$data/vehicles/particleSystems/threshingStrawParticleSystem.i3d", self.baseDirectory);
            self.grainTankParticleSystems[desc.index] = currentPS;
            if self.defaultGrainTankParticleSystem == nil then
                self.defaultGrainTankParticleSystem = currentPS;
            end;
        end;
        i = i + 1;
    end;

    self.strawToggleTime = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.strawParticleSystems#toggleTime"), 2500);
    self.strawEnableTime = nil;
    self.strawDisableTime = nil;
	self.strawEmitState = false;
	
    self.combineSize = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.combineSize"), 1);

    local numStrawAreas = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.strawAreas#count"), 0);
    self.strawAreas = {}
    for i=1, numStrawAreas do
        local area = {};
        local areanamei = string.format("vehicle.strawAreas.strawArea%d", i);
        area.start = Utils.indexToObject(self.components, getXMLString(xmlFile, areanamei .. "#startIndex"));
        area.width = Utils.indexToObject(self.components, getXMLString(xmlFile, areanamei .. "#widthIndex"));
        area.height = Utils.indexToObject(self.components, getXMLString(xmlFile, areanamei .. "#heightIndex"));
        table.insert(self.strawAreas, area);
    end;

    self.chopperActivated = false;
	self.strawActivated = false;
	self.grainTankActivated = false;
    self.defaultChopperState = false;
	self.defaultGrainTankState = false;
    self.pipeOpening = false;
    self.pipeOpen = false;
    self.pipeClose = true;
    self.pipeParticleActivated = false;

    self.threshingScale = 1;

    self.grainTankFruitTypes = {};
    self.grainTankFruitTypes[FruitUtil.FRUITTYPE_UNKNOWN] = true;

    local fruitTypes = getXMLString(xmlFile, "vehicle.grainTankFruitTypes#fruitTypes");
    if fruitTypes ~= nil then
        local types = Utils.splitString(" ", fruitTypes);
        for k,v in pairs(types) do
            local desc = FruitUtil.fruitTypes[v];
            if desc ~= nil then
                self.grainTankFruitTypes[desc.index] = true;
            end;
        end;
    end;
	
	self.ladder = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.ladder#index"));
	self.handrail = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.handrail#index"));
	self.grainTankPipe = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.grainTankPipe#pipe"));
	self.grainTankElevator = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.grainTankPipe#elevator"));
	
	self.grainTank = {};
	self.grainTank.front = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.grainTank#front"));
	self.grainTank.back = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.grainTank#back"));
	self.grainTank.left = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.grainTank#left"));
	self.grainTank.leftFront = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.grainTank#leftFront"));
	self.grainTank.leftBack = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.grainTank#leftBack"));
	self.grainTank.right = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.grainTank#right"));
	self.grainTank.rightFront = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.grainTank#rightFront"));
	self.grainTank.rightBack = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.grainTank#rightBack"));
	
	self.worklight = {};
	self.worklight.front = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.worklight#front"));
	self.worklight.back = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.worklight#back"));
	
	self.rundumleuchtenAnz = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.rundumleuchten#count"),0);
    self.rundumleuchtenAn = false;
    self.rundumleuchten = {};
    for i=1, self.rundumleuchtenAnz do
        local objname = string.format("vehicle.rundumleuchten.light" .. "%d",i);
        self.rundumleuchten[i] = {};
        self.rundumleuchten[i].rotNode = Utils.indexToObject(self.components, getXMLString(xmlFile, objname .. "#rotNode"));
        self.rundumleuchten[i].light = Utils.indexToObject(self.components, getXMLString(xmlFile, objname .. "#light"));
        self.rundumleuchten[i].source = Utils.indexToObject(self.components, getXMLString(xmlFile, objname .. "#lightsource"));
        self.rundumleuchten[i].speed = Utils.getNoNil(getXMLInt(xmlFile,  objname .. "#rotSpeed"), 1)/1000;
        self.rundumleuchten[i].emit = Utils.getNoNil(getXMLBool(xmlFile, objname .. "#emitLight"), true);
        if not self.rundumleuchten[i].emit and self.rundumleuchten[i].source ~= nil then
           setVisibility(self.rundumleuchten[i].source, false);
        end;
    end;
	
	self.hydraulic = {};
	self.hydraulic.node = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.attacherHydraulik#rotIndex"));
	self.hydraulic.punch = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.attacherHydraulik#transIndex"));
	self.hydraulic.translationPunch = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.attacherHydraulik#translationPunch"));
	self.hydraulic.rotationPunch = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.attacherHydraulik#rotationPunch"));
	local ax, ay, az = getWorldTranslation(self.hydraulic.punch);
    local bx, by, bz = getWorldTranslation(self.hydraulic.translationPunch);
    self.hydraulic.punchDistance = Utils.vector3Length(ax-bx, ay-by, az-bz);
	
	self.driveLight = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.driveLight#index"));
	self.wiper = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.wiper#index"));
	self.strawSheet = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.strawSheet#index"));
	
	self.chopper = {};
	self.chopper.node = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chopperPart1#transportNode"));
	self.chopper.zylinderNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chopperPart1#transportZylRot"));
	self.chopper.zylinderPunch = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chopperPart1#transportZylTrans"));
	self.chopper.translationPunch = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chopperPart1#fixPointTrans"));
	self.chopper.rotationPunch = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chopperPart1#fixPointRot"));
	local ax1, ay1, az1 = getWorldTranslation(self.chopper.zylinderPunch);
    local bx1, by1, bz1 = getWorldTranslation(self.chopper.translationPunch);
    self.chopper.punchDistance = Utils.vector3Length(ax1-bx1, ay1-by1, az1-bz1);
	self.chopper.strawNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chopperPart2#strawNode"));
	self.chopper.strawNode2 = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chopperPart2#strawNode2"));
	self.chopper.zylinderNode2 = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chopperPart2#strawZylRot"));
	self.chopper.zylinderPunch2 = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chopperPart2#strawZylTrans"));
	self.chopper.translationPunch2 = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chopperPart2#fixPointTrans"));
	self.chopper.rotationPunch2 = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chopperPart2#fixPointRot"));
	local ax2, ay2, az2 = getWorldTranslation(self.chopper.zylinderPunch2);
    local bx2, by2, bz2 = getWorldTranslation(self.chopper.translationPunch2);
    self.chopper.punchDistance2 = Utils.vector3Length(ax2-bx2, ay2-by2, az2-bz2);
	self.chopper.drumStrawLeft = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chopperPart3#drumStrawLeft"));
	self.chopper.drumStrawRight = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chopperPart3#drumStrawRight"));
	self.chopper.sheetLeftSmall = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chopperPart3#sheetLeftSmall"));
	self.chopper.sheetLeftBig = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chopperPart3#sheetLeftBig"));
	self.chopper.sheetRightSmall = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chopperPart3#sheetRightSmall"));
	self.chopper.sheetRightBig = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chopperPart3#sheetRightBig"));
	
	self.driveHandle = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.driveHandle#index"));
	
	self.helpPanelPath = Utils.getFilename("Textur/Lexion770special/HUDLexion600.png", self.baseDirectory);
	self.HudWidth = 0.352;
	self.HudHeight = 0.272; --old 0.256;
	self.HudPosX = 0.001;
	self.HudPosY = 0.001;
	self.helpPanelTextPosX = 0.002;
	self.helpPanelTextPosY = 0.356;
	self.helpPanelOverlay = Overlay:new("HUDLexion", self.helpPanelPath, self.HudPosX, self.HudPoxY, self.HudWidth, self.HudHeight);
	self.helpPanelActive = false;
	
    self.currentGrainTankFruitType = FruitUtil.FRUITTYPE_UNKNOWN;
    self.grainTankFillLevel = 0;
    self:setGrainTankFillLevel(0.0, FruitUtil.FRUITTYPE_UNKNOWN);
	
	self.rotationSpeedGrainTank = 0.0006;
	self.ktopen = false;
    self.minThreshold = 0.05;
    self.speedDisplayScale = 1;
    self.drawFillLevel = true;

    self.attachedCutters = {};
    self.numAttachedCutters = 0;

    self.lastLastArea = 0;
    self.lastArea = 0;
	
	self.moveStrawSmall = -0.07;
	self.moveStrawBig = -0.07;
	self.maxSpeed = 0;
	
	self.driveLightActive = false;
	self.transportModeActive = true;
	self.treshingMaschineActive = nil;
	self.worklightActive = false;
	self.worklightActiveFront = false;
	self.worklightActiveBack = false;
	self.cutterActive = nil;
	self.cutterReelActive = false;
	self.isTreshing = false;
	self.isTreshingStarted = false;
	self.strawActive = nil;
	self.ktWarning = false;
	self.specialDriveMode = false;
	self.percentMaschine = 0;
	self.percent = 0;
	self.multipli = 0;
	self.roundWarn = false;
	self.roundMode = 1;
	self.gasMode = 1;
	self.gasWarning1 = false;
	self.gasWarning2 = false;
	self.gasModeText = nil;
	
end;

function Lexion600Combine2:delete()

    for k,v in pairs(self.pipeParticleSystems) do
        Utils.deleteParticleSystem(v);
    end;
    for k,v in pairs(self.chopperParticleSystemsRight) do
        Utils.deleteParticleSystem(v);
    end;
	for k,v in pairs(self.chopperParticleSystemsLeft) do
        Utils.deleteParticleSystem(v);
    end;
    for k,v in pairs(self.strawParticleSystemsLeft) do
        Utils.deleteParticleSystem(v);
    end;
	for k,v in pairs(self.strawParticleSystemsRight) do
        Utils.deleteParticleSystem(v);
    end;
	for k,v in pairs(self.strawParticleSystemsMiddle) do
        Utils.deleteParticleSystem(v);
    end;
	for k,v in pairs(self.grainTankParticleSystems) do
        Utils.deleteParticleSystem(v);
    end;

    if self.threshingStartSound ~= nil then
        delete(self.threshingStartSound);
    end;
    if self.threshingSound ~= nil then
        delete(self.threshingSound);
    end;
	if self.cutterSound ~= nil then
        delete(self.cutterSound);
    end;
    if self.threshingStopSound ~= nil then
        delete(self.threshingStopSound);
    end;
    if self.pipeSound ~= nil then
        delete(self.pipeSound);
    end;

end;

function Lexion600Combine2:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
    local fillLevel = getXMLFloat(xmlFile, key.."#grainTankFillLevel");
    local fruitType = getXMLString(xmlFile, key.."#grainTankFruitType");
    if fillLevel ~= nil and fruitType ~= nil then
        local fruitTypeDesc = FruitUtil.fruitTypes[fruitType];
        if fruitTypeDesc ~= nil then
            self:setGrainTankFillLevel(fillLevel, fruitTypeDesc.index);
        end;
		if fillLevel >= (self.grainTankCapacity/2) then
			self.ktopen = true;
		end;
    end;
    return BaseMission.VEHICLE_LOAD_OK;
end;

function Lexion600Combine2:getSaveAttributesAndNodes(nodeIdent)
    local fruitType = "unknown";
    if self.currentGrainTankFruitType ~= FruitUtil.FRUITTYPE_UNKNOWN then
        fruitType = FruitUtil.fruitIndexToDesc[self.currentGrainTankFruitType].name;
    end;
    local attributes = 'grainTankFillLevel="'..self.grainTankFillLevel..'" grainTankFruitType="'..fruitType..'"';
    return attributes, nil;
end;

function Lexion600Combine2:mouseEvent(posX, posY, isDown, isUp, button)
end;

function Lexion600Combine2:keyEvent(unicode, sym, modifier, isDown)

end;

function Lexion600Combine2:update(dt)

	if self.grainTankFillLevel >= (self.grainTankCapacity/2) then
		self.ktopen = true;
		self.multipli = 5000;
	else
		self.multipli = 1;
	end;
	
	if self.grainTank ~= nil then
		local front = -130*3.1415/180.0;
		local back = 130*3.1415/180.0;
		local left = 145*3.1415/180.0;
		local leftFront = 90*3.1415/180.0;
		local leftBack = -90*3.1415/180.0;
		local right = -145*3.1415/180.0;
		local rightFront = 90*3.1415/180.0;
		local rightBack = -90*3.1415/180.0;
		local grainTankPipe = -45*3.1415/180.0;
		local xfront,yfront,zfront = getRotation(self.grainTank.front);
		local xback,yback,zback = getRotation(self.grainTank.back);
		local xleft,yleft,zleft = getRotation(self.grainTank.left);
		local xleftFront,yleftFront,zleftFront = getRotation(self.grainTank.leftFront);
		local xleftBack,yleftBack,zleftBack = getRotation(self.grainTank.leftBack);
		local xright,yright,zright = getRotation(self.grainTank.right);
		local xrightFront,yrightFront,zrightFront = getRotation(self.grainTank.rightFront);
		local xrightBack,yrightBack,zrightBack = getRotation(self.grainTank.rightBack);
		local xpipe,ypipe,zpipe = getRotation(self.grainTankPipe);
		if self.ktopen then
				xfront = xfront+dt*self.rotationSpeedGrainTank*self.multipli;
				if xfront > 0.0 then
					xfront = 0.0;
				end;
				xback = xback-dt*self.rotationSpeedGrainTank*self.multipli;
				if xback < 0.0 then
					xback = 0.0;
				end;
				if xback == 0 then
					zleft = zleft-dt*self.rotationSpeedGrainTank*self.multipli;
					if zleft < 0.0 then
						zleft = 0.0;
					end;
					zright = zright+dt*self.rotationSpeedGrainTank*self.multipli;
					if zright > 0.0 then
						zright = 0.0;
					end;
					xrightFront = xrightFront-dt*self.rotationSpeedGrainTank*self.multipli/2;
					if xrightFront < 0.0 then
						xrightFront = 0.0;
					end;
					xrightBack = xrightBack+dt*self.rotationSpeedGrainTank*self.multipli/2;
					if xrightBack > 0.0 then
						xrightBack = 0.0;
					end;
					xleftFront = xleftFront-dt*self.rotationSpeedGrainTank*self.multipli/2;
					if xleftFront < 0.0 then
						xleftFront = 0.0;
					end;
					xleftBack = xleftBack+dt*self.rotationSpeedGrainTank*self.multipli/2;
					if xleftBack > 0.0 then
						xleftBack = 0.0;
					end;
					zpipe = zpipe+dt*self.rotationSpeedGrainTank*self.multipli/6;
					if zpipe > 0.0 then
						zpipe = 0.0;
					end;
				end;
			else
				zpipe = zpipe-dt*self.rotationSpeedGrainTank*self.multipli;
				if zpipe < grainTankPipe then
					zpipe = grainTankPipe;
				end;
				zleft = zleft+dt*self.rotationSpeedGrainTank*self.multipli/2;
				if zleft > left then
					zleft = left;
				end;
				zright = zright-dt*self.rotationSpeedGrainTank*self.multipli/2;
				if zright < right then
					zright = right;
				end;
				xleftFront = xleftFront+dt*self.rotationSpeedGrainTank*self.multipli;
				if xleftFront > leftFront then
					xleftFront = leftFront;
				end;
				xleftBack = xleftBack-dt*self.rotationSpeedGrainTank*self.multipli;
				if xleftBack < leftBack then
					xleftBack = leftBack;
				end;
				xrightFront = xrightFront+dt*self.rotationSpeedGrainTank*self.multipli;
				if xrightFront > rightFront then
					xrightFront = rightFront;
				end;
				xrightBack = xrightBack-dt*self.rotationSpeedGrainTank*self.multipli;
				if xrightBack < rightBack then
					xrightBack = rightBack;
				end;
				if zright == right then
					xfront = xfront-dt*self.rotationSpeedGrainTank*self.multipli;
					if xfront < front then
						xfront = front;
					end;
					xback = xback+dt*self.rotationSpeedGrainTank*self.multipli;
					if xback > back then
						xback = back;
					end;
				end;
			end;
			setRotation(self.grainTank.front, xfront, 0, 0);
			setRotation(self.grainTank.back, xback, 0, 0);
			setRotation(self.grainTank.left, 0, 0, zleft);
			setRotation(self.grainTank.leftFront, xleftFront, 0, 0);
			setRotation(self.grainTank.leftBack, xleftBack, 0, 0);
			setRotation(self.grainTank.right, 0, 0, zright);
			setRotation(self.grainTank.rightFront, xrightFront, 0, 0);
			setRotation(self.grainTank.rightBack, xrightBack, 0, 0);
			setRotation(self.grainTankPipe, 0, 0, zpipe);
		end;
	
	if self.rundumleuchtenAn then
		for i=1, self.rundumleuchtenAnz do
		rotate(self.rundumleuchten[i].rotNode, 0, dt*self.rundumleuchten[i].speed, 0);
		end;
	end;
	for i=1, self.rundumleuchtenAnz do
		setVisibility(self.rundumleuchten[i].light, self.rundumleuchtenAn);
	end;
	
	if self.roundMode == 1 then
		self.rundumleuchtenAn = false;
		self.roundWarn = false;
	elseif self.roundMode == 2 then
		self.rundumleuchtenAn = true;
		self.roundWarn = false;
	elseif self.roundMode == 3 then
		self.rundumleuchtenAn = false;
		self.roundWarn = true;
	elseif self.roundMode > 3 then
		self.roundMode = 1;
	end;
	
	if self.gasMode == 1 then
		self.motor.minRpm = 350;
	elseif self.gasMode == 2 then
		self.motor.minRpm = -1500;
	elseif self.gasMode == 3 then
		self.motor.minRpm = -2100;
	end;
	
	if self.gasMode > 3 then
		self.gasMode = 3;
	elseif self.gasMode < 1 then
		self.gasMode = 1;
	end;
	
	if self.cutterActive then
		if self:getIsActiveForSound() then
			if self.cutterSound ~= nil and self.numAttachedCutters > 0 then
				if not self.cutterSoundActive then
					playSample(self.cutterSound, 0, 1, 0);
					self.cutterSoundActive = true;
				end;
			end;
		end;
		if not self.cutterReelActive then
			if self.numAttachedCutters > 0 then
				self.cutterReelActive = true;
				self.chopperActivated = self.defaultChopperState;
				self.grainTankActivated = self.defaultGrainTankState;
				for cutter,implement in pairs(self.attachedCutters) do
					local jointDesc = self.attacherJoints[implement.jointDescIndex];
					jointDesc.moveDown = true;
					cutter:setReelSpeed(0.004);
					cutter:onStartReel();
				end;
			end;
		end;
	else
		if self.cutterReelActive then
			self.cutterReelActive = false;
			for cutter,implement in pairs(self.attachedCutters) do
				local jointDesc = self.attacherJoints[implement.jointDescIndex];
				jointDesc.moveDown = false;
				cutter:onStopReel();
				self.playCutterSound = false;
				self.cutterSoundActive = false;
				if self.cutterSound ~= nil then
					stopSample(self.cutterSound);
				end;
			end;
		end;
	end;
	
if self:getIsActive() then

	if self.isEntered then
		if InputBinding.hasEvent(InputBinding.DRIVEMODE) then
			self.specialDriveMode = not self.specialDriveMode;
		end;
		if InputBinding.hasEvent(InputBinding.ROUNDLIGHT) then
			self.roundMode = self.roundMode + 1;
		end;
		--[[
		if InputBinding.hasEvent(InputBinding.GASADD) then
			self.gasMode = self.gasMode + 1;
		end;
		if InputBinding.hasEvent(InputBinding.GASSUB) then
			self.gasMode = self.gasMode - 1;
		end;
		]]
		if InputBinding.hasEvent(InputBinding.STRAW_ACTIVE) then
			self.strawActive = not self.strawActive;
		end;
		if InputBinding.hasEvent(InputBinding.ACTIVATE_CUTTER) then
			if self.numAttachedCutters > 0 then
				self.cutterActive = not self.cutterActive;
				self.isThreshingStarted = true;
			end;
		end;
		if InputBinding.hasEvent(InputBinding.HELPPANEL) then
			self.helpPanelActive = not self.helpPanelActive;
		end;	
		if InputBinding.hasEvent(InputBinding.TRANSPORT) then
			if self.grainTankFillLevel <= (self.grainTankCapacity/2) then
				self.transportModeActive = not self.transportModeActive;
			else
				self.transportModeActive = false;
			end;
		end;		
		if InputBinding.hasEvent(InputBinding.DRIVELIGHT) or InputBinding.hasEvent(InputBinding.TOGGLE_LIGHTS) then
			if self.isEntered then
				self.driveLightActive = not self.driveLightActive;
				self.lightActive = not self.lightActive;
			end;
		end;
		
		if self.specialDriveMode then
		if self.driveHandle ~= nil then --middle 3.22 for 3.28 back 3.18
			local xHandle, yHandle, zHandle = getTranslation(self.driveHandle);
			local move = self.maxSpeed;
				if self.maxSpeed > 0 then
					zHandle = 3.235 + (move/50000);
					if zHandle > 3.29 then
						zHandle = 3.29;
					end;
				end;
				if self.maxSpeed == 0 then
					zHandle = 3.235;
				end;
				if self.maxSpeed < 0 then
					zHandle = 3.235 - (move/50000)*-1;
					if zHandle < 3.18 then
						zHandle = 3.18;
					end;
				end;
				setTranslation(self.driveHandle, xHandle, yHandle, zHandle);
		end;
		
		self.input = InputBinding.getAnalogInputAxis(InputBinding.AXIS_FORWARD);
		if InputBinding.isAxisZero(self.input) then
			self.input = InputBinding.getDigitalInputAxis(InputBinding.AXIS_FORWARD);
		end;
		
			if self.input == -1 then
				if self.maxSpeed < 500 then
					self.maxSpeed = self.maxSpeed + 35
				elseif self.maxSpeed >= 500 and self.maxSpeed < 1000 then
					self.maxSpeed = self.maxSpeed + 25
				elseif self.maxSpeed >= 1000 and self.maxSpeed < 2000 then
					self.maxSpeed = self.maxSpeed + 45;
				elseif self.maxSpeed >= 2000 then
					self.maxSpeed = self.maxSpeed;
				end;
			end;
			if self.input == 1 then
				if self.maxSpeed > -500 then
					self.maxSpeed = self.maxSpeed - 35
				elseif self.maxSpeed <= -500 and self.maxSpeed > -1000 then
					self.maxSpeed = self.maxSpeed - 25
				elseif self.maxSpeed <= -1000 and self.maxSpeed > -2000 then
					self.maxSpeed = self.maxSpeed - 45;
				elseif self.maxSpeed <= -2000 then
					self.maxSpeed = self.maxSpeed;
				end;
			end;
			if InputBinding.isPressed(InputBinding.DRIVEMODESTOP) then
				self.maxSpeed = 0.0;
			end;

			local acceleration = 0;
			if g_currentMission.allowSteerableMoving and not self.playMotorSound then
				acceleration = -InputBinding.getAnalogInputAxis(InputBinding.AXIS_FORWARD);
				if InputBinding.isAxisZero(acceleration) then
					acceleration = -InputBinding.getDigitalInputAxis(InputBinding.AXIS_FORWARD);
				end;
				if math.abs(acceleration) > 0.8 then
					self.motor:setSpeedLevel(0, true)
				end;
				if self.maxSpeed > 0 then
					acceleration = 1.0;
					self.motor.maxRpmOverride = self.maxSpeed;
				elseif self.maxSpeed < 0 then
					acceleration = -1.0;
					self.motor.maxRpmOverride = self.maxSpeed*-1;
				end;
			end;
			
			if self.steeringEnabled then		
				if self.firstTimeRun then
					WheelsUtil.updateWheelsPhysics(self, dt, self.lastSpeed, acceleration, false, self.requiredDriveMode)
				end;	
			end;
	else
		self.maxSpeed = 0;
		self.motor.maxRpmOverride = self.motor.maxRpm[3];
		local xHandle, yHandle, zHandle = getTranslation(self.driveHandle);
		local move = (self.lastSpeed*self.speedDisplayScale*3600)/400;
			if self.motor.lastMotorRpm > self.motor.minRpm then
				if self.movingDirection == -1 then
					zHandle = 3.235 + move*-1;
					if zHandle < 3.18 then
						zHandle = 3.18;
					end;
				else
					zHandle = 3.235 + move;
					if zHandle > 3.29 then
						zHandle = 3.29;
					end;
				end;
			end;
			if self.motor.lastMotorRpm == self.motor.minRpm then
				zHandle = 3.235;
			end;
			setTranslation(self.driveHandle, xHandle, yHandle, zHandle);
	end;
		
		if not self.transportModeActive then
			if self.grainTankFillLevel < self.grainTankCapacity then
				self.ktWarning = false;
				self.gasWarning1 = false;
				self.gasWarning2 = false;
				if InputBinding.hasEvent(InputBinding.ACTIVATE_TRESHINGMASCHINE) then
					if self.treshingMaschineActive then
						self:stopThreshing();
						if self.isAIThreshing then
							self:stopAIThreshing()
						end;
					else
						--if self.gasMode <= 2 then
							self:startThreshing();
							self.ktopen = true;
						--else
							--self.gasWarning1 = true;
						--end;
					end;
				end;
			end;
		end;
							
		if self.transportModeActive then
			self.cutterActive = false;
			self.ktopen = false;
			if self.treshingMaschineActive then
				self:stopThreshing();
				self:stopAIThreshing();
			end;
			self:closePipe();
			else
				if InputBinding.hasEvent(InputBinding.EMPTY_GRAIN) then
					if self.pipeOpening then
						self:closePipe();
					else
						self:openPipe();
					end;
				end;
				
				if InputBinding.hasEvent(InputBinding.WORKLIGHT) then
					self.worklightActive = not self.worklightActive;
				end;
			end;
			
	end;
	
	if self.chopper ~= nil then
		local ax1, ay1, az1 = getWorldTranslation(self.chopper.zylinderNode);
		local bx1, by1, bz1 = getWorldTranslation(self.chopper.rotationPunch);
		local x1, y1, z1 = worldDirectionToLocal(getParent(self.chopper.zylinderNode), bx1-ax1, by1-ay1, bz1-az1);
		setDirection(self.chopper.zylinderNode,  0, y1*-1, z1*-1, 0, 1, 0);
		if self.chopper.zylinderPunch ~= nil then
			local distance1 = Utils.vector3Length(ax1-bx1, ay1-by1, az1-bz1);
			setTranslation(self.chopper.zylinderPunch, 0, 0, (distance1-self.chopper.punchDistance)*-1);
		end;
		
		local ax2, ay2, az2 = getWorldTranslation(self.chopper.zylinderNode2);
		local bx2, by2, bz2 = getWorldTranslation(self.chopper.rotationPunch2);
		local x3, y3, z3 = worldDirectionToLocal(getParent(self.chopper.zylinderNode2), bx2-ax2, by2-ay2, bz2-az2);
		setDirection(self.chopper.zylinderNode2,  x3, y3, z3, 0, 0, 1);
		if self.chopper.zylinderPunch2 ~= nil then
			local distance2 = Utils.vector3Length(ax2-bx2, ay2-by2, az2-bz2);
			setTranslation(self.chopper.zylinderPunch2, 0, (distance2-self.chopper.punchDistance2)*-1, 0);
		end;
	
		local xstraw, ystraw, zstraw = getRotation(self.chopper.strawNode); --29|0
		local x1straw, y1straw, z1straw = getRotation(self.chopper.strawNode2); --29|0|0
		local x2straw, y2straw, z2straw = getRotation(self.chopper.node); --29|0|0|0 
		local xBlech, yBlech, zBlech = getRotation(self.strawSheet);
		local moveSpeed = 0.0003;
		local nodeMin = -80*3.1456/180.0;
		local node2Min = 80*3.1456/180.0;
		local xRotMax = 41*3.1456/180.0;
		local xRotMax2 = 47*3.1456/180.0;
		local xRotMin2 = 0*3.1456/180.0;
		local xRotMin2straw = -10*3.1456/180.0;
			if self.transportModeActive then
				xstraw = xstraw+dt*moveSpeed;
				if xstraw > xRotMin2 then
					xstraw = xRotMin2; --0
				end;
				x2straw = x2straw-dt*moveSpeed;
				if x2straw < xRotMin2 then
					x2straw = xRotMin2; --0
				end;
				if xstraw >= xRotMin2 then
					xBlech = xBlech+dt*moveSpeed*1.25;
					if xBlech > xRotMax2 then
						xBlech = xRotMax2; 
					end;
					x1straw = x1straw+dt*moveSpeed;
					if x1straw > xRotMax then
						x1straw = xRotMax; --41
					end;
				end;
			else
				if self.strawActive then
					xBlech = xBlech-dt*moveSpeed*1.21;
					if xBlech < xRotMin2straw then
						xBlech = xRotMin2straw;
					end;
					x1straw = x1straw-dt*moveSpeed;
					if x1straw < xRotMin2 then
						x1straw = xRotMin2
					end;
					if x1straw <= xRotMin2 then
						x2straw = x2straw+dt*moveSpeed;
						if x2straw > node2Min then
							x2straw = node2Min; 
						end;
						xstraw = xstraw-dt*moveSpeed;
						if xstraw < nodeMin then
							xstraw = nodeMin; 
						end;
					end;
				else
					xBlech = xBlech-dt*moveSpeed*1.21;
					if xBlech < xRotMin2 then
						xBlech = xRotMin2;
					end;
					x1straw = x1straw-dt*moveSpeed;
					if x1straw < xRotMin2 then
						x1straw = xRotMin2
					end;
					x2straw = x2straw-dt*moveSpeed;
					if x2straw < xRotMin2 then
						x2straw = xRotMin2;
					end;
					xstraw = xstraw+dt*moveSpeed;
					if xstraw > xRotMin2 then
					xstraw = xRotMin2;
					end;
				end;
			end;
		setRotation(self.chopper.strawNode, xstraw, 0, 0);
		setRotation(self.chopper.node, x2straw, 0, 0);
		setRotation(self.chopper.strawNode2, x1straw, 0, 0);
		setRotation(self.strawSheet, xBlech, 0, 0);
	end;
		
	if self.ladder ~= nil then
	local rotationSpeedLadder = 0.0006;
	local ladderMinRotY = -90*3.1415/180.0;
	local handrailMinRotY = -90*3.1415/180.0;
		if self.ladder ~= nil and self.handrail ~= nil then
			local xladder,yladder,zladder = getRotation(self.ladder);
			local xhandrail,yhandrail,zhandrail = getRotation(self.handrail);
		if self.transportModeActive == true then
			yladder = yladder-dt*rotationSpeedLadder;
            if yladder < ladderMinRotY then
               yladder = ladderMinRotY;
            end;
			yhandrail = yhandrail-dt*rotationSpeedLadder;
			if yhandrail < handrailMinRotY then
				yhandrail = handrailMinRotY;
            end;
        else
            yladder = yladder+dt*rotationSpeedLadder;
            if yladder > 0.0 then
                yladder = 0.0;
            end;
            yhandrail = yhandrail+dt*rotationSpeedLadder;
            if yhandrail > 0.0 then
                yhandrail = 0.0;
            end;
        end;
        setRotation(self.ladder, 0, yladder, 0);
        setRotation(self.handrail, 0, yhandrail, 0);
	end;
	end;
			
	if self.pipe ~= nil then
		local pipeRotationSpeed = 0.0006;
        local pipeMinRotY = -90*3.1415/180.0;
        local pipeMaxRotX = 12*3.1415/180.0;
        local pipeXRotationSpeed = 0.00008;
        if self.pipe ~= nil then
            local x,y,z = getRotation(self.pipe);

            if self.pipeOpening then
                y = y-dt*pipeRotationSpeed;
                if y < pipeMinRotY then
                    y = pipeMinRotY;
                end;
                x = x+dt*pipeXRotationSpeed;
                if x > pipeMaxRotX then
                    x = pipeMaxRotX;
                end;
            else
                y = y+dt*pipeRotationSpeed;
                if y > 0.0 then
                    y = 0.0;
                end;
                x = x-dt*pipeXRotationSpeed;
                if x < 0.0 then
                    x = 0.0;
                end;
            end;
            setRotation(self.pipe, x, y, z);

            self.pipeOpen = (math.abs(pipeMinRotY-y) < 0.01);
            self.pipeClose =  ((x == 0) and (y == 0) );
			end;
	end;

	if self.worklightActive then
		if self.transportModeActive then
			setVisibility(self.worklight.front, false);
			setVisibility(self.worklight.back, false);
			if self.driveLightActive then
				setVisibility(self.driveLight, true);
			else
				setVisibility(self.driveLight, false);
			end;
		else
			setVisibility(self.worklight.front, true);
			if self.pipeOpening then
				setVisibility(self.worklight.back, false);
			else
				setVisibility(self.worklight.back, true);
			end;
			if self.driveLightActive then
				setVisibility(self.driveLight, false);
			else
				setVisibility(self.driveLight, true);
			end;
		end;
	else
		setVisibility(self.worklight.front, false);
		setVisibility(self.worklight.back, false);
	end;

	if self.driveLightActive then
		setVisibility(self.driveLight, true);
		if self.transportModeActive then
			setVisibility(self.driveLight, true);
		else
			if self.worklightActive then
				setVisibility(self.driveLight, false);
			else
				setVisibility(self.driveLight, true);
			end;
		end;
	else
		setVisibility(self.driveLight, false);
	end;
	
	if self.treshingMaschineActive then
	
			rotate(self.chopper.drumStrawLeft, 0, -dt*0.75, 0);
			rotate(self.chopper.drumStrawRight, 0, dt*0.75, 0);
			local yMaxBig = Utils.degToRad(55);
			local yMinBig = Utils.degToRad(-55);
			local yMaxSmall = Utils.degToRad(32.5);
			local yMinSmall = Utils.degToRad(-32.5);
			local xsheetLeftSmall, ysheetLeftSmall, zsheetLeftSmall = getRotation(self.chopper.sheetLeftSmall);
			local xsheetLeftBig, ysheetLeftBig, zsheetLeftBig = getRotation(self.chopper.sheetLeftBig);
			local xsheetRightSmall, ysheetRightSmall, zsheetRightSmall = getRotation(self.chopper.sheetRightSmall);
			local xsheetRightBig, ysheetRightBig, zsheetRightBig = getRotation(self.chopper.sheetRightBig);
			--special Thanks to Sven777b
				if (ysheetLeftBig > yMaxBig or ysheetLeftBig < yMinBig) then 
				self.moveStrawBig = self.moveStrawBig*-1; 
				end;
				if (ysheetLeftSmall > yMaxSmall or ysheetLeftSmall < yMinSmall) then 
				self.moveStrawSmall = self.moveStrawSmall*-1; 
				end; 				
			ysheetLeftSmall = ysheetLeftSmall + self.moveStrawSmall*0.827;
			ysheetLeftBig = ysheetLeftBig + self.moveStrawBig*1.4;
			ysheetRightSmall = ysheetRightSmall + self.moveStrawSmall*0.827;
			ysheetRightBig = ysheetRightBig + self.moveStrawBig*1.4;
			
			setRotation(self.chopper.sheetLeftSmall, 0, ysheetLeftSmall, 0);
			setRotation(self.chopper.sheetLeftBig, 0, ysheetLeftBig, 0);
			setRotation(self.chopper.sheetRightSmall, 0, ysheetRightSmall, 0);
			setRotation(self.chopper.sheetRightBig, 0, ysheetRightBig, 0);
	
		if self.grainTankElevator ~= nil then
			rotate(self.grainTankElevator, 0, dt*0.045, 0);
		end;

		if self.playThreshingSound then
			if self:getIsActiveForSound() then
				if self.threshingSound ~= nil and self.playThreshingSoundTime <= self.time then
					playSample(self.threshingSound, 0, 1, 0);
					self.playThreshingSound = false;
					self.threshingSoundActive = true;
				end;
			end;
		end;
		
		local percent = self.grainTankFillLevel/self.grainTankCapacity*100;
		if percent > 75 then
			if self.roundWarn == false then				
				self:openPipe();
			else
				self.rundumleuchtenAn = true;
				for i=1, self.rundumleuchtenAnz do
					setVisibility(self.rundumleuchten[i].light, true);
				end;
				self:openPipe();
			end;
		end;
		
		if self.pipeOpening and percent < 75 then
			self.rundumleuchtenAn = false;
			for i=1, self.rundumleuchtenAnz do
				setVisibility(self.rundumleuchten[i].light, false);
			end;
		end;
	
	end;
		
    local disableChopperEmit = true;
    local disableStrawEmit = true;
	local disableGrainTankEmit = true;
		
	if self.treshingMaschineActive then
		local lastArea = 0;
		local percentArea = 0;
        local fruitType = FruitUtil.FRUITTYPE_UNKNOWN;
            for cutter,implement in pairs(self.attachedCutters) do
                if cutter.reelStarted then
                    if cutter.lastArea > 0 then
                        for cutter,implement in pairs(self.attachedCutters) do
                            cutter:setFruitType(cutter.currentFruitType);
                            self.currentGrainTankFruitType = cutter.currentFruitType;
                        end;
                        fruitType = cutter.currentFruitType;
                        lastArea = lastArea + cutter.lastArea;
						percentArea = percentArea + cutter.percentArea;
                    end;
                end;
            end;
            self.lastArea = lastArea;
			self.percentArea = percentArea;
            if lastArea > 0 then
                local fruitDesc = FruitUtil.fruitIndexToDesc[fruitType];
                if fruitDesc.hasStraw then
					if self.strawActive then
						self.strawActivated = true;
						self.chopperActivated = false;
						self.grainTankActivated = true;
					else
						self.strawActivated = false;
						self.chopperActivated = true;
						self.grainTankActivated = true;
					end;				
				else
					self.strawActivated = false;
					self.chopperActivated = true;
					self.grainTankActivated = true;
					self.strawActive = false;
				end;
				
				if self.grainTankActivated then
					if self.grainTankEnableTime == nil then
						self.grainTankEnableTime = self.time + self.grainTankToggleTime;
					else
						self.grainTankDisableTime = nil;
					end;
					disableGrainTankEmit = false;
				end;

                if self.chopperActivated then
                    if self.chopperEnableTime == nil then
                        self.chopperEnableTime = self.time + self.chopperToggleTime;	
                    else
                        self.chopperDisableTime = nil;		
                    end;
                    disableChopperEmit = false;
				end;
				
                if self.strawActivated then
                    if self.strawEnableTime == nil then
                        self.strawEnableTime = self.time + self.strawToggleTime;
                    else
                        self.strawDisableTime = nil;
                    end;
                    disableStrawEmit = false;
                end;
					
                -- 8000/1200 = 6.66 liter/meter
                -- 8000/1200 / 6 = 1.111 liter/m^2
                -- 8000/1200 / 6 / 2^2 = 0.277777 liter / density pixel (density is 4096^2, on a area of 2048m^2
                local pixelToQm = 2048 / 4096 * 2048 / 4096  / g_currentMission.maxFruitValue; -- 4096px are mapped to 2048m
                local literPerQm = 1;
                if (fruitType ~= FruitUtil.FRUITTYPE_UNKNOWN) then
                    literPerQm = FruitUtil.fruitIndexToDesc[fruitType].literPerQm * (1 + 0.5 * (3 - g_currentMission.missionStats.difficulty));
                end;

                --local literPerPixel = 8000/1200 / 6 / (2*2);

                --literPerPixel = literPerPixel*1.5;
                local qm = lastArea*pixelToQm;
                local newFillLevel = self.grainTankFillLevel+qm*literPerQm*self.threshingScale;
                self:setGrainTankFillLevel(newFillLevel, fruitType);
				
				local multipli = 1;
				if self.strawActive then
					local multipli = 0.8;
				end;
				if (fruitType ~= FruitUtil.FRUITTYPE_UNKNOWN) then
					self.percent = ((percentArea*8.2)*multipli)+(FruitUtil.fruitIndexToDesc[fruitType].literPerQm*15);
				end;
				--[[
				if self.gasMode < 3 then
					self.gasWarning2 = true;
				else
					self.gasWarning2 = false;
				end;]]
			else
				self.percent = 0;
            end;
			
		if self.percent ~= 0 then
			if self.percentMaschine > self.percent then
				self.percentMaschine = self.percentMaschine-0.025*dt;
			end;
			if self.percentMaschine < self.percent then
				self.percentMaschine = self.percentMaschine+0.03*dt;
			end;
		else
			self.percentMaschine = self.percentMaschine-0.025*dt;
		end;
		
		if self.percentMaschine > 100 then
			self.percentMaschine = 100;
		elseif self.percentMaschine < 0 then
			self.percentMaschine = 0
		end;
			
		if self.percentMaschine > 99 then
			for cutter,implement in pairs(self.attachedCutters) do
			cutter.speedLimit = 0;
			end;
		else
			for cutter,implement in pairs(self.attachedCutters) do
			cutter.speedLimit = 24-(self.percentMaschine/11.38);
			cutter.speedViolationTimer = cutter.speedViolationMaxTime;
			end;
		end;
		
	end;
	
	if disableChopperEmit and self.chopperDisableTime == nil then
		self.chopperDisableTime = self.time + self.chopperToggleTime;
	end;
			
	if disableStrawEmit and self.strawDisableTime == nil then
		self.strawDisableTime = self.time + self.strawToggleTime;
	end;
			
	if disableGrainTankEmit and self.grainTankDisableTime == nil then
		self.grainTankDisableTime = self.time + self.grainTankToggleTime;
	end;

    if self.grainTankFillLevel <= 0 then
            for cutter,implement in pairs(self.attachedCutters) do
                cutter:resetFruitType();
            end;
            self.currentGrainTankFruitType = FruitUtil.FRUITTYPE_UNKNOWN;
        end;

    if self.pipeLight ~= nil then
            local pipeLightActive = (self.lightsActive or self.worklightActive) and self.pipeOpening;
            setVisibility(self.pipeLight, pipeLightActive);
        end;
		
	if self.grainTankFillLevel >= self.grainTankCapacity then
			self.cutterActive = false;
			self.chopperActivated = false;
			self.grainTankActivated = false;
			self.strawActivated = false;
			if self.numAttachedCutters > 0 and self.cutterReelActive then
				self.motor.speedLevel = 0;
				self.maxSpeed = 0;
			end;
		end;

    if self.motor ~= nil then
            if self.motor.speedLevel == 1 then
                self.speedDisplayScale = 0.9;
            elseif self.motor.speedLevel == 2 then
                self.speedDisplayScale = 0.8;
            else
                self.speedDisplayScale = 1.0;
            end;
        end;
		
    if not self.pipeOpen or not self.pipeClose then
            if self.pipeSound ~= nil and not self.pipeSoundEnabled then
                if self:getIsActiveForSound() then
                    setSamplePitch(self.pipeSound, self.pipeSoundPitchOffset);
                    playSample(self.pipeSound, 0, 1, 0);
                    self.pipeSoundEnabled = true;
                end;
            end;
        end;

    if self.pipeOpen then
            if self.pipeSound ~= nil and self.pipeSoundEnabled then
                stopSample(self.pipeSound);
                self.pipeSoundEnabled = false;
            end;
        end;

    if self.pipeClose then
            if self.pipeSound ~= nil and self.pipeSoundEnabled then
                stopSample(self.pipeSound);
                self.pipeSoundEnabled = false;
            end;
        end;
		
	if self.grainTankEnableTime ~= nil and self.grainTankEnableTime <= self.time then
			if self.currentGrainTankParticleSystem ~= nil then
                Utils.setEmittingState(self.currentGrainTankParticleSystem, false);
            end;
            self.currentGrainTankParticleSystem = self.grainTankParticleSystems[self.currentGrainTankFruitType];
			if self.currentGrainTankParticleSystem == nil then
                self.currentGrainTankParticleSystem = self.defaultGrainTankParticleSystem;
            end;
            Utils.setEmittingState(self.currentGrainTankParticleSystem, true);
			self.grainTankEnableTime = nil;
        end;

    if self.chopperEnableTime ~= nil and self.chopperEnableTime <= self.time then
            if self.currentChopperParticleSystemRight ~= nil then
                Utils.setEmittingState(self.currentChopperParticleSystemRight, false);
            end;
			if self.currentChopperParticleSystemLeft ~= nil then
                Utils.setEmittingState(self.currentChopperParticleSystemLeft, false);
            end;
            self.currentChopperParticleSystemRight = self.chopperParticleSystemsRight[self.currentGrainTankFruitType];
			self.currentChopperParticleSystemLeft = self.chopperParticleSystemsLeft[self.currentGrainTankFruitType];
            if self.currentChopperParticleSystemLeft == nil then
                self.currentChopperParticleSystemLeft = self.defaultChopperParticleSystemLeft;
            end;
            if self.currentChopperParticleSystemRight == nil then
                self.currentChopperParticleSystemRight = self.defaultChopperParticleSystemRight;
            end;
            Utils.setEmittingState(self.currentChopperParticleSystemRight, true);
			Utils.setEmittingState(self.currentChopperParticleSystemLeft, true);
            self.chopperEnableTime = nil;
		end;	
		
    if self.strawEnableTime ~= nil and self.strawEnableTime <= self.time then
            if self.currentStrawParticleSystemRight ~= nil then
                Utils.setEmittingState(self.currentStrawParticleSystemRight, false);
            end;
			if self.currentStrawParticleSystemLeft ~= nil then
                Utils.setEmittingState(self.currentStrawParticleSystemLeft, false);
            end;
			if self.currentStrawParticleSystemMiddle ~= nil then
                Utils.setEmittingState(self.currentStrawParticleSystemMiddle, false);
            end;
            self.currentStrawParticleSystemRight = self.strawParticleSystemsRight[self.currentGrainTankFruitType];
			self.currentStrawParticleSystemLeft = self.strawParticleSystemsLeft[self.currentGrainTankFruitType];
			self.currentStrawParticleSystemMiddle = self.strawParticleSystemsMiddle[self.currentGrainTankFruitType];
            if self.currentStrawParticleSystemLeft == nil then
                self.currentStrawParticleSystemLeft = self.defaultStrawParticleSystemLeft;
            end;
            if self.currentStrawParticleSystemRight == nil then
                self.currentStrawParticleSystemRight = self.defaultStrawParticleSystemRight;
            end;
			if self.currentStrawParticleSystemMiddle == nil then
                self.currentStrawParticleSystemMiddle = self.defaultStrawParticleSystemMiddle;
            end;
			
			Utils.setEmittingState(self.currentStrawParticleSystemMiddle, true);
			Utils.setEmittingState(self.currentStrawParticleSystemLeft, true);
            Utils.setEmittingState(self.currentStrawParticleSystemRight, true);
            self.strawEnableTime = nil;
            self.strawEmitState = true;
        end;
		
	if self.strawActive then
		if self.strawEmitState then
			for k, strawArea in pairs(self.strawAreas) do
				local x,y,z = getWorldTranslation(strawArea.start);
				local x1,y1,z1 = getWorldTranslation(strawArea.width);
				local x2,y2,z2 = getWorldTranslation(strawArea.height);
				local old, total = Utils.getFruitWindrowArea(self.currentGrainTankFruitType, x, z, x1, z1, x2, z2);
				local value = 1+math.floor(old / total + 0.7); -- round, biased to the bigger value
				value = math.min(value, g_currentMission.maxWindrowValue);
				Utils.updateFruitWindrowArea(self.currentGrainTankFruitType, x, z, x1, z1, x2, z2, value, true);
			end;
		end;
	end;

	if self.grainTankDisableTime ~= nil and self.grainTankDisableTime <= self.time then
		if self.currentGrainTankParticleSystem ~= nil then
            Utils.setEmittingState(self.currentGrainTankParticleSystem, false);
        end;
        self.currentGrainTankParticleSystem = self.grainTankParticleSystems[self.currentGrainTankFruitType];
		if self.currentGrainTankParticleSystem == nil then
            self.currentGrainTankParticleSystem = self.defaultGrainTankParticleSystem;
        end;
		Utils.setEmittingState(self.currentGrainTankParticleSystem, false);
		self.grainTankDisableTime = nil;
    end;
		
    if self.chopperDisableTime ~= nil and self.chopperDisableTime <= self.time then
        if self.currentChopperParticleSystemRight ~= nil then
            Utils.setEmittingState(self.currentChopperParticleSystemRight, false);
        end;
		if self.currentChopperParticleSystemLeft ~= nil then
            Utils.setEmittingState(self.currentChopperParticleSystemLeft, false);
        end;
        self.currentChopperParticleSystemRight = self.chopperParticleSystemsRight[self.currentGrainTankFruitType];
		self.currentChopperParticleSystemLeft = self.chopperParticleSystemsLeft[self.currentGrainTankFruitType];
        if self.currentChopperParticleSystemLeft == nil then
            self.currentChopperParticleSystemLeft = self.defaultChopperParticleSystemLeft;
        end;
        if self.currentChopperParticleSystemRight == nil then
            self.currentChopperParticleSystemRight = self.defaultChopperParticleSystemRight;
        end;
		Utils.setEmittingState(self.currentChopperParticleSystemLeft, false);
        Utils.setEmittingState(self.currentChopperParticleSystemRight, false);
        self.chopperDisableTime = nil;
	end;
	
    if self.strawDisableTime ~= nil and self.strawDisableTime <= self.time then
        if self.currentStrawParticleSystemRight ~= nil then
            Utils.setEmittingState(self.currentStrawParticleSystemRight, false);
        end;
		if self.currentStrawParticleSystemLeft ~= nil then
            Utils.setEmittingState(self.currentStrawParticleSystemLeft, false);
        end;
		if self.currentStrawParticleSystemMiddle ~= nil then
            Utils.setEmittingState(self.currentStrawParticleSystemMiddle, false);
        end;
        self.currentStrawParticleSystemRight = self.strawParticleSystemsRight[self.currentGrainTankFruitType];
		self.currentStrawParticleSystemLeft = self.strawParticleSystemsLeft[self.currentGrainTankFruitType];
		self.currentStrawParticleSystemMiddle = self.strawParticleSystemsMiddle[self.currentGrainTankFruitType];
        if self.currentStrawParticleSystemLeft == nil then
            self.currentStrawParticleSystemLeft = self.defaultStrawParticleSystemLeft;
        end;
        if self.currentStrawParticleSystemRight == nil then
            self.currentStrawParticleSystemRight = self.defaultStrawParticleSystemRight;
        end;
		if self.currentStrawParticleSystemMiddle == nil then
            self.currentStrawParticleSystemMiddle = self.defaultStrawParticleSystemMiddle;
        end;
		Utils.setEmittingState(self.currentStrawParticleSystemLeft, false);
		Utils.setEmittingState(self.currentStrawParticleSystemMiddle, false);
        Utils.setEmittingState(self.currentStrawParticleSystemRight, false);
        self.strawDisableTime = nil;
        self.strawEmitState = false;
	end;
	
    self.lastUnloadingTrailer = nil;
    self.pipeParticleActivated = false;
    if self.pipeOpen then
        if self.grainTankFillLevel > 0 then
            self.pipeParticleActivated = true;
            -- test if we should drain the grain tank
            self.trailerFound = 0;
            local x,y,z = getWorldTranslation(self.pipeRaycastNode);
            raycastAll(x, y, z, 0, -1, 0, "findTrailerRaycastCallback", 10, self);

            local trailer = g_currentMission.objectToTrailer[self.trailerFound];
            self.lastUnloadingTrailer = trailer;
            if self.trailerFound == 0 or trailer == nil or not trailer:allowFillType(self.currentGrainTankFruitType, true) or not trailer.allowFillFromAir then
                self.pipeParticleActivated = false;
            else
                local deltaLevel = self.grainTankUnloadingCapacity*dt/1000.0;
                deltaLevel = math.min(deltaLevel, trailer.capacity - trailer.fillLevel);

                self.grainTankFillLevel = self.grainTankFillLevel-deltaLevel;
                if self.grainTankFillLevel <= 0.0 then
                    deltaLevel = deltaLevel+self.grainTankFillLevel;
                    self.grainTankFillLevel = 0.0;
                    self.pipeParticleActivated = false;
                end;
                if deltaLevel == 0 then
                    self.pipeParticleActivated = false;
                end;
                self:setGrainTankFillLevel(self.grainTankFillLevel, self.currentGrainTankFruitType);
                trailer:setFillLevel(trailer.fillLevel+deltaLevel, self.currentGrainTankFruitType);
            end;
        end;
    end;

    if self.currentGrainTankFruitType ~= FruitUtil.FRUITTYPE_UNKNOWN then
        if self.currentPipeParticleSystem ~= nil then
            Utils.setEmittingState(self.currentPipeParticleSystem, false);
        end;
        if self.pipeParticleActivated then
            self.currentPipeParticleSystem = self.pipeParticleSystems[self.currentGrainTankFruitType];
            if self.currentPipeParticleSystem == nil then
                self.currentPipeParticleSystem = self.defaultPipeParticleSystem;
            end;
            Utils.setEmittingState(self.currentPipeParticleSystem, true);
        end;
    end;
	
	if self.hydraulic ~= nil then
		local ax, ay, az = getWorldTranslation(self.hydraulic.node);
		local bx, by, bz = getWorldTranslation(self.hydraulic.rotationPunch);
		local x, y, z = worldDirectionToLocal(getParent(self.hydraulic.node), bx-ax, by-ay, bz-az);
		setDirection(self.hydraulic.node, x, y, z, 0, 1, 0);
		if self.hydraulic.punch ~= nil then
			local distance = Utils.vector3Length(ax-bx, ay-by, az-bz);
			setTranslation(self.hydraulic.punch, 0, 0, (distance-self.hydraulic.punchDistance));
		end;
	end;
	
	if g_currentMission.environment.lastRainScale <= 0.02 and g_currentMission.environment.timeSinceLastRain > 20 then
		setRotation(self.wiper, 0, 0, 0);
	else
		rotate(self.wiper, 0, 0, dt*0.005);
	end;
	
end;
	
end;

function Lexion600Combine2:draw()
	if self.ktWarning then
		setTextColor(1.0, 0.0, 0.0, 1.0);
		renderText(0.3, 0.48, 0.055, string.format("%s", g_i18n:getText("warning1")));
		setTextColor(1.0, 1.0, 1.0, 1.0);
		g_currentMission:addWarning("", 0.018, 0.033);
	end;
	
    local percent = self.grainTankFillLevel/self.grainTankCapacity*100;
    if self.drawFillLevel then
        self:drawGrainLevel(self.grainTankFillLevel, self.grainTankCapacity, 95);
    end;
	
    if self.pipeOpen and not self.pipeParticleActivated and self.grainTankFillLevel > 0 then
        g_currentMission:addExtraPrintText(g_i18n:getText("Move_the_pipe_over_a_trailer"));
    elseif self.grainTankFillLevel == self.grainTankCapacity then
        g_currentMission:addExtraPrintText(g_i18n:getText("Dump_corn_to_continue_threshing"));
    end;
	
	if self.currentGrainTankFruitType ~= FruitUtil.FRUITTYPE_UNKNOWN then
        g_currentMission.fruitOverlays[self.currentGrainTankFruitType]:render();
    end;
	
	if self.specialDriveMode then
		g_currentMission:addHelpButtonText(g_i18n:getText("driveModeOn"), InputBinding.DRIVEMODE);
	else
		g_currentMission:addHelpButtonText(g_i18n:getText("driveModeOff"), InputBinding.DRIVEMODE);
	end;
	
	if self.cutterActive and not self.treshingMaschineActive then
		for cutter,implement in pairs(self.attachedCutters) do
			if cutter.lastArea > 0 then
				setTextColor(1.0, 0.0, 0.0, 1.0);
				renderText(0.3, 0.48, 0.055, string.format("%s", g_i18n:getText("warning2")));
				setTextColor(1.0, 1.0, 1.0, 1.0);
				g_currentMission:addWarning("", 0.018, 0.033);
			end;
		end;
	end;
	if self.gasWarning1 then
		setTextColor(1.0, 0.0, 0.0, 1.0);
		renderText(0.3, 0.48, 0.055, string.format("%s", g_i18n:getText("gasWarning1")));
		setTextColor(1.0, 1.0, 1.0, 1.0);
		g_currentMission:addWarning("", 0.018, 0.033);
	end;
	if self.gasWarning2 then
		setTextColor(1.0, 0.0, 0.0, 1.0);
		renderText(0.3, 0.48, 0.055, string.format("%s", g_i18n:getText("gasWarning2")));
		setTextColor(1.0, 1.0, 1.0, 1.0);
		g_currentMission:addWarning("", 0.018, 0.033);
	end;
				
	if self.helpPanelActive then
		self.helpPanelOverlay:render();
		if self.roundMode == 1 then
			renderText(self.helpPanelTextPosX, self.helpPanelTextPosY-0.242, 0.022, string.format("Taste %s: %s", InputBinding.getButtonKeyName(InputBinding.ROUNDLIGHT), g_i18n:getText("roundlightOff")));
		elseif self.roundMode == 2 then
			renderText(self.helpPanelTextPosX, self.helpPanelTextPosY-0.242, 0.022, string.format("Taste %s: %s", InputBinding.getButtonKeyName(InputBinding.ROUNDLIGHT), g_i18n:getText("roundlightOn")));
		elseif self.roundMode == 3 then
			renderText(self.helpPanelTextPosX, self.helpPanelTextPosY-0.242, 0.022, string.format("Taste %s: %s", InputBinding.getButtonKeyName(InputBinding.ROUNDLIGHT), g_i18n:getText("roundlightAuto")));
		end;
		renderText(self.helpPanelTextPosX, self.helpPanelTextPosY-0.11, 0.022, string.format("Taste %s: %s", InputBinding.getButtonKeyName(InputBinding.HELPPANEL), g_i18n:getText("helpPanelOn")));
		if self.gasMode == 1 then
			self.gasModeText = "Standgas";
		elseif self.gasMode == 2 then
			self.gasModeText = "1/2 Gas";
		elseif self.gasMode == 3 then
			self.gasModeText = "Vollgas";
		end;
		--renderText(self.helpPanelTextPosX, self.helpPanelTextPosY-0.352, 0.022, string.format("Taste %s / %s: %s", InputBinding.getButtonKeyName(InputBinding.GASSUB), InputBinding.getButtonKeyName(InputBinding.GASADD), self.gasModeText));
		if self.transportModeActive then
			renderText(self.helpPanelTextPosX, self.helpPanelTextPosY-0.132, 0.022, string.format("Taste %s: %s", InputBinding.getButtonKeyName(InputBinding.TRANSPORT), g_i18n:getText("transportActive")));
		else
			renderText(self.helpPanelTextPosX, self.helpPanelTextPosY-0.132, 0.022, string.format("Taste %s: %s", InputBinding.getButtonKeyName(InputBinding.TRANSPORT), g_i18n:getText("transportNotActive")));
			if self.treshingMaschineActive then
					local red = 1.0;
					local green = 1.0;
				if self.percentMaschine < 50 then
					red = (self.percentMaschine/50);
				elseif self.percentMaschine > 50 then
					green = 2-(self.percentMaschine/50);
				end;
					setTextColor(red, green, 0.0, 1.0);
					renderText(self.helpPanelTextPosX, self.helpPanelTextPosY-0.154, 0.022, string.format("Dreschwerkauslastung: %d%%", self.percentMaschine));
					setTextColor(1.0, 1.0, 1.0, 1.0);
				renderText(self.helpPanelTextPosX, self.helpPanelTextPosY-0.176, 0.022, string.format("Taste %s: %s", InputBinding.getButtonKeyName(InputBinding.ACTIVATE_TRESHINGMASCHINE), g_i18n:getText("treshingDeActive")));
				if self.strawActive then
					renderText(self.helpPanelTextPosX, self.helpPanelTextPosY-0.198, 0.022, string.format("Taste %s: %s", InputBinding.getButtonKeyName(InputBinding.STRAW_ACTIVE), g_i18n:getText("strawOn")));
				else
					renderText(self.helpPanelTextPosX, self.helpPanelTextPosY-0.198, 0.022, string.format("Taste %s: %s", InputBinding.getButtonKeyName(InputBinding.STRAW_ACTIVE), g_i18n:getText("strawOff")));
				end;
				if self.pipeOpening then
					renderText(self.helpPanelTextPosX, self.helpPanelTextPosY-0.22, 0.022, string.format("Taste %s: %s", InputBinding.getButtonKeyName(InputBinding.EMPTY_GRAIN), g_i18n:getText("Pipe_in")));
				else
					renderText(self.helpPanelTextPosX, self.helpPanelTextPosY-0.22, 0.022, string.format("Taste %s: %s", InputBinding.getButtonKeyName(InputBinding.EMPTY_GRAIN), g_i18n:getText("Dump_corn")));
				end;
				if self.worklightActive then
					renderText(self.helpPanelTextPosX, self.helpPanelTextPosY-0.264, 0.022, string.format("Taste %s: %s", InputBinding.getButtonKeyName(InputBinding.WORKLIGHT), g_i18n:getText("nightWorklightOn")));
				else
					renderText(self.helpPanelTextPosX, self.helpPanelTextPosY-0.264, 0.022, string.format("Taste %s: %s", InputBinding.getButtonKeyName(InputBinding.WORKLIGHT), g_i18n:getText("nightWorklightOff")));
				end;
			else
				renderText(self.helpPanelTextPosX, self.helpPanelTextPosY-0.176, 0.022, string.format("Taste %s: %s", InputBinding.getButtonKeyName(InputBinding.ACTIVATE_TRESHINGMASCHINE), g_i18n:getText("treshingActive")));
			end;
			if self.numAttachedCutters > 0 then
				if self.cutterActive then
					renderText(self.helpPanelTextPosX, self.helpPanelTextPosY-0.286, 0.022, string.format("Taste %s: %s", InputBinding.getButtonKeyName(InputBinding.ACTIVATE_CUTTER), g_i18n:getText("Turn_off_cutter")));
				else
					renderText(self.helpPanelTextPosX, self.helpPanelTextPosY-0.286, 0.022, string.format("Taste %s: %s", InputBinding.getButtonKeyName(InputBinding.ACTIVATE_CUTTER), g_i18n:getText("Turn_on_cutter")));
				end;
				for cutter,implement in pairs(self.attachedCutters) do
				if cutter.sidearms.movable then
					--renderText(self.helpPanelTextPosX, self.helpPanelTextPosY-0.308, 0.022, string.format("Tasten %s/%s: %s %s", InputBinding.getButtonKeyName(Lexion600Cutter.InputBinding.HASPEL_BACK), InputBinding.getButtonKeyName(Lexion600Cutter.InputBinding.HASPEL_FORWARD), g_i18n:getText("HASPEL_BACK"), g_i18n:getText("HASPEL_FORWARD")));
					--renderText(self.helpPanelTextPosX, self.helpPanelTextPosY-0.33, 0.022, string.format("Tasten %s/%s: %s %s", InputBinding.getButtonKeyName(Lexion600Cutter.InputBinding.HASPEL_UP), InputBinding.getButtonKeyName(Lexion600Cutter.InputBinding.HASPEL_DOWN), g_i18n:getText("HASPEL_UP"), g_i18n:getText("HASPEL_DOWN")));
				end;
				end;
			end;
		end;
	else
		g_currentMission:addHelpButtonText(g_i18n:getText("helpPanelOff"), InputBinding.HELPPANEL);
		if self.roundMode == 1 then
			g_currentMission:addHelpButtonText(g_i18n:getText("roundlightOff"), InputBinding.ROUNDLIGHT);
		elseif self.roundMode == 2 then
			g_currentMission:addHelpButtonText(g_i18n:getText("roundlightOn"), InputBinding.ROUNDLIGHT);
		elseif self.roundMode == 3 then
			g_currentMission:addHelpButtonText(g_i18n:getText("roundlightAuto"), InputBinding.ROUNDLIGHT);
		end;
	end;
end;

function Lexion600Combine2:onEnter()
    if self.treshingMaschineActive then
        self.playThreshingSound = true;
    end;
	if self.cutterActive then
		self.playCutterSound = true;
		self.cutterSoundActive = false;
	end;
	if not self.isAIThreshing then
		--self.gasMode = 1;
	end;
end;

function Lexion600Combine2:onLeave()
    if self.deactivateOnLeave then
        Lexion600Combine2.onDeactivate(self);
    else
        Lexion600Combine2.onDeactivateSounds(self)
    end;
	if self.worklight.front ~= nil then
		setVisibility(self.worklight.front, false);
	elseif self.worklight.back ~= nil then
		setVisibility(self.worklight.back, false);
	elseif self.pipeLight ~= nil then
		setVisibility(self.pipeLight, false);
	elseif self.driveLight ~= nil then
		setVisibility(self.driveLight, false);
	end;
end;

function Lexion600Combine2:onDeactivate()

    for k,v in pairs(self.chopperParticleSystemsRight) do
        Utils.setEmittingState(v, false);
    end;
	for k,v in pairs(self.chopperParticleSystemsLeft) do
        Utils.setEmittingState(v, false);
    end;
    for k,v in pairs(self.strawParticleSystemsRight) do
        Utils.setEmittingState(v, false);
    end;
	for k,v in pairs(self.strawParticleSystemsLeft) do
        Utils.setEmittingState(v, false);
    end;
	for k,v in pairs(self.strawParticleSystemsMiddle) do
        Utils.setEmittingState(v, false);
    end;
	for k,v in pairs(self.grainTankParticleSystems) do
        Utils.setEmittingState(v, false);
    end;

    self.chopperEnableTime = nil;
    self.chopperDisableTime = nil;
	self.grainTankEnableTime = nil;
    self.grainTankDisableTime = nil;
    self.strawEnableTime = nil;
    self.strawDisableTime = nil;
    self.strawEmitState = false;
	self.cutterActive = false;
	self.gasMode = 1;
	
	Lexion600Combine2.onDeactivateSounds(self)
end;

function Lexion600Combine2:onDeactivateSounds()
    if self.pipeSound ~= nil and self.pipeSoundEnabled then
        stopSample(self.pipeSound);
        self.pipeSoundEnabled = false;
    end;
    if self.threshingSound ~= nil then
        stopSample(self.threshingSound);
    end;
	if self.cutterSound ~= nil then
        stopSample(self.cutterSound);
    end;
end;

function Lexion600Combine2:attachImplement(implement)
    local object = implement.object;
    if object.attacherJoint.jointType == Vehicle.JOINTTYPE_CUTTER then
        self.attachedCutters[object] = implement;
        self.numAttachedCutters = self.numAttachedCutters+1;
        -- cutter assumes the thresher's loaded fruit type
        object:setFruitType(self.currentGrainTankFruitType);
    end;
end;

function Lexion600Combine2:detachImplement(implementIndex)
	local object = self.attachedImplements[implementIndex].object;
    if object.attacherJoint.jointType == Vehicle.JOINTTYPE_CUTTER then
        self.numAttachedCutters = self.numAttachedCutters-1;
        if self.numAttachedCutters == 0 then
            self.cutterActive = false;
        end;
        self.attachedCutters[object] = nil;
    end;
	self.playCutterSound = false;
	self.cutterSoundActive = false;
	if self.cutterSound ~= nil then
	stopSample(self.cutterSound);
	end;
end;

function Lexion600Combine2:allowGrainTankFruitType(fruitType)
    local allowed = false;

    if self.grainTankFruitTypes[fruitType] then -- is fruit type accepted by combine?
        if self.currentGrainTankFruitType ~= FruitUtil.FRUITTYPE_UNKNOWN then -- is combine currently not empty?
            if self.currentGrainTankFruitType ~= fruitType then -- is there another fill type in the tank?
                if self.grainTankFillLevel / self.grainTankCapacity <= self.minThreshold then
                    allowed = true; -- fill level is low enough to be overridden
                end;
            else
                allowed = true; -- fill type is the same as the combine's current fill type
            end;
        else
            allowed = true; -- combine is empty --> FruitUtil.FRUITTYPE_UNKNOWN
        end;
    end;

    return allowed;
end;

function Lexion600Combine2:emptyGrainTankIfLowFillLevel()
    if self.grainTankFillLevel / self.grainTankCapacity <= self.minThreshold then
        self.grainTankFillLevel = 0; -- empty the combine
        --return true;
    end;
    --return false;
end;

function Lexion600Combine2:setGrainTankFillLevel(fillLevel, fruitType)
    if not self:allowGrainTankFruitType(fruitType) then
        return;
    end;

    --self:emptyGrainTankIfLowFillLevel();

    self.grainTankFillLevel = Utils.clamp(fillLevel, 0, self.grainTankCapacity);

    if self.currentGrainTankFruitType ~= fruitType then
        self.currentGrainTankFruitType = fruitType;
        if self.currentGrainTankPlane ~= nil then
            setVisibility(self.currentGrainTankPlane, false);
        end;
        if self.currentGrainTankPlaneWindow ~= nil then
            setVisibility(self.currentGrainTankPlaneWindow, false);
        end;
    end;

    if self.grainTankPlanes ~= nil and self.defaultGrainTankPlane ~= nil and fruitType ~= FruitUtil.FRUITTYPE_UNKNOWN then
        local fruitTypeName = FruitUtil.fruitIndexToDesc[fruitType].name;
        local grainPlane = self.grainTankPlanes[fruitTypeName];
        if grainPlane == nil then
            grainPlane = self.defaultGrainTankPlane;
        end;
        if grainPlane.node ~= nil then
            local yTranslation = 0;
            if self.grainTankPlaneAnimCurve then
                local scaleX, scaleY, scaleZ , yTrans = self.grainTankPlaneAnimCurve:get(self.grainTankFillLevel/self.grainTankCapacity);
                yTranslation = yTrans;
                setScale(grainPlane.node, scaleX, scaleY, scaleZ);
            else
                local m = (self.grainTankPlaneMaxY - self.grainTankPlaneMinY) / self.grainTankCapacity;
                yTranslation = m*self.grainTankFillLevel + self.grainTankPlaneMinY;
            end;
            local xPos, yPos, zPos = getTranslation(grainPlane.node);
            setTranslation(grainPlane.node, xPos, yTranslation, zPos);
            setVisibility(grainPlane.node, self.grainTankFillLevel > 0);
            self.currentGrainTankPlane = grainPlane.node;
        end;
        if grainPlane.windowNode ~= nil then
            local yTranslation = 0;
            if self.grainTankPlaneWindowAnimCurve then
                local scaleX, scaleY, scaleZ , yTrans, visiblity = self.grainTankPlaneWindowAnimCurve:get(self.grainTankFillLevel/self.grainTankCapacity);
                yTranslation = yTrans;
                setScale(grainPlane.windowNode, scaleX, scaleY, scaleZ);
                setVisibility(self.grainPlaneWindow, visiblity);
            else
                local m = (self.grainTankPlaneMaxY - self.grainTankPlaneMinY) / self.grainTankCapacity;
                local startFillLevel = (self.grainTankPlaneWindowStartY-self.grainTankPlaneMinY)/m;
                local yTranslation = math.min(m*(self.grainTankFillLevel-startFillLevel)+self.grainTankPlaneWindowMinY, self.grainTankPlaneWindowMaxY);
                setVisibility(grainPlane.windowNode, self.grainTankFillLevel >= startFillLevel);
            end;
            local xPos, yPos, zPos = getTranslation(grainPlane.windowNode);
            setTranslation(grainPlane.windowNode, xPos, yTranslation, zPos);
            self.currentGrainTankPlaneWindow = grainPlane.windowNode;
        end;
    end;
end;

function Lexion600Combine2:startThreshing()

    if not self.treshingMaschineActive then
		self.treshingMaschineActive = true;
		self.isTreshing = true;
		self.ktopen = true;
		local threshingSoundOffset = 0;
		if self.threshingStartSound ~= nil and self:getIsActiveForSound() then
			setSamplePitch(self.threshingStartSound, self.threshingStartSoundPitchOffset);
			playSample(self.threshingStartSound, 1, 1, 0);
			threshingSoundOffset = getSampleDuration(self.threshingStartSound);
		end;

        self.playThreshingSound = true;
        self.playThreshingSoundTime = self.time+threshingSoundOffset;
	end;
	self.gasWarning1 = false;
end;

function Lexion600Combine2:stopThreshing()

    if self.treshingMaschineActive then
		if self.grainTankFillLevel >= (self.grainTankCapacity/2) then
			self.ktWarning = true;
			self.treshingMaschineActive = true;
			self.ktopen = true;
			self.playThreshingSound = true;
			self:openPipe();
		end;
		
		self.motor:setSpeedLevel(0, false);
        self.motor.maxRpmOverride = nil;
		
		self.chopperActivated = false;
		self.grainTankActivated = false;
		self.strawActivated = false;
		
		self.ktopen = false;
        self.playThreshingSound = false;

        if self.threshingSound ~= nil then
            stopSample(self.threshingSound);
        end;

        if self.threshingStopSound ~= nil and self.threshingSoundActive and self:getIsActiveForSound() then
            setSamplePitch(self.threshingStopSound, self.threshingStopSoundPitchOffset);
            playSample(self.threshingStopSound, 1, 1, 0);
            self.threshingSoundActive = false;
        end;
		self.treshingMaschineActive = false;
	end;

	self.gasWarning1 = false;
	self.gasWarning2 = false;
end;

function Lexion600Combine2:findTrailerRaycastCallback(transformId, x, y, z, distance)

    if getUserAttribute(transformId, "vehicleType") == 2 then
        self.trailerFound = transformId;
    end;

    return false;

end;

function Lexion600Combine2:openPipe()
    self.pipeOpening = true;
	
end;

function Lexion600Combine2:closePipe()
    self.pipeOpening = false;
	
end;
