[bb] capsule collider using one pivot + several linepicks + pickables by RemiD [ 11 months ago ]

Started by BlitzBot, June 29, 2017, 00:28:41

Previous topic - Next topic

BlitzBot

Title : capsule collider using one pivot + several linepicks + pickables
Author : RemiD
Posted : 11 months ago

Description : for characters, for vehicles, using Blitz3d linepick system

Code :
Code (blitzbasic) Select
rd-stuff.fr/one-pivot+several-linepicks+pickables-code-example.bb (or see the posts below to copy the 3 parts of the code)

Comments :


BlitzSupport(Posted 11 months ago)

 Hi, RemiD, did you mean to just link to the code for some reason? That wouldn't really be the point of the Code Archives and it would be better placed in a forum post if you don't want to post the actual code here.


RemiD(Posted 11 months ago)

 It is too long, when i try to submit it i get an internal error... Should i split it in several parts ?


BlitzSupport(Posted 11 months ago)

 I'd suggest adding the link as a post in the other Capsule Collider entry you've made, as a related example. The archives should really be full of 'direct' code, without worry that an external web site might disappear at some point.Hope this makes sense.


RemiD(Posted 11 months ago)

 No these 2 codes don't use the same approach for collisions (this one  uses linepicks and pickables meshes, the other uses ellipsoids and collidables meshes).But i will try to post the code in several parts so that it does not rely on my server.<div class="quote"> The archives should really be full of 'direct' code, without worry that an external web site might disappear at some point. </div>make sure to comment on the others code archive entries which do not respect this...


RemiD(Posted 11 months ago)

 Part1 :
Graphics3D(640,480,32,2)  
HidePointer()  

SeedRnd(MilliSecs())  

Global Arial14Font = LoadFont("Arial",14,False,False,False)

Global MPX%
Global MPY%
Global MXDiff#
Global MYDiff#

Global MZOld% = 0
Global MZCur% = 0
Global MWheel% = 0

Const CIdle% = 1 ;Up
Const CPressed% = 2 ;UpToDown
Const CHeld% = 3 ;Down
Const CReleased% = 4 ;DownToUp

Global KeySpaceState%
Global KeySpacePrevState%
Global KeySpaceDownCount

Origine = CreateCube()  
ScaleMesh(Origine,0.01/2,0.01/2,0.01/2)
EntityColor(Origine,255,000,255)

Global Camera = CreateCamera()  
CameraRange(Camera,0.1,100)
CameraClsColor(Camera,000,000,000)  

;terrain
Global TerrainROAM
BuildTerrain()

;buildings
Global BuildingsCount%
Dim BuildingRoot(11)
Dim BuildingRenderer(11)
Dim BuildingXZRadius#(11)
Dim BuildingPickable(11)
BuildBuildings()

;stairs
Global StairsCount%
Dim StairRoot(100)
Dim StairRenderer(100)
Dim StairXZRadius#(100)
Dim StairPickable(100)
BuildStairs()

;slopes
Global SlopesCount%
Dim SlopeRoot(100)
Dim SlopeRenderer(100)
Dim SlopeXZRadius#(100)
Dim SlopePickable(100)
BuildSlopes()

;rocks
Global RocksCount%
Dim RockRoot(10)
Dim RockRenderer(10)
Dim RockXZRadius#(10)
Dim RockPickable(10)
BuildRocks()

;trees
Global TreesCount%
Dim TreeRoot(10)
Dim TreeRenderer(10)
Dim TreeXZRadius#(10)
Dim TreePickable(10)
BuildTrees()

;crates
Global CratesCount%
Dim CrateRoot(10)
Dim CrateRenderer(10)
Dim CrateXZRadius#(10)
Dim CratePickable(10)
BuildCrates()

;barrels
Global BarrelsCount%
Dim BarrelRoot(10)
Dim BarrelRenderer(10)
Dim BarrelXZRadius#(10)
Dim BarrelPickable(10)
BuildBarrels()

;platforms
Global PlatformsCount%
Dim PlatformRoot(100)
Dim PlatformRenderer(100)
Dim PlatformXZRadius#(100)
Dim PlatformPickable(100)
Dim PlatformState%(100)
BuildPlatforms()

Global HumanoidsCount%
Dim HumanoidRoot(10)
Dim HumanoidRootYaw#(10)
Dim HumanoidMiddle(10)
Dim HumanoidEyes(10)
Dim HumanoidEyesPitch#(10)
Dim HumanoidRenderer(10)
Dim HumanoidXZRadius#(10)
Dim HumanoidPickable(10)
Dim HumanoidPostureMode%(10) ;CCrouching CStanding
Dim HumanoidMoveForce#(10)
Dim HumanoidJumpForce#(10)
Dim HumanoidPositionState%(10) ;COnAir or COnGround
Dim HumanoidActionState%(10) ;
Dim HumanoidAnimationState%(10) ;
Dim HumanoidGVX#(10)
Dim HumanoidGVY#(10)
Dim HumanoidGVZ#(10)
Dim HumanoidTarget(10)
BuildHumanoids()

Const COnAir% = 1
Const COnSlope% = 2
Const COnLedge% = 3
Const COnLadder% = 4
Const COnGround% = 5

Const CCrouching% = 1
Const CStanding% = 2

Const CIsCrouchingIdle% = 1
Const CIsCrouchingForward% = 2
Const CIsCrouchingBackward% = 3
Const CIsCrouchingLeft% = 4
Const CIsCrouchingRight% = 5

Const CIsStandingIdle% = 6
Const CIsStandingForward% = 7
Const CIsStandingBackward% = 8
Const CIsStandingLeft% = 9
Const CIsStandingRight% = 10

Const CIsJumping% = 11
Const CIsFalling% = 12
Const CIsLanding% = 13

Const CIsSliding% = 14

;Const CIsGrabbing% =
;Const CIsClimbing% =
;Const CIsLettingGo% =

Global CapsuleRoot = CreatePivot()

Global LPsCount%
Dim LPY#(6)

Global PsCount%
Dim PStartX#(6)
Dim PStartY#(6)
Dim PStartZ#(6)
Dim PPickable%(6)
Dim PPointX#(6)
Dim PPointY#(6)
Dim PPointZ#(6)
Dim PNormalX#(6)
Dim PNormalY#(6)
Dim PNormalZ#(6)

Global Point = CreateCube()
ScaleMesh(Point,0.03/2,0.03/2,0.03/2)
EntityColor(Point,255,000,255)

SunLight = CreateLight(1)  
LightColor(SunLight,200,200,200)  
PositionEntity(SunLight,-1000,1000,-1000,True)  
RotateEntity(SunLight,45,-45,0,True)  

AmbientLight(100,100,100)

PositionEntity(Camera,64,32,-16,True)
RotateEntity(Camera,45,0,0,True)

Global PlayerId%
PlayerId = Rand(1,10)
PositionRotateEntityLikeOtherEntity(Camera,HumanoidEyes(PlayerId))
MoveEntity(Camera,0,0,-3)
HumanoidPostureMode(PlayerId) = CStanding
HumanoidMoveForce(PlayerId) = 0.15

Global LoopTimer = CreateTimer(20)
Global MainLoopMsTime%

Global SetSomeObstaclesAsPickableMsTime%
Global LinepicksMsTime%

Main()

ClearWorld()

End()



RemiD(Posted 11 months ago)

 Part2:Function Main()

 While( KeyDown(1)<>1 )

  MainLoopMsStart% = MilliSecs()

  GetMouseInput()
  GetKeyboardInput()

  UpdatePlayer()
  UpdateAI()

  If( KeyDown(2)=1 )
   Wireframe(True)
  Else
   Wireframe(False)
  EndIf

  PositionRotateEntityLikeOtherEntity(Camera,HumanoidEyes(PlayerId))
  MoveEntity(Camera,0,0,-3)

  SetBuffer(BackBuffer())
  RenderWorld()

  SetFont(Arial14Font)
  Color(255,255,255)
  CText("PlayerPostureMode = "+PostureModeStr(HumanoidPostureMode(PlayerId)),0,0)
  CText("PlayerMoveForce = "+HumanoidMoveForce(PlayerId),0,14)
  CText("PlayerJumpForce = "+HumanoidJumpForce(PlayerId),0,28)
  CText("PlayerPositionState = "+PositionStateStr(HumanoidPositionState(PlayerId)),0,42)
  CText("PlayerActionState = "+ActionStateStr(HumanoidActionState(PlayerId)),0,56)
  CText("PlayerGVX = "+HumanoidGVX(PlayerId),0,70)
  CText("PlayerGVY = "+HumanoidGVY(PlayerId),0,84)
  CText("PlayerGVZ = "+HumanoidGVZ(PlayerId),0,98)

  CText("SetSomeObstaclesAsPickableMsTime = "+SetSomeObstaclesAsPickableMsTime,400,0)
  CText("LinepicksMsTime = "+LinepicksMsTime,400,14)

  WaitTimer(LoopTimer)
  VWait()
  Flip()

  MainLoopMsTime% = MilliSecs() - MainLoopMsStart

 Wend

End Function

Function CText(TextStr$,PX%,PY%)
 Text(PX,PY,TextStr,False,False)
End Function

Function PositionEntityLikeOtherEntity(Entity,OEntity)
 PositionEntity(Entity,EntityX(OEntity,True),EntityY(OEntity,True),EntityZ(OEntity,True),True)
End Function

Function RotateEntityLikeOtherEntity(Entity,OEntity)
 RotateEntity(Entity,EntityPitch(OEntity,True),EntityYaw(OEntity,True),EntityRoll(OEntity,True),True)
End Function

Function PositionRotateEntityLikeOtherEntity(Entity,OEntity)
 PositionEntity(Entity,EntityX(OEntity,True),EntityY(OEntity,True),EntityZ(OEntity,True),True)
 RotateEntity(Entity,EntityPitch(OEntity,True),EntityYaw(OEntity,True),EntityRoll(OEntity,True),True)
End Function

Function SetEntityAsChildOfOtherEntity(Entity,OEntity)
 EntityParent(Entity,OEntity,True)
End Function

Function SetEntityAsFree(Entity)
 EntityParent(Entity,0)
End Function

Function Diag#(SideLength#)
 Diag# = Sqr( (SideLength * SideLength) + (SideLength * SideLength) )
 Return Diag
End Function

Function Distance2D#(PAX#,PAZ#,PBX#,PBZ#)
 VX# = PBX - PAX
 VZ# = PBZ - PAZ
 Distance2D# = Sqr((VX*VX)+(VZ*VZ))
 Return Distance2D
End Function

Function Distance3D#(PAX#,PAY#,PAZ#,PBX#,PBY#,PBZ#)
 VX# = PBX - PAX
 VY# = PBY - PAY
 VZ# = PBZ - PAZ
 Distance3D# = Sqr((VX*VX)+(VY*VY)+(VZ*VZ))
 Return Distance3D
End Function

Function AddSurfaceToOtherSurface(Mesh,Surface,OSurface)
 For TId% = 0 To CountTriangles(Surface)-1
  ;V0
  V0Id% = TriangleVertex(Surface,TId,0)
  V0LX# = VertexX(Surface,V0Id)
  V0LY# = VertexY(Surface,V0Id)
  V0LZ# = VertexZ(Surface,V0Id)
  TFormPoint(V0LX,V0LY,V0LZ,Mesh,0)
  V0GX# = TFormedX()
  V0GY# = TFormedY()
  V0GZ# = TFormedZ()
  V0NX# = VertexNX(Surface,V0Id)
  V0NY# = VertexNY(Surface,V0Id)
  V0NZ# = VertexNZ(Surface,V0Id)
  ;V1
  V1Id% = TriangleVertex(Surface,TId,1)
  V1LX# = VertexX(Surface,V1Id)
  V1LY# = VertexY(Surface,V1Id)
  V1LZ# = VertexZ(Surface,V1Id)
  TFormPoint(V1LX,V1LY,V1LZ,Mesh,0)
  V1GX# = TFormedX()
  V1GY# = TFormedY()
  V1GZ# = TFormedZ()
  V1NX# = VertexNX(Surface,V1Id)
  V1NY# = VertexNY(Surface,V1Id)
  V1NZ# = VertexNZ(Surface,V1Id)
  ;V2
  V2Id% = TriangleVertex(Surface,TId,2)
  V2LX# = VertexX(Surface,V2Id)
  V2LY# = VertexY(Surface,V2Id)
  V2LZ# = VertexZ(Surface,V2Id)
  TFormPoint(V2LX,V2LY,V2LZ,Mesh,0)
  V2GX# = TFormedX()
  V2GY# = TFormedY()
  V2GZ# = TFormedZ()
  V2NX# = VertexNX(Surface,V2Id)
  V2NY# = VertexNY(Surface,V2Id)
  V2NZ# = VertexNZ(Surface,V2Id)
  ;Triangle
  OldVerticesCount = CountVertices(OSurface)
  NV0Id% = OldVerticesCount-1 + 1
  NV1Id% = OldVerticesCount-1 + 2
  NV2Id% = OldVerticesCount-1 + 3
  AddVertex(OSurface,V0GX,V0GY,V0GZ)
  VertexNormal(OSurface,NV0Id,V0NX,V0NY,V0NZ)
  AddVertex(OSurface,V1GX,V1GY,V1GZ)
  VertexNormal(OSurface,NV1Id,V1NX,V1NY,V1NZ)
  AddVertex(OSurface,V2GX,V2GY,V2GZ)
  VertexNormal(OSurface,NV2Id,V2NX,V2NY,V2NZ)
  AddTriangle(OSurface,NV0Id,NV1Id,NV2Id)
 Next
End Function

Function ColorSurfaceWithBrush(Surface,R%,G%,B%,A#=1.0,Fx%=0)
 TBrush = CreateBrush()
 BrushColor(TBrush,R,G,B)
 BrushAlpha(TBrush,A)
 BrushFX(TBrush,Fx)
 PaintSurface(Surface,TBrush)
 FreeBrush(TBrush)
End Function

Function BuildTerrain()

 TerrainROAM = CreateTerrain(128)
 For HX% = 0 To 128-1 Step 1
  For HZ% = 0 To 128-1 Step 1
   HeightRGB% = Rand(030,032) ;030 to 032 for 20cm variation
   HeightY# = 1.0/255.0*Float(HeightRGB)
   ModifyTerrain(TerrainROAM,HX,HZ,HeightY,False)
  Next
 Next
 ScaleEntity(TerrainROAM,1,25.5,1)
 TerrainDetail(TerrainROAM,4000,True)
 TerrainShading(TerrainROAM,True)
 EntityAlpha(TerrainROAM,0.5)

 TerrainDiffuseTexture = CreateTexture(128,128)
 SetBuffer(TextureBuffer(TerrainDiffuseTexture))
  For PX% = 0 To 128-1 Step 1
   For PY% = 0 To 128-1 Step 1
    R% = 000
    G% = Rand(090,110)
    B% = 000
    Color(R,G,B)
    Plot(PX,PY)
   Next
  Next
 ScaleTexture(TerrainDiffuseTexture,128,128)
 TextureBlend(TerrainDiffuseTexture,2)
 ;EntityTexture(TerrainROAM,TerrainDiffuseTexture,0,0)

 NameEntity(TerrainROAM,"TER"+Str(1))

End Function

Function BuildBuildings()
 
 For i% = 1 To 10 Step 1

  Levels% = Rand(1,15)
 
  BuildingsCount = BuildingsCount + 1
  Id% = BuildingsCount

  BuildingRoot(Id) = CreatePivot()

  BuildingRenderer(Id) = CreateMesh()
  CreateSurface(BuildingRenderer(Id))
  For L% = 1 To Levels Step 1
   TWidth# = Rand(3,10)
   TDepth# = Rand(3,10)
   For GX# = 0 To TWidth-1 Step 1
    For GZ# = 0 To TDepth-1 Step 1
     RandomChoice% = Rand(1,3)
     If( RandomChoice = 1 Or RandomChoice = 2  )
      ;add a part
      TPart = CreateCube()
      ScaleMesh(TPart,1.0/2,1.0/2,1.0/2)
      PositionMesh(TPart,1.0/2,1.0/2,1.0/2)
      PositionMesh(TPart,GX,L-1,GZ)
      AddSurfaceToOtherSurface(TPart,GetSurface(TPart,1),GetSurface(BuildingRenderer(Id),1))
      FreeEntity(TPart)
     Else If( RandomChoice = 3 )
      ;add nothing
     EndIf
    Next
   Next
  Next
  MWidth# = MeshWidth(BuildingRenderer(Id))
  MDepth# = MeshDepth(BuildingRenderer(Id))
  PositionMesh(BuildingRenderer(Id),-MWidth/2,0,-MDepth/2)
  ;ColorSurfaceWithBrush(GetSurface(BuildingRenderer(Id),1),075,075,075)
  HideEntity(BuildingRenderer(Id))

  BuildingXZRadius(Id) = Diag(10)/2

  BuildingPickable(Id) = CopyEntity(BuildingRenderer(Id))
  EntityColor(BuildingPickable(Id),255,255,255)
  EntityAlpha(BuildingPickable(Id),0.5)

  .LineChooseBuildingPosition
  PositionEntity(BuildingRoot(Id),Rnd(0+MWidth/2,128-MWidth/2),3.1,Rnd(0+MDepth/2,128-10-3-MDepth/2),True)
  ;is far enough from another building ?
  For OId% = 1 To BuildingsCount Step 1
   If( OId <> Id )
    If( Distance2D(EntityX(BuildingRoot(Id),True),EntityZ(BuildingRoot(Id),True),EntityX(BuildingRoot(OId),True),EntityZ(BuildingRoot(OId),True)) <= BuildingXZRadius(Id)+BuildingXZRadius(OId)+1 )
     Goto LineChooseBuildingPosition
    EndIf
   EndIf
  Next
  PositionRotateEntityLikeOtherEntity(BuildingRenderer(Id),BuildingRoot(Id))
  PositionRotateEntityLikeOtherEntity(BuildingPickable(Id),BuildingRoot(Id))
 
  NameEntity(BuildingPickable(Id),"BUI"+Str(Id))

 Next

End Function

Function BuildStairs()

 For THeight# = 0.125 To 0.375 Step 0.125
  For TDepth# = 0.25 To 0.5 Step 0.125

   StairsCount = StairsCount + 1
   Id% = StairsCount

   StairRoot(Id) = CreatePivot()

   StairRenderer(Id) = CreateMesh()
   CreateSurface(StairRenderer(Id))
   TWidth# = 3.0
   ;THeight# = 0.25 ;0.25
   ;TDepth# = 0.25
   For ii% = 1 To 12 Step 1
    TX# = 0
    TY# = 0+((ii-1)*THeight)
    TZ# = 0+((ii-1)*TDepth)
    TPart = CreateCube()
    ScaleMesh(TPart,TWidth/2,THeight/2,TDepth/2)
    PositionMesh(TPart,0,THeight/2,TDepth/2)
    PositionMesh(TPart,0,TY,TZ)
    AddSurfaceToOtherSurface(TPart,GetSurface(TPart,1),GetSurface(StairRenderer(Id),1))
    FreeEntity(TPart)
   Next
   ;PositionMesh(StairRenderer(Id),0,0,MeshDepth(StairRenderer(Id))/2)
   MWidth# = MeshWidth(StairRenderer(Id))
   MDepth# = MeshDepth(StairRenderer(Id))
   ;ColorSurfaceWithBrush(GetSurface(StairRenderer(Id),1),075,075,075)
   HideEntity(StairRenderer(Id))
 
   StairXZRadius(Id) = MDepth

   StairPickable(Id) = CopyEntity(StairRenderer(Id))
   EntityColor(StairPickable(Id),255,255,255)
   EntityAlpha(StairPickable(Id),0.5)

   .LineChooseStairPosition
   PositionEntity(StairRoot(Id),0+1.5+(Id-1)*3.0,3.1,128.0-10,True)
   PositionRotateEntityLikeOtherEntity(StairRenderer(Id),StairRoot(Id))
   PositionRotateEntityLikeOtherEntity(StairPickable(Id),StairRoot(Id))
 
   NameEntity(StairPickable(Id),"STA"+Str(Id))

  Next

 Next

End Function

Function BuildSlopes()

 For Pitch# = 0 To -90.0 Step -10.0

  SlopesCount = SlopesCount + 1
  Id% = SlopesCount

  SlopeRoot(Id) = CreatePivot()

  SlopeRenderer(Id) = CreateMesh()
  CreateSurface(SlopeRenderer(Id))
  TWidth# = 3.0
  TDepth# = 10.0

  TPart = CreateMesh()
  TSurface = CreateSurface(TPart)
  AddVertex(TSurface, -1.0, 0.0, 1.0 )
  AddVertex(TSurface, 1.0, 0.0, 1.0 )
  AddVertex(TSurface, -1.0, 0.0, -1.0 )
  AddVertex(TSurface, 1.0, 0.0, -1.0 )
  AddTriangle(TSurface,0,1,2)
  AddTriangle(TSurface,2,1,3)
  ScaleMesh(TPart,3.0/2,1.0,10.0/2)
  PositionMesh(TPart,0,0,10.0/2)
  RotateMesh(TPart,Pitch,0,0)
  UpdateNormals(TPart)
  ;AddSurfaceToOtherSurface(TPart,GetSurface(TPart,1),GetSurface(SlopeRenderer(Id),1))
  AddMesh(TPart,SlopeRenderer(Id))
  FreeEntity(TPart)

  ;PositionMesh(SlopeRenderer(Id),0,0,MeshDepth(SlopeRenderer(Id))/2)
  MWidth# = MeshWidth(SlopeRenderer(Id))
  MDepth# = MeshDepth(SlopeRenderer(Id))
  ;ColorSurfaceWithBrush(GetSurface(SlopeRenderer(Id),1),075,075,075)
  HideEntity(SlopeRenderer(Id))
 
  SlopeXZRadius(Id) = 13

  SlopePickable(Id) = CopyEntity(SlopeRenderer(Id))
  EntityColor(SlopePickable(Id),255,255,255)
  EntityAlpha(SlopePickable(Id),0.5)

  PositionEntity(SlopeRoot(Id),50+1.5+(Id-1)*3.0,3.1,128.0-10,True)
  PositionRotateEntityLikeOtherEntity(SlopeRenderer(Id),SlopeRoot(Id))
  PositionRotateEntityLikeOtherEntity(SlopePickable(Id),SlopeRoot(Id))
 
  NameEntity(SlopePickable(Id),"SLO"+Str(Id))

 Next

End Function

Function BuildRocks()
 
 For i% = 1 To 10 Step 1
 
  RocksCount = RocksCount + 1
  Id% = RocksCount

  RockRoot(Id) = CreatePivot()

  RockRenderer(Id) = CreateSphere(8)  
  Width# = Rnd(0.5,1.0)
  Height# = Rnd(0.25,0.5)
  Depth# = Rnd(0.5,1.0)
  ScaleMesh(RockRenderer(Id),Width/2,Height/2,Depth/2)
  ;ColorSurfaceWithBrush(GetSurface(RockRenderer(Id),1),075,075,075)
  HideEntity(RockRenderer(Id))

  RockXZRadius(Id) = 0.5

  RockPickable(Id) = CopyEntity(RockRenderer(Id))
  EntityColor(RockPickable(Id),255,255,255)
  EntityAlpha(RockPickable(Id),0.5)

  .LineChooseRockPosition
  PositionEntity(RockRoot(Id),Rnd(0+0.5,128-0.5),3.1,Rnd(0+0.5,128-10-3-0.5),True)
  ;is far enough from another building ?
  For OId% = 1 To BuildingsCount Step 1
   If( Distance2D(EntityX(RockRoot(Id),True),EntityZ(RockRoot(Id),True),EntityX(BuildingRoot(OId),True),EntityZ(BuildingRoot(OId),True)) <= RockXZRadius(Id)+BuildingXZRadius(OId)+1 )
    Goto LineChooseRockPosition
   EndIf
  Next
  ;is far enough from another stair ?
  For OId% = 1 To StairsCount Step 1
   If( Distance2D(EntityX(RockRoot(Id),True),EntityZ(RockRoot(Id),True),EntityX(StairRoot(OId),True),EntityZ(StairRoot(OId),True)) <= RockXZRadius(Id)+StairXZRadius(OId)+1 )
    Goto LineChooseRockPosition
   EndIf
  Next
  ;is far enough from another rock ?
  For OId% = 1 To RocksCount Step 1
   If( OId <> Id )
    If( Distance2D(EntityX(RockRoot(Id),True),EntityZ(RockRoot(Id),True),EntityX(RockRoot(OId),True),EntityZ(RockRoot(OId),True)) <= RockXZRadius(Id)+RockXZRadius(OId)+1 )
     Goto LineChooseRockPosition
    EndIf
   EndIf
  Next
  PositionRotateEntityLikeOtherEntity(RockRenderer(Id),RockRoot(Id))
  PositionRotateEntityLikeOtherEntity(RockPickable(Id),RockRoot(Id))
 
  NameEntity(RockPickable(Id),"ROC"+Str(Id))

 Next

End Function

Function BuildTrees()

 For i% = 1 To 10 Step 1
 
  TreesCount = TreesCount + 1
  Id% = TreesCount

  TreeRoot(Id) = CreatePivot()

  TreeRenderer(Id) = CreateMesh()
  CreateSurface(TreeRenderer(Id))
  TPart = CreateCone(4)
  ScaleMesh(TPart,0.5/2,(10.0-1.5)/2,0.5/2)
  PositionMesh(TPart,0,(10.0-1.5)/2,0)
  AddSurfaceToOtherSurface(TPart,GetSurface(TPart,1),GetSurface(TreeRenderer(Id),1))
  FreeEntity(TPart)
  OldYaw# = 0
  For Y# = 1.5 To 10-1.5 Step 0.25
   Scale# = (10.0-1.5-Y)
   If( Scale > 5.0 )
    Scale = 5.0
   EndIf
   .LineChooseBrancheYaw
   Yaw# = Rnd(-180.0,180.0)
   If( Yaw > OldYaw-45 And Yaw < OldYaw+45 )
    Goto LineChooseBrancheYaw
   EndIf
   OldYaw = Yaw
   TPart = CreateCone(4)
   ScaleMesh(TPart,Scale/20/2,Scale/2,Scale/20/2)
   PositionMesh(TPart,0,Scale/2,0)
   RotateMesh(TPart,-45,Yaw,0)
   PositionMesh(TPart,0,Y,0)
   AddSurfaceToOtherSurface(TPart,GetSurface(TPart,1),GetSurface(TreeRenderer(Id),1))
   FreeEntity(TPart)
  Next
  ;ColorSurfaceWithBrush(GetSurface(TreeRenderer(Id),1),075,050,025)
  HideEntity(TreeRenderer(Id))

  TreeXZRadius(Id) = 5.0

  TreePickable(Id) = CopyEntity(TreeRenderer(Id))
  EntityColor(TreePickable(Id),255,255,255)
  EntityAlpha(TreePickable(Id),0.5)

  .LineChooseTreePosition
  PositionEntity(TreeRoot(Id),Rnd(0+5.0,128-5.0),3.0,Rnd(0+5.0,128-10-3-5.0),True)
  ;is far enough from another building ?
  For OId% = 1 To BuildingsCount Step 1
   If( Distance2D(EntityX(TreeRoot(Id),True),EntityZ(TreeRoot(Id),True),EntityX(BuildingRoot(OId),True),EntityZ(BuildingRoot(OId),True)) <= TreeXZRadius(Id)+BuildingXZRadius(OId)+1 )
    Goto LineChooseTreePosition
   EndIf
  Next
  ;is far enough from another Stair ?
  For OId% = 1 To StairsCount Step 1
   If( Distance2D(EntityX(TreeRoot(Id),True),EntityZ(TreeRoot(Id),True),EntityX(StairRoot(OId),True),EntityZ(StairRoot(OId),True)) <= TreeXZRadius(Id)+StairXZRadius(OId)+1 )
    Goto LineChooseTreePosition
   EndIf
  Next
  ;is far enough from another rock ?
  For OId% = 1 To RocksCount Step 1
   If( Distance2D(EntityX(TreeRoot(Id),True),EntityZ(TreeRoot(Id),True),EntityX(RockRoot(OId),True),EntityZ(RockRoot(OId),True)) <= TreeXZRadius(Id)+RockXZRadius(OId)+1 )
    Goto LineChooseTreePosition
   EndIf
  Next
  ;is far enough from another tree ?
  For OId% = 1 To TreesCount Step 1
   If( OId <> Id )
    If( Distance2D(EntityX(TreeRoot(Id),True),EntityZ(TreeRoot(Id),True),EntityX(TreeRoot(OId),True),EntityZ(TreeRoot(OId),True)) <= TreeXZRadius(Id)+TreeXZRadius(OId)+1 )
     Goto LineChooseTreePosition
    EndIf
   EndIf
  Next
  PositionRotateEntityLikeOtherEntity(TreeRenderer(Id),TreeRoot(Id))
  PositionRotateEntityLikeOtherEntity(TreePickable(Id),TreeRoot(Id))
 
  NameEntity(TreePickable(Id),"TRE"+Str(Id))

 Next

End Function

Function BuildCrates()

 For i% = 1 To 10 Step 1
 
  CratesCount = CratesCount + 1
  Id% = CratesCount

  CrateRoot(Id) = CreatePivot()

  CrateRenderer(Id) = CreateMesh()
  CreateSurface(CrateRenderer(Id))
  TPart = CreateCube()
  ScaleMesh(TPart,0.5/2,0.5/2,0.5/2)
  PositionMesh(TPart,0,0.5/2,0)
  AddSurfaceToOtherSurface(TPart,GetSurface(TPart,1),GetSurface(CrateRenderer(Id),1))
  FreeEntity(TPart)
  ;ColorSurfaceWithBrush(GetSurface(CrateRenderer(Id),1),100,075,050)
  HideEntity(CrateRenderer(Id))

  CrateXZRadius(Id) = Diag(0.5)/2

  CratePickable(Id) = CopyEntity(CrateRenderer(Id))
  EntityColor(CratePickable(Id),255,255,255)
  EntityAlpha(CratePickable(Id),0.5)

  .LineChooseCratePosition
  PositionEntity(CrateRoot(Id),Rnd(0+0.25,128-0.25),3.2,Rnd(0+0.25,128-10-3-0.25),True)
  ;is far enough from another building ?
  For OId% = 1 To BuildingsCount Step 1
   If( Distance2D(EntityX(CrateRoot(Id),True),EntityZ(CrateRoot(Id),True),EntityX(BuildingRoot(OId),True),EntityZ(BuildingRoot(OId),True)) <= CrateXZRadius(Id)+BuildingXZRadius(OId)+1 )
    Goto LineChooseCratePosition
   EndIf
  Next
  ;is far enough from another Stair ?
  For OId% = 1 To StairsCount Step 1
   If( Distance2D(EntityX(CrateRoot(Id),True),EntityZ(CrateRoot(Id),True),EntityX(StairRoot(OId),True),EntityZ(StairRoot(OId),True)) <= CrateXZRadius(Id)+StairXZRadius(OId)+1 )
    Goto LineChooseCratePosition
   EndIf
  Next
  ;is far enough from another rock ?
  For OId% = 1 To RocksCount Step 1
   If( Distance2D(EntityX(CrateRoot(Id),True),EntityZ(CrateRoot(Id),True),EntityX(RockRoot(OId),True),EntityZ(RockRoot(OId),True)) <= CrateXZRadius(Id)+RockXZRadius(OId)+1 )
    Goto LineChooseCratePosition
   EndIf
  Next
  ;is far enough from another tree ?
  For OId% = 1 To TreesCount Step 1
   If( Distance2D(EntityX(CrateRoot(Id),True),EntityZ(CrateRoot(Id),True),EntityX(TreeRoot(OId),True),EntityZ(TreeRoot(OId),True)) <= CrateXZRadius(Id)+TreeXZRadius(OId)+1 )
    Goto LineChooseCratePosition
   EndIf
  Next
  ;is far enough from another crate ?
  For OId% = 1 To CratesCount Step 1
   If( OId <> Id )
    If( Distance2D(EntityX(CrateRoot(Id),True),EntityZ(CrateRoot(Id),True),EntityX(CrateRoot(OId),True),EntityZ(CrateRoot(OId),True)) <= CrateXZRadius(Id)+CrateXZRadius(OId)+1 )
     Goto LineChooseCratePosition
    EndIf
   EndIf
  Next
  PositionRotateEntityLikeOtherEntity(CrateRenderer(Id),CrateRoot(Id))
  PositionRotateEntityLikeOtherEntity(CratePickable(Id),CrateRoot(Id))
 
  NameEntity(CratePickable(Id),"CRA"+Str(Id))

 Next

End Function

Function BuildBarrels()

 For i% = 1 To 10 Step 1
 
  BarrelsCount = BarrelsCount + 1
  Id% = BarrelsCount

  BarrelRoot(Id) = CreatePivot()

  BarrelRenderer(Id) = CreateMesh()
  CreateSurface(BarrelRenderer(Id))
  TPart = CreateCylinder(8)
  ScaleMesh(TPart,0.5/2,1.0/2,0.5/2)
  PositionMesh(TPart,0,1.0/2,0)
  ;AddSurfaceToOtherSurface(TPart,GetSurface(TPart,1),GetSurface(BarrelRenderer(Id),1))
  AddMesh(TPart,BarrelRenderer(Id))
  FreeEntity(TPart)
  ;ColorSurfaceWithBrush(GetSurface(BarrelRenderer(Id),1),100,075,050)
  HideEntity(BarrelRenderer(Id))

  BarrelXZRadius(Id) = 0.25

  BarrelPickable(Id) = CopyEntity(BarrelRenderer(Id))
  EntityColor(BarrelPickable(Id),255,255,255)
  EntityAlpha(BarrelPickable(Id),0.5)

  .LineChooseBarrelPosition
  PositionEntity(BarrelRoot(Id),Rnd(0+0.25,128-0.25),3.2,Rnd(0+0.25,128-10-3-0.25),True)
  ;is far enough from another building ?
  For OId% = 1 To BuildingsCount Step 1
   If( Distance2D(EntityX(BarrelRoot(Id),True),EntityZ(BarrelRoot(Id),True),EntityX(BuildingRoot(OId),True),EntityZ(BuildingRoot(OId),True)) <= BarrelXZRadius(Id)+BuildingXZRadius(OId)+1 )
    Goto LineChooseBarrelPosition
   EndIf
  Next
  ;is far enough from another Stair ?
  For OId% = 1 To StairsCount Step 1
   If( Distance2D(EntityX(BarrelRoot(Id),True),EntityZ(BarrelRoot(Id),True),EntityX(StairRoot(OId),True),EntityZ(StairRoot(OId),True)) <= BarrelXZRadius(Id)+StairXZRadius(OId)+1 )
    Goto LineChooseBarrelPosition
   EndIf
  Next
  ;is far enough from another rock ?
  For OId% = 1 To RocksCount Step 1
   If( Distance2D(EntityX(BarrelRoot(Id),True),EntityZ(BarrelRoot(Id),True),EntityX(RockRoot(OId),True),EntityZ(RockRoot(OId),True)) <= BarrelXZRadius(Id)+RockXZRadius(OId)+1 )
    Goto LineChooseBarrelPosition
   EndIf
  Next
  ;is far enough from another tree ?
  For OId% = 1 To TreesCount Step 1
   If( Distance2D(EntityX(BarrelRoot(Id),True),EntityZ(BarrelRoot(Id),True),EntityX(TreeRoot(OId),True),EntityZ(TreeRoot(OId),True)) <= BarrelXZRadius(Id)+TreeXZRadius(OId)+1 )
    Goto LineChooseBarrelPosition
   EndIf
  Next
  ;is far enough from another crate ?
  For OId% = 1 To CratesCount Step 1
   If( Distance2D(EntityX(BarrelRoot(Id),True),EntityZ(BarrelRoot(Id),True),EntityX(CrateRoot(OId),True),EntityZ(CrateRoot(OId),True)) <= BarrelXZRadius(Id)+CrateXZRadius(OId)+1 )
    Goto LineChooseBarrelPosition
   EndIf
  Next
  ;is far enough from another Barrel ?
  For OId% = 1 To BarrelsCount Step 1
   If( OId <> Id )
    If( Distance2D(EntityX(BarrelRoot(Id),True),EntityZ(BarrelRoot(Id),True),EntityX(BarrelRoot(OId),True),EntityZ(BarrelRoot(OId),True)) <= BarrelXZRadius(Id)+BarrelXZRadius(OId)+1 )
     Goto LineChooseBarrelPosition
    EndIf
   EndIf
  Next
  PositionRotateEntityLikeOtherEntity(BarrelRenderer(Id),BarrelRoot(Id))
  PositionRotateEntityLikeOtherEntity(BarrelPickable(Id),BarrelRoot(Id))
 
  NameEntity(BarrelPickable(Id),"BAR"+Str(Id))

 Next

End Function

Function BuildPlatforms()

 For i% = 1 To 30 Step 1

  PlatformsCount = PlatformsCount + 1
  Id% = PlatformsCount

  PlatformRoot(Id) = CreatePivot()

  PlatformRenderer(Id) = CreateMesh()
  CreateSurface(PlatformRenderer(Id))
  TPart = CreateCube()
  ScaleMesh(TPart,3.0/2,0.1/2,3.0/2)
  PositionMesh(TPart,0,0.1/2,0)
  AddSurfaceToOtherSurface(TPart,GetSurface(TPart,1),GetSurface(PlatformRenderer(Id),1))
  FreeEntity(TPart)
  Width# = MeshWidth(PlatformRenderer(Id))
  Depth# = MeshDepth(PlatformRenderer(Id))
  ;ColorSurfaceWithBrush(GetSurface(PlatformRenderer(Id),1),075,075,075)
  HideEntity(PlatformRenderer(Id))

  PlatformXZRadius(Id) = Diag(3.0)/2

  PlatformPickable(Id) = CopyEntity(PlatformRenderer(Id))
  EntityColor(PlatformPickable(Id),255,255,255)
  EntityAlpha(PlatformPickable(Id),0.5)

  .LineChoosePlatformPosition
  PositionEntity(PlatformRoot(Id),Rnd(0+Width/2,128-Width/2),3.2+Rnd(0.5,10),Rnd(0+Depth/2,128-10-3-Depth/2),True)
  ;is far enough from another building ?
  For OId% = 1 To BuildingsCount Step 1
   If( Distance2D(EntityX(PlatformRoot(Id),True),EntityZ(PlatformRoot(Id),True),EntityX(BuildingRoot(OId),True),EntityZ(BuildingRoot(OId),True)) <= PlatformXZRadius(Id)+BuildingXZRadius(OId)+1 )
    Goto LineChoosePlatformPosition
   EndIf
  Next
  ;is far enough from another Stair ?
  For OId% = 1 To StairsCount Step 1
   If( Distance2D(EntityX(PlatformRoot(Id),True),EntityZ(PlatformRoot(Id),True),EntityX(StairRoot(OId),True),EntityZ(StairRoot(OId),True)) <= PlatformXZRadius(Id)+StairXZRadius(OId)+1 )
    Goto LineChoosePlatformPosition
   EndIf
  Next
  ;is far enough from another rock ?
  For OId% = 1 To RocksCount Step 1
   If( EntityY(PlatformRoot(Id)) < 3.2+0.5 And Distance2D(EntityX(PlatformRoot(Id),True),EntityZ(PlatformRoot(Id),True),EntityX(RockRoot(OId),True),EntityZ(RockRoot(OId),True)) <= PlatformXZRadius(Id)+RockXZRadius(OId)+1 )
    Goto LineChoosePlatformPosition
   EndIf
  Next
  ;is far enough from another tree ?
  For OId% = 1 To TreesCount Step 1
   If( EntityY(PlatformRoot(Id)) < 3.2+10.0 And Distance2D(EntityX(PlatformRoot(Id),True),EntityZ(PlatformRoot(Id),True),EntityX(TreeRoot(OId),True),EntityZ(TreeRoot(OId),True)) <= PlatformXZRadius(Id)+TreeXZRadius(OId)+1 )
    Goto LineChoosePlatformPosition
   EndIf
  Next
  ;is far enough from another crate ?
  For OId% = 1 To CratesCount Step 1
   If( EntityY(PlatformRoot(Id)) < 3.2+0.5 And Distance2D(EntityX(PlatformRoot(Id),True),EntityZ(PlatformRoot(Id),True),EntityX(CrateRoot(OId),True),EntityZ(CrateRoot(OId),True)) <= PlatformXZRadius(Id)+CrateXZRadius(OId)+1 )
    Goto LineChoosePlatformPosition
   EndIf
  Next
  ;is far enough from another Barrel ?
  For OId% = 1 To BarrelsCount Step 1
   If( EntityY(PlatformRoot(Id)) < 3.2+1.0 And Distance2D(EntityX(PlatformRoot(Id),True),EntityZ(PlatformRoot(Id),True),EntityX(BarrelRoot(OId),True),EntityZ(BarrelRoot(OId),True)) <= PlatformXZRadius(Id)+BarrelXZRadius(OId)+1 )
    Goto LineChoosePlatformPosition
   EndIf
  Next
  ;is far enough from another Platform ?
  For OId% = 1 To PlatformsCount Step 1
   If( OId <> Id )
    If( EntityY(PlatformRoot(Id)) => EntityY(PlatformRoot(OId)) And EntityY(PlatformRoot(Id)) <= EntityY(PlatformRoot(OId))+0.1 And Distance2D(EntityX(PlatformRoot(Id),True),EntityZ(PlatformRoot(Id),True),EntityX(PlatformRoot(OId),True),EntityZ(PlatformRoot(OId),True)) <= PlatformXZRadius(Id)+PlatformXZRadius(OId)+1 )
    Goto LineChoosePlatformPosition
   EndIf
   EndIf
  Next
  PositionRotateEntityLikeOtherEntity(PlatformRenderer(Id),PlatformRoot(Id))
  PositionRotateEntityLikeOtherEntity(PlatformPickable(Id),PlatformRoot(Id))
 
  NameEntity(PlatformPickable(Id),"PLA"+Str(Id))

 Next

End Function

Function BuildHumanoids()

 For i% = 1 To 10 Step 1

  HumanoidsCount = HumanoidsCount + 1
  Id% = HumanoidsCount

  HumanoidRoot(Id) = CreatePivot()

  HumanoidMiddle(Id) = CreatePivot()
  PositionRotateEntityLikeOtherEntity(HumanoidMiddle(Id),HumanoidRoot(Id))
  MoveEntity(HumanoidMiddle(Id),0,0.875,0)
  SetEntityAsChildOfOtherEntity(HumanoidMiddle(Id),HumanoidRoot(Id))
 
  HumanoidEyes(Id) = CreatePivot()

  HumanoidRenderer(Id) = CreateCube()
  ScaleMesh(HumanoidRenderer(Id),0.5/2,1.75/2,0.25/2)
  PositionMesh(HumanoidRenderer(Id),0,1.75/2,0)
  ColorSurfaceWithBrush(GetSurface(HumanoidRenderer(Id),1),Rand(025,255),Rand(025,255),Rand(025,255))
  HideEntity(HumanoidRenderer(Id))

  HumanoidXZRadius(Id) = 0.25

  HumanoidPickable(Id) = CreateCylinder(16)
  ScaleMesh(HumanoidPickable(Id),0.5/2,1.0/2,0.5/2)
  PositionMesh(HumanoidPickable(Id),0,1.0/2,0)
  EntityColor(HumanoidPickable(Id),255,255,255)
  EntityAlpha(HumanoidPickable(Id),0.5)

  .LineChooseHumanoidPosition
  PositionEntity(HumanoidRoot(Id),Rnd(0+0.25,128-0.25),3.2+0.1,Rnd(0+0.25,128-10-3-0.25),True)
  ;is far enough from another building ?
  For OId% = 1 To BuildingsCount Step 1
   If( Distance2D(EntityX(HumanoidRoot(Id),True),EntityZ(HumanoidRoot(Id),True),EntityX(BuildingRoot(OId),True),EntityZ(BuildingRoot(OId),True)) <= HumanoidXZRadius(Id)+BuildingXZRadius(OId)+1 )
    Goto LineChooseHumanoidPosition
   EndIf
  Next
  ;is far enough from another Stair ?
  For OId% = 1 To StairsCount Step 1
   If( Distance2D(EntityX(HumanoidRoot(Id),True),EntityZ(HumanoidRoot(Id),True),EntityX(StairRoot(OId),True),EntityZ(StairRoot(OId),True)) <= HumanoidXZRadius(Id)+StairXZRadius(OId)+1 )
    Goto LineChooseHumanoidPosition
   EndIf
  Next
  ;is far enough from another rock ?
  For OId% = 1 To RocksCount Step 1
   If( Distance2D(EntityX(HumanoidRoot(Id),True),EntityZ(HumanoidRoot(Id),True),EntityX(RockRoot(OId),True),EntityZ(RockRoot(OId),True)) <= HumanoidXZRadius(Id)+RockXZRadius(OId)+1 )
    Goto LineChooseHumanoidPosition
   EndIf
  Next
  ;is far enough from another tree ?
  For OId% = 1 To TreesCount Step 1
   If( Distance2D(EntityX(HumanoidRoot(Id),True),EntityZ(HumanoidRoot(Id),True),EntityX(TreeRoot(OId),True),EntityZ(TreeRoot(OId),True)) <= HumanoidXZRadius(Id)+TreeXZRadius(OId)+1 )
    Goto LineChooseHumanoidPosition
   EndIf
  Next
  ;is far enough from another crate ?
  For OId% = 1 To CratesCount Step 1
   If( Distance2D(EntityX(HumanoidRoot(Id),True),EntityZ(HumanoidRoot(Id),True),EntityX(CrateRoot(OId),True),EntityZ(CrateRoot(OId),True)) <= HumanoidXZRadius(Id)+CrateXZRadius(OId)+1 )
    Goto LineChooseHumanoidPosition
   EndIf
  Next
  ;is far enough from another barrel ?
  For OId% = 1 To BarrelsCount Step 1
   If( Distance2D(EntityX(HumanoidRoot(Id),True),EntityZ(HumanoidRoot(Id),True),EntityX(BarrelRoot(OId),True),EntityZ(BarrelRoot(OId),True)) <= HumanoidXZRadius(Id)+BarrelXZRadius(OId)+1 )
    Goto LineChooseHumanoidPosition
   EndIf
  Next
  ;is far enough from another platform ?
  For OId% = 1 To PlatformsCount Step 1
   If( Distance2D(EntityX(HumanoidRoot(Id),True),EntityZ(HumanoidRoot(Id),True),EntityX(PlatformRoot(OId),True),EntityZ(PlatformRoot(OId),True)) <= HumanoidXZRadius(Id)+PlatformXZRadius(OId)+1 )
    If( EntityY(PlatformRoot(OId),True) < 3.2+1.75+1 )
     Goto LineChooseHumanoidPosition
    EndIf
   EndIf
  Next
  ;is far enough from another humanoid ?
  For OId% = 1 To HumanoidsCount Step 1
   If( OId <> Id )
    If( Distance2D(EntityX(HumanoidRoot(Id),True),EntityZ(HumanoidRoot(Id),True),EntityX(HumanoidRoot(OId),True),EntityZ(HumanoidRoot(OId),True)) <= HumanoidXZRadius(Id)+HumanoidXZRadius(OId)+1 )
     Goto LineChooseHumanoidPosition
    EndIf
   EndIf
  Next
  PositionRotateEntityLikeOtherEntity(HumanoidRenderer(Id),HumanoidRoot(Id))
  SetEntityAsChildOfOtherEntity(HumanoidRenderer(Id),HumanoidRoot(Id))
  PositionRotateEntityLikeOtherEntity(HumanoidPickable(Id),HumanoidRoot(Id))
  SetEntityAsChildOfOtherEntity(HumanoidPickable(Id),HumanoidRoot(Id))

  HumanoidTarget(Id) = CreatePivot()
  PositionEntity(HumanoidTarget(Id),Rnd(0+0.25,128.0-0.25),3.2,Rnd(0+0.25,128.0-0.25),True)

  ;HumanoidPostureMode(Id) = Rand(1,2)
  HumanoidPostureMode(Id) = CStanding
  ScaleEntity(HumanoidPickable(Id),1,1.75,1)
  PositionRotateEntityLikeOtherEntity(HumanoidEyes(Id),HumanoidRoot(Id))
  MoveEntity(HumanoidEyes(Id),0,1.75-0.1,0)
  HumanoidMoveForce(Id) = Rnd(0.05,0.5)
  HumanoidJumpForce(Id) = 0
  HumanoidPositionState(Id) = COnAir
  HumanoidActionState(Id) = CIsFalling
  HumanoidGVX(Id) = 0
  HumanoidGVY(Id) = 0
  HumanoidGVZ(Id) = 0

  NameEntity(HumanoidPickable(Id),"HUM"+Str(Id))

 Next

End Function



RemiD(Posted 11 months ago)

 Part3 :[code]
Function GetMouseInput()

 MPX = MouseX()
 MPY = MouseY()

 MXDiff = MouseXSpeed()
 MYDiff = MouseYSpeed()

 MWheel = 0
 MZCur = MouseZ()
 If(MZCur > MZOld)
  MWheel = + 1
  MZOld = MZCur
 ElseIf(MZCur < MZOld)
  MWheel = - 1
  MZOld = MZCur
 EndIf

End Function

Function GetKeyboardInput()

 KeySpaceState = CIdle
 If( KeyDown(57) = 1 )
  KeySpaceDownCount = KeySpaceDownCount + 1
  If( KeySpaceDownCount = 1 )
   KeySpaceState = CPressed
   KeySpacePrevState = CPressed
  Else If( KeySpaceDownCount > 1 )
   KeySpaceState = CHeld
   KeySpacePrevState = CHeld
  EndIf
 Else If( KeyDown(57) = 0 )
  KeySpaceDownCount = 0
  If( KeySpacePrevState = CPressed Or KeySpacePrevState = CHeld )
   KeySpaceState = CReleased
   KeySpacePrevState = CReleased
  EndIf
 EndIf

End Function

Function UpdatePlayer()

;----------------------------------------------------------------------------------------------------

;each static entity which needs to be considered as an obstacle has a pickable (low tris mesh)
;each turningmoving entity which needs to be considered as an obstacle has a pickable (low tris mesh)
;each pickable has a XZRadius (so that it can sometimes be considered and sometimes not considered depending if it is near enough or too far)
;only one turningmoving entity is turnedmoved at a time so that all others entities which must be considered as obstacles are static

;for each obstacle
 ;set this obstacle as notpickable
 ;calculate the xzdistance between this humanoid and this obstacle
 ;if near enough (less than humanoidxzradius+obstaclexzradius+maxxztranslationlength)
  ;set this obstacle as pickable

;calculate the initialtranslationxyzvector
;calculate the initialtranslationxyzvectorlength
;position rotate the capsule at the humanoid position orientation
;with linepicks and pickables, detect collisions between the capsule and pickables (several linepicks : if crouched : from 0+0.25 to 0.875-0.25 radius 0.25 | if standup : from 0+0.25 to 1.75-0.25 radius 0.25 )
;for each linepick
 ;calculate and store the start point xyz of the linepick
 ;throw the linepick
 ;check if a pick happened between the linepick and a pickable
 ;if yes
  ;store the pick pickable ref
  ;store the pick point xyz
  ;store the pick normal nxnynz
;for each pick
 ;calculate the xyzdistance between the start point of the linepick and the pick point
;determine which xyzdistance is the smallest distance
;use the start point, the pick pickable ref, the pick point xyz, the pick normal nxnynz, having the smallest xyzdistance
;calculate the vectorfactor (smallestxyzdistance/initialtranslationxyzvectorlength)
;calculate the finaltranslationxyzvector (initialtranslationxyzvector*vectorfactor)
;translate the capsule
;if needed, get the pick pickable ref, the pick pickable name, the pick point xyz, the pick normal nxnynz
;position rotate the humanoid at the capsule position orientation

;for each obstacle
 ;set this obstacle as notpickable

;----------------------------------------------------------------------------------------------------


 Id% = PlayerId

 ;for each obstacle
  ;set this obstacle as notpickable
  ;calculate the xzdistance between this humanoid and this obstacle
  ;if near enough (less than humanoidxzradius+obstaclexzradius+maxxztranslationlength)
   ;set this obstacle as pickable

 SetSomeObstaclesAsPickableMsTime = 0

 LinepicksMsTime = 0

 MsStart% = MilliSecs()
 EntityPickMode(TerrainROAM,2)
 EntityColor(TerrainROAM,255,255,255)
 For OId% = 1 To BuildingsCount Step 1
  EntityColor(BuildingPickable(OId),255,255,255)
  D# = Distance2D(EntityX(HumanoidRoot(Id),True),EntityZ(HumanoidRoot(Id),True),EntityX(BuildingRoot(OId),True),EntityZ(BuildingRoot(OId),True))
  If( D <= HumanoidXZRadius(Id)+BuildingXZRadius(OId)+1.0 )
   EntityPickMode(BuildingPickable(OId),2)
   EntityColor(BuildingPickable(OId),000,000,255)
  EndIf
 Next
 For OId% = 1 To StairsCount Step 1
  EntityColor(StairPickable(OId),255,255,255)
  D# = Distance2D(EntityX(HumanoidRoot(Id),True),EntityZ(HumanoidRoot(Id),True),EntityX(StairRoot(OId),True),EntityZ(StairRoot(OId),True))
  If( D <= HumanoidXZRadius(Id)+StairXZRadius(OId)+1.0 )
   EntityPickMode(StairPickable(OId),2)
   EntityColor(StairPickable(OId),000,000,255)
  EndIf
 Next
 For OId% = 1 To SlopesCount Step 1
  EntityColor(SlopePickable(OId),255,255,255)
  D# = Distance2D(EntityX(HumanoidRoot(Id),True),EntityZ(HumanoidRoot(Id),True),EntityX(SlopeRoot(OId),True),EntityZ(SlopeRoot(OId),True))
  If( D <= HumanoidXZRadius(Id)+SlopeXZRadius(OId)+1.0 )
   EntityPickMode(SlopePickable(OId),2)
   EntityColor(SlopePickable(OId),000,000,255)
  EndIf
 Next
 For OId% = 1 To RocksCount Step 1
  EntityColor(RockPickable(OId),255,255,255)
  D# = Distance2D(EntityX(HumanoidRoot(Id),True),EntityZ(HumanoidRoot(Id),True),EntityX(RockRoot(OId),True),EntityZ(RockRoot(OId),True))
  If( D <= HumanoidXZRadius(Id)+RockXZRadius(OId)+1.0 )
   EntityPickMode(RockPickable(OId),2)
   EntityColor(RockPickable(OId),000,000,255)
  EndIf
 Next
 For OId% = 1 To TreesCount Step 1
  EntityColor(TreePickable(OId),255,255,255)
  D# = Distance2D(EntityX(HumanoidRoot(Id),True),EntityZ(HumanoidRoot(Id),True),EntityX(TreeRoot(OId),True),EntityZ(TreeRoot(OId),True))
  If( D <= HumanoidXZRadius(Id)+TreeXZRadius(OId)+1.0 )
   EntityPickMode(TreePickable(OId),2)
   EntityColor(TreePickable(OId),000,000,255)
  EndIf
 Next
 For OId% = 1 To CratesCount Step 1
  EntityColor(CratePickable(OId),255,255,255)
  D# = Distance2D(EntityX(HumanoidRoot(Id),True),EntityZ(HumanoidRoot(Id),True),EntityX(CrateRoot(OId),True),EntityZ(CrateRoot(OId),True))
  If( D <= HumanoidXZRadius(Id)+CrateXZRadius(OId)+1.0 )
   EntityPickMode(CratePickable(OId),2)
   EntityColor(CratePickable(OId),000,000,255)
  EndIf
 Next
 For OId% = 1 To BarrelsCount Step 1
  EntityColor(BarrelPickable(OId),255,255,255)
  D# = Distance2D(EntityX(HumanoidRoot(Id),True),EntityZ(HumanoidRoot(Id),True),EntityX(BarrelRoot(OId),True),EntityZ(BarrelRoot(OId),True))
  If( D <= HumanoidXZRadius(Id)+BarrelXZRadius(OId)+1.0 )
   EntityPickMode(BarrelPickable(OId),2)
   EntityColor(BarrelPickable(OId),000,000,255)
  EndIf
 Next
 For OId% = 1 To PlatformsCount Step 1
  EntityColor(PlatformPickable(OId),255,255,255)
  D# = Distance2D(EntityX(HumanoidRoot(Id),True),EntityZ(HumanoidRoot(Id),True),EntityX(PlatformRoot(OId),True),EntityZ(PlatformRoot(OId),True))
  If( D <= HumanoidXZRadius(Id)+PlatformXZRadius(OId)+1.0 )
   EntityPickMode(PlatformPickable(OId),2)
   EntityColor(PlatformPickable(OId),000,000,255)
  EndIf
 Next
 For OId% = 1 To HumanoidsCount Step 1
  If( OId <> Id )
   EntityColor(HumanoidPickable(OId),255,255,255)
   D# = Distance2D(EntityX(HumanoidRoot(Id),True),EntityZ(HumanoidRoot(Id),True),EntityX(HumanoidRoot(OId),True),EntityZ(HumanoidRoot(OId),True))
   If( D <= HumanoidXZRadius(Id)+HumanoidXZRadius(OId)+1.0 )
    EntityPickMode(HumanoidPickable(OId),2)
    EntityColor(HumanoidPickable(OId),000,000,255)
   EndIf
  EndIf
 Next
 MsTime% = MilliSecs() - MsStart
 SetSomeObstaclesAsPickableMsTime = SetSomeObstaclesAsPickableMsTime + MsTime

 ;if entity is not OnLedge is not OnLadder
 If( HumanoidPositionState(Id) <> COnSlope And HumanoidPositionState(Id) <> COnLedge And HumanoidPositionState(Id) <> COnLadder )

  ;with linepick and pickable, check if entity is near enough from a ground (< 0.25) or too far from a ground (=> 0.25)
  ;if near enough from a ground
   ;entity is OnGround
   ;entity IsIdle
  ;else if too far from a ground
   ;entity is OnAir
   ;entity IsFalling
  MsStart% = MilliSecs()
  PickY# = 0
  PickNY# = 0
  TFormVector(0,-100,0,HumanoidMiddle(Id),0)
  LinePick(EntityX(HumanoidMiddle(Id),True),EntityY(HumanoidMiddle(Id),True),EntityZ(HumanoidMiddle(Id),True),TFormedX(),TFormedY(),TFormedZ(),0.24) ;0.24 works well...
  MsTime% = MilliSecs() - MsStart
  LinepicksMsTime = LinepicksMsTime + MsTime
  PickableRef = PickedEntity()
  If( PickableRef <> 0 )
   PickableName$ = EntityName(PickableRef)
   PickableKind$ = Left(PickableName,3)
   PickableId% = Right(PickableName,Len(PickableName)-3)
   PickY# = PickedY()
   PickNY# = PickedNY()
  Else If( PickableRef = 0 )
   PickableName$ = EntityName(TerrainROAM)
   PickableKind$ = Left(PickableName,3)
   PickableId% = Right(PickableName,Len(PickableName)-3)
   PickY# = TerrainY(TerrainROAM,EntityX(HumanoidMiddle(Id),True),0,EntityZ(HumanoidMiddle(Id),True))
   PickNY# = 0
  EndIf
  If( EntityY(HumanoidRoot(Id),True) => PickY+0.4375 )
   HumanoidPositionState(Id) = COnAir
   HumanoidActionState(Id) = CIsFalling
   HumanoidJumpForce(Id) = 0
  Else If( EntityY(HumanoidRoot(Id),True) < PickY+0.4375 )

   If( PickableKind <> "SLO" )
    If( HumanoidPositionState(Id) = COnAir )  
     HumanoidPositionState(Id) = COnGround
     HumanoidActionState(Id) = CIsLanding
     PositionEntity(HumanoidRoot(Id),EntityX(HumanoidRoot(Id),True),PickY,EntityZ(HumanoidRoot(Id),True),True)
    Else If( HumanoidPositionState(Id) = COnGround )
     HumanoidPositionState(Id) = COnGround
     HumanoidActionState(Id) = 0
     PositionEntity(HumanoidRoot(Id),EntityX(HumanoidRoot(Id),True),PickY,EntityZ(HumanoidRoot(Id),True),True)
    EndIf
   Else If( PickableKind = "SLO" )
    If( PickNY > 0.75 And PickNY <= 1.0 )
     If( HumanoidPositionState(Id) = COnAir )  
      HumanoidPositionState(Id) = COnGround
      HumanoidActionState(Id) = CIsLanding
      PositionEntity(HumanoidRoot(Id),EntityX(HumanoidRoot(Id),True),PickY,EntityZ(HumanoidRoot(Id),True),True)
     Else If( HumanoidPositionState(Id) = COnGround )
      HumanoidPositionState(Id) = COnGround
      HumanoidActionState(Id) = 0
      PositionEntity(HumanoidRoot(Id),EntityX(HumanoidRoot(Id),True),PickY,EntityZ(HumanoidRoot(Id),True),True)
     EndIf
    Else If( PickNY < 0.5 )
     HumanoidPositionState(Id) = COnSlope
     HumanoidActionState(Id) = CIsSliding
     PositionEntity(HumanoidRoot(Id),EntityX(HumanoidRoot(Id),True),PickY,EntityZ(HumanoidRoot(Id),True),True)
    EndIf
   EndIf
 
  EndIf  
 EndIf

 ;if entity is OnAir
 If( HumanoidPositionState(Id) = COnAir )

  ;if entity IsFalling
  If( HumanoidActionState(Id) = CIsFalling )
   ;can fall
   ;can grab a ledge
   ;can grab a ladder
   ;can land on a ground

   ;calculate the initialxztranslationvector
   ;with linepicks and pickables, detect collisions with obstacles
   ;calculate the finalxztranslation
   ;xztranslate

   If( KeyHit(42)=1 )
    If( HumanoidPostureMode(Id) = CCrouching )
     TFormVector(0,1.75-0.25,0,HumanoidRoot(Id),0)
     LinePick(EntityX(HumanoidRoot(Id),True),EntityY(HumanoidRoot(Id),True),EntityZ(HumanoidRoot(Id),True),0,TFormedY(),0,0.24)
     PickableRef = PickedEntity()
     If( PickableRef = 0 )
      HumanoidPostureMode(Id) = CStanding
     EndIf
    Else If( HumanoidPostureMode(Id) = CStanding )
     ;
    EndIf
   Else If( KeyHit(29)=1)
    If( HumanoidPostureMode(Id) = CCrouching )
     ;
    Else If( HumanoidPostureMode(Id) = CStanding )
     HumanoidPostureMode(Id) = CCrouching
    EndIf
   EndIf

   ;calculate the initialtranslationxzvector
   If( KeyDown(17) = 1 )
    TFormVector(0,0,0.005,HumanoidRoot(Id),0)
   Else If( KeyDown(31) = 1 )
    TFormVector(0,0,-0.005,HumanoidRoot(Id),0)
   Else If(KeyDown(30) = 1 )
    TFormVector(-0.005,0,0,HumanoidRoot(Id),0)
   Else If( KeyDown(32) = 1 )
    TFormVector(0.005,0,0,HumanoidRoot(Id),0)
   EndIf
   HumanoidGVX(Id) = HumanoidGVX(Id) + TFormedX()
   HumanoidGVZ(Id) = HumanoidGVZ(Id) + TFormedZ()

   HumanoidGVX(Id) = HumanoidGVX(Id)
   HumanoidGVZ(Id) = HumanoidGVZ(Id)
   ;calculate the initialtranslationxzvectorlength (without the 0.25radius)
   GVLength# = Sqr( ( HumanoidGVX(Id) * HumanoidGVX(Id) ) + ( HumanoidGVZ(Id) * HumanoidGVZ(Id) ) )
   
   Scale# = (GVLength+0.25+1.0)/GVLength
   LPVX# = HumanoidGVX(Id)*Scale
   LPVZ# = HumanoidGVZ(Id)*Scale

   ;position rotate the capsule at the humanoid position orientation
   PositionRotateEntityLikeOtherEntity(CapsuleRoot,HumanoidRoot(Id))

   ;if crouched
   If( HumanoidPostureMode(Id) = CCrouching )
    LPsCount% = 3
    LPY(1) = 0.25
    LPY(2) = 0.875/2
    LPY(3) = 0.875-0.25
   ;if standup
   Else If( HumanoidPostureMode(Id) = CStanding )
    LPsCount% = 6
    LPY(1) = 0.25
    LPY(2) = 0.5
    LPY(3) = 0.75
    LPY(4) = 1.0
    LPY(5) = 1.25
    LPY(6) = 1.5
   EndIf

   MsStart% = MilliSecs()
   PsCount = 0
   For i% = 1 To LPsCount Step 1
    Y# = LPY(i)
    LinePick(EntityX(HumanoidRoot(Id),True),EntityY(HumanoidRoot(Id),True)+Y,EntityZ(HumanoidRoot(Id),True),LPVX,0,LPVZ,0.25)
    PickableRef = PickedEntity()
    If( PickableRef <> 0 )
     If( PickedY() > EntityY(HumanoidRoot(Id),True)+0.4375 )
      PsCount = PsCount + 1
      PId% = PsCount
      PStartX(PId) = EntityX(HumanoidRoot(Id),True)
      PStartY(PId) = EntityY(HumanoidRoot(Id),True)+Y
      PStartZ(PId) = EntityZ(HumanoidRoot(Id),True)
      PPickable(PId) = PickableRef
      PPointX(PId) = PickedX()
      PPointY(PId) = PickedY()
      PPointZ(PId) = PickedZ()
      PNormalX(PId) = PickedNX()
      PNormalY(PId) = PickedNY()
      PNormalZ(PId) = PickedNZ()
     EndIf
    EndIf
   Next
   MsTime% = MilliSecs() - MsStart
   LinepicksMsTime = LinepicksMsTime + MsTime

   If( PsCount > 0 )
    SmallestD# = 1000000
    SId% = 0
    For PId% = 1 To PsCount Step 1
     D# = Distance3D(PStartX(PId),PStartY(PId),PStartZ(PId),PPointX(PId),PPointY(PId),PPointZ(PId))
     If( D < 0.25+GVLength )
      If( D < SmallestD )
       SmallestD = D
       SId = PId
      EndIf
     EndIf
    Next
    If( SmallestD < 0.25+GVLength And SId > 0 )
     EntityColor(PPickable(SId),255,000,255)
     VFactor# = (SmallestD-0.25)/GVLength
     If( VFactor < 0.01 )
      VFactor = 0
     EndIf
     TranslateEntity(HumanoidRoot(Id),HumanoidGVX(Id)*VFactor,0,HumanoidGVZ(Id)*VFactor,True)
     HumanoidGVX(Id) = -HumanoidGVX(Id)/10
     HumanoidGVZ(Id) = -HumanoidGVZ(Id)/10
     ;HumanoidGVX(Id) = 0
     ;HumanoidGVZ(Id) = 0
     ;here i can retrieve the pickable ref, the pickable name, the pickable point xyz, the pickable nxnynz
     ;DebugLog("PPickableRef = "+PPickable(SId))
     ;DebugLog("PPickableName = "+EntityName(PPickable(SId)))
     ;DebugLog("PPoint X,Y,Z = "+PPointX(SId)+","+PPointY(SId)+","+PPointZ(SId))
     ;DebugLog("PNormal NX,NY,NZ = "+PNormalX(SId)+","+PNormalY(SId)+","+PNormalZ(SId))
     PName$ = EntityName(PPickable(SId))
     PKind$ = Left(PName,3)
     PId% = Int(Right(PName,Len(PName)-3))
     ;depending on the kind of pickable and depending on the picked normal decide if humanoid is OnAir or OnLedge or OnLadder
     If( PKind = "BUI" Or PKind = "CRA" Or PKind = "BAR" Or PKind = "PLA" )
      ;does the picked normal corresponds to a wall ?
      ;if yes
       ;is the humanoid oriented towards enough the wall ?
       ;if yes
        ;is there a grabbable ledge near enough (between humanoidrootY+0.4375 to humanoidrootY+2.05 ?)
        ;if yes
         ;humanoid is OnLedge
         ;humanoid IsGrabbing
        ;else if no
         ;humanoid is OnAir
         ;humanoid IsFalling
       ;else if no
        ;humanoid is OnAir
        ;humanoid IsFalling
      ;else if no
       ;humanoid is OnAir
       ;humanoid IsFalling
     Else If( PKind = "LAD" )
      ;is the humanoid oriented towards enough the ladder ?
      ;if yes
       ;humanoid is OnLadder
       ;humanoid IsGrabbing
      ;else if no
       ;humanoid is OnAir
       ;humanoid IsFalling
     Else
      ;humanoid is OnAir
      ;humanoid IsFalling
     EndIf
    Else
     TranslateEntity(HumanoidRoot(Id),HumanoidGVX(Id),0,HumanoidGVZ(Id),True)
    EndIf
   Else If( PsCount = 0 )
    TranslateEntity(HumanoidRoot(Id),HumanoidGVX(Id),0,HumanoidGVZ(Id),True)
   EndIf

   ;calculate the initialytranslationvector
   ;with linepicks and pickables, detect collisions with ceilings or grounds
   ;calculate the finalytranslation
   ;ytranslate

   ;calculate the initialtranslationyvector
   HumanoidGVY(Id) = HumanoidGVY(Id) - 0.4905/10 ;(9.81/1000*MainLoopMsTime) ;gravityattraction

   ;calculate the initialtranslationyvectorlength
   GVLength# = Abs(HumanoidGVY(Id))
   
   If( HumanoidGVY(Id) => 0 )
    ;detect collisions with ceilings
 
    MsStart% = MilliSecs()
    TFormVector(0,100,0,HumanoidMiddle(Id),0)
    LinePick(EntityX(HumanoidMiddle(Id),True),EntityY(HumanoidMiddle(Id),True),EntityZ(HumanoidMiddle(Id),True),0,TFormedY(),0,0.24) ;0.25
    MsTime% = MilliSecs() - MsStart
    LinepicksMsTime = LinepicksMsTime + MsTime
    PickableRef = PickedEntity()
    If( PickableRef <> 0 )
     PStartX(1) = EntityX(HumanoidMiddle(Id),True)
     PStartY(1) = EntityY(HumanoidMiddle(Id),True)
     PStartZ(1) = EntityZ(HumanoidMiddle(Id),True)
     PPickable(1) = PickableRef
     PPointX(1) = PickedX()
     PPointY(1) = PickedY()
     PPointZ(1) = PickedZ()
     ;PNormalX(1) = PickedNX()
     ;PNormalY(1) = PickedNY()
     ;PNormalZ(1) = PickedNZ()

     D# = Distance3D(PStartX(1),PStartY(1),PStartZ(1),PPointX(1),PPointY(1),PPointZ(1))
     If( D < 0.875+GVLength )
      ;EntityColor(PPickable(1),255,000,255)
      VFactor# = (D-0.875)/GVLength
      If( VFactor < 0.01 )
       VFactor = 0
      EndIf
      TranslateEntity(HumanoidRoot(Id),0,HumanoidGVY(Id)*VFactor,0,True)  
      HumanoidGVY(Id) = 0
     Else
      TranslateEntity(HumanoidRoot(Id),0,HumanoidGVY(Id),0,True)
     EndIf
    Else If( PickableRef = 0 )
     TranslateEntity(HumanoidRoot(Id),0,HumanoidGVY(Id),0,True)
    EndIf

   Else If( HumanoidGVY(Id) < 0 )
    ;detect collisions with grounds

    MsStart% = MilliSecs()
    TFormVector(0,-100,0,HumanoidMiddle(Id),0)
    LinePick(EntityX(HumanoidMiddle(Id),True),EntityY(HumanoidMiddle(Id),True),EntityZ(HumanoidMiddle(Id),True),0,TFormedY(),0,0.24) ;0.25
    MsTime% = MilliSecs() - MsStart
    LinepicksMsTime = LinepicksMsTime + MsTime
    PickableRef = PickedEntity()
    If( PickableRef <> 0 )
     PStartX(1) = EntityX(HumanoidMiddle(Id),True)
     PStartY(1) = EntityY(HumanoidMiddle(Id),True)
     PStartZ(1) = EntityZ(HumanoidMiddle(Id),True)
     PPickable(1) = PickableRef
     PPointX(1) = PickedX()
     PPointY(1) = PickedY()
     PPointZ(1) = PickedZ()
     ;PNormalX(1) = PickedNX()
     ;PNormalY(1) = PickedNY()
     ;PNormalZ(1) = PickedNZ()

     D# = Distance3D(PStartX(1),PStartY(1),PStartZ(1),PPointX(1),PPointY(1),PPointZ(1))
     If( D < 0.875+GVLength )
      ;EntityColor(PPickable(1),255,000,255)
      VFactor# = (D-0.875)/GVLength
      If( VFactor < 0.01 )
       VFactor = 0
      EndIf
      TranslateEntity(HumanoidRoot(Id),0,HumanoidGVY(Id)*VFactor,0,True)  
     Else
      TranslateEntity(HumanoidRoot(Id),0,HumanoidGVY(Id),0,True)
     EndIf
    Else If( PickableRef = 0 )
     PStartX(1) = EntityX(HumanoidMiddle(Id),True)
     PStartY(1) = EntityY(HumanoidMiddle(Id),True)
     PStartZ(1) = EntityZ(HumanoidMiddle(Id),True)
     PPickable(1) = TerrainROAM
     PPointX(1) = EntityX(HumanoidMiddle(Id),True)
     PPointY(1) = TerrainY(TerrainROAM,EntityX(HumanoidMiddle(Id),True),0,EntityZ(HumanoidMiddle(Id),True))
     PPointZ(1) = EntityY(HumanoidMiddle(Id),True)
     ;PNormalX(1) = PickedNX()
     ;PNormalY(1) = PickedNY()
     ;PNormalZ(1) = PickedNZ()
     D# = Distance3D(PStartX(1),PStartY(1),PStartZ(1),PPointX(1),PPointY(1),PPointZ(1))
     If( D < 0.875+GVLength+0.01 )
      ;EntityColor(PPickable(1),255,000,255)
      VFactor# = (D-0.875)/GVLength
      If( VFactor < 0.01 )
       VFactor = 0
      EndIf
      TranslateEntity(HumanoidRoot(Id),0,HumanoidGVY(Id)*VFactor,0,True)  
      HumanoidGVY(Id) = 0
     Else
      TranslateEntity(HumanoidRoot(Id),0,HumanoidGVY(Id),0,True)
     EndIf
    EndIf

   EndIf

  EndIf

 ;else if entity is OnSlope
 Else If( HumanoidPositionState(Id) = COnSlope )
 
  If( HumanoidActionState(Id) = CIsSliding )
   
   ;calculate the initialxztranslationvector (depending on the slope normal and the slope steep)
   ;with linepicks and pickables, detect collisions with obstacles
   ;calculate the finalxztranslation
   ;xztranslate

   DebugLog("PickY = "+PickY)
   DebugLog("PickNY = "+PickNY)
   SlopeSteep# = (0.75-PickNY)/0.75
   DebugLog("SlopeSteep = "+SlopeSteep)

   ;with linepicks and pickables, detect what is below the feet of humanoid
   ;if it is the same slope
    ;position the feet of humanoid at this position
   ;if it is another ground
    ;position the feet of humanoid at this position ?

  EndIf  

 ;else if entity is OnLedge
 Else If( HumanoidPositionState(Id) = COnLedge )

  ;if entity IsGrabbing
  If( HumanoidActionState(Id) = CIsGrabbing )
   ;can moveleft
   ;can moveright
   ;can climb
   ;can letgo

  ;else if entity IsClimbing
  Else If( HumanoidActionState(Id) = CIsClimbing )

  ;else if entity IsLettingGo
  Else If( HumanoidActionState(Id) = CIsLettingGo )

  EndIf

 ;else if entity is OnLadder
 Else If( HumanoidPositionState(Id) = COnLadder )

  ;if entity IsGrabbing
  If( HumanoidActionState(Id) = CIsGrabbing )
   ;can moveup
   ;can movedown
   ;can climb
   ;can letgo

  ;else if entity IsClimbing
  Else If( HumanoidActionState(Id) = CIsClimbing )

  ;else if entity IsLettingGo
  Else If( HumanoidActionState(Id) = CIsLettingGo )
 
  EndIf

 ;else if entity is OnGround
 Else If( HumanoidPositionState(Id) = COnGround )

  ;if entity IsLanding
  If( HumanoidActionState(Id) = CIsLanding )
   HumanoidActionState(Id) = 0
  EndIf
  If( HumanoidActionState(Id) = 0 )
   ;can crouchidle
   ;can standupidle
   ;can turnleft
   ;can turnright
   ;can crouchforward
   ;can crouchbackward
   ;can crouchleft
   ;can crouchright
   ;can standforward
   ;can standbackward
   ;can standleft
   ;can standright
   ;can jump
   ;can attackwithprojectile
   ;can attackwithblade
   ;can dodgetofront
   ;can dodgetoback
   ;can dodgetoleft
   ;can dodgetoright
   ;can protect
   ;can behit
   ;can beconfused
   ;can becomeunconsciouscollapse
   ;can becomeconsciousstandup
   ;can takeitem
   ;can putitem
   ;can useitem

   ;turn left or right
   If( KeyDown(16) = 1 )
    TurnEntity(HumanoidRoot(Id),0,2,0)
   Else If( KeyDown(18) = 1 )
    TurnEntity(HumanoidRoot(Id),0,-2,0)
   EndIf
 
   RootYawVar# = -Float(MXDiff)/10
   If( RootYawVar > 10 )
    RootYawVar = 10
   Else If( RootYawVar < - 10 )
    RootYawVar = -10
   EndIf
   TurnEntity(HumanoidRoot(Id),0,RootYawVar,0)

   If( KeyHit(42)=1 )
    If( HumanoidPostureMode(Id) = CCrouching )
     TFormVector(0,1.75-0.25,0,HumanoidRoot(Id),0)
     LinePick(EntityX(HumanoidRoot(Id),True),EntityY(HumanoidRoot(Id),True),EntityZ(HumanoidRoot(Id),True),0,TFormedY(),0,0.24)
     PickableRef = PickedEntity()
     If( PickableRef = 0 )
      HumanoidPostureMode(Id) = CStanding
     Else If( PickableRef <> 0 )
      PositionEntity(Point,PickedX(),PickedY(),PickedZ(),True)
     EndIf
    Else If( HumanoidPostureMode(Id) = CStanding )
     ;
    EndIf
   Else If( KeyHit(29)=1)
    If( HumanoidPostureMode(Id) = CCrouching )
     ;
    Else If( HumanoidPostureMode(Id) = CStanding )
     HumanoidPostureMode(Id) = CCrouching
    EndIf
   EndIf

   If( MWheel=1 Or KeyHit(201)=1 )
    HumanoidMoveForce(Id) = HumanoidMoveForce(Id) + 0.05
    If( HumanoidMoveForce(Id) > 0.5 )
     HumanoidMoveForce(Id) = 0.5
    EndIf
   Else If( MWheel=-1 Or KeyHit(209)=1 )
    HumanoidMoveForce(Id) = HumanoidMoveForce(Id) - 0.05
    If( HumanoidMoveForce(Id) < 0.05 )
     HumanoidMoveForce(Id) = 0.05
    EndIf
   EndIf

   HumanoidActionState(Id) = 0
   If( HumanoidPostureMode(Id) = CCrouching )
    HumanoidActionState(Id) = CIsCrouchingIdle
   Else If( HumanoidPostureMode(Id) = CStanding )
    HumanoidActionState(Id) = CIsStandingIdle
   EndIf
   TFormVector(0,0,0,HumanoidRoot(Id),0)
   HumanoidGVX(Id) = 0
   HumanoidGVY(Id) = 0
   HumanoidGVZ(Id) = 0

   If( KeyDown(17) = 1 )
    If( HumanoidPostureMode(Id) = CCrouching )
     HumanoidActionState(Id) = CIsCrouchingForward
    Else If( HumanoidPostureMode(Id) = CStanding )
     HumanoidActionState(Id) = CIsStandingForward
    EndIf
    TFormVector(0,0,HumanoidMoveForce(Id),HumanoidRoot(Id),0)
   Else If( KeyDown(31) = 1 )
    If( HumanoidPostureMode(Id) = CCrouching )
     HumanoidActionState(Id) = CIsCrouchingBackward
    Else If( HumanoidPostureMode(Id) = CStanding )
     HumanoidActionState(Id) = CIsStandingBackward
    EndIf
    TFormVector(0,0,-HumanoidMoveForce(Id),HumanoidRoot(Id),0)
   Else If(KeyDown(30) = 1 )
    If( HumanoidPostureMode(Id) = CCrouching )
     HumanoidActionState(Id) = CIsCrouchingLeft
    Else If( HumanoidPostureMode(Id) = CStanding )
     HumanoidActionState(Id) = CIsStandingLeft
    EndIf
    TFormVector(-HumanoidMoveForce(Id),0,0,HumanoidRoot(Id),0)
   Else If( KeyDown(32) = 1 )
    If( HumanoidPostureMode(Id) = CCrouching )
     HumanoidActionState(Id) = CIsCrouchingRight
    Else If( HumanoidPostureMode(Id) = CStanding )
     HumanoidActionState(Id) = CIsStandingRight
    EndIf
    TFormVector(HumanoidMoveForce(Id),0,0,HumanoidRoot(Id),0)
   EndIf
   HumanoidGVX(Id) = TFormedX()
   HumanoidGVZ(Id) = TFormedZ()

   ;calculate the initialxztranslationvector (depending on if movingforward, movingbackward, movingleft, movingright)
   ;with linepicks and pickables, detect collisions with obstacles
   ;calculate the finalxztranslation
   ;xztranslate

   ;calculate the initialtranslationxzvector
   HumanoidGVX(Id) = HumanoidGVX(Id)
   HumanoidGVZ(Id) = HumanoidGVZ(Id)
   ;calculate the initialtranslationxzvectorlength (without the 0.25radius)
   GVLength# = Sqr( ( HumanoidGVX(Id) * HumanoidGVX(Id) ) + ( HumanoidGVZ(Id) * HumanoidGVZ(Id) ) )
   
   Scale# = (GVLength+0.25+1.0)/GVLength
   LPVX# = HumanoidGVX(Id)*Scale
   LPVZ# = HumanoidGVZ(Id)*Scale

   ;position rotate the capsule at the humanoid position orientation
   PositionRotateEntityLikeOtherEntity(CapsuleRoot,HumanoidRoot(Id))

   ;if crouched
   If( HumanoidPostureMode(Id) = CCrouching )
    LPsCount% = 3
    LPY(1) = 0.25
    LPY(2) = 0.875/2
    LPY(3) = 0.875-0.25
   ;if standup
   Else If( HumanoidPostureMode(Id) = CStanding )
    LPsCount% = 6
    LPY(1) = 0.25 ;=0+0.25
    LPY(2) = 0.5
    LPY(3) = 0.75
    LPY(4) = 1.0
    LPY(5) = 1.25
    LPY(6) = 1.5 ;=1.75-0.25
   EndIf

   MsStart% = MilliSecs()
   PsCount = 0
   For i% = 1 To LPsCount Step 1
    Y# = LPY(i)
    LinePick(EntityX(HumanoidRoot(Id),True),EntityY(HumanoidRoot(Id),True)+Y,EntityZ(HumanoidRoot(Id),True),LPVX,0,LPVZ,0.25)
    PickableRef = PickedEntity()
    If( PickableRef <> 0 )
     If( PickedY() > EntityY(HumanoidRoot(Id),True)+0.4375 )
      PsCount = PsCount + 1
      PId% = PsCount
      PStartX(PId) = EntityX(HumanoidRoot(Id),True)
      PStartY(PId) = EntityY(HumanoidRoot(Id),True)+Y
      PStartZ(PId) = EntityZ(HumanoidRoot(Id),True)
      PPickable(PId) = PickableRef
      PPointX(PId) = PickedX()
      PPointY(PId) = PickedY()
      PPointZ(PId) = PickedZ()
      PNormalX(PId) = PickedNX()
      PNormalY(PId) = PickedNY()
      PNormalZ(PId) = PickedNZ()
     EndIf
    EndIf
   Next
   MsTime% = MilliSecs() - MsStart
   LinepicksMsTime = LinepicksMsTime + MsTime

   If( PsCount > 0 )
    SmallestD# = 1000000
    SId% = 0
    For PId% = 1 To PsCount Step 1
     D# = Distance3D(PStartX(PId),PStartY(PId),PStartZ(PId),PPointX(PId),PPointY(PId),PPointZ(PId))
     If( D < 0.25+GVLength )
      If( D < SmallestD )
       SmallestD = D
       SId = PId
      EndIf
     EndIf
    Next
    If( SmallestD < 0.25+GVLength And SId > 0 )
     EntityColor(PPickable(SId),255,000,255)
     VFactor# = (SmallestD-0.25)/GVLength
     If( VFactor < 0.01 )
      VFactor = 0
     EndIf
     TranslateEntity(HumanoidRoot(Id),HumanoidGVX(Id)*VFactor,0,HumanoidGVZ(Id)*VFactor,True)  
     HumanoidGVX(Id) = -HumanoidGVX(Id)/10
     HumanoidGVZ(Id) = -HumanoidGVZ(Id)/10
     ;HumanoidGVX(Id) = 0
     ;HumanoidGVZ(Id) = 0
     ;here i can retrieve the pickable ref, the pickable name, the pickable point xyz, the pickable nxnynz
     ;DebugLog("PPickableRef = "+PPickable(SId))
     ;DebugLog("PPickableName = "+EntityName(PPickable(SId)))
     ;DebugLog("PPoint X,Y,Z = "+PPointX(SId)+","+PPointY(SId)+","+PPointZ(SId))
     ;DebugLog("PNormal NX,NY,NZ = "+PNormalX(SId)+","+PNormalY(SId)+","+PNormalZ(SId))
     PName$ = EntityName(PPickable(SId))
     PKind$ = Left(PName,3)
     PId% = Int(Right(PName,Len(PName)-3))
     ;depending on the kind of pickable and depending on the picked normal decide if humanoid is OnAir or OnLedge or OnLadder
     If( PKind = "BUI" Or PKind = "PLA" )
      ;does the picked normal corresponds to a wall ?
      ;if yes
       ;is the humanoid oriented towards enough the wall ?
       ;if yes
        ;is there a grabbable ledge near enough (between humanoidrootY+0.4375 to humanoidrootY+2.05 ?)
        ;if yes
         ;humanoid is OnLedge
         ;humanoid IsGrabbing
        ;else if no
         ;humanoid is OnAir
         ;humanoid IsFalling
       ;else if no
        ;humanoid is OnAir
        ;humanoid IsFalling
      ;else if no
       ;humanoid is OnAir
       ;humanoid IsFalling
     Else If( PKind = "LAD" )
      ;is the humanoid oriented towards enough the ladder ?
      ;if yes
       ;humanoid is OnLadder
       ;humanoid IsGrabbing
      ;else if no
       ;humanoid is OnAir
       ;humanoid IsFalling
     Else
      ;humanoid is OnAir
      ;humanoid IsFalling
     EndIf
    Else
     TranslateEntity(HumanoidRoot(Id),HumanoidGVX(Id),0,HumanoidGVZ(Id),True)
    EndIf
   Else If( PsCount = 0 )
    TranslateEntity(HumanoidRoot(Id),HumanoidGVX(Id),0,HumanoidGVZ(Id),True)
   EndIf

   If( HumanoidPostureMode(Id) = CStanding )

    If ( KeySpaceState = CPre

RemiD