From 0918eb3bcdefd0d6ee4bd573b761454c99f032f6 Mon Sep 17 00:00:00 2001 From: Paweł Redman Date: Mon, 29 Jun 2015 00:52:09 +0200 Subject: Initial implementation of new grenades. --- assets/models/players/human_base/animation.cfg | 4 + assets/models/players/human_bsuit/animation.cfg | 4 + assets/models/weapons/grenade/LICENSE | 1 + assets/models/weapons/grenade/flash0.wav | Bin 0 -> 20200 bytes assets/models/weapons/grenade/grenade.jpg | Bin 31424 -> 19526 bytes assets/models/weapons/grenade/weapon.cfg | 6 +- assets/scripts/aw_level4.particle | 199 ---------- assets/scripts/hu_explosive_grenade.particle | 498 ++---------------------- assets/scripts/hw_flamer.particle | 160 -------- assets/scripts/hw_flamer.trail | 14 - assets/sound/weapons/grenade/LICENSE | 3 + assets/sound/weapons/grenade/prime.wav | Bin 0 -> 22780 bytes assets/sound/weapons/grenade/tick.wav | Bin 0 -> 10960 bytes src/cgame/cg_draw.c | 52 ++- src/cgame/cg_event.c | 8 + src/cgame/cg_local.h | 3 + src/cgame/cg_main.c | 6 +- src/cgame/cg_weapons.c | 36 +- src/game/bg_misc.c | 42 +- src/game/bg_pmove.c | 135 +++++-- src/game/bg_public.h | 12 +- src/game/g_active.c | 9 +- src/game/g_client.c | 2 +- src/game/g_cmds.c | 81 +++- src/game/g_combat.c | 15 + src/game/g_local.h | 3 +- src/game/g_missile.c | 4 +- src/game/g_team.c | 2 +- src/game/g_weapon.c | 26 +- src/game/tremulous.h | 8 +- src/ui/ui_local.h | 1 + src/ui/ui_main.c | 31 +- 32 files changed, 434 insertions(+), 931 deletions(-) create mode 100644 assets/models/weapons/grenade/LICENSE create mode 100644 assets/models/weapons/grenade/flash0.wav delete mode 100644 assets/scripts/aw_level4.particle delete mode 100644 assets/scripts/hw_flamer.trail create mode 100644 assets/sound/weapons/grenade/LICENSE create mode 100644 assets/sound/weapons/grenade/prime.wav create mode 100644 assets/sound/weapons/grenade/tick.wav 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 Binary files /dev/null and b/assets/models/weapons/grenade/flash0.wav differ diff --git a/assets/models/weapons/grenade/grenade.jpg b/assets/models/weapons/grenade/grenade.jpg index a645b65..eb9240d 100644 Binary files a/assets/models/weapons/grenade/grenade.jpg and b/assets/models/weapons/grenade/grenade.jpg 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 Binary files /dev/null and b/assets/sound/weapons/grenade/prime.wav differ diff --git a/assets/sound/weapons/grenade/tick.wav b/assets/sound/weapons/grenade/tick.wav new file mode 100644 index 0000000..6624c47 Binary files /dev/null and b/assets/sound/weapons/grenade/tick.wav 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( ); -- cgit