+#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");
BADCVAR("g_maplist_votable_nodetail");
BADCVAR("g_maplist_votable_suggestions");
BADCVAR("g_maxplayers");
- BADCVAR("g_minstagib");
BADCVAR("g_mirrordamage");
BADCVAR("g_nexball_goallimit");
BADCVAR("g_powerups");
BADPREFIX("g_warmup_");
BADPREFIX("sv_ready_restart_");
+ // mutators that announce themselves properly to the server browser
+ BADCVAR("g_minstagib");
+ BADCVAR("g_new_toys");
+ BADCVAR("g_nix");
+
if(autocvar_g_minstagib)
{
BADCVAR("g_grappling_hook");
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);
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();
compressShortVector_init();
- allowed_to_spawn = TRUE;
-
entity head;
head = nextent(world);
maxclients = 0;
}
// needs to be done so early because of the constants they create
- RegisterWeapons();
- RegisterGametypes();
+ CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
+ CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
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();
WeaponStats_Init();
- addstat(STAT_WEAPONS, AS_INT, weapons);
+ WEPSET_ADDSTAT();
addstat(STAT_SWITCHWEAPON, AS_INT, switchweapon);
addstat(STAT_SWITCHINGWEAPON, AS_INT, switchingweapon);
addstat(STAT_GAMESTARTTIME, AS_FLOAT, stat_game_starttime);
addstat(STAT_HAGAR_LOAD, AS_INT, hagar_load);
- if(g_ca || g_freezetag)
+ if(g_ca)
{
addstat(STAT_REDALIVE, AS_INT, redalive_stat);
addstat(STAT_BLUEALIVE, AS_INT, bluealive_stat);
- addstat(STAT_YELLOWALIVE, AS_INT, yellowalive_stat);
- addstat(STAT_PINKALIVE, AS_INT, pinkalive_stat);
- }
- if(g_freezetag)
- {
- addstat(STAT_FROZEN, AS_INT, freezetag_frozen);
- addstat(STAT_REVIVE_PROGRESS, AS_FLOAT, freezetag_revive_progress);
}
// g_movementspeed hack
addstat(STAT_MOVEVARS_MAXSPEED, AS_FLOAT, stat_sv_maxspeed);
addstat(STAT_MOVEVARS_AIRACCEL_QW, AS_FLOAT, stat_sv_airaccel_qw);
addstat(STAT_MOVEVARS_AIRSTRAFEACCEL_QW, AS_FLOAT, stat_sv_airstrafeaccel_qw);
-
+
// secrets
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();
-
+
// set up information replies for clients and server to use
lsmaps_reply = "^7Maps available: ";
lsnewmaps_reply = "^7Maps without a record set: ";
col = "^2";
else
col = "^3";
-
+
++j;
-
+
lsmaps_reply = strcat(lsmaps_reply, col, MapInfo_Map_bspname, " ");
-
+
if(g_race && !stof(db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, RACE_RECORD, "time"))))
lsnewmaps_reply = strcat(lsnewmaps_reply, col, MapInfo_Map_bspname, " ");
else if(g_cts && !stof(db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, CTS_RECORD, "time"))))
lsnewmaps_reply = strcat(lsnewmaps_reply, col, MapInfo_Map_bspname, " ");
}
}
-
+
lsmaps_reply = strzone(strcat(lsmaps_reply, "\n"));
lsnewmaps_reply = strzone(strcat(((!g_race && !g_cts) ? "Need to be playing race or CTS for lsnewmaps to work." : lsnewmaps_reply), "\n"));
for(i = 0; i < 10; ++i)
{
- records_reply[i] = strzone(getrecords(i));
+ s = getrecords(i);
+ if (s)
+ records_reply[i] = strzone(s);
}
-
+
ladder_reply = strzone(getladder());
rankings_reply = strzone(getrankings());
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
alreadychangedlevel = TRUE;
return TRUE;
}
- if (autocvar_samelevel) // if samelevel is set, stay on same level
+ if (!reinit && autocvar_samelevel) // if samelevel is set, stay on same level
{
localcmd("restart\n");
alreadychangedlevel = TRUE;
alreadychangedlevel = TRUE;
return TRUE;
}
- if(autocvar_lastlevel)
+ if(!reinit && autocvar_lastlevel)
{
cvar_settemp_restore();
localcmd("set lastlevel 0\ntogglemenu 1\n");
void IntermissionThink()
{
FixIntermissionClient(self);
-
+
float server_screenshot = (autocvar_sv_autoscreenshot && self.cvar_cl_autoscreenshot);
float client_screenshot = (self.cvar_cl_autoscreenshot == 2);
-
+
if( (server_screenshot || client_screenshot)
&& ((self.autoscreenshot > 0) && (time > self.autoscreenshot)) )
{
print(s, "\n");
if(to_eventlog)
GameLogEcho(s);
+
+ file = -1;
if(to_file)
{
file = fopen(autocvar_sv_logscores_filename, FILE_APPEND);
}
}
-
+void minstagib_stop_countdown(entity e);
/*
go to the next level for deathmatch
only called if a time or frag limit has expired
GameLogClose();
FOR_EACH_PLAYER(other) {
+ minstagib_stop_countdown(other);
FixIntermissionClient(other);
if(other.winning)
bprint(other.netname, " ^7wins.\n");
if(autocvar_g_campaign)
CampaignPreIntermission();
+ MUTATOR_CALLHOOK(MatchEnd);
+
localcmd("\nsv_hook_gameend\n");
}
// - for this timelimit_overtime needs to be >0 of course
// - also check the winning condition calculated in the previous frame and only add normal overtime
// again, if at the point at which timelimit would be extended again, still no winner was found
- if ((checkrules_overtimesadded >= 0) && (checkrules_overtimesadded < autocvar_timelimit_overtimes) && autocvar_timelimit_overtime && !(g_race && !g_race_qualifying))
+ if (!autocvar_g_campaign && (checkrules_overtimesadded >= 0) && (checkrules_overtimesadded < autocvar_timelimit_overtimes) && autocvar_timelimit_overtime && !(g_race && !g_race_qualifying))
{
return 1; // need to call InitiateOvertime later
}
{
if(!checkrules_suddendeathend)
{
- checkrules_suddendeathend = time + 60 * autocvar_timelimit_suddendeath;
+ if(autocvar_g_campaign)
+ checkrules_suddendeathend = time; // no suddendeath in campaign
+ else
+ checkrules_suddendeathend = time + 60 * autocvar_timelimit_suddendeath;
if(g_race && !g_race_qualifying)
race_StartCompleting();
}
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)
else if(team1_score + team2_score + team3_score + team4_score == 1)
{
float t, i;
- if(team1_score) t = COLOR_TEAM1;
- if(team2_score) t = COLOR_TEAM2;
- if(team3_score) t = COLOR_TEAM3;
- if(team4_score) t = COLOR_TEAM4;
+ if(team1_score)
+ t = COLOR_TEAM1;
+ else if(team2_score)
+ t = COLOR_TEAM2;
+ else if(team3_score)
+ t = COLOR_TEAM3;
+ else // if(team4_score)
+ t = COLOR_TEAM4;
CheckAllowedTeams(world);
for(i = 0; i < MAX_TEAMSCORE; ++i)
{
leadlimit = 0; // no leadlimit for now
}
- if(g_onslaught)
- timelimit = 0; // ONS has its own overtime rule
-
if(timelimit > 0)
{
timelimit += game_starttime;
return;
}
+ if(g_onslaught)
+ timelimit = 0; // ONS has its own overtime rule
+
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))
mapvote_maps[mapvote_count] = strzone(nextMap);
mapvote_maps_suggested[mapvote_count] = isSuggestion;
+ pakfile = string_null;
for(i = 0; i < mapvote_screenshot_dirs_count; ++i)
{
mapfile = strcat(mapvote_screenshot_dirs[i], "/", mapvote_maps[i]);
clients_found = 0;
FOR_EACH_REALCLIENT(self)
{
+ // TODO add timer
print("Redirecting: sending connect command to ", self.netname, "\n");
if(redirection_target == "self")
- stuffcmd(self, "\ndisconnect; reconnect\n");
+ stuffcmd(self, "\ndisconnect; defer ", ftos(autocvar_quit_and_redirect_timer), " reconnect\n");
else
- stuffcmd(self, strcat("\ndisconnect; connect ", redirection_target, "\n"));
+ stuffcmd(self, strcat("\ndisconnect; defer ", ftos(autocvar_quit_and_redirect_timer), " \"connect ", redirection_target, "\"\n"));
++clients_found;
}