Merge remote branch 'origin/master' into tzork/vehicles-2
authorJakob MG <jakob_mg@hotmail.com>
Thu, 9 Jun 2011 17:49:10 +0000 (19:49 +0200)
committerJakob MG <jakob_mg@hotmail.com>
Thu, 9 Jun 2011 17:49:10 +0000 (19:49 +0200)
119 files changed:
effectinfo.txt
gfx/vehicles/axh-bracket.tga [new file with mode: 0644]
gfx/vehicles/axh-cross.tga [new file with mode: 0644]
gfx/vehicles/axh-dropcross.tga [new file with mode: 0644]
gfx/vehicles/axh-ring.tga [new file with mode: 0644]
gfx/vehicles/axh-special1.tga [new file with mode: 0644]
gfx/vehicles/axh-special2.tga [new file with mode: 0644]
gfx/vehicles/axh-tag.tga [new file with mode: 0644]
gfx/vehicles/axh-target.tga [new file with mode: 0644]
gfx/vehicles/axh-x.tga [new file with mode: 0644]
gfx/vehicles/bar_dwn_left.tga [new file with mode: 0644]
gfx/vehicles/bar_dwn_right.tga [new file with mode: 0644]
gfx/vehicles/bar_up_left.tga [new file with mode: 0644]
gfx/vehicles/bar_up_right.tga [new file with mode: 0644]
gfx/vehicles/bullets.tga [new file with mode: 0644]
gfx/vehicles/frame.tga [new file with mode: 0644]
gfx/vehicles/health.tga [new file with mode: 0644]
gfx/vehicles/hud_bg.tga [deleted file]
gfx/vehicles/raptor.tga [new file with mode: 0644]
gfx/vehicles/raptor_bombs.tga [new file with mode: 0644]
gfx/vehicles/raptor_guns.tga [new file with mode: 0644]
gfx/vehicles/rocket.tga [new file with mode: 0644]
gfx/vehicles/shield.tga [new file with mode: 0644]
gfx/vehicles/shiled.tga [deleted file]
gfx/vehicles/vh-shield.tga [new file with mode: 0644]
models/vehicles/bomblet.md3 [new file with mode: 0644]
models/vehicles/bumblebee.tga [new file with mode: 0644]
models/vehicles/bumblebee_body.dpm [new file with mode: 0644]
models/vehicles/bumblebee_gloss.tga [new file with mode: 0644]
models/vehicles/bumblebee_glow.tga [new file with mode: 0644]
models/vehicles/bumblebee_norm.tga [new file with mode: 0644]
models/vehicles/bumblebee_pants.tga [new file with mode: 0644]
models/vehicles/bumblebee_plasma_left.dpm [new file with mode: 0644]
models/vehicles/bumblebee_plasma_right.dpm [new file with mode: 0644]
models/vehicles/bumblebee_ray.dpm [new file with mode: 0644]
models/vehicles/clusterbomb.md3 [new file with mode: 0644]
models/vehicles/clusterbomb_folded.md3 [new file with mode: 0644]
models/vehicles/clusterbomb_fragment.md3 [new file with mode: 0644]
models/vehicles/raptor.dpm
models/vehicles/raptor_body.dpm [new file with mode: 0644]
models/vehicles/raptor_cockpit.dpm
models/vehicles/rocket01.md3 [new file with mode: 0644]
models/vehicles/rocket02.md3 [new file with mode: 0644]
models/vehicles/rockets.tga [new file with mode: 0644]
models/vehicles/rockets_gloss.tga [new file with mode: 0644]
models/vehicles/rockets_glow.tga [new file with mode: 0644]
models/vehicles/rockets_reflect.tga [new file with mode: 0644]
models/vehicles/spiderbot.dpm
models/vehicles/spiderbot.dpm.framegroups
models/vehicles/spiderbot_cockpit.dpm
models/vehicles/spiderbot_top.dpm
models/vehicles/spinner.dpm
models/vehicles/tracer.md3 [new file with mode: 0644]
models/vehicles/tracercore.tga [new file with mode: 0644]
models/vehicles/tracertrail.tga [new file with mode: 0644]
models/vehicles/tracertrail_glow.tga [new file with mode: 0644]
qcsrc/client/Main.qc
qcsrc/client/View.qc
qcsrc/client/casings.qc
qcsrc/client/csqc_constants.qc
qcsrc/client/damage.qc
qcsrc/client/hud.qc
qcsrc/client/progs.src
qcsrc/client/projectile.qc
qcsrc/client/vehicles/racer.qc [new file with mode: 0644]
qcsrc/client/vehicles/raptor.qc [new file with mode: 0644]
qcsrc/client/vehicles/spiderbot.qc [new file with mode: 0644]
qcsrc/client/vehicles/vehicles.qc [new file with mode: 0644]
qcsrc/client/vehicles/vehicles.qh [new file with mode: 0644]
qcsrc/common/constants.qh
qcsrc/qc-client.cbp
qcsrc/server/autocvars.qh
qcsrc/server/cl_client.qc
qcsrc/server/cl_player.qc
qcsrc/server/ctf.qc
qcsrc/server/movelib.qc
qcsrc/server/progs.src
qcsrc/server/vehicles/bumblebee.qc [new file with mode: 0644]
qcsrc/server/vehicles/collision.qc [new file with mode: 0644]
qcsrc/server/vehicles/network.qc [new file with mode: 0644]
qcsrc/server/vehicles/racer.qc
qcsrc/server/vehicles/raptor.qc
qcsrc/server/vehicles/spiderbot.qc
qcsrc/server/vehicles/vehicles.qc
qcsrc/server/vehicles/vehicles.qh
qcsrc/server/vehicles/vehicles_def.qh [new file with mode: 0644]
qcsrc/server/w_common.qc
scripts/vehicles.shader [new file with mode: 0644]
scripts/vrockets.shader [new file with mode: 0644]
sound/vehicles/alarm.wav [new file with mode: 0644]
sound/vehicles/alarm_shield.wav [new file with mode: 0644]
sound/vehicles/lock.wav [new file with mode: 0644]
sound/vehicles/locked.wav [new file with mode: 0644]
sound/vehicles/locking.wav [new file with mode: 0644]
sound/vehicles/racer_boost.wav [new file with mode: 0644]
sound/vehicles/racer_idle.wav [new file with mode: 0644]
sound/vehicles/racer_move.wav [new file with mode: 0644]
sound/vehicles/raptor_fly.wav [new file with mode: 0644]
sound/vehicles/raptor_speed.wav [new file with mode: 0644]
sound/vehicles/spiderbot_die.wav [new file with mode: 0644]
sound/vehicles/spiderbot_idle.wav [new file with mode: 0644]
sound/vehicles/spiderbot_jump.wav [new file with mode: 0644]
sound/vehicles/spiderbot_land.wav [new file with mode: 0644]
sound/vehicles/spiderbot_strafe.wav [new file with mode: 0644]
sound/vehicles/spiderbot_walk.wav [new file with mode: 0644]
textures/cockpit_gloss.tga [new file with mode: 0644]
textures/cockpit_reflect.tga [new file with mode: 0644]
textures/raptor.jpg [deleted file]
textures/raptor.tga [new file with mode: 0644]
textures/raptor_cockpit.jpg [deleted file]
textures/spiderbot_reflect.tga [new file with mode: 0644]
textures/wakazachi_gloss.jpg [new file with mode: 0644]
textures/wakazachi_glow.tga [new file with mode: 0644]
textures/wakazachi_reflect.tga [new file with mode: 0644]
vehicle_bumblebee.cfg [new file with mode: 0644]
vehicle_racer.cfg
vehicle_raptor.cfg
vehicle_spiderbot.cfg
vehicles.cfg [new file with mode: 0644]

index e2b476c..6378e3f 100644 (file)
@@ -1691,11 +1691,11 @@ effect crylink_impact
 countabsolute 1
 type decal
 tex 47 47
-size 24 24
+size 8 8
 alpha 256 256 0
 originjitter 12 12 12
-//lightradius 200
-//lightradiusfade 800
+//lightradius 60
+//lightradiusfade 300
 //lightcolor 3.2 0.4 4
 // purple flare effect
 effect crylink_impact
@@ -1703,34 +1703,34 @@ countabsolute 1
 type static
 tex 39 39
 color 0x504060 0x504060
-size 24 24
+size 8 8
 alpha 256 256 512
 // purple sparks
 effect crylink_impact
-count 40
+count 10
 type spark
 tex 41 41
 color 0xA040C0 0xA040C0
 bounce 2
-size 6 6
+size 1 2
 alpha 256 256 1024
-velocityjitter 512 512 512
+velocityjitter 256 256 256
 // purple splash
 effect crylink_impact
 count 1.5
 type static
 color 0xE070FF 0xE070FF
-size 16 16
+size 8 8
 alpha 256 256 512
-velocityjitter 32 32 32
+velocityjitter 8 8 8
 // purple splash
 effect crylink_impact
-count 3
+count 1.5
 type static
 color 0xE070FF 0xE070FF
-size 16 16
+size 8 8
 alpha 256 256 1024
-velocityjitter 256 256 256
+velocityjitter 32 32 32
 
 
 
@@ -2269,6 +2269,7 @@ bounce 1.6
 velocityjitter 324 324 524
 rotate -180 180 -1000 1000
 
+
 // used in qcsrc/server/g_hook.qc:     pointparticles(particleeffectnum("grapple_muzzleflash"), org, '0 0 0', 1)
 effect grapple_muzzleflash
 lightradius 160
@@ -5195,65 +5196,1152 @@ velocitymultiplier 15
 airfriction -1
 rotate 0 360 -180 180
 
-// seeker missile trail
-effect TR_SEEKER
+// ---------------vechicles
+
+effect spiderbot_minigun_trail
+notunderwater
 trailspacing 10
 type smoke
-notunderwater
-color 0x000000 0x666666
+color 0xd0d0a0 0xffffff
 tex 0 8
-size 2 2
-bounce 1
-sizeincrease 11
-alpha 200 300 200
-lightradius 100
-lighttime 0
-lightcolor 6 3 1
+size 1 2
+alpha 20 50 100
+sizeincrease 2
+velocityjitter 5 5 5
+gravity -0.03
+airfriction 1
+
+effect spiderbot_minigun_muzzleflash
+count 3
+type spark
+color 0xff9c00 0xff8400
+tex 48 55
+size 10 15
+alpha 256 512 6280
+airfriction 10
 originjitter 2 2 2
-velocityjitter 3 3 3
-velocitymultiplier -0.02
-rotate -180 180 -30 30
-//gravity -0.11
+velocityjitter 150 150 150
+velocitymultiplier 0.35
+sizeincrease -100
+stretchfactor 1.3
+rotate -180 180 4000 -4000
 // fire
-effect TR_SEEKER
-trailspacing 4
+effect spiderbot_minigun_muzzleflash
+count 6
+type spark
+color 0xff9c00 0xff8400
+tex 8 15
+size 5 7
+alpha 256 512 6280
+airfriction 12
+originjitter 2 2 2
+velocityjitter 200 200 200
+velocitymultiplier 0.2
+sizeincrease -10
+stretchfactor 0.8
+effect spiderbot_minigun_muzzleflash
+countabsolute 2
 type static
-color 0xffdf72 0x811200
 tex 48 55
-size 5 5
-sizeincrease -30
-alpha 100 144 588
+color 0xff9c00 0xff8400
+size 32 32
+alpha 256 512 6680
+sizeincrease -100
+stretchfactor 0.1
+rotate -180 180 4000 -4000
+lightradius 120
+lightradiusfade 8000
+lightcolor 3 3 0
+
+effect spiderbot_minigun_impact
+countabsolute 1
+type static
+tex 65 65
+color 0xff9c00 0xf6ff00
+size 52 52
+alpha 50 100 1680
+sizeincrease -100
+stretchfactor 0.1
+rotate -180 180 4000 -4000
+// fire
+effect spiderbot_minigun_impact
+count 7
+type spark
+color 0xff9c00 0xff8400
+tex 48 55
+size 9 15
+alpha 256 512 6280
+airfriction 10
+originjitter 2 2 2
+velocityjitter 250 250 150
+velocitymultiplier 0.2
+sizeincrease 100
+stretchfactor 3
+airfriction 6
+rotate -180 180 4000 -4000
+// smoke 
+effect spiderbot_minigun_impact
+count 6
+type smoke
+color 0xd0d0a0 0xffffff
+tex 0 8
+size 10 20
+alpha 50 50 190
+sizeincrease 80
+velocityjitter 100 100 250
+velocitymultiplier 0.49
+gravity 1.3
+airfriction 10
+rotate -180 180 0 0
+// smoke 2
+effect spiderbot_minigun_impact
+count 7
+type spark
+color 0xd0d0a0 0xffffff
+tex 0 8
+size 15 19
+alpha 25 51 128
+airfriction 6
+originjitter 2 2 2
+velocityjitter 250 250 150
+velocitymultiplier 0.2
+sizeincrease 100
+stretchfactor 7.6
+// derbis
+effect spiderbot_minigun_impact
+notunderwater
+count 3
+type alphastatic
+tex 66 68
+color 0x99977D 0xFFFFFF
+size 6 8
+alpha 644 756 1484
+gravity 1.1
+airfriction 0.4
+sizeincrease -10
+velocitymultiplier 0.15
+originjitter 16 16 16
+velocityjitter 124 124 224
+rotate -180 180 -1000 1000
+// decal
+effect spiderbot_minigun_impact
+countabsolute 1
+type decal
+tex 56 59
+size 20 25
+alpha 256 256 0
+originjitter 16 16 16
+rotate -180 180 0 0
+
+effect spiderbot_rocket_explode
+countabsolute 1
+type decal
+tex 8 16
+size 72 72
+alpha 256 256 0
+originjitter 23 23 23
+lightradius 300
+lightradiusfade 1750
+lightcolor 8 4 0
+// shockwave
+effect spiderbot_rocket_explode
+countabsolute 1
+type static
+tex 33 33 
+size 22 22
+alpha 56 56 230
+color 0x8f0d00 0xff5a00
+sizeincrease 2400
+// glow
+effect spiderbot_rocket_explode
+countabsolute 1
+type static
+tex 64 64
+size 120 120
+alpha 156 156 830
+color 0x8f0d00 0xff5a00
+sizeincrease 240
+// fire effect
+effect spiderbot_rocket_explode
+notunderwater
+count 32
+type static
+tex 48 55
+color 0x8f0d00 0xff5a00
+size 12 21
+sizeincrease 495
+alpha 200 256 812
 airfriction 8
-velocityjitter 32 32 32
-velocitymultiplier -1.5
-// bubbles
-effect TR_SEEKER
-type bubble
+liquidfriction 8
+originjitter 100 100 100
+velocityjitter 512 512 512
+rotate -180 180 -50 50
+// fire effect 2
+effect spiderbot_rocket_explode
+notunderwater
+count 16
+type spark
+tex 48 55
+color 0x8f0d00 0xff5a00
+size 3 3
+sizeincrease 120
+alpha 200 256 912
+airfriction -2
+liquidfriction 8
+velocityjitter 412 412 412
+rotate -180 180 -150 150
+stretchfactor 10
+// fire rays
+effect spiderbot_rocket_explode
+notunderwater
+count 10
+type spark
+tex 48 55
+color 0x8f0d00 0xff5a00
+size 13 54
+sizeincrease 120
+alpha 200 256 1600
+airfriction -3
+liquidfriction 8
+originjitter 40 40 40
+velocityjitter 712 712 712
+stretchfactor 10
+// smoke
+effect spiderbot_rocket_explode
+type alphastatic
+notunderwater
+tex 0 8
+count 10
+size 10 15
+sizeincrease 280
+alpha 300 650 756
+originjitter 100 100 100
+velocityjitter 200 200 200
+airfriction 3
+color 0x4F4B46 0x000000
+rotate -180 180 -20 20
+// smoke2
+effect spiderbot_rocket_explode
+type alphastatic
+notunderwater
+tex 0 8
+count 3
+size 100 150
+sizeincrease 30
+alpha 300 650 556
+originjitter 10 10 10
+velocityjitter 200 200 200
+airfriction 2
+gravity -0.5
+color 0x4F4B46 0x000000
+rotate -180 180 -20 20
+// underwater bubbles
+effect spiderbot_rocket_explode
 underwater
-trailspacing 16
+count 32
+type bubble
 tex 62 62
-size 1 2
-alpha 256 256 256
+color 0x404040 0x808080
+size 1 3
+alpha 128 256 64
 gravity -0.125
 bounce 1.5
-liquidfriction 4
-velocityjitter 16 16 16
-velocitymultiplier -0.31
-rotate 0 0 0 0
-// sparks
-effect TR_SEEKER
+liquidfriction 0.25
+originjitter 160 160 160
+velocityjitter 144 144 144
+// underwatershockwave
+effect spiderbot_rocket_explode
+underwater
+type smoke
+countabsolute 1
+tex 33 33
+size 30 30
+sizeincrease 1200
+alpha 40 40 300
+
+
+effect spiderbot_rocket_thrust
 notunderwater
-trailspacing 20
+count 3
 type spark
-tex 40 40
-color 0xFFFDD9 0xFFFDD9
-size 0.5 0.5
-alpha 444 512 1866
-stretchfactor 0.3
-//gravity 1
-bounce 1
-//velocityoffset 0 0 15
-airfriction 5
-originjitter 1 1 1
-velocityjitter 100 100 100
-velocitymultiplier -0.31
+tex 48 55
+color 0x8f0d00 0xff5a00
+size 5 10
+sizeincrease -40
+alpha 200 256 1600
+velocityjitter 20 20 20
+velocitymultiplier -1.4
+stretchfactor 0.9
+effect spiderbot_rocket_thrust
+notunderwater
+count 4
+type static
+tex 48 55
+color 0x8f0d00 0xff5a00
+size 25 25
+sizeincrease -3000
+alpha 200 200 9000
+velocityjitter 60 60 60
+velocitymultiplier -1.4
+stretchfactor 1
+rotate -180 180 -500 500
+
+
+
+// long lasting smoke
+effect spiderbot_rocket_launch
+notunderwater
+count 8
+type smoke
+tex 0 8
+color 0xFFFFFF 0xD9C4B0
+size 30 30
+sizeincrease 20
+alpha 100 156 60
+velocityjitter 60 60 60
+velocitymultiplier -0.1
+airfriction 0.3
+gravity -0.01
+// fast smoke
+effect spiderbot_rocket_launch
+notunderwater
+count 14
+type smoke
+tex 0 8
+color 0xFFFFFF 0xD9C4B0
+size 30 30
+sizeincrease 20
+alpha 100 156 260
+gravity -0.3
+velocityjitter 160 160 60
+airfriction 0.3
+// fire
+effect spiderbot_rocket_launch
+notunderwater
+count 14
+type spark
+tex 48 55
+color 0x8f0d00 0xff5a00
+size 30 30
+sizeincrease 40
+velocitymultiplier 0.5
+alpha 200 256 1960
+velocityjitter 60 60 60
+airfriction 0.3
+stretchfactor 3
+airfriction 0.3
+//sparks
+effect spiderbot_rocket_launch
+notunderwater
+count 10
+type spark
+tex 40 40
+color 0xFFFFFF 0xD9C4B0
+size 1 4
+alpha 200 256 1000
+velocityjitter 160 160 160
+velocitymultiplier -0.5
+
+effect wakizashi_gun_impact
+count 15
+type spark
+color 0xff0000 0xc03535
+tex 41 41
+size 4 7
+alpha 256 512 1180
+airfriction 4
+gravity 3
+originjitter 40 40 10
+velocityjitter 350 350 550
+velocityoffset 0 0 700
+stretchfactor 0.9
+effect wakizashi_gun_impact
+type smoke
+count 24
+color 0xd0d0a0 0xc03535
+tex 0 8
+size 10 20
+alpha 50 90 150
+sizeincrease 80
+velocityjitter 250 250 450
+velocityoffset 0 0 600
+originjitter 40 40 10
+airfriction 4
+sizeincrease 80
+rotate -180 180 0 0
+effect wakizashi_gun_impact
+countabsolute 1
+type smoke
+tex 65 65
+color 0xff0000 0xc03535
+size 82 82
+alpha 250 300 680
+sizeincrease -180
+effect wakizashi_gun_impact
+countabsolute 1
+type smoke
+tex 33 33
+color 0xff0000 0xc03535
+size 40 40
+alpha 50 100 620
+sizeincrease 900
+rotate -180 180 400 -400
+effect wakizashi_gun_impact
+countabsolute 1
+type decal
+tex 59 59
+size 14 14
+alpha 256 256 0
+originjitter 16 16 16
+rotate -180 180 0 0
+
+effect wakizashi_gun_muzzleflash
+count 16
+type spark
+color 0xff0000 0xc03535
+tex 8 15
+size 5 7
+alpha 256 512 6280
+airfriction 12
+originjitter 2 2 2
+velocityjitter 200 200 200
+velocitymultiplier 0.2
+sizeincrease -10
+stretchfactor 0.7
+
+effect wakizashi_rocket_explode
+countabsolute 1
+type decal
+tex 8 16
+size 72 72
+alpha 256 256 0
+originjitter 23 23 23
+lightradius 300
+lightradiusfade 1750
+lightcolor 8 4 0
+// shockwave
+effect wakizashi_rocket_explode
+countabsolute 1
+type static
+tex 33 33 
+size 22 22
+alpha 56 56 230
+color 0x8f0d00 0xff5a00
+sizeincrease 2400
+// glow
+effect wakizashi_rocket_explode
+countabsolute 1
+type static
+tex 64 64
+size 120 120
+alpha 156 156 830
+color 0x8f0d00 0xff5a00
+sizeincrease 240
+// fire effect
+effect wakizashi_rocket_explode
+notunderwater
+count 64
+type static
+tex 48 55
+color 0xFFAE00 0xff5a00
+size 12 21
+sizeincrease 195
+alpha 200 256 512
+airfriction 2
+liquidfriction 8
+originjitter 10 10 10
+velocityjitter 512 512 512
+rotate -180 180 -50 50
+// fire rays
+effect wakizashi_rocket_explode
+notunderwater
+count 10
+type spark
+tex 48 55
+color 0xFFEA00 0xff5a00
+size 43 54
+sizeincrease 120
+alpha 200 256 1600
+airfriction -3
+liquidfriction 8
+originjitter 40 40 40
+velocityjitter 512 512 512
+stretchfactor 10
+// smoke
+effect wakizashi_rocket_explode
+type alphastatic
+notunderwater
+tex 0 8
+count 32
+size 10 15
+sizeincrease 230
+alpha 300 450 556
+originjitter 100 100 100
+velocityjitter 200 200 200
+airfriction 3
+color 0x4F4B46 0x000000
+rotate -180 180 -20 20
+// bouncing sparks
+effect wakizashi_rocket_explode
+notunderwater
+count 14
+type spark
+tex 40 40
+color 0xffa35b 0xfff2be
+size 1 2
+alpha 644 956 884
+gravity 1
+airfriction 1
+liquidfriction 0.8
+velocityoffset 0 0 170
+originjitter 60 60 60
+velocityjitter 524 524 524
+// underwater bubbles
+effect wakizashi_rocket_explode
+underwater
+count 32
+type bubble
+tex 62 62
+color 0x404040 0x808080
+size 1 3
+alpha 128 256 64
+gravity -0.125
+bounce 1.5
+liquidfriction 0.25
+originjitter 160 160 160
+velocityjitter 144 144 144
+// underwatershockwave
+effect wakizashi_rocket_explode
+underwater
+type smoke
+countabsolute 1
+tex 33 33
+size 30 30
+sizeincrease 1200
+alpha 40 40 300
+
+effect wakizashi_rocket_thrust
+notunderwater
+countabsolute 3
+type spark
+tex 48 55
+color 0x00FFDD 0x6200FF
+size 14 19
+sizeincrease -2
+alpha 200 256 1600
+velocityjitter 60 60 60
+velocitymultiplier -1.1
+stretchfactor 1
+effect wakizashi_rocket_thrust
+notunderwater
+countabsolute 2
+type spark
+tex 48 55
+color 0xFFFF33 0xFFEE00
+size 5 10
+sizeincrease -2
+alpha 200 256 1900
+velocityjitter 60 60 60
+velocitymultiplier -0.3
+stretchfactor 3
+
+// long lasting smoke
+effect wakizashi_rocket_launch
+notunderwater
+count 8
+type smoke
+tex 0 8
+color 0xFFFFFF 0xD9C4B0
+size 3 30
+sizeincrease 20
+alpha 100 156 60
+velocityjitter 160 160 60
+velocitymultiplier -0.1
+airfriction 0.3
+// fast smoke
+effect wakizashi_rocket_launch
+notunderwater
+count 14
+type smoke
+tex 0 8
+color 0xFFFFFF 0xD9C4B0
+size 30 30
+sizeincrease 20
+alpha 100 156 260
+velocityjitter 160 160 60
+velocitymultiplier 0.4
+airfriction 0.3
+//sparks
+effect wakizashi_rocket_launch
+notunderwater
+count 10
+type spark
+tex 40 40
+color 0xFFFFFF 0xD9C4B0
+size 1 4
+alpha 200 256 1000
+velocityjitter 60 60 60
+velocitymultiplier -1.5
+
+effect wakizashi_booster_smoke
+type alphastatic
+notunderwater
+tex 0 8
+count 3
+size 60 100
+sizeincrease 10
+gravity -0.1
+alpha 200 750 200
+velocityjitter 40 40 40
+originjitter 60 60 60
+airfriction 2
+color 0xA69A80 0xB3B39F
+rotate -180 180 -20 20
+
+// decal
+effect raptor_cannon_impact
+countabsolute 1
+type decal
+tex 47 47
+size 24 24
+alpha 256 256 0
+originjitter 16 16 16
+rotate -180 180 0 0
+//spark
+effect raptor_cannon_impact
+notunderwater
+count 6
+type spark
+tex 40 40
+color 0xD400FF 0x571863
+size 1 1
+alpha 644 956 784
+gravity 1
+airfriction 0.2
+velocityoffset 0 0 150
+originjitter 16 16 16
+velocityjitter 124 124 524
+// smoke
+effect raptor_cannon_impact
+count 4
+type alphastatic
+tex 0 7
+size 50 50
+color 0x646364 0x151515
+alpha 428 428 600
+rotate -180 180 0 0
+velocityjitter 200 200 300
+velocityoffset 0 0 340
+gravity 0.7
+airfriction 2
+// fire
+effect raptor_cannon_impact
+notunderwater
+count 10
+type static
+tex 48 55
+color 0xD400FF 0x571863
+size 33 44
+sizeincrease 25
+alpha 200 256 812
+bounce 1.5
+airfriction 8
+liquidfriction 8
+originjitter 8 8 8
+velocityjitter 312 312 312
+
+
+effect raptor_cannon_muzzleflash
+count 16
+type spark
+color 0xD400FF 0x571863
+tex 8 15
+size 10 17
+alpha 1256 1512 56280
+airfriction 12
+originjitter 2 2 2
+velocityjitter 200 200 200
+velocitymultiplier 0.2
+sizeincrease -10
+stretchfactor 0.6
+effect raptor_cannon_muzzleflash
+countabsolute 1
+type static
+tex 48 55
+color 0xD400FF 0x571863
+size 32 32
+alpha 6056 20112 406280
+sizeincrease -100
+stretchfactor 0.1
+rotate -180 180 4000 -4000
+lightradius 150
+lightradiusfade 6000
+lightcolor 3 0 6
+
+// decal
+effect raptor_bomb_impact
+countabsolute 1
+type decal
+tex 8 16
+size 84 84
+alpha 256 256 0
+originjitter 16 16 16
+rotate -180 180 0 0
+
+//spark vertical
+effect raptor_bomb_impact
+count 3
+type spark
+color 0xff9c00 0xff3c00
+tex 48 55
+size 20 40
+alpha 300 300 600
+originjitter 10 10 10
+velocityjitter 40 40 120
+stretchfactor 210
+sizeincrease 50
+
+//fire
+effect raptor_bomb_impact
+count 4
+type static 
+color 0xff9c00 0xff3c00
+tex 48 55
+size 30 120
+alpha 300 300 500
+originjitter 10 10 10
+velocityjitter 950 950 0
+sizeincrease 230
+airfriction 2
+
+//smoke
+effect raptor_bomb_impact
+count 4
+type spark
+blend alpha
+tex 0 7
+size 120 180
+color 0x646364 0x151515
+alpha 428 428 600
+rotate -180 180 0 0
+velocityjitter 200 200 280
+velocityoffset 0 0 280
+originjitter 30 30 10
+stretchfactor 10
+
+//smoke 2
+effect raptor_bomb_impact
+count 4
+//type alphastatic
+type spark
+blend alpha
+tex 0 7
+size 40 100
+color 0x646364 0x151515
+alpha 328 328 350
+rotate -180 180 0 0
+velocityjitter 200 200 300
+velocityoffset 0 0 580
+originjitter 30 30 10
+sizeincrease 60
+airfriction 0.6
+gravity 2
+
+// sparks
+effect raptor_bomb_impact
+notunderwater
+count 5
+type spark
+tex 40 40
+color 0xffa35b 0xfff2be
+size 3 5
+alpha 644 956 984
+gravity 1
+airfriction 0.3
+velocityoffset 0 0 350
+originjitter 16 16 16
+velocityjitter 174 174 924
+stretchfactor 2
+
+effect raptor_bomb_spread
+notunderwater
+count 34
+type spark
+tex 40 40
+color 0xffa35b 0xfff2be
+size 1 2
+alpha 644 956 1284
+gravity 1
+airfriction 1
+liquidfriction 0.8
+originjitter 110 110 110
+velocityjitter 324 324 324
+
+
+// generic explosion size:big (biggest explosion ever)
+effect explosion_big
+countabsolute 1
+type decal
+tex 8 16
+size 172 172
+alpha 256 256 0
+originjitter 23 23 23
+lightradius 600
+lightradiusfade 1750
+lightcolor 8 4 0
+// shockwave
+effect explosion_big
+countabsolute 1
+type static
+tex 33 33 
+size 72 72
+alpha 56 56 330
+color 0x8f0d00 0xff5a00
+sizeincrease 4400
+// fire effect
+effect explosion_big
+notunderwater
+count 64
+type static
+tex 48 55
+color 0x8f0d00 0xff5a00
+size 133 144
+sizeincrease 45
+alpha 200 256 712
+airfriction 8
+liquidfriction 8
+originjitter 80 80 80
+velocityjitter 2512 2512 2512
+// fire rays
+effect explosion_big
+notunderwater
+count 64
+type spark
+tex 48 55
+color 0x8f0d00 0xff5a00
+size 133 144
+sizeincrease 45
+alpha 200 256 800
+airfriction -5
+liquidfriction 8
+originjitter 40 40 40
+velocityjitter 512 512 512
+stretchfactor 10
+// smoke
+effect explosion_big
+type alphastatic
+notunderwater
+tex 0 8
+count 32
+size 50 100
+sizeincrease 244
+alpha 300 650 456
+velocityjitter 3444 3444 3444
+airfriction 8
+color 0x4F4B46 0x000000
+// bouncing sparks
+effect explosion_big
+notunderwater
+count 34
+type spark
+tex 40 40
+color 0xffa35b 0xfff2be
+size 3 4
+alpha 644 956 1284
+gravity 1
+airfriction 1
+liquidfriction 0.8
+velocityoffset 0 0 370
+originjitter 160 160 160
+velocityjitter 924 924 924
+stretchfactor 0.7
+// derbis
+effect explosion_big
+notunderwater
+count 16
+type alphastatic
+tex 66 68
+color 0xFFFFFF 0xcac5b4
+size 10 16
+alpha 444 1356 1184
+gravity 2.3
+airfriction 0.5
+velocityjitter 1800 1800 1800
+velocityoffset 0 0 970
+sizeincrease -5
+rotate -180 180 -1000 1000
+// underwater bubbles
+effect explosion_big
+underwater
+count 32
+type bubble
+tex 62 62
+color 0x404040 0x808080
+size 3 3
+alpha 128 256 64
+gravity -0.125
+bounce 1.5
+liquidfriction 0.25
+originjitter 160 160 160
+velocityjitter 444 444 444
+// underwatershockwave
+effect explosion_big
+underwater
+type smoke
+countabsolute 1
+tex 33 33
+size 30 30
+sizeincrease 2900
+alpha 40 40 300
+velocitymultiplier 0.3
+
+
+// generic explosion size:medium (it leaves rising smoke for a longer time)
+// shockwave
+effect explosion_medium
+countabsolute 1
+type static
+tex 33 33 
+size 72 72
+alpha 56 56 330
+color 0x8f0d00 0xff5a00
+sizeincrease 2400
+// fire effect
+effect explosion_medium
+notunderwater
+count 32
+type static
+tex 48 55
+color 0x8f0d00 0xff5a00
+size 133 144
+sizeincrease 45
+alpha 200 256 712
+airfriction 8
+liquidfriction 8
+originjitter 30 30 30
+velocityjitter 1512 1512 1512
+rotate -180 180 -500 500
+// fire effect 2
+effect explosion_medium
+notunderwater
+count 32
+type static
+tex 48 55
+color 0x8f0d00 0xff5a00
+size 73 94
+sizeincrease 40
+gravity -2
+alpha 200 256 612
+airfriction 8
+liquidfriction 8
+originjitter 30 30 30
+velocityjitter 1512 1512 1512
+rotate -180 180 -150 150
+// fire rays
+effect explosion_medium
+notunderwater
+count 14
+type spark
+tex 48 55
+color 0x8f0d00 0xff5a00
+size 43 74
+sizeincrease 40
+alpha 200 256 800
+airfriction -3
+liquidfriction 8
+originjitter 40 40 40
+velocityjitter 512 512 512
+stretchfactor 8
+// smoke 
+effect explosion_medium
+type alphastatic
+notunderwater
+tex 0 8
+count 5
+size 250 300
+sizeincrease -30
+alpha 300 650 756
+originjitter 100 100 100
+velocityjitter 200 200 200
+airfriction 3
+color 0x4F4B46 0x000000
+rotate -180 180 -20 20
+// smoke 2
+effect explosion_medium
+type alphastatic
+notunderwater
+tex 0 8
+count 10
+size 50 100
+sizeincrease 50
+gravity -0.3
+alpha 300 650 256
+originjitter 100 100 100
+velocityjitter 500 500 500
+velocityoffset 0 0 200
+airfriction 3
+color 0x4F4B46 0x000000
+rotate -180 180 -20 20
+// smoke rays
+effect explosion_medium
+type spark
+notunderwater
+tex 0 8
+count 13
+size 150 200
+sizeincrease 100
+alpha 140 255 350
+velocityjitter 250 250 250
+originjitter 40 40 40
+color 0x4F4B46 0x000000
+stretchfactor 50
+// bouncing sparks
+effect explosion_medium
+notunderwater
+count 14
+type spark
+tex 40 40
+color 0xffa35b 0xfff2be
+size 2 3
+alpha 644 956 984
+gravity 1
+airfriction 1
+liquidfriction 0.8
+velocityoffset 0 0 370
+originjitter 100 100 100
+velocityjitter 624 624 624
+stretchfactor 0.7
+// underwater bubbles
+effect explosion_medium
+underwater
+count 32
+type bubble
+tex 62 62
+color 0x404040 0x808080
+size 3 3
+alpha 128 256 64
+gravity -0.125
+bounce 1.5
+liquidfriction 0.25
+originjitter 160 160 160
+velocityjitter 444 444 444
+// underwatershockwave
+effect explosion_medium
+underwater
+type smoke
+countabsolute 1
+tex 33 33
+size 30 30
+sizeincrease 2900
+alpha 40 40 300
+velocitymultiplier 0.3
+
+// generic explosion size:small (its fire only, made to support other explosions)
+// shockwave
+effect explosion_small
+countabsolute 1
+type static
+tex 33 33 
+size 22 22
+alpha 56 56 330
+color 0x8f0d00 0xff5a00
+sizeincrease 2400
+// fire effect
+effect explosion_small
+notunderwater
+count 16
+type static
+tex 48 55
+color 0x8f0d00 0xff5a00
+size 1 44
+sizeincrease 45
+alpha 200 256 1212
+airfriction 5
+liquidfriction 8
+velocityjitter 512 512 512
+rotate -180 180 -500 500
+// fire effect 2
+effect explosion_small
+notunderwater
+count 16
+type static
+tex 48 55
+color 0x8f0d00 0xff5a00
+size 73 94
+sizeincrease 40
+alpha 200 256 812
+airfriction 8
+liquidfriction 8
+velocityjitter 912 912 912
+rotate -180 180 -150 150
+// fire rays
+effect explosion_small
+notunderwater
+count 14
+type spark
+tex 48 55
+color 0x8f0d00 0xff5a00
+size 13 54
+sizeincrease 30
+alpha 200 256 1300
+airfriction -3
+liquidfriction 8
+originjitter 40 40 40
+velocityjitter 512 512 512
+stretchfactor 8
+// underwater bubbles
+effect explosion_small
+underwater
+count 32
+type bubble
+tex 62 62
+color 0x404040 0x808080
+size 1 3
+alpha 128 256 64
+gravity -0.125
+bounce 1.5
+liquidfriction 0.25
+originjitter 160 160 160
+velocityjitter 144 144 144
+// underwatershockwave
+effect explosion_small
+underwater
+type smoke
+countabsolute 1
+tex 33 33
+size 30 30
+sizeincrease 1200
+alpha 40 40 300
+
+// big smoke ( for spamming on damaged stuff )
+effect smoke_big
+type alphastatic
+notunderwater
+tex 0 8
+count 3
+size 30 60
+sizeincrease 15
+gravity -0.5
+alpha 200 750 200
+originjitter 55 55 55
+velocityjitter 140 140 200
+velocityoffset 0 0 200
+airfriction 4
+color 0x4F4B46 0x000000
+rotate -180 180 -20 20
+
+// small smoke ( more precise than big one, for spamming on damaged parts like raptors spinner )
+effect smoke_small
+type alphastatic
+notunderwater
+tex 0 8
+count 3
+size 60 100
+sizeincrease -10
+gravity -0.5
+alpha 200 750 200
+velocityjitter 40 40 400
+velocityoffset 0 0 200
+airfriction 4
+color 0x4F4B46 0x000000
+rotate -180 180 -20 20
\ No newline at end of file
diff --git a/gfx/vehicles/axh-bracket.tga b/gfx/vehicles/axh-bracket.tga
new file mode 100644 (file)
index 0000000..82f0796
Binary files /dev/null and b/gfx/vehicles/axh-bracket.tga differ
diff --git a/gfx/vehicles/axh-cross.tga b/gfx/vehicles/axh-cross.tga
new file mode 100644 (file)
index 0000000..69e1c0b
Binary files /dev/null and b/gfx/vehicles/axh-cross.tga differ
diff --git a/gfx/vehicles/axh-dropcross.tga b/gfx/vehicles/axh-dropcross.tga
new file mode 100644 (file)
index 0000000..e8ba095
Binary files /dev/null and b/gfx/vehicles/axh-dropcross.tga differ
diff --git a/gfx/vehicles/axh-ring.tga b/gfx/vehicles/axh-ring.tga
new file mode 100644 (file)
index 0000000..bb3ade5
Binary files /dev/null and b/gfx/vehicles/axh-ring.tga differ
diff --git a/gfx/vehicles/axh-special1.tga b/gfx/vehicles/axh-special1.tga
new file mode 100644 (file)
index 0000000..184a065
Binary files /dev/null and b/gfx/vehicles/axh-special1.tga differ
diff --git a/gfx/vehicles/axh-special2.tga b/gfx/vehicles/axh-special2.tga
new file mode 100644 (file)
index 0000000..caad1d7
Binary files /dev/null and b/gfx/vehicles/axh-special2.tga differ
diff --git a/gfx/vehicles/axh-tag.tga b/gfx/vehicles/axh-tag.tga
new file mode 100644 (file)
index 0000000..4eb3b66
Binary files /dev/null and b/gfx/vehicles/axh-tag.tga differ
diff --git a/gfx/vehicles/axh-target.tga b/gfx/vehicles/axh-target.tga
new file mode 100644 (file)
index 0000000..8c05908
Binary files /dev/null and b/gfx/vehicles/axh-target.tga differ
diff --git a/gfx/vehicles/axh-x.tga b/gfx/vehicles/axh-x.tga
new file mode 100644 (file)
index 0000000..f6a4fce
Binary files /dev/null and b/gfx/vehicles/axh-x.tga differ
diff --git a/gfx/vehicles/bar_dwn_left.tga b/gfx/vehicles/bar_dwn_left.tga
new file mode 100644 (file)
index 0000000..011f9a9
Binary files /dev/null and b/gfx/vehicles/bar_dwn_left.tga differ
diff --git a/gfx/vehicles/bar_dwn_right.tga b/gfx/vehicles/bar_dwn_right.tga
new file mode 100644 (file)
index 0000000..e93b5e6
Binary files /dev/null and b/gfx/vehicles/bar_dwn_right.tga differ
diff --git a/gfx/vehicles/bar_up_left.tga b/gfx/vehicles/bar_up_left.tga
new file mode 100644 (file)
index 0000000..f49d205
Binary files /dev/null and b/gfx/vehicles/bar_up_left.tga differ
diff --git a/gfx/vehicles/bar_up_right.tga b/gfx/vehicles/bar_up_right.tga
new file mode 100644 (file)
index 0000000..a3b5910
Binary files /dev/null and b/gfx/vehicles/bar_up_right.tga differ
diff --git a/gfx/vehicles/bullets.tga b/gfx/vehicles/bullets.tga
new file mode 100644 (file)
index 0000000..ff853ee
Binary files /dev/null and b/gfx/vehicles/bullets.tga differ
diff --git a/gfx/vehicles/frame.tga b/gfx/vehicles/frame.tga
new file mode 100644 (file)
index 0000000..92a6573
Binary files /dev/null and b/gfx/vehicles/frame.tga differ
diff --git a/gfx/vehicles/health.tga b/gfx/vehicles/health.tga
new file mode 100644 (file)
index 0000000..3956a3f
Binary files /dev/null and b/gfx/vehicles/health.tga differ
diff --git a/gfx/vehicles/hud_bg.tga b/gfx/vehicles/hud_bg.tga
deleted file mode 100644 (file)
index a2ba3b3..0000000
Binary files a/gfx/vehicles/hud_bg.tga and /dev/null differ
diff --git a/gfx/vehicles/raptor.tga b/gfx/vehicles/raptor.tga
new file mode 100644 (file)
index 0000000..9a2519a
Binary files /dev/null and b/gfx/vehicles/raptor.tga differ
diff --git a/gfx/vehicles/raptor_bombs.tga b/gfx/vehicles/raptor_bombs.tga
new file mode 100644 (file)
index 0000000..9012fb2
Binary files /dev/null and b/gfx/vehicles/raptor_bombs.tga differ
diff --git a/gfx/vehicles/raptor_guns.tga b/gfx/vehicles/raptor_guns.tga
new file mode 100644 (file)
index 0000000..0d0012a
Binary files /dev/null and b/gfx/vehicles/raptor_guns.tga differ
diff --git a/gfx/vehicles/rocket.tga b/gfx/vehicles/rocket.tga
new file mode 100644 (file)
index 0000000..f0385b9
Binary files /dev/null and b/gfx/vehicles/rocket.tga differ
diff --git a/gfx/vehicles/shield.tga b/gfx/vehicles/shield.tga
new file mode 100644 (file)
index 0000000..916268f
Binary files /dev/null and b/gfx/vehicles/shield.tga differ
diff --git a/gfx/vehicles/shiled.tga b/gfx/vehicles/shiled.tga
deleted file mode 100644 (file)
index bd728e2..0000000
Binary files a/gfx/vehicles/shiled.tga and /dev/null differ
diff --git a/gfx/vehicles/vh-shield.tga b/gfx/vehicles/vh-shield.tga
new file mode 100644 (file)
index 0000000..bd728e2
Binary files /dev/null and b/gfx/vehicles/vh-shield.tga differ
diff --git a/models/vehicles/bomblet.md3 b/models/vehicles/bomblet.md3
new file mode 100644 (file)
index 0000000..55ca725
Binary files /dev/null and b/models/vehicles/bomblet.md3 differ
diff --git a/models/vehicles/bumblebee.tga b/models/vehicles/bumblebee.tga
new file mode 100644 (file)
index 0000000..a20e851
Binary files /dev/null and b/models/vehicles/bumblebee.tga differ
diff --git a/models/vehicles/bumblebee_body.dpm b/models/vehicles/bumblebee_body.dpm
new file mode 100644 (file)
index 0000000..9962dd7
Binary files /dev/null and b/models/vehicles/bumblebee_body.dpm differ
diff --git a/models/vehicles/bumblebee_gloss.tga b/models/vehicles/bumblebee_gloss.tga
new file mode 100644 (file)
index 0000000..bbfb176
Binary files /dev/null and b/models/vehicles/bumblebee_gloss.tga differ
diff --git a/models/vehicles/bumblebee_glow.tga b/models/vehicles/bumblebee_glow.tga
new file mode 100644 (file)
index 0000000..c688168
Binary files /dev/null and b/models/vehicles/bumblebee_glow.tga differ
diff --git a/models/vehicles/bumblebee_norm.tga b/models/vehicles/bumblebee_norm.tga
new file mode 100644 (file)
index 0000000..0ab707c
Binary files /dev/null and b/models/vehicles/bumblebee_norm.tga differ
diff --git a/models/vehicles/bumblebee_pants.tga b/models/vehicles/bumblebee_pants.tga
new file mode 100644 (file)
index 0000000..32d0aa5
Binary files /dev/null and b/models/vehicles/bumblebee_pants.tga differ
diff --git a/models/vehicles/bumblebee_plasma_left.dpm b/models/vehicles/bumblebee_plasma_left.dpm
new file mode 100644 (file)
index 0000000..57df41a
Binary files /dev/null and b/models/vehicles/bumblebee_plasma_left.dpm differ
diff --git a/models/vehicles/bumblebee_plasma_right.dpm b/models/vehicles/bumblebee_plasma_right.dpm
new file mode 100644 (file)
index 0000000..1689979
Binary files /dev/null and b/models/vehicles/bumblebee_plasma_right.dpm differ
diff --git a/models/vehicles/bumblebee_ray.dpm b/models/vehicles/bumblebee_ray.dpm
new file mode 100644 (file)
index 0000000..2e36eb5
Binary files /dev/null and b/models/vehicles/bumblebee_ray.dpm differ
diff --git a/models/vehicles/clusterbomb.md3 b/models/vehicles/clusterbomb.md3
new file mode 100644 (file)
index 0000000..c0842df
Binary files /dev/null and b/models/vehicles/clusterbomb.md3 differ
diff --git a/models/vehicles/clusterbomb_folded.md3 b/models/vehicles/clusterbomb_folded.md3
new file mode 100644 (file)
index 0000000..f1b65a6
Binary files /dev/null and b/models/vehicles/clusterbomb_folded.md3 differ
diff --git a/models/vehicles/clusterbomb_fragment.md3 b/models/vehicles/clusterbomb_fragment.md3
new file mode 100644 (file)
index 0000000..516da16
Binary files /dev/null and b/models/vehicles/clusterbomb_fragment.md3 differ
index 83518c5..bbd758a 100644 (file)
Binary files a/models/vehicles/raptor.dpm and b/models/vehicles/raptor.dpm differ
diff --git a/models/vehicles/raptor_body.dpm b/models/vehicles/raptor_body.dpm
new file mode 100644 (file)
index 0000000..2a28317
Binary files /dev/null and b/models/vehicles/raptor_body.dpm differ
index fe933e4..d321f37 100644 (file)
Binary files a/models/vehicles/raptor_cockpit.dpm and b/models/vehicles/raptor_cockpit.dpm differ
diff --git a/models/vehicles/rocket01.md3 b/models/vehicles/rocket01.md3
new file mode 100644 (file)
index 0000000..1d9aab9
Binary files /dev/null and b/models/vehicles/rocket01.md3 differ
diff --git a/models/vehicles/rocket02.md3 b/models/vehicles/rocket02.md3
new file mode 100644 (file)
index 0000000..0a3eef0
Binary files /dev/null and b/models/vehicles/rocket02.md3 differ
diff --git a/models/vehicles/rockets.tga b/models/vehicles/rockets.tga
new file mode 100644 (file)
index 0000000..a6b873c
Binary files /dev/null and b/models/vehicles/rockets.tga differ
diff --git a/models/vehicles/rockets_gloss.tga b/models/vehicles/rockets_gloss.tga
new file mode 100644 (file)
index 0000000..22616da
Binary files /dev/null and b/models/vehicles/rockets_gloss.tga differ
diff --git a/models/vehicles/rockets_glow.tga b/models/vehicles/rockets_glow.tga
new file mode 100644 (file)
index 0000000..14c9f30
Binary files /dev/null and b/models/vehicles/rockets_glow.tga differ
diff --git a/models/vehicles/rockets_reflect.tga b/models/vehicles/rockets_reflect.tga
new file mode 100644 (file)
index 0000000..3cad23f
Binary files /dev/null and b/models/vehicles/rockets_reflect.tga differ
index eeb5e92..2b5624f 100644 (file)
Binary files a/models/vehicles/spiderbot.dpm and b/models/vehicles/spiderbot.dpm differ
index f9db722..835bd3b 100644 (file)
@@ -1,6 +1,17 @@
-1   30  20 1 // forward
-32  30  20 1 // backward
-63  30  20 1 // left
-94  30 20 1 // right
-125 30 20 0 // jump
-0   1   20 0 // idle
+/*
+Generated framegroups file for spiderbot
+Used by DarkPlaces to simulate frame groups in DPM models.
+*/
+
+1 31 30 1 // spiderbot forward
+32 31 30 1 // spiderbot backwards
+63 31 20 1 // spiderbot left
+94 31 20 1 // spiderbot right
+125 31 20 0 // spiderbot jump
+156 1 1 0 // spiderbot idle
+157 12 20 0 // spiderbot jump2
+169 7 20 0 // spiderbot jump_charge
+176 11 15 0 // spiderbot jump_fly
+187 21 20 0 // spiderbot jump_land
+208 51 15 0 // spiderbot death
+259 3 1 0 // spiderbot dead
index 8d64449..a851f3e 100644 (file)
Binary files a/models/vehicles/spiderbot_cockpit.dpm and b/models/vehicles/spiderbot_cockpit.dpm differ
index 5085e6b..e9209ba 100644 (file)
Binary files a/models/vehicles/spiderbot_top.dpm and b/models/vehicles/spiderbot_top.dpm differ
index d3d83b4..7e453f2 100644 (file)
Binary files a/models/vehicles/spinner.dpm and b/models/vehicles/spinner.dpm differ
diff --git a/models/vehicles/tracer.md3 b/models/vehicles/tracer.md3
new file mode 100644 (file)
index 0000000..81ef34b
Binary files /dev/null and b/models/vehicles/tracer.md3 differ
diff --git a/models/vehicles/tracercore.tga b/models/vehicles/tracercore.tga
new file mode 100644 (file)
index 0000000..811db46
Binary files /dev/null and b/models/vehicles/tracercore.tga differ
diff --git a/models/vehicles/tracertrail.tga b/models/vehicles/tracertrail.tga
new file mode 100644 (file)
index 0000000..38a4f03
Binary files /dev/null and b/models/vehicles/tracertrail.tga differ
diff --git a/models/vehicles/tracertrail_glow.tga b/models/vehicles/tracertrail_glow.tga
new file mode 100644 (file)
index 0000000..75ff134
Binary files /dev/null and b/models/vehicles/tracertrail_glow.tga differ
index c9fbc87..4e54f81 100644 (file)
@@ -47,7 +47,7 @@ void WaypointSprite_Load();
 void CSQC_Init(void)
 {
        prvm_language = cvar_string("prvm_language");
-       
+
 #ifdef USE_FTE
 #pragma target ID
        __engine_check = checkextension("DP_SV_WRITEPICTURE");
@@ -139,6 +139,8 @@ void CSQC_Init(void)
        GibSplash_Precache();
        Casings_Precache();
        DamageInfo_Precache();
+       Vehicles_Precache();
+
        if(autocvar_cl_announcer != cl_announcer_prev) {
                Announcer_Precache();
                if(cl_announcer_prev)
@@ -902,7 +904,7 @@ void Ent_ReadAccuracy(void)
                        weapon_accuracy[w] = -1;
                return;
        }
-       
+
        for(w = 0, f = 1; w <= WEP_LAST - WEP_FIRST; ++w, f *= 2)
        {
                if(sf & f)
@@ -984,6 +986,7 @@ void(float bIsNewEntity) CSQC_Ent_Update =
                case ENT_CLIENT_LGBEAM: Ent_ReadHook(bIsNewEntity, ENT_CLIENT_LGBEAM); break;
                case ENT_CLIENT_GAUNTLET: Ent_ReadHook(bIsNewEntity, ENT_CLIENT_GAUNTLET); break;
                case ENT_CLIENT_ACCURACY: Ent_ReadAccuracy(); break;
+               case ENT_CLIENT_AUXILIARYXHAIR: Net_AuXair2(bIsNewEntity); break;
                default:
                        //error(strcat(_("unknown entity type in CSQC_Ent_Update: %d\n"), self.enttype));
                        error(sprintf(_("Unknown entity type in CSQC_Ent_Update (enttype: %d, edict: %d, classname: %s)\n"), self.enttype, num_for_edict(self), self.classname));
@@ -1410,6 +1413,10 @@ float CSQC_Parse_TempEntity()
                        Net_WeaponComplain();
                        bHandled = true;
                        break;
+        case TE_CSQC_VEHICLESETUP:
+            Net_VehicleSetup();
+            bHandled = true;
+            break;
                default:
                        // No special logic for this temporary entity; return 0 so the engine can handle it
                        bHandled = false;
index 8c7f87c..e26eca3 100644 (file)
@@ -1,12 +1,3 @@
-#define spider_rocket_icon "gfx/vehicles/rocket_ico.tga"
-#define spider_rocket_targ "gfx/vehicles/target.tga"
-#define SPIDER_CROSS "textures/spiderbot/cross.tga"
-#define rkt_size 32
-#define rld_size_x 256
-#define rld_size_y 16
-
-void CSQC_WAKIZASHI_HUD();
-
 entity porto;
 vector polyline[16];
 float trace_dphitcontents;
@@ -377,6 +368,8 @@ void CSQC_UpdateView(float w, float h)
        vector v, vo;
        vector vf_size, vf_min;
        float a;
+       float hud;
+       hud = getstati(STAT_HUD);
 
        button_attack2 = (input_buttons & BUTTON_3);
        button_zoom = (input_buttons & BUTTON_4);
@@ -725,7 +718,7 @@ void CSQC_UpdateView(float w, float h)
        {
                float contentalpha_temp, incontent, liquidalpha, contentfadetime;
                vector liquidcolor;
-               
+
                switch(pointcontents(view_origin))
                {
                        case CONTENT_WATER:
@@ -733,26 +726,26 @@ void CSQC_UpdateView(float w, float h)
                                liquidcolor = stov(autocvar_hud_contents_water_color);
                                incontent = 1;
                                break;
-                               
+
                        case CONTENT_LAVA:
                                liquidalpha = autocvar_hud_contents_lava_alpha;
                                liquidcolor = stov(autocvar_hud_contents_lava_color);
                                incontent = 1;
-                               break;  
-                                                       
+                               break;
+
                        case CONTENT_SLIME:
                                liquidalpha = autocvar_hud_contents_slime_alpha;
                                liquidcolor = stov(autocvar_hud_contents_slime_color);
                                incontent = 1;
                                break;
-                               
+
                        default:
                                liquidalpha = 0;
                                liquidcolor = '0 0 0';
                                incontent = 0;
                                break;
                }
-               
+
                if(incontent) // fade in/out at different speeds so you can do e.g. instant fade when entering water and slow when leaving it.
                { // also lets delcare previous values for blending properties, this way it isn't reset until after you have entered a different content
                        contentfadetime = autocvar_hud_contents_fadeintime;
@@ -761,15 +754,16 @@ void CSQC_UpdateView(float w, float h)
                }
                else
                        contentfadetime = autocvar_hud_contents_fadeouttime;
-                       
+
                contentalpha_temp = bound(0, drawframetime / max(0.0001, contentfadetime), 1);
                contentavgalpha = contentavgalpha * (1 - contentalpha_temp) + incontent * contentalpha_temp;
-               
+
                if(contentavgalpha)
                        drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, liquidcolor_prev, contentavgalpha * liquidalpha_prev, DRAWFLAG_NORMAL);
        }
        
        if(autocvar_hud_damage && !autocvar_chase_active)
+
        {
                splash_size_x = max(vid_conwidth, vid_conheight);
                splash_size_y = max(vid_conwidth, vid_conheight);
@@ -866,14 +860,14 @@ void CSQC_UpdateView(float w, float h)
                nextsound_typehit_time = time + autocvar_cl_hitsound_antispam_time;
        }
 
-       float hud;
-       hud = getstati(STAT_HUD);
        if(hud == HUD_SPIDERBOT)
                CSQC_SPIDER_HUD();
        else if(hud == HUD_WAKIZASHI)
         CSQC_WAKIZASHI_HUD();
     else if(hud == HUD_RAPTOR)
         CSQC_RAPTOR_HUD();
+    else if(hud == HUD_BUMBLEBEE)
+        CSQC_BUMBLE_HUD();
        else
        {
                if(gametype == GAME_FREEZETAG)
@@ -959,13 +953,13 @@ void CSQC_UpdateView(float w, float h)
                        else if(autocvar_crosshair_color_by_health)
                        {
                                local float x = getstati(STAT_HEALTH);
-                               
+
                                //x = red
                                //y = green
                                //z = blue
-                               
+
                                wcross_color_z = 0;
-                               
+
                                if(x > 200)
                                {
                                        wcross_color_x = 0;
@@ -986,7 +980,7 @@ void CSQC_UpdateView(float w, float h)
                                {
                                        wcross_color_x = 1;
                                        wcross_color_y = 1;
-                                       wcross_color_z = 0.2 + (x-50)*0.02 * 0.8;  
+                                       wcross_color_z = 0.2 + (x-50)*0.02 * 0.8;
                                }
                                else if(x > 20)
                                {
@@ -1030,7 +1024,7 @@ void CSQC_UpdateView(float w, float h)
 
                                wcross_scale += sin(pickup_crosshair_size) * autocvar_crosshair_pickup;
                        }
-                       
+
                        vector hitindication_color;
                        if(autocvar_crosshair_hitindication)
                        {
@@ -1114,7 +1108,7 @@ void CSQC_UpdateView(float w, float h)
                                float ring_value, ring_scale, ring_alpha, ring_inner_value, ring_inner_alpha;
                                string ring_image, ring_inner_image;
                                vector ring_rgb, ring_inner_rgb;
-                               
+
                                ring_scale = autocvar_crosshair_ring_size;
 
                                float weapon_clipload, weapon_clipsize;
@@ -1127,30 +1121,30 @@ void CSQC_UpdateView(float w, float h)
 
                                if(nex_charge_movingavg == 0) // this should only happen if we have just loaded up the game
                                        nex_charge_movingavg = nex_charge;
-                                       
+
 
                                // handle the values
                                if (autocvar_crosshair_ring && activeweapon == WEP_NEX && nex_charge && autocvar_crosshair_ring_nex) // ring around crosshair representing velocity-dependent damage for the nex
                                {
-                                       if (nex_chargepool || use_nex_chargepool) { 
-                                               use_nex_chargepool = 1; 
+                                       if (nex_chargepool || use_nex_chargepool) {
+                                               use_nex_chargepool = 1;
                                                ring_inner_value = nex_chargepool;
-                                       } else { 
+                                       } else {
                                                nex_charge_movingavg = (1 - autocvar_crosshair_ring_nex_currentcharge_movingavg_rate) * nex_charge_movingavg + autocvar_crosshair_ring_nex_currentcharge_movingavg_rate * nex_charge;
-                                               ring_inner_value = bound(0, autocvar_crosshair_ring_nex_currentcharge_scale * (nex_charge - nex_charge_movingavg), 1); 
+                                               ring_inner_value = bound(0, autocvar_crosshair_ring_nex_currentcharge_scale * (nex_charge - nex_charge_movingavg), 1);
                                        }
-                                               
+
                                        ring_inner_alpha = autocvar_crosshair_ring_nex_inner_alpha;
                                        ring_inner_rgb = eX * autocvar_crosshair_ring_nex_inner_color_red + eY * autocvar_crosshair_ring_nex_inner_color_green + eZ * autocvar_crosshair_ring_nex_inner_color_blue;
                                        ring_inner_image = "gfx/crosshair_ring_inner.tga";
-                                       
+
                                        // draw the outer ring to show the current charge of the weapon
                                        ring_value = nex_charge;
                                        ring_alpha = autocvar_crosshair_ring_nex_alpha;
                                        ring_rgb = wcross_color;
                                        ring_image = "gfx/crosshair_ring_nexgun.tga";
                                }
-                               else if (autocvar_crosshair_ring && activeweapon == WEP_MINE_LAYER && minelayer_maxmines && autocvar_crosshair_ring_minelayer) 
+                               else if (autocvar_crosshair_ring && activeweapon == WEP_MINE_LAYER && minelayer_maxmines && autocvar_crosshair_ring_minelayer)
                                {
                                        ring_value = bound(0, getstati(STAT_LAYED_MINES) / minelayer_maxmines, 1); // if you later need to use the count of bullets in another place, then add a float for it. For now, no need to.
                                        ring_alpha = autocvar_crosshair_ring_minelayer_alpha;
@@ -1165,13 +1159,13 @@ void CSQC_UpdateView(float w, float h)
                                        ring_image = "gfx/crosshair_ring.tga";
                                }
 
-                               if(autocvar_crosshair_ring_reload && weapon_clipsize) // forces there to be only an ammo ring 
+                               if(autocvar_crosshair_ring_reload && weapon_clipsize) // forces there to be only an ammo ring
                                {
                                        ring_value = bound(0, weapon_clipload / weapon_clipsize, 1);
                                        ring_scale = autocvar_crosshair_ring_reload_size;
                                        ring_alpha = autocvar_crosshair_ring_reload_alpha;
                                        ring_rgb = wcross_color;
-                                       
+
                                        // Note: This is to stop Taoki from complaining that the image doesn't match all potential balances.
                                        // if a new image for another weapon is added, add the code (and its respective file/value) here
                                        if ((activeweapon == WEP_RIFLE) && (weapon_clipsize == 80))
@@ -1299,297 +1293,6 @@ void CSQC_UpdateView(float w, float h)
        R_SetView(VF_SIZE, '1 0 0' * w + '0 1 0' * h);
 }
 
-#define spider_h "gfx/vehicles/hud_bg.tga"
-#define spider_b "gfx/vehicles/sbot.tga"
-#define spider_r "gfx/vehicles/sbot_rpods.tga"
-#define spider_g "gfx/vehicles/sbot_mguns.tga"
-#define spider_s "gfx/vehicles/shiled.tga"
-#define spider_a1 "gfx/hud/sb_rocket.tga"
-#define spider_a2 "gfx/sb_bullets.tga"
-
-void CSQC_SPIDER_HUD()
-{
-       float rockets, reload, heat, hp, shield;
-       vector picsize, hudloc;
-
-    // Fetch health & ammo stats
-    hp      = bound(0,getstatf(STAT_VEHICLESTAT_HEALTH), 1);
-       shield  = bound(0,getstatf(STAT_VEHICLESTAT_SHIELD), 1);
-       heat    = min(getstatf(STAT_VEHICLESTAT_RELOAD1), 2);
-       rockets =     getstati(STAT_VEHICLESTAT_AMMO2);
-       reload  = min(getstatf(STAT_VEHICLESTAT_RELOAD2), 1);
-
-    // Draw the crosshairs
-    picsize = drawgetimagesize(SPIDER_CROSS);
-    picsize_x *= autocvar_cl_vehicle_spiderbot_cross_size;
-    picsize_y *= autocvar_cl_vehicle_spiderbot_cross_size;
-    drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), SPIDER_CROSS, picsize, '1 1 1', autocvar_cl_vehicle_spiderbot_cross_alpha, DRAWFLAG_NORMAL);
-
-    hudloc_y =  4;
-    hudloc_x = 4;
-
-    picsize = drawgetimagesize(spider_h) * 0.5;
-    drawpic(hudloc, spider_h, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-
-    picsize = drawgetimagesize(spider_a2) * 0.5;
-    drawpic(hudloc + '120 96  0', spider_a2, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-
-    drawstring(hudloc + '145 19  0', strcat(ftos(rint(hp * 100)), "%"),'15 15 0','0 1 0', 1, DRAWFLAG_NORMAL);
-    drawstring(hudloc + '175 34  0', strcat(ftos(rint(shield * 100)), "%"),'15 15 0','0 0 1', 1, DRAWFLAG_NORMAL);
-    drawstring(hudloc + '136 102  0', strcat(ftos(100 - rint(heat * 100)), "%"),'14 14 0','1 1 0', 1, DRAWFLAG_NORMAL);
-
-    picsize = drawgetimagesize(spider_a1) * 0.85;
-    if(rockets == 9)
-    {
-        drawpic(hudloc + '132 54  0', spider_a1, picsize, '-1 -1 -1', 1, DRAWFLAG_NORMAL);
-        drawstring(hudloc + '179 69 0', strcat(ftos(rint(reload * 100)), "%"),'14 14 0','1 1 0', 1, DRAWFLAG_NORMAL);
-    }
-    else
-    {
-        drawpic(hudloc + '132 54  0', spider_a1, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-        drawstring(hudloc + '179 69  0', strcat(ftos(9 - rockets), "/8"),'14 14 0','1 1 0', 1, DRAWFLAG_NORMAL);
-    }
-
-    picsize = drawgetimagesize(spider_b) * 0.5;
-    hudloc_y = 10.5;
-    hudloc_x = 10.5;
-
-    drawpic(hudloc, spider_s, picsize, '1 1 1', shield, DRAWFLAG_NORMAL);
-    drawpic(hudloc, spider_b, picsize, '0 1 0' * hp + '1 0 0' * (1 - hp), 1, DRAWFLAG_NORMAL);
-    drawpic(hudloc, spider_r, picsize, '1 1 1' * reload + '1 0 0' * (1 - reload), 1, DRAWFLAG_NORMAL);
-    drawpic(hudloc, spider_g, picsize, '1 1 1' * (1 - heat) + '1 0 0' *  heat, 1, DRAWFLAG_NORMAL);
-
-
-       /*
-       // Draw health bar
-       p = '0.5 0 0' * (vid_conwidth - (rkt_size * 8));
-       p = p + '0 1 0' * vid_conheight - '0 32 0';
-       //pp = ('0 1 0' * hp) + ('1 0 0' * (1-hp));
-       drawfill(p, '256 0 0' * shield + '0 8 0' , '0.5 0.5 1', 0.75, DRAWFLAG_NORMAL);
-       p_y += 8;
-       drawfill(p, '256 0 0' * hp + '0 8 0' , '0 1 0', 0.75, DRAWFLAG_NORMAL);
-       p_x += 256 * hp;
-       drawfill(p, '256 0 0' * (1-hp) + '0 8 0' , '0 0 0', 0.75, DRAWFLAG_NORMAL);
-
-       // Draw minigun heat indicator
-       p = '0.5 0 0' * (vid_conwidth - 256);
-       p = p + '0 1 0' * vid_conheight - '0 34  0';
-       drawfill(p, '256 0 0' * (1-heat) + '0 2 0' ,'0 0 1', 0.5, DRAWFLAG_NORMAL);
-       p_x += 256 * (1-heat);
-       drawfill(p, '256 0 0' * heat  + '0 2 0' , '1 0 0', 0.5, DRAWFLAG_NORMAL);
-
-
-       // Draw rocket icons for loaded/empty tubes.
-       pp = '0.5 0 0' * (vid_conwidth - (rkt_size * 8));
-       pp += '0 1 0' * vid_conheight - '0 64 0';
-       for(i = 0; i < 8; ++i)
-       {
-               p = pp + '1 0 0' * (rkt_size * i);
-               if(rockets == 8)
-               {
-                       if(floor(reload * 8) == i)
-                       {
-                               drawpic(p, spider_rocket_icon, '1 1 0' * rkt_size, '1 0 0' + '0 1 0' * ((reload*8)-i), 0.75 , DRAWFLAG_NORMAL);
-                       }
-                       else if(i < reload * 8)
-                               drawpic(p, spider_rocket_icon, '1 1 0' * rkt_size, '1 1 0', 0.75 , DRAWFLAG_NORMAL);
-                       else
-                               drawpic(p, spider_rocket_icon, '1 1 0' * rkt_size, '0.5 0.5 0.5', 0.75, DRAWFLAG_NORMAL);
-               }
-               else
-               {
-                       if(i < rockets)
-                               drawpic(p, spider_rocket_icon, '1 1 0' * rkt_size, '0 0 0', 0.25, DRAWFLAG_NORMAL);
-                       else
-                               drawpic(p, spider_rocket_icon, '1 1 0' * rkt_size, '0 1 0' * reload, 0.75, DRAWFLAG_NORMAL);
-               }
-       }
-       */
-
-       if (scoreboard_showscores)
-       {
-               HUD_DrawScoreboard();
-               HUD_DrawCenterPrint();
-       }
-
-}
-
-#define raptor_h "gfx/vehicles/hud_bg.tga"
-#define raptor_b "gfx/vehicles/raptor.tga"
-#define raptor_g1 "gfx/vehicles/raptor_guns.tga"
-#define raptor_g2 "gfx/vehicles/raptor_bombs.tga"
-#define raptor_s "gfx/vehicles/shiled.tga"
-
-void CSQC_RAPTOR_HUD()
-{
-       float reload, hp, shield, energy;
-       vector picsize, hudloc;
-
-    // Fetch health & ammo stats
-    hp      = bound(0,getstatf(STAT_VEHICLESTAT_HEALTH), 1);
-       shield  = bound(0,getstatf(STAT_VEHICLESTAT_SHIELD), 1);
-       reload  = min(getstatf(STAT_VEHICLESTAT_RELOAD1), 1);
-       energy  = min(getstatf(STAT_VEHICLESTAT_ENERGY),  1);
-
-    // Draw the crosshairs
-    picsize = drawgetimagesize(SPIDER_CROSS);
-    picsize_x *= autocvar_cl_vehicle_spiderbot_cross_size;
-    picsize_y *= autocvar_cl_vehicle_spiderbot_cross_size;
-    drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), SPIDER_CROSS, picsize, '1 1 1', autocvar_cl_vehicle_spiderbot_cross_alpha, DRAWFLAG_NORMAL);
-
-    hudloc_y =  4;
-    hudloc_x = 4;
-
-    picsize = drawgetimagesize(raptor_h) * 0.5;
-    drawpic(hudloc, raptor_h, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-
-    picsize = drawgetimagesize(spider_a2) * 0.5;
-    drawpic(hudloc + '120 96  0', spider_a2, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-
-    drawstring(hudloc + '145 19  0', strcat(ftos(rint(hp * 100)), "%"),'15 15 0','0 1 0', 1, DRAWFLAG_NORMAL);
-    drawstring(hudloc + '175 34  0', strcat(ftos(rint(shield * 100)), "%"),'15 15 0','0 0 1', 1, DRAWFLAG_NORMAL);
-    drawstring(hudloc + '136 102 0', strcat(ftos(rint(energy * 100)), "%"),'15 15 0','0.5 0.5 1', 1, DRAWFLAG_NORMAL);
-
-
-    picsize = drawgetimagesize(spider_a1) * 0.85;
-    if(reload == 1)
-    {
-        drawpic(hudloc + '132 54  0', spider_a1, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-        drawstring(hudloc + '179 69  0', strcat(ftos(rint(reload * 100)), "%"),'14 14 0','0 1 0', 0.5, DRAWFLAG_NORMAL);
-    }
-    else
-    {
-        drawpic(hudloc + '132 54  0', spider_a1, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-        drawstring(hudloc + '179 69  0', strcat(ftos(rint(reload * 100)), "%"),'14 14 0','0 0 1', 1, DRAWFLAG_NORMAL);
-    }
-
-    picsize = drawgetimagesize(raptor_b) * 0.5;
-    hudloc_y = 10.5;
-    hudloc_x = 10.5;
-
-    drawpic(hudloc, raptor_s, picsize, '1 1 1', shield, DRAWFLAG_NORMAL);
-    drawpic(hudloc, raptor_b, picsize, '0 1 0' * hp + '1 0 0' * (1 - hp), 1, DRAWFLAG_NORMAL);
-    drawpic(hudloc, raptor_g1, picsize, '1 1 1' * energy + '1 0 0' * (1 - energy), 1, DRAWFLAG_NORMAL);
-    drawpic(hudloc, raptor_g2, picsize, '1 1 1' * reload + '1 0 0' *  (1 - reload), 1, DRAWFLAG_NORMAL);
-
-
-       if (scoreboard_showscores)
-       {
-               HUD_DrawScoreboard();
-               HUD_DrawCenterPrint();
-       }
-
-}
-
-#define waki_h "gfx/vehicles/hud_bg.tga"
-#define waki_b "gfx/vehicles/waki.tga"
-#define waki_e "gfx/vehicles/waki_e.tga"
-#define waki_g "gfx/vehicles/waki_guns.tga"
-#define waki_r "gfx/vehicles/waki_rockets.tga"
-#define waki_s "gfx/vehicles/shiled.tga"
-
-#define waki_a1 "gfx/hud/sb_rocket.tga"
-#define waki_a2 "gfx/sb_cells.tga"
-
-void CSQC_WAKIZASHI_HUD()
-{
-       // 0--1 floats. 1 = 100%, 0.6 = 50%.
-       float health, shield, energy, rockets;
-       vector picsize, hudloc;
-
-    picsize = drawgetimagesize(SPIDER_CROSS);
-    picsize_x *= autocvar_cl_vehicle_spiderbot_cross_size;
-    picsize_y *= autocvar_cl_vehicle_spiderbot_cross_size;
-    drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), SPIDER_CROSS, picsize, '1 1 1', autocvar_cl_vehicle_spiderbot_cross_alpha, DRAWFLAG_NORMAL);
-
-/*
-const float STAT_VEHICLESTAT_HEALTH  = 60;
-const float STAT_VEHICLESTAT_SHIELD  = 61;
-const float STAT_VEHICLESTAT_ENERGY  = 62;
-const float STAT_VEHICLESTAT_AMMO1   = 63;
-const float STAT_VEHICLESTAT_RELAOD1 = 64;
-const float STAT_VEHICLESTAT_AMMO2   = 65;
-const float STAT_VEHICLESTAT_RELOAD2 = 66;
-*/
-    health  = min(getstatf(STAT_VEHICLESTAT_HEALTH),  1);
-       shield  = min(getstatf(STAT_VEHICLESTAT_SHIELD),  1);
-       energy  = min(getstatf(STAT_VEHICLESTAT_ENERGY),  1);
-       rockets = bound(0,getstatf(STAT_VEHICLESTAT_RELOAD1), 1);
-
-    hudloc_y =  4;
-    hudloc_x = 4;
-
-    picsize = drawgetimagesize(waki_h) * 0.5;
-    drawpic(hudloc, waki_h, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-
-    picsize = drawgetimagesize(waki_a2) * 0.7;
-    drawpic(hudloc + '116 92  0', waki_a2, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-
-
-    drawstring(hudloc + '145 19  0', strcat(ftos(rint(health * 100)), "%"),'15 15 0','0 1 0', 1, DRAWFLAG_NORMAL);
-    drawstring(hudloc + '175 34  0', strcat(ftos(rint(shield * 100)), "%"),'15 15 0','0 0 1', 1, DRAWFLAG_NORMAL);
-
-    drawstring(hudloc + '136 102  0', strcat(ftos(rint(energy * 100)), "%"),'14 14 0','1 1 1', 1, DRAWFLAG_NORMAL);
-
-    picsize = drawgetimagesize(waki_a1) * 0.75;
-    if(rockets == 1)
-    {
-        drawpic(hudloc + '140 55  0', waki_a1, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-        drawpic(hudloc + '144 59  0', waki_a1, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
-    }
-    else
-    {
-        drawpic(hudloc + '140 55  0', waki_a1, picsize, '-1 -1 -1', 1, DRAWFLAG_NORMAL);
-        drawpic(hudloc + '144 59  0', waki_a1, picsize, '-1 -1 -1', 1, DRAWFLAG_NORMAL);
-        drawstring(hudloc + '165 69 0', strcat(ftos(rint(rockets * 100)), "%"),'14 14 0','1 1 0', 1, DRAWFLAG_NORMAL);
-    }
-
-    picsize = drawgetimagesize(waki_b) * 0.5;
-    hudloc_y = 10.5;
-    hudloc_x = 10.5;
-
-    drawpic(hudloc, waki_s, picsize, '1 1 1', shield, DRAWFLAG_NORMAL);
-    drawpic(hudloc, waki_b, picsize, '0 1 0' * health + '1 0 0' * (1 - health), 1, DRAWFLAG_NORMAL);
-    drawpic(hudloc, waki_r, picsize, '1 1 1' * rockets + '1 0 0' * (1 - rockets), 1, DRAWFLAG_NORMAL);
-    drawpic(hudloc, waki_e, picsize, '1 1 1' * energy + '1 0 0' *  (1 - energy), 1, DRAWFLAG_NORMAL);
-
-
-
-       /*
-       p = '0.5 0 0' * (vid_conwidth - (rkt_size * 8));
-       p = p + '0 1 0' * vid_conheight - '0 32 0';
-
-       // Draw health bar
-       p_y += 8;
-       drawfill(p, '256 0 0' * health + '0 8 0' , '0 0.7 0', 0.75, DRAWFLAG_NORMAL);
-       p_x += 256 * health;
-       drawfill(p, '256 0 0' * (1 - health) + '0 8 0' , '0 0 0', 0.75, DRAWFLAG_NORMAL);
-
-       // Draw shiled bar
-       p_x -= 256 * health;
-       p_y += 4;
-       drawfill(p, '256 0 0' * shield + '0 4 0' , '0.25 0.25 1', 0.5, DRAWFLAG_NORMAL);
-
-       // Draw energy
-       //p_x -= 256 * health;
-       p_y -= 8;
-       drawfill(p, '256 0 0' * energy + '0 4 0' , '1 1 1', 0.75, DRAWFLAG_NORMAL);
-
-       // Draw rockets bar
-       p_y += 12;
-       drawfill(p, '256 0 0' * rockets + '0 4 0' , '1 0 0', 0.75, DRAWFLAG_NORMAL);
-       */
-
-
-
-
-       if (scoreboard_showscores)
-       {
-               HUD_DrawScoreboard();
-               HUD_DrawCenterPrint();
-       }
-
-}
 
 void CSQC_common_hud(void)
 {
@@ -1625,7 +1328,7 @@ void CSQC_common_hud(void)
                        HUD_DrawScoreboard();
 
                        if (scoreboard_active) // scoreboard/accuracy
-                       {       
+                       {
                                HUD_Reset();
                                // HUD_DrawScoreboard takes care of centerprint_start
                        }
@@ -1653,6 +1356,11 @@ void CSQC_common_hud(void)
                case HUD_WAKIZASHI:
                        CSQC_WAKIZASHI_HUD();
                        break;
+
+        case HUD_BUMBLEBEE:
+            CSQC_BUMBLE_HUD();
+            break;
+
        }
 }
 
index 860e829..423896f 100644 (file)
@@ -75,7 +75,7 @@ void Ent_Casing(float isNew)
 {
        entity casing;
 
-       casing = RubbleNew("casing");
+    casing = RubbleNew("casing");
        casing.state = ReadByte();
        casing.silent = (casing.state & 0x80);
        casing.state = (casing.state & 0x7F);
index 93051cc..5976eb9 100644 (file)
@@ -164,7 +164,6 @@ const float BUTTON_14 = 65536;
 const float BUTTON_15 = 131072;
 const float BUTTON_16 = 262144;
 
-
 const float DRAWFLAG_NORMAL = 0;
 const float DRAWFLAG_ADDITIVE = 1;
 const float DRAWFLAG_MODULATE = 2;
index 783f667..cd33855 100644 (file)
@@ -69,9 +69,80 @@ void Ent_DamageInfo(float isNew)
        }
 
        self = oldself;
-
-       // TODO spawn particle effects and sounds based on w_deathtype
        
+       if(DEATH_ISVEHICLE(w_deathtype))
+       {
+           traceline(w_org - normalize(force) * 16, w_org + normalize(force) * 16, MOVE_NOMONSTERS, world);
+           if(trace_plane_normal != '0 0 0')       
+            w_backoff = trace_plane_normal;
+        else
+            w_backoff = -1 * normalize(w_org - (w_org + normalize(force) * 16));
+           
+           setorigin(self, w_org + w_backoff * 2); // for sound() calls
+           
+           switch(w_deathtype)
+           {            
+            case DEATH_VHCRUSH:
+                break;
+                
+            case DEATH_SBMINIGUN:
+                string _snd;
+                _snd = strcat("weapons/ric", ftos(1 + rint(random() * 2)), ".waw");
+                sound(self, CHAN_PROJECTILE, _snd, VOL_BASE, ATTN_NORM);
+                pointparticles(particleeffectnum("spiderbot_minigun_impact"), self.origin, w_backoff * 1000, 1);
+                break;
+            case DEATH_SBROCKET:
+                sound(self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
+                pointparticles(particleeffectnum("spiderbot_rocket_explode"), self.origin, w_backoff * 1000, 1);
+                break;
+            case DEATH_SBBLOWUP:
+                sound(self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_MIN);
+                pointparticles(particleeffectnum("explosion_big"), self.origin, w_backoff * 1000, 1);
+                break;
+                
+            case DEATH_WAKIGUN:
+                sound(self, CHAN_PROJECTILE, "weapons/laserimpact.wav", VOL_BASE, ATTN_NORM);
+                pointparticles(particleeffectnum("wakizashi_gun_impact"), self.origin, w_backoff * 1000, 1);
+                break;
+            case DEATH_WAKIROCKET:
+                sound(self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
+                pointparticles(particleeffectnum("wakizashi_rocket_explode"), self.origin, w_backoff * 1000, 1);
+                break;
+            case DEATH_WAKIBLOWUP:
+                sound(self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_MIN);
+                pointparticles(particleeffectnum("explosion_big"), self.origin, w_backoff * 1000, 1);
+                break;
+                
+            case DEATH_RAPTOR_CANNON:
+                sound(self, CHAN_PROJECTILE, "weapons/laserimpact.wav", VOL_BASE, ATTN_NORM);
+                pointparticles(particleeffectnum("raptor_cannon_impact"), self.origin, w_backoff * 1000, 1);
+                break;
+            case DEATH_RAPTOR_BOMB_SPLIT:
+                float i;
+                vector ang, vel;
+                for(i = 1; i < 4; ++i)
+                {
+                    vel = normalize(w_org - (w_org + normalize(force) * 16)) + randomvec() * 128;
+                    ang = vectoangles(vel);
+                    RaptorCBShellfragToss(w_org, vel, ang + '0 0 1' * (120 * i));
+                }
+                    
+                
+                sound(self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
+                pointparticles(particleeffectnum("raptor_bomb_spread"), self.origin, w_backoff * 1000, 1);
+                break;
+            case DEATH_RAPTOR_BOMB:
+                sound(self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
+                pointparticles(particleeffectnum("raptor_bomb_impact"), self.origin, w_backoff * 1000, 1);
+                break;
+            case DEATH_RAPTOR_DEATH:
+                sound(self, CHAN_PROJECTILE, "weapons/laserimpact.wav", VOL_BASE, ATTN_MIN);
+                pointparticles(particleeffectnum("explosion_big"), self.origin, w_backoff * 1000, 1);
+                break;
+           }
+       }
+       
+       // TODO spawn particle effects and sounds based on w_deathtype
        if(!DEATH_ISSPECIAL(w_deathtype))
        {
                float hitwep;
index a737c82..129a77d 100644 (file)
@@ -1755,7 +1755,7 @@ void HUD_KillNotify(string s1, string s2, string s3, float type, float msg) // s
                        HUD_KillNotify_Push(s1, s2, 1, DEATH_HURTTRIGGER);
                        if(alsoprint)
                                print(sprintf(_("^1%s^1 was thrown into a world of hurt by %s\n"), s2, s1));
-               } else if(type == DEATH_SBCRUSH) {
+               } else if(type == DEATH_VHCRUSH) {
                        HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
                        if(alsoprint)
                                print (sprintf(_("^1%s^1 was crushed by %s\n"), s2, s1));
index 4219eef..3fc65a6 100644 (file)
@@ -32,6 +32,7 @@ noise.qh
 teamplay.qh
 
 main.qh
+vehicles/vehicles.qh
 
 sortlist.qc
 miscfunctions.qc
@@ -59,9 +60,10 @@ modeleffects.qc
 tuba.qc
 target_music.qc
 
-//vehicles/spiderbot.qc
+vehicles/vehicles.qc
 shownames.qh
 shownames.qc
+
 Main.qc
 View.qc
 interpolate.qc
index 092cdc2..2282723 100644 (file)
@@ -27,10 +27,12 @@ void Projectile_ResetTrail(vector to)
        self.trail_oldorigin = to;
        self.trail_oldtime = time;
 }
+
 void Projectile_DrawTrail(vector to)
 {
        vector from;
        float t0;
+
        from = self.trail_oldorigin;
        t0 = self.trail_oldtime;
        self.trail_oldorigin = to;
@@ -195,7 +197,7 @@ void Ent_Projectile()
        //   effects
        //
        // projectiles don't send angles, because they always follow the velocity
-       
+
        f = ReadByte();
        self.count = (f & 0x80);
        self.iflags = (self.iflags & IFLAG_INTERNALMASK) | IFLAG_AUTOANGLES | IFLAG_ANGLES;
@@ -294,6 +296,14 @@ void Ent_Projectile()
                        case PROJECTILE_TAG: setmodel(self, "models/laser.mdl"); self.traileffect = particleeffectnum("TR_ROCKET"); break;
                        case PROJECTILE_FLAC: setmodel(self, "models/hagarmissile.mdl"); self.scale = 0.4; self.traileffect = particleeffectnum("TR_SEEKER"); break;
                        case PROJECTILE_SEEKER: setmodel(self, "models/tagrocket.md3"); self.traileffect = particleeffectnum("TR_SEEKER"); break;
+
+                       case PROJECTILE_RAPTORBOMB:    setmodel(self, "models/vehicles/clusterbomb.md3"); self.gravity = 1; self.avelocity = '0 0 180'; self.traileffect = particleeffectnum(""); break;
+                       case PROJECTILE_RAPTORBOMBLET: setmodel(self, "models/vehicles/bomblet.md3");     self.gravity = 1; self.avelocity = '0 0 180'; self.traileffect = particleeffectnum(""); break;
+                       case PROJECTILE_RAPTORCANNON:  setmodel(self, "models/plasmatrail.mdl"); self.traileffect = particleeffectnum("TR_CRYLINKPLASMA"); break;
+
+                       case PROJECTILE_SPIDERROCKET: setmodel(self, "models/vehicles/rocket02.md3"); self.traileffect = particleeffectnum("spiderbot_rocket_thrust"); break;
+                       case PROJECTILE_WAKIROCKET:   setmodel(self, "models/vehicles/rocket01.md3");  self.traileffect = particleeffectnum("wakizashi_rocket_thrust"); break;
+                       case PROJECTILE_WAKICANNON:   setmodel(self, "models/laser.mdl");  self.traileffect = particleeffectnum(""); break;
                        default:
                                error("Received invalid CSQC projectile, can't work with this!");
                                break;
@@ -384,6 +394,22 @@ void Ent_Projectile()
                                self.mins = '-4 -4 -4';
                                self.maxs = '4 4 4';
                                break;
+            case PROJECTILE_RAPTORBOMB:
+                               self.mins = '-3 -3 -3';
+                               self.maxs = '3 3 3';
+                               break;
+            case PROJECTILE_RAPTORBOMBLET:
+                               break;
+            case PROJECTILE_RAPTORCANNON:
+                               break;
+            case PROJECTILE_SPIDERROCKET:
+                loopsound(self, CHAN_PROJECTILE, "weapons/tag_rocket_fly.wav", VOL_BASE, ATTN_NORM);
+                               break;
+            case PROJECTILE_WAKIROCKET:
+                loopsound(self, CHAN_PROJECTILE, "weapons/tag_rocket_fly.wav", VOL_BASE, ATTN_NORM);
+                               break;
+            case PROJECTILE_WAKICANNON:
+                               break;
                        default:
                                break;
                }
@@ -406,7 +432,7 @@ void Ent_Projectile()
 
        if(!(self.count & 0x80))
                InterpolateOrigin_Note();
-       
+
        self.draw = Projectile_Draw;
        self.entremove = Ent_RemoveProjectile;
 }
@@ -424,9 +450,11 @@ void Projectile_Precache()
        precache_model("models/rocket.md3");
        precache_model("models/tagrocket.md3");
        precache_model("models/tracer.mdl");
+
        precache_sound("weapons/electro_fly.wav");
        precache_sound("weapons/rocket_fly.wav");
        precache_sound("weapons/fireball_fly.wav");
        precache_sound("weapons/fireball_fly2.wav");
        precache_sound("weapons/tag_rocket_fly.wav");
+
 }
diff --git a/qcsrc/client/vehicles/racer.qc b/qcsrc/client/vehicles/racer.qc
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/qcsrc/client/vehicles/raptor.qc b/qcsrc/client/vehicles/raptor.qc
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/qcsrc/client/vehicles/spiderbot.qc b/qcsrc/client/vehicles/spiderbot.qc
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/qcsrc/client/vehicles/vehicles.qc b/qcsrc/client/vehicles/vehicles.qc
new file mode 100644 (file)
index 0000000..76891b0
--- /dev/null
@@ -0,0 +1,718 @@
+#define hud_bg "gfx/vehicles/frame.tga"
+#define hud_sh "gfx/vehicles/vh-shield.tga"
+
+#define hud_hp_bar "gfx/vehicles/bar_up_left.tga"
+#define hud_hp_ico "gfx/vehicles/health.tga"
+#define hud_sh_bar "gfx/vehicles/bar_dwn_left.tga"
+#define hud_sh_ico "gfx/vehicles/shield.tga"
+
+#define hud_ammo1_bar "gfx/vehicles/bar_up_right.tga"
+#define hud_ammo1_ico "gfx/vehicles/bullets.tga"
+#define hud_ammo2_bar "gfx/vehicles/bar_dwn_right.tga"
+#define hud_ammo2_ico "gfx/vehicles/rocket.tga"
+
+entity dropmark;
+float autocvar_cl_vehicles_hudscale;
+float autocvar_cl_vehicles_hudalpha;
+
+
+void CSQC_WAKIZASHI_HUD();
+void CSQC_SPIDER_HUD();
+void CSQC_RAPTOR_HUD();
+void CSQC_BUMBLE_HUD();
+
+#define MAX_AXH 4
+entity AuxiliaryXhair[MAX_AXH];
+const var void Draw_Not();
+
+.string axh_image;
+.float  axh_fadetime;
+.float  axh_drawflag;
+.float  axh_scale;
+
+void AuxiliaryXhair_Draw2D()
+{
+    vector loc, psize;
+
+    psize = self.axh_scale * drawgetimagesize(self.axh_image);
+    loc = project_3d_to_2d(self.origin) - 0.5 * psize;
+    if not (loc_z < 0 || loc_x < 0 || loc_y < 0 || loc_x > vid_conwidth || loc_y > vid_conheight)
+    {
+        loc_z = 0;
+        psize_z = 0;
+        drawpic(loc, self.axh_image, psize, self.colormod, self.alpha, self.axh_drawflag);
+    }
+
+    if(time - self.cnt > self.axh_fadetime)
+        self.draw2d = Draw_Not;
+}
+
+void Net_AuXair2(float bIsNew)
+{
+    float axh_id;
+    entity axh;
+
+    axh_id = bound(0, ReadByte(), MAX_AXH);
+    axh = AuxiliaryXhair[axh_id];
+
+    if(axh == world || wasfreed(axh))  // MADNESS? THIS IS QQQQCCCCCCCCC (wasfreed, why do you exsist?)
+    {
+        axh               = spawn();
+               axh.draw2d        = Draw_Not;
+               axh.drawmask      = MASK_NORMAL;
+               axh.axh_drawflag  = DRAWFLAG_ADDITIVE;
+               axh.axh_fadetime  = 0.1;
+               axh.axh_image     = "gfx/vehicles/axh-ring.tga";
+               axh.axh_scale     = 1;
+        axh.alpha         = 1;
+               AuxiliaryXhair[axh_id] = axh;
+    }
+
+    axh.draw2d   = AuxiliaryXhair_Draw2D;
+
+       axh.origin_x = ReadCoord();
+       axh.origin_y = ReadCoord();
+       axh.origin_z = ReadCoord();
+
+       axh.colormod_x = ReadByte() / 255;
+       axh.colormod_y = ReadByte() / 255;
+       axh.colormod_z = ReadByte() / 255;
+    axh.cnt = time;
+}
+
+void Net_VehicleSetup()
+{
+
+    float hud_id, i;
+    hud_id = bound(HUD_SPIDERBOT, ReadByte(), HUD_RAPTOR);
+
+    // Init auxiliary crosshairs
+    entity axh;
+    for(i = 0; i < MAX_AXH; ++i)
+    {
+        axh = AuxiliaryXhair[i];
+        if(axh != world && !wasfreed(axh))  // MADNESS? THIS IS QQQQCCCCCCCCC (wasfreed, why do you exsist?)
+            remove(axh);
+
+        axh               = spawn();
+               axh.draw2d        = Draw_Not;
+               axh.drawmask      = MASK_NORMAL;
+               axh.axh_drawflag  = DRAWFLAG_NORMAL;
+               axh.axh_fadetime  = 0.1;
+               axh.axh_image     = "gfx/vehicles/axh-ring.tga";
+               axh.axh_scale     = 1;
+        axh.alpha         = 1;
+               AuxiliaryXhair[i] = axh;
+    }
+
+    switch(hud_id)
+    {
+        case HUD_SPIDERBOT:
+            // Minigun1
+            AuxiliaryXhair[0].axh_image   = "gfx/vehicles/axh-ring.tga";
+            AuxiliaryXhair[0].axh_scale   = 0.25;
+            // Minigun2
+            AuxiliaryXhair[1].axh_image   = "gfx/vehicles/axh-ring.tga";
+            AuxiliaryXhair[1].axh_scale   = 0.25;
+            // Rocket
+            AuxiliaryXhair[2].axh_image   = "gfx/vehicles/axh-special1.tga";
+            AuxiliaryXhair[2].axh_scale   = 0.5;
+            break;
+
+        case HUD_WAKIZASHI:
+            AuxiliaryXhair[0].axh_image   = "gfx/vehicles/axh-bracket.tga";
+            AuxiliaryXhair[0].axh_scale   = 0.25;
+            break;
+
+        case HUD_RAPTOR:
+            AuxiliaryXhair[0].axh_image   = "gfx/vehicles/axh-special2.tga";
+            AuxiliaryXhair[0].axh_scale   = 0.5;
+            //AuxiliaryXhair[0].alpha       = 0.5;
+
+            AuxiliaryXhair[1].axh_image   = "gfx/vehicles/axh-bracket.tga";
+            AuxiliaryXhair[1].axh_scale   = 0.25;
+            //AuxiliaryXhair[1].alpha       = 0.75;
+            //AuxiliaryXhair[1].axh_drawflag  = DRAWFLAG_NORMAL;
+            break;
+
+        case HUD_BUMBLEBEE:
+            // Plasma cannons
+            AuxiliaryXhair[0].axh_image   = "gfx/vehicles/axh-ring.tga";
+            AuxiliaryXhair[0].axh_scale   = 0.25;
+            // Raygun
+            AuxiliaryXhair[1].axh_image   = "gfx/vehicles/axh-special1.tga";
+            AuxiliaryXhair[1].axh_scale   = 0.25;
+            break;
+    }
+}
+#define HUD_GETSTATS \
+    float vh_health    = getstati(STAT_VEHICLESTAT_HEALTH);  \
+       float shield    = getstati(STAT_VEHICLESTAT_SHIELD);  \
+       float energy    = getstati(STAT_VEHICLESTAT_ENERGY);  \
+       float ammo1     = getstati(STAT_VEHICLESTAT_AMMO1);   \
+       float reload1   = getstati(STAT_VEHICLESTAT_RELOAD1); \
+       float ammo2     = getstati(STAT_VEHICLESTAT_AMMO2);   \
+       float reload2   = getstati(STAT_VEHICLESTAT_RELOAD2);
+
+void CSQC_BUMBLE_HUD()
+{
+}
+
+
+#define spider_ico  "gfx/vehicles/sbot.tga"
+#define spider_rkt  "gfx/vehicles/sbot_rpods.tga"
+#define spider_mgun "gfx/vehicles/sbot_mguns.tga"
+#define spider_xhair "gfx/vehicles/axh-special1.tga"
+float alarm1time;
+float alarm2time;
+
+void CSQC_SPIDER_HUD()
+{
+       if(autocvar_r_letterbox)
+        return;
+
+    vector picsize, hudloc, pic2size, picloc;
+    float i;
+
+    // Fetch health & ammo stats
+       HUD_GETSTATS
+
+    picsize = drawgetimagesize(hud_bg) * autocvar_cl_vehicles_hudscale;
+    hudloc_y = vid_conheight - picsize_y;
+    hudloc_x = vid_conwidth * 0.5 - picsize_x * 0.5;
+
+    drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL);
+
+    //drawstring(hudloc + '145 19  0', strcat(ftos(vh_health), "%"),'15 15 0','0 1 0', 1, DRAWFLAG_NORMAL);
+    //drawstring(hudloc + '175 34  0', strcat(ftos(shield), "%"),'15 15 0','0 0 1', 1, DRAWFLAG_NORMAL);
+    //drawstring(hudloc + '136 102  0', strcat(ftos(ammo1), "%"),'14 14 0','1 1 0', 1, DRAWFLAG_NORMAL);
+    //drawstring(hudloc + '179 69  0', strcat(ftos(9 - ammo2), " / 8"),'14 14 0','1 1 0', 1, DRAWFLAG_NORMAL);
+
+    ammo1   *= 0.01;
+    shield  *= 0.01;
+    vh_health  *= 0.01;
+    reload2 *= 0.01;
+
+    pic2size = drawgetimagesize(spider_ico) * (autocvar_cl_vehicles_hudscale * 0.8);
+    picloc = picsize * 0.5 - pic2size * 0.5;
+    if(vh_health < 0.25)
+        drawpic(hudloc + picloc, spider_ico, pic2size,  '1 0 0' + '0 1 1' * sin(time * 8),  1, DRAWFLAG_NORMAL);
+    else
+        drawpic(hudloc + picloc, spider_ico, pic2size,  '1 1 1' * vh_health  + '1 0 0' * (1 - vh_health),  1, DRAWFLAG_NORMAL);    
+    drawpic(hudloc + picloc, spider_rkt, pic2size,  '1 1 1' * reload2 + '1 0 0' * (1 - reload2), 1, DRAWFLAG_NORMAL);
+    drawpic(hudloc + picloc, spider_mgun, pic2size, '1 1 1' * ammo1   + '1 0 0' * (1 - ammo1),   1, DRAWFLAG_NORMAL);
+    drawpic(hudloc + picloc, hud_sh, pic2size,  '1 1 1', shield, DRAWFLAG_NORMAL);
+
+// Health bar
+    picsize = drawgetimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '69 69 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - vh_health)), 0, vid_conwidth, vid_conheight);
+    drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    picsize = drawgetimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale;
+    picloc = '37 65 0' * autocvar_cl_vehicles_hudscale;
+    if(vh_health < 0.25)
+    {
+        if(alarm1time < time)
+        {
+            alarm1time = time + 2;
+            sound(world, CHAN_PAIN, strcat("vehicles/alarm.wav"), VOL_BASEVOICE, ATTN_NONE);
+        }        
+        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    }        
+    else
+    {
+        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+        if(alarm1time)
+        {
+            sound(world, CHAN_PAIN, strcat("misc/null.wav"), VOL_BASEVOICE, ATTN_NONE);
+            alarm1time = 0;
+        }        
+    }
+// Shield bar
+    picsize = drawgetimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '69 140 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - shield)), 0, vid_conwidth, vid_conheight);
+    drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    picloc = '40 136 0' * autocvar_cl_vehicles_hudscale;
+    picsize = drawgetimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale;
+    if(shield < 0.25)
+    {
+        if(alarm2time < time)
+        {
+            alarm2time = time + 1;
+            sound(world, CHAN_TRIGGER, strcat("vehicles/alarm_shield.wav"), VOL_BASEVOICE, ATTN_NONE);
+        }
+        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    }
+    else
+    {
+        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+        if(alarm2time)
+        {            
+            sound(world, CHAN_TRIGGER, strcat("misc/null.wav"), VOL_BASEVOICE, ATTN_NONE);
+            alarm2time = 0;
+        }
+    }
+    
+
+// Minigun bar
+    picsize = drawgetimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '450 69 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc_x + picloc_x, picloc_y, picsize_x * ammo1, vid_conheight);
+    drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    picsize = drawgetimagesize(hud_ammo1_ico) * autocvar_cl_vehicles_hudscale;
+    picloc = '664 60 0' * autocvar_cl_vehicles_hudscale;
+    if(ammo1 < 0.2)
+        drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    else
+        drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+
+// Rocket ammo bar
+    picsize = drawgetimagesize(hud_ammo2_bar) * autocvar_cl_vehicles_hudscale;
+    ammo1 = picsize_x / 8;
+    picloc = '450 140 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc_x + picloc_x, hudloc_y + picloc_y, picsize_x * reload2, vid_conheight);
+    drawpic(hudloc + picloc, hud_ammo2_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    drawresetcliparea();
+
+// ..  and icons
+    pic2size = 0.35 * drawgetimagesize(hud_ammo2_ico) * autocvar_cl_vehicles_hudscale;
+    picloc_x -= pic2size_x;
+    picloc_y += pic2size_y * 2.25;
+    if(ammo2 == 9)
+    {
+        for(i = 1; i < 9; ++i)
+        {
+            picloc_x += ammo1;
+            drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, ((8 * reload2 <= i) ? '0 0 0' : '1 1 1'), 0.75, DRAWFLAG_NORMAL);
+        }
+    }
+    else
+    {
+        for(i = 1; i < 9; ++i)
+        {
+            picloc_x += ammo1;
+            drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, ((i >= ammo2) ? '1 1 1' : '0 0 0'), 0.75, DRAWFLAG_NORMAL);
+        }
+    }
+    pic2size = drawgetimagesize(hud_ammo2_ico) * autocvar_cl_vehicles_hudscale;
+    picloc = '664 130 0' * autocvar_cl_vehicles_hudscale;
+    if(ammo2 == 9)
+        drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    else
+        drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 1 1', 1, DRAWFLAG_NORMAL);
+
+
+    HUD_DrawCenterPrint();
+
+       if (scoreboard_showscores)
+               HUD_DrawScoreboard();
+    else
+    {
+        picsize = drawgetimagesize(spider_xhair);
+        picsize_x *= autocvar_cl_vehicle_spiderbot_cross_size;
+        picsize_y *= autocvar_cl_vehicle_spiderbot_cross_size;
+
+        drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), spider_xhair, picsize, '1 1 1', autocvar_cl_vehicle_spiderbot_cross_alpha, DRAWFLAG_ADDITIVE);
+    }
+}
+
+#define raptor_ico  "gfx/vehicles/raptor.tga"
+#define raptor_gun  "gfx/vehicles/raptor_guns.tga"
+#define raptor_bomb "gfx/vehicles/raptor_bombs.tga"
+#define raptor_drop "gfx/vehicles/axh-dropcross.tga"
+#define raptor_xhair "gfx/vehicles/axh-ring.tga"
+void CSQC_RAPTOR_HUD()
+{
+       if(autocvar_r_letterbox)
+        return;
+
+    vector picsize, hudloc, pic2size, picloc;
+
+    // Fetch health & ammo stats
+       HUD_GETSTATS
+
+    picsize = drawgetimagesize(hud_bg) * autocvar_cl_vehicles_hudscale;
+    hudloc_y = vid_conheight - picsize_y;
+    hudloc_x = vid_conwidth * 0.5 - picsize_x * 0.5;
+
+    drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL);
+
+    ammo1   *= 0.01;
+    ammo2   *= 0.01;
+    shield  *= 0.01;
+    vh_health  *= 0.01;
+    energy  *= 0.01;
+    reload1 = reload2 * 0.01;
+    //reload2 *= 0.01;
+
+    pic2size = drawgetimagesize(spider_ico) * (autocvar_cl_vehicles_hudscale * 0.8);
+    picloc = picsize * 0.5 - pic2size * 0.5;
+    if(vh_health < 0.25)
+        drawpic(hudloc + picloc, raptor_ico, pic2size,  '1 0 0' + '0 1 1' * sin(time * 8),  1, DRAWFLAG_NORMAL);
+    else
+        drawpic(hudloc + picloc, raptor_ico, pic2size,  '1 1 1' * vh_health  + '1 0 0' * (1 - vh_health),  1, DRAWFLAG_NORMAL);
+    drawpic(hudloc + picloc, raptor_bomb, pic2size,  '1 1 1' * reload1 + '1 0 0' * (1 - reload1), 1, DRAWFLAG_NORMAL);
+    drawpic(hudloc + picloc, raptor_gun, pic2size, '1 1 1' * energy   + '1 0 0' * (1 - energy),   1, DRAWFLAG_NORMAL);
+    drawpic(hudloc + picloc, hud_sh, pic2size,  '1 1 1', shield, DRAWFLAG_NORMAL);
+
+// Health bar
+    picsize = drawgetimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '69 69 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - vh_health)), 0, vid_conwidth, vid_conheight);
+    drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    picsize = drawgetimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale;
+    picloc = '37 65 0' * autocvar_cl_vehicles_hudscale;
+    if(vh_health < 0.25)
+    {
+        if(alarm1time < time)
+        {
+            alarm1time = time + 2;
+            sound(self, CHAN_PAIN, strcat("vehicles/alarm.wav"), VOL_BASEVOICE, ATTN_NONE);
+        }
+        
+        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    }        
+    else
+    {
+        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+        if(alarm1time)
+        {
+            sound(self, CHAN_PAIN, strcat("misc/null.wav"), VOL_BASEVOICE, ATTN_NONE);
+            alarm1time = 0;
+        }
+    }
+
+// Shield bar
+    picsize = drawgetimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '69 140 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - shield)), 0, vid_conwidth, vid_conheight);
+    drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    picloc = '40 136 0' * autocvar_cl_vehicles_hudscale;
+    picsize = drawgetimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale;
+    if(shield < 0.25)
+    {
+        if(alarm2time < time)
+        {
+            alarm2time = time + 1;
+            sound(world, CHAN_TRIGGER, strcat("vehicles/alarm_shield.wav"), VOL_BASEVOICE, ATTN_NONE);
+        }
+        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    }
+    else
+    {
+        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+        if(alarm2time)
+        {            
+            sound(world, CHAN_TRIGGER, strcat("misc/null.wav"), VOL_BASEVOICE, ATTN_NONE);
+            alarm2time = 0;
+        }
+    }
+    
+// Gun bar
+    picsize = drawgetimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '450 69 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc_x + picloc_x, picloc_y, picsize_x * energy, vid_conheight);
+    drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    picsize = drawgetimagesize(hud_ammo1_ico) * autocvar_cl_vehicles_hudscale;
+    picloc = '664 60 0' * autocvar_cl_vehicles_hudscale;
+    if(energy < 0.2)
+        drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    else
+        drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+
+// Bomb bar
+    picsize = drawgetimagesize(hud_ammo2_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '450 140 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc_x + picloc_x, hudloc_y + picloc_y, picsize_x * reload1, vid_conheight);
+    drawpic(hudloc + picloc, hud_ammo2_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    pic2size = drawgetimagesize(hud_ammo2_ico) * autocvar_cl_vehicles_hudscale;
+    picloc = '664 130 0' * autocvar_cl_vehicles_hudscale;
+    if(reload1 != 1)
+        drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    else
+        drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 1 1', 1, DRAWFLAG_NORMAL);
+
+// Bombing crosshair
+    if(!dropmark)
+    {
+        dropmark = spawn();
+        dropmark.owner = self;
+        dropmark.gravity = 1;
+    }
+
+    if(reload2 == 100)
+    {
+        vector where;
+
+        setorigin(dropmark, pmove_org);
+        dropmark.velocity = pmove_vel;
+        tracetoss(dropmark, self);
+
+        where = project_3d_to_2d(trace_endpos);
+
+        setorigin(dropmark, trace_endpos);
+        picsize = drawgetimagesize(raptor_drop) * 0.2;
+
+        if not (where_z < 0 || where_x < 0 || where_y < 0 || where_x > vid_conwidth || where_y > vid_conheight)
+        {
+            where_x -= picsize_x * 0.5;
+            where_y -= picsize_y * 0.5;
+            where_z = 0;
+            drawpic(where, raptor_drop, picsize, '0 2 0', 1, DRAWFLAG_ADDITIVE);
+        }
+        dropmark.cnt = time + 5;
+    }
+    else
+    {
+        vector where;
+        if(dropmark.cnt > time)
+        {
+            where = project_3d_to_2d(dropmark.origin);
+            picsize = drawgetimagesize(raptor_drop) * 0.25;
+
+            if not (where_z < 0 || where_x < 0 || where_y < 0 || where_x > vid_conwidth || where_y > vid_conheight)
+            {
+                where_x -= picsize_x * 0.5;
+                where_y -= picsize_y * 0.5;
+                where_z = 0;
+                drawpic(where, raptor_drop, picsize, '2 0 0', 1, DRAWFLAG_ADDITIVE);
+            }
+        }
+    }
+
+    HUD_DrawCenterPrint();
+
+       if (scoreboard_showscores)
+               HUD_DrawScoreboard();
+    else
+    {
+        picsize = drawgetimagesize(raptor_xhair);
+        picsize_x *= 0.5;
+        picsize_y *= 0.5;
+
+        drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), raptor_xhair, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    }
+}
+
+#define waki_ico "gfx/vehicles/waki.tga"
+#define waki_eng "gfx/vehicles/waki_e.tga"
+#define waki_gun "gfx/vehicles/waki_guns.tga"
+#define waki_rkt "gfx/vehicles/waki_rockets.tga"
+#define waki_xhair "gfx/vehicles/axh-special1.tga"
+void CSQC_WAKIZASHI_HUD()
+{
+/*
+    drawpic(hudloc, waki_s, picsize, '1 1 1', shield, DRAWFLAG_NORMAL);
+    drawpic(hudloc, waki_b, picsize, '0 1 0' * health + '1 0 0'  * (1 - health), 1, DRAWFLAG_NORMAL);
+    drawpic(hudloc, waki_r, picsize, '1 1 1' * reload1 + '1 0 0' * (1 - reload1), 1, DRAWFLAG_NORMAL);
+    drawpic(hudloc, waki_e, picsize, '1 1 1' * energy + '1 0 0'  * (1 - energy), 1, DRAWFLAG_NORMAL);
+*/
+       if(autocvar_r_letterbox)
+        return;
+
+    vector picsize, hudloc, pic2size, picloc;
+
+    // Fetch health & ammo stats
+       HUD_GETSTATS
+
+    picsize = drawgetimagesize(hud_bg) * autocvar_cl_vehicles_hudscale;
+    hudloc_y = vid_conheight - picsize_y;
+    hudloc_x = vid_conwidth * 0.5 - picsize_x * 0.5;
+
+    drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL);
+
+    shield  *= 0.01;
+    vh_health  *= 0.01;
+    energy  *= 0.01;
+    reload1 *= 0.01;
+
+    pic2size = drawgetimagesize(spider_ico) * (autocvar_cl_vehicles_hudscale * 0.8);
+    picloc = picsize * 0.5 - pic2size * 0.5;
+    if(vh_health < 0.25)
+        drawpic(hudloc + picloc, waki_ico, pic2size,  '1 0 0' + '0 1 1' * sin(time * 8),  1, DRAWFLAG_NORMAL);
+    else
+        drawpic(hudloc + picloc, waki_ico, pic2size,  '1 1 1' * vh_health  + '1 0 0' * (1 - vh_health),  1, DRAWFLAG_NORMAL);
+    drawpic(hudloc + picloc, waki_eng, pic2size, '1 1 1' * energy   + '1 0 0' * (1 - energy),   1, DRAWFLAG_NORMAL);
+    drawpic(hudloc + picloc, waki_gun, pic2size, '1 1 1' * energy   + '1 0 0' * (1 - energy),   1, DRAWFLAG_NORMAL);
+    drawpic(hudloc + picloc, waki_rkt, pic2size,  '1 1 1' * reload1 + '1 0 0' * (1 - reload1), 1, DRAWFLAG_NORMAL);
+    drawpic(hudloc + picloc, hud_sh, pic2size,  '1 1 1', shield, DRAWFLAG_NORMAL);
+
+// Health bar
+    picsize = drawgetimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '69 69 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - vh_health)), 0, vid_conwidth, vid_conheight);
+    drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    picsize = drawgetimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale;
+    picloc = '37 65 0' * autocvar_cl_vehicles_hudscale;
+    if(vh_health < 0.25)
+    {
+        if(alarm1time < time)
+        {
+            alarm1time = time + 2;
+            sound(self, CHAN_PAIN, strcat("vehicles/alarm.wav"), VOL_BASEVOICE, ATTN_NONE);
+        }
+        
+        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    }        
+    else
+    {
+        drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+        if(alarm1time)
+        {
+            sound(self, CHAN_PAIN, strcat("misc/null.wav"), VOL_BASEVOICE, ATTN_NONE);
+            alarm1time = 0;
+        }        
+    }
+        
+
+// Shield bar
+    picsize = drawgetimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '69 140 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - shield)), 0, vid_conwidth, vid_conheight);
+    drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    picloc = '40 136 0' * autocvar_cl_vehicles_hudscale;
+    picsize = drawgetimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale;
+    if(shield < 0.25)
+    {
+        if(alarm2time < time)
+        {
+            alarm2time = time + 1;
+            sound(world, CHAN_TRIGGER, strcat("vehicles/alarm_shield.wav"), VOL_BASEVOICE, ATTN_NONE);
+        }
+        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    }
+    else
+    {
+        drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+        if(alarm2time)
+        {            
+            sound(world, CHAN_TRIGGER, strcat("misc/null.wav"), VOL_BASEVOICE, ATTN_NONE);
+            alarm2time = 0;
+        }
+    }
+    
+// Gun bar
+    picsize = drawgetimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '450 69 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc_x + picloc_x, picloc_y, picsize_x * energy, vid_conheight);
+    drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    picsize = drawgetimagesize(hud_ammo1_ico) * autocvar_cl_vehicles_hudscale;
+    picloc = '664 60 0' * autocvar_cl_vehicles_hudscale;
+    if(energy < 0.2)
+        drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    else
+        drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+
+// Bomb bar
+    picsize = drawgetimagesize(hud_ammo2_bar) * autocvar_cl_vehicles_hudscale;
+    picloc = '450 140 0' * autocvar_cl_vehicles_hudscale;
+    drawsetcliparea(hudloc_x + picloc_x, hudloc_y + picloc_y, picsize_x * reload1, vid_conheight);
+    drawpic(hudloc + picloc, hud_ammo2_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    drawresetcliparea();
+// ..  and icon
+    pic2size = drawgetimagesize(hud_ammo2_ico) * autocvar_cl_vehicles_hudscale;
+    picloc = '664 130 0' * autocvar_cl_vehicles_hudscale;
+    if(reload1 != 1)
+        drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL);
+    else
+        drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 1 1', 1, DRAWFLAG_NORMAL);
+
+
+    HUD_DrawCenterPrint();
+
+       if (scoreboard_showscores)
+               HUD_DrawScoreboard();
+    else
+    {
+        picsize = drawgetimagesize(waki_xhair);
+        picsize_x *= 0.5;
+        picsize_y *= 0.5;
+
+
+        drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), waki_xhair, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    }
+}
+
+void Vehicles_Precache()
+{
+// fixme: HAAAAKKKZZZ!!!!!!!!!!!! (this belongs as a setting in default.cfg)
+    autocvar_cl_vehicles_hudscale = 0.5;
+    autocvar_cl_vehicles_hudalpha = 0.75;
+
+
+       precache_model("models/vehicles/wakizashi.dpm");
+
+       precache_model("models/vehicles/bomblet.md3");
+       precache_model("models/vehicles/clusterbomb.md3");
+       precache_model("models/vehicles/clusterbomb_fragment.md3");
+       precache_model("models/vehicles/rocket01.md3");
+       precache_model("models/vehicles/rocket02.md3");
+       
+       precache_sound ("vehicles/alarm.wav");
+       precache_sound ("vehicles/alarm_shield.wav");
+}
+
+void RaptorCBShellfragDraw()
+{
+       
+       Movetype_Physics_MatchTicrate(autocvar_cl_gibs_ticrate, autocvar_cl_gibs_sloppy);
+       if(wasfreed(self))
+               return;     
+
+       self.move_avelocity += randomvec() * 15;
+       self.renderflags = 0;
+       if(self.cnt < time)
+       self.alpha = bound(0, self.nextthink - time, 1);
+
+       if(self.alpha < ALPHA_MIN_VISIBLE)
+        remove(self);
+}
+
+void RaptorCBShellfragToss(vector _org, vector _vel, vector _ang)
+{
+    entity sfrag;
+    
+    sfrag = spawn();
+    setmodel(sfrag, "models/vehicles/clusterbomb_fragment.md3");
+    setorigin(sfrag, _org);
+
+       sfrag.move_movetype = MOVETYPE_BOUNCE;
+       sfrag.gravity = 0.15;
+       sfrag.solid = SOLID_CORPSE;
+
+       sfrag.draw = RaptorCBShellfragDraw;
+
+       sfrag.move_origin = sfrag.origin = _org;
+       sfrag.move_velocity = _vel;
+       sfrag.move_avelocity = prandomvec() * vlen(sfrag.move_velocity);
+       sfrag.angles = self.move_angles = _ang;
+
+       sfrag.move_time = time;
+       sfrag.damageforcescale = 4;
+
+       sfrag.nextthink = time + 3;
+       sfrag.cnt = time + 2;
+       sfrag.alpha = 1;
+    sfrag.drawmask = MASK_NORMAL;
+}
diff --git a/qcsrc/client/vehicles/vehicles.qh b/qcsrc/client/vehicles/vehicles.qh
new file mode 100644 (file)
index 0000000..66b2af1
--- /dev/null
@@ -0,0 +1,4 @@
+void RaptorCBShellfragDraw();
+void RaptorCBShellfragToss(vector _org, vector _vel, vector _ang);
+void Vehicles_Precache();
+
index 507cff8..e5b121c 100644 (file)
@@ -64,6 +64,7 @@ const float TE_CSQC_WEAPONCOMPLAIN = 113;
 const float TE_CSQC_NEX_SCOPE = 116;
 const float TE_CSQC_MINELAYER_MAXMINES = 117;
 const float TE_CSQC_HAGAR_MAXROCKETS = 118;
+const float TE_CSQC_VEHICLESETUP = 119;
 
 const float RACE_NET_CHECKPOINT_HIT_QUALIFYING = 0; // byte checkpoint, short time, short recordtime, string recordholder
 const float RACE_NET_CHECKPOINT_CLEAR = 1;
@@ -118,6 +119,8 @@ const float ENT_CLIENT_SHOWNAMES = 31;
 const float ENT_CLIENT_WARPZONE_TELEPORTED = 32;
 
 const float ENT_CLIENT_TURRET = 40;
+const float ENT_CLIENT_AUXILIARYXHAIR = 50;
+const float ENT_CLIENT_VEHICLE = 60;
 
 const float SPRITERULE_DEFAULT = 0;
 const float SPRITERULE_TEAMPLAY = 1;
@@ -333,9 +336,13 @@ const float CTF_STATE_DEFEND = 2;
 const float CTF_STATE_COMMANDER = 3;
 
 const float HUD_NORMAL = 0;
-const float HUD_SPIDERBOT = 10;
-const float HUD_WAKIZASHI = 11;
-const float HUD_RAPTOR    = 12;
+const float HUD_VEHICLE_FIRST   = 10;
+const float HUD_SPIDERBOT       = 10;
+const float HUD_WAKIZASHI       = 11;
+const float HUD_RAPTOR          = 12;
+const float HUD_BUMBLEBEE       = 13;
+const float HUD_VEHICLE_LAST    = 13;
+
 const vector eX = '1 0 0';
 const vector eY = '0 1 0';
 const vector eZ = '0 0 1';
@@ -358,6 +365,7 @@ const float STAT_PINKALIVE = 103;
 const float STAT_FROZEN = 104;
 const float STAT_REVIVE_PROGRESS = 105;
 
+
 const float STAT_DOM_TOTAL_PPS = 100;
 const float STAT_DOM_PPS_RED = 101;
 const float STAT_DOM_PPS_BLUE = 102;
@@ -367,9 +375,6 @@ const float STAT_DOM_PPS_YELLOW = 104;
 //const float STAT_SPIDERBOT_AIM     53 // compressShotOrigin
 //const float STAT_SPIDERBOT_TARGET  54 // compressShotOrigin
 
-
-
-
 // moved that here so the client knows the max.
 // # of maps, I'll use arrays for them :P
 #define MAPVOTE_COUNT 10
@@ -499,6 +504,13 @@ float PROJECTILE_FIREBALL = 21;
 float PROJECTILE_FIREMINE = 22;
 float PROJECTILE_BULLET_GLOWING_TRACER = 23;
 
+float PROJECTILE_RAPTORCANNON   = 24;
+float PROJECTILE_RAPTORBOMB     = 25;
+float PROJECTILE_RAPTORBOMBLET  = 26;
+float PROJECTILE_SPIDERROCKET   = 27;
+float PROJECTILE_WAKIROCKET     = 28;
+float PROJECTILE_WAKICANNON     = 29;
+
 float SPECIES_HUMAN        =  0;
 float SPECIES_ROBOT_SOLID  =  1;
 float SPECIES_ALIEN        =  2;
@@ -532,14 +544,20 @@ float DEATH_TURRET = 10020;
 float DEATH_QUIET = 10021;
 float DEATH_HEADSHOT = 10022;
 
-float DEATH_SBMINIGUN = 10030;
-float DEATH_SBROCKET  = 10031;
-float DEATH_SBCRUSH   = 10032;
-float DEATH_SBBLOWUP  = 10033;
-
-float DEATH_WAKIGUN    = 10040;
-float DEATH_WAKIROCKET = 10041;
-float DEATH_WAKIBLOWUP = 10042;
+float  DEATH_VHFIRST       = 10030;
+float  DEATH_VHCRUSH       = 10030;
+float  DEATH_SBMINIGUN     = 10031;
+float  DEATH_SBROCKET      = 10032;
+float  DEATH_SBBLOWUP      = 10033;
+float  DEATH_WAKIGUN       = 10034;
+float  DEATH_WAKIROCKET    = 10035;
+float  DEATH_WAKIBLOWUP    = 10036;
+float  DEATH_RAPTOR_CANNON = 10037;
+float  DEATH_RAPTOR_BOMB   = 10038;
+float  DEATH_RAPTOR_BOMB_SPLIT = 10039;
+float  DEATH_RAPTOR_DEATH  = 10040;
+float  DEATH_VHLAST        = 10040;
+#define DEATH_ISVEHICLE(t)  ((t) >= DEATH_VHFIRST && (t) <= DEATH_VHLAST)
 
 float DEATH_GENERIC = 10050;
 
index 056b98e..a30c4c4 100644 (file)
@@ -6,28 +6,38 @@
                <Option makefile="client" />
                <Option makefile_is_custom="1" />
                <Option pch_mode="2" />
-               <Option compiler="qaukec" />
+               <Option compiler="fteqcc" />
+               <MakeCommands>
+                       <Build command="$make -src $makefile" />
+                       <CompileFile command="$make -src $makefile" />
+                       <Clean command="$make -src $makefile" />
+                       <DistClean command="" />
+                       <AskRebuildNeeded command="" />
+                       <SilentBuild command="$make -src $makefile" />
+               </MakeCommands>
                <Build>
                        <Target title="Debug">
                                <Option output="bin\Debug\qc-server" prefix_auto="1" extension_auto="1" />
                                <Option object_output="obj\Debug\" />
                                <Option type="1" />
-                               <Option compiler="qaukec" />
+                               <Option compiler="fteqcc" />
                                <Compiler>
                                        <Add option="-g" />
                                </Compiler>
                                <MakeCommands>
                                        <Build command="$make -src $makefile" />
-                                       <CompileFile command="" />
-                                       <Clean command="" />
+                                       <CompileFile command="$make -src $makefile" />
+                                       <Clean command="$make -src $makefile" />
                                        <DistClean command="" />
+                                       <AskRebuildNeeded command="" />
+                                       <SilentBuild command="$make -src $makefile" />
                                </MakeCommands>
                        </Target>
                        <Target title="Release">
                                <Option output="bin\Release\qc-server" prefix_auto="1" extension_auto="1" />
                                <Option object_output="obj\Release\" />
                                <Option type="1" />
-                               <Option compiler="qaukec" />
+                               <Option compiler="fteqcc" />
                                <Compiler>
                                        <Add option="-O2" />
                                </Compiler>
                                        <Add option="-s" />
                                </Linker>
                                <MakeCommands>
-                                       <Build command="$make -src $makefile" />
-                                       <CompileFile command="" />
-                                       <Clean command="" />
+                                       <Build command="$make -DRELEASE -src $makefile" />
+                                       <CompileFile command="$make -DRELEASE -src $makefile" />
+                                       <Clean command="$make -DRELEASE -src $makefile" />
                                        <DistClean command="" />
+                                       <AskRebuildNeeded command="" />
+                                       <SilentBuild command="$make -DRELEASE -src $makefile" />
                                </MakeCommands>
                        </Target>
                </Build>
                <Compiler>
-                       <Add option="-Wall" />
+                       <Add option="-g" />
                </Compiler>
                <Unit filename="client\Defs.qc" />
                <Unit filename="client\Main.qc" />
                <Unit filename="client\progs.src" />
                <Unit filename="client\projectile.qc" />
                <Unit filename="client\rubble.qc" />
-               <Unit filename="client\sbar.qc" />
                <Unit filename="client\sortlist.qc" />
                <Unit filename="client\teamplay.qc" />
                <Unit filename="client\teamradar.qc" />
                <Unit filename="client\teamradar.qh" />
                <Unit filename="client\tuba.qc" />
+               <Unit filename="client\vehicles\vehicles.qc" />
+               <Unit filename="client\vehicles\vehicles.qh" />
                <Unit filename="client\wall.qc" />
                <Unit filename="client\waypointsprites.qc" />
                <Unit filename="client\waypointsprites.qh" />
index 36b4189..f4b8491 100644 (file)
@@ -1011,68 +1011,6 @@ float autocvar_g_turrets_unit_walker_std_rocket_turnrate;
 float autocvar_g_turrets_unit_walker_std_rockets_range;
 float autocvar_g_turrets_unit_walker_std_rockets_range_min;
 float autocvar_g_use_ammunition;
-float autocvar_g_vehicle_racer_afterburn_cost;
-float autocvar_g_vehicle_racer_anglestabilizer;
-float autocvar_g_vehicle_racer_downforce;
-float autocvar_g_vehicle_racer_energy;
-float autocvar_g_vehicle_racer_energy_usepause;
-float autocvar_g_vehicle_racer_health;
-float autocvar_g_vehicle_racer_laser_cost;
-float autocvar_g_vehicle_racer_laser_damage;
-float autocvar_g_vehicle_racer_laser_radius;
-float autocvar_g_vehicle_racer_laser_refire;
-float autocvar_g_vehicle_racer_laser_speed;
-float autocvar_g_vehicle_racer_pitchspeed;
-float autocvar_g_vehicle_racer_power_air;
-float autocvar_g_vehicle_racer_power_min;
-float autocvar_g_vehicle_racer_power_solid;
-float autocvar_g_vehicle_racer_reload;
-float autocvar_g_vehicle_racer_respawntime;
-float autocvar_g_vehicle_racer_rocket_accel;
-float autocvar_g_vehicle_racer_rocket_damage;
-float autocvar_g_vehicle_racer_rocket_radius;
-float autocvar_g_vehicle_racer_rocket_refire;
-float autocvar_g_vehicle_racer_rocket_speed;
-float autocvar_g_vehicle_racer_rocket_turnrate;
-float autocvar_g_vehicle_racer_shield;
-float autocvar_g_vehicle_racer_speed_afterburn;
-float autocvar_g_vehicle_racer_speed_forward;
-float autocvar_g_vehicle_racer_speed_strafe;
-float autocvar_g_vehicle_racer_springlength;
-float autocvar_g_vehicle_racer_turnroll;
-float autocvar_g_vehicle_racer_turnspeed;
-float autocvar_g_vehicle_raptor_reload;
-float autocvar_g_vehicle_spiderbot_crush_dmg;
-float autocvar_g_vehicle_spiderbot_crush_force;
-float autocvar_g_vehicle_spiderbot_head_pitchlimit_down;
-float autocvar_g_vehicle_spiderbot_head_pitchlimit_up;
-float autocvar_g_vehicle_spiderbot_head_pitchspeed;
-float autocvar_g_vehicle_spiderbot_head_turnlimit;
-float autocvar_g_vehicle_spiderbot_head_turnspeed;
-float autocvar_g_vehicle_spiderbot_health;
-float autocvar_g_vehicle_spiderbot_minigun_cooldown;
-float autocvar_g_vehicle_spiderbot_minigun_damage;
-float autocvar_g_vehicle_spiderbot_minigun_heat;
-float autocvar_g_vehicle_spiderbot_minigun_refire;
-float autocvar_g_vehicle_spiderbot_minigun_spread;
-float autocvar_g_vehicle_spiderbot_movement_inertia;
-float autocvar_g_vehicle_spiderbot_respawntime;
-float autocvar_g_vehicle_spiderbot_rocket_damage;
-float autocvar_g_vehicle_spiderbot_rocket_edgedamage;
-float autocvar_g_vehicle_spiderbot_rocket_force;
-float autocvar_g_vehicle_spiderbot_rocket_health;
-float autocvar_g_vehicle_spiderbot_rocket_lifetime;
-float autocvar_g_vehicle_spiderbot_rocket_noise;
-float autocvar_g_vehicle_spiderbot_rocket_radius;
-float autocvar_g_vehicle_spiderbot_rocket_refire;
-float autocvar_g_vehicle_spiderbot_rocket_reload;
-float autocvar_g_vehicle_spiderbot_rocket_speed;
-float autocvar_g_vehicle_spiderbot_rocket_turnrate;
-float autocvar_g_vehicle_spiderbot_shield;
-float autocvar_g_vehicle_spiderbot_speed_stop;
-float autocvar_g_vehicle_spiderbot_speed_strafe;
-float autocvar_g_vehicle_spiderbot_speed_walk;
-float autocvar_g_vehicle_spiderbot_turnspeed;
 float autocvar_g_waypointeditor;
 float autocvar_g_waypoints_for_items;
 float autocvar_g_waypointsprite_deadlifetime;
index 51f8cf2..8bffe77 100644 (file)
@@ -596,7 +596,7 @@ void FixPlayermodel();
 void PutObserverInServer (void)
 {
        entity  spot;
-
+    self.hud = HUD_NORMAL;
        race_PreSpawnObserver();
 
        spot = SelectSpawnPoint (TRUE);
@@ -1565,7 +1565,7 @@ void ClientConnect (void)
        playerdemo_init();
 
        anticheat_init();
-       
+
        race_PreSpawnObserver();
 
        //if(g_domination)
@@ -1786,6 +1786,15 @@ Called when a client disconnects from the server
 void ReadyCount();
 void ClientDisconnect (void)
 {
+       if(self.vehicle)
+       {
+           entity oldself;
+           oldself = self;
+           self = self.vehicle;
+           vehicles_exit(VHEF_RELESE);
+           self = oldself;
+       }
+
        if not(self.flags & FL_CLIENT)
        {
                print("Warning: ClientDisconnect without ClientConnect\n");
@@ -2013,7 +2022,7 @@ void player_powerups (void)
 {
        // add a way to see what the items were BEFORE all of these checks for the mutator hook
        olditems = self.items;
-       
+
        if((self.items & IT_USING_JETPACK) && !self.deadflag)
        {
                SoundEntity_StartSound(self, CHAN_PLAYER, "misc/jetpack_fly.wav", VOL_BASE, autocvar_g_jetpack_attenuation);
@@ -2029,7 +2038,7 @@ void player_powerups (void)
 
        if(!self.modelindex || self.deadflag) // don't apply the flags if the player is gibbed
                return;
-       
+
        Fire_ApplyDamage(self);
        Fire_ApplyEffect(self);
 
@@ -2135,7 +2144,7 @@ void player_powerups (void)
                if (time < self.spawnshieldtime)
                        self.effects = self.effects | (EF_ADDITIVE | EF_FULLBRIGHT);
        }
-       
+
        MUTATOR_CALLHOOK(PlayerPowerups);
 }
 
@@ -2350,17 +2359,40 @@ void SpectateCopy(entity spectatee) {
        self.dmg_save = spectatee.dmg_save;
        self.dmg_inflictor = spectatee.dmg_inflictor;
        self.angles = spectatee.v_angle;
-       self.fixangle = TRUE;
+       //self.fixangle = TRUE;
        setorigin(self, spectatee.origin);
        setsize(self, spectatee.mins, spectatee.maxs);
        SetZoomState(spectatee.zoomstate);
 
        anticheat_spectatecopy(spectatee);
+
+       //self.vehicle = spectatee.vehicle;
+
+       self.hud = spectatee.hud;
+       if(spectatee.vehicle)
+    {
+        setorigin(self, spectatee.origin);
+        self.velocity = spectatee.vehicle.velocity;
+        //self.v_angle += spectatee.vehicle.angles;
+        //self.v_angle_x *= -1;
+        self.vehicle_health = spectatee.vehicle_health;
+        self.vehicle_shield = spectatee.vehicle_shield;
+        self.vehicle_energy = spectatee.vehicle_energy;
+        self.vehicle_ammo1 = spectatee.vehicle_ammo1;
+        self.vehicle_ammo2 = spectatee.vehicle_ammo2;
+        self.vehicle_reload1 = spectatee.vehicle_reload1;
+        self.vehicle_reload2 = spectatee.vehicle_reload2;
+        
+        msg_entity = self;
+        WriteByte (MSG_ONE, SVC_SETVIEWPORT);
+        WriteEntity(MSG_ONE, spectatee);
+        //self.tur_head = spectatee.vehicle.vehicle_viewport;
+    }
 }
 
 float SpectateUpdate() {
        if(!self.enemy)
-               return 0;
+           return 0;           
 
        if (self == self.enemy)
                return 0;
@@ -2383,17 +2415,28 @@ float SpectateNext() {
                self.enemy = other;
 
        if(self.enemy.classname == "player") {
-               msg_entity = self;
-               WriteByte(MSG_ONE, SVC_SETVIEW);
-               WriteEntity(MSG_ONE, self.enemy);
-               //stuffcmd(self, "set viewsize $tmpviewsize \n");
-               self.movetype = MOVETYPE_NONE;
-               accuracy_resend(self);
-
-               if(!SpectateUpdate())
-                       PutObserverInServer();
-
-               return 1;
+           if(self.enemy.vehicle)
+           {      
+            msg_entity = self;
+            WriteByte(MSG_ONE, SVC_SETVIEWPORT);
+            WriteEntity(MSG_ONE, self.enemy);
+            //stuffcmd(self, "set viewsize $tmpviewsize \n");
+            self.movetype = MOVETYPE_NONE;
+            accuracy_resend(self);
+           }
+           else 
+           {           
+            msg_entity = self;
+            WriteByte(MSG_ONE, SVC_SETVIEW);
+            WriteEntity(MSG_ONE, self.enemy);
+            //stuffcmd(self, "set viewsize $tmpviewsize \n");
+            self.movetype = MOVETYPE_NONE;
+            accuracy_resend(self);
+
+            if(!SpectateUpdate())
+                PutObserverInServer();
+        }
+        return 1;
        } else {
                return 0;
        }
@@ -3076,7 +3119,7 @@ void PlayerPostThink (void)
 
        if(self.waypointsprite_attachedforcarrier)
                WaypointSprite_UpdateHealth(self.waypointsprite_attachedforcarrier, '1 0 0' * healtharmor_maxdamage(self.health, self.armorvalue, autocvar_g_balance_armor_blockpercent));
-       
+
        if(self.classname == "player" && self.deadflag == DEAD_NO && autocvar_r_showbboxes)
        {
                if(!self.showheadshotbbox)
index 04ce7c0..ac47f51 100644 (file)
@@ -559,7 +559,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht
                        awep = DEATH_WEAPONOF(deathtype);
                valid_damage_for_weaponstats = 1;
        }
-       
+
        if(valid_damage_for_weaponstats)
        {
                dh = dh - max(self.health, 0);
index cf16cec..fea1ef4 100644 (file)
@@ -49,7 +49,7 @@ float ctf_captureshield_shielded(entity p)
 
        // player is in the worse half, if >= half the players are better than him, or consequently, if < half of the players are worse
        // use this rule here
-       
+
        if(players_worseeq >= players_total * captureshield_max_ratio)
                return FALSE;
 
@@ -297,7 +297,7 @@ void DropFlag(entity e, entity penalty_receiver, entity attacker)
        e.playerid = attacker.playerid;
        e.ctf_droptime = time;
        WaypointSprite_Spawn("flagdropped", 0, 0, e, '0 0 1' * 61, world, COLOR_TEAM1 + COLOR_TEAM2 - e.team, e, waypointsprite_attachedforcarrier, FALSE);
-       
+
        if(p.waypointsprite_attachedforcarrier)
        {
                WaypointSprite_Ping(p.waypointsprite_attachedforcarrier);
@@ -509,10 +509,10 @@ void FlagTouch()
        {
                if (other.next_take_time > time)
                        return;
-                       
+
                if (autocvar_g_ctf_flag_pickup_effects) // pickup effect
                        pointparticles(particleeffectnum("smoke_ring"), 0.5 * (self.absmin + self.absmax), '0 0 0', 1);
-                       
+
                // pick up
                self.flagpickuptime = time; // used for timing runs
                self.speedrunning = other.speedrunning; // if speedrunning, flag will self-return and teleport the owner back after the record
@@ -597,7 +597,7 @@ void FlagTouch()
 
                        if (autocvar_g_ctf_flag_pickup_effects) // field pickup effect
                                pointparticles(particleeffectnum("smoke_ring"), 0.5 * (self.absmin + self.absmax), '0 0 0', 1);
-                       
+
                        // pick up
                        self.solid = SOLID_NOT;
                        setorigin(self, self.origin); // relink
@@ -736,7 +736,7 @@ void item_flag_postspawn()
                if(self.team == COLOR_TEAM2)
                        // Blue
                        self.glow_color = 210;
-                       
+
                self.glow_size = 25;
                self.glow_trail = 1;
        }
@@ -1081,7 +1081,7 @@ entity(float cteam) ctf_team_has_commander =
        entity pl;
        if(cteam != COLOR_TEAM1 || cteam != COLOR_TEAM2)
                return world;
-       
+
        FOR_EACH_REALPLAYER(pl) {
                if(pl.team == cteam && pl.iscommander) {
                        return pl;
@@ -1099,7 +1099,7 @@ void(entity e, float st) ctf_setstate =
 void(float cteam) ctf_new_commander =
 {
        entity pl, plmax;
-       
+
        plmax = world;
        FOR_EACH_REALPLAYER(pl) {
                if(pl.team == cteam) {
@@ -1124,14 +1124,14 @@ void(float cteam) ctf_new_commander =
 void() ctf_clientconnect =
 {
        self.iscommander = FALSE;
-       
+
        if(!self.team || self.classname != "player") {
                ctf_setstate(self, -1);
        } else
                ctf_setstate(self, 0);
 
        self.team_saved = self.team;
-       
+
        if(self.team != 0 && self.classname == "player" && !ctf_team_has_commander(self.team)) {
                ctf_new_commander(self.team);
        }
@@ -1156,9 +1156,9 @@ void() ctf_playerchanged =
                        ctf_setstate(self, -1);
                ctf_new_commander(self.team_saved);
        }
-       
+
        self.team_saved = self.team;
-       
+
        ctf_new_commander(self.team);
 };
 
index 89feff9..34eaf31 100644 (file)
@@ -161,10 +161,14 @@ void movelib_update(vector dir,float force)
 }
 */
 
+/*
 void movelib_move_simple(vector newdir,float velo,float blendrate)
 {
     self.velocity = self.velocity * (1 - blendrate) + (newdir * blendrate) * velo;
 }
+*/
+#define movelib_move_simple(newdir,velo,blendrate) \
+    self.velocity = self.velocity * (1 - blendrate) + (newdir * blendrate) * velo
 
 void movelib_beak_simple(float force)
 {
index 488dd10..58d40db 100644 (file)
@@ -30,6 +30,7 @@ mutators/mutator_dodging.qh
 
 //// tZork Turrets ////
 tturrets/include/turrets_early.qh
+vehicles/vehicles_def.qh
 
 campaign.qh
 ../common/campaign_common.qh
diff --git a/qcsrc/server/vehicles/bumblebee.qc b/qcsrc/server/vehicles/bumblebee.qc
new file mode 100644 (file)
index 0000000..80aa8bd
--- /dev/null
@@ -0,0 +1,372 @@
+#ifdef SVQC
+// Auto cvars
+float autocvar_g_vehicle_bumblebee_speed_forward;
+float autocvar_g_vehicle_bumblebee_speed_strafe;
+float autocvar_g_vehicle_bumblebee_speed_up;
+float autocvar_g_vehicle_bumblebee_speed_down;
+float autocvar_g_vehicle_bumblebee_turnspeed;
+float autocvar_g_vehicle_bumblebee_pitchspeed;
+float autocvar_g_vehicle_bumblebee_pitchlimit;
+float autocvar_g_vehicle_bumblebee_friction;
+
+float autocvar_g_vehicle_bumblebee_energy;
+float autocvar_g_vehicle_bumblebee_energy_regen;
+float autocvar_g_vehicle_bumblebee_energy_regen_pause;
+
+float autocvar_g_vehicle_bumblebee_health;
+float autocvar_g_vehicle_bumblebee_health_regen;
+float autocvar_g_vehicle_bumblebee_health_regen_pause;
+
+float autocvar_g_vehicle_bumblebee_shield;
+float autocvar_g_vehicle_bumblebee_shield_regen;
+float autocvar_g_vehicle_bumblebee_shield_regen_pause;
+
+float autocvar_g_vehicle_bumblebee_cannon_cost;
+float autocvar_g_vehicle_bumblebee_cannon_damage;
+float autocvar_g_vehicle_bumblebee_cannon_radius;
+float autocvar_g_vehicle_bumblebee_cannon_refire;
+float autocvar_g_vehicle_bumblebee_cannon_speed;
+float autocvar_g_vehicle_bumblebee_cannon_spread;
+float autocvar_g_vehicle_bumblebee_cannon_force;
+
+float autocvar_g_vehicle_bumblebee_cannon_turnspeed;
+float autocvar_g_vehicle_bumblebee_cannon_pitchlimit_down;
+float autocvar_g_vehicle_bumblebee_cannon_pitchlimit_up;
+float autocvar_g_vehicle_bumblebee_cannon_turnlimit_in;
+float autocvar_g_vehicle_bumblebee_cannon_turnlimit_out;
+
+float autocvar_g_vehicle_bumblebee_respawntime;
+
+float autocvar_g_vehicle_bumblebee_blowup_radius;
+float autocvar_g_vehicle_bumblebee_blowup_coredamage;
+float autocvar_g_vehicle_bumblebee_blowup_edgedamage;
+float autocvar_g_vehicle_bumblebee_blowup_forceintensity;
+
+#define BUMB_MIN '-120 -120 -40'
+#define BUMB_MAX '120 120 40'
+
+.entity gunner1;
+//.entity gunner2;
+.vector lastaim;
+float bumb_gunner_frame()
+{
+    entity vehic, gun, gunner;
+    float ftmp, ftmp2;
+    vector vtmp;
+
+    vehic   = self.vehicle;
+    gun     = self.vehicle.gun1;
+    gunner  = self;
+
+    self    = vehic;
+    vehic.solid = SOLID_NOT;
+    crosshair_trace(gunner);
+
+    //vtmp = gettaginfo(vehic, gettagindexvehic, "tag_hardpoint01"));
+    vtmp = gettaginfo(gun, gettagindex(gun, "muzzle"));
+    vtmp = vectoangles(normalize(trace_endpos - vtmp)); // Find the direction & angle
+    vtmp = shortangle_vxy(vtmp - (vehic.angles + gun.angles), vehic.angles + gun.angles);     // Find aim offset
+
+    // Bind to aimspeed
+    ftmp2 = autocvar_g_vehicle_bumblebee_cannon_turnspeed * frametime; ftmp = -ftmp2;
+    vtmp_x = bound(ftmp, vtmp_x, ftmp2);
+    vtmp_y = bound(ftmp, vtmp_y, ftmp2);
+    // Bind to limts
+    gun.angles_x = bound(-autocvar_g_vehicle_bumblebee_cannon_pitchlimit_down, vtmp_x + gun.angles_x, autocvar_g_vehicle_bumblebee_cannon_pitchlimit_up);
+    gun.angles_y = bound(-autocvar_g_vehicle_bumblebee_cannon_turnlimit_in,  vtmp_y + gun.angles_y, autocvar_g_vehicle_bumblebee_cannon_turnlimit_out);
+
+    if(gunner.BUTTON_ATCK && gun.cnt <= time)
+    {
+        vtmp = gettaginfo(gun, gettagindex(gun, "muzzle"));
+        v_forward = normalize(v_forward);
+        vtmp += v_forward * 50;
+
+        fireBullet (vtmp, v_forward, autocvar_g_vehicle_spiderbot_minigun_spread, autocvar_g_vehicle_spiderbot_minigun_damage,
+            autocvar_g_vehicle_spiderbot_minigun_spread, DEATH_SBMINIGUN, 0);
+
+        gun.cnt = time + 0.1;
+    }
+
+    setorigin(gunner, vehic.origin);
+    gunner.velocity = vehic.velocity;
+
+    vehic.solid = SOLID_BBOX;
+    gunner.BUTTON_ATCK = gunner.BUTTON_ATCK2 = gunner.BUTTON_CROUCH = 0;
+    self = gunner;
+    return 1;
+}
+
+void bumb_gunner_enter()
+{
+    if(self.gunner1 != world)
+        return;
+
+    self.gunner1         = other;
+    self.gunner1.vehicle = self;
+
+    msg_entity = other;
+    WriteByte (MSG_ONE, SVC_SETVIEWPORT);
+    WriteEntity(MSG_ONE, self.gun1);
+    WriteByte (MSG_ONE, SVC_SETVIEWANGLES);
+    if(self.tur_head)
+    {
+        WriteAngle(MSG_ONE, self.gun1.angles_x + self.angles_x); // tilt
+        WriteAngle(MSG_ONE, self.gun1.angles_y + self.angles_y); // yaw
+        WriteAngle(MSG_ONE, 0);                                  // roll
+    }
+    other.PlayerPhysplug = bumb_gunner_frame;
+}
+
+float bumb_pilot_frame()
+{
+    entity pilot, gunner, vehic;
+    vector newvel;
+
+    pilot = self;
+    vehic = self.vehicle;
+    self   = vehic;
+
+    if(pilot.BUTTON_USE && vehic.deadflag == DEAD_NO)
+    {
+        self = vehic;
+        vehicles_exit(VHEF_NORMAL);
+        self = pilot;
+        return 0;
+    }
+
+    if(vehic.deadflag != DEAD_NO)
+    {
+        self = pilot;
+        pilot.BUTTON_ATCK = pilot.BUTTON_ATCK2 = 0;
+        return 1;
+    }
+
+    crosshair_trace(pilot);
+
+    vector vang;
+    float ftmp;
+
+    vang = vehic.angles;
+    newvel = vectoangles(normalize(trace_endpos - self.origin + '0 0 32'));
+    vang_x *= -1;
+    newvel_x *= -1;
+    if(newvel_x > 180)  newvel_x -= 360;
+    if(newvel_x < -180) newvel_x += 360;
+    if(newvel_y > 180)  newvel_y -= 360;
+    if(newvel_y < -180) newvel_y += 360;
+
+    ftmp = shortangle_f(pilot.v_angle_y - vang_y, vang_y);
+    if(ftmp > 180)  ftmp -= 360; if(ftmp < -180) ftmp += 360;
+    vehic.avelocity_y = bound(-autocvar_g_vehicle_bumblebee_turnspeed, ftmp + vehic.avelocity_y * 0.9, autocvar_g_vehicle_bumblebee_turnspeed);
+
+    // Pitch
+    ftmp = 0;
+    if(pilot.movement_x > 0 && vang_x < autocvar_g_vehicle_bumblebee_pitchlimit) ftmp = 5;
+    else if(pilot.movement_x < 0 && vang_x > -autocvar_g_vehicle_bumblebee_pitchlimit) ftmp = -20;
+
+    newvel_x = bound(-autocvar_g_vehicle_bumblebee_pitchlimit, newvel_x , autocvar_g_vehicle_bumblebee_pitchlimit);
+    ftmp = vang_x - bound(-autocvar_g_vehicle_bumblebee_pitchlimit, newvel_x + ftmp, autocvar_g_vehicle_bumblebee_pitchlimit);
+    vehic.avelocity_x = bound(-autocvar_g_vehicle_bumblebee_pitchspeed, ftmp + vehic.avelocity_x * 0.9, autocvar_g_vehicle_bumblebee_pitchspeed);
+
+    vehic.angles_x = anglemods(vehic.angles_x);
+    vehic.angles_y = anglemods(vehic.angles_y);
+    vehic.angles_z = anglemods(vehic.angles_z);
+
+    makevectors('0 1 0' * vehic.angles_y);
+    newvel = vehic.velocity * -autocvar_g_vehicle_bumblebee_friction;
+
+    if(pilot.movement_x != 0)
+    {
+        if(pilot.movement_x > 0)
+            newvel += v_forward  * autocvar_g_vehicle_bumblebee_speed_forward;
+        else if(pilot.movement_x < 0)
+            newvel -= v_forward  * autocvar_g_vehicle_bumblebee_speed_forward;
+    }
+
+    if(pilot.movement_y != 0)
+    {
+        if(pilot.movement_y < 0)
+            newvel -= v_right * autocvar_g_vehicle_bumblebee_speed_strafe;
+        else if(pilot.movement_y > 0)
+            newvel += v_right * autocvar_g_vehicle_bumblebee_speed_strafe;
+        ftmp = newvel * v_right;
+        ftmp *= frametime * 0.1;
+        vehic.angles_z = bound(-15, vehic.angles_z + ftmp, 15);
+    }
+    else
+    {
+        vehic.angles_z *= 0.95;
+        if(vehic.angles_z >= -1 && vehic.angles_z <= -1)
+            vehic.angles_z = 0;
+    }
+
+    if(pilot.BUTTON_CROUCH)
+        newvel -=   v_up * autocvar_g_vehicle_bumblebee_speed_down;
+    else if (pilot.BUTTON_JUMP)
+        newvel +=  v_up * autocvar_g_vehicle_bumblebee_speed_up;
+
+    vehic.velocity  += newvel * frametime;
+    pilot.velocity = pilot.movement  = vehic.velocity;
+    setorigin(pilot,vehic.origin + '0 0 32');
+
+
+    if(vehic.vehicle_flags  & VHF_SHIELDREGEN)
+        vehicles_regen(dmg_time, vehicle_shield, autocvar_g_vehicle_bumblebee_shield, autocvar_g_vehicle_bumblebee_shield_regen_pause, autocvar_g_vehicle_bumblebee_shield_regen, frametime);
+
+    if(vehic.vehicle_flags  & VHF_HEALTHREGEN)
+        vehicles_regen(dmg_time, vehicle_health, autocvar_g_vehicle_bumblebee_health, autocvar_g_vehicle_bumblebee_health_regen_pause, autocvar_g_vehicle_bumblebee_health_regen, frametime);
+
+    if(vehic.vehicle_flags  & VHF_ENERGYREGEN)
+        vehicles_regen(cnt, vehicle_energy, autocvar_g_vehicle_bumblebee_energy, autocvar_g_vehicle_bumblebee_energy_regen_pause, autocvar_g_vehicle_bumblebee_energy_regen, frametime);
+
+    VEHICLE_UPDATE_PLAYER(health, bumblebee);
+    VEHICLE_UPDATE_PLAYER(energy, bumblebee);
+    if(vehic.vehicle_flags & VHF_HASSHIELD)
+        VEHICLE_UPDATE_PLAYER(shield, bumblebee);
+
+    pilot.BUTTON_ATCK = pilot.BUTTON_ATCK2 = pilot.BUTTON_CROUCH = 0;
+    self = pilot;
+
+    return 1;
+}
+
+void bumb_think()
+{
+    self.velocity = self.velocity * 0.99;
+    self.nextthink = time + 0.1;
+}
+
+void bumb_enter()
+{
+    self.touch  = bumb_gunner_enter;
+}
+
+void bumb_exit(float eject)
+{
+    self.owner = world;
+    self.touch = vehicles_touch;
+}
+
+void bumb_spawn()
+{
+    self.vehicle_health = autocvar_g_vehicle_bumblebee_health;
+    self.vehicle_shield = autocvar_g_vehicle_bumblebee_shield;
+    self.movetype       = MOVETYPE_TOSS;
+    self.solid          = SOLID_BBOX;
+    //self.vehicle_energy = 1;
+    self.movetype = MOVETYPE_FLY;
+    setorigin(self, self.origin + '0 0 25');
+}
+
+void bumb_die()
+{
+    self.health       = 0;
+    self.event_damage = SUB_Null;
+    self.iscreature   = FALSE;
+    self.solid        = SOLID_CORPSE;
+    self.takedamage   = DAMAGE_NO;
+    self.deadflag     = DEAD_DYING;
+    self.movetype     = MOVETYPE_BOUNCE;
+
+    pointparticles(particleeffectnum("rocket_explode"), findbetterlocation (self.origin, 16), '0 0 0', 1);
+}
+
+void bumb_dinit()
+{
+    if not (vehicle_initialize(
+             "Bumblebee",
+             "models/vehicles/bumblebee_body.dpm",
+             "",
+             "models/vehicles/spiderbot_cockpit.dpm",
+             "", "", "tag_viewport",
+             HUD_BUMBLEBEE,
+             BUMB_MIN, BUMB_MAX,
+             FALSE,
+             bumb_spawn, autocvar_g_vehicle_bumblebee_respawntime,
+             bumb_pilot_frame,
+             bumb_enter, bumb_exit,
+             bumb_die,   bumb_think,
+             FALSE))
+    {
+        remove(self);
+        return;
+    }
+    self.gun1 = spawn();
+    setmodel(self.gun1, "models/vehicles/bumblebee_ray.dpm");
+    setattachment(self.gun1, self, "tag_hardpoint03");
+
+    self.gun1 = spawn();
+    self.gun2 = spawn();
+
+    self.gun1.owner = self;
+    self.gun2.owner = self;
+
+    setmodel(self.gun1, "models/vehicles/bumblebee_plasma_right.dpm");
+    setmodel(self.gun2, "models/vehicles/bumblebee_plasma_left.dpm");
+
+    setattachment(self.gun1, self, "tag_hardpoint01");
+    setattachment(self.gun2, self, "tag_hardpoint02");
+
+    vector ofs;
+    ofs = gettaginfo(self, gettagindex(self, "tag_hardpoint01"));
+    ofs -= self.origin;
+    setattachment(self.gun1, self, "");
+    setorigin(self.gun1, ofs);
+
+    ofs = gettaginfo(self, gettagindex(self, "tag_hardpoint02"));
+    ofs -= self.origin;
+    setattachment(self.gun2, self, "");
+    setorigin(self.gun2, ofs);
+
+
+}
+
+void spawnfunc_vehicle_bumblebee()
+{
+
+    precache_model ("models/vehicles/bumblebee_body.dpm");
+    precache_model ("models/vehicles/bumblebee_plasma_left.dpm");
+    precache_model ("models/vehicles/bumblebee_plasma_right.dpm");
+    precache_model ("models/vehicles/bumblebee_ray.dpm");
+
+    //vehicles_configcheck("vehicle_bumblebee.cfg", autocvar_g_vehicle_bumblebee_health);
+
+    if(autocvar_g_vehicle_bumblebee_energy)
+        if(autocvar_g_vehicle_bumblebee_energy_regen)
+            self.vehicle_flags |= VHF_ENERGYREGEN;
+
+    if(autocvar_g_vehicle_bumblebee_shield)
+        self.vehicle_flags |= VHF_HASSHIELD;
+
+    if(autocvar_g_vehicle_bumblebee_shield_regen)
+        self.vehicle_flags |= VHF_SHIELDREGEN;
+
+    if(autocvar_g_vehicle_bumblebee_health_regen)
+        self.vehicle_flags |= VHF_HEALTHREGEN;
+
+    self.think = bumb_dinit;
+    self.nextthink = time + 1;
+}
+#endif // SVQC
+
+#ifdef CSQC
+void bumblebee_draw()
+{
+
+}
+
+void bumblebee_draw2d()
+{
+
+}
+
+void bumblebee_read_extra()
+{
+
+}
+
+void vehicle_bumblebee_assemble()
+{
+
+}
+#endif //CSQC
diff --git a/qcsrc/server/vehicles/collision.qc b/qcsrc/server/vehicles/collision.qc
new file mode 100644 (file)
index 0000000..11488a0
--- /dev/null
@@ -0,0 +1,55 @@
+vector collision_force;
+vector collision_angle;
+
+vector bb1[9];
+vector bb2[9];
+
+float collision_run()
+{
+    vector vtmp, vmin, vmax, vrot, vforce, vtmp2, vtmp3;
+    float i, fvel, bcol;
+
+
+    // Extract the 8 bbox corners from mins/maxs for self
+    vmax = self.maxs;
+    vmin = self.mins;
+    bb1[0] = vmax;
+    vtmp   = vmax; vtmp_x = vmin_x; bb1[1] = vtmp;
+    vtmp   = vmax; vtmp_y = vmin_y; bb1[2] = vtmp;
+    vtmp   = vmin; vtmp_z = vmax_z; bb1[3] = vtmp;
+    bb1[4] = vmin;
+    vtmp   = vmin; vtmp_x = vmax_x; bb1[5] = vtmp;
+    vtmp   = vmin; vtmp_y = vmax_y; bb1[6] = vtmp;
+    vtmp   = vmax; vtmp_z = vmin_z; bb1[7] = vtmp;
+
+    makevectors(self.angles + '-2 0 0' * self.angles_x);
+    bcol = 0;
+
+    // Pass1: Transform by rotation, ajust points by impact/s
+    for(i = 8; i >= 0; --i)
+    {
+        vtmp = bb1[i];
+        vtmp = self.origin + vtmp_x * v_forward - vtmp_y * v_right + vtmp_z * v_up;
+        traceline(self.origin, vtmp, MOVE_WORLDONLY, self);
+        te_lightning1(world,self.origin,vtmp);
+        if(trace_fraction != 1.0)
+        {
+            vforce += (trace_endpos - vtmp);
+            vtmp3 = self.origin + self.velocity * frametime;
+            vtmp2 =  vectoangles(normalize(vtmp - vtmp3));
+            vrot   += (vectoangles(normalize(trace_endpos - vtmp3)) - vtmp2);
+            bcol += 1;
+        }
+    }
+
+    if(bcol)
+    {
+
+        vtmp = self.origin + self.velocity * frametime;
+        self.angles += vrot * frametime;
+        self.velocity += vforce * frametime;
+
+    }
+
+}
+
diff --git a/qcsrc/server/vehicles/network.qc b/qcsrc/server/vehicles/network.qc
new file mode 100644 (file)
index 0000000..688aa7c
--- /dev/null
@@ -0,0 +1,237 @@
+#ifdef VEHICLES_CSQC
+// SendFlags
+float VSF_SETUP       = 1;          /// Send vehicle type etc
+float VSF_ORIGIN      = 2;          /// Send location
+float VSF_MOVEMENT    = 4;          /// Send movement update (and angles)
+float VSF_AVEL        = 8;          /// Send Angular velocity
+float VSF_STATS       = 16;         /// Send ammo, health etc
+float VSF_EXTRA       = 32;         /// Send additional data (turret rotations etc). Handeld per vehicle type.
+float VSF_ANIMINFO    = 64;         /// Animation info
+float VSF_FULL_UPDATE = 16777215;    /// Send everything
+
+float VSX_FAR   = 1;
+float VSX_OWNER = 2;
+float VSX_GUN1  = 4;
+float VSX_GUN2  = 8;
+
+#ifdef SVQC
+#define VSX_FARDISTANCE 2000
+float send_vehile(entity to, float sf)
+{
+       float dist, xf;
+
+    var void WriteFunc(float, float);
+
+    dist = vlen(self.origin - to.origin);
+    if(to == self.owner)
+        xf |= VSX_OWNER;
+    else if(dist > VSX_FARDISTANCE)
+        xf |= VSX_FAR;
+
+       // Always send a movement and origin to owner
+       if(to == self.owner)
+           sf |= VSF_ORIGIN | VSF_MOVEMENT;
+
+       WriteByte(MSG_ENTITY, ENT_CLIENT_VEHICLE);
+
+       // We need to know client-side what was sent
+       WriteByte(MSG_ENTITY, sf);
+       WriteByte(MSG_ENTITY, xf);
+
+       if(sf & VSF_SETUP)
+       {
+        WriteByte(MSG_ENTITY,  self.hud);        //vehicle type = hud
+        WriteByte(MSG_ENTITY,  self.team);
+        WriteShort(MSG_ENTITY, self.colormap);
+        WriteShort(MSG_ENTITY, self.vehicle_flags);
+       }
+
+    if(sf & VSF_ORIGIN)
+    {
+        WriteFunc = ((xf & VSX_FAR) ? WriteShort : WriteCoord);
+        WriteFunc(MSG_ENTITY, self.origin_x);
+        WriteFunc(MSG_ENTITY, self.origin_y);
+        WriteFunc(MSG_ENTITY, self.origin_z);
+    }
+
+    if(sf & VSF_MOVEMENT)
+    {
+        WriteFunc = ((xf & VSX_FAR) ? WriteShort : WriteCoord);
+        WriteFunc(MSG_ENTITY, self.velocity_x);
+        WriteFunc(MSG_ENTITY, self.velocity_y);
+        WriteFunc(MSG_ENTITY, self.velocity_z);
+
+        WriteFunc = ((xf & VSX_FAR) ? WriteShort : WriteAngle);
+        WriteFunc(MSG_ENTITY, self.angles_x);
+        WriteFunc(MSG_ENTITY, self.angles_y);
+        WriteFunc(MSG_ENTITY, self.angles_z);
+    }
+
+    if(sf & VSF_AVEL)
+    {
+        WriteFunc = ((xf & VSX_FAR) ? WriteShort : WriteCoord);
+        WriteFunc(MSG_ENTITY, self.avelocity_x);
+        WriteFunc(MSG_ENTITY, self.avelocity_y);
+        WriteFunc(MSG_ENTITY, self.avelocity_z);
+    }
+
+    if(sf & VSF_STATS)
+    {
+        WriteByte(MSG_ENTITY, self.vehicle_health);
+        if(xf & VSX_OWNER)
+        {
+            WriteByte(MSG_ENTITY, self.vehicle_shield);
+            WriteByte(MSG_ENTITY, self.vehicle_energy);
+
+            WriteByte(MSG_ENTITY, self.vehicle_ammo1);
+            WriteByte(MSG_ENTITY, self.vehicle_reload1);
+
+            WriteByte(MSG_ENTITY, self.vehicle_ammo2);
+            WriteByte(MSG_ENTITY, self.vehicle_reload2);
+
+        }
+    }
+
+    if(sf & VSF_EXTRA)
+        self.vehile_send_exta(to, sf);
+
+    return TRUE;
+}
+
+void net_link_vehile()
+{
+    self.SendFlags = 0xFFFFFF;
+    Net_LinkEntity(self, FALSE, 0, send_vehile);
+}
+#endif // SVQC
+
+#ifdef CSQC
+void vehicle_spiderbot_assemble()
+{
+
+}
+
+void vehicle_raptor_assemble()
+{
+
+}
+
+void vehicle_bumblebee_assemble()
+{
+
+}
+
+.float lastupdate;
+void read_vehicle(float bIsNew)
+{
+    float sf, xf;
+    var float ReadFunc();
+
+    sf = ReadByte();
+    xf = ReadByte();
+
+    if(xf & VSX_OWNER)
+        vehicle = self;
+
+       if(sf & VSF_SETUP)
+       {
+        self.vehicle_hud   = ReadByte();
+        self.team          = ReadByte();
+        self.colormap      = ReadShort();
+        self.vehicle_flags = ReadShort();
+
+        switch(self.vehicle_hud)
+        {
+            case HUD_WAKIZASHI:
+                vehicle_racer_assemble();
+                break;
+            case HUD_SPIDERBOT:
+                vehicle_spiderbot_assemble();
+                break;
+            case HUD_RAPTOR:
+                vehicle_raptor_assemble();
+                break;
+            case HUD_BUMBLEBEE:
+                vehicle_bumblebee_assemble();
+                break;
+            default:
+                break;
+        }
+       }
+
+       if(self.vehicle_hud == HUD_WAKIZASHI && xf & VSX_OWNER)
+       {
+
+        vehicle_hudmodel.owner  = self;
+       }
+
+    //if(xf & VSX_FAR)
+    //    dprint("Client vehicle faaar set\n");
+
+    if(sf & VSF_ORIGIN)
+    {
+        ReadFunc = ((xf & VSX_FAR) ? ReadShort : ReadCoord);
+        self.origin_x = ReadFunc();
+        self.origin_y = ReadFunc();
+        self.origin_z = ReadFunc();
+
+        setorigin(self, self.origin);
+        //self.lastupdate = time;
+    }
+
+    if(sf & VSF_MOVEMENT)
+    {
+        ReadFunc = ((xf & VSX_FAR) ? ReadShort : ReadCoord);
+        self.velocity_x  = ReadFunc();
+        self.velocity_y  = ReadFunc();
+        self.velocity_z  = ReadFunc();
+
+        ReadFunc = ((sf & VSX_FAR) ? ReadShort : ReadAngle);
+        self.angles_x = ReadFunc();
+        self.angles_y = ReadFunc();
+        self.angles_z = ReadFunc();
+
+        //self.lastupdate = time;
+        // self.move_velocity  = self.velocity;
+        // self.move_angles    = self.angles;
+    }
+
+    if(sf & VSF_AVEL)
+    {
+        ReadFunc = ((xf & VSX_FAR) ? ReadShort : ReadCoord);
+        self.avelocity_x = ReadFunc();
+        self.avelocity_y = ReadFunc();
+        self.avelocity_z = ReadFunc();
+
+        // self.move_avelocity  = self.avelocity;
+    }
+
+    if(sf & VSF_STATS)
+    {
+        self.vehicle_health = ReadByte();
+        if(xf & VSX_OWNER)
+        {
+            self.vehicle_shield  = ReadByte();
+            self.vehicle_energy  = ReadByte();
+            self.vehicle_ammo1   = ReadByte();
+            self.vehicle_reload1 = ReadByte();
+            self.vehicle_ammo2   = ReadByte();
+            self.vehicle_reload2 = ReadByte();
+        }
+    }
+
+    if(sf & VSF_EXTRA)
+        self.vehile_read_exta(sf);
+
+}
+
+#endif // CSQC
+#else
+#ifdef CSQC
+.float lastupdate;
+void read_vehicle(float bIsNew)
+{
+
+}
+#endif
+#endif // VEHICLES_CSQC
index 09efab4..7fefdeb 100644 (file)
-#define RACER_MIN '-80 -80 -40'
-#define RACER_MAX '80 80 40'
-#define RACER_TICRATE 0.05
+#define RACER_MIN '-120 -120 -40'
+#define RACER_MAX '120 120 40'
+#define RACER_ENGINE "sound/vehicles/racer.wav"
 
+#ifdef SVQC
 void racer_exit(float eject);
 void racer_enter();
-//void racer_think();
 
-float racer_power_air;
-float racer_power_solid;
-float racer_power_min;
-float racer_anglestabilizer;
-float racer_springlength;
-
-float racer_healthmax;
-float racer_shieldmax;
-float racer_energymax;
-
-float racer_pitchspeed;
-float racer_turnspeed;
-float racer_turnroll;
-float racer_speed_forward;
-float racer_speed_strafe;
-
-float racer_afterburn_cost;
-
-float  jetfromtag_power;
-float  jetfromtag_normpower;
-vector jetfromtag_origin;
-float  jetfromtag_groundcontact;
-
-void racer_loadsettings()
-{
-    racer_power_min         = autocvar_g_vehicle_racer_power_min   * 0.25;
-    racer_power_air         = autocvar_g_vehicle_racer_power_air   * 0.25;
-    racer_power_solid       = autocvar_g_vehicle_racer_power_solid * 0.25;
-
-    racer_springlength      = autocvar_g_vehicle_racer_springlength;
-    racer_anglestabilizer   = autocvar_g_vehicle_racer_anglestabilizer;
-    racer_pitchspeed        = autocvar_g_vehicle_racer_pitchspeed;
-    racer_turnspeed         = autocvar_g_vehicle_racer_turnspeed;
-    racer_turnroll          = autocvar_g_vehicle_racer_turnroll;
-    racer_speed_forward     = autocvar_g_vehicle_racer_speed_forward;
-    racer_speed_strafe      = autocvar_g_vehicle_racer_speed_strafe;
-
-    racer_afterburn_cost    = autocvar_g_vehicle_racer_afterburn_cost;
-
-    racer_healthmax = autocvar_g_vehicle_racer_health;
-    racer_shieldmax = autocvar_g_vehicle_racer_shield;
-    racer_energymax = autocvar_g_vehicle_racer_energy;
-
-}
-
-vector racer_jetfromtag(string tagname)
-{
-    vector force_dir;
-    float  air_frac, solid_frac, air_pwr, solid_pwr;
-
-    jetfromtag_origin = gettaginfo(self,gettagindex(self,tagname));
-    v_forward  = normalize(v_forward) * -1;
-
-    force_dir = jetfromtag_origin - (v_forward  * racer_springlength);
-    traceline(jetfromtag_origin, force_dir, MOVE_NORMAL, self);
-    //te_lightning1(world,jetfromtag_origin, force_dir);
-
-    //trace_fraction *= trace_fraction;
-
-    solid_frac = 1 - trace_fraction;
-    air_frac = trace_fraction;
-
-    if (trace_fraction != 1.0)
-        jetfromtag_groundcontact = 1;
-
-    solid_pwr = solid_frac * racer_power_solid;
-    air_pwr   = air_frac * racer_power_air;
-
-    jetfromtag_power     = solid_pwr + air_pwr;
-    jetfromtag_normpower = jetfromtag_power / (racer_power_air + racer_power_solid);
-
-    //te_lightning1(world,jetfromtag_origin,jetfromtag_origin + normalize(self.origin - force_dir) * max(jetfromtag_power, racer_power_min));
-    //return normalize(self.origin - force_dir) * max(jetfromtag_power, racer_power_min);
-    return v_forward  * max(jetfromtag_power, racer_power_min);
-}
+// Auto cvars
+float autocvar_g_vehicle_racer_speed_afterburn;
+float autocvar_g_vehicle_racer_afterburn_cost;
+
+float autocvar_g_vehicle_racer_anglestabilizer;
+float autocvar_g_vehicle_racer_downforce;
+
+float autocvar_g_vehicle_racer_speed_forward;
+float autocvar_g_vehicle_racer_speed_strafe;
+float autocvar_g_vehicle_racer_springlength;
+float autocvar_g_vehicle_racer_upforcedamper;
+float autocvar_g_vehicle_racer_friction;
+
+float autocvar_g_vehicle_racer_hovertype;
+float autocvar_g_vehicle_racer_hoverpower;
+
+float autocvar_g_vehicle_racer_turnroll;
+float autocvar_g_vehicle_racer_turnspeed;
+float autocvar_g_vehicle_racer_pitchspeed;
+
+float autocvar_g_vehicle_racer_energy;
+float autocvar_g_vehicle_racer_energy_regen;
+float autocvar_g_vehicle_racer_energy_regen_pause;
+
+float autocvar_g_vehicle_racer_health;
+float autocvar_g_vehicle_racer_health_regen;
+float autocvar_g_vehicle_racer_health_regen_pause;
+
+float autocvar_g_vehicle_racer_shield;
+float autocvar_g_vehicle_racer_shield_regen;
+float autocvar_g_vehicle_racer_shield_regen_pause;
+
+float autocvar_g_vehicle_racer_cannon_cost;
+float autocvar_g_vehicle_racer_cannon_damage;
+float autocvar_g_vehicle_racer_cannon_radius;
+float autocvar_g_vehicle_racer_cannon_refire;
+float autocvar_g_vehicle_racer_cannon_speed;
+float autocvar_g_vehicle_racer_cannon_spread;
+float autocvar_g_vehicle_racer_cannon_force;
+
+float autocvar_g_vehicle_racer_rocket_accel;
+float autocvar_g_vehicle_racer_rocket_damage;
+float autocvar_g_vehicle_racer_rocket_radius;
+float autocvar_g_vehicle_racer_rocket_force;
+float autocvar_g_vehicle_racer_rocket_refire;
+float autocvar_g_vehicle_racer_rocket_speed;
+float autocvar_g_vehicle_racer_rocket_turnrate;
+
+float autocvar_g_vehicle_racer_rocket_locktarget;
+float autocvar_g_vehicle_racer_rocket_locking_time;
+float autocvar_g_vehicle_racer_rocket_locking_releasetime;
+float autocvar_g_vehicle_racer_rocket_locked_time;
+float autocvar_g_vehicle_racer_rocket_locked_maxangle;
+
+float autocvar_g_vehicle_racer_respawntime;
+
+float autocvar_g_vehicle_racer_blowup_radius;
+float autocvar_g_vehicle_racer_blowup_coredamage;
+float autocvar_g_vehicle_racer_blowup_edgedamage;
+float autocvar_g_vehicle_racer_blowup_forceintensity;
+
+var vector racer_force_from_tag(string tag_name, float spring_length, float max_power);
 
 void racer_align4point()
 {
-    vector push_vector;
+    vector push_vector, v_add;
     float fl_push, fr_push, bl_push, br_push;
 
-    jetfromtag_groundcontact = 0;
 
-    push_vector = racer_jetfromtag("tag_engine_fr");
-    fr_push = jetfromtag_normpower;
-    traceline(jetfromtag_origin, jetfromtag_origin + self.velocity * frametime, MOVE_NORMAL,self);
-    if(trace_fraction != 1)
-        self.velocity += normalize(self.origin - trace_endpos) * (vlen(self.velocity) * 1.25);
+    push_vector  = racer_force_from_tag("tag_engine_fr", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
+    fr_push      = force_fromtag_normpower;
+    //vehicles_sweap_collision(force_fromtag_origin, self.velocity, frametime, v_add, autocvar_g_vehicle_racer_collision_multiplier);
 
-    push_vector += racer_jetfromtag("tag_engine_fl");
-    fl_push = jetfromtag_normpower;
-    traceline(jetfromtag_origin, jetfromtag_origin + self.velocity * frametime, MOVE_NORMAL,self);
-    if(trace_fraction != 1)
-        self.velocity += normalize(self.origin - trace_endpos) * (vlen(self.velocity) * 1.25);
+    push_vector += racer_force_from_tag("tag_engine_fl", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
+    fl_push      = force_fromtag_normpower;
+    //vehicles_sweap_collision(force_fromtag_origin, self.velocity, frametime, v_add, autocvar_g_vehicle_racer_collision_multiplier);
 
-    push_vector += racer_jetfromtag("tag_engine_br");
-    br_push = jetfromtag_normpower;
-    traceline(jetfromtag_origin, jetfromtag_origin + self.velocity * frametime, MOVE_NORMAL,self);
-    if(trace_fraction != 1)
-        self.velocity += normalize(self.origin - trace_endpos) * (vlen(self.velocity) * 1.25);
+    push_vector += racer_force_from_tag("tag_engine_br", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
+    br_push      = force_fromtag_normpower;
+    //vehicles_sweap_collision(force_fromtag_origin, self.velocity, frametime, v_add, autocvar_g_vehicle_racer_collision_multiplier);
 
-    push_vector += racer_jetfromtag("tag_engine_bl");
-    bl_push = jetfromtag_normpower;
-    traceline(jetfromtag_origin, jetfromtag_origin + self.velocity * frametime, MOVE_NORMAL,self);
-    if(trace_fraction != 1)
-        self.velocity += normalize(self.origin - trace_endpos) * (vlen(self.velocity) * 1.25);
+    push_vector += racer_force_from_tag("tag_engine_bl", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
+    bl_push      = force_fromtag_normpower;
+    //vehicles_sweap_collision(force_fromtag_origin, self.velocity, frametime, v_add, autocvar_g_vehicle_racer_collision_multiplier);
 
-    self.velocity =  self.velocity + (push_vector * frametime);
-    self.velocity_z -= autocvar_sv_gravity * frametime;
+    self.velocity += (push_vector * frametime);
 
-    push_vector_x = (fl_push - bl_push);
+    // Anti ocilation
+    if(self.velocity_z  > 0)
+        self.velocity_z *= 1 - (autocvar_g_vehicle_racer_upforcedamper * frametime);
+
+    self.velocity   += v_add;
+    //self.velocity_z -= autocvar_sv_gravity * frametime;
+
+    push_vector_x =  (fl_push - bl_push);
     push_vector_x += (fr_push - br_push);
     push_vector_x *= 360;
 
@@ -124,105 +108,42 @@ void racer_align4point()
     push_vector_z += (br_push - bl_push);
     push_vector_z *= 360;
 
-    //if (push_vector_z != 0)
-        if(self.angles_z > 0)
-            self.angles_z = max(0, self.angles_z - (racer_anglestabilizer * frametime));
-        else
-            self.angles_z = min(0, self.angles_z + (racer_anglestabilizer * frametime));
-    //else
-        self.angles_z += push_vector_z * frametime;
+    // Apply angle diffrance
+    self.angles_z += push_vector_z * frametime;
+    self.angles_x += push_vector_x * frametime;
 
-    //if (push_vector_x != 0)
-        if(self.angles_x > 0)
-            self.angles_x = max(0, self.angles_x - (racer_anglestabilizer * frametime));
-        else
-            self.angles_x = min(0, self.angles_x + (racer_anglestabilizer * frametime));
-    //else
-        self.angles_x += push_vector_x * frametime;
-}
-
-void racer_bolt_explode()
-{
-    vector org2;
-
-    org2 = findbetterlocation (self.origin, 8);
-    pointparticles(particleeffectnum("laser_impact"), org2, trace_plane_normal * 1000, 1);
-    RadiusDamage (self, self.realowner, autocvar_g_vehicle_racer_laser_damage, 0, autocvar_g_vehicle_racer_laser_radius, world, 150, DEATH_WAKIGUN, world);
-    sound (self, CHAN_PROJECTILE, "weapons/electro_impact.wav", VOL_BASE, ATTN_NORM);
-
-    remove (self);
-}
-
-void racer_rocket_explode()
-{
-    vector org2;
-
-    //if not(self.owner)
-    //    self.owner = self.realowner;
-
-    sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
-    org2 = findbetterlocation (self.origin, 16);
-    pointparticles(particleeffectnum("rocket_explode"), org2, '0 0 0', 1);
-    RadiusDamage (self, self.realowner ,autocvar_g_vehicle_racer_rocket_damage, 0, autocvar_g_vehicle_racer_rocket_radius, world, 150, DEATH_WAKIROCKET, world);
-
-    remove (self);
-}
-
-void racer_rocket_touch()
-{
-    if(other.owner == self.owner)
-        return;
-
-    PROJECTILE_TOUCH;
-    /*
-    if(pointcontents(self.origin) == CONTENT_SKY)
-    {
-        self.think = SUB_Remove;
-        self.nextthink = time;
-        return;
-    }
-    */
-
-    racer_rocket_explode();
+    // Apply stabilizer
+    self.angles_x *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * frametime);
+    self.angles_z *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * frametime);
 }
 
 void racer_fire_cannon(string tagname)
 {
+    vector v;
     entity bolt;
 
-    bolt = spawn();
-    bolt.solid           = SOLID_TRIGGER;
-    bolt.movetype        = MOVETYPE_FLYMISSILE;
-    bolt.flags           = FL_PROJECTILE | FL_NOTARGET;
-    bolt.owner           = self;
-    bolt.realowner       = self.owner;
-    bolt.touch           = racer_bolt_explode;
-    bolt.think           = racer_bolt_explode;
-    bolt.nextthink       = time + 9;
-    bolt.bot_dodge       = TRUE;
-    bolt.bot_dodgerating = autocvar_g_vehicle_racer_laser_damage;
-    setorigin(bolt, gettaginfo(self,gettagindex(self,tagname)));
+    v = gettaginfo(self, gettagindex(self, tagname));
+    bolt = vehicles_projectile("wakizashi_gun_muzzleflash", "weapons/lasergun_fire.wav",
+                           v, normalize(v_forward + randomvec() * autocvar_g_vehicle_racer_cannon_spread) * autocvar_g_vehicle_racer_cannon_speed,
+                           autocvar_g_vehicle_racer_cannon_damage, autocvar_g_vehicle_racer_cannon_radius, autocvar_g_vehicle_racer_cannon_force,  0,
+                           DEATH_WAKIGUN, PROJECTILE_WAKICANNON, 0, TRUE, TRUE);
 
-    vector v;
-       // FIXME this uses prydon cursor
-    v = normalize(self.owner.cursor_trace_endpos - bolt.origin);
+       // Fix z-aim (for chase mode)
+    v = normalize(trace_endpos - bolt.origin);
     v_forward_z = v_z * 0.5;
-
-    bolt.velocity = v_forward * autocvar_g_vehicle_racer_laser_speed;
-
-    CSQCProjectile(bolt, TRUE, PROJECTILE_LASER, TRUE);
+    bolt.velocity = v_forward * autocvar_g_vehicle_racer_cannon_speed;
 }
 
 void racer_rocket_groundhugger()
 {
-    vector newdir,olddir;
-    float oldspeed, newspeed;
+    vector olddir, newdir;
+    float oldvel, newvel;
 
     self.nextthink  = time;
 
-    if ((self.owner.deadflag != DEAD_NO) || (self.cnt < time))
+    if(self.owner.deadflag != DEAD_NO || self.cnt < time)
     {
-        racer_rocket_explode();
+        self.use();
         return;
     }
 
@@ -232,35 +153,45 @@ void racer_rocket_groundhugger()
         return;
     }
 
-    olddir   = normalize(self.velocity);
-    oldspeed = vlen(self.velocity);
+    olddir = normalize(self.velocity);
+    oldvel = vlen(self.velocity);
+    newvel = oldvel + self.lip;
 
-    tracebox(self.origin, self.mins, self.maxs, self.origin + olddir * 512, MOVE_WORLDONLY,self);
-    if(trace_fraction >= 0.35)
+    tracebox(self.origin, self.mins, self.maxs, self.origin + olddir * 64, MOVE_WORLDONLY,self);
+    if(trace_fraction <= 0.5)
     {
-        traceline(trace_endpos, trace_endpos - '0 0 512', MOVE_NORMAL, self);
-        if(trace_fraction != 1.0)
-            newdir = trace_endpos + '0 0 32';
-
-        newdir = normalize(newdir - self.origin);
+        // Hitting somethign soon, just speed ahead
+        self.velocity = olddir * newvel;
+        UpdateCSQCProjectile(self);
+        return;
     }
 
-    newspeed = oldspeed + self.lip;
-    self.velocity = normalize(olddir + newdir * self.wait) * newspeed;
+    traceline(trace_endpos, trace_endpos - '0 0 64', MOVE_NORMAL, self);
+    if(trace_fraction != 1.0)
+    {
+        newdir = normalize(trace_endpos + '0 0 64' - self.origin) * autocvar_g_vehicle_racer_rocket_turnrate;
+        self.velocity = normalize(olddir + newdir) * newvel;
+    }
+    else
+    {
+        self.velocity = olddir * newvel;
+        self.velocity_z -= 1600 * sys_frametime; // 2x grav looks better for this one
+    }
 
     UpdateCSQCProjectile(self);
+    return;
 }
 
-void racer_rocket_think()
+void racer_rocket_tracker()
 {
-    vector newdir,olddir, eorg, edir;
-    float oldspeed, newspeed, dist;
+    vector olddir, newdir;
+    float oldvel, newvel;
 
     self.nextthink  = time;
 
-    if ((self.owner.deadflag != DEAD_NO) || (self.cnt < time))
+    if (self.owner.deadflag != DEAD_NO || self.cnt < time)
     {
-        racer_rocket_explode();
+        self.use();
         return;
     }
 
@@ -271,111 +202,70 @@ void racer_rocket_think()
     }
 
     olddir = normalize(self.velocity);
-    oldspeed = vlen(self.velocity);
-    fixedmakevectors(olddir);
-    eorg = 0.5 * (self.enemy.absmin + self.enemy.absmax);
-    edir = normalize(eorg - self.origin);
-    dist = vlen(self.origin - self.enemy.origin);
+    oldvel = vlen(self.velocity);
+    newvel = oldvel + self.lip;
+    makevectors(vectoangles(olddir));
+
+    traceline(self.origin, self.origin + v_forward * 64 - '0 0 32', MOVE_NORMAL, self);
+    newdir = normalize(self.enemy.origin - self.origin);
 
-    if(dist > 512)
+    if(vlen(newdir - v_forward) > autocvar_g_vehicle_racer_rocket_locked_maxangle)
     {
-        vector ddir;
-        float p;
-        p = dist / self.delay;
-        p = max(0.05, p * 0.25);
-        ddir = steerlib_traceavoid(p, oldspeed * 0.25);
-        edir += ddir * 0.95;
+        //bprint("Target lost!\n");
+        //dprint("OF:", ftos(vlen(newdir - v_forward)), "\n");
+        self.think = racer_rocket_groundhugger;
+        return;
     }
 
-    newdir = normalize(olddir + edir * self.wait);
-    newspeed = oldspeed + self.lip;
-    self.velocity = normalize(olddir + newdir * self.wait) * newspeed;
+    if(trace_fraction != 1.0)
+        newdir_z += 16 * sys_frametime;
+
+    self.velocity = normalize(olddir + newdir * autocvar_g_vehicle_racer_rocket_turnrate) * newvel;
+    self.velocity_z -= 800 * sys_frametime;
 
     UpdateCSQCProjectile(self);
+    return;
 }
 
-void racer_fire_rocket(string tagname)
+void racer_fire_rocket(string tagname, entity trg)
 {
+    vector v;
     entity rocket;
 
-    rocket = spawn();
-    setsize (rocket, '-1 -1 -1', '1 1 1');
-    rocket.lip             = autocvar_g_vehicle_racer_rocket_accel * sys_frametime;
-    rocket.wait            = autocvar_g_vehicle_racer_rocket_turnrate;
-    rocket.solid           = SOLID_BBOX;
-    rocket.movetype        = MOVETYPE_FLYMISSILE;
-    rocket.flags           = FL_PROJECTILE;
-    rocket.owner           = self;
-    rocket.realowner       = self.owner;
-    rocket.touch           = racer_rocket_touch;
-    rocket.bot_dodge       = TRUE;
-    rocket.bot_dodgerating = autocvar_g_vehicle_racer_rocket_damage;
-    setorigin(rocket, gettaginfo(self,gettagindex(self,tagname)));
-
-    /*
-    if( (self.tur_head.gun1) && (self.tur_head.cnt > time))
-        rocket.enemy = self.tur_head.gun1;
-
-    if(rocket.enemy)
-    {
-        rocket.delay           = vlen(rocket.enemy.origin  - rocket.origin);
-        rocket.cnt             = time + 9;
-        rocket.velocity = v_forward * autocvar_g_vehicle_racer_rocket_speed;
-        rocket.think = racer_rocket_think;
-        rocket.nextthink = time;
-        CSQCProjectile(rocket, FALSE, PROJECTILE_ROCKET, FALSE); // no culling, has fly sound
-    }
-    else
-    {
-    */
-        rocket.cnt             = time + 9;
-        rocket.velocity = v_forward * autocvar_g_vehicle_racer_rocket_speed;
-        rocket.think = racer_rocket_groundhugger;
-        rocket.nextthink = time;
-        CSQCProjectile(rocket, TRUE, PROJECTILE_ROCKET, TRUE);
-    //}
-}
-
-float racer_customizeentityforclient()
-{
+    v = gettaginfo(self, gettagindex(self, tagname));
+    rocket = vehicles_projectile("wakizashi_rocket_launch", "weapons/rocket_fire.wav",
+                           v, v_forward * autocvar_g_vehicle_racer_rocket_speed,
+                           autocvar_g_vehicle_racer_rocket_damage, autocvar_g_vehicle_racer_rocket_radius, autocvar_g_vehicle_racer_rocket_force, 3,
+                           DEATH_WAKIROCKET, PROJECTILE_WAKIROCKET, 20, FALSE, FALSE);
 
-    if(self.deadflag == DEAD_DEAD)
-        return FALSE;
+    rocket.lip              = autocvar_g_vehicle_racer_rocket_accel * sys_frametime;
+    rocket.wait             = autocvar_g_vehicle_racer_rocket_turnrate;
+    rocket.nextthink        = time;
+    rocket.enemy            = trg;
+    rocket.cnt              = time + 15;
 
-    /*
-    if(other == self.owner)
-        self.alpha = -1;
+    if(trg)
+        rocket.think            = racer_rocket_tracker;
     else
-        self.alpha = 1;
-    */
-
-    return TRUE;
+        rocket.think            = racer_rocket_groundhugger;
 }
 
-float racer_pplug()
+float racer_frame()
 {
     entity player, racer;
-    float ftmp, ftmp2;
     vector df;
-
-    if(autocvar_g_vehicle_racer_reload)
-    {
-        racer_loadsettings();
-        cvar_set("g_vehicle_racer_reload","0");
-    }
+    float ftmp;
 
     player          = self;
     racer           = self.vehicle;
 
-    player.BUTTON_ZOOM = 0;
-    player.BUTTON_CROUCH = 0;
+    player.BUTTON_ZOOM = player.BUTTON_CROUCH = 0;
 
     self = racer;
 
     if(player.BUTTON_USE)
     {
-        self = racer;
-        racer_exit(0);
+        vehicles_exit(VHEF_NORMAL);
         self = player;
         return 0;
     }
@@ -387,66 +277,88 @@ float racer_pplug()
         return 1;
     }
 
-
     racer_align4point();
 
-    racer.angles_x *= -1;
-    makevectors(racer.angles);
+    crosshair_trace(player);
 
-    // Rotate Body
-    ftmp = racer_turnspeed * sys_frametime;
-    ftmp2 = ftmp * -1;
+    racer.angles_x *= -1;
 
-    ftmp = bound(ftmp2, shortangle_f(player.v_angle_y - racer.angles_y, racer.angles_y), ftmp);
-    ftmp2 = anglemods(racer.angles_y + ftmp);
+    // Yaw
+    ftmp = autocvar_g_vehicle_racer_turnspeed * frametime;
+    ftmp = bound(-ftmp, shortangle_f(player.v_angle_y - racer.angles_y, racer.angles_y), ftmp);
+    racer.angles_y = anglemods(racer.angles_y + ftmp);
 
     // Roll
-    ftmp = bound(-45, shortangle_f(player.v_angle_z + ((racer.angles_y - ftmp2) * racer_turnroll), racer.angles_z), 45);
-    ftmp = anglemods(racer.angles_z + ftmp);
-    racer.angles_z = bound(-85, ftmp, 85);
+    racer.angles_z += -ftmp * autocvar_g_vehicle_racer_turnroll * frametime;
 
-    // Turn
-    racer.angles_y = ftmp2;
+    // Pitch
+    ftmp = autocvar_g_vehicle_racer_pitchspeed  * frametime;
+    ftmp = bound(-ftmp, shortangle_f(player.v_angle_x - racer.angles_x, racer.angles_x), ftmp);
+    racer.angles_x = bound(-30, anglemods(racer.angles_x + ftmp), 30);
 
-    // Pitch Body
-    ftmp = racer_pitchspeed * sys_frametime;
-    ftmp2 = ftmp * -1;
-
-    ftmp = bound(ftmp2,shortangle_f(player.v_angle_x - racer.angles_x,racer.angles_x),ftmp);
-    racer.angles_x = anglemods(racer.angles_x + ftmp);
+    makevectors(racer.angles);
     racer.angles_x *= -1;
 
-    df = racer.velocity * -0.5;
+
+    ftmp = racer.velocity_z;
+    df = racer.velocity * -autocvar_g_vehicle_racer_friction;
+    racer.velocity_z = ftmp;
 
     if(player.movement_x != 0)
     {
         if(player.movement_x > 0)
-            df += v_forward  * racer_speed_forward;
+            df += v_forward  * autocvar_g_vehicle_racer_speed_forward;
         else if(player.movement_x < 0)
-            df -= v_forward  * racer_speed_forward;
+            df -= v_forward  * autocvar_g_vehicle_racer_speed_forward;
     }
 
     if(player.movement_y != 0)
     {
         if(player.movement_y < 0)
-            df -= v_right * racer_speed_strafe;
+            df -= v_right * autocvar_g_vehicle_racer_speed_strafe;
         else if(player.movement_y > 0)
-            df += v_right * racer_speed_strafe;
+            df += v_right * autocvar_g_vehicle_racer_speed_strafe;
     }
-
-    // limit _z to avoid flying on normal thrust
-    if(df_z > 0)
-        df_z = min(df_z,700);
-
-
+    
+    if(vlen(player.movement) != 0)
+    {
+        if(self.sound_nexttime < time || self.sounds != 1)
+        {        
+            self.sounds = 1;
+            self.sound_nexttime = time + 10.922667; //soundlength("vehicles/racer_move.wav");
+            sound (self, CHAN_TRIGGER, "vehicles/racer_move.wav", VOL_VEHICLEENGINE, ATTN_NORM);
+        }
+    }
+    else
+    {        
+        if(self.sound_nexttime < time || self.sounds != 0)
+        {        
+            self.sounds = 0;
+            self.sound_nexttime = time + 11.888604; //soundlength("vehicles/racer_idle.wav");
+            sound (self, CHAN_TRIGGER, "vehicles/racer_idle.wav", VOL_VEHICLEENGINE, ATTN_NORM);
+        }        
+    }
+    
     // Afterburn
-    if (player.BUTTON_JUMP)
-    if(racer.vehicle_energy >= (racer_afterburn_cost * frametime))
+    if (player.BUTTON_JUMP && racer.vehicle_energy >= (autocvar_g_vehicle_racer_afterburn_cost * frametime))
     {
-        racer.wait = time + autocvar_g_vehicle_racer_energy_usepause;
-        racer.vehicle_energy -= racer_afterburn_cost * frametime;
+        racer.wait = time;
+        racer.vehicle_energy -= autocvar_g_vehicle_racer_afterburn_cost * frametime;
         df += (v_forward * autocvar_g_vehicle_racer_speed_afterburn);
+        
+        if(self.strength_finished < time)
+        {        
+            //self.sounds = 2;
+            self.strength_finished = time + 10.922667; //soundlength("vehicles/racer_boost.wav");
+            sound (self, CHAN_PAIN, "vehicles/racer_boost.wav", VOL_VEHICLEENGINE, ATTN_NORM);
+        }        
+    }
+    else
+    {
+        self.strength_finished = 0;
+        sound (self, CHAN_PAIN, "misc/null.wav", VOL_VEHICLEENGINE, ATTN_NORM);
     }
+        
 
     racer.velocity  += df * frametime;
 
@@ -454,23 +366,14 @@ float racer_pplug()
     racer.velocity  = racer.velocity - df;
     player.movement = racer.velocity;
 
-    /*
-    // for homing rockets
-       // FIXME this uses prydon cursor
-    if(self.owner.cursor_trace_ent)
-    {
-        self.tur_head.gun1 = self.owner.cursor_trace_ent;
-        self.tur_head.cnt = time + 1;
-    }
-    */
-
     if(player.BUTTON_ATCK)
     if(time > racer.attack_finished_single)
-    if(racer.vehicle_energy >= autocvar_g_vehicle_racer_laser_cost)
+    if(racer.vehicle_energy >= autocvar_g_vehicle_racer_cannon_cost)
     {
-        racer.vehicle_energy -= autocvar_g_vehicle_racer_laser_cost;
-        racer.wait = time + autocvar_g_vehicle_racer_energy_usepause;
+        racer.vehicle_energy -= autocvar_g_vehicle_racer_cannon_cost;
+        racer.wait = time;
 
+        crosshair_trace(player);
         if(racer.cnt)
         {
             racer_fire_cannon("tag_fire1");
@@ -481,285 +384,167 @@ float racer_pplug()
             racer_fire_cannon("tag_fire2");
             racer.cnt = 1;
         }
-        racer.attack_finished_single = time + autocvar_g_vehicle_racer_laser_refire;
+        racer.attack_finished_single = time + autocvar_g_vehicle_racer_cannon_refire;
+        //self.owner.vehicle_energy = racer.vehicle_energy / autocvar_g_vehicle_racer_energy;
     }
 
-    if(player.BUTTON_ATCK2)
-    if(time > racer.delay)
+    if(autocvar_g_vehicle_racer_rocket_locktarget)
     {
-        racer_fire_rocket("tag_rocket_r");
-        racer_fire_rocket("tag_rocket_l");
-        racer.delay = time + autocvar_g_vehicle_racer_rocket_refire;
-        racer.lip = time;
+        vehicles_locktarget((1 / autocvar_g_vehicle_racer_rocket_locking_time) * frametime,
+                         (1 / autocvar_g_vehicle_racer_rocket_locking_releasetime) * frametime,
+                         autocvar_g_vehicle_racer_rocket_locked_time);
 
+        if(self.lock_target)
+        {
+            if(racer.lock_strength == 1)
+                UpdateAuxiliaryXhair(player, real_origin(self.lock_target), '1 0 0', 0);
+            else if(self.lock_strength > 0.5)
+                UpdateAuxiliaryXhair(player, real_origin(self.lock_target), '0 1 0', 0);
+            else if(self.lock_strength < 0.5)
+                UpdateAuxiliaryXhair(player, real_origin(self.lock_target), '0 0 1', 0);
+        }
     }
 
-    player.vehicle_reload1 = (time - racer.lip) / (racer.delay-racer.lip);
-    vehicle_stdproc_shiledregen(racer_shieldmax, frametime);
-    vehicle_stdproc_healthregen(racer_healthmax, frametime);
-
-    if (racer.wait < time)
-        vehicle_stdproc_energyregen(racer_energymax, frametime);
-    else
-        player.vehicle_energy = (racer.vehicle_energy / racer_energymax);
-
-    self = player;
+    if(time > racer.delay)
+    if(player.BUTTON_ATCK2)
+    {
+        self.misc_bulletcounter += 1;
+        racer.delay = time + 0.3;
+        if(self.misc_bulletcounter == 1)
+            racer_fire_rocket("tag_rocket_r", (self.lock_strength == 1 && self.lock_target) ? self.lock_target : world);
+        else if(self.misc_bulletcounter == 2)
+        {
+            racer_fire_rocket("tag_rocket_l", (self.lock_strength == 1 && self.lock_target) ? self.lock_target : world);
+            self.lock_strength  = 0;
+            self.lock_target    = world;
+            self.misc_bulletcounter = 0;
 
-    player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0;
-    setorigin(player,racer.origin + '0 0 32');
-    player.velocity = racer.velocity;
+            racer.delay = time + autocvar_g_vehicle_racer_rocket_refire;
+            racer.lip = time;
+        }
+    }
+    player.vehicle_reload1 = bound(0, 100 * ((time - racer.lip) / (racer.delay - racer.lip)), 100);
 
-    return 1;
-}
+    if(self.vehicle_flags  & VHF_SHIELDREGEN)
+        vehicles_regen(dmg_time, vehicle_shield, autocvar_g_vehicle_racer_shield, autocvar_g_vehicle_racer_shield_regen_pause, autocvar_g_vehicle_racer_shield_regen, frametime);
 
-void racer_exitthink()
-{
-    float a, b, c;
+    if(self.vehicle_flags  & VHF_HEALTHREGEN)
+        vehicles_regen(dmg_time, vehicle_health, autocvar_g_vehicle_racer_health, autocvar_g_vehicle_racer_health_regen_pause, autocvar_g_vehicle_racer_health_regen, frametime);
 
-    self.nextthink = time;
+    if(self.vehicle_flags  & VHF_ENERGYREGEN)
+        vehicles_regen(wait, vehicle_energy, autocvar_g_vehicle_racer_energy, autocvar_g_vehicle_racer_energy_regen_pause, autocvar_g_vehicle_racer_energy_regen, frametime);
 
-    a = racer_anglestabilizer;
-    b = racer_springlength;
-    c = racer_power_solid;
 
-    racer_anglestabilizer = 36;
-    racer_springlength = 96;
-    racer_power_solid = 300;
+    VEHICLE_UPDATE_PLAYER(health, racer);
+    VEHICLE_UPDATE_PLAYER(energy, racer);
 
-    racer_align4point();
+    if(self.vehicle_flags & VHF_HASSHIELD)
+        VEHICLE_UPDATE_PLAYER(shield, racer);
 
-    if(self.velocity_z < 0)
-        self.velocity_z *= 0.95;
 
-    racer_anglestabilizer = a;
-    racer_springlength = b;
-    racer_power_solid = c;
+    player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0;
+    setorigin(player,racer.origin + '0 0 32');
+    player.velocity = racer.velocity;
 
-    self.velocity_x *= 0.95;
-    self.velocity_y *= 0.95;
+    self = player;
+    return 1;
 }
 
-void racer_spawnthink()
+void racer_think()
 {
-    float a, b, c;
-    vector dorg;
-
-    self.nextthink = time;
-
-    a = racer_anglestabilizer;
-    b = racer_springlength;
-    c = racer_power_solid;
-
-    racer_anglestabilizer = 36;
-    racer_springlength = 96;
-    racer_power_solid = 300;
-
-    // self.velocity_z += sin(time * 128) * 4;
-
-    racer_align4point();
+    /*
+    float a, b, c;a = autocvar_g_vehicle_racer_anglestabilizer;
+    b = autocvar_g_vehicle_racer_springlength;
+    c = autocvar_g_vehicle_racer_hoverpower;
 
-    if(self.velocity_z < 0)
-        self.velocity_z *= 0.98;
+    autocvar_g_vehicle_racer_anglestabilizer = 36;
+    autocvar_g_vehicle_racer_springlength = 96;
+    autocvar_g_vehicle_racer_hoverpower = 300;
+    */
 
-    racer_anglestabilizer = a;
-    racer_springlength = b;
-    racer_power_solid = c;
+    racer_align4point(); //time - self.nextthink);
 
-    self.velocity_x *= 0.95;
-    self.velocity_y *= 0.95;
+    /*
+    //if(self.velocity_z > 0)
+    //    self.velocity_z *= 0.95;
 
-    dorg = self.pos1 - self.origin ;
+    autocvar_g_vehicle_racer_anglestabilizer = a;
+    autocvar_g_vehicle_racer_springlength = b;
+    autocvar_g_vehicle_racer_hoverpower = c;
+    */
 
-    self.velocity_x = bound(-32, self.velocity_x + dorg_x, 32);
-    self.velocity_y = bound(-32, self.velocity_y + dorg_y, 32);
+    self.velocity_x *= 0.9;
+    self.velocity_y *= 0.9;
+    self.velocity_z *= 0.8;
+    self.velocity_z += sin(time * 2) * 16;
+    self.nextthink = time; // + 0.05;
 }
 
 void racer_enter()
 {
-    self.owner = other;
-
-
-    self.nextthink = 0;
-    self.flags               = 0;
-    self.vehicle_hudmodel.viewmodelforclient = self.owner;
-    self.colormap             = self.owner.colormap;
-
-    self.owner.PlayerPhysplug = racer_pplug;
-    self.owner.takedamage     = DAMAGE_NO;
-    self.owner.event_damage   = SUB_Null;
-    self.owner.vehicle        = self;
-    self.owner.angles = self.angles;
-    self.owner.solid          = SOLID_NOT;
-    self.owner.movetype       = MOVETYPE_NOCLIP;
-    self.owner.alpha          = -1;
-    self.owner.hud            = HUD_WAKIZASHI;
-    self.owner.effects        |= EF_NODRAW;
-    self.owner.view_ofs = '0 0 0';
-
+    self.movetype = MOVETYPE_BOUNCE;
     self.owner.vehicle_health = (self.vehicle_health / autocvar_g_vehicle_racer_health);
     self.owner.vehicle_shield = (self.vehicle_shield / autocvar_g_vehicle_racer_shield);
-
-    setorigin(other,self.origin + '0 0 32');
-    other.velocity = self.velocity;
-
-    other.flags &~= FL_ONGROUND;
-    msg_entity = other;
-    WriteByte (MSG_ONE, SVC_SETVIEWPORT);
-    WriteEntity( MSG_ONE, self.vehicle_viewport);
-
-    WriteByte (MSG_ONE, SVC_SETVIEWANGLES); // 10 = SVC_SETVIEWANGLES
-    WriteAngle(MSG_ONE,  self.angles_x * -1);    // tilt
-    WriteAngle(MSG_ONE,  self.angles_y);    // yaw
-    WriteAngle(MSG_ONE,  0);                // roll
-}
-
-void racer_spawn();
-void racer_return()
-{
-    pointparticles(particleeffectnum("teleport"), self.enemy.origin + '0 0 64', '0 0 0', 1);
-    self.enemy.think = racer_spawn;
-    self.enemy.nextthink = time;
-    remove(self);
 }
 
 void racer_exit(float eject)
 {
-       self.colormap   = 1024;
-       self.flags      = FL_NOTARGET;
+    vector spot;
+    
+    self.think      = racer_think;
+    self.nextthink  = time;
+    self.movetype   = MOVETYPE_TOSS;
 
     if not (self.owner)
         return;
 
-    msg_entity = self.owner;
-    WriteByte (MSG_ONE, SVC_SETVIEWPORT);
-    WriteEntity( MSG_ONE, self.owner);
-
-    WriteByte (MSG_ONE, SVC_SETVIEWANGLES);    // 10 = SVC_SETVIEWANGLES
-    WriteAngle(MSG_ONE,  0);                   // tilt
-    WriteAngle(MSG_ONE,  self.angles_y); // yaw
-    WriteAngle(MSG_ONE,  0);                   // roll
-
-    if (self.deadflag == DEAD_NO)
-    {
-        self.think = racer_exitthink;
-        self.nextthink = time;
-    }
-
-    self.owner.takedamage     = DAMAGE_AIM;
-    self.owner.solid          = SOLID_SLIDEBOX;
-    self.owner.movetype       = MOVETYPE_WALK;
-
-    setsize(self.owner,PL_MIN,PL_MAX);
-
-    self.owner.effects        &~= EF_NODRAW;
-    self.owner.alpha          = 1;
-    self.owner.PlayerPhysplug = SUB_Null;
-    self.owner.vehicle        = world;
-       self.owner.view_ofs       = PL_VIEW_OFS;
-       self.owner.event_damage   = PlayerDamage;
-       self.owner.hud            = HUD_NORMAL;
-
-    self.vehicle_hudmodel.viewmodelforclient = self;
-
+       makevectors(self.angles);
        if(eject)
        {
-           makevectors(self.angles);
-           setorigin(self.owner,self.origin + v_forward * 100);
+           spot = self.origin + v_forward * 100 + '0 0 64';
+           spot = vehicles_findgoodexit(spot);
+           setorigin(self.owner , spot);
            self.owner.velocity = (v_up + v_forward * 0.25) * 750;
        }
        else
        {
-           self.owner.velocity = (v_forward) * -150;
-        setorigin(self.owner,self.origin - v_forward * 128);
+           spot = self.origin - v_forward * 200 + '0 0 64';
+           spot = vehicles_findgoodexit(spot);
+           setorigin(self.owner , spot);
        }
-
+       
     self.owner = world;
-
-    if (self.deadflag != DEAD_NO)
-    {
-        entity ret;
-        ret = spawn();
-        ret.enemy = self;
-        ret.think = racer_return;
-        ret.nextthink = time + autocvar_g_vehicle_racer_respawntime;
-    }
-}
-
-void racer_touch()
-{
-    if(self.owner)
-    {
-        if(vlen(self.velocity) == 0)
-            return;
-
-        if(other.classname != "player")
-            return;
-
-        vector a;
-        a = normalize(other.origin - self.origin);
-        a = a - normalize(self.velocity);
-
-        return;
-    }
-
-    if(other.classname != "player")
-        return;
-
-    if(other.deadflag != DEAD_NO)
-        return;
-
-    if(other.vehicle != world)
-        return;
-
-    racer_enter();
 }
 
 void racer_spawn()
 {
-    self.think = racer_spawnthink;
-    self.nextthink = time;
-
-    self.flags      = FL_NOTARGET;
-    self.effects   = 0;
-
-    self.vehicle_health = racer_healthmax;
-    self.vehicle_shield = racer_shieldmax;
+    self.think          = racer_think;
+    self.nextthink      = time;
+    self.vehicle_health = autocvar_g_vehicle_racer_health;
+    self.vehicle_shield = autocvar_g_vehicle_racer_shield;
 
-    self.event_damage = vehicle_stdproc_damage;
-    self.touch      = racer_touch;
+    self.movetype       = MOVETYPE_TOSS;
+    self.solid          = SOLID_SLIDEBOX;
+    self.delay          = time;
+    self.scale          = 0.5;
 
-    self.iscreature = TRUE;
-    self.scale      = 0.5;
-    self.movetype   = MOVETYPE_FLY;
-    self.solid      = SOLID_SLIDEBOX;
-    self.takedamage = DAMAGE_AIM;
-
-    self.alpha = 1;
-       self.colormap = 1024;
-       self.deadflag    = DEAD_NO;
-    self.bot_attack = TRUE;
-
-    self.vehicle_energy = 1;
-    self.vehicle_hudmodel.viewmodelforclient = self;
-
-    setorigin(self, self.pos1);
-    self.angles = self.pos2;
-
-    setsize(self,RACER_MIN * 0.5,RACER_MAX * 0.5);
-    pointparticles(particleeffectnum("teleport"), self.origin + '0 0 64', '0 0 0', 1);
-    self.delay = time;
+    setsize(self, RACER_MIN * 0.5, RACER_MAX * 0.5);
 }
 
 
 void racer_blowup()
 {
-
     sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
-    pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
+    pointparticles(particleeffectnum("explosion_big"), self.origin, '0 0 0', 1);
 
     self.deadflag    = DEAD_DEAD;
     self.vehicle_exit(VHEF_NORMAL);
-    RadiusDamage (self, self, 250, 15, 250, world, 250, DEATH_WAKIBLOWUP, world);
+
+    RadiusDamage (self, self, autocvar_g_vehicle_racer_blowup_coredamage,
+                                       autocvar_g_vehicle_racer_blowup_edgedamage,
+                                       autocvar_g_vehicle_racer_blowup_radius, world,
+                                       autocvar_g_vehicle_racer_blowup_forceintensity,
+                                       DEATH_WAKIBLOWUP, world);
 
     self.alpha = -1;
     self.nextthink  = time + autocvar_g_vehicle_racer_respawntime;
@@ -767,20 +552,22 @@ void racer_blowup()
     self.movetype   = MOVETYPE_NONE;
     self.effects    = EF_NODRAW;
 
-    self.avelocity_z  = 0;
-    self.colormod = '0 0 0';
+    self.colormod  = '0 0 0';
+    self.avelocity = '0 0 0';
+    self.velocity  = '0 0 0';
 
-    setorigin(self,self.pos1);
+    setorigin(self, self.pos1);
+       self.think     = racer_spawn;
+       self.nextthink = time + autocvar_g_vehicle_racer_respawntime;
 }
 
-void racer_dietouch()
+void racer_deadtouch()
 {
-    if(self.wait > time)
-        return;
-
-    self.wait = time + 0.75;
-
-    pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
+    dprint("Boink!\n");
+    self.avelocity_x *= 0.7;
+    self.cnt -= 1;
+    if(self.cnt <= 0)
+        racer_blowup();
 }
 
 void racer_die()
@@ -788,111 +575,94 @@ void racer_die()
     self.health       = 0;
     self.event_damage = SUB_Null;
     self.iscreature   = FALSE;
-    self.solid        = SOLID_NOT;
+    self.solid        = SOLID_CORPSE;
     self.takedamage   = DAMAGE_NO;
-    self.touch        = racer_dietouch;
     self.deadflag     = DEAD_DYING;
     self.movetype     = MOVETYPE_BOUNCE;
-    self.wait = time;
-
-    pointparticles(particleeffectnum("rocket_explode"), findbetterlocation (self.origin, 16), '0 0 0', 1);
-
-    self.velocity     += '0 0 128';
+    self.wait         = time;
+    self.cnt          = 1 + random() * 2;
+    self.touch        = racer_deadtouch;
+    
+    pointparticles(particleeffectnum("explosion_medium"), self.origin, '0 0 0', 1);    
 
     if(random() < 0.5)
-        self.avelocity_z  = 16;
+        self.avelocity_z  = 32;
     else
-        self.avelocity_z  = -16;
+        self.avelocity_z  = -32;
 
-    self.colormod = '-0.5 -0.5 -0.5';
+    self.avelocity_x = -vlen(self.velocity) * 0.2;
+    self.velocity   += '0 0 700';
+    self.colormod    = '-0.5 -0.5 -0.5';
 
        self.think     = racer_blowup;
-       self.nextthink = time + 3;
+       self.nextthink = 2 + time + random() * 3;
 }
 
 void racer_dinit()
 {
+    if not (vehicle_initialize(
+             "Wakizashi",
+             "models/vehicles/wakizashi.dpm",
+             "",
+             "models/vehicles/wakizashi_cockpit.dpm",
+             "", "", "tag_viewport",
+             HUD_WAKIZASHI,
+             0.5 * RACER_MIN, 0.5 * RACER_MAX,
+             FALSE,
+             racer_spawn, autocvar_g_vehicle_racer_respawntime,
+             racer_frame,
+             racer_enter, racer_exit,
+             racer_die,   racer_think,
+             TRUE))
+    {
+        remove(self);
+        return;
+    }
 
-    tracebox(self.origin + '0 0 100', RACER_MIN * 0.5, RACER_MAX * 0.5, self.origin - '0 0 10000', MOVE_WORLDONLY, self);
-    setorigin(self,trace_endpos);
-
-    if (self.netname == "")
-        self.netname     = "Race PoD";
-
-    self.cvar_basename      = "g_vehicle_racer";
-
-    self.vehicle_viewport   = spawn();
-    self.vehicle_hudmodel   = spawn();
-    //self.ccamera            = spawn();
-
-    setorigin(self, self.origin);
-
-    setmodel(self,"models/vehicles/wakizashi.dpm");
-    setmodel(self.vehicle_hudmodel, "models/vehicles/wakizashi_cockpit.dpm");
-    setmodel (self.vehicle_viewport, "null");
+    if(autocvar_g_vehicle_racer_hovertype != 0)
+        racer_force_from_tag = vehicles_force_fromtag_maglev;
+    else
+        racer_force_from_tag = vehicles_force_fromtag_hover;
 
+    // FIXME: this be hakkz, fix the models insted (scale body, add tag_viewport to the hudmodel).
+    self.scale = 0.5;
     setattachment(self.vehicle_hudmodel, self, "");
     setattachment(self.vehicle_viewport, self, "tag_viewport");
 
-    self.vehicle_hudmodel.viewmodelforclient = self;
-    self.customizeentityforclient            = racer_customizeentityforclient;
-
-    self.tur_head     = spawn();
-
-    self.pos1         = self.origin;
-    self.pos2         = self.angles;
-    self.angles       = '0 0 0';
-    self.angles       = self.pos1;
-
-    self.vehicle_die  = racer_die;
-    self.vehicle_exit = racer_exit;
-
-    addstat(STAT_HUD, AS_INT,  hud);
-       addstat(STAT_VEHICLESTAT_HEALTH,  AS_FLOAT, vehicle_health);
-       addstat(STAT_VEHICLESTAT_SHIELD,  AS_FLOAT, vehicle_shield);
-       addstat(STAT_VEHICLESTAT_ENERGY,  AS_FLOAT, vehicle_energy);
-
-       addstat(STAT_VEHICLESTAT_AMMO1,   AS_INT,   vehicle_ammo1);
-       addstat(STAT_VEHICLESTAT_RELOAD1, AS_FLOAT, vehicle_reload1);
-
-       addstat(STAT_VEHICLESTAT_AMMO2,   AS_INT,   vehicle_ammo2);
-       addstat(STAT_VEHICLESTAT_RELOAD2, AS_FLOAT, vehicle_reload2);
-
-    racer_spawn();
+    self.mass               = 900;
 }
 
 void spawnfunc_vehicle_racer()
 {
-    g_turrets_common_precash();
-    racer_loadsettings();
-
-    self.vehicle_flags      = VHF_HASSHIELD | VHF_SHIELDREGEN;
-
-    /*
-    traceline(self.origin,self.origin - '0 0 2048',MOVE_WORLDONLY,self);
-    if(trace_startsolid)
-    {
-        dprint("WARNING: vehicle_racer placed in solid\n");
-        traceline(self.origin + '0 0 512' ,self.origin - '0 0 2048',MOVE_WORLDONLY,self);
-        if(trace_startsolid || trace_fraction == 1.0)
-        {
-            dprint("ERROR: vehicle_racer placed in more then 512 units into solid\n");
-            remove(self);
-            return;
-        }
-    }
-    */
 
-    if(trace_fraction != 1.0)
-        setorigin(self,trace_endpos + '0 0 128');
-    else
-        dprint("WARNING: vehicle_racer placed more then 2048 units above ground.\n");
+    precache_sound ("weapons/laserimpact.wav");
+    precache_sound ("weapons/lasergun_fire.wav");
+    precache_sound ("weapons/rocket_fire.wav");
+    precache_sound ("weapons/rocket_impact.wav");
+    
+    precache_sound ("vehicles/racer_idle.wav");
+    precache_sound ("vehicles/racer_move.wav");
+    precache_sound ("vehicles/racer_boost.wav");
 
+    precache_model ("models/vhshield.md3");
     precache_model ("models/vehicles/wakizashi.dpm");
     precache_model ("models/vehicles/wakizashi_cockpit.dpm");
-    precache_model ("maps/bspmodel.bsp");
 
+    vehicles_configcheck("vehicle_racer.cfg", autocvar_g_vehicle_racer_health);
+    if(autocvar_g_vehicle_racer_energy)
+        if(autocvar_g_vehicle_racer_energy_regen)
+            self.vehicle_flags |= VHF_ENERGYREGEN;
+
+    if(autocvar_g_vehicle_racer_shield)
+        self.vehicle_flags |= VHF_HASSHIELD;
+
+    if(autocvar_g_vehicle_racer_shield_regen)
+        self.vehicle_flags |= VHF_SHIELDREGEN;
+
+    if(autocvar_g_vehicle_racer_health_regen)
+        self.vehicle_flags |= VHF_HEALTHREGEN;
 
     self.think = racer_dinit;
-    self.nextthink = time + 1;
+    self.nextthink = time + (autocvar_g_vehicles_delayspawn ? autocvar_g_vehicle_racer_respawntime + (random() * autocvar_g_vehicles_delayspawn_jitter) : 0.5);
 }
+#endif // SVQC
index 38ebad0..6d12066 100644 (file)
-#define RAPTOR_MIN '-40 -40 0'
-#define RAPTOR_MAX '40 40 40'
-
-float raptor_movestyle;
-float raptor_turnspeed;
-float raptor_turnroll;
-float raptor_pitchspeed;
-float raptor_speed_forward;
-float raptor_speed_strafe;
-float raptor_speed_up;
-float raptor_speed_down;
-
-float raptor_bomblet_waves;
-float raptor_bomblet_wavefirst;
-float raptor_bomblet_wavenext;
-float raptor_bomblet_wawespread;
-float raptor_bomblets;
-float raptor_bomblet_damage;
-float raptor_bomblet_edgedamage;
-float raptor_bomblet_radius;
-float raptor_bomblet_force;
-float raptor_bombs_refire;
-
-float raptor_beam_dps;
-float raptor_beam_fops;
-float raptor_beam_aps;
-float raptor_beam_size;
-float raptor_beam_leangth;
-float raptor_beam_refire;
-
-float raptor_shield_max;
-float raptor_shield_regen;
-
-float raptor_health_max;
-float raptor_health_regen;
-
-float raptor_energy_max;
-float raptor_energy_regen;
+#ifdef SVQC
+#define RAPTOR_MIN '-80 -80 0'
+#define RAPTOR_MAX '80 80 70'
+//#define RAPTOR_ENGINE "sound/vehicles/raptor.wav"
+float autocvar_g_vehicle_raptor_respawntime;
+
+float autocvar_g_vehicle_raptor_movestyle;
+float autocvar_g_vehicle_raptor_turnspeed;
+float autocvar_g_vehicle_raptor_pitchspeed;
+float autocvar_g_vehicle_raptor_pitchlimit;
+
+float autocvar_g_vehicle_raptor_speed_forward;
+float autocvar_g_vehicle_raptor_speed_strafe;
+float autocvar_g_vehicle_raptor_speed_up;
+float autocvar_g_vehicle_raptor_speed_down;
+float autocvar_g_vehicle_raptor_friction;
+
+float autocvar_g_vehicle_raptor_bomblets;
+float autocvar_g_vehicle_raptor_bomblet_alt;
+float autocvar_g_vehicle_raptor_bomblet_time;
+float autocvar_g_vehicle_raptor_bomblet_damage;
+float autocvar_g_vehicle_raptor_bomblet_spread;
+float autocvar_g_vehicle_raptor_bomblet_edgedamage;
+float autocvar_g_vehicle_raptor_bomblet_radius;
+float autocvar_g_vehicle_raptor_bomblet_force;
+float autocvar_g_vehicle_raptor_bomblet_explode_delay;
+float autocvar_g_vehicle_raptor_bombs_refire;
+
+float autocvar_g_vehicle_raptor_cannon_turnspeed;
+float autocvar_g_vehicle_raptor_cannon_turnlimit;
+float autocvar_g_vehicle_raptor_cannon_pitchlimit_up;
+float autocvar_g_vehicle_raptor_cannon_pitchlimit_down;
+
+float autocvar_g_vehicle_raptor_cannon_locktarget;
+float autocvar_g_vehicle_raptor_cannon_locking_time;
+float autocvar_g_vehicle_raptor_cannon_locking_releasetime;
+float autocvar_g_vehicle_raptor_cannon_locked_time;
+float autocvar_g_vehicle_raptor_cannon_predicttarget;
+
+float autocvar_g_vehicle_raptor_cannon_cost;
+float autocvar_g_vehicle_raptor_cannon_damage;
+float autocvar_g_vehicle_raptor_cannon_radius;
+float autocvar_g_vehicle_raptor_cannon_refire;
+float autocvar_g_vehicle_raptor_cannon_speed;
+float autocvar_g_vehicle_raptor_cannon_spread;
+float autocvar_g_vehicle_raptor_cannon_force;
+
+float autocvar_g_vehicle_raptor_energy;
+float autocvar_g_vehicle_raptor_energy_regen;
+float autocvar_g_vehicle_raptor_energy_regen_pause;
+
+float autocvar_g_vehicle_raptor_health;
+float autocvar_g_vehicle_raptor_health_regen;
+float autocvar_g_vehicle_raptor_health_regen_pause;
+
+float autocvar_g_vehicle_raptor_shield;
+float autocvar_g_vehicle_raptor_shield_regen;
+float autocvar_g_vehicle_raptor_shield_regen_pause;
 
 void raptor_spawn();
-void raptor_return();
-float raptor_pplug();
+float raptor_frame();
 float raptor_takeoff();
-float raptor_land();
 
 .entity bomb1;
 .entity bomb2;
 
 float raptor_altitude(float amax)
 {
-       tracebox(self.origin, self.mins, self.maxs, '0 0 -1' * amax, TRUE, self);
-       if(trace_fraction == 1)
-        return amax+1;
-    else
-        return vlen(self.origin - trace_endpos);
+       tracebox(self.origin, self.mins, self.maxs, self.origin - ('0 0 1' * amax), TRUE, self);
+    return vlen(self.origin - trace_endpos);
 }
 
-void raptor_loadsettings()
-{
-    raptor_movestyle     = CCVAR("_movestyle");
-    raptor_turnspeed     = CCVAR("_turnspeed");
-    raptor_turnroll      = CCVAR("_turnroll");
-    raptor_pitchspeed    = CCVAR("_pitchspeed");
-    raptor_speed_forward = CCVAR("_speed_forward");
-    raptor_speed_strafe  = CCVAR("_speed_strafe");
-    raptor_speed_up      = CCVAR("_speed_up");
-    raptor_speed_down    = CCVAR("_speed_down");
-
-    raptor_bomblet_waves      = CCVAR("_bomblet_waves ");
-    raptor_bomblet_wavefirst  = CCVAR("_bomblet_wavefirst");
-    raptor_bomblet_wavenext   = CCVAR("_bomblet_wavenext");
-    raptor_bomblet_wawespread = CCVAR("_bomblet_wawespread");
-    raptor_bomblets           = CCVAR("_bomblets");
-    raptor_bomblet_damage     = CCVAR("_bomblet_damage");
-    raptor_bomblet_edgedamage = CCVAR("_bomblet_edgedamage");
-    raptor_bomblet_radius     = CCVAR("_bomblet_radius");
-    raptor_bomblet_force      = CCVAR("_bomblet_force ");
-    raptor_bombs_refire       = CCVAR("_bombs_refire");
-
-    raptor_beam_dps     = CCVAR("_beam_dps");
-    raptor_beam_fops    = CCVAR("_beam_fops");
-    raptor_beam_aps     = CCVAR("_beam_aps");
-    raptor_beam_size    = CCVAR("_beam_size");
-    raptor_beam_leangth = CCVAR("_beam_length");
-    raptor_beam_refire  = CCVAR("_beam_refire");
-
-    raptor_shield_max    = CCVAR("_shield");
-    raptor_shield_regen  = CCVAR("_shield_regen");
-
-    raptor_health_max    = CCVAR("_health");
-    raptor_health_regen  = CCVAR("_health_regen");
-
-    raptor_energy_max    = CCVAR("_energy");
-    raptor_energy_regen  = CCVAR("_energy_regen");
-}
 
-void raptor_bombs_return()
+void raptor_bomblet_boom()
 {
-    self.owner.bomb1.alpha = 1;
-    self.owner.bomb2.alpha = 1;
+    RadiusDamage (self, self.realowner, autocvar_g_vehicle_raptor_bomblet_damage,
+                                    autocvar_g_vehicle_raptor_bomblet_edgedamage,
+                                    autocvar_g_vehicle_raptor_bomblet_radius, world,
+                                    autocvar_g_vehicle_raptor_bomblet_force, DEATH_RAPTOR_BOMB, world);
     remove(self);
 }
 
-void raptor_bomblet_boom()
+void raptor_bomblet_touch()
 {
-    if(other.enemy == self.enemy)
+    if(other == self.owner)
         return;
 
-    pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
-    RadiusDamage (self, self.enemy, raptor_bomblet_damage, raptor_bomblet_edgedamage, raptor_bomblet_radius, world, raptor_bomblet_force, DEATH_SBROCKET, world);
-    remove(self);
+    PROJECTILE_TOUCH;
+    self.think = raptor_bomblet_boom;
+    self.nextthink = time + random() * autocvar_g_vehicle_raptor_bomblet_explode_delay;
 }
 
 void raptor_bomb_burst()
 {
-    self.angles = vectoangles(self.velocity);
-
-    if(self.cnt < time)
+    if(self.cnt > time)
+    if(autocvar_g_vehicle_raptor_bomblet_alt)
     {
-        entity bomblet;
-        float i,v;
-        vector d;
-
-        makevectors(self.angles);
-        v = vlen(self.velocity) + random();
-        d = normalize(self.velocity);
-        pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
-
-        for(i = 0; i < raptor_bomblets; ++i)
-        {
-
-            bomblet = spawn();
-            setorigin(bomblet,self.origin);
-
-            setmodel(bomblet,"models/vehicles/raptor_bomb.dpm");
-            bomblet.scale = 0.5;
-
-            bomblet.owner = self.owner;
-            bomblet.enemy = self.enemy;
-
-            bomblet.solid = SOLID_TRIGGER;
-            bomblet.movetype    = MOVETYPE_BOUNCE;
-            bomblet.touch = raptor_bomblet_boom;
-
-            bomblet.think = raptor_bomblet_boom;
-            bomblet.nextthink = time + 5;
-
-            //bomblet.modelflags = MF_ROCKET;
-            bomblet.modelflags = MF_GRENADE;
-
-            bomblet.velocity =  normalize(d + randomvec() * raptor_bomblet_wawespread) * v;
-
-            bomblet.angles = vectoangles(bomblet.velocity);
-        }
-
-        self.wait -= 1;
-        if(self.wait <= 0)
+        self.nextthink = time;
+        traceline(self.origin, self.origin + (normalize(self.velocity) * autocvar_g_vehicle_raptor_bomblet_alt), MOVE_NORMAL, self);
+        if((trace_fraction == 1.0) || (vlen(self.origin - self.owner.origin) < autocvar_g_vehicle_raptor_bomblet_radius))
         {
-            remove(self);
+            UpdateCSQCProjectile(self);
             return;
         }
+    }
+
+    entity bomblet;
+    float i;
 
-        self.cnt = time + raptor_bomblet_wavenext;
+    Damage_DamageInfo(self.origin, 0, 0, 0, '0 0 0', DEATH_RAPTOR_BOMB_SPLIT, self);
+
+    for(i = 0; i < autocvar_g_vehicle_raptor_bomblets; ++i)
+    {
+        bomblet = spawn();
+        setorigin(bomblet, self.origin);
+
+        bomblet.movetype    = MOVETYPE_TOSS;
+        bomblet.touch       = raptor_bomblet_touch;
+        bomblet.think       = raptor_bomblet_boom;
+        bomblet.nextthink   = time + 5;
+        bomblet.owner       = self.owner;
+        bomblet.realowner   = self.realowner;
+        bomblet.velocity    = normalize(normalize(self.velocity) + (randomvec() * autocvar_g_vehicle_raptor_bomblet_spread)) * vlen(self.velocity);
+
+        PROJECTILE_MAKETRIGGER(bomblet);
+        CSQCProjectile(bomblet, TRUE, PROJECTILE_RAPTORBOMBLET, TRUE);
     }
 
-    self.nextthink = time;
+    remove(self);
 }
 
 void raptor_bomb_touch()
@@ -175,492 +138,466 @@ void raptor_bombdrop()
 {
     entity bomb_1, bomb_2;
 
-    self.bomb1.alpha = 0.25;
-    self.bomb2.alpha = 0.25;
-
     bomb_1 = spawn();
     bomb_2 = spawn();
 
-    setmodel(bomb_1,"models/vehicles/raptor_bomb.dpm");
-    setmodel(bomb_2,"models/vehicles/raptor_bomb.dpm");
-
     setorigin(bomb_1, gettaginfo(self, gettagindex(self, "bombmount_left")));
     setorigin(bomb_2, gettaginfo(self, gettagindex(self, "bombmount_right")));
 
-    bomb_1.movetype  = bomb_2.movetype    = MOVETYPE_TOSS;
-    bomb_1.velocity  = bomb_2.velocity    = self.velocity;
-    bomb_1.touch     = bomb_2.touch       = raptor_bomb_touch;
-    bomb_1.think     = bomb_2.think       = raptor_bomb_burst;
-    bomb_1.nextthink = bomb_2.nextthink   = time;
-    bomb_1.cnt       = bomb_2.cnt         = time + raptor_bomblet_wavefirst;
-    bomb_1.wait       = bomb_2.wait       = raptor_bomblet_waves;
-
-    bomb_1.avelocity = bomb_2.avelocity   = '0 0 180';
-    bomb_1.owner     = bomb_2.owner       = self;
-    bomb_1.enemy     = bomb_2.enemy       = self.owner;
-    bomb_1.angles    = bomb_2.angles      = self.angles;
+    bomb_1.movetype     = bomb_2.movetype   = MOVETYPE_BOUNCE;
+    bomb_1.velocity     = bomb_2.velocity   = self.velocity;
+    bomb_1.touch        = bomb_2.touch      = raptor_bomb_touch;
+    bomb_1.think        = bomb_2.think      = raptor_bomb_burst;
+    bomb_1.cnt          = bomb_2.cnt        = time + 10;
+
+    if(autocvar_g_vehicle_raptor_bomblet_alt)
+        bomb_1.nextthink = bomb_2.nextthink  = time;
+    else
+        bomb_1.nextthink = bomb_2.nextthink  = time + autocvar_g_vehicle_raptor_bomblet_time;
+
+    bomb_1.owner     = bomb_2.owner      = self;
+    bomb_1.realowner = bomb_2.realowner  = self.owner;
     bomb_1.solid     = bomb_2.solid      = SOLID_BBOX;
+    bomb_1.gravity   = bomb_2.gravity    = 1;
+
+    PROJECTILE_MAKETRIGGER(bomb_1);
+    PROJECTILE_MAKETRIGGER(bomb_2);
+
+    CSQCProjectile(bomb_1, TRUE, PROJECTILE_RAPTORBOMB, TRUE);
+    CSQCProjectile(bomb_2, TRUE, PROJECTILE_RAPTORBOMB, TRUE);
 
-    bomb_1 = spawn();
-    bomb_1.owner = self;
-    bomb_1.think = raptor_bombs_return;
-    bomb_1.nextthink = time + raptor_bombs_refire;
 }
 
-void raptor_animator_think()
+
+void raptor_fire_cannon(entity gun, string tagname)
 {
-    self.owner.frame += 1;
-    if(self.owner.frame == self.cnt)
-        remove(self);
-    else
-        self.nextthink = time + self.wait;
+    entity bolt;
+    vector b_org;
+    b_org = gettaginfo(gun, gettagindex(gun, tagname));
+    bolt = vehicles_projectile("raptor_cannon_muzzleflash", "weapons/lasergun_fire.wav",
+                           b_org, normalize(v_forward + randomvec() * autocvar_g_vehicle_raptor_cannon_spread) * autocvar_g_vehicle_raptor_cannon_speed,
+                           autocvar_g_vehicle_raptor_cannon_damage, autocvar_g_vehicle_raptor_cannon_radius, autocvar_g_vehicle_raptor_cannon_force,  0,
+                           DEATH_RAPTOR_CANNON, PROJECTILE_RAPTORCANNON, 0, TRUE, TRUE);
 }
 
-void raptor_setanim(float start, float end, float length)
+void raptor_think()
 {
-    entity ani;
-    if(self.tur_head.enemy)
-        ani = self.tur_head.enemy;
-    else
-        ani = spawn();
-
-    self.tur_head.enemy = ani;
-    ani.owner = self;
-    self.frame = start;
-    ani.cnt = end;
-    ani.wait = sys_frametime / length;
-    ani.think = raptor_animator_think;
-    ani.nextthink = time + ani.wait;
 }
 
-void raptor_beam (vector start, vector end, vector smin, vector smax, float bforce, float f_dmg, float deathtype)
+void raptor_enter()
 {
-    vector hitloc, force, endpoint, dir;
-    entity ent;
+    self.owner.PlayerPhysplug = raptor_takeoff;
+    self.movetype       = MOVETYPE_BOUNCEMISSILE;
+    self.solid          = SOLID_SLIDEBOX;
+    self.owner.vehicle_health = (self.vehicle_health / autocvar_g_vehicle_raptor_health);
+    self.owner.vehicle_shield = (self.vehicle_shield / autocvar_g_vehicle_raptor_shield);
+    self.velocity_z = 1; // Nudge upwards to takeoff sequense can work.
+    self.tur_head.exteriormodeltoclient = self.owner;
 
-    dir = normalize(end - start);
-    force = dir * bforce;
+    self.delay = time + autocvar_g_vehicle_raptor_bombs_refire;
+    self.lip   = time;
 
-    // go a little bit into the wall because we need to hit this wall later
-    end = end + dir;
-
-    // trace multiple times until we hit a wall, each obstacle will be made unsolid.
-    // note down which entities were hit so we can damage them later
-    while (1)
-    {
-        tracebox(start, smin, smax, end, FALSE, world);
-
-        // if it is world we can't hurt it so stop now
-        if (trace_ent == world || trace_fraction == 1)
-            break;
-
-        if (trace_ent.solid == SOLID_BSP)
-            break;
-
-        // make the entity non-solid so we can hit the next one
-        trace_ent.railgunhit = TRUE;
-        trace_ent.railgunhitloc = end;
-        trace_ent.railgunhitsolidbackup = trace_ent.solid;
-
-        // make the entity non-solid
-        trace_ent.solid = SOLID_NOT;
-    }
-
-    endpoint = trace_endpos;
-
-    // find all the entities the railgun hit and hurt them
-    ent = findchainfloat(railgunhit, TRUE);
-    while (ent)
-    {
-        // get the details we need to call the damage function
-        ent.solid = ent.railgunhitsolidbackup;
-        hitloc = ent.railgunhitloc;
-        ent.railgunhitloc = '0 0 0';
-        ent.railgunhitsolidbackup = SOLID_NOT;
-        ent.railgunhit = FALSE;
-
-        // apply the damage
-        if (ent.takedamage)
-            Damage (ent, self, self, f_dmg, deathtype, hitloc, force);
-
-        ent = ent.chain;
-    }
-    trace_endpos = endpoint;
 }
 
-
-void raptor_enter()
+void raptor_land()
 {
-    // Remove this when bots know how to use vehicles
-    if (clienttype(other) != CLIENTTYPE_REAL)
-        return;
-
-    if(teams_matter)
-        if(self.team)
-            if(self.team != other.team)
-                return;
-
-    self.owner = other;
-    self.switchweapon = other.switchweapon;
-
-    self.event_damage          = vehicle_stdproc_damage;
-    self.colormap              = self.owner.colormap;
-    self.vehicle_hudmodel.viewmodelforclient = self.owner;
-    self.nextthink             = 0;
-    self.owner.angles          = self.angles;
-    self.owner.takedamage      = DAMAGE_NO;
-    self.owner.solid           = SOLID_NOT;
-    self.owner.movetype        = MOVETYPE_NOCLIP;
-    self.owner.alpha           = -1;
-    self.owner.PlayerPhysplug  = raptor_takeoff;
-    self.owner.vehicle         = self;
-    self.owner.event_damage    = SUB_Null;
-    self.owner.hud             = HUD_RAPTOR;
-    self.owner.vehicle_health  = self.vehicle_health / raptor_health_max;
-    self.owner.vehicle_shield  = self.vehicle_shield / raptor_shield_max;
-    self.owner.view_ofs        = '0 0 1';
-    self.owner.vehicle_ammo1   = self.vehicle_ammo1;
-    self.owner.vehicle_ammo2   = self.vehicle_ammo2;
-    self.owner.vehicle_reload1 = self.vehicle_reload1;
-    self.owner.vehicle_reload2 = self.vehicle_reload2;
-
-    other.flags &~= FL_ONGROUND;
-    self.flags &~= FL_ONGROUND;
-
-    self.frame = 0;
-    raptor_setanim(0, 25, 1);
+    float hgt;
 
-    self.team                 = self.owner.team;
-    self.flags               -= FL_NOTARGET;
+    hgt = raptor_altitude(512);
+    self.velocity = (self.velocity * 0.9) + ('0 0 -1800' * (hgt / 256) * sys_frametime);
+    self.angles_x *= 0.95;
+    self.angles_z *= 0.95;
 
-    self.velocity = '0 0 1';
+    if(hgt < 128)
+        if(self.frame != 0)
+            self.frame = max(self.frame - 0.25, 0);
 
-    setorigin(other,self.origin + '0 0 32');
-    other.velocity = self.velocity;
+    self.bomb1.gun1.avelocity_y = 90 + ((self.frame / 25) * 2000);
+    self.bomb1.gun2.avelocity_y = -self.bomb1.gun1.avelocity_y;
 
-    other.flags &~= FL_ONGROUND;
-    msg_entity = other;
-    WriteByte (MSG_ONE, SVC_SETVIEWPORT);
-    WriteEntity( MSG_ONE, self.vehicle_viewport);
+    if(hgt < 16)
+    {
+        self.movetype   = MOVETYPE_TOSS;
+        self.think      = raptor_think;
+    }
 
-    WriteByte (MSG_ONE, SVC_SETVIEWANGLES);     // 10 = SVC_SETVIEWANGLES
-    WriteAngle(MSG_ONE,  self.angles_x * -1);   // tilt
-    WriteAngle(MSG_ONE,  self.angles_y);        // yaw
-    WriteAngle(MSG_ONE,  0);                    // roll
+    self.nextthink  = time;
 }
 
 void raptor_exit(float eject)
 {
-       self.colormap   = 1024;
-       self.flags      = FL_NOTARGET;
-
-    if not (self.owner)
-        return;
-
-    msg_entity = self.owner;
-    WriteByte (MSG_ONE, SVC_SETVIEWPORT);
-    WriteEntity( MSG_ONE, self.owner);
-
-    WriteByte (MSG_ONE, SVC_SETVIEWANGLES);    // 10 = SVC_SETVIEWANGLES
-    WriteAngle(MSG_ONE,  0);                   // tilt
-    WriteAngle(MSG_ONE,  self.angles_y); // yaw
-    WriteAngle(MSG_ONE,  0);                   // roll
+    vector spot;
+    self.tur_head.exteriormodeltoclient = world;
 
-    if (self.deadflag == DEAD_NO)
+    if(self.deadflag == DEAD_NO)
     {
-        //self.think = racer_exitthink;
-        self.nextthink = time;
+        self.think      = raptor_land;
+        self.nextthink  = time;
     }
 
-    self.owner.takedamage     = DAMAGE_AIM;
-    self.owner.solid          = SOLID_SLIDEBOX;
-    self.owner.movetype       = MOVETYPE_WALK;
-
-    setsize(self.owner,PL_MIN,PL_MAX);
-
-    self.owner.effects        &~= EF_NODRAW;
-    self.owner.alpha          = 1;
-    self.owner.PlayerPhysplug = SUB_Null;
-    self.owner.vehicle        = world;
-       self.owner.view_ofs       = PL_VIEW_OFS;
-       self.owner.event_damage   = PlayerDamage;
-       self.owner.hud            = HUD_NORMAL;
-       //self.exteriormodeltoclient = self;
-
-    self.vehicle_hudmodel.viewmodelforclient = self;
+    if not (self.owner)
+        return;
 
+       makevectors(self.angles);
        if(eject)
        {
-           makevectors(self.angles);
-           setorigin(self.owner,self.origin + v_forward * 100);
+           spot = self.origin + v_forward * 100 + '0 0 64';
+           spot = vehicles_findgoodexit(spot);
+           setorigin(self.owner , spot);
            self.owner.velocity = (v_up + v_forward * 0.25) * 750;
        }
        else
        {
-           self.owner.velocity = (v_forward) * -150;
-        setorigin(self.owner,self.origin - v_forward * 128);
+           spot = self.origin - v_forward * 200 + '0 0 64';
+           spot = vehicles_findgoodexit(spot);
+           setorigin(self.owner , spot);
        }
-
+       
     self.owner = world;
+}
 
-    if (self.deadflag != DEAD_NO)
+float raptor_takeoff()
+{
+    entity player, raptor;
+    
+    player = self;
+    raptor = self.vehicle;
+    self   = raptor;
+    
+    if(self.sound_nexttime < time)
+    {        
+        self.sound_nexttime = time + 7.955812; //soundlength("vehicles/raptor_fly.wav");
+        sound (self, CHAN_TRIGGER, "vehicles/raptor_speed.wav", VOL_VEHICLEENGINE, ATTN_NORM);
+    }   
+
+    // Takeoff sequense
+    if(raptor.frame < 25)
     {
-        entity ret;
-        ret = spawn();
-        ret.enemy = self;
-        ret.think = raptor_return;
-        ret.nextthink = time + autocvar_g_vehicle_racer_respawntime;
+        raptor.frame += 0.25;
+        raptor.velocity_z = min(raptor.velocity_z * 1.5, 256);
+        self.bomb1.gun1.avelocity_y = 90 + ((raptor.frame / 25) * 25000);
+        self.bomb1.gun2.avelocity_y = -self.bomb1.gun1.avelocity_y;
+        player.BUTTON_ATCK = player.BUTTON_ATCK2 = player.BUTTON_CROUCH = 0;
+
+        setorigin(player, raptor.origin + '0 0 32');
     }
-}
+    else
+        player.PlayerPhysplug = raptor_frame;
 
+    if(self.vehicle_flags  & VHF_SHIELDREGEN)
+        vehicles_regen(dmg_time, vehicle_shield, autocvar_g_vehicle_raptor_shield, autocvar_g_vehicle_raptor_shield_regen_pause, autocvar_g_vehicle_raptor_shield_regen, frametime);
 
-float raptor_pplug()
-{
-    entity player, vhic;
-    float ftmp, ftmp2, energy_used;
-    vector df;
+    if(self.vehicle_flags  & VHF_HEALTHREGEN)
+        vehicles_regen(dmg_time, vehicle_health, autocvar_g_vehicle_raptor_health, autocvar_g_vehicle_raptor_health_regen_pause, autocvar_g_vehicle_raptor_health_regen, frametime);
 
+    if(self.vehicle_flags  & VHF_ENERGYREGEN)
+        vehicles_regen(cnt, vehicle_energy, autocvar_g_vehicle_raptor_energy, autocvar_g_vehicle_raptor_energy_regen_pause, autocvar_g_vehicle_raptor_energy_regen, frametime);
 
-    if(autocvar_g_vehicle_raptor_reload)
-    {
-        raptor_loadsettings();
-        cvar_set("g_vehicle_raptor_reload","0");
-    }
 
-    player = self;
-    vhic   = self.vehicle;
-    self    = vhic;
+    raptor.bomb1.alpha = raptor.bomb2.alpha = (time - raptor.lip) / (raptor.delay - raptor.lip);
+    player.vehicle_reload2 = bound(0, raptor.bomb1.alpha * 100, 100);
+
+    VEHICLE_UPDATE_PLAYER(health, raptor);
+    VEHICLE_UPDATE_PLAYER(energy, raptor);
+    if(self.vehicle_flags & VHF_HASSHIELD)
+        VEHICLE_UPDATE_PLAYER(shield, raptor);
+
+    player.BUTTON_ATCK = player.BUTTON_ATCK2 = player.BUTTON_CROUCH = 0;
+    self = player;
+    return 1;
+}
+
+float raptor_frame()
+{
+    entity player, raptor;
+    float ftmp, ftmp2;
+    vector df, ra;
 
-    if(player.BUTTON_USE)
+    player = self;
+    raptor = self.vehicle;
+    self   = raptor;
+        
+    /*
+    ftmp = vlen(self.velocity);
+    if(ftmp > autocvar_g_vehicle_raptor_speed_forward) 
+        ftmp = 1;
+    else  
+        ftmp = ftmp / autocvar_g_vehicle_raptor_speed_forward;
+    */
+        
+    if(self.sound_nexttime < time)
+    {        
+        self.sound_nexttime = time + 7.955812; 
+        //sound (self.tur_head, CHAN_TRIGGER, "vehicles/raptor_fly.wav", 1 - ftmp,   ATTN_NORM );
+        sound (self, CHAN_TRIGGER, "vehicles/raptor_speed.wav", 1, ATTN_NORM);        
+        self.wait = ftmp;
+    }        
+    /*
+    else if(fabs(ftmp - self.wait) > 0.2)
     {
-        self = vhic;
-        raptor_exit(0);
+        sound (self.tur_head, CHAN_TRIGGER, "", 1 - ftmp,   ATTN_NORM );
+        sound (self, CHAN_TRIGGER, "", ftmp, ATTN_NORM);        
+        self.wait = ftmp;
+    }
+    */
+    
+    if(player.BUTTON_USE && raptor.deadflag == DEAD_NO)
+    {
+        self = raptor;
+        vehicles_exit(VHEF_NORMAL);
         self = player;
         return 0;
     }
 
-    if(vhic.deadflag != DEAD_NO)
+    if(raptor.deadflag != DEAD_NO)
     {
         self = player;
         player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0;
         return 1;
     }
+    crosshair_trace(player);
 
-    vhic.angles_x *= -1;
-    // Rotate Body
-    ftmp = raptor_turnspeed * sys_frametime;
 
-    ftmp = bound(-ftmp, shortangle_f(player.v_angle_y - vhic.angles_y, vhic.angles_y), ftmp);
+    vector vang;
+    vang = raptor.angles;
+    df = vectoangles(normalize(trace_endpos - self.origin + '0 0 32'));
+    vang_x *= -1;
+    df_x *= -1;
+    if(df_x > 180)  df_x -= 360;
+    if(df_x < -180) df_x += 360;
+    if(df_y > 180)  df_y -= 360;
+    if(df_y < -180) df_y += 360;
 
-    // Roll
-    //ftmp = bound(-90,shortangle_f(player.v_angle_z + ((vhic.angles_y - ftmp2) * raptor_turnroll), vhic.angles_z),90);
-    //ftmp = safeangle(vhic.angles_z + ftmp);
-    //vhic.angles_z = ftmp;
+    ftmp = shortangle_f(player.v_angle_y - vang_y, vang_y);
+    if(ftmp > 180)  ftmp -= 360; if(ftmp < -180) ftmp += 360;
+    raptor.avelocity_y = bound(-autocvar_g_vehicle_raptor_turnspeed, ftmp + raptor.avelocity_y * 0.9, autocvar_g_vehicle_raptor_turnspeed);
 
-    // Turn
-    vhic.angles_y = anglemods(vhic.angles_y + ftmp);
+    // Pitch
+    ftmp = 0;
+    if(player.movement_x > 0 && vang_x < autocvar_g_vehicle_raptor_pitchlimit) ftmp = 5;
+    else if(player.movement_x < 0 && vang_x > -autocvar_g_vehicle_raptor_pitchlimit) ftmp = -20;
 
-    // Pitch Body
-    ftmp = raptor_pitchspeed  * sys_frametime;
+    df_x = bound(-autocvar_g_vehicle_raptor_pitchlimit, df_x , autocvar_g_vehicle_raptor_pitchlimit);
+    ftmp = vang_x - bound(-autocvar_g_vehicle_raptor_pitchlimit, df_x + ftmp, autocvar_g_vehicle_raptor_pitchlimit);
+    raptor.avelocity_x = bound(-autocvar_g_vehicle_raptor_pitchspeed, ftmp + raptor.avelocity_x * 0.9, autocvar_g_vehicle_raptor_pitchspeed);
 
-    ftmp = bound(-ftmp, shortangle_f(player.v_angle_x - vhic.angles_x,vhic.angles_x), ftmp);
+    raptor.angles_x = anglemods(raptor.angles_x);
+    raptor.angles_y = anglemods(raptor.angles_y);
+    raptor.angles_z = anglemods(raptor.angles_z);
 
-    vhic.angles_x = bound(-60,anglemods(vhic.angles_x + ftmp),60);
-    vhic.angles_x *= -1;
 
-    if(raptor_movestyle == 1)
-    {
-        ftmp = vhic.angles_z;
-        vhic.angles_z = 0;
-        ftmp2 = vhic.angles_x;
-        vhic.angles_x = 0;
-        fixedmakevectors(vhic.angles);
-        vhic.angles_z = ftmp;
-        vhic.angles_x = ftmp2;
-    }
+    if(autocvar_g_vehicle_raptor_movestyle == 1)
+        makevectors('0 1 0' * raptor.angles_y);
     else
-        fixedmakevectors(vhic.angles);
+        makevectors(player.v_angle);
 
-    df = vhic.velocity * -1;
+    df = raptor.velocity * -autocvar_g_vehicle_raptor_friction;
 
     if(player.movement_x != 0)
     {
         if(player.movement_x > 0)
-            df += v_forward  * raptor_speed_forward;
+            df += v_forward  * autocvar_g_vehicle_raptor_speed_forward;
         else if(player.movement_x < 0)
-            df -= v_forward  * raptor_speed_forward;
+            df -= v_forward  * autocvar_g_vehicle_raptor_speed_forward;
     }
 
     if(player.movement_y != 0)
     {
         if(player.movement_y < 0)
-            df -= v_right * raptor_speed_strafe;
+            df -= v_right * autocvar_g_vehicle_raptor_speed_strafe;
         else if(player.movement_y > 0)
-            df += v_right * raptor_speed_strafe;
+            df += v_right * autocvar_g_vehicle_raptor_speed_strafe;
 
-        vhic.angles_z = bound(-30,vhic.angles_z + (player.movement_y / raptor_speed_strafe),30);
+        raptor.angles_z = bound(-30,raptor.angles_z + (player.movement_y / autocvar_g_vehicle_raptor_speed_strafe),30);
     }
     else
     {
-        vhic.angles_z *= 0.95;
-        if(vhic.angles_z >= -1 && vhic.angles_z <= -1)
-            vhic.angles_z = 0;
+        raptor.angles_z *= 0.95;
+        if(raptor.angles_z >= -1 && raptor.angles_z <= -1)
+            raptor.angles_z = 0;
     }
 
     if(player.BUTTON_CROUCH)
-        df -=   v_up * raptor_speed_down;
+        df -=   v_up * autocvar_g_vehicle_raptor_speed_down;
     else if (player.BUTTON_JUMP)
-        df +=  v_up * raptor_speed_up;
-    //else
-        //df_z = vhic.velocity_z * -1;
+        df +=  v_up * autocvar_g_vehicle_raptor_speed_up;
 
-    vhic.velocity  += df * frametime;
-    player.velocity = player.movement  = vhic.velocity;
-    setorigin(player,vhic.origin + '0 0 32');
+    raptor.velocity  += df * frametime;
+    //player.velocity = raptor.velocity;
+    player.velocity = player.movement  = raptor.velocity;
+    setorigin(player, raptor.origin + '0 0 32');
 
-    // Aim the gunz
-    /*
-    vector target_angle, move_angle, org1, org2, targ;
-
-    makevectors(player.v_angle);
-
-    //targ = (vhic.origin + player.view_ofs) + v_forward * MAX_SHOT_DISTANCE;
-    targ = player.cursor_trace_endpos;
-
-    org1 = gettaginfo(vhic.gun1,gettagindex(vhic.gun1, "fire1"));
-    org2 = gettaginfo(vhic.gun2,gettagindex(vhic.gun2, "fire1"));
+    vector vf, ad;
+    // Target lock & predict
+    if(autocvar_g_vehicle_raptor_cannon_locktarget)
+    {
 
-    traceline(vhic.origin + player.view_ofs, targ, FALSE, vhic);
-    targ = trace_endpos;
+        vehicles_locktarget((1 / autocvar_g_vehicle_raptor_cannon_locking_time) * frametime,
+                             (1 / autocvar_g_vehicle_raptor_cannon_locking_releasetime) * frametime,
+                             autocvar_g_vehicle_raptor_cannon_locked_time);
 
-    // Find the direction
-    target_angle = vectoangles(normalize(targ - org1)); // And make a angle
+        if(self.lock_target != world)
+        if(autocvar_g_vehicle_raptor_cannon_predicttarget)
+        if(self.lock_strength == 1)
+        {
+            float i, distance, impact_time;
+
+            vf = real_origin(raptor.lock_target);
+            ad = vf;
+            for(i = 0; i < 4; ++i)
+            {
+                distance = vlen(ad - raptor.origin);
+                impact_time = distance / autocvar_g_vehicle_raptor_cannon_speed;
+                ad = vf + raptor.lock_target.velocity * impact_time;
+            }
+            trace_endpos = ad;
+            //UpdateAuxiliaryXhair(player, trace_endpos, '1 1 1', 0);
+        }
 
-    // Find the diffrence between where we currently aim and where we want to aim
-    move_angle = target_angle - (vhic.angles + vhic.gun1.angles);
-    move_angle = shortangle_vxy(move_angle,(vhic.angles + vhic.gun1.angles));
-    vhic.gun1.angles_x = bound(-10, move_angle_x + vhic.gun1.angles_x, 10);
-    vhic.gun1.angles_y = bound(-15, move_angle_y + vhic.gun1.angles_y, 15);
+        if(self.lock_target)
+        {
+            if(raptor.lock_strength == 1)
+                UpdateAuxiliaryXhair(player, real_origin(raptor.lock_target), '1 0 0', 1);
+            else if(self.lock_strength > 0.5)
+                UpdateAuxiliaryXhair(player, real_origin(raptor.lock_target), '0 1 0', 1);
+            else if(self.lock_strength < 0.5)
+                UpdateAuxiliaryXhair(player, real_origin(raptor.lock_target), '0 0 1', 1);
+        }
+    }
 
-    // Find the direction
-    target_angle = vectoangles(normalize(targ - org2)); // And make a angle
+    ra = raptor.angles;
+    ra_z = 0;
+    // Aim the gunz
+    ftmp2 = autocvar_g_vehicle_raptor_cannon_turnspeed * frametime;
+    ftmp = -ftmp2;
+
+    // Gun1
+    df = gettaginfo(raptor.gun1, gettagindex(raptor.gun1, "fire1"));
+    ad = df;
+    vf = v_forward;
+    //if(self.lock_strength == 1)
+    //{
+        df = vectoangles(normalize(trace_endpos - df)); // Find the direction & angle
+        df = shortangle_vxy(df - (ra + raptor.gun1.angles), ra + raptor.gun1.angles);     // Find aim offset        
+    //}
+    //else    
+    //    df = '0 0 0';
+        
+    // Bind to aimspeed
+    df_x = bound(ftmp, df_x, ftmp2);
+    df_y = bound(ftmp, df_y, ftmp2);
+    // Bind to limts
+    raptor.gun1.angles_x = bound(-autocvar_g_vehicle_raptor_cannon_pitchlimit_down, df_x + raptor.gun1.angles_x, autocvar_g_vehicle_raptor_cannon_pitchlimit_up);
+    raptor.gun1.angles_y = bound(-autocvar_g_vehicle_raptor_cannon_turnlimit,  df_y + raptor.gun1.angles_y, autocvar_g_vehicle_raptor_cannon_turnlimit);
+
+    // Gun2
+    df = gettaginfo(raptor.gun2, gettagindex(raptor.gun2, "fire1"));
+    ad += df;
+    vf += v_forward;
+    //if(self.lock_strength == 1)
+    //{
+        df = vectoangles(normalize(trace_endpos - df)); // Find the direction & angle
+        df = shortangle_vxy(df - (ra + raptor.gun2.angles), ra + raptor.gun2.angles);     // Find aim offset        
+    //}
+    //else    
+    //    df = '0 0 0';
+        
+    // Bind to aimspeed
+    df_x = bound(ftmp, df_x, ftmp2);
+    df_y = bound(ftmp, df_y, ftmp2);
+    // Bind to limts
+    raptor.gun2.angles_x = bound(-autocvar_g_vehicle_raptor_cannon_pitchlimit_down, df_x + raptor.gun2.angles_x, autocvar_g_vehicle_raptor_cannon_pitchlimit_up);
+    raptor.gun2.angles_y = bound(-autocvar_g_vehicle_raptor_cannon_turnlimit,  df_y + raptor.gun2.angles_y, autocvar_g_vehicle_raptor_cannon_turnlimit);
 
-    move_angle = target_angle - (vhic.angles + vhic.gun2.angles);
-    move_angle = shortangle_vxy(move_angle,(vhic.angles + vhic.gun2.angles));
-    vhic.gun2.angles_x = bound(-15,move_angle_x + vhic.gun2.angles_x,15);
-    vhic.gun2.angles_y = bound(-20,move_angle_y + vhic.gun2.angles_y,20);
-       */
+    /*
+    ad = ad * 0.5;
+    v_forward = vf * 0.5;
+    traceline(ad, ad + v_forward * MAX_SHOT_DISTANCE, MOVE_NORMAL, raptor);
+    UpdateAuxiliaryXhair(player, trace_endpos, '0 1 0', 0);
+    */
+    
     if(player.BUTTON_ATCK)
-    if(vhic.vehicle_energy > (raptor_beam_aps * sys_frametime))
+    if(raptor.attack_finished_single <= time)
+    if(raptor.vehicle_energy > autocvar_g_vehicle_raptor_cannon_cost)
     {
-        vector start;
-        self = player;
-
-        start = gettaginfo(vhic.gun1, gettagindex(vhic.gun1, "fire1"));
-        traceline(start, start + v_forward * MAX_SHOT_DISTANCE, TRUE, player);
-        te_lightning1(vhic.gun1, start, trace_endpos);
-        raptor_beam(start, trace_endpos, '-1 -1 -1' * raptor_beam_size, '1 1 1' * raptor_beam_size, raptor_beam_fops * sys_frametime, raptor_beam_dps * sys_frametime, DEATH_SBROCKET);
-
-
-        start = gettaginfo(vhic.gun2, gettagindex(vhic.gun2, "fire1"));
-        traceline(start, start + v_forward * MAX_SHOT_DISTANCE, TRUE, player);
-        te_lightning1(vhic.gun2, start, trace_endpos);
-        raptor_beam(start, trace_endpos, '-1 -1 -1' * raptor_beam_size, '1 1 1' * raptor_beam_size, raptor_beam_fops * sys_frametime, raptor_beam_dps * sys_frametime, DEATH_SBROCKET);
-
-        self = vhic;
-
-        vhic.vehicle_energy -= raptor_beam_aps * sys_frametime;
-        vhic.cnt = time + 1;
+        raptor.misc_bulletcounter += 1;
+        raptor.attack_finished_single = time + autocvar_g_vehicle_raptor_cannon_refire;
+        if(raptor.misc_bulletcounter <= 2)
+            raptor_fire_cannon(self.gun1, "fire1");
+        else if(raptor.misc_bulletcounter == 3)
+            raptor_fire_cannon(self.gun2, "fire1");
+        else
+        {
+            raptor.attack_finished_single = time + autocvar_g_vehicle_raptor_cannon_refire * 2;
+            raptor_fire_cannon(self.gun2, "fire1");
+            raptor.misc_bulletcounter = 0;
+        }
+        raptor.vehicle_energy -= autocvar_g_vehicle_raptor_cannon_cost;
+        self.cnt = time;
     }
 
-    if(vhic.cnt < time)
-        vhic.vehicle_energy = min(vhic.vehicle_energy += raptor_energy_regen * frametime, raptor_energy_max);
+    if(self.vehicle_flags  & VHF_SHIELDREGEN)
+        vehicles_regen(dmg_time, vehicle_shield, autocvar_g_vehicle_raptor_shield, autocvar_g_vehicle_raptor_shield_regen_pause, autocvar_g_vehicle_raptor_shield_regen, frametime);
 
-    player.vehicle_energy = vhic.vehicle_energy / raptor_energy_max;
+    if(self.vehicle_flags  & VHF_HEALTHREGEN)
+        vehicles_regen(dmg_time, vehicle_health, autocvar_g_vehicle_raptor_health, autocvar_g_vehicle_raptor_health_regen_pause, autocvar_g_vehicle_raptor_health_regen, frametime);
 
+    if(self.vehicle_flags  & VHF_ENERGYREGEN)
+        vehicles_regen(cnt, vehicle_energy, autocvar_g_vehicle_raptor_energy, autocvar_g_vehicle_raptor_energy_regen_pause, autocvar_g_vehicle_raptor_energy_regen, frametime);
 
+
+    if(time > raptor.delay)
     if(player.BUTTON_ATCK2)
-    if(time > vhic.delay)
     {
         raptor_bombdrop();
-        vhic.delay = time + raptor_bombs_refire;
+        raptor.delay = time + autocvar_g_vehicle_raptor_bombs_refire;
+        raptor.lip   = time;
     }
 
-    player.BUTTON_ATCK = player.BUTTON_ATCK2 = player.BUTTON_CROUCH = 0;
-    vehicle_stdproc_shiledregen(raptor_shield_max, frametime);
-    vehicle_stdproc_healthregen(raptor_health_max, frametime);
+    raptor.bomb1.alpha = raptor.bomb2.alpha = (time - raptor.lip) / (raptor.delay - raptor.lip);
+    player.vehicle_reload2 = bound(0, raptor.bomb1.alpha * 100, 100);
 
-    self = player;
+    VEHICLE_UPDATE_PLAYER(health, raptor);
+    VEHICLE_UPDATE_PLAYER(energy, raptor);
+    if(self.vehicle_flags & VHF_HASSHIELD)
+        VEHICLE_UPDATE_PLAYER(shield, raptor);
 
+    player.BUTTON_ATCK = player.BUTTON_ATCK2 = player.BUTTON_CROUCH = 0;
     return 1;
 }
 
-float raptor_takeoff()
+void raptor_blowup()
 {
-    entity player, vhic;
-
-    if(self.vehicle.frame < 25)
-        return 1;
-
-    player = self;
-    vhic   = self.vehicle;
-    self    = vhic;
-
-    if(raptor_altitude(512) <= 256)
-    {
-        vhic.velocity_z = min(vhic.velocity_z * 1.5, 256);
-    }
-    else
-    {
-        player.PlayerPhysplug = raptor_pplug;
-    }
+    sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
+    pointparticles(particleeffectnum("explosion_big"), self.origin, '0 0 0', 1);
 
-    player.BUTTON_CROUCH = player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0;
-    self = player;
+    self.deadflag    = DEAD_DEAD;
+    self.vehicle_exit(VHEF_NORMAL);
+    RadiusDamage (self, self, 250, 15, 250, world, 250, DEATH_WAKIBLOWUP, world);
 
-    return 1;
-}
-
-float raptor_land()
-{
-    return 0;
-}
+    self.alpha          = -1;
+    self.movetype       = MOVETYPE_NONE;
+    self.effects        = EF_NODRAW;
+    self.colormod       = '0 0 0';
+    self.avelocity      = '0 0 0';
+    self.velocity       = '0 0 0';
 
-void raptor_return()
-{
-    pointparticles(particleeffectnum("teleport"), self.enemy.origin + '0 0 64', '0 0 0', 1);
-    self.enemy.think = raptor_spawn;
-    self.enemy.nextthink = time;
-    remove(self);
+    setorigin(self, self.pos1);
+    self.touch = SUB_Null;
+    self.nextthink = 0;
 }
 
-void raptor_think()
+void raptor_diethink()
 {
-}
+    //self.avelocity += '0 0.5 1' * (random() * 5);
+    //self.avelocity -= '0 0.5 1' * (random() * 5);
 
-void raptor_touch()
-{
-    if(self.owner)
+    if(random() < 0.1)
     {
-        if(vlen(self.velocity) == 0)
-            return;
-
-        if(other.classname != "player")
-            return;
-
-        return;
+        sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
+        pointparticles(particleeffectnum("explosion_small"), randomvec() * 80 + (self.origin + '0 0 100'), '0 0 0', 1);
     }
-
-    if(other.classname != "player")
-        return;
-
-    if(other.deadflag != DEAD_NO)
-        return;
-
-    if(other.vehicle != world)
-        return;
-
-    raptor_enter();
+    self.nextthink = time + 0.1;
 }
 
 void raptor_die()
@@ -668,148 +605,120 @@ void raptor_die()
     self.health       = 0;
     self.event_damage = SUB_Null;
     self.iscreature   = FALSE;
-    self.solid        = SOLID_NOT;
+    self.solid        = SOLID_CORPSE;
     self.takedamage   = DAMAGE_NO;
-    //self.touch        = racer_dietouch;
     self.deadflag     = DEAD_DYING;
     self.movetype     = MOVETYPE_BOUNCE;
-    self.wait = time;
-
-    pointparticles(particleeffectnum("rocket_explode"), findbetterlocation (self.origin, 16), '0 0 0', 1);
+    self.think        = raptor_diethink;
+    self.nextthink    = time;
+    
+    pointparticles(particleeffectnum("explosion_medium"), findbetterlocation (self.origin, 16), '0 0 0', 1);
 
-    self.velocity     += '0 0 128';
+    self.velocity_z += 600;
 
-    if(random() < 0.5)
-        self.avelocity_z  = 45;
-    else
-        self.avelocity_z  = -45;
+    self.avelocity = '0 0.5 1' * (random() * 400);
+    self.avelocity -= '0 0.5 1' * (random() * 400);
 
     self.colormod = '-0.5 -0.5 -0.5';
-
-       self.think     = raptor_spawn;
-       self.nextthink = time + 5;
+       self.touch     = raptor_blowup;
 }
 
 void raptor_spawn()
 {
-    self.flags     = FL_NOTARGET;
-    self.effects   = 0;
-
-    self.vehicle_health = raptor_health_max;
-    self.vehicle_shield = raptor_shield_max;
-
-    self.event_damage = vehicle_stdproc_damage;
-    self.touch      = raptor_touch;
-
-    self.iscreature = TRUE;
-    self.movetype   = MOVETYPE_FLY;
-    self.solid      = SOLID_SLIDEBOX;
-    self.takedamage = DAMAGE_AIM;
-
-    self.alpha = 1;
-       self.colormap = 1024;
-       self.deadflag    = DEAD_NO;
-    self.bot_attack = TRUE;
-
-    self.colormod = '1 1 1';
-    self.avelocity = '0 0 0';
-    self.velocity = '0 0 0';
-
+    self.frame          = 0;
+    self.vehicle_health = autocvar_g_vehicle_raptor_health;
+    self.vehicle_shield = autocvar_g_vehicle_raptor_shield;
+    self.movetype       = MOVETYPE_TOSS;
+    self.solid          = SOLID_SLIDEBOX;
     self.vehicle_energy = 1;
-    self.vehicle_hudmodel.viewmodelforclient = self;
 
-    setorigin(self, self.pos1);
-    self.angles = self.pos2;
+    self.bomb1.gun1.avelocity_y = 90;
+    self.bomb1.gun2.avelocity_y = -90;
 
-    setsize(self,RAPTOR_MIN ,RAPTOR_MAX );
-    pointparticles(particleeffectnum("teleport"), self.origin + '0 0 64', '0 0 0', 1);
+    setsize(self, RAPTOR_MIN, RAPTOR_MAX );
     self.delay = time;
 }
 
-float raptor_customizeentityforclient()
+// If we dont do this ever now and then, the raptors rotors
+// stop working, presumably due to angle overflow. cute.
+void raptor_rotor_anglefix()
 {
-    if(self.deadflag == DEAD_DEAD)
-        return FALSE;
-
-    /*
-    if(other == self.owner)
-        self.alpha = -1;
-    else
-        self.alpha = 1;
-    */
-
-    return TRUE;
+    self.gun1.angles_y = anglemods(self.gun1.angles_y);
+    self.gun2.angles_y = anglemods(self.gun2.angles_y);
+    self.nextthink = time + 15;
 }
 
 void raptor_dinit()
 {
+    entity spinner;
+    vector ofs;
+
+    if not (vehicle_initialize(
+             "Raptor",
+             "models/vehicles/raptor.dpm",
+             "",
+             "models/vehicles/raptor_cockpit.dpm",
+             "", "tag_hud", "tag_camera",
+             HUD_RAPTOR,
+             RAPTOR_MIN, RAPTOR_MAX,
+             FALSE,
+             raptor_spawn, autocvar_g_vehicle_raptor_respawntime,
+             raptor_frame,
+             raptor_enter, raptor_exit,
+             raptor_die,   raptor_think,
+             FALSE))
+    {
+        remove(self);
+        return;
+    }
 
-    if (self.netname == "")
-        self.netname     = "Raptor";
-
-    setorigin(self, self.origin);
+    //FIXME: Camera is in a bad place in HUD model.
+    //setorigin(self.vehicle_viewport, '25 0 5');
 
     self.frame = 0;
 
-    setmodel(self,"models/vehicles/raptor.dpm");
-
     self.bomb1 = spawn();
     self.bomb2 = spawn();
+    self.gun1  = spawn();
+    self.gun2  = spawn();
 
-    setmodel(self.bomb1,"models/vehicles/raptor_bomb.dpm");
-    setmodel(self.bomb2,"models/vehicles/raptor_bomb.dpm");
+    setmodel(self.bomb1,"models/vehicles/clusterbomb_folded.md3");
+    setmodel(self.bomb2,"models/vehicles/clusterbomb_folded.md3");
+    setmodel(self.gun1, "models/vehicles/raptor_gun.dpm");
+    setmodel(self.gun2, "models/vehicles/raptor_gun.dpm");
+    setmodel(self.tur_head, "models/vehicles/raptor_body.dpm");
 
     setattachment(self.bomb1, self,"bombmount_left");
     setattachment(self.bomb2, self,"bombmount_right");
+    setattachment(self.tur_head, self,"root");
 
 
-    if not (self.vehicle_hudmodel)
-    {
-        self.vehicle_hudmodel   = spawn();
-        setmodel(self.vehicle_hudmodel, "models/vehicles/raptor_cockpit.dpm");
-        //setattachment(self.vehicle_hudmodel, self, "tag_viewport");
-        setattachment(self.vehicle_hudmodel, self, "tag_hud");
-    }
-
-    if not (self.vehicle_viewport)
-    {
-        self.vehicle_viewport   = spawn();
-        setmodel (self.vehicle_viewport, "null");
-        setattachment(self.vehicle_viewport, self.vehicle_hudmodel, "tag_camera");
-    }
-
-    if not (self.gun1)
-    {
-        self.gun1   = spawn();
-        setmodel(self.gun1, "models/vehicles/raptor_gun.dpm");
-        setattachment(self.gun1, self, "gunmount_left");
-    }
-
-    if not (self.gun2)
-    {
-        self.gun2   = spawn();
-        setmodel(self.gun2, "models/vehicles/raptor_gun.dpm");
-        setattachment(self.gun2, self, "gunmount_right");
-    }
-
-    self.tur_head     = spawn();
-    self.pos1         = self.origin;
-    self.pos2         = self.angles;
-
-    self.vehicle_hudmodel.viewmodelforclient = self;
-    self.customizeentityforclient            = raptor_customizeentityforclient;
+    // FIXME Guns mounts to angled bones
+    self.bomb1.angles = self.angles;
+    self.angles = '0 0 0';
+    // This messes up gun-aim, so work arround it.
+    //setattachment(self.gun1, self, "gunmount_left");
+    ofs = gettaginfo(self, gettagindex(self, "gunmount_left"));
+    ofs -= self.origin;
+    setattachment(self.gun1, self, "");
+    setorigin(self.gun1, ofs);
 
-    self.vehicle_die  = raptor_die;
-    self.vehicle_exit = raptor_exit;
+    //setattachment(self.gun2, self, "gunmount_right");
+    ofs = gettaginfo(self, gettagindex(self, "gunmount_right"));
+    ofs -= self.origin;
+    setattachment(self.gun2, self, "");
+    setorigin(self.gun2, ofs);
 
+    self.angles = self.bomb1.angles;
+    self.bomb1.angles = '0 0 0';
 
-    entity spinner;
     spinner = spawn();
     spinner.owner = self;
     setmodel(spinner,"models/vehicles/spinner.dpm");
     setattachment(spinner, self, "engine_left");
     spinner.movetype = MOVETYPE_NOCLIP;
     spinner.avelocity = '0 90 0';
+    self.bomb1.gun1 = spinner;
 
     spinner = spawn();
     spinner.owner = self;
@@ -817,76 +726,44 @@ void raptor_dinit()
     setattachment(spinner, self, "engine_right");
     spinner.movetype = MOVETYPE_NOCLIP;
     spinner.avelocity = '0 -90 0';
+    self.bomb1.gun2 = spinner;
 
-    addstat(STAT_HUD, AS_INT,  hud);
-       addstat(STAT_VEHICLESTAT_HEALTH,  AS_FLOAT, vehicle_health);
-       addstat(STAT_VEHICLESTAT_SHIELD,  AS_FLOAT, vehicle_shield);
-       addstat(STAT_VEHICLESTAT_ENERGY,  AS_FLOAT, vehicle_energy);
-
-       addstat(STAT_VEHICLESTAT_AMMO1,   AS_INT,   vehicle_ammo1);
-       addstat(STAT_VEHICLESTAT_RELOAD1, AS_FLOAT, vehicle_reload1);
-
-       addstat(STAT_VEHICLESTAT_AMMO2,   AS_INT,   vehicle_ammo2);
-       addstat(STAT_VEHICLESTAT_RELOAD2, AS_FLOAT, vehicle_reload2);
+    // Sigh.
+    self.bomb1.think = raptor_rotor_anglefix;
+    self.bomb1.nextthink = time;
 
-    raptor_spawn();
+    self.mass               = 1 ;
 }
 
 void spawnfunc_vehicle_raptor()
 {
-    self.cvar_basename      = "g_vehicle_raptor";
-    raptor_loadsettings();
+    vehicles_configcheck("vehicle_raptor.cfg", autocvar_g_vehicle_raptor_health);
+    
+    if(autocvar_g_vehicle_raptor_shield)
+        self.vehicle_flags |= VHF_HASSHIELD;
 
-    self.vehicle_flags      = VHF_HASSHIELD | VHF_SHIELDREGEN;
+    if(autocvar_g_vehicle_raptor_shield_regen)
+        self.vehicle_flags |= VHF_SHIELDREGEN;
 
-    traceline(self.origin, self.origin - '0 0 2048', MOVE_WORLDONLY, self);
-    if(trace_startsolid)
-    {
-        dprint("WARNING: vehicle_raptor placed in solid\n");
-        traceline(self.origin + '0 0 512' ,self.origin - '0 0 2048',MOVE_WORLDONLY,self);
-        if(trace_startsolid || trace_fraction == 1.0)
-        {
-            dprint("ERROR: vehicle_raptor placed in more then 512 units into solid\n");
-            remove(self);
-            return;
-        }
-    }
+    if(autocvar_g_vehicle_raptor_health_regen)
+        self.vehicle_flags |= VHF_HEALTHREGEN;
 
-    if(trace_fraction != 1.0)
-        setorigin(self,trace_endpos + '0 0 8');
-    else
-        dprint("WARNING: vehicle_racer placed more then 2048 units above ground.\n");
+    if(autocvar_g_vehicle_raptor_energy_regen)
+        self.vehicle_flags |= VHF_ENERGYREGEN;
 
     precache_model ("models/vehicles/raptor.dpm");
     precache_model ("models/vehicles/raptor_gun.dpm");
     precache_model ("models/vehicles/spinner.dpm");
     precache_model ("models/vehicles/raptor_cockpit.dpm");
-    precache_model ("models/vehicles/raptor_bomb.dpm");
-
-
+    precache_model ("models/vehicles/clusterbomb.md3");
+    precache_model ("models/vehicles/clusterbomb_folded.md3");
+    precache_model ("models/vehicles/raptor_body.dpm");
+    
+    precache_sound ("vehicles/raptor_fly.wav");
+    precache_sound ("vehicles/raptor_speed.wav");
+    precache_sound ("");
+    
     self.think = raptor_dinit;
-    self.nextthink = time + 1;
-}
-
-
-void spawnfunc_vehicle_raptor2()
-{
-    entity iqm,dpm,md3;
-
-    precache_model ("models/vehicles/test.iqm");
-    precache_model ("models/vehicles/test.dpm");
-    precache_model ("models/vehicles/test.md3");
-
-    iqm = spawn();
-    dpm = spawn();
-    md3 = spawn();
-    iqm.scale = md3.scale = dpm.scale = 10;
-
-    //setmodel(iqm,"models/vehicles/test.iqm");
-    //setmodel(dpm,"models/vehicles/test.dpm");
-    setmodel(md3,"models/vehicles/test.md3");
-
-    setorigin(iqm, self.origin + '0 0 16');
-    setorigin(dpm, self.origin + '0 20 32');
-    setorigin(iqm, self.origin + '0 40 48');
+    self.nextthink = time + (autocvar_g_vehicles_delayspawn ? autocvar_g_vehicle_raptor_respawntime + (random() * autocvar_g_vehicles_delayspawn_jitter) : 0.5);
 }
+#endif // SVQC
index 6743f73..0f217f9 100644 (file)
@@ -1,71 +1,74 @@
-const vector spiderbot_MIN = '-75 -75 0';
-const vector spiderbot_MAX  = '75 75 100';
-
-#define spiderbot_spawnpnt wkr_spawn
+const vector SPIDERBOT_MIN = '-75 -75 10';
+const vector SPIDERBOT_MAX  = '75 75 125';
+
+#ifdef SVQC
+float autocvar_g_vehicle_spiderbot_respawntime;
+
+float autocvar_g_vehicle_spiderbot_speed_stop;
+float autocvar_g_vehicle_spiderbot_speed_strafe;
+float autocvar_g_vehicle_spiderbot_speed_walk;
+float autocvar_g_vehicle_spiderbot_turnspeed;
+float autocvar_g_vehicle_spiderbot_movement_inertia;
+
+float autocvar_g_vehicle_spiderbot_springlength;
+float autocvar_g_vehicle_spiderbot_springup;
+float autocvar_g_vehicle_spiderbot_springblend;
+
+float autocvar_g_vehicle_spiderbot_head_pitchlimit_down;
+float autocvar_g_vehicle_spiderbot_head_pitchlimit_up;
+float autocvar_g_vehicle_spiderbot_head_pitchspeed;
+float autocvar_g_vehicle_spiderbot_head_turnlimit;
+float autocvar_g_vehicle_spiderbot_head_turnspeed;
+
+//float autocvar_g_vehicle_spiderbot_energy;
+//float autocvar_g_vehicle_spiderbot_energy_regen;
+//float autocvar_g_vehicle_spiderbot_energy_regen_pause;
+
+float autocvar_g_vehicle_spiderbot_health;
+float autocvar_g_vehicle_spiderbot_health_regen;
+float autocvar_g_vehicle_spiderbot_health_regen_pause;
+
+float autocvar_g_vehicle_spiderbot_shield;
+float autocvar_g_vehicle_spiderbot_shield_regen;
+float autocvar_g_vehicle_spiderbot_shield_regen_pause;
+
+float autocvar_g_vehicle_spiderbot_minigun_damage;
+float autocvar_g_vehicle_spiderbot_minigun_refire;
+float autocvar_g_vehicle_spiderbot_minigun_spread;
+float autocvar_g_vehicle_spiderbot_minigun_ammo_cost;
+float autocvar_g_vehicle_spiderbot_minigun_ammo_max;
+float autocvar_g_vehicle_spiderbot_minigun_ammo_regen;
+float autocvar_g_vehicle_spiderbot_minigun_ammo_regen_pause;
+
+float autocvar_g_vehicle_spiderbot_rocket_damage;
+float autocvar_g_vehicle_spiderbot_rocket_force;
+float autocvar_g_vehicle_spiderbot_rocket_radius;
+float autocvar_g_vehicle_spiderbot_rocket_speed;
+float autocvar_g_vehicle_spiderbot_rocket_refire;
+float autocvar_g_vehicle_spiderbot_rocket_reload;
+float autocvar_g_vehicle_spiderbot_rocket_health;
+float autocvar_g_vehicle_spiderbot_rocket_noise;
+float autocvar_g_vehicle_spiderbot_rocket_turnrate;
+float autocvar_g_vehicle_spiderbot_rocket_lifetime;
 
 void spiderbot_exit(float eject);
 void spiderbot_enter();
-
-void spiderbot_rocket_explode()
-{
-    vector org2;
-
-    if(self.event_damage != SUB_Null)
-    {
-        self.event_damage = SUB_Null;
-        self.think = spiderbot_rocket_explode;
-        self.nextthink = time;
-        return;
-    }
-
-    sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
-    org2 = findbetterlocation (self.origin, 16);
-    pointparticles(particleeffectnum("rocket_explode"), org2, '0 0 0', 1);
-    w_deathtypestring = "dident escape the rocket barrage";
-
-    if(!self.owner)
-        self.owner = self.realowner;
-
-    RadiusDamage (self, self.owner,
-        autocvar_g_vehicle_spiderbot_rocket_damage,
-        autocvar_g_vehicle_spiderbot_rocket_edgedamage,
-        autocvar_g_vehicle_spiderbot_rocket_radius, world,
-        autocvar_g_vehicle_spiderbot_rocket_force, DEATH_SBROCKET, world);
-
-    remove (self);
-}
-
-void spiderbot_rocket_touch()
-{
-    if(self.owner)
-    {
-        if(other == self.owner.vehicle)
-            return;
-
-        if(other == self.owner.vehicle.tur_head)
-            return;
-    }
-
-    PROJECTILE_TOUCH;
-    spiderbot_rocket_explode();
-}
+void spiderbot_spawn();
 
 void spiderbot_rocket_unguided()
 {
-    vector newdir,olddir;
+    vector newdir, olddir;
 
     self.nextthink  = time;
 
-
     olddir = normalize(self.velocity);
     newdir = normalize(self.pos1 - self.origin) + randomvec() * autocvar_g_vehicle_spiderbot_rocket_noise;
     self.velocity = normalize(olddir + newdir * autocvar_g_vehicle_spiderbot_rocket_turnrate) * autocvar_g_vehicle_spiderbot_rocket_speed;
 
     UpdateCSQCProjectile(self);
 
-    if (self.owner.deadflag != DEAD_NO || self.cnt < time)
-        spiderbot_rocket_explode();
-
+    if (self.owner.deadflag != DEAD_NO || self.cnt < time || vlen(self.pos1 - self.origin) < 16)
+        self.use();
 }
 
 void spiderbot_rocket_guided()
@@ -74,10 +77,10 @@ void spiderbot_rocket_guided()
 
     self.nextthink  = time;
 
-    if not (self.owner.vehicle)
+    if not (self.realowner.vehicle)
         self.think = spiderbot_rocket_unguided;
 
-    crosshair_trace(self.owner);
+    crosshair_trace(self.realowner);
     olddir = normalize(self.velocity);
     newdir = normalize(trace_endpos - self.origin) + randomvec() * autocvar_g_vehicle_spiderbot_rocket_noise;
     self.velocity = normalize(olddir + newdir * autocvar_g_vehicle_spiderbot_rocket_turnrate) * autocvar_g_vehicle_spiderbot_rocket_speed;
@@ -85,26 +88,17 @@ void spiderbot_rocket_guided()
     UpdateCSQCProjectile(self);
 
     if (self.owner.deadflag != DEAD_NO || self.cnt < time)
-        spiderbot_rocket_explode();
-}
-
-void spiderbot_rocket_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
-{
-    self.health -= damage;
-    self.velocity += force;
-    if(self.health < 1)
-        spiderbot_rocket_explode();
+        self.use();
 }
 
 void spiderbot_guide_release()
 {
     entity rkt;
-    rkt = findchainentity(owner,self.owner);
+    rkt = findchainentity(realowner, self.owner);
     if not (rkt)
         return;
 
     crosshair_trace(self.owner);
-
     while(rkt)
     {
         if(rkt.think == spiderbot_rocket_guided)
@@ -112,13 +106,14 @@ void spiderbot_guide_release()
             rkt.pos1 = trace_endpos;
             rkt.think = spiderbot_rocket_unguided;
         }
-
         rkt = rkt.chain;
     }
 }
 
 void spiderbot_rocket_do()
 {
+
+    vector v;
     entity rocket;
 
     if (self.owner.BUTTON_ATCK2)
@@ -131,7 +126,6 @@ void spiderbot_rocket_do()
 
             return;
         }
-
         self.wait = 1;
     }
     else
@@ -151,33 +145,20 @@ void spiderbot_rocket_do()
     if not (self.owner.BUTTON_ATCK2)
         return;
 
-    sound (self, CHAN_WEAPON, "weapons/rocket_fire.wav", VOL_BASE, ATTN_NORM);
-    rocket                    = spawn ();
-    setsize (rocket, '-1 -1 -1', '1 1 1'); // give it some size so it can be shot
-    setorigin(rocket,gettaginfo(self.tur_head,gettagindex(self.tur_head,"tag_fire")));
-    te_explosion (rocket.origin);
-
     crosshair_trace(self.owner);
 
-    rocket.classname       = "spiderbot_rocket";
-    rocket.bot_dodge       = TRUE;
-    rocket.bot_dodgerating = autocvar_g_vehicle_spiderbot_rocket_damage;
-    rocket.cnt             = time + autocvar_g_vehicle_spiderbot_rocket_lifetime;
-    rocket.health          = autocvar_g_vehicle_spiderbot_rocket_health;
-    rocket.takedamage      = DAMAGE_AIM;
-    rocket.event_damage    = spiderbot_rocket_damage;
-    rocket.owner           = self.owner;
-    rocket.nextthink       = time;
-    rocket.movetype        = MOVETYPE_FLYMISSILE;
-    rocket.velocity        = normalize(v_forward + (v_up * 0.5) + randomvec() * 0.25) * autocvar_g_vehicle_spiderbot_rocket_speed;
-    rocket.angles          = vectoangles(rocket.velocity);
-    rocket.think           = spiderbot_rocket_guided;
-    rocket.touch           = spiderbot_rocket_touch;
-    rocket.flags           = FL_PROJECTILE;
-    rocket.solid           = SOLID_TRIGGER;
-    rocket.pos1            = trace_endpos;
-
-       CSQCProjectile(rocket, FALSE, PROJECTILE_ROCKET, FALSE); // no culling, has fly sound
+    v = gettaginfo(self.tur_head,gettagindex(self.tur_head,"tag_fire"));
+    rocket = vehicles_projectile("spiderbot_rocket_launch", "weapons/rocket_fire.wav",
+                           v, normalize(v_forward) * autocvar_g_vehicle_spiderbot_rocket_speed,
+                           autocvar_g_vehicle_spiderbot_rocket_damage, autocvar_g_vehicle_spiderbot_rocket_radius, autocvar_g_vehicle_spiderbot_rocket_force, 1,
+                           DEATH_SBROCKET, PROJECTILE_SPIDERROCKET, autocvar_g_vehicle_spiderbot_rocket_health, FALSE, FALSE);
+
+    rocket.cnt        = time + 15;
+    rocket.classname  = "spiderbot_rocket";
+    rocket.pos1       = trace_endpos;
+    rocket.think      = spiderbot_rocket_guided;
+    rocket.nextthink  = time;
+    rocket.cnt        = time + autocvar_g_vehicle_spiderbot_rocket_lifetime;
 
     self.tur_head.frame += 1;
     if (self.tur_head.frame == 9)
@@ -188,138 +169,36 @@ void spiderbot_rocket_do()
     self.gun2.cnt = time + self.attack_finished_single;
 }
 
-/*
-void spiderbot_minigun_fire_Flash_Go() {
-       if (self.frame > 10)
-       {
-               self.alpha = -1;
-               setmodel(self,"");
-               return;
-       }
-
-       self.frame = self.frame + 2;
-       self.alpha = self.alpha - 0.2;
-       self.scale -= 0.01;
-       self.nextthink = time + 0.02;
-}
-*/
-
-void spiderbot_minigun_fire(entity gun, float trail)
-{
-    vector v;
-    
-    v = gettaginfo(gun,gettagindex(gun,"barrels"));
-    v_forward = normalize(v_forward);
-
-    sound (gun, CHAN_WEAPON, "weapons/uzi_fire.wav", VOL_BASE, ATTN_NORM);
-
-    fireBullet (v, v_forward, autocvar_g_vehicle_spiderbot_minigun_spread, autocvar_g_vehicle_spiderbot_minigun_damage,
-        autocvar_g_vehicle_spiderbot_minigun_spread, DEATH_SBMINIGUN, 0);
-
-
-       UziFlash();
-       setattachment(self.muzzle_flash, self.tur_head, "tag_fire");
-
-    if(trail)
-        trailparticles(self, particleeffectnum("EF_MGTURRETTRAIL"), v, trace_endpos);
-}
-
-void spiderbot_miniguns_do()
-{
-    float ftmp;
-
-    if((self.vehicle_reload1 == 1) || (!self.owner.BUTTON_ATCK))
-    {
-
-        ftmp = 1 / autocvar_g_vehicle_spiderbot_minigun_cooldown * sys_frametime;
-        self.owner.vehicle_reload1 = max(self.owner.vehicle_reload1 - ftmp, 0);
-        if(self.owner.vehicle_reload1 <= 0)
-            self.vehicle_reload1 = 0;
-
-        return ;
-    }
-
-    if (self.owner.BUTTON_ATCK)
-    {
-
-        // Animate miniguns
-        self.gun1.angles_z += (1440 * sys_frametime);
-        self.gun2.angles_z -= (1440 * sys_frametime);
-        if(self.gun1.angles_z >= 360)
-        {
-            self.gun1.angles_z = 0;
-            self.gun2.angles_z = 360;
-        }
-
-        if (self.tur_head.attack_finished_single < time)
-        {
-            // Fire bullets, alternating trails left<->right
-            self = self.owner;
-            if(self.misc_bulletcounter == 1)
-            {
-                spiderbot_minigun_fire(self.vehicle.gun1, 0);
-                spiderbot_minigun_fire(self.vehicle.gun2, 1);
-                self.misc_bulletcounter = 0;
-            }
-            else
-            {
-                spiderbot_minigun_fire(self.vehicle.gun1, 1);
-                spiderbot_minigun_fire(self.vehicle.gun2, 0);
-                self.misc_bulletcounter += 1;
-            }
-
-            self = self.vehicle;
-
-            ftmp = autocvar_g_vehicle_spiderbot_minigun_refire / autocvar_g_vehicle_spiderbot_minigun_heat;
-            self.owner.vehicle_reload1 +=  ftmp;
-
-            if(self.owner.vehicle_reload1 >= 1)
-            {
-                self.vehicle_reload1 = 1;
-                self.owner.vehicle_reload1 = 1;
-                self.tur_head.attack_finished_single = autocvar_g_vehicle_spiderbot_minigun_cooldown + time;
-            }
-            else
-                self.tur_head.attack_finished_single = autocvar_g_vehicle_spiderbot_minigun_refire + time;
-        }
-
-        self = self.owner;
-        return;
-    }
-}
-
-float spiderbot_pplug()
+float spiderbot_frame()
 {
     vector ad;
-    entity player,spider;
+    entity player, spider;
     float ftmp;
 
-    if not (self.owner)
-    {
-    }
-
     player = self;
     spider = self.vehicle;
+    self   = spider;
 
-    player.BUTTON_ZOOM = 0;
-    player.BUTTON_CROUCH = 0;
-    player.switchweapon = 0;
+    player.BUTTON_ZOOM      = 0;
+    player.BUTTON_CROUCH    = 0;
+    player.switchweapon     = 0;
 
     if(player.BUTTON_USE)
     {
-        self = spider;
-        spiderbot_exit(0);
+        vehicles_exit(VHEF_NORMAL);
         self = player;
         return 0;
     }
 
     crosshair_trace(player);
-    ad = vectoangles(normalize(trace_endpos - gettaginfo(spider.tur_head,gettagindex(spider.tur_head,"tag_hud")))) - (spider.tur_head.angles + spider.angles);
+    //UpdateAuxiliaryXhair(player, trace_endpos, ('1 0 0' * player.vehicle_reload2) + ('0 1 0' * (1 - player.vehicle_reload2)), 2);
 
-    fixedmakevectors(spider.angles);
-    if(ad_x > 180) ad_x -= 360;
+    player.v_angle_x *= -1;
+    ad = player.v_angle - (spider.tur_head.angles + spider.angles);
+    player.v_angle_x *= -1;
+    if(ad_x > 180)  ad_x -= 360;
     if(ad_x < -180) ad_x += 360;
-    if(ad_y > 180) ad_y -= 360;
+    if(ad_y > 180)  ad_y -= 360;
     if(ad_y < -180) ad_y += 360;
 
     // Rotate head
@@ -328,19 +207,45 @@ float spiderbot_pplug()
     spider.tur_head.angles_y = bound(autocvar_g_vehicle_spiderbot_head_turnlimit * -1, spider.tur_head.angles_y + ad_y, autocvar_g_vehicle_spiderbot_head_turnlimit);
 
     // Pitch head
+#if 0 // Enable to pich by cross-trace (more precise in chase, but less predictable)
+    ad = vectoangles(normalize(trace_endpos - gettaginfo(spider.tur_head,gettagindex(spider.tur_head,"tag_hud")))) - (spider.tur_head.angles + spider.angles);
+    if(ad_x > 180) ad_x -= 360;
+    if(ad_x < -180) ad_x += 360;
+#endif
     ftmp = autocvar_g_vehicle_spiderbot_head_pitchspeed * sys_frametime;
-    ad_x = bound(-ftmp, ad_x, ftmp);
+    ad_x = bound(ftmp * -1, ad_x, ftmp);
     spider.tur_head.angles_x = bound(autocvar_g_vehicle_spiderbot_head_pitchlimit_down, spider.tur_head.angles_x + ad_x, autocvar_g_vehicle_spiderbot_head_pitchlimit_up);
 
     // Turn Body
     ftmp = autocvar_g_vehicle_spiderbot_turnspeed * sys_frametime;
     ftmp = bound(-ftmp, spider.tur_head.angles_y, ftmp);
 
-    self = spider;
+    makevectors(spider.angles + '-2 0 0' * spider.angles_x);
+
+/*
+    vector ofs;
+    ofs = self.origin + v_up * 128;
+    te_lightning1(world, ofs, ofs + v_up * 32);
+    te_lightning1(world, ofs, ofs + v_right * 128);
+    te_lightning1(world, ofs, ofs + v_forward * 256);
+*/
+
+    movelib_groundalign4point(autocvar_g_vehicle_spiderbot_springlength, autocvar_g_vehicle_spiderbot_springup, autocvar_g_vehicle_spiderbot_springblend);
+
     if(spider.flags & FL_ONGROUND)
     {
-        if(player.BUTTON_JUMP && self.tur_head.wait < time)
+        if(spider.frame == 4 && self.tur_head.wait != 0)
         {
+            sound (self, CHAN_TRIGGER, "vehicles/spiderbot_land.wav", VOL_VEHICLEENGINE, ATTN_NORM);
+            spider.frame = 5;            
+        }
+        
+        if(player.BUTTON_JUMP && self.tur_head.wait < time)
+        {        
+            sound (self, CHAN_TRIGGER, "vehicles/spiderbot_jump.wav", VOL_VEHICLEENGINE, ATTN_NORM);
+            //dprint("spiderbot_jump:", ftos(soundlength("vehicles/spiderbot_jump.wav")), "\n");
+            self.delay = 0;
+
             self.tur_head.wait = time + 2;
             player.BUTTON_JUMP = 0;
             spider.velocity   = v_forward * 700 + v_up * 600;
@@ -350,6 +255,13 @@ float spiderbot_pplug()
         {
             if(vlen(player.movement) == 0)
             {
+                if(self.sound_nexttime < time || self.delay != 3)
+                {                        
+                    self.delay = 3;
+                    self.sound_nexttime = time + 6.486500; //soundlength("vehicles/spiderbot_idle.wav");
+                    //dprint("spiderbot_idle:", ftos(soundlength("vehicles/spiderbot_idle.wav")), "\n");
+                    sound (self, CHAN_TRIGGER, "vehicles/spiderbot_idle.wav", VOL_VEHICLEENGINE, ATTN_NORM);
+                }                
                 movelib_beak_simple(autocvar_g_vehicle_spiderbot_speed_stop);
                 spider.frame = 5;
             }
@@ -372,6 +284,14 @@ float spiderbot_pplug()
                     }
                     player.movement_y = 0;
                     movelib_move_simple(normalize(v_forward * player.movement_x),autocvar_g_vehicle_spiderbot_speed_walk,autocvar_g_vehicle_spiderbot_movement_inertia);
+
+                    if(self.sound_nexttime < time || self.delay != 1)
+                    {                        
+                        self.delay = 1;
+                        self.sound_nexttime = time + 6.486500; //soundlength("vehicles/spiderbot_walk.wav");
+                        sound (self, CHAN_TRIGGER, "vehicles/spiderbot_walk.wav", VOL_VEHICLEENGINE, ATTN_NORM);
+                        //dprint("spiderbot_walk:", ftos(soundlength("vehicles/spiderbot_walk.wav")), "\n");
+                    }
                 }
                 else if(player.movement_y != 0)
                 {
@@ -386,31 +306,103 @@ float spiderbot_pplug()
                         spider.frame = 3;
                     }
                     movelib_move_simple(normalize(v_right * player.movement_y),autocvar_g_vehicle_spiderbot_speed_strafe,autocvar_g_vehicle_spiderbot_movement_inertia);
+                    if(self.sound_nexttime < time || self.delay != 2)
+                    {                        
+                        self.delay = 2;
+                        self.sound_nexttime = time + 6.486500; //soundlength("vehicles/spiderbot_strafe.wav");
+                        sound (self, CHAN_TRIGGER, "vehicles/spiderbot_strafe.wav", VOL_VEHICLEENGINE, ATTN_NORM);
+                        //dprint("spiderbot_strafe:", ftos(soundlength("vehicles/spiderbot_strafe.wav")), "\n");
+                    }
                 }
-
             }
         }
-        movelib_groundalign4point(300,100,0.25);
     }
 
-    spiderbot_miniguns_do();
+    self.angles_x = bound(-45, self.angles_x, 45);
+    self.angles_z = bound(-45, self.angles_z, 45);
+
+    if(player.BUTTON_ATCK)
+    {
+        spider.cnt = time;
+        if(spider.vehicle_ammo1 >= autocvar_g_vehicle_spiderbot_minigun_ammo_cost && spider.tur_head.attack_finished_single <= time)
+        {
+            entity gun;
+            vector v;
+            spider.misc_bulletcounter += 1;
+
+            self = player;
+
+            mod(spider.misc_bulletcounter, 2) ? gun = spider.gun1 : gun = spider.gun2;
+            v = gettaginfo(gun, gettagindex(gun, "barrels"));
+            v_forward = normalize(v_forward);
+            v += v_forward * 50;
+
+            fireBullet (v, v_forward, autocvar_g_vehicle_spiderbot_minigun_spread, autocvar_g_vehicle_spiderbot_minigun_damage,
+                autocvar_g_vehicle_spiderbot_minigun_spread, DEATH_SBMINIGUN, 0);
+
+            sound (gun, CHAN_WEAPON, "weapons/uzi_fire.wav", VOL_BASE, ATTN_NORM);
+            trailparticles(self, particleeffectnum("spiderbot_minigun_trail"), v, trace_endpos);
+            pointparticles(particleeffectnum("spiderbot_minigun_muzzleflash"), v, v_forward * 2500, 1);
+
+            self = spider;
+
+            spider.vehicle_ammo1 -= autocvar_g_vehicle_spiderbot_minigun_ammo_cost;
+            spider.tur_head.attack_finished_single = time + autocvar_g_vehicle_spiderbot_minigun_refire;
+            player.vehicle_ammo1 = (spider.vehicle_ammo1 / autocvar_g_vehicle_spiderbot_minigun_ammo_max) * 100;
+        }
+    }
+    else
+        vehicles_regen(cnt, vehicle_ammo1, autocvar_g_vehicle_spiderbot_minigun_ammo_max,
+                                           autocvar_g_vehicle_spiderbot_minigun_ammo_regen_pause,
+                                           autocvar_g_vehicle_spiderbot_minigun_ammo_regen, frametime);
+
     spiderbot_rocket_do();
-    vehicle_stdproc_shiledregen(CCVAR("_shield"), frametime);
-    vehicle_stdproc_healthregen(CCVAR("_health"), frametime);
+
+    if(self.vehicle_flags  & VHF_SHIELDREGEN)
+        vehicles_regen(dmg_time, vehicle_shield, autocvar_g_vehicle_spiderbot_shield, autocvar_g_vehicle_spiderbot_shield_regen_pause, autocvar_g_vehicle_spiderbot_shield_regen, frametime);
+
+    if(self.vehicle_flags  & VHF_HEALTHREGEN)
+        vehicles_regen(dmg_time, vehicle_health, autocvar_g_vehicle_spiderbot_health, autocvar_g_vehicle_spiderbot_health_regen_pause, autocvar_g_vehicle_spiderbot_health_regen, frametime);
 
     player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0;
     player.vehicle_ammo2 = spider.tur_head.frame;
 
     if(spider.gun2.cnt <= time)
-        player.vehicle_reload2 = 1;
+        player.vehicle_reload2 = 100;
     else
-        player.vehicle_reload2 = 1 - ((spider.gun2.cnt - time) / spider.attack_finished_single);
+        player.vehicle_reload2 = 100 - ((spider.gun2.cnt - time) / spider.attack_finished_single) * 100;
 
-    setorigin(player,spider.origin + '0 0 64');
+    setorigin(player, spider.origin + '0 0 1' * SPIDERBOT_MAX_z);
     player.velocity = spider.velocity;
 
-    self = player;
+    VEHICLE_UPDATE_PLAYER(health, spiderbot);
+
+    if(self.vehicle_flags & VHF_HASSHIELD)
+        VEHICLE_UPDATE_PLAYER(shield, spiderbot);
+
+#if 1 // 0 to enable per-gun impact aux crosshairs
+    // Avarage gun impact point's -> aux cross
+    vector vf;
+    ad = gettaginfo(spider.gun1, gettagindex(spider.gun1, "barrels"));
+    vf = v_forward;
+    ad += gettaginfo(spider.gun2, gettagindex(spider.gun2, "barrels"));
+    vf += v_forward;
+    ad = ad * 0.5;
+    v_forward = vf * 0.5;
+    traceline(ad, ad + v_forward * MAX_SHOT_DISTANCE, MOVE_NORMAL, spider);
+    UpdateAuxiliaryXhair(player, trace_endpos, ('1 0 0' * player.vehicle_reload1) + ('0 1 0' * (1 - player.vehicle_reload1)), 0);
+
+#else
+    ad = gettaginfo(spider.gun1, gettagindex(spider.gun1, "barrels"));
+    traceline(ad, ad + v_forward * MAX_SHOT_DISTANCE, MOVE_NORMAL, spider);
+    UpdateAuxiliaryXhair(player, trace_endpos, ('1 0 0' * player.vehicle_reload1) + ('0 1 0' * (1 - player.vehicle_reload1)), 0);
+
+    ad = gettaginfo(spider.gun2, gettagindex(spider.gun2, "barrels"));
+    traceline(ad, ad + v_forward * MAX_SHOT_DISTANCE, MOVE_NORMAL, spider);
+    UpdateAuxiliaryXhair(player, trace_endpos, ('1 0 0' * player.vehicle_reload1) + ('0 1 0' * (1 - player.vehicle_reload1)), 1);
+#endif
 
+    self = player;
     return 1;
 }
 
@@ -424,71 +416,16 @@ void spiderbot_think()
 
 void spiderbot_enter()
 {
-    // Remove this when bots know how to use the spiderbot
-    if (clienttype(other) != CLIENTTYPE_REAL)
-        return;
-
-    self.colormod = self.tur_head.colormod = '0 0 0';
-
-    if(teams_matter)
-    if(self.team)
-    if(self.team != other.team)
-        return;
-
-    self.owner = other;
-    self.switchweapon = other.switchweapon;
-
-    self.event_damage         = vehicle_stdproc_damage ;
-    self.colormap             = self.owner.colormap;
-    self.tur_head.colormap    = self.owner.colormap;
-    self.vehicle_hudmodel.viewmodelforclient = self.owner;
-    self.nextthink            = 0;
-    self.owner.angles         = self.angles;
-    self.owner.takedamage     = DAMAGE_NO;
-    self.owner.solid          = SOLID_NOT;
-    self.owner.movetype       = MOVETYPE_NOCLIP;
-    self.owner.alpha          = -1;
-    self.owner.PlayerPhysplug = spiderbot_pplug;
-    self.owner.vehicle        = self;
-    self.owner.event_damage   = SUB_Null;
-    self.owner.hud            = HUD_SPIDERBOT;
+    self.movetype   = MOVETYPE_WALK;
     self.owner.vehicle_health = (self.vehicle_health / autocvar_g_vehicle_spiderbot_health);
     self.owner.vehicle_shield = (self.vehicle_shield / autocvar_g_vehicle_spiderbot_shield);
-    self.owner.view_ofs       = '0 0 0';
-    self.owner.vehicle_ammo1 = self.vehicle_ammo1;
-    self.owner.vehicle_ammo2 = self.vehicle_ammo2;
-    self.owner.vehicle_reload1 = self.vehicle_reload1;
-    self.owner.vehicle_reload2 = self.vehicle_reload2;
-
-    //if(other.flags & FL_ONGROUND)
-        other.flags &~= FL_ONGROUND;
-
-    //if(self.flags & FL_ONGROUND)
-        self.flags &~= FL_ONGROUND;
-
-    self.team                 = self.owner.team;
-    self.flags               -= FL_NOTARGET;
-
-    if(clienttype(other) == CLIENTTYPE_REAL)
-    {
-        msg_entity = other;
-        WriteByte (MSG_ONE, SVC_SETVIEWPORT);
-        WriteEntity(MSG_ONE, self.vehicle_viewport);
-
-        WriteByte (MSG_ONE, SVC_SETVIEWANGLES);  // 10 = SVC_SETVIEWANGLES
-        WriteAngle(MSG_ONE, self.tur_head.angles_x + self.angles_x);    // tilt
-        WriteAngle(MSG_ONE, self.tur_head.angles_y + self.angles_y);    // yaw
-        WriteAngle(MSG_ONE, 0);    // roll
-    }
 }
 
 void spiderbot_exit(float eject)
 {
     entity e;
-    self.frame = 5;
-
-    self.flags      |= FL_NOTARGET;
-
+    vector spot;
+    
     e = findchain(classname,"spiderbot_rocket");
     while(e)
     {
@@ -500,252 +437,192 @@ void spiderbot_exit(float eject)
         e = e.chain;
     }
 
-    self.owner.switchweapon = self.switchweapon;
-
-    self.velocity = '0 0 0';
-    if(clienttype(self.owner) == CLIENTTYPE_REAL)
-    {
-        msg_entity = self.owner;
-        WriteByte (MSG_ONE, SVC_SETVIEWPORT);
-        WriteEntity( MSG_ONE, self.owner);
-
-        WriteByte (MSG_ONE, SVC_SETVIEWANGLES);  // 10 = SVC_SETVIEWANGLES
-        WriteAngle(MSG_ONE, 0);    // tilt
-        WriteAngle(MSG_ONE, self.angles_y);    // yaw
-        WriteAngle(MSG_ONE, 0);    // roll
-    }
-
-    self.think = spiderbot_think;
-    self.nextthink = time;
-    self.owner.takedamage     = DAMAGE_AIM;
-    self.owner.solid          = SOLID_SLIDEBOX;
-    self.owner.movetype       = MOVETYPE_WALK;
-
-    setsize(self.owner,PL_MIN,PL_MAX);
-
-    self.owner.alpha          = 1;
-    self.owner.PlayerPhysplug = SUB_Null;
-    self.owner.vehicle        = world;
-       self.owner.view_ofs       = PL_VIEW_OFS;
-       self.owner.hud            = HUD_NORMAL;
-       self.owner.event_damage   = PlayerDamage;
-
-       self.colormap            = 1024;
-       self.tur_head.colormap   = 1024;
-
-    if not (teams_matter)
-        self.team                = 0;
-    else
-    {
-        self.team = self.spiderbot_spawnpnt.team ;
-        if (self.team == COLOR_TEAM1) self.colormod = '1.4 0.8 0.8';
-        if (self.team == COLOR_TEAM2) self.colormod = '0.8 0.8 1.4';
-        self.tur_head.colormod = self.colormod;
-    }
-
-       self.vehicle_hudmodel.viewmodelforclient = self;
-       self.tur_head.nodrawtoclient             = self;
+    self.velocity   = '0 0 0';
+    self.think      = spiderbot_think;
+    self.nextthink  = time;
+    self.frame      = 5;
+    self.movetype   = MOVETYPE_WALK;
 
-    setattachment(self.owner,world,"");
+    if not (self.owner)
+        return;
 
        makevectors(self.angles);
        if(eject)
        {
-           setorigin(self.owner,self.origin + v_forward * 100 + '0 0 64');
+           spot = self.origin + v_forward * 100 + '0 0 64';
+           spot = vehicles_findgoodexit(spot);
+           setorigin(self.owner , spot);
            self.owner.velocity = (v_up + v_forward * 0.25) * 750;
        }
        else
-        setorigin(self.owner,self.origin - v_forward * 200 + '0 0 64');
-
+       {
+           spot = self.origin - v_forward * 200 + '0 0 64';
+           spot = vehicles_findgoodexit(spot);
+           setorigin(self.owner , spot);
+       }
+        
     self.owner = world;
 }
 
-float spiderbot_crushable(entity e)
+void spiderbot_spawn()
 {
-    if(e.classname == "corpse")
-        return 1;
-
-    if(e.classname == "player")
-        return 1;
-
-    if(e.classname == "monster_zombie")
-        return 1;
-
-    return 0;
+    self.frame              = 5;
+    self.tur_head.frame     = 1;
+    self.think              = spiderbot_think;
+    self.nextthink          = time;
+    self.vehicle_health     = autocvar_g_vehicle_spiderbot_health;
+    self.vehicle_shield     = autocvar_g_vehicle_spiderbot_shield;
+    self.movetype           = MOVETYPE_WALK;
+    self.solid              = SOLID_SLIDEBOX;
+    self.alpha              = self.tur_head.alpha = self.gun1.alpha = self.gun2.alpha = 1;
+    self.tur_head.angles    = '0 0 0';
+
+    setorigin(self, self.pos1 + '0 0 128');
+    self.angles = self.pos2;
 }
 
-void spiderbot_touch()
+void spiderbot_headfade()
 {
-    if(self.owner)
-    {
-        if(vlen(self.velocity) == 0)
-            return;
-
-        if not (spiderbot_crushable(other))
-            return;
-
-        //todo: add check for velocity/angle here (so we dont cush players runing into us from behind)
+       self.think = spiderbot_headfade;
+       self.nextthink = self.fade_time;
+       self.alpha = 1 - (time - self.fade_time) * self.fade_rate;
 
-        Damage(other,self,self.owner,autocvar_g_vehicle_spiderbot_crush_dmg,DEATH_SBCRUSH,'0 0 0', normalize(other.origin - self.origin) * autocvar_g_vehicle_spiderbot_crush_force );
-        return;
+    if(self.cnt < time || self.alpha < 0.1)
+    {
+        if(self.alpha > 0.1)
+        {
+            sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
+            pointparticles(particleeffectnum("explosion_big"), self.origin + '0 0 100', '0 0 0', 1);
+        }
+        remove(self);
     }
-
-    if(other.classname != "player")
-        return;
-
-    if(other.deadflag != DEAD_NO)
-        return;
-
-    if(other.vehicle != world)
-        return;
-
-    spiderbot_enter();
-}
-
-float spiderbot_customizeentityforclient()
-{
-    if(self.deadflag == DEAD_DEAD)
-        return FALSE;
-
-    return TRUE;
-}
-
-void spiderbot_spawn()
-{
-    self.frame = 5;
-    self.think = spiderbot_think;
-    self.nextthink = time;
-
-    setsize(self,spiderbot_MIN,spiderbot_MAX);
-
-    self.owner = world;
-    self.velocity = '0 0 0';
-    self.vehicle_health = CCVAR("_health");
-    self.vehicle_shield = CCVAR("_shield");
-    self.event_damage = vehicle_stdproc_damage;
-    self.iscreature = TRUE;
-    self.movetype   = MOVETYPE_WALK;
-    self.solid      = SOLID_SLIDEBOX;
-    self.takedamage = DAMAGE_AIM;
-    self.touch      = spiderbot_touch;
-    self.alpha      = self.tur_head.alpha = self.gun1.alpha = self.gun2.alpha = 1;
-    self.tur_head.angles = '0 0 0';
-       self.colormap = 1024;
-       self.tur_head.colormap = 1024;
-       self.deadflag    = DEAD_NO;
-    self.bot_attack = TRUE;
-    self.flags      |= FL_NOTARGET;
-    self.vehicle_hudmodel.viewmodelforclient = self;
-    self.tur_head.frame = 1;
-
-    setorigin(self,self.spiderbot_spawnpnt.origin + '0 0 1.25' * spiderbot_MAX_z);
-    self.angles = self.spiderbot_spawnpnt.angles;
-
-    if (self.team == COLOR_TEAM1)
-        self.colormod = '1.4 0.8 0.8';
-    else if (self.team == COLOR_TEAM2)
-        self.colormod = '0.8 0.8 1.4';
-    else
-        self.colormod = '0 0 0';
-
-    self.tur_head.colormod = self.colormod;
-
-
-    pointparticles(particleeffectnum("teleport"), self.origin + '0 0 64', '0 0 0', 1);
 }
 
 void spiderbot_blowup()
 {
-    sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
-    pointparticles(particleeffectnum("rocket_explode"), findbetterlocation (self.origin, 16), '0 0 0', 1);
+    if(self.cnt > time)
+    {
+        if(random() < 0.1)
+        {
+            sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
+            pointparticles(particleeffectnum("explosion_small"), randomvec() * 80 + (self.origin + '0 0 100'), '0 0 0', 1);
+        }
+        self.nextthink = time + 0.1;
+        return;
+    }
+    
+    entity h, g1, g2, b;
+    b = spawn();
+    h = spawn();
+    g1 = spawn();
+    g2 = spawn();
+
+    setmodel(b,  "models/vehicles/spiderbot.dpm");
+    setmodel(h,  "models/vehicles/spiderbot_top.dpm");
+    setmodel(g1, "models/vehicles/spiderbot_barrels.dpm");
+    setmodel(g2, "models/vehicles/spiderbot_barrels.dpm");
+
+    setorigin(b, self.origin);
+    b.frame         = 11;
+    b.angles        = self.angles;
+    setsize(b, self.mins, self.maxs);
+
+    setorigin(h, gettaginfo(self, gettagindex(self, "tag_head")));
+    h.movetype      = MOVETYPE_BOUNCE;
+    h.solid         = SOLID_BBOX;
+    h.velocity      = v_up * (500 + random() * 500) + randomvec() * 128;
+    h.modelflags    = MF_ROCKET;
+    h.effects       = EF_FLAME | EF_LOWPRECISION;
+    h.avelocity     = randomvec() * 360;
+
+    h.alpha         = 1;
+    h.cnt           = time + (3.5 * random());
+    h.fade_rate     = 1 / min(autocvar_g_vehicle_spiderbot_respawntime, 10);
+    h.fade_time     = time;
+    h.think         = spiderbot_headfade;
+    h.nextthink     = time;
+
+    setorigin(g1, gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_hardpoint01")));
+    g1.movetype     = MOVETYPE_TOSS;
+    g1.solid        = SOLID_CORPSE;
+    g1.velocity     = v_forward * 700 + (randomvec() * 32);
+    g1.avelocity    = randomvec() * 180;
+
+    setorigin(g2, gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_hardpoint02")));
+    g2.movetype     = MOVETYPE_TOSS;
+    g2.solid        = SOLID_CORPSE;
+    g2.velocity     = v_forward * 700 + (randomvec() * 32);
+    g2.avelocity    = randomvec() * 180;
+
+    h.colormod = b.colormod = g1.colormod = g2.colormod = '-2 -2 -2';
+
+    SUB_SetFade(b,  time + 5, min(autocvar_g_vehicle_spiderbot_respawntime, 1));
+    //SUB_SetFade(h,  time, min(autocvar_g_vehicle_spiderbot_respawntime, 10));
+    SUB_SetFade(g1, time, min(autocvar_g_vehicle_spiderbot_respawntime, 10));
+    SUB_SetFade(g2, time, min(autocvar_g_vehicle_spiderbot_respawntime, 10));
 
     RadiusDamage (self, self, 250, 15, 250, world, 250, DEATH_SBBLOWUP, world);
 
     self.alpha = self.tur_head.alpha = self.gun1.alpha = self.gun2.alpha = -1;
-    self.nextthink  = time + autocvar_g_vehicle_spiderbot_respawntime;
-    self.think      = spiderbot_spawn;
     self.movetype   = MOVETYPE_NONE;
-
-    setorigin(self, self.tur_aimpos);
+    self.deadflag   = DEAD_DEAD;
+    self.solid      = SOLID_NOT;
+    self.tur_head.effects  &~=  EF_FLAME;
+       self.vehicle_hudmodel.viewmodelforclient = self;
 }
 
 void spiderbot_die()
 {
-
-    self.health = 0;
-    self.event_damage = SUB_Null;
-    self.iscreature = FALSE;
-    self.solid      = SOLID_NOT;
-    self.takedamage = DAMAGE_NO;
-    self.touch      = SUB_Null;
-    self.nextthink  = time + random() * 2;
-    self.think      = spiderbot_blowup;
-    self.deadflag    = DEAD_DEAD;
-       self.vehicle_hudmodel.viewmodelforclient = self;
-       self.frame = 0;
-       self.tur_head.frame = 1;
-
+    sound (self, CHAN_TRIGGER, "vehicles/spiderbot_die.wav", VOL_BASE, ATTN_NORM);
+    pointparticles(particleeffectnum("explosion_medium"), self.origin + '0 0 100', '0 0 0', 1);
+
+    self.health             = 0;
+    self.event_damage       = SUB_Null;
+    self.takedamage         = DAMAGE_NO;
+    self.touch              = SUB_Null;
+    self.cnt                = 3.4 + time + random() * 2;
+    self.think              = spiderbot_blowup;
+    self.nextthink          = time;
+    self.deadflag           = DEAD_DYING;
+       self.frame              = 5;
+       self.tur_head.effects  |= EF_FLAME;
+       self.colormod           = self.tur_head.colormod = '-1 -1 -1';
+       self.frame              = 10;
+       self.movetype           = MOVETYPE_TOSS;
 }
 
 void vewhicle_spiderbot_dinit()
 {
+    if not (vehicle_initialize(
+             "Spiderbot",
+             "models/vehicles/spiderbot.dpm",
+             "models/vehicles/spiderbot_top.dpm",
+             "models/vehicles/spiderbot_cockpit.dpm",
+             "tag_head", "tag_hud", "",
+             HUD_SPIDERBOT,
+             SPIDERBOT_MIN, SPIDERBOT_MAX,
+             FALSE,
+             spiderbot_spawn, autocvar_g_vehicle_spiderbot_respawntime,
+             spiderbot_frame,
+             spiderbot_enter, spiderbot_exit,
+             spiderbot_die,   spiderbot_think,
+             FALSE))
+    {
+        remove(self);
+        return;
+    }
 
-    self.spiderbot_spawnpnt = spawn();
-    self.spiderbot_spawnpnt.angles = self.angles;
-
-    setorigin(self,self.origin);
-    tracebox(self.origin + '0 0 100', spiderbot_MIN, spiderbot_MAX, self.origin - '0 0 10000', MOVE_WORLDONLY, self);
-    setorigin(self.spiderbot_spawnpnt,trace_endpos);
-
-    if(self.team && !teams_matter)
-        self.team = 0;
-    else
-        self.spiderbot_spawnpnt.team = self.team;
-
-    addstat(STAT_HUD, AS_INT,  hud);
-       addstat(STAT_VEHICLESTAT_HEALTH,  AS_FLOAT, vehicle_health);
-       addstat(STAT_VEHICLESTAT_SHIELD,  AS_FLOAT, vehicle_shield);
-       addstat(STAT_VEHICLESTAT_ENERGY,  AS_FLOAT, vehicle_energy);
-       addstat(STAT_VEHICLESTAT_AMMO1,   AS_INT,   vehicle_ammo1);
-       addstat(STAT_VEHICLESTAT_RELOAD1, AS_FLOAT, vehicle_reload1);
-       addstat(STAT_VEHICLESTAT_AMMO2,   AS_INT,   vehicle_ammo2);
-       addstat(STAT_VEHICLESTAT_RELOAD2, AS_FLOAT, vehicle_reload2);
-
-    if (self.netname == "")
-        self.netname     = "spiderbot";
-
-    self.tur_head           = spawn();
     self.gun1               = spawn();
     self.gun2               = spawn();
-    self.vehicle_viewport   = spawn();
-    self.vehicle_hudmodel   = spawn();
-    self.vehicle_flags      = VHF_HASSHIELD | VHF_SHIELDREGEN | VHF_HEALTHREGEN | VHF_DEATHEJECT;
-    self.cvar_basename      = "g_vehicle_spiderbot";
-    self.gravity            = 2;
 
-    setmodel(self, "models/vehicles/spiderbot.dpm");
-    setmodel(self.tur_head, "models/vehicles/spiderbot_top.dpm");
     setmodel(self.gun1, "models/vehicles/spiderbot_barrels.dpm");
     setmodel(self.gun2, "models/vehicles/spiderbot_barrels.dpm");
-    setmodel(self.vehicle_hudmodel, "models/vehicles/spiderbot_cockpit.dpm");
-    setmodel(self.vehicle_viewport, "null");
-
-    setattachment(self.tur_head, self, "tag_head");
-    setattachment(self.vehicle_hudmodel, self.tur_head, "tag_hud");
-    setattachment(self.vehicle_viewport, self.vehicle_hudmodel, "");
 
     setattachment(self.gun1, self.tur_head, "tag_hardpoint01");
     setattachment(self.gun2, self.tur_head, "tag_hardpoint02");
 
-    self.tur_head.owner = self;
-    self.customizeentityforclient          = spiderbot_customizeentityforclient;
-
-    self.tur_aimpos = self.origin;
-
-    spiderbot_spawn();
-
-    self.vehicle_die = spiderbot_die;
-    self.vehicle_exit = spiderbot_exit;
+    self.gravity            = 2;
+    self.mass               = 5000;
 }
 
 void spawnfunc_vehicle_spiderbot()
@@ -758,8 +635,27 @@ void spawnfunc_vehicle_spiderbot()
     precache_model ( "models/uziflash.md3");
 
     precache_sound ( "weapons/rocket_impact.wav" );
-
-    //self.team                = -1;
-    self.think = vewhicle_spiderbot_dinit;
-    self.nextthink = time + 0.5;
+    precache_sound ( "weapons/uzi_fire.wav" );
+    precache_sound ( "weapons/rocket_impact.wav");
+    
+    precache_sound ( "vehicles/spiderbot_die.wav");
+    precache_sound ( "vehicles/spiderbot_idle.wav");
+    precache_sound ( "vehicles/spiderbot_jump.wav");
+    precache_sound ( "vehicles/spiderbot_strafe.wav");
+    precache_sound ( "vehicles/spiderbot_walk.wav");
+    precache_sound ( "vehicles/spiderbot_land.wav");
+
+    vehicles_configcheck("vehicle_spiderbot.cfg", autocvar_g_vehicle_spiderbot_health);
+    if(autocvar_g_vehicle_spiderbot_shield)
+        self.vehicle_flags |= VHF_HASSHIELD;
+
+    if(autocvar_g_vehicle_spiderbot_shield_regen)
+        self.vehicle_flags |= VHF_SHIELDREGEN;
+
+    if(autocvar_g_vehicle_spiderbot_health_regen)
+        self.vehicle_flags |= VHF_HEALTHREGEN;
+    
+    self.think = vewhicle_spiderbot_dinit;    
+    self.nextthink = time + (autocvar_g_vehicles_delayspawn ? autocvar_g_vehicle_spiderbot_respawntime + (random() * autocvar_g_vehicles_delayspawn_jitter) : 0.5);
 }
+#endif // SVQC
index 7cc2949..69c0f87 100644 (file)
-void vehicle_stdproc_enter()
+float autocvar_g_vehicles_crush_dmg;
+float autocvar_g_vehicles_crush_force;
+float autocvar_g_vehicles_delayspawn;
+float autocvar_g_vehicles_delayspawn_jitter;
+
+void vehicles_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force);
+void vehicles_return();
+void vehicles_enter();
+void vehicles_touch();
+void vehicles_reset_colors();
+void vehicles_clearrturn();
+void vehicles_setreturn();
+
+
+/** AuxiliaryXhair*
+    Send additional points of interest to be drawn, to vehicle owner
+**/
+float MAX_AXH = 4;
+.entity AuxiliaryXhair[MAX_AXH];
+
+float SendAuxiliaryXhair(entity to, float sf)
+{
+
+       WriteByte(MSG_ENTITY, ENT_CLIENT_AUXILIARYXHAIR);
+
+       WriteByte(MSG_ENTITY, self.cnt);
+
+       WriteCoord(MSG_ENTITY, self.origin_x);
+       WriteCoord(MSG_ENTITY, self.origin_y);
+       WriteCoord(MSG_ENTITY, self.origin_z);
+
+    WriteByte(MSG_ENTITY, rint(self.colormod_x * 255));
+    WriteByte(MSG_ENTITY, rint(self.colormod_y * 255));
+    WriteByte(MSG_ENTITY, rint(self.colormod_z * 255));
+
+    return TRUE;
+}
+
+void UpdateAuxiliaryXhair(entity own, vector loc, vector clr, float axh_id)
+{
+    entity axh;
+
+    axh_id = bound(0, axh_id, MAX_AXH);
+    axh = own.AuxiliaryXhair[axh_id];
+
+    if(axh == world || wasfreed(axh))  // MADNESS? THIS IS QQQQCCCCCCCCC (wasfreed, why do you exsist?)
+    {
+        axh                     = spawn();
+        axh.cnt                 = axh_id;
+        axh.drawonlytoclient    = own;
+        axh.owner               = own;
+        Net_LinkEntity(axh, FALSE, 0, SendAuxiliaryXhair);
+    }
+
+    setorigin(axh, loc);
+    axh.colormod            = clr;
+    axh.SendFlags           = 0x01;
+    own.AuxiliaryXhair[axh_id] = axh;
+}
+
+/*
+// SVC_TEMPENTITY based, horrible with even 50 ping. hm.
+// WriteByte(MSG_ONE, SVC_TEMPENTITY) uses reliable messagess, never use for thinsg that need continous updates.
+void SendAuxiliaryXhair2(entity own, vector loc, vector clr, float axh_id)
 {
+       msg_entity = own;
+
+       WriteByte(MSG_ONE, SVC_TEMPENTITY);
+       WriteByte(MSG_ONE, TE_CSQC_AUXILIARYXHAIR);
+
+       WriteByte(MSG_ONE, axh_id);
+
+       WriteCoord(MSG_ONE, loc_x);
+       WriteCoord(MSG_ONE, loc_y);
+       WriteCoord(MSG_ONE, loc_z);
+
+    WriteByte(MSG_ONE, rint(clr_x * 255));
+    WriteByte(MSG_ONE, rint(clr_y * 255));
+    WriteByte(MSG_ONE, rint(clr_z * 255));
+
 }
+*/
+// End AuxiliaryXhair
 
-void vehicle_stdproc_exit(float eject)
+/**
+    Notifies the client that he enterd a vehicle, and sends 
+    realavent data.
+    
+    only sends vehicle_id atm (wich is a HUD_* constant, ex. HUD_SPIDERBOT)
+**/
+void CSQCVehicleSetup(entity own, float vehicle_id)
 {
+       msg_entity = own;
+
+       WriteByte(MSG_ONE, SVC_TEMPENTITY);
+       WriteByte(MSG_ONE, TE_CSQC_VEHICLESETUP);
+       WriteByte(MSG_ONE, vehicle_id);
 }
 
-void vehicle_stdproc_shiledregen(float rmax, float dt)
+/** vehicles_locktarget
+
+    Generic target locking.
+
+    Figure out if what target is "locked" (if any), for missile tracking as such.
+
+    after calling, "if(self.lock_target != world && self.lock_strength == 1)" mean
+    you have a locked in target.
+
+    Exspects a crosshair_trace() or equivalent to be
+    dont before calling.
+
+**/
+.entity lock_target;
+.float  lock_strength;
+.float  lock_time;
+.float  lock_soundtime;
+void vehicles_locktarget(float incr, float decr, float _lock_time)
 {
-    if(self.vehicle_shield < rmax)
-    if(self.dmg_time + CCVAR("_shield_regen_dmgpause") < time)
+    if(self.lock_target && self.lock_target.deadflag != DEAD_NO)
     {
-        self.vehicle_shield = min(self.vehicle_shield + CCVAR("_shield_regen") * dt, rmax);
+        self.lock_target    = world;
+        self.lock_strength  = 0;
+        self.lock_time      = 0;
+    }
 
-        if(self.owner)
-            self.owner.vehicle_shield = self.vehicle_shield / rmax;
+    if(self.lock_time > time)
+    {
+        if(self.lock_target)
+        if(self.lock_soundtime < time)
+        {
+            self.lock_soundtime = time + 0.5;
+            play2(self.owner, "vehicles/locked.wav");
+        }
+        
+        return;
+    }
+
+    if(trace_ent != world)
+    {
+        if(teams_matter && trace_ent.team == self.team)
+            trace_ent = world;
+
+        if(trace_ent.deadflag != DEAD_NO)
+            trace_ent = world;
+
+        if not (trace_ent.vehicle_flags & VHF_ISVEHICLE || trace_ent.turrcaps_flags & TFL_TURRCAPS_ISTURRET)
+            trace_ent = world;
+    }
+
+    if(self.lock_target == world && trace_ent != world)
+        self.lock_target = trace_ent;
+    
+    if(self.lock_target && trace_ent == self.lock_target) 
+    {            
+        if(self.lock_strength != 1 && self.lock_strength + incr >= 1)
+        {
+            play2(self.owner, "vehicles/lock.wav");
+            self.lock_soundtime = time + 0.8;
+        }        
+        else if (self.lock_strength != 1 && self.lock_soundtime < time)
+        {            
+            play2(self.owner, "vehicles/locking.wav");
+            self.lock_soundtime = time + 0.3;
+        }
+        
+    }    
+        
+    // Have a locking target
+    // Trace hit current target
+    if(trace_ent == self.lock_target && trace_ent != world)
+    {
+        self.lock_strength = min(self.lock_strength + incr, 1);
+        if(self.lock_strength == 1)
+            self.lock_time = time + _lock_time;
+    }
+    else
+    {
+        if(trace_ent)
+            self.lock_strength = max(self.lock_strength - decr * 2, 0);
+        else
+            self.lock_strength = max(self.lock_strength - decr, 0);
+
+        if(self.lock_strength == 0)
+            self.lock_target = world;
     }
 }
 
-void vehicle_stdproc_healthregen(float rmax, float dt)
+#define VEHICLE_UPDATE_PLAYER(fld,vhname) \
+self.owner.vehicle_##fld = (self.vehicle_##fld / autocvar_g_vehicle_##vhname##_##fld) * 100
+
+#define vehicles_sweap_collision(orig,vel,dt,acm,mult) \
+traceline(orig, orig + vel * dt, MOVE_NORMAL, self); \
+if(trace_fraction != 1) \
+    acm += normalize(self.origin - trace_endpos) * (vlen(vel) * mult)
+
+// Hover movement support
+float  force_fromtag_power;
+float  force_fromtag_normpower;
+vector force_fromtag_origin;
+vector vehicles_force_fromtag_hover(string tag_name, float spring_length, float max_power)
+{
+    force_fromtag_origin = gettaginfo(self, gettagindex(self, tag_name));
+    v_forward  = normalize(v_forward) * -1;
+    traceline(force_fromtag_origin, force_fromtag_origin - (v_forward  * spring_length), MOVE_NORMAL, self);
+
+    force_fromtag_power = (1 - trace_fraction) * max_power;
+    force_fromtag_normpower = force_fromtag_power / max_power;
+
+    return v_forward  * force_fromtag_power;
+}
+
+// Experimental hovermode wich uses attraction/repulstion from surface insted of gravity/repulsion
+// Can possibly be use to move abt any surface (inclusing walls/celings)
+vector vehicles_force_fromtag_maglev(string tag_name, float spring_length, float max_power)
 {
 
-    if(self.dmg_time + CCVAR("_health_regen_dmgpause") < time)
-    if(self.vehicle_health < rmax)
+    force_fromtag_origin = gettaginfo(self, gettagindex(self, tag_name));
+    v_forward  = normalize(v_forward) * -1;
+    traceline(force_fromtag_origin, force_fromtag_origin - (v_forward  * spring_length), MOVE_NORMAL, self);
+
+    // TODO - this may NOT be compatible with wall/celing movement, unhardcode 0.25 (engine count multiplier)
+    if(trace_fraction == 1.0)
     {
-        self.vehicle_health = min(self.vehicle_health + CCVAR("_health_regen") * dt, rmax);
+        force_fromtag_normpower = -0.25;
+        return '0 0 -200';
+    }
 
-        if(self.owner)
-            self.owner.vehicle_health = self.vehicle_health / rmax;
+    force_fromtag_power = ((1 - trace_fraction) - trace_fraction) * max_power;
+    force_fromtag_normpower = force_fromtag_power / max_power;
+
+    return v_forward  * force_fromtag_power;
+}
+
+// Generic vehile projectile system
+void vehicles_projectile_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+{
+    // Ignore damage from oterh projectiles from my owner (dont mess up volly's)
+    if(inflictor.owner == self.owner)
+        return; 
+    
+    self.health -= damage;
+    self.velocity += force;
+    if(self.health < 1)
+    {
+        self.takedamage = DAMAGE_NO;
+        self.event_damage = SUB_Null;
+        self.think = self.use;
+        self.nextthink = time;
+    }
+
+}
+
+void vehicles_projectile_explode()
+{
+    if(self.owner && other != world)
+    {
+        if(other == self.owner.vehicle)
+            return;
+
+        if(other == self.owner.vehicle.tur_head)
+            return;
+    }
+
+       PROJECTILE_TOUCH;
+
+       self.event_damage = SUB_Null;
+    RadiusDamage (self, self.realowner, self.shot_dmg, 0, self.shot_radius, self, self.shot_force, self.totalfrags, other);
+
+    remove (self);
+}
+
+entity vehicles_projectile(string _mzlfx, string _mzlsound,
+                           vector _org, vector _vel,
+                           float _dmg, float _radi, float _force,  float _size,
+                           float _deahtype, float _projtype, float _health,
+                           float _cull, float _clianim)
+{
+    entity proj;
+
+    proj = spawn();
+
+    PROJECTILE_MAKETRIGGER(proj);
+    setorigin(proj, _org);
+
+    proj.shot_dmg         = _dmg;
+    proj.shot_radius      = _radi;
+    proj.shot_force       = _force;
+    proj.totalfrags       = _deahtype;
+    proj.solid            = SOLID_BBOX;
+    proj.movetype         = MOVETYPE_FLYMISSILE;
+    proj.flags            = FL_PROJECTILE;
+    proj.bot_dodge        = TRUE;
+    proj.bot_dodgerating  = _dmg;
+    proj.velocity         = _vel;
+    proj.touch            = vehicles_projectile_explode;
+    proj.use              = vehicles_projectile_explode;
+    proj.owner            = self;
+    proj.realowner        = self.owner;
+    proj.think            = SUB_Remove;
+    proj.nextthink        = time + 30;
+
+    if(_health)
+    {
+        proj.takedamage       = DAMAGE_AIM;
+        proj.event_damage     = vehicles_projectile_damage;
+        proj.health           = _health;
+    }
+    else
+        proj.flags           = FL_PROJECTILE | FL_NOTARGET;
+
+    if(_mzlsound)
+        sound (self, CHAN_WEAPON, _mzlsound, VOL_BASE, ATTN_NORM);
+
+    if(_mzlfx)
+        pointparticles(particleeffectnum(_mzlfx), proj.origin, proj.velocity, 1);
+
+
+    setsize (proj, '-1 -1 -1' * _size, '1 1 1' * _size);
+
+    CSQCProjectile(proj, _clianim, _projtype, _cull);
+
+    return proj;
+}
+// End generic vehile projectile system
+
+/** vehicles_spawn
+    Exetuted for all vehicles on (re)spawn.
+    Sets defaults for newly spawned units.
+**/
+void vehicles_spawn()
+{
+    dprint("Spawning vehicle: ", self.netname, "\n");
+
+    // De-own & reset
+    self.vehicle_hudmodel.viewmodelforclient = self;
+
+    self.owner              = world;
+    self.touch              = vehicles_touch;
+    self.event_damage       = vehicles_damage;
+    self.iscreature         = TRUE;
+    self.movetype           = MOVETYPE_WALK;
+    self.solid              = SOLID_SLIDEBOX;
+    self.takedamage         = DAMAGE_AIM;
+       self.deadflag           = DEAD_NO;
+    self.bot_attack         = TRUE;
+    self.flags              = FL_NOTARGET;
+    self.avelocity          = '0 0 0';
+    self.velocity           = '0 0 0';
+
+    // Reset locking
+    self.lock_strength      = 0;
+    self.lock_target        = world;
+    self.misc_bulletcounter = 0;
+
+    // Return to spawn
+    self.angles             = self.pos2;
+    setorigin(self, self.pos1 + '0 0 128');
+    // Show it
+    pointparticles(particleeffectnum("teleport"), self.origin + '0 0 64', '0 0 0', 1);
+
+    vehicles_reset_colors();
+    self.vehicle_spawn();
+}
+
+// Better way of determening whats crushable needed! (fl_crushable?)
+float vehicles_crushable(entity e)
+{
+    if(e.classname == "player")
+        return TRUE;
+
+    if(e.classname == "monster_zombie")
+        return TRUE;
+
+    return FALSE;
+}
+
+void vehicles_touch()
+{
+    // Vehicle currently in use
+    if(self.owner)
+    {
+        // Colided with world?
+        if(other == world)
+        {
+            // Apply velocity based self damage here
+        }
+        else
+        {
+            if(other.vehicle_flags & VHF_ISVEHICLE)
+            {
+                //other.velocity += self.velocity * (self.mass / other.mass);
+            }
+            else if(vehicles_crushable(other))
+            {
+                if(vlen(self.velocity) != 0)
+                    Damage(other, self, self.owner, autocvar_g_vehicles_crush_dmg, DEATH_VHCRUSH, '0 0 0', normalize(other.origin - self.origin) * autocvar_g_vehicles_crush_force);
+            }
+        }
+        return;
+    }
+
+    if(other.classname != "player")
+        return;
+
+    if(other.deadflag != DEAD_NO)
+        return;
+
+    if(other.vehicle != world)
+        return;
+
+    // Remove this when bots know how to use vehicles.
+    if (clienttype(other) != CLIENTTYPE_REAL)
+        return;
+
+    vehicles_enter();
+}
+
+void vehicles_enter()
+{
+   // Remove this when bots know how to use vehicles
+    if (clienttype(other) != CLIENTTYPE_REAL)
+        return;
+
+    if(self.phase > time)
+        return;
+
+    if(teams_matter)
+    if(self.team)
+    if(self.team != other.team)
+        return;
+
+    self.vehicle_ammo1   = 0;
+    self.vehicle_ammo2   = 0;
+    self.vehicle_reload1 = 0;
+    self.vehicle_reload2 = 0;
+    self.vehicle_energy  = 0;
+
+    self.owner          = other;
+    self.switchweapon   = other.switchweapon;
+
+    // .viewmodelforclient works better.
+    //self.vehicle_hudmodel.drawonlytoclient = self.owner;
+
+    self.vehicle_hudmodel.viewmodelforclient = self.owner;
+
+    self.event_damage         = vehicles_damage;
+    self.nextthink            = 0;
+    self.owner.angles         = self.angles;
+    self.owner.takedamage     = DAMAGE_NO;
+    self.owner.solid          = SOLID_NOT;
+    self.owner.movetype       = MOVETYPE_NOCLIP;
+    self.owner.alpha          = -1;
+    self.owner.vehicle        = self;
+    self.owner.event_damage   = SUB_Null;
+    self.owner.view_ofs       = '0 0 0';
+    self.colormap             = self.owner.colormap;
+    if(self.tur_head)
+        self.tur_head.colormap    = self.owner.colormap;
+
+    self.owner.hud            = self.hud;
+    self.owner.PlayerPhysplug = self.PlayerPhysplug;
+
+    self.owner.vehicle_ammo1    = self.vehicle_ammo1;
+    self.owner.vehicle_ammo2    = self.vehicle_ammo2;
+    self.owner.vehicle_reload1  = self.vehicle_reload1;
+    self.owner.vehicle_reload2  = self.vehicle_reload2;
+
+    // Cant do this, hides attached objects too.
+    //self.exteriormodeltoclient = self.owner;
+    //self.tur_head.exteriormodeltoclient = self.owner;
+
+    other.flags &~= FL_ONGROUND;
+    self.flags  &~= FL_ONGROUND;
+
+    self.team                 = self.owner.team;
+    self.flags               -= FL_NOTARGET;
+
+    msg_entity = other;
+    WriteByte (MSG_ONE, SVC_SETVIEWPORT);
+    WriteEntity(MSG_ONE, self.vehicle_viewport);
+
+    WriteByte (MSG_ONE, SVC_SETVIEWANGLES);
+    if(self.tur_head)
+    {
+        WriteAngle(MSG_ONE, self.tur_head.angles_x + self.angles_x); // tilt
+        WriteAngle(MSG_ONE, self.tur_head.angles_y + self.angles_y); // yaw
+        WriteAngle(MSG_ONE, 0);                                      // roll
+    }
+    else
+    {
+        WriteByte (MSG_ONE, SVC_SETVIEWANGLES);
+        WriteAngle(MSG_ONE,  self.angles_x * -1); // tilt
+        WriteAngle(MSG_ONE,  self.angles_y);      // yaw
+        WriteAngle(MSG_ONE,  0);                  // roll
+    }
+
+    vehicles_clearrturn();
+
+    CSQCVehicleSetup(self.owner, self.hud);
+
+    self.vehicle_enter();
+}
+
+/** vehicles_findgoodexit
+    Locates a valid location for the player to exit the vehicle.
+    Will first try prefer_spot, then up 100 random spots arround the vehicle
+    wich are in direct line of sight and empty enougth to hold a players bbox
+**/
+vector vehicles_findgoodexit(vector prefer_spot)
+{
+    vector exitspot;
+    float mysize;
+    
+    tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, prefer_spot, MOVE_NORMAL, self.owner);
+    if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
+        return prefer_spot;
+    
+    mysize = vlen(self.maxs - self.mins);
+    float i;
+    vector v, v2;
+    v2 = 0.5 * (self.absmin + self.absmax);
+    for(i = 0; i < 100; ++i)
+    {        
+        v = randomvec();
+        v_z = 0;
+        v = v2 + normalize(v) * mysize;
+        tracebox(v2, PL_MIN, PL_MAX, v, MOVE_NORMAL, self.owner);
+        if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
+            return v;
     }
+    
+    /*
+    exitspot = (self.origin + '0 0 48') + v_forward * mysize;
+    tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, self.owner);
+    if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
+        return exitspot;
+    
+    exitspot = (self.origin + '0 0 48') - v_forward * mysize;
+    tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, self.owner);
+    if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
+        return exitspot;
+
+    exitspot = (self.origin + '0 0 48') + v_right * mysize;
+    tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, self.owner);
+    if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
+        return exitspot;
+    
+    exitspot = (self.origin + '0 0 48') - v_right * mysize;
+    tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, self.owner);
+    if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
+        return exitspot;
+    */
+    
+    return self.origin;
+}
+
+/** vehicles_exit
+    Standarrd vehicle release fucntion.
+    custom code goes in self.vehicle_exit
+**/
+void vehicles_exit(float eject)
+{      
+       self.flags |= FL_NOTARGET;
+
+    if (self.owner)
+    {
+        msg_entity = self.owner;
+        WriteByte (MSG_ONE, SVC_SETVIEWPORT);
+        WriteEntity( MSG_ONE, self.owner);
+
+        WriteByte (MSG_ONE, SVC_SETVIEWAN