X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=data%2Fqcsrc%2Fserver%2Fcl_client.qc;h=29f39be31fe7813c3d08754451ecbaf12547fb45;hb=bf7ed15977857de30addba2229da888cb425fef4;hp=eaa93cf820e97497a2d2e6c245ad536f3390c270;hpb=cd0ac8cefda12d4a5d5808dca19af9ed3922c11e;p=voretournament%2Fvoretournament.git diff --git a/data/qcsrc/server/cl_client.qc b/data/qcsrc/server/cl_client.qc index eaa93cf8..29f39be3 100644 --- a/data/qcsrc/server/cl_client.qc +++ b/data/qcsrc/server/cl_client.qc @@ -436,11 +436,11 @@ string setmodel_state() newmodel_extension = substring(self.playermodel, strlen(self.playermodel) - 4, 4); float vore_state; - if(self.stomach_load > self.stat_stomachmaxload * 0.6) + if(self.stomach_load > self.stomach_maxload * 0.75) vore_state = 3; - else if(self.stomach_load > self.stat_stomachmaxload * 0.3) + else if(self.stomach_load > self.stomach_maxload * 0.5) vore_state = 2; - else if(self.stomach_load) + else if(self.stomach_load > self.stomach_maxload * 0.25) vore_state = 1; if(vore_state) @@ -459,7 +459,7 @@ Client_customizeentityforclient void Client_setmodel(string applymodel) { local vector m1, m2; - if(self.classname != "player" || self.deadflag != DEAD_NO) // prevent some bugs + if(self.classname != "player") // prevent some bugs return; if(applymodel == self.model || self.spectatee_status) // no change to apply return; @@ -531,7 +531,7 @@ float Client_customizeentityforclient() // don't do this if we have chase_active enabled, as we'd be seeing a floating stomach from third person view if not(chase || other.classname == "observer") // the observer check prevents a bug - if(other.predator == self || other.fakepredator == self) + if(other.predator == self) { Client_setmodel(stomachmodel); self.effects |= EF_NODEPTHTEST; // don't hide behind walls @@ -541,9 +541,9 @@ float Client_customizeentityforclient() Client_setmodel(setmodel_state()); self.effects &~= EF_NODEPTHTEST; - if not(self.stat_eaten || self.fakeprey) + if not(self.stat_eaten) self.alpha = default_player_alpha; - else if(cvar("g_vore_neighborprey_distance") && !self.fakeprey && (self.predator == other.predator || self.predator == other.fakepredator) && !(chase || other.classname == "observer")) + else if(cvar("g_vore_neighborprey_distance") && self.predator == other.predator && !(chase || other.classname == "observer")) { self.alpha = default_player_alpha; // allow seeing neighboring prey self.effects |= EF_NODEPTHTEST; // don't hide behind the stomach's own EF_NODEPTHTEST @@ -846,8 +846,7 @@ void PutClientInServer (void) RemoveGrabber(self); // Wazat's Grabber - Vore_DeadPrey_Detach(self); - self.fakeprey = FALSE; // clear the fakeprey status + Vore_Disconnect(); self.swallow_progress_pred = self.swallow_progress_prey = 0; self.classname = "player"; @@ -929,6 +928,7 @@ void PutClientInServer (void) self.angles_z = 0; // never spawn tilted even if the spot says to self.fixangle = TRUE; // turn this way immediately + self.leanangle_damage_force = '0 0 0'; self.velocity = '0 0 0'; self.avelocity = '0 0 0'; self.punchangle = '0 0 0'; @@ -1020,7 +1020,7 @@ void PutClientInServer (void) entity e; e = get_weaponinfo(j); if(e.spawnflags & WEP_FLAG_RELOADABLE) // prevent accessing undefined cvars - self.weapon_load[j] = cvar(strcat("g_balance_", e.netname, "_reload_ammo")); + self.(weapon_load[j]) = cvar(strcat("g_balance_", e.netname, "_reload_ammo")); } oldself = self; @@ -1053,7 +1053,10 @@ float ClientInit_SendEntity(entity to, float sf) WriteByte(MSG_ENTITY, cvar("g_balance_weaponswitchdelay") * 255.0); WriteShort(MSG_ENTITY, cvar("g_vore")); - WriteShort(MSG_ENTITY, cvar("g_healthsize")); + if(cvar("g_healthsize")) + WriteShort(MSG_ENTITY, cvar("g_healthsize_center")); + else + WriteShort(MSG_ENTITY, -1); // healthsize is disabled WriteShort(MSG_ENTITY, cvar("g_healthsize_min")); WriteShort(MSG_ENTITY, cvar("g_healthsize_max")); @@ -1692,7 +1695,7 @@ void ChatBubbleThink() remove(self); return; } - if ((self.owner.BUTTON_CHAT && !self.owner.deadflag && !self.owner.stat_eaten && self.owner.fakepredator.classname != "player") + if ((self.owner.BUTTON_CHAT && !self.owner.deadflag && !self.owner.stat_eaten) #ifdef TETRIS || self.owner.tetris_on #endif @@ -1743,6 +1746,12 @@ void UpdateChatBubble() .float oldcolormap; void respawn(void) { + // don't allow respawing if the prey is still digesting + if(cvar("g_balance_vore_digestion_limit_blockrespawn")) + if(self.predator.digesting && self.health > cvar("g_balance_vore_digestion_limit")) + return; + + setmodel(self, self.playermodel); // prevents an issue with dead predators if(self.alpha >= 0 && self.modelindex != 0 && cvar("g_respawn_ghosts")) { self.solid = SOLID_NOT; @@ -2106,7 +2115,7 @@ void SpectateCopy(entity spectatee) { self.stomach_load = spectatee.stomach_load; self.stat_eaten = spectatee.stat_eaten; self.stat_stomachload = spectatee.stat_stomachload; - self.stat_stomachmaxload = spectatee.stat_stomachmaxload; + self.stat_stomachmaxload = spectatee.stomach_maxload; self.stat_digesting = spectatee.stat_digesting; self.stat_canleave = spectatee.stat_canleave; self.stat_canswallow = spectatee.stat_canswallow; @@ -2305,13 +2314,16 @@ float vercmp(string v1, string v2) return vercmp_recursive(v1, v2); } +.float last_alive_scale; void SetPlayerSize() { - if(cvar("g_healthsize")) + if(!cvar("g_healthsize")) + return; + + if(self.deadflag == DEAD_NO) { // change player scale based on the amount of health we have - - self.scale = bound(cvar("g_healthsize_min"), self.health, cvar("g_healthsize_max")) / cvar("g_healthsize"); + self.scale = pow(bound(cvar("g_healthsize_min"), self.health, cvar("g_healthsize_max")) / cvar("g_healthsize_center"), cvar("g_healthsize")); // The following code sets the bounding box to match the player's size. // It is currently disabled because of issues with engine movement prediction (cl_movement). @@ -2329,13 +2341,23 @@ void SetPlayerSize() if(!self.stat_eaten) self.view_ofs = PL_VIEW_OFS * self.scale; } + + self.last_alive_scale = self.scale; + } + else if(self.last_alive_scale) + { + // if the player is dead, use the last scale he had when he was alive + self.scale = self.last_alive_scale; } - if(self.stat_eaten && cvar("g_vore_neighborprey_distance")) + if(cvar("g_healthsize_death") && self.deadflag != DEAD_NO) { - // resize prey if neighborprey is enabled - self.scale *= cvar("g_vore_neighborprey_scale"); + // dead players shrink to zero as they head toward the health limit + self.scale *= 1 - bound(0, (self.health / cvar("g_healthsize_death_min")) * cvar("g_healthsize_death"), 1); } + + if(self.scale < 0.1) + self.scale = 0.1; // stuff breaks if scale is smaller than this } void ObserverThink() @@ -2420,6 +2442,7 @@ Called every frame for each client before the physics are run */ void() ctf_setstatus; .float items_added; +.vector avg_vel; void PlayerPreThink (void) { self.stat_game_starttime = game_starttime; @@ -2524,9 +2547,62 @@ void PlayerPreThink (void) self.fixangle = TRUE; } - if(frametime) + if(self.deadflag == DEAD_NO && !self.stat_eaten) // prevents bugs { + // lean the player with damage and acceleration + // credits go to divVerent for these maths :) + vector L0, L1, LF, LA; + + LA = AnglesTransform_FromAngles(self.angles); + + // acceleration leaning + if(cvar("g_leanplayer_acceleration")) + { + // average velocity to obtain a smooth acceleration + float f; + f = frametime * cvar("g_leanplayer_acceleration_fade"); + self.avg_vel = self.avg_vel * (1 - f) + self.velocity * f; + } + vector accel; + accel = self.velocity - self.avg_vel * cvar("g_leanplayer_acceleration"); // acceleration + + // bound angles to the specified limit + accel_x = bound(-cvar("g_leanplayer_acceleration_max"), accel_x, cvar("g_leanplayer_acceleration_max")); + accel_y = bound(-cvar("g_leanplayer_acceleration_max"), accel_y, cvar("g_leanplayer_acceleration_max")); + accel_z = bound(-cvar("g_leanplayer_acceleration_max"), accel_z, cvar("g_leanplayer_acceleration_max")); + + L0_x = vlen(accel); + L0_y = L1_y = vectoyaw(accel); + + L0 = AnglesTransform_FromAngles(L0); + L1 = AnglesTransform_FromAngles(L1); + LF = AnglesTransform_Multiply(AnglesTransform_Invert(L1), L0); + LA = AnglesTransform_Multiply(LA, LF); + // end of acceleration leaning + + // damage leaning + L0 = vectoangles(self.leanangle_damage_loc); + L1 = vectoangles(self.leanangle_damage_loc + self.leanangle_damage_force); + + L0 = AnglesTransform_FromAngles(L0); + L1 = AnglesTransform_FromAngles(L1); + LF = AnglesTransform_Multiply(AnglesTransform_Invert(L1), L0); + + LA = AnglesTransform_Multiply(LA, LF); + + // fade the player back to normal rotation each frame + if(self.leanangle_damage_force) // safety + self.leanangle_damage_force = self.leanangle_damage_force * cvar("g_leanplayer_damage_fade"); + // end of damage leaning + + self.angles = AnglesTransform_Normalize(AnglesTransform_ToAngles(LA), TRUE); + } + + SetPlayerSize(); + + if(frametime) + { if(self.health <= 0 && cvar("g_deathglow")) { if(self.glowmod_x > 0) @@ -2683,8 +2759,6 @@ void PlayerPreThink (void) } } - SetPlayerSize(); - FixPlayermodel(); GrabberFrame();