algorembrant's picture
Upload 88 files
0712d5f verified
-- src/StarterPlayer/StarterCharacterScripts/AxeController.client.lua
-- Handles both fist punching and axe chopping
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local CollectionService = game:GetService("CollectionService")
local player = Players.LocalPlayer
local mouse = player:GetMouse()
local character = player.Character or player.CharacterAdded:Wait()
local ChoppingConfig = require(ReplicatedStorage:WaitForChild("Shared"):WaitForChild("ChoppingConfig"))
local CraftingConfig = require(ReplicatedStorage:WaitForChild("Shared"):WaitForChild("CraftingConfig"))
local ChopEvent = ReplicatedStorage:WaitForChild("Events"):WaitForChild("ChopEvent")
local canSwing = true
local function getCurrentWeapon()
local axeType = nil
if character then
axeType = character:GetAttribute("EquippedAxe")
end
if not axeType or axeType == "" then
axeType = player:GetAttribute("EquippedAxe")
end
-- No axe = use fists
if not axeType or axeType == "" or axeType == "None" then
return CraftingConfig.Fist, "Fist"
end
local stats = ChoppingConfig.AxeTypes[axeType]
if stats then
return stats, axeType
end
return CraftingConfig.Fist, "Fist"
end
local function playSwingAnimation(weaponType)
local humanoid = character:FindFirstChildOfClass("Humanoid")
if not humanoid then return end
local camera = workspace.CurrentCamera
if camera then
task.spawn(function()
local shake = weaponType == "Fist" and 1 or 2
for i = 1, 3 do
camera.CFrame = camera.CFrame * CFrame.Angles(0, 0, math.rad(-shake + i * (shake * 0.6)))
task.wait(0.03)
end
end)
end
end
local function createHitEffect(position, weaponType)
local part = Instance.new("Part")
part.Size = Vector3.new(0.4, 0.4, 0.4)
part.Position = position
part.Anchored = true
part.CanCollide = false
part.Material = Enum.Material.Neon
part.Shape = Enum.PartType.Ball
part.Parent = workspace.Terrain
if weaponType == "Fist" then
part.BrickColor = BrickColor.new("Bright orange")
else
part.BrickColor = BrickColor.new("Bright yellow")
end
task.spawn(function()
for i = 1, 5 do
part.Size = part.Size * 1.3
part.Transparency = i / 5
task.wait(0.03)
end
part:Destroy()
end)
end
local function onInputBegan(input, gameProcessed)
if gameProcessed then return end
if input.UserInputType == Enum.UserInputType.MouseButton1 then
if not canSwing then return end
if not character or not character:FindFirstChild("Head") then return end
local weaponStats, weaponType = getCurrentWeapon()
local rayOrigin = character.Head.Position
local rayDirection = (mouse.Hit.Position - rayOrigin).Unit * weaponStats.Range
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {character}
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
if raycastResult and raycastResult.Instance then
local hitPart = raycastResult.Instance
-- Only chop tree segments
if CollectionService:HasTag(hitPart, "TreeSegment") then
playSwingAnimation(weaponType)
createHitEffect(raycastResult.Position, weaponType)
ChopEvent:FireServer(hitPart, raycastResult.Position)
end
end
-- Cooldown applies even on miss (animation commitment)
canSwing = false
task.wait(weaponStats.SwingCooldown)
canSwing = true
end
end
player.CharacterAdded:Connect(function(char)
character = char
end)
UserInputService.InputBegan:Connect(onInputBegan)