- wget -O data/maps/g-23.waypoints.cache https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/g-23.waypoints.cache
- wget -O data/maps/g-23.waypoints.hardwired https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/g-23.waypoints.hardwired
- make
- - EXPECT=814b0e609bcf01dc2a44f2b17fa366b4
- - EXPECT=4bd5b0276cdd100c831c73f0400eca71
++ - EXPECT=f05b0d5a3aa761c72406d4d2b47dba86
- HASH=$(${ENGINE} -noconfig -nohome +exec serverbench.cfg
| tee /dev/stderr
| grep '^:'
pl = players.sort_next;
if(pl == me)
pl = pl.sort_next;
- if(scores_flags[ps_primary] & SFL_ZERO_IS_WORST)
- if(pl.scores[ps_primary] == 0)
+ if(scores_flags(ps_primary) & SFL_ZERO_IS_WORST)
+ if(pl.scores(ps_primary) == 0)
- pl = world;
+ pl = NULL;
- score = me.(scores[ps_primary]);
+ score = me.(scores(ps_primary));
timer = TIME_ENCODED_TOSTRING(score);
draw_beginBoldFont();
LOG_INFO(_("^2scoreboard_columns_set default\n"));
LOG_INFO(_("^2scoreboard_columns_set ^7field1 field2 ...\n"));
LOG_INFO(_("The following field names are recognized (case insensitive):\n"));
-- LOG_INFO(_("You can use a ^3|^7 to start the right-aligned fields.\n\n"));
++ LOG_INFO(_("You can use a ^3|^7 to start the right-aligned fields.\n"));
++ LOG_INFO("\n");
LOG_INFO(_("^3name^7 or ^3nick^7 Name of a player\n"));
LOG_INFO(_("^3ping^7 Ping time\n"));
LOG_INFO(_("^3pl^7 Packet loss\n"));
++ LOG_INFO(_("^3elo^7 Player ELO\n"));
LOG_INFO(_("^3kills^7 Number of kills\n"));
LOG_INFO(_("^3deaths^7 Number of deaths\n"));
LOG_INFO(_("^3suicides^7 Number of suicides\n"));
LOG_INFO(_("^3takes^7 Number of domination points taken (DOM)\n"));
LOG_INFO(_("^3bckills^7 Number of ball carrier kills\n"));
LOG_INFO(_("^3bctime^7 Total amount of time holding the ball in Keepaway\n"));
-- LOG_INFO(_("^3score^7 Total score\n\n"));
++ LOG_INFO(_("^3score^7 Total score\n"));
++ LOG_INFO("\n");
LOG_INFO(_("Before a field you can put a + or - sign, then a comma separated list\n"
"of game types, then a slash, to make the field show up only in these\n"
// scoreboard setup
void ons_ScoreRules()
{
- CheckAllowedTeams(world);
+ CheckAllowedTeams(NULL);
ScoreRules_basics(((c4>=0) ? 4 : (c3>=0) ? 3 : 2), SFL_SORT_PRIO_PRIMARY, 0, true);
ScoreInfo_SetLabel_TeamScore (ST_ONS_CAPS, "destroyed", SFL_SORT_PRIO_PRIMARY);
- ScoreInfo_SetLabel_PlayerScore(SP_ONS_CAPS, "caps", SFL_SORT_PRIO_SECONDARY);
+ ScoreInfo_SetLabel_PlayerScore(SP_ONS_CAPS, "caps", SFL_SORT_PRIO_SECONDARY);
ScoreInfo_SetLabel_PlayerScore(SP_ONS_TAKES, "takes", 0);
ScoreRules_basics_end();
}
MUTATOR_HOOKABLE(WantWeapon, EV_WantWeapon);
#define EV_AddPlayerScore(i, o) \
- /**/ i(entity, score_field) \
- /**/ i(float, ret_float) \
- /**/ o(float, ret_float) \
- /** score field */ i(int, MUTATOR_ARGV_0_int) \
++ /** score field */ i(PlayerScoreField, MUTATOR_ARGV_0_entity) \
+ /** score */ i(float, MUTATOR_ARGV_1_float) \
+ /**/ o(float, MUTATOR_ARGV_1_float) \
+ /** player */ i(entity, MUTATOR_ARGV_2_entity) \
/**/
- PlayerScoreField score_field;
MUTATOR_HOOKABLE(AddPlayerScore, EV_AddPlayerScore);
#define EV_GetPlayerStatus(i, o) \
// scoreboard stuff
const float ST_ASSAULT_OBJECTIVES = 1;
-const float SP_ASSAULT_OBJECTIVES = 4;
// predefined spawnfuncs
- void target_objective_decrease_activate();
+ void target_objective_decrease_activate(entity this);
#endif
#ifdef IMPLEMENTATION
// scoreboard setup
void ctf_ScoreRules(int teams)
{
- CheckAllowedTeams(world);
+ CheckAllowedTeams(NULL);
ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, 0, true);
ScoreInfo_SetLabel_TeamScore (ST_CTF_CAPS, "caps", SFL_SORT_PRIO_PRIMARY);
- ScoreInfo_SetLabel_PlayerScore(SP_CTF_CAPS, "caps", SFL_SORT_PRIO_SECONDARY);
- ScoreInfo_SetLabel_PlayerScore(SP_CTF_CAPTIME, "captime", SFL_LOWER_IS_BETTER | SFL_TIME);
- ScoreInfo_SetLabel_PlayerScore(SP_CTF_PICKUPS, "pickups", 0);
- ScoreInfo_SetLabel_PlayerScore(SP_CTF_FCKILLS, "fckills", 0);
- ScoreInfo_SetLabel_PlayerScore(SP_CTF_RETURNS, "returns", 0);
- ScoreInfo_SetLabel_PlayerScore(SP_CTF_DROPS, "drops", SFL_LOWER_IS_BETTER);
+ ScoreInfo_SetLabel_PlayerScore(SP_CTF_CAPS, "caps", SFL_SORT_PRIO_SECONDARY);
+ ScoreInfo_SetLabel_PlayerScore(SP_CTF_CAPTIME, "captime", SFL_LOWER_IS_BETTER | SFL_TIME);
+ ScoreInfo_SetLabel_PlayerScore(SP_CTF_PICKUPS, "pickups", 0);
+ ScoreInfo_SetLabel_PlayerScore(SP_CTF_FCKILLS, "fckills", 0);
+ ScoreInfo_SetLabel_PlayerScore(SP_CTF_RETURNS, "returns", 0);
+ ScoreInfo_SetLabel_PlayerScore(SP_CTF_DROPS, "drops", SFL_LOWER_IS_BETTER);
ScoreRules_basics_end();
}
MUTATOR_HOOKFUNCTION(lms, AddPlayerScore)
{
if(gameover)
- if(score_field == SP_LMS_RANK)
- if(M_ARGV(0, int) == SP_LMS_RANK) // score field
++ if(M_ARGV(0, entity) == SP_LMS_RANK) // score field
return true; // allow writing to this field in intermission as it is needed for newly joining players
- return false;
}
// scoreboard stuff
longflags = 0;
for(i = 0, p = 1; i < MAX_TEAMSCORE; ++i, p *= 2)
- if(self.(teamscores(i)) > 127 || self.(teamscores(i)) <= -128)
- if(this.(teamscores[i]) > 127 || this.(teamscores[i]) <= -128)
++ if(this.(teamscores(i)) > 127 || this.(teamscores(i)) <= -128)
longflags |= p;
#if MAX_TEAMSCORE <= 8
if(sendflags & p)
{
if(longflags & p)
- WriteInt24_t(MSG_ENTITY, self.(teamscores(i)));
- WriteInt24_t(MSG_ENTITY, this.(teamscores[i]));
++ WriteInt24_t(MSG_ENTITY, this.(teamscores(i)));
else
- WriteChar(MSG_ENTITY, self.(teamscores(i)));
- WriteChar(MSG_ENTITY, this.(teamscores[i]));
++ WriteChar(MSG_ENTITY, this.(teamscores(i)));
}
return true;
bool PlayerScore_SendEntity(entity this, entity to, float sendflags)
{
- float i, p, longflags;
-
WriteHeader(MSG_ENTITY, ENT_CLIENT_SCORES);
- WriteByte(MSG_ENTITY, etof(self.owner));
+ WriteByte(MSG_ENTITY, etof(this.owner));
- longflags = 0;
- for(i = 0, p = 1; i < MAX_SCORE; ++i, p *= 2)
- if(this.(scores[i]) > 127 || this.(scores[i]) <= -128)
+ int longflags = 0;
+ FOREACH(Scores, true, {
+ int p = 1 << (i % 16);
- if (self.(scores(it)) > 127 || self.(scores(it)) <= -128)
++ if (this.(scores(it)) > 127 || this.(scores(it)) <= -128)
longflags |= p;
+ });
-#if MAX_SCORE <= 8
- WriteByte(MSG_ENTITY, sendflags);
- WriteByte(MSG_ENTITY, longflags);
-#else
WriteShort(MSG_ENTITY, sendflags);
WriteShort(MSG_ENTITY, longflags);
-#endif
- for(i = 0, p = 1; i < MAX_SCORE; ++i, p *= 2)
- if(sendflags & p)
+ FOREACH(Scores, true, {
+ int p = 1 << (i % 16);
+ if (sendflags & p)
{
if(longflags & p)
- WriteInt24_t(MSG_ENTITY, self.(scores(it)));
- WriteInt24_t(MSG_ENTITY, this.(scores[i]));
++ WriteInt24_t(MSG_ENTITY, this.(scores(it)));
else
- WriteChar(MSG_ENTITY, self.(scores(it)));
- WriteChar(MSG_ENTITY, this.(scores[i]));
++ WriteChar(MSG_ENTITY, this.(scores(it)));
}
+ });
return true;
}
if(!player.scorekeeper)
error("player has no scorekeeper");
remove(player.scorekeeper);
- player.scorekeeper = world;
+ player.scorekeeper = NULL;
}
-float PlayerScore_Add(entity player, float scorefield, float score)
+float PlayerScore_Add(entity player, PlayerScoreField scorefield, float score)
{
- bool mutator_returnvalue = MUTATOR_CALLHOOK(AddPlayerScore, scorefield, score);
- score = ret_float;
+ bool mutator_returnvalue = MUTATOR_CALLHOOK(AddPlayerScore, scorefield, score, player);
+ score = M_ARGV(1, float);
if(gameover)
if(!mutator_returnvalue)
#include <common/constants.qh>
- entity scores_initialized; // non-world when scores labels/rules have been set
+ entity scores_initialized; // non-NULL when scores labels/rules have been set
-.float scores[MAX_SCORE];
-.float teamscores[MAX_TEAMSCORE];
.float scoreboard_pos;
/**