Advertisement
Guest User

Untitled

a guest
Mar 19th, 2019
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.03 KB | None | 0 0
  1. GM.CraftingRange = 72
  2.  
  3. GM.Crafts = {
  4. {
  5. Name = "a big wooden crate",
  6. a = {"*physics*", {"models/props_junk/wood_crate001a.mdl", "models/props_junk/wood_crate001a_damaged.mdl", "models/props_junk/wood_crate001a_damagedmax.mdl"}},
  7. b = {"*physics*", {"models/props_junk/wood_crate001a.mdl", "models/props_junk/wood_crate001a_damaged.mdl", "models/props_junk/wood_crate001a_damagedmax.mdl"}},
  8. Result = {"prop_physics", Model("models/props_junk/wood_crate002a.mdl")}
  9. },
  10. {
  11. Name = "a bust-on-a-stick",
  12. callback = function(enta, entb)
  13. return enta:IsPhysicsModel("models/props_combine/breenbust.mdl") and entb:IsWeaponType("weapon_zs_plank")
  14. end,
  15. Result = {"weapon_zs_bust"}
  16. },
  17. {
  18. Name = "an oil-filled barrel",
  19. a = {"*physics*", "models/props_junk/gascan001a.mdl"},
  20. b = {"*physics*", "models/props_c17/oildrum001.mdl"},
  21. Result = {"prop_physics", Model("models/props_c17/oildrum001_explosive.mdl")}
  22. },
  23. {
  24. Name = "a sawhack",
  25. callback = function(enta, entb)
  26. return enta:IsPhysicsModel("models/props_junk/sawblade001a.mdl") and entb:IsWeaponType("weapon_zs_axe")
  27. end,
  28. Result = {"weapon_zs_sawhack"}
  29. },
  30. {
  31. Name = "a mega masher",
  32. callback = function(enta, entb)
  33. return enta:IsPhysicsModel("models/props_c17/oildrum001_explosive.mdl") and entb:IsWeaponType("weapon_zs_sledgehammer")
  34. end,
  35. Result = {"weapon_zs_megamasher"}
  36. },
  37. {
  38. Name = "an electrohammer",
  39. callback = function(enta, entb)
  40. return enta:IsPhysicsModel("models/items/car_battery01.mdl") and entb:IsWeaponType("weapon_zs_hammer")
  41. end,
  42. Result = {"weapon_zs_electrohammer"}
  43. },
  44. {
  45. Name = "a 'Waraxe' handgun",
  46. callback = function(enta, entb)
  47. return enta:IsWeaponType("weapon_zs_battleaxe") and entb:IsWeaponType("weapon_zs_battleaxe")
  48. end,
  49. Result = {"weapon_zs_waraxe"}
  50. },
  51. {
  52. Name = "a 'Kongol Axe'",
  53. callback = function(enta, entb)
  54. return enta:IsWeaponType("weapon_zs_butcherknife") and entb:IsWeaponType("weapon_zs_axe")
  55. end,
  56. Result = {"weapon_zs_kongol"}
  57. },
  58. {
  59. Name = "a 'Plaster Shotgun'",
  60. callback = function(enta, entb)
  61. return enta:IsWeaponType("weapon_zs_blaster") and entb:IsWeaponType("weapon_zs_blaster")
  62. end,
  63. Result = {"weapon_zs_plaster"}
  64. },
  65. {
  66. Name = "a 'Slosser Assault Rifle'",
  67. callback = function(enta, entb)
  68. return enta:IsWeaponType("weapon_zs_slaughter") and entb:IsWeaponType("weapon_zs_tosser")
  69. end,
  70. Result = {"weapon_zs_slosser"}
  71. },
  72. {
  73. Name = "a 'explosive crowbar'",
  74. callback = function(enta, entb)
  75. return enta:IsPhysicsModel("models/props_c17/oildrum001_explosive.mdl") and entb:IsWeaponType("weapon_zs_crowbar")
  76. end,
  77. Result = {"weapon_zs_explosivecrowbar"}
  78. },
  79. {
  80. Name = "a 'Ultra Masher'",
  81. callback = function(enta, entb)
  82. return enta:IsWeaponType("weapon_zs_megamasher") and entb:IsWeaponType("weapon_zs_megamasher")
  83. end,
  84. Result = {"weapon_zs_ultramasher"}
  85. },
  86. {
  87. Name = "a 'Boom Masher'",
  88. callback = function(enta, entb)
  89. return enta:IsWeaponType("weapon_zs_megamasher") and entb:IsWeaponType("weapon_zs_boomstick")
  90. end,
  91. Result = {"weapon_zs_boommasher"}
  92. },
  93. {
  94. Name = "a 'Nuke Masher'",
  95. callback = function(enta, entb)
  96. return enta:IsWeaponType("weapon_zs_ultramasher") and entb:IsWeaponType("weapon_zs_glauncher")
  97. end,
  98. Result = {"weapon_zs_nukemasher"}
  99. },
  100. {
  101. Name = "a 'God Nuke Masher'",
  102. callback = function(enta, entb)
  103. return enta:IsWeaponType("weapon_zs_nukemasher") and entb:IsWeaponType("weapon_zs_nukearm")
  104. end,
  105. Result = {"weapon_zs_godnukemasher"}
  106. },
  107. {
  108. Name = "a 'Empowered Sledgehammer'",
  109. callback = function(enta, entb)
  110. return enta:IsWeaponType("weapon_zs_empower") and entb:IsWeaponType("weapon_zs_sledgehammer")
  111. end,
  112. Result = {"weapon_zs_empoweredhammer"}
  113. },
  114. {
  115. Name = "a 'Empowered Crowbar'",
  116. callback = function(enta, entb)
  117. return enta:IsWeaponType("weapon_zs_empower") and entb:IsWeaponType("weapon_zs_crowbar")
  118. end,
  119. Result = {"weapon_zs_empoweredcrowbar"}
  120. },
  121. {
  122. Name = "a 'Fury Crowbar'",
  123. callback = function(enta, entb)
  124. return enta:IsPhysicsModel("models/props_c17/oildrum001_explosive.mdl") and entb:IsWeaponType("weapon_zs_empoweredcrowbar")
  125. end,
  126. Result = {"weapon_zs_furycrowbar"}
  127. },
  128. {
  129. Name = "a 'Empowered Shovel'",
  130. callback = function(enta, entb)
  131. return enta:IsWeaponType("weapon_zs_empower") and entb:IsWeaponType("weapon_zs_shovel")
  132. end,
  133. Result = {"weapon_zs_empoweredshovel"}
  134. },
  135. {
  136. Name = "a 'Electric Shovel'",
  137. callback = function(enta, entb)
  138. return enta:IsPhysicsModel("models/items/car_battery01.mdl") and entb:IsWeaponType("weapon_zs_shovel")
  139. end,
  140. Result = {"weapon_zs_electricshovel"}
  141. },
  142. {
  143. Name = "a 'Gravedigger'",
  144. callback = function(enta, entb)
  145. return enta:IsPhysicsModel("models/items/car_battery01.mdl") and entb:IsWeaponType("weapon_zs_empoweredshovel")
  146. end,
  147. Result = {"weapon_zs_gravedigger"}
  148. },
  149. {
  150. Name = "Fridge Brilliance",
  151. callback = function(enta, entb)
  152. return enta:IsWeaponType("weapon_zs_empoweredhammer") and entb:IsPhysicsModel("models/props_interiors/vendingmachinesoda01a.mdl")
  153. end,
  154. Result = {"weapon_zs_fridgebrilliance"}
  155. },
  156. {
  157. Name = "a 'Empowered Gun'",
  158. callback = function(enta, entb)
  159. return enta:IsWeaponType("weapon_zs_empower") and entb:IsWeaponType("weapon_zs_gun")
  160. end,
  161. Result = {"weapon_zs_empoweredgun"}
  162. },
  163. {
  164. Name = "Slagfinity",
  165. callback = function(enta, entb)
  166. return enta:IsWeaponType("weapon_zs_slagpistol") and entb:IsWeaponType("weapon_zs_infinity")
  167. end,
  168. Result = {"weapon_zs_slagfinity"}
  169. },
  170. {
  171. Name = "Propeller-Go-Fast",
  172. callback = function(enta, entb)
  173. return enta:IsWeaponType("weapon_zs_propellerblade") and entb:IsWeaponType("weapon_zs_sanic")
  174. end,
  175. Result = {"weapon_zs_propellersanic"}
  176. },
  177. {
  178. Name = "Manarm Handgun",
  179. callback = function(enta, entb)
  180. return enta:IsWeaponType("weapon_zs_longarm") and entb:IsWeaponType("weapon_zs_empower")
  181. end,
  182. Result = {"weapon_zs_manarm"}
  183. },
  184. {
  185. Name = "Brawlaxe Handgun",
  186. callback = function(enta, entb)
  187. return enta:IsWeaponType("weapon_zs_manarm") and entb:IsWeaponType("weapon_zs_eternity")
  188. end,
  189. Result = {"weapon_zs_brawlaxe"}
  190. },
  191. {
  192. Name = "Infinity Plank",
  193. callback = function(enta, entb)
  194. return enta:IsWeaponType("weapon_zs_infinity") and entb:IsWeaponType("weapon_zs_plank")
  195. end,
  196. Result = {"weapon_zs_infinityplank"}
  197. },
  198. {
  199. Name = "Gunstick",
  200. callback = function(enta, entb)
  201. return enta:IsWeaponType("weapon_zs_gun") and entb:IsWeaponType("weapon_zs_boomstick")
  202. end,
  203. Result = {"weapon_zs_gunstick"}
  204. },
  205. {
  206. Name = "Big Gun Owens Handgun Gun Gun",
  207. callback = function(enta, entb)
  208. return enta:IsWeaponType("weapon_zs_gun") and entb:IsWeaponType("weapon_zs_bigowens")
  209. end,
  210. Result = {"weapon_zs_biggunowens"}
  211. },
  212. {
  213. Name = "Gunfinity",
  214. callback = function(enta, entb)
  215. return enta:IsWeaponType("weapon_zs_gun") and entb:IsWeaponType("weapon_zs_infinity")
  216. end,
  217. Result = {"weapon_zs_gunfinity"}
  218. },
  219. {
  220. Name = "Infinochet",
  221. callback = function(enta, entb)
  222. return enta:IsWeaponType("weapon_zs_magnum") and entb:IsWeaponType("weapon_zs_infinity")
  223. end,
  224. Result = {"weapon_zs_infinochet"}
  225. },
  226. {
  227. Name = "Deagle Redeemers",
  228. callback = function(enta, entb)
  229. return enta:IsWeaponType("weapon_zs_redeemers") and entb:IsWeaponType("weapon_zs_deagle")
  230. end,
  231. Result = {"weapon_zs_deagleredeemers"}
  232. },
  233. {
  234. Name = "Cancer's Deagle Redeemers",
  235. callback = function(enta, entb)
  236. return enta:IsWeaponType("weapon_zs_deagleredeemers") and entb:IsWeaponType("weapon_zs_cancerkit")
  237. end,
  238. Result = {"weapon_zs_cancer"}
  239. },
  240. {
  241. Name = "Cancer's Deagle",
  242. callback = function(enta, entb)
  243. return enta:IsWeaponType("weapon_zs_deagle") and entb:IsWeaponType("weapon_zs_cancerkit")
  244. end,
  245. Result = {"weapon_zs_cance"}
  246. },
  247. {
  248. Name = "a 'Electric Medkit'",
  249. callback = function(enta, entb)
  250. return enta:IsPhysicsModel("models/items/car_battery01.mdl") and entb:IsWeaponType("weapon_zs_medicalkit")
  251. end,
  252. Result = {"weapon_zs_shockkit"}
  253. },
  254. {
  255. Name = "Silenced Owens",
  256. callback = function(enta, entb)
  257. return enta:IsWeaponType("weapon_zs_owens") and entb:IsWeaponType("weapon_zs_silencer")
  258. end,
  259. Result = {"weapon_zs_sowens"}
  260. },
  261. {
  262. Name = "Gun 2",
  263. callback = function(enta, entb)
  264. return enta:IsWeaponType("weapon_zs_gun") and entb:IsWeaponType("weapon_zs_gun")
  265. end,
  266. Result = {"weapon_zs_gun2"}
  267. },
  268. {
  269. Name = "Gun 3",
  270. callback = function(enta, entb)
  271. return enta:IsWeaponType("weapon_zs_gun2") and entb:IsWeaponType("weapon_zs_gun2")
  272. end,
  273. Result = {"weapon_zs_gun3"}
  274. },
  275. {
  276. Name = "Gun 4",
  277. callback = function(enta, entb)
  278. return enta:IsWeaponType("weapon_zs_gun3") and entb:IsWeaponType("weapon_zs_gun3")
  279. end,
  280. Result = {"weapon_zs_gun4"}
  281. },
  282. {
  283. Name = "Gun 5",
  284. callback = function(enta, entb)
  285. return enta:IsWeaponType("weapon_zs_gun4") and entb:IsWeaponType("weapon_zs_gun4")
  286. end,
  287. Result = {"weapon_zs_gun5"}
  288. },
  289. {
  290. Name = "A bouncy boomstick",
  291. callback = function(enta, entb)
  292. return enta:IsWeaponType("weapon_zs_magnum") and entb:IsWeaponType("weapon_zs_originalboomstick")
  293. end,
  294. Result = {"weapon_zs_ricochetstick"}
  295. },
  296. {
  297. Name = "A white rifle",
  298. callback = function(enta, entb)
  299. return enta:IsWeaponType("weapon_zs_crackler") and entb:IsWeaponType("weapon_zs_infinity")
  300. end,
  301. Result = {"weapon_zs_cracker"}
  302. },
  303. {
  304. Name = "Owens Crossbow",
  305. callback = function(enta, entb)
  306. return enta:IsWeaponType("weapon_zs_bigowens") and entb:IsWeaponType("weapon_zs_crossbow")
  307. end,
  308. Result = {"weapon_zs_owenscrossbow"}
  309. },
  310. {
  311. Name = "Owens Hunting Shotgun",
  312. callback = function(enta, entb)
  313. return enta:IsWeaponType("weapon_zs_bigowens") and entb:IsWeaponType("weapon_zs_originalboomstick")
  314. end,
  315. Result = {"weapon_zs_owenshunting"}
  316. },
  317. {
  318. Name = "Owens Sniper Rifle",
  319. callback = function(enta, entb)
  320. return enta:IsWeaponType("weapon_zs_bigowens") and entb:IsWeaponType("weapon_zs_awp")
  321. end,
  322. Result = {"weapon_zs_owenssniper"}
  323. },
  324. {
  325. Name = "The First Owens Weapon",
  326. callback = function(enta, entb)
  327. return enta:IsWeaponType("weapon_zs_bigowens") and entb:IsWeaponType("weapon_zs_m249")
  328. end,
  329. Result = {"weapon_zs_owensthefirst"}
  330. },
  331. {
  332. Name = "Owens Mark II",
  333. callback = function(enta, entb)
  334. return enta:IsWeaponType("weapon_zs_bigowens") and entb:IsWeaponType("weapon_zs_largeowens")
  335. end,
  336. Result = {"weapon_zs_owensmark2"}
  337. },
  338. {
  339. Name = "Owens Revenge",
  340. callback = function(enta, entb)
  341. return enta:IsWeaponType("weapon_zs_bigowens") and entb:IsWeaponType("weapon_zs_zedeagle")
  342. end,
  343. Result = {"weapon_zs_owensrevenge"}
  344. },
  345. {
  346. Name = "Owens Meme Factory",
  347. callback = function(enta, entb)
  348. return enta:IsWeaponType("weapon_zs_bigowens") and entb:IsWeaponType("weapon_zs_memer")
  349. end,
  350. Result = {"weapon_zs_owensmeme"}
  351. },
  352. {
  353. Name = "Owens Crossbow",
  354. callback = function(enta, entb)
  355. return enta:IsWeaponType("weapon_zs_bigowens") and entb:IsWeaponType("weapon_zs_crossbow")
  356. end,
  357. Result = {"weapon_zs_owenscrossbow"}
  358. },
  359. {
  360. Name = "Owens Energy Cannon",
  361. callback = function(enta, entb)
  362. return enta:IsWeaponType("weapon_zs_bigowens") and entb:IsWeaponType("weapon_zs_glueon")
  363. end,
  364. Result = {"weapon_zs_owensenergycannon"}
  365. },
  366. {
  367. Name = "a modified manhack",
  368. callback = function(enta, entb)
  369. return enta:IsPhysicsModel("models/props_junk/sawblade001a.mdl") and entb:IsWeaponType("weapon_zs_manhack")
  370. end,
  371. Result = {"weapon_zs_manhack_saw"}
  372. }
  373. }
  374.  
  375. function GM:GetCraftingRecipe(enta, entb)
  376. if not enta:IsValid() or not entb:IsValid() or enta == entb then return end
  377.  
  378. for _, recipe in pairs(self.Crafts) do
  379. if self:CraftingRecipeMatches(enta, entb, recipe) then return recipe end
  380. end
  381. end
  382.  
  383. function GM:GetCraftTarget(enta, entb)
  384. return enta:OBBMaxs():Distance(enta:OBBMins()) > entb:OBBMaxs():Distance(entb:OBBMins()) and enta or entb
  385. end
  386.  
  387. function GM:CraftingRecipeMatches(enta, entb, recipe, checkedswap)
  388. local entaclass = enta:GetClass()
  389. local entbclass = entb:GetClass()
  390. local entaisphysics = string.sub(entaclass, 1, 12) == "prop_physics"
  391. local entbisphysics = string.sub(entbclass, 1, 12) == "prop_physics"
  392.  
  393. if recipe.callback and recipe.callback(enta, entb) then
  394. return true
  395. end
  396.  
  397. if recipe.a and recipe.b and (recipe.a[1] == entaclass or entaisphysics and recipe.a[1] == "*physics*") and (recipe.b[1] == entbclass or entaisphysics and recipe.a[1] == "*physics*") then
  398. local mdla = string.lower(enta:GetModel())
  399. local mdlb = string.lower(entb:GetModel())
  400. if (recipe.a[2] == nil or type(recipe.a[2]) == "table" and table.HasValue(recipe.a[2], mdla) or mdla == recipe.a[2]) and (recipe.b[2] == nil or type(recipe.b[2]) == "table" and table.HasValue(recipe.b[2], mdlb) or mdlb == recipe.b[2]) then
  401. return true
  402. end
  403. end
  404.  
  405. if not checkedswap then
  406. return self:CraftingRecipeMatches(entb, enta, recipe, true)
  407. end
  408. end
  409.  
  410. function GM:CanCraft(pl, enta, entb)
  411. if self:GetCraftingRecipe(enta, entb) == nil or not pl:IsValid() or not pl:Alive() or pl:Team() ~= TEAM_HUMAN then return false end
  412.  
  413. if enta:IsBarricadeProp() or entb:IsBarricadeProp() or enta:GetName() ~= "" or entb:GetName() ~= "" then return false end
  414.  
  415. local nearestb = entb:NearestPoint(enta:LocalToWorld(enta:OBBCenter()))
  416. local nearesta = enta:NearestPoint(entb:LocalToWorld(entb:OBBCenter()))
  417. if nearesta:Distance(nearestb) > self.CraftingRange or not TrueVisibleFilters(nearesta, nearestb, pl, enta, entb) then return false end
  418.  
  419. local eyepos = pl:EyePos()
  420. if enta:NearestPoint(eyepos):Distance(eyepos) > self.CraftingRange or entb:NearestPoint(eyepos):Distance(eyepos) > self.CraftingRange then return false end
  421.  
  422. if not TrueVisibleFilters(nearesta, eyepos, pl, enta, entb) or not TrueVisibleFilters(nearestb, eyepos, pl, enta, entb) then return false end
  423.  
  424. return true
  425. end
  426.  
  427. local meta = FindMetaTable("Entity")
  428. if not meta then return end
  429.  
  430. function meta:IsPhysicsModel(mdl)
  431. return string.sub(self:GetClass(), 1, 12) == "prop_physics" and (not mdl or string.lower(self:GetModel()) == string.lower(mdl))
  432. end
  433.  
  434. function meta:IsWeaponType(class)
  435. return self:GetClass() == "prop_weapon" and self:GetWeaponType() == class
  436. end
  437.  
  438. if true then return end
  439.  
  440. function GM:GetCraftingRecipe(enta, entb)
  441. if not enta:IsValid() or not entb:IsValid() or enta == entb then return end
  442.  
  443. for _, recipe in pairs(self.Crafts) do
  444. if self:CraftingRecipeMatches(enta, entb, recipe) then return recipe end
  445. end
  446. end
  447.  
  448. function GM:GetCraftTarget(enta, entb)
  449. return enta:OBBMaxs():Distance(enta:OBBMins()) > entb:OBBMaxs():Distance(entb:OBBMins()) and enta or entb
  450. end
  451.  
  452. function GM:CraftingRecipeMatches(enta, entb, recipe, checkedswap)
  453. local entaclass = enta:GetClass()
  454. local entbclass = entb:GetClass()
  455. local entaisphysics = string.sub(entaclass, 1, 12) == "prop_physics"
  456. local entbisphysics = string.sub(entbclass, 1, 12) == "prop_physics"
  457.  
  458. if recipe.callback and recipe.callback(enta, entb) then
  459. return true
  460. end
  461.  
  462. if recipe.a and recipe.b and (recipe.a[1] == entaclass or entaisphysics and recipe.a[1] == "*physics*") and (recipe.b[1] == entbclass or entaisphysics and recipe.a[1] == "*physics*") then
  463. local mdla = string.lower(enta:GetModel())
  464. local mdlb = string.lower(entb:GetModel())
  465. if (recipe.a[2] == nil or type(recipe.a[2]) == "table" and table.HasValue(recipe.a[2], mdla) or mdla == recipe.a[2]) and (recipe.b[2] == nil or type(recipe.b[2]) == "table" and table.HasValue(recipe.b[2], mdlb) or mdlb == recipe.b[2]) then
  466. return true
  467. end
  468. end
  469.  
  470. if not checkedswap then
  471. return self:CraftingRecipeMatches(entb, enta, recipe, true)
  472. end
  473. end
  474.  
  475. function GM:GetAllValidCraftingRecipes(pl)
  476. local craftable = {}
  477.  
  478. for _, craft in pairs(self.Crafts) do
  479. if self:CanCraft(pl, craft) then
  480. table.insert(craftable, craft)
  481. end
  482. end
  483.  
  484. return craftable
  485. end
  486.  
  487. -- Preliminary tests for all entity types.
  488. -- Classes are enforced by the recipes so if someone makes a recipe inolving players or worldspawn then oh well.
  489. function GM:IsValidCraftingEntity(ent, pl)
  490. return not ent:IsWeapon()
  491. and not (ent:IsPhysicsModel() and ent:GetName() ~= "")
  492. and not (ent:IsWeapon() and ent:GetOwner() ~= pl)
  493. end
  494.  
  495. -- This checks everything and is what determines if a recipe displays to the player in their menu.
  496. function GM:CanCraft(pl, craft)
  497. if not pl:IsValid() or not pl:Alive() or pl:Team() ~= TEAM_HUMAN then return false end
  498.  
  499. local plpos = pl:EyePos()
  500. local entities = ents.FindValidInSphere(plpos, self.CraftingRange)
  501.  
  502. if craft.CanCraft and not craft:CanCraft(pl, entities, plpos) then return false end
  503.  
  504. local ingredients = {}
  505.  
  506. for _, ent in pairs(entities) do
  507. if craft.CanUseEntity and not craft:CanUseEntity(ent, pl) then continue end
  508. end
  509.  
  510. -- All ingredients accounted for?
  511. --for _, ingredient
  512.  
  513. local nearestb = entb:NearestPoint(enta:LocalToWorld(enta:OBBCenter()))
  514. local nearesta = enta:NearestPoint(entb:LocalToWorld(entb:OBBCenter()))
  515. if nearesta:Distance(nearestb) > self.CraftingRange or not TrueVisibleFilters(nearesta, nearestb, pl, enta, entb) then return false end
  516.  
  517. local eyepos = pl:EyePos()
  518. if enta:NearestPoint(eyepos):Distance(eyepos) > self.CraftingRange or entb:NearestPoint(eyepos):Distance(eyepos) > self.CraftingRange then return false end
  519.  
  520. if not TrueVisibleFilters(nearesta, eyepos, pl, enta, entb) or not TrueVisibleFilters(nearestb, eyepos, pl, enta, entb) then return false end
  521.  
  522. return true
  523. end
  524.  
  525. local meta = FindMetaTable("Entity")
  526. if not meta then return end
  527.  
  528. function meta:IsPhysicsModel(mdl)
  529. return string.sub(self:GetClass(), 1, 12) == "prop_physics" and (not mdl or string.lower(self:GetModel()) == string.lower(mdl))
  530. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement