-- -- local moddir = g_currentModDirectory; Hose = {}; function Hose.prerequisitesPresent(specializations) return true; end; function Hose:printTable( _tbl, _str, _dpth, _mdpth ) if _dpth >= _mdpth then return; end; for i,j in pairs( _tbl ) do print(_dpth.._str.." "..tostring(i).." "..tostring(j)); if string.match( type(j), "table" ) then self:printTable(j, _str.." ", _dpth+1, _mdpth); end end end; function Hose:load(savegame) -- debug self.printTable = Hose.printTable; self.setFollow = Hose.setFollow; self.setAttach = Hose.setAttach; self.setAttachStation = Hose.setAttachStation; self.setRelease = Hose.setRelease; self.setIsAttached = Hose.setIsAttached; self.setVehicleAndHoseRefIdxInRange = Hose.setVehicleAndHoseRefIdxInRange; self.setStationInRange = Hose.setStationInRange; self.updateMesh = Hose.updateMesh; self.msh = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.mesh#index")); self.jnts = {}; for i=1,17 do local e = Utils.indexToObject(self.components, getXMLString(self.xmlFile, string.format("vehicle.jnts.jnt%d#index",i))); table.insert(self.jnts, e); end self.jntsRef = getParent(self.jnts[1]); self.ctors = {}; for i=1,2 do local e = {}; e.refNode = Utils.indexToObject(self.components, getXMLString(self.xmlFile, string.format("vehicle.ref%d#index",i))); -- ?! e.fillDelta = getXMLFloat( e.plIR = false; e.follow = false; e.attach = false; e.isAttached = false e.release = false; e.joint = nil; e.veh = 0; e.refId = 0; e.station = 0; table.insert(self.ctors, e); end; self.extraJnts = {}; -- for 3rd and 4th comp., but how to set ref TGs? - dynamically .) .. we'll see table.insert( self.extraJnts, nil ); table.insert( self.extraJnts, nil ); -- self.vehicleInRangeSend = 0; self.stationInRangeSend = 0; --# local ax,ay,az = getWorldTranslation(self.components[1].node); local bx,by,bz = getWorldTranslation(self.components[4].node); --local cx,cy,cz = getWorldTranslation(self.components[3].node); --local dx,dy,dz = getWorldTranslation(self.components[4].node); self.hoseLength = Utils.vector3Length( bx-ax, by-ay, bz-az ); self.d12 = self.hoseLength; --Utils.vector3Length( bx-ax, by-ay, bz-az ); self.compDist = self.hoseLength; -- ! last ! link( getRootNode(), self.msh ); setTranslation( self.msh, 0, 0, 0 ); setRotation( self.msh, 0, 0, 0 ); self.lastPos = {}; self.lastPos[1] = {}; self.lastPos[1].pos = {0,0,0}; self.lastPos[2] = {}; self.lastPos[2].pos = {0,0,0}; -- HUD self.huds = {}; self.huds.xPos = 0.84; self.huds.yPos = 0.85; self.hud = {}; self.hud.xPos = 0.84; self.hud.yPos = 0.85; self.huds.hoseAndHandHUD = Overlay:new("hosehud", Utils.getFilename("hud/Complete.png", self.baseDirectory), self.huds.xPos, self.huds.yPos, 0.11, 0.04); self.sId2Joint = false; end; function Hose:preDelete() end; function Hose:delete() if self.msh ~= nil then delete(self.msh); end; for i=1,2 do removeJoint(self.ctors[1].joint); end end; function Hose:readStream(streamId, connection) --print("function Hose:readStream(streamId, connection)"); for i=1,2 do self.ctors[i].follow = streamReadBool(streamId); self.ctors[i].isAttached = streamReadBool(streamId); local v = streamReadInt32(streamId); if v ~= 0 then self.ctors[i].vehToLoad = v; else self.ctors[i].veh = 0; end; local v = streamReadInt32(streamId); if v ~= 0 then self.ctors[i].stationToLoad = v; else self.ctors[i].station = 0; end; self.ctors[i].refId = streamReadInt32(streamId); end; local id = streamReadInt32(streamId); if id ~= 0 then self.vehicleInRangeSendToLoad = id; else self.vehicleInRange = 0; end; local id2 = streamReadInt32(streamId); self.hoseRefIdxInRangeSend = id2; end; function Hose:writeStream(streamId, connection) --print("function Hose:writeStream(streamId, connection)"); for i=1,2 do streamWriteBool(streamId, self.ctors[i].follow); streamWriteBool(streamId, self.ctors[i].isAttached); if self.ctors[i].veh ~= 0 then local veh = self.ctors[i].veh; local id = networkGetObjectId(veh); --print("id="..tostring(id).." veh="..tostring(veh).." self.ctors[i].veh="..tostring(self.ctors[i].veh)); streamWriteInt32(streamId, id); else streamWriteInt32(streamId, 0); end if self.ctors[i].station ~= 0 then local station = self.ctors[i].station; local id = networkGetObjectId(station); --print("id="..tostring(id).." station="..tostring(station).." self.ctors[i].station="..tostring(self.ctors[i].station)); streamWriteInt32(streamId, id); else streamWriteInt32(streamId, 0); end streamWriteInt32(streamId, self.ctors[i].refId); end; if self.vehicleInRangeSend ~= 0 then local id = networkGetObjectId(self.vehicleInRangeSend); streamWriteInt32(streamId, id); streamWriteInt32(streamId, self.hoseRefIdxInRangeSend ); else streamWriteInt32(streamId, 0); streamWriteInt32(streamId, 0 ); end; end; function Hose:mouseEvent(posX, posY, isDown, isUp, button) end; function Hose:keyEvent(unicode, sym, modifier, isDown) end; function Hose:update(dt) --# if self.isClient then self:updateMesh(); end; if self.vehicleInRangeSendToLoad ~= nil then self.vehicleInRange = networkGetObject(self.vehicleInRangeSendToLoad); --print("self.vehicleInRange ="..tostring(self.vehicleInRange).." "..tostring(self.vehicleInRangeToLoad)); self.vehicleInRangeSendToLoad = nil; end; for i=1,2 do if self.ctors[i].vehToLoad ~= nil then self.ctors[i].veh = networkGetObject(self.ctors[i].vehToLoad); --print("self.ctors[i].veh ="..tostring(self.ctors[i].veh).." "..tostring(self.ctors[i].vehToLoad)); self.ctors[i].vehToLoad = nil; end; if self.ctors[i].stationToLoad ~= nil then self.ctors[i].station = networkGetObject(self.ctors[i].stationToLoad); self.ctors[i].stationToLoad = nil; end; end; --print("table.getn(g_currentMission.users)="..table.getn(g_currentMission.users).." table.getn(g_currentMission.players)="..table.getn(g_currentMission.players)); --print("g_currentMission.controlledVehicle="..tostring(g_currentMission.controlledVehicle)); --# if self.isClient and g_currentMission.controlledVehicle == nil then if g_gui.currentGui == nil and Input.isMouseButtonPressed(Input.MOUSE_BUTTON_LEFT) and Input.mouseButtonPressedThisFrame[1] == true then --print("################"); --for i,j in pairs(self.ctors) do -- print(tostring(i).."=> ir:"..tostring(j.plIR).." /follow:"..tostring(j.follow).." /att:"..tostring(j.attach).." /isAtt:"..tostring(j.isAttached).." /rel:"..tostring(j.release).." /joint:"..tostring(j.joint).." /veh:"..tostring(j.veh).." /refId:"..tostring(j.refId).." /station:"..tostring(j.station)); --end local sId; local sId2; if self.ctors[1].plIR == true and self.ctors[2].plIR == false then sId = 1; sId2 = 2; Input.mouseButtonPressedThisFrame[1] = false; elseif self.ctors[1].plIR == false and self.ctors[2].plIR == true then sId = 2; sId2 = 1; Input.mouseButtonPressedThisFrame[1] = false; else --if self.ctors[1].follow then -- sId = 1; -- sId2 = 2; --elseif self.ctors[2].follow then -- sId = 2; -- sId2 = 1; --end --print("-INPUT> not in range"); return; end if self.ctors[sId].follow == false then if self.ctors[sId].isAttached == false then --print("follow t "..sId); self:setFollow( g_currentMission.playerUserId, sId, true); --g_currentMission.playerUserId, sId, true); --playerUserId, sId, true ); else if self.ctors[sId].veh ~= 0 then --print("release (1) "..sId); self:setRelease( self.ctors[sId].veh, sId, self.ctors[sId].refId ); elseif self.ctors[sId].station ~= 0 then --print("release station(1)"..sId); self:setRelease( self.ctors[sId].station, sId, 0); end; end; else if self.vehicleInRangeSend == 0 and self.stationInRangeSend == 0 then --print("follow f "..sId); self:setFollow( g_currentMission.playerUserId, sId, false); --g_currentMission.playerUserId, sId, false); --.playerUserId, sId, false ); else if self.ctors[sId].isAttached == false and self.vehicleInRangeSend ~= 0 and self.ctors[sId2].follow == false then --print("attach "..sId); self:setFollow( g_currentMission.playerUserId, sId, false); self:setAttach( self.vehicleInRangeSend, sId, self.hoseRefIdxInRangeSend ); --self.hoseRefInRange.id ); elseif self.ctors[sId].isAttached == false and self.stationInRangeSend ~= 0 and self.ctors[sId2].follow == false then --print("attachStation "..sId.." "..tostring(self.stationInRangeSend)); self:setFollow( g_currentMission.playerUserId, sId, false); self:setAttachStation( self.stationInRangeSend, sId ); else if self.ctors[sId].veh ~= 0 then --print("release (2)"..sId); self:setRelease( self.ctors[sId].veh, sId, self.ctors[sId].refId); elseif self.ctors[sId].station ~= 0 then --print("release station(2)"..sId); self:setRelease( self.ctors[sId].station, sId, 0); end; end; end; end; end; end; if self.isServer then --## disconnect hose from ref when to far away local sId = 0; if (self.ctors[1].isAttached and self.ctors[2].follow) then sId = 2; elseif (self.ctors[2].isAttached and self.ctors[1].follow) then sId = 1; elseif (self.ctors[1].isAttached and self.ctors[2].isAttached) then if (self.ctors[1].veh ~= self.ctors[2].veh) or (self.ctors[1].station ~= 0 and self.ctors[2].veh ~= 0 ) or (self.ctors[1].veh ~= 0 and self.ctors[2].station ~= 0 ) then sId = 3; end; end; --print(tostring(self.ctors[1].veh).." "..tostring(self.ctors[1].station).." "..tostring(self.ctors[1].isAttached)); --print(tostring(self.ctors[2].veh).." "..tostring(self.ctors[2].station).." "..tostring(self.ctors[2].isAttached)); -- if sId > 0 then --print("sId="..sId.." check for safety"); local c1=1; local c2=4; if sId == 2 then c1 = 4; c2 = 1; end; local ax,ay,az = getWorldTranslation( self.components[c1].node ); local bx,by,bz = getWorldTranslation( self.components[c2].node ); local d = Utils.vector3Length( bx-ax, by-ay, bz-az ); if d > 0.99*self.hoseLength then if sId == 3 then local veh1 = self.ctors[1].veh; if veh1 == 0 then veh1 = self.ctors[1].station; end; local veh2 = self.ctors[2].veh; if veh2 == 0 then veh2 = self.ctors[2].station; end; if veh1 ~= veh2 then if veh1.hoseRef ~= nil then if string.match( 'park', veh1.hoseRef.refs[self.ctors[1].refId].rt ) then self:setRelease( veh1, 1, self.ctors[1].refId); else self:setRelease( veh1, 1, self.ctors[1].refId); self:setRelease( veh2, 2, self.ctors[2].refId); end; else --print("IMPOSSIBLE ?!"); self:setRelease( veh1, 1, self.ctors[1].refId); self:setRelease( veh2, 2, self.ctors[2].refId); end; end; else self:setFollow( self.plIdToFollow, sId, false ); end; end end; --### if self.ctors[1].follow == true or self.ctors[2].follow == true and self.plIdToFollow ~= 0 then local user; local idx; --print("--------------should follow-----------"); --print("g_currentMission.playerUserId="..tostring(g_currentMission.playerUserId)); for i,us in pairs(g_currentMission.users) do --print("us.nickname="..tostring(us.nickname).." us.userId="..tostring(us.userId).." "..tostring(self.plIdToFollow)); if us.userId == self.plIdToFollow then user = us; idx = i; break; end; end; local player; if idx ~= nil and user ~= nil and g_currentMission.users[idx] ~= nil then for i,pl in pairs(g_currentMission.players) do --print("pl.controllerName="..tostring(pl.controllerName).." pl.id="..tostring(pl.id).." "..tostring(self.plIdToFollow).." pl.index="..tostring(pl.index)); if pl.owner ~= nil then --if pl.owner == g_currentMission.users[self.plIdToFollow].connection then if pl.owner == g_currentMission.users[idx].connection then player = pl; break; end end; end; else print("::WARNING/ERROR?::"); print("::WARNING/ERROR?:: Hose could not follow player !!!"); print("::WARNING/ERROR?::"); end; --if g_currentMission.players[idx] ~= nil then -- player = g_currentMission.players[idx]; --end --print("player="..tostring(player)); --if player == nil then --self.ctors[1].follow = false; --self.ctors[2].follow = false; --end; --print("player = "..tostring(player)); --print("self.ctors[1].follow:", self.ctors[1].follow) --print("self.ctors[2].follow:", self.ctors[2].follow) --[[if self.ctors[1].follow == true then --setTranslation( self.components[1].node, x, y+0.4, z ); --local xp, yp, zp = local x,y,z = localToWorld(player.graphicsRootNode, 0.3,0.3,-0.6 ); local rx,ry,rz = getWorldRotation(player.graphicsRootNode); setTranslation( self.components[1].node, x,y,z ); setRotation( self.components[1].node, rx,ry,rz); elseif self.ctors[2].follow == true then local x,y,z = localToWorld(player.graphicsRootNode, 0.3,0.3,-0.6 ); local rx,ry,rz = getWorldRotation(player.graphicsRootNode); setTranslation( self.components[4].node, x,y,z ); setRotation( self.components[4].node, rx,ry,rz); --rotate( self.components[4].node, 0,3.14159,0 ); end;]] --[[if self.ctors[1].follow == true then --setTranslation( self.components[1].node, x, y+0.4, z ); --local xp, yp, zp = local x,y,z = localToWorld(player.rootNode, 0.3,0.3,-0.6 ); local rx,ry,rz = getWorldRotation(player.rootNode); setTranslation( self.components[1].node, x,y,z ); setRotation( self.components[1].node, rx,ry,rz); elseif self.ctors[2].follow == true then local x,y,z = localToWorld(player.rootNode, 0.3,0.3,-0.6 ); local rx,ry,rz = getWorldRotation(player.rootNode); setTranslation( self.components[4].node, x,y,z ); setRotation( self.components[4].node, rx,ry,rz); --rotate( self.components[4].node, 0,3.14159,0 ); end;]] --[[if self.isServer then if self.ctors[1].follow or self.ctors[2].follow then if not self.sId2Joint then local sId = 1; if self.ctors[2].follow then sId = 2; end; local cmpId = 1; if self.ctors[2].follow then cmpId = 4; end; local x,y,z = getWorldTranslation(player.rootNode); local rx,ry,rz = getWorldRotation(player.rootNode); setTranslation(self.components[cmpId].node, x,y,z); setRotation(self.components[cmpId].node, rx,ry,rz); print("hose create joint") local constr = JointConstructor:new(); constr:setActors(player.rootNode, self.components[cmpId].node); constr:setJointTransforms(player.rootNode, self.components[cmpId].node); for i=1, 3 do constr:setRotationLimit(i-1, -0, 0); constr:setTranslationLimit(i-1, true, 0, 0); end; self.ctors[sId].joint = constr:finalize(); --setPairCollision(player.graphicsRootNode, self.components[cmpId].node, false); self.ctors[sId].isAttached = true; self:setIsAttached(sId, true); self.sId2Joint = true; end; if self.sId2Joint then print("hose create joint done") if self.ctors[1].follow then for i=1,table.getn(self.componentJoints),1 do local jnt = self.componentJoints[i]; print("hose create joint stage1") setJointFrame(jnt.jointIndex, 0, jnt.jointNode); print("hose create joint stage2") end; elseif self.ctors[2].follow then for i=table.getn(self.componentJoints),1,-1 do local jnt = self.componentJoints[i]; print("hose create joint stage2") setJointFrame(jnt.jointIndex, 1, jnt.jointNode); print("hose create joint stage2") end; end; end; end; end]] end; end; --# search for tankers/hoseRefs -- optimize ?! if self.isServer then self.vehicleInRange = 0; self.hoseRefIdxInRange = 0; self.stationInRange = 0; if self.ctors[1].follow == true or self.ctors[2].follow == true then --[[ local player; for i,pl in pairs(g_currentMission.players) do if pl.owner ~= nil then -- if pl.owner == g_currentMission.users[self.plIdToFollow].connection then player = pl; end; end; end; ]]-- local user; local idx; --print("--------------should follow-----------"); --print("g_currentMission.playerUserId="..tostring(g_currentMission.playerUserId)); for i,us in pairs(g_currentMission.users) do --print("us.nickname="..tostring(us.nickname).." us.userId="..tostring(us.userId).." "..tostring(self.plIdToFollow)); if us.userId == self.plIdToFollow then user = us; idx = i; break; end; end; local player; for i,pl in pairs(g_currentMission.players) do --print("pl.controllerName="..tostring(pl.controllerName).." pl.id="..tostring(pl.id).." "..tostring(self.plIdToFollow).." pl.index="..tostring(pl.index)); if pl.owner ~= nil then --if pl.owner == g_currentMission.users[self.plIdToFollow].connection then if pl.owner == g_currentMission.users[idx].connection then player = pl; break; end end; end; --if player == nil then --self.ctors[1].follow = false; --self.ctors[2].follow = false; --else for i,veh in pairs(g_currentMission.vehicles) do if veh.hoseRef ~= nil then local x,y,z = getWorldTranslation(player.graphicsRootNode); for j,ref in pairs(veh.hoseRef.refs) do local x1,y1,z1 = getWorldTranslation(ref.node); local d = Utils.vector3Length( x-x1, y-y1, z-z1 ); if d < 1.5 then if ref.isUsed == false then local park = false; if self.ctors[1].isAttached == true or self.ctors[2].isAttached == true then park = string.match( ref.rt, 'park' ); end; if not park then self.vehicleInRange = veh; self.hoseRefIdxInRange = j; break; end; end; end end; end; end -- check for stations --print("MapHoseRefStation="..tostring(MapHoseRefStation)); if MapHoseRefStation ~= nil and MapHoseRefStation.MapHoseRefStation ~= nil then --print("MapHoseRefStation.stations="..tostring(MapHoseRefStation.stations)); if MapHoseRefStation.MapHoseRefStation.stations ~= nil then local x,y,z = getWorldTranslation(player.graphicsRootNode); for i, stat in pairs(MapHoseRefStation.MapHoseRefStation.stations) do --print("stat="..tostring(stat)); if stat.ref1 ~= nil and stat.ref2 ~= nil then --print("stat.ref1="..tostring(stat.ref1).." stat.ref2="..tostring(stat.ref2)); local x1,y1,z1 = getWorldTranslation(stat.ref1); local d = Utils.vector3Length( x-x1, y-y1, z-z1 ); if d < 1.5 then if stat.isUsed == false then self.stationInRange = stat; break; end; end; end; end end; end; --end end; if self.vehicleInRange ~= self.vehicleInRangeSend then self:setVehicleAndHoseRefIdxInRange(self.vehicleInRange, self.hoseRefIdxInRange); end; if self.stationInRange ~= self.stationInRangeSend then self:setStationInRange(self.stationInRange); end; end; --# HUDs or render text? if self.isClient then setTextBold(true); setTextColor(0.0, 0.0, 0.0, 1.0); local xpos = 0.4; local ypos = 0.05; local plIR = self.ctors[1].plIR or self.ctors[2].plIR; if plIR and (not self.ctors[1].follow and not self.ctors[2].follow) then --renderText(xpos, ypos-0.02, 0.02, string.format(g_i18n:getText("HOSEREF_INTERACT"), Input.MOUSE_BUTTON_LEFT)); --renderText(xpos, ypos-0.02, 0.02, "hose"); --xpos = xpos - 0.0005; --ypos = ypos - 0.0005; --setTextColor(0.2, 0.2, 1.0, 1.0); --renderText(xpos, ypos-0.02, 0.02, string.format(g_i18n:getText("HOSEREF_INTERACT"), Input.MOUSE_BUTTON_LEFT)); --renderText(xpos, ypos-0.02, 0.02, "hose"); g_currentMission:enableHudIcon("attach", 1); --g_currentMission:enableHudIcon("hosehud", self.huds.hoseAndHandHUD.overlayId); --self.huds.hoseAndHandHUD:render(); else local show = (self.ctors[1].follow) or (self.ctors[2].follow); show = show and (self.plIdToFollow == g_currentMission.playerUserId); if show then if self.vehicleInRangeSend ~= 0 then --renderText(xpos, ypos-0.02, 0.02, string.format(g_i18n:getText("HOSEREF_INTERACT"), Input.MOUSE_BUTTON_LEFT)); --renderText(xpos, ypos-0.02, 0.02, "vehicle"); --xpos = xpos - 0.0005; --ypos = ypos - 0.0005; --setTextColor(1.0, 0.0, 1.0, 1.0); --renderText(xpos, ypos-0.02, 0.02, string.format(g_i18n:getText("HOSEREF_INTERACT"), Input.MOUSE_BUTTON_LEFT)); --renderText(xpos, ypos-0.02, 0.02, "vehicle"); --g_currentMission:enableHudIcon("refuel", 1); g_currentMission:enableHudIcon("attach", 1); elseif self.stationInRangeSend ~= 0 then --renderText(xpos, ypos-0.02, 0.02, string.format(g_i18n:getText("HOSEREF_INTERACT"), Input.MOUSE_BUTTON_LEFT)); --renderText(xpos, ypos-0.02, 0.02, "station"); --xpos = xpos - 0.0005; --ypos = ypos - 0.0005; --setTextColor(1.0, 1.0, 1.0, 1.0); --renderText(xpos, ypos-0.02, 0.02, string.format(g_i18n:getText("HOSEREF_INTERACT"), Input.MOUSE_BUTTON_LEFT)); --renderText(xpos, ypos-0.02, 0.02, "station"); --g_currentMission:enableHudIcon("refuel", 1); g_currentMission:enableHudIcon("attach", 1); end; end; end; setTextBold(false); end; end; function Hose:updateTick(dt) -- dist from local player to refs if g_currentMission.player ~= nil then local follow = self.ctors[1].follow or self.ctors[2].follow; if follow == false then local x,y,z = getWorldTranslation(g_currentMission.player.graphicsRootNode); for i=1,2 do local x1,y1,z1 = getWorldTranslation( self.ctors[i].refNode ); local d = Utils.vector3Length( x-x1, y-y1, z-z1 ); if d < 1.2 then self.ctors[i].plIR = true; break; else self.ctors[i].plIR = false; end end; end; end; end; function Hose:draw() end; function Hose:onAttach(attacherVehicle) end; function Hose:onDetach() end; --### function Hose:setFollow( plUserId, sId, state, noEventSend ) --print("function Hose:setFollow("..tostring(plUserId)..", "..tostring(sId)..", "..tostring(state)..", "..tostring(noEventSend)); Hose_SetFollowEvent.sendEvent(self, plUserId, sId, state, noEventSend); self.ctors[sId].follow = state; self.plIdToFollow = plUserId; if self.isServer then local user; local idx; --print("--------------should follow-----------"); --print("g_currentMission.playerUserId="..tostring(g_currentMission.playerUserId)); for i,us in pairs(g_currentMission.users) do --print("us.nickname="..tostring(us.nickname).." us.userId="..tostring(us.userId).." "..tostring(self.plIdToFollow)); if us.userId == self.plIdToFollow then user = us; idx = i; break; end; end; local player; if idx ~= nil and user ~= nil and g_currentMission.users[idx] ~= nil then for i,pl in pairs(g_currentMission.players) do --print("pl.controllerName="..tostring(pl.controllerName).." pl.id="..tostring(pl.id).." "..tostring(self.plIdToFollow).." pl.index="..tostring(pl.index)); if pl.owner ~= nil then --if pl.owner == g_currentMission.users[self.plIdToFollow].connection then if pl.owner == g_currentMission.users[idx].connection then player = pl; break; end end; end; else print("::WARNING/ERROR?::"); print("::WARNING/ERROR?:: Hose could not follow player !!!"); print("::WARNING/ERROR?::"); end; --[[if player ~= nil then if state then local cmpId = 1; if sId == 2 then cmpId = 4; end; local node = player.rootNode; --if sId == 2 then --node = self.ctors[sId].station.ref2; --end local x,y,z = getWorldTranslation(node); local rx,ry,rz = getWorldRotation(node); setTranslation( self.components[cmpId].node, x,y,z ); setRotation( self.components[cmpId].node, rx,ry,rz ); local constr = JointConstructor:new(); constr:setActors(node, self.components[cmpId].node); constr:setJointTransforms(node, self.components[cmpId].node); for i=1, 3 do constr:setRotationLimit(i-1, -0, 0); constr:setTranslationLimit(i-1, true, 0, 0); end; self.ctors[sId].joint = constr:finalize(); --setPairCollision(self.ctors[sId].station.id, self.components[cmpId].node, false); else removeJoint(self.ctors[sId].joint); end; else print("hose: attach, player = nil") end;]] if state then if sId == 1 then setTranslation( self.components[1].node, 0.3,1.3,-0.6 ); link(player.rootNode, self.components[1].node); setTranslation( self.components[1].node, 0.3,1.3,-0.6 ); setTranslation( self.components[1].node, 0.3,1.3,-0.6 ); setTranslation( self.components[1].node, 0.3,1.3,-0.6 ); setTranslation( self.components[1].node, 0.3,1.3,-0.6 ); elseif sId == 2 then setTranslation( self.components[4].node, 0.3,1.3,-0.6 ); link(player.rootNode, self.components[4].node); setTranslation( self.components[4].node, 0.3,1.3,-0.6 ); setTranslation( self.components[4].node, 0.3,1.3,-0.6 ); setTranslation( self.components[4].node, 0.3,1.3,-0.6 ); setTranslation( self.components[4].node, 0.3,1.3,-0.6 ); end; else if sId == 1 then --local x,y,z = getTranslation(player.cameraId); link(getRootNode(), self.components[1].node); --setTranslation( self.components[1].node, x,y,z); elseif sId == 2 then --local x,y,z = getTranslation(player.cameraId); link(getRootNode(), self.components[4].node); --setTranslation( self.components[4].node, x,y,z); end; end; end; end; --### function Hose:setAttach(veh, sId, refId, noEventSend) --print("function Hose:setAttach("..tostring(veh)..", "..tostring(sId)..", "..tostring(refId)..", "..tostring(noEventSend)); Hose_SetAttachEvent.sendEvent(self, veh, sId, refId, noEventSend); self.ctors[sId].veh = veh; self.ctors[sId].refId = refId; self.ctors[sId].follow = false; self.plIdToFollow = 0; local park; if (self.ctors[sId].veh ~= 0 and self.ctors[sId].refId ~= 0) then local ref = self.ctors[sId].veh.hoseRef.refs[self.ctors[sId].refId]; park = string.match( ref.rt, 'park' ); if park then --and sId == 2 then self.ctors[1].veh = veh; self.ctors[1].refId = refId; self.ctors[1].follow = false; self.ctors[2].veh = veh; self.ctors[2].refId = refId; self.ctors[2].follow = false; end; end; if park and sId == 2 then sId = 1; end; if self.isServer then if (self.ctors[sId].veh ~= 0 and self.ctors[sId].refId ~= 0) then local cmpId = 1; if sId == 2 then cmpId = 4; end; local ref = self.ctors[sId].veh.hoseRef.refs[self.ctors[sId].refId]; local x,y,z = getWorldTranslation(ref.node); -- self.hoseRefInRange.node); local rx,ry,rz; if sId == 1 then rx,ry,rz = getWorldRotation(ref.node); --self.hoseRefInRange.node); else rx,ry,rz = getWorldRotation(ref.node2); --self.hoseRefInRange.node2); end setTranslation( self.components[cmpId].node, x,y,z ); setRotation( self.components[cmpId].node, rx,ry,rz ); local constr = JointConstructor:new(); constr:setActors(self.ctors[sId].veh.components[ref.compIdx].node, self.components[cmpId].node); if sId == 1 then constr:setJointTransforms(ref.node, ref.node); else constr:setJointTransforms(ref.node2, ref.node2); end; for i=1, 3 do constr:setRotationLimit(i-1, -0, 0); constr:setTranslationLimit(i-1, true, 0, 0); end; self.ctors[sId].joint = constr:finalize(); --print("hose pair1") --setPairCollision(self.ctors[sId].veh.components[ref.compIdx].node, self.components[cmpId].node, false); --print("hose pair2") --[[ if not park then if sId == 1 then for i=1,table.getn(self.componentJoints),1 do local jnt = self.componentJoints[i]; setJointFrame(jnt.jointIndex, 0, jnt.jointNode); end; else for i=table.getn(self.componentJoints),1,-1 do local jnt = self.componentJoints[i]; setJointFrame(jnt.jointIndex, 1, jnt.jointNode); end; end; end; ]]-- -- play animation self.ctors[sId].veh:setRefState(self.ctors[sId].refId, true, self); self.ctors[sId].isAttached = true; self:setIsAttached(sId, true); --# 2nd side (4th comp.) if park then local sId2 = 2; local cmpId2 = 4; local x,y,z = localToWorld(ref.node, 0, 0, self.hoseLength); local rx,ry,rz; if sId == 1 then rx,ry,rz = getWorldRotation(ref.node); --self.hoseRefInRange.node); else rx,ry,rz = getWorldRotation(ref.node2); --self.hoseRefInRange.node2); end setTranslation( self.components[cmpId2].node, x,y,z ); setRotation( self.components[cmpId2].node, rx,ry,rz ); local constr = JointConstructor:new(); constr:setActors(self.ctors[sId].veh.components[ref.compIdx].node, self.components[cmpId2].node); constr:setJointTransforms(ref.node, ref.node); for i=1, 3 do constr:setRotationLimit(i-1, -0, 0); constr:setTranslationLimit(i-1, true, 0, 0); end; self.ctors[sId2].joint = constr:finalize(); --setPairCollision(self.ctors[sId].veh.components[ref.compIdx].node, self.components[cmpId2].node, false); --[[print("hose pair3") for i,vc in pairs(self.ctors[sId].veh.components) do for j,sc in pairs(self.components) do setPairCollision(vc.node, sc.node, false); end; end; print("hose pair4") for k, impl in pairs(self.ctors[sId].veh.attachedImplements) do for i,vc in pairs(impl.object.components) do for j,sc in pairs(self.components) do setPairCollision(vc.node, sc.node, false); end; end; end; print("hose pair5")]] self.ctors[sId2].veh:setRefState(self.ctors[sId2].refId, true, self); self.ctors[sId2].isAttached = true; self:setIsAttached(sId2, true); --## 2nd and 3rd comp. local ax,ay,az = getWorldTranslation(self.components[1].node); local dx,dy,dz = getWorldTranslation(self.components[4].node); local x,y,z; if sId == 1 then cmpId2 = 2; x = ax + (dx-ax)/3; y = ay + (dy-az)/3; z = az + (dy-az)/3; else cmpId2 = 3; x = dx + (ax-dx)/3; y = dy + (ay-dz)/3; z = dz + (ay-dz)/3; end setTranslation( self.components[cmpId2].node, x,y,z ); setRotation( self.components[cmpId2].node, rx,ry,rz ); if sId == 1 then cmpId2 = 3; x = ax + 2*(dx-ax)/3; y = ay + 2*(dy-az)/3; z = az + 2*(dy-az)/3; else cmpId2 = 2; x = dx + 2*(ax-dx)/3; y = dy + 2*(ay-dz)/3; z = dz + 2*(ay-dz)/3; end setTranslation( self.components[cmpId2].node, x,y,z ); setRotation( self.components[cmpId2].node, rx,ry,rz ); --[[ if sId == 1 then for i=1,table.getn(self.componentJoints),1 do local jnt = self.componentJoints[i]; setJointFrame(jnt.jointIndex, 0, jnt.jointNode); end; else for i=table.getn(self.componentJoints),1,-1 do local jnt = self.componentJoints[i]; setJointFrame(jnt.jointIndex, 1, jnt.jointNode); end; end; ]]-- end; --[[ if sId == 1 then for i=1,table.getn(self.componentJoints),1 do local jnt = self.componentJoints[i]; setJointFrame(jnt.jointIndex, 1, jnt.jointNode); end; else for i=table.getn(self.componentJoints),1,-1 do local jnt = self.componentJoints[i]; setJointFrame(jnt.jointIndex, 0, jnt.jointNode); end; end; ]]-- end; end; end; --### function Hose:setAttachStation(station, sId, noEventSend) --print("function Hose:setAttachStation("..tostring(station)..", "..tostring(sId)..", "..tostring(noEventSend)); Hose_SetAttachStationEvent.sendEvent(self, station, sId, noEventSend); self.ctors[sId].veh = 0; self.ctors[sId].refId = 0; self.ctors[sId].station = station; self.ctors[sId].follow = false; self.plIdToFollow = 0; -- attach if self.isServer then if (self.ctors[sId].station ~= 0 ) then local cmpId = 1; if sId == 2 then cmpId = 4; end; local node = self.ctors[sId].station.ref1; if sId == 2 then node = self.ctors[sId].station.ref2; end local x,y,z = getWorldTranslation(node); local rx,ry,rz = getWorldRotation(node); setTranslation( self.components[cmpId].node, x,y,z ); setRotation( self.components[cmpId].node, rx,ry,rz ); local constr = JointConstructor:new(); constr:setActors(self.ctors[sId].station.id, self.components[cmpId].node); constr:setJointTransforms(node, node); for i=1, 3 do constr:setRotationLimit(i-1, -0, 0); constr:setTranslationLimit(i-1, true, 0, 0); end; self.ctors[sId].joint = constr:finalize(); --setPairCollision(self.ctors[sId].station.id, self.components[cmpId].node, false); if sId == 1 then for i=1,table.getn(self.componentJoints),1 do local jnt = self.componentJoints[i]; setJointFrame(jnt.jointIndex, 0, jnt.jointNode); end; else for i=table.getn(self.componentJoints),1,-1 do local jnt = self.componentJoints[i]; setJointFrame(jnt.jointIndex, 1, jnt.jointNode); end; end; --self.ctors[sId].station:setRefState(true); MapHoseRefStation.MapHoseRefStation:setRefState( self.ctors[sId].station.stationId, true ); self.ctors[sId].isAttached = true; self:setIsAttached(sId, true); end; end end --### function Hose:setIsAttached(sId, state, noEventSend) --print("function Hose:setIsAttached("..tostring(sId)..", "..tostring(state)..", "..tostring(noEventSend)); Hose_SetIsAttachedEvent.sendEvent(self, sId, state, noEventSend); self.ctors[sId].isAttached = state; end; --### function Hose:setRelease(veh, sId, refId, noEventSend) --print("function Hose:setRelease("..tostring(veh)..", "..tostring(sId)..", "..tostring(refId)); Hose_SetReleaseEvent.sendEvent(self, veh, sId, refId, noEventSend); self.ctors[sId].veh = veh; -- set to zero at end self.ctors[sId].refId = refId; self.ctors[sId].follow = false; self.plIdToFollow = 0; if self.isServer then if self.ctors[sId].veh ~= 0 then local park = false; if refId ~= 0 then local ref = self.ctors[sId].veh.hoseRef.refs[self.ctors[sId].refId]; park = string.match( ref.rt, 'park' ); if park then sId = 1; end; end; removeJoint(self.ctors[sId].joint); if self.ctors[sId].refId ~= 0 then self.ctors[sId].veh:setRefState(self.ctors[sId].refId, false, 0); else MapHoseRefStation.MapHoseRefStation:setRefState( self.ctors[sId].station.stationId, false ); end; self.ctors[sId].isAttached = false; self.ctors[sId].veh = 0; self.ctors[sId].refId = 0; self.ctors[sId].station = 0; self:setIsAttached(sId, false); if park then sId = 2; removeJoint(self.ctors[sId].joint); removeJoint(self.extraJnts[1]); removeJoint(self.extraJnts[2]); self.ctors[sId].veh:setRefState(self.ctors[sId].refId, false, 0); self.ctors[sId].isAttached = false; self.ctors[sId].veh = 0; self.ctors[sId].refId = 0; self.ctors[sId].station = 0; self:setIsAttached(sId, false); end end; end end; --### function Hose:setVehicleAndHoseRefIdxInRange(veh, j, noEventSend) --print("function Hose:setVehicleAndHoseRefIdxInRange("..tostring(veh)..", "..tostring(j)..", "..tostring(noEventSend)); Hose_SetVehicleAndRefIdxEvent.sendEvent(self, veh, j, noEventSend); self.vehicleInRangeSend = veh; self.hoseRefIdxInRangeSend = j; end; --### function Hose:setStationInRange(stat, noEventSend) --print("function Hose:setStationInRange("..tostring(stat)..", "..tostring(noEventSend)); Hose_SetStationEvent.sendEvent(self, stat, noEventSend); self.stationInRangeSend = stat; end; --### function Hose:updateMesh() --### catmull rom spline local x1,y1,z1 = localToWorld( self.components[1].node, 0,0,-7 ); -- or -10 ? local x2,y2,z2 = localToWorld( self.components[1].node, 0,0,-0.05 ); local x3,y3,z3 = localToWorld( self.components[4].node, 0,0, 0.05 ); local x4,y4,z4 = localToWorld( self.components[4].node, 0,0, 7 ); --local dist = Utils.vector3Length( x3-x2, y3-y2, z3-z2 ); local dist1 = Utils.vector3Length( x2-self.lastPos[1].pos[1], y2-self.lastPos[1].pos[2], z2-self.lastPos[1].pos[3] ); local dist2 = Utils.vector3Length( x3-self.lastPos[2].pos[1], y3-self.lastPos[2].pos[2], z3-self.lastPos[2].pos[3] ); if dist1 > 0.001 or dist2 > 0.001 then --math.abs(self.compDist - dist) > 0.001 then self.compDist = dist; self.lastPos[1].pos = {x2,y2,z2}; self.lastPos[2].pos = {x3,y3,z3}; --# 1) for i=1,17 do local t = (i-1)/16; --local xc = 0.5 *((2 * pts[2].x) + (-pts[1].x + pts[3].x) * t + (2*pts[1].x - 5*pts[2].x + 4*pts[3].x - pts[4].x) * t^2 + (-pts[1].x + 3*pts[2].x - 3*pts[3].x + pts[4].x) * t^3); --local yc = 0.5 *((2 * pts[2].y) + (-pts[1].y + pts[3].y) * t + (2*pts[1].y - 5*pts[2].y + 4*pts[3].y - pts[4].y) * t^2 + (-pts[1].y + 3*pts[2].y - 3*pts[3].y + pts[4].y) * t^3); --local zc = 0.5 *((2 * pts[2].z) + (-pts[1].z + pts[3].z) * t + (2*pts[1].z - 5*pts[2].z + 4*pts[3].z - pts[4].z) * t^2 + (-pts[1].z + 3*pts[2].z - 3*pts[3].z + pts[4].z) * t^3); local xc = 0.5 *((2 * x2) + (-x1 + x3) * t + (2*x1 - 5*x2 + 4*x3 - x4) * t^2 + (-x1 + 3*x2 - 3*x3 + x4) * t^3); local yc = 0.5 *((2 * y2) + (-y1 + y3) * t + (2*y1 - 5*y2 + 4*y3 - y4) * t^2 + (-y1 + 3*y2 - 3*y3 + y4) * t^3); local zc = 0.5 *((2 * z2) + (-z1 + z3) * t + (2*z1 - 5*z2 + 4*z3 - z4) * t^2 + (-z1 + 3*z2 - 3*z3 + z4) * t^3); local x,y,z = worldToLocal( self.jntsRef, xc,yc,zc ); setTranslation( self.jnts[i], x,y,z ); if Vehicle.debugRendering then drawDebugPoint( xc,yc,zc, 1,i/17,0,1 ); end; end --# 2) for i=1,16 do local bx,by,bz = getWorldTranslation(self.jnts[i+1]); local ax,ay,az = getWorldTranslation(self.jnts[i]); local dx,dy,dz = worldDirectionToLocal( self.jntsRef, bx-ax, by-ay, bz-az ); setDirection( self.jnts[i], dx,dy,dz ); end local bx,by,bz = localToWorld( self.components[4].node, 0,0,1 ); local ax,ay,az = getWorldTranslation(self.jnts[17]); local dx,dy,dz = worldDirectionToLocal( self.jntsRef, bx-ax, by-ay, bz-az ); setDirection( self.jnts[17], dx,dy,dz ); end; --# debug line --[[ for s=0,table.getn(pts)-4 do local p0 = { x=pts[s+1].x, y=pts[s+1].y; z=pts[s+1].z }; local p1 = { x=pts[s+2].x, y=pts[s+2].y; z=pts[s+2].z }; local p2 = { x=pts[s+3].x, y=pts[s+3].y; z=pts[s+3].z }; local p3 = { x=pts[s+4].x, y=pts[s+4].y; z=pts[s+4].z }; for t=0,1,0.1 do local xc = 0.5 *((2 * p1.x) + (-p0.x + p2.x) * t + (2*p0.x - 5*p1.x + 4*p2.x - p3.x) * t^2 + (-p0.x + 3*p1.x - 3*p2.x + p3.x) * t^3); local yc = 0.5 *((2 * p1.y) + (-p0.y + p2.y) * t + (2*p0.y - 5*p1.y + 4*p2.y - p3.y) * t^2 + (-p0.y + 3*p1.y - 3*p2.y + p3.y) * t^3); local zc = 0.5 *((2 * p1.z) + (-p0.z + p2.z) * t + (2*p0.z - 5*p1.z + 4*p2.z - p3.z) * t^2 + (-p0.z + 3*p1.z - 3*p2.z + p3.z) * t^3); local t2 = t + 0.1; local xn = 0.5 *((2 * p1.x) + (-p0.x + p2.x) * t2 + (2*p0.x - 5*p1.x + 4*p2.x - p3.x) * t2^2 + (-p0.x + 3*p1.x - 3*p2.x + p3.x) * t2^3); local yn = 0.5 *((2 * p1.y) + (-p0.y + p2.y) * t2 + (2*p0.y - 5*p1.y + 4*p2.y - p3.y) * t2^2 + (-p0.y + 3*p1.y - 3*p2.y + p3.y) * t2^3); -- local zn = 0.5 *((2 * p1.z) + (-p0.z + p2.z) * t2 + (2*p0.z - 5*p1.z + 4*p2.z - p3.z) * t2^2 + (-p0.z + 3*p1.z - 3*p2.z + p3.z) * t2^3); drawDebugLine(xc, yc, zc, 1,0,0, xn, yn, zn, 1,1,0); end end ]]-- end;