mirror of
https://github.com/Resxt/Plutonium-T6-Scripts.git
synced 2025-04-19 13:42:54 +00:00
Create mapvote
This commit is contained in:
parent
ed74e92e0f
commit
92c37b15ea
105
mapvote/README.md
Normal file
105
mapvote/README.md
Normal file
@ -0,0 +1,105 @@
|
||||
# Mapvote
|
||||
|
||||
A customizable mapvote script for multiplayer.
|
||||
Zombies is not supported yet but is planned for the future.
|
||||
|
||||
Also note that this only works for dedicated servers.
|
||||
You can still run the script in a private match to get a preview of the colors and everything but it won't rotate to your chosen map/mode due a technical limitation.
|
||||
|
||||
This is heavily inspired by [LastDemon99's IW5 mapvote](https://github.com/LastDemon99/IW5_VoteSystem).
|
||||
I also re-used some code from [DoktorSAS T6 mapvote](https://github.com/DoktorSAS/PlutoniumT6Mapvote).
|
||||
Huge thanks to both of them.
|
||||
|
||||

|
||||
|
||||
## mapvote.gsc
|
||||
|
||||
This script can either be installed in the `scripts` folder or in the `scripts\mp` folder.
|
||||
**IMPORTANT** Installing `mapvote_mp_extend.gsc` in `scripts\mp` is **mandatory** to make the mapvote work normally.
|
||||
|
||||
### Main features
|
||||
|
||||
- It allows up to 6 maps and 4 modes to be displayed at once
|
||||
- It has separate map and mode choices
|
||||
- It supports custom gamemode names and custom cfg
|
||||
- It rotates a completely random map and mode when there are no votes
|
||||
- It has a good level of customization
|
||||
- It has a debug mode to quickly preview the menu
|
||||
|
||||
### Getting started
|
||||
|
||||
By default the script is disabled to avoid running on all your servers.
|
||||
Simply set `mapvote_enable` to 1 and the script will be loaded, which as a result will display the voting menu after the killcam.
|
||||
|
||||
To configure the menu before putting it on your server I recommend running it in a custom game with the `mapvote_debug` dvar set to `1`.
|
||||
To do that simply boot up the game with the scripts installed and paste this command in the console `set mapvote_enable 1;set mapvote_debug 1`.
|
||||
Start a custom game and pick any class and you will see the menu. Everything will work but map rotation which is normal.
|
||||
You can then configure the dvars directly in your console and restart the map with `map_restart` in the console to edit the menu quickly and get your perfect setup.
|
||||
|
||||
### Dvars
|
||||
|
||||
Here are the dvars you can configure:
|
||||
|
||||
| Name | Description | Default value | Accepted values | Example |
|
||||
|---|---|---|---|---|
|
||||
| mapvote_enable | Toggle whether the mapvote is activated or not. 0 is off and 1 is on | 0 | 0 or 1 | 1 |
|
||||
| mapvote_debug | Toggle whether the mapvote runs in debug mode or not. This will display the mapvote menu a few seconds after starting the game. 0 is off and 1 is on | 0 | 0 or 1 | 1 |
|
||||
| mapvote_maps | A list of the maps that are available for rotation. Each map name needs to start with a capitalized letter and each map is separated with : | Every BO2 maps including DLC maps | Any map name, starting with a capitalized letter and separated with a colon (:) | "Nuketown:Raid" |
|
||||
| mapvote_modes | A list of the modes that are available for rotation. The first parameter is how the mode will be displayed, it can be set to anything you like, the second parameter is the name of the cfg file to load found in the gamesettings folder | "Team Deathmatch;tdm:Domination;dom:Hardpoint;koth" | Any name you want followed by a semi-colon (;) with the cfg name and separated with a colon (:) | "Team Deathmatch;tdm:Domination;dom" |
|
||||
| mapvote_colors_selected | The color of the text when hovered or selected. This is also the color of the votes count | "blue" | red, green, yellow, blue, cyan, purple, white, grey, gray, black | "red" |
|
||||
| mapvote_colors_unselected | The color of the text when not hovered and not selected | "white" | red, green, yellow, blue, cyan, purple, white, grey, gray, black | "green" |
|
||||
| mapvote_colors_timer | The color of the timer as long as it has more than 5 seconds remaining | "blue" | red, green, yellow, blue, cyan, purple, white, grey, gray, black | "yellow" |
|
||||
| mapvote_colors_timer_low | The color of the timer when it has 5 or less seconds remaining | "red" | red, green, yellow, blue, cyan, purple, white, grey, gray, black | "blue" |
|
||||
| mapvote_colors_help_text | The color of the help text at the bottom explaining how to use the menu | "white" | red, green, yellow, blue, cyan, purple, white, grey, gray, black | "cyan" |
|
||||
| mapvote_colors_help_accent | The color of the accented text of the help text at the bottom | "blue" | red, green, yellow, blue, cyan, purple, white, grey, gray, black | "purple" |
|
||||
| mapvote_colors_help_accent_mode | The accenting mode for the help text. <standard> only puts the accent color on the button to press and <max> puts it on both the buttons and the action it does | "standard" | standard, max | "max" |
|
||||
| mapvote_vote_time | The time the vote lasts (in seconds) | 30 | Any plain number above 5 | 20 |
|
||||
| mapvote_blur_level | The amount of blur to put at the end of the killcam. The max recommended value is 5. 0 disables it | 2.5 | Any number | 3 |
|
||||
| mapvote_blur_fade_in_time | The time (in seconds) it takes for the blur to reach <mapvote_blur_level>. For example if you set it to 10 and <mapvote_blur_level> is 5 then it will progressively blur the screen from 0 to 5 in 10 seconds | 2 | Any number | 5 |
|
||||
| mapvote_horizontal_spacing | The horizontal spacing between the map/mode names on the left and the vote counts on the right. I recommend setting this value according to your map and modes length so that it doesn't overlap with the vote counts | 75 | Any plain number | 50 |
|
||||
|
||||
### Configuration
|
||||
|
||||
Below is an example CFG showing how each dvars can be configured.
|
||||
The values you see are the default values that will be used if you don't set a dvar.
|
||||
|
||||
```c
|
||||
set "mapvote_maps", "Aftermath:Cargo:Carrier:Drone:Express:Hijacked:Meltdown:Overflow:Plaza:Raid:Slums:Standoff:Turbine:Yemen:Nuketown:Downhill:Mirage:Hydro:Grind:Encore:Magma:Vertigo:Studio:Uplink:Detour:Cove:Rush:Dig:Frost:Pod:Takeoff"
|
||||
set "mapvote_modes", "Team Deathmatch;tdm:Domination;dom:Hardpoint;koth"
|
||||
set "mapvote_colors_selected", "blue"
|
||||
set "mapvote_colors_unselected", "white"
|
||||
set "mapvote_colors_timer", "blue"
|
||||
set "mapvote_colors_timer_low", "red"
|
||||
set "mapvote_colors_help_text", "white"
|
||||
set "mapvote_colors_help_accent", "blue"
|
||||
set "mapvote_colors_help_accent_mode", "standard"
|
||||
set "mapvote_vote_time", 30
|
||||
set "mapvote_blur_level", 2.5
|
||||
set "mapvote_blur_fade_in_time", 2
|
||||
set "mapvote_horizontal_spacing", 75
|
||||
```
|
||||
|
||||
Here are some pre-set values if you want to quickly copy/paste something
|
||||
|
||||
| Description | Value |
|
||||
|---|---|
|
||||
| All base game maps | "Aftermath:Cargo:Carrier:Drone:Express:Hijacked:Meltdown:Overflow:Plaza:Raid:Slums:Standoff:Turbine:Yemen" |
|
||||
| All DLC maps | "Nuketown:Downhill:Mirage:Hydro:Grind:Encore:Magma:Vertigo:Studio:Uplink:Detour:Cove:Rush:Dig:Frost:Pod:Takeoff" |
|
||||
| Classic modes | "Team Deathmatch;tdm:Domination;dom:Hardpoint;koth" |
|
||||
| Objective modes | "Demolition;dem:Headquaters;hq:Capture the Flag;ctf" |
|
||||
| Alternative modes | "Kill Confirmed;conf:One Flag CTF;oneflag" |
|
||||
| Party modes | "Gun Game;gun:One in the Chamber;oic:Sharpshooter;shrp:Sticks & Stones;sas" |
|
||||
| FFA 24/7 | "Free for All;dm" |
|
||||
| SND 24/7 | "Search & Destroy;sd" |
|
||||
|
||||
### Notes
|
||||
|
||||
- When two maps/modes have the same votes, the lowest one in the list will win. In the future it would be nice to randomize between both
|
||||
- Ending the game with ESC doesn't work when in debug mode. Use `map_restart` in the console when your script is compiled. And if you want to leave use `disconnect` in the console until this is fixed
|
||||
- When there's only one map/mode the right map/mode will be chosen but adding an option to hide single vote elements would be nice
|
||||
|
||||
## mapvote_mp_extend.gsc
|
||||
|
||||
A small script that goes with `mapvote.gsc` to make it work in multiplayer.
|
||||
It has to be installed in the `mp` directory since it contains multiplayer only code.
|
||||
Putting it in `scripts` or `scripts\zm` will throw an error when booting up a zombies map.
|
BIN
mapvote/images/mapvote.png
Normal file
BIN
mapvote/images/mapvote.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 MiB |
BIN
mapvote/mapvote.gsc
Normal file
BIN
mapvote/mapvote.gsc
Normal file
Binary file not shown.
BIN
mapvote/mapvote_mp_extend.gsc
Normal file
BIN
mapvote/mapvote_mp_extend.gsc
Normal file
Binary file not shown.
833
mapvote/source/mapvote-source.gsc
Normal file
833
mapvote/source/mapvote-source.gsc
Normal file
@ -0,0 +1,833 @@
|
||||
/*
|
||||
======================================================================
|
||||
| Game: Plutonium T6 |
|
||||
| Description : Let players vote |
|
||||
| for a map and mode at the end of each game |
|
||||
| Author: Resxt |
|
||||
======================================================================
|
||||
| https://github.com/Resxt/Plutonium-T6-Scripts/tree/main/mapvote |
|
||||
======================================================================
|
||||
*/
|
||||
|
||||
#include maps\mp\gametypes\_hud_util;
|
||||
#include maps\mp\gametypes_zm\_hud_util;
|
||||
#include common_scripts\utility;
|
||||
#include maps\mp\_utility;
|
||||
|
||||
/* Entry point */
|
||||
|
||||
Init()
|
||||
{
|
||||
if (GetDvarInt("mapvote_enable"))
|
||||
{
|
||||
InitMapvote();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Init section */
|
||||
|
||||
InitMapvote()
|
||||
{
|
||||
InitDvars();
|
||||
InitVariables();
|
||||
|
||||
level thread ListenForStartVote();
|
||||
level thread ListenForEndVote();
|
||||
|
||||
if (GetDvarInt("mapvote_debug"))
|
||||
{
|
||||
Print("[MAPVOTE] Debug mode is ON");
|
||||
wait 3;
|
||||
level notify("vote_start");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Starting the mapvote normally is handled in mp\mapvote_mp_extend.gsc
|
||||
//replaceFunc(maps\mp\gametypes\_killcam::finalkillcamwaiter, ::OnKillcamEnd);
|
||||
}
|
||||
}
|
||||
|
||||
InitDvars()
|
||||
{
|
||||
SetDvarIfNotInitialized("mapvote_debug", false);
|
||||
|
||||
SetDvarIfNotInitialized("mapvote_maps", "Aftermath:Cargo:Carrier:Drone:Express:Hijacked:Meltdown:Overflow:Plaza:Raid:Slums:Standoff:Turbine:Yemen:Nuketown:Downhill:Mirage:Hydro:Grind:Encore:Magma:Vertigo:Studio:Uplink:Detour:Cove:Rush:Dig:Frost:Pod:Takeoff");
|
||||
SetDvarIfNotInitialized("mapvote_modes", "Team Deathmatch;tdm:Domination;dom:Hardpoint;koth");
|
||||
SetDvarIfNotInitialized("mapvote_colors_selected", "blue");
|
||||
SetDvarIfNotInitialized("mapvote_colors_unselected", "white");
|
||||
SetDvarIfNotInitialized("mapvote_colors_timer", "blue");
|
||||
SetDvarIfNotInitialized("mapvote_colors_timer_low", "red");
|
||||
SetDvarIfNotInitialized("mapvote_colors_help_text", "white");
|
||||
SetDvarIfNotInitialized("mapvote_colors_help_accent", "blue");
|
||||
SetDvarIfNotInitialized("mapvote_colors_help_accent_mode", "standard");
|
||||
SetDvarIfNotInitialized("mapvote_vote_time", 30);
|
||||
SetDvarIfNotInitialized("mapvote_blur_level", 2.5);
|
||||
SetDvarIfNotInitialized("mapvote_blur_fade_in_time", 2);
|
||||
SetDvarIfNotInitialized("mapvote_horizontal_spacing", 75);
|
||||
}
|
||||
|
||||
InitVariables()
|
||||
{
|
||||
SetMapvoteData("map");
|
||||
SetMapvoteData("mode");
|
||||
level.mapvote["vote_time"] = GetDvarInt("mapvote_vote_time");
|
||||
|
||||
level.mapvote["colors"]["unselected"] = GetGscColor(GetDvar("mapvote_colors_unselected"));
|
||||
level.mapvote["colors"]["selected"] = GetGscColor(GetDvar("mapvote_colors_selected"));
|
||||
level.mapvote["colors"]["timer"] = GetGscColor(GetDvar("mapvote_colors_timer"));
|
||||
level.mapvote["colors"]["timer_low"] = GetGscColor(GetDvar("mapvote_colors_timer_low"));
|
||||
level.mapvote["colors"]["help_text"] = GetChatColor(GetDvar("mapvote_colors_help_text"));
|
||||
level.mapvote["colors"]["help_accent"] = GetChatColor(GetDvar("mapvote_colors_help_accent"));
|
||||
level.mapvote["colors"]["help_accent_mode"] = GetDvar("mapvote_colors_help_accent_mode");
|
||||
|
||||
level.mapvote["blur_level"] = GetDvarInt("mapvote_blur_level");
|
||||
level.mapvote["blur_fade_in_time"] = GetDvarInt("mapvote_blur_fade_in_time");
|
||||
level.mapvote["horizontal_spacing"] = GetDvarInt("mapvote_horizontal_spacing");
|
||||
|
||||
level.mapvote["vote"]["maps"] = [];
|
||||
level.mapvote["vote"]["modes"] = [];
|
||||
level.mapvote["hud"]["maps"] = [];
|
||||
level.mapvote["hud"]["modes"] = [];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Player section */
|
||||
|
||||
/*
|
||||
This is used instead of notifyonplayercommand("down", "speed_throw")
|
||||
to fix an issue where players using toggle ads would have to press right click twice for it to register one right click.
|
||||
With this instead it keeps scrolling even 0.35s until they right click again which is a better user experience
|
||||
*/
|
||||
ListenForRightClick()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (self AdsButtonPressed())
|
||||
{
|
||||
self notify("up");
|
||||
wait 0.35;
|
||||
}
|
||||
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
ListenForVoteInputs()
|
||||
{
|
||||
self endon("disconnect");
|
||||
|
||||
self thread ListenForRightClick();
|
||||
|
||||
self notifyonplayercommand("down", "+attack");
|
||||
self notifyonplayercommand("select", "+gostand");
|
||||
self notifyonplayercommand("select", "+usereload");
|
||||
self notifyonplayercommand("select", "+activate");
|
||||
self notifyonplayercommand("unselect", "+frag");
|
||||
|
||||
if (GetDvarInt("mapvote_debug"))
|
||||
{
|
||||
self notifyonplayercommand("debug", "+melee");
|
||||
}
|
||||
|
||||
while(true)
|
||||
{
|
||||
input = self waittill_any_return("down", "up", "select", "unselect", "debug");
|
||||
|
||||
section = self.mapvote["vote_section"];
|
||||
|
||||
if (section == "end" && input != "unselect" && input != "debug")
|
||||
{
|
||||
continue; // stop/skip execution
|
||||
}
|
||||
|
||||
if (input == "down")
|
||||
{
|
||||
if (self.mapvote[section]["hovered_index"] < (level.mapvote[section + "s"]["by_index"].size - 1))
|
||||
{
|
||||
self playlocalsound("uin_start_count_down");
|
||||
self UpdateSelection(section, (self.mapvote[section]["hovered_index"] + 1));
|
||||
}
|
||||
}
|
||||
else if (input == "up")
|
||||
{
|
||||
if (self.mapvote[section]["hovered_index"] > 0)
|
||||
{
|
||||
self playlocalsound("uin_start_count_down");
|
||||
self UpdateSelection(section, (self.mapvote[section]["hovered_index"] - 1));
|
||||
}
|
||||
}
|
||||
else if (input == "select")
|
||||
{
|
||||
self playlocalsound("mpl_killconfirm_tags_pickup");
|
||||
|
||||
self ConfirmSelection(section);
|
||||
}
|
||||
else if (input == "unselect")
|
||||
{
|
||||
if (section != "map")
|
||||
{
|
||||
self playlocalsound("fly_betty_jump");
|
||||
|
||||
self CancelSelection(section);
|
||||
}
|
||||
}
|
||||
else if (input == "debug" && GetDvarInt("mapvote_debug"))
|
||||
{
|
||||
Print("--------------------------------");
|
||||
|
||||
foreach (player in GetHumanPlayers())
|
||||
{
|
||||
if (player.mapvote["map"]["selected_index"] == -1)
|
||||
{
|
||||
Print(player.name + " did not vote for any map");
|
||||
}
|
||||
else
|
||||
{
|
||||
Print(player.name + " voted for map [" + player.mapvote["map"]["selected_index"] +"] " + level.mapvote["maps"]["by_index"][player.mapvote["map"]["selected_index"]]);
|
||||
}
|
||||
|
||||
if (player.mapvote["mode"]["selected_index"] == -1)
|
||||
{
|
||||
Print(player.name + " did not vote for any mode");
|
||||
}
|
||||
else
|
||||
{
|
||||
Print(player.name + " voted for mode [" + player.mapvote["mode"]["selected_index"] + "] " + level.mapvote["modes"]["by_index"][player.mapvote["mode"]["selected_index"]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wait 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Vote section */
|
||||
|
||||
CreateVoteMenu()
|
||||
{
|
||||
//level endon("game_ended");
|
||||
|
||||
spacing = 20;
|
||||
hudLastPosY = -(((level.mapvote["maps"]["by_index"].size + level.mapvote["modes"]["by_index"].size + 1) * spacing) / 2);
|
||||
//hudLastPosY = -100;
|
||||
|
||||
for (mapIndex = 0; mapIndex < level.mapvote["maps"]["by_index"].size; mapIndex++)
|
||||
{
|
||||
mapVotesHud = CreateHudText("", "objective", 1.5, "LEFT", "CENTER", level.mapvote["horizontal_spacing"], hudLastPosY, true, 0);
|
||||
mapVotesHud.color = level.mapvote["colors"]["selected"];
|
||||
|
||||
level.mapvote["hud"]["maps"][mapIndex] = mapVotesHud;
|
||||
|
||||
foreach (player in GetHumanPlayers())
|
||||
{
|
||||
player.mapvote["map"][mapIndex]["hud"] = player CreateHudText(level.mapvote["maps"]["by_index"][mapIndex], "objective", 1.5, "LEFT", "CENTER", -level.mapvote["horizontal_spacing"], hudLastPosY);
|
||||
|
||||
if (mapIndex == 0)
|
||||
{
|
||||
player UpdateSelection("map", 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetElementUnselected(player.mapvote["map"][mapIndex]["hud"]);
|
||||
}
|
||||
}
|
||||
|
||||
hudLastPosY += spacing;
|
||||
}
|
||||
|
||||
hudLastPosY += spacing; // Space between maps and modes sections
|
||||
|
||||
for (modeIndex = 0; modeIndex < level.mapvote["modes"]["by_index"].size; modeIndex++)
|
||||
{
|
||||
modeVotesHud = CreateHudText("", "objective", 1.5, "LEFT", "CENTER", level.mapvote["horizontal_spacing"], hudLastPosY, true, 0);
|
||||
modeVotesHud.color = level.mapvote["colors"]["selected"];
|
||||
|
||||
level.mapvote["hud"]["modes"][modeIndex] = modeVotesHud;
|
||||
|
||||
foreach (player in GetHumanPlayers())
|
||||
{
|
||||
player.mapvote["mode"][modeIndex]["hud"] = player CreateHudText(level.mapvote["modes"]["by_index"][modeIndex], "objective", 1.5, "LEFT", "CENTER", -level.mapvote["horizontal_spacing"], hudLastPosY);
|
||||
|
||||
SetElementUnselected(player.mapvote["mode"][modeIndex]["hud"]);
|
||||
}
|
||||
|
||||
hudLastPosY += spacing;
|
||||
}
|
||||
|
||||
foreach(player in GetHumanPlayers())
|
||||
{
|
||||
player.mapvote["map"]["selected_index"] = -1;
|
||||
player.mapvote["mode"]["selected_index"] = -1;
|
||||
|
||||
buttonsHelpMessage = "";
|
||||
|
||||
if (level.mapvote["colors"]["help_accent_mode"] == "standard")
|
||||
{
|
||||
buttonsHelpMessage = level.mapvote["colors"]["help_text"] + "Press " + level.mapvote["colors"]["help_accent"] + "[{+attack}] " + level.mapvote["colors"]["help_text"] + "to go down - Press " + level.mapvote["colors"]["help_accent"] + "[{+speed_throw}] " + level.mapvote["colors"]["help_text"] + "to go up - Press " + level.mapvote["colors"]["help_accent"] + "[{+gostand}] OR [{+activate}] " + level.mapvote["colors"]["help_text"] + "to select - Press " + level.mapvote["colors"]["help_accent"] + "[{+frag}] " + level.mapvote["colors"]["help_text"] + "to undo";
|
||||
}
|
||||
else if(level.mapvote["colors"]["help_accent_mode"] == "max")
|
||||
{
|
||||
buttonsHelpMessage = level.mapvote["colors"]["help_text"] + "Press " + level.mapvote["colors"]["help_accent"] + "[{+attack}] " + level.mapvote["colors"]["help_text"] + "to go " + level.mapvote["colors"]["help_accent"] + "down " + level.mapvote["colors"]["help_text"] + "- Press " + level.mapvote["colors"]["help_accent"] + "[{+speed_throw}] " + level.mapvote["colors"]["help_text"] + "to go " + level.mapvote["colors"]["help_accent"] + "up " + level.mapvote["colors"]["help_text"] + "- Press " + level.mapvote["colors"]["help_accent"] + "[{+gostand}] " + level.mapvote["colors"]["help_accent"] + "OR " + level.mapvote["colors"]["help_accent"] + "[{+activate}] " + level.mapvote["colors"]["help_text"] + "to " + level.mapvote["colors"]["help_accent"] + "select " + level.mapvote["colors"]["help_text"] + "- Press " + level.mapvote["colors"]["help_accent"] + "[{+frag}] " + level.mapvote["colors"]["help_text"] + "to " + level.mapvote["colors"]["help_accent"] + "undo";
|
||||
}
|
||||
|
||||
if (GetDvarInt("mapvote_debug"))
|
||||
{
|
||||
if (level.mapvote["colors"]["help_accent_mode"] == "standard")
|
||||
{
|
||||
buttonsHelpMessage = buttonsHelpMessage + " - Press " + level.mapvote["colors"]["help_accent"] + "[{+melee}] " + level.mapvote["colors"]["help_text"] + "to debug";
|
||||
}
|
||||
else if(level.mapvote["colors"]["help_accent_mode"] == "max")
|
||||
{
|
||||
buttonsHelpMessage = buttonsHelpMessage + level.mapvote["colors"]["help_text"] + " - Press " + level.mapvote["colors"]["help_accent"] + "[{+melee}] " + level.mapvote["colors"]["help_text"] + "to " + level.mapvote["colors"]["help_accent"] + "debug";
|
||||
}
|
||||
}
|
||||
|
||||
player CreateHudText(buttonsHelpMessage, "objective", 1.5, "CENTER", "CENTER", 0, 210);
|
||||
}
|
||||
}
|
||||
|
||||
CreateVoteTimer()
|
||||
{
|
||||
soundFX = spawn("script_origin", (0,0,0));
|
||||
soundFX hide();
|
||||
|
||||
timerhud = CreateTimer(level.mapvote["vote_time"], &"Vote ends in: ", "objective", 1.5, "CENTER", "CENTER", 0, -210);
|
||||
timerhud.color = level.mapvote["colors"]["timer"];
|
||||
for (i = level.mapvote["vote_time"]; i > 0; i--)
|
||||
{
|
||||
if(i <= 5)
|
||||
{
|
||||
timerhud.color = level.mapvote["colors"]["timer_low"];
|
||||
soundFX playSound( "mpl_ui_timer_countdown" );
|
||||
}
|
||||
wait(1);
|
||||
}
|
||||
level notify("vote_end");
|
||||
}
|
||||
|
||||
ListenForStartVote()
|
||||
{
|
||||
level endon("end_game");
|
||||
level waittill("vote_start");
|
||||
|
||||
for (i = 0; i < level.mapvote["maps"]["by_index"].size; i++)
|
||||
{
|
||||
level.mapvote["vote"]["maps"][i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < level.mapvote["modes"]["by_index"].size; i++)
|
||||
{
|
||||
level.mapvote["vote"]["modes"][i] = 0;
|
||||
}
|
||||
|
||||
level thread CreateVoteMenu();
|
||||
level thread CreateVoteTimer();
|
||||
|
||||
foreach (player in GetHumanPlayers())
|
||||
{
|
||||
player FreezeControlsAllowLook(1);
|
||||
player SetBlur(level.mapvote["blur_level"], level.mapvote["blur_fade_in_time"]);
|
||||
|
||||
player thread ListenForVoteInputs();
|
||||
}
|
||||
}
|
||||
|
||||
ListenForEndVote()
|
||||
{
|
||||
level endon("end_game");
|
||||
level waittill("vote_end");
|
||||
|
||||
mostVotedMapIndex = 0;
|
||||
mostVotedMapVotes = 0;
|
||||
mostVotedModeIndex = 0;
|
||||
mostVotedModeVotes = 0;
|
||||
|
||||
foreach (mapIndex in GetArrayKeys(level.mapvote["vote"]["maps"]))
|
||||
{
|
||||
if (level.mapvote["vote"]["maps"][mapIndex] > mostVotedMapVotes)
|
||||
{
|
||||
mostVotedMapIndex = mapIndex;
|
||||
mostVotedMapVotes = level.mapvote["vote"]["maps"][mapIndex];
|
||||
}
|
||||
}
|
||||
|
||||
foreach (modeIndex in GetArrayKeys(level.mapvote["vote"]["modes"]))
|
||||
{
|
||||
if (level.mapvote["vote"]["modes"][modeIndex] > mostVotedModeVotes)
|
||||
{
|
||||
mostVotedModeIndex = modeIndex;
|
||||
mostVotedModeVotes = level.mapvote["vote"]["modes"][modeIndex];
|
||||
}
|
||||
}
|
||||
|
||||
if (mostVotedMapVotes == 0)
|
||||
{
|
||||
mostVotedMapIndex = GetRandomElementInArray(GetArrayKeys(level.mapvote["vote"]["maps"]));
|
||||
|
||||
if (GetDvarInt("mapvote_debug"))
|
||||
{
|
||||
Print("[MAPVOTE] No vote for map. Chosen random map index: " + mostVotedMapIndex);
|
||||
}
|
||||
}
|
||||
|
||||
if (mostVotedModeVotes == 0)
|
||||
{
|
||||
mostVotedModeIndex = GetRandomElementInArray(GetArrayKeys(level.mapvote["vote"]["modes"]));
|
||||
|
||||
if (GetDvarInt("mapvote_debug"))
|
||||
{
|
||||
Print("[MAPVOTE] No vote for mode. Chosen random mode index: " + mostVotedModeIndex);
|
||||
}
|
||||
}
|
||||
|
||||
modeName = level.mapvote["modes"]["by_index"][mostVotedModeIndex];
|
||||
modeCfg = level.mapvote["modes"]["by_name"][level.mapvote["modes"]["by_index"][mostVotedModeIndex]];
|
||||
mapName = GetMapCodeName(level.mapvote["maps"]["by_index"][mostVotedMapIndex]);
|
||||
|
||||
if (GetDvarInt("mapvote_debug"))
|
||||
{
|
||||
Print("[MAPVOTE] Rotating to " + mapName + " | " + modeName + " (" + modeCfg + ".cfg)");
|
||||
}
|
||||
|
||||
setdvar("sv_maprotationcurrent", "exec " + modeCfg + ".cfg map " + mapName);
|
||||
setdvar("sv_maprotation", "exec " + modeCfg + ".cfg map " + mapName);
|
||||
}
|
||||
|
||||
SetMapvoteData(type)
|
||||
{
|
||||
limit = 0;
|
||||
|
||||
availableElements = StrTok(GetDvar("mapvote_" + type + "s"), ":");
|
||||
|
||||
if (type == "map")
|
||||
{
|
||||
if (availableElements.size < 6)
|
||||
{
|
||||
limit = availableElements.size;
|
||||
}
|
||||
else
|
||||
{
|
||||
limit = 6;
|
||||
}
|
||||
|
||||
level.mapvote["maps"]["by_index"] = GetRandomUniqueElementsInArray(availableElements, limit);
|
||||
}
|
||||
else if (type == "mode")
|
||||
{
|
||||
if (availableElements.size < 4)
|
||||
{
|
||||
limit = availableElements.size;
|
||||
}
|
||||
else
|
||||
{
|
||||
limit = 4;
|
||||
}
|
||||
|
||||
finalElements = [];
|
||||
|
||||
foreach (mode in GetRandomUniqueElementsInArray(availableElements, limit))
|
||||
{
|
||||
splittedMode = StrTok(mode, ";");
|
||||
finalElements = AddElementToArray(finalElements, splittedMode[0]);
|
||||
|
||||
level.mapvote["modes"]["by_name"][splittedMode[0]] = splittedMode[1];
|
||||
}
|
||||
|
||||
level.mapvote["modes"]["by_index"] = finalElements;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* HUD section */
|
||||
|
||||
UpdateSelection(type, index)
|
||||
{
|
||||
if (type == "map" || type == "mode")
|
||||
{
|
||||
if (!IsDefined(self.mapvote[type]["hovered_index"]))
|
||||
{
|
||||
self.mapvote[type]["hovered_index"] = 0;
|
||||
}
|
||||
|
||||
self.mapvote["vote_section"] = type;
|
||||
|
||||
SetElementUnselected(self.mapvote[type][self.mapvote[type]["hovered_index"]]["hud"]); // Unselect previous element
|
||||
SetElementSelected(self.mapvote[type][index]["hud"]); // Select new element
|
||||
|
||||
self.mapvote[type]["hovered_index"] = index; // Update the index
|
||||
}
|
||||
else if (type == "end")
|
||||
{
|
||||
self.mapvote["vote_section"] = "end";
|
||||
}
|
||||
}
|
||||
|
||||
ConfirmSelection(type)
|
||||
{
|
||||
self.mapvote[type]["selected_index"] = self.mapvote[type]["hovered_index"];
|
||||
level.mapvote["vote"][type + "s"][self.mapvote[type]["selected_index"]] = (level.mapvote["vote"][type + "s"][self.mapvote[type]["selected_index"]] + 1);
|
||||
level.mapvote["hud"][type + "s"][self.mapvote[type]["selected_index"]] SetValue(level.mapvote["vote"][type + "s"][self.mapvote[type]["selected_index"]]);
|
||||
|
||||
if (type == "map")
|
||||
{
|
||||
modeIndex = 0;
|
||||
|
||||
if (IsDefined(self.mapvote["mode"]["hovered_index"]))
|
||||
{
|
||||
modeIndex = self.mapvote["mode"]["hovered_index"];
|
||||
}
|
||||
|
||||
self UpdateSelection("mode", modeIndex);
|
||||
}
|
||||
else if (type == "mode")
|
||||
{
|
||||
self UpdateSelection("end");
|
||||
}
|
||||
}
|
||||
|
||||
CancelSelection(type)
|
||||
{
|
||||
typeToCancel = "";
|
||||
|
||||
if (type == "mode")
|
||||
{
|
||||
typeToCancel = "map";
|
||||
}
|
||||
else if (type == "end")
|
||||
{
|
||||
typeToCancel = "mode";
|
||||
}
|
||||
|
||||
level.mapvote["vote"][typeToCancel + "s"][self.mapvote[typeToCancel]["selected_index"]] = (level.mapvote["vote"][typeToCancel + "s"][self.mapvote[typeToCancel]["selected_index"]] - 1);
|
||||
level.mapvote["hud"][typeToCancel + "s"][self.mapvote[typeToCancel]["selected_index"]] SetValue(level.mapvote["vote"][typeToCancel + "s"][self.mapvote[typeToCancel]["selected_index"]]);
|
||||
|
||||
self.mapvote[typeToCancel]["selected_index"] = -1;
|
||||
|
||||
if (type == "mode")
|
||||
{
|
||||
SetElementUnselected(self.mapvote["mode"][self.mapvote["mode"]["hovered_index"]]["hud"]);
|
||||
self.mapvote["vote_section"] = "map";
|
||||
}
|
||||
else if (type == "end")
|
||||
{
|
||||
self.mapvote["vote_section"] = "mode";
|
||||
}
|
||||
}
|
||||
|
||||
SetElementSelected(element)
|
||||
{
|
||||
element.color = level.mapvote["colors"]["selected"];
|
||||
}
|
||||
|
||||
SetElementUnselected(element)
|
||||
{
|
||||
element.color = level.mapvote["colors"]["unselected"];
|
||||
}
|
||||
|
||||
CreateHudText(text, font, fontScale, relativeToX, relativeToY, relativeX, relativeY, isServer, value)
|
||||
{
|
||||
hudText = "";
|
||||
|
||||
if (IsDefined(isServer) && isServer)
|
||||
{
|
||||
hudText = CreateServerFontString( font, fontScale );
|
||||
}
|
||||
else
|
||||
{
|
||||
hudText = CreateFontString( font, fontScale );
|
||||
}
|
||||
|
||||
if (IsDefined(value))
|
||||
{
|
||||
hudText.label = text;
|
||||
hudText SetValue(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
hudText SetText(text);
|
||||
}
|
||||
|
||||
hudText SetPoint(relativeToX, relativeToY, relativeX, relativeY);
|
||||
|
||||
hudText.hideWhenInMenu = 1;
|
||||
hudText.glowAlpha = 0;
|
||||
|
||||
return hudText;
|
||||
}
|
||||
|
||||
CreateTimer(time, label, font, fontScale, relativeToX, relativeToY, relativeX, relativeY)
|
||||
{
|
||||
timer = createServerTimer(font, fontScale);
|
||||
timer setpoint(relativeToX, relativeToY, relativeX, relativeY);
|
||||
timer.label = label;
|
||||
timer.hideWhenInMenu = 1;
|
||||
timer.glowAlpha = 0;
|
||||
timer setTimer(time);
|
||||
|
||||
return timer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Utils section */
|
||||
|
||||
SetDvarIfNotInitialized(dvar, value)
|
||||
{
|
||||
if (!IsInitialized(dvar))
|
||||
{
|
||||
SetDvar(dvar, value);
|
||||
}
|
||||
}
|
||||
|
||||
IsInitialized(dvar)
|
||||
{
|
||||
result = GetDvar(dvar);
|
||||
return result != "";
|
||||
}
|
||||
|
||||
IsBot()
|
||||
{
|
||||
return IsDefined(self.pers["isBot"]) && self.pers["isBot"];
|
||||
}
|
||||
|
||||
GetHumanPlayers()
|
||||
{
|
||||
humanPlayers = [];
|
||||
|
||||
foreach (player in level.players)
|
||||
{
|
||||
if (!player IsBot())
|
||||
{
|
||||
humanPlayers[humanPlayers.size] = player;
|
||||
}
|
||||
}
|
||||
|
||||
return humanPlayers;
|
||||
}
|
||||
|
||||
GetRandomElementInArray(array)
|
||||
{
|
||||
return array[GetArrayKeys(array)[randomint(array.size)]];
|
||||
}
|
||||
|
||||
GetRandomUniqueElementsInArray(array, limit)
|
||||
{
|
||||
finalElements = [];
|
||||
|
||||
for (i = 0; i < limit; i++)
|
||||
{
|
||||
findElement = true;
|
||||
|
||||
while (findElement)
|
||||
{
|
||||
randomElement = GetRandomElementInArray(array);
|
||||
|
||||
if (!ArrayContainsValue(finalElements, randomElement))
|
||||
{
|
||||
finalElements = AddElementToArray(finalElements, randomElement);
|
||||
|
||||
findElement = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return finalElements;
|
||||
}
|
||||
|
||||
ArrayContainsValue(array, valueToFind)
|
||||
{
|
||||
if (array.size == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (value in array)
|
||||
{
|
||||
if (value == valueToFind)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
AddElementToArray(array, element)
|
||||
{
|
||||
array[array.size] = element;
|
||||
return array;
|
||||
}
|
||||
|
||||
GetMapCodeName(mapName)
|
||||
{
|
||||
switch(mapName)
|
||||
{
|
||||
case "Nuketown":
|
||||
return "mp_nuketown_2020";
|
||||
|
||||
case "Hijacked":
|
||||
return "mp_hijacked";
|
||||
|
||||
case "Meltdown":
|
||||
return "mp_meltdown";
|
||||
|
||||
case "Express":
|
||||
return "mp_express";
|
||||
|
||||
case "Carrier":
|
||||
return "mp_carrier";
|
||||
|
||||
case "Overflow":
|
||||
return "mp_overflow";
|
||||
|
||||
case "Slums":
|
||||
return "mp_slums";
|
||||
|
||||
case "Aftermath":
|
||||
return "mp_la";
|
||||
|
||||
case "Cargo":
|
||||
return "mp_dockside";
|
||||
|
||||
case "Turbine":
|
||||
return "mp_turbine";
|
||||
|
||||
case "Drone":
|
||||
return "mp_drone";
|
||||
|
||||
case "Raid":
|
||||
return "mp_raid";
|
||||
|
||||
case "Standoff":
|
||||
return "mp_village";
|
||||
|
||||
case "Plaza":
|
||||
return "mp_nightclub";
|
||||
|
||||
case "Yemen":
|
||||
return "mp_socotra";
|
||||
|
||||
case "Uplink":
|
||||
return "mp_uplink";
|
||||
|
||||
case "Detour":
|
||||
return "mp_bridge";
|
||||
|
||||
case "Cove":
|
||||
return "mp_castaway";
|
||||
|
||||
case "Rush":
|
||||
return "mp_paintball";
|
||||
|
||||
case "Studio":
|
||||
return "mp_studio";
|
||||
|
||||
case "Magma":
|
||||
return "mp_magma";
|
||||
|
||||
case "Vertigo":
|
||||
return "mp_vertigo";
|
||||
|
||||
case "Encore":
|
||||
return "mp_concert";
|
||||
|
||||
case "Downhill":
|
||||
return "mp_downhill";
|
||||
|
||||
case "Grind":
|
||||
return "mp_skate";
|
||||
|
||||
case "Hydro":
|
||||
return "mp_hydro";
|
||||
|
||||
case "Mirage":
|
||||
return "mp_mirage";
|
||||
|
||||
case "Frost":
|
||||
return "mp_frostbite";
|
||||
|
||||
case "Takeoff":
|
||||
return "mp_takeoff";
|
||||
|
||||
case "Pod":
|
||||
return "mp_pod";
|
||||
|
||||
case "Dig":
|
||||
return "mp_dig";
|
||||
}
|
||||
}
|
||||
|
||||
GetGscColor(colorName)
|
||||
{
|
||||
switch (colorName)
|
||||
{
|
||||
case "red":
|
||||
return (1, 0, 0.059);
|
||||
|
||||
case "green":
|
||||
return (0.549, 0.882, 0.043);
|
||||
|
||||
case "yellow":
|
||||
return (1, 0.725, 0);
|
||||
|
||||
case "blue":
|
||||
return (0, 0.553, 0.973);
|
||||
|
||||
case "cyan":
|
||||
return (0, 0.847, 0.922);
|
||||
|
||||
case "purple":
|
||||
return (0.427, 0.263, 0.651);
|
||||
|
||||
case "white":
|
||||
return (1, 1, 1);
|
||||
|
||||
case "grey":
|
||||
case "gray":
|
||||
return (0.137, 0.137, 0.137);
|
||||
|
||||
case "black":
|
||||
return (0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
GetChatColor(colorName)
|
||||
{
|
||||
switch(colorName)
|
||||
{
|
||||
case "red":
|
||||
return "^1";
|
||||
|
||||
case "green":
|
||||
return "^2";
|
||||
|
||||
case "yellow":
|
||||
return "^3";
|
||||
|
||||
case "blue":
|
||||
return "^4";
|
||||
|
||||
case "cyan":
|
||||
return "^5";
|
||||
|
||||
case "purple":
|
||||
return "^6";
|
||||
|
||||
case "white":
|
||||
return "^7";
|
||||
|
||||
case "grey":
|
||||
return "^0";
|
||||
|
||||
case "black":
|
||||
return "^0";
|
||||
}
|
||||
}
|
32
mapvote/source/mapvote_mp_extend-source.gsc
Normal file
32
mapvote/source/mapvote_mp_extend-source.gsc
Normal file
@ -0,0 +1,32 @@
|
||||
#include maps\mp\_utility;
|
||||
|
||||
Init()
|
||||
{
|
||||
if (GetDvarInt("mapvote_enable"))
|
||||
{
|
||||
replaceFunc(maps\mp\gametypes\_killcam::finalkillcamwaiter, ::OnKillcamEnd);
|
||||
}
|
||||
}
|
||||
|
||||
OnKillcamEnd()
|
||||
{
|
||||
if (!IsDefined(level.finalkillcam_winner))
|
||||
{
|
||||
if (isRoundBased() && !wasLastRound())
|
||||
return false;
|
||||
wait 3;
|
||||
|
||||
level notify("vote_start");
|
||||
level waittill("vote_end");
|
||||
return false;
|
||||
}
|
||||
|
||||
level waittill("final_killcam_done");
|
||||
if (isRoundBased() && !wasLastRound())
|
||||
return true;
|
||||
wait 3;
|
||||
|
||||
level notify("vote_start");
|
||||
level waittill("vote_end");
|
||||
return true;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user