LUADOC - Farming Simulator 22

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.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

activateRideState

Description
Definition
activateRideState()
Code
3205function Player:activateRideState()
3206 if not self.playerStateMachine:isActive("animalRide") then
3207 self.playerStateMachine:activateState("animalRide")
3208 end
3209end

calculate2DDotProductAgainstVelocity

Description
Definition
calculate2DDotProductAgainstVelocity()
Code
2614function Player:calculate2DDotProductAgainstVelocity(velocity, currentSpeed, vector)
2615 local normalizedVelX = velocity[1] / currentSpeed
2616 local normalizedVelZ = velocity[3] / currentSpeed
2617 local vectorMagnitude = math.sqrt(vector[1] * vector[1] + vector[3] * vector[3])
2618 local normalizedVectorX = vector[1] / vectorMagnitude
2619 local normalizedVectorZ = vector[3] / vectorMagnitude
2620 local dot = normalizedVelX * normalizedVectorX + normalizedVelZ * normalizedVectorZ
2621
2622 return dot
2623end

cameraBob

Description
Apply bobbing to the camera to imitate waves or footsteps.
Definition
cameraBob()
Code
2431function Player:cameraBob(dt)
2432 local amplitude = 0.0
2433 local isSwimming = self.playerStateMachine:isActive("swim")
2434 local isWalking = self.playerStateMachine:isActive("walk")
2435 local isCrouching = self.playerStateMachine:isActive("crouch")
2436 local isRunning = self.playerStateMachine:isActive("run")
2437 local targetCameraOffset = 0.0
2438 local dtInSec = dt * 0.001
2439
2440 if isSwimming then
2441 amplitude = 0.045
2442 targetCameraOffset = self.baseInformation.waterCameraOffset
2443 elseif isCrouching then
2444 amplitude = 0.045
2445 elseif isWalking or isRunning then
2446 amplitude = 0.025
2447 end
2448
2449 if self.baseInformation.currentWaterCameraOffset ~= targetCameraOffset then
2450 local deltaOffset = targetCameraOffset - self.baseInformation.currentWaterCameraOffset
2451 if math.abs(deltaOffset) > 0.001 then
2452 self.baseInformation.currentWaterCameraOffset = self.baseInformation.currentWaterCameraOffset + deltaOffset * dtInSec / 0.75
2453 else
2454 self.baseInformation.currentWaterCameraOffset = self.baseInformation.currentWaterCameraOffset + deltaOffset
2455 end
2456 if math.abs(targetCameraOffset) > 0.001 then
2457 self.baseInformation.currentWaterCameraOffset = MathUtil.clamp(self.baseInformation.currentWaterCameraOffset, 0, targetCameraOffset)
2458 else
2459 self.baseInformation.currentWaterCameraOffset = math.max(self.baseInformation.currentWaterCameraOffset, 0)
2460 end
2461 end
2462
2463 local delta
2464 if amplitude ~= 0.0 then
2465 local actualSpeed = self.motionInformation.currentCoveredGroundDistance / dtInSec
2466 local dtInSecClamped = math.min(dtInSec, 0.06)
2467 local timeOffset, amplitudeScale
2468
2469 if isSwimming then
2470 timeOffset = math.min(math.max(self.motionInformation.currentCoveredGroundDistance * 1.0, 0.6 * dtInSecClamped), 3.0 * dtInSecClamped * 1.0)
2471 amplitudeScale = math.min(math.max(actualSpeed / 3.0, 0.5), 1.0)
2472 else
2473 timeOffset = math.min(self.motionInformation.currentCoveredGroundDistance, 3.0 * dtInSecClamped) * 3.0
2474 amplitudeScale = math.min(actualSpeed / 3.0, 1.0)
2475 end
2476
2477 self.baseInformation.headBobTime = self.baseInformation.headBobTime + timeOffset
2478 amplitudeScale = (self.baseInformation.lastCameraAmplitudeScale + amplitudeScale) * 0.5
2479 delta = amplitudeScale * amplitude * math.sin(self.baseInformation.headBobTime) + self.baseInformation.currentWaterCameraOffset
2480 self.baseInformation.lastCameraAmplitudeScale = amplitudeScale
2481 else
2482 delta = self.baseInformation.currentWaterCameraOffset
2483 end
2484
2485 return delta
2486end

checkObjectInRange

Description
Definition
checkObjectInRange()
Code
2078function Player:checkObjectInRange()
2079 -- handle picking up of objects
2080 if self.isServer then
2081 if not self.isCarryingObject then
2082 local x,y,z = localToWorld(self.cameraNode, 0,0,1.0)
2083 local dx,dy,dz = localDirectionToWorld(self.cameraNode, 0,0,-1)
2084 self.lastFoundObject = nil
2085 self.lastFoundObjectHitPoint = nil
2086 self.lastFoundAnyObject = nil
2087 raycastAll(x,y,z, dx,dy,dz, "pickUpObjectRaycastCallback", Player.MAX_PICKABLE_OBJECT_DISTANCE, self)
2088 self.isObjectInRange = self.lastFoundObject ~= nil
2089--#debug self.raycastCallbackIndex = 0
2090
2091 self.hudUpdater:setCurrentRaycastTarget(self.lastFoundAnyObject)
2092 else
2093 -- check if object still exists
2094 if self.pickedUpObject ~= nil then
2095 if not entityExists(self.pickedUpObject) then
2096 Player.PICKED_UP_OBJECTS[self.pickedUpObject] = false
2097 self.pickedUpObject = nil
2098 self.pickedUpObjectJointId = nil
2099 self.isCarryingObject = false
2100 end
2101 end
2102 end
2103 else
2104 -- Update HUD on client too
2105 if not self.isCarryingObject then
2106 local x,y,z = localToWorld(self.cameraNode, 0,0,1.0)
2107 local dx,dy,dz = localDirectionToWorld(self.cameraNode, 0,0,-1)
2108
2109 self.lastFoundAnyObject = nil
2110 raycastAll(x,y,z, dx,dy,dz, "pickUpObjectRaycastCallback", Player.MAX_PICKABLE_OBJECT_DISTANCE, self)
2111--#debug self.raycastCallbackIndex = 0
2112
2113 self.hudUpdater:setCurrentRaycastTarget(self.lastFoundAnyObject)
2114 end
2115 end
2116end

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
1751function Player.consoleCommandReloadIKChains(unusedSelf)
1752 local player = g_currentMission.player
1753 local style = player.model.style
1754
1755 local newModel = PlayerModel.new()
1756 newModel:load(player.model.style.xmlFilename, true, player.isOwner, true, function(_, success, _)
1757 if success then
1758 player:setModel(newModel)
1759 player:setStyle(style, false)
1760
1761 g_messageCenter:publish(MessageType.PLAYER_STYLE_CHANGED, style, player.userId)
1762
1763 log("Finished reload")
1764 end
1765 end, nil, nil)
1766end

consoleCommandThirdPersonView

Description
Toggle player debug info display
Definition
consoleCommandThirdPersonView()
Return Values
stringthatwill be displayed on console
Code
2766function Player:consoleCommandThirdPersonView()
2767 self:setThirdPersonViewActive(not self.thirdPersonViewActive)
2768
2769 return "Player Third Person = " .. tostring(self.thirdPersonViewActive)
2770end

consoleCommandToggleFlightMode

Description
Toggle flight mode
Definition
consoleCommandToggleFlightMode()
Return Values
stringthatwill be displayed on console
Code
1652function Player:consoleCommandToggleFlightMode()
1653 local usage = "Use key J to en-/disable flight mode, keys Q and E change the altitude. No Hud Mode was moved to gsHudVisibility"
1654 g_flightModeEnabled = not g_flightModeEnabled
1655 if not g_flightModeEnabled then
1656 self.debugFlightMode = false -- force reset flight mode
1657 end
1658
1659 if GS_IS_MOBILE_VERSION then
1660 g_currentMission:onLeaveVehicle()
1661 end
1662 if g_flightModeEnabled then
1663 print(usage)
1664 end
1665 return "PlayerFlightMode = " .. tostring(g_flightModeEnabled)
1666end

consoleCommandToggleNoClipMode

Description
Toggle player CCT no clip mode
Definition
consoleCommandToggleNoClipMode()
Code
1670function Player:consoleCommandToggleNoClipMode(disableTerrainCollision)
1671 local usage = "Usage: gsPlayerNoClip [disableTerrainCollision]"
1672 local ret
1673 disableTerrainCollision = Utils.stringToBoolean(disableTerrainCollision)
1674
1675 self.noClipEnabled = not self.noClipEnabled
1676 if self.noClipEnabled then
1677 self.cctMovementCollisionMaskBackup = self.cctMovementCollisionMask
1678 self.cctMovementCollisionMask = (disableTerrainCollision and 0) or CollisionFlag.TERRAIN
1679 ret = string.format("Enabled player noClip mode (%s)", (disableTerrainCollision and "including terrain") or "excluding terrain")
1680 else
1681 self.cctMovementCollisionMask = self.cctMovementCollisionMaskBackup
1682 self.cctMovementCollisionMaskBackup = nil
1683 ret = "Disabled player noClip mode"
1684 end
1685
1686 return string.format("%s\n%s", ret, usage)
1687end

consoleCommandTogglePickupRaycastDebug

Description
Toggle player pickup raycast debug: displays nodeId, node name, colMask and triggerProperty of hit nodes
Definition
consoleCommandTogglePickupRaycastDebug()
Code
1722function Player:consoleCommandTogglePickupRaycastDebug()
1723 self.pickupRaycastDebugEnabled = not self.pickupRaycastDebugEnabled
1724 return "pickupRaycastDebugEnabled=" .. tostring(self.pickupRaycastDebugEnabled)
1725end

consoleCommandTogglePlayerDebug

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

consoleCommandToggleSuperStrongMode

Description
Toggle super-strength mode
Definition
consoleCommandToggleSuperStrongMode()
Code
1700function Player:consoleCommandToggleSuperStrongMode()
1701 if self.superStrengthEnabled then
1702 self.superStrengthEnabled = false
1703 Player.MAX_PICKABLE_OBJECT_MASS = self.superStrengthPickupMassBackup
1704 Player.MAX_PICKABLE_OBJECT_DISTANCE = self.superStrengthPickupDistanceBackup
1705 self.superStrengthPickupMassBackup = nil
1706
1707 return "Player now has normal strength"
1708 else
1709 self.superStrengthEnabled = true
1710 self.superStrengthPickupMassBackup = Player.MAX_PICKABLE_OBJECT_MASS
1711 Player.MAX_PICKABLE_OBJECT_MASS = 50
1712 self.superStrengthPickupDistanceBackup = Player.MAX_PICKABLE_OBJECT_DISTANCE
1713 Player.MAX_PICKABLE_OBJECT_DISTANCE = 6.0
1714
1715 return "Player now has super-strength and increased range"
1716 end
1717end

consoleCommandToggleWoodCuttingMaker

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

debugDraw

Description
Prints player debug information regarding motion and input.
Definition
debugDraw()
Code
2521function Player:debugDraw()
2522 if (self.baseInformation.isInDebug) then
2523 setTextColor(1, 0, 0, 1)
2524 local line = 0.96
2525 renderText(0.05, line, 0.02, "[motion]"); line = line - 0.02
2526 renderText(0.05, line, 0.02, string.format("isOnGround(%s) ", tostring(self.baseInformation.isOnGround))); line = line - 0.02
2527 renderText(0.05, line, 0.02, string.format("lastPosition(%3.4f, %3.4f)", self.baseInformation.lastPositionX, self.baseInformation.lastPositionZ)); line = line - 0.02
2528 renderText(0.05, line, 0.02, string.format("distanceCovered(%.2f)", self.motionInformation.coveredGroundDistance)); line = line - 0.02
2529 renderText(0.05, line, 0.02, string.format("inWater(%s)", tostring(self.baseInformation.isInWater))); line = line - 0.02
2530 renderText(0.05, line, 0.02, string.format("currentSpeed(%.3f) speedY(%.3f)", self.motionInformation.currentSpeed, self.motionInformation.currentSpeedY)); line = line - 0.02
2531 renderText(0.05, line, 0.02, string.format("rotY(%.3f)", self.graphicsRotY)); line = line - 0.02
2532 renderText(0.05, line, 0.02, string.format("estimatedYaw(%.3f)", self.estimatedYawVelocity)); line = line - 0.02
2533 renderText(0.05, line, 0.02, string.format("cameraRotY(%.3f)", self.cameraRotY)); line = line - 0.02
2534
2535
2536 setTextColor(0, 1, 0, 1)
2537 line = line - 0.02
2538 renderText(0.05, line, 0.02, "[input]"); line = line - 0.02
2539 renderText(0.05, line, 0.02, string.format("right(%3.4f)", self.inputInformation.moveRight))
2540 line = line - 0.02
2541 renderText(0.05, line, 0.02, string.format("forward(%3.4f)", self.inputInformation.moveForward))
2542 line = line - 0.02
2543 renderText(0.05, line, 0.02, string.format("pitch(%3.4f)", self.inputInformation.pitchCamera))
2544 line = line - 0.02
2545 renderText(0.05, line, 0.02, string.format("yaw(%3.4f)", self.inputInformation.yawCamera))
2546 line = line - 0.02
2547 renderText(0.05, line, 0.02, string.format("runAxis(%3.4f)", self.inputInformation.runAxis))
2548 line = line - 0.02
2549 renderText(0.05, line, 0.02, string.format("crouchState(%s)", tostring(self.inputInformation.crouchState)))
2550 line = line - 0.02
2551 renderText(0.05, line, 0.02, string.format("interactState(%s)", tostring(self.inputInformation.interactState)))
2552 end
2553end

delete

Description
Delete
Definition
delete()
Code
375function Player:delete()
376 self.isDeleting = true
377
378 if self.isOwner then -- only remove action events if this Player instance was controller by the current user
379 g_messageCenter:unsubscribeAll(self)
380 self:removeActionEvents()
381 end
382
383 if self.isCarryingObject then
384 if g_server ~= nil then
385 self:pickUpObject(false)
386 end
387 end
388
389 g_currentMission:removeMapHotspot(self.playerHotspot)
390 self.playerHotspot:delete()
391
392 if self.pickedUpObjectOverlay ~= nil then
393 self.pickedUpObjectOverlay:delete()
394 self.aimOverlay:delete()
395 self.brushOverlay:delete()
396 self.petOverlay:delete()
397 end
398
399 if self:hasHandtoolEquipped() then
400 self.baseInformation.currentHandtool:onDeactivate()
401 self.baseInformation.currentHandtool:delete()
402 self.baseInformation.currentHandtool = nil
403 end
404
405 self.model:delete()
406
407 removeCCT(self.controllerIndex)
408 delete(self.rootNode)
409 delete(self.graphicsRootNode)
410
411 self.playerStateMachine:delete()
412 self.hudUpdater:delete()
413 self:deleteStartleAnimalData()
414
415 if self.foliageBendingId ~= nil then
416 g_currentMission.foliageBendingSystem:destroyObject(self.foliageBendingId)
417 self.foliageBendingId = nil
418 end
419
420 if self.isOwner then
421 removeConsoleCommand("gsPlayerFlightMode")
422 removeConsoleCommand("gsWoodCuttingMarkerVisiblity")
423 removeConsoleCommand("gsPlayerDebug")
424 removeConsoleCommand("gsPlayerNoClip")
425 removeConsoleCommand("gsPlayerThirdPerson")
426 removeConsoleCommand("gsPlayerIKChainsReload")
427 removeConsoleCommand("gsTip")
428 removeConsoleCommand("gsPlayerSuperStrength")
429--#debug removeConsoleCommand("gsPlayerRaycastDebug")
430 end
431
432 Player:superClass().delete(self)
433end

deleteStartleAnimalData

Description
Remove animal sound timer and sound itself (deprecated?)
Definition
deleteStartleAnimalData()
Code
1729function Player:deleteStartleAnimalData()
1730 if (self.startleAnimalSoundTimerId) then
1731 removeTimer(self.startleAnimalSoundTimerId)
1732 self.startleAnimalSoundTimerId = nil
1733 end
1734 self:deleteStartleAnimalSound()
1735end

deleteStartleAnimalSound

Description
Remove animal sound(deprecated?)
Definition
deleteStartleAnimalSound()
Code
1739function Player:deleteStartleAnimalSound()
1740 if (self.startleAnimalSoundNode) then
1741 delete(self.startleAnimalSoundNode)
1742 self.startleAnimalSoundNode = nil
1743 end
1744 self.startleAnimalSoundTimerId = nil
1745end

draw

Description
Draws overlay information
Definition
draw()
Code
1465function Player:draw()
1466 if self:getIsInputAllowed() then
1467 if self:hasHandtoolEquipped() then
1468 self.baseInformation.currentHandtool:draw()
1469 else
1470 if not g_noHudModeEnabled then
1471 if self.playerStateMachine:isAvailable("animalPet") then
1472 self.petOverlay:render()
1473 elseif self.playerStateMachine:isAvailable("animalInteract") and self.playerStateMachine:getState("animalInteract"):getCanClean() then
1474 self.brushOverlay:render()
1475 elseif not self.isCarryingObject and self.isObjectInRange then
1476 self.pickedUpObjectOverlay:render()
1477 else
1478 self.aimOverlay:render()
1479 end
1480 end
1481 end
1482 end
1483end

drawUIInfo

Description
Renders UI information for the player
Definition
drawUIInfo()
Code
1442function Player:drawUIInfo()
1443 if self.isClient and self.isControlled and not self.isEntered then
1444 if not g_gui:getIsGuiVisible() and not g_noHudModeEnabled and g_gameSettings:getValue(GameSettings.SETTING.SHOW_MULTIPLAYER_NAMES) then
1445 local x, y, z = getTranslation(self.graphicsRootNode)
1446 local x1, y1, z1 = getWorldTranslation(getCamera())
1447 local diffX = x - x1
1448 local diffY = y - y1
1449 local diffZ = z - z1
1450 local dist = MathUtil.vector3LengthSq(diffX, diffY, diffZ)
1451 if dist <= 100 * 100 then
1452 y = y + self.baseInformation.tagOffset[2]
1453
1454 local user = g_currentMission.userManager:getUserByUserId(self.userId)
1455 if user ~= nil then
1456 Utils.renderTextAtWorldPosition(x, y, z, user:getNickname(), getCorrectTextSize(0.02), 0)
1457 end
1458 end
1459 end
1460 end
1461end

equipHandtool

Description
Definition
equipHandtool()
Code
1973function Player:equipHandtool(handtoolFilename, force, noEventSend, equippedCallbackFunction, equippedCallbackTarget)
1974 if self.isOwner then -- make sure we only change depth of field for locally controlled player instances
1975 if handtoolFilename == nil or handtoolFilename == "" then
1976 g_depthOfFieldManager:reset()
1977 else
1978 g_depthOfFieldManager:setManipulatedParams(0.8, 0.6, nil, nil, nil)
1979 end
1980 end
1981
1982 if handtoolFilename ~= nil and handtoolFilename ~= "" and not fileExists(handtoolFilename) then
1983 Logging.error("Unable to equip handTool '%s'. Config file does not exist!", handtoolFilename)
1984 end
1985
1986 PlayerSetHandToolEvent.sendEvent(self, handtoolFilename, force, noEventSend)
1987
1988 local arguments = {
1989 equippedCallbackFunction = equippedCallbackFunction,
1990 equippedCallbackTarget = equippedCallbackTarget
1991 }
1992
1993 if self:hasHandtoolEquipped() then
1994 if self.baseInformation.currentHandtool.configFileName:lower() ~= handtoolFilename:lower() or handtoolFilename == "" or force then
1995 self.baseInformation.currentHandtool:onDeactivate()
1996 self.baseInformation.currentHandtool:delete()
1997 self.baseInformation.currentHandtool = nil
1998 end
1999 if handtoolFilename ~= "" then
2000 self:loadHandTool(handtoolFilename, self.handToolLoaded, arguments)
2001 end
2002 else
2003 if handtoolFilename ~= "" then
2004 self:loadHandTool(handtoolFilename, self.handToolLoaded, arguments)
2005 end
2006 end
2007end

getCanEnterRideable

Description
Vehicle can be entered
Definition
getCanEnterRideable()
Return Values
boolcanBeEnteredvehicle is in range to be entered
Code
1328function Player:getCanEnterRideable()
1329 if self.canEnterVehicle then
1330 local vehicle = g_currentMission.interactiveVehicleInRange
1331 if vehicle ~= nil then
1332 if SpecializationUtil.hasSpecialization(Rideable, vehicle.specializations) then
1333 return true
1334 end
1335 end
1336 end
1337
1338 return false
1339end

getCanEnterVehicle

Description
Vehicle can be entered
Definition
getCanEnterVehicle()
Return Values
boolcanBeEnteredvehicle is in range to be entered
Code
1321function Player:getCanEnterVehicle()
1322 return self.canEnterVehicle and not self:getCanEnterRideable()
1323end

getDesiredSpeed

Description
Definition
getDesiredSpeed()
Code
2557function Player:getDesiredSpeed()
2558 local inputRight = self.inputInformation.moveRight
2559 local inputForward = self.inputInformation.moveForward
2560
2561 if ((inputForward ~= 0.0) or (inputRight ~= 0.0)) then
2562 local isSwimming = self.playerStateMachine:isActive("swim")
2563 local isCrouching = self.playerStateMachine:isActive("crouch")
2564 local isFalling = self.playerStateMachine:isActive("fall")
2565 local isUsingHandtool = self:hasHandtoolEquipped()
2566 local baseSpeed = self.motionInformation.maxWalkingSpeed
2567 if isFalling then
2568 baseSpeed = self.motionInformation.maxFallingSpeed
2569 elseif isSwimming then
2570 baseSpeed = self.motionInformation.maxSwimmingSpeed
2571 elseif isCrouching then
2572 baseSpeed = self.motionInformation.maxCrouchingSpeed
2573 end
2574
2575 local magnitude = math.sqrt(inputRight * inputRight + inputForward * inputForward)
2576 local desiredSpeed = MathUtil.clamp(magnitude, 0.0, 1.0) * baseSpeed
2577 local inputRun = self.inputInformation.runAxis
2578
2579 if (inputRun > 0.0) and not (isSwimming or isCrouching or isUsingHandtool) then -- check if we are running
2580 local runningSpeed = self.motionInformation.maxRunningSpeed
2581
2582 if g_addTestCommands then
2583 runningSpeed = self.motionInformation.maxPresentationRunningSpeed
2584 elseif g_addCheatCommands and (g_currentMission.isMasterUser or g_currentMission:getIsServer()) then
2585 runningSpeed = self.motionInformation.maxCheatRunningSpeed
2586 end
2587 desiredSpeed = math.max(desiredSpeed + (runningSpeed - desiredSpeed) * MathUtil.clamp(inputRun, 0.0, 1.0), desiredSpeed)
2588 end
2589 return desiredSpeed
2590 end
2591 return 0.0
2592end

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
2055function Player:getEquippedHandtoolFilename()
2056 return self.baseInformation.currentHandtool ~= nil and self.baseInformation.currentHandtool.configFileName or ""
2057end

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
752function Player:getIsInputAllowed()
753 return self.isEntered and self.isClient and not g_gui:getIsGuiVisible()
754end

getIsRideStateAvailable

Description
Definition
getIsRideStateAvailable()
Code
3195function Player:getIsRideStateAvailable()
3196 if not self.playerStateMachine:isActive("animalRide") then
3197 return self.playerStateMachine:isAvailable("animalRide")
3198 end
3199
3200 return false
3201end

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
369function Player:getParentComponent(node)
370 return self.graphicsRootNode
371end

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
1296function Player:getPositionData()
1297 local posX, posY, posZ = getTranslation(self.rootNode)
1298 if self.isClient and self.isControlled and self.isEntered then
1299 return posX, posY, posZ, self.rotY
1300 else
1301 return posX, posY, posZ, self.graphicsRotY + math.pi
1302 end
1303end

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
1639function Player:getUpdatePriority(skipCount, x, y, z, coeff, connection, isGuiVisible)
1640 if self.owner == connection then
1641 return 50
1642 end
1643 local x1, y1, z1 = getTranslation(self.rootNode)
1644 local dist = MathUtil.vector3Length(x1 - x, y1 - y, z1 - z)
1645 local clipDist = self.clipDistance
1646 return (1 - dist / clipDist) * 0.8 + 0.5 * skipCount * 0.2
1647end

handToolLoaded

Description
Called when hand tool was fully loaded
Definition
handToolLoaded(table handTool)
Arguments
tablehandToolhand tool
Code
2012function Player:handToolLoaded(handTool, arguments)
2013 if self.baseInformation.currentHandtool ~= nil then
2014 self.baseInformation.currentHandtool:onDeactivate()
2015 self.baseInformation.currentHandtool:delete()
2016 self.baseInformation.currentHandtool = nil
2017 end
2018
2019 self.baseInformation.currentHandtool = handTool
2020
2021 handTool:setHandNode(self.model.rightArmToolNode)
2022 handTool:onActivate(self:getIsInputAllowed())
2023
2024 if handTool.targets ~= nil then
2025 local ikChains = self.model:getIKChains()
2026 for ikChainId, target in pairs(handTool.targets) do
2027 IKUtil.setTarget(ikChains, ikChainId, target)
2028 end
2029 self:setIKDirty()
2030 end
2031
2032 local equippedCallbackFunction = arguments.equippedCallbackFunction
2033 local equippedCallbackTarget = arguments.equippedCallbackTarget
2034
2035 if equippedCallbackFunction ~= nil then
2036 equippedCallbackFunction(equippedCallbackTarget, handTool)
2037 end
2038end

hasHandtoolEquipped

Description
Definition
hasHandtoolEquipped()
Code
2048function Player:hasHandtoolEquipped()
2049 return self.baseInformation.currentHandtool ~= nil
2050end

load

Description
Loading player information
Definition
load(string xmlFilename, table creatorConnection, bool isOwner)
Arguments
stringxmlFilenameXML filename containing player information
tablecreatorConnection
boolisOwnertrue is current player is owner
Code
278function Player:load(creatorConnection, isOwner)
279 self.networkInformation.creatorConnection = creatorConnection
280 self.isOwner = isOwner
281
282 -- Root node based on physics. CCT is attached here
283 self.rootNode = createTransformGroup("PlayerCCT")
284 link(getRootNode(), self.rootNode)
285 -- Root node that decides client position (directly controlled by player for smoothness)
286 self.graphicsRootNode = createTransformGroup("player_graphicsRootNode")
287 link(getRootNode(), self.graphicsRootNode)
288
289 -- Create the player camera. We'll move this camera between targets such as the 1p target or the 3p target.
290 self.cameraNode = createCamera("player_camera", math.rad(70), 0.15, 6000)
291 self.fovY = calculateFovY(self.cameraNode)
292 setFovY(self.cameraNode, self.fovY)
293
294 self.thirdPersonLookatNode = createTransformGroup("thirdPersonLookatNode")
295 link(self.graphicsRootNode, self.thirdPersonLookatNode)
296 --local radius, height = self.model:getCapsuleSize()
297 --local headHeight = height + radius
298 setTranslation(self.thirdPersonLookatNode, 0, 0, 0)
299 --setTranslation(self.thirdPersonLookatNode, 0, headHeight, 0)
300
301 self.thirdPersonLookfromNode = createTransformGroup("thirdPersonLookfromNode")
302 link(self.thirdPersonLookatNode, self.thirdPersonLookfromNode)
303 --setTranslation(self.thirdPersonLookfromNode, 0, 0, -5) -- 5m camera distance
304 setTranslation(self.thirdPersonLookfromNode, 0, 0, -2) -- 5m camera distance
305
306 self:updateCameraModelTarget()
307
308 self.foliageBendingNode = createTransformGroup("player_foliageBendingNode")
309 link(self.graphicsRootNode, self.foliageBendingNode)
310
311 self.playerStateMachine:load()
312
313 self.isObjectInRange = false
314 self.isCarryingObject = false
315 self.pickedUpObject = nil
316
317 local uiScale = g_gameSettings:getValue("uiScale")
318
319 local pickupWidth, pickupHeight = getNormalizedScreenValues(80 * uiScale, 80 * uiScale)
320 self.pickedUpObjectOverlay = Overlay.new(g_baseHUDFilename, 0.5, 0.5, pickupWidth, pickupHeight)
321 self.pickedUpObjectOverlay:setAlignment(Overlay.ALIGN_VERTICAL_MIDDLE, Overlay.ALIGN_HORIZONTAL_CENTER)
322 self.pickedUpObjectOverlay:setUVs(GuiUtils.getUVs{0, 138, 80, 80})
323 self.pickedUpObjectOverlay:setColor(1, 1, 1, 0.3)
324
325 local aimWidth, aimHeight = getNormalizedScreenValues(20 * uiScale, 20 * uiScale)
326 self.aimOverlay = Overlay.new(g_baseHUDFilename, 0.5, 0.5, aimWidth, aimHeight)
327 self.aimOverlay:setAlignment(Overlay.ALIGN_VERTICAL_MIDDLE, Overlay.ALIGN_HORIZONTAL_CENTER)
328 self.aimOverlay:setUVs(GuiUtils.getUVs{0, 48, 48, 48})
329 self.aimOverlay:setColor(1, 1, 1, 0.3)
330
331 local brushWidth, brushHeight = getNormalizedScreenValues(75 * uiScale, 75 * uiScale)
332 self.brushOverlay = Overlay.new(g_baseHUDFilename, 0.5, 0.5, brushWidth, brushHeight)
333 self.brushOverlay:setAlignment(Overlay.ALIGN_VERTICAL_MIDDLE, Overlay.ALIGN_HORIZONTAL_CENTER)
334 self.brushOverlay:setUVs(GuiUtils.getUVs{307, 494, 75, 75})
335 self.brushOverlay:setColor(1, 1, 1, 0.3)
336
337 local petWidth, petHeight = getNormalizedScreenValues(75 * uiScale, 75 * uiScale)
338 self.petOverlay = Overlay.new(g_baseHUDFilename, 0.5, 0.5, petWidth, petHeight)
339 self.petOverlay:setAlignment(Overlay.ALIGN_VERTICAL_MIDDLE, Overlay.ALIGN_HORIZONTAL_CENTER)
340 self.petOverlay:setUVs(GuiUtils.getUVs{307, 419, 75, 75})
341 self.petOverlay:setColor(1, 1, 1, 0.3)
342
343
344 self:moveToAbsoluteInternal(0, -200, 0)
345
346 self:rebuildCCT()
347
348 self.lockedInput = false
349
350 if self.isOwner then
351 addConsoleCommand("gsPlayerFlightMode", "Enables/disables the flight mode toggle (key J). Use keys Q and E to change altitude", "consoleCommandToggleFlightMode", self)
352 addConsoleCommand("gsWoodCuttingMarkerVisiblity", "Enables/disables chainsaw woodcutting marker", "Player.consoleCommandToggleWoodCuttingMaker", nil)
353 addConsoleCommand("gsPlayerDebug", "Enables/disables player debug information", "consoleCommandTogglePlayerDebug", self)
354 addConsoleCommand("gsPlayerNoClip", "Enables/disables player no clip/collision mode. Use 'gsPlayerNoClip true' to also turn of terrain collision", "consoleCommandToggleNoClipMode", self)
355 if g_addTestCommands then
356 addConsoleCommand("gsTip", "Tips a fillType into a trigger", "consoleCommandTip", self)
357 addConsoleCommand("gsPlayerIKChainsReload", "Reloads player IKChains", "Player.consoleCommandReloadIKChains", nil)
358 addConsoleCommand("gsPlayerSuperStrength", "Enables/disables player super strength", "consoleCommandToggleSuperStrongMode", self)
359--#debug addConsoleCommand("gsPlayerRaycastDebug", "Enables/disables player pickup raycast debug information", "consoleCommandTogglePickupRaycastDebug", self)
360 addConsoleCommand("gsPlayerThirdPerson", "Enables/disables player third person view", "consoleCommandThirdPersonView", self)
361 end
362 end
363end

loadHandTool

Description
Loading hand tools for the player
Definition
loadHandTool(string xmlFilename)
Arguments
stringxmlFilenameXML filename
Return Values
tablereturnsthe handtool
Code
1931function Player:loadHandTool(xmlFilename, asyncCallbackFunction, asyncCallbackArguments)
1932 if GS_IS_CONSOLE_VERSION and not fileExists(xmlFilename) then
1933 return nil
1934 end
1935 local dataStoreItem = g_storeManager:getItemByXMLFilename(xmlFilename)
1936 if dataStoreItem ~= nil then
1937 local storeItemXmlFilename = dataStoreItem.xmlFilename
1938 local xmlFile = loadXMLFile("TempXML", storeItemXmlFilename)
1939 local handToolType = getXMLString(xmlFile, "handTool.handToolType")
1940 delete(xmlFile)
1941
1942 if handToolType ~= nil then
1943 local classObject = HandTool.handToolTypes[handToolType]
1944 if classObject == nil then
1945 local modName, _ = Utils.getModNameAndBaseDirectory(storeItemXmlFilename)
1946 if modName ~= nil then
1947 handToolType = modName.."."..handToolType
1948 classObject = HandTool.handToolTypes[handToolType]
1949 end
1950 end
1951 local handTool = nil
1952 if classObject ~= nil then
1953 handTool = classObject.new(self.isServer, self.isClient)
1954 else
1955 Logging.devError("Error: Invalid handtool type '%s'", handToolType)
1956 end
1957 if handTool ~= nil then
1958 if not handTool:load(storeItemXmlFilename, self, asyncCallbackFunction, asyncCallbackArguments) then
1959 Logging.devError("Error: Failed to load handtool '%s'", storeItemXmlFilename)
1960 handTool:delete()
1961 handTool = nil
1962 end
1963 end
1964
1965 return handTool
1966 end
1967 end
1968 return nil
1969end

lockInput

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

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
746function Player:mouseEvent(posX, posY, isDown, isUp, button)
747end

movePlayer

Description
Definition
movePlayer()
Code
2408function Player:movePlayer(dt, movementX, movementY, movementZ)
2409 self.debugFlightCoolDown = self.debugFlightCoolDown - 1
2410 if self.debugFlightMode then
2411 movementY = self.inputInformation.moveUp * dt
2412 end
2413
2414 self.networkInformation.tickTranslation[1] = self.networkInformation.tickTranslation[1] + movementX
2415 self.networkInformation.tickTranslation[2] = self.networkInformation.tickTranslation[2] + movementY
2416 self.networkInformation.tickTranslation[3] = self.networkInformation.tickTranslation[3] + movementZ
2417 moveCCT(self.controllerIndex, movementX, movementY, movementZ, self.cctMovementCollisionMask)
2418
2419 self.networkInformation.index = self.networkInformation.index + 1
2420 if not self.isServer then
2421 -- remove old history (above 100 entries)
2422 while table.getn(self.networkInformation.history) > 100 do
2423 table.remove(self.networkInformation.history, 1)
2424 end
2425 table.insert(self.networkInformation.history, {index=self.networkInformation.index, movementX=movementX, movementY=movementY, movementZ=movementZ})
2426 end
2427end

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
1378function Player:moveRootNodeToAbsolute(x, y, z)
1379 self:moveTo(x, y, z, true, true)
1380end

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, bool isRootNode)
Arguments
floatxnew x position
floatynew y position
floatznew z position
boolisAbsoluteif true, Y coordinate is in absolute, not calculated from terrain height
boolisRootNodeif true, coordinates are expected to be at the bottom of the player capsule, otherweise half capsule height will be added to y
Code
1348function Player:moveTo(x, y, z, isAbsolute, isRootNode)
1349 self:unequipHandtool()
1350
1351 if not self.isServer and self.isOwner then
1352 g_client:getServerConnection():sendEvent(PlayerTeleportEvent.new(x, y, z, isAbsolute, isRootNode))
1353 end
1354 if not isAbsolute then
1355 local terrainHeight = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, x, 300, z)
1356 y = terrainHeight + y
1357 end
1358 if not isRootNode then
1359 y = y + self.model.capsuleTotalHeight * 0.5
1360 end
1361 self:moveToAbsoluteInternal(x, y, z)
1362end

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
1369function Player:moveToAbsolute(x, y, z)
1370 self:moveTo(x, y, z, true, false)
1371end

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
1423function Player:moveToAbsoluteInternal(x, y, z)
1424 setTranslation(self.rootNode, x, y, z)
1425 setTranslation(self.graphicsRootNode, x, y, z)
1426
1427 self.networkInformation.interpolationTime:reset()
1428 self.networkInformation.interpolatorPosition:setPosition(x,y,z)
1429 self.networkInformation.updateTargetTranslationPhysicsIndex = -1
1430
1431 self.lastAnimPosX = x
1432 self.lastAnimPosY = y
1433 self.lastAnimPosZ = z
1434 self.walkDistance = 0
1435
1436 local _
1437 self.baseInformation.lastPositionX, _, self.baseInformation.lastPositionZ = getTranslation(self.graphicsRootNode)
1438end

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
1385function Player:moveToExitPoint(exitVehicle)
1386 if exitVehicle.getExitNode == nil then
1387 return
1388 end
1389
1390 local exitPoint = exitVehicle:getExitNode()
1391 local x, y, z = getWorldTranslation(exitPoint)
1392 local terrainHeight = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, x, 300, z)
1393
1394 y = math.max(terrainHeight + 0.1, y + 0.9)
1395 self:moveToAbsolute(x, y, z)
1396 local dx, _, dz = localDirectionToWorld(exitPoint, 0, 0, -1)
1397 self.rotY = MathUtil.getYRotationFromDirection(dx, dz)
1398
1399 --self.targetGraphicsRotY = self.rotY
1400 --self.graphicsRotY = self.rotY
1401 --(I) setRotation(self.graphicsRootNode, 0, self.graphicsRotY, 0)
1402 setRotation(self.cameraNode, self.rotX, self.rotY, 0)
1403end

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
77function Player.new(isServer, isClient)
78 local self = Object.new(isServer, isClient, Player_mt)
79
80 self.isControlled = false
81 self.isOwner = false
82 self.isEntered = false
83 self.debugFlightModeWalkingSpeed = 0.016
84 self.debugFlightModeRunningFactor = 1
85
86 self.model = PlayerModel.new()
87 self.model:loadEmpty()
88
89 self.cctMovementCollisionMask = CollisionMask.PLAYER_MOVEMENT
90
91 self.networkInformation = {}
92 self.networkInformation.creatorConnection = nil
93 self.networkInformation.history = {}
94 self.networkInformation.index = 0
95 if self.isServer then
96 self.networkInformation.sendIndex = 0
97 end
98 self.networkInformation.interpolationTime = InterpolationTime.new(1.2)
99 self.networkInformation.interpolatorPosition = InterpolatorPosition.new(0.0, 0.0, 0.0)
100 self.networkInformation.interpolatorQuaternion = InterpolatorQuaternion.new(0.0, 0.0, 0.0, 1.0) -- only used on server side for rotation of camera
101 self.networkInformation.interpolatorOnGround = InterpolatorValue.new(0.0)
102 self.networkInformation.tickTranslation = {0.0, 0.0, 0.0}
103 self.networkInformation.dirtyFlag = self:getNextDirtyFlag()
104 self.networkInformation.updateTargetTranslationPhysicsIndex = -1
105 self.networkInformation.rotateObject = false
106 self.networkInformation.rotateObjectInputV = 0.0
107 self.networkInformation.rotateObjectInputH = 0.0
108
109 self.motionInformation = {}
110 self.motionInformation.damping = 0.8
111 self.motionInformation.mass = 80.0 -- in kg
112 self.motionInformation.maxAcceleration = 50.0 -- m/s^2
113 self.motionInformation.maxDeceleration = 50.0 -- m/s^2
114 self.motionInformation.gravity = -9.8
115
116 -- if getUserName() == "jkuijpers" then
117 -- -- real walking speed: 1.4, real running speed: 6.5, real swimming speed: 0.9
118 -- self.motionInformation.maxIdleSpeed = 0.1 -- in m/s
119 -- self.motionInformation.maxWalkingSpeed = 1.4 -- in m/s 4
120 -- self.motionInformation.maxRunningSpeed = 9.0 -- in m/s
121 -- self.motionInformation.maxSwimmingSpeed = 3.0 -- in m/s
122 -- self.motionInformation.maxCrouchingSpeed = 2.0 -- in m/s
123 -- self.motionInformation.maxFallingSpeed = 1.4 -- in m/s
124 -- self.motionInformation.maxCheatRunningSpeed = 9.0 -- in m/s
125 -- self.motionInformation.maxPresentationRunningSpeed = 9.0 -- in m/s
126 -- self.motionInformation.maxSpeedDelay = 0.1 -- in s (how long before max speed is reached)
127 -- self.motionInformation.brakeDelay = 0.001 -- in s (how long before velocity is null)
128 -- self.motionInformation.brakeForce = {0.0, 0.0, 0.0} -- in N (force to apply to stop the player gradually)
129 -- else
130
131 self.motionInformation.maxIdleSpeed = 0.1 -- in m/s
132 self.motionInformation.maxWalkingSpeed = 4.0 -- in m/s
133 self.motionInformation.maxRunningSpeed = 9.0 -- in m/s
134 self.motionInformation.maxSwimmingSpeed = 3.0 -- in m/s
135 self.motionInformation.maxCrouchingSpeed = 2.0 -- in m/s
136 self.motionInformation.maxFallingSpeed = 6.0 -- in m/s
137 self.motionInformation.maxCheatRunningSpeed = 34.0 -- in m/s
138 self.motionInformation.maxPresentationRunningSpeed = 128.0 -- in m/s
139 self.motionInformation.maxSpeedDelay = 0.1 -- in s (how long before max speed is reached)
140 self.motionInformation.brakeDelay = 0.001 -- in s (how long before velocity is null)
141 self.motionInformation.brakeForce = {0.0, 0.0, 0.0} -- in N (force to apply to stop the player gradually)
142 -- end
143 self.motionInformation.currentGroundSpeed = 0.0 -- in m/s
144 self.motionInformation.minimumFallingSpeed = -0.00001 -- in m/s
145 self.motionInformation.coveredGroundDistance = 0.0 -- in m
146 self.motionInformation.currentCoveredGroundDistance = 0.0
147 self.motionInformation.justMoved = false --
148 self.motionInformation.isBraking = false
149 self.motionInformation.lastSpeed = 0.0
150 self.motionInformation.currentSpeed = 0.0
151 self.motionInformation.currentSpeedY = 0.0
152 self.motionInformation.isReverse = false
153 self.motionInformation.desiredSpeed = 0.0
154 self.motionInformation.jumpHeight = 1 -- in m
155 self.motionInformation.currentWorldDirX = 0.0
156 self.motionInformation.currentWorldDirZ = 1.0
157 self.motionInformation.currentSpeedX = 0.0
158 self.motionInformation.currentSpeedZ = 0.0
159
160 self.baseInformation = {}
161 self.baseInformation.lastPositionX = 0.0
162 self.baseInformation.lastPositionZ = 0.0
163 self.baseInformation.isOnGround = true
164 self.baseInformation.isOnGroundPhysics = true
165 self.baseInformation.isCloseToGround = true
166 self.baseInformation.isInWater = false
167 self.baseInformation.waterDepth = 0
168 self.baseInformation.wasInWater = false
169 self.baseInformation.waterLevel = -1.4
170 self.baseInformation.waterCameraOffset = 0.3
171 self.baseInformation.currentWaterCameraOffset = 0.0
172 self.baseInformation.plungedInWater = false
173 self.baseInformation.plungedYVelocityThreshold = -2.0
174 self.baseInformation.isInDebug = false
175 self.baseInformation.tagOffset = {0.0, 1.9, 0.0}
176 self.baseInformation.translationAlphaDifference = 0.0
177 self.baseInformation.animDt = 0.0
178 self.baseInformation.isCrouched = false
179 self.baseInformation.isUsingChainsawHorizontal = false
180 self.baseInformation.isUsingChainsawVertical = false
181 self.baseInformation.currentHandtool = nil
182 self.baseInformation.headBobTime = 0.0
183 self.baseInformation.lastCameraAmplitudeScale = 0.0
184 self.lastEstimatedForwardVelocity = 0.0
185
186 self.inputInformation = {}
187 self.inputInformation.moveForward = 0.0
188 self.inputInformation.moveRight = 0.0
189 self.inputInformation.moveUp = 0.0 -- for debug flight mode
190 self.inputInformation.pitchCamera = 0.0
191 self.inputInformation.yawCamera = 0.0
192 self.inputInformation.runAxis = 0.0
193 self.inputInformation.crouchState = Player.BUTTONSTATES.RELEASED
194 self.inputInformation.interactState = Player.BUTTONSTATES.RELEASED
195
196 -- These are the parameters for the input registration and the eventId
197 self.inputInformation.registrationList = {}
198 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 }
199 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 }
200 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 }
201 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 }
202 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 }
203 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 }
204 -- TODO: read from game settings? also needs to be applied to PlayerStateCrouch.toggleMode. triggerAlways = not crouchToggleMode
205 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 }
206 self.inputInformation.registrationList[InputAction.ANIMAL_PET] = { eventId="", callback=self.onInputActivateObject, triggerUp=false, triggerDown=true, triggerAlways=false, activeType=Player.INPUT_ACTIVE_TYPE.IS_MOVEMENT, callbackState=nil, text="", textVisibility=true }
207 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 }
208 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 }
209 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 }
210 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 }
211 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 }
212 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 }
213 self.inputInformation.registrationList[InputAction.SWITCH_HANDTOOL] = { eventId="", callback=self.onInputCycleHandTool, triggerUp=false, triggerDown=true, triggerAlways=false, activeType=Player.INPUT_ACTIVE_TYPE.STARTS_DISABLED, callbackState=nil, text=g_i18n:getText("input_SWITCH_HANDTOOL"), textVisibility=false }
214 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 }
215 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 }
216 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 }
217
218 -- Player movement lock flag
219 self.walkingIsLocked = false
220
221 self.canRideAnimal = false
222 self.canEnterVehicle = false
223
224 self.isTorchActive = false
225
226 self.rotX = 0
227 self.rotY = 0
228 self.cameraRotY = 0
229
230 self.oldYaw = 0.0 -- in rad
231 self.newYaw = 0.0 -- in rad
232 self.estimatedYawVelocity = 0.0 -- in rad/s
233
234 self.graphicsRotY = 0
235 self.targetGraphicsRotY = 0
236
237 self.thirdPersonViewActive = false
238
239 self.camera = 0
240
241 self.time = 0
242
243 self.clipDistance = 500
244 self.waterY = -2000
245
246 self.lastAnimPosX = 0
247 self.lastAnimPosY = 0
248 self.lastAnimPosZ = 0
249
250 self.walkDistance = 0
251 self.animUpdateTime = 0
252
253 self.allowPlayerPickUp = Platform.allowPlayerPickUp
254
255 self.debugFlightMode = false
256 self.debugFlightCoolDown = 0
257
258 self.requestedFieldData = false
259
260 self.playerStateMachine = PlayerStateMachine.new(self)
261 self.hudUpdater = PlayerHUDUpdater.new()
262
263 self.farmId = FarmManager.SPECTATOR_FARM_ID
264
265 self.cameraBobbingEnabled = g_gameSettings:getValue(GameSettings.SETTING.CAMERA_BOBBING)
266
267 self.playerHotspot = PlayerHotspot.new()
268 self.playerHotspot:setPlayer(self)
269
270 return self
271end

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
1497function Player:onEnter(isControlling)
1498 self:raiseActive()
1499 if self.foliageBendingNode ~= nil and self.foliageBendingId == nil and g_currentMission.foliageBendingSystem then
1500 -- foliage bending
1501 self.foliageBendingId = g_currentMission.foliageBendingSystem:createRectangle(-0.5, 0.5, -0.5, 0.5, 0.4, self.foliageBendingNode)
1502 end
1503
1504 if self.isServer then
1505 self:setOwner(self.networkInformation.creatorConnection)
1506 end
1507 if isControlling or self.isServer then
1508 self:raiseDirtyFlags(self.networkInformation.dirtyFlag)
1509 end
1510
1511 self.isControlled = true
1512 if isControlling then
1513 g_messageCenter:subscribe(MessageType.INPUT_BINDINGS_CHANGED, self.onInputBindingsChanged, self)
1514 g_messageCenter:publish(MessageType.OWN_PLAYER_ENTERED)
1515 g_currentMission:addPauseListeners(self, Player.onPauseGame)
1516 setRotation(self.cameraNode, 0, 0, 0)
1517 setCamera(self.cameraNode)
1518 self.isEntered = true
1519 self:setVisibility(false)
1520 self:registerActionEvents()
1521 g_currentMission.environmentAreaSystem:setReferenceNode(self.cameraNode)
1522 else
1523 self:setVisibility(true)
1524 end
1525
1526 self.playerHotspot:setOwnerFarmId(self.farmId)
1527 g_currentMission:addMapHotspot(self.playerHotspot)
1528
1529 if self.isServer and not self.isEntered and g_currentMission.trafficSystem ~= nil and g_currentMission.trafficSystem.trafficSystemId ~= 0 then
1530 addTrafficSystemPlayer(g_currentMission.trafficSystem.trafficSystemId, self.graphicsRootNode)
1531 end
1532 self.isTorchActive = false
1533end

onEnterFarmhouse

Description
Definition
onEnterFarmhouse()
Code
2064function Player:onEnterFarmhouse()
2065 if self.isServer then
2066 local dogHouse = g_currentMission:getDoghouse(self.farmId)
2067 if dogHouse ~= nil and dogHouse.dog ~= nil and dogHouse.dog.entityFollow == self.rootNode then
2068 dogHouse.dog:teleportToSpawn()
2069 end
2070 end
2071end

onGhostAdd

Description
Empty function
Definition
onGhostAdd()
Code
1627function Player:onGhostAdd()
1628end

onGhostRemove

Description
Deletes player
Definition
onGhostRemove()
Code
1621function Player:onGhostRemove()
1622 self:delete()
1623end

onInputActivateHandtool

Description
Definition
onInputActivateHandtool()
Code
3187function Player:onInputActivateHandtool(_, inputValue)
3188 if self:hasHandtoolEquipped() then
3189 self.baseInformation.currentHandtool.activatePressed = inputValue ~= 0
3190 end
3191end

onInputActivateObject

Description
Event function for interacting with an animal
Definition
onInputActivateObject()
Code
3114function Player:onInputActivateObject(_, inputValue)
3115 self.playerStateMachine:activateState("animalPet")
3116end

onInputCrouch

Description
Event function for crouching.
Definition
onInputCrouch()
Code
3031function Player:onInputCrouch(_, inputValue)
3032 if self.playerStateMachine:isAvailable("crouch") then
3033 self.playerStateMachine:activateState("crouch")
3034 end
3035
3036 self.inputInformation.crouchState = Player.BUTTONSTATES.PRESSED
3037end

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
3131function Player:onInputCycleHandTool(_, direction)
3132 if self.playerStateMachine:isAvailable("cycleHandtool") then
3133 local cycleHandtoolState = self.playerStateMachine:getState("cycleHandtool")
3134 cycleHandtoolState.cycleDirection = direction
3135 self.playerStateMachine:activateState("cycleHandtool")
3136 end
3137end

onInputDebugFlyToggle

Description
Event function for the debug flying toggle.
Definition
onInputDebugFlyToggle()
Code
3149function Player:onInputDebugFlyToggle()
3150 if not self.walkingIsDisabled then
3151 if self.debugFlightCoolDown <= 0 then
3152 if g_flightModeEnabled then
3153 self.debugFlightMode = not self.debugFlightMode
3154 self.debugFlightCoolDown = 10
3155 end
3156 end
3157 end
3158end

onInputDebugFlyUpDown

Description
Event function for the debug flying vertical movement.
Definition
onInputDebugFlyUpDown(nil, float inputValue)
Arguments
nil
floatinputValue
Code
3164function Player:onInputDebugFlyUpDown(_, inputValue)
3165 if not self.walkingIsDisabled then
3166 local move = inputValue * 0.25 * self.debugFlightModeWalkingSpeed * self.debugFlightModeRunningFactor
3167 self.inputInformation.moveUp = self.inputInformation.moveUp + move
3168 end
3169end

onInputEnter

Description
Event function for enter
Definition
onInputEnter(nil, float inputValue)
Arguments
nil
floatinputValue
Code
3175function Player:onInputEnter(_, inputValue)
3176 if g_time > g_currentMission.lastInteractionTime + 200 then
3177 if g_currentMission.interactiveVehicleInRange and g_currentMission.accessHandler:canFarmAccess(self.farmId, g_currentMission.interactiveVehicleInRange) then
3178 g_currentMission.interactiveVehicleInRange:interact()
3179 elseif self.canRideAnimal then
3180 self.playerStateMachine:activateState("animalRide")
3181 end
3182 end
3183end

onInputInteract

Description
Event function for interacting with an animal
Definition
onInputInteract()
Code
3094function Player:onInputInteract(_, inputValue)
3095 -- Note: we need to store pressed state for animal cleaning (see PlayerStateAnimalInteract) which is a continuous
3096 -- action. Therefore, this event is called onUp and onDown. When the down event is received, input will be non-zero.
3097 if self.inputInformation.interactState ~= Player.BUTTONSTATES.PRESSED and inputValue ~= 0 then
3098 if self.playerStateMachine:isAvailable("drop") then
3099 self.playerStateMachine:activateState("drop")
3100 elseif self.playerStateMachine:isAvailable("pickup") then
3101 self.playerStateMachine:activateState("pickup")
3102 elseif self.playerStateMachine:isAvailable("animalInteract") then
3103 self.playerStateMachine:activateState("animalInteract")
3104 end
3105
3106 self.inputInformation.interactState = Player.BUTTONSTATES.PRESSED
3107 else
3108 self.inputInformation.interactState = Player.BUTTONSTATES.RELEASED
3109 end
3110end

onInputJump

Description
Event function for jumping.
Definition
onInputJump()
Code
3086function Player:onInputJump(_, inputValue)
3087 if self.playerStateMachine:isAvailable("jump") then
3088 self.playerStateMachine:activateState("jump")
3089 end
3090end

onInputLookLeftRight

Description
Event function for player camera horizontal axis.
Definition
onInputLookLeftRight(nil, float inputValue)
Arguments
nil
floatinputValue
Code
2956function Player:onInputLookLeftRight(_, inputValue, _, _, isMouse)
2957 if not self.lockedInput then
2958 if isMouse then
2959 inputValue = inputValue * 0.001 * 16.666
2960 else
2961 inputValue = inputValue * g_currentDt *0.001
2962 end
2963 self.inputInformation.yawCamera = self.inputInformation.yawCamera + inputValue
2964 end
2965 self.inputInformation.isMouseRotation = isMouse
2966end

onInputLookUpDown

Description
Event function for player camera vertical axis.
Definition
onInputLookUpDown(nil, float inputValue)
Arguments
nil
floatinputValue
Code
2981function Player:onInputLookUpDown(_, inputValue, _, _, isMouse)
2982 if not self.lockedInput then
2983 local pitchValue = g_gameSettings:getValue("invertYLook") and -inputValue or inputValue
2984 if isMouse then
2985 pitchValue = pitchValue * 0.001 * 16.666
2986 else
2987 pitchValue = pitchValue * g_currentDt *0.001
2988 end
2989 self.inputInformation.pitchCamera = self.inputInformation.pitchCamera + pitchValue
2990 end
2991end

onInputMoveForward

Description
Event function for player forward/backward movement.
Definition
onInputMoveForward(nil, float inputValue)
Arguments
nil
floatinputValue
Code
3007function Player:onInputMoveForward(_, inputValue)
3008 if not self.lockedInput then
3009 self.inputInformation.moveForward = self.inputInformation.moveForward + inputValue
3010 end
3011end

onInputMoveSide

Description
Event function for player strafe movement.
Definition
onInputMoveSide(nil, float inputValue)
Arguments
nil
floatinputValue
Code
2997function Player:onInputMoveSide(_, inputValue)
2998 if not self.lockedInput then
2999 self.inputInformation.moveRight = self.inputInformation.moveRight + inputValue
3000 end
3001end

onInputRotateObjectHorizontally

Description
Event function for rotating object.
Definition
onInputRotateObjectHorizontally()
Code
3041function Player:onInputRotateObjectHorizontally(_, inputValue)
3042 if self.pickedUpObjectJointId ~= nil and math.abs(inputValue) > 0 then
3043 self:rotateObject(inputValue, 0.0, 1.0, 0.0)
3044 elseif self.isCarryingObject and self.isClient and self.isControlled then
3045 if inputValue ~= 0.0 then
3046 self.networkInformation.rotateObject = true
3047 else
3048 self.networkInformation.rotateObject = false
3049 end
3050 self.networkInformation.rotateObjectInputH = inputValue
3051 end
3052end

onInputRotateObjectVertically

Description
Event function for rotating object.
Definition
onInputRotateObjectVertically()
Code
3056function Player:onInputRotateObjectVertically(_, inputValue)
3057 if self.pickedUpObjectJointId ~= nil and math.abs(inputValue) > 0 then
3058 self:rotateObject(inputValue, 1.0, 0.0, 0.0)
3059 elseif self.isCarryingObject and self.isClient and self.isControlled then
3060 if inputValue ~= 0.0 then
3061 self.networkInformation.rotateObject = true
3062 else
3063 self.networkInformation.rotateObject = false
3064 end
3065 self.networkInformation.rotateObjectInputV = inputValue
3066 end
3067end

onInputRun

Description
Event function for player running.
Definition
onInputRun(nil, float inputValue)
Arguments
nil
floatinputValue
Code
3017function Player:onInputRun(_, inputValue)
3018 self.inputInformation.runAxis = inputValue
3019
3020 if self.debugFlightMode then
3021 if inputValue > 0 and self.debugFlightModeRunningFactor ~= 4.0 then
3022 self.debugFlightModeRunningFactor = 4.0
3023 elseif inputValue == 0 and self.debugFlightModeRunningFactor ~= 1.0 then
3024 self.debugFlightModeRunningFactor = 1.0
3025 end
3026 end
3027end

onInputThrowObject

Description
Event function for throwing an object.
Definition
onInputThrowObject()
Code
3141function Player:onInputThrowObject(_, inputValue)
3142 if self.playerStateMachine:isAvailable("throw") then
3143 self.playerStateMachine:activateState("throw")
3144 end
3145end

onInputToggleLight

Description
Event function for flashlight toggle.
Definition
onInputToggleLight()
Code
3120function Player:onInputToggleLight()
3121 if self.playerStateMachine:isAvailable("useLight") then
3122 self.playerStateMachine:activateState("useLight")
3123 end
3124end

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
1544function Player:onLeave()
1545 if self.isControlled then
1546 g_messageCenter:publish(MessageType.OWN_PLAYER_LEFT)
1547 g_messageCenter:unsubscribe(MessageType.INPUT_BINDINGS_CHANGED, self)
1548 end
1549
1550 g_currentMission:removeMapHotspot(self.playerHotspot)
1551
1552 -- stop swim sound
1553 g_soundManager:stopSamples(self.model.soundInformation.samples)
1554
1555 self:removeActionEvents()
1556
1557 if self.foliageBendingId ~= nil then
1558 g_currentMission.foliageBendingSystem:destroyObject(self.foliageBendingId)
1559 self.foliageBendingId = nil
1560 end
1561
1562 if self.isServer then
1563 self:setOwner(nil)
1564 end
1565 if self.isEntered or self.isServer then
1566 self:raiseDirtyFlags(self.networkInformation.dirtyFlag)
1567 end
1568 if self.isServer and not self.isEntered and g_currentMission.trafficSystem ~= nil and g_currentMission.trafficSystem.trafficSystemId ~= 0 then
1569 removeTrafficSystemPlayer(g_currentMission.trafficSystem.trafficSystemId, self.graphicsRootNode)
1570 end
1571
1572 g_currentMission:addPauseListeners(self)
1573
1574 --clear history
1575 self.networkInformation.history = {}
1576 self.isControlled = false
1577 self.isEntered = false
1578 self:setVisibility(false)
1579
1580 if self:hasHandtoolEquipped() then
1581 self.baseInformation.currentHandtool:onDeactivate()
1582 self.baseInformation.currentHandtool:delete()
1583 self.baseInformation.currentHandtool = nil
1584 end
1585 local dogHouse = g_currentMission:getDoghouse(self.farmId)
1586 if dogHouse ~= nil and dogHouse.dog ~= nil then
1587 dogHouse.dog:onPlayerLeave(self)
1588 end
1589
1590 self.model:enableTorch(false)
1591 self:moveToAbsoluteInternal(0, -200, 0)
1592end

onLeaveVehicle

Description
Called when player leaves vehicle
Definition
onLeaveVehicle()
Code
1537function Player:onLeaveVehicle()
1538 self.playerStateMachine:deactivateState("animalRide")
1539 self.playerStateMachine:deactivateState("jump")
1540end

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
2343function Player:onPickedUpObjectJointBreak(jointIndex, breakingImpulse)
2344 if jointIndex == self.pickedUpObjectJointId then
2345 self:pickUpObject(false)
2346 end
2347 -- Do not delete the joint internally, we already deleted it
2348 return false
2349end

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
2189function Player:pickUpObject(state, noEventSend)
2190 PlayerPickUpObjectEvent.sendEvent(self, state, noEventSend)
2191
2192 if self.isServer then
2193 if state and (self.isObjectInRange and self.lastFoundObject ~= nil and entityExists(self.lastFoundObject)) and not self.isCarryingObject then
2194 local constr = JointConstructor.new()
2195
2196 -- disable collision with CCT
2197 self.pickedUpObjectCollisionMask = getCollisionMask(self.lastFoundObject)
2198 local newPickedUpObjectCollisionFlag = bitXOR(bitAND(self.pickedUpObjectCollisionMask, self.cctMovementCollisionMask), self.pickedUpObjectCollisionMask)
2199 setCollisionMask(self.lastFoundObject, newPickedUpObjectCollisionFlag)
2200
2201 local kinematicHelperNode, kinematicHelperNodeChild = self.model:getKinematicHelpers()
2202 constr:setActors(kinematicHelperNode, self.lastFoundObject)
2203
2204 for i=0, 2 do
2205 constr:setRotationLimit(i, 0, 0)
2206 constr:setTranslationLimit(i, true, 0, 0)
2207 end
2208
2209 -- set position of joint to center of the object
2210 local mx, my, mz = getCenterOfMass(self.lastFoundObject)
2211 local wx, wy, wz = localToWorld(self.lastFoundObject, mx, my, mz)
2212 constr:setJointWorldPositions(wx, wy, wz, wx, wy, wz)
2213
2214 local nx, ny, nz = localDirectionToWorld(self.lastFoundObject, 1, 0, 0)
2215 constr:setJointWorldAxes(nx, ny, nz, nx, ny, nz)
2216
2217 local yx, yy, yz = localDirectionToWorld(self.lastFoundObject, 0, 1, 0)
2218 constr:setJointWorldNormals(yx, yy, yz, yx, yy, yz)
2219 constr:setEnableCollision(false)
2220
2221 -- Update child, used for object rotation by player
2222 setWorldTranslation(kinematicHelperNodeChild, wx, wy, wz)
2223 setWorldRotation(kinematicHelperNodeChild, getWorldRotation(self.lastFoundObject))
2224
2225 -- set spring/damper ?!
2226 local dampingRatio = 1.0
2227 local mass = getMass(self.lastFoundObject)
2228
2229 local rotationLimitSpring = {}
2230 local rotationLimitDamper = {}
2231 for i=1, 3 do
2232 rotationLimitSpring[i] = mass * 60
2233 rotationLimitDamper[i] = dampingRatio * 2 * math.sqrt( mass * rotationLimitSpring[i] )
2234 --print(" rotSpring/Damper = "..tostring(rotationLimitSpring[i]).." / "..tostring(rotationLimitDamper[i]))
2235 end
2236 constr:setRotationLimitSpring(rotationLimitSpring[1], rotationLimitDamper[1], rotationLimitSpring[2], rotationLimitDamper[2], rotationLimitSpring[3], rotationLimitDamper[3])
2237
2238 local translationLimitSpring = {}
2239 local translationLimitDamper = {}
2240 for i=1, 3 do
2241 translationLimitSpring[i] = mass * 60
2242 translationLimitDamper[i] = dampingRatio * 2 * math.sqrt( mass * translationLimitSpring[i] )
2243 --print(" transSpring/Damper = "..tostring(translationLimitSpring[i]).." / "..tostring(translationLimitDamper[i]))
2244 end
2245 constr:setTranslationLimitSpring(translationLimitSpring[1], translationLimitDamper[1], translationLimitSpring[2], translationLimitDamper[2], translationLimitSpring[3], translationLimitDamper[3])
2246
2247 local forceAcceleration = 4
2248 local forceLimit = forceAcceleration * mass * 40.0
2249 constr:setBreakable(forceLimit, forceLimit)
2250
2251 self.pickedUpObjectJointId = constr:finalize()
2252
2253 addJointBreakReport(self.pickedUpObjectJointId, "onPickedUpObjectJointBreak", self)
2254
2255 self.pickedUpObject = self.lastFoundObject
2256 self.isCarryingObject = true
2257 Player.PICKED_UP_OBJECTS[self.pickedUpObject] = true
2258
2259 local object = g_currentMission:getNodeObject(self.pickedUpObject)
2260 if object ~= nil then
2261 object.thrownFromPosition = nil
2262 end
2263 else
2264 if self.pickedUpObjectJointId ~= nil then
2265 removeJoint(self.pickedUpObjectJointId)
2266 self.pickedUpObjectJointId = nil
2267 self.isCarryingObject = false
2268 Player.PICKED_UP_OBJECTS[self.pickedUpObject] = false
2269
2270 if entityExists(self.pickedUpObject) then
2271 local vx, vy, vz = getLinearVelocity(self.pickedUpObject)
2272 if vx ~= nil then -- in case the object has switched from dynamic to kinematic
2273 vx = MathUtil.clamp(vx, -5, 5)
2274 vy = MathUtil.clamp(vy, -5, 5)
2275 vz = MathUtil.clamp(vz, -5, 5)
2276 setLinearVelocity(self.pickedUpObject, vx, vy, vz)
2277 end
2278 -- setAngularVelocity(self.pickedUpObject, vx, vy, vz)
2279 setCollisionMask(self.pickedUpObject, self.pickedUpObjectCollisionMask)
2280 self.pickedUpObjectCollisionMask = 0
2281 end
2282
2283 local object = g_currentMission:getNodeObject(self.pickedUpObject)
2284 if object ~= nil then
2285 object.thrownFromPosition = nil
2286 end
2287 self.pickedUpObject = nil
2288 end
2289 end
2290 end
2291end

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
2126function Player:pickUpObjectRaycastCallback(hitObjectId, x, y, z, distance)
2127 if hitObjectId ~= g_currentMission.terrainRootNode and Player.PICKED_UP_OBJECTS[hitObjectId] ~= true then
2128
2129--#debug if self.pickupRaycastDebugEnabled then
2130--#debug renderText(0.010, 0.55, 0.02, "Player raycast callback")
2131--#debug local colMaskDec = getCollisionMask(hitObjectId)
2132--#debug local text = string.format("nodeId=%s (%s), maskHex=%x, maskDec=%s, hasTrigger=%s", hitObjectId, getName(hitObjectId), colMaskDec, colMaskDec, getHasTrigger(hitObjectId))
2133--#debug renderText(0.010, 0.53 - self.raycastCallbackIndex * 0.02, 0.016, text)
2134--#debug self.raycastCallbackIndex = self.raycastCallbackIndex + 1
2135--#debug end
2136
2137 local rigidBodyType = getRigidBodyType(hitObjectId)
2138 if rigidBodyType == RigidBodyType.DYNAMIC or rigidBodyType == RigidBodyType.KINEMATIC then
2139 -- Store any object we hit, even it if cannot be picked up.
2140 -- This is used for the info HUD
2141 self.lastFoundAnyObject = hitObjectId
2142
2143 if not self.isServer then
2144 -- only consider first potentially valid object
2145 return false
2146 end
2147 end
2148
2149 if self.isServer and rigidBodyType == RigidBodyType.DYNAMIC then
2150 -- check if mounted:
2151 local canBePickedUp = true
2152 local object = g_currentMission:getNodeObject(hitObjectId)
2153 if object ~= nil then
2154 if object.dynamicMountObject ~= nil or object.tensionMountObject ~= nil then
2155 canBePickedUp = false
2156 end
2157 if object.getCanBePickedUp ~= nil then
2158 if not object:getCanBePickedUp(self) and not self.superStrengthEnabled then
2159 canBePickedUp = false
2160 end
2161 end
2162 end
2163
2164 if canBePickedUp then
2165 local mass
2166 if object ~= nil and object.getTotalMass ~= nil then
2167 mass = object:getTotalMass()
2168 else
2169 mass = getMass(hitObjectId)
2170 end
2171
2172 self.lastFoundObject = hitObjectId
2173 self.lastFoundObjectMass = mass
2174 self.lastFoundObjectHitPoint = {x, y, z}
2175 end
2176
2177 -- only consider first potentially valid object
2178 return false
2179 end
2180 end
2181
2182 return true
2183end

readStream

Description
Reads from network stream
Definition
readStream(integer streamId, table connection)
Arguments
integerstreamIdid of the stream to read
tableconnectionconnection information
Code
458function Player:readStream(streamId, connection, objectId)
459 Player:superClass().readStream(self, streamId, connection)
460
461 local isOwner = streamReadBool(streamId)
462
463 local x = streamReadFloat32(streamId)
464 local y = streamReadFloat32(streamId)
465 local z = streamReadFloat32(streamId)
466
467 local isControlled = streamReadBool(streamId)
468
469 self.farmId = streamReadUIntN(streamId, FarmManager.FARM_ID_SEND_NUM_BITS)
470 self.userId = NetworkUtil.readNodeObjectId(streamId)
471
472 self:load(connection, isOwner)
473
474 self:moveToAbsoluteInternal(x, y, z)
475 self:setLightIsActive(streamReadBool(streamId), true)
476
477 if isControlled ~= self.isControlled then
478 if isControlled then
479 self:onEnter(false)
480 else
481 self:onLeave()
482 end
483 end
484
485 local hasHandtool = streamReadBool(streamId)
486 if hasHandtool then
487 local handtoolFilename = NetworkUtil.convertFromNetworkFilename(streamReadString(streamId))
488 self:equipHandtool(handtoolFilename, true, true)
489 end
490
491 -- The object has been received. Request any style info from the server
492 g_client:getServerConnection():sendEvent(PlayerRequestStyleEvent.new(objectId))
493end

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
528function Player:readUpdateStream(streamId, timestamp, connection)
529 if connection:getIsServer() then
530 -- client code (read data from server)
531 -- TODO look into Vehicle:readUpdateStream NetworkUtil.readCompressedWorldPosition and NetworkUtil.readCompressedAngle
532 local x = streamReadFloat32(streamId)
533 local y = streamReadFloat32(streamId)
534 local z = streamReadFloat32(streamId)
535 local alpha = streamReadFloat32(streamId)
536 self.cameraRotY = alpha
537
538 self.isObjectInRange = streamReadBool(streamId)
539 if self.isObjectInRange then
540 -- TODO: compress
541 self.lastFoundObjectMass = streamReadFloat32(streamId)
542 else
543 self.lastFoundObjectMass = nil
544 end
545 self.isCarryingObject = streamReadBool(streamId)
546 local isOnGround = streamReadBool(streamId)
547
548 if self.isOwner then
549 local index = streamReadInt32(streamId)
550 --print("CLIENT ( "..tostring(self).." ): x/y/z = "..tostring(x).." / "..tostring(y).." / "..tostring(z))
551 -- remove history entries before the one sent by the server
552 while self.networkInformation.history[1] ~= nil and self.networkInformation.history[1].index <= index do
553 table.remove(self.networkInformation.history, 1)
554 end
555 -- set position sent by server
556 setCCTPosition(self.controllerIndex, x, y, z)
557 -- move cct from the rest of the history queue
558 -- Accumulate moves from multiple history entries so that we never apply more than 5 moveCCT's
559 local history = self.networkInformation.history
560 local numHistory = #history
561 if numHistory <= 5 then
562 for i=1,numHistory do
563 moveCCT(self.controllerIndex, history[i].movementX, history[i].movementY, history[i].movementZ, self.cctMovementCollisionMask)
564 end
565 else
566 -- Accumulate moves with different amounts so that we achieve exactly the correct historty
567 -- Some will use floored, some will use floored + 1
568 -- Use the smaller amount for the older moves as errors for older moves potentially leads to larger errors now than for more recent ones
569 local accumSizeSmall = math.floor(numHistory / 5)
570 local numSmall = 5 - numHistory + accumSizeSmall * 5
571 local startI = 1
572 for i=1,5 do
573 local endI
574 if i <= numSmall then
575 endI = startI+accumSizeSmall-1
576 else
577 endI = startI+accumSizeSmall
578 end
579 local movementX, movementY, movementZ = 0,0,0
580 for j=startI,endI do
581 movementX = movementX + history[j].movementX
582 movementY = movementY + history[j].movementY
583 movementZ = movementZ + history[j].movementZ
584 end
585 moveCCT(self.controllerIndex, movementX, movementY, movementZ, self.cctMovementCollisionMask)
586 startI = endI+1
587 end
588 end
589 -- set target physics index to current index
590 self.networkInformation.updateTargetTranslationPhysicsIndex = getPhysicsUpdateIndex() -- update until the current physics index is simulated
591 -- [animation]
592 self.baseInformation.isCrouched = streamReadBool(streamId)
593 --
594 else
595 local isControlled = streamReadBool(streamId)
596 if isControlled ~= self.isControlled then
597 self:moveToAbsoluteInternal(x, y, z)
598 if isControlled then
599 self:onEnter(false)
600 else
601 self:onLeave()
602 end
603 else
604 -- other clients: set position, refrain from using target index and start new network interpolation phase
605 setTranslation(self.rootNode, x, y, z)
606 self.networkInformation.interpolatorPosition:setTargetPosition(x, y, z)
607 if isOnGround then
608 self.networkInformation.interpolatorOnGround:setTargetValue(1.0)
609 else
610 self.networkInformation.interpolatorOnGround:setTargetValue(0.0)
611 end
612 self.networkInformation.updateTargetTranslationPhysicsIndex = -1
613 self.networkInformation.interpolationTime:startNewPhaseNetwork()
614 -- force update
615 self:raiseActive()
616 end
617 -- [animation]
618 self.baseInformation.isCrouched = streamReadBool(streamId)
619 --
620 end
621 else
622 -- server code (read data from client)
623 if connection == self.networkInformation.creatorConnection then
624 -- 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()
625 local movementX=streamReadFloat32(streamId)
626 local movementY=streamReadFloat32(streamId)
627 local movementZ=streamReadFloat32(streamId)
628
629 local qx = streamReadFloat32(streamId)
630 local qy = streamReadFloat32(streamId)
631 local qz = streamReadFloat32(streamId)
632 local qw = streamReadFloat32(streamId)
633
634 local index = streamReadInt32(streamId)
635 local isControlled = streamReadBool(streamId)
636
637 moveCCT(self.controllerIndex, movementX, movementY, movementZ, self.cctMovementCollisionMask)
638
639 self.networkInformation.interpolationTime:startNewPhaseNetwork()
640 self.networkInformation.interpolatorQuaternion:setTargetQuaternion(qx, qy, qz, qw)
641 local physicsIndex = getPhysicsUpdateIndex()
642 table.insert(self.networkInformation.history, {index=index, physicsIndex = physicsIndex})
643
644 self.networkInformation.updateTargetTranslationPhysicsIndex = physicsIndex -- update until the current physics index is simulated
645
646 self:raiseActive()
647 if isControlled ~= self.isControlled then
648 if isControlled then
649 self:onEnter(false)
650 else
651 self:onLeave()
652 end
653 end
654 -- [animation]
655 self.baseInformation.isCrouched = streamReadBool(streamId)
656 --
657 if self.isCarryingObject then
658 self.networkInformation.rotateObject = streamReadBool(streamId)
659 if self.networkInformation.rotateObject then
660 self.networkInformation.rotateObjectInputH = streamReadFloat32(streamId)
661 self.networkInformation.rotateObjectInputV = streamReadFloat32(streamId)
662 end
663 end
664 end
665 end
666end

recordPositionInformation

Description
Definition
recordPositionInformation()
Code
2596function Player:recordPositionInformation()
2597 local currentPositionX, _, currentPositionZ = getTranslation(self.graphicsRootNode)
2598 local deltaPosX = currentPositionX - self.baseInformation.lastPositionX
2599 local deltaPosZ = currentPositionZ - self.baseInformation.lastPositionZ
2600 self.baseInformation.lastPositionX = currentPositionX
2601 self.baseInformation.lastPositionZ = currentPositionZ
2602
2603 local groundDistanceCovered = MathUtil.vector2Length(deltaPosX, deltaPosZ)
2604 self.motionInformation.justMoved = groundDistanceCovered > 0.0
2605
2606 if self.baseInformation.isOnGround then
2607 self.motionInformation.currentCoveredGroundDistance = groundDistanceCovered
2608 self.motionInformation.coveredGroundDistance = self.motionInformation.coveredGroundDistance + groundDistanceCovered
2609 end
2610end

registerActionEvents

Description
Register required player action events.
Definition
registerActionEvents()
Code
2877function Player:registerActionEvents()
2878 -- register action events for the player context without switching (important when this is called from within the UI context)
2879 g_inputBinding:beginActionEventsModification(Player.INPUT_CONTEXT_NAME)
2880
2881 for actionId, inputRegisterEntry in pairs(self.inputInformation.registrationList) do
2882 local _
2883 local startActive = false
2884
2885 if inputRegisterEntry.activeType == Player.INPUT_ACTIVE_TYPE.STARTS_ENABLED then
2886 startActive = true
2887 elseif inputRegisterEntry.activeType == Player.INPUT_ACTIVE_TYPE.STARTS_DISABLED then
2888 startActive = false
2889 elseif inputRegisterEntry.activeType == Player.INPUT_ACTIVE_TYPE.IS_MOVEMENT then
2890 startActive = not self.walkingIsLocked
2891 elseif inputRegisterEntry.activeType == Player.INPUT_ACTIVE_TYPE.IS_CARRYING then
2892 startActive = self.isCarryingObject
2893 elseif inputRegisterEntry.activeType == Player.INPUT_ACTIVE_TYPE.IS_DEBUG then
2894 startActive = self.baseInformation.isInDebug
2895 end
2896
2897 -- register with conflict removal flag, will disable conflicting bindings of newly registered actions
2898 _, inputRegisterEntry.eventId = g_inputBinding:registerActionEvent(actionId, self, inputRegisterEntry.callback, inputRegisterEntry.triggerUp, inputRegisterEntry.triggerDown, inputRegisterEntry.triggerAlways, startActive, inputRegisterEntry.callbackState, true)
2899 if inputRegisterEntry.text ~= nil and inputRegisterEntry.text ~= "" then
2900 g_inputBinding:setActionEventText(inputRegisterEntry.eventId, inputRegisterEntry.text)
2901 end
2902
2903 g_inputBinding:setActionEventTextVisibility(inputRegisterEntry.eventId, inputRegisterEntry.textVisibility)
2904 end
2905
2906 if g_touchHandler ~= nil then
2907 if not self.walkingIsLocked then
2908 self.touchListenerY = g_touchHandler:registerGestureListener(TouchHandler.GESTURE_AXIS_Y, Player.touchEventLookUpDown, self)
2909 self.touchListenerX = g_touchHandler:registerGestureListener(TouchHandler.GESTURE_AXIS_X, Player.touchEventLookLeftRight, self)
2910 else
2911 g_touchHandler:removeGestureListener(self.touchListenerY)
2912 g_touchHandler:removeGestureListener(self.touchListenerX)
2913 end
2914 end
2915
2916 -- reset registration context, update event data in input system:
2917 g_inputBinding:endActionEventsModification()
2918
2919 if self.isEntered then
2920 g_currentMission.activatableObjectsSystem:activate(Player.INPUT_CONTEXT_NAME)
2921 end
2922end

removeActionEvents

Description
Remove all player action events.
Definition
removeActionEvents()
Code
2926function Player:removeActionEvents()
2927 -- reset previously disabled bindings' enabled state
2928 g_inputBinding:resetActiveActionBindings()
2929
2930 -- modify action events in player context without switching (important because this can be called from within the UI)
2931 g_inputBinding:beginActionEventsModification(Player.INPUT_CONTEXT_NAME)
2932 g_inputBinding:removeActionEventsByTarget(self)
2933 for _, inputRegisterEntry in pairs(self.inputInformation.registrationList) do
2934 inputRegisterEntry.eventId = ""
2935 end
2936 g_inputBinding:endActionEventsModification()
2937
2938 if self.isEntered then
2939 g_currentMission.activatableObjectsSystem:deactivate(Player.INPUT_CONTEXT_NAME)
2940 end
2941end

resetBrake

Description
Definition
resetBrake()
Code
2627function Player:resetBrake()
2628 self:setVelocityToMotion(0.0, 0.0, 0.0)
2629 self:setAccelerationToMotion(0.0, 0.0, 0.0)
2630 self.motionInformation.brakeForce = {0.0, 0.0, 0.0}
2631 self.motionInformation.isBraking = false
2632end

resetCameraInputsInformation

Description
Reset for input managed in update() method
Definition
resetCameraInputsInformation()
Code
2513function Player:resetCameraInputsInformation()
2514 self.inputInformation.pitchCamera = 0
2515 self.inputInformation.yawCamera = 0
2516 self.inputInformation.crouchState = Player.BUTTONSTATES.RELEASED
2517end

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
2504function Player:resetInputsInformation()
2505 self.inputInformation.moveRight = 0
2506 self.inputInformation.moveForward = 0
2507 self.inputInformation.moveUp = 0
2508 self.inputInformation.runAxis = 0
2509end

rotateObject

Description
Rotates object
Definition
rotateObject()
Code
3071function Player:rotateObject(inputValue, axisX, axisY, axisZ)
3072 local jointIndex = self.pickedUpObjectJointId
3073 local actor = 0
3074
3075 local _, objectTransform = self.model:getKinematicHelpers()
3076 local rotX, rotY, rotZ = localDirectionToLocal(self.cameraNode, objectTransform, axisX, axisY, axisZ)
3077 local dtInSec = g_physicsDt * 0.001
3078 local rotation = math.rad(90.0) * dtInSec * inputValue
3079
3080 rotateAboutLocalAxis(objectTransform, rotation, rotX, rotY, rotZ)
3081 setJointFrame(jointIndex, actor, objectTransform)
3082end

setCustomWorkStylePreset

Description
Sets a custom work style preset
Definition
setCustomWorkStylePreset()
Code
1876function Player:setCustomWorkStylePreset(presetName)
1877 if self.isDeleting then
1878 return
1879 end
1880
1881 self.model:applyCustomWorkStyle(presetName)
1882end

setCuttingAnim

Description
Set cutting animation
Definition
setCuttingAnim(bool isCutting, bool isHorizontalCut)
Arguments
boolisCuttingtrue if player is cutting
boolisHorizontalCuttrue if player is cutting horizontaly
Code
439function Player:setCuttingAnim(isCutting, isHorizontalCut)
440 if not isCutting and (self.baseInformation.isUsingChainsawHorizontal or self.baseInformation.isUsingChainsawVertical) then
441 self.baseInformation.isUsingChainsawHorizontal = false
442 self.baseInformation.isUsingChainsawVertical = false
443 elseif isCutting then
444 if isHorizontalCut then
445 self.baseInformation.isUsingChainsawHorizontal = true
446 self.baseInformation.isUsingChainsawVertical = false
447 else
448 self.baseInformation.isUsingChainsawHorizontal = false
449 self.baseInformation.isUsingChainsawVertical = true
450 end
451 end
452end

setIKDirty

Description
Sets all ik chain node to dirty so that they are recalculated
Definition
setIKDirty()
Code
1307function Player:setIKDirty()
1308 self.model:setIKDirty()
1309end

setInputState

Description
Disable given input action
Definition
setInputState()
Code
994function Player:setInputState(inputAction, state)
995--#debug assertWithCallstack(inputAction ~= nil)
996 local id = self.inputInformation.registrationList[inputAction].eventId
997 g_inputBinding:setActionEventActive(id, state)
998 g_inputBinding:setActionEventTextVisibility(id, state)
999 self.inputInformation.registrationList[inputAction].lastState = state
1000end

setLightIsActive

Description
Set torch state. This is called by the player state machine
Definition
setLightIsActive()
Code
1770function Player:setLightIsActive(isActive, noEventSend)
1771 if isActive ~= self.isTorchActive then
1772 self.isTorchActive = isActive
1773 PlayerToggleLightEvent.sendEvent(self, isActive, noEventSend)
1774
1775 self.model:enableTorch(isActive, true)
1776 end
1777end

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
1409function Player:setRotation(rotX, rotY)
1410 self.rotX = math.min(1.2, math.max(-1.5, rotX))
1411 self.rotY = rotY
1412
1413 self.graphicsRotY = rotY
1414 self.cameraRotY = rotY
1415 self.targetGraphicsRotY = rotY
1416end

setThirdPersonViewActive

Description
Enables or disables the third person view
Definition
setThirdPersonViewActive(boolean isActive)
Arguments
booleanisActivethird person view is active
Code
2749function Player:setThirdPersonViewActive(isActive)
2750 self.thirdPersonViewActive = isActive
2751
2752 self:updateCameraModelTarget()
2753end

setVisibility

Description
Sets third person mesh visibility
Definition
setVisibility(bool visibility)
Arguments
boolvisibilityif true will update visibility accordingly.
Code
1597function Player:setVisibility(visibility)
1598 self.model:setVisibility(visibility)
1599end

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
2726function Player:setWalkingLock(isLocked)
2727 self.walkingIsLocked = isLocked
2728
2729 for _, inputRegistration in pairs(self.inputInformation.registrationList) do
2730 if inputRegistration.activeType == Player.INPUT_ACTIVE_TYPE.IS_MOVEMENT then
2731 g_inputBinding:setActionEventActive(inputRegistration.eventId, not isLocked)
2732 end
2733 end
2734
2735 if g_touchHandler ~= nil then
2736 if not isLocked then
2737 self.touchListenerY = g_touchHandler:registerGestureListener(TouchHandler.GESTURE_AXIS_Y, Player.touchEventLookUpDown, self)
2738 self.touchListenerX = g_touchHandler:registerGestureListener(TouchHandler.GESTURE_AXIS_X, Player.touchEventLookLeftRight, self)
2739 else
2740 g_touchHandler:removeGestureListener(self.touchListenerY)
2741 g_touchHandler:removeGestureListener(self.touchListenerX)
2742 end
2743 end
2744end

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
1608function Player:testScope(x, y, z, coeff)
1609 local x1, y1, z1 = getTranslation(self.rootNode)
1610 local dist = MathUtil.vector3Length(x1 - x, y1 - y, z1 - z)
1611 local clipDist = self.clipDistance
1612 if dist < clipDist * clipDist then
1613 return true
1614 else
1615 return false
1616 end
1617end

throwObject

Description
Throws an object. Activates dog to fetch a ball if conditions are met.
Definition
throwObject()
Code
2295function Player:throwObject(noEventSend)
2296 PlayerThrowObjectEvent.sendEvent(self, noEventSend)
2297 if self.pickedUpObject ~= nil and self.pickedUpObjectJointId ~= nil then
2298 local pickedUpObject = self.pickedUpObject
2299 self:pickUpObject(false)
2300
2301 local mass = getMass(pickedUpObject)
2302
2303 local v = 8 * (1.1-mass/Player.MAX_PICKABLE_OBJECT_MASS) -- speed between 0.8 and 8.8 based on mass of current object
2304 local vx, vy, vz = localDirectionToWorld(self.cameraNode, 0, 0, -v)
2305 setLinearVelocity(pickedUpObject, vx, vy, vz)
2306
2307 local object = g_currentMission:getNodeObject(pickedUpObject)
2308 if object ~= nil then
2309 object.thrownFromPosition = {getWorldTranslation(self.rootNode)}
2310
2311 if object:isa(DogBall) then
2312 local dogHouse = g_currentMission:getDoghouse(self.farmId)
2313 if dogHouse ~= nil then
2314 local dog = dogHouse:getDog()
2315 if dog ~= nil then
2316 local px,py,pz = getWorldTranslation(self.rootNode)
2317 local distance, _ = getCompanionClosestDistance(dog.dogInstance, px, py, pz)
2318 if distance < 10.0 then
2319 dog:fetchItem(self, object)
2320 end
2321 end
2322 end
2323 end
2324 end
2325 elseif (self.isObjectInRange and self.lastFoundObject ~= nil) and not self.isCarryingObject then
2326 local mass = getMass(self.lastFoundObject)
2327
2328 if mass <= Player.MAX_PICKABLE_OBJECT_MASS then
2329 local v = 8 * (1.1 - mass / Player.MAX_PICKABLE_OBJECT_MASS) -- speed between 0.8 and 8.8 based on mass of current object
2330 local halfSqrt = 0.707106781
2331 -- Add the impulse in 45deg towards the y axis of the camera
2332 local vx,vy,vz = localDirectionToWorld(self.cameraNode, 0.0, halfSqrt * v, -halfSqrt * v)
2333 setLinearVelocity(self.lastFoundObject, vx, vy, vz)
2334 end
2335 end
2336end

touchEventLookLeftRight

Description
Definition
touchEventLookLeftRight()
Code
2945function Player:touchEventLookLeftRight(value)
2946 if self:getIsInputAllowed() then
2947 local factor = (g_screenWidth / g_screenHeight) * 100
2948 Player.onInputLookLeftRight(self, nil, value * factor, nil, nil, false)
2949 end
2950end

touchEventLookUpDown

Description
Definition
touchEventLookUpDown()
Code
2970function Player:touchEventLookUpDown(value)
2971 if self:getIsInputAllowed() then
2972 local factor = (g_screenHeight / g_screenWidth) * -100
2973 Player.onInputLookUpDown(self, nil, value * factor, nil, nil, false)
2974 end
2975end

unequipHandtool

Description
Definition
unequipHandtool()
Code
2042function Player:unequipHandtool()
2043 self:equipHandtool("", true)
2044end

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
823function Player:update(dt)
824 self.time = self.time + dt
825
826 -- 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)))
827 if not self.isEntered and self.isClient and self.isControlled then
828 self:updateFX()
829 end
830
831 -- check if the player is on ground
832 if self.isServer or self.isEntered then
833 local _, _, isOnGround = getCCTCollisionFlags(self.controllerIndex)
834 self.baseInformation.isOnGroundPhysics = isOnGround
835 end
836
837 if self.isClient and self.isControlled then
838 self:updateWaterParams()
839 if Platform.hasPlayer then
840 self:updateSound()
841 end
842 end
843
844 if self.isEntered and self.isClient and not g_gui:getIsGuiVisible() then
845 if not g_currentMission.isPlayerFrozen then
846 self:updatePlayerStates()
847 self.playerStateMachine:update(dt)
848 self:recordPositionInformation()
849
850 local bobDelta = 0
851 if self.cameraBobbingEnabled and not self.thirdPersonViewActive then
852 bobDelta = self:cameraBob(dt)
853 end
854 self:updateCameraTranslation(bobDelta)
855
856 self:debugDraw()
857 self.playerStateMachine:debugDraw(dt)
858
859 if not self.walkingIsLocked then
860 self.rotX = self.rotX - self.inputInformation.pitchCamera * g_gameSettings:getValue(GameSettings.SETTING.CAMERA_SENSITIVITY)
861 self.rotY = self.rotY - self.inputInformation.yawCamera * g_gameSettings:getValue(GameSettings.SETTING.CAMERA_SENSITIVITY)
862
863 if self.thirdPersonViewActive then
864 self.rotX = math.min(0, math.max(-1, self.rotX))
865
866 -- Rotate camera target around player
867 setRotation(self.thirdPersonLookatNode, -self.rotX, self.rotY, 0)
868
869 -- DebugUtil.drawDebugNode(self.thirdPersonLookatNode, "thirdPersonLookatNode", false)
870 -- DebugUtil.drawDebugNode(self.thirdPersonLookfromNode, "thirdPersonLookfromNode", false)
871 else
872 self.rotX = math.min(1.2, math.max(-1.5, self.rotX))
873 setRotation(self.cameraNode, self.rotX, self.rotY, 0)
874 setRotation(self.foliageBendingNode, 0, self.rotY, 0)
875 end
876 end
877 self:updateActionEvents()
878
879 local x, y, z = getWorldTranslation(self.cameraNode)
880 g_currentMission.activatableObjectsSystem:setPosition(x, y, z)
881 end
882 end
883
884 if self:hasHandtoolEquipped() then
885 self.baseInformation.currentHandtool:update(dt, self:getIsInputAllowed())
886
887 if self.playerStateMachine:isActive("swim") then
888 self:unequipHandtool()
889 end
890 end
891
892 self:updateInterpolation()
893
894 local isModelVisible = (self.isClient and self.isControlled) or self.thirdPersonViewActive
895
896 if isModelVisible then
897 self:updateRotation(dt)
898 end
899
900 -- animation
901 if self.isClient and self.isControlled and (not self.isEntered or isModelVisible) then
902 self:updateAnimationParameters(dt)
903 self.model:updateAnimations(dt)
904
905 -- Animation Debug
906 --local a,b,c = getWorldTranslation(self.rootNode)
907 --b = b + 1.0
908 --conditionalAnimationDebugDraw(self.model.animationInformation.player, a,b,c)
909 end
910
911 -- objects in front of player: server needs to update controlled clients, clients only themselves
912 if self.allowPlayerPickUp and self.isControlled and (self.isServer or self.isEntered) then
913 self:checkObjectInRange()
914 end
915
916 -- if self.isEntered or (self.isControlled and self.networkInformation.interpolationTime.isDirty) then
917 if self.isEntered or self.networkInformation.interpolationTime.isDirty then
918 self:raiseActive()
919 end
920
921 if self.isClient and self.isControlled and not self.isEntered and self.networkInformation.rotateObject then
922 self:rotateObject(self.networkInformation.rotateObjectInputV, 1.0, 0.0, 0.0)
923 self:rotateObject(self.networkInformation.rotateObjectInputH, 0.0, 1.0, 0.0)
924 end
925 self:resetCameraInputsInformation()
926
927 if self.isEntered then
928 self.hudUpdater:update(dt, self:getPositionData())
929 end
930end

updateActionEvents

Description
Update action event states and input hint display.
Definition
updateActionEvents()
Code
1011function Player:updateActionEvents()
1012 -- light
1013 local isDark = not g_currentMission.environment.isSunOn
1014 local eventIdToggleLight = self.inputInformation.registrationList[InputAction.TOGGLE_LIGHTS_FPS].eventId
1015 if self.playerStateMachine:isAvailable("useLight") and isDark then
1016 g_inputBinding:setActionEventTextVisibility(eventIdToggleLight, isDark and self.model:getHasTorch())
1017 end
1018
1019 local stateSwitchHandTool = false
1020 local stateActivateHandTool = false
1021 local stateInteract = false
1022 local stateAnimalPet = false
1023 local stateEnter = false
1024 local stateThrowObject = false
1025 local stateObjectLeftRight = false
1026 local stateObjectUpDown = false
1027
1028 -- tools
1029 if self.playerStateMachine:isAvailable("cycleHandtool") then
1030 stateSwitchHandTool = true
1031 end
1032
1033 if self:hasHandtoolEquipped() then
1034 stateActivateHandTool = true
1035 self.playerStateMachine:isAvailable("activateObject")
1036 else
1037 if self.playerStateMachine:isAvailable("throw") then
1038 stateThrowObject = true
1039 end
1040
1041 if self.isCarryingObject then
1042 stateObjectLeftRight = true
1043 stateObjectUpDown = true
1044 end
1045
1046 if self.playerStateMachine:isAvailable("animalPet") then
1047 local eventIdActivateObject = self.inputInformation.registrationList[InputAction.ANIMAL_PET].eventId
1048 stateAnimalPet = true
1049 g_inputBinding:setActionEventText(eventIdActivateObject, g_i18n:getText("action_petAnimal"))
1050 end
1051
1052 local eventIdInteract = self.inputInformation.registrationList[InputAction.INTERACT].eventId
1053 if self.playerStateMachine:isAvailable("drop") then
1054 g_inputBinding:setActionEventText(eventIdInteract, g_i18n:getText("action_dropObject"))
1055 stateInteract = true
1056 elseif self.playerStateMachine:isAvailable("pickup") then
1057 g_inputBinding:setActionEventText(eventIdInteract, g_i18n:getText("action_pickUpObject"))
1058 stateInteract = true
1059 elseif self.playerStateMachine:isAvailable("animalInteract") or self.playerStateMachine:isActive("animalInteract") then
1060 local animalInteractState = self.playerStateMachine:getState("animalInteract")
1061 local animalInteractText = string.format(g_i18n:getText("action_interactAnimal"), animalInteractState.interactText)
1062 g_inputBinding:setActionEventText(eventIdInteract, animalInteractText)
1063 stateInteract = true
1064 end
1065 end
1066
1067 -- enter vehicle or ride animal
1068 self.canRideAnimal = self.playerStateMachine:isAvailable("animalRide")
1069 self.canEnterVehicle = g_currentMission.interactiveVehicleInRange and g_currentMission.interactiveVehicleInRange:getIsEnterable()
1070 local vehicleIsRideable = self.canEnterVehicle and SpecializationUtil.hasSpecialization(Rideable, g_currentMission.interactiveVehicleInRange.specializations)
1071 local eventIdEnter = self.inputInformation.registrationList[InputAction.ENTER].eventId
1072 if self.canEnterVehicle and not vehicleIsRideable then
1073 g_inputBinding:setActionEventText(eventIdEnter, g_i18n:getText("button_enterVehicle"))
1074 stateEnter = true
1075 elseif self.canRideAnimal or vehicleIsRideable then
1076 local rideableName = ""
1077 if self.canRideAnimal then
1078 local rideState = self.playerStateMachine:getState("animalRide")
1079 rideableName = rideState:getRideableName()
1080 elseif vehicleIsRideable then
1081 rideableName = g_currentMission.interactiveVehicleInRange:getFullName()
1082 end
1083 g_inputBinding:setActionEventText(eventIdEnter, string.format(g_i18n:getText("action_rideAnimal"), rideableName))
1084 stateEnter = true
1085 end
1086
1087 -- first disable all inactive inputs to avoid conflicts if not active in this frame
1088 self:disableInput(InputAction.SWITCH_HANDTOOL, stateSwitchHandTool)
1089 self:disableInput(InputAction.ACTIVATE_HANDTOOL, stateActivateHandTool)
1090 self:disableInput(InputAction.INTERACT, stateInteract)
1091 self:disableInput(InputAction.ANIMAL_PET, stateAnimalPet)
1092 self:disableInput(InputAction.ENTER, stateEnter)
1093 self:disableInput(InputAction.THROW_OBJECT, stateThrowObject)
1094 self:disableInput(InputAction.ROTATE_OBJECT_LEFT_RIGHT, stateObjectLeftRight)
1095 self:disableInput(InputAction.ROTATE_OBJECT_UP_DOWN, stateObjectUpDown)
1096
1097 self:setInputState(InputAction.SWITCH_HANDTOOL, stateSwitchHandTool)
1098 self:setInputState(InputAction.ACTIVATE_HANDTOOL, stateActivateHandTool)
1099 self:setInputState(InputAction.INTERACT, stateInteract)
1100 self:setInputState(InputAction.ANIMAL_PET, stateAnimalPet)
1101 self:setInputState(InputAction.ENTER, stateEnter)
1102 self:setInputState(InputAction.THROW_OBJECT, stateThrowObject)
1103 self:setInputState(InputAction.ROTATE_OBJECT_LEFT_RIGHT, stateObjectLeftRight)
1104 self:setInputState(InputAction.ROTATE_OBJECT_UP_DOWN, stateObjectUpDown)
1105
1106
1107 -- debug movements
1108 local eventIdDebugFlyToggle = self.inputInformation.registrationList[InputAction.DEBUG_PLAYER_ENABLE].eventId
1109 g_inputBinding:setActionEventActive(eventIdDebugFlyToggle, g_flightModeEnabled)
1110 local eventIdDebugFlyUpDown = self.inputInformation.registrationList[InputAction.DEBUG_PLAYER_UP_DOWN].eventId
1111 g_inputBinding:setActionEventActive(eventIdDebugFlyUpDown, g_flightModeEnabled)
1112end

updateAnimationParameters

Description
Updates the parameters that will drive the animation
Definition
updateAnimationParameters(float dt)
Arguments
floatdtdelta time in ms
Code
759function Player:updateAnimationParameters(dt)
760 local ni = self.networkInformation
761 --local dx = (ni.interpolatorPosition.targetPositionX - ni.interpolatorPosition.lastPositionX)
762 local dy = (ni.interpolatorPosition.targetPositionY - ni.interpolatorPosition.lastPositionY)
763 --local dz = (ni.interpolatorPosition.targetPositionZ - ni.interpolatorPosition.lastPositionZ)
764 --local vx = dx / (ni.interpolationTime.interpolationDuration * 0.001)
765 local vy = dy / (ni.interpolationTime.interpolationDuration * 0.001)
766 --local vz = dz / (ni.interpolationTime.interpolationDuration * 0.001)
767 --local dirX, dirZ = math.sin(self.graphicsRotY), math.cos(self.graphicsRotY)
768 --local estimatedForwardVelocity = vx * dirX + vz * dirZ
769 -- @see using calculation in Player:updateRotation() for a less unstable speed
770 -- self.lastEstimatedForwardVelocity = self.lastEstimatedForwardVelocity * 0.5 + estimatedForwardVelocity * 0.5
771
772 if not self.isEntered and self.baseInformation.animDt ~= nil and self.baseInformation.animDt ~= 0 then
773 self.oldYaw = self.newYaw
774 self.newYaw = self.cameraRotY
775 self.estimatedYawVelocity = MathUtil.getAngleDifference(self.newYaw, self.oldYaw) / (self.baseInformation.animDt * 0.001)
776 self.baseInformation.animDt = 0
777 end
778
779 local bi = self.baseInformation
780 self.model:setAnimationParameters(bi.isOnGround, bi.isInWater, bi.isCrouched, bi.isCloseToGround, self.lastEstimatedForwardVelocity, vy, self.estimatedYawVelocity)
781end

updateFX

Description
Update particle FX.
Definition
updateFX()
Code
2400function Player:updateFX()
2401 local x, y, z = getWorldTranslation(self.rootNode)
2402
2403 self.model:updateFX(x, y, z, self.baseInformation.isInWater, self.baseInformation.plungedInWater, self.waterY)
2404end

updateInterpolation

Description
Updates interpolations for physics, camera and position
Definition
updateInterpolation()
Code
1157function Player:updateInterpolation()
1158 if self.isControlled then
1159 local needsCameraInterp = self.isServer and not self.isEntered
1160 local needsPositionInterp = self.isClient
1161
1162 if needsCameraInterp or needsPositionInterp then
1163 if self.networkInformation.interpolationTime.isDirty then
1164 self.networkInformation.interpolationTime:update(g_physicsDtUnclamped)
1165 if needsCameraInterp then
1166 local qx, qy, qz, qw = self.networkInformation.interpolatorQuaternion:getInterpolatedValues(self.networkInformation.interpolationTime.interpolationAlpha)
1167
1168 setQuaternion(self.cameraNode, qx, qy, qz, qw)
1169 end
1170 if needsPositionInterp then
1171 local x, y, z = self.networkInformation.interpolatorPosition:getInterpolatedValues(self.networkInformation.interpolationTime.interpolationAlpha)
1172
1173 -- xyz is center of the CCT capsule. We subtract a radius and half the height to get to ground level
1174 local radius, height = self.model:getCapsuleSize()
1175 setTranslation(self.graphicsRootNode, x, y - radius - height / 2, z)
1176
1177 local isOnGroundFloat = self.networkInformation.interpolatorOnGround:getInterpolatedValue(self.networkInformation.interpolationTime.interpolationAlpha)
1178 self.baseInformation.isOnGround = isOnGroundFloat > 0.99
1179 self.baseInformation.isCloseToGround = isOnGroundFloat > 0.01
1180 end
1181 end
1182 end
1183 end
1184end

updateInterpolationTick

Description
Updates interpolations for physics, camera and position
Definition
updateInterpolationTick()
Code
1116function Player:updateInterpolationTick()
1117 if self.isEntered then
1118 local xt, yt, zt = getTranslation(self.rootNode)
1119
1120 -- Reuse the existing target position if the change is very small to avoid jitter
1121 local interpPos = self.networkInformation.interpolatorPosition
1122 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
1123 xt, yt, zt = interpPos.targetPositionX, interpPos.targetPositionY, interpPos.targetPositionZ
1124 end
1125 self.networkInformation.interpolatorPosition:setTargetPosition(xt, yt, zt)
1126
1127 if self.baseInformation.isOnGroundPhysics then
1128 self.networkInformation.interpolatorOnGround:setTargetValue(1.0)
1129 else
1130 self.networkInformation.interpolatorOnGround:setTargetValue(0.0)
1131 end
1132 self.networkInformation.interpolationTime:startNewPhase(75)
1133 elseif self.networkInformation.updateTargetTranslationPhysicsIndex >= 0 then
1134 local xt, yt, zt = getTranslation(self.rootNode)
1135 if getIsPhysicsUpdateIndexSimulated(self.networkInformation.updateTargetTranslationPhysicsIndex) then
1136 self.networkInformation.updateTargetTranslationPhysicsIndex = -1
1137 else
1138 -- Reuse the existing target position if the change is very small to avoid jitter
1139 local interpPos = self.networkInformation.interpolatorPosition
1140 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
1141 xt, yt, zt = interpPos.targetPositionX, interpPos.targetPositionY, interpPos.targetPositionZ
1142 end
1143 end
1144 self.networkInformation.interpolatorPosition:setTargetPosition(xt, yt, zt)
1145 if self.baseInformation.isOnGroundPhysics then
1146 self.networkInformation.interpolatorOnGround:setTargetValue(1.0)
1147 else
1148 self.networkInformation.interpolatorOnGround:setTargetValue(0.0)
1149 end
1150 self.networkInformation.interpolatorQuaternion:setTargetQuaternion(self.networkInformation.interpolatorQuaternion.targetQuaternionX, self.networkInformation.interpolatorQuaternion.targetQuaternionY, self.networkInformation.interpolatorQuaternion.targetQuaternionZ, self.networkInformation.interpolatorQuaternion.targetQuaternionW)
1151 self.networkInformation.interpolationTime:startNewPhase(75)
1152 end
1153end

updateKinematic

Description
Updates player movement depending on inputs (run, crouch, swim) and apply gravity
Definition
updateKinematic()
Code
2636function Player:updateKinematic(dt)
2637 local dtInSec = dt * 0.001
2638 local inputX = self.inputInformation.moveRight
2639 local inputZ = self.inputInformation.moveForward
2640 if inputX ~= 0.0 or inputZ ~= 0.0 then
2641 local normInputX, normInputZ = MathUtil.vector2Normalize(inputX, inputZ)
2642 local _
2643 self.motionInformation.currentWorldDirX, _, self.motionInformation.currentWorldDirZ = localDirectionToWorld(self.cameraNode, normInputX, 0.0, normInputZ)
2644 self.motionInformation.currentWorldDirX, self.motionInformation.currentWorldDirZ = MathUtil.vector2Normalize(self.motionInformation.currentWorldDirX, self.motionInformation.currentWorldDirZ)
2645 end
2646 local desiredSpeed = self:getDesiredSpeed()
2647 local desiredSpeedX = self.motionInformation.currentWorldDirX * desiredSpeed
2648 local desiredSpeedZ = self.motionInformation.currentWorldDirZ * desiredSpeed
2649
2650 local speedChangeX = (desiredSpeedX - self.motionInformation.currentSpeedX)
2651 local speedChangeZ = (desiredSpeedZ - self.motionInformation.currentSpeedZ)
2652
2653 if not self.baseInformation.isOnGround then
2654 -- reduce acceleration when in the air
2655 speedChangeX = speedChangeX * 0.2
2656 speedChangeZ = speedChangeZ * 0.2
2657 end
2658
2659 self.motionInformation.currentSpeedX = self.motionInformation.currentSpeedX + speedChangeX
2660 self.motionInformation.currentSpeedZ = self.motionInformation.currentSpeedZ + speedChangeZ
2661 self.motionInformation.currentSpeed = math.sqrt(self.motionInformation.currentSpeedX * self.motionInformation.currentSpeedX + self.motionInformation.currentSpeedZ * self.motionInformation.currentSpeedZ)
2662
2663 local movementX = self.motionInformation.currentSpeedX * dtInSec
2664 local movementY = 0.0
2665 local movementZ = self.motionInformation.currentSpeedZ * dtInSec
2666
2667 -- Swim adjustment
2668 local _, y, _ = getWorldTranslation(self.rootNode)
2669 local deltaWater = y - self.waterY - self.model.capsuleTotalHeight * 0.5
2670 local waterLevel = self.baseInformation.waterLevel
2671
2672 local distToWaterLevel = deltaWater - waterLevel
2673
2674 if distToWaterLevel > 0.001 then
2675 -- Update gravity / vertical movement
2676 local gravityFactor = 3.0 -- for falling faster
2677 local gravitySpeedChange = gravityFactor * self.motionInformation.gravity * dtInSec
2678 self.motionInformation.currentSpeedY = math.max(self.motionInformation.currentSpeedY + gravitySpeedChange, self.motionInformation.gravity * 7.0) -- clamp after 7s of falling
2679 if distToWaterLevel < self.model.capsuleTotalHeight * 0.5 then
2680 -- hack to reduce unsteability in low framerate
2681 movementY = math.max(self.motionInformation.currentSpeedY * dtInSec, -distToWaterLevel * 0.5)
2682 else
2683 movementY = math.max(self.motionInformation.currentSpeedY * dtInSec, -distToWaterLevel)
2684 end
2685 self.motionInformation.currentSpeedY = movementY / math.max(dtInSec, 0.000001) -- calc actual speed with clamped movement
2686 elseif distToWaterLevel < -0.01 then
2687 local buoyancySpeed = -self.motionInformation.gravity
2688 movementY = math.min(buoyancySpeed * dtInSec, -distToWaterLevel)
2689 self.motionInformation.currentSpeedY = movementY / math.max(dtInSec, 0.000001) -- calc actual speed with clamped movement
2690 else
2691 self.motionInformation.currentSpeedY = 0.0
2692 end
2693
2694 self:movePlayer(dt, movementX, movementY, movementZ)
2695end

updateNetworkMovementHistory

Description
Definition
updateNetworkMovementHistory()
Code
1188function Player:updateNetworkMovementHistory()
1189 if self.isEntered and self.isClient then
1190 self:raiseDirtyFlags(self.networkInformation.dirtyFlag)
1191 elseif self.isServer and not self.isEntered and self.isControlled then
1192 -- find the latest index, which is already simulated now
1193 local latestSimulatedIndex = -1
1194 while self.networkInformation.history[1] ~= nil and getIsPhysicsUpdateIndexSimulated(self.networkInformation.history[1].physicsIndex) do
1195 latestSimulatedIndex = self.networkInformation.history[1].index
1196 table.remove(self.networkInformation.history, 1)
1197 end
1198 if latestSimulatedIndex >= 0 then
1199 self.networkInformation.sendIndex = latestSimulatedIndex
1200 self:raiseDirtyFlags(self.networkInformation.dirtyFlag)
1201 end
1202 end
1203end

updatePlayerStates

Description
Updates player state machine
Definition
updatePlayerStates()
Code
2699function Player:updatePlayerStates()
2700 if self.playerStateMachine:isAvailable("fall") then
2701 self.playerStateMachine:activateState("fall")
2702 end
2703
2704 if self.baseInformation.waterDepth > 0.4 then
2705 self.playerStateMachine:deactivateState("crouch")
2706 end
2707
2708 if self.baseInformation.isInWater and self.playerStateMachine:isAvailable("swim") then
2709 self.playerStateMachine:activateState("swim")
2710 end
2711
2712 if (self.inputInformation.moveForward ~= 0) or (self.inputInformation.moveRight ~= 0) then
2713 if (self.inputInformation.runAxis > 0.0) and self.playerStateMachine:isAvailable("run") then
2714 self.playerStateMachine:activateState("run")
2715 elseif self.playerStateMachine:isAvailable("walk") then
2716 self.playerStateMachine:activateState("walk")
2717 end
2718 else
2719 self.playerStateMachine:activateState("idle")
2720 end
2721end

updateRotation

Description
Updates rotation of player avatar over the network
Definition
updateRotation(float dt)
Arguments
floatdtdelta time in ms
Code
1208function Player:updateRotation(dt)
1209 if not self.isEntered then
1210 local animDt = 60
1211 self.animUpdateTime = self.animUpdateTime + dt
1212 if self.animUpdateTime > animDt then
1213 if self.isServer then
1214 local x, _, z = localDirectionToLocal(self.cameraNode, getParent(self.cameraNode), 0, 0, 1)
1215 local alpha = math.atan2(x, z)
1216 self.cameraRotY = alpha
1217 end
1218
1219 local x, y, z = getTranslation(self.graphicsRootNode)
1220 local dx, _, dz = x - self.lastAnimPosX, y - self.lastAnimPosY, z - self.lastAnimPosZ
1221 local dirX, dirZ = -math.sin(self.cameraRotY), -math.cos(self.cameraRotY)
1222 local movementDist = dx * dirX + dz * dirZ -- Note: |dir| = 1
1223
1224 if (dx * dx + dz * dz) < 0.001 then
1225 self.targetGraphicsRotY = self.cameraRotY + math.rad(180.0)
1226 else
1227 if movementDist > -0.001 then
1228 self.targetGraphicsRotY = math.atan2(dx, dz)
1229 else
1230 self.targetGraphicsRotY = math.atan2(-dx, -dz)
1231 end
1232 end
1233
1234 dirX, dirZ = -math.sin(self.targetGraphicsRotY), -math.cos(self.targetGraphicsRotY)
1235 movementDist = dx * dirX + dz * dirZ -- Note: |dir| = 1
1236 movementDist = self.walkDistance * 0.2 + movementDist * 0.8
1237 self.walkDistance = movementDist
1238 self.lastEstimatedForwardVelocity = -movementDist / (self.animUpdateTime * 0.001)
1239
1240 self.lastAnimPosX = x
1241 self.lastAnimPosY = y
1242 self.lastAnimPosZ = z
1243
1244 self.baseInformation.animDt = self.animUpdateTime
1245 self.animUpdateTime = 0
1246 end
1247
1248 self.targetGraphicsRotY = MathUtil.normalizeRotationForShortestPath(self.targetGraphicsRotY, self.graphicsRotY)
1249 local maxDeltaRotY = math.rad(0.5) * dt
1250 self.graphicsRotY = math.min(math.max(self.targetGraphicsRotY, self.graphicsRotY - maxDeltaRotY), self.graphicsRotY + maxDeltaRotY)
1251
1252 self.model:setSkeletonRotation(self.graphicsRotY)
1253 elseif self.thirdPersonViewActive then
1254 local x, y, z = getTranslation(self.graphicsRootNode)
1255 local dx, _, dz = x - self.lastAnimPosX, y - self.lastAnimPosY, z - self.lastAnimPosZ
1256
1257 local horizontalSpeed = math.sqrt(dx * dx + dz * dz)
1258 self.horizontalSpeed = horizontalSpeed
1259 self.lastEstimatedForwardVelocity = horizontalSpeed / (dt * 0.001)
1260
1261 -- At speed 0, dirY is also 0 so it always resets to a base rotation.
1262 if horizontalSpeed > 0.0001 then
1263 local dirY = MathUtil.getYRotationFromDirection(dx, dz)
1264 local newY = self.graphicsRotY
1265
1266 local diff = (dirY - newY) / (dt * 0.05)
1267 diff = MathUtil.clamp(diff, -0.1, 0.1)
1268
1269 newY = newY + diff
1270
1271 self.graphicsRotY = newY
1272 self.model:setSkeletonRotation(newY)
1273 self.cameraRotY = newY
1274 end
1275
1276 self.oldYaw = self.newYaw
1277 self.newYaw = self.cameraRotY
1278
1279 -- Used for player rotation in animation
1280 self.estimatedYawVelocity = MathUtil.getAngleDifference(self.newYaw, self.oldYaw) / dt * math.min(self.horizontalSpeed * 50, 10)
1281
1282 self.lastAnimPosX = x
1283 self.lastAnimPosY = y
1284 self.lastAnimPosZ = z
1285
1286 self.baseInformation.animDt = dt
1287 end
1288end

updateSound

Description
Update sound for the player: steps (when crouch, walk, run), swim, plunge
Definition
updateSound()
Code
2356function Player:updateSound()
2357 local isCrouching, isWalking, isRunning, isSwimming
2358 local forwardVel
2359
2360 isCrouching = self.playerStateMachine:isActive("crouch")
2361 isSwimming = self.playerStateMachine:isActive("swim")
2362
2363 if not self.isEntered then
2364 forwardVel = self.model:getLastForwardVelocity()
2365
2366 if isCrouching then
2367 elseif math.abs(forwardVel) <= self.motionInformation.maxWalkingSpeed then
2368 isWalking = true
2369 elseif math.abs(forwardVel) > self.motionInformation.maxWalkingSpeed then
2370 isRunning = true
2371 end
2372 else
2373 forwardVel = math.abs(self.motionInformation.currentSpeed)
2374 isWalking = self.playerStateMachine:isActive("walk")
2375 isRunning = self.playerStateMachine:isActive("run")
2376 end
2377
2378 -- Detect when we start jumping or when we dropped to the ground for one-shot sound effects
2379 local didJump = false
2380 local isJumping = self.playerStateMachine:isActive("jump")
2381 if self.wasJumping ~= isJumping then
2382 self.wasJumping = isJumping
2383
2384 didJump = isJumping
2385 end
2386
2387 local isDropping = self.playerStateMachine:isActive("fall")
2388 local didTouchGround = false
2389 if self.wasDropping ~= isDropping then
2390 self.wasDropping = isDropping
2391
2392 didTouchGround = not isDropping
2393 end
2394
2395 self.model:setSoundParameters(forwardVel, isCrouching, isWalking, isRunning, isSwimming, self.baseInformation.plungedInWater, self.baseInformation.isInWater, self.motionInformation.coveredGroundDistance, self.motionInformation.maxSwimmingSpeed, self.baseInformation.waterLevel, didJump, didTouchGround, self.waterY)
2396end

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
935function Player:updateTick(dt)
936 if self.isEntered and not g_gui:getIsGuiVisible() and not g_currentMission.isPlayerFrozen then
937 self:updateKinematic(dt)
938 end
939
940 self.playerStateMachine:updateTick(dt)
941
942 if self:hasHandtoolEquipped() then
943 self.baseInformation.currentHandtool:updateTick(dt, self:getIsInputAllowed())
944 end
945 self:updateNetworkMovementHistory()
946 self:updateInterpolationTick()
947
948 self:resetInputsInformation()
949
950
951 -- -------------------------
952 -- @todo: check and add again
953 -- -------------------------
954 -- local xt, yt, zt = getTranslation(self.rootNode)
955 -- --[[
956 -- if GS_PLATFORM_PLAYSTATION or GS_PLATFORM_XBOX then
957 -- xt = xt + self.movementX
958 -- zt = zt + self.movementZ
959 -- yt = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, xt, 300, zt) + self.height
960 -- setTranslation(self.rootNode, xt, yt, zt)
961 -- end
962 -- --]]
963 -- -------------------------
964 if self.isServer and self.isControlled then
965 if not GS_PLATFORM_PC then
966 local x, y, z = getTranslation(self.rootNode)
967 local paramsXZ = g_currentMission.vehicleXZPosCompressionParams
968 if not NetworkUtil.getIsWorldPositionInCompressionRange(x, paramsXZ) or
969 not NetworkUtil.getIsWorldPositionInCompressionRange(z, paramsXZ) or
970 getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, x, y, z) > y + 20
971 then
972 self:moveTo(g_currentMission.playerStartX, g_currentMission.playerStartY, g_currentMission.playerStartZ, g_currentMission.playerStartIsAbsolute, false)
973 return
974 end
975 end
976 end
977 -- -------------------------
978
979 -- Prevent player from getting stuck in a high level of snow
980 if self.isControlled and not self.noClipEnabled then -- disable if noClip mode is enabled to allow moving below the terrain
981 local px, py, pz = getTranslation(self.rootNode)
982 local dy = DensityMapHeightUtil.getCollisionHeightAtWorldPos(px, py, pz)
983
984 local heightOffset = 0.5 * self.model.capsuleHeight -- for root node origin to terrain
985 if py < dy + heightOffset - 0.1 then
986 py = dy + heightOffset + 0.05 -- 5cm above so no clipping occurs. Gravity will fix it.
987 setTranslation(self.rootNode, px, py, pz)
988 end
989 end
990end

updateWaterParams

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
updateWaterParams()
Code
785function Player:updateWaterParams()
786 local x, y, z = getWorldTranslation(self.rootNode)
787 local yw = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, x, y, z)
788
789 g_currentMission.environmentAreaSystem:getWaterYAtWorldPositionAsync(x, y, z, function(_, waterY)
790 self.waterY = waterY or -2000
791 end, nil, nil)
792
793 local playerY = y - self.model.capsuleTotalHeight * 0.5
794 local deltaWater = playerY - self.waterY
795
796 local waterLevel = self.baseInformation.waterLevel
797 local velocityY
798
799 if deltaWater < -50 then
800 return
801 end
802
803 if not self.isEntered then
804 velocityY = self.model.animationInformation.parameters.verticalVelocity.value
805 else
806 velocityY = self.motionInformation.currentSpeedY
807 end
808
809 self.baseInformation.wasInWater = self.baseInformation.isInWater
810 self.baseInformation.isInWater = deltaWater <= waterLevel
811 self.baseInformation.waterDepth = math.max(0, self.waterY - playerY)
812
813 if not self.baseInformation.wasInWater and self.baseInformation.isInWater and velocityY < self.baseInformation.plungedYVelocityThreshold then
814 self.baseInformation.plungedInWater = true
815 else
816 self.baseInformation.plungedInWater = false
817 end
818end

writeStream

Description
Writes in network stream
Definition
writeStream(integer streamId, table connection)
Arguments
integerstreamIdid of the stream to read
tableconnectionconnection information
Code
500function Player:writeStream(streamId, connection)
501 Player:superClass().writeStream(self, streamId, connection)
502 streamWriteBool(streamId, connection == self.networkInformation.creatorConnection)
503
504 local x, y, z = getTranslation(self.rootNode)
505 streamWriteFloat32(streamId, x)
506 streamWriteFloat32(streamId, y)
507 streamWriteFloat32(streamId, z)
508
509 streamWriteBool(streamId, self.isControlled)
510
511 streamWriteUIntN(streamId, self.farmId, FarmManager.FARM_ID_SEND_NUM_BITS)
512 NetworkUtil.writeNodeObjectId(streamId, self.userId)
513
514 streamWriteBool(streamId, self.isTorchActive)
515
516 local hasHandtool = self:hasHandtoolEquipped()
517 streamWriteBool(streamId, hasHandtool)
518 if hasHandtool then
519 streamWriteString(streamId, NetworkUtil.convertToNetworkFilename(self.baseInformation.currentHandtool.configFileName))
520 end
521end

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
673function Player:writeUpdateStream(streamId, connection, dirtyMask)
674 if not connection:getIsServer() then
675 -- server code (send data to client)
676 local x, y, z = getTranslation(self.rootNode)
677 --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))
678 streamWriteFloat32(streamId, x)
679 streamWriteFloat32(streamId, y)
680 streamWriteFloat32(streamId, z)
681
682 local dx, _, dz = localDirectionToLocal(self.cameraNode, getParent(self.cameraNode), 0, 0, 1)
683 local alpha = math.atan2(dx, dz)
684 streamWriteFloat32(streamId, alpha)
685
686 streamWriteBool(streamId, self.isObjectInRange)
687 if self.isObjectInRange then
688 streamWriteFloat32(streamId, self.lastFoundObjectMass)
689 end
690 streamWriteBool(streamId, self.isCarryingObject)
691 streamWriteBool(streamId, self.baseInformation.isOnGroundPhysics)
692 local isOwner = connection == self.networkInformation.creatorConnection
693 if isOwner then
694 streamWriteInt32(streamId, self.networkInformation.sendIndex)
695 -- [animation]
696 local isCrouching = self.baseInformation.isCrouched
697 streamWriteBool(streamId, isCrouching)
698 --
699 else
700 streamWriteBool(streamId, self.isControlled)
701 -- [animation]
702 local isCrouching = self.baseInformation.isCrouched or self.playerStateMachine:isActive("crouch")
703 streamWriteBool(streamId, isCrouching)
704 --
705 end
706 else
707 -- client code (send data to server)
708 if self.isOwner then
709 -- sending translation information to the server and reset the translations accumulated over the update() calls
710 streamWriteFloat32(streamId, self.networkInformation.tickTranslation[1])
711 streamWriteFloat32(streamId, self.networkInformation.tickTranslation[2])
712 streamWriteFloat32(streamId, self.networkInformation.tickTranslation[3])
713 self.networkInformation.tickTranslation[1] = 0.0
714 self.networkInformation.tickTranslation[2] = 0.0
715 self.networkInformation.tickTranslation[3] = 0.0
716 local x, y, z, w = getQuaternion(self.cameraNode)
717 streamWriteFloat32(streamId, x) -- ? ToDo: Utils.writeCompressedQuaternion()
718 streamWriteFloat32(streamId, y)
719 streamWriteFloat32(streamId, z)
720 streamWriteFloat32(streamId, w)
721
722 streamWriteInt32(streamId, self.networkInformation.index)
723 streamWriteBool(streamId, self.isControlled)
724 -- [animation]
725 local isCrouching = self.playerStateMachine:isActive("crouch")
726 streamWriteBool(streamId, isCrouching)
727 --
728 if self.isCarryingObject then
729 streamWriteBool(streamId, self.networkInformation.rotateObject)
730 if self.networkInformation.rotateObject then
731 streamWriteFloat32(streamId, self.networkInformation.rotateObjectInputH)
732 streamWriteFloat32(streamId, self.networkInformation.rotateObjectInputV)
733 end
734 end
735 end
736 end
737end