Advertisement
Guest User

swm_wpn_mgr.script

a guest
Jan 13th, 2014
209
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.75 KB | None | 0 0
  1. --[[ ----------------------------------------------------------------------------------------------
  2. Ïëàòôîðìû: CoP 1.6.2
  3. Îïèñàíèå : Ñêðèïòîâûé ìåíåäæåð îðóæèÿ äëÿ ÍÏÑ
  4. Ïîääåðæêà: 2013 © Shoker Mod
  5. Àâòîðû : Shoker
  6. Âåðñèÿ : 3.0 (01.01.2014) - ýòà âåðñèÿ èñïîëüçóåò äâèæêîâóþ ïðàâêó òèïà îðóæèÿ, äàáû äâèæêîâûé ìåíåäæåð âûáèðàë åãî â ïîñëåäíèþ î÷åðåäü
  7. --]] ----------------------------------------------------------------------------------------------
  8.  
  9. local DIST_MEMORY_TIME = xr_danger.DANGER_INERTION_TIME or 30000 --> Âðåìÿ ïîñëå ïîòåðè âðàãà, êîòîðîå ÍÏÑ åù¸ íå ïðîáóåò ìåíÿòü îðóæèå
  10. local NEXT_UPD_TIME = 3000 --> Èíòåðâàë â ì\ñåê, ÷åðåç êîòîðûé ÍÏÑ ïðîáóåò âûáðàòü ñåáå íîâîå îðóæèå
  11. local NEXT_UPD_TIME_MST = 9000 --> Òîæå ñàìîå, íî âðàã ìîíñòð è îí áëèçêî
  12. local CLS_DISTANCE = 20 --> Äèñòàíöèÿ, êîòîðàÿ ñ÷èòàåòñÿ áëèçêîé
  13. local PST_DISTANCE = 9 --> Äèñòàíöèÿ, íà êîòîðîé ÍÏÑ ëó÷øå ïåðåêëþ÷èòñÿ íà ïèñòîëåò åñëè ïàòðîíû êîí÷àòñÿ à ÍÏÑ âèäèò âðàãà
  14. local SEE_DISTANCE = 6 --> Äèñòàíöèÿ, íà êîòîðîé ñ÷èòàåì ÷òî ÍÏÑ âñåãäà âèäèò âðàãà
  15. local MST_DISTANCE = 5 --> Åñëè ìîíñòðû áëèæå ýòîé äèñòàíöèè òî ñðàçó âçÿòü ïèñòîëåò, åñëè ó íàñ íåòó secondary
  16.  
  17. --[[
  18. Ñóùåñòâóþùèå òèïû îðóæèÿ: (weapon_type)
  19. * none - îðóæèå, êîòîðîå ÍÏÑ íå ìîãóò èñïîëüçîâàòü (ïî äåôîëòó) - îäíàêî åñëè äðóãîãî îðóæèÿ ó íåãî íå áóäåò, ìîæåò è âçÿòü â ðóêè <!>
  20. * pistol - ïèñòîëåòû, èñïîëüçóþòñÿ íà áëèçêîé äèñòàíöèè êîãäà â îñíîâíîì êîí÷èëèñü ïàòðîíû, à âðàã áëèçêî, ìåíÿþòñÿ íà PDW
  21. * pdw - ïèñòîëåòû-ïóëåì¸òû, èñïîëüçóþòñÿ íà áëèçêîé äèñòàíöèè (åñëè íåò äðîáîâèêà), ïðèîðèòåòíåé àâòîìàòîâ
  22. * sniper - ñíàéïåðñêèå âèíòîâêè, èñïîëüçóþòñÿ êîãäà âðàã äàëåêî
  23. * dbarshg - äâóõñòâîëêè, õóæå pdw
  24. * shotgun - äðîáîâèêè, ïðåäïî÷òèòåëüíåé ÷àì pdw äëÿ áëèçêèõ ðàññòîÿíèé
  25. * auto - àâòîìàòè÷åñêèå âèíòîâêè è ò.ä è ò.ï, îñíîâíîå îðóæèå ñðåäíèõ äèñòàíöèé.
  26. * mguns - ïóëåì¸òû
  27. * explosive - âçðûâîîïàñíîå îðóæèå, êîòîðîå ìîæíî èñïîëüçîâàòü òîëüêî èçäàëåêà
  28. * special - îðóæèå ýòîãî òèïà âñåãäà ëó÷øåå, è ÍÏÑ åãî íå ñìåíÿåò
  29. --]]
  30.  
  31.  
  32. local primary_types = { --> Äàëüíèé áîé
  33. auto = 1,
  34. sniper = 2,
  35. mguns = 3,
  36. explosive = 4,
  37. }
  38.  
  39. local secondary_types = { --> Áëèæíèé áîé
  40. dbarshg = 1,
  41. pdw = 2,
  42. shotgun = 3, --> ÷åì áîëüøå öèôðà, òåì áîëüøå ïðèîðèòåò äàííîãî òèïà
  43. }
  44.  
  45. local current_wpn_tbl = {} --> òàáëèöà ãäå õðàíèòñÿ òåêóùèé âûáîð îðóæèÿ è âðåìÿ ñëåäóþùåé âûáîðêè
  46.  
  47. --\\ Ïîëó÷àåì òàáëèöó, ãäå õðàíÿòñÿ ïàðàìåòðû òåêóùåãî âûáîðà ÍÏÑ
  48. function get_tbl(id)
  49. if current_wpn_tbl[id] == nil then
  50. current_wpn_tbl[id] = {}
  51. current_wpn_tbl[id].locked = false --> çàïðåòèòü ñìåíó îðóæèÿ, åñëè êîí÷èëàñü îáîéìà
  52. current_wpn_tbl[id].cur_id = nil --> ID òåêóùåãî îðóæèÿ
  53. current_wpn_tbl[id].upd_time = 0 --> âðåìÿ ñëåäóþùåãî âûáîðà
  54. end
  55. return current_wpn_tbl[id]
  56. end
  57.  
  58. function get_wpn(ctbl)
  59. local wpn_id = ctbl.cur_id
  60. if wpn_id == nil then return nil end
  61.  
  62. local wpn = level.object_by_id(wpn_id)
  63. if wpn == nil or isWeapon(wpn) == false then
  64. ctbl.cur_id = nil
  65. return nil
  66. else
  67. return wpn
  68. end
  69. end
  70.  
  71. local wm_list = {} --> ëèñò âñåõ ìåíåäæåðîâ îðóæèÿ [id] = mgr
  72.  
  73. --\\ Àïäåéò ÍÏÑ
  74. function npc_update(npc)
  75. local id = npc:id()
  76. if npc:alive() then
  77. if wm_list[id] == nil then
  78. wm_list[id] = weapon_manager(npc) --> Ñîçäà¸ì íîâûé ìåíåäæåð
  79. end
  80.  
  81. wm_list[id]:update()
  82. else
  83. if wm_list[id] ~= nil then
  84. wm_list[id]:kill_wm(1) --> ̸ðòâûì ÍÏÑ åãî óáèðàåì
  85. end
  86. end
  87. end
  88.  
  89. --\\ Êîëáåê íà net_destroy êëèåíòñêîãî îáúåêòà
  90. function on_unregistre_obj(obj, id)
  91. local wpn_mgr = wm_list[id]
  92. if wpn_mgr ~= nil then
  93. wpn_mgr:kill_wm(4)
  94. end
  95. end
  96.  
  97. --------------------------------------
  98.  
  99. class "weapon_manager"
  100. function weapon_manager:__init(npc)
  101. self.npc_id = npc:id()
  102. self.npc = npc
  103. self.last_enemy_time = 0
  104. self.last_distance = 0
  105. self.bKilled = false
  106. self.wpns_list = {} --> Ñïèñîê îðóæèÿ, ïðèíàäëåæàùåãî ÍÏÑ
  107. self.ctbl = get_tbl(self.npc_id) --> Òàáëèöà ñ òåêóùèì îðóæèåì ÍÏÑ
  108. end
  109.  
  110. --\\ Îáíîâëåíèå ìåíåäæåðà
  111. function weapon_manager:update()
  112. self:fill_wpn_list()
  113. self:get_current_wpn()
  114. end
  115.  
  116. --\\ Ñàìî-ïðîâåðêà ìåíåäæåðà íà âàëèäíîñòü
  117. function weapon_manager:self_test()
  118. local npc = level.object_by_id(self.npc_id)
  119. local snpc = alife():object(self.npc_id)
  120. local npc_name
  121.  
  122. if snpc == nil then
  123. npc_name = "<snpc = nil>"
  124. else
  125. npc_name = snpc:name()
  126. end
  127.  
  128. if npc == nil or not IsStalker(npc) then
  129. abort("weapon_manager:npc = nil! bKilled = %s, Owner name = %s ", tostring(self.bKilled), npc_name)
  130. end
  131. end
  132.  
  133. --\\ Óäàëåíèå ìåíåäæåðà
  134. function weapon_manager:kill_wm(iType)
  135. self.bKilled = true --> Ôëàã ÷òî ìåíåäæåð áûë "óáèò"
  136. self.npc = nil --> Óäàëÿåì ññûëêó íà îáúåêò ÍÏÑ
  137. wm_list[self.npc_id] = nil --> Ñíîñèì ñàì ìåíåäæåð
  138. end
  139.  
  140. --\\ Ñòðîèì ëèñò îðóæèÿ ó ÍÏÑ, à òàêæå ïðÿ÷åì íå òåêóùåå
  141. function weapon_manager:fill_wpn_list()
  142. --* Ñòðîèì ñïèñîê îðóæèÿ ó ÍÏÑ
  143. local function find_wpn(npc, wpn)
  144. if isWeapon(wpn) then
  145. self.wpns_list[wpn:id()] = true
  146. end
  147. end
  148. self.npc:iterate_inventory(find_wpn, self.npc)
  149.  
  150. --* Äàëåå ïåðåíîñèì âñ¸ íå àêòèâíîå îðóæèå èç èíâåíòîðÿ ÍÏÑ â ÿùèê
  151.  
  152. for id, _ in pairs(self.wpns_list) do
  153. local wpn = level.object_by_id(id)
  154. local bIsActive = false
  155.  
  156. --> Îðóæèå íå ó íàñ â èíâåíòîðå è íå â ÿùèêå - çíà÷èò ìû åãî ïîòåðÿëè
  157. local parent = nil
  158. if wpn ~= nil then
  159. parent = wpn:parent()
  160. local cwpn = get_wpn(self.ctbl)
  161. bIsActive = (cwpn ~= nil and cwpn:id() == wpn:id())
  162.  
  163. self.Engine = xray.Get(wpn, "CWeapon", true) --> Äàííûå èç ïàìÿòè äëÿ êëèåíòñêîãî îáúåêòà
  164.  
  165. if parent == nil or (parent:id() ~= self.npc_id) then
  166. self.wpns_list[id] = nil --> ñòâîë ïîòåðÿëè
  167. else
  168. if bIsActive == false then --> íå àêòèâíîå îðóæèå íûêàåì â ÿùèê
  169. -- if parent:id() == self.npc_id then
  170. --self.npc:transfer_item(wpn, box)
  171. self.Engine:Set("ef_main_weapon_type", 0)
  172. self.Engine:Set("ef_weapon_type", 0)
  173. -- end
  174. else --> àêòèâíîå ñó¸ì ÍÏÑ
  175. -- if parent:id() == box:id() then
  176. --box:transfer_item(wpn, self.npc)
  177. self.Engine:Set("ef_main_weapon_type", _u.ltx(wpn:section(), "ef_main_weapon_type", "num"))
  178. self.Engine:Set("ef_weapon_type", _u.ltx(wpn:section(), "ef_weapon_type", "num"))
  179. -- end
  180. end
  181. end
  182. else
  183. self.wpns_list[id] = nil --> Ñòâîë ïîõîæå óäàäèëèë
  184. end
  185. end
  186.  
  187. end
  188.  
  189. --\\ Íàõîäèì ëó÷øåå îðóæèå äëÿ ÍÏÑ
  190. function weapon_manager:get_current_wpn()
  191. local id = self.npc_id
  192. local npc = self.npc
  193.  
  194. local special_wpn = nil --> ñïåö-îðóæèå, èìååò ïðèîðèòåò íà âûáîð.
  195.  
  196. local bIsEmptyMag = false --> ôëàã, ÷òî â òåêóùåì îðóæèè êîí÷èëàñü îáîéìà
  197. local cur_wpn = get_wpn(self.ctbl) --> ññûëêà íà òåêóùåå îðóæèå
  198.  
  199. if cur_wpn ~= nil and cur_wpn:get_ammo_in_magazine() == 0 then
  200. bIsEmptyMag = true
  201. end
  202.  
  203. if self.ctbl.upd_time < time_global() or (bIsEmptyMag == true and self.ctbl.locked == false) then
  204. self.ctbl.locked = false
  205.  
  206. local weapon_tbl = {} --> òàáëèöà âñåõ ñòâîëîâ ó ÍÏÑ âèäà (ñòâîë = òèï)
  207. local primary, pcost, ppri = nil, 0, 0 --> îñíîâíîå îðóæèå ÍÏÑ (àâòîìàòû, ñíàéïåðñêîå, îñîáîå)
  208. local secondary, scost, spri = nil, 0, 0 --> âòîðè÷íîå îðóæèå ÍÏÑ (PDW, Äðîáîâèêè)
  209. local pistol, pst_cost = nil, 0 --> ïèñòîëåò
  210.  
  211. local enemy = npc:best_enemy() --> òåêóùèé âðàã ÍÏÑ
  212. local dist = 10000 --> ðàññòîÿíèå äî âðàãà
  213. local bSee = false --> âèäèò ëè ÍÏÑ âðàãà
  214. local bMob = false --> âðàã - ìîíñòð
  215.  
  216. if enemy ~= nil then
  217. dist = npc:position():distance_to(enemy:position())
  218. self.last_enemy_time = time_global()
  219. self.last_distance = dist
  220. if dist <= SEE_DISTANCE then
  221. bSee = true
  222. else
  223. bSee = npc:see(enemy)
  224. end
  225. bMob = IsMonster(enemy)
  226. else
  227. --* Åñëè âðàã áûë íî èñ÷åç, òî íåêîòîðîå âðåìÿ èñïîëüçóåì òåêóùåå îðóæèå (ïðè óñëîâèè ÷òî îíî ó íàñ âîîáùå åñòü)
  228. if cur_wpn ~= nil and (time_global() - self.last_enemy_time <= DIST_MEMORY_TIME) then
  229. self.ctbl.upd_time = time_global() + NEXT_UPD_TIME/2
  230. return
  231. end
  232. end
  233.  
  234. local bExpl = false --> îñíîâíîå îðóæèå âçðûâîîïàñíî
  235.  
  236. --* Íàõîäèì ëó÷øåå îñíîâíîå è âòîðè÷íîå îðóæèå äëÿ ÍÏÑ
  237. for wpn_id, bIsActive in pairs(self.wpns_list) do
  238. local wpn = level.object_by_id(wpn_id)
  239.  
  240. if wpn ~= nil then
  241. ------------------------------------------
  242. local sec = wpn:section()
  243. local wpn_type = _u.ltx(sec, "weapon_type", "str") or "none"
  244.  
  245. if wpn_type ~= "none" then
  246. ---------------------------
  247. local cost = wpn:cost()
  248.  
  249. --* Åñëè åñòü îðóæèå òèïà special, òî ñðàçó âûáèðàåì åãî
  250. if wpn_type == "special" then
  251. special_wpn = wpn
  252. break
  253. end
  254.  
  255. --* Èùåì ëó÷øèé ïèñòîëåò
  256. if wpn_type == "pistol" then
  257. if math.abs(cost - pst_cost) > 1000 then
  258. pistol = wpn
  259. pst_cost = cost
  260. end
  261. end
  262.  
  263. local wpn_prior = nil
  264.  
  265. --* Èùåì ëó÷øåå îñíîâíîå
  266. wpn_prior = primary_types[wpn_type]
  267. if wpn_prior ~= nil then
  268. if wpn_prior >= ppri then
  269. if (wpn_prior ~= ppri) or (math.abs(cost - pcost) >= 2000) then
  270. primary = wpn
  271. pcost = cost
  272.  
  273. if wpn_type == "explosive" then
  274. bExpl = true
  275. else
  276. bExpl = false
  277. end
  278. end
  279. end
  280. end
  281.  
  282. wpn_prior = nil
  283.  
  284. --* Èùåì ëó÷øåå âòîðè÷íîå
  285. wpn_prior = secondary_types[wpn_type]
  286. if wpn_prior ~= nil then
  287. if wpn_prior >= spri then
  288. if (wpn_prior ~= spri) or (math.abs(cost - scost) >= 2000) then
  289. secondary = wpn
  290. scost = cost
  291. end
  292. end
  293. end
  294. ---------------------------
  295. end
  296. ------------------------------------------
  297. end
  298. end
  299.  
  300. --* Ïðîâåðÿåì íàøëè ëè õîòü êàêîå òî îðóæèå
  301. if special_wpn == nil and primary == nil and secondary == nil and pistol == nil then
  302. return npc:set_weapon(nil, NEXT_UPD_TIME)
  303. end
  304.  
  305. --* Åñëè ó íàñ âçðûâîîïàñíîå îðóæèå, è íåòó çàïàñíîãî, òî ïðîáóåì þçàòü ïèñòîëåò âáëèçè
  306. if bExpl and secondary == nil then
  307. secondary = pistol
  308. end
  309.  
  310. --* Åñëè ó íàñ íåòó âðàãà, òî "çàðÿäèì" âñå ñòâîëû ÍÏÑ, äàáû â ãîðÿ÷êå áîÿ îí íå ïîëåç ïåðåçàðÿæàòüñÿ
  311. if enemy == nil then
  312. --! Íå ó÷èòûâàåò ÷òî ðàçìåð ìàãàçèíà ìîæåò èçìåíèòüñÿ ñ àïãðåéäîì, íî ýòî ñëèøêîì çàòðàòíî ñ÷èòàòü
  313. local function set_ammo(wpn)
  314. if wpn ~= nil then
  315. local ammo_max = _u.ltx(wpn:section(), "ammo_mag_size", "num") or nil
  316. if ammo_max ~= nil and wpn:get_ammo_in_magazine() < ammo_max then
  317. wpn:set_ammo_elapsed(ammo_max)
  318. end
  319. end
  320. end
  321.  
  322. set_ammo(primary)
  323. set_ammo(secondary)
  324. set_ammo(pistol)
  325. end
  326.  
  327. if special_wpn == nil then --> Òåïåðü âûáèðàåì êàêîé òèï îðóæèÿ íàì ñåé÷àñ þçàòü
  328. ------------------------------------------
  329. --* Åñëè âðàã ìîíñòð, è îí íà êðèòè÷íîì ðàññòîÿíèè, òî áåð¸ì ïèñòîëåò ïðè îòñóòñòâèè âòîðè÷íîãî îðóæèÿ
  330. if bMob == true and dist <= MST_DISTANCE then
  331. if secondary == nil and pistol ~= nil then
  332. return npc:set_weapon(pistol, NEXT_UPD_TIME_MST)
  333. end
  334. end
  335.  
  336. if bMob == false and dist <= PST_DISTANCE and bSee == true then
  337. if pistol ~= nil then
  338. if (secondary == nil or secondary:get_ammo_in_magazine() == 0) then
  339. return npc:set_weapon(pistol, NEXT_UPD_TIME)
  340. end
  341. end
  342. end
  343.  
  344. --* Âðàã óæå áëèçêî, ïåðåêëþ÷àåìñÿ íà âòîðè÷íîå
  345. if dist <= CLS_DISTANCE then
  346. if secondary ~= nil then
  347. return npc:set_weapon(secondary, NEXT_UPD_TIME)
  348. end
  349. end
  350.  
  351. --* Èíà÷å äà¸ì â ðóêè ïåðâîå, ÷òî åñòü
  352. if primary ~= nil then
  353. return npc:set_weapon(primary, NEXT_UPD_TIME)
  354. end
  355.  
  356. if secondary ~= nil then
  357. return npc:set_weapon(secondary, NEXT_UPD_TIME)
  358. end
  359.  
  360. return npc:set_weapon(pistol, NEXT_UPD_TIME)
  361. ------------------------------------------
  362. end
  363. end
  364.  
  365. if special_wpn ~= nil then
  366. return npc:set_weapon(special_wpn, NEXT_UPD_TIME)
  367. end
  368.  
  369. npc:set_weapon(cur_wpn)
  370. end
  371.  
  372.  
  373. -----------------------------------------------------------------------
  374.  
  375. --\\ Ïðèíóäèòåëüíî óñòàíàâëèâàåì ÍÏÑ äàííóþ ïóøêó êàê îñíîâíóþ íà çàäàííûé ïðîìåæóòîê âðåìåíè â ì\ñåê
  376. function game_object:set_weapon(wpn, upd_time, bLocked)
  377. if bLocked == nil then bLocked = false end
  378.  
  379. if wpn == nil or not isWeapon(wpn) then
  380. wpn = nil
  381. end
  382.  
  383. local npc = self
  384. local id = npc:id()
  385. local ctbl = get_tbl(id)
  386.  
  387. --* Íå ïóùàåì îðóæèå íå èç èíâåíòîðÿ ÍÏÑ
  388. if wpn ~= nil then
  389. local parent = wpn:parent()
  390. if parent == nil or (parent:id() ~= id) then
  391. return nil
  392. end
  393. end
  394.  
  395. if wpn == nil then
  396. ctbl.cur_id = nil
  397. else
  398. ctbl.cur_id = wpn:id()
  399. end
  400.  
  401. ctbl.locked = bLocked
  402.  
  403. if upd_time ~= nil then
  404. ctbl.upd_time = time_global() + upd_time
  405. end
  406.  
  407. return wpn
  408. end
  409.  
  410. --\\ Ïîëó÷àåì ëó÷øóþ ïóøêó ÍÏÑ
  411. function game_object:best_weapon()
  412. local npc = self
  413. local id = npc:id()
  414. local ctbl = get_tbl(id)
  415. return get_wpn(ctbl)
  416. end
  417.  
  418. -----------------------------------------------------
  419. -- Íåíóæíûå ôóíêöèè, îñòàâëåííûå äëÿ ñîâìåñòèìîñòè --
  420. -----------------------------------------------------
  421.  
  422. --\\ Êîëáåê íà àïäåéò èãðîêà
  423. local box_upd_time = 0
  424. function actor_update()
  425.  
  426. end
  427.  
  428. --\\ Êîëáåê íà ñîõðàíåíèÿ èãðîêà
  429. function actor_save()
  430.  
  431. end
  432.  
  433. --\\ Êîëáåê íà ïåðåõîä ÍÏÑ â îôôëàéí
  434. function npc_switch_offline(sobj)
  435.  
  436. end
  437.  
  438. --\\ Êîëáåê íà óäàëåíèå ÍÏÑ èç èãðû
  439. function npc_on_unregister(sobj)
  440.  
  441. end
  442.  
  443. function onModInit()
  444. --> Ïóñòûøêà. Èñïîëüçóåì äëÿ çàãðóçêè ñêðèïòà â ïàìÿòü èãðû. (íå ïîìíþ ïî÷åìó prefetch() íå çàþçàë, ìîæåò è ôóíêöèÿ óæå íå íóæíà)
  445. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement