Advertisement
Simoss

Untitled

Sep 17th, 2017
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 46.88 KB | None | 0 0
  1. CONTROL_MARGIN_RIGHT = 5
  2. LINE_MARGIN = 5
  3. LINE_HEIGHT = 16
  4.  
  5. g_Root = getRootElement()
  6. g_ResRoot = getResourceRootElement(getThisResource())
  7. g_Me = getLocalPlayer()
  8. setElementData( g_Me, 'isWarpIntoEnabled', nil )
  9. setElementData( g_Me, 'isWarpEnabled', nil )
  10. server = createServerCallInterface()
  11. guiSetInputMode("no_binds_when_editing")
  12.  
  13. -- Place to store the ticks for anti spam:
  14. local antiCommandSpam = {}
  15.  
  16. -- Player's current gravity set by gravity window --
  17. local playerGravity = getGravity()
  18.  
  19. -- Local settings received from server
  20. local command_ddos_protection
  21. local tries_required_to_trigger
  22. local tries_required_to_trigger_exceptions
  23. local duration_of_global_ban
  24.  
  25. -- Settings are stored in meta.xml
  26. addEvent("spamProtectionSettings", true)
  27. function spamProtectionSettings(settings)
  28. if settings then
  29. command_ddos_protection = settings.command_spam_protection
  30. tries_required_to_trigger = settings.tries_required_to_trigger
  31. tries_required_to_trigger_exceptions = settings.tries_required_to_trigger_low
  32. duration_of_global_ban = settings.command_spam_ban_duration
  33. end
  34. end
  35. addEventHandler("spamProtectionSettings", localPlayer, spamProtectionSettings)
  36.  
  37. -- Store the tries for forced global cooldown
  38. local global_cooldown = 0
  39. function isCommandOnCD(cmd, exception)
  40. local tick = getTickCount()
  41.  
  42. -- check if a global cd is active
  43. if command_ddos_protection == "true" and global_cooldown ~= 0 then
  44. if tick - global_cooldown <= duration_of_global_ban then
  45. local duration = math.ceil((duration_of_global_ban-tick+global_cooldown)/1000)
  46. errMsg("You are banned from using commands for " .. duration .." seconds due to continuous spam")
  47. return true
  48. end
  49. end
  50.  
  51. if command_ddos_protection ~= "true" then
  52. return false
  53. end
  54.  
  55. if not antiCommandSpam[cmd] then
  56. antiCommandSpam[cmd] = {time = tick, tries = 1}
  57. return false
  58. end
  59.  
  60. local oldTime = antiCommandSpam[cmd].time
  61. if (tick-oldTime) > 2000 then
  62. antiCommandSpam[cmd].time = tick
  63. antiCommandSpam[cmd].tries = 1
  64. return false
  65. end
  66.  
  67. antiCommandSpam[cmd].tries = antiCommandSpam[cmd].tries + 1
  68.  
  69. if exception and (antiCommandSpam[cmd].tries < tries_required_to_trigger_exceptions) then
  70. return false
  71. end
  72.  
  73. if (exception == nil) and (antiCommandSpam[cmd].tries < tries_required_to_trigger) then
  74. return false
  75. end
  76.  
  77. -- activate a global command cooldown
  78. global_cooldown = tick
  79. antiCommandSpam[cmd].tries = 0
  80. errMsg("Failed, do not spam the '" .. tostring(cmd) .. "' command!")
  81. return true
  82. end
  83.  
  84. ---------------------------
  85. -- Set skin window
  86. ---------------------------
  87. function skinInit()
  88. setControlNumber(wndSkin, 'skinid', getElementModel(g_Me))
  89. end
  90.  
  91. function showSkinID(leaf)
  92. if leaf.id then
  93. setControlNumber(wndSkin, 'skinid', leaf.id)
  94. end
  95. end
  96.  
  97. function applySkin()
  98. local skinID = getControlNumber(wndSkin, 'skinid')
  99. if skinID then
  100. server.setMySkin(skinID)
  101. fadeCamera(true)
  102. end
  103. end
  104.  
  105. wndSkin = {
  106. 'wnd',
  107. text = 'Set skin',
  108. width = 250,
  109. x = -20,
  110. y = 0.3,
  111. controls = {
  112. {
  113. 'lst',
  114. id='skinlist',
  115. width=230,
  116. height=290,
  117. columns={
  118. {text='Skin', attr='name'}
  119. },
  120. rows={xml='skins.xml', attrs={'id', 'name'}},
  121. onitemclick=showSkinID,
  122. onitemdoubleclick=applySkin
  123. },
  124. {'txt', id='skinid', text='', width=50},
  125. {'btn', id='set', onclick=applySkin},
  126. {'btn', id='close', closeswindow=true}
  127. },
  128. oncreate = skinInit
  129. }
  130.  
  131. function setSkinCommand(cmd, skin)
  132. if isCommandOnCD(cmd) then return end
  133. skin = skin and tonumber(skin)
  134. if skin then
  135. server.setMySkin(skin)
  136. fadeCamera(true)
  137. closeWindow(wndSpawnMap)
  138. closeWindow(wndSetPos)
  139. end
  140. end
  141. addCommandHandler('setskin', setSkinCommand)
  142. addCommandHandler('ss', setSkinCommand)
  143.  
  144. ---------------------------
  145. --- Set animation window
  146. ---------------------------
  147.  
  148. function applyAnimation(leaf)
  149. if type(leaf) ~= 'table' then
  150. leaf = getSelectedGridListLeaf(wndAnim, 'animlist')
  151. if not leaf then
  152. return
  153. end
  154. end
  155. server.setPedAnimation(g_Me, leaf.parent.name, leaf.name, true, true)
  156. end
  157.  
  158. function stopAnimation()
  159. server.setPedAnimation(g_Me, false)
  160. end
  161. addCommandHandler("stopanim", stopAnimation)
  162. bindKey("lshift", "down", "stopanim")
  163.  
  164. wndAnim = {
  165. 'wnd',
  166. text = 'Set animation',
  167. width = 250,
  168. x = -20,
  169. y = 0.3,
  170. controls = {
  171. {
  172. 'lst',
  173. id='animlist',
  174. width=230,
  175. height=290,
  176. columns={
  177. {text='Animation', attr='name'}
  178. },
  179. rows={xml='animations.xml', attrs={'name'}},
  180. expandlastlevel=false,
  181. onitemdoubleclick=applyAnimation
  182. },
  183. {'btn', id='set', onclick=applyAnimation},
  184. {'btn', id='stop', onclick=stopAnimation},
  185. {'btn', id='close', closeswindow=true}
  186. }
  187. }
  188.  
  189. addCommandHandler('anim',
  190. function(command, lib, name)
  191. if lib and name and (
  192. (lib:lower() == "finale" and name:lower() == "fin_jump_on") or
  193. (lib:lower() == "finale2" and name:lower() == "fin_cop1_climbout")
  194. ) then
  195. errMsg('This animation may not be set by command.')
  196. return
  197. end
  198. server.setPedAnimation(g_Me, lib, name, true, true)
  199. end
  200. )
  201.  
  202. ---------------------------
  203. -- Weapon window
  204. ---------------------------
  205.  
  206. function addWeapon(leaf, amount)
  207. if isCommandOnCD("giveweapon", true) then return end
  208. if type(leaf) ~= 'table' then
  209. leaf = getSelectedGridListLeaf(wndWeapon, 'weaplist')
  210. amount = getControlNumber(wndWeapon, 'amount')
  211. if not amount or not leaf or not leaf.id then
  212. return
  213. end
  214. end
  215. server.giveMeWeapon(leaf.id, amount)
  216. end
  217.  
  218. wndWeapon = {
  219. 'wnd',
  220. text = 'Give weapon',
  221. width = 250,
  222. controls = {
  223. {
  224. 'lst',
  225. id='weaplist',
  226. width=230,
  227. height=280,
  228. columns={
  229. {text='Weapon', attr='name'}
  230. },
  231. rows={xml='weapons.xml', attrs={'id', 'name'}},
  232. onitemdoubleclick=function(leaf) addWeapon(leaf, 500) end
  233. },
  234. {'br'},
  235. {'txt', id='amount', text='500', width=60},
  236. {'btn', id='add', onclick=addWeapon},
  237. {'btn', id='close', closeswindow=true}
  238. }
  239. }
  240.  
  241. function giveWeaponCommand(cmd, weapon, amount)
  242. if isCommandOnCD(cmd) then return end
  243. weapon = tonumber(weapon) or getWeaponIDFromName(weapon)
  244. if not weapon then
  245. return
  246. end
  247. amount = amount and tonumber(amount) or 500
  248. server.giveMeWeapon(math.floor(weapon), amount)
  249. end
  250. addCommandHandler('give', giveWeaponCommand)
  251. addCommandHandler('wp', giveWeaponCommand)
  252.  
  253. ---------------------------
  254. -- Fighting style
  255. ---------------------------
  256.  
  257. addCommandHandler('setstyle',
  258. function(cmd, style)
  259. style = style and tonumber(style)
  260. if style then
  261. server.setPedFightingStyle(g_Me, style)
  262. end
  263. end
  264. )
  265.  
  266. ---------------------------
  267. -- Clothes window
  268. ---------------------------
  269. function clothesInit()
  270. if getElementModel(g_Me) ~= 0 then
  271. errMsg('You must have the CJ skin set in order to apply clothes.')
  272. closeWindow(wndClothes)
  273. return
  274. end
  275. if not g_Clothes then
  276. triggerServerEvent('onClothesInit', resourceRoot)
  277. end
  278. end
  279.  
  280. addEvent('onClientClothesInit', true)
  281. addEventHandler('onClientClothesInit', resourceRoot,
  282. function(clothes)
  283. g_Clothes = clothes.allClothes
  284. for i,typeGroup in ipairs(g_Clothes) do
  285. for j,cloth in ipairs(typeGroup.children) do
  286. if not cloth.name then
  287. cloth.name = cloth.model .. ' - ' .. cloth.texture
  288. end
  289. cloth.wearing =
  290. clothes.playerClothes[typeGroup.type] and
  291. clothes.playerClothes[typeGroup.type].texture == cloth.texture and
  292. clothes.playerClothes[typeGroup.type].model == cloth.model
  293. or false
  294. end
  295. table.sort(typeGroup.children, function(a, b) return a.name < b.name end)
  296. end
  297. bindGridListToTable(wndClothes, 'clothes', g_Clothes, false)
  298. end
  299. )
  300.  
  301. function clothListClick(cloth)
  302. setControlText(wndClothes, 'addremove', cloth.wearing and 'remove' or 'add')
  303. end
  304.  
  305. function applyClothes(cloth)
  306. if not cloth then
  307. cloth = getSelectedGridListLeaf(wndClothes, 'clothes')
  308. if not cloth then
  309. return
  310. end
  311. end
  312. if cloth.wearing then
  313. cloth.wearing = false
  314. setControlText(wndClothes, 'addremove', 'add')
  315. server.removePedClothes(g_Me, cloth.parent.type)
  316. else
  317. local prevClothIndex = table.find(cloth.siblings, 'wearing', true)
  318. if prevClothIndex then
  319. cloth.siblings[prevClothIndex].wearing = false
  320. end
  321. cloth.wearing = true
  322. setControlText(wndClothes, 'addremove', 'remove')
  323. server.addPedClothes(g_Me, cloth.texture, cloth.model, cloth.parent.type)
  324. end
  325. end
  326.  
  327. wndClothes = {
  328. 'wnd',
  329. text = 'Clothes',
  330. x = -20,
  331. y = 0.3,
  332. width = 350,
  333. controls = {
  334. {
  335. 'lst',
  336. id='clothes',
  337. width=330,
  338. height=390,
  339. columns={
  340. {text='Clothes', attr='name', width=0.6},
  341. {text='Wearing', attr='wearing', enablemodify=true, width=0.3}
  342. },
  343. rows={
  344. {name='Retrieving clothes list...'}
  345. },
  346. onitemclick=clothListClick,
  347. onitemdoubleclick=applyClothes
  348. },
  349. {'br'},
  350. {'btn', text='add', id='addremove', width=60, onclick=applyClothes},
  351. {'btn', id='close', closeswindow=true}
  352. },
  353. oncreate = clothesInit
  354. }
  355.  
  356. function addClothesCommand(cmd, type, model, texture)
  357. type = type and tonumber(type)
  358. if type and model and texture then
  359. server.addPedClothes(g_Me, texture, model, type)
  360. end
  361. end
  362. addCommandHandler('addclothes', addClothesCommand)
  363. addCommandHandler('ac', addClothesCommand)
  364.  
  365. function removeClothesCommand(cmd, type)
  366. type = type and tonumber(type)
  367. if type then
  368. server.removePedClothes(g_Me, type)
  369. end
  370. end
  371. addCommandHandler('removeclothes', removeClothesCommand)
  372. addCommandHandler('rc', removeClothesCommand)
  373.  
  374. ---------------------------
  375. -- Player gravity window
  376. ---------------------------
  377. function playerGravInit()
  378. triggerServerEvent('onPlayerGravInit', resourceRoot)
  379. end
  380.  
  381. addEvent('onClientPlayerGravInit', true)
  382. addEventHandler('onClientPlayerGravInit', resourceRoot,
  383. function(curgravity)
  384. setControlText(wndGravity, 'gravval', string.sub(tostring(curgravity), 1, 6))
  385. end
  386. )
  387.  
  388. function selectPlayerGrav(leaf)
  389. setControlNumber(wndGravity, 'gravval', leaf.value)
  390. end
  391.  
  392. function applyPlayerGrav()
  393. local grav = getControlNumber(wndGravity, 'gravval')
  394. if grav then
  395. playerGravity = grav
  396. server.setPedGravity(g_Me, grav)
  397. end
  398. closeWindow(wndGravity)
  399. end
  400.  
  401. function setGravityCommand(cmd, grav)
  402. if isCommandOnCD(cmd) then return end
  403. local grav = grav and tonumber(grav)
  404. if grav then
  405. playerGravity = grav
  406. server.setPedGravity(g_Me, tonumber(grav))
  407. end
  408. end
  409. addCommandHandler('setgravity', setGravityCommand)
  410. addCommandHandler('grav', setGravityCommand)
  411.  
  412. wndGravity = {
  413. 'wnd',
  414. text = 'Set gravity',
  415. width = 300,
  416. controls = {
  417. {
  418. 'lst',
  419. id='gravlist',
  420. width=280,
  421. height=200,
  422. columns={
  423. {text='Gravity', attr='name'}
  424. },
  425. rows={
  426. {name='Space', value=0},
  427. {name='Moon', value=0.001},
  428. {name='Normal', value=0.008},
  429. {name='Strong', value=0.015}
  430. },
  431. onitemclick=selectPlayerGrav,
  432. onitemdoubleclick=applyPlayerGrav
  433. },
  434. {'lbl', text='Exact value: '},
  435. {'txt', id='gravval', text='', width=80},
  436. {'br'},
  437. {'btn', id='ok', onclick=applyPlayerGrav},
  438. {'btn', id='cancel', closeswindow=true}
  439. },
  440. oncreate = playerGravInit
  441. }
  442.  
  443. ---------------------------
  444. -- Warp to player window
  445. ---------------------------
  446. function warpInit()
  447. local players = table.map(getElementsByType('player'), function(p) return { player = p, name = getPlayerName(p) } end)
  448. table.sort(players, function(a, b) return a.name < b.name end)
  449. bindGridListToTable(wndWarp, 'playerlist', players, true)
  450. end
  451.  
  452. function warpTo(leaf)
  453. if not leaf then
  454. leaf = getSelectedGridListLeaf(wndWarp, 'playerlist')
  455. if not leaf then
  456. return
  457. end
  458. end
  459. if isElement(leaf.player) then
  460. if ( getElementData( leaf.player, 'isWarpEnabled' ) == 'false' ) then outputChatBox( 'Error, You cannot warp to this player', 255, 0, 0, true ) return end
  461. server.warpMe(leaf.player)
  462. end
  463. closeWindow(wndWarp)
  464. end
  465.  
  466. wndWarp = {
  467. 'wnd',
  468. text = 'Warp to player',
  469. width = 300,
  470. alpha = 1.0,
  471. controls = {
  472. {
  473. 'lst',
  474. id='playerlist',
  475. width=280,
  476. height=330,
  477. columns={
  478. {text='Player', attr='name'}
  479. },
  480. onitemdoubleclick=warpTo
  481. },
  482. {'btn', id='warp', onclick=warpTo},
  483. {'btn', id='cancel', closeswindow=true}
  484. },
  485. oncreate = warpInit
  486. }
  487.  
  488. function warpToCommand(cmd, player)
  489. if player then
  490. player = getPlayerFromName(player)
  491. if player then
  492. server.warpMe(player)
  493. end
  494. else
  495. createWindow(wndWarp)
  496. showCursor(true)
  497. end
  498. end
  499.  
  500. addCommandHandler('warpto', warpToCommand)
  501. addCommandHandler('wt', warpToCommand)
  502.  
  503. ---------------------------
  504. -- Stats window
  505. ---------------------------
  506.  
  507. function initStats()
  508. applyToLeaves(getGridListCache(wndStats, 'statslist'), function(leaf) leaf.value = getPedStat(g_Me, leaf.id) end)
  509. end
  510.  
  511. function selectStat(leaf)
  512. setControlNumber(wndStats, 'statval', leaf.value)
  513. end
  514.  
  515. function maxStat(leaf)
  516. setControlNumber(wndStats, 'statval', 1000)
  517. applyStat()
  518. end
  519.  
  520. function applyStat()
  521. local leaf = getSelectedGridListLeaf(wndStats, 'statslist')
  522. if not leaf then
  523. return
  524. end
  525. local value = getControlNumber(wndStats, 'statval')
  526. if not value then
  527. return
  528. end
  529. leaf.value = value
  530. server.setPedStat(g_Me, leaf.id, value)
  531. end
  532.  
  533. wndStats = {
  534. 'wnd',
  535. text = 'Stats',
  536. width = 300,
  537. x = -20,
  538. y = 0.3,
  539. controls = {
  540. {
  541. 'lst',
  542. id='statslist',
  543. width=280,
  544. columns={
  545. {text='Stat', attr='name', width=0.6},
  546. {text='Value', attr='value', width=0.3, enablemodify=true}
  547. },
  548. rows={xml='stats.xml', attrs={'name', 'id'}},
  549. onitemclick=selectStat,
  550. onitemdoubleclick=maxStat
  551. },
  552. {'txt', id='statval', text='', width=60},
  553. {'btn', id='set', onclick=applyStat},
  554. {'btn', id='close', closeswindow=true}
  555. },
  556. oncreate = initStats
  557. }
  558.  
  559. ---------------------------
  560. -- Bookmarks window
  561. ---------------------------
  562.  
  563. local bookmarkList
  564. local bookmarks
  565.  
  566. function initBookmarks ()
  567. bookmarkList = wndBookmarks.controls[1].element
  568. if bookmarks then return end
  569. loadBookmarks ()
  570. addEventHandler("onClientGUIDoubleClick",bookmarkList,gotoBookmark)
  571. end
  572.  
  573. function loadBookmarks ()
  574. bookmarks = {}
  575. local xml = xmlLoadFile("bookmarks.xml")
  576. if not xml then
  577. xml = xmlCreateFile("bookmarks.xml","catalog")
  578. end
  579. guiGridListClear(bookmarkList)
  580. for i,child in ipairs (xmlNodeGetChildren(xml) or {}) do
  581. local row = guiGridListAddRow(bookmarkList)
  582. guiGridListSetItemText(bookmarkList,row,1,tostring(xmlNodeGetAttribute(child,"name")),false,false)
  583. guiGridListSetItemText(bookmarkList,row,2,tostring(xmlNodeGetAttribute(child,"zone")),false,false)
  584. bookmarks[row+1] = {tonumber(xmlNodeGetAttribute(child,"x")),tonumber(xmlNodeGetAttribute(child,"y")),tonumber(xmlNodeGetAttribute(child,"z"))}
  585. end
  586. end
  587.  
  588. function saveBookmarks ()
  589. if fileExists("bookmarks.xml") then
  590. fileDelete("bookmarks.xml")
  591. end
  592. local xml = xmlCreateFile("bookmarks.xml","catalog")
  593. for row=0,(guiGridListGetRowCount(bookmarkList)-1) do
  594. local child = xmlCreateChild(xml,"bookmark")
  595. xmlNodeSetAttribute(child,"name",guiGridListGetItemText(bookmarkList,row,1))
  596. xmlNodeSetAttribute(child,"zone",guiGridListGetItemText(bookmarkList,row,2))
  597. xmlNodeSetAttribute(child,"x",tostring(bookmarks[row+1][1]))
  598. xmlNodeSetAttribute(child,"y",tostring(bookmarks[row+1][2]))
  599. xmlNodeSetAttribute(child,"z",tostring(bookmarks[row+1][3]))
  600. end
  601. xmlSaveFile(xml)
  602. xmlUnloadFile(xml)
  603. end
  604.  
  605. function saveLocation ()
  606. local name = getControlText(wndBookmarks,"bookmarkname")
  607. if name ~= "" then
  608. local x,y,z = getElementPosition(g_Me)
  609. local zone = getZoneName(x,y,z,false)
  610. if x and y and z then
  611. local row = guiGridListAddRow(bookmarkList)
  612. guiGridListSetItemText(bookmarkList,row,1,name,false,false)
  613. guiGridListSetItemText(bookmarkList,row,2,zone,false,false)
  614. bookmarks[row+1] = {x,y,z}
  615. setControlText(wndBookmarks,"bookmarkname","")
  616. saveBookmarks()
  617. end
  618. else
  619. outputChatBox("Please enter a name for the bookmark")
  620. end
  621. end
  622.  
  623. function deleteLocation ()
  624. local row,column = guiGridListGetSelectedItem(bookmarkList)
  625. if row and row ~= -1 then
  626. table.remove(bookmarks,row+1)
  627. guiGridListRemoveRow(bookmarkList,row)
  628. saveBookmarks()
  629. end
  630. end
  631.  
  632. function gotoBookmark ()
  633. local row,column = guiGridListGetSelectedItem(bookmarkList)
  634. if row and row ~= -1 then
  635. fadeCamera(false)
  636. if isPedDead(g_Me) then
  637. setTimer(server.spawnMe,1000,1,unpack(bookmarks[row+1]))
  638. else
  639. setTimer(setElementPosition,1000,1,g_Me,unpack(bookmarks[row+1]))
  640. end
  641. setTimer(function () fadeCamera(true) setCameraTarget(g_Me) end,2000,1)
  642. end
  643. end
  644.  
  645. wndBookmarks = {
  646. 'wnd',
  647. text = 'Bookmarks',
  648. width = 400,
  649. x = -300,
  650. y = 0.2,
  651. controls = {
  652. {
  653. 'lst',
  654. id='bookmarklist',
  655. width=400,
  656. columns={
  657. {text='Name', attr='name', width=0.3},
  658. {text='Zone', attr='zone', width=0.6}
  659. }
  660. },
  661. {'txt', id='bookmarkname', text='', width=225},
  662. {'btn', id='save current location', onclick=saveLocation, width=150},
  663. {'btn', id='delete selected location', onclick=deleteLocation, width=225},
  664. {'btn', id='close', closeswindow=true, width=150}
  665. },
  666. oncreate = initBookmarks
  667. }
  668.  
  669. ---------------------------
  670. -- Jetpack toggle
  671. ---------------------------
  672. function toggleJetPack()
  673. if not doesPedHaveJetPack(g_Me) then
  674. server.givePedJetPack(g_Me)
  675. guiCheckBoxSetSelected(getControl(wndMain, 'jetpack'), true)
  676. else
  677. server.removePedJetPack(g_Me)
  678. guiCheckBoxSetSelected(getControl(wndMain, 'jetpack'), false)
  679. end
  680. end
  681.  
  682. bindKey('j', 'down', toggleJetPack)
  683.  
  684. addCommandHandler('jetpack', toggleJetPack)
  685. addCommandHandler('jp', toggleJetPack)
  686.  
  687.  
  688. ---------------------------
  689. -- Fall off bike toggle
  690. ---------------------------
  691. function toggleFallOffBike()
  692. setPedCanBeKnockedOffBike(g_Me, guiCheckBoxGetSelected(getControl(wndMain, 'falloff')))
  693. end
  694.  
  695. ---------------------------
  696. -- Set position window
  697. ---------------------------
  698. do
  699. local screenWidth, screenHeight = guiGetScreenSize()
  700. g_MapSide = (screenHeight * 0.85)
  701. end
  702.  
  703. function setPosInit()
  704. local x, y, z = getElementPosition(g_Me)
  705. setControlNumbers(wndSetPos, { x = x, y = y, z = z })
  706.  
  707. addEventHandler('onClientRender', g_Root, updatePlayerBlips)
  708. end
  709.  
  710. function fillInPosition(relX, relY, btn)
  711. if (btn == 'right') then
  712. closeWindow (wndSetPos)
  713. return
  714. end
  715.  
  716. local x = relX*6000 - 3000
  717. local y = 3000 - relY*6000
  718. local hit, hitX, hitY, hitZ
  719. hit, hitX, hitY, hitZ = processLineOfSight(x, y, 3000, x, y, -3000)
  720. setControlNumbers(wndSetPos, { x = x, y = y, z = hitZ or 0 })
  721. end
  722.  
  723. function setPosClick()
  724. if setPlayerPosition(getControlNumbers(wndSetPos, {'x', 'y', 'z'})) ~= false then
  725. if getElementInterior(g_Me) ~= 0 then
  726. if getPedOccupiedVehicle(g_Me) and getVehicleController(getPedOccupiedVehicle(g_Me)) == g_Me then
  727. server.setElementInterior(getPedOccupiedVehicle(g_Me), 0)
  728. end
  729. server.setElementInterior(g_Me, 0)
  730. end
  731. closeWindow(wndSetPos)
  732. end
  733. end
  734.  
  735. function setPlayerPosition(x, y, z)
  736. local elem = getPedOccupiedVehicle(g_Me)
  737. local distanceToGround
  738. local isVehicle
  739. if elem and getPedOccupiedVehicle(g_Me) then
  740. local controller = getVehicleController(elem)
  741. if controller and controller ~= g_Me then
  742. errMsg('Only the driver of the vehicle can set its position.')
  743. return false
  744. end
  745. distanceToGround = getElementDistanceFromCentreOfMassToBaseOfModel(elem) + 3
  746. isVehicle = true
  747. else
  748. elem = g_Me
  749. distanceToGround = 0.4
  750. isVehicle = false
  751. end
  752. local hit, hitX, hitY, hitZ = processLineOfSight(x, y, 3000, x, y, -3000)
  753. if not hit then
  754. if isVehicle then
  755. server.fadeVehiclePassengersCamera(false)
  756. else
  757. fadeCamera(false)
  758. end
  759. if isTimer(g_TeleportMatrixTimer) then killTimer(g_TeleportMatrixTimer) end
  760. g_TeleportMatrixTimer = setTimer(setCameraMatrix, 1000, 1, x, y, z)
  761. if not grav then
  762. grav = playerGravity
  763. setGravity(0.001)
  764. end
  765. if isTimer(g_TeleportTimer) then killTimer(g_TeleportTimer) end
  766. g_TeleportTimer = setTimer(
  767. function()
  768. local hit, groundX, groundY, groundZ = processLineOfSight(x, y, 3000, x, y, -3000)
  769. if hit then
  770. local waterZ = getWaterLevel(x, y, 100)
  771. z = (waterZ and math.max(groundZ, waterZ) or groundZ) + distanceToGround
  772. if isPedDead(g_Me) then
  773. server.spawnMe(x, y, z)
  774. else
  775. server.setMyPos(x, y, z)
  776. end
  777. setCameraPlayerMode()
  778. setGravity(grav)
  779. if isVehicle then
  780. server.fadeVehiclePassengersCamera(true)
  781. else
  782. fadeCamera(true)
  783. end
  784. killTimer(g_TeleportTimer)
  785. g_TeleportTimer = nil
  786. grav = nil
  787. end
  788. end,
  789. 500,
  790. 0
  791. )
  792. else
  793. if isPedDead(g_Me) then
  794. server.spawnMe(x, y, z + distanceToGround)
  795. else
  796. server.setMyPos(x, y, z + distanceToGround)
  797. if isVehicle then
  798. setTimer(setElementVelocity, 100, 1, elem, 0, 0, 0)
  799. setTimer(setVehicleTurnVelocity, 100, 1, elem, 0, 0, 0)
  800. end
  801. end
  802. end
  803. end
  804.  
  805. function updatePlayerBlips()
  806. if not g_PlayerData then
  807. return
  808. end
  809. local wnd = isWindowOpen(wndSpawnMap) and wndSpawnMap or wndSetPos
  810. local mapControl = getControl(wnd, 'map')
  811. for elem,player in pairs(g_PlayerData) do
  812. if not player.gui.mapBlip then
  813. player.gui.mapBlip = guiCreateStaticImage(0, 0, 9, 9, elem == g_Me and 'localplayerblip.png' or 'playerblip.png', false, mapControl)
  814. player.gui.mapLabelShadow = guiCreateLabel(0, 0, 100, 14, player.name, false, mapControl)
  815. local labelWidth = guiLabelGetTextExtent(player.gui.mapLabelShadow)
  816. guiSetSize(player.gui.mapLabelShadow, labelWidth, 14, false)
  817. guiSetFont(player.gui.mapLabelShadow, 'default-bold-small')
  818. guiLabelSetColor(player.gui.mapLabelShadow, 255, 255, 255)
  819. player.gui.mapLabel = guiCreateLabel(0, 0, labelWidth, 14, player.name, false, mapControl)
  820. guiSetFont(player.gui.mapLabel, 'default-bold-small')
  821. guiLabelSetColor(player.gui.mapLabel, 0, 0, 0)
  822. for i,name in ipairs({'mapBlip', 'mapLabelShadow'}) do
  823. addEventHandler('onClientGUIDoubleClick', player.gui[name],
  824. function()
  825. server.warpMe(elem)
  826. closeWindow(wnd)
  827. end,
  828. false
  829. )
  830. end
  831. end
  832. local x, y = getElementPosition(elem)
  833. x = math.floor((x + 3000) * g_MapSide / 6000) - 4
  834. y = math.floor((3000 - y) * g_MapSide / 6000) - 4
  835. guiSetPosition(player.gui.mapBlip, x, y, false)
  836. guiSetPosition(player.gui.mapLabelShadow, x + 14, y - 4, false)
  837. guiSetPosition(player.gui.mapLabel, x + 13, y - 5, false)
  838. end
  839. end
  840.  
  841. addEventHandler('onClientPlayerChangeNick', g_Root,
  842. function(oldNick, newNick)
  843. if (not g_PlayerData) then return end
  844. local player = g_PlayerData[source]
  845. player.name = newNick
  846. if player.gui.mapLabel then
  847. guiSetText(player.gui.mapLabelShadow, newNick)
  848. guiSetText(player.gui.mapLabel, newNick)
  849. local labelWidth = guiLabelGetTextExtent(player.gui.mapLabelShadow)
  850. guiSetSize(player.gui.mapLabelShadow, labelWidth, 14, false)
  851. guiSetSize(player.gui.mapLabel, labelWidth, 14, false)
  852. end
  853. end
  854. )
  855.  
  856. function closePositionWindow()
  857. removeEventHandler('onClientRender', g_Root, updatePlayerBlips)
  858. end
  859.  
  860. wndSetPos = {
  861. 'wnd',
  862. text = 'Set position',
  863. width = g_MapSide + 20,
  864. controls = {
  865. {'img', id='map', src='map.png', width=g_MapSide, height=g_MapSide, onclick=fillInPosition, ondoubleclick=setPosClick},
  866. {'txt', id='x', text='', width=60},
  867. {'txt', id='y', text='', width=60},
  868. {'txt', id='z', text='', width=60},
  869. {'btn', id='ok', onclick=setPosClick},
  870. {'btn', id='cancel', closeswindow=true},
  871. {'lbl', text='Right click on map to close'}
  872. },
  873. oncreate = setPosInit,
  874. onclose = closePositionWindow
  875. }
  876.  
  877. function getPosCommand(cmd, playerName)
  878. local player, sentenceStart
  879.  
  880. if playerName then
  881. player = getPlayerFromName(playerName)
  882. if not player then
  883. errMsg('There is no player named "' .. playerName .. '".')
  884. return
  885. end
  886. playerName = getPlayerName(player) -- make sure case is correct
  887. sentenceStart = playerName .. ' is '
  888. else
  889. player = g_Me
  890. sentenceStart = 'You are '
  891. end
  892.  
  893. local px, py, pz = getElementPosition(player)
  894. local vehicle = getPedOccupiedVehicle(player)
  895. if vehicle then
  896. outputChatBox(sentenceStart .. 'in a ' .. getVehicleName(vehicle), 0, 255, 0)
  897. else
  898. outputChatBox(sentenceStart .. 'on foot', 0, 255, 0)
  899. end
  900. outputChatBox(sentenceStart .. 'at (' .. string.format("%.5f", px) .. ' ' .. string.format("%.5f", py) .. ' ' .. string.format("%.5f", pz) .. ')', 0, 255, 0)
  901. end
  902. addCommandHandler('getpos', getPosCommand)
  903. addCommandHandler('gp', getPosCommand)
  904.  
  905. function setPosCommand(cmd, x, y, z, r)
  906. -- Handle setpos if used like: x, y, z, r or x,y,z,r
  907. local x, y, z, r = string.gsub(x or "", ",", " "), string.gsub(y or "", ",", " "), string.gsub(z or "", ",", " "), string.gsub(r or "", ",", " ")
  908. -- Extra handling for x,y,z,r
  909. if (x and y == "" and not tonumber(x)) then
  910. x, y, z, r = unpack(split(x, " "))
  911. end
  912.  
  913. local px, py, pz = getElementPosition(g_Me)
  914. local pr = getPedRotation(g_Me)
  915.  
  916. -- If somebody doesn't provide all XYZ explain that we will use their current X Y or Z.
  917. local message = ""
  918. if (not tonumber(x)) then
  919. message = "X "
  920. end
  921. if (not tonumber(y)) then
  922. message = message.."Y "
  923. end
  924. if (not tonumber(z)) then
  925. message = message.."Z "
  926. end
  927. if (message ~= "") then
  928. outputChatBox(message.."arguments were not provided. Using your current "..message.."values instead.", 255, 255, 0)
  929. end
  930.  
  931. setPlayerPosition(tonumber(x) or px, tonumber(y) or py, tonumber(z) or pz)
  932. if (isPedInVehicle(g_Me)) then
  933. local vehicle = getPedOccupiedVehicle(g_Me)
  934. if (vehicle and isElement(vehicle) and getVehicleController(vehicle) == g_Me) then
  935. setElementRotation(vehicle, 0, 0, tonumber(r) or pr)
  936. end
  937. else
  938. setPedRotation(g_Me, tonumber(r) or pr)
  939. end
  940. end
  941. addCommandHandler('setpos', setPosCommand)
  942. addCommandHandler('sp', setPosCommand)
  943.  
  944. ---------------------------
  945. -- Spawn map window
  946. ---------------------------
  947. function warpMapInit()
  948. addEventHandler('onClientRender', g_Root, updatePlayerBlips)
  949. end
  950.  
  951. function spawnMapDoubleClick(relX, relY)
  952. setPlayerPosition(relX*6000 - 3000, 3000 - relY*6000, 0)
  953. closeWindow(wndSpawnMap)
  954. end
  955.  
  956. function closeSpawnMap()
  957. showCursor(false)
  958. removeEventHandler('onClientRender', g_Root, updatePlayerBlips)
  959. for elem,data in pairs(g_PlayerData) do
  960. for i,name in ipairs({'mapBlip', 'mapLabelShadow', 'mapLabel'}) do
  961. if data.gui[name] then
  962. destroyElement(data.gui[name])
  963. data.gui[name] = nil
  964. end
  965. end
  966. end
  967. end
  968.  
  969. wndSpawnMap = {
  970. 'wnd',
  971. text = 'Select spawn position',
  972. width = g_MapSide + 20,
  973. controls = {
  974. {'img', id='map', src='map.png', width=g_MapSide, height=g_MapSide, ondoubleclick=spawnMapDoubleClick},
  975. {'lbl', text='Welcome to freeroam. Double click a location on the map to spawn.', width=g_MapSide-60, align='center'},
  976. {'btn', id='close', closeswindow=true}
  977. },
  978. oncreate = warpMapInit,
  979. onclose = closeSpawnMap
  980. }
  981.  
  982. ---------------------------
  983. -- Interior window
  984. ---------------------------
  985.  
  986. local function setPositionAfterInterior(x,y,z)
  987. setPlayerPosition(x,y,z)
  988. setCameraTarget(g_Me)
  989. fadeCamera(true,1)
  990. end
  991.  
  992. function setPlayerInterior(x,y,z,i)
  993. setCameraMatrix(x,y,z)
  994. setCameraInterior(i)
  995. server.setElementInterior(g_Me, i)
  996. setTimer(setPositionAfterInterior,1000,1,x,y,z)
  997. end
  998.  
  999. function setInterior(leaf)
  1000. local vehicle = getPedOccupiedVehicle(g_Me)
  1001. if vehicle and getVehicleController (vehicle) ~= g_Me then
  1002. outputChatBox ("* Only the driver may set interior/dimension", 255, 0, 0)
  1003. return
  1004. end
  1005. if vehicle then
  1006. server.setElementInterior(vehicle, leaf.world)
  1007. for i=0,getVehicleMaxPassengers(vehicle) do
  1008. local player = getVehicleOccupant(vehicle, i)
  1009. if player and player ~= g_Me then
  1010. server.setElementInterior(player, leaf.world)
  1011. server.setCameraInterior(player, leaf.world)
  1012. end
  1013. end
  1014. end
  1015. fadeCamera(false,1)
  1016. setTimer(setPlayerInterior,1000,1,leaf.posX, leaf.posY, leaf.posZ, leaf.world)
  1017. closeWindow(wndSetInterior)
  1018. end
  1019.  
  1020. wndSetInterior = {
  1021. 'wnd',
  1022. text = 'Set interior',
  1023. width = 250,
  1024. controls = {
  1025. {
  1026. 'lst',
  1027. id='interiors',
  1028. width=230,
  1029. height=300,
  1030. columns={
  1031. {text='Interior', attr='name'}
  1032. },
  1033. rows={xml='interiors.xml', attrs={'name', 'posX', 'posY', 'posZ', 'world'}},
  1034. onitemdoubleclick=setInterior
  1035. },
  1036. {'btn', id='close', closeswindow=true}
  1037. }
  1038. }
  1039.  
  1040. ---------------------------
  1041. -- Create vehicle window
  1042. ---------------------------
  1043. function createSelectedVehicle(leaf)
  1044. if not leaf then
  1045. leaf = getSelectedGridListLeaf(wndCreateVehicle, 'vehicles')
  1046. if not leaf then
  1047. return
  1048. end
  1049. end
  1050. server.giveMeVehicles(leaf.id)
  1051. end
  1052.  
  1053. wndCreateVehicle = {
  1054. 'wnd',
  1055. text = 'Create vehicle',
  1056. width = 300,
  1057. controls = {
  1058. {
  1059. 'lst',
  1060. id='vehicles',
  1061. width=280,
  1062. height=340,
  1063. columns={
  1064. {text='Vehicle', attr='name'}
  1065. },
  1066. rows={xml='vehicles.xml', attrs={'id', 'name'}},
  1067. onitemdoubleclick=createSelectedVehicle
  1068. },
  1069. {'btn', id='create', onclick=createSelectedVehicle},
  1070. {'btn', id='close', closeswindow=true}
  1071. }
  1072. }
  1073.  
  1074. function createVehicleCommand(cmd, ...)
  1075. if isCommandOnCD(cmd) then return end
  1076. local vehID
  1077. local vehiclesToCreate = {}
  1078. local args = { ... }
  1079. for i,v in ipairs(args) do
  1080. vehID = tonumber(v)
  1081. if not vehID then
  1082. vehID = getVehicleModelFromName(v)
  1083. end
  1084. if vehID then
  1085. table.insert(vehiclesToCreate, math.floor(vehID))
  1086. end
  1087. end
  1088. server.giveMeVehicles(vehiclesToCreate)
  1089. end
  1090. addCommandHandler('createvehicle', createVehicleCommand)
  1091. addCommandHandler('cv', createVehicleCommand)
  1092.  
  1093. ---------------------------
  1094. -- Repair vehicle
  1095. ---------------------------
  1096. function repairVehicle()
  1097. local vehicle = getPedOccupiedVehicle(g_Me)
  1098. if vehicle then
  1099. server.fixVehicle(vehicle)
  1100. end
  1101. end
  1102.  
  1103. addCommandHandler('repair', repairVehicle)
  1104. addCommandHandler('rp', repairVehicle)
  1105.  
  1106. ---------------------------
  1107. -- Flip vehicle
  1108. ---------------------------
  1109. function flipVehicle()
  1110. local vehicle = getPedOccupiedVehicle(g_Me)
  1111. if vehicle then
  1112. local rX, rY, rZ = getElementRotation(vehicle)
  1113. server['set' .. 'VehicleRotation'](vehicle, 0, 0, (rX > 90 and rX < 270) and (rZ + 180) or rZ)
  1114. end
  1115. end
  1116.  
  1117. addCommandHandler('flip', flipVehicle)
  1118. addCommandHandler('f', flipVehicle)
  1119.  
  1120. ---------------------------
  1121. -- Vehicle upgrades
  1122. ---------------------------
  1123. function upgradesInit()
  1124. local vehicle = getPedOccupiedVehicle(g_Me)
  1125. if not vehicle then
  1126. errMsg('Please enter a vehicle to change the upgrades of.')
  1127. closeWindow(wndUpgrades)
  1128. return
  1129. end
  1130. local installedUpgrades = getVehicleUpgrades(vehicle)
  1131. local compatibleUpgrades = {}
  1132. local slotName, group
  1133. for i,upgrade in ipairs(getVehicleCompatibleUpgrades(vehicle)) do
  1134. slotName = getVehicleUpgradeSlotName(upgrade)
  1135. group = table.find(compatibleUpgrades, 'name', slotName)
  1136. if not group then
  1137. group = { 'group', name = slotName, children = {} }
  1138. table.insert(compatibleUpgrades, group)
  1139. else
  1140. group = compatibleUpgrades[group]
  1141. end
  1142. table.insert(group.children, { id = upgrade, installed = table.find(installedUpgrades, upgrade) ~= false })
  1143. end
  1144. table.sort(compatibleUpgrades, function(a, b) return a.name < b.name end)
  1145. bindGridListToTable(wndUpgrades, 'upgradelist', compatibleUpgrades, true)
  1146. end
  1147.  
  1148. function selectUpgrade(leaf)
  1149. setControlText(wndUpgrades, 'addremove', leaf.installed and 'remove' or 'add')
  1150. end
  1151.  
  1152. function addRemoveUpgrade(selUpgrade)
  1153. -- Add or remove selected upgrade
  1154. local vehicle = getPedOccupiedVehicle(g_Me)
  1155. if not vehicle then
  1156. return
  1157. end
  1158.  
  1159. if not selUpgrade then
  1160. selUpgrade = getSelectedGridListLeaf(wndUpgrades, 'upgradelist')
  1161. if not selUpgrade then
  1162. return
  1163. end
  1164. end
  1165.  
  1166. if selUpgrade.installed then
  1167. -- remove upgrade
  1168. selUpgrade.installed = false
  1169. setControlText(wndUpgrades, 'addremove', 'add')
  1170. server.removeVehicleUpgrade(vehicle, selUpgrade.id)
  1171. else
  1172. -- add upgrade
  1173. local prevUpgradeIndex = table.find(selUpgrade.siblings, 'installed', true)
  1174. if prevUpgradeIndex then
  1175. selUpgrade.siblings[prevUpgradeIndex].installed = false
  1176. end
  1177. selUpgrade.installed = true
  1178. setControlText(wndUpgrades, 'addremove', 'remove')
  1179. server.addVehicleUpgrade(vehicle, selUpgrade.id)
  1180. end
  1181. end
  1182.  
  1183. wndUpgrades = {
  1184. 'wnd',
  1185. text = 'Vehicle upgrades',
  1186. width = 300,
  1187. x = -20,
  1188. y = 0.3,
  1189. controls = {
  1190. {
  1191. 'lst',
  1192. id='upgradelist',
  1193. width=280,
  1194. height=340,
  1195. columns={
  1196. {text='Upgrade', attr='id', width=0.6},
  1197. {text='Installed', attr='installed', width=0.3, enablemodify=true}
  1198. },
  1199. onitemclick=selectUpgrade,
  1200. onitemdoubleclick=addRemoveUpgrade
  1201. },
  1202. {'btn', id='addremove', text='add', width=60, onclick=addRemoveUpgrade},
  1203. {'btn', id='ok', closeswindow=true}
  1204. },
  1205. oncreate = upgradesInit
  1206. }
  1207.  
  1208. function addUpgradeCommand(cmd, upgrade)
  1209. local vehicle = getPedOccupiedVehicle(g_Me)
  1210. if vehicle and upgrade then
  1211. server.addVehicleUpgrade(vehicle, tonumber(upgrade) or 0)
  1212. end
  1213. end
  1214. addCommandHandler('addupgrade', addUpgradeCommand)
  1215. addCommandHandler('au', addUpgradeCommand)
  1216.  
  1217. function removeUpgradeCommand(cmd, upgrade)
  1218. local vehicle = getPedOccupiedVehicle(g_Me)
  1219. if vehicle and upgrade then
  1220. server.removeVehicleUpgrade(vehicle, tonumber(upgrade) or 0)
  1221. end
  1222. end
  1223. addCommandHandler('removeupgrade', removeUpgradeCommand)
  1224. addCommandHandler('ru', removeUpgradeCommand)
  1225.  
  1226. ---------------------------
  1227. -- Toggle lights
  1228. ---------------------------
  1229. function forceLightsOn()
  1230. local vehicle = getPedOccupiedVehicle(g_Me)
  1231. if not vehicle then
  1232. return
  1233. end
  1234. if guiCheckBoxGetSelected(getControl(wndMain, 'lightson')) then
  1235. server.setVehicleOverrideLights(vehicle, 2)
  1236. guiCheckBoxSetSelected(getControl(wndMain, 'lightsoff'), false)
  1237. else
  1238. server.setVehicleOverrideLights(vehicle, 0)
  1239. end
  1240. end
  1241.  
  1242. function forceLightsOff()
  1243. local vehicle = getPedOccupiedVehicle(g_Me)
  1244. if not vehicle then
  1245. return
  1246. end
  1247. if guiCheckBoxGetSelected(getControl(wndMain, 'lightsoff')) then
  1248. server.setVehicleOverrideLights(vehicle, 1)
  1249. guiCheckBoxSetSelected(getControl(wndMain, 'lightson'), false)
  1250. else
  1251. server.setVehicleOverrideLights(vehicle, 0)
  1252. end
  1253. end
  1254.  
  1255.  
  1256. ---------------------------
  1257. -- Color
  1258. ---------------------------
  1259.  
  1260. function setColorCommand(cmd, ...)
  1261. local vehicle = getPedOccupiedVehicle(g_Me)
  1262. if not vehicle then
  1263. return
  1264. end
  1265. local colors = { getVehicleColor(vehicle) }
  1266. local args = { ... }
  1267. for i=1,12 do
  1268. colors[i] = args[i] and tonumber(args[i]) or colors[i]
  1269. end
  1270. server.setVehicleColor(vehicle, unpack(colors))
  1271. end
  1272. addCommandHandler('color', setColorCommand)
  1273. addCommandHandler('cl', setColorCommand)
  1274.  
  1275. function openColorPicker()
  1276. editingVehicle = getPedOccupiedVehicle(localPlayer)
  1277. if (editingVehicle) then
  1278. colorPicker.openSelect(colors)
  1279. end
  1280. end
  1281.  
  1282. function closedColorPicker()
  1283. local r1, g1, b1, r2, g2, b2, r3, g3, b3, r4, g4, b4 = getVehicleColor(editingVehicle, true)
  1284. server.setVehicleColor(editingVehicle, r1, g1, b1, r2, g2, b2, r3, g3, b3, r4, g4, b4)
  1285. local r, g, b = getVehicleHeadLightColor(editingVehicle)
  1286. server.setVehicleHeadLightColor(editingVehicle, r, g, b)
  1287. editingVehicle = nil
  1288. end
  1289.  
  1290. function updateColor()
  1291. if (not colorPicker.isSelectOpen) then return end
  1292. local r, g, b = colorPicker.updateTempColors()
  1293. if (editingVehicle and isElement(editingVehicle)) then
  1294. local r1, g1, b1, r2, g2, b2, r3, g3, b3, r4, g4, b4 = getVehicleColor(editingVehicle, true)
  1295. if (guiCheckBoxGetSelected(checkColor1)) then
  1296. r1, g1, b1 = r, g, b
  1297. end
  1298. if (guiCheckBoxGetSelected(checkColor2)) then
  1299. r2, g2, b2 = r, g, b
  1300. end
  1301. if (guiCheckBoxGetSelected(checkColor3)) then
  1302. r3, g3, b3 = r, g, b
  1303. end
  1304. if (guiCheckBoxGetSelected(checkColor4)) then
  1305. r4, g4, b4 = r, g, b
  1306. end
  1307. if (guiCheckBoxGetSelected(checkColor5)) then
  1308. setVehicleHeadLightColor(editingVehicle, r, g, b)
  1309. end
  1310. setVehicleColor(editingVehicle, r1, g1, b1, r2, g2, b2, r3, g3, b3, r4, g4, b4)
  1311. end
  1312. end
  1313. addEventHandler("onClientRender", root, updateColor)
  1314.  
  1315. ---------------------------
  1316. -- Paintjob
  1317. ---------------------------
  1318.  
  1319. function paintjobInit()
  1320. local vehicle = getPedOccupiedVehicle(g_Me)
  1321. if not vehicle then
  1322. errMsg('You need to be in a car to change its paintjob.')
  1323. closeWindow(wndPaintjob)
  1324. return
  1325. end
  1326. local paint = getVehiclePaintjob(vehicle)
  1327. if paint then
  1328. guiGridListSetSelectedItem(getControl(wndPaintjob, 'paintjoblist'), paint+1, 1)
  1329. end
  1330. end
  1331.  
  1332. function applyPaintjob(paint)
  1333. server.setVehiclePaintjob(getPedOccupiedVehicle(g_Me), paint.id)
  1334. end
  1335.  
  1336. wndPaintjob = {
  1337. 'wnd',
  1338. text = 'Car paintjob',
  1339. width = 220,
  1340. x = -20,
  1341. y = 0.3,
  1342. controls = {
  1343. {
  1344. 'lst',
  1345. id='paintjoblist',
  1346. width=200,
  1347. height=130,
  1348. columns={
  1349. {text='Paintjob ID', attr='id'}
  1350. },
  1351. rows={
  1352. {id=0},
  1353. {id=1},
  1354. {id=2},
  1355. {id=3}
  1356. },
  1357. onitemclick=applyPaintjob,
  1358. ondoubleclick=function() closeWindow(wndPaintjob) end
  1359. },
  1360. {'btn', id='close', closeswindow=true},
  1361. },
  1362. oncreate = paintjobInit
  1363. }
  1364.  
  1365. function setPaintjobCommand(cmd, paint)
  1366. local vehicle = getPedOccupiedVehicle(g_Me)
  1367. paint = paint and tonumber(paint)
  1368. if not paint or not vehicle then
  1369. return
  1370. end
  1371. server.setVehiclePaintjob(vehicle, paint)
  1372. end
  1373. addCommandHandler('paintjob', setPaintjobCommand)
  1374. addCommandHandler('pj', setPaintjobCommand)
  1375.  
  1376. ---------------------------
  1377. -- Time
  1378. ---------------------------
  1379. function timeInit()
  1380. local hours, minutes = getTime()
  1381. setControlNumbers(wndTime, { hours = hours, minutes = minutes })
  1382. end
  1383.  
  1384. function selectTime(leaf)
  1385. setControlNumbers(wndTime, { hours = leaf.h, minutes = leaf.m })
  1386. end
  1387.  
  1388. function applyTime()
  1389. local hours, minutes = getControlNumbers(wndTime, { 'hours', 'minutes' })
  1390. server.setTime(hours, minutes)
  1391. closeWindow(wndTime)
  1392. end
  1393.  
  1394. wndTime = {
  1395. 'wnd',
  1396. text = 'Set time',
  1397. width = 220,
  1398. controls = {
  1399. {
  1400. 'lst',
  1401. id='timelist',
  1402. width=200,
  1403. height=150,
  1404. columns={
  1405. {text='Time', attr='name'}
  1406. },
  1407. rows={
  1408. {name='Midnight', h=0, m=0},
  1409. {name='Dawn', h=5, m=0},
  1410. {name='Morning', h=9, m=0},
  1411. {name='Noon', h=12, m=0},
  1412. {name='Afternoon', h=15, m=0},
  1413. {name='Evening', h=20, m=0},
  1414. {name='Night', h=22, m=0}
  1415. },
  1416. onitemclick=selectTime,
  1417. ondoubleclick=applyTime
  1418. },
  1419. {'txt', id='hours', text='', width=40},
  1420. {'lbl', text=':'},
  1421. {'txt', id='minutes', text='', width=40},
  1422. {'btn', id='ok', onclick=applyTime},
  1423. {'btn', id='cancel', closeswindow=true}
  1424. },
  1425. oncreate = timeInit
  1426. }
  1427.  
  1428. function setTimeCommand(cmd, hours, minutes)
  1429. if not hours then
  1430. return
  1431. end
  1432. local curHours, curMinutes = getTime()
  1433. hours = tonumber(hours) or curHours
  1434. minutes = minutes and tonumber(minutes) or curMinutes
  1435. setTime(hours, minutes)
  1436. end
  1437. addCommandHandler('settime', setTimeCommand)
  1438. addCommandHandler('st', setTimeCommand)
  1439.  
  1440. function toggleFreezeTime()
  1441. local state = guiCheckBoxGetSelected(getControl(wndMain, 'freezetime'))
  1442. guiCheckBoxSetSelected(getControl(wndMain, 'freezetime'), not state)
  1443. server.setTimeFrozen(state)
  1444. end
  1445.  
  1446. function setTimeFrozen(state, h, m, w)
  1447. guiCheckBoxSetSelected(getControl(wndMain, 'freezetime'), state)
  1448. if state then
  1449. if not g_TimeFreezeTimer then
  1450. g_TimeFreezeTimer = setTimer(function() setTime(h, m) setWeather(w) end, 5000, 0)
  1451. setMinuteDuration(9001)
  1452. end
  1453. else
  1454. if g_TimeFreezeTimer then
  1455. killTimer(g_TimeFreezeTimer)
  1456. g_TimeFreezeTimer = nil
  1457. end
  1458. setMinuteDuration(1000)
  1459. end
  1460. end
  1461.  
  1462. ---------------------------
  1463. -- Weather
  1464. ---------------------------
  1465. function applyWeather(leaf)
  1466. if not leaf then
  1467. leaf = getSelectedGridListLeaf(wndWeather, 'weatherlist')
  1468. if not leaf then
  1469. return
  1470. end
  1471. end
  1472. server.setWeather(leaf.id)
  1473. closeWindow(wndWeather)
  1474. end
  1475.  
  1476. wndWeather = {
  1477. 'wnd',
  1478. text = 'Set weather',
  1479. width = 250,
  1480. controls = {
  1481. {
  1482. 'lst',
  1483. id='weatherlist',
  1484. width=230,
  1485. height=290,
  1486. columns = {
  1487. {text='Weather type', attr='name'}
  1488. },
  1489. rows={xml='weather.xml', attrs={'id', 'name'}},
  1490. onitemdoubleclick=applyWeather
  1491. },
  1492. {'btn', id='ok', onclick=applyWeather},
  1493. {'btn', id='cancel', closeswindow=true}
  1494. }
  1495. }
  1496.  
  1497. function setWeatherCommand(cmd, weather)
  1498. weather = weather and tonumber(weather)
  1499. if weather then
  1500. setWeather(weather)
  1501. end
  1502. end
  1503. addCommandHandler('setweather', setWeatherCommand)
  1504. addCommandHandler('sw', setWeatherCommand)
  1505.  
  1506. ---------------------------
  1507. -- Game speed
  1508. ---------------------------
  1509. function gameSpeedInit()
  1510. setControlNumber(wndGameSpeed, 'speed', getGameSpeed())
  1511. end
  1512.  
  1513. function selectGameSpeed(leaf)
  1514. setControlNumber(wndGameSpeed, 'speed', leaf.id)
  1515. end
  1516.  
  1517. function applyGameSpeed()
  1518. speed = getControlNumber(wndGameSpeed, 'speed')
  1519. if speed then
  1520. server.setMyGameSpeed(speed)
  1521. end
  1522. closeWindow(wndGameSpeed)
  1523. end
  1524.  
  1525. wndGameSpeed = {
  1526. 'wnd',
  1527. text = 'Set game speed',
  1528. width = 220,
  1529. controls = {
  1530. {
  1531. 'lst',
  1532. id='speedlist',
  1533. width=200,
  1534. height=150,
  1535. columns={
  1536. {text='Speed', attr='name'}
  1537. },
  1538. rows={
  1539. {id=3, name='3x'},
  1540. {id=2, name='2x'},
  1541. {id=1, name='1x'},
  1542. {id=0.5, name='0.5x'}
  1543. },
  1544. onitemclick=selectGameSpeed,
  1545. ondoubleclick=applyGameSpeed
  1546. },
  1547. {'txt', id='speed', text='', width=40},
  1548. {'btn', id='ok', onclick=applyGameSpeed},
  1549. {'btn', id='cancel', closeswindow=true}
  1550. },
  1551. oncreate = gameSpeedInit
  1552. }
  1553.  
  1554. function setGameSpeedCommand(cmd, speed)
  1555. speed = speed and tonumber(speed)
  1556. if speed then
  1557. server.setMyGameSpeed(speed)
  1558. end
  1559. end
  1560.  
  1561. addCommandHandler('setgamespeed', setGameSpeedCommand)
  1562. addCommandHandler('speed', setGameSpeedCommand)
  1563.  
  1564. ---------------------------
  1565. -- Main window
  1566. ---------------------------
  1567.  
  1568. function updateGUI(updateVehicle)
  1569. -- update position
  1570. local x, y, z = getElementPosition(g_Me)
  1571. setControlNumbers(wndMain, {xpos=math.ceil(x), ypos=math.ceil(y), zpos=math.ceil(z)})
  1572.  
  1573. -- update jetpack toggle
  1574. guiCheckBoxSetSelected( getControl(wndMain, 'jetpack'), doesPedHaveJetPack(g_Me) )
  1575.  
  1576. if updateVehicle then
  1577. -- update current vehicle
  1578. local vehicle = getPedOccupiedVehicle(g_Me)
  1579. if vehicle and isElement(vehicle) then
  1580. setControlText(wndMain, 'curvehicle', getVehicleName(vehicle))
  1581. else
  1582. setControlText(wndMain, 'curvehicle', 'On foot')
  1583. end
  1584. end
  1585. end
  1586.  
  1587. function mainWndShow()
  1588. if not getPedOccupiedVehicle(g_Me) then
  1589. hideControls(wndMain, 'repair', 'flip', 'upgrades', 'color', 'paintjob', 'lightson', 'lightsoff')
  1590. end
  1591. updateTimer = updateTimer or setTimer(updateGUI, 2000, 0)
  1592. updateGUI(true)
  1593. end
  1594.  
  1595. function mainWndClose()
  1596. killTimer(updateTimer)
  1597. updateTimer = nil
  1598. colorPicker.closeSelect()
  1599. end
  1600.  
  1601. function onEnterVehicle(vehicle)
  1602. setControlText(wndMain, 'curvehicle', getVehicleName(vehicle))
  1603. showControls(wndMain, 'repair', 'flip', 'upgrades', 'color', 'paintjob', 'lightson', 'lightsoff')
  1604. guiCheckBoxSetSelected(getControl(wndMain, 'lightson'), getVehicleOverrideLights(vehicle) == 2)
  1605. guiCheckBoxSetSelected(getControl(wndMain, 'lightsoff'), getVehicleOverrideLights(vehicle) == 1)
  1606. end
  1607.  
  1608. function onExitVehicle(vehicle)
  1609. setControlText(wndMain, 'curvehicle', 'On foot')
  1610. hideControls(wndMain, 'repair', 'flip', 'upgrades', 'color', 'paintjob', 'lightson', 'lightsoff')
  1611. closeWindow(wndUpgrades)
  1612. closeWindow(wndColor)
  1613. end
  1614.  
  1615. function killLocalPlayer()
  1616. server.killPed(g_Me)
  1617. end
  1618.  
  1619. function alphaCommand(command, alpha)
  1620. alpha = alpha and tonumber(alpha)
  1621. if alpha then
  1622. server.setElementAlpha(g_Me, alpha)
  1623. end
  1624. end
  1625. addCommandHandler('alpha', alphaCommand)
  1626. addCommandHandler('ap', alphaCommand)
  1627.  
  1628. addCommandHandler('kill', killLocalPlayer)
  1629.  
  1630. function togglewarptome()
  1631. if ( guiCheckBoxGetSelected( getControl ( wndMain, 'togglewarptme' ) ) == true ) then
  1632. setElementData( g_Me, 'isWarpEnabled', 'false' )
  1633. else
  1634. setElementData( g_Me, 'isWarpEnabled', nil )
  1635. end
  1636. end
  1637.  
  1638. wndMain = {
  1639. 'wnd',
  1640. text = 'FR GUI',
  1641. x = 10,
  1642. y = 150,
  1643. width = 280,
  1644. controls = {
  1645. {'lbl', text='Local player'},
  1646. {'br'},
  1647. {'btn', id='kill', onclick=killLocalPlayer},
  1648. {'btn', id='skin', window=wndSkin},
  1649. {'btn', id='anim', window=wndAnim},
  1650. {'btn', id='weapon', window=wndWeapon},
  1651. {'btn', id='clothes', window=wndClothes},
  1652. {'btn', id='playergrav', text='grav', window=wndGravity},
  1653. {'btn', id='warp', window=wndWarp},
  1654. {'btn', id='stats', window=wndStats},
  1655. {'btn', id='bookmarks', window=wndBookmarks},
  1656. {'br'},
  1657. {'chk', id='jetpack', onclick=toggleJetPack},
  1658. {'chk', id='falloff', text='fall off bike', onclick=toggleFallOffBike},
  1659. {'chk', id='togglewarptme', text='Disable Warping', onclick=togglewarptome, width=1000, height = 20},
  1660. {'br'},
  1661.  
  1662. {'lbl', text='Pos:'},
  1663. {'lbl', id='xpos', text='x', width=45},
  1664. {'lbl', id='ypos', text='y', width=45},
  1665. {'lbl', id='zpos', text='z', width=45},
  1666. {'btn', id='setpos', text='map', window=wndSetPos},
  1667. {'btn', id='setinterior', text='int', window=wndSetInterior},
  1668. {'br'},
  1669. {'br'},
  1670.  
  1671. {'lbl', text='Vehicles'},
  1672. {'br'},
  1673. {'lbl', text='Current:'},
  1674. {'lbl', id='curvehicle'},
  1675. {'br'},
  1676. {'btn', id='createvehicle', window=wndCreateVehicle, text='create'},
  1677. {'btn', id='repair', onclick=repairVehicle},
  1678. {'btn', id='flip', onclick=flipVehicle},
  1679. {'btn', id='upgrades', window=wndUpgrades},
  1680. {'btn', id='color', onclick=openColorPicker},
  1681. {'btn', id='paintjob', window=wndPaintjob},
  1682. {'br'},
  1683. {'chk', id='lightson', text='Lights on', onclick=forceLightsOn},
  1684. {'chk', id='lightsoff', text='Lights off', onclick=forceLightsOff},
  1685. {'br'},
  1686. {'br'},
  1687.  
  1688. {'lbl', text='Environment'},
  1689. {'br'},
  1690. {'btn', id='time', window=wndTime},
  1691. {'chk', id='freezetime', text='freeze', onclick=toggleFreezeTime},
  1692. {'btn', id='weather', window=wndWeather},
  1693. {'btn', id='speed', window=wndGameSpeed}
  1694. },
  1695. oncreate = mainWndShow,
  1696. onclose = mainWndClose
  1697. }
  1698.  
  1699. function errMsg(msg)
  1700. outputChatBox(msg, 255, 0, 0)
  1701. end
  1702.  
  1703. addEventHandler('onClientResourceStart', g_ResRoot,
  1704. function()
  1705. fadeCamera(true)
  1706. setTimer(getPlayers, 1000, 1)
  1707.  
  1708. bindKey('f1', 'down', toggleFRWindow)
  1709. createWindow(wndMain)
  1710. hideAllWindows()
  1711. guiCheckBoxSetSelected(getControl(wndMain, 'jetpack'), doesPedHaveJetPack(g_Me))
  1712. guiCheckBoxSetSelected(getControl(wndMain, 'falloff'), canPedBeKnockedOffBike(g_Me))
  1713. setJetpackMaxHeight ( 9001 )
  1714.  
  1715. triggerServerEvent('onLoadedAtClient', g_ResRoot)
  1716. end
  1717. )
  1718.  
  1719. function showWelcomeMap()
  1720. createWindow(wndSpawnMap)
  1721. showCursor(true)
  1722. end
  1723.  
  1724. function showMap()
  1725. createWindow(wndSetPos)
  1726. showCursor(true)
  1727. end
  1728.  
  1729. function toggleFRWindow()
  1730. if isWindowOpen(wndMain) then
  1731. showCursor(false)
  1732. hideAllWindows()
  1733. colorPicker.closeSelect()
  1734. else
  1735. showCursor(true)
  1736. showAllWindows()
  1737. end
  1738. end
  1739.  
  1740. addCommandHandler('fr', toggleFRWindow)
  1741.  
  1742. function getPlayers()
  1743. g_PlayerData = {}
  1744. table.each(getElementsByType('player'), joinHandler)
  1745. end
  1746.  
  1747. function joinHandler(player)
  1748. if (not g_PlayerData) then return end
  1749. g_PlayerData[player or source] = { name = getPlayerName(player or source), gui = {} }
  1750. end
  1751. addEventHandler('onClientPlayerJoin', g_Root, joinHandler)
  1752.  
  1753. addEventHandler('onClientPlayerQuit', g_Root,
  1754. function()
  1755. if (not g_PlayerData) then return end
  1756. table.each(g_PlayerData[source].gui, destroyElement)
  1757. g_PlayerData[source] = nil
  1758. end
  1759. )
  1760.  
  1761. addEventHandler('onClientPlayerWasted', g_Me,
  1762. function()
  1763. onExitVehicle(g_Me)
  1764. end
  1765. )
  1766.  
  1767. addEventHandler('onClientPlayerVehicleEnter', g_Me, onEnterVehicle)
  1768. addEventHandler('onClientPlayerVehicleExit', g_Me, onExitVehicle)
  1769.  
  1770. addEventHandler('onClientResourceStop', g_ResRoot,
  1771. function()
  1772. showCursor(false)
  1773. setPedAnimation(g_Me, false)
  1774. end
  1775. )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement