LUADOC - Farming Simulator 19

Script v1.7.1.0

Engine v1.7.1.0

Foundation Reference

Player

Description
class.
Parent
Object
XML Configuration Parameters
player.filenamei3d file of the player
player.camera#indexscenegraph node of the player camera
player.light#indexscenegraph node of the light
player.pickUpKinematicHelper#indexscenegraph node of the light
player.character#type"male" or "female"
player.character#physicsCapsuleHeightcapsule height (in m)
player.character#physicsCapsuleRadiuscapsule radius (in m)
player.character.thirdPerson#meshscenegraph node of the 3rd person mesh
player.character.thirdPerson#skeletonscenegraph node of the skeleton
player.character.thirdPerson#animRootNodescenegraph node of the root node
player.character.thirdPerson#spinescenegraph node of the spine
player.character.thirdPerson#torsoscenegraph node of the torso
player.character.thirdPerson#leftHandNodescenegraph node of the left hand
player.character.thirdPerson#rightHandNodescenegraph node of the right hand
player.character.firstPerson#spinescenegraph node of the 1st person spine
player.character.firstPerson#cutFocusOffsetoffset for the focus of the chainsaw cut (in m)
player.character.firstPerson#cutFocusRotationrotation for the focus of the chainsaw cut (in deg)
player.character.firstPerson#minCutDistanceminimum distance for the chainsaw cutting (in m)
player.character.firstPerson#maxCutDistancemaximum distance for the chainsaw cutting (in m)
player.character.firstPerson#cutDetectionDistancedistance to detect a cut for the chainsaw (in m)
player.character.firstPerson#cuttingCameraNodescenegraph node for the chainsaw camera
player.character.toolNode#firstPersonTranslationtranslation of the tools node (in m)
player.character.toolNode#firstPersonRotationrotation of the tool node (in deg)
player.character.toolNode#thirdPersonTranslationtranslation of the tools node (in m)
player.character.toolNode#thirdPersonRotationrotation of the tool node (in deg)
player.ikChainssee IKUtil
player.particleSystemssee ParticleUtil
player.soundssee SoundManager
player.conditionalAnimationsee c++ interface for conditionalAnimation

Functions

calculate2DDotProductAgainstVelocity

Description
Definition
calculate2DDotProductAgainstVelocity()
Code
2688function Player:calculate2DDotProductAgainstVelocity(velocity, currentSpeed, vector)
2689 local normalizedVelX = velocity[1] / currentSpeed
2690 local normalizedVelZ = velocity[3] / currentSpeed
2691 local vectorMagnitude = math.sqrt(vector[1] * vector[1] + vector[3] * vector[3])
2692 local normalizedVectorX = vector[1] / vectorMagnitude
2693 local normalizedVectorZ = vector[3] / vectorMagnitude
2694 local dot = normalizedVelX * normalizedVectorX + normalizedVelZ * normalizedVectorZ
2695
2696 return dot
2697end

cameraBob

Description
For water
Definition
cameraBob()
Code
2514function Player:cameraBob(dt)
2515 local amplitude = 0.0
2516 local isSwimming = self.playerStateMachine:isActive("swim")
2517 local isWalking = self.playerStateMachine:isActive("walk")
2518 local isCrouching = self.playerStateMachine:isActive("crouch")
2519 local isRunning = self.playerStateMachine:isActive("run")
2520 local targetCameraOffset = 0.0
2521 local dtInSec = dt * 0.001
2522
2523 if isSwimming then
2524 amplitude = 0.045
2525 targetCameraOffset = self.baseInformation.waterCameraOffset
2526 elseif isCrouching then
2527 amplitude = 0.045
2528 elseif isWalking or isRunning then
2529 amplitude = 0.025
2530 end
2531
2532 if self.baseInformation.currentWaterCameraOffset ~= targetCameraOffset then
2533 local deltaOffset = targetCameraOffset - self.baseInformation.currentWaterCameraOffset
2534 if math.abs(deltaOffset) > 0.001 then
2535 self.baseInformation.currentWaterCameraOffset = self.baseInformation.currentWaterCameraOffset + deltaOffset * dtInSec / 0.75
2536 else
2537 self.baseInformation.currentWaterCameraOffset = self.baseInformation.currentWaterCameraOffset + deltaOffset
2538 end
2539 if math.abs(targetCameraOffset) > 0.001 then
2540 self.baseInformation.currentWaterCameraOffset = MathUtil.clamp(self.baseInformation.currentWaterCameraOffset, 0, targetCameraOffset)
2541 else
2542 self.baseInformation.currentWaterCameraOffset = math.max(self.baseInformation.currentWaterCameraOffset, 0)
2543 end
2544 end
2545
2546 local delta = 0.0
2547 if amplitude ~= 0.0 then
2548 local actualSpeed = self.motionInformation.currentCoveredGroundDistance / dtInSec
2549 local dtInSecClamped = math.min(dtInSec, 0.06)
2550 local timeOffset, amplitudeScale
2551
2552 if isSwimming then
2553 timeOffset = math.min(math.max(self.motionInformation.currentCoveredGroundDistance * 1.0, 0.6 * dtInSecClamped), 3.0 * dtInSecClamped * 1.0)
2554 amplitudeScale = math.min(math.max(actualSpeed / 3.0, 0.5), 1.0)
2555 else
2556 timeOffset = math.min(self.motionInformation.currentCoveredGroundDistance, 3.0 * dtInSecClamped) * 3.0
2557 amplitudeScale = math.min(actualSpeed / 3.0, 1.0)
2558 end
2559
2560 self.baseInformation.headBobTime = self.baseInformation.headBobTime + timeOffset
2561 amplitudeScale = (self.baseInformation.lastCameraAmplitudeScale + amplitudeScale) * 0.5
2562 delta = amplitudeScale * amplitude * math.sin(self.baseInformation.headBobTime) + self.baseInformation.currentWaterCameraOffset
2563 self.baseInformation.lastCameraAmplitudeScale = amplitudeScale
2564 else
2565 delta = self.baseInformation.currentWaterCameraOffset
2566 end
2567 local cameraY = self.camY
2568 local currentCamX, _, currentCamZ = getTranslation(self.cameraNode)
2569
2570 if not isCrouching then
2571 setTranslation(self.cameraNode, currentCamX, cameraY + delta, currentCamZ)
2572 else
2573 local crouchState = self.playerStateMachine:getState("crouch")
2574 local crouchCamY = crouchState.crouchCameraY
2575 setTranslation(self.cameraNode, currentCamX, crouchCamY + delta, currentCamZ)
2576 end
2577end

checkObjectInRange

Description
Definition
checkObjectInRange()
Code
1213function Player:checkObjectInRange()
1214 -- handle picking up of objects
1215 if self.isControlled then
1216 if self.isServer then
1217 if not self.isCarryingObject then
1218 local x,y,z = localToWorld(self.cameraNode, 0,0,1.0)
1219 local dx,dy,dz = localDirectionToWorld(self.cameraNode, 0,0,-1)
1220 self.lastFoundObject = nil
1221 self.lastFoundObjectHitPoint = nil
1222 raycastAll(x,y,z, dx,dy,dz, "pickUpObjectRaycastCallback", Player.MAX_PICKABLE_OBJECT_DISTANCE, self)
1223 self.isObjectInRange = self.lastFoundObject ~= nil
1224 else
1225 -- check if object still exists
1226 if self.pickedUpObject ~= nil then
1227 if not entityExists(self.pickedUpObject) then
1228 Player.PICKED_UP_OBJECTS[self.pickedUpObject] = false
1229 self.pickedUpObject = nil
1230 self.pickedUpObjectJointId = nil
1231 self.isCarryingObject = false
1232 end
1233 end
1234 end
1235 end
1236 end
1237end

consoleCommandReloadIKChains

Description
Reloads IK chains. Used when modifying IK chains in the player configuration file.
Definition
consoleCommandReloadIKChains(table unusedSelf)
Arguments
tableunusedSelfunused parameter
Return Values
stringthatwill be displayed on console
Code
1947function Player.consoleCommandReloadIKChains(unusedSelf)
1948 local xmlFile = loadXMLFile("TempXML", g_currentMission.player.xmlFilename)
1949
1950 local i = 0
1951 while true do
1952 local key = string.format("player.ikChains.ikChain(%d)", i)
1953 if not hasXMLProperty(xmlFile, key) then
1954 break
1955 end
1956
1957 local id = getXMLString(xmlFile, key.. "#id")
1958 local chain = g_currentMission.player.ikChains[id]
1959 if chain ~= nil then
1960 for k, node in pairs(chain.nodes) do
1961 local nodeKey = key..string.format(".node(%d)", k - 1)
1962 node.minRx = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, nodeKey .. "#minRx"), -180))
1963 node.maxRx = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, nodeKey .. "#maxRx"), 180))
1964 node.minRy = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, nodeKey .. "#minRy"), -180))
1965 node.maxRy = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, nodeKey .. "#maxRy"), 180))
1966 node.minRz = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, nodeKey .. "#minRz"), -180))
1967 node.maxRz = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, nodeKey .. "#maxRz"), 180))
1968 node.damping = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, nodeKey .. "#damping"), 0))
1969
1970 chain.ikChainSolver:setJointTransformGroup(k - 1, node.node, node.minRx, node.maxRx, node.minRy, node.maxRy, node.minRz, node.maxRz, node.damping)
1971 end
1972 end
1973 i = i + 1
1974 end
1975
1976 g_currentMission.player:setIKDirty()
1977
1978 delete(xmlFile)
1979end

consoleCommandToggleFlightAndNoHUDMode

Description
Toggle flight mode
Definition
consoleCommandToggleFlightAndNoHUDMode()
Return Values
stringthatwill be displayed on console
Code
1891function Player:consoleCommandToggleFlightAndNoHUDMode()
1892 g_flightAndNoHUDKeysEnabled = not g_flightAndNoHUDKeysEnabled
1893 if not g_flightAndNoHUDKeysEnabled then
1894 self.debugFlightMode = false -- force reset flight mode
1895 end
1896
1897 return "PlayerFlightAndNoHUDMode = " .. tostring(g_flightAndNoHUDKeysEnabled)
1898end

consoleCommandTogglePlayerDebug

Description
Toggle player debug info display
Definition
consoleCommandTogglePlayerDebug()
Return Values
stringthatwill be displayed on console
Code
2809function Player:consoleCommandTogglePlayerDebug()
2810 self.baseInformation.isInDebug = not self.baseInformation.isInDebug
2811 return "Player Debug = " .. tostring(self.baseInformation.isInDebug)
2812end

consoleCommandToggleSuperStrongMode

Description
Toggle super-strength mode
Definition
consoleCommandToggleSuperStrongMode()
Code
1911function Player:consoleCommandToggleSuperStrongMode()
1912 if self.superStrengthEnabled then
1913 self.superStrengthEnabled = false
1914 Player.MAX_PICKABLE_OBJECT_MASS = 0.2
1915 return "Player now has normal strength"
1916 else
1917 self.superStrengthEnabled = true
1918 Player.MAX_PICKABLE_OBJECT_MASS = 25
1919 return "Player now has super-strength"
1920 end
1921end

consoleCommandToggleWoodCuttingMaker

Description
Toggle wood cutting marker
Definition
consoleCommandToggleWoodCuttingMaker(table unusedSelf)
Arguments
tableunusedSelfunused parameter
Return Values
stringthatwill be displayed on console
Code
1904function Player.consoleCommandToggleWoodCuttingMaker(unusedSelf)
1905 g_woodCuttingMarkerEnabled = not g_woodCuttingMarkerEnabled
1906 return "WoodCuttingMarker = " .. tostring(g_woodCuttingMarkerEnabled)
1907end

debugDraw

Description
Prints player debug information regarding motion and input.
Definition
debugDraw()
Code
2598function Player:debugDraw()
2599 if (self.baseInformation.isInDebug) then
2600 setTextColor(1, 0, 0, 1)
2601 local line = 0.96
2602 renderText(0.05, line, 0.02, "[motion]") line = line - 0.02
2603 renderText(0.05, line, 0.02, string.format("isOnGround(%s) ", tostring(self.baseInformation.isOnGround))) line = line - 0.02
2604 renderText(0.05, line, 0.02, string.format("lastPosition(%3.4f, %3.4f)", self.baseInformation.lastPositionX, self.baseInformation.lastPositionZ)) line = line - 0.02
2605 renderText(0.05, line, 0.02, string.format("distanceCovered(%.2f)", self.motionInformation.coveredGroundDistance)) line = line - 0.02
2606 renderText(0.05, line, 0.02, string.format("inWater(%s)", tostring(self.baseInformation.isInWater))) line = line - 0.02
2607 renderText(0.05, line, 0.02, string.format("currentSpeed(%.3f) speedY(%.3f)", self.motionInformation.currentSpeed, self.motionInformation.currentSpeedY)) line = line - 0.02
2608
2609 setTextColor(0, 1, 0, 1)
2610 line = line - 0.02
2611 renderText(0.05, line, 0.02, "[input]")line = line - 0.02
2612 renderText(0.05, line, 0.02, string.format("right(%3.4f)", self.inputInformation.moveRight))
2613 line = line - 0.02
2614 renderText(0.05, line, 0.02, string.format("forward(%3.4f)", self.inputInformation.moveForward))
2615 line = line - 0.02
2616 renderText(0.05, line, 0.02, string.format("pitch(%3.4f)", self.inputInformation.pitchCamera))
2617 line = line - 0.02
2618 renderText(0.05, line, 0.02, string.format("yaw(%3.4f)", self.inputInformation.yawCamera))
2619 line = line - 0.02
2620 renderText(0.05, line, 0.02, string.format("runAxis(%3.4f)", self.inputInformation.runAxis))
2621 line = line - 0.02
2622 renderText(0.05, line, 0.02, string.format("crouchState(%s)", tostring(self.inputInformation.crouchState)))
2623 line = line - 0.02
2624 renderText(0.05, line, 0.02, string.format("interactState(%s)", tostring(self.inputInformation.interactState)))
2625 line = line - 0.02
2626 end
2627end

delete

Description
Delete
Definition
delete()
Code
689function Player:delete()
690 if self.isOwner then -- only remove action events if this Player instance was controller by the current user
691 g_messageCenter:unsubscribeAll(self)
692 self:removeActionEvents()
693 end
694
695 if self.isCarryingObject then
696 if g_server ~= nil then
697 self:pickUpObject(false)
698 end
699 end
700
701 if self.pickedUpObjectOverlay ~= nil then
702 self.pickedUpObjectOverlay:delete()
703 end
704
705 if self:hasHandtoolEquipped() then
706 self.baseInformation.currentHandtool:onDeactivate()
707 self.baseInformation.currentHandtool:delete()
708 self.baseInformation.currentHandtool = nil
709 end
710 -- @note: chainsaw stop sounds needs to be deleted afterwards
711 for _, sample in pairs(self.soundInformation.samples) do
712 g_soundManager:deleteSample(sample)
713 end
714 g_soundManager:deleteSamples(self.soundInformation.surfaceSounds)
715
716 if self.animationInformation.player ~= 0 then
717 delete(self.animationInformation.player)
718 self.animationInformation.player = 0
719 end
720 Player.deleteVisuals(self, self.ikChains)
721 removeCCT(self.controllerIndex)
722 delete(self.rootNode)
723 self.playerStateMachine:delete()
724 self:deleteStartleAnimalData()
725 self.lightNode = nil
726 if self.foliageBendingId ~= nil then
727 g_currentMission.foliageBendingSystem:destroyObject(self.foliageBendingId)
728 self.foliageBendingId = nil
729 end
730
731 if self.isOwner then
732 removeConsoleCommand("gsToggleFlightAndNoHUDMode")
733 removeConsoleCommand("gsToggleWoodCuttingMaker")
734 removeConsoleCommand("gsTogglePlayerDebug")
735 removeConsoleCommand("gsReloadIKChains")
736 removeConsoleCommand("gsToggleSuperStrength")
737 end
738
739 Player:superClass().delete(self)
740end

deleteHandToolStopSample

Description
Definition
deleteHandToolStopSample()
Code
2271function Player:deleteHandToolStopSample()
2272 if self.soundInformation.samples.handtoolStop.soundSample ~= nil then
2273 g_soundManager:deleteSample(self.soundInformation.samples.handtoolStop)
2274 self.soundInformation.samples.handtoolStop = {}
2275 self.soundInformation.deleteHandtoolStopSampleAfterPlay = false
2276 end
2277end

deleteStartleAnimalData

Description
Remove animal sound timer and sound itself (deprecated?)
Definition
deleteStartleAnimalData()
Code
1925function Player:deleteStartleAnimalData()
1926 if (self.startleAnimalSoundTimerId) then
1927 removeTimer(self.startleAnimalSoundTimerId)
1928 self.startleAnimalSoundTimerId = nil
1929 end
1930 self:deleteStartleAnimalSound()
1931end

deleteStartleAnimalSound

Description
Remove animal sound(deprecated?)
Definition
deleteStartleAnimalSound()
Code
1935function Player:deleteStartleAnimalSound()
1936 if (self.startleAnimalSoundNode) then
1937 delete(self.startleAnimalSoundNode)
1938 self.startleAnimalSoundNode = nil
1939 end
1940 self.startleAnimalSoundTimerId = nil
1941end

deleteVisuals

Description
Delete visual information for the player
Definition
deleteVisuals(table self, table ikChains)
Arguments
tableselfplayer object for unloading the visuals
tableikChainslist of IK chains
Code
636function Player.deleteVisuals(self, ikChains)
637 if self.filename ~= nil then
638 ---
639 -- fix for: WARNING: COLLISION MESH FOR 'kinematicHelper' IS BEING COOKED AT RUNTIME - THIS WILL NOT WORK ON CONSOLES
640 -- local isPlayer = string.match(self.xmlFilename, "player")
641 -- g_i3DManager:releaseSharedI3DFile(self.filename, nil, isPlayer)
642 --
643 g_i3DManager:releaseSharedI3DFile(self.filename, nil, false)
644 self.filename = nil
645 end
646 for chainId, _ in pairs(ikChains) do
647 IKUtil.deleteIKChain(ikChains, chainId)
648 end
649
650 if self.particleSystemsInformation ~= nil then
651 if self.particleSystemsInformation.swimNode ~= nil then
652 delete(self.particleSystemsInformation.swimNode)
653 end
654 if self.particleSystemsInformation.plungeNode ~= nil then
655 delete(self.particleSystemsInformation.plungeNode)
656 end
657
658 ParticleUtil.deleteParticleSystem(self.particleSystemsInformation.systems.swim)
659 ParticleUtil.deleteParticleSystem(self.particleSystemsInformation.systems.plunge)
660 end
661
662 self.visualInformation:unlinkProtectiveWear()
663
664 if self.thirdPersonSpineNode ~= nil then
665 delete(self.thirdPersonSpineNode)
666 self.thirdPersonSpineNode = nil
667 end
668 if self.skeletonThirdPerson ~= nil then
669 delete(self.skeletonThirdPerson)
670 self.skeletonThirdPerson = nil
671 end
672 if self.meshThirdPerson ~= nil then
673 delete(self.meshThirdPerson)
674 self.meshThirdPerson = nil
675 end
676 if self.graphicsRootNode ~= nil then
677 delete(self.graphicsRootNode)
678 self.graphicsRootNode = nil
679 end
680end

draw

Description
Draws overlay information
Definition
draw()
Code
1690function Player:draw()
1691 if self:getIsInputAllowed() then
1692 if self:hasHandtoolEquipped() then
1693 self.baseInformation.currentHandtool:draw()
1694 elseif not self.isCarryingObject and self.isObjectInRange and not self:hasHandtoolEquipped() then
1695 if not g_flightAndNoHUDKeysEnabled and self.pickedUpObjectOverlay ~= nil then
1696 self.pickedUpObjectOverlay:setDimension(self.pickedUpObjectWidth, self.pickedUpObjectHeight)
1697 self.pickedUpObjectOverlay:setUVs(self.pickedUpObjectHandUVs)
1698 self.pickedUpObjectOverlay:render()
1699 end
1700 elseif not g_flightAndNoHUDKeysEnabled and self.pickedUpObjectOverlay ~= nil then
1701 self.pickedUpObjectOverlay:setDimension(self.pickedUpObjectAimingWidth, self.pickedUpObjectAimingHeight)
1702 self.pickedUpObjectOverlay:setUVs(self.pickedUpObjectAimingUVs)
1703 self.pickedUpObjectOverlay:render()
1704 end
1705 end
1706end

drawUIInfo

Description
Renders UI information for the player
Definition
drawUIInfo()
Code
1671function Player:drawUIInfo()
1672 if self.isClient and self.isControlled and not self.isEntered then
1673 if not g_gui:getIsGuiVisible() and not g_flightAndNoHUDKeysEnabled then
1674 local x, y, z = getTranslation(self.graphicsRootNode)
1675 local x1, y1, z1 = getWorldTranslation(getCamera())
1676 local diffX = x - x1
1677 local diffY = y - y1
1678 local diffZ = z - z1
1679 local dist = MathUtil.vector3LengthSq(diffX, diffY, diffZ)
1680 if dist <= 100 * 100 then
1681 y = y + self.baseInformation.tagOffset[2]
1682 Utils.renderTextAtWorldPosition(x, y, z, self.visualInformation.playerName, getCorrectTextSize(0.02), 0)
1683 end
1684 end
1685 end
1686end

equipHandtool

Description
Definition
equipHandtool()
Code
2200function Player:equipHandtool(handtoolFilename, force, noEventSend)
2201 if self.isOwner then -- make sure we only change depth of field for locally controlled player instances
2202 if handtoolFilename == nil or handtoolFilename == "" then
2203 g_depthOfFieldManager:reset()
2204 else
2205 g_depthOfFieldManager:setManipulatedParams(0.8, 0.6, nil, nil, nil)
2206 end
2207 end
2208
2209 PlayerSetHandToolEvent.sendEvent(self, handtoolFilename, force, noEventSend)
2210
2211 if self:hasHandtoolEquipped() then
2212 if self.baseInformation.currentHandtool.configFileName:lower() ~= handtoolFilename:lower() or handtoolFilename == "" or force then
2213 self.baseInformation.currentHandtool:onDeactivate()
2214 self.baseInformation.currentHandtool:delete()
2215 self.baseInformation.currentHandtool = nil
2216 end
2217 if handtoolFilename ~= "" then
2218 self.baseInformation.currentHandtool = self:loadHandTool(handtoolFilename)
2219 end
2220 else
2221 if handtoolFilename ~= "" then
2222 self.baseInformation.currentHandtool = self:loadHandTool(handtoolFilename)
2223 end
2224 end
2225 -- if we have loaded a handtool, then we configure it
2226 if self:hasHandtoolEquipped() then
2227 self.baseInformation.currentHandtool:onActivate(self:getIsInputAllowed())
2228 self.baseInformation.currentHandtool:setHandNode(self.rightArmToolNode)
2229
2230 local ikTargets = self.baseInformation.currentHandtool.targets
2231 if ikTargets ~= nil then
2232 for ikChainId, target in pairs(ikTargets) do
2233 IKUtil.setTarget(self.ikChains, ikChainId, target)
2234 end
2235 self:setIKDirty()
2236 end
2237 end
2238end

getDesiredSpeed

Description
Definition
getDesiredSpeed()
Code
2631function Player:getDesiredSpeed()
2632 local inputRight = self.inputInformation.moveRight
2633 local inputForward = self.inputInformation.moveForward
2634
2635 if ((inputForward ~= 0.0) or (inputRight ~= 0.0)) then
2636 local isSwimming = self.playerStateMachine:isActive("swim")
2637 local isCrouching = self.playerStateMachine:isActive("crouch")
2638 local isFalling = self.playerStateMachine:isActive("fall")
2639 local isUsingHandtool = self:hasHandtoolEquipped()
2640 local baseSpeed = self.motionInformation.maxWalkingSpeed
2641 local runningSpeed = 0
2642 if isFalling then
2643 baseSpeed = self.motionInformation.maxFallingSpeed
2644 elseif isSwimming then
2645 baseSpeed = self.motionInformation.maxSwimmingSpeed
2646 elseif isCrouching then
2647 baseSpeed = self.motionInformation.maxCrouchingSpeed
2648 end
2649
2650 local magnitude = math.sqrt(inputRight * inputRight + inputForward * inputForward)
2651 local desiredSpeed = MathUtil.clamp(magnitude, 0.0, 1.0) * baseSpeed
2652 local inputRun = self.inputInformation.runAxis
2653
2654 if (inputRun > 0.0) and not (isSwimming or isCrouching or isUsingHandtool) then -- check if we are running
2655 runningSpeed = self.motionInformation.maxRunningSpeed
2656
2657 if g_addTestCommands and not g_isPresentationVersion then
2658 runningSpeed = self.motionInformation.maxPresentationRunningSpeed
2659 elseif g_addCheatCommands and not g_isPresentationVersion and (g_currentMission.isMasterUser or g_currentMission:getIsServer()) then
2660 runningSpeed = self.motionInformation.maxCheatRunningSpeed
2661 end
2662 desiredSpeed = math.max(desiredSpeed + (runningSpeed - desiredSpeed) * MathUtil.clamp(inputRun, 0.0, 1.0), desiredSpeed)
2663 end
2664 return desiredSpeed
2665 end
2666 return 0.0
2667end

getEquippedHandtoolFilename

Description
Get the configuration filename of a currently equipped hand tool.
Definition
getEquippedHandtoolFilename()
Return Values
stringFilenameof currently equipped hand tool or empty string if no hand tool is equipped
Code
2255function Player:getEquippedHandtoolFilename()
2256 return self.baseInformation.currentHandtool ~= nil and self.baseInformation.currentHandtool.configFileName or ""
2257end

getIsInputAllowed

Description
A function to check if input is allowed. Player is entered and is a client as well as the gui is visible.
Definition
getIsInputAllowed()
Return Values
booltrueif input is allowed.
Code
1053function Player:getIsInputAllowed()
1054 return self.isEntered and self.isClient and not g_gui:getIsGuiVisible()
1055end

getParentComponent

Description
Gets the parent node
Definition
getParentComponent(table node)
Arguments
tablenodethis parameter is unused in this function
Return Values
tablereturnsthe graphics root node
Code
628function Player:getParentComponent(node)
629 return self.graphicsRootNode
630end

getPositionData

Description
Let position information of the root node of the player
Definition
getPositionData()
Return Values
floatposXx position of player
floatposYy position of player
floatposZz position of player
floatgraphicsRotYrotation of the player
Code
1549function Player:getPositionData()
1550 local posX, posY, posZ = getTranslation(self.rootNode)
1551 if self.isClient and self.isControlled and self.isEntered then
1552 return posX, posY, posZ, self.rotY
1553 else
1554 return posX, posY, posZ, self.graphicsRotY
1555 end
1556end

getUpdatePriority

Description
Calculate a priority value from the position of the root node and the clpi distance
Definition
getUpdatePriority(float skipCount, float x, float y, float z, float coeff, table connection)
Arguments
floatskipCount
floatxworld x position
floatyworld y position
floatzworld z position
floatcoeffparameter is unused
tableconnectionstructure containing connection information
Return Values
floatreturnscalculated priority
Code
1878function Player:getUpdatePriority(skipCount, x, y, z, coeff, connection)
1879 if self.owner == connection then
1880 return 50
1881 end
1882 local x1, y1, z1 = getTranslation(self.rootNode)
1883 local dist = MathUtil.vector3Length(x1 - x, y1 - y, z1 - z)
1884 local clipDist = self.clipDistance
1885 return (1 - dist / clipDist) * 0.8 + 0.5 * skipCount * 0.2
1886end

groundRaycastCallback

Description
Callback used to get object below player
Definition
groundRaycastCallback(integer hitObjectId, float x, float y, float z, float distance)
Arguments
integerhitObjectIdscenegraph object id
floatxworld x hit position
floatyworld y hit position
floatzworld z hit position
floatdistancedistance at which the cast hit the object
Return Values
boolreturnstrue object that was hit is valid
Code
1989function Player:groundRaycastCallback(hitObjectId, x, y, z, distance)
1990 self.belowPlayerObject = hitObjectId
1991 return false
1992end

hasHandtoolEquipped

Description
Definition
hasHandtoolEquipped()
Code
2248function Player:hasHandtoolEquipped()
2249 return self.baseInformation.currentHandtool ~= nil
2250end

load

Description
Loading player information
Definition
load(string xmlFilename, string controllerName, integer playerColorIndex, table creatorConnection, bool isOwner)
Arguments
stringxmlFilenameXML filename containing player information
stringcontrollerNamename of the player controlling
integerplayerColorIndexcolor index of the table g_playerColors[]
tablecreatorConnection
boolisOwnertrue is current player is owner
Code
580function Player:load(xmlFilename, playerStyle, creatorConnection, isOwner)
581 self.networkInformation.creatorConnection = creatorConnection
582 self.isOwner = isOwner
583 self.rootNode = createTransformGroup("PlayerCCT")
584 link(getRootNode(), self.rootNode)
585
586 self.ikChains = {}
587 Player.loadVisuals(self, xmlFilename, playerStyle, nil, true, self.ikChains, self.getParentComponent, self, nil)
588
589 self.playerStateMachine:load()
590
591 self.isObjectInRange = false
592 self.isCarryingObject = false
593 self.pickedUpObject = nil
594
595 local uiScale = g_gameSettings:getValue("uiScale")
596
597 -- TODO: move to HUD
598 self.pickedUpObjectWidth, self.pickedUpObjectHeight = getNormalizedScreenValues(80 * uiScale, 80 * uiScale)
599 self.pickedUpObjectOverlay = Overlay:new(g_baseHUDFilename, 0.5, 0.5, self.pickedUpObjectWidth, self.pickedUpObjectHeight)
600 self.pickedUpObjectOverlay:setAlignment(Overlay.ALIGN_VERTICAL_MIDDLE, Overlay.ALIGN_HORIZONTAL_CENTER)
601 self.pickedUpObjectHandUVs = getNormalizedUVs{0, 138, 80, 80}
602 self.pickedUpObjectAimingUVs = getNormalizedUVs{0, 48, 48, 48}
603 self.pickedUpObjectAimingWidth, self.pickedUpObjectAimingHeight = getNormalizedScreenValues(20 * uiScale, 20 * uiScale)
604 self.pickedUpObjectOverlay:setUVs(self.pickedUpObjectAimingUVs)
605 self.pickedUpObjectOverlay:setColor(1, 1, 1, 0.3)
606
607 self:moveToAbsoluteInternal(0, -200, 0)
608
609 self.controllerIndex = createCCT(self.rootNode, self.baseInformation.capsuleRadius, self.baseInformation.capsuleHeight, 0.6, 45.0, 0.1, Player.kinematicCollisionMask, self.motionInformation.mass)
610
611 self.lockedInput = false
612
613 if self.isOwner then
614 addConsoleCommand("gsToggleFlightAndNoHUDMode", "Enables/disables the flight (J) and no HUD (O) toggle keys", "consoleCommandToggleFlightAndNoHUDMode", self)
615 addConsoleCommand("gsToggleWoodCuttingMaker", "Enables/disables chainsaw woodcutting marker", "Player.consoleCommandToggleWoodCuttingMaker", nil)
616 addConsoleCommand("gsTogglePlayerDebug", "Enables/disables player debug information", "consoleCommandTogglePlayerDebug", self)
617 if g_addTestCommands then
618 addConsoleCommand("gsReloadIKChains", "Reloads IKChains", "Player.consoleCommandReloadIKChains", nil)
619 addConsoleCommand("gsToggleSuperStrength", "Enables/disables player super strength", "consoleCommandToggleSuperStrongMode", self)
620 end
621 end
622end

loadHandTool

Description
Loading hand tools for the player
Definition
loadHandTool(string xmlFilename)
Arguments
stringxmlFilenameXML filename
Return Values
tablereturnsthe handtool
Code
2158function Player:loadHandTool(xmlFilename)
2159 if GS_IS_CONSOLE_VERSION and not fileExists(xmlFilename) then
2160 return nil
2161 end
2162 local dataStoreItem = g_storeManager:getItemByXMLFilename(xmlFilename)
2163 if dataStoreItem ~= nil then
2164 local storeItemXmlFilename = dataStoreItem.xmlFilename
2165 local xmlFile = loadXMLFile("TempXML", storeItemXmlFilename)
2166 local handToolType = getXMLString(xmlFile, "handTool.handToolType")
2167 delete(xmlFile)
2168
2169 if handToolType ~= nil then
2170 local classObject = HandTool.handToolTypes[handToolType]
2171 if classObject == nil then
2172 local modName, _ = Utils.getModNameAndBaseDirectory(storeItemXmlFilename)
2173 if modName ~= nil then
2174 handToolType = modName.."."..handToolType
2175 classObject = HandTool.handToolTypes[handToolType]
2176 end
2177 end
2178 local handTool = nil
2179 if classObject ~= nil then
2180 handTool = classObject:new(self.isServer, self.isClient)
2181 else
2182 g_logManager:devError("Error: Invalid handtool type '%s'", handToolType)
2183 end
2184 if handTool ~= nil then
2185 if not handTool:load(storeItemXmlFilename, self) then
2186 g_logManager:devError("Error: Failed to load handtool '%s'", storeItemXmlFilename)
2187 handTool:delete()
2188 handTool = nil
2189 end
2190 end
2191
2192 return handTool
2193 end
2194 end
2195 return nil
2196end

loadHandToolStopSample

Description
Definition
loadHandToolStopSample()
Code
2261function Player:loadHandToolStopSample(xmlFile, xmlPath, xmlNode)
2262 if self.soundInformation.samples.handtoolStop.soundSample ~= nil then
2263 self:deleteHandToolStopSample()
2264 end
2265 local sample = g_soundManager:loadSampleFromXML(xmlFile, xmlPath, xmlNode, self.baseDirectory, self.rightArmToolNode, 1, AudioGroup.VEHICLE, nil, nil)
2266 self.soundInformation.samples.handtoolStop = sample
2267end

loadVisuals

Description
Loading visuals for the player
Definition
loadVisuals(table self, string xmlFilename, table playerStyle, table linkNode, bool isRealPlayer, table ikChains, function getParentFunc, function getParentFuncTarget, table parentObj)
Arguments
tableselfplayer object for loading the visuals
stringxmlFilenameXML filename
tableplayerStyle
tablelinkNodenode to link the third person skeleton of the player on
boolisRealPlayerfalse if player is in a vehicle
tableikChainslist of IK chains
functiongetParentFunc
functiongetParentFuncTarget
tableparentObjparent object
Return Values
booltrueif ok
Code
291function Player.loadVisuals(self, xmlFilename, playerStyle, linkNode, isRealPlayer, ikChains, getParentFunc, getParentFuncTarget, parentObj)
292 self.xmlFilename = xmlFilename
293 self.customEnvironment, self.baseDirectory = Utils.getModNameAndBaseDirectory(xmlFilename)
294 local xmlFile = loadXMLFile("TempXML", xmlFilename)
295 if xmlFile == 0 then
296 return false
297 end
298
299 local filename = getXMLString(xmlFile, "player.filename")
300 self.filename = Utils.getFilename(filename, self.baseDirectory)
301 local rootNode = g_i3DManager:loadSharedI3DFile(self.filename, nil, nil, true)
302
303 self.graphicsRootNode = createTransformGroup("player_graphicsRootNode")
304
305 if isRealPlayer then
306 self.cameraNode = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "player.camera#index"))
307 if self.cameraNode == nil then
308 g_logManager:devError("Error: Failed to find player camera in '%s'", self.filename)
309 end
310 self.camX, self.camY, self.camZ = getTranslation(self.cameraNode)
311 setNearClip(self.cameraNode, 0.15) -- lessens night light windows flickering (standard value: 0.1)
312 setFarClip(self.cameraNode, 6000) -- prevents distance mountains from clipping (standard value: 5000)
313 self.fovY = calculateFovY(self.cameraNode)
314 setFovY(self.cameraNode, self.fovY)
315
316 self.animRootThirdPerson = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "player.character.thirdPerson#animRootNode"))
317 if self.animRootThirdPerson == nil then
318 g_logManager:devError("Error: Failed to find animation root node in '%s'", self.filename)
319 end
320
321 -- Capsule information
322 self.baseInformation.capsuleHeight = getXMLFloat(xmlFile, "player.character#physicsCapsuleHeight")
323 self.baseInformation.capsuleRadius = getXMLFloat(xmlFile, "player.character#physicsCapsuleRadius")
324 self.baseInformation.capsuleTotalHeight = self.baseInformation.capsuleHeight + 2.0 * self.baseInformation.capsuleRadius
325
326 -- first person view
327 self.cuttingCameraNode = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "player.character.firstPerson#cuttingCameraNode"))
328 setNearClip(self.cuttingCameraNode, 0.15)
329 setFarClip(self.cuttingCameraNode, 6000)
330 self.fovY = calculateFovY(self.cuttingCameraNode)
331 setFovY(self.cuttingCameraNode, self.fovY)
332 end
333
334 -- Avator customization
335 self.visualInformation = PlayerStyle:new()
336 self.visualInformation:copySelection(playerStyle)
337 self.visualInformation:loadXML(self, rootNode, xmlFile, "player.character")
338
339 self.skeletonThirdPerson = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "player.character.thirdPerson#skeleton"))
340
341 if self.skeletonThirdPerson == nil then
342 g_logManager:devError("Error: Failed to find skeleton root node in '%s'", self.filename)
343 end
344
345 self.meshThirdPerson = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "player.character.thirdPerson#mesh"))
346
347 if self.meshThirdPerson == nil then
348 g_logManager:devError("Error: Failed to find player mesh in '%s'", self.filename)
349 end
350
351 if self.meshThirdPerson ~= nil then
352 setVisibility(self.meshThirdPerson, false)
353 setClipDistance(self.meshThirdPerson, 200)
354 end
355
356 self.thirdPersonSpineNode = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "player.character.thirdPerson#spine"))
357 self.thirdPersonSuspensionNode = Utils.getNoNil(I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "player.character.thirdPerson#suspension")), self.thirdPersonSpineNode)
358 self.thirdPersonRightHandNode = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "player.character.thirdPerson#rightHandNode"))
359 self.thirdPersonLeftHandNode = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "player.character.thirdPerson#leftHandNode"))
360 self.thirdPersonHeadNode = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "player.character.thirdPerson#headNode"))
361
362 self.lightNode = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "player.light#index"))
363 if self.lightNode ~= nil then
364 setVisibility(self.lightNode, false)
365 end
366
367 self.pickUpKinematicHelperNode = I3DUtil.indexToObject(rootNode, getXMLString(xmlFile, "player.pickUpKinematicHelper#index"))
368 if self.pickUpKinematicHelperNode ~= nil then
369 self.pickUpKinematicHelperNodeChild = createTransformGroup("pickUpKinematicHelperNodeChild")
370 link(self.pickUpKinematicHelperNode, self.pickUpKinematicHelperNodeChild)
371 end
372
373 -- IK Chains
374 local i = 0
375 while true do
376 local key = string.format("player.ikChains.ikChain(%d)", i)
377 if not hasXMLProperty(xmlFile, key) then
378 break
379 end
380 IKUtil.loadIKChain(xmlFile, key, rootNode, rootNode, ikChains)
381 i = i + 1
382 end
383 IKUtil.setIKChainInactive(ikChains, "spine")
384 if isRealPlayer then
385 IKUtil.deleteIKChain(ikChains, "rightFoot")
386 IKUtil.deleteIKChain(ikChains, "leftFoot")
387 IKUtil.deleteIKChain(ikChains, "rightArm")
388 IKUtil.deleteIKChain(ikChains, "leftArm")
389 IKUtil.deleteIKChain(ikChains, "spine")
390 end
391
392 -- Linking: Do not use indexToObject below
393 if self.meshThirdPerson ~= nil then
394 link(getRootNode(), self.meshThirdPerson)
395 end
396 if isRealPlayer then
397 self.chainsawCameraFocus = createTransformGroup("player_chainsawCameraFocus")
398 self.chainsawSplitShapeFocus = createTransformGroup("player_chainsawSplitShapeFocus")
399 link(self.cameraNode, self.chainsawCameraFocus)
400 link(self.chainsawCameraFocus, self.chainsawSplitShapeFocus)
401
402 local cutFocusOffset = StringUtil.getVectorNFromString(Utils.getNoNil(getXMLString(xmlFile, "player.character.firstPerson#cutFocusOffset"), "0 0 -1"), 3)
403 setTranslation(self.chainsawSplitShapeFocus, unpack(cutFocusOffset))
404 local cutFocusRotation = StringUtil.getVectorNFromString(Utils.getNoNil(getXMLString(xmlFile, "player.character.firstPerson#cutFocusRotation"), "0 0 0"), 3)
405 local rotX2, rotY2, rotZ2 = unpack(cutFocusRotation)
406 setRotation(self.chainsawSplitShapeFocus, math.rad(rotX2), math.rad(rotY2), math.rad(rotZ2))
407 self.minCutDistance = Utils.getNoNil(getXMLFloat(xmlFile, "player.character.firstPerson#minCutDistance"), 0.5)
408 self.maxCutDistance = Utils.getNoNil(getXMLFloat(xmlFile, "player.character.firstPerson#maxCutDistance"), 1.0)
409 self.cutDetectionDistance = Utils.getNoNil(getXMLFloat(xmlFile, "player.character.firstPerson#cutDetectionDistance"), 10.0)
410 end
411
412 if isRealPlayer then
413 self.skeletonRootNode = createTransformGroup("player_skeletonRootNode")
414 self.foliageBendingNode = createTransformGroup("player_foliageBendingNode")
415
416 link(getRootNode(), self.graphicsRootNode)
417 link(self.graphicsRootNode, self.cameraNode)
418 link(self.graphicsRootNode, self.skeletonRootNode)
419 link(self.graphicsRootNode, self.foliageBendingNode)
420
421 if self.animRootThirdPerson ~= nil then
422 link(self.skeletonRootNode, self.animRootThirdPerson)
423 if self.skeletonThirdPerson ~= nil then
424 link(self.animRootThirdPerson, self.skeletonThirdPerson)
425 end
426 end
427
428 self.visualInformation:linkProtectiveWear(self.skeletonRootNode)
429
430 if self.skeletonThirdPerson ~= nil and getNumOfChildren(self.skeletonThirdPerson) > 0 then
431 local animNode = g_animCache:getNode(AnimationCache.CHARACTER)
432 cloneAnimCharacterSet(animNode, getParent(self.skeletonThirdPerson))
433 local animCharsetId = getAnimCharacterSet(getChildAt(self.skeletonThirdPerson, 0))
434 self.animationInformation.player = createConditionalAnimation()
435
436 for key, parameter in pairs(self.animationInformation.parameters) do
437 conditionalAnimationRegisterParameter(self.animationInformation.player, parameter.id, parameter.type, key)
438 end
439 initConditionalAnimation(self.animationInformation.player, animCharsetId, self.xmlFilename, "player.conditionalAnimation")
440 setConditionalAnimationSpecificParameterIds(self.animationInformation.player, self.animationInformation.parameters.absForwardVelocity.id, self.animationInformation.parameters.yawVelocity.id)
441 end
442
443 self.leftArmToolNode = createTransformGroup("leftArmToolNode")
444 self.rightArmToolNode = createTransformGroup("rightArmToolNode")
445
446 if self.isOwner then
447 local toolRotation = StringUtil.getVectorNFromString(Utils.getNoNil(getXMLString(xmlFile, "player.character.toolNode#firstPersonRotation"), "0 0 0"), 3)
448 local rotX, rotY, rotZ = unpack(toolRotation)
449 setRotation(self.rightArmToolNode, math.rad(rotX), math.rad(rotY), math.rad(rotZ))
450 local toolTranslate = StringUtil.getVectorNFromString(Utils.getNoNil(getXMLString(xmlFile, "player.character.toolNode#firstPersonTranslation"), "0 0 0"), 3)
451 local transX, transY, transZ = unpack(toolTranslate)
452 setTranslation(self.rightArmToolNode, transX, transY, transZ)
453 link(self.cuttingCameraNode, self.rightArmToolNode)
454 else
455 -- right
456 local toolRotationR = StringUtil.getVectorNFromString(Utils.getNoNil(getXMLString(xmlFile, "player.character.toolNode#thirdPersonRightNodeRotation"), "0 0 0"), 3)
457 local rotRX, rotRY, rotRZ = unpack(toolRotationR)
458 setRotation(self.rightArmToolNode, math.rad(rotRX), math.rad(rotRY), math.rad(rotRZ))
459 local toolTranslateR = StringUtil.getVectorNFromString(Utils.getNoNil(getXMLString(xmlFile, "player.character.toolNode#thirdPersonRightNodeTranslation"), "0 0 0"), 3)
460 local transRX, transRY, transRZ = unpack(toolTranslateR)
461 setTranslation(self.rightArmToolNode, transRX, transRY, transRZ)
462 link(self.thirdPersonRightHandNode, self.rightArmToolNode)
463 -- left
464 local toolRotationL = StringUtil.getVectorNFromString(Utils.getNoNil(getXMLString(xmlFile, "player.character.toolNode#thirdPersonLeftNodeRotation"), "0 0 0"), 3)
465 local rotLX, rotLY, rotLZ = unpack(toolRotationL)
466 setRotation(self.leftArmToolNode, math.rad(rotLX), math.rad(rotLY), math.rad(rotLZ))
467 local toolTranslateL = StringUtil.getVectorNFromString(Utils.getNoNil(getXMLString(xmlFile, "player.character.toolNode#thirdPersonLeftNodeTranslation"), "0 0 0"), 3)
468 local transLX, transLY, transLZ = unpack(toolTranslateL)
469 setTranslation(self.leftArmToolNode, transLX, transLY, transLZ)
470 link(self.thirdPersonLeftHandNode, self.leftArmToolNode)
471 -- light
472 link(self.thirdPersonHeadNode, self.lightNode)
473 local lightRotation = StringUtil.getVectorNFromString(Utils.getNoNil(getXMLString(xmlFile, "player.light#thirdPersonRotation"), "0 0 0"), 3)
474 local lightRotX, lightRotY, lightRotZ = unpack(lightRotation)
475 local lightTranslate = StringUtil.getVectorNFromString(Utils.getNoNil(getXMLString(xmlFile, "player.light#thirdPersonTranslation"), "0 0 0"), 3)
476 local lightTransX, lightTransY, lightTransZ = unpack(lightTranslate)
477 setRotation(self.lightNode, math.rad(lightRotX), math.rad(lightRotY), math.rad(lightRotZ))
478 setTranslation(self.lightNode, lightTransX, lightTransY, lightTransZ)
479 end
480
481 -- Fx
482 self.particleSystemsInformation.swimNode = createTransformGroup("swimFXNode")
483 link(getRootNode(), self.particleSystemsInformation.swimNode)
484 self.particleSystemsInformation.plungeNode = createTransformGroup("plungeFXNode")
485 link(getRootNode(), self.particleSystemsInformation.plungeNode)
486
487 ParticleUtil.loadParticleSystem(xmlFile, self.particleSystemsInformation.systems.swim, "player.particleSystems.swim", self.particleSystemsInformation.swimNode, false, nil, self.baseDirectory)
488 ParticleUtil.loadParticleSystem(xmlFile, self.particleSystemsInformation.systems.plunge, "player.particleSystems.plunge", self.particleSystemsInformation.plungeNode, false, nil, self.baseDirectory)
489 --
490 self.visualInformation:applySelection()
491 if self.isOwner then
492 self.visualInformation:setVisibility(false)
493 else
494 self.visualInformation:setVisibility(true)
495 end
496 else
497 link(linkNode, self.skeletonThirdPerson)
498 self.visualInformation:linkProtectiveWear(linkNode)
499
500 if self.pickUpKinematicHelperNode ~= nil then
501 delete(self.pickUpKinematicHelperNode)
502 self.pickUpKinematicHelperNode = nil
503 end
504 if self.lightNode ~= nil then
505 delete(self.lightNode)
506 self.lightNode = nil
507 end
508 if self.cameraNode ~= nil then
509 delete(self.cameraNode)
510 self.cameraNode = nil
511 end
512 local offset = {localToLocal(self.thirdPersonSpineNode, self.skeletonThirdPerson, 0, 0, 0)}
513
514 setTranslation(self.skeletonThirdPerson, -offset[1], -offset[2], -offset[3])
515 self.visualInformation:applySelection()
516 self.visualInformation:setVisibility(true)
517 end
518
519 -- Sound
520 if isRealPlayer then
521 self.soundInformation.surfaceSounds = {}
522 self.soundInformation.surfaceIdToSound = {}
523 self.soundInformation.surfaceNameToSound = {}
524 self.soundInformation.currentSurfaceSound = nil
525
526 if not self.isOwner then
527 for _, surfaceSound in pairs(g_currentMission.surfaceSounds) do
528 if surfaceSound.type == "footstep" and surfaceSound.sample ~= nil then
529 local sample = g_soundManager:cloneSample(surfaceSound.sample, self.rootNode, self)
530 sample.sampleName = surfaceSound.name
531
532 table.insert(self.soundInformation.surfaceSounds, sample)
533 self.soundInformation.surfaceIdToSound[surfaceSound.materialId] = sample
534 self.soundInformation.surfaceNameToSound[surfaceSound.name] = sample
535 end
536 end
537
538 self.soundInformation.samples.swim = g_soundManager:loadSampleFromXML(xmlFile, "player.sounds.water", "swim", self.baseDirectory, self.rootNode, 0, AudioGroup.ENVIRONMENT, nil, nil)
539 self.soundInformation.samples.swimIdle = g_soundManager:loadSampleFromXML(xmlFile, "player.sounds.water", "swimIdle", self.baseDirectory, self.rootNode, 0, AudioGroup.ENVIRONMENT, nil, nil)
540 self.soundInformation.samples.plunge = g_soundManager:loadSampleFromXML(xmlFile, "player.sounds.water", "plunge", self.baseDirectory, self.rootNode, 1, AudioGroup.ENVIRONMENT, nil, nil)
541 self.soundInformation.samples.flashlight = g_soundManager:loadSampleFromXML(xmlFile, "player.sounds.tools", "flashlight", self.baseDirectory, self.rootNode, 1, AudioGroup.ENVIRONMENT, nil, nil)
542 self.soundInformation.samples.horseBrush = g_soundManager:loadSampleFromXML(xmlFile, "player.sounds.tools", "horseBrush", self.baseDirectory, self.rootNode, 0, AudioGroup.ENVIRONMENT, nil, nil)
543 else
544 for _, surfaceSound in pairs(g_currentMission.surfaceSounds) do
545 if surfaceSound.type == "footstep" and surfaceSound.sample ~= nil then
546 local sample = g_soundManager:cloneSample2D(surfaceSound.sample, self)
547 sample.sampleName = surfaceSound.name
548
549 table.insert(self.soundInformation.surfaceSounds, sample)
550 self.soundInformation.surfaceIdToSound[surfaceSound.materialId] = sample
551 self.soundInformation.surfaceNameToSound[surfaceSound.name] = sample
552 end
553 end
554
555 self.soundInformation.samples.swim = g_soundManager:loadSample2DFromXML(xmlFile, "player.sounds.water", "swim", self.baseDirectory, 0, AudioGroup.ENVIRONMENT)
556 self.soundInformation.samples.swimIdle = g_soundManager:loadSample2DFromXML(xmlFile, "player.sounds.water", "swimIdle", self.baseDirectory, 0, AudioGroup.ENVIRONMENT)
557 self.soundInformation.samples.plunge = g_soundManager:loadSample2DFromXML(xmlFile, "player.sounds.water", "plunge", self.baseDirectory, 1, AudioGroup.ENVIRONMENT)
558 self.soundInformation.samples.flashlight = g_soundManager:loadSample2DFromXML(xmlFile, "player.sounds.tools", "flashlight", self.baseDirectory, 1, AudioGroup.ENVIRONMENT)
559 self.soundInformation.samples.horseBrush = g_soundManager:loadSample2DFromXML(xmlFile, "player.sounds.tools", "horseBrush", self.baseDirectory, 0, AudioGroup.ENVIRONMENT)
560 end
561
562 self.soundInformation.distancePerFootstep.crouch = Utils.getNoNil(getXMLFloat(xmlFile, "player.sounds.footsteps#distancePerFootstepCrouch"), 0.5)
563 self.soundInformation.distancePerFootstep.walk = Utils.getNoNil(getXMLFloat(xmlFile, "player.sounds.footsteps#distancePerFootstepWalk"), 0.75)
564 self.soundInformation.distancePerFootstep.run = Utils.getNoNil(getXMLFloat(xmlFile, "player.sounds.footsteps#distancePerFootstepRun"), 1.5)
565 end
566 IKUtil.updateAlignNodes(ikChains, getParentFunc, getParentFuncTarget, parentObj)
567
568 delete(xmlFile)
569 delete(rootNode)
570 return true
571end

lockInput

Description
Locks player input
Definition
lockInput(bool locked)
Arguments
boollockedif true, will lock input
Code
1571function Player:lockInput(locked)
1572 self.lockedInput = locked
1573end

mouseEvent

Description
Function called when mouse is moved (call from BaseMission).
Definition
mouseEvent(float posX, float posY, bool isDown, bool isUp, button)
Arguments
floatposXposition of the mouse
floatposYposition of the mouse
boolisDown
boolisUp
button
Code
1047function Player:mouseEvent(posX, posY, isDown, isUp, button)
1048end

movePlayer

Description
Definition
movePlayer()
Code
2491function Player:movePlayer(dt, movementX, movementY, movementZ)
2492 self.debugFlightCoolDown = self.debugFlightCoolDown - 1
2493 if self.debugFlightMode then
2494 movementY = self.inputInformation.moveUp * dt
2495 end
2496
2497 self.networkInformation.tickTranslation[1] = self.networkInformation.tickTranslation[1] + movementX
2498 self.networkInformation.tickTranslation[2] = self.networkInformation.tickTranslation[2] + movementY
2499 self.networkInformation.tickTranslation[3] = self.networkInformation.tickTranslation[3] + movementZ
2500 moveCCT(self.controllerIndex, movementX, movementY, movementZ, Player.movementCollisionMask)
2501
2502 self.networkInformation.index = self.networkInformation.index + 1
2503 if not self.isServer then
2504 -- remove old history (above 100 entries)
2505 while table.getn(self.networkInformation.history) > 100 do
2506 table.remove(self.networkInformation.history, 1)
2507 end
2508 table.insert(self.networkInformation.history, {index=self.networkInformation.index, movementX=movementX, movementY=movementY, movementZ=movementZ})
2509 end
2510end

moveRootNodeToAbsolute

Description
Moves the player to the given position, such that the root node is at x, y, z
Definition
moveRootNodeToAbsolute(float x, float y, float z)
Arguments
floatxnew x position
floatynew y position
floatznew z position
Code
1611function Player:moveRootNodeToAbsolute(x, y, z)
1612 self:moveTo(x, y, z, true, true)
1613end

moveTo

Description
Moves the player to the given position, with the given y offset to the terrain
Definition
moveTo(float x, float y, float z, bool isAbsolute)
Arguments
floatxnew x position
floatynew y position
floatznew z position
boolisAbsoluteif true, Y coordinate is in absolute, not calculated from terrain height
Code
1581function Player:moveTo(x, y, z, isAbsolute, isRootNode)
1582 self:unequipHandtool()
1583
1584 if not self.isServer and self.isOwner then
1585 g_client:getServerConnection():sendEvent(PlayerTeleportEvent:new(x, y, z, isAbsolute, isRootNode))
1586 end
1587 if not isAbsolute then
1588 local terrainHeight = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, x, 300, z)
1589 y = terrainHeight + y
1590 end
1591 if not isRootNode then
1592 y = y + self.baseInformation.capsuleTotalHeight * 0.5
1593 end
1594 self:moveToAbsoluteInternal(x, y, z)
1595end

moveToAbsolute

Description
Moves the player root node to the given position, such that the feet are at x, y, z
Definition
moveToAbsolute(float x, float y, float z)
Arguments
floatxnew x position
floatynew y position
floatznew z position
Code
1602function Player:moveToAbsolute(x, y, z)
1603 self:moveTo(x, y, z, true, false)
1604end

moveToAbsoluteInternal

Description
Move player root node and graphics node to a specific position. Updates interpolation parameters
Definition
moveToAbsoluteInternal(float x, float y, float z)
Arguments
floatxnew x position
floatynew y position
floatznew z position
Code
1653function Player:moveToAbsoluteInternal(x, y, z)
1654 setTranslation(self.rootNode, x, y, z)
1655 setTranslation(self.graphicsRootNode, x, y - self.baseInformation.capsuleTotalHeight * 0.5, z)
1656
1657 self.networkInformation.interpolationTime:reset()
1658 self.networkInformation.interpolatorPosition:setPosition(x,y,z)
1659 self.networkInformation.updateTargetTranslationPhysicsIndex = -1
1660
1661 self.lastAnimPosX = x
1662 self.lastAnimPosY = y
1663 self.lastAnimPosZ = z
1664 self.walkDistance = 0
1665
1666 self.baseInformation.lastPositionX, _, self.baseInformation.lastPositionZ = getTranslation(self.graphicsRootNode)
1667end

moveToExitPoint

Description
Moves player to vehicle exit node
Definition
moveToExitPoint(table exitVehicle)
Arguments
tableexitVehiclevehicle class that will be used to get the exit node to place the player
Code
1618function Player:moveToExitPoint(exitVehicle)
1619 local exitPoint
1620 if exitVehicle.getExitNode ~= nil then
1621 exitPoint = exitVehicle:getExitNode()
1622 end
1623 local x, y, z = getWorldTranslation(exitPoint)
1624 local terrainHeight = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, x, 300, z)
1625 y = math.max(terrainHeight + 0.1, y + 0.9)
1626 self:moveToAbsolute(x, y, z)
1627 local dx, _, dz = localDirectionToWorld(exitPoint, 0, 0, -1)
1628 self.rotY = MathUtil.getYRotationFromDirection(dx, dz)
1629
1630 --self.targetGraphicsRotY = self.rotY
1631 --self.graphicsRotY = self.rotY
1632 --(I) setRotation(self.graphicsRootNode, 0, self.graphicsRotY, 0)
1633 setRotation(self.cameraNode, self.rotX, self.rotY, 0)
1634end

new

Description
Creating player and initializing member variables
Definition
new(boolean isServer, boolean isClient)
Arguments
booleanisServeris server
booleanisClientis client
Return Values
tableinstanceInstance of object
Code
70function Player:new(isServer, isClient)
71 local self = Object:new(isServer, isClient, Player_mt)
72
73 self.isControlled = false
74 self.isOwner = false
75 self.isEntered = false
76 self.debugFlightModeWalkingSpeed = 0.016
77 self.debugFlightModeRunningFactor = 1
78
79 self.networkInformation = {}
80 self.networkInformation.creatorConnection = nil
81 self.networkInformation.history = {}
82 self.networkInformation.index = 0
83 if self.isServer then
84 self.networkInformation.sendIndex = 0
85 end
86 self.networkInformation.interpolationTime = InterpolationTime:new(1.2)
87 self.networkInformation.interpolatorPosition = InterpolatorPosition:new(0.0, 0.0, 0.0)
88 self.networkInformation.interpolatorQuaternion = InterpolatorQuaternion:new(0.0, 0.0, 0.0, 1.0) -- only used on server side for rotation of camera
89 self.networkInformation.interpolatorOnGround = InterpolatorValue:new(0.0)
90 self.networkInformation.tickTranslation = {0.0, 0.0, 0.0}
91 self.networkInformation.dirtyFlag = self:getNextDirtyFlag()
92 self.networkInformation.updateTargetTranslationPhysicsIndex = -1
93 self.networkInformation.rotateObject = false
94 self.networkInformation.rotateObjectInputV = 0.0
95 self.networkInformation.rotateObjectInputH = 0.0
96
97 self.motionInformation = {}
98 self.motionInformation.damping = 0.8
99 self.motionInformation.mass = 80.0 -- in kg
100 self.motionInformation.maxAcceleration = 50.0 -- m/s^2
101 self.motionInformation.maxDeceleration = 50.0 -- m/s^2
102 self.motionInformation.inverseMass = 1.0 / self.motionInformation.mass -- in kg ^ -1
103 self.motionInformation.gravity = -9.8
104 self.motionInformation.maxIdleSpeed = 0.1 -- in m/s
105 self.motionInformation.maxWalkingSpeed = 4.0 -- in m/s
106 self.motionInformation.maxRunningSpeed = 9.0 -- in m/s
107 self.motionInformation.maxSwimmingSpeed = 3.0 -- in m/s
108 self.motionInformation.maxCrouchingSpeed = 2.0 -- in m/s
109 self.motionInformation.maxFallingSpeed = 6.0 -- in m/s
110 self.motionInformation.maxCheatRunningSpeed = 34.0 -- in m/s
111 self.motionInformation.maxPresentationRunningSpeed = 128.0 -- in m/s
112 self.motionInformation.maxSpeedDelay = 0.1 -- in s (how long before max speed is reached)
113 self.motionInformation.brakeDelay = 0.001 -- in s (how long before velocity is null)
114 self.motionInformation.brakeForce = {0.0, 0.0, 0.0} -- in N (force to apply to stop the player gradually)
115 self.motionInformation.currentGroundSpeed = 0.0 -- in m/s
116 self.motionInformation.minimumFallingSpeed = -0.00001 -- in m/s
117 self.motionInformation.coveredGroundDistance = 0.0 -- in m
118 self.motionInformation.currentCoveredGroundDistance = 0.0
119 self.motionInformation.justMoved = false --
120 self.motionInformation.isBraking = false
121 self.motionInformation.lastSpeed = 0.0
122 self.motionInformation.currentSpeed = 0.0
123 self.motionInformation.currentSpeedY = 0.0
124 self.motionInformation.isReverse = false
125 self.motionInformation.desiredSpeed = 0.0
126 self.motionInformation.jumpHeight = 1.5 -- in m
127 self.motionInformation.currentWorldDirX = 0.0
128 self.motionInformation.currentWorldDirZ = 1.0
129 self.motionInformation.currentSpeedX = 0.0
130 self.motionInformation.currentSpeedZ = 0.0
131
132 self.baseInformation = {}
133 self.baseInformation.lastPositionX = 0.0
134 self.baseInformation.lastPositionZ = 0.0
135 self.baseInformation.isOnGround = true
136 self.baseInformation.isOnGroundPhysics = true
137 self.baseInformation.isCloseToGround = true
138 self.baseInformation.isInWater = false
139 self.baseInformation.wasInWater = false
140 self.baseInformation.waterLevel = -1.4
141 self.baseInformation.waterCameraOffset = 0.3
142 self.baseInformation.currentWaterCameraOffset = 0.0
143 self.baseInformation.plungedInWater = false
144 self.baseInformation.plungedYVelocityThreshold = -2.0
145 self.baseInformation.isInDebug = false
146 self.baseInformation.capsuleHeight = 0.0
147 self.baseInformation.capsuleRadius = 0.0
148 self.baseInformation.tagOffset = {0.0, 1.9, 0.0}
149 self.baseInformation.translationAlphaDifference = 0.0
150 self.baseInformation.animDt = 0.0
151 self.baseInformation.isCrouched = false
152 self.baseInformation.isUsingChainsawHorizontal = false
153 self.baseInformation.isUsingChainsawVertical = false
154 self.baseInformation.currentHandtool = nil
155 self.baseInformation.capsuleTotalHeight = 0.0
156 self.baseInformation.headBobTime = 0.0
157 self.baseInformation.lastCameraAmplitudeScale = 0.0
158 self.lastEstimatedForwardVelocity = 0.0
159
160 self.inputInformation = {}
161 self.inputInformation.moveForward = 0.0
162 self.inputInformation.moveRight = 0.0
163 self.inputInformation.moveUp = 0.0 -- for debug flight mode
164 self.inputInformation.pitchCamera = 0.0
165 self.inputInformation.yawCamera = 0.0
166 self.inputInformation.runAxis = 0.0
167 self.inputInformation.crouchState = Player.BUTTONSTATES.RELEASED
168 self.inputInformation.interactState = Player.BUTTONSTATES.RELEASED
169
170 -- These are the parameters for the input registration and the eventId
171 self.inputInformation.registrationList = {}
172 self.inputInformation.registrationList[InputAction.AXIS_MOVE_SIDE_PLAYER] = { eventId="", callback=self.onInputMoveSide, triggerUp=false, triggerDown=false, triggerAlways=true, activeType=Player.INPUT_ACTIVE_TYPE.IS_MOVEMENT, callbackState=nil, text="", textVisibility=false }
173 self.inputInformation.registrationList[InputAction.AXIS_MOVE_FORWARD_PLAYER] = { eventId="", callback=self.onInputMoveForward, triggerUp=false, triggerDown=false, triggerAlways=true, activeType=Player.INPUT_ACTIVE_TYPE.IS_MOVEMENT, callbackState=nil, text="", textVisibility=false }
174 self.inputInformation.registrationList[InputAction.AXIS_LOOK_LEFTRIGHT_PLAYER] = { eventId="", callback=self.onInputLookLeftRight, triggerUp=false, triggerDown=false, triggerAlways=true, activeType=Player.INPUT_ACTIVE_TYPE.IS_MOVEMENT, callbackState=nil, text="", textVisibility=false }
175 self.inputInformation.registrationList[InputAction.AXIS_LOOK_UPDOWN_PLAYER] = { eventId="", callback=self.onInputLookUpDown, triggerUp=false, triggerDown=false, triggerAlways=true, activeType=Player.INPUT_ACTIVE_TYPE.IS_MOVEMENT, callbackState=nil, text="", textVisibility=false }
176 self.inputInformation.registrationList[InputAction.AXIS_RUN] = { eventId="", callback=self.onInputRun, triggerUp=false, triggerDown=false, triggerAlways=true, activeType=Player.INPUT_ACTIVE_TYPE.IS_MOVEMENT, callbackState=nil, text="", textVisibility=false }
177 self.inputInformation.registrationList[InputAction.JUMP] = { eventId="", callback=self.onInputJump, triggerUp=false, triggerDown=true, triggerAlways=false, activeType=Player.INPUT_ACTIVE_TYPE.IS_MOVEMENT, callbackState=nil, text="", textVisibility=GS_IS_CONSOLE_VERSION }
178 -- TODO: read from game settings? also needs to be applied to PlayerStateCrouch.toggleMode. triggerAlways = not crouchToggleMode
179 self.inputInformation.registrationList[InputAction.CROUCH] = { eventId="", callback=self.onInputCrouch, triggerUp=false, triggerDown=true, triggerAlways=true, activeType=Player.INPUT_ACTIVE_TYPE.IS_MOVEMENT, callbackState=nil, text="", textVisibility=GS_IS_CONSOLE_VERSION }
180 self.inputInformation.registrationList[InputAction.ACTIVATE_OBJECT] = { eventId="", callback=self.onInputActivateObject, triggerUp=false, triggerDown=true, triggerAlways=false, activeType=Player.INPUT_ACTIVE_TYPE.IS_MOVEMENT, callbackState=nil, text="", textVisibility=true }
181 self.inputInformation.registrationList[InputAction.ROTATE_OBJECT_LEFT_RIGHT] = { eventId="", callback=self.onInputRotateObjectHorizontally, triggerUp=false, triggerDown=false, triggerAlways=true, activeType=Player.INPUT_ACTIVE_TYPE.IS_CARRYING, callbackState=nil, text=g_i18n:getText("action_rotateObjectHorizontally"), textVisibility=true }
182 self.inputInformation.registrationList[InputAction.ROTATE_OBJECT_UP_DOWN] = { eventId="", callback=self.onInputRotateObjectVertically, triggerUp=false, triggerDown=false, triggerAlways=true, activeType=Player.INPUT_ACTIVE_TYPE.IS_CARRYING, callbackState=nil, text=g_i18n:getText("action_rotateObjectVertically"), textVisibility=true }
183 self.inputInformation.registrationList[InputAction.ENTER] = { eventId="", callback=self.onInputEnter, triggerUp=false, triggerDown=true, triggerAlways=false, activeType=Player.INPUT_ACTIVE_TYPE.STARTS_ENABLED, callbackState=nil, text="", textVisibility=false }
184 self.inputInformation.registrationList[InputAction.TOGGLE_LIGHTS_FPS] = { eventId="", callback=self.onInputToggleLight, triggerUp=false, triggerDown=true, triggerAlways=false, activeType=Player.INPUT_ACTIVE_TYPE.STARTS_ENABLED, callbackState=nil, text="", textVisibility=false }
185 self.inputInformation.registrationList[InputAction.THROW_OBJECT] = { eventId="", callback=self.onInputThrowObject, triggerUp=false, triggerDown=true, triggerAlways=false, activeType=Player.INPUT_ACTIVE_TYPE.STARTS_DISABLED, callbackState=nil, text=g_i18n:getText("input_THROW_OBJECT"), textVisibility=true }
186 self.inputInformation.registrationList[InputAction.INTERACT] = { eventId="", callback=self.onInputInteract, triggerUp=true, triggerDown=true, triggerAlways=false, activeType=Player.INPUT_ACTIVE_TYPE.STARTS_DISABLED, callbackState=nil, text="", textVisibility=true }
187 self.inputInformation.registrationList[InputAction.NEXT_HANDTOOL] = { eventId="", callback=self.onInputCycleHandTool, triggerUp=false, triggerDown=true, triggerAlways=false, activeType=Player.INPUT_ACTIVE_TYPE.STARTS_DISABLED, callbackState=1, text=g_i18n:getText("input_NEXT_HANDTOOL"), textVisibility=false }
188 self.inputInformation.registrationList[InputAction.PREVIOUS_HANDTOOL] = { eventId="", callback=self.onInputCycleHandTool, triggerUp=false, triggerDown=true, triggerAlways=false, activeType=Player.INPUT_ACTIVE_TYPE.STARTS_DISABLED, callbackState=-1, text=g_i18n:getText("input_PREVIOUS_HANDTOOL"), textVisibility=false }
189 self.inputInformation.registrationList[InputAction.DEBUG_PLAYER_ENABLE] = { eventId="", callback=self.onInputDebugFlyToggle, triggerUp=false, triggerDown=true, triggerAlways=false, activeType=Player.INPUT_ACTIVE_TYPE.IS_DEBUG, callbackState=nil, text="", textVisibility=false }
190 self.inputInformation.registrationList[InputAction.DEBUG_PLAYER_UP_DOWN] = { eventId="", callback=self.onInputDebugFlyUpDown, triggerUp=false, triggerDown=false, triggerAlways=true, activeType=Player.INPUT_ACTIVE_TYPE.IS_DEBUG, callbackState=nil, text="", textVisibility=false }
191 self.inputInformation.registrationList[InputAction.ACTIVATE_HANDTOOL] = { eventId="", callback=self.onInputActivateHandtool, triggerUp=false, triggerDown=true, triggerAlways=true, activeType=Player.INPUT_ACTIVE_TYPE.STARTS_DISABLED, callbackState=nil, text=g_i18n:getText("input_ACTIVATE_HANDTOOL"), textVisibility=false }
192
193 self.soundInformation = {}
194 self.soundInformation.samples = {}
195
196 self.soundInformation.samples.swim = {}
197 self.soundInformation.samples.plunge = {}
198 self.soundInformation.samples.horseBrush = {}
199 self.soundInformation.samples.handtoolStop = {}
200 self.soundInformation.deleteHandtoolStopSampleAfterPlay = false
201 self.soundInformation.distancePerFootstep = {}
202 self.soundInformation.distancePerFootstep.crouch = 0.5
203 self.soundInformation.distancePerFootstep.walk = 0.75
204 self.soundInformation.distancePerFootstep.run = 1.5
205 self.soundInformation.distanceSinceLastFootstep = 0.0
206
207 self.particleSystemsInformation = {}
208 self.particleSystemsInformation.systems = {}
209 self.particleSystemsInformation.systems.swim = {}
210 self.particleSystemsInformation.systems.plunge = {}
211 self.particleSystemsInformation.swimNode = 0
212 self.particleSystemsInformation.plungeNode = 0
213
214 self.animationInformation = {}
215 self.animationInformation.player = 0
216 self.animationInformation.parameters = {}
217 self.animationInformation.parameters.forwardVelocity = {id=1, value=0.0, type=1}
218 self.animationInformation.parameters.verticalVelocity = {id=2, value=0.0, type=1}
219 self.animationInformation.parameters.yawVelocity = {id=3, value=0.0, type=1}
220 self.animationInformation.parameters.absYawVelocity = {id=4, value=0.0, type=1}
221 self.animationInformation.parameters.onGround = {id=5, value=false, type=0}
222 self.animationInformation.parameters.inWater = {id=6, value=false, type=0}
223 self.animationInformation.parameters.isCrouched = {id=7, value=false, type=0}
224 self.animationInformation.parameters.absForwardVelocity = {id=8, value=0.0, type=1}
225 self.animationInformation.parameters.isCloseToGround = {id=9, value=false, type=0}
226 self.animationInformation.parameters.isUsingChainsawHorizontal = {id=10, value=false, type=0}
227 self.animationInformation.parameters.isUsingChainsawVertical = {id=11, value=false, type=0}
228
229 -- @see Player.loadCustomization for the content of this struct
230 self.visualInformation = nil
231
232 -- cached info
233 self.animationInformation.oldYaw = 0.0 -- in rad
234 self.animationInformation.newYaw = 0.0 -- in rad
235 self.animationInformation.estimatedYawVelocity = 0.0 -- in rad/s
236
237 -- Player movement lock flag
238 self.walkingIsLocked = false
239
240 self.canRideAnimal = false
241 self.canEnterVehicle = false
242
243 self.isLightActive = false
244
245 self.rotX = 0
246 self.rotY = 0
247 self.cameraRotY = 0
248
249 self.graphicsRotY = 0
250 self.targetGraphicsRotY = 0
251
252 self.camera = 0
253
254 self.time = 0
255
256 self.lightNode = nil
257
258 self.clipDistance = 500
259
260 self.lastAnimPosX = 0
261 self.lastAnimPosY = 0
262 self.lastAnimPosZ = 0
263
264 self.walkDistance = 0
265 self.animUpdateTime = 0
266
267 self.debugFlightMode = false
268 self.debugFlightCoolDown = 0
269
270 self.requestedFieldData = false
271
272 self.playerStateMachine = PlayerStateMachine:new(self)
273
274 self.farmId = FarmManager.SPECTATOR_FARM_ID
275
276 return self
277end

onEnter

Description
Called when player enters mission. Sets player mesh visibility. Update traffic system with player info. Register player action events.
Definition
onEnter(bool isControlling)
Arguments
boolisControllingtrue if controlled
Code
1720function Player:onEnter(isControlling)
1721 self:raiseActive()
1722 if self.foliageBendingNode ~= nil and self.foliageBendingId == nil then
1723 -- foliage bending
1724 self.foliageBendingId = g_currentMission.foliageBendingSystem:createRectangle(-0.5, 0.5, -0.5, 0.5, 0.4, self.foliageBendingNode)
1725 end
1726
1727 if self.isServer then
1728 self:setOwner(self.networkInformation.creatorConnection)
1729 end
1730 if isControlling or self.isServer then
1731 self:raiseDirtyFlags(self.networkInformation.dirtyFlag)
1732 end
1733
1734 self.isControlled = true
1735 if isControlling then
1736 g_messageCenter:subscribe(MessageType.INPUT_BINDINGS_CHANGED, self.onInputBindingsChanged, self)
1737 g_currentMission:addPauseListeners(self, Player.onPausGame)
1738 setRotation(self.cameraNode, 0, 0, 0)
1739 setCamera(self.cameraNode)
1740 self.isEntered = true
1741 self:setVisibility(false)
1742 self:registerActionEvents()
1743 else
1744 self:setVisibility(true)
1745 end
1746 if self.isServer and not self.isEntered and g_currentMission.trafficSystem ~= nil and g_currentMission.trafficSystem.trafficSystemId ~= 0 then
1747 addTrafficSystemPlayer(g_currentMission.trafficSystem.trafficSystemId, self.graphicsRootNode)
1748 end
1749 self.isLightActive = false
1750end

onEnterFarmhouse

Description
Definition
onEnterFarmhouse()
Code
2298function Player:onEnterFarmhouse()
2299 if self.isServer then
2300 local dogHouse = g_currentMission:getDoghouse(self.farmId)
2301 if dogHouse ~= nil and dogHouse.dog ~= nil and dogHouse.dog.entityFollow == self.rootNode then
2302 dogHouse.dog:teleportToSpawn()
2303 end
2304 end
2305end

onGhostAdd

Description
Empty function
Definition
onGhostAdd()
Code
1866function Player:onGhostAdd()
1867end

onGhostRemove

Description
Deletes player
Definition
onGhostRemove()
Code
1860function Player:onGhostRemove()
1861 self:delete()
1862end

onInputActivateHandtool

Description
Definition
onInputActivateHandtool()
Code
3129function Player:onInputActivateHandtool(_, inputValue)
3130 if self:hasHandtoolEquipped() then
3131 self.baseInformation.currentHandtool.activatePressed = inputValue ~= 0
3132 end
3133end

onInputActivateObject

Description
Event function for interacting with an animal
Definition
onInputActivateObject()
Code
3047function Player:onInputActivateObject(_, inputValue)
3048 if self.playerStateMachine:isAvailable("activateObject") then
3049 self.playerStateMachine:activateState("activateObject")
3050 elseif self.playerStateMachine:isAvailable("animalFeed") then
3051 self.playerStateMachine:activateState("animalFeed")
3052 elseif self.playerStateMachine:isAvailable("animalPet") then
3053 self.playerStateMachine:activateState("animalPet")
3054 end
3055end

onInputCrouch

Description
Event function for crouching.
Definition
onInputCrouch()
Code
2965function Player:onInputCrouch(_, inputValue)
2966 if self.playerStateMachine:isAvailable("crouch") then
2967 self.playerStateMachine:activateState("crouch")
2968 end
2969
2970 self.inputInformation.crouchState = Player.BUTTONSTATES.PRESSED
2971end

onInputCycleHandTool

Description
Event function for cycling through available hand tools.
Definition
onInputCycleHandTool(nil, nil, integer direction)
Arguments
nil
nil
integerdirectiondirection in which the equipment is cycled through
Code
3070function Player:onInputCycleHandTool(_, _, direction)
3071 if self.playerStateMachine:isAvailable("cycleHandtool") then
3072 local cycleHandtoolState = self.playerStateMachine:getState("cycleHandtool")
3073 cycleHandtoolState.cycleDirection = direction
3074 self.playerStateMachine:activateState("cycleHandtool")
3075 end
3076end

onInputDebugFlyToggle

Description
Event function for the debug flying toggle.
Definition
onInputDebugFlyToggle()
Code
3088function Player:onInputDebugFlyToggle()
3089 if not self.walkingIsDisabled then
3090 if self.debugFlightCoolDown <= 0 then
3091 if g_flightAndNoHUDKeysEnabled then
3092 self.debugFlightMode = not self.debugFlightMode
3093 self.debugFlightCoolDown = 10
3094 end
3095 end
3096 end
3097end

onInputDebugFlyUpDown

Description
Event function for the debug flying vertical movement.
Definition
onInputDebugFlyUpDown(nil, float inputValue)
Arguments
nil
floatinputValue
Code
3103function Player:onInputDebugFlyUpDown(_, inputValue)
3104 if not self.walkingIsDisabled then
3105 local move = inputValue * 0.5 * self.debugFlightModeWalkingSpeed * self.debugFlightModeRunningFactor
3106 self.inputInformation.moveUp = self.inputInformation.moveUp + move
3107 end
3108end

onInputEnter

Description
Event function for enter
Definition
onInputEnter(nil, float inputValue)
Arguments
nil
floatinputValue
Code
3114function Player:onInputEnter(_, inputValue)
3115 if g_time > g_currentMission.lastInteractionTime + 200 then
3116 local enterVehicle = false
3117 if g_currentMission.interactiveVehicleInRange and g_currentMission.accessHandler:canFarmAccess(self.farmId, g_currentMission.interactiveVehicleInRange) then
3118 g_currentMission.interactiveVehicleInRange:interact()
3119 enterVehicle = true
3120 elseif self.canRideAnimal then
3121 self.playerStateMachine:activateState("animalRide")
3122 enterVehicle = true
3123 end
3124 end
3125end

onInputInteract

Description
Event function for interacting with an animal
Definition
onInputInteract()
Code
3027function Player:onInputInteract(_, inputValue)
3028 -- Note: we need to store pressed state for animal cleaning (see PlayerStateAnimalInteract) which is a continuous
3029 -- action. Therefore, this event is called onUp and onDown. When the down event is received, input will be non-zero.
3030 if self.inputInformation.interactState ~= Player.BUTTONSTATES.PRESSED and inputValue ~= 0 then
3031 if self.playerStateMachine:isAvailable("drop") then
3032 self.playerStateMachine:activateState("drop")
3033 elseif self.playerStateMachine:isAvailable("pickup") then
3034 self.playerStateMachine:activateState("pickup")
3035 elseif self.playerStateMachine:isAvailable("animalInteract") then
3036 self.playerStateMachine:activateState("animalInteract")
3037 end
3038
3039 self.inputInformation.interactState = Player.BUTTONSTATES.PRESSED
3040 else
3041 self.inputInformation.interactState = Player.BUTTONSTATES.RELEASED
3042 end
3043end

onInputJump

Description
Event function for jumping.
Definition
onInputJump()
Code
3019function Player:onInputJump(_, inputValue)
3020 if self.playerStateMachine:isAvailable("jump") then
3021 self.playerStateMachine:activateState("jump")
3022 end
3023end

onInputLookLeftRight

Description
Event function for player camera horizontal axis.
Definition
onInputLookLeftRight(nil, float inputValue)
Arguments
nil
floatinputValue
Code
2899function Player:onInputLookLeftRight(_, inputValue, _, _, isMouse)
2900 if not self.lockedInput then
2901 if isMouse then
2902 inputValue = inputValue * 0.001 * 16.666
2903 else
2904 inputValue = inputValue * g_currentDt *0.001
2905 end
2906 self.inputInformation.yawCamera = self.inputInformation.yawCamera + inputValue
2907 end
2908 self.inputInformation.isMouseRotation = isMouse
2909end

onInputLookUpDown

Description
Event function for player camera vertical axis.
Definition
onInputLookUpDown(nil, float inputValue)
Arguments
nil
floatinputValue
Code
2915function Player:onInputLookUpDown(_, inputValue, _, _, isMouse)
2916 if not self.lockedInput then
2917 local pitchValue = g_gameSettings:getValue("invertYLook") and -inputValue or inputValue
2918 if isMouse then
2919 pitchValue = pitchValue * 0.001 * 16.666
2920 else
2921 pitchValue = pitchValue * g_currentDt *0.001
2922 end
2923 self.inputInformation.pitchCamera = self.inputInformation.pitchCamera + pitchValue
2924 end
2925end

onInputMoveForward

Description
Event function for player forward/backward movement.
Definition
onInputMoveForward(nil, float inputValue)
Arguments
nil
floatinputValue
Code
2941function Player:onInputMoveForward(_, inputValue)
2942 if not self.lockedInput then
2943 self.inputInformation.moveForward = self.inputInformation.moveForward + inputValue
2944 end
2945end

onInputMoveSide

Description
Event function for player strafe movement.
Definition
onInputMoveSide(nil, float inputValue)
Arguments
nil
floatinputValue
Code
2931function Player:onInputMoveSide(_, inputValue)
2932 if not self.lockedInput then
2933 self.inputInformation.moveRight = self.inputInformation.moveRight + inputValue
2934 end
2935end

onInputRotateObjectHorizontally

Description
Event function for rotating object.
Definition
onInputRotateObjectHorizontally()
Code
2975function Player:onInputRotateObjectHorizontally(_, inputValue)
2976 if self.pickedUpObjectJointId ~= nil and math.abs(inputValue) > 0 then
2977 self:rotateObject(inputValue, 0.0, 1.0, 0.0)
2978 elseif self.isCarryingObject and self.isClient and self.isControlled then
2979 if inputValue ~= 0.0 then
2980 self.networkInformation.rotateObject = true
2981 else
2982 self.networkInformation.rotateObject = false
2983 end
2984 self.networkInformation.rotateObjectInputH = inputValue
2985 end
2986end

onInputRotateObjectVertically

Description
Event function for rotating object.
Definition
onInputRotateObjectVertically()
Code
2990function Player:onInputRotateObjectVertically(_, inputValue)
2991 if self.pickedUpObjectJointId ~= nil and math.abs(inputValue) > 0 then
2992 self:rotateObject(inputValue, 1.0, 0.0, 0.0)
2993 elseif self.isCarryingObject and self.isClient and self.isControlled then
2994 if inputValue ~= 0.0 then
2995 self.networkInformation.rotateObject = true
2996 else
2997 self.networkInformation.rotateObject = false
2998 end
2999 self.networkInformation.rotateObjectInputV = inputValue
3000 end
3001end

onInputRun

Description
Event function for player running.
Definition
onInputRun(nil, float inputValue)
Arguments
nil
floatinputValue
Code
2951function Player:onInputRun(_, inputValue)
2952 self.inputInformation.runAxis = inputValue
2953
2954 if self.debugFlightMode then
2955 if inputValue > 0 and self.debugFlightModeRunningFactor ~= 4.0 then
2956 self.debugFlightModeRunningFactor = 4.0
2957 elseif inputValue == 0 and self.debugFlightModeRunningFactor ~= 1.0 then
2958 self.debugFlightModeRunningFactor = 1.0
2959 end
2960 end
2961end

onInputThrowObject

Description
Event function for throwing an object.
Definition
onInputThrowObject()
Code
3080function Player:onInputThrowObject(_, inputValue)
3081 if self.playerStateMachine:isAvailable("throw") then
3082 self.playerStateMachine:activateState("throw")
3083 end
3084end

onInputToggleLight

Description
Event function for flashlight toggle.
Definition
onInputToggleLight()
Code
3059function Player:onInputToggleLight()
3060 if self.playerStateMachine:isAvailable("useLight") then
3061 self.playerStateMachine:activateState("useLight")
3062 end
3063end

onLeave

Description
Called when player Leaves mission. Update traffic system to ignore this player. Clear position history, visibility. Removes tools. Deregister from companion animal system. Moves to (0, -200, 0)
Definition
onLeave()
Code
1761function Player:onLeave()
1762 if self.isControlled then
1763 g_messageCenter:unsubscribe(MessageType.INPUT_BINDINGS_CHANGED, self)
1764 end
1765
1766 -- stop swim sound
1767 if g_soundManager:getIsSamplePlaying(self.soundInformation.samples.swim) then
1768 g_soundManager:stopSample(self.soundInformation.samples.swim)
1769 end
1770 if g_soundManager:getIsSamplePlaying(self.soundInformation.samples.swimIdle) then
1771 g_soundManager:stopSample(self.soundInformation.samples.swimIdle)
1772 end
1773
1774 self:removeActionEvents()
1775 -- unregister animal interess
1776 for husbandryId, _ in pairs(g_currentMission.husbandries) do
1777 setAnimalInteressNode(husbandryId, 0)
1778 end
1779
1780 if self.foliageBendingId ~= nil then
1781 g_currentMission.foliageBendingSystem:destroyObject(self.foliageBendingId)
1782 self.foliageBendingId = nil
1783 end
1784
1785 if self.isServer then
1786 self:setOwner(nil)
1787 end
1788 if self.isEntered or self.isServer then
1789 self:raiseDirtyFlags(self.networkInformation.dirtyFlag)
1790 end
1791 if self.isServer and not self.isEntered and g_currentMission.trafficSystem ~= nil and g_currentMission.trafficSystem.trafficSystemId ~= 0 then
1792 removeTrafficSystemPlayer(g_currentMission.trafficSystem.trafficSystemId, self.graphicsRootNode)
1793 end
1794
1795 g_currentMission:addPauseListeners(self)
1796
1797 --clear history
1798 self.networkInformation.history = {}
1799 self.isControlled = false
1800 self.isEntered = false
1801 self:setVisibility(false)
1802
1803 if self:hasHandtoolEquipped() then
1804 self.baseInformation.currentHandtool:onDeactivate()
1805 self.baseInformation.currentHandtool:delete()
1806 self.baseInformation.currentHandtool = nil
1807 end
1808 local dogHouse = g_currentMission:getDoghouse(self.farmId)
1809 if dogHouse ~= nil and dogHouse.dog ~= nil then
1810 dogHouse.dog:onPlayerLeave(self)
1811 end
1812
1813 if self.lightNode ~= nil then
1814 setVisibility(self.lightNode, false)
1815 end
1816 self:moveToAbsoluteInternal(0, -200, 0)
1817end

onLeaveVehicle

Description
Called when player leaves vehicle
Definition
onLeaveVehicle()
Code
1754function Player:onLeaveVehicle()
1755 self.playerStateMachine:deactivateState("animalRide")
1756 self.playerStateMachine:deactivateState("jump")
1757end

onPickedUpObjectJointBreak

Description
Callback when picked-up object's joint is broken
Definition
onPickedUpObjectJointBreak(integer jointIndex, float breakingImpulse)
Arguments
integerjointIndexindex of the joint
floatbreakingImpulse
Return Values
alwaysreturnsfalse
Code
2350function Player:onPickedUpObjectJointBreak(jointIndex, breakingImpulse)
2351 if jointIndex == self.pickedUpObjectJointId then
2352 self:pickUpObject(false)
2353 end
2354 -- Do not delete the joint internally, we already deleted it
2355 return false
2356end

pickUpObject

Description
Picks up an object and links it via a spring mechanism.
Definition
pickUpObject(bool state, bool noEventSend)
Arguments
boolstateif true will join the object, else the joint is removed
boolnoEventSendunused parameter
Code
2043function Player:pickUpObject(state, noEventSend)
2044 PlayerPickUpObjectEvent.sendEvent(self, state, noEventSend)
2045 if self.isServer then
2046 if state and (self.isObjectInRange and self.lastFoundObject ~= nil) and not self.isCarryingObject then
2047 local constr = JointConstructor:new()
2048
2049 -- disable collision with CCT
2050 self.pickedUpObjectCollisionMask = getCollisionMask(self.lastFoundObject)
2051 local newPickedUpObjectCollisionFlag = bitXOR(bitAND(self.pickedUpObjectCollisionMask, Player.movementCollisionMask), self.pickedUpObjectCollisionMask)
2052 setCollisionMask(self.lastFoundObject, newPickedUpObjectCollisionFlag)
2053
2054 constr:setActors(self.pickUpKinematicHelperNode, self.lastFoundObject)
2055
2056 for i=0, 2 do
2057 constr:setRotationLimit(i, 0, 0)
2058 constr:setTranslationLimit(i, true, 0, 0)
2059 end
2060
2061 -- set position of joint
2062 local mx, my, mz = getCenterOfMass(self.lastFoundObject)
2063 local wx, wy, wz = localToWorld(self.lastFoundObject, mx, my, mz)
2064 constr:setJointWorldPositions(wx, wy, wz, wx, wy, wz)
2065
2066 local nx, ny, nz = localDirectionToWorld(self.lastFoundObject, 1, 0, 0)
2067 constr:setJointWorldAxes(nx, ny, nz, nx, ny, nz)
2068
2069 local yx, yy, yz = localDirectionToWorld(self.lastFoundObject, 0, 1, 0)
2070 constr:setJointWorldNormals(yx, yy, yz, yx, yy, yz)
2071 constr:setEnableCollision(false)
2072
2073 setWorldTranslation(self.pickUpKinematicHelperNodeChild, wx, wy, wz)
2074 setWorldRotation(self.pickUpKinematicHelperNodeChild, getWorldRotation(self.lastFoundObject))
2075
2076 -- set spring/damper ?!
2077 local dampingRatio = 1.0
2078 local mass = getMass(self.lastFoundObject)
2079
2080 local rotationLimitSpring = {}
2081 local rotationLimitDamper = {}
2082 for i=1, 3 do
2083 rotationLimitSpring[i] = mass * 60
2084 rotationLimitDamper[i] = dampingRatio * 2 * math.sqrt( mass * rotationLimitSpring[i] )
2085 --print(" rotSpring/Damper = "..tostring(rotationLimitSpring[i]).." / "..tostring(rotationLimitDamper[i]))
2086 end
2087 constr:setRotationLimitSpring(rotationLimitSpring[1], rotationLimitDamper[1], rotationLimitSpring[2], rotationLimitDamper[2], rotationLimitSpring[3], rotationLimitDamper[3])
2088
2089 local translationLimitSpring = {}
2090 local translationLimitDamper = {}
2091 for i=1, 3 do
2092 translationLimitSpring[i] = mass * 60
2093 translationLimitDamper[i] = dampingRatio * 2 * math.sqrt( mass * translationLimitSpring[i] )
2094 --print(" transSpring/Damper = "..tostring(translationLimitSpring[i]).." / "..tostring(translationLimitDamper[i]))
2095 end
2096 constr:setTranslationLimitSpring(translationLimitSpring[1], translationLimitDamper[1], translationLimitSpring[2], translationLimitDamper[2], translationLimitSpring[3], translationLimitDamper[3])
2097
2098 local forceAcceleration = 4
2099 local forceLimit = forceAcceleration * mass * 40.0
2100 constr:setBreakable(forceLimit, forceLimit)
2101
2102 self.pickedUpObjectJointId = constr:finalize()
2103
2104 addJointBreakReport(self.pickedUpObjectJointId, "onPickedUpObjectJointBreak", self)
2105
2106 self.pickedUpObject = self.lastFoundObject
2107 self.isCarryingObject = true
2108 Player.PICKED_UP_OBJECTS[self.pickedUpObject] = true
2109
2110 local object = g_currentMission:getNodeObject(self.pickedUpObject)
2111 if object ~= nil then
2112 object.thrownFromPosition = nil
2113 end
2114 else
2115 if self.pickedUpObjectJointId ~= nil then
2116 removeJoint(self.pickedUpObjectJointId)
2117 self.pickedUpObjectJointId = nil
2118 self.isCarryingObject = false
2119 Player.PICKED_UP_OBJECTS[self.pickedUpObject] = false
2120
2121 if entityExists(self.pickedUpObject) then
2122 local vx, vy, vz = getLinearVelocity(self.pickedUpObject)
2123 vx = MathUtil.clamp(vx, -5, 5)
2124 vy = MathUtil.clamp(vy, -5, 5)
2125 vz = MathUtil.clamp(vz, -5, 5)
2126 setLinearVelocity(self.pickedUpObject, vx, vy, vz)
2127 -- setAngularVelocity(self.pickedUpObject, vx, vy, vz)
2128 setCollisionMask(self.pickedUpObject, self.pickedUpObjectCollisionMask)
2129 self.pickedUpObjectCollisionMask = 0
2130 end
2131
2132 local object = g_currentMission:getNodeObject(self.pickedUpObject)
2133 if object ~= nil then
2134 object.thrownFromPosition = nil
2135 end
2136 self.pickedUpObject = nil
2137 end
2138 end
2139 end
2140end

pickUpObjectRaycastCallback

Description
Callback used when raycast hists an object. Updates player information so it can be used to pickup the object.
Definition
pickUpObjectRaycastCallback(integer hitObjectId, float x, float y, float z, float distance)
Arguments
integerhitObjectIdscenegraph object id
floatxworld x hit position
floatyworld y hit position
floatzworld z hit position
floatdistancedistance at which the cast hit the object
Return Values
boolreturnstrue object that was hit is valid
Code
2003function Player:pickUpObjectRaycastCallback(hitObjectId, x, y, z, distance)
2004 if hitObjectId ~= g_currentMission.terrainDetailId and Player.PICKED_UP_OBJECTS[hitObjectId] ~= true then
2005 if getRigidBodyType(hitObjectId) == "Dynamic" then
2006
2007 local mass = getMass(hitObjectId)
2008 -- check if mounted:
2009 local canBePickedUp = true
2010 local object = g_currentMission:getNodeObject(hitObjectId)
2011 if object ~= nil then
2012 if object.dynamicMountObject ~= nil then
2013 canBePickedUp = false
2014 end
2015 if object.getTotalMass ~= nil then
2016 mass = object:getTotalMass()
2017 end
2018 if object.getCanBePickedUp ~= nil then
2019 if not object:getCanBePickedUp(self) then
2020 canBePickedUp = false
2021 end
2022 end
2023 end
2024
2025 if canBePickedUp then
2026 self.lastFoundObject = hitObjectId
2027 self.lastFoundObjectMass = mass
2028 self.lastFoundObjectHitPoint = {x, y, z}
2029 end
2030
2031 -- only consider first potentially valid object
2032 return false
2033 end
2034 end
2035
2036 return true
2037end

playHandToolStopSample

Description
Definition
playHandToolStopSample()
Code
2281function Player:playHandToolStopSample()
2282 if self.soundInformation.samples.handtoolStop.soundSample ~= nil then
2283 g_soundManager:playSample(self.soundInformation.samples.handtoolStop)
2284 self.soundInformation.deleteHandtoolStopSampleAfterPlay = true
2285 end
2286end

readStream

Description
Reads from network stream
Definition
readStream(integer streamId, table connection)
Arguments
integerstreamIdid of the stream to read
tableconnectionconnection information
Code
765function Player:readStream(streamId, connection)
766 Player:superClass().readStream(self, streamId)
767 local isOwner = streamReadBool(streamId)
768 local filename = NetworkUtil.convertFromNetworkFilename(streamReadString(streamId))
769 local x = streamReadFloat32(streamId)
770 local y = streamReadFloat32(streamId)
771 local z = streamReadFloat32(streamId)
772 local isControlled = streamReadBool(streamId)
773 if self.visualInformation == nil then
774 self.visualInformation = PlayerStyle:new()
775 end
776 self.visualInformation:readStream(streamId, connection)
777 self.farmId = streamReadUIntN(streamId, FarmManager.FARM_ID_SEND_NUM_BITS)
778 if self.filename == nil then
779 self:load(filename, self.visualInformation, connection, isOwner)
780 end
781 self:moveToAbsoluteInternal(x, y, z)
782
783 self:setLightIsActive(streamReadBool(streamId), true)
784
785 if isControlled ~= self.isControlled then
786 if isControlled then
787 self:onEnter(false)
788 else
789 self:onLeave()
790 end
791 end
792
793 local hasHandtool = streamReadBool(streamId)
794 if hasHandtool then
795 local handtoolFilename = NetworkUtil.convertFromNetworkFilename(streamReadString(streamId))
796 self:equipHandtool(handtoolFilename, true, true)
797 end
798end

readUpdateStream

Description
Reads from network stream via update
Definition
readUpdateStream(integer streamId, integer timestamp, table connection)
Arguments
integerstreamIdid of the stream to read
integertimestamptimestamp of the packet
tableconnectionconnection information
Code
831function Player:readUpdateStream(streamId, timestamp, connection)
832 if connection:getIsServer() then
833 -- client code (read data from server)
834 local x = streamReadFloat32(streamId)
835 local y = streamReadFloat32(streamId)
836 local z = streamReadFloat32(streamId)
837 local alpha = streamReadFloat32(streamId)
838 self.cameraRotY = alpha
839
840 self.isObjectInRange = streamReadBool(streamId)
841 if self.isObjectInRange then
842 self.lastFoundObjectMass = streamReadFloat32(streamId)
843 else
844 self.lastFoundObjectMass = nil
845 end
846 self.isCarryingObject = streamReadBool(streamId)
847 local isOnGround = streamReadBool(streamId)
848
849 if self.isOwner then
850 local index = streamReadInt32(streamId)
851 --print("CLIENT ( "..tostring(self).." ): x/y/z = "..tostring(x).." / "..tostring(y).." / "..tostring(z))
852 -- remove history entries before the one sent by the server
853 while self.networkInformation.history[1] ~= nil and self.networkInformation.history[1].index <= index do
854 table.remove(self.networkInformation.history, 1)
855 end
856 -- set position sent by server
857 setCCTPosition(self.controllerIndex, x, y, z)
858 -- move cct from the rest of the history queue
859 -- Accumulate moves from multiple history entries so that we never apply more than 5 moveCCT's
860 local history = self.networkInformation.history
861 local numHistory = #history
862 if numHistory <= 5 then
863 for i=1,numHistory do
864 moveCCT(self.controllerIndex, history[i].movementX, history[i].movementY, history[i].movementZ, Player.movementCollisionMask)
865 end
866 else
867 -- Accumulate moves with different amounts so that we achieve exactly the correct historty
868 -- Some will use floored, some will use floored + 1
869 -- Use the smaller amount for the older moves as errors for older moves potentially leads to larger errors now than for more recent ones
870 local accumSizeSmall = math.floor(numHistory / 5)
871 local numSmall = 5 - numHistory + accumSizeSmall * 5
872 local startI = 1
873 for i=1,5 do
874 local endI
875 if i <= numSmall then
876 endI = startI+accumSizeSmall-1
877 else
878 endI = startI+accumSizeSmall
879 end
880 local movementX, movementY, movementZ = 0,0,0
881 for j=startI,endI do
882 movementX = movementX + history[j].movementX
883 movementY = movementY + history[j].movementY
884 movementZ = movementZ + history[j].movementZ
885 end
886 moveCCT(self.controllerIndex, movementX, movementY, movementZ, Player.movementCollisionMask)
887 startI = endI+1
888 end
889 end
890 -- set target physics index to current index
891 self.networkInformation.updateTargetTranslationPhysicsIndex = getPhysicsUpdateIndex() -- update until the current physics index is simulated
892 -- [animation]
893 self.baseInformation.isCrouched = streamReadBool(streamId)
894 --
895 else
896 local isControlled = streamReadBool(streamId)
897 if isControlled ~= self.isControlled then
898 self:moveToAbsoluteInternal(x, y, z)
899 if isControlled then
900 self:onEnter(false)
901 else
902 self:onLeave()
903 end
904 else
905 -- other clients: set position, refrain from using target index and start new network interpolation phase
906 setTranslation(self.rootNode, x, y, z)
907 self.networkInformation.interpolatorPosition:setTargetPosition(x, y, z)
908 if isOnGround then
909 self.networkInformation.interpolatorOnGround:setTargetValue(1.0)
910 else
911 self.networkInformation.interpolatorOnGround:setTargetValue(0.0)
912 end
913 self.networkInformation.updateTargetTranslationPhysicsIndex = -1
914 self.networkInformation.interpolationTime:startNewPhaseNetwork()
915 -- force update
916 self:raiseActive()
917 end
918 -- [animation]
919 self.baseInformation.isCrouched = streamReadBool(streamId)
920 --
921 end
922 else
923 -- server code (read data from client)
924 if connection == self.networkInformation.creatorConnection then
925 -- we received translation information from client and we ask the physics to move the avatar; we insert the current physics index in the history queue and force an update()
926 local movementX=streamReadFloat32(streamId)
927 local movementY=streamReadFloat32(streamId)
928 local movementZ=streamReadFloat32(streamId)
929
930 local qx = streamReadFloat32(streamId)
931 local qy = streamReadFloat32(streamId)
932 local qz = streamReadFloat32(streamId)
933 local qw = streamReadFloat32(streamId)
934
935 local index = streamReadInt32(streamId)
936 local isControlled = streamReadBool(streamId)
937
938 moveCCT(self.controllerIndex, movementX, movementY, movementZ, Player.movementCollisionMask)
939
940 self.networkInformation.interpolationTime:startNewPhaseNetwork()
941 self.networkInformation.interpolatorQuaternion:setTargetQuaternion(qx, qy, qz, qw)
942 local physicsIndex = getPhysicsUpdateIndex()
943 table.insert(self.networkInformation.history, {index=index, physicsIndex = physicsIndex})
944
945 self.networkInformation.updateTargetTranslationPhysicsIndex = physicsIndex -- update until the current physics index is simulated
946
947 self:raiseActive()
948 if isControlled ~= self.isControlled then
949 if isControlled then
950 self:onEnter(false)
951 else
952 self:onLeave()
953 end
954 end
955 -- [animation]
956 self.baseInformation.isCrouched = streamReadBool(streamId)
957 --
958 if self.isCarryingObject then
959 self.networkInformation.rotateObject = streamReadBool(streamId)
960 if self.networkInformation.rotateObject then
961 self.networkInformation.rotateObjectInputH = streamReadFloat32(streamId)
962 self.networkInformation.rotateObjectInputV = streamReadFloat32(streamId)
963 end
964 end
965 end
966 end
967end

recordPositionInformation

Description
Definition
recordPositionInformation()
Code
2671function Player:recordPositionInformation()
2672 local currentPositionX, _, currentPositionZ = getTranslation(self.graphicsRootNode)
2673 local deltaPosX = currentPositionX - self.baseInformation.lastPositionX
2674 local deltaPosZ = currentPositionZ - self.baseInformation.lastPositionZ
2675 self.baseInformation.lastPositionX = currentPositionX
2676 self.baseInformation.lastPositionZ = currentPositionZ
2677
2678 local groundDistanceCovered = MathUtil.vector2Length(deltaPosX, deltaPosZ)
2679 self.motionInformation.justMoved = groundDistanceCovered > 0.0
2680 if self.baseInformation.isOnGround then
2681 self.motionInformation.currentCoveredGroundDistance = groundDistanceCovered
2682 self.motionInformation.coveredGroundDistance = self.motionInformation.coveredGroundDistance + groundDistanceCovered
2683 end
2684end

registerActionEvents

Description
Register required player action events.
Definition
registerActionEvents()
Code
2848function Player:registerActionEvents()
2849 -- register action events for the player context without switching (important when this is called from within the UI context)
2850 g_inputBinding:beginActionEventsModification(Player.INPUT_CONTEXT_NAME)
2851
2852 for actionId, inputRegisterEntry in pairs(self.inputInformation.registrationList) do
2853 local eventAdded = false
2854 local startActive = false
2855
2856 if inputRegisterEntry.activeType == Player.INPUT_ACTIVE_TYPE.STARTS_ENABLED then
2857 startActive = true
2858 elseif inputRegisterEntry.activeType == Player.INPUT_ACTIVE_TYPE.STARTS_DISABLED then
2859 startActive = false
2860 elseif inputRegisterEntry.activeType == Player.INPUT_ACTIVE_TYPE.IS_MOVEMENT then
2861 startActive = not self.walkingIsLocked
2862 elseif inputRegisterEntry.activeType == Player.INPUT_ACTIVE_TYPE.IS_CARRYING then
2863 startActive = self.isCarryingObject
2864 elseif inputRegisterEntry.activeType == Player.INPUT_ACTIVE_TYPE.IS_DEBUG then
2865 startActive = self.baseInformation.isInDebug
2866 end
2867
2868 -- register with conflict removal flag, will disable conflicting bindings of newly registered actions
2869 eventAdded, inputRegisterEntry.eventId = g_inputBinding:registerActionEvent(actionId, self, inputRegisterEntry.callback, inputRegisterEntry.triggerUp, inputRegisterEntry.triggerDown, inputRegisterEntry.triggerAlways, startActive, inputRegisterEntry.callbackState, true)
2870 if inputRegisterEntry.text ~= nil and inputRegisterEntry.text ~= "" then
2871 g_inputBinding:setActionEventText(inputRegisterEntry.eventId, inputRegisterEntry.text)
2872 end
2873
2874 g_inputBinding:setActionEventTextVisibility(inputRegisterEntry.eventId, inputRegisterEntry.textVisibility)
2875 end
2876 -- reset registration context, update event data in input system:
2877 g_inputBinding:endActionEventsModification()
2878end

removeActionEvents

Description
Remove all player action events.
Definition
removeActionEvents()
Code
2882function Player:removeActionEvents()
2883 -- reset previously disabled bindings' enabled state
2884 g_inputBinding:resetActiveActionBindings()
2885
2886 -- modify action events in player context without switching (important because this can be called from within the UI)
2887 g_inputBinding:beginActionEventsModification(Player.INPUT_CONTEXT_NAME)
2888 g_inputBinding:removeActionEventsByTarget(self)
2889 for _, inputRegisterEntry in pairs(self.inputInformation.registrationList) do
2890 inputRegisterEntry.eventId = ""
2891 end
2892 g_inputBinding:endActionEventsModification()
2893end

resetBrake

Description
Definition
resetBrake()
Code
2701function Player:resetBrake()
2702 self:setVelocityToMotion(0.0, 0.0, 0.0)
2703 self:setAccelerationToMotion(0.0, 0.0, 0.0)
2704 self.motionInformation.brakeForce = {0.0, 0.0, 0.0}
2705 self.motionInformation.isBraking = false
2706end

resetCameraInputsInformation

Description
Reset for input managed in update() method
Definition
resetCameraInputsInformation()
Code
2590function Player:resetCameraInputsInformation()
2591 self.inputInformation.pitchCamera = 0
2592 self.inputInformation.yawCamera = 0
2593 self.inputInformation.crouchState = Player.BUTTONSTATES.RELEASED
2594end

resetInputsInformation

Description
Reset input information inbetween frames. Input is accumulated by events until read, processed and reset. Reset for input managed in updateTick() method
Definition
resetInputsInformation()
Code
2581function Player:resetInputsInformation()
2582 self.inputInformation.moveRight = 0
2583 self.inputInformation.moveForward = 0
2584 self.inputInformation.moveUp = 0
2585 self.inputInformation.runAxis = 0
2586end

rotateObject

Description
Rotates object
Definition
rotateObject()
Code
3005function Player:rotateObject(inputValue, axisX, axisY, axisZ)
3006 local jointIndex = self.pickedUpObjectJointId
3007 local actor = 0
3008 local objectTransform = self.pickUpKinematicHelperNodeChild
3009 local rotX, rotY, rotZ = localDirectionToLocal(self.cameraNode, objectTransform, axisX, axisY, axisZ)
3010 local dtInSec = g_physicsDt * 0.001
3011 local rotation = math.rad(90.0) * dtInSec * inputValue
3012
3013 rotateAboutLocalAxis(objectTransform, rotation, rotX, rotY, rotZ)
3014 setJointFrame(jointIndex, actor, objectTransform)
3015end

setCuttingAnim

Description
Set cutting animation
Definition
setCuttingAnim(bool isCutting, bool isHorizontalCut)
Arguments
boolisCuttingtrue if player is cutting
boolisHorizontalCuttrue if player is cutting horizontaly
Code
746function Player:setCuttingAnim(isCutting, isHorizontalCut)
747 if not isCutting and (self.baseInformation.isUsingChainsawHorizontal or self.baseInformation.isUsingChainsawVertical) then
748 self.baseInformation.isUsingChainsawHorizontal = false
749 self.baseInformation.isUsingChainsawVertical = false
750 elseif isCutting then
751 if isHorizontalCut then
752 self.baseInformation.isUsingChainsawHorizontal = true
753 self.baseInformation.isUsingChainsawVertical = false
754 else
755 self.baseInformation.isUsingChainsawHorizontal = false
756 self.baseInformation.isUsingChainsawVertical = true
757 end
758 end
759end

setIKDirty

Description
Sets all ik chain node to dirty so that they are recalculated
Definition
setIKDirty()
Code
1560function Player:setIKDirty()
1561 IKUtil.setIKChainDirty(self.ikChains, "rightFoot")
1562 IKUtil.setIKChainDirty(self.ikChains, "leftFoot")
1563 IKUtil.setIKChainDirty(self.ikChains, "rightArm")
1564 IKUtil.setIKChainDirty(self.ikChains, "leftArm")
1565 IKUtil.setIKChainDirty(self.ikChains, "spine")
1566end

setLightIsActive

Description
Definition
setLightIsActive()
Code
2144function Player:setLightIsActive(isActive, noEventSend)
2145 if isActive ~= self.isLightActive then
2146 self.isLightActive = isActive
2147 PlayerToggleLightEvent.sendEvent(self, isActive, noEventSend)
2148
2149 setVisibility(self.lightNode, isActive)
2150 g_soundManager:playSample(self.soundInformation.samples.flashlight)
2151 end
2152end

setRotation

Description
Set player rotation
Definition
setRotation(float rotX, float rotY)
Arguments
floatrotXset rotation x parameter; vertical X rotation is clamped
floatrotYset rotation y parameter (graphics node, target graphics and camera)
Code
1640function Player:setRotation(rotX, rotY)
1641 self.rotX = math.min(1.2, math.max(-1.5, rotX))
1642 self.rotY = rotY
1643 self.graphicsRotY = rotY
1644 self.cameraRotY = rotY
1645 self.targetGraphicsRotY = rotY
1646end

setVisibility

Description
Sets third person mesh visibility
Definition
setVisibility(bool visibility)
Arguments
boolvisibilityif true will update visibility accordingly.
Code
1822function Player:setVisibility(visibility)
1823 if self.meshThirdPerson ~= nil then
1824 setVisibility(self.meshThirdPerson, visibility)
1825 self.visualInformation:setVisibility(visibility)
1826 end
1827end

setWalkingLock

Description
Lock or unlock the player's movement. Sets the Player.walkingIsLocked flag and enables/disables movement action events accordingly.
Definition
setWalkingLock(isLocked If)
Arguments
isLockedIftrue, the player's movement is locked. Otherwise, it is released.
Code
2796function Player:setWalkingLock(isLocked)
2797 self.walkingIsLocked = isLocked
2798
2799 for _, inputRegistration in pairs(self.inputInformation.registrationList) do
2800 if inputRegistration.activeType == Player.INPUT_ACTIVE_TYPE.IS_MOVEMENT then
2801 g_inputBinding:setActionEventActive(inputRegistration.eventId, not isLocked)
2802 end
2803 end
2804end

setWoodWorkVisibility

Description
Sets visibility for gloves and helmet. Gloves code is deprecated.
Definition
setWoodWorkVisibility(bool visibilityGloves, bool visibilityHelmet)
Arguments
boolvisibilityGlovesif true will update visibility of gloves accordingly.
boolvisibilityHelmetif true will update visibility of helmet accordingly.
Code
1833function Player:setWoodWorkVisibility(state, uvs)
1834 if self.isEntered then
1835 self.visualInformation:setProtectiveVisibility(false)
1836 end
1837 self.visualInformation:setProtectiveVisibility(state)
1838end

testScope

Description
Check if a position is within clip distance
Definition
testScope(float x, float y, float z, float coeff)
Arguments
floatxworld x position
floatyworld y position
floatzworld z position
floatcoeffparameter is unused
Return Values
boolreturnstrue if distance to player root node is lower than clip distance
Code
1847function Player:testScope(x, y, z, coeff)
1848 local x1, y1, z1 = getTranslation(self.rootNode)
1849 local dist = MathUtil.vector3Length(x1 - x, y1 - y, z1 - z)
1850 local clipDist = self.clipDistance
1851 if dist < clipDist * clipDist then
1852 return true
1853 else
1854 return false
1855 end
1856end

throwObject

Description
Throws an object. Activates dog to fetch a ball if conditions are met.
Definition
throwObject()
Code
2309function Player:throwObject(noEventSend)
2310 PlayerThrowObjectEvent.sendEvent(self, noEventSend)
2311 if self.pickedUpObject ~= nil and self.pickedUpObjectJointId ~= nil then
2312 local pickedUpObject = self.pickedUpObject
2313 self:pickUpObject(false)
2314
2315 local mass = getMass(pickedUpObject)
2316
2317 local v = 8 * (1.1-mass/Player.MAX_PICKABLE_OBJECT_MASS) -- speed between 0.8 and 8.8 based on mass of current object
2318 local vx, vy, vz = localDirectionToWorld(self.cameraNode, 0, 0, -v)
2319 setLinearVelocity(pickedUpObject, vx, vy, vz)
2320
2321 local object = g_currentMission:getNodeObject(pickedUpObject)
2322 if object ~= nil then
2323 object.thrownFromPosition = {getWorldTranslation(self.rootNode)}
2324
2325 if object:isa(DogBall) then
2326 local dogHouse = g_currentMission:getDoghouse(self.farmId)
2327 if dogHouse ~= nil and dogHouse.dog ~= nil and dogHouse.dog.playersInRange[self.rootNode] then
2328 dogHouse.dog:fetchItem(self, object)
2329 end
2330 end
2331 end
2332 elseif (self.isObjectInRange and self.lastFoundObject ~= nil) and not self.isCarryingObject then
2333 local mass = getMass(self.lastFoundObject)
2334
2335 if mass <= Player.MAX_PICKABLE_OBJECT_MASS then
2336 local v = 8 * (1.1 - mass / Player.MAX_PICKABLE_OBJECT_MASS) -- speed between 0.8 and 8.8 based on mass of current object
2337 local halfSqrt = 0.707106781
2338 -- Add the impulse in 45deg towards the y axis of the camera
2339 local vx,vy,vz = localDirectionToWorld(self.cameraNode, 0.0, halfSqrt * v, -halfSqrt * v)
2340 setLinearVelocity(self.lastFoundObject, vx, vy, vz)
2341 end
2342 end
2343end

unequipHandtool

Description
Definition
unequipHandtool()
Code
2242function Player:unequipHandtool()
2243 self:equipHandtool("", true)
2244end

update

Description
Main update function for the player. Taking care of: fx, water parms, sound, player states, motion, debug, action events, hand tools, animation, object picking, IK
Definition
update(float dt)
Arguments
floatdtdelta time in ms
Code
1132function Player:update(dt)
1133 self.time = self.time + dt
1134
1135 -- print(string.format("-- [Player:update][%s] isEntered(%s) isServer(%s) isClient(%s) isControlled(%s)", tostring(self), tostring(self.isEntered), tostring(self.isServer), tostring(self.isClient), tostring(self.isControlled)))
1136 if not self.isEntered and self.isClient and self.isControlled then
1137 self:updateFX()
1138 end
1139
1140 -- check if the player is on ground
1141 if self.isServer or self.isEntered then
1142 local _, _, isOnGround = getCCTCollisionFlags(self.controllerIndex)
1143 self.baseInformation.isOnGroundPhysics = isOnGround
1144 end
1145
1146 if self.isClient and self.isControlled then
1147 self:updateWaterParms()
1148 self:updateSound()
1149 end
1150
1151 if self.isEntered and self.isClient and not g_gui:getIsGuiVisible() then
1152 if not g_currentMission.isPlayerFrozen then
1153 self:updatePlayerStates()
1154 self.playerStateMachine:update(dt)
1155 self:recordPositionInformation()
1156 self:cameraBob(dt)
1157 self:debugDraw()
1158 self.playerStateMachine:debugDraw(dt)
1159
1160 if not self.walkingIsLocked then
1161 self.rotX = self.rotX - self.inputInformation.pitchCamera * g_gameSettings:getValue(GameSettings.SETTING.CAMERA_SENSITIVITY)
1162 self.rotY = self.rotY - self.inputInformation.yawCamera * g_gameSettings:getValue(GameSettings.SETTING.CAMERA_SENSITIVITY)
1163
1164 self.rotX = math.min(1.2, math.max(-1.5, self.rotX))
1165 setRotation(self.cameraNode, self.rotX, self.rotY, 0)
1166 setRotation(self.foliageBendingNode, 0, self.rotY, 0)
1167 end
1168 self:updateActionEvents()
1169 end
1170 end
1171
1172 if self:hasHandtoolEquipped() then
1173 self.baseInformation.currentHandtool:update(dt, self:getIsInputAllowed())
1174
1175 if self.playerStateMachine:isActive("swim") then
1176 self:unequipHandtool()
1177 end
1178 end
1179
1180 self:updateInterpolation()
1181
1182 if self.isClient and self.isControlled then
1183 self:updateRotation(dt)
1184 end
1185
1186 -- animation
1187 if self.isClient and self.isControlled and not self.isEntered then
1188 self:updateAnimationParameters(dt)
1189 updateConditionalAnimation(self.animationInformation.player, dt)
1190
1191 -- Animation Debug
1192 --local a,b,c = getWorldTranslation(self.rootNode)
1193 --b = b + 1.0
1194 --conditionalAnimationDebugDraw(self.animationInformation.player, a,b,c)
1195 end
1196
1197 -- objects in front of player
1198 self:checkObjectInRange()
1199 -- if self.isEntered or (self.isControlled and self.networkInformation.interpolationTime.isDirty) then
1200 if self.isEntered or self.networkInformation.interpolationTime.isDirty then
1201 self:raiseActive()
1202 end
1203
1204 if self.isClient and self.isControlled and not self.isEntered and self.networkInformation.rotateObject then
1205 self:rotateObject(self.networkInformation.rotateObjectInputV, 1.0, 0.0, 0.0)
1206 self:rotateObject(self.networkInformation.rotateObjectInputH, 0.0, 1.0, 0.0)
1207 end
1208 self:resetCameraInputsInformation()
1209end

updateActionEvents

Description
Update action event states and input hint display.
Definition
updateActionEvents()
Code
1289function Player:updateActionEvents()
1290 -- light
1291 local isDark = g_currentMission.environment.currentHour > g_currentMission.environment.nightStart - 0.5 or g_currentMission.environment.currentHour < g_currentMission.environment.nightEnd + 0.5
1292 local eventIdToggleLight = self.inputInformation.registrationList[InputAction.TOGGLE_LIGHTS_FPS].eventId
1293 if self.playerStateMachine:isAvailable("useLight") and isDark then
1294 g_inputBinding:setActionEventTextVisibility(eventIdToggleLight, isDark and self.lightNode ~= nil)
1295 end
1296
1297 local eventList = self.inputInformation.registrationList
1298 function disableInput(inputAction)
1299 local id = eventList[inputAction].eventId
1300 g_inputBinding:setActionEventActive(id, false)
1301 g_inputBinding:setActionEventTextVisibility(id, false)
1302 end
1303
1304 function enableInput(inputAction)
1305 local id = eventList[inputAction].eventId
1306 g_inputBinding:setActionEventActive(id, true)
1307 g_inputBinding:setActionEventTextVisibility(id, true)
1308 end
1309
1310 disableInput(InputAction.NEXT_HANDTOOL)
1311 disableInput(InputAction.PREVIOUS_HANDTOOL)
1312 disableInput(InputAction.ACTIVATE_HANDTOOL)
1313 disableInput(InputAction.INTERACT)
1314 disableInput(InputAction.ACTIVATE_OBJECT)
1315 disableInput(InputAction.ENTER)
1316 disableInput(InputAction.THROW_OBJECT)
1317 disableInput(InputAction.ROTATE_OBJECT_LEFT_RIGHT)
1318 disableInput(InputAction.ROTATE_OBJECT_UP_DOWN)
1319
1320 -- tools
1321 if self.playerStateMachine:isAvailable("cycleHandtool") then
1322 enableInput(InputAction.NEXT_HANDTOOL)
1323 enableInput(InputAction.PREVIOUS_HANDTOOL)
1324 end
1325
1326
1327 if self:hasHandtoolEquipped() then
1328 enableInput(InputAction.ACTIVATE_HANDTOOL)
1329
1330 local eventIdActivateObject = self.inputInformation.registrationList[InputAction.ACTIVATE_OBJECT].eventId
1331 if self.playerStateMachine:isAvailable("activateObject") then
1332 enableInput(InputAction.ACTIVATE_OBJECT)
1333 local activateObjectState = self.playerStateMachine:getState("activateObject")
1334 g_inputBinding:setActionEventText(eventIdActivateObject, activateObjectState.activateText)
1335 end
1336 else
1337
1338 if self.playerStateMachine:isAvailable("throw") then
1339 enableInput(InputAction.THROW_OBJECT)
1340 end
1341
1342 local eventIdObjectRotateHorizontally = self.inputInformation.registrationList[InputAction.ROTATE_OBJECT_LEFT_RIGHT].eventId
1343 local eventIdObjectRotateVertically = self.inputInformation.registrationList[InputAction.ROTATE_OBJECT_UP_DOWN].eventId
1344 if self.isCarryingObject then
1345 enableInput(InputAction.ROTATE_OBJECT_LEFT_RIGHT)
1346 enableInput(InputAction.ROTATE_OBJECT_UP_DOWN)
1347 end
1348
1349 local eventIdActivateObject = self.inputInformation.registrationList[InputAction.ACTIVATE_OBJECT].eventId
1350 if self.playerStateMachine:isAvailable("activateObject") then
1351 enableInput(InputAction.ACTIVATE_OBJECT)
1352 local activateObjectState = self.playerStateMachine:getState("activateObject")
1353 g_inputBinding:setActionEventText(eventIdActivateObject, activateObjectState.activateText)
1354 elseif self.playerStateMachine:isAvailable("animalFeed") then
1355 enableInput(InputAction.ACTIVATE_OBJECT)
1356 g_inputBinding:setActionEventText(eventIdActivateObject, g_i18n:getText("action_feedAnimal"))
1357 elseif self.playerStateMachine:isAvailable("animalPet") then
1358 enableInput(InputAction.ACTIVATE_OBJECT)
1359 g_inputBinding:setActionEventText(eventIdActivateObject, g_i18n:getText("action_petAnimal"))
1360 end
1361
1362 local eventIdInteract = self.inputInformation.registrationList[InputAction.INTERACT].eventId
1363 if self.playerStateMachine:isAvailable("drop") then
1364 g_inputBinding:setActionEventText(eventIdInteract, g_i18n:getText("action_dropObject"))
1365 enableInput(InputAction.INTERACT)
1366 elseif self.playerStateMachine:isAvailable("pickup") then
1367 g_inputBinding:setActionEventText(eventIdInteract, g_i18n:getText("action_pickUpObject"))
1368 enableInput(InputAction.INTERACT)
1369 elseif self.playerStateMachine:isAvailable("animalInteract") or self.playerStateMachine:isActive("animalInteract") then
1370 local animalInteractState = self.playerStateMachine:getState("animalInteract")
1371 local animalInteractText = string.format(g_i18n:getText("action_interactAnimal"), animalInteractState.interactText)
1372 g_inputBinding:setActionEventText(eventIdInteract, animalInteractText)
1373 enableInput(InputAction.INTERACT)
1374 elseif self.inputInformation.interactState == Player.BUTTONSTATES.RELEASED then
1375 disableInput(InputAction.INTERACT)
1376 end
1377 end
1378
1379 -- enter vehicle or ride animal
1380 self.canRideAnimal = self.playerStateMachine:isAvailable("animalRide")
1381 self.canEnterVehicle = g_currentMission.interactiveVehicleInRange and g_currentMission.interactiveVehicleInRange:getIsEnterable()
1382 local vehicleIsRideable = self.canEnterVehicle and SpecializationUtil.hasSpecialization(Rideable, g_currentMission.interactiveVehicleInRange.specializations)
1383 local eventIdEnter = self.inputInformation.registrationList[InputAction.ENTER].eventId
1384 if self.canEnterVehicle and not vehicleIsRideable then
1385 g_inputBinding:setActionEventText(eventIdEnter, g_i18n:getText("button_enterVehicle"))
1386 enableInput(InputAction.ENTER)
1387 elseif self.canRideAnimal or vehicleIsRideable then
1388 local rideableName = ""
1389 if self.canRideAnimal then
1390 local rideState = self.playerStateMachine:getState("animalRide")
1391 rideableName = rideState:getRideableName()
1392 elseif vehicleIsRideable then
1393 rideableName = g_currentMission.interactiveVehicleInRange:getFullName()
1394 end
1395 g_inputBinding:setActionEventText(eventIdEnter, string.format(g_i18n:getText("action_rideAnimal"), rideableName))
1396 enableInput(InputAction.ENTER)
1397 end
1398
1399 -- debug movements
1400 local eventIdDebugFlyToggle = self.inputInformation.registrationList[InputAction.DEBUG_PLAYER_ENABLE].eventId
1401 g_inputBinding:setActionEventActive(eventIdDebugFlyToggle, g_flightAndNoHUDKeysEnabled)
1402 local eventIdDebugFlyUpDown = self.inputInformation.registrationList[InputAction.DEBUG_PLAYER_UP_DOWN].eventId
1403 g_inputBinding:setActionEventActive(eventIdDebugFlyUpDown, g_flightAndNoHUDKeysEnabled)
1404end

updateAnimationParameters

Description
Updates the parameters that will drive the animation
Definition
updateAnimationParameters(float dt)
Arguments
floatdtdelta time in ms
Code
1060function Player:updateAnimationParameters(dt)
1061 local dx = (self.networkInformation.interpolatorPosition.targetPositionX - self.networkInformation.interpolatorPosition.lastPositionX)
1062 local dy = (self.networkInformation.interpolatorPosition.targetPositionY - self.networkInformation.interpolatorPosition.lastPositionY)
1063 local dz = (self.networkInformation.interpolatorPosition.targetPositionZ - self.networkInformation.interpolatorPosition.lastPositionZ)
1064 local vx = dx / (self.networkInformation.interpolationTime.interpolationDuration * 0.001)
1065 local vy = dy / (self.networkInformation.interpolationTime.interpolationDuration * 0.001)
1066 local vz = dz / (self.networkInformation.interpolationTime.interpolationDuration * 0.001)
1067 local dirX, dirZ = math.sin(self.graphicsRotY), math.cos(self.graphicsRotY)
1068 local estimatedForwardVelocity = vx * dirX + vz * dirZ
1069 -- @see using calculation in Player:updateRotation() for a less unstable speed
1070 -- self.lastEstimatedForwardVelocity = self.lastEstimatedForwardVelocity * 0.5 + estimatedForwardVelocity * 0.5
1071
1072 if self.baseInformation.animDt ~= nil and self.baseInformation.animDt ~= 0 then
1073 self.animationInformation.oldYaw = self.animationInformation.newYaw
1074 self.animationInformation.newYaw = self.cameraRotY
1075 self.animationInformation.estimatedYawVelocity = MathUtil.getAngleDifference(self.animationInformation.newYaw, self.animationInformation.oldYaw) / (self.baseInformation.animDt * 0.001)
1076 self.baseInformation.animDt = 0
1077 end
1078
1079 local params = self.animationInformation.parameters
1080 params.forwardVelocity.value = self.lastEstimatedForwardVelocity
1081 params.verticalVelocity.value = vy
1082 params.yawVelocity.value = self.animationInformation.estimatedYawVelocity
1083 params.absYawVelocity.value = math.abs(self.animationInformation.estimatedYawVelocity)
1084 params.onGround.value = self.baseInformation.isOnGround
1085 params.inWater.value = self.baseInformation.isInWater
1086 params.isCrouched.value = self.baseInformation.isCrouched
1087 params.absForwardVelocity.value = math.abs(self.lastEstimatedForwardVelocity)
1088 params.isCloseToGround.value = self.baseInformation.isCloseToGround
1089 params.isUsingChainsawHorizontal.value = self.baseInformation.isUsingChainsawHorizontal
1090 params.isUsingChainsawVertical.value = self.baseInformation.isUsingChainsawVertical
1091
1092 for _, parameter in pairs(self.animationInformation.parameters) do
1093 if parameter.type == 0 then
1094 setConditionalAnimationBoolValue(self.animationInformation.player, parameter.id, parameter.value)
1095 elseif parameter.type == 1 then
1096 setConditionalAnimationFloatValue(self.animationInformation.player, parameter.id, parameter.value)
1097 end
1098 end
1099end

updateFX

Description
Update particle FX.
Definition
updateFX()
Code
2467function Player:updateFX()
2468 -- swim
2469 -- if self.baseInformation.isInWater then -- and self.motionInformation.justMoved then
2470 -- local x, _, z = getWorldTranslation(self.rootNode)
2471
2472 -- setWorldTranslation(self.particleSystemsInformation.swimNode, x, g_currentMission.waterY, z)
2473 -- ParticleUtil.setEmittingState(self.particleSystemsInformation.systems.swim, true)
2474 -- else
2475 -- ParticleUtil.resetNumOfEmittedParticles(self.particleSystemsInformation.systems.swim)
2476 -- ParticleUtil.setEmittingState(self.particleSystemsInformation.systems.swim, false)
2477 -- end
2478
2479 -- plunge
2480 if self.baseInformation.plungedInWater then
2481 local x, _, z = getWorldTranslation(self.rootNode)
2482
2483 setWorldTranslation(self.particleSystemsInformation.plungeNode, x, g_currentMission.waterY, z)
2484 ParticleUtil.resetNumOfEmittedParticles(self.particleSystemsInformation.systems.plunge)
2485 ParticleUtil.setEmittingState(self.particleSystemsInformation.systems.plunge, true)
2486 end
2487end

updateInterpolation

Description
Updates interpolations for physics, camera and position
Definition
updateInterpolation()
Code
1448function Player:updateInterpolation()
1449 if self.isControlled then
1450 local needsCameraInterp = self.isServer and not self.isEntered
1451 local needsPositionInterp = self.isClient
1452
1453 if needsCameraInterp or needsPositionInterp then
1454 if self.networkInformation.interpolationTime.isDirty then
1455 self.networkInformation.interpolationTime:update(g_physicsDtUnclamped)
1456 if needsCameraInterp then
1457 local qx, qy, qz, qw = self.networkInformation.interpolatorQuaternion:getInterpolatedValues(self.networkInformation.interpolationTime.interpolationAlpha)
1458
1459 setQuaternion(self.cameraNode, qx, qy, qz, qw)
1460 end
1461 if needsPositionInterp then
1462 local x, y, z = self.networkInformation.interpolatorPosition:getInterpolatedValues(self.networkInformation.interpolationTime.interpolationAlpha)
1463 setTranslation(self.graphicsRootNode, x, y - self.baseInformation.capsuleTotalHeight * 0.5, z)
1464 local isOnGroundFloat = self.networkInformation.interpolatorOnGround:getInterpolatedValue(self.networkInformation.interpolationTime.interpolationAlpha)
1465 self.baseInformation.isOnGround = isOnGroundFloat > 0.9
1466 self.baseInformation.isCloseToGround = isOnGroundFloat > 0.5
1467 end
1468 end
1469 end
1470 end
1471end

updateInterpolationTick

Description
Updates interpolations for physics, camera and position
Definition
updateInterpolationTick()
Code
1408function Player:updateInterpolationTick()
1409 if self.isEntered then
1410 local xt, yt, zt = getTranslation(self.rootNode)
1411 -- Reuse the existing target position if the change is very small to avoid jitter
1412 local interpPos = self.networkInformation.interpolatorPosition
1413 if math.abs(xt-interpPos.targetPositionX) < 0.001 and math.abs(yt-interpPos.targetPositionY) < 0.001 and math.abs(zt-interpPos.targetPositionZ) < 0.001 then
1414 xt, yt, zt = interpPos.targetPositionX, interpPos.targetPositionY, interpPos.targetPositionZ
1415 end
1416 self.networkInformation.interpolatorPosition:setTargetPosition(xt, yt, zt)
1417
1418 if self.baseInformation.isOnGroundPhysics then
1419 self.networkInformation.interpolatorOnGround:setTargetValue(1.0)
1420 else
1421 self.networkInformation.interpolatorOnGround:setTargetValue(0.0)
1422 end
1423 self.networkInformation.interpolationTime:startNewPhase(75)
1424 elseif self.networkInformation.updateTargetTranslationPhysicsIndex >= 0 then
1425 local xt, yt, zt = getTranslation(self.rootNode)
1426 if getIsPhysicsUpdateIndexSimulated(self.networkInformation.updateTargetTranslationPhysicsIndex) then
1427 self.networkInformation.updateTargetTranslationPhysicsIndex = -1
1428 else
1429 -- Reuse the existing target position if the change is very small to avoid jitter
1430 local interpPos = self.networkInformation.interpolatorPosition
1431 if math.abs(xt-interpPos.targetPositionX) < 0.001 and math.abs(yt-interpPos.targetPositionY) < 0.001 and math.abs(zt-interpPos.targetPositionZ) < 0.001 then
1432 xt, yt, zt = interpPos.targetPositionX, interpPos.targetPositionY, interpPos.targetPositionZ
1433 end
1434 end
1435 self.networkInformation.interpolatorPosition:setTargetPosition(xt, yt, zt)
1436 if self.baseInformation.isOnGroundPhysics then
1437 self.networkInformation.interpolatorOnGround:setTargetValue(1.0)
1438 else
1439 self.networkInformation.interpolatorOnGround:setTargetValue(0.0)
1440 end
1441 self.networkInformation.interpolatorQuaternion:setTargetQuaternion(self.networkInformation.interpolatorQuaternion.targetQuaternionX, self.networkInformation.interpolatorQuaternion.targetQuaternionY, self.networkInformation.interpolatorQuaternion.targetQuaternionZ, self.networkInformation.interpolatorQuaternion.targetQuaternionW)
1442 self.networkInformation.interpolationTime:startNewPhase(75)
1443 end
1444end

updateKinematic

Description
Updates player movement depending on inputs (run, crouch, swim) and apply gravity
Definition
updateKinematic()
Code
2710function Player:updateKinematic(dt)
2711 local dtInSec = dt * 0.001
2712 local inputX = self.inputInformation.moveRight
2713 local inputZ = self.inputInformation.moveForward
2714 if inputX ~= 0.0 or inputZ ~= 0.0 then
2715 local normInputX, normInputZ = MathUtil.vector2Normalize(inputX, inputZ)
2716 self.motionInformation.currentWorldDirX, _, self.motionInformation.currentWorldDirZ = localDirectionToWorld(self.cameraNode, normInputX, 0.0, normInputZ)
2717 self.motionInformation.currentWorldDirX, self.motionInformation.currentWorldDirZ = MathUtil.vector2Normalize(self.motionInformation.currentWorldDirX, self.motionInformation.currentWorldDirZ)
2718 end
2719 local desiredSpeed = self:getDesiredSpeed()
2720 local desiredSpeedX = self.motionInformation.currentWorldDirX * desiredSpeed
2721 local desiredSpeedZ = self.motionInformation.currentWorldDirZ * desiredSpeed
2722
2723 local speedChangeX = (desiredSpeedX - self.motionInformation.currentSpeedX)
2724 local speedChangeZ = (desiredSpeedZ - self.motionInformation.currentSpeedZ)
2725
2726 if not self.baseInformation.isOnGround then
2727 -- reduce acceleration when in the air
2728 speedChangeX = speedChangeX * 0.2
2729 speedChangeZ = speedChangeZ * 0.2
2730 end
2731
2732 self.motionInformation.currentSpeedX = self.motionInformation.currentSpeedX + speedChangeX
2733 self.motionInformation.currentSpeedZ = self.motionInformation.currentSpeedZ + speedChangeZ
2734 self.motionInformation.currentSpeed = math.sqrt(self.motionInformation.currentSpeedX * self.motionInformation.currentSpeedX + self.motionInformation.currentSpeedZ * self.motionInformation.currentSpeedZ)
2735
2736 local movementX = self.motionInformation.currentSpeedX * dtInSec
2737 local movementY = 0.0
2738 local movementZ = self.motionInformation.currentSpeedZ * dtInSec
2739
2740 -- Swim adjustment
2741 local _, y, _ = getWorldTranslation(self.rootNode)
2742 local deltaWater = y - g_currentMission.waterY - self.baseInformation.capsuleTotalHeight * 0.5
2743 local waterLevel = self.baseInformation.waterLevel
2744
2745 local distToWaterLevel = deltaWater - waterLevel
2746
2747 if distToWaterLevel > 0.001 then
2748 -- Update gravity / vertical movement
2749 local gravityFactor = 3.0 -- for falling faster
2750 local gravitySpeedChange = gravityFactor * self.motionInformation.gravity * dtInSec
2751 self.motionInformation.currentSpeedY = math.max(self.motionInformation.currentSpeedY + gravitySpeedChange, self.motionInformation.gravity * 7.0) -- clamp after 7s of falling
2752 if distToWaterLevel < self.baseInformation.capsuleTotalHeight * 0.5 then
2753 -- hack to reduce unsteability in low framerate
2754 movementY = math.max(self.motionInformation.currentSpeedY * dtInSec, -distToWaterLevel * 0.5)
2755 else
2756 movementY = math.max(self.motionInformation.currentSpeedY * dtInSec, -distToWaterLevel)
2757 end
2758 self.motionInformation.currentSpeedY = movementY / math.max(dtInSec, 0.000001) -- calc actual speed with clamped movement
2759 elseif distToWaterLevel < -0.01 then
2760 local buoyancySpeed = -self.motionInformation.gravity
2761 movementY = math.min(buoyancySpeed * dtInSec, -distToWaterLevel)
2762 self.motionInformation.currentSpeedY = movementY / math.max(dtInSec, 0.000001) -- calc actual speed with clamped movement
2763 else
2764 self.motionInformation.currentSpeedY = 0.0
2765 end
2766
2767 self:movePlayer(dt, movementX, movementY, movementZ)
2768end

updateNetworkMovementHistory

Description
Definition
updateNetworkMovementHistory()
Code
1475function Player:updateNetworkMovementHistory()
1476 if self.isEntered and self.isClient then
1477 self:raiseDirtyFlags(self.networkInformation.dirtyFlag)
1478 elseif self.isServer and not self.isEntered and self.isControlled then
1479 -- find the latest index, which is already simulated now
1480 local latestSimulatedIndex = -1
1481 while self.networkInformation.history[1] ~= nil and getIsPhysicsUpdateIndexSimulated(self.networkInformation.history[1].physicsIndex) do
1482 latestSimulatedIndex = self.networkInformation.history[1].index
1483 table.remove(self.networkInformation.history, 1)
1484 end
1485 if latestSimulatedIndex >= 0 then
1486 self.networkInformation.sendIndex = latestSimulatedIndex
1487 self:raiseDirtyFlags(self.networkInformation.dirtyFlag)
1488 end
1489 end
1490end

updatePlayerStates

Description
Updates player state machine
Definition
updatePlayerStates()
Code
2772function Player:updatePlayerStates()
2773 if self.playerStateMachine:isAvailable("fall") then
2774 self.playerStateMachine:activateState("fall")
2775 end
2776
2777 if self.baseInformation.isInWater and self.playerStateMachine:isAvailable("swim") then
2778 self.playerStateMachine:activateState("swim")
2779 self.playerStateMachine:deactivateState("crouch")
2780 end
2781
2782 if (self.inputInformation.moveForward ~= 0) or (self.inputInformation.moveRight ~= 0) then
2783 if (self.inputInformation.runAxis > 0.0) and self.playerStateMachine:isAvailable("run") then
2784 self.playerStateMachine:activateState("run")
2785 elseif self.playerStateMachine:isAvailable("walk") then
2786 self.playerStateMachine:activateState("walk")
2787 end
2788 else
2789 self.playerStateMachine:activateState("idle")
2790 end
2791end

updatePlayHandToolStopSample

Description
Definition
updatePlayHandToolStopSample()
Code
2290function Player:updatePlayHandToolStopSample()
2291 if self.soundInformation.deleteHandtoolStopSampleAfterPlay and self.soundInformation.samples.handtoolStop.soundSample ~= nil and not g_soundManager:getIsSamplePlaying(self.soundInformation.samples.handtoolStop) then
2292 self:deleteHandToolStopSample()
2293 end
2294end

updateRotation

Description
Updates rotation of player avatar over the network
Definition
updateRotation(float dt)
Arguments
floatdtdelta time in ms
Code
1495function Player:updateRotation(dt)
1496 if not self.isEntered then
1497 local animDt = 60
1498 self.animUpdateTime = self.animUpdateTime + dt
1499 if self.animUpdateTime > animDt then
1500 if self.isServer then
1501 local x, _, z = localDirectionToLocal(self.cameraNode, getParent(self.cameraNode), 0, 0, 1)
1502 local alpha = math.atan2(x, z)
1503 self.cameraRotY = alpha
1504 end
1505
1506 local x, y, z = getTranslation(self.graphicsRootNode)
1507 local dx, _, dz = x - self.lastAnimPosX, y - self.lastAnimPosY, z - self.lastAnimPosZ
1508 local dirX, dirZ = -math.sin(self.cameraRotY), -math.cos(self.cameraRotY)
1509 local movementDist = dx * dirX + dz * dirZ -- Note: |dir| = 1
1510
1511 if (dx * dx + dz * dz) < 0.001 then
1512 self.targetGraphicsRotY = self.cameraRotY + math.rad(180.0)
1513 else
1514 if movementDist > -0.001 then
1515 self.targetGraphicsRotY = math.atan2(dx, dz)
1516 else
1517 self.targetGraphicsRotY = math.atan2(-dx, -dz)
1518 end
1519 end
1520
1521 dirX, dirZ = -math.sin(self.targetGraphicsRotY), -math.cos(self.targetGraphicsRotY)
1522 movementDist = dx * dirX + dz * dirZ -- Note: |dir| = 1
1523 movementDist = self.walkDistance * 0.2 + movementDist * 0.8
1524 self.walkDistance = movementDist
1525 self.lastEstimatedForwardVelocity = -movementDist / (self.animUpdateTime * 0.001)
1526
1527 self.lastAnimPosX = x
1528 self.lastAnimPosY = y
1529 self.lastAnimPosZ = z
1530
1531 self.baseInformation.animDt = self.animUpdateTime
1532 self.animUpdateTime = 0
1533 end
1534
1535 self.targetGraphicsRotY = MathUtil.normalizeRotationForShortestPath(self.targetGraphicsRotY, self.graphicsRotY)
1536 local maxDeltaRotY = math.rad(0.5) * dt
1537 self.graphicsRotY = math.min(math.max(self.targetGraphicsRotY, self.graphicsRotY - maxDeltaRotY), self.graphicsRotY + maxDeltaRotY)
1538
1539 setRotation(self.skeletonRootNode, 0, self.graphicsRotY, 0)
1540 end
1541end

updateSound

Description
Update sound for the player: steps (when crouch, walk, run), swim, plunge
Definition
updateSound()
Code
2388function Player:updateSound()
2389 -- Foot steps
2390 local distanceToCheck = -1.0
2391 local forwardVel = 0.0
2392
2393 if not self.isEntered then
2394 forwardVel = getConditionalAnimationFloatValue(self.animationInformation.player, self.animationInformation.parameters.absForwardVelocity.id)
2395 if self.playerStateMachine:isActive("crouch") then
2396 distanceToCheck = self.soundInformation.distancePerFootstep.crouch
2397 elseif math.abs(forwardVel) <= self.motionInformation.maxWalkingSpeed then
2398 distanceToCheck = self.soundInformation.distancePerFootstep.walk
2399 elseif math.abs(forwardVel) > self.motionInformation.maxWalkingSpeed then
2400 distanceToCheck = self.soundInformation.distancePerFootstep.run
2401 end
2402 else
2403 forwardVel = math.abs(self.motionInformation.currentSpeed)
2404 if self.playerStateMachine:isActive("crouch") then
2405 distanceToCheck = self.soundInformation.distancePerFootstep.crouch
2406 elseif self.playerStateMachine:isActive("walk") then
2407 distanceToCheck = self.soundInformation.distancePerFootstep.walk
2408 elseif self.playerStateMachine:isActive("run") then
2409 distanceToCheck = self.soundInformation.distancePerFootstep.run
2410 end
2411 end
2412
2413 local isSwimming = self.playerStateMachine:isActive("swim")
2414 if distanceToCheck > 0.0 or isSwimming then
2415 local delta = self.motionInformation.coveredGroundDistance - self.soundInformation.distanceSinceLastFootstep
2416 delta = delta - distanceToCheck
2417
2418 if delta > 0 or isSwimming then
2419 local wx, wy, wz = getWorldTranslation(self.rootNode)
2420 local sample, shallowWater = self:getCurrentSurfaceSound(wx, wy, wz)
2421
2422 if not self.baseInformation.isInWater then
2423 if g_soundManager:getIsSamplePlaying(self.soundInformation.samples.swim) then
2424 g_soundManager:stopSample(self.soundInformation.samples.swim)
2425 end
2426 if g_soundManager:getIsSamplePlaying(self.soundInformation.samples.swimIdle) then
2427 g_soundManager:stopSample(self.soundInformation.samples.swimIdle)
2428 end
2429 end
2430
2431 if self.baseInformation.isInWater and not shallowWater then
2432 if math.abs(forwardVel) < (self.motionInformation.maxSwimmingSpeed * 0.75) then
2433 if g_soundManager:getIsSamplePlaying(self.soundInformation.samples.swim) then
2434 g_soundManager:stopSample(self.soundInformation.samples.swim)
2435 end
2436 if not g_soundManager:getIsSamplePlaying(self.soundInformation.samples.swimIdle) then
2437 g_soundManager:playSample(self.soundInformation.samples.swimIdle)
2438 end
2439 else
2440 if g_soundManager:getIsSamplePlaying(self.soundInformation.samples.swimIdle) then
2441 g_soundManager:stopSample(self.soundInformation.samples.swimIdle)
2442 end
2443 if not g_soundManager:getIsSamplePlaying(self.soundInformation.samples.swim) then
2444 g_soundManager:playSample(self.soundInformation.samples.swim)
2445 end
2446 end
2447 else
2448 if sample ~= nil then
2449 g_soundManager:playSample(sample)
2450 end
2451 end
2452 self.soundInformation.distanceSinceLastFootstep = self.motionInformation.coveredGroundDistance + delta
2453 end
2454 end
2455
2456 -- plunge
2457 if self.baseInformation.plungedInWater then
2458 g_soundManager:playSample(self.soundInformation.samples.plunge)
2459 end
2460
2461 -- handTools
2462 self:updatePlayHandToolStopSample()
2463end

updateTick

Description
Update function called when network ticks. Takes care of movements/position, player state machine, interpolation phase, physics, handtools. Inputs are reset here.
Definition
updateTick(float dt)
Arguments
floatdtdelta time in ms
Code
1242function Player:updateTick(dt)
1243 if self.isEntered and not g_gui:getIsGuiVisible() and not g_currentMission.isPlayerFrozen then
1244 self:updateKinematic(dt)
1245 end
1246
1247 self.playerStateMachine:updateTick(dt)
1248
1249 if self:hasHandtoolEquipped() then
1250 self.baseInformation.currentHandtool:updateTick(dt, self:getIsInputAllowed())
1251 end
1252 self:updateNetworkMovementHistory()
1253 self:updateInterpolationTick()
1254
1255 self:resetInputsInformation()
1256
1257
1258 -- -------------------------
1259 -- @todo: check and add again
1260 -- -------------------------
1261 -- local xt, yt, zt = getTranslation(self.rootNode)
1262 -- --[[
1263 -- if GS_PLATFORM_TYPE == GS_PLATFORM_TYPE_PS4 or GS_PLATFORM_TYPE == GS_PLATFORM_TYPE_XBOXONE then
1264 -- xt = xt + self.movementX
1265 -- zt = zt + self.movementZ
1266 -- yt = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, xt, 300, zt) + self.height
1267 -- setTranslation(self.rootNode, xt, yt, zt)
1268 -- end
1269 -- --]]
1270 -- -------------------------
1271 if self.isServer and self.isControlled then
1272 if GS_PLATFORM_TYPE ~= GS_PLATFORM_TYPE_PC then
1273 local x, y, z = getTranslation(self.rootNode)
1274 local paramsXZ = g_currentMission.vehicleXZPosCompressionParams
1275 if not NetworkUtil.getIsWorldPositionInCompressionRange(x, paramsXZ) or
1276 not NetworkUtil.getIsWorldPositionInCompressionRange(z, paramsXZ) or
1277 getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, x, y, z) > y + 20
1278 then
1279 self:moveTo(g_currentMission.playerStartX, g_currentMission.playerStartY, g_currentMission.playerStartZ, g_currentMission.playerStartIsAbsolute, false)
1280 return
1281 end
1282 end
1283 end
1284 -- -------------------------
1285end

updateWaterParms

Description
Updates information related to the player and the water level. It is used for particle effects when plunging and checking if the player is in water.
Definition
updateWaterParms()
Code
1103function Player:updateWaterParms()
1104 local _, y, _ = getWorldTranslation(self.rootNode)
1105 local deltaWater = y - g_currentMission.waterY - self.baseInformation.capsuleTotalHeight * 0.5
1106 local waterLevel = self.baseInformation.waterLevel
1107 local velocityY = 0.0
1108
1109 if deltaWater < -50 then
1110 return
1111 end
1112
1113 if not self.isEntered then
1114 velocityY = self.animationInformation.parameters.verticalVelocity.value
1115 else
1116 velocityY = self.motionInformation.currentSpeedY
1117 end
1118
1119 self.baseInformation.wasInWater = self.baseInformation.isInWater
1120 self.baseInformation.isInWater = deltaWater <= waterLevel
1121
1122 if not self.baseInformation.wasInWater and self.baseInformation.isInWater and velocityY < self.baseInformation.plungedYVelocityThreshold then
1123 self.baseInformation.plungedInWater = true
1124 else
1125 self.baseInformation.plungedInWater = false
1126 end
1127end

writeStream

Description
Writes in network stream
Definition
writeStream(integer streamId, table connection)
Arguments
integerstreamIdid of the stream to read
tableconnectionconnection information
Code
805function Player:writeStream(streamId, connection)
806 Player:superClass().writeStream(self, streamId)
807 streamWriteBool(streamId, connection == self.networkInformation.creatorConnection)
808 streamWriteString(streamId, NetworkUtil.convertToNetworkFilename(self.xmlFilename))
809 local x, y, z=getTranslation(self.rootNode)
810 streamWriteFloat32(streamId, x)
811 streamWriteFloat32(streamId, y)
812 streamWriteFloat32(streamId, z)
813 streamWriteBool(streamId, self.isControlled)
814 self.visualInformation:writeStream(streamId, connection)
815 streamWriteUIntN(streamId, self.farmId, FarmManager.FARM_ID_SEND_NUM_BITS)
816
817 streamWriteBool(streamId, self.isLightActive)
818
819 local hasHandtool = self:hasHandtoolEquipped()
820 streamWriteBool(streamId, hasHandtool)
821 if hasHandtool then
822 streamWriteString(streamId, NetworkUtil.convertToNetworkFilename(self.baseInformation.currentHandtool.configFileName))
823 end
824end

writeUpdateStream

Description
Writes to network stream via update
Definition
writeUpdateStream(integer streamId, integer timestamp, table connection)
Arguments
integerstreamIdid of the stream to read
integertimestamptimestamp of the packet
tableconnectionconnection information
Code
974function Player:writeUpdateStream(streamId, connection, dirtyMask)
975 if not connection:getIsServer() then
976 -- server code (send data to client)
977 local x, y, z = getTranslation(self.rootNode)
978 --print("SERVER ( "..tostring(self).."/"..tostring(self.controllerName).."/"..tostring(self.networkInformation.creatorConnection).." ): x/y/z="..tostring(x).." / "..tostring(y).." / "..tostring(z).." self.sendIndex="..tostring(self.networkInformation.sendIndex))
979 streamWriteFloat32(streamId, x)
980 streamWriteFloat32(streamId, y)
981 streamWriteFloat32(streamId, z)
982
983 local x, _, z = localDirectionToLocal(self.cameraNode, getParent(self.cameraNode), 0, 0, 1)
984 local alpha = math.atan2(x, z)
985 streamWriteFloat32(streamId, alpha)
986
987 streamWriteBool(streamId, self.isObjectInRange)
988 if self.isObjectInRange then
989 streamWriteFloat32(streamId, self.lastFoundObjectMass)
990 end
991 streamWriteBool(streamId, self.isCarryingObject)
992 streamWriteBool(streamId, self.baseInformation.isOnGroundPhysics)
993 local isOwner = connection == self.networkInformation.creatorConnection
994 if isOwner then
995 streamWriteInt32(streamId, self.networkInformation.sendIndex)
996 -- [animation]
997 local isCrouching = self.baseInformation.isCrouched
998 streamWriteBool(streamId, isCrouching)
999 --
1000 else
1001 streamWriteBool(streamId, self.isControlled)
1002 -- [animation]
1003 local isCrouching = self.baseInformation.isCrouched or self.playerStateMachine:isActive("crouch")
1004 streamWriteBool(streamId, isCrouching)
1005 --
1006 end
1007 else
1008 -- client code (send data to server)
1009 if self.isOwner then
1010 -- sending translation information to the server and reset the translations accumulated over the update() calls
1011 streamWriteFloat32(streamId, self.networkInformation.tickTranslation[1])
1012 streamWriteFloat32(streamId, self.networkInformation.tickTranslation[2])
1013 streamWriteFloat32(streamId, self.networkInformation.tickTranslation[3])
1014 self.networkInformation.tickTranslation[1] = 0.0
1015 self.networkInformation.tickTranslation[2] = 0.0
1016 self.networkInformation.tickTranslation[3] = 0.0
1017 local x, y, z, w = getQuaternion(self.cameraNode)
1018 streamWriteFloat32(streamId, x) -- ? ToDo: Utils.writeCompressedQuaternion()
1019 streamWriteFloat32(streamId, y)
1020 streamWriteFloat32(streamId, z)
1021 streamWriteFloat32(streamId, w)
1022
1023 streamWriteInt32(streamId, self.networkInformation.index)
1024 streamWriteBool(streamId, self.isControlled)
1025 -- [animation]
1026 local isCrouching = self.playerStateMachine:isActive("crouch")
1027 streamWriteBool(streamId, isCrouching)
1028 --
1029 if self.isCarryingObject then
1030 streamWriteBool(streamId, self.networkInformation.rotateObject)
1031 if self.networkInformation.rotateObject then
1032 streamWriteFloat32(streamId, self.networkInformation.rotateObjectInputH)
1033 streamWriteFloat32(streamId, self.networkInformation.rotateObjectInputV)
1034 end
1035 end
1036 end
1037 end
1038end