-- =====================
-- 서비스 및 변수 정의
-- =====================
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Lighting = game:GetService("Lighting")
local UIS = game:GetService("UserInputService")
local Debris = game:GetService("Debris")
local TweenService = game:GetService("TweenService")

local player = Players.LocalPlayer
local camera = workspace.CurrentCamera

-- 기능 활성화 상태 변수
local BeamEnabled = true 
local SnowEnabled = true
local IsMouseDown = false 
local MaxDistance = 1000 -- 최대 사거리

-- 캐릭터가 무기(Tool)를 들고 있는지 확인하는 함수
local function hasWeaponEquipped()
    local character = player.Character
    if character then
        local tool = character:FindFirstChildOfClass("Tool")
        if tool then
            return true
        end
    end
    return false
end

-- =====================
-- 1. [강제 렌더링] 눈덩이 생성 시스템
-- =====================
RunService.Heartbeat:Connect(function()
    if SnowEnabled and math.random(1, 2) == 1 then 
        local snow = Instance.new("Part")
        snow.Shape = Enum.PartType.Ball
        snow.Size = Vector3.new(1, 1, 1)
        snow.Color = Color3.fromRGB(255, 255, 255)
        snow.Material = Enum.Material.Ice
        snow.Anchored = false
        snow.CanCollide = false
        snow.CanQuery = false 
        
        local pos = camera.CFrame.Position + Vector3.new(math.random(-150, 150), 60, math.random(-150, 150))
        snow.CFrame = CFrame.new(pos)
        snow.Parent = workspace
        
        local bv = Instance.new("BodyVelocity")
        bv.Velocity = Vector3.new(math.random(-5, 5), -15, math.random(-5, 5))
        bv.Parent = snow
        
        Debris:AddItem(snow, 6)
    end
end)

-- =====================
-- 2. 노란색 빔 생성 함수
-- =====================
local function createYellowBeam(origin, targetPosition)
    local distance = (targetPosition - origin).Magnitude
    if distance <= 0.05 then return end
    
    local beam = Instance.new("Part")
    beam.Size = Vector3.new(0.15, 0.15, distance)
    beam.Anchored = true
    beam.CanCollide = false
    beam.Material = Enum.Material.Neon
    beam.Color = Color3.fromRGB(255, 255, 0)
    
    beam.CFrame = CFrame.new(origin, targetPosition) * CFrame.new(0, 0, -distance / 2)
    beam.Parent = workspace
    
    Debris:AddItem(beam, 2)
    TweenService:Create(beam, TweenInfo.new(2, Enum.EasingStyle.Quad), {Transparency = 1, Size = Vector3.new(0, 0, distance)}):Play()
end

-- =====================
-- 3. 고급 셰이더 효과 함수
-- =====================
local function applyShader()
    Lighting.ClockTime = 14
    Lighting.Brightness = 3.5
    Lighting.GlobalShadows = true
    Lighting.Ambient = Color3.fromRGB(30, 30, 35)
    Lighting.OutdoorAmbient = Color3.fromRGB(45, 50, 60)
    
    local fx = {"ShaderBloom", "ShaderCC", "ShaderRays", "ShaderAtmos"}
    for _, name in pairs(fx) do 
        if not Lighting:FindFirstChild(name) then 
            if name == "ShaderBloom" then Instance.new("BloomEffect", Lighting).Name = name
            elseif name == "ShaderCC" then Instance.new("ColorCorrectionEffect", Lighting).Name = name
            elseif name == "ShaderRays" then Instance.new("SunRaysEffect", Lighting).Name = name
            elseif name == "ShaderAtmos" then Instance.new("Atmosphere", Lighting).Name = name end
        end 
    end
end

task.spawn(applyShader)

-- =====================
-- 4. Wallbang (벽 관통) 레이캐스트 연산 함수
-- =====================
local function castWallbangRay(origin, directionUnit)
    local currentOrigin = origin
    local accumulatedDistance = 0
    
    -- 레이캐스트 필터 설정 (본인 캐릭터 제외)
    local raycastParams = RaycastParams.new()
    raycastParams.FilterType = Enum.RaycastFilterType.Exclude
    local filterInstances = {}
    if player.Character then
        table.insert(filterInstances, player.Character)
    end
    raycastParams.FilterDescendantsInstances = filterInstances

    while accumulatedDistance < MaxDistance do
        local remainingDistance = MaxDistance - accumulatedDistance
        local result = workspace:Raycast(currentOrigin, directionUnit * remainingDistance, raycastParams)
        
        -- 아무것도 맞지 않았다면 최대 사거리 지점을 반환
        if not result then
            return origin + (directionUnit * MaxDistance)
        end
        
        local hitInstance = result.Instance
        local hitPosition = result.Position
        
        -- 현재까지 이동한 거리 갱신
        accumulatedDistance = accumulatedDistance + (hitPosition - currentOrigin).Magnitude
        
        -- 맞은 오브젝트가 플레이어 캐릭터(Humanoid)의 일부인지 확인
        local character = hitInstance.Parent
        local humanoid = character:FindFirstChildOfClass("Humanoid") or (character.Parent and character.Parent:FindFirstChildOfClass("Humanoid"))
        
        if humanoid then
            -- 캐릭터를 찾았다면 관통을 멈추고 해당 타격 지점을 반환
            return hitPosition
        end
        
        -- 플레이어가 아니라 일반 벽(오브젝트)이라면 필터에 추가하여 다음 루프에서 무시하도록 설정
        table.insert(filterInstances, hitInstance)
        raycastParams.FilterDescendantsInstances = filterInstances
        
        -- 벽 바로 뒤에서 다시 레이를 쏠 수 있도록 소량의 오프셋을 주어 시작 지점 이동
        currentOrigin = hitPosition + (directionUnit * 0.05)
    end
    
    return origin + (directionUnit * MaxDistance)
end

-- =====================
-- 5. 상시 연사 루프
-- =====================
RunService.RenderStepped:Connect(function()
    if BeamEnabled and IsMouseDown and hasWeaponEquipped() then
        local origin = camera.CFrame.Position
        local directionUnit = camera.CFrame.LookVector
        
        -- Wallbang 로직을 통해 최종 타격 위치 계산
        local targetPosition = castWallbangRay(origin, directionUnit)
        
        -- 계산된 최종 지점까지 빔 생성
        task.spawn(createYellowBeam, origin, targetPosition)
    end
end)

-- =====================
-- 6. 마우스/터치 인식
-- =====================
UIS.InputBegan:Connect(function(input, gp)
    if gp then return end
    if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
        IsMouseDown = true
    end
end)

UIS.InputEnded:Connect(function(input)
    if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
        IsMouseDown = false
    end
end)

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: