I have adapted it in my own way so that it supports voting for maps and game modes.
#include maps\mp\_utility;
#include common_scripts\utility;
#include maps\mp\gametypes\_hud_util;
init() {
precacheshader("gradient_fadein");
precacheshader("gradient_top");
precacheshader("white");
//Set here the maps you want to rotate, separate them with a #.
level.mapvotemaps = strtok("mp_alpha#mp_bootleg#mp_bravo#mp_carbon#mp_dome#mp_exchange#mp_hardhat#mp_interchange#mp_lambeth#mp_mogadishu#mp_paris#mp_plaza2#mp_radar#mp_seatown#mp_underground#mp_village#mp_terminal_cls#mp_rust#mp_highrise#mp_italy#mp_park#mp_overwatch#mp_morningwood#mp_meteora#mp_cement#mp_qadeem#mp_restrepo_ss#mp_hillside_ss#mp_courtyard_ss#mp_aground_ss#mp_six_ss#mp_burn_ss#mp_crosswalk_ss#mp_shipbreaker#mp_roughneck#mp_moab#mp_boardwalk#mp_nola#mp_favela#mp_nuked#mp_nightshift", "#");
//Set the type/gamemode here, whatever your dsr file is called without the . When doing so, you must also modify within the "maptostring()" function in the "switch(type)" section so that the name of the dsr file matches the type/game mode.
level.mapvotetype = strtok("TDM_default#DOM_default", "#");
//The description of maps must go hand in hand with the maps, so that there are no errors when showing them in the vote.
level.mapvotedescs = strtok("European city center. Great for Team \nDefender.#Medium sized Asian market. Fun for all game \nmodes.#African colonial settlement. Fight to control \nthe center.#Medium sized refinery. Great for any number \nof players.#Small outpost in the desert. Fast and frantic \naction.#Urban map with wide streets. Good for long \nand short range fights.#A small construction site. Fast paced, close \nquarter action.#Destroyed freeway. Great for a wide range of \nspaces and styles.#Derelict Russian ghost town. Great for \ncareful, tactical engagements.#Crash site in an African city. Classic urban \ncombat.#Parisian district. Great for Domination and Kill \nConfirmed.#Medium sized German mall. Intense Search & \nDestroy games.#Large Siberian airbase. Great for epic large \nbattles.#A costal town. Narrow streets bring hectic, \nclose encounters.#Small subway station. Fast paced action both \ninside and out.#Large African village. Great for all game \nmodes.#Russian airport terminal under siege. The \nclassic fan favorite is back.#Tiny desert sandstorm. Fast-paced action on \na small map.#Classic MW2's Rooftop skyscraper.#A small coastal Italian town. Features tight \nclose quarter combat.#Large New York park set in autumn. Great for \nlong distance fire fights.#Unfinished top of a skyscraper. Features \ntense Demolition matches.#Air Force One crash site. Very open map with a \nfew homes that provide cover.#Greek Monastery on a sandstone pillar. \nFeatures both medium and long range combat.#Korean cement factory. Great for close \nquarter combat and tactical maneuvering.#Luxury resort in Dubai. Features Intense \nDomination maches# Remote outpost in Afghanistan. Tight, Sparse \ninteriors linked by open lanes and overlooks #Upscale beachside retreat. Multi-tiered run \nand gun combat haven. #Roman ruins near Mt. Vesuvius. Strong \ninteriors offset by multi-level flanks.#Shipwreck on the irish coast. Open layout \nallows for long distance engagements#American farm in the path of a monster \ntornado. Sparse interiors and well-defined lanes.#War torn section of mid-east highway. \nPlentiful cover and close quarter fighting#Metro intersection on lockdown. Strong \ninterior locations and tactical urban combat#Ship scavenging operation on the indian \ncoast. Dominant overwatch positions and \n strong flank routes.#Deep Water drilling rig. Medium to long range \nengagements between multi-tiered, joined \nplatforms#Abandoned Utah mining settlement. Features \nan open layout and strong flanks.#Jersey shore amusement boardwalk. \nElevated main path set off by close quarters. \nflanks#New Orleans under assault. Features \nfast-paced matches with abundant close \nquarters fighting.#Alleyways of Brazil. Great for all modes\nand all sizes.#A deserted nuke testing facility used in the Cold War.#Urban City fighting. In and out of apartments/nclose range engagements.", "#");
level.mapvoteindices = [];
tryes = 0;
while(level.mapvoteindices.size < 6 && tryes < 100) {
tryes++;
j = randomint(level.mapvotemaps.size);
k = randomint(level.mapvotetype.size);
while(inArray(level.mapvoteindices,(level.mapvotemaps[j] + "#" + level.mapvotetype[k] + "#" + level.mapvotedescs[j])))
{
j = randomint(level.mapvotemaps.size);
k = randomint(level.mapvotetype.size);
}
level.mapvoteindices[level.mapvoteindices.size] = level.mapvotemaps[j] + "#" + level.mapvotetype[k] + "#" + level.mapvotedescs[j];
}
replacefunc(maps\mp\gametypes\_gamelogic::waittillFinalKillcamDone, ::finalkillcamhook);
}
finalkillcamhook() {
if (!IsDefined(level.finalkillcam_winner)) {
mapvote();
return false;
} else {
level waittill("final_killcam_done");
mapvote();
return true;
}
}
mapvote() {
if (!waslastround()) return;
level.mapvoteui[0] = shader("white", "TOP", "TOP", 0, 120, 350, 20, (0.157,0.173,0.161), 1, 1, true);
level.mapvoteui[1] = shader("white", "TOP", "TOP", 0, 140, 350, 60, (0.310,0.349,0.275), 1, 1, true);
level.mapvoteui[2] = shader("gradient_top", "TOP", "TOP", 0, 140, 350, 2, (1,1,1), 1, 2, true);
level.mapvoteui[3] = shader("white", "TOP", "TOP", 0, 200, 350, 20, (0.212,0.231,0.220), 1, 1, true);
level.mapvoteui[4] = shader("white", "TOP", "TOP", 0, 220, 350, 20, (0.180,0.196,0.188), 1, 1, true);
level.mapvoteui[5] = shader("white", "TOP", "TOP", 0, 240, 350, 20, (0.212,0.231,0.220), 1, 1, true);
level.mapvoteui[6] = shader("white", "TOP", "TOP", 0, 260, 350, 20, (0.180,0.196,0.188), 1, 1, true);
level.mapvoteui[7] = shader("white", "TOP", "TOP", 0, 280, 350, 20, (0.212,0.231,0.220), 1, 1, true);
level.mapvoteui[8] = shader("white", "TOP", "TOP", 0, 300, 350, 20, (0.180,0.196,0.188), 1, 1, true);
level.mapvoteui[9] = shader("white", "TOP", "TOP", 0, 320, 350, 20, (0.157,0.173,.161), 1, 1, true);
level.mapvoteui[10] = shader("white", "TOP", "TOP", 0, 340, 350, 20, (0.310,0.349,0.275), 1, 1, true);
level.mapvoteui[11] = shader("gradient_top", "TOP", "TOP", 0, 320, 350, 2, (1,1,1), 1, 2, true);
level.mapvoteui[12] = text(&"VOTING PHASE: ", "LEFT", "TOP", -170, 130, 1, "hudSmall", (1,1,1), 1, 3, true, 20);
level.mapvoteui[13] = text( maptostring(strTok(level.mapvoteindices[0],"#")[0], strTok(level.mapvoteindices[0],"#")[1]), "LEFT", "TOP", -170, 210, 1.5, "objective", (1,1,1), 1, 3, true);
level.mapvoteui[14] = text( maptostring(strTok(level.mapvoteindices[1],"#")[0], strTok(level.mapvoteindices[1],"#")[1]), "LEFT", "TOP", -170, 230, 1.5, "normal", (1,1,1), 1, 3, true);
level.mapvoteui[15] = text( maptostring(strTok(level.mapvoteindices[2],"#")[0], strTok(level.mapvoteindices[2],"#")[1]), "LEFT", "TOP", -170, 250, 1.5, "normal", (1,1,1), 1, 3, true);
level.mapvoteui[16] = text( maptostring(strTok(level.mapvoteindices[3],"#")[0], strTok(level.mapvoteindices[3],"#")[1]), "LEFT", "TOP", -170, 270, 1.5, "normal", (1,1,1), 1, 3, true);
level.mapvoteui[17] = text( maptostring(strTok(level.mapvoteindices[4],"#")[0], strTok(level.mapvoteindices[4],"#")[1]), "LEFT", "TOP", -170, 290, 1.5, "normal", (1,1,1), 1, 3, true);
level.mapvoteui[18] = text( maptostring(strTok(level.mapvoteindices[5],"#")[0], strTok(level.mapvoteindices[5],"#")[1]), "LEFT", "TOP", -170, 310, 1.5, "normal", (1,1,1), 1, 3, true);
//////////////
//TODO: speed_throw/toggleads_throw will show bound/unbound for hold/toggle ads players. compromise may be to use forward/back, depending on how controller
//bindings handle this.
level.mapvoteui[19] = text("Up ^2[{+attack}] ^7Down ^2[{+toggleads_throw}]", "LEFT", "TOP", -170, 330, 1.5, "normal", (1,1,1), 1, 3, true);
level.mapvoteui[20] = text("Vote ^2[{+activate}]", "RIGHT", "TOP", 170, 330, 1.5, "normal", (1,1,1), 1, 3, true);
foreach(player in level.players) player thread input();
for(i = 0; i <= 20; i++) {
level.mapvoteui[12] setvalue(20 - i);
//playsoundonplayers("trophy_detect_projectile");
wait 1;
}
level notify("mapvote_over");
besti = 0;
bestv = -1;
for(i = 0; i < 6; i++) {
if(level.mapvoteui[i + 13].value > bestv) {
besti = i;
bestv = level.mapvoteui[i + 13].value;
}
}
//Note: We wait to prevent the scoreboard popping up at the end for a cleaner transition (Don't wait infinitely as a failsafe).
//TODO: Proper manipulation of sv_level.mapvotemaps is the better way to do this as it would allow the final scoreboard to show.
setDvar( "sv_maprotationcurrent", "dsr " + strTok(level.mapvoteindices[besti],"#")[1] + " map " + strTok(level.mapvoteindices[besti],"#")[0] );
}
input() {
self endon("disconnect");
self endon("mapvote_over");
index = 0;
selected = -1;
select[0] = self text((index + 1) + "/6", "RIGHT", "TOP", 170, 130, 1.5, "normal", (1,1,1), 1, 3, false);
select[1] = self text(strTok(level.mapvoteindices[index],"#")[2], "LEFT", "TOP", -170, 150, 1.5, "normal", (1,1,1), 1, 3, false);
select[2] = self shader("gradient_fadein", "TOP", "TOP", 0, 200, 350, 20, (1,1,1), 0.5, 2, false);
select[3] = self shader("gradient_top", "TOP", "TOP", 0, 220, 350, 2, (1,1,1), 1, 2, false);
self notifyonplayercommand("up", "+attack");
self notifyonplayercommand("up", "+forward");
self notifyonplayercommand("down", "+toggleads_throw");
self notifyonplayercommand("down", "+speed_throw");
self notifyonplayercommand("down", "+back");
self notifyonplayercommand("select", "+usereload");
self notifyonplayercommand("select", "+activate");
self notifyonplayercommand("select", "+frag");
for(;;) {
command = self waittill_any_return("up", "down", "select");
if(command == "up" && index > 0) {
index--;
select[0] settext((index + 1) + "/6");
select[1] settext(strTok(level.mapvoteindices[index],"#")[2]);
select[2].y -= 20;
select[3].y -= 20;
self playlocalsound("mouse_over");
} else if(command == "down" && index < 5) {
index++;
select[0] settext((index + 1) + "/6");
select[1] settext(strTok(level.mapvoteindices[index],"#")[2]);
select[2].y += 20;
select[3].y += 20;
self playlocalsound("mouse_over");
} else if(command == "select") {
if(selected == -1) {
selected = index;
level.mapvoteui[selected + 13].value += 1;
level.mapvoteui[selected + 13].text = strTok(level.mapvoteui[selected + 13].text,":")[0] + ":" + level.mapvoteui[selected + 13].value;
level.mapvoteui[selected + 13] settext(level.mapvoteui[selected + 13].text);
//iPrintLn(level.mapvoteui[selected + 13].text);
self playlocalsound("mouse_click");
} else if(selected != index) {
level.mapvoteui[selected + 13].value -= 1;
level.mapvoteui[selected + 13].text = strTok(level.mapvoteui[selected + 13].text,":")[0] + ":" + level.mapvoteui[selected + 13].value;
level.mapvoteui[selected + 13] settext(level.mapvoteui[selected + 13].text);
selected = index;
level.mapvoteui[selected + 13].value += 1;
level.mapvoteui[selected + 13].text = strTok(level.mapvoteui[selected + 13].text,":")[0] + ":" + level.mapvoteui[selected + 13].value;
level.mapvoteui[selected + 13] settext(level.mapvoteui[selected + 13].text);
//iPrintLn(level.mapvoteui[selected + 13].text);
self playlocalsound("mouse_click");
}
}
}
}
text(text, align, relative, x, y, fontscale, font, color, alpha, sort, server, value) {
element = spawnstruct();
if(server) {
element = createServerFontString( font, fontscale );
} else {
element = self createFontString( font, fontscale );
}
if(isdefined(value)) {
element.label = text;
element.value = value;
element setvalue(value);
} else {
element settext(text);
element.text = text;
element.value = 0;
}
element.hidewheninmenu = true;
element.color = color;
element.alpha = alpha;
element.sort = sort;
element setpoint(align, relative, x, y);
return element;
}
addTextHud( who, x, y, alpha, alignX, alignY, horiz, vert, fontScale, sort ) {
if( isPlayer( who ) )
hud = newClientHudElem( who );
else
hud = newHudElem();
hud.x = x;
hud.y = y;
hud.alpha = alpha;
hud.sort = sort;
hud.alignX = alignX;
hud.alignY = alignY;
if(isdefined(vert))
hud.vertAlign = vert;
if(isdefined(horiz))
hud.horzAlign = horiz;
if(fontScale != 0)
hud.fontScale = fontScale;
hud.foreground = 1;
hud.archived = 0;
return hud;
}
shader(shader, align, relative, x, y, width, height, color, alpha, sort, server) {
element = spawnstruct();
if(server) {
element = newhudelem(self);
} else {
element = newclienthudelem(self);
}
element.elemtype = "icon";
element.hidewheninmenu = true;
element.shader = shader;
element.width = width;
element.height = height;
element.align = align;
element.relative = relative;
element.xoffset = 0;
element.yoffset = 0;
element.children = [];
element.sort = sort;
element.color = color;
element.alpha = alpha;
element setparent(level.uiparent);
element setshader(shader, width, height);
element setpoint(align, relative, x, y);
return element;
}
randomindices() {
array = [];
for (i = 0; i < 6; i++) {
array[i] = randomint(level.mapvotemaps.size);
for (j = 0; j < i; j++) {
if (array[i] == array[j]) {
i--;
break;
}
}
}
return array;
}
maptostring(map,type) {
switch(map) {
case "mp_alpha": map = "LOCKDOWN";
break;
case "mp_bootleg": map = "BOOTLEG";
break;
case "mp_bravo": map = "MISSION";
break;
case "mp_carbon": map = "CARBON";
break;
case "mp_dome": map = "DOME";
break;
case "mp_exchange": map = "DOWNTURN";
break;
case "mp_hardhat": map = "HARDHAT";
break;
case "mp_interchange": map = "INTERCHANGE";
break;
case "mp_lambeth": map = "FALLEN";
break;
case "mp_mogadishu": map = "BAKAARA";
break;
case "mp_paris": map = "RESISTANCE";
break;
case "mp_plaza2": map = "ARKADEN";
break;
case "mp_radar": map = "OUTPOST";
break;
case "mp_seatown": map = "SEATOWN";
break;
case "mp_underground": map = "UNDERGROUND";
break;
case "mp_village": map = "VILLAGE";
break;
case "mp_terminal_cls": map = "TERMINAL";
break;
case "mp_rust": map = "RUST";
break;
case "mp_highrise": map = "HIGHRISE";
break;
case "mp_italy": map = "PIAZZA";
break;
case "mp_park": map = "LIBERATION";
break;
case "mp_overwatch": map = "OVERWATCH";
break;
case "mp_morningwood": map = "BLACK BOX";
break;
case "mp_meteora": map = "SANCTUARY";
break;
case "mp_qadeem": map = "OASIS";
break;
case "mp_restrepo_ss": map = "LOOKOUT";
break;
case "mp_hillside_ss": map = "GETAWAY";
break;
case "mp_courtyard_ss": map = "EROSION";
break;
case "mp_aground_ss": map = "AGROUND";
break;
case "mp_six_ss": map = "VORTEX";
break;
case "mp_burn_ss": map = "U-TURN";
break;
case "mp_crosswalk_ss": map = "INTERSECTION";
break;
case "mp_shipbreaker": map = "DECOMMISSION";
break;
case "mp_roughneck": map = "OFF SHORE";
break;
case "mp_moab": map = "GULCH";
break;
case "mp_boardwalk": map = "BOARDWALK";
break;
case "mp_nola": map = "PARISH";
break;
case "mp_favela": map = "FAVELA";
break;
case "mp_nuked": map = "NUKETOWN";
break;
case "mp_nightshift": map = "SKIDROW";
break;
case "mp_cement": map = "FOUNDATION";
break;
default:
break;
}
switch(type) {
case "TDM_default": map = map + " (TEAM DEATHMATCH)" + " :0";
break;
case "DOM_default":map = map + " (DOMINATION)" + " :0";
break;
case "DEM_default": map = map + " (DEMOLITION)" + " :0";
break;
case "INF_Default": map = map + " (INFECTED)" + " :0";
break;
case "FFA_default":map = map + " (FREE FOR ALL)" + " :0";
break;
case "CTF_default":map = map + " (CAPTURE THE FLAG)" + " :0";
break;
case "DZ_default":map = map + " (DROP ZONE)" + " :0";
break;
case "GG_default":map = map + " (GUN GAME)" + " :0";
break;
case "HQ_default":map = map + " (HEADQUARTERS)" + " :0";
break;
case "JUG_default":map = map + " (JUGGERNAUT)" + " :0";
break;
case "KC_default":map = map + " (KILL CONFIRMED)" + " :0";
break;
case "OIC_default":map = map + " (ONE IN THE CHAMBER)" + " :0";
break;
case "SAB_default":map = map + " (SABOTAGE)" + " :0";
break;
case "SD_default":map = map + " (SEARCH AND DESTROY)" + " :0";
break;
case "TDEF_default":map = map + " (TEAM DEFENDER)" + " :0";
break;
case "TJ_default":map = map + " (TEAM JUGGERNAUT)" + " :0";
break;
default:
break;
}
return map;
}
inArray(array, text)
{
for(i=0; i<array.size; i++)
{
if(array[i] == text)
return true;
}
return false;
}