-- -- Big thanks to all of those who helped with development of IC -- SFM-Modding, LoogleCZ, And other... -- Original IC: Manuel Leithner -- Edit IC and current development: Martin Fabík (LoogleCZ) -- Testing: Daniel Zapletal, Martin Fabík -- and others... -- -- Free for non-comerecial usage -- -- Important note: this is BETA script. If anyone found errors, please contact me at mar.fabik@gmail.com -- Script is under active development. You can discuss changes with me at mar.fabik@gmail.com -- -- version ID - 2.95 -- version date - 24.4.2016 (19:44) -- if originalInputBindingUpdate == nil then originalInputBindingUpdate = InputBinding.update; InputBinding.update = function(dt) InputBinding.accumMouseMovementXBackUp = InputBinding.accumMouseMovementX; InputBinding.accumMouseMovementYBackUp = InputBinding.accumMouseMovementY; originalInputBindingUpdate(dt); end; end; InteractiveControl = {}; local MDR = g_currentModDirectory; source(MDR.."ICSources/actionFunction.lua"); source(MDR.."ICSources/extraFunctions.lua"); source(MDR.."ICSources/InteractiveControlEvent.lua"); function InteractiveControl.prerequisitesPresent(specializations) return true; end; function InteractiveControl:load(savegame) self.renderOverlayAndInfo = SpecializationUtil.callSpecializationsFunction("renderOverlayAndInfo"); self.toggleICState = SpecializationUtil.callSpecializationsFunction("toggleICState"); self.actionOnObject = SpecializationUtil.callSpecializationsFunction("actionOnObject"); self.updateOpenStatus = SpecializationUtil.callSpecializationsFunction("updateOpenStatus"); self.loadICButtonFromXML = InteractiveControl.loadICButtonFromXML; source(MDR.."ICSources/functionsInit.lua"); self.LIC = {}; self.LIC.interactiveObjects = {}; self.LIC.objectsListeners = {}; self.LIC.getElementListeners = {}; self.indoorCamIndex = 1; self.outdoorCamIndex = 2; self.LIC.lastMouseXPos = 0; self.LIC.lastMouseYPos = 0; self.LIC.foundInteractiveObject = nil; self.LIC.isMouseActive = false; self.LIC.minOutsideDistance = Utils.getNoNil(getXMLFloat(self.xmlFile,"vehicle.interactiveComponents#minDist"), 3); self.LIC.toggleStateStyle = Utils.getNoNil(getXMLFloat(self.xmlFile,"vehicle.interactiveComponents#toggleStyle"), 0); self.LIC.isInOutsideRange = false; self.LIC.isInitialized = false; self.LIC.isClicked = false; self.LIC.camRotPlayer = {}; self.LIC.partLen = {}; local j = 0; --=========================================-- self.LIC.joints = {}; self.LIC.joints.front = {}; self.LIC.joints.back = {}; for k,joint in pairs(self.attacherJoints) do if joint.jointType == Vehicle.JOINTTYPE_IMPLEMENT or joint.jointType == Vehicle.JOINTTYPE_CUTTER or joint.jointType == Vehicle.JOINTTYPE_CUTTERHARVESTER or joint.jointType == Vehicle.JOINTTYPE_TRAILER or joint.jointType == Vehicle.JOINTTYPE_TRAILERLOW then local x,y,z = getWorldTranslation(self.attacherJoints[k].jointTransform); local rx,ry,rz = worldToLocal(self.rootNode,x,y,z); if rz > 0 then table.insert(self.LIC.joints.front,k); else table.insert(self.LIC.joints.back,k); end; end; end; --=========================================-- -- Interactive Window -- local i=0; while true do local objectType = 0; local key = string.format("vehicle.interactiveComponents.windows.window(%d)", i); if not hasXMLProperty(self.xmlFile, key) then break; end; local animation = getXMLString(self.xmlFile, key .. "#animName"); local looping = Utils.getNoNil(getXMLBool(self.xmlFile, key.."#looping"), false); local speedScale = -Utils.getNoNil(getXMLFloat(self.xmlFile, key .. "#animSpeedScale"), 1); local clipParent = Utils.indexToObject(self.components, getXMLString(self.xmlFile, key .. "#clipRoot")); local animClip = nil; if clipParent ~= nil and clipParent ~= 0 then animClip = {}; animClip.animCharSet = getAnimCharacterSet(clipParent); if animClip.animCharSet ~= 0 then local clip = getAnimClipIndex(animClip.animCharSet, getXMLString(self.xmlFile, key .. "#clip")); assignAnimTrackClip(animClip.animCharSet, 0, clip); setAnimTrackLoopState(animClip.animCharSet, 0, looping); animClip.animDuration = getAnimClipDuration(animClip.animCharSet, clip); setAnimTrackTime(animClip.animCharSet, 0, 0); end; end; if animation ~= nil or animClip ~= nil then self.LIC.interactiveObjects[j] = {}; self.LIC.interactiveObjects[j].animation = animation; self.LIC.interactiveObjects[j].animClip = animClip; self.LIC.interactiveObjects[j].speedScale = speedScale; self.LIC.interactiveObjects[j].objectType = objectType; self.LIC.interactiveObjects[j].looping = looping; self.LIC.interactiveObjects[j].isEntered = false; self:loadICButtonFromXML(self.xmlFile, key, self.LIC.interactiveObjects[j], j); j = j + 1; else print(string.format("Cannot load Interactive Window - vehicle.interactiveComponents.windows.window(%d)",i)); print(" - Missing animation or animation clip."); end; i = i + 1; end; self.LIC.partLen.animation = j; --=========================================-- --=========================================-- -- Interactive Buttons -- local i=0; while true do local objectType = 1; local key = string.format("vehicle.interactiveComponents.buttons.button(%d)", i); if not hasXMLProperty(self.xmlFile, key) then break; end; local event = getXMLString(self.xmlFile, key .. "#event"); if event ~= nil then self.LIC.interactiveObjects[j] = {}; self.LIC.interactiveObjects[j].event = event; self.LIC.interactiveObjects[j].objectType = objectType; self.LIC.interactiveObjects[j].isEntered = false; self:loadICButtonFromXML(self.xmlFile, key, self.LIC.interactiveObjects[j], j); if string.sub( self.LIC.interactiveObjects[j].event, 1, 10 ) == "l2gsToggle" then self.LIC.interactiveObjects[j].synch = false; end; j = j + 1; else print(string.format("Cannot load Interactive Button - vehicle.interactiveComponents.buttons.button(%d)",i)); print(" - missing event"); end; i = i + 1; end; self.LIC.partLen.button = j-self.LIC.partLen.animation; --=========================================-- --=========================================-- -- Interactive Monitors -- local i=0; local m=0; while true do local objectType = 2; local key = string.format("vehicle.interactiveComponents.monitors.monitor(%d)", i); if not hasXMLProperty(self.xmlFile, key) then break; end; local useStart = Utils.getNoNil(getXMLBool(self.xmlFile, key .. "#useStart"), true); local startAnimation = getXMLString(self.xmlFile, key .. "#animName"); local layerBackupPos = getXMLString(self.xmlFile, key .. "#layerClosePos"); local layerVisPos = getXMLString(self.xmlFile, key .. "#layerVisPos"); local defaultLayer = getXMLInt(self.xmlFile, key .. "#defaultLayer"); local moveDef = Utils.getNoNil(getXMLBool(self.xmlFile, key .. "#moveDefaultLayer"), false); if layerBackupPos ~= nil and layerVisPos ~= nil then self.LIC.interactiveObjects[j] = {}; self.LIC.interactiveObjects[j].objectType = objectType; self.LIC.interactiveObjects[j].useStart = useStart; self.LIC.interactiveObjects[j].startAnimation = startAnimation; self.LIC.interactiveObjects[j].defaultLayer = defaultLayer; self.LIC.interactiveObjects[j].moveDef = moveDef; self.LIC.interactiveObjects[j].layerBackupPos = {}; self.LIC.interactiveObjects[j].layerBackupPos[1],self.LIC.interactiveObjects[j].layerBackupPos[2],self.LIC.interactiveObjects[j].layerBackupPos[3] = Utils.getVectorFromString(layerBackupPos); self.LIC.interactiveObjects[j].layerVisPos = {}; self.LIC.interactiveObjects[j].layerVisPos[1],self.LIC.interactiveObjects[j].layerVisPos[2],self.LIC.interactiveObjects[j].layerVisPos[3] = Utils.getVectorFromString(layerVisPos); self.LIC.interactiveObjects[j].isEntered = false; self.LIC.interactiveObjects[j].activeLayer = defaultLayer; self.LIC.interactiveObjects[j].layerButtons = {}; self.LIC.interactiveObjects[j].layerIndexes = {}; self:loadICButtonFromXML(self.xmlFile, key, self.LIC.interactiveObjects[j]); local k = 0; local upperLayerIndex = j; while true do local key2 = string.format(key..".layer(%d)", k); if not hasXMLProperty(self.xmlFile, key2) then break; end; local name = Utils.getNoNil((getXMLString(self.xmlFile, key2 .. "#name")), "ERROR"); local index = Utils.indexToObject(self.components, getXMLString(self.xmlFile, key2 .. "#index")); local size = Utils.getNoNil(getXMLFloat(self.xmlFile, key2 .. ".open#size"), 0.1); local mark = Utils.indexToObject(self.components, getXMLString(self.xmlFile, key2 .. ".open#mark")); local size1 = Utils.getNoNil(getXMLFloat(self.xmlFile, key2 .. ".close#size"), 0.1); local mark1 = Utils.indexToObject(self.components, getXMLString(self.xmlFile, key2 .. ".close#mark")); local onMessage = g_i18n:getText(Utils.getNoNil(getXMLString(self.xmlFile, key2 .. "#onMessage"), "ic_button_on")); local offMessage = g_i18n:getText(Utils.getNoNil(getXMLString(self.xmlFile, key2 .. "#offMessage") , "ic_button_off")); if mark ~= nil then setVisibility(mark,false); end; if mark1 ~= nil then setVisibility(mark1,false); end; if index ~= nil then self.LIC.interactiveObjects[upperLayerIndex].layerIndexes[k] = index; if mark1 ~= nil and mark ~= nil then j = j + 1; m = m + 1; self.LIC.interactiveObjects[j] = {}; self.LIC.interactiveObjects[j].event = "openDisplayLayer"; self.LIC.interactiveObjects[j].objectType = 1; self.LIC.interactiveObjects[j].index = k; self.LIC.interactiveObjects[j].name = name; self.LIC.interactiveObjects[j].mark = mark; self.LIC.interactiveObjects[j].size = size; self.LIC.interactiveObjects[j].onMessage = onMessage; self.LIC.interactiveObjects[j].offMessage = onMessage; self.LIC.interactiveObjects[j].synch = self.LIC.interactiveObjects[upperLayerIndex].synch; self.LIC.interactiveObjects[j].parentLayer = upperLayerIndex; self.LIC.interactiveObjects[j].isOpen = false; local sf = getXMLString(self.xmlFile, key2..".open#soundFile"); if sf ~= nil then self.LIC.interactiveObjects[j].audio = createSample(string.format("ICSound%d",j)); loadSample(self.LIC.interactiveObjects[j].audio, MDR..sf, false); end; table.insert(self.LIC.interactiveObjects[upperLayerIndex].layerButtons,j); j = j + 1; m = m + 1; self.LIC.interactiveObjects[j] = {}; self.LIC.interactiveObjects[j].event = "closeDisplayLayer"; self.LIC.interactiveObjects[j].objectType = 1; self.LIC.interactiveObjects[j].index = k; self.LIC.interactiveObjects[j].name = name; self.LIC.interactiveObjects[j].mark = mark1; self.LIC.interactiveObjects[j].size = size1; self.LIC.interactiveObjects[j].onMessage = offMessage; self.LIC.interactiveObjects[j].offMessage = offMessage; self.LIC.interactiveObjects[j].synch = self.LIC.interactiveObjects[upperLayerIndex].synch; self.LIC.interactiveObjects[j].parentLayer = upperLayerIndex; self.LIC.interactiveObjects[j].isOpen = false; local sf = getXMLString(self.xmlFile, key2..".close#soundFile"); if sf ~= nil then self.LIC.interactiveObjects[j].audio = createSample(string.format("ICSound%d",j)); loadSample(self.LIC.interactiveObjects[j].audio, MDR..sf, false); end; table.insert(self.LIC.interactiveObjects[upperLayerIndex].layerButtons,j); setVisibility(index, false); -- prvne open a potom close end; end; k = k + 1; end; j = j + 1; m = m + 1; self:actionOnObject(upperLayerIndex, false, true); else print(string.format("Cannot load Interactive monitor - vehicle.interactiveComponents.monitors.monitor(%d)",i)); print(" - invalid backup and vis positions"); end; i = i + 1; end; self.LIC.partLen.monitor = m; --=========================================-- --=========================================-- -- Interactive visibility -- local i=0; local m=0; while true do local objectType = 3; local key = string.format("vehicle.interactiveComponents.visControls.button(%d)", i); if not hasXMLProperty(self.xmlFile, key) then break; end; local defVis = getXMLBool(self.xmlFile, key .. "#defaultVis"); local typeChange = Utils.getNoNil(getXMLString(self.xmlFile, key .. "#typeChange"), "set"); local controlObject = getXMLString(self.xmlFile, key .. "#controlElem"); self.LIC.interactiveObjects[j] = {}; self.LIC.interactiveObjects[j].objectType = objectType; self.LIC.interactiveObjects[j].typeChange = typeChange; self.LIC.interactiveObjects[j].isEntered = false; if controlObject ~= nil then self.LIC.interactiveObjects[j].controlObject = Utils.indexToObject(self.components, controlObject); end; self.LIC.interactiveObjects[j].objects = {}; local k = 0; while true do local key2 = string.format(key..".index(%d)", k); if not hasXMLProperty(self.xmlFile, key2) then break; end; local index = getXMLString(self.xmlFile, key2.."#index"); if index ~= nil then self.LIC.interactiveObjects[j].objects[(k+1)] = Utils.indexToObject(self.components, index); if defVis ~= nil then setVisibility(self.LIC.interactiveObjects[j].objects[(k+1)], defVis); end; end; k = k + 1; end; self:loadICButtonFromXML(self.xmlFile, key, self.LIC.interactiveObjects[j], j); j = j + 1; m = m + 1; i = i + 1; end; self.LIC.partLen.visibility = m; --=========================================-- --============ MULTI BUTTONS ==============-- local i=0; self.LIC.partLen.mbutton = 0; while true do local objectType = 4; local key = string.format("vehicle.interactiveComponents.multiButtons.mbutton(%d)", i); if not hasXMLProperty(self.xmlFile, key) then break; end; self.LIC.interactiveObjects[j] = {}; self.LIC.interactiveObjects[j].objectType = objectType; self.LIC.interactiveObjects[j].isEntered = false; if hasXMLProperty(self.xmlFile, key..".control") then local mbtype = getXMLString(self.xmlFile, key..".control#type"); local index = getXMLInt(self.xmlFile, key..".control#index"); if index <= self.LIC.partLen[mbtype] then local indexFinal = index; if mbtype == "animation" then elseif mbtype == "button" then indexFinal = indexFinal + self.LIC.partLen.animation; elseif mbtype == "monitor" then indexFinal = indexFinal + self.LIC.partLen.button + self.LIC.partLen.animation; elseif mbtype == "visibility" then indexFinal = indexFinal + self.LIC.partLen.monitor + self.LIC.partLen.button + self.LIC.partLen.animation; elseif mbtype == "mbutton" then indexFinal = indexFinal + self.LIC.partLen.visibility + self.LIC.partLen.monitor + self.LIC.partLen.button + self.LIC.partLen.animation; end; self.LIC.interactiveObjects[j].controlElement = indexFinal; end; end; local k = 0; self.LIC.interactiveObjects[j].actionElements = {}; while true do key2 = string.format(key..".part(%d)",k); if not hasXMLProperty(self.xmlFile, key2) then break; end; local mbtype = getXMLString(self.xmlFile, key2.."#type"); local index = getXMLInt(self.xmlFile, key2.."#index"); local neg = Utils.getNoNil(getXMLInt(self.xmlFile, key2.."#negStatus"),false); if index <= self.LIC.partLen[mbtype] then local indexFinal = index; if mbtype == "animation" then elseif mbtype == "button" then indexFinal = indexFinal + self.LIC.partLen.animation; elseif mbtype == "monitor" then indexFinal = indexFinal + self.LIC.partLen.button + self.LIC.partLen.animation; elseif mbtype == "visibility" then indexFinal = indexFinal + self.LIC.partLen.monitor + self.LIC.partLen.button + self.LIC.partLen.animation; elseif mbtype == "mbutton" then indexFinal = indexFinal + self.LIC.partLen.visibility + self.LIC.partLen.monitor + self.LIC.partLen.button + self.LIC.partLen.animation; end; self.LIC.interactiveObjects[j].actionElements[indexFinal] = neg; end; k = k + 1; end; self:loadICButtonFromXML(self.xmlFile, key, self.LIC.interactiveObjects[j], j); j = j + 1; self.LIC.partLen.mbutton = self.LIC.partLen.mbutton + 1; i = i + 1; end; --====================================-- --=== LOAD CROSS BUTTONS LISTENERS ===-- local i=0; while true do local key = string.format("vehicle.interactiveComponents.buttonsListeners.listener(%d)", i); if not hasXMLProperty(self.xmlFile, key) then break; end; self.LIC.objectsListeners[i] = {}; local j = 0; while true do local key2 = string.format(key .. ".element(%d)", j); if not hasXMLProperty(self.xmlFile, key2) then break; end; local Ltype = getXMLString(self.xmlFile, key2.."#type"); local Oindex = getXMLInt(self.xmlFile, key2.."#index"); if Oindex <= self.LIC.partLen[Ltype] then local indexFinal = Oindex; if Ltype == "animation" then elseif Ltype == "button" then indexFinal = indexFinal + self.LIC.partLen.animation; elseif Ltype == "monitor" then indexFinal = indexFinal + self.LIC.partLen.button + self.LIC.partLen.animation; elseif Ltype == "visibility" then indexFinal = indexFinal + self.LIC.partLen.monitor + self.LIC.partLen.button + self.LIC.partLen.animation; elseif Ltype == "mbutton" then indexFinal = indexFinal + self.LIC.partLen.visibility + self.LIC.partLen.monitor + self.LIC.partLen.button + self.LIC.partLen.animation; end; table.insert(self.LIC.objectsListeners[i],indexFinal); if self.LIC.getElementListeners[indexFinal] == nil then table.insert(self.LIC.getElementListeners,indexFinal,{}); end; self.LIC.getElementListeners[indexFinal][table.getn(self.LIC.getElementListeners[indexFinal])] = i; end; j = j + 1; end; i = i + 1; end; end; function InteractiveControl:delete() end; function InteractiveControl:readStream(streamId, connection) local icCount = streamReadInt8(streamId); for i=0, icCount do local LICId = streamReadInt8(streamId); local isOpen = streamReadBool(streamId); if self.LIC.interactiveObjects[LICId] ~= nil then if self.LIC.interactiveObjects[LICId].synch then self:actionOnObject(LICId, isOpen, false); end; end; end; end; function InteractiveControl:writeStream(streamId, connection) local icCount = (table.getn(self.LIC.interactiveObjects)-1); streamWriteInt8(streamId, icCount); for i=0, icCount do streamWriteInt8(streamId, i); streamWriteBool(streamId, self.LIC.interactiveObjects[i].isOpen); end; end; function InteractiveControl:mouseEvent(posX, posY, isDown, isUp, button) self.LIC.lastMouseXPos = posX; self.LIC.lastMouseYPos = posY; end; function InteractiveControl:keyEvent(unicode, sym, modifier, isDown) end; function InteractiveControl:update(dt) local blockToggle = false; if self.isMotorStarted then self.forceIsActive = true; if not self.LIC.isInitialized then self.LIC.isInitialized = not self.LIC.isInitialized; for k,v in pairs(self.LIC.interactiveObjects) do if v.objectType == 2 and v.useStart then self:actionOnObject(k, true); end; end; end; else self.forceIsActive = false; if self.LIC.isInitialized then self.LIC.isInitialized = not self.LIC.isInitialized; for k,v in pairs(self.LIC.interactiveObjects) do if v.objectType == 2 then self:actionOnObject(k, false); end; end; end; end; if Input.isMouseButtonPressed(Input.MOUSE_BUTTON_LEFT) and self.LIC.foundInteractiveObject ~= nil then if not self.LIC.isClicked then self.LIC.isClicked = true; self:actionOnObject(self.LIC.foundInteractiveObject); if self.LIC.interactiveObjects[self.LIC.foundInteractiveObject].audio ~= nil then if self:getIsActiveForSound() then playSample(self.LIC.interactiveObjects[self.LIC.foundInteractiveObject].audio,1,1,0); end; end; end; else self.LIC.isClicked = false; end; if self.isMouseActive then self.mouseButton = MouseControlsVehicle.BUTTON_NONE; end; self.LIC.foundInteractiveObject = nil; if self.LIC.isInOutsideRange and not blockToggle then if self.LIC.isMouseActive then g_currentMission:addHelpButtonText(g_i18n:getText("InteractiveControl_Off"), InputBinding.INTERACTIVE_CONTROL_SWITCH); else g_currentMission:addHelpButtonText(g_i18n:getText("InteractiveControl_On"), InputBinding.INTERACTIVE_CONTROL_SWITCH); end; if self.LIC.toggleStateStyle == 0 then if InputBinding.hasEvent(InputBinding.INTERACTIVE_CONTROL_SWITCH) then self:toggleICState(true); end; elseif self.LIC.toggleStateStyle == 1 then if InputBinding.isPressed(InputBinding.INTERACTIVE_CONTROL_SWITCH) then self:toggleICState(true,true); else self:toggleICState(true,false); end; end; blockToggle = true; end; if self:getIsActive() then if self.isClient and self:getIsActiveForInput(false) and not self:hasInputConflictWithSelection() and not blockToggle then if self.LIC.isMouseActive then g_currentMission:addHelpButtonText(g_i18n:getText("InteractiveControl_Off"), InputBinding.INTERACTIVE_CONTROL_SWITCH); else g_currentMission:addHelpButtonText(g_i18n:getText("InteractiveControl_On"), InputBinding.INTERACTIVE_CONTROL_SWITCH); end; if self.LIC.toggleStateStyle == 0 then if InputBinding.hasEvent(InputBinding.INTERACTIVE_CONTROL_SWITCH) then self:toggleICState(false); end; elseif self.LIC.toggleStateStyle == 1 then if InputBinding.isPressed(InputBinding.INTERACTIVE_CONTROL_SWITCH) then self:toggleICState(false,true); else self:toggleICState(false,false); end; end; blockToggle = true; end; end; if self.LIC.isMouseActive and not self.isEntered then self.LIC.lastMouseXPos = InputBinding.mousePosXLast; self.LIC.lastMouseYPos = InputBinding.mousePosYLast; for _,v in pairs(self.LIC.interactiveObjects) do v.isEntered = false; end if self.LIC.lastMouseXPos ~= nil and self.LIC.lastMouseYPos ~= nil then for k,v in pairs(self.LIC.interactiveObjects) do if v.mark ~= nil and self.LIC.foundInteractiveObject == nil then local worldX,worldY,worldZ = getWorldTranslation(v.mark); local x,y,z = project(worldX,worldY,worldZ); if z <= 1 then if self.LIC.lastMouseXPos > (x-v.size/2) and self.LIC.lastMouseXPos < (x+v.size/2) then if self.LIC.lastMouseYPos > (y-v.size/2) and self.LIC.lastMouseYPos < (y+v.size/2) then if v.canOutside then v.isEntered = true; self:renderOverlayAndInfo(v); self:updateOpenStatus(k); self.LIC.foundInteractiveObject = k; break; end; end; end; end; end; end; end; end; if self:getIsActive() then InputBinding.accumMouseMovementXBackUp = 0; InputBinding.accumMouseMovementYBackUp = 0; end; end; function InteractiveControl:updateTick(dt) if g_currentMission.player ~= nil then local nearestDistance = self.LIC.minOutsideDistance; local px, py, pz = getWorldTranslation(self.rootNode); local vx, vy, vz = getWorldTranslation(g_currentMission.player.rootNode); local distance = Utils.vector3Length(px-vx, py-vy, pz-vz); if distance < nearestDistance then self.LIC.isInOutsideRange = true; else if self.LIC.isInOutsideRange then self:toggleICState(false, false); self.LIC.isInOutsideRange = false; end; end; end; end; function InteractiveControl:draw() if self.LIC.isMouseActive and self.isEntered then for _,v in pairs(self.LIC.interactiveObjects) do v.isEntered = false; end if self.LIC.lastMouseXPos ~= nil and self.LIC.lastMouseYPos ~= nil then for k,v in pairs(self.LIC.interactiveObjects) do if v.mark ~= nil and self.LIC.foundInteractiveObject == nil then local worldX,worldY,worldZ = getWorldTranslation(v.mark); local x,y,z = project(worldX,worldY,worldZ); if z <= 1 then if self.LIC.lastMouseXPos > (x-v.size/2) and self.LIC.lastMouseXPos < (x+v.size/2) then if self.LIC.lastMouseYPos > (y-v.size/2) and self.LIC.lastMouseYPos < (y+v.size/2) then if not v.canOutside then v.isEntered = true; self:renderOverlayAndInfo(v); self:updateOpenStatus(k); self.LIC.foundInteractiveObject = k; break; end; end; end; end; end; end; end; end; end; function InteractiveControl:onEnter() end; function InteractiveControl:onLeave() self:toggleICState(false, false); -- g_mouseControlsHelp.active = true; if g_gui.currentGui == nil then InputBinding.setShowMouseCursor(false); end; end; function InteractiveControl:renderOverlayAndInfo(object) if object.isOpen then g_currentMission:addExtraPrintText(string.format(object.offMessage, object.name)); else g_currentMission:addExtraPrintText(string.format(object.onMessage, object.name)); end; end; function InteractiveControl:toggleICState(isOutside, forceStatus) if self.isClient then if self.LIC.isMouseActive == nil then print("Shit happens"); self.LIC.isMouseActive = false; self:toggleICState(false, true); self:toggleICState(false, false); end; if self.LIC.isMouseActive ~= forceStatus then if forceStatus == nil then self.LIC.isMouseActive = not self.LIC.isMouseActive; else self.LIC.isMouseActive = forceStatus; end; -- g_mouseControlsHelp.active = not self.LIC.isMouseActive; if self.LIC.isMouseActive then if g_currentMission.player ~= nil then g_currentMission.player.walkingIsLocked = true; end; InputBinding.setShowMouseCursor(true); if self.cameras ~= nil then for _,v in pairs(self.cameras) do v.isActivated = false; end; end; else if g_currentMission.player ~= nil then g_currentMission.player.walkingIsLocked = false; end; InputBinding.setShowMouseCursor(false); for _,v in pairs(self.LIC.interactiveObjects) do v.isEntered = false; if v.mark ~= nil then setVisibility(v.mark, false); end; end; if self.cameras ~= nil then for _,v in pairs(self.cameras) do v.isActivated = true; end; end; end; if self.LIC.isMouseActive then for k,v in pairs(self.LIC.interactiveObjects) do if isOutside and v.canOutside then if v.mark ~= nil then setVisibility(v.mark, true); end; elseif (not isOutside or isOutside == nil) and not v.canOutside then if v.mark ~= nil then setVisibility(v.mark, true); end; end; end; end; if not self.LIC.isMouseActive then self.LIC.foundInteractiveObject = nil; end; end; end; end; function InteractiveControl:loadICButtonFromXML(xmlFile, key, ICBtn, index) ICBtn.name = g_i18n:getText(Utils.getNoNil((getXMLString(xmlFile, key .. "#name")), "ERROR")); ICBtn.size = Utils.getNoNil((getXMLFloat(xmlFile, key .. "#size")), 0.05); ICBtn.mark = Utils.indexToObject(self.components, getXMLString(xmlFile, key .. "#mark")); if ICBtn.mark ~= nil then setVisibility(ICBtn.mark,false); end; ICBtn.isOpen = Utils.getNoNil((getXMLBool(xmlFile, key .. "#defaultStatus")), false); ICBtn.onMessage = g_i18n:getText(Utils.getNoNil(getXMLString(xmlFile, key .. "#onMessage"), "ic_button_on")); ICBtn.offMessage = g_i18n:getText(Utils.getNoNil(getXMLString(xmlFile, key .. "#offMessage") , "ic_button_off")); ICBtn.canOutside = Utils.getNoNil(getXMLBool(xmlFile, key.."#isOutside"), false); ICBtn.synch = Utils.getNoNil(getXMLBool(xmlFile, key.."#synch"), true); local initAction = Utils.getNoNil((getXMLBool(xmlFile, key .. "#initAction")), true); local soundFile = getXMLString(xmlFile, key.."#soundFile"); if soundFile ~= nil and index ~= nil then ICBtn.audio = createSample(string.format("ICSound%d",index)); loadSample(ICBtn.audio, MDR..soundFile, false); end; if initAction and index ~= nil and self.isServer then self:actionOnObject(index, ICBtn.isOpen, true); end; end;