· 8 years ago · Feb 12, 2018, 03:48 AM
1util.AddNetworkString( "CMV_Start" )
2util.AddNetworkString( "CMV_End" )
3util.AddNetworkString( "CMV_Votes" )
4util.AddNetworkString( "CMV_Inform" )
5
6local cfg = CMV.Config
7
8CMV.Voting = false
9CMV.RTV = math.Round( #player.GetHumans() * cfg.RTVAmount )
10CMV.RTVAmount = 0
11CMV.Maps = {}
12CMV.Votes = {}
13
14for i = 1, cfg.MapAmount do
15 table.insert( CMV.Votes, 0 )
16end
17
18function CMV:ChangeMap()
19 RunConsoleCommand( "changelevel", self )
20end
21
22function CMV:LoadGamemodes()
23 if !sql.TableExists( "cmv_cooldown" ) then
24 sql.Query "CREATE TABLE IF NOT EXISTS cmv_cooldown ( map TEXT NOT NULL, remaining INTEGER NOT NULL )"
25 end
26
27 if !cfg.AutoPrefix then
28 hook.Add( "CMV_ChangeMap", "CMV_ChangeMap", CMV.ChangeMap )
29 return
30 end
31
32 local gamemodesTable = {
33 "terrortown",
34 "deathrun",
35 "murder",
36 "jailbreak",
37 "prop_hunt",
38 "zombiesurvival",
39 "fretta",
40 "stalker",
41 "guesswho"
42 }
43
44 local gamemodeName = GetConVar( "gamemode" ):GetString()
45
46 if !table.HasValue( gamemodesTable, gamemodeName ) then
47 if gmod.GetGamemode().BaseClass.FolderName and gmod.GetGamemode().BaseClass.FolderName:lower() == "fretta" then
48 gamemodeName = "fretta"
49 include( "clean_mapvote/gamemodes/" .. gamemodeName .. ".lua" )
50 end
51
52 if gmod.GetGamemode() and gmod.GetGamemode().Name == "Enhanced Prop Hunt" then
53 gamemodeName = "fretta"
54 include( "clean_mapvote/gamemodes/" .. gamemodeName .. ".lua" )
55 end
56
57 error "No valid gamemode detected!"
58 return
59 end
60
61 include( "clean_mapvote/gamemodes/" .. gamemodeName .. ".lua" )
62end
63
64CMV:LoadGamemodes()
65
66function CMV:PlayerInitialize()
67 self.Voted = false
68 self.VotedMap = 0
69 self.NextVote = CurTime()
70end
71hook.Add( "PlayerAuthed", "CMV_PlayerInitialize", CMV.PlayerInitialize )
72
73function CMV:GetMaps()
74 local availableMaps = {}
75 local tempMaps = {}
76 local mapCooldowns = sql.Query "SELECT * FROM cmv_cooldown"
77
78 for _, prefix in ipairs( cfg.Prefixes ) do
79 availableMaps[ _ ] = file.Find( "maps/" .. prefix .. "*.bsp", "GAME" )
80 end
81
82 for _, mapdir in ipairs( availableMaps ) do
83 for _, map in ipairs( mapdir ) do
84 table.insert( tempMaps, map:Replace( ".bsp", "" ) )
85 end
86 end
87
88 for _, map in ipairs( tempMaps ) do
89 if map:find( game.GetMap() ) then
90 table.remove( tempMaps, _ )
91 break
92 end
93 end
94
95 for _, map in ipairs( cfg.BlacklistMaps ) do
96 if table.HasValue( tempMaps, map ) then
97 table.RemoveByValue( tempMaps, map )
98 end
99 end
100
101 for _, map in ipairs( cfg.ExtraMaps ) do
102 table.insert( tempMaps, map )
103 end
104
105 if mapCooldowns != nil then
106 for _, row in ipairs( mapCooldowns ) do
107 if table.HasValue( tempMaps, row.map ) then
108 table.RemoveByValue( tempMaps, row.map )
109 end
110 end
111 end
112
113 local iterations = cfg.ExtendMap and cfg.MapAmount - 1 or cfg.MapAmount
114
115 for i = 1, iterations do
116 local map = table.Random( tempMaps )
117 table.insert( CMV.Maps, map )
118 table.RemoveByValue( tempMaps, map )
119 end
120
121 if cfg.ExtendMap then
122 table.insert( CMV.Maps, game.GetMap() )
123 end
124end
125
126function CMV:Start()
127 if CMV.Voting then return end
128
129 self:Print "A mapvote has begun..."
130
131 CMV.Voting = true
132 CMV:GetMaps()
133
134 net.Start( "CMV_Start" )
135 net.WriteTable( CMV.Maps )
136 net.Broadcast()
137
138 timer.Simple( cfg.VoteTime, function()
139 CMV:End()
140 end )
141end
142
143function CMV:End()
144 if !CMV.Voting then return end
145
146 CMV.Voting = false
147
148 local winningIndex = table.GetWinningKey( CMV.Votes )
149 local winningMap = CMV.Maps[ winningIndex ]
150
151 net.Start( "CMV_End" )
152 net.WriteString( winningMap )
153 net.Broadcast()
154
155 local mapCooldowns = sql.Query "SELECT * FROM cmv_cooldown"
156 local cooledMaps = {}
157
158 if mapCooldowns != nil then
159 for _, row in ipairs( mapCooldowns ) do
160 sql.Query( "UPDATE cmv_cooldown SET remaining = remaining - 1 WHERE map = " .. SQLStr( row.map ) )
161
162 if tonumber( row.remaining ) - 1 == 0 then
163 sql.Query( "DELETE FROM cmv_cooldown WHERE map = " .. SQLStr( row.map ) )
164 end
165
166 table.insert( cooledMaps, row.map )
167 end
168 end
169
170 if !table.HasValue( cooledMaps, game.GetMap() ) then
171 sql.Query( "INSERT INTO cmv_cooldown ( map, remaining ) VALUES( " .. SQLStr( game.GetMap() ) .. ", " .. SQLStr( cfg.Cooldown ) .. " )" )
172 end
173
174 timer.Simple( cfg.PostVoteTime, function()
175 hook.Call( "CMV_ChangeMap", nil, winningMap )
176 end )
177end
178
179function CMV:Inform( msg, ply )
180 net.Start( "CMV_Inform" )
181 net.WriteString( msg )
182
183 if ply then
184 net.Send( ply )
185 else
186 net.Broadcast()
187 end
188end
189
190function CMV:Vote( useless, args )
191 local map = tonumber( args[ 1 ] )
192
193 if self.NextVote < CurTime() then
194 if CMV.Voting and map < cfg.MapAmount + 1 and map > 0 then
195 local voteAmount = cfg.VotePower[ self:GetUserGroup() ] and cfg.VotePower[ self:GetUserGroup() ] or 1
196
197 if self.Voted then
198 CMV.Votes[ self.VotedMap ] = CMV.Votes[ self.VotedMap ] - voteAmount
199 CMV.Votes[ map ] = CMV.Votes[ map ] + voteAmount
200 self.VotedMap = map
201 else
202 CMV.Votes[ map ] = CMV.Votes[ map ] + voteAmount
203 self.Voted = true
204 self.VotedMap = map
205 end
206
207 net.Start( "CMV_Votes" )
208 net.WriteTable( CMV.Votes )
209 net.Broadcast()
210 end
211
212 self.NextVote = CurTime() + .2
213 end
214end
215concommand.Add( "cmv_vote", CMV.Vote )
216
217function CMV:RTVCommand()
218 if !CMV.Voting then
219 if self.RTVed then
220 CMV:Inform( "You have already rocked the vote! " .. CMV.RTV - CMV.RTVAmount .. " more votes required to start a map vote.", self )
221 else
222 CMV:Inform( self:Nick() .. " has rocked the vote! " .. CMV.RTV - CMV.RTVAmount .. " more votes required to start a map vote." )
223 CMV.RTVAmount = CMV.RTVAmount + 1
224 self.RTVed = true
225 end
226 end
227end
228concommand.Add( cfg.RTVCommand, CMV.RTVCommand )
229
230function CMV:CheckRTV()
231 if #player.GetHumans() < 1 then return end
232
233 CMV.RTV = math.Round( #player.GetHumans() * cfg.RTVAmount )
234
235 if CMV.RTVAmount >= CMV.RTV and !CMV.Voting then
236 if GetConVar( "gamemode" ) == "terrortown" then
237 if GetRoundState() == ROUND_POST or GetRoundState() == ROUND_WAIT or #player.GetHumans() <= 2 then
238 CMV:Start()
239 end
240 else
241 CMV:Start()
242 end
243
244 hook.Remove( "Think", "CMV_CheckRTV" )
245 end
246end
247hook.Add( "Think", "CMV_CheckRTV", CMV.CheckRTV )
248
249function CMV:Chat( text )
250 if text:lower():match( "^[!/:.]" .. cfg.RTVChatCommand ) then
251 self:ConCommand( cfg.RTVCommand )
252
253 return ""
254 end
255end
256hook.Add( "PlayerSay", "CMV_Chat", CMV.Chat )