X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fcl_player.qc;h=67738c4c6c0d28fb4c59a960203330356dd1567a;hb=c1ca8fe324d3d3a5facbdc70857eaa4b3be88ece;hp=04ac977f433be4bcc63bf8d41e29cc95f8c0c2eb;hpb=d1d799c4320d9ea36e9657fdaa9f980e22750fa8;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/cl_player.qc b/qcsrc/server/cl_player.qc index 04ac977f4..67738c4c6 100644 --- a/qcsrc/server/cl_player.qc +++ b/qcsrc/server/cl_player.qc @@ -155,6 +155,7 @@ void CopyBody(float keepvelocity) self.teleportable = oldself.teleportable; self.damagedbycontents = oldself.damagedbycontents; self.angles = oldself.angles; + self.v_angle = oldself.v_angle; self.avelocity = oldself.avelocity; self.classname = "body"; self.damageforcescale = oldself.damageforcescale; @@ -245,7 +246,7 @@ void player_anim (void) else deadbits = ANIMSTATE_DEAD2; float animbits = deadbits; - if(self.frozen) + if(self.freezetag_frozen) animbits |= ANIMSTATE_FROZEN; if(self.crouch) animbits |= ANIMSTATE_DUCK; @@ -262,22 +263,9 @@ void player_anim (void) void SpawnThrownWeapon (vector org, float w) { - if(g_pinata) - { - float j; - for(j = WEP_FIRST; j <= WEP_LAST; ++j) - { - if(WEPSET_CONTAINS_EW(self, j)) - if(W_IsWeaponThrowable(j)) - W_ThrowNewWeapon(self, j, FALSE, org, randomvec() * 175 + '0 0 325'); - } - } - else - { - if(WEPSET_CONTAINS_EW(self, self.weapon)) - if(W_IsWeaponThrowable(self.weapon)) - W_ThrowNewWeapon(self, self.weapon, FALSE, org, randomvec() * 125 + '0 0 200'); - } + if(self.weapons & WepSet_FromWeapon(self.weapon)) + if(W_IsWeaponThrowable(self.weapon)) + W_ThrowNewWeapon(self, self.weapon, FALSE, org, randomvec() * 125 + '0 0 200'); } void PlayerCorpseDamage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) @@ -289,18 +277,18 @@ void PlayerCorpseDamage (entity inflictor, entity attacker, float damage, float // damage resistance (ignore most of the damage from a bullet or similar) damage = max(damage - 5, 1); - v = healtharmor_applydamage(self.armorvalue, autocvar_g_balance_armor_blockpercent, damage); + v = healtharmor_applydamage(self.armorvalue, autocvar_g_balance_armor_blockpercent, deathtype, damage); take = v_x; save = v_y; if(sound_allowed(MSG_BROADCAST, attacker)) { if (save > 10) - sound (self, CH_SHOTS, "misc/armorimpact.wav", VOL_BASE, ATTN_NORM); + sound (self, CH_SHOTS, "misc/armorimpact.wav", VOL_BASE, ATTEN_NORM); else if (take > 30) - sound (self, CH_SHOTS, "misc/bodyimpact2.wav", VOL_BASE, ATTN_NORM); + sound (self, CH_SHOTS, "misc/bodyimpact2.wav", VOL_BASE, ATTEN_NORM); else if (take > 10) - sound (self, CH_SHOTS, "misc/bodyimpact1.wav", VOL_BASE, ATTN_NORM); + sound (self, CH_SHOTS, "misc/bodyimpact1.wav", VOL_BASE, ATTEN_NORM); } if (take > 50) @@ -334,11 +322,107 @@ void PlayerCorpseDamage (entity inflictor, entity attacker, float damage, float } } +// g__str: +// If 0, default is used. +// If <0, 0 is used. +// Otherwise, g_str (default value) is used. +// For consistency, negative values there are mapped to zero too. +#define GAMETYPE_DEFAULTED_SETTING(str) \ + ((gametype_setting_tmp = cvar(strcat("g_", GetGametype(), "_" #str))), \ + (gametype_setting_tmp < 0) ? 0 : \ + (gametype_setting_tmp == 0) ? max(0, autocvar_g_##str) : \ + gametype_setting_tmp) + + +void calculate_player_respawn_time() +{ + float gametype_setting_tmp; + float sdelay_max = GAMETYPE_DEFAULTED_SETTING(respawn_delay_max); + float sdelay_small = GAMETYPE_DEFAULTED_SETTING(respawn_delay_small); + float sdelay_large = GAMETYPE_DEFAULTED_SETTING(respawn_delay_large); + float sdelay_small_count = GAMETYPE_DEFAULTED_SETTING(respawn_delay_small_count); + float sdelay_large_count = GAMETYPE_DEFAULTED_SETTING(respawn_delay_large_count); + float waves = GAMETYPE_DEFAULTED_SETTING(respawn_waves); + + float pcount = 1; // Include myself whether or not team is already set right and I'm a "player". + entity pl; + if (teamplay) + { + FOR_EACH_PLAYER(pl) + if (pl != self) + if (pl.team == self.team) + ++pcount; + if (sdelay_small_count == 0) + sdelay_small_count = 1; + if (sdelay_large_count == 0) + sdelay_large_count = 1; + } + else + { + FOR_EACH_PLAYER(pl) + if (pl != self) + ++pcount; + if (sdelay_small_count == 0) + { + if (g_cts) + { + // Players play independently. No point in requiring enemies. + sdelay_small_count = 1; + } + else + { + // Players play AGAINST each other. Enemies required. + sdelay_small_count = 2; + } + } + if (sdelay_large_count == 0) + { + if (g_cts) + { + // Players play independently. No point in requiring enemies. + sdelay_large_count = 1; + } + else + { + // Players play AGAINST each other. Enemies required. + sdelay_large_count = 2; + } + } + } + + float sdelay; + + if (pcount <= sdelay_small_count) + sdelay = sdelay_small; + else if (pcount >= sdelay_large_count) + sdelay = sdelay_large; + else // NOTE: this case implies sdelay_large_count > sdelay_small_count. + sdelay = sdelay_small + (sdelay_large - sdelay_small) * (pcount - sdelay_small_count) / (sdelay_large_count - sdelay_small_count); + + if(waves) + self.respawn_time = ceil((time + sdelay) / waves) * waves; + else + self.respawn_time = time + sdelay; + + if(sdelay < sdelay_max) + self.respawn_time_max = time + sdelay_max; + else + self.respawn_time_max = self.respawn_time; + + if((sdelay + waves >= 5.0) && (self.respawn_time - time > 1.75)) + self.respawn_countdown = 10; // first number to count down from is 10 + else + self.respawn_countdown = -1; // do not count down + + if(g_cts || autocvar_g_forced_respawn) + self.respawn_flags = self.respawn_flags | RESPAWN_FORCE; +} + void ClientKill_Now_TeamChange(); void PlayerDamage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) { - float take, save, waves, sdelay, dh, da, j; + float take, save, dh, da, j; vector v; float valid_damage_for_weaponstats; float excess; @@ -366,7 +450,10 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht ear1 += v_right * -10; ear2 += v_right * +10; d = inflictor.origin - self.origin; - f = (d * v_right) / vlen(d); // this is cos of angle of d and v_right! + if (d) + f = (d * v_right) / vlen(d); // this is cos of angle of d and v_right! + else + f = 0; // Assum ecenter. force = v_right * vlen(force); Violence_GibSplash_At(ear1, force * -1, 2, bound(0, damage, 25) / 2 * (0.5 - 0.5 * f), self, attacker); Violence_GibSplash_At(ear2, force, 2, bound(0, damage, 25) / 2 * (0.5 + 0.5 * f), self, attacker); @@ -385,7 +472,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht Violence_GibSplash_At(hitloc, force, 2, bound(0, damage, 200) / 16, self, attacker); - v = healtharmor_applydamage(self.armorvalue, autocvar_g_balance_armor_blockpercent, damage); + v = healtharmor_applydamage(self.armorvalue, autocvar_g_balance_armor_blockpercent, deathtype, damage); take = v_x; save = v_y; @@ -428,11 +515,11 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht if(sound_allowed(MSG_BROADCAST, attacker)) { if (save > 10) - sound (self, CH_SHOTS, "misc/armorimpact.wav", VOL_BASE, ATTN_NORM); + sound (self, CH_SHOTS, "misc/armorimpact.wav", VOL_BASE, ATTEN_NORM); else if (take > 30) - sound (self, CH_SHOTS, "misc/bodyimpact2.wav", VOL_BASE, ATTN_NORM); + sound (self, CH_SHOTS, "misc/bodyimpact2.wav", VOL_BASE, ATTEN_NORM); else if (take > 10) - sound (self, CH_SHOTS, "misc/bodyimpact1.wav", VOL_BASE, ATTN_NORM); // FIXME possibly remove them? + sound (self, CH_SHOTS, "misc/bodyimpact1.wav", VOL_BASE, ATTEN_NORM); // FIXME possibly remove them? } if (take > 50) @@ -498,9 +585,6 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht self.dmg_take = self.dmg_take + take;//max(take - 10, 0); self.dmg_inflictor = inflictor; - if(g_ca && self != attacker && IS_PLAYER(attacker)) - PlayerTeamScore_Add(attacker, SP_SCORE, ST_SCORE, (damage - excess) * autocvar_g_ca_damage2score_multiplier); - float abot, vbot, awep; abot = (IS_BOT_CLIENT(attacker)); vbot = (IS_BOT_CLIENT(self)); @@ -511,7 +595,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht if(vbot || IS_REAL_CLIENT(self)) if(abot || IS_REAL_CLIENT(attacker)) if(attacker && self != attacker) - if(IsDifferentTeam(self, attacker)) + if(DIFF_TEAM(self, attacker)) { if(DEATH_ISSPECIAL(deathtype)) awep = attacker.weapon; @@ -629,34 +713,11 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht self.solid = SOLID_CORPSE; self.ballistics_density = autocvar_g_ballistics_density_corpse; // don't stick to the floor - self.flags &~= FL_ONGROUND; + self.flags &= ~FL_ONGROUND; // dying animation self.deadflag = DEAD_DYING; // when to allow respawn - sdelay = 0; - waves = 0; - sdelay = cvar(strcat("g_", GetGametype(), "_respawn_delay")); - if(!sdelay) - { - if(g_cts) - sdelay = 0; // no respawn delay in CTS - else - sdelay = autocvar_g_respawn_delay; - } - waves = cvar(strcat("g_", GetGametype(), "_respawn_waves")); - if(!waves) - waves = autocvar_g_respawn_waves; - if(waves) - self.respawn_time = ceil((time + sdelay) / waves) * waves; - else - self.respawn_time = time + sdelay; - if((sdelay + waves >= 5.0) && (self.respawn_time - time > 1.75)) - self.respawn_countdown = 10; // first number to count down from is 10 - else - self.respawn_countdown = -1; // do not count down - - if(g_cts || autocvar_g_forced_respawn) - self.respawn_flags = self.respawn_flags | RESPAWN_FORCE; + calculate_player_respawn_time(); self.death_time = time; if (random() < 0.5) @@ -710,7 +771,7 @@ float Say(entity source, float teamsay, entity privatesay, string msgin, float f msgin = formatmessage(msgin); - if not(IS_PLAYER(source)) + if (!IS_PLAYER(source)) colorstr = "^0"; // black for spectators else if(teamplay) colorstr = Team_ColorCode(source.team); @@ -870,10 +931,10 @@ float Say(entity source, float teamsay, entity privatesay, string msgin, float f } if(!privatesay) - if not(IS_PLAYER(source)) + if (!IS_PLAYER(source)) { - if not(intermission_running) - if(teamsay || (autocvar_g_chat_nospectators == 1) || (autocvar_g_chat_nospectators == 2 && !(inWarmupStage || gameover))) + if (!intermission_running) + if(teamsay || (autocvar_g_chat_nospectators == 1) || (autocvar_g_chat_nospectators == 2 && !(warmup_stage || gameover))) teamsay = -1; // spectators } @@ -916,7 +977,7 @@ float Say(entity source, float teamsay, entity privatesay, string msgin, float f { sprint(source, sourcemsgstr); sprint(privatesay, msgstr); - if not(autocvar_g_chat_tellprivacy) { dedicated_print(msgstr); } // send to server console too if "tellprivacy" is disabled + if (!autocvar_g_chat_tellprivacy) { dedicated_print(msgstr); } // send to server console too if "tellprivacy" is disabled if(cmsgstr != "") centerprint(privatesay, cmsgstr); } @@ -938,7 +999,7 @@ float Say(entity source, float teamsay, entity privatesay, string msgin, float f { sprint(source, sourcemsgstr); dedicated_print(msgstr); // send to server console too - FOR_EACH_REALCLIENT(head) if not(IS_PLAYER(head)) + FOR_EACH_REALCLIENT(head) if (!IS_PLAYER(head)) if(head != source) sprint(head, msgstr); } @@ -1027,7 +1088,7 @@ void PrecachePlayerSounds(string f) } fclose(fh); - if not(allvoicesamples) + if (!allvoicesamples) { #define _VOICEMSG(m) allvoicesamples = strcat(allvoicesamples, " ", #m); ALLVOICEMSGS @@ -1112,15 +1173,15 @@ void FakeGlobalSound(string sample, float chan, float voicetype) { msg_entity = self; if(IS_REAL_CLIENT(msg_entity)) - soundto(MSG_ONE, self, chan, sample, VOL_BASE, ATTN_NONE); + soundto(MSG_ONE, self, chan, sample, VOL_BASE, ATTEN_NONE); } break; case VOICETYPE_TEAMRADIO: msg_entity = self; if(msg_entity.cvar_cl_voice_directional == 1) - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_MIN); + soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_MIN); else - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_NONE); + soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE); break; case VOICETYPE_AUTOTAUNT: if(!sv_autotaunt) @@ -1134,9 +1195,9 @@ void FakeGlobalSound(string sample, float chan, float voicetype) if (tauntrand < msg_entity.cvar_cl_autotaunt) { if (msg_entity.cvar_cl_voice_directional >= 1) - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, bound(ATTN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTN_MAX)); + soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, bound(ATTEN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTEN_MAX)); else - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_NONE); + soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE); } break; case VOICETYPE_TAUNT: @@ -1149,13 +1210,13 @@ void FakeGlobalSound(string sample, float chan, float voicetype) break; msg_entity = self; if (msg_entity.cvar_cl_voice_directional >= 1) - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, bound(ATTN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTN_MAX)); + soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, bound(ATTEN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTEN_MAX)); else - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_NONE); + soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE); break; case VOICETYPE_PLAYERSOUND: msg_entity = self; - soundto(MSG_ONE, self, chan, sample, VOL_BASE, ATTN_NORM); + soundto(MSG_ONE, self, chan, sample, VOL_BASE, ATTEN_NORM); break; default: backtrace("Invalid voice type!"); @@ -1187,9 +1248,9 @@ void GlobalSound(string sample, float chan, float voicetype) if(IS_REAL_CLIENT(msg_entity)) { if(msg_entity.cvar_cl_voice_directional == 1) - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_MIN); + soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_MIN); else - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_NONE); + soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE); } } break; @@ -1200,13 +1261,13 @@ void GlobalSound(string sample, float chan, float voicetype) if(IS_REAL_CLIENT(msg_entity)) { if(msg_entity.cvar_cl_voice_directional == 1) - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_MIN); + soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_MIN); else - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_NONE); + soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE); } msg_entity = self; if(IS_REAL_CLIENT(msg_entity)) - soundto(MSG_ONE, self, chan, sample, VOL_BASE, ATTN_NONE); + soundto(MSG_ONE, self, chan, sample, VOL_BASE, ATTEN_NONE); } break; case VOICETYPE_TEAMRADIO: @@ -1214,9 +1275,9 @@ void GlobalSound(string sample, float chan, float voicetype) if(!teamplay || msg_entity.team == self.team) { if(msg_entity.cvar_cl_voice_directional == 1) - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_MIN); + soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_MIN); else - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_NONE); + soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE); } break; case VOICETYPE_AUTOTAUNT: @@ -1231,9 +1292,9 @@ void GlobalSound(string sample, float chan, float voicetype) if (tauntrand < msg_entity.cvar_cl_autotaunt) { if (msg_entity.cvar_cl_voice_directional >= 1) - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, bound(ATTN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTN_MAX)); + soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, bound(ATTEN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTEN_MAX)); else - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_NONE); + soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE); } break; case VOICETYPE_TAUNT: @@ -1247,13 +1308,13 @@ void GlobalSound(string sample, float chan, float voicetype) FOR_EACH_REALCLIENT(msg_entity) { if (msg_entity.cvar_cl_voice_directional >= 1) - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, bound(ATTN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTN_MAX)); + soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, bound(ATTEN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTEN_MAX)); else - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTN_NONE); + soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE); } break; case VOICETYPE_PLAYERSOUND: - sound(self, chan, sample, VOL_BASE, ATTN_NORM); + sound(self, chan, sample, VOL_BASE, ATTEN_NORM); break; default: backtrace("Invalid voice type!");