void CopyBody(float keepvelocity)\r
{\r
local entity oldself;\r
- if (self.effects & EF_NODRAW)\r
+ if (self.effects & EF_NODRAW || self.alpha < 0)\r
return;\r
oldself = self;\r
self = spawn();\r
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
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
\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
\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
}\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
\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
self.armorvalue = self.armorvalue - save;\r
self.health = self.health - take;\r
// pause regeneration for 5 seconds\r
- self.pauseregen_finished = max(self.pauseregen_finished, time + cvar("g_balance_pause_health_regen"));\r
+ self.pauseregenhealth_finished = max(self.pauseregenhealth_finished, time + cvar("g_balance_pause_health_regen"));\r
+ self.pauseregenarmor_finished = max(self.pauseregenarmor_finished, time + cvar("g_balance_pause_armor_regen"));\r
}\r
self.dmg_save = self.dmg_save + save;//max(save - 10, 0);\r
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
self.armorvalue = self.armorvalue - save;\r
self.health = self.health - take;\r
// pause regeneration for 5 seconds\r
- self.pauseregen_finished = max(self.pauseregen_finished, time + cvar("g_balance_pause_health_regen"));\r
+ self.pauseregenhealth_finished = max(self.pauseregenhealth_finished, time + cvar("g_balance_pause_health_regen"));\r
+ self.pauseregenarmor_finished = max(self.pauseregenarmor_finished, time + cvar("g_balance_pause_armor_regen"));\r
\r
if (time > self.pain_finished) //Don't switch pain sequences like crazy\r
{\r
}\r
\r
if(sound_allowed(MSG_BROADCAST, attacker))\r
+ if(self.health > 1)\r
{\r
- if(self.health > 75) // TODO make a "gentle" version?\r
+ if(deathtype == DEATH_FALL)\r
+ PlayerSound(self, playersound_fall, CHAN_PAIN, VOICETYPE_PLAYERSOUND);\r
+ else if(self.health > 75) // TODO make a "gentle" version?\r
PlayerSound(self, playersound_pain100, CHAN_PAIN, VOICETYPE_PLAYERSOUND);\r
else if(self.health > 50)\r
PlayerSound(self, playersound_pain75, CHAN_PAIN, VOICETYPE_PLAYERSOUND);\r
else if(self.health > 25)\r
PlayerSound(self, playersound_pain50, CHAN_PAIN, VOICETYPE_PLAYERSOUND);\r
- else if(self.health > 1)\r
+ else\r
PlayerSound(self, playersound_pain25, CHAN_PAIN, VOICETYPE_PLAYERSOUND);\r
}\r
}\r
// 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
}\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
}\r
}\r
\r
-.float dropweapon_check;\r
void UpdateSelectedPlayer()\r
{\r
entity selected;\r
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
\r
// FLOOD CONTROL\r
flood = 0;\r
+ var .float flood_field;\r
if(floodcontrol)\r
{\r
float flood_spl;\r
float flood_burst;\r
float flood_lmax;\r
- var .float flood_field;\r
float lines;\r
if(privatesay)\r
{\r
}\r
}\r
\r
- if (timeoutStatus == 2) //when game is paused, no flood protection\r
- source.flood_field = flood = 0;\r
+ if (timeoutStatus == 2) { //when game is paused, no flood protection\r
+ source.flood_field = 0;\r
+ flood = 0;\r
+ }\r
\r
if(flood == 2)\r
{\r
}\r
\r
.float modelindex_for_playersound;\r
+.float skin_for_playersound;\r
void UpdatePlayerSounds()\r
{\r
if(self.modelindex == self.modelindex_for_playersound)\r
+ if(self.skin == self.skin_for_playersound)\r
return;\r
self.modelindex_for_playersound = self.modelindex;\r
+ self.skin_for_playersound = self.skin;\r
ClearPlayerSounds();\r
LoadPlayerSounds("sound/player/default.sounds", 1);\r
- LoadPlayerSounds(strcat(self.model, ".sounds"), 0);\r
+ LoadPlayerSounds(strcat(self.model, "_", ftos(self.skin), ".", "sounds"), 0);\r
+ 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
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
{\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
{\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
{\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
{\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
break;\r
case VOICETYPE_TAUNT:\r
{\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
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