WriteByte(0, TE_CSQC_TEAMNAGGER);
}
-void send_CSQC_nexvelocity(entity e) {
- msg_entity = e;
- WriteByte(MSG_ONE, SVC_TEMPENTITY);
- WriteByte(MSG_ONE, TE_CSQC_NEX_VELOCITY);
- WriteByte(MSG_ONE, bound(0, fabs(cvar("g_balance_nex_velocitydependent_halflife")), 1));
- WriteShort(MSG_ONE, cvar("g_balance_nex_velocitydependent_minspeed"));
- WriteShort(MSG_ONE, cvar("g_balance_nex_velocitydependent_maxspeed"));
- WriteByte(MSG_ONE, cvar("g_balance_nex_velocitydependent_falloff_rate"));
- WriteByte(MSG_ONE, cvar("g_balance_nex_secondary_charge"));
- WriteByte(MSG_ONE, cvar("g_balance_nex_secondary_charge_rate"));
-}
-
void send_CSQC_cr_maxbullets(entity e) {
msg_entity = e;
WriteByte(MSG_ONE, SVC_TEMPENTITY);
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)
{
WriteString(MSG_ENTITY, "");
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
+ WriteCoord(MSG_ENTITY, self.bouncefactor); // g_balance_grenadelauncher_bouncefactor
+ WriteCoord(MSG_ENTITY, self.bouncestop); // g_balance_grenadelauncher_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
+ WriteByte(MSG_ENTITY, serverflags); // client has to know if it should zoom or not
return TRUE;
}
self.cnt = cvar("g_balance_weaponswitchdelay");
self.SendFlags |= 1;
}
- if(self.bouncefactor != cvar("g_balance_grenadelauncher_secondary_bouncefactor"))
+ if(self.bouncefactor != cvar("g_balance_grenadelauncher_bouncefactor"))
{
- self.bouncefactor = cvar("g_balance_grenadelauncher_secondary_bouncefactor");
+ self.bouncefactor = cvar("g_balance_grenadelauncher_bouncefactor");
self.SendFlags |= 1;
}
- if(self.bouncestop != cvar("g_balance_grenadelauncher_secondary_bouncestop"))
+ if(self.bouncestop != cvar("g_balance_grenadelauncher_bouncestop"))
{
- self.bouncestop = cvar("g_balance_grenadelauncher_secondary_bouncestop");
+ self.bouncestop = cvar("g_balance_grenadelauncher_bouncestop");
self.SendFlags |= 1;
}
}
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)
*/
}
+float PlayerInIDList(entity p, string idlist)
+{
+ float n, i;
+ string s;
+
+ // NOTE: we do NOT check crypto_keyfp here, an unsigned ID is fine too for this
+ if not(p.crypto_idfp)
+ return 0;
+
+ // this function allows abbreviated player IDs too!
+ n = tokenize_console(idlist);
+ for(i = 0; i < n; ++i)
+ {
+ s = argv(i);
+ if(s == substring(p.crypto_idfp, 0, strlen(s)))
+ return 1;
+ }
+
+ return 0;
+}
+
/*
=============
ClientConnect
//if(g_domination)
// dom_player_join_team(self);
+ // identify the right forced team
+ if(PlayerInIDList(self, cvar_string("g_forced_team_red")))
+ self.team_forced = COLOR_TEAM1;
+ else if(PlayerInIDList(self, cvar_string("g_forced_team_blue")))
+ self.team_forced = COLOR_TEAM2;
+ else if(PlayerInIDList(self, cvar_string("g_forced_team_yellow")))
+ self.team_forced = COLOR_TEAM3;
+ else if(PlayerInIDList(self, cvar_string("g_forced_team_pink")))
+ self.team_forced = COLOR_TEAM4;
+ else if(cvar_string("g_forced_team_otherwise") == "red")
+ self.team_forced = COLOR_TEAM1;
+ else if(cvar_string("g_forced_team_otherwise") == "blue")
+ self.team_forced = COLOR_TEAM2;
+ else if(cvar_string("g_forced_team_otherwise") == "yellow")
+ self.team_forced = COLOR_TEAM3;
+ else if(cvar_string("g_forced_team_otherwise") == "pink")
+ self.team_forced = COLOR_TEAM4;
+ else if(cvar_string("g_forced_team_otherwise") == "spectate")
+ self.team_forced = -1;
+ else if(cvar_string("g_forced_team_otherwise") == "spectator")
+ self.team_forced = -1;
+ else
+ self.team_forced = 0;
+
+ if(!teams_matter)
+ if(self.team_forced > 0)
+ self.team_forced = 0;
+
JoinBestTeam(self, FALSE, FALSE); // if the team number is valid, keep it
- if((cvar("sv_spectate") == 1 && !g_lms) || cvar("g_campaign")) {
+ if((cvar("sv_spectate") == 1 && !g_lms) || cvar("g_campaign") || self.team_forced < 0) {
self.classname = "observer";
} else {
if(teams_matter)
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;
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_nexvelocity(self);
send_CSQC_cr_maxbullets(self);
CheatInitClient();
strunzone(self.netname_previous);
if(self.clientstatus)
strunzone(self.clientstatus);
+ if(self.weaponorder_byimpulse)
+ strunzone(self.weaponorder_byimpulse);
ClearPlayerSounds();
self.health = spectatee.health;
self.impulse = 0;
self.items = spectatee.items;
+ self.last_pickup = spectatee.last_pickup;
self.metertime = spectatee.metertime;
self.strength_finished = spectatee.strength_finished;
self.invincible_finished = spectatee.invincible_finished;
* @return bool TRUE if the player is allowed to join, false otherwise
*/
float isJoinAllowed() {
+ if(self.team_forced < 0)
+ return FALSE; // forced spectators can never join
+
if (!cvar("g_maxplayers"))
return TRUE;
}
player_regen();
+
+ // rot nex charge to the charge limit
+ if(cvar("g_balance_nex_charge_rot_rate") && self.nex_charge > cvar("g_balance_nex_charge_limit"))
+ self.nex_charge = bound(cvar("g_balance_nex_charge_limit"), self.nex_charge - cvar("g_balance_nex_charge_rot_rate") * frametime / W_TICSPERFRAME, 1);
+
if(frametime)
player_anim();
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)));