kyo_kyo

handler

May 7th, 2025
44
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.96 KB | None | 0 0
  1. local rs = game:GetService("ReplicatedStorage")
  2. local ts = game:GetService("TweenService")
  3. local uis = game:GetService("UserInputService")
  4. local deb = game:GetService("Debris")
  5. local col = game:GetService("CollectionService")
  6.  
  7. local plrtalking = false
  8. local closedialogue = false
  9. local talking = false
  10. local whoistalking = nil
  11. local responding = false
  12. local line = nil
  13. local layer = nil
  14. local dialogues = nil
  15. local emotions = {[1] = nil, [2] = nil}
  16. local showing1 = false
  17. local showing2 = false
  18.  
  19. local list = require(rs.Dialogues)
  20. local expressions = rs.Emotions
  21.  
  22. local gui = script.Parent.Parent
  23. local ui = gui.main
  24. local chars = ui.characters
  25. local chr1 = chars.char1
  26. local chr2 = chars.char2
  27. local grad = ui.gradient
  28. local skip = ui.skip
  29. local img = ui.img
  30. local narr = ui.narrate
  31. local msg = ui.msg
  32. local logger = ui.logs
  33. local logs = ui.log
  34. local box = msg.box
  35. local resp = msg.responses
  36. local txt = box.text
  37.  
  38. local exponential = TweenInfo.new(1, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out)
  39.  
  40. gui.Enabled = false
  41. skip.Visible = false
  42. chars.Position = UDim2.fromScale(0, 1)
  43. grad.Position = UDim2.fromScale(1, 1.333)
  44. msg.Position = UDim2.fromScale(0, 1.333)
  45. box.Position = UDim2.fromScale(0.5, 0.5)
  46. resp.Position = UDim2.fromScale(1.2, 0.5)
  47. narr.Visible = false
  48. narr.GroupTransparency = 1
  49. narr.txt.Text = ""
  50. logs.Position = UDim2.new(1.2, -10, 0, 10)
  51. logger.Visible = false
  52.  
  53. logs.MouseButton1Click:Connect(function()
  54. logger.Visible = not logger.Visible
  55.  
  56. if logger.Visible then
  57. logs.Text = "Hide Chatlog"
  58. else
  59. logs.Text = "Show Chatlog"
  60. end
  61. end)
  62.  
  63. for _, chr in pairs(chars:GetChildren()) do
  64. if chr:IsA("ViewportFrame") then
  65. local cam = Instance.new("Camera")
  66. cam.Parent = chr
  67. cam.CFrame = CFrame.new(0, 1, -10) * CFrame.Angles(0, math.rad(-180), 0)
  68. cam.FieldOfView = 40
  69. chr.CurrentCamera = cam
  70. end
  71. end
  72.  
  73. local function createlog(msg, narrating)
  74. local logged = script.logged:Clone()
  75. logged.Parent = logger.scroller
  76. logged.TextSize = math.round((32 / 1080) * gui.AbsoluteSize.Y)
  77.  
  78. if narrating then
  79. logged.Text = msg
  80. else
  81. logged.Text = msg
  82.  
  83. end
  84.  
  85. task.defer(function()
  86. local lwidth = logged.AbsoluteSize.X
  87. local msize = game:GetService("TextService"):GetTextSize(logged.Text, logged.TextSize, logged.Font, Vector2.new(lwidth, math.huge))
  88.  
  89. local count = math.ceil(msize.Y / logged.TextSize)
  90. logged.Size = UDim2.fromScale(1, 0.05 * count)
  91.  
  92. if narrating then
  93. logged.FontFace = Font.new(logged.FontFace.Family, logged.FontFace.Weight, Enum.FontStyle.Italic)
  94. else
  95. logged.FontFace = Font.new(logged.FontFace.Family, logged.FontFace.Weight, Enum.FontStyle.Normal)
  96. end
  97. end)
  98. end
  99.  
  100. local function close()
  101. skip.Visible = false
  102. ts:Create(chars, exponential, {Position = UDim2.fromScale(0, 1)}):Play()
  103. ts:Create(grad, exponential, {Position = UDim2.fromScale(1, 1.333)}):Play()
  104. ts:Create(msg, exponential, {Position = UDim2.fromScale(0, 1.333)}):Play()
  105. ts:Create(box, exponential, {Position = UDim2.fromScale(0.5, 0.5)}):Play()
  106. ts:Create(resp, exponential, {Position = UDim2.fromScale(1.2, 0.5)}):Play()
  107. ts:Create(logs, exponential, {Position = UDim2.new(1.2, -10, 0, 10)}):Play()
  108. task.wait(1)
  109. gui.Enabled = false
  110. logs.Visible = false
  111. dialogues = nil
  112. plrtalking = false
  113. closedialogue = false
  114. talking = false
  115. responding = false
  116. line = nil
  117. layer = nil
  118. dialogues = nil
  119. emotions = {[1] = nil, [2] = nil}
  120. chr1:SetAttribute("Character", nil)
  121. chr2:SetAttribute("Character", nil)
  122.  
  123. for _, emotion in pairs(chars:GetDescendants()) do
  124. if emotion:IsA("Model") and not emotion:IsA("WorldModel") then
  125. emotion:Destroy()
  126. end
  127. end
  128.  
  129. for _, response in pairs(resp:GetChildren()) do
  130. if response:IsA("Frame") then
  131. response:Destroy()
  132. end
  133. end
  134.  
  135. for _, log in pairs(logger.scroller:GetChildren()) do
  136. if log:IsA("TextLabel") then
  137. log:Destroy()
  138. end
  139. end
  140. end
  141.  
  142. local function chartoggle()
  143. if showing1 and showing2 then
  144. ts:Create(chr1, exponential, {Size = UDim2.fromScale(0.5, 1)}):Play()
  145. ts:Create(chr2, exponential, {Size = UDim2.fromScale(0.5, 1)}):Play()
  146. elseif showing1 then
  147. ts:Create(chr1, exponential, {Size = UDim2.fromScale(1, 1)}):Play()
  148. ts:Create(chr2, exponential, {Size = UDim2.fromScale(0, 1)}):Play()
  149. elseif showing2 then
  150. ts:Create(chr1, exponential, {Size = UDim2.fromScale(0, 1)}):Play()
  151. ts:Create(chr2, exponential, {Size = UDim2.fromScale(1, 1)}):Play()
  152. end
  153. end
  154.  
  155. local function sfx(pitch)
  156. local clone = script.talk:Clone()
  157. clone.Parent = script
  158. clone.PitchShiftSoundEffect.Octave = (pitch + (math.random() * 0.1 - 0.05)) / 2
  159. clone.Volume += (math.random() * 0.1 - 0.05)
  160. clone:Play()
  161. deb:AddItem(clone, clone.TimeLength / 2)
  162. end
  163.  
  164. local function playertalk(str)
  165. txt.FontFace.Weight = Enum.FontWeight.Regular
  166. txt.TextSize = 32
  167. txt.TextColor3 = Color3.fromRGB(255, 255, 255)
  168.  
  169. plrtalking = true
  170. txt.Text = str
  171. txt.MaxVisibleGraphemes = 0
  172.  
  173. createlog("You: "..str, false)
  174.  
  175. for i = 0, string.len(str) do
  176. if not plrtalking then
  177. txt.MaxVisibleGraphemes = #str
  178. break
  179. end
  180.  
  181. sfx(1.25)
  182. txt.MaxVisibleGraphemes += 1
  183. task.wait(0.02)
  184. end
  185.  
  186. plrtalking = false
  187. end
  188.  
  189. local function btnhandler(btn)
  190. if btn:IsA("TextButton") then
  191. btn.MouseEnter:Connect(function()
  192. ts:Create(btn.Parent.txt, exponential, {Position = UDim2.fromScale(0.55, 0.5)}):Play()
  193. end)
  194.  
  195. btn.MouseLeave:Connect(function()
  196. btn.Parent.txt.TextColor3 = Color3.fromRGB(255, 255, 255)
  197. ts:Create(btn.Parent.txt, exponential, {
  198. Position = UDim2.fromScale(0.5, 0.5),
  199. }):Play()
  200. end)
  201.  
  202. btn.MouseButton1Down:Connect(function()
  203. btn.Parent.txt.TextColor3 = Color3.fromRGB(160, 160, 160)
  204. end)
  205.  
  206. btn.MouseButton1Up:Connect(function()
  207. btn.Parent.txt.TextColor3 = Color3.fromRGB(255, 255, 255)
  208. end)
  209.  
  210. btn.MouseButton1Click:Connect(function()
  211. responding = false
  212. ts:Create(box, exponential, {Position = UDim2.fromScale(0.5, 0.5)}):Play()
  213. ts:Create(resp, exponential, {Position = UDim2.fromScale(1.2, 0.5)}):Play()
  214. local prevline = line
  215. line = 0
  216.  
  217. local rlayer = dialogues.messages[layer][prevline].respond
  218. local rdata = dialogues.responses[rlayer][tonumber(btn.Parent.Name)]
  219.  
  220. if rdata.msg == "" then
  221. close()
  222. return
  223. end
  224.  
  225. skip.Visible = true
  226. box.character.Text = "You"
  227. playertalk(rdata.msg)
  228. layer = rdata.display
  229.  
  230. for _, response in pairs(resp:GetChildren()) do
  231. if response:IsA("Frame") then
  232. response:Destroy()
  233. end
  234. end
  235. end)
  236. end
  237. end
  238.  
  239. local function respond()
  240. responding = true
  241. skip.Visible = false
  242.  
  243. ts:Create(box, exponential, {Position = UDim2.fromScale(0.355, 0.5)}):Play()
  244. ts:Create(resp, exponential, {Position = UDim2.fromScale(0.81, 0.5)}):Play()
  245.  
  246. for k, v in ipairs(dialogues.responses[dialogues.messages[layer][line].respond]) do
  247. local clone = script.option:Clone()
  248. clone.Name = k
  249. clone.keybind.Text = k
  250. clone.txt.Text = v.btntxt
  251. clone:SetAttribute("Message", v.msg)
  252. clone.Parent = resp
  253. btnhandler(clone.btn)
  254. end
  255. end
  256.  
  257. local function typewriter(str, spe, msg, char)
  258. if plrtalking then return end
  259.  
  260. talking = true
  261. txt.Text = str
  262. txt.MaxVisibleGraphemes = 0
  263. txt.FontFace.Weight = msg == 3 and Enum.FontWeight.Light or msg == 2 and Enum.FontWeight.Bold or Enum.FontWeight.Regular
  264. txt.TextSize = msg == 3 and 24 or msg == 2 and 48 or 32
  265. txt.TextColor3 = msg == 3 and Color3.fromRGB(160, 160, 160) or Color3.fromRGB(255, 255, 255)
  266. local pitch = dialogues.configs.vocalranges[char]
  267. pitch = msg == 2 and pitch + 0.2 or msg == 3 and pitch - 0.2 or pitch
  268.  
  269. createlog(box.character.Text..": "..str, false)
  270.  
  271. for i = 0, string.len(str) do
  272. if not talking then
  273. txt.MaxVisibleGraphemes = #str
  274. break
  275. end
  276.  
  277. sfx(pitch)
  278. txt.MaxVisibleGraphemes += 1
  279. task.wait(spe)
  280. end
  281.  
  282. talking = false
  283.  
  284. if dialogues.messages[layer][line].autoskip then
  285. line += 1
  286. showline()
  287. end
  288.  
  289. if dialogues.messages[layer][line].respond then
  290. respond()
  291. end
  292. end
  293.  
  294. local function emotionchange(num, char, new)
  295. if emotions[num] == new then return end
  296. if expressions[char:GetAttribute("Character")][new] then emotions[num] = new end
  297.  
  298. for _, chr in pairs(char.WorldModel:GetChildren()) do
  299. chr:PivotTo(CFrame.new(0, -10, 0))
  300. end
  301.  
  302. char.WorldModel:FindFirstChild(new):PivotTo(CFrame.identity)
  303.  
  304. char.Position = UDim2.fromScale(char.Position.X.Scale, 0.05)
  305. ts:Create(char, exponential,
  306. {Position = UDim2.fromScale(char.Position.X.Scale, 0)}
  307. ):Play()
  308. end
  309.  
  310. function showline()
  311. if plrtalking then return end
  312.  
  313. local closing = false
  314. local current = dialogues.messages[layer][line]
  315.  
  316. if current.exit then
  317. closing = true
  318. end
  319.  
  320. if current.imgdisplay then
  321. ts:Create(ui, TweenInfo.new(0.25), {GroupColor3 = Color3.fromRGB(0, 0, 0)}):Play()
  322. task.delay(0.25, function()
  323. img.Image = current.imgdisplay
  324. img.Visible = true
  325. ts:Create(ui, TweenInfo.new(1), {GroupColor3 = Color3.fromRGB(255, 255, 255)}):Play()
  326. end)
  327. end
  328.  
  329. if current.imagehide then
  330. ts:Create(ui, TweenInfo.new(0.25), {GroupColor3 = Color3.fromRGB(0, 0, 0)}):Play()
  331. task.delay(0.25, function()
  332. img.Image = ""
  333. img.Visible = false
  334. ts:Create(ui, TweenInfo.new(1), {GroupColor3 = Color3.fromRGB(255, 255, 255)}):Play()
  335. end)
  336. end
  337.  
  338. if current.narrate then
  339. if narr.txt.Text == "" then
  340. narr.GroupTransparency = 1
  341. narr.Visible = true
  342. ts:Create(narr, TweenInfo.new(0.1), {GroupTransparency = 0}):Play()
  343. task.wait(0.1)
  344.  
  345. narr.txt.Text = current.narrate
  346. narr.txt.MaxVisibleGraphemes = 0
  347.  
  348. createlog(current.narrate, true)
  349.  
  350. for i = 0, string.len(narr.txt.Text) do
  351. narr.txt.MaxVisibleGraphemes += 1
  352. task.wait(0.025)
  353. end
  354. else
  355. for i = string.len(narr.txt.Text), 0 do
  356. narr.txt.MaxVisibleGraphemes -= 1
  357. task.wait(0.02)
  358. end
  359.  
  360. narr.txt.Text = current.narrate
  361.  
  362. createlog(current.narrate, true)
  363.  
  364. for i = 0, string.len(narr.txt.Text) do
  365. narr.txt.MaxVisibleGraphemes += 1
  366. task.wait(0.025)
  367. end
  368. end
  369. if closing then
  370. closedialogue = true
  371. return
  372. end
  373. return
  374. else
  375. if narr.Visible then
  376. ts:Create(narr, TweenInfo.new(0.1), {GroupTransparency = 1}):Play()
  377. task.wait(0.1)
  378.  
  379. narr.Visible = false
  380. narr.txt.Text = ""
  381. end
  382. end
  383.  
  384. if current.show1 then
  385. showing1 = true
  386. end
  387.  
  388. if current.show2 then
  389. showing2 = true
  390. end
  391.  
  392. if current.hide1 then
  393. showing1 = false
  394. end
  395.  
  396. if current.hide2 then
  397. showing2 = false
  398. end
  399.  
  400. if showing1 and showing2 then
  401. ts:Create(chr1, exponential, {Size = UDim2.fromScale(0.5, 1)}):Play()
  402. ts:Create(chr2, exponential, {Size = UDim2.fromScale(0.5, 1)}):Play()
  403. elseif showing1 then
  404. ts:Create(chr1, exponential, {Size = UDim2.fromScale(1, 1)}):Play()
  405. ts:Create(chr2, exponential, {Size = UDim2.fromScale(0, 1)}):Play()
  406. elseif showing2 then
  407. ts:Create(chr1, exponential, {Size = UDim2.fromScale(0, 1)}):Play()
  408. ts:Create(chr2, exponential, {Size = UDim2.fromScale(1, 1)}):Play()
  409. end
  410.  
  411. if current.event then
  412. if current.event:IsA("RemoteEvent") then
  413. current.event:FireServer()
  414. elseif current.event:IsA("BindableEvent") then
  415. current.event:Fire()
  416. end
  417. end
  418.  
  419. local talking = current.talking
  420.  
  421. box.character.Text = current.name
  422. emotionchange(1,
  423. chr1,
  424. current.emotion1
  425. )
  426. if chr2:GetAttribute("Character") and dialogues.configs.characters[2] then
  427. emotionchange(2,
  428. chr2,
  429. current.emotion2
  430. )
  431. end
  432.  
  433. typewriter(current.msg, 0.02, current.text, current.talking)
  434.  
  435. if closing then
  436. closedialogue = true
  437. return
  438. end
  439. end
  440.  
  441. local function start()
  442. gui.Enabled = true
  443.  
  444. box.character.Text = dialogues.messages[1][1].name
  445. txt.Text = ""
  446.  
  447. local initem1 = expressions:FindFirstChild(chr1:GetAttribute("Character"))[dialogues.messages[1][1].emotion1]:Clone()
  448. local initem2
  449.  
  450. if chr2:GetAttribute("Character") and expressions:FindFirstChild(chr2:GetAttribute("Character")) then
  451. if dialogues.messages[1][1].emotion2 then
  452. local check = expressions:FindFirstChild(chr2:GetAttribute("Character"))[dialogues.messages[1][1].emotion2]
  453. if check then
  454. initem2 = check:Clone()
  455. end
  456. end
  457. end
  458.  
  459. for _, em:Model in pairs(expressions[chr1:GetAttribute("Character")]:GetChildren()) do
  460. if em:IsA("Model") then
  461. local clone = em:Clone()
  462. clone.Parent = chr1:FindFirstChildOfClass("WorldModel")
  463. clone:PivotTo(CFrame.new(0, -10, 0))
  464. col:AddTag(clone, "Loader")
  465. end
  466. end
  467.  
  468. if initem2 then
  469. for _, em in pairs(expressions[chr2:GetAttribute("Character")]:GetChildren()) do
  470. if em:IsA("Model") then
  471. local clone = em:Clone()
  472. clone.Parent = chr2:FindFirstChildOfClass("WorldModel")
  473. clone:PivotTo(CFrame.new(0, -10, 0))
  474. col:AddTag(clone, "Loader")
  475. end
  476. end
  477. end
  478.  
  479. for _, emotion in pairs(chr1.WorldModel:GetChildren()) do
  480. if emotion:IsA("Model") then
  481. if col:HasTag(emotion, "Loader") then continue end
  482. emotion:Destroy()
  483. end
  484. end
  485.  
  486. initem1.Parent = chr1:FindFirstChildOfClass("WorldModel")
  487. emotions[1] = dialogues.messages[1][1].emotion1
  488.  
  489. if initem2 then
  490. initem2.Parent = chr2:FindFirstChildOfClass("WorldModel")
  491. emotions[2] = dialogues.messages[1][1].emotion2
  492. end
  493.  
  494. task.wait(0.1)
  495.  
  496. ts:Create(chars, exponential, {Position = UDim2.fromScale(0 ,0)}):Play()
  497. ts:Create(grad, exponential, {Position = UDim2.fromScale(1, 1)}):Play()
  498. ts:Create(msg, exponential, {Position = UDim2.fromScale(0, 1)}):Play()
  499. task.wait(1)
  500.  
  501. line = 1
  502. layer = 1
  503. skip.Visible = true
  504.  
  505. ts:Create(logs, exponential, {Position = UDim2.new(1, -10, 0, 10)}):Play()
  506.  
  507. showline()
  508. end
  509.  
  510. local function skipline()
  511. if responding then return end
  512.  
  513. if closedialogue then
  514. close()
  515. return
  516. end
  517.  
  518. if not talking then
  519. if plrtalking then
  520. plrtalking = false
  521. return
  522. else
  523. line = (line or 0) + 1
  524. end
  525. showline()
  526. else
  527. talking = false
  528. end
  529. end
  530.  
  531. skip.MouseButton1Click:Connect(function()
  532. skipline()
  533. end)
  534.  
  535. uis.InputBegan:Connect(function(input, gpr)
  536. if gpr then return end
  537. if not dialogues then return end
  538. if not skip.Visible then return end
  539.  
  540.  
  541. if input.KeyCode == Enum.KeyCode.Space then
  542. skipline()
  543. end
  544. end)
  545.  
  546. rs.start.OnClientEvent:Connect(function(dialogue)
  547. dialogues = list[dialogue]
  548.  
  549. if dialogues.messages[1][1].show1 then
  550. showing1 = true
  551. else
  552. showing1 = false
  553. end
  554.  
  555. if dialogues.messages[1][1].show2 then
  556. showing2 = true
  557. else
  558. showing2 = false
  559. end
  560.  
  561. if showing1 and showing2 then
  562. chr1.Size = UDim2.fromScale(0.5, 1)
  563. chr2.Size = UDim2.fromScale(0.5, 1)
  564. elseif showing1 then
  565. chr1.Size = UDim2.fromScale(1, 1)
  566. chr2.Size = UDim2.fromScale(0, 1)
  567. elseif showing2 then
  568. chr1.Size = UDim2.fromScale(0, 1)
  569. chr2.Size = UDim2.fromScale(1, 1)
  570. end
  571.  
  572. chr1:SetAttribute("Character", dialogues.configs.characters[1])
  573. emotions[1] = dialogues.messages[1][1].emotion1
  574.  
  575. if dialogues.configs.characters[2] then
  576. chr2:SetAttribute("Character", dialogues.configs.characters[2])
  577. emotions[2] = dialogues.messages[1][1].emotion2
  578. end
  579. start()
  580. end)
Advertisement
Add Comment
Please, Sign In to add comment