---xyzspain
Wrapper = {};
function Wrapper.prerequisitesPresent(specializations)
return SpecializationUtil.hasSpecialization(Attachable, specializations);
end;
function Wrapper:load(xmlFile)
-- desplazamiento de conjuntos
self.setHydraulicDirection = SpecializationUtil.callSpecializationsFunction("setHydraulicDirection");
local hydraulicsCount = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.hydraulics#count"), 0);
self.hydraulics = {};
for i=1, hydraulicsCount do
local hydraulicName = string.format("vehicle.hydraulics.hydraulic%d", i);
self.hydraulics = {};
self.hydraulics.node = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#index"));
self.hydraulics.punch = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#punch"));
self.hydraulics.translationPunch = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#punchFixpoint"));
self.hydraulics.fixPoint = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#fixpoint"));
local ax, ay, az;
if self.hydraulics.punch ~= nil then
ax, ay, az = getWorldTranslation(self.hydraulics.punch);
else
ax, ay, az = getWorldTranslation(self.hydraulics.node);
end;
local bx, by, bz = getWorldTranslation(self.hydraulics.translationPunch);
self.hydraulics.punchDistance = Utils.vector3Length(ax-bx, ay-by, az-bz);
self.hydraulics[i].doScale = Utils.getNoNil(getXMLBool(xmlFile, hydraulicName .. "#doScale"), false);
end;
-------------------
self.setArmMode = SpecializationUtil.callSpecializationsFunction("setArmMode");
self.setWrappingMode = SpecializationUtil.callSpecializationsFunction("setWrappingMode");
self.wrappingMode=false;
self.baleInTable=false;
-- Wrapper
-- Specialization for Wrapper mod
--
-- @author JoXXer
-- @date 2011/01/09
-- Wickler
-- Specialization zum automatischen wickeln
--
-- @author teiger
-- @date 14/10/2011
self.setWrapping = SpecializationUtil.callSpecializationsFunction("setWrapping");
self.setUnloading = SpecializationUtil.callSpecializationsFunction("setUnloading");
self.setBalesVisibility = SpecializationUtil.callSpecializationsFunction("setBalesVisibility");
self.setResetActiveBale = SpecializationUtil.callSpecializationsFunction("setResetActiveBale");
self.createBale = SpecializationUtil.callSpecializationsFunction("createBale");
self.dropBale = SpecializationUtil.callSpecializationsFunction("dropBale");
-- Static Bales --
self.numStaticBales = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.staticBales#count"), 0);
self.staticBales = {};
for i=1, self.numStaticBales do
local baleNamei = string.format("vehicle.staticBales.staticBale" .. "%d", i);
self.staticBales[i] = Utils.indexToObject(self.components, getXMLString(xmlFile, baleNamei .. "#index"));
end;
-- Bale wrappingTable attacher --
self.searchTableBales = Wrapper.searchTableBales;
self.attachTableObjects = Wrapper.attachTableObjects;
self.detachTableObjects = Wrapper.detachTableObjects;
self.isBaleInTableRange = Wrapper.isBaleInTableRange;
self.tablePlace = {};
self.tablePlace.node1 = Utils.indexToObject(self.components, getXMLString(xmlFile,"vehicle.Wrappingtable#castPoint1"));
self.tablePlace.node2 = Utils.indexToObject(self.components, getXMLString(xmlFile,"vehicle.Wrappingtable#castPoint2"));
self.tablePlace.attacherNode = Utils.indexToObject(self.components, Utils.getNoNil(getXMLString(xmlFile,"vehicle.Wrappingtable#attacherNode"),"0>3"));
self.tablePlace.highOffset = Utils.getNoNil(getXMLFloat(xmlFile,"vehicle.Wrappingtable#highOffset"),4);
self.AttachedTableObjects = {};
self.allowTableAttachment = true;
self.balesOnTableAttached = false;
self.baleCanBeWrapped = false;
-- Animations --
self.WrappingAnimation = getXMLString(xmlFile, "vehicle.WrappingTableWrapping#animationName");
self.isReadyToUnload = false;
self.isUnloading = false;
self.isWrapping = false;
self.isReadyToLoad = false;
self.isBaleVisible = false;
self.resetActiveBale = false;
self.baleActive = 1;
self.usedFruitType = 0;
self.baleInRange = {};
--create bale-stuff--
self.baleTypes = {};
local i = 0;
while true do
local key = string.format("vehicle.baleTypes.baleType(%d)", i);
local t = getXMLString(xmlFile, key.."#fruitType");
local filename = getXMLString(xmlFile, key.."#filename");
if t==nil or filename==nil then
break;
end;
local entry = {};
entry.filename = filename;
--local desc = FruitUtil.fruitTypes[t];
local desc = FruitUtil.fruitTypes[t];
if desc ~= nil then
self.baleTypes[desc.index] = entry;
if self.defaultBaleType == nil then
self.defaultBaleType = entry;
end;
end;
i = i +1;
end;
if self.defaultBaleType == nil then
self.baleTypes = nil;
end;
self.bales = {};
self.baleAnimRoot = Utils.getNoNil(Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.baleAnimation#node")), "0>3");
------------------------------------attach bale in range error---------------------
self.hayBale = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.hayBale#index"));
setVisibility(self.hayBale, false);
self.strawBale = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.strawBale#index"));
setVisibility(self.strawBale, false);
self.select=false;
self.wrapperActive = false;
end;
function Wrapper:delete()
end;
function Wrapper:mouseEvent(posX, posY, isDown, isUp, button)
end;
function Wrapper:keyEvent(unicode, sym, modifier, isDown)
end;
function Wrapper:getSaveAttributesAndNodes(nodeIdent)
end;
function Wrapper:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
if not resetVehicles then
end;
return BaseMission.VEHICLE_LOAD_OK;
end;
function Wrapper:update(dt)
if self.attacherVehicle ~= nil then
-- if self:getIsActiveForInput() then
--if self.animationParts[4].clipStartTime then
--if self.attacherVehicle ~= nil then
-- if self.attacherVehicle.pickupMode ~= nil then
-- self:setArmMode(self.attacherVehicle.pickupMode);
-- end;
if self:getIsActiveForInput() then
if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA2) then
self.wrapperActive = not self.wrapperActive;
end;
if InputBinding.hasEvent(InputBinding.WRAPPING) then
self:setWrappingMode(not self.wrappingMode);
end;
-- if InputBinding.hasEvent(InputBinding.CHAPUZA) then
-- self.select= not self.select
-- end;
end
if not self.isWrapping and not self.isUnloading then
self:setArmMode(self.wrapperActive);
end
if self.isReadyToLoad then
self:searchTableBales();
if self.baleCanBeWrapped then
self.isWrapping = true;
self:searchTableBales();
self:setWrapping(true);
end;
end;
if self.isReadyToUnload then
self:setUnloading(not self.isUnloading);
end;
if not self.wrappingMode then --and (self:getIsActive() or self.attacherVehicle:getIsActive()) then
-- if self.animationParts[1].clipEndTime then
self:searchTableBales();
if self.baleInTable then
self:setUnloading(true);
else
self:setUnloading(false);
end;
elseif self.wrappingMode then
if not self.isReadyToUnload then
if self.animationParts[1].clipEndTime and self.animationParts[4].clipEndTime then
self.isReadyToLoad = true;
end;
elseif self.isReadyToUnload then
self.isReadyToLoad = false;
end;
end;
-- if self.baleInTable then
-- renderText(0.1, 0.12, 0.03," ok ");
-- else
-- renderText(0.1, 0.15, 0.03," no ");
-- end;
if self.armMode then
self:setAnimationTime(1, self.animationParts[1].animDuration);
self:setAnimationTime(4, self.animationParts[4].animDuration);
else
self:setAnimationTime(1, self.animationParts[1].offSet);
end;
end; ---attacher
for i, jointDesc in pairs(self.componentJoints) do
setJointFrame(self.componentJoints[i].jointIndex, 0, self.componentJoints[i].jointNode);
end;
self:setHydraulicDirection();
end;
function Wrapper:setArmMode(armMode)
ArmEvent.sendEvent(self, armMode, noEventSend);
self.armMode = armMode;
end;
function Wrapper:setWrappingMode(wrappingMode)
WrappingEvent.sendEvent(self, wrappingMode, noEventSend);
self.wrappingMode = wrappingMode;
end;
function Wrapper:updateTick(dt)
if self:getRealAnimationTime(self.WrappingAnimation)>= 29000 and self.isWrapping then
self.animation3=true;
self.isWrapping = false;
self.isReadyToUnload = true;
self:setBalesVisibility(not self.isBaleVisible);
self:setResetActiveBale(not self.resetActiveBale);
if self.baleTypes ~= nil then
-- create bale
self:createBale(self.usedFruitType);
if g_server ~= nil then
g_server:broadcastEvent(CreateBaleEvent:new(self, self.usedFruitType, 0), nil, nil, self);
else
g_client:getServerConnection():sendEvent(CreateBaleEvent:new(self, self.usedFruitType, 0));
end;
end;
end;
if self.isUnloading then
if table.getn(self.bales) > 0 then
self:dropBale(1);
if g_client ~= nil then
g_client:getServerConnection():sendEvent(DropBaleEvent:new(self, 1, 0));
end;
end;
end;
if self.isWrapping then
if self:getRealAnimationTime(self.WrappingAnimation) > 0 and self:getRealAnimationTime(self.WrappingAnimation) <= 25000 then
self:setAnimationTime(5, 1);
end;
if self:getRealAnimationTime(self.WrappingAnimation) > 0 and self:getRealAnimationTime(self.WrappingAnimation) <= 27500 then
self:setAnimationTime(6, 1);
end;
if self:getRealAnimationTime(self.WrappingAnimation) >= 1026 and getVisibility(self.staticBales[1]) == false and self.baleActive == 1 then
self:setBalesVisibility(not self.isBaleVisible);
elseif self:getRealAnimationTime(self.WrappingAnimation) >= 2500 and getVisibility(self.staticBales[2]) == false and self.baleActive == 2 then
self:setBalesVisibility(not self.isBaleVisible);
elseif self:getRealAnimationTime(self.WrappingAnimation) >= 5000 and getVisibility(self.staticBales[3]) == false and self.baleActive == 3 then
self:setBalesVisibility(not self.isBaleVisible);
elseif self:getRealAnimationTime(self.WrappingAnimation) >= 7500 and getVisibility(self.staticBales[4]) == false and self.baleActive == 4 then
self:setBalesVisibility(not self.isBaleVisible);
elseif self:getRealAnimationTime(self.WrappingAnimation) >= 10000 and getVisibility(self.staticBales[5]) == false and self.baleActive == 5 then
self:setBalesVisibility(not self.isBaleVisible);
elseif self:getRealAnimationTime(self.WrappingAnimation) >= 12500 and getVisibility(self.staticBales[6]) == false and self.baleActive == 6 then
self:setBalesVisibility(not self.isBaleVisible);
elseif self:getRealAnimationTime(self.WrappingAnimation) >= 15000 and getVisibility(self.staticBales[7]) == false and self.baleActive == 7 then
self:setBalesVisibility(not self.isBaleVisible);
elseif self:getRealAnimationTime(self.WrappingAnimation) >= 17500 and getVisibility(self.staticBales[8]) == false and self.baleActive == 8 then
self:setBalesVisibility(not self.isBaleVisible);
elseif self:getRealAnimationTime(self.WrappingAnimation) >= 20000 and getVisibility(self.staticBales[9]) == false and self.baleActive == 9 then
self:setBalesVisibility(not self.isBaleVisible);
elseif self:getRealAnimationTime(self.WrappingAnimation) >= 22500 and getVisibility(self.staticBales[10]) == false and self.baleActive == 10 then
self:setBalesVisibility(not self.isBaleVisible);
elseif self:getRealAnimationTime(self.WrappingAnimation) >= 25000 and getVisibility(self.staticBales[11]) == false and self.baleActive == 11 then
self:setBalesVisibility(not self.isBaleVisible);
self:setAnimationTime(5, 0);
end;
if self:getRealAnimationTime(self.WrappingAnimation) >= 23500 and self.animation3 then
if self.animationParts[3].clipStartTime then
self:setAnimationTime(3, self.animationParts[3].animDuration);
elseif self.animationParts[3].clipEndTime then
self:setAnimationTime(3, self.animationParts[3].offSet);
end;
end;
if self:getRealAnimationTime(self.WrappingAnimation) >= 27500 then
self.animation3=false;
self:setAnimationTime(6, 0);
end;
self.select = true;
if self.usedFruitType == Fillable.FILLTYPE_DRYGRASS_WINDROW or self.usedFruitType == Fillable.FILLTYPE_GRASS_WINDROW then
self.select = false;
end
if self.select then
setVisibility(self.strawBale, true);
setVisibility(self.hayBale, false);
else
setVisibility(self.hayBale, true);
setVisibility(self.strawBale, false);
end;
else
-- if self.animationParts[3].clipEndTime then
-- self:setAnimationTime(3, self.animationParts[3].offSet);
-- end;
setVisibility(self.hayBale, false);
setVisibility(self.strawBale, false);
end;
end;
--tableattachings--
function Wrapper:isBaleInTableRange(node1,node2,Yoffset,Bale)
local Xmax, Ymax, Zmax = getWorldTranslation(node1);
Xmax, Ymax, Zmax = worldToLocal(self.tablePlace.attacherNode,Xmax, Ymax, Zmax);
local Xmin, Ymin, Zmin = getWorldTranslation(node2);
Xmin, Ymin, Zmin = worldToLocal(self.tablePlace.attacherNode,Xmin, Ymin, Zmin);
local Xt, Yt, Zt = getWorldTranslation(Bale);
Xt, Yt, Zt = worldToLocal(self.tablePlace.attacherNode,Xt, Yt, Zt);
if (Xt < math.max(Xmax,Xmin) and Xt > math.min(Xmax,Xmin)) and (Zt < math.max(Zmax,Zmin) and Zt > math.min(Zmax,Zmin)) and (Yt<= ((Ymax+Ymin)/2)+Yoffset and Yt>= (Ymax+Ymin)/2) then
return true;
else
return false;
end;
end;
function Wrapper:searchTableBales()
for index,item in pairs(g_currentMission.itemsToSave) do
if item.item:isa(Bale) then
if item.item.isAttached == nil then
local isInRange = self:isBaleInTableRange(self.tablePlace.node1,self.tablePlace.node2,self.tablePlace.highOffset,item.item.nodeId);
if isInRange and self.isWrapping and self.wrappingMode then
local baleObject = item.item;
if baleObject ~= nil and baleObject:isa(Bale) then
self.usedFruitType = baleObject.fillType;
self.usedFillLevel = baleObject.fillLevel;
baleObject:delete();
end;
self.baleCanBeWrapped = false;
elseif isInRange and self.wrappingMode then
self.baleCanBeWrapped = isInRange;
self.baleInRange = item.item;
elseif isInRange and not self.wrappingMode then
self.baleInTable = isInRange;
self.baleInRange = item.item;
elseif not isInRange and self.baleInRange == item.item then
self.baleCanBeWrapped = isInRange;
self.baleInTable = isInRange;
self.baleInRange = nil;
end;
end;
end;
end;
end;
function Wrapper:attachTableObjects(object,baleT)
local attachedobject = {};
attachedobject.object = object;
if self.isServer then
attachedobject.AT = createTransformGroup("AT");
link(self.tablePlace.attacherNode,attachedobject.AT);
attachedobject.objectMass = getMass(object);
setMass(object,attachedobject.objectMass*0.01);
-- self:tableOrientJoint(object,attachedobject.AT);
local constr = JointConstructor:new();
constr:setActors(self.tablePlace.attacherNode, object);
constr:setJointTransforms(attachedobject.AT, object);
for i=1, 3 do
constr:setTranslationLimit(i-1, true, 0, 0);
constr:setRotationLimit(i-1,0,0);
end;
attachedobject.JointIndex = constr:finalize();
if baleT ~= nil then
attachedobject.baleT = baleT;
baleT.isAttached = true;
end;
end;
table.insert(self.AttachedTableObjects, attachedobject);
return true;
end;
function Wrapper:detachTableObjects()
if self.isServer then
for k,v in pairs(self.AttachedTableObjects) do
removeJoint(v.JointIndex);
delete(v.AT);
v.JointIndex = nil;
setMass(v.object,v.objectMass);
if v.baleT ~= nil then
v.baleT.isAttached = nil;
end;
end;
end;
self.AttachedTableObjects = nil;
self.AttachedTableObjects = {};
self.balesOnTableAttached = false;
end;
function Wrapper:setBalesVisibility(baleVisibility, noEventSend)
if baleVisibility ~= self.isBaleVisible then
if noEventSend == nil or noEventSend == false then
if g_server ~= nil then
g_server:broadcastEvent(SetBalesEvent:new(self, baleVisibility), nil, nil, self);
else
g_client:getServerConnection():sendEvent(SetBalesEvent:new(self, baleVisibility));
end;
end;
self.isBaleVisibile = baleVisibility;
if self.baleActive ~= 12 then
setVisibility(self.staticBales[self.baleActive], baleVisibility);
end;
if self.baleActive ~= 1 then
setVisibility(self.staticBales[self.baleActive-1], not baleVisibility);
end;
--print(string.format("Should set bale" .. "%d" .. " visible in setBalesVisibility", self.baleActive));
self.baleActive = self.baleActive+1;
end;
end;
function Wrapper:setUnloading(isUnloadingState,noEventSend)
SetUnloadingEvent.sendEvent(self, isUnloadingState, noEventSend);
-- Play unloading animation --
self.isWrappingTableDown = isUnloadingState;
if self.isWrappingTableDown then
if self.animationParts[2].clipStartTime then
self:setAnimationTime(2, self.animationParts[2].animDuration);
self.isUnloading = true;
self:setArmMode(false);
end;
else
if self.animationParts[2].clipEndTime then
self:setAnimationTime(2, self.animationParts[2].offSet);
self:setAnimationTime(4, self.animationParts[4].offSet);
self.isUnloading = false;
self.isReadyToUnload = false;
end;
end;
end;
function Wrapper:draw()
-- self.armMode self.wrappingMode self.wrappingMode self.baleInTable self.isReadyToUnload self.isUnloading self.wrapperActive
-- local tmp = self.baleInTable;
-- if tmp then
-- renderText(0.85,0.76,0.015, "bale in table");
-- else
-- renderText(0.85,0.76,0.015, "NOT bale in table");
-- end;
-- if self.wrappingMode then
-- renderText(0.85,0.71,0.015, "wrapping mode");
-- else
-- renderText(0.85,0.71,0.015, "NOT wrapping mode");
-- end;
-- if self.isUnloading then
-- renderText(0.85,0.66,0.015, "is unloading");
-- else
-- renderText(0.85,0.66,0.015, "NOT is unloading");
-- end;
-- renderText(0.85,0.61,0.015, string.format("usedfruittype: %3.0f", self.usedFruitType));
if self.wrapperActive then
g_currentMission:addHelpButtonText(g_i18n:getText("Wrapper_active"), InputBinding.IMPLEMENT_EXTRA2);
else
g_currentMission:addHelpButtonText(g_i18n:getText("Wrapper_deactive"), InputBinding.IMPLEMENT_EXTRA2);
end;
if not self.wrappingMode then
g_currentMission:addHelpButtonText(g_i18n:getText("Wrapper_7"), InputBinding.WRAPPING);
else
g_currentMission:addHelpButtonText(g_i18n:getText("Wrapper_8"), InputBinding.WRAPPING);
end;
-- if self.select then
-- g_currentMission:addHelpButtonText(g_i18n:getText("Wrapper_9"), InputBinding.CHAPUZA);
-- else
-- g_currentMission:addHelpButtonText(g_i18n:getText("Wrapper_10"), InputBinding.CHAPUZA);
-- end;
end;
function Wrapper:onAttach(attacherVehicle)
self.attacherVehicle = attacherVehicle;
self.animation3=true;
end;
function Wrapper:onDetach()
end;
function Wrapper:setWrapping(isWrapping,noEventSend)
SetWrappingEvent.sendEvent(self, isWrapping, noEventSend);
-- Play wrapping animation --
if self.WrappingAnimation ~= nil and self.playAnimation ~= nil then
self:playAnimation(self.WrappingAnimation, 1, nil, true);
self.isReadyToLoad = false;
end;
end;
function Wrapper:createBale(usedFruitType)
local baleType = self.baleTypes[usedFruitType];
if baleType == nil then
baleType = self.defaultBaleType;
end;
local baleRoot = Utils.loadSharedI3DFile(baleType.filename, self.baseDirectory);
local baleId = getChildAt(baleRoot, 0);
setRigidBodyType(baleId, "None");
link(self.baleAnimRoot, baleId);
delete(baleRoot);
local bale = {};
bale.id = baleId;
bale.time = 0;
bale.fillType = usedFruitType;
bale.fruitType = usedFruitType;
bale.filename = Utils.getFilename(baleType.filename, self.baseDirectory);
bale.lastX, bale.lastY, bale.lastZ = getWorldTranslation(bale.id);
table.insert(self.bales, bale);
local i = table.getn(self.bales);
--print("Bale should be created");
end;
function Wrapper:dropBale(baleIndex)
local bale = self.bales[baleIndex];
if bale ~= nil then
--local deltaRealTime = (self.time - self.baleLastPositionTime)/1000;
local x,y,z = getWorldTranslation(bale.id);
local rx,ry,rz = getWorldRotation(bale.id);
link(getRootNode(), bale.id);
if self.isServer then
local baleObject = Bale:new(self.isServer, self.isClient);
baleObject:load(bale.filename, x,y,z,rx,ry,rz);
if self.usedFruitType == Fillable.FILLTYPE_WHEAT_WINDROW or self.usedFruitType == Fillable.FILLTYPE_BARLEY_WINDROW then
baleObject.fillType = self.usedFruitType;
baleObject.fruitType = self.usedFruitType;
baleObject.fillLevel = self.usedFillLevel*1.2;
else
baleObject.fillType = Fillable.FILLTYPE_SILAGE;
baleObject.fruitType = Fillable.FILLTYPE_SILAGE;
baleObject.fillLevel = self.usedFillLevel;
end;
baleObject:register();
--local lx, ly, lz = bale.lastX, bale.lastY, bale.lastZ;
--setLinearVelocity(baleObject.nodeId, (x-lx)/deltaRealTime, (y-ly)/deltaRealTime, (z-lz)/deltaRealTime);
end;
delete(bale.id);
table.remove(self.bales, baleIndex);
end;
end;
function Wrapper:setResetActiveBale(activeBaleReset, noEventSend)
SetActiveBaleEvent.sendEvent(self, activeBaleReset, noEventSend);
if activeBaleReset then
self.baleActive = 1;
end;
end;
function Wrapper:readStream(streamId, connection)
self:setWrapping(streamReadBool(streamId), true);
self:setUnloading(streamReadBool(streamId), true);
self:setBalesVisibility(streamReadBool(streamId), true);
self:setResetActiveBale(streamReadBool(streamId), true);
local numBales = streamReadInt16(streamId);
for i=1, numBales do
local fruitType = streamReadInt8(streamId);
self:createBale(fruitType);
end;
end;
function Wrapper:writeStream(streamId, connection)
streamWriteBool(streamId, self.isWrapping);
streamWriteBool(streamId, self.isUnloading);
streamWriteBool(streamId, self.isBaleVisible);
streamWriteBool(streamId, self.resetActiveBale);
streamWriteInt16(streamId, table.getn(self.bales));
for i=1, table.getn(self.bales) do
local bale = self.bales[i];
streamWriteInt8(streamId, bale.fruitType);
end;
end;
function Wrapper:setHydraulicDirection()
for i=1, table.getn(self.hydraulics) do
local ax, ay, az = getWorldTranslation(self.hydraulics[i].node);
local bx, by, bz = getWorldTranslation(self.hydraulics[i].fixPoint);
local x, y, z = worldDirectionToLocal(getParent(self.hydraulics[i].node), bx-ax, by-ay, bz-az);
setDirection(self.hydraulics[i].node, x, y, z, 0, 1, 0);
local distance = Utils.vector3Length(ax-bx, ay-by, az-bz);
if self.hydraulics[i].doScale then
local xScale, yScale, zScale = getScale(self.hydraulics[i].node);
local newScale = yScale * (distance / self.hydraulics[i].punchDistance);
setScale(self.hydraulics[i].node, 1, 1, newScale);
else
if self.hydraulics[i].punch ~= nil then
setTranslation(self.hydraulics[i].punch, 0, 0, distance-self.hydraulics[i].punchDistance);
end;
end;
end;
end;