local Players = game:GetService("Players") local Workspace = game:GetService("Workspace") local Debris = game:GetService("Debris") local LocalPlayer = Players.LocalPlayer local WEAPON_ASSET_ID = 136461991241487 -- ID da Arma 3D local PORTAL_ASSET_ID = 2160656233 -- ID do Portal 3D local TOOL_ICON_ID = 120404128273122 -- Novo ID da Imagem do Ícone no Inventário local TOOL_NAME = "Portal Gun" -- Nomes Atualizados dos Portais local NOME_PORTAL_1 = "Porta9202837" local NOME_PORTAL_2 = "portal81738380" -- Ajustes de Posição e Rotação da Arma na Mão local POSITION_OFFSET = Vector3.new(0, -0.2, -1) local ROTATION_OFFSET = CFrame.Angles(math.rad(180), math.rad(90), math.rad(0)) -- Controle de Estado local cliqueCount = 0 local portal1 = nil local portal2 = nil local cooldownTeleport = false local executandoDisparo = false -- Interface do Canto Inferior Direito local function mostrarNotificacaoDireita() local pGui = LocalPlayer:WaitForChild("PlayerGui") local sg = pGui:FindFirstChild("PortalGunNotif") or Instance.new("ScreenGui") sg.Name = "PortalGunNotif" sg.ResetOnSpawn = false sg.Parent = pGui local frame = Instance.new("Frame") frame.Size = UDim2.new(0, 200, 0, 40) frame.Position = UDim2.new(1, -210, 1, -50) frame.BackgroundColor3 = Color3.fromRGB(25, 25, 25) frame.BorderSizePixel = 0 frame.Parent = sg local corner = Instance.new("UICorner") corner.CornerRadius = UDim.new(0, 8) corner.Parent = frame local label = Instance.new("TextLabel") label.Size = UDim2.new(1, 0, 1, 0) label.BackgroundTransparency = 1 label.Text = "Portal gun 1.2 Carregado" label.TextColor3 = Color3.fromRGB(255, 255, 255) label.TextSize = 14 label.Font = Enum.Font.SourceSansBold label.Parent = frame task.delay(4, function() if sg then sg:Destroy() end end) end -- Ajuste físico do modelo da arma local function ajustarFisicaDaPart(part) if part:IsA("BasePart") then part.Anchored = false part.CanCollide = false part.CanTouch = false part.CanQuery = false part.Massless = true part.CustomPhysicalProperties = PhysicalProperties.new(0.001, 0, 0, 0, 0) end end -- Solda o modelo da arma local function soldarModeloEPreparar(instancia) local parts = {} if instancia:IsA("BasePart") then table.insert(parts, instancia) ajustarFisicaDaPart(instancia) end for _, child in ipairs(instancia:GetDescendants()) do if child:IsA("BasePart") then table.insert(parts, child) ajustarFisicaDaPart(child) end end if #parts > 1 then local mainPart = parts[1] for i = 2, #parts do local weld = Instance.new("WeldConstraint") weld.Part0 = mainPart weld.Part1 = parts[i] weld.Parent = mainPart end end end -- Carrega o Portal 3D e limpa scripts internos local function carregarModeloPortal(cframeTarget, nomePortal) local success, result = pcall(function() return game:GetObjects("rbxassetid://" .. PORTAL_ASSET_ID)[1] end) local portalObj = nil if success and result then portalObj = result else portalObj = Instance.new("Part") portalObj.Size = Vector3.new(4, 7, 0.5) portalObj.Color = Color3.fromRGB(150, 0, 255) portalObj.Material = Enum.Material.Neon end portalObj.Name = nomePortal -- Apaga scripts, avisos e prompts nativos do asset for _, child in ipairs(portalObj:GetDescendants()) do if child:IsA("ProximityPrompt") or child:IsA("BillboardGui") or child:IsA("SurfaceGui") or child:IsA("Script") or child:IsA("LocalScript") then child:Destroy() end end if portalObj:IsA("Model") then portalObj:PivotTo(cframeTarget) for _, child in ipairs(portalObj:GetDescendants()) do if child:IsA("BasePart") then child.Anchored = true child.CanCollide = false child.CanTouch = true end end elseif portalObj:IsA("BasePart") then portalObj.CFrame = cframeTarget portalObj.Anchored = true portalObj.CanCollide = false portalObj.CanTouch = true end portalObj.Parent = Workspace return portalObj end local function getPortalCFrame(portal) if not portal then return nil end if portal:IsA("Model") then return portal:GetPivot() elseif portal:IsA("BasePart") then return portal.CFrame end return nil end -- Configuração do Teletransporte por Toque com Recarga de 2 Segundos local function configurarGatilhosDeTeleport() if not portal1 or not portal2 then return end local function aplicarGatilho(portalOrigem, obterPortalDestino) local partsTarget = {} if portalOrigem:IsA("BasePart") then table.insert(partsTarget, portalOrigem) else for _, v in ipairs(portalOrigem:GetDescendants()) do if v:IsA("BasePart") then table.insert(partsTarget, v) end end end for _, part in ipairs(partsTarget) do part.Touched:Connect(function(hit) if cooldownTeleport then return end local char = hit.Parent local hrp = char:FindFirstChild("HumanoidRootPart") if hrp and char == LocalPlayer.Character then local destPortal = obterPortalDestino() if destPortal then local destCFrame = getPortalCFrame(destPortal) if destCFrame then cooldownTeleport = true hrp.CFrame = destCFrame * CFrame.new(0, 0, -4) task.wait(2) cooldownTeleport = false end end end end) end end aplicarGatilho(portal1, function() return portal2 end) aplicarGatilho(portal2, function() return portal1 end) end -- Disparo da Bola Roxa com Cronômetro Máximo de 3 Segundos local function dispararBolaRoxa(etapa) local char = LocalPlayer.Character if not char or not char:FindFirstChild("HumanoidRootPart") then executandoDisparo = false return end local mouse = LocalPlayer:GetMouse() local targetPos = mouse.Hit and mouse.Hit.Position or (char.HumanoidRootPart.CFrame * CFrame.new(0, 0, -50)).Position local startPos = char.HumanoidRootPart.Position + Vector3.new(0, 1.5, 0) local direction = (targetPos - startPos).Unit local bola = Instance.new("Part") bola.Shape = Enum.PartType.Ball bola.Size = Vector3.new(1.5, 1.5, 1.5) bola.Color = Color3.fromRGB(140, 0, 255) bola.Material = Enum.Material.Neon bola.CanCollide = true bola.Anchored = false bola.CFrame = CFrame.new(startPos, startPos + direction) local bv = Instance.new("BodyVelocity") bv.MaxForce = Vector3.new(math.huge, math.huge, math.huge) bv.Velocity = direction * 150 bv.Parent = bola bola.Parent = Workspace local impactoProcessado = false local conect = nil local function criarPortalNoImpacto(hitCFrame) if impactoProcessado then return end impactoProcessado = true if conect then conect:Disconnect() end if bola and bola.Parent then bola:Destroy() end if etapa == 1 then if portal1 then portal1:Destroy() end portal1 = carregarModeloPortal(hitCFrame, NOME_PORTAL_1) elseif etapa == 2 then if portal2 then portal2:Destroy() end portal2 = carregarModeloPortal(hitCFrame, NOME_PORTAL_2) configurarGatilhosDeTeleport() end executandoDisparo = false end -- Timer limite de 3 segundos para spawnar o portal caso dispare no céu task.delay(3, function() if not impactoProcessado and bola and bola.Parent then local finalCFrame = CFrame.new(bola.Position, bola.Position + direction) criarPortalNoImpacto(finalCFrame) end end) bola.Touched:Connect(function(hit) if hit and not hit:IsDescendantOf(char) and hit.Name ~= NOME_PORTAL_1 and hit.Name ~= NOME_PORTAL_2 then local raycastParams = RaycastParams.new() raycastParams.FilterDescendantsInstances = {char, bola} raycastParams.FilterType = Enum.RaycastFilterType.Exclude local result = Workspace:Raycast(bola.Position, direction * 5, raycastParams) local surfaceNormal = result and result.Normal or Vector3.new(0, 1, 0) local hitPos = result and result.Position or bola.Position local finalCFrame = CFrame.new(hitPos + (surfaceNormal * 0.5), hitPos + surfaceNormal) * CFrame.Angles(math.rad(90), 0, 0) criarPortalNoImpacto(finalCFrame) end end) conect = game:GetService("RunService").Heartbeat:Connect(function() if impactoProcessado or not bola or not bola.Parent then if conect then conect:Disconnect() end return end local raycastParams = RaycastParams.new() raycastParams.FilterDescendantsInstances = {char, bola} raycastParams.FilterType = Enum.RaycastFilterType.Exclude local result = Workspace:Raycast(bola.Position, direction * 4, raycastParams) if result then if conect then conect:Disconnect() end local finalCFrame = CFrame.new(result.Position + (result.Normal * 0.5), result.Position + result.Normal) * CFrame.Angles(math.rad(90), 0, 0) criarPortalNoImpacto(finalCFrame) end end) end -- Processador da Ação local function processarClique() if executandoDisparo then return end cliqueCount = cliqueCount + 1 if cliqueCount == 1 then executandoDisparo = true dispararBolaRoxa(1) elseif cliqueCount == 2 then executandoDisparo = true dispararBolaRoxa(2) elseif cliqueCount >= 3 then if portal1 then portal1:Destroy() portal1 = nil end if portal2 then portal2:Destroy() portal2 = nil end cliqueCount = 0 end end -- Criador da Tool local function criarPortalGun() local backpack = LocalPlayer:WaitForChild("Backpack") local character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait() for _, item in ipairs(backpack:GetChildren()) do if item.Name == TOOL_NAME or item.Name == "gun" or item.Name == "Gun" then item:Destroy() end end for _, item in ipairs(character:GetChildren()) do if item.Name == TOOL_NAME or item.Name == "gun" or item.Name == "Gun" then item:Destroy() end end local tool = Instance.new("Tool") tool.Name = TOOL_NAME tool.TextureId = "rbxassetid://" .. tostring(TOOL_ICON_ID) tool.RequiresHandle = true local handle = Instance.new("Part") handle.Name = "Handle" handle.Size = Vector3.new(0.2, 0.2, 0.2) handle.Transparency = 1 ajustarFisicaDaPart(handle) handle.Parent = tool tool.Parent = backpack local modelo3D = nil tool.Equipped:Connect(function() local char = LocalPlayer.Character if not char then return end local success, result = pcall(function() return game:GetObjects("rbxassetid://" .. WEAPON_ASSET_ID)[1] end) if success and result then if result:IsA("Tool") then local visualContainer = Instance.new("Model") visualContainer.Name = "VisualModel" for _, child in ipairs(result:GetChildren()) do if child:IsA("BasePart") or child:IsA("Model") or child:IsA("Accessory") then child.Parent = visualContainer end end result:Destroy() modelo3D = visualContainer else modelo3D = result end soldarModeloEPreparar(modelo3D) local rightHand = char:FindFirstChild("RightHand") or char:FindFirstChild("Right Arm") if rightHand then local offsetCFrame = CFrame.new(POSITION_OFFSET) * ROTATION_OFFSET local mainPart = modelo3D:IsA("Model") and (modelo3D.PrimaryPart or modelo3D:FindFirstChildWhichIsA("BasePart")) or modelo3D if mainPart then if modelo3D:IsA("Model") then modelo3D:PivotTo(rightHand.CFrame * offsetCFrame) else mainPart.CFrame = rightHand.CFrame * offsetCFrame end local weldToHand = Instance.new("WeldConstraint") weldToHand.Part0 = rightHand weldToHand.Part1 = mainPart weldToHand.Parent = mainPart end end modelo3D.Parent = char end end) tool.Activated:Connect(function() processarClique() end) tool.Unequipped:Connect(function() if modelo3D then modelo3D:Destroy() modelo3D = nil end end) end -- Limpeza e Verificação de Portais local function verificarELimparPortais() local pGui = LocalPlayer:WaitForChild("PlayerGui") local portaisEncontrados = {} for _, obj in ipairs(Workspace:GetChildren()) do if obj.Name == NOME_PORTAL_1 or obj.Name == NOME_PORTAL_2 or obj.Name == "Portal1" or obj.Name == "Portal2" then table.insert(portaisEncontrados, obj) end end local totalPortais = #portaisEncontrados local redGui = Instance.new("ScreenGui") redGui.Name = "RedPortalCheckGUI" redGui.ResetOnSpawn = false redGui.Parent = pGui local frameRed = Instance.new("Frame") frameRed.Size = UDim2.new(0, 220, 0, 70) frameRed.Position = UDim2.new(0.5, -110, 0.5, -35) frameRed.BackgroundColor3 = Color3.fromRGB(180, 40, 40) frameRed.BorderSizePixel = 0 frameRed.Parent = redGui local corner = Instance.new("UICorner") corner.CornerRadius = UDim.new(0, 8) corner.Parent = frameRed local lblStatus = Instance.new("TextLabel") lblStatus.Size = UDim2.new(1, 0, 1, 0) lblStatus.BackgroundTransparency = 1 lblStatus.Text = "Verificando Portais... 0/" .. totalPortais lblStatus.TextColor3 = Color3.fromRGB(255, 255, 255) lblStatus.TextSize = 16 lblStatus.Font = Enum.Font.SourceSansBold lblStatus.Parent = frameRed task.wait(0.5) if totalPortais > 0 then for i, pObj in ipairs(portaisEncontrados) do lblStatus.Text = "Limpando Portais... " .. i .. "/" .. totalPortais pObj:Destroy() task.wait(0.5) end end redGui:Destroy() criarPortalGun() end -- Janela Principal (GUI) local function iniciarGUI() mostrarNotificacaoDireita() local pGui = LocalPlayer:WaitForChild("PlayerGui") local mainGui = Instance.new("ScreenGui") mainGui.Name = "PortalGunMainGUI" mainGui.ResetOnSpawn = false mainGui.Parent = pGui local frame = Instance.new("Frame") frame.Size = UDim2.new(0, 320, 0, 180) frame.Position = UDim2.new(0.5, -160, 0.5, -90) frame.BackgroundColor3 = Color3.fromRGB(35, 35, 35) frame.BorderSizePixel = 0 frame.Parent = mainGui local corner = Instance.new("UICorner") corner.CornerRadius = UDim.new(0, 10) corner.Parent = frame local title = Instance.new("TextLabel") title.Size = UDim2.new(1, 0, 0, 40) title.BackgroundTransparency = 1 title.Text = "Portal gun foi iniciado você está na versão 1.2" title.TextColor3 = Color3.fromRGB(255, 255, 255) title.TextSize = 13 title.Font = Enum.Font.SourceSansBold title.Parent = frame local bugs = Instance.new("TextLabel") bugs.Size = UDim2.new(1, 0, 0, 50) bugs.Position = UDim2.new(0, 0, 0, 40) bugs.BackgroundTransparency = 1 bugs.Text = "Bugs consertados✅\nÍcone no inventário alterado✅" bugs.TextColor3 = Color3.fromRGB(180, 255, 180) bugs.TextSize = 14 bugs.Font = Enum.Font.SourceSansBold bugs.Parent = frame local btnOk = Instance.new("TextButton") btnOk.Size = UDim2.new(0, 100, 0, 35) btnOk.Position = UDim2.new(0.5, -50, 1, -45) btnOk.BackgroundColor3 = Color3.fromRGB(0, 150, 255) btnOk.Text = "OK" btnOk.TextColor3 = Color3.fromRGB(255, 255, 255) btnOk.Font = Enum.Font.SourceSansBold btnOk.TextSize = 16 btnOk.Parent = frame local btnCorner = Instance.new("UICorner") btnCorner.CornerRadius = UDim.new(0, 6) btnCorner.Parent = btnOk btnOk.MouseButton1Click:Connect(function() mainGui:Destroy() verificarELimparPortais() end) end -- Execução do Script iniciarGUI()