How to modify this module so that it works with npcs?

as the title suggests, how would i modify the script bellow so I can make an npc use the module too, because it always gives an error due to the character:model

local module = {}

module.Hitbox = function(Character:Model, CFrameOffset:CFrame, Size:number, Damage:number, BlockDamage:number, KnockBack, VfxPart:BasePart)
	local Hrp = Character:FindFirstChildOfClass("Humanoid").RootPart
	local String = Instance.new("StringValue")
	String.Name = KnockBack
	local player = game.Players:GetPlayerFromCharacter(Character)
	local rs = game:GetService("ReplicatedStorage")
	
	local Hitbox = workspace:GetPartBoundsInBox(Hrp.CFrame * CFrameOffset, Vector3.one * Size)

	local Filtered = {}

	for _, Parts in Hitbox do
		local PossibleCharacter = Parts.Parent

		if PossibleCharacter == Character or table.find(Filtered, PossibleCharacter) then continue end

		local Humanoid = PossibleCharacter:FindFirstChild("Humanoid")
		if not Humanoid then continue end
		local VfxClone = VfxPart:Clone()
		local ParryVfx = rs.ParryVfx:Clone()

		local PossiblePlayer = game.Players:GetPlayerFromCharacter(PossibleCharacter)
		if PossiblePlayer then

			local leaderstats = PossiblePlayer:WaitForChild("leaderstats")
			local BlockValue = leaderstats.BlockValue

			if PossibleCharacter:GetAttribute("IsBlocking") == true and PossibleCharacter:GetAttribute("Parrying") == false and PossibleCharacter:GetAttribute("IsGaurdBroken") == false then
				BlockValue.Value -= BlockDamage
			end

			if PossibleCharacter:GetAttribute("IsBlocking") == false and PossibleCharacter:GetAttribute("Parrying") == false and PossibleCharacter:GetAttribute("IsGaurdBroken") == false then
				if KnockBack == "yes"  then
					local bodyVelocity = Instance.new("BodyVelocity")
					bodyVelocity.Name = "KNOCKBACK"
					bodyVelocity.MaxForce = Vector3.new(100000000, 0, 100000000)
					bodyVelocity.Velocity = player.Character.HumanoidRootPart.CFrame.LookVector.unit * 30
					PossibleCharacter:SetAttribute("KnockBack", true)
					bodyVelocity.Parent = PossibleCharacter.HumanoidRootPart
					Humanoid:TakeDamage(Damage)
					game.Debris:AddItem(bodyVelocity, 0.65)
					PossibleCharacter:SetAttribute("KnockBack", false)


				else
					Humanoid:TakeDamage(Damage)
					VfxClone.CFrame = Humanoid.RootPart.CFrame
					VfxClone.Parent = workspace

					PossibleCharacter:SetAttribute("Stunned", true)
					task.wait(1)
					PossibleCharacter:SetAttribute("Stunned", false)
				end
			end

			if PossibleCharacter:GetAttribute("IsBlocking") == true and PossibleCharacter:GetAttribute("Parrying") == true and PossibleCharacter:GetAttribute("IsGaurdBroken") == false then
				--local katanaParry = game:GetService("ReplicatedFirst").Animations.KatanaParry
				--local KatanaParryTrack = hum:LoadAnimation(katanaParry)
				--KatanaParryTrack:Play()
				ParryVfx.Parent = workspace
				ParryVfx.CFrame = PossibleCharacter:WaitForChild("Humanoid").RootPart.CFrame

			end
			game.Debris:AddItem(ParryVfx,0.5 )
			
		else
			local NpcChar = Humanoid.Parent
			
			if NpcChar:GetAttribute("IsBlocking") == true and NpcChar:GetAttribute("Parrying") == false and NpcChar:GetAttribute("IsGaurdBroken") == false then
				NpcChar:SetAttribute("BlockValue", NpcChar:GetAttribute("BlockValue") - BlockDamage)
			end

			if NpcChar:GetAttribute("IsBlocking") == false and NpcChar:GetAttribute("Parrying") == false and NpcChar:GetAttribute("IsGaurdBroken") == false then
				if KnockBack == "yes"  then
					local bodyVelocity = Instance.new("BodyVelocity")
					bodyVelocity.Name = "KNOCKBACK"
					bodyVelocity.MaxForce = Vector3.new(100000000, 0, 100000000)
					bodyVelocity.Velocity = player.Character.HumanoidRootPart.CFrame.LookVector.unit * 30
					NpcChar:SetAttribute("KnockBack", true)
					bodyVelocity.Parent = NpcChar.HumanoidRootPart
					Humanoid:TakeDamage(Damage)
					game.Debris:AddItem(bodyVelocity, 0.65)
					task.wait(0.6)
					NpcChar:SetAttribute("KnockBack", false)
					
					
				else
					Humanoid:TakeDamage(Damage)
					VfxClone.CFrame = Humanoid.RootPart.CFrame
					VfxClone.Parent = workspace

					NpcChar:SetAttribute("Stunned", true)
					task.wait(1)
					NpcChar:SetAttribute("Stunned", false)
				end
			end

			if NpcChar:GetAttribute("IsBlocking") == true and NpcChar:GetAttribute("Parrying") == true and NpcChar:GetAttribute("IsGaurdBroken") == false then
				--local katanaParry = game:GetService("ReplicatedFirst").Animations.KatanaParry
				--local KatanaParryTrack = hum:LoadAnimation(katanaParry)
				--KatanaParryTrack:Play()
				ParryVfx.Parent = workspace
				ParryVfx.CFrame = NpcChar:WaitForChild("Humanoid").RootPart.CFrame

			end
			
		end

			
		

		table.insert(Filtered, PossibleCharacter)
		task.delay(0.5, game.Destroy, VfxClone, ParryVfx)
	end

	table.clear(Filtered)
end

return module

1 Like

Well, I am not sure that it will work but here’s my version:

local module = {}

module.Hitbox = function(Character: Model, CFrameOffset: CFrame, Size: number, Damage: number, BlockDamage: number, KnockBack: string, VfxPart: BasePart)
    local Hrp = Character:FindFirstChild("HumanoidRootPart")
    if not Hrp then return end -- Ensure RootPart exists

    local rs = game:GetService("ReplicatedStorage")
    local Hitbox = workspace:GetPartBoundsInBox(Hrp.CFrame * CFrameOffset, Vector3.one * Size)
    local Filtered = {}

    for _, Part in ipairs(Hitbox) do
        local PossibleCharacter = Part.Parent
        if PossibleCharacter == Character or table.find(Filtered, PossibleCharacter) then continue end

        local Humanoid = PossibleCharacter:FindFirstChild("Humanoid")
        if not Humanoid then continue end

        local VfxClone = VfxPart:Clone()
        local ParryVfx = rs:FindFirstChild("ParryVfx") and rs.ParryVfx:Clone()

        local PossiblePlayer = game.Players:GetPlayerFromCharacter(PossibleCharacter)
        local IsNpc = not PossiblePlayer -- Identify if it's an NPC

        if PossiblePlayer then
            local leaderstats = PossiblePlayer:FindFirstChild("leaderstats")
            local BlockValue = leaderstats and leaderstats:FindFirstChild("BlockValue")

            if PossibleCharacter:GetAttribute("IsBlocking") and not PossibleCharacter:GetAttribute("Parrying") and not PossibleCharacter:GetAttribute("IsGuardBroken") then
                if BlockValue then
                    BlockValue.Value -= BlockDamage
                end
            end

            if not PossibleCharacter:GetAttribute("IsBlocking") then
                if KnockBack == "yes" then
                    local bodyVelocity = Instance.new("BodyVelocity")
                    bodyVelocity.Name = "KNOCKBACK"
                    bodyVelocity.MaxForce = Vector3.new(1e8, 0, 1e8)
                    bodyVelocity.Velocity = Hrp.CFrame.LookVector * 30
                    bodyVelocity.Parent = PossibleCharacter.HumanoidRootPart
                    game.Debris:AddItem(bodyVelocity, 0.65)
                end
                Humanoid:TakeDamage(Damage)
            end

        elseif IsNpc then
            if PossibleCharacter:GetAttribute("IsBlocking") and not PossibleCharacter:GetAttribute("Parrying") and not PossibleCharacter:GetAttribute("IsGuardBroken") then
                PossibleCharacter:SetAttribute("BlockValue", PossibleCharacter:GetAttribute("BlockValue") - BlockDamage)
            end

            if not PossibleCharacter:GetAttribute("IsBlocking") then
                if KnockBack == "yes" then
                    local bodyVelocity = Instance.new("BodyVelocity")
                    bodyVelocity.Name = "KNOCKBACK"
                    bodyVelocity.MaxForce = Vector3.new(1e8, 0, 1e8)
                    bodyVelocity.Velocity = Hrp.CFrame.LookVector * 30
                    bodyVelocity.Parent = PossibleCharacter.HumanoidRootPart
                    game.Debris:AddItem(bodyVelocity, 0.65)
                end
                Humanoid:TakeDamage(Damage)
            end
        end

        if ParryVfx and PossibleCharacter:GetAttribute("Parrying") then
            ParryVfx.CFrame = Hrp.CFrame
            ParryVfx.Parent = workspace
            game.Debris:AddItem(ParryVfx, 0.5)
        end

        VfxClone.CFrame = Hrp.CFrame
        VfxClone.Parent = workspace
        game.Debris:AddItem(VfxClone, 0.5)

        table.insert(Filtered, PossibleCharacter)
    end

    table.clear(Filtered)
end

return module
1 Like