From: Rudolf Polzer Date: Fri, 20 Jan 2012 16:17:25 +0000 (+0100) Subject: Merge branch 'master' of git://de.git.xonotic.org/xonotic/xonotic-data.pk3dir X-Git-Tag: xonotic-v0.6.0~104^2~7 X-Git-Url: http://git.xonotic.org/?a=commitdiff_plain;h=2ab57b248854a04ac90ab5652f409770a20139c0;hp=58eb471d26174f7d18d8ea0777378fb16ce17db2;p=xonotic%2Fxonotic-data.pk3dir.git Merge branch 'master' of git://de.git.xonotic.org/xonotic/xonotic-data.pk3dir --- diff --git a/defaultXonotic.cfg b/defaultXonotic.cfg index 5c142926a..b3092fa09 100644 --- a/defaultXonotic.cfg +++ b/defaultXonotic.cfg @@ -321,6 +321,14 @@ set g_telefrags_teamplay 1 "never telefrag team mates" set g_telefrags_avoid 1 "when teleporters have a random destination, avoid teleporting to locations where a telefrag would happen" set g_teleport_maxspeed 0 "maximum speed that a player can keep when going through a teleporter (if a misc_teleporter_dest also has a cap the smallest one of these will be used), 0 = don't limit, -1 = keep no speed" +seta cl_damageeffect 1 "enable weapon damage effects. 1 enables the feature on skeletal models, 2 on any model" +seta cl_damageeffect_ticrate 0.1 "particle spawn rate" +seta cl_damageeffect_bones 5 "how many damages to allow on a rigged mesh at once (non-skeletal objects are limited to one)" +seta cl_damageeffect_distribute 1 "divide particle intensity if multiple damages are present" +seta cl_damageeffect_lifetime 0.1 "how much a damage effect lasts, based on damage amount" +seta cl_damageeffect_lifetime_min 3 "minimum lifetime a damage effect may have" +seta cl_damageeffect_lifetime_max 6 "maximum lifetime a damage effect may have" + set g_respawn_ghosts 1 "if 1 dead bodies become ghosts and float away when the player respawns" set g_respawn_ghosts_speed 5 "the speed with which respawn ghosts float and rotate" set g_respawn_ghosts_maxtime 6 "maximum amount of time a respawn ghost can last, minimum time is half this value. 0 disables and ghosts fade when the body would" diff --git a/effectinfo.txt b/effectinfo.txt index 0d464f5f7..8b555fa89 100644 --- a/effectinfo.txt +++ b/effectinfo.txt @@ -6686,3 +6686,704 @@ gravity -0.125 bounce 1.5 liquidfriction 4 velocityjitter 16 16 16 + +// laser damage effect +// used in qcsrc/client/damage.qc: pointparticles(self.team, org, '0 0 0', 1); +effect damage_laser +notunderwater +count 3 +type smoke +tex 0 8 +color 0x880000 0xff4400 +size 2 4 +sizeincrease 8 +alpha 128 16 128 +gravity 0 +originjitter 2 2 2 +velocityjitter 0.4 0.4 0.6 +velocitymultiplier 0 +airfriction -0.35 +rotate 0 180 -30 30 + +// shotgun damage effect, normal blood +// used in qcsrc/client/damage.qc: pointparticles(self.team, org, '0 0 0', 1); +effect damage_shotgun +count 0.6 +type blood +tex 24 32 +size 2 4 +alpha 256 256 64 +color 0xA8FFFF 0xA8FFFFF +bounce -1 +airfriction 1 +liquidfriction 4 +velocityjitter 64 64 64 +velocitymultiplier 5 +staincolor 0x808080 0x808080 +staintex 16 24 +//blood mist +effect damage_shotgun +count 1 +type alphastatic +tex 0 8 +size 8 16 +alpha 100 256 400 +color 0x000000 0x420000 +originjitter 1 1 1 + +// shotgun damage effect, alien blood +// used in qcsrc/client/damage.qc: pointparticles(self.team, org, '0 0 0', 1); +effect damage_shotgun_alien +count 0.6 +type blood +tex 24 32 +size 2 4 +alpha 256 256 64 +color 0xDC9BCD 0xDC9BCD +bounce -1 +airfriction 1 +liquidfriction 4 +velocityjitter 64 64 64 +velocitymultiplier 5 +staincolor 0x808080 0x808080 +staintex 16 24 +//blood mist +effect damage_shotgun_alien +count 1 +type alphastatic +tex 0 8 +size 8 16 +alpha 100 256 400 +color 0x000000 0x204010 +originjitter 1 1 1 + +// shotgun damage effect, robot blood +// used in qcsrc/client/damage.qc: pointparticles(self.team, org, '0 0 0', 1); +effect damage_shotgun_robot +count 0.6 +type blood +tex 24 32 +size 2 4 +alpha 256 256 64 +color 0xC0D890 0xC0D890 +bounce -1 +airfriction 1 +liquidfriction 4 +velocityjitter 64 64 64 +velocitymultiplier 5 +staincolor 0x808080 0x808080 +staintex 16 24 +//blood mist +effect damage_shotgun_robot +count 1 +type alphastatic +tex 0 8 +size 8 16 +alpha 100 256 400 +color 0x000000 0x301860 +originjitter 1 1 1 + +// uzi damage effect, normal blood +// used in qcsrc/client/damage.qc: pointparticles(self.team, org, '0 0 0', 1); +effect damage_uzi +count 0.3 +type blood +tex 24 32 +size 2 4 +alpha 256 256 64 +color 0xA8FFFF 0xA8FFFFF +bounce -1 +airfriction 1 +liquidfriction 4 +velocityjitter 32 32 32 +velocitymultiplier 5 +staincolor 0x808080 0x808080 +staintex 16 24 +//blood mist +effect damage_uzi +count 1 +type alphastatic +tex 0 8 +size 6 12 +alpha 100 256 400 +color 0x000000 0x420000 +originjitter 0 0 0 + +// uzi damage effect, alien blood +// used in qcsrc/client/damage.qc: pointparticles(self.team, org, '0 0 0', 1); +effect damage_uzi_alien +count 0.3 +type blood +tex 24 32 +size 2 4 +alpha 256 256 64 +color 0xDC9BCD 0xDC9BCD +bounce -1 +airfriction 1 +liquidfriction 4 +velocityjitter 32 32 32 +velocitymultiplier 5 +staincolor 0x808080 0x808080 +staintex 16 24 +//blood mist +effect damage_uzi_alien +count 1 +type alphastatic +tex 0 8 +size 6 12 +alpha 100 256 400 +color 0x000000 0x204010 +originjitter 0 0 0 + +// uzi damage effect, robot blood +// used in qcsrc/client/damage.qc: pointparticles(self.team, org, '0 0 0', 1); +effect damage_uzi_robot +count 0.3 +type blood +tex 24 32 +size 2 4 +alpha 256 256 64 +color 0xC0D890 0xC0D890 +bounce -1 +airfriction 1 +liquidfriction 4 +velocityjitter 32 32 32 +velocitymultiplier 5 +staincolor 0x808080 0x808080 +staintex 16 24 +//blood mist +effect damage_uzi_robot +count 1 +type alphastatic +tex 0 8 +size 6 12 +alpha 100 256 400 +color 0x000000 0x301860 +originjitter 0 0 0 + +// minelayer damage effect +// used in qcsrc/client/damage.qc: pointparticles(self.team, org, '0 0 0', 1); +effect damage_minelayer +notunderwater +count 3 +type smoke +tex 48 55 +size 4 8 +alpha 512 64 1024 +gravity -0.5 +color 0x8f0d00 0xff5a00 +sizeincrease -15 +originjitter 2 2 2 +velocityjitter 22 22 50 +// smoke +effect damage_minelayer +notunderwater +type alphastatic +count 2 +tex 0 8 +size 4 8 +sizeincrease 5 +alpha 128 32 128 +color 0x000000 0x111111 +gravity -0.3 +originjitter 4 4 4 +velocityjitter 11 11 50 +// light +/*effect damage_minelayer +notunderwater +trailspacing 8 +lightradius 60 +lightradiusfade 280 +lightcolor 0.7 0.4 0.2*/ + +// grenadelauncher damage effect +// used in qcsrc/client/damage.qc: pointparticles(self.team, org, '0 0 0', 1); +effect damage_grenadelauncher +notunderwater +count 3 +type smoke +tex 48 55 +size 4 8 +alpha 512 64 1024 +gravity -0.5 +color 0x8f0d00 0xff5a00 +sizeincrease -15 +originjitter 2 2 2 +velocityjitter 22 22 50 +// smoke +effect damage_grenadelauncher +notunderwater +type alphastatic +count 2 +tex 0 8 +size 4 8 +sizeincrease 5 +alpha 128 32 128 +color 0x000000 0x111111 +gravity -0.3 +originjitter 4 4 4 +velocityjitter 11 11 50 +// light +/*effect damage_grenadelauncher +notunderwater +trailspacing 8 +lightradius 60 +lightradiusfade 280 +lightcolor 0.7 0.4 0.2*/ + +// electro damage effect +// used in qcsrc/client/damage.qc: pointparticles(self.team, org, '0 0 0', 1); +effect damage_electro +notunderwater +count 2 +type static +tex 47 47 +color 0x66ffff 0x2288ff +size 6 10 +sizeincrease -14 +alpha 48 8 48 +gravity -0.0001 +airfriction 0.2 +liquidfriction 0.8 +originjitter 3 3 3 +velocityjitter 8 8 16 +velocitymultiplier 0 +airfriction -0.5 +rotate 180 360 -30 30 +// plasma smoke +effect damage_electro +notunderwater +count 4 +type smoke +tex 0 8 +color 0x2244ff 0x002266 +size 4 8 +sizeincrease 10 +alpha 64 16 64 +gravity 0 +originjitter 4 4 4 +velocityjitter 0.4 0.4 0.6 +velocitymultiplier 0 +airfriction -0.35 +rotate 0 180 -30 30 +// bouncing sparks +effect damage_electro +count 0.5 +type spark +tex 66 68 +color 0x003090 0x00CCFF +size 1 1 +alpha 768 64 256 +gravity 0.2 +airfriction 1 +bounce 1.5 +liquidfriction 0.8 +velocityoffset 0 0 0 +velocityjitter 32 32 32 +// light +/*effect damage_electro +notunderwater +trailspacing 8 +lightradius 50 +lightradiusfade 220 +lightcolor 0.2 0.6 0.8*/ + +// crylink damage effect +// used in qcsrc/client/damage.qc: pointparticles(self.team, org, '0 0 0', 1); +effect damage_crylink +notunderwater +count 2 +type static +tex 38 38 +color 0xff44ff 0x9966ff +size 0.5 1 +sizeincrease -8 +alpha 48 16 48 +gravity -0.0001 +airfriction 0.6 +liquidfriction 0.8 +originjitter 3 3 3 +velocityjitter 10 10 20 +velocitymultiplier 0 +airfriction -0.5 +rotate 180 360 -30 30 +// plasma smoke +effect damage_crylink +notunderwater +count 4 +type smoke +tex 0 8 +color 0x8844ff 0x662244 +size 5 10 +sizeincrease 6 +alpha 64 16 64 +gravity 0.001 +originjitter 4 4 4 +velocityjitter 0.4 0.4 0.6 +velocitymultiplier 0 +airfriction -0.35 +rotate 0 180 -30 30 +// floating sparks +effect damage_crylink +count 0.3 +type spark +color 0x903090 0xFFD0FF +size 0.5 0.5 +sizeincrease -5 +alpha 192 192 128 +gravity 0 +airfriction 0.2 +liquidfriction 0.8 +velocityoffset 0 0 0 +velocityjitter 12 12 12 +// light +/*effect damage_crylink +notunderwater +trailspacing 8 +lightradius 50 +lightradiusfade 240 +lightcolor 0.6 0.2 0.8*/ + +// hlac damage effect +// used in qcsrc/client/damage.qc: pointparticles(self.team, org, '0 0 0', 1); +effect damage_hlac +notunderwater +count 3 +type smoke +tex 0 8 +color 0x880000 0xff4400 +size 2 4 +sizeincrease 10 +alpha 128 16 128 +gravity 0 +originjitter 4 4 4 +velocityjitter 0.4 0.4 0.6 +velocitymultiplier 0 +airfriction -0.35 +rotate 0 180 -30 30 + +// nex damage effect +// used in qcsrc/client/damage.qc: pointparticles(self.team, org, '0 0 0', 1); +effect damage_nex +count 1 +type static +tex 47 47 +color 0xffffff 0x88ffff +size 5 10 +sizeincrease -14 +alpha 64 8 64 +gravity -0.0001 +airfriction 0.1 +liquidfriction 0.6 +originjitter 4 4 4 +velocityjitter 8 8 16 +velocitymultiplier 0 +airfriction -0.5 +rotate 180 360 -30 30 +// plasma smoke +effect damage_nex +count 2 +type smoke +tex 0 8 +color 0x6688ff 0x226688 +size 4 8 +sizeincrease 8 +alpha 64 16 64 +gravity 0 +originjitter 2 2 2 +velocityjitter 0.5 0.5 0.8 +velocitymultiplier 0 +airfriction -0.35 +rotate 0 180 -30 30 +// bouncing sparks +effect damage_nex +count 0.2 +type spark +tex 41 41 +color 0xD9FDFF 0xD9FDFF +size 1 1 +alpha 255 255 112 +bounce 1.6 +stretchfactor 0.7 +velocityjitter 100 100 300 +velocitymultiplier 3 +airfriction 2 +gravity 1 +// light +/*effect damage_nex +trailspacing 8 +lightradius 60 +lightradiusfade 280 +lightcolor 0.6 0.8 0.8*/ + +// minstanex damage effect +// used in qcsrc/client/damage.qc: pointparticles(self.team, org, '0 0 0', 1); +effect damage_minstanex +count 2 +type static +tex 47 47 +color 0xffffff 0x88ffff +size 5 10 +sizeincrease -14 +alpha 64 8 64 +gravity -0.0001 +airfriction 0.1 +liquidfriction 0.6 +originjitter 4 4 4 +velocityjitter 8 8 16 +velocitymultiplier 0 +airfriction -0.5 +rotate 180 360 -30 30 +// plasma smoke +effect damage_minstanex +count 4 +type smoke +tex 0 8 +color 0x6688ff 0x226688 +size 4 8 +sizeincrease 8 +alpha 64 16 64 +gravity 0 +originjitter 2 2 2 +velocityjitter 0.5 0.5 0.8 +velocitymultiplier 0 +airfriction -0.35 +rotate 0 180 -30 30 +// bouncing sparks +effect damage_minstanex +count 0.2 +type spark +tex 41 41 +color 0xD9FDFF 0xD9FDFF +size 1 1 +alpha 255 255 112 +bounce 1.6 +stretchfactor 0.7 +velocityjitter 100 100 300 +velocitymultiplier 3 +airfriction 2 +gravity 1 +// light +/*effect damage_minstanex +trailspacing 8 +lightradius 60 +lightradiusfade 240 +lightcolor 0.6 0.8 0.8*/ + +// sniperrifle damage effect, normal blood +// used in qcsrc/client/damage.qc: pointparticles(self.team, org, '0 0 0', 1); +effect damage_rifle +count 0.3 +type blood +tex 24 32 +size 2 4 +alpha 256 256 64 +color 0xA8FFFF 0xA8FFFFF +bounce -1 +airfriction 1 +liquidfriction 4 +velocityjitter 32 32 32 +velocitymultiplier 5 +staincolor 0x808080 0x808080 +staintex 16 24 +//blood mist +effect damage_rifle +count 1 +type alphastatic +tex 0 8 +size 6 12 +alpha 100 256 400 +color 0x000000 0x420000 +originjitter 0 0 0 + +// sniperrifle damage effect, alien blood +// used in qcsrc/client/damage.qc: pointparticles(self.team, org, '0 0 0', 1); +effect damage_rifle_alien +count 0.3 +type blood +tex 24 32 +size 2 4 +alpha 256 256 64 +color 0xDC9BCD 0xDC9BCD +bounce -1 +airfriction 1 +liquidfriction 4 +velocityjitter 32 32 32 +velocitymultiplier 5 +staincolor 0x808080 0x808080 +staintex 16 24 +//blood mist +effect damage_rifle_alien +count 1 +type alphastatic +tex 0 8 +size 6 12 +alpha 100 256 400 +color 0x000000 0x204010 +originjitter 0 0 0 + +// sniperrifle damage effect, robot blood +// used in qcsrc/client/damage.qc: pointparticles(self.team, org, '0 0 0', 1); +effect damage_rifle_robot +count 0.3 +type blood +tex 24 32 +size 2 4 +alpha 256 256 64 +color 0xC0D890 0xC0D890 +bounce -1 +airfriction 1 +liquidfriction 4 +velocityjitter 32 32 32 +velocitymultiplier 5 +staincolor 0x808080 0x808080 +staintex 16 24 +//blood mist +effect damage_rifle_robot +count 1 +type alphastatic +tex 0 8 +size 6 12 +alpha 100 256 400 +color 0x000000 0x301860 +originjitter 0 0 0 + +// seeker damage effect +// used in qcsrc/client/damage.qc: pointparticles(self.team, org, '0 0 0', 1); +effect damage_seeker +notunderwater +count 3 +type smoke +tex 48 55 +size 4 8 +alpha 512 32 1024 +gravity -0.3 +color 0x8f0c00 0xff2200 +sizeincrease -10 +originjitter 2 2 2 +velocityjitter 22 22 50 +// smoke +effect damage_seeker +notunderwater +type alphastatic +count 2 +tex 0 8 +size 2 4 +sizeincrease 10 +alpha 128 32 128 +color 0x000000 0x111111 +gravity -0.3 +originjitter 4 4 4 +velocityjitter 11 11 50 +// light +/*effect damage_seeker +notunderwater +trailspacing 8 +lightradius 65 +lightradiusfade 280 +lightcolor 0.7 0.5 0.1*/ + +// hagar damage effect +// used in qcsrc/client/damage.qc: pointparticles(self.team, org, '0 0 0', 1); +effect damage_hagar +notunderwater +count 3 +type smoke +tex 48 55 +size 4 8 +alpha 512 32 1024 +gravity -0.3 +color 0x8f0c00 0xff3a00 +sizeincrease -10 +originjitter 2 2 2 +velocityjitter 22 22 50 +// smoke +effect damage_hagar +notunderwater +type alphastatic +count 2 +tex 0 8 +size 2 4 +sizeincrease 10 +alpha 128 32 128 +color 0x000000 0x111111 +gravity -0.3 +originjitter 4 4 4 +velocityjitter 11 11 50 +// light +/*effect damage_hagar +notunderwater +trailspacing 8 +lightradius 65 +lightradiusfade 280 +lightcolor 0.7 0.5 0.1*/ + +// fireball damage effect +// used in qcsrc/client/damage.qc: pointparticles(self.team, org, '0 0 0', 1); +effect damage_fireball +notunderwater +count 4 +type smoke +tex 48 55 +size 5 10 +alpha 256 16 512 +gravity -0.5 +color 0x8f0d00 0xff5a00 +sizeincrease -10 +originjitter 8 8 8 +velocityjitter 22 22 50 +// smoke +effect damage_fireball +notunderwater +type alphastatic +count 4 +tex 0 8 +size 4 8 +sizeincrease 10 +alpha 128 32 128 +color 0x000000 0x111111 +gravity -0.3 +originjitter 6 6 6 +velocityjitter 11 11 50 +// light +/*effect damage_fireball +notunderwater +trailspacing 8 +lightradius 65 +lightradiusfade 280 +lightcolor 1.0 0.8 0.4*/ + +// rocketlauncher damage effect +// used in qcsrc/client/damage.qc: pointparticles(self.team, org, '0 0 0', 1); +effect damage_rocketlauncher +notunderwater +count 3 +type smoke +tex 48 55 +size 5 10 +alpha 512 64 1024 +gravity -0.7 +color 0x8f0c00 0xff2a00 +sizeincrease -10 +originjitter 4 4 4 +velocityjitter 22 22 30 +// smoke +effect damage_rocketlauncher +notunderwater +type alphastatic +count 3 +tex 0 8 +size 4 8 +sizeincrease 10 +alpha 128 32 128 +color 0x000000 0x111111 +gravity -0.3 +originjitter 4 4 4 +velocityjitter 11 11 50 +// light +/*effect damage_rocketlauncher +notunderwater +trailspacing 8 +lightradius 60 +lightradiusfade 280 +lightcolor 0.8 0.6 0.2*/ diff --git a/effects-high.cfg b/effects-high.cfg index 0e011fe56..95fd0f8bd 100644 --- a/effects-high.cfg +++ b/effects-high.cfg @@ -2,6 +2,7 @@ cl_decals 1 cl_decals_models 0 cl_decals_time 4 cl_particles_quality 1 +cl_damageeffect 1 gl_flashblend 0 gl_picmip -1 gl_texture_anisotropy 16 diff --git a/effects-low.cfg b/effects-low.cfg index a9cff5abe..e4391c703 100644 --- a/effects-low.cfg +++ b/effects-low.cfg @@ -2,6 +2,7 @@ cl_decals 1 cl_decals_models 0 cl_decals_time 2 cl_particles_quality 0.4 +cl_damageeffect 0 gl_flashblend 1 gl_picmip 1 gl_texture_anisotropy 1 diff --git a/effects-med.cfg b/effects-med.cfg index 5be8356e2..de41d388c 100644 --- a/effects-med.cfg +++ b/effects-med.cfg @@ -2,6 +2,7 @@ cl_decals 1 cl_decals_models 0 cl_decals_time 2 cl_particles_quality 1 +cl_damageeffect 0 gl_flashblend 0 gl_picmip 0 gl_texture_anisotropy 1 diff --git a/effects-normal.cfg b/effects-normal.cfg index 0aebfb79d..490087efd 100644 --- a/effects-normal.cfg +++ b/effects-normal.cfg @@ -2,6 +2,7 @@ cl_decals 1 cl_decals_models 0 cl_decals_time 2 cl_particles_quality 1 +cl_damageeffect 1 gl_flashblend 0 gl_picmip 0 gl_texture_anisotropy 1 diff --git a/effects-omg.cfg b/effects-omg.cfg index 350e9b849..55a91e450 100644 --- a/effects-omg.cfg +++ b/effects-omg.cfg @@ -2,6 +2,7 @@ cl_decals 0 cl_decals_models 0 cl_decals_time 2 cl_particles_quality 0.4 +cl_damageeffect 0 gl_flashblend 1 gl_picmip 1337 gl_texture_anisotropy 1 diff --git a/effects-ultimate.cfg b/effects-ultimate.cfg index 7e4125bf4..8c859f08d 100644 --- a/effects-ultimate.cfg +++ b/effects-ultimate.cfg @@ -2,6 +2,7 @@ cl_decals 1 cl_decals_models 1 cl_decals_time 10 cl_particles_quality 1 +cl_damageeffect 2 gl_flashblend 0 gl_picmip -1 gl_texture_anisotropy 16 diff --git a/effects-ultra.cfg b/effects-ultra.cfg index 1c9b9db30..9dda230ca 100644 --- a/effects-ultra.cfg +++ b/effects-ultra.cfg @@ -2,6 +2,7 @@ cl_decals 1 cl_decals_models 1 cl_decals_time 10 cl_particles_quality 1 +cl_damageeffect 1 gl_flashblend 0 gl_picmip -1 gl_texture_anisotropy 16 diff --git a/models/null.md3 b/models/null.md3 deleted file mode 100644 index 288e88f3f..000000000 Binary files a/models/null.md3 and /dev/null differ diff --git a/qcsrc/client/autocvars.qh b/qcsrc/client/autocvars.qh index 5c05e2fee..eb7c6d2fb 100644 --- a/qcsrc/client/autocvars.qh +++ b/qcsrc/client/autocvars.qh @@ -374,6 +374,13 @@ var float autocvar_cl_eventchase_distance = 140; var float autocvar_cl_eventchase_speed = 1.3; float autocvar_cl_lerpexcess; string autocvar__togglezoom; +float autocvar_cl_damageeffect; +float autocvar_cl_damageeffect_ticrate; +float autocvar_cl_damageeffect_bones; +float autocvar_cl_damageeffect_distribute; +float autocvar_cl_damageeffect_lifetime; +float autocvar_cl_damageeffect_lifetime_min; +float autocvar_cl_damageeffect_lifetime_max; float autocvar_cl_playerdetailreduction; float autocvar_cl_loddistance1 = 1024; float autocvar_cl_loddistance2 = 4096; diff --git a/qcsrc/client/damage.qc b/qcsrc/client/damage.qc index 5910dba3e..34c15837a 100644 --- a/qcsrc/client/damage.qc +++ b/qcsrc/client/damage.qc @@ -1,6 +1,119 @@ +void DamageEffect_Think() +{ + // if particle distribution is enabled, slow ticrate by total number of damages + if(autocvar_cl_damageeffect_distribute) + self.nextthink = time + autocvar_cl_damageeffect_ticrate * self.owner.total_damages; + else + self.nextthink = time + autocvar_cl_damageeffect_ticrate; + + if(time >= self.cnt || !self.owner || !self.owner.modelindex || !self.owner.drawmask) + { + // time is up or the player got gibbed / disconnected + self.owner.total_damages = max(0, self.owner.total_damages - 1); + remove(self); + return; + } + if(self.state && !self.owner.csqcmodel_isdead) + { + // if the player was dead but is now alive, it means he respawned + // if so, clear his damage effects, or damages from his dead body will be copied back + self.owner.total_damages = max(0, self.owner.total_damages - 1); + remove(self); + return; + } + self.state = self.owner.csqcmodel_isdead; +#ifdef COMPAT_XON050_ENGINE + if(self.owner.isplayermodel && (self.owner.entnum == player_localentnum || self.owner.entnum == spectatee_status) && !autocvar_chase_active) +#else + if(self.owner.isplayermodel && (self.owner.entnum == player_localentnum) && !autocvar_chase_active) +#endif + return; // if we aren't using a third person camera, hide our own effects + + // now generate the particles + vector org; + org = gettaginfo(self, 0); // origin at attached location + pointparticles(self.team, org, '0 0 0', 1); +} + +void DamageEffect(vector hitorg, float dmg, float type, float specnum) +{ + // particle effects for players and objects damaged by weapons (eg: flames coming out of victims shot with rockets) + + float life, nearestbone; + string specstr, effectname; + entity e; + + if(!autocvar_cl_damageeffect || autocvar_cl_gentle || autocvar_cl_gentle_damage) + return; + if(!self || !self.modelindex || !self.drawmask) + return; + + // if this is a rigged mesh, the effect will show on the bone where damage was dealt + // we do this by choosing the skeletal bone closest to the impact, and attaching our entity to it + // if there's no skeleton, object origin will automatically be selected + FOR_EACH_TAG(self) + { + if(!tagnum) + continue; // skip empty bones + // blacklist bones positioned outside the mesh, or the effect will be floating + // TODO: Do we have to do it this way? Why do these bones exist at all? + if(gettaginfo_name == "master" || gettaginfo_name == "knee_L" || gettaginfo_name == "knee_R" || gettaginfo_name == "leg_L" || gettaginfo_name == "leg_R") + continue; // player model bone blacklist + + // now choose the bone closest to impact origin + if(vlen(hitorg - gettaginfo(self, tagnum)) <= vlen(hitorg - gettaginfo(self, nearestbone))) + nearestbone = tagnum; + } + gettaginfo(self, nearestbone); // set gettaginfo_name + + // return if we reached our damage effect limit or damages are disabled + // TODO: When the limit is reached, it would be better if the oldest damage was removed instead of not adding a new one + if(nearestbone) + { + if(self.total_damages >= autocvar_cl_damageeffect_bones) + return; // allow multiple damages on skeletal models + } + else + { + if(autocvar_cl_damageeffect < 2 || self.total_damages) + return; // allow a single damage on non-skeletal models + } + + life = bound(autocvar_cl_damageeffect_lifetime_min, dmg * autocvar_cl_damageeffect_lifetime, autocvar_cl_damageeffect_lifetime_max); + specstr = species_prefix(specnum); + type = DEATH_WEAPONOF(type); + e = get_weaponinfo(type); + + effectname = strcat("damage_", e.netname); + + // if damage was dealt with a bullet weapon, our effect is blood + // since blood is species dependent, include the species tag + if(type == WEP_SHOTGUN || type == WEP_UZI || type == WEP_RIFLE) + { + if(self.isplayermodel) + { + effectname = strcat(effectname, "_", specstr); + effectname = substring(effectname, 0, strlen(effectname) - 1); // remove the _ symbol at the end of the species tag + } + else + return; // objects don't bleed + } + + e = spawn(); + setmodel(e, "null"); // necessary to attach and read origin // samual: FIXME: this is weird, is there some better way to do this? + setattachment(e, self, gettaginfo_name); // attach to the given bone + e.classname = "damage"; + e.owner = self; + e.cnt = time + life; + e.team = particleeffectnum(effectname); + e.think = DamageEffect_Think; + e.nextthink = time; + self.total_damages += 1; +} + void Ent_DamageInfo(float isNew) { - float dmg, rad, edge, thisdmg, forcemul; + float dmg, rad, edge, thisdmg, forcemul, species; vector force, thisforce; entity oldself; @@ -18,6 +131,7 @@ void Ent_DamageInfo(float isNew) rad = ReadByte(); edge = ReadByte(); force = decompressShortVector(ReadShort()); + species = ReadByte(); if not(isNew) return; @@ -72,140 +186,141 @@ void Ent_DamageInfo(float isNew) if(self.event_damage) self.event_damage(thisdmg, w_deathtype, w_org, thisforce); + + DamageEffect(w_org, thisdmg, w_deathtype, species); } self = oldself; if(DEATH_ISVEHICLE(w_deathtype)) { - traceline(w_org - normalize(force) * 16, w_org + normalize(force) * 16, MOVE_NOMONSTERS, world); - if(trace_plane_normal != '0 0 0') - w_backoff = trace_plane_normal; - else - w_backoff = -1 * normalize(w_org - (w_org + normalize(force) * 16)); - - setorigin(self, w_org + w_backoff * 2); // for sound() calls - - switch(w_deathtype) - { - case DEATH_VHCRUSH: - break; - - case DEATH_SBMINIGUN: - string _snd; - _snd = strcat("weapons/ric", ftos(1 + rint(random() * 2)), ".waw"); - sound(self, CH_SHOTS, _snd, VOL_BASE, ATTN_NORM); - pointparticles(particleeffectnum("spiderbot_minigun_impact"), self.origin, w_backoff * 1000, 1); - break; - case DEATH_SBROCKET: - sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM); - pointparticles(particleeffectnum("spiderbot_rocket_explode"), self.origin, w_backoff * 1000, 1); - break; - case DEATH_SBBLOWUP: - sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_MIN); - pointparticles(particleeffectnum("explosion_big"), self.origin, w_backoff * 1000, 1); - break; - - case DEATH_WAKIGUN: - sound(self, CH_SHOTS, "weapons/laserimpact.wav", VOL_BASE, ATTN_NORM); - pointparticles(particleeffectnum("wakizashi_gun_impact"), self.origin, w_backoff * 1000, 1); - break; - case DEATH_WAKIROCKET: - sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM); - pointparticles(particleeffectnum("wakizashi_rocket_explode"), self.origin, w_backoff * 1000, 1); - break; - case DEATH_WAKIBLOWUP: - sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_MIN); - pointparticles(particleeffectnum("explosion_big"), self.origin, w_backoff * 1000, 1); - break; - - case DEATH_RAPTOR_CANNON: - sound(self, CH_SHOTS, "weapons/laserimpact.wav", VOL_BASE, ATTN_NORM); - pointparticles(particleeffectnum("raptor_cannon_impact"), self.origin, w_backoff * 1000, 1); - break; - case DEATH_RAPTOR_BOMB_SPLIT: - float i; - vector ang, vel; - for(i = 1; i < 4; ++i) - { - vel = normalize(w_org - (w_org + normalize(force) * 16)) + randomvec() * 128; - ang = vectoangles(vel); - RaptorCBShellfragToss(w_org, vel, ang + '0 0 1' * (120 * i)); - } - - - sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM); - pointparticles(particleeffectnum("raptor_bomb_spread"), self.origin, w_backoff * 1000, 1); - break; - case DEATH_RAPTOR_BOMB: - sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM); - pointparticles(particleeffectnum("raptor_bomb_impact"), self.origin, w_backoff * 1000, 1); - break; - case DEATH_RAPTOR_DEATH: - sound(self, CH_SHOTS, "weapons/laserimpact.wav", VOL_BASE, ATTN_MIN); - pointparticles(particleeffectnum("explosion_big"), self.origin, w_backoff * 1000, 1); - break; - } + traceline(w_org - normalize(force) * 16, w_org + normalize(force) * 16, MOVE_NOMONSTERS, world); + if(trace_plane_normal != '0 0 0') + w_backoff = trace_plane_normal; + else + w_backoff = -1 * normalize(w_org - (w_org + normalize(force) * 16)); + + setorigin(self, w_org + w_backoff * 2); // for sound() calls + + switch(w_deathtype) + { + case DEATH_VHCRUSH: + break; + + // spiderbot + case DEATH_SBMINIGUN: + string _snd; + _snd = strcat("weapons/ric", ftos(1 + rint(random() * 2)), ".waw"); + sound(self, CH_SHOTS, _snd, VOL_BASE, ATTN_NORM); + pointparticles(particleeffectnum("spiderbot_minigun_impact"), self.origin, w_backoff * 1000, 1); + break; + case DEATH_SBROCKET: + sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM); + pointparticles(particleeffectnum("spiderbot_rocket_explode"), self.origin, w_backoff * 1000, 1); + break; + case DEATH_SBBLOWUP: + sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_MIN); + pointparticles(particleeffectnum("explosion_big"), self.origin, w_backoff * 1000, 1); + break; + + case DEATH_WAKIGUN: + sound(self, CH_SHOTS, "weapons/laserimpact.wav", VOL_BASE, ATTN_NORM); + pointparticles(particleeffectnum("wakizashi_gun_impact"), self.origin, w_backoff * 1000, 1); + break; + case DEATH_WAKIROCKET: + sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM); + pointparticles(particleeffectnum("wakizashi_rocket_explode"), self.origin, w_backoff * 1000, 1); + break; + case DEATH_WAKIBLOWUP: + sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_MIN); + pointparticles(particleeffectnum("explosion_big"), self.origin, w_backoff * 1000, 1); + break; + + case DEATH_RAPTOR_CANNON: + sound(self, CH_SHOTS, "weapons/laserimpact.wav", VOL_BASE, ATTN_NORM); + pointparticles(particleeffectnum("raptor_cannon_impact"), self.origin, w_backoff * 1000, 1); + break; + case DEATH_RAPTOR_BOMB_SPLIT: + float i; + vector ang, vel; + for(i = 1; i < 4; ++i) + { + vel = normalize(w_org - (w_org + normalize(force) * 16)) + randomvec() * 128; + ang = vectoangles(vel); + RaptorCBShellfragToss(w_org, vel, ang + '0 0 1' * (120 * i)); + } + sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM); + pointparticles(particleeffectnum("raptor_bomb_spread"), self.origin, w_backoff * 1000, 1); + break; + case DEATH_RAPTOR_BOMB: + sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM); + pointparticles(particleeffectnum("raptor_bomb_impact"), self.origin, w_backoff * 1000, 1); + break; + case DEATH_RAPTOR_DEATH: + sound(self, CH_SHOTS, "weapons/laserimpact.wav", VOL_BASE, ATTN_MIN); + pointparticles(particleeffectnum("explosion_big"), self.origin, w_backoff * 1000, 1); + break; + } } if(DEATH_ISTURRET(w_deathtype)) - { - string _snd; - traceline(w_org - normalize(force) * 16, w_org + normalize(force) * 16, MOVE_NOMONSTERS, world); - if(trace_plane_normal != '0 0 0') - w_backoff = trace_plane_normal; - else - w_backoff = -1 * normalize(w_org - (w_org + normalize(force) * 16)); - - setorigin(self, w_org + w_backoff * 2); // for sound() calls - - switch(w_deathtype) - { - case DEATH_TURRET_EWHEEL: - sound(self, CH_SHOTS, "weapons/laserimpact.wav", VOL_BASE, ATTN_MIN); - pointparticles(particleeffectnum("laser_impact"), self.origin, w_backoff * 1000, 1); - break; - - case DEATH_TURRET_FLAC: - pointparticles(particleeffectnum("hagar_explode"), w_org, '0 0 0', 1); - _snd = strcat("weapons/hagexp", ftos(1 + rint(random() * 2)), ".waw"); - sound(self, CH_SHOTS, _snd, VOL_BASE, ATTN_NORM); - break; - - case DEATH_TURRET_MLRS: - case DEATH_TURRET_HK: - case DEATH_TURRET_WALKER_ROCKET: - case DEATH_TURRET_HELLION: - sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_MIN); - pointparticles(particleeffectnum("rocket_explode"), self.origin, w_backoff * 1000, 1); - break; - - case DEATH_TURRET_MACHINEGUN: - case DEATH_TURRET_WALKER_GUN: - _snd = strcat("weapons/ric", ftos(1 + rint(random() * 2)), ".waw"); - sound(self, CH_SHOTS, _snd, VOL_BASE, ATTN_NORM); - pointparticles(particleeffectnum("machinegun_impact"), self.origin, w_backoff * 1000, 1); - break; - - case DEATH_TURRET_PLASMA: - sound(self, CH_SHOTS, "weapons/electro_impact.wav", VOL_BASE, ATTN_MIN); - pointparticles(particleeffectnum("electro_impact"), self.origin, w_backoff * 1000, 1); - break; - - case DEATH_TURRET_WALKER_MEELE: - sound(self, CH_SHOTS, "weapons/ric1.wav", VOL_BASE, ATTN_MIN); - pointparticles(particleeffectnum("TE_SPARK"), self.origin, w_backoff * 1000, 1); - break; - - case DEATH_TURRET_PHASER: - break; - - case DEATH_TURRET_TESLA: - te_smallflash(self.origin); - break; - - } + { + string _snd; + traceline(w_org - normalize(force) * 16, w_org + normalize(force) * 16, MOVE_NOMONSTERS, world); + if(trace_plane_normal != '0 0 0') + w_backoff = trace_plane_normal; + else + w_backoff = -1 * normalize(w_org - (w_org + normalize(force) * 16)); + + setorigin(self, w_org + w_backoff * 2); // for sound() calls + + switch(w_deathtype) + { + case DEATH_TURRET_EWHEEL: + sound(self, CH_SHOTS, "weapons/laserimpact.wav", VOL_BASE, ATTN_MIN); + pointparticles(particleeffectnum("laser_impact"), self.origin, w_backoff * 1000, 1); + break; + + case DEATH_TURRET_FLAC: + pointparticles(particleeffectnum("hagar_explode"), w_org, '0 0 0', 1); + _snd = strcat("weapons/hagexp", ftos(1 + rint(random() * 2)), ".waw"); + sound(self, CH_SHOTS, _snd, VOL_BASE, ATTN_NORM); + break; + + case DEATH_TURRET_MLRS: + case DEATH_TURRET_HK: + case DEATH_TURRET_WALKER_ROCKET: + case DEATH_TURRET_HELLION: + sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_MIN); + pointparticles(particleeffectnum("rocket_explode"), self.origin, w_backoff * 1000, 1); + break; + + case DEATH_TURRET_MACHINEGUN: + case DEATH_TURRET_WALKER_GUN: + _snd = strcat("weapons/ric", ftos(1 + rint(random() * 2)), ".waw"); + sound(self, CH_SHOTS, _snd, VOL_BASE, ATTN_NORM); + pointparticles(particleeffectnum("machinegun_impact"), self.origin, w_backoff * 1000, 1); + break; + + case DEATH_TURRET_PLASMA: + sound(self, CH_SHOTS, "weapons/electro_impact.wav", VOL_BASE, ATTN_MIN); + pointparticles(particleeffectnum("electro_impact"), self.origin, w_backoff * 1000, 1); + break; + + case DEATH_TURRET_WALKER_MEELE: + sound(self, CH_SHOTS, "weapons/ric1.wav", VOL_BASE, ATTN_MIN); + pointparticles(particleeffectnum("TE_SPARK"), self.origin, w_backoff * 1000, 1); + break; + + case DEATH_TURRET_PHASER: + break; + + case DEATH_TURRET_TESLA: + te_smallflash(self.origin); + break; + + } } // TODO spawn particle effects and sounds based on w_deathtype diff --git a/qcsrc/client/damage.qh b/qcsrc/client/damage.qh new file mode 100644 index 000000000..23982f132 --- /dev/null +++ b/qcsrc/client/damage.qh @@ -0,0 +1 @@ +.float total_damages; // number of effects which currently are attached to a player \ No newline at end of file diff --git a/qcsrc/client/gibs.qc b/qcsrc/client/gibs.qc index 6f6316bec..22825bc4f 100644 --- a/qcsrc/client/gibs.qc +++ b/qcsrc/client/gibs.qc @@ -115,6 +115,7 @@ void TossGib (string mdlname, vector safeorg, vector org, vector vconst, vector // TODO remove some gibs according to cl_nogibs gib = RubbleNew("gib"); + gib.classname = "gib"; gib.move_movetype = MOVETYPE_BOUNCE; gib.gravity = 1; gib.solid = SOLID_CORPSE; diff --git a/qcsrc/client/progs.src b/qcsrc/client/progs.src index a33570a2f..972efb6a0 100644 --- a/qcsrc/client/progs.src +++ b/qcsrc/client/progs.src @@ -27,6 +27,8 @@ command/cl_cmd.qh autocvars.qh +damage.qh + ../csqcmodellib/interpolate.qh teamradar.qh hud.qh diff --git a/qcsrc/common/util.qc b/qcsrc/common/util.qc index 09a58c099..1930d7c6f 100644 --- a/qcsrc/common/util.qc +++ b/qcsrc/common/util.qc @@ -2213,6 +2213,22 @@ float ReadApproxPastTime() } #endif +#ifndef MENUQC +.float skeleton_bones_index; +void Skeleton_SetBones(entity e) +{ + // set skeleton_bones to the total number of bones on the model + if(e.skeleton_bones_index == e.modelindex) + return; // same model, nothing to update + + float skelindex; + skelindex = skel_create(e.modelindex); + e.skeleton_bones = skel_get_numbones(skelindex); + skel_delete(skelindex); + e.skeleton_bones_index = e.modelindex; +} +#endif + string to_execute_next_frame; void execute_next_frame() { diff --git a/qcsrc/common/util.qh b/qcsrc/common/util.qh index 485e190b9..5685f4db2 100644 --- a/qcsrc/common/util.qh +++ b/qcsrc/common/util.qh @@ -291,6 +291,12 @@ float InterpretBoolean(string input); // generic shutdown handler void Shutdown(); +#ifndef MENUQC +.float skeleton_bones; +void Skeleton_SetBones(entity e); +// loops through the tags of model v using counter tagnum +#define FOR_EACH_TAG(v) float tagnum; Skeleton_SetBones(v); for(tagnum = 0; tagnum < v.skeleton_bones; tagnum++, gettaginfo(v, tagnum)) +#endif #ifdef SVQC void WriteApproxPastTime(float dst, float t); #endif diff --git a/qcsrc/dpdefs/csprogsdefs.qc b/qcsrc/dpdefs/csprogsdefs.qc index 623fb01c7..5fd52179c 100644 --- a/qcsrc/dpdefs/csprogsdefs.qc +++ b/qcsrc/dpdefs/csprogsdefs.qc @@ -1410,3 +1410,10 @@ float trace_networkentity; const float RF_FULLBRIGHT = 256; const float RF_NOSHADOW = 512; float RF_DYNAMICMODELLIGHT = 8192; + +float gettaginfo_parent; +string gettaginfo_name; +vector gettaginfo_offset; +vector gettaginfo_forward; +vector gettaginfo_right; +vector gettaginfo_up; diff --git a/qcsrc/menu/xonotic/dialog_settings_effects.c b/qcsrc/menu/xonotic/dialog_settings_effects.c index 385252bcb..4e5a9088c 100644 --- a/qcsrc/menu/xonotic/dialog_settings_effects.c +++ b/qcsrc/menu/xonotic/dialog_settings_effects.c @@ -111,11 +111,17 @@ void XonoticEffectsSettingsTab_fill(entity me) me.TR(me); me.TR(me); me.TD(me, 1, 1.1, e = makeXonoticTextLabel(0, _("Particle quality:"))); - me.TD(me, 1, 1.9, e = makeXonoticSlider(0.2, 1.0, 0.1, "cl_particles_quality")); + me.TD(me, 1, 2, e = makeXonoticSlider(0.2, 1.0, 0.1, "cl_particles_quality")); me.TR(me); me.TD(me, 1, 1.1, e = makeXonoticTextLabel(0, _("Particle distance:"))); - me.TD(me, 1, 1.9, e = makeXonoticSlider(500, 2000, 100, "r_drawparticles_drawdistance")); + me.TD(me, 1, 2, e = makeXonoticSlider(500, 2000, 100, "r_drawparticles_drawdistance")); me.TR(me); + me.TD(me, 1, 1.1, e = makeXonoticTextLabel(0, _("Damage effects:"))); + me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_damageeffect")); + e.addValue(e, _("Disabled"), "0"); + e.addValue(e, _("Skeletal"), "1"); + e.addValue(e, _("All"), "2"); + e.configureXonoticTextSliderValues(e); me.TR(me); me.TD(me, 1, 1.5, e = makeXonoticCheckBox(0, "cl_decals", _("Decals"))); me.TD(me, 1, 1.5, e = makeXonoticCheckBox(0, "cl_decals_models", _("Decals on models"))); diff --git a/qcsrc/server/cl_player.qc b/qcsrc/server/cl_player.qc index 15173b9ad..49b52555f 100644 --- a/qcsrc/server/cl_player.qc +++ b/qcsrc/server/cl_player.qc @@ -198,6 +198,8 @@ void CopyBody(float keepvelocity) Drag_MoveDrag(oldself, self); + self.owner = oldself; + if(self.colormap <= maxclients && self.colormap > 0) self.colormap = 1024 + oldself.clientcolors; @@ -421,6 +423,7 @@ void PlayerCorpseDamage (entity inflictor, entity attacker, float damage, float Violence_GibSplash(self, 1, 1, attacker); self.alpha = -1; self.solid = SOLID_NOT; // restore later + self.takedamage = DAMAGE_NO; // restore later } } diff --git a/qcsrc/server/g_damage.qc b/qcsrc/server/g_damage.qc index bd4426c3a..bdaeef0a5 100644 --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@ -14,10 +14,11 @@ float Damage_DamageInfo_SendEntity(entity to, float sf) WriteByte(MSG_ENTITY, bound(0, self.dmg_radius, 255)); WriteByte(MSG_ENTITY, bound(1, self.dmg_edge, 255)); WriteShort(MSG_ENTITY, self.oldorigin_x); + WriteByte(MSG_ENTITY, self.species); return TRUE; } -void Damage_DamageInfo(vector org, float coredamage, float edgedamage, float rad, vector force, float deathtype, entity dmgowner) +void Damage_DamageInfo(vector org, float coredamage, float edgedamage, float rad, vector force, float deathtype, float bloodtype, entity dmgowner) { // TODO maybe call this from non-edgedamage too? // TODO maybe make the client do the particle effects for the weapons and the impact sounds using this info? @@ -35,8 +36,8 @@ void Damage_DamageInfo(vector org, float coredamage, float edgedamage, float rad e.dmg_radius = rad; e.dmg_force = vlen(force); e.velocity = force; - e.oldorigin_x = compressShortVector(e.velocity); + e.species = bloodtype; Net_LinkEntity(e, FALSE, 0.2, Damage_DamageInfo_SendEntity); } @@ -996,9 +997,9 @@ float RadiusDamage (entity inflictor, entity attacker, float coredamage, float e else force = normalize(force); if(forceintensity >= 0) - Damage_DamageInfo(blastorigin, coredamage, edgedamage, rad, forceintensity * force, deathtype, attacker); + Damage_DamageInfo(blastorigin, coredamage, edgedamage, rad, forceintensity * force, deathtype, 0, attacker); else - Damage_DamageInfo(blastorigin, coredamage, edgedamage, -rad, (-forceintensity) * force, deathtype, attacker); + Damage_DamageInfo(blastorigin, coredamage, edgedamage, -rad, (-forceintensity) * force, deathtype, 0, attacker); } stat_damagedone = 0; diff --git a/qcsrc/server/g_violence.qc b/qcsrc/server/g_violence.qc index f5def6a7d..cae5e3520 100644 --- a/qcsrc/server/g_violence.qc +++ b/qcsrc/server/g_violence.qc @@ -25,6 +25,14 @@ void Violence_GibSplash_At(vector org, vector dir, float type, float amount, ent if(!sound_allowed(MSG_BROADCAST, gibowner) || !sound_allowed(MSG_BROADCAST, attacker)) e.state |= 0x40; // "silence" bit e.state |= 8 * self.species; // gib type, ranges from 0 to 15 + + // if this is a copied dead body, send the num of its player instead + // TODO: remove this field, read from model txt files + if(self.classname == "body") + e.team = num_for_edict(self.owner); + else + e.team = num_for_edict(self); + setorigin(e, org); e.velocity = dir; diff --git a/qcsrc/server/mutators/sandbox.qc b/qcsrc/server/mutators/sandbox.qc index 66377d1d8..e7f51aa88 100644 --- a/qcsrc/server/mutators/sandbox.qc +++ b/qcsrc/server/mutators/sandbox.qc @@ -744,7 +744,7 @@ MUTATOR_HOOKFUNCTION(sandbox_PlayerCommand) print_to(self, strcat("^2SANDBOX - INFO: ^7Object is owned by \"^7", e.netname, "^7\", created \"^3", e.message, "^7\", last edited \"^3", e.message2, "^7\"")); return TRUE; case "mesh": - for(i = 1; gettaginfo(e, i); i++) + FOR_EACH_TAG(e) s = strcat(s, "^7\"^5", gettaginfo_name, "^7\", "); print_to(self, strcat("^2SANDBOX - INFO: ^7Object mesh is \"^3", e.model, "^7\" at animation frame ^3", ftos(e.frame), " ^7containing the following tags: ", s)); return TRUE; diff --git a/qcsrc/server/vehicles/raptor.qc b/qcsrc/server/vehicles/raptor.qc index 497385925..ab0d38815 100644 --- a/qcsrc/server/vehicles/raptor.qc +++ b/qcsrc/server/vehicles/raptor.qc @@ -111,7 +111,7 @@ void raptor_bomb_burst() entity bomblet; float i; - Damage_DamageInfo(self.origin, 0, 0, 0, '0 0 0', DEATH_RAPTOR_BOMB_SPLIT, self); + Damage_DamageInfo(self.origin, 0, 0, 0, '0 0 0', DEATH_RAPTOR_BOMB_SPLIT, 0, self); for(i = 0; i < autocvar_g_vehicle_raptor_bomblets; ++i) { diff --git a/qcsrc/server/w_common.qc b/qcsrc/server/w_common.qc index a05c17bd4..fab3b41b2 100644 --- a/qcsrc/server/w_common.qc +++ b/qcsrc/server/w_common.qc @@ -66,6 +66,9 @@ void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, f continue; } + if(trace_ent.solid == SOLID_BSP || trace_ent.solid == SOLID_SLIDEBOX) + Damage_DamageInfo(trace_endpos, bdamage, 0, 0, force, deathtype, trace_ent.species, self); + // if it is world we can't hurt it so stop now if (trace_ent == world || trace_fraction == 1) break; @@ -173,8 +176,8 @@ void W_BallisticBullet_Hit (void) f = pow(bound(0, vlen(self.velocity) / vlen(self.oldvelocity), 1), 2); // energy multiplier q = 1 + self.dmg_edge / self.dmg; - if(other.solid == SOLID_BSP) - Damage_DamageInfo(self.origin, self.dmg * f, 0, 0, max(1, self.dmg_force) * normalize(self.velocity) * f, self.projectiledeathtype, self); + if(other.solid == SOLID_BSP || other.solid == SOLID_SLIDEBOX) + Damage_DamageInfo(self.origin, self.dmg * f, 0, 0, max(1, self.dmg_force) * normalize(self.velocity) * f, self.projectiledeathtype, other.species, self); if(other && other != self.enemy) { @@ -232,7 +235,7 @@ void W_BallisticBullet_LeaveSolid_think() { float f; f = pow(bound(0, vlen(self.velocity) / vlen(self.oldvelocity), 1), 2); // energy multiplier - Damage_DamageInfo(self.origin, 0, 0, 0, max(1, self.dmg_force) * normalize(self.velocity) * -f, self.projectiledeathtype, self); + Damage_DamageInfo(self.origin, 0, 0, 0, max(1, self.dmg_force) * normalize(self.velocity) * -f, self.projectiledeathtype, 0, self); } UpdateCSQCProjectile(self); @@ -526,10 +529,10 @@ void fireBullet (vector start, vector dir, float spread, float damage, float for end = trace_endpos; - if ((trace_fraction != 1.0) && (pointcontents (trace_endpos) != CONTENT_SKY)) + if (pointcontents (trace_endpos) != CONTENT_SKY) { if not (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT) - Damage_DamageInfo(trace_endpos, damage, 0, 0, dir * max(1, force), dtype, self); + Damage_DamageInfo(trace_endpos, damage, 0, 0, dir * max(1, force), dtype, trace_ent.species, self); Damage (trace_ent, self, self, damage, dtype, trace_endpos, dir * force); } diff --git a/qcsrc/server/w_minstanex.qc b/qcsrc/server/w_minstanex.qc index f688219bd..b66386d50 100644 --- a/qcsrc/server/w_minstanex.qc +++ b/qcsrc/server/w_minstanex.qc @@ -77,10 +77,6 @@ void W_MinstaNex_Attack (void) else WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3"), w_shotorg, v); - // flash and burn the wall - if (trace_ent.solid == SOLID_BSP && !(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)) - Damage_DamageInfo(trace_endpos, 10000, 0, 0, 800 * w_shotdir, WEP_MINSTANEX, self); - if (g_minstagib) W_DecreaseAmmo(ammo_cells, 1, autocvar_g_balance_minstanex_reload_ammo); else diff --git a/qcsrc/server/w_nex.qc b/qcsrc/server/w_nex.qc index cdcabc866..51afdd00f 100644 --- a/qcsrc/server/w_nex.qc +++ b/qcsrc/server/w_nex.qc @@ -71,10 +71,6 @@ void W_Nex_Attack (float issecondary) //beam and muzzle flash done on client SendCSQCNexBeamParticle(charge); - // flash and burn the wall - if (trace_ent.solid == SOLID_BSP && !(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)) - Damage_DamageInfo(trace_endpos, mydmg, 0, 0, myforce * w_shotdir, WEP_NEX, self); - W_DecreaseAmmo(ammo_cells, myammo, autocvar_g_balance_nex_reload_ammo); } diff --git a/qcsrc/server/w_seeker.qc b/qcsrc/server/w_seeker.qc index c4c08bb51..7cf9f58d8 100644 --- a/qcsrc/server/w_seeker.qc +++ b/qcsrc/server/w_seeker.qc @@ -393,7 +393,7 @@ void Seeker_Tag_Explode () { //if(other==self.realowner) // return; - Damage_DamageInfo(self.origin, 0, 0, 0, self.velocity, WEP_SEEKER | HITTYPE_BOUNCE, self); + Damage_DamageInfo(self.origin, 0, 0, 0, self.velocity, WEP_SEEKER | HITTYPE_BOUNCE, other.species, self); remove (self); } @@ -421,7 +421,7 @@ void Seeker_Tag_Touch() te_knightspike(org2); self.event_damage = SUB_Null; - Damage_DamageInfo(self.origin, 0, 0, 0, self.velocity, WEP_SEEKER | HITTYPE_HEADSHOT, self); + Damage_DamageInfo(self.origin, 0, 0, 0, self.velocity, WEP_SEEKER | HITTYPE_HEADSHOT, other.species, self); if (other.takedamage == DAMAGE_AIM && other.deadflag == DEAD_NO) {