]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' of git://de.git.xonotic.org/xonotic/xonotic-data.pk3dir
authorRudolf Polzer <divverent@alientrap.org>
Fri, 20 Jan 2012 16:17:25 +0000 (17:17 +0100)
committerRudolf Polzer <divverent@alientrap.org>
Fri, 20 Jan 2012 16:17:25 +0000 (17:17 +0100)
28 files changed:
defaultXonotic.cfg
effectinfo.txt
effects-high.cfg
effects-low.cfg
effects-med.cfg
effects-normal.cfg
effects-omg.cfg
effects-ultimate.cfg
effects-ultra.cfg
models/null.md3 [deleted file]
qcsrc/client/autocvars.qh
qcsrc/client/damage.qc
qcsrc/client/damage.qh [new file with mode: 0644]
qcsrc/client/gibs.qc
qcsrc/client/progs.src
qcsrc/common/util.qc
qcsrc/common/util.qh
qcsrc/dpdefs/csprogsdefs.qc
qcsrc/menu/xonotic/dialog_settings_effects.c
qcsrc/server/cl_player.qc
qcsrc/server/g_damage.qc
qcsrc/server/g_violence.qc
qcsrc/server/mutators/sandbox.qc
qcsrc/server/vehicles/raptor.qc
qcsrc/server/w_common.qc
qcsrc/server/w_minstanex.qc
qcsrc/server/w_nex.qc
qcsrc/server/w_seeker.qc

index 5c142926a2ba0263c507f5800ecb3df952476d8e..b3092fa097ee6c3126a39e6596969545093a3bc8 100644 (file)
@@ -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"
index 0d464f5f7740d4dc7e9d26e4242fb4b7cd974182..8b555fa8981d60492509837fcaa7810ef6ef7933 100644 (file)
@@ -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*/
index 0e011fe56be28f6516e54bd5cf76fab65031acac..95fd0f8bd1ae39c8d66e3558e8704f1d47f391eb 100644 (file)
@@ -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
index a9cff5abe5e85b3f5bd38c64bd5a5293cda43e89..e4391c703d4ed00be4f1191c4abf6c9888c9eb38 100644 (file)
@@ -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
index 5be8356e2e11c52fca16d0f258372bb05eaddd9f..de41d388cc89e460636d6f301038b36528f49162 100644 (file)
@@ -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
index 0aebfb79dfd709737399f73b5e83721720415bda..490087efdf070f9218fb702d92384b1d57934a1a 100644 (file)
@@ -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
index 350e9b8497afd77ae4b187b01d1e1e7b9fa4ed55..55a91e45092ac3058d46bdcf215e7947cae69371 100644 (file)
@@ -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
index 7e4125bf45bf224371e234cf601e70c2e46ff1df..8c859f08d971a3a1ba5b432ded2d2fd62383f4f4 100644 (file)
@@ -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
index 1c9b9db3012a4f9d05d76aacac7180feea54880e..9dda230cad36e1773a39083b3cc46b33d67d2fd4 100644 (file)
@@ -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 (file)
index 288e88f..0000000
Binary files a/models/null.md3 and /dev/null differ
index 5c05e2feec513b1438ac12a7d9f53ae30c1eee70..eb7c6d2fb43953d35a2dfce459a3441b6b86825c 100644 (file)
@@ -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;
index 5910dba3e41d13f4cf4636e34cf1983de9b9f5ef..34c15837acc26fe3e9cade3ce1430bd218b9da87 100644 (file)
@@ -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 (file)
index 0000000..23982f1
--- /dev/null
@@ -0,0 +1 @@
+.float total_damages; // number of effects which currently are attached to a player
\ No newline at end of file
index 6f6316bec1d4c46e2fd474e874316b8563f0af29..22825bc4f38d4912b70c51922098c20213308581 100644 (file)
@@ -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;
index a33570a2f9c3291b7402ea61a7d9eb6a39914e9a..972efb6a0ae5df9cbf5d777507a3bd6af53a980e 100644 (file)
@@ -27,6 +27,8 @@ command/cl_cmd.qh
 
 autocvars.qh
 
+damage.qh
+
 ../csqcmodellib/interpolate.qh
 teamradar.qh
 hud.qh
index 09a58c0997bc9a312b3cdd12307e814200562453..1930d7c6fc4a04f2c7d33d029631f79bae308c29 100644 (file)
@@ -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()
 {
index 485e190b9e47b0550a4e5cbaf3e809357f7548b8..5685f4db27d42ec177e03e666a6939c2eb8f8489 100644 (file)
@@ -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
index 623fb01c781a6db13f031fb69c6a16dcb3c307e4..5fd52179c6f8221f16d06fff39d77f002fde8db6 100644 (file)
@@ -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;
index 385252bcb106f9d1c432212b8042a8792ccfa8c6..4e5a9088cbdbeeef67b27407dd343a97ccbc3846 100644 (file)
@@ -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")));
index 15173b9ad4bfccb434c1d52980ccee57e3e21d76..49b52555f6ebb0734b8ee371a3b33f08b5cf8466 100644 (file)
@@ -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
        }
 }
 
index bd4426c3aaa68e30ad4705208bf04fbcb2d81b42..bdaeef0a53d19d3ed48ae81cf3468b560350ffb4 100644 (file)
@@ -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;
index f5def6a7dd68e4dd9660d62f4a1d7811372509bc..cae5e3520bc5043939e32f5abeb20952b0eb40b4 100644 (file)
@@ -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;
 
index 66377d1d84aade6398814d045f04926cefdc7d17..e7f51aa887f7931445f0006452db6110a7e8928f 100644 (file)
@@ -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;
index 4973859259be48a3619eabdba70de148b87b8366..ab0d388155bf7ca8d17c674d31507770656533e4 100644 (file)
@@ -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)
     {
index a05c17bd4b40f7dbd392f0a8b45970824d4bb6e8..fab3b41b22808002cca28a5316f0664d65346d21 100644 (file)
@@ -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);
        }
index f688219bd32b0a350a3a052faf58b7f9d68d5b09..b66386d50a59229309d6f1409648b895b3e93e68 100644 (file)
@@ -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
index cdcabc86688996cde0ce04f43dd94816ab9eb88e..51afdd00f100bcb7a3847960c43ec561619c08dd 100644 (file)
@@ -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);
 }
 
index c4c08bb51230983d2b80abe456a567eff56f53c0..7cf9f58d8ce8026a94aa1748754122add077aa86 100644 (file)
@@ -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)
        {