Include "include\FastExt.bb"
Include "Include\ProShadows.bb"
Include "Include\FastImage.bb"

Include "Include\PickedUVW.bb"
Include "Include\SkyBox.bb"

Include "Include\INI File Functions v2.2.bb"

; "Include\TokamakCar.bb" загружается позже

Type Bullets_Type
	Field mesh
	Field time
End Type

Type PlayerBullets_Type
	Field mesh
	Field time
	Field dmg
	Field speed#
End Type

Type Enemys_Type
	Field mesh
	Field shadow
	Field health
	Field speed#
	Field snd_alert
	Field attack_time
End Type

Type Ways_Type
	Field pivot
End Type

SolidBullet=1
SolidEnemy=2
SolidWorld=3

INI_OpenFile("Config.ini")
Global Width=INI_ReadValue("Screen", "Width", "800")
Global Height=INI_ReadValue("Screen", "Height", "600") 
Global Bits=INI_ReadValue("Screen", "Bits", "32") 
Global FullScreen=INI_ReadValue("Screen", "FullScreen", "2") 

Graphics3D Width,Height,Bits,FullScreen
Width2=Width/2		; пол ширины
Height2=Height/2	; пол высоты (для центровки мыши)

AmbientLight 170,170,170		; освещение мира

InitExt()	; FastExt подгрузка
InitDraw()	; FastImage подгрузка
FastFont=LoadImageFont("Data\comic_sans_ms_40.txt")

MilliSeconds=MilliSecs()
SeedRnd MilliSeconds 	; установки рандомизации
SetBuffer BackBuffer()	; установка буффера обмена

TexRend=INI_ReadValue("Shadows", "TexRend", "0")
CubeMap=INI_ReadValue("Shadows", "CubeMap", "0")
Res1=INI_ReadValue("Shadows", "Res1", "1")
Res2=INI_ReadValue("Shadows", "Res2", "1")

ProShadows_Init(TexRend,CubeMap)
ExtendRange#=128.0	;Extended light range
Range#=32.0	;Light range
SmoothFade=1	;Smooth fade of shadow edge enabled
SunPt#=45 : SunYw#=-45 : SunRl#=0  ;angles of 'sun'
ProShadows_CreateSun(Res1,Range#, SmoothFade,Res2, ExtendRange#,SunPt#,SunYw#,SunRl#)

INI_CloseFile()

Title=LoadImageEx("Data\Textures\Title.jpg")

StartDraw()
DrawImageEx Title,Width2,Height2
EndDraw()
Flip

Repeat
Until (KeyHit(28)) Or (KeyHit(57)) Or (KeyHit(1))

Title=LoadImageEx("Data\Textures\RIP.jpg")

StartDraw()
DrawImageEx Title,Width2,Height2
EndDraw()
Flip

Repeat
Until (KeyHit(28)) Or (KeyHit(57)) Or (KeyHit(1))

CamActive=0

HidePointer
Global Camera=CreateCamera()
PositionEntity Camera,0,6,-2
Cursor3D=CreateCube()
ScaleEntity Cursor3D,0.1,0.1,0.1
HideEntity Cursor3D

Global CamX#,CamY#,CamZ#,CamPitch#,CamYaw#,CamRoll#,XXX#

	; ### Игрок ### <<<

Global GunNum=1
Dim Gun_Option(3,11)		; (номер ружья, опции ружья)
; пояснение опций
; 1 - мин. урон
; 2 - макс. урон
; 3 - кол-во пуль
; 4 - разброс
; 5 - задержка выстрела
; 6 - время выстрела
; 7 - скорость пули
; 8 - звук выстрела
; 9 - кол-во патронов
; 10 - макс. патронов
; 11 - пламя пули

Gun_Option(1,1)=25
Gun_Option(1,2)=30
Gun_Option(1,3)=1
Gun_Option(1,4)=1
Gun_Option(1,5)=150
Gun_Option(1,6)=0
Gun_Option(1,7)=20.0
Gun_Option(1,8)=LoadSound("Data\Sounds\Shot.wav")
Gun_Option(1,9)=200
Gun_Option(1,10)=200
Gun_Option(1,11)=LoadSprite("Data\Textures\Flame.bmp")
HideEntity Gun_Option(1,11)

Gun_Option(2,1)=45
Gun_Option(2,2)=55
Gun_Option(2,3)=4
Gun_Option(2,4)=3
Gun_Option(2,5)=1000
Gun_Option(2,6)=0
Gun_Option(2,7)=25.0
Gun_Option(2,8)=LoadSound("Data\Sounds\GunShot.wav")
Gun_Option(2,9)=16
Gun_Option(2,10)=64
Gun_Option(2,11)=LoadSprite("Data\Textures\Flame.bmp")
EntityColor Gun_Option(2,11),255,0,00
HideEntity Gun_Option(2,11)

Gun_Option(3,1)=220
Gun_Option(3,2)=220
Gun_Option(3,3)=1
Gun_Option(3,4)=0
Gun_Option(3,5)=1500
Gun_Option(3,6)=0
Gun_Option(3,7)=40.0
Gun_Option(3,8)=LoadSound("Data\Sounds\LaserShot.wav")
Gun_Option(3,9)=5
Gun_Option(3,10)=32
Gun_Option(3,11)=LoadSprite("Data\Textures\Flame.bmp")
EntityColor Gun_Option(3,11),0,255,0
HideEntity Gun_Option(3,11)

Global PlayerHP=100
PlayerMoney=0

Player_TurrelMesh=LoadMesh("Data\Models\Turrel.3ds")
ScaleEntity Player_TurrelMesh,0.3,0.3,0.3
Player_TurrelXrot#=0
Player_TurrelYrot#=0

SunShadow=CreateLight(2)
LightColor SunShadow,10,10,10
LightRange SunShadow,1000
PositionEntity SunShadow,0,100,0

Sun=CreateLight(2)
LightColor Sun,10,10,10
LightRange Sun,3000
PositionEntity Sun,0,300,0
	; ### Игрок ### >>>
	
	; ### TOKAMAK Машина ### <<<
Include "Include\TokamakCar.bb"
Tokamak_Prepare()
	; ### TOKAMAK Машина ### >>>

Terrain=LoadMesh("Data\Models\Map1low.3ds")
ScaleMesh Terrain,35.0,35.0,35.0
RotateMesh Terrain,-90,0,0
;PositionMesh Terrain,0,-30,0
MakeTokCollider(Terrain); коллзия с плато
EntityPickMode Terrain,2
NameEntity Terrain,"Terrain"
ProShadows_PaintRecieverSun(Terrain,0,0,1)
Global Terrain_tex=LoadTexture("Data\Textures\Track.bmp",256)
surf=GetSurface(Terrain,1)
brush=GetSurfaceBrush(surf)
BrushTexture brush,Terrain_tex,0,ProShadows_DiffuseLayer()
PaintSurface surf,brush
EntityType Terrain,SolidWorld

SkyBox=MakeSkyBox("Data\Textures\Sky\sky")
EntityPickMode SkyBox,2
NameEntity SkyBox,"SkyBox"

Global MapWayCurrent=0,MapLaps=0,Girls=0
Dim MapWay(13,2)
MapWay(1,1)=-105 : MapWay(1,2)=-105
MapWay(2,1)=-85 : MapWay(2,2)=25
MapWay(3,1)=50 : MapWay(3,2)=-70
MapWay(4,1)=70 : MapWay(4,2)=5
MapWay(5,1)=-20 : MapWay(5,2)=10
MapWay(6,1)=-25 : MapWay(6,2)=75
MapWay(7,1)=-110 : MapWay(7,2)=85
MapWay(8,1)=10 : MapWay(8,2)=90
MapWay(9,1)=55 : MapWay(9,2)=40
MapWay(10,1)=40 : MapWay(10,2)=90
MapWay(11,1)=105 : MapWay(11,2)=105
MapWay(12,1)=105 : MapWay(12,2)=-105
MapWay(13,1)=-75 : MapWay(13,2)=-105

For i=1 To 13
	Way.Ways_Type=New Ways_Type
	Way\pivot=CreatePivot()
	PositionEntity Way\pivot,MapWay(i,1),0.3,MapWay(i,2)
	NameEntity Way\pivot,i
Next

Snd_CheckPoint=LoadSound("Data\Sounds\CheckPoint.wav")
Snd_WayEnd=LoadSound("Data\Sounds\WayEnd.wav")

Global PlayerMesh=LoadMesh("Data\Models\Baggy.3ds")	; загрузка модели машины
ScaleMesh PlayerMesh,0.3,0.3,0.3		; размер модели
PositionMesh PlayerMesh,0.0,-2.1,0.0	; начальная позиция
RotateMesh PlayerMesh,0,180,0			; начальный угол
PlayerTex=LoadTexture("Data\Textures\Metall.jpg")
EntityTexture PlayerMesh,PlayerTex
EntityTexture Player_TurrelMesh,PlayerTex

Global BodyShadow_Mesh=LoadMesh("Data\Models\Baggy_shadow.3ds")	; загрузка упрощённой модели для тени
ScaleMesh BodyShadow_Mesh,0.3,0.3,0.3	; размер как у машины
ProShadows_AddCaster(BodyShadow_Mesh,1)	; добавляем модель в раздачу тени машины

Centerpivot=CreatePivot()

period=1000/FPS ; период
time=MilliSeconds-period ; расчёт времени
Global timestep#=1.5/FPS ; шаг времени


	; ### МОНСТРЫ ### <<<
Global MonsterSpawnTime=MilliSeconds : MonsterMaxSpawnTime=3000 : MonsterMaxCount=10 : MonsterCount=0
Global Monster_speed#=4

Dim Monster_Option(3,8)		; (номер ружья, опции ружья)
; пояснение опций
; 1 - жизни
; 2 - скорость
; 3 - текстура
; 4 - модель
; 5 - анимация бега
; 6 - анимация удара
; 7 - анимация смерти
; 8 - звук ярости

Monster_Option(1,1)=100
Monster_Option(1,2)=15.0
Monster_Option(1,3)=LoadTexture("Data\Models\Raptor\Skin.bmp")
Monster_Option(1,4)=LoadAnimMesh("Data\Models\Raptor\Model.b3d")
Monster_Option(1,5)=LoadAnimSeq(Monster_Option(1,4),"Data\Models\Raptor\Model.b3d")
Monster_Option(1,8)=LoadSound("Data\Sounds\Zombie\zombieye_alert.wav")

Monster_Option(2,1)=200
Monster_Option(2,2)=8.0
Monster_Option(2,3)=LoadTexture("Data\Models\Zombieye\Skin.bmp")
Monster_Option(2,4)=LoadAnimMesh("Data\Models\Zombieye\Model.b3d")
Monster_Option(2,5)=LoadAnimSeq(Monster_Option(2,4),"Data\Models\Zombieye\Model.b3d")
Monster_Option(2,8)=LoadSound("Data\Sounds\Zombie\zombieye_alert.wav")

Dim Snd_ZombiePain(3)

Snd_ZombiePain(1)=LoadSound("Data\Sounds\Zombie\zm_pain1.wav")
Snd_ZombiePain(2)=LoadSound("Data\Sounds\Zombie\zm_pain2.wav")
Snd_ZombiePain(3)=LoadSound("Data\Sounds\Zombie\zm_pain3.wav")

Dim Snd_ZombieAttack(3)

Snd_ZombieAttack(1)=LoadSound("Data\Sounds\Zombie\zm_attack1.wav")
Snd_ZombieAttack(2)=LoadSound("Data\Sounds\Zombie\zm_attack2.wav")
Snd_ZombieAttack(3)=LoadSound("Data\Sounds\Zombie\zm_attack3.wav")

HideEntity Monster_Option(1,4)
HideEntity Monster_Option(2,4)

MonsterShadow=LoadAnimMesh("Data\Models\Shadow_run.b3d")
MonsterShadowAnimRun=LoadAnimSeq(MonsterShadow,"Data\Models\Shadow_run.b3d")	; анимация бега
HideEntity MonsterShadow
	; ### МОНСТРЫ ### >>>

GirlTex=LoadTexture("Data\Models\Natasha_mix\Skin.bmp")
Global GirlMesh=LoadAnimMesh("Data\Models\Natasha_mix\Model.b3d")
GirlMeshAnim=LoadAnimSeq(GirlMesh,"Data\Models\Natasha_mix\Model.b3d")
ScaleEntity GirlMesh,0.05,0.05,0.05
Animate GirlMesh,1,0.2,GirlMeshAnim
EntityTexture GirlMesh,GirlTex

Global GirlShadow=LoadAnimMesh("Data\Models\Natasha_mix\Model.b3d")
GirlShadowAnim=LoadAnimSeq(GirlShadow,"Data\Models\Natasha_mix\Model.b3d")	; анимация бега
ScaleEntity GirlShadow,0.05,0.05,0.05
Animate GirlShadow,1,0.2,GirlShadowAnim
ProShadows_AddCaster(GirlShadow,2)

PlaceGirl()

Dim Snd_GirlsSmile(2)

Snd_GirlsSmile(1)=LoadSound("Data\Sounds\GirlXaxa1.wav")
Snd_GirlsSmile(2)=LoadSound("Data\Sounds\GirlXaxa2.wav")

Snd_Ricoshet=LoadSound("Data\Sounds\Ricoshet.wav")

Collisions SolidBullet,SolidEnemy,1,1
Collisions SolidEnemy,SolidWorld,2,2

ImgMap=LoadImageEx("Data\Textures\Map1View.png")
ImgPlayer=LoadImageEx("Data\Textures\MapPlayer.png",1+2)
ImgEnemy=LoadImageEx("Data\Textures\MapEnemy.png")
ImgMark=LoadImageEx("Data\Textures\MapMark.png")
ImgWay=LoadImageEx("Data\Textures\MapWay.png")

ImgAim=LoadImageEx("Data\Textures\Aim.png",2)

Snd_Music=LoadSound("Data\Sounds\music.mp3")
LoopSound Snd_Music
PlaySound Snd_Music

; Главный цикл
While Not KeyHit(1)
Delay 1

	Repeat 
		elapsed=MilliSecs()-time ; пройденное время
	Until elapsed

	ticks=elapsed/period
	tween#=Float(elapsed Mod period)/Float(period)
	
For k=1 To ticks
	time=time+period
	If k=ticks Then CaptureWorld
	
	MilliSeconds=MilliSecs()
	SeedRnd MilliSeconds 	; установки рандомизации
	
	;[Block TOKAMAK Update]
	TOKSIM_Advance(1.5/FPS,1)
	
	;UpdateWorld

	PlaceMesh PlayerMesh,Body_RB
	PositionEntity FR_Wheel,TOKRB_GetX#(FR_Spr_RB),TOKRB_GetY#(FR_Spr_RB),TOKRB_GetZ#(FR_Spr_RB)
	RotateEntity FR_Wheel,EntityPitch#(PlayerMesh),EntityYaw#(PlayerMesh),EntityRoll#(PlayerMesh)
	TurnEntity FR_Wheel,0,Turn#,0 
	PositionEntity FL_Wheel,TOKRB_GetX#(FL_Spr_RB),TOKRB_GetY#(FL_Spr_RB),TOKRB_GetZ#(FL_Spr_RB)
	RotateEntity FL_Wheel,EntityPitch#(PlayerMesh),EntityYaw#(PlayerMesh),EntityRoll#(PlayerMesh)
	TurnEntity FL_Wheel,0,Turn#,0 
	PositionEntity RR_Wheel,TOKRB_GetX#(RR_Spr_RB),TOKRB_GetY#(RR_Spr_RB),TOKRB_GetZ#(RR_Spr_RB)
	RotateEntity RR_Wheel,EntityPitch#(PlayerMesh),EntityYaw#(PlayerMesh),EntityRoll#(PlayerMesh)
	PositionEntity RL_Wheel,TOKRB_GetX#(RL_Spr_RB),TOKRB_GetY#(RL_Spr_RB),TOKRB_GetZ#(RL_Spr_RB)
	RotateEntity RL_Wheel,EntityPitch#(PlayerMesh),EntityYaw#(PlayerMesh),EntityRoll#(PlayerMesh)
	
	UpdateSpring 1.2,-0.5,-1.5,RR_Spr_RB,50,6.0,1.1
	UpdateSpring -1.2,-0.5,-1.5,RL_Spr_RB,50,6.0,1.1
	UpdateSpring 1.2,-0.5,1.65,FR_Spr_RB,50,6.0,1.1
	UpdateSpring -1.2,-0.5,1.65,FL_Spr_RB,50,6.0,1.1

	RRColl=False
	RLColl=False
	FRColl=False
	FLColl=False
	; проверка коллизий
	If TOKSIM_GetCollisionCount()>0 Then ; счёт коллизий
		For c=0 To TOKSIM_GetCollisionCount()-1
			If PeekInt(ColBank,0+(c*104))= RR_Spr_RB Then RRColl=True
			If PeekInt(ColBank,0+(c*104))= RL_Spr_RB Then RLColl=True
			If PeekInt(ColBank,0+(c*104))= FR_Spr_RB Then FRColl=True
			If PeekInt(ColBank,0+(c*104))= FL_Spr_RB Then FLColl=True
	  Next
	EndIf
	;[End Block]
	
	If PlayerHP>0 Then
		; ускорение и торможение
		If KeyDown(17) Then Acc#=Acc#+1.0
		
		If Acc#>11 Then
			Acc#=11
		Else If KeyDown(31)Then
			Acc#=Acc#-1.0
			If Acc#<6.0 Then Acc#=-6.0
		Else			; иначе плавный останов авто
			Acc#=Acc#*0.95
			If Acc#>-0.01 And Acc#<0.01 Then Acc#=0.0
		EndIf
		
		If KeyDown(57)Then ; ручной тормоз
			Acc#=-5*vel#
		EndIf
	EndIf

	;[Block TOKAMAK Update]
	TFormVector 0,0,1,PlayerMesh,0
	vx#=TFormedX#()
	vy#=TFormedY#()
	vz#=TFormedZ#()
	;TOKRB_ApplyImpulse Body_RB,vx#*acc#*timestep#,vy#*acc#*timestep#,vz#*acc#*timestep#
	
	If RRColl=True Then
	TOKRB_ApplyImpulse RR_Spr_RB,vx#*Acc#*timestep#,vy#*Acc#*timestep#,vz#*Acc#*timestep#
	EndIf
	If RLColl=True Then
	TOKRB_ApplyImpulse RL_Spr_RB,vx#*Acc#*timestep#,vy#*Acc#*timestep#,vz#*Acc#*timestep#
	EndIf

	TFormVector 0,0,1,FR_Wheel,0
	vx#=TFormedX#()
	vy#=TFormedY#()
	vz#=TFormedZ#()
	;TOKRB_ApplyImpulse FR_Spr_RB,vx#*acc#*timestep#,vy#*acc#*timestep#,vz#*acc#*timestep#
	TFormVector 0,0,1,FL_Wheel,0
	vx#=TFormedX#()
	vy#=TFormedY#()
	vz#=TFormedZ#()
	;TOKRB_ApplyImpulse FL_Spr_RB,vx#*acc#*timestep#,vy#*acc#*timestep#,vz#*acc#*timestep#

;	TFormVector 0,0,Acc#/4.0,PlayerMesh,0
;	TOKRB_ApplyImpulse RR_Spr_RB,TFormedX#()*timestep#,TFormedY#()*timestep#,TFormedZ#()*timestep#
;	TOKRB_ApplyImpulse RL_Spr_RB,TFormedX#()*timestep#,TFormedY#()*timestep#,TFormedZ#()*timestep#
;	TFormVector 0,0,Acc#/4.0,FR_Wheel,0
;	TOKRB_ApplyImpulse FR_Spr_RB,TFormedX#()*timestep#,TFormedY#()*timestep#,TFormedZ#()*timestep#
;	TFormVector 0,0,Acc#/4.0,FL_Wheel,0
;	TOKRB_ApplyImpulse FL_Spr_RB,TFormedX#()*timestep#,TFormedY#()*timestep#,TFormedZ#()*timestep#


	CarVelx#=TOKRB_GetVelocityX#(Body_RB); скорость авто по x
	CarVely#=TOKRB_GetVelocityY#(Body_RB); скорость авто по y
	CarVelz#=TOKRB_GetVelocityZ#(Body_RB); скорость авто по z
	TFormNormal 0,0,1,PlayerMesh,0
	CarVel#=Abs(DotProduct#(TFormedX#(),TFormedY#(),TFormedZ#(),CarVelx#,CarVely#,CarVelz#)); скорость авто
	TurnFactor#=1.0-((1.0/35.0)*CarVel#); показатель поворота
	
	MaxTurn#=37.0 ; угол поворота
	CurrTurn#=MaxTurn#*TurnFactor# ; текущий поворот
	If PlayerHP>0 Then
		If KeyDown(32)Then
		 Turn#=Turn#-0.7 ; налево
		 If Turn#<-MaxTurn#*TurnFactor# Then Turn#=-MaxTurn#*TurnFactor#
		ElseIf KeyDown(30)Then
		 Turn#=Turn#+0.7 ; направо
		 If Turn#>MaxTurn#*TurnFactor# Then Turn#=MaxTurn#*TurnFactor#
		Else
		 Turn=Turn*0.95
		 If Turn#>-0.1 And Turn#<0.1 Then Turn#=0.0
		EndIf
	EndIf
	
	AngVelx#=TOKRB_GetAngularVelocityX#(Body_RB)
	AngVely#=TOKRB_GetAngularVelocityY#(Body_RB)
	AngVelz#=TOKRB_GetAngularVelocityZ#(Body_RB)
	TFormNormal 0,1,0,PlayerMesh,0
	AngVel#=Abs(DotProduct#(TFormedX#(),TFormedY#(),TFormedZ#(),AngVelx#,AngVely#,AngVelz#))

	;If KeyHit(57)Or(AngVel#>1.0 And CarVel#>10.0)Then ; расчёт заноса
	;	Slip=True
	;EndIf
	
	If Slip=True Then 
	GripFactor#=0.99
	EndIf	
	If AngVel#<0.7 And Slip=True Then 
	GripFactor#=0.98
	;Slip=False
	EndIf	
	If AngVel#<0.5 And Slip=True Then 
	GripFactor#=0.97
	;Slip=False
	EndIf	
	If AngVel#<0.3 And Slip=True Then 
	GripFactor#=0.9
	Slip=False
	EndIf
	
	; трение
	; для правого заднего колеса
	Vx#=TOKRB_GetVelocityX#(RR_Spr_RB)
	Vy#=TOKRB_GetVelocityY#(RR_Spr_RB)
	Vz#=TOKRB_GetVelocityZ#(RR_Spr_RB)
	;GripFactor#=GripFactor(Sqr(vx#*vx#+vy#*vy#+vz#*vz#))
	TFormVector Vx#,Vy#,Vz#,0,PlayerMesh
	TFormVector TFormedX#()*GripFactor#,TFormedY#(),TFormedZ#(),PlayerMesh,0
	If RRColl=True Then
	TOKRB_SetVelocity RR_Spr_RB,TFormedX#(),TFormedY#(),TFormedZ#()
 	EndIf

	; для левого заднего колеса
	Vx#=TOKRB_GetVelocityX#(RL_Spr_RB)
	Vy#=TOKRB_GetVelocityY#(RL_Spr_RB)
	Vz#=TOKRB_GetVelocityZ#(RL_Spr_RB)
	;GripFactor#=GripFactor(Sqr(vx#*vx#+vy#*vy#+vz#*vz#))
	TFormVector Vx#,Vy#,Vz#,0,PlayerMesh
	TFormVector TFormedX#()*GripFactor#,TFormedY#(),TFormedZ#(),PlayerMesh,0
	If RLColl=True Then
	TOKRB_SetVelocity RL_Spr_RB,TFormedX#(),TFormedY#(),TFormedZ#()
	EndIf
	
	; для правого переднего колеса
	Vx#=TOKRB_GetVelocityX#(FR_Spr_RB)
	Vy#=TOKRB_GetVelocityY#(FR_Spr_RB)
	Vz#=TOKRB_GetVelocityZ#(FR_Spr_RB)
	;GripFactor#=GripFactor(Sqr(vx#*vx#+vy#*vy#+vz#*vz#))
	TFormVector Vx#,Vy#,Vz#,0,FR_Wheel
	TFormVector TFormedX#()*GripFactor#,TFormedY#(),TFormedZ#(),FR_Wheel,0
	If FRColl=True Then
	TOKRB_SetVelocity FR_Spr_RB,TFormedX#(),TFormedY#(),TFormedZ#()
	EndIf
	
	; для левого переднего колеса
	Vx#=TOKRB_GetVelocityX#(FL_Spr_RB)
	Vy#=TOKRB_GetVelocityY#(FL_Spr_RB)
	Vz#=TOKRB_GetVelocityZ#(FL_Spr_RB)
	;GripFactor#=GripFactor(Sqr(vx#*vx#+vy#*vy#+vz#*vz#))
	TFormVector Vx#,Vy#,Vz#,0,FL_Wheel
	TFormVector TFormedX#()*GripFactor#,TFormedY#(),TFormedZ#(),FL_Wheel,0
	If FLColl=True Then
	TOKRB_SetVelocity FL_Spr_RB,TFormedX#(),TFormedY#(),TFormedZ#()
	EndIf


	TFormNormal 0,0,-1,PlayerMesh,0
	dragConstant#=1.1
 	velX#=TOKRB_GetVelocityX#(Body_RB)
 	velY#=TOKRB_GetVelocityY#(Body_RB)
 	velZ#=TOKRB_GetVelocityZ#(Body_RB)

 	dot#=DotProduct#(TFormedX#(),TFormedY#(),TFormedZ#(),velX#,velY#,velZ#)
 	dragX#=dot#*TFormedX#()*-dragConstant#
 	dragY#=dot#*TFormedY#()*-dragConstant#
 	dragZ#=dot#*TFormedZ#()*-dragConstant#
	TOKRB_ApplyImpulse Body_RB,dragX#*timestep#,dragY#*timestep#,dragZ#*timestep#
	
	;PositionEntity camtargetpivot,EntityX#(PlayerMesh),EntityY#(PlayerMesh),EntityZ#(PlayerMesh)
	;RotateEntity camtargetpivot,EntityPitch#(PlayerMesh),EntityYaw#(PlayerMesh),EntityRoll#(PlayerMesh)
	;MoveEntity camtargetpivot,0,1,-2
	;RotateEntity camtargetpivot,EntityPitch#(PlayerMesh),EntityYaw#(PlayerMesh),EntityRoll#(PlayerMesh)
	;chaseCam Camera,PlayerMesh,xoff#,yoff#=2,zoff#=-5,spd#=0.8
	;UpdateCamera camtargetpivot,campoint,25.0,5.0,0.0
	;PositionEntity Camera,TOKRB_GetX#(campoint),TOKRB_GetY#(campoint),TOKRB_GetZ#(campoint)
	
	;UpdateCamera Camera,camtargetpivot,0.02 ; камера следует за авто ; если убрать,то камера на одном месте
	;[End Block]

	MousX=Width2
	MousY=Height2
	
	MousXs=MouseXSpeed() ;see how far the mouse has been moved
	MousYs=MouseYSpeed() ;see how far the mouse has been moved
	MoveMouse MousX,MousY ;put the mouse back in the middle of the screen
	
	MousX=MousX+MousXs ;adjust mouse co-ords
	MousY=MousY+MousYs
	
	If MousX<Width2 Then Player_TurrelXrot#=Player_TurrelXrot#+0.2*(Width2-MousX)/1 ;/Player_Zoom,0
	If MousX>Width2 Then Player_TurrelXrot#=Player_TurrelXrot#-0.2*(MousX-Width2)/1 ;/Player_Zoom,0
	If Player_TurrelXrot#>360 Then Player_TurrelXrot#=1
	If Player_TurrelXrot#<0 Then Player_TurrelXrot#=359
	
	If CamActive=0 Then
		If MousY<Height2 Then Player_TurrelYrot#=Player_TurrelYrot#+0.2*(Height2-MousY)/1 ;/Player_Zoom,0	; << пассивная камера
		If MousY>Height2 Then Player_TurrelYrot#=Player_TurrelYrot#-0.2*(MousY-Height2)/1 ;/Player_Zoom,0
		If Player_TurrelYrot#>25 Then Player_TurrelYrot#=25
		If Player_TurrelYrot#<-25 Then Player_TurrelYrot#=-25
		
		PositionEntity Camera,EntityX#(PlayerMesh),EntityY#(PlayerMesh)+3,EntityZ#(PlayerMesh)
		RotateEntity Camera,-Player_TurrelYrot#,Player_TurrelXrot#,0
		MoveEntity Camera,0,0,-7 	; >> пассивная камера
	Else
		If MousY<Height2 Then Player_TurrelYrot#=Player_TurrelYrot#-0.2*(Height2-MousY)/1 ;/Player_Zoom,0	; << активная камера
		If MousY>Height2 Then Player_TurrelYrot#=Player_TurrelYrot#+0.2*(MousY-Height2)/1 ;/Player_Zoom,0
		If Player_TurrelYrot#>30 Then Player_TurrelYrot#=30
		If Player_TurrelYrot#<-25 Then Player_TurrelYrot#=-25
		
		PositionEntity Camera,EntityX#(PlayerMesh),EntityY#(PlayerMesh)+3,EntityZ#(PlayerMesh)
		RotateEntity Camera,EntityPitch#(PlayerMesh)+10+Player_TurrelYrot#,Player_TurrelXrot#,-EntityRoll#(PlayerMesh)	; (PlayerMesh) - супер активная
		MoveEntity Camera,0,0,-7 	; >> активная камера
	EndIf
	
	CamX#=EntityX#(Camera) : CamY#=EntityY#(Camera) : CamZ#=EntityZ#(Camera)		; сохраняем на запас данные камеры для 
	CamPitch#=EntityPitch#(Camera) : CamYaw#=EntityYaw#(Camera) : CamRoll#=EntityRoll#(Camera)	; восстановления после смещений на пиканья
	
	Picked=CameraPick(Camera,MouseX(),MouseY())
	If Picked>0 Then
		If EntityName(Picked)="Terrain" Then
			PositionEntity Cursor3D,PickedX#(),PickedY#(),PickedZ#()
		EndIf
		If EntityName(Picked)="SkyBox" Then
			PositionEntity Cursor3D,PickedX#(),PickedY#(),PickedZ#()
		EndIf
	EndIf
	
	PositionEntity BodyShadow_Mesh,EntityX#(PlayerMesh),EntityY#(PlayerMesh),EntityZ#(PlayerMesh)		; синхр. позиции тени игрока
	RotateEntity BodyShadow_Mesh,EntityPitch#(PlayerMesh),EntityYaw#(PlayerMesh),EntityRoll#(PlayerMesh)		; синхр. угла тени игрока
	
	PositionEntity Player_TurrelMesh,EntityX#(PlayerMesh),EntityY#(PlayerMesh),EntityZ#(PlayerMesh)			; ставим пушку
	RotateEntity Player_TurrelMesh,EntityPitch#(PlayerMesh),EntityYaw#(PlayerMesh),EntityRoll#(PlayerMesh)	; к машине
	MoveEntity Player_TurrelMesh,0,0.8,-0.55	; корректировка положения на крышу
	PointEntity Player_TurrelMesh,Cursor3D		; прицел пушки на 3Д-курсор
	
	PointEntity GirlMesh,PlayerMesh
	RotateEntity GirlMesh,0,EntityYaw#(GirlMesh)+180,0
	RotateEntity GirlShadow,0,EntityYaw#(GirlMesh)+180,0
	
	If EntityDistance(PlayerMesh,GirlMesh)<4 Then
		If PlayerHP<100 Then PlayerHP=PlayerHP+5
		If PlayerHP>100 Then PlayerHP=100
		PlayerMoney=PlayerMoney+100
		Girls=Girls+1
		Gun_Option(1,9)=Gun_Option(1,9)+30 : If Gun_Option(1,9)>Gun_Option(1,10) Then Gun_Option(1,9)=Gun_Option(1,10)
		Gun_Option(2,9)=Gun_Option(2,9)+6 : If Gun_Option(2,9)>Gun_Option(2,10) Then Gun_Option(2,9)=Gun_Option(2,10)
		Gun_Option(3,9)=Gun_Option(3,9)+1 : If Gun_Option(3,9)>Gun_Option(3,10) Then Gun_Option(3,9)=Gun_Option(3,10)
		PlaySound Snd_GirlsSmile(Rand(1,2))
		PlaceGirl()
	EndIf
	
	If KeyHit(2)=True Then GunNum=1
	If KeyHit(3)=True Then GunNum=2
	If KeyHit(4)=True Then GunNum=3
	
	If MouseDown(1)=True Then	; левая кнопка мыши
		If (PlayerHP>0) And (Gun_Option(GunNum,9)>0) And (MilliSeconds-Gun_Option(GunNum,5)>Gun_Option(GunNum,6)) Then
			For i=1 To Gun_Option(GunNum,3)
				PlayerBullet.PlayerBullets_Type=New PlayerBullets_Type	; создаём новую пулю
				PlayerBullet\mesh=CopyEntity(Gun_Option(GunNum,11))	; модель пули
				ScaleSprite PlayerBullet\mesh,0.3,0.3		; размер
				PositionEntity PlayerBullet\mesh,EntityX#(Player_TurrelMesh),EntityY#(Player_TurrelMesh),EntityZ#(Player_TurrelMesh)		; ставим пулю к пушке
				RotateEntity PlayerBullet\mesh,EntityPitch#(Player_TurrelMesh)+Rnd(-Gun_Option(GunNum,4),Gun_Option(GunNum,4)),EntityYaw#(Player_TurrelMesh)+Rnd(-Gun_Option(GunNum,4),Gun_Option(GunNum,4)),EntityRoll#(Player_TurrelMesh)	; поворачиваем пулю по углу пушки
				EntityType PlayerBullet\mesh,SolidBullet
				PlayerBullet\dmg=Rand(Gun_Option(GunNum,1),Gun_Option(GunNum,2))
				PlayerBullet\speed#=Gun_Option(GunNum,7)
			Next
			PlaySound Gun_Option(GunNum,8)		; звук стрельбы
			Gun_Option(GunNum,9)=Gun_Option(GunNum,9)-1
			Gun_Option(GunNum,6)=MilliSeconds
		EndIf
	EndIf
	
	For PlayerBullet.PlayerBullets_Type=Each PlayerBullets_Type	; проверяем каждую пулю
		MoveEntity PlayerBullet\mesh,0,0,PlayerBullet\speed#/10	; перемещение пули про траектории полёта (по оси Z=скорость)
		PlayerBullet\time=PlayerBullet\time+1	; увеличиваем время старения
		
		For x=1 To CountCollisions(PlayerBullet\mesh)	; проверка каждого удара пули
			If GetEntityType(CollisionEntity(PlayerBullet\mesh,x))=SolidEnemy	; пуля попала в монстра
				PlayerBullet\time=400/2.0	; убиваем пулю
				DeadEnemy.Enemys_Type=Object.Enemys_Type(EntityName(CollisionEntity(PlayerBullet\mesh,x)))
				DeadEnemy\health=DeadEnemy\health-PlayerBullet\dmg
				
				PositionEntity Camera,EntityX#(DeadEnemy\Mesh),EntityY#(DeadEnemy\Mesh)+10,EntityZ#(DeadEnemy\Mesh)		; в запас на 10 выше
				RotateEntity Camera,90,0,0	; ставим камеру смотрящую на землю под попадание пули
				If CameraPick(Camera,MouseX(),MouseY())=Terrain Then
					PaintBlood(Terrain_tex,PickedU()*(TextureWidth(Terrain_tex)-1),PickedV()*(TextureHeight(Terrain_tex)-1),5)
				EndIf
				CreateBlood(DeadEnemy\Mesh,PlayerBullet\dmg/10)	; выпускаем кровь (модель,количество капель)
				
				PlaySound Snd_ZombiePain(Rand(1,3))
			EndIf
		Next
		
		If LinePick(EntityX#(PlayerBullet\Mesh),EntityY#(PlayerBullet\Mesh),EntityZ#(PlayerBullet\Mesh),0,-10,0,0.1)<>0 Then	; проверка земли под пулей (запас линии вниз на -10)
			BullY#=PickedY#()	; как высоко пуля от земли по Y
		EndIf
		If EntityY#(PlayerBullet\Mesh)<BullY#+0.75 Then	; если пуля под землёй (попала в землю)		; в запасе высота пули
			PositionEntity Camera,EntityX#(PlayerBullet\Mesh),EntityY#(PlayerBullet\Mesh)+10,EntityZ#(PlayerBullet\Mesh)		; в запас на 10 выше
			RotateEntity Camera,90,0,0	; ставим камеру смотрящую на землю под попадание пули
			If CameraPick(Camera,MouseX(),MouseY())=Terrain Then
				PaintDot(Terrain_tex,PickedU()*(TextureWidth(Terrain_tex)-1),PickedV()*(TextureHeight(Terrain_tex)-1),0)
			EndIf
			PlayerBullet\time=400/2.0	; убиваем пулю
			PlaySound Snd_Ricoshet		; звук рикошета
		EndIf
		
		If PlayerBullet\time>300/2.0 Then		; если пуля стара
			FreeEntity PlayerBullet\Mesh		; удаляем модель
			Delete PlayerBullet					; удаляем пулю
		EndIf
	Next
	
	For Way.Ways_Type=Each Ways_Type
		If EntityDistance(Way\pivot,PlayerMesh)<10 Then
			If Int(EntityName(Way\pivot))=MapWayCurrent+1 Then
				PlaySound Snd_CheckPoint
				MapWayCurrent=MapWayCurrent+1
				PlayerMoney=PlayerMoney+10
				Gun_Option(1,9)=Gun_Option(1,9)+30 : If Gun_Option(1,9)>Gun_Option(1,10) Then Gun_Option(1,9)=Gun_Option(1,10)
				Gun_Option(2,9)=Gun_Option(2,9)+4 : If Gun_Option(2,9)>Gun_Option(2,10) Then Gun_Option(2,9)=Gun_Option(2,10)
			EndIf
			If MapWayCurrent>12 Then
				MapWayCurrent=0
				MapLaps=MapLaps+1
				PlaySound Snd_WayEnd
				PlayerMoney=PlayerMoney+500
				Gun_Option(1,9)=Gun_Option(1,9)+100 : If Gun_Option(1,9)>Gun_Option(1,10) Then Gun_Option(1,9)=Gun_Option(1,10)
				Gun_Option(2,9)=Gun_Option(2,9)+32 : If Gun_Option(2,9)>Gun_Option(2,10) Then Gun_Option(2,9)=Gun_Option(2,10)
				Gun_Option(3,9)=Gun_Option(3,9)+8 : If Gun_Option(3,9)>Gun_Option(3,10) Then Gun_Option(3,9)=Gun_Option(3,10)
			EndIf
		EndIf
	Next
	
	If (MilliSeconds-MonsterSpawnTime>MonsterMaxSpawnTime) And (MonsterCount<MonsterMaxCount) Then
		MonsterCount=MonsterCount+1
		MonsterNum=Rand(1,2)
		
		Enemy.Enemys_Type=New Enemys_Type
		Enemy\health=Monster_Option(MonsterNum,1)
		Enemy\speed#=Monster_Option(MonsterNum,2)
		
		Enemy\mesh=CopyEntity(Monster_Option(MonsterNum,4))
		ScaleEntity Enemy\mesh,0.1,0.1,0.1
		Animate Enemy\mesh,1,Monster_speed#*0.1,Monster_Option(MonsterNum,5)
		EntityTexture Enemy\mesh,Monster_Option(MonsterNum,3)
		NameEntity Enemy\mesh,Handle(Enemy)
		
		Enemy\shadow=CopyEntity(MonsterShadow)
		Animate Enemy\shadow,1,Monster_speed#*0.2528,MonsterShadowAnimRun
		ScaleEntity Enemy\shadow,0.1,0.1,0.1
		ProShadows_AddCaster(Enemy\shadow,2)
		
		map_side=Rand(1,4)
		If map_side=1 Then PositionEntity Enemy\mesh,-125,13,Rand(-125,125)
		If map_side=2 Then PositionEntity Enemy\mesh,125,13,Rand(-125,125)
		If map_side=3 Then PositionEntity Enemy\mesh,Rand(-125,125),13,-125
		If map_side=4 Then PositionEntity Enemy\mesh,Rand(-125,125),13,125
		PositionEntity Enemy\shadow,EntityX#(Enemy\mesh),EntityY#(Enemy\mesh),EntityZ#(Enemy\mesh)
		
		EntityType Enemy\mesh,SolidEnemy
		EntityRadius Enemy\mesh,1,3.3
		
		Enemy\snd_alert=Monster_Option(MonsterNum,8)
		MonsterSpawnTime=MilliSeconds
	EndIf
	
	For Enemy.Enemys_Type=Each Enemys_Type	; проверяем каждого врага
		If (EntityDistance(Enemy\Mesh,PlayerMesh)<Rand(30,60)) And (Enemy\snd_alert>0) Then
			PlaySound Enemy\snd_alert
			Enemy\snd_alert=-1
		EndIf
		If EntityDistance(Enemy\Mesh,PlayerMesh)>8 Then MoveEntity Enemy\mesh,0,0,Enemy\speed#/100
		If EntityDistance(Enemy\Mesh,PlayerMesh)<9 Then
			If Enemy\attack_time<MilliSeconds
				Enemy\attack_time=MilliSeconds+2000
				PlayerHP=PlayerHP-5
				PlaySound Snd_ZombieAttack(Rand(1,3))
			EndIf
		EndIf
		
		MoveEntity Enemy\mesh,0,-0.1,0
		PositionEntity Enemy\shadow,EntityX#(Enemy\Mesh),EntityY#(Enemy\Mesh),EntityZ#(Enemy\Mesh)
		
		PointEntity Enemy\mesh,PlayerMesh
		RotateEntity Enemy\mesh,0,EntityYaw#(Enemy\mesh),0
		RotateEntity Enemy\shadow,EntityPitch#(Enemy\mesh),EntityYaw#(Enemy\mesh),EntityRoll#(Enemy\mesh)
		
		If Enemy\health<1 Then
			PlayerMoney=PlayerMoney+(50-Enemy\speed*2)
			MonsterCount=MonsterCount-1
			FreeEntity Enemy\mesh
			FreeEntity Enemy\shadow
			Delete Enemy
		EndIf
	Next
Next

If PlayerHP<0 Then PlayerHP=0

PositionEntity Camera,CamX#,CamY#,CamZ#			; восстанавливаем позицию камеры
RotateEntity Camera,CamPitch#,CamYaw#,CamRoll#	; восстанавливаем поворот камеры, после смещений на пиканья

UpdateBlood()

;update shadows
ProShadows_Update(Camera)

;global update
ProShadows_ShowCasters()			;show caster before update world for animation processing
UpdateWorld
ProShadows_HideCasters()			;hide casters after update world
;global renderworld
RenderWorld

StartDraw()
SetRotation 0

DrawText Gun_Option(1,9)+" / " +Gun_Option(1,10),5,140
DrawText Gun_Option(2,9)+" / " +Gun_Option(2,10),5,170
DrawText Gun_Option(3,9)+" / " +Gun_Option(3,10),5,200

DrawText PlayerHP+"%",155,5
DrawText PlayerMoney+"$",155,40
DrawText "geBku:"+Girls,155,70
DrawText "kpyru:"+MapLaps,155,110

DrawImageEx ImgMap,75,75

For Enemy.Enemys_Type=Each Enemys_Type
	If Enemy\mesh<>0 Then
		DrawImageEx ImgEnemy,75-EntityX#(Enemy\mesh)/2,EntityZ#(Enemy\mesh)/2+75
	EndIf
Next

If MapWayCurrent<13 Then
	DrawImageEx ImgWay,73-MapWay(MapWayCurrent+1,1)/2,MapWay(MapWayCurrent+1,2)/2+73
Else
	DrawImageEx ImgWay,73-MapWay(MapWayCurrent,1)/2,MapWay(MapWayCurrent,2)/2+73
EndIf

DrawImageEx ImgMark,75-EntityX#(GirlMesh)/2,EntityZ#(GirlMesh)/2+75
SetRotation 90-EntityYaw#(PlayerMesh)
DrawImageEx ImgPlayer,75-EntityX#(PlayerMesh)/2,EntityZ#(PlayerMesh)/2+75
SetRotation 0
DrawImageEx ImgAim,Width2+1,Height2+4

EndDraw()

Flip ;False ;( из за фальши видеокарточка сильно кипятится,но рендеринг улучшается)

Wend

SaveBuffer TextureBuffer(Terrain_tex),"Data\Textures\Track.bmp"

TOKSIM_DestroySimulator(); уничтожить симулятор
DeinitDraw()

ShowPointer

End

Function PlaceGirl()
	x=Rand(-110,110)
	y=Rand(-110,110)
	If LinePick(x,10,y,0,-20,0,0.1)<>0 Then
		PositionEntity GirlMesh,x,PickedY#()+1.8,y
		PositionEntity GirlShadow,x,PickedY#()+1.8,y
	EndIf
End Function

Type TBlood
	Field dy#,ent
	Field life
End Type

Function CreateBlood(ent,count)	; выпускаем кровь (модель,количество капель)
	For i=1 To count
		b.TBlood=New TBlood
		b\dy=.01-Rnd(0,0.01)
		b\ent=CreateSprite(ent)
		EntityParent b\ent,0
		EntityColor b\ent,128,0,0
		TurnEntity b\ent,Rnd(-180,180),Rnd(-180,180),Rnd(-180,180)
	Next
End Function
 
Function UpdateBlood()
	For b.TBlood=Each TBlood
		MoveEntity b\ent,0,0,0.3
		TranslateEntity b\ent,0,b\dy,0
		b\dy=b\dy-0.05
		b\life=b\life+1
		
		If b\life>30
			FreeEntity b\ent
			Delete b
		EndIf
	Next
End Function

;~IDEal Editor Parameters:
;~F#163#19B#34D#356#35B#366
;~C#Blitz3D