X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fmapvoting.qc;h=d68b35f435bd0ecced8049fc5886ba0dab5c4dc2;hb=a3db866c56c22ccbce46807b9712fb4ca538954c;hp=8d747e254e5f8a9da7afa9043019e097c206f6e4;hpb=969dc49d01d650a812706aba16c765af488605d0;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/mapvoting.qc b/qcsrc/server/mapvoting.qc index 8d747e254..d68b35f43 100644 --- a/qcsrc/server/mapvoting.qc +++ b/qcsrc/server/mapvoting.qc @@ -1,19 +1,19 @@ #include "mapvoting.qh" -#include -#include -#include -#include -#include "g_world.qh" -#include "command/cmd.qh" -#include "command/getreplies.qh" -#include "../common/constants.qh" +#include +#include #include -#include "../common/mapinfo.qh" -#include "../common/playerstats.qh" +#include #include -#include "../common/util.qh" - +#include +#include +#include +#include +#include +#include +#include +#include +#include // definitions @@ -48,10 +48,10 @@ entity mapvote_ent; */ Gametype GameTypeVote_Type_FromString(string type_name) { - Gametype type = MapInfo_Type_FromString(type_name, false); + Gametype type = MapInfo_Type_FromString(type_name, false, false); if (type == NULL) type = MapInfo_Type_FromString(cvar_string( - strcat("sv_vote_gametype_",type_name,"_type")), false); + strcat("sv_vote_gametype_",type_name,"_type")), false, false); return type; } @@ -59,11 +59,11 @@ int GameTypeVote_AvailabilityStatus(string type_name) { int flag = GTV_FORBIDDEN; - Gametype type = MapInfo_Type_FromString(type_name, false); + Gametype type = MapInfo_Type_FromString(type_name, false, false); if ( type == NULL ) { type = MapInfo_Type_FromString(cvar_string( - strcat("sv_vote_gametype_",type_name,"_type")), false); + strcat("sv_vote_gametype_",type_name,"_type")), false, false); flag |= GTV_CUSTOM; } @@ -197,9 +197,32 @@ void MapVote_AddVotable(string nextMap, bool isSuggestion) mapvote_count += 1; } +void MapVote_AddVotableMaps(int nmax, int smax) +{ + int available_maps = 0; + if (autocvar_g_maplist != "") + { + int c = tokenizebyseparator(autocvar_g_maplist, " "); + for (int i = 0; i < c; ++i) + { + if (Map_Check(i, 1) || Map_Check(i, 2)) + ++available_maps; + } + } + int max_attempts = available_maps; + if (available_maps >= 2) + max_attempts = min(available_maps * 5, 100); + + if (smax && mapvote_suggestion_ptr) + for(int i = 0; i < max_attempts && mapvote_count < smax; ++i) + MapVote_AddVotable(mapvote_suggestions[floor(random() * mapvote_suggestion_ptr)], true); + + for (int i = 0; i < max_attempts && mapvote_count < nmax; ++i) + MapVote_AddVotable(GetNextMap(), false); +} + void MapVote_Init() { - int i; int nmax, smax; MapVote_ClearAllVotes(); @@ -220,15 +243,10 @@ void MapVote_Init() if(mapvote_screenshot_dirs_count == 0) mapvote_screenshot_dirs_count = tokenize_console("maps levelshots"); mapvote_screenshot_dirs_count = min(mapvote_screenshot_dirs_count, MAPVOTE_SCREENSHOT_DIRS_COUNT); - for(i = 0; i < mapvote_screenshot_dirs_count; ++i) + for(int i = 0; i < mapvote_screenshot_dirs_count; ++i) mapvote_screenshot_dirs[i] = strzone(argv(i)); - 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); + MapVote_AddVotableMaps(nmax, smax); if(mapvote_count == 0) { @@ -237,8 +255,7 @@ void MapVote_Init() if(autocvar_g_maplist_shuffle) ShuffleMaplist(); localcmd("\nmenu_cmd sync\n"); - for(i = 0; i < 100 && mapvote_count < nmax; ++i) - MapVote_AddVotable(GetNextMap(), false); + MapVote_AddVotableMaps(nmax, 0); } mapvote_count_real = mapvote_count; @@ -337,6 +354,8 @@ void GameTypeVote_SendOption(int i) } } +int mapvote_winner; +float mapvote_winner_time; bool MapVote_SendEntity(entity this, entity to, int sf) { int i; @@ -344,6 +363,9 @@ bool MapVote_SendEntity(entity this, entity to, int sf) if(sf & 1) sf &= ~2; // if we send 1, we don't need to also send 2 + if (!mapvote_winner_time) + sf &= ~8; // no winner yet + WriteHeader(MSG_ENTITY, ENT_CLIENT_MAPVOTE); WriteByte(MSG_ENTITY, sf); @@ -361,13 +383,13 @@ bool MapVote_SendEntity(entity this, entity to, int sf) if ( gametypevote ) { // gametype vote - WriteByte(MSG_ENTITY, 1); + WriteByte(MSG_ENTITY, BIT(0)); // gametypevote_flags WriteString(MSG_ENTITY, autocvar_nextmap); } else if ( autocvar_sv_vote_gametype ) { // map vote but gametype has been chosen via voting screen - WriteByte(MSG_ENTITY, 2); + WriteByte(MSG_ENTITY, BIT(1)); // gametypevote_flags WriteString(MSG_ENTITY, MapInfo_Type_ToText(MapInfo_CurrentGametype())); } else @@ -401,12 +423,17 @@ bool MapVote_SendEntity(entity this, entity to, int sf) WriteByte(MSG_ENTITY, to.mapvote); } + if(sf & 8) + { + WriteByte(MSG_ENTITY, mapvote_winner + 1); + } + return true; } void MapVote_Spawn() { - Net_LinkEntity(mapvote_ent = spawn(), false, 0, MapVote_SendEntity); + Net_LinkEntity(mapvote_ent = new(mapvote_ent), false, 0, MapVote_SendEntity); } void MapVote_TouchMask() @@ -419,6 +446,13 @@ void MapVote_TouchVotes(entity voter) mapvote_ent.SendFlags |= 4; } +void MapVote_Winner(int mappos) +{ + mapvote_ent.SendFlags |= 8; + mapvote_winner_time = time; + mapvote_winner = mappos; +} + bool MapVote_Finished(int mappos) { if(alreadychangedlevel) @@ -470,8 +504,7 @@ bool MapVote_Finished(int mappos) return false; } - Map_Goto_SetStr(mapvote_maps[mappos]); - Map_Goto(0); + MapVote_Winner(mappos); alreadychangedlevel = true; return true; @@ -520,14 +553,14 @@ bool MapVote_CheckRules_2() if ( mapvote_maps_flags[i] & GTV_AVAILABLE ) { RandomSelection_AddFloat(i, 1, mapvote_selections[i]); - if ( gametypevote && mapvote_maps[i] == MapInfo_Type_ToString(MapInfo_CurrentGametype()) ) + if ( gametypevote && mapvote_maps[i] == MapInfo_Type_ToString(MapInfo_CurrentGametype()) ) { currentVotes = mapvote_selections[i]; currentPlace = i; } } firstPlaceVotes = RandomSelection_best_priority; - if ( autocvar_sv_vote_gametype_default_current && firstPlaceVotes == 0 ) + if (gametypevote && autocvar_sv_vote_gametype_default_current && firstPlaceVotes == 0) firstPlace = currentPlace; else firstPlace = RandomSelection_chosen_float; @@ -548,8 +581,12 @@ bool MapVote_CheckRules_2() if(firstPlace == -1) error("No first place in map vote... WTF?"); - if(secondPlace == -1 || time > mapvote_timeout || (mapvote_voters_real - firstPlaceVotes) < firstPlaceVotes) + if(secondPlace == -1 || time > mapvote_timeout + || (mapvote_voters_real - firstPlaceVotes) < firstPlaceVotes + || mapvote_selections[mapvote_count - 1] == mapvote_voters) + { return MapVote_Finished(firstPlace); + } if(mapvote_keeptwotime) if(time > mapvote_keeptwotime || (mapvote_voters_real - firstPlaceVotes - secondPlaceVotes) < secondPlaceVotes) @@ -585,17 +622,23 @@ bool MapVote_CheckRules_2() void MapVote_Tick() { - MapVote_CheckRules_1(); // count if(MapVote_CheckRules_2()) // decide return; int totalvotes = 0; - FOREACH_CLIENT(IS_REAL_CLIENT(it), { + FOREACH_CLIENT(true, { + if(!IS_REAL_CLIENT(it)) + { + // apply the same special health value to bots too for consistency's sake + if(GetResource(it, RES_HEALTH) != 2342) + SetResourceExplicit(it, RES_HEALTH, 2342); + continue; + } // hide scoreboard again if(GetResource(it, RES_HEALTH) != 2342) { - SetResourceExplicit(it, RES_HEALTH, 2342); + SetResourceExplicit(it, RES_HEALTH, 2342); // health in the voting phase CS(it).impulse = 0; msg_entity = it; @@ -640,6 +683,16 @@ void MapVote_Think() if(!mapvote_run) return; + if (mapvote_winner_time) + { + if (time > mapvote_winner_time + 1) + { + Map_Goto_SetStr(mapvote_maps[mapvote_winner]); + Map_Goto(0); + } + return; + } + if(alreadychangedlevel) return; @@ -648,6 +701,8 @@ void MapVote_Think() //dprint("tick\n"); mapvote_nextthink = time + 0.5; + if (mapvote_nextthink > mapvote_timeout - 0.1) // make sure there's no delay when map vote times out + mapvote_nextthink = mapvote_timeout + 0.001; if(!mapvote_initialized) { @@ -791,7 +846,7 @@ bool GameTypeVote_Start() mapvote_count_real = mapvote_count; - gametypevote = 1; + gametypevote = true; if ( really_available == 0 ) {