File size: 3,490 Bytes
0712d5f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
-- src/ServerScriptService/CraftingManager.server.lua

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local CraftingConfig = require(ReplicatedStorage:WaitForChild("Shared"):WaitForChild("CraftingConfig"))
local ChoppingConfig = require(ReplicatedStorage:WaitForChild("Shared"):WaitForChild("ChoppingConfig"))
local CraftEvent = ReplicatedStorage:WaitForChild("Events"):WaitForChild("CraftEvent")
local NotificationEvent = ReplicatedStorage:WaitForChild("Events"):WaitForChild("NotificationEvent")
local ShopEvent = ReplicatedStorage:WaitForChild("Events"):WaitForChild("ShopEvent")
local SoundEvent = ReplicatedStorage:WaitForChild("Events"):WaitForChild("SoundEvent")

local function getPlayerResources(player)
	local data = _G.GetPlayerData(player)
	if not data then return {} end
	if not data.Resources then
		data.Resources = {}
	end
	return data.Resources
end

local function canCraft(player, recipeId)
	local recipe = CraftingConfig.Recipes[recipeId]
	if not recipe then return false, "Unknown recipe" end

	local resources = getPlayerResources(player)

	for material, requiredAmount in pairs(recipe.Materials) do
		local have = resources[material] or 0
		if have < requiredAmount then
			return false, "Need " .. tostring(requiredAmount) .. " " .. material .. " (have " .. tostring(have) .. ")"
		end
	end

	-- Check if player already owns this tool
	if ChoppingConfig.AxeTypes[recipeId] and _G.HasInInventory and _G.HasInInventory(player, "Tools", recipeId) then
		return false, "You already own " .. (recipe.Name or recipeId)
	end

	return true, "OK"
end

local function craftItem(player, recipeId)
	-- Anti-cheat
	if _G.IsRateLimited and _G.IsRateLimited(player, "Craft") then return end

	local canDo, reason = canCraft(player, recipeId)
	if not canDo then
		NotificationEvent:FireClient(player, "Error", reason)
		SoundEvent:FireClient(player, "PurchaseFail", nil)
		return
	end

	local recipe = CraftingConfig.Recipes[recipeId]
	local resources = getPlayerResources(player)

	-- Deduct materials
	for material, requiredAmount in pairs(recipe.Materials) do
		resources[material] = resources[material] - requiredAmount
	end

	-- Add tool to inventory
	if _G.AddToInventory then
		_G.AddToInventory(player, "Tools", recipeId)
	end

	-- Auto-equip if it is an axe
	if ChoppingConfig.AxeTypes[recipeId] then
		local data = _G.GetPlayerData(player)
		if data then
			data.EquippedAxe = recipeId
			player:SetAttribute("EquippedAxe", recipeId)
			if player.Character then
				player.Character:SetAttribute("EquippedAxe", recipeId)
			end
		end
	end

	NotificationEvent:FireClient(player, "Crafted", "Crafted " .. (recipe.Name or recipeId) .. "!")
	SoundEvent:FireClient(player, "ConstructComplete", nil)

	-- Send updated inventory to client
	local data = _G.GetPlayerData(player)
	if data then
		ShopEvent:FireClient(player, "InventoryUpdate", data.Inventory)
		CraftEvent:FireClient(player, "ResourceUpdate", data.Resources)
	end
end

-- Handle resource query from client
local function onCraftEvent(player, action, data)
	if action == "Craft" then
		craftItem(player, data)
	elseif action == "QueryResources" then
		local resources = getPlayerResources(player)
		CraftEvent:FireClient(player, "ResourceUpdate", resources)
	end
end

CraftEvent.OnServerEvent:Connect(onCraftEvent)

print("Crafting Manager initialized")