Yorum satırlarını ve çıktı mesajlarını türkçeleştir:

-- ServerScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local spawnAreas = workspace:WaitForChild("GrassSpawnAreas")
local ServerFunctions_sample = require(game.ServerScriptService.Scripts.GeneralFunctions_sample)

local Config = require(ReplicatedStorage:WaitForChild("ClickFarmConfig"))
local ClickFarmStorage = ReplicatedStorage:WaitForChild("ClickFarmStorage")

-- Tables to store grass templates and configurations
local grassTemplates = {}
local grassNameToConfig = {}
local grassObjects = {} -- Maps GrassID to grass instances
local grassIDCounter = 0 -- Counter for unique GrassIDs

-- Load grass templates
for areaName, config in pairs(Config.GrassAreas) do
	local grassName = config.GrassName
	local bonusGrassName = config.BonusGrassName

	-- Load standard grass
	if not grassTemplates[grassName] then
		grassTemplates[grassName] = ClickFarmStorage:WaitForChild(grassName)
	end

	-- Load bonus grass
	if bonusGrassName and not grassTemplates[bonusGrassName] then
		grassTemplates[bonusGrassName] = ClickFarmStorage.BonusGrass:WaitForChild(bonusGrassName)
	end

	-- Map grass names to their configurations
	grassNameToConfig[grassName] = {config = config, is_bonus = false, areaName = areaName}
	if bonusGrassName then
		grassNameToConfig[bonusGrassName] = {config = config, is_bonus = true, areaName = areaName}
	end
end

local grassDestroyedEvent = ReplicatedStorage:WaitForChild("GrassDestroyedEvent")
local grassEffectsEvent = ReplicatedStorage:WaitForChild("GrassEffectsEvent") -- RemoteEvent

local function initializeGrassGrid(areaName, config)
	local spawnArea = spawnAreas:FindFirstChild(areaName)
	if not spawnArea then
		warn("Spawn area not found: " .. areaName)
		return {}
	end

	local grassSpawnArea = spawnArea:FindFirstChild("GrassSpawnArea")
	if not grassSpawnArea then
		warn("GrassSpawnArea not found: " .. areaName)
		return {}
	end

	local areaPosition = grassSpawnArea.Position
	local areaSize = grassSpawnArea.Size

	local totalGrassCount = config.GrassCount or 1400
	local areaWidth = areaSize.X
	local areaLength = areaSize.Z

	-- Calculate grid dimensions
	local gridArea = areaWidth * areaLength
	local gridSpacing = math.sqrt(gridArea / totalGrassCount)
	local gridCountX = math.max(1, math.floor(areaWidth / gridSpacing))
	local gridCountZ = math.max(1, math.floor(areaLength / gridSpacing))

	local adjustedGridSpacingX = areaWidth / gridCountX
	local adjustedGridSpacingZ = areaLength / gridCountZ

	local grassGrid = {}
	for i = 0, gridCountX - 1 do
		for j = 0, gridCountZ - 1 do
			local posX = areaPosition.X - (areaWidth / 2) + (i + 0.5) * adjustedGridSpacingX
			local posZ = areaPosition.Z - (areaLength / 2) + (j + 0.5) * adjustedGridSpacingZ
			table.insert(grassGrid, Vector3.new(posX, areaPosition.Y, posZ))
		end
	end

	return grassGrid
end

local function spawnGrass(position, grassTemplate, areaName, bonusGrassTemplate, bonusChance)
	local grass
	if math.random() <= bonusChance and bonusGrassTemplate then
		grass = bonusGrassTemplate:Clone()
	else
		grass = grassTemplate:Clone()
	end
	grass.Position = position

	-- Random rotation around the Y-axis
	grass.Orientation = Vector3.new(0, math.random(0, 360), 0)

	-- Assign a unique GrassID using an Attribute
	grassIDCounter = grassIDCounter + 1
	local grassID = tostring(grassIDCounter)
	grass:SetAttribute("GrassID", grassID)

	-- Add grass to grassObjects table
	grassObjects[grassID] = grass

	local areaFolder = spawnAreas:FindFirstChild(areaName)
	if not areaFolder then
		warn("Spawn area folder not found: " .. areaName)
		return
	end

	local grassFolder = areaFolder:FindFirstChild(grassTemplate.Name)
	if not grassFolder then
		grassFolder = Instance.new("Folder")
		grassFolder.Name = grassTemplate.Name
		grassFolder.Parent = areaFolder
	end

	grass.Parent = grassFolder
end

local function onGrassRemoved(grass, player)
	local grassInfo = grassNameToConfig[grass.Name]
	if not grassInfo then
		warn("AreaName or Config not found for grass: " .. grass.Name)
		return
	end

	local areaName = grassInfo.areaName
	local config = grassInfo.config

	-- Add money to player
	ServerFunctions_sample.addPlayerLocalMoney(player, config.CashMultiplier)

	-- Notify all clients to create effects
	grassEffectsEvent:FireAllClients(grass.Position, grass.Name)

	-- Remove grass from grassObjects table
	local grassID = grass:GetAttribute("GrassID")
	if grassID then
		grassObjects[grassID] = nil
	else
		warn("GrassID attribute missing for grass: " .. grass.Name)
	end

	-- Destroy grass
	grass:Destroy()

	-- Respawn grass after a delay
	local respawnDelay = math.random(config.RespawnDelayMin, config.RespawnDelayMax)
	task.delay(respawnDelay, function()
		local grassTemplate = grassTemplates[config.GrassName]
		local bonusGrassTemplate = grassTemplates[config.BonusGrassName]
		local bonusChance = config.BonusSpawnChance or 0

		spawnGrass(grass.Position, grassTemplate, areaName, bonusGrassTemplate, bonusChance)
	end)
end

-- RemoteEvent listener
grassDestroyedEvent.OnServerEvent:Connect(function(player, grassID)
	-- Find the grass in grassObjects
	local foundGrass = grassObjects[grassID]

	if foundGrass and foundGrass.Parent then
		-- Grass is valid, process removal
		onGrassRemoved(foundGrass, player)
	else
		warn(string.format("Invalid or already processed grass: GrassID: %s [%s (%d)]", grassID, player.Name, player.UserId))
	end
end)

-- Spawn grasses at the start
for areaName, config in pairs(Config.GrassAreas) do
	local grassGrid = initializeGrassGrid(areaName, config)
	local grassTemplate = grassTemplates[config.GrassName]
	local bonusGrassTemplate = grassTemplates[config.BonusGrassName]
	local bonusChance = config.BonusSpawnChance or 0
	for _, position in ipairs(grassGrid) do
		spawnGrass(position, grassTemplate, areaName, bonusGrassTemplate, bonusChance)
	end
end