X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fserver%2Fcl_client.qc;h=fda3e902fa31649e8746faeaee0892a201755590;hp=ef83ef63543c7dc1a77c1633be408fb5ba45a0c1;hb=4c1fcf7b3bdaee8fd10d48d2ac5b21c3a9371de1;hpb=9301604b1b5894e57227d32785b9a9460e9a3f51 diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index ef83ef635..76f81c8d7 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -6,6 +6,13 @@ void send_CSQC_teamnagger() { 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, cvar("g_balance_campingrifle_magazinecapacity")); +} + void Announce(string snd) { WriteByte(MSG_ALL, SVC_TEMPENTITY); WriteByte(MSG_ALL, TE_CSQC_ANNOUNCE); @@ -398,8 +405,15 @@ Checks if the argument string can be a valid playermodel. Returns a valid one in doubt. ============= */ -string FallbackPlayerModel = "models/player/marine.zym"; +string FallbackPlayerModel; string CheckPlayerModel(string plyermodel) { + if(FallbackPlayerModel != cvar_defstring("_cl_playermodel")) + { + // note: we cannot summon Don Strunzone here, some player may + // still have the model string set. In case anyone manages how + // to change a cvar default, we'll have a small leak here. + FallbackPlayerModel = strzone(cvar_defstring("_cl_playermodel")); + } if(strlen(plyermodel) < 4) return FallbackPlayerModel; if( substring(plyermodel,0,14) != "models/player/") @@ -508,7 +522,6 @@ float Client_customizeentityforclient() return TRUE; } -void UpdatePlayerSounds(); void setmodel_lod(entity e, string modelname) { string s; @@ -860,10 +873,11 @@ void PutClientInServer (void) self.iscreature = TRUE; self.movetype = MOVETYPE_WALK; self.solid = SOLID_SLIDEBOX; + self.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_SOLID; if(cvar("g_playerclip_collisions")) - self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP; - else - self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY; + self.dphitcontentsmask |= DPCONTENTS_PLAYERCLIP; + if(clienttype(self) == CLIENTTYPE_BOT && cvar("g_botclip_collisions")) + self.dphitcontentsmask |= DPCONTENTS_BOTCLIP; self.frags = FRAGS_PLAYER; if(independent_players) MAKE_INDEPENDENT_PLAYER(self); @@ -875,6 +889,8 @@ void PutClientInServer (void) self.effects = 0; self.air_finished = time + 12; self.dmg = 2; + if(cvar("g_balance_nex_charge")) + self.nex_charge = cvar("g_balance_nex_charge_start"); if(inWarmupStage) { @@ -933,6 +949,7 @@ void PutClientInServer (void) self.nextthink = 0; self.hook_time = 0; self.dmg_team = 0; + self.ballistics_density = cvar("g_ballistics_density_player"); self.metertime = 0; @@ -1056,22 +1073,69 @@ float ClientInit_SendEntity(entity to, float sf) { WriteByte(MSG_ENTITY, ENT_CLIENT_INIT); WriteByte(MSG_ENTITY, g_nexball_meter_period * 32); - WriteCoord(MSG_ENTITY, hook_shotorigin_x); - WriteCoord(MSG_ENTITY, hook_shotorigin_y); - WriteCoord(MSG_ENTITY, hook_shotorigin_z); - + WriteInt24_t(MSG_ENTITY, compressShotOrigin(hook_shotorigin[0])); + WriteInt24_t(MSG_ENTITY, compressShotOrigin(hook_shotorigin[1])); + WriteInt24_t(MSG_ENTITY, compressShotOrigin(hook_shotorigin[2])); + WriteInt24_t(MSG_ENTITY, compressShotOrigin(hook_shotorigin[3])); + WriteInt24_t(MSG_ENTITY, compressShotOrigin(electro_shotorigin[0])); + WriteInt24_t(MSG_ENTITY, compressShotOrigin(electro_shotorigin[1])); + WriteInt24_t(MSG_ENTITY, compressShotOrigin(electro_shotorigin[2])); + WriteInt24_t(MSG_ENTITY, compressShotOrigin(electro_shotorigin[3])); + WriteInt24_t(MSG_ENTITY, compressShotOrigin(gauntlet_shotorigin[0])); + WriteInt24_t(MSG_ENTITY, compressShotOrigin(gauntlet_shotorigin[1])); + WriteInt24_t(MSG_ENTITY, compressShotOrigin(gauntlet_shotorigin[2])); + WriteInt24_t(MSG_ENTITY, compressShotOrigin(gauntlet_shotorigin[3])); if(sv_foginterval && world.fog != "") WriteString(MSG_ENTITY, world.fog); else WriteString(MSG_ENTITY, ""); - WriteByte(MSG_ENTITY, cvar("g_balance_armor_blockpercent") * 255.0); - WriteByte(MSG_ENTITY, cvar("g_balance_weaponswitchdelay") * 255.0); + WriteByte(MSG_ENTITY, self.count * 255.0); // g_balance_armor_blockpercent + WriteByte(MSG_ENTITY, self.cnt * 255.0); // g_balance_weaponswitchdelay + WriteCoord(MSG_ENTITY, self.bouncefactor); // g_balance_grenadelauncher_secondary_bouncefactor + WriteCoord(MSG_ENTITY, self.bouncestop); // g_balance_grenadelauncher_secondary_bouncestop + WriteByte(MSG_ENTITY, cvar("g_balance_nex_secondary")); // client has to know if it should zoom or not + WriteByte(MSG_ENTITY, cvar("g_balance_campingrifle_secondary")); // client has to know if it should zoom or not return TRUE; } +void ClientInit_CheckUpdate() +{ + self.nextthink = time; + if(self.count != cvar("g_balance_armor_blockpercent")) + { + self.count = cvar("g_balance_armor_blockpercent"); + self.SendFlags |= 1; + } + if(self.cnt != cvar("g_balance_weaponswitchdelay")) + { + self.cnt = cvar("g_balance_weaponswitchdelay"); + self.SendFlags |= 1; + } + if(self.bouncefactor != cvar("g_balance_grenadelauncher_secondary_bouncefactor")) + { + self.bouncefactor = cvar("g_balance_grenadelauncher_secondary_bouncefactor"); + self.SendFlags |= 1; + } + if(self.bouncestop != cvar("g_balance_grenadelauncher_secondary_bouncestop")) + { + self.bouncestop = cvar("g_balance_grenadelauncher_secondary_bouncestop"); + self.SendFlags |= 1; + } +} + void ClientInit_Spawn() { - Net_LinkEntity(spawn(), FALSE, 0, ClientInit_SendEntity); + entity o; + entity e; + e = spawn(); + e.classname = "clientinit"; + e.think = ClientInit_CheckUpdate; + Net_LinkEntity(e, FALSE, 0, ClientInit_SendEntity); + + o = self; + self = e; + ClientInit_CheckUpdate(); + self = o; } /* @@ -1241,7 +1305,28 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto void ClientKill (void) { - ClientKill_TeamChange(0); + if((g_arena || g_ca) && ((champion && champion.classname == "player" && player_count > 1) || player_count == 1)) // don't allow a kill in this case either + { + // do nothing + } + else + ClientKill_TeamChange(0); +} + +void CTS_ClientKill_Think (void) +{ + 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; } void DoTeamChange(float destteam) @@ -1300,8 +1385,9 @@ void FixClientCvars(entity e) if(g_race || g_cts) stuffcmd(e, "cl_cmd settemp cl_movecliptokeyboard 2\n"); if(cvar("g_antilag") == 3) // client side hitscan - //stuffcmd(e, "cl_cmd settemp cl_prydoncursor -1\ncl_cmd settemp cl_prydoncursor_notrace 0\n"); stuffcmd(e, "cl_cmd settemp cl_prydoncursor_notrace 0\n"); + if(sv_gentle) + stuffcmd(e, "cl_cmd settemp cl_gentle 1\n"); /* * we no longer need to stuff this. Remove this comment block if you feel * 2.3 and higher (or was it 2.2.3?) don't need these any more @@ -1332,10 +1418,6 @@ Called when a client connects to the server string ColoredTeamName(float t); void DecodeLevelParms (void); //void dom_player_join_team(entity pl); -#ifdef UID -.float uid_kicktime; -.string uid; -#endif void ClientConnect (void) { float t; @@ -1351,6 +1433,10 @@ void ClientConnect (void) DecodeLevelParms(); +#ifdef WATERMARK + sprint(self, strcat("^4SVQC Build information: ", WATERMARK(), "\n")); +#endif + self.classname = "player_joining"; self.flags = FL_CLIENT; @@ -1509,12 +1595,6 @@ void ClientConnect (void) else self.hitplotfh = -1; -#ifdef UID - if(clienttype(self) == CLIENTTYPE_REAL) - if not(self.uid) - self.uid_kicktime = time + 60; -#endif - if(g_race || g_cts) { string rr; if(g_cts) @@ -1523,11 +1603,12 @@ void ClientConnect (void) rr = RACE_RECORD; t = stof(db_get(ServerProgsDB, strcat(GetMapname(), rr, "time"))); + msg_entity = self; race_send_recordtime(MSG_ONE); race_send_speedaward(MSG_ONE); speedaward_alltimebest = stof(db_get(ServerProgsDB, strcat(GetMapname(), rr, "speed/speed"))); - speedaward_alltimebest_holder = db_get(ServerProgsDB, strcat(GetMapname(), rr, "speed/netname")); + speedaward_alltimebest_holder = uid2name(db_get(ServerProgsDB, strcat(GetMapname(), rr, "speed/crypto_idfp"))); race_send_speedaward_alltimebest(MSG_ONE); float i; @@ -1535,9 +1616,11 @@ void ClientConnect (void) race_SendRankings(i, 0, 0, MSG_ONE); } } - else if(cvar("sv_teamnagger") && !g_ca) // teamnagger is currently bad for ca + else if(cvar("sv_teamnagger") && !(cvar("bot_vs_human") && (c3==-1 && c4==-1)) && !g_ca) // teamnagger is currently bad for ca send_CSQC_teamnagger(); + send_CSQC_cr_maxbullets(self); + CheatInitClient(); } @@ -1748,10 +1831,31 @@ void UpdateTeamBubble() else self.colormod = '1 1 1'; };*/ +.float oldcolormap; void respawn(void) { + if(self.modelindex != 0 && cvar("g_respawn_ghosts")) + { + self.solid = SOLID_NOT; + self.takedamage = DAMAGE_NO; + self.movetype = MOVETYPE_FLY; + self.velocity = '0 0 1' * cvar("g_respawn_ghosts_speed"); + self.avelocity = randomvec() * cvar("g_respawn_ghosts_speed") * 3 - randomvec() * cvar("g_respawn_ghosts_speed") * 3; + self.effects |= EF_ADDITIVE; + self.oldcolormap = self.colormap; + self.colormap = 512; + pointparticles(particleeffectnum("respawn_ghost"), self.origin, '0 0 0', 1); + if(cvar("g_respawn_ghosts_maxtime")) + SUB_SetFade (self, time + cvar("g_respawn_ghosts_maxtime") / 2 + random () * (cvar("g_respawn_ghosts_maxtime") - cvar("g_respawn_ghosts_maxtime") / 2), 1.5); + } + CopyBody(1); self.effects |= EF_NODRAW; // prevent another CopyBody + if(self.oldcolormap) + { + self.colormap = self.oldcolormap; + self.oldcolormap = 0; + } PutClientInServer(); } @@ -2458,9 +2562,9 @@ void PlayerPreThink (void) if(self.cvar_g_xonoticversion) if(time > self.version_nagtime) { - if(strstr(self.cvar_g_xonoticversion, "svn", 0) < 0) + if(strstr(self.cvar_g_xonoticversion, "git", 0) < 0) { - if(strstr(cvar_string("g_xonoticversion"), "svn", 0) >= 0) + if(strstr(cvar_string("g_xonoticversion"), "git", 0) >= 0) { dprint("^1NOTE^7 to ", self.netname, "^7 - the server is running ^3Xonotic ", cvar_string("g_xonoticversion"), " (beta)^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n"); sprint(self, strcat("\{1}^1NOTE: ^7the server is running ^3Xonotic ", cvar_string("g_xonoticversion"), " (beta)^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n")); @@ -2531,7 +2635,23 @@ void PlayerPreThink (void) if(frametime) { - self.glowmod = colormapPaletteColor(self.clientcolors & 0x0F, TRUE) * 2; + if(self.health <= 0 && cvar("g_deathglow")) + { + if(self.glowmod_x > 0) + self.glowmod_x -= cvar("g_deathglow") * frametime; + else + self.glowmod_x = -1; + if(self.glowmod_y > 0) + self.glowmod_y -= cvar("g_deathglow") * frametime; + else + self.glowmod_y = -1; + if(self.glowmod_z > 0) + self.glowmod_z -= cvar("g_deathglow") * frametime; + else + self.glowmod_z = -1; + } + else + self.glowmod = colormapPaletteColor(self.clientcolors & 0x0F, TRUE) * 2; player_powerups(); } @@ -2591,7 +2711,6 @@ void PlayerPreThink (void) FOR_EACH_PLAYER(other) if(self != other) { if(time > other.touchexplode_time) - if(other.classname == "player") if(other.deadflag == DEAD_NO) if not(IS_INDEPENDENT_PLAYER(other)) if(boxesoverlap(self.absmin, self.absmax, other.absmin, other.absmax)) @@ -2709,7 +2828,7 @@ void PlayerPreThink (void) } if(!zoomstate_set) - SetZoomState(self.BUTTON_ZOOM || (self.BUTTON_ATCK2 && self.weapon == WEP_NEX)); + SetZoomState(self.BUTTON_ZOOM || (self.BUTTON_ATCK2 && self.weapon == WEP_NEX) || (self.BUTTON_ATCK2 && self.weapon == WEP_CAMPINGRIFLE && cvar("g_balance_campingrifle_secondary") == 0)); float oldspectatee_status; oldspectatee_status = self.spectatee_status; @@ -2762,9 +2881,16 @@ float isInvisibleString(string s) switch(c) { case 0: - case 32: - case 160: + case 32: // space break; + case 192: // charmap space + if (!cvar("utf8_enable")) + break; + return FALSE; + case 160: // space in unicode fonts + case 0xE000 + 192: // utf8 charmap space + if (cvar("utf8_enable")) + break; default: return FALSE; } @@ -2780,6 +2906,18 @@ Called every frame for each client after the physics are run ============= */ .float idlekick_lasttimeleft; +.entity showheadshotbbox; +void showheadshotbbox_think() +{ + if(self.owner.showheadshotbbox != self) + { + remove(self); + return; + } + self.nextthink = time; + setorigin(self, self.owner.origin); + setsize(self, GetHeadshotMins(self.owner), GetHeadshotMaxs(self.owner)); +} void PlayerPostThink (void) { // Savage: Check for nameless players @@ -2797,16 +2935,6 @@ void PlayerPostThink (void) self.stat_count -= 1; } -#ifdef UID - if(self.uid_kicktime) - if(time > self.uid_kicktime) - { - bprint("^3", self.netname, "^3 was kicked for missing UID.\n"); - dropclient(self); - return; - } -#endif - if(sv_maxidle && frametime) { // WORKAROUND: only use dropclient in server frames (frametime set). Never use it in cl_movement frames (frametime zero). @@ -2881,8 +3009,40 @@ void PlayerPostThink (void) if(self.waypointsprite_attachedforcarrier) WaypointSprite_UpdateHealth(self.waypointsprite_attachedforcarrier, '1 0 0' * healtharmor_maxdamage(self.health, self.armorvalue, cvar("g_balance_armor_blockpercent"))); + if(self.classname == "player" && self.deadflag == DEAD_NO && cvar("r_showbboxes")) + { + if(!self.showheadshotbbox) + { + self.showheadshotbbox = spawn(); + self.showheadshotbbox.classname = "headshotbbox"; + self.showheadshotbbox.owner = self; + self.showheadshotbbox.think = showheadshotbbox_think; + self.showheadshotbbox.nextthink = time; + self = self.showheadshotbbox; + self.think(); + self = self.owner; + } + } + else + { + if(self.showheadshotbbox) + remove(self.showheadshotbbox); + } + playerdemo_write(); + if((g_cts || g_race) && self.cvar_cl_allow_uid2name) + { + if(!self.stored_netname) + self.stored_netname = strzone(uid2name(self.crypto_idfp)); + if(self.stored_netname != self.netname) + { + db_put(ServerProgsDB, strcat("uid2name", self.crypto_idfp), self.netname); + strunzone(self.stored_netname); + self.stored_netname = strzone(self.netname); + } + } + /* if(g_race) dprint(sprintf("%f %.6f\n", time, race_GetFractionalLapCount(self)));