#include "g_world.qh"
-#include "_all.qh"
#include "anticheat.qh"
#include "antilag.qh"
#include "g_hook.qh"
#include "ipban.qh"
#include "mapvoting.qh"
-#include "mutators/mutators_include.qh"
+#include "mutators/all.qh"
#include "race.qh"
#include "scores.qh"
#include "teamplay.qh"
#include "weapons/weaponstats.qh"
-#include "../common/buffs.qh"
+#include "../common/buffs/all.qh"
#include "../common/constants.qh"
-#include "../common/deathtypes.qh"
-#include "../common/effects.qh"
+#include "../common/deathtypes/all.qh"
#include "../common/mapinfo.qh"
#include "../common/monsters/all.qh"
#include "../common/monsters/sv_monsters.qh"
#include "../common/vehicles/all.qh"
#include "../common/notifications.qh"
+#include "../common/physics.qh"
#include "../common/playerstats.qh"
#include "../common/stats.qh"
#include "../common/teams.qh"
+#include "../common/triggers/trigger/secret.qh"
+#include "../common/triggers/target/music.qh"
#include "../common/util.qh"
#include "../common/items/all.qh"
#include "../common/weapons/all.qh"
.float latency_time;
entity pingplreport;
void PingPLReport_Think()
-{
+{SELFPARAM();
float delta;
entity e;
e = edict_num(self.cnt + 1);
if(IS_REAL_CLIENT(e))
{
- WriteByte(MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte(MSG_BROADCAST, TE_CSQC_PINGPLREPORT);
+ WriteHeader(MSG_BROADCAST, TE_CSQC_PINGPLREPORT);
WriteByte(MSG_BROADCAST, self.cnt);
WriteShort(MSG_BROADCAST, max(1, e.ping));
WriteByte(MSG_BROADCAST, ceil(e.ping_packetloss * 255));
}
else
{
- WriteByte(MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte(MSG_BROADCAST, TE_CSQC_PINGPLREPORT);
+ WriteHeader(MSG_BROADCAST, TE_CSQC_PINGPLREPORT);
WriteByte(MSG_BROADCAST, self.cnt);
WriteShort(MSG_BROADCAST, 0);
WriteByte(MSG_BROADCAST, 0);
}
void PingPLReport_Spawn()
{
- pingplreport = spawn();
- pingplreport.classname = "pingplreport";
+ pingplreport = new(pingplreport);
+ make_pure(pingplreport);
pingplreport.think = PingPLReport_Think;
pingplreport.nextthink = time;
}
}
void GotoFirstMap()
-{
+{SELFPARAM();
float n;
if(autocvar__sv_init)
{
else
{
self.nextthink = time + 1;
- print("Waiting for _sv_init being set to 1 by initialization scripts...\n");
+ LOG_INFO("Waiting for _sv_init being set to 1 by initialization scripts...\n");
}
}
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)
tracebox(o, '-1 -1 -1' * i, '1 1 1' * i, o - '0 0 32768', MOVE_WORLDONLY, world);
if(trace_fraction == 1)
continue;
- print(ftos(i), " -> ", vtos(trace_endpos), "\n");
+ LOG_INFO(ftos(i), " -> ", vtos(trace_endpos), "\n");
}
break;
}
entity randomseed;
-float RandomSeed_Send(entity to, int sf)
+bool RandomSeed_Send(entity this, entity to, int sf)
{
- WriteByte(MSG_ENTITY, ENT_CLIENT_RANDOMSEED);
+ WriteHeader(MSG_ENTITY, ENT_CLIENT_RANDOMSEED);
WriteShort(MSG_ENTITY, self.cnt);
return true;
}
void RandomSeed_Think()
-{
+{SELFPARAM();
self.cnt = bound(0, floor(random() * 65536), 65535);
self.nextthink = time + 5;
self.SendFlags |= 1;
}
void RandomSeed_Spawn()
-{
- randomseed = spawn();
+{SELFPARAM();
+ randomseed = new(randomseed);
+ make_pure(randomseed);
randomseed.think = RandomSeed_Think;
Net_LinkEntity(randomseed, false, 0, RandomSeed_Send);
- entity oldself;
- oldself = self;
- self = randomseed;
- self.think(); // sets random seed and nextthink
- self = oldself;
+ WITH(entity, self, randomseed, randomseed.think()); // sets random seed and nextthink
}
-void spawnfunc___init_dedicated_server(void)
+spawnfunc(__init_dedicated_server)
{
// handler for _init/_init map (only for dedicated server initialization)
remove = remove_unsafely;
- entity e;
- e = spawn();
+ entity e = spawn();
e.think = GotoFirstMap;
e.nextthink = time; // this is usually 1 at this point
- e = spawn();
- e.classname = "info_player_deathmatch"; // safeguard against player joining
+ e = new(info_player_deathmatch); // safeguard against player joining
self.classname = "worldspawn"; // safeguard against various stuff ;)
// needs to be done so early because of the constants they create
static_init();
- CALL_ACCUMULATED_FUNCTION(RegisterTurrets);
- CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
- CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
- CALL_ACCUMULATED_FUNCTION(RegisterEffects);
+ static_init_late();
+ static_init_precache();
MapInfo_Enumerate();
MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
void WeaponStats_Init();
void WeaponStats_Shutdown();
void Physics_AddStats();
-void spawnfunc_worldspawn (void)
+spawnfunc(worldspawn)
{
float fd, l, j, n;
string s;
// needs to be done so early because of the constants they create
static_init();
- CALL_ACCUMULATED_FUNCTION(RegisterTurrets);
- CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
- CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
- CALL_ACCUMULATED_FUNCTION(RegisterEffects);
-
- initialize_minigames();
ServerProgsDB = db_load(strcat("server.db", autocvar_sessionid));
PlayerStats_GameReport_Init(); // we need this to be initiated before InitGameplayMode
- precache_model ("null"); // we need this one before InitGameplayMode
InitGameplayMode();
+ static_init_late();
+ static_init_precache();
readlevelcvars();
GrappleHookInit();
MUTATOR_CALLHOOK(BuildMutatorsString, s);
s = ret_string;
- // simple, probably not good in the mutator system
- if(autocvar_g_grappling_hook)
- s = strcat(s, ":grappling_hook");
-
// initialiation stuff, not good in the mutator system
if(!autocvar_g_use_ammunition)
s = strcat(s, ":no_use_ammunition");
continue;
if(argv(0) == "cd")
{
- print("Found ^1UNSUPPORTED^7 cd loop command in .cfg file; put this line in mapinfo instead:\n");
- print(" cdtrack ", argv(2), "\n");
+ LOG_INFO("Found ^1UNSUPPORTED^7 cd loop command in .cfg file; put this line in mapinfo instead:\n");
+ LOG_INFO(" cdtrack ", argv(2), "\n");
}
else if(argv(0) == "fog")
{
- print("Found ^1UNSUPPORTED^7 fog command in .cfg file; put this line in worldspawn in the .map/.bsp/.ent file instead:\n");
- print(" \"fog\" \"", s, "\"\n");
+ LOG_INFO("Found ^1UNSUPPORTED^7 fog command in .cfg file; put this line in worldspawn in the .map/.bsp/.ent file instead:\n");
+ LOG_INFO(" \"fog\" \"", s, "\"\n");
}
else if(argv(0) == "set")
{
- print("Found ^1UNSUPPORTED^7 set command in .cfg file; put this line in mapinfo instead:\n");
- print(" clientsettemp_for_type all ", argv(1), " ", argv(2), "\n");
+ LOG_INFO("Found ^1UNSUPPORTED^7 set command in .cfg file; put this line in mapinfo instead:\n");
+ LOG_INFO(" clientsettemp_for_type all ", argv(1), " ", argv(2), "\n");
}
else if(argv(0) != "//")
{
- print("Found ^1UNSUPPORTED^7 set command in .cfg file; put this line in mapinfo instead:\n");
- print(" clientsettemp_for_type all ", argv(0), " ", argv(1), "\n");
+ LOG_INFO("Found ^1UNSUPPORTED^7 set command in .cfg file; put this line in mapinfo instead:\n");
+ LOG_INFO(" clientsettemp_for_type all ", argv(0), " ", argv(1), "\n");
}
}
fclose(fd);
world_initialized = 1;
}
-void spawnfunc_light (void)
+spawnfunc(light)
{
//makestatic (self); // Who the f___ did that?
remove(self);
if(currentbots || autocvar_bot_number || player_count < autocvar_minplayers)
if(autocvar_g_maplist_check_waypoints)
{
- dprint("checkwp "); dprint(map);
+ LOG_TRACE("checkwp "); LOG_TRACE(map);
if(!fexists(strcat("maps/", map, ".waypoints")))
{
- dprint(": no waypoints\n");
+ LOG_TRACE(": no waypoints\n");
return false;
}
- dprint(": has waypoints\n");
+ LOG_TRACE(": has waypoints\n");
}
// open map size restriction file
- dprint("opensize "); dprint(map);
+ LOG_TRACE("opensize "); LOG_TRACE(map);
fh = fopen(strcat("maps/", map, ".sizes"), FILE_READ);
if(fh >= 0)
{
float mapmin, mapmax;
- dprint(": ok, ");
+ LOG_TRACE(": ok, ");
mapmin = stof(fgets(fh));
mapmax = stof(fgets(fh));
fclose(fh);
if(player_count < mapmin)
{
- dprint("not enough\n");
+ LOG_TRACE("not enough\n");
return false;
}
if(player_count > mapmax)
{
- dprint("too many\n");
+ LOG_TRACE("too many\n");
return false;
}
- dprint("right size\n");
+ LOG_TRACE("right size\n");
return true;
}
- dprint(": not found\n");
+ LOG_TRACE(": not found\n");
return true;
}
return strcat("maps/", argv(position), ".bsp");
}
-string strwords(string s, float w)
-{
- float endpos;
- for(endpos = 0; w && endpos >= 0; --w)
- endpos = strstrofs(s, " ", endpos + 1);
- if(endpos < 0)
- return s;
- else
- return substring(s, 0, endpos);
-}
-
-float strhasword(string s, string w)
-{
- return strstrofs(strcat(" ", s, " "), strcat(" ", w, " "), 0) >= 0;
-}
-
void Map_MarkAsRecent(string m)
{
cvar_set("g_maplist_mostrecent", strwords(strcat(m, " ", autocvar_g_maplist_mostrecent), max(0, autocvar_g_maplist_mostrecent_count)));
return 0;
}
else
- dprint( "Couldn't select '", filename, "'..\n" );
+ LOG_TRACE( "Couldn't select '", filename, "'..\n" );
return 0;
}
{
float pass, i;
- dprint("Trying MaplistMethod_Iterate\n");
+ LOG_TRACE("Trying MaplistMethod_Iterate\n");
for(pass = 1; pass <= 2; ++pass)
{
float() MaplistMethod_Repeat = // fallback method
{
- dprint("Trying MaplistMethod_Repeat\n");
+ LOG_TRACE("Trying MaplistMethod_Repeat\n");
if(Map_Check(Map_Current, 2))
return Map_Current;
{
float i, imax;
- dprint("Trying MaplistMethod_Random\n");
+ LOG_TRACE("Trying MaplistMethod_Random\n");
imax = 42;
{
float i, j, imax, insertpos;
- dprint("Trying MaplistMethod_Shuffle\n");
+ LOG_TRACE("Trying MaplistMethod_Shuffle\n");
imax = 42;
insertpos = pow(random(), 1 / exponent); // ]0, 1]
insertpos = insertpos * (Map_Count - 1); // ]0, Map_Count - 1]
insertpos = ceil(insertpos) + 1; // {2, 3, 4, ..., Map_Count}
- dprint("SHUFFLE: insert pos = ", ftos(insertpos), "\n");
+ LOG_TRACE("SHUFFLE: insert pos = ", ftos(insertpos), "\n");
// insert the current map there
newlist = "";
*/
.float autoscreenshot;
void IntermissionThink()
-{
+{SELFPARAM();
FixIntermissionClient(self);
float server_screenshot = (autocvar_sv_autoscreenshot && self.cvar_cl_autoscreenshot);
s = strcat(s, GetGametype(), "_", GetMapname(), ":", ftos(rint(time)));
if(to_console)
- print(s, "\n");
+ LOG_INFO(s, "\n");
if(to_eventlog)
GameLogEcho(s);
s = strcat(":labels:player:", GetPlayerScoreString(world, 0));
if(to_console)
- print(s, "\n");
+ LOG_INFO(s, "\n");
if(to_eventlog)
GameLogEcho(s);
if(to_file)
{
s = strcat(":player:see-labels:", GetPlayerScoreString(other, 0), ":");
s = strcat(s, ftos(rint(time - other.jointime)), ":");
- if(IS_PLAYER(other) || other.caplayer == 1 || g_lms)
+ if(IS_PLAYER(other) || MUTATOR_CALLHOOK(GetPlayerStatus, other, s))
s = strcat(s, ftos(other.team), ":");
else
s = strcat(s, "spectator:");
if(to_console)
- print(s, other.netname, "\n");
+ LOG_INFO(s, other.netname, "\n");
if(to_eventlog)
GameLogEcho(strcat(s, ftos(other.playerid), ":", other.netname));
if(to_file)
{
s = strcat(":labels:teamscores:", GetTeamScoreString(0, 0));
if(to_console)
- print(s, "\n");
+ LOG_INFO(s, "\n");
if(to_eventlog)
GameLogEcho(s);
if(to_file)
s = strcat(":teamscores:see-labels:", GetTeamScoreString(i, 0));
s = strcat(s, ":", ftos(i));
if(to_console)
- print(s, "\n");
+ LOG_INFO(s, "\n");
if(to_eventlog)
GameLogEcho(s);
if(to_file)
}
if(to_console)
- print(":end\n");
+ LOG_INFO(":end\n");
if(to_eventlog)
GameLogEcho(":end");
if(to_file)
e.solid = SOLID_NOT;
e.movetype = MOVETYPE_NONE;
e.takedamage = DAMAGE_NO;
- if(e.weaponentity)
+ for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
- e.weaponentity.effects = EF_NODRAW;
- if (e.weaponentity.weaponentity)
- e.weaponentity.weaponentity.effects = EF_NODRAW;
+ .entity weaponentity = weaponentities[slot];
+ if(e.(weaponentity))
+ {
+ e.(weaponentity).effects = EF_NODRAW;
+ if (e.(weaponentity).(weaponentity))
+ e.(weaponentity).(weaponentity).effects = EF_NODRAW;
+ }
}
if(IS_REAL_CLIENT(e))
{
bprint(other.netname, " ^7wins.\n");
}
+ entity oldself = self;
+ target_music_kill();
+ self = oldself;
+
if(autocvar_g_campaign)
CampaignPreIntermission();
============
*/
void CheckRules_Player()
-{
+{SELFPARAM();
if (gameover) // someone else quit the game already
return;
// they win. Otherwise the defending team wins once the timelimit passes.
void assault_new_round();
float WinningCondition_Assault()
-{
+{SELFPARAM();
float status;
WinningConditionHelper(); // set worldstatus
}
else
{
- entity oldself;
- oldself = self;
- self = ent;
- assault_new_round();
- self = oldself;
+ WITH(entity, self, ent, assault_new_round());
}
}
}
return status;
}
-// LMS winning condition: game terminates if and only if there's at most one
-// one player who's living lives. Top two scores being equal cancels the time
-// limit.
-float WinningCondition_LMS()
-{
- entity head, head2;
- float have_player;
- float have_players;
- float l;
-
- have_player = false;
- have_players = false;
- l = LMS_NewPlayerLives();
-
- head = find(world, classname, "player");
- if(head)
- have_player = true;
- head2 = find(head, classname, "player");
- if(head2)
- have_players = true;
-
- if(have_player)
- {
- // we have at least one player
- if(have_players)
- {
- // two or more active players - continue with the game
- }
- else
- {
- // exactly one player?
-
- ClearWinners();
- SetWinners(winning, 0); // NOTE: exactly one player is still "player", so this works out
-
- if(l)
- {
- // game still running (that is, nobody got removed from the game by a frag yet)? then continue
- return WINNING_NO;
- }
- else
- {
- // a winner!
- // and assign him his first place
- PlayerScore_Add(head, SP_LMS_RANK, 1);
- return WINNING_YES;
- }
- }
- }
- else
- {
- // nobody is playing at all...
- if(l)
- {
- // wait for players...
- }
- else
- {
- // SNAFU (maybe a draw game?)
- ClearWinners();
- dprint("No players, ending game.\n");
- return WINNING_YES;
- }
- }
-
- // When we get here, we have at least two players who are actually LIVING,
- // now check if the top two players have equal score.
- WinningConditionHelper();
-
- ClearWinners();
- if(WinningConditionHelper_winner)
- WinningConditionHelper_winner.winning = true;
- if(WinningConditionHelper_topscore == WinningConditionHelper_secondscore)
- return WINNING_NEVER;
-
- // Top two have different scores? Way to go for our beloved TIMELIMIT!
- return WINNING_NO;
-}
-
void ShuffleMaplist()
{
cvar_set("g_maplist", shufflewords(autocvar_g_maplist));
if(WinningConditionHelper_zeroisworst)
leadlimit = 0; // not supported in this mode
- if(g_dm || g_tdm || g_ca || g_freezetag || (g_race && !g_race_qualifying) || g_nexball)
+ if(MUTATOR_CALLHOOK(Scores_CountFragsRemaining))
// these modes always score in increments of 1, thus this makes sense
{
if(leaderfrags != WinningConditionHelper_topscore)
return;
}
- float checkrules_status;
- checkrules_status = WinningCondition_RanOutOfSpawns();
+ int checkrules_status = WinningCondition_RanOutOfSpawns();
if(checkrules_status == WINNING_YES)
- {
bprint("Hey! Someone ran out of spawns!\n");
- }
- else if(g_race && !g_race_qualifying && timelimit >= 0)
- {
- checkrules_status = WinningCondition_Race(fraglimit);
- //print("WC_RACE yields ", ftos(checkrules_status), "\n");
- }
- else if(g_race && g_race_qualifying == 2 && timelimit >= 0)
- {
- checkrules_status = WinningCondition_QualifyingThenRace(fraglimit);
- //print("WC_QUALIFYING_THEN_RACE yields ", ftos(checkrules_status), "\n");
- }
- else if(g_assault)
- {
- checkrules_status = WinningCondition_Assault(); // TODO remove this?
- }
- else if(g_lms)
- {
- checkrules_status = WinningCondition_LMS();
- }
+ else if(MUTATOR_CALLHOOK(CheckRules_World, checkrules_status, timelimit, fraglimit))
+ checkrules_status = ret_float;
else
- {
checkrules_status = WinningCondition_Scores(fraglimit, leadlimit);
- //print("WC_SCORES yields ", ftos(checkrules_status), "\n");
- }
if(checkrules_status == WINNING_STARTSUDDENDEATHOVERTIME)
{
void EndFrame()
-{
+{SELFPARAM();
anticheat_endframe();
float altime;
- FOR_EACH_REALCLIENT(self)
+ entity e_;
+ FOR_EACH_REALCLIENT(e_)
{
- entity e = IS_SPEC(self) ? self.enemy : self;
+ entity e = IS_SPEC(e_) ? e_.enemy : e_;
if(e.typehitsound)
- self.typehit_time = time;
+ e_.typehit_time = time;
else if(e.damage_dealt)
{
- self.hit_time = time;
- self.damage_dealt_total += ceil(e.damage_dealt);
+ e_.hit_time = time;
+ e_.damage_dealt_total += ceil(e.damage_dealt);
}
}
altime = time + frametime * (1 + autocvar_g_antilag_nudge);
// add another frametime because client shows everything with
// 1 frame of lag (cl_nolerp 0). The last +1 however should not be
// needed!
- FOR_EACH_CLIENT(self)
+ FOR_EACH_CLIENT(e_)
{
- self.typehitsound = false;
- self.damage_dealt = 0;
- antilag_record(self, altime);
+ e_.typehitsound = false;
+ e_.damage_dealt = 0;
+ setself(e_);
+ antilag_record(e_, altime);
+ }
+ FOR_EACH_MONSTER(e_)
+ {
+ setself(e_);
+ antilag_record(e_, altime);
}
- FOR_EACH_MONSTER(self)
- antilag_record(self, altime);
}
float redirection_timeout;
float redirection_nextthink;
float RedirectionThink()
-{
+{SELFPARAM();
float clients_found;
if(redirection_target == "")
redirection_nextthink = time + 1;
clients_found = 0;
- FOR_EACH_REALCLIENT(self)
+ entity e;
+ FOR_EACH_REALCLIENT(e)
{
+ setself(e);
// TODO add timer
- print("Redirecting: sending connect command to ", self.netname, "\n");
+ LOG_INFO("Redirecting: sending connect command to ", self.netname, "\n");
if(redirection_target == "self")
stuffcmd(self, "\ndisconnect; defer ", ftos(autocvar_quit_and_redirect_timer), " reconnect\n");
else
++clients_found;
}
- print("Redirecting: ", ftos(clients_found), " clients left.\n");
+ LOG_INFO("Redirecting: ", ftos(clients_found), " clients left.\n");
if(time > redirection_timeout || clients_found == 0)
localcmd("\nwait; wait; wait; quit\n");
if(world_initialized > 0)
{
world_initialized = 0;
- print("Saving persistent data...\n");
+ LOG_INFO("Saving persistent data...\n");
Ban_SaveBans();
// playerstats with unfinished match
CheatShutdown(); // must be after cheatcount check
db_close(ServerProgsDB);
db_close(TemporaryDB);
- print("done!\n");
+ LOG_INFO("done!\n");
// tell the bot system the game is ending now
bot_endgame();
}
else if(world_initialized == 0)
{
- print("NOTE: crashed before even initializing the world, not saving persistent data\n");
+ LOG_INFO("NOTE: crashed before even initializing the world, not saving persistent data\n");
}
}