r5192 - in trunk/data/qcsrc: common server
esteel at icculus.org
esteel at icculus.org
Thu Dec 11 10:00:11 EST 2008
Author: esteel
Date: 2008-12-11 10:00:11 -0500 (Thu, 11 Dec 2008)
New Revision: 5192
Modified:
trunk/data/qcsrc/common/gamecommand.qc
trunk/data/qcsrc/server/clientcommands.qc
trunk/data/qcsrc/server/g_world.qc
Log:
doh, no time to fix those dependencies right now
Modified: trunk/data/qcsrc/common/gamecommand.qc
===================================================================
--- trunk/data/qcsrc/common/gamecommand.qc 2008-12-11 14:48:53 UTC (rev 5191)
+++ trunk/data/qcsrc/common/gamecommand.qc 2008-12-11 15:00:11 UTC (rev 5192)
@@ -44,6 +44,540 @@
void rpn_pushf(float f) { return rpn_push(ftos(f)); }
void rpn_setf(float f) { return rpn_set(ftos(f)); }
+float mapvote_nextthink;
+float mapvote_initialized;
+float mapvote_keeptwotime;
+float mapvote_timeout;
+string mapvote_message;
+string mapvote_screenshot_dir;
+
+float mapvote_count;
+float mapvote_count_real;
+string mapvote_maps[MAPVOTE_COUNT];
+float mapvote_maps_suggested[MAPVOTE_COUNT];
+string mapvote_suggestions[MAPVOTE_COUNT];
+float mapvote_suggestion_ptr;
+float mapvote_maxlen;
+float mapvote_voters;
+float mapvote_votes[MAPVOTE_COUNT];
+float mapvote_run;
+float mapvote_detail;
+float mapvote_abstain;
+float mapvote_dirty;
+.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!";
+ m = MapInfo_FixName(m);
+ if(!m)
+ return "The map you suggested is not available on this server.";
+ if(!cvar("g_maplist_votable_override_mostrecent"))
+ if(Map_IsRecent(m))
+ return "This server does not allow for recent maps to be played again. Please be patient for some rounds.";
+
+ if(!MapInfo_CheckMap(m))
+ return "The map you suggested does not support the current game mode.";
+ 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 = floor(random() * mapvote_suggestion_ptr);
+ }
+ else
+ {
+ i = mapvote_suggestion_ptr;
+ mapvote_suggestion_ptr += 1;
+ }
+ if(mapvote_suggestions[i] != "")
+ strunzone(mapvote_suggestions[i]);
+ mapvote_suggestions[i] = strzone(m);
+ if(cvar("sv_eventlog"))
+ GameLogEcho(strcat(":vote:suggested:", m, ":", ftos(self.playerid)));
+ return strcat("Suggestion of ", m, " 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_SendData(float target);
+void MapVote_Init()
+{
+ float i;
+ float nmax, smax;
+
+ MapVote_ClearAllVotes();
+
+ mapvote_count = 0;
+ mapvote_detail = !cvar("g_maplist_votable_nodetail");
+ mapvote_abstain = cvar("g_maplist_votable_abstain");
+
+ if(mapvote_abstain)
+ nmax = min(MAPVOTE_COUNT - 1, cvar("g_maplist_votable"));
+ else
+ nmax = min(MAPVOTE_COUNT, cvar("g_maplist_votable"));
+ smax = min3(nmax, cvar("g_maplist_votable_suggestions"), mapvote_suggestion_ptr);
+
+ if(mapvote_suggestion_ptr)
+ for(i = 0; i < 100 && mapvote_count < smax; ++i)
+ MapVote_AddVotable(mapvote_suggestions[floor(random() * mapvote_suggestion_ptr)], 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", MapInfo_ListAllowedMaps(0, MAPINFO_FLAG_HIDDEN));
+ localcmd("\nmenu_cmd sync\n");
+ for(i = 0; i < 100 && mapvote_count < nmax; ++i)
+ MapVote_AddVotable(GetNextMap(), FALSE);
+ }
+
+ mapvote_count_real = mapvote_count;
+ if(mapvote_abstain)
+ MapVote_AddVotable("don't care", 0);
+
+ //dprint("mapvote count is ", ftos(mapvote_count), "\n");
+
+ mapvote_keeptwotime = time + cvar("g_maplist_votable_keeptwotime");
+ mapvote_timeout = time + cvar("g_maplist_votable_timeout");
+ if(mapvote_count_real < 3 || mapvote_keeptwotime <= time)
+ mapvote_keeptwotime = 0;
+ mapvote_message = "Choose a map and press its key!";
+
+ mapvote_screenshot_dir = cvar_string("g_maplist_votable_screenshot_dir");
+ if(mapvote_screenshot_dir == "")
+ mapvote_screenshot_dir = "maps";
+ mapvote_screenshot_dir = strzone(mapvote_screenshot_dir);
+
+ if(!cvar("g_maplist_textonly"))
+ MapVote_SendData(MSG_ALL);
+}
+
+void MapVote_SendPicture(float id)
+{
+ msg_entity = self;
+ WriteByte(MSG_ONE, SVC_TEMPENTITY);
+ WriteByte(MSG_ONE, TE_CSQC_MAPVOTE);
+ WriteByte(MSG_ONE, MAPVOTE_NET_PIC);
+ WriteByte(MSG_ONE, id);
+ WritePicture(MSG_ONE, strcat(mapvote_screenshot_dir, "/", mapvote_maps[id]), 3072);
+}
+
+float GameCommand_MapVote(string cmd)
+{
+ if(!intermission_running)
+ return FALSE;
+ if(!cvar("g_maplist_textonly"))
+ {
+ if(cmd == "mv_getpic")
+ {
+ MapVote_SendPicture(stof(argv(1)));
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+float MapVote_GetMapMask()
+{
+ float mask, i, power;
+ mask = 0;
+ for(i = 0, power = 1; i < mapvote_count; ++i, power *= 2)
+ if(mapvote_maps[i] != "")
+ mask |= power;
+ return mask;
+}
+
+void MapVote_SendData(float targ)
+{
+ string mapfile, pakfile;
+ float i, o;
+ WriteByte(targ, SVC_TEMPENTITY);
+ WriteByte(targ, TE_CSQC_CONFIG);
+ WriteString(targ, "mv_screenshot_dir");
+ WriteString(targ, mapvote_screenshot_dir);
+
+ WriteByte(targ, SVC_TEMPENTITY);
+ WriteByte(targ, TE_CSQC_MAPVOTE);
+ WriteByte(targ, MAPVOTE_NET_INIT);
+
+ WriteByte(targ, mapvote_count);
+ WriteByte(targ, mapvote_abstain);
+ WriteByte(targ, mapvote_detail);
+ WriteCoord(targ, mapvote_timeout);
+ if(mapvote_count <= 8)
+ WriteByte(targ, MapVote_GetMapMask());
+ else
+ WriteShort(targ, MapVote_GetMapMask());
+ for(i = 0; i < mapvote_count; ++i)
+ if(mapvote_maps[i] != "")
+ {
+ WriteString(targ, mapvote_maps[i]);
+ mapfile = strcat(mapvote_screenshot_dir, "/", mapvote_maps[i]);
+ pakfile = whichpack(strcat(mapfile, ".tga"));
+ if(pakfile == "")
+ pakfile = whichpack(strcat(mapfile, ".jpg"));
+ if(pakfile == "")
+ pakfile = whichpack(strcat(mapfile, ".png"));
+ print("pakfile is ", pakfile, "\n");
+ for(o = strstr(pakfile, "/", 0)+1; o > 0; o = strstr(pakfile, "/", 0)+1)
+ pakfile = substring(pakfile, o, 999);
+ WriteString(targ, pakfile);
+ }
+}
+
+void MapVote_UpdateData(float targ)
+{
+ float i;
+ WriteByte(targ, SVC_TEMPENTITY);
+ WriteByte(targ, TE_CSQC_MAPVOTE);
+ WriteByte(targ, MAPVOTE_NET_UPDATE);
+ if(mapvote_count <= 8)
+ WriteByte(targ, MapVote_GetMapMask());
+ else
+ WriteShort(targ, MapVote_GetMapMask());
+ if(mapvote_detail)
+ for(i = 0; i < mapvote_count; ++i)
+ if(mapvote_maps[i] != "")
+ WriteByte(targ, mapvote_votes[i]);
+}
+
+void MapVote_TellVote(float targ, float vote)
+{
+ WriteByte(targ, SVC_TEMPENTITY);
+ WriteByte(targ, TE_CSQC_MAPVOTE);
+ WriteByte(targ, MAPVOTE_NET_OWNVOTE);
+ WriteByte(targ, vote);
+}
+
+float MapVote_Finished(float mappos)
+{
+ string result;
+ float i;
+ float didntvote;
+
+ if(cvar("sv_eventlog"))
+ {
+ result = strcat(":vote:finished:", mapvote_maps[mappos]);
+ result = strcat(result, ":", ftos(mapvote_votes[mappos]), "::");
+ didntvote = mapvote_voters;
+ for(i = 0; i < mapvote_count; ++i)
+ if(mapvote_maps[i] != "")
+ {
+ didntvote -= mapvote_votes[i];
+ if(i != mappos)
+ {
+ result = strcat(result, ":", mapvote_maps[i]);
+ result = strcat(result, ":", ftos(mapvote_votes[i]));
+ }
+ }
+ result = strcat(result, ":didn't vote:", ftos(didntvote));
+
+ GameLogEcho(result);
+ if(mapvote_maps_suggested[mappos])
+ GameLogEcho(strcat(":vote:suggestion_accepted:", mapvote_maps[mappos]));
+ }
+
+ FOR_EACH_REALCLIENT(other)
+ FixClientCvars(other);
+
+ Map_Goto_SetStr(mapvote_maps[mappos]);
+ Map_Goto();
+ alreadychangedlevel = TRUE;
+ 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;
+ float mapvote_voters_real;
+ string result;
+
+ mapvote_voters_real = mapvote_voters;
+ if(mapvote_abstain)
+ mapvote_voters_real -= mapvote_votes[mapvote_count - 1];
+
+ RandomSelection_Init();
+ for(i = 0; i < mapvote_count_real; ++i) if(mapvote_maps[i] != "")
+ RandomSelection_Add(world, i, 1, mapvote_votes[i]);
+ firstPlace = RandomSelection_chosen_float;
+ firstPlaceVotes = RandomSelection_best_priority;
+ //dprint("First place: ", ftos(firstPlace), "\n");
+ //dprint("First place votes: ", ftos(firstPlaceVotes), "\n");
+
+ RandomSelection_Init();
+ for(i = 0; i < mapvote_count_real; ++i) if(mapvote_maps[i] != "")
+ if(i != firstPlace)
+ RandomSelection_Add(world, i, 1, mapvote_votes[i]);
+ secondPlace = RandomSelection_chosen_float;
+ secondPlaceVotes = RandomSelection_best_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_real - firstPlaceVotes) < firstPlaceVotes)
+ return MapVote_Finished(firstPlace);
+
+ if(mapvote_keeptwotime)
+ if(time > mapvote_keeptwotime || (mapvote_voters_real - firstPlaceVotes - secondPlaceVotes) < secondPlaceVotes)
+ {
+ float didntvote;
+ mapvote_dirty = TRUE;
+ 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), "::");
+ didntvote = mapvote_voters;
+ for(i = 0; i < mapvote_count; ++i)
+ if(mapvote_maps[i] != "")
+ {
+ didntvote -= mapvote_votes[i];
+ if(i != firstPlace)
+ if(i != secondPlace)
+ {
+ result = strcat(result, ":", mapvote_maps[i]);
+ result = strcat(result, ":", ftos(mapvote_votes[i]));
+ if(i < mapvote_count_real)
+ {
+ strunzone(mapvote_maps[i]);
+ mapvote_maps[i] = "";
+ }
+ }
+ }
+ result = strcat(result, ":didn't vote:", ftos(didntvote));
+ if(cvar("sv_eventlog"))
+ GameLogEcho(result);
+ }
+
+ return FALSE;
+}
+void MapVote_Tick()
+{
+ string msgstr;
+ string tmp;
+ float i;
+ float keeptwo;
+ float totalvotes;
+
+ keeptwo = mapvote_keeptwotime;
+ MapVote_CheckRules_1(); // count
+ if(MapVote_CheckRules_2()) // decide
+ return;
+
+ totalvotes = 0;
+ FOR_EACH_REALCLIENT(other)
+ {
+ // hide scoreboard again
+ if(other.health != 2342)
+ {
+ other.health = 2342;
+ other.impulse = 0;
+ if(clienttype(other) == CLIENTTYPE_REAL)
+ {
+ if(cvar("g_maplist_textonly"))
+ 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)
+ play2(other, "misc/invshot.wav");
+
+ // 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;
+ if(mapvote_detail)
+ mapvote_dirty = TRUE;
+
+ msg_entity = other;
+ MapVote_TellVote(MSG_ONE, other.mapvote);
+ }
+ other.impulse = 0;
+
+ if(other.mapvote)
+ ++totalvotes;
+ }
+
+ MapVote_CheckRules_1(); // just count
+
+ if(!cvar("g_maplist_textonly"))
+ if(mapvote_dirty) // 1 if "keeptwo" or "impulse" happened before
+ {
+ MapVote_UpdateData(MSG_BROADCAST);
+ mapvote_dirty = FALSE;
+ }
+
+ if(cvar("g_maplist_textonly"))
+ {
+ 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);
+ if(mapvote_abstain)
+ msgstr = substring(msgstr, 1, strlen(msgstr) - 1);
+ 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 = strpad(mapvote_maxlen, tmp);
+ tmp = strcat(ftos(mod(i + 1, 10)), ": ", tmp);
+ if(mapvote_detail)
+ {
+ tmp = strcat(tmp, " ^2(", ftos(mapvote_votes[i]), " vote");
+ if(mapvote_votes[i] != 1)
+ tmp = strcat(tmp, "s");
+ tmp = strcat(tmp, ")");
+ tmp = strpad(mapvote_maxlen + 15, tmp);
+ }
+ if(mapvote_abstain)
+ if(i == mapvote_count - 1)
+ msgstr = strcat(msgstr, "\n");
+ if(other.mapvote == i + 1)
+ msgstr = strcat(msgstr, "^3> ", tmp, "\n");
+ else
+ msgstr = strcat(msgstr, "^7 ", tmp, "\n");
+ }
+
+ msgstr = strcat(msgstr, "\n\n^2", ftos(totalvotes), " vote");
+ if(totalvotes != 1)
+ msgstr = strcat(msgstr, "s");
+ msgstr = strcat(msgstr, " cast");
+ i = ceil(mapvote_timeout - time);
+ msgstr = strcat(msgstr, "\n", ftos(i), " second");
+ if(i != 1)
+ msgstr = strcat(msgstr, "s");
+ msgstr = strcat(msgstr, " left");
+
+ centerprint_atprio(other, CENTERPRIO_MAPVOTE, msgstr);
+ }
+ }
+}
+void MapVote_Start()
+{
+ if(mapvote_run)
+ return;
+
+ MapInfo_Enumerate();
+ if(MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), 0, (g_maplist_allow_hidden ? MAPINFO_FLAG_HIDDEN : 0), 1))
+ mapvote_run = TRUE;
+}
+void MapVote_Think()
+{
+ if(!mapvote_run)
+ return;
+
+ if(alreadychangedlevel)
+ return;
+
+ if(time < mapvote_nextthink)
+ return;
+ //dprint("tick\n");
+
+ mapvote_nextthink = time + 0.5;
+
+ if(!mapvote_initialized)
+ {
+ mapvote_initialized = TRUE;
+ if(DoNextMapOverride())
+ return;
+ if(!cvar("g_maplist_votable") || player_count <= 0)
+ {
+ GotoNextMap();
+ return;
+ }
+ MapVote_Init();
+ }
+
+ MapVote_Tick();
+};
+
+string GotoMap(string m)
+{
+ if(!MapInfo_CheckMap(m))
+ return "The map you chose is not available on this server.";
+ cvar_set("nextmap", m);
+ cvar_set("timelimit", "-1");
+ if(mapvote_initialized || alreadychangedlevel)
+ {
+ if(DoNextMapOverride())
+ return "Map switch initiated.";
+ else
+ return "Hm... no. For some reason I like THIS map more.";
+ }
+ else
+ return "Map switch will happen after scoreboard.";
+}
+
float GameCommand_Generic(string command)
{
float argc;
@@ -79,6 +613,7 @@
print(" maplist add map\n");
print(" maplist remove map\n");
print(" maplist shuffle\n");
+ print(" suggestmap map\n");
return TRUE;
}
@@ -561,6 +1096,8 @@
}
return TRUE;
#endif
+ } else if(argv(0) == "suggestmap") {
+ print(strcat(MapVote_Suggest(argv(1)), "\n"));
}
return FALSE;
Modified: trunk/data/qcsrc/server/clientcommands.qc
===================================================================
--- trunk/data/qcsrc/server/clientcommands.qc 2008-12-11 14:48:53 UTC (rev 5191)
+++ trunk/data/qcsrc/server/clientcommands.qc 2008-12-11 15:00:11 UTC (rev 5192)
@@ -56,7 +56,6 @@
}
void ReadyCount();
-string MapVote_Suggest(string m);
.float floodcontrol_chat;
.float floodcontrol_team;
Modified: trunk/data/qcsrc/server/g_world.qc
===================================================================
--- trunk/data/qcsrc/server/g_world.qc 2008-12-11 14:48:53 UTC (rev 5191)
+++ trunk/data/qcsrc/server/g_world.qc 2008-12-11 15:00:11 UTC (rev 5192)
@@ -1786,541 +1786,6 @@
NextLevel();
};
-float mapvote_nextthink;
-float mapvote_initialized;
-float mapvote_keeptwotime;
-float mapvote_timeout;
-string mapvote_message;
-string mapvote_screenshot_dir;
-
-float mapvote_count;
-float mapvote_count_real;
-string mapvote_maps[MAPVOTE_COUNT];
-float mapvote_maps_suggested[MAPVOTE_COUNT];
-string mapvote_suggestions[MAPVOTE_COUNT];
-float mapvote_suggestion_ptr;
-float mapvote_maxlen;
-float mapvote_voters;
-float mapvote_votes[MAPVOTE_COUNT];
-float mapvote_run;
-float mapvote_detail;
-float mapvote_abstain;
-float mapvote_dirty;
-.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!";
- m = MapInfo_FixName(m);
- if(!m)
- return "The map you suggested is not available on this server.";
- if(!cvar("g_maplist_votable_override_mostrecent"))
- if(Map_IsRecent(m))
- return "This server does not allow for recent maps to be played again. Please be patient for some rounds.";
-
- if(!MapInfo_CheckMap(m))
- return "The map you suggested does not support the current game mode.";
- 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 = floor(random() * mapvote_suggestion_ptr);
- }
- else
- {
- i = mapvote_suggestion_ptr;
- mapvote_suggestion_ptr += 1;
- }
- if(mapvote_suggestions[i] != "")
- strunzone(mapvote_suggestions[i]);
- mapvote_suggestions[i] = strzone(m);
- if(cvar("sv_eventlog"))
- GameLogEcho(strcat(":vote:suggested:", m, ":", ftos(self.playerid)));
- return strcat("Suggestion of ", m, " 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_SendData(float target);
-void MapVote_Init()
-{
- float i;
- float nmax, smax;
-
- MapVote_ClearAllVotes();
-
- mapvote_count = 0;
- mapvote_detail = !cvar("g_maplist_votable_nodetail");
- mapvote_abstain = cvar("g_maplist_votable_abstain");
-
- if(mapvote_abstain)
- nmax = min(MAPVOTE_COUNT - 1, cvar("g_maplist_votable"));
- else
- nmax = min(MAPVOTE_COUNT, cvar("g_maplist_votable"));
- smax = min3(nmax, cvar("g_maplist_votable_suggestions"), mapvote_suggestion_ptr);
-
- if(mapvote_suggestion_ptr)
- for(i = 0; i < 100 && mapvote_count < smax; ++i)
- MapVote_AddVotable(mapvote_suggestions[floor(random() * mapvote_suggestion_ptr)], 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", MapInfo_ListAllowedMaps(0, MAPINFO_FLAG_HIDDEN));
- localcmd("\nmenu_cmd sync\n");
- for(i = 0; i < 100 && mapvote_count < nmax; ++i)
- MapVote_AddVotable(GetNextMap(), FALSE);
- }
-
- mapvote_count_real = mapvote_count;
- if(mapvote_abstain)
- MapVote_AddVotable("don't care", 0);
-
- //dprint("mapvote count is ", ftos(mapvote_count), "\n");
-
- mapvote_keeptwotime = time + cvar("g_maplist_votable_keeptwotime");
- mapvote_timeout = time + cvar("g_maplist_votable_timeout");
- if(mapvote_count_real < 3 || mapvote_keeptwotime <= time)
- mapvote_keeptwotime = 0;
- mapvote_message = "Choose a map and press its key!";
-
- mapvote_screenshot_dir = cvar_string("g_maplist_votable_screenshot_dir");
- if(mapvote_screenshot_dir == "")
- mapvote_screenshot_dir = "maps";
- mapvote_screenshot_dir = strzone(mapvote_screenshot_dir);
-
- if(!cvar("g_maplist_textonly"))
- MapVote_SendData(MSG_ALL);
-}
-
-void MapVote_SendPicture(float id)
-{
- msg_entity = self;
- WriteByte(MSG_ONE, SVC_TEMPENTITY);
- WriteByte(MSG_ONE, TE_CSQC_MAPVOTE);
- WriteByte(MSG_ONE, MAPVOTE_NET_PIC);
- WriteByte(MSG_ONE, id);
- WritePicture(MSG_ONE, strcat(mapvote_screenshot_dir, "/", mapvote_maps[id]), 3072);
-}
-
-float GameCommand_MapVote(string cmd)
-{
- if(!intermission_running)
- return FALSE;
- if(!cvar("g_maplist_textonly"))
- {
- if(cmd == "mv_getpic")
- {
- MapVote_SendPicture(stof(argv(1)));
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-float MapVote_GetMapMask()
-{
- float mask, i, power;
- mask = 0;
- for(i = 0, power = 1; i < mapvote_count; ++i, power *= 2)
- if(mapvote_maps[i] != "")
- mask |= power;
- return mask;
-}
-
-void MapVote_SendData(float targ)
-{
- string mapfile, pakfile;
- float i, o;
- WriteByte(targ, SVC_TEMPENTITY);
- WriteByte(targ, TE_CSQC_CONFIG);
- WriteString(targ, "mv_screenshot_dir");
- WriteString(targ, mapvote_screenshot_dir);
-
- WriteByte(targ, SVC_TEMPENTITY);
- WriteByte(targ, TE_CSQC_MAPVOTE);
- WriteByte(targ, MAPVOTE_NET_INIT);
-
- WriteByte(targ, mapvote_count);
- WriteByte(targ, mapvote_abstain);
- WriteByte(targ, mapvote_detail);
- WriteCoord(targ, mapvote_timeout);
- if(mapvote_count <= 8)
- WriteByte(targ, MapVote_GetMapMask());
- else
- WriteShort(targ, MapVote_GetMapMask());
- for(i = 0; i < mapvote_count; ++i)
- if(mapvote_maps[i] != "")
- {
- WriteString(targ, mapvote_maps[i]);
- mapfile = strcat(mapvote_screenshot_dir, "/", mapvote_maps[i]);
- pakfile = whichpack(strcat(mapfile, ".tga"));
- if(pakfile == "")
- pakfile = whichpack(strcat(mapfile, ".jpg"));
- if(pakfile == "")
- pakfile = whichpack(strcat(mapfile, ".png"));
- print("pakfile is ", pakfile, "\n");
- for(o = strstr(pakfile, "/", 0)+1; o > 0; o = strstr(pakfile, "/", 0)+1)
- pakfile = substring(pakfile, o, 999);
- WriteString(targ, pakfile);
- }
-}
-
-void MapVote_UpdateData(float targ)
-{
- float i;
- WriteByte(targ, SVC_TEMPENTITY);
- WriteByte(targ, TE_CSQC_MAPVOTE);
- WriteByte(targ, MAPVOTE_NET_UPDATE);
- if(mapvote_count <= 8)
- WriteByte(targ, MapVote_GetMapMask());
- else
- WriteShort(targ, MapVote_GetMapMask());
- if(mapvote_detail)
- for(i = 0; i < mapvote_count; ++i)
- if(mapvote_maps[i] != "")
- WriteByte(targ, mapvote_votes[i]);
-}
-
-void MapVote_TellVote(float targ, float vote)
-{
- WriteByte(targ, SVC_TEMPENTITY);
- WriteByte(targ, TE_CSQC_MAPVOTE);
- WriteByte(targ, MAPVOTE_NET_OWNVOTE);
- WriteByte(targ, vote);
-}
-
-float MapVote_Finished(float mappos)
-{
- string result;
- float i;
- float didntvote;
-
- if(cvar("sv_eventlog"))
- {
- result = strcat(":vote:finished:", mapvote_maps[mappos]);
- result = strcat(result, ":", ftos(mapvote_votes[mappos]), "::");
- didntvote = mapvote_voters;
- for(i = 0; i < mapvote_count; ++i)
- if(mapvote_maps[i] != "")
- {
- didntvote -= mapvote_votes[i];
- if(i != mappos)
- {
- result = strcat(result, ":", mapvote_maps[i]);
- result = strcat(result, ":", ftos(mapvote_votes[i]));
- }
- }
- result = strcat(result, ":didn't vote:", ftos(didntvote));
-
- GameLogEcho(result);
- if(mapvote_maps_suggested[mappos])
- GameLogEcho(strcat(":vote:suggestion_accepted:", mapvote_maps[mappos]));
- }
-
- FOR_EACH_REALCLIENT(other)
- FixClientCvars(other);
-
- Map_Goto_SetStr(mapvote_maps[mappos]);
- Map_Goto();
- alreadychangedlevel = TRUE;
- 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;
- float mapvote_voters_real;
- string result;
-
- mapvote_voters_real = mapvote_voters;
- if(mapvote_abstain)
- mapvote_voters_real -= mapvote_votes[mapvote_count - 1];
-
- RandomSelection_Init();
- for(i = 0; i < mapvote_count_real; ++i) if(mapvote_maps[i] != "")
- RandomSelection_Add(world, i, 1, mapvote_votes[i]);
- firstPlace = RandomSelection_chosen_float;
- firstPlaceVotes = RandomSelection_best_priority;
- //dprint("First place: ", ftos(firstPlace), "\n");
- //dprint("First place votes: ", ftos(firstPlaceVotes), "\n");
-
- RandomSelection_Init();
- for(i = 0; i < mapvote_count_real; ++i) if(mapvote_maps[i] != "")
- if(i != firstPlace)
- RandomSelection_Add(world, i, 1, mapvote_votes[i]);
- secondPlace = RandomSelection_chosen_float;
- secondPlaceVotes = RandomSelection_best_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_real - firstPlaceVotes) < firstPlaceVotes)
- return MapVote_Finished(firstPlace);
-
- if(mapvote_keeptwotime)
- if(time > mapvote_keeptwotime || (mapvote_voters_real - firstPlaceVotes - secondPlaceVotes) < secondPlaceVotes)
- {
- float didntvote;
- mapvote_dirty = TRUE;
- 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), "::");
- didntvote = mapvote_voters;
- for(i = 0; i < mapvote_count; ++i)
- if(mapvote_maps[i] != "")
- {
- didntvote -= mapvote_votes[i];
- if(i != firstPlace)
- if(i != secondPlace)
- {
- result = strcat(result, ":", mapvote_maps[i]);
- result = strcat(result, ":", ftos(mapvote_votes[i]));
- if(i < mapvote_count_real)
- {
- strunzone(mapvote_maps[i]);
- mapvote_maps[i] = "";
- }
- }
- }
- result = strcat(result, ":didn't vote:", ftos(didntvote));
- if(cvar("sv_eventlog"))
- GameLogEcho(result);
- }
-
- return FALSE;
-}
-void MapVote_Tick()
-{
- string msgstr;
- string tmp;
- float i;
- float keeptwo;
- float totalvotes;
-
- keeptwo = mapvote_keeptwotime;
- MapVote_CheckRules_1(); // count
- if(MapVote_CheckRules_2()) // decide
- return;
-
- totalvotes = 0;
- FOR_EACH_REALCLIENT(other)
- {
- // hide scoreboard again
- if(other.health != 2342)
- {
- other.health = 2342;
- other.impulse = 0;
- if(clienttype(other) == CLIENTTYPE_REAL)
- {
- if(cvar("g_maplist_textonly"))
- 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)
- play2(other, "misc/invshot.wav");
-
- // 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;
- if(mapvote_detail)
- mapvote_dirty = TRUE;
-
- msg_entity = other;
- MapVote_TellVote(MSG_ONE, other.mapvote);
- }
- other.impulse = 0;
-
- if(other.mapvote)
- ++totalvotes;
- }
-
- MapVote_CheckRules_1(); // just count
-
- if(!cvar("g_maplist_textonly"))
- if(mapvote_dirty) // 1 if "keeptwo" or "impulse" happened before
- {
- MapVote_UpdateData(MSG_BROADCAST);
- mapvote_dirty = FALSE;
- }
-
- if(cvar("g_maplist_textonly"))
- {
- 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);
- if(mapvote_abstain)
- msgstr = substring(msgstr, 1, strlen(msgstr) - 1);
- 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 = strpad(mapvote_maxlen, tmp);
- tmp = strcat(ftos(mod(i + 1, 10)), ": ", tmp);
- if(mapvote_detail)
- {
- tmp = strcat(tmp, " ^2(", ftos(mapvote_votes[i]), " vote");
- if(mapvote_votes[i] != 1)
- tmp = strcat(tmp, "s");
- tmp = strcat(tmp, ")");
- tmp = strpad(mapvote_maxlen + 15, tmp);
- }
- if(mapvote_abstain)
- if(i == mapvote_count - 1)
- msgstr = strcat(msgstr, "\n");
- if(other.mapvote == i + 1)
- msgstr = strcat(msgstr, "^3> ", tmp, "\n");
- else
- msgstr = strcat(msgstr, "^7 ", tmp, "\n");
- }
-
- msgstr = strcat(msgstr, "\n\n^2", ftos(totalvotes), " vote");
- if(totalvotes != 1)
- msgstr = strcat(msgstr, "s");
- msgstr = strcat(msgstr, " cast");
- i = ceil(mapvote_timeout - time);
- msgstr = strcat(msgstr, "\n", ftos(i), " second");
- if(i != 1)
- msgstr = strcat(msgstr, "s");
- msgstr = strcat(msgstr, " left");
-
- centerprint_atprio(other, CENTERPRIO_MAPVOTE, msgstr);
- }
- }
-}
-void MapVote_Start()
-{
- if(mapvote_run)
- return;
-
- MapInfo_Enumerate();
- if(MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), 0, (g_maplist_allow_hidden ? MAPINFO_FLAG_HIDDEN : 0), 1))
- mapvote_run = TRUE;
-}
-void MapVote_Think()
-{
- if(!mapvote_run)
- return;
-
- if(alreadychangedlevel)
- return;
-
- if(time < mapvote_nextthink)
- return;
- //dprint("tick\n");
-
- mapvote_nextthink = time + 0.5;
-
- if(!mapvote_initialized)
- {
- mapvote_initialized = TRUE;
- if(DoNextMapOverride())
- return;
- if(!cvar("g_maplist_votable") || player_count <= 0)
- {
- GotoNextMap();
- return;
- }
- MapVote_Init();
- }
-
- MapVote_Tick();
-};
-
-string GotoMap(string m)
-{
- if(!MapInfo_CheckMap(m))
- return "The map you chose is not available on this server.";
- cvar_set("nextmap", m);
- cvar_set("timelimit", "-1");
- if(mapvote_initialized || alreadychangedlevel)
- {
- if(DoNextMapOverride())
- return "Map switch initiated.";
- else
- return "Hm... no. For some reason I like THIS map more.";
- }
- else
- return "Map switch will happen after scoreboard.";
-}
-
-
void EndFrame()
{
FOR_EACH_REALCLIENT(self)
More information about the nexuiz-commits
mailing list