Rem Project: Ivalice
Rem Created: Thursday, April 30, 2015


'==============================================================================================================================================
gosub _setup_world
'==============================================================================================================================================
`gosub _make_cloth
'==============================================================================================================================================
GOSUB _NPC_Initialize
     
          
     `Make player character
     currentCharObj = 1           
     makeCharacter( 1 , 2 , "media/balthier/balthier idle.x" , "media/balthier/balthier sword 21.x" , "", "", "", "" )
     makeCharacter( 2 , 2 , "media/balthier/balthier idle.x" , "media/balthier/balthier sword 21.x" , "", "", "", "" )      
        
     `zombie
     load object "media/zombie 1/zombie 1.x", currentCharObj +10
     TEXTURE OBJECT currentCharObj +10, 0, 500
     Set object transparency currentCharObj + 10, 4
     `set object emissive currentCharObj +10, RGB(250,250,250)
     position object currentCharObj +10, 250,0,1000
     scale object currentCharObj +10, 60000,60000,60000
     set object speed currentCharObj +10, 50
     loop object currentCharObj +10
     SET OBJECT LIGHT currentCharObj +10, 1
     `SET OBJECT COLLISION TO POLYGONS currentCharObj +10
     `SET OBJECT COLLISION OFF currentCharObj +10
     `SET OBJECT COLLISION TO POLYGONS currentCharObj +10
     `SHOW OBJECT BOUNDS currentCharObj +10, 1
     
     `skeleton
     load object "media/skeleton 1/skeleton 2.x", currentCharObj +11, 5
     TEXTURE OBJECT currentCharObj +11, 0, 501
     Set object transparency currentCharObj + 11, 4
     `set object emissive currentCharObj +11, RGB(250,250,250)
     position object currentCharObj +11, 1000,250,2000
     scale object currentCharObj +11, 53000,53000,53000
     set object speed currentCharObj +11, 50
     loop object currentCharObj +11
     SET OBJECT LIGHT currentCharObj +11, 1
     
     `maya
     load object "media/balthier/balthier idle.x", currentCharObj +12,5
     `TEXTURE OBJECT currentCharObj +12, 0, 2
     color object currentCharObj +12,rgb(255,255,255)
     `Set object transparency currentCharObj + 12, 4
     `set object emissive currentCharObj +12, RGB(250,250,250)
     `set object diffuse currentCharObj +12, RGB(250,250,250)
     position object currentCharObj +12, 1100,250,2000
     scale object currentCharObj +12, 53000,53000,53000
     `set object speed currentCharObj +12, 50
     `loop object currentCharObj +12
     `SET OBJECT LIGHT currentCharObj +12, 1
     Set Object cull currentCharObj +12, 0
     
     `box
     MAKE OBJECT BOX currentCharObj +13, 100,100,100
     position object currentCharObj +13, 1400,250,2000
     
     
     `helmet
     LOAD OBJECT "media/elite knight helmet/elite helmet.x", currentCharObj +100
     `SCALE OBJECT currentCharObj +11, 25000,25000,25000
     SET OBJECT COLLISION OFF currentCharObj +100
     TEXTURE OBJECT currentCharObj +100, 0, 300
     TEXTURE OBJECT currentCharObj +100, 1, 301
     SET OBJECT LIGHT currentCharObj +100, 1
     SET BUMP MAPPING ON currentCharObj +100, 301
     scale object currentCharObj +100, 23000,23000,23000
     `SET LIGHT MAPPING ON currentCharObj +11, 302
     
      `helmet for dummy
      dummyhelmet = currentCharObj +200
     LOAD OBJECT "media/elite knight helmet/elite helmet.x", dummyhelmet
     SET OBJECT COLLISION OFF dummyhelmet
     TEXTURE OBJECT dummyhelmet, 0, 300
     TEXTURE OBJECT dummyhelmet, 1, 301
     SET OBJECT LIGHT dummyhelmet, 1
     SET BUMP MAPPING ON dummyhelmet, 301
     scale object dummyhelmet, 23000,23000,23000
          
   
     `sword real
     GLOBAL swordObj = 102
     LOAD OBJECT "media/WP_A_0201/WP A 1.x", swordObj
     `SET OBJECT COLLISION OFF currentCharObj +101
     TEXTURE OBJECT swordObj, 0,  303
     SET BUMP MAPPING ON swordObj, 304
     SET OBJECT COLLISION TO BOXES swordObj
     scale object swordObj, 20000,20000,20000
     `SET OBJECT COLLISION TO SPHERES swordObj
     `MAKE OBJECT COLLISION BOX swordObj, -1,-1,1, 1,1,200, 0    
     `SHOW OBJECT BOUNDS swordObj, 1
     
     `shirt
     GLOBAL shirtObj = 103
     LOAD OBJECT "media/BD_A_9500_unpack elite knight armor/elite knight shirt.x", shirtObj
     SET OBJECT COLLISION OFF shirtObj
     SET OBJECT CULL shirtObj, 1
     TEXTURE OBJECT shirtObj, 0,  305
     SET OBJECT TRANSPARENCY shirtObj, 3
     scale object shirtObj, 20000,20000,20000
     
     `right shoulder
     GLOBAL RShoulderObj = 104
     LOAD OBJECT "media/BD_A_9500_unpack elite knight armor/elite right shoulder.x", RShoulderObj
     SET OBJECT COLLISION OFF RShoulderObj
     `TEXTURE OBJECT RShoulderObj, 0,  307
     SET BUMP MAPPING ON RShoulderObj, 308
     SET OBJECT TRANSPARENCY RShoulderObj, 3
     scale object RShoulderObj, 20000,20000,20000
     
     `right gauntlet
     GLOBAL RGauntletObj = 105
     LOAD OBJECT "media/AM_A_9500 elite gauntlet/elite right gauntlet.x", RGauntletObj
     SET OBJECT COLLISION OFF RGauntletObj
     `TEXTURE OBJECT RShoulderObj, 0,  307
     `SET BUMP MAPPING ON RGauntletObj, 308
     SET OBJECT TRANSPARENCY RGauntletObj, 3
     scale object RGauntletObj, 20000,20000,20000
     
     `loin cloth
     GLOBAL hipObj = 106
     LOAD OBJECT "media/BD_A_9500_unpack elite knight armor/elite hip.x", hipObj
     SET OBJECT COLLISION OFF hipObj
     `TEXTURE OBJECT hipObj, 0,  305
     SET OBJECT CULL hipObj, 0
     SET OBJECT TRANSPARENCY hipObj, 3
     scale object hipObj, 20000,20000,20000
   
     

'==============================================================================================================================================

        
    `Make NPC using function
     ````gosub _make_NPC
     GOSUB _NPC_Initialize
     `Make_NPC( currentCharObj , "media/IrisHeart/iris short.x" , currentCharObj+1  , currentCharObj+2 , currentCharObj+3 )
    
     NPClogics(1,3) = 1
     NPClogics(1,3) = 1  :`NPCcontrol 1 =1
     NPClogics(1,1) = 0  :`following  =0
     
     
     

'==============================================================================================================================================
gosub _setup_chatbox
'==============================================================================================================================================




'##############################################################################################################################################
'##############################################################################################################################################
'##############################################################################################################################################d
'##############################################################################################################################################
'##############################################################################################################################################
'##############################################################################################################################################
'##############################################################################################################################################

DO
`MAIN LOOP


'=============================================================================================================================================    
Rem MOVEMENTS 
     
        
     `Counter

    `Time
     deltaTime# = timer() - time#
     time# = timer() 
     
     Counter = counter +1
     If counter > 60 THEN counter =1 
     
     `Movement_logics( 1 , currentCharObj , dummycube ) 
     `Movement_logics( 2 , currentCharObj , NPC2dummycube ) 
             
        
     `NPC1 movements                
     `Walking_sequence( currentCharObj , footleft , footright , NPC2lefthip , NPC2leftknee , NPC2righthip , NPC2rightknee , dummycube , NPC1 )
     `Hand_swing( currentCharObj, NPC1 , footleft , footright , NPC2leftshoulder , NPC2leftelbow , NPC2rightshoulder , NPC2rightelbow )

     `Control_NPC( currentCharObj , footleft , footright , NPC2lefthip , NPC2leftknee , NPC2righthip , NPC2rightknee , dummycube , 1 )
                 IF KEYSTATE(57) = 1
                     `Control_NPC( currentCharObj , footleft , footright , NPC2lefthip , NPC2leftknee , NPC2righthip , NPC2rightknee , dummycube , 1 )
                     `Control_NPC( currentCharObj , footleft , footright , NPC2lefthip , NPC2leftknee , NPC2righthip , NPC2rightknee , dummycube , 1 )
                 ENDIF
          
'==============================================================================================================================================
Rem Camera 
gosub _camera_movement
PlayerCharMovement( 1 , 1 , 2 , currentCharObj +2 )

`Position helmet
PositionParts( 1 , 43 , currentCharObj +100 , 0 , 0 , 0 , 30 , -10 , -100 , 0 , 0 , 0 )
`Position hemet for dummy
PositionParts( 2 , 43 , dummyhelmet , 0 , 0 , 0 , 30 , -10 , -100 , 0 , 0 , 0)

`Position sword
`PositionParts( 1 , 62 , swordObj , 0 , 0 , 0 , 0 , 0 , 0, 0 , 0 , 0)
PositionParts( 1 , 62 , swordObj , 60 , 0 , 0 , 0 , 90 , 0, 0 , 0 , 0)

`position shirt
PositionParts( 1 , 42 , shirtObj , 0 , 0 , 0 , -5 , 0 , -95, 0 , 0 , 0)
`PositionParts( 1 , 42 , shirtObj , 0 , 0 , 0 , 0 , 0 , 0, 0 , 0 , 0)

`position right shoulder
PositionParts( 1 , 47 , RShoulderObj , 0 , 0 , 0 , 180 , 0 , 180, 0 , 0 , 0)

`position right gauntlet
PositionParts( 1 , 50 , RGauntletObj , 0 , 0 , 0 , 0 , 180 , 10, 0 , 0 , -0.02)

`position loin cloth
PositionParts( 1 , 41 , hipObj , 0 , 0 , 0 , -10 , 0 , -90, 0.03 , 0 , 0.06)

PlayerDist# = sqrt(((camera position x(0)-object position x(currentCharObj))^2) + ((camera position y(0)-object position y(currentCharObj)- 180)^2) + ((camera position z(0)-object position z(currentCharObj))^2))
'==============================================================================================================================================
`COMMANDS
   
Rem toggle chatbox
    gosub _toggle_chatbox
Rem Commands
    `gosub _chat_commands 

'==============================================================================================================================================

`Symbol Movement
`symbola = curveangle (symbola + 20, symbola,10)
`yrotate object 401, symbola

'==============================================================================================================================================    
    REM SHOW COORDINATES
    text 10,10, "FPS:"+ str$(screen fps())
    text 10,30, "Character collision:" + STR$(object collision(currentCharObj,0))
    text 10,50, "lastObj:" + STR$(lastObj)
    text 10,70, "collisionDIst#:" + STR$(collisionDIst#)
    text 10,90, "NPC 2 HP:" + STR$(NPCStatus(2,1))
    text 10,110, "Sword collision:" + STR$(object collision(swordObj,0))
    text 10,130, "prevFootR#:" + STR$(NPCmov(1,35))
    text 10,150, "prevFootL#:" + STR$(NPCmov(1,36))
    
        
    IF (mouseclick() = 2) 
    text 1050,10, "Time:" + get time$()
        
    ```'text 10,90, "wind: "+ str$(WINDFACTOR#)
    ```'text 10,140, "particles position x" + str$(particles(r,c).position.x)
    ```'text 10,170, "colliding particles : " + str$(collisions(b).p1.r)
    ```'text 10,200, "collision activity :" + str$(b)
    ```'text 10,230, "collision vector : " + str$(collisions(b).n.x)
    
    `text 1500,80, "leftShoulder X angle : "+ str$( limb angle x (NPC1, blueLeftShoulder) )
    `text 1500,100, "leftShoulder Y angle : "+ str$( limb angle y (NPC1, blueLeftShoulder) )
    `text 1500,120, "leftShoulder Z angle : "+ str$( limb angle Z (NPC1, blueLeftShoulder) )
    `text 1500,140, "leftElbow X angle : "+ str$( limb angle x (NPC1, blueLeftElbow) )
    `text 1500,160, "leftElbow Y angle : "+ str$( limb angle y (NPC1, blueLeftElbow) )
    `text 1500,180, "leftElbow Z angle : "+ str$( limb angle Z (NPC1, blueLeftElbow) )
    ENDIF
   
   
    sprite 1,10,0,1000
    SET SPRITE PRIORITY 1, 1
    SIZE SPRITE 1, 1000, 50
    
    `PASTE IMAGE 1000 ,10,10, 1
    sprite 2,10,20,1001
    SIZE SPRITE 2, 1000, 15
    SET SPRITE ALPHA 2, 200
    
    


       
       
SYNC
`FASTSYNC
LOOP



'##############################################################################################################################################
'##############################################################################################################################################
'##############################################################################################################################################
'##############################################################################################################################################
'##############################################################################################################################################
'##############################################################################################################################################



'==============================================================================================================================================

_Load_Stuff:
`Images 
            LOAD IMAGE "media/white.bmp", 1
            `LOAD IMAGE "media/eastersand.png", 2
            LOAD IMAGE "media/blueSky.JPG", 2
            
            LOAD IMAGE "media/ds tex/wall 1 4b41e51a.png", 3
            LOAD IMAGE "media/ds tex/wall 1 bump b3134190.png", 4
                        
            LOAD IMAGE "media/ds tex/wall 3 f724ec66.png", 5
            LOAD IMAGE "media/ds tex/wall 3 bump b3134190.png", 6
                        
            load image "media/tile16.png",100
            load image "media/ivalice textures/floor 1.png", 200
            
            LOAD IMAGE "media/elite knight helmet/HDA9500.dds", 300
            LOAD IMAGE "media/elite knight helmet/HDA9500n.dds", 301
            LOAD IMAGE "media/elite knight helmet/HDA9500s.dds", 302
            
            LOAD IMAGE "media/WP_A_0201/WP_A_0201.dds", 303
            LOAD IMAGE "media/WP_A_0201/WP_A_0201_n [Unknown24].dds", 304
            
            LOAD IMAGE "media/BD_A_9500_unpack elite knight armor/BD_A_9500_1.dds", 305
            LOAD IMAGE "media/BD_A_9500_unpack elite knight armor/BD_A_9500_1_n [Unknown24].dds", 306
            LOAD IMAGE "media/BD_A_9500_unpack elite knight armor/BD_A_9500_2.dds", 307
            LOAD IMAGE "media/BD_A_9500_unpack elite knight armor/BD_A_9500_2_n [Unknown24].dds", 308
            LOAD IMAGE "media/AM_A_9500 elite gauntlet/AM_A_9500.dds", 309
            LOAD IMAGE "media/AM_A_9500 elite gauntlet/AM_A_9500_n [Unknown24].dds", 310
            
            LOAD IMAGE "media/zombie 1/n1097_00.png", 500
            LOAD IMAGE "media/skeleton 1/n1100_00.png", 501
            
            
            LOAD IMAGE "media/ds tex/lifebar.png", 1000
            LOAD IMAGE "media/ds tex/red bar.png", 1001
            shadowbone = 1
            `load effect "media/FX/ShadowMappingBumpBone.fx",shadowbone,0
            `load effect "media/FX/ShadowMappingFix.fx",2,0
     '-------------------------------------------------------------------------------------------------------------------------------
            `EFFECTS
            shader =1
            load effect "media/shaders/Bumpmapping.fx",1,0
            if shader=1 then set effect technique 1,"lighting1"
            if shader=2 then set effect technique 1,"lighting2"
            if shader=3 then set effect technique 1,"lighting3"
            if shader=4 then set effect technique 1,"lighting4"
            if shader=5 then set effect technique 1,"lighting5"
            if shader=6 then set effect technique 1,"lighting6"
            if shader=7 then set effect technique 1,"lighting7"
            if shader=8 then set effect technique 1,"lighting8"
            set vector4 2,255,255,255,0
            set effect constant vector 1,"LC_1",2        :`light colour
            set effect constant vector 1,"LC_2",2        :`light colour
            set effect constant vector 1,"LC_3",2        :`light colour
            set effect constant vector 1,"LC_4",2        :`light colour
            set effect constant vector 1,"LC_5",2        :`light colour
            set effect constant vector 1,"LC_6",2        :`light colour
            set effect constant vector 1,"LC_7",2        :`light colour
            set effect constant vector 1,"LC_8",2        :`light colour
            effectRange = 700 
            set effect constant float 1,"LR_1",effectRange     :`light range
            set effect constant float 1,"LR_2",effectRange     :`light range
            set effect constant float 1,"LR_3",effectRange     :`light range
            set effect constant float 1,"LR_4",effectRange     :`light range
            set effect constant float 1,"LR_5",effectRange     :`light range
            set effect constant float 1,"LR_6",effectRange     :`light range
            set effect constant float 1,"LR_7",effectRange     :`light range
            set effect constant float 1,"LR_8",effectRange     :`light range
       '-------------------------------------------------------------------------------------------------------------------------------    
            
        `Objects
            `load object "media/elementalist/ilia.x",body,1
            `make object sphere footLeft, 2
            `make object sphere footRight, 3
            `make object cube dummycube,4
            `make object cloth1, 1002
        `Musics
            `Load music "media/Peaceful Repose.mp3",1
                `Loop music 1
                `set music volume 1,1
RETURN

'###############################################################################################################################################


_Setup_World:
    `Init Sync
        sync on: sync rate 80
        desktopwidth=desktop width()
        desktopheight=desktop height()
        `set display mode desktopwidth*0.94, desktopheight*0.94,32,0
        set display mode desktopwidth*0.995, desktopheight*0.995,32,1
        `set window size desktopwidth,desktopheight
        Set window position -2,-18
        `maximize window
        `sync rate 80
        `SYNC
    `Misc
        disable escapekey 
        autocam off 
        hide mouse
        set text size 22
        `set text to bold
        `set text transparent
        set text opaque
        ink RGB(1,1,200), RGB(500,500,500) 
    `Init Backdrop and Fog
        Backdrop on 
        `Color Backdrop RGB(255,255,255)   :rem twilight sky 255,197,138  deepblue sky 12,70,167   lightblue 116,165,245    white 255,255,255   black 0,0,0
        Color Backdrop RGB(1,1,1) 
        Set camera range 100, 100000  :rem 2000000
        set camera fov 0, 45
        `Fog on
        `Fog distance 10  : rem 40000
        `Fog color RGB(1,1,1)       :rem RGB(255,197,138)
        
        `set ambient light 100
        set ambient light 0
        color ambient light RGB(255,255,255)  
        
        REM Make sun light
        make light 1
        set point light 1, 0, 0, 0
        position light 1,  0, 500, 2000
        set light range 1, 300000
        color light 1, RGB(255,0,0)
           
        
        `make light 0
        set point light 0, 0, 500000, 500000
        position light 0,  0, 500000, 200000
        set light range 0, 1
        color light 0, RGB(255,0,0)
        
        rem make light vectors
        null=make vector4(1)
        null=make vector4(2)
        
        
        
    `Time
        global time# as float
        time# = timer()
        global deltaTime# as float
        deltaTime# = 0
        GLOBAL counter = 0
   
     `Load stuff
     GOSUB _Load_Stuff
        
     REMSTART
    `Original Matrix 
        matrixwidth = 100000
        matrixlength = 100000
        make matrix 1, matrixwidth, matrixlength, 200, 200
        Prepare matrix texture 1,2,1,1
        `make matrix 1,1,1,1,1
            `make matrix 1, matrixwidth, matrixlength,50,50
            `prepare matrix texture 1, 1 ,1,1
            `randomize matrix 1,100  :rem 300
            position matrix 1, -matrixwidth/2, 0, -matrixlength/2
        `set matrix 1,0,0,1,0,1,1,1
            `set matrix wireframe on 1
        update matrix 1
        REMEND
       
 
    
     `set global collision on
     `Make origin box mesh
         `global originBox = 400
         `Make object box 400,1,1,1
         `Make mesh from object originBox, originBox
         `DELETE OBJECT 400
    
     `==================================================================================================================================================
     
     `Make Sky backdrop
     MAKE OBJECT SPHERE 499, 200000
     POSITION OBJECT 499, 0,0,0
     SET OBJECT CULL 499, 0
     TEXTURE OBJECT 499, 2
     SCALE OBJECT TEXTURE 499, 5000, 5000
     SET OBJECT TEXTURE 499, 0, 0
     SET OBJECT EMISSIVE 499, RGB(255,255,255)
     SET OBJECT SPECULAR 499, RGB(255,255,255)
     SET OBJECT DIFFUSE 499, RGB(255,255,255)
     SET OBJECT LIGHT 499, 0
     SET OBJECT FOG 499,0
     SET OBJECT COLLISION OFF 499
     HIDE OBJECT 499
     
     `Make marker box to carve dungeon
     Make object box 498, 10,10,10      
     MAKE OBJECT COLLISION BOX 498, -30,-5,-30, 50,600,50, 0
     POSITION OBJECT 498, 0, 100000, 0
     
     `Make base terrain object
     `GLOBAL terrainNum = 500
     `Make Object BOX terrainNum, 10 , 10 , 10
     ``SET OBJECT COLLISION TO BOXES terrainNum
     ``SET OBJECT COLLISION TO POLYGONS terrainNum
     ```MAKE OBJECT COLLISION BOX terrainNum, -1,-1,-1, 1,1,1, 0
     ``POSITION OBJECT terrainNum, 0,-50000, 0
     `SHOW OBJECT BOUNDS terrainNum
     
     `MAKE LAND
     GLOBAL lastObj = 5000
     GLOBAL startObj = 5001
     `GLOBAL limbNum = 0
     
     
    `================================================================================================================================================== 
    `Initialize dungeon path arays
     GLOBAL DIM dungeonPath(100, 100, 500,4) AS INTEGER  :`dungeonPath(corridor number , dungeonLevel , tile/block number, locationX/locationY/direction of block/dungeonLevel)
     GLOBAL DIM dungeonRoom(100, 100, 500,4) AS INTEGER
    
    REM Make dungeon bases
     FillLevel( 0 , 20 , 500 , 1 , 5 , 6 )
     FillLevel( 1 , 20 , 500 , 1 , 5 , 6 )
     FillLevel( 2 , 20 , 500 , 1 , 5 , 6 )
     FillLevel( 3 , 20 , 500 , 1 , 5 , 6 )
     
     `dig rooms
     DigRoom( 1 , 1 , 9 , 0 , 0 )
     `================================================================================================================================================== 
         
         
     `MakeCorridor( 0 , 0 , 0 , 3 , 10 , 10 )
     `MakeRoom( 1 , 0 , 5 , 7 , 0 , 0 , 5 ,6 )
     
     `==================================================================================================================================================    
       
        
       
        `Init camera variables
        Global camAY# as float
        camAY# = 0: camAX# = 0
        camDist# = 800
        camheight# = 250
        cameraType = 1
        `position camera 0, 60, 0, -30
        `position camera 0,matrixwidth/2 + 40, get ground height(1, matrixwidth/2,matrixlength/2), matrixlength/2
        
       rem set automatic collision for camera
       automatic camera collision 0, 1,0, 0

       set global collision on 
        
RETURN
'##############################################################################################################################################

_Setup_Chatbox:
    maxPlayers = 8
    Dim players$(maxPlayers)
    
    rem Define an array to record key presses so we can monitor user input.
    dim key$(1)
    
    rem The player list and the chat space can't overlap, but we don't want them pushing
    rem each other off the screen so the chat space resizes itself depending on how many
    rem players we're showing.
    dim chatlines$(28 - maxPlayers)
    chatflag$=""
    latestline=0
    action$=""
    
    rem These 6 are the important variables used to make and find games
    connection=0
    connection$=""
    host$=""
    playername$="Player"
    netsession=0
    netsession$=""
    
    rem Initial miscellaneous
    global currentmessage$ = "^0^"
    'global following = 0
    
    Gosub _load_words_library
    
    
RETURN
'##############################################################################################################################################

_Load_Words_Library:
    
    dim Follow$(3) as string
        Follow$(0) = "come"
        Follow$(1) = "follow"
        Follow$(2) = "stay with me"
        Follow$(3) = "stay close"
    
    dim Prohibit$(2) as string
        Prohibit$(0) = "don't"
        Prohibit$(1) = "dont"
        Prohibit$(2) = "stop"
    
    dim Shoo$(3) as string
        shoo$(0) = "get lost"
        shoo$(1) = "go away"
        shoo$(2) = "stay away"
        shoo$(3) = "shoo"
        
    dim Name$(2) as string
        Name$(0) = "hakim"
        Name$(1) = "npc1"
        Name$(2) = "npc2"
RETURN
'##############################################################################################################################################


`LEG FUNCTIONS
function dist3d(x1#,y1#,z1#,x2#,y2#,z2#)
   dx# = x1# - x2#
   dy# = y1# - y2#
   dz# = z1# - z2#
   d# = sqrt(dx#^2 + dy#^2 + dz#^2)
endfunction d#

function dist2d(x1#,y1#,x2#,y2#)
   dx# = x1# - x2#
   dy# = y1# - y2#
   d# = sqrt(dx#^2 + dy#^2)
endfunction d#

'###############################################################################################################################################
FUNCTION makeCharacter( characterNum , totalModelNum , firstModel$ , secondModel$ , thirdModel$ , fourthModel$ , fifthModel$ , sixthModel$ ) 
     `startmodel = dummy object number
     `endmodel = dummy object + total model sets
     `firstModel$ = path of first character model
     
     charObjNum = characterNum
     startModelNum = (characterNum*20) + 500
     endModelNum = (characterNum*20) + 500 +  totalModelNum - 1
     
     rem main collision box
     MAKE OBJECT BOX charObjNum, 50,50,50
     MAKE OBJECT COLLISION BOX charObjNum, -60, -0, -60, 60, 340, 60, 0
     POSITION OBJECT charObjNum, 1000, 250,1000
     SHOW OBJECT BOUNDS charObjNum, 1
     HIDE OBJECT charObjNum
     
     rem main model,
     IF (endModelNum-startModelNum) > -1
     load object firstModel$, startModelNum
     `MAKE OBJECT COLLISION BOX startModelNum, -100, 1, 50, 100, 340, 100, 1
     `SET OBJECT COLLISION TO POLYGONS startModelNum+1
     SET OBJECT COLLISION OFF startModelNum
     ````TEXTURE OBJECT startModelNum , 100
     SET OBJECT WIREFRAME startModelNum , 1
     `SET ALPHA MAPPING ON startModelNum , 100
     `SHOW OBJECT BOUNDS startModelNum 
     ENDIF 
     
         
     `second model to take its animation
     IF (endModelNum-startModelNum) >0
     load object secondModel$, startModelNum +1
     `SET ALPHA MAPPING ON startModelNum +1, 1
     HIDE OBJECT startModelNum +1
     `TEXTURE OBJECT startModelNum+1 , 1
     SET OBJECT COLLISION OFF startModelNum +1
     ENDIF
      
     append object secondModel$, (startModelNum ), total object frames(startModelNum)+1
     
     make object sphere endModelNum +1, 10
     SET OBJECT COLLISION OFF endModelNum +1
     make object sphere endModelNum +2, 10
     SET OBJECT COLLISION OFF endModelNum +2
     
     FOR x = (startModelNum) TO endModelNum
     Set object transparency x, 4
     set object emissive x, RGB(255,255,255)
     set object ambience x, RGB(255,255,255)
     set object DIFFUSE x, RGB(250,250,250)
     set object SPECULAR x, RGB(250,250,250)
     SET OBJECT CULL x, 0
     SET OBJECT LIGHT x, 1
     position object x, 1000, 250,1000
     scale object x, 50000,50000,50000
     set object speed x, 50
     `SHOW OBJECT BOUNDS x, 1
     NEXT x
 ENDFUNCTION
'###############################################################################################################################################

FUNCTION PlayerCharMovement( playerNum , characterNum , totalModelNum , currentModelNum )
    
   charObjNum = characterNum
   startModelNum = (characterNum*20) + 500
   endModelNum = (characterNum*20) + 500 +  totalModelNum - 1
    
    x# = NPCmov(playerNum,1)
    y# = NPCmov(playerNum,2)
    z# = NPCmov(playerNum,3)
    ay# = NPCmov(playerNum,4)
        vx# = NPCmov(playerNum,5)
        vy# = NPCmov(playerNum,6)
        vz# = NPCmov(playerNum,7)
        v# = NPCmov(playerNum,8)
        footsine# = NPCmov(playerNum,29)
        attackPhase = NPCmov(playerNum,34) 
   `Previous foot position
   prevFootR# = NPCmov(playerNum,35)
   prevFootRX# = OBJECT POSITION X(endModelNum +1)
   prevFootRZ# = OBJECT POSITION Z(endModelNum +1)
   prevFootL# = NPCmov(playerNum,36)
   prevFootLX# = OBJECT POSITION X(endModelNum +2)
   prevFootLZ# = OBJECT POSITION Z(endModelNum +2)

   
  `Movement
   move = 0: curveSpeed# = 70 / deltaTime#: acc# = (0.025 + speedplus# ):`*(prevFootR#+prevFootL#) :`acc# = (0.025 + speedplus# ) :  `* deltaTime# :Rem acc#=0.0006 * deltaTime# , curveSpeed#=20 
   walking = 1   
   
    if keystate(17)=1
      ay# = curveangle(camAY#, ay#, curveSpeed#)
      NPCmov(playerNum,4) = ay# 
      move = 1
      `NPCmov(playerNum,30) = 1
   endif
   if keystate(30)=1
      ay# = curveangle(camAY# - 90, ay#, curveSpeed#)
      NPCmov(playerNum,4) = ay# 
      move = 1
      `NPCmov(playerNum,30) = 1 
   endif
   if keystate(31)=1
      ay# = curveangle(camAY# + 180, ay#, curveSpeed#)
      NPCmov(playerNum,4) = ay# 
      move = 1
      `NPCmov(playerNum,30) = 1
   endif
   if keystate(32)=1
      ay# = curveangle(camAY# + 90, ay#, curveSpeed#)
      NPCmov(playerNum,4) = ay# 
      move = 1
      `NPCmov(playerNum,30) = 1
   endif
   
   `hide/show active models
   `IF counter = 10
       `FOR x = startModelNum + to EndModelNum
           `HIDE OBJECT x
       `NEXT x
       `SET ALPHA MAPPING ON  currentModelNum, 100
       `SHOW OBJECT currentModelNum
       `SHOW OBJECT startModelNum
   `ENDIF
   `----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
   `ATTACK IF MOUSECLICK
   `Attackphase  = 1 If mouseclick, and attackphase  = 0
   IF (MOUSECLICK() = 1) AND (attackPhase = 0)
       attackPhase = 1
       NPCmov(1,34) = 1
       move = 0
   ENDIF 
   `Attackphase  = 2 If mouseclick, and attackphase  = 1 AND attack animation 1 is at the end
   IF (MOUSECLICK() = 1) AND (attackPhase = 1) AND (OBJECT FRAME (startModelNum) > 567 + 1 + 706 -9)
       attackPhase = 2
       NPCmov(1,34) = 2
       move = 0
   ENDIF
   `Attackphase  = 1 If mouseclick, and attackphase  = 2 AND attack animation 2 is at the end
   IF (MOUSECLICK() = 1) AND (attackPhase = 2) AND (OBJECT FRAME (startModelNum) > 567 + 1 + 740 -8)
       attackPhase = 1
       NPCmov(1,34) = 1
       move = 0
   ENDIF
   
   `Play idle animation if finished attack in attackphase = 1  
   IF (OBJECT FRAME (startModelNum) > 567 + 1 + 706 -1) AND (attackPhase = 1)
       STOP OBJECT  (startModelNum)
       LOOP OBJECT (startModelNum), 567 +1, 567 + 1 +31
       attackPhase = 0
       NPCmov(1,34) = 0
   ENDIF
   
   `play attack  animation 1 if attackphase = 1
   IF attackPhase = 1 
       move = 0
       STOP OBJECT  (startModelNum)
       LOOP OBJECT (startModelNum),  567 + 1 + 670,567 + 1 + 706
   ENDIF
   `play attack animation 2 if attackphase = 2
   IF attackPhase = 2
       move = 0
       STOP OBJECT  (startModelNum)
       LOOP OBJECT (startModelNum),  567 + 1 + 707,567 + 1 + 741
   ENDIF
   
   `Play idle animation if finishing attack in attackphase = 1   
   IF (OBJECT FRAME (startModelNum) > 567 + 1 + 706 -1) AND (attackPhase = 1)
       STOP OBJECT  (startModelNum)
       LOOP OBJECT (startModelNum), 567 +1, 567 + 1 +31
       attackPhase = 0
       NPCmov(1,34) = 0
   ENDIF
   `Play idle animation if finished attack in attackphase = 2   
   IF (OBJECT FRAME (startModelNum) > 567 + 1 + 740 -1) AND (attackPhase = 2)
       STOP OBJECT  (startModelNum)
       LOOP OBJECT (startModelNum), 567 +1, 567 + 1 +31
       attackPhase = 0
       NPCmov(1,34) = 0
   ENDIF
  `----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
   
   `Attack damage dealing stuff
   IF attackphase > 0
       targetHit = OBJECT COLLISION(102,0)
       IF (targetHit < 100) 
       IF (targetHit> characterNum) AND (NPCCombat(characterNum, targetHit, 1) = 0)
           NPCStatus(targetHit,1) = NPCStatus(targetHit,1) - 5
           NPCCombat(characterNum, targetHit, 1) = 1
       ENDIF
       ENDIF
   ENDIF
      
   IF (attackphase = 1) AND (OBJECT FRAME (startModelNum) > 567 + 1 + 706 -1)
       FOR x = 1 TO 100
            NPCCombat(characterNum, x, 1) = 0
       NEXT x
   ENDIF
   IF (attackphase = 1) AND (OBJECT FRAME (startModelNum) = 567 + 1 + 670)
       FOR x = 1 TO 100
            NPCCombat(characterNum, x, 1) = 0
       NEXT x
   ENDIF
   
   IF (attackphase = 2) AND (OBJECT FRAME (startModelNum) > 567 + 1 + 740 -1)
       FOR x = 1 TO 100
            NPCCombat(characterNum, x, 1) = 0
       NEXT x
   ENDIF
   IF (attackphase = 2) AND (OBJECT FRAME (startModelNum) = 567 + 1 + 707)
       FOR x = 1 TO 100
            NPCCombat(characterNum, x, 1) = 0
       NEXT x
   ENDIF
  `----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
   
   `If Move = 1 then move player , play animations,
   IF move = 1 AND (attackPhase = 0)
       vx# = vx# + newxvalue(0, ay#, acc#)
       vz# = vz# + newzvalue(0, ay#, acc#)
       vy# = vy# + newYvalue(0, ay#, acc#)
       
       `vx#= newxvalue(OBJECT POSITION X(startModelNum), ay#, acc#)
       `vz#= newzvalue(OBJECT POSITION Z(startModelNum), ay#, acc#)
                                                
       FOR x = startModelNum TO endModelNum
           YROTATE OBJECT x, ay#
       NEXT x
        
       WINDFACTOR# = 1000
           `IF (OBJECT FRAME (currentModelNum) < 110) OR (OBJECT FRAME (currentModelNum) >129)
               STOP OBJECT (startModelNum) 
               `LOOP OBJECT currentModelNum, 80, 109  :`walking
               `LOOP OBJECT currentModelNum , 110, 129   :`running
               LOOP OBJECT (startModelNum) , 567 + 1 + 234  , 567 + 1+ 253  :`running
           `ENDIF
       ELSE   `if move = 0
               
               `IF (OBJECT FRAME (currentModelNum ) >109) AND (OBJECT FRAME (currentModelNum) <130)
                   `STOP OBJECT currentModelNum
                   `LOOP OBJECT currentModelNum, 186, 207
               `ENDIF
               `IF (OBJECT FRAME (currentModelNum) = 206) OR (OBJECT FRAME (currentModelNum) <80)
                   `STOP OBJECT currentModelNum
                   `LOOP OBJECT currentModelNum, 0, 79
               `ENDIF
               
               ` IF object frame is in walking animation, then paly stopping animation
               IF (OBJECT FRAME (startModelNum ) > (567+ 1 + 234)) AND (OBJECT FRAME (startModelNum) <(567 + 1 + 254))
                   STOP OBJECT (startModelNum)
                   LOOP OBJECT (startModelNum), 567 + 1 + 174, 567 + 1 + 193
               ENDIF
               `IF object frame is at the end of stopping OR in idle aniamtion, then play idle animation
               IF (OBJECT FRAME (startModelNum) = 567 + 1+ 193 -1) OR (OBJECT FRAME (startModelNum) <(567 + 1 +31 +1 ))
                   STOP OBJECT (startModelNum)
                   LOOP OBJECT (startModelNum), 567 +1, 567 + 1 +31
               ENDIF
   ENDIF
     
 `----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  
   `Calculate player position before collision + gravity
   cx#= OBJECT position x(characterNum) + vx# * deltaTime#*15
   cz#= OBJECT position z(characterNum) + vz# * deltaTime#*15
   `cy#= OBJECT position Y(characterNum) - 1 * deltaTime#*15
   cy#= OBJECT position Y(characterNum) -2
       
   `Collision calculation
   SET OBJECT COLLISION OFF swordObj
   charHit = object collision(characterNum,0)
    `if charHit > 500
       collisionx#=cx# -get object collision x()
       collisiony#=cy# -get object collision y()
       collisionz#=cz# -get object collision z()
    `ENDIF
    
   `Position player after collision
   POSITION OBJECT characterNum, collisionx#, collisiony#, collisionz#
   FOR x = startModelNum TO endModelNum
   `FOR x = startModelNum TO (startModelNum +1)
       `POSITION OBJECT x, cx#, collisiony#, cz#
       POSITION OBJECT x, collisionx#, collisiony#, collisionz#
   NEXT x
   SET OBJECT COLLISION ON swordObj
     
   POSITION LIGHT 1, OBJECT position x(characterNum), OBJECT position Y(characterNum)+200, OBJECT position z(characterNum)
   POSITION OBJECT endModelNum +1, LIMB POSITION X(startModelNum , 30), LIMB POSITION Y(startModelNum , 30), LIMB POSITION Z(startModelNum , 30)
   POSITION OBJECT endModelNum +2, LIMB POSITION X(startModelNum , 33), LIMB POSITION Y(startModelNum , 33), LIMB POSITION Z(startModelNum , 33)
   
   `SET EFFECT POSITIONS
   set vector4 1,OBJECT position x(characterNum), OBJECT position Y(characterNum)+200, OBJECT position z(characterNum),0.0
   `set vector4 1,OBJECT position x(2), OBJECT position Y(2)+200, OBJECT position z(2),0.0
   set effect constant vector 1,"LP_1",1
   set effect constant vector 1,"LP_2",1
   set effect constant vector 1,"LP_3",1
   set effect constant vector 1,"LP_4",1
   set effect constant vector 1,"LP_5",1
   set effect constant vector 1,"LP_6",1
   set effect constant vector 1,"LP_7",1
   set effect constant vector 1,"LP_8",1
   
   currentFootRX# = OBJECT POSITION X(endModelNum +1)
   currentFootRZ# = OBJECT POSITION Z(endModelNum +1)
   prevFootR# = dist2D(currentFootRX#,currentFootRZ#,prevFootRX#,prevFootRZ#)
   currentFootLX# = OBJECT POSITION X(endModelNum +2)
   currentFootLZ# = OBJECT POSITION Z(endModelNum +2)
   prevFootL# = dist2D(currentFootLX#,currentFootLZ#,prevFootLX#,prevFootLZ#)
  
      
   for i = 1 to int(deltaTime#) + 1
      vx# = vx# / 1.03: vz# = vz# / 1.03    `vx# = vx# / 1.003: vz# = vz# / 1.003
   next i
   v# = sqrt(vx#^2 + vz#^2) * 360
   `Move
           x# = x# + vx# * deltaTime#
           z# = z# + vz# * deltaTime#
   
      
        NPCmov(playerNum,1) = x#
        NPCmov(playerNum,2) = y#
        NPCmov(playerNum,3) = z#
        NPCmov(playerNum,4) = ay#
        NPCmov(playerNum,5) = vx#
        NPCmov(playerNum,6) = vy#
        NPCmov(playerNum,7) = vz#
        NPCmov(playerNum,8) = v#
       
        NPCmov(playerNum,29) = footsine#
        NPCmov(playerNum,34) = attackPhase
        NPCmov(playerNum,35) = prevFootR#
        NPCmov(playerNum,36) = prevFootL#
       
ENDFUNCTION
'###############################################################################################################################################

FUNCTION PositionParts( characterNum , limbNum , partNum , addAngleX , addAngleY , addAngleZ , offsetAngleX , offsetAngleY , offsetAngleZ , offsetX# , offsetY# , offsetZ# )
    `rotate z if want to rotate x
    `rotate x if want to rotate y
    `rotate y if want to rotate z
    posLag# = 1.5
    angleLag# = 1.5
        
    characterModel = (characterNum*20)+500
    `partAngleX# = LIMB DIRECTION X(characterModel, limbNum)
    `partAngleY# = LIMB DIRECTION Y(characterModel, limbNum)
    `partAngleZ# = LIMB DIRECTION Z(characterModel, limbNum)
    ```partAngleX# = LIMB DIRECTION Z(characterModel, limbNum)
    ```partAngleY# = LIMB DIRECTION X(characterModel, limbNum)
    ```partAngleZ# = LIMB DIRECTION Y(characterModel, limbNum)
    partAngleX# = CURVEANGLE(LIMB DIRECTION X(characterModel, limbNum)+ addAngleX, OBJECT ANGLE X(partNum), angleLag#)
    partAngleY# = CURVEANGLE(LIMB DIRECTION Y(characterModel, limbNum)+ addAngleY, OBJECT ANGLE Y(partNum), angleLag#)
    partAngleZ# = CURVEANGLE(LIMB DIRECTION Z(characterModel, limbNum)+ addAngleZ, OBJECT ANGLE Z(partNum), angleLag#)
    
    limbPosX# = CURVEVALUE(LIMB POSITION X(characterModel, limbNum), OBJECT POSITION X(partNum) , posLag#)
    limbPosY# = CURVEVALUE(LIMB POSITION Y(characterModel, limbNum), OBJECT POSITION Y(partNum) , posLag#)
    limbPosZ# = CURVEVALUE(LIMB POSITION Z(characterModel, limbNum), OBJECT POSITION Z(partNum) , posLag#)
    POSITION OBJECT partNum, limbPosX#, limbPosY#, limbPosZ#
    `POSITION OBJECT partNum, LIMB POSITION X(characterModel, limbNum), LIMB POSITION Y(characterModel, limbNum), LIMB POSITION Z(characterModel, limbNum)
    OFFSET LIMB partNum, 0, offsetX#, offsetY#, offsetZ#
    `ROTATE OBJECT partNum, partAngleX# + 70, partAngleY#, partAngleZ#
    `ROTATE LIMB partNum, 0, 0, 90, 0
    ROTATE OBJECT partNum, partAngleX# , partAngleY# , partAngleZ#
    `ROTATE OBJECT partNum, partAngleX# + addAngleX, partAngleY# + addAngleY , partAngleZ# + addAngleZ
    ROTATE LIMB partNum, 0, offsetAngleX, offsetAngleY, offsetAngleZ
    
    

ENDFUNCTION

'###############################################################################################################################################

FUNCTION Make_NPC( ObjNum , modelPath$ , footLeft , footRight , dummycubeObjNum)
    `Make body
        
        `````load object "media/GreenHeart/green base.x",NPC1
        `load object "media/GreenHeart/green modified.x",NPC1 `load greenheart green trimmed chest.x
        load object modelPath$,ObjNum
        scale object ObjNum, 270,270,270 `scale greenheart
        ```scale object NPC1, 500,500,500 `scale blue alloy
        ```set object transparency NPC1, 4  `set blue alloy transparency for orbs, ect
        set object cull ObjNum,0
        set object light ObjNum, 1
        set object emissive ObjNum, RGB(200,200,200)
        ```set object diffuse NPC1, RGB(255,255,255), 0
        ```set object specular power NPC1, 500
        set object specular ObjNum, RGB(20,20,20)
        ```set shadow shading on NPC1, 1, 100, 0
        ```set object effect NPC1,1
        `set alpha mapping on ObjNum, 20
        make object collision box objNum,-30,-10,-30,30,200,30,0
        `SHOW OBJECT BOUNDS objNum      
              
                    `Black texture
                    set object emissive ObjNum, RGB(1,1,1) :set object diffuse ObjNum, RGB(1,1,1)
                    set object wireframe ObjNum, 1
                    
        `rotate inital NPC limb
        'rotate limb NPC1, 71, 40, 0, 0
        'rotate limb NPC1, 73, 40, 0, 0
        'rotate limb NPC1, 81, 40, 0, 0
        'rotate limb NPC1, 91, 40, 0, 0
                
    
    `Make feet
        `footLeft = 2
        make object sphere footLeft, 15
        `automatic object collision footleft,0.001,0
        make object collision box footleft,-8,-8,-8,8,8,8,0
        set shadow shading on footleft, -1,1000,1
        set alpha mapping on footleft,0
        `hide object footLeft
        `footRight = 3
        make object sphere footRight, 15
        `automatic object collision footRight,0.001,0
        make object collision box footRight,-8,-8,-8,8,8,8,0
        set shadow shading on footright, -1,1000,1
        set alpha mapping on footright,0
        `hide object footright
    rem Initial position
        position object footLeft, 0 , 0,0
        position object footRight, 0 , 0,0
        position object objNum,  0, 0,0
            `position object footLeft, matrixwidth/2, get ground height(1, matrixwidth/2,matrixlength/2),matrixlength/2
            `position object footRight, matrixwidth/2, get ground height(1, matrixwidth/2,matrixlength/2),matrixlength/2
            `position object Dunya,  matrixwidth/2, get ground height(1, matrixwidth/2,matrixlength/2),matrixlength/2
    rem make dummy cube for NPC head direction
        dummycube = 4
        make object cube dummycubeObjNum,10
        position object dummycubeObjNum, object position x(objNum), object position y(objNum)+ 190, object position z(objNum)
        hide object dummycubeObjNum
   
ENDFUNCTION
'###############################################################################################################################################

`_Walking_Sequence:
function walking_sequence( body , footLeft , footRight  , leftHip , leftKnee , rightHip , rightKnee , dummycube , NPCnum ) 

IF NPClogics(NPCnum,3) = 0
rem if want to rotate x axis, then rotate y axis
rem if want to rotate z axis, then rotate x axis
rem if want to rotate  y axis, rotate z axis 

 x# = NPCmov(NPCnum,1)
 y# = NPCmov(NPCnum,2)
 z# = NPCmov(NPCnum,3)
 ay# = NPCmov(NPCnum,4)
        vx# = NPCmov(NPCnum,5)
        vy# = NPCmov(NPCnum,6)
        vz# = NPCmov(NPCnum,7)
        v# = NPCmov(NPCnum,8)
        rightmove = NPCmov(NPCnum,9)
        leftmove = NPCmov(NPCnum,10)
        oldleftx# = NPCmov(NPCnum,11)
        oldlefty# = NPCmov(NPCnum,12)
        oldleftz# = NPCmov(NPCnum,13)
        leftx# = NPCmov(NPCnum,14)
        lefty# = NPCmov(NPCnum,15)
        leftz# = NPCmov(NPCnum,16)
        oldrightx# = NPCmov(NPCnum,17)
        oldrighty# = NPCmov(NPCnum,18)
        oldrightz# = NPCmov(NPCnum,19)
        rightx# = NPCmov(NPCnum,20)
        righty# = NPCmov(NPCnum,21)
        rightz# = NPCmov(NPCnum,22)
        footsine# = NPCmov(NPCnum,29)
   groundheightL# = NPCmov(NPCnum,32)
   groundheightR# = NPCmov(NPCnum,33)
        

      
`MOVEMENTS
  ` Time
   'deltaTime# = timer() - time#
   'time# = timer()
  
   `Movement
   move = 0: curveSpeed# = 20: acc# = (0.0006 + speedplus#) * deltaTime# :Rem acc#=0.0003 * deltaTime# , curveSpeed#=20
   walking = 1   
   remstart
   if keystate(17)=1
      ay# = curveangle(camAY#, ay#, curveSpeed#)
      move = 1
   endif
   if keystate(30)=1
      ay# = curveangle(camAY# - 90, ay#, curveSpeed#)
      move = 1
   endif
   if keystate(31)=1
      ay# = curveangle(camAY# + 180, ay#, curveSpeed#)
      move = 1
   endif
   if keystate(32)=1
      ay# = curveangle(camAY# + 90, ay#, curveSpeed#)
      move = 1
   endif
   remend
   
'----------------------------------------------------------------------------------------------------------------------------------------------    
   remstart
   `Following player if conditons fullfilled
        dunyaplayerdist# = dist3d ( object position x(body) , object position y(body) , object position z(body), camera position x(0) , (camera position y(0)-180) , camera position z(0) )
                                                    
        If following =1 and  ( dunyaplayerdist# > 180) 
                                                                                        
            ay# = curveangle(object angle y(dummycube), ay# , curveSpeed#) :`direct Dunya to player
            
            move = 1
                                                                      
        endif
     remend   
    
    'Movement_logics( NPCnumber , NPC , headcube ) 
    move = NPCmov(NPCnum,30)                                            
'----------------------------------------------------------------------------------------------------------------------------------------------    
                                               `text 10,260, "move = " + str$ (move) 
                                                `text 300,200, "NPCmov(1,4) = " + str$(NPCmov(NPCnum,4))
   `Velocity
   if move = 1
       vx# = vx# + newxvalue(0, ay#, acc#)
       vz# = vz# + newzvalue(0, ay#, acc#)
       vy# = vy# + newzvalue(0, ay#, acc#)
                                                
       Yrotate object body, ay#
       'rotate limb body, 0, 0 , ay# , 0                                                           
                                                
       WINDFACTOR# = 1000
   endif
                
                 
   
   If move = 0
        'WINDFACTOR# = -10000 + rnd(20000)
        WINDFACTOR# = 50
   endif
                     
      
   `Speed up 
   remstart
   if mouseclick()=2
           inc speedplus#, 0.0001  
           WINDFACTOR#=20000
       endif
   if mouseclick()<>2 then speedplus# = 0
   remend

   
   for i = 1 to int(deltaTime#) + 1
      vx# = vx# / 1.003: vz# = vz# / 1.003    `vx# = vx# / 1.003: vz# = vz# / 1.003
   next i
   v# = sqrt(vx#^2 + vz#^2) * 360
   `Move
           x# = x# + vx# * deltaTime#
           z# = z# + vz# * deltaTime#
   `Position
   `Position object body, x#, y#, z#    
           footx#=(object position x(footRight) + object position x(footLeft)) / 2  + vx# * deltaTime#
           footz#=(object position z(footRight) + object position z(footLeft)) / 2  + vx# * deltaTime#
   
      
   

   `Reset 
   'print footSine#
   if move = 0 and walking = 0
      if footSine# > 180
         footSine# = 0
      else
         footSine# = 180
      endif
   endif
   `Footsine
   footSine# = footSine# + 0.5 * deltaTime#
   if footSine# > 360 then footSine# = footSine# - 360

   
   
   `Left foot movement
           width# = 5 : walking = 0    :rem width# = 7
           if footSine# < 180
                  if leftMove = 0
                                           
                     oldleftx# = object position x(footleft): oldleftz# = object position z(footleft)
                     oldlefty# = object position y(footleft)
                     leftx# = newxvalue(footx#, ay# - 90, width#)
                     leftz# = newzvalue(footz#, ay# - 90, width#)
                     leftx# = newxvalue(leftx#, ay#, v#)
                     leftz# = newzvalue(leftz#, ay#, v#)
                     `lefty# = get ground height(1, leftx#, leftz#)
                     
                     
                     
                           `Left foot groundheight detection
                           `Checking the highest groundheight
                            grounddistL# = intersect object (terrainNum,  leftx#, object position y (footleft)+160 + 100000, leftz#,      leftx#,  -5000, leftz# ) 
                           `Calculating ground height
                            If (groundDistL# > 0) or (groundDistL# < 0)
                                groundheightL# = object position y (footleft)+160 +100000 - grounddistL#
                                else groundheightL# = object position y (body)
                            endif
                            NPCmov(NPCnum,32) = groundheightL#
                            `text 1500,200, " groundheightL " + str$ (groundheightL#)
                            `text 1500,220, " grounddistL " + str$ (grounddistL#)
                     
                     
                     lefty# = groundheightL#
                        
                            `Left foot collision detection - prevent climbing too high
                            stepHeight# = lefty# - oldlefty#
                            if (stepHeight# > 150) `or (stepHeight# < -150)
                               lefty# = oldlefty#
                               `for x = startObj to lastObj
                                  leftHit = OBJECT COLLISION(body,0)
                                  IF leftHit > 499
                                  `If object exist(x)
                                  `if (object collision(body,x) > 0) 
              
                                     ```cx#= object position x(footleft) -(get object collision x())
                                     ```cy#= object position y(footleft)-(get object collision y())
                                     ```cz#= object position z(footleft)-(get object collision z())
                                     ```position object footleft, cx#, cy# ,cz#
                                     leftx# = leftx# -(get object collision x())
                                     ```lefty#= lefty# -(get object collision y())
                                     leftz# = leftz# -(get object collision z())
                                          
                                    `Slow down vx#, vz#
                                     NPCmov(NPCnum,5) = NPCmov(NPCnum,5) *0.1    ` vx
                                     vx# = vx# *0.1
                                     NPCmov(NPCnum,7) = NPCmov(NPCnum,7) *0.1    `vz
                                     vz# = vz# *0.1
                                     NPCmov(NPCnum,6) = NPCmov(NPCnum,6) *0.1     `vy
                                     vy# = vy# *0.1
                                  `endif
                                  Endif  
                               `Next
                               leftMove = 1
                               rightMove = 1
                               move = 0
                            Endif
                           
                     leftMove = 1
                  endif
              fx# = oldleftx# + (leftx#-oldleftx#) * footSine#/180
              fz# = oldleftz# + (leftz#-oldleftz#) * footSine#/180
              fy# = oldlefty# + (lefty#-oldlefty#) * footSine#/180
                  if sqrt((oldleftx#-leftx#)^2 + (oldleftz#-leftz#)^2) > 10
                     position object footLeft, fx#, fy# + sin(footSine#) * 10, fz#        :rem position object footLeft, fx#, fy# + sin(footSine#) * 10, fz#
                     walking = 1
                  endif
              `position object footLeft, leftx#, 0 + sin(footSine#) * 0, leftz#
           else
              leftMove = 0
           endif
           
   `Right foot movement
           if footSine# > 180
              if rightMove = 0
                                           
                 oldrightx# = object position x(footRight): oldrightz# = object position z(footRight)
                 oldrighty# = object position y(footRight)
                 rightx# = newxvalue(footx#, ay# + 90, width#)
                 rightz# = newzvalue(footz#, ay# + 90, width#)
                 rightx# = newxvalue(rightx#, ay#, v#)
                 rightz# = newzvalue(rightz#, ay#, v#)
                 `righty# = get ground height(1, rightx#, rightz#)
                 
                 
               
                      `RIght foot groundheight detection    
                       grounddistR# = intersect object (terrainNum, rightx#,  object position y (footright)+160 +100000, rightz#,     rightx#,  -5000, rightz#) 
                      `If height detection available, groundhesight is present
                       If (groundDistR# > 0) or (groundDistR# < 0)
                           groundheightR# = object position y (footright)+160 +100000 - grounddistR#
                       else groundheightR# = object position y (body)
                       endif
                       NPCmov(NPCnum,33) = groundheightR#
                       `text 1500,240, " groundheightR " + str$ (groundheightR#)
                       `text 1500,260, " grounddistR " + str$ (grounddistR#)
                 
                 
                 
                 righty# = groundheightR#
                       
                     
                       `Collision detection right foot - to prevent climbing too high
                       stepHeight# = righty# - oldrighty#
                       if (stepHeight# > 150) `or (stepHeight# < -150)
                            righty# = oldrighty#
                          
                            `for x = startObj to lastObj
                               `If object exist(x) 
                               `if (object collision(body,x) > 0)
                            rightHit = OBJECT COLLISION(body,0)
                            IF rightHit > 499 
                                  ```cx#= object position x(footright) -(get object collision x())
                                  ```cy#= object position y(footright)-(get object collision y())
                                  ```cz#= object position z(footright)-(get object collision z())
                                  ```position object footleft, cx#, cy# ,cz#
                                      rightx# = rightx# -(get object collision x())
                                      ```righty# = righty#-(get object collision y())
                                      rightz# = rightz#-(get object collision z())
                                  `Slow down vx#, vz#
                                      NPCmov(NPCnum,5) = NPCmov(NPCnum,5) *0.1    ` vx#
                                      vx# = vx# *0.1
                                      NPCmov(NPCnum,7) = NPCmov(NPCnum,7) *0.1    `vz#
                                      vz# = vz# *0.1
                                      NPCmov(NPCnum,6) = NPCmov(NPCnum,6) *0.1    `vy#  
                                      vy# = vy# *0.1
                               `endif
                               Endif
                            `next
                            leftMove = 1
                            rightMove = 1
                            move = 0
                         Endif        
                                    
                     rightMove = 1
              endif
              fx# = oldrightx# + (rightx#-oldrightx#) * (footSine#-180)/180
              fz# = oldrightz# + (rightz#-oldrightz#) * (footSine#-180)/180
              fy# = oldrighty# + (righty#-oldrighty#) * (footSine#-180)/180
              if sqrt((oldrightx#-rightx#)^2 + (oldrightz#-rightz#)^2) > 10
                 position object footright, fx#, fy# - sin(footSine#) * 10, fz#
                 walking = 1
              endif
              `position object footright, rightx#, 0- sin(footSine#) * 0, rightz#
           else
              rightMove = 0
           endif

  
   `body position
           px# = (object position x(footRight) + object position x(footLeft)) / 2
           pz# = (object position z(footRight) + object position z(footLeft)) / 2
           py# = (object position y(footRight) + object position y(footLeft)) / 2
           maxy# = 57            :rem maxy#=57
           dist# = dist3d(object position x(footright), object position y(footright), object position z(footright),object position x(footleft), object position y(footleft), object position z(footleft))/3
           value# = (dist# / maxy#) : rem * 0.1 , 0.3                                      :rem Up and down sway  : value# = (dist# / maxy#)
           if value#>1 then value# = 1
           if value#<-1 then value#=-1
           angle# = acos(value#)
           'py# = py# + sin(angle#)*maxy#
           py# = (py#) + sin(angle#)*maxy# 
           POSITION object body, px#, py#, pz#     :rem position body
                                            
           YROTATE object body, ay#                :rem modified body rotation
                                 
   
   

   `orientation vector
           r=make vector3(1)
           set vector3 1, newxvalue(0,ay#,1),0,newzvalue(0,ay#,1)
           r=make vector3(2)
           set vector3 2, 0, 1, 0
           cross product vector3 2, 1, 2
        Rem Sway body left-right
           sway# = sin(footSine#)*3*v#/33
           px# = px# - x vector3(2) *sway# *0.2     :rem  px# = px# - x vector3(2) *sway#   
           pz# = pz# - z vector3(2) *sway# *0.2
           position object body, px#, py#-60, pz#
   `position rotate leg left
           legoffset# = 10  :rem legoffset#=10
           legx# = newxvalue(px#, ay# - 90, legoffset#)
           legz# = newzvalue(pz#, ay# - 90, legoffset#)
           legy# = py#
   `difference vector
           r=make vector3(3)
           set vector3 3, object position x(footLeft)-legx#, object position y(footLeft)-legy#, object position z(footLeft)-legz#
           temp1# =dot product vector3(1,3)
           temp2# = dot product vector3(2,3)
           temp3# = legy# - object position y(footLeft)
   `basic rotate left limb
           legaz# = atanfull(0-temp2#, temp3#)
           legax# = atanfull(0-temp1#, temp3#)
   rem add left knee bend
           length# = 58.5
           dist# = dist3d(legx#,legy#,legz#,object position x(footLeft),object position y(footLeft),object position z(footLeft))
           value#=(dist#/length#)
           if value#>1 then value# = 1
           if value#<-1 then value#=-1
           kneea# = acos(value#)
   `rotate left hip & knee
           rotate limb body, leftHip, (-legax# + kneea# -10), 0, (legaz#*0.2)  :rem hip rotate limb legleft, 0, legax# - kneea#, 0, legaz#
             `if (legax# - kneea# + 10) <0
                `leftkneebend# = (legax# - kneea# + 20)
             `endif
           rotate limb body, leftKnee, (-2*kneea# ) + leftkneebend#*0.7 + 20, 0 , 0        :rem knee rotate limb legleft, 1, 2*kneea#, 0, 0
           
   
   
   `position rotate leg right
           legoffset# = 10
           legx# = newxvalue(px#, ay# + 90, legoffset#)
           legz# = newzvalue(pz#, ay# + 90, legoffset#)
           legy# = py#
   `difference vector
           r=make vector3(3)
           set vector3 3, object position x(footright)-legx#, object position y(footright)-legy#, object position z(footright)-legz#
           temp1# =dot product vector3(1,3)
           temp2# = dot product vector3(2,3)
           temp3# = legy# - object position y(footright)
   `basic rotate
           legaz# = atanfull(0-temp2#, temp3#)
           legax# = atanfull(0-temp1#, temp3#)
   `add right knee bend
           length# = 58.5
           dist# = dist3d(legx#,legy#,legz#,object position x(footright),object position y(footright),object position z(footright))
           value#=(dist#/length#)
           if value#>1 then value# = 1
           if value#<-1 then value#=-1
           kneea# = acos(value#)
   `rotate right hip & knee
           rotate limb body, rightHip, (-legax# + kneea# -10), 0, (legaz#*0.2)   :rem hip rotate limb legright, 0, legax# - kneea#, 0, legaz#
             `if (legax# - kneea# + 10) <0
                `rightkneebend# = (legax# - kneea# + 20)
             `endif
           rotate limb body, rightKnee, (-2*kneea# ) + rightkneebend#*0.7 + 20, 0 , 0                                :rem knee rotate limb legright, 1, 2*kneea#, 0, 0
         
           
        NPCmov(NPCnum,1) = x#
        NPCmov(NPCnum,2) = y#
        NPCmov(NPCnum,3) = z#
        NPCmov(NPCnum,4) = ay#
        NPCmov(NPCnum,5) = vx#
        NPCmov(NPCnum,6) = vy#
        NPCmov(NPCnum,7) = vz#
        NPCmov(NPCnum,8) = v#
        NPCmov(NPCnum,9) = rightmove
        NPCmov(NPCnum,10) = leftmove
        NPCmov(NPCnum,11) = oldleftx#
        NPCmov(NPCnum,12) = oldlefty#
        NPCmov(NPCnum,13) = oldleftz#
        NPCmov(NPCnum,14) = leftx#
        NPCmov(NPCnum,15) = lefty#
        NPCmov(NPCnum,16) = leftz#
        NPCmov(NPCnum,17) = oldrightx#
        NPCmov(NPCnum,18) = oldrighty#
        NPCmov(NPCnum,19) = oldrightz#
        NPCmov(NPCnum,20) = rightx#
        NPCmov(NPCnum,21) = righty#
        NPCmov(NPCnum,22) = rightz#
        'NPCmov(NPCnum,23) = fx#
        'NPCmov(NPCnum,24) = fy#
        'NPCmov(NPCnum,25) = fz#
        NPCmov(NPCnum,29) = footsine#
        NPCmov(NPCnum,32) = groundheightL#
        NPCmov(NPCnum,33) = groundheightR#
ENDIF  

ENDFUNCTION

'##############################################################################################################################################

function hand_swing( body , NPCnum , footleft , footright , leftshoulder , leftelbow , rightshoulder , rightelbow )
`_walking_hand_swing:
swing# = 1

x# = NPCmov(NPCnum,1)
 y# = NPCmov(NPCnum,2)
 z# = NPCmov(NPCnum,3)
 ay# = NPCmov(NPCnum,4)
        vx# = NPCmov(NPCnum,5)
        vy# = NPCmov(NPCnum,6)
        vz# = NPCmov(NPCnum,7)
        v# = NPCmov(NPCnum,8)
        rightmove = NPCmov(NPCnum,9)
        leftmove = NPCmov(NPCnum,10)
        oldleftx# = NPCmov(NPCnum,11)
        oldlefty# = NPCmov(NPCnum,12)
        oldleftz# = NPCmov(NPCnum,13)
        leftx# = NPCmov(NPCnum,14)
        lefty# = NPCmov(NPCnum,15)
        leftz# = NPCmov(NPCnum,16)
        oldrightx# = NPCmov(NPCnum,17)
        oldrighty# = NPCmov(NPCnum,18)
        oldrightz# = NPCmov(NPCnum,19)
        rightx# = NPCmov(NPCnum,20)
        righty# = NPCmov(NPCnum,21)
        rightz# = NPCmov(NPCnum,22)
        footsine# = NPCmov(NPCnum,29)
        
'IF NPClogics(NPCnum,3) = 1
'IF NPClogics(1,3) = 1
`body position
           px# = (object position x(footRight) + object position x(footLeft)) / 2
           pz# = (object position z(footRight) + object position z(footLeft)) / 2
           py# = (object position y(footRight) + object position y(footLeft)) / 2
           maxy# = 57            :rem maxy#=57
           dist# = dist3d(object position x(footright), object position y(footright), object position z(footright),object position x(footleft), object position y(footleft), object position z(footleft))/3
           value# = (dist# / maxy#) : rem * 0.1                                       :rem Up and down sway  : value# = (dist# / maxy#)
           if value#>1 then value# = 1
           if value#<-1 then value#=-1
           angle# = acos(value#)
           'py# = py# + sin(angle#)*maxy#
           py# = (py#) + sin(angle#)*maxy# 
              

   `orientation vector
           r=make vector3(1)
           set vector3 1, newxvalue(0,ay#,1),0,newzvalue(0,ay#,1)
           r=make vector3(2)
           set vector3 2, 0, 1, 0
           cross product vector3 2, 1, 2
        Rem Sway body left-right
           sway# = sin(footSine#)*3*v#/33
           px# = px# - x vector3(2) *sway# *0.2     :rem  px# = px# - x vector3(2) *sway#   
           pz# = pz# - z vector3(2) *sway# *0.2

   
   
   If (NPClogics(NPCnum,3) = 1) 
   elbowA# = 1
   else
   elbowA# = 1
   Endif


   `LEFT HAND SWING
   ` position rotate left shoulder
           legoffset# = 10
           legx# = newxvalue(px#, ay# + 90, legoffset#)
           legz# = newzvalue(pz#, ay# + 90, legoffset#)
           legy# = py#
   ` difference vector
           r=make vector3(3)
           set vector3 3, object position x(footright)-legx#, object position y(footright)-legy#, object position z(footright)-legz#
           temp1# =dot product vector3(1,3)
           temp2# = dot product vector3(2,3)
           temp3# = legy# - object position y(footright)
   ` basic rotate
           'yrotate object legright, ay#
           legaz# = atanfull(0-temp2#, temp3#)
           legax# = atanfull(0-temp1#, temp3#)
   ` add LEFT SHOULDER & elbow bend
           length# = 58
           dist# = dist3d(legx#,legy#,legz#,object position x(footright),object position y(footright),object position z(footright))
           value#=(dist#/length#)
           if value#>1 then value# = 1
           if value#<-1 then value#=-1
           kneea# = acos(value#)
           ````ROTATE LIMB body, leftshoulder, -10, ((legax# - kneea#)*0.3) + 5, -legaz# *2
           ````rotate limb body, leftelbow, 0, 5 + (2*kneea#)*0.2, 0
           ROTATE LIMB body, leftshoulder, legaz# *1 , ((legax# - kneea#)*0.5*swing#) + 5 ,  80      - legax# *0.05*swing#
             if (legax# - kneea# + 10) > 0
                leftelbowbend# = (legax# - kneea# + 20)
             endif
           `rotate limb body, leftelbow, 0 , -5 + (2*kneea#)*0.2* elbowA#*swing# - leftelbowbend#, 0
           rotate limb body, leftelbow, 0 , -5*(elbowA#*1*swing#) + (2*kneea#)*0.2*swing# * elbowA#, 0
                      
    
    `RIGHT HAND SWING
    ` position rotate right shoulder
           legoffset# = 10  :rem legoffset#=10
           legx# = newxvalue(px#, ay# - 90, legoffset#)
           legz# = newzvalue(pz#, ay# - 90, legoffset#)
           legy# = py#
   ` difference vector
           r=make vector3(3)
           set vector3 3, object position x(footLeft)-legx#, object position y(footLeft)-legy#, object position z(footLeft)-legz#
           temp1# =dot product vector3(1,3)
           temp2# = dot product vector3(2,3)
           temp3# = legy# - object position y(footLeft)
           'print temp2#
   ` basic rotate
           'yrotate object legleft, ay#
           'yrotate object body, ay#                :rem modified body rotation
           legaz# = atanfull(0-temp2#, temp3#)
           legax# = atanfull(0-temp1#, temp3#)
   `add right shoulder & elbow bend
           length# = 58
           dist# = dist3d(legx#,legy#,legz#,object position x(footLeft),object position y(footLeft),object position z(footLeft))
           value#=(dist#/length#)
           if value#>1 then value# = 1
           if value#<-1 then value#=-1
           kneea# = acos(value#)
           ````ROTATE LIMB body, rightshoulder, 10, ((legax# - kneea#)*0.3) + 5, -legaz# *2
           ````rotate limb body, rightelbow, 0, 5 + (2*kneea#)*0.2, 0
           ``ROTATE LIMB body, rightshoulder, -legaz# *2, ((legax# - kneea#)*0.3) + 0, -80
           ``rotate limb body, rightelbow, 5 + (2*kneea#)*0.2, 0, 0
           `ROTATE LIMB body, rightshoulder, legaz# *1 + NPClimb(NPCnum,1,1),   ((-legax# + kneea#)*1) -10  + NPClimb(NPCnum,1,2) ,   -80  + legax# *0.05 + NPClimb(NPCnum,1,3)
           ROTATE LIMB body, rightshoulder, legaz# *1*swing#,   ((-legax# + kneea#)*0.5*swing#) -5 ,   -80  + legax# *0.05*swing#
           rotate limb body, rightelbow, 0 , 5*(elbowA#*1*swing#) - (2*kneea#)*0.2*swing# * elbowA#, 0


'ENDIF

ENDFUNCTION

'##############################################################################################################################################
'##############################################################################################################################################


`_Control NPC walking:
function Control_NPC( body , footLeft , footRight  , leftHip , leftKnee , rightHip , rightKnee , dummycube , NPCnum ) 

IF NPClogics(NPCnum,3) = 1

rem if want to rotate x axis, then rotate y axis
rem if want to rotate z axis, then rotate x axis
rem if want to rotate  y axis, rotate z axis 

 x# = NPCmov(NPCnum,1)
 y# = NPCmov(NPCnum,2)
 z# = NPCmov(NPCnum,3)
 ay# = NPCmov(NPCnum,4)
        vx# = NPCmov(NPCnum,5)
        vy# = NPCmov(NPCnum,6)
        vz# = NPCmov(NPCnum,7)
        v# = NPCmov(NPCnum,8)
        rightmove = NPCmov(NPCnum,9)
        leftmove = NPCmov(NPCnum,10)
        oldleftx# = NPCmov(NPCnum,11)
        oldlefty# = NPCmov(NPCnum,12)
        oldleftz# = NPCmov(NPCnum,13)
        leftx# = NPCmov(NPCnum,14)
        lefty# = NPCmov(NPCnum,15)
        leftz# = NPCmov(NPCnum,16)
        oldrightx# = NPCmov(NPCnum,17)
        oldrighty# = NPCmov(NPCnum,18)
        oldrightz# = NPCmov(NPCnum,19)
        rightx# = NPCmov(NPCnum,20)
        righty# = NPCmov(NPCnum,21)
        rightz# = NPCmov(NPCnum,22)
        footsine# = NPCmov(NPCnum,29)
   groundheightL# = NPCmov(NPCnum,32)
   groundheightR# = NPCmov(NPCnum,33)
   
   
   
         

`MOVEMENTS
  ` Time
   'deltaTime# = timer() - time#
   'time# = timer()
  
   `Movement
   move = 0: curveSpeed# = 160 / deltaTime#: acc# = (0.0009 + speedplus# ) * deltaTime# :Rem acc#=0.0006 * deltaTime# , curveSpeed#=20 
   walking = 1   
   
   if keystate(17)=1
      ay# = curveangle(camAY#, ay#, curveSpeed#)
      NPCmov(NPCnum,4) = ay# 
      move = 1
      NPCmov(NPCnum,30) = 1
   endif
   if keystate(30)=1
      ay# = curveangle(camAY# - 90, ay#, curveSpeed#)
      NPCmov(NPCnum,4) = ay# 
      move = 1
      NPCmov(NPCnum,30) = 1 
   endif
   if keystate(31)=1
      ay# = curveangle(camAY# + 180, ay#, curveSpeed#)
      NPCmov(NPCnum,4) = ay# 
      move = 1
      NPCmov(NPCnum,30) = 1
   endif
   if keystate(32)=1
      ay# = curveangle(camAY# + 90, ay#, curveSpeed#)
      NPCmov(NPCnum,4) = ay# 
      move = 1
      NPCmov(NPCnum,30) = 1
   endif
  
   
'----------------------------------------------------------------------------------------------------------------------------------------------    
   remstart
   `Following player if conditons fullfilled
        dunyaplayerdist# = dist3d ( object position x(body) , object position y(body) , object position z(body), camera position x(0) , (camera position y(0)-180) , camera position z(0) )
                                                    
        If following =1 and  ( dunyaplayerdist# > 180) 
                                                                                        
            ay# = curveangle(object angle y(dummycube), ay# , curveSpeed#) :`direct Dunya to player
            
            move = 1
                                                                      
        endif
     remend   
    
    'Movement_logics( NPCnumber , NPC , headcube ) 
    move = NPCmov(NPCnum,30)                                            
'----------------------------------------------------------------------------------------------------------------------------------------------    
                                                `text 10,260, "move = " + str$ (move) 
                                                `text 300,200, "NPCmov(1,4) = " + str$(NPCmov(NPCnum,4))
   `Velocity
   if move = 1
       vx# = vx# + newxvalue(0, ay#, acc#)
       vz# = vz# + newzvalue(0, ay#, acc#)
       vy# = vy# + newzvalue(0, ay#, acc#)
                                                
       Yrotate object body, ay#
       'rotate limb body, 0, 0 , ay# , 0                                                           
                                                
       WINDFACTOR# = 1000
   endif
                
                 
   
   If move = 0
        'WINDFACTOR# = -10000 + rnd(20000)
        WINDFACTOR# = 50
   endif
                     
      
   `Speed up 
   remstart
   if mouseclick()=2
           inc speedplus#, 0.0001  
           WINDFACTOR#=20000
       endif
   if mouseclick()<>2 then speedplus# = 0
   remend

   
   for i = 1 to int(deltaTime#) + 1
      vx# = vx# / 1.003: vz# = vz# / 1.003    `vx# = vx# / 1.003: vz# = vz# / 1.003
   next i
   v# = sqrt(vx#^2 + vz#^2) * 360
   `Move
           x# = x# + vx# * deltaTime#
           z# = z# + vz# * deltaTime#
   `Position
   `Position object body, x#, y#, z#    
           footx#=(object position x(footRight) + object position x(footLeft)) / 2  + vx# * deltaTime#
           footz#=(object position z(footRight) + object position z(footLeft)) / 2  + vx# * deltaTime#
   
      
   

   `Reset 
   'print footSine#
   if move = 0 and walking = 0
      if footSine# > 180
         footSine# = 0
      else
         footSine# = 180
      endif
   endif
   `Footsine
   footSine# = footSine# + 0.5 * deltaTime#
   if footSine# > 360 then footSine# = footSine# - 360

   
   
   `Left foot movement
           width# = 5 : walking = 0    :rem width# = 7
           if footSine# < 180
                  if leftMove = 0
                                           
                     oldleftx# = object position x(footleft): oldleftz# = object position z(footleft)
                     oldlefty# = object position y(footleft)
                     leftx# = newxvalue(footx#, ay# - 90, width#)
                     leftz# = newzvalue(footz#, ay# - 90, width#)
                     leftx# = newxvalue(leftx#, ay#, v#)
                     leftz# = newzvalue(leftz#, ay#, v#)
                     `lefty# = get ground height(1, leftx#, leftz#)
                     
                     
                     
                           `Left foot groundheight detection
                           `Checking the highest groundheight
                            grounddistL# = intersect object (terrainNum,  leftx#, object position y (footleft)+160 + 5000, leftz#,      leftx#,  object position y (footleft)-5000, leftz# ) 
                           `Calculating ground height
                            If (groundDistL# > 0) or (groundDistL# < 0)
                                groundheightL# = object position y (footleft)+160 +5000 - grounddistL#
                                else groundheightL# = object position y (body)
                            endif
                            NPCmov(NPCnum,32) = groundheightL#
                            `text 1500,200, " groundheightL " + str$ (groundheightL#)
                            `text 1500,220, " grounddistL " + str$ (grounddistL#)
                     
                     
                     lefty# = groundheightL#
                        
                           remstart
                           `Left foot collision detection - prevent climbing too high
                            stepHeight# = lefty# - oldlefty#
                            if (stepHeight# > 150) `or (stepHeight# < -150)
                               lefty# = oldlefty#
                               `for x = startObj to lastObj
                                  leftHit = OBJECT COLLISION(body,0)
                                  IF leftHit > 499
                                  `If object exist(x)
                                  `if (object collision(body,x) > 0) 
              
                                     ```cx#= object position x(footleft) -(get object collision x())
                                     ```cy#= object position y(footleft)-(get object collision y())
                                     ```cz#= object position z(footleft)-(get object collision z())
                                     ```position object footleft, cx#, cy# ,cz#
                                     leftx# = leftx# -(get object collision x())
                                     ```lefty#= lefty# -(get object collision y())
                                     leftz# = leftz# -(get object collision z())
                                          
                                    `Slow down vx#, vz#
                                     NPCmov(NPCnum,5) = NPCmov(NPCnum,5) *0.01    ` vx
                                     vx# = vx# *0.1
                                     NPCmov(NPCnum,7) = NPCmov(NPCnum,7) *0.01    `vz
                                     vz# = vz# *0.1
                                     NPCmov(NPCnum,6) = NPCmov(NPCnum,6) *0.01     `vy
                                     vy# = vy# *0.1
                                     NPCmov(NPCnum,8) = NPCmov(NPCnum,8) *0.01    `v#
                                     v# = v# *0.01
                                  `endif
                                  Endif  
                               `Next
                               leftMove = 1
                               rightMove = 1
                               move = 0
                            Endif
                           remend
                           
                                                                                
                           
                     leftMove = 1
                  endif
              fx# = oldleftx# + (leftx#-oldleftx#) * footSine#/180
              fz# = oldleftz# + (leftz#-oldleftz#) * footSine#/180
              fy# = oldlefty# + (lefty#-oldlefty#) * footSine#/180
                  if sqrt((oldleftx#-leftx#)^2 + (oldleftz#-leftz#)^2) > 10
                     position object footLeft, fx#, fy# + sin(footSine#) * 10, fz#        :rem position object footLeft, fx#, fy# + sin(footSine#) * 10, fz#
                     walking = 1
                  endif
              `position object footLeft, leftx#, 0 + sin(footSine#) * 0, leftz#
           else
              leftMove = 0
           endif
   `Right foot movement
           if footSine# > 180
              if rightMove = 0
                                           
                 oldrightx# = object position x(footRight): oldrightz# = object position z(footRight)
                 oldrighty# = object position y(footRight)
                 rightx# = newxvalue(footx#, ay# + 90, width#)
                 rightz# = newzvalue(footz#, ay# + 90, width#)
                 rightx# = newxvalue(rightx#, ay#, v#)
                 rightz# = newzvalue(rightz#, ay#, v#)
                 `righty# = get ground height(1, rightx#, rightz#)
                 
                 
               
                      `RIght foot groundheight detection    
                       grounddistR# = intersect object (terrainNum, rightx#,  object position y (footright)+160 +100000, rightz#,     rightx#,  -5000, rightz#) 
                      `If height detection available, groundhesight is present
                       If (groundDistR# > 0) or (groundDistR# < 0)
                           groundheightR# = object position y (footright)+160 +100000 - grounddistR#
                       else groundheightR# = object position y (body)
                       endif
                       NPCmov(NPCnum,33) = groundheightR#
                       `text 1500,240, " groundheightR " + str$ (groundheightR#)
                       `text 1500,260, " grounddistR " + str$ (grounddistR#)
                 
                 
                 
                 righty# = groundheightR#
                       
                      remstart
                       `Collision detection right foot - to prevent climbing too high
                       stepHeight# = righty# - oldrighty#
                       if (stepHeight# > 150) `or (stepHeight# < -150)
                            righty# = oldrighty#
                          
                            `for x = startObj to lastObj
                               `If object exist(x) 
                               `if (object collision(body,x) > 0)
                            rightHit = OBJECT COLLISION(body,0)
                            IF rightHit > 499 
                                  ```cx#= object position x(footright) -(get object collision x())
                                  ```cy#= object position y(footright)-(get object collision y())
                                  ```cz#= object position z(footright)-(get object collision z())
                                  ```position object footleft, cx#, cy# ,cz#
                                      rightx# = rightx# -(get object collision x())
                                      ```righty# = righty#-(get object collision y())
                                      rightz# = rightz#-(get object collision z())
                                  `Slow down vx#, vz#
                                      NPCmov(NPCnum,5) = NPCmov(NPCnum,5) *0.01    ` vx#
                                      vx# = vx# *0.1
                                      NPCmov(NPCnum,7) = NPCmov(NPCnum,7) *0.01    `vz#
                                      vz# = vz# *0.1
                                      NPCmov(NPCnum,6) = NPCmov(NPCnum,6) *0.01    `vy#  
                                      vy# = vy# *0.1
                                      NPCmov(NPCnum,8) = NPCmov(NPCnum,8) *0.01    `v#
                                      v# = v# *0.01
                               `endif
                               Endif
                            `next
                            leftMove = 1
                            rightMove = 1
                            move = 0
                         Endif
                        remend
                        
                                                 
                                                         
                     rightMove = 1
              endif
              fx# = oldrightx# + (rightx#-oldrightx#) * (footSine#-180)/180
              fz# = oldrightz# + (rightz#-oldrightz#) * (footSine#-180)/180
              fy# = oldrighty# + (righty#-oldrighty#) * (footSine#-180)/180
              if sqrt((oldrightx#-rightx#)^2 + (oldrightz#-rightz#)^2) > 10
                 position object footright, fx#, fy# - sin(footSine#) * 10, fz#
                 walking = 1
              endif
              `position object footright, rightx#, 0- sin(footSine#) * 0, rightz#
           else
              rightMove = 0
           endif

  
   `body position
           px# = (object position x(footRight) + object position x(footLeft)) / 2
           pz# = (object position z(footRight) + object position z(footLeft)) / 2
           py# = (object position y(footRight) + object position y(footLeft)) / 2
           maxy# = 57            :rem maxy#=57
           dist# = dist3d(object position x(footright), object position y(footright), object position z(footright),object position x(footleft), object position y(footleft), object position z(footleft))/3
           value# = (dist# / maxy#) : rem * 0.1 , 0.3                                      :rem Up and down sway  : value# = (dist# / maxy#)
           if value#>1 then value# = 1
           if value#<-1 then value#=-1
           angle# = acos(value#)
           'py# = py# + sin(angle#)*maxy#
           py# = (py#) + sin(angle#)*maxy# 
           POSITION object body, px#, py#, pz#     :rem position body
                                            
           YROTATE object body, ay#                :rem modified body rotation
                                 
   
   

   `orientation vector
           r=make vector3(1)
           set vector3 1, newxvalue(0,ay#,1),0,newzvalue(0,ay#,1)
           r=make vector3(2)
           set vector3 2, 0, 1, 0
           cross product vector3 2, 1, 2
        Rem Sway body left-right
           sway# = sin(footSine#)*3*v#/33
           px# = px# - x vector3(2) *sway# *0.2     :rem  px# = px# - x vector3(2) *sway#   
           pz# = pz# - z vector3(2) *sway# *0.2
           position object body, px#, py#-60, pz#
   `position rotate leg left
           legoffset# = 10  :rem legoffset#=10
           legx# = newxvalue(px#, ay# - 90, legoffset#)
           legz# = newzvalue(pz#, ay# - 90, legoffset#)
           legy# = py#
   `difference vector
           r=make vector3(3)
           set vector3 3, object position x(footLeft)-legx#, object position y(footLeft)-legy#, object position z(footLeft)-legz#
           temp1# =dot product vector3(1,3)
           temp2# = dot product vector3(2,3)
           temp3# = legy# - object position y(footLeft)
   `basic rotate left limb
           legaz# = atanfull(0-temp2#, temp3#)
           legax# = atanfull(0-temp1#, temp3#)
   rem add left knee bend
           length# = 58.5
           dist# = dist3d(legx#,legy#,legz#,object position x(footLeft),object position y(footLeft),object position z(footLeft))
           value#=(dist#/length#)
           if value#>1 then value# = 1
           if value#<-1 then value#=-1
           kneea# = acos(value#)
   `rotate left hip & knee
           rotate limb body, leftHip, (-legax# + kneea# -10), 0, (legaz#*0.2)  :rem hip rotate limb legleft, 0, legax# - kneea#, 0, legaz#
             `if (legax# - kneea# + 10) <0
                `leftkneebend# = (legax# - kneea# + 20)
             `endif
           rotate limb body, leftKnee, (-2*kneea# ) + leftkneebend#*0.7 + 20, 0 , 0        :rem knee rotate limb legleft, 1, 2*kneea#, 0, 0
           
   
   
   `position rotate leg right
           legoffset# = 10
           legx# = newxvalue(px#, ay# + 90, legoffset#)
           legz# = newzvalue(pz#, ay# + 90, legoffset#)
           legy# = py#
   `difference vector
           r=make vector3(3)
           set vector3 3, object position x(footright)-legx#, object position y(footright)-legy#, object position z(footright)-legz#
           temp1# =dot product vector3(1,3)
           temp2# = dot product vector3(2,3)
           temp3# = legy# - object position y(footright)
   `basic rotate
           legaz# = atanfull(0-temp2#, temp3#)
           legax# = atanfull(0-temp1#, temp3#)
   `add right knee bend
           length# = 58.5
           dist# = dist3d(legx#,legy#,legz#,object position x(footright),object position y(footright),object position z(footright))
           value#=(dist#/length#)
           if value#>1 then value# = 1
           if value#<-1 then value#=-1
           kneea# = acos(value#)
   `rotate right hip & knee
           rotate limb body, rightHip, (-legax# + kneea# -10), 0, (legaz#*0.2)   :rem hip rotate limb legright, 0, legax# - kneea#, 0, legaz#
             `if (legax# - kneea# + 10) <0
                `rightkneebend# = (legax# - kneea# + 20)
             `endif
           rotate limb body, rightKnee, (-2*kneea# ) + rightkneebend#*0.7 + 20, 0 , 0                                :rem knee rotate limb legright, 1, 2*kneea#, 0, 0
           
        NPCmov(NPCnum,1) = x#
        NPCmov(NPCnum,2) = y#
        NPCmov(NPCnum,3) = z#
        NPCmov(NPCnum,4) = ay#
        NPCmov(NPCnum,5) = vx#
        NPCmov(NPCnum,6) = vy#
        NPCmov(NPCnum,7) = vz#
        NPCmov(NPCnum,8) = v#
        NPCmov(NPCnum,9) = rightmove
        NPCmov(NPCnum,10) = leftmove
        NPCmov(NPCnum,11) = oldleftx#
        NPCmov(NPCnum,12) = oldlefty#
        NPCmov(NPCnum,13) = oldleftz#
        NPCmov(NPCnum,14) = leftx#
        NPCmov(NPCnum,15) = lefty#
        NPCmov(NPCnum,16) = leftz#
        NPCmov(NPCnum,17) = oldrightx#
        NPCmov(NPCnum,18) = oldrighty#
        NPCmov(NPCnum,19) = oldrightz#
        NPCmov(NPCnum,20) = rightx#
        NPCmov(NPCnum,21) = righty#
        NPCmov(NPCnum,22) = rightz#
        'NPCmov(NPCnum,23) = fx#
        'NPCmov(NPCnum,24) = fy#
        'NPCmov(NPCnum,25) = fz#
        NPCmov(NPCnum,29) = footsine#
        NPCmov(NPCnum,32) = groundheightL#
        NPCmov(NPCnum,33) = groundheightR# 
  ENDIF   

ENDFUNCTION

'##############################################################################################################################################


Function Movement_Logics( NPCnum , body , dummycube)
        IF object exist(body)
        following = NPClogics(NPCnum,1) 
        ay# = NPCmov(NPCnum,4) 
    
    `Following player
        dunyaplayerdist# = dist3d ( object position x(body) , object position y(body) , object position z(body), camera position x(0) , (camera position y(0)-180) , camera position z(0) )
                          
        If following =1 and  ( dunyaplayerdist# > 180) 
            ay# = curveangle(object angle y(dummycube), ay#, curveSpeed#)
            move = 1
        endif
        
        If following =0
            move = 0
        Endif
        
        NPCmov(NPCnum,4) = ay#
        NPCmov(NPCnum,30) = move
        
        ENDIF

ENDFUNCTION

'##############################################################################################################################################

Function Head_Turn( dummycube , body , head , NPCnum )


REM HEAD & DUMMY CUBE ORIENTATION
        dummyax# = NPCmov(NPCnum,23)
        dummyay# = NPCmov(NPCnum,24)
        dummyaz# = NPCmov(NPCnum,25)
        headax# = NPCmov(NPCnum,26)
        headay# = NPCmov(NPCnum,27)
        headaz# = NPCmov(NPCnum,28)

 

`Dummy orientation
    position object dummycube, object position x(body), object position y(body)+ 160, object position z(body)
    point object dummycube, camera position x(0), camera position y(0)+ 3 , camera position z (0)
    dummyax# = object angle x(dummycube) :dummyaz# = object angle z(dummycube) :dummyay# = object angle y(dummycube)

`Head orientation
    'headax# = curveangle (dummyax#, headax#, 17)
    'headaz# = curveangle (dummyaz#, headaz#, 17)
    'headay# = curveangle (dummyay#  - object angle y(body) - NPCmov(NPCnum,4) , headay#, 17 )
    
    If NPClogics(NPCnum,3) = 0
         headay# = curveangle (dummyay#  - object angle y(body)  , headay#, 17 )
         NPCmov(NPCnum,27) = headay#
         headax# = curveangle (dummyax#, headax#, 17)
         headaz# = curveangle (dummyaz#, headaz#, 17)
    ENDIF
    if NPClogics(NPCnum,3)  = 1
         headay# = curveangle (camera angle y() - object angle y(body) , headay#, 17 )
         NPCmov(NPCnum,27) = headay#
         headax# = curveangle (-dummyax#, headax#, 17)
         headaz# = curveangle (-dummyaz#, headaz#, 17)
    ENDIF
`Limit head rotation
    if (headay# > 85) and  (headay# < 180) then headay# = 85
    if (headay# < 275) and  (headay# => 180) then headay# = 275
`Rotate head
    ''''Rotate limb body, head, headax#-8 - (2500/(Playerdist#^2)), headay#, 0
    Rotate limb body, head, -headax#  ,  -headay#  , 0
    
 
        NPCmov(NPCnum,23) = dummyax#
        NPCmov(NPCnum,24) = dummyay#
        NPCmov(NPCnum,25) = dummyaz#
        NPCmov(NPCnum,26) = headax#
        NPCmov(NPCnum,27) = headay#
        NPCmov(NPCnum,28) = headaz#
  
  
    
ENDFUNCTION

'##############################################################################################################################################

_Camera_Movement:
    `CAMERA
   `cameray# : direction the camera will be moving to
   `cvx# cvz# : camera velocity
   `cx# cz# cy# : camera position
   
   IF KEYSTATE(59)
       camDist# = 1000
       camHeight# = 250
       focusObj =  currentCharObj   
       cameraType = 1
   ENDIF
   IF KEYSTATE(60)
       camDist# = 20
       camHeight# = 0 
       focusObj = (currentCharObj*20) + 500   
       cameraType = 2
   ENDIF
   
   
   
   camAX# = wrapvalue(camAX# + mousemovey()*0.1)
   camAY# = wrapvalue(camAY# + mousemovex()*0.1)
   camAZ# = camAZ# + mousemovez()*0.1
      
   `smoothing camera rotation
   cameravx# = wrapvalue(curveangle( camAX#, cameravx#, 5) )
   cameravy# = wrapvalue(curveangle( camAY#, cameravy#, 5) )
   cameravz# = curveValue( camAZ#, cameravz#, 1 * deltaTime# )
   `rotate camera 0, camAX#, camAY#, 0
   rotate camera 0, cameravx#, cameravy#, 0
   `rotate OBJECT cameraObj, cameravx#, cameravy#, 0
                 
   
   
   `Move camera
   if cameramove=1
   cvx# = cvx# + newxvalue(0, cameray#, acce#)
   cvz# = cvz# + newzvalue(0, cameray#, acce#)
   cvy# = cvy# + newYvalue(0, cameray#, acce#)
   endif
      
   IF cameraType = 1
   cx#= OBJECT POSITION X(currentCharObj) + cvx# * deltaTime#
   cz#= OBJECT POSITION Z(currentCharObj) + cvz# * deltaTime#
   ```cy#= get ground height (1,camera position x(0) , camera position z(0) ) +camheight#
   ``cy#= object position y (NPC1) +camheight#
   cy#= OBJECT POSITION Y(currentCharObj) + cvY# * deltaTime# + camheight#
   ENDIF
   
   IF cameraType = 2
   cx#= LIMB POSITION X((currentCharObj*20) + 500 , 43) + cvx# * deltaTime#
   cz#= LIMB POSITION Z((currentCharObj*20) + 500 , 43) + cvY# * deltaTime# + camheight#
   ```cy#= get ground height (1,camera position x(0) , camera position z(0) ) +camheight#
   ``cy#= object position y (NPC1) +camheight#
   cy#= LIMB POSITION Y((currentCharObj*20) + 500 , 43) + cvz# * deltaTime#           
   ENDIF
   
   
   `time-based movement & sliding effect 
   for i = 1 to int(deltaTime#) + 1
      cvx# = cvx# / 1.03: cvz# = cvz# / 1.03: cvy# = cvy# / 1.03
      `cvx# = cvx# / 1.015: cvz# = cvz# / 1.015
   next i
      
        
        
        
                           
       `Zoom In/out
       ```cameraHit = OBJECT COLLISION(10000,0)
       ```IF cameraHit = 0
       Position camera 0, cx#, cy#, cz#
       ```Position camera 0, OBJECT POSITION X(currentCharObj), OBJECT POSITION Y(currentCharObj), OBJECT POSITION Z(currentCharObj)
       `POSITION OBJECT cameraObj, cx#, cy#, cz#
       ```move camera 0, -camDist# + mousez()*0.1
       `If playerDist# > camDist#  
           `move camera 0, -camDist# + mousez()*0.0001*(playerDist#)
           oldcamPos# = camPos#
           camPos# = CURVEVALUE( -camDist# + (camAZ#*0.005*(playerDist#)), camPos#, 40)
           move camera 0, camPos#
           ```MOVE OBJECT 10000, camPos#
           `POSITION OBJECT cameraObj, CAMERA POSITION X(0), CAMERA POSITION Y(0), CAMERA POSITION Z(0)
           `move camera 0, -camDist# + (camAZ#*0.0005*(playerDist#)) 
       `Endif
       REMSTART
       If (playerDist# < camDist#)  or (playerDist# = camDist#)
           ````move camera 0, -camDist# + mousez()*0.1
           camPos# = CURVEVALUE(-camDist# + (camAZ#*1.0), camPos#, 40)
           move camera 0, camPos#
           MOVE OBJECT 1, camPos#
           `move camera 0, -camDist# + (camAZ#*1.0) 
       Endif
       REMEND
       `ENDIF
       
       remstart
       `Camera collision   
        FOR X = 1 TO 3
       `POSITION OBJECT 1, camera position x(0), camera position y(0), camera position z(0)
       SET OBJECT COLLISION OFF currentCharObj
       cameraHit = OBJECT COLLISION(cameraObj,0)
       IF cameraHit > 490
           collisionDIst# = -INTERSECT OBJECT(cameraHit, OBJECT POSITION X(currentCharObj), OBJECT POSITION Y(currentCharObj), OBJECT POSITION Z(currentCharObj), OBJECT POSITION X(cameraObj), OBJECT POSITION Y(cameraObj), OBJECT POSITION Z(cameraObj))
           ```colDIst1# = INTERSECT OBJECT(cameraHit, OBJECT POSITION X(10000), OBJECT POSITION Y(10000), OBJECT POSITION Z(10000), OBJECT POSITION X(currentCharObj), OBJECT POSITION Y(currentCharObj), OBJECT POSITION Z(currentCharObj))
           ```colDist2# = dist3D( OBJECT POSITION X(currentCharObj), OBJECT POSITION Y(currentCharObj), OBJECT POSITION Z(currentCharObj), OBJECT POSITION X(10000), OBJECT POSITION Y(10000), OBJECT POSITION Z(10000) ) 
           ```collisionDist# = -colDIst2# + colDIst1# +0
           camPos# = CURVEVALUE(collisionDist#, camPos#, 1)
           Position camera 0, cx#, cy#, cz#
           move camera 0, camPos# 
           POSITION OBJECT cameraObj, camera position x(0), camera position y(0), camera position z(0)
        ENDIF
        SET OBJECT COLLISION ON currentCharObj
        NEXT X
        remend
        
             
       
   rem zoom in/out   
   `move camera 0, -camDist#+ (mousez()*0.1)
   
   Rem adjust camera height
   `if mouseclick() = 3  
        `if keystate(17)= 1 then inc camheight#,1
        `if keystate(31)= 1 then dec camheight#,1
   `endif
   
   rem keep mouse above ground
       If camera position y (0) < OBJECT POSITION Y(currentCharObj) + 15
           Position camera 0, camera position x(0), OBJECT POSITION Y(currentCharObj) +16, camera position z(0)
       Endif
       
   
   rem prevent camera turning up/down too much
   if  (camAX# < 310 and camAX# > 180) then camAX# = 310        :rem Limit down
   if (camAX# >60 and camAX# <=180) then camAX# = 60            :rem Limit up
   
   `if (camAX# >80 ) then camAX# = 80            :rem Limit down
   if  (cameravx# < 310 and cameravx# => 180) then cameravx# = 310        :rem Limit down
   if (cameravx# > 60 and cameravx# <=90 ) then cameravx# = 60            :rem Limit up
RETURN

'##############################################################################################################################################
_NPC_Initialize:

`NPC1 variable/ Green heart limbs
 NPC1 = 1
 dummycube = currentCharObj+3
 footLeft = currentCharObj+1
 footRight = currentCharObj+2
        dunyahead = 64
        dunyatorso = 16
        dunyahip = 2
        dunyaleftHip = 4
        dunyaleftKnee = 5
        dunyarightHip = 9
        dunyarightKnee = 10
        dunyaleftShoulder = 19
        dunyaleftElbow = 22
        dunyarightShoulder = 41
        dunyarightElbow = 44
              blueNeck = 17
              blueTorso = 10
              bluehip = 7
              blueLeftHip = 29
              blueLeftKnee = 30
              blueRightHip = 34
              blueRightKnee = 35
              blueLeftShoulder = 12
              blueLeftElbow = 13
              blueRightShoulder = 25
              blueRightElbow = 26
              
  `Make NPC2 body/Iris Heart limbs
        NPC2 = 20
  `Limbs List
        NPC2head = 59
        NPC2torso = 16
        NPC2hip = 2
        NPC2leftHip = 4
        NPC2leftKnee = 5
        NPC2rightHip = 7
        NPC2rightKnee = 8
        NPC2leftShoulder = 14
        NPC2leftElbow = 17
        NPC2rightShoulder = 37
        NPC2rightElbow = 40
    `Make feet
        NPC2footLeft = 21
        NPC2footRight = 22
        NPC2dummycube = 23
        
        
     `global rightmove : global leftmove                                                  :`EXCLUSIVE
    
                     `global oldleftx# : global oldleftz# :global oldlefty#              :`EXCLUSIVE
                     `global leftx#
                     `global leftz#
                     `global lefty# 
                     
                 `global oldrightx# : global oldrightz#  :global oldrighty#              :`EXCLUSIVE
                 `global rightx#
                 `global rightz# 
                 `global righty# 
                     
              `''global fx#                                                                :`EXCLUSIVE
              `''global fz#                                                                :`EXCLUSIVE
              `''global fy#                                                                :`EXCLUSIVE
    
    
    
    
    
        speed# = 0.1: acc# = 0
        x# = 0: y# = 50: z# = 0                                                          :`EXCLUSIVE
        ay# = 0
        vx# = 0: vy# = 0: vz# = 0
        speedplus#=0
                
        v# = 0
        footsine# = 180
        
        `Array for movement variables
        global dim NPCmov(10,40) as float
        NPCmov(1,1) = x#
        NPCmov(1,2) = y#
        NPCmov(1,3) = z#
        NPCmov(1,4) = ay#
        NPCmov(1,5) = vx#
        NPCmov(1,6) = vy#
        NPCmov(1,7) = vz#
        NPCmov(1,8) = v#
        NPCmov(1,9) = rightmove
        NPCmov(1,10) = leftmove
        NPCmov(1,11) = oldleftx#
        NPCmov(1,12) = oldlefty#
        NPCmov(1,13) = oldleftz#
        NPCmov(1,14) = leftx#
        NPCmov(1,15) = lefty#
        NPCmov(1,16) = leftz#
        NPCmov(1,17) = oldrightx#
        NPCmov(1,18) = oldrighty#
        NPCmov(1,19) = oldrightz#
        NPCmov(1,20) = rightx#
        NPCmov(1,21) = righty#
        NPCmov(1,22) = rightz#
        NPCmov(1,23) = dummyax#
        NPCmov(1,24) = dummyay#
        NPCmov(1,25) = dummyaz#
        NPCmov(1,26) = headax#
        NPCmov(1,27) = headay#
        NPCmov(1,28) = headaz#
        NPCmov(1,29) = footsine#
        NPCmov(1,30) = move
        NPCmov(1,31) = blinking
        NPCmov(1,32) = highestgroundheightL# : highestgroundheightL# = 0
        NPCmov(1,33) = highestgroundheightR# : highestgroundheightR# = 0
        NPCmov(1,34) = attackPhase
        
        `Array for NPC logics
        global dim NPClogics(3,10) as float
        NPClogics(1,1) = following
        NPClogics(1,2) = sitting
        NPClogics(1,3) = NPCcontrol
        
        `Array for Limb Angles
        global dim NPClimb(3,100,3) as float
        NPClimb(1,1) = rightshoulder
        NPClimb(1,2) = rightelbow
        NPClimb(1,3) = rightwrist
        NPClimb(1,4) = rightthumb1
        NPClimb(1,5) = rightthumb2
        NPClimb(1,6) = rightthumb3
        NPClimb(1,7) = rightindex1
        NPClimb(1,8) = rightindex2
        NPClimb(1,9) = rightindex3
        NPClimb(1,10) = rightmid1
        NPClimb(1,11) = rightmid2
        NPClimb(1,12) = rightmid3
        NPClimb(1,13) = rightring1
        NPClimb(1,14) = rightring2
        NPClimb(1,15) = rightring3
        NPClimb(1,16) = rightlittle1
        NPClimb(1,17) = rightlittle2
        NPClimb(1,18) = rightlittle3
            NPClimb(1,19) = leftshoulder
            NPClimb(1,20) = leftelbow
            NPClimb(1,21) = leftwrist
            NPClimb(1,22) = leftthumb1
            NPClimb(1,23) = leftthumb2
            NPClimb(1,24) = leftthumb3
            NPClimb(1,25) = leftindex1
            NPClimb(1,26) = leftindex2
            NPClimb(1,27) = leftindex3
            NPClimb(1,28) = leftmid1
            NPClimb(1,29) = leftmid2
            NPClimb(1,30) = leftmid3
            NPClimb(1,31) = leftring1
            NPClimb(1,32) = leftring2
            NPClimb(1,33) = leftring3
            NPClimb(1,34) = leftlittle1
            NPClimb(1,35) = leftlittle2
            NPClimb(1,36) = leftlittle3
        NPClimb(1,37) = rightHip
        NPClimb(1,38) = rightKnee
        NPClimb(1,39) = rightAnkle
        NPClimb(1,40) = rightToe11
        NPClimb(1,41) = rightToe12
        NPClimb(1,42) = rightToe13
        NPClimb(1,43) = rightToe21
        NPClimb(1,44) = rightToe22
        NPClimb(1,45) = rightToe23
        NPClimb(1,46) = rightToe31
        NPClimb(1,47) = rightToe32
        NPClimb(1,48) = rightToe33
        NPClimb(1,49) = rightToe41
        NPClimb(1,50) = rightToe42
        NPClimb(1,51) = rightToe43
        NPClimb(1,52) = rightToe51
        NPClimb(1,53) = rightToe52
        NPClimb(1,54) = rightToe53
            NPClimb(1,55) = leftHip
            NPClimb(1,56) = leftKnee
            NPClimb(1,57) = leftAnkle
            NPClimb(1,58) = leftToe11
            NPClimb(1,59) = leftToe12
            NPClimb(1,60) = leftToe13
            NPClimb(1,61) = leftToe21
            NPClimb(1,62) = leftToe22
            NPClimb(1,63) = leftToe23
            NPClimb(1,64) = leftToe31
            NPClimb(1,65) = leftToe32
            NPClimb(1,66) = leftToe33
            NPClimb(1,67) = leftToe41
            NPClimb(1,68) = leftToe42
            NPClimb(1,69) = leftToe43
            NPClimb(1,70) = leftToe51
            NPClimb(1,71) = leftToe52
            NPClimb(1,72) = leftToe53
            
        `Array for NPC status
        DIM NPCStatus(10,30)
        NPCStatus(1,1) = HP : NPCStatus(1,1) = 50 : NPCStatus(2,1) = 50
        NPCStatus(1,2) = stamina
        
        `Array for NPC combat parameters : playerNum, terget hitted , parameters
        DIM NPCCombat(10,100, 30)
        NPCCombat(1,1,1) = attackHit
        NPCCombat(1,1,2) = damage
        
        `Array for NPC equipments
        DIM NPCEquipment(100, 30)
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''            
    REMSTART
    `Init camera variables
        Global camAY# as float
        camAY# = 0: camAX# = 0
        camDist# = 1000
        camheight# = 200
        position camera 0, 0, 0, 0
        XROTATE camera 0, camAX#
        'position camera 0,matrixwidth/2 + 40, get ground height(1, matrixwidth/2,matrixlength/2), matrixlength/2
    REMEND
RETURN

'##############################################################################################################################################

_TOGGLE_CHATBOX:

    Update_Keystate()
     
    `turn mouse and chatbox on/off
    `Turn on mouse, on chatbox
        if escapekey()=1 and chatbox=0
            if freemouse=0
            chatbox=1
            freemouse=1
            endif
        endif
    rem prevent consecutive on/off, must release key to off  again    
        if escapekey()=0 and chatbox=1 and freemouse=1 then freemouse=0
    rem off mouse, off chatbox    
        if escapekey()=1 and chatbox=1 and freemouse=0 
            chatbox=0  
            freemouse=1
        endif
    rem prevent consecutive on/off. must release key to on again    
        if escapekey()=0 and chatbox=0 and freemouse=1 then freemouse=0
        
        
    If chatbox=0
        position mouse screen width()/2,screen height()/2
        hide mouse
        'If (text background type()=1) then set text transparent
        'If text size()>1 then     set text size 1
    Endif
    
    If chatbox=1  
        show mouse
        If (text background type()=0) then set text opaque
        If text size() < 22 then set text size 18
                
        rem Read the keybaord input and send it out as a chat line where necessary
           gosub _handle_chat_key_input
           
           `Handle Chatlines
        gosub _handle_sending_chatline
        
           rem Show chat line as user types it (chatline$ is use in _handle_chat_key_input)
           chatlinebase = endofplayerlist + 415
        
           rem Draw some lines around the chat area to make it a bit more obvious
           'gosub _draw_chat_box
           text 10, chatlinebase, " SEND:" + chatline$
        
        
           rem Print out the total count of messages sent and received in the bottom right
           rem corner of the screen.
           'text screen width() - 1 - text width("Sent: " + str$(msgoutcount)), screen height() - 30, "Sent: " + str$(msgoutcount)
           'text screen width() - 1 - text width("Received: " + str$(msgincount)), screen height() - 15, "Recieved: " + str$(msgincount)
        
        
       Endif
    
        chatbase = chatlinebase + 15
        gosub _show_chat
        
RETURN

'##############################################################################################################################################

 
'##############################################################################################################################################

FUNCTION makeBox( boxObjNum, limbNum , meshNum , width# , height# , depth# , alpha , red , green , blue , x# , y# , z# )
`Make boxes as part of terrain 
        
           `Make new box to attach as limb to terrain object
           
            MAKE OBJECT CYLINDER boxObjNum, width#
            SCALE OBJECT boxObjNum, 100, 1, 100
                        
            `make object box boxObjNum, width#, height#, depth#
            
            ```instance object boxObjNum, 400
            color object boxObjNum, RGB(red,green,blue)
            set object diffuse boxObjNum, RGB(red,green,blue)
            ```````set object specular boxObjNum, RGB(red,green,blue)
            set object ambience boxObjNum, RGB(red,green,blue)
            ```````texture object boxObjNum, 1
            set alpha mapping on boxObjNum, alpha
            position object boxObjNum, x#,y#,z#
            set shadow shading on boxObjNum,-1,10000,1
            `hide object boxObjNum
                
            `REMSTART
           `Make limb from mesh
            `make mesh from object meshNum, boxObjNum
            `add limb terrainNum, limbNum, meshNum
            'add limb terrainNum, limbNum, originBox
            'scale limb terrainNum, limbNum, 100*width#, 100*height#, 100*depth#
            'offset limb terrainNum, limbNum, x#, y#, z#
            'hide limb terrainNum, limbNum
            `color limb terrainNum, limbNum, RGB(red,green,blue)
            `delete mesh meshNum
            `REMEND
        
        `Set up collision
            make object collision box boxObjNum, -20 -((width#)*0.5), -(height#)*0.5,  -70 -((depth#)*0.50) , 20 + ((width#)*0.5) , (height#)*0.5 , 80+ ((depth#)*0.5) , 0
ENDFUNCTION
'#########################################################################################################################################################################
FUNCTION FillLevel( dungeonLevel , levelSize, BoxSize , ROTATE ,  tex , bumpTex )
     boxSize = BoxSize
     baseSquareNum = levelSize
     dungeonLevel = dungeonLevel
     `startLimb = limbNum
     
     `FOR x = (lastObj+1) to (lastObj+1 + (baseSquareNum*baseSquareNum))
     FOR x = (lastObj+1) to (lastObj + (baseSquareNum*baseSquareNum)) 
         MAKE OBJECT BOX x, boxSize,boxSize,boxSize
         `SET OBJECT COLLISION TO BOXES x
         `SET OBJECT COLLISION TO POLYGONS x
         TEXTURE OBJECT x, 0, tex
         TEXTURE OBJECT x, 1, bumpTex
         `SET BUMP MAPPING ON x, bumpTex
         `SCALE OBJECT TEXTURE x,0,0.02,0.02
         `SCALE OBJECT TEXTURE x,1,0.02,0.02
         SET OBJECT EFFECT x,1
         ROTATE OBJECT x, -RND(ROTATE) + RND(ROTATE*2), -RND(ROTATE) + RND(ROTATE*2), -RND(ROTATE) + RND(ROTATE*2)
         MAKE OBJECT COLLISION BOX x, -(boxSize/2)*1.2,-(boxSize/2),-(boxSize/2)*1.2, (boxSize/2)*1.2,(boxSize/2),(boxSize/2)*1.2, 0
         `SET OBJECT CULL x, 0
         `SET SHADOW SHADING ON x,-1,30,1
         `SET OBJECT EMISSIVE x, RGB(255,255,255)
         `SET OBJECT DIFFUSE x, RGB(0,0,0)
         `SET OBJECT SPECULAR x, RGB(50,50,50)
         `SET OBJECT SPECULAR POWER x, 1000
         `SHOW OBJECT BOUNDS x, 1
         
         `add limb terrainNum, x-500, originBox
         `scale limb terrainNum, x-500, boxSize, boxSize, boxSize
     NEXT x
     
     `Arrange boxes
     FOR x = 0 TO (baseSquareNum-1)
         FOR z = 0 TO (baseSquareNum-1)
             POSITION OBJECT (lastObj +1 + z)+(x*baseSquareNum),       x*boxSize, dungeonLevel*boxSize, z*boxSize
             `offset limb terrainNum, (lastObj-500 + 1 + z)+(x*baseSquareNum), x*boxSize, dungeonLevel*boxSize, z*boxSize
             `hide limb terrainNum, (startLimb+1 + z)+(x*baseSquareNum)
         NEXT z
     NEXT x 
     lastObj = lastObj + (baseSquareNum*baseSquareNum)
     `limbNum = lastObj- 500 + (baseSquareNum*baseSquareNum)
     
     
ENDFUNCTION

'#########################################################################################################################################################################
FUNCTION DigCorridor( corridorNum , dungeonLevel , xStart , zStart , xEnd , zEnd )
     boxSize = 500
     xCurrent = xStart
     zCurrent = zStart
     direction = 1
     
     `Calculate path
     `DIM dungeonPath(dungeonLevel500,2)
     FOR X= 0 to (400)
         buildAxis = RND(1) +1  : `directions 1=+x, 2=-x, 3=+z, 4=-z
         dungeonPath(corridorNum,dungeonLevel ,x,1) = xCurrent
         dungeonPath(corridorNum,dungeonLevel ,x,2) = zCurrent
         dungeonPath(corridorNum,dungeonLevel ,x,3) = direction
         dungeonPath(corridorNum,dungeonLevel ,x,3) = dungeonLevel
         
         IF buildAxis = 1
         IF xEnd > xCurrent
             `xCurrent = xCUrrent + 1
             `dungeonPath(dungeonLevel,x,1) = xCurrent
             `dungeonPath(dungeonLevel,x,2) = zCurrent
             xCurrent = xCurrent + 1
             direction = 1
         ENDIF
         IF xEnd < xCurrent
             `xCurrent = xCUrrent - 1
             `dungeonPath(dungeonLevel,x,1) = xCurrent
             `dungeonPath(dungeonLevel,x,2) = zCurrent
             xCurrent = xCurrent - 1
             direction = 2
         ENDIF
         ENDIF
         
         IF buildAxis = 2
         IF zEnd > zCurrent
             `zCurrent = zCurrent + 1
             `dungeonPath(dungeonLevel,x,1) = xCurrent
             `dungeonPath(dungeonLevel,x,2) = zCurrent
             zCurrent = zCurrent + 1
             direction = 3
         ENDIF
         IF zEnd < zCurrent
             `zCurrent = zCurrent - 1
             `dungeonPath(dungeonLevel,x,1) = xCurrent
             `dungeonPath(dungeonLevel,x,2) = zCurrent
             zCurrent = zCurrent - 1
             direction = 4
         ENDIF
         ENDIF
     NEXT X
     
     `Carve dungeon
     FOR Z = 1 TO 4
     FOR X= 0 to (400)
         POSITION OBJECT 498, dungeonPath(corridorNum,dungeonLevel ,x,1)*boxSize, dungeonLevel*boxSize , dungeonPath(corridorNum,dungeonLevel ,x,2)*boxSize
         HIT = object collision(498,0)
         IF HIT >0
         IF OBJECT EXIST(HIT) > 0
             SET OBJECT COLLISION OFF HIT
             HIDE OBJECT HIT
             `POSITION OBJECT HIT, OBJECT POSITION X(HIT), 10000, OBJECT POSITION Z(HIT)
             `offset limb terrainNum, HIT - 500, Object position x (HIT), Object position y (HIT) -5000, Object position z (HIT)
         ENDIF
         ENDIF
     NEXT X
     NEXT Z
ENDFUNCTION

'###########################################################################################################################################################################
FUNCTION DigRoom( roomNum , dungeonLevel , roomSize, startX, startZ )
    boxSize = 500
    xStart = startX 
    zStart = startZ
    xEnd = startX + roomSize - 1
    zEnd = startZ + roomSize - 1 
    
       
    FOR Z= 0 TO (roomsize-1)
    FOR X= 0 TO (roomsize-1)
        dungeonRoom(roomNum,dungeonLevel ,x + (z*roomsize),1) = xStart + x
        dungeonRoom(roomNum,dungeonLevel ,x + (z*roomsize),2) = zStart + z
        dungeonRoom(roomNum,dungeonLevel ,x + (z*roomsize),3) = 1
        dungeonRoom(roomNum,dungeonLevel ,x + (z*roomsize),4) = dungeonLevel
    NEXT X
    NEXT Z
    
    FOR Z = 1 TO 4
    FOR X= 0 TO ((roomsize*roomsize)-1)
        `POSITION OBJECT 498, dungeonRoom(roomNum,x,1)*1000, dungeonLevel*2 , dungeonRoom(roomNum,x,2)*1000
        POSITION OBJECT 498, dungeonRoom(roomNum,dungeonLevel ,x,1)*boxSize, dungeonLevel*boxSize , dungeonRoom(roomNum,dungeonLevel ,x,2)*boxSize
        HIT = object collision(498,0)
        IF HIT >0
        IF OBJECT EXIST(HIT) > 0
            SET OBJECT COLLISION OFF HIT
            HIDE OBJECT HIT
            `POSITION OBJECT HIT, OBJECT POSITION X(HIT), 10000, OBJECT POSITION Z(HIT)
            `offset limb terrainNum, HIT - 500, Object position x (HIT), Object position y (HIT) -5000, Object position z (HIT)
        ENDIF
        ENDIF
    NEXT x
    NEXT Z
ENDFUNCTION
'###########################################################################################################################################################################

FUNCTION MakeRoom( roomNum , dungeonLevel , roomSizeX , roomSizeZ , startX , startZ , tex , bumpTex )
    boxSize = 500
    xEnd = startX + roomSizeX - 1
    zEnd = startZ + roomSizeZ - 1
    
    IF roomSizeX > roomSizeZ
    FOR Z= 0 TO (roomsizeZ-1)
    FOR X= 0 TO (roomsizeX-1)
        dungeonRoom(roomNum,dungeonLevel ,x + (z*roomsizeX),1) = xStart + x
        dungeonRoom(roomNum,dungeonLevel ,x + (z*roomsizeX),2) = zStart + z
        dungeonRoom(roomNum,dungeonLevel ,x + (z*roomsizeX),3) = 1
        dungeonRoom(roomNum,dungeonLevel ,x + (z*roomsizeX),4) = dungeonLevel
    NEXT X
    NEXT Z 
    ENDIF
    
    IF roomSizeZ > roomSizeX
    FOR X= 0 TO (roomsizeX-1)
    FOR Z= 0 TO (roomsizeZ-1)
        dungeonRoom(roomNum,dungeonLevel ,z + (x*roomsizeZ),1) = xStart + x
        dungeonRoom(roomNum,dungeonLevel ,z + (x*roomsizeZ),2) = zStart + z
        dungeonRoom(roomNum,dungeonLevel ,z + (x*roomsizeZ),3) = 1
        dungeonRoom(roomNum,dungeonLevel ,z + (x*roomsizeZ),4) = dungeonLevel
    NEXT Z 
    NEXT X
    ENDIF
    
    FOR X= 0 TO ((roomsizeX*roomsizeZ)-1)
         rem Make floor
         `MAKE OBJECT PLANE lastObj+1+x, boxSize, boxSize
         MAKE OBJECT BOX lastObj+1+x, boxSize,boxSize,boxSize
         MAKE OBJECT COLLISION BOX lastObj+1+x, -boxSize/2,-boxSize/2,-boxSize/2, boxSize/2,boxSize/2,boxSize/2, 0
         SET OBJECT EFFECT lastObj+1+x,1
         `XROTATE OBJECT lastObj+1+x, 10
         `YROTATE OBJECT lastObj+1+x, 90
         TEXTURE OBJECT lastObj+1+x, 0, tex
         TEXTURE OBJECT lastObj+1+x, 1, bumpTex
         SET OBJECT EFFECT lastObj+1+x,1
         `SET BUMP MAPPING ON lastObj+1+x, bumpTex
         `SET OBJECT CULL lastObj+1+x, 0
         `SHOW OBJECT BOUNDS lastObj+1+x , 1
         POSITION OBJECT lastObj+1+x, dungeonRoom(roomNum,dungeonLevel ,x,1)*boxSize, (dungeonLevel*boxSize) - (boxSize/2) , dungeonRoom(roomNum,dungeonLevel ,x,2)*boxSize
        lastObj = lastObj +1
        
        `IF x = xStart, then make left wall
        IF dungeonRoom(roomNum,dungeonLevel ,x,1) = xStart
        FOR p = 0 to 1
           `MAKE OBJECT PLANE lastObj+1+x, boxSize, boxSize
           MAKE OBJECT BOX lastObj+1+x, boxSize,boxSize,boxSize
           MAKE OBJECT COLLISION BOX lastObj+1+x,    -boxSize/2,-boxSize/2,-boxSize/2, boxSize/2,boxSize/2,boxSize/2, 0
           `XROTATE OBJECT lastObj+1+x, 1
           `ZROTATE OBJECT lastObj+1+x, 270
           TEXTURE OBJECT lastObj+1+x, 0, tex
           TEXTURE OBJECT lastObj+1+x, 1, bumpTex
           SET OBJECT EFFECT lastObj+1+x, 1
           `set effect technique 1,"lighting1"
           `SET BUMP MAPPING ON lastObj+1+x, 4
           `SET OBJECT CULL lastObj+1+x, 1
           `SHOW OBJECT BOUNDS lastObj+1+x , 1
           POSITION OBJECT lastObj+1+x, (dungeonRoom(roomNum,dungeonLevel ,x,1)*boxSize) - (boxSize), dungeonLevel*boxSize + (boxSize*(p+0.5)) , dungeonRoom(roomNum,dungeonLevel ,x,2)*boxSize
           lastObj = lastObj +1
        NEXT p
        ENDIF
        
        `IF x = xEnd, then make right wall
        IF dungeonRoom(roomNum,dungeonLevel ,x,1) = xEnd
        FOR p = 0 to 1
           `MAKE OBJECT PLANE lastObj+1+x, boxSize, boxSize
           MAKE OBJECT BOX lastObj+1+x, boxSize,boxSize,boxSize
           MAKE OBJECT COLLISION BOX lastObj+1+x,    -boxSize/2,-boxSize/2,-boxSize/2, boxSize/2,boxSize/2,boxSize/2, 0
           YROTATE OBJECT lastObj+1+x, 0
           `IF p = 0 THEN  TEXTURE OBJECT lastObj+1+x, 3
           TEXTURE OBJECT lastObj+1+x, 0, tex
           TEXTURE OBJECT lastObj+1+x, 1, bumpTex
           SET OBJECT EFFECT lastObj+1+x, 1
           `SET BUMP MAPPING ON lastObj+1+x, 4
           `SET OBJECT CULL lastObj+1+x, 1
           `SHOW OBJECT BOUNDS lastObj+1+x , 1
           POSITION OBJECT lastObj+1+x, (dungeonRoom(roomNum,dungeonLevel ,x,1)*boxSize) + (boxSize), dungeonLevel*boxSize + (boxSize*(p+0.5)) , dungeonRoom(roomNum,dungeonLevel ,x,2)*boxSize
           lastObj = lastObj +1
        NEXT p
        ENDIF
        
        `IF z = zStart, then make back wall
        IF dungeonRoom(roomNum,dungeonLevel ,x,2) = zStart
        FOR p = 0 to 1
           `MAKE OBJECT PLANE lastObj+1+x, boxSize, boxSize
           MAKE OBJECT BOX lastObj+1+x, boxSize,boxSize,boxSize
           MAKE OBJECT COLLISION BOX lastObj+1+x,    -boxSize/2,-boxSize/2,-boxSize/2, boxSize/2,boxSize/2,boxSize/2, 0
           `YROTATE OBJECT lastObj+1+x, 180
           `IF p = 0 THEN  TEXTURE OBJECT lastObj+1+x, 3
           TEXTURE OBJECT lastObj+1+x, 0, tex
           TEXTURE OBJECT lastObj+1+x, 1, bumpTex
           SET OBJECT EFFECT lastObj+1+x, 1
           `SET BUMP MAPPING ON lastObj+1+x, 4
           `SET OBJECT CULL lastObj+1+x, 1
           `SHOW OBJECT BOUNDS lastObj+1+x , 1
           POSITION OBJECT lastObj+1+x, (dungeonRoom(roomNum,dungeonLevel ,x,1)*boxSize), dungeonLevel*boxSize + (boxSize*(p+0.5)) , dungeonRoom(roomNum,dungeonLevel ,x,2)*boxSize - (boxSize)
           lastObj = lastObj +1
        NEXT p
        ENDIF
        
        `IF z = zEnd, then make front wall
        IF dungeonRoom(roomNum,dungeonLevel ,x,2) = zEnd
        FOR p = 0 to 1
           `MAKE OBJECT PLANE lastObj+1+x, boxSize, boxSize
           MAKE OBJECT BOX lastObj+1+x, boxSize,boxSize,boxSize
           MAKE OBJECT COLLISION BOX lastObj+1+x,    -boxSize/2,-boxSize/2,-boxSize/2, boxSize/2,boxSize/2,boxSize/2, 0
           `YROTATE OBJECT lastObj+1+x, 180
           `IF p = 0 THEN  TEXTURE OBJECT lastObj+1+x, 3
           TEXTURE OBJECT lastObj+1+x, 0, tex
           TEXTURE OBJECT lastObj+1+x, 1, bumpTex
           SET OBJECT EFFECT lastObj+1+x, 1
           `SET BUMP MAPPING ON lastObj+1+x, 4
           `SET OBJECT CULL lastObj+1+x, 1
           `SHOW OBJECT BOUNDS lastObj+1+x , 1
           POSITION OBJECT lastObj+1+x, (dungeonRoom(roomNum,dungeonLevel ,x,1)*boxSize), dungeonLevel*boxSize + (boxSize*(p+0.5)) , dungeonRoom(roomNum,dungeonLevel ,x,2)*boxSize + (boxSize)
           lastObj = lastObj +1
        NEXT p
        ENDIF
    NEXT x
ENDFUNCTION

'###########################################################################################################################################################################
Function update_keystate()
   remstart
      A very simple way of detecting when a key is pressed and when it's released.
      key$(0) represents a "key down" i.e. when a key is pressed.
      key$(1) represents a "key up" i.e. when a key is released.
      If key$(1) isn't empty then it's equal to a key that's just been released.
      We use this to determine what the user is typing so that we don't pause the
      program with an INPUT command.
      If we used the letter that was currently being pressed then we would get one
      letter for every frame per second.
   remend

   key$(1)=""

   if key$(0) <> inkey$()
      key$(1) = key$(0)
   endif

   key$(0)=inkey$()
   
endfunction

'==============================================================================================================================================

_handle_chat_key_input:

   rem Reset the flag and clear the input line.
   if chatflag$="DONE" then chatflag$="" : chatline$=""

   rem If a key is pressed
   If key$(1)<>""
      rem Did the user press backspace? (ascii 8)
      if asc( key$(1) )=8
         rem backspace - chop off the character at the end of the line
         chatline$ = left$( chatline$, len(chatline$)-1)
      else
         rem did the user hit return? (ascii 13)
         if asc( key$(1) )=13
            rem Yep - they hit return.
            rem Mark the chat line as being DONE and ready for sending.
            chatflag$="DONE"
         else
            rem add anything else the user types to the chat line
            chatline$ = chatline$ + key$(1)
         Endif
      Endif
   Endif
   
return

'==============================================================================================================================================

_handle_sending_chatline:
   if chatflag$="DONE"
      rem send out our chat line
      'send net message string 0, chatline$

      rem Update the currentmessage$ variable for use with the subroutine.
      rem Add our own name to the line for our own benefit.
      'currentmessage$ = playername$ + ": " + chatline$
      currentmessage$ = chatline$                    rem currentmessage$ = playername + chatline$

      rem we won't receive our chat message over te network so we have to "cheat" and add
      rem it to our chat array manually.
      gosub _add_current_message_to_chat

      rem update our counter
      msgoutcount = msgoutcount+1
   endif
return
'=============================================================================================================================================

_add_current_message_to_chat:
   rem Move along to the next slot in our message array
   latestline = latestline+1

   rem Make sure we wrap around to the start if we count past the end of the array.
   if latestline > array count(chatlines$(0)) then latestline = 1

   rem Overwrite whatever is here with the current message.
   chatlines$(latestline)=currentmessage$
   
   `register commands if exist
   gosub _chat_commands
   
   rem Close chatbox if Enter is hit
   chatbox = 0
return

'==============================================================================================================================================

_show_chat:
   rem Go through all the chat lines we've recorded and print them out to the screen.
   rem Have to do it backwards, though, so the newest one appears at the bottom of the screen.
   for n = 0 to array count(chatlines$(0))-1
      thisline = latestline-n

      rem check to make sure we wrap around to the end of the array if we count backwards
      rem past the beginning.
      if thisline < 1 then thisline = array count(chatlines$(0)) + thisline
      text 10, chatbase+15*array count(chatlines$(0))-((n+1)*15), chatlines$(thisline)
   next n
    
return
'==============================================================================================================================================

_Chat_Commands:
`Give commands using chat
        
    IF chatbox = 1 
    
    `Following
        `Start Following    
        for p=0 to 2
        for f=0 to 3
        for n=0 to 2
            if  (find sub string$(currentmessage$,Follow$(f))> 0)  and  (find sub string$(currentmessage$,Prohibit$(p))< 0)  and  (find sub string$(currentmessage$,Name$(n))> 0)
            following = 1
            `NPClogics(n,1) = following
            endif
        next n
        next f
        next p
        
        `Stop Following
        for p=0 to 2
        for n=0 to 2
            if  (find sub string$(currentmessage$,Prohibit$(p))> 0)  and   (find sub string$(currentmessage$,Name$(n))> 0)
            `(find sub string$(currentmessage$,Follow$(f))> 0)  and
            following = 0
            `NPClogics(n,1) = following
            endif
        next n
        next p
        
        `Shoo!
        for n=0 to 2
        For s=0 to 3
            if  (find sub string$(currentmessage$,shoo$(s))> 0) and  (find sub string$(currentmessage$,Name$(n))> 0)
            Following = 0
            `NPClogics(n,1) = following
            endif
        Next s
        Next n
     
     ENDIF
     
RETURN


'##############################################################################################################################################





