From a12a5eaa4a707cd230236fdb0a890e33deb89ac1 Mon Sep 17 00:00:00 2001 From: div0 Date: Sat, 10 Jan 2009 15:05:47 +0000 Subject: [PATCH] svc_stopsound; make sure exploding projectiles ALWAYS get their sound removed even if there is packet loss git-svn-id: svn://svn.icculus.org/nexuiz/trunk@5481 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- .../qcsrc/menu/nexuiz/dialog_settings_audio.c | 2 +- data/qcsrc/server/arena.qc | 2 +- data/qcsrc/server/constants.qh | 12 +-- data/qcsrc/server/miscfunctions.qc | 89 +++++++++++++++++-- data/qcsrc/server/t_plats.qc | 2 +- data/qcsrc/server/w_electro.qc | 7 +- data/qcsrc/server/w_rocketlauncher.qc | 3 +- data/qcsrc/server/w_seeker.qc | 3 +- 8 files changed, 95 insertions(+), 25 deletions(-) diff --git a/data/qcsrc/menu/nexuiz/dialog_settings_audio.c b/data/qcsrc/menu/nexuiz/dialog_settings_audio.c index 27bb60016..cbf7e0c47 100644 --- a/data/qcsrc/menu/nexuiz/dialog_settings_audio.c +++ b/data/qcsrc/menu/nexuiz/dialog_settings_audio.c @@ -72,7 +72,7 @@ void fillNexuizAudioSettingsTab(entity me) me.TR(me); me.TDempty(me, 0.2); s = makeNexuizDecibelsSlider(-20, 0, 0.5, "snd_entchannel4volume"); - makeMulti(s, "snd_playerchannel4volume"); + makeMulti(s, "snd_playerchannel4volume snd_entchannel6volume"); me.TD(me, 1, 0.8, e = makeNexuizSliderCheckBox(-1000000, 1, s, "Shots:")); me.TD(me, 1, 2, s); setDependentStringNotEqual(e, "volume", "0"); diff --git a/data/qcsrc/server/arena.qc b/data/qcsrc/server/arena.qc index e19a6d81b..bac809e3f 100644 --- a/data/qcsrc/server/arena.qc +++ b/data/qcsrc/server/arena.qc @@ -89,7 +89,7 @@ void reset_map() } else if(self.flags & FL_PROJECTILE) // remove any projectiles left { - sound(self, CHAN_PROJECTILE, "misc/null.wav", VOL_BASE, ATTN_NORM); + stopsound(self, CHAN_PROJECTILE); remove(self); } else if(self.isdecor) diff --git a/data/qcsrc/server/constants.qh b/data/qcsrc/server/constants.qh index 4c8669091..3192cd5e6 100644 --- a/data/qcsrc/server/constants.qh +++ b/data/qcsrc/server/constants.qh @@ -135,7 +135,7 @@ float CHAN_WEAPON2 = 5; // Nex fire (separated as it is a very long sound) float CHAN_PAIN = 6; // Pain // on world: UNUSED // on players: pain PAIN - // on entities: UNUSED + // on entities: projectiles flying SHOTS float CHAN_PLAYER = 7; // Player body // on world: UNUSED // on players: player sounds PLAYER @@ -159,11 +159,11 @@ float EF_DIMLIGHT = 8; #define EFMASK_CHEAP (EF_ADDITIVE | EF_DOUBLESIDED | EF_FULLBRIGHT | EF_NODEPTHTEST | EF_NODRAW | EF_NOGUNBOB | EF_NOSHADOW | EF_LOWPRECISION | EF_SELECTABLE) -float MSG_BROADCAST = 0; -float MSG_ONE = 1; -float MSG_ALL = 2; -float MSG_INIT = 3; -float MSG_ENTITY = 5; +float MSG_BROADCAST = 0; // unreliable +float MSG_ONE = 1; // reliable +float MSG_ALL = 2; // reliable +float MSG_INIT = 3; // initialization +float MSG_ENTITY = 5; // csqc // Deathtypes (weapon deathtypes are the IT_* constants below) // NOTE: when adding death types, please add an explanation to Docs/spamlog.txt too. diff --git a/data/qcsrc/server/miscfunctions.qc b/data/qcsrc/server/miscfunctions.qc index b670757a0..4c3f2e575 100644 --- a/data/qcsrc/server/miscfunctions.qc +++ b/data/qcsrc/server/miscfunctions.qc @@ -1068,15 +1068,52 @@ string precache_sound (string s) = #19; void(entity e, float chan, string samp, float vol, float atten) sound = #8; float precache_sound_index (string s) = #19; +#define SND_VOLUME 1 +#define SND_ATTENUATION 2 +#define SND_LARGEENTITY 8 +#define SND_LARGESOUND 16 + void soundtoat(float dest, entity e, vector o, float chan, string samp, float vol, float atten) { - WriteByte(dest, 6); - WriteByte(dest, 27); // all bits except SND_LOOPING - WriteByte(dest, vol * 255); - WriteByte(dest, atten * 64); - WriteEntity(dest, e); - WriteByte(dest, chan); - WriteShort(dest, precache_sound_index(samp)); + float entno, idx; + entno = num_for_edict(e); + idx = precache_sound_index(samp); + + float sflags; + sflags = 0; + + atten = floor(atten * 64); + vol = floor(vol * 255); + + if(vol != 255) + sflags |= SND_VOLUME; + if(atten != 64) + sflags |= SND_ATTENUATION; + if(entno >= 8192) + sflags |= SND_LARGEENTITY; + if(idx >= 256) + sflags |= SND_LARGESOUND; + + WriteByte(dest, SVC_SOUND); + WriteByte(dest, sflags); + if(sflags & SND_VOLUME) + WriteByte(dest, vol * 255); + if(sflags & SND_ATTENUATION) + WriteByte(dest, atten); + if(sflags & SND_LARGEENTITY) + { + WriteShort(dest, entno); + WriteByte(dest, chan); + } + else + { + WriteShort(dest, entno * 8 + chan); + } + if(sflags & SND_LARGESOUND) + WriteShort(dest, idx); + else + WriteByte(dest, idx); + WriteCoord(dest, o_x); WriteCoord(dest, o_y); WriteCoord(dest, o_z); @@ -1091,6 +1128,41 @@ void soundat(entity e, vector o, float chan, string samp, float vol, float atten { soundtoat(MSG_BROADCAST, e, o, chan, samp, vol, atten); } +void stopsoundto(float dest, entity e, float chan) +{ + float entno; + entno = num_for_edict(e); + + if(entno >= 8192) + { + float idx, sflags; + idx = precache_sound_index("misc/null.wav"); + sflags = SND_LARGEENTITY; + if(idx >= 256) + sflags |= SND_LARGESOUND; + WriteByte(dest, SVC_SOUND); + WriteByte(dest, sflags); + WriteShort(dest, entno); + WriteByte(dest, chan); + if(sflags & SND_LARGESOUND) + WriteShort(dest, idx); + else + WriteByte(dest, idx); + WriteCoord(dest, e.origin_x); + WriteCoord(dest, e.origin_y); + WriteCoord(dest, e.origin_z); + } + else + { + WriteByte(dest, SVC_STOPSOUND); + WriteShort(dest, entno * 8 + chan); + } +} +void stopsound(entity e, float chan) +{ + stopsoundto(MSG_BROADCAST, e, chan); // unreliable, gets there fast + stopsoundto(MSG_ALL, e, chan); // in case of packet loss +} void play2(entity e, string filename) { @@ -1662,8 +1734,7 @@ float SUB_NoImpactCheck() #define SUB_OwnerCheck() (other && (other == self.owner)) #define PROJECTILE_TOUCH do { if(SUB_OwnerCheck()) return; if(SUB_NoImpactCheck()) { remove(self); return; } } while(0) -const string STR_MISC_NULL_WAV = "misc/null.wav"; -#define PROJECTILE_TOUCH_NOSOUND do { if(SUB_OwnerCheck()) return; if(SUB_NoImpactCheck()) { sound (self, CHAN_PROJECTILE, STR_MISC_NULL_WAV, VOL_BASE, ATTN_NORM); remove(self); return; } } while(0) +#define PROJECTILE_TOUCH_NOSOUND do { if(SUB_OwnerCheck()) return; if(SUB_NoImpactCheck()) { stopsound(self, CHAN_PAIN); remove(self); return; } } while(0) float MAX_IPBAN_URIS = 16; diff --git a/data/qcsrc/server/t_plats.qc b/data/qcsrc/server/t_plats.qc index 0f39579ba..1d94c99fe 100644 --- a/data/qcsrc/server/t_plats.qc +++ b/data/qcsrc/server/t_plats.qc @@ -246,7 +246,7 @@ void train_wait() self.nextthink = self.ltime + self.wait; if(self.noise != "") - sound(self, CHAN_TRIGGER, STR_MISC_NULL_WAV, VOL_BASE, ATTN_IDLE); + stopsoundto(MSG_BROADCAST, self, CHAN_TRIGGER); // send this as unreliable only, as the train will resume operation shortly anyway }; void train_next() diff --git a/data/qcsrc/server/w_electro.qc b/data/qcsrc/server/w_electro.qc index 6278ff39c..cd68b8e60 100644 --- a/data/qcsrc/server/w_electro.qc +++ b/data/qcsrc/server/w_electro.qc @@ -22,6 +22,7 @@ void W_Plasma_Explode (void) RadiusDamage (self, self.owner, cvar("g_balance_electro_primary_damage"), cvar("g_balance_electro_primary_edgedamage"), cvar("g_balance_electro_primary_radius"), world, cvar("g_balance_electro_primary_force"), self.projectiledeathtype, other); } + stopsound (self, CHAN_PAIN); sound (self, CHAN_PROJECTILE, "weapons/electro_impact.wav", VOL_BASE, ATTN_NORM); remove (self); @@ -111,8 +112,7 @@ void W_Electro_Attack() setmodel(proj, "models/elaser.mdl"); // precision set above setsize(proj, '0 0 0', '0 0 0'); - // LordHavoc: disabled because no one likes this sound and it sometimes never stops due to packet loss - //sound (proj, CHAN_PROJECTILE, "weapons/electro_fly.wav", VOL_BASE, ATTN_NORM); + sound (proj, CHAN_PAIN, "weapons/electro_fly.wav", VOL_BASE, ATTN_NORM); } void W_Electro_Attack2() @@ -151,9 +151,6 @@ void W_Electro_Attack2() proj.health = cvar("g_balance_electro_secondary_health"); proj.event_damage = W_Plasma_Damage; proj.flags = FL_PROJECTILE; - - // LordHavoc: disabled because no one likes this sound and it sometimes never stops due to packet loss - //sound (proj, CHAN_PROJECTILE, "weapons/electro_fly.wav", VOL_BASE, ATTN_NORM); } void spawnfunc_weapon_electro (void) diff --git a/data/qcsrc/server/w_rocketlauncher.qc b/data/qcsrc/server/w_rocketlauncher.qc index a5dc455a1..0f8aa1798 100644 --- a/data/qcsrc/server/w_rocketlauncher.qc +++ b/data/qcsrc/server/w_rocketlauncher.qc @@ -4,6 +4,7 @@ void W_Rocket_Explode (void) { vector org2; + stopsound(self, CHAN_PAIN); sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM); org2 = findbetterlocation (self.origin, 16); @@ -241,7 +242,7 @@ void W_Rocket_Attack (void) missile.nextthink = time; missile.cnt = time + cvar("g_balance_rocketlauncher_lifetime"); missile.effects = EF_LOWPRECISION; - sound (missile, CHAN_PROJECTILE, "weapons/rocket_fly.wav", VOL_BASE, ATTN_NORM); + sound (missile, CHAN_PAIN, "weapons/rocket_fly.wav", VOL_BASE, ATTN_NORM); missile.flags = FL_PROJECTILE; // muzzle flash for 1st person view diff --git a/data/qcsrc/server/w_seeker.qc b/data/qcsrc/server/w_seeker.qc index ff0997d29..3e6e0ee03 100644 --- a/data/qcsrc/server/w_seeker.qc +++ b/data/qcsrc/server/w_seeker.qc @@ -308,6 +308,7 @@ void Seeker_Tag_Touch() te_knightspike(org2); self.event_damage = SUB_Null; + stopsound (self, CHAN_PAIN); sound (self, CHAN_PROJECTILE, "weapons/tag_impact.wav", 1, ATTN_NORM); if (other.takedamage == DAMAGE_AIM && other.deadflag == DEAD_NO) @@ -363,7 +364,7 @@ void Seeker_Fire_Tag() missile.effects = EF_FULLBRIGHT | EF_NOSHADOW | EF_LOWPRECISION; missile.modelflags = MF_TRACER3; - sound (missile, CHAN_PROJECTILE, "weapons/tag_rocket_fly.wav", VOL_BASE, ATTN_NORM); + sound (missile, CHAN_PAIN, "weapons/tag_rocket_fly.wav", VOL_BASE, ATTN_NORM); missile.flags = FL_PROJECTILE; missile.velocity = w_shotdir * cvar("g_balance_seeker_tag_speed"); -- 2.39.2