-- SCRIPT DE TORNADOS COMBINADOS (MENOR NO INÍCIO + MAIOR APÓS 5 MINUTOS) local Players = game:GetService("Players") local RunService = game:GetService("RunService") local LocalPlayer = Players.LocalPlayer local Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait() local RootPart = Character:WaitForChild("HumanoidRootPart") local ID_SOM = "rbxassetid://123731555496199" -- FUNÇÃO GERADORA DE TORNADO local function criarTornado(config) local ALCANCE_SUCCAO = config.AlcanceSuccao or 50 local FORCA_PUXAO = config.ForcaPuxao or 10 local VELOCIDADE_TORNADO = config.Velocidade or 8 local ALTURA_NUVENS = config.AlturaNuvens or 350 local DISTANCIA_SPAWN = config.DistanciaSpawn or 80 local LARGURA_BASE = config.LarguraBase or 12 local LARGURA_TOPO = config.LarguraTopo or 200 local QTD_BLOCOS = config.QtdBlocos or 6 -- 1. Base do Tornado local posicaoInicial = RootPart.CFrame * CFrame.new(0, 0, -DISTANCIA_SPAWN) local baseTornado = Instance.new("Part") baseTornado.Name = config.Nome or "BaseTornado" baseTornado.Size = Vector3.new(20, 1, 20) baseTornado.CFrame = CFrame.new(posicaoInicial.Position) baseTornado.Anchored = true baseTornado.CanCollide = false baseTornado.Transparency = 1 baseTornado.Parent = workspace -- 2. Som em Loop local somTornado = Instance.new("Sound") somTornado.Name = "SomTornado" somTornado.SoundId = ID_SOM somTornado.Volume = config.Volume or 2 somTornado.Looped = true somTornado.RollOffMaxDistance = config.DistanciaSom or 500 somTornado.RollOffMinDistance = 20 somTornado.Parent = baseTornado somTornado:Play() -- 3. Nuvens no Céu local nuvemSky = Instance.new("Part") nuvemSky.Size = Vector3.new(1, 1, 1) nuvemSky.Anchored = true nuvemSky.CanCollide = false nuvemSky.Transparency = 1 nuvemSky.CFrame = baseTornado.CFrame * CFrame.new(0, ALTURA_NUVENS, 0) nuvemSky.Parent = workspace local attachmentNuvem = Instance.new("Attachment", nuvemSky) local emissorNuvem = Instance.new("ParticleEmitter", attachmentNuvem) emissorNuvem.Texture = "rbxasset://textures/particles/smoke_main.dds" emissorNuvem.Rate = config.TaxaFumaca or 150 emissorNuvem.Lifetime = NumberRange.new(6, 10) emissorNuvem.Speed = NumberRange.new(15, 30) emissorNuvem.SpreadAngle = Vector2.new(180, 180) emissorNuvem.Color = ColorSequence.new(Color3.fromRGB(170, 170, 180)) emissorNuvem.Size = NumberSequence.new({ NumberSequenceKeypoint.new(0, 60), NumberSequenceKeypoint.new(0.5, 180), NumberSequenceKeypoint.new(1, 250) }) emissorNuvem.Transparency = NumberSequence.new({ NumberSequenceKeypoint.new(0, 0.6), NumberSequenceKeypoint.new(0.5, 0.2), NumberSequenceKeypoint.new(1, 1) }) -- 4. Chuva local emissorChuva = Instance.new("ParticleEmitter", attachmentNuvem) emissorChuva.Texture = "rbxasset://textures/particles/sparkles_main.dds" emissorChuva.Rate = 400 emissorChuva.Lifetime = NumberRange.new(3, 5) emissorChuva.Speed = NumberRange.new(120, 180) emissorChuva.EmissionDirection = Enum.NormalId.Bottom emissorChuva.Acceleration = Vector3.new(0, -200, 0) emissorChuva.Orientation = Enum.ParticleOrientation.VelocityParallel emissorChuva.SpreadAngle = Vector2.new(45, 45) emissorChuva.Color = ColorSequence.new(Color3.fromRGB(180, 210, 255)) emissorChuva.Size = NumberSequence.new({ NumberSequenceKeypoint.new(0, 1), NumberSequenceKeypoint.new(1, 1.5) }) emissorChuva.Transparency = NumberSequence.new({ NumberSequenceKeypoint.new(0, 0.2), NumberSequenceKeypoint.new(1, 0.6) }) -- 5. Corpo do Tornado local attachmentBase = Instance.new("Attachment", baseTornado) local fumacaCorpo = Instance.new("ParticleEmitter", attachmentBase) fumacaCorpo.Texture = "rbxasset://textures/particles/smoke_main.dds" fumacaCorpo.Rate = config.TaxaFumaca or 220 fumacaCorpo.Lifetime = NumberRange.new(6, 9) fumacaCorpo.Speed = NumberRange.new(45, 75) fumacaCorpo.SpreadAngle = Vector2.new(10, 10) fumacaCorpo.Acceleration = Vector3.new(0, 30, 0) fumacaCorpo.Color = ColorSequence.new(Color3.fromRGB(180, 180, 190)) fumacaCorpo.Size = NumberSequence.new({ NumberSequenceKeypoint.new(0, LARGURA_BASE), NumberSequenceKeypoint.new(0.5, LARGURA_TOPO * 0.45), NumberSequenceKeypoint.new(1, LARGURA_TOPO) }) fumacaCorpo.RotSpeed = NumberRange.new(300, 600) -- 6. Blocos Voando local blocosVoadores = {} for i = 1, QTD_BLOCOS do local bloco = Instance.new("Part") bloco.Size = Vector3.new(4, 4, 4) bloco.Color = Color3.fromRGB(180, 150, 120) bloco.Material = Enum.Material.Wood bloco.Anchored = true bloco.CanCollide = false bloco.Parent = workspace table.insert(blocosVoadores, { Objeto = bloco, Altura = math.random(5, 120), Angulo = math.random(0, 360), RaioGiro = math.random(15, 45) }) end -- 7. Movimentação do Tornado local function getNovoDestino() return Vector3.new( baseTornado.Position.X + math.random(-600, 600), posicaoInicial.Position.Y, baseTornado.Position.Z + math.random(-600, 600) ) end local destinoAtual = getNovoDestino() -- 8. Loop Principal (RenderStepped) local tempoSegurando = 0 local noTornado = false local cooldownArremesso = 0 local anguloJogador = 0 local conexao = RunService.RenderStepped:Connect(function(dt) if not baseTornado or not baseTornado.Parent then return end -- Mover base local direcao = (destinoAtual - baseTornado.Position) if direcao.Magnitude < 20 then destinoAtual = getNovoDestino() else local proximaPosicao = baseTornado.Position + (direcao.Unit * VELOCIDADE_TORNADO * dt) baseTornado.CFrame = CFrame.new(proximaPosicao) end nuvemSky.CFrame = baseTornado.CFrame * CFrame.new(0, ALTURA_NUVENS, 0) -- Animação dos blocos for _, dados in ipairs(blocosVoadores) do dados.Angulo = dados.Angulo + (4 * dt) dados.Altura = dados.Altura + (25 * dt) if dados.Altura > 200 then dados.Altura = 5 end local raio = (dados.Altura / 200) * dados.RaioGiro + 10 local x = math.cos(dados.Angulo) * raio local z = math.sin(dados.Angulo) * raio dados.Objeto.CFrame = CFrame.new(baseTornado.Position + Vector3.new(x, dados.Altura, z)) end -- Atração do jogador if RootPart and Character:FindFirstChild("Humanoid") then local posCentro = Vector3.new(baseTornado.Position.X, 0, baseTornado.Position.Z) local posJogador = Vector3.new(RootPart.Position.X, 0, RootPart.Position.Z) local distancia = (posJogador - posCentro).Magnitude if cooldownArremesso > 0 then cooldownArremesso = cooldownArremesso - dt elseif distancia <= ALCANCE_SUCCAO or noTornado then noTornado = true tempoSegurando = tempoSegurando + dt anguloJogador = anguloJogador + (6 * dt) if tempoSegurando < 2 then local raioGiro = (LARGURA_BASE > 20) and 28 or 15 local offsetX = math.cos(anguloJogador) * raioGiro local offsetZ = math.sin(anguloJogador) * raioGiro local alvoX = baseTornado.Position.X + offsetX local alvoZ = baseTornado.Position.Z + offsetZ RootPart.AssemblyLinearVelocity = Vector3.new( (alvoX - RootPart.Position.X) * FORCA_PUXAO, 20, (alvoZ - RootPart.Position.Z) * FORCA_PUXAO ) else local direcaoFora = (RootPart.Position - baseTornado.Position).Unit if direcaoFora.Magnitude == 0 then direcaoFora = Vector3.new(math.random(-1,1), 0, math.random(-1,1)).Unit end local forcaArremesso = (LARGURA_BASE > 20) and 220 or 180 RootPart.AssemblyLinearVelocity = (direcaoFora * forcaArremesso) + Vector3.new(0, 120, 0) noTornado = false tempoSegurando = 0 cooldownArremesso = 3 end else tempoSegurando = 0 noTornado = false end end end) end -- 1. TORNADO MENOR (SPAWNA NA HORA) print("🌀 Tornado Menor spawnando agora...") criarTornado({ Nome = "TornadoMenor", AlcanceSuccao = 50, ForcaPuxao = 10, Velocidade = 8, AlturaNuvens = 350, DistanciaSpawn = 80, LarguraBase = 12, LarguraTopo = 200, QtdBlocos = 6, Volume = 2, DistanciaSom = 500, TaxaFumaca = 220 }) -- 2. TORNADO MAIOR E GROSSO (SPAWNA A 5 MINUTOS / 300 SEGUNDOS) task.spawn(function() task.wait(300) -- Aguarda 5 minutos print("🌪️ 5 minutos se passaram! Spawnando Tornado Gigante a 300 blocos...") criarTornado({ Nome = "TornadoMaiorGigante", AlcanceSuccao = 90, ForcaPuxao = 20, Velocidade = 8, AlturaNuvens = 350, DistanciaSpawn = 300, LarguraBase = 35, LarguraTopo = 280, QtdBlocos = 8, Volume = 2.5, DistanciaSom = 800, TaxaFumaca = 300 }) end)