Need help to cut log into pieces

  1. I want to make the log’s choppable into sections.

  2. Not sure how to go about it. At the moment the log is made when the trunk is cut but it’s too long or it sections it right away. I want to be able cut a log after it has fallen down.

  3. Various different code for fireing the server, calling a function but it does just not seem to work.
    Here is my code
    Server script:

-- Define the function that returns the maximum health for a given tree type
local function maxHealthForTreeType(treeType)
	if treeType == "IceLolliTree" then
		return 3
	elseif treeType == "CandyTree" then
		return 5
	elseif treeType == "DonutTree" then
		return 1
	elseif treeType == "PopcornTree" then
		return 7
	elseif treeType == "FudgeTree" then
		return 15
	elseif treeType == "ChipsTree" then
		return 2
	elseif treeType == "KababTree" then
		return 2
	elseif treeType == "SlusheeTree" then
		return 2
	else
		return 7
	end
end

-- Axeserver
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local AxeRE = ReplicatedStorage:WaitForChild("AxeRE")

local CollectionService = game:GetService("CollectionService")

local cooldown = {}

-- Table to store tree data for regrowth
local treeData = {}

-- Function to destroy the log after 30 minutes
local function destroyLog(logPart)
	wait(1800)  -- Wait for 30 minutes
	if logPart and logPart.Parent then
		logPart:Destroy()
	end
end

-- Function to regrow a tree
local function regrowTree(treeType, position, originalTrunk)
	local growthTime = 10  -- Time in seconds for the tree to fully grow
	local growthStepInterval = 0.1  -- Interval between growth steps
	local growthSteps = growthTime / growthStepInterval

	local treeInfo = treeData[originalTrunk]

	if treeInfo then
		local basePosition = position - Vector3.new(0, treeInfo.originalTrunkSize.Y / 2, 0)
		local treeTrunk = Instance.new("Part")
		treeTrunk.Name = "Trunk"
		treeTrunk.Size = Vector3.new(treeInfo.originalTrunkSize.X, 1, treeInfo.originalTrunkSize.Z)
		treeTrunk.Position = basePosition  -- Set the bottom position of the trunk
		treeTrunk.Anchored = true
		treeTrunk.Parent = workspace

		-- Set tree attributes (e.g., health, type)
		local healthValue = Instance.new("IntValue")
		healthValue.Name = "Health"
		healthValue.Value = 1  -- Set a small initial health
		healthValue.Parent = treeTrunk

		local treeTypeValue = Instance.new("StringValue")
		treeTypeValue.Name = "treeType"
		treeTypeValue.Value = treeType
		treeTypeValue.Parent = treeTrunk

		CollectionService:AddTag(treeTrunk, "Tree")

		-- Gradually grow the tree upwards
		for step = 1, growthSteps do
			local growthPercentage = step / growthSteps
			local newSize = Vector3.new(treeInfo.originalTrunkSize.X, treeInfo.originalTrunkSize.Y * growthPercentage, treeInfo.originalTrunkSize.Z)
			treeTrunk.Size = newSize

			-- Keep the original color
			treeTrunk.BrickColor = treeInfo.trunkColor

			-- Keep the material constant as "Wood"
			treeTrunk.Material = Enum.Material.Wood

			local newPosition = basePosition + Vector3.new(0, treeInfo.originalTrunkSize.Y * growthPercentage / 2, 0)
			treeTrunk.Position = newPosition

			wait(growthStepInterval)
		end

		-- Set final attributes and size
		treeTrunk.Size = treeInfo.originalTrunkSize
		treeTrunk.BrickColor = treeInfo.trunkColor
		treeTrunk.Material = Enum.Material.Wood

		-- Recreate leaves if available in the stored data
		if treeInfo.leaves then
			local newLeaves = treeInfo.leaves:Clone()
			newLeaves.Parent = treeTrunk
			newLeaves.Size = treeInfo.originalLeavesSize  -- Set the original leaves size
		end

		-- Handle any other necessary actions for the new tree trunk
	end
end

AxeRE.OnServerEvent:Connect(function(player, target, mouseHit)
	if not cooldown[player] and player.Character and target and target.Name == "Trunk" and target:FindFirstChild("Health") and mouseHit then
		local hrp = player.Character.HumanoidRootPart
		local distance = (hrp.Position - target.Position).Magnitude

		if distance <= 6 then
			cooldown[player] = true

			local treeTypeValue = target:FindFirstChild("treeType")
			if treeTypeValue then
				local treeType = treeTypeValue.Value

				local healthValue
				if treeType == "IceLolliTree" then
					healthValue = 3  -- Set the health value for IceLolliTreeLog
				elseif treeType == "CandyTree" then
					healthValue = 5  -- Set the health value for CandyTreeLog
				elseif treeType == "DonutTree" then
					healthValue = 1  -- Set the health value for DonutTreeLog
				elseif treeType == "PopcornTree" then
					healthValue = 7
				elseif treeType == "ChipsTree" then
					healthValue = 2  -- Set the health value for CandyTreeLog
				elseif treeType == "FudgeTree" then
					healthValue = 15  -- Set the health value for DonutTreeLog
				elseif treeType == "KababTree" then
					healthValue = 15
				elseif treeType == "SlusheeTree" then
					healthValue = 15
				else
					healthValue = 7  -- Set a default value for unrecognized tree type
				end

				-- Store tree data before destroying
				local treeInfo = {
					trunkMaterial = target.Material,
					trunkColor = target.BrickColor,
					leaves = target:FindFirstChild("Leaves"),
					originalTrunkSize = target.Size,  -- Store the original trunk size
					originalLeavesSize = target:FindFirstChild("Leaves") and target.Leaves.Size or nil  -- Store the original leaves size
				}
				local originalWorthValue = target:FindFirstChild("Worth")
				local originalWorth = 1  -- Default to 1
				if originalWorthValue then
					originalWorth = originalWorthValue.Value
				else

				end
				treeData[target] = treeInfo

				-- Perform chopping logic here
				local trunkHealth = target.Health
				trunkHealth.Value = trunkHealth.Value - 1

				if trunkHealth.Value <= 0 then
					-- Destroy the trunk and leaves
					target:Destroy()
					local leaves = target:FindFirstChild("Leaves")
					if leaves then
						local fallingLeaves = leaves:Clone()
						fallingLeaves.Parent = workspace
						fallingLeaves.Anchored = false
						fallingLeaves.Position = leaves.Position  -- Position it same as the original leaves
						fallingLeaves.Velocity = Vector3.new(0, -10, 0)  -- Apply downward velocity

						-- Destroy the leaves after 300 seconds
						spawn(function()
							wait(300)
							if fallingLeaves and fallingLeaves.Parent then
								fallingLeaves:Destroy()
							end
						end)
					end
					-- Create a new log part based on the tree type
					local logPart = Instance.new("Part")
					logPart.Name = treeType .. "Log"  -- Example: CandyTreeLog
					logPart.Size = Vector3.new(2, 20, 2)  -- Adjust size as needed
					logPart.Position = target.Position
					logPart.Anchored = false
					logPart.Parent = workspace

					-- Add "Health" attribute with the determined value
					local logHealth = Instance.new("IntValue")
					logHealth.Name = "Health"
					logHealth.Value = healthValue
					logHealth.Parent = logPart

					-- Add "Worth" attribute
					local worthValue = Instance.new("NumberValue")
					worthValue.Name = "Worth"
					worthValue.Value = originalWorth  -- Set the value from the original tree trunk
					worthValue.Parent = logPart

					local configValue = Instance.new("StringValue")
					configValue.Name = "Configuration"
					configValue.Value = "Draggable"
					configValue.Parent = logPart

					CollectionService:AddTag(logPart, "Draggable")

					--add owner tag
					local ownerValue = Instance.new("IntValue")
					ownerValue.Name = "Owner"
					ownerValue.Value = player
					ownerValue.Parent = logPart

					-- Add "Creator" attribute to mark ownership
					local creatorValue = Instance.new("ObjectValue")
					creatorValue.Name = "Creator"
					creatorValue.Value = player  -- Set the value to the chopping player
					creatorValue.Parent = logPart

					-- Apply properties from the trunk to the log
					logPart.Material = treeInfo.trunkMaterial
					logPart.BrickColor = treeInfo.trunkColor
					-- Handle any other necessary actions for the log part, such as physics, appearance, etc.

					-- Start the function to destroy the log after 30 minutes
					spawn(function()
						destroyLog(logPart)
					end)

					-- Call the regrowTree function after a delay (e.g., 1800 seconds or 30 minutes)
					spawn(function()
						wait(10)  -- Adjust this delay as needed
						regrowTree(treeType, target.Position, target)
					end)
				end
			end

			wait(1)
			cooldown[player] = false
		end
	end
end)

Local tool script

--clientscript

local tool = script.Parent
local UserInputService = game:GetService("UserInputService")
local mouse = game.Players.LocalPlayer:GetMouse()

local cooldown = false
local connection = nil

-- Reference the animation by its name
local chopAnimationName = "ChopAnimation"

-- Add the sound
local chopSound = tool:WaitForChild("ChopSound") -- Make sure you have a sound named "ChopSound" in the tool

local function MarkAsGrabbable(part)
	if not part:FindFirstChild("CanGrab") then
		local canGrab = Instance.new("BoolValue")
		canGrab.Name = "CanGrab"
		canGrab.Value = true
		canGrab.Parent = part
	end
end

local function Activate()
	if not cooldown then
		cooldown = true

		local target = mouse.Target
		if target and target.Parent then
			local logPart = target.Parent:FindFirstChild("Log")  -- Assuming "Log" is the name of the log part you're chopping
			if logPart then
				MarkAsGrabbable(logPart)
			end
		end

		-- Play the chop animation
		local humanoid = tool.Parent:FindFirstChildOfClass("Humanoid")
		if humanoid then
			local chopAnimation = humanoid:LoadAnimation(tool[chopAnimationName])
			chopAnimation:Play()

			-- Connect the Stopped event to play the sound at the end of the animation
			chopAnimation.Stopped:Connect(function()
				if chopSound then
					chopSound:Play()
				end
			end)
		end

		game.ReplicatedStorage.AxeRE:FireServer(mouse.Target, mouse.Hit)

		wait(1)
		cooldown = false
	end
end

local function InputBegan(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
		Activate()
	end
end

local function InputEnded(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
		cooldown = false
	end
end

local function Equipped()
	connection = UserInputService.InputBegan:Connect(InputBegan)
	UserInputService.InputEnded:Connect(InputEnded)
end

local function Unequipped()
	if connection then
		connection:Disconnect()
	end
	cooldown = false
end

tool.Equipped:Connect(Equipped)
tool.Unequipped:Connect(Unequipped)

2 Likes

You can use the SubtractAsync function of the in game CSG library to split the log.

1 Like

Will this cut a whole part into sections because looking at it, it seems to be different parts.

2 Likes

Tried that but it’s not allowing the sections.
Kinda like the cutting parts similar to Lumber Tycoon 2 does it.

1 Like

you do not need CSG to cut a block into two blocks

1 Like

Please explain? Looking to be able to cut it several times based on raycast i think but never used it and don’t know what to do.

1 Like

Well, a block can be split into two blocks that perfectly fit into the original block. The calculations for doing this I don’t know off the top of my head, but it basically entails choosing an axis and a distance along that axis, then cloning the block, and resizing both of them so that they share an edge along the position of the cut. For trees, you’re also going to want to reposition welds (calculate which side each weld is on, so that you can move it to the correct side of the cut). The way to do this varies by game, and I happen to be working on a game that involves it (see Metalworks Sandbox Demo for another example in the wild) but I don’t really have time to dive further into it right now.

1 Like

You could take it from LT2’s creator himself:

1 Like

Not sure what you’re going for here but it looks like you’re on the right track. Really no need to split the tree into parts at all. Just drop the parts down next to the tree to be picked up or directly into the backpack. Once the amount of dropped pieces are exhausted remove the tree.

Maybe make a few increasingly chopped up versions of the tree and as the parts drop you swap the tree as they go. I’d get the 1st part working then maybe add this to it.

Graphicly this would look way better and even give the ability to make the increasingly chopped up versions of the tree look really good.

1 Like