+#define LATENCY_THINKRATE 10
+.float latency_sum;
+.float latency_cnt;
+.float latency_time;
entity pingplreport;
void PingPLReport_Think()
{
WriteShort(MSG_BROADCAST, max(1, e.ping));
WriteByte(MSG_BROADCAST, ceil(e.ping_packetloss * 255));
WriteByte(MSG_BROADCAST, ceil(e.ping_movementloss * 255));
+
+ // record latency times for clients throughout the match so we can report it to playerstats
+ if(time > (e.latency_time + LATENCY_THINKRATE))
+ {
+ e.latency_sum += e.ping;
+ e.latency_cnt += 1;
+ e.latency_time = time;
+ //print("sum: ", ftos(e.latency_sum), ", cnt: ", ftos(e.latency_cnt), ", avg: ", ftos(e.latency_sum / e.latency_cnt), ".\n");
+ }
}
else
{
string GetMapname();
string GetGametype();
void GotoNextMap(float reinit);
-void ShuffleMaplist()
+void ShuffleMaplist();
float(float reinit) DoNextMapOverride;
void SetDefaultAlpha()
BADCVAR("g_balance_kill_delay");
BADCVAR("g_ca_point_leadlimit");
BADCVAR("g_ctf_captimerecord_always");
- BADCVAR("g_ctf_flag_capture_effects");
BADCVAR("g_ctf_flag_glowtrails");
- BADCVAR("g_ctf_flag_pickup_effects");
+ BADCVAR("g_ctf_flag_pickup_verbosename");
BADCVAR("g_domination_point_leadlimit");
BADCVAR("g_forced_respawn");
BADCVAR("g_keyhunt_point_leadlimit");
BADCVAR("gametype");
BADCVAR("g_antilag");
BADCVAR("g_balance_teams");
- BADCVAR("g_balance_teams_force");
+ BADCVAR("g_balance_teams_prevent_imbalance");
+ BADCVAR("g_balance_teams_scorefactor");
BADCVAR("g_ban_sync_trusted_servers");
BADCVAR("g_ban_sync_uri");
BADCVAR("g_ctf_ignore_frags");
self.classname = "worldspawn"; // safeguard against various stuff ;)
// needs to be done so early because of the constants they create
- RegisterWeapons();
- RegisterGametypes();
+ CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
+ CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
+ CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
+ CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
MapInfo_Enumerate();
MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
void Map_MarkAsRecent(string m);
float world_already_spawned;
-void RegisterWeapons();
void Nagger_Init();
void ClientInit_Spawn();
void WeaponStats_Init();
}
// needs to be done so early because of the constants they create
- RegisterWeapons();
- RegisterGametypes();
+ CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
+ CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
+ CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
+ CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
ServerProgsDB = db_load(strcat("server.db", autocvar_sessionid));
Map_MarkAsRecent(mapname);
+ PlayerStats_Init(); // we need this to be initiated before InitGameplayMode
+
precache_model ("null"); // we need this one before InitGameplayMode
InitGameplayMode();
readlevelcvars();
WaypointSprite_Init();
- //if (g_domination)
- // dom_init();
-
GameLogInit(); // prepare everything
// NOTE for matchid:
// changing the logic generating it is okay. But:
addstat(STAT_SECRETS_TOTAL, AS_FLOAT, stat_secrets_total);
addstat(STAT_SECRETS_FOUND, AS_FLOAT, stat_secrets_found);
+ // misc
+ addstat(STAT_RESPAWN_TIME, AS_FLOAT, stat_respawn_time);
+
next_pingtime = time + 5;
detect_maptype();
cvar_set("sv_curl_serverpackages", substring(s, 1, -1));
}
- PlayerStats_Init();
-
// MOD AUTHORS: change this, and possibly remove a few of the blocks below to ignore certain changes
modname = "Xonotic";
// physics/balance/config changes that count as mod
modname = "MinstaGib";
// extra mutators that deserve to count as mod
MUTATOR_CALLHOOK(SetModname);
- // weird game types that deserve to count as mod
- if(g_cts)
- modname = "CTS";
+
// save it for later
modname = strzone(modname);
if(autocvar_g_campaign)
CampaignPreIntermission();
+ MUTATOR_CALLHOOK(MatchEnd);
+
localcmd("\nsv_hook_gameend\n");
}
{
if (head.health > 0)
{
- if (head.team == COLOR_TEAM1) t1 = 1;
- if (head.team == COLOR_TEAM2) t2 = 1;
- if (head.team == COLOR_TEAM3) t3 = 1;
- if (head.team == COLOR_TEAM4) t4 = 1;
+ if (head.team == FL_TEAM_1) t1 = 1;
+ if (head.team == FL_TEAM_2) t2 = 1;
+ if (head.team == FL_TEAM_3) t3 = 1;
+ if (head.team == FL_TEAM_4) t4 = 1;
}
head = find(head, classname, "onslaught_generator");
}
{
// game over, only one team remains (or none)
ClearWinners();
- if (t1) SetWinners(team, COLOR_TEAM1);
- if (t2) SetWinners(team, COLOR_TEAM2);
- if (t3) SetWinners(team, COLOR_TEAM3);
- if (t4) SetWinners(team, COLOR_TEAM4);
+ if (t1) SetWinners(team, FL_TEAM_1);
+ if (t2) SetWinners(team, FL_TEAM_2);
+ if (t3) SetWinners(team, FL_TEAM_3);
+ if (t4) SetWinners(team, FL_TEAM_4);
dprint("Have a winner, ending game.\n");
return WINNING_YES;
}
status = WINNING_NO;
// as the timelimit has not yet passed just assume the defending team will win
- if(assault_attacker_team == COLOR_TEAM1)
+ if(assault_attacker_team == FL_TEAM_1)
{
- SetWinners(team, COLOR_TEAM2);
+ SetWinners(team, FL_TEAM_2);
}
else
{
- SetWinners(team, COLOR_TEAM1);
+ SetWinners(team, FL_TEAM_1);
}
entity ent;
if(teamplay)
{
- team1_score = TeamScore_GetCompareValue(COLOR_TEAM1);
- team2_score = TeamScore_GetCompareValue(COLOR_TEAM2);
- team3_score = TeamScore_GetCompareValue(COLOR_TEAM3);
- team4_score = TeamScore_GetCompareValue(COLOR_TEAM4);
+ team1_score = TeamScore_GetCompareValue(FL_TEAM_1);
+ team2_score = TeamScore_GetCompareValue(FL_TEAM_2);
+ team3_score = TeamScore_GetCompareValue(FL_TEAM_3);
+ team4_score = TeamScore_GetCompareValue(FL_TEAM_4);
}
ClearWinners();
limitreached = (limitreached || leadlimitreached);
}
+ if(limit)
+ game_completion_ratio = max(game_completion_ratio, bound(0, WinningConditionHelper_topscore / limit, 1));
+
return GetWinningCode(
WinningConditionHelper_topscore && limitreached,
WinningConditionHelper_equality
return WINNING_STARTSUDDENDEATHOVERTIME;
else
return WINNING_NEVER;
- return wc;
}
float WinningCondition_QualifyingThenRace(float limit)
FOR_EACH_PLAYER(head) if(head.deadflag == DEAD_NO)
{
- if(head.team == COLOR_TEAM1)
+ if(head.team == FL_TEAM_1)
team1_score = 1;
- else if(head.team == COLOR_TEAM2)
+ else if(head.team == FL_TEAM_2)
team2_score = 1;
- else if(head.team == COLOR_TEAM3)
+ else if(head.team == FL_TEAM_3)
team3_score = 1;
- else if(head.team == COLOR_TEAM4)
+ else if(head.team == FL_TEAM_4)
team4_score = 1;
}
for(head = world; (head = find(head, classname, "info_player_deathmatch")) != world; )
{
- if(head.team == COLOR_TEAM1)
+ if(head.team == FL_TEAM_1)
team1_score = 1;
- else if(head.team == COLOR_TEAM2)
+ else if(head.team == FL_TEAM_2)
team2_score = 1;
- else if(head.team == COLOR_TEAM3)
+ else if(head.team == FL_TEAM_3)
team3_score = 1;
- else if(head.team == COLOR_TEAM4)
+ else if(head.team == FL_TEAM_4)
team4_score = 1;
}
{
float t, i;
if(team1_score)
- t = COLOR_TEAM1;
+ t = FL_TEAM_1;
else if(team2_score)
- t = COLOR_TEAM2;
+ t = FL_TEAM_2;
else if(team3_score)
- t = COLOR_TEAM3;
+ t = FL_TEAM_3;
else // if(team4_score)
- t = COLOR_TEAM4;
+ t = FL_TEAM_4;
CheckAllowedTeams(world);
for(i = 0; i < MAX_TEAMSCORE; ++i)
{
- if(t != COLOR_TEAM1) if(c1 >= 0) TeamScore_AddToTeam(COLOR_TEAM1, i, -1000);
- if(t != COLOR_TEAM2) if(c2 >= 0) TeamScore_AddToTeam(COLOR_TEAM2, i, -1000);
- if(t != COLOR_TEAM3) if(c3 >= 0) TeamScore_AddToTeam(COLOR_TEAM3, i, -1000);
- if(t != COLOR_TEAM4) if(c4 >= 0) TeamScore_AddToTeam(COLOR_TEAM4, i, -1000);
+ if(t != FL_TEAM_1) if(c1 >= 0) TeamScore_AddToTeam(FL_TEAM_1, i, -1000);
+ if(t != FL_TEAM_2) if(c2 >= 0) TeamScore_AddToTeam(FL_TEAM_2, i, -1000);
+ if(t != FL_TEAM_3) if(c3 >= 0) TeamScore_AddToTeam(FL_TEAM_3, i, -1000);
+ if(t != FL_TEAM_4) if(c4 >= 0) TeamScore_AddToTeam(FL_TEAM_4, i, -1000);
}
AddWinners(team, t);
float wantovertime;
wantovertime = 0;
+ if(timelimit > game_starttime)
+ game_completion_ratio = (time - game_starttime) / (timelimit - game_starttime);
+ else
+ game_completion_ratio = 0;
+
if(checkrules_suddendeathend)
{
if(!checkrules_suddendeathwarning)
if(mapvote_initialized)
return "Can't suggest - voting is already in progress!";
m = MapInfo_FixName(m);
- if(!m)
+ if not(m)
return "The map you suggested is not available on this server.";
if(!autocvar_g_maplist_votable_suggestions_override_mostrecent)
if(Map_IsRecent(m))