sizeincrease -80
color 0xFFFFFF 0xFFFFFF
+
+ // nade effects
+ effect nade_blue
+ trailspacing 1
+ type smoke
+ color 0x006cff 0x0600ff
+ tex 65 65
+ size 3 3
+ sizeincrease -1
+ alpha 100 100 250
+ //gravity -0.11
+ // fire
+ effect nade_blue
+ notunderwater
+ trailspacing 8
+ type smoke
+ color 0x0600ff 0x9794ff
+ tex 65 65
+ size 15 25
+ sizeincrease -10
+ alpha 30 30 150
+ // bubbles
+ effect nade_blue
+ underwater
+ trailspacing 16
+ type bubble
+ tex 62 62
+ color 0x006cff 0x0600ff
+ size 1 1
+ alpha 256 256 256
+ gravity -0.125
+ bounce 1.5
+ liquidfriction 4
+ velocityjitter 16 16 16
+
+ effect nade_red
+ trailspacing 1
+ type smoke
+ color 0xff0000 0xff3c00
+ tex 65 65
+ size 3 3
+ sizeincrease -1
+ alpha 100 100 250
+ //gravity -0.11
+ // fire
+ effect nade_red
+ notunderwater
+ trailspacing 8
+ type smoke
+ color 0xff0000 0xffa2a2
+ tex 65 65
+ size 15 25
+ sizeincrease -10
+ alpha 30 30 150
+ // bubbles
+ effect nade_red
+ underwater
+ trailspacing 16
+ type bubble
+ tex 62 62
+ color 0xff0000 0xff3c00
+ size 1 1
+ alpha 256 256 256
+ gravity -0.125
+ bounce 1.5
+ liquidfriction 4
+ velocityjitter 16 16 16
+
+ effect nade_yellow
+ trailspacing 1
+ type smoke
+ color 0xFFFF0F 0xFFFF0F
+ tex 65 65
+ size 3 3
+ sizeincrease -1
+ alpha 100 100 250
+ //gravity -0.11
+ // fire
+ effect nade_yellow
+ notunderwater
+ trailspacing 8
+ type smoke
+ color 0xFFFF0F 0xFFFF0F
+ tex 65 65
+ size 15 25
+ sizeincrease -10
+ alpha 30 30 150
+ // bubbles
+ effect nade_yellow
+ underwater
+ trailspacing 16
+ type bubble
+ tex 62 62
+ color 0xFFFF0F 0xFFFF0F
+ size 1 1
+ alpha 256 256 256
+ gravity -0.125
+ bounce 1.5
+ liquidfriction 4
+ velocityjitter 16 16 16
+
+ effect nade_pink
+ trailspacing 1
+ type smoke
+ color 0xFF0FFF 0xFF0FFF
+ tex 65 65
+ size 3 3
+ sizeincrease -1
+ alpha 100 100 250
+ //gravity -0.11
+ // fire
+ effect nade_pink
+ notunderwater
+ trailspacing 8
+ type smoke
+ color 0xFF0FFF 0xFF0FFF
+ tex 65 65
+ size 15 25
+ sizeincrease -10
+ alpha 30 30 150
+ // bubbles
+ effect nade_pink
+ underwater
+ trailspacing 16
+ type bubble
+ tex 62 62
+ color 0xFF0FFF 0xFF0FFF
+ size 1 1
+ alpha 256 256 256
+ gravity -0.125
+ bounce 1.5
+ liquidfriction 4
+ velocityjitter 16 16 16
+
+ effect nade
+ trailspacing 1
+ type smoke
+ color 0xFFFFFF 0xFFFFFF
+ tex 65 65
+ size 3 3
+ sizeincrease -1
+ alpha 100 100 250
+ //gravity -0.11
+ // fire
+ effect nade
+ notunderwater
+ trailspacing 8
+ type smoke
+ color 0xFFFFFF 0xFFFFFF
+ tex 65 65
+ size 15 25
+ sizeincrease -10
+ alpha 30 30 150
+ // bubbles
+ effect nade
+ underwater
+ trailspacing 16
+ type bubble
+ tex 62 62
+ color 0xFFFFFF 0xFFFFFF
+ size 1 1
+ alpha 256 256 256
+ gravity -0.125
+ bounce 1.5
+ liquidfriction 4
+ velocityjitter 16 16 16
+
+ effect nade_red_burn
+ trailspacing 1
+ type smoke
+ color 0xff0000 0xff3c00
+ tex 65 65
+ size 5 5
+ sizeincrease -1
+ alpha 100 100 250
+ //gravity -0.11
+ // fire
+ effect nade_red_burn
+ notunderwater
+ trailspacing 64
+ type smoke
+ color 0xff0000 0xffa2a2
+ tex 65 65
+ size 45 25
+ sizeincrease -30
+ alpha 200 200 1000
+ // bubbles
+ effect nade_red_burn
+ underwater
+ trailspacing 16
+ type bubble
+ tex 62 62
+ color 0xff0000 0xff3c00
+ size 1 1
+ alpha 256 256 256
+ gravity -0.125
+ bounce 1.5
+ liquidfriction 4
+ velocityjitter 16 16 16
+ effect nade_red_burn
+ trailspacing 16
+ type smoke
+ color 0xff0000 0xff3c00
+ tex 71 73
+ size 15 25
+ sizeincrease -40
+ rotate -180 180 20 -20
+ originjitter 2 2 2
+ velocityjitter 10 10 10
+ alpha 300 900 1500
+
+ effect nade_blue_burn
+ trailspacing 1
+ type smoke
+ color 0x006cff 0x0600ff
+ tex 65 65
+ size 5 5
+ sizeincrease -1
+ alpha 100 100 250
+ //gravity -0.11
+ // fire
+ effect nade_blue_burn
+ notunderwater
+ trailspacing 64
+ type smoke
+ color 0x0600ff 0x9794ff
+ tex 65 65
+ size 45 25
+ sizeincrease -30
+ alpha 200 200 1000
+ // bubbles
+ effect nade_blue_burn
+ underwater
+ trailspacing 16
+ type bubble
+ tex 62 62
+ color 0x006cff 0x0600ff
+ size 1 1
+ alpha 256 256 256
+ gravity -0.125
+ bounce 1.5
+ liquidfriction 4
+ velocityjitter 16 16 16
+ effect nade_blue_burn
+ trailspacing 16
+ type smoke
+ color 0x006cff 0x0600ff
+ tex 33 33
+ size 25 25
+ sizeincrease -30
+
+ effect nade_yellow_burn
+ trailspacing 1
+ type smoke
+ color 0xFFFF0F 0xFFFF0F
+ tex 65 65
+ size 5 5
+ sizeincrease -1
+ alpha 100 100 250
+ //gravity -0.11
+ // fire
+ effect nade_yellow_burn
+ notunderwater
+ trailspacing 64
+ type smoke
+ color 0xFFFF0F 0xFFFF0F
+ tex 65 65
+ size 45 25
+ sizeincrease -30
+ alpha 200 200 1000
+ // bubbles
+ effect nade_yellow_burn
+ underwater
+ trailspacing 16
+ type bubble
+ tex 62 62
+ color 0xFFFF0F 0xFFFF0F
+ size 1 1
+ alpha 256 256 256
+ gravity -0.125
+ bounce 1.5
+ liquidfriction 4
+ velocityjitter 16 16 16
+ effect nade_yellow_burn
+ trailspacing 16
+ type smoke
+ color 0xFFFF0F 0xFFFF0F
+ tex 33 33
+ size 25 25
+ sizeincrease -30
+
+ effect nade_pink_burn
+ trailspacing 1
+ type smoke
+ color 0xFF0FFF 0xFF0FFF
+ tex 65 65
+ size 5 5
+ sizeincrease -1
+ alpha 100 100 250
+ //gravity -0.11
+ // fire
+ effect nade_pink_burn
+ notunderwater
+ trailspacing 64
+ type smoke
+ color 0xFF0FFF 0xFF0FFF
+ tex 65 65
+ size 45 25
+ sizeincrease -30
+ alpha 200 200 1000
+ // bubbles
+ effect nade_pink_burn
+ underwater
+ trailspacing 16
+ type bubble
+ tex 62 62
+ color 0xFF0FFF 0xFF0FFF
+ size 1 1
+ alpha 256 256 256
+ gravity -0.125
+ bounce 1.5
+ liquidfriction 4
+ velocityjitter 16 16 16
+ effect nade_pink_burn
+ trailspacing 16
+ type smoke
+ color 0xFF0FFF 0xFF0FFF
+ tex 33 33
+ size 25 25
+ sizeincrease -30
+
+ effect nade_burn
+ trailspacing 1
+ type smoke
+ color 0xFFFFFF 0xFFFFFF
+ tex 65 65
+ size 5 5
+ sizeincrease -1
+ alpha 100 100 250
+ //gravity -0.11
+ // fire
+ effect nade_burn
+ notunderwater
+ trailspacing 64
+ type smoke
+ color 0xFFFFFF 0xFFFFFF
+ tex 65 65
+ size 45 25
+ sizeincrease -30
+ alpha 200 200 1000
+ // bubbles
+ effect nade_burn
+ underwater
+ trailspacing 16
+ type bubble
+ tex 62 62
+ color 0xFFFFFF 0xFFFFFF
+ size 1 1
+ alpha 256 256 256
+ gravity -0.125
+ bounce 1.5
+ liquidfriction 4
+ velocityjitter 16 16 16
+ effect nade_burn
+ trailspacing 16
+ type smoke
+ color 0xFFFFFF 0xFFFFFF
+ tex 33 33
+ size 25 25
+ sizeincrease -30
+
+ effect nade_blue_explode
+ countabsolute 1
+ type decal
+ tex 8 16
+ size 88 88
+ alpha 256 256 0
+ originjitter 26 26 26
+ lightradius 300
+ lightradiusfade 1500
+ lightcolor 20 20 100
+ // shockwave
+ effect nade_blue_explode
+ type smoke
+ countabsolute 1
+ tex 33 33
+ size 32 32
+ sizeincrease 1800
+ color 0x80C0FF 0x80C0FF
+ alpha 80 80 650
+ velocitymultiplier 44
+ // fire
+ effect nade_blue_explode
+ notunderwater
+ count 16
+ type smoke
+ color 0x629dff 0x0018ff
+ tex 48 55
+ size 20 24
+ sizeincrease 555
+ alpha 400 656 2000
+ airfriction 30
+ originjitter 50 50 50
+ velocityjitter 320 320 320
+ rotate -180 180 -9 9
+ // fire streched
+ effect nade_blue_explode
+ count 8
+ type spark
+ tex 48 55
+ color 0x629dff 0x0018ff
+ size 60 90
+ alpha 1500 3000 13000
+ stretchfactor 80
+ sizeincrease 40
+ velocityjitter 30 30 30
+ airfriction -9
+ //smoke
+ effect nade_blue_explode
+ type smoke
+ count 32
+ blend alpha
+ tex 0 7
+ size 60 30
+ color 0x222222 0x000000
+ alpha 128 328 390
+ rotate -180 180 2 -2
+ velocityjitter 200 200 200
+ velocityoffset 0 0 180
+ originjitter 50 50 10
+ sizeincrease 50
+ airfriction 0.04
+ gravity 0.4
+ // underwater bubbles
+ effect nade_blue_explode
+ underwater
+ count 32
+ type bubble
+ tex 62 62
+ color 0x404040 0x808080
+ size 3 6
+ alpha 128 256 64
+ gravity -0.125
+ bounce 1.5
+ liquidfriction 0.25
+ originjitter 16 16 16
+ velocityjitter 196 196 196
+ rotate 0 0 0 0
+ // bouncing sparks
+ effect nade_blue_explode
+ notunderwater
+ count 8
+ type spark
+ tex 40 40
+ color 0x006cff 0x0600ff
+ size 1 2
+ alpha 644 956 484
+ gravity 1
+ airfriction 1
+ bounce 1.6
+ liquidfriction 0.8
+ velocityoffset 0 0 80
+ originjitter 16 16 16
+ velocityjitter 424 424 624
+ // notbouncing sparks
+ effect nade_blue_explode
+ count 16
+ type spark
+ tex 40 40
+ color 0x006cff 0x0600ff
+ size 1 2
+ alpha 644 956 684
+ gravity 0.5
+ airfriction 0.7
+ liquidfriction 0.8
+ velocityoffset 0 0 80
+ originjitter 16 16 16
+ velocityjitter 424 424 624
+ // derbis
+ effect nade_blue_explode
+ notunderwater
+ count 12
+ type alphastatic
+ tex 66 68
+ color 0x6a3d25 0xcac5b4
+ size 2 6
+ alpha 644 956 684
+ gravity 1.3
+ airfriction 0.5
+ bounce 1.6
+ velocityjitter 324 324 524
+ rotate -180 180 -1000 1000
+
+ effect nade_red_explode
+ countabsolute 1
+ type decal
+ tex 8 16
+ size 88 88
+ alpha 256 256 0
+ originjitter 26 26 26
+ lightradius 300
+ lightradiusfade 1500
+ lightcolor 100 20 20
+ // shockwave
+ effect nade_red_explode
+ type smoke
+ countabsolute 1
+ tex 33 33
+ size 32 32
+ sizeincrease 2200
+ color 0xff0000 0xffa2a2
+ alpha 80 80 650
+ velocitymultiplier 44
+ // fire
+ effect nade_red_explode
+ notunderwater
+ count 16
+ type smoke
+ color 0xff0000 0xff4200
+ tex 48 55
+ size 20 24
+ sizeincrease 555
+ alpha 400 656 2000
+ airfriction 30
+ originjitter 50 50 50
+ velocityjitter 320 320 320
+ rotate -180 180 -9 9
+ // fire streched
+ effect nade_red_explode
+ count 8
+ type spark
+ tex 48 55
+ color 0xff0000 0xff4200
+ size 60 90
+ alpha 1500 3000 13000
+ stretchfactor 80
+ sizeincrease 40
+ velocityjitter 30 30 30
+ airfriction -9
+ //smoke
+ effect nade_red_explode
+ type smoke
+ count 32
+ blend alpha
+ tex 0 7
+ size 60 30
+ color 0x222222 0x000000
+ alpha 128 328 390
+ rotate -180 180 2 -2
+ velocityjitter 200 200 200
+ velocityoffset 0 0 180
+ originjitter 50 50 10
+ sizeincrease 50
+ airfriction 0.04
+ gravity 0.4
+ // underwater bubbles
+ effect nade_red_explode
+ underwater
+ count 32
+ type bubble
+ tex 62 62
+ color 0x404040 0x808080
+ size 3 6
+ alpha 128 256 64
+ gravity -0.125
+ bounce 1.5
+ liquidfriction 0.25
+ originjitter 16 16 16
+ velocityjitter 196 196 196
+ rotate 0 0 0 0
+ // bouncing sparks
+ effect nade_red_explode
+ notunderwater
+ count 8
+ type spark
+ tex 40 40
+ color 0xff0000 0xffa2a2
+ size 1 2
+ alpha 644 956 484
+ gravity 1
+ airfriction 1
+ bounce 1.6
+ liquidfriction 0.8
+ velocityoffset 0 0 80
+ originjitter 16 16 16
+ velocityjitter 424 424 624
+ // notbouncing sparks
+ effect nade_red_explode
+ count 16
+ type spark
+ tex 40 40
+ color 0xff0000 0xffa2a2
+ size 1 2
+ alpha 644 956 684
+ gravity 0.5
+ airfriction 0.7
+ liquidfriction 0.8
+ velocityoffset 0 0 80
+ originjitter 16 16 16
+ velocityjitter 424 424 624
+ // derbis
+ effect nade_red_explode
+ notunderwater
+ count 8
+ type smoke
+ tex 71 73
+ color 0xff0000 0xffa2a2
+ size 20 40
+ alpha 644 956 2500
+ originjitter 64 64 64
+ velocityjitter 324 324 324
+ rotate -180 180 -100 100
+
+ effect nade_yellow_explode
+ countabsolute 1
+ type decal
+ tex 8 16
+ size 88 88
+ alpha 256 256 0
+ originjitter 26 26 26
+ lightradius 300
+ lightradiusfade 1500
+ lightcolor 100 20 20
+ // shockwave
+ effect nade_yellow_explode
+ type smoke
+ countabsolute 1
+ tex 33 33
+ size 32 32
+ sizeincrease 2200
+ color 0xff0000 0xffa2a2
+ alpha 80 80 650
+ velocitymultiplier 44
+ // fire
+ effect nade_yellow_explode
+ notunderwater
+ count 16
+ type smoke
+ color 0xFFFF0F 0xFFFF0F
+ tex 48 55
+ size 20 24
+ sizeincrease 555
+ alpha 400 656 2000
+ airfriction 30
+ originjitter 50 50 50
+ velocityjitter 320 320 320
+ rotate -180 180 -9 9
+ // fire streched
+ effect nade_yellow_explode
+ count 8
+ type spark
+ tex 48 55
+ color 0xFFFF0F 0xFFFF0F
+ size 60 90
+ alpha 1500 3000 13000
+ stretchfactor 80
+ sizeincrease 40
+ velocityjitter 30 30 30
+ airfriction -9
+ //smoke
+ effect nade_yellow_explode
+ type smoke
+ count 32
+ blend alpha
+ tex 0 7
+ size 60 30
+ color 0x222222 0x000000
+ alpha 128 328 390
+ rotate -180 180 2 -2
+ velocityjitter 200 200 200
+ velocityoffset 0 0 180
+ originjitter 50 50 10
+ sizeincrease 50
+ airfriction 0.04
+ gravity 0.4
+ // underwater bubbles
+ effect nade_yellow_explode
+ underwater
+ count 32
+ type bubble
+ tex 62 62
+ color 0x404040 0x808080
+ size 3 6
+ alpha 128 256 64
+ gravity -0.125
+ bounce 1.5
+ liquidfriction 0.25
+ originjitter 16 16 16
+ velocityjitter 196 196 196
+ rotate 0 0 0 0
+ // bouncing sparks
+ effect nade_yellow_explode
+ notunderwater
+ count 8
+ type spark
+ tex 40 40
+ color 0xff0000 0xffa2a2
+ size 1 2
+ alpha 644 956 484
+ gravity 1
+ airfriction 1
+ bounce 1.6
+ liquidfriction 0.8
+ velocityoffset 0 0 80
+ originjitter 16 16 16
+ velocityjitter 424 424 624
+ // notbouncing sparks
+ effect nade_yellow_explode
+ count 16
+ type spark
+ tex 40 40
+ color 0xff0000 0xffa2a2
+ size 1 2
+ alpha 644 956 684
+ gravity 0.5
+ airfriction 0.7
+ liquidfriction 0.8
+ velocityoffset 0 0 80
+ originjitter 16 16 16
+ velocityjitter 424 424 624
+ // derbis
+ effect nade_yellow_explode
+ notunderwater
+ count 8
+ type smoke
+ tex 71 73
+ color 0xff0000 0xffa2a2
+ size 20 40
+ alpha 644 956 2500
+ originjitter 64 64 64
+ velocityjitter 324 324 324
+ rotate -180 180 -100 100
+
+ effect nade_pink_explode
+ countabsolute 1
+ type decal
+ tex 8 16
+ size 88 88
+ alpha 256 256 0
+ originjitter 26 26 26
+ lightradius 300
+ lightradiusfade 1500
+ lightcolor 100 20 20
+ // shockwave
+ effect nade_pink_explode
+ type smoke
+ countabsolute 1
+ tex 33 33
+ size 32 32
+ sizeincrease 2200
+ color 0xff0000 0xffa2a2
+ alpha 80 80 650
+ velocitymultiplier 44
+ // fire
+ effect nade_pink_explode
+ notunderwater
+ count 16
+ type smoke
+ color 0xFF0FFF 0xFF0FFF
+ tex 48 55
+ size 20 24
+ sizeincrease 555
+ alpha 400 656 2000
+ airfriction 30
+ originjitter 50 50 50
+ velocityjitter 320 320 320
+ rotate -180 180 -9 9
+ // fire streched
+ effect nade_pink_explode
+ count 8
+ type spark
+ tex 48 55
+ color 0xFF0FFF 0xFF0FFF
+ size 60 90
+ alpha 1500 3000 13000
+ stretchfactor 80
+ sizeincrease 40
+ velocityjitter 30 30 30
+ airfriction -9
+ //smoke
+ effect nade_pink_explode
+ type smoke
+ count 32
+ blend alpha
+ tex 0 7
+ size 60 30
+ color 0x222222 0x000000
+ alpha 128 328 390
+ rotate -180 180 2 -2
+ velocityjitter 200 200 200
+ velocityoffset 0 0 180
+ originjitter 50 50 10
+ sizeincrease 50
+ airfriction 0.04
+ gravity 0.4
+ // underwater bubbles
+ effect nade_pink_explode
+ underwater
+ count 32
+ type bubble
+ tex 62 62
+ color 0x404040 0x808080
+ size 3 6
+ alpha 128 256 64
+ gravity -0.125
+ bounce 1.5
+ liquidfriction 0.25
+ originjitter 16 16 16
+ velocityjitter 196 196 196
+ rotate 0 0 0 0
+ // bouncing sparks
+ effect nade_pink_explode
+ notunderwater
+ count 8
+ type spark
+ tex 40 40
+ color 0xff0000 0xffa2a2
+ size 1 2
+ alpha 644 956 484
+ gravity 1
+ airfriction 1
+ bounce 1.6
+ liquidfriction 0.8
+ velocityoffset 0 0 80
+ originjitter 16 16 16
+ velocityjitter 424 424 624
+ // notbouncing sparks
+ effect nade_pink_explode
+ count 16
+ type spark
+ tex 40 40
+ color 0xff0000 0xffa2a2
+ size 1 2
+ alpha 644 956 684
+ gravity 0.5
+ airfriction 0.7
+ liquidfriction 0.8
+ velocityoffset 0 0 80
+ originjitter 16 16 16
+ velocityjitter 424 424 624
+ // derbis
+ effect nade_pink_explode
+ notunderwater
+ count 8
+ type smoke
+ tex 71 73
+ color 0xff0000 0xffa2a2
+ size 20 40
+ alpha 644 956 2500
+ originjitter 64 64 64
+ velocityjitter 324 324 324
+ rotate -180 180 -100 100
+
+ effect nade_explode
+ countabsolute 1
+ type decal
+ tex 8 16
+ size 88 88
+ alpha 256 256 0
+ originjitter 26 26 26
+ lightradius 300
+ lightradiusfade 1500
+ lightcolor 100 20 20
+ // shockwave
+ effect nade_explode
+ type smoke
+ countabsolute 1
+ tex 33 33
+ size 32 32
+ sizeincrease 2200
+ color 0xff0000 0xffa2a2
+ alpha 80 80 650
+ velocitymultiplier 44
+ // fire
+ effect nade_explode
+ notunderwater
+ count 16
+ type smoke
+ color 0xFFFFFF 0xFFFFFF
+ tex 48 55
+ size 20 24
+ sizeincrease 555
+ alpha 400 656 2000
+ airfriction 30
+ originjitter 50 50 50
+ velocityjitter 320 320 320
+ rotate -180 180 -9 9
+ // fire streched
+ effect nade_explode
+ count 8
+ type spark
+ tex 48 55
+ color 0xFFFFFF 0xFFFFFF
+ size 60 90
+ alpha 1500 3000 13000
+ stretchfactor 80
+ sizeincrease 40
+ velocityjitter 30 30 30
+ airfriction -9
+ //smoke
+ effect nade_explode
+ type smoke
+ count 32
+ blend alpha
+ tex 0 7
+ size 60 30
+ color 0x222222 0x000000
+ alpha 128 328 390
+ rotate -180 180 2 -2
+ velocityjitter 200 200 200
+ velocityoffset 0 0 180
+ originjitter 50 50 10
+ sizeincrease 50
+ airfriction 0.04
+ gravity 0.4
+ // underwater bubbles
+ effect nade_explode
+ underwater
+ count 32
+ type bubble
+ tex 62 62
+ color 0x404040 0x808080
+ size 3 6
+ alpha 128 256 64
+ gravity -0.125
+ bounce 1.5
+ liquidfriction 0.25
+ originjitter 16 16 16
+ velocityjitter 196 196 196
+ rotate 0 0 0 0
+ // bouncing sparks
+ effect nade_explode
+ notunderwater
+ count 8
+ type spark
+ tex 40 40
+ color 0xff0000 0xffa2a2
+ size 1 2
+ alpha 644 956 484
+ gravity 1
+ airfriction 1
+ bounce 1.6
+ liquidfriction 0.8
+ velocityoffset 0 0 80
+ originjitter 16 16 16
+ velocityjitter 424 424 624
+ // notbouncing sparks
+ effect nade_explode
+ count 16
+ type spark
+ tex 40 40
+ color 0xff0000 0xffa2a2
+ size 1 2
+ alpha 644 956 684
+ gravity 0.5
+ airfriction 0.7
+ liquidfriction 0.8
+ velocityoffset 0 0 80
+ originjitter 16 16 16
+ velocityjitter 424 424 624
+ // derbis
+ effect nade_explode
+ notunderwater
+ count 8
+ type smoke
+ tex 71 73
+ color 0xff0000 0xffa2a2
+ size 20 40
+ alpha 644 956 2500
+ originjitter 64 64 64
+ velocityjitter 324 324 324
+ rotate -180 180 -100 100
++
+// laser_shockwave_attack
+// used nowhere in code
+effect laser_shockwave_attack
+// glow and light
+//countabsolute 1
+//type smoke
+//color 0xcc0000 0xff0000
+//tex 65 65
+//size 10 15
+//alpha 256 512 6280
+//airfriction 10
+//sizeincrease 1.5
+//stretchfactor 2
+//lightradius 200
+//lightradiusfade 2000
+//lightcolor 3 0.1 0.1
+// electricity
+effect laser_shockwave_attack
+count 1
+type spark
+color 0xb44215 0xff0000
+tex 43 43
+size 5 7
+bounce 0
+alpha 4096 4096 20000
+airfriction 1
+originjitter 2 2 2
+velocityjitter 10 10 10
+velocitymultiplier 10
+sizeincrease 1.5
+stretchfactor 2.3
+rotate -180 180 4000 -4000
+// fire
+effect laser_shockwave_attack
+count 1
+type spark
+color 0xff4200 0xff0000
+tex 8 15
+size 7 9
+bounce 0
+alpha 4096 4096 20000
+airfriction 1
+originjitter 2 2 2
+velocityjitter 10 10 10
+velocitymultiplier 10
+sizeincrease 1.5
+stretchfactor 2
+
+// new_laser_impact
+// used nowhere in code
+// decal
+effect new_laser_impact
+countabsolute 1
+type decal
+tex 8 16
+size 72 72
+alpha 256 256 0
+originjitter 2 2 2
+// flare effect
+//effect new_laser_impact
+//countabsolute 1
+//type static
+//tex 39 39
+//color 0xFF2010 0xFF2010
+//alpha 256 256 1024
+//size 24 24
+// sparks that rapidly expand and rapidly slow down to form an interesting spherical effect
+effect new_laser_impact
+count 128
+type spark
+color 0x800000 0xFF8020
+alpha 256 256 1024
+size 4 4
+bounce 1.5
+gravity 0.5
+airfriction 1
+liquidfriction 1
+originjitter 20 20 20
+velocityjitter 256 256 256
//draw either the old v2.3 beam or the new beam
charge = sqrt(charge); // divide evenly among trail spacing and alpha
- particles_alphamin = particles_alphamax = charge;
+ particles_alphamin = particles_alphamax = particles_fade = charge;
+
if (autocvar_cl_particles_oldnexbeam && (getstati(STAT_ALLOW_OLDNEXBEAM) || isdemo()))
- WarpZone_TrailParticles_WithMultiplier(world, particleeffectnum("TE_TEI_G3"), shotorg, endpos, charge, 1);
+ WarpZone_TrailParticles_WithMultiplier(world, particleeffectnum("TE_TEI_G3"), shotorg, endpos, 1, PARTICLES_USEALPHA | PARTICLES_USEFADE);
else
- WarpZone_TrailParticles_WithMultiplier(world, particleeffectnum("nex_beam"), shotorg, endpos, charge, 1);
+ WarpZone_TrailParticles_WithMultiplier(world, particleeffectnum("nex_beam"), shotorg, endpos, 1, PARTICLES_USEALPHA | PARTICLES_USEFADE);
}
+
+.vector sw_shotorg;
+.vector sw_endpos;
+.float sw_spread_max;
+.float sw_spread_min;
+.float sw_time;
+
+void Draw_Shockwave()
+{
+ float a = bound(0, (0.5 - ((time - self.sw_time) / 0.4)), 0.5);
+
+ if not(a) { remove(self); }
+
+ vector deviation, angle;
+
+ vector sw_color = getcsqcplayercolor(self.sv_entnum); // GetTeamRGB(GetPlayerColor(self.sv_entnum));
+
+ vector first_min_end = '0 0 0', prev_min_end = '0 0 0', new_min_end = '0 0 0';
+ vector first_max_end = '0 0 0', prev_max_end = '0 0 0', new_max_end = '0 0 0';
+
+ float new_max_dist, new_min_dist;
+
+ vector shotdir = normalize(self.sw_endpos - self.sw_shotorg);
+ vectorvectors(shotdir);
+ vector right = v_right;
+ vector up = v_up;
+
+ float counter, dist_before_normal = 200, shots = 20;
+
+ vector min_end = ((self.sw_shotorg + (shotdir * dist_before_normal)) + (up * self.sw_spread_min));
+ vector max_end = (self.sw_endpos + (up * self.sw_spread_max));
+
+ float spread_to_min = vlen(normalize(min_end - self.sw_shotorg) - shotdir);
+ float spread_to_max = vlen(normalize(max_end - min_end) - shotdir);
+
+ for(counter = 0; counter < shots; ++counter)
+ {
+ // perfect circle effect lines
+ angle = '0 0 0';
+ makevectors('0 360 0' * (0.75 + (counter - 0.5) / shots));
+ angle_y = v_forward_x;
+ angle_z = v_forward_y;
+
+ // first do the spread_to_min effect
+ deviation = angle * spread_to_min;
+ deviation = ((shotdir + (right * deviation_y) + (up * deviation_z)));
+ new_min_dist = dist_before_normal;
+ new_min_end = (self.sw_shotorg + (deviation * new_min_dist));
+ //te_lightning2(world, new_min_end, self.sw_shotorg);
+
+ // then calculate spread_to_max effect
+ deviation = angle * spread_to_max;
+ deviation = ((shotdir + (right * deviation_y) + (up * deviation_z)));
+ new_max_dist = vlen(new_min_end - self.sw_endpos);
+ new_max_end = (new_min_end + (deviation * new_max_dist));
+ //te_lightning2(world, new_end, prev_min_end);
+
+
+ if(counter == 0)
+ {
+ first_min_end = new_min_end;
+ first_max_end = new_max_end;
+ }
+
+ if(counter >= 1)
+ {
+ R_BeginPolygon("", DRAWFLAG_NORMAL);
+ R_PolygonVertex(prev_min_end, '0 0 0', sw_color, a);
+ R_PolygonVertex(new_min_end, '0 0 0', sw_color, a);
+ R_PolygonVertex(self.sw_shotorg, '0 0 0', sw_color, a);
+ R_EndPolygon();
+
+ R_BeginPolygon("", DRAWFLAG_NORMAL);
+ R_PolygonVertex(new_min_end, '0 0 0', sw_color, a);
+ R_PolygonVertex(prev_min_end, '0 0 0', sw_color, a);
+ R_PolygonVertex(prev_max_end, '0 0 0', sw_color, a);
+ R_PolygonVertex(new_max_end, '0 0 0', sw_color, a);
+ R_EndPolygon();
+ }
+
+ prev_min_end = new_min_end;
+ prev_max_end = new_max_end;
+
+ if((counter + 1) == shots)
+ {
+ R_BeginPolygon("", DRAWFLAG_NORMAL);
+ R_PolygonVertex(prev_min_end, '0 0 0', sw_color, a);
+ R_PolygonVertex(first_min_end, '0 0 0', sw_color, a);
+ R_PolygonVertex(self.sw_shotorg, '0 0 0', sw_color, a);
+ R_EndPolygon();
+
+ R_BeginPolygon("", DRAWFLAG_NORMAL);
+ R_PolygonVertex(first_min_end, '0 0 0', sw_color, a);
+ R_PolygonVertex(prev_min_end, '0 0 0', sw_color, a);
+ R_PolygonVertex(prev_max_end, '0 0 0', sw_color, a);
+ R_PolygonVertex(first_max_end, '0 0 0', sw_color, a);
+ R_EndPolygon();
+ }
+ }
+}
+
+void Net_ReadShockwaveParticle()
+{
+ entity shockwave;
+ shockwave = spawn();
+ shockwave.draw = Draw_Shockwave;
+
+ shockwave.sw_shotorg_x = ReadCoord(); shockwave.sw_shotorg_y = ReadCoord(); shockwave.sw_shotorg_z = ReadCoord();
+ shockwave.sw_endpos_x = ReadCoord(); shockwave.sw_endpos_y = ReadCoord(); shockwave.sw_endpos_z = ReadCoord();
+
+ shockwave.sw_spread_max = ReadByte();
+ shockwave.sw_spread_min = ReadByte();
+
+ shockwave.sv_entnum = ReadByte();
+
+ shockwave.sw_time = time;
+}
+
--- /dev/null
- particles_alphamin = particles_alphamax = sqrt(self.alpha);
- boxparticles(self.traileffect, self, from, to, self.velocity, self.velocity, sqrt(self.alpha), PARTICLES_USEALPHA);
+.vector iorigin1, iorigin2;
+.float spawntime;
+.vector trail_oldorigin;
+.float trail_oldtime;
+.float fade_time, fade_rate;
+
+void SUB_Stop()
+{
+ self.move_velocity = self.move_avelocity = '0 0 0';
+ self.move_movetype = MOVETYPE_NONE;
+}
+
+.float alphamod;
+.float count; // set if clientside projectile
+.float cnt; // sound index
+.float gravity;
+.float snd_looping;
+.float silent;
+
+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;
+ self.trail_oldtime = time;
+
+ // force the effect even for stationary firemine
+ if(self.cnt == PROJECTILE_FIREMINE)
+ if(from == to)
+ from_z += 1;
+
+ if (self.traileffect)
+ {
++ particles_alphamin = particles_alphamax = particles_fade = sqrt(self.alpha);
++ boxparticles(self.traileffect, self, from, to, self.velocity, self.velocity, 1, PARTICLES_USEALPHA | PARTICLES_USEFADE | PARTICLES_DRAWASTRAIL);
+ }
+}
+
+void Projectile_Draw()
+{
+ vector rot;
+ vector trailorigin;
+ float f;
+ float drawn;
+ float t;
+ float a;
+
+ f = self.move_flags;
+
+ if(self.count & 0x80)
+ {
+ //self.move_flags &~= FL_ONGROUND;
+ if(self.move_movetype == MOVETYPE_NONE || self.move_movetype == MOVETYPE_FLY)
+ Movetype_Physics_NoMatchServer();
+ // the trivial movetypes do not have to match the
+ // server's ticrate as they are ticrate independent
+ // NOTE: this assumption is only true if MOVETYPE_FLY
+ // projectiles detonate on impact. If they continue
+ // moving, we might still be ticrate dependent.
+ else
+ Movetype_Physics_MatchServer(autocvar_cl_projectiles_sloppy);
+ if(!(self.move_flags & FL_ONGROUND))
+ if(self.velocity != '0 0 0')
+ self.move_angles = self.angles = vectoangles(self.velocity);
+ }
+ else
+ {
+ InterpolateOrigin_Do();
+ }
+
+ if(self.count & 0x80)
+ {
+ drawn = (time >= self.spawntime - 0.02);
+ t = max(time, self.spawntime);
+ }
+ else
+ {
+ drawn = (self.iflags & IFLAG_VALID);
+ t = time;
+ }
+
+ if(!(f & FL_ONGROUND))
+ {
+ rot = '0 0 0';
+ switch(self.cnt)
+ {
+ /*
+ case PROJECTILE_GRENADE:
+ rot = '-2000 0 0'; // forward
+ break;
+ */
+ case PROJECTILE_GRENADE_BOUNCING:
+ rot = '0 -1000 0'; // sideways
+ break;
++ case PROJECTILE_NADE_RED_BURN:
++ case PROJECTILE_NADE_RED:
++ case PROJECTILE_NADE_BLUE_BURN:
++ case PROJECTILE_NADE_BLUE:
++ case PROJECTILE_NADE_YELLOW_BURN:
++ case PROJECTILE_NADE_YELLOW:
++ case PROJECTILE_NADE_PINK_BURN:
++ case PROJECTILE_NADE_PINK:
++ case PROJECTILE_NADE_BURN:
++ case PROJECTILE_NADE:
++ rot = self.avelocity;
++ break;
+ case PROJECTILE_HOOKBOMB:
+ rot = '1000 0 0'; // forward
+ break;
+ default:
+ break;
+ }
+ self.angles = AnglesTransform_ToAngles(AnglesTransform_Multiply(AnglesTransform_FromAngles(self.angles), rot * (t - self.spawntime)));
+ }
+
+ vector ang;
+ ang = self.angles;
+ ang_x = -ang_x;
+ makevectors(ang);
+
+ a = 1 - (time - self.fade_time) * self.fade_rate;
+ self.alpha = bound(0, self.alphamod * a, 1);
+ if(self.alpha <= 0)
+ drawn = 0;
+ self.renderflags = 0;
+
+ trailorigin = self.origin;
+ switch(self.cnt)
+ {
++ case PROJECTILE_NADE_RED_BURN:
++ case PROJECTILE_NADE_RED:
++ case PROJECTILE_NADE_BLUE_BURN:
++ case PROJECTILE_NADE_BLUE:
++ case PROJECTILE_NADE_YELLOW_BURN:
++ case PROJECTILE_NADE_YELLOW:
++ case PROJECTILE_NADE_PINK_BURN:
++ case PROJECTILE_NADE_PINK:
++ case PROJECTILE_NADE_BURN:
++ case PROJECTILE_NADE:
++ trailorigin += v_up * 4;
++ break;
+ case PROJECTILE_GRENADE:
+ case PROJECTILE_GRENADE_BOUNCING:
+ trailorigin += v_right * 1 + v_forward * -10;
+ break;
+ default:
+ break;
+ }
+ if(drawn)
+ Projectile_DrawTrail(trailorigin);
+ else
+ Projectile_ResetTrail(trailorigin);
+
+ self.drawmask = 0;
+
+ if(!drawn)
+ return;
+
+ switch(self.cnt)
+ {
+ case PROJECTILE_BULLET_GLOWING:
+ case PROJECTILE_BULLET_GLOWING_TRACER:
+ adddynamiclight(self.origin, 50 * a, '1 1 0');
+ break;
+ default:
+ break;
+ }
+
+ self.drawmask = MASK_NORMAL;
+}
+
+void loopsound(entity e, float ch, string samp, float vol, float attn)
+{
+ if(self.silent)
+ return;
+
+ sound(e, ch, samp, vol, attn);
+ e.snd_looping = ch;
+}
+
+void Ent_RemoveProjectile()
+{
+ if(self.count & 0x80)
+ {
+ tracebox(self.origin, self.mins, self.maxs, self.origin + self.velocity * 0.05, MOVE_NORMAL, self);
+ Projectile_DrawTrail(trace_endpos);
+ }
+}
+
+void Ent_Projectile()
+{
+ float f;
+
+ // projectile properties:
+ // kind (interpolated, or clientside)
+ //
+ // modelindex
+ // origin
+ // scale
+ // if clientside:
+ // velocity
+ // gravity
+ // soundindex (hardcoded list)
+ // 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 | IFLAG_ORIGIN;
+ self.solid = SOLID_TRIGGER;
+ //self.effects = EF_NOMODELFLAGS;
+
+ // this should make collisions with bmodels more exact, but it leads to
+ // projectiles no longer being able to lie on a bmodel
+ self.move_nomonsters = MOVE_WORLDONLY;
+ if(f & 0x40)
+ self.move_flags |= FL_ONGROUND;
+ else
+ self.move_flags &~= FL_ONGROUND;
+
+ if(!self.move_time)
+ {
+ // for some unknown reason, we don't need to care for
+ // sv_gameplayfix_delayprojectiles here.
+ self.move_time = time;
+ self.spawntime = time;
+ }
+ else
+ self.move_time = max(self.move_time, time);
+
+ if(!(self.count & 0x80))
+ InterpolateOrigin_Undo();
+
+ if(f & 1)
+ {
+ self.origin_x = ReadCoord();
+ self.origin_y = ReadCoord();
+ self.origin_z = ReadCoord();
+ setorigin(self, self.origin);
+ if(self.count & 0x80)
+ {
+ self.velocity_x = ReadCoord();
+ self.velocity_y = ReadCoord();
+ self.velocity_z = ReadCoord();
+ if(f & 0x10)
+ self.gravity = ReadCoord();
+ else
+ self.gravity = 0; // none
+ self.move_origin = self.origin;
+ self.move_velocity = self.velocity;
+ }
+
+ if(time == self.spawntime || (self.count & 0x80) || (f & 0x08))
+ {
+ self.trail_oldorigin = self.origin;
+ if(!(self.count & 0x80))
+ InterpolateOrigin_Reset();
+ }
+
+ if(f & 0x20)
+ {
+ self.fade_time = time + ReadByte() * ticrate;
+ self.fade_rate = 1 / (ReadByte() * ticrate);
+ }
+ else
+ {
+ self.fade_time = 0;
+ self.fade_rate = 0;
+ }
+ }
+
+ if(f & 2)
+ {
+ self.cnt = ReadByte();
+
+ self.silent = (self.cnt & 0x80);
+ self.cnt = (self.cnt & 0x7F);
+
+ self.scale = 1;
+ self.traileffect = 0;
+ switch(self.cnt)
+ {
+ case PROJECTILE_ELECTRO: setmodel(self, "models/ebomb.mdl");self.traileffect = particleeffectnum("TR_NEXUIZPLASMA"); break;
+ case PROJECTILE_ROCKET: setmodel(self, "models/rocket.md3");self.traileffect = particleeffectnum("TR_ROCKET"); self.scale = 2; break;
+ case PROJECTILE_BULLET: setmodel(self, "models/tracer.mdl");self.traileffect = particleeffectnum("tr_bullet"); break;
+ case PROJECTILE_BULLET_GLOWING: setmodel(self, "models/tracer.mdl");self.traileffect = particleeffectnum("tr_rifle_weak"); break;
+ case PROJECTILE_BULLET_GLOWING_TRACER: setmodel(self, "models/tracer.mdl");self.traileffect = particleeffectnum("tr_rifle"); break;
+ case PROJECTILE_CRYLINK: setmodel(self, "models/plasmatrail.mdl");self.traileffect = particleeffectnum("TR_CRYLINKPLASMA"); break;
+ case PROJECTILE_CRYLINK_BOUNCING: setmodel(self, "models/plasmatrail.mdl");self.traileffect = particleeffectnum("TR_CRYLINKPLASMA"); break;
+ case PROJECTILE_ELECTRO_BEAM: setmodel(self, "models/elaser.mdl");self.traileffect = particleeffectnum("TR_NEXUIZPLASMA"); break;
+ case PROJECTILE_GRENADE: setmodel(self, "models/grenademodel.md3");self.traileffect = particleeffectnum("TR_GRENADE"); break;
+ case PROJECTILE_GRENADE_BOUNCING: setmodel(self, "models/grenademodel.md3");self.traileffect = particleeffectnum("TR_GRENADE"); break;
+ case PROJECTILE_MINE: setmodel(self, "models/mine.md3");self.traileffect = particleeffectnum("TR_GRENADE"); break;
+ case PROJECTILE_LASER: setmodel(self, "models/laser.mdl");self.traileffect = particleeffectnum(""); break;
+ case PROJECTILE_HLAC: setmodel(self, "models/hlac_bullet.md3");self.traileffect = particleeffectnum(""); break;
+ case PROJECTILE_PORTO_RED: setmodel(self, "models/grenademodel.md3");self.traileffect = particleeffectnum("TR_WIZSPIKE"); self.scale = 4; break;
+ case PROJECTILE_PORTO_BLUE: setmodel(self, "models/grenademodel.md3");self.traileffect = particleeffectnum("TR_WIZSPIKE"); self.scale = 4; break;
+ case PROJECTILE_HOOKBOMB: setmodel(self, "models/grenademodel.md3");self.traileffect = particleeffectnum("TR_KNIGHTSPIKE"); break;
+ case PROJECTILE_HAGAR: setmodel(self, "models/hagarmissile.mdl");self.traileffect = particleeffectnum("tr_hagar"); self.scale = 0.75; break;
+ case PROJECTILE_HAGAR_BOUNCING: setmodel(self, "models/hagarmissile.mdl");self.traileffect = particleeffectnum("tr_hagar"); self.scale = 0.75; break;
+ case PROJECTILE_FIREBALL: self.model = ""; self.modelindex = 0; self.traileffect = particleeffectnum("fireball"); break; // particle effect is good enough
+ case PROJECTILE_FIREMINE: self.model = ""; self.modelindex = 0; self.traileffect = particleeffectnum("firemine"); break; // particle effect is good enough
+ 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;
+
+ case PROJECTILE_BUMBLE_GUN: setmodel(self, "models/elaser.mdl");self.traileffect = particleeffectnum("TR_NEXUIZPLASMA"); break;
+ case PROJECTILE_BUMBLE_BEAM: setmodel(self, "models/elaser.mdl");self.traileffect = particleeffectnum("TR_NEXUIZPLASMA"); break;
++
++ case PROJECTILE_NADE_RED: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_red"); break;
++ case PROJECTILE_NADE_RED_BURN: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_red_burn"); break;
++ case PROJECTILE_NADE_BLUE: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_blue"); break;
++ case PROJECTILE_NADE_BLUE_BURN: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_blue_burn"); break;
++ case PROJECTILE_NADE_YELLOW: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_yellow"); break;
++ case PROJECTILE_NADE_YELLOW_BURN: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_yellow_burn"); break;
++ case PROJECTILE_NADE_PINK: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_pink"); break;
++ case PROJECTILE_NADE_PINK_BURN: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_pink_burn"); break;
++ case PROJECTILE_NADE: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade"); break;
++ case PROJECTILE_NADE_BURN: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_burn"); break;
+
+ default:
+ error("Received invalid CSQC projectile, can't work with this!");
+ break;
+ }
+
+ self.mins = '0 0 0';
+ self.maxs = '0 0 0';
+ self.colormod = '0 0 0';
+ self.move_touch = SUB_Stop;
+ self.move_movetype = MOVETYPE_TOSS;
+ self.alphamod = 1;
+
+ switch(self.cnt)
+ {
+ case PROJECTILE_ELECTRO:
+ // only new engines support sound moving with object
+ loopsound(self, CH_SHOTS_SINGLE, "weapons/electro_fly.wav", VOL_BASE, ATTN_NORM);
+ self.mins = '0 0 -4';
+ self.maxs = '0 0 -4';
+ self.move_movetype = MOVETYPE_BOUNCE;
+ self.move_touch = func_null;
+ self.move_bounce_factor = g_balance_electro_secondary_bouncefactor;
+ self.move_bounce_stopspeed = g_balance_electro_secondary_bouncestop;
+ break;
+ case PROJECTILE_ROCKET:
+ loopsound(self, CH_SHOTS_SINGLE, "weapons/rocket_fly.wav", VOL_BASE, ATTN_NORM);
+ self.mins = '-3 -3 -3';
+ self.maxs = '3 3 3';
+ break;
+ case PROJECTILE_GRENADE:
+ self.mins = '-3 -3 -3';
+ self.maxs = '3 3 3';
+ break;
++ case PROJECTILE_NADE_RED_BURN:
++ case PROJECTILE_NADE_RED:
++ case PROJECTILE_NADE_BLUE_BURN:
++ case PROJECTILE_NADE_BLUE:
++ self.mins = '-3 -3 -3';
++ self.maxs = '3 3 3';
++ self.move_movetype = MOVETYPE_BOUNCE;
++ self.move_touch = func_null;
++ self.scale = 1.5;
++ self.avelocity = randomvec() * 720;
++ break;
+ case PROJECTILE_GRENADE_BOUNCING:
+ self.mins = '-3 -3 -3';
+ self.maxs = '3 3 3';
+ self.move_movetype = MOVETYPE_BOUNCE;
+ self.move_touch = func_null;
+ self.move_bounce_factor = g_balance_grenadelauncher_bouncefactor;
+ self.move_bounce_stopspeed = g_balance_grenadelauncher_bouncestop;
+ break;
++ case PROJECTILE_NADE_RED_BURN:
++ case PROJECTILE_NADE_RED:
++ case PROJECTILE_NADE_BLUE_BURN:
++ case PROJECTILE_NADE_BLUE:
++ case PROJECTILE_NADE_YELLOW_BURN:
++ case PROJECTILE_NADE_YELLOW:
++ case PROJECTILE_NADE_PINK_BURN:
++ case PROJECTILE_NADE_PINK:
++ case PROJECTILE_NADE_BURN:
++ case PROJECTILE_NADE:
++ self.mins = '-16 -16 -16';
++ self.maxs = '16 16 16';
++ self.move_movetype = MOVETYPE_BOUNCE;
++ self.move_touch = func_null;
++ self.scale = 1.5;
++ self.avelocity = randomvec() * 720;
++ break;
+ case PROJECTILE_MINE:
+ self.mins = '-4 -4 -4';
+ self.maxs = '4 4 4';
+ break;
+ case PROJECTILE_PORTO_RED:
+ self.colormod = '2 1 1';
+ self.alphamod = 0.5;
+ self.move_movetype = MOVETYPE_BOUNCE;
+ self.move_touch = func_null;
+ break;
+ case PROJECTILE_PORTO_BLUE:
+ self.colormod = '1 1 2';
+ self.alphamod = 0.5;
+ self.move_movetype = MOVETYPE_BOUNCE;
+ self.move_touch = func_null;
+ break;
+ case PROJECTILE_HAGAR_BOUNCING:
+ self.move_movetype = MOVETYPE_BOUNCE;
+ self.move_touch = func_null;
+ break;
+ case PROJECTILE_CRYLINK_BOUNCING:
+ self.move_movetype = MOVETYPE_BOUNCE;
+ self.move_touch = func_null;
+ break;
+ case PROJECTILE_FIREBALL:
+ loopsound(self, CH_SHOTS_SINGLE, "weapons/fireball_fly2.wav", VOL_BASE, ATTN_NORM);
+ self.mins = '-16 -16 -16';
+ self.maxs = '16 16 16';
+ break;
+ case PROJECTILE_FIREMINE:
+ loopsound(self, CH_SHOTS_SINGLE, "weapons/fireball_fly.wav", VOL_BASE, ATTN_NORM);
+ self.move_movetype = MOVETYPE_BOUNCE;
+ self.move_touch = func_null;
+ self.mins = '-4 -4 -4';
+ self.maxs = '4 4 4';
+ break;
+ case PROJECTILE_TAG:
+ self.mins = '-2 -2 -2';
+ self.maxs = '2 2 2';
+ break;
+ case PROJECTILE_FLAC:
+ self.mins = '-2 -2 -2';
+ self.maxs = '2 2 2';
+ break;
+ case PROJECTILE_SEEKER:
+ loopsound(self, CH_SHOTS_SINGLE, "weapons/tag_rocket_fly.wav", VOL_BASE, ATTN_NORM);
+ 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, CH_SHOTS_SINGLE, "weapons/tag_rocket_fly.wav", VOL_BASE, ATTN_NORM);
+ break;
+ case PROJECTILE_WAKIROCKET:
+ loopsound(self, CH_SHOTS_SINGLE, "weapons/tag_rocket_fly.wav", VOL_BASE, ATTN_NORM);
+ break;
+ /*
+ case PROJECTILE_WAKICANNON:
+ break;
+ case PROJECTILE_BUMBLE_GUN:
+ // only new engines support sound moving with object
+ loopsound(self, CH_SHOTS_SINGLE, "weapons/electro_fly.wav", VOL_BASE, ATTN_NORM);
+ self.mins = '0 0 -4';
+ self.maxs = '0 0 -4';
+ self.move_movetype = MOVETYPE_BOUNCE;
+ self.move_touch = func_null;
+ self.move_bounce_factor = g_balance_electro_secondary_bouncefactor;
+ self.move_bounce_stopspeed = g_balance_electro_secondary_bouncestop;
+ break;
+ */
+ default:
+ break;
+ }
+ setsize(self, self.mins, self.maxs);
+ }
+
+ if(self.gravity)
+ {
+ if(self.move_movetype == MOVETYPE_FLY)
+ self.move_movetype = MOVETYPE_TOSS;
+ if(self.move_movetype == MOVETYPE_BOUNCEMISSILE)
+ self.move_movetype = MOVETYPE_BOUNCE;
+ }
+ else
+ {
+ if(self.move_movetype == MOVETYPE_TOSS)
+ self.move_movetype = MOVETYPE_FLY;
+ if(self.move_movetype == MOVETYPE_BOUNCE)
+ self.move_movetype = MOVETYPE_BOUNCEMISSILE;
+ }
+
+ if(!(self.count & 0x80))
+ InterpolateOrigin_Note();
+
+ self.draw = Projectile_Draw;
+ self.entremove = Ent_RemoveProjectile;
+}
+
+void Projectile_Precache()
+{
+ precache_model("models/ebomb.mdl");
+ precache_model("models/elaser.mdl");
+ precache_model("models/grenademodel.md3");
+ precache_model("models/mine.md3");
+ precache_model("models/hagarmissile.mdl");
+ precache_model("models/hlac_bullet.md3");
+ precache_model("models/laser.mdl");
+ precache_model("models/plasmatrail.mdl");
+ precache_model("models/rocket.md3");
+ precache_model("models/tagrocket.md3");
+ precache_model("models/tracer.mdl");
++
++ precache_model("models/weapons/v_ok_grenade.md3");
+
+ 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");
+
+}
--- /dev/null
+// switch between weapons
+void Send_WeaponComplain(entity e, float wpn, string wpnname, float type)
+{
+ msg_entity = e;
+ WriteByte(MSG_ONE, SVC_TEMPENTITY);
+ WriteByte(MSG_ONE, TE_CSQC_WEAPONCOMPLAIN);
+ WriteByte(MSG_ONE, wpn);
+ WriteString(MSG_ONE, wpnname);
+ WriteByte(MSG_ONE, type);
+}
+
+float client_hasweapon(entity cl, float wpn, float andammo, float complain)
+{
+ float f;
+ entity oldself;
+
+ if(time < self.hasweapon_complain_spam)
+ complain = 0;
++
++ if(wpn == WEP_HOOK && !g_grappling_hook && autocvar_g_nades && !WEPSET_CONTAINS_EW(cl, wpn) && !WEPSET_CONTAINS_AW(weaponsInMap, wpn))
++ complain = 0;
++
+ if(complain)
+ self.hasweapon_complain_spam = time + 0.2;
+
+ if (wpn < WEP_FIRST || wpn > WEP_LAST)
+ {
+ if (complain)
+ sprint(self, "Invalid weapon\n");
+ return FALSE;
+ }
+ if (WEPSET_CONTAINS_EW(cl, wpn))
+ {
+ if (andammo)
+ {
+ if(cl.items & IT_UNLIMITED_WEAPON_AMMO)
+ {
+ f = 1;
+ }
+ else
+ {
+ oldself = self;
+ self = cl;
+ f = WEP_ACTION(wpn, WR_CHECKAMMO1);
+ f = f + WEP_ACTION(wpn, WR_CHECKAMMO2);
+
+ // always allow selecting the Mine Layer if we placed mines, so that we can detonate them
+ entity mine;
+ if(wpn == WEP_MINE_LAYER)
+ for(mine = world; (mine = find(mine, classname, "mine")); ) if(mine.owner == self)
+ f = 1;
+
+ self = oldself;
+ }
+ if (!f)
+ {
+ if (complain)
+ if(IS_REAL_CLIENT(cl))
+ {
+ play2(cl, "weapons/unavailable.wav");
+ Send_WeaponComplain (cl, wpn, W_Name(wpn), 0);
+ }
+ return FALSE;
+ }
+ }
+ return TRUE;
+ }
+ if (complain)
+ {
+ // DRESK - 3/16/07
+ // Report Proper Weapon Status / Modified Weapon Ownership Message
+ if (WEPSET_CONTAINS_AW(weaponsInMap, wpn))
+ {
+ Send_WeaponComplain(cl, wpn, W_Name(wpn), 1);
+
+ if(autocvar_g_showweaponspawns)
+ {
+ entity e;
+ string s;
+
+ e = get_weaponinfo(wpn);
+ s = e.model2;
+
+ for(e = world; (e = findfloat(e, weapon, wpn)); )
+ {
+ if(e.classname == "droppedweapon")
+ continue;
+ if not(e.flags & FL_ITEM)
+ continue;
+ WaypointSprite_Spawn(
+ s,
+ 1, 0,
+ world, e.origin,
+ self, 0,
+ world, enemy,
+ 0,
+ RADARICON_NONE, '0 0 0'
+ );
+ }
+ }
+ }
+ else
+ {
+ Send_WeaponComplain (cl, wpn, W_Name(wpn), 2);
+ }
+
+ play2(cl, "weapons/unavailable.wav");
+ }
+ return FALSE;
+}
+
+float W_GetCycleWeapon(entity pl, string weaponorder, float dir, float imp, float complain, float skipmissing)
+{
+ // We cannot tokenize in this function, as GiveItems calls this
+ // function. Thus we must use car/cdr.
+ float weaponwant, first_valid, prev_valid, switchtonext, switchtolast, c;
+ string rest;
+ switchtonext = switchtolast = 0;
+ first_valid = prev_valid = 0;
+ float weaponcur;
+
+ if(skipmissing || pl.selectweapon == 0)
+ weaponcur = pl.switchweapon;
+ else
+ weaponcur = pl.selectweapon;
+
+ if(dir == 0)
+ switchtonext = 1;
+
+ c = 0;
+
+ rest = weaponorder;
+ while(rest != "")
+ {
+ weaponwant = stof(car(rest)); rest = cdr(rest);
+ if(imp >= 0)
+ if((get_weaponinfo(weaponwant)).impulse != imp)
+ continue;
+
+ ++c;
+
+ if(!skipmissing || client_hasweapon(pl, weaponwant, TRUE, FALSE))
+ {
+ if(switchtonext)
+ return weaponwant;
+ if(!first_valid)
+ first_valid = weaponwant;
+ if(weaponwant == weaponcur)
+ {
+ if(dir >= 0)
+ switchtonext = 1;
+ else if(prev_valid)
+ return prev_valid;
+ else
+ switchtolast = 1;
+ }
+ prev_valid = weaponwant;
+ }
+ }
+ if(first_valid)
+ {
+ if(switchtolast)
+ return prev_valid;
+ else
+ return first_valid;
+ }
+ // complain (but only for one weapon on the button that has been pressed)
+ if(complain)
+ {
+ self.weaponcomplainindex += 1;
+ c = mod(self.weaponcomplainindex, c) + 1;
+ rest = weaponorder;
+ while(rest != "")
+ {
+ weaponwant = stof(car(rest)); rest = cdr(rest);
+ if(imp >= 0)
+ if((get_weaponinfo(weaponwant)).impulse != imp)
+ continue;
+
+ --c;
+ if(c == 0)
+ {
+ client_hasweapon(pl, weaponwant, TRUE, TRUE);
+ break;
+ }
+ }
+ }
+ return 0;
+}
+
+void W_SwitchWeapon_Force(entity e, float w)
+{
+ e.cnt = e.switchweapon;
+ e.switchweapon = w;
+ e.selectweapon = w;
+}
+
+// perform weapon to attack (weaponstate and attack_finished check is here)
+void W_SwitchToOtherWeapon(entity pl)
+{
+ // hack to ensure it switches to an OTHER weapon (in case the other fire mode still has ammo, we want that anyway)
+ float w, ww;
+ w = pl.weapon;
+ if(WEPSET_CONTAINS_EW(pl, w))
+ {
+ WEPSET_ANDNOT_EW(pl, w);
+ ww = w_getbestweapon(pl);
+ WEPSET_OR_EW(pl, w);
+ }
+ else
+ ww = w_getbestweapon(pl);
+ if(ww)
+ W_SwitchWeapon_Force(pl, ww);
+}
+
+void W_SwitchWeapon(float imp)
+{
+ if (self.switchweapon != imp)
+ {
+ if (client_hasweapon(self, imp, TRUE, TRUE))
+ W_SwitchWeapon_Force(self, imp);
+ else
+ self.selectweapon = imp; // update selectweapon ANYWAY
+ }
+ else { WEP_ACTION(self.weapon, WR_RELOAD); }
+}
+
+void W_CycleWeapon(string weaponorder, float dir)
+{
+ float w;
+ w = W_GetCycleWeapon(self, weaponorder, dir, -1, 1, TRUE);
+ if(w > 0)
+ W_SwitchWeapon(w);
+}
+
+void W_NextWeaponOnImpulse(float imp)
+{
+ float w;
+ w = W_GetCycleWeapon(self, self.cvar_cl_weaponpriority, +1, imp, 1, (self.cvar_cl_weaponimpulsemode == 0));
+ if(w > 0)
+ W_SwitchWeapon(w);
+}
+
+// next weapon
+void W_NextWeapon(float list)
+{
+ if(list == 0)
+ W_CycleWeapon(weaponorder_byid, -1);
+ else if(list == 1)
+ W_CycleWeapon(self.weaponorder_byimpulse, -1);
+ else if(list == 2)
+ W_CycleWeapon(self.cvar_cl_weaponpriority, -1);
+}
+
+// prev weapon
+void W_PreviousWeapon(float list)
+{
+ if(list == 0)
+ W_CycleWeapon(weaponorder_byid, +1);
+ else if(list == 1)
+ W_CycleWeapon(self.weaponorder_byimpulse, +1);
+ else if(list == 2)
+ W_CycleWeapon(self.cvar_cl_weaponpriority, +1);
+}
+
+// previously used if exists and has ammo, (second) best otherwise
+void W_LastWeapon(void)
+{
+ if(client_hasweapon(self, self.cnt, TRUE, FALSE))
+ W_SwitchWeapon(self.cnt);
+ else
+ W_SwitchToOtherWeapon(self);
+}