Guest User

Untitled

a guest
Jul 22nd, 2019
52
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. if not vRP.modules.police then return end
  2.  
  3. local lang = vRP.lang
  4. local htmlEntities = module("vrp", "lib/htmlEntities")
  5.  
  6. -- this module define some police tools and functions
  7. local Police = class("Police", vRP.Extension)
  8.  
  9. -- SUBCLASS
  10.  
  11. Police.User = class("User")
  12.  
  13. -- insert a police record (will do a save)
  14. --- record: text for one line
  15. function Police.User:insertPoliceRecord(record)
  16. table.insert(self.police_records, record)
  17. self:savePoliceRecords()
  18. end
  19.  
  20. function Police.User:savePoliceRecords()
  21. -- save records
  22. vRP:setCData(self.cid, "vRP:police:records", msgpack.pack(self.police_records))
  23. end
  24.  
  25. -- PRIVATE METHODS
  26.  
  27. -- menu: police_pc records
  28. local function menu_police_pc_records(self)
  29. local function m_add(menu)
  30. local user = menu.user
  31. local tuser = menu.data.tuser
  32.  
  33. local record = user:prompt(lang.police.pc.records.add.prompt(), "")
  34. if record and string.len(record) > 0 then
  35. tuser:insertPoliceRecord(record)
  36. user:actualizeMenu()
  37. else
  38. vRP.EXT.Base.remote._notify(user.source,lang.common.invalid_value())
  39. end
  40. end
  41.  
  42. local function m_delete(menu)
  43. local user = menu.user
  44. local tuser = menu.data.tuser
  45.  
  46. local index = parseInt(user:prompt(lang.police.pc.records.delete.prompt(), ""))
  47. if index > 0 and index <= #tuser.police_records then
  48. table.remove(tuser.police_records, index)
  49. tuser:savePoliceRecords()
  50.  
  51. user:actualizeMenu()
  52. else
  53. vRP.EXT.Base.remote._notify(user.source,lang.common.invalid_value())
  54. end
  55. end
  56.  
  57. vRP.EXT.GUI:registerMenuBuilder("police_pc.records", function(menu)
  58. menu.title = lang.police.pc.records.title()
  59. menu.css.header_color = "rgba(0,125,255,0.75)"
  60.  
  61. local tuser = menu.data.tuser
  62.  
  63. -- add records
  64. for i, record in ipairs(tuser.police_records) do
  65. menu:addOption("#"..i, nil, htmlEntities.encode(record))
  66. end
  67.  
  68. menu:addOption(lang.police.pc.records.add.title(), m_add)
  69. menu:addOption(lang.police.pc.records.delete.title(), m_delete)
  70. end)
  71. end
  72.  
  73. -- menu: police pc
  74. local function menu_police_pc(self)
  75. -- search identity by registration
  76. local function m_searchreg(menu)
  77. local user = menu.user
  78.  
  79.  
  80. local reg = user:prompt(lang.police.pc.searchreg.prompt(),"")
  81. local cid = vRP.EXT.Identity:getByRegistration(reg)
  82. if cid then
  83. local identity = vRP.EXT.Identity:getIdentity(cid)
  84. if identity then
  85. local smenu = user:openMenu("identity", {cid = cid})
  86. menu:listen("remove", function(menu) menu.user:closeMenu(smenu) end)
  87. else
  88. vRP.EXT.Base.remote._notify(user.source,lang.common.not_found())
  89. end
  90. else
  91. vRP.EXT.Base.remote._notify(user.source,lang.common.not_found())
  92. end
  93. end
  94.  
  95. -- show police records by registration
  96. local function m_police_records(menu)
  97. local user = menu.user
  98.  
  99. local reg = user:prompt(lang.police.pc.searchreg.prompt(),"")
  100. local tuser
  101. local cid = vRP.EXT.Identity:getByRegistration(reg)
  102. if cid then tuser = vRP.users_by_cid[cid] end
  103.  
  104. if tuser then
  105. local smenu = user:openMenu("police_pc.records", {tuser = tuser})
  106. menu:listen("remove", function(menu) menu.user:closeMenu(smenu) end)
  107. else
  108. vRP.EXT.Base.remote._notify(user.source,lang.common.not_found())
  109. end
  110. end
  111.  
  112. -- close business of an arrested owner
  113. local function m_closebusiness(menu)
  114. local user = menu.user
  115.  
  116. local nuser
  117. local nplayer = vRP.EXT.Base.remote.getNearestPlayer(user.source,5)
  118. if nplayer then nuser = vRP.users_by_source[nplayer] end
  119.  
  120. if nuser then
  121. local identity = nuser.identity
  122.  
  123. local business = vRP.EXT.Business:getBusiness(nuser.cid)
  124.  
  125. if identity and business then
  126. if user:request(lang.police.pc.closebusiness.request({identity.name,identity.firstname,business.name}),15) then
  127. vRP.EXT.Business:closeBusiness(nuser.cid)
  128. vRP.EXT.Base.remote._notify(user.source,lang.police.pc.closebusiness.closed())
  129. end
  130. else
  131. vRP.EXT.Base.remote._notify(user.source,lang.common.no_player_near())
  132. end
  133. else
  134. vRP.EXT.Base.remote._notify(user.source,lang.common.no_player_near())
  135. end
  136. end
  137.  
  138. -- track vehicle
  139. local function m_trackveh(menu)
  140. local user = menu.user
  141.  
  142. local reg = user:prompt(lang.police.pc.trackveh.prompt_reg(),"")
  143.  
  144. local tuser
  145. local cid = vRP.EXT.Identity:getByRegistration(reg)
  146. if cid then tuser = vRP.users_by_cid[cid] end
  147.  
  148. if tuser then
  149. local note = user:prompt(lang.police.pc.trackveh.prompt_note(),"")
  150. -- begin veh tracking
  151. vRP.EXT.Base.remote._notify(user.source,lang.police.pc.trackveh.tracking())
  152. local seconds = math.random(self.cfg.trackveh.min_time,self.cfg.trackveh.max_time)
  153.  
  154. SetTimeout(seconds*1000,function()
  155. local ok,x,y,z = vRP.EXT.Garage.remote.getAnyOwnedVehiclePosition(tuser.source)
  156. if ok then -- track success
  157. vRP.EXT.Phone:sendServiceAlert(nil, self.cfg.trackveh.service,x,y,z,lang.police.pc.trackveh.tracked({reg,note}))
  158. else
  159. vRP.EXT.Base.remote._notify(user.source,lang.police.pc.trackveh.track_failed({reg,note})) -- failed
  160. end
  161. end)
  162. else
  163. vRP.EXT.Base.remote._notify(user.source,lang.common.not_found())
  164. end
  165. end
  166.  
  167. vRP.EXT.GUI:registerMenuBuilder("police_pc", function(menu)
  168. menu.title = lang.police.pc.title()
  169. menu.css.header_color = "rgba(0,125,255,0.75)"
  170.  
  171. menu:addOption(lang.police.pc.searchreg.title(), m_searchreg, lang.police.pc.searchreg.description())
  172. menu:addOption(lang.police.pc.trackveh.title(), m_trackveh, lang.police.pc.trackveh.description())
  173. menu:addOption(lang.police.pc.records.title(), m_police_records, lang.police.pc.records.description())
  174. menu:addOption(lang.police.pc.closebusiness.title(), m_closebusiness, lang.police.pc.closebusiness.description())
  175. end)
  176. end
  177.  
  178. -- menu: police fine
  179. local function menu_police_fine(self)
  180. local function m_fine(menu, name)
  181. local user = menu.user
  182. local tuser = menu.data.tuser
  183.  
  184. local amount = self.cfg.fines[name]
  185. if amount then
  186. if tuser:tryFullPayment(amount) then
  187. tuser:insertPoliceRecord(lang.police.menu.fine.record({name,amount}))
  188. vRP.EXT.Base.remote._notify(user.source,lang.police.menu.fine.fined({name,amount}))
  189. vRP.EXT.Base.remote._notify(tuser.source,lang.police.menu.fine.notify_fined({name,amount}))
  190.  
  191. user:closeMenu(menu)
  192. else
  193. vRP.EXT.Base.remote._notify(user.source,lang.money.not_enough())
  194. end
  195. end
  196. end
  197.  
  198. vRP.EXT.GUI:registerMenuBuilder("police.fine", function(menu)
  199. menu.title = lang.police.menu.fine.title()
  200. menu.css.header_color = "rgba(0,125,255,0.75)"
  201.  
  202. local money = menu.data.money
  203.  
  204. for _,fine in ipairs(self.sorted_fines) do -- add fines in function of money available
  205. local name, amount = fine[1], fine[2]
  206.  
  207. if amount <= money then
  208. menu:addOption(name, m_fine, amount, name)
  209. end
  210. end
  211. end)
  212. end
  213.  
  214. -- menu: police check
  215. local function menu_police_check(self)
  216. vRP.EXT.GUI:registerMenuBuilder("police.check", function(menu)
  217. menu.title = lang.police.menu.check.title()
  218. menu.css.header_color = "rgba(0,125,255,0.75)"
  219.  
  220. local tuser = menu.data.tuser
  221.  
  222. local wallet = tuser:getWallet()
  223. local items = clone(tuser:getInventory())
  224.  
  225. -- add worn weapons to items
  226. local weapons = vRP.EXT.PlayerState.remote.getWeapons(tuser.source)
  227. for id, weapon in pairs(weapons) do
  228. local b_id = "wbody|"..id
  229. local b_amount = items[b_id] or 0
  230. items[b_id] = b_amount+1
  231.  
  232. if weapon.ammo > 0 then
  233. local a_id = "wammo|"..id
  234. local a_amount = items[a_id] or 0
  235. items[a_id] = a_amount+weapon.ammo
  236. end
  237. end
  238.  
  239. -- general info
  240. menu:addOption(lang.police.menu.check.info.title(), nil, lang.police.menu.check.info.description({wallet}))
  241.  
  242. -- items
  243. for fullid, amount in pairs(items) do
  244. local citem = vRP.EXT.Inventory:computeItem(fullid)
  245. if citem then
  246. menu:addOption(htmlEntities.encode(citem.name), nil, lang.inventory.iteminfo({amount,citem.description, string.format("%.2f",citem.weight)}))
  247. end
  248. end
  249. end)
  250. end
  251.  
  252. -- menu: police
  253. local function menu_police(self)
  254. local function m_handcuff(menu)
  255. local user = menu.user
  256.  
  257. local nuser
  258. local nplayer = vRP.EXT.Base.remote.getNearestPlayer(user.source,10)
  259. if nplayer then nuser = vRP.users_by_source[nplayer] end
  260.  
  261. if nuser then
  262. self.remote._toggleHandcuff(nuser.source)
  263. else
  264. vRP.EXT.Base.remote._notify(user.source,lang.common.no_player_near())
  265. end
  266. end
  267.  
  268. local function m_drag(menu)
  269. local user = menu.user
  270.  
  271. local nuser
  272. local nplayer = vRP.EXT.Base.remote.getNearestPlayer(user.source,10)
  273. if nplayer then nuser = vRP.users_by_source[nplayer] end
  274.  
  275. if nuser then
  276. local followed = self.remote.getFollowedPlayer(nuser.source)
  277. if followed ~= user.source then -- drag
  278. if self.remote.isHandcuffed(nuser.source) then -- check handcuffed
  279. self.remote._followPlayer(nuser.source, user.source)
  280. else
  281. vRP.EXT.Base.remote._notify(user.source,lang.police.not_handcuffed())
  282. end
  283. else -- stop follow
  284. self.remote._followPlayer(nuser.source)
  285. end
  286. else
  287. vRP.EXT.Base.remote._notify(user.source,lang.common.no_player_near())
  288. end
  289. end
  290.  
  291. local function m_putinveh(menu)
  292. local user = menu.user
  293.  
  294. local nuser
  295. local nplayer = vRP.EXT.Base.remote.getNearestPlayer(user.source,10)
  296. if nplayer then nuser = vRP.users_by_source[nplayer] end
  297.  
  298. if nuser then
  299. if self.remote.isHandcuffed(nuser.source) then -- check handcuffed
  300. self.remote._putInNearestVehicleAsPassenger(nuser.source, 5)
  301. else
  302. vRP.EXT.Base.remote._notify(user.source,lang.police.not_handcuffed())
  303. end
  304. else
  305. vRP.EXT.Base.remote._notify(user.source,lang.common.no_player_near())
  306. end
  307. end
  308.  
  309. local function m_getoutveh(menu)
  310. local user = menu.user
  311.  
  312. local nuser
  313. local nplayer = vRP.EXT.Base.remote.getNearestPlayer(user.source,10)
  314. if nplayer then nuser = vRP.users_by_source[nplayer] end
  315.  
  316. if nuser then
  317. if self.remote.isHandcuffed(nuser.source) then -- check handcuffed
  318. vRP.EXT.Garage.remote._ejectVehicle(nuser.source)
  319. else
  320. vRP.EXT.Base.remote._notify(user.source,lang.police.not_handcuffed())
  321. end
  322. else
  323. vRP.EXT.Base.remote._notify(user.source,lang.common.no_player_near())
  324. end
  325. end
  326.  
  327. local function m_askid(menu)
  328. local user = menu.user
  329.  
  330. local nuser
  331. local nplayer = vRP.EXT.Base.remote.getNearestPlayer(user.source,10)
  332. if nplayer then nuser = vRP.users_by_source[nplayer] end
  333.  
  334. if nuser then
  335. vRP.EXT.Base.remote._notify(user.source,lang.police.menu.askid.asked())
  336. if nuser:request(lang.police.menu.askid.request(),15) then
  337. user:openMenu("identity", {cid = nuser.cid})
  338. else
  339. vRP.EXT.Base.remote._notify(user.source,lang.common.request_refused())
  340. end
  341. else
  342. vRP.EXT.Base.remote._notify(user.source,lang.common.no_player_near())
  343. end
  344. end
  345.  
  346. local function m_check(menu)
  347. local user = menu.user
  348.  
  349. local nuser
  350. local nplayer = vRP.EXT.Base.remote.getNearestPlayer(user.source,5)
  351. if nplayer then nuser = vRP.users_by_source[nplayer] end
  352.  
  353. if nuser then
  354. if self.remote.isHandcuffed(nuser.source) then -- check handcuffed
  355. user:openMenu("police.check", {tuser = nuser})
  356. vRP.EXT.Base.remote._notify(nuser.source,lang.police.menu.check.checked())
  357. else
  358. vRP.EXT.Base.remote._notify(user.source,lang.police.not_handcuffed())
  359. end
  360. else
  361. vRP.EXT.Base.remote._notify(user.source,lang.common.no_player_near())
  362. end
  363. end
  364.  
  365. local function m_seize(menu)
  366. local user = menu.user
  367.  
  368. local nuser
  369. local nplayer = vRP.EXT.Base.remote.getNearestPlayer(user.source,5)
  370. if nplayer then nuser = vRP.users_by_source[nplayer] end
  371.  
  372. if nuser then
  373. if nuser:hasPermission("police.seizable") then
  374. if self.remote.isHandcuffed(nuser.source) then -- check handcuffed
  375. -- weapons
  376. local weapons = vRP.EXT.PlayerState.remote.replaceWeapons(nuser.source, {})
  377.  
  378. for k,v in pairs(weapons) do
  379. -- convert weapons to parametric weapon items
  380. user:tryGiveItem("wbody|"..k, 1)
  381. if v.ammo > 0 then
  382. user:tryGiveItem("wammo|"..k, v.ammo)
  383. end
  384. end
  385.  
  386.  
  387. -- items
  388. local inventory = nuser:getInventory()
  389.  
  390. for _,key in pairs(self.cfg.seizable_items) do -- transfer seizable items
  391. local sub_items = {key} -- single item
  392.  
  393. if string.sub(key,1,1) == "*" then -- seize all parametric items of this id
  394. local id = string.sub(key,2)
  395. sub_items = {}
  396. for fullid in pairs(inventory) do
  397. if splitString(fullid, "|")[1] == id then -- same parametric item
  398. table.insert(sub_items, fullid) -- add full idname
  399. end
  400. end
  401. end
  402.  
  403. for _,fullid in pairs(sub_items) do
  404. local amount = nuser:getItemAmount(fullid)
  405. if amount > 0 then
  406. local citem = vRP.EXT.Inventory:computeItem(fullid)
  407. if citem then -- do transfer
  408. if nuser:tryTakeItem(fullid,amount) then
  409. user:tryGiveItem(fullid,amount)
  410. end
  411. end
  412. end
  413. end
  414. end
  415.  
  416. vRP.EXT.Base.remote._notify(nuser.source,lang.police.menu.seize.seized())
  417. else
  418. vRP.EXT.Base.remote._notify(user.source,lang.police.not_handcuffed())
  419. end
  420. end
  421. else
  422. vRP.EXT.Base.remote._notify(user.source,lang.common.no_player_near())
  423. end
  424. end
  425.  
  426. local function m_jail(menu)
  427. local user = menu.user
  428.  
  429. local nuser
  430. local nplayer = vRP.EXT.Base.remote.getNearestPlayer(user.source,5)
  431. if nplayer then nuser = vRP.users_by_source[nplayer] end
  432.  
  433. if nuser then
  434. if self.remote.isJailed(nuser.source) then
  435. self.remote._unjail(nuser.source)
  436. vRP.EXT.Base.remote._notify(nuser.source,lang.police.menu.jail.notify_unjailed())
  437. vRP.EXT.Base.remote._notify(user.source,lang.police.menu.jail.unjailed())
  438. else -- find the nearest jail
  439. local x,y,z = vRP.EXT.Base.remote.getPosition(nuser.source)
  440. local d_min = 1000
  441. local v_min = nil
  442. for k,v in pairs(self.cfg.jails) do
  443. local dx,dy,dz = x-v[1],y-v[2],z-v[3]
  444. local dist = math.sqrt(dx*dx+dy*dy+dz*dz)
  445.  
  446. if dist <= d_min and dist <= 15 then -- limit the research to 15 meters
  447. d_min = dist
  448. v_min = v
  449. end
  450.  
  451. -- jail
  452. if v_min then
  453. self.remote._jail(nuser.source,v_min[1],v_min[2],v_min[3],v_min[4])
  454. vRP.EXT.Base.remote._notify(nuser.source,lang.police.menu.jail.notify_jailed())
  455. vRP.EXT.Base.remote._notify(user.source,lang.police.menu.jail.jailed())
  456. else
  457. vRP.EXT.Base.remote._notify(user.source,lang.police.menu.jail.not_found())
  458. end
  459. end
  460. end
  461. else
  462. vRP.EXT.Base.remote._notify(user.source,lang.common.no_player_near())
  463. end
  464. end
  465.  
  466. local function m_fine(menu)
  467. local user = menu.user
  468.  
  469. local nuser
  470. local nplayer = vRP.EXT.Base.remote.getNearestPlayer(user.source,5)
  471. if nplayer then nuser = vRP.users_by_source[nplayer] end
  472.  
  473. if nuser then
  474. local money = nuser:getWallet()+nuser:getBank()
  475. user:openMenu("police.fine", {tuser = nuser, money = money})
  476. else
  477. vRP.EXT.Base.remote._notify(user.source,lang.common.no_player_near())
  478. end
  479. end
  480.  
  481. vRP.EXT.GUI:registerMenuBuilder("police", function(menu)
  482. local user = menu.user
  483. menu.title = lang.police.title()
  484. menu.css.header_color = "rgba(0,125,255,0.75)"
  485.  
  486. if user:hasPermission("police.askid") then
  487. menu:addOption(lang.police.menu.askid.title(), m_askid, lang.police.menu.askid.description())
  488. end
  489.  
  490. if user:hasPermission("police.handcuff") then
  491. menu:addOption(lang.police.menu.handcuff.title(), m_handcuff, lang.police.menu.handcuff.description())
  492. end
  493.  
  494. if user:hasPermission("police.drag") then
  495. menu:addOption(lang.police.menu.drag.title(), m_drag, lang.police.menu.drag.description())
  496. end
  497.  
  498. if user:hasPermission("police.putinveh") then
  499. menu:addOption(lang.police.menu.putinveh.title(), m_putinveh, lang.police.menu.putinveh.description())
  500. end
  501.  
  502. if user:hasPermission("police.getoutveh") then
  503. menu:addOption(lang.police.menu.getoutveh.title(), m_getoutveh, lang.police.menu.getoutveh.description())
  504. end
  505.  
  506. if user:hasPermission("police.check") then
  507. menu:addOption(lang.police.menu.check.title(), m_check, lang.police.menu.check.description())
  508. end
  509.  
  510. if user:hasPermission("police.seize") then
  511. menu:addOption(lang.police.menu.seize.title(), m_seize, lang.police.menu.seize.description())
  512. end
  513.  
  514. if user:hasPermission("police.jail") then
  515. menu:addOption(lang.police.menu.jail.title(), m_jail, lang.police.menu.jail.description())
  516. end
  517.  
  518. if user:hasPermission("police.fine") then
  519. menu:addOption(lang.police.menu.fine.title(), m_fine, lang.police.menu.fine.description())
  520. end
  521. end)
  522. end
  523.  
  524. local function define_items(self)
  525. local function m_bulletproof_vest_wear(menu)
  526. local user = menu.user
  527. local fullid = menu.data.fullid
  528.  
  529. if user:tryTakeItem(fullid, 1) then -- take vest
  530. vRP.EXT.PlayerState.remote._setArmour(user.source, 100)
  531.  
  532. local namount = user:getItemAmount(fullid)
  533. if namount > 0 then
  534. user:actualizeMenu()
  535. else
  536. user:closeMenu(menu)
  537. end
  538. end
  539. end
  540.  
  541. local function i_bulletproof_vest_menu(args, menu)
  542. menu:addOption(lang.item.bulletproof_vest.wear.title(), m_bulletproof_vest_wear)
  543. end
  544.  
  545. vRP.EXT.Inventory:defineItem("bulletproof_vest", lang.item.bulletproof_vest.name(), lang.item.bulletproof_vest.description(), i_bulletproof_vest_menu, 1.5)
  546. end
  547.  
  548. -- targets: map of wanted users
  549. -- listeners: map of user
  550. function listen_wanted(self, targets, listeners)
  551. local Map = vRP.EXT.Map
  552.  
  553. for target in pairs(targets) do
  554. local x,y,z = vRP.EXT.Base.remote.getPosition(target.source)
  555. local ment = clone(self.cfg.wanted.map_entity)
  556. ment[2].player = target.source
  557. ment[2].title = lang.police.wanted({self:getUserWantedLevel(target)})
  558.  
  559. for listener in pairs(listeners) do
  560. Map.remote._setEntity(listener.source, "vRP:police:wanted:"..target.id, ment[1], ment[2])
  561. end
  562. end
  563. end
  564.  
  565. -- targets: map of wanted users
  566. -- listeners: map of user
  567. function unlisten_wanted(self, targets, listeners)
  568. local Map = vRP.EXT.Map
  569.  
  570. for target in pairs(targets) do
  571. for listener in pairs(listeners) do
  572. Map.remote._removeEntity(listener.source, "vRP:police:wanted:"..target.id)
  573. end
  574. end
  575. end
  576.  
  577. -- METHODS
  578.  
  579. function Police:__construct()
  580. vRP.Extension.__construct(self)
  581.  
  582. self.cfg = module("cfg/police")
  583.  
  584. -- sort fines
  585. self.sorted_fines = {}
  586. for name, amount in pairs(self.cfg.fines) do
  587. table.insert(self.sorted_fines, {name, amount})
  588. end
  589. table.sort(self.sorted_fines, function(a,b) return a[2] < b[2] end)
  590.  
  591. self:log(#self.cfg.pcs.." PCs "..#self.cfg.jails.." jails "..#self.sorted_fines.." fines")
  592.  
  593. self.wantedlvl_users = {} -- map of user => wanted level
  594. self.wanted_listeners = {} -- map of user
  595.  
  596. -- items
  597. define_items(self)
  598.  
  599. -- menu
  600. menu_police_pc_records(self)
  601. menu_police_pc(self)
  602. menu_police_fine(self)
  603. menu_police_check(self)
  604. menu_police(self)
  605.  
  606. -- main menu
  607. local function m_police(menu)
  608. menu.user:openMenu("police")
  609. end
  610.  
  611. local function m_store_weapons(menu)
  612. local user = menu.user
  613.  
  614. local weapons = vRP.EXT.PlayerState.remote.replaceWeapons(user.source, {})
  615. for k,v in pairs(weapons) do
  616. -- convert weapons to parametric weapon items
  617. user:tryGiveItem("wbody|"..k, 1)
  618. if v.ammo > 0 then
  619. user:tryGiveItem("wammo|"..k, v.ammo)
  620. end
  621. end
  622. end
  623.  
  624. vRP.EXT.GUI:registerMenuBuilder("main", function(menu)
  625. if menu.user:hasPermission("police.menu") then
  626. menu:addOption(lang.police.title(), m_police)
  627. end
  628.  
  629. if menu.user:hasPermission("player.store_weapons") then
  630. menu:addOption(lang.police.menu.store_weapons.title(), m_store_weapons, lang.police.menu.store_weapons.description())
  631. end
  632. end)
  633.  
  634.  
  635. -- task: wanted listening
  636. local function task_wanted()
  637. local listeners = vRP.EXT.Group:getUsersByPermission("police.wanted")
  638.  
  639. local wanted_listeners = {} -- new wanted listeners
  640. for _,listener in pairs(listeners) do
  641. wanted_listeners[listener] = true
  642. end
  643.  
  644. -- added listeners
  645. local added = {}
  646. for listener in pairs(wanted_listeners) do
  647. if not self.wanted_listeners[listener] then
  648. added[listener] = true
  649. end
  650. end
  651.  
  652. -- deleted listeners
  653. local deleted = {}
  654. for listener in pairs(self.wanted_listeners) do
  655. if not wanted_listeners[listener] then
  656. deleted[listener] = true
  657. end
  658. end
  659.  
  660. self.wanted_listeners = wanted_listeners -- update
  661.  
  662. listen_wanted(self, self.wantedlvl_users, added)
  663. unlisten_wanted(self, self.wantedlvl_users, deleted)
  664.  
  665. SetTimeout(5000, task_wanted)
  666. end
  667.  
  668. async(function()
  669. task_wanted()
  670. end)
  671. end
  672.  
  673. function Police:getUserWantedLevel(user)
  674. return self.wantedlvl_users[user] or 0
  675. end
  676.  
  677. -- EVENT
  678. Police.event = {}
  679.  
  680. function Police.event:characterLoad(user)
  681. -- load records
  682. local sdata = vRP:getCData(user.cid, "vRP:police:records")
  683. user.police_records = (sdata and string.len(sdata) > 0 and msgpack.unpack(sdata) or {})
  684. end
  685.  
  686. function Police.event:playerSpawn(user, first_spawn)
  687. if first_spawn then
  688. local menu
  689. local function enter(user)
  690. if user:hasPermission("police.pc") then
  691. menu = user:openMenu("police_pc")
  692. end
  693. end
  694.  
  695. local function leave(user)
  696. if menu then
  697. user:closeMenu(menu)
  698. end
  699. end
  700.  
  701. -- build police PCs
  702. for k,v in pairs(self.cfg.pcs) do
  703. local x,y,z = table.unpack(v)
  704.  
  705. local ment = clone(self.cfg.pc_map_entity)
  706. ment[2].title = lang.police.pc.title()
  707. ment[2].pos = {x,y,z-1}
  708. vRP.EXT.Map.remote._addEntity(user.source, ment[1], ment[2])
  709.  
  710. user:setArea("vRP:police:pc:"..k,x,y,z,1,1.5,enter,leave)
  711. end
  712. end
  713. end
  714.  
  715. function Police.event:playerLeave(user)
  716. self.wantedlvl_users[user] = nil
  717. unlisten_wanted(self, {[user] = true}, self.wanted_listeners)
  718. end
  719.  
  720. -- TUNNEL
  721. Police.tunnel = {}
  722.  
  723. -- receive wanted level
  724. function Police.tunnel:updateWantedLevel(level)
  725. local user = vRP.users_by_source[source]
  726.  
  727. if user and user:isReady() then
  728. local was_wanted = (self:getUserWantedLevel(user) > 0)
  729. local is_wanted = (level > 0)
  730. local lvl_changed = level ~= self:getUserWantedLevel(user)
  731.  
  732. if lvl_changed then
  733. -- send wanted to listening service
  734. if not was_wanted and is_wanted then -- add to wanted
  735. self.wantedlvl_users[user] = level
  736.  
  737. listen_wanted(self, {[user] = level}, self.wanted_listeners)
  738.  
  739. -- alert
  740. local x,y,z = vRP.EXT.Base.remote.getPosition(user.source)
  741. vRP.EXT.Phone:sendServiceAlert(nil, self.cfg.wanted.service,x,y,z,lang.police.wanted({level}))
  742. elseif was_wanted and not is_wanted then -- remove from wanted
  743. self.wantedlvl_users[user] = nil
  744. unlisten_wanted(self, {[user] = true}, self.wanted_listeners)
  745. elseif is_wanted then -- level changed
  746. self.wantedlvl_users[user] = level
  747. listen_wanted(self, {[user] = level}, self.wanted_listeners)
  748. end
  749. end
  750. end
  751. end
  752.  
  753. vRP:registerExtension(Police)
RAW Paste Data