-- Lemken_Zirkon -- Specialization for Lemken_Zirkon mod -- -- @author Tobias F. (John Deere 6930, 1. LS-Modschmiede) -- @date LastEdit 02/10/09 Lemken_Zirkon = {}; function Lemken_Zirkon.prerequisitesPresent(specializations) return SpecializationUtil.hasSpecialization(Attachable, specializations); end; function Lemken_Zirkon:load(xmlFile) self.aiTerrainDetailChannel1 = g_currentMission.sowingChannel; self.aiTerrainDetailChannel2 = g_currentMission.cultivatorChannel; self.safeMode = true self.spinners = {}; local spinnerCount = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.spinners#count"), 0); for i=0, spinnerCount do local spinnerName = string.format("vehicle.spinners.spinner(%d)", i); local node = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, spinnerName .. "#index")); if node == nil then break; else table.insert(self.spinners, node); end; end; self.spinnerRotScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.spinners#rotScale"), 1); self.isLemkenAttacher = true; self.isTurnedOn = false; self.aiTerrainDetailChannel1 = g_currentMission.ploughChannel; self.aiTerrainDetailChannel2 = g_currentMission.cultivatorChannel; self.groundParticleSystems = {}; local psName = "vehicle.groundParticleSystem"; Utils.loadParticleSystem(xmlFile, self.groundParticleSystems, psName, self.components, false, nil, self.baseDirectory) self.groundParticleSystemActive = false; self.Marker = {}; self.Marker.areActivated = false; local NodeMarkerLeft = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.Marker.Left#index")); if NodeMarkerLeft ~= nil then self.Marker.Left = {}; self.Marker.Left.node = NodeMarkerLeft; local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.Marker.Left#minRot")); self.Marker.Left.minRot = {}; self.Marker.Left.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0)); self.Marker.Left.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0)); self.Marker.Left.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0)); x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.Marker.Left#maxRot")); self.Marker.Left.maxRot = {}; self.Marker.Left.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0)); self.Marker.Left.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0)); self.Marker.Left.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0)); self.Marker.Left.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.Marker.Left#rotTime"), 2)*1000; self.Marker.Left.isDown = false; end; local NodeMarkerRight = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.Marker.Right#index")); if NodeMarkerRight ~= nil then self.Marker.Right = {}; self.Marker.Right.node = NodeMarkerRight; local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.Marker.Right#minRot")); self.Marker.Right.minRot = {}; self.Marker.Right.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0)); self.Marker.Right.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0)); self.Marker.Right.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0)); x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.Marker.Right#maxRot")); self.Marker.Right.maxRot = {}; self.Marker.Right.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0)); self.Marker.Right.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0)); self.Marker.Right.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0)); self.Marker.Right.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.Marker.Right#rotTime"), 2)*1000; self.Marker.Right.isDown = false; end; self.wasToFast = false; self.groundContactReport = SpecializationUtil.callSpecializationsFunction("groundContactReport"); self.GroundContactReportNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.GroundContactReportNode#index")); self.contactReportNodes = {}; if self.GroundContactReportNode ~= nil then local entry = {}; entry.node = self.GroundContactReportNode; entry.hasGroundContact = false; self.contactReportNodes[entry.node] = entry; end; self.Lemken_ZirkonContactReportsActive = false; local jointTypeStr = getXMLString(xmlFile,"vehicle.attacherJoints.attacherJoint#jointType"); if jointTypeStr ~= nil then local jointType = Vehicle.jointTypeNameToInt[jointTypeStr]; if jointType == nil then Vehicle.registerJointType(jointTypeStr); print("register Jointtype: " .. jointTypeStr); jointType = Vehicle.jointTypeNameToInt[jointTypeStr]; end; if jointType ~= nil then self.attacherJoints[1].jointType = jointType; end; 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; end; function Lemken_Zirkon:delete() Lemken_Zirkon.removeContactReports(self); if self.cultivatorSound ~= nil then delete(self.cultivatorSound); end; Utils.deleteParticleSystem(self.groundParticleSystems); end; function Lemken_Zirkon:mouseEvent(posX, posY, isDown, isUp, button) end; function Lemken_Zirkon:keyEvent(unicode, sym, modifier, isDown) end; function Lemken_Zirkon:update(dt) if self:getIsActiveForInput() then if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA2) then self.safeMode = not self.safeMode end; end; if self:getIsActiveForInput() then if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA) then self.isTurnedOn = not self.isTurnedOn; end; if self.Marker.areActivated then if InputBinding.hasEvent(InputBinding.Z_LEFTMARKER) then self.Marker.Left.isDown = true; self.Marker.Right.isDown = false; end; if InputBinding.hasEvent(InputBinding.Z_RIGHTMARKER) then self.Marker.Left.isDown = false; self.Marker.Right.isDown = true; end; end; if InputBinding.hasEvent(InputBinding.Z_RIGHTMARKER) and InputBinding.hasEvent(InputBinding.Z_LEFTMARKER) then self.Marker.areActivated = not self.Marker.areActivated; end; end; if self:getIsActive() then self.wasToFast = false; local toFast = self:doCheckSpeedLimit() and self.lastSpeed*3600 > 15; if not toFast then self.wasToFast = toFast; end; if self.Marker.Right ~= nil and self.Marker.Left ~= nil then if self.Marker.Right.isDown then local x, y, z = getRotation(self.Marker.Right.node); local rot = {x,y,z}; local newRot = Utils.getMovedLimitedValues(rot, self.Marker.Right.maxRot, self.Marker.Right.minRot, 3, self.Marker.Right.rotTime, dt,false); setRotation(self.Marker.Right.node, unpack(newRot)); if self.cuttingAreas[3] ~= nil and self.contactReportNodes[self.GroundContactReportNode].hasGroundContact then local x,y,z = getWorldTranslation(self.cuttingAreas[3].start); local x1,y1,z1 = getWorldTranslation(self.cuttingAreas[3].width); local x2,y2,z2 = getWorldTranslation(self.cuttingAreas[3].height); if self.safeMode then Cultivator.updateSafeArea(x, z, x1, z1, x2, z2) else Utils.updateCultivatorArea(x, z, x1, z1, x2, z2); end; end; else local x, y, z = getRotation(self.Marker.Right.node); local rot = {x,y,z}; local newRot = Utils.getMovedLimitedValues(rot, self.Marker.Right.maxRot, self.Marker.Right.minRot, 3, self.Marker.Right.rotTime, dt,true); setRotation(self.Marker.Right.node, unpack(newRot)); end; if self.Marker.Left.isDown then local x, y, z = getRotation(self.Marker.Left.node); local rot = {x,y,z}; local newRot = Utils.getMovedLimitedValues(rot, self.Marker.Left.maxRot, self.Marker.Left.minRot, 3, self.Marker.Left.rotTime, dt,false); setRotation(self.Marker.Left.node, unpack(newRot)); if self.cuttingAreas[2] ~= nil and self.contactReportNodes[self.GroundContactReportNode].hasGroundContact then local x,y,z = getWorldTranslation(self.cuttingAreas[2].start); local x1,y1,z1 = getWorldTranslation(self.cuttingAreas[2].width); local x2,y2,z2 = getWorldTranslation(self.cuttingAreas[2].height); Utils.updatePloughArea(x, z, x1, z1, x2, z2); end; else local x, y, z = getRotation(self.Marker.Left.node); local rot = {x,y,z}; local newRot = Utils.getMovedLimitedValues(rot, self.Marker.Left.maxRot, self.Marker.Left.minRot, 3, self.Marker.Left.rotTime, dt,true); setRotation(self.Marker.Left.node, unpack(newRot)); end; end; if not self.Marker.areActivated then self.Marker.Left.isDown = false; self.Marker.Right.isDown = false; end; if self.isTurnedOn then if self.contactReportNodes[self.GroundContactReportNode].hasGroundContact then 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 > 3 then if not self.groundParticleSystemActive then self.groundParticleSystemActive = true; Utils.setEmittingState(self.groundParticleSystems, true); end; end; if self.cuttingAreas[1] ~= nil then local x,y,z = getWorldTranslation(self.cuttingAreas[1].start); local x1,y1,z1 = getWorldTranslation(self.cuttingAreas[1].width); local x2,y2,z2 = getWorldTranslation(self.cuttingAreas[1].height); Utils.updateCultivatorArea(x, z, x1, z1, x2, z2); end; else if self.groundParticleSystemActive then self.groundParticleSystemActive = false; Utils.setEmittingState(self.groundParticleSystems, false); end; if self.cultivatorSoundEnabled then stopSample(self.cultivatorSound); self.cultivatorSoundEnabled = false; end; end; for i=1, table.getn(self.spinners) do if self.spinners[i] ~= nil then rotate(self.spinners[i], 0, self.spinnerRotScale * -1, 0); end; end; end; if self.cultivatorSoundEnabled then if self.lastSpeed*3600 < 3 then stopSample(self.cultivatorSound); self.cultivatorSoundEnabled = false; end; end; end; end; function Lemken_Zirkon:draw() if self.safeMode then g_currentMission:addHelpButtonText("switch to normal Mode", InputBinding.IMPLEMENT_EXTRA2); else g_currentMission:addHelpButtonText("switch to safe Mode", InputBinding.IMPLEMENT_EXTRA2); end; if self.isTurnedOn then g_currentMission:addHelpButtonText(string.format(g_i18n:getText("turn_off_OBJECT"), self.typeDesc), InputBinding.IMPLEMENT_EXTRA); else g_currentMission:addHelpButtonText(string.format(g_i18n:getText("turn_on_OBJECT"), self.typeDesc), InputBinding.IMPLEMENT_EXTRA); end; if self.wasToFast and self.contactReportNodes[self.GroundContactReportNode].hasGroundContact 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); elseif self.wasToFast then g_currentMission:addWarning(g_i18n:getText("Deactivate_on_Street") .. "\n" .. g_i18n:getText("Key_Eng_Deu") .. " " .. string.format(InputBinding.getButtonKeyName(InputBinding.IMPLEMENT_EXTRA)), 0.07+0.022, 0.019+0.029); end; if not self.Marker.areActivated then local Markertext = (g_i18n:getText("Key_Eng_Deu").." "..InputBinding.getButtonKeyName(InputBinding.Z_LEFTMARKER).." + "..InputBinding.getButtonKeyName(InputBinding.Z_RIGHTMARKER).." "..g_i18n:getText("ACTIVATE_MARKER")); g_currentMission:addExtraPrintText(Markertext); else if self.Marker.Left.isDown then g_currentMission:addHelpButtonText(g_i18n:getText("MARKER_RIGHT"), InputBinding.Z_RIGHTMARKER); elseif self.Marker.Right.isDown then g_currentMission:addHelpButtonText(g_i18n:getText("MARKER_LEFT"), InputBinding.Z_LEFTMARKER); else local Markertext2 = (g_i18n:getText("Key_Eng_Deu").." "..InputBinding.getButtonKeyName(InputBinding.Z_LEFTMARKER)..": "..g_i18n:getText("MARKER_LEFT")..", "..InputBinding.getButtonKeyName(InputBinding.Z_RIGHTMARKER)..": "..g_i18n:getText("MARKER_RIGHT")); g_currentMission:addExtraPrintText(Markertext2); end; local Markertext = (g_i18n:getText("Key_Eng_Deu").." "..InputBinding.getButtonKeyName(InputBinding.Z_LEFTMARKER).." + "..InputBinding.getButtonKeyName(InputBinding.Z_RIGHTMARKER).." "..g_i18n:getText("DEACTIVATE_MARKER")); g_currentMission:addExtraPrintText(Markertext); end; if self.attachedVehicle ~= nil then self.attachedVehicle:draw() end; end; function Lemken_Zirkon:onAttach(attacherVehicle) Lemken_Zirkon.addContactReports(self); end; function Lemken_Zirkon:onDetach() self:onDeactivateSounds() if self.deactivateOnDetach then Lemken_Zirkon.onDeactivate(self); end; Lemken_Zirkon.removeContactReports(self); end; function Lemken_Zirkon:onDeactivate() self.isTurnedOn = false; end; function Lemken_Zirkon:aiTurnOn() self.isTurnedOn = true; self.Marker.areActivated = false; end; function Lemken_Zirkon:onDeactivateSounds() if self.cultivatorSoundEnabled then stopSample(self.cultivatorSound); self.cultivatorSoundEnabled = false; end; end; function Lemken_Zirkon:addContactReports() if not self.Lemken_ZirkonContactReportsActive then for k, v in pairs(self.contactReportNodes) do addContactReport(v.node, 0.0001, "groundContactReport", self); end; self.Lemken_ZirkonContactReportsActive = true; end; end; function Lemken_Zirkon:removeContactReports() if self.Lemken_ZirkonContactReportsActive then for k, v in pairs(self.contactReportNodes) do removeContactReport(v.node); v.hasGroundContact = false; end; self.Lemken_ZirkonContactReportsActive = false; end; end; function Lemken_Zirkon: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;