Guest User

Untitled

a guest
Mar 29th, 2016
161
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 26.71 KB | None | 0 0
  1. if SERVER then return end
  2.  
  3. local ShowTimeStamps = false // show timestamps by default
  4. local ScrollDownWhenTurnedOff = true // scroll down after hitting Enter or Escape by default
  5.  
  6. local MaxMessageHistory = 150 // how much messages should be displayed in the history
  7. local MessageFadeoutTime = 10 // how much time in seconds before a new message fades out
  8. local PrintChatToConsole = false // should everything said in chat be also added to the console log
  9.  
  10. local ShowMessageIcons = true // show join/leave + chat print messages with an icon below
  11. local InfoMessageIcon = Material("icon16/information.png") // message icon for join/leave + blue chat print messages
  12.  
  13. local ShowIconsForPlayers = true // show player avatar/rank icons NOTE:Players can enable/disable this
  14.  
  15. local ShowPlayerAvatars = false // show player Avatar icons, WARNING:Overrides user rank icons
  16. local ShowPlayerRanks = true // show player Rank icons, avatar icons must be turned off(false)
  17.  
  18. local EnableRankGlow = true // show glowing rank labels in front of player names. ex:[Admin] TOMASAS: 123
  19. local RankLabelGlowSize = 0.8 // the size of the glow, anywhere from 0.5 to 1.5 should be good. Default is 0.8
  20. local RankGlowUserGroups = {}// display ranks with glow, format RankGlowUserGroups["userGroupHere"] = {"RankNameHere", Color(1,2,3)}
  21. RankGlowUserGroups["vip"] = {"VIP", Color(255, 255, 0)}
  22. RankGlowUserGroups["admin"] = {"GFL Admin", Color(0, 255, 0)}
  23. RankGlowUserGroups["superadmin"] = {"Super Admin", Color(255, 140, 0)}
  24. RankGlowUserGroups["owner"] = {"Owner", Color(255, 0, 0)}
  25.  
  26.  
  27. local DefaultUserIcon = Material("icon16/user.png") // default user icon
  28. local AdminIcon = Material("C:/garrysmod/garrysmod/materials/icon16/admin.png") // IsAdmin viable player icon
  29. local SuperAdminIcon = Material("C:/garrysmod/garrysmod/materials/icon16/shield_rainbow.png") // IsSuperAdmin viable player icon
  30. local OwnerIcon = Material("C:/garrysmod/garrysmod/materials/icon16/shield_rainbow.png") // ULX Owner custom group, added to custom code below.
  31.  
  32. // chat colors, ex "[red]" will be [red] in chat
  33. // color format Color(Red, Green, Blue), numbers are from 0-255 intensity
  34. local ChatColorTags = {["[red]"] = Color(255, 0, 0),
  35. ["[green]"] = Color(0, 255, 0),
  36. ["[blue]"] = Color(0, 0, 255),
  37. ["[white]"] = Color(255, 255, 255),
  38. }
  39. local EnableChatColorTags = false // enable or disable [color] tags in chat
  40.  
  41. // CHANGE SKIN TYPE HERE, 1 to 3
  42. local SkinType = 1 // default skin - 1, round skin - 2, full round skin - 3
  43.  
  44. local font = "Segoe UI" //type of font to use, recommended use default - Segoe UI
  45. local ChatTextboxColor = Color(255, 255, 255, 255) //textbox that you enter text background color
  46. local ChatHighlightColor = Color(255, 255, 255, 100) // chat text highlighting color
  47.  
  48. local white, black = Color(255, 255, 255, 255), Color(10, 10, 10, 255) //default message color, all message shadow color
  49.  
  50. // screen pos is multiplied by a percent of your screen to look the same on different resolutions
  51. local ChatPosX = ScrW() * 0.0125 //chat position on the x axis
  52. local ChatPosY = ScrH() * 0.5725 //chat position on the y axis
  53.  
  54.  
  55. --------------------------------- DONT EDIT AFTER THIS LINE IF YOU DON'T CODE LUA ------------------------------------------
  56. local surface, draw, Color, type = surface, draw, Color, type
  57. font = (font == "Segoe UI" and system.IsWindows()) and "Segoe UI" or font == "Segoe UI" and "Verdana" or font
  58. surface.CreateFont("ChatTextNormal", {
  59. font = font,
  60. size = 23,
  61. weight = 500
  62. })
  63. surface.SetFont("ChatTextNormal")
  64. local _, Ftall = surface.GetTextSize("AbC1230")
  65.  
  66. local function shouldDrawPaint(self)
  67. if !NewChatIsOpen then
  68. return
  69. else
  70. local ctime = CurTime()+4.5
  71. for i=1, #self.pList.Can.Items do // make them fade in
  72. self.pList.Can.Items[i].CreateTime = ctime
  73. end
  74. return true
  75. end
  76. end
  77.  
  78. --[[Skin Templates:
  79. SkinTable[1] = {}
  80. SkinTable[1].EntryPaint = SkinTable[1].EntryPaint
  81. SkinTable[1].GearPaint = SkinTable[1].GearPaint // args: teamSay = true/false, self
  82. SkinTable[1].Init = function(self) // OPTIONAL FUNCTION
  83.  
  84. end
  85. SkinTable[1].Paint = function(self)
  86. if !shouldDrawPaint(self) then return end
  87. end
  88. SkinTable[1].PaintOver = function(self)// OPTIONAL FUNCTION
  89. if !NewChatIsOpen then return end
  90. end
  91. ]]
  92. local GearMat = Material("icon16/cog.png")
  93. local SkinTable = {}
  94. SkinTable[1] = {}
  95. SkinTable[1].EntryPaint = function(self)
  96. surface.SetDrawColor(0, 0, 0, 255)
  97. DisableClipping(true)
  98. surface.DrawOutlinedRect(0, 0, self:GetWide()+1, self:GetTall())
  99. DisableClipping(false)
  100. surface.SetDrawColor(ChatTextboxColor)
  101. surface.DrawRect(1, 1, self:GetWide()-1, self:GetTall()-2)
  102. self:DrawTextEntryText(self.m_colText, self.m_colHighlight, self.m_colCursor)
  103. end
  104. SkinTable[1].GearPaint = function(teamSay, self)
  105. surface.SetDrawColor(teamSay and 0 or 255,teamSay and 215 or 255,teamSay and 0 or 255, 255)
  106. surface.DrawRect(0, 0, self:GetWide(), self:GetTall())
  107.  
  108. surface.SetDrawColor(0, 0, 0, 255)
  109. surface.DrawLine(0, 0, self:GetWide(), 0)
  110. surface.DrawLine(0, self:GetTall()-1, self:GetWide(), self:GetTall()-1)
  111. DisableClipping(true)
  112. surface.DrawLine(-1, 0, -1, self:GetTall())
  113. DisableClipping(false)
  114. surface.SetDrawColor(255, 255, 255, 255)
  115. surface.SetMaterial(GearMat)
  116. surface.DrawTexturedRect(2, 2, 16, 16)
  117. end
  118. SkinTable[1].Paint = function(self)
  119. if !shouldDrawPaint(self) then return end
  120.  
  121. surface.SetDrawColor(189, 195, 199, 255)
  122. surface.DrawLine(0, self:GetTall()-26, self:GetWide(), self:GetTall()-26)
  123. surface.SetDrawColor(136, 140, 141, 100)
  124. DisableClipping(true)
  125. surface.DrawRect(0, 0, self:GetWide(), self:GetTall()+5)
  126. DisableClipping(false)
  127. end
  128. SkinTable[1].PaintOver = function(self)
  129. if !NewChatIsOpen then return end
  130. DisableClipping(true)
  131. surface.SetDrawColor(44, 62, 80, 255)
  132. surface.DrawOutlinedRect(-1, -1, self:GetWide()+2, self:GetTall()+6)
  133. DisableClipping(false)
  134. end
  135.  
  136. SkinTable[2] = {}
  137. SkinTable[2].EntryPaint = SkinTable[1].EntryPaint
  138. SkinTable[2].GearPaint = SkinTable[1].GearPaint
  139. SkinTable[2].Init = function(self)
  140. self.Grip.LowestAlpha = 125
  141. self.Grip.Paint = function()
  142. local a = self.Grip:GetAlpha()
  143. draw.RoundedBox(4, 0, 0, self.Grip:GetWide(), self.Grip:GetTall(), Color(0, 0, 0, a))
  144. end
  145.  
  146. end
  147. SkinTable[2].Paint = function(self)
  148. if !shouldDrawPaint(self) then return end
  149.  
  150. DisableClipping(true)
  151. draw.RoundedBox(6, -2, -2, self:GetWide()+4, self:GetTall()+9, Color(0, 0, 0, 150))
  152. DisableClipping(false)
  153. end
  154.  
  155.  
  156. SkinTable[3] = {}
  157. SkinTable[3].EntryPaint = function(self)
  158. DisableClipping(true)
  159. draw.RoundedBoxEx(6, 0, 0, self:GetWide()+2, self:GetTall(), Color(0, 0, 0, 150), false, true, false, true)
  160. DisableClipping(false)
  161. self:DrawTextEntryText(Color(255, 255, 255, 255), self.m_colHighlight, Color(255, 255, 255, 255))
  162. end
  163. SkinTable[3].GearPaint = function(teamSay, self)
  164. DisableClipping(true)
  165. draw.RoundedBoxEx(6, -2, 0, self:GetWide()+2, self:GetTall(), Color(0,teamSay and 215 or 0,0, 150), true, false, true, false)
  166. DisableClipping(false)
  167. surface.SetDrawColor(255, 255, 255, 255)
  168. surface.SetMaterial(GearMat)
  169. surface.DrawTexturedRect(2, 2, 16, 16)
  170. end
  171. SkinTable[3].Init = function(self)
  172. self.Grip.LowestAlpha = 125
  173. self.Grip.Paint = function()
  174. local a = self.Grip:GetAlpha()
  175. draw.RoundedBox(4, 0, 0, self.Grip:GetWide(), self.Grip:GetTall(), Color(0, 0, 0, a))
  176. end
  177.  
  178. end
  179. SkinTable[3].Paint = function(self)
  180. if !shouldDrawPaint(self) then return end
  181.  
  182. DisableClipping(true)
  183. draw.RoundedBox(6, -2, -2, self:GetWide()+4, self:GetTall()-22, Color(0, 0, 0, 150))
  184. DisableClipping(false)
  185. end
  186.  
  187. local function toBit(s) return s and 1 or 0 end // take care of chat config save and loading
  188. local ChatConVar = CreateClientConVar("tomasas_chatbox_cfg", table.concat({toBit(ShowMessageIcons), toBit(ShowIconsForPlayers), toBit(ShowTimeStamps), toBit(ScrollDownWhenTurnedOff)}, "|"), true, false)
  189. local chat_cfg = string.Explode("|", ChatConVar:GetString())
  190. ShowMessageIcons = tobool(chat_cfg[1])
  191. ShowIconsForPlayers = tobool(chat_cfg[2])
  192. ShowTimeStamps = tobool(chat_cfg[3])
  193. ScrollDownWhenTurnedOff = tobool(chat_cfg[4])
  194. local function SaveChatConfig()
  195. RunConsoleCommand("tomasas_chatbox_cfg", table.concat({toBit(ShowMessageIcons), toBit(ShowIconsForPlayers), toBit(ShowTimeStamps), toBit(ScrollDownWhenTurnedOff)}, "|"))
  196. end
  197.  
  198. chat.GetChatBoxPos = function() return ChatPosX, ChatPosY end
  199.  
  200.  
  201. local menu, PanelPaint = ChatframePanel
  202. local function OpenChat()
  203. if menu and menu.IsValid and menu:IsValid() then if menu.Entry then menu.CFG:Remove() menu.Entry:Remove() end menu.Grip:Remove() menu.pList.Can:Remove() menu.pList:Remove() menu:Remove() end
  204. menu = vgui.Create("DFrame")
  205. ChatframePanel = menu // make the chat accessable globally
  206. menu:SetTitle("")
  207. for k, v in pairs(SkinTable[SkinType]) do // handle skins
  208. if k != "Init" then
  209. menu[k] = v
  210. end
  211. end
  212. menu:ShowCloseButton(false)
  213. menu:SetDraggable(false)
  214. menu:SetSize(320 * (ScrH()/480), ScreenScale(99)*0.5+26)
  215. local chatx, chaty = chat.GetChatBoxPos()
  216. menu:SetPos(chatx, chaty)
  217.  
  218. chatx, chaty = menu:GetSize()
  219.  
  220. local pList = vgui.Create("DPanel", menu)
  221. menu.pList = pList
  222. pList:SetPaintBackground(false)
  223. pList:SetSize(chatx, chaty-26)
  224. pList:SetPos(0, 0)
  225. pList.Can = vgui.Create("DPanel", pList)
  226. pList.Can:SetPaintBackground(false)
  227. pList.Can.Items = {}
  228. pList.Can:SetSize(pList:GetWide(), 0)
  229. pList.OnMouseWheeled = function(self, dir)
  230. if self.Can:GetTall() <= self:GetTall() then return end
  231. local x, y = self.Can:GetPos()
  232. self.Can:SetPos(0, math.Clamp(y+dir*math.Round(self:GetTall()*0.15), -self.Can:GetTall()+self:GetTall(), 0))
  233. end
  234. menu.AddItem = function(self, item)
  235. self = pList
  236. local size = #self.Can.Items
  237. if size == MaxMessageHistory then // limit it off at MaxMessageHistory messages
  238. table.remove(self.Can.Items, 1):Remove()
  239. local itemSize
  240. table.insert(self.Can.Items, item)
  241. item:SetParent(self.Can)
  242.  
  243. local curPos = 0
  244. for i=1, #self.Can.Items do //rebuild positions
  245. itemSize = self.Can.Items[i-1] and self.Can.Items[i-1]:GetTall()+3 or 0
  246. curPos = curPos+itemSize
  247. self.Can.Items[i]:SetPos(0, curPos)
  248. end
  249. local x, y = self.Can.Items[#self.Can.Items]:GetPos()
  250. itemSize = self.Can.Items[#self.Can.Items]:GetTall()
  251. y = y+itemSize
  252.  
  253. local tallsize, ypos = self.Can:GetPos()
  254. tallsize = -self.Can:GetTall()+self:GetTall()
  255. self.Can:SetTall(y)
  256.  
  257. if ypos == tallsize then
  258. self.Can:SetPos(0, -self.Can:GetTall()+self:GetTall())
  259. end
  260.  
  261. return
  262. end
  263. local itemSize = item:GetTall()+3
  264. self.Can:SetTall(self.Can:GetTall() + itemSize)
  265. table.insert(self.Can.Items, item)
  266. item:SetParent(self.Can)
  267. item:SetPos(0, self.Can:GetTall()-itemSize)
  268. local x, y = self.Can:GetPos()
  269.  
  270. if size < 5 or y == -self.Can:GetTall()+self:GetTall()+itemSize then
  271. self.Can:SetPos(0, -self.Can:GetTall()+self:GetTall())
  272. end
  273.  
  274. end
  275.  
  276. local grip = vgui.Create("DButton", menu)
  277. menu.Grip = grip
  278. grip.LowestAlpha = 70
  279. grip.MaxAlpha = 255
  280. grip:SetText("")
  281. grip:SetSize(6, 20)
  282. grip:SetPos(20, pList:GetWide()-20)
  283. grip.Think = function(self)
  284. self:SetAlpha(!NewChatIsOpen and 0 or (!self.Hovered and !self.Holding) and self.LowestAlpha or self.MaxAlpha)
  285.  
  286. local Cx, Cy = pList.Can:GetPos()
  287. local gripSize = math.Clamp(pList:GetTall()/pList.Can:GetTall()*(pList:GetTall()-4), 20, (pList:GetTall()-4))
  288. local trackScrollAreaSize = pList:GetTall()-4 - gripSize
  289.  
  290. if self.Holding and !input.IsMouseDown(MOUSE_LEFT) then
  291. self.Holding = false
  292. elseif self.Holding and Cy<1 then
  293. local mPosDelta = self.LastMouseY - gui.MouseY()
  294. local x, y = pList.Can:GetPos()
  295. pList.Can:SetPos(0, math.Clamp(y+mPosDelta*(trackScrollAreaSize/gripSize), -pList.Can:GetTall()+pList:GetTall(), 0))
  296. end
  297.  
  298. local windowScrollAreaSize = pList:GetTall() - pList.Can:GetTall()
  299. local windowPositionRatio = Cy/windowScrollAreaSize
  300. local gripPositionOnTrack = trackScrollAreaSize * windowPositionRatio
  301. grip:SetSize(10, gripSize)
  302. self:SetPos(menu:GetWide()-12, gripPositionOnTrack+2)
  303.  
  304. self.LastMouseY = gui.MouseY()
  305. end
  306. grip.OnMousePressed = function(self) self.Holding = true end
  307. grip.OnCursorEntered = function(self) self.Hovered = true end
  308. grip.OnCursorExited = function(self) self.Hovered = false end
  309.  
  310. if SkinTable[SkinType].Init then
  311. SkinTable[SkinType].Init(menu)
  312. end
  313. end
  314. timer.Simple(0, OpenChat)
  315.  
  316. local ignoreNotify
  317. function chat.IgnoreNextNotify() // USE: call this before when you don't want chat.AddText to trigger player name to player entity convertion
  318. ignoreNotify = true // for ex. when chat.AddText("[OOC]TOMASAS", Color(1,2,3), ":blabla") turns to ("[OOC]", plyEntity, ...)
  319. end
  320.  
  321. chat.AddText = function(...) // USE: chat.AddText( [Icon IMaterial], Any arguments )
  322. if !menu then return end // so dumb scripts can't add text before Derma and chat is loaded
  323. local TextTable, TextPosX, TextPosY, NoFirstPlayer, icon, avatar = {...}, 0, 0
  324. local type1 = type(TextTable[1])
  325. if type1 == "IMaterial" then
  326. icon = TextTable[1]
  327. TextPosX = 17
  328. table.remove(TextTable, 1)
  329. NoFirstPlayer = true
  330. end
  331. if !ignoreNotify and (ShowIconsForPlayers or EnableRankGlow) and type(TextTable[2]) == "string" then // slight hack for non-player object player chat, shooting names instead of players
  332. local tbl = player.GetAll()
  333. for i=1, #tbl do
  334. local nick = tbl[i]:Nick()
  335. local placeFound = string.find(TextTable[2], nick, 1, true)
  336. if placeFound then
  337. local part1 = string.Replace(TextTable[2], nick, "")
  338. local part2 = part1:sub(placeFound)
  339. part1 = part1:sub(1, placeFound-1)
  340. table.insert(TextTable, 2, part1)
  341. TextTable[3] = tbl[i]
  342. if part2 != "" then
  343. if type(TextTable[1]) == "table" then
  344. table.insert(TextTable, 4, TextTable[1])
  345. table.insert(TextTable, 5, part2)
  346. else
  347. table.insert(TextTable, 4, part2)
  348. end
  349. end
  350. break
  351. end
  352. end
  353. end
  354. if ShowTimeStamps then
  355. table.insert(TextTable, 1, os.date("%H:%M "))
  356. end
  357. local i, TextTableNum = 0, #TextTable //take care of player/entity objects + avatar/rank icon if needed
  358. while i != TextTableNum do
  359. i = i + 1
  360. local t = type(TextTable[i])
  361. if t == "Player" then
  362. if EnableRankGlow then // insert rank labels with a glow table if needed
  363. for k,v in pairs(RankGlowUserGroups) do
  364. if TextTable[i]:IsUserGroup(k) then
  365. table.insert(TextTable, i, "[")
  366. table.insert(TextTable, i+1, v)
  367. table.insert(TextTable, i+2, "] ")
  368. i = i + 3
  369. TextTableNum = TextTableNum + 3
  370. break
  371. end
  372. end
  373. end
  374. table.insert(TextTable, i+1, TextTable[i]:Nick())
  375. TextTableNum = TextTableNum + 1
  376. if !NoFirstPlayer and ShowIconsForPlayers then
  377. if ShowPlayerAvatars then
  378. avatar = vgui.Create("AvatarImage")
  379. avatar:SetPlayer(TextTable[i], 16)
  380. avatar:SetSize(16, 16)
  381. TextPosX = 17
  382. elseif ShowPlayerRanks then
  383. if TextTable[i]:IsSuperAdmin() then
  384. icon = SuperAdminIcon
  385. elseif TextTable[i]:IsAdmin() then
  386. icon = AdminIcon
  387. elseif TextTable[i]:IsUserGroup("owner") then
  388. icon = OwnerIcon
  389. else
  390. icon = DefaultUserIcon
  391. end
  392. TextPosX = 17
  393. end
  394. NoFirstPlayer = true
  395. end
  396. TextTable[i] = team.GetColor(TextTable[i]:Team())
  397. i = i + 1
  398. elseif t != "string" and t != "table" then
  399. if TextTable[i].IsValid and TextTable[i]:IsValid() then
  400. TextTable[i] = TextTable[i]:GetClass()
  401. else
  402. TextTable[i] = "NULL"
  403. end
  404. end
  405. end
  406. if EnableChatColorTags then // take care of color tags
  407. local noTagsLeft
  408. while !noTagsLeft do
  409. local foundTag
  410. for i=1, #TextTable do
  411. if type(TextTable[i]) == "string" then//ChatColorTags
  412. for k, v in pairs(ChatColorTags) do
  413. local pos = string.find(TextTable[i], k, 1, true)
  414. if pos then
  415. local str1, str2 = TextTable[i]:sub(1, pos-1), TextTable[i]:sub(pos+k:len())
  416. TextTable[i] = str1
  417. table.insert(TextTable, i+1, v)
  418. table.insert(TextTable, i+2, str2)
  419. foundTag = true
  420. break
  421. end
  422. end
  423. end
  424. end
  425. noTagsLeft = !foundTag
  426. end
  427. end
  428.  
  429. local FinalText = {}
  430. local windowSizeX = 320 * (ScrH()/480)-4 //4 is the padding offset
  431.  
  432. surface.SetFont("ChatTextNormal")
  433. local _, tall = surface.GetTextSize("AbC1230")
  434. TextTableNum = #TextTable
  435. local pos = 0
  436. local LineText = ""
  437. local LastColor = Color(255, 255, 255, 255)
  438. while pos != TextTableNum do
  439. pos = pos + 1
  440. if type(TextTable[pos]) == "table" and type(TextTable[pos][2]) == "table" then // glow table
  441. local text = TextTable[pos][1]
  442. local x, y = surface.GetTextSize(text)
  443. table.insert(FinalText, {text, TextPosX, TextPosY, TextTable[pos][2], 1})
  444. TextPosX = TextPosX + x
  445. else // color or text
  446. while type(TextTable[pos]) == "table" do
  447. LastColor = Color(TextTable[pos].r, TextTable[pos].g, TextTable[pos].b, TextTable[pos].a)
  448. pos = pos + 1
  449. end
  450. local text = TextTable[pos]
  451. local x, y = surface.GetTextSize(text)
  452.  
  453. if TextPosX + x >= windowSizeX then
  454. local startpos, t, t2, size = #FinalText
  455. for line in (text):gmatch("[^%s]+") do //wordwrap
  456. if t then
  457. t2 = table.concat({t, line}, " ")
  458. else
  459. t2 = line
  460. t = ""
  461. end
  462. size = surface.GetTextSize(t2)
  463. if TextPosX + size >= windowSizeX then
  464. table.insert(FinalText, {t, TextPosX, TextPosY, LastColor})
  465. TextPosX = 0
  466. TextPosY = TextPosY + tall
  467. t = line
  468. else
  469. t = t2
  470. end
  471. end
  472. table.insert(FinalText, {t, TextPosX, TextPosY, LastColor})
  473. //FinalText[startpos][1] = string.sub(FinalText[startpos][1], 2)
  474. size = surface.GetTextSize(t2)
  475. TextPosX = TextPosX + size
  476. else
  477. table.insert(FinalText, {text, TextPosX, TextPosY, LastColor})
  478. TextPosX = TextPosX + x
  479. end
  480.  
  481. end
  482.  
  483. end
  484.  
  485. local ListItem = vgui.Create("DPanel", menu.pList)
  486. ListItem.IsChatTextPanel = true
  487. if avatar then
  488. ListItem.Avatar = avatar
  489. avatar:SetParent(ListItem)
  490. avatar:SetPos(4, 5)
  491. else
  492. ListItem.Icon = icon
  493. end
  494. ListItem.CreateTime = CurTime()+MessageFadeoutTime
  495. ListItem.Text = FinalText
  496. ListItem:SetSize(menu.pList:GetWide(), TextPosY+tall)
  497. ListItem.Paint = PanelPaint
  498. ListItem:SetPaintBackground(false)
  499. local TextTable = {}
  500. for i=1, #FinalText do
  501. local len = FinalText[i][1]:len()
  502. local TextX, TextY = FinalText[i][2], FinalText[i][3]
  503. for a=1, len do
  504. local x = surface.GetTextSize(FinalText[i][1][a])
  505. TextX = TextX + x
  506. table.insert(TextTable, {FinalText[i][1][a], TextX, TextY})
  507. end
  508. end
  509. ListItem.TextTable = TextTable
  510. menu:AddItem(ListItem)
  511.  
  512. if PrintChatToConsole then
  513. local pack, a = {}, 0
  514.  
  515. for i=1, #FinalText do
  516. a = a + 1
  517. pack[a] = FinalText[i][4]
  518. a = a + 1
  519. pack[a] = FinalText[i][1]
  520. end
  521. pack[a+1] = "\n"
  522. MsgC(unpack(pack))
  523. end
  524.  
  525. ignoreNotify = false
  526.  
  527. end
  528.  
  529. local MousePressedX, MousePressedY, MouseReleasedX, MouseReleasedY, SelectedChatMsg, SelectingText
  530. local function MousePress()
  531. local pan = vgui.GetHoveredPanel()
  532. if !pan or !pan.IsChatTextPanel then return end
  533. MousePressedX, MousePressedY = pan:CursorPos()
  534. SelectedChatMsg = pan
  535. SelectingText = true
  536. end
  537. local function MouseRelease()
  538. SelectingText = false
  539. local pan = vgui.GetHoveredPanel()
  540. if !pan or !pan.IsChatTextPanel then return end
  541. MouseReleasedX, MouseReleasedY = pan:CursorPos()
  542. end
  543. local mouseDown
  544. local function ChatThink() // GUIMousePressed/Released hooks are both broken, thanks garry :^) (aren't called when pressed on chat)
  545. local down = input.IsMouseDown(MOUSE_LEFT)
  546. if down and !mouseDown then
  547. MousePress()
  548. mouseDown = true
  549. elseif !down and mouseDown then
  550. MouseRelease()
  551. mouseDown = false
  552. elseif !down and !mouseDown and SelectedChatMsg and input.IsMouseDown(MOUSE_RIGHT) then
  553. SelectedChatMsg = nil
  554. elseif SelectedChatMsg and SelectedChatMsg:IsValid() and input.IsKeyDown(KEY_LCONTROL) and input.IsKeyDown(KEY_C) then
  555. local str = ""
  556. for i=1, #SelectedChatMsg.TextTable do
  557. if SelectedChatMsg.TextTable[i][4] then
  558. str = table.concat({str, SelectedChatMsg.TextTable[i][1]}, "")
  559. end
  560. end
  561. SetClipboardText(str)
  562. end
  563. end
  564.  
  565. function PanelPaint(self)
  566. local curtime = CurTime()
  567. local a = self.CreateTime - curtime <= 1 and (self.CreateTime-curtime)*255 or 255
  568. if a < 0 then return end
  569.  
  570. if SelectedChatMsg == self then
  571. if SelectingText then
  572. MouseReleasedX, MouseReleasedY = self:CursorPos()
  573. for i=1, #self.TextTable do
  574. if (MousePressedX < self.TextTable[i][2] and MousePressedY-Ftall <= self.TextTable[i][3] and MouseReleasedY-Ftall > self.TextTable[i][3]) or (MousePressedX <= self.TextTable[i][2] and MouseReleasedX >= self.TextTable[i][2] and MousePressedY-Ftall < self.TextTable[i][3] and MouseReleasedY > self.TextTable[i][3]) or (MousePressedY <= Ftall and MouseReleasedY > Ftall and self.TextTable[i][3] >= Ftall and self.TextTable[i][3] <= Ftall and MouseReleasedX>=self.TextTable[i][2]) then
  575. self.TextTable[i][4] = true
  576. else
  577. self.TextTable[i][4] = nil
  578. end
  579. end
  580. end
  581. local lines = self.TextTable[#self.TextTable][3]/Ftall + 1
  582. surface.SetDrawColor(ChatHighlightColor)
  583. for i=1, lines do
  584. local xsize, x, start = 0, 0
  585. for a=1, #self.TextTable do
  586. if self.TextTable[a][4] and self.TextTable[a][3] == i*Ftall-Ftall then
  587. x = a== 1 and 4 or x == 0 and self.TextTable[a][2]-4 or x
  588. xsize = self.TextTable[a][2]-x+4
  589. end
  590. end
  591. surface.DrawRect(x, Ftall*i-Ftall, xsize, Ftall)
  592. end
  593. end
  594.  
  595. if self.Icon then
  596. surface.SetDrawColor(255, 255, 255, a)
  597. surface.SetMaterial(self.Icon)
  598. surface.DrawTexturedRect(4, 5, 16, 16)
  599. elseif self.Avatar then
  600. self.Avatar:SetAlpha(a)
  601. end
  602. for i=1, #self.Text do
  603. self.Text[i][4].a = a
  604. if self.Text[i][5] then // glow table
  605. local pulse = math.cos(curtime*2)*127.5+127.5
  606. pulse = pulse <= a and pulse or a
  607. draw.SimpleTextOutlined(self.Text[i][1], "ChatTextNormal", 4+self.Text[i][2], self.Text[i][3], self.Text[i][4], 0, 0, RankLabelGlowSize, Color(self.Text[i][4].r, self.Text[i][4].g, self.Text[i][4].b, pulse))
  608. else // just text
  609. draw.SimpleTextOutlined(self.Text[i][1], "ChatTextNormal", 4+self.Text[i][2], self.Text[i][3], self.Text[i][4], 0, 0, 0.5, Color(black.r, black.g, black.b, a))
  610. end
  611. end
  612. end
  613.  
  614. local cfg// hackish~ fix for options not going away, I blame derma
  615. local function ConfigButton(teamSay)
  616. if cfg and cfg:IsValid() then cfg:Remove() cfg = nil end
  617. cfg = vgui.Create("DButton")
  618. menu.CFG = cfg
  619. cfg:SetSize(20, 20)
  620. local x, y = menu.Entry:GetPos()
  621. cfg:SetPos(x-20, y)
  622. cfg:SetText("")
  623. cfg.Paint = function(self, x, y) SkinTable[SkinType].GearPaint(teamSay, self, x, y) end
  624. cfg.DoClick = function(self)
  625. if self.CFGPanel and self.CFGPanel:IsValid() then self.CFGPanel:Remove() return end
  626. local panel = vgui.Create("DPanel")
  627. panel:SetPos(x-20, y+20)
  628. local x, y = menu.Entry:GetSize()
  629. panel:SetSize(x+20, 25)
  630. self.CFGPanel = panel
  631. local oldRemove = self.Remove //hacky, derma sucks anyway
  632. self.Remove = function() self.CFGPanel:Remove() oldRemove(self) end
  633. panel.Paint = function(self)
  634. surface.SetDrawColor(255, 255, 255, 255)
  635. surface.DrawRect(0, 0, self:GetWide(), self:GetTall())
  636. draw.SimpleText("Show info icons", "Default", 22, 6, Color(0, 0, 0, 255))
  637. draw.SimpleText("Show player icons", "Default", 157, 6, Color(0, 0, 0, 255))
  638. draw.SimpleText("Show timestamps", "Default", 293, 6, Color(0, 0, 0, 255))
  639. draw.SimpleText("Scroll chat down on close", "Default", 428, 6, Color(0, 0, 0, 255))
  640. end
  641. local CB1 = vgui.Create("DCheckBox", panel)
  642. CB1:SetPos(5, 5)
  643. CB1:SetValue(toBit(ShowMessageIcons))
  644. CB1.OnChange = function(self, state)
  645. ShowMessageIcons = state
  646. SaveChatConfig()
  647. end
  648. local CB2 = vgui.Create("DCheckBox", panel)
  649. CB2:SetPos(140, 5)
  650. CB2:SetValue(toBit(ShowIconsForPlayers))
  651. CB2.OnChange = function(self, state)
  652. ShowIconsForPlayers = state
  653. SaveChatConfig()
  654. end
  655. local CB3 = vgui.Create("DCheckBox", panel)
  656. CB3:SetPos(275, 5)
  657. CB3:SetValue(toBit(ShowTimeStamps))
  658. CB3.OnChange = function(self, state)
  659. ShowTimeStamps = state
  660. SaveChatConfig()
  661. end
  662. local CB4 = vgui.Create("DCheckBox", panel)
  663. CB4:SetPos(410, 5)
  664. CB4:SetValue(toBit(ScrollDownWhenTurnedOff))
  665. CB4.OnChange = function(self, state)
  666. ScrollDownWhenTurnedOff = state
  667. SaveChatConfig()
  668. end
  669.  
  670. end
  671.  
  672. end
  673.  
  674. hook.Add("PlayerBindPress", "NewChatText", function(ply, bind, press)
  675. if bind == "messagemode" or bind == "messagemode2" then
  676. if press then
  677. local teamSay = bind == "messagemode2"
  678. hook.Call("StartChat", GAMEMODE, teamSay)
  679. local entry = vgui.Create("DTextEntry")
  680. local chatx, chaty = menu:GetPos()
  681. entry:SetAllowNonAsciiCharacters(true)
  682. entry:SetPos(chatx+20, chaty+menu:GetTall()-20)
  683. entry:SetSize(menu:GetWide()-20, 20)
  684. menu.Entry = entry
  685. menu.Entry.Paint = SkinTable[SkinType].EntryPaint
  686. menu.Entry.OnTextChanged = function(self)
  687. if self:GetValue():len() > 126 then
  688. self:SetText(self:GetValue():sub(1, 126))
  689. self:SetCaretPos(126)
  690. surface.PlaySound("/resource/warning.wav")
  691. end
  692. hook.Call("ChatTextChanged", GAMEMODE, self:GetValue())
  693. end
  694. menu.Entry.OnEnter = function(self)
  695. local txt = self:GetValue()
  696. RunConsoleCommand(!teamSay and "say" or "say_team", txt)
  697. self:SetText("")
  698. hook.Call("FinishChat", GAMEMODE)
  699. SelectedChatMsg = nil
  700. menu.CFG:Remove()
  701. self:Remove()
  702. end
  703. menu.Entry.OnKeyCodeTyped = function(self, key)
  704. if key == KEY_ESCAPE then
  705. hook.Call("FinishChat", GAMEMODE)
  706. SelectedChatMsg = nil
  707. menu.CFG:Remove()
  708. menu.Entry:Remove()
  709. gui.HideGameUI()
  710. elseif key == KEY_ENTER then
  711. self:OnEnter()
  712. end
  713. end
  714. ConfigButton(teamSay)
  715. menu.Entry:MakePopup()
  716. menu.Entry:SetKeyboardInputEnabled(true)
  717. menu.Entry:RequestFocus()
  718. local x, y =menu.Entry:GetPos()
  719. gui.SetMousePos(x, y+20)
  720. end
  721. return true
  722. end
  723. end)
  724.  
  725. hook.Add("ChatText", "NewChatText", function(id, name, str, stype)
  726. chat.IgnoreNextNotify() //need to escape and tell it's a notify, Player.ChatPrint and alike won't trigger player name matching and mess up
  727. if ShowMessageIcons then
  728. chat.AddText(InfoMessageIcon, stype=="joinleave" and Color(161, 255, 161) or Color(151, 211, 255), str)
  729. else
  730. chat.AddText(stype=="joinleave" and Color(161, 255, 161) or Color(151, 211, 255), str)
  731. end
  732. return true
  733. end)
  734. hook.Add("HUDShouldDraw", "DisableDefaultChat", function(t) if t=="CHudChat" then return false end end )
  735. hook.Add("StartChat", "NewChatIsOpen", function() NewChatIsOpen = true end)
  736. hook.Add("FinishChat", "NewChatIsOpen", function()
  737. NewChatIsOpen = false
  738. if ScrollDownWhenTurnedOff then
  739. menu.pList.Can:SetPos(0, -menu.pList.Can:GetTall()+menu.pList:GetTall())
  740. end
  741. end)
  742. hook.Add("Think", "NewChatThink", ChatThink)
  743. //©Tomasas 2013-2015[/code]
Advertisement
Add Comment
Please, Sign In to add comment