prio = 0;
// filter out spots for the wrong team
- if(teamcheck)
- if(spot.team != teamcheck)
- return '-1 0 0';
+ if(teamcheck >= 0)
+ if(spot.team != teamcheck)
+ return '-1 0 0';
if(race_spawns)
if(spot.target == "")
spotlist = spot;
/*
- if(teamcheck)
+ if(teamcheck >= 0)
if(spot.team != teamcheck)
error("invalid spawn added");
/*
entity e;
- if(teamcheck)
+ if(teamcheck >= 0)
for(e = spotlist; e; e = e.chain)
{
print("seen ", etos(e), "\n");
if (spot)
return spot;
- teamcheck = 0;
+ if(anypoint)
+ teamcheck = -1;
+ else if(have_team_spawns > 0)
+ {
+ if(have_team_spawns_forteam[self.team] == 0)
+ {
+ // we request a spawn for a team, and we have team
+ // spawns, but that team has no spawns?
+ if(have_team_spawns[0])
+ // try noteam spawns
+ teamcheck = 0;
+ else
+ // if not, any spawn has to do
+ teamcheck = -1;
+ }
+ else
+ teamcheck = self.team; // MUST be team
+ }
+ else if(have_team_spawns == 0 && have_team_spawns[0])
+ teamcheck = 0; // MUST be noteam
+ else
+ teamcheck = -1;
+ // if we get here, we either require team spawns but have none, or we require non-team spawns and have none; use any spawn then
- if(!anypoint && have_team_spawns > 0)
- teamcheck = self.team;
// get the list of players
playerlist = findchain(classname, "player");
print("spot mindistance: ", vtos(spot.spawnpoint_score), "\n");
entity e;
- if(teamcheck)
+ if(teamcheck >= 0)
for(e = firstspot; e; e = e.chain)
if(e.team != teamcheck)
error("invalid spawn found");
}
if(self.flagcarried)
- DropFlag(self.flagcarried, world, world);
+ ctf_Handle_Drop(self); // FIXCTF
if(self.ballcarried && g_nexball)
DropBall(self.ballcarried, self.origin + self.ballcarried.origin, self.velocity);
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;
// reset fields the weapons may use
for (j = WEP_FIRST; j <= WEP_LAST; ++j)
+ {
weapon_action(j, WR_RESETPLAYER);
+ // all weapons must be fully loaded when we spawn
+ 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"));
+ }
+
oldself = self;
self = spot;
activator = oldself;
WriteByte(MSG_ENTITY, autocvar_g_balance_nex_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
+ WriteByte(MSG_ENTITY, autocvar_g_balance_minelayer_limit); // minelayer max mines
WriteCoord(MSG_ENTITY, autocvar_g_trueaim_minrange);
return TRUE;
}
Portal_ClearAll(self);
if(self.flagcarried)
- DropFlag(self.flagcarried, world, world);
+ ctf_Handle_Drop(self); // FIXCTF
if(self.ballcarried && g_nexball)
DropBall(self.ballcarried, self.origin + self.ballcarried.origin, self.velocity);
self.impulse = 0;
self.items = spectatee.items;
self.last_pickup = spectatee.last_pickup;
+ self.hit_time = spectatee.hit_time;
self.metertime = spectatee.metertime;
self.strength_finished = spectatee.strength_finished;
self.invincible_finished = spectatee.invincible_finished;
self.weapons = spectatee.weapons;
self.switchweapon = spectatee.switchweapon;
self.weapon = spectatee.weapon;
+ self.nex_charge = spectatee.nex_charge;
+ self.nex_chargepool_ammo = spectatee.nex_chargepool_ammo;
+ self.minelayer_mines = spectatee.minelayer_mines;
self.punchangle = spectatee.punchangle;
self.view_ofs = spectatee.view_ofs;
self.v_angle = spectatee.v_angle;
void LeaveSpectatorMode()
{
- if(isJoinAllowed()) {
+ if(nJoinAllowed(1)) {
if(!teams_matter || autocvar_g_campaign || autocvar_g_balance_teams || (self.wasplayer && autocvar_g_changeteam_banned) || self.team_forced > 0) {
self.classname = "player";
* Determines whether the player is allowed to join. This depends on cvar
* g_maxplayers, if it isn't used this function always return TRUE, otherwise
* it checks whether the number of currently playing players exceeds g_maxplayers.
- * @return bool TRUE if the player is allowed to join, false otherwise
+ * @return int number of free slots for players, 0 if none
*/
-float isJoinAllowed() {
+float nJoinAllowed(float includeMe) {
if(self.team_forced < 0)
return FALSE; // forced spectators can never join
+ // TODO simplify this
+ local entity e;
+
+ local float totalClients;
+ FOR_EACH_CLIENT(e)
+ totalClients += 1;
+
if (!autocvar_g_maxplayers)
- return TRUE;
+ return maxclients - totalClients + includeMe;
- local entity e;
local float currentlyPlaying;
- FOR_EACH_REALPLAYER(e) {
- if(e.classname == "player")
- currentlyPlaying += 1;
- }
+ FOR_EACH_REALPLAYER(e)
+ currentlyPlaying += 1;
+
if(currentlyPlaying < autocvar_g_maxplayers)
- return TRUE;
+ return min(maxclients - totalClients + includeMe, autocvar_g_maxplayers - currentlyPlaying);
- return FALSE;
+ return 0;
}
/**
Called every frame for each client before the physics are run
=============
*/
-void() ctf_setstatus;
+//void() ctf_setstatus;
void() nexball_setstatus;
.float items_added;
void PlayerPreThink (void)
return; // the think tics
}
- if(self.teleport_time)
- if(time > self.teleport_time)
- {
- self.teleport_time = 0;
- self.effects = self.effects - (self.effects & EF_NODRAW);
- }
-
if(frametime > 0) // don't do this in cl_movement frames, just in server ticks
UpdateSelectedPlayer();
if (g_minstagib)
minstagib_ammocheck();
- if(g_ctf)
- ctf_setstatus();
+ //if(g_ctf)
+ // ctf_setstatus();
if(g_nexball)
nexball_setstatus();
playerdemo_write();
- if((g_cts || g_race) && self.cvar_cl_allow_uid2name == 1)
+ if((g_cts || g_race) && self.cvar_cl_allow_uidtracking == 1 && self.cvar_cl_allow_uid2name == 1)
{
if(!self.stored_netname)
self.stored_netname = strzone(uid2name(self.crypto_idfp));