-
What do you want to achieve? Keep it simple and clear!
I realize my system for spawning items is slow because i do every thing on the server, so i decided to take a look a replica service. I am currently using replica Service for the replication of the data. So if the player breaks the item or damages it, it will replicate for all other players ingame, also i want to load certain items either based on the current zone the player is in or, the zone around the player. -
What is the issue? Include screenshots / videos if possible!
I have no clue what to do, when the item is clone withing the spawn item function, i create a new replica. But don’t know what to do from there, also i have other functions to have the player move to the item and start taking its health so the player can get a rewards from the item.
-
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I Look on devForum and i only found replicating Data for like profile service
function module:startSearching(player, itemInstance, zoneName, position, orientation, parent)
DataService:GetReplica(player):andThen(function(replica)
foundItems[player] = {}
-- Get the player's inventory and max bag size
local Inventory = replica.Data.ItemInventory.Inventory
local MaxBagSize = replica.Data.ItemInventory.MaxBagSize
local itemCount = 0
-- Count the number of items in the inventory
for _ in pairs(Inventory) do
itemCount = itemCount + 1
end
-- Check if the inventory is full
if itemCount >= MaxBagSize then
Network:FireClient(
player,
"Notify",
"Your inventory is full! Auction or sell some thing to Clear it up.",
3
)
playSound("Error", 1, workspace.Sounds)
return -- Exit the function if the inventory is full
end
local billboardGui = itemInstance.PrimaryPart:FindFirstChild("PileBillBoard")
local fillFrame = billboardGui and billboardGui.Frame.HealthBar
billboardGui.PileName.Text = itemInstance.Name
local health = itemInstance:GetAttribute("Health")
if searchingPlayers[player.UserId] then
return
end
searchingPlayers[player.UserId] = true
-- Ensure the player has a character and the character has a Humanoid
local character = player.Character
local humanoid = character and character:FindFirstChildOfClass("Humanoid")
local playerPosition = character.PrimaryPart.Position
local pilePosition = itemInstance.PrimaryPart.Position
local distance = (playerPosition - pilePosition).Magnitude
local walkSpeed = humanoid and humanoid.WalkSpeed
local timeToReach = distance / walkSpeed
if not humanoid then
searchingPlayers[player.UserId] = nil
return
end
-- Move the player to the item
local offset = Vector3.new(0, 0, 5)
humanoid:MoveTo(itemInstance.PrimaryPart.Position + offset) -- Adjust the offset as needed
task.wait(timeToReach - 1)
playerPosition = character.PrimaryPart.Position
distance = (playerPosition - pilePosition).Magnitude
if distance > 32 then
searchingPlayers[player.UserId] = nil
return -- Exit the function if the player is not near the pile
end
while itemInstance:GetAttribute("Health") > 0 do
Network:FireClient(player, "PlayDirtSound")
local isCritical = math.random() < 0.1 -- 10% chance of a critical hit
local healthReductionRate = isCritical and replica.Data.Damage * 1.5 or replica.Data.Damage
Network:FireClient(player, "DealDamage", healthReductionRate, isCritical)
itemInstance:SetAttribute("Health", itemInstance:GetAttribute("Health") - healthReductionRate)
updateHealthBar(itemInstance, fillFrame, health)
local scaleFactor = itemInstance:GetAttribute("Health") / health
local newSize = itemInstance.PrimaryPart.Size * scaleFactor
local tweenInfo = TweenInfo.new(0.3, Enum.EasingStyle.Linear, Enum.EasingDirection.Out)
local tweenGoal = {}
tweenGoal.Size = newSize
local tween = TweenService:Create(itemInstance.PrimaryPart, tweenInfo, tweenGoal)
tween:Play()
tween.Completed:Wait()
end
module:finishSearching(player, itemInstance, zoneName, position, orientation, parent)
end)
end
function module:finishSearching(player, itemInstance, zoneName, position, orientation, parent)
DataService:GetReplica(player):andThen(function(replica)
searchingPlayers[player.UserId] = nil
if not replica then
return
end
replica:SetValue(
{ "JunkyardData", "TotalJunkPilesSearched" },
replica.Data.JunkyardData.TotalJunkPilesSearched + 1
)
print("TotalJunkPilesSearched: " .. replica.Data.JunkyardData.TotalJunkPilesSearched)
local MaxBagSize = replica.Data.ItemInventory.MaxBagSize
local Inventory = replica.Data.ItemInventory.Inventory
local itemCount = 0
local itemName = itemInstance.Name
local itemData = ItemsData[itemName].Items
local itemsList = {}
local spawnRate = itemData.SpawnRate or 0.5
local respawnDelay = 1 / spawnRate
if itemData then
for _, itemInfo in pairs(itemData) do
table.insert(itemsList, itemInfo)
end
else
warn("Item data not found for item: " .. itemName)
end
for i = 1, 3 do
local selectedItem = selectRandomItem(itemsList)
if selectedItem then
--- a way to add all three item to the foundItems[player] table
if not foundItems[player] then
foundItems[player] = {}
end
table.insert(foundItems[player], selectedItem)
end
end
for _ in pairs(Inventory) do
itemCount = itemCount + 1
end
if itemCount <= MaxBagSize then
Network:FireClient(player, "FinishedSearching")
Network:FireClient(player, "RewardsEvent", foundItems[player])
for _, item in ipairs(foundItems[player]) do
replica:ArrayInsert({ "ItemInventory", "Inventory" }, item)
end
else
Network:FireClient(
player,
"Notify",
"Your inventory is full! Auction or sell some thing to Clear it up.",
3
)
playSound("Error", 1, workspace.Sounds)
end
SetParticles(itemInstance)
itemInstance:Destroy()
Network:FireClient(player, "FinishedSearching")
task.spawn(function()
module:respawnIngredient(itemName, zoneName, position, orientation, parent, respawnDelay)
end)
end)
end
function module:spawnItem(itemName, zoneName, position, orientation, parent)
local itemCount = itemInstances[itemName] or 0
if itemCount >= 10 then
handleError("Maximum limit reached for item: " .. itemName)
return
end
local itemData = PilesData[itemName]
if not itemData then
handleError("No data found for item: " .. itemName)
return
end
local itemModel = Items[zoneName]:FindFirstChild(itemName)
if not itemModel then
handleError("No model found for item: " .. itemName)
return
end
local zonePart = parent.Parent
local zoneSize = zonePart.Size
local randomX = position.X + (math.random(-1, 1)) * zoneSize.X * .5
local randomY = position.Y -- Adjust this if you have a height offset
local randomZ = position.Z + (math.random(-1, 1)) * zoneSize.Z * .5
local orientationX = math.rad(orientation.X)
local orientationY = math.rad(orientation.Y)
local orientationZ = math.rad(orientation.Z)
local itemInstance = itemModel:Clone()
itemInstance.Name = itemName
local newItem = ReplicaService.NewReplica({
ClassToken = ClassToken,
Data = {
IsDestoryed = false,
Health = itemData.Health
},
Replication = "All"
})
local newCFrame = CFrame.new(Vector3.new(randomX, randomY, randomZ)) * CFrame.Angles(orientationX, orientationY, orientationZ)
itemInstance:SetPrimaryPartCFrame(newCFrame)
itemInstance.Parent = parent
local primaryPart = itemInstance.PrimaryPart
local billboardGui = primaryPart:FindFirstChild("PileBillBoard")
billboardGui.PileName.Text = itemInstance.Name
local health = itemData.Health or 100
itemInstance:SetAttribute("Health", health)
itemInstances[itemName] = itemCount + 1
local fadeDuration = 2
local tweenInfo = TweenInfo.new(fadeDuration, Enum.EasingStyle.Bounce, Enum.EasingDirection.Out)
local tweenGoal = { Transparency = 0 }
local descendants = itemInstance:GetDescendants()
for _, child in ipairs(descendants) do
if child:IsA("BasePart") then
local tween = TweenService:Create(child, tweenInfo, tweenGoal)
tween:Play()
end
end
raycaseItem(itemInstance)
module:setUpClickDetector(itemInstance, function(player)
module:startSearching(player, itemInstance, zoneName, position, orientation, parent)
end)
end