---------------------------------
-----------Unia Ares L-----------
---------------------------------
---------------------------------
--------- @author  Lipa ---------
-------- @date  11/03/10 --------
---------------------------------


Unia_Ares_L = {};

function Unia_Ares_L.prerequisitesPresent(specializations)
    return true;
end;

function Unia_Ares_L:load(xmlFile)

    self.groundContactReport = SpecializationUtil.callSpecializationsFunction("groundContactReport");

    self.speedRotatingParts = {};
    local i=0;
    while true do
        local baseName = string.format("vehicle.speedRotatingParts.speedRotatingPart(%d)", i);
        local index = getXMLString(xmlFile, baseName.. "#index");
        if index == nil then
            break;
        end;
        local node = Utils.indexToObject(self.components, index);
        if node ~= nil then
            local entry = {};
            entry.node = node;
            entry.rotationSpeedScale = getXMLFloat(xmlFile, baseName.."#rotationSpeedScale");
            if entry.rotationSpeedScale == nil then
                entry.rotationSpeedScale = 1.0/Utils.getNoNil(getXMLFloat(xmlFile, baseName.."#radius"), 1);
            end;

            entry.foldMinLimit = Utils.getNoNil(getXMLFloat(xmlFile, baseName .. "#foldMinLimit"), 0);
            entry.foldMaxLimit = Utils.getNoNil(getXMLFloat(xmlFile, baseName .. "#foldMaxLimit"), 1);

            table.insert(self.speedRotatingParts, entry);
        end;
        i = i+1;
    end;

    local drumNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.drum#index"));
    if drumNode ~= nil then
        print("Warning: vehicle.drum is no longer used, use speedRotatingParts\n");
    end;

    self.contactReportNodes = {};
    local contactReportNodeFound = false;
    local i=0;
    while true do
        local baseName = string.format("vehicle.contactReportNodes.contactReportNode(%d)", i);
        local index = getXMLString(xmlFile, baseName.. "#index");
        if index == nil then
            break;
        end;
        local node = Utils.indexToObject(self.components, index);
        if node ~= nil then
            local entry = {};
            entry.node = node;
            entry.hasGroundContact = false;

            self.contactReportNodes[node] = entry;
            contactReportNodeFound = true;
        end;
        i = i+1;
    end;
    if not contactReportNodeFound then
        local entry = {};
        entry.node = self.components[1].node;
        entry.hasGroundContact = false;
        self.contactReportNodes[entry.node] = entry;
    end;

    self.groundReferenceThreshold = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.groundReferenceNode#threshold"), 0.2);
    self.groundReferenceNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.groundReferenceNode#index"));

    local numCuttingAreas = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.cuttingAreas#count"), 0);
    for i=1, numCuttingAreas do
        local areanamei = string.format("vehicle.cuttingAreas.cuttingArea%d", i);
        self.cuttingAreas[i].foldMinLimit = Utils.getNoNil(getXMLFloat(xmlFile, areanamei .. "#foldMinLimit"), 0);
        self.cuttingAreas[i].foldMaxLimit = Utils.getNoNil(getXMLFloat(xmlFile, areanamei .. "#foldMaxLimit"), 1);
    end;

    local cultivatorSound = getXMLString(xmlFile, "vehicle.cultivatorSound#file");
    if cultivatorSound ~= nil and cultivatorSound ~= "" then
        cultivatorSound = Utils.getFilename(cultivatorSound, self.baseDirectory);
        self.cultivatorSound = createSample("cultivatorSound");
        loadSample(self.cultivatorSound, cultivatorSound, false);
        self.cultivatorSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.cultivatorSound#pitchOffset"), 0);
        self.cultivatorSoundVolume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.cultivatorSound#volume"), 1.0);
        self.cultivatorSoundEnabled = false;
    end;

    self.groundParticleSystems = {};
    local psName = "vehicle.groundParticleSystem";
    Utils.loadParticleSystem(xmlFile, self.groundParticleSystems, psName, self.components, false, nil, self.baseDirectory)
    self.groundParticleSystemActive = false;

    self.onlyActiveWhenLowered = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.onlyActiveWhenLowered#value"), true);

    self.aiTerrainDetailChannel1 = g_currentMission.ploughChannel;
    self.aiTerrainDetailChannel2 = g_currentMission.sowingChannel;

    self.speedViolationMaxTime = 2500;
    self.speedViolationTimer = self.speedViolationMaxTime;
    self.cultivatorContactReportsActive = false;
    self.startActivationTimeout = 2000;
    self.startActivationTime = 0;
	
	-----Rotacje-----
	local rotationNodePartRamie = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.rotationPartRamie#index"));
    if rotationNodePartRamie ~= nil then
        self.rotationPartRamie = {};
        self.rotationPartRamie.node = rotationNodePartRamie;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.rotationPartRamie#minRot"));
        self.rotationPartRamie.minRot = {};
        self.rotationPartRamie.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotationPartRamie.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotationPartRamie.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.rotationPartRamie#maxRot"));
        self.rotationPartRamie.maxRot = {};
        self.rotationPartRamie.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotationPartRamie.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotationPartRamie.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        self.rotationPartRamie.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationPartRamie#rotTime"), 2)*1000;
        self.rotationPartRamie.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationPartRamie#touchRotLimit"), 10));
    end; 
	local rotationNodePartGora = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.rotationPartGora#index"));
    if rotationNodePartGora ~= nil then
        self.rotationPartGora = {};
        self.rotationPartGora.node = rotationNodePartGora;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.rotationPartGora#minRot"));
        self.rotationPartGora.minRot = {};
        self.rotationPartGora.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotationPartGora.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotationPartGora.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.rotationPartGora#maxRot"));
        self.rotationPartGora.maxRot = {};
        self.rotationPartGora.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotationPartGora.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotationPartGora.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        self.rotationPartGora.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationPartGora#rotTime"), 2)*1000;
        self.rotationPartGora.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationPartGora#touchRotLimit"), 10));
    end; 
	local rotationNodePartZaczep = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.rotationPartZaczep#index"));
    if rotationNodePartZaczep ~= nil then
        self.rotationPartZaczep = {};
        self.rotationPartZaczep.node = rotationNodePartZaczep;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.rotationPartZaczep#minRot"));
        self.rotationPartZaczep.minRot = {};
        self.rotationPartZaczep.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotationPartZaczep.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotationPartZaczep.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.rotationPartZaczep#maxRot"));
        self.rotationPartZaczep.maxRot = {};
        self.rotationPartZaczep.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotationPartZaczep.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotationPartZaczep.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        self.rotationPartZaczep.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationPartZaczep#rotTime"), 2)*1000;
        self.rotationPartZaczep.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationPartZaczep#touchRotLimit"), 10));
    end;  	
	local rotationNodePartHydraulika = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.rotationPartHydraulika#index"));
    if rotationNodePartHydraulika ~= nil then
        self.rotationPartHydraulika = {};
        self.rotationPartHydraulika.node = rotationNodePartHydraulika;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.rotationPartHydraulika#minRot"));
        self.rotationPartHydraulika.minRot = {};
        self.rotationPartHydraulika.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotationPartHydraulika.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotationPartHydraulika.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.rotationPartHydraulika#maxRot"));
        self.rotationPartHydraulika.maxRot = {};
        self.rotationPartHydraulika.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotationPartHydraulika.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotationPartHydraulika.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        self.rotationPartHydraulika.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationPartHydraulika#rotTime"), 2)*1000;
        self.rotationPartHydraulika.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationPartHydraulika#touchRotLimit"), 10));
    end;   		
	local translationNodeWspornik1 = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.translationWspornik1#index"));
    if translationNodeWspornik1 ~= nil then
        self.translationWspornik1 = {};
        self.translationWspornik1.node = translationNodeWspornik1;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.translationWspornik1#minTrans"));
        self.translationWspornik1.minTrans = {};
        self.translationWspornik1.minTrans[1] = Utils.getNoNil(x, 0);
        self.translationWspornik1.minTrans[2] = Utils.getNoNil(y, 0);
        self.translationWspornik1.minTrans[3] = Utils.getNoNil(z, 0);

        x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.translationWspornik1#maxTrans"));
        self.translationWspornik1.maxTrans = {};
        self.translationWspornik1.maxTrans[1] = Utils.getNoNil(x, 0);
        self.translationWspornik1.maxTrans[2] = Utils.getNoNil(y, 0);
        self.translationWspornik1.maxTrans[3] = Utils.getNoNil(z, 0);

        self.translationWspornik1.transTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.translationWspornik1#transTime"), 2)*1000;
        self.translationWspornik1.touchTransLimit = Utils.getNoNil(getXMLString(xmlFile, "vehicle.translationWspornik1#touchTransLimit"), 10);
    end; 
	local translationNodeWspornik2 = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.translationWspornik2#index"));
    if translationNodeWspornik2 ~= nil then
        self.translationWspornik2 = {};
        self.translationWspornik2.node = translationNodeWspornik2;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.translationWspornik2#minTrans"));
        self.translationWspornik2.minTrans = {};
        self.translationWspornik2.minTrans[1] = Utils.getNoNil(x, 0);
        self.translationWspornik2.minTrans[2] = Utils.getNoNil(y, 0);
        self.translationWspornik2.minTrans[3] = Utils.getNoNil(z, 0);

        x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.translationWspornik2#maxTrans"));
        self.translationWspornik2.maxTrans = {};
        self.translationWspornik2.maxTrans[1] = Utils.getNoNil(x, 0);
        self.translationWspornik2.maxTrans[2] = Utils.getNoNil(y, 0);
        self.translationWspornik2.maxTrans[3] = Utils.getNoNil(z, 0);

        self.translationWspornik2.transTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.translationWspornik2#transTime"), 2)*1000;
        self.translationWspornik2.touchTransLimit = Utils.getNoNil(getXMLString(xmlFile, "vehicle.translationWspornik2#touchTransLimit"), 10);
    end;
	------ Dzwieki -----
	local workSound = getXMLString(xmlFile, "vehicle.workSound#file");
    if workSound ~= nil and workSound ~= "" then
        workSound = Utils.getFilename(workSound, self.baseDirectory);
        self.workSound = createSample("workSound");
        self.workSoundEnabled = false;
        loadSample(self.workSound, workSound, false);
        self.workSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.workSound#pitchOffset"), 1);
        self.workSoundVolume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.workSound#volume"), 1);
    end;
	
end;

function Unia_Ares_L:delete()

    Utils.deleteParticleSystem(self.groundParticleSystems);

    Unia_Ares_L.removeContactReports(self);

    if self.cultivatorSound ~= nil then
        delete(self.cultivatorSound);
    end;

	if self.workSoundEnabled then
		stopSample(self.workSound);
		self.workSoundEnabled = false;
	end;
	
end;

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

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

	if sym == Input.KEY_KP_1 then
		self.rotationMaxRamie = isDown;
		self.rotationMaxGora = isDown;
		self.rotationMaxZaczep = isDown;
		self.rotationMaxHydraulika = isDown;
		self.translationMax = isDown;
	end;
	if sym == Input.KEY_KP_0 then
		self.rotationMinRamie = isDown;
		self.rotationMinGora = isDown;
		self.rotationMinZaczep = isDown;
		self.rotationMinHydraulika = isDown;
		self.translationMin = isDown;
	end;	

end;

function Unia_Ares_L:update(dt)

    if self:getIsActive() then
        local hasGroundContact = false;
        for k, v in pairs(self.contactReportNodes) do
            if v.hasGroundContact then
                hasGroundContact = true;
                break;
            end;
        end;

        if not hasGroundContact then
            if self.groundReferenceNode ~= nil then
                local x,y,z = getWorldTranslation(self.groundReferenceNode);
                local terrainHeight = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, x, 0, z);
                if terrainHeight+self.groundReferenceThreshold >= y then
                    hasGroundContact = true;
                end;
            end;
        end;

        if hasGroundContact then
            local foldAnimTime = self.foldAnimTime;
            if self.startActivationTime <= self.time then
                if not self.onlyActiveWhenLowered or self:isLowered(false) then
                    for k, cuttingArea in pairs(self.cuttingAreas) do
                        if foldAnimTime == nil or (foldAnimTime <= cuttingArea.foldMaxLimit and foldAnimTime >= cuttingArea.foldMinLimit) then
                            local x,y,z = getWorldTranslation(cuttingArea.start);
                            local x1,y1,z1 = getWorldTranslation(cuttingArea.width);
                            local x2,y2,z2 = getWorldTranslation(cuttingArea.height);
                            Utils.updateCultivatorArea(x, z, x1, z1, x2, z2);
                        end;
                    end;
                end;

                if self:doCheckSpeedLimit() and self.lastSpeed*3600 > 20 then
                    self.speedViolationTimer = self.speedViolationTimer - dt;
                    if self.speedViolationTimer < 0 then
                        if self.attacherVehicle then
                            self.attacherVehicle:detachImplementByObject(self);
                        end;
                    end;
                else
                    self.speedViolationTimer = self.speedViolationMaxTime;
                end;
            end;

            for k,v in pairs(self.speedRotatingParts) do
                if foldAnimTime == nil or (foldAnimTime <= v.foldMaxLimit and foldAnimTime >= v.foldMinLimit) then
                    rotate(v.node, v.rotationSpeedScale * self.lastSpeedReal * self.movingDirection * dt, 0, 0);
                end;
            end;

            if self.cultivatorSound ~= nil and not self.cultivatorSoundEnabled and self:getIsActiveForSound() then
                if self.lastSpeed*3600 > 3 then
                    playSample(self.cultivatorSound, 0, self.cultivatorSoundVolume, 0);
                    setSamplePitch(self.cultivatorSound, self.cultivatorSoundPitchOffset);
                    self.cultivatorSoundEnabled = true;
                end;
            end;

            if self.lastSpeed*3600 > 5 and not self.groundParticleSystemActive then
                self.groundParticleSystemActive = true;
                Utils.setEmittingState(self.groundParticleSystems, true);
            end;

            if self.lastSpeed*3600 < 5 and self.groundParticleSystemActive then
                self.groundParticleSystemActive = false;
                Utils.setEmittingState(self.groundParticleSystems, false);
            end;

        else
            self.speedViolationTimer = self.speedViolationMaxTime;

            if self.cultivatorSoundEnabled then
                stopSample(self.cultivatorSound);
                self.cultivatorSoundEnabled = false;
            end;

            if self.groundParticleSystemActive then
                self.groundParticleSystemActive = false;
                Utils.setEmittingState(self.groundParticleSystems, false);
            end;

        end;
		
		-----Rotacje-----
		local doRotate = self.rotationMaxRamie or self.rotationMinRamie
		if self.rotationPartRamie ~= nil and doRotate then
			local x, y, z = getRotation(self.rotationPartRamie.node);
			local rot = {x,y,z};
			local newRot = Utils.getMovedLimitedValues(rot, self.rotationPartRamie.maxRot, self.rotationPartRamie.minRot, 3, self.rotationPartRamie.rotTime, dt, not self.rotationMaxRamie);
			setRotation(self.rotationPartRamie.node, unpack(newRot));
		end;
		local doRotate = self.rotationMaxGora or self.rotationMinGora
		if self.rotationPartGora ~= nil and doRotate then
			local x, y, z = getRotation(self.rotationPartGora.node);
			local rot = {x,y,z};
			local newRot = Utils.getMovedLimitedValues(rot, self.rotationPartGora.maxRot, self.rotationPartGora.minRot, 3, self.rotationPartGora.rotTime, dt, not self.rotationMaxGora);
			setRotation(self.rotationPartGora.node, unpack(newRot));
		end;
		local doRotate = self.rotationMaxZaczep or self.rotationMinZaczep
		if self.rotationPartZaczep ~= nil and doRotate then
			local x, y, z = getRotation(self.rotationPartZaczep.node);
			local rot = {x,y,z};
			local newRot = Utils.getMovedLimitedValues(rot, self.rotationPartZaczep.maxRot, self.rotationPartZaczep.minRot, 3, self.rotationPartZaczep.rotTime, dt, not self.rotationMaxZaczep);
			setRotation(self.rotationPartZaczep.node, unpack(newRot));
		end;
		local doRotate = self.rotationMaxHydraulika or self.rotationMinHydraulika
		if self.rotationPartHydraulika ~= nil and doRotate then
			local x, y, z = getRotation(self.rotationPartHydraulika.node);
			local rot = {x,y,z};
			local newRot = Utils.getMovedLimitedValues(rot, self.rotationPartHydraulika.maxRot, self.rotationPartHydraulika.minRot, 3, self.rotationPartHydraulika.rotTime, dt, not self.rotationMaxHydraulika);
			setRotation(self.rotationPartHydraulika.node, unpack(newRot));
		end;
		local doTranslate = self.translationMax or self.translationMin
		if self.translationWspornik1 ~= nil and doTranslate then 
			local x, y, z = getTranslation(self.translationWspornik1.node); 
			local trans = {x,y,z}; 
			local newTrans = Utils.getMovedLimitedValues(trans, self.translationWspornik1.maxTrans, self.translationWspornik1.minTrans, 3, self.translationWspornik1.transTime, dt, not self.translationMax); 
			setTranslation(self.translationWspornik1.node, unpack(newTrans)); 
		end;
		local doTranslate = self.translationMax or self.translationMin
		if self.translationWspornik2 ~= nil and doTranslate then 
			local x, y, z = getTranslation(self.translationWspornik2.node); 
			local trans = {x,y,z}; 
			local newTrans = Utils.getMovedLimitedValues(trans, self.translationWspornik2.maxTrans, self.translationWspornik2.minTrans, 3, self.translationWspornik2.transTime, dt, not self.translationMax); 
			setTranslation(self.translationWspornik2.node, unpack(newTrans)); 
		end;
		-----Rotacje END------
		
    else
        if self.groundParticleSystemActive then
            self.groundParticleSystemActive = false;
            Utils.setEmittingState(self.groundParticleSystems, false);
        end;
		if self.workSoundEnabled then
			stopSample(self.workSound);
			self.workSoundEnabled = false;
		end;
    end;

    if self.cultivatorSoundEnabled then
        if self.lastSpeed*3600 < 3 then
            stopSample(self.cultivatorSound);
            self.cultivatorSoundEnabled = false;
        end;
    end;

end;

function Unia_Ares_L:draw()
    if math.abs(self.speedViolationTimer - self.speedViolationMaxTime) > 2 then
        g_currentMission:addWarning(g_i18n:getText("Dont_drive_to_fast") .. "\n" .. string.format(g_i18n:getText("Cruise_control_levelN"), "1", InputBinding.getButtonKeyName(InputBinding.SPEED_LEVEL1)), 0.07+0.022, 0.019+0.029);
    end;
	g_currentMission:addExtraPrintText("Wcisnij KP1/KP0 : Podnies/Opusc chwytak");
end;

function Unia_Ares_L:onAttach(attacherVehicle)
    Unia_Ares_L.onActivate(self);
    Unia_Ares_L.addContactReports(self);
    self.startActivationTime = self.time + self.startActivationTimeout;
end;

function Unia_Ares_L:onDetach()
    if self.deactivateOnDetach then
        Unia_Ares_L.onDeactivate(self);
        Unia_Ares_L.removeContactReports(self);
    else
        Unia_Ares_L.onDeactivateSounds(self);
    end;
	if self.workSoundEnabled then
		stopSample(self.workSound);
		self.workSoundEnabled = false;
	end;	
end;

function Unia_Ares_L:onEnter()
    Unia_Ares_L.onActivate(self);
    Unia_Ares_L.addContactReports(self);
end;

function Unia_Ares_L:onLeave()
    if self.deactivateOnLeave then
        Unia_Ares_L.onDeactivate(self);
        Unia_Ares_L.removeContactReports(self);
    else
        Unia_Ares_L.onDeactivateSounds(self);
    end;
end;

function Unia_Ares_L:onActivate()
end;

function Unia_Ares_L:onDeactivate()
    self.speedViolationTimer = self.speedViolationMaxTime;

    if self.groundParticleSystemActive then
        self.groundParticleSystemActive = false;
        Utils.setEmittingState(self.groundParticleSystems, false);
    end;

    Unia_Ares_L.onDeactivateSounds(self);
end;

function Unia_Ares_L:onDeactivateSounds()
    if self.cultivatorSoundEnabled then
        stopSample(self.cultivatorSound);
        self.cultivatorSoundEnabled = false;
    end;
end;

function Unia_Ares_L:addContactReports()
    if not self.cultivatorContactReportsActive then
        for k, v in pairs(self.contactReportNodes) do
            addContactReport(v.node, 0.0001, "groundContactReport", self);
        end;

        self.cultivatorContactReportsActive = true;
    end;
end;

function Unia_Ares_L:removeContactReports()
    if self.cultivatorContactReportsActive then
        for k, v in pairs(self.contactReportNodes) do
            removeContactReport(v.node);
            v.hasGroundContact = false;
        end;
        self.cultivatorContactReportsActive = false;
    end;
end;

function Unia_Ares_L:groundContactReport(objectId, otherObjectId, isStart, normalForce, tangentialForce)

    if otherObjectId == g_currentMission.terrainRootNode then
        local entry = self.contactReportNodes[objectId];
        if entry ~= nil then
            entry.hasGroundContact = isStart or normalForce > 0 or tangentialForce > 0;
        end;
    end;

end;

function Unia_Ares_L:validateAttacherJoint(implement, jointDesc, dt)
    return true;
end;