]> git.xonotic.org Git - voretournament/voretournament.git/blobdiff - data/qcsrc/server/vore.qc
Separate and fix some cvars
[voretournament/voretournament.git] / data / qcsrc / server / vore.qc
index 300dfc738519484a138c72cd3e3720d215f66cc2..54faf616cc670a5a7ca604a38bfbb8364e1fbc56 100644 (file)
@@ -139,9 +139,14 @@ void Vore_GurgleSound()
 {\r
        if(time > self.gurglesound_finished || (self.gurgle_oldstomachload != self.stomach_load && !self.digesting))\r
        {\r
-               GlobalSound(self.playersound_gurgle, CHAN_TRIGGER, VOICETYPE_GURGLE);\r
+               GlobalSound(self.playersound_gurgle, CHAN_TRIGGER, VOICETYPE_GURGLE, VOL_BASE);\r
+\r
+               // yes, hard coded sound length. I know it's bad but what can I do?\r
+               if(cvar("g_healthsize") && cvar("g_healthsize_pitch"))\r
+                       self.gurglesound_finished = time + 11 * pow(self.scale, -cvar("g_healthsize_pitch")); // modified sound pitch, based on player scale\r
+               else\r
+                       self.gurglesound_finished = time + 11; // yes, hard coded sound length. I know it's bad but what can I do?\r
 \r
-               self.gurglesound_finished = time + 11; // yes, hard coded sound length. I know it's bad but what can I do?\r
                self.gurgle_oldstomachload = self.stomach_load;\r
        }\r
 }\r
@@ -152,10 +157,12 @@ void Vore_AutoDigest(entity e)
 \r
        if(!cvar("g_vore_digestion") || e.digesting)\r
                return;\r
-       if(clienttype(e) != CLIENTTYPE_REAL)\r
-               return; // this feature is only for players, not bots\r
+       if(g_rpg)\r
+               return; // RPG is choice based, so don't do things automatically there\r
        if(e.stomach_load)\r
                return; // don't start digestion if we already ate someone, as that means we manually disabled it after the first prey and want it off\r
+       if(clienttype(e) != CLIENTTYPE_REAL)\r
+               return; // this feature is only for players, not bots\r
        if(Stomach_TeamMates_check(e))\r
                return; // never begin automatic digestion if we've swallowed a team mate\r
 \r
@@ -202,7 +209,7 @@ void Vore_StomachLoad_Apply()
        self.stomach_load = final_load;\r
 \r
        // apply weight\r
-       self.gravity = 1 + (self.stomach_load / self.stomach_maxload) * cvar("g_balance_vore_load_pred_weight");\r
+       self.gravity = 1 * (cvar("g_healthsize") ? pow(self.scale, cvar("g_healthsize_weight")) : 1) + (self.stomach_load / self.stomach_maxload) * cvar("g_balance_vore_load_pred_weight");\r
        if(!self.gravity && self.stomach_load)\r
                self.gravity = 0.00001; // 0 becomes 1 for gravity, so do this to allow 0 gravity\r
 }\r
@@ -296,6 +303,9 @@ void Vore_Swallow(entity e)
        e.solid = SOLID_NOT;\r
        e.aiment = e.predator; // follow the predator, automatically unset when regurgitated\r
 \r
+       float scalediff;\r
+       scalediff = cvar("g_healthsize") ? e.scale / e.predator.scale : 1; // the tighter the gut, the greater the effect\r
+\r
        // drop keys (KH) and flags (CTF) when we get swallowed\r
        kh_Key_DropAll(e, FALSE);\r
        if(e.flagcarried)\r
@@ -314,7 +324,9 @@ void Vore_Swallow(entity e)
 \r
        PlayerSound(e.predator, playersound_swallow, CHAN_VOICE, VOICETYPE_PLAYERSOUND);\r
        setanim(e.predator, e.predator.anim_pain1, FALSE, TRUE, TRUE); // looks good for swallowing / regurgitating\r
-       e.predator.punchangle_x -= cvar("g_balance_vore_swallow_predator_punchangle");\r
+       e.predator.punchangle_x = crandom() * cvar("g_balance_vore_swallow_predator_punchangle") * scalediff;\r
+       e.predator.punchangle_y = crandom() * cvar("g_balance_vore_swallow_predator_punchangle") * scalediff;\r
+       e.predator.punchangle_z = crandom() * cvar("g_balance_vore_swallow_predator_punchangle") * scalediff;\r
        e.predator.regurgitate_prepare = 0;\r
        e.predator.spawnshieldtime = 0; // lose spawn shield when we vore\r
        e.predator.hitsound += 1; // play this for team mates too, as we could be swallowing them to heal them\r
@@ -329,23 +341,38 @@ void Vore_Swallow(entity e)
 \r
 void Vore_SwallowStep(entity e)\r
 {\r
-       if(!cvar("g_balance_vore_swallow_speed_fill"))\r
+       if(!cvar("g_balance_vore_swallow_speed_fill_player"))\r
        {\r
                Vore_Swallow(e);\r
                return;\r
        }\r
 \r
+       // when the predator starts swallowing, play his grab sound\r
+       if(!self.swallow_progress_pred)\r
+               PlayerSound(self, playersound_grab, CHAN_PAIN, VOICETYPE_PLAYERSOUND);\r
+\r
        Vore_SwallowModel_Update(e, self);\r
 \r
        // increase the progress value until it reaches 1, then swallow the player\r
        if(e.swallow_progress_prey < 1)\r
        {\r
                float fill;\r
-               fill = cvar("g_balance_vore_swallow_speed_fill") * frametime;\r
-               if(cvar("g_healthsize") && cvar("g_balance_vore_swallow_speed_fill_scalediff")) // fill rate depends on predator size compared to prey size\r
-                       fill *= pow(self.scale / e.scale, cvar("g_balance_vore_swallow_speed_fill_scalediff"));\r
-               if(cvar("g_balance_vore_swallow_speed_fill_stomachload") && e.stomach_load) // fill rate is influenced by the prey's stomach load\r
-                       fill *= (1 - ((e.stomach_load / e.stomach_maxload) * bound(0, cvar("g_balance_vore_swallow_speed_fill_stomachload"), 1)));\r
+               fill = cvar("g_balance_vore_swallow_speed_fill_player") * frametime;\r
+               if(cvar("g_healthsize") && cvar("g_balance_vore_swallow_speed_fill_scalediff_player")) // fill rate depends on predator size compared to prey size\r
+                       fill *= pow(self.scale / e.scale, cvar("g_balance_vore_swallow_speed_fill_scalediff_player"));\r
+               if(cvar("g_balance_vore_swallow_speed_fill_player_stomachload") && e.stomach_load) // fill rate is influenced by the prey's stomach load\r
+                       fill *= (1 - ((e.stomach_load / e.stomach_maxload) * bound(0, cvar("g_balance_vore_swallow_speed_fill_player_stomachload"), 1)));\r
+\r
+               // skill-based speed offset for bots\r
+               if(skill && cvar("skill_offset"))\r
+               {\r
+                       float ofs;\r
+                       ofs = pow(skill / cvar("skill_offset_center"), cvar("skill_offset"));\r
+                       if(clienttype(self) == CLIENTTYPE_BOT)\r
+                               fill *= ofs;\r
+                       if(clienttype(e) == CLIENTTYPE_BOT)\r
+                               fill /= ofs;\r
+               }\r
 \r
                e.swallow_progress_prey += fill;\r
        }\r
@@ -370,6 +397,7 @@ void Vore_Regurgitate(entity e)
        e.punchvector_z = -cvar("g_balance_vore_regurgitate_prey_punchvector");\r
 \r
        // if the prey has been fully digested, silently detach them\r
+       if(cvar("g_balance_vore_regurgitate_death_silent"))\r
        if(e.deadflag != DEAD_NO && e.health <= cvar("g_balance_vore_digestion_limit"))\r
        {\r
                e.predator = world;\r
@@ -377,10 +405,13 @@ void Vore_Regurgitate(entity e)
                return;\r
        }\r
 \r
+       float scalediff;\r
+       scalediff = cvar("g_healthsize") ? e.scale / e.predator.scale : 1; // the tighter the gut, the greater the effect\r
+\r
        // apply velocities\r
        makevectors(e.predator.v_angle);\r
-       e.velocity = v_forward * cvar("g_balance_vore_regurgitate_force");\r
-       e.predator.velocity += -v_forward * cvar("g_balance_vore_regurgitate_predatorforce");\r
+       e.velocity = v_forward * cvar("g_balance_vore_regurgitate_force") * scalediff;\r
+       e.predator.velocity += -v_forward * cvar("g_balance_vore_regurgitate_predatorforce") * scalediff;\r
        e.pusher = e.predator; // allows us to frag players by regurgitating them in deadly pits\r
        e.pushltime = time + cvar("g_maxpushtime");\r
 \r
@@ -389,7 +420,7 @@ void Vore_Regurgitate(entity e)
        PlayerGib(e, e.predator);\r
 \r
        // regurgitated prey is given this amount of swallow progress, to simulate being more vulnerable\r
-       if(cvar("g_balance_vore_swallow_speed_fill") && cvar("g_balance_vore_regurgitate_swallowprogress"))\r
+       if(cvar("g_balance_vore_swallow_speed_fill_player") && cvar("g_balance_vore_regurgitate_swallowprogress"))\r
        {\r
                e.swallow_progress_prey = cvar("g_balance_vore_regurgitate_swallowprogress");\r
                Vore_SwallowModel_Update(e, e.predator);\r
@@ -407,8 +438,10 @@ void Vore_Regurgitate(entity e)
 \r
        PlayerSound(e.predator, playersound_regurgitate, CHAN_VOICE, VOICETYPE_PLAYERSOUND);\r
        setanim(e.predator, e.predator.anim_pain1, FALSE, TRUE, TRUE); // looks good for swallowing / regurgitating\r
-       pointparticles(particleeffectnum("vore_regurgitate"), e.predator.origin, '0 0 0', 1);\r
-       e.predator.punchangle_x += cvar("g_balance_vore_regurgitate_predator_punchangle");\r
+       pointparticles(particleeffectnum("vore_regurgitate"), e.predator.origin, '0 0 0', floor(scalediff * PARTICLE_MULTIPLIER));\r
+       e.predator.punchangle_x = crandom() * cvar("g_balance_vore_regurgitate_predator_punchangle") * scalediff;\r
+       e.predator.punchangle_y = crandom() * cvar("g_balance_vore_regurgitate_predator_punchangle") * scalediff;\r
+       e.predator.punchangle_z = crandom() * cvar("g_balance_vore_regurgitate_predator_punchangle") * scalediff;\r
        e.predator.regurgitate_prepare = 0;\r
        e.predator.action_delay = time + cvar("g_balance_vore_action_delay");\r
        Vore_SetPreyPositions(e.predator);\r
@@ -419,9 +452,10 @@ void Vore_Regurgitate(entity e)
        e.predator = world;\r
 }\r
 \r
-void Vore_Disconnect()\r
+void Vore_Disconnect(float consumables)\r
 {\r
        // frees prey from their predators when someone disconnects or goes spectating, or in other circumstances\r
+       entity e;\r
 \r
        // prey disconnects or goes spectating while inside someone's belly\r
        if(self.stat_eaten)\r
@@ -434,6 +468,15 @@ void Vore_Disconnect()
                if(head.predator == self)\r
                        Vore_Regurgitate(head);\r
        }\r
+       // remove consumable items when we disconnect\r
+       if(consumables)\r
+       {\r
+               for(e = world; (e = find(e, classname, "consumable")); )\r
+               {\r
+                       if(e.predator == self)\r
+                               Item_Consumable_Remove(e, TRUE);\r
+               }\r
+       }\r
 \r
        self.stomach_load = self.gravity = 0; // prevents a bug\r
        Vore_GurgleSound(); // stop the gurgling sound\r
@@ -459,14 +502,14 @@ void Vore_Digest()
 \r
                damage_offset = 1;\r
                if(cvar("g_balance_vore_digestion_distribute")) // apply distributed digestion damage\r
-                       damage_offset *= self.predator.stomach_load / self.predator.stomach_maxload;\r
+                       damage_offset /= (1 - (self.predator.stomach_load / self.predator.stomach_maxload) * bound(0, cvar("g_balance_vore_digestion_distribute"), 1));\r
                if(cvar("g_healthsize") && cvar("g_balance_vore_digestion_scalediff")) // apply player scale to digestion damage\r
                        damage_offset *= pow(self.scale / self.predator.scale, cvar("g_balance_vore_digestion_scalediff"));\r
-               damage_offset = ceil(damage_offset);\r
 \r
-               damage = cvar("g_balance_vore_digestion_damage") / damage_offset;\r
-               if(cvar("g_balance_vore_digestion_damage_death") && self.deadflag != DEAD_NO) // amplify digestion damage for dead prey\r
-                       damage *= cvar("g_balance_vore_digestion_damage_death");\r
+               if(self.deadflag != DEAD_NO)\r
+                       damage = cvar("g_balance_vore_digestion_damage_death") / damage_offset;\r
+               else\r
+                       damage = cvar("g_balance_vore_digestion_damage") / damage_offset;\r
 \r
                Damage(self, self.predator, self.predator, damage, DEATH_DIGESTION, self.origin, '0 0 0');\r
                if(cvar("g_balance_vore_digestion_vampire") && self.predator.health < cvar("g_balance_vore_digestion_vampire_stable"))\r
@@ -513,27 +556,38 @@ void Vore_StomachKick()
        if(self.deadflag != DEAD_NO)\r
                return;\r
 \r
+       float scalediff;\r
+       scalediff = pow(self.scale / self.predator.scale, cvar("g_balance_vore_kick_scalediff"));\r
+\r
        if(time > self.stomachkick_delay && !self.kick_pressed)\r
        {\r
-               float damage, vol;\r
+               float damage, vol, pitch;\r
                vector force;\r
                damage = cvar("g_balance_vore_kick_damage");\r
                force = v_forward * cvar("g_balance_vore_kick_force");\r
                vol = VOL_BASE;\r
 \r
+               // modified sound pitch, based on player scale\r
+               if(cvar("g_healthsize") && cvar("g_healthsize_pitch"))\r
+                       pitch = pow(self.predator.scale, -cvar("g_healthsize_pitch"));\r
+\r
                // apply player scale to the damage / force of the kick\r
                if(cvar("g_healthsize") && cvar("g_balance_vore_kick_scalediff"))\r
                {\r
-                       damage *= pow(self.scale / self.predator.scale, cvar("g_balance_vore_kick_scalediff"));\r
-                       force *= pow(self.scale / self.predator.scale, cvar("g_balance_vore_kick_scalediff"));\r
-                       vol *= pow(self.scale / self.predator.scale, cvar("g_balance_vore_kick_scalediff")); // kick sound volume based on the same scale\r
+                       damage *= scalediff;\r
+                       force *= scalediff;\r
+                       vol *= scalediff; // kick sound volume based on the same scale\r
                }\r
                vol = bound(0, vol, 1);\r
 \r
                Damage(self.predator, self, self, damage, DEATH_STOMACHKICK, self.predator.origin, force);\r
-               sound(self.predator, CHAN_PROJECTILE, strcat("weapons/hit", ftos(floor(random() * 8)), ".wav"), vol, ATTN_NORM);\r
-               self.predator.punchangle_x -= cvar("g_balance_vore_kick_predator_punchangle");\r
-               self.punchangle_x += cvar("g_balance_vore_kick_prey_punchangle");\r
+               sound7(self.predator, CHAN_PROJECTILE, strcat("weapons/hit", ftos(floor(random() * 8)), ".wav"), vol, ATTN_NORM, 100 * pitch, 0);\r
+               self.predator.punchangle_x = crandom() * cvar("g_balance_vore_kick_predator_punchangle") * scalediff;\r
+               self.predator.punchangle_y = crandom() * cvar("g_balance_vore_kick_predator_punchangle") * scalediff;\r
+               self.predator.punchangle_z = crandom() * cvar("g_balance_vore_kick_predator_punchangle") * scalediff;\r
+               self.punchangle_x = crandom() * cvar("g_balance_vore_kick_prey_punchangle") * scalediff;\r
+               self.punchangle_y = crandom() * cvar("g_balance_vore_kick_prey_punchangle") * scalediff;\r
+               self.punchangle_z = crandom() * cvar("g_balance_vore_kick_prey_punchangle") * scalediff;\r
 \r
                // abort the predator's scheduled regurgitation\r
                if(random() < cvar("g_balance_vore_kick_cutregurgitate"))\r
@@ -675,7 +729,7 @@ void Vore()
                if(cvar("g_vore_regurgitatecolor_particles"))\r
                if(self.regurgitatecolor_particles_tick < time)\r
                {\r
-                       pointparticles(particleeffectnum("vore_regurgitate_constant"), self.origin, '0 0 0', 1);\r
+                       pointparticles(particleeffectnum("vore_regurgitate_constant"), self.origin, '0 0 0', floor((cvar("g_healthsize") ? self.scale : 1) * PARTICLE_MULTIPLIER));\r
                        self.regurgitatecolor_particles_tick = time + cvar("g_vore_regurgitatecolor_particles") * vlen(self.colormod); // particle time depends on how dirty the player is\r
                }\r
        }\r
@@ -708,17 +762,9 @@ void Vore()
        if(cvar("g_balance_vore_swallow_speed_decrease"))\r
        {\r
                if(self.swallow_progress_pred)\r
-               {\r
-                       self.swallow_progress_pred -= cvar("g_balance_vore_swallow_speed_decrease") * frametime;\r
-                       if(self.swallow_progress_pred < 0)\r
-                               self.swallow_progress_pred = 0;\r
-               }\r
+                       self.swallow_progress_pred = max(0, self.swallow_progress_pred - cvar("g_balance_vore_swallow_speed_decrease") * frametime);\r
                if(self.swallow_progress_prey)\r
-               {\r
-                       self.swallow_progress_prey -= cvar("g_balance_vore_swallow_speed_decrease") * frametime;\r
-                       if(self.swallow_progress_prey < 0)\r
-                               self.swallow_progress_prey = 0;\r
-               }\r
+                       self.swallow_progress_prey = max(0, self.swallow_progress_prey - cvar("g_balance_vore_swallow_speed_decrease") * frametime);\r
        }\r
 \r
        // set the predator's stomach load and capacity\r
@@ -727,12 +773,12 @@ void Vore()
        // apply delays and skip the vore system under some circumstances\r
        if(!cvar("g_vore")) // the vore system is disabled\r
        {\r
-               Vore_Disconnect();\r
+               Vore_Disconnect(TRUE);\r
                return;\r
        }\r
        if(time < game_starttime || (time < warmup && !inWarmupStage)) // don't allow vore before a round begins\r
        {\r
-               Vore_Disconnect();\r
+               Vore_Disconnect(FALSE);\r
                return;\r
        }\r
        if(self.spectatee_status)\r
@@ -786,6 +832,7 @@ void Vore()
 \r
        // predator wishes to regurgitate his prey\r
        if(self.BUTTON_REGURGITATE && time > self.action_delay)\r
+       if(!self.regurgitate_prepare)\r
        {\r
                if(self.stomach_load)\r
                {\r
@@ -858,9 +905,8 @@ void Vore()
        // apply delayed regurgitating if it was scheduled\r
        if(self.predator.regurgitate_prepare && time > self.predator.regurgitate_prepare)\r
        {\r
-               self.predator.regurgitate_prepare = 0;\r
-               self.predator.complain_vore = time + complain_delay_time; // prevent complaining the next frame if this empties our stomach\r
                Vore_Regurgitate(self);\r
+               self.predator.complain_vore = time + complain_delay_time; // prevent complaining the next frame if this empties our stomach\r
        }\r
 \r
        // execute digesting and team healing\r