Advertisement
Guest User

Untitled

a guest
Nov 29th, 2021
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.00 KB | None | 0 0
  1. #include <amxmodx>
  2.  
  3. new const PLUGIN[] = "Mapchooser"
  4. new const VERSION[] = "3.0"
  5. new const AUTHOR[] = "Prayer/Safety1st"
  6.  
  7. new g_teamScore[2]
  8.  
  9. new nextmap, vote_answers, maxspeed
  10. new mp_timelimit, mp_winlimit, mp_maxrounds, mp_roundtime
  11. new extendmapmax_pcvar, extendmapstep_pcvar, votetime_pcvar, votemaps_pcvar
  12. new result_red_pcvar, result_green_pcvar, result_blue_pcvar
  13.  
  14. #define TASK_PLUGIN_ID 44747477
  15. #define TASK_SCREEN_ID 979699
  16. #define TASK_RESULT_ID 12111
  17.  
  18. const HudLen = 512
  19.  
  20. new Array:g_mapName
  21. new g_mapNums
  22. new g_saveids[10]
  23.  
  24. new g_voteCount[10]
  25. new g_nextName[10]
  26. new g_lastMap[32]
  27. new g_currentMap[32]
  28. new g_mapVoteNum
  29.  
  30. new g_votemaps
  31. new g_maxspeed = 320
  32.  
  33. new Float:f_timelimit = 0.0 // we want to restore timelimit only if we touched it
  34.  
  35. new bool:willbevote = false // there will be a vote
  36. new bool:voteStarted = false // there is vote in progress
  37. new bool:forceBlock = true // block player's selections if vote is canceled
  38. new bool:hasExtend = false // map was extended
  39. new bool:lastRound = false // map changing will be at the current round end
  40. new bool:forceChange = true // we should force map end in case if it is not round-based limit coming soon
  41.  
  42. new bool:hasBlind[33] = { false, ... }
  43. new g_msgScreenFade
  44.  
  45. new g_PlayersVoted = 0
  46. new g_PlayersNum = 0
  47.  
  48. new
  49. g_result_red,
  50. g_result_green,
  51. g_result_blue
  52.  
  53. new const g_mape_mici[] = "mape_mici.ini"
  54. new const g_mape_mari[] = "mape_mari.ini"
  55.  
  56. new delimiter
  57.  
  58. public plugin_init()
  59. {
  60. register_plugin(PLUGIN, VERSION, AUTHOR)
  61. register_cvar("super_mapchooser",VERSION,FCVAR_SERVER|FCVAR_SPONLY|FCVAR_UNLOGGED)
  62. register_dictionary("mapchooser.txt")
  63.  
  64. extendmapmax_pcvar = register_cvar("amx_extendmap_max", "90")
  65. extendmapstep_pcvar = register_cvar("amx_extendmap_step", "15")
  66. register_event("HLTV", "Event_NewRound", "a", "1=0", "2=0")
  67. register_event("TextMsg", "Event_RestartRound", "a", "2&#Game_C", "2&#Game_w")
  68. register_event("ScreenFade", "Event_ScreenFade", "be")
  69. register_event("TeamScore", "team_score", "a")
  70. register_logevent("Event_RoundEnd", 2, "0=World triggered","1=Round_End")
  71.  
  72. votetime_pcvar = register_cvar("mapchooser_votetime", "15")
  73. votemaps_pcvar = register_cvar("mapchooser_votemaps", "5")
  74.  
  75. result_red_pcvar = register_cvar("mapchooser_result_red", "0")
  76. result_green_pcvar = register_cvar("mapchooser_result_green", "255")
  77. result_blue_pcvar = register_cvar("mapchooser_result_blue", "100")
  78.  
  79. delimiter = register_cvar("mapchooser_delimiter", "9")
  80.  
  81. g_msgScreenFade = get_user_msgid("ScreenFade")
  82.  
  83. set_task(8.0, "taskListening", TASK_PLUGIN_ID, "", 0, "b")
  84. }
  85.  
  86. public plugin_cfg()
  87. {
  88. nextmap = get_cvar_pointer("amx_nextmap")
  89. vote_answers = get_cvar_pointer("amx_vote_answers")
  90. maxspeed = get_cvar_pointer("sv_maxspeed")
  91.  
  92. mp_timelimit = get_cvar_pointer("mp_timelimit")
  93. mp_winlimit = get_cvar_pointer("mp_winlimit")
  94. mp_maxrounds = get_cvar_pointer("mp_maxrounds")
  95. mp_roundtime = get_cvar_pointer("mp_roundtime")
  96.  
  97. g_votemaps = get_pcvar_num(votemaps_pcvar)
  98.  
  99. if(g_votemaps > 8)
  100. g_votemaps = 8
  101. else if(g_votemaps < 1)
  102. g_votemaps = 1
  103.  
  104. register_menucmd(register_menuid("superMapChooserMenu"), (-1^(-1<<(g_votemaps + 1))), "countVote")
  105.  
  106. g_mapName = ArrayCreate(32)
  107.  
  108. get_localinfo("lastMap", g_lastMap, sizeof g_lastMap -1)
  109. set_localinfo("lastMap", "")
  110.  
  111. new maps_ini_file[64]
  112. get_localinfo("amxx_configsdir", maps_ini_file, sizeof maps_ini_file -1)
  113.  
  114. format(maps_ini_file, sizeof maps_ini_file -1, "%s/maps.ini", maps_ini_file)
  115.  
  116. if(!file_exists(maps_ini_file))
  117. get_cvar_string("mapcyclefile", maps_ini_file, sizeof maps_ini_file -1)
  118.  
  119. if(loadSettings(maps_ini_file))
  120. Reset()
  121.  
  122. g_maxspeed = get_pcvar_num(maxspeed)
  123. get_mapname(g_currentMap, sizeof g_currentMap -1)
  124. }
  125.  
  126. public client_disconnect(id)
  127. {
  128. remove_task(id+TASK_SCREEN_ID)
  129. remove_task(id+TASK_RESULT_ID)
  130.  
  131. hasBlind[id] = false
  132. }
  133.  
  134. public Event_RestartRound()
  135. Reset()
  136.  
  137. public Event_RoundEnd()
  138. {
  139. if(lastRound && forceChange)
  140. set_task(4.5,"ForceChangeMap")
  141. }
  142.  
  143. public ForceChangeMap()
  144. {
  145. // trick: decrease mp_timelimit value to force map change. 0.3 min was carefully chosen by experiments
  146. set_pcvar_float(mp_timelimit, get_gametime() / 60.0 - 0.3)
  147. }
  148.  
  149. public Reset()
  150. {
  151. g_PlayersVoted = 0
  152. g_PlayersNum = 0
  153.  
  154. if(voteStarted)
  155. {
  156. voteStarted = false
  157. forceBlock = true
  158. remove_task(TASK_PLUGIN_ID) // remove 'checkVotes' task
  159.  
  160. if(!hasExtend)
  161. {
  162. chat_color(0, "%L", LANG_SERVER, "INTERRUPTED")
  163. }
  164. else hasExtend = false
  165. }
  166.  
  167. if(willbevote)
  168. {
  169. set_task(8.0, "taskListening", TASK_PLUGIN_ID, "", 0, "b")
  170.  
  171. if(f_timelimit > 0.0)
  172. set_pcvar_float(mp_timelimit, f_timelimit)
  173. }
  174.  
  175. willbevote = false
  176. lastRound = false
  177. forceChange = true
  178. }
  179.  
  180. public PauseGame()
  181. {
  182. new players[32], pid;
  183. get_players(players, g_PlayersNum)
  184. for(new i=0;i<g_PlayersNum;i++)
  185. {
  186. pid = players[i]
  187. hasBlind[pid] = true
  188.  
  189. message_begin(MSG_ONE, g_msgScreenFade, _, pid)
  190. write_short(1<<12) // Duration
  191. write_short(1<<9) // Hold time
  192. write_short(1<<0) // Fade type
  193. write_byte(0) // Red
  194. write_byte(0) // Green
  195. write_byte(0) // Blue
  196. write_byte(255) // Alpha
  197. message_end()
  198.  
  199. set_task(1.0, "cmdFadeScreen", pid+TASK_SCREEN_ID, "", 0, "b")
  200. }
  201.  
  202. set_pcvar_num(maxspeed, 0)
  203. }
  204.  
  205. public ContinueGame()
  206. {
  207. new players[32], num, pid
  208. get_players(players, num)
  209. for(new i=0;i<num;i++)
  210. {
  211. pid = players[i]
  212.  
  213. hasBlind[pid] = false
  214.  
  215. remove_task(pid+TASK_SCREEN_ID)
  216. remove_task(pid+TASK_RESULT_ID)
  217.  
  218. message_begin(MSG_ONE, g_msgScreenFade, _, pid)
  219. write_short(1<<0)
  220. write_short(1<<0)
  221. write_short(1<<0)
  222. write_byte(0)
  223. write_byte(0)
  224. write_byte(0)
  225. write_byte(0)
  226. message_end()
  227. }
  228.  
  229. set_pcvar_num(maxspeed, g_maxspeed)
  230. }
  231.  
  232. public taskListening()
  233. {
  234. new winlimit = get_pcvar_num(mp_winlimit)
  235.  
  236. if(winlimit)
  237. {
  238. new c = winlimit - 2
  239. if(!((c > g_teamScore[0]) && (c > g_teamScore[1])))
  240. {
  241. forceChange = false
  242. willbevote = true
  243. }
  244. }
  245.  
  246. new maxrounds = get_pcvar_num(mp_maxrounds)
  247.  
  248. if(maxrounds)
  249. {
  250. if(!((maxrounds - 2) > (g_teamScore[0] + g_teamScore[1])))
  251. {
  252. forceChange = false
  253. willbevote = true
  254. }
  255. }
  256.  
  257. new Float:f_timeleft
  258. new Float:f_diff
  259. new Float:f_roundtime
  260.  
  261. f_timeleft = float(get_timeleft())
  262.  
  263. if (f_timeleft)
  264. {
  265. f_roundtime = get_pcvar_float(mp_roundtime) * 60.0
  266. f_diff = f_roundtime - f_timeleft + get_pcvar_float(votetime_pcvar) + 15.0
  267. // we need additional 10 seconds upper to don't get countdown voice
  268.  
  269. if(!(f_timeleft < 1.0 || f_timeleft > f_diff))
  270. willbevote = true
  271. }
  272.  
  273. if(!willbevote)
  274. return
  275.  
  276. remove_task(TASK_PLUGIN_ID) // remove 'taskListening' task
  277.  
  278. chat_color(0, "%L", LANG_SERVER, "VOTE_NEXT_ROUND")
  279.  
  280. // increase timelimit if it might elapse earlier than needed
  281. if (f_timeleft)
  282. {
  283. f_timelimit = get_pcvar_float(mp_timelimit) // save current timelimit
  284. set_pcvar_float(mp_timelimit, f_timelimit + f_diff / 60.0)
  285. }
  286. }
  287.  
  288. public Event_NewRound()
  289. {
  290. if(willbevote && !lastRound)
  291. {
  292. forceBlock = false
  293. hasExtend = false
  294.  
  295. g_result_red = get_pcvar_num(result_red_pcvar)
  296. g_result_green = get_pcvar_num(result_green_pcvar)
  297. g_result_blue = get_pcvar_num(result_blue_pcvar)
  298.  
  299. cmdVoteNextmap()
  300. }
  301. }
  302.  
  303. public cmdVoteNextmap()
  304. {
  305. new file[64]
  306. get_localinfo("amxx_configsdir", file, sizeof file -1)
  307.  
  308. if( get_playersnum() > get_pcvar_num(delimiter) )
  309. {
  310. format(file, sizeof file -1, "%s/%s", file, g_mape_mari)
  311. loadSettings(file)
  312. }
  313. else
  314. {
  315. format(file, sizeof file -1, "%s/%s", file, g_mape_mici)
  316. loadSettings(file)
  317. }
  318.  
  319. new
  320. mkeys = ((1<<g_votemaps) + 1),
  321. menu[HudLen],
  322. a
  323.  
  324. new pos = format(menu, HudLen -1, " \r%L:^n^n", LANG_SERVER, "VOTE_TITLE")
  325. new dmax = (g_mapNums > g_votemaps) ? g_votemaps : g_mapNums
  326.  
  327. new unki = 0
  328.  
  329. for(g_mapVoteNum = 0; g_mapVoteNum < dmax; g_mapVoteNum++)
  330. {
  331. a = random_num(0, g_mapNums -1)
  332.  
  333. while(isInMenu(a))
  334. {
  335. if(++a >= g_mapNums)
  336. {
  337. a = 0
  338. }
  339. }
  340.  
  341. g_nextName[g_mapVoteNum] = a
  342.  
  343. new map[32]
  344. ArrayGetString(g_mapName, a, map, sizeof map -1)
  345.  
  346. pos += format(menu[pos], HudLen -1, " \y%d.\w %s^n", g_mapVoteNum + 1, map)
  347.  
  348. g_saveids[unki] = a
  349. unki++
  350.  
  351. mkeys |= (1<<g_mapVoteNum)
  352.  
  353. g_voteCount[g_mapVoteNum] = 0
  354. }
  355.  
  356. g_voteCount[g_votemaps] = 0
  357. g_voteCount[g_votemaps + 1] = 0
  358.  
  359. new winlimit = get_pcvar_num(mp_winlimit)
  360. new maxrounds = get_pcvar_num(mp_maxrounds)
  361.  
  362. if((winlimit + maxrounds) == 0 && f_timelimit < get_pcvar_float(extendmapmax_pcvar))
  363. {
  364. pos += format(menu[pos], HudLen -1, " \y%d.\w %s \y[%L]", g_votemaps + 1, g_currentMap, LANG_SERVER, "PROLONG")
  365. mkeys |= (1<<g_votemaps)
  366. }
  367.  
  368. show_menu(0, mkeys, menu, get_pcvar_num(votetime_pcvar), "superMapChooserMenu")
  369.  
  370. chat_color(0, "%L", LANG_SERVER, "VOTE_STARTED")
  371.  
  372. client_cmd(0, "spk gman/gman_choose2")
  373. set_task(get_pcvar_float(votetime_pcvar), "checkVotes", TASK_PLUGIN_ID)
  374.  
  375. PauseGame()
  376.  
  377. voteStarted = true
  378.  
  379. log_amx("Super Vote: Voting for the nextmap started")
  380. }
  381.  
  382. public checkVotes()
  383. {
  384. voteStarted = false
  385.  
  386. new bolt = 0
  387.  
  388. for(new a = 0; a < g_mapVoteNum; a++)
  389. {
  390. if(g_voteCount[bolt] < g_voteCount[a])
  391. bolt = a
  392. }
  393.  
  394. //clear channel #2
  395. set_hudmessage(.channel=2)
  396. show_hudmessage(0, "")
  397.  
  398. set_hudmessage(255, 127, 0, -1.0, 0.42, 2, 0.1, 10.0, 0.05, 1.0, 2)
  399.  
  400. if((g_voteCount[g_votemaps] > g_voteCount[bolt]) && (g_voteCount[g_votemaps] > g_voteCount[g_votemaps + 1]))
  401. {
  402. new Float:steptime = get_pcvar_float(extendmapstep_pcvar)
  403. f_timelimit = f_timelimit + steptime
  404.  
  405. chat_color(0, "%L", LANG_SERVER, "MAP_EXTENDING", steptime)
  406. show_hudmessage(0, "%L", LANG_SERVER, "MAP_EXTENDING_HUD", steptime)
  407.  
  408. log_amx("Super Vote: Voting for the nextmap finished. Map %s will be extended to next %.0f minutes", g_currentMap, steptime)
  409.  
  410. hasExtend = true
  411.  
  412. Reset()
  413. ContinueGame()
  414.  
  415. return
  416. }
  417.  
  418. new smap[32]
  419.  
  420. if(g_voteCount[bolt] && (g_voteCount[g_votemaps + 1] <= g_voteCount[bolt]))
  421. {
  422. ArrayGetString(g_mapName, g_nextName[bolt], smap, sizeof smap -1)
  423. set_pcvar_string(nextmap, smap)
  424. }
  425. else get_pcvar_string(nextmap, smap, sizeof smap -1) // get nextmap name in case if no one voted
  426.  
  427. chat_color(0, "%L", LANG_SERVER, "NEXT_MAP_CHOSEN", smap)
  428. show_hudmessage(0, "%L", LANG_SERVER, "NEXT_MAP_CHOSEN_HUD", smap)
  429.  
  430. if(forceChange)
  431. {
  432. chat_color(0, "%L", LANG_SERVER, "LAST_ROUND")
  433. set_hudmessage(255, 0, 0, -1.0, 0.58, 2, 0.1, 10.0, 0.05, 1.0, 1)
  434. show_hudmessage(0, "%L", LANG_SERVER, "LAST_ROUND_HUD")
  435. }
  436.  
  437. new players[32], num, pid
  438. get_players(players, num)
  439.  
  440. for(new i=0;i<num;i++)
  441. {
  442. pid = players[i]
  443. remove_task(pid+TASK_RESULT_ID)
  444. }
  445.  
  446. log_amx("Super Vote: Voting for the nextmap finished. The nextmap will be %s", smap)
  447.  
  448. lastRound = true
  449.  
  450. // increase timelimit if it might elapse earlier than current round
  451. new Float:f_timeleft = float(get_timeleft())
  452. if(f_timeleft) // there is timelimit for map definately
  453. set_pcvar_float(mp_timelimit, get_gametime() / 60.0 + get_pcvar_float(mp_roundtime))
  454.  
  455. ContinueGame()
  456. }
  457.  
  458. public countVote(id, key)
  459. {
  460. if(!voteStarted && forceBlock)
  461. return PLUGIN_HANDLED
  462.  
  463. if(get_pcvar_float(vote_answers))
  464. {
  465. new name[32]
  466. get_user_name(id, name, sizeof name -1)
  467.  
  468. if(key == g_votemaps)
  469. {
  470. chat_color(0, "%L", LANG_SERVER, "VOTED_EXTEND", name)
  471. }
  472. else if(key < g_votemaps)
  473. {
  474. new map[32]
  475. ArrayGetString(g_mapName, g_nextName[key], map, sizeof map -1)
  476.  
  477. chat_color(0, "%L", LANG_SERVER, "VOTED", name, map)
  478. }
  479.  
  480. cmdShowResults(id+TASK_RESULT_ID)
  481. set_task(0.8, "cmdShowResults", id+TASK_RESULT_ID, "", 0, "b")
  482. }
  483.  
  484. client_cmd(id, "spk UI/buttonclickrelease")
  485.  
  486. g_voteCount[key]++
  487. g_PlayersVoted++
  488.  
  489. return PLUGIN_HANDLED
  490. }
  491.  
  492. public cmdShowResults(pid)
  493. {
  494. static id
  495. id = pid-TASK_RESULT_ID
  496.  
  497. if(is_user_connected(id))
  498. {
  499. static i, len, message[HudLen]
  500.  
  501. len = format(message, sizeof message -1, "%L^n^n", LANG_SERVER, "VOTE_RESULTS")
  502.  
  503. for(i=0;i<g_votemaps;i++)
  504. {
  505. new map[32]
  506. ArrayGetString(g_mapName, g_saveids[i], map, sizeof map -1)
  507. len += format(message[len], HudLen -1, "[%d] | %s^n", g_voteCount, map)
  508. }
  509.  
  510. len += format(message[len], HudLen -1, "[%d] | %s [%L]^n^n", g_voteCount, g_currentMap, LANG_SERVER, "PROLONGED")
  511. len += format(message[len], HudLen -1, "%L", LANG_SERVER, "VOTE_TOTAL", g_PlayersVoted, g_PlayersNum)
  512.  
  513. set_hudmessage(g_result_red, g_result_green, g_result_blue, 0.36, 0.3, 0, 1.0, 4.0, 0.1, 0.2, 2)
  514. show_hudmessage(id, message)
  515. }
  516. }
  517.  
  518. public Event_ScreenFade(id)
  519. {
  520. if(hasBlind[id])
  521. {
  522. set_task(0.6, "cmdFadeScreen", id+TASK_SCREEN_ID)
  523. }
  524. }
  525.  
  526. public cmdFadeScreen(pid)
  527. {
  528. new id = pid-TASK_SCREEN_ID
  529.  
  530. if(is_user_connected(id))
  531. {
  532. message_begin(MSG_ONE, g_msgScreenFade, _, id)
  533. write_short(1<<0) // Duration
  534. write_short(1<<0) // Hold time
  535. write_short(1<<2) // Fade type
  536. write_byte(0) // Red
  537. write_byte(0) // Green
  538. write_byte(0) // Blue
  539. write_byte(255) // Alpha
  540. message_end()
  541. }
  542. }
  543.  
  544. public plugin_end()
  545. {
  546. new current_map[32]
  547.  
  548. set_pcvar_num(maxspeed, g_maxspeed)
  549.  
  550. get_mapname(current_map, sizeof current_map -1)
  551. set_localinfo("lastMap", current_map)
  552. }
  553.  
  554. stock bool:ValidMap(mapname[])
  555. {
  556. if(is_map_valid(mapname))
  557. {
  558. return true
  559. }
  560.  
  561. new len = strlen(mapname) -4
  562.  
  563. if(len < 0)
  564. {
  565. return false
  566. }
  567.  
  568. if(equali(mapname[len], ".bsp"))
  569. {
  570. mapname[len] = '^0'
  571.  
  572. if(is_map_valid(mapname))
  573. {
  574. return true
  575. }
  576. }
  577.  
  578. return false
  579. }
  580.  
  581. loadSettings(filename[])
  582. {
  583. if(!file_exists(filename))
  584. return 0
  585.  
  586. new
  587. currentMap[32],
  588. szText[32],
  589. buff[256]
  590.  
  591. get_mapname(currentMap, sizeof currentMap -1)
  592.  
  593. new fp = fopen(filename, "r")
  594.  
  595. while(!feof(fp))
  596. {
  597. buff[0] = '^0'
  598.  
  599. fgets(fp, buff, sizeof buff -1)
  600.  
  601. parse(buff, szText, sizeof szText -1)
  602.  
  603. if((szText[0] != ';') && ValidMap(szText) && !equali(szText, g_lastMap) && !equali(szText, currentMap))
  604. {
  605. ArrayPushString(g_mapName, szText)
  606.  
  607. g_mapNums++
  608. }
  609. }
  610.  
  611. fclose(fp)
  612.  
  613. return g_mapNums
  614. }
  615.  
  616. bool:isInMenu(id)
  617. {
  618. for(new a = 0; a < g_mapVoteNum; a++)
  619. {
  620. if(id == g_nextName[a])
  621. {
  622. return true
  623. }
  624. }
  625.  
  626. return false
  627. }
  628.  
  629. //From the AMXX nextmap base file
  630. public team_score()
  631. {
  632. new team[2]
  633. read_data(1,team,1)
  634. g_teamScore[(team[0]=='C') ? 0 : 1] = read_data(2)
  635. }
  636. stock chat_color(const id, const input[], any:...)
  637. {
  638. new count = 1, players[32]
  639. static msg[320]
  640. vformat(msg, 190, input, 3)
  641. replace_all(msg, 190, "!g", "^4")
  642. replace_all(msg, 190, "!n", "^1")
  643. replace_all(msg, 190, "!t", "^3")
  644. replace_all(msg, 190, "!t2", "^0")
  645. if (id) players[0] = id; else get_players(players, count, "ch")
  646. {
  647. for (new i = 0; i < count; i++)
  648. {
  649. if (is_user_connected(players[i]))
  650. {
  651. message_begin(MSG_ONE_UNRELIABLE, get_user_msgid("SayText"), _, players[i])
  652. write_byte(players[i])
  653. write_string(msg)
  654. message_end()
  655. }
  656. }
  657. }
  658. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement