forcaPalletTrattenitore = {};
function forcaPalletTrattenitore.prerequisitesPresent(specializations) return true; end;
function forcaPalletTrattenitore:load(xmlFile) 
	self.punteDx = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.punte#indexDx"));
	self.punteSx = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.punte#indexSx")); 
	self.fermiDx = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.fermi#indexDx"));
	self.fermiSx = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.fermi#indexSx")); 
	self.positions = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.positions"), 0.0);
	self.posDir = 0; self.dist = 0.1; self.distC = 0.65; self.currentPuntaDx = 6; self.currentPuntaSx = 20; self.currentPuntaDxB = 30; self.currentPuntaSxB = 44;
	self.pos01 = false; self.pos02 = true; self.pos03 = false; self.pos04 = true; self.pos05 = true; self.pos06 = false;
	self.pos07 = false; self.pos08 = true; self.pos09 = true; self.pos10 = false; self.pos11 = true; self.pos12 = false;
	self.pos13 = false; self.pos14 = false; self.pos15 = false; self.pos16 = false; self.pos17 = false; self.pos18 = false;
	self.pos19 = false; self.pos20 = false; self.pos21 = false; self.pos22 = false; self.pos23 = false;	self.pos24 = false; 
	self.tubiIdraulici = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.tubiIdraulici#index"));
	self.setcurrentTrattenitore = SpecializationUtil.callSpecializationsFunction("setcurrentTrattenitore"); self.currentTrattenitore = 0;
	self.setcurrentDistanzaL = SpecializationUtil.callSpecializationsFunction("setcurrentDistanzaL"); self.currentDistanzaL = 0;
	self.setcurrentDistanzaF = SpecializationUtil.callSpecializationsFunction("setcurrentDistanzaF"); self.currentDistanzaF = 0;
	self.resetBracci = false; self.trattenitoriLaterali = true; self.extraWeightsDefaultMass = getMass(self.components[1].node);
	self.destra = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.trattenitore#destra"));
	self.sinistra = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.trattenitore#sinistra")); 
	self.frontale = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.trattenitore#frontale")); end
function forcaPalletTrattenitore:delete() end;
function forcaPalletTrattenitore:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	local currentTrattenitore = getXMLInt(xmlFile, key .. "#currentTrattenitore"); if currentTrattenitore ~= nil then self:setcurrentTrattenitore(currentTrattenitore); if currentTrattenitore == 1 then self:playAnimation("trattenitoreSuperiore", -1); elseif currentTrattenitore == 3 then self:playAnimation("trattenitoreSuperiore", 1); self.currentDistanzaL = 0; self.currentDistanzaF = 0; end; end; 
	local currentPuntaDx = getXMLInt(xmlFile, key .. "#currentPuntaDx"); if currentPuntaDx ~= nil then self:setcurrentPuntaDx(currentPuntaDx-1); setTranslation(self.fermiDx, (currentPuntaDx)/2*self.dist-self.distC, 0.756, 0.084); end;
	local currentPuntaSx = getXMLInt(xmlFile, key .. "#currentPuntaSx"); if currentPuntaSx ~= nil then self:setcurrentPuntaSx(currentPuntaSx-1); setTranslation(self.fermiSx, (currentPuntaSx)/2*self.dist-self.distC, 0.756, 0.084); end;
	self.pos01 = false; self.pos02 = true; self.pos03 = true; self.pos04 = true; self.pos05 = true; self.pos06 = false;	self.pos07 = false; self.pos08 = true; self.pos09 = true; self.pos10 = true; self.pos11 = true; self.pos12 = false;
	self.pos13 = false; self.pos14 = false; self.pos15 = false; self.pos16 = false; self.pos17 = false; self.pos18 = false; self.pos19 = false; self.pos20 = false; self.pos21 = false; self.pos22 = false; self.pos23 = false;	self.pos24 = false;
	if currentPuntaDx/2 == 1 or currentPuntaSx/2 == 1 then self.pos01 = false; end;	if currentPuntaDx/2 == 2 or currentPuntaSx/2 == 2 then self.pos02 = false; end;
	if currentPuntaDx/2 == 3 or currentPuntaSx/2 == 3 then self.pos03 = false; end;	if currentPuntaDx/2 == 4 or currentPuntaSx/2 == 4 then self.pos04 = false; end;
	if currentPuntaDx/2 == 5 or currentPuntaSx/2 == 5 then self.pos05 = false; end;	if currentPuntaDx/2 == 6 or currentPuntaSx/2 == 6 then self.pos06 = false; end;
	if currentPuntaDx/2 == 7 or currentPuntaSx/2 == 7 then self.pos07 = false; end;	if currentPuntaDx/2 == 8 or currentPuntaSx/2 == 8 then self.pos08 = false; end;
	if currentPuntaDx/2 == 9 or currentPuntaSx/2 == 9 then self.pos09 = false; end;	if currentPuntaDx/2 == 10 or currentPuntaSx/2 == 10 then self.pos10 = false; end;
	if currentPuntaDx/2 == 11 or currentPuntaSx/2 == 11 then self.pos11 = false; end; if currentPuntaDx/2 == 12 or currentPuntaSx/2 == 12 then self.pos12 = false; end;
	if currentPuntaDx/2 == 13 or currentPuntaSx/2 == 13 then self.pos13 = false; end; if currentPuntaDx/2 == 14 or currentPuntaSx/2 == 14 then self.pos14 = false; end;
	if currentPuntaDx/2 == 15 or currentPuntaSx/2 == 15 then self.pos15 = false; end; if currentPuntaDx/2 == 16 or currentPuntaSx/2 == 16 then self.pos16 = false; end;
	if currentPuntaDx/2 == 17 or currentPuntaSx/2 == 17 then self.pos17 = false; end; if currentPuntaDx/2 == 18 or currentPuntaSx/2 == 18 then self.pos18 = false; end;
	if currentPuntaDx/2 == 19 or currentPuntaSx/2 == 19 then self.pos19 = false; end; if currentPuntaDx/2 == 20 or currentPuntaSx/2 == 20 then self.pos20 = false; end;
	if currentPuntaDx/2 == 21 or currentPuntaSx/2 == 21 then self.pos21 = false; end; if currentPuntaDx/2 == 22 or currentPuntaSx/2 == 22 then self.pos22 = false; end;
	if currentPuntaDx/2 == 23 or currentPuntaSx/2 == 23 then self.pos23 = false; end; if currentPuntaDx/2 == 24 or currentPuntaSx/2 == 24 then self.pos24 = false; end;
	return BaseMission.VEHICLE_LOAD_OK; end;
function forcaPalletTrattenitore:getSaveAttributesAndNodes(nodeIdent) local attributes = 'currentTrattenitore="' .. self.currentTrattenitore .. '"'; return attributes; end;
function forcaPalletTrattenitore:readStream(streamId, connection) self:setcurrentTrattenitore(streamReadInt8(streamId), true); self:setcurrentDistanzaL(streamReadInt8(streamId), true); self:setcurrentDistanzaF(streamReadInt8(streamId), true); end;
function forcaPalletTrattenitore:writeStream(streamId, connection) streamWriteInt8(streamId, self.currentTrattenitore); streamWriteInt8(streamId, self.currentDistanzaL); streamWriteInt8(streamId, self.currentDistanzaF); end;
function forcaPalletTrattenitore:setcurrentTrattenitore(int, noEventSend) self.currentTrattenitore = int; setcurrentTrattenitoreEvent.sendEvent(self, int, noEventSend); end;
function forcaPalletTrattenitore:setcurrentDistanzaL(int, noEventSend) self.currentDistanzaL = int; setcurrentDistanzaLEvent.sendEvent(self, int, noEventSend); end;
function forcaPalletTrattenitore:setcurrentDistanzaF(int, noEventSend) self.currentDistanzaF = int; setcurrentDistanzaFEvent.sendEvent(self, int, noEventSend); end;
function forcaPalletTrattenitore:mouseEvent(posX, posY, isDown, isUp, button) end;
function forcaPalletTrattenitore:keyEvent(unicode, sym, modifier, isDown) end;
function forcaPalletTrattenitore:update(dt)
	if self:getIsActiveForInput() or self.currentAttacco == 1 then
		if not self.resetBracci and (self.currentTrattenitore == 1 or self.currentTrattenitore == 3) then 
		g_currentMission:showBlinkingWarning(g_i18n:getText("CSZReset"), 1000); self.currentTrattenitore = self.currentTrattenitore - 1; end; end;
	if g_currentMission.player ~= nil and g_currentMission.player.isEntered then 
		local px, py, pz = getWorldTranslation(g_currentMission.player.rootNode); local mx, my, mz = getWorldTranslation(self.components[1].node);  local tx, ty, tz = getWorldTranslation(self.components[2].node);
		if Utils.vector3Length(px-mx, py-my, pz-mz) < 3 then 
			if Utils.vector3Length(mx-tx, my-ty, mz-tz) < 3 then
				if InputBinding.hasEvent(InputBinding.change) then 
					if self.currentTrattenitore == 1 and not self:getIsAnimationPlaying("trattenitoreSuperiore") then self:setcurrentTrattenitore(2);
					elseif self.currentTrattenitore == 3 and not self:getIsAnimationPlaying("trattenitoreSuperiore") then self:setcurrentTrattenitore(0); end; end;	
					if self.currentTrattenitore == 1 then g_currentMission:addHelpButtonText(g_i18n:getText("trattenitore"), InputBinding.change); 
					elseif self.currentTrattenitore == 3 then g_currentMission:addHelpButtonText(g_i18n:getText("trattenitore"), InputBinding.change); end; end;
			if self.currentTrattenitore == 3 then 
				if self.trattenitoriLaterali then
				if InputBinding.isPressed(InputBinding.selectRemove) then if self.currentDistanzaL > 1 then self.currentDistanzaL = self.currentDistanzaL - 1; end; end;
				if InputBinding.isPressed(InputBinding.selectAdd)    then if self.currentDistanzaL < 45 then self.currentDistanzaL = self.currentDistanzaL + 1; end; end;
				else 
				if InputBinding.isPressed(InputBinding.selectRemove) then if self.currentDistanzaF > 1 then self.currentDistanzaF = self.currentDistanzaF - 1; end; end;
				if InputBinding.isPressed(InputBinding.selectAdd)    then if self.currentDistanzaF < 45 then self.currentDistanzaF = self.currentDistanzaF + 1; end; end;
				end;
				if self.attacherVehicle == nil then g_currentMission:addHelpButtonText(g_i18n:getText("cambiaOggetto"), InputBinding.CAMERA_SWITCH); end; self:setcurrentDistanzaF(self.currentDistanzaF); self:setcurrentDistanzaL(self.currentDistanzaL);
				g_currentMission:addHelpButtonText(string.format(g_i18n:getText("selectRemove"), self.typeDesc), InputBinding.selectRemove); g_currentMission:addHelpButtonText(string.format(g_i18n:getText("selectAdd"), self.typeDesc), InputBinding.selectAdd);	end;
			if InputBinding.hasEvent(InputBinding.CAMERA_SWITCH) then self.trattenitoriLaterali = not self.trattenitoriLaterali; end;
			if self.trattenitoriLaterali then g_currentMission:addExtraPrintText(g_i18n:getText("distanzaL")..self.currentDistanzaL); 
			else g_currentMission:addExtraPrintText(g_i18n:getText("distanzaF")..self.currentDistanzaF); end; end; end; end;
function forcaPalletTrattenitore:updateTick(dt) 
	if self.currentTrattenitore == 0 then self:playAnimation("trattenitoreSuperiore", -1, nil, true); self.resetBracci = true; self.currentTrattenitore = 1; self:setcurrentDistanzaF(0); self:setcurrentDistanzaL(0); setTranslation(self.destra, 0, 0, 0); setTranslation(self.sinistra, 0, 0, 0); setTranslation(self.frontale, 0, 0, 0); setMass(self.components[1].node, self.extraWeightsDefaultMass);
	elseif self.currentTrattenitore == 2 then self:playAnimation("trattenitoreSuperiore", 1, nil, true); self.resetBracci = true; self.currentTrattenitore = 3; setMass(self.components[1].node, self.extraWeightsDefaultMass + 0.2); end;
	if self.currentTrattenitore == 3 then 
		setTranslation(self.destra, -self.currentDistanzaL/100, 0, 0); setTranslation(self.sinistra, self.currentDistanzaL/100, 0, 0); setTranslation(self.frontale, 0, 0, self.currentDistanzaF/100); end; end;
function forcaPalletTrattenitore:draw() end;
function forcaPalletTrattenitore:onAttach(attacherVehicle, jointDescIndex) setVisibility(self.tubiIdraulici, false); end;
function forcaPalletTrattenitore:onDetach() setVisibility(self.tubiIdraulici, true); end;
function forcaPalletTrattenitore:onDeactivate() end;
setcurrentTrattenitoreEvent = {}; setcurrentTrattenitoreEvent_mt = Class(setcurrentTrattenitoreEvent, Event); InitEventClass(setcurrentTrattenitoreEvent, "setcurrentTrattenitoreEvent");
function setcurrentTrattenitoreEvent:emptyNew() local self = Event:new(setcurrentTrattenitoreEvent_mt); self.className="setcurrentTrattenitoreEvent"; return self; end;
function setcurrentTrattenitoreEvent:new(vehicle, currentTrattenitore) local self = setcurrentTrattenitoreEvent:emptyNew() self.vehicle = vehicle; self.currentTrattenitore = currentTrattenitore; return self; end;
function setcurrentTrattenitoreEvent:readStream(streamId, connection) local id = streamReadInt32(streamId); self.vehicle = networkGetObject(id); self.currentTrattenitore = streamReadInt8(streamId); self.vehicle:setcurrentTrattenitore(self.currentTrattenitore, true);
	if not connection:getIsServer() then g_server:broadcastEvent(setcurrentTrattenitoreEvent:new(self.vehicle, self.currentTrattenitore), nil, connection, self.vehicle); end; end;
function setcurrentTrattenitoreEvent:writeStream(streamId, connection) streamWriteInt32(streamId, networkGetObjectId(self.vehicle)); streamWriteInt8(streamId, self.currentTrattenitore); end;
function setcurrentTrattenitoreEvent.sendEvent(vehicle, currentTrattenitore, noEventSend) if noEventSend == nil or noEventSend == false then
	if g_server ~= nil then	g_server:broadcastEvent(setcurrentTrattenitoreEvent:new(vehicle, currentTrattenitore), nil, nil, vehicle);
	else g_client:getServerConnection():sendEvent(setcurrentTrattenitoreEvent:new(vehicle, currentTrattenitore)); end; end; end;
setcurrentDistanzaLEvent = {}; setcurrentDistanzaLEvent_mt = Class(setcurrentDistanzaLEvent, Event); InitEventClass(setcurrentDistanzaLEvent, "setcurrentDistanzaLEvent");
function setcurrentDistanzaLEvent:emptyNew() local self = Event:new(setcurrentDistanzaLEvent_mt); self.className="setcurrentDistanzaLEvent"; return self; end;
function setcurrentDistanzaLEvent:new(vehicle, currentDistanzaL) local self = setcurrentDistanzaLEvent:emptyNew() self.vehicle = vehicle; self.currentDistanzaL = currentDistanzaL; return self; end;
function setcurrentDistanzaLEvent:readStream(streamId, connection) local id = streamReadInt32(streamId); self.vehicle = networkGetObject(id); self.currentDistanzaL = streamReadInt8(streamId); self.vehicle:setcurrentDistanzaL(self.currentDistanzaL, true);
	if not connection:getIsServer() then g_server:broadcastEvent(setcurrentDistanzaLEvent:new(self.vehicle, self.currentDistanzaL), nil, connection, self.vehicle); end; end;
function setcurrentDistanzaLEvent:writeStream(streamId, connection) streamWriteInt32(streamId, networkGetObjectId(self.vehicle)); streamWriteInt8(streamId, self.currentDistanzaL); end;
function setcurrentDistanzaLEvent.sendEvent(vehicle, currentDistanzaL, noEventSend) if noEventSend == nil or noEventSend == false then
	if g_server ~= nil then	g_server:broadcastEvent(setcurrentDistanzaLEvent:new(vehicle, currentDistanzaL), nil, nil, vehicle);
	else g_client:getServerConnection():sendEvent(setcurrentDistanzaLEvent:new(vehicle, currentDistanzaL)); end; end; end;
setcurrentDistanzaFEvent = {}; setcurrentDistanzaFEvent_mt = Class(setcurrentDistanzaFEvent, Event); InitEventClass(setcurrentDistanzaFEvent, "setcurrentDistanzaFEvent");
function setcurrentDistanzaFEvent:emptyNew() local self = Event:new(setcurrentDistanzaFEvent_mt); self.className="setcurrentDistanzaFEvent"; return self; end;
function setcurrentDistanzaFEvent:new(vehicle, currentDistanzaF) local self = setcurrentDistanzaFEvent:emptyNew() self.vehicle = vehicle; self.currentDistanzaF = currentDistanzaF; return self; end;
function setcurrentDistanzaFEvent:readStream(streamId, connection) local id = streamReadInt32(streamId); self.vehicle = networkGetObject(id); self.currentDistanzaF = streamReadInt8(streamId); self.vehicle:setcurrentDistanzaF(self.currentDistanzaF, true);
	if not connection:getIsServer() then g_server:broadcastEvent(setcurrentDistanzaFEvent:new(self.vehicle, self.currentDistanzaF), nil, connection, self.vehicle); end; end;
function setcurrentDistanzaFEvent:writeStream(streamId, connection) streamWriteInt32(streamId, networkGetObjectId(self.vehicle)); streamWriteInt8(streamId, self.currentDistanzaF); end;
function setcurrentDistanzaFEvent.sendEvent(vehicle, currentDistanzaF, noEventSend) if noEventSend == nil or noEventSend == false then
	if g_server ~= nil then	g_server:broadcastEvent(setcurrentDistanzaFEvent:new(vehicle, currentDistanzaF), nil, nil, vehicle);
	else g_client:getServerConnection():sendEvent(setcurrentDistanzaFEvent:new(vehicle, currentDistanzaF)); end; end; end;