3rdPersonCam with Pivot - Why-o-why isn't this working?

Started by Rick Nasher, February 05, 2018, 20:01:21

Previous topic - Next topic

Rick Nasher

- fingers x-ed -
_______________________________________
B3D + physics + shaders + X-platform = AGK!
:D ..ALIENBREED *LIVES* (thanks to Qube).. :D
_______________________________________

Rick Nasher

#1
V6.1 - introduced types..
// Project: Universal 1st/3rd person framework.
// Created: 2017-02-04


WindowAndDisplaySetup() 
AssignKeys()

foldstart // ------------------- Initialization variables  ----------------------------.
#option_explicit

#constant version#=6.1
#constant physscale=40
#constant texturized=0  // toggle procedural generated textures or plain colors(faster)
Global progresscount=0


// camera & player controller..
#constant MaxCameraDistance#= 280/2 // needs work..
Global MinCameraDistance#
MinCameraDistance# = 140

Global NewCameraDistance#
NewCameraDistance#=MaxCameraDistance#
Global UserCameraDistance#
UserCameraDistance#=MaxCameraDistance#
Global CameraDistance#

Global CameraAngleX#,CameraAngleY#
Global GetPointerMoveX#, GetPointerMoveY#
Global RayObjectID


Global adjustfactorX#=0
Global adjustfactorZ#=0
Global FrameTime#
Global PointerX#, PointerY#, PointerZ#
Global cam_up=0

Global mouselocked=0
Global cammode=0
Global endgame=0
Global infodisplay=1
Global helpdisplay=0
Global nightMode=0
Global lightMode=0
Global torchOn=0
Global fog=0

Global gravity#=  20 //60 // if set lower than the ricochet of bullet collisions can set player up into the sky like a rocket booster.
                                   //  -10.0 meters per second on the Y axis will give the correct visual result.

// player..
Global playerheight#=  72 // 1.8*physscale
Global playerwidth# =  40 // 1 *physscale
Global hspeed#= 80  // 2    * 40
Global vspeed#= 20  // 0.5 * 40
Global speed#= 1 // 40   // 1   * 40
Global jump=0
Global upy#=0
Global maxjump#  //5
maxjump#=  200 //120 //  gravity# *3
Global jumpwait#=0
Global falling=0
Global climbing=0
Global hitobjectatx, hitobjectaty, hitobjectatz,object_hit, object_hit_ammount
////////////////////////////////<<<<<<<<<<<
Global flymode=0

// objects..
Global planeID

// player(s)..
Global PlayerObjectID,rightarmID, leftarmID, gunID, gunendID,targetID, unaBrow, nose, tail, SourceID
Global targetIDx#, targetIDy#, targetIDz#

Global PlayerX#,PlayerY#,PlayerZ#
Global oldPlayerX#,oldPlayerY#,oldPlayerZ#
Global newPlayerX#,newPlayerY#,newPlayerZ#
Global newestPlayerX#, newestPlayerY#, newestPlayerZ#
Global swapped_player
////////////////////////////////<<<<<<<<<<<<<<<<<<<<<<<<<

// building..
//Global floor3A

// elevator..
Global ElevatorY#=1
ElevatorY#=ElevatorY#*physscale
Global ElevatorVector#=.1
ElevatorVector#=ElevatorVector#*physscale
ElevatorVector#=4
Global Elevator1
Global EleTimerSet=0
Global EleWait#=0
Global FirstFloorDone=0
Global SecFloorDone=0
Global ThrdFloorDone=0
Global TopFloor=0
Global ElevatorDoorLeft0
Global ElevatorDoorRight0
Global ElevatorDoorLeft1
Global ElevatorDoorRight1

// ladder & jumppad..
Global ladderhitbox
Global ladderhitbox2
Global pad

//remstart
//////////////////// needs sorting(due to opt explic)...
Global img, delayperiod#, delay#, steeltexture, rooflighttexture
Global elevatortop, elevatorlight, elevatorwallleft, elevatorwallfront, elevatorpostleft, elevatorpostright, elevatorroof
Global wr, wg, wb, wt, wr#,wg#, wb#,wt#, lx#, ly#, lz#
Global l1, l2, l3, l4, l5, l22, leftlightpodbulb, rightlightpodbulb, blucone, redcone
Global ladderBulbBtmCap1 ,ladderBulbBtmHng1, ladderBulb1  // ladderbulpbtmcap1
Global ladderBulbTopCap2, ladderBulbBtmHng2, ladderBulb2 , ladderBulb3
Global ladderLightC, ladderLight2C, ladderLight3C
Global ladderBulb2BtmCap1, ladderBulb2BtmHng1
Global ladderBulb2TopCap2, ladderBulb2BtmHng2
Global ladderBulb3BtmCap1, ladderBulb3BtmHng1
Global ladderBulb3TopCap2, ladderBulb3BtmHng2
////////////////////
// text..
Global dis$ as string

//remend
foldend

CreateWorld() // ------------- Setup Environment -------------------------------.

foldstart // ------------------- Players system ------------------------------------.
type MeshIDs
body_mID as integer
unaBrow_mID as  integer
nose_mID as integer
tail_mID as integer

footLeft_mID as integer
footRight_mID as integer
leftArm_mID as integer
rightArm_mID as integer

gun_mID as integer
gunsight_mID as integer
gunend_mID as integer
target_mID as integer

campivot_mID as integer
endtype
 
type CharacterType
// vars
name as string      // character's  name
species as string  //  human, enemy, extra,  monster, bot
energy as float

// physical..
width as float     // mesh width
height as float    // mesh height
weight as float   // for use with physics

// coords & angles....
x as float
y as float
z as float
anglex as float
angley as float
anglez as float

oldx as float
oldy as float
oldz as float
oldanglex as float
oldangley as float
oldanglez as float

// meshes..        
mesh as MeshIDs
endtype

Global player as CharacterType[5] // Setup an array of 5 players as type Character

// create players..  using :  createPlayer( plr ref as Character, n$, spc$, nrg#, wdt#, hgt#, wgt#, ix#, iy#, iz#, iax#, iay#, iaz#)

Global localPlayer as integer // used for switching players..
localPlayer=1 // start of as player1
createPlayer( player[localPlayer], "Player1", "human",100, playerwidth#, playerheight#, 80, 0,0,0, 0,0,0  )
SetObjectPosition( player[1].mesh.body_mID, 0,playerheight#/2,-10*physscale)
Global plrtexture  as integer
//If texturized=1
plrtexture =CreateTexture(250,24, makecolor(155,155,205) ,27)
SetObjectImage( player[1].mesh.body_mID, plrtexture, 0 )
//endif

createPlayer( player[2], "Player2", "human",100,1.8,1,80,0,0,0, 0,0,0  )
SetObjectColor( player[2].mesh.body_mID,200,50,55,255)
SetObjectPosition( player[2].mesh.body_mID, -300,playerheight#/2,0)

createPlayer( player[3], "Player3", "human",100,1.8,1,80,0,0,0, 0,0,0  )
SetObjectColor( player[3].mesh.body_mID,50,50,200,255)
SetObjectPosition( player[3].mesh.body_mID, -500,playerheight#/2,0)

foldend


do // -------------------------- Main loop ------------------------------------------.

FrameTime#=GetFrameTime()

//UpdateElevator()
//UpdateLights()

UpdatePlayer(localPlayer)
// UpdateProjectile()

CheckAdditionalKeys()

DisplayInfo()
DisplayHelp()

If  endgame=1 then exit
sync()

loop
ClearPointLights()
End // exit  game..

// ----------------------------- Functions ------------------------------------------.

foldstart // ------------------- setup and update world --------------------------.

Function WindowAndDisplaySetup()
// ------------not really needed for this example -------
// set window properties
SetWindowTitle("Test V"+str(version#,1) )

// set display properties
SetWindowSize(1920,1080,0)
SetWindowAllowResize(1) // allow the user to resize the window

SetVirtualResolution(1920,1080) // doesn't have to match the window
//setvirtualresolution(1024,600)
SetOrientationAllowed(1,1,1,1) // allow both portrait and landscape on mobile devices
SetSyncRate(30,0) // 30fps instead of 60 to save battery
SetScissor(0,0,0,0) // use the maximum available screen space, no black borders
UseNewDefaultFonts(1) // since version 2.0.22 we can use nicer default fonts
SetPrintSize( 20 )
SetPrintColor( 00, 00, 00,255 )

SetClearColor(1,128,198)
SetGlobal3DDepth(10000) // Sets the position of all 3D objects relative to 2D objects.

SetResolutionMode(1)
SetAntialiasMode(1)
SetImmersiveMode(1)
SetRawMouseVisible(0)
SetCameraRange(1,1,1000 *physscale)
SetAmbientColor(128,128,128)
SetGenerateMipmaps(1)
// -----------------------------------------------------------
fog=1
// add some atmospheric fog
SetFogMode( fog )
SetFogColor( 161,183,209 )
SetFogRange( 50*physscale, 700*physscale )
//SetFogRange( 60,95 )
SetFogSunColor( 255,230,179 )

// -----------------------------------------------------------
SetShadowMappingMode(3)
SetShadowSmoothing(1) // random sampling
SetShadowMapSize(2048,2024)
EndFunction

Function CreateWorld()


// create a plane for things to stand on, turn its collision off, rotate it and position it under the middle box to act as a ground
// this is purely coismetic
planeID=CreateObjectPlane(40000,40000)
SetObjectCollisionMode(planeID,0) // this is to stop it interfering with the collision with the map
// ensure everything is at correct starting point an orientation at creation.
SetObjectPosition(planeID,0,0,0) : SetObjectRotation(planeID,0,0,0)
// put where we want it..
SetObjectRotation(planeID,90,0,0) // put it flat
SetObjectPosition(planeID,0,0,0) //realign with origin
If texturized=1
planetexture as integer
planetexture = CreateTexture(512,512, makecolor(50,200,100) ,20) //
progresscount=progresscount+1

SetObjectImage(planeID,planetexture,0)
Else
SetObjectColor(planeID,50,200,100,255) // color it lawn style
Endif



// mark the center of our world(0,0,0). with a streetlight..
Global centerpoleID // center mark
centerpoleID=CreateObjectCylinder(240,8,480)
SetObjectPosition(centerpoleID,0,120,0) :  SetObjectRotation(centerpoleID,0,0,0) // ensure is at correct starting point.
If texturized=1
//poletexture = CreateTexture(512,512, makecolor(10,10,10) ,20) //
// poletexture = CreateTexture(20,255, makecolor(50,255,255) ,50)
Global poletexture
poletexture = CreateTexture(20,255, makecolor(186, 196, 200) ,50)
progresscount=progresscount+1
SetObjectImage(centerpoleID,poletexture,0)
Else
SetObjectColor( centerpoleID ,0,0,0,255)
Endif
SetObjectCastShadow(centerpoleID,1)

Lightbulb as integer
Lightbulb=CreateObjectCapsule(40,80,1280)
SetObjectPosition(Lightbulb,0,6*physscale,0)
SetObjectColor(Lightbulb, 255,255,255,225)
SetObjectTransparency(Lightbulb,1)
SetObjectColorEmissive(Lightbulb,1255,1255,1255)

Lightcap as integer
Lightcap= CreateObjectCone(20,80,1280)
SetObjectPosition(Lightcap,0,280,0)
If texturized=1
Global poletexture2
//poletexture2 = CreateTexture(20,20, makecolor(50,255,255) ,50)
poletexture2 = CreateTexture(20,20, makecolor(186, 196, 200) ,50)
progresscount=progresscount+1
SetObjectImage(Lightcap,poletexture2,0)
Else
SetObjectColor(Lightcap, 55,55,55,255)
Endif
SetObjectCastShadow(centerpoleID,1)


// Create some random static scenery objects to test with..
Global Dim obstacle[20]
Global Dim textureobstacle[20]
Local i as integer, r as integer

For i=2 To 20
r=Random(1,4)
if r=1
obstacle[i]=CreateObjectBox( random(1,800), random(1,800) , random(1,800) )
SetObjectPosition(obstacle[i],0,0,0) :  SetObjectRotation(obstacle[i],0,0,0) // ensure is at correct starting point.
SetObjectPosition(  obstacle[i], Random(-3000, 3000),0,Random(-3000,1000))
SetObjectRotation (obstacle[i],0.0,Random(0,360),0.0)
elseif r=2
obstacle[i]=CreateObjectCone(random(1,800),random(1000,2000),random(1,1200))
SetObjectPosition(obstacle[i],0,0,0) :  SetObjectRotation(obstacle[i],0,0,0) // ensure is at correct starting point.
//SetObjectPosition(  obstacle[i], Random(-2000,2000),0,Random(-2000,2000))
SetObjectPosition(  obstacle[i], Random(-3000, 3000),0,Random(-3000,1000))
SetObjectRotation (obstacle[i],0.0,Random(0,360),0.0)
elseif r=3
obstacle[i]=CreateObjectCylinder(random(1,280),random(1,600),random(1,1200))
SetObjectPosition(obstacle[i],0,0,0) :  SetObjectRotation(obstacle[i],0,0,0) // ensure is at correct starting point.
//SetObjectPosition( obstacle[i], Random(-2000,2000),0,Random(-2000,2000))

   // SetObjectPosition(  obstacle[i], Random(-3000, 3000),0,Random(-3000,1000))
while GetObjectX(  obstacle[i] ) = 0 or GetObjectX(  obstacle[i] ) < -500  or GetObjectX(  obstacle[i] ) < 500 or GetObjectZ( obstacle[i] ) = 0  or (GetObjectZ( obstacle[i] ) > -500   and GetObjectZ(  obstacle[i] ) < 500)
SetObjectPosition(  obstacle[i], Random(-3000, 3000),0,Random(-3000,1000))
endwhile

SetObjectRotation (obstacle[i],Random(0,360),Random(0,360),0.0)
//SetObjectScale (obstacle[i],-Random(.2,1),-Random(.2,1),-Random(.2,1))

else
//( diameter, rows, columns )
diameter# as float, rows# as float, colums# as float

diameter#= random(20,1000)
rows#=random(.1,25)
colums#=random(5,32)
obstacle[i]=CreateObjectsphere(diameter#,rows# ,colums# )
SetObjectPosition(obstacle[i],0,0,0) :  SetObjectRotation(obstacle[i],0,0,0) // ensure is at correct starting point.
//SetObjectPosition(  obstacle[i], Random(-2000,2000),-diameter#/5+random(0,40),Random(-2000,2000))
SetObjectPosition(  obstacle[i], Random(-3000,3000),-diameter#/5+random(0,40),Random(-3000,1000))
// SetObjectScale (obstacle[i],Random(.2,1),Random(.2,1),Random(.2,1))
SetObjectRotation (obstacle[i],0.0,Random(0,360),0.0)
endif

//SetObjectScale (obstacle[i],Random(.2,2),Random(.2,2),Random(.2,2))
SetObjectRotation (obstacle[i],0.0,Random(0,360),0.0)

If texturized=1
textureobstacle[i] = CreateTexture ( Random(0,1024), Random(0,1024), makecolor( Random(0,255), Random(0,255), Random(0,255) ) ,  Random(1,100) )
progresscount=progresscount+1
SetObjectImage(obstacle[i],textureobstacle[i],0)
Else
SetObjectColor (obstacle[i],Random(0,255),Random(0,255),Random(0,255),Random(0,255))
Endif

SetObjectCollisionMode(obstacle[i],1)
SetObjectCastShadow(obstacle[i],1)
Next

//  create jumping pad(s)
padsupport as integer
padsupport=CreateObjectBox(  160, 80 , 160 )
SetObjectPosition(padsupport,0,0,0) :  SetObjectRotation(padsupport,0,0,0) // ensure is at correct starting point.
SetObjectPosition(  padsupport, -200 ,0 ,  2000 )
SetObjectColor (padsupport,55,55,55,255)
SetObjectCastShadow(padsupport,1)

//pad as integer
pad=CreateObjectsphere(2,120 ,120 )
SetObjectScale(pad, 60 , 10, 60 ) 
SetObjectPosition(pad,0,0,0) :  SetObjectRotation(pad,0,0,0) // ensure is at correct starting point.
SetObjectPosition(  pad, -200, 40, 2000)
SetObjectColor (pad,155,100,155,255)

//CreateLights()


EndFunction

Function Updateworld()

If nightMode
SetAmbientColor(12,12,12)
SetClearColor(12,12,12)

Else
SetAmbientColor(128,128,128)
SetClearColor(1,128,198)
EndIf

EndFunction

foldend

foldstart // .------------------ setup and update players ------------------------.

function createPlayer( plr ref as CharacterType, n$, spc$, nrg#, wdt#, hgt#, wgt#, ix#, iy#, iz#, iax#, iay#, iaz#)
// setup player properities..
plr.name = n$
plr.species= spc$
plr.energy = nrg#
plr.width = wdt#
plr.height = hgt#
plr.weight = wgt#

plr.x = ix#
plr.y = iy#
plr.z = iz#
plr.anglex = iax#
plr.angley = iay#
plr.anglez = iaz#

plr.oldx = ix#
plr.oldy = iy#
plr.oldz = iz#
plr.oldanglex = iax#
plr.oldangley = iay#
plr.oldanglez = iaz#

addMeshesToPlayer( plr )   // add meshes that make up this character
endfunction

function addMeshesToPlayer( plr ref as CharacterType )
// add meshes that make up the character..

plr.mesh.body_mID = CreateObjectCapsule(playerwidth#,playerheight#,1) // ( diameter, height, axis )
SetObjectPosition(plr.mesh.body_mID, 0, playerheight#/2, -400)  // 0,1*playerheight#/2,-10*physscale)
SetObjectCastShadow(plr.mesh.body_mID,1)
SetObjectCollisionMode(plr.mesh.body_mID, 0)  //prevent self hiting


// add some detail so orientation of player is more clear..
plr.mesh.unaBrow_mID = CreateObjectCone(.4*physscale,.8*physscale,12):SetObjectColor( plr.mesh.unaBrow_mID ,0,0,0,255)
SetObjectPosition(plr.mesh.unaBrow_mID,0,0,0) :  SetObjectRotation(plr.mesh.unaBrow_mID,0,0,0) // ensure is at correct starting point.
SetObjectPosition( plr.mesh.unaBrow_mID ,0,.4*physscale,.3*physscale)
SetObjectRotation( plr.mesh.unaBrow_mID ,-180,0,0)
SetObjectCastShadow(plr.mesh.unaBrow_mID,1)
SetObjectCollisionMode(plr.mesh.unaBrow_mID,0)  //prevent self hiting
FixObjectToObject(plr.mesh.unaBrow_mID,plr.mesh.body_mID)

plr.mesh.nose_mID = CreateObjectSphere(.2*physscale,1.2,12):SetObjectColor( plr.mesh.nose_mID,255,0,0,255) // //250,150,155,255=pink
SetObjectPosition(plr.mesh.nose_mID,0,0,0) :  SetObjectRotation(plr.mesh.nose_mID,0,0,0) // ensure is at correct starting point.
SetObjectPosition( plr.mesh.nose_mID,0,.2*physscale,.5*physscale)
SetObjectCastShadow(plr.mesh.nose_mID,1)
SetObjectCollisionMode(plr.mesh.nose_mID,0)  //prevent self hiting
FixObjectToObject(plr.mesh.nose_mID,plr.mesh.body_mID)

plr.mesh.tail_mID = CreateObjectcone(.2*physscale,.3*physscale,12):SetObjectColor( plr.mesh.tail_mID ,255,255,255,255)
SetObjectPosition(plr.mesh.tail_mID ,0,0,0) :  SetObjectRotation(plr.mesh.tail_mID ,0,0,0) // ensure is at correct starting point.
//SetObjectPosition( tail,0,-.9*physscale,-.4*physscale)
SetObjectPosition( plr.mesh.tail_mID ,0,-.81*physscale,-.4*physscale)
SetObjectRotation(plr.mesh.tail_mID ,-130,0,0)
SetObjectCastShadow(plr.mesh.tail_mID ,1)
SetObjectCollisionMode(plr.mesh.tail_mID ,0)  //prevent self hiting
FixObjectToObject(plr.mesh.tail_mID ,plr.mesh.body_mID)


plr.mesh.footLeft_mID = CreateObjectcone(.2*physscale,.3*physscale,12):SetObjectColor( plr.mesh.footLeft_mID,255,0,0,255)
SetObjectPosition(plr.mesh.footLeft_mID,0,0,0) :  SetObjectRotation(plr.mesh.footLeft_mID,0,0,0) // ensure is at correct starting point.
SetObjectPosition( plr.mesh.footLeft_mID,-.2*physscale,-.77*physscale,.25*physscale)
SetObjectRotation(plr.mesh.footLeft_mID,0,0,0)
SetObjectCastShadow(plr.mesh.footLeft_mID,1)
SetObjectCollisionMode(plr.mesh.footLeft_mID,0)  //prevent self hiting
FixObjectToObject(plr.mesh.footLeft_mID,plr.mesh.body_mID)


plr.mesh.footRight_mID = CreateObjectcone(.2*physscale,.3*physscale,12):SetObjectColor( plr.mesh.footRight_mID,255,0,0,255)
SetObjectPosition(plr.mesh.footRight_mID,0,0,0) :  SetObjectRotation(plr.mesh.footRight_mID,0,0,0) // ensure is at correct starting point.
SetObjectPosition( plr.mesh.footRight_mID,.2*physscale,-.77*physscale,.25*physscale)
SetObjectRotation(plr.mesh.footRight_mID,0,0,0)
SetObjectCastShadow(plr.mesh.footRight_mID,1)
SetObjectCollisionMode(plr.mesh.footRight_mID,0)  //prevent self hiting
FixObjectToObject(plr.mesh.footRight_mID,plr.mesh.body_mID)

// add left arm..
plr.mesh.leftArm_mID = CreateObjectSphere(.6*physscale,10,10) //diameter, rows, columns )
SetObjectScale(plr.mesh.leftArm_mID,.7,1.4,1)
SetObjectColor( plr.mesh.leftArm_mID,150,150,255,255)
SetObjectPosition(plr.mesh.leftArm_mID,0,0,0) :  SetObjectRotation(plr.mesh.leftArm_mID,0,0,0) // ensure is at correct starting point.
SetObjectPosition(plr.mesh.leftArm_mID,-.4*physscale,-.1*physscale,.1*physscale)
SetObjectRotation(plr.mesh.leftArm_mID,0,0,00)
FixObjectToObject(plr.mesh.leftArm_mID, plr.mesh.body_mID)
SetObjectCollisionMode(plr.mesh.leftArm_mID,0)  //prevent self hiting
SetObjectCastShadow(plr.mesh.leftArm_mID,1)

// add right arm..
plr.mesh.rightArm_mID = CreateObjectSphere(.6*physscale,10,10) //diameter, rows, columns )
SetObjectColor( plr.mesh.rightArm_mID,150,150,255,255)
SetObjectPosition(plr.mesh.rightArm_mID,0,0,0) :  SetObjectRotation(plr.mesh.rightArm_mID,0,0,0) // ensure is at correct starting point.
SetObjectPosition(plr.mesh.rightArm_mID,.4*physscale,0,.1*physscale)
SetObjectRotation(plr.mesh.rightArm_mID,0,0,0)
FixObjectToObject(plr.mesh.rightArm_mID,plr.mesh.body_mID )
SetObjectCollisionMode(plr.mesh.rightArm_mID,0)  //prevent self hiting
SetObjectCastShadow(plr.mesh.rightArm_mID,1)

// add gun..
plr.mesh.gun_mID = CreateObjectCylinder(1.1*physscale,.2*physscale,10) //height, diameter, segments )
SetObjectPosition(plr.mesh.gun_mID,0,0,0) :  SetObjectRotation(plr.mesh.gun_mID,0,0,0) // ensure is
SetObjectPosition(plr.mesh.gun_mID,0,0,0) :  SetObjectRotation(plr.mesh.gun_mID,0,0,0) // ensure is at correct starting point.
SetObjectRotation(plr.mesh.gun_mID,90,7,0) // rotate the cylinder from vertical to horizontal position(infliuences also the coords syst; x=y
SetObjectPosition(plr.mesh.gun_mID,0.2*physscale,0.15*physscale,0.4*physscale)
FixObjectToObject(plr.mesh.gun_mID,plr.mesh.rightArm_mID)
SetObjectColor(plr.mesh.gun_mID,0,0,0,255) //
SetObjectCollisionMode(plr.mesh.gun_mID,0)  //prevent self hiting
SetObjectCastShadow(plr.mesh.gun_mID,1)


//create  marker for sight at end of gun and use as pivot for releasing bullets.
plr.mesh.gunsight_mID= CreateObjectCone(.1*physscale,0.14*physscale,1*physscale) //height, diameter, segments
SetObjectPosition(plr.mesh.gunsight_mID,0,0,0) :  SetObjectRotation(plr.mesh.gunsight_mID,0,0,0) // ensure is at correct starting point.
SetObjectRotation(plr.mesh.gunsight_mID,90,180,0)
SetObjectPosition (plr.mesh.gunsight_mID,0,.5*physscale,-0.1*physscale)
FixObjectToObject(plr.mesh.gunsight_mID, plr.mesh.gun_mID )
SetObjectColor(plr.mesh.gunsight_mID,50,50,55,255) //
SetObjectCollisionMode(plr.mesh.gunsight_mID,0)  //prevent self hiting
SetObjectCastShadow(plr.mesh.gunsight_mID,1)

//create  pivot for releasing bullets.
plr.mesh.gunend_mID= CreateObjectSphere(.3*physscale,16,16) //height, diameter, segments
SetObjectPosition(plr.mesh.gunend_mID,0,0,0) :  SetObjectRotation(plr.mesh.gunend_mID,0,0,0) // ensure is at correct starting point.
SetObjectRotation(plr.mesh.gunend_mID,-90,0,0)
SetObjectPosition(plr.mesh.gunend_mID,-0.01*physscale,0.5*physscale,-0.01*physscale)
FixObjectToObject(plr.mesh.gunend_mID,plr.mesh.gun_mID)
SetObjectColor(plr.mesh.gunend_mID,255,255,0,55) //
SetObjectCollisionMode(plr.mesh.gunend_mID,0)  //prevent self hiting
SetObjectTransparency(plr.mesh.gunend_mID,1)
//SetObjectVisible(plr.mesh.gunend_mID,0)


plr.mesh.target_mID= CreateObjectSphere(.25*physscale,16,16) //height, diameter, segments
//targetID= CreateObjectbox(4,4,1) //height, diameter, segments
SetObjectPosition(plr.mesh.target_mID,0,0,0) :  SetObjectRotation(plr.mesh.target_mID,0,0,0) // ensure is at correct starting point.
SetObjectRotation(plr.mesh.target_mID,-90,0,0)
SetObjectPosition(plr.mesh.target_mID,-0.01*physscale,.65*physscale,0.01*physscale)
FixObjectToObject(plr.mesh.target_mID,plr.mesh.gun_mID)
SetObjectColor(plr.mesh.target_mID,255,0,0,155) //
SetObjectCollisionMode(plr.mesh.target_mID,0)  //prevent self hiting
SetObjectTransparency(plr.mesh.target_mID,1)
MoveObjectLocalZ(plr.mesh.target_mID, 7*physscale)
SetObjectColorEmissive(plr.mesh.target_mID,255,0,0)
//targetTexture=LoadImage( "blue.png" )
//setobjectimage( plr.mesh.target_mID, targetTexture, 1 )


// cam pivot..
plr.mesh.campivot_mID = CreateObjectBox(.5*physscale,.5*physscale,.5*physscale):SetObjectColor( plr.mesh.campivot_mID  ,255,255,0,105)
SetObjectPosition(plr.mesh.campivot_mID, 0,0,0) :  SetObjectRotation(plr.mesh.campivot_mID ,0,0,0) // ensure is at correct starting point.
//SetObjectPosition(plr.mesh.campivot_mID  ,0, 40 ,-20) //0,1*physscale,-.5*physscale)
SetObjectPosition(plr.mesh.campivot_mID  ,0, 40 , -40)  //-MaxCameraDistance#)  //1 unit above and behind the player.
SetObjectTransparency(plr.mesh.campivot_mID ,1)
SetObjectCollisionMode(plr.mesh.campivot_mID ,0)  //prevent self hiting
FixObjectToObject(plr.mesh.campivot_mID ,plr.mesh.body_mID)
FixObjectPivot(plr.mesh.campivot_mID )

endfunction

Function UpdatePlayer(locPlr as integer)

Local joystick_x# as float
Local joystick_y# as float
Local PointerX# as float
Local PointerY# as float
Local CamPivotX# as float
Local CamPivotY# as float
Local CamPivotZ# as float
Local NewCamPivotX# as float
Local NewCamPivotY# as float
Local NewCamPivotZ# as float

// store players current x,y,z and angles before any movement..
player[locPlr].oldx = GetObjectX(player[locPlr].mesh.body_mID)
player[locPlr].oldy = GetObjectY(player[locPlr].mesh.body_mID)
player[locPlr].oldx = GetObjectZ(player[locPlr].mesh.body_mID)

// -------------------------- jumping..  --------------------------------------------------------------------
If  GetRawKeyState(KEY_SPACE)  and falling=0  // Space = jump
If  jump=0 and Timer()>jumpwait# //  inair=0 // if not juming/inair  already, so no jumping when falling..
jump=1  // intitiate new jump
jumpwait#=Timer()+.4 // delay should  so player cannot initiate jumping right after for is weird,
Endif
Endif

// excute jump..
if jump=1  // if jump has been initiated 
upy#=upy#+40 //(gravity#*jmultiplier#) // count up till max jump heigth reached.
if  upy#>=maxjump#  // if maxheight reached then  reset y to 0 and no end jump..
upy#=0
jump=0
else // if not reached maximum height yet  then..
MoveObjectLocalY(player[locPlr].mesh.body_mID,40) // the actual jump.
endif
endif

// ------------------------------------------------------------------------------------------------------------
// get input from mouse pointer..(to turn player left/right and/or turn cam up/dow)
PointerX#=GetPointerX()
PointerY#=GetPointerY()

If mouseLocked=0
setrawmouseposition(GetVirtualWidth()*0.5,GetVirtualHeight()*0.5) // re-center mouse on screen
EndIf
GetPointerMoveX#=(PointerX#-GetPointerX()) // calculate distance moved
GetPointerMoveY#=(PointerY#-GetPointerY())

// for turning left/right..
If  GetRawKeyState(KEY_LEFT)  OR GetRawKeyState(KEY_A) // Left/A = turn player left
GetPointerMoveX# =  -hspeed#
Endif
If GetRawKeyState(KEY_RIGHT) OR GetRawKeyState(KEY_D) // Right/D = turn player right
GetPointerMoveX# =  hspeed#
Endif

// get current camera angles..
CameraAngleX#=CameraAngleX#+GetPointerMoveY#*FrameTime#
CameraAngleY#=CameraAngleY#+GetPointerMoveX#*FrameTime# // calc camera angle
UserCameraDistance#=UserCameraDistance#-GetRawMouseWheelDelta() *40  // zoom in/out when used mousewheel
if UserCameraDistance#>MaxCameraDistance# then UserCameraDistance#=MaxCameraDistance# //limit max dist from cam
if UserCameraDistance#<MinCameraDistance#  then UserCameraDistance#=MinCameraDistance# // limit minimum dist from cam
// ------------------------------------------------------------------------------------------------------------
//  for moving forward/backward..

// get player's AGK joystick input.
// On PC WASD are used, on devices without kybd will create a virtual onscreen joystick.
// ( can optionally be positiioned differently on screen using SetJoystickScreenPosition ).
joystick_x# = GetJoyStickX()*hspeed#      // horizontal movement input
joystick_y# = GetJoyStickY()*-vspeed#     // vertical movement input


// get vertical keybpard input (PC only)..
speed#=1 //  set initial speed.
If (GetRawKeyState(KEY_UP)  or GetRawKeyState(KEY_W)  or GetRawMouseRightState() ) AND  GetRawKeyState(KEY_SHIFT) // Up/W/RBM + SHIFT = move player forward(run)
speed#=3 //  with shift = speedup.
joystick_y#=1*vspeed#  *speed# //addjust z
ElseIf GetRawKeyState(KEY_UP)  or GetRawKeyState(KEY_W)  or GetRawMouseRightState() // Up/W/RBM = move player forward (walk)
speed#=1 // without Shift = normal speed.
joystick_y#=1*vspeed#  *speed# //addjust z
Else
//
endif
If   GetRawKeyState(KEY_DOWN)  or GetRawKeyState(KEY_S)  // Down/S = move player backward. (acually  I think  the S key will be read by default when using GetJoyStick() so pehaps redundant..
joystick_y#=1*-vspeed# *speed#
Endif


// move player based on the input  of  joystick and  mouse..
RotateObjectLocalY(player[locPlr].mesh.body_mID,joystick_x#) // seems redundant,but somehow makes cam movement more fluid?
MoveObjectLocalZ(player[locPlr].mesh.body_mID,joystick_y#)
SetObjectRotation(player[locPlr].mesh.body_mID,0,CameraAngleY#,0) // set player at  Y angle calculated according to mousemovement, don't move X angle for player will then tilt up/down

// for strafe.. ( if not put here then doesn't work )
If GetRawKeyState(KEY_Q) // Q = move (strafe) player left
joystick_y# = .1*-hspeed#
MoveObjectLocalX(player[locPlr].mesh.body_mID,joystick_y#)
Endif
If GetRawKeyState(KEY_E) // E = move (strafe) player right
joystick_y# = .1*hspeed#
MoveObjectLocalX(player[locPlr].mesh.body_mID,joystick_y#)
Endif

// -------------------------- apply gravity..  --------------------------------------------------------------
if flymode=1
falling=0 // gravity#=0.0
else // always apply gravity, unless fly mode active..
falling=1 //gravity#=0.5 
endif
if jump=0
MoveObjectLocalY(player[locPlr].mesh.body_mID,-gravity#)  ///2) // gravity ""always on'' except when jumping..
endif
// ------------------------------------------------------------------------------------------------------------


// ################### manage collision checking for the player with other geometry #############
// after above movements, get players new x,y,z's for usage with collisions..
player[locPlr].x=GetObjectX(player[locPlr].mesh.body_mID)
player[locPlr].y=GetObjectY(player[locPlr].mesh.body_mID)
player[locPlr].z=GetObjectZ(player[locPlr].mesh.body_mID)

// sphere cast between the old and new positions of the player to see if we hit something while moving to new location..
object_hit = ObjectSphereSlide(0,player[locPlr].oldx ,  player[locPlr].oldy,  player[locPlr].oldz,  player[locPlr].x,  player[locPlr].y,  player[locPlr].z,  playerwidth#)

// if the sphere has collided with an object then calculate sphere new position to give sliding collision
If object_hit <> 0 // we've hit something then adjust the x,y,z's ..

newestPlayerX#=GetObjectRayCastSlideX(0)
if newestPlayerX#<>player[locPlr].x
//hitobjectatx=1
endif
newestPlayerY#=GetObjectRayCastSlideY(0)
if newestPlayerY#<>player[locPlr].y
//hitobjectaty=1
falling=0
endif
newestPlayerZ#=GetObjectRayCastSlideZ(0)
if newestPlayerZ#<>player[locPlr].z
//hitobjectatz=1
endif

if object_hit = ladderhitbox or object_hit = ladderhitbox2 //or object_hit= Stairs
gravity#= -70 //-.5  //1 // reduce/reverse  gravity

elseif object_hit = pad
jump=1
maxjump#=750
gravity#=-30 //1 // cancel out gravity
else // if hit something else..
gravity#= 20 //70 //.5
maxjump#=200 // 5 //*physscale
endif

else // nothing hit ( could also be up in air)
hitobjectatx=0 : hitobjectaty=0 : hitobjectatz=0
//climbing=0
if jump=0
maxjump#=200
gravity#= 20
endif

// nothings hit so original values after move are still valid, no need to  orrect..
newestPlayerX#=player[locPlr].x
newestPlayerY#=player[locPlr].y
newestPlayerZ#=player[locPlr].z

EndIf

// prevent falling through floor due to gravity update..
If newestPlayerY# <=playerheight#/2 // so if gravity aplied but now ending up below the btm floor.. (could also be checked against terrainy.
newestPlayerY#=playerheight#/2 // limit/reset y to minimm y so don't fall through floor
falling=0
endif

// (re)position player onto new corrected location..
SetObjectPosition(player[locPlr].mesh.body_mID, newestPlayerX#, newestPlayerY#, newestPlayerZ# ) //process all modifications made above.


// **************************************************************************************
    // ************************************ CAMERA MOVEMENT *************************
// **************************************************************************************

// ####### manage camera avoiding geometry inbetween player and cam ########
// get player's current  x,y,z's after moves above. and store them..
player[locPlr].x=GetObjectX(player[locPlr].mesh.body_mID )
player[locPlr].y=GetObjectY(player[locPlr].mesh.body_mID )
player[locPlr].z=GetObjectZ(player[locPlr].mesh.body_mID )

// ------------------------------------------------------------------------------------------------------------
If cammode=0 //  3rd person mode(default)..

// 1st: sync campivot to new player location..
SetObjectPosition(player[locPlr].mesh.campivot_mID, player[locPlr].x, player[locPlr].y+40, player[locPlr].z) // sync pivot with player pos, but a bit higher(shoulderheight).
SetObjectRotation(player[locPlr].mesh.campivot_mID, GetObjectAngleX(player[locPlr].mesh.body_mID) ,GetObjectAngleY(player[locPlr].mesh.body_mID) ,GetObjectAngleZ(player[locPlr].mesh.body_mID)   ) // sync rotation also.
// store the pivot's positions..
CamPivotX# = GetObjectX(player[locPlr].mesh.campivot_mID )
CamPivotY# = GetObjectY(player[locPlr].mesh.campivot_mID )
CamPivotZ# = GetObjectZ(player[locPlr].mesh.campivot_mID )
// now move pivot behind the player at max distance..
    MoveObjectLocalZ( player[locPlr].mesh.campivot_mID,  -MaxCameraDistance#)

// get the campivot''s new  location..
NewCamPivotX# = GetObjectX(player[locPlr].mesh.campivot_mID )
NewCamPivotY# = GetObjectY(player[locPlr].mesh.campivot_mID )
NewCamPivotZ# = GetObjectZ(player[locPlr].mesh.campivot_mID )

// cast from old pivot pos to new to see if something in between the old and new positions..
RayObjectID=ObjectRayCast(0,CamPivotX#,CamPivotY#,CamPivotZ#,NewCamPivotX#,NewCamPivotY#,NewCamPivotZ#) // sent a ray from players pos to cam behind player.
if RayObjectID<>0 // if an object was hit, this means there's an object between player and cam, obstructing the view'
NewCameraDistance#=GetObjectRayCastDistance(0) // get distance to where has been hit.
else
NewCameraDistance#=UserCameraDistance# // nothing's hit so just set to user defined zoom distance.
endif

// calculate new pivot distance..
SetObjectPosition(player[locPlr].mesh.campivot_mID, CamPivotX#,CamPivotY#,CamPivotZ#) // 1st set back to original position.
CameraDistance#=CurveValue(NewCameraDistance#, CameraDistance#,10) //  new camdistance in 10 steps..
MoveObjectLocalZ(player[locPlr].mesh.campivot_mID, -CameraDistance#) // move pivot to newly calculated distance behind the player.


//UpdateCamera(locPlr)  //  replaced below  with   this  function , renabled for debuging..
// ------------------------------------------------------------------------------------------------------------------
// handle camera angles .
// ---- limit cam x angle otherwise may tilt too far up or down..
If CameraAngleX# < 0 // ( iaw: if cam angle negative , we're looking up)
if CameraAngleX#<= -90 // if exceeds allowed range..
CameraAngleX#=-90 // limit angle up angle.
endif
  // update campivot pos:  move campivot backwards to new campivot position behind player..(local z-axis)..
MoveObjectLocalZ(player[locPlr].mesh.campivot_mID, -CameraAngleX#*2.05)

elseIf CameraAngleX#>85 // if in exceeds allowed range..
CameraAngleX#=85 // limit cam down angle.
// update campivot pos:  move campivot backwards to new campivot position behind player..(local z-axis)..
MoveObjectLocalZ(player[locPlr].mesh.campivot_mID, CameraAngleX#*2.05) //
else //  so we're looking up or down or straight ahead, and within allowed range..
// no need to restrain any angles, just update campivot  pos:  move campivot backwards  to new campivot position behind player..(local z-axis)..
MoveObjectLocalZ(  player[locPlr].mesh.campivot_mID, CameraAngleX#*2.05) //
endif

// sync camera position to campivot..
// 1st place camera at player's campivot position, which is slightly above player at shoulderheight.
SetCameraPosition(1,GetObjectX(player[locPlr].mesh.campivot_mID ),GetObjectY(player[locPlr].mesh.campivot_mID ),GetObjectZ(player[locPlr].mesh.campivot_mID ) )   
// now rotate camera as set by inputs of controllers..
SetCameraRotation(1,CameraAngleX#,CameraAngleY#,0 ) // set camera at angle calculated according to mouse(etc)input..


ElseIf cammode =1 // 1st person mode..
foldstart
SetCameraPosition(1,PlayerX#,PlayerY#+24,PlayerZ#-16)   // place camera at player position
SetCameraRotation(1,CameraAngleX#,CameraAngleY#,0) // set camera at angle calculated according to mousemovent

// need to hide face objects?
//SetObjectVisible(PlayerObjectID,cammode)
SetCameraPosition(1,PlayerX#,PlayerY#+(.6*physscale),PlayerZ#-(.4*physscale))   // place camera at player position
// ------------------------------------------------------------------------------------------------------------
foldend
Elseif cammode =2 // detached cam mode..(currently only for debugging) // still needs cam correction for not allowed angles.as in 3rd pers mode.
foldstart
//Setcameralookat(1,PlayerX#,PlayerY#+(.6*physscale),PlayerZ#-(.4*physscale),0) // follow the player around from afar
Setcameralookat(1,PlayerX#,20,PlayerZ#-16,0) // follow the player around from afar

//CameraDistance#=CurveValue(NewCameraDistance#,CameraDistance#,10)
if CameraDistance#<MinCameraDistance#*4

CameraDistance#=MinCameraDistance#*4

SetCameraPosition(1,PlayerX#,PlayerY#,PlayerZ#) // set initial player position.
If jump=0
// MoveCameraLocaly(1,-adjustfactorY#) ///5) // move cam to new position above the player when needed, so floor don't get in the way

MoveCameraLocalZ(1,-CameraDistance#) // move cam to new position behind the player.
endif
endif

// need to still make cam move along when player moves sideways or wanders off too far depth wise.. obstacle avoiding can also be used here,
foldend
Endif

// ------------------------------------------------------------------------------------------------------------
//  also  update  arm+gun rotation ..
SetobjectRotation(player[locPlr].mesh.rightArm_mID,CameraAngleX#,0,0) // adjust gun position according to cam
// ------------------------------------------------------------------------------------------------------------
EndFunction

Function UpdateCamera(locPlr as integer) // sync cam with pivot

// handle camera angles .
// ---- limit cam x angle otherwise may tilt too far up or down..
If CameraAngleX# < 0 // ( iaw: if cam angle negative , we're looking up)
if CameraAngleX#<= -90 // if exceeds allowed range..
CameraAngleX#=-90 // limit angle up angle.
endif
  // update campivot pos:  move campivot backwards to new campivot position behind player..(local z-axis)..
MoveObjectLocalZ(player[locPlr].mesh.campivot_mID, -CameraAngleX#*2.05)
elseIf CameraAngleX#>85 // if in exceeds allowed range..
CameraAngleX#=85 // limit cam down angle.
// update campivot pos:  move campivot backwards to new campivot position behind player..(local z-axis)..
MoveObjectLocalZ(player[locPlr].mesh.campivot_mID, CameraAngleX#*2.05) //
else //  so we're looking up or down or straight ahead, and within allowed range..
// no need to restrain any angles, just update campivot  pos:  move campivot backwards  to new campivot position behind player..(local z-axis)..
MoveObjectLocalZ(  player[locPlr].mesh.campivot_mID, CameraAngleX#*2.05) //
endif

// sync camera position to campivot..
// 1st place camera at player's campivot position, which is slightly above player at shoulderheight.
SetCameraPosition(1,GetObjectX(player[locPlr].mesh.campivot_mID ),GetObjectY(player[locPlr].mesh.campivot_mID ),GetObjectZ(player[locPlr].mesh.campivot_mID ) )   
// now rotate camera as set by inputs of controllers..
SetCameraRotation(1,CameraAngleX#,CameraAngleY#,0 ) // set camera at angle calculated according to mouse(etc)input..
//SetCameraRotation(1,CameraAngleX#,CameraAngleY#,CameraAngleY#) ) // mod for drunk / drug / wounded walk

// SetObjectPosition(player[locPlr].mesh.campivot_mID, GetObjectX(player[locPlr].mesh.campivot_mID ),GetObjectY(player[locPlr].mesh.campivot_mID ),GetObjectZ(player[locPlr].mesh.campivot_mID ) )   
EndFunction
foldend

foldstart // ------------------- additionals ----------------------------------------.

function CurveValue(Destination#,Current#,Steps#)
Current#=Current#+((Destination#-Current#)/Steps#)
endfunction Current#

Function AssignKeys()
   
#constant KEY_KEY_BACKSPACE   8
#constant KEY_TAB   9

#constant KEY_ENTER 13 // also numpad enter
#constant KEY_SHIFT 16
#constant KEY_CONTROL 17
#constant KEY_ALT 18 // added
#constant KEY_ESC 27

#constant KEY_SPACE 32
#constant KEY_PAGEUP 33
#constant KEY_PAGEDOWN 34
#constant KEY_END 35
#constant KEY_HOME 36
#constant KEY_LEFT 37
#constant KEY_UP 38
#constant KEY_RIGHT 39
#constant KEY_DOWN 40

#constant KEY_INSERT 45
#constant KEY_DELETE 46

#constant KEY_0 48
#constant KEY_1 49
#constant KEY_2 50
#constant KEY_3 51
#constant KEY_4 52
#constant KEY_5 53
#constant KEY_6 54
#constant KEY_7 55
#constant KEY_8 56
#constant KEY_9 57

#constant KEY_A 65
#constant KEY_B 66
#constant KEY_C 67
#constant KEY_D 68
#constant KEY_E 69
#constant KEY_F 70
#constant KEY_G 71
#constant KEY_H 72
#constant KEY_I 73
#constant KEY_J 74
#constant KEY_K 75
#constant KEY_L 76
#constant KEY_M 77
#constant KEY_N 78
#constant KEY_O 79
#constant KEY_P 80
#constant KEY_Q 81
#constant KEY_R 82
#constant KEY_S 83
#constant KEY_T 84
#constant KEY_U 85
#constant KEY_V 86
#constant KEY_W 87
#constant KEY_X 88
#constant KEY_Y 89
#constant KEY_Z 90
#constant KEY_CONTEXT   93

#constant KEY_NUM_MULTIPLY 106 // numpad multiply
#constant KEY_NUM_PLUS 107 // numpad plus

#constant KEY_F1 112
#constant KEY_F2 113
#constant KEY_F3 114
#constant KEY_F4 115
#constant KEY_F5 116
#constant KEY_F6 117
#constant KEY_F7 118
#constant KEY_F8 119
  //#constant KEY_F9 120 // does not exist


#constant KEY_SEMICOL 186   
#constant KEY_EQUALS 187
#constant KEY_COMMA 188
#constant KEY_MINUS 189  // numpad subtract
#constant KEY_PERIOD 190  // also  numpad
#constant KEY_SLASH 191 
#constant KEY_SINGLQUOTE 192  // numpad divide (this is the same code as the grave accent/tilde key and seems to be a bug,
   // should be 191 to match the forward slash key)

#constant KEY_SQRBRLEFT 219
#constant KEY_BACKSLASH 220
#constant KEY_SQRBRRIGHT 221
#constant KEY_HASH 222 // APOSTROPHE ?
#constant KEY_ACCENT 223 // ' << is called what?

EndFunction

Function CheckAdditionalKeys()

//
// CTRL / LMB = shoot
// MMBwheel  = +: zoom , -:  release (as in how I did in Blitz GameX 15 )
//
// Space = jump
// Alt / C =  crouch
// Enter = chat
// KEY_BACKSLASH =

// Tab/MMBbtn+whl = scroll+select weapon/inventrory
// M = toggle Map
// N = toggle Compas
// R = toggle Radar
// P = toggle Pause
// L = toggle Lights on/off
// T = toggle Torch on/off.

// F = toggle Focus (lock mouse to screen).
// I = toggle display Inverntory screen??
// Esc = 1x: mainmenu , 2x: exit(windows only)
// F1 = help/ info (as done in F3)
// F2 = toggle Audio on/off
// F3 = toggle 1st / 3rd person / detached / fly mode )
// F4 = Focus / Lock mouse

// Debug Functions:
// F5 = Refresh/reset player/environment ??
// F6 = toggkle Fog ??
// F7 = toggle sun on/off ??
// F8 = day/night mode  ??

// Home = Show waypoint to home
// End = Show waypoint to nearest exit??
// PgUp = reorganize item up in inverntory screen
// PgDown = reorganize item down in inventory screen

remstart
if  GetRawKeyState(KEY_SPACE) = 1 //Space(jump)
initJump(grav decrease for while, jump_time)
endif

if GetRawKeyState(KEY_Alt = 1 //C(crouch)
crouchPlayer = 1
endif
remend

if GetRawKeyState(KEY_CONTROL) = 1 or GetRawMouseLeftState()  //Ctrl/LMB
//CreateProjectile(PlayerObjectID)
// CreateProjectile(gunendID) // shoot from gunend

//if item=weapon
// launchProjectile
//else
// useCurrentItem
//endif
endif


if GetRawKeyPressed (KEY_BACKSLASH) //KEY_BACKSLASH = swap player..
localPlayer=localPlayer+1

if localPlayer=4
localPlayer=1
// works but cam coords and angles need to be stored at players so that can pick back up correct orientation,
// not of last player..(to do)
swapped_player=1
endif
endif

if GetRawKeyState(KEY_L) = 1 and timer()>delayperiod# // L= toggle streetlight on/off.
lightMode=1-lightMode
if GetPointLightExists( 30 ) =0 and lightMode=0
// CreatePointLight(6, GetObjectX(targetID),GetObjectY(targetID), GetObjectZ(targetID),5,1255,1255,1255)
// CreatePointLight(1, GetObjectWorldX(targetID),GetObjectWorldY(targetID), GetObjectWorldZ(targetID),5,1255,1255,1255)
CreatePointLight(30 , 0,480,0, 5000, 1255, 1255, 1255)
SetPointLightMode(30,1)
SetPointLightPosition(30,0,480,0)
delayperiod#=Timer()+1
elseif GetPointLightExists( 30 ) =1 and lightMode=1
DeletePointLight(30)
endif
endif

If GetRawKeyState(KEY_T) = 1 // T= toggle totch on/off.
torchOn=1-torchOn
delayperiod#=Timer()+1000000
For delay#=0 to delayperiod#
Next delay# // make sure doesn't  get  pressed right after again.
Endif

If GetRawKeyState(KEY_F) = 1 // F= toggle focus (lock mouse to screen).
mouseLocked=1-mouseLocked
SetRawMouseVisible (mouseLocked)
delayperiod#=Timer()+1000000
For delay#=0 to delayperiod#
Next delay# // make sure doesn't  get  pressed right after again.
Endif


If  GetRawKeyState(KEY_F1) = 1 // F1= help
helpdisplay=1-helpdisplay
delayperiod#=Timer()+1000000
For delay#=0 to delayperiod#
Next delay# // make sure doesn't  get  pressed right after again.
EndIf

If  GetRawKeyState(KEY_F2) = 1  // F2= info
infodisplay=1-infodisplay
delayperiod#=Timer()+1000000
For delay#=0 to delayperiod#
Next delay# // make sure doesn't  get  pressed right after again.
EndIf

If  GetRawKeyPressed(KEY_F3) = 1  // F3= toggle (1st/3rd person)

cammode=cammode+1

if cammode=1 // 1st person mode..

endif

if cammode=2  // detached cam mode..
MoveCameraLocalZ(1,-10) // move cam to new position behind the player.
MoveCameraLocalY(1,3) // move cam to new position behind the player.
endif

if cammode=3
cammode=0
flymode=1 //flymode on
endif

if cammode=4 // reset to default 3rd person mode
cammode=0
flymode=0  //flymode off
endif

//delayperiod#=Timer()+5000000
//For delay#=0 to delayperiod#
//Next delay# // make sure doesn't  get  pressed right after again.

EndIf





If  GetRawKeyState(KEY_F4) = 1 // F4 = toggle fly/walk mode
flymode=1-flymode
delayperiod#=Timer()+1000000
For delay#=0 to delayperiod#
Next delay# // make sure doesn't  get  pressed right after again.
EndIf

If  GetRawKeyState(KEY_F7) = 1 // F7 = toggle sun on/off
//sunMode=1-sunMode
delayperiod#=Timer()+1000000
For delay#=0 to delayperiod#
Next delay# // make sure doesn't  get  pressed right after again.
UpdateWorld()
EndIf

If  GetRawKeyState(KEY_F8) = 1 // F8 =  day/night mode
nightMode=1-nightMode
If nightMode=1
lightMode=1
CreatePointLight(30 , 0,5,0, 400, 1255, 1255, 1255)
SetPointLightMode(30,1)
SetPointLightPosition(30,0,5*40,0)


else
lightMode=0
DeletePointLight(30)
endif

delayperiod#=Timer()+1000000
For delay#=0 to delayperiod#
Next delay# // make sure doesn't  get  pressed right after again.
UpdateWorld()
EndIf

//CreatePointLight(30 , 0,5*40,0,  400, 1255, 1255, 1255)
//SetPointLightMode(30,1)
//SetPointLightPosition(30,0,5*40,0)



remstart
If GetRawKeyState(KEY_I) = 1 then inventoryMode=1-inventoryMode //toggle inventory/zoom
If Tab/MMBwheel and inventoryMode=True then select weapon/item+ or - 
If Tab/MMBwheel and inventoryMode=False then zoom+ or -

If Enter/MMB and mulitPlayer then chat=1-chat
If M(map) then mapDisplay=1-mapDisplay


If P/Pause then pauseGame=1-pauseGame
If F1(help) then helpDisplay=1-helpDisplay

If F4(fog)
If F5
If F5 then audioOn=1-audioOn

If F6
gfxMode=gfxMode+1
if gfxMode=gfxMax
gfxMode=gfxModeMin(PC only)
endif
endif
endif
remend

If GetRawKeyPressed(KEY_ESC) then endgame=1 // Esc = exit(windows only)

EndFunction

Function CreateTexture(sizex# as float, sizey# as float, color, density as integer)
 
// Function to create a texture
//
// Inputs - Sizex - size of the texture to create - width
//          Sizey - size of the texture to create - height
//          Color - is the main color of the image
//          Denisity - is a the depth of the texture - the lower the value, the more detail. higher value = no detail
//
// Returns the image for the resulting texture
//
// EG. CreateTexture ( 100, 100,  makecolor(0,0,255), 100)
//          This could create a DEEP water effect texture?

Local memblockid as integer
Local imgwidth as integer
Local imgheight as integer
Local size as integer
Local offset as integer
Local r as integer, g as integer, b as integer, a as integer
Local strength as integer
Local img as integer

//SetPrintColor( 225,255,255)
SetPrintSize(60)
Print("")
Print("")
Print("")
Print("")
Print ("                           Please wait, creating textures: " + Str( progresscount) )

sync()

swap()
drawbox(0,0,sizex#, sizey#, color, color,color,color, 1)
render()
img = getimage(0,0,sizex#, sizey#)
 
memblockid = CreateMemblockFromImage (img)
imgwidth = GetMemblockInt(memblockid, 0)
imgheight = GetMemblockInt(memblockid, 4)
 
 
size=GetMemblockSize(memblockid)
 
for offset=12 to size-4 step 4

r=GetMemblockByte(memblockid, offset)
g=GetMemblockByte(memblockid, offset+1)
b=GetMemblockByte(memblockid, offset+2)
a=GetMemblockByte(memblockid, offset+3)
 
 
strength=random(1,density)
 
SetMemblockByte (memblockid, offset, r-strength)
SetMemblockByte (memblockid, offset+1, g-strength)
SetMemblockByte (memblockid, offset+2, b-strength )
SetMemblockByte (memblockid, offset+3, a-strength)

next
 
deleteimage (img)
 
img = CreateImageFromMemblock(memblockid)
DeleteMemblock(memblockid)
 



EndFunction img

foldend

foldstart // ------------------- display text ---------------------------------------.

Function DisplayInfo()
Local camdis$ as string



SetPrintColor( 225,255,255)
SetPrintSize(30)

If infodisplay
// print info on screen..

Print ("FPS: " + str(  ScreenFPS() ))
Print ("FrameTime: " + str(  GetFrameTime() ))
Print ("Seconds: " + str( GetSeconds() ))
Print ("Polygons: " + str(   GetPolygonsDrawn ()  ))
Print ("")
// Print ("Player  X:  " + Str(GetObjectX(Player)) + "   , Player  Y:  " + Str(GetObjectY(Player)) +"   ,   Player  Z:  " + Str(GetObjectZ(Player)))
Print ("Player  X:  " + Str(PlayerX#) + "   , Player  Y:  " + Str(PlayerY#) +"   ,   Player  Z:  " + Str(PlayerZ#))
Print ("CameraX:  " + Str(GetCameraX(1)) + " , CameraY:  " + Str(GetCameraY(1)) +" ,  CameraZ:  " + Str(GetCameraZ(1)))
Print("CameraAngleX: "+ str(CameraAngleX#)+"   CameraAngleY: "+ str(CameraAngleY#) )  // +"CameraAngleZ: "+ str(CameraAngleZ#))
Print("--------------------------------------------")
Print("CameraDistance#: "+ str(CameraDistance#))
Print("NewCameraDistance#: "+ str(NewCameraDistance#))
Print("UserCameraDistance#: "+ str(UserCameraDistance#)) 
Print("RayObjectID#: "+ str(RayObjectID))
Print("--------------------------------------------")
Print("")
if cammode=0 then camdis$="3rd person(default)"
if cammode=1 then camdis$="1st person"
if cammode=2 then camdis$="detached"
Print("Cammode: "+ camdis$)
Print("")
Print("flymode: "+ str(flymode))
Print("nightmode: "+ str(nightMode))
Print("timer: " + str(timer()) )
Print("EleWait#: " +str(EleWait#))
remstart
Print("shotdelay: " + str(shotdelay#))

Print("bulletcount: " + str(bulletcount) + "        ammountofammo: " + str(ammountofammo))
Print("hitobjectatx: " + str(hitobjectatx))
Print("hitobjectaty: " + str(hitobjectaty))
Print("hitobjectatz: " + str(hitobjectatz))
//for n = 0 to 100
//print ("bulletLight[]= " + str(bulletLight[n] ) +"  " )
//next
remend
print("")
if object_hit=ladderhitbox or object_hit=ladderhitbox2
dis$="hit"
endif
Print("ladder hit: " + dis$ +" = " + str(ladderhitbox) )
Print ("object_hit: "+str(object_hit) )
Print("GetObjectRayCastNumHits: "+ str(GetObjectRayCastNumHits()) )
Print("maxjump: " + str(maxjump#))
Print("")
//Print("pad= "+str(pad))
Print("GetObjectY(Elevator1): " + str(GetObjectY(Elevator1)))
//Print ("bullx#: "+str(bullx#) + " bully#: " + str(bully#) + " bullz#"+str(bullz#) )
//Print ("BulletLight[bulletcount]= "+str(BulletLight[1])) //100224
//Print ("targetIDx: "+Str(GetObjectX(targetID))+", targetIDy: "+str(GetObjectY(targetID))+", targetIDz: "+Str(GetObjectZ(targetID)))
Print("")

Print ("F1 = Help")

EndIf

EndFunction

Function DisplayHelp()
If helpdisplay
// print info on screen..
Print ("F2 = toggle tech info")
Print ("F3 = toggle 1st/3rd person mode")
Print ("F4 = toggle fly/walk mode")
Print ("F5 = toggle audio on/off")
Print ("F6 = toggle fog on/off")
Print ("F7 = toggle sun on/off")
Print ("F8 = toggle day/night")
Print("")
Print ("W, A, S, D, RMB, cursor keys = move")
Print ("Q, E =  strafe")
Print ("Mouse to look round")
Print ("Mousewheel = zoom in/out")
Print ("Shift  + move = run")
Print ("Space =  jump, (+ forward = climb/fly-when in flymode)")
Print ("-Not implemented yet/fully-")
Print ("Alt = crouch")
Print ("Ctrl / LMB = fire/use item")
Print ("Tab / i = cycle inventory items")
Print ("T =  torch, M = map, C = compass ")
Print ("")
Print ("F = toggle Mouse lock")
Print ("Esc = exit, P = pause" )

EndIf


EndFunction

foldend

_______________________________________
B3D + physics + shaders + X-platform = AGK!
:D ..ALIENBREED *LIVES* (thanks to Qube).. :D
_______________________________________

Rick Nasher

#2
V6.0 - Introduced campivot, cam fine. campivot running away:

// Project: Universal 1st/3rd person framework.
// Created: 2018-02-04


WindowAndDisplaySetup()
AssignKeys()

foldstart // ------------------- Initialization variables  ----------------------------.
#option_explicit

#constant version#=6.0
#constant physscale=40
#constant texturized=0  // toggle procedural generated textures or plain colors(faster)
Global progresscount=0


// camera & player controller..
#constant MaxCameraDistance#= 280/2  // needs work..
Global MinCameraDistance#
MinCameraDistance# = 140

Global NewCameraDistance#
NewCameraDistance#=MaxCameraDistance#
Global UserCameraDistance#
UserCameraDistance#=MaxCameraDistance#
Global CameraDistance#

Global CameraAngleX#,CameraAngleY#
Global GetPointerMoveX#, GetPointerMoveY#
Global RayObjectID


Global adjustfactorX#=0
Global adjustfactorZ#=0
Global FrameTime#
Global PointerX#, PointerY#, PointerZ#
Global cam_up=0

Global mouselocked=0
Global cammode=0
Global endgame=0
Global infodisplay=1
Global helpdisplay=0
Global nightMode=0
Global lightMode=0
Global torchOn=0
Global fog=0

Global gravity#=  20 //60 // if set lower than the ricochet of bullet collisions can set player up into the sky like a rocket booster.
   //  -10.0 meters per second on the Y axis will give the correct visual result.

// player..
Global playerheight#=  72 // 1.8*physscale
Global playerwidth# =  40 // 1 *physscale
Global hspeed#= 80  // 2    * 40
Global vspeed#= 20  // 0.5 * 40
Global speed#= 1 // 40   // 1   * 40
Global jump=0
Global upy#=0
Global maxjump#  //5
maxjump#=  200 //120 //  gravity# *3
Global jumpwait#=0
Global falling=0
Global climbing=0
Global hitobjectatx, hitobjectaty, hitobjectatz,object_hit, object_hit_ammount

Global flymode=0

// objects..
Global planeID

// player(s)..
Global PlayerObjectID,rightarmID, leftarmID, gunID, gunendID,targetID, unaBrow, nose, tail, SourceID
Global targetIDx#, targetIDy#, targetIDz#

Global PlayerX#,PlayerY#,PlayerZ#
Global oldPlayerX#,oldPlayerY#,oldPlayerZ#
Global newPlayerX#,newPlayerY#,newPlayerZ#
Global newestPlayerX#, newestPlayerY#, newestPlayerZ#
Global swapped_player

// building..
//Global floor3A

// elevator..
Global ElevatorY#=1
ElevatorY#=ElevatorY#*physscale
Global ElevatorVector#=.1
ElevatorVector#=ElevatorVector#*physscale
ElevatorVector#=4
Global Elevator1
Global EleTimerSet=0
Global EleWait#=0
Global FirstFloorDone=0
Global SecFloorDone=0
Global ThrdFloorDone=0
Global TopFloor=0
Global ElevatorDoorLeft0
Global ElevatorDoorRight0
Global ElevatorDoorLeft1
Global ElevatorDoorRight1

// ladder & jumppad..
Global ladderhitbox
Global ladderhitbox2
Global pad

//remstart
// needs sorting(due to opt explic)...
Global img, delayperiod#, delay#, steeltexture, rooflighttexture
Global elevatortop, elevatorlight, elevatorwallleft, elevatorwallfront, elevatorpostleft, elevatorpostright, elevatorroof
Global wr, wg, wb, wt, wr#,wg#, wb#,wt#, lx#, ly#, lz#
Global l1, l2, l3, l4, l5, l22, leftlightpodbulb, rightlightpodbulb, blucone, redcone
Global ladderBulbBtmCap1 ,ladderBulbBtmHng1, ladderBulb1  // ladderbulpbtmcap1
Global ladderBulbTopCap2, ladderBulbBtmHng2, ladderBulb2 , ladderBulb3
Global ladderLightC, ladderLight2C, ladderLight3C
Global ladderBulb2BtmCap1, ladderBulb2BtmHng1
Global ladderBulb2TopCap2, ladderBulb2BtmHng2
Global ladderBulb3BtmCap1, ladderBulb3BtmHng1
Global ladderBulb3TopCap2, ladderBulb3BtmHng2

// text..
Global dis$ as string

//remend
foldend

CreateWorld() // ------------ Setup Environment --------------------------------.

foldstart // ------------------- Create Players  ------------------------------------.
type MeshIDs
body_mID as integer
unaBrow_mID as  integer
nose_mID as integer
tail_mID as integer

footLeft_mID as integer
footRight_mID as integer
leftArm_mID as integer
rightArm_mID as integer

gun_mID as integer
gunsight_mID as integer
gunend_mID as integer
target_mID as integer

campivot_mID as integer
endtype
 
type CharacterType
// vars
name as string      // character's  name
species as string  //  human, enemy, extra,  monster, bot
energy as float

// physical..
width as float     // mesh width
height as float    // mesh height
weight as float   // for use with physics

// coords & angles....
x as float
y as float
z as float
anglex as float
angley as float
anglez as float

oldx as float
oldy as float
oldz as float
oldanglex as float
oldangley as float
oldanglez as float

// meshes..        
mesh as MeshIDs
endtype

Global player as CharacterType[5] // Setup an array of 5 players as type Character

// create players..  using :  createPlayer( plr ref as Character, n$, spc$, nrg#, wdt#, hgt#, wgt#, ix#, iy#, iz#, iax#, iay#, iaz#)

Global localPlayer as integer // used for switching players..
localPlayer=1 // start of as player1
createPlayer( player[localPlayer], "Player1", "human",100, playerwidth#, playerheight#, 80, 0,0,0, 0,0,0  )
SetObjectPosition( player[1].mesh.body_mID, 0,playerheight#/2,-10*physscale)
Global plrtexture  as integer
//If texturized=1
plrtexture =CreateTexture(250,24, makecolor(155,155,205) ,27)
SetObjectImage( player[1].mesh.body_mID, plrtexture, 0 )
//endif

createPlayer( player[2], "Player2", "human",100,1.8,1,80,0,0,0, 0,0,0  )
SetObjectColor( player[2].mesh.body_mID,200,50,55,255)
SetObjectPosition( player[2].mesh.body_mID, -300,playerheight#/2,0)

createPlayer( player[3], "Player3", "human",100,1.8,1,80,0,0,0, 0,0,0  )
SetObjectColor( player[3].mesh.body_mID,50,50,200,255)
SetObjectPosition( player[3].mesh.body_mID, -500,playerheight#/2,0)

foldend


do // -------------------------- Main loop ------------------------------------------.

FrameTime#=GetFrameTime()

//UpdateElevator()
//UpdateLights()

UpdatePlayer(localPlayer)
//UpdateProjectile()

CheckAdditionalKeys()

DisplayInfo()
DisplayHelp()

If  endgame=1 then exit
sync()

loop
ClearPointLights()
End // exit  game..

// ----------------------------- Functions ------------------------------------------.

foldstart // ------------------- setup and update world --------------------------.

Function WindowAndDisplaySetup()
// ------------not really needed for this example -------
// set window properties
SetWindowTitle("Test V"+str(version#,1) )

// set display properties
SetWindowSize(1920,1080,0)
SetWindowAllowResize(1) // allow the user to resize the window

SetVirtualResolution(1920,1080) // doesn't have to match the window
//setvirtualresolution(1024,600)
SetOrientationAllowed(1,1,1,1) // allow both portrait and landscape on mobile devices
SetSyncRate(30,0) // 30fps instead of 60 to save battery
SetScissor(0,0,0,0) // use the maximum available screen space, no black borders
UseNewDefaultFonts(1) // since version 2.0.22 we can use nicer default fonts
SetPrintSize( 20 )
SetPrintColor( 00, 00, 00,255 )

SetClearColor(1,128,198)
SetGlobal3DDepth(10000) // Sets the position of all 3D objects relative to 2D objects.

SetResolutionMode(1)
SetAntialiasMode(1)
SetImmersiveMode(1)
SetRawMouseVisible(0)
SetCameraRange(1,1,1000 *physscale)
SetAmbientColor(128,128,128)
SetGenerateMipmaps(1)
// -----------------------------------------------------------
fog=1
// add some atmospheric fog
SetFogMode( fog )
SetFogColor( 161,183,209 )
SetFogRange( 50*physscale, 700*physscale )
//SetFogRange( 60,95 )
SetFogSunColor( 255,230,179 )

// -----------------------------------------------------------
SetShadowMappingMode(3)
SetShadowSmoothing(1) // random sampling
SetShadowMapSize(2048,2024)
EndFunction

Function CreateWorld()


// create a plane for things to stand on, turn its collision off, rotate it and position it under the middle box to act as a ground
// this is purely coismetic
planeID=CreateObjectPlane(40000,40000)
SetObjectCollisionMode(planeID,0) // this is to stop it interfering with the collision with the map
// ensure everything is at correct starting point an orientation at creation.
SetObjectPosition(planeID,0,0,0) : SetObjectRotation(planeID,0,0,0)
// put where we want it..
SetObjectRotation(planeID,90,0,0) // put it flat
SetObjectPosition(planeID,0,0,0) //realign with origin
If texturized=1
planetexture as integer
planetexture = CreateTexture(512,512, makecolor(50,200,100) ,20) //
progresscount=progresscount+1

SetObjectImage(planeID,planetexture,0)
Else
SetObjectColor(planeID,50,200,100,255) // color it lawn style
Endif



// mark the center of our world(0,0,0). with a streetlight..
Global centerpoleID // center mark
centerpoleID=CreateObjectCylinder(240,8,480)
SetObjectPosition(centerpoleID,0,120,0) :  SetObjectRotation(centerpoleID,0,0,0) // ensure is at correct starting point.
If texturized=1
//poletexture = CreateTexture(512,512, makecolor(10,10,10) ,20) //
// poletexture = CreateTexture(20,255, makecolor(50,255,255) ,50)
Global poletexture
poletexture = CreateTexture(20,255, makecolor(186, 196, 200) ,50)
progresscount=progresscount+1
SetObjectImage(centerpoleID,poletexture,0)
Else
SetObjectColor( centerpoleID ,0,0,0,255)
Endif
SetObjectCastShadow(centerpoleID,1)

Lightbulb as integer
Lightbulb=CreateObjectCapsule(40,80,1280)
SetObjectPosition(Lightbulb,0,6*physscale,0)
SetObjectColor(Lightbulb, 255,255,255,225)
SetObjectTransparency(Lightbulb,1)
SetObjectColorEmissive(Lightbulb,1255,1255,1255)

Lightcap as integer
Lightcap= CreateObjectCone(20,80,1280)
SetObjectPosition(Lightcap,0,280,0)
If texturized=1
Global poletexture2
//poletexture2 = CreateTexture(20,20, makecolor(50,255,255) ,50)
poletexture2 = CreateTexture(20,20, makecolor(186, 196, 200) ,50)
progresscount=progresscount+1
SetObjectImage(Lightcap,poletexture2,0)
Else
SetObjectColor(Lightcap, 55,55,55,255)
Endif
SetObjectCastShadow(centerpoleID,1)


// Create some random static scenery objects to test with..
Global Dim obstacle[20]
Global Dim textureobstacle[20]
Local i as integer, r as integer

For i=2 To 20
r=Random(1,4)
if r=1
obstacle[i]=CreateObjectBox( random(1,800), random(1,800) , random(1,800) )
SetObjectPosition(obstacle[i],0,0,0) :  SetObjectRotation(obstacle[i],0,0,0) // ensure is at correct starting point.
SetObjectPosition(  obstacle[i], Random(-3000, 3000),0,Random(-3000,1000))
SetObjectRotation (obstacle[i],0.0,Random(0,360),0.0)
elseif r=2
obstacle[i]=CreateObjectCone(random(1,800),random(1000,2000),random(1,1200))
SetObjectPosition(obstacle[i],0,0,0) :  SetObjectRotation(obstacle[i],0,0,0) // ensure is at correct starting point.
//SetObjectPosition(  obstacle[i], Random(-2000,2000),0,Random(-2000,2000))
SetObjectPosition(  obstacle[i], Random(-3000, 3000),0,Random(-3000,1000))
SetObjectRotation (obstacle[i],0.0,Random(0,360),0.0)
elseif r=3
obstacle[i]=CreateObjectCylinder(random(1,280),random(1,600),random(1,1200))
SetObjectPosition(obstacle[i],0,0,0) :  SetObjectRotation(obstacle[i],0,0,0) // ensure is at correct starting point.
//SetObjectPosition( obstacle[i], Random(-2000,2000),0,Random(-2000,2000))

   // SetObjectPosition(  obstacle[i], Random(-3000, 3000),0,Random(-3000,1000))
while GetObjectX(  obstacle[i] ) = 0 or GetObjectX(  obstacle[i] ) < -500  or GetObjectX(  obstacle[i] ) < 500 or GetObjectZ( obstacle[i] ) = 0  or (GetObjectZ( obstacle[i] ) > -500   and GetObjectZ(  obstacle[i] ) < 500)
SetObjectPosition(  obstacle[i], Random(-3000, 3000),0,Random(-3000,1000))
endwhile

SetObjectRotation (obstacle[i],Random(0,360),Random(0,360),0.0)
//SetObjectScale (obstacle[i],-Random(.2,1),-Random(.2,1),-Random(.2,1))

else
//( diameter, rows, columns )
diameter# as float, rows# as float, colums# as float

diameter#= random(20,1000)
rows#=random(.1,25)
colums#=random(5,32)
obstacle[i]=CreateObjectsphere(diameter#,rows# ,colums# )
SetObjectPosition(obstacle[i],0,0,0) :  SetObjectRotation(obstacle[i],0,0,0) // ensure is at correct starting point.
//SetObjectPosition(  obstacle[i], Random(-2000,2000),-diameter#/5+random(0,40),Random(-2000,2000))
SetObjectPosition(  obstacle[i], Random(-3000,3000),-diameter#/5+random(0,40),Random(-3000,1000))
// SetObjectScale (obstacle[i],Random(.2,1),Random(.2,1),Random(.2,1))
SetObjectRotation (obstacle[i],0.0,Random(0,360),0.0)
endif

//SetObjectScale (obstacle[i],Random(.2,2),Random(.2,2),Random(.2,2))
SetObjectRotation (obstacle[i],0.0,Random(0,360),0.0)

If texturized=1
textureobstacle[i] = CreateTexture ( Random(0,1024), Random(0,1024), makecolor( Random(0,255), Random(0,255), Random(0,255) ) ,  Random(1,100) )
progresscount=progresscount+1
SetObjectImage(obstacle[i],textureobstacle[i],0)
Else
SetObjectColor (obstacle[i],Random(0,255),Random(0,255),Random(0,255),Random(0,255))
Endif

SetObjectCollisionMode(obstacle[i],1)
SetObjectCastShadow(obstacle[i],1)
Next

//  create jumping pad(s)
padsupport as integer
padsupport=CreateObjectBox(  160, 80 , 160 )
SetObjectPosition(padsupport,0,0,0) :  SetObjectRotation(padsupport,0,0,0) // ensure is at correct starting point.
SetObjectPosition(  padsupport, -200 ,0 ,  2000 )
SetObjectColor (padsupport,55,55,55,255)
SetObjectCastShadow(padsupport,1)

//pad as integer
pad=CreateObjectsphere(2,120 ,120 )
SetObjectScale(pad, 60 , 10, 60 ) 
SetObjectPosition(pad,0,0,0) :  SetObjectRotation(pad,0,0,0) // ensure is at correct starting point.
SetObjectPosition(  pad, -200, 40, 2000)
SetObjectColor (pad,155,100,155,255)

//CreateLights()


EndFunction

Function Updateworld()

If nightMode
SetAmbientColor(12,12,12)
SetClearColor(12,12,12)

Else
SetAmbientColor(128,128,128)
SetClearColor(1,128,198)
EndIf

EndFunction

foldend

foldstart // .------------------- setup and update players -----------------------.

function createPlayer( plr ref as CharacterType, n$, spc$, nrg#, wdt#, hgt#, wgt#, ix#, iy#, iz#, iax#, iay#, iaz#)
// setup player properities..
plr.name = n$
plr.species= spc$
plr.energy = nrg#
plr.width = wdt#
plr.height = hgt#
plr.weight = wgt#

plr.x = ix#
plr.y = iy#
plr.z = iz#
plr.anglex = iax#
plr.angley = iay#
plr.anglez = iaz#

addMeshesToPlayer( plr )   // add meshes that make up this character
endfunction

function addMeshesToPlayer( plr ref as CharacterType )
// add meshes that make up the character..

plr.mesh.body_mID = CreateObjectCapsule(playerwidth#,playerheight#,1) // ( diameter, height, axis )
SetObjectPosition(plr.mesh.body_mID, 0, playerheight#/2, -400)  // 0,1*playerheight#/2,-10*physscale)
SetObjectCastShadow(plr.mesh.body_mID,1)
SetObjectCollisionMode(plr.mesh.body_mID, 0)  //prevent self hiting


// add some detail so orientation of player is more clear..
plr.mesh.unaBrow_mID = CreateObjectCone(.4*physscale,.8*physscale,12):SetObjectColor( plr.mesh.unaBrow_mID ,0,0,0,255)
SetObjectPosition(plr.mesh.unaBrow_mID,0,0,0) :  SetObjectRotation(plr.mesh.unaBrow_mID,0,0,0) // ensure is at correct starting point.
SetObjectPosition( plr.mesh.unaBrow_mID ,0,.4*physscale,.3*physscale)
SetObjectRotation( plr.mesh.unaBrow_mID ,-180,0,0)
SetObjectCastShadow(plr.mesh.unaBrow_mID,1)
SetObjectCollisionMode(plr.mesh.unaBrow_mID,0)  //prevent self hiting
FixObjectToObject(plr.mesh.unaBrow_mID,plr.mesh.body_mID)

plr.mesh.nose_mID = CreateObjectSphere(.2*physscale,1.2,12):SetObjectColor( plr.mesh.nose_mID,255,0,0,255) // //250,150,155,255=pink
SetObjectPosition(plr.mesh.nose_mID,0,0,0) :  SetObjectRotation(plr.mesh.nose_mID,0,0,0) // ensure is at correct starting point.
SetObjectPosition( plr.mesh.nose_mID,0,.2*physscale,.5*physscale)
SetObjectCastShadow(plr.mesh.nose_mID,1)
SetObjectCollisionMode(plr.mesh.nose_mID,0)  //prevent self hiting
FixObjectToObject(plr.mesh.nose_mID,plr.mesh.body_mID)

plr.mesh.tail_mID = CreateObjectcone(.2*physscale,.3*physscale,12):SetObjectColor( plr.mesh.tail_mID ,255,255,255,255)
SetObjectPosition(plr.mesh.tail_mID ,0,0,0) :  SetObjectRotation(plr.mesh.tail_mID ,0,0,0) // ensure is at correct starting point.
//SetObjectPosition( tail,0,-.9*physscale,-.4*physscale)
SetObjectPosition( plr.mesh.tail_mID ,0,-.81*physscale,-.4*physscale)
SetObjectRotation(plr.mesh.tail_mID ,-130,0,0)
SetObjectCastShadow(plr.mesh.tail_mID ,1)
SetObjectCollisionMode(plr.mesh.tail_mID ,0)  //prevent self hiting
FixObjectToObject(plr.mesh.tail_mID ,plr.mesh.body_mID)


plr.mesh.footLeft_mID = CreateObjectcone(.2*physscale,.3*physscale,12):SetObjectColor( plr.mesh.footLeft_mID,255,0,0,255)
SetObjectPosition(plr.mesh.footLeft_mID,0,0,0) :  SetObjectRotation(plr.mesh.footLeft_mID,0,0,0) // ensure is at correct starting point.
SetObjectPosition( plr.mesh.footLeft_mID,-.2*physscale,-.77*physscale,.25*physscale)
SetObjectRotation(plr.mesh.footLeft_mID,0,0,0)
SetObjectCastShadow(plr.mesh.footLeft_mID,1)
SetObjectCollisionMode(plr.mesh.footLeft_mID,0)  //prevent self hiting
FixObjectToObject(plr.mesh.footLeft_mID,plr.mesh.body_mID)


plr.mesh.footRight_mID = CreateObjectcone(.2*physscale,.3*physscale,12):SetObjectColor( plr.mesh.footRight_mID,255,0,0,255)
SetObjectPosition(plr.mesh.footRight_mID,0,0,0) :  SetObjectRotation(plr.mesh.footRight_mID,0,0,0) // ensure is at correct starting point.
SetObjectPosition( plr.mesh.footRight_mID,.2*physscale,-.77*physscale,.25*physscale)
SetObjectRotation(plr.mesh.footRight_mID,0,0,0)
SetObjectCastShadow(plr.mesh.footRight_mID,1)
SetObjectCollisionMode(plr.mesh.footRight_mID,0)  //prevent self hiting
FixObjectToObject(plr.mesh.footRight_mID,plr.mesh.body_mID)

// add left arm..
plr.mesh.leftArm_mID = CreateObjectSphere(.6*physscale,10,10) //diameter, rows, columns )
SetObjectScale(plr.mesh.leftArm_mID,.7,1.4,1)
SetObjectColor( plr.mesh.leftArm_mID,150,150,255,255)
SetObjectPosition(plr.mesh.leftArm_mID,0,0,0) :  SetObjectRotation(plr.mesh.leftArm_mID,0,0,0) // ensure is at correct starting point.
SetObjectPosition(plr.mesh.leftArm_mID,-.4*physscale,-.1*physscale,.1*physscale)
SetObjectRotation(plr.mesh.leftArm_mID,0,0,00)
FixObjectToObject(plr.mesh.leftArm_mID, plr.mesh.body_mID)
SetObjectCollisionMode(plr.mesh.leftArm_mID,0)  //prevent self hiting
SetObjectCastShadow(plr.mesh.leftArm_mID,1)

// add right arm..
plr.mesh.rightArm_mID = CreateObjectSphere(.6*physscale,10,10) //diameter, rows, columns )
SetObjectColor( plr.mesh.rightArm_mID,150,150,255,255)
SetObjectPosition(plr.mesh.rightArm_mID,0,0,0) :  SetObjectRotation(plr.mesh.rightArm_mID,0,0,0) // ensure is at correct starting point.
SetObjectPosition(plr.mesh.rightArm_mID,.4*physscale,0,.1*physscale)
SetObjectRotation(plr.mesh.rightArm_mID,0,0,0)
FixObjectToObject(plr.mesh.rightArm_mID,plr.mesh.body_mID )
SetObjectCollisionMode(plr.mesh.rightArm_mID,0)  //prevent self hiting
SetObjectCastShadow(plr.mesh.rightArm_mID,1)

// add gun..
plr.mesh.gun_mID = CreateObjectCylinder(1.1*physscale,.2*physscale,10) //height, diameter, segments )
SetObjectPosition(plr.mesh.gun_mID,0,0,0) :  SetObjectRotation(plr.mesh.gun_mID,0,0,0) // ensure is
SetObjectPosition(plr.mesh.gun_mID,0,0,0) :  SetObjectRotation(plr.mesh.gun_mID,0,0,0) // ensure is at correct starting point.
SetObjectRotation(plr.mesh.gun_mID,90,7,0) // rotate the cylinder from vertical to horizontal position(infliuences also the coords syst; x=y
SetObjectPosition(plr.mesh.gun_mID,0.2*physscale,0.15*physscale,0.4*physscale)
FixObjectToObject(plr.mesh.gun_mID,plr.mesh.rightArm_mID)
SetObjectColor(plr.mesh.gun_mID,0,0,0,255) //
SetObjectCollisionMode(plr.mesh.gun_mID,0)  //prevent self hiting
SetObjectCastShadow(plr.mesh.gun_mID,1)


//create  marker for sight at end of gun and use as pivot for releasing bullets.
plr.mesh.gunsight_mID= CreateObjectCone(.1*physscale,0.14*physscale,1*physscale) //height, diameter, segments
SetObjectPosition(plr.mesh.gunsight_mID,0,0,0) :  SetObjectRotation(plr.mesh.gunsight_mID,0,0,0) // ensure is at correct starting point.
SetObjectRotation(plr.mesh.gunsight_mID,90,180,0)
SetObjectPosition (plr.mesh.gunsight_mID,0,.5*physscale,-0.1*physscale)
FixObjectToObject(plr.mesh.gunsight_mID, plr.mesh.gun_mID )
SetObjectColor(plr.mesh.gunsight_mID,50,50,55,255) //
SetObjectCollisionMode(plr.mesh.gunsight_mID,0)  //prevent self hiting
SetObjectCastShadow(plr.mesh.gunsight_mID,1)

//create  pivot for releasing bullets.
plr.mesh.gunend_mID= CreateObjectSphere(.3*physscale,16,16) //height, diameter, segments
SetObjectPosition(plr.mesh.gunend_mID,0,0,0) :  SetObjectRotation(plr.mesh.gunend_mID,0,0,0) // ensure is at correct starting point.
SetObjectRotation(plr.mesh.gunend_mID,-90,0,0)
SetObjectPosition(plr.mesh.gunend_mID,-0.01*physscale,0.5*physscale,-0.01*physscale)
FixObjectToObject(plr.mesh.gunend_mID,plr.mesh.gun_mID)
SetObjectColor(plr.mesh.gunend_mID,255,255,0,55) //
SetObjectCollisionMode(plr.mesh.gunend_mID,0)  //prevent self hiting
SetObjectTransparency(plr.mesh.gunend_mID,1)
//SetObjectVisible(plr.mesh.gunend_mID,0)


//remstart
plr.mesh.target_mID= CreateObjectSphere(.25*physscale,16,16) //height, diameter, segments
//targetID= CreateObjectbox(4,4,1) //height, diameter, segments
SetObjectPosition(plr.mesh.target_mID,0,0,0) :  SetObjectRotation(plr.mesh.target_mID,0,0,0) // ensure is at correct starting point.
SetObjectRotation(plr.mesh.target_mID,-90,0,0)
SetObjectPosition(plr.mesh.target_mID,-0.01*physscale,.65*physscale,0.01*physscale)
FixObjectToObject(plr.mesh.target_mID,plr.mesh.gun_mID)
SetObjectColor(plr.mesh.target_mID,255,0,0,155) //
SetObjectCollisionMode(plr.mesh.target_mID,0)  //prevent self hiting
SetObjectTransparency(plr.mesh.target_mID,1)
MoveObjectLocalZ(plr.mesh.target_mID, 7*physscale)
SetObjectColorEmissive(plr.mesh.target_mID,255,0,0)

//targetTexture=LoadImage( "blue.png" )
//setobjectimage( plr.mesh.target_mID, targetTexture, 1 )
//remend

// cam pivot..
plr.mesh.campivot_mID = CreateObjectBox(.5*physscale,.5*physscale,.5*physscale):SetObjectColor( plr.mesh.campivot_mID  ,255,255,0,105)
SetObjectPosition(plr.mesh.campivot_mID, 0,0,0) :  SetObjectRotation(plr.mesh.campivot_mID ,0,0,0) // ensure is at correct starting point.
//SetObjectPosition(plr.mesh.campivot_mID  ,0, 40 ,-20) //0,1*physscale,-.5*physscale)
SetObjectPosition(plr.mesh.campivot_mID  ,0, 40 , -40)  //-MaxCameraDistance#)  //1 unit above and behind the player.
SetObjectTransparency(plr.mesh.campivot_mID ,1)
SetObjectCollisionMode(plr.mesh.campivot_mID ,0)  //prevent self hiting
FixObjectToObject(plr.mesh.campivot_mID ,plr.mesh.body_mID)
FixObjectPivot(plr.mesh.campivot_mID )

endfunction

Function UpdatePlayer(locPlr as integer)

Local joystick_x# as float
Local joystick_y# as float
Local PointerX# as float
Local PointerY# as float
Local CamPivotX# as float
Local CamPivotY# as float
Local CamPivotZ# as float
Local NewCamPivotX# as float
Local NewCamPivotY# as float
Local NewCamPivotZ# as float

// store players current x,y,z and angles before any movement..
oldPlayerX#=GetObjectX(player[locPlr].mesh.body_mID)
oldPlayerY#=GetObjectY(player[locPlr].mesh.body_mID)
oldPlayerZ#=GetObjectZ(player[locPlr].mesh.body_mID)

// -------------------------- jumping..  ------------------------------------------------------------------
If  GetRawKeyState(KEY_SPACE)  and falling=0  // Space = jump
If  jump=0 and Timer()>jumpwait# //  inair=0 // if not juming/inair  already, so no jumping when falling..
jump=1  // intitiate new jump
jumpwait#=Timer()+.4 // delay should  so player cannot initiate jumping right after for is weird,
Endif
Endif

// excute jump..
if jump=1  // if jump has been initiated 
upy#=upy#+40 //(gravity#*jmultiplier#) // count up till max jump heigth reached.
if  upy#>=maxjump#  // if maxheight reached then  reset y to 0 and no end jump..
upy#=0
jump=0
else // if not reached maximum height yet  then..
MoveObjectLocalY(player[locPlr].mesh.body_mID,40) // the actual jump.
endif
endif

// -------------------------------- if this bit put at camera section, then no smooth movement --------------
// get input from mouse pointer..(to turn player left/right and/or turn cam up/dow)
PointerX#=GetPointerX()
PointerY#=GetPointerY()

If mouseLocked=0
setrawmouseposition(GetVirtualWidth()*0.5,GetVirtualHeight()*0.5) // re-center mouse on screen
EndIf
GetPointerMoveX#=(PointerX#-GetPointerX()) // calculate distance moved
GetPointerMoveY#=(PointerY#-GetPointerY())

// for turning left/right..
If  GetRawKeyState(KEY_LEFT)  OR GetRawKeyState(KEY_A) // Left/A = turn player left
GetPointerMoveX# =  -hspeed#
Endif
If GetRawKeyState(KEY_RIGHT) OR GetRawKeyState(KEY_D) // Right/D = turn player right
GetPointerMoveX# =  hspeed#
Endif

// get current camera angles..
CameraAngleX#=CameraAngleX#+GetPointerMoveY#*FrameTime#
CameraAngleY#=CameraAngleY#+GetPointerMoveX#*FrameTime# // calc camera angle
UserCameraDistance#=UserCameraDistance#-GetRawMouseWheelDelta() *40  // zoom in/out when used mousewheel
if UserCameraDistance#>MaxCameraDistance# then UserCameraDistance#=MaxCameraDistance# //limit max dist from cam
if UserCameraDistance#<MinCameraDistance#  then UserCameraDistance#=MinCameraDistance# // limit minimum dist from cam
// --------------------------------------------------------------------------------------------------------
// For moving forward/backward..

// get player's AGK joystick input.
// On PC WASD are used, on devices without kybd will create a virtual onscreen joystick.
// ( can optionally be positiioned differently on screen using SetJoystickScreenPosition ).
joystick_x# = GetJoyStickX()*hspeed#      // horizontal movement input
joystick_y# = GetJoyStickY()*-vspeed#     // vertical movement input


// get vertical keybpard input (PC only)..
speed#=1 //  set initial speed.
If (GetRawKeyState(KEY_UP) = 1 or GetRawKeyState(KEY_W)  or GetRawMouseRightState() ) AND  GetRawKeyState(KEY_SHIFT) // Up/W/RBM + SHIFT = move player forward(run)
speed#=3 // Shift = speedup.
joystick_y#=1*vspeed#  *speed# //addjust z
ElseIf GetRawKeyState(KEY_UP) = 1 or GetRawKeyState(KEY_W)  or GetRawMouseRightState() // Up/W/RBM = move player forward (walk)
speed#=1 // without Shift = normal speed.
joystick_y#=1*vspeed#  *speed# //addjust z
Else
//
endif
If   GetRawKeyState(KEY_DOWN) or GetRawKeyState(KEY_S)   // Down/S = move player backward
joystick_y#=1*-vspeed# *speed#
Endif


// move player based on the input  of  joystick and  mouse..
RotateObjectLocalY(player[locPlr].mesh.body_mID,joystick_x#) // seems redundant,but somehow makes cam movement more fluid?
MoveObjectLocalZ(player[locPlr].mesh.body_mID,joystick_y#)
SetObjectRotation(player[locPlr].mesh.body_mID,0,CameraAngleY#,0) // set player at  Y angle calculated according to mousemovement, don't move X angle for player will then tilt up/down

// for strafe.. ( if not put here then doesn't work )
If GetRawKeyState(KEY_Q) // Q = move (strafe) player left
joystick_y# = .1*-hspeed#
MoveObjectLocalX(player[locPlr].mesh.body_mID,joystick_y#)
Endif
If GetRawKeyState(KEY_E) // E = move (strafe) player right
joystick_y# = .1*hspeed#
MoveObjectLocalX(player[locPlr].mesh.body_mID,joystick_y#)
Endif

// -------------------------- apply gravity..  --------------------------------------------------------------
if flymode=1
falling=0 // gravity#=0.0
else // always apply gravity, unless fly mode active..
falling=1 //gravity#=0.5 
endif
if jump=0
MoveObjectLocalY(player[locPlr].mesh.body_mID,-gravity#)  ///2) // gravity ""always on'' except when jumping..
endif
// --------------------------------------------------------------------------------------------------------


// ################### manage collision checking for the player with other geometry #############
// after above movements, get players new x,y,z's for usage with collisions..
newPlayerX#=GetObjectX(player[locPlr].mesh.body_mID)
newPlayerY#=GetObjectY(player[locPlr].mesh.body_mID)
newPlayerZ#=GetObjectZ(player[locPlr].mesh.body_mID)

// sphere cast between the old and new positions of the player to see if we hit something while moving to new location..
object_hit = ObjectSphereSlide(0,  oldPlayerX#,  oldPlayerY#,  oldPlayerZ#,  newPlayerX#,  newPlayerY#,  newPlayerZ#,  playerwidth#)

// if the sphere has collided with an object then calculate sphere new position to give sliding collision
If object_hit <> 0 // we've hit something then adjust the x,y,z's ..

newestPlayerX#=GetObjectRayCastSlideX(0)
if newestPlayerX#<>newPlayerX#
//hitobjectatx=1
endif
newestPlayerY#=GetObjectRayCastSlideY(0)
if newestPlayerY#<>newPlayerY#
//hitobjectaty=1
falling=0
endif
newestPlayerZ#=GetObjectRayCastSlideZ(0)
if newestPlayerZ#<>newPlayerZ#
//hitobjectatz=1
endif

if object_hit = ladderhitbox or object_hit = ladderhitbox2 //or object_hit= Stairs
gravity#= -70 //-.5  //1 // reduce/reverse  gravity

elseif object_hit = pad
jump=1
maxjump#=750
gravity#=-30 //1 // cancel out gravity
else // if hit something else..
gravity#= 20 //70 //.5
maxjump#=200 // 5 //*physscale
endif

else // nothing hit ( could also be up in air)
hitobjectatx=0 : hitobjectaty=0 : hitobjectatz=0
//climbing=0
if jump=0
maxjump#=200
gravity#= 20
endif

// nothings hit so original values after move are still valid, no need to  orrect..
newestPlayerX#=newPlayerX#
newestPlayerY#=newPlayerY#
newestPlayerZ#=newPlayerZ#

EndIf

// prevent falling through floor due to gravity update..
If newestPlayerY# <=playerheight#/2 // so if gravity aplied but now ending up below the btm floor.. (could also be checked against terrainy.
newestPlayerY#=playerheight#/2 // limit/reset y to minimm y so don't fall through floor
falling=0
endif

// (re)position player onto new corrected location..
SetObjectPosition(player[locPlr].mesh.body_mID, newestPlayerX#, newestPlayerY#, newestPlayerZ# ) //process all modifications made above.


// **************************************************************************************
// ************************************ CAMERA MOVEMENT **********************************
// **************************************************************************************

// #################### manage camera avoiding geometry inbetween player and cam ################
// get player's current  x,y,z's.. (new position for player moved)
PlayerX#=GetObjectX(player[locPlr].mesh.body_mID )
PlayerY#=GetObjectY(player[locPlr].mesh.body_mID )
PlayerZ#=GetObjectZ(player[locPlr].mesh.body_mID )

// ----------------------------------------------------------------------------------------------------------------
If cammode=0 //  3rd person mode(default)..

// 1st: sync campivot to new player location..
SetObjectPosition(player[locPlr].mesh.campivot_mID,PlayerX#,PlayerY#+40,PlayerZ#) // sync pivot with player pos, but a bit higher(shoulderheight).
SetObjectRotation(player[locPlr].mesh.campivot_mID, GetObjectAngleX(player[locPlr].mesh.body_mID) ,GetObjectAngleY(player[locPlr].mesh.body_mID) ,GetObjectAngleZ(player[locPlr].mesh.body_mID)   ) // sync rotation also.
// store the pivot's positions..
CamPivotX# = GetObjectX(player[locPlr].mesh.campivot_mID )
CamPivotY# = GetObjectY(player[locPlr].mesh.campivot_mID )
CamPivotZ# = GetObjectZ(player[locPlr].mesh.campivot_mID )
// now move pivot behind the player max distance..
MoveObjectLocalZ( player[locPlr].mesh.campivot_mID,  -MaxCameraDistance#)

// get the campivot''s new  location..
NewCamPivotX# = GetObjectX(player[locPlr].mesh.campivot_mID )
NewCamPivotY# = GetObjectY(player[locPlr].mesh.campivot_mID )
NewCamPivotZ# = GetObjectZ(player[locPlr].mesh.campivot_mID )

// cast from old pivot pos to new to see if something in between the old and new positions..
RayObjectID=ObjectRayCast(0,CamPivotX#,CamPivotY#,CamPivotZ#,NewCamPivotX#,NewCamPivotY#,NewCamPivotZ#) // sent a ray from players pos to cam behind player.
if RayObjectID<>0 // if an object was hit, this means there's an object between player and cam, obstructing the view'
NewCameraDistance#=GetObjectRayCastDistance(0) // get distance to where has been hit.
else
NewCameraDistance#=UserCameraDistance# // nothing's hit so just set to user defined zoom distance.
endif

// calculate new pivot distance..
SetObjectPosition(player[locPlr].mesh.campivot_mID, CamPivotX#,CamPivotY#,CamPivotZ#) // 1st set back to original position.
CameraDistance#=CurveValue(NewCameraDistance#, CameraDistance#,10) //  new camdistance in 10 steps..
MoveObjectLocalZ(player[locPlr].mesh.campivot_mID, -CameraDistance#) // move pivot to newly calculated distance behind the player.

// -----------------------------------------------------------------------------------------------------------------
// handle camera angles .
// ---- limit cam x angle otherwise may tilt too far up or down..
If CameraAngleX# < 0 // so if cam angle negative , we're looking up..
if CameraAngleX#<= -90  //70
CameraAngleX#=-90   //-70
endif
MoveObjectLocalZ(player[locPlr].mesh.campivot_mID, -CameraAngleX#*2.05) // move cam to new position above the player when needed, so floor don't get in the way
//MoveCameraLocalY(player[locPlr].mesh.campivot_mID, -CameraAngleX#*2.05) // move cam to new position above the player when needed, so floor don't get in the way

elseIf CameraAngleX#>85 //
CameraAngleX#=85 //
MoveObjectLocalZ(player[locPlr].mesh.campivot_mID, CameraAngleX#*2.05) // move cam to new position above the player when needed, so floor don't get in the way
//MoveCameraLocalY(player[locPlr].mesh.campivot_mID, CameraAngleX#*40.05) // move cam to new position above the player when needed, so floor don't get in the way
else
//MoveCameraLocalY(player[locPlr].mesh.campivot_mID, -CameraAngleX#*20.05) // move cam to new position above the player when needed, so floor don't get in the way
MoveObjectLocalZ(  player[locPlr].mesh.campivot_mID, CameraAngleX#*2.05) // move cam to new position above the player when needed, so floor don't get in the way
endif

//Set camera position to pivot..
SetCameraPosition(1,GetObjectX(player[locPlr].mesh.campivot_mID ),GetObjectY(player[locPlr].mesh.campivot_mID ),GetObjectZ(player[locPlr].mesh.campivot_mID ) )   // place camera at player's campivot position, but a bit higher(shoulderheight.
// now rotate  camera as set above by inputs of controllers..
SetCameraRotation(1,CameraAngleX#,CameraAngleY#,0 ) // set camera at angle calculated according to mousemovent

// ---------------------------------------------------------

// also rotate the gun..
SetobjectRotation(player[locPlr].mesh.rightArm_mID,CameraAngleX#,0,0) // adjust gun position according to cam


// ----------------------------------------------------------------------------------------------------------------
ElseIf cammode =1 // 1st person mode..
foldstart
SetCameraPosition(1,PlayerX#,PlayerY#+24,PlayerZ#-16)   // place camera at player position
SetCameraRotation(1,CameraAngleX#,CameraAngleY#,0) // set camera at angle calculated according to mousemovent
SetObjectRotation(rightarmID,CameraAngleX#,0,0) // adjust gun position according to cam

// need to hide face objects?
//SetObjectVisible(PlayerObjectID,cammode)
SetCameraPosition(1,PlayerX#,PlayerY#+(.6*physscale),PlayerZ#-(.4*physscale))   // place camera at player position
// ----------------------------------------------------------------------------------------------------------------
foldend
Elseif cammode =2 // detached cam mode..(currently only for debugging) // still needs cam correction for not allowed angles.as in 3rd pers mode.
foldstart
//Setcameralookat(1,PlayerX#,PlayerY#+(.6*physscale),PlayerZ#-(.4*physscale),0) // follow the player around from afar
Setcameralookat(1,PlayerX#,20,PlayerZ#-16,0) // follow the player around from afar

//CameraDistance#=CurveValue(NewCameraDistance#,CameraDistance#,10)
if CameraDistance#<MinCameraDistance#*4

CameraDistance#=MinCameraDistance#*4

SetCameraPosition(1,PlayerX#,PlayerY#,PlayerZ#) // set initial player position.
If jump=0
// MoveCameraLocaly(1,-adjustfactorY#) ///5) // move cam to new position above the player when needed, so floor don't get in the way

MoveCameraLocalZ(1,-CameraDistance#) // move cam to new position behind the player.
endif
endif

// need to still make cam move along when player moves sideways or wanders off to far depth wise.. obstacle avoiding can also be used here,
SetobjectRotation(player[locPlr].mesh.rightArm_mID,CameraAngleX#,0,0) // adjust gun position according to cam(mouse actually in this case)
foldend
Endif

// ------------------------------------------------------------------------------------------------------------
// also rotate the gun..
SetobjectRotation(player[locPlr].mesh.rightArm_mID,CameraAngleX#,0,0) // adjust gun position according to cam
// ------------------------------------------------------------------------------------------------------------

EndFunction

Function UpdateCamera(locPlr as integer) // sync cam with pivot

// handle camera angles .
// ---- limit cam x angle otherwise may tilt too far up or down..
If CameraAngleX# < 0 // ( iaw: if cam angle negative , we're looking up)
if CameraAngleX#<= -90 // if exceeds allowed range..
CameraAngleX#=-90 // limit angle up angle.
endif
  // update campivot pos:  move campivot backwards to new campivot position behind player..(local z-axis)..
MoveObjectLocalZ(player[locPlr].mesh.campivot_mID, -CameraAngleX#*2.05)
elseIf CameraAngleX#>85 // if in exceeds allowed range..
CameraAngleX#=85 // limit cam down angle.
// update campivot pos:  move campivot backwards to new campivot position behind player..(local z-axis)..
MoveObjectLocalZ(player[locPlr].mesh.campivot_mID, CameraAngleX#*2.05) //
else //  so we're looking up or down or straight ahead, and within allowed range..
// no need to restrain any angles, just update campivot  pos:  move campivot backwards  to new campivot position behind player..(local z-axis)..
MoveObjectLocalZ(  player[locPlr].mesh.campivot_mID, CameraAngleX#*2.05) //
endif

// sync camera position to campivot..
// 1st place camera at player's campivot position, which is slightly above player at shoulderheight.
SetCameraPosition(1,GetObjectX(player[locPlr].mesh.campivot_mID ),GetObjectY(player[locPlr].mesh.campivot_mID ),GetObjectZ(player[locPlr].mesh.campivot_mID ) )   
// now rotate camera as set by inputs of controllers..
SetCameraRotation(1,CameraAngleX#,CameraAngleY#,0 ) // set camera at angle calculated according to mouse(etc)input..
//SetCameraRotation(1,CameraAngleX#,CameraAngleY#,CameraAngleY#) ) // mod for drunk / drug / wounded walk

EndFunction

foldend

foldstart // -------------------- additionals ---------------------------------------.

function CurveValue(Destination#,Current#,Steps#)
Current#=Current#+((Destination#-Current#)/Steps#)
endfunction Current#

Function AssignKeys()
   
#constant KEY_KEY_BACKSPACE   8
#constant KEY_TAB   9

#constant KEY_ENTER 13 // also numpad enter
#constant KEY_SHIFT 16
#constant KEY_CONTROL 17
#constant KEY_ALT 18 // added
#constant KEY_ESC 27

#constant KEY_SPACE 32
#constant KEY_PAGEUP 33
#constant KEY_PAGEDOWN 34
#constant KEY_END 35
#constant KEY_HOME 36
#constant KEY_LEFT 37
#constant KEY_UP 38
#constant KEY_RIGHT 39
#constant KEY_DOWN 40

#constant KEY_INSERT 45
#constant KEY_DELETE 46

#constant KEY_0 48
#constant KEY_1 49
#constant KEY_2 50
#constant KEY_3 51
#constant KEY_4 52
#constant KEY_5 53
#constant KEY_6 54
#constant KEY_7 55
#constant KEY_8 56
#constant KEY_9 57

#constant KEY_A 65
#constant KEY_B 66
#constant KEY_C 67
#constant KEY_D 68
#constant KEY_E 69
#constant KEY_F 70
#constant KEY_G 71
#constant KEY_H 72
#constant KEY_I 73
#constant KEY_J 74
#constant KEY_K 75
#constant KEY_L 76
#constant KEY_M 77
#constant KEY_N 78
#constant KEY_O 79
#constant KEY_P 80
#constant KEY_Q 81
#constant KEY_R 82
#constant KEY_S 83
#constant KEY_T 84
#constant KEY_U 85
#constant KEY_V 86
#constant KEY_W 87
#constant KEY_X 88
#constant KEY_Y 89
#constant KEY_Z 90
#constant KEY_CONTEXT   93

#constant KEY_NUM_MULTIPLY 106 // numpad multiply
#constant KEY_NUM_PLUS 107 // numpad plus

#constant KEY_F1 112
#constant KEY_F2 113
#constant KEY_F3 114
#constant KEY_F4 115
#constant KEY_F5 116
#constant KEY_F6 117
#constant KEY_F7 118
#constant KEY_F8 119
  //#constant KEY_F9 120 // does not exist


#constant KEY_SEMICOL 186   
#constant KEY_EQUALS 187
#constant KEY_COMMA 188
#constant KEY_MINUS 189  // numpad subtract
#constant KEY_PERIOD 190  // also  numpad
#constant KEY_SLASH 191 
#constant KEY_SINGLQUOTE 192  // numpad divide (this is the same code as the grave accent/tilde key and seems to be a bug,
   // should be 191 to match the forward slash key)

#constant KEY_SQRBRLEFT 219
#constant KEY_BACKSLASH 220
#constant KEY_SQRBRRIGHT 221
#constant KEY_HASH 222 // APOSTROPHE ?
#constant KEY_ACCENT 223 // ' << is called what?

EndFunction

Function CheckAdditionalKeys()


if GetRawKeyState(KEY_CONTROL) = 1 or GetRawMouseLeftState()  //Ctrl/LMB
//CreateProjectile(PlayerObjectID)
// CreateProjectile(gunendID) // shoot from gunend

//if item=weapon
// launchProjectile
//else
// useCurrentItem
//endif
endif


if GetRawKeyPressed (KEY_BACKSLASH) //KEY_BACKSLASH = swap player..
localPlayer=localPlayer+1

if localPlayer=4
localPlayer=1
// works but cam coords and angles need to be stored at players so that can pick back up correct orientation,
// not of last player..(to do)
swapped_player=1
endif
endif

if GetRawKeyState(KEY_L) = 1 and timer()>delayperiod# // L= toggle streetlight on/off.
lightMode=1-lightMode
if GetPointLightExists( 30 ) =0 and lightMode=0
// CreatePointLight(6, GetObjectX(targetID),GetObjectY(targetID), GetObjectZ(targetID),5,1255,1255,1255)
// CreatePointLight(1, GetObjectWorldX(targetID),GetObjectWorldY(targetID), GetObjectWorldZ(targetID),5,1255,1255,1255)
CreatePointLight(30 , 0,480,0, 5000, 1255, 1255, 1255)
SetPointLightMode(30,1)
SetPointLightPosition(30,0,480,0)
delayperiod#=Timer()+1
elseif GetPointLightExists( 30 ) =1 and lightMode=1
DeletePointLight(30)
endif
endif

If GetRawKeyState(KEY_T) = 1 // T= toggle totch on/off.
torchOn=1-torchOn
delayperiod#=Timer()+1000000
For delay#=0 to delayperiod#
Next delay# // make sure doesn't  get  pressed right after again.
Endif

If GetRawKeyState(KEY_F) = 1 // F= toggle focus (lock mouse to screen).
mouseLocked=1-mouseLocked
SetRawMouseVisible (mouseLocked)
delayperiod#=Timer()+1000000
For delay#=0 to delayperiod#
Next delay# // make sure doesn't  get  pressed right after again.
Endif


If  GetRawKeyState(KEY_F1) = 1 // F1= help
helpdisplay=1-helpdisplay
delayperiod#=Timer()+1000000
For delay#=0 to delayperiod#
Next delay# // make sure doesn't  get  pressed right after again.
EndIf

If  GetRawKeyState(KEY_F2) = 1  // F2= info
infodisplay=1-infodisplay
delayperiod#=Timer()+1000000
For delay#=0 to delayperiod#
Next delay# // make sure doesn't  get  pressed right after again.
EndIf

If  GetRawKeyPressed(KEY_F3) = 1  // F3= toggle (1st/3rd person)

cammode=cammode+1

if cammode=1 // 1st person mode..

endif

if cammode=2  // detached cam mode..
MoveCameraLocalZ(1,-10) // move cam to new position behind the player.
MoveCameraLocalY(1,3) // move cam to new position behind the player.
endif

if cammode=3
cammode=0
flymode=1 //flymode on
endif

if cammode=4 // reset to default 3rd person mode
cammode=0
flymode=0  //flymode off
endif

//delayperiod#=Timer()+5000000
//For delay#=0 to delayperiod#
//Next delay# // make sure doesn't  get  pressed right after again.

EndIf



If  GetRawKeyState(KEY_F4) = 1 // F4 = toggle fly/walk mode
flymode=1-flymode
delayperiod#=Timer()+1000000
For delay#=0 to delayperiod#
Next delay# // make sure doesn't  get  pressed right after again.
EndIf

If  GetRawKeyState(KEY_F7) = 1 // F7 = toggle sun on/off
//sunMode=1-sunMode
delayperiod#=Timer()+1000000
For delay#=0 to delayperiod#
Next delay# // make sure doesn't  get  pressed right after again.
UpdateWorld()
EndIf

If  GetRawKeyState(KEY_F8) = 1 // F8 =  day/night mode
nightMode=1-nightMode
If nightMode=1
lightMode=1
CreatePointLight(30 , 0,5,0, 400, 1255, 1255, 1255)
SetPointLightMode(30,1)
SetPointLightPosition(30,0,5*40,0)


else
lightMode=0
DeletePointLight(30)
endif

delayperiod#=Timer()+1000000
For delay#=0 to delayperiod#
Next delay# // make sure doesn't  get  pressed right after again.
UpdateWorld()
EndIf

If GetRawKeyPressed(KEY_ESC) then endgame=1 // Esc = exit(windows only)

EndFunction

Function CreateTexture(sizex# as float, sizey# as float, color, density as integer)
 
// Function to create a texture
//
// Inputs - Sizex - size of the texture to create - width
//          Sizey - size of the texture to create - height
//          Color - is the main color of the image
//          Denisity - is a the depth of the texture - the lower the value, the more detail. higher value = no detail
//
// Returns the image for the resulting texture
//
// EG. CreateTexture ( 100, 100,  makecolor(0,0,255), 100)
//          This could create a DEEP water effect texture?

Local memblockid as integer
Local imgwidth as integer
Local imgheight as integer
Local size as integer
Local offset as integer
Local r as integer, g as integer, b as integer, a as integer
Local strength as integer

//SetPrintColor( 225,255,255)
SetPrintSize(60)
Print("")
Print("")
Print("")
Print("")
Print ("                           Please wait, creating textures: " + Str( progresscount) )

sync()

swap()
drawbox(0,0,sizex#, sizey#, color, color,color,color, 1)
render()
img = getimage(0,0,sizex#, sizey#)
 
memblockid = CreateMemblockFromImage (img)
imgwidth = GetMemblockInt(memblockid, 0)
imgheight = GetMemblockInt(memblockid, 4)
 
 
size=GetMemblockSize(memblockid)
 
for offset=12 to size-4 step 4

r=GetMemblockByte(memblockid, offset)
g=GetMemblockByte(memblockid, offset+1)
b=GetMemblockByte(memblockid, offset+2)
a=GetMemblockByte(memblockid, offset+3)
 
 
strength=random(1,density)
 
SetMemblockByte (memblockid, offset, r-strength)
SetMemblockByte (memblockid, offset+1, g-strength)
SetMemblockByte (memblockid, offset+2, b-strength )
SetMemblockByte (memblockid, offset+3, a-strength)

next
 
deleteimage (img)
 
img = CreateImageFromMemblock(memblockid)
DeleteMemblock(memblockid)
 



EndFunction img

foldend

foldstart // -------------------- display text --------------------------------------.

Function DisplayInfo()
Local camdis$ as string



SetPrintColor( 225,255,255)
SetPrintSize(30)

If infodisplay
// print info on screen..

Print ("FPS: " + str(  ScreenFPS() ))
Print ("FrameTime: " + str(  GetFrameTime() ))
Print ("Seconds: " + str( GetSeconds() ))
Print ("Polygons: " + str(   GetPolygonsDrawn ()  ))
Print ("")
// Print ("Player  X:  " + Str(GetObjectX(Player)) + "   , Player  Y:  " + Str(GetObjectY(Player)) +"   ,   Player  Z:  " + Str(GetObjectZ(Player)))
Print ("Player  X:  " + Str(PlayerX#) + "   , Player  Y:  " + Str(PlayerY#) +"   ,   Player  Z:  " + Str(PlayerZ#))
Print ("CameraX:  " + Str(GetCameraX(1)) + " , CameraY:  " + Str(GetCameraY(1)) +" ,  CameraZ:  " + Str(GetCameraZ(1)))
Print("CameraAngleX: "+ str(CameraAngleX#)+"   CameraAngleY: "+ str(CameraAngleY#) )  // +"CameraAngleZ: "+ str(CameraAngleZ#))
Print("--------------------------------------------")
Print("CameraDistance#: "+ str(CameraDistance#))
Print("NewCameraDistance#: "+ str(NewCameraDistance#))
Print("UserCameraDistance#: "+ str(UserCameraDistance#)) 
Print("RayObjectID#: "+ str(RayObjectID))
Print("--------------------------------------------")
Print("")
if cammode=0 then camdis$="3rd person(default)"
if cammode=1 then camdis$="1st person"
if cammode=2 then camdis$="detached"
Print("Cammode: "+ camdis$)
Print("")
Print("flymode: "+ str(flymode))
Print("nightmode: "+ str(nightMode))
Print("timer: " + str(timer()) )
Print("EleWait#: " +str(EleWait#))
remstart
Print("shotdelay: " + str(shotdelay#))

Print("bulletcount: " + str(bulletcount) + "        ammountofammo: " + str(ammountofammo))
Print("hitobjectatx: " + str(hitobjectatx))
Print("hitobjectaty: " + str(hitobjectaty))
Print("hitobjectatz: " + str(hitobjectatz))
//for n = 0 to 100
//print ("bulletLight[]= " + str(bulletLight[n] ) +"  " )
//next
remend
print("")
if object_hit=ladderhitbox or object_hit=ladderhitbox2
dis$="hit"
endif
Print("ladder hit: " + dis$ +" = " + str(ladderhitbox) )
Print ("object_hit: "+str(object_hit) )
Print("GetObjectRayCastNumHits: "+ str(GetObjectRayCastNumHits()) )
Print("maxjump: " + str(maxjump#))
Print("")
//Print("pad= "+str(pad))
Print("GetObjectY(Elevator1): " + str(GetObjectY(Elevator1)))
//Print ("bullx#: "+str(bullx#) + " bully#: " + str(bully#) + " bullz#"+str(bullz#) )
//Print ("BulletLight[bulletcount]= "+str(BulletLight[1])) //100224
//Print ("targetIDx: "+Str(GetObjectX(targetID))+", targetIDy: "+str(GetObjectY(targetID))+", targetIDz: "+Str(GetObjectZ(targetID)))
Print("")

Print ("F1 = Help")

EndIf

EndFunction

Function DisplayHelp()
If helpdisplay
// print info on screen..
Print ("F2 = toggle tech info")
Print ("F3 = toggle 1st/3rd person mode")
Print ("F4 = toggle fly/walk mode")
Print ("F5 = toggle audio on/off")
Print ("F6 = toggle fog on/off")
Print ("F7 = toggle sun on/off")
Print ("F8 = toggle day/night")
Print("")
Print ("W, A, S, D, RMB, cursor keys = move")
Print ("Q, E =  strafe")
Print ("Mouse to look round")
Print ("Mousewheel = zoom in/out")
Print ("Shift  + move = run")
Print ("Space =  jump, (+ forward = climb/fly-when in flymode)")
Print ("-Not implemented yet/fully-")
Print ("Alt = crouch")
Print ("Ctrl / LMB = fire/use item")
Print ("Tab / i = cycle inventory items")
Print ("T =  torch, M = map, C = compass ")
Print ("")
Print ("F = toggle Mouse lock")
Print ("Esc = exit, P = pause" )

EndIf


EndFunction

foldend

_______________________________________
B3D + physics + shaders + X-platform = AGK!
:D ..ALIENBREED *LIVES* (thanks to Qube).. :D
_______________________________________

Rick Nasher

#3
Hi guys,

I've added a pivot for the cam to have more flexibility, so that the camera is able to look up all the way.
For instance near a building without it going through the floor:


Or all the way down, for instance near a cliff.


It then goes over the player's head and looks down (can see your own toes):  :P



But I ran into 2 mysterious issues:

ISSUE 1: I've noticed in v6.0 that the campivot is *not* in the expected location behind the player,
but tends to live a life of it's own
, can see it on the left drifting away into the distance(see circled area).
This even though the camera itself is working fine, is behind the player as intended.
The other players haven't not moved yet, so there the campivot is still in place(see arrows).

>>How can the campivot *not* be in the correct x,y,z while the camera attached to this campivot *is* in the correct location behind the player??


ISSUE 2: I've also modified the UpdatePlayer() function into UpdatePlayer(locPlr as integer) in V6.1, for being able to control multiple players using types and arrays through the same code.

For instance in v6.0 it looks like this:

// store players current x,y,z and angles before any movement..
oldPlayerX#=GetObjectX(player[locPlr].mesh.body_mID)


As can be seen I'm using the fields of the player type in V6.1.;

// store players current x,y,z and angles before any movement..
player[locPlr].oldx = GetObjectX(player[locPlr].mesh.body_mID)


>>Why after converting all of the player references to it's type x,y,z fields, are the collisions behaving erratic and is the player at times reseting position to 0,0,0. ?




I can't seem to figure out why. Hopefully someone can shed some light on this, for I'm ready to pull my hair out. :( Any help is much appreciated.

I've included simplified cut down versions below in code boxes, but also as download for convenience.
Download(both versions): http://www.mediafire.com/file/zh5w053gjxikb5e/Univ3D_1%263P_Framework.rar

_______________________________________
B3D + physics + shaders + X-platform = AGK!
:D ..ALIENBREED *LIVES* (thanks to Qube).. :D
_______________________________________

RemiD

I have seen a similar problem in Blitz3d, and the cause of the problem was not obvious ??? :
basically, some commands (blitz3d functions) are taken into account only once per renderworld (per entity)
This is the case for entityparent().
So if you use entityparent several times for the same entity in the mainloop, only the last one will be taken into account !
Maybe your problem is caused by something similar to that ?


Or it may be caused by the collision system, if your camera has a collider, you may not be able to reposition it as you want because it has constraints in the "collisions world" (same thing with a physics engine)

Rick Nasher

Thanks for your reply RemiD.
Quote from: RemiD on February 05, 2018, 21:35:50
I have seen a similar problem in Blitz3d, and the cause of the problem was not obvious ??? :
basically, some commands (blitz3d functions) are taken into account only once per renderworld (per entity)
This is the case for entityparent().
So if you use entityparent several times for the same entity in the mainloop, only the last one will be taken into account !
Maybe your problem is caused by something similar to that ?

Hmm, don't think so. I've tried not using EntityParent( FixObjectToObject in AGK) but it doesn't make any difference. Also it appears to work fine on the arm for instance, but I will investigate this in a more simplified test.

Quote
Or it may be caused by the collision system, if your camera has a collider, you may not be able to reposition it as you want because it has constraints in the "collisions world" (same thing with a physics engine)

Could be. AGK collisions work by ray or sphere casting from original position to the location it moved to. If then something was hit, it can by choice perfom either a slide or do nothing action and return the location where was hit so one can adjust location.

In any case weird. It drives me crazy. The changes do not seem that drastic to me. Perhaps it's a variable scope thing..
_______________________________________
B3D + physics + shaders + X-platform = AGK!
:D ..ALIENBREED *LIVES* (thanks to Qube).. :D
_______________________________________

RemiD

Quote
I've tried not using EntityParent( FixObjectToObject in AGK) but it doesn't make any difference.
I don't say to not use entityparent() / FixObjectToObject()
I say to be careful how you use it several times for the same entity
Because apparently only the last called command is considered per renderworld()...
So a similar issue may happen with AGK (but it may not be the cause of your problem in this case)

So my point was : your code is not necessarily what happens in the "game engine" because you don't know exactly how it is translated in the different systems (transform, collisions, physics), when an entity is updated, and what happens "behind the scene"

Rick Nasher

#7
Could very well be indeed. Just doubting my own code a bit as I'm such a crappy coder. :-)
_______________________________________
B3D + physics + shaders + X-platform = AGK!
:D ..ALIENBREED *LIVES* (thanks to Qube).. :D
_______________________________________