#include "../common/monsters/all.qh"
#include "../common/monsters/sv_monsters.qh"
#include "../common/vehicles/all.qh"
-#include "../common/notifications.qh"
+#include "../common/notifications/all.qh"
#include "../common/physics/player.qh"
#include "../common/playerstats.qh"
#include "../common/stats.qh"
#include "../common/util.qh"
#include "../common/items/all.qh"
#include "../common/weapons/all.qh"
+#include "../common/state.qh"
const float LATENCY_THINKRATE = 10;
.float latency_sum;
delta = 3 / maxclients;
if(delta < sys_frametime)
delta = 0;
- self.nextthink = time + delta;
+ this.nextthink = time + delta;
- e = edict_num(self.cnt + 1);
+ e = edict_num(this.cnt + 1);
if(IS_REAL_CLIENT(e))
{
WriteHeader(MSG_BROADCAST, TE_CSQC_PINGPLREPORT);
- WriteByte(MSG_BROADCAST, self.cnt);
+ WriteByte(MSG_BROADCAST, this.cnt);
WriteShort(MSG_BROADCAST, max(1, e.ping));
WriteByte(MSG_BROADCAST, ceil(e.ping_packetloss * 255));
WriteByte(MSG_BROADCAST, ceil(e.ping_movementloss * 255));
else
{
WriteHeader(MSG_BROADCAST, TE_CSQC_PINGPLREPORT);
- WriteByte(MSG_BROADCAST, self.cnt);
+ WriteByte(MSG_BROADCAST, this.cnt);
WriteShort(MSG_BROADCAST, 0);
WriteByte(MSG_BROADCAST, 0);
WriteByte(MSG_BROADCAST, 0);
}
- self.cnt = (self.cnt + 1) % maxclients;
+ this.cnt = (this.cnt + 1) % maxclients;
}
void PingPLReport_Spawn()
{
- pingplreport = new(pingplreport);
- make_pure(pingplreport);
+ pingplreport = new_pure(pingplreport);
pingplreport.think = PingPLReport_Think;
pingplreport.nextthink = time;
}
BADPREFIX("g_chat_flood_");
BADPREFIX("g_ghost_items");
BADPREFIX("g_playerstats_");
- BADPREFIX("g_respawn_ghosts");
BADPREFIX("g_voice_flood_");
BADPREFIX("log_file");
BADPREFIX("rcon_");
BADCVAR("g_nexball");
BADCVAR("g_onslaught");
BADCVAR("g_race");
+ BADCVAR("g_race_laps_limit");
BADCVAR("g_race_qualifying_timelimit");
+ BADCVAR("g_race_qualifying_timelimit_override");
BADCVAR("g_tdm");
BADCVAR("g_tdm_teams");
BADCVAR("leadlimit");
// now check if the changes are actually gameplay relevant
- // does nothing visible
+ // does nothing gameplay relevant
BADCVAR("captureleadlimit_override");
+ BADCVAR("gameversion");
+ BADCVAR("g_allow_oldvortexbeam");
BADCVAR("g_balance_kill_delay");
- BADCVAR("g_ca_point_limit");
+ BADCVAR("g_campcheck_distance");
BADCVAR("g_ca_point_leadlimit");
+ BADCVAR("g_ca_point_limit");
BADCVAR("g_ctf_captimerecord_always");
BADCVAR("g_ctf_flag_glowtrails");
BADCVAR("g_ctf_flag_pickup_verbosename");
BADCVAR("g_domination_point_leadlimit");
BADCVAR("g_forced_respawn");
- BADCVAR("g_freezetag_point_limit");
BADCVAR("g_freezetag_point_leadlimit");
- BADCVAR("g_keyhunt_point_leadlimit");
- BADPREFIX("g_mod_");
+ BADCVAR("g_freezetag_point_limit");
+ BADCVAR("g_hats");
BADCVAR("g_invasion_point_limit");
+ BADCVAR("g_keyhunt_point_leadlimit");
BADCVAR("g_nexball_goalleadlimit");
- BADCVAR("g_tdm_point_limit");
BADCVAR("g_tdm_point_leadlimit");
+ BADCVAR("g_tdm_point_limit");
BADCVAR("leadlimit_and_fraglimit");
BADCVAR("leadlimit_override");
BADCVAR("pausable");
BADCVAR("sv_allow_fullbright");
BADCVAR("sv_checkforpacketsduringsleep");
+ BADCVAR("sv_intermission_cdtrack");
+ BADCVAR("sv_minigames");
+ BADCVAR("sv_namechangetimer");
+ BADCVAR("sv_precacheplayermodels");
BADCVAR("sv_timeout");
- BADPREFIX("sv_timeout_");
BADPREFIX("crypto_");
+ BADPREFIX("gameversion_");
BADPREFIX("g_chat_");
BADPREFIX("g_ctf_captimerecord_");
BADPREFIX("g_maplist_votable_");
+ BADPREFIX("g_mod_");
+ BADPREFIX("g_respawn_");
BADPREFIX("net_");
BADPREFIX("prvm_");
BADPREFIX("skill_");
BADPREFIX("sv_cullentities_");
BADPREFIX("sv_maxidle_");
+ BADPREFIX("sv_minigames_");
+ BADPREFIX("sv_timeout_");
BADPREFIX("sv_vote_");
BADPREFIX("timelimit_");
- BADCVAR("gameversion");
- BADPREFIX("gameversion_");
- BADCVAR("sv_minigames");
- BADPREFIX("sv_minigames_");
- BADCVAR("sv_namechangetimer");
// allowed changes to server admins (please sync this to server.cfg)
// vi commands:
BADCVAR("g_mirrordamage");
BADCVAR("g_nexball_goallimit");
BADCVAR("g_powerups");
+ BADCVAR("g_spawnshieldtime");
BADCVAR("g_start_delay");
+ BADCVAR("g_superspectate");
BADCVAR("g_tdm_teams_override");
BADCVAR("g_warmup");
BADCVAR("g_weapon_stay"); BADPRESUFFIX("g_", "_weapon_stay");
BADCVAR("sv_vote_simple_majority_factor");
BADCVAR("teamplay_mode");
BADCVAR("timelimit_override");
- BADCVAR("g_spawnshieldtime");
BADPREFIX("g_warmup_");
BADPREFIX("sv_ready_restart_");
bool RandomSeed_Send(entity this, entity to, int sf)
{
WriteHeader(MSG_ENTITY, ENT_CLIENT_RANDOMSEED);
- WriteShort(MSG_ENTITY, self.cnt);
+ WriteShort(MSG_ENTITY, this.cnt);
return true;
}
void RandomSeed_Think()
{SELFPARAM();
- self.cnt = bound(0, floor(random() * 65536), 65535);
- self.nextthink = time + 5;
+ this.cnt = bound(0, floor(random() * 65536), 65535);
+ this.nextthink = time + 5;
- self.SendFlags |= 1;
+ this.SendFlags |= 1;
}
void RandomSeed_Spawn()
{SELFPARAM();
- randomseed = new(randomseed);
- make_pure(randomseed);
+ randomseed = new_pure(randomseed);
randomseed.think = RandomSeed_Think;
Net_LinkEntity(randomseed, false, 0, RandomSeed_Send);
- WITH(entity, self, randomseed, randomseed.think()); // sets random seed and nextthink
+ WITHSELF(randomseed, randomseed.think()); // sets random seed and nextthink
}
spawnfunc(__init_dedicated_server)
MapInfo_Shutdown();
}
+void SetLimits(int fraglimit_override, int leadlimit_override, float timelimit_override, float qualifying_override)
+{
+ if(!autocvar_g_campaign)
+ {
+ if(fraglimit_override >= 0) cvar_set("fraglimit", ftos(fraglimit_override));
+ if(timelimit_override >= 0) cvar_set("timelimit", ftos(timelimit_override));
+ if(leadlimit_override >= 0) cvar_set("leadlimit", ftos(leadlimit_override));
+ if(qualifying_override >= 0) cvar_set("g_race_qualifying_timelimit", ftos(qualifying_override));
+ }
+ limits_are_set = true;
+}
+
void Map_MarkAsRecent(string m);
float world_already_spawned;
void Nagger_Init();
if (!server_is_dedicated)
{
// force unloading of server pk3 files when starting a listen server
- localcmd("\nfs_rescan\n");
+ // localcmd("\nfs_rescan\n"); // FIXME: does more harm than good, has unintended side effects. What we really want is to unload temporary pk3s only
// restore csqc_progname too
string expect = "csprogs.dat";
wantrestart = cvar_string_normal("csqc_progname") != expect;
// Only ever use versioned csprogs.dat files on dedicated servers;
// we need to reset csqc_progname on clients ourselves, and it's easier if the client's release name is constant
string pk3csprogs = "csprogs-" WATERMARK ".dat";
- if (cvar_string_normal("csqc_progname") != pk3csprogs && fexists(pk3csprogs))
+ // This always works; fall back to it if a versioned csprogs.dat is suddenly missing
+ string select = "csprogs.dat";
+ if (fexists(pk3csprogs)) select = pk3csprogs;
+ if (cvar_string_normal("csqc_progname") != select)
{
- cvar_set_normal("csqc_progname", pk3csprogs);
+ cvar_set_normal("csqc_progname", select);
wantrestart = true;
}
// Check for updates on startup
}
}
}
- if (wantrestart) changelevel(mapname);
- // let initialization continue, shutdown depends on it
+ if (wantrestart)
+ {
+ LOG_INFOF("Restart requested\n");
+ changelevel(mapname);
+ // let initialization continue, shutdown depends on it
+ }
}
float fd, l;
readlevelcvars();
GrappleHookInit();
+ if(!limits_are_set)
+ SetLimits(autocvar_fraglimit_override, autocvar_leadlimit_override, autocvar_timelimit_override, -1);
+
+ if(warmup_limit == 0)
+ warmup_limit = (autocvar_timelimit > 0) ? autocvar_timelimit * 60 : autocvar_timelimit;
+
player_count = 0;
bot_waypoints_for_items = autocvar_g_waypoints_for_items;
if(bot_waypoints_for_items == 1)
return;
if(!mapvote_initialized)
- if (time < intermission_exittime + 10 && !(self.BUTTON_ATCK || self.BUTTON_JUMP || self.BUTTON_ATCK2 || self.BUTTON_HOOK || self.BUTTON_USE))
+ if (time < intermission_exittime + 10 && !(PHYS_INPUT_BUTTON_ATCK(self) || PHYS_INPUT_BUTTON_JUMP(self) || PHYS_INPUT_BUTTON_ATCK2(self) || PHYS_INPUT_BUTTON_HOOK(self) || PHYS_INPUT_BUTTON_USE(self)))
return;
MapVote_Start();
*/
void NextLevel()
{
+ SELFPARAM();
gameover = true;
intermission_running = 1;
PlayerStats_GameReport(true);
WeaponStats_Shutdown();
- Kill_Notification(NOTIF_ALL, world, MSG_CENTER, 0); // kill all centerprints now
+ Kill_Notification(NOTIF_ALL, world, MSG_CENTER, CPID_Null); // kill all centerprints now
if(autocvar_sv_eventlog)
GameLogEcho(":gameover");
bprint(it.netname, " ^7wins.\n");
));
- entity oldself = self;
- target_music_kill();
- self = oldself;
+ WITHSELF(NULL, target_music_kill());
if(autocvar_g_campaign)
CampaignPreIntermission();
if (gameover) // someone else quit the game already
return;
- if(!IS_DEAD(self))
- self.play_time += frametime;
+ if(!IS_DEAD(this))
+ this.play_time += frametime;
// fixme: don't check players; instead check spawnfunc_dom_team and spawnfunc_ctf_team entities
// (div0: and that in CheckRules_World please)
FOREACH_CLIENT(IS_PLAYER(it), LAMBDA(it.winning = 0));
}
-// Assault winning condition: If the attackers triggered a round end (by fulfilling all objectives)
-// they win. Otherwise the defending team wins once the timelimit passes.
-void assault_new_round();
-float WinningCondition_Assault()
-{SELFPARAM();
- float status;
-
- WinningConditionHelper(); // set worldstatus
-
- status = WINNING_NO;
- // as the timelimit has not yet passed just assume the defending team will win
- if(assault_attacker_team == NUM_TEAM_1)
- {
- SetWinners(team, NUM_TEAM_2);
- }
- else
- {
- SetWinners(team, NUM_TEAM_1);
- }
-
- entity ent;
- ent = find(world, classname, "target_assault_roundend");
- if(ent)
- {
- if(ent.winning) // round end has been triggered by attacking team
- {
- bprint("ASSAULT: round completed...\n");
- SetWinners(team, assault_attacker_team);
-
- TeamScore_AddToTeam(assault_attacker_team, ST_ASSAULT_OBJECTIVES, 666 - TeamScore_AddToTeam(assault_attacker_team, ST_ASSAULT_OBJECTIVES, 0));
-
- if(ent.cnt == 1 || autocvar_g_campaign) // this was the second round
- {
- status = WINNING_YES;
- }
- else
- {
- WITH(entity, self, ent, assault_new_round());
- }
- }
- }
-
- return status;
-}
-
void ShuffleMaplist()
{
cvar_set("g_maplist", shufflewords(autocvar_g_maplist));
void EndFrame()
-{SELFPARAM();
+{
anticheat_endframe();
- float altime;
- FOREACH_CLIENT(IS_REAL_CLIENT(it), LAMBDA(
+ FOREACH_CLIENT(IS_REAL_CLIENT(it), {
entity e = IS_SPEC(it) ? it.enemy : it;
- if(e.typehitsound)
+ if (e.typehitsound) {
it.typehit_time = time;
- else if(e.damage_dealt)
- {
+ } else if (e.damage_dealt) {
it.hit_time = time;
it.damage_dealt_total += ceil(e.damage_dealt);
}
- ));
- altime = time + frametime * (1 + autocvar_g_antilag_nudge);
+ });
// add 1 frametime because after this, engine SV_Physics
// increases time by a frametime and then networks the frame
// add another frametime because client shows everything with
// 1 frame of lag (cl_nolerp 0). The last +1 however should not be
// needed!
- FOREACH_CLIENT(true, LAMBDA(
+ float altime = time + frametime * (1 + autocvar_g_antilag_nudge);
+ FOREACH_CLIENT(true, {
it.typehitsound = false;
it.damage_dealt = 0;
- setself(it);
- antilag_record(it, altime);
- ));
- FOREACH_ENTITY_FLAGS(flags, FL_MONSTER, LAMBDA(
- setself(it);
- antilag_record(it, altime);
- ));
- FOREACH_CLIENT(PS(it), LAMBDA(
+ antilag_record(it, CS(it), altime);
+ });
+ FOREACH_ENTITY_FLAGS(flags, FL_MONSTER, {
+ antilag_record(it, it, altime);
+ });
+ FOREACH_CLIENT(PS(it), {
PlayerState s = PS(it);
s.ps_push(s, it);
- ));
+ });
}