X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fcl_client.qc;h=e943c94a4d82b9ea98d108f0c93e9026d7ddf8b6;hb=624f5e6b91ebc9891fb764ea8d0ab49638b6936b;hp=5ff519bd70695e15627a7680d7342b2ef9f441d7;hpb=57c5dfd12fc3f7ce7b2bc844325a2c85929f10de;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index 5ff519bd7..e943c94a4 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -2,15 +2,8 @@ void race_send_recordtime(float msg); void race_SendRankings(float pos, float prevpos, float del, float msg); void send_CSQC_teamnagger() { - WriteByte(0, SVC_TEMPENTITY); - WriteByte(0, TE_CSQC_TEAMNAGGER); -} - -void send_CSQC_cr_maxbullets(entity e) { - msg_entity = e; - WriteByte(MSG_ONE, SVC_TEMPENTITY); - WriteByte(MSG_ONE, TE_CSQC_CR_MAXBULLETS); - WriteByte(MSG_ONE, autocvar_g_balance_campingrifle_magazinecapacity); + WriteByte(MSG_BROADCAST, SVC_TEMPENTITY); + WriteByte(MSG_BROADCAST, TE_CSQC_TEAMNAGGER); } void Announce(string snd) { @@ -724,15 +717,6 @@ void PutObserverInServer (void) self.frags = FRAGS_SPECTATOR; } -float RestrictSkin(float s) -{ - if(!teams_matter) - return s; - if(s == 6) - return 6; - return mod(s, 3); -} - void FixPlayermodel() { local string defaultmodel; @@ -794,7 +778,7 @@ void FixPlayermodel() } oldskin = self.skinindex; - self.skinindex = RestrictSkin(stof(self.playerskin)); + self.skinindex = stof(self.playerskin); } if(chmdl || oldskin != self.skinindex) @@ -905,6 +889,23 @@ void PutClientInServer (void) self.nex_charge = autocvar_g_balance_nex_charge_start; } + // all weapons must be fully loaded the first time we pick them up, so set their load to maximum at respawn + self.laser_load = autocvar_g_balance_laser_reload_ammo; + self.shotgun_load = autocvar_g_balance_shotgun_reload_ammo; + self.uzi_load = autocvar_g_balance_uzi_reload_ammo; + self.grenadelauncher_load = autocvar_g_balance_grenadelauncher_reload_ammo; + self.minelayer_load = autocvar_g_balance_minelayer_reload_ammo; + self.electro_load = autocvar_g_balance_electro_reload_ammo; + self.crylink_load = autocvar_g_balance_crylink_reload_ammo; + self.hlac_load = autocvar_g_balance_hlac_reload_ammo; + self.nex_load = autocvar_g_balance_nex_reload_ammo; + self.minstanex_load = autocvar_g_balance_minstanex_reload_ammo; + self.sniperrifle_load = autocvar_g_balance_sniperrifle_reload_ammo; + self.seeker_load = autocvar_g_balance_seeker_reload_ammo; + self.hagar_load = autocvar_g_balance_hagar_reload_ammo; + self.fireball_load = autocvar_g_balance_fireball_reload_ammo; + self.rocketlauncher_load = autocvar_g_balance_rocketlauncher_reload_ammo; + if(inWarmupStage) { self.ammo_shells = warmup_start_ammo_shells; @@ -1121,8 +1122,9 @@ float ClientInit_SendEntity(entity to, float sf) WriteCoord(MSG_ENTITY, self.ebouncefactor); // g_balance_grenadelauncher_bouncefactor WriteCoord(MSG_ENTITY, self.ebouncestop); // g_balance_grenadelauncher_bouncestop WriteByte(MSG_ENTITY, autocvar_g_balance_nex_secondary); // client has to know if it should zoom or not - WriteByte(MSG_ENTITY, autocvar_g_balance_campingrifle_secondary); // client has to know if it should zoom or not + WriteByte(MSG_ENTITY, autocvar_g_balance_sniperrifle_secondary); // client has to know if it should zoom or not WriteByte(MSG_ENTITY, serverflags); // client has to know if it should zoom or not + WriteCoord(MSG_ENTITY, autocvar_g_trueaim_minrange); return TRUE; } @@ -1222,6 +1224,7 @@ Called when a client types 'kill' in the console ============= */ +.float clientkill_nexttime; void ClientKill_Now_TeamChange() { if(self.killindicator_teamchange == -1) @@ -1229,24 +1232,30 @@ void ClientKill_Now_TeamChange() self.team = -1; JoinBestTeam( self, FALSE, FALSE ); } + else if(self.killindicator_teamchange == -2) + { + if(g_ca) + self.caplayer = 0; + if(blockSpectators) + sprint(self, strcat("^7You have to become a player within the next ", ftos(autocvar_g_maxplayers_spectator_blocktime), " seconds, otherwise you will be kicked, because spectators aren't allowed at this time!\n")); + PutObserverInServer(); + } else SV_ChangeTeam(self.killindicator_teamchange - 1); } void ClientKill_Now() { + remove(self.killindicator); + self.killindicator = world; + if(self.killindicator_teamchange) ClientKill_Now_TeamChange(); // in any case: Damage(self, self, self, 100000, DEATH_KILL, self.origin, '0 0 0'); - if(self.killindicator) - { - dprint("Cleaned up after a leaked kill indicator.\n"); - remove(self.killindicator); - self.killindicator = world; - } + // now I am sure the player IS dead } void KillIndicator_Think() { @@ -1263,6 +1272,11 @@ void KillIndicator_Think() ClientKill_Now(); // no oldself needed return; } + else if(g_cts && self.health == 1) // health == 1 means that it's silent + { + self.nextthink = time + 1; + self.cnt -= 1; + } else { if(self.cnt <= 10) @@ -1275,6 +1289,8 @@ void KillIndicator_Think() { if(self.owner.killindicator_teamchange == -1) centerprint(self.owner, strcat("Changing team in ", ftos(self.cnt), " seconds")); + else if(self.owner.killindicator_teamchange == -2) + centerprint(self.owner, strcat("Spectating in ", ftos(self.cnt), " seconds")); else centerprint(self.owner, strcat("Changing to ", ColoredTeamName(self.owner.killindicator_teamchange), " in ", ftos(self.cnt), " seconds")); } @@ -1286,19 +1302,34 @@ void KillIndicator_Think() } } -void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto +void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto, -2 = spec { float killtime; entity e; killtime = autocvar_g_balance_kill_delay; - if(g_race_qualifying) + if(g_race_qualifying || g_cts) killtime = 0; + if(g_cts && self.killindicator && self.killindicator.health == 1) // self.killindicator.health == 1 means that the kill indicator was spawned by CTS_ClientKill + { + remove(self.killindicator); + self.killindicator = world; + + ClientKill_Now(); // allow instant kill in this case + return; + } + self.killindicator_teamchange = targetteam; - if(!self.killindicator) + if(!self.killindicator) { + if(self.modelindex && self.deadflag == DEAD_NO) + { + killtime = max(killtime, self.clientkill_nexttime - time); + self.clientkill_nexttime = time + killtime + autocvar_g_balance_kill_antispam; + } + if(killtime <= 0 || !self.modelindex || self.deadflag != DEAD_NO) { ClientKill_Now(); @@ -1314,7 +1345,7 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto self.killindicator.nextthink = time + (self.lip) * 0.05; self.killindicator.cnt = ceil(killtime); self.killindicator.count = bound(0, ceil(killtime), 10); - sprint(self, strcat("^1You'll be dead in ", ftos(self.killindicator.cnt), " seconds\n")); + //sprint(self, strcat("^1You'll be dead in ", ftos(self.killindicator.cnt), " seconds\n")); for(e = world; (e = find(e, classname, "body")) != world; ) { @@ -1334,10 +1365,14 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto } if(self.killindicator) { - if(targetteam) - self.killindicator.colormod = TeamColor(targetteam); - else + if(targetteam == 0) // just die self.killindicator.colormod = '0 0 0'; + else if(targetteam == -1) // auto + self.killindicator.colormod = '0 1 0'; + else if(targetteam == -2) // spectate + self.killindicator.colormod = '0.5 0.5 0.5'; + else + self.killindicator.colormod = TeamColor(targetteam); } } @@ -1347,7 +1382,7 @@ void ClientKill (void) { // do nothing } - else if(g_freezetag && self.freezetag_frozen == 1) + else if(self.freezetag_frozen) { // do nothing } @@ -1355,20 +1390,15 @@ void ClientKill (void) ClientKill_TeamChange(0); } -void CTS_ClientKill_Think (void) +void CTS_ClientKill (entity e) // silent version of ClientKill, used when player finishes a CTS run. Useful to prevent cheating by running back to the start line and starting out with more speed { - self = self.owner; // set self to the player to be killed - sprint(self, "^1You were killed in order to prevent cheating!"); - ClientKill_Now(); -} - -void CTS_ClientKill (float t) // silent version of ClientKill -{ - entity e; - e = spawn(); - e.owner = self; - e.think = CTS_ClientKill_Think; - e.nextthink = t; + e.killindicator = spawn(); + e.killindicator.owner = e; + e.killindicator.think = KillIndicator_Think; + e.killindicator.nextthink = time + (e.lip) * 0.05; + e.killindicator.cnt = ceil(autocvar_g_cts_finish_kill_delay); + e.killindicator.health = 1; // this is used to indicate that it should be silent + e.lip = 0; } void DoTeamChange(float destteam) @@ -1722,8 +1752,6 @@ void ClientConnect (void) else if(autocvar_sv_teamnagger && !(autocvar_bot_vs_human && (c3==-1 && c4==-1)) && !g_ca) // teamnagger is currently bad for ca send_CSQC_teamnagger(); - send_CSQC_cr_maxbullets(self); - CheatInitClient(); PlayerStats_AddPlayer(self); @@ -2029,7 +2057,7 @@ void player_powerups (void) self.modelflags &~= MF_ROCKET; } - self.effects &~= (EF_RED | EF_BLUE | EF_ADDITIVE | EF_FULLBRIGHT | EF_FLAME | EF_NODEPTHTEST); + self.effects &~= (EF_DIMLIGHT | EF_RED | EF_BLUE | EF_ADDITIVE | EF_FULLBRIGHT | EF_FLAME | EF_NODEPTHTEST); if(!self.modelindex || self.deadflag) // don't apply the flags if the player is gibbed return; @@ -2718,7 +2746,7 @@ void PlayerPreThink (void) if(frametime) player_anim(); button_pressed = (self.BUTTON_ATCK || self.BUTTON_JUMP || self.BUTTON_ATCK2 || self.BUTTON_HOOK || self.BUTTON_USE); - force_respawn = (g_lms || (g_ca) || autocvar_g_forced_respawn); + force_respawn = (g_lms || g_ca || g_cts || autocvar_g_forced_respawn); if (self.deadflag == DEAD_DYING) { if(force_respawn) @@ -2882,7 +2910,7 @@ void PlayerPreThink (void) } if(!zoomstate_set) - SetZoomState(self.BUTTON_ZOOM || (self.BUTTON_ATCK2 && self.weapon == WEP_NEX) || (self.BUTTON_ATCK2 && self.weapon == WEP_CAMPINGRIFLE && autocvar_g_balance_campingrifle_secondary == 0)); + SetZoomState(self.BUTTON_ZOOM || (self.BUTTON_ATCK2 && self.weapon == WEP_NEX) || (self.BUTTON_ATCK2 && self.weapon == WEP_SNIPERRIFLE && autocvar_g_balance_sniperrifle_secondary == 0)); float oldspectatee_status; oldspectatee_status = self.spectatee_status; @@ -2923,6 +2951,10 @@ void PlayerPreThink (void) } target_voicescript_next(self); + + // if a player goes unarmed after holding a loaded weapon, empty his clip size and remove the crosshair ammo ring + if(!self.weapon) + self.clip_load = self.clip_size = 0; } float isInvisibleString(string s)