]> git.xonotic.org Git - voretournament/voretournament.git/blobdiff - data/qcsrc/server/cl_player.qc
Use Erebus animations for the nex fox models, which are a lot prettier. Also fix...
[voretournament/voretournament.git] / data / qcsrc / server / cl_player.qc
index bef0ec68355d2b26fd0af6c57ac306384673c69a..c0887e40ab197aa7869cb645a8433ddb21273f8f 100644 (file)
@@ -104,8 +104,6 @@ void WeaponStats_LogKill(float awep, float vwep)
 void CopyBody(float keepvelocity)\r
 {\r
        local entity oldself;\r
-       if (self.fakeprey)\r
-               return;\r
        if (self.effects & EF_NODRAW || self.alpha < 0)\r
                return;\r
        oldself = self;\r
@@ -114,6 +112,7 @@ void CopyBody(float keepvelocity)
        self.lip = oldself.lip;\r
        self.colormap = oldself.colormap;\r
        self.colormod = oldself.colormod;\r
+       self.glowmod = oldself.glowmod;\r
        self.iscreature = oldself.iscreature;\r
        self.angles = oldself.angles;\r
        self.avelocity = oldself.avelocity;\r
@@ -143,6 +142,7 @@ void CopyBody(float keepvelocity)
        self.solid = oldself.solid;\r
        self.takedamage = oldself.takedamage;\r
        self.think = oldself.think;\r
+       self.scale = oldself.scale;\r
        self.customizeentityforclient = oldself.customizeentityforclient;\r
        self.uncustomizeentityforclient = oldself.uncustomizeentityforclient;\r
        self.uncustomizeentityforclient_set = oldself.uncustomizeentityforclient_set;\r
@@ -218,76 +218,41 @@ float player_getspecies()
 \r
 void player_setupanimsformodel()\r
 {\r
-       local string animfilename;\r
-       local float animfile;\r
        // defaults for legacy .zym models without animinfo files\r
-       self.anim_die1 = '0 1 0.5'; // 2 seconds\r
-       self.anim_die2 = '1 1 0.5'; // 2 seconds\r
-       self.anim_draw = '2 1 3'; // TODO: analyze models and set framerate\r
-       self.anim_duck = '3 1 100'; // this anim seems bogus in most models, so make it play VERY briefly!\r
-       self.anim_duckwalk = '4 1 1';\r
-       self.anim_duckjump = '5 1 100'; // zym anims keep playing until changed, so this only has to start the anim, landing will end it\r
-       self.anim_duckidle = '6 1 1';\r
-       self.anim_idle = '7 1 1';\r
-       self.anim_jump = '8 1 100'; // zym anims keep playing until changed, so this only has to start the anim, landing will end it\r
-       self.anim_pain1 = '9 1 2'; // 0.5 seconds\r
-       self.anim_pain2 = '10 1 2'; // 0.5 seconds\r
-       self.anim_shoot = '11 1 5'; // TODO: analyze models and set framerate\r
-       self.anim_taunt = '12 1 0.33'; // FIXME?  there is no code using this anim\r
-       self.anim_run = '13 1 1';\r
-       self.anim_runbackwards = '14 1 1';\r
-       self.anim_strafeleft = '15 1 1';\r
-       self.anim_straferight = '16 1 1';\r
-       self.anim_dead1 = '17 1 1';\r
-       self.anim_dead2 = '18 1 1';\r
-       self.anim_forwardright = '19 1 1';\r
-       self.anim_forwardleft = '20 1 1';\r
-       self.anim_backright = '21 1 1';\r
-       self.anim_backleft  = '22 1 1';\r
-       animparseerror = FALSE;\r
-       animfilename = strcat(self.model, ".animinfo");\r
-       animfile = fopen(animfilename, FILE_READ);\r
-       if (animfile >= 0)\r
-       {\r
-               self.anim_die1         = animparseline(animfile);\r
-               self.anim_die2         = animparseline(animfile);\r
-               self.anim_draw         = animparseline(animfile);\r
-               self.anim_duck         = animparseline(animfile);\r
-               self.anim_duckwalk     = animparseline(animfile);\r
-               self.anim_duckjump     = animparseline(animfile);\r
-               self.anim_duckidle     = animparseline(animfile);\r
-               self.anim_idle         = animparseline(animfile);\r
-               self.anim_jump         = animparseline(animfile);\r
-               self.anim_pain1        = animparseline(animfile);\r
-               self.anim_pain2        = animparseline(animfile);\r
-               self.anim_shoot        = animparseline(animfile);\r
-               self.anim_taunt        = animparseline(animfile);\r
-               self.anim_run          = animparseline(animfile);\r
-               self.anim_runbackwards = animparseline(animfile);\r
-               self.anim_strafeleft   = animparseline(animfile);\r
-               self.anim_straferight  = animparseline(animfile);\r
-               self.anim_forwardright = animparseline(animfile);\r
-               self.anim_forwardleft  = animparseline(animfile);\r
-               self.anim_backright    = animparseline(animfile);\r
-               self.anim_backleft     = animparseline(animfile);\r
-               fclose(animfile);\r
-\r
-               // derived anims\r
-               self.anim_dead1 = '0 1 1' + '1 0 0' * (self.anim_die1_x + self.anim_die1_y - 1);\r
-               self.anim_dead2 = '0 1 1' + '1 0 0' * (self.anim_die2_x + self.anim_die2_y - 1);\r
-\r
-               if (animparseerror)\r
-                       print("Parse error in ", animfilename, ", some player animations are broken\n");\r
-       }\r
-       else\r
-               dprint("File ", animfilename, " not found, assuming legacy .zym model animation timings\n");\r
-\r
-       // the line below is disabled due to issues with the stomach model, which cannot be animated.\r
-       // customizeentityforclient cannot let this part of the code know whether it's the stomach model or normal\r
-       // player model we're using. Attempting to animate the stomach model causes BIG issues, and must not be allowed.\r
-\r
+       self.anim_die1 = animfixfps(self, '0 1 0.5'); // 2 seconds\r
+       self.anim_die2 = animfixfps(self, '1 1 0.5'); // 2 seconds\r
+       self.anim_draw = animfixfps(self, '2 1 3');\r
+       // self.anim_duck = '3 1 100'; // This anim is broken, use slot 3 as a new free slot in the future ;)\r
+       self.anim_duckwalk = animfixfps(self, '4 1 1');\r
+       self.anim_duckjump = '5 1 100'; // NOTE: zym anims keep playing until changed, so this only has to start the anim, landing will end it\r
+       self.anim_duckidle = animfixfps(self, '6 1 1');\r
+       self.anim_idle = animfixfps(self, '7 1 1');\r
+       self.anim_jump = '8 1 100'; // NOTE: zym anims keep playing until changed, so this only has to start the anim, landing will end it\r
+       self.anim_pain1 = animfixfps(self, '9 1 2'); // 0.5 seconds\r
+       self.anim_pain2 = animfixfps(self, '10 1 2'); // 0.5 seconds\r
+       self.anim_shoot = animfixfps(self, '11 1 5'); // analyze models and set framerate\r
+       self.anim_taunt = animfixfps(self, '12 1 0.33');\r
+       self.anim_run = animfixfps(self, '13 1 1');\r
+       self.anim_runbackwards = animfixfps(self, '14 1 1');\r
+       self.anim_strafeleft = animfixfps(self, '15 1 1');\r
+       self.anim_straferight = animfixfps(self, '16 1 1');\r
+       //self.anim_dead1 = animfixfps(self, '17 1 1');\r
+       //self.anim_dead2 = animfixfps(self, '18 1 1');\r
+       self.anim_forwardright = animfixfps(self, '19 1 1');\r
+       self.anim_forwardleft = animfixfps(self, '20 1 1');\r
+       self.anim_backright = animfixfps(self, '21 1 1');\r
+       self.anim_backleft  = animfixfps(self, '22 1 1');\r
+       self.anim_melee = animfixfps(self, '23 1 1');\r
+       self.anim_duckwalkbackwards = animfixfps(self, '24 1 1');\r
+       self.anim_duckwalkstrafeleft = animfixfps(self, '25 1 1');\r
+       self.anim_duckwalkstraferight = animfixfps(self, '26 1 1');\r
+       self.anim_duckwalkforwardright = animfixfps(self, '27 1 1');\r
+       self.anim_duckwalkforwardleft = animfixfps(self, '28 1 1');\r
+       self.anim_duckwalkbackright = animfixfps(self, '29 1 1');\r
+       self.anim_duckwalkbackleft  = animfixfps(self, '30 1 1');\r
+       // TODO introspect models for finding right "fps" value (1/duration)\r
        // reset animstate now\r
-       //setanim(self, self.anim_idle, TRUE, FALSE, TRUE);\r
+       setanim(self, self.anim_idle, TRUE, FALSE, TRUE);\r
 };\r
 \r
 void player_anim (void)\r
@@ -312,7 +277,18 @@ void player_anim (void)
 \r
        if (!self.animstate_override)\r
        {\r
-               if (!(self.flags & FL_ONGROUND))\r
+               if(self.swallow_progress_pred)\r
+                       setanim(self, self.anim_duckjump, TRUE, FALSE, FALSE); // looks good for predators who are swallowing\r
+               else if(self.swallow_progress_prey)\r
+                       setanim(self, self.anim_die2, FALSE, FALSE, FALSE); // looks good for prey who's getting swallowed\r
+               else if(self.stat_eaten)\r
+               {\r
+                       if(self.BUTTON_ATCK || self.predator.digesting)\r
+                               setanim(self, self.anim_pain2, FALSE, TRUE, FALSE); // looks good for prey attacking the stomach or being digested\r
+                       else\r
+                               setanim(self, self.anim_jump, FALSE, TRUE, FALSE); // looks good for prey idling inside the stomach\r
+               }\r
+               else if (!(self.flags & FL_ONGROUND))\r
                {\r
                        if (self.crouch)\r
                                setanim(self, self.anim_duckjump, FALSE, TRUE, self.restart_jump);\r
@@ -322,8 +298,22 @@ void player_anim (void)
                }\r
                else if (self.crouch)\r
                {\r
-                       if (self.movement_x * self.movement_x + self.movement_y * self.movement_y > 20)\r
+                       if (self.movement_x > 0 && self.movement_y == 0)\r
                                setanim(self, self.anim_duckwalk, TRUE, FALSE, FALSE);\r
+                       else if (self.movement_x < 0 && self.movement_y == 0)\r
+                               setanim(self, self.anim_duckwalkbackwards, TRUE, FALSE, FALSE);\r
+                       else if (self.movement_x == 0 && self.movement_y > 0)\r
+                               setanim(self, self.anim_duckwalkstraferight, TRUE, FALSE, FALSE);\r
+                       else if (self.movement_x == 0 && self.movement_y < 0)\r
+                               setanim(self, self.anim_duckwalkstrafeleft, TRUE, FALSE, FALSE);\r
+                       else if (self.movement_x > 0 && self.movement_y > 0)\r
+                               setanim(self, self.anim_duckwalkforwardright, TRUE, FALSE, FALSE);\r
+                       else if (self.movement_x > 0 && self.movement_y < 0)\r
+                               setanim(self, self.anim_duckwalkforwardleft, TRUE, FALSE, FALSE);\r
+                       else if (self.movement_x < 0 && self.movement_y > 0)\r
+                               setanim(self, self.anim_duckwalkbackright, TRUE, FALSE, FALSE);\r
+                       else if (self.movement_x < 0 && self.movement_y < 0)\r
+                               setanim(self, self.anim_duckwalkbackleft, TRUE, FALSE, FALSE);\r
                        else\r
                                setanim(self, self.anim_duckidle, TRUE, FALSE, FALSE);\r
                }\r
@@ -354,12 +344,21 @@ void player_anim (void)
 \r
        if (self.weaponentity)\r
        if (!self.weaponentity.animstate_override)\r
-               setanim(self.weaponentity, self.weaponentity.anim_idle, TRUE, FALSE, FALSE);\r
+       {\r
+               if(self.swallow_progress_pred)\r
+                       setanim(self.weaponentity, self.weaponentity.anim_fire2, TRUE, FALSE, FALSE); // looks good for predators who are swallowing\r
+               else if(self.swallow_progress_prey)\r
+                       setanim(self.weaponentity, self.weaponentity.anim_reload, TRUE, FALSE, FALSE); // looks good for prey who's getting swallowed\r
+               else if(self.stat_eaten && self.BUTTON_ATCK)\r
+                       setanim(self.weaponentity, self.weaponentity.anim_fire1, TRUE, FALSE, FALSE); // looks good for prey attacking the stomach\r
+               else\r
+                       setanim(self.weaponentity, self.weaponentity.anim_idle, TRUE, FALSE, FALSE);\r
+       }\r
 }\r
 \r
-void SpawnThrownWeapon (vector org, float w)\r
+void SpawnThrownWeapon (vector org, float w, float doreduce)\r
 {\r
-       W_ThrowWeapon(randomvec() * 125 + '0 0 200', org - self.origin, FALSE);\r
+       W_ThrowWeapon(randomvec() * 125 + '0 0 200', org - self.origin, doreduce);\r
 }\r
 \r
 void PlayerCorpseDamage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)\r
@@ -402,18 +401,7 @@ void PlayerCorpseDamage (entity inflictor, entity attacker, float damage, float
        self.dmg_take = self.dmg_take + take;//max(take - 10, 0);\r
        self.dmg_inflictor = inflictor;\r
 \r
-       if (self.health <= -75 && self.modelindex != 0)\r
-       {\r
-               // don't use any animations as a gib\r
-               self.frame = 0;\r
-               self.dead_frame = 0;\r
-               // view just above the floor\r
-               self.view_ofs = '0 0 4';\r
-\r
-               Violence_GibSplash(self, 1, 1, attacker);\r
-               self.modelindex = 0; // restore later\r
-               self.solid = SOLID_NOT; // restore later\r
-       }\r
+       PlayerGib(self, attacker);\r
 }\r
 \r
 void ClientKill_Now_TeamChange();\r
@@ -593,7 +581,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht
                // clear selected player display\r
                ClearSelectedPlayer();\r
                // throw a weapon\r
-               SpawnThrownWeapon (self.origin + (self.mins + self.maxs) * 0.5, self.switchweapon);\r
+               SpawnThrownWeapon (self.origin + (self.mins + self.maxs) * 0.5, self.switchweapon, FALSE);\r
                // print an obituary message\r
                Obituary (attacker, inflictor, self, deathtype);\r
                race_PreDie();\r
@@ -614,19 +602,25 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht
                }\r
                // clear waypoints\r
                WaypointSprite_PlayerDead();\r
-               // make the corpse upright (not tilted)\r
-               self.angles_x = 0;\r
-               self.angles_z = 0;\r
-               // don't spin\r
-               self.avelocity = '0 0 0';\r
-               // view from the floor\r
-               self.view_ofs = '0 0 -8';\r
-               // toss the corpse\r
-               self.movetype = MOVETYPE_TOSS;\r
-               // shootable corpse\r
-               self.solid = SOLID_CORPSE;\r
-               // don't stick to the floor\r
-               self.flags &~= FL_ONGROUND;\r
+\r
+               // configure these properties if the dead body is not a prey\r
+               if(!self.stat_eaten)\r
+               {\r
+                       // make the corpse upright (not tilted)\r
+                       self.angles_x = 0;\r
+                       self.angles_z = 0;\r
+                       // don't spin\r
+                       self.avelocity = '0 0 0';\r
+                       // view from the floor\r
+                       self.view_ofs = '0 0 -8';\r
+                       // toss the corpse\r
+                       self.movetype = MOVETYPE_TOSS;\r
+                       // shootable corpse\r
+                       self.solid = SOLID_CORPSE;\r
+                       // don't stick to the floor\r
+                       self.flags &~= FL_ONGROUND;\r
+               }\r
+\r
                // dying animation\r
                self.deadflag = DEAD_DYING;\r
                // when to allow respawn\r
@@ -745,7 +739,6 @@ void ClearSelectedPlayer()
        }\r
 }\r
 \r
-.float dropweapon_check;\r
 void UpdateSelectedPlayer()\r
 {\r
        entity selected;\r
@@ -753,12 +746,12 @@ void UpdateSelectedPlayer()
        selected = world;\r
        selected_score = 0.95; // 18 degrees\r
 \r
-       if(self.predator.classname == "player")\r
+       if(self.stat_eaten)\r
        {\r
                if(!self.dropweapon_check)\r
                if(self.predator.team != self.team) // don't disarm team mates when swallowing them\r
                if(random() < cvar("g_balance_vore_swallow_dropweapon"))\r
-                       SpawnThrownWeapon (self.origin + (self.mins + self.maxs) * 0.5, self.switchweapon);\r
+                       SpawnThrownWeapon (self.origin + (self.mins + self.maxs) * 0.5, self.switchweapon, TRUE);\r
                self.dropweapon_check = TRUE;\r
        }\r
        else\r
@@ -1211,10 +1204,12 @@ void UpdatePlayerSounds()
        LoadPlayerSounds(strcat(self.model, ".sounds"), 0);\r
 }\r
 \r
-void GlobalSound(string sample, float chan, float voicetype)\r
+void GlobalSound(string sample, float chan, float voicetype, float vol)\r
 {\r
        float n;\r
        float tauntrand;\r
+       float vol_scale, vol_prey, vol_apply;\r
+       float pitch;\r
 \r
        if(sample == "")\r
                return;\r
@@ -1226,6 +1221,17 @@ void GlobalSound(string sample, float chan, float voicetype)
        else\r
                sample = strcat(argv(0), ".wav"); // randomization\r
 \r
+       // modified volume, used for attenuated (non-radio) voices\r
+       vol_scale = vol_prey = 1;\r
+       if(cvar("g_healthsize") && cvar("g_healthsize_soundfactor")) // amplify or reduce sound volume based on the size of the player\r
+               vol_scale *= bound(0, pow(self.scale, cvar("g_healthsize_soundfactor")), 1);\r
+       if(self.stat_eaten && cvar("g_vore_soundocclusion")) // reduce sound volume for prey, to simulate stomach culling\r
+               vol_prey *= bound(0, cvar("g_vore_soundocclusion"), 1);\r
+\r
+       // modified sound pitch, based on player scale\r
+       if(cvar("g_healthsize") && cvar("g_healthsize_pitch"))\r
+               pitch = pow(self.scale, -cvar("g_healthsize_pitch"));\r
+\r
        switch(voicetype)\r
        {\r
                case VOICETYPE_LASTATTACKER_ONLY:\r
@@ -1237,13 +1243,12 @@ void GlobalSound(string sample, float chan, float voicetype)
                                        {\r
                                                if(msg_entity.cvar_cl_voice_directional == 1)\r
                                                {\r
-                                                       if(self.predator.classname == "player")\r
-                                                               soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE * bound(0, cvar("g_vore_soundocclusion"), 1), ATTN_MIN);\r
-                                                       else\r
-                                                               soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_MIN);\r
+                                                       vol_apply = vol;\r
+                                                       vol_apply *= (self.predator != msg_entity.predator && self != msg_entity) ? vol_scale * vol_prey : vol_scale;\r
+                                                       soundto(MSG_ONE, self, chan, sample, vol_apply, ATTN_MIN, pitch);\r
                                                }\r
                                                else\r
-                                                       soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_NONE);\r
+                                                       soundto(MSG_ONE, self, chan, sample, vol, ATTN_NONE, pitch);\r
                                        }\r
                                }\r
                        break;\r
@@ -1256,17 +1261,16 @@ void GlobalSound(string sample, float chan, float voicetype)
                                        {\r
                                                if(msg_entity.cvar_cl_voice_directional == 1)\r
                                                {\r
-                                                       if(self.predator.classname == "player")\r
-                                                               soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE * bound(0, cvar("g_vore_soundocclusion"), 1), ATTN_MIN);\r
-                                                       else\r
-                                                               soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_MIN);\r
+                                                       vol_apply = vol;\r
+                                                       vol_apply *= (self.predator != msg_entity.predator && self != msg_entity) ? vol_scale * vol_prey : vol_scale;\r
+                                                       soundto(MSG_ONE, self, chan, sample, vol_apply, ATTN_MIN, pitch);\r
                                                }\r
                                                else\r
-                                                       soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_NONE);\r
+                                                       soundto(MSG_ONE, self, chan, sample, vol, ATTN_NONE, pitch);\r
                                        }\r
                                        msg_entity = self;\r
                                        if(clienttype(msg_entity) == CLIENTTYPE_REAL)\r
-                                               soundto(MSG_ONE, self, chan, sample, VOL_BASE, ATTN_NONE);\r
+                                               soundto(MSG_ONE, self, chan, sample, VOL_BASE, ATTN_NONE, pitch);\r
                                }\r
                        break;\r
                case VOICETYPE_TEAMRADIO:\r
@@ -1275,13 +1279,12 @@ void GlobalSound(string sample, float chan, float voicetype)
                                {\r
                                        if(msg_entity.cvar_cl_voice_directional == 1)\r
                                        {\r
-                                               if(self.predator.classname == "player")\r
-                                                       soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE * bound(0, cvar("g_vore_soundocclusion"), 1), ATTN_MIN);\r
-                                               else\r
-                                                       soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_MIN);\r
+                                               vol_apply = vol;\r
+                                               vol_apply *= (self.predator != msg_entity.predator && self != msg_entity) ? vol_scale * vol_prey : vol_scale;\r
+                                               soundto(MSG_ONE, self, chan, sample, vol_apply, ATTN_MIN, pitch);\r
                                        }\r
                                        else\r
-                                               soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_NONE);\r
+                                               soundto(MSG_ONE, self, chan, sample, vol, ATTN_NONE, pitch);\r
                                }\r
                        break;\r
                case VOICETYPE_AUTOTAUNT:\r
@@ -1293,18 +1296,17 @@ void GlobalSound(string sample, float chan, float voicetype)
                                break;\r
                        tauntrand = random();\r
                        FOR_EACH_REALCLIENT(msg_entity)\r
-                       {\r
                                if (tauntrand < msg_entity.cvar_cl_autotaunt)\r
-                               if (msg_entity.cvar_cl_voice_directional >= 1)\r
                                {\r
-                                       if(self.predator.classname == "player")\r
-                                               soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE * bound(0, cvar("g_vore_soundocclusion"), 1), bound(ATTN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTN_MAX));\r
+                                       if (msg_entity.cvar_cl_voice_directional >= 1)\r
+                                       {\r
+                                               vol_apply = vol;\r
+                                               vol_apply *= (self.predator != msg_entity.predator && self != msg_entity) ? vol_scale * vol_prey : vol_scale;\r
+                                               soundto(MSG_ONE, self, chan, sample, vol_apply, bound(ATTN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTN_MAX), pitch);\r
+                                       }\r
                                        else\r
-                                               soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, bound(ATTN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTN_MAX));\r
+                                               soundto(MSG_ONE, self, chan, sample, vol, ATTN_NONE, pitch);\r
                                }\r
-                               else\r
-                                       soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_NONE);\r
-                       }\r
                        break;\r
                case VOICETYPE_TAUNT:\r
                        if(self.classname == "player")\r
@@ -1318,23 +1320,25 @@ void GlobalSound(string sample, float chan, float voicetype)
                        {\r
                                if (msg_entity.cvar_cl_voice_directional >= 1)\r
                                {\r
-                                       if(self.predator.classname == "player")\r
-                                               soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE * bound(0, cvar("g_vore_soundocclusion"), 1), bound(ATTN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTN_MAX));\r
-                                       else\r
-                                               soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, bound(ATTN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTN_MAX));\r
+                                       vol_apply = vol;\r
+                                       vol_apply *= (self.predator != msg_entity.predator && self != msg_entity) ? vol_scale * vol_prey : vol_scale;\r
+                                       soundto(MSG_ONE, self, chan, sample, vol_apply, bound(ATTN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTN_MAX), pitch);\r
                                }\r
                                else\r
-                                       soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_NONE);\r
+                                       soundto(MSG_ONE, self, chan, sample, vol, ATTN_NONE, pitch);\r
                        }\r
                case VOICETYPE_PLAYERSOUND:\r
-                       if(self.predator.classname == "player")\r
-                               sound(self, chan, sample, VOL_BASE * bound(0, cvar("g_vore_soundocclusion"), 1), ATTN_NORM);\r
-                       else\r
-                               sound(self, chan, sample, VOL_BASE, ATTN_NORM);\r
+                       FOR_EACH_REALCLIENT(msg_entity)\r
+                       {\r
+                               vol_apply = vol;\r
+                               vol_apply *= (self.predator != msg_entity.predator && self != msg_entity) ? vol_scale * vol_prey : vol_scale;\r
+                               soundto(MSG_ONE, self, chan, sample, vol_apply, ATTN_NORM, pitch);\r
+                       }\r
                        break;\r
                case VOICETYPE_GURGLE:\r
+                       // since players can't be prey and predators at the same time, we don't use the prey modifier for the gurgle sound volume\r
                        if(self.stomach_load)\r
-                               sound(self, chan, sample, VOL_BASE * self.stomach_load / cvar("g_balance_vore_swallow_limit"), ATTN_NORM);\r
+                               sound7(self, chan, sample, bound(0, vol_scale * (self.stomach_load / self.stomach_maxload), 1), ATTN_NORM, pitch * 100, 0);\r
                        else\r
                                stopsound(self, chan);\r
                        break;\r
@@ -1352,7 +1356,7 @@ void PlayerSound(entity player, .string samplefield, float chan, float voicetype
        oldself = self;\r
        self = player;\r
        sample = self.samplefield;\r
-       GlobalSound(sample, chan, voicetype);\r
+       GlobalSound(sample, chan, voicetype, VOL_BASEVOICE);\r
        self = oldself;\r
 }\r
 \r