r2266 - branches/nexuiz-2.0/data/qcsrc/server
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Wed Mar 28 08:32:54 EDT 2007
Author: div0
Date: 2007-03-28 08:32:53 -0400 (Wed, 28 Mar 2007)
New Revision: 2266
Modified:
branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc
branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc
branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc
branches/nexuiz-2.0/data/qcsrc/server/ctf.qc
branches/nexuiz-2.0/data/qcsrc/server/defs.qh
branches/nexuiz-2.0/data/qcsrc/server/domination.qc
branches/nexuiz-2.0/data/qcsrc/server/g_world.qc
branches/nexuiz-2.0/data/qcsrc/server/havocbot_roles.qc
branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc
branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc
Log:
map voting; simple majority; vote nagging; FOR_EACH_PLAYER
Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc 2007-03-28 10:14:16 UTC (rev 2265)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc 2007-03-28 12:32:53 UTC (rev 2266)
@@ -653,6 +653,25 @@
Damage(self, self, self, 100000, DEATH_KILL, self.origin, '0 0 0');
}
+void FixClientCvars(entity e)
+{
+ // send prediction settings to the client
+ stuffcmd(e, "\nin_bindmap 0 0\n");
+ stuffcmd(e, strcat("cl_gravity ", ftos(cvar("sv_gravity")), "\n"));
+ stuffcmd(e, strcat("cl_movement_accelerate ", ftos(cvar("sv_accelerate")), "\n"));
+ stuffcmd(e, strcat("cl_movement_friction ", ftos(cvar("sv_friction")), "\n"));
+ stuffcmd(e, strcat("cl_movement_maxspeed ", ftos(cvar("sv_maxspeed")), "\n"));
+ stuffcmd(e, strcat("cl_movement_airaccelerate ", ftos(cvar("sv_airaccelerate")), "\n"));
+ stuffcmd(e, strcat("cl_movement_maxairspeed ", ftos(cvar("sv_maxairspeed")), "\n"));
+ stuffcmd(e, strcat("cl_movement_stopspeed ", ftos(cvar("sv_stopspeed")), "\n"));
+ stuffcmd(e, strcat("cl_movement_jumpvelocity ", ftos(cvar("g_balance_jumpheight")), "\n"));
+ stuffcmd(e, strcat("cl_movement_stepheight ", ftos(cvar("sv_stepheight")), "\n"));
+ stuffcmd(e, strcat("set cl_movement_friction_on_land ", ftos(cvar("sv_friction_on_land")), "\n"));
+ stuffcmd(e, strcat("set cl_movement_airaccel_qw ", ftos(cvar("sv_airaccel_qw")), "\n"));
+ stuffcmd(e, strcat("set cl_movement_airaccel_sideways_friction ", ftos(cvar("sv_airaccel_sideways_friction")), "\n"));
+ stuffcmd(e, strcat("cl_movement_edgefriction 1\n"));
+}
+
/*
=============
ClientConnect
@@ -722,19 +741,8 @@
// TODO: is this being used for anything else than cd tracks?
// Remember: SVC_CDTRACK exists. Maybe it should be used.
- // send prediction settings to the client
- stuffcmd(self, strcat("cl_movement_accelerate ", ftos(cvar("sv_accelerate")), "\n"));
- stuffcmd(self, strcat("cl_movement_friction ", ftos(cvar("sv_friction")), "\n"));
- stuffcmd(self, strcat("cl_movement_maxspeed ", ftos(cvar("sv_maxspeed")), "\n"));
- stuffcmd(self, strcat("cl_movement_airaccelerate ", ftos(cvar("sv_airaccelerate")), "\n"));
- stuffcmd(self, strcat("cl_movement_maxairspeed ", ftos(cvar("sv_maxairspeed")), "\n"));
- stuffcmd(self, strcat("cl_movement_stopspeed ", ftos(cvar("sv_stopspeed")), "\n"));
- stuffcmd(self, strcat("cl_movement_jumpvelocity ", ftos(cvar("g_balance_jumpheight")), "\n"));
- stuffcmd(self, strcat("cl_movement_stepheight ", ftos(cvar("sv_stepheight")), "\n"));
- stuffcmd(self, strcat("set cl_movement_friction_on_land ", ftos(cvar("sv_friction_on_land")), "\n"));
- stuffcmd(self, strcat("set cl_movement_airaccel_qw ", ftos(cvar("sv_airaccel_qw")), "\n"));
- stuffcmd(self, strcat("set cl_movement_airaccel_sideways_friction ", ftos(cvar("sv_airaccel_sideways_friction")), "\n"));
- stuffcmd(self, strcat("cl_movement_edgefriction 0\n"));
+ FixClientCvars(self);
+
// Wazat's grappling hook
SetGrappleHookBindings();
@@ -1335,6 +1343,7 @@
=============
*/
void() ctf_setstatus;
+.float vote_nagtime;
void PlayerPreThink (void)
{
// version nagging
@@ -1351,6 +1360,14 @@
self.version_nagtime = 0;
}
+ // vote nagging
+ if(self.cvar_scr_centertime)
+ if(time > self.vote_nagtime)
+ {
+ VoteNag();
+ self.vote_nagtime = time + self.cvar_scr_centertime * 0.6;
+ }
+
if(self.classname == "player") {
local vector m1, m2;
@@ -1545,10 +1562,12 @@
if (self.flags & FL_JUMPRELEASED) {
if (self.button2 && self.version == cvar("gameversion")) {
+ self.welcomemessage_time = 0;
self.flags = self.flags - FL_JUMPRELEASED;
LeaveSpectatorMode();
return;
} else if(self.button0 && self.version == cvar("gameversion")) {
+ self.welcomemessage_time = 0;
self.flags = self.flags - FL_JUMPRELEASED;
if(SpectateNext() == 1) {
self.classname = "spectator";
@@ -1563,10 +1582,12 @@
} else if(self.classname == "spectator") {
if (self.flags & FL_JUMPRELEASED) {
if (self.button2 && self.version == cvar("gameversion")) {
+ self.welcomemessage_time = 0;
self.flags = self.flags - FL_JUMPRELEASED;
LeaveSpectatorMode();
return;
} else if(self.button0) {
+ self.welcomemessage_time = 0;
self.flags = self.flags - FL_JUMPRELEASED;
if(SpectateNext() == 1) {
self.classname = "spectator";
@@ -1575,6 +1596,7 @@
PutClientInServer();
}
} else if (self.button3) {
+ self.welcomemessage_time = 0;
self.flags = self.flags - FL_JUMPRELEASED;
self.classname = "observer";
PutClientInServer();
Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc 2007-03-28 10:14:16 UTC (rev 2265)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc 2007-03-28 12:32:53 UTC (rev 2266)
@@ -455,7 +455,7 @@
// 2. if we don't have a cursor trace, find the player which is least
// mis-aimed at
entity p;
- for(p = find(world, classname, "player"); p; p = find(p, classname, "player"))
+ FOR_EACH_PLAYER(p)
{
float c;
c = UpdateSelectedPlayer_canSee(p, selected_score, 100); // 100 = 2.5 meters
Modified: branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc 2007-03-28 10:14:16 UTC (rev 2265)
+++ branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc 2007-03-28 12:32:53 UTC (rev 2266)
@@ -1,6 +1,7 @@
void ReadyCount();
float ValidateMap(string vote);
void(entity e) DropFlag;
+string MapVote_Suggest(string m);
void Say(entity source, float teamsay, string msgin)
{
@@ -17,6 +18,9 @@
if(!teams_matter)
teamsay = FALSE;
+ if(intermission_running)
+ teamsay = FALSE;
+
if(source.classname != "player") // observers can't
teamsay = FALSE;
@@ -36,44 +40,22 @@
else
msgstr = strzone(strcat("\{1}^3", source.netname, "^7: ", msgin, "\n"));
- head = find(world, classname, "player");
- while(head)
+ if(teamsay)
{
- if(clienttype(head) == CLIENTTYPE_REAL)
- if(!teamsay || (head.team == source.team))
- {
- sprint(head, msgstr);
- if(teamsay)
- centerprint(head, cmsgstr);
- //stuffcmd(head, "play2 misc/talk.wav\n");
- }
- head = find(head, classname, "player");
- }
-
- if(!teamsay)
- {
- head = find(world, classname, "observer");
- while(head)
+ FOR_EACH_REALPLAYER(head)
{
- if(clienttype(head) == CLIENTTYPE_REAL)
+ if(head.team == source.team)
{
sprint(head, msgstr);
- //stuffcmd(head, "play2 misc/talk.wav\n");
+ centerprint(head, cmsgstr);
}
- head = find(head, classname, "observer");
}
- head = find(world, classname, "spectator");
- while(head)
- {
- if(clienttype(head) == CLIENTTYPE_REAL)
- {
- sprint(head, msgstr);
- //stuffcmd(head, "play2 misc/talk.wav\n");
- }
- head = find(head, classname, "spectator");
- }
- ServerConsoleEcho(substring(msgstr, 1, strlen(msgstr) - 2), TRUE);
}
+ else
+ {
+ bprint(msgstr);
+ //ServerConsoleEcho(substring(msgstr, 1, strlen(msgstr) - 2), TRUE);
+ }
strunzone(msgstr);
}
@@ -330,6 +312,8 @@
sprint(self, strcat(col, argv(i), " "));
}
sprint(self, "\n");
+ } else if(argv(0) == "teamstatus") {
+ PrintScoreboard(self);
} else if(argv(0) == "say") {
Say(self, FALSE, substring(s, 4, strlen(s) - 4));
//clientcommand(self, formatmessage(s));
@@ -342,6 +326,8 @@
sprint(self, "ERROR: unsupported info command\n");
else
wordwrap_sprint(cmd, 1111);
+ } else if(argv(0) == "suggestmap") {
+ sprint(self, strcat(MapVote_Suggest(argv(1)), "\n"));
} else {
cmd = argv(0);
/* checks not needed any more since DP has separated clientcommands and regular commands
@@ -453,26 +439,12 @@
}
void VoteReset() {
- local string searchclass;
- searchclass = "player";
+ local entity player;
- while (TRUE)
+ FOR_EACH_CLIENT(player)
{
- local entity player;
- player = find(player, classname, searchclass);
- while(player)
- {
- player.vote_vote = 0;
- player = find(player, classname, searchclass);
- }
-
- if("player" == searchclass) {
- searchclass = "observer";
- } else if("observer" == searchclass) {
- searchclass = "spectator";
- } else {
- break;
- }
+ player.vote_vote = 0;
+ centerprint_expire(player, CENTERPRIO_VOTE);
}
votecalled = FALSE;
@@ -511,6 +483,12 @@
VoteReset();
}
+void VoteNag() {
+ if(votecalled)
+ if(self.vote_vote == 0)
+ centerprint_atprio(self, CENTERPRIO_VOTE, strcat("^7^3", votecaller.netname, "^2 called a vote for:\n^1", votecalledvote, "\n\n^2You have not voted yet!\n^2HINT: By default, F1 is yes and F2 is no."));
+}
+
void VoteCount() {
local float playercount;
playercount = 0;
@@ -518,34 +496,16 @@
yescount = 0;
local float nocount;
nocount = 0;
- local string searchclass;
- searchclass = "player";
+ local entity player;
- while (TRUE)
+ FOR_EACH_REALCLIENT(player)
{
- local entity player;
- player = find(player, classname, searchclass);
-
- while(player)
- {
- if(clienttype(player) != CLIENTTYPE_BOT) {
- if(player.vote_vote < 0) {
- nocount++;
- } else if(player.vote_vote > 0) {
- yescount++;
- }
- playercount++;
- }
- player = find(player, classname, searchclass);
+ if(player.vote_vote < 0) {
+ nocount++;
+ } else if(player.vote_vote > 0) {
+ yescount++;
}
-
- if("player" == searchclass) {
- searchclass = "observer";
- } else if("observer" == searchclass) {
- searchclass = "specator";
- } else {
- break;
- }
+ playercount++;
}
if((playercount == 1) && votecalledmaster) {
@@ -563,7 +523,15 @@
} else if((playercount / 2) < nocount) { // vote rejected
VoteReject();
} else if(time > votefinished) { // vote timedout
- VoteTimeout();
+ if(cvar("sv_vote_simple_majority"))
+ if(yescount > nocount)
+ VoteAccept();
+ else if(nocount > yescount)
+ VoteReject();
+ else
+ VoteTimeout();
+ else
+ VoteTimeout();
} // else still running
}
@@ -573,16 +541,11 @@
local entity e;
local float r, p;
- e = find(world, classname, "player");
-
- while(e)
+ FOR_EACH_REALPLAYER(e)
{
- if(clienttype(e) == CLIENTTYPE_REAL)
- {
- p += 1;
- if(e.ready) r += 1;
- }
- e = find(e, classname, "player");
+ p += 1;
+ if(e.ready)
+ r += 1;
}
if(p && r == p)
Modified: branches/nexuiz-2.0/data/qcsrc/server/ctf.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/ctf.qc 2007-03-28 10:14:16 UTC (rev 2265)
+++ branches/nexuiz-2.0/data/qcsrc/server/ctf.qc 2007-03-28 12:32:53 UTC (rev 2266)
@@ -213,15 +213,13 @@
LogCTF("capture", other.flagcarried.team, other);
// give credit to the individual player
UpdateFrags(other, cvar("g_ctf_flagscore_capture"));
+
// give credit to all players of the team (rewards large teams)
// NOTE: this defaults to 0
- head = find(head, classname, "player");
- while (head)
- {
+ FOR_EACH_PLAYER(head)
if (head.team == self.team)
UpdateFrags(head, cvar("g_ctf_flagscore_capture_team"));
- head = find(head, classname, "player");
- }
+
sound (self, CHAN_AUTO, self.noise2, 1, ATTN_NONE);
RegenFlag (other.flagcarried);
other.flagcarried = world;
@@ -246,11 +244,9 @@
LogCTF("steal", self.team, other);
sound (self, CHAN_AUTO, self.noise, 1, ATTN_NONE);
- player = find(world, classname, "player");
- while(player) {
- if(player.team == self.team) centerprint(player, "The enemy got your flag! Retrieve it!");
- player = find(player, classname, "player");
- }
+ FOR_EACH_PLAYER(player)
+ if(player.team == self.team)
+ centerprint(player, "The enemy got your flag! Retrieve it!");
self.movetype = MOVETYPE_NONE;
setorigin(self, FLAG_CARRY_POS);
@@ -287,11 +283,10 @@
LogCTF("pickup", self.team, other);
sound (self, CHAN_AUTO, self.noise, 1, ATTN_NONE);
- player = find(world, classname, "player");
- while(player) {
- if(player.team == self.team) centerprint(player, "The enemy got your flag! Retrieve it!");
- player = find(player, classname, "player");
- }
+ FOR_EACH_PLAYER(player)
+ if(player.team == self.team)
+ centerprint(player, "The enemy got your flag! Retrieve it!");
+
self.movetype = MOVETYPE_NONE; // flag must have MOVETYPE_NONE here, otherwise it will drop through the floor...
setorigin(self, FLAG_CARRY_POS);
setattachment(self, other, "");
Modified: branches/nexuiz-2.0/data/qcsrc/server/defs.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/defs.qh 2007-03-28 10:14:16 UTC (rev 2265)
+++ branches/nexuiz-2.0/data/qcsrc/server/defs.qh 2007-03-28 12:32:53 UTC (rev 2266)
@@ -301,6 +301,9 @@
.float selected_player_display_needs_update; // are regular updates necessary? (health)
.float selected_player_display_timeout; // when the selection will time out
+void FixIntermissionClient(entity e);
+void FixClientCvars(entity e);
+
void centerprint_atprio(entity e, float prio, string s);
void centerprint_expire(entity e, float prio);
void centerprint(entity e, string s);
Modified: branches/nexuiz-2.0/data/qcsrc/server/domination.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/domination.qc 2007-03-28 10:14:16 UTC (rev 2265)
+++ branches/nexuiz-2.0/data/qcsrc/server/domination.qc 2007-03-28 12:32:53 UTC (rev 2266)
@@ -125,26 +125,18 @@
{
teamfragamt = cvar("g_domination_point_teamamt");
- head = find(head, classname, "player");
- while (head)
- {
+ FOR_EACH_PLAYER(head)
if (head.team == self.goalentity.team)
UpdateFrags(head, teamfragamt);
- head = find(head, classname, "player");
- }
}
// if the player left the game, changed teams or became spectator, we have to find another player on the same team to give credit to
if (!self.enemy.flags || self.enemy.team != self.goalentity.team || self.enemy.killcount == -666) // flags is zero on removed clients
{
other = self.enemy;
- head = find(head, classname, "player");
- while (head)
- {
+ FOR_EACH_PLAYER(head)
if (head.team == self.goalentity.team)
self.enemy = head;
- head = find(head, classname, "player");
- }
if(self.enemy == other) // search returned no matching player, reset dom point
{
dom_controlpoint_setup();
Modified: branches/nexuiz-2.0/data/qcsrc/server/g_world.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_world.qc 2007-03-28 10:14:16 UTC (rev 2265)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_world.qc 2007-03-28 12:32:53 UTC (rev 2266)
@@ -3,6 +3,7 @@
string GetMapname();
void GotoNextMap();
void HandleMaplistShuffleCommands();
+float() DoNextMapOverride;
void SetDefaultAlpha()
{
@@ -61,7 +62,8 @@
if(argv(0) != GetMapname())
{
cvar_set("nextmap", argv(0));
- GotoNextMap();
+ if(!DoNextMapOverride())
+ GotoNextMap();
}
}
}
@@ -340,6 +342,9 @@
registercvar("_g_maplist_shufflenow", "0");
registercvar("_g_maplist_have_shuffled", "0");
+ registercvar("_g_maplist_add", "");
+ registercvar("_g_maplist_remove", "");
+ registercvar("_g_maplist_putfirst", "");
player_count = 0;
lms_lowest_lives = 0;
@@ -449,9 +454,12 @@
return "dm";
}
+string getmapname_stored;
string GetMapname()
{
- return strcat(GetGametype(), "_", mapname);
+ if(getmapname_stored == "")
+ getmapname_stored = strzone(strcat(GetGametype(), "_", mapname));
+ return getmapname_stored;
}
float Map_Count, Map_Current;
@@ -511,6 +519,7 @@
string Map_Filename(float position)
{
+ // FIXME unused
return strcat("maps/", argv(position), ".mapcfg");
}
@@ -537,12 +546,39 @@
return 0;
}
-void(float position) Map_Goto =
+void(string nextmapname) Map_Goto_SetStr =
{
+ if(getmapname_stored != "")
+ strunzone(getmapname_stored);
+ if(nextmapname == "")
+ getmapname_stored = "";
+ else
+ getmapname_stored = strzone(nextmapname);
+}
+
+void(float position) Map_Goto_SetFloat =
+{
cvar_set("g_maplist_index", ftos(position));
- localcmd(strcat("exec \"", Map_Filename(position) ,"\"\n"));
+ Map_Goto_SetStr(argv(position));
}
+void() GameResetCfg =
+{
+ // if an exit cfg is defined by exiting map, exec it.
+ string exit_cfg;
+ exit_cfg = cvar_string("exit_cfg");
+ if(exit_cfg != "")
+ localcmd(strcat("exec \"", exit_cfg, "\"\n"));
+
+ localcmd("exec game_reset.cfg\n");
+};
+
+void() Map_Goto =
+{
+ GameResetCfg();
+ localcmd(strcat("exec \"maps/", getmapname_stored ,".mapcfg\"\n"));
+}
+
// return codes of map selectors:
// -1 = temporary failure (that is, try some method that is guaranteed to succeed)
// -2 = permanent failure
@@ -645,31 +681,51 @@
// isn't chosen in the first pass that should have been
}
-void() GotoNextMap =
+string() GetNextMap =
{
- //local string nextmap;
- //local float n, nummaps;
- //local string s;
- string exit_cfg;
- if (alreadychangedlevel)
- return;
- alreadychangedlevel = TRUE;
+ float nextMap;
+ Maplist_Init();
+ nextMap = -1;
+
+ if(nextMap == -1)
+ if(cvar("g_maplist_shuffle") > 0)
+ nextMap = MaplistMethod_Shuffle(cvar("g_maplist_shuffle") + 1);
+
+ if(nextMap == -1)
+ if(cvar("g_maplist_selectrandom"))
+ nextMap = MaplistMethod_Random();
+
+ if(nextMap == -1)
+ nextMap = MaplistMethod_Iterate();
+
+ if(nextMap == -1)
+ nextMap = MaplistMethod_Repeat();
+
+ if(nextMap >= 0)
+ {
+ Map_Goto_SetFloat(nextMap);
+ return getmapname_stored;
+ }
+
+ return "";
+};
+
+float() DoNextMapOverride =
+{
if(cvar("g_campaign"))
{
CampaignPostIntermission();
- return;
+ return TRUE;
}
-
if(cvar("quit_when_empty"))
{
if(player_count <= currentbots)
{
localcmd("quit\n");
- return;
+ return TRUE;
}
}
-
if (cvar("samelevel")) // if samelevel is set, stay on same level
{
// this does not work because it tries to exec maps/nexdm01.mapcfg (which doesn't exist, it should be trying maps/dm_nexdm01.mapcfg for example)
@@ -677,72 +733,55 @@
// so instead just restart the current map using the restart command (DOES NOT WORK PROPERLY WITH exit_cfg STUFF)
localcmd("restart\n");
//changelevel (mapname);
- return;
+ return TRUE;
}
-
- // if an exit cfg is defined by exiting map, exec it.
- exit_cfg = cvar_string("exit_cfg");
- if(exit_cfg != "")
- localcmd(strcat("exec \"", exit_cfg, "\"\n"));
-
- localcmd("exec game_reset.cfg\n");
-
-
- if (cvar("lastlevel"))
+ if(cvar_string("nextmap") != "")
+ if(TryFile(strcat("maps/", cvar_string("nextmap"), ".mapcfg")))
+ {
+ Map_Goto_SetStr(cvar_string("nextmap"));
+ Map_Goto();
+ return TRUE;
+ }
+ if(cvar("lastlevel"))
{
+ GameResetCfg();
localcmd(strcat("set lastlevel 0\n"));
localcmd(strcat("togglemenu\n"));
+ return TRUE;
}
- else
+ return FALSE;
+};
+
+void() GotoNextMap =
+{
+ //local string nextmap;
+ //local float n, nummaps;
+ //local string s;
+ if (alreadychangedlevel)
+ return;
+ alreadychangedlevel = TRUE;
+
{
- float nextMap;
+ string nextMap;
float allowReset;
- // cvar "nextmap" always gets priority
- if(cvar_string("nextmap") != "")
- if(TryFile(strcat("maps/", cvar_string("nextmap"), ".mapcfg")))
- {
- localcmd(strcat("exec \"maps/", cvar_string("nextmap"), ".mapcfg\"\n"));
- return;
- }
-
for(allowReset = 1; allowReset >= 0; --allowReset)
{
- Maplist_Init();
- nextMap = -1;
+ nextMap = GetNextMap();
+ if(nextMap != "")
+ break;
- if(nextMap == -1)
- if(cvar("g_maplist_shuffle") > 0)
- nextMap = MaplistMethod_Shuffle(cvar("g_maplist_shuffle") + 1);
-
- if(nextMap == -1)
- if(cvar("g_maplist_selectrandom"))
- nextMap = MaplistMethod_Random();
-
- if(nextMap == -1)
- nextMap = MaplistMethod_Iterate();
-
- if(nextMap == -1)
- nextMap = MaplistMethod_Repeat();
-
- if(nextMap >= 0)
+ if(allowReset)
{
- Map_Goto(nextMap);
- break;
+ bprint( "Maplist contains no single playable map! Resetting it to default map list.\n" );
+ cvar_set("g_maplist", cvar_string("g_maplist_defaultlist"));
}
- else // PERMANENT FAILURE
+ else
{
- if(allowReset)
- {
- bprint( "Maplist contains no single playable map! Resetting it to default map list.\n" );
- cvar_set("g_maplist", cvar_string("g_maplist_defaultlist"));
- }
- else
- {
- error("Everything is broken - not even the default map list works. Please report this to the developers.");
- }
+ error("Everything is broken - not even the default map list works. Please report this to the developers.");
}
}
+ Map_Goto();
}
};
@@ -755,8 +794,12 @@
============
*/
.float autoscreenshot;
+void() MapVote_Think;
+float mapvote_initialized;
void() IntermissionThink =
{
+ FixIntermissionClient(self);
+
if(cvar("sv_autoscreenshot"))
if(self.autoscreenshot)
if(time > self.autoscreenshot)
@@ -770,10 +813,12 @@
if (time < intermission_exittime)
return;
- if (time < intermission_exittime + 10 && !self.button0 && !self.button2 && !self.button3 && !self.button6 && !self.buttonuse)
- return;
+ if(!mapvote_initialized)
+ if (time < intermission_exittime + 10 && !self.button0 && !self.button2 && !self.button3 && !self.button6 && !self.buttonuse)
+ return;
- GotoNextMap ();
+ if(intermission_exittime >= 0)
+ MapVote_Think();
};
/*
@@ -859,8 +904,7 @@
fputs(file, strcat(s, "\n"));
}
- other = findchainflags(flags, FL_CLIENT);
- while (other)
+ FOR_EACH_CLIENT(other)
{
if ((clienttype(other) == CLIENTTYPE_REAL) || (clienttype(other) == CLIENTTYPE_BOT && cvar("sv_logscores_bots")))
{
@@ -876,7 +920,6 @@
else if(cvar("sv_logscores_console"))
ServerConsoleEcho(strcat(s, other.netname), TRUE);
}
- other = other.chain;
}
if(cvar("sv_eventlog") && gameover)
@@ -890,7 +933,35 @@
}
}
+void FixIntermissionClient(entity e)
+{
+ if(!e.autoscreenshot) // initial call
+ {
+ e.angles = e.v_angle;
+ e.angles_x = -e.angles_x;
+ e.autoscreenshot = time + 0.8; // used for autoscreenshot
+ e.health = -2342;
+ // first intermission phase; voting phase has positive health (used to decide whether to send SVC_FINALE or not)
+ e.solid = SOLID_NOT;
+ e.movetype = MOVETYPE_NONE;
+ e.takedamage = DAMAGE_NO;
+ if(e.weaponentity)
+ e.weaponentity.effects = EF_NODRAW;
+ stuffcmd(e, "\nscr_printspeed 1000000\n");
+ if(clienttype(e) == CLIENTTYPE_REAL)
+ {
+ msg_entity = e;
+ WriteByte(MSG_ONE, SVC_INTERMISSION);
+ }
+ }
+ //e.velocity = '0 0 0';
+ //e.fixangle = TRUE;
+
+ // TODO halt weapon animation
+}
+
+
/*
go to the next level for deathmatch
only called if a time or frag limit has expired
@@ -928,7 +999,7 @@
GameLogClose();
maxTotalFrags = 0;
- for(other = world; (other = findflags(other, flags, FL_CLIENT)); )
+ FOR_EACH_CLIENT(other)
{
if(maxTotalFrags < other.totalfrags)
maxTotalFrags = other.totalfrags;
@@ -936,15 +1007,9 @@
minTotalFrags = other.totalfrags;
}
- for(other = world; (other = findflags(other, flags, FL_CLIENT)); )
+ FOR_EACH_CLIENT(other)
{
- //other.nextthink = time + 0.5;
- other.takedamage = DAMAGE_NO;
- other.solid = SOLID_NOT;
- other.movetype = MOVETYPE_NONE;
- other.angles = other.v_angle;
- other.angles_x = other.angles_x * -1;
- other.autoscreenshot = time + 0.8; // used for autoscreenshot
+ FixIntermissionClient(other);
self = other;
@@ -962,7 +1027,7 @@
if(cvar("g_campaign"))
CampaignPreIntermission();
- WriteByte (MSG_ALL, SVC_INTERMISSION);
+ // WriteByte (MSG_ALL, SVC_INTERMISSION);
};
/*
@@ -1021,37 +1086,25 @@
void(.float field, float value) SetWinners =
{
entity head;
- head = findchain(classname, "player");
- while (head)
- {
+ FOR_EACH_PLAYER(head)
head.winning = (head.field == value);
- head = head.chain;
- }
}
// set the .winning flag for those players with a given field value
void(.float field, float value) AddWinners =
{
entity head;
- head = findchain(classname, "player");
- while (head)
- {
+ FOR_EACH_PLAYER(head)
if(head.field == value)
head.winning = 1;
- head = head.chain;
- }
}
// clear the .winning flags
void(void) ClearWinners =
{
entity head;
- head = findchain(classname, "player");
- while (head)
- {
+ FOR_EACH_PLAYER(head)
head.winning = 0;
- head = head.chain;
- }
}
float() LMS_NewPlayerLives =
@@ -1137,9 +1190,8 @@
// check if the top two players have equal score.
checkrules_leaderfrags = 0;
- head = findchain(classname, "player");
checkrules_equality = FALSE;
- while (head)
+ FOR_EACH_PLAYER(head)
{
if(head.frags > checkrules_leaderfrags)
{
@@ -1148,7 +1200,6 @@
}
else if(head.frags > 0 && head.frags == checkrules_leaderfrags)
checkrules_equality = TRUE;
- head = head.chain;
}
SetWinners(frags, checkrules_leaderfrags);
@@ -1173,9 +1224,8 @@
checkrules_oldleaderfrags = checkrules_leaderfrags;
checkrules_leaderfrags = 0;
- head = findchain(classname, "player");
checkrules_equality = FALSE;
- while (head)
+ FOR_EACH_PLAYER(head)
{
if(head.frags > checkrules_leaderfrags)
{
@@ -1184,7 +1234,6 @@
}
else if(head.frags > 0 && head.frags == checkrules_leaderfrags)
checkrules_equality = TRUE;
- head = head.chain;
}
if(checkrules_leaderfrags > 0)
@@ -1258,8 +1307,7 @@
team1_score = team2_score = team3_score = team4_score = 0;
- head = findchain(classname, "player");
- while (head)
+ FOR_EACH_PLAYER(head)
{
if(head.team == COLOR_TEAM1)
team1_score += head.frags;
@@ -1269,7 +1317,6 @@
team3_score += head.frags;
else if(head.team == COLOR_TEAM4)
team4_score += head.frags;
- head = head.chain;
}
return WinningConditionBase_Teamplay(fraglimit);
@@ -1284,8 +1331,7 @@
team1_score = team2_score = team3_score = team4_score = 0;
- head = findchain(classname, "player");
- while (head)
+ FOR_EACH_PLAYER(head)
{
if(head.team == COLOR_TEAM1)
{
@@ -1307,14 +1353,21 @@
if(head.frags > team4_score)
team4_score = head.frags;
}
- head = head.chain;
}
return WinningConditionBase_Teamplay(fraglimit);
}
-void PrintScoreboardFor(string name, string colorcode, float whichteam)
+void print_to(entity e, string s)
{
+ if(e)
+ sprint(e, strcat(s, "\n"));
+ else
+ ServerConsoleEcho(s, TRUE);
+}
+
+void PrintScoreboardFor(entity e, string name, string colorcode, float whichteam)
+{
entity head;
float v;
float teamvalue;
@@ -1322,15 +1375,14 @@
string s;
float found;
found = FALSE;
- head = find(world, classname, "player");
teamvalue = 0;
- while(head)
+ FOR_EACH_PLAYER(head)
{
if(!whichteam || head.team == whichteam)
{
if(name != "")
if(!found)
- ServerConsoleEcho(strcat(" ", colorcode, name, ":"), FALSE);
+ print_to(e, strcat(" ", colorcode, name, ":"));
found = TRUE;
fragtotal = fragtotal + head.frags;
s = ftos(head.frags);
@@ -1343,33 +1395,35 @@
v = PlayerValue(head);
teamvalue += v;
s = strcat(s, " / ", ftos(v));
- ServerConsoleEcho(strcat(" ", colorcode, head.netname, colorcode, " (", s, ")"), TRUE);
+ print_to(e, strcat(" ", colorcode, head.netname, colorcode, " (", s, ")"));
}
- head = find(head, classname, "player");
}
if(whichteam && found)
{
s = ftos(fragtotal);
s = strcat(s, " / ", ftos(teamvalue));
- ServerConsoleEcho(strcat(colorcode, " (total: ", s, ")"), FALSE);
+ print_to(e, strcat(colorcode, " (total: ", s, ")"));
}
}
-void PrintScoreboard()
+void PrintScoreboard(entity e)
{
- ServerConsoleEcho("Scoreboard:", FALSE);
+ print_to(e, strcat("Time: ", ftos(time / 60)));
+ print_to(e, strcat("Timelimit: ", ftos(cvar("timelimit"))));
+ print_to(e, strcat("Fraglimit: ", ftos(cvar("fraglimit"))));
+ print_to(e, "Scoreboard:");
if(teams_matter)
{
- PrintScoreboardFor("Red", "^1", COLOR_TEAM1);
- PrintScoreboardFor("Blue", "^4", COLOR_TEAM2);
- PrintScoreboardFor("Pink", "^6", COLOR_TEAM3);
- PrintScoreboardFor("Yellow", "^3", COLOR_TEAM4);
+ PrintScoreboardFor(e, "Red", "^1", COLOR_TEAM1);
+ PrintScoreboardFor(e, "Blue", "^4", COLOR_TEAM2);
+ PrintScoreboardFor(e, "Pink", "^6", COLOR_TEAM3);
+ PrintScoreboardFor(e, "Yellow", "^3", COLOR_TEAM4);
}
else
{
- PrintScoreboardFor("", "^7", 0);
+ PrintScoreboardFor(e, "", "^7", 0);
}
- ServerConsoleEcho(".", FALSE);
+ print_to(e, ".");
}
void RemoveFromMaplist(string m)
@@ -1441,6 +1495,22 @@
ServerConsoleEcho("Map already in list.", FALSE);
}
+void MakeFirstInMaplist(string m)
+{
+ if(!TryFile(strcat("maps/", m, ".mapcfg")))
+ {
+ ServerConsoleEcho("Map not found.", FALSE);
+ return;
+ }
+
+ m = strzone(m);
+ RemoveFromMaplist(m);
+ cvar_set("g_maplist", strcat("'", m, "'", cvar_string("g_maplist")));
+ strunzone(m);
+
+ ServerConsoleEcho("Map added as first one.", FALSE);
+}
+
void ShuffleMaplist()
{
string result;
@@ -1488,6 +1558,11 @@
RemoveFromMaplist(cvar_string("_g_maplist_remove"));
cvar_set("_g_maplist_remove", "");
}
+ if(cvar_string("_g_maplist_putfirst") != "")
+ {
+ MakeFirstInMaplist(cvar_string("_g_maplist_putfirst"));
+ cvar_set("_g_maplist_putfirst", "");
+ }
if(cvar("_g_maplist_shufflenow") || (cvar("g_maplist_shuffle") && !cvar("_g_maplist_have_shuffled")))
{
ShuffleMaplist();
@@ -1520,7 +1595,8 @@
if (intermission_running)
if (time >= intermission_exittime + 60)
{
- GotoNextMap();
+ if(!DoNextMapOverride())
+ GotoNextMap();
return;
}
@@ -1532,7 +1608,7 @@
if(cvar("_scoreboard"))
{
cvar_set("_scoreboard", "0");
- PrintScoreboard();
+ PrintScoreboard(world);
}
HandleMaplistShuffleCommands();
@@ -1540,8 +1616,20 @@
timelimit = cvar("timelimit") * 60;
fraglimit = cvar("fraglimit");
- if (timelimit && time >= timelimit)
- InitiateOvertime();
+ if(checkrules_overtimeend)
+ {
+ if(!checkrules_overtimewarning)
+ {
+ checkrules_overtimewarning = TRUE;
+ //sound(world, CHAN_AUTO, "announcer/robotic/1minuteremains.ogg", 1, ATTN_NONE);
+ bcenterprint("^3Now playing ^1OVERTIME^3!\n\n^3Keep fragging until we have a ^1winner^3!");
+ }
+ }
+ else
+ {
+ if (timelimit && time >= timelimit)
+ InitiateOvertime();
+ }
if (checkrules_overtimeend && time >= checkrules_overtimeend)
{
@@ -1549,13 +1637,6 @@
return;
}
- if(!checkrules_overtimewarning && checkrules_overtimeend)
- {
- checkrules_overtimewarning = TRUE;
- //sound(world, CHAN_AUTO, "announcer/robotic/1minuteremains.ogg", 1, ATTN_NONE);
- bcenterprint("^3Now playing ^1OVERTIME^3!\n\n^3Keep fragging until we have a ^1winner^3!");
- }
-
if (!checkrules_oneminutewarning && timelimit > 0 && time > timelimit - 60)
{
checkrules_oneminutewarning = TRUE;
@@ -1596,9 +1677,351 @@
ClearWinners();
if(checkrules_overtimeend)
- if(status != WINNING_NEVER)
+ if(status != WINNING_NEVER || time >= checkrules_overtimeend)
status = WINNING_YES;
if(status == WINNING_YES)
NextLevel();
};
+
+float randsel_value;
+float randsel_priority;
+float randsel_count;
+void RandSel_Init()
+{
+ randsel_value = -1;
+ randsel_priority = -1;
+ randsel_count = -1;
+}
+void RandSel_Add(float priority, float value)
+{
+ if(priority > randsel_priority)
+ {
+ randsel_priority = priority;
+ randsel_value = value;
+ randsel_count = 1;
+ }
+ else if(priority == randsel_priority)
+ {
+ randsel_count += 1;
+ if(ceil(random() * randsel_count) == 1)
+ randsel_value = value;
+ }
+}
+
+float mapvote_nextthink;
+float mapvote_initialized;
+float mapvote_keeptwotime;
+float mapvote_timeout;
+string mapvote_message;
+
+#define MAPVOTE_COUNT 10
+float mapvote_count;
+string mapvote_maps[MAPVOTE_COUNT];
+float mapvote_maps_suggested[MAPVOTE_COUNT];
+string mapvote_suggestions[MAPVOTE_COUNT];
+float mapvote_suggestion_ptr;
+string mapvote_fillstr;
+float mapvote_maxlen;
+float mapvote_voters;
+float mapvote_votes[MAPVOTE_COUNT];
+.float mapvote;
+
+void MapVote_ClearAllVotes()
+{
+ FOR_EACH_CLIENT(other)
+ other.mapvote = 0;
+}
+
+string MapVote_Suggest(string m)
+{
+ float i;
+ if(m == "")
+ return "That's not how to use this command.";
+ if(!cvar("g_maplist_votable_suggestions"))
+ return "Suggestions are not accepted on this server.";
+ if(mapvote_initialized)
+ return "Can't suggest - voting is already in progress!";
+ if(!TryFile(strcat("maps/", m, ".mapcfg")))
+ return "The map you suggested is not available on this server.";
+ for(i = 0; i < mapvote_suggestion_ptr; ++i)
+ if(mapvote_suggestions[i] == m)
+ return "This map was already suggested.";
+ if(mapvote_suggestion_ptr >= MAPVOTE_COUNT)
+ {
+ i = ceil(random() * mapvote_suggestion_ptr) - 1;
+ }
+ else
+ {
+ i = mapvote_suggestion_ptr;
+ mapvote_suggestion_ptr += 1;
+ }
+ if(mapvote_suggestions[i] != "")
+ strunzone(mapvote_suggestions[i]);
+ mapvote_suggestions[i] = strzone(m);
+ GameLogEcho(strcat(":vote:suggested:", m, ":", ftos(self.playerid), ":", self.netname), TRUE);
+ return "Suggestion accepted.";
+}
+
+void MapVote_AddVotable(string nextMap, float isSuggestion)
+{
+ float j;
+ if(nextMap == "")
+ return;
+ for(j = 0; j < mapvote_count; ++j)
+ if(mapvote_maps[j] == nextMap)
+ return;
+ if(strlen(nextMap) > mapvote_maxlen)
+ mapvote_maxlen = strlen(nextMap);
+ mapvote_maps[mapvote_count] = strzone(nextMap);
+ mapvote_maps_suggested[mapvote_count] = isSuggestion;
+ mapvote_count += 1;
+}
+
+void MapVote_Init()
+{
+ float i;
+ float nmax, smax;
+
+ MapVote_ClearAllVotes();
+
+ nmax = min(MAPVOTE_COUNT, cvar("g_maplist_votable"));
+ smax = min(nmax, cvar("g_maplist_votable_suggestions"));
+ mapvote_count = 0;
+
+ for(i = 0; i < 100 && mapvote_count < smax; ++i)
+ MapVote_AddVotable(mapvote_suggestions[ceil(random() * mapvote_suggestion_ptr) - 1], TRUE);
+
+ for(i = 0; i < 100 && mapvote_count < nmax; ++i)
+ MapVote_AddVotable(GetNextMap(), FALSE);
+
+ if(mapvote_count == 0)
+ {
+ bprint( "Maplist contains no single playable map! Resetting it to default map list.\n" );
+ cvar_set("g_maplist", cvar_string("g_maplist_defaultlist"));
+ for(i = 0; i < 100 && mapvote_count < nmax; ++i)
+ MapVote_AddVotable(GetNextMap(), FALSE);
+ }
+
+ //dprint("mapvote count is ", ftos(mapvote_count), "\n");
+
+ mapvote_fillstr = " ";
+ while(strlen(mapvote_fillstr) < mapvote_maxlen + 16)
+ mapvote_fillstr = strcat(mapvote_fillstr, mapvote_fillstr);
+ mapvote_fillstr = strzone(mapvote_fillstr);
+
+ mapvote_keeptwotime = time + cvar("g_maplist_votable_keeptwotime");
+ mapvote_timeout = time + cvar("g_maplist_votable_timeout");
+ if(mapvote_count < 3 || mapvote_keeptwotime <= time)
+ mapvote_keeptwotime = 0;
+ mapvote_message = "Choose a map and press its key!";
+}
+float MapVote_Finished(float mappos)
+{
+ string result;
+ float i;
+
+ result = strcat(":vote:finished:", mapvote_maps[mappos]);
+ result = strcat(result, ":", ftos(mapvote_votes[mappos]), "::");
+ for(i = 0; i < mapvote_count; ++i)
+ if(i != mappos)
+ if(mapvote_maps[i] != "")
+ {
+ result = strcat(result, ":", mapvote_maps[i]);
+ result = strcat(result, ":", ftos(mapvote_votes[i]));
+ }
+ GameLogEcho(result, FALSE);
+ if(mapvote_maps_suggested[mappos])
+ GameLogEcho(strcat(":vote:suggestion_accepted:", mapvote_maps[mappos]), FALSE);
+
+ FOR_EACH_REALCLIENT(other)
+ FixClientCvars(other);
+
+ Map_Goto_SetStr(mapvote_maps[mappos]);
+ Map_Goto();
+ return TRUE;
+}
+void MapVote_CheckRules_1()
+{
+ float i;
+
+ for(i = 0; i < mapvote_count; ++i) if(mapvote_maps[i] != "")
+ {
+ //dprint("Map ", ftos(i), ": "); dprint(mapvote_maps[i], "\n");
+ mapvote_votes[i] = 0;
+ }
+
+ mapvote_voters = 0;
+ FOR_EACH_REALCLIENT(other)
+ {
+ ++mapvote_voters;
+ if(other.mapvote)
+ {
+ i = other.mapvote - 1;
+ //dprint("Player ", other.netname, " vote = ", ftos(other.mapvote - 1), "\n");
+ mapvote_votes[i] = mapvote_votes[i] + 1;
+ }
+ }
+}
+
+float MapVote_CheckRules_2()
+{
+ float i;
+ float firstPlace, secondPlace;
+ float firstPlaceVotes, secondPlaceVotes;
+ string result;
+
+ RandSel_Init();
+ for(i = 0; i < mapvote_count; ++i) if(mapvote_maps[i] != "")
+ RandSel_Add(mapvote_votes[i], i);
+ firstPlace = randsel_value;
+ firstPlaceVotes = randsel_priority;
+ //dprint("First place: ", ftos(firstPlace), "\n");
+ //dprint("First place votes: ", ftos(firstPlaceVotes), "\n");
+
+ RandSel_Init();
+ for(i = 0; i < mapvote_count; ++i) if(mapvote_maps[i] != "")
+ if(i != firstPlace)
+ RandSel_Add(mapvote_votes[i], i);
+ secondPlace = randsel_value;
+ secondPlaceVotes = randsel_priority;
+ //dprint("Second place: ", ftos(secondPlace), "\n");
+ //dprint("Second place votes: ", ftos(secondPlaceVotes), "\n");
+
+ if(firstPlace == -1)
+ error("No first place in map vote... WTF?");
+
+ if(secondPlace == -1 || time > mapvote_timeout || (mapvote_voters - firstPlaceVotes) < firstPlaceVotes)
+ return MapVote_Finished(firstPlace);
+
+ if(mapvote_keeptwotime)
+ if(time > mapvote_keeptwotime || (mapvote_voters - firstPlaceVotes - secondPlaceVotes) < secondPlaceVotes)
+ {
+ mapvote_message = "Now decide between the TOP TWO!";
+ mapvote_keeptwotime = 0;
+ result = strcat(":vote:keeptwo:", mapvote_maps[firstPlace]);
+ result = strcat(result, ":", ftos(firstPlaceVotes));
+ result = strcat(result, ":", mapvote_maps[secondPlace]);
+ result = strcat(result, ":", ftos(secondPlaceVotes), "::");
+ for(i = 0; i < mapvote_count; ++i)
+ if(i != firstPlace)
+ if(i != secondPlace)
+ if(mapvote_maps[i] != "")
+ {
+ result = strcat(result, ":", mapvote_maps[i]);
+ result = strcat(result, ":", ftos(mapvote_votes[i]));
+ strunzone(mapvote_maps[i]);
+ mapvote_maps[i] = "";
+ }
+ GameLogEcho(result, FALSE);
+ }
+
+ return FALSE;
+}
+void MapVote_Tick()
+{
+ string msgstr;
+ string tmp;
+ float i;
+ float keeptwo;
+
+ keeptwo = mapvote_keeptwotime;
+ MapVote_CheckRules_1(); // count
+ if(MapVote_CheckRules_2()) // decide
+ return;
+
+ FOR_EACH_REALCLIENT(other)
+ {
+ // hide scoreboard again
+ if(other.health != 2342)
+ {
+ other.health = 2342;
+ other.impulse = 0;
+ if(clienttype(other) == CLIENTTYPE_REAL)
+ {
+ stuffcmd(other, "\nin_bind 7 1 \"impulse 1\"; in_bind 7 2 \"impulse 2\"; in_bind 7 3 \"impulse 3\"; in_bind 7 4 \"impulse 4\"; in_bind 7 5 \"impulse 5\"; in_bind 7 6 \"impulse 6\"; in_bind 7 7 \"impulse 7\"; in_bind 7 8 \"impulse 8\"; in_bind 7 9 \"impulse 9\"; in_bind 7 0 \"impulse 10\"; in_bind 7 KP_1 \"impulse 1\"; in_bind 7 KP_2 \"impulse 2\"; in_bind 7 KP_3 \"impulse 3\"; in_bind 7 KP_4 \"impulse 4\"; in_bind 7 KP_5 \"impulse 5\"; in_bind 7 KP_6 \"impulse 6\"; in_bind 7 KP_7 \"impulse 7\"; in_bind 7 KP_8 \"impulse 8\"; in_bind 7 KP_9 \"impulse 9\"; in_bind 7 KP_0 \"impulse 10\"; in_bindmap 7 0\n");
+ msg_entity = other;
+ WriteByte(MSG_ONE, SVC_FINALE);
+ WriteString(MSG_ONE, "");
+ }
+ }
+
+ // notify about keep-two
+ if(keeptwo != 0 && mapvote_keeptwotime == 0)
+ stuffcmd(other, "\nplay2 misc/invshot.wav\n");
+
+ // clear possibly invalid votes
+ if(mapvote_maps[other.mapvote - 1] == "")
+ other.mapvote = 0;
+ // use impulses as new vote
+ if(other.impulse >= 1 && other.impulse <= mapvote_count)
+ if(mapvote_maps[other.impulse - 1] != "")
+ other.mapvote = other.impulse;
+ other.impulse = 0;
+ }
+
+ MapVote_CheckRules_1(); // just count
+
+ FOR_EACH_REALCLIENT(other)
+ {
+ // display voting screen
+ msgstr = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
+ msgstr = substring(msgstr, 0, strlen(msgstr) - mapvote_count);
+ msgstr = strcat(msgstr, mapvote_message);
+ msgstr = strcat(msgstr, "\n\n");
+ for(i = 0; i < mapvote_count; ++i)
+ if(mapvote_maps[i] == "")
+ msgstr = strcat(msgstr, "\n");
+ else
+ {
+ tmp = mapvote_maps[i];
+ tmp = strcat(tmp, substring(mapvote_fillstr, 0, mapvote_maxlen - strlen(tmp)));
+ tmp = strcat(ftos(math_mod(i + 1, 10)), ": ", tmp);
+ tmp = strcat(tmp, " ^2(", ftos(mapvote_votes[i]), " vote");
+ if(mapvote_votes[i] != 1)
+ tmp = strcat(tmp, "s");
+ tmp = strcat(tmp, ")");
+ tmp = strcat(tmp, substring(mapvote_fillstr, 0, mapvote_maxlen + 15 - strlen(tmp)));
+ if(other.mapvote == i + 1)
+ msgstr = strcat(msgstr, "^3> ", tmp, "\n");
+ else
+ msgstr = strcat(msgstr, "^7 ", tmp, "\n");
+ }
+ i = ceil(mapvote_timeout - time);
+ msgstr = strcat(msgstr, "\n\n", ftos(i), " second");
+ if(i != 1)
+ msgstr = strcat(msgstr, "s");
+ msgstr = strcat(msgstr, " left");
+
+ centerprint_atprio(other, CENTERPRIO_MAPVOTE, msgstr);
+ }
+}
+void MapVote_Think()
+{
+ if(alreadychangedlevel)
+ return;
+
+ if(time < mapvote_nextthink)
+ return;
+ //dprint("tick\n");
+
+ mapvote_nextthink = time + 0.5;
+
+ if(!mapvote_initialized)
+ {
+ mapvote_initialized = TRUE;
+ if(DoNextMapOverride())
+ {
+ alreadychangedlevel = TRUE;
+ return;
+ }
+ if(!cvar("g_maplist_votable"))
+ {
+ GotoNextMap();
+ return;
+ }
+ MapVote_Init();
+ }
+
+ MapVote_Tick();
+};
Modified: branches/nexuiz-2.0/data/qcsrc/server/havocbot_roles.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/havocbot_roles.qc 2007-03-28 10:14:16 UTC (rev 2265)
+++ branches/nexuiz-2.0/data/qcsrc/server/havocbot_roles.qc 2007-03-28 12:32:53 UTC (rev 2266)
@@ -73,8 +73,7 @@
//dprint(ftos(self.team)); dprint(" -> noteam is "); dprint(ftos(noteam));
//dprint("\n");
- head = findchain(classname, "player");
- while (head)
+ FOR_EACH_PLAYER(head)
{
if (self != head)
if (head.health > 0)
@@ -91,7 +90,6 @@
navigation_routerating(head, t * ratingscale);
}
}
- head = head.chain;
}
};
Modified: branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc 2007-03-28 10:14:16 UTC (rev 2265)
+++ branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc 2007-03-28 12:32:53 UTC (rev 2266)
@@ -1,3 +1,9 @@
+#define FOR_EACH_CLIENT(v) for(v = world; (v = findflags(v, flags, FL_CLIENT)) != world; )
+#define FOR_EACH_REALCLIENT(v) FOR_EACH_CLIENT(v) if(clienttype(v) == CLIENTTYPE_REAL)
+string STR_PLAYER = "player";
+#define FOR_EACH_PLAYER(v) for(v = world; (v = find(v, classname, STR_PLAYER)) != world; )
+#define FOR_EACH_REALPLAYER(v) FOR_EACH_PLAYER(v) if(clienttype(v) == CLIENTTYPE_REAL)
+
float logfile_open;
float logfile;
@@ -3,12 +9,9 @@
void(string s) bcenterprint
{
+ // TODO replace by MSG_ALL (would show it to spectators too, though)?
entity head;
- head = find(world, classname, "player");
- while(head)
- {
+ FOR_EACH_PLAYER(head)
if(clienttype(head) == CLIENTTYPE_REAL)
centerprint(head, s);
- head = find(head, classname, "player");
- }
}
@@ -413,21 +416,15 @@
p.frags = p.frags - f;
nTeam = 0;
- head = find(world, classname, "player");
- while(head)
- {
+ FOR_EACH_PLAYER(head)
if(head != p)
if(head.team == targetteam)
nTeam = nTeam + 1;
- head = find(head, classname, "player");
- }
if(nTeam == 0)
return;
- head = find(world, classname, "player");
- while(head)
- {
+ FOR_EACH_PLAYER(head)
if(head != p)
if(head.team == targetteam)
{
@@ -436,8 +433,6 @@
f = f - d;
nTeam = nTeam - 1;
}
- head = find(head, classname, "player");
- }
if(nTeam != 0)
error("nPlayers in team changed!");
@@ -512,11 +507,16 @@
}
#define CENTERPRIO_POINT 1
+#define CENTERPRIO_VOTE 4
#define CENTERPRIO_NORMAL 5
+#define CENTERPRIO_MAPVOTE 9
.float centerprint_priority;
.float centerprint_expires;
void centerprint_atprio(entity e, float prio, string s)
{
+ if(intermission_running)
+ if(prio < CENTERPRIO_MAPVOTE)
+ return;
if(time > e.centerprint_expires)
e.centerprint_priority = 0;
if(prio >= e.centerprint_priority)
@@ -538,3 +538,5 @@
{
centerprint_atprio(e, CENTERPRIO_NORMAL, s);
}
+
+void VoteNag();
Modified: branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc 2007-03-28 10:14:16 UTC (rev 2265)
+++ branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc 2007-03-28 12:32:53 UTC (rev 2266)
@@ -565,8 +565,7 @@
// FIXME: also find and memorize the lowest-scoring bot on each team (in case players must be shuffled around)
// also remember the lowest-scoring player
- head = find(world, classname, "player");
- while(head)
+ FOR_EACH_PLAYER(head)
{
if(head != ignore)// && head.netname != "")
{
@@ -604,7 +603,6 @@
}
}
}
- head = find(head, classname, "player");
}
}
@@ -995,8 +993,7 @@
lowest_player_score = 999999999;
// find the lowest-scoring player & bot of that team
- head = find(world, classname, "player");
- while(head)
+ FOR_EACH_PLAYER(head)
{
if(head.team == steam)
{
@@ -1017,7 +1014,6 @@
}
}
}
- head = find(head, classname, "player");
}
// prefers to move a bot...
More information about the nexuiz-commits
mailing list