Advertisement
Guest User

Untitled

a guest
Feb 23rd, 2019
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 41.53 KB | None | 0 0
  1. --
  2. -- racemidvote_server.lua
  3. --
  4. -- Mid-race random map vote and
  5. -- NextMapVote handled in this file
  6. --
  7.  
  8. local lastVoteStarterName = ''
  9. local lastVoteStarterCount = 0
  10. local mapIsAlreadySet = false
  11. local g_ForcedNextMap
  12. local mapBlock
  13. local hunterMsg = false
  14.  
  15. ----------------------------------------------------------------------------
  16. -- displayHilariarseMessage
  17. --
  18. -- Comedy gold
  19. ----------------------------------------------------------------------------
  20. function displayHilariarseMessage( player )
  21. if not player then
  22. lastVoteStarterName = ''
  23. else
  24. local playerName = getPlayerName(player)
  25. local msg = ''
  26. if playerName == lastVoteStarterName then
  27. lastVoteStarterCount = lastVoteStarterCount + 1
  28. if lastVoteStarterCount == 5 then
  29. msg = playerName .. ' started a vote. Hardly a suprise.'
  30. elseif lastVoteStarterCount == 10 then
  31. msg = 'Guess what! '..playerName .. ' started ANOTHER vote!'
  32. elseif lastVoteStarterCount < 5 then
  33. msg = playerName .. ' started another vote.'
  34. else
  35. msg = playerName .. ' continues to abuse the vote system.'
  36. end
  37. else
  38. lastVoteStarterCount = 0
  39. lastVoteStarterName = playerName
  40. msg = playerName .. ' started a vote.'
  41. end
  42. outputRace( msg )
  43. end
  44. end
  45.  
  46.  
  47. ----------------------------------------------------------------------------
  48. -- displayKillerPunchLine
  49. --
  50. -- Sewing kits available in the foyer
  51. ----------------------------------------------------------------------------
  52. function displayKillerPunchLine( player )
  53. if lastVoteStarterName ~= '' then
  54. outputRace( 'Offical news: Everybody hates ' .. lastVoteStarterName )
  55. end
  56. end
  57.  
  58.  
  59. ----------------------------------------------------------------------------
  60. -- startMidMapVoteForRandomMap
  61. --
  62. -- Start the vote menu if during a race and more than 30 seconds from the end
  63. -- No messages if this was not started by a player
  64. ----------------------------------------------------------------------------
  65. function startMidMapVoteForRandomMap(player)
  66.  
  67. -- Check state and race time left
  68. if not stateAllowsRandomMapVote() or g_CurrentRaceMode:getTimeRemaining() < 30000 then
  69. if player then
  70. outputRace( "I'm afraid I can't let you do that, " .. getPlayerName(player) .. ".", player )
  71. end
  72. return
  73. end
  74.  
  75. displayHilariarseMessage( player )
  76. exports.votemanager:stopPoll()
  77.  
  78. -- Actual vote started here
  79. local pollDidStart = exports.votemanager:startPoll {
  80. title='Do you want to change to a random map?',
  81. percentage=51,
  82. timeout=15,
  83. allowchange=true,
  84. visibleTo=getRootElement(),
  85. [1]={'Yes', 'midMapVoteResult', getRootElement(), true},
  86. [2]={'No', 'midMapVoteResult', getRootElement(), false;default=true},
  87. }
  88.  
  89. -- Change state if vote did start
  90. if pollDidStart then
  91. gotoState('MidMapVote')
  92. end
  93.  
  94. end
  95. --addCommandHandler('new',startMidMapVoteForRandomMap)
  96.  
  97.  
  98. ----------------------------------------------------------------------------
  99. -- event midMapVoteResult
  100. --
  101. -- Called from the votemanager when the poll has completed
  102. ----------------------------------------------------------------------------
  103. addEvent('midMapVoteResult')
  104. addEventHandler('midMapVoteResult', getRootElement(),
  105. function( votedYes )
  106. -- Change state back
  107. if stateAllowsRandomMapVoteResult() then
  108. gotoState('Running')
  109. if votedYes then
  110. startRandomMap()
  111. else
  112. displayKillerPunchLine()
  113. end
  114. end
  115. end
  116. )
  117.  
  118.  
  119.  
  120. ----------------------------------------------------------------------------
  121. -- startRandomMap
  122. --
  123. -- Changes the current map to a random race map
  124. ----------------------------------------------------------------------------
  125. function startRandomMap()
  126.  
  127. -- Handle forced nextmap setting
  128. if maybeApplyForcedNextMap() then
  129. return
  130. end
  131.  
  132. -- Get a random map chosen from the 10% of least recently player maps, with enough spawn points for all the players (if required)
  133. local map = getRandomMapCompatibleWithGamemode( getThisResource(), 10, g_GameOptions.ghostmode and 0 or getTotalPlayerCount() )
  134. if map then
  135. g_IgnoreSpawnCountProblems = map -- Uber hack 4000
  136. if not exports.mapmanager:changeGamemodeMap ( map, nil, true ) then
  137. problemChangingMap()
  138. end
  139. else
  140. outputWarning( 'startRandomMap failed' )
  141. end
  142. end
  143.  
  144.  
  145. ----------------------------------------------------------------------------
  146. -- outputRace
  147. --
  148. -- Race color is defined in the settings
  149. ----------------------------------------------------------------------------
  150. function outputRace(message, toElement)
  151. toElement = toElement or g_Root
  152. local r, g, b = getColorFromString(string.upper(get("color")))
  153. if getElementType(toElement) == 'console' then
  154. outputServerLog(message)
  155. else
  156. if toElement == rootElement then
  157. outputServerLog(message)
  158. end
  159. if getElementType(toElement) == 'player' then
  160. message = '[PM] ' .. message
  161. end
  162. outputChatBox(message, toElement, r, g, b)
  163. end
  164. end
  165.  
  166.  
  167. ----------------------------------------------------------------------------
  168. -- problemChangingMap
  169. --
  170. -- Sort it
  171. ----------------------------------------------------------------------------
  172. function problemChangingMap()
  173. outputRace( 'Changing to random map in 5 seconds' )
  174. local currentMap = exports.mapmanager:getRunningGamemodeMap()
  175. TimerManager.createTimerFor("resource","mapproblem"):setTimer(
  176. function()
  177. -- Check that something else hasn't already changed the map
  178. if currentMap == exports.mapmanager:getRunningGamemodeMap() then
  179. startRandomMap()
  180. end
  181. end,
  182. math.random(4500,5500), 1 )
  183. end
  184.  
  185.  
  186.  
  187. --
  188. --
  189. -- NextMapVote
  190. --
  191. --
  192. --
  193.  
  194. local g_Poll
  195.  
  196. ----------------------------------------------------------------------------
  197. -- startNextMapVote
  198. --
  199. -- Start a votemap for the next map. Should only be called during the
  200. -- race state 'NextMapSelect'
  201. ----------------------------------------------------------------------------
  202. function startNextMapVote()
  203.  
  204. exports.votemanager:stopPoll()
  205.  
  206. -- Handle forced nextmap setting
  207. if maybeApplyForcedNextMap() then
  208. return
  209. end
  210.  
  211. -- Get all maps
  212. local compatibleMaps = exports.mapmanager:getMapsCompatibleWithGamemode(getThisResource())
  213.  
  214. -- limit it to eight random maps
  215. if #compatibleMaps > 8 then
  216. math.randomseed(getTickCount())
  217. repeat
  218. table.remove(compatibleMaps, math.random(1, #compatibleMaps))
  219. until #compatibleMaps == 8
  220. elseif #compatibleMaps < 2 then
  221. return false, errorCode.onlyOneCompatibleMap
  222. end
  223.  
  224. -- mix up the list order
  225. for i,map in ipairs(compatibleMaps) do
  226. local swapWith = math.random(1, #compatibleMaps)
  227. local temp = compatibleMaps[i]
  228. compatibleMaps[i] = compatibleMaps[swapWith]
  229. compatibleMaps[swapWith] = temp
  230. end
  231.  
  232. local poll = {
  233. title="Choose the next map:",
  234. visibleTo=getRootElement(),
  235. percentage=51,
  236. timeout=15,
  237. allowchange=true;
  238. }
  239.  
  240. for index, map in ipairs(compatibleMaps) do
  241. local mapName = getResourceInfo(map, "name") or getResourceName(map)
  242. table.insert(poll, {mapName, 'nextMapVoteResult', getRootElement(), map})
  243. end
  244.  
  245. local currentMap = exports.mapmanager:getRunningGamemodeMap()
  246. if currentMap then
  247. table.insert(poll, {"Play again", 'nextMapVoteResult', getRootElement(), currentMap})
  248. end
  249.  
  250. -- Allow addons to modify the poll
  251. g_Poll = poll
  252. triggerEvent('onPollStarting', g_Root, poll )
  253. poll = g_Poll
  254. g_Poll = nil
  255.  
  256. local pollDidStart = exports.votemanager:startPoll(poll)
  257.  
  258. if pollDidStart then
  259. gotoState('NextMapVote')
  260. addEventHandler("onPollEnd", getRootElement(), chooseRandomMap)
  261. end
  262.  
  263. return pollDidStart
  264. end
  265.  
  266.  
  267. -- Used by addons in response to onPollStarting
  268. addEvent('onPollModified')
  269. addEventHandler('onPollModified', getRootElement(),
  270. function( poll )
  271. g_Poll = poll
  272. end
  273. )
  274.  
  275.  
  276. function chooseRandomMap (chosen)
  277. if not chosen then
  278. cancelEvent()
  279. math.randomseed(getTickCount())
  280. exports.votemanager:finishPoll(1)
  281. end
  282. removeEventHandler("onPollEnd", getRootElement(), chooseRandomMap)
  283. end
  284.  
  285.  
  286.  
  287. ----------------------------------------------------------------------------
  288. -- event nextMapVoteResult
  289. --
  290. -- Called from the votemanager when the poll has completed
  291. ----------------------------------------------------------------------------
  292. addEvent('nextMapVoteResult')
  293. addEventHandler('nextMapVoteResult', getRootElement(),
  294. function( map )
  295. if stateAllowsNextMapVoteResult() then
  296. if not exports.mapmanager:changeGamemodeMap ( map, nil, true ) then
  297. problemChangingMap()
  298. end
  299. end
  300. end
  301. )
  302.  
  303.  
  304.  
  305. ----------------------------------------------------------------------------
  306. -- startMidMapVoteForRestartMap
  307. --
  308. -- Start the vote menu to restart the current map if during a race
  309. -- No messages if this was not started by a player
  310. ----------------------------------------------------------------------------
  311. function startMidMapVoteForRestartMap(player)
  312.  
  313. -- Check state and race time left
  314. if not stateAllowsRestartMapVote() then
  315. if player then
  316. outputRace( "I'm afraid I can't let you do that, " .. getPlayerName(player) .. ".", player )
  317. end
  318. return
  319. end
  320.  
  321. displayHilariarseMessage( player )
  322. exports.votemanager:stopPoll()
  323.  
  324. -- Actual vote started here
  325. local pollDidStart = exports.votemanager:startPoll {
  326. title='Do you want to restart the current map?',
  327. percentage=51,
  328. timeout=15,
  329. allowchange=true,
  330. visibleTo=getRootElement(),
  331. [1]={'Yes', 'midMapRestartVoteResult', getRootElement(), true},
  332. [2]={'No', 'midMapRestartVoteResult', getRootElement(), false;default=true},
  333. }
  334.  
  335. -- Change state if vote did start
  336. if pollDidStart then
  337. gotoState('MidMapVote')
  338. end
  339.  
  340. end
  341. --addCommandHandler('voteredo',startMidMapVoteForRestartMap)
  342.  
  343.  
  344. ----------------------------------------------------------------------------
  345. -- event midMapRestartVoteResult
  346. --
  347. -- Called from the votemanager when the poll has completed
  348. ----------------------------------------------------------------------------
  349. addEvent('midMapRestartVoteResult')
  350. addEventHandler('midMapRestartVoteResult', getRootElement(),
  351. function( votedYes )
  352. -- Change state back
  353. if stateAllowsRandomMapVoteResult() then
  354. gotoState('Running')
  355. if votedYes then
  356. if not exports.mapmanager:changeGamemodeMap ( exports.mapmanager:getRunningGamemodeMap(), nil, true ) then
  357. problemChangingMap()
  358. end
  359. else
  360. displayKillerPunchLine()
  361. end
  362. end
  363. end
  364. )
  365.  
  366. addCommandHandler('redo',
  367. function( player, command, value )
  368. if isPlayerInACLGroup(player, g_GameOptions.admingroup) then
  369. local currentMap = exports.mapmanager:getRunningGamemodeMap()
  370. --if currentMap then
  371. if currentMap then
  372. --if not g_ForcedNextMap then
  373. outputChatBox('#FF6400M#ffffffap #FF6400r#ffffffestarted #FF6400b#ffffffy ' .. getPlayerNametagText(player), g_Root, 0, 240, 0,true)
  374. if not exports.mapmanager:changeGamemodeMap (currentMap, nil, true) then
  375. problemChangingMap()
  376. --end
  377. end
  378. else
  379. outputRace("You can't restart the map because no map is running", player)
  380. end
  381. else
  382. outputRace("You are not an Admin", player)
  383. end
  384. end
  385. )
  386.  
  387.  
  388. addCommandHandler('random',
  389. function( player, command, value )
  390. if isPlayerInACLGroup(player, g_GameOptions.admingroup) or isPlayerInACLGroup(player, "Moderator") or isPlayerInACLGroup(player, "SuperModerator") then
  391. if not stateAllowsRandomMapVote() or g_CurrentRaceMode:getTimeRemaining() < 1000 then
  392. outputRace( "Random command only works during a race and when no polls are running.", player )
  393. else
  394. local choice = {'#FF6400S#fffffftarted'}
  395. outputChatBox("#FF6400R#ffffffandom~> #FF6400N#ffffffext #FF6400M#ffffffap " .. choice[math.random( 1, #choice )] .. " #FF6400b#ffffffy " .. getPlayerNametagText(player), g_Root, 0, 240, 0, true)
  396. startRandomMap()
  397. end
  398. end
  399. end
  400. )
  401.  
  402. function RGBToHex(red, green, blue, alpha)
  403. if((red < 0 or red > 255 or green < 0 or green > 255 or blue < 0 or blue > 255) or (alpha and (alpha < 0 or alpha > 255))) then
  404. return nil
  405. end
  406. if(alpha) then
  407. return string.format("#%.2X%.2X%.2X%.2X", red,green,blue,alpha)
  408. else
  409. return string.format("#%.2X%.2X%.2X", red,green,blue)
  410. end
  411. end
  412.  
  413.  
  414. ----------------------------------------------------------------------------
  415. -- maybeApplyForcedNextMap
  416. --
  417. -- Returns true if nextmap did override
  418. ----------------------------------------------------------------------------
  419. function maybeApplyForcedNextMap()
  420. if g_ForcedNextMap then
  421. local map = g_ForcedNextMap
  422. g_ForcedNextMap = nil
  423. g_IgnoreSpawnCountProblems = map -- Uber hack 4000
  424. if not exports.mapmanager:changeGamemodeMap ( map, nil, true ) then
  425. outputWarning( 'Forced next map failed' )
  426. return false
  427. end
  428. return true
  429. end
  430. return false
  431. end
  432.  
  433. ---------------------------------------------------------------------------
  434. --
  435. -- Testing
  436. --
  437. --
  438. --
  439. ---------------------------------------------------------------------------
  440. --addCommandHandler('forcevote',
  441. -- function( player, command, value )
  442. -- if not _TESTING and not isPlayerInACLGroup(player, g_GameOptions.admingroup) then
  443. -- return
  444. -- end
  445. -- startNextMapVote()
  446. -- end
  447. --)
  448.  
  449.  
  450. ---------------------------------------------------------------------------
  451. --
  452. -- getRandomMapCompatibleWithGamemode
  453. --
  454. -- This should go in mapmanager, but ACL needs doing
  455. --
  456. ---------------------------------------------------------------------------
  457.  
  458. addEventHandler('onResourceStart', getRootElement(),
  459. function( res )
  460. if exports.mapmanager:isMap( res ) then
  461. setMapLastTimePlayed( res )
  462. end
  463. end
  464. )
  465.  
  466. addEvent('onPlayerPickUpRacePickup')
  467. addEventHandler("onPlayerPickUpRacePickup", getRootElement(),
  468. function (number, sort, model)
  469. if sort == "vehiclechange" then
  470. if model == 425 then
  471. local mapname = call(getResourceFromName("mapmanager"),"getRunningGamemodeMap")
  472. setHunterOnMap(mapname)
  473. if not hunterMsg then
  474. outputChatBox( "#FF6400H#ffffffunter#FF6400A#fffffflert~> #FF6400H#ffffffunter #FF6400r#ffffffeached! Sky and water will be reseted to default color!", getRootElement(),255,255,255,true )
  475. triggerClientEvent("onServerSendHunterMessage",getRootElement(),hunterHundleInfo)
  476. hunterMsg = true
  477. end
  478. if getActivePlayerCount() <= 1 then
  479. setElementHealth(source, 0)
  480. end
  481. end
  482. end
  483. end)
  484.  
  485.  
  486. function toptimeMapAdd()
  487. local mapname = call(getResourceFromName("mapmanager"),"getRunningGamemodeMap")
  488. local mapInfo = getMapInfo( mapname )
  489. mapInfo.toptimes = ( mapInfo.toptimes or 0 ) + 1
  490. saveMapInfoItem( mapname, mapInfo )
  491. end
  492. addEvent("onPlayerToptimeImprovement",true)
  493. addEventHandler("onPlayerToptimeImprovement", getRootElement(),toptimeMapAdd)
  494.  
  495.  
  496. function getRandomMapCompatibleWithGamemode( gamemode, oldestPercentage, minSpawnCount )
  497.  
  498. -- Get all relevant maps
  499. local compatibleMaps = exports.mapmanager:getMapsCompatibleWithGamemode( gamemode )
  500.  
  501. if #compatibleMaps == 0 then
  502. outputDebugString( 'getRandomMapCompatibleWithGamemode: No maps.', 1 )
  503. return false
  504. end
  505.  
  506. -- Sort maps by time since played
  507. local sortList = {}
  508. for i,map in ipairs(compatibleMaps) do
  509. sortList[i] = {}
  510. sortList[i].map = map
  511. sortList[i].lastTimePlayed = getMapLastTimePlayed( map )
  512. end
  513.  
  514. table.sort( sortList, function(a, b) return a.lastTimePlayed > b.lastTimePlayed end )
  515.  
  516. -- Use the bottom n% of maps as the initial selection pool
  517. local cutoff = #sortList - math.floor( #sortList * oldestPercentage / 100 )
  518.  
  519. outputDebug( 'RANDMAP', 'getRandomMapCompatibleWithGamemode' )
  520. outputDebug( 'RANDMAP', ''
  521. .. ' minSpawns:' .. tostring( minSpawnCount )
  522. .. ' nummaps:' .. tostring( #sortList )
  523. .. ' cutoff:' .. tostring( cutoff )
  524. .. ' poolsize:' .. tostring( #sortList - cutoff + 1 )
  525. )
  526.  
  527. math.randomseed( getTickCount() % 50000 )
  528. local fallbackMap
  529. while #sortList > 0 do
  530. -- Get random item from range
  531. local idx = math.random( cutoff, #sortList )
  532. local map = sortList[idx].map
  533.  
  534. if not minSpawnCount or minSpawnCount <= getMapSpawnPointCount( map ) then
  535. outputDebug( 'RANDMAP', ''
  536. .. ' ++ using map:' .. tostring( getResourceName( map ) )
  537. .. ' spawns:' .. tostring( getMapSpawnPointCount( map ) )
  538. .. ' age:' .. tostring( getRealTimeSeconds() - getMapLastTimePlayed( map ) )
  539. )
  540. return map
  541. end
  542.  
  543. -- Remember best match incase we cant find any with enough spawn points
  544. if not fallbackMap or getMapSpawnPointCount( fallbackMap ) < getMapSpawnPointCount( map ) then
  545. fallbackMap = map
  546. end
  547.  
  548. outputDebug( 'RANDMAP', ''
  549. .. ' skip:' .. tostring( getResourceName( map ) )
  550. .. ' spawns:' .. tostring( getMapSpawnPointCount( map ) )
  551. .. ' age:' .. tostring( getRealTimeSeconds() - getMapLastTimePlayed( map ) )
  552. )
  553.  
  554. -- If map not good enough, remove from the list and try another
  555. table.remove( sortList, idx )
  556. -- Move cutoff up the list if required
  557. cutoff = math.min( cutoff, #sortList )
  558. end
  559.  
  560. -- No maps found - use best match
  561. outputDebug( 'RANDMAP', ''
  562. .. ' ** fallback map:' .. tostring( getResourceName( fallbackMap ) )
  563. .. ' spawns:' .. tostring( getMapSpawnPointCount( fallbackMap ) )
  564. .. ' ageLstPlyd:' .. tostring( getRealTimeSeconds() - getMapLastTimePlayed( fallbackMap ) )
  565. )
  566. return fallbackMap
  567. end
  568.  
  569. -- Look for spawnpoints in map file
  570. -- Not very quick as it loads the map file everytime
  571. function countSpawnPointsInMap(res)
  572. local count = 0
  573. local meta = xmlLoadFile(':' .. getResourceName(res) .. '/' .. 'meta.xml')
  574. if meta then
  575. local mapnode = xmlFindChild(meta, 'map', 0) or xmlFindChild(meta, 'race', 0)
  576. local filename = mapnode and xmlNodeGetAttribute(mapnode, 'src')
  577. xmlUnloadFile(meta)
  578. if filename then
  579. local map = xmlLoadFile(':' .. getResourceName(res) .. '/' .. filename)
  580. if map then
  581. while xmlFindChild(map, 'spawnpoint', count) do
  582. count = count + 1
  583. end
  584. xmlUnloadFile(map)
  585. end
  586. end
  587. end
  588. return count
  589. end
  590.  
  591. ---------------------------------------------------------------------------
  592. -- g_MapInfoList access
  593. ---------------------------------------------------------------------------
  594. local g_MapInfoList
  595.  
  596. function getMapLastTimePlayed( map )
  597. local mapInfo = getMapInfo( map )
  598. return mapInfo.lastTimePlayed or 0
  599. end
  600.  
  601. function setMapLastTimePlayed( map, time )
  602. time = time or getRealTimeSeconds()
  603. local mapInfo = getMapInfo( map )
  604. local lastTimePlayed = mapInfo.lastTimePlayed
  605. mapInfo.lastTimePlayedText = getRealDateTimeString(getRealTime(lastTimePlayed))
  606. mapInfo.lastTimePlayed = time
  607. mapInfo.playedCount = ( mapInfo.playedCount or 0 ) + 1
  608. saveMapInfoItem( map, mapInfo )
  609. end
  610.  
  611. function setHunterOnMap(map)
  612. local mapInfo = getMapInfo( map )
  613. mapInfo.hunter = ( mapInfo.hunter or 0 ) + 1
  614. saveMapInfoItem( map, mapInfo )
  615. end
  616.  
  617. function getMapSpawnPointCount( map )
  618. local mapInfo = getMapInfo( map )
  619. if not mapInfo.spawnPointCount then
  620. mapInfo.spawnPointCount = countSpawnPointsInMap( map )
  621. saveMapInfoItem( map, mapInfo )
  622. end
  623. return mapInfo.spawnPointCount
  624. end
  625.  
  626. function getMapInfo( map )
  627. if not g_MapInfoList then
  628. loadMapInfoAll()
  629. end
  630. if not g_MapInfoList[map] then
  631. g_MapInfoList[map] = {}
  632. end
  633. local mapInfo = g_MapInfoList[map]
  634. if mapInfo.loadTime ~= getResourceLoadTime(map) then
  635. -- Reset or clear data that may change between loads
  636. mapInfo.loadTime = getResourceLoadTime( map )
  637. mapInfo.spawnPointCount = false
  638. end
  639. return mapInfo
  640. end
  641.  
  642.  
  643. ---------------------------------------------------------------------------
  644. -- g_MapInfoList <-> database
  645. ---------------------------------------------------------------------------
  646. function sqlString(value)
  647. value = tostring(value) or ''
  648. return "'" .. value:gsub( "(['])", "''" ) .. "'"
  649. end
  650.  
  651. function sqlInt(value)
  652. return tonumber(value) or 0
  653. end
  654.  
  655. function getTableName(value)
  656. return sqlString( 'race_mapInfo' )
  657. end
  658.  
  659. function ensureTableExists()
  660. local cmd = ( 'CREATE TABLE IF NOT EXISTS ' .. getTableName() .. ' ('
  661. .. 'resName TEXT UNIQUE'
  662. .. ', infoName TEXT '
  663. .. ', spawnPointCount INTEGER'
  664. .. ', playedCount INTEGER'
  665. .. ', lastTimePlayedText TEXT'
  666. .. ', lastTimePlayed INTEGER'
  667. .. ', hunter INTEGER'
  668. .. ', toptimes INTEGER'
  669. .. ', likes INTEGER'
  670. .. ')' )
  671. executeSQLQuery( cmd )
  672. end
  673.  
  674. -- Load all rows into g_MapInfoList
  675. function loadMapInfoAll()
  676. ensureTableExists()
  677. local rows = executeSQLQuery( 'SELECT * FROM ' .. getTableName() )
  678. g_MapInfoList = {}
  679. for i,row in ipairs(rows) do
  680. local map = getResourceFromName( row.resName )
  681. if map then
  682. local mapInfo = getMapInfo( map )
  683. mapInfo.playedCount = row.playedCount
  684. mapInfo.lastTimePlayed = row.lastTimePlayed
  685. mapInfo.lastTimePlayedText = row.lastTimePlayedText
  686. mapInfo.hunter = row.hunter
  687. mapInfo.toptimes = row.toptimes
  688. mapInfo.likes = row.likes
  689. end
  690. end
  691. end
  692.  
  693. -- Save one row
  694. function saveMapInfoItem( map, info )
  695. executeSQLQuery( 'BEGIN TRANSACTION' )
  696.  
  697. ensureTableExists()
  698.  
  699. local cmd = ( 'INSERT OR IGNORE INTO ' .. getTableName() .. ' VALUES ('
  700. .. '' .. sqlString( getResourceName( map ) )
  701. .. ',' .. sqlString( "" )
  702. .. ',' .. sqlInt( 0 )
  703. .. ',' .. sqlInt( 0 )
  704. .. ',' .. sqlString( "" )
  705. .. ',' .. sqlInt( 0 )
  706. .. ',' .. sqlInt( 0 )
  707. .. ',' .. sqlInt( 0 )
  708. .. ',' .. sqlInt( 0 )
  709. .. ')' )
  710. executeSQLQuery( cmd )
  711.  
  712. cmd = ( 'UPDATE ' .. getTableName() .. ' SET '
  713. .. 'infoName=' .. sqlString( getResourceInfo( map, "name" ) )
  714. .. ',spawnPointCount=' .. sqlInt( info.spawnPointCount )
  715. .. ',playedCount=' .. sqlInt( info.playedCount )
  716. .. ',lastTimePlayedText=' .. sqlString( info.lastTimePlayedText or "-" )
  717. .. ',lastTimePlayed=' .. sqlInt( info.lastTimePlayed )
  718. .. ',hunter=' .. sqlInt( info.hunter)
  719. .. ',toptimes=' .. sqlInt( info.toptimes)
  720. .. ',likes=' .. sqlInt( info.likes)
  721. .. ' WHERE '
  722. .. 'resName=' .. sqlString( getResourceName( map ) )
  723. )
  724. executeSQLQuery( cmd )
  725.  
  726. executeSQLQuery( 'END TRANSACTION' )
  727. end
  728.  
  729.  
  730. ---------------------------------------------------------------------------
  731. --
  732. -- More things that should go in mapmanager
  733. --
  734. ---------------------------------------------------------------------------
  735. addCommandHandler('hurpderp',
  736. function( player, command, ... )
  737. local query = #{...}>0 and table.concat({...},' ') or nil
  738. if not query then
  739. if g_ForcedNextMap then
  740. outputRace( 'Next map is ' .. getMapName( g_ForcedNextMap ), player )
  741. else
  742. outputRace( 'Next map is not set', player )
  743. end
  744. return
  745. end
  746. local map, errormsg = findMap( query )
  747. if not map then
  748. outputRace( errormsg, player )
  749. return
  750. end
  751. if g_ForcedNextMap == map then
  752. outputRace( 'Next map is already set to ' .. getMapName( g_ForcedNextMap ), player )
  753. return
  754. end
  755. g_ForcedNextMap = map
  756. end
  757. )
  758.  
  759.  
  760. addCommandHandler('checkmap',
  761. function( player, command, ... )
  762. local query = #{...}>0 and table.concat({...},' ') or nil
  763. if query then
  764. local map, errormsg = findMap( query )
  765. if(map)then
  766. errormsgS = "Resource name: '"..getResourceName(map).."'"
  767. else
  768. errormsgS = "Resource not Found"
  769. end
  770. outputRace( errormsg, player )
  771. outputRace( errormsgS, player )
  772. end
  773. end
  774. )
  775.  
  776. function buyNextmap( ... )
  777. local query = #{...}>0 and table.concat({...},' ') or nil
  778. if not query then
  779. return
  780. end
  781. local admin = true
  782. if not _TESTING and admin == false then
  783. return
  784. end
  785. local map, errormsg = findMap( query )
  786. if not map then
  787. return
  788. end
  789. if g_ForcedNextMap == map then
  790. return
  791. end
  792. g_ForcedNextMap = map
  793. mapIsAlreadySet = true
  794. local confirm = true
  795. mapBlock = getMapName( g_ForcedNextMap )
  796. triggerClientEvent("onNextMap", getRootElement(), confirm,getMapName( g_ForcedNextMap ))
  797. end
  798. addEvent("onBoughtMap",true)
  799. addEventHandler("onBoughtMap",getRootElement(),buyNextmap)
  800.  
  801. addCommandHandler('pawnsucksxd',
  802. function( player, command, ... )
  803. local query = #{...}>0 and table.concat({...},' ') or nil
  804. if not query then
  805. if g_ForcedNextMap then
  806. outputRace( 'Next map is ' .. getMapName( g_ForcedNextMap ), player )
  807. else
  808. outputRace( 'Next map is not set', player )
  809. end
  810. return
  811. end
  812. local map, errormsg = findMap( query )
  813. if not map then
  814. outputRace( errormsg, player )
  815. return
  816. end
  817. if g_ForcedNextMap == map then
  818. outputRace( 'Next map is already set to ' .. getMapName( g_ForcedNextMap ), player )
  819. return
  820. end
  821. g_ForcedNextMap = map
  822. triggerEvent("onRaceSetNextMap", getRootElement())
  823. triggerClientEvent(getRootElement(), "nextmapchange", getRootElement(), getMapName(g_ForcedNextMap))
  824. end
  825. )
  826. function setNextmapByPanel(...)
  827. local query = #{...}>0 and table.concat({...},' ') or nil
  828. local map, errormsg = findMap( query )
  829. if not map then
  830. return
  831. end
  832. g_ForcedNextMap = map
  833. triggerClientEvent(getRootElement(), "nextmapchange", getRootElement(), getMapName(g_ForcedNextMap))
  834. end
  835. addEvent("onUseranelWantSetMap",true)
  836. addEventHandler("onUseranelWantSetMap",getRootElement(),setNextmapByPanel)
  837.  
  838. addCommandHandler('vaskagag',
  839. function( player, command, ... )
  840. local query = #{...}>0 and table.concat({...},' ') or nil
  841. if not query then
  842. if g_ForcedNextMap then
  843. outputRace( 'Next map is ' .. getMapName( g_ForcedNextMap ), player )
  844. else
  845. outputRace( 'Next map is not set', player )
  846. end
  847. return
  848. end
  849. if not _TESTING and not isPlayerInACLGroup(player, g_GameOptions.admingroup) then
  850. return
  851. end
  852. local map, errormsg = findMap( query )
  853. if not map then
  854. outputRace( errormsg, player )
  855. return
  856. end
  857. if g_ForcedNextMap == map then
  858. outputRace( 'Next map is already set to ' .. getMapName( g_ForcedNextMap ), player )
  859. return
  860. end
  861.  
  862. if not stateAllowsRandomMapVote() or g_CurrentRaceMode:getTimeRemaining() < 30000 then
  863. if player then
  864. outputRace( "I'm afraid I can't let you do that, " .. getPlayerName(player) .. ".", player )
  865. end
  866. return
  867. end
  868.  
  869. displayHilariarseMessage( player )
  870. exports.votemanager:stopPoll()
  871. nextmapvoteselecteD = map
  872. -- Actual vote started here
  873. local pollDidStart = exports.votemanager:startPoll {
  874. title='Do you want to set next map to '..getMapName( map )..'?',
  875. percentage=51,
  876. timeout=10,
  877. allowchange=true,
  878. visibleTo=getRootElement(),
  879. [1]={'Yes', 'midNextMapVoteResult', getRootElement(), true},
  880. [2]={'No', 'midNextMapVoteResult', getRootElement(), false;default=true},
  881. }
  882.  
  883. -- Change state if vote did start
  884. if pollDidStart then
  885. gotoState('MidMapVote')
  886. end
  887. --g_ForcedNextMap = map
  888. --outputChatBox('Next map set to ' .. getMapName( g_ForcedNextMap ) .. ' by ' .. getPlayerName( player ), g_Root, 0, 240, 0)
  889. --triggerEvent("onRaceSetNextMap", getRootElement())
  890. --triggerClientEvent(getRootElement(), "nextmapchange", getRootElement(), getMapName(g_ForcedNextMap))
  891. end
  892. )
  893.  
  894. --Find a map which matches, or nil and a text message if there is not one match
  895. function findMap( query )
  896. local maps = findMaps( query )
  897.  
  898. -- Make status string
  899. local status = "Found " .. #maps .. " match" .. ( #maps==1 and "" or "es" )
  900. for i=1,math.min(5,#maps) do
  901. status = status .. ( i==1 and ": " or ", " ) .. "'" .. getMapName( maps[i] ) .. "'"
  902. end
  903. if #maps > 5 then
  904. status = status .. " (" .. #maps - 5 .. " more)"
  905. end
  906.  
  907. if #maps == 0 then
  908. return nil, status .. " for '" .. query .. "'"
  909. end
  910. if #maps == 1 then
  911. return maps[1], status
  912. end
  913. if #maps > 1 then
  914. return nil, status
  915. end
  916. end
  917.  
  918. -- Find all maps which match the query string
  919. function findMaps( query )
  920. local results = {}
  921. --escape all meta chars
  922. query = string.gsub(query, "([%*%+%?%.%(%)%[%]%{%}%\%/%|%^%$%-])","%%%1")
  923. -- Loop through and find matching maps
  924. for i,resource in ipairs(exports.mapmanager:getMapsCompatibleWithGamemode(getThisResource())) do
  925. local resName = getResourceName( resource )
  926. local infoName = getMapName( resource )
  927.  
  928. -- Look for exact match first
  929. if query == resName or query == infoName then
  930. return {resource}
  931. end
  932.  
  933. -- Find match for query within infoName
  934. if string.find( infoName:lower(), query:lower() ) then
  935. table.insert( results, resource )
  936. break
  937. end
  938. end
  939. return results
  940. end
  941.  
  942.  
  943. function findMapSpecial( query )
  944. local maps = findMapsSpecial( query )
  945.  
  946. -- Make status string
  947. local status = "Found " .. #maps .. " match" .. ( #maps==1 and "" or "es" )
  948. for i=1,math.min(5,#maps) do
  949. status = status .. ( i==1 and ": " or ", " ) .. "'" .. getMapName( maps[i] ) .. "'"
  950. end
  951. if #maps > 5 then
  952. status = status .. " (" .. #maps - 5 .. " more)"
  953. end
  954.  
  955. if #maps == 0 then
  956. return nil, status .. " for '" .. query .. "'"
  957. end
  958. if #maps == 1 then
  959. return maps[1], status
  960. end
  961. if #maps > 1 then
  962. return nil, status
  963. end
  964. end
  965.  
  966. function findMapsSpecial( query )
  967. local results = {}
  968. --escape all meta chars
  969. query = string.gsub(query, "([%*%+%?%.%(%)%[%]%{%}%\%/%|%^%$%-])","%%%1")
  970. -- Loop through and find matching maps
  971. for i,resource in ipairs(exports.mapmanager:getMapsCompatibleWithGamemode(getThisResource())) do
  972. local resName = getResourceName( resource )
  973. local infoName = getMapName( resource )
  974.  
  975. -- Look for exact match first
  976. if query == resName or query == infoName then
  977. return {resource}
  978. end
  979.  
  980. -- Find match for query within infoName
  981. local querryEdited = tostring(query)
  982. local infoNameEdited = tostring(infoName)
  983. querryEdited = querryEdited.."end"
  984. infoNameEdited = infoNameEdited.."end"
  985. infoNameEdited:lower()
  986. querryEdited:lower()
  987.  
  988. if string.find( infoNameEdited, querryEdited) then
  989. table.insert( results, resource )
  990. break
  991. end
  992.  
  993. end
  994. return results
  995. end
  996.  
  997. function getMapName( map )
  998. return getResourceInfo( map, "name" ) or getResourceName( map ) or "unknown"
  999. end
  1000.  
  1001. addCommandHandler("deletemap",
  1002. function(thePlayer,command)
  1003. local currentMap = exports.mapmanager:getRunningGamemodeMap()
  1004. if currentMap then
  1005. if isPlayerInACLGroup(thePlayer, g_GameOptions.admingroup) then
  1006. local resourceState = getResourceState(currentMap)
  1007. if resourceState == "running" then
  1008. if stopResource(currentMap) then
  1009. setTimer(deleteMapWithDelay,1000,1,currentMap,thePlayer)
  1010. end
  1011. end
  1012. end
  1013. end
  1014. end
  1015. )
  1016.  
  1017. function deleteMapWithDelay(mapResource,thePlayer)
  1018. if mapResource then
  1019. local mapName = getMapName(mapResource)
  1020. deleteResource(mapResource)
  1021. outputChatBox(mapName.." #FF6400d#ffffffeleted #FF6400b#ffffffy "..getPlayerNametagText(thePlayer).."#ffffff." , g_Root, 255, 255, 255,true)
  1022. startRandomMap()
  1023. end
  1024. end
  1025.  
  1026. -- Find all maps which match the query string
  1027. function findMaps( query )
  1028. local results = {}
  1029. --escape all meta chars
  1030. query = string.gsub(query, "([%*%+%?%.%(%)%[%]%{%}%\%/%|%^%$%-])","%%%1")
  1031. -- Loop through and find matching maps
  1032. for i,resource in ipairs(exports.mapmanager:getMapsCompatibleWithGamemode(getThisResource())) do
  1033. local resName = getResourceName( resource )
  1034. local infoName = getMapName( resource )
  1035.  
  1036. -- Look for exact match first
  1037. if query == resName or query == infoName then
  1038. return {resource}
  1039. end
  1040.  
  1041. -- Find match for query within infoName
  1042. if string.find( infoName:lower(), query:lower() ) then
  1043. table.insert( results, resource )
  1044. end
  1045. end
  1046. return results
  1047. end
  1048.  
  1049. function getMapName( map )
  1050. return getResourceInfo( map, "name" ) or getResourceName( map ) or "unknown"
  1051. end
  1052.  
  1053. -------------------------VOTE REDO-----------------------------
  1054. local isEventRunning = false
  1055. local votesRedo = 0
  1056. local allowRedo = false
  1057. local lastMap = ""
  1058. local requiredVotes = 100
  1059. local reqFlag = false
  1060.  
  1061. function onEventBlock(state)
  1062. isEventRunning = state
  1063. end
  1064. addEvent("onEventStateChange", true)
  1065. addEventHandler("onEventStateChange", getRootElement(), onEventBlock)
  1066.  
  1067.  
  1068. local votedPlayers = {}
  1069.  
  1070. function addVotedPlayers(player)
  1071. votedPlayers[#votedPlayers+1] = getPlayerSerial(player)
  1072. end
  1073.  
  1074. function checkVotedPlayer(player)
  1075. for i=1,#votedPlayers do
  1076. if (getPlayerSerial(player) == votedPlayers[i])then
  1077. return true
  1078. end
  1079. end
  1080. return false
  1081. end
  1082.  
  1083. function voteRedoManagment(player)
  1084. if not(tostring(isEventRunning) == "true") then
  1085. if not(checkVotedPlayer(player)) then
  1086. local currentMap = getMapName(exports.mapmanager:getRunningGamemodeMap())
  1087.  
  1088. if not(reqFlag) then
  1089. requiredVotes = tonumber(math.ceil((getPlayerCount()/2)))
  1090. reqFlag = true
  1091. end
  1092.  
  1093. if not(currentMap == lastMap) then
  1094. if(votesRedo >= requiredVotes) then
  1095. outputChatBox("#FF6600* T#ffffffhe #ff6600m#ffffffap #ff6600w#ffffffill #ff6600be r#ffffffrestarted", player, 255,255,255,true)
  1096. allowRedo = true
  1097. end
  1098.  
  1099. if(votesRedo < requiredVotes) then
  1100. votesRedo = votesRedo + 1
  1101. addVotedPlayers(player)
  1102. local r, g, b = getPlayerNametagColor(player)
  1103. local hex = RGBToHex(r, g, b)
  1104. outputChatBox("#FF6600* V#ffffffoteredo #ff6600| #FF6600"..votesRedo.."#FFFFFF/#FF6600"..requiredVotes.." #ff6600| V#ffffffoted #ff6600B#ffffffy ".. hex ..''.. _getPlayerName(player)..'#FFFFFF ', root, 255, 100, 0, true)
  1105. end
  1106. else
  1107. outputChatBox("#FF6600* Y#ffffffou #ff6600c#ffffffan't #ff6600V#ffffffote #ff6600a s#ffffffecond #ff6600T#fffffime #ff6600o#ffffffn #ff6600t#ffffffhe #ff6600s#ffffffame #ff6600m#ffffffap!", player, 255,255,255,true)
  1108. end
  1109. else
  1110. outputChatBox("#FF6600* Y#FFFFFFou #FF6600h#FFFFFFave #ff6600a#fffffflready #Ff6600v#ffffffoted #ff6600o#ffffffn #ff6600t#ffffffhis #ff6600m#ffffffap", player, 255,255,255,true)
  1111. end
  1112. else
  1113. outputChatBox("#FF6600* #FFFFFFYou can't voteredo maps during the #ff6600DGE#FFFFFF.",player,255,255,255,true)
  1114. end
  1115. end
  1116. addCommandHandler("voteredo", voteRedoManagment)
  1117. addCommandHandler("vr", voteRedoManagment)
  1118.  
  1119. function onGridCountDown (stateName)
  1120. if stateName == "PostFinish" then
  1121. lastMap = getMapName(exports.mapmanager:getRunningGamemodeMap())
  1122. if(allowRedo)then
  1123. setTimer(function()
  1124. voteRedoMap()
  1125. outputChatBox('#ff6600* R#FFFFFFestarted #FF6600B#FFFFFFy #FF6600V#ffffffoteredo.', root, 255, 100, 0, true)
  1126. votesRedo = 0
  1127. allowRedo = false
  1128. votedPlayers = {}
  1129. reqFlag = false
  1130. end,7000, 1)
  1131. end
  1132. end
  1133. end
  1134. addEvent("onRaceStateChanging",true)
  1135. addEventHandler("onRaceStateChanging", getRootElement(), onGridCountDown)
  1136.  
  1137. --voteRedo
  1138. function voteRedoMap()
  1139. local currentMap = exports.mapmanager:getRunningGamemodeMap()
  1140. if currentMap then
  1141. if not exports.mapmanager:changeGamemodeMap (currentMap, nil, true) then
  1142. problemChangingMap()
  1143. end
  1144. else
  1145. outputRace("You can't restart the map because no map is running", getRootElement())
  1146. end
  1147. end
  1148.  
  1149. --Played maps array.
  1150. local mapTimeLimit = 1500 --25 min.
  1151. local currentDate = 0
  1152. local objects = {}
  1153. function addMapToArray(map)
  1154. local mapName = tostring(map)
  1155. local mapTime = tonumber(getCurrentTimeHMS())
  1156. local found = false
  1157.  
  1158. local map = {}
  1159. map[1] = mapName
  1160. map[2] = mapTime+mapTimeLimit
  1161.  
  1162. for i,mapA in ipairs(objects)do
  1163. if (mapA[1] == mapName)then
  1164. mapA[1] = map[1]
  1165. mapA[2] = map[2]
  1166. found = true
  1167. break
  1168. end
  1169. end
  1170.  
  1171. if not(found)then
  1172. for i,mapA in ipairs(objects)do
  1173. if (mapA[2] == false)then
  1174. mapA[1] = map[1]
  1175. mapA[2] = map[2]
  1176. found = true
  1177. break
  1178. end
  1179. end
  1180. end
  1181.  
  1182. if not(found)then
  1183. objects[#objects+1] = map
  1184. end
  1185. end
  1186.  
  1187.  
  1188. function checkMap(mapName)
  1189. if(getPlayerCount() == 1)then
  1190. return true
  1191. end
  1192. local todayDate = getDate ()
  1193. local currentTime = tonumber(getCurrentTimeHMS())
  1194.  
  1195. if not(tonumber(currentDate) == tonumber(todayDate))then
  1196. ressetAllMapsTime()
  1197. currentDate = tonumber(todayDate)
  1198. end
  1199.  
  1200. for i,mapA in ipairs(objects)do
  1201. if (mapA[2])and(currentTime > mapA[2])then
  1202. mapA[2] = false
  1203. end
  1204. end
  1205.  
  1206. for i,mapA in ipairs(objects)do
  1207. if(mapA[1] == mapName)then
  1208. if (mapA[2])and(currentTime > mapA[2] or mapA[2] == false)then
  1209. return true
  1210. else
  1211. if(mapA[2])then
  1212. return mapA[2]-currentTime
  1213. else
  1214. return false
  1215. end
  1216. end
  1217. end
  1218. end
  1219. return true
  1220. end
  1221.  
  1222. function ressetAllMapsTime()
  1223. objects = {}
  1224. end
  1225.  
  1226. function getCurrentTimeHMS ()
  1227. local time = getRealTime()
  1228. local hours = time.hour
  1229. local minutes = time.minute
  1230. local seconds = time.second
  1231. local secondsLength = #tostring(minutes)
  1232. local minutesLength = #tostring(minutes)
  1233. local hoursLength = #tostring(hours)
  1234. if (secondsLength == 1) then seconds = "0"..seconds end
  1235. if (minutesLength == 1) then minutes = "0"..minutes end
  1236. if (hoursLength == 1) then hours = "0"..hours end
  1237. local minutesSeconds = tonumber((hours*60*60)+(minutes*60)+seconds)
  1238.  
  1239. return minutesSeconds
  1240. end
  1241.  
  1242.  
  1243. function getDate ()
  1244. local time = getRealTime()
  1245. local hours = time.hour
  1246. local minutes = time.minute
  1247. local date = time.monthday
  1248.  
  1249. return date
  1250. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement