float scores_flags_primary;
float teamscores_flags_primary;
-vector ScoreField_Compare(entity t1, entity t2, .float field, float fieldflags, vector previous) // returns: cmp value, best prio
+vector ScoreField_Compare(entity t1, entity t2, .float field, float fieldflags, vector previous, float strict) // returns: cmp value, best prio
{
- if(!(fieldflags & SFL_SORT_PRIO_MASK)) // column does not sort
+ if(!strict && !(fieldflags & SFL_SORT_PRIO_MASK)) // column does not sort
return previous;
if(fieldflags & SFL_SORT_PRIO_MASK < previous_y)
return previous;
return TeamScore_AddToTeam(player.team, scorefield, score);
}
-float TeamScore_Compare(entity t1, entity t2)
+float TeamScore_Compare(entity t1, entity t2, float strict)
{
if(!t1 || !t2) return (!t2) - !t1;
{
var .float f;
f = teamscores[i];
- result = ScoreField_Compare(t1, t2, f, teamscores_flags[i], result);
+ result = ScoreField_Compare(t1, t2, f, teamscores_flags[i], result, strict);
}
+
+ if (result_x == 0 && strict)
+ result_x = t1.team - t2.team;
+
return result_x;
}
Net_LinkEntity(scores_initialized, FALSE, 0, ScoreInfo_SendEntity);
}
if(teams >= 1)
- TeamScore_Spawn(FL_TEAM_1, "Red");
+ TeamScore_Spawn(NUM_TEAM_1, "Red");
if(teams >= 2)
- TeamScore_Spawn(FL_TEAM_2, "Blue");
+ TeamScore_Spawn(NUM_TEAM_2, "Blue");
if(teams >= 3)
- TeamScore_Spawn(FL_TEAM_3, "Yellow");
+ TeamScore_Spawn(NUM_TEAM_3, "Yellow");
if(teams >= 4)
- TeamScore_Spawn(FL_TEAM_4, "Pink");
+ TeamScore_Spawn(NUM_TEAM_4, "Pink");
}
/*
return TRUE;
}
-void PlayerScore_Clear(entity player)
+float PlayerScore_Clear(entity player)
{
entity sk;
float i;
if(teamscores_entities_count)
- return;
+ return 0;
- if(g_lms) return;
- if(g_arena || g_ca) return;
- if(g_cts) return; // in CTS, you don't lose score by observing
- if(g_race && g_race_qualifying) return; // in qualifying, you don't lose score by observing
+ if(MUTATOR_CALLHOOK(ForbidPlayerScore_Clear)) return 0;
+
+ if(g_cts) return 0; // in CTS, you don't lose score by observing
+ if(g_race && g_race_qualifying) return 0; // in qualifying, you don't lose score by observing
sk = player.scorekeeper;
for(i = 0; i < MAX_SCORE; ++i)
sk.SendFlags |= pow(2, i);
sk.(scores[i]) = 0;
}
+
+ return 1;
}
void Score_ClearAll()
return r;
}
-float PlayerScore_Compare(entity t1, entity t2)
+float PlayerScore_Compare(entity t1, entity t2, float strict)
{
if(!t1 || !t2) return (!t2) - !t1;
{
var .float f;
f = scores[i];
- result = ScoreField_Compare(t1, t2, f, scores_flags[i], result);
+ result = ScoreField_Compare(t1, t2, f, scores_flags[i], result, strict);
}
+
+ if (result_x == 0 && strict)
+ result_x = num_for_edict(t1.owner) - num_for_edict(t2.owner);
+
return result_x;
}
// so to match pure, match for :P0:
// to match full, match for :S0:
+ fullstatus = autocvar_g_full_getstatus_responses;
+
s = GetGametype();
s = strcat(s, ":", autocvar_g_xonoticversion);
s = strcat(s, ":P", ftos(cvar_purechanges_count));
s = strcat(s, ":S", ftos(nJoinAllowed(world)));
s = strcat(s, ":F", ftos(serverflags));
s = strcat(s, ":M", modname);
- s = strcat(s, "::", GetPlayerScoreString(world, 1)); // make this 1 once we can, note: this doesn't contain any :<letter>
-
- fullstatus = autocvar_g_full_getstatus_responses;
+ s = strcat(s, "::", GetPlayerScoreString(world, (fullstatus ? 1 : 2)));
if(teamscores_entities_count)
{
for(t = 0; t < 16; ++t)
{
sk = teamscorekeepers[t];
- c = TeamScore_Compare(winnerscorekeeper, sk);
+ c = TeamScore_Compare(winnerscorekeeper, sk, 1);
if(c < 0)
{
WinningConditionHelper_secondteam = WinningConditionHelper_winnerteam;
}
else
{
- c = TeamScore_Compare(secondscorekeeper, sk);
+ c = TeamScore_Compare(secondscorekeeper, sk, 1);
if(c < 0)
{
WinningConditionHelper_secondteam = t + 1;
}
}
- WinningConditionHelper_equality = (TeamScore_Compare(winnerscorekeeper, secondscorekeeper) == 0);
+ WinningConditionHelper_equality = (TeamScore_Compare(winnerscorekeeper, secondscorekeeper, 0) == 0);
if(WinningConditionHelper_equality)
WinningConditionHelper_winnerteam = WinningConditionHelper_secondteam = -1;
FOR_EACH_PLAYER(p)
{
sk = p.scorekeeper;
- c = PlayerScore_Compare(winnerscorekeeper, sk);
+ c = PlayerScore_Compare(winnerscorekeeper, sk, 1);
if(c < 0)
{
WinningConditionHelper_second = WinningConditionHelper_winner;
}
else
{
- c = PlayerScore_Compare(secondscorekeeper, sk);
+ c = PlayerScore_Compare(secondscorekeeper, sk, 1);
if(c < 0)
{
WinningConditionHelper_second = p;
}
}
- WinningConditionHelper_equality = (PlayerScore_Compare(winnerscorekeeper, secondscorekeeper) == 0);
+ WinningConditionHelper_equality = (PlayerScore_Compare(winnerscorekeeper, secondscorekeeper, 0) == 0);
if(WinningConditionHelper_equality)
WinningConditionHelper_winner = WinningConditionHelper_second = world;
s = strcat(s, ":human");
else
s = strcat(s, ":bot");
- if(p.classname != "player" && !g_arena && !g_ca && !g_lms)
+ if(p.classname != "player" && !g_arena && p.caplayer != 1 && !g_lms)
s = strcat(s, ":spectator");
}
else
{
- if(p.classname == "player" || g_arena || g_ca || g_lms)
+ if(p.classname == "player" || g_arena || p.caplayer == 1 || g_lms)
s = GetPlayerScoreString(p, 2);
else
s = "-666";
if(tm == 0)
{
// label
- for(i = 0; i < MAX_SCORE; ++i)
+ for(i = 0; i < MAX_TEAMSCORE; ++i)
if(teamscores_flags[i] & SFL_SORT_PRIO_MASK == SFL_SORT_PRIO_PRIMARY)
{
f = teamscores_flags[i];
out = strcat(out, GetScoreLogLabel(l, f), ",");
}
if(shortString < 2)
- for(i = 0; i < MAX_SCORE; ++i)
+ for(i = 0; i < MAX_TEAMSCORE; ++i)
if(teamscores_flags[i] & SFL_SORT_PRIO_MASK == SFL_SORT_PRIO_SECONDARY)
{
f = teamscores_flags[i];
out = strcat(out, GetScoreLogLabel(l, f), ",");
}
if(shortString < 1)
- for(i = 0; i < MAX_SCORE; ++i)
+ for(i = 0; i < MAX_TEAMSCORE; ++i)
if(teamscores_flags[i] & SFL_SORT_PRIO_MASK != SFL_SORT_PRIO_PRIMARY)
if(teamscores_flags[i] & SFL_SORT_PRIO_MASK != SFL_SORT_PRIO_SECONDARY)
{
return out;
}
-float PlayerTeamScore_Compare(entity p1, entity p2)
+float PlayerTeamScore_Compare(entity p1, entity p2, float teams, float strict)
{
- if(teamscores_entities_count)
+ if(teams && teamscores_entities_count)
+ {
if(p1.team != p2.team)
{
entity t1, t2;
float r;
t1 = teamscorekeepers[p1.team - 1];
t2 = teamscorekeepers[p2.team - 1];
- r = TeamScore_Compare(t1, t2);
- if(r == 0) // ensure a deterministic order
- r = p1.team - p2.team;
+ r = TeamScore_Compare(t1, t2, ((teams >= 0) ? 1 : strict));
return r;
}
+ if(teams < 0)
+ return 0;
+ }
- return PlayerScore_Compare(p1.scorekeeper, p2.scorekeeper);
+ return PlayerScore_Compare(p1.scorekeeper, p2.scorekeeper, strict);
}
-entity PlayerScore_Sort(.float field)
+entity PlayerScore_Sort(.float field, float teams, float strict, float nospectators)
{
entity p, plist, pprev, pbest, pbestprev, pfirst, plast;
- float i;
+ float i, j;
plist = world;
FOR_EACH_CLIENT(p)
p.field = 0;
- FOR_EACH_PLAYER(p) if(p.scorekeeper)
+ FOR_EACH_CLIENT(p) if(p.scorekeeper)
{
+ if(nospectators)
+ if(p.frags == FRAGS_SPECTATOR)
+ continue;
+
p.chain = plist;
plist = p;
}
pfirst = plast = world;
- i = 0;
+ i = j = 0;
while(plist)
{
pprev = pbestprev = world;
pbest = plist;
for(p = plist; (pprev = p), (p = p.chain); )
{
- if(PlayerTeamScore_Compare(p, pbest) > 0)
+ if(PlayerTeamScore_Compare(p, pbest, teams, strict) > 0)
{
pbest = p;
pbestprev = pprev;
pbestprev.chain = pbest.chain;
pbest.chain = world;
- pbest.field = ++i;
+ ++i;
+ if(!plast || PlayerTeamScore_Compare(plast, pbest, teams, 0))
+ j = i;
+
+ pbest.field = j;
if not(pfirst)
pfirst = pbest;
++t;
w = bound(6, floor(SCORESWIDTH / t - 1), 9);
- p = PlayerScore_Sort(score_dummyfield);
+ p = PlayerScore_Sort(score_dummyfield, 1, 1, 0);
t = -1;
if(!teamscores_entities_count)