summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assets/models/players/human_base/animation.cfg4
-rw-r--r--assets/models/players/human_bsuit/animation.cfg4
-rw-r--r--assets/models/weapons/grenade/LICENSE1
-rw-r--r--assets/models/weapons/grenade/flash0.wavbin0 -> 20200 bytes
-rw-r--r--assets/models/weapons/grenade/grenade.jpgbin31424 -> 19526 bytes
-rw-r--r--assets/models/weapons/grenade/weapon.cfg6
-rw-r--r--assets/scripts/aw_level4.particle199
-rw-r--r--assets/scripts/hu_explosive_grenade.particle498
-rw-r--r--assets/scripts/hw_flamer.particle160
-rw-r--r--assets/scripts/hw_flamer.trail14
-rw-r--r--assets/sound/weapons/grenade/LICENSE3
-rw-r--r--assets/sound/weapons/grenade/prime.wavbin0 -> 22780 bytes
-rw-r--r--assets/sound/weapons/grenade/tick.wavbin0 -> 10960 bytes
-rw-r--r--src/cgame/cg_draw.c52
-rw-r--r--src/cgame/cg_event.c8
-rw-r--r--src/cgame/cg_local.h3
-rw-r--r--src/cgame/cg_main.c6
-rw-r--r--src/cgame/cg_weapons.c36
-rw-r--r--src/game/bg_misc.c42
-rw-r--r--src/game/bg_pmove.c135
-rw-r--r--src/game/bg_public.h12
-rw-r--r--src/game/g_active.c9
-rw-r--r--src/game/g_client.c2
-rw-r--r--src/game/g_cmds.c81
-rw-r--r--src/game/g_combat.c15
-rw-r--r--src/game/g_local.h3
-rw-r--r--src/game/g_missile.c4
-rw-r--r--src/game/g_team.c2
-rw-r--r--src/game/g_weapon.c26
-rw-r--r--src/game/tremulous.h8
-rw-r--r--src/ui/ui_local.h1
-rw-r--r--src/ui/ui_main.c31
32 files changed, 434 insertions, 931 deletions
diff --git a/assets/models/players/human_base/animation.cfg b/assets/models/players/human_base/animation.cfg
index 6ccb57b..6c65233 100644
--- a/assets/models/players/human_base/animation.cfg
+++ b/assets/models/players/human_base/animation.cfg
@@ -18,12 +18,16 @@ footsteps custom
130 6 0 15 // TORSO_ATTACK (MUST NOT CHANGE -- hand animation is synced to this)
136 6 0 15 // TORSO_ATTACK2 (MUST NOT CHANGE -- hand animation is synced to this)
+125 10 0 50 // TORSO_ATTACK3
+
142 5 0 20 // TORSO_DROP (MUST NOT CHANGE -- hand animation is synced to this)
147 4 0 20 // TORSO_RAISE (MUST NOT CHANGE -- hand animation is synced to this)
151 1 0 15 // TORSO_STAND
152 1 0 15 // TORSO_STAND2
+110 1 1 15 // TORSO_STAND3
+
153 8 8 16 // LEGS_WALKCR
161 12 12 20 // LEGS_WALK
173 9 9 15 // LEGS_RUN
diff --git a/assets/models/players/human_bsuit/animation.cfg b/assets/models/players/human_bsuit/animation.cfg
index 3de86e1..965d140 100644
--- a/assets/models/players/human_bsuit/animation.cfg
+++ b/assets/models/players/human_bsuit/animation.cfg
@@ -17,12 +17,16 @@ footsteps custom
130 6 0 15 // TORSO_ATTACK (MUST NOT CHANGE -- hand animation is synced to this)
130 6 0 15 // TORSO_ATTACK2 (MUST NOT CHANGE -- hand animation is synced to this)
+125 10 0 50 // TORSO_ATTACK3
+
142 5 0 20 // TORSO_DROP (MUST NOT CHANGE -- hand animation is synced to this)
147 4 0 20 // TORSO_RAISE (MUST NOT CHANGE -- hand animation is synced to this)
151 1 0 15 // TORSO_STAND
152 1 0 15 // TORSO_STAND2
+110 1 1 15 // TORSO_STAND3
+
153 9 9 20 // LEGS_WALKCR
162 8 8 20 // LEGS_WALK
170 13 13 23 // LEGS_RUN
diff --git a/assets/models/weapons/grenade/LICENSE b/assets/models/weapons/grenade/LICENSE
new file mode 100644
index 0000000..a3821a7
--- /dev/null
+++ b/assets/models/weapons/grenade/LICENSE
@@ -0,0 +1 @@
+flash0.wav is a derivative work of a sound made by qubodup, released into the public domain.
diff --git a/assets/models/weapons/grenade/flash0.wav b/assets/models/weapons/grenade/flash0.wav
new file mode 100644
index 0000000..ec87e69
--- /dev/null
+++ b/assets/models/weapons/grenade/flash0.wav
Binary files differ
diff --git a/assets/models/weapons/grenade/grenade.jpg b/assets/models/weapons/grenade/grenade.jpg
index a645b65..eb9240d 100644
--- a/assets/models/weapons/grenade/grenade.jpg
+++ b/assets/models/weapons/grenade/grenade.jpg
Binary files differ
diff --git a/assets/models/weapons/grenade/weapon.cfg b/assets/models/weapons/grenade/weapon.cfg
index 9d0811c..6e6cec6 100644
--- a/assets/models/weapons/grenade/weapon.cfg
+++ b/assets/models/weapons/grenade/weapon.cfg
@@ -1,12 +1,16 @@
+weaponModel models/weapons/grenade/grenade.md3
icon icons/iconw_nade
+crosshair 24 gfx/2d/crosshair-lgun_s
primary
{
missileModel models/weapons/grenade/grenade.md3
missileAnimates 0 20 20 0
+ flashSound 0 models/weapons/grenade/flash0.wav
+
impactMark 64 gfx/marks/bullet_mrk
- impactParticleSystem models/weapons/grenade/impactPS2
+ impactParticleSystem models/weapons/grenade/impactPS
impactSound 0 models/weapons/grenade/impact0.wav
impactQuake 120
diff --git a/assets/scripts/aw_level4.particle b/assets/scripts/aw_level4.particle
deleted file mode 100644
index 88f0deb..0000000
--- a/assets/scripts/aw_level4.particle
+++ /dev/null
@@ -1,199 +0,0 @@
-
-models/weapons/grenade/impactFBPS2
-{
- ejector
- {
- particle
- {
- shader sync gfx/sprites/smoke
- displacement 0 0 23 ~5
- velocityType static
- velocityDir linear
- velocityMagnitude 60
- velocity 0 0 1 ~360
- accelerationType static
- accelerationDir linear
- accelerationMagnitude 60
- acceleration 0 0 -1 ~360
- radius 10 25.0 370.0
- alpha 0 0.5 0.0
- rotation 0 0 -
- bounce 0.5
- lifeTime 15000
- childSystem models/weapons/smoke/addimpactPS4
- }
-
- count 10
- delay 0
- period 10 - ~0%
- }
-
- ejector
- {
- particle
- {
- shader sync flame3 flame4 flame5 flame6 flame7 flame8 flame9 flame10 flame11 flame12 flame13 flame14 flame15 flame16 flame17 flame18 flame19 flame20 flame21 flame22 flame23 flame24 flame25
-
- displacement 0 0 11 ~20
-
- velocityType static
- velocityDir linear
- velocityMagnitude 200~75%
- velocity 0 0 1 ~10
-
- accelerationType static
- accelerationDir linear
- accelerationMagnitude 300
- acceleration 0 0 -1 0
-
- radius 0 400 0.0
- alpha 0 1.0 0.0
- rotation 0 ~360 -
- bounce 0
-
- lifeTime 800
-
- childSystem models/weapons/grenade/impactTrailPS2
- }
-
- count 5
- delay 0
- period 10 - ~0%
- }
-
- ejector
- {
- particle
- {
- shader sync gfx/sprites/spark
-
- displacement 0 0 8 ~20
-
- velocityType static
- velocityDir linear
- velocityMagnitude 700~3%
- velocity 0 0 1 ~320
-
- accelerationType static
- accelerationDir linear
- accelerationMagnitude 800
- acceleration 0 0 1 0
-
- radius 0 20.0 2.0
- alpha 0 1.0 0.0
- rotation 0 ~360 -
- bounce 0.1
- bounceMark 2~2 60 gfx/marks/burn_mrk
-
- lifeTime 200
- onDeathSystem models/weapons/smoke/addimpactFlamePSsm
- }
-
- count 15
- delay 0
- period 0 - ~0%
- }
-}
-
-
-
-
-
-models/weapons/level4/muzzlePS
-{
- ejector
- {
- particle
- {
- shader sync flame10 flame11 flame12 flame13 flame14 flame15 flame16 flame17 flame18 flame19 flame20 flame21 flame22 flame23 flame24 flame25
- displacement 0 0 0 ~5.0
-
- parentVelocityFraction 0.65
-
- velocityType cent
- velocityDir linear
- velocityMagnitude 500
- velocity 0 0 0 ~0
-
- physicsRadius 15
-
- radius 0 25.0 60.0
- alpha 0 1.0 1.0
- rotation 0 ~360 -
- bounce 0
-
- lifeTime 1000
- }
-
- count 10
- delay 0
- period 15 - ~0%
- }
-
-}
-
-
-
-models/weapons/smoke/addimpactFlame2PSsm
-
- {
- ejector
- {
- particle
- {
- shader sync textures/yeflamer/flamesadd
- displacement 0 0 0 ~10
-
- parentVelocityFraction 0.0~0.05
- velocityType static
- velocityDir linear
- velocityMagnitude 2
- velocity 0 0 -1 ~360
-
- radius 0 180.0 10.0
- alpha 0 1 0.0
- rotation 0 ~360 -
- lifeTime 10000
- }
-
- count 1
- delay 0
- period 0 - ~0
- }
-}
-
-
-models/weapons/flamer/pMissile2PS
-{
- ejector
- {
- particle
- {
- shader sync gfx/sprites/spark
-
- displacement 0 0 8 ~0
-
- velocityType static
- velocityDir linear
- velocityMagnitude 400~20%
- velocity 0 0 -1 ~190
-
- accelerationType static
- accelerationDir linear
- accelerationMagnitude 800
- acceleration 0 0 -1 0
-
- radius 0 5.5 1.5
- alpha 0 1.0 0.0
- rotation 0 ~360 -
- bounce 0.1
-
- lifeTime 3000
- onDeathSystem models/weapons/smoke/addimpactFlamePSsm
- }
-
- count 10
- delay 0
- period 25 - ~0%
- }
-}
diff --git a/assets/scripts/hu_explosive_grenade.particle b/assets/scripts/hu_explosive_grenade.particle
index 8424617..99595fe 100644
--- a/assets/scripts/hu_explosive_grenade.particle
+++ b/assets/scripts/hu_explosive_grenade.particle
@@ -1,502 +1,70 @@
-models/weapons/grenade/impactTrailPS
-{
- ejector
- {
- particle
- {
- shader sync flame3 flame4 flame5 flame6 flame7 flame8 flame9 flame10 flame11 flame12 flame13 flame14 flame15 flame16 flame17 flame18 flame19 flame20 flame21 flame22 flame23 flame24 flame25
-
- displacement 0 0 0 ~0
-
- velocityType static
- velocityDir linear
- velocityMagnitude 30
- velocity 0 0 -1 ~0
-
- radius 0 30.0 10.0
- alpha 0 1.0 0.0
- rotation 0 ~360 -
- bounce 0
-
- lifeTime 500
- }
-
- count 5
- delay 0
- period 40 - 0
- }
-}
-
models/weapons/grenade/impactPS
{
ejector
{
particle
{
- shader sync flame3 flame4 flame5 flame6 flame7 flame8 flame9 flame10 flame11 flame12 flame13 flame14 flame15 flame16 flame17 flame18 flame19 flame20 flame21 flame22 flame23 flame24 flame25
-
- displacement 0 0 11 ~0
-
- velocityType static
- velocityDir linear
- velocityMagnitude 200~75%
- velocity 0 0 1 ~10
-
- accelerationType static
- accelerationDir linear
- accelerationMagnitude 300
- acceleration 0 0 -1 0
-
- radius 0 10.0 40.0
- alpha 0 1.0 0.0
- rotation 0 ~360 -
- bounce 0
-
- lifeTime 500
-
- childSystem models/weapons/grenade/impactTrailPS
- }
-
- count 5
- delay 0
- period 10 - ~0%
- }
-
- ejector
- {
- particle
- {
- shader sync gfx/grenade/flare_01
-
- displacement 0 0 8 ~0
-
- velocityType static
- velocityDir linear
- velocityMagnitude 10~50%
- velocity 0 0 1 ~60
-
- radius 0 100.0 200.0
- alpha 250 1.0 0.0
- rotation 0 ~360 -
- bounce 0.0
-
- lifeTime 300
- }
-
- count 1
- delay 0
- period 10 - ~0%
- }
-
- ejector
- {
- particle
- {
- shader sync gfx/sprites/spark
-
- displacement 0 0 8 ~0
-
- velocityType static
- velocityDir linear
- velocityMagnitude 700~3%
- velocity 0 0 1 ~180
-
- accelerationType static
- accelerationDir linear
- accelerationMagnitude 800
- acceleration 0 0 1 0
-
- radius 0 10.0 2.0
- alpha 0 1.0 0.0
- rotation 0 ~360 -
- bounce 0
-
- lifeTime 300
- }
-
- count 150
- delay 0
- period 0 - ~0%
- }
-}
-
-
-models/weapons/grenade/impactPS2
-{
- ejector
- {
- particle
- {
- shader sync gfx/sprites/smoke2
-
- displacement 0 0 0 50.0
- normalDisplacement 3.0
-
- velocityType normal
- velocityDir linear
- velocityMagnitude 10
- velocity 0 0 0 0
-
- accelerationType static
- accelerationDir linear
- accelerationMagnitude 1
- acceleration 0 0 1 0
-
- radius 0 100.0 500.0
- alpha 0 1 0.0
- rotation 0 ~360 -
- bounce 0.0
-
- lifeTime 15000
- }
-
- count 1
- delay 0
- period 0 - ~0%
- }
-
- ejector
- {
- particle
- {
- shader sync gfx/sprites/smoke2
- displacement 0 0 23 ~0
- velocityType static
- velocityDir linear
- velocityMagnitude 60
- velocity 0 0 1 ~360
- realLight
- accelerationType static
- accelerationDir linear
- accelerationMagnitude 60
- acceleration 0 0 -1 ~360
- radius 8 20.0 300.0
- alpha 0 0.5 0.0
- rotation 0 0 -
- bounce 0.5
- lifeTime 5000
- childSystem models/weapons/smoke/addimpactPS4
- }
-
- count 5
- delay 0
- period 10 - ~0%
- }
-
- ejector
- {
- particle
- {
- shader sync flame3 flame4 flame5 flame6 flame7 flame8 flame9 flame10 flame11 flame12 flame13 flame14 flame15 flame16 flame17 flame18 flame19 flame20 flame21 flame22 flame23 flame24 flame25
-
- displacement 0 0 11 ~0
-
- velocityType static
- velocityDir linear
- velocityMagnitude 200~75%
- velocity 0 0 1 ~10
-
- accelerationType static
- accelerationDir linear
- accelerationMagnitude 300
- acceleration 0 0 -1 0
-
- radius 0 150.0 40.0
- alpha 0 1.0 0.0
- rotation 0 ~360 -
- bounce 0
-
- lifeTime 500
-
- childSystem models/weapons/grenade/impactTrailPS2
- }
+ shader sync gfx/sprites/smoke
+ displacement 0 0 0 0
- count 5
- delay 0
- period 10 - ~0%
- }
-
- ejector
- {
- particle
- {
- shader sync gfx/sprites/spark
+ velocityType normal
- displacement 0 0 8 ~20
+ velocityDir linear
- velocityType static
- velocityDir linear
- velocityMagnitude 700~3%
- velocity 0 0 1 ~320
+ velocityMagnitude 100
+ velocity 0 0 0 ~35
accelerationType static
accelerationDir linear
- accelerationMagnitude 800
- acceleration 0 0 1 0
+ acceleration 0 0 -1 ~5
+ accelerationMagnitude 25
- radius 0 10.0 2.0
- alpha 0 1.0 0.0
- rotation 0 ~360 -
- bounce 0.1
- bounceMark 2~2 32 gfx/marks/burn_mrk
+ radius 0 0 100
+ alpha 250 .75 0
+ rotation 0 ~-15 ~15
+ bounce 0.0
- lifeTime 150
- onDeathSystem models/weapons/smoke/addimpactFlamePSsm
+ lifeTime 800~200
}
- count 10
- delay 0
- period 0 - ~0%
+ count 10
+ delay 0
+ period 0 - 0
}
- ejector
- {
- particle
- {
- shader sync gfx/sprites/spark
-
- displacement 0 0 8 ~0
-
- velocityType static
- velocityDir linear
- velocityMagnitude 400~20%
- velocity 0 0 -1 ~190
-
- accelerationType static
- accelerationDir linear
- accelerationMagnitude 800
- acceleration 0 0 -1 0
-
- radius 0 1.5 0.5
- alpha 0 1.0 0.0
- rotation 0 ~360 -
- bounce 0.1
-
- lifeTime 3000
- onDeathSystem models/weapons/smoke/addimpactFlamePSsm
- }
- count 30
- delay 0
- period 0 - ~0%
- }
-}
-//smoke nade
-models/weapons/smoke/impactPS
-{
-
ejector
{
particle
{
+ shader sync rocketx1 rocketx2 rocketx3 rocketx4 rocketx5 rocketx6 rocketx7 rocketx8 rocketx9 rocketx10 rocketx11 rocketx12 rocketx13 rocketx14 rocketx15 rocketx16 rocketx17 rocketx18 rocketx19 rocketx20 rocketx21 rocketx22 rocketx23 rocketx24 rocketx25 rocketx26 rocketx27 rocketx28 rocketx29
+ displacement 0 0 0 0
- shader sync gfx/sprites/smoke2
- displacement 0 0 3 0
-
- velocityType static
- velocityDir linear
- velocityMagnitude 20
- velocity 0 0 50 ~20
-
- realLight
-
- accelerationType static
- accelerationDir linear
- accelerationMagnitude 1
- acceleration 0 0 1 ~360
-
- radius 0 2 10.0
- alpha 0 1 0.0
- rotation 20 ~360 -
- bounce 0.5
- lifeTime 5000
+ velocityType normal
+ velocityDir linear
- }
+ velocityMagnitude 100
+ velocity 0 0 0 ~35
- count infinite
- delay 4000
- period 50 - ~0%
- }
-
- ejector
- {
- particle
- {
- shader sync gfx/sprites/smoke2
- displacement 0 0 23 ~0
- velocityType static
- velocityDir linear
- velocityMagnitude 60
- velocity 0 0 1 ~360
- realLight
accelerationType static
accelerationDir linear
- accelerationMagnitude 60
- acceleration 0 0 -1 ~360
- radius 8 20.0 370.0
- alpha 0 0.5 0.0
- rotation 0 0 -
- bounce 0.5
- lifeTime 20000
- childSystem models/weapons/smoke/addimpactPS
- }
-
- count 40
- delay 6000
- period 10 - ~0%
- }
-}
-
-//smoke nade add
-models/weapons/smoke/addimpactPS
-
- {
- ejector
- {
- particle
- {
- shader sync gfx/sprites/smoke2
- displacement 0 0 0 ~0
- velocityType static
- velocityDir linear
- velocityMagnitude 50
- velocity 0 0 1 ~360
-
- radius 0 50 300.0
- alpha 0 1 0.0
- rotation 0 ~360 -
- bounce 0.5
- realLight
- lifeTime 40000
- }
-
- count 2
- delay 2000
- period 80 - ~0%
- }
-}
-
-//flame add
-models/weapons/smoke/addimpactFlamePS
-
- {
- ejector
- {
- particle
- {
- shader sync textures/yeflamer/flamesadd
- displacement 0 0 0 ~0
-
- parentVelocityFraction 0.0~0.05
- velocityType static
- velocityDir linear
- velocityMagnitude 2
- velocity 0 0 -1 ~360
-
- radius 0 50.0 50.0
- alpha 0 1 0.0
- rotation 0 ~360 -
- lifeTime 10000
- }
-
- count 1
- delay 0
- period 0 - ~0%
- }
-}
-models/weapons/smoke/addimpactFlamePSsm
-
- {
- ejector
- {
- particle
- {
- shader sync textures/yeflamer/flamesadd
- displacement 0 0 0 ~0
-
- parentVelocityFraction 0.0~0.05
- velocityType static
- velocityDir linear
- velocityMagnitude 2
- velocity 0 0 -1 ~360
-
- radius 0 20.0 20.0
- alpha 0 1 0.0
- rotation 0 ~360 -
- lifeTime 10000
- }
-
- count 1
- delay 0
- period 0 - ~0%
- }
-}
-
-
-
-
-
-models/weapons/grenade/impactTrailPS2
-{
- ejector
- {
- particle
- {
- shader sync flame3 flame4 flame5 flame6 flame7 flame8 flame9 flame10 flame11 flame12 flame13 flame14 flame15 flame16 flame17 flame18 flame19 flame20 flame21 flame22 flame23 flame24 flame25
-
- displacement 0 0 0 ~0
-
- velocityType static
- velocityDir linear
- velocityMagnitude 30
- velocity 0 0 -1 ~0
-
- radius 0 150.0 10.0
- alpha 0 1.0 0.0
- rotation 0 ~360 -
- bounce 0
-
- lifeTime 500
- }
-
- count 5
- delay 0
- period 40 - 0
- }
-}
-
-
+ acceleration 0 0 -1 ~5
+ accelerationMagnitude 25
-//smoke nade add
-models/weapons/smoke/addimpactPS4
-
- {
- ejector
- {
- particle
- {
- shader sync gfx/sprites/smoke
- displacement 0 0 0 ~0
- velocityType static
- velocityDir linear
- velocityMagnitude 50
- velocity 0 0 1 ~360
+ radius 0 50 120
+ alpha 250 1 1
+ rotation ~360 0 0
+ bounce 0.0
+ color 0 { 0.8 0.2 0.2 } -
- radius 0 50 300.0
- alpha 0 1 0.0
- rotation 0 ~360 -
- bounce 0.5
- realLight
- lifeTime 10000
+ lifeTime 300~100
}
- count 2
- delay 2000
- period 80 - ~0%
+ count 1
+ delay 0
+ period 0 - 0
}
}
-
-
diff --git a/assets/scripts/hw_flamer.particle b/assets/scripts/hw_flamer.particle
index 77ae52a..430b5ae 100644
--- a/assets/scripts/hw_flamer.particle
+++ b/assets/scripts/hw_flamer.particle
@@ -35,166 +35,6 @@ models/weapons/flamer/muzzlePS
}
-models/weapons/flamer/impactbigPS
-{
- ejector
- {
- particle
- {
- shader sync gfx/sprites/smoke
-
- displacement 0 0 0 50.0
- normalDisplacement 3.0
-
- velocityType normal
- velocityDir linear
- velocityMagnitude 10
- velocity 0 0 0 0
-
- accelerationType static
- accelerationDir linear
- accelerationMagnitude 1
- acceleration 0 0 1 0
-
- radius 0 20.0 70.0
- alpha 0 1 0.0
- rotation 0 ~360 -
- bounce 0.0
-
- lifeTime 10000
- }
-
- count 1
- delay 0
- period 0 - ~0%
- }
-
- ejector
- {
- particle
- {
- shader sync gfx/sprites/smoke
- displacement 0 0 23 ~0
- velocityType static
- velocityDir linear
- velocityMagnitude 60
- velocity 0 0 1 ~360
- realLight
- accelerationType static
- accelerationDir linear
- accelerationMagnitude 60
- acceleration 0 0 -1 ~360
- radius 8 20.0 150.0
- alpha 0 0.5 0.0
- rotation 0 0 -
- bounce 0.5
- lifeTime 4000
- childSystem models/weapons/smoke/addimpactPS4
- }
-
- count 1
- delay 0
- period 10 - ~0%
- }
-
- ejector
- {
- particle
- {
- shader sync flame3 flame4 flame5 flame6 flame7 flame8 flame9 flame10 flame11 flame12 flame13 flame14 flame15 flame16 flame17 flame18 flame19 flame20 flame21 flame22 flame23 flame24 flame25
-
- displacement 0 0 11 ~0
-
- velocityType static
- velocityDir linear
- velocityMagnitude 200~75%
- velocity 0 0 1 ~10
-
- accelerationType static
- accelerationDir linear
- accelerationMagnitude 300
- acceleration 0 0 -1 0
-
- radius 0 110.0 70.0
- alpha 0 1.0 0.0
- rotation 0 ~360 -
- bounce 0
-
- lifeTime 500
-
- childSystem models/weapons/grenade/impactTrailPS2
- }
-
- count 4
- delay 0
- period 10 - ~0%
- }
-
- ejector
- {
- particle
- {
- shader sync gfx/sprites/spark
-
- displacement 0 0 8 ~20
-
- velocityType static
- velocityDir linear
- velocityMagnitude 700~3%
- velocity 0 0 1 ~320
-
- accelerationType static
- accelerationDir linear
- accelerationMagnitude 800
- acceleration 0 0 1 0
-
- radius 0 80.0 5.0
- alpha 0 1.0 0.0
- rotation 0 ~360 -
- bounce 0.1
- bounceMark 2~2 32 gfx/marks/burn_mrk
-
- lifeTime 180
- onDeathSystem models/weapons/smoke/addimpactFlamePSsm
- }
-
- count 6
- delay 0
- period 0 - ~0%
- }
- ejector
- {
- particle
- {
- shader sync gfx/sprites/spark
-
- displacement 0 0 8 ~0
-
- velocityType static
- velocityDir linear
- velocityMagnitude 400~20%
- velocity 0 0 -1 ~190
-
- accelerationType static
- accelerationDir linear
- accelerationMagnitude 800
- acceleration 0 0 -1 0
-
- radius 0 5.5 1.5
- alpha 0 1.0 0.0
- rotation 0 ~360 -
- bounce 0.1
-
- lifeTime 3000
- onDeathSystem models/weapons/smoke/addimpactFlamePSsm
- }
-
- count 25
- delay 0
- period 0 - ~0%
- }
-}
-
models/weapons/flamer/pMissilePS
{
diff --git a/assets/scripts/hw_flamer.trail b/assets/scripts/hw_flamer.trail
deleted file mode 100644
index 4ba8db6..0000000
--- a/assets/scripts/hw_flamer.trail
+++ /dev/null
@@ -1,14 +0,0 @@
-models/weapons/flamer/missileTS
-{
- beam
- {
- shader gfx/flamer/trail
-
- segments 3
- width 80.0 20.0
- alpha 1.0 0.1
- segmentTime 120
-
- textureType stretch 0.0 1.0
- }
-} \ No newline at end of file
diff --git a/assets/sound/weapons/grenade/LICENSE b/assets/sound/weapons/grenade/LICENSE
new file mode 100644
index 0000000..3db75f4
--- /dev/null
+++ b/assets/sound/weapons/grenade/LICENSE
@@ -0,0 +1,3 @@
+tick.wav is a derivative work of a sound made by delphidebrain, released under the terms of Creative Commons Attribution 3.0.
+
+prime.wav is a derivative work of a sound made by Ryan Conway, released under the terms of Creative Commons Attribution 3.0.
diff --git a/assets/sound/weapons/grenade/prime.wav b/assets/sound/weapons/grenade/prime.wav
new file mode 100644
index 0000000..431cca9
--- /dev/null
+++ b/assets/sound/weapons/grenade/prime.wav
Binary files differ
diff --git a/assets/sound/weapons/grenade/tick.wav b/assets/sound/weapons/grenade/tick.wav
new file mode 100644
index 0000000..6624c47
--- /dev/null
+++ b/assets/sound/weapons/grenade/tick.wav
Binary files differ
diff --git a/src/cgame/cg_draw.c b/src/cgame/cg_draw.c
index 0ee4042..4e2ba77 100644
--- a/src/cgame/cg_draw.c
+++ b/src/cgame/cg_draw.c
@@ -315,7 +315,7 @@ static void CG_DrawPlayerCreditsValue( rectDef_t *rect, vec4_t color, qboolean p
ps = &cg.snap->ps;
//if the build timer pie is showing don't show this
- if( ( cent->currentState.weapon == WP_ABUILD ) && ps->stats[ STAT_MISC ] )
+ if( ( cent->currentState.weapon == WP_ABUILD ) && ps->stats[ STAT_BUILD_TIMER ] )
return;
value = ps->persistant[ PERS_CREDIT ];
@@ -454,7 +454,7 @@ static void CG_DrawPlayerClipsRing( rectDef_t *rect, vec4_t backColor,
{
playerState_t *ps = &cg.snap->ps;
centity_t *cent;
- float buildTime = ps->stats[ STAT_MISC ];
+ float buildTime = ps->stats[ STAT_BUILD_TIMER ];
float progress;
float maxDelay;
weapon_t weapon;
@@ -502,7 +502,7 @@ static void CG_DrawPlayerBuildTimerRing( rectDef_t *rect, vec4_t backColor,
{
playerState_t *ps = &cg.snap->ps;
// centity_t *cent;
- float buildTime = ps->stats[ STAT_MISC ];
+ float buildTime = ps->stats[ STAT_BUILD_TIMER ];
float progress;
vec4_t color;
@@ -764,7 +764,11 @@ static void CG_DrawPlayerAmmoValue( rectDef_t *rect, vec4_t color )
int valueMarked = -1;
qboolean bp = qfalse;
- switch( BG_PrimaryWeapon( cg.snap->ps.stats ) )
+ if( cg.snap->ps.weapon == WP_GRENADE )
+ {
+ value = cg.snap->ps.stats[ STAT_GRENADES ];
+ }
+ else switch( BG_PrimaryWeapon( cg.snap->ps.stats ) )
{
case WP_NONE:
case WP_BLASTER:
@@ -932,7 +936,7 @@ static void CG_DrawPlayerBuildTimer( rectDef_t *rect, vec4_t color )
ps = &cg.snap->ps;
- if( ps->stats[ STAT_MISC ] <= 0 )
+ if( ps->stats[ STAT_BUILD_TIMER ] <= 0 )
return;
switch( BG_PrimaryWeapon( ps->stats ) )
@@ -945,7 +949,7 @@ static void CG_DrawPlayerBuildTimer( rectDef_t *rect, vec4_t color )
return;
}
- index = 8 * ( ps->stats[ STAT_MISC ] - 1 ) / MAXIMUM_BUILD_TIME;
+ index = 8 * ( ps->stats[ STAT_BUILD_TIMER ] - 1 ) / MAXIMUM_BUILD_TIME;
if( index > 7 )
index = 7;
else if( index < 0 )
@@ -970,6 +974,10 @@ static void CG_DrawPlayerClipsValue( rectDef_t *rect, vec4_t color )
int value;
playerState_t *ps = &cg.snap->ps;
+ if( cg.snap->ps.weapon == WP_GRENADE )
+ {
+ return;
+ }
switch( BG_PrimaryWeapon( ps->stats ) )
{
case WP_NONE:
@@ -1106,12 +1114,16 @@ static float CG_ChargeProgress( void )
min = 0;
max = LEVEL1_WARP_TIME;
}
-
else if( cg.snap->ps.weapon == WP_LUCIFER_CANNON || cg.snap->ps.weapon == WP_FLAMER )
{
min = LCANNON_CHARGE_TIME_MIN;
max = LCANNON_CHARGE_TIME_MAX;
}
+ else if( cg.snap->ps.weapon == WP_GRENADE )
+ {
+ min = 0;
+ max = GRENADE_FUSE_TIME;
+ }
if( max - min <= 0.0f )
return 0.0f;
@@ -1186,14 +1198,17 @@ static void CG_DrawPlayerChargeBar( rectDef_t *rect, vec4_t ref_color,
color[ 3 ] = ref_color[ 3 ] * cg.chargeMeterAlpha;
// Flash red for Lucifer Cannon warning
- if( (cg.snap->ps.weapon == WP_FLAMER ) &&
-
- cg.snap->ps.stats[ STAT_MISC ] >= LCANNON_CHARGE_TIME_WARN &&
- ( cg.time & 128 ) )
- {
- color[ 0 ] = 1.0f;
- color[ 1 ] = 0.0f;
- color[ 2 ] = 0.0f;
+ if( cg.time & 128 )
+ {
+ if( ( cg.snap->ps.weapon == WP_LUCIFER_CANNON &&
+ cg.snap->ps.stats[ STAT_MISC ] >= LCANNON_CHARGE_TIME_WARN ) ||
+ ( cg.snap->ps.weapon == WP_GRENADE &&
+ cg.snap->ps.stats[ STAT_MISC ] >= GRENADE_TIME_WARN ) )
+ {
+ color[ 0 ] = 1.0f;
+ color[ 1 ] = 0.0f;
+ color[ 2 ] = 0.0f;
+ }
}
x = rect->x;
@@ -2745,7 +2760,12 @@ void CG_DrawWeaponIcon( rectDef_t *rect, vec4_t color )
return;
}
- if( ps->clips == 0 && !BG_Weapon( weapon )->infiniteAmmo )
+ if( weapon == WP_GRENADE && ps->stats[ STAT_GRENADES ] <= 0 )
+ {
+ color[ 0 ] = 1.0f;
+ color[ 1 ] = color[ 2 ] = 0.0f;
+ }
+ else if( weapon != WP_GRENADE && ps->clips == 0 && !BG_Weapon( weapon )->infiniteAmmo )
{
float ammoPercent = (float)ps->ammo / (float)maxAmmo;
diff --git a/src/cgame/cg_event.c b/src/cgame/cg_event.c
index eaf925e..b3a8396 100644
--- a/src/cgame/cg_event.c
+++ b/src/cgame/cg_event.c
@@ -1007,6 +1007,14 @@ void CG_EntityEvent( centity_t *cent, vec3_t position )
}
break;
+ case EV_GRENADE_PRIME:
+ trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.grenadePrimeSound );
+ break;
+
+ case EV_GRENADE_TICK:
+ trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.grenadeTickSound );
+ break;
+
//
// missile impacts
//
diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h
index 4642f64..7721e45 100644
--- a/src/cgame/cg_local.h
+++ b/src/cgame/cg_local.h
@@ -1367,6 +1367,9 @@ typedef struct
qhandle_t warpParticle;
qhandle_t brightenShaders[ NUM_BRIGHTEN_SHADERS ];
+
+ sfxHandle_t grenadePrimeSound;
+ sfxHandle_t grenadeTickSound;
} cgMedia_t;
typedef struct
diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c
index 158c0b5..2761922 100644
--- a/src/cgame/cg_main.c
+++ b/src/cgame/cg_main.c
@@ -461,7 +461,8 @@ static void CG_SetUIVars( void )
BG_Upgrade( i )->purchasable )
strcat( carriageCvar, va( "U%d ", i ) );
}
- strcat( carriageCvar, "$" );
+
+ strcat( carriageCvar, va( "G%d $", cg.snap->ps.stats[ STAT_GRENADES ] ) );
trap_Cvar_Set( "ui_carriage", carriageCvar );
@@ -777,6 +778,9 @@ static void CG_RegisterSounds( void )
cgs.media.warpEnterSound = trap_S_RegisterSound( "sound/player/level1/warp1.wav", qfalse );
cgs.media.warpExitSound = trap_S_RegisterSound( "sound/player/level1/warp2.wav", qfalse );
cgs.media.warpingSound = trap_S_RegisterSound( "sound/player/level1/warping.wav", qfalse );
+
+ cgs.media.grenadePrimeSound = trap_S_RegisterSound( "sound/weapons/grenade/prime.wav", qfalse );
+ cgs.media.grenadeTickSound = trap_S_RegisterSound( "sound/weapons/grenade/tick.wav", qfalse );
}
diff --git a/src/cgame/cg_weapons.c b/src/cgame/cg_weapons.c
index 4f2ef13..7fb68c9 100644
--- a/src/cgame/cg_weapons.c
+++ b/src/cgame/cg_weapons.c
@@ -1401,6 +1401,32 @@ void CG_AddViewWeapon( playerState_t *ps )
hand.origin );
}
+ // Grenade animations
+ // too tired to do this the right way...
+ if( weapon == WP_GRENADE )
+ {
+ float dx = 8.0f, dy = -5.0f, dz = -5.0f;
+
+ if( ps->stats[ STAT_GRENADES ] <= 0 )
+ {
+ return;
+ }
+
+ if( ps->stats[ STAT_MISC ] > 0 )
+ {
+ dx -= 4.0f * ps->stats[ STAT_MISC ] / 100;
+ dz += 2.0f * ps->stats[ STAT_MISC ] / 100;
+ }
+ else if( ps->weaponTime > 0 )
+ {
+ dz -= 0.015f * ps->weaponTime;
+ }
+
+ VectorMA( hand.origin, dx, cg.refdef.viewaxis[ 0 ], hand.origin );
+ VectorMA( hand.origin, dy, cg.refdef.viewaxis[ 1 ], hand.origin );
+ VectorMA( hand.origin, dz, cg.refdef.viewaxis[ 2 ], hand.origin );
+ }
+
AnglesToAxis( angles, hand.axis );
// map torso animations to weapon animations
@@ -1517,10 +1543,18 @@ void CG_DrawItemSelect( rectDef_t *rect, vec4_t color )
if( !BG_InventoryContainsWeapon( i, cg.snap->ps.stats ) )
continue;
- if( !ps->ammo && !ps->clips && !BG_Weapon( i )->infiniteAmmo )
+ if( i == WP_GRENADE && ps->stats[ STAT_GRENADES ] <= 0 )
+ {
+ colinfo[ numItems ] = 1;
+ }
+ else if( i != WP_GRENADE && !ps->ammo && !ps->clips && !BG_Weapon( i )->infiniteAmmo )
+ {
colinfo[ numItems ] = 1;
+ }
else
+ {
colinfo[ numItems ] = 0;
+ }
if( i == cg.weaponSelect )
selectedItem = numItems;
diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c
index ff158bb..b5bd305 100644
--- a/src/game/bg_misc.c
+++ b/src/game/bg_misc.c
@@ -3190,8 +3190,7 @@ static const weaponAttributes_t bg_weapons[ ] =
qfalse, //qboolean longRanged;
TEAM_ALIENS //team_t team;
},
-
- {
+ {
WP_BLASTER, //int weaponNum;
0, //int price;
STAGE_GE_1, //int stages
@@ -3507,11 +3506,11 @@ static const weaponAttributes_t bg_weapons[ ] =
},
{
WP_GRENADE, //int weaponNum;
- GRENADE_PRICE, //int price;
- STAGE_GE_3, //int stages
- SLOT_NONE, //int slots;
+ 0, //int price;
+ STAGE_GE_1, //int stages
+ 0, //int slots;
"grenade", //char *weaponName;
- "Grenade", //char *humanName;
+ "[yenade]Grenades", //char *humanName;
"",
1, //int maxAmmo;
0, //int maxClips;
@@ -3838,7 +3837,7 @@ static const upgradeAttributes_t bg_upgrades[ ] =
STAGE_GE_4, //int stages
SLOT_NONE, //int slots;
"gren", //char *upgradeName;
- "[yenade]Explosive Grenade", //char *humanName;
+ "[yenade]Grenade", //char *humanName;
"A small incendinary device ideal for damaging tightly packed "
"alien structures. Has a five second timer.",
0,
@@ -4101,7 +4100,12 @@ char *eventnames[ ] =
"EV_MGTURRET_SPINUP", // trigger a sound
"EV_RPTUSE_SOUND", // trigger a sound
"EV_LEV2_ZAP",
- "EV_ACIDBOMB_BOUNCE"
+ "EV_ACIDBOMB_BOUNCE",
+ "EV_ROCKETL_PRIME",
+ "EV_WARP_ENTER",
+ "EV_WARP_EXIT",
+ "EV_GRENADE_PRIME",
+ "EV_GRENADE_TICK"
};
/*
@@ -4382,8 +4386,9 @@ Does the player hold a weapon?
*/
qboolean BG_InventoryContainsWeapon( int weapon, int stats[ ] )
{
- // humans always have a blaster
- if( stats[ STAT_TEAM ] == TEAM_HUMANS && weapon == WP_BLASTER )
+ // humans always have a blaster and a grenade thrower
+ if( stats[ STAT_TEAM ] == TEAM_HUMANS &&
+ ( weapon == WP_BLASTER || weapon == WP_GRENADE ) )
return qtrue;
return ( stats[ STAT_WEAPON ] == weapon );
@@ -4400,8 +4405,12 @@ int BG_SlotsForInventory( int stats[ ] )
int i, slot, slots;
slots = BG_Weapon( stats[ STAT_WEAPON ] )->slots;
+
if( stats[ STAT_TEAM ] == TEAM_HUMANS )
- slots |= BG_Weapon( WP_BLASTER )->slots;
+ {
+ slots |= BG_Weapon( WP_BLASTER )->slots |
+ BG_Weapon( WP_GRENADE )->slots;
+ }
for( i = UP_NONE; i < UP_NUM_UPGRADES; i++ )
{
@@ -4653,6 +4662,12 @@ qboolean BG_PlayerCanChangeWeapon( playerState_t *ps )
ps->stats[ STAT_MISC ] > LCANNON_CHARGE_TIME_MIN )
return qfalse;
+ if( ps->weapon == WP_GRENADE &&
+ ps->stats[ STAT_MISC ] > 0 )
+ {
+ return qfalse;
+ }
+
return ps->weaponTime <= 0 || ps->weaponstate != WEAPON_FIRING;
}
@@ -5101,6 +5116,11 @@ weapon_t BG_PrimaryWeapon( int stats[ ] )
if( BG_InventoryContainsWeapon( WP_BLASTER, stats ) )
return WP_BLASTER;
+ if( BG_InventoryContainsWeapon( WP_GRENADE, stats ) )
+ {
+ return WP_GRENADE;
+ }
+
return WP_NONE;
}
diff --git a/src/game/bg_pmove.c b/src/game/bg_pmove.c
index 4fd73f1..f8f8a69 100644
--- a/src/game/bg_pmove.c
+++ b/src/game/bg_pmove.c
@@ -2861,9 +2861,10 @@ static void PM_BeginWeaponChange( int weapon )
if( pm->ps->weaponstate == WEAPON_DROPPING )
return;
- // prevent storing a primed rocket launcher
- if( pm->ps->weapon == WP_ROCKET_LAUNCHER &&
- pm->ps->stats[ STAT_MISC ] > 0 )
+ // prevent storing a primed rocket launcher or grenade
+ if( ( pm->ps->weapon == WP_ROCKET_LAUNCHER ||
+ pm->ps->weapon == WP_GRENADE ) &&
+ pm->ps->stats[ STAT_MISC ] > 0 )
return;
// cancel a reload
@@ -2932,9 +2933,17 @@ static void PM_TorsoAnimation( void )
if( !( pm->ps->persistant[ PERS_STATE ] & PS_NONSEGMODEL ) )
{
if( pm->ps->weapon == WP_BLASTER )
+ {
PM_ContinueTorsoAnim( TORSO_STAND2 );
+ }
+ else if( pm->ps->weapon == WP_GRENADE )
+ {
+ PM_ContinueTorsoAnim( TORSO_STAND3 );
+ }
else
+ {
PM_ContinueTorsoAnim( TORSO_STAND );
+ }
}
PM_ContinueWeaponAnim( WANIM_IDLE );
@@ -3104,6 +3113,32 @@ static void PM_Weapon( void )
}
}
+ if( pm->ps->weapon == WP_GRENADE )
+ {
+ if( !pm->ps->weaponTime &&
+ pm->ps->stats[ STAT_GRENADES ] > 0 &&
+ ( ( pm->cmd.buttons & BUTTON_ATTACK ) ||
+ pm->ps->stats[ STAT_MISC ] > 0 ) )
+ {
+ int old_time;
+
+ old_time = pm->ps->stats[ STAT_MISC ];
+
+ if( old_time == 0 )
+ {
+ PM_AddEvent( EV_GRENADE_PRIME );
+ }
+
+ pm->ps->stats[ STAT_MISC ] += pml.msec;
+
+ if( pm->ps->stats[ STAT_MISC ] < GRENADE_FUSE_TIME &&
+ old_time / 1000 < pm->ps->stats[ STAT_MISC ] / 1000 )
+ {
+ PM_AddEvent( EV_GRENADE_TICK );
+ }
+ }
+ }
+
// don't allow attack until all buttons are up
if( pm->ps->pm_flags & PMF_RESPAWNED )
return;
@@ -3200,7 +3235,9 @@ static void PM_Weapon( void )
else minAmmo = 1;
// check for out of ammo
- if( pm->ps->ammo < minAmmo && !pm->ps->clips && !BG_Weapon( pm->ps->weapon )->infiniteAmmo )
+ if( ( pm->ps->weapon != WP_GRENADE && pm->ps->ammo < minAmmo &&
+ !pm->ps->clips && !BG_Weapon( pm->ps->weapon )->infiniteAmmo ) ||
+ ( pm->ps->weapon == WP_GRENADE && pm->ps->stats[ STAT_GRENADES ] <= 0 ) )
{
if( attack1 || ( BG_Weapon( pm->ps->weapon )->hasAltMode && attack2 ) || ( BG_Weapon( pm->ps->weapon )->hasThirdMode && attack3 ) )
{
@@ -3345,6 +3382,36 @@ static void PM_Weapon( void )
return;
}
+ case WP_GRENADE:
+ if( attack1 || pm->ps->stats[ STAT_MISC ] == 0 )
+ {
+ pm->ps->weaponTime = 0;
+
+ if( pm->ps->stats[ STAT_MISC ] < GRENADE_FUSE_TIME )
+ {
+ pm->ps->weaponstate = WEAPON_READY;
+ return;
+ }
+ }
+
+ if( pm->ps->stats[ STAT_MISC ] > GRENADE_TIME_MIN )
+ {
+ attack1 = qtrue;
+ }
+ else if( pm->ps->stats[ STAT_MISC ] > 0 )
+ {
+ pm->ps->weaponTime = 0;
+ pm->ps->weaponstate = WEAPON_READY;
+ return;
+ }
+ else
+ {
+ pm->ps->weaponTime = 0;
+ pm->ps->weaponstate = WEAPON_READY;
+ return;
+ }
+ break;
+
default:
if( !attack1 && !attack2 && !attack3 )
{
@@ -3462,7 +3529,11 @@ static void PM_Weapon( void )
//FIXME: this should be an option in the client weapon.cfg
switch( pm->ps->weapon )
{
-
+ case WP_GRENADE:
+ PM_StartTorsoAnim( TORSO_ATTACK3 );
+ PM_StartWeaponAnim( WANIM_ATTACK1 );
+ break;
+
case WP_BLASTER:
PM_StartTorsoAnim( TORSO_ATTACK2 );
PM_StartWeaponAnim( WANIM_ATTACK1 );
@@ -3544,27 +3615,39 @@ static void PM_Weapon( void )
( pm->ps->weapon == WP_ALEVEL4 && attack3 )||
( pm->ps->weapon == WP_ALEVEL5 && attack3 ))
{
- switch( pm->ps->weapon ) {
- case WP_MASS_DRIVER:
- if( attack3 ) {
- pm->ps->ammo -= 7;
- if( pm->ps->ammo < 7 ) pm->ps->ammo += 1;
- } else pm->ps->ammo--;
- break;
- case WP_LUCIFER_CANNON:
- if( attack1 && !attack2 ) {
- pm->ps->ammo -= ( pm->ps->stats[ STAT_MISC ] * LCANNON_CHARGE_AMMO +
- LCANNON_CHARGE_TIME_MAX - 1 ) / LCANNON_CHARGE_TIME_MAX;
- } else pm->ps->ammo--;
- break;
- case WP_LAS_GUN:
- if( attack2 ) {
- pm->ps->ammo -= 25;
- } else pm->ps->ammo--;
- break;
- default:
- pm->ps->ammo--;
- break;
+ switch( pm->ps->weapon )
+ {
+ case WP_LUCIFER_CANNON:
+ if( attack1 && !attack2 )
+ {
+ pm->ps->ammo -=
+ ( pm->ps->stats[ STAT_MISC ] * LCANNON_CHARGE_AMMO +
+ LCANNON_CHARGE_TIME_MAX - 1 ) / LCANNON_CHARGE_TIME_MAX;
+ }
+ else
+ {
+ pm->ps->ammo--;
+ }
+ break;
+
+ case WP_LAS_GUN:
+ if( attack2 )
+ {
+ pm->ps->ammo -= 25;
+ }
+ else
+ {
+ pm->ps->ammo--;
+ }
+ break;
+
+ case WP_GRENADE:
+ pm->ps->stats[ STAT_GRENADES ]--;
+ break;
+
+ default:
+ pm->ps->ammo--;
+ break;
}
// Stay on the safe side
diff --git a/src/game/bg_public.h b/src/game/bg_public.h
index b0c1213..f377739 100644
--- a/src/game/bg_public.h
+++ b/src/game/bg_public.h
@@ -243,8 +243,10 @@ typedef enum
STAT_MISC, // for uh...misc stuff (pounce, trample, lcannon)
STAT_BUILDABLE, // which ghost model to display for building
STAT_FALLDIST, // the distance the player fell
- STAT_VIEWLOCK // direction to lock the view in
- // netcode has space for 3 more
+ STAT_VIEWLOCK, // direction to lock the view in
+ STAT_GRENADES,
+ STAT_BUILD_TIMER
+ // netcode has space for 1 more
} statIndex_t;
#define SCA_WALLCLIMBER 0x00000001
@@ -569,7 +571,9 @@ typedef enum
EV_ACIDBOMB_BOUNCE,
EV_ROCKETL_PRIME,
EV_WARP_ENTER,
- EV_WARP_EXIT
+ EV_WARP_EXIT,
+ EV_GRENADE_PRIME,
+ EV_GRENADE_TICK
} entity_event_t;
typedef enum
@@ -659,10 +663,12 @@ typedef enum
TORSO_GESTURE,
TORSO_ATTACK,
TORSO_ATTACK2,
+ TORSO_ATTACK3,
TORSO_DROP,
TORSO_RAISE,
TORSO_STAND,
TORSO_STAND2,
+ TORSO_STAND3,
LEGS_WALKCR,
LEGS_WALK,
LEGS_RUN,
diff --git a/src/game/g_active.c b/src/game/g_active.c
index b3df37b..c1a473d 100644
--- a/src/game/g_active.c
+++ b/src/game/g_active.c
@@ -579,6 +579,7 @@ void SpectatorThink( gentity_t *ent, usercmd_t *ucmd )
client->ps.speed = client->pers.flySpeed;
client->ps.stats[ STAT_STAMINA ] = 0;
client->ps.stats[ STAT_MISC ] = 0;
+ client->ps.stats[ STAT_BUILD_TIMER ] = 0;
client->ps.stats[ STAT_BUILDABLE ] = BA_NONE;
client->ps.stats[ STAT_CLASS ] = PCL_NONE;
client->ps.weapon = WP_NONE;
@@ -778,11 +779,11 @@ void ClientTimerActions( gentity_t *ent, int msec )
BG_InventoryContainsWeapon( WP_HBUILD, client->ps.stats ) )
{
// Update build timer
- if( client->ps.stats[ STAT_MISC ] > 0 )
- client->ps.stats[ STAT_MISC ] -= 100;
+ if( client->ps.stats[ STAT_BUILD_TIMER ] > 0 )
+ client->ps.stats[ STAT_BUILD_TIMER ] -= 100;
- if( client->ps.stats[ STAT_MISC ] < 0 )
- client->ps.stats[ STAT_MISC ] = 0;
+ if( client->ps.stats[ STAT_BUILD_TIMER ] < 0 )
+ client->ps.stats[ STAT_BUILD_TIMER ] = 0;
}
switch( weapon )
diff --git a/src/game/g_client.c b/src/game/g_client.c
index ccf65e8..4fd2bb8 100644
--- a/src/game/g_client.c
+++ b/src/game/g_client.c
@@ -1554,7 +1554,7 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles
{
spawn_angles[ YAW ] += 180.0f;
AngleNormalize360( spawn_angles[ YAW ] );
-
+
//
G_Sound( ent, CHAN_VOICE, G_SoundIndex( "sound/buildables/human/spawn1.wav" ) );
}
diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c
index 2b7b105..de0090b 100644
--- a/src/game/g_cmds.c
+++ b/src/game/g_cmds.c
@@ -449,7 +449,7 @@ void Cmd_Give_f( gentity_t *ent )
{
ADMP( "usage: give [what]\n" );
ADMP( "usage: valid choices are: all, health, funds [amount], stamina, "
- "ammo\n" );
+ "ammo, grenades\n" );
return;
}
@@ -488,18 +488,32 @@ void Cmd_Give_f( gentity_t *ent )
if( give_all || Q_stricmp( name, "stamina" ) == 0 )
ent->client->ps.stats[ STAT_STAMINA ] = STAMINA_MAX;
+ if( give_all || Q_stricmp( name, "grenades" ) == 0 )
+ {
+ ent->client->ps.stats[ STAT_GRENADES ] = GRENADE_MAX;
+ }
+
if( give_all || Q_stricmp( name, "ammo" ) == 0 )
{
gclient_t *client = ent->client;
+ int weapon;
if( client->ps.weapon != WP_ALEVEL3_UPG &&
BG_Weapon( client->ps.weapon )->infiniteAmmo )
return;
- client->ps.ammo = BG_Weapon( client->ps.weapon )->maxAmmo;
- client->ps.clips = BG_Weapon( client->ps.weapon )->maxClips;
+ weapon = BG_PrimaryWeapon( client->ps.stats );
+
+ if( weapon == WP_BLASTER ||
+ weapon == WP_GRENADE )
+ {
+ return;
+ }
+
+ client->ps.ammo = BG_Weapon( weapon )->maxAmmo;
+ client->ps.clips = BG_Weapon( weapon )->maxClips;
- if( BG_Weapon( client->ps.weapon )->usesEnergy &&
+ if( BG_Weapon( weapon )->usesEnergy &&
BG_InventoryContainsUpgrade( UP_BATTPACK, client->ps.stats ) )
client->ps.ammo = (int)( (float)client->ps.ammo * BATTPACK_MODIFIER );
}
@@ -1777,7 +1791,7 @@ void Cmd_Class_f( gentity_t *ent )
if( ent->client->sess.spectatorState == SPECTATOR_NOT &&
( currentClass == PCL_ALIEN_BUILDER0 ||
currentClass == PCL_ALIEN_BUILDER0_UPG ) &&
- ent->client->ps.stats[ STAT_MISC ] > 0 )
+ ent->client->ps.stats[ STAT_BUILD_TIMER ] > 0 )
{
G_TriggerMenu( ent->client->ps.clientNum, MN_A_EVOLVEBUILDTIMER );
return;
@@ -1925,7 +1939,7 @@ void Cmd_Destroy_f( gentity_t *ent )
( ent->client->pers.teamSelection == TEAM_HUMANS &&
!G_FindPower( traceEnt, qtrue ) ) )
{
- if( ent->client->ps.stats[ STAT_MISC ] > 0 )
+ if( ent->client->ps.stats[ STAT_BUILD_TIMER ] > 0 )
{
G_AddEvent( ent, EV_BUILD_DELAY, ent->client->ps.clientNum );
return;
@@ -1950,7 +1964,7 @@ void Cmd_Destroy_f( gentity_t *ent )
{
if( !g_cheats.integer ) // add a bit to the build timer
{
- ent->client->ps.stats[ STAT_MISC ] +=
+ ent->client->ps.stats[ STAT_BUILD_TIMER ] +=
BG_Buildable( traceEnt->s.modelindex )->buildTime / 4;
}
G_Damage( traceEnt, ent, ent, forward, tr.endpos,
@@ -1978,7 +1992,8 @@ void Cmd_ActivateItem_f( gentity_t *ent )
// "weapon" aliased to whatever weapon you have
if( !Q_stricmp( "weapon", s ) )
{
- if( ent->client->ps.weapon == WP_BLASTER &&
+ if( ( ent->client->ps.weapon == WP_BLASTER ||
+ ent->client->ps.weapon == WP_GRENADE ) &&
BG_PlayerCanChangeWeapon( &ent->client->ps ) )
G_ForceWeaponChange( ent, WP_NONE );
return;
@@ -1987,6 +2002,13 @@ void Cmd_ActivateItem_f( gentity_t *ent )
upgrade = BG_UpgradeByName( s )->number;
weapon = BG_WeaponByName( s )->number;
+ // for backward compatibility
+ if( upgrade == UP_GRENADE )
+ {
+ upgrade = UP_NONE;
+ weapon = WP_GRENADE;
+ }
+
if( upgrade != UP_NONE && BG_InventoryContainsUpgrade( upgrade, ent->client->ps.stats ) )
BG_ActivateUpgrade( upgrade, ent->client->ps.stats );
else if( weapon != WP_NONE &&
@@ -2045,7 +2067,8 @@ void Cmd_ToggleItem_f( gentity_t *ent )
//special case to allow switching between
//the blaster and the primary weapon
- if( ent->client->ps.weapon != WP_BLASTER )
+ if( ent->client->ps.weapon != WP_BLASTER &&
+ ent->client->ps.weapon != WP_GRENADE )
weapon = WP_BLASTER;
else
weapon = WP_NONE;
@@ -2211,6 +2234,12 @@ void Cmd_Buy_f( gentity_t *ent )
return;
}
+ if( upgrade == UP_GRENADE && ent->client->ps.stats[ STAT_GRENADES ] >= GRENADE_MAX )
+ {
+ trap_SendServerCommand( ent-g_entities, "print \"You can't carry any more grenades\n\"" );
+ return;
+ }
+
if( upgrade == UP_AMMO )
G_GiveClientMaxAmmo( ent, energyOnly );
else
@@ -2230,8 +2259,16 @@ void Cmd_Buy_f( gentity_t *ent )
ent->client->ps.eFlags ^= EF_TELEPORT_BIT;
}
- //add to inventory
- BG_AddUpgradeToInventory( upgrade, ent->client->ps.stats );
+ //UP_GRENADE isn't actually an upgrade, it's ammo for WP_GRENADE
+ if( upgrade == UP_GRENADE )
+ {
+ ent->client->ps.stats[ STAT_GRENADES ]++;
+ }
+ else
+ {
+ //add to inventory
+ BG_AddUpgradeToInventory( upgrade, ent->client->ps.stats );
+ }
}
if( upgrade == UP_BATTPACK )
@@ -2294,7 +2331,7 @@ void Cmd_Sell_f( gentity_t *ent )
if( BG_InventoryContainsWeapon( weapon, ent->client->ps.stats ) )
{
//guard against selling the HBUILD weapons exploit
- if( weapon == WP_HBUILD && ent->client->ps.stats[ STAT_MISC ] > 0 )
+ if( weapon == WP_HBUILD && ent->client->ps.stats[ STAT_BUILD_TIMER ] > 0 )
{
G_TriggerMenu( ent->client->ps.clientNum, MN_H_ARMOURYBUILDTIMER );
return;
@@ -2320,8 +2357,18 @@ void Cmd_Sell_f( gentity_t *ent )
trap_SendServerCommand( ent-g_entities, "print \"You can't sell this item\n\"" );
return;
}
+
+ //UP_GRENADE is not an actual upgrade, it's ammo for WP_GRENADE
+ if( upgrade == UP_GRENADE )
+ {
+ if( ent->client->ps.stats[ STAT_GRENADES ] > 0 )
+ {
+ ent->client->ps.stats[ STAT_GRENADES ]--;
+ G_AddCreditToClient( ent->client, (short)BG_Upgrade( upgrade )->price, qfalse );
+ }
+ }
//remove upgrade if carried
- if( BG_InventoryContainsUpgrade( upgrade, ent->client->ps.stats ) )
+ else if( BG_InventoryContainsUpgrade( upgrade, ent->client->ps.stats ) )
{
// shouldn't really need to test for this, but just to be safe
if( upgrade == UP_BATTLESUIT )
@@ -2413,6 +2460,14 @@ void Cmd_Sell_f( gentity_t *ent )
G_AddCreditToClient( ent->client, (short)BG_Upgrade( i )->price, qfalse );
}
}
+
+ if( ent->client->ps.stats[ STAT_GRENADES ] > 0 )
+ {
+ G_AddCreditToClient( ent->client,
+ ent->client->ps.stats[ STAT_GRENADES ] *
+ (short)BG_Upgrade( UP_GRENADE )->price, qfalse );
+ ent->client->ps.stats[ STAT_GRENADES ] = 0;
+ }
}
else
G_TriggerMenu( ent->client->ps.clientNum, MN_H_UNKNOWNITEM );
diff --git a/src/game/g_combat.c b/src/game/g_combat.c
index bfe0de9..397bde0 100644
--- a/src/game/g_combat.c
+++ b/src/game/g_combat.c
@@ -432,6 +432,21 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
if( level.intermissiontime )
return;
+ if( self->client->ps.weapon == WP_GRENADE &&
+ self->client->ps.stats[ STAT_MISC ] > 0 )
+ {
+ int fuse_left;
+
+ fuse_left = GRENADE_FUSE_TIME - self->client->ps.stats[ STAT_MISC ];
+
+ if( fuse_left < 0 )
+ {
+ fuse_left = 0;
+ }
+
+ launch_grenade( self, self->s.origin, vec3_origin, fuse_left );
+ }
+
self->client->ps.pm_type = PM_DEAD;
self->suicideTime = 0;
diff --git a/src/game/g_local.h b/src/game/g_local.h
index c1cde73..c968642 100644
--- a/src/game/g_local.h
+++ b/src/game/g_local.h
@@ -1011,8 +1011,7 @@ gentity_t *fire_bounceBall( gentity_t *self, vec3_t start, vec3_t dir );
gentity_t *fire_bounceBall2( gentity_t *self, vec3_t start, vec3_t dir, int weapon, int dmg, int mod, int speed, int radius );
gentity_t *fire_bounceBall3( gentity_t *self, vec3_t start, vec3_t dir, int weapon, int dmg, int mod, int speed, int radius );
gentity_t *fire_hive( gentity_t *self, vec3_t start, vec3_t dir );
-gentity_t *launch_grenade( gentity_t *self, vec3_t start, vec3_t dir );
-gentity_t *launch_grenade_flames( gentity_t *self, vec3_t start, vec3_t dir );
+gentity_t *launch_grenade( gentity_t *self, vec3_t start, vec3_t dir, int fuse_time );
gentity_t *launch_shield( gentity_t *self, vec3_t start, vec3_t dir );
gentity_t *launch_saw( gentity_t *self, vec3_t start, vec3_t dir );
gentity_t *fire_md2( gentity_t *self, vec3_t start, vec3_t dir );
diff --git a/src/game/g_missile.c b/src/game/g_missile.c
index 5dd9725..8d7a93c 100644
--- a/src/game/g_missile.c
+++ b/src/game/g_missile.c
@@ -695,7 +695,7 @@ gentity_t *fire_rocket( gentity_t *self, vec3_t start, vec3_t dir )
launch_grenade
=================
*/
-gentity_t *launch_grenade( gentity_t *self, vec3_t start, vec3_t dir )
+gentity_t *launch_grenade( gentity_t *self, vec3_t start, vec3_t dir, int fuse_time )
{
gentity_t *bolt;
@@ -703,7 +703,7 @@ gentity_t *launch_grenade( gentity_t *self, vec3_t start, vec3_t dir )
bolt = G_Spawn( );
bolt->classname = "grenade";
bolt->pointAgainstWorld = qfalse;
- bolt->nextthink = level.time + 5000;
+ bolt->nextthink = level.time + fuse_time;
bolt->think = G_ExplodeMissile;
bolt->s.eType = ET_MISSILE;
bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;
diff --git a/src/game/g_team.c b/src/game/g_team.c
index f92936f..ad0873c 100644
--- a/src/game/g_team.c
+++ b/src/game/g_team.c
@@ -302,7 +302,7 @@ void G_BalanceTeams( void )
// Refund all weapons and equipment before team change
for( i = WP_NONE+1; i < WP_NUM_WEAPONS; ++i )
{
- if ( i == WP_HBUILD && ent->client->ps.stats[ STAT_MISC ] > 0 )
+ if ( i == WP_HBUILD && ent->client->ps.stats[ STAT_BUILD_TIMER ] > 0 )
continue;
if (BG_InventoryContainsWeapon( i, ent->client->ps.stats ) && BG_Weapon( i )->purchasable )
{
diff --git a/src/game/g_weapon.c b/src/game/g_weapon.c
index 0925973..265358a 100644
--- a/src/game/g_weapon.c
+++ b/src/game/g_weapon.c
@@ -80,7 +80,12 @@ void G_GiveClientMaxAmmo( gentity_t *ent, qboolean buyingEnergyAmmo )
for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ )
{
qboolean energyWeapon;
-
+
+ if( i == WP_GRENADE )
+ {
+ continue;
+ }
+
energyWeapon = BG_Weapon( i )->usesEnergy;
if( !BG_InventoryContainsWeapon( i, ent->client->ps.stats ) ||
BG_Weapon( i )->infiniteAmmo ||
@@ -626,9 +631,20 @@ GRENADE
void throwGrenade( gentity_t *ent )
{
+ int fuse_left;
+
G_CombatStats_Fire( ent, CSW_GRENADE, GRENADE_DAMAGE );
- launch_grenade( ent, muzzle, forward );
+ fuse_left = GRENADE_FUSE_TIME - ent->client->ps.stats[ STAT_MISC ];
+
+ if( fuse_left < 0 )
+ {
+ fuse_left = 0;
+ }
+
+ launch_grenade( ent, muzzle, forward, fuse_left );
+
+ ent->client->ps.stats[ STAT_MISC ] = 0;
}
/*
@@ -937,7 +953,7 @@ void CheckCkitRepair( gentity_t *ent )
int bHealth;
if( ent->client->ps.weaponTime > 0 ||
- ent->client->ps.stats[ STAT_MISC ] > 0 )
+ ent->client->ps.stats[ STAT_BUILD_TIMER ] > 0 )
return;
BG_GetClientViewOrigin( &ent->client->ps, viewOrigin );
@@ -997,7 +1013,7 @@ void buildFire( gentity_t *ent, dynMenu_t menu )
if( buildable > BA_NONE )
{
- if( ent->client->ps.stats[ STAT_MISC ] > 0 )
+ if( ent->client->ps.stats[ STAT_BUILD_TIMER ] > 0 )
{
G_AddEvent( ent, EV_BUILD_DELAY, ent->client->ps.clientNum );
return;
@@ -1007,7 +1023,7 @@ void buildFire( gentity_t *ent, dynMenu_t menu )
{
if( !g_cheats.integer )
{
- ent->client->ps.stats[ STAT_MISC ] +=
+ ent->client->ps.stats[ STAT_BUILD_TIMER ] +=
BG_Buildable( buildable )->buildTime;
}
diff --git a/src/game/tremulous.h b/src/game/tremulous.h
index 3262b55..9a7a8c8 100644
--- a/src/game/tremulous.h
+++ b/src/game/tremulous.h
@@ -357,11 +357,15 @@ TREMULOUS EDGE MOD SRC FILE
#define PAINSAW_BLADERANGE 100.0f
#define GRENADE_PRICE 200
-#define GRENADE_REPEAT 0
+#define GRENADE_MAX 3
+#define GRENADE_REPEAT 500
#define GRENADE_K_SCALE 1.0f
-#define GRENADE_DAMAGE HDM(340)
+#define GRENADE_DAMAGE HDM(200)
#define GRENADE_RANGE 192.0f
#define GRENADE_SPEED 700.0f
+#define GRENADE_TIME_MIN 500
+#define GRENADE_TIME_WARN 1500
+#define GRENADE_FUSE_TIME 3000
#define SHOTGUN_PRICE 150
#define SHOTGUN_SHELLS 8
diff --git a/src/ui/ui_local.h b/src/ui/ui_local.h
index 2c78e26..1d4303a 100644
--- a/src/ui/ui_local.h
+++ b/src/ui/ui_local.h
@@ -270,6 +270,7 @@ typedef struct
int weapons;
int upgrades;
+ int grenades;
serverStatus_t serverStatus;
diff --git a/src/ui/ui_main.c b/src/ui/ui_main.c
index 6487fae..dc5bc26 100644
--- a/src/ui/ui_main.c
+++ b/src/ui/ui_main.c
@@ -2353,6 +2353,17 @@ static void UI_ParseCarriageList( void )
uiInfo.upgrades |= ( 1 << i );
}
+ else if( iterator[ 0 ] == 'G' )
+ {
+ iterator++;
+
+ while( iterator[ 0 ] != ' ' )
+ *bufPointer++ = *iterator++;
+
+ *bufPointer++ = '\n';
+
+ uiInfo.grenades = atoi( buffer );
+ }
iterator++;
}
@@ -2444,7 +2455,7 @@ static void UI_LoadHumanArmourySells( void )
{
if( uiInfo.weapons & ( 1 << i ) )
{
- uiInfo.humanArmourySellList[ j ].text = BG_Weapon( i )->humanName;
+ uiInfo.humanArmourySellList[ j ].text =BG_Weapon( i )->humanName;
uiInfo.humanArmourySellList[ j ].cmd =
String_Alloc( va( "cmd sell %s\n", BG_Weapon( i )->name ) );
uiInfo.humanArmourySellList[ j ].type = INFOTYPE_WEAPON;
@@ -2458,9 +2469,18 @@ static void UI_LoadHumanArmourySells( void )
for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ )
{
- if( uiInfo.upgrades & ( 1 << i ) )
+ if( ( uiInfo.upgrades & ( 1 << i ) ) ||
+ ( i == UP_GRENADE && uiInfo.grenades ) )
{
- uiInfo.humanArmourySellList[ j ].text = BG_Upgrade( i )->humanName;
+ if( i == UP_GRENADE )
+ {
+ uiInfo.humanArmourySellList[ j ].text =
+ String_Alloc( va( "%s (%d)", BG_Upgrade( i )->humanName, uiInfo.grenades ) );
+ }
+ else
+ {
+ uiInfo.humanArmourySellList[ j ].text = BG_Upgrade( i )->humanName;
+ }
uiInfo.humanArmourySellList[ j ].cmd =
String_Alloc( va( "cmd sell %s\n", BG_Upgrade( i )->name ) );
uiInfo.humanArmourySellList[ j ].type = INFOTYPE_UPGRADE;
@@ -2482,10 +2502,13 @@ static void UI_ArmouryRefreshCb( void *data )
{
int oldWeapons = uiInfo.weapons;
int oldUpgrades = uiInfo.upgrades;
+ int oldGrenades = uiInfo.grenades;
UI_ParseCarriageList( );
- if( uiInfo.weapons != oldWeapons || uiInfo.upgrades != oldUpgrades )
+ if( uiInfo.weapons != oldWeapons ||
+ uiInfo.upgrades != oldUpgrades ||
+ uiInfo.grenades != oldGrenades )
{
UI_LoadHumanArmouryBuys( );
UI_LoadHumanArmourySells( );