function v3.OnLoad(_) --[[Anonymous function at line 214]]
--[[
Upvalues:
[1] = u12
[2] = u15
[3] = u19
[4] = u13
[5] = u1
[6] = u9
[7] = u2
[8] = u16
--]]
local function u56(p53, p54) --[[Anonymous function at line 215]]
--[[
Upvalues:
[1] = u12
--]]
local u55 = script[p54 or "Explosion"]:Clone()
u55.CFrame = p53
u55.Parent = workspace
u12.emit(u55)
task.delay(5, function() --[[Anonymous function at line 222]]
--[[
Upvalues:
[1] = u55
--]]
u55:Destroy()
end)
end
u15.OnClientEvent:Connect(function(p57, u58, p59) --[[Anonymous function at line 227]]
--[[
Upvalues:
[1] = u19
[2] = u13
[3] = u1
[4] = u9
[5] = u2
--]]
local v60 = u19[p57]
if v60 and v60:FindFirstChild("Svinina Bombardino") then
for _, u61 in v60["Svinina Bombardino"]:GetChildren() do
if u61.Name ~= "RootPart" then
u61.Transparency = 1
task.delay(1, function() --[[Anonymous function at line 236]]
--[[
Upvalues:
[1] = u61
--]]
u61.Transparency = 0
end)
end
end
end
local u62 = u13:Clone()
u62.PrimaryPart.Anchored = true
u62:PivotTo(CFrame.new(u58))
local v63 = u1.Sounds.Events["Bombardiro Crocodilo"].DroppingBomb:Clone()
v63.Parent = u62
u62.Parent = workspace
v63:Play()
local u64 = 0
local u65 = u9.calculateTimeToGround(u58.y, p59.y)
local u66 = nil
u66 = u2.PostSimulation:Connect(function(p67) --[[Anonymous function at line 257]]
--[[
Upvalues:
[1] = u64
[2] = u65
[3] = u62
[4] = u58
[5] = u9
[6] = u66
--]]
u64 = u64 + p67
local v68 = u64 / u65
local v69 = u62
local v70 = CFrame.new
local v71 = u58
local v72 = u9.simulateGravity(u64)
v69:PivotTo(v70(v71 - vector.create(0, v72, 0)) * CFrame.Angles(-u64 * 3.141592653589793 * 2, 0, 0))
if v68 >= 1 then
u66:Disconnect()
for _, v73 in u62:GetDescendants() do
if v73:IsA("BasePart") then
v73.Transparency = 1
elseif v73:IsA("ParticleEmitter") then
v73:Destroy()
end
end
task.wait(3)
u62:Destroy()
end
end)
end)
u16.OnClientEvent:Connect(function(p74, p75) --[[Anonymous function at line 279]]
--[[
Upvalues:
[1] = u56
--]]
local v76 = u56
if typeof(p74) ~= "CFrame" then
p74 = CFrame.new(p74)
end
v76(p74, p75)
end)
end
return v3 - Edit
03:12:20.354
- Edit
03:12:20.354
============================== - Edit
03:12:20.354 📜 ReplicatedStorage.Controllers.EventController.Events.Rainbow - Edit
03:12:20.354 ==============================
- Edit
03:12:20.354 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
local v1 = game:GetService("ReplicatedStorage")
game:GetService("TweenService")
game:GetService("RunService")
game:GetService("Lighting")
game:GetService("Players")
require(v1.Shared.EventTypes)
local v2 = {}
require(v1.Controllers.AnimalController)
local u3 = require(v1.Controllers.SoundController)
require(v1.Controllers.EventController)
local u4 = require(v1.Controllers.CycleController)
local v5 = require(v1.Packages.Trove)
require(v1.Packages.Net)
local u6 = require(v1.Shared.VFX)
local _ = script.Name
local u7 = workspace.Events.Rainbow
local u8 = v5.new()
function v2.OnStart(_) --[[Anonymous function at line 25]]
--[[
Upvalues:
[1] = u4
[2] = u3
[3] = u6
[4] = u7
[5] = u8
--]]
u4:Update()
u3:UpdateOST()
u6.emit(u7.Emit)
u8:Add(task.spawn(function() --[[Anonymous function at line 31]]
--[[
Upvalues:
[1] = u3
[2] = u7
--]]
u3:PlaySound("Sounds.Sfx.RainbowActivatedEffect", u7.SoundParts.RainbowActivatedEffect.Position)
end))
u8:Add(task.spawn(function() --[[Anonymous function at line 35]]
--[[
Upvalues:
[1] = u3
[2] = u7
--]]
u3:PlaySound("Sounds.Sfx.RainbowMachineEnabled", u7.SoundParts.RainbowMachineEnabled.Position)
end))
u8:Add(task.spawn(function() --[[Anonymous function at line 39]]
--[[
Upvalues:
[1] = u7
--]]
local v9 = NumberSequence.new({ NumberSequenceKeypoint.new(0, 1), NumberSequenceKeypoint.new(1, 1) })
local v10 = u7.Enabled.RainbowMain.RainbowHandle.Wiggler.Attachment3:GetChildren()
for _, v11 in v10 do
v11.Transparency = v9
v11.Enabled = true
end
local v12 = workspace:GetServerTimeNow()
while true do
local v13 = workspace:GetServerTimeNow()
local v14 = (v13 - v12) % 3.5 / 3.5
local v15 = NumberSequence.new({ NumberSequenceKeypoint.new(0, 1), NumberSequenceKeypoint.new(1 - v14, 1), NumberSequenceKeypoint.new(1, 0) })
if v13 - v12 >= 3.5 then
break
end
for _, v16 in v10 do
v16.Transparency = v15
end
task.wait()
end
for _, v17 in v10 do
v17.Transparency = NumberSequence.new({ NumberSequenceKeypoint.new(0, 0), NumberSequenceKeypoint.new(1, 0) })
end
end))
u6.enable(u7.Enabled)
u8:Add(function() --[[Anonymous function at line 82]]
--[[
Upvalues:
[1] = u6
[2] = u7
--]]
u6.disable(u7.Enabled)
end)
end
function v2.OnStop(_) --[[Anonymous function at line 87]]
--[[
Upvalues:
[1] = u8
--]]
u8:Destroy()
end
function v2.OnLoad(_) --[[Anonymous function at line 91]] end
return v2 - Edit
03:12:20.354
- Edit
03:12:20.354
============================== - Edit
03:12:20.354 📜 ReplicatedStorage.Controllers.EventController.Events.Water - Edit
03:12:20.354 ==============================
- Edit
03:12:20.354 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
game:GetService("ServerScriptService")
local u1 = game:GetService("ReplicatedStorage")
local u2 = game:GetService("ContentProvider")
local u3 = game:GetService("RunService")
game:GetService("Players")
require(u1.Shared.EventTypes)
local v4 = {}
local u5 = require(u1.Controllers.EffectController)
local u6 = require(u1.Controllers.AnimalController)
local u7 = require(u1.Controllers.SoundController)
local u8 = require(u1.Controllers.CycleController)
local u9 = require(u1.Controllers.EventController)
local u10 = require(u1.Controllers.EventController.ClientEventUtils)
require(u1.Packages.CreateTween)
local u11 = require(u1.Packages.Observers)
require(u1.Utils.MathUtils)
local v12 = require(u1.Packages.Trove)
local v13 = require(u1.Packages.Net)
local u14 = require(u1.Shared.VFX)
require(u1.Shared.Snapshot)
local u15 = script.Name
local u16 = v13:RemoteEvent("EventService/Water/Burst")
local u17 = v12.new()
local u18 = {}
local function u36() --[[Anonymous function at line 36]]
--[[
Upvalues:
[1] = u17
[2] = u3
[3] = u11
--]]
local v19 = u17:Extend()
local u20 = table.create(4)
v19:Add(function() --[[Anonymous function at line 48]]
--[[
Upvalues:
[1] = u20
--]]
table.clear(u20)
end)
local u21 = 0
v19:Add(u3.PreRender:Connect(function(p22) --[[Anonymous function at line 53]]
--[[
Upvalues:
[1] = u21
[2] = u20
--]]
debug.profilebegin("Water Event")
u21 = u21 + p22
for v23, v24 in u20 do
if v24.target and v24.targetAttachment then
v24.beam.First.Enabled = true
v24.beam.Second.Enabled = true
local v25 = u21 - v23 + 1
local v26 = math.clamp(v25, 0, 1)
local v27 = v24.beam.WorldPosition
v24.targetAttachment.Position = v27 + (v24.target:GetPivot().Position - v27) * v26
end
end
debug.profileend()
end))
v19:Add(u11.observeTag("WaterPlayerVFX", function(u28) --[[Anonymous function at line 75]]
--[[
Upvalues:
[1] = u20
[2] = u11
--]]
local u29 = script.PlayerVFX.Beam:Clone()
u29.Parent = u28
local u30 = script.PlayerVFX.Torso:Clone()
u30.Parent = u28
local u31 = u28:GetAttribute("WaterIndex")
u20[u31] = {
["beam"] = u29,
["target"] = nil
}
local u35 = u11.observeTag("WaterPlayerVFX", function(p32) --[[Anonymous function at line 88]]
--[[
Upvalues:
[1] = u28
[2] = u29
[3] = u20
--]]
if p32 == u28 then
return nil
end
if p32:GetAttribute("WaterIndex") ~= u28:GetAttribute("WaterIndex") % 4 + 1 then
return nil
end
local u33 = Instance.new("Attachment")
u33.Position = u29.WorldPosition
u33.Parent = workspace.Terrain
local v34 = u20[u28:GetAttribute("WaterIndex")]
v34.target = p32
v34.beam.First.Attachment0 = u33
v34.beam.Second.Attachment0 = u33
v34.targetAttachment = u33
return function() --[[Anonymous function at line 107]]
--[[
Upvalues:
[1] = u33
--]]
u33:Destroy()
end
end)
return function() --[[Anonymous function at line 112]]
--[[
Upvalues:
[1] = u30
[2] = u29
[3] = u35
[4] = u20
[5] = u31
--]]
u30:Destroy()
u29:Destroy()
u35()
u20[u31] = nil
end
end))
end
local function u57() --[[Anonymous function at line 122]]
--[[
Upvalues:
[1] = u17
[2] = u11
[3] = u18
[4] = u3
--]]
local u37 = {}
u17:Add(u11.observeTag("WaterShark", function(u38) --[[Anonymous function at line 124]]
--[[
Upvalues:
[1] = u18
[2] = u37
--]]
local v39 = u38:GetAttribute("SharkType") or "Orcalero Orcala"
local v40 = script[v39]
local u41 = v40:Clone()
u41.PrimaryPart.Anchored = true
u41.Parent = u38
local v42
if v40 == script["Orcalero Orcala"] then
v42 = script.OrcaleroSwim
else
v42 = script.TralaleroSwim
end
local v43
if v40 == script["Orcalero Orcala"] then
v43 = script.OrcaleroAttack
else
v43 = script.TralaleroAttack
end
local u44 = u41.AnimationController.Animator:LoadAnimation(v42)
u44.Priority = Enum.AnimationPriority.Action
local u45 = u41.AnimationController.Animator:LoadAnimation(v43)
u45.Priority = Enum.AnimationPriority.Action4
u45.Looped = false
u44:Play()
local function u46() --[[Anonymous function at line 144]]
--[[
Upvalues:
[1] = u44
[2] = u45
--]]
u44:Stop(0)
u44:Destroy()
u45:Stop(0)
u45:Destroy()
end
local u47 = u38:GetAttributeChangedSignal("Attack"):Connect(function() --[[Anonymous function at line 152]]
--[[
Upvalues:
[1] = u45
--]]
u45:Play()
end)
u18[u38.Name] = u41
local v48 = u37
table.insert(v48, u38)
return function() --[[Anonymous function at line 159]]
--[[
Upvalues:
[1] = u37
[2] = u38
[3] = u47
[4] = u41
[5] = u18
[6] = u46
--]]
local v49 = table.find(u37, u38)
if v49 then
table.remove(u37, v49)
end
u47:Disconnect()
u41:Destroy()
u18[u38.Name] = nil
local v50 = u46
if type(v50) == "function" then
u46()
u46 = nil
end
end
end))
u17:Add(u3.PreRender:Connect(function(_) --[[Anonymous function at line 176]]
--[[
Upvalues:
[1] = u37
[2] = u18
--]]
debug.profilebegin("WaterEvent:Update Sharks")
local v51 = {}
local v52 = {}
for _, v53 in u37 do
local v54 = u18[v53.Name]
if v54 then
local v55 = v54.PrimaryPart
table.insert(v51, v55)
local v56 = v53.CFrame
table.insert(v52, v56)
end
end
workspace:BulkMoveTo(v51, v52, Enum.BulkMoveMode.FireCFrameChanged)
debug.profileend()
end))
end
function v4.OnStart(_) --[[Anonymous function at line 194]]
--[[
Upvalues:
[1] = u9
[2] = u15
[3] = u1
[4] = u17
[5] = u5
[6] = u8
[7] = u7
[8] = u57
[9] = u11
[10] = u3
[11] = u36
--]]
local v58 = u9:GetActiveEventData(u15)
assert(v58)
u1:SetAttribute("WaterEvent", true)
u17:Add(function() --[[Anonymous function at line 199]]
--[[
Upvalues:
[1] = u1
[2] = u5
[3] = u15
[4] = u8
[5] = u7
--]]
u1:SetAttribute("WaterEvent", nil)
u5:Activate("Blink")
u5:Stop(u15, "GrassRecolor")
u8:Update()
u7:UpdateOST()
u7:UpdateAmbience()
end)
u17:Add(task.delay(v58.startedAt + 4 - workspace:GetServerTimeNow(), function() --[[Anonymous function at line 209]]
--[[
Upvalues:
[1] = u5
[2] = u17
[3] = u15
[4] = u8
[5] = u7
[6] = u57
[7] = u11
[8] = u3
--]]
u5:Activate("Blink")
local v59 = u17:Add(Instance.new("ColorCorrectionEffect"))
v59.Brightness = 0.15
v59.Contrast = 0.1
v59.Saturation = -0.1
v59.TintColor = Color3.fromRGB(113, 186, 234)
v59.Parent = workspace.CurrentCamera
u17:Clone(script.Water).Parent = workspace
u5:Run(u15, "GrassRecolor")
u8:Update()
u7:UpdateOST()
u7:UpdateAmbience()
u57()
u17:Add(u11.observeCharacters(function(_, u60) --[[Anonymous function at line 230]]
--[[
Upvalues:
[1] = u11
--]]
return u11.observeChildren(u60, function(p61) --[[Anonymous function at line 231]]
--[[
Upvalues:
[1] = u11
[2] = u60
--]]
if p61.Name ~= "UpperTorso" then
return nil
end
local u62 = {}
for _, v63 in script.PlayerBubbles:GetChildren() do
local v64 = v63:Clone()
v64.Parent = p61
table.insert(u62, v64)
end
local u69 = u11.observeChildren(u60, function(u65) --[[Anonymous function at line 244]]
--[[
Upvalues:
[1] = u62
--]]
if not u65:IsA("Humanoid") then
return nil
end
local u68 = u65:GetPropertyChangedSignal("MoveDirection"):Connect(function() --[[Anonymous function at line 249]]
--[[
Upvalues:
[1] = u65
[2] = u62
--]]
local v66 = u65.MoveDirection ~= Vector3.new(0, 0, 0)
for _, v67 in u62 do
v67.Enabled = v66
end
end)
return function() --[[Anonymous function at line 256]]
--[[
Upvalues:
[1] = u68
--]]
u68:Disconnect()
end
end)
return function() --[[Anonymous function at line 261]]
--[[
Upvalues:
[1] = u62
[2] = u69
--]]
for _, v70 in u62 do
v70:Destroy()
end
table.clear(u62)
u69()
end
end)
end))
u17:Add(function() --[[Anonymous function at line 272]]
workspace.Gravity = 196.2
end)
u17:Add(u3.PostSimulation:Connect(function(_) --[[Anonymous function at line 276]]
workspace.Gravity = 29.429999999999996
end))
end))
u17:Add(task.spawn(function() --[[Anonymous function at line 281]]
--[[
Upvalues:
[1] = u36
--]]
u36()
end))
end
function v4.OnStop(_) --[[Anonymous function at line 286]]
--[[
Upvalues:
[1] = u17
--]]
u17:Destroy()
end
function v4.OnLoad(_) --[[Anonymous function at line 290]]
--[[
Upvalues:
[1] = u2
[2] = u16
[3] = u6
[4] = u18
[5] = u10
[6] = u14
[7] = u7
[8] = u1
--]]
task.spawn(pcall, function() --[[Anonymous function at line 291]]
--[[
Upvalues:
[1] = u2
--]]
u2:PreloadAsync(script:GetChildren())
end)
u16.OnClientEvent:Connect(function(p71, p72) --[[Anonymous function at line 295]]
--[[
Upvalues:
[1] = u6
[2] = u18
[3] = u10
[4] = u14
[5] = u7
[6] = u1
--]]
local v73 = u6:GetAnimals()[p72]
if v73 then
local v74 = u18[p71]
if v74 then
v74.Parent:SetAttribute("Attack", not v74.Parent:GetAttribute("Attack"))
end
local v75 = script.Burst:Clone()
v75.CFrame = CFrame.new(u10.getAnimalPosition(p72, {
["top"] = true
}))
v75.Anchored = false
local v76 = Instance.new("WeldConstraint")
v76.Part0 = v75
v76.Part1 = v73.AnimalModel.PrimaryPart
v76.Parent = v75
v75.Parent = workspace
u14.emit(v75)
u7:PlaySound(u1.Sounds.Events.Water["Brainrot Hit"], v75.Position)
end
end)
end
return v4 - Edit
03:12:20.354
- Edit
03:12:20.355
============================== - Edit
03:12:20.355 📜 ReplicatedStorage.Controllers.EventController.Events.Brazil - Edit
03:12:20.355 ==============================
- Edit
03:12:20.355 local u1 = game:GetService("ReplicatedStorage")
local u2 = game:GetService("ContentProvider")
game:GetService("TweenService")
local u3 = game:GetService("RunService")
local u4 = game:GetService("Lighting")
local u5 = game:GetService("Players")
game:GetService("Debris")
require(u1.Shared.EventTypes)
local v6 = {}
local u7 = require(u1.Controllers.EncryptedAssetsController)
local u8 = require(u1.Controllers.AnimalController)
local u9 = require(u1.Controllers.EffectController)
local u10 = require(u1.Controllers.CameraController)
local u11 = require(u1.Controllers.SoundController)
local u12 = require(u1.Controllers.EventController)
local u13 = require(u1.Controllers.CycleController)
local u14 = require(u1.Shared.SharedEventUtils)
local u15 = require(u1.Packages.CreateTween)
require(u1.Shared.TweenPivot)
local u16 = require(u1.Packages.Observers)
require(u1.Utils.MathUtils)
require(u1.Packages.Signal)
require(u1.Packages.Spring)
local u17 = require(u1.Packages.Trove)
require(u1.Packages.Shake)
local v18 = require(u1.Packages.Net)
local u19 = require(u1.Shared.VFX)
local u20 = u5.LocalPlayer
local u21 = workspace.CurrentCamera
local u22 = Color3.fromRGB(128, 255, 0)
local u23 = Color3.fromRGB(0, 255, 0)
local u24 = script.Name
local u25 = workspace.Sounds.BrazilEvent
local u26 = workspace.Events.Brazil.FullMapFloor
local u27 = v18:RemoteEvent("EventService/Brazil/Focus")
local u28 = v18:RemoteEvent("EventService/Brazil/Burst")
local u29 = u17.new()
local function u33() --[[Anonymous function at line 52]]
--[[
Upvalues:
[1] = u26
--]]
local v30 = u26.Position
local v31 = u26.Size.X * 0.5 * (math.random(0, 1) * 2 - 1)
local v32 = u26.Size.Z * 0.5 * (math.random(0, 1) * 2 - 1)
return v30 + Vector3.new(v31, 0, v32)
end
local function u37(p34) --[[Anonymous function at line 60]]
local u35 = Instance.new("Attachment")
u35.Name = "Attachment"
u35.CFrame = CFrame.new(0, 3, 0)
local u36 = Instance.new("PointLight")
u36.Name = "PointLight"
u36.Brightness = 4
u36.Color = Color3.fromRGB(255, 157, 0)
u36.Range = 6
u36.Parent = u35
u35.Parent = p34
return function() --[[Anonymous function at line 74]]
--[[
Upvalues:
[1] = u35
[2] = u36
--]]
u35:Destroy()
u36:Destroy()
end
end
function v6.OnStart(_) --[[Anonymous function at line 80]]
--[[
Upvalues:
[1] = u12
[2] = u24
[3] = u29
[4] = u9
[5] = u13
[6] = u11
[7] = u28
[8] = u8
[9] = u1
[10] = u19
[11] = u4
[12] = u21
[13] = u16
[14] = u5
[15] = u17
[16] = u3
[17] = u20
[18] = u14
[19] = u27
[20] = u37
[21] = u25
[22] = u7
[23] = u33
[24] = u15
[25] = u22
[26] = u23
[27] = u10
--]]
local u38 = u12:GetActiveEventData(u24)
assert(u38)
local function u49(p39, u40, u41) --[[Anonymous function at line 88]]
--[[
Upvalues:
[1] = u38
--]]
local function u44() --[[Anonymous function at line 89]]
--[[
Upvalues:
[1] = u40
[2] = u38
--]]
local v42 = u40
local v43 = u38.startedAt + v42 - workspace:GetServerTimeNow()
return math.max(v43, 0)
end
local function v45() --[[Anonymous function at line 93]]
--[[
Upvalues:
[1] = u41
[2] = u44
--]]
u41(u44)
end
local u46 = nil
local v47 = u38.startedAt + p39 - workspace:GetServerTimeNow()
local v48 = math.max(v47, 0)
if v48 > 0 then
u46 = task.delay(v48, v45)
else
u41(u44)
end
return function() --[[Anonymous function at line 106]]
--[[
Upvalues:
[1] = u46
--]]
if u46 and coroutine.status(u46) == "suspended" then
pcall(task.cancel, u46)
end
end
end
u29:Add(function() --[[Anonymous function at line 113]]
--[[
Upvalues:
[1] = u9
[2] = u13
[3] = u11
--]]
u9:Activate("Blink")
u13:Update()
u11:UpdateOST()
end)
u29:Add(u28.OnClientEvent:Connect(function(p50) --[[Anonymous function at line 119]]
--[[
Upvalues:
[1] = u8
[2] = u11
[3] = u1
[4] = u19
--]]
local v51 = u8:GetAnimals()[p50]
if v51 then
local v52 = v51.AnimalModel
local v53
if v52.PrimaryPart then
v53 = v52.PrimaryPart.CFrame
else
v53 = v52:GetPivot()
end
local u54 = v53.Position
task.spawn(function() --[[Anonymous function at line 140]]
--[[
Upvalues:
[1] = u11
[2] = u1
[3] = u54
--]]
u11:PlaySound(u1.Sounds.Events.Brazil.Hit, u54)
end)
local u55 = script.Burst:Clone()
u55:PivotTo(CFrame.new(u54))
u55.Anchored = false
local v56 = Instance.new("WeldConstraint")
v56.Part0 = u55
v56.Part1 = v51.AnimalModel.PrimaryPart
v56.Parent = u55
u55.Parent = workspace
u19.emit(u55)
task.delay(5, function() --[[Anonymous function at line 157]]
--[[
Upvalues:
[1] = u55
--]]
u55:Destroy()
end)
end
end))
local u57 = u4:FindFirstChild("Cartoon")
if u57 then
u57.Parent = u1
u29:Add(function() --[[Anonymous function at line 165]]
--[[
Upvalues:
[1] = u57
[2] = u4
--]]
u57.Parent = u4
end)
end
local u58 = u29:Clone(Instance.new("ColorCorrectionEffect"))
u58.Parent = u21
local u59 = nil
local u60 = u29:Clone(script.Stage)
local u61 = u29:Clone(script.VFX)
local function u108() --[[Anonymous function at line 243]]
--[[
Upvalues:
[1] = u61
[2] = u29
[3] = u16
[4] = u17
[5] = u3
[6] = u8
[7] = u1
[8] = u14
[9] = u27
--]]
local u62 = {}
local u63 = {}
local u64 = {}
for _, v65 in u61.Square.Bottom:GetChildren() do
if v65:IsA("Attachment") then
u62[v65] = v65.Position
table.insert(u63, v65)
end
end
for _, v66 in u61.Square.Top:GetChildren() do
if v66:IsA("Attachment") then
u62[v66] = v66.Position
table.insert(u64, v66)
end
end
local u67 = Vector3.new(9, 9, 9)
for _, v68 in u63 do
v68.Position = u62[v68] * Vector3.new(1, 1, 1) * 9
end
for _, v69 in u64 do
v69.Position = u62[v69] * Vector3.new(1, 1, 1) * 9
end
u29:Add(u16.observeTag("BrazilHitbox", function(u70) --[[Anonymous function at line 275]]
--[[
Upvalues:
[1] = u17
[2] = u3
[3] = u8
[4] = u1
[5] = u67
[6] = u64
[7] = u62
[8] = u63
[9] = u14
[10] = u61
[11] = u27
--]]
local v71 = u17.new()
local u72 = nil
local u73 = nil
local u74 = 0
local u75 = false
v71:Add(u3.PostSimulation:Connect(function(p76) --[[Anonymous function at line 285]]
--[[
Upvalues:
[1] = u70
[2] = u73
[3] = u8
[4] = u75
[5] = u1
[6] = u74
[7] = u72
[8] = u67
[9] = u64
[10] = u62
[11] = u63
[12] = u14
[13] = u61
--]]
local v77 = workspace:GetServerTimeNow()
local v78 = u70.CFrame
local v79 = u70:GetAttribute("Focused")
local v80
if u73 and (v79 and v79 <= v77) then
v80 = u8:GetAnimals()[u73]
else
v80 = nil
end
if v80 then
if not u75 then
u75 = true
local u81 = u1.Sounds.Events.Brazil.Cube:Clone()
u81.Parent = u70
u81:Play()
u81.Ended:Once(function() --[[Anonymous function at line 297]]
--[[
Upvalues:
[1] = u81
--]]
u81:Destroy()
end)
end
local v82 = (v77 - v79) / 1
local v83 = math.clamp(v82, 0, 1)
local v84 = (v77 - (v79 + 1)) / 1
u74 = math.clamp(v84, 0, 1)
local v85 = v80.AnimalModel
local v86 = v85:FindFirstChild("VfxInstance")
local v87 = v80.Instance:GetPivot()
local v88
if v86 then
v88 = v86.Size
else
v88 = v85:GetExtentsSize()
end
local v89 = (v88 * Vector3.new(1.25, 1.5, 1.25)):Min(Vector3.new(9, 18, 9))
v78 = CFrame.new(v87.X, v78.Y, v87.Z)
if not u72 then
u72 = u67
end
local v90 = u72
assert(v90)
local v91 = u72:Lerp(v89, v83)
local v92 = u72
local v93 = v89.X
local v94 = v89.Z
local v95 = v92:Lerp(Vector3.new(v93, 0, v94), v83)
u67 = v91
for _, v96 in u64 do
local v97 = u62[v96]
local v98 = u74 * 1
v96.Position = (v97 + Vector3.new(0, v98, 0)) * v91
end
for _, v99 in u63 do
v99.Position = u62[v99] * v95
end
else
if u75 then
u75 = false
end
local v100 = -4 * p76
local v101 = math.exp(v100)
u67 = (Vector3.new(9, 9, 9)):Lerp(u67, v101)
u72 = u67
local v102 = u74
u74 = math.lerp(0, v102, v101)
for _, v103 in u64 do
local v104 = u62[v103]
local v105 = u74 * 1
v103.Position = (v104 + Vector3.new(0, v105, 0)) * u67
end
for _, v106 in u63 do
v106.Position = u62[v106] * u67
end
end
u14.pushPartCFrame(u61.Square, v78)
end))
v71:Add(u27.OnClientEvent:Connect(function(p107) --[[Anonymous function at line 356]]
--[[
Upvalues:
[1] = u72
[2] = u67
[3] = u73
--]]
u72 = u67
u73 = p107
end))
return v71:WrapClean()
end, { workspace }))
end
local function u115() --[[Anonymous function at line 365]]
--[[
Upvalues:
[1] = u29
[2] = u16
[3] = u17
[4] = u37
--]]
u29:Add(u16.observeCharacters(function(_, u109) --[[Anonymous function at line 366]]
--[[
Upvalues:
[1] = u17
[2] = u37
--]]
local u110 = u17.new()
u110:Add(task.spawn(function() --[[Anonymous function at line 369]]
--[[
Upvalues:
[1] = u109
[2] = u110
[3] = u37
--]]
local v111 = u109:WaitForChild("UpperTorso")
if v111 then
u110:Add((u37(v111)))
end
end))
return u110:WrapClean()
end))
u29:Add(u16.observeChildren(workspace.RenderedMovingAnimals, function(u112) --[[Anonymous function at line 381]]
--[[
Upvalues:
[1] = u17
[2] = u37
--]]
local u113 = u17.new()
u113:Add(task.spawn(function() --[[Anonymous function at line 384]]
--[[
Upvalues:
[1] = u112
[2] = u113
[3] = u37
--]]
local v114 = u112:WaitForChild("RootPart")
if v114 then
u113:Add((u37(v114)))
end
end))
return u113:WrapClean()
end))
end
local function u193() --[[Anonymous function at line 397]]
--[[
Upvalues:
[1] = u4
[2] = u29
[3] = u25
[4] = u7
[5] = u38
[6] = u61
[7] = u60
[8] = u19
[9] = u115
[10] = u108
[11] = u33
[12] = u3
[13] = u15
[14] = u22
[15] = u23
[16] = u59
[17] = u10
[18] = u49
--]]
u4.Ambient = Color3.fromRGB(50, 50, 50)
u4.OutdoorAmbient = Color3.fromRGB(71, 71, 71)
u29:Add(function() --[[Anonymous function at line 400]]
--[[
Upvalues:
[1] = u4
--]]
u4.Ambient = Color3.fromRGB(241, 241, 241)
u4.OutdoorAmbient = Color3.fromRGB(212, 212, 212)
end)
u29:Add(function() --[[Anonymous function at line 406]]
--[[
Upvalues:
[1] = u25
--]]
u25:Stop()
end)
u29:Add(task.spawn(function() --[[Anonymous function at line 410]]
--[[
Upvalues:
[1] = u7
[2] = u25
[3] = u38
--]]
u7:WaitForAssetId("rbxassetid://136243635275209")
u25.SoundId = "rbxassetid://136243635275209"
while not u25.IsLoaded do
task.wait()
end
u25.TimePosition = workspace:GetServerTimeNow() - (u38.startedAt + 5)
u25:Play()
end))
u29:Clone(script.Night_Sky).Parent = u4
u61.Parent = u60
u19.disable(u61)
local u116 = u29:Add(Instance.new("Color3Value"))
u116.Value = Color3.fromRGB(0, 0, 0)
local u117 = u29:Add(Instance.new("Color3Value"))
u117.Value = Color3.fromRGB(0, 0, 0)
u19.enable(u61)
u19.disable(u61.firestuff)
u115()
u108()
local u118 = {}
local u119 = {}
local u120 = {}
local u121 = {}
local u122 = {}
local u123 = 0
local u124 = 0
local u125 = 1
for _, v126 in u60:GetDescendants() do
if v126:IsA("SpotLight") then
table.insert(u118, v126)
elseif v126:IsA("ParticleEmitter") or v126:IsA("Beam") then
if v126:IsDescendantOf(u61.Square) or v126:IsDescendantOf(u61.bigbeams) then
table.insert(u119, v126)
else
table.insert(u122, v126)
end
if v126:IsA("ParticleEmitter") then
u120[v126] = v126.TimeScale
table.insert(u121, v126)
end
end
end
local u127 = {}
local u128 = {}
local u129 = {}
local u130 = {}
for _, v131 in u61.initial:GetChildren() do
local v132 = v131.att1
u127[v132] = u33()
u128[v132] = u33()
v132.WorldCFrame = CFrame.new(u128[v132])
table.insert(u129, v132)
for _, v133 in v132:GetChildren() do
table.insert(u130, v133)
end
end
local u134 = {}
local u135 = {}
local u136 = {}
for _, v137 in u61.thinbeams:GetChildren() do
local v138 = v137.att1
u127[v138] = u33()
u128[v138] = u33()
v138.WorldCFrame = CFrame.new(u128[v138])
table.insert(u134, v138)
local v139 = {}
for _, v140 in v138:GetChildren() do
v140.Enabled = false
table.insert(v139, v140)
end
u135[v139] = v137.Position.Y
table.insert(u136, v139)
end
table.sort(u136, function(p141, p142) --[[Anonymous function at line 501]]
--[[
Upvalues:
[1] = u135
--]]
return u135[p141] < u135[p142]
end)
local u143 = false
local u144 = false
local u145 = 0
u29:Add(u3.PostSimulation:Connect(function(p146) --[[Anonymous function at line 509]]
--[[
Upvalues:
[1] = u124
[2] = u123
[3] = u25
[4] = u121
[5] = u120
[6] = u145
[7] = u127
[8] = u33
[9] = u134
[10] = u129
[11] = u128
[12] = u136
[13] = u143
[14] = u19
[15] = u61
[16] = u130
[17] = u144
[18] = u38
[19] = u125
[20] = u15
[21] = u116
[22] = u22
[23] = u23
[24] = u117
[25] = u59
[26] = u122
[27] = u119
[28] = u118
[29] = u10
--]]
local v147 = workspace:GetServerTimeNow()
u124 = u124 - p146
u123 = u123 - p146
local v148 = u25.TimePosition
local v149 = u25.PlaybackLoudness
local v150 = v149 / 1000
local v151 = math.clamp(v150, 0, 1)
for _, v152 in u121 do
local v153 = v151 / 0.05
v152.TimeScale = math.clamp(v153, 1, 2) * u120[v152]
end
if v149 >= 320 and v147 - u145 >= 2 then
u145 = v147
for v154, _ in u127 do
u127[v154] = u33()
end
end
for _, v155 in { u134, u129 } do
for _, v156 in v155 do
local v157 = u128[v156]
local v158 = u127[v156]
local v159 = v158 - v157
local v160 = vector.magnitude(v159)
local v161 = (v149 - 100) / 200
local v162 = math.clamp(v161, 0, 1)
local v163 = math.lerp(35, 120, v162) * p146
if v160 < v163 then
u127[v156] = u33()
else
v158 = v157 + vector.normalize(v159) * v163
end
u128[v156] = v158
v156.WorldCFrame = CFrame.new(v158)
end
end
if v148 >= 17 then
local v164 = (v148 - 17) // #u136
local v165 = math.max(v164, 2)
if v148 >= 82 then
v165 = v165 + 10
end
local v166 = #u136
for v167 = 1, math.min(v165, v166) do
for _, v168 in u136[v167] do
v168.Enabled = true
end
end
end
if v148 >= 17 and not u143 then
u19.enable(u61.firestuff)
task.delay(5.5, function() --[[Anonymous function at line 569]]
--[[
Upvalues:
[1] = u19
[2] = u61
--]]
u19.disable(u61.firestuff)
end)
u143 = true
for _, v169 in u130 do
v169.Enabled = false
end
end
if v148 >= 83 and not u144 then
u144 = true
u19.enable(u61.firestuff)
task.delay(5.5, function() --[[Anonymous function at line 583]]
--[[
Upvalues:
[1] = u19
[2] = u61
--]]
u19.disable(u61.firestuff)
end)
end
if v151 >= 0.11 and u123 <= 0 then
local v170 = u38.startedAt + 6 - workspace:GetServerTimeNow()
if math.max(v170, 0) <= 0 then
u123 = 0.4
u125 = u125 == 1 and 2 or 1
local v171 = u15
local v172 = u116
local v173 = TweenInfo.new(0.2)
local v174 = {}
local v175
if u125 == 1 then
v175 = u22
else
v175 = u23
end
v174.Value = v175
v171(v172, v173, v174)
local v176 = u15
local v177 = u117
local v178 = TweenInfo.new(0.2)
local v179 = {}
local v180
if u125 == 1 then
v180 = u23
else
v180 = u22
end
v179.Value = v180
v176(v177, v178, v179)
end
end
if u59 then
local v181 = u59
local v182 = v151 / 0.07
v181:AdjustSpeed((math.clamp(v182, 0.8, 1.5)))
end
local v183 = u116.Value
local v184 = u117.Value
local v185 = ColorSequence.new(v183)
local v186 = ColorSequence.new(v184)
for _, v187 in u122 do
v187.Color = v185
end
for _, v188 in u119 do
v188.Color = v186
end
for _, v189 in u118 do
v189.Color = v183
end
if v151 >= 0.1 and u124 <= 0 then
u124 = 0.1
u10:Fov(v151 / 0.7 * 15 + 70, 0.1)
end
end))
u29:Add((u49(5, 6, function(p190) --[[Anonymous function at line 631]]
--[[
Upvalues:
[1] = u15
[2] = u116
[3] = u22
[4] = u117
[5] = u23
--]]
local v191 = {
["Value"] = u22
}
u15(u116, TweenInfo.new(p190()), v191)
local v192 = {
["Value"] = u23
}
u15(u117, TweenInfo.new(p190()), v192)
end)))
u60.Parent = workspace
end
u29:Add((u49(0, 5, function(p194) --[[Anonymous function at line 644]]
--[[
Upvalues:
[1] = u15
[2] = u58
[3] = u9
[4] = u29
[5] = u193
[6] = u38
--]]
u15(u58, TweenInfo.new(p194(), Enum.EasingStyle.Sine, Enum.EasingDirection.Out), {
["Brightness"] = -1.2
})
u9:Run("BrazilEvent", "GrassRecolor")
u29:Add(function() --[[Anonymous function at line 650]]
--[[
Upvalues:
[1] = u9
--]]
u9:Stop("BrazilEvent", "GrassRecolor")
end)
u29:Add(task.delay(p194(), function() --[[Anonymous function at line 654]]
--[[
Upvalues:
[1] = u193
[2] = u15
[3] = u58
[4] = u38
--]]
u193()
local v195 = u15
local v196 = u58
local v197 = TweenInfo.new
local v198 = u38.startedAt + 6 - workspace:GetServerTimeNow()
v195(v196, v197(math.max(v198, 0), Enum.EasingStyle.Sine, Enum.EasingDirection.Out), {
["Brightness"] = 0
})
end))
end)))
local v199 = u29
local v200 = task.delay
local v201 = u38.startedAt + 20 - workspace:GetServerTimeNow()
v199:Add(v200(math.max(v201, 0), function() --[[Anonymous function at line 182]]
--[[
Upvalues:
[1] = u29
[2] = u16
[3] = u5
[4] = u17
[5] = u59
[6] = u3
[7] = u38
[8] = u20
--]]
u29:Add(u16.observeCharacter(u5.LocalPlayer, function(_, u202) --[[Anonymous function at line 184]]
--[[
Upvalues:
[1] = u17
[2] = u59
[3] = u3
[4] = u38
[5] = u20
--]]
local u203 = u17.new()
u203:Add(task.spawn(function() --[[Anonymous function at line 187]]
--[[
Upvalues:
[1] = u202
[2] = u59
[3] = u203
[4] = u3
[5] = u38
[6] = u20
--]]
local u204 = u202:WaitForChild("Humanoid")
if u204 then
local v205 = u204:WaitForChild("Animator")
if v205 then
local u206 = v205:LoadAnimation(script.Dance)
u206.Priority = Enum.AnimationPriority.Action
u59 = u206
local u207 = 0
u203:Add(u3.PostSimulation:Connect(function(p208) --[[Anonymous function at line 205]]
--[[
Upvalues:
[1] = u38
[2] = u206
[3] = u204
[4] = u20
[5] = u207
--]]
workspace:GetServerTimeNow()
local v209 = u38.startedAt + 55 - workspace:GetServerTimeNow()
if math.max(v209, 0) > 0 then
if not u206.IsPlaying then
u206:Play()
end
elseif u204.MoveDirection ~= Vector3.new(0, 0, 0) or u20:GetAttribute("Stealing") then
u207 = 0
if u206.IsPlaying then
u206:Stop()
end
else
if u207 < 3 then
u207 = u207 + p208
return
end
if not u206.IsPlaying then
u206:Play()
return
end
end
end))
u203:Add(function() --[[Anonymous function at line 231]]
--[[
Upvalues:
[1] = u206
[2] = u59
--]]
u206:Stop()
u206:Destroy()
u59 = nil
end)
end
else
return
end
end))
return u203:WrapClean()
end))
end))
u13:Update()
u11:UpdateOST()
end
function v6.OnStop(_) --[[Anonymous function at line 669]]
--[[
Upvalues:
[1] = u29
--]]
u29:Destroy()
end
function v6.OnLoad(_) --[[Anonymous function at line 673]]
--[[
Upvalues:
[1] = u2
--]]
task.spawn(pcall, function() --[[Anonymous function at line 674]]
--[[
Upvalues:
[1] = u2
--]]
u2:PreloadAsync(script:GetChildren())
end)
end
return v6
- Edit
03:12:20.355
- Edit
03:12:20.357
============================== - Edit
03:12:20.357 📜 ReplicatedStorage.Controllers.EventController.Events.Los Matteos - Edit
03:12:20.357 ==============================
- Edit
03:12:20.357 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
game:GetService("ServerScriptService")
local u1 = game:GetService("ReplicatedStorage")
local u2 = game:GetService("ContentProvider")
local u3 = game:GetService("RunService")
local u4 = game:GetService("Players")
local u5 = game:GetService("Debris")
require(u1.Shared.EventTypes)
local v6 = {}
local u7 = require(u1.Controllers.EffectController)
require(u1.Controllers.AnimalController)
local u8 = require(u1.Controllers.SoundController)
local u9 = require(u1.Controllers.CycleController)
local u10 = require(u1.Controllers.EventController)
require(u1.Controllers.EventController.ClientEventUtils)
local u11 = require(u1.Shared.SharedEventUtils)
local u12 = require(u1.Packages.EvLightning)
local u13 = require(u1.Packages.CreateTween)
local u14 = require(u1.Shared.ShakePresets)
local u15 = require(u1.Packages.Observers)
require(u1.Utils.MathUtils)
require(u1.Shared.Snapshot)
require(script.TreeRootAnimator)
local v16 = require(u1.Packages.Shake)
local v17 = require(u1.Packages.Trove)
local v18 = require(u1.Packages.Net)
local u19 = require(u1.Shared.VFX)
local u20 = script.Name
local u21 = script.Clouds:GetChildren()
local u22 = workspace.Events["Los Matteos"].CloudsStart
local u23 = workspace.Events["Los Matteos"].CloudsEnd
local u24 = v18:RemoteEvent("EventService/Los Matteos/CreateLightningBolt")
local u25 = RaycastParams.new()
u25.FilterDescendantsInstances = { workspace.Events["Los Matteos"].Areas }
u25.FilterType = Enum.RaycastFilterType.Include
local u26 = v17.new()
local u27 = Instance.new("Part")
u27.Anchored = true
u27.CanCollide = false
u27.TopSurface = Enum.SurfaceType.Smooth
u27.BottomSurface = Enum.SurfaceType.Smooth
u27.Material = Enum.Material.Neon
u27.Color = Color3.fromRGB(96, 234, 255)
local u28 = v16.new()
u28.Amplitude = 3
u28.Frequency = 0.1
u28.FadeInTime = 0
u28.FadeOutTime = 0.6
u28.PositionInfluence = Vector3.new(0.5, 0.5, 0.5)
u28.RotationInfluence = Vector3.new(2.5, 0.5, 0.5)
local function u46() --[[Anonymous function at line 64]]
--[[
Upvalues:
[1] = u26
[2] = u3
[3] = u15
--]]
local v29 = u26:Extend()
local u30 = table.create(4)
v29:Add(function() --[[Anonymous function at line 76]]
--[[
Upvalues:
[1] = u30
--]]
table.clear(u30)
end)
local u31 = 0
v29:Add(u3.PreRender:Connect(function(p32) --[[Anonymous function at line 81]]
--[[
Upvalues:
[1] = u31
[2] = u30
--]]
debug.profilebegin("Los Matteos Event")
u31 = u31 + p32
for v33, v34 in u30 do
if v34.target and v34.targetAttachment then
v34.beam.First.Enabled = true
v34.beam.Second.Enabled = true
local v35 = u31 - v33 + 1
local v36 = math.clamp(v35, 0, 1)
local v37 = v34.beam.WorldPosition
v34.targetAttachment.Position = v37 + (v34.target:GetPivot().Position - v37) * v36
end
end
debug.profileend()
end))
v29:Add(u15.observeTag("LosMatteosPlayerVFX", function(u38) --[[Anonymous function at line 103]]
--[[
Upvalues:
[1] = u30
[2] = u15
--]]
local u39 = script.PlayerVFX.Beam:Clone()
u39.Parent = u38
local u40 = script.PlayerVFX.Torso:Clone()
u40.Parent = u38
local u41 = u38:GetAttribute("LosMatteosIndex")
u30[u41] = {
["beam"] = u39,
["target"] = nil
}
local u45 = u15.observeTag("LosMatteosPlayerVFX", function(p42) --[[Anonymous function at line 116]]
--[[
Upvalues:
[1] = u38
[2] = u39
[3] = u30
--]]
if p42 == u38 then
return nil
end
if p42:GetAttribute("LosMatteosIndex") ~= u38:GetAttribute("LosMatteosIndex") % 3 + 1 then
return nil
end
local u43 = Instance.new("Attachment")
u43.Position = u39.WorldPosition
u43.Parent = workspace.Terrain
local v44 = u30[u38:GetAttribute("LosMatteosIndex")]
v44.target = p42
v44.beam.First.Attachment0 = u43
v44.beam.Second.Attachment0 = u43
v44.targetAttachment = u43
return function() --[[Anonymous function at line 135]]
--[[
Upvalues:
[1] = u43
--]]
u43:Destroy()
end
end)
return function() --[[Anonymous function at line 140]]
--[[
Upvalues:
[1] = u40
[2] = u39
[3] = u45
[4] = u30
[5] = u41
--]]
u40:Destroy()
u39:Destroy()
u45()
u30[u41] = nil
end
end))
end
function v6.OnStart(_) --[[Anonymous function at line 150]]
--[[
Upvalues:
[1] = u10
[2] = u20
[3] = u1
[4] = u25
[5] = u26
[6] = u7
[7] = u9
[8] = u8
[9] = u13
[10] = u15
[11] = u4
[12] = u22
[13] = u23
[14] = u21
[15] = u3
[16] = u11
[17] = u24
[18] = u28
[19] = u14
[20] = u19
[21] = u5
[22] = u12
[23] = u27
[24] = u46
--]]
local u47 = u10:GetActiveEventData(u20)
assert(u47)
local u48 = u1:GetAttribute("LosMatteosSpawn")
if not u48 then
u48 = workspace.MapCenter.Position
local v49 = workspace:Raycast(u48, Vector3.new(-0, -25, -0), u25)
if v49 then
local v50 = u48.X
local v51 = v49.Position.Y
local v52 = u48.Z
u48 = Vector3.new(v50, v51, v52)
end
end
u1:SetAttribute("LosMatteosEvent", true)
u26:Add(function() --[[Anonymous function at line 164]]
--[[
Upvalues:
[1] = u1
[2] = u7
[3] = u9
[4] = u8
--]]
u1:SetAttribute("LosMatteosEvent", nil)
u7:Activate("Blink")
u9:Update()
u8:UpdateOST()
u8:UpdateAmbience()
end)
local function u84(p53, p54, u55) --[[Anonymous function at line 177]]
--[[
Upvalues:
[1] = u26
[2] = u13
--]]
local function v71(u56, u57, u58, p59) --[[Anonymous function at line 178]]
--[[
Upvalues:
[1] = u26
[2] = u55
[3] = u13
--]]
local u60 = u56.CFrame
local v61 = p59 and 0 or u57.X
local v62 = p59 and 0 or u57.Z
local v63 = Vector3.new(v61, 0, v62)
local v64 = u60 * CFrame.new(0, -(u57.Y - v63.Y) / 2, 0)
u56.Size = v63
u56.CFrame = v64
local u65 = u56.Transparency
u56.Transparency = 1
local v66 = u26
local v67 = task.delay
local v68
if u55 then
v68 = u55(u58)
else
v68 = u58
end
v66:Add(v67(v68, function() --[[Anonymous function at line 189]]
--[[
Upvalues:
[1] = u56
[2] = u65
[3] = u55
[4] = u58
[5] = u13
[6] = u57
[7] = u60
--]]
u56.Transparency = u65
local v69 = not u55 and 1 or u55(u58 + 1)
local v70 = TweenInfo.new(v69, Enum.EasingStyle.Quint, Enum.EasingDirection.Out)
u13(u56, v70, {
["Size"] = u57
})
u13(u56, v70, {
["CFrame"] = u60
})
end))
end
local v72 = {}
local v73 = (1 / 0)
local v74 = (-1 / 0)
for _, v75 in p53:GetDescendants() do
if v75:IsA("BasePart") and v75.Transparency < 1 then
table.insert(v72, v75)
local v76 = v75.Position.Y
v73 = math.min(v73, v76)
local v77 = v75.Position.Y
v74 = math.max(v74, v77)
end
end
table.sort(v72, function(p78, p79) --[[Anonymous function at line 215]]
return p78.Position.Y < p79.Position.Y
end)
local v80 = v74 - v73
for _, v81 in v72 do
local v82 = v81.Color.R * 255 < 90
local v83 = (v81.Position.Y - v73) / v80 * p54
if v82 then
v83 = v83 + 0.2
end
v71(v81, v81.Size, v83, v82)
end
end
u26:Add(task.spawn(function() --[[Anonymous function at line 231]]
--[[
Upvalues:
[1] = u8
[2] = u1
[3] = u48
--]]
u8:PlaySound(u1.Sounds.Events["Los Matteos"].Grow, u48, false)
end))
u26:Add(task.delay(u47.startedAt + 3 - workspace:GetServerTimeNow(), function() --[[Anonymous function at line 235]]
--[[
Upvalues:
[1] = u1
[2] = u26
[3] = u9
[4] = u8
[5] = u48
[6] = u84
[7] = u47
--]]
u1:SetAttribute("LosMatteosEventNightTime", true)
u26:Add(function() --[[Anonymous function at line 237]]
--[[
Upvalues:
[1] = u1
--]]
u1:SetAttribute("LosMatteosEventNightTime", nil)
end)
u9:Update()
u8:UpdateOST()
u8:UpdateAmbience()
local v85 = u26:Clone(script.Tree)
v85:PivotTo(CFrame.new(u48))
if u1:GetAttribute("LosMatteosEventIsRainbow") then
for _, v86 in v85.Leaves:GetDescendants() do
v86:SetAttribute("RainbowIgnoreTransparency", true)
v86:AddTag("RainbowModel")
end
end
v85.Parent = workspace
u84(v85, 5, function(p87) --[[Anonymous function at line 257]]
--[[
Upvalues:
[1] = u47
--]]
local v88 = p87 + 3
return u47.startedAt + v88 - workspace:GetServerTimeNow()
end)
end))
u26:Add(task.delay(u47.startedAt + 7 - workspace:GetServerTimeNow(), function() --[[Anonymous function at line 262]]
--[[
Upvalues:
[1] = u1
--]]
u1.Sounds.Events["Los Matteos"].Roots:Play()
end))
u26:Add(function() --[[Anonymous function at line 266]]
--[[
Upvalues:
[1] = u1
--]]
u1.Sounds.Events["Los Matteos"].Roots:Stop()
end)
u26:Add(u1:GetAttributeChangedSignal("LosMatteosGrowing"):Connect(function() --[[Anonymous function at line 270]]
--[[
Upvalues:
[1] = u1
--]]
u1.Sounds.Events["Los Matteos"].Roots.Looped = u1:GetAttribute("LosMatteosGrowing") ~= false
end))
u26:Add(u15.observeTag("LosMatteos_Tree", function(p89) --[[Anonymous function at line 274]]
--[[
Upvalues:
[1] = u84
--]]
u84(p89, 1)
return nil
end))
u26:Add(u15.observeCharacter(u4.LocalPlayer, function(_, p90) --[[Anonymous function at line 279]]
--[[
Upvalues:
[1] = u26
[2] = u15
--]]
return u26:Add(u15.observeAttribute(p90, "Matteo_CollectedTree", function(p91) --[[Anonymous function at line 280]]
--[[
Upvalues:
[1] = u26
[2] = u15
--]]
if p91 then
return u26:Add(u15.observeTag("LosMatteos_TreePrompt", function(u92) --[[Anonymous function at line 286]]
u92.Enabled = false
return function() --[[Anonymous function at line 290]]
--[[
Upvalues:
[1] = u92
--]]
u92.Enabled = true
end
end, { workspace }))
else
return nil
end
end))
end))
local u93 = {}
local function v123() --[[Anonymous function at line 306]]
--[[
Upvalues:
[1] = u22
[2] = u23
[3] = u26
[4] = u21
[5] = u13
[6] = u93
[7] = u3
[8] = u11
--]]
local function u109(p94, p95) --[[Anonymous function at line 310]]
--[[
Upvalues:
[1] = u22
[2] = u23
[3] = u26
[4] = u21
[5] = u13
[6] = u93
--]]
local v96 = u22.Position
local v97 = u22.Size
local v98 = u23.Position
local v99 = u26:Clone(u21[math.random(1, #u21)])
v99.Transparency = 1
v99.CFrame = CFrame.new(v96.X + math.random(-v97.X * 0.5, v97.X * 0.5), v96.Y, v96.Z + (p94 or 0) * 30 + (p95 or 0))
local v100 = v99.Position.X
local v101 = v96.Y
local v102 = v98.Z
local v103 = Vector3.new(v100, v101, v102)
local v104 = v98 - v96
local v105 = v103 - v99.Position
if vector.dot(v104, v105) >= 0 then
v99.Parent = workspace.Camera
local v106 = 50 / v99.Size.Magnitude
local v107 = {
["instance"] = v99,
["speed"] = math.clamp(v106, 5, 15) * (math.random(80, 120) / 100),
["startPos"] = v99.Position,
["endPos"] = v103
}
u26:Add(u13(v99, TweenInfo.new(0.5, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, (p95 or 0) * 0.1 + (math.abs(p94 or 0) + 1) * 0.5), {
["Transparency"] = 0
}))
local v108 = u93
table.insert(v108, v107)
return v107
end
end
local v110 = 0
for v111 = 1, 50 do
u109(v110, v111)
if v111 % 3 == 1 then
v110 = v110 + 1
end
end
u26:Add(u3.PostSimulation:Connect(function(p112) --[[Anonymous function at line 360]]
--[[
Upvalues:
[1] = u93
[2] = u26
[3] = u13
[4] = u109
[5] = u11
--]]
for v113 = #u93, 1, -1 do
local v114 = u93[v113]
local u115 = v114.instance
local v116 = u115.Position
local v117 = v114.endPos - v116
local v118 = vector.normalize(v117)
local v119 = v114.endPos - v116
local v120 = vector.magnitude(v119)
local v121 = v114.speed * p112
local v122
if v120 < v121 then
v122 = v114.endPos
table.remove(u93, v113)
u26:Add(u13(u115, TweenInfo.new(0.5, Enum.EasingStyle.Sine, Enum.EasingDirection.In), {
["Transparency"] = 1
})).Completed:Once(function() --[[Anonymous function at line 379]]
--[[
Upvalues:
[1] = u26
[2] = u115
--]]
u26:Remove(u115)
end)
u109()
else
v122 = v116 + v118 * v121
end
u11.pushPartCFrame(u115, CFrame.lookAt(v122, v122 + v118))
end
end))
end
u26:Add(task.delay(u47.startedAt + 8 - workspace:GetServerTimeNow(), function() --[[Anonymous function at line 394]]
--[[
Upvalues:
[1] = u26
--]]
u26:Clone(script.RainWeather).Parent = workspace
end))
u26:Add(u24.OnClientEvent:Connect(function(p124, u125, u126) --[[Anonymous function at line 399]]
--[[
Upvalues:
[1] = u28
[2] = u26
[3] = u14
[4] = u93
[5] = u8
[6] = u1
[7] = u13
[8] = u19
[9] = u5
[10] = u12
[11] = u27
--]]
local v127 = Random.new(p124)
local v128 = (workspace.CurrentCamera.CFrame.Position - u125).Magnitude
if v128 <= 75 then
local v129 = u28:Clone()
local v130 = (1 - v128 / 75 * 0.5) ^ 2
v129.Amplitude = v129.Amplitude * v130
v129.RotationInfluence = v129.RotationInfluence * v130
u26:Add(u14.BindShakeToCamera(v129))
v129:Start()
end
local v131 = {}
for _, v132 in u93 do
if ((v132.instance.Position - u125) * Vector3.new(1, 0, 1)).Magnitude < 100 then
local v133 = v132.instance
table.insert(v131, v133)
end
end
local v134
if #v131 > 0 then
local v135 = v131[v127:NextInteger(1, #v131)]
v134 = v135.Position
u8:PlaySound(u1.Sounds.Events["Los Matteos"]["Lightning Strike"], v135.Position, false)
local v136 = v135.Color
v135.Color = Color3.fromRGB(90, 109, 161)
u13(v135, TweenInfo.new(1, Enum.EasingStyle.Sine), {
["Color"] = v136
})
for _, v137 in script.CloudParticles:GetChildren() do
local v138 = v137:Clone()
v138.Parent = v135
u19.emit(v138)
u5:AddItem(v138, 2)
end
else
v134 = u125 + Vector3.new(0, 70, 0)
end
local u139 = u12.create(v134, u125, {
["bends"] = 4,
["thickness"] = 1,
["max_depth"] = 1,
["fork_bends"] = 1,
["fork_chance"] = 30,
["decay"] = 3,
["material"] = Enum.Material.Neon
})
local u140 = Instance.new("Model")
u139.model = u140
u140.Name = "LightningBolt"
local v141 = u139:GetLines()
table.sort(v141, function(p142, p143) --[[Anonymous function at line 465]]
return p142.origin.Y > p143.origin.Y
end)
local v144 = v141[#v141].origin.Y
local v145 = v141[1].origin.Y
local v146 = v145 - v144
local v147 = u139.random:NextInteger(10, 20) / 100
local u148 = table.create(#v141)
for v149, v150 in v141 do
if v150.goal.Y >= u125.Y then
local v151 = (v145 - v150.origin.Y) / v146 * v147
local v152 = math.max(v151, 0)
local v153 = u27:Clone()
local v154 = u139.thickness - v150.depth * 2 * 0.1
local v155 = u139.thickness - v150.depth * 2 * 0.1
local v156 = (v150.origin - v150.goal).Magnitude + 0.5
v153.Size = Vector3.new(v154, v155, v156)
v153.CFrame = CFrame.new((v150.goal + v150.origin) / 2, v150.goal)
v153.Transparency = 1
v153.Parent = u140
u148[v149] = v153
u13(v153, TweenInfo.new(0.05, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, v152), {
["Transparency"] = v150.transparency
})
end
end
task.delay(v147 + 0.05, function() --[[Anonymous function at line 496]]
--[[
Upvalues:
[1] = u126
[2] = u125
[3] = u19
[4] = u8
[5] = u1
[6] = u148
[7] = u13
[8] = u139
[9] = u140
--]]
local u157
if u126 then
u157 = script.StrikeBrainrot:Clone()
else
u157 = script.Strike:Clone()
end
u157.Position = u125
u157.Parent = workspace
u19.emit(u157)
if u126 then
u8:PlaySound(u1.Sounds.Events["Los Matteos"].Hit, u125, false)
else
u8:PlaySound(u1.Sounds.Events["Los Matteos"].HitNothing, u125, false)
end
for _, u158 in u148 do
task.spawn(function() --[[Anonymous function at line 510]]
--[[
Upvalues:
[1] = u158
[2] = u13
--]]
u158.Transparency = 0
task.wait(0.1)
u158.Transparency = 1
task.wait(0.1)
u13(u158, TweenInfo.new(0.1, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, true), {
["Transparency"] = 0.4
})
end)
end
task.delay(u139.options.decay or 1, function() --[[Anonymous function at line 521]]
--[[
Upvalues:
[1] = u157
[2] = u140
[3] = u139
--]]
u157:Destroy()
u140:Destroy()
u139.destroyed = true
end)
end)
u140.Parent = workspace.CurrentCamera
u139.drew = true
end))
v123()
u26:Add(task.spawn(function() --[[Anonymous function at line 534]]
--[[
Upvalues:
[1] = u46
--]]
u46()
end))
end
function v6.OnStop(_) --[[Anonymous function at line 539]]
--[[
Upvalues:
[1] = u26
--]]
u26:Destroy()
end
function v6.OnLoad(_) --[[Anonymous function at line 543]]
--[[
Upvalues:
[1] = u2
--]]
task.spawn(pcall, function() --[[Anonymous function at line 544]]
--[[
Upvalues:
[1] = u2
--]]
u2:PreloadAsync(script:GetChildren())
end)
end
return v6 - Edit
03:12:20.357
- Edit
03:12:20.358
============================== - Edit
03:12:20.358 📜 ReplicatedStorage.Controllers.EventController.Events.Los Matteos.TreeRootAnimator - Edit
03:12:20.358 ==============================
- Edit
03:12:20.358 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
local u1 = game:GetService("RunService")
local v2 = game:GetService("ReplicatedStorage")
local v3 = require(v2.Packages.Observers)
local u4 = require(v2.Packages.Trove)
local u5 = {
"StartX",
"StartZ",
"Direction",
"FromLength",
"ToLength",
"TweenDuration",
"TweenId",
"ThicknessY",
"PauseUntil"
}
local u6 = {}
local u7 = {}
local u8 = {}
local u9 = nil
local function u14(p10) --[[Anonymous function at line 37]]
--[[
Upvalues:
[1] = u5
--]]
local v11 = {}
for _, v12 in u5 do
local v13 = p10:GetAttribute(v12)
if typeof(v13) ~= "number" and typeof(v13) ~= "Vector2" then
return nil
end
v11[v12] = v13
end
v11.Elapsed = 0
v11.Part = p10
return v11
end
local function u29(p15, p16) --[[Anonymous function at line 55]]
local v17 = p15.Part.Position.Y
local v18 = p16 or p15.FromLength
local v19 = (v18 - 1) * 0.5
local v20
if p15.Direction.X == 0 then
local v21 = p15.StartX + 0.5
local v22 = p15.StartZ + p15.Direction.Y * v19
v20 = Vector3.new(v21, v17, v22)
else
local v23 = p15.StartX + p15.Direction.X * v19
local v24 = p15.StartZ + 0.5
v20 = Vector3.new(v23, v17, v24)
end
local v25 = p15.Direction.X == 0 and 2 or math.max(1, v18)
local v26 = p15.Direction.Y == 0 and 2 or math.max(1, v18)
local v27 = p15.Part
local v28 = p15.ThicknessY
v27.Size = Vector3.new(v25, v28, v26)
p15.Part.CFrame = CFrame.new(v20)
end
local function u44(p30) --[[Anonymous function at line 132]]
--[[
Upvalues:
[1] = u14
[2] = u8
[3] = u7
[4] = u6
[5] = u29
[6] = u9
[7] = u1
--]]
local v31 = u14(p30)
if v31 then
local v32 = v31.TweenId
if u8[p30] == v32 then
return
else
u8[p30] = v32
if workspace:GetServerTimeNow() < v31.PauseUntil then
u7[p30] = v31
u6[p30] = nil
else
u6[p30] = v31
u7[p30] = nil
end
u29(v31)
if not (u9 and u9.Connected) then
u9 = u1.PostSimulation:Connect(function(p33) --[[Anonymous function at line 80]]
--[[
Upvalues:
[1] = u6
[2] = u9
[3] = u7
[4] = u29
--]]
if next(u6) == nil and (u9 ~= nil and u9.Connected) then
u9:Disconnect()
u9 = nil
else
local v34 = workspace:GetServerTimeNow()
for v35, v36 in u7 do
if v36.PauseUntil <= v34 then
u6[v35] = v36
u7[v35] = nil
u29(v36)
else
u29(v36)
end
end
local v37 = 0
for v38, v39 in u6 do
if v34 < v39.PauseUntil then
u7[v38] = v39
u6[v38] = nil
u29(v39)
else
v39.Elapsed = v39.Elapsed + p33
local v40 = v39.TweenDuration
local v41 = math.max(v40, 0.011111111111111112)
local v42 = v39.Elapsed / v41
local v43 = math.clamp(v42, 0, 1)
u29(v39, v39.FromLength + (v39.ToLength - v39.FromLength) * v43)
if v43 >= 1 then
u6[v38] = nil
end
end
v37 = v37 + 1
if v37 >= 3 then
break
end
end
end
end)
end
end
else
return
end
end
return v3.observeTag("RootRunTween", function(u45) --[[Anonymous function at line 165]]
--[[
Upvalues:
[1] = u4
[2] = u44
[3] = u6
[4] = u7
[5] = u29
[6] = u14
[7] = u9
[8] = u1
[9] = u8
--]]
if not u45:IsA("BasePart") then
return nil
end
local u46 = u4.new()
u44(u45)
u46:Add(u45:GetAttributeChangedSignal("TweenId"):Connect(function() --[[Anonymous function at line 176]]
--[[
Upvalues:
[1] = u44
[2] = u45
--]]
u44(u45)
end))
u46:Add(u45:GetAttributeChangedSignal("PauseUntil"):Connect(function() --[[Anonymous function at line 180]]
--[[
Upvalues:
[1] = u45
[2] = u6
[3] = u7
[4] = u29
[5] = u14
[6] = u9
[7] = u1
--]]
local v47 = u45:GetAttribute("PauseUntil") or 0
local v48 = workspace:GetServerTimeNow()
local v49 = u6[u45]
local v50 = u7[u45]
if v48 < v47 then
if v49 then
v49.PauseUntil = v47
u7[u45] = v49
u6[u45] = nil
u29(v49)
elseif v50 then
v50.PauseUntil = v47
u29(v50)
else
local v51 = u14(u45)
if v51 then
u7[u45] = v51
u29(v51)
end
end
if u9 and u9.Connected then
return
end
u9 = u1.PostSimulation:Connect(function(p52) --[[Anonymous function at line 80]]
--[[
Upvalues:
[1] = u6
[2] = u9
[3] = u7
[4] = u29
--]]
if next(u6) == nil and (u9 ~= nil and u9.Connected) then
u9:Disconnect()
u9 = nil
else
local v53 = workspace:GetServerTimeNow()
for v54, v55 in u7 do
if v55.PauseUntil <= v53 then
u6[v54] = v55
u7[v54] = nil
u29(v55)
else
u29(v55)
end
end
local v56 = 0
for v57, v58 in u6 do
if v53 < v58.PauseUntil then
u7[v57] = v58
u6[v57] = nil
u29(v58)
else
v58.Elapsed = v58.Elapsed + p52
local v59 = v58.TweenDuration
local v60 = math.max(v59, 0.011111111111111112)
local v61 = v58.Elapsed / v60
local v62 = math.clamp(v61, 0, 1)
u29(v58, v58.FromLength + (v58.ToLength - v58.FromLength) * v62)
if v62 >= 1 then
u6[v57] = nil
end
end
v56 = v56 + 1
if v56 >= 3 then
break
end
end
end
end)
end
end))
return function() --[[Anonymous function at line 212]]
--[[
Upvalues:
[1] = u46
[2] = u6
[3] = u45
[4] = u8
--]]
u46:Destroy()
u6[u45] = nil
u8[u45] = nil
end
end) - Edit
03:12:20.358
- Edit
03:12:20.358
============================== - Edit
03:12:20.358 📜 ReplicatedStorage.Controllers.EventController.Events.Starfall - Edit
03:12:20.358 ==============================
- Edit
03:12:20.358 -- Thanks For Angelus Decompiles --> https://discord.gg/CYXme7yEG9
-- Decompiled with Velocity Script Decompiler
local v_u_1 = game:GetService("ReplicatedStorage")
local v_u_2 = game:GetService("TweenService")
local v_u_3 = game:GetService("Debris")
local v_u_4 = game:GetService("Lighting")
require(v_u_1.Shared.EventTypes)
local v5 = {}
local v6 = require(v_u_1.Packages.Net)
local v7 = require(v_u_1.Packages.Trove)
local v_u_8 = require(v_u_1.Shared.VFX)
local v9 = require(v_u_1.Packages.Shake)
local v_u_10 = require(v_u_1.Shared.ShakePresets)
local v_u_11 = require(v_u_1.Controllers.CycleController)
local v_u_12 = require(v_u_1.Controllers.SoundController)
local v_u_13 = require(v_u_1.Controllers.EventController)
local v_u_14 = require(v_u_1.Controllers.EffectController)
local v_u_15 = require(v_u_1.Controllers.AnimalController)
local v_u_16 = v6:RemoteEvent("EventService/Starfall/CreateStar")
local v_u_17 = v6:RemoteEvent("EventService/Starfall/ExplodeStar")
local v_u_18 = script.Name
local v_u_19 = v9.new()
v_u_19.Amplitude = 1.5
v_u_19.Frequency = 0.1
v_u_19.FadeInTime = 0
v_u_19.FadeOutTime = 0.6
v_u_19.PositionInfluence = Vector3.new(0.2, 0.2, 0.2)
v_u_19.RotationInfluence = Vector3.new(2.5, 0.5, 0.5)
local v_u_20 = v7.new()
local v_u_21 = {}
function v5.OnStart(_)
-- upvalues: (copy) v_u_13, (copy) v_u_18, (copy) v_u_1, (copy) v_u_20, (copy) v_u_14, (copy) v_u_8, (copy) v_u_4, (copy) v_u_11, (copy) v_u_12
local v22 = v_u_13:GetActiveEventData(v_u_18)
assert(v22)
v_u_1:SetAttribute("Starfall", true)
v_u_20:Add(function()
-- upvalues: (ref) v_u_1
v_u_1:SetAttribute("Starfall", nil)
end)
v_u_20:Add(function()
-- upvalues: (ref) v_u_14
v_u_14:Activate("Blink")
end)
local v_u_23 = v_u_20:Clone(script.StarfallWeather)
v_u_8.disable(v_u_23)
v_u_23.Parent = workspace
local v24 = v22.startedAt + 4 - workspace:GetServerTimeNow()
v_u_20:Add(task.delay(v24, function()
-- upvalues: (ref) v_u_14, (ref) v_u_4, (ref) v_u_20, (ref) v_u_8, (copy) v_u_23
v_u_14:Activate("Blink")
local v_u_25 = v_u_4:FindFirstChildOfClass("Atmosphere")
if v_u_25 then
v_u_25.Parent = script
v_u_20:Add(function()
-- upvalues: (copy) v_u_25, (ref) v_u_4
v_u_25.Parent = v_u_4
end)
end
v_u_20:Clone(script.Atmosphere).Parent = v_u_4
local v_u_26 = v_u_4:FindFirstChildOfClass("Sky")
if v_u_26 then
v_u_26.Parent = script
v_u_20:Add(function()
-- upvalues: (copy) v_u_26, (ref) v_u_4
v_u_26.Parent = v_u_4
end)
end
v_u_20:Clone(script.Sky).Parent = v_u_4
v_u_8.enable(v_u_23)
end))
v_u_11:Update()
v_u_12:UpdateOST()
end
function v5.OnStop(_)
-- upvalues: (copy) v_u_20, (copy) v_u_21
v_u_20:Destroy()
for _, v27 in v_u_21 do
if v27.Tween then
v27.Tween:Cancel()
end
if v27.Model then
v27.Model:Destroy()
end
end
table.clear(v_u_21)
end
function v5.OnLoad(_)
-- upvalues: (copy) v_u_16, (copy) v_u_2, (copy) v_u_21, (copy) v_u_17, (copy) v_u_12, (copy) v_u_1, (copy) v_u_3, (copy) v_u_15, (copy) v_u_19, (copy) v_u_20, (copy) v_u_10
v_u_16.OnClientEvent:Connect(function(p_u_28, p29, p30, p31)
-- upvalues: (ref) v_u_2, (ref) v_u_21
local v32 = script.Meteor:Clone()
v32:PivotTo(CFrame.new(p29))
v32.Parent = workspace
local v33 = v32.PrimaryPart
if v33 then
local v34 = v_u_2:Create(v33, TweenInfo.new(p31, Enum.EasingStyle.Linear), {
["CFrame"] = CFrame.lookAt(p30, p29)
})
v34:Play()
v_u_21[p_u_28] = {
["Model"] = v32,
["Tween"] = v34
}
v34.Completed:Once(function()
-- upvalues: (ref) v_u_21, (copy) p_u_28
if v_u_21[p_u_28] then
v_u_21[p_u_28].Tween = nil
end
end)
else
warn("Starfall meteor model is missing a PrimaryPart!")
v32:Destroy()
end
end)
v_u_17.OnClientEvent:Connect(function(p35, p_u_36, p37)
-- upvalues: (ref) v_u_21, (ref) v_u_12, (ref) v_u_1, (ref) v_u_3, (ref) v_u_15, (ref) v_u_19, (ref) v_u_20, (ref) v_u_10
local v38 = v_u_21[p35]
if v38 then
task.spawn(function()
-- upvalues: (ref) v_u_12, (ref) v_u_1, (copy) p_u_36
v_u_12:PlaySound(v_u_1.Sounds.Events.Starfall.Impact, p_u_36)
end)
if v38.Tween then
v38.Tween:Cancel()
end
if v38.Model then
local v39 = v38.Model
for _, v40 in v39:GetDescendants() do
if v40:IsA("ParticleEmitter") then
v40.Enabled = false
elseif v40:IsA("BasePart") then
v40.Transparency = 1
end
end
v_u_3:AddItem(v39, 3)
end
v_u_21[p35] = nil
end
if p37 then
local v41 = v_u_15:GetAnimals()[p37]
if v41 then
local v42 = v41.AnimalModel.PrimaryPart
local v43 = v41.AnimalModel
local v44
if v43.PrimaryPart then
v44 = v43.PrimaryPart.CFrame
else
v44 = v43:GetPivot()
end
local v45 = v44.Position
local v46 = v41.AnimalModel:GetExtentsSize().Y * 0.5
local v_u_47 = v45 + Vector3.new(0, v46, 0)
task.spawn(function()
-- upvalues: (ref) v_u_12, (ref) v_u_1, (ref) v_u_47
v_u_12:PlaySound(v_u_1.Sounds.Events.Starfall.BrainrotHit, v_u_47)
end)
local v48 = script.StruckVFX:Clone()
v48:PivotTo(CFrame.new(v_u_47))
v48.Anchored = false
local v49 = Instance.new("WeldConstraint")
v49.Part0 = v48
v49.Part1 = v42
v49.Parent = v48
v48.Parent = workspace
for _, v_u_50 in v48:GetDescendants() do
if v_u_50:IsA("ParticleEmitter") then
task.delay(v_u_50:GetAttribute("EmitDelay") or 0, function()
-- upvalues: (copy) v_u_50
v_u_50:Emit(v_u_50:GetAttribute("EmitCount"))
end)
end
end
v_u_3:AddItem(v48, 5)
end
else
local v51 = script.Explosion:Clone()
v51:PivotTo(CFrame.new(p_u_36))
v51.Parent = workspace
for _, v_u_52 in v51:GetDescendants() do
if v_u_52:IsA("ParticleEmitter") then
task.delay(v_u_52:GetAttribute("EmitDelay") or 0, function()
-- upvalues: (copy) v_u_52
v_u_52:Emit(v_u_52:GetAttribute("EmitCount") or 1)
end)
end
end
v_u_3:AddItem(v51, 5)
local v53 = (workspace.CurrentCamera.CFrame.Position - p_u_36).Magnitude
if v53 <= 150 then
local v54 = v_u_19:Clone()
local v55 = 1 - v53 / 150
local v56 = math.pow(v55, 2)
v54.Amplitude = v54.Amplitude * v56
v54.RotationInfluence = v54.RotationInfluence * v56
v_u_20:Add(v_u_10.BindShakeToCamera(v54))
v54:Start()
end
return
end
end)
end
return v5 - Edit
03:12:20.358
- Edit
03:12:20.358
============================== - Edit
03:12:20.358 📜 ReplicatedStorage.Controllers.EventController.Events.Glitch - Edit
03:12:20.358 ==============================
- Edit
03:12:20.358 -- Thanks For Angelus Decompiles --> https://discord.gg/CYXme7yEG9
-- Decompiled with Velocity Script Decompiler
local v_u_1 = game:GetService("RunService")
local v_u_2 = game:GetService("ReplicatedStorage")
game:GetService("ContentProvider")
require(v_u_2.Shared.EventTypes)
local v3 = {}
local v_u_4 = require(v_u_2.Controllers.AnimalController)
local v_u_5 = require(v_u_2.Controllers.SoundController)
local v_u_6 = require(v_u_2.Controllers.CycleController)
require(v_u_2.Packages.Synchronizer)
require(v_u_2.Packages.FFlags)
local v7 = require(v_u_2.Packages.Trove)
local v8 = require(v_u_2.Packages.Net)
local v_u_9 = require(v_u_2.Shared.VFX)
local v_u_10 = v8:RemoteEvent("EventService/Glitch/HoleEffect")
local _ = script.Name
local v_u_11 = CFrame.new(-410.752, -9.782, 59.406)
local v_u_12 = v7.new()
function v3.OnStart(_)
-- upvalues: (copy) v_u_2, (copy) v_u_12, (copy) v_u_6, (copy) v_u_5
Random.new()
v_u_2:SetAttribute("GlitchEvent", true)
v_u_12:Add(function()
-- upvalues: (ref) v_u_2
v_u_2:SetAttribute("GlitchEvent", nil)
end)
v_u_6:Update()
v_u_5:UpdateOST()
end
function v3.OnStop(_)
-- upvalues: (copy) v_u_12
v_u_12:Destroy()
end
function v3.OnLoad(_)
-- upvalues: (copy) v_u_10, (copy) v_u_4, (copy) v_u_11, (copy) v_u_5, (copy) v_u_1, (copy) v_u_9
v_u_10.OnClientEvent:Connect(function(p13, p_u_14)
-- upvalues: (ref) v_u_4, (ref) v_u_11, (ref) v_u_5, (ref) v_u_1, (ref) v_u_9
local v15 = v_u_4:GetAnimals()[p13]
if v15 then
local v_u_16 = script.Hole:Clone()
v_u_16:PivotTo(CFrame.new(v_u_11.X, v_u_11.Y + v_u_16.Size.Y * 0.5, v15.Instance:GetPivot().Z + v_u_16.Size.Z * 0.5))
v_u_16.Parent = workspace
task.spawn(function()
-- upvalues: (ref) v_u_5, (copy) v_u_16
v_u_5:PlaySound("Sounds.Events.Glitch.Hole", v_u_16:GetPivot().Position)
end)
local v_u_17 = v15.Instance
local v_u_18 = v_u_17:GetPivot()
local v_u_19 = nil
v_u_19 = v_u_1.PostSimulation:Connect(function(_)
-- upvalues: (copy) p_u_14, (ref) v_u_19, (copy) v_u_16, (ref) v_u_9, (copy) v_u_17, (copy) v_u_18
local v20 = workspace:GetServerTimeNow() - p_u_14
local v21
if v20 < 0.15 then
v21 = 0
elseif v20 < 1 then
local v22 = (v20 - 0.15) / 0.85
local v23 = math.clamp(v22, 0, 1)
v21 = -(v23 * v23 * 98.1)
else
local v24 = (v20 - 1) / 0.5
local v25 = math.clamp(v24, 0, 1) * 0.4
v21 = 15.696000000000002 - v25 * v25 * 98.1
end
if v20 >= 1.5 then
v_u_19:Disconnect()
v_u_16:Destroy()
elseif v20 >= 1 then
v_u_9.disable(v_u_16)
end
v_u_17:PivotTo(v_u_18 + Vector3.new(0, v21, 0))
end)
end
end)
end
return v3 - Edit
03:12:20.358
- Edit
03:12:20.358
============================== - Edit
03:12:20.359 📜 ReplicatedStorage.Controllers.EventController.Events.10B Visits - Edit
03:12:20.359 ==============================
- Edit
03:12:20.359 -- Thanks For Angelus Decompiles --> https://discord.gg/CYXme7yEG9
-- Decompiled with Velocity Script Decompiler
local v_u_1 = game:GetService("ReplicatedStorage")
local v_u_2 = game:GetService("ContentProvider")
local v_u_3 = game:GetService("TweenService")
local v_u_4 = game:GetService("RunService")
game:GetService("Players")
game:GetService("Debris")
require(v_u_1.Shared.EventTypes)
local v5 = {}
local v_u_6 = require(v_u_1.Controllers.AnimalController)
local v_u_7 = require(v_u_1.Controllers.SoundController)
local v_u_8 = require(v_u_1.Controllers.EventController)
local v_u_9 = require(v_u_1.Controllers.CycleController)
local v_u_10 = require(v_u_1.Controllers.EventController.ClientEventUtils)
local v_u_11 = require(v_u_1.Shared.SharedEventUtils)
require(v_u_1.Packages.Synchronizer)
local v_u_12 = require(v_u_1.Shared.ShakePresets)
require(v_u_1.Packages.Observers)
local v_u_13 = require(v_u_1.Shared.TweenPivot)
local v_u_14 = require(v_u_1.Utils.MathUtils)
local v15 = require(v_u_1.Packages.Trove)
local v16 = require(v_u_1.Packages.Net)
local v_u_17 = require(v_u_1.Shared.VFX)
local v_u_18 = v16:RemoteEvent("EventService/10B Visits/CreateFirework")
local v_u_19 = v16:RemoteEvent("EventService/10B Visits/ExplodeTraitEffect")
local v_u_20 = script.Name
local v_u_21 = v15.new()
local v_u_22 = RaycastParams.new()
v_u_22.FilterType = Enum.RaycastFilterType.Include
v_u_22.FilterDescendantsInstances = { workspace.Map, workspace.Plots }
local v_u_23 = {}
function v5.OnStart(_)
-- upvalues: (copy) v_u_8, (copy) v_u_20, (copy) v_u_1, (copy) v_u_21, (copy) v_u_7, (copy) v_u_9, (copy) v_u_12, (copy) v_u_3, (copy) v_u_13, (copy) v_u_18, (copy) v_u_23, (copy) v_u_17, (copy) v_u_22, (copy) v_u_4, (copy) v_u_10, (copy) v_u_11, (copy) v_u_14
local v24 = v_u_8:GetActiveEventData(v_u_20)
assert(v24)
v_u_1:SetAttribute("10BVisitsEvent", true)
v_u_21:Add(function()
-- upvalues: (ref) v_u_1
v_u_1:SetAttribute("10BVisitsEvent", nil)
end)
v_u_7:UpdateOST()
v_u_9:Update()
local v_u_25 = v_u_1.Models.Events["10B Visits"].Fireworks:Clone()
v_u_25.Parent = workspace
local v_u_26 = v_u_25:GetChildren()
table.sort(v_u_26, function(p27, p28)
local v29 = p27.Name
local v30 = tonumber(v29)
local v31 = p28.Name
return v30 < tonumber(v31)
end)
local v_u_32 = {}
for _, v33 in v_u_26 do
v_u_32[v33] = v33.CFrame
end
local v_u_34 = v_u_12.BumpS:Clone()
v_u_21:Add(v_u_34)
v_u_34.Sustain = true
v_u_21:Add(v_u_12.BindShakeToCamera(v_u_34, workspace.CurrentCamera))
v_u_34:Start()
v_u_21:Add(task.delay(v24.startedAt + 4 - workspace:GetServerTimeNow(), function()
-- upvalues: (copy) v_u_34
v_u_34:StopSustain()
end))
v_u_21:Add(function()
-- upvalues: (copy) v_u_26, (ref) v_u_3, (copy) v_u_32, (copy) v_u_25
for _, v35 in v_u_26 do
local v36 = v_u_3
local v37 = TweenInfo.new(1 + math.random() + math.random(), Enum.EasingStyle.Quad, Enum.EasingDirection.In)
local v38 = {}
local v39 = v_u_32[v35]
local v40 = v35.Size.Y * 1.1
v38.CFrame = v39 - Vector3.new(0, v40, 0)
v36:Create(v35, v37, v38):Play()
end
task.wait(3)
v_u_25:Destroy()
end)
local v_u_41 = v_u_21:Clone(script.DroneRig)
v_u_41.Parent = workspace
local v_u_42 = v_u_41.AnimationController.Animator:LoadAnimation(script.DronesAnimation)
v_u_42:Play(0, 1, 0.2)
v_u_42:GetMarkerReachedSignal("TungFinished"):Once(function()
-- upvalues: (copy) v_u_42
v_u_42:AdjustSpeed(1)
end)
v_u_42:GetMarkerReachedSignal("Lower"):Once(function()
-- upvalues: (ref) v_u_13, (copy) v_u_41
v_u_13(v_u_41, TweenInfo.new(1), script.DroneRig:GetPivot() - Vector3.new(0, 100, 0)):Play()
end)
v_u_42:GetMarkerReachedSignal("Freeze"):Once(function()
-- upvalues: (copy) v_u_42
v_u_42:AdjustSpeed(0)
end)
local v_u_43 = {}
for _, v44 in v_u_41:GetChildren() do
if v44:IsA("BasePart") then
table.insert(v_u_43, v44)
end
end
v_u_21:Add(v_u_18.OnClientEvent:Connect(function(p45)
-- upvalues: (ref) v_u_23, (copy) v_u_26, (copy) v_u_32, (ref) v_u_17, (ref) v_u_1, (ref) v_u_7, (ref) v_u_3, (copy) v_u_43, (ref) v_u_22, (ref) v_u_4, (ref) v_u_10, (ref) v_u_11, (ref) v_u_14
for v46, v_u_47 in p45 do
local v48 = script.Effects
local v49 = v_u_47.FireworkEffect
local v_u_50 = v48[tostring(v49)]
local v_u_51 = ColorSequence.new(Color3.new(1, 1, 1))
local v52 = v_u_50.specs["Embers [20]"]
if v52 then
v_u_51 = v52.Color
end
v_u_23[v46] = v_u_51
local v53 = v_u_26[v_u_47.Chosen]
local v_u_54 = script.Firework:Clone()
v_u_54.CFrame = v_u_32[v53]
v_u_54.Parent = workspace
local v_u_55 = script.FireworkStartup:Clone()
local v56 = v_u_32[v53]
local v57 = v53.Size.Y * 0.5 - v_u_55.Size.Y * 0.5
v_u_55.CFrame = v56 + Vector3.new(0, v57, 0)
v_u_55.Parent = workspace
v_u_17.emit(v_u_55)
local v58 = v_u_1.Sounds.Events["10B Visits"]["Trail Sound Ball"]:Clone()
v58.Parent = v_u_54
v_u_7:PlaySound(v58)
local v59 = v_u_1.Sounds.Events["10B Visits"].Shot:Clone()
v59.Parent = v_u_55
v_u_7:PlaySound(v59)
task.delay(2, function()
-- upvalues: (copy) v_u_55
v_u_55:Destroy()
end)
local v60 = v_u_32[v53]
local v61 = v53.Size.Y
local v_u_62 = v60 - Vector3.new(0, v61, 0)
local v63 = v_u_32[v53]
local v64 = v_u_47.Height
local v_u_65 = v63 + Vector3.new(0, v64, 0)
local v66 = v_u_47.Height / 20
local v_u_67 = v_u_3:Create(v_u_54, TweenInfo.new(v66, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {
["CFrame"] = v_u_65
})
v_u_67:Play()
task.delay(v66 * 0.8, function()
-- upvalues: (copy) v_u_67, (ref) v_u_7, (ref) v_u_1, (copy) v_u_65, (ref) v_u_51, (ref) v_u_43, (copy) v_u_50, (ref) v_u_17, (copy) v_u_54, (copy) v_u_47, (copy) v_u_62, (ref) v_u_22, (ref) v_u_4, (ref) v_u_10, (ref) v_u_11, (ref) v_u_14
v_u_67:Destroy()
v_u_7:PlaySound(v_u_1.Sounds.Events["10B Visits"]["Firework Explosion"], v_u_65.Position)
local v68 = v_u_51.Keypoints[1].Value
for _, v69 in v_u_43 do
v69.Color = v68
end
local v_u_70 = v_u_50:Clone()
v_u_70.CFrame = v_u_65
v_u_70.Parent = workspace
v_u_17.emit(v_u_70)
v_u_54:Destroy()
task.delay(4, function()
-- upvalues: (copy) v_u_70
v_u_70:Destroy()
end)
for _, v_u_71 in v_u_47.Falloffs do
local v_u_72
if typeof(v_u_71) == "Vector3" then
v_u_72 = v_u_62 + v_u_71
local v73 = workspace:Raycast((v_u_65 + v_u_71).Position, Vector3.new(-0, -200, -0), v_u_22)
if v73 then
v_u_72 = CFrame.new(v73.Position)
end
else
v_u_72 = nil
end
local v_u_74 = script.Falloff:Clone()
v_u_74.CFrame = v_u_65
for _, v75 in v_u_74:GetDescendants() do
if v75:IsA("ParticleEmitter") then
v75.Color = v_u_51
end
end
v_u_74.Parent = workspace
local v_u_76 = 0
local v_u_77 = nil
v_u_77 = v_u_4.PostSimulation:Connect(function(p78)
-- upvalues: (ref) v_u_76, (ref) v_u_72, (copy) v_u_71, (ref) v_u_10, (ref) v_u_11, (copy) v_u_74, (ref) v_u_14, (ref) v_u_65, (ref) v_u_47, (ref) v_u_51, (ref) v_u_17, (ref) v_u_77
v_u_76 = v_u_76 + p78
local v79 = v_u_72
if not v79 then
local v80 = v_u_71
if type(v80) == "string" then
v79 = CFrame.new(v_u_10.getAnimalPosition(v_u_71, {
["top"] = true
}))
end
end
local v81 = v79 or CFrame.identity
local v82 = v_u_76 / 2.3
local v83 = v_u_11.pushPartCFrame
local v84 = v_u_74
local v85 = CFrame.new
local v86 = v_u_14.quadBezier
local v87 = v_u_65.Position
local v88 = v_u_65.Position
local v89 = v_u_47.Height
v83(v84, v85(v86(v82, v87, v88 + Vector3.new(0, v89, 0) + (v81.Position - v_u_65.Position) * Vector3.new(1, 0, 1) * 0.7, v81.Position)))
if v82 >= 1 then
local v90 = v_u_71
if type(v90) ~= "string" then
local v_u_91 = script.GroundImpact:Clone()
local v92 = v_u_91.Size.Y * 0.5
v_u_91.CFrame = v81 + Vector3.new(0, v92, 0)
for _, v93 in v_u_91:GetDescendants() do
if v93:IsA("ParticleEmitter") then
v93.Color = v_u_51
end
end
v_u_91.Parent = workspace
v_u_17.emit(v_u_91)
v_u_17.disable(v_u_74)
task.delay(3, function()
-- upvalues: (ref) v_u_74, (copy) v_u_91
v_u_74:Destroy()
v_u_91:Destroy()
end)
v_u_77:Disconnect()
end
end
end)
end
end)
end
end))
local v94 = Random.new()
for _, v95 in v_u_26 do
local v96 = v_u_32[v95]
local v97 = v95.Size.Y * 1.1
v95.CFrame = v96 - Vector3.new(0, v97, 0)
local v_u_98 = v_u_3:Create(v95, TweenInfo.new(v94:NextNumber(3, 7), Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {
["CFrame"] = v_u_32[v95]
})
local v_u_99 = v_u_21:Add(function()
-- upvalues: (copy) v_u_98
v_u_98:Cancel()
v_u_98:Destroy()
end)
v_u_98.Completed:Once(function()
-- upvalues: (ref) v_u_21, (copy) v_u_99
v_u_21:Remove(v_u_99)
end)
v_u_98:Play()
end
end
function v5.OnStop(_)
-- upvalues: (copy) v_u_21, (copy) v_u_23
v_u_21:Destroy()
table.clear(v_u_23)
end
function v5.OnLoad(_)
-- upvalues: (copy) v_u_2, (copy) v_u_19, (copy) v_u_6, (copy) v_u_10, (copy) v_u_17, (copy) v_u_7, (copy) v_u_1
task.spawn(pcall, function()
-- upvalues: (ref) v_u_2
v_u_2:PreloadAsync(script:GetChildren())
end)
v_u_19.OnClientEvent:Connect(function(p100, p101)
-- upvalues: (ref) v_u_6, (ref) v_u_10, (ref) v_u_17, (ref) v_u_7, (ref) v_u_1
local v102 = v_u_6:GetAnimals()[p101]
if v102 then
local v103 = script.FireworkBurst:Clone()
v103.CFrame = CFrame.new(v_u_10.getAnimalPosition(p101, {
["top"] = true
}))
v103.Anchored = false
local v104 = ColorSequence.new(Color3.new(1, 1, 1))
local v105 = script.Effects[tostring(p100)].specs["Embers [20]"]
if v105 then
v104 = v105.Color
end
for _, v106 in v103:GetDescendants() do
if v106:IsA("ParticleEmitter") then
v106.Color = v104
end
end
local v107 = Instance.new("WeldConstraint")
v107.Part0 = v103
v107.Part1 = v102.AnimalModel.PrimaryPart
v107.Parent = v103
v103.Parent = workspace
v_u_17.emit(v103)
v_u_7:PlaySound(v_u_1.Sounds.Events["10B Visits"]["Brainrot Hit"], v103.Position)
end
end)
end
return v5 - Edit
03:12:20.359
- Edit
03:12:20.359
============================== - Edit
03:12:20.359 📜 ReplicatedStorage.Controllers.EventController.Events.Snow - Edit
03:12:20.359 ==============================
- Edit
03:12:20.359 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
local u1 = game:GetService("ReplicatedStorage")
local u2 = game:GetService("CollectionService")
local u3 = game:GetService("TweenService")
game:GetService("RunService")
local u4 = game:GetService("Lighting")
game:GetService("Players")
require(u1.Shared.EventTypes)
local v5 = {}
local u6 = require(u1.Controllers.AnimalController)
local u7 = require(u1.Controllers.EffectController)
local u8 = require(u1.Controllers.SoundController)
local u9 = require(u1.Controllers.EventController)
local u10 = require(u1.Controllers.CycleController)
require(u1.Shared.ShakePresets)
require(u1.Packages.Observers)
local v11 = require(u1.Packages.Trove)
local v12 = require(u1.Packages.Net)
local u13 = require(u1.Shared.VFX)
local u14 = script.Name
local u15 = v12:RemoteEvent("EventService/Snow/Hit")
local u16 = v11.new()
function v5.OnStart(_) --[[Anonymous function at line 29]]
--[[
Upvalues:
[1] = u9
[2] = u14
[3] = u1
[4] = u16
[5] = u13
[6] = u4
[7] = u7
[8] = u10
[9] = u8
--]]
local v17 = u9:GetActiveEventData(u14)
assert(v17)
u1:SetAttribute("Snow", true)
u16:Add(function() --[[Anonymous function at line 38]]
--[[
Upvalues:
[1] = u1
--]]
u1:SetAttribute("Snow", nil)
end)
local v18 = v17.startedAt + 4 - workspace:GetServerTimeNow()
local u19 = u16:Clone(script.SnowWeather)
u13.disable(u19)
u19.Parent = workspace
u16:Add(task.delay(v18, function() --[[Anonymous function at line 52]]
--[[
Upvalues:
[1] = u4
[2] = u16
[3] = u13
[4] = u19
--]]
local u20 = u4:FindFirstChild("Atmosphere")
if u20 then
u20.Parent = script
u16:Add(function() --[[Anonymous function at line 56]]
--[[
Upvalues:
[1] = u20
[2] = u4
--]]
u20.Parent = u4
end)
end
u16:Clone(script.AtmosphereSnow).Parent = u4
local u21 = u4:FindFirstChild("Cartoon")
if u21 then
u21.Parent = script
u16:Add(function() --[[Anonymous function at line 66]]
--[[
Upvalues:
[1] = u21
[2] = u4
--]]
u21.Parent = u4
end)
end
u16:Clone(script.SkySnow).Parent = u4
u13.enable(u19)
end))
u7:Run("Snow", "GrassRecolor")
u16:Add(function() --[[Anonymous function at line 77]]
--[[
Upvalues:
[1] = u7
--]]
u7:Stop("Snow", "GrassRecolor")
end)
u10:Update()
u8:UpdateOST()
-- u8:UpdateAmbience()
end
function v5.OnStop(_) --[[Anonymous function at line 86]]
--[[
Upvalues:
[1] = u16
--]]
u16:Destroy()
end
function v5.OnLoad(_) --[[Anonymous function at line 90]]
--[[
Upvalues:
[1] = u15
[2] = u6
[3] = u8
[4] = u1
[5] = u3
[6] = u16
[7] = u2
--]]
u15.OnClientEvent:Connect(function(p22) --[[Anonymous function at line 91]]
--[[
Upvalues:
[1] = u6
[2] = u8
[3] = u1
--]]
local v23
if type(p22) == "string" then
local v24 = u6:GetAnimals()[p22]
if not v24 then
return
end
local v25 = v24.AnimalModel
local v26
if v25.PrimaryPart then
v26 = v25.PrimaryPart.CFrame
else
v26 = v25:GetPivot()
end
local v27 = v26.Position
local v28 = v24.AnimalModel:GetExtentsSize().Y * 0.5
v23 = v27 + Vector3.new(0, v28, 0)
p22 = v24.AnimalModel.PrimaryPart
else
v23 = p22:GetPivot().Position
end
u8:PlaySound(u1.Sounds.Events.Snow.Burst, v23)
local v29 = script.StruckVFX:Clone()
v29:PivotTo(CFrame.new(v23))
v29.Anchored = false
local v30 = Instance.new("WeldConstraint")
v30.Part0 = v29
v30.Part1 = p22
v30.Parent = v29
v29.Parent = workspace
for _, u31 in v29:GetDescendants() do
if u31:IsA("ParticleEmitter") then
task.delay(u31:GetAttribute("EmitDelay") or 0, function() --[[Anonymous function at line 135]]
--[[
Upvalues:
[1] = u31
--]]
u31:Emit(u31:GetAttribute("EmitCount"))
end)
end
end
end)
local function u38(u32) --[[Anonymous function at line 142]]
--[[
Upvalues:
[1] = u3
--]]
task.wait(math.random() * 0.8)
local u33 = u32:GetPivot() * CFrame.new(0, 10, 0)
local u34 = Instance.new("CFrameValue")
u34.Value = u32:GetPivot()
local u36 = u34.Changed:Connect(function(p35) --[[Anonymous function at line 150]]
--[[
Upvalues:
[1] = u32
--]]
u32:PivotTo(p35)
end)
local v37 = u3:Create(u34, TweenInfo.new(1.2), {
["Value"] = u33
})
v37:Play()
v37.Completed:Connect(function() --[[Anonymous function at line 159]]
--[[
Upvalues:
[1] = u36
[2] = u34
[3] = u32
[4] = u33
--]]
u36:Disconnect()
u34:Destroy()
u32:PivotTo(u33)
end)
end
u16:Add(u2:GetInstanceAddedSignal("SnowPile"):Connect(function(p39) --[[Anonymous function at line 174]]
--[[
Upvalues:
[1] = u38
--]]
if p39:IsA("Model") then
task.spawn(u38, p39)
end
end))
for _, v40 in u2:GetTagged("SnowPile") do
if v40:IsA("Model") then
task.spawn(u38, v40)
end
end
end
return v5 - Edit
03:12:20.359
- Edit
03:12:20.359
============================== - Edit
03:12:20.360 📜 ReplicatedStorage.Controllers.EventController.Events.Molten - Edit
03:12:20.360 ==============================
- Edit
03:12:20.360 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
local u1 = game:GetService("ReplicatedStorage")
local u2 = game:GetService("TweenService")
game:GetService("RunService")
local u3 = game:GetService("Lighting")
game:GetService("Players")
require(u1.Shared.EventTypes)
local v4 = {}
local u5 = require(u1.Controllers.EffectController)
local u6 = require(u1.Controllers.SoundController)
local u7 = require(u1.Controllers.EventController)
local u8 = require(u1.Controllers.CycleController)
local u9 = require(u1.Shared.ShakePresets)
require(u1.Packages.Observers)
local v10 = require(u1.Packages.Trove)
require(u1.Packages.Net)
local u11 = require(u1.Shared.VFX)
local u12 = script.Name
local u13 = v10.new()
function v4.OnStart(_) --[[Anonymous function at line 25]]
--[[
Upvalues:
[1] = u7
[2] = u12
[3] = u6
[4] = u1
[5] = u13
[6] = u2
[7] = u9
[8] = u11
[9] = u5
[10] = u3
[11] = u8
--]]
local v14 = u7:GetActiveEventData(u12)
assert(v14)
task.spawn(function() --[[Anonymous function at line 29]]
--[[
Upvalues:
[1] = u6
--]]
u6:PlaySound("Sounds.Events.Molten.LavaActivate")
end)
local u15 = u1.Models.Events.Molten.Craters:Clone()
u15.Parent = workspace
local u16 = u15:GetChildren()
table.sort(u16, function(p17, p18) --[[Anonymous function at line 41]]
local v19 = p17.Name
local v20 = tonumber(v19)
local v21 = p18.Name
return v20 < tonumber(v21)
end)
local u22 = {}
for _, v23 in u16 do
u22[v23] = v23.PrimaryPart:GetPivot()
end
u13:Add(function() --[[Anonymous function at line 50]]
--[[
Upvalues:
[1] = u16
[2] = u2
[3] = u22
[4] = u15
--]]
for _, v24 in u16 do
local v25 = v24:GetExtentsSize()
local v26 = u2
local v27 = v24.PrimaryPart
local v28 = TweenInfo.new(1 + math.random() + math.random(), Enum.EasingStyle.Quad, Enum.EasingDirection.In)
local v29 = {}
local v30 = u22[v24]
local v31 = v25.Y * 1.1
v29.CFrame = v30 - Vector3.new(0, v31, 0)
v26:Create(v27, v28, v29):Play()
end
task.wait(3)
u15:Destroy()
end)
local u32 = u9.BumpS:Clone()
u13:Add(u32)
u32.Sustain = true
u13:Add(u9.BindShakeToCamera(u32, workspace.CurrentCamera))
u32:Start()
local v33 = v14.startedAt + 4 - workspace:GetServerTimeNow()
u13:Add(task.delay(v33, function() --[[Anonymous function at line 72]]
--[[
Upvalues:
[1] = u32
--]]
u32:StopSustain()
end))
local u34 = u13:Clone(script.MoltenWeather)
u11.disable(u34)
u34.Parent = workspace
u13:Add(task.delay(v33, function() --[[Anonymous function at line 80]]
--[[
Upvalues:
[1] = u5
[2] = u3
[3] = u13
[4] = u11
[5] = u34
--]]
u5:Activate("Blink")
local u35 = u3:FindFirstChild("Atmosphere")
if u35 then
u35.Parent = script
u13:Add(function() --[[Anonymous function at line 86]]
--[[
Upvalues:
[1] = u35
[2] = u3
--]]
u35.Parent = u3
end)
end
u13:Clone(script.AtmosphereMolten).Parent = u3
local u36 = u3:FindFirstChild("Cartoon")
if u36 then
u36.Parent = script
u13:Add(function() --[[Anonymous function at line 96]]
--[[
Upvalues:
[1] = u36
[2] = u3
--]]
u36.Parent = u3
end)
end
u13:Clone(script.SkyMolten).Parent = u3
u11.enable(u34)
end))
u13:Add(function() --[[Anonymous function at line 106]]
--[[
Upvalues:
[1] = u5
--]]
u5:Activate("Blink")
end)
u5:Run("MoltenEvent", "GrassRecolor")
u13:Add(function() --[[Anonymous function at line 111]]
--[[
Upvalues:
[1] = u5
--]]
u5:Stop("MoltenEvent", "GrassRecolor")
end)
local v37 = Random.new()
for _, v38 in ipairs(u16) do
local v39 = v38:GetExtentsSize()
local v40 = v38:GetPrimaryPartCFrame()
v38:PivotTo(v40 * CFrame.new(0, -v39.Y * 1.1, 0))
u2:Create(v38.PrimaryPart, TweenInfo.new(v37:NextNumber(3, 7), Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {
["CFrame"] = v40
}):Play()
end
u8:Update()
u6:UpdateOST()
end
function v4.OnStop(_) --[[Anonymous function at line 135]]
--[[
Upvalues:
[1] = u13
--]]
u13:Destroy()
end
function v4.OnLoad(_) --[[Anonymous function at line 139]] end
return v4 - Edit
03:12:20.360
- Edit
03:12:20.360
============================== - Edit
03:12:20.360 📜 ReplicatedStorage.Controllers.EventController.Events.Concert - Edit
03:12:20.360 ==============================
- Edit
03:12:20.360 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
local u1 = game:GetService("ReplicatedStorage")
game:GetService("TweenService")
local u2 = game:GetService("RunService")
local u3 = game:GetService("Lighting")
local u4 = game:GetService("Players")
require(u1.Shared.EventTypes)
local v5 = {}
local u6 = require(u1.Controllers.EncryptedAssetsController)
local u7 = require(u1.Controllers.AnimalController)
local u8 = require(u1.Controllers.EffectController)
local u9 = require(u1.Controllers.CameraController)
local u10 = require(u1.Controllers.SoundController)
local u11 = require(u1.Controllers.EventController)
local u12 = require(u1.Controllers.CycleController)
local u13 = require(u1.Packages.CreateTween)
require(u1.Shared.TweenPivot)
local u14 = require(u1.Packages.Observers)
local u15 = require(u1.Utils.MathUtils)
local u16 = require(u1.Packages.Signal)
require(u1.Packages.Spring)
local u17 = require(u1.Packages.Trove)
require(u1.Packages.Shake)
local v18 = require(u1.Packages.Net)
local u19 = require(u1.Shared.VFX)
local u20 = u4.LocalPlayer
local u21 = workspace.CurrentCamera
local u22 = script.Name
local u23 = workspace.Sounds.Concert
local u24 = v18:RemoteEvent("EventService/Concert/Shoot")
local u25 = u17.new()
local u26 = nil
function v5.OnStart(_) --[[Anonymous function at line 44]]
--[[
Upvalues:
[1] = u11
[2] = u22
[3] = u25
[4] = u8
[5] = u12
[6] = u10
[7] = u3
[8] = u1
[9] = u21
[10] = u23
[11] = u6
[12] = u19
[13] = u24
[14] = u7
[15] = u2
[16] = u15
[17] = u13
[18] = u9
[19] = u16
[20] = u14
[21] = u4
[22] = u17
[23] = u20
--]]
local u27 = u11:GetActiveEventData(u22)
assert(u27)
local function u38(p28, u29, u30) --[[Anonymous function at line 52]]
--[[
Upvalues:
[1] = u27
--]]
local function u33() --[[Anonymous function at line 53]]
--[[
Upvalues:
[1] = u29
[2] = u27
--]]
local v31 = u29
local v32 = u27.startedAt + v31 - workspace:GetServerTimeNow()
return math.max(v32, 0)
end
local function v34() --[[Anonymous function at line 57]]
--[[
Upvalues:
[1] = u30
[2] = u33
--]]
u30(u33)
end
local u35 = nil
local v36 = u27.startedAt + p28 - workspace:GetServerTimeNow()
local v37 = math.max(v36, 0)
if v37 > 0 then
u35 = task.delay(v37, v34)
else
u30(u33)
end
return function() --[[Anonymous function at line 70]]
--[[
Upvalues:
[1] = u35
--]]
if u35 and coroutine.status(u35) == "suspended" then
pcall(task.cancel, u35)
end
end
end
u25:Add(function() --[[Anonymous function at line 77]]
--[[
Upvalues:
[1] = u8
[2] = u12
[3] = u10
--]]
u8:Activate("Blink")
u12:Update()
u10:UpdateOST()
end)
local u39 = u3:FindFirstChild("Atmosphere")
if u39 then
u39.Parent = u1
u25:Add(function() --[[Anonymous function at line 86]]
--[[
Upvalues:
[1] = u39
[2] = u3
--]]
u39.Parent = u3
end)
end
u25:Clone(script.Atmosphere).Parent = u3
local u40 = u3:FindFirstChild("Cartoon")
if u40 then
u40.Parent = u1
u25:Add(function() --[[Anonymous function at line 96]]
--[[
Upvalues:
[1] = u40
[2] = u3
--]]
u40.Parent = u3
end)
end
local u41 = nil
local u42 = u25:Clone(Instance.new("ColorCorrectionEffect"))
u42.Parent = u21
local function u180() --[[Anonymous function at line 113]]
--[[
Upvalues:
[1] = u3
[2] = u25
[3] = u23
[4] = u6
[5] = u27
[6] = u19
[7] = u24
[8] = u7
[9] = u10
[10] = u1
[11] = u2
[12] = u15
[13] = u38
[14] = u41
[15] = u13
[16] = u9
--]]
u3.Ambient = Color3.new(0, 0, 0)
u3.OutdoorAmbient = Color3.fromRGB(100, 100, 100)
u3.EnvironmentDiffuseScale = 0
u3.EnvironmentSpecularScale = 0
u25:Add(function() --[[Anonymous function at line 118]]
--[[
Upvalues:
[1] = u3
--]]
u3.Ambient = Color3.fromRGB(241, 241, 241)
u3.OutdoorAmbient = Color3.fromRGB(212, 212, 212)
u3.EnvironmentDiffuseScale = 1
u3.EnvironmentSpecularScale = 0.5
end)
u25:Add(function() --[[Anonymous function at line 126]]
--[[
Upvalues:
[1] = u23
--]]
u23:Stop()
end)
u25:Add(task.spawn(function() --[[Anonymous function at line 130]]
while not u23.IsLoaded do
task.wait()
end
local v43 = u23
local v44 = u23.TimePosition
local v45 = workspace:GetServerTimeNow() - (u27.startedAt + 5)
v43.TimePosition = math.max(v44, v45)
u23:Play()
end))
local u46 = {
Color3.fromRGB(255, 255, 255),
Color3.fromRGB(255, 0, 0),
Color3.fromRGB(255, 128, 0),
Color3.fromRGB(255, 255, 0),
Color3.fromRGB(128, 255, 0),
Color3.fromRGB(0, 255, 0),
Color3.fromRGB(0, 255, 128),
Color3.fromRGB(0, 255, 255),
Color3.fromRGB(0, 0, 255),
Color3.fromRGB(128, 0, 255),
Color3.fromRGB(255, 0, 255),
Color3.fromRGB(255, 0, 128),
Color3.fromRGB(255, 0, 255),
Color3.fromRGB(0, 128, 255)
}
u25:Clone(script.Night_Sky).Parent = u3
local u47 = u25:Clone(script.Stage)
local u48 = u25:Clone(script.VFX)
local u49 = u48.SmokeStage
u25:Add(u49)
u49.Parent = workspace
u48.Parent = u47
u19.disable(u48)
local u50 = u47.SpotLights:GetChildren()
local _ = #u50
local u51 = {}
local u52 = {}
local u53 = {}
local u54 = {}
local u55 = {}
local u56 = false
local u57 = false
local u58 = {}
local u59 = {}
local u60 = false
local u61 = false
local u62 = {}
local u63 = {}
for _, v64 in u50 do
u51[v64] = v64:GetPivot()
u52[v64] = 0
u53[v64] = 0
u54[v64] = 25
v64.Rotate.Neon["1"].LightBeam:Destroy()
local v65 = script.lightbeambig.Beams:Clone()
for _, v66 in v65:GetChildren() do
v66.Attachment0 = v64.Rotate.Neon["1"]
v66.Attachment1 = v64.Rotate.Neon["2"]
v66.Parent = v64.Rotate.Neon
table.insert(u55, v66)
end
v65:Destroy()
end
u47.Parent = workspace
local u67 = { u47.Rigs.TungTung, u47.Rigs.Tralalero, u47.Rigs.Chimpanzini }
local u68 = {}
for _, v69 in u67 do
if v69.Name ~= "TungTung" then
for _, v70 in v69:GetChildren() do
if v70:IsA("BasePart") then
v70.Transparency = 1
end
end
end
local v71 = {}
local v72 = v69.Throw
local v73 = v69.AnimationController.Animator:LoadAnimation(v72)
u25:Add(v73, "Stop")
u25:Add(v73)
v71.Throw = v73
local v74 = v69.Shuffle
local v75 = v69.AnimationController.Animator:LoadAnimation(v74)
u25:Add(v75, "Stop")
u25:Add(v75)
v71.Shuffle = v75
u68[v69] = v71
end
local u76 = u25:Add(Instance.new("Color3Value"))
u76.Value = Color3.fromRGB(0, 0, 0)
for _, v77 in u68 do
v77.Shuffle:Play()
end
local u78 = true
u25:Add(function() --[[Anonymous function at line 241]]
--[[
Upvalues:
[1] = u78
--]]
u78 = false
end)
u25:Add(u24.OnClientEvent:Connect(function(p79, p80, u81)
local u82 = u7:GetAnimals()[p80]
if u82 then
local v83 = u67[p79] or u67[1]
if v83 then
u68[v83].Throw:Play()
task.wait(0.25)
if u78 then
local u84 = v83:FindFirstChild("SHOOT", true).WorldPosition
task.spawn(function()
u10:PlaySound(u1.Sounds.Events.Concert.Shoot, u84)
end)
local u85 = script.DiscoProjectile:Clone()
u85.Part.CFrame = CFrame.new(u84)
u85.Parent = workspace
local u86 = nil
u86 = u2.PreRender:Connect(function()
debug.profilebegin("Concert Disco Shoot")
local v87 = u82.AnimalModel
local v88
if v87.PrimaryPart then
v88 = v87.PrimaryPart.CFrame
else
v88 = v87:GetPivot()
end
local u89 = v88.Position
local v90 = u84 + (u89 - u84) * 0.5 + Vector3.new(0, 90, 0)
local v91 = 1 - (u81 + 3 - workspace:GetServerTimeNow()) / 3
local v92 = u15.quadBezier(math.clamp(v91, 0, 1), u84, v90, u89)
u85.Part.CFrame = CFrame.new(v92)
if v91 >= 1 then
u86:Disconnect()
task.spawn(function()
u10:PlaySound(u1.Sounds.Events.Concert.Hit, u89)
end)
u85:Destroy()
local u93 = script.DiscoExplosion:Clone()
u93:PivotTo(CFrame.new(u89))
u93.Anchored = false
local v94 = Instance.new("WeldConstraint")
v94.Part0 = u93
v94.Part1 = u82.AnimalModel.PrimaryPart
v94.Parent = u93
u93.Parent = workspace
u19.emit(u93)
task.delay(3, function()
u93:Destroy()
end)
-- Add FireServer call to notify the server of the hit
u24:FireServer(p79, p80, u81)
end
debug.profileend()
end)
end
end
end
end))
u25:Add((u38(10, 15, function(u96) --[[Anonymous function at line 333]]
--[[
Upvalues:
[1] = u19
[2] = u48
[3] = u55
[4] = u25
[5] = u2
[6] = u23
[7] = u58
[8] = u62
[9] = u68
[10] = u41
[11] = u46
[12] = u13
[13] = u76
[14] = u59
[15] = u63
[16] = u50
[17] = u53
[18] = u54
[19] = u52
[20] = u51
[21] = u60
[22] = u56
[23] = u49
[24] = u61
[25] = u47
[26] = u57
[27] = u9
--]]
u19.enable(u48)
local u97 = 1
local u98 = 0
local u99 = 0
local u100 = 0
local u101 = 0
local u102 = {}
local u103 = Color3.new(0, 0, 0)
local u104 = ColorSequence.new(u103)
task.delay(u96(), function() --[[Anonymous function at line 347]]
--[[
Upvalues:
[1] = u55
--]]
for _, v105 in u55 do
v105.Enabled = true
end
end)
u25:Add(function() --[[Anonymous function at line 353]]
workspace.Gravity = 196.2
end)
u25:Add(u2.PostSimulation:Connect(function(p106) --[[Anonymous function at line 357]]
--[[
Upvalues:
[1] = u99
[2] = u98
[3] = u101
[4] = u100
[5] = u23
[6] = u58
[7] = u62
[8] = u68
[9] = u41
[10] = u96
[11] = u97
[12] = u46
[13] = u13
[14] = u76
[15] = u103
[16] = u59
[17] = u102
[18] = u104
[19] = u63
[20] = u50
[21] = u53
[22] = u54
[23] = u52
[24] = u51
[25] = u60
[26] = u55
[27] = u56
[28] = u19
[29] = u49
[30] = u61
[31] = u47
[32] = u57
[33] = u9
--]]
workspace.Gravity = 29.429999999999996
u99 = u99 - p106
u98 = u98 - p106
u101 = u101 - p106
u100 = u100 - p106
local v107 = u23.TimePosition
local v108
if v107 >= 20 and v107 <= 25 then
v108 = true
elseif v107 >= 70 then
v108 = v107 <= 94.5
else
v108 = false
end
local v109 = (u23.PlaybackLoudness - 100) / 900
local v110 = math.clamp(v109, 0, 1)
for _, v111 in u58 do
local v112 = v110 / 0.05
v111.TimeScale = math.clamp(v112, 1, 2) * u62[v111]
end
for v113, v114 in u68 do
if v113.Name == "TungTung" then
local v115 = v114.Shuffle
local v116 = v110 * 0.5 / 0.13
v115:AdjustSpeed((math.clamp(v116, 0.25, 1)))
else
local v117 = v114.Shuffle
local v118 = v110 / 0.13
v117:AdjustSpeed((math.clamp(v118, 0.5, 1.5)))
end
end
if u41 then
local v119 = u41
local v120
if v108 then
v120 = 3
else
local v121 = v110 / 0.06
v120 = math.clamp(v121, 1, 3)
end
v119:AdjustSpeed(v120)
end
local v122
if v107 >= 70 and v107 <= 94.5 then
if v107 >= 85 then
v122 = 0.05
else
local v123 = (v107 - 70) / 12
local v124 = math.min(v123, 1)
v122 = math.lerp(0.5, 0.2, v124)
end
else
v122 = v108 and 0.1 or 0.3
end
if (v110 >= 0.11 or v108) and (u100 <= 0 and u96() <= 0) then
u100 = v122
u97 = u97 % #u46 + 1
u13(u76, TweenInfo.new(0.2), {
["Value"] = u46[u97]
})
end
local v125 = u76.Value
if v107 >= 94.3 and v107 <= 97.7 then
v125 = u103
end
local v126 = ColorSequence.new(v125)
for _, v127 in u59 do
local v128
if u102[v127] then
v128 = u104
else
v128 = v126
end
v127.Color = v128
end
for _, v129 in u63 do
local v130
if u102[v129] then
v130 = u103
else
v130 = v125
end
v129.Color = v130
end
local v131
if v108 then
v131 = 1.5
else
local v132 = v110 / 0.25
v131 = math.clamp(v132, 0.05, 1)
end
local v133 = p106 * v131
for _, v134 in u50 do
local v135 = u53[v134] or 0
local v136 = u54[v134] or 0
local v137 = (u52[v134] or 0) + v133
local v138 = math.clamp(v137, 0, 1)
u52[v134] = v138
if v138 >= 1 then
u52[v134] = 0
u53[v134] = v136
local v139 = u54
v139[v134] = v139[v134] * -1
else
local v140 = math.lerp(v135, v136, v138)
local v141 = math.rad(v140)
v134:PivotTo(u51[v134] * CFrame.Angles(0, v141, not u60 and 0 or v141))
if u60 then
for _, v142 in v134.Rotate.Neon:GetChildren() do
if v142.Name == "CustomAttachment_-1" or (v142.Name == "2" or v142.Name == "CustomAttachment_2") then
local v143 = v142.Position.X
local v144 = v138 * 3.141592653589793
local v145 = math.sin(v144) * 100
v142.Position = Vector3.new(v143, v145, 300)
end
end
end
end
end
if v108 and u99 <= 0 then
local v146 = math.random(100, 200)
u99 = v146 / 1000
local v147 = {}
for _, u148 in u55 do
v147[u148] = true
local v149 = u148.Width0 - 0.5
u148.Width0 = math.max(v149, 0.5)
local v150 = u148.Width1 - 2.5
u148.Width1 = math.max(v150, 1)
local v151 = u148.Brightness + 0.5
u148.Brightness = math.min(v151, 13)
u148.Enabled = false
task.delay(math.random(50, v146) / 1000, function() --[[Anonymous function at line 458]]
--[[
Upvalues:
[1] = u148
--]]
u148.Enabled = true
end)
end
for _, u152 in u59 do
if not v147[u152] then
u102[u152] = true
task.delay(math.random(50, v146) / 1000, function() --[[Anonymous function at line 469]]
--[[
Upvalues:
[1] = u102
[2] = u152
--]]
u102[u152] = nil
end)
end
end
for _, u153 in u63 do
u102[u153] = true
task.delay(math.random(50, v146) / 1000, function() --[[Anonymous function at line 476]]
--[[
Upvalues:
[1] = u102
[2] = u153
--]]
u102[u153] = nil
end)
end
end
if v107 >= 25 and not u56 then
u56 = true
for _, v154 in u50 do
local v155 = v154.Rotate.Neon["1"]
local v156 = v154.Rotate.Neon["2"]
local v157 = v156:Clone()
v157.Name = "CustomAttachment_1"
v157.Parent = v154.Rotate.Neon
u13(v156, TweenInfo.new(5), {
["Position"] = v156.Position + Vector3.new(15, 0, 0)
})
u13(v157, TweenInfo.new(5), {
["Position"] = v156.Position - Vector3.new(15, 0, 0)
})
local v158 = script.lightbeambig.Beams:Clone()
for _, v159 in v158:GetChildren() do
v159.Width0 = 0.5
v159.Width1 = 1
v159.Brightness = 13
v159.Attachment0 = v155
v159.Attachment1 = v157
v159.Parent = v154.Rotate.Neon
local v160 = u55
table.insert(v160, v159)
local v161 = u59
table.insert(v161, v159)
end
v158:Destroy()
end
end
if v107 >= 71 and not u60 then
u19.enable(u49)
task.delay(5, function() --[[Anonymous function at line 519]]
--[[
Upvalues:
[1] = u19
[2] = u49
--]]
u19.disable(u49)
end)
u60 = true
for _, v162 in u50 do
local v163 = v162.Rotate.Neon["1"]
local v164 = v162.Rotate.Neon["2"]
local v165 = v164.Position - Vector3.new(15, 0, 0)
u13(v164, TweenInfo.new(5), {
["Position"] = v165
})
for v166 = -2, 2 do
if v166 ~= 0 then
local v167 = v164:Clone()
v167.Name = ("CustomAttachment_%*"):format(v166)
v167.Parent = v162.Rotate.Neon
local v168 = u13
local v169 = TweenInfo.new(5)
local v170 = {}
local v171 = v166 * 30
v170.Position = v165 + Vector3.new(v171, 0, 0)
v168(v167, v169, v170)
local v172 = script.lightbeambig.Beams:Clone()
for _, v173 in v172:GetChildren() do
v173.Width0 = 0.5
v173.Width1 = 1
v173.Brightness = 13
v173.Attachment0 = v163
v173.Attachment1 = v167
v173.Parent = v162.Rotate.Neon
local v174 = u55
table.insert(v174, v173)
local v175 = u59
table.insert(v175, v173)
end
v172:Destroy()
end
end
end
end
if v107 >= 36 and not u61 then
u61 = true
for _, v176 in u47.Rigs.Tralalero:GetChildren() do
if v176:IsA("BasePart") then
u13(v176, TweenInfo.new(1), {
["Transparency"] = 0
})
end
end
end
if v107 >= 61.5 and not u57 then
u57 = true
for _, v177 in u47.Rigs.Chimpanzini:GetChildren() do
if v177:IsA("BasePart") then
u13(v177, TweenInfo.new(1), {
["Transparency"] = 0
})
end
end
end
if (v110 >= 0.2 or v108) and u98 <= 0 then
u98 = v108 and 0.2 or 0.1
u9:Fov((v110 - 0.2) * 15 + 70, 0.1)
end
end))
end)))
for _, v178 in u47:GetDescendants() do
if v178:IsA("BasePart") and v178.Name == "Neon" or v178:IsA("SpotLight") then
table.insert(u63, v178)
elseif v178:IsA("ParticleEmitter") or v178:IsA("Beam") then
table.insert(u59, v178)
if v178:IsA("ParticleEmitter") then
u62[v178] = v178.TimeScale
table.insert(u58, v178)
end
end
end
u25:Add((u38(10, 15, function(p179) --[[Anonymous function at line 613]]
--[[
Upvalues:
[1] = u13
[2] = u76
[3] = u46
--]]
u13(u76, TweenInfo.new(p179()), {
["Value"] = u46[1]
})
end)))
end
u25:Add((u38(0, 5, function(p181) --[[Anonymous function at line 620]]
--[[
Upvalues:
[1] = u13
[2] = u42
[3] = u180
[4] = u8
[5] = u25
--]]
u13(u42, TweenInfo.new(p181(), Enum.EasingStyle.Sine, Enum.EasingDirection.Out), {
["Brightness"] = -1
})
task.delay(p181(), u180)
u8:Run("ConcertEvent", "GrassRecolor")
u25:Add(function() --[[Anonymous function at line 628]]
--[[
Upvalues:
[1] = u8
--]]
u8:Stop("ConcertEvent", "GrassRecolor")
end)
u8:Run("ConcertEvent", "WallRecolor")
u25:Add(function() --[[Anonymous function at line 633]]
--[[
Upvalues:
[1] = u8
--]]
u8:Stop("ConcertEvent", "WallRecolor")
end)
u8:Run("ConcertEvent", "WallBottomRecolor")
u25:Add(function() --[[Anonymous function at line 638]]
--[[
Upvalues:
[1] = u8
--]]
u8:Stop("ConcertEvent", "WallBottomRecolor")
end)
end)))
u25:Add((u38(10, 15, function(p182) --[[Anonymous function at line 643]]
--[[
Upvalues:
[1] = u13
[2] = u42
--]]
u13(u42, TweenInfo.new(p182(), Enum.EasingStyle.Sine, Enum.EasingDirection.Out), {
["Brightness"] = -0.05
})
end)))
local v183 = u25
local v184 = task.delay
local v185 = u27.startedAt + 24.5 - workspace:GetServerTimeNow()
v183:Add(v184(math.max(v185, 0), function() --[[Anonymous function at line 652]]
--[[
Upvalues:
[1] = u25
[2] = u16
[3] = u14
[4] = u4
[5] = u17
[6] = u41
[7] = u2
[8] = u27
[9] = u20
--]]
u25:Add(u16.new())
u25:Add(u14.observeCharacter(u4.LocalPlayer, function(_, u186) --[[Anonymous function at line 656]]
--[[
Upvalues:
[1] = u17
[2] = u41
[3] = u2
[4] = u27
[5] = u20
--]]
local u187 = u17.new()
u187:Add(task.spawn(function() --[[Anonymous function at line 659]]
--[[
Upvalues:
[1] = u186
[2] = u41
[3] = u187
[4] = u2
[5] = u27
[6] = u20
--]]
local u188 = u186:WaitForChild("Humanoid")
if u188 then
local v189 = u188:WaitForChild("Animator")
if v189 then
local u190 = v189:LoadAnimation(script.Dance)
u190.Priority = Enum.AnimationPriority.Action
u41 = u190
local u191 = 0
u187:Add(u2.PostSimulation:Connect(function(p192) --[[Anonymous function at line 677]]
--[[
Upvalues:
[1] = u27
[2] = u190
[3] = u188
[4] = u20
[5] = u191
--]]
workspace:GetServerTimeNow()
local v193 = u27.startedAt + 84.5 - workspace:GetServerTimeNow()
if math.max(v193, 0) > 0 then
if not u190.IsPlaying then
u190:Play()
end
elseif u188.MoveDirection ~= Vector3.new(0, 0, 0) or u20:GetAttribute("Stealing") then
u191 = 0
if u190.IsPlaying then
u190:Stop()
end
else
if u191 < 3 then
u191 = u191 + p192
return
end
if not u190.IsPlaying then
u190:Play()
return
end
end
end))
u187:Add(function() --[[Anonymous function at line 703]]
--[[
Upvalues:
[1] = u190
[2] = u41
--]]
u190:Stop()
u190:Destroy()
u41 = nil
end)
end
else
return
end
end))
return u187:WrapClean()
end))
end))
u12:Update()
u10:UpdateOST()
end
function v5.OnStop(_) --[[Anonymous function at line 718]]
--[[
Upvalues:
[1] = u25
[2] = u26
--]]
u25:Destroy()
u26 = nil
end
function v5.OnLoad(_) --[[Anonymous function at line 723]] end
return v5 - Edit
03:12:20.360
- Edit
03:12:20.362
============================== - Edit
03:12:20.362 📜 ReplicatedStorage.Controllers.EventController.Events.4th of July - Edit
03:12:20.362 ==============================
- Edit
03:12:20.362 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: 4th of July, time of decompilation: Fri Jul 4 20:46:27 2025 ]]
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local l_TweenService_0 = game:GetService("TweenService");
local l_RunService_0 = game:GetService("RunService");
local _ = game:GetService("Players");
local _ = game:GetService("Debris");
local _ = require(l_ReplicatedStorage_0.Shared.EventTypes);
local v6 = {};
local v7 = require(l_ReplicatedStorage_0.Controllers.AnimalController);
local v8 = require(l_ReplicatedStorage_0.Controllers.SoundController);
local v9 = require(l_ReplicatedStorage_0.Controllers.EventController);
local v10 = require(l_ReplicatedStorage_0.Controllers.CycleController);
local _ = require(l_ReplicatedStorage_0.Packages.Synchronizer);
local v12 = require(l_ReplicatedStorage_0.Shared.ShakePresets);
local _ = require(l_ReplicatedStorage_0.Packages.Observers);
local v14 = require(l_ReplicatedStorage_0.Packages.Trove);
local v15 = require(l_ReplicatedStorage_0.Packages.Net);
local v16 = v15:RemoteEvent("EventService/4th of July/SpawnEffect");
local v17 = v15:RemoteEvent("EventService/4th of July/CreateFirework");
local v18 = v15:RemoteEvent("EventService/4th of July/ExplodeTraitEffect");
local l_Name_0 = script.Name;
local v20 = v14.new();
local v21 = RaycastParams.new();
v21.FilterType = Enum.RaycastFilterType.Include;
v21.FilterDescendantsInstances = {
workspace.Map,
workspace.Plots
};
@native
local function _(v22, v23, v24, v25) --[[ Line: 33 ]] --[[ Name: quadBezier ]]
return (1 - v22) ^ 2 * v23 + (1 - v22) * 2 * v22 * v24 + v22 ^ 2 * v25;
end;
local function v31(v27) --[[ Line: 37 ]] --[[ Name: getTargetPosition ]]
-- upvalues: v7 (copy)
local v28 = v7:GetAnimals()[v27];
if not v28 then
return (Vector3.new(0, 0, 0, 0));
else
local _ = nil;
local l_AnimalModel_0 = v28.AnimalModel;
return (if l_AnimalModel_0.PrimaryPart then l_AnimalModel_0.PrimaryPart.CFrame else l_AnimalModel_0:GetPivot()).Position + Vector3.new(0, v28.AnimalModel:GetExtentsSize().Y * 0.5, 0);
end;
end;
v6.OnStart = function(_) --[[ Line: 55 ]] --[[ Name: OnStart ]]
-- upvalues: v9 (copy), l_Name_0 (copy), l_ReplicatedStorage_0 (copy), v20 (copy), v8 (copy), v10 (copy), v12 (copy), l_TweenService_0 (copy), v17 (copy), v21 (copy), l_RunService_0 (copy), v31 (copy)
local l_v9_ActiveEventData_0 = v9:GetActiveEventData(l_Name_0);
assert(l_v9_ActiveEventData_0);
l_ReplicatedStorage_0:SetAttribute("4thOfJulyEvent", true);
v20:Add(function() --[[ Line: 60 ]]
-- upvalues: l_ReplicatedStorage_0 (ref)
l_ReplicatedStorage_0:SetAttribute("4thOfJulyEvent", nil);
end);
v8:UpdateOST();
v10:Update();
local v34 = l_ReplicatedStorage_0.Models.Events["4th of July"].Fireworks:Clone();
v34.Parent = workspace;
local l_v34_Children_0 = v34:GetChildren();
table.sort(l_v34_Children_0, function(v36, v37) --[[ Line: 71 ]]
return tonumber(v36.Name) < tonumber(v37.Name);
end);
local v38 = {};
for _, v40 in l_v34_Children_0 do
v38[v40] = v40.CFrame;
end;
local v41 = v12.BumpS:Clone();
v20:Add(v41);
v41.Sustain = true;
v20:Add(v12.BindShakeToCamera(v41, workspace.CurrentCamera));
v41:Start();
v20:Add(task.delay(l_v9_ActiveEventData_0.startedAt + 4 - workspace:GetServerTimeNow(), function() --[[ Line: 86 ]]
-- upvalues: v41 (copy)
v41:StopSustain();
end));
v20:Add(function() --[[ Line: 90 ]]
-- upvalues: l_v34_Children_0 (copy), l_TweenService_0 (ref), v38 (copy), v34 (copy)
for _, v43 in l_v34_Children_0 do
l_TweenService_0:Create(v43, TweenInfo.new(1 + math.random() + math.random(), Enum.EasingStyle.Quad, Enum.EasingDirection.In), {
CFrame = v38[v43] - Vector3.new(0, v43.Size.Y * 1.1, 0)
}):Play();
end;
task.wait(3);
v34:Destroy();
end);
v20:Add(v17.OnClientEvent:Connect(function(v44) --[[ Line: 102 ]]
-- upvalues: l_v34_Children_0 (copy), v38 (copy), l_ReplicatedStorage_0 (ref), v8 (ref), l_TweenService_0 (ref), v21 (ref), l_RunService_0 (ref), v31 (ref)
for _, v46 in v44 do
local v47 = l_v34_Children_0[v46.Chosen];
local v48 = script.Firework:Clone();
v48.CFrame = v38[v47];
v48.Parent = workspace;
local v49 = script.FireworkStartup:Clone();
v49.CFrame = v38[v47] + Vector3.new(0, v47.Size.Y * 0.5 - v49.Size.Y * 0.5, 0);
v49.Parent = workspace;
for _, v51 in v49:GetDescendants() do
if v51:IsA("ParticleEmitter") then
v51:Emit(v51:GetAttribute("EmitCount"));
end;
end;
local v52 = l_ReplicatedStorage_0.Sounds.Events["4th of July"]["Trail Sound Ball"]:Clone();
v52.Parent = v48;
--task.spawn(function()
--pcall(function()
--v8:PlaySound(v52);
--end);
--end);
local v53 = l_ReplicatedStorage_0.Sounds.Events["4th of July"].Shot:Clone();
v53.Parent = v49;
--task.spawn(function()
--pcall(function()
-- v8:PlaySound(v53);
--end);
--end);
task.delay(2, function() --[[ Line: 134 ]]
-- upvalues: v49 (copy)
v49:Destroy();
end);
local v54 = v38[v47] - Vector3.new(0, v47.Size.Y, 0);
local v55 = v38[v47] + Vector3.new(0, v46.Height, 0);
local v56 = v46.Height / 20;
local v57 = l_TweenService_0:Create(v48, TweenInfo.new(v56, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {
CFrame = v55
});
v57:Play();
task.delay(v56 * 0.8, function() --[[ Line: 146 ]]
-- upvalues: v57 (copy), v8 (ref), l_ReplicatedStorage_0 (ref), v55 (copy), v46 (copy), v48 (copy), v54 (copy), v21 (ref), l_RunService_0 (ref), v31 (ref)
v57:Destroy();
--task.spawn(function()
--pcall(function()
--v8:PlaySound(l_ReplicatedStorage_0.Sounds.Events["4th of July"]["Firework Explosion"], v55.Position);
--end);
--end);
local v58 = script.Effects[tostring(v46.FireworkEffect)]:Clone();
v58.CFrame = v55;
v58.Parent = workspace;
for _, v60 in v58:GetDescendants() do
if v60:IsA("ParticleEmitter") then
v60:Emit(v60:GetAttribute("EmitCount"));
end;
end;
v48:Destroy();
task.delay(4, function() --[[ Line: 163 ]]
-- upvalues: v58 (copy)
v58:Destroy();
end);
for _, v62 in v46.Falloffs do
local v63 = nil;
if typeof(v62) == "Vector3" then
v63 = v54 + v62;
local v64 = workspace:Raycast((v55 + v62).Position, Vector3.new(-0, -200, -0, -0), v21);
if v64 then
v63 = CFrame.new(v64.Position);
end;
end;
local v65 = script.Falloff:Clone();
v65.CFrame = v55;
v65.Parent = workspace;
local v66 = 0;
local v67 = nil;
do
local l_v63_0, l_v66_0, l_v67_0 = v63, v66, v67;
l_v67_0 = l_RunService_0.PostSimulation:Connect(function(v71) --[[ Line: 185 ]]
-- upvalues: l_v66_0 (ref), l_v63_0 (ref), v62 (copy), v31 (ref), v65 (copy), v55 (ref), v46 (ref), l_v67_0 (ref)
l_v66_0 = l_v66_0 + v71;
local v72 = l_v63_0 or type(v62) == "string" and CFrame.new((v31(v62))) or CFrame.identity;
local v73 = l_v66_0 / 2.3;
local l_v65_0 = v65;
local l_new_0 = CFrame.new;
local l_Position_0 = v55.Position;
local v77 = v55.Position + Vector3.new(0, v46.Height, 0) + (v72.Position - v55.Position) * Vector3.new(1, 0, 1, 0) * 0.7;
local l_Position_1 = v72.Position;
l_v65_0.CFrame = l_new_0((1 - v73) ^ 2 * l_Position_0 + (1 - v73) * 2 * v73 * v77 + v73 ^ 2 * l_Position_1);
if v73 >= 1 and type(v62) ~= "string" then
l_v65_0 = script.GroundImpact:Clone();
l_v65_0.CFrame = v72 + Vector3.new(0, l_v65_0.Size.Y * 0.5, 0);
l_v65_0.Parent = workspace;
for _, v80 in l_v65_0:GetDescendants() do
if v80:IsA("ParticleEmitter") then
v80:Emit(v80:GetAttribute("EmitCount"));
end;
end;
for _, v82 in v65:GetDescendants() do
if v82:IsA("ParticleEmitter") then
v82.Enabled = false;
end;
end;
task.delay(3, function() --[[ Line: 226 ]]
-- upvalues: v65 (ref), l_v65_0 (copy)
v65:Destroy();
l_v65_0:Destroy();
end);
l_v67_0:Disconnect();
end;
end);
end;
end;
end);
end;
end));
local v83 = Random.new();
for _, v85 in l_v34_Children_0 do
v85.CFrame = v38[v85] - Vector3.new(0, v85.Size.Y * 1.1, 0);
local v86 = l_TweenService_0:Create(v85, TweenInfo.new(v83:NextNumber(3, 7), Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {
CFrame = v38[v85]
});
local v87 = v20:Add(function() --[[ Line: 247 ]]
-- upvalues: v86 (copy)
v86:Cancel();
v86:Destroy();
end);
v86.Completed:Once(function() --[[ Line: 252 ]]
-- upvalues: v20 (ref), v87 (copy)
v20:Remove(v87);
end);
v86:Play();
end;
end;
v6.OnStop = function(_) --[[ Line: 260 ]] --[[ Name: OnStop ]]
-- upvalues: v20 (copy)
v20:Destroy();
end;
v6.OnLoad = function(_) --[[ Line: 264 ]] --[[ Name: OnLoad ]]
-- upvalues: v18 (copy), v7 (copy), v31 (copy), v8 (copy), l_ReplicatedStorage_0 (copy), v16 (copy)
v18.OnClientEvent:Connect(function(v90) --[[ Line: 265 ]]
-- upvalues: v7 (ref), v31 (ref), v8 (ref), l_ReplicatedStorage_0 (ref)
local v91 = v7:GetAnimals()[v90];
if not v91 then
return;
else
local v92 = script.FireworkBurst:Clone();
v92.CFrame = CFrame.new((v31(v90)));
v92.Anchored = false;
local l_WeldConstraint_0 = Instance.new("WeldConstraint");
l_WeldConstraint_0.Part0 = v92;
l_WeldConstraint_0.Part1 = v91.AnimalModel.PrimaryPart;
l_WeldConstraint_0.Parent = v92;
v92.Parent = workspace;
--task.spawn(function()
--pcall(function()
--v8:PlaySound(l_ReplicatedStorage_0.Sounds.Events["4th of July"]["Brainrot Hit"], v92.Position);
--end);
--end);
for _, v95 in v92:GetDescendants() do
if v95:IsA("ParticleEmitter") then
task.delay(v95:GetAttribute("EmitDelay") or 0, function() --[[ Line: 286 ]]
-- upvalues: v95 (copy)
v95:Emit(v95:GetAttribute("EmitCount"));
end);
end;
end;
return;
end;
end);
v16.OnClientEvent:Connect(function(v96) --[[ Line: 293 ]]
local v97 = script.SpawnEffect:Clone();
for _, v99 in v97.fx:GetDescendants() do
if v99:IsA("ParticleEmitter") or v99:IsA("Beam") then
v99.Enabled = true;
end;
end;
v97.Parent = workspace;
task.wait(v96 + 5 - workspace:GetServerTimeNow());
for _, v101 in v97.explode:GetDescendants() do
if v101:IsA("ParticleEmitter") then
task.delay(v101:GetAttribute("EmitDelay") or 0, function() --[[ Line: 306 ]]
-- upvalues: v101 (copy)
v101:Emit(v101:GetAttribute("EmitCount"));
end);
end;
end;
for _, v103 in v97.fx:GetDescendants() do
if v103:IsA("ParticleEmitter") or v103:IsA("Beam") then
v103.Enabled = false;
end;
end;
task.wait(3);
v97:Destroy();
end);
end;
return v6; - Edit
03:12:20.362
- Edit
03:12:20.362
============================== - Edit
03:12:20.362 📜 ReplicatedStorage.Controllers.EventController.Events.Bloodmoon - Edit
03:12:20.363 ==============================
- Edit
03:12:20.363 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: Bloodmoon, time of decompilation: Sat Jun 28 18:35:10 2025 ]]
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("TweenService");
local _ = game:GetService("RunService");
local l_Lighting_0 = game:GetService("Lighting");
local _ = game:GetService("Players");
local _ = require(l_ReplicatedStorage_0.Shared.EventTypes);
local v6 = {};
local _ = require(l_ReplicatedStorage_0.Controllers.AnimalController);
local v8 = require(l_ReplicatedStorage_0.Controllers.SoundController);
local _ = require(l_ReplicatedStorage_0.Controllers.EventController);
local v10 = require(l_ReplicatedStorage_0.Controllers.CycleController);
local _ = require(l_ReplicatedStorage_0.Packages.Spring);
local v12 = require(l_ReplicatedStorage_0.Packages.Trove);
local _ = require(l_ReplicatedStorage_0.Packages.Shake);
local _ = require(l_ReplicatedStorage_0.Packages.Net);
local _ = script.Name;
local v16 = v12.new();
v6.OnStart = function(_) --[[ Line: 24 ]] --[[ Name: OnStart ]]
-- upvalues: l_Lighting_0 (copy), v16 (copy), v10 (copy), v8 (copy)
v16:Add(function() --[[ Line: 27 ]]
-- upvalues: l_Atmosphere_0 (copy), l_Lighting_0 (ref)
script.Atmosphere.Parent = l_Lighting_0;
end);
v16:Clone(script.AtmosphereBloodmoon).Parent = l_Lighting_0;
v16:Add(function() --[[ Line: 35 ]]
-- upvalues: l_Cartoon_0 (copy), l_Lighting_0 (ref)
script.Cartoon.Parent = l_Lighting_0;
end);
v16:Clone(script.SkyBloodmoon).Parent = l_Lighting_0;
v10:Update();
v8:UpdateOST();
end;
v6.OnStop = function(_) --[[ Line: 45 ]] --[[ Name: OnStop ]]
-- upvalues: v16 (copy)
v16:Destroy();
end;
v6.OnLoad = function(_) --[[ Line: 49 ]] --[[ Name: OnLoad ]]
end;
return v6; - Edit
03:12:20.363
- Edit
03:12:20.363
============================== - Edit
03:12:20.363 📜 ReplicatedStorage.Controllers.EventController.Events.Candy - Edit
03:12:20.363 ==============================
- Edit
03:12:20.363 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: Candy, time of decompilation: Sat Jul 5 18:09:18 2025 ]]
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("TweenService");
local _ = game:GetService("RunService");
local l_Lighting_0 = game:GetService("Lighting");
local _ = game:GetService("Players");
local _ = require(l_ReplicatedStorage_0.Shared.EventTypes);
local v6 = {};
local v7 = require(l_ReplicatedStorage_0.Controllers.SoundController);
local _ = require(l_ReplicatedStorage_0.Controllers.EventController);
local v9 = require(l_ReplicatedStorage_0.Controllers.CycleController);
local v10 = require(l_ReplicatedStorage_0.Packages.Trove);
local _ = require(l_ReplicatedStorage_0.Packages.Net);
local _ = script.Name;
local v13 = v10.new();
v6.OnStart = function(_) --[[ Line: 21 ]] --[[ Name: OnStart ]]
-- upvalues: l_Lighting_0 (copy), v13 (copy), v9 (copy), v7 (copy)
local l_Atmosphere_0 = l_Lighting_0:WaitForChild("Atmosphere");
l_Atmosphere_0.Parent = script;
v13:Add(function() --[[ Line: 24 ]]
-- upvalues: l_Atmosphere_0 (copy), l_Lighting_0 (ref)
l_Atmosphere_0.Parent = l_Lighting_0;
end);
v13:Clone(script.AtmosphereCandy).Parent = l_Lighting_0;
local l_Cartoon_0 = l_Lighting_0:WaitForChild("Cartoon");
l_Cartoon_0.Parent = script;
v13:Add(function() --[[ Line: 32 ]]
-- upvalues: l_Cartoon_0 (copy), l_Lighting_0 (ref)
l_Cartoon_0.Parent = l_Lighting_0;
end);
v13:Clone(script.SkyCandy).Parent = l_Lighting_0;
local v17 = script.CandyWeather:Clone();
v17.Parent = workspace;
v13:Add(function() --[[ Line: 40 ]]
-- upvalues: v17 (copy)
for _, v19 in v17:GetDescendants() do
if v19:IsA("ParticleEmitter") then
v19.Enabled = false;
end;
end;
task.wait(4);
v17:Destroy();
end);
v9:Update();
v7:UpdateOST();
end;
v6.OnStop = function(_) --[[ Line: 56 ]] --[[ Name: OnStop ]]
-- upvalues: v13 (copy)
v13:Destroy();
end;
v6.OnLoad = function(_) --[[ Line: 60 ]] --[[ Name: OnLoad ]]
end;
return v6; - Edit
03:12:20.363
- Edit
03:12:20.363
============================== - Edit
03:12:20.363 📜 ReplicatedStorage.Controllers.EventController.Events.Crab Rave - Edit
03:12:20.363 ==============================
- Edit
03:12:20.364 -- Thanks For Angelus Decompiles --> https://discord.gg/CYXme7yEG9
-- Decompiled with Velocity Script Decompiler
local v_u_1 = game:GetService("ReplicatedStorage")
local v_u_2 = game:GetService("ContentProvider")
local v_u_3 = game:GetService("TweenService")
local v_u_4 = game:GetService("RunService")
game:GetService("Lighting")
local v_u_5 = game:GetService("Players")
require(v_u_1.Shared.EventTypes)
local v6 = {}
local v_u_7 = require(v_u_1.Controllers.CameraController)
local v_u_8 = require(v_u_1.Controllers.AnimalController)
local v_u_9 = require(v_u_1.Controllers.EffectController)
local v_u_10 = require(v_u_1.Controllers.SoundController)
local v_u_11 = require(v_u_1.Controllers.CycleController)
local v_u_12 = require(v_u_1.Controllers.EventController)
require(v_u_1.Packages.Synchronizer)
local v_u_13 = require(v_u_1.Packages.Observers)
require(v_u_1.Shared.TweenPivot)
local v_u_14 = require(v_u_1.Packages.Signal)
require(v_u_1.Packages.FFlags)
local v_u_15 = require(v_u_1.Packages.Trove)
local v16 = require(v_u_1.Packages.Net)
local v_u_17 = require(v_u_1.Shared.VFX)
local v_u_18 = v16:RemoteEvent("EventService/Crab Rave/Hit")
local v_u_19 = v_u_5.LocalPlayer
local v_u_20 = workspace.Sounds.CrabRave
local v_u_21 = script.Name
local v_u_22 = v_u_15.new()
function v6.OnStart(_)
-- upvalues: (copy) v_u_12, (copy) v_u_21, (copy) v_u_22, (copy) v_u_1, (copy) v_u_11, (copy) v_u_10, (copy) v_u_20, (copy) v_u_3, (copy) v_u_17, (copy) v_u_9, (copy) v_u_13, (copy) v_u_15, (copy) v_u_4, (copy) v_u_7, (copy) v_u_14, (copy) v_u_5, (copy) v_u_19
local v_u_23 = v_u_12:GetActiveEventData(v_u_21)
assert(v_u_23)
local v_u_24 = true
v_u_22:Add(function()
-- upvalues: (ref) v_u_24
v_u_24 = false
end)
v_u_1:SetAttribute("CrabRave", true)
v_u_22:Add(function()
-- upvalues: (ref) v_u_1, (ref) v_u_11, (ref) v_u_10
v_u_1:SetAttribute("CrabRave", nil)
v_u_11:Update()
v_u_10:UpdateOST()
end)
v_u_22:Add(task.spawn(function()
-- upvalues: (ref) v_u_20, (copy) v_u_23
while not v_u_20.IsLoaded do
task.wait()
end
local v25 = v_u_20
local v26 = v_u_20.TimePosition
local v27 = workspace:GetServerTimeNow() - v_u_23.startedAt
v25.TimePosition = math.max(v26, v27)
end))
v_u_11:Update()
v_u_10:UpdateOST()
local v_u_28 = v_u_22:Add(Instance.new("ColorCorrectionEffect"))
v_u_28.Parent = workspace.CurrentCamera
local v_u_29 = v_u_22:Clone(script.Ocean)
v_u_29.Parent = workspace
local v_u_30 = v_u_22:Add(Instance.new("Highlight"))
assert(v_u_30)
v_u_30.DepthMode = Enum.HighlightDepthMode.Occluded
v_u_30.FillColor = Color3.new(1, 1, 1)
v_u_30.FillTransparency = 1
v_u_30.OutlineTransparency = 1
for _, v31 in v_u_29:GetChildren() do
if v31:IsA("Beam") then
local v32 = v31.TextureLength
v31.TextureLength = 0
v_u_3:Create(v_u_29.ocean, TweenInfo.new(v_u_23.startedAt + 45 - workspace:GetServerTimeNow(), Enum.EasingStyle.Quint, Enum.EasingDirection.In), {
["TextureLength"] = v32
}):Play()
end
end
v_u_3:Create(v_u_29.att1, TweenInfo.new(v_u_23.startedAt + 45 - workspace:GetServerTimeNow(), Enum.EasingStyle.Quint, Enum.EasingDirection.In), {
["Position"] = Vector3.new(0, 0, 400)
}):Play()
v_u_3:Create(v_u_28, TweenInfo.new(v_u_23.startedAt + 1.95 - workspace:GetServerTimeNow()), {
["Brightness"] = -1.2
}):Play()
v_u_22:Add(task.delay(v_u_23.startedAt + 45 - workspace:GetServerTimeNow(), function()
-- upvalues: (ref) v_u_17, (copy) v_u_29
v_u_17.enable(v_u_29.oceanparticles)
end))
v_u_9:Run("CrabRaveEvent", "GrassRecolor")
v_u_22:Add(function()
-- upvalues: (ref) v_u_9
v_u_9:Stop("CrabRaveEvent", "GrassRecolor")
end)
v_u_22:Add(function()
-- upvalues: (ref) v_u_9
v_u_9:Activate("Blink")
end)
v_u_22:Add(v_u_13.observeTag("CrabRaveCrabFolder", function(p33)
-- upvalues: (ref) v_u_30
v_u_30.Parent = p33
return nil
end))
v_u_22:Add(v_u_13.observeTag("CrabRaveCrabs", function(p_u_34)
-- upvalues: (ref) v_u_15, (copy) v_u_23, (ref) v_u_4
local v_u_35 = v_u_15.new()
local v_u_36 = p_u_34.Parent.Name
local v_u_37 = v_u_35:Clone(script.Crab)
local v_u_38 = nil
local v_u_39 = nil
v_u_37["Cylinder.005"].Transparency = 1
v_u_35:Add(task.delay(v_u_23.startedAt + 2 - workspace:GetServerTimeNow(), function()
-- upvalues: (copy) v_u_37
v_u_37["Cylinder.005"].Transparency = 0
end))
local v_u_40 = v_u_35:Add(Instance.new("Weld"))
v_u_40.Part0 = v_u_37["Cylinder.005"]
v_u_40.Part1 = p_u_34.HumanoidRootPart
v_u_40.C1 = CFrame.new(0, 3.6, 0)
v_u_40.Parent = v_u_37
local v_u_41 = 0
local v_u_42 = 0
local v_u_43 = CFrame.new(0, 3.6, 0)
v_u_35:Add(v_u_4.PostSimulation:Connect(function(p44)
-- upvalues: (ref) v_u_42, (ref) v_u_41, (copy) v_u_40, (copy) v_u_43
local v45 = v_u_42 - v_u_41
if math.abs(v45) >= 0.1 then
local v46 = v_u_42
local v47 = v_u_41 - v_u_42
local v48 = p44 * -1
v_u_41 = v46 + v47 * math.exp(v48)
v_u_40.C1 = v_u_43 * CFrame.Angles(0, v_u_41, 0)
end
end))
v_u_37.Parent = p_u_34
local v49 = script.Animation1
local v_u_50 = v_u_37.AnimationController:LoadAnimation(v49)
v_u_35:Add(function()
-- upvalues: (copy) v_u_50
v_u_50:Stop(0)
v_u_50:Destroy()
end)
local v51 = script.Animation2
local v_u_52 = v_u_37.AnimationController:LoadAnimation(v51)
v_u_35:Add(function()
-- upvalues: (copy) v_u_52
v_u_52:Stop(0)
v_u_52:Destroy()
end)
local v53 = script.Animation3_Right
local v_u_54 = v_u_37.AnimationController:LoadAnimation(v53)
v_u_35:Add(function()
-- upvalues: (copy) v_u_54
v_u_54:Stop(0)
v_u_54:Destroy()
end)
local v55 = script.Animation3_Left
local v_u_56 = v_u_37.AnimationController:LoadAnimation(v55)
v_u_35:Add(function()
-- upvalues: (copy) v_u_56
v_u_56:Stop(0)
v_u_56:Destroy()
end)
v_u_56.Priority = Enum.AnimationPriority.Action
local v57 = script.Animation4_Walk
local v_u_58 = v_u_37.AnimationController:LoadAnimation(v57)
v_u_35:Add(function()
-- upvalues: (copy) v_u_58
v_u_58:Stop(0)
v_u_58:Destroy()
end)
local v_u_59 = v_u_58
v_u_59.Priority = Enum.AnimationPriority.Action
local v60 = script.Animation4_Attack
local v_u_61 = v_u_37.AnimationController:LoadAnimation(v60)
v_u_35:Add(function()
-- upvalues: (copy) v_u_61
v_u_61:Stop(0)
v_u_61:Destroy()
end)
v_u_61.Priority = Enum.AnimationPriority.Action4
local v_u_62 = v_u_59
v_u_50:Play()
local v63 = p_u_34:FindFirstChildOfClass("Humanoid")
if v63 then
v_u_35:Add(v63.Running:Connect(function(p64)
-- upvalues: (ref) v_u_62, (ref) v_u_38, (ref) v_u_39
if p64 > 1 then
if not v_u_62.IsPlaying then
v_u_62:Play()
end
if v_u_38 then
v_u_38.ParticleEmitter.Enabled = true
end
if v_u_39 then
v_u_39.ParticleEmitter.Enabled = true
return
end
else
if v_u_62.IsPlaying then
v_u_62:Stop()
end
if v_u_38 then
v_u_38.ParticleEmitter.Enabled = false
end
if v_u_39 then
v_u_39.ParticleEmitter.Enabled = false
end
end
end))
end
v_u_35:Add(p_u_34:GetAttributeChangedSignal("Attack"):Connect(function()
-- upvalues: (copy) v_u_61
v_u_61:Play()
end))
local v65 = script.Animation5
local v_u_66 = v_u_37.AnimationController:LoadAnimation(v65)
v_u_35:Add(function()
-- upvalues: (copy) v_u_66
v_u_66:Stop(0)
v_u_66:Destroy()
end)
v_u_66.Priority = Enum.AnimationPriority.Action2
local v67 = script.Animation6
local v_u_68 = v_u_37.AnimationController:LoadAnimation(v67)
v_u_35:Add(function()
-- upvalues: (copy) v_u_68
v_u_68:Stop(0)
v_u_68:Destroy()
end)
v_u_68.Priority = Enum.AnimationPriority.Action2
local v69 = script.Animation7
local v_u_70 = v_u_37.AnimationController:LoadAnimation(v69)
v_u_35:Add(function()
-- upvalues: (copy) v_u_70
v_u_70:Stop(0)
v_u_70:Destroy()
end)
v_u_70.Priority = Enum.AnimationPriority.Action2
local v71 = script.Animation8
local v_u_72 = v_u_37.AnimationController:LoadAnimation(v71)
v_u_35:Add(function()
-- upvalues: (copy) v_u_72
v_u_72:Stop(0)
v_u_72:Destroy()
end)
local v_u_73 = v_u_72
v_u_73.Priority = Enum.AnimationPriority.Action2
local v_u_74 = {
v_u_66,
v_u_68,
v_u_70,
v_u_73
}
local v_u_75 = nil
v_u_35:Add(p_u_34:GetAttributeChangedSignal("Dance"):Connect(function()
-- upvalues: (ref) v_u_23, (copy) p_u_34, (copy) v_u_74, (ref) v_u_75
local v76 = v_u_23.startedAt + 85 - workspace:GetServerTimeNow()
local v77 = v_u_23.startedAt + 105 - workspace:GetServerTimeNow()
local v78 = v76 <= 0 and v77 > 0 and 4 or p_u_34:GetAttribute("Dance")
if not v78 or (not v_u_74[v78] or v_u_75 ~= v_u_74[v78]) then
if v_u_75 then
v_u_75:Stop()
v_u_75 = nil
end
if v78 ~= nil then
v_u_75 = v_u_74[v78]
local v79 = v_u_75
assert(v79)
v_u_75:Play()
end
end
end))
local v_u_80 = nil
v_u_35:Add(task.delay(v_u_23.startedAt + 7 - workspace:GetServerTimeNow(), function()
-- upvalues: (copy) v_u_50, (copy) v_u_52
v_u_50:Stop()
v_u_52:Play()
end))
if v_u_36 == "Ground" then
v_u_35:Add(p_u_34:GetAttributeChangedSignal("ReachedFirstTarget"):Once(function()
-- upvalues: (ref) v_u_80, (copy) v_u_35, (copy) v_u_37
v_u_80 = v_u_35:Clone(script.SanddrumRoll)
local v81 = v_u_35:Add(Instance.new("Weld"))
v81.Part0 = v_u_80
v81.Part1 = v_u_37["Cylinder.005"]
v81.C0 = CFrame.new(0.2, 3.629, 4.378)
v81.Parent = v_u_80
v_u_80.Parent = v_u_37
end))
end
v_u_35:Add(task.delay(v_u_23.startedAt + 27.5 - workspace:GetServerTimeNow(), function()
-- upvalues: (copy) v_u_36, (copy) p_u_34, (ref) v_u_80, (copy) v_u_35, (copy) v_u_56, (ref) v_u_62, (ref) v_u_42
if v_u_36 == "Ground" then
p_u_34:GetPivot()
if v_u_80 then
local v_u_82 = v_u_80
v_u_82.ParticleEmitter.Enabled = false
task.delay(3, function()
-- upvalues: (ref) v_u_35, (copy) v_u_82
v_u_35:Remove(v_u_82)
end)
v_u_80 = nil
end
local v83 = v_u_56
if v_u_62 ~= v83 then
if v_u_62.IsPlaying then
v_u_62:Stop()
end
v_u_62 = v83
end
v_u_56:Play(nil, nil, 0.3333333333333333)
v_u_42 = 1.5707963267948966
end
end))
v_u_35:Add(task.delay(v_u_23.startedAt + 31 - workspace:GetServerTimeNow(), function()
-- upvalues: (copy) v_u_36, (copy) v_u_56, (ref) v_u_38, (copy) v_u_35, (copy) v_u_37, (ref) v_u_39, (copy) v_u_52, (copy) v_u_50
if v_u_36 == "Ground" then
v_u_56:AdjustSpeed(1)
v_u_38 = v_u_35:Clone(script.WalkPart)
local v84 = v_u_38
assert(v84)
local v85 = v_u_35:Add(Instance.new("Weld"))
v85.Part0 = v_u_38
v85.Part1 = v_u_37["Cylinder.005"]
v85.C0 = CFrame.new(0.614, 3.129, 4.731) * CFrame.fromOrientation(0, -1.5707963267948966, 0)
v85.Parent = v_u_38
v_u_38.Parent = v_u_37
v_u_39 = v_u_35:Clone(script.WalkPart)
local v86 = v_u_39
assert(v86)
local v87 = v_u_35:Add(Instance.new("Weld"))
v87.Part0 = v_u_39
v87.Part1 = v_u_37["Cylinder.005"]
v87.C0 = CFrame.new(0.414, 3.129, -4.78) * CFrame.fromOrientation(0, -1.5707963267948966, 0)
v87.Parent = v_u_39
v_u_39.Parent = v_u_37
elseif v_u_36 == "Wall" then
v_u_52:Stop()
v_u_50:Play()
end
end))
v_u_35:Add(task.delay(v_u_23.startedAt + 43 - workspace:GetServerTimeNow(), function()
-- upvalues: (copy) v_u_54, (ref) v_u_42
v_u_54:Play(nil, nil, 0.3333333333333333)
v_u_42 = 0
end))
v_u_35:Add(task.delay(v_u_23.startedAt + 46 - workspace:GetServerTimeNow(), function()
-- upvalues: (copy) v_u_54, (copy) v_u_59, (ref) v_u_62, (copy) v_u_36, (copy) v_u_52, (copy) v_u_50
v_u_54:Stop()
local v88 = v_u_59
if v_u_62 ~= v88 then
local v89 = v_u_62.IsPlaying
if v89 then
v_u_62:Stop()
end
v_u_62 = v88
if v89 then
v_u_62:Play()
end
end
if v_u_36 == "Wall" then
v_u_52:Stop()
v_u_50:Play()
end
end))
v_u_35:Add(task.delay(v_u_23.startedAt + 141 - workspace:GetServerTimeNow(), function()
-- upvalues: (ref) v_u_23, (copy) v_u_35, (ref) v_u_4, (copy) v_u_66, (copy) v_u_68, (copy) v_u_70, (copy) v_u_73
local v_u_90 = v_u_23.startedAt + 161 - workspace:GetServerTimeNow()
local v_u_91 = 0
v_u_35:Add(v_u_4.PreSimulation:Connect(function(p92)
-- upvalues: (ref) v_u_91, (copy) v_u_90, (ref) v_u_66, (ref) v_u_68, (ref) v_u_70, (ref) v_u_73
v_u_91 = v_u_91 + p92
local v93 = v_u_91 / v_u_90
v_u_66:AdjustSpeed((math.lerp(1, 0.1, v93)))
v_u_68:AdjustSpeed((math.lerp(1, 0.1, v93)))
v_u_70:AdjustSpeed((math.lerp(1, 0.1, v93)))
v_u_73:AdjustSpeed((math.lerp(1, 0.1, v93)))
end))
end))
return function()
-- upvalues: (copy) v_u_35
v_u_35:Destroy()
end
end))
local _ = workspace.CurrentCamera
local v_u_94 = 0
local v_u_95 = 0
v_u_22:Add(v_u_4.PostSimulation:Connect(function(p96)
-- upvalues: (ref) v_u_95, (ref) v_u_94, (ref) v_u_20, (ref) v_u_30, (ref) v_u_3, (ref) v_u_7
v_u_95 = v_u_95 - p96
v_u_94 = v_u_94 - p96
local v97 = (v_u_20.PlaybackLoudness - 100) / 900
local v98 = math.clamp(v97, 0, 1)
if v_u_94 <= 0 and v_u_30 then
v_u_94 = 0.5
v_u_30.FillTransparency = 0
v_u_3:Create(v_u_30, TweenInfo.new(0.3), {
["FillTransparency"] = 1
}):Play()
end
if v98 >= 0.25 and v_u_95 <= 0 then
v_u_95 = 0.1
v_u_7:Fov((v98 - 0.25) * 20 + 70, 0.1)
end
end))
v_u_22:Add(task.delay(v_u_23.startedAt + 7 - workspace:GetServerTimeNow(), function()
-- upvalues: (ref) v_u_30, (ref) v_u_3, (copy) v_u_28
if v_u_30 then
v_u_30:Destroy()
v_u_30 = nil
end
local v_u_99 = v_u_3:Create(v_u_28, TweenInfo.new(1), {
["Brightness"] = 0
})
v_u_99:Play()
v_u_99.Completed:Once(function()
-- upvalues: (copy) v_u_99
v_u_99:Cancel()
v_u_99:Destroy()
end)
end))
v_u_22:Add(task.delay(v_u_23.startedAt + 46 - workspace:GetServerTimeNow(), function()
-- upvalues: (ref) v_u_22, (ref) v_u_14, (ref) v_u_13, (ref) v_u_5, (ref) v_u_15, (ref) v_u_4, (copy) v_u_23, (ref) v_u_19
v_u_22:Add(v_u_14.new())
local v110 = v_u_22:Add(v_u_13.observeCharacter(v_u_5.LocalPlayer, function(_, p_u_100)
-- upvalues: (ref) v_u_15, (ref) v_u_4, (ref) v_u_23, (ref) v_u_19
local v_u_101 = v_u_15.new()
v_u_101:Add(task.spawn(function()
-- upvalues: (copy) p_u_100, (copy) v_u_101, (ref) v_u_4, (ref) v_u_23, (ref) v_u_19
local v_u_102 = p_u_100:WaitForChild("Humanoid")
if v_u_102 then
local v103 = v_u_102:WaitForChild("Animator")
if v103 then
local v_u_104 = v103:LoadAnimation(script.Dance)
v_u_104.Priority = Enum.AnimationPriority.Action
v_u_104:Play(2)
local v_u_105 = 0
local v_u_106 = 0
v_u_101:Add(v_u_4.PostSimulation:Connect(function(p107)
-- upvalues: (ref) v_u_23, (copy) v_u_104, (ref) v_u_106, (copy) v_u_102, (ref) v_u_19, (ref) v_u_105
local v108 = workspace:GetServerTimeNow()
if v_u_23.startedAt + 66 - (v108 or workspace:GetServerTimeNow()) > 0 then
if not v_u_104.IsPlaying then
v_u_104:Play()
v_u_104.TimePosition = (v108 - v_u_23.startedAt) % v_u_104.Length
end
else
local v109 = v_u_104.Length
if v_u_106 ~= v109 and v109 > 0 then
v_u_106 = v109
v_u_104.TimePosition = (v108 - v_u_23.startedAt) % v109
end
if v_u_102.MoveDirection ~= Vector3.new(0, 0, 0) or v_u_19:GetAttribute("Stealing") then
v_u_105 = 0
if v_u_104.IsPlaying then
v_u_104:Stop()
end
else
if v_u_105 < 3 then
v_u_105 = v_u_105 + p107
return
end
if not v_u_104.IsPlaying then
v_u_104:Play()
v_u_104.TimePosition = (v108 - v_u_23.startedAt) % v_u_104.Length
return
end
end
end
end))
v_u_101:Add(function()
-- upvalues: (copy) v_u_104
v_u_104:Stop()
v_u_104:Destroy()
end)
end
else
return
end
end))
return v_u_101:WrapClean()
end))
v_u_22:Add(task.delay(v_u_23.startedAt + 140 - workspace:GetServerTimeNow(), v110))
end))
end
function v6.OnStop(_)
-- upvalues: (copy) v_u_22
v_u_22:Destroy()
end
function v6.OnLoad(_)
-- upvalues: (copy) v_u_2, (copy) v_u_18, (copy) v_u_8, (copy) v_u_17
task.spawn(pcall, function()
-- upvalues: (ref) v_u_2
v_u_2:PreloadAsync(script:GetChildren())
end)
v_u_18.OnClientEvent:Connect(function(p111)
-- upvalues: (ref) v_u_8, (ref) v_u_17
local v112
if type(p111) == "string" then
local v113 = v_u_8:GetAnimals()[p111]
if not v113 then
return
end
local v114 = v113.AnimalModel
local v115
if v114.PrimaryPart then
v115 = v114.PrimaryPart.CFrame
else
v115 = v114:GetPivot()
end
local v116 = v115.Position
local v117 = v113.AnimalModel:GetExtentsSize().Y * 0.5
v112 = v116 + Vector3.new(0, v117, 0)
p111 = v113.AnimalModel.PrimaryPart
else
v112 = p111:GetPivot().Position
end
local v118 = script.CrabHit:Clone()
v118:PivotTo(CFrame.new(v112))
v118.Anchored = false
local v119 = Instance.new("WeldConstraint")
v119.Part0 = v118
v119.Part1 = p111
v119.Parent = v118
v118.Parent = workspace
v_u_17.emit(v118)
end)
end
return v6 - Edit
03:12:20.364
- Edit
03:12:20.364
============================== - Edit
03:12:20.364 📜 ReplicatedStorage.Controllers.EventController.Events.La Vacca Saturno Saturnita - Edit
03:12:20.364 ==============================
- Edit
03:12:20.364 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: La Vacca Saturno Saturnita, time of decompilation: Sat Jun 28 18:35:10 2025 ]]
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("TweenService");
local l_RunService_0 = game:GetService("RunService");
local _ = game:GetService("Players");
local _ = game:GetService("Debris");
local _ = require(l_ReplicatedStorage_0.Shared.EventTypes);
local v6 = {};
local _ = l_ReplicatedStorage_0.Models.Events["La Vacca"];
local v8 = require(l_ReplicatedStorage_0.Controllers.AnimalController);
local v9 = require(l_ReplicatedStorage_0.Controllers.EffectController);
local v10 = require(l_ReplicatedStorage_0.Controllers.SoundController);
local v11 = require(l_ReplicatedStorage_0.Controllers.EventController);
local v12 = require(l_ReplicatedStorage_0.Controllers.CycleController);
local v13 = require(l_ReplicatedStorage_0.Shared.ShakePresets);
local v14 = require(l_ReplicatedStorage_0.Packages.Observers);
local _ = require(l_ReplicatedStorage_0.Shared.TweenPivot);
local v16 = require(l_ReplicatedStorage_0.Packages.Trove);
local _ = require(l_ReplicatedStorage_0.Packages.Shake);
local v18 = require(l_ReplicatedStorage_0.Packages.Net):RemoteEvent("EventService/LaVacca/Comet");
local l_Name_0 = script.Name;
local v20 = v16.new();
local l_CurrentCamera_0 = workspace.CurrentCamera;
v6.OnStart = function(_) --[[ Line: 32 ]] --[[ Name: OnStart ]]
-- upvalues: v11 (copy), l_Name_0 (copy), v20 (copy), l_ReplicatedStorage_0 (copy), l_RunService_0 (copy), v14 (copy), v9 (copy), v10 (copy), v12 (copy), v18 (copy), v8 (copy), l_CurrentCamera_0 (copy), v13 (copy)
local l_v11_ActiveEventData_0 = v11:GetActiveEventData(l_Name_0);
assert(l_v11_ActiveEventData_0);
local _ = workspace:GetServerTimeNow();
local v25 = l_v11_ActiveEventData_0.startedAt + 11 - workspace:GetServerTimeNow();
if v25 > 0 then
local v26 = v20:Extend();
local v27 = v26:Add(Instance.new("Model"));
local v28 = v26:Add(Instance.new("Part"));
v28.Name = "Center";
v28.Transparency = 1;
v28.Anchored = true;
v28.CanCollide = false;
v28.CanQuery = false;
v28.CanTouch = false;
v28.Size = Vector3.new(1, 1, 1, 0);
v28.Position = l_ReplicatedStorage_0:GetAttribute("LaVaccaCenter") or workspace.MapCenter.Position;
v28.Parent = v27;
v27.PrimaryPart = v28;
v27.Parent = workspace;
local v29 = table.create(3);
v26:Add(function() --[[ Line: 68 ]]
-- upvalues: v29 (copy)
table.clear(v29);
end);
local v30 = 0;
do
local l_v30_0 = v30;
v26:Add(l_RunService_0.PreRender:Connect(function(v32) --[[ Line: 73 ]]
-- upvalues: l_v30_0 (ref), v29 (copy)
debug.profilebegin("La Vacca Event");
l_v30_0 = l_v30_0 + v32;
for v33, v34 in v29 do
if v34.target and v34.targetAttachment then
v34.beam.First.Enabled = true;
v34.beam.Second.Enabled = true;
local v35 = math.clamp(l_v30_0 - v33 + 1, 0, 1);
local l_WorldPosition_0 = v34.beam.WorldPosition;
v34.targetAttachment.Position = l_WorldPosition_0 + (v34.target:GetPivot().Position - l_WorldPosition_0) * v35;
end;
end;
debug.profileend();
end));
local v37 = {};
v26:Add(v14.observeTag("LaVaccaModel", function(v38) --[[ Line: 96 ]]
-- upvalues: v37 (copy), v27 (copy), v29 (copy), v14 (ref)
table.insert(v37, v38);
v38.Parent = v27;
local v39 = script.PlayerVFX.Beam:Clone();
v39.Parent = v38.PrimaryPart;
v29[v38:GetAttribute("LaVaccaIndex")] = {
beam = v39,
target = nil
};
local v43 = v14.observeTag("LaVaccaModel", function(v40) --[[ Line: 108 ]]
-- upvalues: v38 (copy), v39 (copy), v29 (ref)
if v40 == v38 then
return nil;
elseif v40:GetAttribute("LaVaccaIndex") ~= v38:GetAttribute("LaVaccaIndex") % 3 + 1 then
return nil;
else
local l_Attachment_0 = Instance.new("Attachment");
l_Attachment_0.Position = v39.WorldPosition;
l_Attachment_0.Parent = workspace.Terrain;
local v42 = v29[v38:GetAttribute("LaVaccaIndex")];
v42.target = v40.PrimaryPart;
v42.beam.First.Attachment0 = l_Attachment_0;
v42.beam.Second.Attachment0 = l_Attachment_0;
v42.targetAttachment = l_Attachment_0;
return function() --[[ Line: 127 ]]
-- upvalues: l_Attachment_0 (copy)
l_Attachment_0:Destroy();
end;
end;
end);
return function() --[[ Line: 132 ]]
-- upvalues: v29 (ref), v38 (copy), v39 (copy), v43 (copy), v37 (ref)
v29[v38:GetAttribute("LaVaccaIndex")] = nil;
v39:Destroy();
v43();
local v44 = table.find(v37, v38);
if v44 then
table.remove(v37, v44);
end;
end;
end));
local l_CFrame_0 = v28.CFrame;
local v46 = v26:Clone(script.SummonVFX);
v46:PivotTo(l_CFrame_0);
v46.Parent = workspace;
local v47 = v26:Clone(script.SummonVFXBeam);
v47:PivotTo(l_CFrame_0);
v47.Parent = workspace;
v26:Add(l_RunService_0.PostSimulation:Connect(function(_) --[[ Line: 155 ]]
-- upvalues: l_v11_ActiveEventData_0 (copy), v27 (copy), l_CFrame_0 (copy), v47 (copy), v26 (copy)
debug.profilebegin("La Vacca Event Animation");
local l_workspace_ServerTimeNow_1 = workspace:GetServerTimeNow();
if l_workspace_ServerTimeNow_1 < l_v11_ActiveEventData_0.startedAt + 3 then
return;
else
local v50 = math.clamp(1 - (l_v11_ActiveEventData_0.startedAt + 11 - l_workspace_ServerTimeNow_1) / 8, 0, 1);
local v51 = v50 * v50 * 3.141592653589793 * 2 * 8;
local v52 = v50 * v50 * 150;
v27:PivotTo(l_CFrame_0 * CFrame.Angles(0, v51, 0) * CFrame.new(0, v52, 0));
v47.Beams.Position = Vector3.new(0, v52, 0);
if v50 >= 1 then
v26:Clean();
end;
debug.profileend();
return;
end;
end));
v26:Add(v14.observeTag("LaVaccaPlayerVFX", function(v53) --[[ Line: 177 ]]
local v54 = script.PlayerVFX.Torso:Clone();
v54.Parent = v53;
return function() --[[ Line: 181 ]]
-- upvalues: v54 (copy)
v54:Destroy();
end;
end, {
workspace
}));
end;
end;
v20:Add(task.delay(v25, function() --[[ Line: 187 ]]
-- upvalues: v9 (ref), l_Name_0 (ref), v20 (ref), l_ReplicatedStorage_0 (ref), v10 (ref), v12 (ref)
v9:Run(l_Name_0, "Space");
v9:Activate("Blink");
v20:Add(function() --[[ Line: 191 ]]
-- upvalues: v9 (ref)
v9:Activate("Blink");
end);
l_ReplicatedStorage_0:SetAttribute("LaVaccaEvent", true);
v10:UpdateOST();
v12:Update();
v20:Add(function() --[[ Line: 199 ]]
-- upvalues: l_ReplicatedStorage_0 (ref), v9 (ref), l_Name_0 (ref)
l_ReplicatedStorage_0:SetAttribute("LaVaccaEvent", nil);
v9:Stop(l_Name_0, "Space");
end);
end));
v20:Add(v18.OnClientEvent:Connect(function(v55, v56) --[[ Line: 205 ]]
-- upvalues: v8 (ref), v10 (ref), l_ReplicatedStorage_0 (ref), l_RunService_0 (ref), l_CurrentCamera_0 (ref), v13 (ref), v20 (ref)
local v57 = v8:GetAnimals()[v56];
if not v57 then
return;
else
local _ = function() --[[ Line: 211 ]] --[[ Name: getTargetPosition ]]
-- upvalues: v57 (copy)
local _ = nil;
local l_AnimalModel_0 = v57.AnimalModel;
return (if l_AnimalModel_0.PrimaryPart then l_AnimalModel_0.PrimaryPart.CFrame else l_AnimalModel_0:GetPivot()).Position + Vector3.new(0, v57.AnimalModel:GetExtentsSize().Y * 0.5, 0);
end;
local v61 = CFrame.new(v55);
task.spawn(function() --[[ Line: 226 ]]
-- upvalues: v10 (ref), l_ReplicatedStorage_0 (ref), v57 (copy)
local l_v10_0 = v10;
local l_CommetActivation_0 = l_ReplicatedStorage_0.Sounds.Events["La Vacca Saturno Saturnita"].CommetActivation;
local _ = nil;
local l_AnimalModel_1 = v57.AnimalModel;
l_v10_0:PlaySound(l_CommetActivation_0, (if l_AnimalModel_1.PrimaryPart then l_AnimalModel_1.PrimaryPart.CFrame else l_AnimalModel_1:GetPivot()).Position + Vector3.new(0, v57.AnimalModel:GetExtentsSize().Y * 0.5, 0));
end);
local v66 = script.Comet:Clone();
v66:PivotTo(v61);
v66.Parent = workspace;
local v67 = 0;
local v68 = nil;
v68 = l_RunService_0.PreRender:Connect(function(v69) --[[ Line: 237 ]]
-- upvalues: v68 (ref), v67 (ref), v57 (copy), v66 (copy), v61 (copy), v10 (ref), l_ReplicatedStorage_0 (ref), l_CurrentCamera_0 (ref), v13 (ref), v20 (ref)
if not v68 or not v68.Connected then
return;
else
debug.profilebegin("La Vacca Commet Hit");
v67 = v67 + v69;
local l_new_0 = CFrame.new;
local _ = nil;
local l_AnimalModel_2 = v57.AnimalModel;
l_new_0 = l_new_0((if l_AnimalModel_2.PrimaryPart then l_AnimalModel_2.PrimaryPart.CFrame else l_AnimalModel_2:GetPivot()).Position + Vector3.new(0, v57.AnimalModel:GetExtentsSize().Y * 0.5, 0));
local v73 = math.clamp(v67 / 1, 0, 1);
v66:PivotTo(v61:Lerp(l_new_0, v73));
if v73 >= 1 then
v68:Disconnect();
task.spawn(function() --[[ Line: 253 ]]
-- upvalues: v10 (ref), l_ReplicatedStorage_0 (ref), v57 (ref)
local l_v10_1 = v10;
local l_CommetHit_0 = l_ReplicatedStorage_0.Sounds.Events["La Vacca Saturno Saturnita"].CommetHit;
local _ = nil;
local l_AnimalModel_3 = v57.AnimalModel;
l_v10_1:PlaySound(l_CommetHit_0, (if l_AnimalModel_3.PrimaryPart then l_AnimalModel_3.PrimaryPart.CFrame else l_AnimalModel_3:GetPivot()).Position + Vector3.new(0, v57.AnimalModel:GetExtentsSize().Y * 0.5, 0));
end);
if (l_CurrentCamera_0.CFrame.Position - l_new_0.Position).Magnitude <= 70 then
l_AnimalModel_2 = v13.Bump:Clone();
v20:Add(l_AnimalModel_2);
l_AnimalModel_2.Sustain = true;
v20:Add(v13.BindShakeToCamera(l_AnimalModel_2, l_CurrentCamera_0));
l_AnimalModel_2:Start();
local l_l_AnimalModel_2_0 = l_AnimalModel_2 --[[ copy: 4 -> 11 ]];
v20:Add(task.delay(0.3, function() --[[ Line: 265 ]]
-- upvalues: l_l_AnimalModel_2_0 (copy)
l_l_AnimalModel_2_0:StopSustain();
end));
end;
l_AnimalModel_2 = script.CometBurst:Clone();
l_AnimalModel_2:PivotTo(l_new_0);
l_AnimalModel_2.Anchored = false;
local l_WeldConstraint_0 = Instance.new("WeldConstraint");
l_WeldConstraint_0.Part0 = l_AnimalModel_2;
l_WeldConstraint_0.Part1 = v57.AnimalModel.PrimaryPart;
l_WeldConstraint_0.Parent = l_AnimalModel_2;
l_AnimalModel_2.Parent = workspace;
for _, v81 in v66:GetDescendants() do
if v81:IsA("BasePart") then
v81.Transparency = 1;
elseif v81:IsA("ParticleEmitter") then
v81.Enabled = false;
v81:Clear();
end;
end;
for _, v83 in l_AnimalModel_2:GetDescendants() do
if v83:IsA("ParticleEmitter") then
task.delay(v83:GetAttribute("EmitDelay") or 0, function() --[[ Line: 293 ]]
-- upvalues: v83 (copy)
v83:Emit(v83:GetAttribute("EmitCount"));
end);
end;
end;
task.delay(2, function() --[[ Line: 299 ]]
-- upvalues: v66 (ref), l_AnimalModel_2 (copy)
v66:Destroy();
l_AnimalModel_2:Destroy();
end);
end;
debug.profileend();
return;
end;
end);
return;
end;
end));
end;
v6.OnStop = function(_) --[[ Line: 310 ]] --[[ Name: OnStop ]]
-- upvalues: v20 (copy)
v20:Destroy();
end;
v6.OnLoad = function(_) --[[ Line: 314 ]] --[[ Name: OnLoad ]]
end;
return v6; - Edit
03:12:20.364
- Edit
03:12:20.364
============================== - Edit
03:12:20.364 📜 ReplicatedStorage.Controllers.EventController.Events.Matteo - Edit
03:12:20.364 ==============================
- Edit
03:12:20.364 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: Matteo, time of decompilation: Sat Jun 28 18:35:09 2025 ]]
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("TweenService");
local l_Players_0 = game:GetService("Players");
local _ = require(l_ReplicatedStorage_0.Shared.EventTypes);
local v4 = {};
local l_Matteo_0 = l_ReplicatedStorage_0.Models.Events.Matteo;
local v6 = require(l_ReplicatedStorage_0.Packages.Net);
local v7 = require(l_ReplicatedStorage_0.Packages.Trove);
local _ = require(l_ReplicatedStorage_0.Packages.Shake);
local v9 = require(l_ReplicatedStorage_0.Shared.TweenPivot);
local v10 = require(l_ReplicatedStorage_0.Shared.ShakePresets);
local v11 = require(l_ReplicatedStorage_0.Packages.Synchronizer);
local v12 = require(l_ReplicatedStorage_0.Controllers.SoundController);
local v13 = require(l_ReplicatedStorage_0.Controllers.EventController);
local l_Name_0 = script.Name;
local v15 = v7.new();
local _ = workspace.CurrentCamera;
v4.OnStart = function(_) --[[ Line: 25 ]] --[[ Name: OnStart ]]
-- upvalues: v13 (copy), l_Name_0 (copy), l_ReplicatedStorage_0 (copy), v12 (copy), v15 (copy), v10 (copy), v11 (copy), l_Matteo_0 (copy), v9 (copy), l_Players_0 (copy), v6 (copy)
local l_v13_ActiveEventData_0 = v13:GetActiveEventData(l_Name_0);
assert(l_v13_ActiveEventData_0);
local l_workspace_ServerTimeNow_0 = workspace:GetServerTimeNow();
l_ReplicatedStorage_0:SetAttribute("MatteoEvent", true);
v12:UpdateOST();
v15:Add(function() --[[ Line: 33 ]]
-- upvalues: l_ReplicatedStorage_0 (ref), v12 (ref)
l_ReplicatedStorage_0:SetAttribute("MatteoEvent", nil);
v12:UpdateOST();
end);
local v20 = false;
v15:Add(function() --[[ Line: 39 ]]
-- upvalues: v20 (ref)
v20 = true;
end);
-- print(l_v13_ActiveEventData_0)
local v21 = l_v13_ActiveEventData_0.startedAt + 10 - l_workspace_ServerTimeNow_0;
v15:Add(task.delay(v21, function() --[[ Line: 44 ]]
-- upvalues: l_v13_ActiveEventData_0 (copy), l_workspace_ServerTimeNow_0 (copy), v10 (ref), v15 (ref), v11 (ref), l_Matteo_0 (ref), v20 (ref), v9 (ref), l_Players_0 (ref), v6 (ref)
local v22 = l_v13_ActiveEventData_0.startedAt + 14 - l_workspace_ServerTimeNow_0;
if v22 > 0 then
local v23 = v10.Bump:Clone();
v15:Add(v23);
v23.Sustain = true;
v15:Add(v10.BindShakeToCamera(v23, workspace.CurrentCamera));
v23:Start();
local l_v23_0 = v23 --[[ copy: 1 -> 27 ]];
v15:Add(task.delay(v22, function() --[[ Line: 53 ]]
-- upvalues: l_v23_0 (copy)
l_v23_0:StopSustain();
end));
v15:Add(function() --[[ Line: 57 ]]
-- upvalues: v10 (ref)
local v25 = v10.Bump:Clone();
v25.Sustain = true;
local v26 = v10.BindShakeToCamera(v25, workspace.CurrentCamera);
v25:Start();
task.wait(4);
v25:StopSustain();
task.wait(2);
v25:Destroy();
v26();
end);
end;
local v27 = v11:Wait("MatteoEvent");
local v28 = v27:Get("IsRainbow");
local v29 = l_v13_ActiveEventData_0.startedAt + 15 - l_workspace_ServerTimeNow_0;
local v30 = if v28 then {
l_Matteo_0.RainbowTrees.Tree1,
l_Matteo_0.RainbowTrees.Tree2,
l_Matteo_0.RainbowTrees.Tree3,
l_Matteo_0.RainbowTrees.Tree4,
l_Matteo_0.RainbowTrees.Tree5
} else {
l_Matteo_0.NormalTrees.Tree1,
l_Matteo_0.NormalTrees.Tree2,
l_Matteo_0.NormalTrees.Tree3,
l_Matteo_0.NormalTrees.Tree4,
l_Matteo_0.NormalTrees.Tree5
};
local v31 = {};
local v32 = {};
local v33 = script.WindParts:Clone();
v33.Parent = workspace;
v15:Add(function() --[[ Line: 87 ]]
-- upvalues: v33 (copy)
for _, v35 in v33:GetDescendants() do
if v35:IsA("ParticleEmitter") then
v35.Enabled = false;
end;
end;
task.wait(5);
v33:Destroy();
end);
for v36, v37 in v27:Get("TreePositions") do
local v38 = Random.new(v37.X * 100 // 1 + v37.Z * 100 // 1);
local v39 = v38:NextInteger(1, #v30);
local v40 = v38:NextNumber(0, 6.283185307179586);
local v41 = v15:Extend();
v31[v36] = v41;
local v42 = v30[v39]:Clone();
local l_v42_ExtentsSize_0 = v42:GetExtentsSize();
local v44 = CFrame.new(v37) * CFrame.new(0, -l_v42_ExtentsSize_0.Y * 0.5, 0) * CFrame.Angles(0, v40, 0);
local v45 = CFrame.new(v37) * CFrame.new(0, l_v42_ExtentsSize_0.Y * 0.485, 0) * CFrame.Angles(0, v40, 0);
local v46 = v41:Clone(l_Matteo_0.SpawnVFX);
v46.CFrame = CFrame.new(v37) * CFrame.Angles(0, v40, 0);
v46.Parent = workspace;
v41:Add(function() --[[ Line: 120 ]]
-- upvalues: v20 (ref), v9 (ref), v42 (copy), v44 (copy)
task.wait();
if v20 then
local v47 = v9(v42, TweenInfo.new(5, Enum.EasingStyle.Quad, Enum.EasingDirection.In), v44 * CFrame.new(0, -1, 0));
v47:Play();
v47.Completed:Wait();
v42:Destroy();
return;
else
v42:Destroy();
return;
end;
end);
if v29 <= 1 then
v42:PivotTo(v45);
v46:Destroy();
else
v42:PivotTo(v44);
v41:Add(v9(v42, TweenInfo.new(v29, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), v45)):Play();
v41:Add(task.delay(v29 - 1, function() --[[ Line: 140 ]]
-- upvalues: v46 (copy), v41 (copy)
v46.ParticleEmitter.Enabled = false;
task.wait(1);
v41:Remove(v46);
end));
end;
if v28 then
for _, v49 in v42:GetChildren() do
if v49.Name ~= "Handle" then
v49:AddTag("RainbowModel");
end;
end;
end;
v42.Parent = workspace;
local l_Character_0 = l_Players_0.LocalPlayer.Character;
if (v39 == 1 or v39 == 2 or v39 == 3) and (not l_Character_0 or not l_Character_0:GetAttribute("Matteo_CollectedTree")) then
local v51 = v41:Clone(l_Matteo_0.ProximityPart);
table.insert(v32, v51);
v51.ProximityPrompt.Enabled = false;
v41:Add(task.delay(v29 - 1, function() --[[ Line: 165 ]]
-- upvalues: v51 (copy)
v51.ProximityPrompt.Enabled = true;
end));
v51:PivotTo(CFrame.new(v37) * CFrame.new(0, 3, 0));
v51.Parent = workspace;
v41:Add(v51.ProximityPrompt.Triggered:Connect(function() --[[ Line: 172 ]]
-- upvalues: v6 (ref), v36 (copy), v32 (copy)
if not v6:Invoke("EventService/Matteo/CollectTree", v36) then
return;
else
for _, v53 in v32 do
v53:Destroy();
end;
table.clear(v32);
return;
end;
end));
end;
end;
v27:OnDictionaryRemoved("TreePositions", function(_, v55) --[[ Line: 187 ]]
-- upvalues: v31 (copy)
local v56 = v31[v55];
if v56 then
v56:Destroy();
v31[v55] = nil;
end;
end);
end));
end;
v4.OnStop = function(_) --[[ Line: 197 ]] --[[ Name: OnStop ]]
-- upvalues: v15 (copy)
v15:Destroy();
end;
v4.OnLoad = function(_) --[[ Line: 201 ]] --[[ Name: OnLoad ]]
-- upvalues: v6 (copy)
v6:RemoteEvent("EventService/Matteo/SpawnEffect").OnClientEvent:Connect(function(v59) --[[ Line: 202 ]]
local v60 = script.MatteoSpawningVFX:Clone();
for _, v62 in v60:GetDescendants() do
if v62:IsA("ParticleEmitter") or v62:IsA("Beam") then
v62.Enabled = true;
end;
end;
v60.Parent = workspace;
task.wait(v59 + 5 - workspace:GetServerTimeNow());
local v63 = script.MatteoSpawnVFX:Clone();
v63.Parent = workspace;
for _, v65 in v63:GetDescendants() do
if v65:IsA("ParticleEmitter") then
task.delay(v65:GetAttribute("EmitDelay") or 0, function() --[[ Line: 218 ]]
-- upvalues: v65 (copy)
v65:Emit(v65:GetAttribute("EmitCount"));
end);
end;
end;
for _, v67 in v60:GetDescendants() do
if v67:IsA("ParticleEmitter") or v67:IsA("Beam") then
v67.Enabled = false;
end;
end;
task.wait(3);
v63:Destroy();
v60:Destroy();
end);
end;
return v4; - Edit
03:12:20.364
- Edit
03:12:20.364
============================== - Edit
03:12:20.365 📜 ReplicatedStorage.Controllers.EventController.Events.Nyan Cats - Edit
03:12:20.365 ==============================
- Edit
03:12:20.365 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: Nyan Cats, time of decompilation: Sat Jun 28 18:35:10 2025 ]]
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("TweenService");
local l_RunService_0 = game:GetService("RunService");
local _ = game:GetService("Players");
local _ = game:GetService("Debris");
local _ = require(l_ReplicatedStorage_0.Shared.EventTypes);
local v6 = {};
local v7 = require(l_ReplicatedStorage_0.Controllers.AnimalController);
local v8 = require(l_ReplicatedStorage_0.Controllers.EffectController);
local v9 = require(l_ReplicatedStorage_0.Controllers.SoundController);
local v10 = require(l_ReplicatedStorage_0.Controllers.EventController);
local v11 = require(l_ReplicatedStorage_0.Controllers.CycleController);
local _ = require(l_ReplicatedStorage_0.Packages.Synchronizer);
local v13 = require(l_ReplicatedStorage_0.Shared.ShakePresets);
local _ = require(l_ReplicatedStorage_0.Packages.Observers);
local _ = require(l_ReplicatedStorage_0.Shared.TweenPivot);
local v16 = require(l_ReplicatedStorage_0.Packages.Trove);
local _ = require(l_ReplicatedStorage_0.Packages.Shake);
local v18 = require(l_ReplicatedStorage_0.Packages.Net);
local v19 = v18:RemoteEvent("EventService/NyanCats/Struck");
local l_Name_0 = script.Name;
local v21 = v16.new();
local l_CurrentCamera_0 = workspace.CurrentCamera;
@native
local function _(v23, v24, v25, v26) --[[ Line: 31 ]] --[[ Name: quadBezier ]]
return (1 - v23) ^ 2 * v24 + (1 - v23) * 2 * v23 * v25 + v23 ^ 2 * v26;
end;
v6.OnStart = function(_) --[[ Line: 35 ]] --[[ Name: OnStart ]]
-- upvalues: v10 (copy), l_Name_0 (copy), l_ReplicatedStorage_0 (copy), v21 (copy), v8 (copy), v9 (copy), v11 (copy), l_RunService_0 (copy), v19 (copy), v7 (copy), l_CurrentCamera_0 (copy), v13 (copy)
local l_v10_ActiveEventData_0 = v10:GetActiveEventData(l_Name_0);
assert(l_v10_ActiveEventData_0);
l_ReplicatedStorage_0:SetAttribute("NyanCatsEvent", true);
v21:Add(function() --[[ Line: 40 ]]
-- upvalues: l_ReplicatedStorage_0 (ref)
l_ReplicatedStorage_0:SetAttribute("NyanCatsEvent", nil);
end);
v8:Run(l_Name_0, "Space");
v8:Activate("Blink");
v21:Add(function() --[[ Line: 47 ]]
-- upvalues: v8 (ref)
v8:Activate("Blink");
end);
v9:UpdateOST();
v11:Update();
v21:Add(function() --[[ Line: 54 ]]
-- upvalues: v8 (ref), l_Name_0 (ref)
v8:Stop(l_Name_0, "Space");
end);
local l_Position_0 = workspace.MapCenter.CFrame.Position;
local function v39(v31, v32, v33) --[[ Line: 65 ]] --[[ Name: getCatPosition ]]
-- upvalues: l_Position_0 (copy)
local v34 = math.ceil(v31 / 10);
local v35 = (v31 % 10 + 1) / 10;
local v36 = (v32 or 0) + v34 + v35 * 3.141592653589793 * 2;
local v37 = l_Position_0 + vector.create(0, v34 * 15 + 35, 0);
local v38 = vector.create(math.cos(v36) * 270 * 0.5, v33 or math.sin(os.clock() * 6) * 1.5, math.sin(v36) * 420 * 0.5);
return CFrame.lookAt(v37 + v38, v37);
end;
local v40 = table.create(30);
for v41 = 1, 30 do
local v42 = v21:Clone(script.NyanCat);
v42.Parent = workspace;
local v43 = v42.AnimationController.Animator:LoadAnimation(script.Animation);
v43.Looped = true;
v43:Play();
v21:Add(function() --[[ Line: 91 ]]
-- upvalues: v43 (copy)
v43:Stop(0);
v43:Destroy();
end);
v40[v41] = {
model = v42,
scale = v42:GetScale(),
rootPart = v42.RootPart,
state = {
type = "hovering"
},
visualState = {
cframe = v39(v41)
}
};
end;
local v44 = table.create(30);
local v45 = table.create(30);
v21:Add(l_RunService_0.PostSimulation:Connect(function(v46) --[[ Line: 118 ]]
-- upvalues: l_v10_ActiveEventData_0 (copy), v40 (copy), v39 (copy), v44 (copy), v45 (copy)
debug.profilebegin("Nyan Cats");
local l_workspace_ServerTimeNow_0 = workspace:GetServerTimeNow();
local v48 = math.rad((l_workspace_ServerTimeNow_0 - l_v10_ActiveEventData_0.startedAt) * 10);
local v49 = math.sin(l_workspace_ServerTimeNow_0 * 6) * 1.5;
for v50, v51 in v40 do
local v52 = nil;
if v51.state.type == "hovering" then
v51.visualState.startCFrame = nil;
v52 = v39(v50, v48, v49);
elseif v51.state.type == "follow" or v51.state.type == "restore" then
local v53 = v51.state.type == "restore";
if v51.visualState.lastState ~= v51.state.type then
v51.visualState.timer = 0;
v51.visualState.startCFrame = v51.visualState.cframe;
v51.visualState.lastState = v51.state.type;
v51.visualState.p1 = v51.visualState.cframe * if v53 then CFrame.new(0, 100, 0) else CFrame.new(0, 40, -100);
end;
local l_visualState_0 = v51.visualState;
l_visualState_0.timer = l_visualState_0.timer + v46;
l_visualState_0 = v51.state.lerpTime or 3;
local v55 = if v53 then v39(v50, v48, v49).Position else v51.state.value;
local v56 = math.clamp(v51.visualState.timer / l_visualState_0, 0, 1);
local l_Position_1 = v51.visualState.startCFrame.Position;
local l_Position_2 = v51.visualState.p1.Position;
local v59 = (1 - v56) ^ 2 * l_Position_1 + (1 - v56) * 2 * v56 * l_Position_2 + v56 ^ 2 * v55;
v52 = CFrame.lookAt(v59, v55 + Vector3.new(9.999999974752427E-7, 9.999999974752427E-7, 9.999999974752427E-7, 0)) * CFrame.Angles(0, -1.5707963267948966 * math.clamp(v51.visualState.timer / (l_visualState_0 * 0.5), 0, 1), 0);
l_Position_1 = if v53 then math.lerp(0.5, v51.scale, v56) else math.lerp(v51.scale, 0.5, v56);
v51.model:ScaleTo(l_Position_1);
if v53 and v56 >= 1 then
v51.state = {
type = "hovering"
};
end;
end;
v51.visualState.cframe = v52;
v44[v50] = v51.rootPart;
v45[v50] = v52;
end;
workspace:BulkMoveTo(v44, v45, Enum.BulkMoveMode.FireCFrameChanged);
debug.profileend();
end));
v21:Add(v19.OnClientEvent:Connect(function(v60, v61, v62) --[[ Line: 178 ]]
-- upvalues: v7 (ref), l_RunService_0 (ref), v40 (copy), v9 (ref), l_ReplicatedStorage_0 (ref), l_CurrentCamera_0 (ref), v13 (ref), v21 (ref)
local v63 = v7:GetAnimals()[v61];
if not v63 then
return;
else
local _ = function() --[[ Line: 184 ]] --[[ Name: getTargetPosition ]]
-- upvalues: v63 (copy)
local _ = nil;
local l_AnimalModel_0 = v63.AnimalModel;
return (if l_AnimalModel_0.PrimaryPart then l_AnimalModel_0.PrimaryPart.CFrame else l_AnimalModel_0:GetPivot()).Position + Vector3.new(0, v63.AnimalModel:GetExtentsSize().Y * 0.5, 0);
end;
local v67 = v62 + 3 - workspace:GetServerTimeNow();
local v72 = l_RunService_0.PreRender:Connect(function() --[[ Line: 199 ]]
-- upvalues: v40 (ref), v60 (copy), v63 (copy), v67 (copy)
debug.profilebegin("Update Nycan Cat Follow Target");
local v68 = v40[v60];
local v69 = {
type = "follow"
};
local _ = nil;
local l_AnimalModel_1 = v63.AnimalModel;
v69.value = (if l_AnimalModel_1.PrimaryPart then l_AnimalModel_1.PrimaryPart.CFrame else l_AnimalModel_1:GetPivot()).Position + Vector3.new(0, v63.AnimalModel:GetExtentsSize().Y * 0.5, 0);
v69.lerpTime = v67;
v68.state = v69;
debug.profileend();
end);
task.wait(v67);
v72:Disconnect();
v40[v60].state = {
type = "restore"
};
local v73 = nil;
local l_AnimalModel_2 = v63.AnimalModel;
local v75 = (if l_AnimalModel_2.PrimaryPart then l_AnimalModel_2.PrimaryPart.CFrame else l_AnimalModel_2:GetPivot()).Position + Vector3.new(0, v63.AnimalModel:GetExtentsSize().Y * 0.5, 0);
task.spawn(function() --[[ Line: 218 ]]
-- upvalues: v9 (ref), l_ReplicatedStorage_0 (ref), v75 (copy)
v9:PlaySound(l_ReplicatedStorage_0.Sounds.Events["Nyan Cats"].Hit, v75);
end);
v73 = script.StruckVFX:Clone();
v73:PivotTo(CFrame.new(v75));
v73.Anchored = false;
l_AnimalModel_2 = Instance.new("WeldConstraint");
l_AnimalModel_2.Part0 = v73;
l_AnimalModel_2.Part1 = v63.AnimalModel.PrimaryPart;
l_AnimalModel_2.Parent = v73;
v73.Parent = workspace;
for _, v77 in v73:GetDescendants() do
if v77:IsA("ParticleEmitter") then
task.delay(v77:GetAttribute("EmitDelay") or 0, function() --[[ Line: 236 ]]
-- upvalues: v77 (copy)
v77:Emit(v77:GetAttribute("EmitCount"));
end);
end;
end;
task.delay(2, function() --[[ Line: 242 ]]
-- upvalues: v73 (copy)
v73:Destroy();
end);
if (l_CurrentCamera_0.CFrame.Position - v75).Magnitude <= 70 then
local v78 = v13.Bump:Clone();
v21:Add(v78);
v78.Sustain = true;
v21:Add(v13.BindShakeToCamera(v78, l_CurrentCamera_0));
v78:Start();
v21:Add(task.delay(0.3, function() --[[ Line: 254 ]]
-- upvalues: v78 (copy)
v78:StopSustain();
end));
end;
return;
end;
end));
end;
v6.OnStop = function(_) --[[ Line: 261 ]] --[[ Name: OnStop ]]
-- upvalues: v21 (copy)
v21:Destroy();
end;
v6.OnLoad = function(_) --[[ Line: 265 ]] --[[ Name: OnLoad ]]
-- upvalues: v18 (copy)
v18:RemoteEvent("EventService/NyanCats/SpawnEffect").OnClientEvent:Connect(function(v81) --[[ Line: 266 ]]
local v82 = script.NyanCatSpawningVFX:Clone();
for _, v84 in v82:GetDescendants() do
if v84:IsA("ParticleEmitter") or v84:IsA("Beam") then
v84.Enabled = true;
end;
end;
v82.Parent = workspace;
task.wait(v81 + 9 - workspace:GetServerTimeNow());
local v85 = script.NyanCatSpawnVFX:Clone();
v85.Parent = workspace;
for _, v87 in v85:GetDescendants() do
if v87:IsA("ParticleEmitter") then
task.delay(v87:GetAttribute("EmitDelay") or 0, function() --[[ Line: 282 ]]
-- upvalues: v87 (copy)
v87:Emit(v87:GetAttribute("EmitCount"));
end);
end;
end;
for _, v89 in v82:GetDescendants() do
if v89:IsA("ParticleEmitter") or v89:IsA("Beam") then
v89.Enabled = false;
end;
end;
task.wait(3);
v85:Destroy();
v82:Destroy();
end);
end;
return v6; - Edit
03:12:20.365
- Edit
03:12:20.365
============================== - Edit
03:12:20.365 📜 ReplicatedStorage.Controllers.EventController.Events.Raining Tacos - Edit
03:12:20.365 ==============================
- Edit
03:12:20.365 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: Raining Tacos, time of decompilation: Sat Jun 28 18:35:10 2025 ]]
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("TweenService");
local l_RunService_0 = game:GetService("RunService");
local _ = game:GetService("Players");
local _ = require(l_ReplicatedStorage_0.Shared.EventTypes);
local v5 = {};
local v6 = require(l_ReplicatedStorage_0.Controllers.AnimalController);
local v7 = require(l_ReplicatedStorage_0.Controllers.SoundController);
local v8 = require(l_ReplicatedStorage_0.Controllers.EventController);
local v9 = require(l_ReplicatedStorage_0.Controllers.CycleController);
local v10 = require(l_ReplicatedStorage_0.Packages.Spring);
local v11 = require(l_ReplicatedStorage_0.Packages.Trove);
local _ = require(l_ReplicatedStorage_0.Packages.Shake);
local v13 = require(l_ReplicatedStorage_0.Packages.Net):RemoteEvent("EventService/RainingTacos/Shoot");
local l_Name_0 = script.Name;
local v15 = v11.new();
local _ = workspace.CurrentCamera;
@native
local function _(v17, v18, v19, v20) --[[ Line: 26 ]] --[[ Name: quadBezier ]]
return (1 - v17) ^ 2 * v18 + (1 - v17) * 2 * v17 * v19 + v17 ^ 2 * v20;
end;
v5.OnStart = function(_) --[[ Line: 30 ]] --[[ Name: OnStart ]]
-- upvalues: v8 (copy), l_Name_0 (copy), l_ReplicatedStorage_0 (copy), v15 (copy), v7 (copy), v9 (copy), v10 (copy), l_RunService_0 (copy), v13 (copy), v6 (copy)
assert((v8:GetActiveEventData(l_Name_0)));
l_ReplicatedStorage_0:SetAttribute("RainingTacosEvent", true);
v15:Add(function() --[[ Line: 35 ]]
-- upvalues: l_ReplicatedStorage_0 (ref), v7 (ref), v9 (ref)
l_ReplicatedStorage_0:SetAttribute("RainingTacosEvent", nil);
v7:UpdateOST();
v9:Update();
end);
v7:UpdateOST();
v9:Update();
local v23 = v15:Clone(script.Cannon);
v23.Parent = workspace;
local v24 = script.TacoAmbient:Clone();
v15:Add(function() --[[ Line: 48 ]]
-- upvalues: v24 (copy)
for _, v26 in v24:GetDescendants() do
if v26:IsA("ParticleEmitter") then
v26.Enabled = false;
end;
end;
task.wait(5);
v24:Destroy();
end);
v24:PivotTo(workspace.MapCenter.CFrame + Vector3.new(0, 40, 0, 0));
v24.Parent = workspace;
local v27 = v23.Top["Meshes/tacolauncher_Cube.004"]["Meshes/tacolauncher_Cube.003"];
local v28 = v23.Bottom.RootPart["Meshes/tacolauncher_Cube.004"];
local v29 = v10.new(0);
v29.Speed = 6.5;
v29.Damper = 0.85;
local v30 = v10.new(0);
v30.Speed = 9;
v30.Damper = 0.6;
v15:Add(l_RunService_0.PostSimulation:Connect(function(_) --[[ Line: 74 ]]
-- upvalues: v27 (copy), v29 (copy), v28 (copy), v30 (copy)
debug.profilebegin("Raining Tacos Cannon Spring");
v27.C1 = CFrame.new(v29.Position, 0, 0);
v28.C1 = CFrame.Angles(0, 0, -math.rad(v30.Position));
debug.profileend();
end));
v15:Add(v13.OnClientEvent:Connect(function(v32, v33) --[[ Line: 81 ]]
-- upvalues: v6 (ref), v7 (ref), l_ReplicatedStorage_0 (ref), v23 (copy), v30 (copy), v29 (copy), l_RunService_0 (ref)
local v34 = v6:GetAnimals()[v32];
if not v34 then
return;
else
local _ = function() --[[ Line: 87 ]] --[[ Name: getTargetPosition ]]
-- upvalues: v34 (copy)
local _ = nil;
local l_AnimalModel_0 = v34.AnimalModel;
return (if l_AnimalModel_0.PrimaryPart then l_AnimalModel_0.PrimaryPart.CFrame else l_AnimalModel_0:GetPivot()).Position + Vector3.new(0, v34.AnimalModel:GetExtentsSize().Y * 0.5, 0);
end;
local v38 = script.Taco:Clone();
v38.Parent = workspace;
task.spawn(function() --[[ Line: 103 ]]
-- upvalues: v7 (ref), l_ReplicatedStorage_0 (ref), v23 (ref)
v7:PlaySound(l_ReplicatedStorage_0.Sounds.Events["Raining Tacos"].Shoot, v23:GetPivot().Position);
end);
task.spawn(function() --[[ Line: 107 ]]
-- upvalues: v30 (ref), v29 (ref)
v30:Impulse(650);
task.wait(0.05);
v29:Impulse(35);
end);
local l_Position_0 = v23.ShootPart.CFrame.Position;
local v40 = nil;
v40 = l_RunService_0.PreRender:Connect(function() --[[ Line: 116 ]]
-- upvalues: v34 (copy), l_Position_0 (copy), v33 (copy), v38 (copy), v40 (ref), v7 (ref), l_ReplicatedStorage_0 (ref)
debug.profilebegin("Raining Tacos");
local v41 = nil;
local l_AnimalModel_1 = v34.AnimalModel;
local v43 = (if l_AnimalModel_1.PrimaryPart then l_AnimalModel_1.PrimaryPart.CFrame else l_AnimalModel_1:GetPivot()).Position + Vector3.new(0, v34.AnimalModel:GetExtentsSize().Y * 0.5, 0);
v41 = l_Position_0 + (v43 - l_Position_0) * 0.5 + Vector3.new(0, 60, 0, 0);
l_AnimalModel_1 = 1 - (v33 + 2.5 - workspace:GetServerTimeNow()) / 2.5;
local v44 = math.clamp(l_AnimalModel_1, 0, 1);
local l_l_Position_0_0 = l_Position_0;
local v46 = (1 - v44) ^ 2 * l_l_Position_0_0 + (1 - v44) * 2 * v44 * v41 + v44 ^ 2 * v43;
l_l_Position_0_0 = math.clamp(l_AnimalModel_1, 0, 1) + 0.1;
local l_l_Position_0_1 = l_Position_0;
v44 = (1 - l_l_Position_0_0) ^ 2 * l_l_Position_0_1 + (1 - l_l_Position_0_0) * 2 * l_l_Position_0_0 * v41 + l_l_Position_0_0 ^ 2 * v43;
v38.CFrame = CFrame.lookAt(v46, v44);
if l_AnimalModel_1 >= 1 then
v40:Disconnect();
task.spawn(function() --[[ Line: 132 ]]
-- upvalues: v7 (ref), l_ReplicatedStorage_0 (ref), v43 (copy)
v7:PlaySound(l_ReplicatedStorage_0.Sounds.Events["Raining Tacos"].Hit, v43);
end);
v38:Destroy();
l_l_Position_0_0 = script.StruckVFX:Clone();
l_l_Position_0_0:PivotTo(CFrame.new(v43));
l_l_Position_0_0.Anchored = false;
l_l_Position_0_1 = Instance.new("WeldConstraint");
l_l_Position_0_1.Part0 = l_l_Position_0_0;
l_l_Position_0_1.Part1 = v34.AnimalModel.PrimaryPart;
l_l_Position_0_1.Parent = l_l_Position_0_0;
l_l_Position_0_0.Parent = workspace;
for _, v49 in l_l_Position_0_0:GetDescendants() do
if v49:IsA("ParticleEmitter") then
task.delay(v49:GetAttribute("EmitDelay") or 0, function() --[[ Line: 152 ]]
-- upvalues: v49 (copy)
v49:Emit(v49:GetAttribute("EmitCount"));
end);
end;
end;
task.delay(2, function() --[[ Line: 158 ]]
-- upvalues: l_l_Position_0_0 (copy)
l_l_Position_0_0:Destroy();
end);
end;
debug.profileend();
end);
return;
end;
end));
end;
v5.OnStop = function(_) --[[ Line: 168 ]] --[[ Name: OnStop ]]
-- upvalues: v15 (copy)
v15:Destroy();
end;
v5.OnLoad = function(_) --[[ Line: 172 ]] --[[ Name: OnLoad ]]
end;
return v5; - Edit
03:12:20.365
- Edit
03:12:20.365
============================== - Edit
03:12:20.365 📜 ReplicatedStorage.Controllers.EventController.Events.Tung Tung Attack - Edit
03:12:20.365 ==============================
- Edit
03:12:20.366 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: Tung Tung Attack, time of decompilation: Sat Jul 5 18:09:18 2025 ]]
local _ = game:GetService("PathfindingService");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("TweenService");
local _ = game:GetService("RunService");
local _ = game:GetService("Lighting");
local _ = game:GetService("Players");
local _ = require(l_ReplicatedStorage_0.Shared.EventTypes);
local v7 = {};
local v8 = require(l_ReplicatedStorage_0.Controllers.AnimalController);
local v9 = require(l_ReplicatedStorage_0.Controllers.SoundController);
local v10 = require(l_ReplicatedStorage_0.Controllers.EventController);
local v11 = require(l_ReplicatedStorage_0.Controllers.CycleController);
local _ = require(l_ReplicatedStorage_0.Packages.Synchronizer);
local v13 = require(l_ReplicatedStorage_0.Shared.ShakePresets);
local v14 = require(l_ReplicatedStorage_0.Shared.TweenPivot);
local v15 = require(l_ReplicatedStorage_0.Packages.Observers);
local v16 = require(l_ReplicatedStorage_0.Packages.Trove);
local v17 = require(l_ReplicatedStorage_0.Packages.Net);
local l_Name_0 = script.Name;
local v19 = v17:RemoteEvent("EventService/Tung Tung Attack/Hit");
local v20 = v16.new();
local v21 = {};
v7.OnStart = function(_) --[[ Line: 36 ]] --[[ Name: OnStart ]]
-- upvalues: v10 (copy), l_Name_0 (copy), v11 (copy), v9 (copy), v20 (copy), v14 (copy), v15 (copy), v21 (copy), v13 (copy)
local l_v10_ActiveEventData_0 = v10:GetActiveEventData(l_Name_0);
assert(l_v10_ActiveEventData_0);
local l_workspace_ServerTimeNow_0 = workspace:GetServerTimeNow();
v11:Update();
v9:UpdateOST();
local v25 = script["Tung Tung Tung Sahur"]:Clone();
local l_v25_Pivot_0 = v25:GetPivot();
v25:PivotTo(l_v25_Pivot_0 - Vector3.new(0, 40, 0, 0));
v25.Parent = workspace;
local v27 = script.VFX:Clone();
v27.Parent = workspace;
local v28 = v25.AnimationController.Animator:LoadAnimation(script.GiantTungTung);
v28.Looped = false;
v28.Priority = Enum.AnimationPriority.Action4;
v28:Play(0);
local v29 = v25.AnimationController.Animator:LoadAnimation(script.GiantTungTungIdle);
v29.Looped = true;
v29.Priority = Enum.AnimationPriority.Idle;
v29:Play(0);
v20:Add(task.spawn(function() --[[ Line: 64 ]]
-- upvalues: v28 (copy), v9 (ref), v20 (ref), v14 (ref), v25 (copy), l_v25_Pivot_0 (copy)
while v28.Length == 0 do
task.wait();
end;
v9:PlaySound("Sounds.Events.Tung Tung Attack.BigTungTungSpawn");
v28:Stop(0);
v28.TimePosition = 0;
v28:Play(0);
v20:Add(v14(v25, TweenInfo.new(3, Enum.EasingStyle.Sine, Enum.EasingDirection.Out), l_v25_Pivot_0)):Play();
end));
v20:Add(function() --[[ Line: 78 ]]
-- upvalues: v14 (ref), v25 (copy), l_v25_Pivot_0 (copy), v27 (copy), v29 (copy), v28 (copy)
v14(v25, TweenInfo.new(3, Enum.EasingStyle.Quint, Enum.EasingDirection.Out), l_v25_Pivot_0 - Vector3.new(0, 40, 0, 0)):Play();
for _, v31 in v27:GetDescendants() do
if v31:IsA("ParticleEmitter") then
v31.Enabled = false;
end;
end;
task.wait(5);
v25:Destroy();
v29:Stop(0);
v29:Destroy();
v28:Stop(0);
v28:Destroy();
end);
local v32 = Random.new();
v20:Add(v15.observeTag("BabyTungTung", function(v33) --[[ Line: 99 ]]
-- upvalues: v21 (ref), v32 (copy)
local v34 = true;
local v36 = task.spawn(function() --[[ Line: 101 ]]
-- upvalues: v34 (ref), v21 (ref), v32 (ref), v33 (copy)
local v36 = task.spawn(function()
while v34 do
task.wait(v32:NextNumber(2, 4))
end
end)
end);
return function() --[[ Line: 116 ]]
-- upvalues: v34 (ref), v36 (copy)
v34 = false;
pcall(task.cancel, v36);
end;
end));
local v37 = l_v10_ActiveEventData_0.startedAt + 10 - l_workspace_ServerTimeNow_0;
local v38 = script.Caves:Clone();
local v39 = script.Caves2:Clone();
for _, v41 in {
v38["1"],
v38["2"],
v38["3"],
v39["4"],
v39["5"],
v39["6"]
} do
v9:PlaySound("Sounds.Events.Tung Tung Attack.Cave", v41:GetPivot().Position);
end;
v38.Parent = workspace;
v39.Parent = workspace;
v20:Add(v14(v38, TweenInfo.new(v37, Enum.EasingStyle.Quint, Enum.EasingDirection.Out), v38:GetPivot() * CFrame.new(0, 0, 6))):Play();
v20:Add(v14(v39, TweenInfo.new(v37, Enum.EasingStyle.Quint, Enum.EasingDirection.Out), v39:GetPivot() * CFrame.new(0, 0, 6))):Play();
local v42 = v13.BumpS:Clone();
v20:Add(v42);
v42.Sustain = true;
v20:Add(v13.BindShakeToCamera(v42, workspace.CurrentCamera));
v42:Start();
v20:Add(task.delay(v37, function() --[[ Line: 152 ]]
-- upvalues: v42 (copy), v27 (copy)
v42:StopSustain();
for _, v44 in v27.Cave:GetDescendants() do
if v44:IsA("ParticleEmitter") then
v44.Enabled = true;
end;
end;
end));
end;
v7.OnStop = function(_) --[[ Line: 163 ]] --[[ Name: OnStop ]]
-- upvalues: v20 (copy)
v20:Destroy();
end;
v7.OnLoad = function(_) --[[ Line: 167 ]] --[[ Name: OnLoad ]]
-- upvalues: v19 (copy), v8 (copy)
v19.OnClientEvent:Connect(function(v47) --[[ Line: 168 ]]
-- upvalues: v8 (ref)
local v48 = nil;
local v49 = nil;
if type(v47) == "string" then
local v50 = v8:GetAnimals()[v47];
if not v50 then
return;
else
local l_v50_0 = v50 --[[ copy: 3 -> 10 ]];
local _ = function() --[[ Line: 177 ]] --[[ Name: getTargetPosition ]]
-- upvalues: l_v50_0 (copy)
local _ = nil;
local l_AnimalModel_0 = l_v50_0.AnimalModel;
return (if l_AnimalModel_0.PrimaryPart then l_AnimalModel_0.PrimaryPart.CFrame else l_AnimalModel_0:GetPivot()).Position + Vector3.new(0, l_v50_0.AnimalModel:GetExtentsSize().Y * 0.5, 0);
end;
local _ = nil;
local l_AnimalModel_1 = v50.AnimalModel;
v48 = (if l_AnimalModel_1.PrimaryPart then l_AnimalModel_1.PrimaryPart.CFrame else l_AnimalModel_1:GetPivot()).Position + Vector3.new(0, v50.AnimalModel:GetExtentsSize().Y * 0.5, 0);
v49 = v50.AnimalModel.PrimaryPart;
end;
else
v48 = v47:GetPivot().Position;
v49 = v47;
end;
local v57 = script.TungTungHit:Clone();
v57:PivotTo(CFrame.new(v48));
v57.Anchored = false;
local l_WeldConstraint_0 = Instance.new("WeldConstraint");
l_WeldConstraint_0.Part0 = v57;
l_WeldConstraint_0.Part1 = v49;
l_WeldConstraint_0.Parent = v57;
v57.Parent = workspace;
for _, v60 in v57:GetDescendants() do
if v60:IsA("ParticleEmitter") then
task.delay(v60:GetAttribute("EmitDelay") or 0, function() --[[ Line: 210 ]]
-- upvalues: v60 (copy)
v60:Emit(v60:GetAttribute("EmitCount"));
end);
end;
end;
end);
end;
return v7; - Edit
03:12:20.366
- Edit
03:12:20.366
============================== - Edit
03:12:20.366 📜 ReplicatedStorage.Controllers.EventController.Events.Phase 4: Mygame43 - Edit
03:12:20.366 ==============================
- Edit
03:12:20.366 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- Decompiler will be improved VERY SOON!
-- Decompiled with Konstant V2.1, a fast Luau decompiler made in Luau by plusgiant5 (https://discord.gg/brNTY8nX8t)
-- Decompiled on 2025-08-30 12:48:36
-- Luau version 6, Types version 3
-- Time taken: 0.007677 seconds
local ReplicatedStorage_upvr = game:GetService("ReplicatedStorage")
local module = {}
local Name_upvr = script.Name
local RaycastParams_new_result1 = RaycastParams.new()
RaycastParams_new_result1.FilterDescendantsInstances = {workspace.Events["Los Matteos"].Areas}
RaycastParams_new_result1.FilterType = Enum.RaycastFilterType.Include
local CurrentCamera_upvr = workspace.CurrentCamera
local any_new_result1_upvr_2 = require(ReplicatedStorage_upvr.Packages.Trove).new()
local any_new_result1_upvr = require(ReplicatedStorage_upvr.Packages.Shake).new()
any_new_result1_upvr.Amplitude = 5.5
any_new_result1_upvr.Frequency = 0.05
any_new_result1_upvr.FadeInTime = 0
any_new_result1_upvr.FadeOutTime = 0.6
any_new_result1_upvr.PositionInfluence = Vector3.new(0.5, 0.5, 0.5)
any_new_result1_upvr.RotationInfluence = Vector3.new(2.5, 0.5, 0.5)
local ShakePresets_upvr = require(ReplicatedStorage_upvr.Shared.ShakePresets)
local function shakeCameraBasedOnProximity_upvr(arg1) -- Line 58, Named "shakeCameraBasedOnProximity"
--[[ Upvalues[4]:
[1]: CurrentCamera_upvr (readonly)
[2]: any_new_result1_upvr (readonly)
[3]: any_new_result1_upvr_2 (readonly)
[4]: ShakePresets_upvr (readonly)
]]
local Magnitude = (CurrentCamera_upvr.CFrame.Position - arg1).Magnitude
if Magnitude <= 300 then
local clone = any_new_result1_upvr:Clone()
local var12 = (1 - Magnitude / 300 * 0.5) ^ 2
clone.Amplitude *= var12
clone.RotationInfluence *= var12
any_new_result1_upvr_2:Add(ShakePresets_upvr.BindShakeToCamera(clone))
clone:Start()
end
end
local EventController_upvr = require(ReplicatedStorage_upvr.Controllers.EventController)
local EffectController_upvr = require(ReplicatedStorage_upvr.Controllers.EffectController)
local Observers_upvr = require(ReplicatedStorage_upvr.Packages.Observers)
local Spr_upvr = require(ReplicatedStorage_upvr.Packages.Spr)
local RunService_upvr = game:GetService("RunService")
local VFX_upvr = require(ReplicatedStorage_upvr.Shared.VFX)
local SkullEmojiEffectController_upvr = require(ReplicatedStorage_upvr.Controllers.SkullEmojiEffectController)
local any_RemoteEvent_result1_upvr = require(ReplicatedStorage_upvr.Packages.Net):RemoteEvent(`EventService/{Name_upvr}/CreateLightningOrb`)
local TweenService_upvr = game:GetService("TweenService")
local SharedEventUtils_upvr = require(ReplicatedStorage_upvr.Shared.SharedEventUtils)
local MathUtils_upvr = require(ReplicatedStorage_upvr.Utils.MathUtils)
local SoundController_upvr = require(ReplicatedStorage_upvr.Controllers.SoundController)
function module.OnStart(arg1) -- Line 76
--[[ Upvalues[17]:
[1]: EventController_upvr (readonly)
[2]: Name_upvr (readonly)
[3]: any_new_result1_upvr_2 (readonly)
[4]: EffectController_upvr (readonly)
[5]: ReplicatedStorage_upvr (readonly)
[6]: Observers_upvr (readonly)
[7]: Spr_upvr (readonly)
[8]: RunService_upvr (readonly)
[9]: VFX_upvr (readonly)
[10]: CurrentCamera_upvr (readonly)
[11]: SkullEmojiEffectController_upvr (readonly)
[12]: any_RemoteEvent_result1_upvr (readonly)
[13]: TweenService_upvr (readonly)
[14]: SharedEventUtils_upvr (readonly)
[15]: MathUtils_upvr (readonly)
[16]: shakeCameraBasedOnProximity_upvr (readonly)
[17]: SoundController_upvr (readonly)
]]
local any_GetActiveEventData_result1_upvr = EventController_upvr:GetActiveEventData(Name_upvr)
assert(any_GetActiveEventData_result1_upvr)
local function _(arg1_2) -- Line 80, Named "calculateTimeLeftFor"
--[[ Upvalues[1]:
[1]: any_GetActiveEventData_result1_upvr (readonly)
]]
return any_GetActiveEventData_result1_upvr.startedAt + arg1_2 - workspace:GetServerTimeNow()
end
any_new_result1_upvr_2:Add(function() -- Line 84
--[[ Upvalues[1]:
[1]: EffectController_upvr (copied, readonly)
]]
EffectController_upvr:Activate("Blink")
end)
local var27_upvw
local function _(arg1_3) -- Line 91, Named "getOrbPosition"
--[[ Upvalues[1]:
[1]: var27_upvw (read and write)
]]
-- KONSTANTWARNING: Variable analysis failed. Output will have some incorrect variable assignments
local var28 = true
if arg1_3 ~= 2 then
if arg1_3 ~= 3 then
var28 = false
else
var28 = true
end
end
if var28 then
else
end
local cframe = CFrame.new((arg1_3 - 1) * 30 + -45, 50, 15)
if var27_upvw then
return var27_upvw.HumanoidRootPart.CFrame * cframe
end
return cframe
end
ReplicatedStorage_upvr.Sounds.Events["Phase 4: Mygame43"].Appear:Play()
any_new_result1_upvr_2:Add(Observers_upvr.observeTag("Mygame43", function(arg1_4) -- Line 106
--[[ Upvalues[8]:
[1]: var27_upvw (read and write)
[2]: any_GetActiveEventData_result1_upvr (readonly)
[3]: any_new_result1_upvr_2 (copied, readonly)
[4]: Spr_upvr (copied, readonly)
[5]: RunService_upvr (copied, readonly)
[6]: VFX_upvr (copied, readonly)
[7]: CurrentCamera_upvr (copied, readonly)
[8]: SkullEmojiEffectController_upvr (copied, readonly)
]]
var27_upvw = arg1_4
assert(var27_upvw)
local any_LoadAnimation_result1 = var27_upvw.Humanoid.Animator:LoadAnimation(script.Spawn)
var27_upvw.Humanoid.Animator:LoadAnimation(script.Idle):Play()
any_LoadAnimation_result1:Play()
any_LoadAnimation_result1.TimePosition = (7) - (any_GetActiveEventData_result1_upvr.startedAt + 7 - workspace:GetServerTimeNow())
any_new_result1_upvr_2:Add(task.delay(any_GetActiveEventData_result1_upvr.startedAt + 7.7 - workspace:GetServerTimeNow(), function() -- Line 118
--[[ Upvalues[4]:
[1]: var27_upvw (copied, read and write)
[2]: any_new_result1_upvr_2 (copied, readonly)
[3]: Spr_upvr (copied, readonly)
[4]: RunService_upvr (copied, readonly)
]]
-- KONSTANTWARNING: Variable analysis failed. Output will have some incorrect variable assignments
for i_upvr = 1, 4 do
local var37 = true
if i_upvr ~= 2 then
if i_upvr ~= 3 then
var37 = false
else
var37 = true
end
end
if var37 then
else
end
if var27_upvw then
local _ = var27_upvw.HumanoidRootPart.CFrame * CFrame.new((i_upvr - 1) * 30 + -45, 50, 15)
else
end
local clone_3_upvr = any_new_result1_upvr_2:Clone(script.Orb)
-- KONSTANTERROR: Expression was reused, decompilation is incorrect
clone_3_upvr.CFrame = CFrame.new((i_upvr - 1) * 30 + -45, 50, 15) - Vector3.new(0, 100, 0)
clone_3_upvr.Parent = workspace
any_new_result1_upvr_2:Add(function() -- Line 151
--[[ Upvalues[2]:
[1]: Spr_upvr (copied, readonly)
[2]: clone_3_upvr (readonly)
]]
Spr_upvr.stop(clone_3_upvr)
end)
local cframe_2_upvr = CFrame.new((i_upvr - 1) * 30 + -45, 50, 15)
local any_NextNumber_result1_upvr = Random.new():NextNumber(2, 3)
any_new_result1_upvr_2:Add(RunService_upvr.PostSimulation:Connect(function(arg1_5) -- Line 156
--[[ Upvalues[5]:
[1]: Spr_upvr (copied, readonly)
[2]: clone_3_upvr (readonly)
[3]: cframe_2_upvr (readonly)
[4]: i_upvr (readonly)
[5]: any_NextNumber_result1_upvr (readonly)
]]
Spr_upvr.target(clone_3_upvr, 0.8, 1, {
Pivot = cframe_2_upvr + Vector3.new(0, math.sin((os.clock() + i_upvr * 90) * any_NextNumber_result1_upvr) * 4, 0);
})
end))
end
end))
any_new_result1_upvr_2:Add(task.delay(any_GetActiveEventData_result1_upvr.startedAt + 3.6999999999999997 - workspace:GetServerTimeNow(), function() -- Line 164
--[[ Upvalues[5]:
[1]: VFX_upvr (copied, readonly)
[2]: var27_upvw (copied, read and write)
[3]: RunService_upvr (copied, readonly)
[4]: CurrentCamera_upvr (copied, readonly)
[5]: SkullEmojiEffectController_upvr (copied, readonly)
]]
VFX_upvr.enable(var27_upvw)
task.wait(0.6)
RunService_upvr.PreRender:Connect(function(arg1_6) -- Line 168
--[[ Upvalues[2]:
[1]: CurrentCamera_upvr (copied, readonly)
[2]: var27_upvw (copied, read and write)
]]
local CFrame = CurrentCamera_upvr.CFrame
CurrentCamera_upvr.CFrame = CFrame:Lerp(CFrame.lookAt(CFrame.Position, var27_upvw:GetPivot().Position), arg1_6 ^ 0.45)
end):Disconnect()
SkullEmojiEffectController_upvr:Play(3, "Lower")
end))
return nil
end))
any_new_result1_upvr_2:Add(any_RemoteEvent_result1_upvr.OnClientEvent:Connect(function(arg1_7, arg2, arg3, arg4, arg5) -- Line 181
--[[ Upvalues[10]:
[1]: var27_upvw (read and write)
[2]: any_new_result1_upvr_2 (copied, readonly)
[3]: ReplicatedStorage_upvr (copied, readonly)
[4]: VFX_upvr (copied, readonly)
[5]: RunService_upvr (copied, readonly)
[6]: TweenService_upvr (copied, readonly)
[7]: SharedEventUtils_upvr (copied, readonly)
[8]: MathUtils_upvr (copied, readonly)
[9]: shakeCameraBasedOnProximity_upvr (copied, readonly)
[10]: SoundController_upvr (copied, readonly)
]]
-- KONSTANTWARNING: Variable analysis failed. Output will have some incorrect variable assignments
local var49 = true
if arg2 ~= 2 then
if arg2 ~= 3 then
var49 = false
else
var49 = true
end
end
if var49 then
else
end
if var27_upvw then
else
end
-- KONSTANTERROR: Expression was reused, decompilation is incorrect
local Position_upvr = CFrame.new((arg2 - 1) * 30 + -45, 50, 15).Position
local clone_upvr = any_new_result1_upvr_2:Clone(script.OrbSmaller)
clone_upvr.CFrame = CFrame.new(Position_upvr)
local clone_2 = ReplicatedStorage_upvr.Sounds.Events["Phase 4: Mygame43"].OrbFlying:Clone()
clone_2.Parent = clone_upvr
clone_upvr.Parent = workspace
clone_2:Play()
VFX_upvr.enable(clone_upvr)
local random_state = Random.new(arg1_7)
local var55_upvw = 0
local var56_upvr = Position_upvr + (arg3 - Position_upvr) * 0.25 + Vector3.new(random_state:NextNumber(50, 100) * (random_state:NextInteger(0, 1) * 2 - 1), random_state:NextInteger(300, 400), 0)
local var57_upvr = Position_upvr + (arg3 - Position_upvr) * 0.6 + Vector3.new(random_state:NextNumber(50, 150) * (random_state:NextInteger(0, 1) * 2 - 1), random_state:NextInteger(100, 200), 0)
local var58_upvw
var58_upvw = any_new_result1_upvr_2:Add(RunService_upvr.PostSimulation:Connect(function(arg1_8) -- Line 204
--[[ Upvalues[18]:
[1]: var55_upvw (read and write)
[2]: TweenService_upvr (copied, readonly)
[3]: arg4 (readonly)
[4]: SharedEventUtils_upvr (copied, readonly)
[5]: clone_upvr (readonly)
[6]: MathUtils_upvr (copied, readonly)
[7]: Position_upvr (readonly)
[8]: var56_upvr (readonly)
[9]: var57_upvr (readonly)
[10]: arg3 (readonly)
[11]: var58_upvw (read and write)
[12]: any_new_result1_upvr_2 (copied, readonly)
[13]: VFX_upvr (copied, readonly)
[14]: shakeCameraBasedOnProximity_upvr (copied, readonly)
[15]: arg3 (readonly)
[16]: arg5 (readonly)
[17]: SoundController_upvr (copied, readonly)
[18]: ReplicatedStorage_upvr (copied, readonly)
]]
var55_upvw += arg1_8
local any_GetValue_result1 = TweenService_upvr:GetValue(var55_upvw / arg4, Enum.EasingStyle.Sine, Enum.EasingDirection.In)
SharedEventUtils_upvr.pushPartCFrame(clone_upvr, CFrame.new(MathUtils_upvr.cubicBezier(any_GetValue_result1, Position_upvr, var56_upvr, var57_upvr, arg3)))
if 1 <= any_GetValue_result1 and var58_upvw then
any_new_result1_upvr_2:Remove(var58_upvw)
var58_upvw = nil
VFX_upvr.disable(clone_upvr)
task.delay(3, function() -- Line 215
--[[ Upvalues[2]:
[1]: any_new_result1_upvr_2 (copied, readonly)
[2]: clone_upvr (copied, readonly)
]]
any_new_result1_upvr_2:Remove(clone_upvr)
end)
local var61_upvr = shakeCameraBasedOnProximity_upvr
var61_upvr(arg3)
if arg5 then
var61_upvr = script.StrikeBrainrot:Clone()
else
var61_upvr = script.Strike:Clone()
end
var61_upvr.Position = arg3
var61_upvr.Parent = workspace
VFX_upvr.emit(var61_upvr)
task.delay(4, function() -- Line 227
--[[ Upvalues[1]:
[1]: var61_upvr (readonly)
]]
var61_upvr:Destroy()
end)
if arg5 then
SoundController_upvr:PlaySound(ReplicatedStorage_upvr.Sounds.Events["Los Matteos"].Hit, arg3, false)
return
end
SoundController_upvr:PlaySound(ReplicatedStorage_upvr.Sounds.Events["Phase 4: Mygame43"].OrbHitNothing, arg3, false)
end
end))
end))
end
function module.OnStop(arg1) -- Line 241
--[[ Upvalues[1]:
[1]: any_new_result1_upvr_2 (readonly)
]]
any_new_result1_upvr_2:Destroy()
end
local ContentProvider_upvr = game:GetService("ContentProvider")
function module.OnLoad(arg1) -- Line 245
--[[ Upvalues[2]:
[1]: ContentProvider_upvr (readonly)
[2]: ReplicatedStorage_upvr (readonly)
]]
task.spawn(pcall, function() -- Line 246
--[[ Upvalues[1]:
[1]: ContentProvider_upvr (copied, readonly)
]]
ContentProvider_upvr:PreloadAsync(script:GetChildren())
end)
task.spawn(pcall, function() -- Line 250
--[[ Upvalues[2]:
[1]: ContentProvider_upvr (copied, readonly)
[2]: ReplicatedStorage_upvr (copied, readonly)
]]
ContentProvider_upvr:PreloadAsync(ReplicatedStorage_upvr.Models.Events["Phase 4: Mygame43"])
end)
end
return module - Edit
03:12:20.366
- Edit
03:12:20.367
============================== - Edit
03:12:20.367 📜 ReplicatedStorage.Controllers.EventController.Events.Sammyni Spyderini - Edit
03:12:20.367 ==============================
- Edit
03:12:20.367 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
game:GetService("ServerScriptService")
local v_u_1 = game:GetService("ReplicatedStorage")
local v_u_2 = game:GetService("ContentProvider")
local v_u_3 = game:GetService("RunService")
game:GetService("Players")
local v_u_4 = game:GetService("Debris")
require(v_u_1.Shared.EventTypes)
local v5 = {}
local v_u_6 = require(v_u_1.Controllers.EffectController)
local v_u_7 = require(v_u_1.Controllers.AnimalController)
local v_u_8 = require(v_u_1.Controllers.SoundController)
local v_u_9 = require(v_u_1.Controllers.CycleController)
local v_u_10 = require(v_u_1.Controllers.EventController)
require(v_u_1.Controllers.EventController.ClientEventUtils)
local v_u_11 = require(v_u_1.Packages.CreateTween)
require(v_u_1.Shared.TweenPivot)
local v_u_12 = require(v_u_1.Packages.Observers)
require(v_u_1.Utils.MathUtils)
local v_u_13 = require(v_u_1.Packages.Trove)
local v14 = require(v_u_1.Packages.Net)
local v_u_15 = require(v_u_1.Shared.VFX)
require(v_u_1.Shared.Snapshot)
local v_u_16 = workspace.MapCenter
local v_u_17 = script.Name
local v_u_18 = v14:RemoteEvent((("EventService/%*/Burst"):format(v_u_17)))
local v_u_19 = v_u_13.new()
local v_u_20 = RaycastParams.new()
v_u_20.FilterType = Enum.RaycastFilterType.Include
v_u_20.FilterDescendantsInstances = { workspace.Map, workspace.Plots }
local function v_u_25(p21, p22)
local v23 = workspace:Raycast(p21, Vector3.new(-0, -25, -0), v_u_20)
if v23 then
p21 = v23.Position
end
local v_u_24 = script.Hole:Clone()
v_u_24.CFrame = CFrame.new(p21 + Vector3.new(0, 0.01, 0)) * CFrame.Angles(0, 0, 1.5707963267948966)
v_u_24.Size = Vector3.new(0.01, 0.01, 0.01)
v_u_24.Parent = workspace
v_u_11(v_u_24, TweenInfo.new(0.75, Enum.EasingStyle.Quint, Enum.EasingDirection.Out), {
["Size"] = Vector3.new(0.01, 8, 8)
})
task.delay(p22, function()
v_u_11(v_u_24, TweenInfo.new(0.75, Enum.EasingStyle.Quint, Enum.EasingDirection.In), {
["Size"] = Vector3.new(0.01, 0.01, 0.01)
}).Completed:Wait()
v_u_24:Destroy()
end)
end
local function v_u_43()
local v26 = v_u_19:Extend()
local v_u_27 = table.create(4)
v26:Add(function()
table.clear(v_u_27)
end)
local v_u_28 = 0
v26:Add(v_u_3.PreRender:Connect(function(p29)
debug.profilebegin("Sammyni Spyderini Event")
v_u_28 = v_u_28 + p29
for v30, v31 in v_u_27 do
if v31.target and v31.targetAttachment then
v31.beam.First.Enabled = true
v31.beam.Second.Enabled = true
local v32 = v_u_28 - v30 + 1
local v33 = math.clamp(v32, 0, 1)
local v34 = v31.beam.WorldPosition
v31.targetAttachment.Position = v34 + (v31.target:GetPivot().Position - v34) * v33
end
end
debug.profileend()
end))
v26:Add(v_u_12.observeTag("SammyniSpyderiniPlayerVFX", function(p_u_35)
local v_u_36 = script.PlayerVFX.Beam:Clone()
v_u_36.Parent = p_u_35
local v_u_37 = script.PlayerVFX.Torso:Clone()
v_u_37.Parent = p_u_35
local v_u_38 = p_u_35:GetAttribute("SammyniSpyderiniIndex")
v_u_27[v_u_38] = {
["beam"] = v_u_36,
["target"] = nil
}
local v_u_42 = v_u_12.observeTag("SammyniSpyderiniPlayerVFX", function(p39)
if p39 == p_u_35 then
return nil
end
if p39:GetAttribute("SammyniSpyderiniIndex") ~= p_u_35:GetAttribute("SammyniSpyderiniIndex") % 4 + 1 then
return nil
end
local v_u_40 = Instance.new("Attachment")
v_u_40.Position = v_u_36.WorldPosition
v_u_40.Parent = workspace.Terrain
local v41 = v_u_27[p_u_35:GetAttribute("SammyniSpyderiniIndex")]
v41.target = p39
v41.beam.First.Attachment0 = v_u_40
v41.beam.Second.Attachment0 = v_u_40
v41.targetAttachment = v_u_40
return function()
v_u_40:Destroy()
end
end)
return function()
v_u_37:Destroy()
v_u_36:Destroy()
v_u_42()
v_u_27[v_u_38] = nil
end
end))
end
function v5.OnStart(_)
local v44 = v_u_10:GetActiveEventData(v_u_17)
assert(v44)
v_u_1:SetAttribute("SammyniSpyderiniEvent", true)
v_u_19:Add(function()
v_u_1:SetAttribute("SammyniSpyderiniEvent", nil)
v_u_6:Activate("Blink")
v_u_9:Update()
v_u_8:UpdateOST()
v_u_8:UpdateAmbience()
end)
v_u_19:Add(v_u_12.observeTag("SammyniSpyderini", function(p_u_45)
local v46 = v_u_13.new()
local v_u_47 = p_u_45:WaitForChild("HumanoidRootPart")
local v48 = v46:Clone(script["Sammyni Spyderini"])
local v49 = v46:Add(Instance.new("Weld"))
v49.Part0 = v48.PrimaryPart
v49.Part1 = v_u_47
v49.C0 = CFrame.Angles(0, 3.141592653589793, 0)
v49.Parent = v48.PrimaryPart
v48.Parent = p_u_45
local v50 = v48.AnimationController.Animator
local v51 = v50:LoadAnimation(script.Idle)
v51.Priority = Enum.AnimationPriority.Idle
local v_u_52 = v50:LoadAnimation(script.Walk)
v_u_52.Priority = Enum.AnimationPriority.Movement
local v_u_53 = v50:LoadAnimation(script.Attack)
local v_u_54 = v50:LoadAnimation(script.Ground)
v_u_54.Looped = true
local v_u_55 = v50:LoadAnimation(script.InitialGround)
v_u_55.Looped = true
local v_u_56 = v50:LoadAnimation(script.Jump)
v51:Play()
v46:Add(v_u_54:GetMarkerReachedSignal("Freeze"):Connect(function()
v_u_54:AdjustSpeed(0)
end))
v46:Add(v_u_55:GetMarkerReachedSignal("Freeze"):Connect(function()
v_u_55:AdjustSpeed(0)
end))
local v_u_57 = nil
local function v58()
if p_u_45:GetAttribute("InitialGround") then
v_u_57 = true
v_u_8:PlaySound(v_u_1.Sounds.Events["Sammyni Spyderini"].EnterHole, v_u_47.Position, false)
v_u_25(v_u_47.Position, 1.5)
if not v_u_55.IsPlaying then
v_u_55:Play()
return
end
else
if p_u_45:GetAttribute("Ground") then
v_u_8:PlaySound(v_u_1.Sounds.Events["Sammyni Spyderini"].EnterHole, v_u_47.Position, false)
v_u_25(v_u_47.Position, 1.5)
if not v_u_54.IsPlaying then
if v_u_57 then
v_u_54.TimePosition = 0.6
end
v_u_54:Play(v_u_57 and 0 or nil)
if v_u_57 then
v_u_54.TimePosition = 0.6
end
end
v_u_57 = false
return
end
v_u_57 = false
v_u_8:PlaySound(v_u_1.Sounds.Events["Sammyni Spyderini"].LeaveHole, v_u_47.Position, false)
v_u_25(v_u_47.Position, 1.5)
v_u_56:Play()
v_u_54:Stop()
v_u_55:Stop()
end
end
v46:Add(task.defer(function()
if p_u_45:GetAttribute("IsRunning") then
v_u_52:Play()
end
end))
v46:Add(p_u_45:GetAttributeChangedSignal("IsRunning"):Connect(function()
if p_u_45:GetAttribute("IsRunning") then
v_u_52:Play()
else
v_u_52:Stop()
end
end))
if p_u_45:GetAttribute("Ground") and not v_u_54.IsPlaying then
v_u_54.TimePosition = 0.6
v_u_54:Play(0)
v_u_54.TimePosition = 0.6
end
v46:Add(p_u_45:GetAttributeChangedSignal("Ground"):Connect(v58))
v46:Add(p_u_45:GetAttributeChangedSignal("InitialGround"):Connect(v58))
v46:Add(p_u_45:GetAttributeChangedSignal("AttackAnimation"):Connect(function()
v_u_53:Play()
end))
return v46:WrapClean()
end))
local v_u_59 = v44.startedAt + 5 - workspace:GetServerTimeNow()
v_u_19:Add(task.delay(v_u_59, function()
if v_u_59 > 1 then
v_u_8:PlaySound(v_u_1.Sounds.Events["Sammyni Spyderini"].Expanding, workspace.MapCenter.Position, false)
end
local v60 = v_u_19:Clone(script.Web_Main)
for _, v61 in v60.Lines:GetChildren() do
local v62 = v61.Size
v61.Size = Vector3.new(0, 1, 1)
v_u_11(v61, TweenInfo.new(v62.Magnitude / 150, Enum.EasingStyle.Linear, Enum.EasingDirection.Out), {
["Size"] = v62
})
end
for _, v_u_63 in v60:GetDescendants() do
if not v_u_63:IsDescendantOf(v60.Lines) and v_u_63:IsA("BasePart") then
local v64 = v_u_63.Size
v_u_63.Size = Vector3.new(0, 1, 1)
local v_u_65 = v_u_63.Transparency
v_u_63.Transparency = 1
local v66 = ((v_u_63.Position - v_u_16.Position) * Vector3.new(1, 0, 1)).Magnitude * 2 / 150
task.delay(v66, function()
v_u_63.Transparency = v_u_65
end)
v_u_11(v_u_63, TweenInfo.new(0.2, Enum.EasingStyle.Quint, Enum.EasingDirection.Out, 0, false, v66), {
["Size"] = v64
})
end
end
v60.Parent = workspace
v_u_9:Update()
v_u_8:UpdateOST()
v_u_8:UpdateAmbience()
end))
v_u_19:Add(task.spawn(function()
v_u_43()
end))
end
function v5.OnStop(_)
v_u_19:Destroy()
end
function v5.OnLoad(_)
task.spawn(pcall, function()
v_u_2:PreloadAsync(script:GetChildren())
end)
v_u_18.OnClientEvent:Connect(function(p67)
local v68 = v_u_7:GetAnimals()[p67]
if v68 then
local v69 = v68.AnimalModel
local v70 = v68.AnimalModel
if v70 then
v70 = v69.PrimaryPart
end
local v71 = v68.Instance
local v72
if v71 then
v72 = v71.PrimaryPart
else
v72 = v71
end
if v72 and v70 then
local v73 = v_u_19:Clone(script.Burst)
v73:PivotTo(v72.CFrame * CFrame.new(0, (v73.Size.Y + v69:GetExtentsSize().Y) / 2, 0))
v73.Parent = v71
local v74 = Instance.new("WeldConstraint")
v74.Part0 = v73
v74.Part1 = v68.AnimalModel.PrimaryPart
v74.Parent = v73
v_u_15.emit(v73)
v_u_4:AddItem(v73, 5)
v_u_8:PlaySound(v_u_1.Sounds.Events["Sammyni Spyderini"].Hit, v72.CFrame.Position, false)
end
else
return
end
end)
end
return v5 - Edit
03:12:20.367
- Edit
03:12:20.368
============================== - Edit
03:12:20.368 📜 ReplicatedStorage.Controllers.EventController.Events.Strawberry - Edit
03:12:20.368 ==============================
- Edit
03:12:20.368 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
local v_u_1 = game:GetService("ReplicatedStorage")
game:GetService("RunService")
local v_u_2 = game:GetService("Lighting")
local v_u_3 = game:GetService("Debris")
require(v_u_1.Shared.EventTypes)
local v4 = {}
local v_u_5 = require(v_u_1.Controllers.EffectController)
local v_u_6 = require(v_u_1.Controllers.AnimalController)
local v_u_7 = require(v_u_1.Controllers.EventController)
local v_u_8 = require(v_u_1.Controllers.SoundController)
local v_u_9 = require(v_u_1.Packages.CreateTween)
local v10 = require(v_u_1.Packages.Trove)
local v11 = require(v_u_1.Packages.Net)
local v_u_12 = require(v_u_1.Shared.VFX)
local v_u_13 = script.Name
local v_u_14 = v11:RemoteEvent((("EventService/%*/Burst"):format(v_u_13)))
local v_u_15 = v10.new()
local function v_u_47(p16, p17, p_u_18)
local function v34(p_u_19, p_u_20, p_u_21, p22)
local v_u_23 = p_u_19.CFrame
local v24 = p22 and 0 or p_u_20.X
local v25 = p22 and 0 or p_u_20.Z
local v26 = Vector3.new(v24, 0, v25)
local v27 = v_u_23 * CFrame.new(0, -(p_u_20.Y - v26.Y) / 2, 0)
p_u_19.Size = v26
p_u_19.CFrame = v27
local v_u_28 = p_u_19.Transparency
p_u_19.Transparency = 1
local v29 = v_u_15
local v30 = task.delay
local v31
if p_u_18 then
v31 = p_u_18(p_u_21)
else
v31 = p_u_21
end
v29:Add(v30(v31, function()
p_u_19.Transparency = v_u_28
local v32 = not p_u_18 and 1 or p_u_18(p_u_21 + 1)
local v33 = TweenInfo.new(v32, Enum.EasingStyle.Quint, Enum.EasingDirection.Out)
v_u_9(p_u_19, v33, {
["Size"] = p_u_20
})
v_u_9(p_u_19, v33, {
["CFrame"] = v_u_23
})
end))
end
local v35 = {}
local v36 = (1 / 0)
local v37 = (-1 / 0)
for _, v38 in p16:GetDescendants() do
if v38:IsA("BasePart") and v38.Transparency < 1 then
table.insert(v35, v38)
local v39 = v38.Position.Y
v36 = math.min(v36, v39)
local v40 = v38.Position.Y
v37 = math.max(v37, v40)
end
end
table.sort(v35, function(p41, p42)
return p41.Position.Y < p42.Position.Y
end)
local v43 = v37 - v36
for _, v44 in v35 do
local v45 = (v44.Position.Y - v36) / v43 * p17 + 0.25
local v46 = v44:FindFirstAncestorOfClass("Model").Name == "strawberry"
if v46 then
v45 = v45 + 1
end
v34(v44, v44.Size, v45, v46)
end
end
function v4.OnStart(_)
local v_u_48 = v_u_7:GetActiveEventData(v_u_13)
assert(v_u_48)
v_u_1:SetAttribute("StrawberryEvent", true)
v_u_15:Add(function()
v_u_1:SetAttribute("StrawberryEvent", nil)
end)
v_u_5:Activate("Blink")
v_u_5:Run("StrawberryEvent", "GrassRecolor")
v_u_15:Add(function()
v_u_5:Stop("StrawberryEvent", "GrassRecolor")
v_u_5:Activate("Blink")
end)
local v_u_49 = v_u_2:FindFirstChild("Atmosphere")
if v_u_49 then
v_u_49.Parent = script
v_u_15:Add(function()
v_u_49.Parent = v_u_2
end)
end
v_u_15:Clone(script.Atmosphere).Parent = v_u_2
local v_u_50 = v_u_2:FindFirstChildOfClass("Sky")
if v_u_50 then
v_u_50.Parent = script
v_u_15:Add(function()
v_u_50.Parent = v_u_2
end)
end
v_u_15:Clone(script.Sky).Parent = v_u_2
local v51 = v_u_15:Clone(script.StrawberryVFX)
v51.Parent = workspace
v_u_12.enable(v51)
local v52 = v_u_15:Clone(script.Bushes)
local v53 = Random.new()
for _, v54 in v52:GetChildren() do
v_u_47(v54, v53:NextNumber(5, 7), function(p55)
return v_u_48.startedAt + p55 - workspace:GetServerTimeNow()
end)
end
v52.Parent = workspace
end
function v4.OnStop(_)
v_u_15:Destroy()
end
function v4.OnLoad(_)
v_u_14.OnClientEvent:Connect(function(p56)
local v57 = v_u_6:GetAnimals()[p56]
if v57 then
local v58 = v57.AnimalModel
local v59
if v58 then
v59 = v58.PrimaryPart
else
v59 = v58
end
local v60 = v57.Instance
local v61
if v60 then
v61 = v60.PrimaryPart
else
v61 = v60
end
if v61 and v59 then
local v62 = v_u_15:Clone(script.Burst)
v62:PivotTo(v61.CFrame * CFrame.new(0, (v62.Size.Y + v58:GetExtentsSize().Y) / 2, 0))
v62.Parent = v60
local v63 = Instance.new("WeldConstraint")
v63.Part0 = v62
v63.Part1 = v57.AnimalModel.PrimaryPart
v63.Parent = v62
v_u_12.emit(v62)
v_u_3:AddItem(v62, 5)
v_u_8:PlaySound(v_u_1.Sounds.Events.Strawberry.BrainrotHit, v61.CFrame.Position, false)
end
else
return
end
end)
end
return v4 - Edit
03:12:20.368
- Edit
03:12:20.370
============================== - Edit
03:12:20.370 📜 ReplicatedStorage.Controllers.EventController.Events.YinYang - Edit
03:12:20.370 ==============================
- Edit
03:12:20.370 -- YinYangEvent module (fixed / cleaned)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local module = {}
local Trove = require(ReplicatedStorage.Packages.Trove)
local EventController = require(ReplicatedStorage.Controllers.EventController)
local EffectController = require(ReplicatedStorage.Controllers.EffectController)
local VFX = require(ReplicatedStorage.Shared.VFX)
local CycleController = require(ReplicatedStorage.Controllers.CycleController)
local SoundController = require(ReplicatedStorage.Controllers.SoundController)
local Lighting = game:GetService("Lighting")
local RunService = game:GetService("RunService")
local trove = Trove.new()
local Name = script.Name
function module.OnStart()
-- Make sure this event is actually active
assert(EventController:GetActiveEventData(Name))
-- Handle Atmosphere
local Atmosphere = Lighting:FindFirstChild("Atmosphere")
if Atmosphere then
Atmosphere.Parent = script
trove:Add(function()
Atmosphere.Parent = Lighting
end)
end
-- Clone custom Atmosphere
if script:FindFirstChild("AtmosphereYinYang") then
trove:Clone(script.AtmosphereYinYang).Parent = Lighting
end
-- Handle Cartoon lighting
local Cartoon = Lighting:FindFirstChild("Cartoon")
if Cartoon then
Cartoon.Parent = script
trove:Add(function()
Cartoon.Parent = Lighting
end)
end
-- Clone Sky and make it rotate
if script:FindFirstChild("SkyYinYang") then
local skyClone = trove:Clone(script.SkyYinYang)
skyClone.Parent = Lighting
trove:Add(RunService.PostSimulation:Connect(function(dt)
skyClone.SkyboxOrientation += Vector3.new(0, -dt * 0.36, 0)
end))
end
-- Effects
EffectController:Activate("Blink")
trove:Add(function()
EffectController:Activate("Blink")
end)
EffectController:Run("YinYangEvent", "GrassRecolor")
trove:Add(function()
EffectController:Stop("YinYangEvent", "GrassRecolor")
end)
EffectController:Run("YinYangEvent", "WallRecolor")
trove:Add(function()
EffectController:Stop("YinYangEvent", "WallRecolor")
end)
EffectController:Run("YinYangEvent", "WallBottomRecolor")
trove:Add(function()
EffectController:Stop("YinYangEvent", "WallBottomRecolor")
end)
-- Clone event map
if script:FindFirstChild("YinYangMap") then
trove:Clone(script.YinYangMap).Parent = workspace
end
-- Clone weather VFX
if script:FindFirstChild("YinYangWeather") then
local weatherClone = script.YinYangWeather:Clone()
weatherClone.Parent = workspace
trove:Add(function()
VFX.disable(weatherClone)
task.wait(4)
weatherClone:Destroy()
end)
end
-- Update cycle + OST
CycleController:Update()
SoundController:UpdateOST()
end
function module.OnStop()
trove:Destroy()
end
function module.OnLoad()
-- optional
end
return module - Edit
03:12:20.371
- Edit
03:12:20.371
============================== - Edit
03:12:20.371 📜 ReplicatedStorage.Controllers.SettingsController - Edit
03:12:20.371 ==============================
- Edit
03:12:20.371 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
local v1 = game:GetService("ReplicatedStorage")
local v2 = game:GetService("Players")
local u3 = require(v1.Packages.Synchronizer)
local v4 = require(v1.Packages.TopbarPlus)
local v5 = require(v1.Packages.Net)
local u6 = require(v1.Classes.AnimatedButton)
local u7 = require(v1.Controllers.NotificationController)
local u8 = require(v1.Controllers.InterfaceController)
local u9 = require(v1.Controllers.SoundController)
local u10 = require(v1.Shared.Index)
local u11 = require(v1.Datas.Mutations)
local u12 = v5:RemoteFunction("SettingsService/ToggleSetting")
local u13 = v2.LocalPlayer
local v14 = u13.PlayerGui
local u15 = v4.new():setImage(110481567543062, "Selected"):setImage(78403024093069, "Deselected"):setOrder(1)
local u16 = {
["Music"] = 1,
["Sound Effects"] = 2,
["VFX"] = 3,
["Chat Tips"] = 4,
["Base Skin"] = 5
}
local u17 = nil
local u18 = v14:WaitForChild("Settings").Settings
local u19 = u18.Content.ScrollingFrame
local u20 = u19.Template
local u21 = u19.TemplateBaseSkin
local u22 = u18.Header.Close
local v23 = {}
local function u27() --[[Anonymous function at line 52]]
--[[
Upvalues:
[1] = u11
--]]
local v24 = { "Normal" }
for v25, v26 in pairs(u11) do
if not v26.LimitedMutation then
table.insert(v24, v25)
end
end
return v24
end
local function u49(p28) --[[Anonymous function at line 62]]
--[[
Upvalues:
[1] = u19
[2] = u21
[3] = u27
[4] = u10
[5] = u13
[6] = u11
[7] = u6
[8] = u12
[9] = u7
[10] = u9
[11] = u16
[12] = u20
--]]
for _, v29 in u19:GetChildren() do
if v29.Name ~= "Template" and (v29.Name ~= "TemplateBaseSkin" and v29:IsA("Frame")) then
v29:Destroy()
end
end
for u30, v31 in p28 do
if u30 == "Base Skin" then
local v32 = u21:Clone()
v32.Name = u30
v32.Function.Text = u30
for _, v33 in u21.Button.DropDown:GetChildren() do
if v33 ~= "Template" and v33:IsA("Frame") then
v33:Destroy()
end
end
for _, u34 in ipairs((u27())) do
if u34 ~= v31 then
local v35 = v32.Button.DropDown.Template:Clone()
v35.Name = u34
v35.Text.Text = u34
local v36 = u34 == "Normal" and true or u10:IsComplete(u13, u34)
v35.Locked.Visible = not v36
local v37 = u11[u34]
v35.BackgroundColor3 = u34 ~= "Normal" and v37.MainColor or Color3.new(0.490196, 0.435294, 0.435294)
v35.UIStroke.Color = u34 ~= "Normal" and v37.Palettes[1][2] or Color3.new(0.490196, 0.435294, 0.435294)
v35.Text.UIStroke.Color = u34 ~= "Normal" and v37.Palettes[1][2] or Color3.new(0.490196, 0.435294, 0.435294)
if v36 then
local v38 = u6.new(v35)
v38:Animate()
v38.OnActivated:Connect(function() --[[Anonymous function at line 106]]
--[[
Upvalues:
[1] = u19
[2] = u12
[3] = u30
[4] = u34
[5] = u7
[6] = u9
--]]
u19.CanvasSize = UDim2.new(0, 0, 0, 0)
local v39, v40 = u12:InvokeServer(u30, u34)
if not v39 then
u7:Error(v40)
u9:PlaySound("Sounds.Sfx.Error")
end
end)
end
v35.LayoutOrder = u34 == "Normal" and 1 or (u11[u34].Order or 1)
v35.Parent = v32.Button.DropDown
v35.Visible = true
end
end
local u41 = v32.Button
u41.Text.Text = v31
local v42 = u11[v31]
u41.BackgroundColor3 = v31 ~= "Normal" and v42.MainColor or Color3.new(0.490196, 0.435294, 0.435294)
u41.UIStroke.Color = v31 ~= "Normal" and v42.Palettes[1][1] or Color3.new(0.490196, 0.435294, 0.435294)
u6.new(u41).OnActivated:Connect(function() --[[Anonymous function at line 130]]
--[[
Upvalues:
[1] = u41
[2] = u19
--]]
local v43 = u41.DropDown
v43.Visible = not v43.Visible
u41.Polygon.Rotation = v43.Visible and 180 or 0
u19.CanvasSize = v43.Visible and UDim2.new(0, 0, 1.7, 0) or UDim2.new(0, 0, 0, 0)
u19.CanvasPosition = v43.Visible and Vector2.new(0, u19.AbsoluteCanvasSize.Y - u19.AbsoluteSize.Y) or Vector2.new(0, 0)
end)
v32.LayoutOrder = u16[u30]
v32.Parent = u19
v32.Visible = true
else
local v44 = u20:Clone()
v44.Name = u30
v44.Function.Text = u30
local v45 = v44.Buttons.Button
v45.Text.Text = v31 and "On" or "Off"
v45.BackgroundColor3 = v31 and Color3.new(0.0470588, 0.466667, 0.235294) or Color3.new(0.490196, 0.435294, 0.435294)
v45.UIStroke.Color = v31 and Color3.new(0.00784314, 0.219608, 0) or Color3.new(0.403922, 0.356863, 0.356863)
v45.Text.UIStroke.Color = v31 and Color3.new(0.00784314, 0.219608, 0) or Color3.new(0.403922, 0.356863, 0.356863)
local v46 = u6.new(v45)
v46:Animate()
v46.OnActivated:Connect(function() --[[Anonymous function at line 157]]
--[[
Upvalues:
[1] = u12
[2] = u30
[3] = u7
[4] = u9
--]]
local v47, v48 = u12:InvokeServer(u30)
if not v47 then
u7:Error(v48)
u9:PlaySound("Sounds.Sfx.Error")
end
end)
v44.LayoutOrder = u16[u30]
v44.Parent = u19
v44.Visible = true
end
end
end
function v23.Start(_) --[[Anonymous function at line 171]]
--[[
Upvalues:
[1] = u17
[2] = u8
[3] = u18
[4] = u22
[5] = u15
[6] = u3
[7] = u13
[8] = u49
--]]
u17 = u8:Register("Settings", u18, "TopQuint")
u17:AttachCloseButton(u22)
u17:Close()
u15.selected:Connect(function() --[[Anonymous function at line 178]]
--[[
Upvalues:
[1] = u8
--]]
u8:SetState("Settings", true)
end)
u15.deselected:Connect(function() --[[Anonymous function at line 182]]
--[[
Upvalues:
[1] = u8
--]]
u8:SetState("Settings", false)
end)
u17.OnOpen:Connect(function() --[[Anonymous function at line 186]]
--[[
Upvalues:
[1] = u15
--]]
u15:select()
end)
u17.OnClose:Connect(function() --[[Anonymous function at line 190]]
--[[
Upvalues:
[1] = u15
--]]
u15:deselect()
end)
u3:WaitAndCall(u13, function(u50) --[[Anonymous function at line 194]]
--[[
Upvalues:
[1] = u49
--]]
for v51, _ in u50:Get("Settings") do
u50:OnChanged(("Settings.%*"):format(v51), function(_) --[[Anonymous function at line 198]]
--[[
Upvalues:
[1] = u50
[2] = u49
--]]
local v52 = u50:Get("Settings")
task.spawn(u49, v52)
end, true)
end
end)
end
return v23 - Edit
03:12:20.371
- Edit
03:12:20.371
============================== - Edit
03:12:20.371 📜 ReplicatedStorage.Controllers.GalaxyEventController - Edit
03:12:20.371 ==============================
- Edit
03:12:20.371 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
local u1 = game:GetService("ReplicatedStorage")
local u2 = game:GetService("RunService")
local v3 = game:GetService("Players")
local u4 = game:GetService("TweenService")
local v5 = u1:WaitForChild("Controllers")
local u6 = require(v5.InterfaceController)
require(v5.ShopController)
local u7 = require(v5.NotificationController)
require(v5.SoundController)
local v8 = u1:WaitForChild("Packages")
local u9 = require(v8.Observers)
local u10 = require(v8.Synchronizer)
local u11 = require(v8.Timer)
require(v8.Trove)
local v12 = require(v8.Net)
local v13 = u1:WaitForChild("Utils")
local u14 = require(v13.TimeUtils)
local u15 = require(v13.NumberUtils)
local v16 = u1:WaitForChild("Datas")
local u17 = require(v16.GalaxySpinWheel)
local u18 = require(v16.Shop)
local v19 = u1:WaitForChild("Classes")
local u20 = require(script.GalaxySpinWheel)
local u21 = require(v19.AnimatedButton)
local v22 = u1:WaitForChild("Shared")
local u23 = require(v22.Marketplace)
local u24 = v3.LocalPlayer
local u25 = u24.PlayerGui:WaitForChild("GalaxyWheel").GalaxyWheel
local u26 = nil
local u27 = false
local u28 = v12:RemoteEvent("ShopService/Purchase")
local u29 = v12:RemoteEvent("GalaxyEventService/Spin")
v12:RemoteFunction("GalaxyEventService/RequestBuy")
local u30 = false
local v31 = {}
local function u50(p32, p33) --[[Anonymous function at line 87]]
--[[
Upvalues:
[1] = u10
[2] = u24
[3] = u30
[4] = u25
[5] = u27
[6] = u2
[7] = u4
[8] = u17
[9] = u18
[10] = u15
[11] = u7
--]]
local v34 = u10:Wait(u24)
if not u30 then
u30 = true
local u35 = u25.Wheel
local v36 = u35:FindFirstChild("Spinning")
local v37 = u27 and 1 or 0.8
if v36 then
v36.Looped = true
v36.Volume = v37
v36:Play()
end
local v38 = (p32 - 1) * -60 - (math.random() - 0.5) * 0.7 * 60
local v39 = v38 + (u27 and 1 or 9) * 360
local v40 = u27 and 0.5 or 5
local u41 = nil
local v43 = u2.PostSimulation:Connect(function() --[[Anonymous function at line 112]]
--[[
Upvalues:
[1] = u35
[2] = u41
[3] = u25
[4] = u4
--]]
local v42 = (u35.Rotation + 30) / 60 // 1
if u41 ~= v42 then
u41 = v42
u25.Tick.Rotation = -40
u4:Create(u25.Tick, TweenInfo.new(0.3, Enum.EasingStyle.Sine, Enum.EasingDirection.Out), {
["Rotation"] = 0
}):Play()
end
end)
local v44 = u4:Create(u35, TweenInfo.new(v40, Enum.EasingStyle.Quint, Enum.EasingDirection.Out), {
["Rotation"] = v39
})
if v36 then
u4:Create(v36, TweenInfo.new(v40, Enum.EasingStyle.Linear, Enum.EasingDirection.Out), {
["Volume"] = 0
}):Play()
end
v44:Play()
v44.Completed:Wait()
v43:Disconnect()
u35.Rotation = v38
if v36 then
v36:Stop()
v36.Volume = v37
end
local v45 = p33 == true and u17.AltRewards[p32] or u17.Rewards[p32]
local v46
if v45.Type == "Cash-Pack" then
local v47 = u18[v45.Index]
if not u18 then
return false
end
local v48 = v47.Value or 0
local v49 = v34:Get("Rebirth") or 0
if v49 > 0 then
v48 = v48 * (v49 <= 1 and 1.5 or v49)
end
v46 = ("$%*"):format((u15:ToString(v48, 2)))
else
v46 = v45.Display
end
u7:Success((("You received %*!"):format(v46)))
u30 = false
end
end
function v31.SetupGalaxyWheel(_) --[[Anonymous function at line 165]]
--[[
Upvalues:
[1] = u26
[2] = u6
[3] = u25
[4] = u10
[5] = u24
[6] = u17
[7] = u18
[8] = u15
[9] = u23
[10] = u30
[11] = u21
[12] = u27
[13] = u28
[14] = u29
[15] = u1
[16] = u14
[17] = u50
[18] = u11
[19] = u9
[20] = u20
--]]
u26 = u6:Register("GalaxyWheel", u25, "TopQuint")
u26:AttachCloseButton(u25.Close)
u26:Close()
local u51 = u10:Wait(u24)
local function u68() --[[Anonymous function at line 173]]
--[[
Upvalues:
[1] = u25
[2] = u17
[3] = u51
[4] = u18
[5] = u15
[6] = u23
--]]
local v52 = u25.Wheel
local v53 = v52.Items
local v54 = v52.Names
local v55 = v52.Odds
for v56 = 1, #u17.Rewards do
local v57 = u17.Rewards[v56]
if v57 then
if v57.Type == "Item" and u51:Get((("Items.%*"):format(v57.Index))) then
v57 = u17.AltRewards[v56]
end
local v58 = v53:FindFirstChild(v56)
local v59 = v54:FindFirstChild(v56)
local v60 = v55:FindFirstChild(v56)
local v61 = ""
local v62
if v57.Type == "Cash-Pack" then
local v63 = u18[v57.Index].Value
local v64 = u51:Get("Rebirth") or 0
if v64 > 0 then
v63 = v63 * (v64 <= 1 and 1.5 or v64)
end
v61 = ("$%*"):format((u15:ToString(v63, 2)))
v62 = u23:GetProductInfo(v57.Index, "Product").Icon
else
v62 = v57.Icon
end
local v65 = v57.Display
local v66 = v61 == "" and v65 and v65 or v61
local v67 = ("%*%%"):format(v57.Weight)
v58.Image = v62
v59.Text = v66
v60.Text = v67
end
end
end
u68()
u51:OnDictionaryInserted("Items", function(_, p69) --[[Anonymous function at line 226]]
--[[
Upvalues:
[1] = u17
[2] = u30
[3] = u68
--]]
local v70 = false
for v71 = 1, #u17.Rewards do
local v72 = u17.Rewards[v71]
if v72.Type == "Item" and p69 == v72.Index then
v70 = true
break
end
end
if v70 then
while u30 do
task.wait()
end
u68()
end
end)
local u73 = u25.FastSpin.Toggle
local v74 = u21.new(u73)
v74:Animate()
v74.OnActivated:Connect(function() --[[Anonymous function at line 252]]
--[[
Upvalues:
[1] = u27
[2] = u73
--]]
u27 = not u27
u73.Checkmark.Visible = u27
end)
u73.Checkmark.Visible = u27
for _, u75 in u25.Buttons:GetChildren() do
if u75:IsA("ImageButton") and u75.Name ~= "Spin" then
local v76 = u21.new(u75)
v76:Animate()
v76.OnActivated:Connect(function() --[[Anonymous function at line 264]]
--[[
Upvalues:
[1] = u28
[2] = u75
--]]
u28:FireServer(u75:GetAttribute("ProductId"))
end)
local v77 = u23:GetProductInfo(u75:GetAttribute("ProductId"), "Product")
u75.RbxAmount.Text = v77.PriceInRobux
end
end
local u78 = u25.Buttons.Spin
local v79 = u21.new(u78)
v79:Animate()
v79.OnActivated:Connect(function() --[[Anonymous function at line 275]]
--[[
Upvalues:
[1] = u30
[2] = u29
--]]
if u30 ~= true then
u29:FireServer()
end
end)
local function u98() --[[Anonymous function at line 281]]
--[[
Upvalues:
[1] = u1
[2] = u51
[3] = u78
[4] = u14
[5] = u25
--]]
local v80 = 0
if u1:GetAttribute("GalaxyEvent") then
if u51:Get("GalaxySpinWheel.LastFreeClaimed") == u1:GetAttribute("GalaxyEventLastTime") then
local v81 = u78.Main.Timer
local v82 = "Free Spin in %*"
local v83 = u14
local v84 = workspace:GetServerTimeNow()
local v85
if v84 < 1755961200 then
v85 = 1755961200 - v84
else
local v86 = os.date("!*t", workspace:GetServerTimeNow()).wday
local v87 = (v86 == 1 or v86 == 7) and 3600 or 10800
v85 = v87 - v84 % v87
end
v81.Text = v82:format((v83:D(v85)))
else
v80 = v80 + 1
u78.Main.Timer.Text = "SPIN NOW"
end
else
local v88 = u78.Main.Timer
local v89 = "Free Spin in %*"
local v90 = u14
local v91 = workspace:GetServerTimeNow()
local v92
if v91 < 1755961200 then
v92 = 1755961200 - v91
else
local v93 = os.date("!*t", workspace:GetServerTimeNow()).wday
local v94 = (v93 == 1 or v93 == 7) and 3600 or 10800
v92 = v94 - v91 % v94
end
v88.Text = v89:format((v90:D(v92)))
end
local v95 = v80 + u51:Get("GalaxySpinWheel.Spins")
u78.Main.Spins.Text = v95 > 1 and ("Spins (%*)"):format(v95) or ("Spin (%*)"):format(v95)
u78.Main.UIGradient.Enabled = v95 <= 0
local v96 = workspace:GetServerTimeNow() - u51:Get("GalaxySpinWheel.LastDailyDiscount") >= 86400
u25.Buttons.Buy1.Visible = not v96
u25.Buttons.Buy1Discount.Visible = v96
local v97 = u51:Get("GalaxySpinWheel.PaidSpins.x3") >= 5
u25.Buttons.Buy10.Visible = v97
u25.Buttons.Buy3.Visible = not v97
end
u29.OnClientEvent:Connect(function(p99, p100) --[[Anonymous function at line 317]]
--[[
Upvalues:
[1] = u98
[2] = u50
--]]
task.spawn(u98)
u50(p99, p100)
end)
u11.Simple(1, u98)
u9.observeTag("GalaxySpinWheel", function(p101) --[[Anonymous function at line 324]]
--[[
Upvalues:
[1] = u20
--]]
local u102 = u20.new(p101)
return function() --[[Anonymous function at line 326]]
--[[
Upvalues:
[1] = u102
--]]
u102:Destroy()
end
end)
end
function v31.Start(p103) --[[Anonymous function at line 418]]
p103:SetupGalaxyWheel()
end
return v31 - Edit
03:12:20.371
- Edit
03:12:20.372
============================== - Edit
03:12:20.372 📜 ReplicatedStorage.Controllers.GalaxyEventController.GalaxySpinWheel - Edit
03:12:20.372 ==============================
- Edit
03:12:20.372 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
local u1 = game:GetService("ReplicatedStorage")
local u2 = game:GetService("RunService")
local v3 = game:GetService("Players")
local v4 = u1:WaitForChild("Datas")
local u5 = require(v4.GalaxySpinWheel)
local u6 = require(v4.Shop)
local v7 = u1:WaitForChild("Utils")
local u8 = require(v7.TimeUtils)
local u9 = require(v7.NumberUtils)
local v10 = u1:WaitForChild("Controllers")
require(v10.ShopController)
local u11 = require(v10.InterfaceController)
local v12 = u1:WaitForChild("Shared")
local u13 = require(v12.Marketplace)
local v14 = u1:WaitForChild("Packages")
local u15 = require(v14.Trove)
local u16 = require(v14.Timer)
local u17 = require(v14.Synchronizer)
local u18 = v3.LocalPlayer
local u19 = {}
u19.__index = u19
function u19.new(u20) --[[Anonymous function at line 81]]
--[[
Upvalues:
[1] = u17
[2] = u18
[3] = u19
[4] = u15
[5] = u5
[6] = u6
[7] = u9
[8] = u13
[9] = u2
[10] = u11
[11] = u16
[12] = u1
[13] = u8
--]]
local u21 = u17:Wait(u18)
local v22 = u19
local u23 = setmetatable({}, v22)
u23.Instance = u20
u23.Collector = u15.new()
local function u40() --[[Anonymous function at line 90]]
--[[
Upvalues:
[1] = u20
[2] = u5
[3] = u21
[4] = u6
[5] = u9
[6] = u13
--]]
local v24 = u20:WaitForChild("Main"):WaitForChild("SurfaceGui").Wheel
local v25 = v24.Items
local v26 = v24.Names
local v27 = v24.Odds
for v28 = 1, #u5.Rewards do
local v29 = u5.Rewards[v28]
if v29 then
if v29.Type == "Item" and u21:Get((("Items.%*"):format(v29.Index))) then
v29 = u5.AltRewards[v28]
end
local v30 = v25:FindFirstChild(v28)
local v31 = v26:FindFirstChild(v28)
local v32 = v27:FindFirstChild(v28)
local v33 = ""
local v34
if v29.Type == "Cash-Pack" then
local v35 = u6[v29.Index].Value
local v36 = u21:Get("Rebirth") or 0
if v36 > 0 then
v35 = v35 * (v36 <= 1 and 1.5 or v36)
end
v33 = ("$%*"):format((u9:ToString(v35, 2)))
v34 = u13:GetProductInfo(v29.Index, "Product").Icon
else
v34 = v29.Icon
end
local v37 = v29.Display
local v38 = v33 == "" and v37 and v37 or v33
local v39 = ("%*%%"):format(v29.Weight)
v30.Image = v34 or ""
v31.Text = v38
v32.Text = v39
end
end
end
u40()
u23.Collector:Add(u21:OnDictionaryInserted("Items", function(_, p41) --[[Anonymous function at line 148]]
--[[
Upvalues:
[1] = u5
[2] = u40
--]]
local v42 = false
for v43 = 1, #u5.Rewards do
local v44 = u5.Rewards[v43]
if v44.Type == "Item" and p41 == v44.Index then
v42 = true
break
end
end
if v42 then
u40()
end
end))
u23.Collector:Add(u2.RenderStepped:Connect(function(p45) --[[Anonymous function at line 162]]
--[[
Upvalues:
[1] = u23
--]]
local v46 = u23.Instance.Main
local v47 = v46.CFrame
local v48 = CFrame.Angles
local v49 = p45 * 45
v46.CFrame = v47 * v48(math.rad(v49), 0, 0)
end))
u23.Collector:Add(u23.Instance.Root.ProximityPrompt.Triggered:Connect(function() --[[Anonymous function at line 170]]
--[[
Upvalues:
[1] = u11
--]]
u11:Toggle("GalaxyWheel", true)
end))
local v50 = u16.new(1)
u23.Collector:Add(v50, "Destroy")
u23.Collector:Add(v50.Tick:Connect(function() --[[Anonymous function at line 176]]
--[[
Upvalues:
[1] = u1
[2] = u21
[3] = u23
[4] = u8
--]]
if u1:GetAttribute("GalaxyEvent") then
if u21:Get("GalaxySpinWheel.LastFreeClaimed") == u1:GetAttribute("GalaxyEventLastTime") then
local v51 = u23.Instance.Overhead.BillboardGui.Countdown
local v52 = "Free Spin in %*"
local v53 = u8
local v54 = workspace:GetServerTimeNow()
local v55
if v54 < 1755961200 then
v55 = 1755961200 - v54
else
local v56 = os.date("!*t", workspace:GetServerTimeNow()).wday
local v57 = (v56 == 1 or v56 == 7) and 3600 or 10800
v55 = v57 - v54 % v57
end
v51.Text = v52:format((v53:D(v55)))
else
u23.Instance.Overhead.BillboardGui.Countdown.Text = "SPIN NOW"
end
else
local v58 = u23.Instance.Overhead.BillboardGui.Countdown
local v59 = "Free Spin in %*"
local v60 = u8
local v61 = workspace:GetServerTimeNow()
local v62
if v61 < 1755961200 then
v62 = 1755961200 - v61
else
local v63 = os.date("!*t", workspace:GetServerTimeNow()).wday
local v64 = (v63 == 1 or v63 == 7) and 3600 or 10800
v62 = v64 - v61 % v64
end
v58.Text = v59:format((v60:D(v62)))
return
end
end))
v50:StartNow()
return u23
end
function u19.Destroy(p65) --[[Anonymous function at line 194]]
p65.Collector:Destroy()
end
return u19 - Edit
03:12:20.372
- Edit
03:12:20.372
============================== - Edit
03:12:20.372 📜 ReplicatedStorage.Controllers.CustomProximityPromptController - Edit
03:12:20.372 ==============================
- Edit
03:12:20.372 -- Thanks For Angelus Decompiles --> https://discord.gg/CYXme7yEG9
-- Decompiled with Velocity Script Decompiler
local v_u_1 = game:GetService("ProximityPromptService")
local v_u_2 = game:GetService("UserInputService")
local v_u_3 = game:GetService("TweenService")
local v_u_4 = game:GetService("TextService")
local v_u_5 = game:GetService("Players").LocalPlayer:WaitForChild("PlayerGui")
local v_u_6 = {
[Enum.KeyCode.ButtonX] = "rbxasset://textures/ui/Controls/xboxX.png",
[Enum.KeyCode.ButtonY] = "rbxasset://textures/ui/Controls/xboxY.png",
[Enum.KeyCode.ButtonA] = "rbxasset://textures/ui/Controls/xboxA.png",
[Enum.KeyCode.ButtonB] = "rbxasset://textures/ui/Controls/xboxB.png",
[Enum.KeyCode.DPadLeft] = "rbxasset://textures/ui/Controls/dpadLeft.png",
[Enum.KeyCode.DPadRight] = "rbxasset://textures/ui/Controls/dpadRight.png",
[Enum.KeyCode.DPadUp] = "rbxasset://textures/ui/Controls/dpadUp.png",
[Enum.KeyCode.DPadDown] = "rbxasset://textures/ui/Controls/dpadDown.png",
[Enum.KeyCode.ButtonSelect] = "rbxasset://textures/ui/Controls/xboxView.png",
[Enum.KeyCode.ButtonStart] = "rbxasset://textures/ui/Controls/xboxmenu.png",
[Enum.KeyCode.ButtonL1] = "rbxasset://textures/ui/Controls/xboxLB.png",
[Enum.KeyCode.ButtonR1] = "rbxasset://textures/ui/Controls/xboxRB.png",
[Enum.KeyCode.ButtonL2] = "rbxasset://textures/ui/Controls/xboxLT.png",
[Enum.KeyCode.ButtonR2] = "rbxasset://textures/ui/Controls/xboxRT.png",
[Enum.KeyCode.ButtonL3] = "rbxasset://textures/ui/Controls/xboxLS.png",
[Enum.KeyCode.ButtonR3] = "rbxasset://textures/ui/Controls/xboxRS.png",
[Enum.KeyCode.Thumbstick1] = "rbxasset://textures/ui/Controls/xboxLSDirectional.png",
[Enum.KeyCode.Thumbstick2] = "rbxasset://textures/ui/Controls/xboxRSDirectional.png"
}
local v_u_7 = {
[Enum.KeyCode.Backspace] = "rbxasset://textures/ui/Controls/backspace.png",
[Enum.KeyCode.Return] = "rbxasset://textures/ui/Controls/return.png",
[Enum.KeyCode.LeftShift] = "rbxasset://textures/ui/Controls/shift.png",
[Enum.KeyCode.RightShift] = "rbxasset://textures/ui/Controls/shift.png",
[Enum.KeyCode.Tab] = "rbxasset://textures/ui/Controls/tab.png"
}
local v_u_8 = {
["\'"] = "rbxasset://textures/ui/Controls/apostrophe.png",
[","] = "rbxasset://textures/ui/Controls/comma.png",
["`"] = "rbxasset://textures/ui/Controls/graveaccent.png",
["."] = "rbxasset://textures/ui/Controls/period.png",
[" "] = "rbxasset://textures/ui/Controls/spacebar.png"
}
local v_u_9 = {
[Enum.KeyCode.LeftControl] = "Ctrl",
[Enum.KeyCode.RightControl] = "Ctrl",
[Enum.KeyCode.LeftAlt] = "Alt",
[Enum.KeyCode.RightAlt] = "Alt",
[Enum.KeyCode.F1] = "F1",
[Enum.KeyCode.F2] = "F2",
[Enum.KeyCode.F3] = "F3",
[Enum.KeyCode.F4] = "F4",
[Enum.KeyCode.F5] = "F5",
[Enum.KeyCode.F6] = "F6",
[Enum.KeyCode.F7] = "F7",
[Enum.KeyCode.F8] = "F8",
[Enum.KeyCode.F9] = "F9",
[Enum.KeyCode.F10] = "F10",
[Enum.KeyCode.F11] = "F11",
[Enum.KeyCode.F12] = "F12"
}
local function v_u_15(p10, p11)
local v12 = Instance.new("Frame")
v12.Size = UDim2.fromScale(0.5, 1)
v12.Position = UDim2.fromScale(p11 and 0 or 0.5, 0)
v12.BackgroundTransparency = 1
v12.ClipsDescendants = true
v12.Parent = p10
local v13 = Instance.new("ImageLabel")
v13.BackgroundTransparency = 1
v13.Size = UDim2.fromScale(2, 1)
v13.Position = UDim2.fromScale(p11 and 0 or -1, 0)
v13.Image = "rbxasset://textures/ui/Controls/RadialFill.png"
v13.Parent = v12
local v14 = Instance.new("UIGradient")
v14.Transparency = NumberSequence.new({
NumberSequenceKeypoint.new(0, 0),
NumberSequenceKeypoint.new(0.4999, 0),
NumberSequenceKeypoint.new(0.5, 1),
NumberSequenceKeypoint.new(1, 1)
})
v14.Rotation = p11 and 180 or 0
v14.Parent = v13
return v14
end
local function v_u_23()
-- upvalues: (copy) v_u_15
local v16 = Instance.new("Frame")
v16.Name = "CircularProgressBar"
v16.Size = UDim2.fromOffset(58, 58)
v16.AnchorPoint = Vector2.new(0.5, 0.5)
v16.Position = UDim2.fromScale(0.5, 0.5)
v16.BackgroundTransparency = 1
local v_u_17 = v_u_15(v16, true)
local v_u_18 = v_u_15(v16, false)
local v19 = Instance.new("NumberValue")
v19.Name = "Progress"
v19.Parent = v16
v19.Changed:Connect(function(p20)
-- upvalues: (copy) v_u_17, (copy) v_u_18
local v21 = p20 * 360
local v22 = math.clamp(v21, 0, 360)
v_u_17.Rotation = math.clamp(v22, 180, 360)
v_u_18.Rotation = math.clamp(v22, 0, 180)
end)
return v16
end
local function v_u_116(p_u_24, p25, p26)
-- upvalues: (copy) v_u_3, (copy) v_u_6, (copy) v_u_2, (copy) v_u_7, (copy) v_u_8, (copy) v_u_9, (copy) v_u_23, (copy) v_u_4
local v_u_27 = {}
local v_u_28 = {}
local v_u_29 = {}
local v_u_30 = {}
local v31 = TweenInfo.new(p_u_24.HoldDuration, Enum.EasingStyle.Linear, Enum.EasingDirection.Out)
local v32 = TweenInfo.new(0.5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
local v33 = TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
local v34 = TweenInfo.new(0.06, Enum.EasingStyle.Linear, Enum.EasingDirection.Out)
local v_u_35 = Instance.new("BillboardGui")
v_u_35.Name = "Prompt"
v_u_35.AlwaysOnTop = true
local v36 = Instance.new("Frame")
v36.Size = UDim2.fromScale(0.5, 1)
v36.BackgroundTransparency = 1
v36.BackgroundColor3 = Color3.new(0.07, 0.07, 0.07)
v36.Parent = v_u_35
local v_u_37 = p_u_24:GetAttribute("State") == "Sell"
if v_u_37 then
v36.BackgroundColor3 = Color3.fromRGB(67, 0, 0)
end
Instance.new("UICorner").Parent = v36
local v38 = Instance.new("Frame")
v38.Name = "InputFrame"
v38.Size = UDim2.fromScale(1, 1)
v38.BackgroundTransparency = 1
v38.SizeConstraint = Enum.SizeConstraint.RelativeYY
v38.Parent = v36
local v39 = Instance.new("Frame")
v39.Size = UDim2.fromScale(1, 1)
v39.Position = UDim2.fromScale(0.5, 0.5)
v39.AnchorPoint = Vector2.new(0.5, 0.5)
v39.BackgroundTransparency = 1
v39.Parent = v38
local v40 = Instance.new("UIScale")
v40.Parent = v39
local v41 = p25 == Enum.ProximityPromptInputType.Touch and 1.6 or 1.33
local v42 = v_u_3
table.insert(v_u_27, v42:Create(v40, v33, {
["Scale"] = v41
}))
local v43 = v_u_3
table.insert(v_u_28, v43:Create(v40, v33, {
["Scale"] = 1
}))
local v_u_44 = Instance.new("TextLabel")
v_u_44.Name = "ActionText"
v_u_44.Size = UDim2.fromScale(1, 1)
v_u_44.Font = Enum.Font.GothamMedium
v_u_44.TextSize = 19
v_u_44.BackgroundTransparency = 1
v_u_44.TextTransparency = 1
v_u_44.TextColor3 = Color3.new(1, 1, 1)
v_u_44.TextXAlignment = Enum.TextXAlignment.Left
v_u_44.Parent = v36
local v45 = v_u_3
table.insert(v_u_27, v45:Create(v_u_44, v33, {
["TextTransparency"] = 1
}))
local v46 = v_u_3
table.insert(v_u_28, v46:Create(v_u_44, v33, {
["TextTransparency"] = 0
}))
local v47 = v_u_3
table.insert(v_u_29, v47:Create(v_u_44, v33, {
["TextTransparency"] = 1
}))
local v48 = v_u_3
table.insert(v_u_30, v48:Create(v_u_44, v33, {
["TextTransparency"] = 0
}))
local v_u_49 = Instance.new("TextLabel")
v_u_49.Name = "ObjectText"
v_u_49.Size = UDim2.fromScale(1, 1)
v_u_49.Font = Enum.Font.GothamMedium
v_u_49.TextSize = 14
v_u_49.BackgroundTransparency = 1
v_u_49.TextTransparency = 1
v_u_49.TextColor3 = Color3.new(0.7, 0.7, 0.7)
v_u_49.TextXAlignment = Enum.TextXAlignment.Left
v_u_49.Parent = v36
local v50 = v_u_3
table.insert(v_u_27, v50:Create(v_u_49, v33, {
["TextTransparency"] = 1
}))
local v51 = v_u_3
table.insert(v_u_28, v51:Create(v_u_49, v33, {
["TextTransparency"] = 0
}))
local v52 = v_u_3
table.insert(v_u_29, v52:Create(v_u_49, v33, {
["TextTransparency"] = 1
}))
local v53 = v_u_3
table.insert(v_u_30, v53:Create(v_u_49, v33, {
["TextTransparency"] = 0
}))
local v54 = v_u_3
local v55 = {
["Size"] = UDim2.fromScale(0.5, 1),
["BackgroundTransparency"] = 1
}
table.insert(v_u_27, v54:Create(v36, v33, v55))
local v56 = v_u_3
local v57 = {
["Size"] = UDim2.fromScale(1, 1),
["BackgroundTransparency"] = 0.2
}
table.insert(v_u_28, v56:Create(v36, v33, v57))
local v58 = v_u_3
local v59 = {
["Size"] = UDim2.fromScale(0.5, 1),
["BackgroundTransparency"] = 1
}
table.insert(v_u_29, v58:Create(v36, v33, v59))
local v60 = v_u_3
local v61 = {
["Size"] = UDim2.fromScale(1, 1),
["BackgroundTransparency"] = 0.2
}
table.insert(v_u_30, v60:Create(v36, v33, v61))
local v62 = Instance.new("Frame")
v62.Name = "RoundFrame"
v62.Size = UDim2.fromOffset(48, 48)
v62.AnchorPoint = Vector2.new(0.5, 0.5)
v62.Position = UDim2.fromScale(0.5, 0.5)
v62.BackgroundTransparency = 1
v62.Parent = v39
local v63 = Instance.new("UICorner")
v63.CornerRadius = UDim.new(0.5, 0)
v63.Parent = v62
local v64 = v_u_3
table.insert(v_u_29, v64:Create(v62, v34, {
["BackgroundTransparency"] = 1
}))
local v65 = v_u_3
table.insert(v_u_30, v65:Create(v62, v34, {
["BackgroundTransparency"] = 0.5
}))
if p25 == Enum.ProximityPromptInputType.Gamepad then
if v_u_6[p_u_24.GamepadKeyCode] ~= nil then
local v66 = Instance.new("ImageLabel")
v66.Name = "ButtonImage"
v66.AnchorPoint = Vector2.new(0.5, 0.5)
v66.Size = UDim2.fromOffset(24, 24)
v66.Position = UDim2.fromScale(0.5, 0.5)
v66.BackgroundTransparency = 1
v66.ImageTransparency = 1
v66.Image = v_u_2:GetImageForKeyCode(p_u_24.GamepadKeyCode)
v66.Parent = v39
local v67 = v_u_3
table.insert(v_u_29, v67:Create(v66, v34, {
["ImageTransparency"] = 1
}))
local v68 = v_u_3
table.insert(v_u_30, v68:Create(v66, v34, {
["ImageTransparency"] = 0
}))
end
elseif p25 == Enum.ProximityPromptInputType.Touch then
local v69 = Instance.new("ImageLabel")
v69.Name = "ButtonImage"
v69.BackgroundTransparency = 1
v69.ImageTransparency = 1
v69.Size = UDim2.fromOffset(25, 31)
v69.AnchorPoint = Vector2.new(0.5, 0.5)
v69.Position = UDim2.fromScale(0.5, 0.5)
v69.Image = "rbxasset://textures/ui/Controls/TouchTapIcon.png"
v69.Parent = v39
local v70 = v_u_3
table.insert(v_u_29, v70:Create(v69, v34, {
["ImageTransparency"] = 1
}))
local v71 = v_u_3
table.insert(v_u_30, v71:Create(v69, v34, {
["ImageTransparency"] = 0
}))
else
local v72 = Instance.new("ImageLabel")
v72.Name = "ButtonImage"
v72.BackgroundTransparency = 1
v72.ImageTransparency = 1
v72.Size = UDim2.fromOffset(28, 30)
v72.AnchorPoint = Vector2.new(0.5, 0.5)
v72.Position = UDim2.fromScale(0.5, 0.5)
v72.Image = "rbxasset://textures/ui/Controls/key_single.png"
v72.Parent = v39
local v73 = v_u_3
table.insert(v_u_29, v73:Create(v72, v34, {
["ImageTransparency"] = 1
}))
local v74 = v_u_3
table.insert(v_u_30, v74:Create(v72, v34, {
["ImageTransparency"] = 0
}))
local v75 = v_u_2:GetStringForKeyCode(p_u_24.KeyboardKeyCode)
local v76 = v_u_7[p_u_24.KeyboardKeyCode]
if v76 == nil then
v76 = v_u_8[v75]
end
if v76 == nil then
v75 = v_u_9[p_u_24.KeyboardKeyCode] or v75
end
if v76 then
local v77 = Instance.new("ImageLabel")
v77.Name = "ButtonImage"
v77.AnchorPoint = Vector2.new(0.5, 0.5)
v77.Size = UDim2.fromOffset(36, 36)
v77.Position = UDim2.fromScale(0.5, 0.5)
v77.BackgroundTransparency = 1
v77.ImageTransparency = 1
v77.Image = v76
v77.Parent = v39
local v78 = v_u_3
table.insert(v_u_29, v78:Create(v77, v34, {
["ImageTransparency"] = 1
}))
local v79 = v_u_3
table.insert(v_u_30, v79:Create(v77, v34, {
["ImageTransparency"] = 0
}))
elseif v75 == nil or v75 == "" then
local v80 = error
local v81 = p_u_24.Name
local v82 = p_u_24.KeyboardKeyCode
v80("ProximityPrompt \'" .. v81 .. "\' has an unsupported keycode for rendering UI: " .. tostring(v82))
else
local v83 = Instance.new("TextLabel")
v83.Name = "ButtonText"
v83.Position = UDim2.fromOffset(0, -1)
v83.Size = UDim2.fromScale(1, 1)
v83.Font = Enum.Font.GothamMedium
v83.TextSize = 14
if string.len(v75) > 2 then
v83.TextSize = 12
end
v83.BackgroundTransparency = 1
v83.TextTransparency = 1
v83.TextColor3 = Color3.new(1, 1, 1)
v83.TextXAlignment = Enum.TextXAlignment.Center
v83.Text = v75
v83.Parent = v39
local v84 = v_u_3
table.insert(v_u_29, v84:Create(v83, v34, {
["TextTransparency"] = 1
}))
local v85 = v_u_3
table.insert(v_u_30, v85:Create(v83, v34, {
["TextTransparency"] = 0
}))
end
end
if p25 == Enum.ProximityPromptInputType.Touch or p_u_24.ClickablePrompt then
local v86 = Instance.new("TextButton")
v86.BackgroundTransparency = 1
v86.TextTransparency = 1
v86.Size = UDim2.fromScale(1, 1)
v86.Parent = v_u_35
local v_u_87 = false
v86.InputBegan:Connect(function(p88)
-- upvalues: (copy) p_u_24, (ref) v_u_87
if (p88.UserInputType == Enum.UserInputType.Touch or p88.UserInputType == Enum.UserInputType.MouseButton1) and p88.UserInputState ~= Enum.UserInputState.Change then
p_u_24:InputHoldBegin()
v_u_87 = true
end
end)
v86.InputEnded:Connect(function(p89)
-- upvalues: (ref) v_u_87, (copy) p_u_24
if (p89.UserInputType == Enum.UserInputType.Touch or p89.UserInputType == Enum.UserInputType.MouseButton1) and v_u_87 then
v_u_87 = false
p_u_24:InputHoldEnd()
end
end)
v_u_35.Active = true
end
if p_u_24.HoldDuration > 0 then
local v90 = v_u_23()
v90.Parent = v39
local v91 = v_u_3
local v92 = v90.Progress
table.insert(v_u_27, v91:Create(v92, v31, {
["Value"] = 1
}))
local v93 = v_u_3
local v94 = v90.Progress
table.insert(v_u_28, v93:Create(v94, v32, {
["Value"] = 0
}))
end
local v_u_95, v_u_96
if p_u_24.HoldDuration > 0 then
v_u_95 = p_u_24.PromptButtonHoldBegan:Connect(function()
-- upvalues: (copy) v_u_27
for _, v97 in ipairs(v_u_27) do
v97:Play()
end
end)
v_u_96 = p_u_24.PromptButtonHoldEnded:Connect(function()
-- upvalues: (copy) v_u_28
for _, v98 in ipairs(v_u_28) do
v98:Play()
end
end)
else
v_u_95 = nil
v_u_96 = nil
end
local v_u_100 = p_u_24.Triggered:Connect(function()
-- upvalues: (copy) v_u_29
for _, v99 in ipairs(v_u_29) do
v99:Play()
end
end)
local v_u_102 = p_u_24.TriggerEnded:Connect(function()
-- upvalues: (copy) v_u_30
for _, v101 in ipairs(v_u_30) do
v101:Play()
end
end)
local function v112()
-- upvalues: (ref) v_u_4, (copy) p_u_24, (copy) v_u_37, (copy) v_u_44, (copy) v_u_49, (copy) v_u_35
local v103 = v_u_4:GetTextSize(p_u_24.ActionText, 19, Enum.Font.GothamMedium, Vector2.new(1000, 1000))
local v104 = v_u_4:GetTextSize(p_u_24.ObjectText, 14, Enum.Font.GothamMedium, Vector2.new(1000, 1000))
local v105 = v103.X
local v106 = v104.X
local v107 = math.max(v105, v106)
local v108, v109, v110
if v_u_37 then
v108 = 62
v109 = 62
v110 = 62
else
v108 = 72
v109 = 72
v110 = 72
end
if p_u_24.ActionText ~= nil and p_u_24.ActionText ~= "" or p_u_24.ObjectText ~= nil and p_u_24.ObjectText ~= "" then
v108 = v107 + v109 + 24
end
local v111 = (p_u_24.ObjectText == nil or p_u_24.ObjectText == "") and 0 or 9
v_u_44.Position = UDim2.new(0.5, v109 - v108 / 2, 0, v111)
v_u_49.Position = UDim2.new(0.5, v109 - v108 / 2, 0, -10)
v_u_44.Text = p_u_24.ActionText
v_u_49.Text = p_u_24.ObjectText
v_u_44.AutoLocalize = p_u_24.AutoLocalize
v_u_44.RootLocalizationTable = p_u_24.RootLocalizationTable
v_u_49.AutoLocalize = p_u_24.AutoLocalize
v_u_49.RootLocalizationTable = p_u_24.RootLocalizationTable
v_u_35.Size = UDim2.fromOffset(v108, v110)
v_u_35.SizeOffset = Vector2.new(p_u_24.UIOffset.X / v_u_35.Size.Width.Offset, p_u_24.UIOffset.Y / v_u_35.Size.Height.Offset)
end
local v_u_113 = p_u_24.Changed:Connect(v112)
v112()
v_u_35.Adornee = p_u_24.Parent
v_u_35.Parent = p26
for _, v114 in ipairs(v_u_30) do
v114:Play()
end
return function()
-- upvalues: (ref) v_u_95, (ref) v_u_96, (ref) v_u_100, (ref) v_u_102, (copy) v_u_113, (copy) v_u_29, (copy) v_u_35
if v_u_95 then
v_u_95:Disconnect()
end
if v_u_96 then
v_u_96:Disconnect()
end
v_u_100:Disconnect()
v_u_102:Disconnect()
v_u_113:Disconnect()
for _, v115 in ipairs(v_u_29) do
v115:Play()
end
task.wait(0.2)
v_u_35.Parent = nil
end
end
task.spawn(function()
-- upvalues: (copy) v_u_1, (copy) v_u_5, (copy) v_u_116
local v_u_117 = false
v_u_1.PromptShown:Connect(function(p118, p119)
-- upvalues: (ref) v_u_117, (ref) v_u_5, (ref) v_u_116
if p118.Style == Enum.ProximityPromptStyle.Default then
return
elseif p118:GetAttribute("State") ~= "Sell" and p118:GetAttribute("State") ~= "Grab" or not v_u_117 then
local v120 = v_u_5:FindFirstChild("ProximityPrompts")
if v120 == nil then
v120 = Instance.new("ScreenGui")
v120.Name = "ProximityPrompts"
v120.ResetOnSpawn = false
v120.Parent = v_u_5
end
local v121 = v_u_116(p118, p119, v120)
p118.PromptHidden:Wait()
v121()
end
end)
v_u_1.PromptButtonHoldBegan:Connect(function()
-- upvalues: (ref) v_u_117
v_u_117 = true
end)
v_u_1.PromptButtonHoldEnded:Connect(function()
-- upvalues: (ref) v_u_117
v_u_117 = false
end)
end)
return {} - Edit
03:12:20.372
- Edit
03:12:20.372
============================== - Edit
03:12:20.372 📜 ReplicatedStorage.Controllers.MoltenEventController - Edit
03:12:20.372 ==============================
- Edit
03:12:20.372 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
local u1 = game:GetService("ReplicatedStorage")
local u2 = game:GetService("RunService")
local v3 = game:GetService("Players")
local u4 = game:GetService("TweenService")
local v5 = u1:WaitForChild("Controllers")
local u6 = require(v5.InterfaceController)
require(v5.ShopController)
local u7 = require(v5.NotificationController)
require(v5.SoundController)
local v8 = u1:WaitForChild("Packages")
local u9 = require(v8.Observers)
local u10 = require(v8.Synchronizer)
local u11 = require(v8.Timer)
require(v8.Trove)
local v12 = require(v8.Net)
local v13 = u1:WaitForChild("Utils")
local u14 = require(v13.TimeUtils)
local u15 = require(v13.NumberUtils)
local v16 = u1:WaitForChild("Datas")
local u17 = require(v16.MoltenSpinWheel)
local u18 = require(v16.Shop)
local v19 = u1:WaitForChild("Classes")
local u20 = require(script.MoltenSpinWheel)
local u21 = require(v19.AnimatedButton)
local v22 = u1:WaitForChild("Shared")
local u23 = require(v22.Marketplace)
local u24 = v3.LocalPlayer
local u25 = u24.PlayerGui:WaitForChild("MoltenWheel").MoltenWheel
local u26 = nil
local u27 = false
local u28 = false
local u29 = v12:RemoteEvent("ShopService/Purchase")
local u30 = v12:RemoteEvent("MoltenEventService/Spin")
v12:RemoteFunction("MoltenEventService/RequestBuy")
local u31 = false
local v32 = {}
local function u51(p33, p34) --[[Anonymous function at line 83]]
--[[
Upvalues:
[1] = u10
[2] = u24
[3] = u31
[4] = u25
[5] = u28
[6] = u2
[7] = u4
[8] = u17
[9] = u18
[10] = u15
[11] = u7
--]]
local v35 = u10:Wait(u24)
if not u31 then
u31 = true
local u36 = u25.Wheel
local v37 = u36:FindFirstChild("Spinning")
local v38 = u28 and 1 or 0.8
if v37 then
v37.Looped = true
v37.Volume = v38
v37:Play()
end
local v39 = (p33 - 1) * -60 - (math.random() - 0.5) * 0.7 * 60
local v40 = v39 + (u28 and 1 or 9) * 360
local v41 = u28 and 0.5 or 5
local u42 = nil
local v44 = u2.PostSimulation:Connect(function() --[[Anonymous function at line 108]]
--[[
Upvalues:
[1] = u36
[2] = u42
[3] = u25
[4] = u4
--]]
local v43 = (u36.Rotation + 30) / 60 // 1
if u42 ~= v43 then
u42 = v43
u25.Tick.Rotation = -40
u4:Create(u25.Tick, TweenInfo.new(0.3, Enum.EasingStyle.Sine, Enum.EasingDirection.Out), {
["Rotation"] = 0
}):Play()
end
end)
local v45 = u4:Create(u36, TweenInfo.new(v41, Enum.EasingStyle.Quint, Enum.EasingDirection.Out), {
["Rotation"] = v40
})
if v37 then
u4:Create(v37, TweenInfo.new(v41, Enum.EasingStyle.Linear, Enum.EasingDirection.Out), {
["Volume"] = 0
}):Play()
end
v45:Play()
v45.Completed:Wait()
v44:Disconnect()
u36.Rotation = v39
if v37 then
v37:Stop()
v37.Volume = v38
end
local v46 = p34 == true and u17.AltRewards[p33] or u17.Rewards[p33]
local v47
if v46.Type == "Cash-Pack" then
local v48 = u18[v46.Index]
if not u18 then
return false
end
local v49 = v48.Value or 0
local v50 = v35:Get("Rebirth") or 0
if v50 > 0 then
v49 = v49 * (v50 <= 1 and 1.5 or v50)
end
v47 = ("$%*"):format((u15:ToString(v49, 2)))
else
v47 = v46.Display
end
u7:Success((("You received %*!"):format(v47)))
u31 = false
end
end
function v32.SetupMoltenWheel(_) --[[Anonymous function at line 161]]
--[[
Upvalues:
[1] = u26
[2] = u6
[3] = u25
[4] = u10
[5] = u24
[6] = u27
[7] = u17
[8] = u18
[9] = u15
[10] = u23
[11] = u31
[12] = u21
[13] = u28
[14] = u29
[15] = u30
[16] = u1
[17] = u14
[18] = u51
[19] = u11
[20] = u9
[21] = u20
--]]
u26 = u6:Register("MoltenWheel", u25, "TopQuint")
u26:AttachCloseButton(u25.Close)
u26:Close()
local u52 = u10:Wait(u24)
local function u54() --[[Anonymous function at line 168]]
--[[
Upvalues:
[1] = u25
[2] = u27
--]]
for _, v53 in u25.Wheel.Odds:GetChildren() do
if v53:IsA("TextLabel") then
v53.Visible = u27
end
end
end
local function u71() --[[Anonymous function at line 178]]
--[[
Upvalues:
[1] = u25
[2] = u17
[3] = u52
[4] = u18
[5] = u15
[6] = u23
--]]
local v55 = u25.Wheel
local v56 = v55.Items
local v57 = v55.Names
local v58 = v55.Odds
for v59 = 1, #u17.Rewards do
local v60 = u17.Rewards[v59]
if v60 then
if v60.Type == "Item" and u52:Get((("Items.%*"):format(v60.Index))) then
v60 = u17.AltRewards[v59]
end
local v61 = v56:FindFirstChild(v59)
local v62 = v57:FindFirstChild(v59)
local v63 = v58:FindFirstChild(v59)
local v64 = ""
local v65
if v60.Type == "Cash-Pack" then
local v66 = u18[v60.Index].Value
local v67 = u52:Get("Rebirth") or 0
if v67 > 0 then
v66 = v66 * (v67 <= 1 and 1.5 or v67)
end
v64 = ("$%*"):format((u15:ToString(v66, 2)))
v65 = u23:GetProductInfo(v60.Index, "Product").Icon
else
v65 = v60.Icon
end
local v68 = v60.Display
local v69 = v64 == "" and v68 and v68 or v64
local v70 = ("%*%%"):format(v60.Weight)
v61.Image = v65
v62.Text = v69
v63.Text = v70
end
end
end
u71()
u54()
u52:OnDictionaryInserted("Items", function(_, p72) --[[Anonymous function at line 232]]
--[[
Upvalues:
[1] = u17
[2] = u31
[3] = u71
--]]
local v73 = false
for v74 = 1, #u17.Rewards do
local v75 = u17.Rewards[v74]
if v75.Type == "Item" and p72 == v75.Index then
v73 = true
break
end
end
if v73 then
while u31 do
task.wait()
end
u71()
end
end)
local u76 = u25.FastSpin.Toggle
local v77 = u21.new(u76)
v77:Animate()
v77.OnActivated:Connect(function() --[[Anonymous function at line 258]]
--[[
Upvalues:
[1] = u28
[2] = u76
--]]
u28 = not u28
u76.Checkmark.Visible = u28
end)
u76.Checkmark.Visible = u28
for _, u78 in u25.Buttons:GetChildren() do
if u78:IsA("ImageButton") and u78.Name ~= "Spin" then
local v79 = u21.new(u78)
v79:Animate()
v79.OnActivated:Connect(function() --[[Anonymous function at line 270]]
--[[
Upvalues:
[1] = u29
[2] = u78
--]]
u29:FireServer(u78:GetAttribute("ProductId"))
end)
local v80 = u23:GetProductInfo(u78:GetAttribute("ProductId"), "Product")
u78.RbxAmount.Text = v80.PriceInRobux
end
end
local u81 = u25.Buttons.Spin
local v82 = u21.new(u81)
v82:Animate()
v82.OnActivated:Connect(function() --[[Anonymous function at line 281]]
--[[
Upvalues:
[1] = u31
[2] = u30
--]]
if u31 ~= true then
u30:FireServer()
end
end)
local v83 = u25.TogglePercentage
local v84 = u21.new(v83)
v84:Animate()
v84.OnActivated:Connect(function() --[[Anonymous function at line 290]]
--[[
Upvalues:
[1] = u27
[2] = u54
--]]
u27 = not u27
u54()
end)
local function u97() --[[Anonymous function at line 296]]
--[[
Upvalues:
[1] = u1
[2] = u52
[3] = u81
[4] = u14
[5] = u25
--]]
local v85 = 0
if u1:GetAttribute("MoltenEvent") then
if u52:Get("MoltenSpinWheel.LastFreeClaimed") == u1:GetAttribute("MoltenEventLastTime") then
local v86 = u81.Main.Timer
local v87 = u14
local v88 = os.date("!*t", workspace:GetServerTimeNow()).wday
local v89 = (v88 == 1 or v88 == 7) and 3600 or 10800
v86.Text = ("Free Spin in %*"):format((v87:D(v89 - workspace:GetServerTimeNow() % v89)))
else
v85 = v85 + 1
u81.Main.Timer.Text = "SPIN NOW"
end
else
local v90 = u81.Main.Timer
local v91 = u14
local v92 = os.date("!*t", workspace:GetServerTimeNow()).wday
local v93 = (v92 == 1 or v92 == 7) and 3600 or 10800
v90.Text = ("Free Spin in %*"):format((v91:D(v93 - workspace:GetServerTimeNow() % v93)))
end
local v94 = v85 + u52:Get("MoltenSpinWheel.Spins")
u81.Main.Spins.Text = v94 > 1 and ("Spins (%*)"):format(v94) or ("Spin (%*)"):format(v94)
u81.Main.UIGradient.Enabled = v94 <= 0
local v95 = workspace:GetServerTimeNow() - u52:Get("MoltenSpinWheel.LastDailyDiscount") >= 86400
u25.Buttons.Buy1.Visible = not v95
u25.Buttons.Buy1Discount.Visible = v95
local v96 = u52:Get("MoltenSpinWheel.PaidSpins.x3") >= 5
u25.Buttons.Buy10.Visible = v96
u25.Buttons.Buy3.Visible = not v96
end
u30.OnClientEvent:Connect(function(p98, p99) --[[Anonymous function at line 332]]
--[[
Upvalues:
[1] = u97
[2] = u51
--]]
task.spawn(u97)
u51(p98, p99)
end)
u11.Simple(1, u97)
u9.observeTag("MoltenSpinWheel", function(p100) --[[Anonymous function at line 339]]
--[[
Upvalues:
[1] = u20
--]]
local u101 = u20.new(p100)
return function() --[[Anonymous function at line 341]]
--[[
Upvalues:
[1] = u101
--]]
u101:Destroy()
end
end)
end
function v32.Start(p102) --[[Anonymous function at line 433]]
p102:SetupMoltenWheel()
end
return v32 - Edit
03:12:20.372
- Edit
03:12:20.373
============================== - Edit
03:12:20.373 📜 ReplicatedStorage.Controllers.MoltenEventController.MoltenSpinWheel - Edit
03:12:20.373 ==============================
- Edit
03:12:20.373 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
local u1 = game:GetService("ReplicatedStorage")
local u2 = game:GetService("RunService")
local v3 = game:GetService("Players")
local v4 = u1:WaitForChild("Datas")
local u5 = require(v4.MoltenSpinWheel)
local u6 = require(v4.Shop)
local v7 = u1:WaitForChild("Utils")
local u8 = require(v7.TimeUtils)
local u9 = require(v7.NumberUtils)
local v10 = u1:WaitForChild("Controllers")
require(v10.ShopController)
local u11 = require(v10.InterfaceController)
local v12 = u1:WaitForChild("Shared")
local u13 = require(v12.Marketplace)
local v14 = u1:WaitForChild("Packages")
local u15 = require(v14.Trove)
local u16 = require(v14.Timer)
local u17 = require(v14.Synchronizer)
local u18 = v3.LocalPlayer
local u19 = {}
u19.__index = u19
function u19.new(u20) --[[Anonymous function at line 76]]
--[[
Upvalues:
[1] = u17
[2] = u18
[3] = u19
[4] = u15
[5] = u5
[6] = u6
[7] = u9
[8] = u13
[9] = u2
[10] = u11
[11] = u16
[12] = u1
[13] = u8
--]]
local u21 = u17:Wait(u18)
local v22 = u19
local u23 = setmetatable({}, v22)
u23.Instance = u20
u23.Collector = u15.new()
local function u40() --[[Anonymous function at line 85]]
--[[
Upvalues:
[1] = u20
[2] = u5
[3] = u21
[4] = u6
[5] = u9
[6] = u13
--]]
local v24 = u20:WaitForChild("Main"):WaitForChild("SurfaceGui").Wheel
local v25 = v24.Items
local v26 = v24.Names
local v27 = v24.Odds
for v28 = 1, #u5.Rewards do
local v29 = u5.Rewards[v28]
if v29 then
if v29.Type == "Item" and u21:Get((("Items.%*"):format(v29.Index))) then
v29 = u5.AltRewards[v28]
end
local v30 = v25:FindFirstChild(v28)
local v31 = v26:FindFirstChild(v28)
local v32 = v27:FindFirstChild(v28)
local v33 = ""
local v34
if v29.Type == "Cash-Pack" then
local v35 = u6[v29.Index].Value
local v36 = u21:Get("Rebirth") or 0
if v36 > 0 then
v35 = v35 * (v36 <= 1 and 1.5 or v36)
end
v33 = ("$%*"):format((u9:ToString(v35, 2)))
v34 = u13:GetProductInfo(v29.Index, "Product").Icon
else
v34 = v29.Icon
end
local v37 = v29.Display
local v38 = v33 == "" and v37 and v37 or v33
local v39 = ("%*%%"):format(v29.Weight)
v30.Image = v34 or ""
v31.Text = v38
v32.Text = v39
end
end
end
u40()
u23.Collector:Add(u21:OnDictionaryInserted("Items", function(_, p41) --[[Anonymous function at line 143]]
--[[
Upvalues:
[1] = u5
[2] = u40
--]]
local v42 = false
for v43 = 1, #u5.Rewards do
local v44 = u5.Rewards[v43]
if v44.Type == "Item" and p41 == v44.Index then
v42 = true
break
end
end
if v42 then
u40()
end
end))
u23.Collector:Add(u2.RenderStepped:Connect(function(p45) --[[Anonymous function at line 157]]
--[[
Upvalues:
[1] = u23
--]]
local v46 = u23.Instance.Main
local v47 = v46.CFrame
local v48 = CFrame.Angles
local v49 = p45 * 45
v46.CFrame = v47 * v48(math.rad(v49), 0, 0)
end))
u23.Collector:Add(u23.Instance.Root.ProximityPrompt.Triggered:Connect(function() --[[Anonymous function at line 165]]
--[[
Upvalues:
[1] = u11
--]]
u11:Toggle("MoltenWheel", true)
end))
local v50 = u16.new(1)
u23.Collector:Add(v50, "Destroy")
u23.Collector:Add(v50.Tick:Connect(function() --[[Anonymous function at line 171]]
--[[
Upvalues:
[1] = u1
[2] = u21
[3] = u23
[4] = u8
--]]
if u1:GetAttribute("MoltenEvent") then
if u21:Get("MoltenSpinWheel.LastFreeClaimed") == u1:GetAttribute("MoltenEventLastTime") then
local v51 = u23.Instance.Overhead.BillboardGui.Countdown
local v52 = u8
local v53 = os.date("!*t", workspace:GetServerTimeNow()).wday
local v54 = (v53 == 1 or v53 == 7) and 3600 or 10800
v51.Text = ("Free Spin in %*"):format((v52:D(v54 - workspace:GetServerTimeNow() % v54)))
else
u23.Instance.Overhead.BillboardGui.Countdown.Text = "SPIN NOW"
end
else
local v55 = u23.Instance.Overhead.BillboardGui.Countdown
local v56 = u8
local v57 = os.date("!*t", workspace:GetServerTimeNow()).wday
local v58 = (v57 == 1 or v57 == 7) and 3600 or 10800
v55.Text = ("Free Spin in %*"):format((v56:D(v58 - workspace:GetServerTimeNow() % v58)))
return
end
end))
v50:StartNow()
return u23
end
function u19.Destroy(p59) --[[Anonymous function at line 189]]
p59.Collector:Destroy()
end
return u19 - Edit
03:12:20.373
- Edit
03:12:20.373
============================== - Edit
03:12:20.373 📜 ReplicatedStorage.Controllers.AnimationSyncController - Edit
03:12:20.373 ==============================
- Edit
03:12:20.373 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: AnimationSyncController, time of decompilation: Sat Jul 12 13:53:48 2025 ]]
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("RunService");
local _ = require(l_ReplicatedStorage_0.Packages.Observers);
local v3 = require(l_ReplicatedStorage_0.Packages.Timer);
local v4 = {};
local v5 = {};
local function _(v6, v7) --[[ Line: 12 ]] --[[ Name: sync ]]
local v8 = v7 % v6.Length;
if math.abs(v8 - v6.TimePosition) > 0.05 or v6.Length == 0 then
v6.TimePosition = v8;
end;
end;
local function v13(v10, v11) --[[ Line: 19 ]] --[[ Name: triggerResyncFor ]]
while v11 > 0 do
local v12 = os.clock() % v10.Length;
if math.abs(v12 - v10.TimePosition) > 0.05 or v10.Length == 0 then
v10.TimePosition = v12;
end;
v11 = v11 - task.wait();
end;
end;
v4.Add = function(_, v15) --[[ Line: 26 ]] --[[ Name: Add ]]
-- upvalues: v5 (copy), v13 (copy)
table.insert(v5, v15);
local v16 = task.spawn(v13, v15, 1);
return function() --[[ Line: 30 ]]
-- upvalues: v16 (copy), v5 (ref), v15 (copy)
if coroutine.status(v16) == "suspended" then
pcall(task.cancel, v16);
end;
local v17 = table.find(v5, v15);
if v17 then
table.remove(v5, v17);
end;
end;
end;
v3.Simple(1, function() --[[ Line: 42 ]]
-- upvalues: v5 (copy)
local v18 = os.clock();
for _, v20 in v5 do
local v21 = v18 % v20.Length;
if math.abs(v21 - v20.TimePosition) > 0.05 or v20.Length == 0 then
v20.TimePosition = v21;
end;
end;
end);
return v4; - Edit
03:12:20.373
- Edit
03:12:20.373
============================== - Edit
03:12:20.373 📜 ReplicatedStorage.Controllers.ConfirmationController - Edit
03:12:20.373 ==============================
- Edit
03:12:20.373 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: ConfirmationController, time of decompilation: Sat Jul 12 13:53:49 2025 ]]
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local l_Players_0 = game:GetService("Players");
local v2 = require(l_ReplicatedStorage_0.Packages.Signal);
local v3 = require(l_ReplicatedStorage_0.Classes.AnimatedButton);
local l_Confirmation_0 = l_Players_0.LocalPlayer.PlayerGui:WaitForChild("Confirmation");
local l_Template_0 = l_Confirmation_0:WaitForChild("Template");
local v6 = {};
local v7 = false;
v6.IsInPrompt = function(_) --[[ Line: 18 ]] --[[ Name: IsInPrompt ]]
-- upvalues: v7 (ref)
return v7;
end;
v6.Show = function(_, v10) --[[ Line: 22 ]] --[[ Name: Show ]]
-- upvalues: v7 (ref), v2 (copy), l_Template_0 (copy), l_Confirmation_0 (copy), v3 (copy)
while v7 do
task.wait();
end;
v7 = true;
v10 = v10 or "Do you really want to do this?";
local v11 = v2.new();
local v12 = l_Template_0:Clone();
v12.Name = "Confirmation";
v12.Parent = l_Confirmation_0;
v12.Visible = true;
local l_Description_0 = v12.Content.Description;
local l_Close_0 = v12.Close;
local l_Yes_0 = v12.Yes;
local l_No_0 = v12.No;
l_Description_0.Text = v10;
local function _() --[[ Line: 46 ]] --[[ Name: cleanup ]]
-- upvalues: v12 (copy)
v12:Destroy();
end;
local function _(v18) --[[ Line: 50 ]] --[[ Name: respond ]]
-- upvalues: v11 (copy)
v11:Fire(v18);
end;
local v20 = v3.new(l_Yes_0);
v20:Animate();
v20.OnActivated:Connect(function() --[[ Line: 56 ]]
-- upvalues: v11 (copy)
v11:Fire(true);
end);
local v21 = v3.new(l_No_0);
v21:Animate();
v21.OnActivated:Connect(function() --[[ Line: 62 ]]
-- upvalues: v11 (copy)
v11:Fire(false);
end);
local v22 = v3.new(l_Close_0);
v22:Animate();
v22.OnActivated:Connect(function() --[[ Line: 68 ]]
-- upvalues: v11 (copy)
v11:Fire(false);
end);
local v23 = v11:Wait();
v12:Destroy();
v11:Destroy();
v7 = false;
return v23;
end;
return v6; - Edit
03:12:20.373
- Edit
03:12:20.373
============================== - Edit
03:12:20.373 📜 ReplicatedStorage.Controllers.SpectateController - Edit
03:12:20.373 ==============================
- Edit
03:12:20.373 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Controllers = ReplicatedStorage:WaitForChild("Controllers")
local Classes = ReplicatedStorage:WaitForChild("Classes")
local Camera = workspace.CurrentCamera
local Net = require(ReplicatedStorage.Packages.Net)
local InterfaceController = require(Controllers.InterfaceController)
local AnimatedButton = require(Classes.AnimatedButton)
local NotificationController = require(Controllers.NotificationController)
local RemoteEvent = Net:RemoteEvent("ShopService/Purchase")
local SpectateUI = Player:WaitForChild("PlayerGui"):WaitForChild("Main"):WaitForChild("Spectate")
local TrollUI = Player:WaitForChild("PlayerGui"):WaitForChild("Main"):WaitForChild("Troll")
local Playerlist = {}
local currIndex = 1
local db = false
local currentTarget = nil
local notifyIfOpen
local function UpdatePlayers()
Playerlist = {}
for _, plr in ipairs(Players:GetPlayers()) do
if plr ~= Player then
table.insert(Playerlist, plr)
end
end
if currIndex > #Playerlist then
currIndex = 1
end
if #Playerlist == 0 then
currentTarget = nil
Camera.CameraSubject = Player.Character:FindFirstChild("Humanoid") or Player.Character:FindFirstChildWhichIsA("BasePart")
notifyIfOpen("No other players to spectate!")
end
end
local function UpdateCamera(player)
SpectateUI.Frame.PlayerName.Text = player.Name
Camera.CameraSubject = player.Character:FindFirstChild("Humanoid") or player.Character:FindFirstChildWhichIsA("BasePart")
currentTarget = player
end
local TrollProductIds = {
["Kill"] = 3341181646,
["Fling"] = 3341181173,
["Goto"] = 3341182175,
["ResetData"] = 3341180637,
}
notifyIfOpen = function(msg)
local ui = InterfaceController:Get("Spectate")
if ui and ui:IsOpened() then
NotificationController:Error(msg)
end
end
local SpectateController = {}
SpectateController.Start = function()
InterfaceController:Register("Spectate", SpectateUI, "TopSpectate");
InterfaceController:Register("Troll", TrollUI, "TopSpectate");
local spectateUIInterface = InterfaceController:Get("Spectate")
local trollUIInterface = InterfaceController:Get("Troll")
local function resetCameraToSelf()
if Player.Character then
Camera.CameraSubject = Player.Character:FindFirstChild("Humanoid") or Player.Character:FindFirstChildWhichIsA("BasePart")
end
end
if spectateUIInterface then
if spectateUIInterface:IsOpened() then
spectateUIInterface:Close()
end
spectateUIInterface.OnClose:Connect(function()
resetCameraToSelf()
currentTarget = nil
end)
end
if trollUIInterface and trollUIInterface:IsOpened() then
trollUIInterface:Close()
end
UpdatePlayers()
Players.PlayerAdded:Connect(UpdatePlayers)
Players.PlayerRemoving:Connect(UpdatePlayers)
local AnimatedButton1 = AnimatedButton.new(SpectateUI.Next)
AnimatedButton1:Animate()
AnimatedButton1.OnActivated:Connect(function()
if not db then
db = true
currIndex += 1
if currIndex > #Playerlist then
currIndex = 1
end
local selectedPlayer = Playerlist[currIndex]
warn(selectedPlayer)
if selectedPlayer then
UpdateCamera(selectedPlayer)
end
if #Playerlist == 0 then
notifyIfOpen("No other players to spectate!")
db = false
return
end
db = false
end
end)
local AnimatedButton2 = AnimatedButton.new(SpectateUI.Last)
AnimatedButton2:Animate()
AnimatedButton2.OnActivated:Connect(function()
if not db then
db = true
currIndex -= 1
if currIndex < 1 then
currIndex = #Playerlist
end
local selectedPlayer = Playerlist[currIndex]
warn(selectedPlayer)
if selectedPlayer then
UpdateCamera(selectedPlayer)
end
if #Playerlist == 0 then
notifyIfOpen("No other players to spectate!")
db = false
return
end
db = false
end
end)
local AnimatedButton3 = AnimatedButton.new(TrollUI.Fling)
local AnimatedButton4 = AnimatedButton.new(TrollUI.Kill)
local AnimatedButton5 = AnimatedButton.new(TrollUI.GoTO)
local ResetButton
for _, n in ipairs({"ResetData", "Reset", "ResetButton"}) do
local candidate = TrollUI:FindFirstChild(n)
if candidate then
ResetButton = candidate
break
end
end
if not ResetButton then
warn("[SpectateController] Reset button not found in TrollUI. Expected an object named 'ResetData', 'Reset', or 'ResetButton'.")
end
local AnimatedButton6
if ResetButton then
AnimatedButton6 = AnimatedButton.new(ResetButton)
AnimatedButton6:Animate()
end
AnimatedButton3:Animate()
AnimatedButton4:Animate()
AnimatedButton5:Animate()
AnimatedButton3.OnActivated:Connect(function()
if db then return end
if not currentTarget or not currentTarget.Parent then
notifyIfOpen("No valid target selected!")
return
end
db = true
local productId = TrollProductIds.Fling
RemoteEvent:FireServer(productId, currentTarget.UserId)
NotificationController:Notify(string.format("Prompting purchase: Fling %s", currentTarget.Name), 3)
task.delay(2, function()
db = false
end)
end)
AnimatedButton4.OnActivated:Connect(function()
if db then return end
if not currentTarget or not currentTarget.Parent then
notifyIfOpen("No valid target selected!")
return
end
db = true
local productId = TrollProductIds.Kill
RemoteEvent:FireServer(productId, currentTarget.UserId)
NotificationController:Notify(string.format("Prompting purchase: Kill %s", currentTarget.Name), 3)
task.delay(2, function()
db = false
end)
end)
AnimatedButton5.OnActivated:Connect(function()
if db then return end
if not currentTarget or not currentTarget.Parent then
notifyIfOpen("No valid target selected!")
return
end
db = true
local productId = TrollProductIds.Goto
RemoteEvent:FireServer(productId, currentTarget.UserId)
NotificationController:Notify(string.format("Prompting purchase: Goto %s", currentTarget.Name), 3)
task.delay(2, function()
db = false
end)
end)
if AnimatedButton6 then
AnimatedButton6.OnActivated:Connect(function()
if db then return end
if not currentTarget or not currentTarget.Parent then
notifyIfOpen("No valid target selected!")
return
end
db = true
local productId = TrollProductIds.ResetData
RemoteEvent:FireServer(productId, currentTarget.UserId)
NotificationController:Notify(string.format("Prompting purchase: Reset data of %s", currentTarget.Name), 3)
task.delay(2, function()
db = false
end)
end)
end
end
return SpectateController
- Edit
03:12:20.374
- Edit
03:12:20.374
============================== - Edit
03:12:20.374 📜 ReplicatedStorage.Controllers.ItemController - Edit
03:12:20.374 ==============================
- Edit
03:12:20.374 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: ItemController, time of decompilation: Sat Jul 5 18:09:11 2025 ]]
local l_Players_0 = game:GetService("Players");
local _ = game:GetService("StarterGui");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v4 = require(l_Packages_0.Net);
local v5 = require(l_ReplicatedStorage_0.Controllers.BackpackController);
local l_LocalPlayer_0 = l_Players_0.LocalPlayer;
local l_PlayerGui_0 = l_LocalPlayer_0.PlayerGui;
local l_Backpack_0 = l_LocalPlayer_0.Backpack;
local l_Backpack_1 = l_PlayerGui_0:WaitForChild("BackpackGui").Backpack;
local l_Hotbar_0 = l_Backpack_1.Hotbar;
local _ = l_Backpack_1.Inventory;
local l_Highlight_0 = Instance.new("Highlight");
l_Highlight_0.Name = "MainHighlight";
l_Highlight_0.DepthMode = Enum.HighlightDepthMode.Occluded;
l_Highlight_0.FillColor = Color3.fromRGB(255, 0, 0);
l_Highlight_0.FillTransparency = 0.5;
l_Highlight_0.OutlineColor = Color3.fromRGB(155, 0, 0);
l_Highlight_0.OutlineTransparency = 0.8;
l_Highlight_0.Parent = workspace;
l_Highlight_0.Adornee = script;
local v13 = {};
local function v21(v14) --[[ Line: 30 ]] --[[ Name: CooldownFunction ]]
-- upvalues: l_Hotbar_0 (copy)
local l_v14_Attribute_0 = v14:GetAttribute("CurrentSlot");
local v16 = tonumber(v14:GetAttribute("CooldownTime") or 0);
local l_l_Hotbar_0_FirstChild_0 = l_Hotbar_0:FindFirstChild(l_v14_Attribute_0);
if not l_l_Hotbar_0_FirstChild_0 then
return;
else
local l_Icon_0 = l_l_Hotbar_0_FirstChild_0:FindFirstChild("Icon");
if not l_Icon_0 then
return;
else
local v19 = v16 > 0;
local l_CooldownTextLabel_0 = l_Icon_0:FindFirstChild("CooldownTextLabel");
if l_CooldownTextLabel_0 then
l_CooldownTextLabel_0.Text = v16;
l_CooldownTextLabel_0.Visible = v19;
end;
l_Icon_0.ImageColor3 = v19 and Color3.fromRGB(90, 90, 90) or Color3.fromRGB(255, 255, 255);
return;
end;
end;
end;
local function v23(v22) --[[ Line: 54 ]] --[[ Name: SetupTool ]]
-- upvalues: v21 (copy)
v22:GetAttributeChangedSignal("CooldownTime"):Connect(function() --[[ Line: 55 ]]
-- upvalues: v21 (ref), v22 (copy)
v21(v22);
end);
v22:GetAttributeChangedSignal("CurrentSlot"):Connect(function() --[[ Line: 59 ]]
-- upvalues: v21 (ref), v22 (copy)
v21(v22);
end);
end;
v13.Load = function(_) --[[ Line: 64 ]] --[[ Name: Load ]]
for _, v26 in script:GetChildren() do
if v26:IsA("ModuleScript") then
local l_status_0, l_result_0 = pcall(require, v26);
if l_status_0 and l_result_0 and l_result_0.Start then
l_result_0:Start();
end;
end;
end;
end;
v13.Start = function(_) --[[ Line: 77 ]] --[[ Name: Start ]]
-- upvalues: v5 (copy), l_LocalPlayer_0 (copy), l_Backpack_0 (copy), v23 (copy), v4 (copy)
local function v30() --[[ Line: 78 ]] --[[ Name: updateBlockTools ]]
-- upvalues: v5 (ref), l_LocalPlayer_0 (ref)
v5:SetEnabled("BlockTools", not l_LocalPlayer_0:GetAttribute("BlockTools"));
end;
l_LocalPlayer_0:GetAttributeChangedSignal("BlockTools"):Connect(v30);
task.spawn(v30);
for _, v32 in l_Backpack_0:GetChildren() do
if v32:IsA("Tool") then
task.spawn(v23, v32);
end;
end;
l_Backpack_0.ChildAdded:Connect(function(v33) --[[ Line: 91 ]]
-- upvalues: v23 (ref)
if v33:IsA("Tool") then
v23(v33);
end;
end);
v4:RemoteEvent("Tools/Cooldown").OnClientEvent:Connect(function(v34, v35) --[[ Line: 97 ]]
for v36 = v35, 0, -1 do
v34:SetAttribute("CooldownTime", v36);
task.wait(1);
end;
v34:SetAttribute("CooldownTime", nil);
end);
end;
return v13; - Edit
03:12:20.374
- Edit
03:12:20.374
============================== - Edit
03:12:20.374 📜 ReplicatedStorage.Controllers.ItemController.BeeLauncherController - Edit
03:12:20.374 ==============================
- Edit
03:12:20.374 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: BeeLauncherController, time of decompilation: Sat Jul 5 18:09:11 2025 ]]
local l_Players_0 = game:GetService("Players");
local l_Lighting_0 = game:GetService("Lighting");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local l_PlayerScripts_0 = l_Players_0.LocalPlayer.PlayerScripts;
local l_CurrentCamera_0 = workspace.CurrentCamera;
local l_Controls_0 = require(l_PlayerScripts_0:WaitForChild("PlayerModule")):GetControls();
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v7 = require(l_Packages_0.Net);
local l_Buzzing_0 = script.Buzzing;
local v9 = v7:RemoteEvent("UseItem");
local l_moveFunction_0 = l_Controls_0.moveFunction;
local v11 = {};
v9.OnClientEvent:Connect(function(v12) --[[ Line: 23 ]]
-- upvalues: l_CurrentCamera_0 (copy), l_Buzzing_0 (copy), l_Controls_0 (copy), l_Lighting_0 (copy), l_moveFunction_0 (copy)
if v12 ~= "Bee Attack" then
return;
else
l_CurrentCamera_0.FieldOfView = 20;
l_Buzzing_0:Play();
l_Controls_0.moveFunction = function(v13, v14, v15) --[[ Line: 30 ]]
v13:Move(-v14, v15);
end;
local v16 = script.ColorCorrection:Clone();
v16.Parent = l_Lighting_0;
local l_BlurEffect_0 = Instance.new("BlurEffect");
l_BlurEffect_0.Size = 10;
l_BlurEffect_0.Name = "BeeBlur";
l_BlurEffect_0.Parent = l_Lighting_0;
task.delay(5, function() --[[ Line: 42 ]]
-- upvalues: l_Controls_0 (ref), l_moveFunction_0 (ref), l_CurrentCamera_0 (ref), v16 (copy), l_BlurEffect_0 (copy)
l_Controls_0.moveFunction = l_moveFunction_0;
l_CurrentCamera_0.FieldOfView = 70;
v16:Destroy();
l_BlurEffect_0:Destroy();
end);
return;
end;
end);
return v11; - Edit
03:12:20.374
- Edit
03:12:20.374
============================== - Edit
03:12:20.374 📜 ReplicatedStorage.Controllers.ItemController.BoogieBombController - Edit
03:12:20.374 ==============================
- Edit
03:12:20.374 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: BoogieBombController, time of decompilation: Sat Jul 5 18:09:11 2025 ]]
local l_Players_0 = game:GetService("Players");
local l_Lighting_0 = game:GetService("Lighting");
local l_TweenService_0 = game:GetService("TweenService");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = l_Players_0.LocalPlayer;
local l_CurrentCamera_0 = workspace.CurrentCamera;
local l_Shared_0 = l_ReplicatedStorage_0:WaitForChild("Shared");
local v7 = require(l_Shared_0.ShakePresets);
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v9 = require(l_Packages_0.Trove);
local v10 = require(l_Packages_0.Net);
local v11 = require("../CameraController");
local v12 = v10:RemoteEvent("UseItem");
local v13 = v9.new();
local l_BOOM_0 = script.BOOM;
local v15 = TweenInfo.new(0.4, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, -1, true);
local v16 = TweenInfo.new(0.3, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, -1, true);
local v17 = {};
v12.OnClientEvent:Connect(function(v18) --[[ Line: 28 ]]
-- upvalues: l_Lighting_0 (copy), l_BOOM_0 (copy), l_TweenService_0 (copy), l_CurrentCamera_0 (copy), v16 (copy), v15 (copy), v7 (copy), v13 (copy), v11 (copy)
if v18 ~= "Boogie" then
return;
else
local l_ColorCCorrection_0 = l_Lighting_0:FindFirstChild("ColorCCorrection");
if l_ColorCCorrection_0 then
l_ColorCCorrection_0.Enabled = false;
end;
l_BOOM_0:Play();
local l_ColorCorrectionEffect_0 = Instance.new("ColorCorrectionEffect");
l_ColorCorrectionEffect_0.TintColor = Color3.fromRGB(255, 255, 255);
l_ColorCorrectionEffect_0.Name = "DiscoEffect";
l_ColorCorrectionEffect_0.Saturation = -0.2;
l_ColorCorrectionEffect_0.Brightness = 0.1;
l_ColorCorrectionEffect_0.Contrast = 0.1;
l_ColorCorrectionEffect_0.Parent = l_Lighting_0;
local l_BlurEffect_0 = Instance.new("BlurEffect");
l_BlurEffect_0.Size = 3;
l_BlurEffect_0.Parent = l_Lighting_0;
local v22 = l_TweenService_0:Create(l_CurrentCamera_0, v16, {
FieldOfView = 80
});
local v23 = l_TweenService_0:Create(l_ColorCorrectionEffect_0, v15, {
Brightness = 0.25
});
v23:Play();
v22:Play();
local v24 = v7.Bump:Clone();
v13:Add(v24);
v24.Sustain = true;
v13:Add(v7.BindShakeToCamera(v24, l_CurrentCamera_0));
v24:Start();
v13:Add(task.delay(10, function() --[[ Line: 61 ]]
-- upvalues: v24 (copy)
v24:StopSustain();
end));
task.delay(10, function() --[[ Line: 65 ]]
-- upvalues: v23 (copy), l_ColorCorrectionEffect_0 (copy), v22 (copy), l_BOOM_0 (ref), l_BlurEffect_0 (copy), l_CurrentCamera_0 (ref), v11 (ref), l_Lighting_0 (ref), l_ColorCCorrection_0 (copy)
v23:Cancel();
l_ColorCorrectionEffect_0:Destroy();
v22:Cancel();
l_BOOM_0:Stop();
l_BlurEffect_0:Destroy();
task.wait();
l_CurrentCamera_0.FieldOfView = v11:GetDefaultFov();
l_Lighting_0.Ambient = Color3.fromRGB(255, 255, 255);
l_Lighting_0.OutdoorAmbient = Color3.fromRGB(212, 212, 212);
if l_ColorCCorrection_0 then
l_ColorCCorrection_0.Enabled = true;
end;
end);
return;
end;
end);
return v17; - Edit
03:12:20.374
- Edit
03:12:20.374
============================== - Edit
03:12:20.374 📜 ReplicatedStorage.Controllers.ItemController.WebSlingerController - Edit
03:12:20.374 ==============================
- Edit
03:12:20.375 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: WebSlingerController, time of decompilation: Sat Jul 5 18:09:11 2025 ]]
local l_Players_0 = game:GetService("Players");
local _ = game:GetService("Lighting");
local _ = game:GetService("TweenService");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = l_Players_0.LocalPlayer;
local _ = workspace.CurrentCamera;
local l_Controllers_0 = l_ReplicatedStorage_0:WaitForChild("Controllers");
local _ = require(l_Controllers_0.CharacterController);
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local _ = require(l_Packages_0.Net);
return {}; - Edit
03:12:20.375
- Edit
03:12:20.375
============================== - Edit
03:12:20.375 📜 ReplicatedStorage.Controllers.ItemController.PaintballGunController - Edit
03:12:20.375 ==============================
- Edit
03:12:20.375 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: PaintballGunController, time of decompilation: Sat Jul 5 18:09:12 2025 ]]
local _ = game:GetService("Debris");
local l_Players_0 = game:GetService("Players");
local _ = game:GetService("RunService");
local l_TweenService_0 = game:GetService("TweenService");
local _ = game:GetService("CollectionService");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("ServerScriptService");
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v8 = require(l_Packages_0.Net);
local _ = require(l_Packages_0.Debounce);
local l_Main_0 = l_Players_0.LocalPlayer.PlayerGui:WaitForChild("Main");
local v11 = {};
v8:RemoteEvent("Paintball/ShotPlayer").OnClientEvent:Connect(function(v12, v13) --[[ Line: 20 ]]
-- upvalues: l_Main_0 (copy), l_TweenService_0 (copy)
if v12 ~= "PaintballHitted" then
return;
else
local v14 = 1;
local v15 = v13 or math.random(1, 2);
for _ = v14, v15 do
local v17 = script:GetChildren()[math.random(#script:GetChildren())]:Clone();
v17.Parent = l_Main_0;
v17.Rotation = math.random(360);
v17.Position = UDim2.new(math.random(10, 90) / 100, 0, math.random(10, 90) / 100, 0);
v17.ImageColor3 = Color3.fromRGB(math.random(255), math.random(255), math.random(255));
task.delay(v13 and 2 or 4, function() --[[ Line: 31 ]]
-- upvalues: l_TweenService_0 (ref), v17 (copy)
local v18 = l_TweenService_0:Create(v17, TweenInfo.new(0.6, Enum.EasingStyle.Quart, Enum.EasingDirection.In), {
Size = UDim2.new()
});
v18:Play();
v18.Completed:Wait();
v17:Destroy();
end);
end;
return;
end;
end);
return v11; - Edit
03:12:20.375
- Edit
03:12:20.375
============================== - Edit
03:12:20.375 📜 ReplicatedStorage.Controllers.ItemController.FreezeRayController - Edit
03:12:20.375 ==============================
- Edit
03:12:20.375 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: FreezeRayController, time of decompilation: Sat Jul 5 18:09:12 2025 ]]
local l_Debris_0 = game:GetService("Debris");
local l_Players_0 = game:GetService("Players");
local _ = game:GetService("RunService");
local l_SoundService_0 = game:GetService("SoundService");
local l_TweenService_0 = game:GetService("TweenService");
local _ = game:GetService("CollectionService");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("ServerScriptService");
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v9 = require(l_Packages_0.Net);
local _ = require(l_Packages_0.Debounce);
local l_UI_0 = l_SoundService_0:WaitForChild("ToolsSounds").UI;
local l_LocalPlayer_0 = l_Players_0.LocalPlayer;
local l_MainFrame_0 = l_LocalPlayer_0.PlayerGui:WaitForChild("ToolsScreen").MainFrame;
local v14 = {};
local v15 = {};
v9:RemoteEvent("FreezeRay/Escape").OnClientEvent:Connect(function(v16) --[[ Line: 26 ]]
-- upvalues: l_MainFrame_0 (copy), l_TweenService_0 (copy), l_UI_0 (copy), l_Debris_0 (copy), v9 (copy), v15 (copy), l_LocalPlayer_0 (copy)
if v16 ~= "ShowTargets" then
return;
else
for _ = 1, 10 do
local v18 = script.Target:Clone();
v18.Size = UDim2.new();
v18.Position = UDim2.new(math.random(10, 90) / 100, 0, math.random(10, 90) / 100, 0);
v18.Parent = l_MainFrame_0;
l_TweenService_0:Create(v18, TweenInfo.new(0.6, Enum.EasingStyle.Quart, Enum.EasingDirection.In), {
Size = UDim2.new(0.079, 0, 0.125, 0)
}):Play();
local v19 = l_UI_0.FreezeRayShow:Clone();
v19.Parent = l_UI_0;
task.wait();
v19:Play();
l_Debris_0:AddItem(v19, 2);
v18.MouseButton1Down:Connect(function() --[[ Line: 48 ]]
-- upvalues: v9 (ref), v18 (copy), l_UI_0 (ref), l_Debris_0 (ref), v15 (ref)
v9:RemoteEvent("FreezeRay/Escape"):FireServer();
if v18 and v18.Parent then
local v20 = l_UI_0.FreezeRaySuccess:Clone();
v20.Parent = l_UI_0;
task.wait();
v20:Play();
l_Debris_0:AddItem(v20, 2);
table.remove(v15, table.find(v15, v18));
v18:Destroy();
end;
end);
task.delay(math.random(4, 6), function() --[[ Line: 63 ]]
-- upvalues: v18 (copy), v15 (ref), l_UI_0 (ref), l_Debris_0 (ref)
if v18 and v18.Parent then
table.remove(v15, table.find(v15, v18));
v18:Destroy();
local v21 = l_UI_0.FreezeRayWrong:Clone();
v21.Parent = l_UI_0;
task.wait();
v21:Play();
l_Debris_0:AddItem(v21, 2);
end;
end);
table.insert(v15, v18);
if l_LocalPlayer_0:GetAttribute("StopFreeze") then
for _, v23 in v15 do
if v23 and v23.Parent then
v23:Destroy();
end;
end;
table.clear(v15);
return;
else
local v24 = math.random(1, 3) / 10;
task.wait(0.7 + v24);
end;
end;
return;
end;
end);
return v14; - Edit
03:12:20.375
- Edit
03:12:20.375
============================== - Edit
03:12:20.375 📜 ReplicatedStorage.Controllers.ItemController.TrapController - Edit
03:12:20.375 ==============================
- Edit
03:12:20.375 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: TrapController, time of decompilation: Sat Jul 5 18:09:12 2025 ]]
local l_Players_0 = game:GetService("Players");
local _ = game:GetService("Lighting");
local _ = game:GetService("TweenService");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = l_Players_0.LocalPlayer;
local _ = workspace.CurrentCamera;
local l_Controllers_0 = l_ReplicatedStorage_0:WaitForChild("Controllers");
local _ = require(l_Controllers_0.CharacterController);
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v9 = require(l_Packages_0.Net):RemoteEvent("UseItem");
local v10 = {};
v9.OnClientEvent:Connect(function(v11, v12, v13) --[[ Line: 20 ]]
if v11 ~= "Trapped" then
return;
elseif v12 ~= "PlaySound" then
return;
else
local l_v13_FirstChildWhichIsA_0 = v13:FindFirstChildWhichIsA("Sound", true);
if l_v13_FirstChildWhichIsA_0 then
l_v13_FirstChildWhichIsA_0:Play();
end;
return;
end;
end);
return v10; - Edit
03:12:20.375
- Edit
03:12:20.375
============================== - Edit
03:12:20.375 📜 ReplicatedStorage.Controllers.ItemController.CandyLauncherController - Edit
03:12:20.375 ==============================
- Edit
03:12:20.376 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: CandyLauncherController, time of decompilation: Sat Jul 5 18:09:12 2025 ]]
local l_Players_0 = game:GetService("Players");
local l_Lighting_0 = game:GetService("Lighting");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local l_PlayerScripts_0 = l_Players_0.LocalPlayer.PlayerScripts;
local l_CurrentCamera_0 = workspace.CurrentCamera;
local _ = require(l_PlayerScripts_0:WaitForChild("PlayerModule")):GetControls();
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v7 = require(l_Packages_0.Net):RemoteEvent("CandlyLauncher/Launch");
local v8 = {};
v7.OnClientEvent:Connect(function(v9) --[[ Line: 19 ]]
-- upvalues: l_CurrentCamera_0 (copy), l_Lighting_0 (copy)
if v9 ~= "TurnIntoJelly" then
return;
else
l_CurrentCamera_0.FieldOfView = 20;
local v10 = script.ColorCorrection:Clone();
v10.Parent = l_Lighting_0;
task.delay(5, function() --[[ Line: 28 ]]
-- upvalues: l_CurrentCamera_0 (ref), v10 (copy)
l_CurrentCamera_0.FieldOfView = 70;
v10:Destroy();
end);
return;
end;
end);
return v8; - Edit
03:12:20.376
- Edit
03:12:20.376
============================== - Edit
03:12:20.376 📜 ReplicatedStorage.Controllers.ItemController.CandyBombController - Edit
03:12:20.376 ==============================
- Edit
03:12:20.376 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: CandyBombController, time of decompilation: Sat Jul 5 18:09:12 2025 ]]
local l_Players_0 = game:GetService("Players");
local l_Lighting_0 = game:GetService("Lighting");
local _ = game:GetService("TweenService");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = l_Players_0.LocalPlayer;
local l_CurrentCamera_0 = workspace.CurrentCamera;
local l_Shared_0 = l_ReplicatedStorage_0:WaitForChild("Shared");
local _ = require(l_Shared_0.ShakePresets);
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v9 = require(l_Packages_0.Trove);
local v10 = require(l_Packages_0.Net);
local _ = require("../CameraController");
local v12 = v10:RemoteEvent("CandyBomb/Throw");
local _ = v9.new();
local _ = TweenInfo.new(0.4, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, -1, true);
local _ = TweenInfo.new(0.3, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, -1, true);
local v16 = {};
v12.OnClientEvent:Connect(function(v17, v18) --[[ Line: 28 ]]
-- upvalues: l_CurrentCamera_0 (copy), l_Lighting_0 (copy)
if v17 ~= "CandyEffect" then
return;
else
l_CurrentCamera_0.FieldOfView = 20;
local v19 = script.ColorCorrection:Clone();
v19.Parent = l_Lighting_0;
task.delay(v18 or 10, function() --[[ Line: 38 ]]
-- upvalues: l_CurrentCamera_0 (ref), v19 (copy)
l_CurrentCamera_0.FieldOfView = 70;
v19:Destroy();
end);
return;
end;
end);
return v16; - Edit
03:12:20.376
- Edit
03:12:20.376
============================== - Edit
03:12:20.376 📜 ReplicatedStorage.Controllers.ItemController.ConfettiLauncherController - Edit
03:12:20.376 ==============================
- Edit
03:12:20.376 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: ConfettiLauncherController, time of decompilation: Sat Jul 5 18:09:12 2025 ]]
local l_Players_0 = game:GetService("Players");
local _ = game:GetService("Lighting");
local l_TweenService_0 = game:GetService("TweenService");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local l_LocalPlayer_0 = l_Players_0.LocalPlayer;
local l_PlayerGui_0 = l_LocalPlayer_0.PlayerGui;
local l_PlayerScripts_0 = l_LocalPlayer_0.PlayerScripts;
local _ = require(l_PlayerScripts_0:WaitForChild("PlayerModule")):GetControls();
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v9 = require(l_Packages_0.Net);
local l_ConfettiHolder_0 = l_PlayerGui_0:WaitForChild("ToolsScreen").MainFrame.ConfettiHolder;
local v11 = v9:RemoteEvent("UseItem");
local l_ConfettiSizes_0 = script.ConfettiSizes;
local v13 = Random.new();
local v14 = TweenInfo.new(v13:NextNumber(1, 2.5), Enum.EasingStyle.Sine, Enum.EasingDirection.In);
local v15 = {
Color3.fromRGB(255, 55, 55),
Color3.fromRGB(55, 255, 55),
Color3.fromRGB(255, 225, 0),
Color3.fromRGB(0, 75, 255),
Color3.fromRGB(0, 225, 255),
Color3.fromRGB(255, 200, 0),
Color3.fromRGB(255, 125, 0),
Color3.fromRGB(225, 0, 255),
Color3.fromRGB(55, 255, 125),
Color3.fromRGB(255, 0, 255),
Color3.fromRGB(255, 0, 0)
};
local v16 = {};
v11.OnClientEvent:Connect(function(v17) --[[ Line: 47 ]]
-- upvalues: l_ConfettiSizes_0 (copy), v15 (copy), v13 (copy), l_ConfettiHolder_0 (copy), l_TweenService_0 (copy), v14 (copy)
if v17 ~= "Confetti Launcher" then
return;
else
for _ = 1, 500 do
local v19 = l_ConfettiSizes_0[math.random(1, #l_ConfettiSizes_0:GetChildren())]:Clone();
v19.BackgroundColor3 = v15[math.random(1, #v15)];
v19.Position = UDim2.new(v13:NextNumber(-0.3, 1.3), 0, -0.2, 0);
v19.Rotation = v13:NextNumber(10, 360);
v19.Visible = true;
v19.Parent = l_ConfettiHolder_0;
l_TweenService_0:Create(v19, v14, {
Position = UDim2.fromScale(v19.Position.X.Scale, 1.5)
}):Play();
task.wait(0.01);
end;
task.wait(7);
l_ConfettiHolder_0:ClearAllChildren();
return;
end;
end);
return v16; - Edit
03:12:20.376
- Edit
03:12:20.376
============================== - Edit
03:12:20.376 📜 ReplicatedStorage.Controllers.ItemController.NightVisionController - Edit
03:12:20.376 ==============================
- Edit
03:12:20.376 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: NightVisionController, time of decompilation: Sat Jul 12 14:21:20 2025 ]]
local l_Players_0 = game:GetService("Players");
local _ = game:GetService("Lighting");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local l_LocalPlayer_0 = l_Players_0.LocalPlayer;
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v5 = require(l_Packages_0.Net):RemoteEvent("UseItem");
local l_NightVision_0 = script.NightVision;
local l_Nickname_0 = script.Nickname;
local v8 = false;
local v9 = {};
local function v15() --[[ Line: 19 ]] --[[ Name: Disable ]]
-- upvalues: l_Players_0 (copy)
for _, v11 in l_Players_0:GetPlayers() do
task.spawn(function() --[[ Line: 21 ]]
-- upvalues: v11 (copy)
local v12 = v11.Character or v11.CharacterAdded:Wait();
if v12 then
for _, v14 in v12:GetDescendants() do
if v14.Name == "NightVisionGoogles" then
v14:Destroy();
end;
end;
end;
end);
end;
end;
local function v24(v16) --[[ Line: 34 ]] --[[ Name: CreateVisionPartsOnPlayer ]]
-- upvalues: l_LocalPlayer_0 (copy), l_NightVision_0 (copy), l_Nickname_0 (copy)
local v17 = v16.Character or v16.CharacterAdded:Wait();
local l_Head_0 = v17:WaitForChild("Head");
if v16.Name ~= l_LocalPlayer_0.Name then
for _, v20 in v17:GetChildren() do
if v20:IsA("BasePart") and v20:FindFirstChild("NightVisionGoogles") == nil then
for v21 = 1, 6 do
local v22 = l_NightVision_0:Clone();
v22.Parent = v20;
v22.Face = v21 - 1;
v22.Name = "NightVisionGoogles";
end;
end;
end;
local v23 = l_Nickname_0:Clone();
v23.TextLabel.Text = v16.Name;
v23.Parent = l_Head_0;
v23.Name = "NightVisionGoogles";
end;
end;
local function v27() --[[ Line: 55 ]] --[[ Name: Enable ]]
-- upvalues: l_Players_0 (copy), v24 (copy)
for _, v26 in l_Players_0:GetPlayers() do
task.spawn(function() --[[ Line: 57 ]]
-- upvalues: v24 (ref), v26 (copy)
v24(v26);
end);
end;
end;
v5.OnClientEvent:Connect(function(v28, v29) --[[ Line: 63 ]]
-- upvalues: v15 (copy), v27 (copy), v8 (ref)
if v28 ~= "EnableNightVision" then
return;
else
if not v29 then
v15();
else
v27();
end;
v8 = v29;
return;
end;
end);
l_Players_0.PlayerAdded:Connect(function(v30) --[[ Line: 75 ]]
-- upvalues: v8 (ref), v24 (copy)
if v8 then
v24(v30);
end;
end);
v9.Enable = v27;
v9.Disable = v15;
return v9; - Edit
03:12:20.376
- Edit
03:12:20.376
============================== - Edit
03:12:20.377 📜 ReplicatedStorage.Controllers.BackpackController - Edit
03:12:20.377 ==============================
- Edit
03:12:20.377 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: BackpackController, time of decompilation: Sat Jul 5 18:09:13 2025 ]]
local v0 = require(script.Utils.Satchel);
local v1 = {
States = {}
};
v1.Update = function(_) --[[ Line: 8 ]] --[[ Name: Update ]]
-- upvalues: v0 (copy), v1 (copy)
v0:SetBackpackEnabled(next(v1.States) == nil);
end;
v1.SetEnabled = function(_, v4, v5) --[[ Line: 12 ]] --[[ Name: SetEnabled ]]
-- upvalues: v1 (copy)
v1.States[v4] = not v5 or nil;
v1:Update();
end;
return v1; - Edit
03:12:20.377
- Edit
03:12:20.377
============================== - Edit
03:12:20.377 📜 ReplicatedStorage.Controllers.BackpackController.Utils.Satchel - Edit
03:12:20.377 ==============================
- Edit
03:12:20.378 --!strict
--!nolint DeprecatedApi
--[[
Name: Satchel
Version: 1.3.1
Description: Satchel is a modern open-source alternative to Roblox's default backpack. Satchel aims to be more customizable and easier to use than the default backpack while still having a "vanilla" feel.
By: @WinnersTakesAll on Roblox & @RyanLua on GitHub
Acknowledgements (@Roblox):
@OnlyTwentyCharacters, @SolarCrane -- For creating the CoreGui script
@thebrickplanetboy -- For allowing me to republish his fork of the backpack system.
@ForeverHD -- Making Topbar Plus and open-sourcing it for everyone to use
DevForum: https://devforum.roblox.com/t/2451549
]]
--[[
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at Mozilla Public License Version 2.0.
]]
local ContextActionService = game:GetService("ContextActionService")
local TextChatService = game:GetService("TextChatService")
local UserInputService = game:GetService("UserInputService")
local StarterGui = game:GetService("StarterGui")
repeat task.wait() until pcall(function() return StarterGui:GetCore("TopbarEnabled") end) -- Prevent any not registered errors
local GuiService = game:GetService("GuiService")
local RunService = game:GetService("RunService")
local VRService = game:GetService("VRService")
local Players = game:GetService("Players")
local PlayerGui: Instance = Players.LocalPlayer:WaitForChild("PlayerGui")
local BackpackScript = {}
BackpackScript.OpenClose = nil :: any -- Function to toggle open/close
BackpackScript.IsOpen = false :: boolean
BackpackScript.StateChanged = Instance.new("BindableEvent") :: BindableEvent -- Fires after any open/close, passes IsNowOpen
BackpackScript.ModuleName = "Backpack" :: string
BackpackScript.KeepVRTopbarOpen = true :: boolean
BackpackScript.VRIsExclusive = true :: boolean
BackpackScript.VRClosesNonExclusive = true :: boolean
BackpackScript.BackpackEmpty = Instance.new("BindableEvent") :: BindableEvent -- Fires when the backpack is empty (no tools
BackpackScript.BackpackEmpty.Name = "BackpackEmpty"
BackpackScript.BackpackItemAdded = Instance.new("BindableEvent") :: BindableEvent -- Fires when an item is added to the backpack
BackpackScript.BackpackItemAdded.Name = "BackpackAdded"
BackpackScript.BackpackItemRemoved = Instance.new("BindableEvent") :: BindableEvent -- Fires when an item is removed from the backpack
BackpackScript.BackpackItemRemoved.Name = "BackpackRemoved"
local targetScript: ModuleScript = script
-- Constants --
local PREFERRED_TRANSPARENCY: number = GuiService.PreferredTransparency or 1
-- Legacy behavior for backpack
local LEGACY_EDGE_ENABLED: boolean = not targetScript:GetAttribute("OutlineEquipBorder") or false -- Instead of the edge selection being inset, it will be on the outlined. LEGACY_PADDING must be enabled for this to work or this will do nothing
local LEGACY_PADDING_ENABLED: boolean = targetScript:GetAttribute("InsetIconPadding") -- Instead of the icon taking up the full slot, it will be padded on each side.
-- Background
local BACKGROUND_TRANSPARENCY_DEFAULT: number = targetScript:GetAttribute("BackgroundTransparency") or 0.3
local BACKGROUND_TRANSPARENCY: number = BACKGROUND_TRANSPARENCY_DEFAULT * PREFERRED_TRANSPARENCY
local BACKGROUND_CORNER_RADIUS: UDim = UDim.new(0, 8)
local BACKGROUND_COLOR: Color3 = targetScript:GetAttribute("BackgroundColor3")
or Color3.new(25 / 255, 27 / 255, 29 / 255)
-- Slots
local SLOT_EQUIP_COLOR: Color3 = targetScript:GetAttribute("EquipBorderColor3") or Color3.new(0 / 255, 162 / 255, 1)
local SLOT_LOCKED_TRANSPARENCY_DEFAULT: number = targetScript:GetAttribute("BackgroundTransparency") or 0.3 -- Locked means undraggable
local SLOT_LOCKED_TRANSPARENCY: number = SLOT_LOCKED_TRANSPARENCY_DEFAULT * PREFERRED_TRANSPARENCY
local SLOT_EQUIP_THICKNESS: number = targetScript:GetAttribute("EquipBorderSizePixel") or 5 -- Relative
local SLOT_CORNER_RADIUS: UDim = targetScript:GetAttribute("CornerRadius") or UDim.new(0, 8)
local SLOT_BORDER_COLOR: Color3 = Color3.new(1, 1, 1) -- Appears when dragging
-- Tooltips
local TOOLTIP_CORNER_RADIUS: UDim = SLOT_CORNER_RADIUS - UDim.new(0, 5) or UDim.new(0, 3)
local TOOLTIP_BACKGROUND_COLOR: Color3 = targetScript:GetAttribute("BackgroundColor3")
or Color3.new(25 / 255, 27 / 255, 29 / 255)
local TOOLTIP_PADDING: number = 4
local TOOLTIP_HEIGHT: number = 16
local TOOLTIP_OFFSET: number = -5 -- From to
-- Topbar icons
local ARROW_IMAGE_OPEN: string = "rbxasset://textures/ui/TopBar/inventoryOn.png"
local ARROW_IMAGE_CLOSE: string = "rbxasset://textures/ui/TopBar/inventoryOff.png"
-- local ARROW_HOTKEY: { Enum.KeyCode } = { Enum.KeyCode.Backquote, Enum.KeyCode.DPadUp } --TODO: Hookup '~' too?
-- Hotbar slots
local HOTBAR_SLOTS_FULL: number = 10 -- 10 is the max
local HOTBAR_SLOTS_VR: number = 6
local HOTBAR_SLOTS_MINI: number = 6 -- Mobile gets 6 slots instead of default 3 it had before
local HOTBAR_SLOTS_WIDTH_CUTOFF: number = 1024 -- Anything smaller is MINI
local INVENTORY_ROWS_FULL: number = 4
local INVENTORY_ROWS_VR: number = 3
local INVENTORY_ROWS_MINI: number = 2
local INVENTORY_HEADER_SIZE: number = 40
local INVENTORY_ARROWS_BUFFER_VR: number = 40
-- Text
local TEXT_COLOR: Color3 = targetScript:GetAttribute("TextColor3") or Color3.new(1, 1, 1)
local TEXT_STROKE_TRANSPARENCY: number = targetScript:GetAttribute("TextStrokeTransparency") or 0.5
local TEXT_STROKE_COLOR: Color3 = targetScript:GetAttribute("TextStrokeColor3") or Color3.new(0, 0, 0)
-- Search
local SEARCH_BACKGROUND_COLOR: Color3 = Color3.new(25 / 255, 27 / 255, 29 / 255)
local SEARCH_BACKGROUND_TRANSPARENCY_DEFAULT: number = 0.2
local SEARCH_BACKGROUND_TRANSPARENCY: number = SEARCH_BACKGROUND_TRANSPARENCY_DEFAULT * PREFERRED_TRANSPARENCY
local SEARCH_BORDER_COLOR: Color3 = Color3.new(1, 1, 1)
local SEARCH_BORDER_TRANSPARENCY: number = 0.8
local SEARCH_BORDER_THICKNESS: number = 1
local SEARCH_TEXT_PLACEHOLDER: string = "Search"
local SEARCH_TEXT_OFFSET: number = 8
local SEARCH_TEXT: string = ""
local SEARCH_CORNER_RADIUS: UDim = UDim.new(0, 3)
local SEARCH_IMAGE_X: string = "rbxasset://textures/ui/InspectMenu/x.png"
local SEARCH_BUFFER_PIXELS: number = 5
local SEARCH_WIDTH_PIXELS: number = 200
-- Misc
local FONT_FAMILY: Font = targetScript:GetAttribute("FontFace")
or Font.new("rbxasset://fonts/families/BuilderSans.json")
local FONT_SIZE: number = targetScript:GetAttribute("TextSize") or 16
local DROP_HOTKEY_VALUE: number = Enum.KeyCode.Backspace.Value
local ZERO_KEY_VALUE: number = Enum.KeyCode.Zero.Value
local DOUBLE_CLICK_TIME: number = 0.5
local ICON_BUFFER_PIXELS: number = 5
local ICON_SIZE_PIXELS: number = 60
local MOUSE_INPUT_TYPES: { [Enum.UserInputType]: boolean } =
{ -- These are the input types that will be used for mouse -- [[ADDED]], Optional
[Enum.UserInputType.MouseButton1] = true,
[Enum.UserInputType.MouseButton2] = true,
[Enum.UserInputType.MouseButton3] = true,
[Enum.UserInputType.MouseMovement] = true,
[Enum.UserInputType.MouseWheel] = true,
}
local GAMEPAD_INPUT_TYPES: { [Enum.UserInputType]: boolean } =
{ -- These are the input types that will be used for gamepad
[Enum.UserInputType.Gamepad1] = true,
[Enum.UserInputType.Gamepad2] = true,
[Enum.UserInputType.Gamepad3] = true,
[Enum.UserInputType.Gamepad4] = true,
[Enum.UserInputType.Gamepad5] = true,
[Enum.UserInputType.Gamepad6] = true,
[Enum.UserInputType.Gamepad7] = true,
[Enum.UserInputType.Gamepad8] = true,
}
-- Topbar logic
local BackpackEnabled: boolean = true
local Icon: any = require(game:GetService("ReplicatedStorage").Packages:WaitForChild("TopbarPlus"))
local inventoryIcon: any = Icon.new()
:setName("Inventory")
:setImage(ARROW_IMAGE_OPEN, "Selected")
:setImage(ARROW_IMAGE_CLOSE, "Deselected")
:setImageScale(1)
:setCaption("Inventory")
:bindToggleKey(Enum.KeyCode.Backquote)
:autoDeselect(false)
:setOrder(-1)
inventoryIcon.toggled:Connect(function(): ()
if not GuiService.MenuIsOpen then
BackpackScript.OpenClose()
end
end)
local BackpackGui: ScreenGui = Instance.new("ScreenGui")
BackpackGui.DisplayOrder = 120
BackpackGui.IgnoreGuiInset = true
BackpackGui.ResetOnSpawn = false
BackpackGui.Name = "BackpackGui"
BackpackGui.Parent = PlayerGui
local IsTenFootInterface: boolean = GuiService:IsTenFootInterface()
if IsTenFootInterface then
ICON_SIZE_PIXELS = 100
FONT_SIZE = 24
end
local GamepadActionsBound: boolean = false
local IS_PHONE: boolean = UserInputService.TouchEnabled
and workspace.CurrentCamera.ViewportSize.X < HOTBAR_SLOTS_WIDTH_CUTOFF
local Player: Player = Players.LocalPlayer
local MainFrame: Frame = nil
local HotbarFrame: Frame = nil
local InventoryFrame: Frame = nil
local VRInventorySelector: any = nil
local ScrollingFrame: ScrollingFrame = nil
local UIGridFrame: Frame = nil
local UIGridLayout: UIGridLayout = nil
local ScrollUpInventoryButton: any = nil
local ScrollDownInventoryButton: any = nil
local changeToolFunc: any = nil
local Character: Model = Player.Character or Player.CharacterAdded:Wait()
local Humanoid: any = Character:WaitForChild("Humanoid")
local Backpack: Instance = Player:WaitForChild("Backpack")
local Slots = {} -- List of all Slots by index
local LowestEmptySlot: any = nil
local SlotsByTool = {} -- Map of Tools to their assigned Slots
local HotkeyFns = {} -- Map of KeyCode values to their assigned behaviors
local Dragging: { boolean } = {} -- Only used to check if anything is being dragged, to disable other input
local FullHotbarSlots: number = 0 -- Now being used to also determine whether or not LB and RB on the gamepad are enabled.
local ActiveHopper = nil -- NOTE: HopperBin
local StarterToolFound: boolean = false -- Special handling is required for the gear currently equipped on the site
local WholeThingEnabled: boolean = false
local TextBoxFocused: boolean = false -- ANY TextBox, not just the search box
local ViewingSearchResults: boolean = false -- If the results of a search are currently being viewed
-- local HotkeyStrings = {} -- Used for eating/releasing hotkeys
local CharConns: { RBXScriptConnection } = {} -- Holds character Connections to be cleared later
local GamepadEnabled: boolean = false -- determines if our gui needs to be gamepad friendly
local IsVR: boolean = VRService.VREnabled -- Are we currently using a VR device?
local NumberOfHotbarSlots: number = IsVR and HOTBAR_SLOTS_VR or (IS_PHONE and HOTBAR_SLOTS_MINI or HOTBAR_SLOTS_FULL) -- Number of slots shown at the bottom
local NumberOfInventoryRows: number = IsVR and INVENTORY_ROWS_VR
or (IS_PHONE and INVENTORY_ROWS_MINI or INVENTORY_ROWS_FULL) -- How many rows in the popped-up inventory
local BackpackPanel = nil
local lastEquippedSlot: any = nil
local function EvaluateBackpackPanelVisibility(enabled: boolean): boolean
return enabled and inventoryIcon.enabled and BackpackEnabled and VRService.VREnabled
end
local function ShowVRBackpackPopup(): ()
if BackpackPanel and EvaluateBackpackPanelVisibility(true) then
BackpackPanel:ForceShowForSeconds(2)
end
end
local function FindLowestEmpty(): number?
for i: number = 1, NumberOfHotbarSlots do
local slot: any = Slots[i]
if not slot.Tool then
return slot
end
end
return nil
end
local function isInventoryEmpty(): boolean
for i: number = NumberOfHotbarSlots + 1, #Slots do
local slot: any = Slots[i]
if slot and slot.Tool then
return false
end
end
return true
end
BackpackScript.IsInventoryEmpty = isInventoryEmpty
local function UseGazeSelection(): boolean
return false -- disabled in new VR system
end
local function AdjustHotbarFrames(): ()
local inventoryOpen: boolean = InventoryFrame.Visible -- (Show all)
local visualTotal: number = inventoryOpen and NumberOfHotbarSlots or FullHotbarSlots
local visualIndex: number = 0
for i: number = 1, NumberOfHotbarSlots do
local slot: any = Slots[i]
if slot.Tool or inventoryOpen then
visualIndex = visualIndex + 1
slot:Readjust(visualIndex, visualTotal)
slot.Frame.Visible = true
else
slot.Frame.Visible = false
end
end
end
local function UpdateScrollingFrameCanvasSize(): ()
local countX: number = math.floor(ScrollingFrame.AbsoluteSize.X / (ICON_SIZE_PIXELS + ICON_BUFFER_PIXELS))
local maxRow: number = math.ceil((#UIGridFrame:GetChildren() - 1) / countX)
local canvasSizeY: number = maxRow * (ICON_SIZE_PIXELS + ICON_BUFFER_PIXELS) + ICON_BUFFER_PIXELS
ScrollingFrame.CanvasSize = UDim2.new(0, 0, 0, canvasSizeY)
end
local function AdjustInventoryFrames(): ()
for i: number = NumberOfHotbarSlots + 1, #Slots do
local slot: any = Slots[i]
slot.Frame.LayoutOrder = slot.Index
slot.Frame.Visible = (slot.Tool ~= nil)
end
UpdateScrollingFrameCanvasSize()
end
local function UpdateBackpackLayout(): ()
HotbarFrame.Size = UDim2.new(
0,
ICON_BUFFER_PIXELS + (NumberOfHotbarSlots * (ICON_SIZE_PIXELS + ICON_BUFFER_PIXELS)),
0,
ICON_BUFFER_PIXELS + ICON_SIZE_PIXELS + ICON_BUFFER_PIXELS
)
HotbarFrame.Position = UDim2.new(0.5, -HotbarFrame.Size.X.Offset / 2, 1, -HotbarFrame.Size.Y.Offset)
InventoryFrame.Size = UDim2.new(
0,
HotbarFrame.Size.X.Offset,
0,
(HotbarFrame.Size.Y.Offset * NumberOfInventoryRows)
+ INVENTORY_HEADER_SIZE
+ (IsVR and 2 * INVENTORY_ARROWS_BUFFER_VR or 0)
)
InventoryFrame.Position = UDim2.new(
0.5,
-InventoryFrame.Size.X.Offset / 2,
1,
HotbarFrame.Position.Y.Offset - InventoryFrame.Size.Y.Offset
)
ScrollingFrame.Size = UDim2.new(
1,
ScrollingFrame.ScrollBarThickness + 1,
1,
-INVENTORY_HEADER_SIZE - (IsVR and 2 * INVENTORY_ARROWS_BUFFER_VR or 0)
)
ScrollingFrame.Position = UDim2.new(0, 0, 0, INVENTORY_HEADER_SIZE + (IsVR and INVENTORY_ARROWS_BUFFER_VR or 0))
AdjustHotbarFrames()
AdjustInventoryFrames()
end
local function Clamp(low: number, high: number, num: number): number
return math.min(high, math.max(low, num))
end
local function CheckBounds(guiObject: GuiObject, x: number, y: number): boolean
local pos: Vector2 = guiObject.AbsolutePosition
local size: Vector2 = guiObject.AbsoluteSize
return (x > pos.X and x <= pos.X + size.X and y > pos.Y and y <= pos.Y + size.Y)
end
local function GetOffset(guiObject: GuiObject, point: Vector2): number
local centerPoint: Vector2 = guiObject.AbsolutePosition + (guiObject.AbsoluteSize / 2)
return (centerPoint - point).Magnitude
end
local function DisableActiveHopper(): () --NOTE: HopperBin
ActiveHopper:ToggleSelect()
SlotsByTool[ActiveHopper]:UpdateEquipView()
ActiveHopper = nil :: any
end
local function UnequipAllTools(): () --NOTE: HopperBin
if Humanoid then
Humanoid:UnequipTools()
if ActiveHopper then
DisableActiveHopper()
end
end
end
local function EquipNewTool(tool: Tool): () --NOTE: HopperBin
UnequipAllTools()
Humanoid:EquipTool(tool) --NOTE: This would also unequip current Tool
--tool.Parent = Character --TODO: Switch back to above line after EquipTool is fixed!
end
local function IsEquipped(tool: Tool): boolean
return tool and tool.Parent == Character --NOTE: HopperBin
end
-- Create a slot
local function MakeSlot(parent: Instance, initIndex: number?): GuiObject
local index: number = initIndex or (#Slots + 1)
-- Slot Definition --
local slot: any = {}
slot.Tool = nil :: any
slot.Index = index :: number
slot.Frame = nil :: any
local SlotFrame: any = nil
local FakeSlotFrame: Frame = nil
local ToolIcon: ImageLabel = nil
local ToolName: TextLabel = nil
local ToolChangeConn: any = nil
local HighlightFrame: any = nil -- UIStroke
local SelectionObj: ImageLabel = nil
--NOTE: The following are only defined for Hotbar Slots
local ToolTip: TextLabel = nil
local SlotNumber: TextLabel = nil
-- Slot Functions --
-- Update slot transparency
local function UpdateSlotFading(): ()
SlotFrame.SelectionImageObject = nil
SlotFrame.BackgroundTransparency = SlotFrame.Draggable and 0 or SLOT_LOCKED_TRANSPARENCY
end
-- Adjust the slots to the centered
function slot:Readjust(visualIndex: number, visualTotal: number): ...any --NOTE: Only used for Hotbar slots
local centered: number = HotbarFrame.Size.X.Offset / 2
local sizePlus: number = ICON_BUFFER_PIXELS + ICON_SIZE_PIXELS
local midpointish: number = (visualTotal / 2) + 0.5
local factor: number = visualIndex - midpointish
SlotFrame.Position =
UDim2.new(0, centered - (ICON_SIZE_PIXELS / 2) + (sizePlus * factor), 0, ICON_BUFFER_PIXELS)
end
-- Fill the slot with a tool
function slot:Fill(tool: Tool): ...any
-- Clear slot if it has no tool else assign the tool
if not tool then
return self:Clear()
end
self.Tool = tool :: Tool
-- Update the slot with tool data
local function assignToolData(): ()
local icon: string = tool.TextureId
ToolIcon.Image = icon
if icon ~= "" then
-- Enable the tool name on the slot if there is no icon
ToolName.Visible = false
else
ToolName.Visible = true
end
ToolName.Text = tool.Name
-- If there is a tooltip, then show it
if ToolTip and tool:IsA("Tool") then --NOTE: HopperBin
ToolTip.Text = tool.ToolTip
ToolTip.Size = UDim2.new(0, 0, 0, TOOLTIP_HEIGHT)
ToolTip.Position = UDim2.new(0.5, 0, 0, TOOLTIP_OFFSET)
end
end
assignToolData()
-- Disconnect tool event if it exists
if ToolChangeConn then
ToolChangeConn:Disconnect()
ToolChangeConn = nil
end
-- Update the slot with new tool data if the tool's properties changes
ToolChangeConn = tool.Changed:Connect(function(property: string): ()
if property == "TextureId" or property == "Name" or property == "ToolTip" then
assignToolData()
end
end)
local hotbarSlot: boolean = (self.Index <= NumberOfHotbarSlots)
local inventoryOpen: boolean = InventoryFrame.Visible
if (not hotbarSlot or inventoryOpen) and not UserInputService.VREnabled then
SlotFrame.Draggable = true
end
self:UpdateEquipView()
if hotbarSlot then
FullHotbarSlots = FullHotbarSlots + 1
-- If using a controller, determine whether or not we can enable BindCoreAction("BackpackHotbarEquip", etc)
if WholeThingEnabled and FullHotbarSlots >= 1 and not GamepadActionsBound then
-- Player added first item to a hotbar slot, enable BindCoreAction
GamepadActionsBound = true
ContextActionService:BindAction(
"BackpackHotbarEquip",
changeToolFunc,
false,
Enum.KeyCode.ButtonL1,
Enum.KeyCode.ButtonR1
)
end
end
SlotsByTool[tool] = self
LowestEmptySlot = FindLowestEmpty()
end
-- Empty the slot of any tool data
function slot:Clear(): ...any
if not self.Tool then
return
end
-- Disconnect tool event if it exists
if ToolChangeConn then
ToolChangeConn:Disconnect()
ToolChangeConn = nil
end
ToolIcon.Image = ""
ToolName.Text = ""
if ToolTip then
ToolTip.Text = ""
ToolTip.Visible = false
end
SlotFrame.Draggable = false
self:UpdateEquipView(true) -- Show as unequipped
if self.Index <= NumberOfHotbarSlots then
FullHotbarSlots = FullHotbarSlots - 1
if FullHotbarSlots < 1 then
-- Player removed last item from hotbar; UnbindCoreAction("BackpackHotbarEquip"), allowing the developer to use LB and RB.
GamepadActionsBound = false
ContextActionService:UnbindAction("BackpackHotbarEquip")
end
end
SlotsByTool[self.Tool] = nil
self.Tool = nil
LowestEmptySlot = FindLowestEmpty()
end
function slot:UpdateEquipView(unequippedOverride: boolean?): ...any
local override = unequippedOverride or false
if not override and IsEquipped(self.Tool) then -- Equipped
lastEquippedSlot = slot
if not HighlightFrame then
HighlightFrame = Instance.new("UIStroke")
HighlightFrame.Name = "Border"
HighlightFrame.Thickness = SLOT_EQUIP_THICKNESS
HighlightFrame.Color = SLOT_EQUIP_COLOR
HighlightFrame.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
end
if LEGACY_EDGE_ENABLED == true then
HighlightFrame.Parent = ToolIcon
else
HighlightFrame.Parent = SlotFrame
end
else -- In the Backpack
if HighlightFrame then
HighlightFrame.Parent = nil
end
end
UpdateSlotFading()
end
function slot:IsEquipped(): boolean
return IsEquipped(self.Tool)
end
function slot:Delete(): ...any
SlotFrame:Destroy() --NOTE: Also clears connections
table.remove(Slots, self.Index)
local newSize: number = #Slots
-- Now adjust the rest (both visually and representationally)
for slotIndex: number = self.Index :: number, newSize :: number do
Slots[slotIndex]:SlideBack()
end
UpdateScrollingFrameCanvasSize()
end
function slot:Swap(targetSlot: any): ...any --NOTE: This slot (self) must not be empty!
local myTool: any, otherTool: any = self.Tool, targetSlot.Tool
self:Clear()
if otherTool then -- (Target slot might be empty)
targetSlot:Clear()
self:Fill(otherTool)
end
if myTool then
targetSlot:Fill(myTool)
else
targetSlot:Clear()
end
end
function slot:SlideBack(): ...any -- For inventory slot shifting
self.Index = self.Index - 1
SlotFrame.Name = self.Index
SlotFrame.LayoutOrder = self.Index
end
function slot:TurnNumber(on: boolean): ...any
if SlotNumber then
SlotNumber.Visible = on
end
end
function slot:SetClickability(on: boolean): ...any -- (Happens on open/close arrow)
if self.Tool then
if UserInputService.VREnabled then
SlotFrame.Draggable = false
else
SlotFrame.Draggable = not on
end
UpdateSlotFading()
end
end
function slot:CheckTerms(terms: any): number
local hits: number = 0
local function checkEm(str: string, term: any): ()
local _, n: number = str:lower():gsub(term, "")
hits = hits + n
end
local tool: Tool = self.Tool
if tool then
for term: any in pairs(terms) do
checkEm(ToolName.Text, term)
if tool:IsA("Tool") then --NOTE: HopperBin
local toolTipText: string = ToolTip and ToolTip.Text or ""
checkEm(toolTipText, term)
end
end
end
return hits
end
-- Slot select logic, activated by clicking or pressing hotkey
function slot:Select(): ...any
local tool: Tool = slot.Tool
if tool then
if IsEquipped(tool) then --NOTE: HopperBin
UnequipAllTools()
elseif tool.Parent == Backpack then
EquipNewTool(tool)
end
end
end
-- Slot Init Logic --
SlotFrame = Instance.new("TextButton")
SlotFrame.Name = tostring(index)
SlotFrame.BackgroundColor3 = BACKGROUND_COLOR
SlotFrame.BorderColor3 = SLOT_BORDER_COLOR
SlotFrame.Text = ""
SlotFrame.BorderSizePixel = 0
SlotFrame.Size = UDim2.new(0, ICON_SIZE_PIXELS, 0, ICON_SIZE_PIXELS)
SlotFrame.Active = true
SlotFrame.Draggable = false
SlotFrame.BackgroundTransparency = SLOT_LOCKED_TRANSPARENCY
SlotFrame.MouseButton1Click:Connect(function(): ()
changeSlot(slot)
end)
local searchFrameCorner: UICorner = Instance.new("UICorner")
searchFrameCorner.Name = "Corner"
searchFrameCorner.CornerRadius = SLOT_CORNER_RADIUS
searchFrameCorner.Parent = SlotFrame
slot.Frame = SlotFrame
do
local selectionObjectClipper: Frame = Instance.new("Frame")
selectionObjectClipper.Name = "SelectionObjectClipper"
selectionObjectClipper.BackgroundTransparency = 1
selectionObjectClipper.Visible = false
selectionObjectClipper.Parent = SlotFrame
SelectionObj = Instance.new("ImageLabel")
SelectionObj.Name = "Selector"
SelectionObj.BackgroundTransparency = 1
SelectionObj.Size = UDim2.new(1, 0, 1, 0)
SelectionObj.Image = "rbxasset://textures/ui/Keyboard/key_selection_9slice.png"
SelectionObj.ScaleType = Enum.ScaleType.Slice
SelectionObj.SliceCenter = Rect.new(12, 12, 52, 52)
SelectionObj.Parent = selectionObjectClipper
end
ToolIcon = Instance.new("ImageLabel")
ToolIcon.BackgroundTransparency = 1
ToolIcon.Name = "Icon"
ToolIcon.Size = UDim2.new(1, 0, 1, 0)
ToolIcon.Position = UDim2.new(0.5, 0, 0.5, 0)
ToolIcon.AnchorPoint = Vector2.new(0.5, 0.5)
if LEGACY_PADDING_ENABLED == true then
ToolIcon.Size = UDim2.new(1, -SLOT_EQUIP_THICKNESS * 2, 1, -SLOT_EQUIP_THICKNESS * 2)
else
ToolIcon.Size = UDim2.new(1, 0, 1, 0)
end
ToolIcon.Parent = SlotFrame
local ToolIconCorner: UICorner = Instance.new("UICorner")
ToolIconCorner.Name = "Corner"
if LEGACY_PADDING_ENABLED == true then
ToolIconCorner.CornerRadius = SLOT_CORNER_RADIUS - UDim.new(0, SLOT_EQUIP_THICKNESS)
else
ToolIconCorner.CornerRadius = SLOT_CORNER_RADIUS
end
ToolIconCorner.Parent = ToolIcon
ToolName = Instance.new("TextLabel")
ToolName.BackgroundTransparency = 1
ToolName.Name = "ToolName"
ToolName.Text = ""
ToolName.TextColor3 = TEXT_COLOR
ToolName.TextStrokeTransparency = TEXT_STROKE_TRANSPARENCY
ToolName.TextStrokeColor3 = TEXT_STROKE_COLOR
ToolName.FontFace = Font.new(FONT_FAMILY.Family, Enum.FontWeight.Medium, Enum.FontStyle.Normal)
ToolName.TextSize = FONT_SIZE
ToolName.Size = UDim2.new(1, -SLOT_EQUIP_THICKNESS * 2, 1, -SLOT_EQUIP_THICKNESS * 2)
ToolName.Position = UDim2.new(0.5, 0, 0.5, 0)
ToolName.AnchorPoint = Vector2.new(0.5, 0.5)
ToolName.TextWrapped = true
ToolName.TextTruncate = Enum.TextTruncate.AtEnd
ToolName.Parent = SlotFrame
slot.Frame.LayoutOrder = slot.Index
if index <= NumberOfHotbarSlots then -- Hotbar-Specific Slot Stuff
-- ToolTip stuff
ToolTip = Instance.new("TextLabel")
ToolTip.Name = "ToolTip"
ToolTip.Text = ""
ToolTip.Size = UDim2.new(1, 0, 1, 0)
ToolTip.TextColor3 = TEXT_COLOR
ToolTip.TextStrokeTransparency = TEXT_STROKE_TRANSPARENCY
ToolTip.TextStrokeColor3 = TEXT_STROKE_COLOR
ToolTip.FontFace = Font.new(FONT_FAMILY.Family, Enum.FontWeight.Medium, Enum.FontStyle.Normal)
ToolTip.TextSize = FONT_SIZE
ToolTip.ZIndex = 2
ToolTip.TextWrapped = false
ToolTip.TextYAlignment = Enum.TextYAlignment.Center
ToolTip.BackgroundColor3 = TOOLTIP_BACKGROUND_COLOR
ToolTip.BackgroundTransparency = SLOT_LOCKED_TRANSPARENCY
ToolTip.AnchorPoint = Vector2.new(0.5, 1)
ToolTip.BorderSizePixel = 0
ToolTip.Visible = false
ToolTip.AutomaticSize = Enum.AutomaticSize.X
ToolTip.Parent = SlotFrame
local ToolTipCorner: UICorner = Instance.new("UICorner")
ToolTipCorner.Name = "Corner"
ToolTipCorner.CornerRadius = TOOLTIP_CORNER_RADIUS
ToolTipCorner.Parent = ToolTip
local ToolTipPadding: UIPadding = Instance.new("UIPadding")
ToolTipPadding.PaddingLeft = UDim.new(0, TOOLTIP_PADDING)
ToolTipPadding.PaddingRight = UDim.new(0, TOOLTIP_PADDING)
ToolTipPadding.PaddingTop = UDim.new(0, TOOLTIP_PADDING)
ToolTipPadding.PaddingBottom = UDim.new(0, TOOLTIP_PADDING)
ToolTipPadding.Parent = ToolTip
SlotFrame.MouseEnter:Connect(function(): ()
if ToolTip.Text ~= "" then
ToolTip.Visible = true
end
end)
SlotFrame.MouseLeave:Connect(function(): ()
ToolTip.Visible = false
end)
function slot:MoveToInventory(): ...any
if slot.Index <= NumberOfHotbarSlots then -- From a Hotbar slot
local tool: any = slot.Tool
self:Clear() --NOTE: Order matters here
local newSlot: any = MakeSlot(UIGridFrame)
newSlot:Fill(tool)
if IsEquipped(tool) then -- Also unequip it --NOTE: HopperBin
UnequipAllTools()
end
-- Also hide the inventory slot if we're showing results right now
if ViewingSearchResults then
newSlot.Frame.Visible = false
newSlot.Parent = InventoryFrame
end
end
end
-- Show label and assign hotkeys for 1-9 and 0 (zero is always last slot when > 10 total)
if index < 10 or index == NumberOfHotbarSlots then -- NOTE: Hardcoded on purpose!
local slotNum: number = (index < 10) and index or 0
SlotNumber = Instance.new("TextLabel")
SlotNumber.BackgroundTransparency = 1
SlotNumber.Name = "Number"
SlotNumber.TextColor3 = TEXT_COLOR
SlotNumber.TextStrokeTransparency = TEXT_STROKE_TRANSPARENCY
SlotNumber.TextStrokeColor3 = TEXT_STROKE_COLOR
SlotNumber.TextSize = FONT_SIZE
SlotNumber.Text = tostring(slotNum)
SlotNumber.FontFace = Font.new(FONT_FAMILY.Family, Enum.FontWeight.Heavy, Enum.FontStyle.Normal)
SlotNumber.Size = UDim2.new(0.4, 0, 0.4, 0)
SlotNumber.Visible = false
SlotNumber.Parent = SlotFrame
HotkeyFns[ZERO_KEY_VALUE + slotNum] = slot.Select
end
end
do -- Dragging Logic
local startPoint: UDim2 = SlotFrame.Position
local lastUpTime: number = 0
local startParent: any = nil
SlotFrame.DragBegin:Connect(function(dragPoint: UDim2): ()
Dragging[SlotFrame] = true
startPoint = dragPoint
SlotFrame.BorderSizePixel = 2
inventoryIcon:lock()
-- Raise above other slots
SlotFrame.ZIndex = 2
ToolIcon.ZIndex = 2
ToolName.ZIndex = 2
SlotFrame.Parent.ZIndex = 2
if SlotNumber then
SlotNumber.ZIndex = 2
end
-- if HighlightFrame then
-- HighlightFrame.ZIndex = 2
-- for _, child in pairs(HighlightFrame:GetChildren()) do
-- child.ZIndex = 2
-- end
-- end
-- Circumvent the ScrollingFrame's ClipsDescendants property
startParent = SlotFrame.Parent
if startParent == UIGridFrame then
local newPosition: UDim2 = UDim2.new(
0,
SlotFrame.AbsolutePosition.X - InventoryFrame.AbsolutePosition.X,
0,
SlotFrame.AbsolutePosition.Y - InventoryFrame.AbsolutePosition.Y
)
SlotFrame.Parent = InventoryFrame
SlotFrame.Position = newPosition
FakeSlotFrame = Instance.new("Frame")
FakeSlotFrame.Name = "FakeSlot"
FakeSlotFrame.LayoutOrder = SlotFrame.LayoutOrder
FakeSlotFrame.Size = SlotFrame.Size
FakeSlotFrame.BackgroundTransparency = 1
FakeSlotFrame.Parent = UIGridFrame
end
end)
SlotFrame.DragStopped:Connect(function(x: number, y: number): ()
if FakeSlotFrame then
FakeSlotFrame:Destroy()
end
local now: number = os.clock()
SlotFrame.Position = startPoint
SlotFrame.Parent = startParent
SlotFrame.BorderSizePixel = 0
inventoryIcon:unlock()
-- Restore height
SlotFrame.ZIndex = 1
ToolIcon.ZIndex = 1
ToolName.ZIndex = 1
startParent.ZIndex = 1
if SlotNumber then
SlotNumber.ZIndex = 1
end
-- if HighlightFrame then
-- HighlightFrame.ZIndex = 1
-- for _, child in pairs(HighlightFrame:GetChildren()) do
-- child.ZIndex = 1
-- end
-- end
Dragging[SlotFrame] = nil
-- Make sure the tool wasn't dropped
if not slot.Tool then
return
end
-- Check where we were dropped
if CheckBounds(InventoryFrame, x, y) then
if slot.Index <= NumberOfHotbarSlots then
slot:MoveToInventory()
end
-- Check for double clicking on an inventory slot, to move into empty hotbar slot
if slot.Index > NumberOfHotbarSlots and now - lastUpTime < DOUBLE_CLICK_TIME then
if LowestEmptySlot then
local myTool: any = slot.Tool
slot:Clear()
LowestEmptySlot:Fill(myTool)
slot:Delete()
end
now = 0 -- Resets the timer
end
elseif CheckBounds(HotbarFrame, x, y) then
local closest: { number } = { math.huge, nil :: any }
for i: number = 1, NumberOfHotbarSlots do
local otherSlot: any = Slots[i]
local offset: number = GetOffset(otherSlot.Frame, Vector2.new(x, y))
if offset < closest[1] then
closest = { offset, otherSlot }
end
end
local closestSlot: any = closest[2]
if closestSlot ~= slot then
slot:Swap(closestSlot)
if slot.Index > NumberOfHotbarSlots then
local tool: Tool = slot.Tool
if not tool then -- Clean up after ourselves if we're an inventory slot that's now empty
slot:Delete()
else -- Moved inventory slot to hotbar slot, and gained a tool that needs to be unequipped
if IsEquipped(tool) then --NOTE: HopperBin
UnequipAllTools()
end
-- Also hide the inventory slot if we're showing results right now
if ViewingSearchResults then
slot.Frame.Visible = false
slot.Frame.Parent = InventoryFrame
end
end
end
end
else
-- local tool = slot.Tool
-- if tool.CanBeDropped then --TODO: HopperBins
-- tool.Parent = workspace
-- --TODO: Move away from character
-- end
if slot.Index <= NumberOfHotbarSlots then
slot:MoveToInventory() --NOTE: Temporary
end
end
lastUpTime = now
end)
end
-- All ready!
SlotFrame.Parent = parent
Slots[index] = slot
if index > NumberOfHotbarSlots then
UpdateScrollingFrameCanvasSize()
-- Scroll to new inventory slot, if we're open and not viewing search results
if InventoryFrame.Visible and not ViewingSearchResults then
local offset: number = ScrollingFrame.CanvasSize.Y.Offset - ScrollingFrame.AbsoluteSize.Y
ScrollingFrame.CanvasPosition = Vector2.new(0, math.max(0, offset))
end
end
return slot
end
local function OnChildAdded(child: Instance): () -- To Character or Backpack
if not child:IsA("Tool") and not child:IsA("HopperBin") then --NOTE: HopperBin
if child:IsA("Humanoid") and child.Parent == Character then
Humanoid = child
end
return
end
local tool: any = child
if tool.Parent == Character then
ShowVRBackpackPopup()
end
if ActiveHopper and tool.Parent == Character then --NOTE: HopperBin
DisableActiveHopper()
end
--TODO: Optimize / refactor / do something else
if not StarterToolFound and tool.Parent == Character and not SlotsByTool[tool] then
local starterGear: Instance? = Player:FindFirstChild("StarterGear")
if starterGear then
if starterGear:FindFirstChild(tool.Name) then
StarterToolFound = true
local slot: any = LowestEmptySlot or MakeSlot(UIGridFrame)
for i: number = slot.Index, 1, -1 do
local curr = Slots[i] -- An empty slot, because above
local pIndex: number = i - 1
if pIndex > 0 then
local prev = Slots[pIndex] -- Guaranteed to be full, because above
prev:Swap(curr)
else
curr:Fill(tool)
end
end
-- Have to manually unequip a possibly equipped tool
for _, children: Instance in pairs(Character:GetChildren()) do
if children:IsA("Tool") and children ~= tool then
children.Parent = Backpack
end
end
AdjustHotbarFrames()
return -- We're done here
end
end
end
-- The tool is either moving or new
local slot: any = SlotsByTool[tool]
if slot then
slot:UpdateEquipView()
else -- New! Put into lowest hotbar slot or new inventory slot
slot = LowestEmptySlot or MakeSlot(UIGridFrame)
slot:Fill(tool)
if slot.Index <= NumberOfHotbarSlots and not InventoryFrame.Visible then
AdjustHotbarFrames()
end
if tool:IsA("HopperBin") then --NOTE: HopperBin
if tool.Active then
UnequipAllTools()
ActiveHopper = tool
end
end
end
BackpackScript.BackpackItemAdded:Fire()
end
local function OnChildRemoved(child: Instance): () -- From Character or Backpack
if not child:IsA("Tool") and not child:IsA("HopperBin") then --NOTE: HopperBin
return
end
local tool: Tool | any = child
ShowVRBackpackPopup()
-- Ignore this event if we're just moving between the two
local newParent: any = tool.Parent
if newParent == Character or newParent == Backpack then
return
end
local slot: any = SlotsByTool[tool]
if slot then
slot:Clear()
if slot.Index > NumberOfHotbarSlots then -- Inventory slot
slot:Delete()
elseif not InventoryFrame.Visible then
AdjustHotbarFrames()
end
end
if tool :: any == ActiveHopper then --NOTE: HopperBin
ActiveHopper = nil :: any
end
BackpackScript.BackpackItemRemoved:Fire()
if isInventoryEmpty() then
BackpackScript.BackpackEmpty:Fire()
end
end
local function OnCharacterAdded(character: Model): ()
-- First, clean up any old slots
for i: number = #Slots, 1, -1 do
local slot = Slots[i]
if slot.Tool then
slot:Clear()
end
if i > NumberOfHotbarSlots then
slot:Delete()
end
end
ActiveHopper = nil :: any --NOTE: HopperBin
-- And any old Connections
for _, conn: RBXScriptConnection in pairs(CharConns) do
conn:Disconnect()
end
CharConns = {}
-- Hook up the new character
Character = character
table.insert(CharConns, character.ChildRemoved:Connect(OnChildRemoved))
table.insert(CharConns, character.ChildAdded:Connect(OnChildAdded))
for _, child: Instance in pairs(character:GetChildren()) do
OnChildAdded(child)
end
--NOTE: Humanoid is set inside OnChildAdded
-- And the new backpack, when it gets here
Backpack = Player:WaitForChild("Backpack")
table.insert(CharConns, Backpack.ChildRemoved:Connect(OnChildRemoved))
table.insert(CharConns, Backpack.ChildAdded:Connect(OnChildAdded))
for _, child: Instance in pairs(Backpack:GetChildren()) do
OnChildAdded(child)
end
AdjustHotbarFrames()
end
local function OnInputBegan(input: InputObject, isProcessed: boolean): ()
local ChatInputBarConfiguration =
TextChatService:FindFirstChildOfClass("ChatInputBarConfiguration") :: ChatInputBarConfiguration
-- Pass through keyboard hotkeys when not typing into a TextBox and not disabled (except for the Drop key)
if
input.UserInputType == Enum.UserInputType.Keyboard
and not TextBoxFocused
and not ChatInputBarConfiguration.IsFocused
and (WholeThingEnabled or input.KeyCode.Value == DROP_HOTKEY_VALUE)
then
local hotkeyBehavior: any = HotkeyFns[input.KeyCode.Value]
if hotkeyBehavior then
hotkeyBehavior(isProcessed)
end
end
local inputType: Enum.UserInputType = input.UserInputType
if not isProcessed then
if inputType == Enum.UserInputType.MouseButton1 or inputType == Enum.UserInputType.Touch then
if InventoryFrame.Visible then
inventoryIcon:deselect()
end
end
end
end
local function OnUISChanged(): ()
-- Detect if player is using Touch
if UserInputService:GetLastInputType() == Enum.UserInputType.Touch then
for i: number = 1, NumberOfHotbarSlots do
Slots[i]:TurnNumber(false)
end
return
end
-- Detect if player is using Keyboard
if UserInputService:GetLastInputType() == Enum.UserInputType.Keyboard then
for i: number = 1, NumberOfHotbarSlots do
Slots[i]:TurnNumber(true)
end
return
end
-- Detect if player is using Mouse
for _, mouse: any in pairs(MOUSE_INPUT_TYPES) do
if UserInputService:GetLastInputType() == mouse then
for i: number = 1, NumberOfHotbarSlots do
Slots[i]:TurnNumber(true)
end
return
end
end
-- Detect if player is using Controller
for _, gamepad: any in pairs(GAMEPAD_INPUT_TYPES) do
if UserInputService:GetLastInputType() == gamepad then
for i: number = 1, NumberOfHotbarSlots do
Slots[i]:TurnNumber(false)
end
return
end
end
end
local lastChangeToolInputObject: InputObject = nil
local lastChangeToolInputTime: number = nil
local maxEquipDeltaTime: number = 0.06
local noOpFunc = function() end
-- local selectDirection = Vector2.new(0, 0)
function unbindAllGamepadEquipActions(): ()
ContextActionService:UnbindAction("BackpackHasGamepadFocus")
ContextActionService:UnbindAction("BackpackCloseInventory")
end
-- local function setHotbarVisibility(visible: boolean, isInventoryScreen: boolean)
-- for i: number = 1, NumberOfHotbarSlots do
-- local hotbarSlot = Slots[i]
-- if hotbarSlot and hotbarSlot.Frame and (isInventoryScreen or hotbarSlot.Tool) then
-- hotbarSlot.Frame.Visible = visible
-- end
-- end
-- end
-- local function getInputDirection(inputObject: InputObject): Vector2
-- local buttonModifier = 1
-- if inputObject.UserInputState == Enum.UserInputState.End then
-- buttonModifier = -1
-- end
-- if inputObject.KeyCode == Enum.KeyCode.Thumbstick1 then
-- local Magnitude = inputObject.Position.Magnitude
-- if Magnitude > 0.98 then
-- local normalizedVector =
-- Vector2.new(inputObject.Position.X / Magnitude, -inputObject.Position.Y / Magnitude)
-- selectDirection = normalizedVector
-- else
-- selectDirection = Vector2.new(0, 0)
-- end
-- elseif inputObject.KeyCode == Enum.KeyCode.DPadLeft then
-- selectDirection = Vector2.new(selectDirection.X - 1 * buttonModifier, selectDirection.Y)
-- elseif inputObject.KeyCode == Enum.KeyCode.DPadRight then
-- selectDirection = Vector2.new(selectDirection.X + 1 * buttonModifier, selectDirection.Y)
-- elseif inputObject.KeyCode == Enum.KeyCode.DPadUp then
-- selectDirection = Vector2.new(selectDirection.X, selectDirection.Y - 1 * buttonModifier)
-- elseif inputObject.KeyCode == Enum.KeyCode.DPadDown then
-- selectDirection = Vector2.new(selectDirection.X, selectDirection.Y + 1 * buttonModifier)
-- else
-- selectDirection = Vector2.new(0, 0)
-- end
-- return selectDirection
-- end
-- local selectToolExperiment = function(actionName: string, inputState: Enum.UserInputState, inputObject: InputObject)
-- local inputDirection = getInputDirection(inputObject)
-- if inputDirection == Vector2.new(0, 0) then
-- return
-- end
-- local angle = math.atan2(inputDirection.Y, inputDirection.X) - math.atan2(-1, 0)
-- if angle < 0 then
-- angle = angle + (math.pi * 2)
-- end
-- local quarterPi = (math.pi * 0.25)
-- local index = (angle / quarterPi) + 1
-- index = math.floor(index + 0.5) -- round index to whole number
-- if index > NumberOfHotbarSlots then
-- index = 1
-- end
-- if index > 0 then
-- local selectedSlot = Slots[index]
-- if selectedSlot and selectedSlot.Tool and not selectedSlot:IsEquipped() then
-- selectedSlot:Select()
-- end
-- else
-- UnequipAllTools()
-- end
-- end
-- selene: allow(unused_variable)
changeToolFunc = function(actionName: string, inputState: Enum.UserInputState, inputObject: InputObject): ()
if inputState ~= Enum.UserInputState.Begin then
return
end
if lastChangeToolInputObject then
if
(
lastChangeToolInputObject.KeyCode == Enum.KeyCode.ButtonR1
and inputObject.KeyCode == Enum.KeyCode.ButtonL1
)
or (
lastChangeToolInputObject.KeyCode == Enum.KeyCode.ButtonL1
and inputObject.KeyCode == Enum.KeyCode.ButtonR1
)
then
if (os.clock() - lastChangeToolInputTime) <= maxEquipDeltaTime then
UnequipAllTools()
lastChangeToolInputObject = inputObject
lastChangeToolInputTime = os.clock()
return
end
end
end
lastChangeToolInputObject = inputObject
lastChangeToolInputTime = os.clock()
task.delay(maxEquipDeltaTime, function(): ()
if lastChangeToolInputObject ~= inputObject then
return
end
local moveDirection: number = 0
if inputObject.KeyCode == Enum.KeyCode.ButtonL1 then
moveDirection = -1
else
moveDirection = 1
end
for i: number = 1, NumberOfHotbarSlots do
local hotbarSlot: any = Slots[i]
if hotbarSlot:IsEquipped() then
local newSlotPosition: number = moveDirection + i
local hitEdge: boolean = false
if newSlotPosition > NumberOfHotbarSlots then
newSlotPosition = 1
hitEdge = true
elseif newSlotPosition < 1 then
newSlotPosition = NumberOfHotbarSlots
hitEdge = true
end
local origNewSlotPos: number = newSlotPosition
while not Slots[newSlotPosition].Tool do
newSlotPosition = newSlotPosition + moveDirection
if newSlotPosition == origNewSlotPos then
return
end
if newSlotPosition > NumberOfHotbarSlots then
newSlotPosition = 1
hitEdge = true
elseif newSlotPosition < 1 then
newSlotPosition = NumberOfHotbarSlots
hitEdge = true
end
end
if hitEdge then
UnequipAllTools()
lastEquippedSlot = nil
else
Slots[newSlotPosition]:Select()
end
return
end
end
if lastEquippedSlot and lastEquippedSlot.Tool then
lastEquippedSlot:Select()
return
end
local startIndex: number = moveDirection == -1 and NumberOfHotbarSlots or 1
local endIndex: number = moveDirection == -1 and 1 or NumberOfHotbarSlots
for i: number = startIndex, endIndex, moveDirection do
if Slots[i].Tool then
Slots[i]:Select()
return
end
end
end)
end
function getGamepadSwapSlot(): any
for i: number = 1, #Slots do
if Slots[i].Frame.BorderSizePixel > 0 then
return Slots[i]
end
end
return
end
-- selene: allow(unused_variable)
function changeSlot(slot: any): ()
local swapInVr: boolean = not VRService.VREnabled or InventoryFrame.Visible
if slot.Frame == GuiService.SelectedObject and swapInVr then
local currentlySelectedSlot: any = getGamepadSwapSlot()
if currentlySelectedSlot then
currentlySelectedSlot.Frame.BorderSizePixel = 0
if currentlySelectedSlot ~= slot then
slot:Swap(currentlySelectedSlot)
VRInventorySelector.SelectionImageObject.Visible = false
if slot.Index > NumberOfHotbarSlots and not slot.Tool then
if GuiService.SelectedObject == slot.Frame then
GuiService.SelectedObject = currentlySelectedSlot.Frame
end
slot:Delete()
end
if currentlySelectedSlot.Index > NumberOfHotbarSlots and not currentlySelectedSlot.Tool then
if GuiService.SelectedObject == currentlySelectedSlot.Frame then
GuiService.SelectedObject = slot.Frame
end
currentlySelectedSlot:Delete()
end
end
else
local startSize: UDim2 = slot.Frame.Size
local startPosition: UDim2 = slot.Frame.Position
slot.Frame:TweenSizeAndPosition(
startSize + UDim2.new(0, 10, 0, 10),
startPosition - UDim2.new(0, 5, 0, 5),
Enum.EasingDirection.Out,
Enum.EasingStyle.Quad,
0.1,
true,
function(): ()
slot.Frame:TweenSizeAndPosition(
startSize,
startPosition,
Enum.EasingDirection.In,
Enum.EasingStyle.Quad,
0.1,
true
)
end
)
slot.Frame.BorderSizePixel = 3
VRInventorySelector.SelectionImageObject.Visible = true
end
else
slot:Select()
VRInventorySelector.SelectionImageObject.Visible = false
end
end
function vrMoveSlotToInventory(): ()
if not VRService.VREnabled then
return
end
local currentlySelectedSlot: any = getGamepadSwapSlot()
if currentlySelectedSlot and currentlySelectedSlot.Tool then
currentlySelectedSlot.Frame.BorderSizePixel = 0
currentlySelectedSlot:MoveToInventory()
VRInventorySelector.SelectionImageObject.Visible = false
end
end
function enableGamepadInventoryControl(): ()
local goBackOneLevel = function(): ()
-- if inputState ~= Enum.UserInputState.Begin then
-- return
-- end
local selectedSlot: any = getGamepadSwapSlot()
if selectedSlot then
-- selene: allow(shadowing)
local selectedSlot: any = getGamepadSwapSlot()
if selectedSlot then
selectedSlot.Frame.BorderSizePixel = 0
return
end
elseif InventoryFrame.Visible then
inventoryIcon:deselect()
end
end
ContextActionService:BindAction("BackpackHasGamepadFocus", noOpFunc, false, Enum.UserInputType.Gamepad1)
ContextActionService:BindAction(
"BackpackCloseInventory",
goBackOneLevel,
false,
Enum.KeyCode.ButtonB,
Enum.KeyCode.ButtonStart
)
-- Gaze select will automatically select the object for us!
if not UseGazeSelection() then
GuiService.SelectedObject = HotbarFrame:FindFirstChild("1")
end
end
function disableGamepadInventoryControl(): ()
unbindAllGamepadEquipActions()
for i: number = 1, NumberOfHotbarSlots do
local hotbarSlot: any = Slots[i]
if hotbarSlot and hotbarSlot.Frame then
hotbarSlot.Frame.BorderSizePixel = 0
end
end
if GuiService.SelectedObject and GuiService.SelectedObject:IsDescendantOf(MainFrame) then
GuiService.SelectedObject = nil
end
end
local function bindBackpackHotbarAction(): ()
if WholeThingEnabled and not GamepadActionsBound then
GamepadActionsBound = true
ContextActionService:BindAction(
"BackpackHotbarEquip",
changeToolFunc,
false,
Enum.KeyCode.ButtonL1,
Enum.KeyCode.ButtonR1
)
end
end
local function unbindBackpackHotbarAction(): ()
disableGamepadInventoryControl()
GamepadActionsBound = false
ContextActionService:UnbindAction("BackpackHotbarEquip")
end
function gamepadDisconnected(): ()
GamepadEnabled = false
disableGamepadInventoryControl()
end
function gamepadConnected(): ()
GamepadEnabled = true
GuiService:AddSelectionParent("BackpackSelection", MainFrame)
if FullHotbarSlots >= 1 then
bindBackpackHotbarAction()
end
if InventoryFrame.Visible then
enableGamepadInventoryControl()
end
end
local function OnIconChanged(enabled: boolean): ()
-- Check for enabling/disabling the whole thing
enabled = enabled and StarterGui:GetCore("TopbarEnabled")
WholeThingEnabled = enabled
MainFrame.Visible = enabled
-- Eat/Release hotkeys (Doesn't affect UserInputService)
-- for _, keyString in pairs(HotkeyStrings) do
-- if enabled then
-- GuiService:AddKey(keyString)
-- else
-- GuiService:RemoveKey(keyString)
-- end
-- end
if enabled then
if FullHotbarSlots >= 1 then
bindBackpackHotbarAction()
end
else
unbindBackpackHotbarAction()
end
end
local function MakeVRRoundButton(name: string, image: string): (ImageButton, ImageLabel, ImageLabel)
local newButton: ImageButton = Instance.new("ImageButton")
newButton.BackgroundTransparency = 1
newButton.Name = name
newButton.Size = UDim2.new(0, 40, 0, 40)
newButton.Image = "rbxasset://textures/ui/Keyboard/close_button_background.png"
local buttonIcon: ImageLabel = Instance.new("ImageLabel")
buttonIcon.Name = "Icon"
buttonIcon.BackgroundTransparency = 1
buttonIcon.Size = UDim2.new(0.5, 0, 0.5, 0)
buttonIcon.Position = UDim2.new(0.25, 0, 0.25, 0)
buttonIcon.Image = image
buttonIcon.Parent = newButton
local buttonSelectionObject: ImageLabel = Instance.new("ImageLabel")
buttonSelectionObject.BackgroundTransparency = 1
buttonSelectionObject.Name = "Selection"
buttonSelectionObject.Size = UDim2.new(0.9, 0, 0.9, 0)
buttonSelectionObject.Position = UDim2.new(0.05, 0, 0.05, 0)
buttonSelectionObject.Image = "rbxasset://textures/ui/Keyboard/close_button_selection.png"
newButton.SelectionImageObject = buttonSelectionObject
return newButton, buttonIcon, buttonSelectionObject
end
-- Make the main frame, which (mostly) covers the screen
MainFrame = Instance.new("Frame")
MainFrame.BackgroundTransparency = 1
MainFrame.Name = "Backpack"
MainFrame.Size = UDim2.new(1, 0, 1, 0)
MainFrame.Visible = false
MainFrame.Parent = BackpackGui
-- Make the HotbarFrame, which holds only the Hotbar Slots
HotbarFrame = Instance.new("Frame")
HotbarFrame.BackgroundTransparency = 1
HotbarFrame.Name = "Hotbar"
HotbarFrame.Size = UDim2.new(1, 0, 1, 0)
HotbarFrame.Parent = MainFrame
-- Make all the Hotbar Slots
for index: number = 1, NumberOfHotbarSlots do
local slot: any = MakeSlot(HotbarFrame, index)
slot.Frame.Visible = false
if not LowestEmptySlot then
LowestEmptySlot = slot
end
end
local LeftBumperButton: ImageLabel = Instance.new("ImageLabel")
LeftBumperButton.BackgroundTransparency = 1
LeftBumperButton.Name = "LeftBumper"
LeftBumperButton.Size = UDim2.new(0, 40, 0, 40)
LeftBumperButton.Position = UDim2.new(0, -LeftBumperButton.Size.X.Offset, 0.5, -LeftBumperButton.Size.Y.Offset / 2)
local RightBumperButton: ImageLabel = Instance.new("ImageLabel")
RightBumperButton.BackgroundTransparency = 1
RightBumperButton.Name = "RightBumper"
RightBumperButton.Size = UDim2.new(0, 40, 0, 40)
RightBumperButton.Position = UDim2.new(1, 0, 0.5, -RightBumperButton.Size.Y.Offset / 2)
-- Make the Inventory, which holds the ScrollingFrame, the header, and the search box
InventoryFrame = Instance.new("Frame")
InventoryFrame.Name = "Inventory"
InventoryFrame.Size = UDim2.new(1, 0, 1, 0)
InventoryFrame.BackgroundTransparency = BACKGROUND_TRANSPARENCY
InventoryFrame.BackgroundColor3 = BACKGROUND_COLOR
InventoryFrame.Active = true
InventoryFrame.Visible = false
InventoryFrame.Parent = MainFrame
-- Add corners to the InventoryFrame
local corner: UICorner = Instance.new("UICorner")
corner.Name = "Corner"
corner.CornerRadius = BACKGROUND_CORNER_RADIUS
corner.Parent = InventoryFrame
VRInventorySelector = Instance.new("TextButton")
VRInventorySelector.Name = "VRInventorySelector"
VRInventorySelector.Position = UDim2.new(0, 0, 0, 0)
VRInventorySelector.Size = UDim2.new(1, 0, 1, 0)
VRInventorySelector.BackgroundTransparency = 1
VRInventorySelector.Text = ""
VRInventorySelector.Parent = InventoryFrame
local selectorImage: ImageLabel = Instance.new("ImageLabel")
selectorImage.BackgroundTransparency = 1
selectorImage.Name = "Selector"
selectorImage.Size = UDim2.new(1, 0, 1, 0)
selectorImage.Image = "rbxasset://textures/ui/Keyboard/key_selection_9slice.png"
selectorImage.ScaleType = Enum.ScaleType.Slice
selectorImage.SliceCenter = Rect.new(12, 12, 52, 52)
selectorImage.Visible = false
VRInventorySelector.SelectionImageObject = selectorImage
VRInventorySelector.MouseButton1Click:Connect(function(): ()
vrMoveSlotToInventory()
end)
-- Make the ScrollingFrame, which holds the rest of the Slots (however many)
ScrollingFrame = Instance.new("ScrollingFrame")
ScrollingFrame.BackgroundTransparency = 1
ScrollingFrame.Name = "ScrollingFrame"
ScrollingFrame.Size = UDim2.new(1, 0, 1, 0)
ScrollingFrame.Selectable = false
ScrollingFrame.ScrollingDirection = Enum.ScrollingDirection.Y
ScrollingFrame.BorderSizePixel = 0
ScrollingFrame.ScrollBarThickness = 8
ScrollingFrame.ScrollBarImageColor3 = Color3.new(1, 1, 1)
ScrollingFrame.VerticalScrollBarInset = Enum.ScrollBarInset.ScrollBar
ScrollingFrame.CanvasSize = UDim2.new(0, 0, 0, 0)
ScrollingFrame.Parent = InventoryFrame
UIGridFrame = Instance.new("Frame")
UIGridFrame.BackgroundTransparency = 1
UIGridFrame.Name = "UIGridFrame"
UIGridFrame.Selectable = false
UIGridFrame.Size = UDim2.new(1, -(ICON_BUFFER_PIXELS * 2), 1, 0)
UIGridFrame.Position = UDim2.new(0, ICON_BUFFER_PIXELS, 0, 0)
UIGridFrame.Parent = ScrollingFrame
UIGridLayout = Instance.new("UIGridLayout")
UIGridLayout.SortOrder = Enum.SortOrder.LayoutOrder
UIGridLayout.CellSize = UDim2.new(0, ICON_SIZE_PIXELS, 0, ICON_SIZE_PIXELS)
UIGridLayout.CellPadding = UDim2.new(0, ICON_BUFFER_PIXELS, 0, ICON_BUFFER_PIXELS)
UIGridLayout.Parent = UIGridFrame
ScrollUpInventoryButton = MakeVRRoundButton("ScrollUpButton", "rbxasset://textures/ui/Backpack/ScrollUpArrow.png")
ScrollUpInventoryButton.Size = UDim2.new(0, 34, 0, 34)
ScrollUpInventoryButton.Position =
UDim2.new(0.5, -ScrollUpInventoryButton.Size.X.Offset / 2, 0, INVENTORY_HEADER_SIZE + 3)
ScrollUpInventoryButton.Icon.Position = ScrollUpInventoryButton.Icon.Position - UDim2.new(0, 0, 0, 2)
ScrollUpInventoryButton.MouseButton1Click:Connect(function(): ()
ScrollingFrame.CanvasPosition = Vector2.new(
ScrollingFrame.CanvasPosition.X,
Clamp(
0,
ScrollingFrame.CanvasSize.Y.Offset - ScrollingFrame.AbsoluteWindowSize.Y,
ScrollingFrame.CanvasPosition.Y - (ICON_BUFFER_PIXELS + ICON_SIZE_PIXELS)
)
)
end)
ScrollDownInventoryButton = MakeVRRoundButton("ScrollDownButton", "rbxasset://textures/ui/Backpack/ScrollUpArrow.png")
ScrollDownInventoryButton.Rotation = 180
ScrollDownInventoryButton.Icon.Position = ScrollDownInventoryButton.Icon.Position - UDim2.new(0, 0, 0, 2)
ScrollDownInventoryButton.Size = UDim2.new(0, 34, 0, 34)
ScrollDownInventoryButton.Position =
UDim2.new(0.5, -ScrollDownInventoryButton.Size.X.Offset / 2, 1, -ScrollDownInventoryButton.Size.Y.Offset - 3)
ScrollDownInventoryButton.MouseButton1Click:Connect(function(): ()
ScrollingFrame.CanvasPosition = Vector2.new(
ScrollingFrame.CanvasPosition.X,
Clamp(
0,
ScrollingFrame.CanvasSize.Y.Offset - ScrollingFrame.AbsoluteWindowSize.Y,
ScrollingFrame.CanvasPosition.Y + (ICON_BUFFER_PIXELS + ICON_SIZE_PIXELS)
)
)
end)
ScrollingFrame.Changed:Connect(function(prop: string): ()
if prop == "AbsoluteWindowSize" or prop == "CanvasPosition" or prop == "CanvasSize" then
local canScrollUp: boolean = ScrollingFrame.CanvasPosition.Y ~= 0
local canScrollDown: boolean = ScrollingFrame.CanvasPosition.Y
< ScrollingFrame.CanvasSize.Y.Offset - ScrollingFrame.AbsoluteWindowSize.Y
ScrollUpInventoryButton.Visible = canScrollUp
ScrollDownInventoryButton.Visible = canScrollDown
end
end)
-- Position the frames and sizes for the Backpack GUI elements
UpdateBackpackLayout()
--Make the gamepad hint frame
local gamepadHintsFrame: Frame = Instance.new("Frame")
gamepadHintsFrame.Name = "GamepadHintsFrame"
gamepadHintsFrame.Size = UDim2.new(0, HotbarFrame.Size.X.Offset, 0, (IsTenFootInterface and 95 or 60))
gamepadHintsFrame.BackgroundTransparency = BACKGROUND_TRANSPARENCY
gamepadHintsFrame.BackgroundColor3 = BACKGROUND_COLOR
gamepadHintsFrame.Visible = false
gamepadHintsFrame.Parent = MainFrame
local gamepadHintsFrameLayout: UIListLayout = Instance.new("UIListLayout")
gamepadHintsFrameLayout.Name = "Layout"
gamepadHintsFrameLayout.Padding = UDim.new(0, 25)
gamepadHintsFrameLayout.FillDirection = Enum.FillDirection.Horizontal
gamepadHintsFrameLayout.HorizontalAlignment = Enum.HorizontalAlignment.Center
gamepadHintsFrameLayout.SortOrder = Enum.SortOrder.LayoutOrder
gamepadHintsFrameLayout.Parent = gamepadHintsFrame
local gamepadHintsFrameCorner: UICorner = Instance.new("UICorner")
gamepadHintsFrameCorner.Name = "Corner"
gamepadHintsFrameCorner.CornerRadius = BACKGROUND_CORNER_RADIUS
gamepadHintsFrameCorner.Parent = gamepadHintsFrame
local function addGamepadHint(hintImageString: string, hintTextString: string): ()
local hintFrame: Frame = Instance.new("Frame")
hintFrame.Name = "HintFrame"
hintFrame.AutomaticSize = Enum.AutomaticSize.XY
hintFrame.BackgroundTransparency = 1
hintFrame.Parent = gamepadHintsFrame
local hintLayout: UIListLayout = Instance.new("UIListLayout")
hintLayout.Name = "Layout"
hintLayout.Padding = (IsTenFootInterface and UDim.new(0, 20) or UDim.new(0, 12))
hintLayout.FillDirection = Enum.FillDirection.Horizontal
hintLayout.SortOrder = Enum.SortOrder.LayoutOrder
hintLayout.VerticalAlignment = Enum.VerticalAlignment.Center
hintLayout.Parent = hintFrame
local hintImage: ImageLabel = Instance.new("ImageLabel")
hintImage.Name = "HintImage"
hintImage.Size = (IsTenFootInterface and UDim2.new(0, 60, 0, 60) or UDim2.new(0, 30, 0, 30))
hintImage.BackgroundTransparency = 1
hintImage.Image = hintImageString
hintImage.Parent = hintFrame
local hintText: TextLabel = Instance.new("TextLabel")
hintText.Name = "HintText"
hintText.AutomaticSize = Enum.AutomaticSize.XY
hintText.FontFace = Font.new(FONT_FAMILY.Family, Enum.FontWeight.Medium, Enum.FontStyle.Normal)
hintText.TextSize = (IsTenFootInterface and 32 or 19)
hintText.BackgroundTransparency = 1
hintText.Text = hintTextString
hintText.TextColor3 = Color3.new(1, 1, 1)
hintText.TextXAlignment = Enum.TextXAlignment.Left
hintText.TextYAlignment = Enum.TextYAlignment.Center
hintText.TextWrapped = true
hintText.Parent = hintFrame
local textSizeConstraint: UITextSizeConstraint = Instance.new("UITextSizeConstraint")
textSizeConstraint.MaxTextSize = hintText.TextSize
textSizeConstraint.Parent = hintText
end
addGamepadHint(UserInputService:GetImageForKeyCode(Enum.KeyCode.ButtonX), "Remove From Hotbar")
addGamepadHint(UserInputService:GetImageForKeyCode(Enum.KeyCode.ButtonA), "Select/Swap")
addGamepadHint(UserInputService:GetImageForKeyCode(Enum.KeyCode.ButtonB), "Close Backpack")
local function resizeGamepadHintsFrame(): ()
gamepadHintsFrame.Size =
UDim2.new(HotbarFrame.Size.X.Scale, HotbarFrame.Size.X.Offset, 0, (IsTenFootInterface and 95 or 60))
gamepadHintsFrame.Position = UDim2.new(
HotbarFrame.Position.X.Scale,
HotbarFrame.Position.X.Offset,
InventoryFrame.Position.Y.Scale,
InventoryFrame.Position.Y.Offset - gamepadHintsFrame.Size.Y.Offset - ICON_BUFFER_PIXELS
)
local spaceTaken: number = 0
local gamepadHints: { Instance } = gamepadHintsFrame:GetChildren()
local filteredGamepadHints: any = {}
for _, child: Instance in pairs(gamepadHints) do
if child:IsA("GuiObject") then
table.insert(filteredGamepadHints, child)
end
end
--First get the total space taken by all the hints
for guiObjects = 1, #filteredGamepadHints do
if filteredGamepadHints[guiObjects]:IsA("GuiObject") then
filteredGamepadHints[guiObjects].Size = UDim2.new(1, 0, 1, -5)
filteredGamepadHints[guiObjects].Position = UDim2.new(0, 0, 0, 0)
spaceTaken = spaceTaken
+ (
filteredGamepadHints[guiObjects].HintText.Position.X.Offset
+ filteredGamepadHints[guiObjects].HintText.TextBounds.X
)
end
end
--The space between all the frames should be equal
local spaceBetweenElements: number = (gamepadHintsFrame.AbsoluteSize.X - spaceTaken) / (#filteredGamepadHints - 1)
for i: number = 1, #filteredGamepadHints do
filteredGamepadHints[i].Position = (
i == 1 and UDim2.new(0, 0, 0, 0)
or UDim2.new(
0,
filteredGamepadHints[i - 1].Position.X.Offset
+ filteredGamepadHints[i - 1].Size.X.Offset
+ spaceBetweenElements,
0,
0
)
)
filteredGamepadHints[i].Size = UDim2.new(
0,
(filteredGamepadHints[i].HintText.Position.X.Offset + filteredGamepadHints[i].HintText.TextBounds.X),
1,
-5
)
end
end
local searchFrame: Frame = Instance.new("Frame")
do -- Search stuff
searchFrame.Name = "Search"
searchFrame.BackgroundColor3 = SEARCH_BACKGROUND_COLOR
searchFrame.BackgroundTransparency = SEARCH_BACKGROUND_TRANSPARENCY
searchFrame.Size = UDim2.new(
0,
SEARCH_WIDTH_PIXELS - (SEARCH_BUFFER_PIXELS * 2),
0,
INVENTORY_HEADER_SIZE - (SEARCH_BUFFER_PIXELS * 2)
)
searchFrame.Position = UDim2.new(1, -searchFrame.Size.X.Offset - SEARCH_BUFFER_PIXELS, 0, SEARCH_BUFFER_PIXELS)
searchFrame.Parent = InventoryFrame
local searchFrameCorner: UICorner = Instance.new("UICorner")
searchFrameCorner.Name = "Corner"
searchFrameCorner.CornerRadius = SEARCH_CORNER_RADIUS
searchFrameCorner.Parent = searchFrame
local searchFrameBorder: UIStroke = Instance.new("UIStroke")
searchFrameBorder.Name = "Border"
searchFrameBorder.Color = SEARCH_BORDER_COLOR
searchFrameBorder.Thickness = SEARCH_BORDER_THICKNESS
searchFrameBorder.Transparency = SEARCH_BORDER_TRANSPARENCY
searchFrameBorder.Parent = searchFrame
local searchBox: TextBox = Instance.new("TextBox")
searchBox.BackgroundTransparency = 1
searchBox.Name = "TextBox"
searchBox.Text = ""
searchBox.TextColor3 = TEXT_COLOR
searchBox.TextStrokeTransparency = TEXT_STROKE_TRANSPARENCY
searchBox.TextStrokeColor3 = TEXT_STROKE_COLOR
searchBox.FontFace = Font.new(FONT_FAMILY.Family, Enum.FontWeight.Medium, Enum.FontStyle.Normal)
searchBox.PlaceholderText = SEARCH_TEXT_PLACEHOLDER
searchBox.TextColor3 = TEXT_COLOR
searchBox.TextTransparency = TEXT_STROKE_TRANSPARENCY
searchBox.TextStrokeColor3 = TEXT_STROKE_COLOR
searchBox.ClearTextOnFocus = false
searchBox.TextTruncate = Enum.TextTruncate.AtEnd
searchBox.TextSize = FONT_SIZE
searchBox.TextXAlignment = Enum.TextXAlignment.Left
searchBox.TextYAlignment = Enum.TextYAlignment.Center
searchBox.Size = UDim2.new(
0,
(SEARCH_WIDTH_PIXELS - (SEARCH_BUFFER_PIXELS * 2)) - (SEARCH_TEXT_OFFSET * 2) - 20,
0,
INVENTORY_HEADER_SIZE - (SEARCH_BUFFER_PIXELS * 2) - (SEARCH_TEXT_OFFSET * 2)
)
searchBox.AnchorPoint = Vector2.new(0, 0.5)
searchBox.Position = UDim2.new(0, SEARCH_TEXT_OFFSET, 0.5, 0)
searchBox.ZIndex = 2
searchBox.Parent = searchFrame
local xButton: TextButton = Instance.new("TextButton")
xButton.Name = "X"
xButton.Text = ""
xButton.Size = UDim2.new(0, 30, 0, 30)
xButton.Position = UDim2.new(1, -xButton.Size.X.Offset, 0.5, -xButton.Size.Y.Offset / 2)
xButton.ZIndex = 4
xButton.Visible = false
xButton.BackgroundTransparency = 1
xButton.Parent = searchFrame
local xImage: ImageButton = Instance.new("ImageButton")
xImage.Name = "X"
xImage.Image = SEARCH_IMAGE_X
xImage.BackgroundTransparency = 1
xImage.Size = UDim2.new(
0,
searchFrame.Size.Y.Offset - (SEARCH_BUFFER_PIXELS * 4),
0,
searchFrame.Size.Y.Offset - (SEARCH_BUFFER_PIXELS * 4)
)
xImage.AnchorPoint = Vector2.new(0.5, 0.5)
xImage.Position = UDim2.new(0.5, 0, 0.5, 0)
xImage.ZIndex = 1
xImage.BorderSizePixel = 0
xImage.Parent = xButton
local function search(): ()
local terms: { [string]: boolean } = {}
for word: string in searchBox.Text:gmatch("%S+") do
terms[word:lower()] = true
end
local hitTable = {}
for i: number = NumberOfHotbarSlots + 1, #Slots do -- Only search inventory slots
local slot = Slots[i]
local hits: any = slot:CheckTerms(terms)
table.insert(hitTable, { slot, hits })
slot.Frame.Visible = false
slot.Frame.Parent = InventoryFrame
end
table.sort(hitTable, function(left: any, right: any): boolean
return left[2] > right[2]
end)
ViewingSearchResults = true
local hitCount: number = 0
for _, data in ipairs(hitTable) do
local slot, hits: any = data[1], data[2]
if hits > 0 then
slot.Frame.Visible = true
slot.Frame.Parent = UIGridFrame
slot.Frame.LayoutOrder = NumberOfHotbarSlots + hitCount
hitCount = hitCount + 1
end
end
ScrollingFrame.CanvasPosition = Vector2.new(0, 0)
UpdateScrollingFrameCanvasSize()
xButton.ZIndex = 3
end
local function clearResults(): ()
if xButton.ZIndex > 0 then
ViewingSearchResults = false
for i: number = NumberOfHotbarSlots + 1, #Slots do
local slot = Slots[i]
slot.Frame.LayoutOrder = slot.Index
slot.Frame.Parent = UIGridFrame
slot.Frame.Visible = true
end
xButton.ZIndex = 0
end
UpdateScrollingFrameCanvasSize()
end
local function reset(): ()
clearResults()
searchBox.Text = ""
end
local function onChanged(property: string): ()
if property == "Text" then
local text: string = searchBox.Text
if text == "" then
searchBox.TextTransparency = TEXT_STROKE_TRANSPARENCY
clearResults()
elseif text ~= SEARCH_TEXT then
searchBox.TextTransparency = 0
search()
end
xButton.Visible = text ~= "" and text ~= SEARCH_TEXT
end
end
local function focusLost(enterPressed: boolean): ()
if enterPressed then
--TODO: Could optimize
search()
end
end
xButton.MouseButton1Click:Connect(reset)
searchBox.Changed:Connect(onChanged)
searchBox.FocusLost:Connect(focusLost)
BackpackScript.StateChanged.Event:Connect(function(isNowOpen: boolean): ()
-- InventoryIcon:getInstance("iconButton").Modal = isNowOpen -- Allows free mouse movement even in first person
if not isNowOpen then
reset()
end
end)
HotkeyFns[Enum.KeyCode.Escape.Value] = function(isProcessed: any): ()
if isProcessed then -- Pressed from within a TextBox
reset()
end
end
local function detectGamepad(lastInputType: Enum.UserInputType): ()
if lastInputType == Enum.UserInputType.Gamepad1 and not UserInputService.VREnabled then
searchFrame.Visible = false
else
searchFrame.Visible = true
end
end
UserInputService.LastInputTypeChanged:Connect(detectGamepad)
end
-- When menu is opend, disable backpack
GuiService.MenuOpened:Connect(function(): ()
BackpackGui.Enabled = false
inventoryIcon:setEnabled(false)
end)
-- When menu is closed, enable backpack
GuiService.MenuClosed:Connect(function(): ()
BackpackGui.Enabled = true
inventoryIcon:setEnabled(true)
end)
do -- Make the Inventory expand/collapse arrow (unless TopBar)
-- selene: allow(unused_variable)
local removeHotBarSlot = function(name: string, state: Enum.UserInputState, input: InputObject): ()
if state ~= Enum.UserInputState.Begin then
return
end
if not GuiService.SelectedObject then
return
end
for i: number = 1, NumberOfHotbarSlots do
if Slots[i].Frame == GuiService.SelectedObject and Slots[i].Tool then
Slots[i]:MoveToInventory()
return
end
end
end
local function openClose(): ()
if not next(Dragging) then -- Only continue if nothing is being dragged
InventoryFrame.Visible = not InventoryFrame.Visible
local nowOpen: boolean = InventoryFrame.Visible
AdjustHotbarFrames()
HotbarFrame.Active = not HotbarFrame.Active
for i: number = 1, NumberOfHotbarSlots do
Slots[i]:SetClickability(not nowOpen)
end
end
if InventoryFrame.Visible then
if GamepadEnabled then
if GAMEPAD_INPUT_TYPES[UserInputService:GetLastInputType()] then
resizeGamepadHintsFrame()
gamepadHintsFrame.Visible = not UserInputService.VREnabled
end
enableGamepadInventoryControl()
end
if BackpackPanel and VRService.VREnabled then
BackpackPanel:SetVisible(true)
BackpackPanel:RequestPositionUpdate()
end
else
if GamepadEnabled then
gamepadHintsFrame.Visible = false
end
disableGamepadInventoryControl()
end
if InventoryFrame.Visible then
ContextActionService:BindAction("BackpackRemoveSlot", removeHotBarSlot, false, Enum.KeyCode.ButtonX)
else
ContextActionService:UnbindAction("BackpackRemoveSlot")
end
BackpackScript.IsOpen = InventoryFrame.Visible
BackpackScript.StateChanged:Fire(InventoryFrame.Visible)
end
StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false)
BackpackScript.OpenClose = openClose -- Exposed
end
-- Now that we're done building the GUI, we Connect to all the major events
-- Wait for the player if LocalPlayer wasn't ready earlier
while not Player do
task.wait()
Player = Players.LocalPlayer
end
-- Listen to current and all future characters of our player
Player.CharacterAdded:Connect(OnCharacterAdded)
if Player.Character then
OnCharacterAdded(Player.Character)
end
do -- Hotkey stuff
-- Listen to key down
UserInputService.InputBegan:Connect(OnInputBegan)
-- Listen to ANY TextBox gaining or losing focus, for disabling all hotkeys
UserInputService.TextBoxFocused:Connect(function(): ()
TextBoxFocused = true
end)
UserInputService.TextBoxFocusReleased:Connect(function(): ()
TextBoxFocused = false
end)
-- Manual unequip for HopperBins on drop button pressed
HotkeyFns[DROP_HOTKEY_VALUE] = function(): () --NOTE: HopperBin
if ActiveHopper then
UnequipAllTools()
end
end
-- Listen to keyboard status, for showing/hiding hotkey labels
UserInputService.LastInputTypeChanged:Connect(OnUISChanged)
OnUISChanged()
-- Listen to gamepad status, for allowing gamepad style selection/equip
if UserInputService:GetGamepadConnected(Enum.UserInputType.Gamepad1) then
gamepadConnected()
end
UserInputService.GamepadConnected:Connect(function(gamepadEnum: Enum.UserInputType): ()
if gamepadEnum == Enum.UserInputType.Gamepad1 then
gamepadConnected()
end
end)
UserInputService.GamepadDisconnected:Connect(function(gamepadEnum: Enum.UserInputType): ()
if gamepadEnum == Enum.UserInputType.Gamepad1 then
gamepadDisconnected()
end
end)
end
-- Sets whether the backpack is enabled or not
function BackpackScript:SetBackpackEnabled(Enabled: boolean): ()
BackpackEnabled = Enabled
end
-- Returns if the backpack's inventory is open
function BackpackScript:IsOpened(): boolean
return BackpackScript.IsOpen
end
-- Returns on if the backpack is enabled or not
function BackpackScript:GetBackpackEnabled(): boolean
return BackpackEnabled
end
-- Returns the BindableEvent for when the backpack state changes
function BackpackScript:GetStateChangedEvent(): BindableEvent
return BackpackScript.StateChanged
end
-- Update every heartbeat the icon state
RunService.Heartbeat:Connect(function(): ()
OnIconChanged(BackpackEnabled)
end)
-- Update the transparency of the backpack based on GuiService.PreferredTransparency
local function OnPreferredTransparencyChanged(): ()
local preferredTransparency: number = GuiService.PreferredTransparency
BACKGROUND_TRANSPARENCY = BACKGROUND_TRANSPARENCY_DEFAULT * preferredTransparency
InventoryFrame.BackgroundTransparency = BACKGROUND_TRANSPARENCY
SLOT_LOCKED_TRANSPARENCY = SLOT_LOCKED_TRANSPARENCY_DEFAULT * preferredTransparency
for _, slot in ipairs(Slots) do
slot.Frame.BackgroundTransparency = SLOT_LOCKED_TRANSPARENCY
end
SEARCH_BACKGROUND_TRANSPARENCY = SEARCH_BACKGROUND_TRANSPARENCY_DEFAULT * preferredTransparency
searchFrame.BackgroundTransparency = SEARCH_BACKGROUND_TRANSPARENCY
end
GuiService:GetPropertyChangedSignal("PreferredTransparency"):Connect(OnPreferredTransparencyChanged)
return BackpackScript - Edit
03:12:20.378
- Edit
03:12:20.378
============================== - Edit
03:12:20.378 📜 ReplicatedStorage.Controllers.SpawnEffectsController - Edit
03:12:20.378 ==============================
- Edit
03:12:20.378 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
local v1 = game:GetService("ReplicatedStorage")
local u2 = require(v1.Packages.Net)
local u3 = require(v1.Shared.VFX)
return {
["Start"] = function(_) --[[Function name: Start, line 7]]
--[[
Upvalues:
[1] = u2
[2] = u3
--]]
u2:RemoteEvent("GameService/SpawnEffect").OnClientEvent:Connect(function(p4, _) --[[Anonymous function at line 9]]
--[[
Upvalues:
[1] = u3
--]]
local v5 = script[p4]:Clone()
v5.Parent = workspace
u3.emit(v5)
for _, v6 in v5:GetDescendants() do
if v6:IsA("Sound") then
v6:Play()
end
end
task.wait(6)
v5:Destroy()
end)
end
} - Edit
03:12:20.378
- Edit
03:12:20.379
============================== - Edit
03:12:20.379 📜 ReplicatedStorage.Controllers.EffectController - Edit
03:12:20.379 ==============================
- Edit
03:12:20.379 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
require(script.Types)
local EffectsManager = {
Effects = {},
ActiveEffects = {}
}
function EffectsManager:Activate(effectName)
local effect = self.Effects[effectName]
if not effect then
return false
end
if type(effect.Activate) == "function" then
effect:Activate()
end
return true
end
function EffectsManager:Run(playerId, effectName)
local effect = self.Effects[effectName]
if not effect then
return false, false
end
if not self.ActiveEffects[effectName] then
self.ActiveEffects[effectName] = {}
end
local previousActiveEffects = table.clone(self.ActiveEffects[effectName])
self.ActiveEffects[effectName][playerId] = true
if next(previousActiveEffects) then
if type(effect.OnUpdate) == "function" then
effect:OnUpdate()
end
return false, true
else
if type(effect.OnStart) == "function" then
effect:OnStart()
end
return true, true
end
end
function EffectsManager:Stop(playerId, effectName)
local effect = self.Effects[effectName]
if not effect then
return false
end
if not self.ActiveEffects[effectName] then
return false
end
if not next(self.ActiveEffects[effectName]) then
return false
end
self.ActiveEffects[effectName][playerId] = nil
if type(effect.OnUpdate) == "function" then
effect:OnUpdate()
end
if next(self.ActiveEffects[effectName]) then
return false
end
self.ActiveEffects[effectName] = nil
if type(effect.OnStop) == "function" then
effect:OnStop()
end
return true
end
function EffectsManager:Load()
for _, effectModule in script.Effects:GetChildren() do
if effectModule:IsA("ModuleScript") then
local success, effectTable = pcall(require, effectModule)
if success and type(effectTable) == "table" then
if type(effectTable.OnLoad) == "function" then
local loadSuccess, loadError = pcall(effectTable.OnLoad, effectTable)
if not loadSuccess then
warn(string.format(
"Effect %s failed to call Load function:\n%s",
effectModule:GetFullName(),
loadError or "yielded (possibly)"
))
continue
end
end
self.Effects[effectModule.Name] = effectTable
else
warn(string.format(
"Effect %s failed to load:\n%s",
effectModule:GetFullName(),
effectTable or "yielded (possibly)"
))
end
end
end
end
function EffectsManager:Start()
end
return EffectsManager - Edit
03:12:20.379
- Edit
03:12:20.379
============================== - Edit
03:12:20.379 📜 ReplicatedStorage.Controllers.EffectController.Types - Edit
03:12:20.379 ==============================
- Edit
03:12:20.379 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
return nil - Edit
03:12:20.379
- Edit
03:12:20.379
============================== - Edit
03:12:20.379 📜 ReplicatedStorage.Controllers.EffectController.Effects.Space - Edit
03:12:20.379 ==============================
- Edit
03:12:20.379 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
local u1 = game:GetService("ReplicatedStorage")
game:GetService("TweenService")
require(script:FindFirstAncestor("Effects").Parent.Types)
local v2 = {}
local u3 = require(u1.Controllers.EffectController)
local u4 = require(u1.Controllers.SoundController)
local u5 = require(u1.Controllers.CycleController)
local v6 = require(u1.Packages.Trove)
require(u1.Packages.Net)
local _ = script.Name
local u7 = v6.new()
local _ = workspace.CurrentCamera
function v2.OnStart(_) --[[Anonymous function at line 19]]
--[[
Upvalues:
[1] = u1
[2] = u7
[3] = u4
[4] = u5
[5] = u3
--]]
u1:SetAttribute("Effect_Space", true)
u7:Add(function() --[[Anonymous function at line 21]]
--[[
Upvalues:
[1] = u1
--]]
u1:SetAttribute("Effect_Space", nil)
end)
u4:UpdateOST()
u5:Update()
local u8 = u7:Extend()
local u9 = true
u7:Add(function() --[[Anonymous function at line 33]]
--[[
Upvalues:
[1] = u9
--]]
u9 = false
end)
local u10 = nil
local function v15() --[[Anonymous function at line 39]]
--[[
Upvalues:
[1] = u1
[2] = u9
[3] = u10
[4] = u3
[5] = u4
[6] = u5
[7] = u8
--]]
local v11 = u1:GetAttribute("NyanCatsEvent")
local v12
if u9 then
if v11 then
v12 = script.Nyan
else
v12 = script.Space
end
else
v12 = nil
end
if v12 ~= u10 then
u10 = v12
u3:Activate("Blink")
u4:UpdateOST()
u5:Update()
u8:Destroy()
if v12 then
local v13 = u8:Clone(v12)
v13.Parent = workspace
v13.spacemeshbg.Transparency = 0
for _, v14 in v13:GetDescendants() do
if v14:IsA("ParticleEmitter") or v14:IsA("Beam") then
v14.Enabled = true
end
end
end
end
end
u1:GetAttributeChangedSignal("NyanCatsEvent"):Connect(v15)
u7:Add(task.spawn(v15))
u7:Add(v15)
end
function v2.OnStop(_) --[[Anonymous function at line 75]]
--[[
Upvalues:
[1] = u7
--]]
u7:Destroy()
end
function v2.OnLoad(_) --[[Anonymous function at line 79]] end
return v2 - Edit
03:12:20.379
- Edit
03:12:20.379
============================== - Edit
03:12:20.379 📜 ReplicatedStorage.Controllers.EffectController.Effects.Blink - Edit
03:12:20.380 ==============================
- Edit
03:12:20.380 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
local u1 = game:GetService("ReplicatedStorage")
local v2 = game:GetService("TweenService")
require(script:FindFirstAncestor("Effects").Parent.Types)
local v3 = {}
local _ = script.Name
local u4 = Instance.new("ColorCorrectionEffect")
u4.Brightness = 0
u4.TintColor = Color3.fromRGB(255, 255, 255)
u4.Parent = workspace.CurrentCamera
local u5 = v2:Create(u4, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.In), {
["Brightness"] = 0
})
function v3.Activate(_) --[[Anonymous function at line 19]]
--[[
Upvalues:
[1] = u4
[2] = u1
[3] = u5
--]]
u4.Brightness = u1:GetAttribute("WaterEvent") and 2 or 1
u5:Cancel()
u5:Play()
end
return v3 - Edit
03:12:20.380
- Edit
03:12:20.380
============================== - Edit
03:12:20.380 📜 ReplicatedStorage.Controllers.EffectController.Effects.GrassRecolor - Edit
03:12:20.380 ==============================
- Edit
03:12:20.380 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
local u1 = game:GetService("ReplicatedStorage")
game:GetService("TweenService")
require(script:FindFirstAncestor("Effects").Parent.Types)
local v2 = {}
local u3 = require(u1.Packages.CreateTween)
local u4 = require(u1.Packages.Observers)
local v5 = require(u1.Packages.Signal)
local _ = script.Name
local u6 = {
["Context"] = "Default",
["Top"] = Color3.fromRGB(31, 128, 29),
["Bottom"] = Color3.fromRGB(31, 128, 29),
["TweenTime"] = 0
}
local u7 = u6
local u8 = v5.new()
local function u11() --[[Anonymous function at line 30]]
--[[
Upvalues:
[1] = u6
[2] = u1
[3] = u7
[4] = u8
--]]
local v9 = u6
local v10
if u1:GetAttribute("ConcertEvent") then
v10 = {
["Context"] = "Concert",
["Top"] = Color3.fromRGB(157, 155, 151),
["Bottom"] = Color3.fromRGB(46, 71, 89),
["TweenTime"] = 2
}
elseif u1:GetAttribute("RapConcertEvent") then
v10 = {
["Context"] = "RapConcert",
["Top"] = Color3.fromRGB(157, 155, 151),
["Bottom"] = Color3.fromRGB(46, 71, 89),
["TweenTime"] = 2
}
elseif u1:GetAttribute("GalaxyEvent") then
v10 = {
["Context"] = "GalaxyEvent",
["Top"] = Color3.fromRGB(42, 99, 255),
["Bottom"] = Color3.fromRGB(42, 99, 255),
["TweenTime"] = 2
}
elseif u1:GetAttribute("BrazilEvent") then
v10 = {
["Context"] = "Concert",
["Top"] = Color3.fromRGB(215, 92, 31),
["Bottom"] = Color3.fromRGB(215, 92, 31),
["TweenTime"] = 2
}
elseif u1:GetAttribute("CrabRave") then
v10 = {
["Context"] = "CrabRave",
["Top"] = Color3.fromRGB(235, 178, 55),
["Bottom"] = Color3.fromRGB(235, 178, 55),
["TweenTime"] = 1.95
}
elseif u1:GetAttribute("WaterEvent") then
v10 = {
["Context"] = "WaterEvent",
["Top"] = Color3.fromRGB(226, 155, 64),
["Bottom"] = Color3.fromRGB(226, 155, 64),
["TweenTime"] = 0
}
elseif u1:GetAttribute("MoltenEvent") then
v10 = {
["Context"] = "Molten",
["Top"] = Color3.fromRGB(0, 0, 0),
["Bottom"] = Color3.fromRGB(0, 0, 0),
["TweenTime"] = 0.5
}
else
v10 = u1:GetAttribute("Snow") and {
["Context"] = "Snow",
["Top"] = Color3.fromRGB(190, 190, 190),
["Bottom"] = Color3.fromRGB(190, 190, 190),
["TweenTime"] = 8
} or v9
end
if u7.Context ~= v10.Context then
u7 = v10
u8:Fire()
end
end
function v2.OnStart(_) --[[Anonymous function at line 98]]
--[[
Upvalues:
[1] = u11
--]]
u11()
end
function v2.OnUpdate(_) --[[Anonymous function at line 102]]
--[[
Upvalues:
[1] = u11
--]]
u11()
end
function v2.OnLoad(_) --[[Anonymous function at line 106]]
--[[
Upvalues:
[1] = u4
[2] = u3
[3] = u7
[4] = u8
--]]
u4.observeTag("Grass", function(u12) --[[Anonymous function at line 107]]
--[[
Upvalues:
[1] = u3
[2] = u7
[3] = u8
--]]
local u13 = nil
local function v19() --[[Anonymous function at line 110]]
--[[
Upvalues:
[1] = u13
[2] = u3
[3] = u12
[4] = u7
--]]
if u13 then
u13:Cancel()
end
local v14 = u3
local v15 = u12
local v16 = TweenInfo.new(u7.TweenTime)
local v17 = {}
local v18
if u12:GetAttribute("Bottom") then
v18 = u7.Bottom
else
v18 = u7.Top
end
v17.Color = v18
u13 = v14(v15, v16, v17)
end
local u20 = u8:Connect(v19)
task.spawn(v19)
return function() --[[Anonymous function at line 123]]
--[[
Upvalues:
[1] = u20
[2] = u13
--]]
u20:Disconnect()
u13:Cancel()
end
end, { workspace })
end
return v2 - Edit
03:12:20.380
- Edit
03:12:20.380
============================== - Edit
03:12:20.380 📜 ReplicatedStorage.Controllers.EffectController.Effects.WallRecolor - Edit
03:12:20.380 ==============================
- Edit
03:12:20.380 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
local u1 = game:GetService("ReplicatedStorage")
game:GetService("TweenService")
require(script:FindFirstAncestor("Effects").Parent.Types)
local v2 = {}
local u3 = require(u1.Packages.CreateTween)
local u4 = require(u1.Packages.Observers)
local v5 = require(u1.Packages.Signal)
local _ = script.Name
local u6 = {
["Context"] = "Default",
["Color"] = Color3.fromRGB(106, 57, 9)
}
local u7 = u6
local u8 = v5.new()
local function u11() --[[Anonymous function at line 26]]
--[[
Upvalues:
[1] = u6
[2] = u1
[3] = u7
[4] = u8
--]]
local v9 = u6
local v10
if u1:GetAttribute("ConcertEvent") then
v10 = {
["Context"] = "Concert",
["Color"] = Color3.fromRGB(46, 71, 89)
}
elseif u1:GetAttribute("RapConcertEvent") then
v10 = {
["Context"] = "RapConcert",
["Color"] = Color3.fromRGB(46, 71, 89)
}
else
v10 = u1:GetAttribute("GalaxyEvent") and {
["Context"] = "GalaxyEvent",
["Color"] = Color3.fromRGB(20, 57, 67)
} or v9
end
if u7.Context ~= v10.Context then
u7 = v10
u8:Fire()
end
end
function v2.OnStart(_) --[[Anonymous function at line 53]]
--[[
Upvalues:
[1] = u11
--]]
u11()
end
function v2.OnUpdate(_) --[[Anonymous function at line 57]]
--[[
Upvalues:
[1] = u11
--]]
u11()
end
function v2.OnLoad(_) --[[Anonymous function at line 61]]
--[[
Upvalues:
[1] = u4
[2] = u3
[3] = u7
[4] = u8
--]]
u4.observeTag("Wall", function(u12) --[[Anonymous function at line 62]]
--[[
Upvalues:
[1] = u3
[2] = u7
[3] = u8
--]]
local u13 = nil
local function v14() --[[Anonymous function at line 65]]
--[[
Upvalues:
[1] = u13
[2] = u3
[3] = u12
[4] = u7
--]]
if u13 then
u13:Cancel()
end
u13 = u3(u12, TweenInfo.new(2), {
["Color"] = u7.Color
})
end
local u15 = u8:Connect(v14)
task.spawn(v14)
return function() --[[Anonymous function at line 78]]
--[[
Upvalues:
[1] = u15
[2] = u13
--]]
u15:Disconnect()
u13:Cancel()
end
end, { workspace })
end
return v2 - Edit
03:12:20.380
- Edit
03:12:20.381
============================== - Edit
03:12:20.381 📜 ReplicatedStorage.Controllers.EffectController.Effects.WallBottomRecolor - Edit
03:12:20.381 ==============================
- Edit
03:12:20.381 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
local u1 = game:GetService("ReplicatedStorage")
game:GetService("TweenService")
require(script:FindFirstAncestor("Effects").Parent.Types)
local v2 = {}
local u3 = require(u1.Packages.CreateTween)
local u4 = require(u1.Packages.Observers)
local v5 = require(u1.Packages.Signal)
local _ = script.Name
local u6 = {
["Context"] = "Default",
["Color"] = Color3.fromRGB(99, 95, 98)
}
local u7 = u6
local u8 = v5.new()
local function u11() --[[Anonymous function at line 26]]
--[[
Upvalues:
[1] = u6
[2] = u1
[3] = u7
[4] = u8
--]]
local v9 = u6
local v10
if u1:GetAttribute("ConcertEvent") then
v10 = {
["Context"] = "Concert",
["Color"] = Color3.fromRGB(17, 17, 17)
}
else
v10 = u1:GetAttribute("RapConcertEvent") and {
["Context"] = "RapConcert",
["Color"] = Color3.fromRGB(17, 17, 17)
} or v9
end
if u7.Context ~= v10.Context then
u7 = v10
u8:Fire()
end
end
function v2.OnStart(_) --[[Anonymous function at line 48]]
--[[
Upvalues:
[1] = u11
--]]
u11()
end
function v2.OnUpdate(_) --[[Anonymous function at line 52]]
--[[
Upvalues:
[1] = u11
--]]
u11()
end
function v2.OnLoad(_) --[[Anonymous function at line 56]]
--[[
Upvalues:
[1] = u4
[2] = u3
[3] = u7
[4] = u8
--]]
u4.observeTag("WallBottom", function(u12) --[[Anonymous function at line 57]]
--[[
Upvalues:
[1] = u3
[2] = u7
[3] = u8
--]]
local u13 = nil
local function v14() --[[Anonymous function at line 60]]
--[[
Upvalues:
[1] = u13
[2] = u3
[3] = u12
[4] = u7
--]]
if u13 then
u13:Cancel()
end
u13 = u3(u12, TweenInfo.new(2), {
["Color"] = u7.Color
})
end
local u15 = u8:Connect(v14)
task.spawn(v14)
return function() --[[Anonymous function at line 73]]
--[[
Upvalues:
[1] = u15
[2] = u13
--]]
u15:Disconnect()
u13:Cancel()
end
end, { workspace })
end
return v2 - Edit
03:12:20.381
- Edit
03:12:20.381
============================== - Edit
03:12:20.381 📜 ReplicatedStorage.Controllers.ShopController - Edit
03:12:20.381 ==============================
- Edit
03:12:20.381 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- Decompiled with Velocity Script Decompiler
local v_u_1 = game:GetService("ReplicatedStorage")
local v_u_2 = game:GetService("Players")
game:GetService("MarketplaceService")
local v3 = v_u_1:WaitForChild("Controllers")
local v_u_4 = require(v3.InterfaceController)
local v5 = v_u_1:WaitForChild("Packages")
local v_u_6 = require(v_u_1.Packages.Gradients)
local v_u_7 = require(v5.Synchronizer)
local v_u_8 = require(v5.Observers)
local v_u_9 = require(v5.FFlags)
local v10 = require(v5.Signal)
local v_u_11 = require(v5.Timer)
local v_u_12 = require(v5.Trove)
local v13 = require(v5.Net)
local v14 = v_u_1:WaitForChild("Classes")
local v_u_15 = require(v14.AnimatedButton)
local v16 = v_u_1:WaitForChild("Utils")
local v_u_17 = require(v16.NumberUtils)
local v_u_18 = require(v16.TimeUtils)
local v19 = v_u_1:WaitForChild("Shared")
local v_u_20 = require(v19.Animals)
local v_u_21 = require(v19.Marketplace)
require(v19.Updates)
local v_u_22 = require(v19.Policy)
local v23 = v_u_1:WaitForChild("Datas")
local v_u_24 = require(v23.ServerLuck)
local v_u_25 = require(v23.LuckyBlocks)
local v_u_26 = require(v23.Mutations)
local v_u_27 = require(v23.Shop)
local v_u_28 = v_u_2.LocalPlayer
local v29 = v_u_28.PlayerGui
local v_u_30 = v29:WaitForChild("Shop").Shop
local v_u_31 = v29:WaitForChild("GiftPlayer").GiftPlayer
local v_u_32 = v_u_31:WaitForChild("Header"):WaitForChild("Close")
local v_u_33 = v_u_31:WaitForChild("Main"):WaitForChild("List")
local v_u_34 = v_u_33:WaitForChild("Template")
local v35 = v_u_30.GiftPlayerSelect
local v_u_36 = v35:WaitForChild("GiftButton")
local v_u_37 = v_u_36:WaitForChild("Txt")
local v_u_38 = v35:WaitForChild("PlayerSelected")
local v_u_39 = v_u_38:WaitForChild("PlayerImage"):WaitForChild("Headshot")
local v_u_40 = v_u_38:WaitForChild("PlayerName")
local v_u_41 = v13:RemoteEvent("ShopService/Purchase")
local v_u_42 = v_u_11.new(300)
local v_u_43 = nil
local v_u_44 = v10.new()
local v_u_45 = nil
local v46 = {}
local function v_u_78()
-- upvalues: (copy) v_u_30, (copy) v_u_22, (copy) v_u_2, (copy) v_u_9, (copy) v_u_18, (copy) v_u_25, (copy) v_u_12, (copy) v_u_1, (copy) v_u_20, (ref) v_u_45, (copy) v_u_26, (copy) v_u_15, (copy) v_u_41, (ref) v_u_43, (copy) v_u_21, (copy) v_u_17
local v47 = v_u_30.Content.List.LuckyBlocksList
local v_u_48 = v_u_30.Content.List.LuckyBlocks
v47.Visible = false
v_u_48.Visible = false
local v49 = v_u_22.getPolicy(v_u_2.LocalPlayer)
if v49 and not v49.ArePaidRandomItemsRestricted then
v47.Visible = true
v_u_48.Visible = true
task.spawn(function()
-- upvalues: (ref) v_u_9, (copy) v_u_48, (ref) v_u_18
while true do
local v50 = workspace:GetServerTimeNow()
local v51 = v_u_9:GetInstant("LuckyBlockEndTimer", 1753545600) - v50
v_u_48.Text = v51 <= 0 and "LUCKY BLOCKS" or ("LUCKY BLOCKS (%*)"):format((v_u_18:E(v51)))
task.wait(1)
end
end)
for _, v_u_52 in v47:GetChildren() do
local v_u_53 = v_u_25[v_u_52.Name]
if v_u_53 then
local v_u_54 = v_u_53.ProductId
if v_u_54 then
local v_u_55 = v_u_12.new()
local v_u_56 = nil
local function v_u_68(p57)
-- upvalues: (copy) v_u_52, (ref) v_u_56, (ref) v_u_1, (copy) v_u_53, (ref) v_u_20, (copy) v_u_55
v_u_52.Odds.Visible = p57
if p57 == v_u_56 then
return
else
v_u_56 = p57
if p57 then
local v58 = v_u_1:GetAttribute("GalaxyEvent") and "Galaxy" or nil
local v59 = {}
for v60, v61 in v_u_53.Animals do
table.insert(v59, {
["animal"] = v60,
["chance"] = v61
})
end
table.sort(v59, function(p62, p63)
return p63.chance < p62.chance
end)
for v64 = 1, 4 do
local v65 = v_u_52.Odds:FindFirstChild((tostring(v64)))
if v65 then
local v66 = v59[v64]
if v66 then
local v67 = v_u_20:AttachOnViewport(v66.animal, v65, true, v58)
if v67 then
v_u_55:Add(v67)
end
v65.Chance.Text = ("%*%%"):format(v66.chance)
v65.Visible = true
else
v65.Visible = false
end
end
end
else
v_u_55:Clean()
end
end
end
local v_u_69 = v_u_12.new()
local function v_u_73()
-- upvalues: (copy) v_u_69, (ref) v_u_45, (ref) v_u_1, (ref) v_u_26, (copy) v_u_52, (ref) v_u_20
v_u_69:Destroy()
if v_u_45:IsOpened() then
local v70 = v_u_1:GetAttribute("GalaxyEvent") and "Galaxy" or nil
local v71
if v70 then
v71 = v_u_26[v70]
else
v71 = v70
end
if v71 then
v_u_52.Mutation.Text = v71.DisplayWithRichText
v_u_52.Mutation.Visible = true
else
v_u_52.Mutation.Visible = nil
end
local v72 = v_u_20:AttachOnViewport(v_u_52.Name, v_u_52.IconViewport, true, v70)
if v72 then
v_u_69:Add(v72)
end
end
end
task.spawn(v_u_73)
v_u_45.OnClose:Connect(function()
-- upvalues: (copy) v_u_68, (copy) v_u_73
v_u_68(false)
v_u_73()
end)
v_u_45.OnOpen:Connect(function()
-- upvalues: (copy) v_u_68, (copy) v_u_73
v_u_68(true)
v_u_73()
end)
v_u_1:GetAttributeChangedSignal("GalaxyEvent"):Connect(function()
-- upvalues: (copy) v_u_73, (copy) v_u_52, (copy) v_u_68
task.spawn(v_u_73)
if v_u_52.Odds.Visible then
v_u_68(false)
v_u_68(true)
end
end)
local v74 = v_u_15.new(v_u_52.Buy)
v74:Animate()
v74.OnActivated:Connect(function()
-- upvalues: (ref) v_u_41, (copy) v_u_54, (ref) v_u_43
v_u_41:FireServer(v_u_54, v_u_43)
end)
task.spawn(function()
-- upvalues: (ref) v_u_21, (copy) v_u_54, (copy) v_u_52, (ref) v_u_17
local v75 = v_u_21:GetProductInfo(v_u_54, "Product")
local v76 = v_u_52.Buy.Price
local v77 = v75.PriceInRobux
v76.Text = ("%*%*"):format("\238\128\130", v77 == 999999999 and "???" or v_u_17:Comma(v77))
end)
end
end
end
end
end
local function v_u_85(p_u_79)
-- upvalues: (copy) v_u_28, (copy) v_u_34, (copy) v_u_2, (copy) v_u_15, (ref) v_u_43, (copy) v_u_31, (copy) v_u_37, (copy) v_u_38, (copy) v_u_40, (copy) v_u_39, (copy) v_u_44, (copy) v_u_33
if p_u_79 ~= v_u_28 then
local v80 = v_u_34:Clone()
v80.Name = p_u_79.Name
v80.PlayerName.Text = p_u_79.Name
local v81 = v80.PlayerImage.Headshot
local v_u_82 = ""
if pcall(function()
-- upvalues: (ref) v_u_82, (ref) v_u_2, (copy) p_u_79
v_u_82 = v_u_2:GetUserThumbnailAsync(p_u_79.UserId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size100x100)
end) then
v81.Image = v_u_82
end
local v83 = v80.Gift
local v84 = v_u_15.new(v83)
v84:Animate()
v84.OnActivated:Connect(function()
-- upvalues: (ref) v_u_43, (copy) p_u_79, (ref) v_u_31, (ref) v_u_37, (ref) v_u_38, (ref) v_u_40, (ref) v_u_39, (ref) v_u_82, (ref) v_u_44
v_u_43 = p_u_79.UserId
v_u_31.Visible = false
v_u_37.Text = "Back"
v_u_38.Visible = true
v_u_40.Text = "@" .. p_u_79.Name
v_u_39.Image = v_u_82
v_u_44:Fire(true)
end)
v80.Visible = true
v80.Parent = v_u_33
end
end
function v46.Start(_)
-- upvalues: (ref) v_u_45, (copy) v_u_4, (copy) v_u_30, (copy) v_u_7, (copy) v_u_28, (copy) v_u_8, (copy) v_u_27, (copy) v_u_17, (copy) v_u_21, (copy) v_u_15, (copy) v_u_41, (ref) v_u_43, (copy) v_u_42, (copy) v_u_44, (copy) v_u_6, (copy) v_u_24, (copy) v_u_36, (copy) v_u_38, (copy) v_u_37, (copy) v_u_31, (copy) v_u_32, (copy) v_u_18, (copy) v_u_11, (copy) v_u_78, (copy) v_u_2, (copy) v_u_85, (copy) v_u_33
v_u_45 = v_u_4:Register("Shop", v_u_30, "TopQuint")
v_u_45:AttachCloseButton(v_u_30.Header.Close)
v_u_45:Close()
v_u_7:WaitAndCall(v_u_28, function(p_u_86)
-- upvalues: (ref) v_u_8, (ref) v_u_27, (ref) v_u_17, (ref) v_u_21, (ref) v_u_15, (ref) v_u_41, (ref) v_u_43, (ref) v_u_42, (ref) v_u_44, (ref) v_u_6, (ref) v_u_24
v_u_8.observeTag("CashProduct", function(p87)
-- upvalues: (ref) v_u_27, (copy) p_u_86, (ref) v_u_17, (ref) v_u_21, (ref) v_u_15, (ref) v_u_41, (ref) v_u_43, (ref) v_u_42
local v88 = p87.Name
local v_u_89 = tonumber(v88)
local v_u_90 = v_u_27[v_u_89]
if v_u_90 then
local v_u_91 = p87:WaitForChild("Buy", 5)
local v_u_92 = p87:WaitForChild("Icon", 5)
local v_u_93 = p87:WaitForChild("Amount", 5)
local function v96()
-- upvalues: (copy) v_u_93, (copy) v_u_90, (ref) p_u_86, (ref) v_u_17
if v_u_93 then
local v94 = v_u_90.Value or 0
local v95 = p_u_86:Get("Rebirth") or 0
if v95 > 0 then
v94 = v94 * (v95 <= 1 and 1.5 or v95)
end
v_u_93.Text = ("$%*"):format((v_u_17:Comma(v94)))
end
end
local function v_u_101()
-- upvalues: (ref) v_u_21, (copy) v_u_89, (copy) v_u_91, (ref) v_u_17, (copy) v_u_92
local v97 = v_u_21:GetProductInfo(v_u_89, "Product")
if v_u_91 then
local v98 = v_u_91.Txt
local v99
if v97.PriceInRobux == nil then
v99 = "Failed to load!"
else
local v100 = v97.PriceInRobux
v99 = ("%*%*"):format("\238\128\130", v100 == 999999999 and "???" or v_u_17:Comma(v100)) or "Failed to load!"
end
v98.Text = v99
end
if v_u_92 and v97.Icon then
v_u_92.ScaleType = Enum.ScaleType.Fit
v_u_92.Image = v97.Icon
end
end
v_u_101()
p_u_86:OnChanged("Rebirth", v96, true)
local v102 = v_u_15.new(v_u_91)
v102:Animate()
v102.OnActivated:Connect(function()
-- upvalues: (ref) v_u_41, (copy) v_u_89, (ref) v_u_43
v_u_41:FireServer(v_u_89, v_u_43)
end)
v_u_42.Tick:Connect(function()
-- upvalues: (copy) v_u_101
v_u_101()
end)
end
end)
v_u_8.observeTag("ItemProduct", function(p103)
-- upvalues: (ref) v_u_27, (ref) v_u_21, (ref) v_u_17, (ref) v_u_44, (ref) v_u_42, (copy) p_u_86, (ref) v_u_15, (ref) v_u_41, (ref) v_u_43
local v104 = p103.Name
local v_u_105 = tonumber(v104)
local v_u_106 = v_u_27[v_u_105]
if v_u_106 then
local v107 = p103:WaitForChild("Buy", 5)
local v_u_108
if v107 then
v_u_108 = v107:WaitForChild("Price", 5)
else
v_u_108 = v107
end
local v_u_109 = p103:WaitForChild("Icon", 5)
local v_u_110 = false
local v_u_111 = false
local function v_u_116()
-- upvalues: (ref) v_u_21, (copy) v_u_105, (copy) v_u_108, (ref) v_u_110, (ref) v_u_111, (ref) v_u_17, (copy) v_u_109
local v112 = v_u_21:GetProductInfo(v_u_105, "Product")
if v_u_108 and (v_u_110 == false or v_u_111 == true) then
local v113 = v_u_108
local v114
if v112.PriceInRobux == nil then
v114 = "Failed to load!"
else
local v115 = v112.PriceInRobux
v114 = ("%*%*"):format("\238\128\130", v115 == 999999999 and "???" or v_u_17:Comma(v115)) or "Failed to load!"
end
v113.Text = v114
end
if v112.Icon and v_u_109 then
v_u_109.ScaleType = Enum.ScaleType.Fit
v_u_109.Image = v112.Icon
end
end
v_u_44:Connect(function(p117)
-- upvalues: (ref) v_u_111, (ref) v_u_110, (copy) v_u_108, (copy) v_u_116
v_u_111 = p117
if p117 or not v_u_110 then
v_u_116()
else
v_u_110 = true
v_u_108.Text = "Owned"
end
end)
v_u_42.Tick:Connect(function()
-- upvalues: (ref) v_u_110, (copy) v_u_116
if v_u_110 == false then
v_u_116()
end
end)
p_u_86:OnDictionaryInserted("Items", function(_, p118)
-- upvalues: (copy) v_u_106, (ref) v_u_110, (copy) v_u_108
if p118 == v_u_106.Display then
v_u_110 = true
v_u_108.Text = "Owned"
end
end)
if p_u_86:Get((("Items.%*"):format(v_u_106.Display))) == true then
v_u_110 = true
v_u_108.Text = "Owned"
end
v_u_116()
local v119 = v_u_15.new(v107)
v119:Animate()
v119.OnActivated:Connect(function()
-- upvalues: (ref) v_u_41, (copy) v_u_105, (ref) v_u_43
v_u_41:FireServer(v_u_105, v_u_43)
end)
end
end)
v_u_8.observeTag("GamepassProduct", function(p_u_120)
-- upvalues: (ref) v_u_27, (ref) v_u_21, (ref) v_u_17, (ref) v_u_44, (ref) v_u_42, (copy) p_u_86, (ref) v_u_15, (ref) v_u_43, (ref) v_u_41
local v121 = p_u_120.Name
local v_u_122 = tonumber(v121)
local v_u_123 = v_u_27[v_u_122]
if v_u_123 then
local v124 = p_u_120:WaitForChild("Buy", 5)
local v_u_125
if v124 then
v_u_125 = v124:WaitForChild("Price", 5)
else
v_u_125 = v124
end
p_u_120:WaitForChild("Icon", 5)
local v_u_126 = false
local v_u_127 = false
local function v_u_132()
-- upvalues: (ref) v_u_127, (ref) v_u_21, (copy) p_u_120, (copy) v_u_122, (copy) v_u_125, (ref) v_u_126, (ref) v_u_17
local v128 = v_u_127 == true and v_u_21:GetProductInfo(p_u_120:GetAttribute("ProductId"), "Product") or v_u_21:GetProductInfo(v_u_122, "Gamepass")
if v_u_125 and (v_u_126 == false or v_u_127) then
local v129 = v_u_125
local v130
if v128.PriceInRobux == nil then
v130 = "Failed to load!"
else
local v131 = v128.PriceInRobux
v130 = ("%*%*"):format("\238\128\130", v131 == 999999999 and "???" or v_u_17:Comma(v131)) or "Failed to load!"
end
v129.Text = v130
end
end
v_u_44:Connect(function(p133)
-- upvalues: (ref) v_u_127, (ref) v_u_126, (copy) v_u_125, (copy) v_u_132
v_u_127 = p133
if p133 or not v_u_126 then
v_u_132()
else
v_u_126 = true
v_u_125.Text = "Owned"
end
end)
v_u_42.Tick:Connect(function()
-- upvalues: (ref) v_u_126, (copy) v_u_132
if v_u_126 == false then
v_u_132()
end
end)
p_u_86:OnDictionaryInserted("Gamepass", function(_, p134)
-- upvalues: (copy) v_u_123, (ref) v_u_126, (copy) v_u_125
if p134 == v_u_123.Display then
v_u_126 = true
v_u_125.Text = "Owned"
end
end)
if p_u_86:Get((("Gamepass.%*"):format(v_u_123.Display))) == true then
v_u_126 = true
v_u_125.Text = "Owned"
end
v_u_132()
local v135 = v_u_15.new(v124)
v135:Animate()
v135.OnActivated:Connect(function()
-- upvalues: (ref) v_u_43, (copy) p_u_120, (ref) v_u_41, (copy) v_u_122
if v_u_43 then
v_u_41:FireServer(p_u_120:GetAttribute("ProductId"), v_u_43)
else
v_u_41:FireServer(v_u_122, v_u_43)
end
end)
end
end)
v_u_8.observeTag("StarterPack", function(p_u_136)
-- upvalues: (ref) v_u_27, (copy) p_u_86, (ref) v_u_21, (ref) v_u_17, (ref) v_u_44, (ref) v_u_42, (ref) v_u_15, (ref) v_u_41, (ref) v_u_43
local v_u_137 = v_u_27[3290334159]
if v_u_137 then
local v138 = p_u_136:WaitForChild("Buy", 5)
local v_u_139
if v138 then
v_u_139 = v138:WaitForChild("Price", 5)
else
v_u_139 = v138
end
local v_u_140 = false
local v_u_141 = false
local function v_u_143()
-- upvalues: (copy) v_u_137, (ref) p_u_86, (ref) v_u_141, (copy) p_u_136
for _, v142 in v_u_137.Rewards.Items do
if p_u_86:Get("Items." .. v142) == true and v_u_141 == false then
p_u_136.Visible = false
return
end
end
p_u_136.Visible = true
end
v_u_44:Connect(function(p144)
-- upvalues: (ref) v_u_141, (ref) v_u_140, (copy) v_u_139, (ref) v_u_21, (ref) v_u_17, (copy) v_u_143
v_u_141 = p144
if p144 or not v_u_140 then
local v145 = v_u_21:GetProductInfo(3290334159, "Product")
if v_u_139 and (v_u_140 == false or v_u_141 == true) then
local v146 = v_u_139
local v147
if v145.PriceInRobux == nil then
v147 = "Failed to load!"
else
local v148 = v145.PriceInRobux
v147 = ("%*%*"):format("\238\128\130", v148 == 999999999 and "???" or v_u_17:Comma(v148)) or "Failed to load!"
end
v146.Text = v147
end
else
v_u_140 = true
v_u_139.Text = "Owned"
end
v_u_143()
end)
v_u_42.Tick:Connect(function()
-- upvalues: (ref) v_u_140, (ref) v_u_21, (copy) v_u_139, (ref) v_u_141, (ref) v_u_17
if v_u_140 == false then
local v149 = v_u_21:GetProductInfo(3290334159, "Product")
if v_u_139 and (v_u_140 == false or v_u_141 == true) then
local v150 = v_u_139
local v151
if v149.PriceInRobux == nil then
v151 = "Failed to load!"
else
local v152 = v149.PriceInRobux
v151 = ("%*%*"):format("\238\128\130", v152 == 999999999 and "???" or v_u_17:Comma(v152)) or "Failed to load!"
end
v150.Text = v151
end
end
end)
v_u_143()
p_u_86:OnDictionaryInserted("Items", v_u_143)
local v153 = v_u_21:GetProductInfo(3290334159, "Product")
if v_u_139 and (v_u_140 == false or v_u_141 == true) then
local v154
if v153.PriceInRobux == nil then
v154 = "Failed to load!"
else
local v155 = v153.PriceInRobux
v154 = ("%*%*"):format("\238\128\130", v155 == 999999999 and "???" or v_u_17:Comma(v155)) or "Failed to load!"
end
v_u_139.Text = v154
end
local v156 = v_u_15.new(v138)
v156:Animate()
v156.OnActivated:Connect(function()
-- upvalues: (ref) v_u_41, (ref) v_u_43
v_u_41:FireServer(3290334159, v_u_43)
end)
end
end)
v_u_8.observeTag("RainbowText", function(p157)
-- upvalues: (ref) v_u_6
return v_u_6.apply(p157, "Rainbow")
end)
v_u_8.observeTag("ZebraText", function(p158)
-- upvalues: (ref) v_u_6
return v_u_6.apply(p158, "Zebra")
end)
v_u_42:Start();
(function(p159)
-- upvalues: (ref) v_u_21
for _, v160 in p159 do
task.defer(v_u_21.GetProductInfo, v_u_21, v160, "Product")
end
end)({ v_u_24[2].ProductId })
end)
local v161 = v_u_15.new(v_u_36)
v161:Animate()
v161.OnActivated:Connect(function()
-- upvalues: (ref) v_u_43, (ref) v_u_38, (ref) v_u_37, (ref) v_u_44, (ref) v_u_31
if v_u_43 then
v_u_43 = nil
v_u_38.Visible = false
v_u_37.Text = "Gift Player"
v_u_44:Fire(false)
else
v_u_31.Visible = not v_u_31.Visible
end
end)
local v162 = v_u_15.new(v_u_32)
v162:Animate()
v162.OnActivated:Connect(function()
-- upvalues: (ref) v_u_31, (ref) v_u_44
v_u_31.Visible = false
v_u_44:Fire(false)
end)
local v_u_163 = v_u_30.Content.List.ServerLuck
v_u_7:WaitAndCall("ServerLuck", function(p_u_164)
-- upvalues: (copy) v_u_163, (ref) v_u_18, (ref) v_u_24, (ref) v_u_21, (ref) v_u_17, (ref) v_u_11, (ref) v_u_15, (ref) v_u_41
local v_u_165 = nil
local v_u_166 = os.clock()
local function v179()
-- upvalues: (ref) v_u_166, (ref) v_u_165, (copy) p_u_164, (ref) v_u_163, (ref) v_u_18, (ref) v_u_24, (ref) v_u_21, (ref) v_u_17
if os.clock() - v_u_166 >= 300 then
v_u_166 = os.clock()
v_u_165 = nil
end
local v167 = p_u_164:Get("EndTime")
if v167 then
local v168 = v167 - workspace:GetServerTimeNow()
local v169 = math.floor(v168)
local v170 = math.clamp(v169, 0, (1 / 0))
if v170 <= 0 then
v167 = nil
v_u_165 = nil
else
v_u_163.Frame.Timer.Text = v_u_18:A(v170)
end
end
v_u_163.Frame.Timer.Visible = v167 ~= nil
local v171 = p_u_164:Get("Index") or 0
local v172 = #v_u_24
local v173 = v171 + 1
local v174 = math.min(v173, v172)
if v171 ~= v_u_165 then
v_u_165 = v171
local v175 = v172 <= v171 and "MAX" or ("%dx > %dx"):format(v171 == 0 and 1 or v_u_24[v171].Multiplier, v_u_24[v174].Multiplier)
local v176 = v_u_21:GetProductInfo(v_u_24[v174].ProductId, "Product")
local v177 = v_u_163.Frame.Buy.Price
local v178 = v176.PriceInRobux
v177.Text = ("%*%*"):format("\238\128\130", v178 == 999999999 and "???" or v_u_17:Comma(v178))
v_u_163.Frame.LuckVector.Image = v176.Icon
v_u_163.Frame.Pattern.Image = v176.Icon
v_u_163.Frame.Amount.Text = v175
end
end
p_u_164:OnChanged("Index", v179)
p_u_164:OnChanged("EndTime", v179)
v_u_11.Simple(1, v179)
local v180 = v_u_15.new(v_u_163.Frame.Buy)
v180:Animate()
v180.OnActivated:Connect(function()
-- upvalues: (copy) p_u_164, (ref) v_u_24, (ref) v_u_41
local v181 = p_u_164:Get("Index") or 0
local v182 = #v_u_24
local v183 = v181 + 1
v_u_41:FireServer(v_u_24[math.min(v183, v182)].ProductId)
end)
end)
v_u_78()
for _, v184 in v_u_2:GetPlayers() do
v_u_85(v184)
end
v_u_2.PlayerAdded:Connect(function(p185)
-- upvalues: (ref) v_u_85
v_u_85(p185)
end)
v_u_2.PlayerRemoving:Connect(function(p186)
-- upvalues: (ref) v_u_33
local v187 = v_u_33:FindFirstChild(p186.Name)
if v187 then
v187:Destroy()
end
end)
for _, v188 in v_u_30.Header.Main:GetChildren() do
if v188:IsA("ImageButton") then
local v_u_189 = v_u_30.Content.List:FindFirstChild(v188.Name)
if v_u_189 then
local v190 = v_u_15.new(v188)
v190:Animate()
v190.OnActivated:Connect(function()
-- upvalues: (ref) v_u_30, (copy) v_u_189
local v191 = v_u_30.Content.List
local v192 = v_u_189.AbsolutePosition.Y - v191.AbsolutePosition.Y + v191.CanvasPosition.Y
v191.CanvasPosition = Vector2.new(v191.CanvasPosition.X, v192)
end)
end
end
end
end
return v46 - Edit
03:12:20.381
- Edit
03:12:20.381
============================== - Edit
03:12:20.381 📜 ReplicatedStorage.Controllers.YinYangEventController - Edit
03:12:20.382 ==============================
- Edit
03:12:20.382 ---------------------------------------------------
-- Saved by Angelus Decompiles | With Script + GUI
-- Discord: https://discord.gg/nDWm6PkFrT
---------------------------------------------------
--Decompiled by Medal, I take no credit I only Made The dumper and I I.. I iron man
local v_u_1 = game:GetService("ReplicatedStorage")
local v_u_2 = game:GetService("RunService")
local v3 = game:GetService("Players")
local v_u_4 = game:GetService("TweenService")
local v5 = v_u_1:WaitForChild("Controllers")
local v_u_6 = require(v5.InterfaceController)
require(v5.ShopController)
local v_u_7 = require(v5.NotificationController)
require(v5.SoundController)
local v8 = v_u_1:WaitForChild("Packages")
local v_u_9 = require(v8.Observers)
local v_u_10 = require(v8.Synchronizer)
local v_u_11 = require(v8.Timer)
require(v8.Trove)
local v12 = require(v8.Net)
local v13 = v_u_1:WaitForChild("Utils")
local v_u_14 = require(v13.TimeUtils)
local v_u_15 = require(v13.NumberUtils)
local v16 = v_u_1:WaitForChild("Datas")
local v_u_17 = require(v16.YinYangSpinWheel)
local v_u_18 = require(v16.Shop)
local v19 = v_u_1:WaitForChild("Classes")
local v_u_20 = require(script.YinYangSpinWheel)
local v_u_21 = require(v19.AnimatedButton)
local v22 = v_u_1:WaitForChild("Shared")
local v_u_23 = require(v22.Marketplace)
local v_u_24 = v3.LocalPlayer
local v_u_25 = v_u_24.PlayerGui:WaitForChild("YinYangWheel").YinYangWheel
local v_u_26 = nil
local v_u_27 = false
local v_u_28 = v12:RemoteEvent("ShopService/Purchase")
local v_u_29 = v12:RemoteEvent("YinYangEventService/Spin")
v12:RemoteFunction("YinYangEventService/RequestBuy")
local v_u_30 = false
local v31 = {}
local function v_u_50(p32, p33)
-- upvalues: (copy) v_u_10, (copy) v_u_24, (ref) v_u_30, (copy) v_u_25, (ref) v_u_27, (copy) v_u_2, (copy) v_u_4, (copy) v_u_17, (copy) v_u_18, (copy) v_u_15, (copy) v_u_7
local v34 = v_u_10:Wait(v_u_24)
if not v_u_30 then
v_u_30 = true
local v_u_35 = v_u_25.Wheel
local v36 = v_u_35:FindFirstChild("Spinning")
local v37 = v_u_27 and 1 or 0.8
if v36 then
v36.Looped = true
v36.Volume = v37
v36:Play()
end
local v38 = (p32 - 1) * -60 - (math.random() - 0.5) * 0.7 * 60
local v39 = v38 + (v_u_27 and 1 or 9) * 360
local v40 = v_u_27 and 0.5 or 5
local v_u_41 = nil
local v43 = v_u_2.PostSimulation:Connect(function()
-- upvalues: (copy) v_u_35, (ref) v_u_41, (ref) v_u_25, (ref) v_u_4
debug.profilebegin("YinYangEventController:ResultAnimation")
local v42 = (v_u_35.Rotation + 30) / 60 // 1
if v_u_41 ~= v42 then
v_u_41 = v42
v_u_25.Tick.Rotation = -40
v_u_4:Create(v_u_25.Tick, TweenInfo.new(0.3, Enum.EasingStyle.Sine, Enum.EasingDirection.Out), {
["Rotation"] = 0
}):Play()
end
debug.profileend()
end)
local v44 = v_u_4:Create(v_u_35, TweenInfo.new(v40, Enum.EasingStyle.Quint, Enum.EasingDirection.Out), {
["Rotation"] = v39
})
if v36 then
v_u_4:Create(v36, TweenInfo.new(v40, Enum.EasingStyle.Linear, Enum.EasingDirection.Out), {
["Volume"] = 0
}):Play()
end
v44:Play()
v44.Completed:Wait()
v43:Disconnect()
v_u_35.Rotation = v38
if v36 then
v36:Stop()
v36.Volume = v37
end
local v45 = p33 == true and v_u_17.AltRewards[p32] or v_u_17.Rewards[p32]
local v46
if v45.Type == "Cash-Pack" then
local v47 = v_u_18[v45.Index]
if not v_u_18 then
return false
end
local v48 = v47.Value or 0
local v49 = v34:Get("Rebirth") or 0
if v49 > 0 then
v48 = v48 * (v49 <= 1 and 1.5 or v49)
end
v46 = ("$%*"):format((v_u_15:ToString(v48, 2)))
else
v46 = v45.Display
end
v_u_7:Success((("You received %*!"):format(v46)))
v_u_30 = false
end
end
function v31.SetupYinYangWheel(_)
-- upvalues: (ref) v_u_26, (copy) v_u_6, (copy) v_u_25, (copy) v_u_10, (copy) v_u_24, (copy) v_u_17, (copy) v_u_18, (copy) v_u_15, (copy) v_u_23, (ref) v_u_30, (copy) v_u_21, (ref) v_u_27, (copy) v_u_28, (copy) v_u_29, (copy) v_u_1, (copy) v_u_14, (copy) v_u_50, (copy) v_u_11, (copy) v_u_9, (copy) v_u_20
v_u_26 = v_u_6:Register("YinYangWheel", v_u_25, "TopQuint")
v_u_26:AttachCloseButton(v_u_25.Close)
v_u_26:Close()
local v_u_51 = v_u_10:Wait(v_u_24)
local function v_u_74()
-- upvalues: (ref) v_u_25, (ref) v_u_17, (copy) v_u_51, (ref) v_u_18, (ref) v_u_15, (ref) v_u_23
local v52 = v_u_25.Wheel
local v53 = v52.Items
local v54 = v52.Names
local v55 = v52.Odds
local v56 = {}
for v57 = 1, #v_u_17.Rewards do
local v58 = v_u_17.Rewards[v57]
if v58 then
if v58.Type == "Item" and v_u_51:Get((("Items.%*"):format(v58.Index))) then
v58 = v_u_17.AltRewards[v57]
end
v56[v57] = v58.Weight
end
end
local v59 = 0
for _, v60 in v56 do
v59 = v59 + v60
end
v56[5] = v56[5] + (100 - v59)
for v61 = 1, #v_u_17.Rewards do
local v62 = v_u_17.Rewards[v61]
if v62 then
if v62.Type == "Item" and v_u_51:Get((("Items.%*"):format(v62.Index))) then
v62 = v_u_17.AltRewards[v61]
end
local v63 = v53:FindFirstChild(v61)
local v64 = v54:FindFirstChild(v61)
local v65 = v55:FindFirstChild(v61)
local v66 = ""
local v67
if v62.Type == "Cash-Pack" then
local v68 = v_u_18[v62.Index].Value
local v69 = v_u_51:Get("Rebirth") or 0
if v69 > 0 then
v68 = v68 * (v69 <= 1 and 1.5 or v69)
end
v66 = ("$%*"):format((v_u_15:ToString(v68, 2)))
v67 = v_u_23:GetProductInfo(v62.Index, "Product").Icon
else
v67 = v62.Icon
end
local v70 = v62.Display
local v71 = v66 == "" and v70 and v70 or v66
local v72 = v56[v61] * 100
local v73 = ("%*%%"):format(math.floor(v72) / 100)
v63.Image = v67
v64.Text = v71
v65.Text = v73
end
end
end
v_u_74()
v_u_51:OnDictionaryInserted("Items", function(_, p75)
-- upvalues: (ref) v_u_17, (ref) v_u_30, (copy) v_u_74
local v76 = false
for v77 = 1, #v_u_17.Rewards do
local v78 = v_u_17.Rewards[v77]
if v78.Type == "Item" and p75 == v78.Index then
v76 = true
break
end
end
if v76 then
while v_u_30 do
task.wait()
end
v_u_74()
end
end)
local v_u_79 = v_u_25.FastSpin.Toggle
local v80 = v_u_21.new(v_u_79)
v80:Animate()
v80.OnActivated:Connect(function()
-- upvalues: (ref) v_u_27, (copy) v_u_79
v_u_27 = not v_u_27
v_u_79.Checkmark.Visible = v_u_27
end)
v_u_79.Checkmark.Visible = v_u_27
for _, v_u_81 in v_u_25.Buttons:GetChildren() do
if v_u_81:IsA("ImageButton") and v_u_81.Name ~= "Spin" then
local v82 = v_u_21.new(v_u_81)
v82:Animate()
v82.OnActivated:Connect(function()
-- upvalues: (ref) v_u_28, (copy) v_u_81
v_u_28:FireServer(v_u_81:GetAttribute("ProductId"))
end)
local v83 = v_u_23:GetProductInfo(v_u_81:GetAttribute("ProductId"), "Product")
v_u_81.RbxAmount.Text = v83.PriceInRobux
end
end
local v_u_84 = v_u_25.Buttons.Spin
local v85 = v_u_21.new(v_u_84)
v85:Animate()
v85.OnActivated:Connect(function()
-- upvalues: (ref) v_u_30, (ref) v_u_29
if v_u_30 ~= true then
v_u_29:FireServer()
end
end)
local function v_u_104()
-- upvalues: (ref) v_u_1, (copy) v_u_51, (copy) v_u_84, (ref) v_u_14, (ref) v_u_25
local v86 = 0
if v_u_1:GetAttribute("YinYangEvent") then
if v_u_51:Get("YinYangSpinWheel.LastFreeClaimed") == v_u_1:GetAttribute("YinYangEventLastTime") then
local v87 = v_u_84.Main.Timer
local v88 = "Free Spin in %*"
local v89 = v_u_14
local v90 = workspace:GetServerTimeNow()
local v91
if v90 < 1755961200 then
v91 = 1755961200 - v90
else
local v92 = os.date("!*t", workspace:GetServerTimeNow()).wday
local v93 = (v92 == 1 or v92 == 7) and 3600 or 10800
v91 = v93 - v90 % v93
end
v87.Text = v88:format((v89:D(v91)))
else
v86 = v86 + 1
v_u_84.Main.Timer.Text = "SPIN NOW"
end
else
local v94 = v_u_84.Main.Timer
local v95 = "Free Spin in %*"
local v96 = v_u_14
local v97 = workspace:GetServerTimeNow()
local v98
if v97 < 1755961200 then
v98 = 1755961200 - v97
else
local v99 = os.date("!*t", workspace:GetServerTimeNow()).wday
local v100 = (v99 == 1 or v99 == 7) and 3600 or 10800
v98 = v100 - v97 % v100
end
v94.Text = v95:format((v96:D(v98)))
end
local v101 = v86 + v_u_51:Get("YinYangSpinWheel.Spins")
v_u_84.Main.Spins.Text = v101 > 1 and ("Spins (%*)"):format(v101) or ("Spin (%*)"):format(v101)
v_u_84.Main.UIGradient.Enabled = v101 <= 0
local v102 = workspace:GetServerTimeNow() - v_u_51:Get("YinYangSpinWheel.LastDailyDiscount") >= 86400
v_u_25.Buttons.Buy1.Visible = not v102
v_u_25.Buttons.Buy1Discount.Visible = v102
local v103 = v_u_51:Get("YinYangSpinWheel.PaidSpins.x3") >= 5
v_u_25.Buttons.Buy10.Visible = v103
v_u_25.Buttons.Buy3.Visible = not v103
end
v_u_29.OnClientEvent:Connect(function(p105, p106)
-- upvalues: (copy) v_u_104, (ref) v_u_50
task.spawn(v_u_104)
v_u_50(p105, p106)
end)
v_u_11.Simple(1, v_u_104)
v_u_9.observeTag("YinYangSpinWheel", function(p107)
-- upvalues: (ref) v_u_20
local v_u_108 = v_u_20.new(p107)
return function()
-- upvalues: (copy) v_u_108
v_u_108:Destroy()
end
end)
end
function v31.Start(p109)
p109:SetupYinYangWheel()
end
return v31
- Edit
03:12:20.382
- Edit
03:12:20.382
============================== - Edit
03:12:20.382 📜 ReplicatedStorage.Controllers.YinYangEventController.YinYangSpinWheel - Edit
03:12:20.382 ==============================
- Edit
03:12:20.382 ---------------------------------------------------
-- Saved by Angelus Decompiles | With Script + GUI
-- Discord: https://discord.gg/nDWm6PkFrT
---------------------------------------------------
--Decompiled by Medal, I take no credit I only Made The dumper and I I.. I iron man
local v_u_1 = game:GetService("ReplicatedStorage")
local v_u_2 = game:GetService("RunService")
local v3 = game:GetService("Players")
local v4 = v_u_1:WaitForChild("Datas")
local v_u_5 = require(v4.YinYangSpinWheel)
local v_u_6 = require(v4.Shop)
local v7 = v_u_1:WaitForChild("Utils")
local v_u_8 = require(v7.TimeUtils)
local v_u_9 = require(v7.NumberUtils)
local v10 = v_u_1:WaitForChild("Controllers")
require(v10.ShopController)
local v_u_11 = require(v10.InterfaceController)
local v12 = v_u_1:WaitForChild("Shared")
local v_u_13 = require(v12.Marketplace)
local v14 = v_u_1:WaitForChild("Packages")
local v_u_15 = require(v14.Trove)
local v_u_16 = require(v14.Timer)
local v_u_17 = require(v14.Synchronizer)
local v_u_18 = v3.LocalPlayer
local v_u_19 = {}
v_u_19.__index = v_u_19
function v_u_19.new(p_u_20)
-- upvalues: (copy) v_u_17, (copy) v_u_18, (copy) v_u_19, (copy) v_u_15, (copy) v_u_5, (copy) v_u_6, (copy) v_u_9, (copy) v_u_13, (copy) v_u_2, (copy) v_u_11, (copy) v_u_16, (copy) v_u_1, (copy) v_u_8
local v_u_21 = v_u_17:Wait(v_u_18)
local v22 = v_u_19
local v_u_23 = setmetatable({}, v22)
v_u_23.Instance = p_u_20
v_u_23.Collector = v_u_15.new()
local function v_u_40()
-- upvalues: (copy) p_u_20, (ref) v_u_5, (copy) v_u_21, (ref) v_u_6, (ref) v_u_9, (ref) v_u_13
local v24 = p_u_20:WaitForChild("Main"):WaitForChild("SurfaceGui").Wheel
local v25 = v24.Items
local v26 = v24.Names
local v27 = v24.Odds
for v28 = 1, #v_u_5.Rewards do
local v29 = v_u_5.Rewards[v28]
if v29 then
if v29.Type == "Item" and v_u_21:Get((("Items.%*"):format(v29.Index))) then
v29 = v_u_5.AltRewards[v28]
end
local v30 = v25:FindFirstChild(v28)
local v31 = v26:FindFirstChild(v28)
local v32 = v27:FindFirstChild(v28)
local v33 = ""
local v34
if v29.Type == "Cash-Pack" then
local v35 = v_u_6[v29.Index].Value
local v36 = v_u_21:Get("Rebirth") or 0
if v36 > 0 then
v35 = v35 * (v36 <= 1 and 1.5 or v36)
end
v33 = ("$%*"):format((v_u_9:ToString(v35, 2)))
v34 = v_u_13:GetProductInfo(v29.Index, "Product").Icon
else
v34 = v29.Icon
end
local v37 = v29.Display
local v38 = v33 == "" and v37 and v37 or v33
local v39 = ("%*%%"):format(v29.Weight)
v30.Image = v34 or ""
v31.Text = v38
v32.Text = v39
end
end
end
v_u_40()
v_u_23.Collector:Add(v_u_21:OnDictionaryInserted("Items", function(_, p41)
-- upvalues: (ref) v_u_5, (copy) v_u_40
local v42 = false
for v43 = 1, #v_u_5.Rewards do
local v44 = v_u_5.Rewards[v43]
if v44.Type == "Item" and p41 == v44.Index then
v42 = true
break
end
end
if v42 then
v_u_40()
end
end))
v_u_23.Collector:Add(v_u_2.RenderStepped:Connect(function(p45)
-- upvalues: (copy) v_u_23
debug.profilebegin("YinYangSpinWheel:Rotate3D")
local v46 = v_u_23.Instance.Main
local v47 = v46.CFrame
local v48 = CFrame.Angles
local v49 = p45 * 45
v46.CFrame = v47 * v48(0, 0, (math.rad(v49)))
debug.profileend()
end))
v_u_23.Collector:Add(v_u_23.Instance.Root.ProximityPrompt.Triggered:Connect(function()
-- upvalues: (ref) v_u_11
v_u_11:Toggle("YinYangWheel", true)
end))
local v50 = v_u_16.new(1)
v_u_23.Collector:Add(v50, "Destroy")
v_u_23.Collector:Add(v50.Tick:Connect(function()
-- upvalues: (ref) v_u_1, (copy) v_u_21, (copy) v_u_23, (ref) v_u_8
if v_u_1:GetAttribute("YinYangEvent") then
if v_u_21:Get("YinYangSpinWheel.LastFreeClaimed") == v_u_1:GetAttribute("YinYangEventLastTime") then
local v51 = v_u_23.Instance.Overhead.BillboardGui.Countdown
local v52 = v_u_8
local v53 = workspace:GetServerTimeNow()
local v54 = os.date("!*t", workspace:GetServerTimeNow()).wday
local v55 = (v54 == 1 or v54 == 7) and 3600 or 10800
v51.Text = ("Free Spin in %*"):format((v52:D(v55 - v53 % v55)))
else
v_u_23.Instance.Overhead.BillboardGui.Countdown.Text = "SPIN NOW"
end
else
local v56 = v_u_23.Instance.Overhead.BillboardGui.Countdown
local v57 = v_u_8
local v58 = workspace:GetServerTimeNow()
local v59 = os.date("!*t", workspace:GetServerTimeNow()).wday
local v60 = (v59 == 1 or v59 == 7) and 3600 or 10800
v56.Text = ("Free Spin in %*"):format((v57:D(v60 - v58 % v60)))
return
end
end))
v50:StartNow()
return v_u_23
end
function v_u_19.Destroy(p61)
p61.Collector:Destroy()
end
return v_u_19
- Edit
03:12:20.382
- Edit
03:12:20.382
============================== - Edit
03:12:20.382 📜 ReplicatedStorage.Components.Npc - Edit
03:12:20.382 ==============================
- Edit
03:12:20.382 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: Npc, time of decompilation: Sat Jun 28 18:34:38 2025 ]]
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local l_Players_0 = game:GetService("Players");
local l_TweenService_0 = game:GetService("TweenService");
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v4 = require(l_Packages_0.Component);
local v5 = require(l_Packages_0.Trove);
local l_Controllers_0 = l_ReplicatedStorage_0:WaitForChild("Controllers");
local v7 = require(l_Controllers_0.DialogController);
local l_Utils_0 = l_ReplicatedStorage_0:WaitForChild("Utils");
local v9 = require(l_Utils_0.StringUtils);
local v10 = TweenInfo.new(0.5, Enum.EasingStyle.Linear);
local _ = l_Players_0.LocalPlayer;
local v12 = v4.new({
Tag = "Npc"
});
v12.Construct = function(v13) --[[ Line: 44 ]] --[[ Name: Construct ]]
-- upvalues: v5 (copy), l_TweenService_0 (copy), v10 (copy), v7 (copy), v9 (copy), l_ReplicatedStorage_0 (copy)
v13.Collector = v5.new();
v13.Hightlight = Instance.new("Highlight");
v13.Hightlight.FillTransparency = 1;
v13.Hightlight.OutlineColor = Color3.fromRGB(255, 255, 255);
v13.Hightlight.OutlineTransparency = 1;
v13.Hightlight.DepthMode = Enum.HighlightDepthMode.Occluded;
v13.Hightlight.Parent = v13.Instance;
v13.ProximityPrompt = Instance.new("ProximityPrompt", v13.Instance);
v13.ProximityPrompt.ActionText = "Talk";
v13.ProximityPrompt.ObjectText = v13.Instance:GetAttribute("PromptObjectText") or "";
v13.ShownTween = l_TweenService_0:Create(v13.Hightlight, v10, {
OutlineTransparency = 0
});
v13.HiddenTween = l_TweenService_0:Create(v13.Hightlight, v10, {
OutlineTransparency = 1
});
v13.DialogText = v7:GetDialogText();
v13.DialogText.Parent = v13.Instance.PrimaryPart;
if v13.Instance:GetAttribute("IdlePath") then
local v14 = v9:ReadPath(l_ReplicatedStorage_0, v13.Instance:GetAttribute("IdlePath"));
local v15 = v13.Instance:WaitForChild("Humanoid"):WaitForChild("Animator"):LoadAnimation(v14);
v15.Looped = true;
v15:Play();
end;
end;
v12.Start = function(v16) --[[ Line: 74 ]] --[[ Name: Start ]]
-- upvalues: v7 (copy)
v16.Collector:Add(v16.ProximityPrompt.Triggered:Connect(function() --[[ Line: 76 ]]
-- upvalues: v7 (ref), v16 (copy)
v7:StartDialog(v16.Instance:GetAttribute("Dialog"), v16.Instance:GetAttribute("Index"), v16.DialogText);
end));
v16.Collector:Add(v16.ProximityPrompt.PromptShown:Connect(function() --[[ Line: 80 ]]
-- upvalues: v16 (copy)
v16.ShownTween:Play();
end));
v16.Collector:Add(v16.ProximityPrompt.PromptHidden:Connect(function() --[[ Line: 84 ]]
-- upvalues: v16 (copy)
v16.HiddenTween:Play();
end));
end;
v12.Stop = function(v17) --[[ Line: 90 ]] --[[ Name: Stop ]]
v17.Collector:Destroy();
end;
return v12; - Edit
03:12:20.382
- Edit
03:12:20.382
============================== - Edit
03:12:20.382 📜 ReplicatedStorage.Items.Tung Bat.Controller - Edit
03:12:20.382 ==============================
- Edit
03:12:20.382 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local Tool = script.Parent
local Cooldowns = {}
local AttackAnimation = Instance.new("Animation")
AttackAnimation.AnimationId = "rbxassetid://76004596847337"
local AttackAnimationTrack
local IdleAnimation = Instance.new("Animation")
IdleAnimation.AnimationId = "rbxassetid://100085329463227"
local IdleAnimationTrack
local Humanoid
local function CreateHitbox(Character)
local Root = Character:FindFirstChild("HumanoidRootPart")
if not Root then return end
local Size = Vector3.new(12, 12, 12)
local CFramePos = Root.CFrame * CFrame.new(0, 0, -3)
return Region3.new(CFramePos.Position - Size/2, CFramePos.Position + Size/2)
end
local function GetTargets(Character)
local Region = CreateHitbox(Character)
if not Region then return {} end
local Parts = workspace:FindPartsInRegion3(Region, Character, 10)
local Targets = {}
for _, Part in ipairs(Parts) do
local Char = Part.Parent
local H = Char:FindFirstChild("Humanoid")
if H and H.Health > 0 and Char ~= Character and not Targets[Char] then
Targets[Char] = H
end
end
return Targets
end
local function ApplySlap(Player, Target, Direction)
local H = Target:FindFirstChild("Humanoid")
local Root = Target:FindFirstChild("HumanoidRootPart")
if not H or not Root or H.Health <= 0 then return false end
H:TakeDamage(0)
local TargetPlayer = Players:GetPlayerFromCharacter(Target)
if TargetPlayer then
TargetPlayer:SetAttribute("Stealing", false)
end
CombatController:FireClient(TargetPlayer, 450, Direction)
RagdollModule.TimedRagdoll(Target, 1.5)
return true
end
Tool.Equipped:Connect(function()
local Char = Tool.Parent
Humanoid = Char:FindFirstChild("Humanoid")
if Humanoid then
IdleAnimationTrack = Humanoid:LoadAnimation(IdleAnimation)
end
end)
Tool.Unequipped:Connect(function()
if IdleAnimationTrack then
IdleAnimationTrack:Stop()
IdleAnimationTrack = nil
end
if AttackAnimationTrack then
AttackAnimationTrack:Stop()
AttackAnimationTrack = nil
end
Humanoid = nil
end)
Tool.Activated:Connect(function()
local Char = Tool.Parent
local Player = Players:GetPlayerFromCharacter(Char)
if not Player or not Char:FindFirstChild("HumanoidRootPart") then return end
local Last = Cooldowns[Player.UserId] or 0
if os.clock() - Last < 0.5 then return end
Cooldowns[Player.UserId] = os.clock()
if IdleAnimationTrack then
IdleAnimationTrack:Stop()
end
if Humanoid then
AttackAnimationTrack = Humanoid:LoadAnimation(AttackAnimation)
AttackAnimationTrack:Play()
AttackAnimationTrack.Stopped:Connect(function()
if Humanoid and IdleAnimationTrack then
IdleAnimationTrack:Play()
end
end)
end
local Dir = Char.HumanoidRootPart.CFrame.LookVector
local HitSomething = false
for Target in pairs(GetTargets(Char)) do
if ApplySlap(Player, Target, Dir) then
HitSomething = true
end
end
if HitSomething then
if Tool:FindFirstChild("Hit") then
Tool.Hit:Play()
end
else
if Tool:FindFirstChild("Slash") then
Tool.Slash:Play()
end
end
end)
Tool.Equipped:Connect(function()
local Player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if Player and Player:GetAttribute("Stealing") then
Tool.Parent = Player.Backpack
end
end)
- Edit
03:12:20.383
- Edit
03:12:20.383
============================== - Edit
03:12:20.383 📜 ReplicatedStorage.Items.Speed Coil.SpeedController - Edit
03:12:20.383 ==============================
- Edit
03:12:20.383 local tool = script.Parent
local Players = game:GetService("Players")
script.Parent.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
script.Parent:SetAttribute("SpeedModifier",1.5)
end)
script.Parent.Unequipped:Connect(function()
script.Parent:SetAttribute("SpeedModifier",0)
end) - Edit
03:12:20.383
- Edit
03:12:20.383
============================== - Edit
03:12:20.383 📜 ReplicatedStorage.Items.Coil Combo.ComboController - Edit
03:12:20.383 ==============================
- Edit
03:12:20.383 local PlayerSpeed = 32
local Players = game:GetService("Players")
local tool = script.Parent
script.Parent.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
script.Parent:SetAttribute("JumpModifier",1.9)
script.Parent:SetAttribute("SpeedModifier",1.9)
end)
script.Parent.Unequipped:Connect(function()
script.Parent:SetAttribute("JumpModifier",0)
script.Parent:SetAttribute("SpeedModifier",0)
end)
- Edit
03:12:20.383
- Edit
03:12:20.383
============================== - Edit
03:12:20.383 📜 ReplicatedStorage.Items.Coil Combo.ComboScript - Edit
03:12:20.383 ==============================
- Edit
03:12:20.383 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: ComboScript, time of decompilation: Tue Jun 24 14:16:10 2025 ]]
local l_Parent_0 = script.Parent;
l_Parent_0.Equipped:Connect(function() --[[ Line: 4 ]]
workspace.Gravity = 29.429999999999996;
end);
l_Parent_0.Unequipped:Connect(function() --[[ Line: 11 ]]
workspace.Gravity = 196.2;
end); - Edit
03:12:20.383
- Edit
03:12:20.383
============================== - Edit
03:12:20.383 📜 ReplicatedStorage.Items.Invisibility Cloak.InvisibilityController - Edit
03:12:20.383 ==============================
- Edit
03:12:20.383 local Tool = script.Parent
local TweenService = game:GetService("TweenService")
local IsInvisible = false
local FadeTime = 0.5
local CurrentCharacter = nil
local WooshStart = Tool:WaitForChild("Handle"):WaitForChild("WooshStart")
local WooshEnd = Tool:WaitForChild("Handle"):WaitForChild("WooshEnd")
local function FadeParts(Parent, Enabled)
for _, Part in ipairs(Parent:GetDescendants()) do
if Part:IsA("BasePart") and Part.Name ~= "HumanoidRootPart" then
local GoalTransparency = Enabled and 1 or 0
TweenService:Create(Part, TweenInfo.new(FadeTime), { Transparency = GoalTransparency }):Play()
local Face = Part:FindFirstChild("face")
if Face then
TweenService:Create(Face, TweenInfo.new(FadeTime), { Transparency = GoalTransparency }):Play()
end
elseif Part:IsA("Decal") then
local GoalTransparency = Enabled and 1 or 0
TweenService:Create(Part, TweenInfo.new(FadeTime), { Transparency = GoalTransparency }):Play()
end
end
end
local function ApplyInvisibility(Character, Enabled, PlaySound)
FadeParts(Character, Enabled)
FadeParts(Tool, Enabled)
local Humanoid = Character:FindFirstChildOfClass("Humanoid")
if Humanoid then
Humanoid.NameDisplayDistance = Enabled and 0 or 100
if Enabled then
Tool:SetAttribute("SpeedModifier", 1.75)
else
Tool:SetAttribute("SpeedModifier", 1)
end
end
if PlaySound then
if Enabled then
WooshStart:Play()
else
WooshEnd:Play()
end
end
end
Tool.Equipped:Connect(function()
CurrentCharacter = Tool.Parent
if IsInvisible and CurrentCharacter then
FadeParts(Tool, true)
end
end)
Tool.Activated:Connect(function()
if not CurrentCharacter then return end
local Humanoid = CurrentCharacter:FindFirstChildOfClass("Humanoid")
if not Humanoid then return end
IsInvisible = not IsInvisible
ApplyInvisibility(CurrentCharacter, IsInvisible, true)
end)
Tool.Unequipped:Connect(function()
if IsInvisible and CurrentCharacter then
IsInvisible = false
ApplyInvisibility(CurrentCharacter, false, false)
end
CurrentCharacter = nil
end) - Edit
03:12:20.384
- Edit
03:12:20.384
============================== - Edit
03:12:20.384 📜 ReplicatedStorage.Items.Taser Gun.TaserController - Edit
03:12:20.384 ==============================
- Edit
03:12:20.384 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local Debounce = require(Packages.Debounce)
local RagdollModule = require(Packages.Ragdoll)
local TASER_COOLDOWN = 5
local TASER_RANGE = 50
local taserRemote = Net:RemoteEvent("TaserGun/ShotPlayer")
local function createBeam(startPos, endPos)
local beamPartStart = Instance.new("Part")
beamPartStart.Anchored = true
beamPartStart.CanCollide = false
beamPartStart.Transparency = 1
beamPartStart.Size = Vector3.new(0.1, 0.1, 0.1)
beamPartStart.Position = startPos
beamPartStart.Parent = workspace
local beamPartEnd = Instance.new("Part")
beamPartEnd.Anchored = true
beamPartEnd.CanCollide = false
beamPartEnd.Transparency = 1
beamPartEnd.Size = Vector3.new(0.1, 0.1, 0.1)
beamPartEnd.Position = endPos
beamPartEnd.Parent = workspace
local attachmentStart = Instance.new("Attachment")
attachmentStart.Position = Vector3.new(0, 0, 0)
attachmentStart.Parent = beamPartStart
local attachmentEnd = Instance.new("Attachment")
attachmentEnd.Position = Vector3.new(0, 0, 0)
attachmentEnd.Parent = beamPartEnd
local beam = Instance.new("Beam")
beam.Attachment0 = attachmentStart
beam.Attachment1 = attachmentEnd
beam.Color = ColorSequence.new(Color3.fromRGB(0, 255, 255))
beam.Width0 = 0.5
beam.Width1 = 0.5
beam.Transparency = NumberSequence.new(0)
beam.Parent = workspace
game.Debris:AddItem(beamPartStart, 1)
game.Debris:AddItem(beamPartEnd, 1)
end
local function isValidTarget(player, targetModel, taserPosition)
if not targetModel or not targetModel:IsA("Model") then
return false
end
local humanoid = targetModel:FindFirstChildOfClass("Humanoid")
if not humanoid or humanoid.Health <= 0 then
return false
end
local targetPlayer = Players:GetPlayerFromCharacter(targetModel)
if not targetPlayer then
return false
end
local rootPart = targetModel:FindFirstChild("HumanoidRootPart")
if not rootPart then
return false
end
local distance = (taserPosition - rootPart.Position).Magnitude
if distance > TASER_RANGE then
return false
end
return true, targetPlayer, humanoid, rootPart
end
taserRemote.OnServerEvent:Connect(function(player, targetModel)
if not player or not player.Character or not player.Character:FindFirstChild("HumanoidRootPart") then
return
end
if Debounce(("ServerTaser/%s"):format(player.Name), TASER_COOLDOWN) then
return
end
local taserPosition = player.Character.HumanoidRootPart.Position
local isValid, targetPlayer, targetHumanoid, targetRootPart = isValidTarget(player, targetModel, taserPosition)
if not isValid then
return
end
if not targetPlayer.Character then
return
end
createBeam(taserPosition, targetRootPart.Position)
RagdollModule.TimedRagdoll(targetPlayer.Character, 3)
end)
local tool = script.Parent
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end) - Edit
03:12:20.384
- Edit
03:12:20.384
============================== - Edit
03:12:20.384 📜 ReplicatedStorage.Items.Taser Gun.TaserScript - Edit
03:12:20.384 ==============================
- Edit
03:12:20.384 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: TaserScript, time of decompilation: Tue Jun 24 14:16:10 2025 ]]
local _ = game:GetService("StarterPlayer");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("ServerScriptService");
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v4 = require(l_Packages_0.Net);
local v5 = require(l_Packages_0.Debounce);
local l_Parent_0 = script.Parent;
local l_Parent_1 = l_Parent_0.Parent.Parent;
l_Parent_0.Activated:Connect(function() --[[ Line: 14 ]]
-- upvalues: v5 (copy), l_Parent_1 (copy), v4 (copy)
if v5(("ItemUse/TaserGun/%*"):format(l_Parent_1.Name), 5) then
return;
else
local l_Target_0 = game.Players.LocalPlayer:GetMouse().Target;
if not l_Target_0 then
return;
else
local l_l_Target_0_FirstAncestorOfClass_0 = l_Target_0:FindFirstAncestorOfClass("Model");
if not l_l_Target_0_FirstAncestorOfClass_0 then
return;
elseif not l_l_Target_0_FirstAncestorOfClass_0:FindFirstChildOfClass("Humanoid") then
return;
else
v4:RemoteEvent("TaserGun/ShotPlayer"):FireServer(l_l_Target_0_FirstAncestorOfClass_0);
return;
end;
end;
end;
end); - Edit
03:12:20.384
- Edit
03:12:20.384
============================== - Edit
03:12:20.384 📜 ReplicatedStorage.Items.Rage Table.TableController - Edit
03:12:20.384 ==============================
- Edit
03:12:20.384 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local COOLDOWN_DURATION = 5
local Cooldowns = {}
local ThrowTableTemplate = Instance.new("Part")
ThrowTableTemplate.FormFactor = Enum.FormFactor.Custom
ThrowTableTemplate.Size = Vector3.new(4.8, 2.43, 3.63)
ThrowTableTemplate.CanCollide = true
local tmesh = Instance.new("SpecialMesh")
tmesh.MeshId = "http://www.roblox.com/asset/?id=111868131"
tmesh.TextureId = "http://www.roblox.com/asset/?id=111867655"
tmesh.Parent = ThrowTableTemplate
local function FindAttachedHumanoid(part)
local current = part
while current and current.Parent do
if current.Parent:FindFirstChild("Humanoid") then
return current.Parent
end
current = current.Parent
end
return nil
end
Net:RemoteEvent("Table/LaunchTable").OnServerEvent:Connect(function(player)
local now = tick()
if Cooldowns[player] and now - Cooldowns[player] < COOLDOWN_DURATION then
return
end
Cooldowns[player] = now
local character = player.Character
if not character then return end
local tool = character:FindFirstChildWhichIsA("Tool")
if not tool or tool.Name ~= "Rage Table" then return end
tool:SetAttribute("CooldownTime", COOLDOWN_DURATION)
task.spawn(function()
for i = COOLDOWN_DURATION - 1, 0, -1 do
task.wait(1)
if tool and tool:IsDescendantOf(game) then
tool:SetAttribute("CooldownTime", i)
end
end
end)
local humanoid = character:FindFirstChildOfClass("Humanoid")
local torso = character:FindFirstChild("Torso") or character:FindFirstChild("UpperTorso")
if not humanoid or humanoid.Health <= 0 or not torso then return end
humanoid.WalkSpeed = 0
local lookGyro = Instance.new("BodyGyro")
lookGyro.MaxTorque = Vector3.new(0, math.huge, 0)
lookGyro.CFrame = torso.CFrame - torso.CFrame.Position
lookGyro.Parent = torso
local tableClone = ThrowTableTemplate:Clone()
tableClone.CFrame = torso.CFrame + Vector3.new(0, 0, 3)
tableClone.Parent = workspace
local angularVelocity = Instance.new("BodyAngularVelocity")
angularVelocity.MaxTorque = Vector3.new(math.huge, math.huge, math.huge)
angularVelocity.AngularVelocity = (torso.CFrame * CFrame.Angles(0, math.pi / 2, 0)).LookVector * 5
angularVelocity.Parent = tableClone
local velocity = Instance.new("BodyVelocity")
velocity.MaxForce = Vector3.new(math.huge, 0, math.huge)
velocity.Velocity = torso.CFrame.LookVector * 15
velocity.Parent = tableClone
local touched = false
local connection
connection = tableClone.Touched:Connect(function(part)
if touched then return end
if part:IsDescendantOf(character) then return end
if part.Parent == workspace.Terrain or part.Anchored then return end
local targetCharacter = FindAttachedHumanoid(part)
if targetCharacter and targetCharacter ~= character then
touched = true
local targetHumanoid = targetCharacter:FindFirstChildOfClass("Humanoid")
if targetHumanoid and targetHumanoid.Health > 0 then
local root = targetCharacter:FindFirstChild("HumanoidRootPart")
if root then
local wasAnchored = root.Anchored
root.Anchored = true
task.delay(1.5, function()
if root then root.Anchored = wasAnchored end
end)
end
targetHumanoid.BreakJointsOnDeath = false
RagdollModule.TimedRagdoll(targetCharacter, 3)
task.delay(3, function()
if targetHumanoid then
targetHumanoid.BreakJointsOnDeath = true
end
end)
tableClone.Velocity = Vector3.new(0, 0, 0)
angularVelocity:Destroy()
velocity:Destroy()
if connection then connection:Disconnect() end
task.delay(2, function()
if tableClone then tableClone:Destroy() end
end)
end
end
end)
task.delay(6, function()
if lookGyro then lookGyro:Destroy() end
humanoid.WalkSpeed = 16
end)
task.delay(8, function()
if connection then connection:Disconnect() end
if tableClone and tableClone.Parent then
tableClone:Destroy()
end
end)
end)
local tool = script.Parent
tool:SetAttribute("CooldownTime", 0)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end)
- Edit
03:12:20.384
- Edit
03:12:20.384
============================== - Edit
03:12:20.384 📜 ReplicatedStorage.Items.Rage Table.TableScript - Edit
03:12:20.385 ==============================
- Edit
03:12:20.385 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: TableScript, time of decompilation: Tue Jun 24 14:16:10 2025 ]]
local _ = game:GetService("StarterPlayer");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("ServerScriptService");
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v4 = require(l_Packages_0.Net);
local v5 = require(l_Packages_0.Debounce);
local l_Parent_0 = script.Parent;
local l_Parent_1 = l_Parent_0.Parent.Parent;
local v8 = nil;
l_Parent_0.Activated:Connect(function() --[[ Line: 15 ]]
-- upvalues: v5 (copy), l_Parent_1 (copy), v8 (ref), v4 (copy)
if not v8 then
v8 = l_Parent_1.Character:WaitForChild("Humanoid"):WaitForChild("Animator"):LoadAnimation(script.ThrowTable);
v8.Priority = Enum.AnimationPriority.Action;
v8.Looped = false;
end;
v4:RemoteEvent("Table/LaunchTable"):FireServer();
task.wait(0.1);
v8:Play();
return;
end); - Edit
03:12:20.385
- Edit
03:12:20.385
============================== - Edit
03:12:20.385 📜 ReplicatedStorage.Items.Boogie Bomb.BoogieController - Edit
03:12:20.385 ==============================
- Edit
03:12:20.385 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local RemoteEvent = Net:RemoteEvent("BoogieBomb/Throw")
local tool = script.Parent
RemoteEvent.OnServerEvent:Connect(function(player)
local character = player.Character
if not character then return end
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if not humanoidRootPart then return end
for _, targetPlayer in Players:GetPlayers() do
if targetPlayer ~= player then
local targetCharacter = targetPlayer.Character
if targetCharacter then
local targetHumanoidRootPart = targetCharacter:FindFirstChild("HumanoidRootPart")
if targetHumanoidRootPart then
local distance = (humanoidRootPart.Position - targetHumanoidRootPart.Position).Magnitude
if distance <= 30 then
RemoteEvent:FireClient(targetPlayer)
tool:Destroy()
end
end
end
end
end
end)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end) - Edit
03:12:20.385
- Edit
03:12:20.385
============================== - Edit
03:12:20.385 📜 ReplicatedStorage.Items.Boogie Bomb.BoogieScript - Edit
03:12:20.385 ==============================
- Edit
03:12:20.385 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: BoogieScript, time of decompilation: Tue Jun 24 14:16:10 2025 ]]
local _ = game:GetService("RunService");
local _ = game:GetService("TweenService");
local _ = game:GetService("StarterPlayer");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("ServerScriptService");
local _ = l_ReplicatedStorage_0:WaitForChild("Models").ToolsExtras;
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v7 = require(l_Packages_0.Net);
local v8 = require(l_Packages_0.Debounce);
local l_Parent_0 = script.Parent;
local l_Parent_1 = l_Parent_0.Parent.Parent;
l_Parent_0.Activated:Connect(function() --[[ Line: 20 ]]
-- upvalues: v8 (copy), l_Parent_1 (copy), v7 (copy)
if v8(("ItemUse/BoogieTimeThrow/%*"):format(l_Parent_1.Name), 10) then
return;
else
v7:RemoteEvent("BoogieBomb/Throw"):FireServer();
return;
end;
end); - Edit
03:12:20.385
- Edit
03:12:20.385
============================== - Edit
03:12:20.385 📜 ReplicatedStorage.Items.Gravity Coil.GravityScript - Edit
03:12:20.385 ==============================
- Edit
03:12:20.385 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: ComboScript, time of decompilation: Tue Jun 24 14:16:10 2025 ]]
local l_Parent_0 = script.Parent;
l_Parent_0.Equipped:Connect(function() --[[ Line: 4 ]]
workspace.Gravity = 29.429999999999996;
end);
l_Parent_0.Unequipped:Connect(function() --[[ Line: 11 ]]
workspace.Gravity = 196.2;
end); - Edit
03:12:20.385
- Edit
03:12:20.385
============================== - Edit
03:12:20.386 📜 ReplicatedStorage.Items.Gravity Coil.GravityController - Edit
03:12:20.386 ==============================
- Edit
03:12:20.386 local PlayerSpeed = 32
local Players = game:GetService("Players")
local tool = script.Parent
script.Parent.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
script.Parent:SetAttribute("JumpModifier",1.9)
end)
script.Parent.Unequipped:Connect(function()
script.Parent:SetAttribute("JumpModifier",0)
end)
- Edit
03:12:20.386
- Edit
03:12:20.386
============================== - Edit
03:12:20.386 📜 ReplicatedStorage.Items.Medusa's Head v1.MedusaScript - Edit
03:12:20.386 ==============================
- Edit
03:12:20.386 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: MedusaScript, time of decompilation: Tue Jun 24 14:16:10 2025 ]]
local l_RunService_0 = game:GetService("RunService");
local l_TweenService_0 = game:GetService("TweenService");
local _ = game:GetService("StarterPlayer");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("ServerScriptService");
local l_ToolsExtras_0 = l_ReplicatedStorage_0:WaitForChild("Models").ToolsExtras;
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v7 = require(l_Packages_0.Net);
local v8 = require(l_Packages_0.Debounce);
local l_Parent_0 = script.Parent;
local l_Parent_1 = l_Parent_0.Parent.Parent;
local v11 = nil;
local v12 = nil;
local v13 = TweenInfo.new(0.3, Enum.EasingStyle.Quart, Enum.EasingDirection.In);
local v14 = nil;
local v15 = nil;
local function _() --[[ Line: 26 ]] --[[ Name: SetupHumanoidFunction ]]
-- upvalues: l_Parent_1 (copy), v15 (ref)
local l_Character_0 = l_Parent_1.Character;
local v17 = l_Character_0 and l_Character_0:FindFirstChildOfClass("Humanoid");
if v17 then
v17.Died:Once(function() --[[ Line: 30 ]]
-- upvalues: l_Parent_1 (ref), v15 (ref)
local l_workspace_FirstChild_0 = workspace:FindFirstChild((("%*.Ring"):format(l_Parent_1.Name)));
if l_workspace_FirstChild_0 then
l_workspace_FirstChild_0:Destroy();
end;
if v15 then
v15:Disconnect();
end;
end);
end;
end;
local function v24(v20) --[[ Line: 42 ]] --[[ Name: TweenRing ]]
-- upvalues: v14 (ref), l_TweenService_0 (copy), v13 (copy)
if not v14 then
return;
else
local v21 = Instance.new("NumberValue", script);
v21.Value = not v20 and 0.75 or 1.0E-4;
v21.Changed:Connect(function(v22) --[[ Line: 49 ]]
-- upvalues: v14 (ref)
if v14 then
v14:ScaleTo(v22);
end;
end);
local v23 = l_TweenService_0:Create(v21, v13, {
Value = v20 and 0.75 or 1.0E-4
});
v23:Play();
v23.Completed:Connect(function() --[[ Line: 57 ]]
-- upvalues: v21 (copy)
v21:Destroy();
end);
v23.Completed:Wait();
return;
end;
end;
local function v26() --[[ Line: 63 ]] --[[ Name: LoadAnimations ]]
-- upvalues: v11 (ref), v12 (ref), l_Parent_1 (copy)
if v11 and v12 then
return;
else
local l_Animator_0 = l_Parent_1.Character:WaitForChild("Humanoid"):WaitForChild("Animator");
v11 = l_Animator_0:LoadAnimation(script.Idle);
v11.Priority = Enum.AnimationPriority.Action;
v11.Looped = true;
v12 = l_Animator_0:LoadAnimation(script.Attack);
v12.Priority = Enum.AnimationPriority.Action4;
v12.Looped = false;
return;
end;
end;
l_Parent_0.Activated:Connect(function() --[[ Line: 82 ]]
-- upvalues: v7 (copy), v12 (ref), v8 (copy), l_Parent_1 (copy)
local l_status_0, l_result_0 = pcall(function() --[[ Line: 87 ]]
-- upvalues: v7 (ref)
return v7:Invoke("MedusaHead/Transform");
end);
if not l_status_0 or type(l_result_0) ~= "number" then
return;
else
if v12 then
v12:Play();
end;
v8(("ItemUse/MedusaAttackAnimation/%*"):format(l_Parent_1.Name), l_result_0 - workspace:GetServerTimeNow());
return;
end;
end);
l_Parent_0.Equipped:Connect(function() --[[ Line: 102 ]]
-- upvalues: v14 (ref), v15 (ref), v26 (copy), v11 (ref), l_ToolsExtras_0 (copy), l_Parent_1 (copy), v24 (copy), l_RunService_0 (copy)
if v14 then
v14:Destroy();
end;
if v15 then
v15:Disconnect();
end;
v26();
v11:Play();
v14 = l_ToolsExtras_0.Ring:Clone();
v14.Name = ("%*.Ring"):format(l_Parent_1.Name);
v14:PivotTo(l_Parent_1.Character:GetPivot());
v14.Parent = workspace;
v24(true);
local l_Character_1 = l_Parent_1.Character;
local v30 = l_Character_1 and l_Character_1:FindFirstChildOfClass("Humanoid");
if v30 then
v30.Died:Once(function() --[[ Line: 30 ]]
-- upvalues: l_Parent_1 (ref), v15 (ref)
local l_workspace_FirstChild_1 = workspace:FindFirstChild((("%*.Ring"):format(l_Parent_1.Name)));
if l_workspace_FirstChild_1 then
l_workspace_FirstChild_1:Destroy();
end;
if v15 then
v15:Disconnect();
end;
end);
end;
v15 = l_RunService_0.Heartbeat:Connect(function() --[[ Line: 121 ]]
-- upvalues: l_Parent_1 (ref), v14 (ref)
local l_Character_2 = l_Parent_1.Character;
local v33 = l_Character_2 and l_Character_2:FindFirstChild("HumanoidRootPart");
if not v33 or not v33.Parent then
return;
else
if v14 then
v14:PivotTo(v33:GetPivot() * CFrame.new(0, -3, 0));
end;
return;
end;
end);
end);
l_Parent_0.Unequipped:Connect(function() --[[ Line: 133 ]]
-- upvalues: v15 (ref), v24 (copy), v14 (ref), v11 (ref), v12 (ref)
if v15 then
v15:Disconnect();
v15 = nil;
end;
v24(false);
if v15 then
v15:Disconnect();
v15 = nil;
end;
if v14 then
v14:Destroy();
v14 = nil;
end;
if v11 and v11.IsPlaying then
v11:Stop();
end;
if v12 and v12.IsPlaying then
v12:Stop();
end;
end); - Edit
03:12:20.386
- Edit
03:12:20.386
============================== - Edit
03:12:20.386 📜 ReplicatedStorage.Items.Medusa's Head v1.MedusaController - Edit
03:12:20.386 ==============================
- Edit
03:12:20.386 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Debris = game:GetService("Debris")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local debounce = {}
local COOLDOWN = 25 -- cooldown in seconds
local function TagHumanoid(humanoid, player)
local Creator_Tag = Instance.new("ObjectValue")
Creator_Tag.Name = "creator"
Creator_Tag.Value = player
Debris:AddItem(Creator_Tag, 2)
Creator_Tag.Parent = humanoid
end
Net:RemoteFunction("MedusaHead/Transform").OnServerInvoke = function(player)
if not player.Character then
return
end
local tool = player.Character:FindFirstChildWhichIsA("Tool")
local humanoid = player.Character:FindFirstChildOfClass("Humanoid")
if not humanoid or humanoid.Health <= 0 then
return
end
local head = player.Character:FindFirstChild("Head")
if not head then
return
end
player.Character.Archivable = true
-- Cooldown check
if debounce[player] and tick() - debounce[player] < COOLDOWN then
return 0
end
local regionPos = head.Position
local radius = 15
for _, targetPlayer in pairs(Players:GetPlayers()) do
if targetPlayer ~= player and targetPlayer.Character then
targetPlayer.Character.Archivable = true
local targetCharacter = targetPlayer.Character
local targetHumanoid = targetCharacter:FindFirstChildOfClass("Humanoid")
local targetRootPart = targetCharacter:FindFirstChild("HumanoidRootPart")
if targetHumanoid and targetRootPart and targetHumanoid.Health > 0 then
local distance = (targetRootPart.Position - regionPos).Magnitude
if distance <= radius then
local forceFieldExists = false
for _, v in pairs(targetCharacter:GetChildren()) do
if v:IsA("ForceField") then
forceFieldExists = true
break
end
end
if not forceFieldExists then
TagHumanoid(targetHumanoid, player)
local stoneClone = targetCharacter:Clone()
stoneClone.Parent = workspace
stoneClone.HumanoidRootPart.CFrame = targetCharacter.HumanoidRootPart.CFrame
for _, v in pairs(stoneClone:GetChildren()) do
if v:IsA("BasePart") then
v.Anchored = true
v.BrickColor = BrickColor.new("Dark stone grey")
v.Material = Enum.Material.SmoothPlastic
elseif v:IsA("Humanoid") then
v:Destroy()
end
end
Debris:AddItem(stoneClone, 5)
RagdollModule.TimedRagdoll(targetCharacter, 5)
end
end
end
end
end
debounce[player] = tick()
return 5
end
local tool = script.Parent
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end)
- Edit
03:12:20.386
- Edit
03:12:20.386
============================== - Edit
03:12:20.386 📜 ReplicatedStorage.Items.Bee Launcher.BeeLauncherController - Edit
03:12:20.386 ==============================
- Edit
03:12:20.386 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local RemoteEvent = Net:RemoteEvent("BeeLauncher/Shoot")
local tool = script.Parent
RemoteEvent.OnServerEvent:Connect(function(player, targetPlayer)
if not targetPlayer or not Players:GetPlayerFromCharacter(targetPlayer.Character) then return end
local character = player.Character
local targetCharacter = targetPlayer.Character
if not character or not targetCharacter then return end
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
local targetHumanoidRootPart = targetCharacter:FindFirstChild("HumanoidRootPart")
if not humanoidRootPart or not targetHumanoidRootPart then return end
local distance = (humanoidRootPart.Position - targetHumanoidRootPart.Position).Magnitude
if distance > 30 then return end
RemoteEvent:FireClient(targetPlayer)
end)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end) - Edit
03:12:20.386
- Edit
03:12:20.387
============================== - Edit
03:12:20.387 📜 ReplicatedStorage.Items.Bee Launcher.BeeLauncherScript - Edit
03:12:20.387 ==============================
- Edit
03:12:20.387 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: BeeLauncherScript, time of decompilation: Tue Jun 24 14:16:11 2025 ]]
local l_Players_0 = game:GetService("Players");
local l_RunService_0 = game:GetService("RunService");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = l_ReplicatedStorage_0:WaitForChild("Models").ToolsExtras;
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v5 = require(l_Packages_0.Net);
local v6 = require(l_Packages_0.Debounce);
local l_Parent_0 = script.Parent;
local l_Parent_1 = l_Parent_0.Parent.Parent;
local l_Highlight_0 = Instance.new("Highlight");
l_Highlight_0.DepthMode = Enum.HighlightDepthMode.Occluded;
l_Highlight_0.FillColor = Color3.fromRGB(255, 0, 0);
l_Highlight_0.FillTransparency = 0.5;
l_Highlight_0.OutlineColor = Color3.fromRGB(155, 0, 0);
l_Highlight_0.OutlineTransparency = 0.8;
l_Highlight_0.Parent = workspace;
l_Highlight_0.Adornee = script;
local v10 = nil;
local function v20() --[[ Line: 30 ]] --[[ Name: GetNearestPlayer ]]
-- upvalues: l_Parent_1 (copy), l_Players_0 (copy)
local l_Character_0 = l_Parent_1.Character;
if not l_Character_0 then
return;
else
local l_HumanoidRootPart_0 = l_Character_0:FindFirstChild("HumanoidRootPart");
if not l_HumanoidRootPart_0 then
return;
else
local v13 = nil;
local v14 = 1e999;
for _, v16 in l_Players_0:GetPlayers() do
if v16 ~= l_Parent_1 then
local l_Character_1 = v16.Character;
local v18 = l_Character_1 and l_Character_1:FindFirstChild("HumanoidRootPart");
if v18 then
local l_Magnitude_0 = (l_HumanoidRootPart_0.Position - v18.Position).Magnitude;
if l_Magnitude_0 <= 30 and l_Magnitude_0 < v14 then
v14 = l_Magnitude_0;
v13 = l_Character_1;
end;
end;
end;
end;
return v13, l_Players_0:GetPlayerFromCharacter(v13);
end;
end;
end;
l_Parent_0.Activated:Connect(function() --[[ Line: 60 ]]
-- upvalues: v6 (copy), l_Parent_1 (copy), v5 (copy), v10 (ref)
if v6(("ItemUse/BeeAttackClient/%*"):format(l_Parent_1.Name), 10) then
return;
else
v5:RemoteEvent("BeeLauncher/Shoot"):FireServer(v10);
return;
end;
end);
l_Parent_0.Equipped:Connect(function() --[[ Line: 67 ]]
-- upvalues: l_RunService_0 (copy), v20 (copy), v10 (ref), l_Highlight_0 (copy)
l_RunService_0:BindToRenderStep("BeeTarget", Enum.RenderPriority.Character.Value + 1, function() --[[ Line: 68 ]]
-- upvalues: v20 (ref), v10 (ref), l_Highlight_0 (ref)
local v21, v22 = v20();
if v21 and v21 ~= v10 then
l_Highlight_0.Adornee = v21;
v10 = v22;
return;
else
l_Highlight_0.Adornee = script;
v10 = nil;
return;
end;
end);
end);
l_Parent_0.Unequipped:Connect(function() --[[ Line: 80 ]]
-- upvalues: l_RunService_0 (copy), l_Highlight_0 (copy), v10 (ref)
l_RunService_0:UnbindFromRenderStep("BeeTarget");
l_Highlight_0.Adornee = script;
v10 = nil;
end); - Edit
03:12:20.387
- Edit
03:12:20.387
============================== - Edit
03:12:20.387 📜 ReplicatedStorage.Items.Flying Carpet.Script - Edit
03:12:20.387 ==============================
- Edit
03:12:20.387 Tool = script.Parent
Handle = Tool:WaitForChild("Handle")
Players = game:GetService("Players")
Debris = game:GetService("Debris")
RemovalMonitor = script:WaitForChild("RemovalMonitor")
CarpetPieces = {
{MeshId = 223079795, Angle = 160},
{MeshId = 223079835, Angle = 100},
{MeshId = 223079888, Angle = 100},
{MeshId = 223079981, Angle = 160},
}
CarpetSize = Vector3.new(3, 0.5, 6.5)
BaseUrl = "http://www.roblox.com/asset/?id="
Rate = (1 / 10)
BasePart = Instance.new("Part")
BasePart.Material = Enum.Material.Plastic
BasePart.Shape = Enum.PartType.Block
BasePart.TopSurface = Enum.SurfaceType.Smooth
BasePart.BottomSurface = Enum.SurfaceType.Smooth
BasePart.FormFactor = Enum.FormFactor.Custom
BasePart.Size = Vector3.new(0.2, 0.2, 0.2)
BasePart.CanCollide = false
BasePart.Locked = true
ColorPart = BasePart:Clone()
ColorPart.Name = "ColorPart"
ColorPart.Reflectance = 0.25
ColorPart.Transparency = 0.1
ColorPart.Material = Enum.Material.SmoothPlastic
ColorPart.FrontSurface = Enum.SurfaceType.SmoothNoOutlines
ColorPart.BackSurface = Enum.SurfaceType.SmoothNoOutlines
ColorPart.TopSurface = Enum.SurfaceType.SmoothNoOutlines
ColorPart.BottomSurface = Enum.SurfaceType.SmoothNoOutlines
ColorPart.LeftSurface = Enum.SurfaceType.SmoothNoOutlines
ColorPart.RightSurface = Enum.SurfaceType.SmoothNoOutlines
ColorPart.Size = Vector3.new(1, 1, 1)
ColorPart.Anchored = true
ColorPart.CanCollide = false
ColorMesh = Instance.new("SpecialMesh")
ColorMesh.Name = "Mesh"
ColorMesh.MeshType = Enum.MeshType.FileMesh
ColorMesh.MeshId = (BaseUrl .. "9856898")
ColorMesh.TextureId = (BaseUrl .. "1361097")
ColorMesh.Scale = (ColorPart.Size * 2) --Default mesh scale is 1/2 the size of a 1x1x1 brick.
ColorMesh.Offset = Vector3.new(0, 0, 0)
ColorMesh.VertexColor = Vector3.new(1, 1, 1)
ColorMesh.Parent = ColorPart
RainbowColors = {
Vector3.new(1, 0, 0),
Vector3.new(1, 0.5, 0),
Vector3.new(1, 1, 0),
Vector3.new(0, 1, 0),
Vector3.new(0, 1, 1),
Vector3.new(0, 0, 1),
Vector3.new(0.5, 0, 1)
}
Animations = {
Sit = {Animation = Tool:WaitForChild("Sit"), FadeTime = nil, Weight = nil, Speed = nil, Duration = nil},
}
Grips = {
Normal = CFrame.new(-1.5, 0, 0, 0, 0, -1, -1, 8.90154915e-005, 0, 8.90154915e-005, 1, 0),
Flying = CFrame.new(-1.5, 0.5, -0.75, -1, 0, -8.99756625e-009, -8.99756625e-009, 8.10000031e-008, 1, 7.28802977e-016, 0.99999994, -8.10000103e-008)
}
Flying = false
ToolEquipped = false
ServerControl = (Tool:FindFirstChild("ServerControl") or Instance.new("RemoteFunction"))
ServerControl.Name = "ServerControl"
ServerControl.Parent = Tool
ClientControl = (Tool:FindFirstChild("ClientControl") or Instance.new("RemoteFunction"))
ClientControl.Name = "ClientControl"
ClientControl.Parent = Tool
Handle.Transparency = 0
Tool.Grip = Grips.Normal
Tool.Enabled = true
function Clamp(Number, Min, Max)
return math.max(math.min(Max, Number), Min)
end
function TransformModel(Objects, Center, NewCFrame, Recurse)
local Objects = ((type(Objects) ~= "table" and {Objects}) or Objects)
for i, v in pairs(Objects) do
if v:IsA("BasePart") then
v.CFrame = NewCFrame:toWorldSpace(Center:toObjectSpace(v.CFrame))
end
if Recurse then
TransformModel(v:GetChildren(), Center, NewCFrame, true)
end
end
end
function Weld(Parent, PrimaryPart)
local Parts = {}
local Welds = {}
local function WeldModel(Parent, PrimaryPart)
for i, v in pairs(Parent:GetChildren()) do
if v:IsA("BasePart") then
if v ~= PrimaryPart then
local Weld = Instance.new("Weld")
Weld.Name = "Weld"
Weld.Part0 = PrimaryPart
Weld.Part1 = v
Weld.C0 = PrimaryPart.CFrame:inverse()
Weld.C1 = v.CFrame:inverse()
Weld.Parent = PrimaryPart
table.insert(Welds, Weld)
end
table.insert(Parts, v)
end
WeldModel(v, PrimaryPart)
end
end
WeldModel(Parent, PrimaryPart)
return Parts, Welds
end
function CleanUp()
for i, v in pairs(Tool:GetChildren()) do
if v:IsA("BasePart") and v ~= Handle then
v:Destroy()
end
end
end
function CreateRainbow(Length)
local RainbowModel = Instance.new("Model")
RainbowModel.Name = "RainbowPart"
local RainbowBoundingBox = BasePart:Clone()
RainbowBoundingBox.Name = "BoundingBox"
RainbowBoundingBox.Transparency = 1
RainbowBoundingBox.Size = RainbowModel:GetModelSize()
RainbowBoundingBox.Anchored = true
RainbowBoundingBox.CanCollide = false
RainbowBoundingBox.CFrame = RainbowModel:GetModelCFrame()
RainbowBoundingBox.Parent = RainbowModel
return RainbowModel
end
function GetRainbowModel()
local ModelName = (Player.Name .. "'s Rainbow")
local Model = game:GetService("Workspace"):FindFirstChild(ModelName)
if not Model then
Model = Instance.new("Model")
Model.Name = ModelName
local RemovalMonitorClone = RemovalMonitor:Clone()
RemovalMonitorClone.Disabled = false
RemovalMonitorClone.Parent = Model
end
return Model
end
function CheckIfAlive()
return (((Character and Character.Parent and Humanoid and Humanoid.Parent and Humanoid.Health > 0 and Torso and Torso.Parent and Player and Player.Parent) and true) or false)
end
function Activated()
if not Tool.Enabled then
return
end
Tool.Enabled = false
Flying = not Flying
if Flying then
Handle.Transparency = 1
CleanUp()
local CarpetParts = {}
for i, v in pairs(CarpetPieces) do
local CarpetPart = BasePart:Clone()
CarpetPart.Size = Vector3.new(CarpetSize.X, CarpetSize.Y, (CarpetSize.Z / #CarpetPieces))
local Mesh = Instance.new("SpecialMesh")
Mesh.MeshType = Enum.MeshType.FileMesh
Mesh.MeshId = (BaseUrl .. v.MeshId)
Mesh.TextureId = (BaseUrl .. "223080038")
Mesh.Scale = Vector3.new(1.125, 1.125, 1.125)
Mesh.VertexColor = Vector3.new(1, 1, 1)
Mesh.Offset = Vector3.new(0, 0, 0)
Mesh.Parent = CarpetPart
local Weld = Instance.new("Weld")
Weld.Part0 = Handle
Weld.Part1 = CarpetPart
local XOffset = (((i == 1 or i == #CarpetPieces) and -0.005) or 0)
local YOffset = ((-((Handle.Size.Z / 2) - (CarpetPart.Size.Z / 2))) + ((CarpetPart.Size.Z * (i - 1))) + ((i == 2 and 0.245) or (i == 3 and 0.04) or (i == #CarpetPieces and 0.28) or 0))
Weld.C1 = CFrame.new(0, XOffset, YOffset)
Weld.Parent = CarpetPart
table.insert(CarpetParts, {Part = CarpetPart, Weld = Weld, InitialCFrame = Weld.C0, Angle = v.Angle})
CarpetPart.Parent = Tool
end
spawn(function()
InvokeClient("PlayAnimation", Animations.Sit)
Tool.Grip = Grips.Flying
end)
Torso.Anchored = true
delay(.2,function()
Torso.Anchored = false
Torso.Velocity = Vector3.new(0,0,0)
Torso.RotVelocity = Vector3.new(0,0,0)
end)
FlightSpin = Instance.new("BodyGyro")
FlightSpin.Name = "FlightSpin"
FlightSpin.P = 10000
FlightSpin.maxTorque = Vector3.new(FlightSpin.P, FlightSpin.P, FlightSpin.P)*100
FlightSpin.cframe = Torso.CFrame
FlightPower = Instance.new("BodyVelocity")
FlightPower.Name = "FlightPower"
FlightPower.velocity = Vector3.new(0, 0, 0)
FlightPower.maxForce = Vector3.new(1,1,1)*1000000
FlightPower.P = 1000
FlightHold = Instance.new("BodyPosition")
FlightHold.Name = "FlightHold"
FlightHold.P = 100000
FlightHold.maxForce = Vector3.new(0, 0, 0)
FlightHold.position = Torso.Position
FlightSpin.Parent = Torso
FlightPower.Parent = Torso
FlightHold.Parent = Torso
spawn(function()
local LastPlace = nil
while Flying and ToolEquipped and CheckIfAlive() do
local CurrentPlace = Handle.Position
local Velocity = Torso.Velocity
Velocity = Vector3.new(Velocity.X, 0, Velocity.Z).magnitude
if LastPlace and Velocity > 10 then
spawn(function()
local Model = GetRainbowModel()
local Distance = (LastPlace - CurrentPlace).magnitude
local Length = Distance + 3.5
local RainbowModel = CreateRainbow(Length)
--Thanks so much to ArceusInator for helping solve this part!
local RainbowCFrame = CFrame.new((LastPlace + (CurrentPlace - LastPlace).unit * (Distance / 2)), CurrentPlace)
TransformModel(RainbowModel, RainbowModel:GetModelCFrame(), RainbowCFrame, true)
Debris:AddItem(RainbowModel, 1)
RainbowModel.Parent = Model
if Model and not Model.Parent then
Model.Parent = game:GetService("Workspace")
end
LastPlace = CurrentPlace
end)
elseif not LastPlace then
LastPlace = CurrentPlace
end
wait(Rate)
end
end)
elseif not Flying then
Torso.Velocity = Vector3.new(0, 0, 0)
Torso.RotVelocity = Vector3.new(0, 0, 0)
for i, v in pairs({FlightSpin, FlightPower, FlightHold}) do
if v and v.Parent then
v:Destroy()
end
end
spawn(function()
Tool.Grip = Grips.Normal
InvokeClient("StopAnimation", Animations.Sit)
end)
end
wait(2)
Tool.Enabled = true
end
function Equipped(Mouse)
Character = Tool.Parent
Humanoid = Character:FindFirstChild("Humanoid")
Torso = Character:FindFirstChild("HumanoidRootPart")
Player = Players:GetPlayerFromCharacter(Character)
if not CheckIfAlive() then
return
end
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
Tool.Parent = player.Backpack
end
if Humanoid then
if Humanoid.RigType == Enum.HumanoidRigType.R15 then
Animations = {
Sit = {Animation = Tool:WaitForChild("SitR15"), FadeTime = nil, Weight = nil, Speed = nil, Duration = nil},
}
else
Animations = {
Sit = {Animation = Tool:WaitForChild("Sit"), FadeTime = nil, Weight = nil, Speed = nil, Duration = nil},
}
end
end
Tool.Grip = Grips.Normal
ToolEquipped = true
end
function Unequipped()
Flying = false
for i, v in pairs({FlightSpin, FlightPower, FlightHold}) do
if v and v.Parent then
v:Destroy()
end
end
CleanUp()
Handle.Transparency = 0
ToolEquipped = false
end
function OnServerInvoke(player, mode, value)
if player ~= Player or not ToolEquipped or not value or not CheckIfAlive() then
return
end
end
function InvokeClient(Mode, Value)
local ClientReturn = nil
pcall(function()
ClientReturn = ClientControl:InvokeClient(Player, Mode, Value)
end)
return ClientReturn
end
CleanUp()
ServerControl.OnServerInvoke = OnServerInvoke
Tool.Activated:connect(Activated)
Tool.Equipped:connect(Equipped)
Tool.Unequipped:connect(Unequipped) - Edit
03:12:20.387
- Edit
03:12:20.387
============================== - Edit
03:12:20.387 📜 ReplicatedStorage.Items.Flying Carpet.Script.RemovalMonitor - Edit
03:12:20.387 ==============================
- Edit
03:12:20.387 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [FilteringEnabled] Server Scripts are IMPOSSIBLE to save - Edit
03:12:20.387
- Edit
03:12:20.388
============================== - Edit
03:12:20.388 📜 ReplicatedStorage.Items.Flying Carpet.MouseIcon - Edit
03:12:20.388 ==============================
- Edit
03:12:20.388 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: MouseIcon, time of decompilation: Tue Jun 24 14:16:11 2025 ]]
Mouse_Icon = "rbxasset://textures/GunCursor.png";
Reloading_Icon = "rbxasset://textures/GunWaitCursor.png";
Tool = script.Parent;
Mouse = nil;
UpdateIcon = function() --[[ Line: 8 ]] --[[ Name: UpdateIcon ]]
if Mouse then
Mouse.Icon = Tool.Enabled and Mouse_Icon or Reloading_Icon;
end;
end;
OnEquipped = function(v0) --[[ Line: 14 ]] --[[ Name: OnEquipped ]]
Mouse = v0;
UpdateIcon();
end;
OnChanged = function(v1) --[[ Line: 19 ]] --[[ Name: OnChanged ]]
if v1 == "Enabled" then
UpdateIcon();
end;
end;
Tool.Equipped:connect(OnEquipped);
Tool.Changed:connect(OnChanged); - Edit
03:12:20.388
- Edit
03:12:20.388
============================== - Edit
03:12:20.388 📜 ReplicatedStorage.Items.Flying Carpet.LocalScript - Edit
03:12:20.388 ==============================
- Edit
03:12:20.388 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: LocalScript, time of decompilation: Tue Jun 24 14:16:11 2025 ]]
Tool = script.Parent;
Handle = Tool:WaitForChild("Handle");
Players = game:GetService("Players");
RunService = game:GetService("RunService");
Camera = game:GetService("Workspace").CurrentCamera;
Animations = {};
LocalObjects = {};
ServerControl = Tool:WaitForChild("ServerControl");
ClientControl = Tool:WaitForChild("ClientControl");
Rate = 0.016666666666666666;
SpeedMultiplier = 1.5;
CameraSpeed = {
X = 40 * SpeedMultiplier,
Z = 60 * SpeedMultiplier
};
Controls = {
Forward = {
Mode = false,
Keys = {
Key = "w",
ByteKey = 17
}
},
Backward = {
Mode = false,
Keys = {
Key = "s",
ByteKey = 18
}
},
Left = {
Mode = false,
Keys = {
Key = "a",
ByteKey = 20
}
},
Right = {
Mode = false,
Keys = {
Key = "d",
ByteKey = 19
}
}
};
ToolEquipped = false;
HandleFlightControl = function() --[[ Line: 45 ]] --[[ Name: HandleFlightControl ]]
if not CheckIfAlive() then
return;
else
if FightMonitor then
FightMonitor:disconnect();
end;
FightMonitor = Torso.ChildAdded:connect(function(v0) --[[ Line: 52 ]]
if Flying then
return;
else
if v0.Name == "FlightHold" then
local l_FlightSpin_0 = Torso:FindFirstChild("FlightSpin");
local l_FlightPower_0 = Torso:FindFirstChild("FlightPower");
local l_FlightHold_0 = Torso:FindFirstChild("FlightHold");
if not l_FlightSpin_0 or not l_FlightPower_0 or not l_FlightHold_0 then
return;
else
Flying = true;
Humanoid.WalkSpeed = 0;
Humanoid.PlatformStand = true;
Humanoid.AutoRotate = false;
DisableJump(true);
Torso.Velocity = Vector3.new(0, 0, 0, 0);
Torso.RotVelocity = Vector3.new(0, 0, 0, 0);
while Flying and l_FlightSpin_0.Parent and l_FlightPower_0.Parent and l_FlightHold_0.Parent and CheckIfAlive() do
local v4 = Vector3.new(0, 0, 0, 0);
local v5 = Camera.CoordinateFrame:vectorToWorldSpace((Vector3.new(0, 0, -1, 0)));
local v6 = Camera.CoordinateFrame:vectorToWorldSpace((Vector3.new(-1, 0, 0, 0)));
local l_CoordinateFrame_0 = Camera.CoordinateFrame;
local v8 = CFrame.new(Vector3.new(0, 0, 0, 0), l_CoordinateFrame_0.lookVector * Vector3.new(1, 0, 1, 0)):vectorToObjectSpace(Humanoid.MoveDirection);
v4 = v4 + (v5 * CameraSpeed.Z * -v8.z or v4);
v4 = v4 + (v6 * CameraSpeed.X * -v8.x or v4);
l_FlightSpin_0.cframe = CFrame.new(Vector3.new(0, 0, 0, 0), v5);
if v4.magnitude < 1 then
l_FlightHold_0.maxForce = Vector3.new(l_FlightHold_0.P, l_FlightHold_0.P, l_FlightHold_0.P);
l_FlightPower_0.maxForce = Vector3.new(0, 0, 0, 0);
l_FlightHold_0.position = Torso.Position;
else
l_FlightHold_0.maxForce = Vector3.new(0, 0, 0, 0);
l_FlightPower_0.maxForce = Vector3.new(l_FlightPower_0.P * 100, l_FlightPower_0.P * 100, l_FlightPower_0.P * 100);
end;
l_FlightPower_0.velocity = v4;
wait(Rate);
end;
Flying = false;
if CheckIfAlive() then
Torso.Velocity = Vector3.new(0, 0, 0, 0);
Torso.RotVelocity = Vector3.new(0, 0, 0, 0);
Humanoid.WalkSpeed = 16;
Humanoid.PlatformStand = false;
Humanoid.AutoRotate = true;
DisableJump(false);
Humanoid:ChangeState(Enum.HumanoidStateType.Freefall);
end;
end;
end;
return;
end;
end);
return;
end;
end;
SetAnimation = function(v9, v10) --[[ Line: 109 ]] --[[ Name: SetAnimation ]]
if v9 == "PlayAnimation" and v10 and ToolEquipped and Humanoid then
for v11, v12 in pairs(Animations) do
if v12.Animation == v10.Animation then
v12.AnimationTrack:Stop();
table.remove(Animations, v11);
end;
end;
local v13 = Humanoid:LoadAnimation(v10.Animation);
table.insert(Animations, {
Animation = v10.Animation,
AnimationTrack = v13
});
v13:Play(v10.FadeTime, v10.Weight, v10.Speed);
return;
else
if v9 == "StopAnimation" and v10 then
for v14, v15 in pairs(Animations) do
if v15.Animation == v10.Animation then
v15.AnimationTrack:Stop();
table.remove(Animations, v14);
end;
end;
end;
return;
end;
end;
DisableJump = function(v16) --[[ Line: 130 ]] --[[ Name: DisableJump ]]
if PreventJump then
PreventJump:disconnect();
end;
if v16 then
PreventJump = Humanoid.Changed:connect(function(v17) --[[ Line: 135 ]]
if v17 == "Jump" then
Humanoid.Jump = false;
end;
end);
end;
end;
CheckIfAlive = function() --[[ Line: 143 ]] --[[ Name: CheckIfAlive ]]
if Character and Character.Parent and Humanoid and Humanoid.Parent and Humanoid.Health > 0 and Torso and Torso.Parent and Player and Player.Parent then
return true;
else
return false;
end;
end;
KeyPress = function(v18, v19) --[[ Line: 147 ]] --[[ Name: KeyPress ]]
local v20 = string.lower(v18);
local v21 = string.byte(v20);
for v22, v23 in pairs(Controls) do
if v20 == v23.Keys.Key or v21 == v23.Keys.ByteKey then
Controls[v22].Mode = v19;
end;
end;
end;
Equipped = function(v24) --[[ Line: 157 ]] --[[ Name: Equipped ]]
Character = Tool.Parent;
Player = Players:GetPlayerFromCharacter(Character);
Humanoid = Character:FindFirstChild("Humanoid");
Torso = Character:FindFirstChild("HumanoidRootPart");
ToolEquipped = true;
if not CheckIfAlive() then
return;
else
v24.KeyDown:connect(function(v25) --[[ Line: 166 ]]
KeyPress(v25, true);
end);
v24.KeyUp:connect(function(v26) --[[ Line: 169 ]]
KeyPress(v26, false);
end);
Spawn(HandleFlightControl);
return;
end;
end;
Unequipped = function() --[[ Line: 175 ]] --[[ Name: Unequipped ]]
Flying = false;
LocalObjects = {};
for _, v28 in pairs(Animations) do
if v28 and v28.AnimationTrack then
v28.AnimationTrack:Stop();
end;
end;
for _, v30 in pairs({
PreventJump,
FightMonitor
}) do
if v30 then
v30:disconnect();
end;
end;
for v31, _ in pairs(Controls) do
Controls[v31].Mode = false;
end;
Animations = {};
ToolEquipped = false;
end;
InvokeServer = function(v33, v34) --[[ Line: 195 ]] --[[ Name: InvokeServer ]]
local v35 = nil;
pcall(function() --[[ Line: 197 ]]
-- upvalues: v35 (ref), v33 (copy), v34 (copy)
v35 = ServerControl:InvokeServer(v33, v34);
end);
return v35;
end;
OnClientInvoke = function(v36, v37) --[[ Line: 203 ]] --[[ Name: OnClientInvoke ]]
if v36 == "PlayAnimation" and v37 and ToolEquipped and Humanoid then
SetAnimation("PlayAnimation", v37);
return;
elseif v36 == "StopAnimation" and v37 then
SetAnimation("StopAnimation", v37);
return;
elseif v36 == "PlaySound" and v37 then
v37:Play();
return;
else
if v36 == "StopSound" and v37 then
v37:Stop();
end;
return;
end;
end;
ClientControl.OnClientInvoke = OnClientInvoke;
Tool.Equipped:connect(Equipped);
Tool.Unequipped:connect(Unequipped); - Edit
03:12:20.388
- Edit
03:12:20.388
============================== - Edit
03:12:20.388 📜 ReplicatedStorage.Items.Laser Gun.LaserController - Edit
03:12:20.388 ==============================
- Edit
03:12:20.388 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local Players = game:GetService("Players")
local Debris = game:GetService("Debris")
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local Speed = 100
local Duration = 9999999
local NozzleOffset = Vector3.new(0, 0.4, -1.1)
local RagdollModule = require(Packages.Ragdoll)
local function FindCharacterAncestor(Parent)
if Parent and Parent ~= game:GetService("Workspace") then
local humanoid = Parent:FindFirstChild("Humanoid")
if humanoid then
return Parent, humanoid
else
return FindCharacterAncestor(Parent.Parent)
end
end
return nil
end
local function SelectionBoxify(Object)
local SelectionBox = Instance.new("SelectionBox")
SelectionBox.Adornee = Object
SelectionBox.Color = BrickColor.new("Neon orange")
SelectionBox.Parent = Object
return SelectionBox
end
local function Light(Object)
local PointLight = Instance.new("PointLight")
PointLight.Range = 12
PointLight.Color = Color3.new(1, 0.5, 0)
PointLight.Parent = Object
end
local function TagHumanoid(humanoid, player)
local Creator_Tag = Instance.new("ObjectValue")
Creator_Tag.Name = "creator"
Creator_Tag.Value = player
Debris:AddItem(Creator_Tag, 2)
Creator_Tag.Parent = humanoid
end
Net:RemoteEvent("LaserGun/ShotPlayer").OnServerEvent:Connect(function(player, hitPosition, handle)
if not player.Character or not hitPosition or not handle then
return
end
local tool = player.Character:FindFirstChildWhichIsA("Tool")
if not tool or tool.Name ~= "Laser Gun" then
return
end
if not tool.Enabled then
return
end
tool.Enabled = false
local handleCFrame = handle.CFrame
local firingPoint = handleCFrame.p + handleCFrame:vectorToWorldSpace(NozzleOffset)
local shotCFrame = CFrame.new(firingPoint, hitPosition.p)
local laserShot = Instance.new("Part")
laserShot.Name = "Effect"
laserShot.BrickColor = BrickColor.new("Really red")
laserShot.Material = Enum.Material.Neon
laserShot.Shape = Enum.PartType.Cylinder
laserShot.Size = Vector3.new(0.3, 2, 0.3)
laserShot.CanCollide = false
laserShot.Locked = true
laserShot.CFrame = shotCFrame + (shotCFrame.lookVector * (laserShot.Size.Y / 2))
SelectionBoxify(laserShot)
Light(laserShot)
local bodyVelocity = Instance.new("BodyVelocity")
bodyVelocity.Velocity = shotCFrame.lookVector * Speed
bodyVelocity.Parent = laserShot
laserShot.Touched:Connect(function(hit)
if not hit or not hit.Parent then
return
end
local character, humanoid = FindCharacterAncestor(hit)
if character and humanoid and character ~= player.Character then
local forceFieldExists = false
for _, v in pairs(character:GetChildren()) do
if v:IsA("ForceField") then
forceFieldExists = true
break
end
end
if not forceFieldExists then
TagHumanoid(humanoid, player)
local root = character:FindFirstChild("HumanoidRootPart") or character:FindFirstChild("Torso")
local direction = (hit.Position - firingPoint).Unit
local targetPlayer = Players:GetPlayerFromCharacter(character)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
CombatController:FireClient(targetPlayer, 1500, direction)
RagdollModule.TimedRagdoll(character, 5)
end
if laserShot and laserShot.Parent then
laserShot:Destroy()
end
end
end)
Debris:AddItem(laserShot, Duration)
laserShot.Parent = game:GetService("Workspace")
task.wait(0)
if handle:FindFirstChild("Fire") then
handle.Fire:Play()
end
task.wait(0)
if handle:FindFirstChild("Reload") then
handle.Reload:Play()
end
tool.Enabled = true
end)
local tool = script.Parent
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end) - Edit
03:12:20.388
- Edit
03:12:20.388
============================== - Edit
03:12:20.388 📜 ReplicatedStorage.Items.Laser Gun.LaserScript - Edit
03:12:20.389 ==============================
- Edit
03:12:20.389 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: LaserScript, time of decompilation: Tue Jun 24 14:16:11 2025 ]]
local _ = game:GetService("StarterPlayer");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("ServerScriptService");
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v4 = require(l_Packages_0.Net);
local l_Parent_0 = script.Parent;
local _ = l_Parent_0.Parent.Parent;
l_Parent_0.Activated:Connect(function() --[[ Line: 11 ]]
-- upvalues: v4 (copy), l_Parent_0 (copy)
local l_Mouse_0 = game.Players.LocalPlayer:GetMouse();
v4:RemoteEvent("LaserGun/ShotPlayer"):FireServer(l_Mouse_0.Hit, l_Parent_0.Handle);
end); - Edit
03:12:20.389
- Edit
03:12:20.389
============================== - Edit
03:12:20.389 📜 ReplicatedStorage.Items.Grapple Hook.HookController - Edit
03:12:20.389 ==============================
- Edit
03:12:20.389 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local Debounce = require(Packages.Debounce)
Net:RemoteEvent("Begin/Hook").OnServerEvent:Connect(function(player, magnitude)
local character = player.Character
if not character then return end
local tool = character:FindFirstChildWhichIsA("Tool")
if not tool or tool.Name ~= "Grapple Hook" then return end
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if not humanoidRootPart then return end
if Debounce(("ItemUse/GrappleHook/%*"):format(player.Name), 3) then return end
if magnitude < 0.08333333333333333 or magnitude > 0.8333333333333334 then return end
local bodyVelocity = Instance.new("BodyVelocity")
bodyVelocity.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
bodyVelocity.Velocity = (humanoidRootPart.Position - tool.Handle.Position).Unit * 100
bodyVelocity.P = 2000
bodyVelocity.Parent = humanoidRootPart
task.delay(magnitude, function()
bodyVelocity:Destroy()
end)
end)
local tool = script.Parent
local Players = game:GetService("Players")
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end) - Edit
03:12:20.389
- Edit
03:12:20.389
============================== - Edit
03:12:20.389 📜 ReplicatedStorage.Items.Grapple Hook.HookScript - Edit
03:12:20.389 ==============================
- Edit
03:12:20.389 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: HookScript, time of decompilation: Tue Jun 24 14:16:11 2025 ]]
local _ = game:GetService("StarterPlayer");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("ServerScriptService");
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v4 = require(l_Packages_0.Net);
local v5 = require(l_Packages_0.Debounce);
local l_Parent_0 = script.Parent;
local l_Handle_0 = l_Parent_0.Handle;
local l_Beam_0 = l_Handle_0:WaitForChild("Beam");
local _ = l_Handle_0.RopeAttachment;
local l_Parent_1 = l_Parent_0.Parent.Parent;
local l_Hit_0 = script.Hit;
local l_Fire_0 = script.Fire;
local function _(v13) --[[ Line: 23 ]] --[[ Name: PlayerChecker ]]
if v13.Parent:FindFirstChild("Humanoid") then
return true;
elseif v13.Parent.Parent:FindFirstChild("Humanoid") then
return true;
else
return false;
end;
end;
l_Parent_0.Activated:Connect(function() --[[ Line: 33 ]]
-- upvalues: l_Parent_1 (copy), v5 (copy), l_Fire_0 (copy), v4 (copy), l_Beam_0 (copy), l_Hit_0 (copy)
if l_Parent_1:GetAttribute("Stealing") then
return;
else
local l_l_Parent_1_Mouse_0 = l_Parent_1:GetMouse();
local l_Hit_1 = l_l_Parent_1_Mouse_0.Hit;
local l_Target_0 = l_l_Parent_1_Mouse_0.Target;
if not l_Target_0 or l_Target_0.Parent:FindFirstChild("Humanoid") and true or l_Target_0.Parent.Parent:FindFirstChild("Humanoid") and true or false then
return;
else
local l_Position_0 = l_Hit_1.Position;
local l_Character_0 = l_Parent_1.Character;
if not l_Character_0 then
return;
else
local l_l_Character_0_FirstChildWhichIsA_0 = l_Character_0:FindFirstChildWhichIsA("Tool", true);
if not l_l_Character_0_FirstChildWhichIsA_0 then
return;
elseif l_l_Character_0_FirstChildWhichIsA_0.Name ~= "Grapple Hook" then
return;
else
local l_HumanoidRootPart_0 = l_Character_0:FindFirstChild("HumanoidRootPart");
if not l_HumanoidRootPart_0 then
return;
else
local l_Unit_0 = (l_Position_0 - l_HumanoidRootPart_0.Position).Unit;
local l_Magnitude_0 = (l_Position_0 - l_HumanoidRootPart_0.Position).Magnitude;
if l_Magnitude_0 >= 10 and l_Magnitude_0 <= 100 then
if v5(("ItemUse/GrappleHook/%*"):format(l_Parent_1.Name), 3) then
return;
else
l_Fire_0:Play();
v4:RemoteEvent("Begin/Hook"):FireServer(l_Magnitude_0 / 120);
local l_Part_0 = Instance.new("Part");
l_Part_0.Anchored = true;
l_Part_0.CanCollide = false;
l_Part_0.Transparency = 1;
l_Part_0.Position = l_Position_0;
l_Part_0.Size = Vector3.new(0.10000000149011612, 0.10000000149011612, 0.10000000149011612, 0);
l_Part_0.Parent = workspace;
local l_Attachment_0 = Instance.new("Attachment");
l_Attachment_0.Position = Vector3.new(0, 0, 0, 0);
l_Attachment_0.Parent = l_Part_0;
l_Beam_0.Attachment0 = l_Attachment_0;
local l_BodyVelocity_0 = Instance.new("BodyVelocity");
l_BodyVelocity_0.MaxForce = Vector3.new(1e999, 1e999, 1e999, 0);
l_BodyVelocity_0.Velocity = l_Unit_0 * 100;
l_BodyVelocity_0.P = 2000;
l_BodyVelocity_0.Parent = l_HumanoidRootPart_0;
l_Hit_0:Play();
task.delay(l_Magnitude_0 / 120, function() --[[ Line: 97 ]]
-- upvalues: l_BodyVelocity_0 (copy), l_Attachment_0 (copy), l_Part_0 (copy), l_Beam_0 (ref)
l_BodyVelocity_0:Destroy();
l_Attachment_0:Destroy();
l_Part_0:Destroy();
l_Beam_0.Attachment0 = nil;
end);
end;
end;
return;
end;
end;
end;
end;
end;
end); - Edit
03:12:20.389
- Edit
03:12:20.389
============================== - Edit
03:12:20.389 📜 ReplicatedStorage.Items.Trap.TrapScript - Edit
03:12:20.389 ==============================
- Edit
03:12:20.389 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: TrapScript, time of decompilation: Tue Jun 24 14:16:11 2025 ]]
local _ = game:GetService("StarterPlayer");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("ServerScriptService");
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v4 = require(l_Packages_0.Net);
local v5 = require(l_Packages_0.Debounce);
local l_Parent_0 = script.Parent;
local l_Parent_1 = l_Parent_0.Parent.Parent;
l_Parent_0.Activated:Connect(function() --[[ Line: 14 ]]
-- upvalues: v5 (copy), l_Parent_1 (copy), v4 (copy)
if v5(("ItemUse/PlaceTrapClient/%*"):format(l_Parent_1.Name), 2) then
return;
else
v4:RemoteEvent("Trap/Place"):FireServer();
return;
end;
end); - Edit
03:12:20.389
- Edit
03:12:20.389
============================== - Edit
03:12:20.390 📜 ReplicatedStorage.Items.Bloodmoon Hammer.BloodController - Edit
03:12:20.390 ==============================
- Edit
03:12:20.390 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local tool = script.Parent
local cooldowns = {}
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://75342767204598"
local animationTrack
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5,5,5)
local cframe = root.CFrame * CFrame.new(0,0,-3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local parts = workspace:FindPartsInRegion3(region, character, 10)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local function applySlap(player: Player, target, direction)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
CombatController:FireClient(targetPlayer, 1200, direction)
RagdollModule.TimedRagdoll(target, 4)
end
tool.Activated:Connect(function()
local char = tool.Parent
local player = game:GetService("Players"):GetPlayerFromCharacter(char)
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < 1 then return end
cooldowns[player.UserId] = os.clock()
local humanoid = char:FindFirstChild("Humanoid")
if humanoid then
animationTrack = humanoid:LoadAnimation(animation)
animationTrack:Play()
end
local dir = char.HumanoidRootPart.CFrame.LookVector
for target in pairs(getTargets(char)) do
applySlap(player, target, dir)
end
end)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end) - Edit
03:12:20.390
- Edit
03:12:20.390
============================== - Edit
03:12:20.390 📜 ReplicatedStorage.Items.Ban Hammer.BanController - Edit
03:12:20.390 ==============================
- Edit
03:12:20.390 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local tool = script.Parent
local cooldowns = {}
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://81553944270096"
local animationTrack
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5,5,5)
local cframe = root.CFrame * CFrame.new(0,0,-3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local parts = workspace:FindPartsInRegion3(region, character, 10)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local function applySlap(player: Player, target, direction)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
CombatController:FireClient(targetPlayer, 1200, direction)
RagdollModule.TimedRagdoll(target, 4)
end
tool.Activated:Connect(function()
local char = tool.Parent
local player = game:GetService("Players"):GetPlayerFromCharacter(char)
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < 1 then return end
cooldowns[player.UserId] = os.clock()
local humanoid = char:FindFirstChild("Humanoid")
if humanoid then
animationTrack = humanoid:LoadAnimation(animation)
animationTrack:Play()
end
local dir = char.HumanoidRootPart.CFrame.LookVector
for target in pairs(getTargets(char)) do
applySlap(player, target, dir)
end
end)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end) - Edit
03:12:20.390
- Edit
03:12:20.390
============================== - Edit
03:12:20.390 📜 ReplicatedStorage.Items.Quantum Cloner.QuantumClonerScript - Edit
03:12:20.390 ==============================
- Edit
03:12:20.390 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: QuantumClonerScript, time of decompilation: Sat Jul 12 14:22:31 2025 ]]
local l_Players_0 = game:GetService("Players");
local l_RunService_0 = game:GetService("RunService");
local _ = game:GetService("StarterPlayer");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("ServerScriptService");
local l_QuantumCloner_0 = l_Players_0.LocalPlayer.PlayerGui:WaitForChild("ToolsFrames").QuantumCloner;
local l_Controllers_0 = l_ReplicatedStorage_0:WaitForChild("Controllers");
local _ = require(l_Controllers_0.CharacterController);
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v9 = require(l_Packages_0.Net);
local v10 = require(l_Packages_0.Debounce);
local l_Parent_0 = script.Parent;
local l_Parent_1 = l_Parent_0.Parent.Parent;
local v13 = nil;
l_Parent_0.Activated:Connect(function() --[[ Line: 26 ]]
-- upvalues: v9 (copy)
local _ = game.Players.LocalPlayer:GetMouse();
v9:RemoteEvent("UseItem"):FireServer();
end);
l_Parent_0.Equipped:Connect(function() --[[ Line: 32 ]]
-- upvalues: v13 (ref), l_RunService_0 (copy), l_Parent_1 (copy), l_QuantumCloner_0 (copy)
v13 = l_RunService_0.Heartbeat:Connect(function() --[[ Line: 33 ]]
-- upvalues: l_Parent_1 (ref), l_QuantumCloner_0 (ref)
if workspace:FindFirstChild((("%*_Clone"):format(l_Parent_1.UserId))) then
l_QuantumCloner_0.Visible = true;
end;
end);
end);
l_Parent_0.Unequipped:Connect(function() --[[ Line: 41 ]]
-- upvalues: v13 (ref), l_QuantumCloner_0 (copy)
if v13 then
v13:Disconnect();
end;
l_QuantumCloner_0.Visible = false;
end);
l_Parent_1.CharacterAdded:Connect(function() --[[ Line: 48 ]]
-- upvalues: l_QuantumCloner_0 (copy), v13 (ref)
l_QuantumCloner_0.Visible = false;
if v13 then
v13:Disconnect();
end;
end);
l_QuantumCloner_0.TeleportToClone.MouseButton1Up:Connect(function() --[[ Line: 55 ]]
-- upvalues: v10 (copy), l_Parent_1 (copy), v9 (copy)
if v10(("ItemUse/QuantumClonerTeleport/%*"):format(l_Parent_1.Name), 5) then
return;
else
v9:RemoteEvent("QuantumCloner/OnTeleport"):FireServer();
return;
end;
end); - Edit
03:12:20.390
- Edit
03:12:20.390
============================== - Edit
03:12:20.390 📜 ReplicatedStorage.Items.Quantum Cloner.QuantumClonerController - Edit
03:12:20.390 ==============================
- Edit
03:12:20.390 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local Debounce = require(Packages.Debounce)
local function CloneCharacter(player)
if not player.Character then
warn("No character found for player: " .. player.Name)
return
end
local equippedTool = player.Character:FindFirstChildOfClass("Tool")
if not equippedTool or equippedTool.Name ~= "Quantum Cloner" then
warn("Player " .. player.Name .. " does not have Quantum Cloner equipped")
return
end
player.Character.Archivable = true
local existingClone = workspace:FindFirstChild(player.UserId .. "_Clone")
if existingClone then
existingClone:Destroy()
end
local character = workspace:FindFirstChild(player.Name)
if not character then
return
end
if not character.Parent then
return
end
local clone = character:Clone()
if not clone then
return
end
clone.Name = player.UserId .. "_Clone"
for _, descendant in pairs(clone:GetDescendants()) do
if descendant:IsA("Script") or descendant:IsA("LocalScript") then
descendant:Destroy()
end
end
local humanoid = clone:FindFirstChildOfClass("Humanoid")
if humanoid then
humanoid.WalkSpeed = 0
humanoid.JumpHeight = 0
humanoid.Health = 1
humanoid.MaxHealth = 1
else
warn("No humanoid found in clone for player: " .. player.Name)
end
clone.Parent = workspace
end
local function TeleportToClone(player)
if not player.Character then
return
end
local equippedTool = player.Character:FindFirstChildOfClass("Tool")
if not equippedTool or equippedTool.Name ~= "Quantum Cloner" then
warn("Player " .. player.Name .. " does not have Quantum Cloner equipped for teleport")
return
end
local clone = workspace:FindFirstChild(player.UserId .. "_Clone")
if not clone or not clone:FindFirstChild("HumanoidRootPart") or not clone:FindFirstChildOfClass("Humanoid") then
return
end
local humanoidRootPart = player.Character:FindFirstChild("HumanoidRootPart")
if humanoidRootPart then
humanoidRootPart.CFrame = clone.HumanoidRootPart.CFrame
clone:Destroy()
else
end
end
Net:RemoteEvent("UseItem").OnServerEvent:Connect(function(player)
CloneCharacter(player)
end)
Net:RemoteEvent("QuantumCloner/OnTeleport").OnServerEvent:Connect(function(player)
TeleportToClone(player)
end)
Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function()
local clone = workspace:FindFirstChild(player.UserId .. "_Clone")
if clone then
clone:Destroy()
end
end)
end)
Players.PlayerRemoving:Connect(function(player)
local clone = workspace:FindFirstChild(player.UserId .. "_Clone")
if clone then
clone:Destroy()
end
end)
local tool = script.Parent
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end) - Edit
03:12:20.390
- Edit
03:12:20.391
============================== - Edit
03:12:20.391 📜 ReplicatedStorage.Items.Web Slinger.WebSlingerController - Edit
03:12:20.391 ==============================
- Edit
03:12:20.391 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local RemoteEvent = Net:RemoteEvent("WebSlinger/ShotWeb")
RemoteEvent.OnServerEvent:Connect(function(player, mouseHit, handle)
local character = player.Character
if not character or not handle then return end
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if not humanoidRootPart then return end
local distance = (humanoidRootPart.Position - mouseHit.Position).Magnitude
if distance > 50 then return end
local ray = Ray.new(humanoidRootPart.Position, (mouseHit.Position - humanoidRootPart.Position).Unit * distance)
local hitPart, hitPosition = workspace:FindPartOnRayWithIgnoreList(ray, {character})
if hitPart and hitPart.Parent and Players:GetPlayerFromCharacter(hitPart.Parent) then
local hitPlayer = Players:GetPlayerFromCharacter(hitPart.Parent)
local hitCharacter = hitPlayer.Character
local hitHumanoidRootPart = hitCharacter and hitCharacter:FindFirstChild("HumanoidRootPart")
local hitHumanoid = hitCharacter and hitCharacter:FindFirstChild("Humanoid")
if hitHumanoidRootPart and hitHumanoid then
local rope = Instance.new("RopeConstraint")
rope.Name = "WebRope"
rope.Attachment0 = Instance.new("Attachment", humanoidRootPart)
rope.Attachment1 = Instance.new("Attachment", hitHumanoidRootPart)
rope.Length = distance
rope.Visible = true
rope.Thickness = 0.1
rope.Color = BrickColor.new("White")
rope.Parent = workspace
local bodyVelocity = Instance.new("BodyVelocity")
bodyVelocity.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
bodyVelocity.Velocity = (humanoidRootPart.Position - hitHumanoidRootPart.Position).Unit * 20
bodyVelocity.Parent = hitHumanoidRootPart
hitHumanoid.Sit = true
hitHumanoid.PlatformStand = true
game:GetService("Debris"):AddItem(rope, 5)
game:GetService("Debris"):AddItem(bodyVelocity, 0.5)
spawn(function()
wait(5)
if hitHumanoid then
hitHumanoid.PlatformStand = false
hitHumanoid.Sit = false
end
end)
end
end
local newCFrame = CFrame.new(mouseHit.Position, humanoidRootPart.Position)
RemoteEvent:FireClient(player, newCFrame)
end)
local tool = script.Parent
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end) - Edit
03:12:20.391
- Edit
03:12:20.391
============================== - Edit
03:12:20.391 📜 ReplicatedStorage.Items.Web Slinger.WebSlingerScript - Edit
03:12:20.391 ==============================
- Edit
03:12:20.391 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: WebSlingerScript, time of decompilation: Tue Jun 24 14:16:12 2025 ]]
local _ = game:GetService("StarterPlayer");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("ServerScriptService");
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v4 = require(l_Packages_0.Net);
local l_Parent_0 = script.Parent;
local _ = l_Parent_0.Parent.Parent;
l_Parent_0.Activated:Connect(function() --[[ Line: 11 ]]
-- upvalues: v4 (copy), l_Parent_0 (copy)
local l_Mouse_0 = game.Players.LocalPlayer:GetMouse();
v4:RemoteEvent("WebSlinger/ShotWeb"):FireServer(l_Mouse_0.Hit, l_Parent_0.Handle);
end); - Edit
03:12:20.391
- Edit
03:12:20.391
============================== - Edit
03:12:20.391 📜 ReplicatedStorage.Items.Rainbow Hammer.RainbowController - Edit
03:12:20.391 ==============================
- Edit
03:12:20.391 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local tool = script.Parent
local cooldowns = {}
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://75342767204598"
local animationTrack
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5,5,5)
local cframe = root.CFrame * CFrame.new(0,0,-3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local parts = workspace:FindPartsInRegion3(region, character, 10)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local function applySlap(player: Player, target, direction)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
h:TakeDamage(0)
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
CombatController:FireClient(targetPlayer, 900, direction)
RagdollModule.TimedRagdoll(target, 4)
end
tool.Activated:Connect(function()
local char = tool.Parent
local player = game:GetService("Players"):GetPlayerFromCharacter(char)
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < 1 then return end
cooldowns[player.UserId] = os.clock()
local humanoid = char:FindFirstChild("Humanoid")
if humanoid then
animationTrack = humanoid:LoadAnimation(animation)
animationTrack:Play()
end
local dir = char.HumanoidRootPart.CFrame.LookVector
for target in pairs(getTargets(char)) do
applySlap(player, target, dir)
end
end)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end) - Edit
03:12:20.391
- Edit
03:12:20.391
============================== - Edit
03:12:20.391 📜 ReplicatedStorage.Items.Gummy Stick.BloodController - Edit
03:12:20.391 ==============================
- Edit
03:12:20.392 local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local tool = script.Parent
local cooldowns = {}
local attackAnimation = Instance.new("Animation")
attackAnimation.AnimationId = "rbxassetid://123619834948143"
local attackAnimationTrack
local idleAnimation = Instance.new("Animation")
idleAnimation.AnimationId = "rbxassetid://114648214746202"
local idleAnimationTrack
local humanoid
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5, 5, 5)
local cframe = root.CFrame * CFrame.new(0, 0, -3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local parts = workspace:FindPartsInRegion3(region, character, 10)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local function applyGummyTransform(player, target)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
if player:GetAttribute("GummyTransform") then return end
local gummyModel = ServerStorage:FindFirstChild("Rainbow Gummy Bears")
if not gummyModel then return end
local gummyMeshes = gummyModel:GetChildren()
if #gummyMeshes == 0 then return end
local randomGummy = gummyMeshes[math.random(1, #gummyMeshes)]:Clone()
local sphere = Instance.new("Part")
sphere.Shape = Enum.PartType.Ball
sphere.Size = Vector3.new(5, 5, 5)
sphere.Massless = false
sphere.CanCollide = true
sphere.Transparency = 1
sphere.Position = root.Position
sphere.Material = Enum.Material.SmoothPlastic
sphere.Friction = 0.4
sphere.Parent = workspace
local gummyPrimaryPart = randomGummy:FindFirstChildWhichIsA("BasePart") or randomGummy
gummyPrimaryPart.CFrame = root.CFrame
randomGummy.Parent = target
local weld = Instance.new("WeldConstraint")
weld.Part0 = sphere
weld.Part1 = gummyPrimaryPart
weld.Parent = sphere
local originalParts = {}
for _, part in pairs(target:GetDescendants()) do
if part:IsA("BasePart") then
originalParts[part] = { Transparency = part.Transparency, CanCollide = part.CanCollide }
part.CanCollide = false
end
end
for _, part in pairs(randomGummy:GetDescendants()) do
if part:IsA("BasePart") then
part.Anchored = false
part.CanCollide = (part == gummyPrimaryPart)
end
end
root.Anchored = true
task.wait()
root.Anchored = false
root.CFrame = sphere.CFrame
local weld2 = Instance.new("WeldConstraint")
weld2.Part0 = root
weld2.Part1 = sphere
weld2.Parent = sphere
player:SetAttribute("GummyTransform", true)
h.WalkSpeed = 0
h.JumpPower = 0
h.PlatformStand = true
local direction = (root.CFrame.LookVector + Vector3.new(0, 0.5, 0)).Unit
local bodyVelocity = Instance.new("BodyVelocity")
bodyVelocity.Velocity = direction * 20
bodyVelocity.MaxForce = Vector3.new(math.huge, 5000, math.huge)
bodyVelocity.Parent = sphere
local bodyAngularVelocity = Instance.new("BodyAngularVelocity")
bodyAngularVelocity.AngularVelocity = Vector3.new(0, 0, 3)
bodyAngularVelocity.MaxTorque = Vector3.new(0, 0, 3000)
bodyAngularVelocity.Parent = sphere
task.delay(3, function()
bodyVelocity:Destroy()
bodyAngularVelocity:Destroy()
end)
task.delay(6, function()
sphere:Destroy()
randomGummy:Destroy()
for part, props in pairs(originalParts) do
if part.Parent then
part.Transparency = props.Transparency
part.CanCollide = props.CanCollide
end
end
player:SetAttribute("GummyTransform", nil)
if h then
h.WalkSpeed = 16
h.JumpPower = 50
h.PlatformStand = false
end
end)
end
tool.Equipped:Connect(function()
local char = tool.Parent
humanoid = char:FindFirstChild("Humanoid")
if humanoid then
idleAnimationTrack = humanoid:LoadAnimation(idleAnimation)
idleAnimationTrack:Play()
end
local player = Players:GetPlayerFromCharacter(char)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end)
tool.Unequipped:Connect(function()
if idleAnimationTrack then
idleAnimationTrack:Stop()
idleAnimationTrack = nil
end
if attackAnimationTrack then
attackAnimationTrack:Stop()
attackAnimationTrack = nil
end
humanoid = nil
end)
tool.Activated:Connect(function()
local char = tool.Parent
local player = Players:GetPlayerFromCharacter(char)
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < 0.7 then return end
cooldowns[player.UserId] = os.clock()
if idleAnimationTrack then
idleAnimationTrack:Stop()
end
if humanoid then
attackAnimationTrack = humanoid:LoadAnimation(attackAnimation)
attackAnimationTrack:Play()
attackAnimationTrack.Stopped:Connect(function()
if humanoid and idleAnimationTrack then
idleAnimationTrack:Play()
end
end)
end
for target in pairs(getTargets(char)) do
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
applyGummyTransform(player, target)
end
end
end) - Edit
03:12:20.392
- Edit
03:12:20.392
============================== - Edit
03:12:20.392 📜 ReplicatedStorage.Items.Body Swap Potion.BodySwapController - Edit
03:12:20.392 ==============================
- Edit
03:12:20.392 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local function swapBodies(player, targetPlayer)
if not player or not targetPlayer then return end
local char1 = player.Character
local char2 = targetPlayer.Character
if not char1 or not char2 then return end
local humanoid1 = char1:FindFirstChildOfClass("Humanoid")
local humanoid2 = char2:FindFirstChildOfClass("Humanoid")
if not humanoid1 or not humanoid2 then return end
local root1 = char1:FindFirstChild("HumanoidRootPart")
local root2 = char2:FindFirstChild("HumanoidRootPart")
if not root1 or not root2 then return end
local pos1 = root1.Position
local pos2 = root2.Position
root1.Position = pos2
root2.Position = pos1
end
Net:RemoteEvent("BodySwap/Fire").OnServerEvent:Connect(function(player, targetPlayer)
if typeof(targetPlayer) == "Instance" and targetPlayer:IsA("Player") then
swapBodies(player, targetPlayer)
end
end)
local tool = script.Parent
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end) - Edit
03:12:20.392
- Edit
03:12:20.392
============================== - Edit
03:12:20.392 📜 ReplicatedStorage.Items.Body Swap Potion.BodySwapScript - Edit
03:12:20.392 ==============================
- Edit
03:12:20.392 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: BodySwapScript, time of decompilation: Tue Jun 24 14:16:14 2025 ]]
local l_Players_0 = game:GetService("Players");
local l_RunService_0 = game:GetService("RunService");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = l_ReplicatedStorage_0:WaitForChild("Models").ToolsExtras;
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v5 = require(l_Packages_0.Net);
local v6 = require(l_Packages_0.Debounce);
local l_Parent_0 = script.Parent;
local l_Parent_1 = l_Parent_0.Parent.Parent;
local l_Highlight_0 = Instance.new("Highlight");
l_Highlight_0.DepthMode = Enum.HighlightDepthMode.Occluded;
l_Highlight_0.FillColor = Color3.fromRGB(255, 0, 0);
l_Highlight_0.FillTransparency = 0.5;
l_Highlight_0.OutlineColor = Color3.fromRGB(155, 0, 0);
l_Highlight_0.OutlineTransparency = 0.8;
l_Highlight_0.Parent = workspace;
l_Highlight_0.Adornee = script;
local v10 = nil;
local function v20() --[[ Line: 30 ]] --[[ Name: GetNearestPlayer ]]
-- upvalues: l_Parent_1 (copy), l_Players_0 (copy)
local l_Character_0 = l_Parent_1.Character;
if not l_Character_0 then
return;
else
local l_HumanoidRootPart_0 = l_Character_0:FindFirstChild("HumanoidRootPart");
if not l_HumanoidRootPart_0 then
return;
else
local v13 = nil;
local v14 = 1e999;
for _, v16 in l_Players_0:GetPlayers() do
if v16 ~= l_Parent_1 then
local l_Character_1 = v16.Character;
local v18 = l_Character_1 and l_Character_1:FindFirstChild("HumanoidRootPart");
if v18 then
local l_Magnitude_0 = (l_HumanoidRootPart_0.Position - v18.Position).Magnitude;
if l_Magnitude_0 <= 50 and l_Magnitude_0 < v14 then
v14 = l_Magnitude_0;
v13 = l_Character_1;
end;
end;
end;
end;
return v13, l_Players_0:GetPlayerFromCharacter(v13);
end;
end;
end;
l_Parent_0.Activated:Connect(function() --[[ Line: 60 ]]
-- upvalues: v6 (copy), l_Parent_1 (copy), v5 (copy), v10 (ref)
if v6(("ItemUse/BodySwapFire/%*"):format(l_Parent_1.Name), 30) then
return;
else
v5:RemoteEvent("BodySwap/Fire"):FireServer(v10);
return;
end;
end);
l_Parent_0.Equipped:Connect(function() --[[ Line: 67 ]]
-- upvalues: l_RunService_0 (copy), v20 (copy), v10 (ref), l_Highlight_0 (copy)
l_RunService_0:BindToRenderStep("BodySwap", Enum.RenderPriority.Character.Value + 1, function() --[[ Line: 68 ]]
-- upvalues: v20 (ref), v10 (ref), l_Highlight_0 (ref)
local v21, v22 = v20();
if v21 and v21 ~= v10 then
l_Highlight_0.Adornee = v21;
v10 = v22;
return;
else
l_Highlight_0.Adornee = script;
v10 = nil;
return;
end;
end);
end);
l_Parent_0.Unequipped:Connect(function() --[[ Line: 80 ]]
-- upvalues: l_RunService_0 (copy), l_Highlight_0 (copy), v10 (ref)
l_RunService_0:UnbindFromRenderStep("BodySwap");
l_Highlight_0.Adornee = script;
v10 = nil;
end); - Edit
03:12:20.392
- Edit
03:12:20.392
============================== - Edit
03:12:20.392 📜 ReplicatedStorage.Items.Laser Cape.LaserCapeController - Edit
03:12:20.392 ==============================
- Edit
03:12:20.392 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local Players = game:GetService("Players")
local Debris = game:GetService("Debris")
local RagdollModule = require(Packages.Ragdoll)
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local function FindCharacterAncestor(Parent)
if Parent and Parent ~= workspace then
local humanoid = Parent:FindFirstChild("Humanoid")
if humanoid then
return Parent, humanoid
else
return FindCharacterAncestor(Parent.Parent)
end
end
return nil
end
local function CreateBeam(startPos, endPos)
local beam = Instance.new("Part")
beam.Name = "LaserBeam"
beam.BrickColor = BrickColor.new("Really red")
beam.Material = Enum.Material.Neon
beam.Anchored = true
beam.CanCollide = false
beam.Transparency = 0.2
local distance = (endPos - startPos).Magnitude
beam.Size = Vector3.new(0.2, 0.2, distance)
beam.CFrame = CFrame.new(startPos, endPos) * CFrame.new(0, 0, -distance / 2)
beam.Parent = workspace
Debris:AddItem(beam, 0.5)
return beam
end
local function TagHumanoid(humanoid, player)
local Creator_Tag = Instance.new("ObjectValue")
Creator_Tag.Name = "creator"
Creator_Tag.Value = player
Debris:AddItem(Creator_Tag, 2)
Creator_Tag.Parent = humanoid
end
Net:RemoteEvent("SuperCape/LaserEyes").OnServerEvent:Connect(function(player, hitCFrame, targetPart)
if not player.Character or not hitCFrame then return end
local tool = player.Character:FindFirstChildWhichIsA("Tool")
if not tool or tool.Name ~= "Laser Cape" or not tool.Enabled then return end
tool.Enabled = false
local head = player.Character:FindFirstChild("Head")
if not head then
tool.Enabled = true
return
end
local root = player.Character:FindFirstChild("HumanoidRootPart")
if not root then
tool.Enabled = true
return
end
local upperTorso = player.Character:FindFirstChild("UpperTorso")
local neck = upperTorso and upperTorso:FindFirstChild("Neck")
local targetPos = hitCFrame.Position
local targetCharacter, targetHumanoid = nil, nil
if targetPart then
targetCharacter, targetHumanoid = FindCharacterAncestor(targetPart)
if targetCharacter then
local targetHead = targetCharacter:FindFirstChild("Head")
if targetHead then
targetPos = targetHead.Position
end
end
end
local startPos = head.Position
local direction = (targetPos - startPos).Unit
local lookVector = root.CFrame.LookVector
local dot = lookVector:Dot(direction)
if dot < 0.3 then
direction = lookVector
end
local endPos = startPos + direction * 100
CreateBeam(startPos, endPos)
if targetCharacter and targetHumanoid and targetCharacter ~= player.Character then
local hasForceField = targetCharacter:FindFirstChildWhichIsA("ForceField") ~= nil
if not hasForceField then
TagHumanoid(targetHumanoid, player)
local root = targetCharacter:FindFirstChild("HumanoidRootPart") or targetCharacter:FindFirstChild("Torso")
if root then
end
local targetPlayer = Players:GetPlayerFromCharacter(targetCharacter)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
CombatController:FireClient(targetPlayer, 900, direction)
RagdollModule.TimedRagdoll(targetCharacter, 2)
end
end
tool.Enabled = true
end)
local tool = script.Parent
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end) - Edit
03:12:20.392
- Edit
03:12:20.392
============================== - Edit
03:12:20.393 📜 ReplicatedStorage.Items.Laser Cape.LaserCapeScript - Edit
03:12:20.393 ==============================
- Edit
03:12:20.393 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: LaserCapeScript, time of decompilation: Tue Jun 24 14:16:12 2025 ]]
local _ = game:GetService("StarterPlayer");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("ServerScriptService");
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v4 = require(l_Packages_0.Net);
local l_Parent_0 = script.Parent;
local _ = l_Parent_0.Parent.Parent;
l_Parent_0.Activated:Connect(function() --[[ Line: 11 ]]
-- upvalues: v4 (copy)
local l_Mouse_0 = game.Players.LocalPlayer:GetMouse();
local l_Target_0 = l_Mouse_0.Target;
v4:RemoteEvent("SuperCape/LaserEyes"):FireServer(l_Mouse_0.Hit, l_Target_0);
end); - Edit
03:12:20.393
- Edit
03:12:20.393
============================== - Edit
03:12:20.393 📜 ReplicatedStorage.Items.Rainbowrath Sword.RainbowrathController - Edit
03:12:20.393 ==============================
- Edit
03:12:20.393 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local tool = script.Parent
local cooldowns = {}
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://133672436374077"
local animationTrack
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5,5,5)
local cframe = root.CFrame * CFrame.new(0,0,-3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local parts = workspace:FindPartsInRegion3(region, character, 10)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local function applySlap(player: Player, target, direction)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
h:TakeDamage(0)
local force = 900 * 0.10
local upwardForce = Vector3.new(0, 10, 0)
local bv = Instance.new("BodyVelocity")
bv.Velocity = direction.Unit * force + upwardForce
bv.MaxForce = Vector3.new(1e5, 1e5, 1e5)
bv.Parent = root
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
game.Debris:AddItem(bv, 0.2)
RagdollModule.TimedRagdoll(target, 5)
end
tool.Activated:Connect(function()
local char = tool.Parent
local player = game:GetService("Players"):GetPlayerFromCharacter(char)
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < 2 then return end
cooldowns[player.UserId] = os.clock()
local humanoid = char:FindFirstChild("Humanoid")
if humanoid then
animationTrack = humanoid:LoadAnimation(animation)
animationTrack:Play()
end
local dir = char.HumanoidRootPart.CFrame.LookVector
local bv = Instance.new("BodyVelocity")
bv.Velocity = dir * 100
bv.MaxForce = Vector3.new(1e5, 1e5, 1e5)
bv.Parent = char.HumanoidRootPart
game.Debris:AddItem(bv, 0.2)
for target in pairs(getTargets(char)) do
applySlap(player, target, dir)
end
end)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end)
- Edit
03:12:20.393
- Edit
03:12:20.393
============================== - Edit
03:12:20.393 📜 ReplicatedStorage.Items.Paintball Gun.PaintballScript - Edit
03:12:20.393 ==============================
- Edit
03:12:20.393 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: PaintballScript, time of decompilation: Sat Jun 28 18:34:46 2025 ]]
local _ = game:GetService("StarterPlayer");
local l_CollectionService_0 = game:GetService("CollectionService");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("ServerScriptService");
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v5 = require(l_Packages_0.Net);
local l_Parent_0 = script.Parent;
local _ = l_Parent_0.Parent.Parent;
l_Parent_0.Activated:Connect(function() --[[ Line: 12 ]]
-- upvalues: l_CollectionService_0 (copy), v5 (copy), l_Parent_0 (copy)
local l_Mouse_0 = game.Players.LocalPlayer:GetMouse();
l_Mouse_0.TargetFilter = table.unpack(l_CollectionService_0:GetTagged("ExcludeFromRaycast"));
v5:RemoteEvent("Paintball/ShotPlayer"):FireServer(l_Mouse_0.Hit, l_Parent_0.Handle);
end); - Edit
03:12:20.393
- Edit
03:12:20.393
============================== - Edit
03:12:20.393 📜 ReplicatedStorage.Items.Paintball Gun.PaintballController - Edit
03:12:20.393 ==============================
- Edit
03:12:20.394 local Debris = game:GetService("Debris")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local CollectionService = game:GetService("CollectionService")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local Net = require(Packages.Net)
local Debounce = require(Packages.Debounce)
local RemoteEvent = Net:RemoteEvent("Paintball/ShotPlayer")
local Colors = {45, 119, 21, 24, 23, 105, 104}
local CooldownTime = 0.5
local Damage = 2
RemoteEvent.OnServerEvent:Connect(function(player, hit, handle)
if Debounce(player, CooldownTime) then return end
local character = player.Character
if not character then return end
local humanoid = character:FindFirstChildOfClass("Humanoid")
if not humanoid then return end
local spawnPos = handle.Position + (hit.Position - handle.Position).Unit * 8
local direction = (hit.Position - handle.Position).Unit
local missile = Instance.new("Part")
missile.Position = spawnPos
missile.Size = Vector3.new(1, 1, 1)
missile.Velocity = direction * 150
missile.BrickColor = BrickColor.new(Colors[math.random(1, #Colors)])
missile.Shape = Enum.PartType.Ball
missile.BottomSurface = Enum.SurfaceType.Smooth
missile.TopSurface = Enum.SurfaceType.Smooth
missile.Name = "Paintball"
missile.Elasticity = 0.2
missile.Reflectance = 0
missile.Friction = 0.9
local angularVelocity = Instance.new("BodyAngularVelocity")
angularVelocity.MaxTorque = Vector3.new(1000, 1000, 1000)
angularVelocity.AngularVelocity = Vector3.new(math.random(-5, 5), math.random(-5, 5), math.random(-5, 5))
angularVelocity.Parent = missile
local drag = Instance.new("BodyForce")
drag.Force = -direction * missile:GetMass() * 5
drag.Parent = missile
local gravityForce = Instance.new("BodyForce")
gravityForce.Force = Vector3.new(0, missile:GetMass() * workspace.Gravity, 0)
gravityForce.Parent = missile
local creator = Instance.new("ObjectValue")
creator.Value = player
creator.Name = "creator"
creator.Parent = missile
missile.Parent = workspace
Debris:AddItem(missile, 8)
missile.Touched:Connect(function(hit)
local normal = (hit.Position - missile.Position).Unit
local faceDirection = normal.Magnitude > 0 and normal or missile.Velocity.Unit
local square = Instance.new("Part")
square.Shape = Enum.PartType.Block
square.Size = Vector3.new(1, 1, 0.1) / 2
square.BrickColor = missile.BrickColor
square.Position = missile.Position
square.CFrame = CFrame.fromMatrix(missile.Position, Vector3.new(1, 0, 0), Vector3.new(0, 1, 0), faceDirection)
square.Anchored = true
square.CanCollide = false
square.Parent = workspace
Debris:AddItem(square, 2)
local humanoid = hit.Parent:FindFirstChildOfClass("Humanoid")
if humanoid then
local hitPlayer = Players:GetPlayerFromCharacter(hit.Parent)
if hitPlayer then
RemoteEvent:FireClient(hitPlayer, "PaintballHitted", 1)
local creatorTag = missile:FindFirstChild("creator")
if creatorTag then
local newTag = creatorTag:Clone()
newTag.Parent = humanoid
Debris:AddItem(newTag, 2)
end
RagdollModule.TimedRagdoll(hit.Parent, 3)
end
end
missile:Destroy()
end)
end)
local tool = script.Parent
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end) - Edit
03:12:20.394
- Edit
03:12:20.394
============================== - Edit
03:12:20.394 📜 ReplicatedStorage.Items.Lollipop.Controller - Edit
03:12:20.394 ==============================
- Edit
03:12:20.394 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local tool = script.Parent
local cooldowns = {}
local attackAnimation = Instance.new("Animation")
attackAnimation.AnimationId = "rbxassetid://123619834948143"
local attackAnimationTrack
local idleAnimation = Instance.new("Animation")
idleAnimation.AnimationId = "rbxassetid://114648214746202"
local idleAnimationTrack
local slashSound = tool:WaitForChild("Slash")
local hitSound = tool:WaitForChild("Hit")
local humanoid
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5, 5, 5)
local cframe = root.CFrame * CFrame.new(0, 0, -3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local parts = workspace:FindPartsInRegion3(region, character, 10)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local function applySlap(player, target, direction)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
CombatController:FireClient(targetPlayer, 450, direction)
RagdollModule.TimedRagdoll(target, 1.5)
hitSound:Play()
end
tool.Equipped:Connect(function()
local char = tool.Parent
humanoid = char:FindFirstChild("Humanoid")
if humanoid then
idleAnimationTrack = humanoid:LoadAnimation(idleAnimation)
idleAnimationTrack:Play()
end
end)
tool.Unequipped:Connect(function()
if idleAnimationTrack then
idleAnimationTrack:Stop()
idleAnimationTrack = nil
end
if attackAnimationTrack then
attackAnimationTrack:Stop()
attackAnimationTrack = nil
end
humanoid = nil
end)
tool.Activated:Connect(function()
local char = tool.Parent
local player = Players:GetPlayerFromCharacter(char)
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < 0.5 then return end
cooldowns[player.UserId] = os.clock()
if idleAnimationTrack then
idleAnimationTrack:Stop()
end
if humanoid then
attackAnimationTrack = humanoid:LoadAnimation(attackAnimation)
attackAnimationTrack:Play()
slashSound:Play()
attackAnimationTrack.Stopped:Connect(function()
if humanoid and idleAnimationTrack then
idleAnimationTrack:Play()
end
end)
end
local dir = char.HumanoidRootPart.CFrame.LookVector
for target in pairs(getTargets(char)) do
applySlap(player, target, dir)
end
end)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end) - Edit
03:12:20.394
- Edit
03:12:20.394
============================== - Edit
03:12:20.394 📜 ReplicatedStorage.Items.Cake Trap.CakeTrapScript - Edit
03:12:20.394 ==============================
- Edit
03:12:20.394 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: TrapScript, time of decompilation: Sat Jul 5 18:09:35 2025 ]]
local _ = game:GetService("StarterPlayer");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("ServerScriptService");
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v4 = require(l_Packages_0.Net);
local v5 = require(l_Packages_0.Debounce);
local l_Parent_0 = script.Parent;
local l_Parent_1 = l_Parent_0.Parent.Parent;
l_Parent_0.Activated:Connect(function() --[[ Line: 14 ]]
-- upvalues: v5 (copy), l_Parent_1 (copy), v4 (copy)
if v5(("ItemUse/PlaceTrapClient/%*"):format(l_Parent_1.Name), 2) then
return;
else
v4:RemoteEvent("CakceTrap/Place"):FireServer();
return;
end;
end); - Edit
03:12:20.394
- Edit
03:12:20.394
============================== - Edit
03:12:20.394 📜 ReplicatedStorage.Items.Cake Trap.CakeTrapController - Edit
03:12:20.394 ==============================
- Edit
03:12:20.395 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [FilteringEnabled] Server Scripts are IMPOSSIBLE to save - Edit
03:12:20.395
- Edit
03:12:20.395
============================== - Edit
03:12:20.395 📜 ReplicatedStorage.Items.Candy Bomb.CandyBombController - Edit
03:12:20.395 ==============================
- Edit
03:12:20.395 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local UseItem = Net:RemoteEvent("CandyBomb/Throw")
UseItem.OnServerEvent:Connect(function(player)
local character = player.Character
if not character then return end
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if not humanoidRootPart then return end
for _, targetPlayer in Players:GetPlayers() do
if targetPlayer ~= player then
local targetCharacter = targetPlayer.Character
if targetCharacter then
local targetHumanoidRootPart = targetCharacter:FindFirstChild("HumanoidRootPart")
if targetHumanoidRootPart then
local distance = (humanoidRootPart.Position - targetHumanoidRootPart.Position).Magnitude
if distance <= 30 then
UseItem:FireClient(targetPlayer, "CandyEffect", 10)
end
end
end
end
end
end)
local tool = script.Parent
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end) - Edit
03:12:20.395
- Edit
03:12:20.395
============================== - Edit
03:12:20.395 📜 ReplicatedStorage.Items.Candy Bomb.CandyBombScript - Edit
03:12:20.395 ==============================
- Edit
03:12:20.395 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: DonutTeleportScript, time of decompilation: Sat Jul 5 18:09:38 2025 ]]
local _ = game:GetService("RunService");
local _ = game:GetService("TweenService");
local _ = game:GetService("StarterPlayer");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("ServerScriptService");
local _ = l_ReplicatedStorage_0:WaitForChild("Models").ToolsExtras;
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v7 = require(l_Packages_0.Net);
local _ = require(l_Packages_0.Debounce);
local l_Parent_0 = script.Parent;
local _ = l_Parent_0.Parent.Parent;
l_Parent_0.Activated:Connect(function() --[[ Line: 20 ]]
-- upvalues: v7 (copy)
v7:RemoteEvent("CandyBomb/Throw"):FireServer();
end); - Edit
03:12:20.395
- Edit
03:12:20.395
============================== - Edit
03:12:20.395 📜 ReplicatedStorage.Items.Confetti Cannon.ConfettirScript - Edit
03:12:20.395 ==============================
- Edit
03:12:20.395 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: ConfettirScript, time of decompilation: Sat Jul 5 18:09:38 2025 ]]
local l_Players_0 = game:GetService("Players");
local l_RunService_0 = game:GetService("RunService");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = l_ReplicatedStorage_0:WaitForChild("Models").ToolsExtras;
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v5 = require(l_Packages_0.Net);
local _ = require(l_Packages_0.Debounce);
local l_Parent_0 = script.Parent;
local l_Parent_1 = l_Parent_0.Parent.Parent;
local l_MainHighlight_0 = workspace:WaitForChild("MainHighlight");
local v10 = nil;
local function v20() --[[ Line: 23 ]] --[[ Name: GetNearestPlayer ]]
-- upvalues: l_Parent_1 (copy), l_Players_0 (copy)
local l_Character_0 = l_Parent_1.Character;
if not l_Character_0 then
return;
else
local l_HumanoidRootPart_0 = l_Character_0:FindFirstChild("HumanoidRootPart");
if not l_HumanoidRootPart_0 then
return;
else
local v13 = nil;
local v14 = 1e999;
for _, v16 in l_Players_0:GetPlayers() do
if v16 ~= l_Parent_1 then
local l_Character_1 = v16.Character;
local v18 = l_Character_1 and l_Character_1:FindFirstChild("HumanoidRootPart");
if v18 then
local l_Magnitude_0 = (l_HumanoidRootPart_0.Position - v18.Position).Magnitude;
if l_Magnitude_0 <= 30 and l_Magnitude_0 < v14 then
v14 = l_Magnitude_0;
v13 = l_Character_1;
end;
end;
end;
end;
return v13, l_Players_0:GetPlayerFromCharacter(v13);
end;
end;
end;
l_Parent_0.Activated:Connect(function() --[[ Line: 53 ]]
-- upvalues: v5 (copy), v10 (ref)
v5:RemoteEvent("UseItem"):FireServer(v10);
end);
l_Parent_0.Equipped:Connect(function() --[[ Line: 57 ]]
-- upvalues: l_RunService_0 (copy), l_MainHighlight_0 (copy), v10 (ref), l_Parent_0 (copy), v20 (copy)
l_RunService_0:UnbindFromRenderStep("Confetti");
l_MainHighlight_0.Adornee = script;
v10 = nil;
l_RunService_0:BindToRenderStep("Confetti", Enum.RenderPriority.Character.Value + 1, function() --[[ Line: 61 ]]
-- upvalues: l_Parent_0 (ref), l_MainHighlight_0 (ref), v10 (ref), v20 (ref)
if l_Parent_0:GetAttribute("CooldownTime") then
l_MainHighlight_0.Adornee = script;
v10 = nil;
return;
else
local v21, v22 = v20();
if v21 and v21 ~= v10 then
l_MainHighlight_0.Adornee = v21;
v10 = v22;
return;
else
l_MainHighlight_0.Adornee = script;
v10 = nil;
return;
end;
end;
end);
end);
l_Parent_0.Unequipped:Connect(function() --[[ Line: 78 ]]
-- upvalues: l_RunService_0 (copy), l_MainHighlight_0 (copy), v10 (ref)
l_RunService_0:UnbindFromRenderStep("Confetti");
l_MainHighlight_0.Adornee = script;
v10 = nil;
end); - Edit
03:12:20.396
- Edit
03:12:20.396
============================== - Edit
03:12:20.396 📜 ReplicatedStorage.Items.Confetti Cannon.ConfettiController - Edit
03:12:20.396 ==============================
- Edit
03:12:20.396 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [FilteringEnabled] Server Scripts are IMPOSSIBLE to save - Edit
03:12:20.396
- Edit
03:12:20.396
============================== - Edit
03:12:20.396 📜 ReplicatedStorage.Items.Candy Coils.ComboController - Edit
03:12:20.396 ==============================
- Edit
03:12:20.396 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [FilteringEnabled] Server Scripts are IMPOSSIBLE to save - Edit
03:12:20.396
- Edit
03:12:20.397
============================== - Edit
03:12:20.397 📜 ReplicatedStorage.Items.Candy Coils.ComboScript - Edit
03:12:20.397 ==============================
- Edit
03:12:20.397 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: ComboScript, time of decompilation: Sat Jul 5 18:09:34 2025 ]]
local l_Parent_0 = script.Parent;
l_Parent_0.Equipped:Connect(function() --[[ Line: 4 ]]
workspace.Gravity = 29.429999999999996;
end);
l_Parent_0.Unequipped:Connect(function() --[[ Line: 11 ]]
workspace.Gravity = 196.2;
end); - Edit
03:12:20.397
- Edit
03:12:20.397
============================== - Edit
03:12:20.397 📜 ReplicatedStorage.Items.Candy Launcher.CandyCanonScript - Edit
03:12:20.397 ==============================
- Edit
03:12:20.397 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: PaintballScript, time of decompilation: Sat Jul 5 18:09:37 2025 ]]
local _ = game:GetService("StarterPlayer");
local l_CollectionService_0 = game:GetService("CollectionService");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("ServerScriptService");
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v5 = require(l_Packages_0.Net);
local l_Parent_0 = script.Parent;
local _ = l_Parent_0.Parent.Parent;
l_Parent_0.Activated:Connect(function() --[[ Line: 12 ]]
-- upvalues: l_CollectionService_0 (copy), v5 (copy), l_Parent_0 (copy)
local l_Mouse_0 = game.Players.LocalPlayer:GetMouse();
l_Mouse_0.TargetFilter = table.unpack(l_CollectionService_0:GetTagged("ExcludeFromRaycast"));
v5:RemoteEvent("UseItem"):FireServer(l_Mouse_0.Hit, l_Parent_0.Handle);
end); - Edit
03:12:20.397
- Edit
03:12:20.397
============================== - Edit
03:12:20.397 📜 ReplicatedStorage.Items.Candy Launcher.CandyCanonController - Edit
03:12:20.397 ==============================
- Edit
03:12:20.397 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [FilteringEnabled] Server Scripts are IMPOSSIBLE to save - Edit
03:12:20.397
- Edit
03:12:20.398
============================== - Edit
03:12:20.398 📜 ReplicatedStorage.Items.All Seeing Sentry.AllSeeingSentryScript - Edit
03:12:20.398 ==============================
- Edit
03:12:20.398 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
local _ = game:GetService("StarterPlayer");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("ServerScriptService");
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v4 = require(l_Packages_0.Net);
local v5 = require(l_Packages_0.Debounce);
local l_Parent_0 = script.Parent;
local l_Parent_1 = l_Parent_0.Parent.Parent;
l_Parent_0.Activated:Connect(function() --[[ Line: 14 ]]
-- upvalues: v5 (copy), l_Parent_1 (copy), v4 (copy)
if v5(("ItemUse/PlaceSentryClient/%*"):format(l_Parent_1.Name), 5) then
return;
else
v4:RemoteEvent("Sentry/Place"):FireServer();
return;
end;
end); - Edit
03:12:20.398
- Edit
03:12:20.398
============================== - Edit
03:12:20.398 📜 ReplicatedStorage.Items.Sweet Scythe.SweetScytheController - Edit
03:12:20.398 ==============================
- Edit
03:12:20.398 local Debris = game:GetService("Debris")
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local TARGET_EFFECT = "Freeze"
local RANGE = 300
local SPAWN_OFFSETS = {
Vector3.new(5, 0, 0),
Vector3.new(-2.5, 0, 4.33),
Vector3.new(-2.5, 0, -4.33)
}
local SPAWN_COUNT = 3
local SPAWN_DELAY = 0.5
local function applyEffect(target, gingerbread)
local targetHumanoid = target:FindFirstChild("Humanoid")
local targetTorso = target:FindFirstChild("Torso")
if targetHumanoid and targetTorso then
local creator = gingerbread:FindFirstChild("creator")
local plr = Players:GetPlayerFromCharacter(target)
if plr and creator and plr == creator.Value then
return
end
for _, v in pairs(targetHumanoid:GetChildren()) do
if v.Name == "creator" then
v:Destroy()
end
end
local newCt = creator:Clone()
Debris:AddItem(newCt, 1)
newCt.Parent = targetHumanoid
if TARGET_EFFECT == "Freeze" then
targetTorso.Anchored = true
task.wait(5)
if targetTorso then
targetTorso.Anchored = false
end
elseif TARGET_EFFECT == "Burn" then
local fire = Instance.new("Fire")
fire.Parent = targetTorso
Debris:AddItem(fire, 5)
for i = 1, 5 do
if targetHumanoid and targetHumanoid.Health > 0 then
targetHumanoid:TakeDamage(2)
task.wait(1)
end
end
elseif TARGET_EFFECT == "Knockback" then
local bodyVelocity = Instance.new("BodyVelocity")
bodyVelocity.MaxForce = Vector3.new(math.huge, 0, math.huge)
bodyVelocity.Velocity = (targetTorso.Position - gingerbread.Torso.Position).Unit * 50
bodyVelocity.Parent = targetTorso
Debris:AddItem(bodyVelocity, 0.2)
end
end
end
local function setupGingerbreadCookie(clone, creatorPlayer)
local torso = clone:WaitForChild("Torso")
local head = clone:WaitForChild("Head")
local humanoid = clone:WaitForChild("Humanoid")
local creator = Instance.new("ObjectValue")
creator.Name = "creator"
creator.Value = creatorPlayer
creator.Parent = clone
clone.PrimaryPart = torso
clone.Parent = game.Workspace
local alive = true
local attacker = nil
torso.Touched:Connect(function(hit)
if hit and hit.Parent and hit.Parent.Name ~= clone.Name and alive then
applyEffect(hit.Parent, clone)
end
end)
humanoid:GetPropertyChangedSignal("Health"):Connect(function()
if humanoid.Health <= 0 then
alive = false
humanoid:Destroy()
local fire = Instance.new("Fire")
fire.Parent = torso
if head then
head:Destroy()
end
task.wait(4)
clone:Destroy()
elseif not attacker then
local creatorTag = humanoid:FindFirstChild("creator")
if creatorTag and creatorTag.Value then
local attackerPlayer = creatorTag.Value
local attackerChar = attackerPlayer.Character
if attackerChar then
attacker = attackerChar:FindFirstChild("Torso")
end
end
end
end)
task.spawn(function()
local nextMove = 0
while alive do
task.wait(0.1)
local currentTime = tick()
if currentTime > nextMove then
nextMove = currentTime + 0.5 + math.random()
if attacker then
local closest = RANGE
local target = nil
for _, v in ipairs(game.Workspace:GetChildren()) do
if v and v:IsA("Model") and v.Name ~= clone.Name then
local t = v:FindFirstChild("Torso")
local h = v:FindFirstChild("Humanoid")
if t and h and h.Health > 0 then
local plr = Players:GetPlayerFromCharacter(v)
if not plr or plr ~= creator.Value then
local mag = (t.Position - torso.Position).Magnitude
if mag < closest and t == attacker then
target = t
closest = mag
end
end
end
end
end
if target then
local point = target.Position + (Vector3.new(math.random() - 0.5, math.random() - 0.5, math.random() - 0.5) * 6)
humanoid:MoveTo(point)
if math.random() < 0.15 then
humanoid.Jump = true
end
end
else
local creatorChar = creatorPlayer.Character
if creatorChar and creatorChar:FindFirstChild("HumanoidRootPart") then
humanoid:MoveTo(creatorChar.HumanoidRootPart.Position)
if math.random() < 0.15 then
humanoid.Jump = true
end
end
end
end
end
end)
Debris:AddItem(clone, 10)
end
script.Parent.Activated:Connect(function()
local player = Players:GetPlayerFromCharacter(script.Parent.Parent)
local basePosition = script.Parent:IsA("Tool") and player.Character and player.Character.HumanoidRootPart.Position or script.Parent.Position
local gingerbreadModel = ServerStorage:FindFirstChild("Gingerbread Cookie")
if gingerbreadModel then
for i = 1, SPAWN_COUNT do
local spawnPos = basePosition + SPAWN_OFFSETS[i]
local clone = gingerbreadModel:Clone()
clone:MoveTo(spawnPos)
setupGingerbreadCookie(clone, player)
task.wait(SPAWN_DELAY)
end
end
end) - Edit
03:12:20.398
- Edit
03:12:20.398
============================== - Edit
03:12:20.398 📜 ReplicatedStorage.Items.Sweet Scythe.SweetScytheScript - Edit
03:12:20.398 ==============================
- Edit
03:12:20.399 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: SweetScytheScript, time of decompilation: Sat Jul 5 18:09:38 2025 ]]
local _ = game:GetService("StarterPlayer");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("ServerScriptService");
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local _ = require(l_Packages_0.Net);
local _ = require(l_Packages_0.Debounce);
local _ = script.Parent.Parent.Parent; - Edit
03:12:20.399
- Edit
03:12:20.399
============================== - Edit
03:12:20.399 📜 ReplicatedStorage.Items.Magnet.MagnetController - Edit
03:12:20.399 ==============================
- Edit
03:12:20.399 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local RemoteEvent = Net:RemoteEvent("UseItem")
local MAGNET_RANGE = 50
local ATTRACTION_FORCE = 50
local ATTRACTION_DURATION = 4
local function findNearestPlayer(sourcePlayer, sourcePosition)
local nearestPlayer = nil
local nearestDistance = math.huge
for _, player in pairs(Players:GetPlayers()) do
if player ~= sourcePlayer and player.Character then
local character = player.Character
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
local humanoid = character:FindFirstChild("Humanoid")
if humanoidRootPart and humanoid and humanoid.Health > 0 then
local hasForceField = false
for _, child in pairs(character:GetChildren()) do
if child:IsA("ForceField") then
hasForceField = true
break
end
end
if not hasForceField then
local distance = (humanoidRootPart.Position - sourcePosition).Magnitude
if distance <= MAGNET_RANGE and distance < nearestDistance then
nearestDistance = distance
nearestPlayer = player
end
end
end
end
end
return nearestPlayer, nearestDistance
end
local function createMagneticConnection(sourcePlayer, targetPlayer)
local sourceCharacter = sourcePlayer.Character
local targetCharacter = targetPlayer.Character
if not sourceCharacter or not targetCharacter then return end
local sourceRootPart = sourceCharacter:FindFirstChild("HumanoidRootPart")
local targetRootPart = targetCharacter:FindFirstChild("HumanoidRootPart")
local targetHumanoid = targetCharacter:FindFirstChild("Humanoid")
if not sourceRootPart or not targetRootPart or not targetHumanoid then return end
local attachment1 = Instance.new("Attachment")
attachment1.Parent = sourceRootPart
local attachment2 = Instance.new("Attachment")
attachment2.Parent = targetRootPart
local ropeConstraint = Instance.new("RopeConstraint")
ropeConstraint.Attachment0 = attachment1
ropeConstraint.Attachment1 = attachment2
ropeConstraint.Length = 20
ropeConstraint.Visible = false
ropeConstraint.Parent = sourceRootPart
local bodyVelocity = Instance.new("BodyVelocity")
bodyVelocity.MaxForce = Vector3.new(8000, 0, 8000)
bodyVelocity.Parent = targetRootPart
local connection
local cleanupPerformed = false
local magnetEffect
local function cleanup()
if cleanupPerformed then return end
cleanupPerformed = true
if connection then
connection:Disconnect()
connection = nil
end
if ropeConstraint and ropeConstraint.Parent then
ropeConstraint:Destroy()
end
if attachment1 and attachment1.Parent then
attachment1:Destroy()
end
if attachment2 and attachment2.Parent then
attachment2:Destroy()
end
if bodyVelocity and bodyVelocity.Parent then
bodyVelocity:Destroy()
end
if magnetEffect and magnetEffect.Parent then
magnetEffect:Destroy()
end
end
local sourcePlayerLeftConnection
local targetPlayerLeftConnection
sourcePlayerLeftConnection = Players.PlayerRemoving:Connect(function(player)
if player == sourcePlayer then
cleanup()
if sourcePlayerLeftConnection then
sourcePlayerLeftConnection:Disconnect()
end
if targetPlayerLeftConnection then
targetPlayerLeftConnection:Disconnect()
end
end
end)
targetPlayerLeftConnection = Players.PlayerRemoving:Connect(function(player)
if player == targetPlayer then
cleanup()
if sourcePlayerLeftConnection then
sourcePlayerLeftConnection:Disconnect()
end
if targetPlayerLeftConnection then
targetPlayerLeftConnection:Disconnect()
end
end
end)
connection = game:GetService("RunService").Heartbeat:Connect(function()
if not sourcePlayer.Parent or not targetPlayer.Parent or
not sourceCharacter.Parent or not targetCharacter.Parent or
not sourceRootPart.Parent or not targetRootPart.Parent or
not bodyVelocity.Parent then
cleanup()
if sourcePlayerLeftConnection then sourcePlayerLeftConnection:Disconnect() end
if targetPlayerLeftConnection then targetPlayerLeftConnection:Disconnect() end
return
end
if targetHumanoid.Health <= 0 then
cleanup()
if sourcePlayerLeftConnection then sourcePlayerLeftConnection:Disconnect() end
if targetPlayerLeftConnection then targetPlayerLeftConnection:Disconnect() end
return
end
local distance = (sourceRootPart.Position - targetRootPart.Position).Magnitude
local direction = (sourceRootPart.Position - targetRootPart.Position).Unit
local pullForce = 60
if distance < 10 then
pullForce = 35
elseif distance < 5 then
pullForce = 15
end
bodyVelocity.Velocity = direction * pullForce
end)
magnetEffect = Instance.new("SelectionBox")
magnetEffect.Adornee = targetCharacter
magnetEffect.Color3 = Color3.fromRGB(255, 0, 255)
magnetEffect.LineThickness = 0.2
magnetEffect.Transparency = 0.5
magnetEffect.Parent = targetCharacter
task.spawn(function()
task.wait(ATTRACTION_DURATION)
cleanup()
if sourcePlayerLeftConnection then sourcePlayerLeftConnection:Disconnect() end
if targetPlayerLeftConnection then targetPlayerLeftConnection:Disconnect() end
end)
end
RemoteEvent.OnServerEvent:Connect(function(player)
local character = player.Character
if not character then return end
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if not humanoidRootPart then return end
local tool = character:FindFirstChildWhichIsA("Tool")
if not tool or tool.Name ~= "Magnet" then return end
if not tool.Enabled then return end
tool.Enabled = false
local nearestPlayer, distance = findNearestPlayer(player, humanoidRootPart.Position)
if nearestPlayer then
createMagneticConnection(player, nearestPlayer)
end
task.spawn(function()
task.wait(3)
if tool and tool.Parent then
tool.Enabled = true
end
end)
end)
local tool = script.Parent
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end) - Edit
03:12:20.399
- Edit
03:12:20.399
============================== - Edit
03:12:20.399 📜 ReplicatedStorage.Items.Magnet.MagnetScript - Edit
03:12:20.399 ==============================
- Edit
03:12:20.400 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: MagnetScript, time of decompilation: Sat Jul 12 13:54:28 2025 ]]
local _ = game:GetService("StarterPlayer");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = game:GetService("ServerScriptService");
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v4 = require(l_Packages_0.Net);
local l_Parent_0 = script.Parent;
local _ = l_Parent_0.Parent.Parent;
l_Parent_0.Activated:Connect(function() --[[ Line: 11 ]]
-- upvalues: v4 (copy)
local _ = game.Players.LocalPlayer:GetMouse();
v4:RemoteEvent("UseItem"):FireServer();
end); - Edit
03:12:20.400
- Edit
03:12:20.400
============================== - Edit
03:12:20.400 📜 ReplicatedStorage.Items.Heart Balloon.HeartBalloonScript - Edit
03:12:20.400 ==============================
- Edit
03:12:20.400 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: HeartBalloonScript, time of decompilation: Sat Jul 12 13:54:32 2025 ]]
local l_LocalPlayer_0 = game:GetService("Players").LocalPlayer;
local l_Parent_0 = script.Parent;
l_Parent_0.Handle:GetPropertyChangedSignal("Transparency"):Connect(function() --[[ Line: 8 ]]
-- upvalues: l_LocalPlayer_0 (copy), l_Parent_0 (copy)
local v2 = l_LocalPlayer_0.Character or l_LocalPlayer_0.CharacterAdded:Wait();
if not l_Parent_0:IsDescendantOf(v2) then
workspace.Gravity = 196.2;
return;
elseif l_Parent_0.Handle.Transparency == 1 then
workspace.Gravity = 196.2;
return;
else
workspace.Gravity = 29.429999999999996;
return;
end;
end);
l_Parent_0.Equipped:Connect(function() --[[ Line: 22 ]]
-- upvalues: l_Parent_0 (copy)
if l_Parent_0.Handle.Transparency == 1 then
workspace.Gravity = 196.2;
return;
else
workspace.Gravity = 29.429999999999996;
return;
end;
end);
l_Parent_0.Unequipped:Connect(function() --[[ Line: 33 ]]
workspace.Gravity = 196.2;
end); - Edit
03:12:20.400
- Edit
03:12:20.400
============================== - Edit
03:12:20.400 📜 ReplicatedStorage.Items.Heart Balloon.HeartBalloonController - Edit
03:12:20.400 ==============================
- Edit
03:12:20.400 local tool = script.Parent
tool.Equipped:Connect(function()
tool.Handle.Transparency = 0
end)
tool.Unequipped:Connect(function()
tool.Handle.Transparency = 1
end) - Edit
03:12:20.400
- Edit
03:12:20.400
============================== - Edit
03:12:20.400 📜 ReplicatedStorage.Items.Lava Blaster.LavaGunScript - Edit
03:12:20.401 ==============================
- Edit
03:12:20.401 -- Thanks For Angelus Decompiles --> https://discord.gg/CYXme7yEG9
-- Decompiled with Velocity Script Decompiler
game:GetService("StarterPlayer")
local v_u_1 = game:GetService("ReplicatedStorage")
game:GetService("ServerScriptService")
local v2 = v_u_1:WaitForChild("Packages")
local v_u_3 = require(v2.Net)
local v4 = script.Parent
local _ = v4.Parent.Parent
v4.Activated:Connect(function()
-- upvalues: (copy) v_u_1, (copy) v_u_3
local _ = game.Players.LocalPlayer
local v5 = require(v_u_1.Packages.PlayerMouse)
v_u_3:RemoteEvent("UseItem"):FireServer(v5.Hit.Position, v5.Target)
end) - Edit
03:12:20.401
- Edit
03:12:20.401
============================== - Edit
03:12:20.401 📜 ReplicatedStorage.Items.Jelly Gun.CandyLauncherScript - Edit
03:12:20.401 ==============================
- Edit
03:12:20.401 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: CandyLauncherScript, time of decompilation: Sat Jul 5 18:09:38 2025 ]]
local _ = game:GetService("Players");
local _ = game:GetService("RunService");
local l_CollectionService_0 = game:GetService("CollectionService");
local l_ReplicatedStorage_0 = game:GetService("ReplicatedStorage");
local _ = l_ReplicatedStorage_0:WaitForChild("Models").ToolsExtras;
local l_Packages_0 = l_ReplicatedStorage_0:WaitForChild("Packages");
local v6 = require(l_Packages_0.Net);
local _ = require(l_Packages_0.Debounce);
local l_Parent_0 = script.Parent;
local l_Parent_1 = l_Parent_0.Parent.Parent;
l_Parent_0.Activated:Connect(function() --[[ Line: 19 ]]
-- upvalues: l_Parent_1 (copy), l_CollectionService_0 (copy), v6 (copy), l_Parent_0 (copy)
local l_l_Parent_1_Mouse_0 = l_Parent_1:GetMouse();
l_l_Parent_1_Mouse_0.TargetFilter = table.unpack(l_CollectionService_0:GetTagged("ExcludeFromRaycast"));
v6:RemoteEvent("CandlyLauncher/Launch"):FireServer(l_l_Parent_1_Mouse_0.Hit, l_Parent_0.Handle);
end); - Edit
03:12:20.401
- Edit
03:12:20.401
============================== - Edit
03:12:20.401 📜 ReplicatedStorage.Items.Jelly Gun.CandyLauncherController - Edit
03:12:20.401 ==============================
- Edit
03:12:20.402 local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local CandyLauncher = Net:RemoteEvent("CandlyLauncher/Launch")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local function applyJellyTransform(player, target)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
if player:GetAttribute("JellyTransform") then return end
local jellyModel = ServerStorage:FindFirstChild("Jelly")
if not jellyModel then return end
local jellyClone = jellyModel:Clone()
local jellyPrimaryPart = jellyClone:FindFirstChildWhichIsA("BasePart") or jellyClone
jellyPrimaryPart.CFrame = root.CFrame
jellyClone.Parent = target
local originalParts = {}
for _, part in pairs(target:GetDescendants()) do
if part:IsA("BasePart") then
originalParts[part] = { Transparency = part.Transparency, CanCollide = part.CanCollide }
part.CanCollide = false
end
end
for _, part in pairs(jellyClone:GetDescendants()) do
if part:IsA("BasePart") then
part.Anchored = false
part.CanCollide = (part == jellyPrimaryPart)
end
end
local weld = Instance.new("WeldConstraint")
weld.Part0 = root
weld.Part1 = jellyPrimaryPart
weld.Parent = root
player:SetAttribute("JellyTransform", true)
local TargetPlayer = Players:GetPlayerFromCharacter(target)
RagdollModule.TimedRagdoll(target,5)
CandyLauncher:FireClient(TargetPlayer,"TurnIntoJelly")
task.delay(10, function()
jellyClone:Destroy()
for part, props in pairs(originalParts) do
if part.Parent then
part.Transparency = props.Transparency
part.CanCollide = props.CanCollide
end
end
player:SetAttribute("JellyTransform", nil)
end)
end
CandyLauncher.OnServerEvent:Connect(function(player, hit, handle)
local character = player.Character
if not character then return end
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if not humanoidRootPart then return end
local targetCharacter = hit and hit.Parent
local targetPlayer = targetCharacter and Players:GetPlayerFromCharacter(targetCharacter)
if targetPlayer and targetPlayer ~= player then
applyJellyTransform(targetPlayer, targetCharacter)
end
end)
local tool = script.Parent
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end) - Edit
03:12:20.402
- Edit
03:12:20.402
============================== - Edit
03:12:20.402 📜 ReplicatedStorage.Items.Splatter Slap.Controller - Edit
03:12:20.402 ==============================
- Edit
03:12:20.402 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local SlapData = require(ReplicatedStorage.Datas.Items)[script.Parent.Name]
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local tool = script.Parent
local cooldowns = {}
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://137003123112104"
local animationTrack
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5, 5, 5)
local cframe = root.CFrame * CFrame.new(0, 0, -3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local params = OverlapParams.new()
params.FilterDescendantsInstances = {character}
params.MaxParts = 10
local parts = workspace:GetPartBoundsInBox(region.CFrame, region.Size, params)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local function applySlap(player: Player, target, direction)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
local success, err = pcall(function()
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
CombatController:FireClient(targetPlayer, SlapData.Force, direction)
RagdollModule.TimedRagdoll(target, SlapData.RagdollDuration)
end)
if not success then
warn("Error applying slap: " .. err)
end
end
tool.Activated:Connect(function()
local char = tool.Parent
local player = Players:GetPlayerFromCharacter(char)
if player:GetAttribute("Stealing") == true then
return
end
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < SlapData.Cooldown then return end
cooldowns[player.UserId] = os.clock()
local humanoid = char:FindFirstChild("Humanoid")
if humanoid and not animationTrack then
animationTrack = humanoid:LoadAnimation(animation)
end
if animationTrack then
animationTrack:Play()
end
local dir = char.HumanoidRootPart.CFrame.LookVector
for target in pairs(getTargets(char)) do
applySlap(player, target, dir)
end
end)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end)
Players.PlayerRemoving:Connect(function(player)
cooldowns[player.UserId] = nil
end) - Edit
03:12:20.402
- Edit
03:12:20.402
============================== - Edit
03:12:20.402 📜 ReplicatedStorage.Items.Slap.Controller - Edit
03:12:20.402 ==============================
- Edit
03:12:20.402 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local SlapData = require(ReplicatedStorage.Datas.Items)[script.Parent.Name]
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local tool = script.Parent
local cooldowns = {}
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://114648214746202"
local animationTrack
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5, 5, 5)
local cframe = root.CFrame * CFrame.new(0, 0, -3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local params = OverlapParams.new()
params.FilterDescendantsInstances = {character}
params.MaxParts = 10
local parts = workspace:GetPartBoundsInBox(region.CFrame, region.Size, params)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local function applySlap(player: Player, target, direction)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
local success, err = pcall(function()
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
CombatController:FireClient(targetPlayer, SlapData.Force, direction)
RagdollModule.TimedRagdoll(target, SlapData.RagdollDuration)
end)
if not success then
warn("Error applying slap: " .. err)
end
end
tool.Activated:Connect(function()
local char = tool.Parent
local player = Players:GetPlayerFromCharacter(char)
if player:GetAttribute("Stealing") == true then
return
end
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < SlapData.Cooldown then return end
cooldowns[player.UserId] = os.clock()
local humanoid = char:FindFirstChild("Humanoid")
if humanoid and not animationTrack then
animationTrack = humanoid:LoadAnimation(animation)
end
if animationTrack then
animationTrack:Play()
end
local dir = char.HumanoidRootPart.CFrame.LookVector
for target in pairs(getTargets(char)) do
applySlap(player, target, dir)
end
end)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end)
Players.PlayerRemoving:Connect(function(player)
cooldowns[player.UserId] = nil
end) - Edit
03:12:20.402
- Edit
03:12:20.402
============================== - Edit
03:12:20.402 📜 ReplicatedStorage.Items.Ruby Slap.Controller - Edit
03:12:20.402 ==============================
- Edit
03:12:20.403 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local SlapData = require(ReplicatedStorage.Datas.Items)[script.Parent.Name]
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local tool = script.Parent
local cooldowns = {}
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://137003123112104"
local animationTrack
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5, 5, 5)
local cframe = root.CFrame * CFrame.new(0, 0, -3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local params = OverlapParams.new()
params.FilterDescendantsInstances = {character}
params.MaxParts = 10
local parts = workspace:GetPartBoundsInBox(region.CFrame, region.Size, params)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local function applySlap(player: Player, target, direction)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
local success, err = pcall(function()
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
CombatController:FireClient(targetPlayer, SlapData.Force, direction)
RagdollModule.TimedRagdoll(target, SlapData.RagdollDuration)
end)
if not success then
warn("Error applying slap: " .. err)
end
end
tool.Activated:Connect(function()
local char = tool.Parent
local player = Players:GetPlayerFromCharacter(char)
if player:GetAttribute("Stealing") == true then
return
end
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < SlapData.Cooldown then return end
cooldowns[player.UserId] = os.clock()
local humanoid = char:FindFirstChild("Humanoid")
if humanoid and not animationTrack then
animationTrack = humanoid:LoadAnimation(animation)
end
if animationTrack then
animationTrack:Play()
end
local dir = char.HumanoidRootPart.CFrame.LookVector
for target in pairs(getTargets(char)) do
applySlap(player, target, dir)
end
end)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end)
Players.PlayerRemoving:Connect(function(player)
cooldowns[player.UserId] = nil
end) - Edit
03:12:20.403
- Edit
03:12:20.403
============================== - Edit
03:12:20.403 📜 ReplicatedStorage.Items.Rainbow Slap.Controller - Edit
03:12:20.403 ==============================
- Edit
03:12:20.403 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local SlapData = require(ReplicatedStorage.Datas.Items)[script.Parent.Name]
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local tool = script.Parent
local cooldowns = {}
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://114648214746202"
local animationTrack
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5, 5, 5)
local cframe = root.CFrame * CFrame.new(0, 0, -3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local params = OverlapParams.new()
params.FilterDescendantsInstances = {character}
params.MaxParts = 10
local parts = workspace:GetPartBoundsInBox(region.CFrame, region.Size, params)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local function applySlap(player: Player, target, direction)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
local success, err = pcall(function()
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
CombatController:FireClient(targetPlayer, SlapData.Force, direction)
RagdollModule.TimedRagdoll(target, SlapData.RagdollDuration)
end)
if not success then
warn("Error applying slap: " .. err)
end
end
tool.Activated:Connect(function()
local char = tool.Parent
local player = Players:GetPlayerFromCharacter(char)
if player:GetAttribute("Stealing") == true then
return
end
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < SlapData.Cooldown then return end
cooldowns[player.UserId] = os.clock()
local humanoid = char:FindFirstChild("Humanoid")
if humanoid and not animationTrack then
animationTrack = humanoid:LoadAnimation(animation)
end
if animationTrack then
animationTrack:Play()
end
local dir = char.HumanoidRootPart.CFrame.LookVector
for target in pairs(getTargets(char)) do
applySlap(player, target, dir)
end
end)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end)
Players.PlayerRemoving:Connect(function(player)
cooldowns[player.UserId] = nil
end) - Edit
03:12:20.403
- Edit
03:12:20.403
============================== - Edit
03:12:20.403 📜 ReplicatedStorage.Items.Rainbow Slap.Handle.Color - Edit
03:12:20.403 ==============================
- Edit
03:12:20.403 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: Color, time of decompilation: Tue Jun 24 14:16:13 2025 ]]
local l_SurfaceAppearance_0 = script.Parent:FindFirstChildOfClass("SurfaceAppearance");
local v1 = Color3.fromRGB(200, 200, 200);
local v2 = Color3.fromRGB(255, 255, 255);
local v3 = 0;
(function() --[[ Line: 12 ]] --[[ Name: pulsarPretoBranco ]]
-- upvalues: v3 (ref), v1 (copy), v2 (copy), l_SurfaceAppearance_0 (copy)
while true do
v3 = v3 + 0.02;
local v4 = (math.sin(v3 * 5) + 1) / 2;
local v5 = v1:Lerp(v2, v4);
if l_SurfaceAppearance_0 then
l_SurfaceAppearance_0.Color = v5;
end;
wait(0.02);
end;
end)(); - Edit
03:12:20.403
- Edit
03:12:20.403
============================== - Edit
03:12:20.403 📜 ReplicatedStorage.Items.Nuclear Slap.Controller - Edit
03:12:20.403 ==============================
- Edit
03:12:20.404 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local SlapData = require(ReplicatedStorage.Datas.Items)[script.Parent.Name]
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local tool = script.Parent
local cooldowns = {}
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://114648214746202"
local animationTrack
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5, 5, 5)
local cframe = root.CFrame * CFrame.new(0, 0, -3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local params = OverlapParams.new()
params.FilterDescendantsInstances = {character}
params.MaxParts = 10
local parts = workspace:GetPartBoundsInBox(region.CFrame, region.Size, params)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local function applySlap(player: Player, target, direction)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
local success, err = pcall(function()
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
CombatController:FireClient(targetPlayer, SlapData.Force, direction)
RagdollModule.TimedRagdoll(target, SlapData.RagdollDuration)
end)
if not success then
warn("Error applying slap: " .. err)
end
end
tool.Activated:Connect(function()
local char = tool.Parent
local player = Players:GetPlayerFromCharacter(char)
if player:GetAttribute("Stealing") == true then
return
end
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < SlapData.Cooldown then return end
cooldowns[player.UserId] = os.clock()
local humanoid = char:FindFirstChild("Humanoid")
if humanoid and not animationTrack then
animationTrack = humanoid:LoadAnimation(animation)
end
if animationTrack then
animationTrack:Play()
end
local dir = char.HumanoidRootPart.CFrame.LookVector
for target in pairs(getTargets(char)) do
applySlap(player, target, dir)
end
end)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end)
Players.PlayerRemoving:Connect(function(player)
cooldowns[player.UserId] = nil
end) - Edit
03:12:20.404
- Edit
03:12:20.404
============================== - Edit
03:12:20.404 📜 ReplicatedStorage.Items.Nuclear Slap.Handle.Color - Edit
03:12:20.404 ==============================
- Edit
03:12:20.404 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: Color, time of decompilation: Tue Jun 24 14:16:12 2025 ]]
local l_SurfaceAppearance_0 = script.Parent:FindFirstChildOfClass("SurfaceAppearance");
local v1 = Color3.fromRGB(150, 255, 0);
local v2 = Color3.fromRGB(255, 255, 255);
local v3 = 0;
(function() --[[ Line: 13 ]] --[[ Name: pulsarNuclear ]]
-- upvalues: v3 (ref), v1 (copy), v2 (copy), l_SurfaceAppearance_0 (copy)
while true do
v3 = v3 + 0.02;
local v4 = (math.sin(v3 * 3) + 1) / 2;
local v5 = v1:Lerp(v2, v4);
if l_SurfaceAppearance_0 then
l_SurfaceAppearance_0.Color = v5;
end;
wait(0.02);
end;
end)(); - Edit
03:12:20.404
- Edit
03:12:20.404
============================== - Edit
03:12:20.404 📜 ReplicatedStorage.Items.Lava Slap.Controller - Edit
03:12:20.404 ==============================
- Edit
03:12:20.404 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local SlapData = require(ReplicatedStorage.Datas.Items)[script.Parent.Name]
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local tool = script.Parent
local cooldowns = {}
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://137003123112104"
local animationTrack
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5, 5, 5)
local cframe = root.CFrame * CFrame.new(0, 0, -3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local params = OverlapParams.new()
params.FilterDescendantsInstances = {character}
params.MaxParts = 10
local parts = workspace:GetPartBoundsInBox(region.CFrame, region.Size, params)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local function applySlap(player: Player, target, direction)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
local success, err = pcall(function()
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
CombatController:FireClient(targetPlayer, SlapData.Force, direction)
RagdollModule.TimedRagdoll(target, SlapData.RagdollDuration)
end)
if not success then
warn("Error applying slap: " .. err)
end
end
tool.Activated:Connect(function()
local char = tool.Parent
local player = Players:GetPlayerFromCharacter(char)
if player:GetAttribute("Stealing") == true then
return
end
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < SlapData.Cooldown then return end
cooldowns[player.UserId] = os.clock()
local humanoid = char:FindFirstChild("Humanoid")
if humanoid and not animationTrack then
animationTrack = humanoid:LoadAnimation(animation)
end
if animationTrack then
animationTrack:Play()
end
local dir = char.HumanoidRootPart.CFrame.LookVector
for target in pairs(getTargets(char)) do
applySlap(player, target, dir)
end
end)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end)
Players.PlayerRemoving:Connect(function(player)
cooldowns[player.UserId] = nil
end) - Edit
03:12:20.404
- Edit
03:12:20.404
============================== - Edit
03:12:20.404 📜 ReplicatedStorage.Items.Iron Slap.Controller - Edit
03:12:20.405 ==============================
- Edit
03:12:20.405 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local SlapData = require(ReplicatedStorage.Datas.Items)[script.Parent.Name]
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local tool = script.Parent
local cooldowns = {}
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://114648214746202"
local animationTrack
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5, 5, 5)
local cframe = root.CFrame * CFrame.new(0, 0, -3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local params = OverlapParams.new()
params.FilterDescendantsInstances = {character}
params.MaxParts = 10
local parts = workspace:GetPartBoundsInBox(region.CFrame, region.Size, params)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local function applySlap(player: Player, target, direction)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
local success, err = pcall(function()
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
CombatController:FireClient(targetPlayer, SlapData.Force, direction)
RagdollModule.TimedRagdoll(target, SlapData.RagdollDuration)
end)
if not success then
warn("Error applying slap: " .. err)
end
end
tool.Activated:Connect(function()
local char = tool.Parent
local player = Players:GetPlayerFromCharacter(char)
if player:GetAttribute("Stealing") == true then
return
end
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < SlapData.Cooldown then return end
cooldowns[player.UserId] = os.clock()
local humanoid = char:FindFirstChild("Humanoid")
if humanoid and not animationTrack then
animationTrack = humanoid:LoadAnimation(animation)
end
if animationTrack then
animationTrack:Play()
end
local dir = char.HumanoidRootPart.CFrame.LookVector
for target in pairs(getTargets(char)) do
applySlap(player, target, dir)
end
end)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end)
Players.PlayerRemoving:Connect(function(player)
cooldowns[player.UserId] = nil
end) - Edit
03:12:20.405
- Edit
03:12:20.405
============================== - Edit
03:12:20.405 📜 ReplicatedStorage.Items.Gold Slap.Controller - Edit
03:12:20.405 ==============================
- Edit
03:12:20.405 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local SlapData = require(ReplicatedStorage.Datas.Items)[script.Parent.Name]
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local tool = script.Parent
local cooldowns = {}
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://114648214746202"
local animationTrack
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5, 5, 5)
local cframe = root.CFrame * CFrame.new(0, 0, -3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local params = OverlapParams.new()
params.FilterDescendantsInstances = {character}
params.MaxParts = 10
local parts = workspace:GetPartBoundsInBox(region.CFrame, region.Size, params)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local function applySlap(player: Player, target, direction)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
local success, err = pcall(function()
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
CombatController:FireClient(targetPlayer, SlapData.Force, direction)
RagdollModule.TimedRagdoll(target, SlapData.RagdollDuration)
end)
if not success then
warn("Error applying slap: " .. err)
end
end
tool.Activated:Connect(function()
local char = tool.Parent
local player = Players:GetPlayerFromCharacter(char)
if player:GetAttribute("Stealing") == true then
return
end
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < SlapData.Cooldown then return end
cooldowns[player.UserId] = os.clock()
local humanoid = char:FindFirstChild("Humanoid")
if humanoid and not animationTrack then
animationTrack = humanoid:LoadAnimation(animation)
end
if animationTrack then
animationTrack:Play()
end
local dir = char.HumanoidRootPart.CFrame.LookVector
for target in pairs(getTargets(char)) do
applySlap(player, target, dir)
end
end)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end)
Players.PlayerRemoving:Connect(function(player)
cooldowns[player.UserId] = nil
end) - Edit
03:12:20.405
- Edit
03:12:20.405
============================== - Edit
03:12:20.405 📜 ReplicatedStorage.Items.Glitched Slap.Controller - Edit
03:12:20.405 ==============================
- Edit
03:12:20.405 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local SlapData = require(ReplicatedStorage.Datas.Items)[script.Parent.Name]
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local tool = script.Parent
local cooldowns = {}
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://114648214746202"
local animationTrack
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5, 5, 5)
local cframe = root.CFrame * CFrame.new(0, 0, -3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local params = OverlapParams.new()
params.FilterDescendantsInstances = {character}
params.MaxParts = 10
local parts = workspace:GetPartBoundsInBox(region.CFrame, region.Size, params)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local function applySlap(player: Player, target, direction)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
local success, err = pcall(function()
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
CombatController:FireClient(targetPlayer, SlapData.Force, direction)
RagdollModule.TimedRagdoll(target, SlapData.RagdollDuration)
end)
if not success then
warn("Error applying slap: " .. err)
end
end
tool.Activated:Connect(function()
local char = tool.Parent
local player = Players:GetPlayerFromCharacter(char)
if player:GetAttribute("Stealing") == true then
return
end
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < SlapData.Cooldown then return end
cooldowns[player.UserId] = os.clock()
local humanoid = char:FindFirstChild("Humanoid")
if humanoid and not animationTrack then
animationTrack = humanoid:LoadAnimation(animation)
end
if animationTrack then
animationTrack:Play()
end
local dir = char.HumanoidRootPart.CFrame.LookVector
for target in pairs(getTargets(char)) do
applySlap(player, target, dir)
end
end)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end)
Players.PlayerRemoving:Connect(function(player)
cooldowns[player.UserId] = nil
end) - Edit
03:12:20.405
- Edit
03:12:20.405
============================== - Edit
03:12:20.405 📜 ReplicatedStorage.Items.Glitched Slap.Handle.Color - Edit
03:12:20.406 ==============================
- Edit
03:12:20.406 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: Color, time of decompilation: Tue Jun 24 14:16:12 2025 ]]
local l_SurfaceAppearance_0 = script.Parent:FindFirstChildOfClass("SurfaceAppearance");
local v1 = Color3.fromRGB(0, 0, 0);
local v2 = Color3.fromRGB(255, 255, 255);
local v3 = 0;
(function() --[[ Line: 12 ]] --[[ Name: pulsarPretoBranco ]]
-- upvalues: v3 (ref), v1 (copy), v2 (copy), l_SurfaceAppearance_0 (copy)
while true do
v3 = v3 + 0.02;
local v4 = (math.sin(v3 * 75) + 1) / 2;
local v5 = v1:Lerp(v2, v4);
if l_SurfaceAppearance_0 then
l_SurfaceAppearance_0.Color = v5;
end;
wait(0.02);
end;
end)(); - Edit
03:12:20.406
- Edit
03:12:20.406
============================== - Edit
03:12:20.406 📜 ReplicatedStorage.Items.Flame Slap.Controller - Edit
03:12:20.406 ==============================
- Edit
03:12:20.406 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local SlapData = require(ReplicatedStorage.Datas.Items)[script.Parent.Name]
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local tool = script.Parent
local cooldowns = {}
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://114648214746202"
local animationTrack
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5, 5, 5)
local cframe = root.CFrame * CFrame.new(0, 0, -3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local params = OverlapParams.new()
params.FilterDescendantsInstances = {character}
params.MaxParts = 10
local parts = workspace:GetPartBoundsInBox(region.CFrame, region.Size, params)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local function applySlap(player: Player, target, direction)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
local success, err = pcall(function()
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
CombatController:FireClient(targetPlayer, SlapData.Force, direction)
RagdollModule.TimedRagdoll(target, SlapData.RagdollDuration)
end)
if not success then
warn("Error applying slap: " .. err)
end
end
tool.Activated:Connect(function()
local char = tool.Parent
local player = Players:GetPlayerFromCharacter(char)
if player:GetAttribute("Stealing") == true then
return
end
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < SlapData.Cooldown then return end
cooldowns[player.UserId] = os.clock()
local humanoid = char:FindFirstChild("Humanoid")
if humanoid and not animationTrack then
animationTrack = humanoid:LoadAnimation(animation)
end
if animationTrack then
animationTrack:Play()
end
local dir = char.HumanoidRootPart.CFrame.LookVector
for target in pairs(getTargets(char)) do
applySlap(player, target, dir)
end
end)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end)
Players.PlayerRemoving:Connect(function(player)
cooldowns[player.UserId] = nil
end) - Edit
03:12:20.406
- Edit
03:12:20.406
============================== - Edit
03:12:20.406 📜 ReplicatedStorage.Items.Flame Slap.Handle.Color - Edit
03:12:20.406 ==============================
- Edit
03:12:20.406 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: Color, time of decompilation: Tue Jun 24 14:16:13 2025 ]]
local l_SurfaceAppearance_0 = script.Parent:FindFirstChildOfClass("SurfaceAppearance");
local v1 = Color3.fromRGB(200, 200, 200);
local v2 = Color3.fromRGB(255, 255, 255);
local v3 = 0;
(function() --[[ Line: 12 ]] --[[ Name: pulsarPretoBranco ]]
-- upvalues: v3 (ref), v1 (copy), v2 (copy), l_SurfaceAppearance_0 (copy)
while true do
v3 = v3 + 0.02;
local v4 = (math.sin(v3 * 3) + 1) / 2;
local v5 = v1:Lerp(v2, v4);
if l_SurfaceAppearance_0 then
l_SurfaceAppearance_0.Color = v5;
end;
wait(0.02);
end;
end)(); - Edit
03:12:20.406
- Edit
03:12:20.406
============================== - Edit
03:12:20.407 📜 ReplicatedStorage.Items.Emerald Slap.Controller - Edit
03:12:20.407 ==============================
- Edit
03:12:20.407 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local SlapData = require(ReplicatedStorage.Datas.Items)[script.Parent.Name]
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local tool = script.Parent
local cooldowns = {}
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://114648214746202"
local animationTrack
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5, 5, 5)
local cframe = root.CFrame * CFrame.new(0, 0, -3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local params = OverlapParams.new()
params.FilterDescendantsInstances = {character}
params.MaxParts = 10
local parts = workspace:GetPartBoundsInBox(region.CFrame, region.Size, params)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local function applySlap(player: Player, target, direction)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
local success, err = pcall(function()
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
CombatController:FireClient(targetPlayer, SlapData.Force, direction)
RagdollModule.TimedRagdoll(target, SlapData.RagdollDuration)
end)
if not success then
warn("Error applying slap: " .. err)
end
end
tool.Activated:Connect(function()
local char = tool.Parent
local player = Players:GetPlayerFromCharacter(char)
if player:GetAttribute("Stealing") == true then
return
end
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < SlapData.Cooldown then return end
cooldowns[player.UserId] = os.clock()
local humanoid = char:FindFirstChild("Humanoid")
if humanoid and not animationTrack then
animationTrack = humanoid:LoadAnimation(animation)
end
if animationTrack then
animationTrack:Play()
end
local dir = char.HumanoidRootPart.CFrame.LookVector
for target in pairs(getTargets(char)) do
applySlap(player, target, dir)
end
end)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end)
Players.PlayerRemoving:Connect(function(player)
cooldowns[player.UserId] = nil
end) - Edit
03:12:20.407
- Edit
03:12:20.407
============================== - Edit
03:12:20.407 📜 ReplicatedStorage.Items.Diamond Slap.Controller - Edit
03:12:20.407 ==============================
- Edit
03:12:20.407 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local SlapData = require(ReplicatedStorage.Datas.Items)[script.Parent.Name]
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local tool = script.Parent
local cooldowns = {}
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://114648214746202"
local animationTrack
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5, 5, 5)
local cframe = root.CFrame * CFrame.new(0, 0, -3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local params = OverlapParams.new()
params.FilterDescendantsInstances = {character}
params.MaxParts = 10
local parts = workspace:GetPartBoundsInBox(region.CFrame, region.Size, params)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local function applySlap(player: Player, target, direction)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
local success, err = pcall(function()
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
CombatController:FireClient(targetPlayer, SlapData.Force, direction)
RagdollModule.TimedRagdoll(target, SlapData.RagdollDuration)
end)
if not success then
warn("Error applying slap: " .. err)
end
end
tool.Activated:Connect(function()
local char = tool.Parent
local player = Players:GetPlayerFromCharacter(char)
if player:GetAttribute("Stealing") == true then
return
end
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < SlapData.Cooldown then return end
cooldowns[player.UserId] = os.clock()
local humanoid = char:FindFirstChild("Humanoid")
if humanoid and not animationTrack then
animationTrack = humanoid:LoadAnimation(animation)
end
if animationTrack then
animationTrack:Play()
end
local dir = char.HumanoidRootPart.CFrame.LookVector
for target in pairs(getTargets(char)) do
applySlap(player, target, dir)
end
end)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end)
Players.PlayerRemoving:Connect(function(player)
cooldowns[player.UserId] = nil
end) - Edit
03:12:20.407
- Edit
03:12:20.407
============================== - Edit
03:12:20.407 📜 ReplicatedStorage.Items.Dev Slap.Handle.Color - Edit
03:12:20.407 ==============================
- Edit
03:12:20.407 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: Color, time of decompilation: Tue Jun 24 14:16:13 2025 ]]
local l_SurfaceAppearance_0 = script.Parent:FindFirstChildOfClass("SurfaceAppearance");
local v1 = {
Color3.fromRGB(255, 0, 0),
Color3.fromRGB(0, 255, 0),
Color3.fromRGB(0, 0, 255),
Color3.fromRGB(255, 255, 0),
Color3.fromRGB(255, 0, 255),
Color3.fromRGB(0, 255, 255),
Color3.fromRGB(255, 255, 255),
Color3.fromRGB(0, 0, 0)
};
(function() --[[ Line: 18 ]] --[[ Name: efeitoGlitch ]]
-- upvalues: v1 (copy), l_SurfaceAppearance_0 (copy)
while true do
local v2 = v1[math.random(1, #v1)];
if l_SurfaceAppearance_0 then
l_SurfaceAppearance_0.Color = v2;
end;
wait(0.01);
end;
end)(); - Edit
03:12:20.407
- Edit
03:12:20.407
============================== - Edit
03:12:20.407 📜 ReplicatedStorage.Items.Dev Slap.Controller - Edit
03:12:20.408 ==============================
- Edit
03:12:20.408 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local SlapData = require(ReplicatedStorage.Datas.Items)[script.Parent.Name]
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local tool = script.Parent
local cooldowns = {}
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://114648214746202"
local animationTrack
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5, 5, 5)
local cframe = root.CFrame * CFrame.new(0, 0, -3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local params = OverlapParams.new()
params.FilterDescendantsInstances = {character}
params.MaxParts = 10
local parts = workspace:GetPartBoundsInBox(region.CFrame, region.Size, params)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local function applySlap(player: Player, target, direction)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
local success, err = pcall(function()
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
CombatController:FireClient(targetPlayer, SlapData.Force, direction)
RagdollModule.TimedRagdoll(target, SlapData.RagdollDuration)
end)
if not success then
warn("Error applying slap: " .. err)
end
end
tool.Activated:Connect(function()
local char = tool.Parent
local player = Players:GetPlayerFromCharacter(char)
if player:GetAttribute("Stealing") == true then
return
end
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < SlapData.Cooldown then return end
cooldowns[player.UserId] = os.clock()
local humanoid = char:FindFirstChild("Humanoid")
if humanoid and not animationTrack then
animationTrack = humanoid:LoadAnimation(animation)
end
if animationTrack then
animationTrack:Play()
end
local dir = char.HumanoidRootPart.CFrame.LookVector
for target in pairs(getTargets(char)) do
applySlap(player, target, dir)
end
end)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end)
Players.PlayerRemoving:Connect(function(player)
cooldowns[player.UserId] = nil
end) - Edit
03:12:20.408
- Edit
03:12:20.408
============================== - Edit
03:12:20.408 📜 ReplicatedStorage.Items.Candy Slap.Handle.Color - Edit
03:12:20.408 ==============================
- Edit
03:12:20.408 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: Color, time of decompilation: Sat Jul 12 14:22:37 2025 ]]
local l_SurfaceAppearance_0 = script.Parent:FindFirstChildOfClass("SurfaceAppearance");
local v1 = Color3.fromRGB(255, 0, 136);
local v2 = Color3.fromRGB(255, 53, 178);
local v3 = 0;
(function() --[[ Line: 13 ]] --[[ Name: pulsarNuclear ]]
-- upvalues: v3 (ref), v1 (copy), v2 (copy), l_SurfaceAppearance_0 (copy)
while true do
v3 = v3 + 0.02;
local v4 = (math.sin(v3 * 3) + 1) / 2;
local v5 = v1:Lerp(v2, v4);
if l_SurfaceAppearance_0 then
l_SurfaceAppearance_0.Color = v5;
end;
wait(0.02);
end;
end)(); - Edit
03:12:20.408
- Edit
03:12:20.408
============================== - Edit
03:12:20.408 📜 ReplicatedStorage.Items.Candy Slap.Controller - Edit
03:12:20.408 ==============================
- Edit
03:12:20.408 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local SlapData = require(ReplicatedStorage.Datas.Items)[script.Parent.Name]
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local tool = script.Parent
local cooldowns = {}
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://114648214746202"
local animationTrack
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5, 5, 5)
local cframe = root.CFrame * CFrame.new(0, 0, -3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local params = OverlapParams.new()
params.FilterDescendantsInstances = {character}
params.MaxParts = 10
local parts = workspace:GetPartBoundsInBox(region.CFrame, region.Size, params)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local function applySlap(player: Player, target, direction)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
local success, err = pcall(function()
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
CombatController:FireClient(targetPlayer, SlapData.Force, direction)
RagdollModule.TimedRagdoll(target, SlapData.RagdollDuration)
end)
if not success then
warn("Error applying slap: " .. err)
end
end
tool.Activated:Connect(function()
local char = tool.Parent
local player = Players:GetPlayerFromCharacter(char)
if player:GetAttribute("Stealing") == true then
return
end
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < SlapData.Cooldown then return end
cooldowns[player.UserId] = os.clock()
local humanoid = char:FindFirstChild("Humanoid")
if humanoid and not animationTrack then
animationTrack = humanoid:LoadAnimation(animation)
end
if animationTrack then
animationTrack:Play()
end
local dir = char.HumanoidRootPart.CFrame.LookVector
for target in pairs(getTargets(char)) do
applySlap(player, target, dir)
end
end)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end)
Players.PlayerRemoving:Connect(function(player)
cooldowns[player.UserId] = nil
end) - Edit
03:12:20.408
- Edit
03:12:20.408
============================== - Edit
03:12:20.408 📜 ReplicatedStorage.Items.Bloodmoon Slap.Handle.Color - Edit
03:12:20.408 ==============================
- Edit
03:12:20.408 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: Color, time of decompilation: Tue Jun 24 14:16:13 2025 ]]
local l_Parent_0 = script.Parent;
local l_SurfaceAppearance_0 = l_Parent_0:FindFirstChildOfClass("SurfaceAppearance");
local l_Highlight_0 = l_Parent_0:FindFirstChildOfClass("Highlight");
local v3 = Color3.fromRGB(200, 25, 25);
local v4 = Color3.fromRGB(155, 25, 25);
local v5 = Color3.fromRGB(125, 25, 25);
local v6 = Color3.fromRGB(75, 25, 25);
local v7 = 0;
if l_Highlight_0 then
l_Highlight_0.FillTransparency = 0.9;
l_Highlight_0.OutlineTransparency = 0;
end;
(function() --[[ Line: 22 ]] --[[ Name: pulsarCores ]]
-- upvalues: v7 (ref), v3 (copy), v4 (copy), v5 (copy), v6 (copy), l_SurfaceAppearance_0 (copy), l_Highlight_0 (copy)
while true do
v7 = v7 + 0.02;
local v8 = (math.sin(v7 * 10) + 1) / 2;
local v9 = v3:Lerp(v4, v8);
local v10 = v5:Lerp(v4, v8);
local v11 = v4:Lerp(v6, v8);
if l_SurfaceAppearance_0 then
l_SurfaceAppearance_0.Color = v9;
end;
if l_Highlight_0 then
l_Highlight_0.FillColor = v10;
l_Highlight_0.OutlineColor = v11;
end;
wait(0.02);
end;
end)(); - Edit
03:12:20.409
- Edit
03:12:20.409
============================== - Edit
03:12:20.409 📜 ReplicatedStorage.Items.Bloodmoon Slap.Controller - Edit
03:12:20.409 ==============================
- Edit
03:12:20.409 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local SlapData = require(ReplicatedStorage.Datas.Items)[script.Parent.Name]
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local tool = script.Parent
local cooldowns = {}
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://114648214746202"
local animationTrack
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5, 5, 5)
local cframe = root.CFrame * CFrame.new(0, 0, -3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local params = OverlapParams.new()
params.FilterDescendantsInstances = {character}
params.MaxParts = 10
local parts = workspace:GetPartBoundsInBox(region.CFrame, region.Size, params)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local function applySlap(player: Player, target, direction)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
local success, err = pcall(function()
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
CombatController:FireClient(targetPlayer, SlapData.Force, direction)
RagdollModule.TimedRagdoll(target, SlapData.RagdollDuration)
end)
if not success then
warn("Error applying slap: " .. err)
end
end
tool.Activated:Connect(function()
local char = tool.Parent
local player = Players:GetPlayerFromCharacter(char)
if player:GetAttribute("Stealing") == true then
return
end
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < SlapData.Cooldown then return end
cooldowns[player.UserId] = os.clock()
local humanoid = char:FindFirstChild("Humanoid")
if humanoid and not animationTrack then
animationTrack = humanoid:LoadAnimation(animation)
end
if animationTrack then
animationTrack:Play()
end
local dir = char.HumanoidRootPart.CFrame.LookVector
for target in pairs(getTargets(char)) do
applySlap(player, target, dir)
end
end)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end)
Players.PlayerRemoving:Connect(function(player)
cooldowns[player.UserId] = nil
end) - Edit
03:12:20.409
- Edit
03:12:20.409
============================== - Edit
03:12:20.409 📜 ReplicatedStorage.Items.Blackhole Slap.Controller - Edit
03:12:20.409 ==============================
- Edit
03:12:20.409 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local SlapData = require(ReplicatedStorage.Datas.Items)[script.Parent.Name]
local tool = script.Parent
local cooldowns = {}
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://114648214746202"
local animationTrack
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5,5,5)
local cframe = root.CFrame * CFrame.new(0,0,-3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local parts = workspace:FindPartsInRegion3(region, character, 10)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local function applySlap(player: Player, target, direction)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
h:TakeDamage(0)
local force = SlapData.Force * 0.10
local upwardForce = Vector3.new(0, 10, 0)
local bv = Instance.new("BodyVelocity")
bv.Velocity = direction.Unit * force + upwardForce
bv.MaxForce = Vector3.new(1e5, 1e5, 1e5)
bv.Parent = root
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
game.Debris:AddItem(bv, 0.2)
RagdollModule.TimedRagdoll(target, SlapData.RagdollDuration)
end
tool.Activated:Connect(function()
local char = tool.Parent
local player = game:GetService("Players"):GetPlayerFromCharacter(char)
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < SlapData.Cooldown then return end
cooldowns[player.UserId] = os.clock()
local humanoid = char:FindFirstChild("Humanoid")
if humanoid then
animationTrack = humanoid:LoadAnimation(animation)
animationTrack:Play()
end
local dir = char.HumanoidRootPart.CFrame.LookVector
for target in pairs(getTargets(char)) do
applySlap(player, target, dir)
end
end) - Edit
03:12:20.409
- Edit
03:12:20.409
============================== - Edit
03:12:20.409 📜 ReplicatedStorage.Items.Blackhole Slap.Handle.Color - Edit
03:12:20.409 ==============================
- Edit
03:12:20.409 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [[ Script name: Color, time of decompilation: Tue Jun 24 14:16:12 2025 ]]
local l_Parent_0 = script.Parent;
local l_SurfaceAppearance_0 = l_Parent_0:FindFirstChildOfClass("SurfaceAppearance");
local l_Highlight_0 = l_Parent_0:FindFirstChildOfClass("Highlight");
local v3 = Color3.fromRGB(0, 0, 0);
local v4 = Color3.fromRGB(255, 170, 0);
local v5 = Color3.new(1, 1, 1);
(function() --[[ Line: 12 ]] --[[ Name: transicaoCores ]]
-- upvalues: v3 (copy), v4 (copy), v5 (copy), l_SurfaceAppearance_0 (copy), l_Highlight_0 (copy)
while true do
for v6 = 0, 1, 0.02 do
local v7 = v3:Lerp(v4, v6);
local v8 = v5:Lerp(v4, v6);
if l_SurfaceAppearance_0 then
l_SurfaceAppearance_0.Color = v7;
end;
if l_Highlight_0 then
l_Highlight_0.FillColor = v8;
l_Highlight_0.OutlineColor = v8;
end;
wait(0.02);
end;
for v9 = 1, 0, -0.02 do
local v10 = v3:Lerp(v4, v9);
local v11 = v5:Lerp(v4, v9);
if l_SurfaceAppearance_0 then
l_SurfaceAppearance_0.Color = v10;
end;
if l_Highlight_0 then
l_Highlight_0.FillColor = v11;
l_Highlight_0.OutlineColor = v11;
end;
wait(0.02);
end;
end;
end)(); - Edit
03:12:20.409
- Edit
03:12:20.409
============================== - Edit
03:12:20.410 📜 ReplicatedStorage.Items.Galaxy Slap.Controller - Edit
03:12:20.410 ==============================
- Edit
03:12:20.410 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local SlapData = require(ReplicatedStorage.Datas.Items)[script.Parent.Name]
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local tool = script.Parent
local cooldowns = {}
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://114648214746202"
local animationTrack
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5, 5, 5)
local cframe = root.CFrame * CFrame.new(0, 0, -3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local params = OverlapParams.new()
params.FilterDescendantsInstances = {character}
params.MaxParts = 10
local parts = workspace:GetPartBoundsInBox(region.CFrame, region.Size, params)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local function applySlap(player: Player, target, direction)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
local success, err = pcall(function()
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
CombatController:FireClient(targetPlayer, SlapData.Force, direction)
RagdollModule.TimedRagdoll(target, SlapData.RagdollDuration)
end)
if not success then
warn("Error applying slap: " .. err)
end
end
tool.Activated:Connect(function()
local char = tool.Parent
local player = Players:GetPlayerFromCharacter(char)
if player:GetAttribute("Stealing") == true then
return
end
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < SlapData.Cooldown then return end
cooldowns[player.UserId] = os.clock()
local humanoid = char:FindFirstChild("Humanoid")
if humanoid and not animationTrack then
animationTrack = humanoid:LoadAnimation(animation)
end
if animationTrack then
animationTrack:Play()
end
local dir = char.HumanoidRootPart.CFrame.LookVector
for target in pairs(getTargets(char)) do
applySlap(player, target, dir)
end
end)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end)
Players.PlayerRemoving:Connect(function(player)
cooldowns[player.UserId] = nil
end) - Edit
03:12:20.410
- Edit
03:12:20.410
============================== - Edit
03:12:20.410 📜 ReplicatedStorage.Items.Galaxy Slap.Handle.Color - Edit
03:12:20.410 ==============================
- Edit
03:12:20.410 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
local u1 = script.Parent:FindFirstChildOfClass("SurfaceAppearance")
local u2 = Color3.fromRGB(105, 90, 180)
local u3 = Color3.fromRGB(173, 216, 230)
local u4 = Color3.fromRGB(255, 182, 193)
local u5 = Color3.fromRGB(255, 255, 255)
local u6 = 0
(function() --[[Function name: efeitoGalaxiaSuave, line 15]]
--[[
Upvalues:
[1] = u6
[2] = u2
[3] = u3
[4] = u4
[5] = u5
[6] = u1
--]]
while true do
u6 = u6 + 0.02
local v7 = u6 * 1.2
local v8 = (math.sin(v7) + 1) / 2
local v9 = (u6 + 1) * 1.2
local v10 = (math.sin(v9) + 1) / 2
local v11 = u2:Lerp(u3, v8):Lerp(u4, v10):Lerp(u5, 0.5)
if u1 then
u1.Color = v11
end
wait(0.02)
end
end)() - Edit
03:12:20.410
- Edit
03:12:20.410
============================== - Edit
03:12:20.410 📜 ReplicatedStorage.Items.Dark Matter Slap.Controller - Edit
03:12:20.410 ==============================
- Edit
03:12:20.410 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local SlapData = require(ReplicatedStorage.Datas.Items)[script.Parent.Name]
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local tool = script.Parent
local cooldowns = {}
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://114648214746202"
local animationTrack
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5, 5, 5)
local cframe = root.CFrame * CFrame.new(0, 0, -3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local params = OverlapParams.new()
params.FilterDescendantsInstances = {character}
params.MaxParts = 10
local parts = workspace:GetPartBoundsInBox(region.CFrame, region.Size, params)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local function applySlap(player: Player, target, direction)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
local success, err = pcall(function()
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
CombatController:FireClient(targetPlayer, SlapData.Force, direction)
RagdollModule.TimedRagdoll(target, SlapData.RagdollDuration)
end)
if not success then
warn("Error applying slap: " .. err)
end
end
tool.Activated:Connect(function()
local char = tool.Parent
local player = Players:GetPlayerFromCharacter(char)
if player:GetAttribute("Stealing") == true then
return
end
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < SlapData.Cooldown then return end
cooldowns[player.UserId] = os.clock()
local humanoid = char:FindFirstChild("Humanoid")
if humanoid and not animationTrack then
animationTrack = humanoid:LoadAnimation(animation)
end
if animationTrack then
animationTrack:Play()
end
local dir = char.HumanoidRootPart.CFrame.LookVector
for target in pairs(getTargets(char)) do
applySlap(player, target, dir)
end
end)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end)
Players.PlayerRemoving:Connect(function(player)
cooldowns[player.UserId] = nil
end) - Edit
03:12:20.410
- Edit
03:12:20.410
============================== - Edit
03:12:20.411 📜 ReplicatedStorage.Items.Dark Matter Slap.Handle.Color - Edit
03:12:20.411 ==============================
- Edit
03:12:20.411 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
local u1 = script.Parent
local u2 = u1:FindFirstChildOfClass("SurfaceAppearance")
local u3 = Color3.fromRGB(10, 0, 20)
local u4 = Color3.fromRGB(128, 17, 255)
local u5 = Color3.fromRGB(220, 180, 255)
local u6 = Color3.fromRGB(255, 240, 255)
local u7 = 0
(function() --[[Function name: pulsarCores, line 16]]
--[[
Upvalues:
[1] = u1
[2] = u7
[3] = u3
[4] = u4
[5] = u5
[6] = u6
[7] = u2
--]]
while true do
local v8 = u1:FindFirstChildOfClass("Highlight")
u7 = u7 + 0.02
local v9 = u7 * 10
local v10 = (math.sin(v9) + 1) / 2
local v11 = u3:Lerp(u4, v10)
local v12 = u5:Lerp(u4, v10)
local v13 = u4:Lerp(u6, v10)
if u2 then
u2.Color = v11
end
if v8 then
v8.FillColor = v12
v8.OutlineColor = v13
end
wait(0.02)
end
end)() - Edit
03:12:20.411
- Edit
03:12:20.411
============================== - Edit
03:12:20.411 📜 ReplicatedStorage.Items.Medusa's Head.MedusaScript - Edit
03:12:20.411 ==============================
- Edit
03:12:20.411 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
local u1 = game:GetService("RunService")
local u2 = game:GetService("TweenService")
game:GetService("StarterPlayer")
local v3 = game:GetService("ReplicatedStorage")
game:GetService("ServerScriptService")
local u4 = v3:WaitForChild("Models").ToolsExtras
local v5 = v3:WaitForChild("Packages")
local u6 = require(v5.Net)
local u7 = require(v5.Debounce)
local v8 = script.Parent
local u9 = v8.Parent.Parent
local u10 = nil
local u11 = nil
local u12 = TweenInfo.new(0.3, Enum.EasingStyle.Quart, Enum.EasingDirection.In)
local u13 = nil
local u14 = nil
local function u19(p15) --[[Anonymous function at line 42]]
--[[
Upvalues:
[1] = u13
[2] = u2
[3] = u12
--]]
if u13 then
local u16 = Instance.new("NumberValue", script)
u16.Value = p15 and 0.0001 or 0.6
u16.Changed:Connect(function(p17) --[[Anonymous function at line 49]]
--[[
Upvalues:
[1] = u13
--]]
if u13 then
u13:ScaleTo(p17)
end
end)
local v18 = u2:Create(u16, u12, {
["Value"] = p15 and 0.6 or 0.0001
})
v18:Play()
v18.Completed:Connect(function() --[[Anonymous function at line 57]]
--[[
Upvalues:
[1] = u16
--]]
u16:Destroy()
end)
v18.Completed:Wait()
end
end
local function u21() --[[Anonymous function at line 63]]
--[[
Upvalues:
[1] = u10
[2] = u11
[3] = u9
--]]
if not (u10 and u11) then
local v20 = u9.Character:WaitForChild("Humanoid"):WaitForChild("Animator")
u10 = v20:LoadAnimation(script.Idle)
u10.Priority = Enum.AnimationPriority.Action
u10.Looped = true
u11 = v20:LoadAnimation(script.Attack)
u11.Priority = Enum.AnimationPriority.Action4
u11.Looped = false
end
end
v8.Activated:Connect(function() --[[Anonymous function at line 82]]
--[[
Upvalues:
[1] = u6
[2] = u11
[3] = u7
[4] = u9
--]]
local v22, v23 = pcall(function() --[[Anonymous function at line 87]]
--[[
Upvalues:
[1] = u6
--]]
return u6:Invoke("UseItem")
end)
if v22 and type(v23) == "number" then
if u11 then
u11:Play()
end
u7(("ItemUse/MedusaAttackAnimation/%*"):format(u9.Name), v23 - workspace:GetServerTimeNow())
end
end)
v8.Equipped:Connect(function() --[[Anonymous function at line 102]]
--[[
Upvalues:
[1] = u13
[2] = u14
[3] = u21
[4] = u10
[5] = u4
[6] = u9
[7] = u19
[8] = u1
--]]
if u13 then
u13:Destroy()
end
if u14 then
u14:Disconnect()
end
u21()
u10:Play()
u13 = u4.Ring:Clone()
u13.Name = ("%*.Ring"):format(u9.Name)
u13:PivotTo(u9.Character:GetPivot())
u13.Parent = workspace
u19(true)
local v24 = u9.Character
if v24 then
v24 = v24:FindFirstChildOfClass("Humanoid")
end
if v24 then
v24.Died:Once(function() --[[Anonymous function at line 30]]
--[[
Upvalues:
[1] = u9
[2] = u14
--]]
local v25 = workspace:FindFirstChild((("%*.Ring"):format(u9.Name)))
if v25 then
v25:Destroy()
end
if u14 then
u14:Disconnect()
end
end)
end
u14 = u1.Heartbeat:Connect(function() --[[Anonymous function at line 121]]
--[[
Upvalues:
[1] = u9
[2] = u13
--]]
local v26 = u9.Character
if v26 then
v26 = v26:FindFirstChild("HumanoidRootPart")
end
if v26 and v26.Parent then
if u13 then
u13:PivotTo(v26:GetPivot() * CFrame.new(0, -3, 0))
end
end
end)
end)
v8.Unequipped:Connect(function() --[[Anonymous function at line 133]]
--[[
Upvalues:
[1] = u14
[2] = u19
[3] = u13
[4] = u10
[5] = u11
--]]
if u14 then
u14:Disconnect()
u14 = nil
end
u19(false)
if u14 then
u14:Disconnect()
u14 = nil
end
if u13 then
u13:Destroy()
u13 = nil
end
if u10 and u10.IsPlaying then
u10:Stop()
end
if u11 and u11.IsPlaying then
u11:Stop()
end
end) - Edit
03:12:20.411
- Edit
03:12:20.411
============================== - Edit
03:12:20.411 📜 ReplicatedStorage.Items.Lava Hammer.Controller - Edit
03:12:20.412 ==============================
- Edit
03:12:20.412 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local tool = script.Parent
local cooldowns = {}
local Net = require(ReplicatedStorage.Packages.Net)
local CombatController = Net:RemoteEvent("CombatService/ApplyImpulse")
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://114648214746202"
local animationTrack
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5,5,5)
local cframe = root.CFrame * CFrame.new(0,0,-3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local parts = workspace:FindPartsInRegion3(region, character, 10)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local function applySlap(player: Player, target, direction)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
CombatController:FireClient(targetPlayer, 1200, direction)
RagdollModule.TimedRagdoll(target, 4)
end
tool.Activated:Connect(function()
local char = tool.Parent
local player = game:GetService("Players"):GetPlayerFromCharacter(char)
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < 1 then return end
cooldowns[player.UserId] = os.clock()
local humanoid = char:FindFirstChild("Humanoid")
if humanoid then
animationTrack = humanoid:LoadAnimation(animation)
animationTrack:Play()
end
local dir = char.HumanoidRootPart.CFrame.LookVector
for target in pairs(getTargets(char)) do
applySlap(player, target, dir)
end
end)
tool.Equipped:Connect(function()
local player = script:FindFirstAncestorWhichIsA("Player") or Players:GetPlayerFromCharacter(script.Parent.Parent)
if player and player:GetAttribute("Stealing") then
tool.Parent = player.Backpack
end
end) - Edit
03:12:20.412
- Edit
03:12:20.412
============================== - Edit
03:12:20.412 📜 ReplicatedStorage.Items.Gummy Bear.BloodController - Edit
03:12:20.412 ==============================
- Edit
03:12:20.412 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
-- [FilteringEnabled] Server Scripts are IMPOSSIBLE to save - Edit
03:12:20.412
- Edit
03:12:20.412
============================== - Edit
03:12:20.412 📜 ReplicatedStorage.Items.Subspace Mine.SubspaceMineScript - Edit
03:12:20.412 ==============================
- Edit
03:12:20.412 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
game:GetService("StarterPlayer")
local v1 = game:GetService("ReplicatedStorage")
game:GetService("ServerScriptService")
local v2 = v1:WaitForChild("Packages")
local u3 = require(v2.Net)
require(v2.Debounce)
local v4 = script.Parent
local _ = v4.Parent.Parent
v4.Activated:Connect(function() --[[Anonymous function at line 14]]
--[[
Upvalues:
[1] = u3
--]]
u3:RemoteEvent("UseItem"):FireServer()
end) - Edit
03:12:20.412
- Edit
03:12:20.413
============================== - Edit
03:12:20.414 📜 ReplicatedStorage.ReplicatedGui.Main.Admin.Content.Holder.Traits.Image.LocalScript - Edit
03:12:20.414 ==============================
- Edit
03:12:20.414 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Traits = require(ReplicatedStorage.Datas.Traits)
local TraitIcons = {}
for _, traitData in pairs(Traits) do
table.insert(TraitIcons, traitData.Icon)
end
local ImageLabel = script.Parent
spawn(function()
local index = 1
while true do
ImageLabel.Image = TraitIcons[index]
index = index + 1
if index > #TraitIcons then
index = 1
end
task.wait(1)
end
end)
- Edit
03:12:20.414
- Edit
03:12:20.414
============================== - Edit
03:12:20.414 📜 ReplicatedStorage.ReplicatedGui.SkullEmoji.SkullEmojiTester - Edit
03:12:20.414 ==============================
- Edit
03:12:20.414 -- Saved by UniversalSynSaveInstance (Join to Copy Games) https://discord.gg/wx4ThpAsmw
local v1 = game:GetService("ReplicatedStorage")
local v2 = require(v1.Controllers.SkullEmojiEffectController)
task.wait(1)
while true do
v2:Play()
task.wait(4)
end - Edit
03:12:20.414
- Edit
03:12:20.423
============================== - Edit
03:12:20.423 📜 ServerScriptService.Services.DataManagment - Edit
03:12:20.424 ==============================
- Edit
03:12:20.424 -->> Services
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local HttpService = game:GetService("HttpService")
local Packages = ReplicatedStorage:WaitForChild("Packages")
-->> Modules
local ProfileStore = require(ServerScriptService.Controllers.ProfileStore)
local Synchronizer = require(ReplicatedStorage.Packages.Synchronizer)
local Template = {
Coins = 25000,
Rebirths = 0,
RainbowSpinWheel = {
Spins = 2,
PaidSpins = { x3 = 0 },
LastDailyDiscount = os.time(),
LastFreeClaimed = 0
},
CandySpinWheel = {
Spins = 2,
PaidSpins = { x3 = 0 },
LastDailyDiscount = os.time(),
LastFreeClaimed = 0
},
BloodmoonSpinWheel = {
Spins = 2,
PaidSpins = { x3 = 0 },
LastDailyDiscount = os.time(),
LastFreeClaimed = 0
},
MoltenSpinWheel = {
Spins = 2,
PaidSpins = { x3 = 0},
LastDailyDiscount = os.time(),
LastFreeClaimed = 0
},
GalaxySpinWheel = {
Spins = 2,
PaidSpins = { x3 = 0},
LastDailyDiscount = os.time(),
LastFreeClaimed = 0
},
YinYangSpinWheel = {
Spins = 2,
PaidSpins = { x3 = 0},
LastDailyDiscount = os.time(),
LastFreeClaimed = 0
},
Steals = 0,
Inventory = {},
LastClaimed = os.date("%j"),
Streak = 1,
Gamepass = {},
RainbowEvent = {
LastClaimed = 0,
SkipPurchased = false
},
BoughtStarterPack = false,
AnimalList = {},
Index = {},
LastOnline = workspace:GetServerTimeNow(),
Settings = {
Music = true,
["Sound Effects"] = true,
VFX = true ,
["Chat Tips"] = true,
["Base Skin"] = "Normal"
},
TutorialFinished = true, -- for now, the tutorial is disabled
TutorialProgress = {
StartedAt = 0,
CompletedAt = 0,
CurrentStep = 1,
StepsCompleted = {}
},
HourPickCooldown = 0
}
local GlobalTemplate = {
ActiveEvents = {}
}
local DATASTORE_KEY = "Data"
local ACTIVE_TEMPLATE = Template
local DataStore = ProfileStore.New(DATASTORE_KEY, ACTIVE_TEMPLATE)
local OriginalDataStore = DataStore
local DataStoreModule = {}
local Profiles = {}
local ProfileLoadingStates = {}
local QueuedOperations = {}
local ProfileLoadingBlacklist = {}
local LOADING_STATES = {
NOT_STARTED = "NotStarted",
LOADING = "Loading",
LOADED = "Loaded",
FAILED = "Failed"
}
local function executeQueuedOperations(player)
local queue = QueuedOperations[player]
if queue then
for _, operation in ipairs(queue) do
task.spawn(operation.func, unpack(operation.args))
end
QueuedOperations[player] = nil
end
end
local function queueOperation(player, func, ...)
if not QueuedOperations[player] then
QueuedOperations[player] = {}
end
table.insert(QueuedOperations[player], {
func = func,
args = {...}
})
end
function DataStoreModule.loadProfile(player: Player)
if ProfileLoadingBlacklist[player] then
warn(`[DataStore] Profile loading blocked for blacklisted player: {player.Name}`)
return nil
end
if Profiles[player] and ProfileLoadingStates[player] == LOADING_STATES.LOADED then
return Profiles[player]
end
if ProfileLoadingStates[player] == LOADING_STATES.LOADING then
while ProfileLoadingStates[player] == LOADING_STATES.LOADING do
task.wait(0.1)
end
return Profiles[player]
end
ProfileLoadingStates[player] = LOADING_STATES.LOADING
local maxRetries = 3
local retryDelay = 5
for attempt = 1, maxRetries do
local success, profile = pcall(function()
return DataStore:StartSessionAsync(tostring(player.UserId))
end)
if not success and tostring(profile):find("session") then
if attempt < maxRetries then
task.wait(8)
continue
end
end
if success and profile then
local dataKeyCount = 0
if profile.Data then
for _ in pairs(profile.Data) do
dataKeyCount = dataKeyCount + 1
end
else
print(`[DEBUG] Profile loaded for {player.Name}: No Data found`)
end
local isEmptyProfile = not profile.Data or dataKeyCount == 0 or profile.Data.Coins == nil
local isStudio = RunService:IsStudio()
if isEmptyProfile then
if not profile.Data then
profile.Data = {}
end
local function deepCopy(original)
local copy = {}
for key, value in pairs(original) do
if typeof(value) == "table" then
copy[key] = deepCopy(value)
else
copy[key] = value
end
end
return copy
end
profile.Data = deepCopy(Template)
else
--print(`[DEBUG] Profile for {player.Name} has data, running normal reconcile`)
end
profile:Reconcile()
profile:AddUserId(player.UserId)
local postReconcileKeyCount = 0
if profile.Data then
for _ in pairs(profile.Data) do
postReconcileKeyCount = postReconcileKeyCount + 1
end
end
if profile.Data and profile.Data.Coins ~= nil then
else
local function deepCopy(original)
local copy = {}
for key, value in pairs(original) do
if typeof(value) == "table" then
copy[key] = deepCopy(value)
else
copy[key] = value
end
end
return copy
end
profile.Data = deepCopy(Template)
end
Profiles[player] = profile
ProfileLoadingStates[player] = LOADING_STATES.LOADED
executeQueuedOperations(player)
return profile
else
local errorMsg = if success then "Session conflict" else tostring(profile)
warn(`Failed to load profile for player: {player.Name} (Attempt {attempt}/{maxRetries}): {errorMsg}`)
if attempt < maxRetries then
local waitTime = retryDelay * attempt
if not success or (success and not profile) then
waitTime = waitTime * 2
end
task.wait(waitTime)
end
end
end
ProfileLoadingStates[player] = LOADING_STATES.FAILED
warn(`All attempts failed to load profile for player: {player.Name}. Player will be kicked.`)
player:Kick("Failed to load your data. Please rejoin the game. (Error Code: 267)")
return nil
end
function DataStoreModule.loadProfileAsync(player: Player)
return task.spawn(function()
return DataStoreModule.loadProfile(player)
end)
end
local function safeDataOperation(player: Player, operation)
if ProfileLoadingBlacklist[player] then
warn(`[DataStore] Data operation blocked for blacklisted player: {player.Name}`)
return nil
end
if not player.Parent then
return nil
end
local state = ProfileLoadingStates[player]
if state == LOADING_STATES.LOADED then
return operation()
elseif state == LOADING_STATES.LOADING then
queueOperation(player, operation)
return nil
else
task.spawn(function()
DataStoreModule.loadProfile(player)
end)
queueOperation(player, operation)
return nil
end
end
function DataStoreModule.saveProfile(player: Player)
local profile = Profiles[player]
if profile then
local maxRetries = 3
local retryDelay = 0.5
for attempt = 1, maxRetries do
local success, err = pcall(function()
profile:EndSession()
end)
if success then
break
else
warn(`Failed to end session for player: {player.Name} (Attempt {attempt}/{maxRetries}): {tostring(err)}`)
if attempt < maxRetries then
task.wait(retryDelay * attempt)
end
end
end
Profiles[player] = nil
ProfileLoadingStates[player] = nil
QueuedOperations[player] = nil
ProfileLoadingBlacklist[player] = nil
end
end
function DataStoreModule.getHourPickCooldown(player: Player)
local profile = Profiles[player]
if profile and profile.Data and ProfileLoadingStates[player] == LOADING_STATES.LOADED then
return profile.Data.HourPickCooldown or 0
end
return 0
end
function DataStoreModule.setHourPickCooldown(player: Player, cooldownEndTime: number)
return safeDataOperation(player, function()
local profile = Profiles[player]
if profile and profile.Data then
profile.Data.HourPickCooldown = cooldownEndTime
return true
end
return false
end)
end
function DataStoreModule.addSteals(player: Player, amount: number)
return safeDataOperation(player, function()
local profile = Profiles[player]
if profile and profile.Data then
profile.Data.Steals = (profile.Data.Steals or 0) + math.max(0, math.floor(amount))
end
end)
end
function DataStoreModule.addAnimal(player: Player, animal: string, mutation: string?, traits: string?)
return safeDataOperation(player, function()
local profile = Profiles[player]
if profile and profile.Data then
local PlayerChanel = Synchronizer:Get(player)
local animalList = profile.Data.AnimalList
local maxAnimals = DataStoreModule.GetMaxAnimals(player)
for i = 1, maxAnimals do
if animalList[i] == "Empty" or animalList[i] == nil then
local animalData = {
Index = animal,
LastCollect = workspace:GetServerTimeNow(),
Mutation = mutation,
Steal = false
}
local Animals = require(ReplicatedStorage.Datas.Animals)
local animalInfo = Animals[animal]
if animalInfo and animalInfo.LuckyBlock and animalInfo.LuckyBlock.Timer then
animalData.Timer = animalInfo.LuckyBlock.Timer
end
if traits and traits ~= "" then
if typeof(traits) == "string" then
local success, decodedTraits = pcall(HttpService.JSONDecode, HttpService, traits)
animalData.Traits = success and decodedTraits or nil
else
animalData.Traits = traits
end
end
animalList[i] = animalData
DataStoreModule.addToIndex(player, animal, mutation)
if PlayerChanel then
PlayerChanel:Set("AnimalAddedOrRemoved", animalList)
PlayerChanel:Set("AnimalPodiums", animalList)
end
local PlotsService = require(script.Parent.Plots)
local plot = PlotsService.getPlot(player)
if plot then
plot:SetAnimalList(animalList)
end
return i
end
end
end
end)
end
function DataStoreModule.removeAnimal(player: Player, slot: number)
return safeDataOperation(player, function()
local profile = Profiles[player]
if profile and profile.Data then
local PlayerChannel = Synchronizer:Get(player)
local animalList = profile.Data.AnimalList
if animalList[slot] and typeof(animalList[slot]) == "table" then
local removedAnimal = animalList[slot]
animalList[slot] = "Empty"
if PlayerChannel then
PlayerChannel:Set("AnimalAddedOrRemoved", animalList)
PlayerChannel:Set("AnimalPodiums", animalList)
end
local PlotsService = require(script.Parent.Plots)
local plot = PlotsService.getPlot(player)
if plot then
plot:SetAnimalList(animalList)
end
return removedAnimal
end
end
return nil
end)
end
function DataStoreModule.updateAnimal(player: Player, slot: number, data: table)
return safeDataOperation(player, function()
local profile = Profiles[player]
if profile and profile.Data then
local animalList = profile.Data.AnimalList
if animalList[slot] and typeof(animalList[slot]) == "table" then
for key, value in pairs(data) do
animalList[slot][key] = value
end
local updatedAnimalList = DataStoreModule.getAnimalList(player)
local PlayerChannel = Synchronizer:Get(player)
if PlayerChannel then
PlayerChannel:Set("AnimalAddedOrRemoved", updatedAnimalList)
PlayerChannel:Set("AnimalPodiums", updatedAnimalList)
end
local PlotsService = require(script.Parent.Plots)
local plot = PlotsService.getPlot(player)
if plot then
plot:SetAnimalList(updatedAnimalList)
end
return true
elseif data == "Empty" then
animalList[slot] = "Empty"
local updatedAnimalList = DataStoreModule.getAnimalList(player)
local PlayerChannel = Synchronizer:Get(player)
if PlayerChannel then
PlayerChannel:Set("AnimalAddedOrRemoved", updatedAnimalList)
PlayerChannel:Set("AnimalPodiums", updatedAnimalList)
end
local PlotsService = require(script.Parent.Plots)
local plot = PlotsService.getPlot(player)
if plot then
plot:SetAnimalList(updatedAnimalList)
end
return true
end
end
return false
end)
end
function DataStoreModule.getAnimalList(player: Player)
local profile = Profiles[player]
if profile and profile.Data and ProfileLoadingStates[player] == LOADING_STATES.LOADED then
return profile.Data.AnimalList
end
return {}
end
function DataStoreModule.GetMaxAnimals(player: Player)
local profile = Profiles[player]
if profile and profile.Data and ProfileLoadingStates[player] == LOADING_STATES.LOADED then
local rebirthTier = profile.Data.Rebirths or 0
local Bases = require(ReplicatedStorage.Datas.Bases)
return Bases[rebirthTier].MaxAnimals
end
local Bases = require(ReplicatedStorage.Datas.Bases)
return Bases[0].MaxAnimals
end
function DataStoreModule.GetCoins(player: Player)
local profile = Profiles[player]
if profile and profile.Data and ProfileLoadingStates[player] == LOADING_STATES.LOADED then
return profile.Data.Coins
end
return 0
end
function DataStoreModule.addCoins(player: Player, amount: number)
return safeDataOperation(player, function()
local profile = Profiles[player]
if profile and profile.Data then
profile.Data.Coins = profile.Data.Coins + math.max(0, math.floor(amount))
end
end)
end
function DataStoreModule.SetCoins(player: Player, amount: number)
return safeDataOperation(player, function()
local profile = Profiles[player]
if profile and profile.Data then
profile.Data.Coins = math.max(0, math.floor(amount))
end
end)
end
function DataStoreModule.deductCoins(player: Player, amount: number)
return safeDataOperation(player, function()
local profile = Profiles[player]
if profile and profile.Data then
local deductAmount = math.abs(math.floor(amount))
local currentCoins = profile.Data.Coins
local newCoins = math.max(0, currentCoins - deductAmount)
profile.Data.Coins = newCoins
return newCoins >= 0 and currentCoins >= deductAmount
end
return false
end)
end
function DataStoreModule.deductRebirths(player: Player, amount: number)
return safeDataOperation(player, function()
local profile = Profiles[player]
if profile and profile.Data then
local deductAmount = math.abs(math.floor(amount))
local currentCoins = profile.Data.Rebirths
local newCoins = math.max(0, currentCoins - deductAmount)
profile.Data.Rebirths = newCoins
return newCoins >= 0 and currentCoins >= deductAmount
end
return false
end)
end
function DataStoreModule.GetRebirths(player: Player)
local profile = Profiles[player]
if profile and profile.Data and ProfileLoadingStates[player] == LOADING_STATES.LOADED then
return profile.Data.Rebirths
end
return 0
end
function DataStoreModule.GetDataMan(player: Player)
local profile = Profiles[player]
if profile and profile.Data and ProfileLoadingStates[player] == LOADING_STATES.LOADED then
local dataKeyCount = 0
for _ in pairs(profile.Data) do
dataKeyCount = dataKeyCount + 1
end
local isDataCorrupted = profile.Data.Coins == nil or dataKeyCount == 0
local isStudio = RunService:IsStudio()
if isDataCorrupted then
local function deepCopy(original)
local copy = {}
for key, value in pairs(original) do
if typeof(value) == "table" then
copy[key] = deepCopy(value)
else
copy[key] = value
end
end
return copy
end
profile.Data = deepCopy(Template)
end
return profile.Data
end
return Template
end
function DataStoreModule.addRebirths(player: Player, amount: number)
return safeDataOperation(player, function()
local profile = Profiles[player]
if profile and profile.Data then
profile.Data.Rebirths = profile.Data.Rebirths + math.max(0, math.floor(amount))
end
end)
end
function DataStoreModule.setRebirths(player: Player, amount: number)
return safeDataOperation(player, function()
local profile = Profiles[player]
if profile and profile.Data then
profile.Data.Rebirths = math.max(0, math.floor(amount))
end
end)
end
function DataStoreModule.isDataReady(player: Player)
return ProfileLoadingStates[player] == LOADING_STATES.LOADED
end
function DataStoreModule.waitForData(player: Player, timeout: number?)
timeout = timeout or 30
local startTime = tick()
while ProfileLoadingStates[player] ~= LOADING_STATES.LOADED do
if tick() - startTime > timeout then
warn(`Timeout waiting for data for player: {player.Name}`)
return false
end
if ProfileLoadingStates[player] == LOADING_STATES.FAILED then
return false
end
task.wait(0.1)
end
return true
end
function DataStoreModule.updateLastOnline(player: Player)
return safeDataOperation(player, function()
local profile = Profiles[player]
if profile and profile.Data then
profile.Data.LastOnline = workspace:GetServerTimeNow()
end
end)
end
function DataStoreModule.getLastOnline(player: Player)
local profile = Profiles[player]
if profile and profile.Data and ProfileLoadingStates[player] == LOADING_STATES.LOADED then
return profile.Data.LastOnline or workspace:GetServerTimeNow()
end
return workspace:GetServerTimeNow()
end
function DataStoreModule.GetGlobalData()
return GlobalTemplate
end
function DataStoreModule.calculateOfflineGains(player: Player)
local profile = Profiles[player]
if profile and profile.Data and ProfileLoadingStates[player] == LOADING_STATES.LOADED then
local currentTime = workspace:GetServerTimeNow()
local lastOnline = profile.Data.LastOnline or currentTime
local offlineTime = math.max(0, currentTime - lastOnline)
local GameData = require(ReplicatedStorage:WaitForChild("Datas").Game)
local rebirths = profile.Data.Rebirths or 0
local maxOfflineTime = GameData.Game.OfflineMaxTime[rebirths] or GameData.Game.OfflineMaxTime[0] or 60
offlineTime = math.min(offlineTime, maxOfflineTime)
local animalList = profile.Data.AnimalList or {}
for i, animal in ipairs(animalList) do
if animal and typeof(animal) == "table" then
if offlineTime > 0 then
animalList[i].OfflineGain = offlineTime
else
animalList[i].OfflineGain = nil
end
animalList[i].Steal = false
end
end
profile.Data.AnimalList = animalList
return animalList
end
return {}
end
function DataStoreModule.addToIndex(player: Player, animalIndex: string, mutation: string?)
return safeDataOperation(player, function()
local profile = Profiles[player]
if profile and profile.Data then
if not profile.Data.Index then
profile.Data.Index = {}
end
if not profile.Data.Index[animalIndex] then
profile.Data.Index[animalIndex] = {}
end
local mutationKey = mutation or "Default"
profile.Data.Index[animalIndex][mutationKey] = true
local PlayerChannel = Synchronizer:Get(player)
if PlayerChannel then
PlayerChannel:Set("Index." .. animalIndex, profile.Data.Index[animalIndex])
PlayerChannel:Set("Index", profile.Data.Index)
end
local Animals = require(ReplicatedStorage.Datas.Animals)
local allCandy = true
for id, _ in pairs(Animals) do
if not (profile.Data.Index[id] and profile.Data.Index[id]["Candy"]) then
allCandy = false
break
end
end
local PlotsService = require(script.Parent.Plots)
local plot = PlotsService.getPlot(player)
if plot then
if plot.RefreshMultiplier then
plot:RefreshMultiplier()
end
if allCandy and plot.ApplyCandySkin then
plot:ApplyCandySkin()
elseif not allCandy then
local allRainbow = true
for id, _ in pairs(Animals) do
if not (profile.Data.Index[id] and profile.Data.Index[id]["Rainbow"]) then
allRainbow = false
break
end
end
if allRainbow and plot.ApplyRainbowSkin then
plot:ApplyRainbowSkin()
elseif not allRainbow then
local allDiamond = true
for id, _ in pairs(Animals) do
if not (profile.Data.Index[id] and profile.Data.Index[id]["Diamond"]) then
allDiamond = false
break
end
end
if allDiamond and plot.ApplyDiamondSkin then
plot:ApplyDiamondSkin()
elseif not allDiamond then
local allGold = true
for id, _ in pairs(Animals) do
if not (profile.Data.Index[id] and profile.Data.Index[id]["Gold"]) then
allGold = false
break
end
end
if allGold and plot.ApplyGoldSkin then
plot:ApplyGoldSkin()
end
end
end
end
return true
end
end
return false
end)
end
function DataStoreModule.isTutorialFinished(player: Player)
local profile = Profiles[player]
if profile and profile.Data and ProfileLoadingStates[player] == LOADING_STATES.LOADED then
return profile.Data.TutorialFinished or false
end
return false
end
function DataStoreModule.finishTutorial(player: Player)
return safeDataOperation(player, function()
local profile = Profiles[player]
if profile and profile.Data then
if not profile.Data.TutorialFinished then
profile.Data.TutorialFinished = true
profile.Data.TutorialProgress.CompletedAt = workspace:GetServerTimeNow()
local PlayerChannel = Synchronizer:Get(player)
if PlayerChannel then
PlayerChannel:Set("TutorialFinished", true)
end
DataStoreModule.addCoins(player, 500)
return true
end
end
return false
end)
end
function DataStoreModule.updateTutorialStep(player: Player, step: number)
return safeDataOperation(player, function()
local profile = Profiles[player]
if profile and profile.Data then
if not profile.Data.TutorialProgress then
profile.Data.TutorialProgress = {
StartedAt = workspace:GetServerTimeNow(),
CompletedAt = 0,
CurrentStep = 1,
StepsCompleted = {}
}
end
profile.Data.TutorialProgress.CurrentStep = step
profile.Data.TutorialProgress.StepsCompleted[step] = workspace:GetServerTimeNow()
local PlayerChannel = Synchronizer:Get(player)
if PlayerChannel then
PlayerChannel:Set("TutorialStep", step)
end
return true
end
return false
end)
end
function DataStoreModule.getTutorialProgress(player: Player)
local profile = Profiles[player]
if profile and profile.Data and ProfileLoadingStates[player] == LOADING_STATES.LOADED then
return profile.Data.TutorialProgress or {
StartedAt = 0,
CompletedAt = 0,
CurrentStep = 1,
StepsCompleted = {}
}
end
return {
StartedAt = 0,
CompletedAt = 0,
CurrentStep = 1,
StepsCompleted = {}
}
end
function DataStoreModule.getGamepasses(player: Player)
local profile = Profiles[player]
if profile and profile.Data and ProfileLoadingStates[player] == LOADING_STATES.LOADED then
return profile.Data.Gamepass or {}
end
return {}
end
function DataStoreModule.getDatastoreKey()
return DATASTORE_KEY
end
function DataStoreModule.forceCleanupSession(player: Player)
local profile = Profiles[player]
if profile then
warn(`Force cleaning up stuck session for player: {player.Name}`)
local success, err = pcall(function()
if profile:IsActive() then
profile:Save()
task.wait(1)
profile:EndSession()
end
end)
if not success then
warn(`Force cleanup failed for player: {player.Name}: {tostring(err)}`)
end
Profiles[player] = nil
ProfileLoadingStates[player] = nil
QueuedOperations[player] = nil
end
end
function DataStoreModule.clearStuckSession(player: Player)
task.wait(5)
return true
end
function DataStoreModule.resetPlayerData(player: Player)
local userId = tostring(player.UserId)
local profile = Profiles[player]
ProfileLoadingBlacklist[player] = true
player:Kick("Profile session end - Please rejoin")
if profile then
local sessionEndSuccess = pcall(function()
profile:EndSession()
end)
if not sessionEndSuccess then
warn("[DataStore] Failed to end session for player:", player.Name)
end
if profile.session_token then
local testData = ProfileStore.Test()
if testData and testData.ActiveSessionCheck then
testData.ActiveSessionCheck[profile.session_token] = nil
print("[DataStore] Manually cleared ActiveSessionCheck for:", player.Name)
end
end
Profiles[player] = nil
ProfileLoadingStates[player] = nil
QueuedOperations[player] = nil
local removeSuccess = false
local maxRetries = 3
for attempt = 1, maxRetries do
local success, err = pcall(function()
DataStore:RemoveAsync(userId)
end)
if success then
removeSuccess = true
print("[DataStore] Successfully removed data for player:", player.Name, "on attempt", attempt)
break
else
warn("[DataStore] Failed to remove data for player:", player.Name, "on attempt", attempt, "Error:", err)
end
end
if not removeSuccess then
warn("[DataStore] Failed to remove data for player after all retries:", player.Name)
end
else
warn("[DataStore] No profile found for player:", player.Name, "during reset")
end
ProfileLoadingBlacklist[player] = nil
print("[DataStore] Removed player from loading blacklist:", player.Name)
end
function DataStoreModule.getProfileState(player: Player)
return ProfileLoadingStates[player] or LOADING_STATES.NOT_STARTED
end
local function startPeriodicCleanup()
task.spawn(function()
while true do
task.wait(300)
for player, profile in pairs(Profiles) do
if not player.Parent then
warn(`Found orphaned profile for disconnected player: {player.Name}`)
DataStoreModule.forceCleanupSession(player)
end
end
for player, state in pairs(ProfileLoadingStates) do
if not player.Parent and state == LOADING_STATES.LOADING then
warn(`Found stuck loading state for disconnected player: {player.Name}`)
ProfileLoadingStates[player] = nil
QueuedOperations[player] = nil
ProfileLoadingBlacklist[player] = nil
end
end
end
end)
end
startPeriodicCleanup()
function DataStoreModule.hasGamepass(player: Player, gamepassName: string)
local profile = Profiles[player]
if profile and profile.Data and ProfileLoadingStates[player] == LOADING_STATES.LOADED then
local gamepasses = profile.Data.Gamepass or {}
return gamepasses[gamepassName] == true
end
return false
end
function DataStoreModule.addGamepass(player: Player, gamepassName: string)
return safeDataOperation(player, function()
local profile = Profiles[player]
if profile and profile.Data then
profile.Data.Gamepass = profile.Data.Gamepass or {}
profile.Data.Gamepass[gamepassName] = true
local PlayerChannel = Synchronizer:Get(player)
if PlayerChannel then
PlayerChannel:Set("Gamepass", profile.Data.Gamepass)
end
return true
end
return false
end)
end
function DataStoreModule.removeGamepass(player: Player, gamepassName: string)
return safeDataOperation(player, function()
local profile = Profiles[player]
if profile and profile.Data then
profile.Data.Gamepass = profile.Data.Gamepass or {}
profile.Data.Gamepass[gamepassName] = false
local PlayerChannel = Synchronizer:Get(player)
if PlayerChannel then
PlayerChannel:Set("Gamepass", profile.Data.Gamepass)
end
return true
end
return false
end)
end
function DataStoreModule.updateGamepasses(player: Player, gamepasses: table)
return safeDataOperation(player, function()
local profile = Profiles[player]
if profile and profile.Data then
profile.Data.Gamepass = gamepasses or {}
local PlayerChannel = Synchronizer:Get(player)
if PlayerChannel then
PlayerChannel:Set("Gamepass", profile.Data.Gamepass)
end
return true
end
return false
end)
end
function DataStoreModule.getTotalGeneration(player: Player)
local profile = Profiles[player]
if not (profile and profile.Data and ProfileLoadingStates[player] == LOADING_STATES.LOADED) then
return 0
end
local Animals = require(ReplicatedStorage.Shared.Animals)
local animalList = profile.Data.AnimalList or {}
local totalGeneration = 0
for _, animal in pairs(animalList) do
if animal and typeof(animal) == "table" and animal.Index then
local generation = Animals:GetGeneration(
animal.Index,
animal.Mutation,
animal.Traits or {},
player
)
totalGeneration = totalGeneration + generation
end
end
return math.floor(totalGeneration)
end
return DataStoreModule - Edit
03:12:20.424
- Edit
03:12:20.424
============================== - Edit
03:12:20.424 📜 ServerScriptService.Services.Players - Edit
03:12:20.424 ==============================
- Edit
03:12:20.424 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Data = ReplicatedStorage:WaitForChild("Datas")
local CollectionService = game:GetService("CollectionService")
local Player = game:GetService("Players")
local DataManagment = require(ServerScriptService.Services.DataManagment)
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local Rebirths = require(Data.Rebirth)
local Friends = require(ReplicatedStorage:WaitForChild("Shared").Friends)
local Animals = require(ReplicatedStorage:WaitForChild("Shared").Animals)
local HttpServices = game:GetService("HttpService")
local CommunicationRoute = ReplicatedStorage.Packages.Synchronizer.CommunicationRoute
local PlayerSynchronizers = {}
local Players = {}
function Players.new(player: Player)
if PlayerSynchronizers[player] then
return PlayerSynchronizers[player]
end
if not DataManagment.isDataReady(player) then
local success = DataManagment.waitForData(player, 30)
if not success then
return nil
end
end
local Data = DataManagment.GetDataMan(player)
if not Data then
return nil
end
local success, plot = pcall(function()
local plot = Synchronizer:Create(player, {})
plot:AddListener(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local steals = Instance.new("IntValue")
steals.Name = "Steals"
steals.Value = Data.Steals or 0
steals.Parent = leaderstats
local rebirths = Instance.new("IntValue")
rebirths.Name = "Rebirths"
rebirths.Value = Data.Rebirths or 0
rebirths.Parent = leaderstats
local coins = Instance.new("IntValue")
coins.Name = "Cash"
coins.Value = Data.Coins or 0
coins.Parent = leaderstats
plot:Set("Coins", Data.Coins or 0)
plot:Set("Rebirth", Data.Rebirths or 0)
plot:Set("Spins", Data.BloodmoonSpinWheelSpins or 0)
plot:Set("PaidSpins", Data.BloodmoonSpinWheelPaidSpins or {})
plot:Set("LastDailyDiscount", Data.BloodmoonSpinWheelLastDailyDiscount or 0)
plot:Set("AnimalPodiums", Data.AnimalList or {})
plot:Set("AnimalAddedOrRemoved", Data.AnimalList or {})
plot:Set("Index", Data.Index or {})
plot:Set("TimesJoined", Data.TimesJoined or 1)
plot:Set("Steals", Data.Steals or 0)
plot:Set("Settings",Data.Settings or {})
plot:Set("Items", Data.Items or {})
plot:Set("Gamepass", Data.Gamepass or {})
plot:Set("AutoBuy", {})
if Data.AutoBuySettings then
for itemName, isEnabled in pairs(Data.AutoBuySettings) do
plot:Set("AutoBuy." .. itemName, isEnabled)
end
end
local rainbowSpinWheelData = Data.RainbowSpinWheel or {}
rainbowSpinWheelData.Spins = rainbowSpinWheelData.Spins or 0
rainbowSpinWheelData.PaidSpins = rainbowSpinWheelData.PaidSpins or {}
rainbowSpinWheelData.LastDailyDiscount = rainbowSpinWheelData.LastDailyDiscount or 0
rainbowSpinWheelData.LastFreeClaimed = rainbowSpinWheelData.LastFreeClaimed or 0
plot:Set("RainbowSpinWheel", rainbowSpinWheelData)
local BloodmoonSpinWheelData = Data.BloodmoonSpinWheel or {}
BloodmoonSpinWheelData.Spins = BloodmoonSpinWheelData.Spins or 0
BloodmoonSpinWheelData.PaidSpins = BloodmoonSpinWheelData.PaidSpins or {}
BloodmoonSpinWheelData.LastDailyDiscount = BloodmoonSpinWheelData.LastDailyDiscount or 0
BloodmoonSpinWheelData.LastFreeClaimed = BloodmoonSpinWheelData.LastFreeClaimed or 0
plot:Set("BloodmoonSpinWheel", BloodmoonSpinWheelData)
local CandySpinWheelData = Data.CandySpinWheel or {}
CandySpinWheelData.Spins = CandySpinWheelData.Spins or 0
CandySpinWheelData.PaidSpins = CandySpinWheelData.PaidSpins or {}
CandySpinWheelData.LastDailyDiscount = CandySpinWheelData.LastDailyDiscount or 0
CandySpinWheelData.LastFreeClaimed = CandySpinWheelData.LastFreeClaimed or 0
plot:Set("CandySpinWheel", CandySpinWheelData)
local MoltenSpinWheelData = Data.MoltenSpinWheel or {}
MoltenSpinWheelData.Spins = MoltenSpinWheelData.Spins or 0
MoltenSpinWheelData.PaidSpins = MoltenSpinWheelData.PaidSpins or {}
MoltenSpinWheelData.LastDailyDiscount = MoltenSpinWheelData.LastDailyDiscount or 0
MoltenSpinWheelData.LastFreeClaimed = MoltenSpinWheelData.LastFreeClaimed or 0
plot:Set("MoltenSpinWheel", MoltenSpinWheelData)
local GalaxySpinWheelData = Data.GalaxySpinWheel or {}
GalaxySpinWheelData.Spins = GalaxySpinWheelData.Spins or 0
GalaxySpinWheelData.PaidSpins = GalaxySpinWheelData.PaidSpins or {}
GalaxySpinWheelData.LastDailyDiscount = GalaxySpinWheelData.LastDailyDiscount or 0
GalaxySpinWheelData.LastFreeClaimed = GalaxySpinWheelData.LastFreeClaimed or 0
plot:Set("GalaxySpinWheel", GalaxySpinWheelData)
local rainbowEventData = Data.RainbowEvent or {}
rainbowEventData.LastClaimed = rainbowEventData.LastClaimed or 0
rainbowEventData.SkipPurchased = rainbowEventData.SkipPurchased or false
plot:Set("RainbowEvent", rainbowEventData)
plot:OnChanged("Coins", function(newValue)
coins.Value = newValue or 0
end, true)
plot:OnChanged("Rebirth", function(newValue)
rebirths.Value = newValue or 0
end, true)
plot:OnChanged("Steals", function(newValue)
steals.Value = newValue or 0
end, true)
CommunicationRoute:FireClient(player, {{"ListenerAdded", player}})
return plot
end)
if not success then
return nil
end
PlayerSynchronizers[player] = plot
return plot
end
function Players.getSynchronizer(player: Player)
return PlayerSynchronizers[player]
end
function Players.waitForSynchronizer(player: Player, timeout: number?)
local timeoutValue = timeout or 30
local startTime = tick()
while tick() - startTime < timeoutValue do
if PlayerSynchronizers[player] then
return PlayerSynchronizers[player]
end
task.wait(0.1)
end
return nil
end
function Players.hasSynchronizer(player: Player)
return PlayerSynchronizers[player] ~= nil
end
Player.PlayerRemoving:Connect(function(player)
if PlayerSynchronizers[player] then
PlayerSynchronizers[player]:Destroy()
PlayerSynchronizers[player] = nil
DataManagment.saveProfile(player)
end
end)
for _, player in pairs(Player:GetPlayers()) do
task.spawn(function()
pcall(function()
Players.new(player)
end)
end)
end
Player.PlayerAdded:Connect(function(player)
task.spawn(function()
pcall(function()
Players.new(player)
end)
end)
end)
return Players - Edit
03:12:20.424
- Edit
03:12:20.424
============================== - Edit
03:12:20.424 📜 ServerScriptService.Services.CmdrService - Edit
03:12:20.424 ==============================
- Edit
03:12:20.424 local CmdrService = {}
CmdrService.__index = CmdrService
local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local HttpService = game:GetService("HttpService")
local Cmdr = require(ServerScriptService.Cmdr)
local Configuration = require(script.Configuration)
export type CmdrServiceType = {
_cmdr: any,
_config: any,
_hooks: {[string]: any},
_isInitialized: boolean,
_webhookUrl: string?,
new: () -> CmdrServiceType,
Initialize: (self: CmdrServiceType) -> (),
RegisterDefaultCommands: (self: CmdrServiceType, groups: {string}?) -> (),
RegisterCustomCommand: (self: CmdrServiceType, commandScript: ModuleScript, serverScript: ModuleScript?) -> (),
RegisterCustomCommands: (self: CmdrServiceType) -> (),
RegisterCustomTypes: (self: CmdrServiceType) -> (),
RegisterCustomType: (self: CmdrServiceType, name: string, typeDefinition: any) -> (),
SetActivationKeys: (self: CmdrServiceType, keys: {Enum.KeyCode}) -> (),
IsAuthorized: (self: CmdrServiceType, player: Player) -> boolean,
AddAuthorizedUser: (self: CmdrServiceType, userId: number) -> (),
RemoveAuthorizedUser: (self: CmdrServiceType, userId: number) -> (),
GetCmdr: (self: CmdrServiceType) -> any,
Destroy: (self: CmdrServiceType) -> (),
_RegisterCommandsInSafely: (self: CmdrServiceType, container: Instance) -> (),
SetWebhookUrl: (self: CmdrServiceType, url: string) -> ()
}
function CmdrService.new(): CmdrServiceType
local self = setmetatable({}, CmdrService)
self._cmdr = nil
self._config = Configuration.new()
self._hooks = {}
self._isInitialized = false
self._webhookUrl = nil
return self
end
function CmdrService:Initialize()
if self._isInitialized then
return
end
local success, err = pcall(function()
self._cmdr = Cmdr
local hooksFolder = script:FindFirstChild("Hooks")
if hooksFolder then
self._cmdr.Registry:RegisterHooksIn(hooksFolder)
end
self:_setupAfterRunHook()
end)
self._isInitialized = true
end
function CmdrService:RegisterDefaultCommands(groups: {string}?)
if not self._isInitialized then
end
if groups then
self._cmdr:RegisterDefaultCommands(groups)
else
self._cmdr:RegisterDefaultCommands({"DefaultAdmin", "DefaultDebug", "DefaultUtil"})
end
end
function CmdrService:RegisterCustomCommand(commandScript: ModuleScript, serverScript: ModuleScript?)
if not self._isInitialized then
end
self._cmdr.Registry:RegisterCommand(commandScript, serverScript)
end
function CmdrService:RegisterCustomCommands()
if not self._isInitialized then
end
local customCommandsFolder = script:FindFirstChild("Commands")
if not customCommandsFolder then
return
end
local customCommands = customCommandsFolder:FindFirstChild("CustomCommands")
if not customCommands then
return
end
self:_RegisterCommandsInSafely(customCommands)
end
function CmdrService:_RegisterCommandsInSafely(container)
local successCount = 0
local failureCount = 0
local skippedServerScripts = {}
local usedServerScripts = {}
for _, commandScript in pairs(container:GetChildren()) do
if commandScript:IsA("ModuleScript") then
if not commandScript.Name:find("Server") then
local serverCommandScript = container:FindFirstChild(commandScript.Name .. "Server")
if serverCommandScript then
usedServerScripts[serverCommandScript] = true
end
local success, err = pcall(function()
self._cmdr.Registry:RegisterCommand(commandScript, serverCommandScript)
end)
if success then
successCount = successCount + 1
else
failureCount = failureCount + 1
end
else
skippedServerScripts[commandScript] = true
end
else
self:_RegisterCommandsInSafely(commandScript)
end
end
for skippedScript in pairs(skippedServerScripts) do
if not usedServerScripts[skippedScript] then
end
end
end
function CmdrService:RegisterCustomTypes()
local customTypesFolder = script:FindFirstChild("Types")
if customTypesFolder then
self._cmdr.Registry:RegisterTypesIn(customTypesFolder)
end
end
function CmdrService:RegisterCustomType(name: string, typeDefinition: any)
self._cmdr.Registry:RegisterType(name, typeDefinition)
end
function CmdrService:IsAuthorized(player: Player): boolean
return self._config:IsAuthorized(player)
end
function CmdrService:AddAuthorizedUser(userId: number)
self._config:AddUser(userId)
end
function CmdrService:RemoveAuthorizedUser(userId: number)
self._config:RemoveUser(userId)
end
function CmdrService:GetCmdr()
return self._cmdr
end
function CmdrService:SetWebhookUrl(url: string)
self._webhookUrl = url
end
function CmdrService:_setupAfterRunHook()
self._cmdr.Registry:RegisterHook("AfterRun", function(commandContext)
if self._webhookUrl then
local success, err = pcall(function()
local player = commandContext.Executor
local argsString = table.concat(commandContext.RawArguments or {}, ", ")
local function truncate(str, maxLen)
if #str > maxLen then
return str:sub(1, maxLen - 3) .. "..."
end
return str
end
local commandValue = truncate(tostring(commandContext.Name), 1024)
local argsValue = truncate(argsString ~= "" and argsString or "None", 1024)
local thumbnailUrl
local data = {
content = "",
embeds = {
{
title = truncate("Command Executed", 256),
fields = {
{ name = "Command", value = commandValue, inline = true },
{ name = "Arguments", value = argsValue, inline = true },
},
author = {
name = truncate(player.DisplayName .. " (@" .. player.Name .. ")", 256),
},
timestamp = os.date("!%Y-%m-%dT%H:%M:%SZ")
}
}
}
local payloadJson = HttpService:JSONEncode(data)
if #payloadJson > 6000 then
data.embeds[1].fields[2].value = truncate(argsValue, 512)
payloadJson = HttpService:JSONEncode(data)
end
task.wait(0.5)
local response
for attempt = 1, 3 do
local httpSuccess, httpResult = pcall(function()
return HttpService:PostAsync(self._webhookUrl, payloadJson, Enum.HttpContentType.ApplicationJson)
end)
if httpSuccess then
response = httpResult
break
elseif httpResult:find("429") then
task.wait(1)
else
local minimalData = { content = "Test webhook from CmdrService: " .. commandValue }
pcall(function()
return HttpService:PostAsync(self._webhookUrl, HttpService:JSONEncode(minimalData), Enum.HttpContentType.ApplicationJson)
end)
error("HTTP 400 (Bad Request)")
end
end
return response
end)
if not success then
end
end
return nil
end, 0)
end
function CmdrService:Destroy()
self._cmdr = nil
self._config = nil
self._hooks = {}
self._isInitialized = false
self._webhookUrl = nil
end
return CmdrService - Edit
03:12:20.424
- Edit
03:12:20.425
============================== - Edit
03:12:20.425 📜 ServerScriptService.Services.CmdrService.Configuration - Edit
03:12:20.425 ==============================
- Edit
03:12:20.425 local Configuration = {}
Configuration.__index = Configuration
local Players = game:GetService("Players")
local GroupService = game:GetService("GroupService")
export type ConfigurationType = {
_authorizedUsers: {[number]: boolean},
_authorizedGroups: {[number]: {rankRequired: number}},
_settings: {[string]: any},
new: () -> ConfigurationType,
IsAuthorized: (self: ConfigurationType, player: Player) -> boolean,
AddUser: (self: ConfigurationType, userId: number) -> (),
RemoveUser: (self: ConfigurationType, userId: number) -> (),
AddGroup: (self: ConfigurationType, groupId: number, rankRequired: number?) -> (),
RemoveGroup: (self: ConfigurationType, groupId: number) -> (),
SetSetting: (self: ConfigurationType, key: string, value: any) -> (),
GetSetting: (self: ConfigurationType, key: string) -> any,
}
local DEFAULT_SETTINGS = {
REQUIRE_AUTHORIZATION = true,
GAME_OWNER_AUTHORIZED = true,
ALLOW_GROUP_AUTHORIZATION = true,
LOG_COMMANDS = true,
ANNOUNCE_COMMAND_USAGE = false,
ACTIVATION_KEYS = {Enum.KeyCode.F2, Enum.KeyCode.Quote},
PLACE_NAME = "Admin Console",
MAX_COMMAND_LENGTH = 1000,
RATE_LIMIT_ENABLED = true,
RATE_LIMIT_COMMANDS_PER_MINUTE = 30
}
local DEFAULT_AUTHORIZED_USERS = {
[7424781731] = true, -- aceworkslarp
}
local DEFAULT_AUTHORIZED_GROUPS = {
}
function Configuration.new(): ConfigurationType
local self = setmetatable({}, Configuration)
self._authorizedUsers = {}
self._authorizedGroups = {}
self._settings = {}
self:_loadDefaults()
return self
end
function Configuration:IsAuthorized(player: Player): boolean
if not self:GetSetting("REQUIRE_AUTHORIZATION") then
return true
end
if self:GetSetting("GAME_OWNER_AUTHORIZED") and player.UserId == game.CreatorId then
return true
end
if self._authorizedUsers[player.UserId] then
return true
end
if self:GetSetting("ALLOW_GROUP_AUTHORIZATION") then
for groupId, groupData in pairs(self._authorizedGroups) do
local success, rank = pcall(function()
return player:GetRankInGroup(groupId)
end)
if success and rank >= groupData.rankRequired then
return true
end
end
end
return false
end
function Configuration:AddUser(userId: number)
if type(userId) ~= "number" then
error("Configuration: UserId must be a number!")
end
self._authorizedUsers[userId] = true
end
function Configuration:RemoveUser(userId: number)
if type(userId) ~= "number" then
error("Configuration: UserId must be a number!")
end
self._authorizedUsers[userId] = nil
end
function Configuration:AddGroup(groupId: number, rankRequired: number?)
if type(groupId) ~= "number" then
error("Configuration: GroupId must be a number!")
end
rankRequired = rankRequired or 1
self._authorizedGroups[groupId] = {
rankRequired = rankRequired
}
end
function Configuration:RemoveGroup(groupId: number)
if type(groupId) ~= "number" then
error("Configuration: GroupId must be a number!")
end
self._authorizedGroups[groupId] = nil
end
function Configuration:SetSetting(key: string, value: any)
if type(key) ~= "string" then
error("Configuration: Setting key must be a string!")
end
self._settings[key] = value
end
function Configuration:GetSetting(key: string): any
if type(key) ~= "string" then
error("Configuration: Setting key must be a string!")
end
return self._settings[key]
end
function Configuration:_loadDefaults()
for key, value in pairs(DEFAULT_SETTINGS) do
self._settings[key] = value
end
for userId, authorized in pairs(DEFAULT_AUTHORIZED_USERS) do
if authorized then
self._authorizedUsers[userId] = true
end
end
for groupId, groupData in pairs(DEFAULT_AUTHORIZED_GROUPS) do
self._authorizedGroups[groupId] = groupData
end
end
function Configuration:GetAuthorizedUsers(): {[number]: boolean}
return self._authorizedUsers
end
function Configuration:GetAuthorizedGroups(): {[number]: {rankRequired: number}}
return self._authorizedGroups
end
function Configuration:GetAllSettings(): {[string]: any}
return self._settings
end
return Configuration - Edit
03:12:20.425
- Edit
03:12:20.425
============================== - Edit
03:12:20.425 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.help - Edit
03:12:20.425 ==============================
- Edit
03:12:20.425 return {
Name = "help";
Aliases = {"commands", "cmds"};
Description = "Shows all available admin commands";
Group = "CustomAdmin";
Args = {};
Run = function(context)
local commands = {
{name = "help", aliases = "commands, cmds", description = "Shows this help menu"},
{name = "AddCoins", aliases = "givecoins, addmoney", description = "Adds coins to a player"},
{name = "RemoveCoins", aliases = "takecoins, removemoney", description = "Removes coins from a player"},
{name = "SpawnRoadBrainrot", aliases = "spawnroad, roadspawn", description = "Spawns a specific animal on the road with optional mutation"},
{name = "AddBrainrot", aliases = "givebrainrot, addanimal", description = "Adds any animal to a player's plot"},
{name = "ServerLuck", aliases = "Serverluck, Serverluck", description = "Adds luck to ur server"},
{name = "CreateMerch", aliases = "CreateMerch, MerchCreate", description = "Create a merch!"},--wana go talk on intsta i got phone now
{name = "RemoveBrainrot", aliases = "deletebrainrot, takebrainrot", description = "Removes brainrot from a player"},
--{name = "GiveTool", aliases = "tool", description = "Gives a tool to a player"}
}
local helpText = "🎯 Available Admin Commands:\n\n"
for _, cmd in ipairs(commands) do
helpText = helpText .. string.format(
"• %s (%s)\n %s\n\n",
cmd.name,
cmd.aliases,
cmd.description
)
end
helpText = helpText .. "💡 Tip: Use F2 to open the command console\n"
helpText = helpText .. "📝 Note: Some commands may require additional arguments"
return helpText
end;
} - Edit
03:12:20.425
- Edit
03:12:20.425
============================== - Edit
03:12:20.425 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.addcoins - Edit
03:12:20.425 ==============================
- Edit
03:12:20.425 return {
Name = "addcoins";
Aliases = {"givecoins", "addmoney"};
Description = "Adds coins to a player or group of players";
Group = "CustomAdmin";
Args = {
{
Type = "players";
Name = "players";
Description = "The players to give coins to";
},
{
Type = "integer";
Name = "amount";
Description = "The amount of coins to add (must be positive)";
}
};
} - Edit
03:12:20.425
- Edit
03:12:20.425
============================== - Edit
03:12:20.425 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.addcoinsServer - Edit
03:12:20.425 ==============================
- Edit
03:12:20.425 local ServerScriptService = game:GetService("ServerScriptService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DataManagement = require(ServerScriptService.Services.DataManagment)
local Synchronizer = require(ReplicatedStorage.Packages.Synchronizer)
return function(context, players, amount)
local successCount = 0
local failedPlayers = {}
for _, player in pairs(players) do
if not DataManagement.isDataReady(player) then
table.insert(failedPlayers, player.Name .. " (data not ready)")
continue
end
local currentCoins = DataManagement.GetCoins(player)
DataManagement.addCoins(player, amount)
task.wait(0.1)
local newCoins = DataManagement.GetCoins(player)
if newCoins > currentCoins then
local playerSync = Synchronizer:Get(player)
if playerSync then
playerSync:Set("Coins", newCoins)
end
successCount = successCount + 1
else
table.insert(failedPlayers, player.Name .. string.format(" (coins unchanged: %d)", currentCoins))
end
end
local response = ""
if successCount > 0 then
response = string.format("✅ Successfully added %d coins to %d player%s",
amount, successCount, successCount == 1 and "" or "s")
end
if #failedPlayers > 0 then
if response ~= "" then
response = response .. "\n"
end
response = response .. "❌ Failed for: " .. table.concat(failedPlayers, ", ")
end
if response == "" then
response = "❌ No players were processed"
end
return response
end - Edit
03:12:20.425
- Edit
03:12:20.426
============================== - Edit
03:12:20.426 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.removecoins - Edit
03:12:20.426 ==============================
- Edit
03:12:20.426 return {
Name = "removecoins";
Aliases = {"takecoins", "removemoney"};
Description = "Removes coins from a player or players";
Group = "CustomAdmin";
Args = {
{
Type = "players";
Name = "Players";
Description = "The players to remove coins from";
},
{
Type = "positiveInteger";
Name = "Amount";
Description = "The amount of coins to remove";
}
};
} - Edit
03:12:20.426
- Edit
03:12:20.426
============================== - Edit
03:12:20.426 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.removecoinsServer - Edit
03:12:20.426 ==============================
- Edit
03:12:20.426 local ServerScriptService = game:GetService("ServerScriptService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DataManagement = require(ServerScriptService.Services.DataManagment)
local Synchronizer = require(ReplicatedStorage.Packages.Synchronizer)
return function(context, players, amount)
if amount <= 0 then
return "❌ Amount must be greater than 0!"
end
if amount > math.huge then
return "❌ Amount too large! Maximum is 1,000,000,000 coins."
end
local successCount = 0
local failedPlayers = {}
for _, player in pairs(players) do
if not DataManagement.isDataReady(player) then
table.insert(failedPlayers, player.Name .. " (data not ready)")
continue
end
local currentCoins = DataManagement.GetCoins(player)
if currentCoins < amount then
table.insert(failedPlayers, player.Name .. string.format(" (insufficient coins: %d)", currentCoins))
continue
end
DataManagement.deductCoins(player, amount)
task.wait(0.1)
local newCoins = DataManagement.GetCoins(player)
if newCoins < currentCoins then
local playerSync = Synchronizer:Get(player)
if playerSync then
playerSync:Set("Coins", newCoins)
end
successCount = successCount + 1
else
table.insert(failedPlayers, player.Name .. string.format(" (coins unchanged: %d)", currentCoins))
end
end
local response = ""
if successCount > 0 then
response = string.format("✅ Successfully removed %d coins from %d player%s",
amount, successCount, successCount == 1 and "" or "s")
end
if #failedPlayers > 0 then
if response ~= "" then
response = response .. "\n"
end
response = response .. "❌ Failed for: " .. table.concat(failedPlayers, ", ")
end
if response == "" then
response = "❌ No players were processed"
end
return response
end - Edit
03:12:20.426
- Edit
03:12:20.426
============================== - Edit
03:12:20.426 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.spawnroadbrainrot - Edit
03:12:20.426 ==============================
- Edit
03:12:20.426 return {
Name = "spawnroadbrainrot";
Aliases = {"spawnroad", "roadspawn"};
Description = "Spawns a specific animal on the road with optional mutation";
Group = "CustomAdmin";
Args = {
{
Type = "animalName";
Name = "Animal";
Description = "The animal to spawn on the road";
},
{
Type = "mutationName";
Name = "Mutation";
Description = "The mutation for the animal (optional)";
Optional = true;
}
};
} - Edit
03:12:20.426
- Edit
03:12:20.426
============================== - Edit
03:12:20.426 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.spawnroadbrainrotServer - Edit
03:12:20.427 ==============================
- Edit
03:12:20.427 local MessagingService = game:GetService("MessagingService") local ServerScriptService = game:GetService("ServerScriptService") local ReplicatedStorage = game:GetService("ReplicatedStorage") local HttpService = game:GetService("HttpService") local Animals = require(ReplicatedStorage.Datas.Animals) local Mutations = require(ReplicatedStorage.Datas.Mutations) local Traits = require(ReplicatedStorage.Datas.Traits) local function spawnRoadAnimal(animalName, mutation, traits) local animalData = nil local animalIndex = animalName animalData = Animals[animalIndex] if not animalData then return false, "Animal '" .. animalName .. "' not found" end if mutation and mutation ~= "" and mutation ~= "Default" then if not Mutations[mutation] then return false, "Mutation '" .. mutation .. "' not found" end else mutation = nil end local validatedTraits = nil if traits and traits ~= "" then local success, decodedTraits = pcall(function() return HttpService:JSONDecode(traits) end) if not success or type(decodedTraits) ~= "table" then return false, "Invalid traits format. Use JSON array like '[\"Taco\", \"Fireworks\"]'" end for _, trait in ipairs(decodedTraits) do if not Traits[trait] then return false, "Trait '" .. trait .. "' not found" end end validatedTraits = decodedTraits end local roadService = _G.RoadAnimalService if not roadService or not roadService.Spawner then return false, "RoadAnimalService not available" end local originalCallback = roadService.Spawner.AnimalSpawnedCallback if validatedTraits and #validatedTraits > 0 then print("🔧 DEBUG: Setting up trait callback for traits:", HttpService:JSONEncode(validatedTraits)) roadService.Spawner.AnimalSpawnedCallback = function(animalTemplate, animalData) print("🔧 DEBUG: AnimalSpawnedCallback triggered for:", animalTemplate.Name) if animalTemplate then local traitsJson = HttpService:JSONEncode(validatedTraits) print("🔧 DEBUG: Applying traits to animal:", traitsJson) animalTemplate:SetAttribute("Traits", traitsJson) print("🔧 DEBUG: Traits attribute set. Current value:", animalTemplate:GetAttribute("Traits")) end if originalCallback then originalCallback(animalTemplate, animalData) end roadService.Spawner.AnimalSpawnedCallback = originalCallback end end local result = roadService.Spawner:SpawnSpecificAnimal(animalIndex, nil, mutation) if result == true then return true, "Animal queued for spawning" elseif type(result) == "userdata" then return true, result else return false, "Failed to spawn animal - spawner returned: " .. tostring(result) end end MessagingService:SubscribeAsync("GlobalRoadAnimalSpawn", function(message) local data = message.Data if data.FromServer == game.JobId then return end local success, result = pcall(function() return spawnRoadAnimal(data.AnimalName, data.Mutation, data.Traits) end) if not success then warn("Failed to spawn global road animal:", result) end end) return function(context, animalName, mutation, traits) local animalData = Animals[animalName] if not animalData then return "❌ Animal '" .. animalName .. "' not found" end if mutation and mutation ~= "" and mutation ~= "Default" and not Mutations[mutation] then return "❌ Mutation '" .. mutation .. "' not found" end if traits and traits ~= "" then local success, decodedTraits = pcall(function() return HttpService:JSONDecode(traits) end) if not success or type(decodedTraits) ~= "table" then return "❌ Invalid traits format. Use JSON array like '[\"Taco\", \"Fireworks\"]'" end for _, trait in ipairs(decodedTraits) do if not Traits[trait] then return "❌ Trait '" .. trait .. "' not found" end end end local cleanMutation = (mutation and mutation ~= "" and mutation ~= "Default") and mutation or nil local cleanTraits = (traits and traits ~= "") and traits or nil local success, result = spawnRoadAnimal(animalName, cleanMutation, cleanTraits) if not success then return "❌ Failed to spawn animal locally: " .. tostring(result) end local publishSuccess, publishError = pcall(function() MessagingService:PublishAsync("GlobalRoadAnimalSpawn", { AnimalName = animalName, Mutation = cleanMutation, Traits = cleanTraits, FromServer = game.JobId, Executor = context.Executor.Name }) end) if not publishSuccess then warn("Failed to publish global spawn message:", publishError) return "⚠️ Animal spawned locally but failed to broadcast globally: " .. tostring(publishError) end local traitText = "" if cleanTraits then traitText = " with traits " .. cleanTraits end local mutationText = "" if cleanMutation then mutationText = " (" .. cleanMutation .. ")" end return "✅ Successfully spawned '" .. animalData.DisplayName .. mutationText .. traitText .. "' globally across all servers!" end - Edit
03:12:20.427
- Edit
03:12:20.427
============================== - Edit
03:12:20.427 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.addbrainrot - Edit
03:12:20.427 ==============================
- Edit
03:12:20.427 return {
Name = "addbrainrot";
Aliases = {"givebrainrot", "addanimal"};
Description = "Adds any animal to a player's plot";
Group = "CustomAdmin";
Args = {
{
Type = "players";
Name = "Players";
Description = "The players to give animals to";
},
{
Type = "animalName";
Name = "Animal";
Description = "The animal to add (optional - random if not specified)";
Optional = true;
},
{
Type = "mutationName";
Name = "Mutation";
Description = "The mutation for the animal (optional)";
Optional = true;
}
};
} - Edit
03:12:20.427
- Edit
03:12:20.427
============================== - Edit
03:12:20.427 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.givebttoolServer - Edit
03:12:20.427 ==============================
- Edit
03:12:20.427 local ServerScriptService = game:GetService("ServerScriptService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DataManagement = require(ServerScriptService.Services.DataManagment)
local Animals = require(ReplicatedStorage.Datas.Animals)
local Mutations = require(ReplicatedStorage.Datas.Mutations)
local ServerStorage = game:GetService("ServerStorage")
return function(context, player)
if player ~= nil then
local Bttol = ServerStorage["F3X Btools!"]:Clone()
if Bttol then
Bttol.Parent = player.Backpack
end
end
end - Edit
03:12:20.427
- Edit
03:12:20.427
============================== - Edit
03:12:20.427 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.removebrainrot - Edit
03:12:20.427 ==============================
- Edit
03:12:20.427 return {
Name = "removebrainrot";
Aliases = {"deletebrainrot", "takebrainrot"};
Description = "Removes an animal from a player's slot";
Group = "CustomAdmin";
Args = {
{
Type = "players";
Name = "players";
Description = "The players to remove the animal from";
},
{
Type = "nonEmptySlot";
Name = "slot";
Description = "The slot number to remove the animal from";
};
};
} - Edit
03:12:20.427
- Edit
03:12:20.428
============================== - Edit
03:12:20.428 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.removebrainrotServer - Edit
03:12:20.428 ==============================
- Edit
03:12:20.428 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Animals = require(ReplicatedStorage.Datas.Animals)
local Net = require(ReplicatedStorage.Packages.Net)
return function(context, players, slot)
local ServerScriptService = game:GetService("ServerScriptService")
local DataManagement = require(ServerScriptService.Services.DataManagment)
if not slot or type(slot) ~= "number" or slot < 1 then
return "❌ Invalid slot number provided!"
end
local successCount = 0
local failedPlayers = {}
local results = {}
for _, player in pairs(players) do
if not DataManagement.isDataReady(player) then
table.insert(failedPlayers, player.Name .. " (data not ready)")
continue
end
local animalList = DataManagement.getAnimalList(player)
if not animalList then
table.insert(failedPlayers, player.Name .. " (no animal list)")
continue
end
local animal = animalList[slot]
if not animal or animal == "Empty" or type(animal) ~= "table" or not animal.Index then
table.insert(failedPlayers, player.Name .. " (no animal in slot " .. tostring(slot) .. ")")
continue
end
local animalData = Animals[animal.Index]
if not animalData then
table.insert(failedPlayers, player.Name .. " (invalid animal data for index " .. tostring(animal.Index) .. ")")
continue
end
local success, result = pcall(function()
return DataManagement.removeAnimal(player, slot)
end)
if success and result then
successCount = successCount + 1
table.insert(results, {
player = player,
animal = animalData.DisplayName or animalData.Name or tostring(animal.Index),
slot = slot
})
else
table.insert(failedPlayers, player.Name .. " (removal failed: " .. tostring(result or "unknown error") .. ")")
end
end
local responseLines = {}
if successCount > 0 then
table.insert(responseLines, string.format("✅ Successfully removed animals from %d player(s):", successCount))
for _, result in ipairs(results) do
table.insert(responseLines, string.format(" • %s - %s (slot %d)",
result.player.Name, result.animal, result.slot))
end
end
if #failedPlayers > 0 then
table.insert(responseLines, string.format("❌ Failed for %d player(s): %s",
#failedPlayers, table.concat(failedPlayers, ", ")))
end
if #responseLines == 0 then
return "❌ No players processed successfully!"
end
return table.concat(responseLines, "\n")
end - Edit
03:12:20.428
- Edit
03:12:20.428
============================== - Edit
03:12:20.428 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.pushserverluck - Edit
03:12:20.428 ==============================
- Edit
03:12:20.428 return {
Name = "ServerLuck";
Aliases = {"s"};
Description = "Add a Server Luck to all or only the server ur in";
Group = "CustomAdmin";
Args = {
{
Type = "number";
Name = "Multi";
Description = "The Luck multiplayer";
},
{
Type = "number";
Name = "Duration";
Description = "How long should it last.";
},
{
Type = "string";
Name = "Host";
Description = "Global or Local";
},
};
} - Edit
03:12:20.428
- Edit
03:12:20.428
============================== - Edit
03:12:20.428 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.announceServer - Edit
03:12:20.428 ==============================
- Edit
03:12:20.428 local TextService = game:GetService("TextService")
local Players = game:GetService("Players")
local MessagingService = game:GetService("MessagingService")
local Chat = game:GetService("Chat")
local Net = require(game.ReplicatedStorage.Packages.Net)
local NotificationEvent = Net:RemoteEvent("NotificationService/Notify")
MessagingService:SubscribeAsync("GlobalAnnouncement", function(message)
local data = message.Data
for _, player in ipairs(Players:GetPlayers()) do
NotificationEvent:FireClient(player, data.Text, 5,nil,"Top")
end
end)
return function(context, text)
local fromUserId = context.Executor.UserId
local fromUserName = context.Executor.Name
MessagingService:PublishAsync("GlobalAnnouncement", {
Text = text,
FromUserId = fromUserId,
FromUserName = fromUserName
})
return "Sent global announcement."
end
- Edit
03:12:20.428
- Edit
03:12:20.428
============================== - Edit
03:12:20.428 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.pushserverluckServer - Edit
03:12:20.429 ==============================
- Edit
03:12:20.429 local MessagingService = game:GetService("MessagingService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Net = require(ReplicatedStorage.Packages.Net)
local NotificationEvent = Net:RemoteEvent("NotificationService/Notify")
MessagingService:SubscribeAsync("ServerLuckGlobal", function(message)
local data = message.Data
if data.FromServer == game.JobId then return end
local currentTime = workspace:GetServerTimeNow()
local endTime = currentTime + data.Duration
ReplicatedStorage:SetAttribute("ServerLuckMultiplier", data.Multiplier)
ReplicatedStorage:SetAttribute("ServerLuckEndTime", endTime)
for _, player in pairs(Players:GetPlayers()) do
NotificationEvent:FireClient(player, string.format("🍀 Server Luck globally set to %dx for %d seconds!", data.Multiplier, data.Duration), 5)
end
end)
return function(context, multiplier, duration, scope)
multiplier = tonumber(multiplier)
duration = tonumber(duration)
if not multiplier or not duration then
return "Invalid multiplier or duration."
end
scope = scope and scope:lower() or "local"
local currentTime = workspace:GetServerTimeNow()
local endTime = currentTime + duration
ReplicatedStorage:SetAttribute("ServerLuckMultiplier", multiplier)
ReplicatedStorage:SetAttribute("ServerLuckEndTime", endTime)
for _, player in pairs(Players:GetPlayers()) do
NotificationEvent:FireClient(player, string.format("🍀 Server Luck locally set to %dx for %d seconds!", multiplier, duration), 5)
end
if scope == "global" then
MessagingService:PublishAsync("ServerLuckGlobal", {
Multiplier = multiplier,
Duration = duration,
FromServer = game.JobId
})
return string.format("Server luck set to %dx for %d seconds.", multiplier, duration)
end
return string.format("Server luck set to %dx for %d seconds.", multiplier, duration)
end
- Edit
03:12:20.429
- Edit
03:12:20.429
============================== - Edit
03:12:20.429 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.announce - Edit
03:12:20.429 ==============================
- Edit
03:12:20.429 return {
Name = "announce";
Aliases = {"m"};
Description = "Makes a server-wide announcement.";
Group = "CustomAdmin";
Args = {
{
Type = "string";
Name = "text";
Description = "The announcement text.";
},
};
} - Edit
03:12:20.429
- Edit
03:12:20.429
============================== - Edit
03:12:20.429 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.teleportServer - Edit
03:12:20.429 ==============================
- Edit
03:12:20.429 return function (_, fromPlayers, destination)
local cframe
if typeof(destination) == "Instance" then
if destination.Character and destination.Character:FindFirstChild("HumanoidRootPart") then
cframe = destination.Character.HumanoidRootPart.CFrame
else
return "Target player has no character."
end
elseif typeof(destination) == "Vector3" then
cframe = CFrame.new(destination)
end
for _, player in ipairs(fromPlayers) do
if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
player.Character.HumanoidRootPart.CFrame = cframe
end
end
return ("Teleported %d players."):format(#fromPlayers)
end
- Edit
03:12:20.429
- Edit
03:12:20.429
============================== - Edit
03:12:20.429 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.teleport - Edit
03:12:20.429 ==============================
- Edit
03:12:20.430 return {
Name = "teleport";
Aliases = {"tp"};
Description = "Teleports a player or set of players to one target.";
Group = "CustomAdmin";
AutoExec = {
"alias \"bring|Brings a player or set of players to you.\" teleport $1{players|players|The players to bring} ${me}";
"alias \"to|Teleports you to another player or location.\" teleport ${me} $1{player @ vector3|Destination|The player or location to teleport to}";
};
Args = {
{
Type = "players";
Name = "From";
Description = "The players to teleport";
},
{
Type = "player @ vector3";
Name = "Destination";
Description = "The player to teleport to"
}
};
} - Edit
03:12:20.430
- Edit
03:12:20.430
============================== - Edit
03:12:20.430 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.respawnServer - Edit
03:12:20.430 ==============================
- Edit
03:12:20.430 return function(_, players)
for _, player in pairs(players) do
if player.Character then
player:LoadCharacter()
end
end
return ("Respawned %d players."):format(#players)
end
- Edit
03:12:20.430
- Edit
03:12:20.430
============================== - Edit
03:12:20.430 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.respawn - Edit
03:12:20.430 ==============================
- Edit
03:12:20.430 return {
Name = "respawn";
Description = "Respawns a player or a group of players.";
Group = "CustomAdmin";
AutoExec = {
"alias \"refresh|Respawns the player and returns them to their previous location.\" var= .refresh_pos ${position $1{player|Player}} && respawn $1 && tp $1 @${{var .refresh_pos}}"
},
Args = {
{
Type = "players";
Name = "targets";
Description = "The players to respawn."
}
}
}
- Edit
03:12:20.431
- Edit
03:12:20.431
============================== - Edit
03:12:20.431 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.killServer - Edit
03:12:20.431 ==============================
- Edit
03:12:20.431 return function (_, players)
for _, player in pairs(players) do
if player.Character then
player.Character:BreakJoints()
end
end
return ("Killed %d players."):format(#players)
end - Edit
03:12:20.431
- Edit
03:12:20.431
============================== - Edit
03:12:20.431 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.kill - Edit
03:12:20.431 ==============================
- Edit
03:12:20.431 return {
Name = "kill";
Aliases = {"slay"};
Description = "Kills a player or set of players.";
Group = "CustomAdmin";
Args = {
{
Type = "players";
Name = "victims";
Description = "The players to kill.";
},
};
} - Edit
03:12:20.431
- Edit
03:12:20.431
============================== - Edit
03:12:20.432 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.kickServer - Edit
03:12:20.432 ==============================
- Edit
03:12:20.432 return function (_, players)
for _, player in pairs(players) do
player:Kick("Kicked by admin.")
end
return ("Kicked %d players."):format(#players)
end - Edit
03:12:20.432
- Edit
03:12:20.432
============================== - Edit
03:12:20.432 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.kick - Edit
03:12:20.432 ==============================
- Edit
03:12:20.432 return {
Name = "kick";
Aliases = {"boot"};
Description = "Kicks a player or set of players.";
Group = "CustomAdmin";
Args = {
{
Type = "players";
Name = "players";
Description = "The players to kick.";
},
};
} - Edit
03:12:20.432
- Edit
03:12:20.432
============================== - Edit
03:12:20.433 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.gotoPlaceServer - Edit
03:12:20.433 ==============================
- Edit
03:12:20.433 local TeleportService = game:GetService("TeleportService")
return function(context, players, placeId, jobId)
players = players or { context.Executor }
if placeId <= 0 then
return "Invalid place ID"
elseif jobId == "-" then
return "Invalid job ID"
end
context:Reply("Commencing teleport...")
if jobId then
for _, player in ipairs(players) do
TeleportService:TeleportToPlaceInstance(placeId, jobId, player)
end
else
TeleportService:TeleportAsync(placeId, players)
end
return "Teleported."
end
- Edit
03:12:20.433
- Edit
03:12:20.433
============================== - Edit
03:12:20.433 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.gotoPlace - Edit
03:12:20.433 ==============================
- Edit
03:12:20.433 return {
Name = "goto-place";
Aliases = {};
Description = "Teleport to a Roblox place";
Group = "CustomAdmin";
AutoExec = {
"alias \"follow-player|Join a player in another server\" goto-place $1{players|Players} ${{get-player-place-instance $2{playerId|Target}}}",
"alias \"rejoin|Rejoin this place. You might end up in a different server.\" goto-place $1{players|Players} ${get-player-place-instance ${me} PlaceId}"
};
Args = {
{
Type = "players";
Name = "Players";
Description = "The players you want to teleport";
},
{
Type = "integer";
Name = "Place ID";
Description = "The Place ID you want to teleport to";
},
{
Type = "string";
Name = "JobId";
Description = "The specific JobId you want to teleport to";
Optional = true;
}
};
} - Edit
03:12:20.433
- Edit
03:12:20.433
============================== - Edit
03:12:20.433 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.rainbowevent - Edit
03:12:20.433 ==============================
- Edit
03:12:20.433 return {
Name = "Rainbowevent";
Aliases = {"r"};
Description = "Enabels the Rainbow Event!";
Group = "CustomAdmin";
Args = {
{
Type = "string";
Name = "Host";
Description = "Global or Local";
},
};
} - Edit
03:12:20.433
- Edit
03:12:20.434
============================== - Edit
03:12:20.434 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.removerebirthServer - Edit
03:12:20.434 ==============================
- Edit
03:12:20.434 local ServerScriptService = game:GetService("ServerScriptService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DataManagement = require(ServerScriptService.Services.DataManagment)
local Synchronizer = require(ReplicatedStorage.Packages.Synchronizer)
return function(context, players, amount)
if amount <= 0 then
return "❌ Amount must be greater than 0!"
end
if amount > 1000000000 then
return "❌ Amount too large! Maximum is 1,000,000,000 coins."
end
local successCount = 0
local failedPlayers = {}
for _, player in pairs(players) do
if not DataManagement.isDataReady(player) then
table.insert(failedPlayers, player.Name .. " (data not ready)")
continue
end
local currentCoins = DataManagement.GetRebirths(player)
if currentCoins < amount then
table.insert(failedPlayers, player.Name .. string.format(" (insufficient coins: %d)", currentCoins))
continue
end
DataManagement.deductRebirths(player, amount)
task.wait(0.1)
local newCoins = DataManagement.GetRebirths(player)
if newCoins < currentCoins then
local playerSync = Synchronizer:Get(player)
if playerSync then
playerSync:Set("Rebirths", newCoins)
end
successCount = successCount + 1
else
table.insert(failedPlayers, player.Name .. string.format(" (coins unchanged: %d)", currentCoins))
end
end
local response = ""
if successCount > 0 then
response = string.format("✅ Successfully removed %d coins from %d player%s",
amount, successCount, successCount == 1 and "" or "s")
end
if #failedPlayers > 0 then
if response ~= "" then
response = response .. "\n"
end
response = response .. "❌ Failed for: " .. table.concat(failedPlayers, ", ")
end
if response == "" then
response = "❌ No players were processed"
end
return response
end - Edit
03:12:20.435
- Edit
03:12:20.435
============================== - Edit
03:12:20.435 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.startevent - Edit
03:12:20.435 ==============================
- Edit
03:12:20.435 return {
Name = "startevent";
Aliases = { "startevent" };
Description = "Start an event by name or random event";
Group = "CustomAdmin";
Args = {
{
Type = "string";
Name = "eventName";
Description = "Name of the event to start or 'random' to start random event";
},
{
Type = "integer";
Name = "duration";
Description = "Duration in seconds (optional)";
Optional = true;
}
};
}
- Edit
03:12:20.435
- Edit
03:12:20.435
============================== - Edit
03:12:20.435 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.starteventServer - Edit
03:12:20.435 ==============================
- Edit
03:12:20.435 return function(context, eventName, duration)
local EventService = _G.EventService
if not EventService then
return "EventService is not initialized!"
end
if not eventName then
return "You must specify an event name or 'random'!"
end
eventName = eventName:lower()
if eventName == "random" then
local success = EventService:StartRandomEvent()
if success then
return "Successfully started a random event!"
else
return "Failed to start random event (no events available)"
end
else
local success = EventService:StartEvent(eventName, duration)
if success then
return string.format("Successfully started event: %s", eventName)
else
return string.format("Failed to start event: %s", eventName)
end
end
end
- Edit
03:12:20.435
- Edit
03:12:20.435
============================== - Edit
03:12:20.435 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.resetdata - Edit
03:12:20.436 ==============================
- Edit
03:12:20.436 return {
Name = "resetdata";
Aliases = {"resetplayerdata", "datareset"};
Description = "Resets a player's saved data profile (DataStore) and kicks them so it regenerates.";
Group = "CustomAdmin";
Args = {
{
Type = "players";
Name = "players";
Description = "The player or players whose data will be wiped and regenerated";
},
};
} - Edit
03:12:20.436
- Edit
03:12:20.436
============================== - Edit
03:12:20.436 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.resetdataServer - Edit
03:12:20.436 ==============================
- Edit
03:12:20.436 local DataManagement = require(game.ServerScriptService.Services.DataManagment)
return function(context, players)
local processed = {}
for _, player in ipairs(players) do
if not player or not player.Parent then
table.insert(processed, "❌ " .. (player and player.Name or "") .. " not in server")
continue
end
local success, lastError = DataManagement.resetPlayerData(player)
if success then
table.insert(processed, "✅ " .. player.Name)
else
table.insert(processed, string.format("❌ %s (%s)", player.Name, tostring(lastError)))
end
end
return table.concat(processed, "\n")
end - Edit
03:12:20.436
- Edit
03:12:20.436
============================== - Edit
03:12:20.436 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.unlockindex - Edit
03:12:20.436 ==============================
- Edit
03:12:20.436 return {
Name = "unlockindex";
Aliases = {"unlockpets", "indexunlock"};
Description = "Unlocks every animal in the selected players' Index for the chosen variant (default/rainbow/gold/diamond/candy/all).";
Group = "CustomAdmin";
Args = {
{
Type = "players";
Name = "players";
Description = "Players whose Index will be filled";
},
{
Type = "string";
Name = "variant";
Description = "Variant to unlock: default, rainbow, gold, diamond, candy or all";
},
};
} - Edit
03:12:20.437
- Edit
03:12:20.437
============================== - Edit
03:12:20.437 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.unlockindexServer - Edit
03:12:20.437 ==============================
- Edit
03:12:20.437 local ServerScriptService = game:GetService("ServerScriptService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DataManagement = require(ServerScriptService.Services.DataManagment)
local Animals = require(ReplicatedStorage.Datas.Animals)
local Synchronizer = require(ReplicatedStorage.Packages.Synchronizer)
local VARIANT_MAP = {
default = "Default",
vanilla = "Default",
none = "Default",
raw = "Default",
gold = "Gold",
diamond = "Diamond",
rainbow = "Rainbow",
candy = "Candy",
all = "*"
}
local ALL_VARIANTS = {"Default", "Gold", "Diamond", "Rainbow", "Candy"}
return function(context, players, variantStr)
if not variantStr then
return "❌ You must specify a variant (default/rainbow/gold/diamond/all)"
end
variantStr = string.lower(tostring(variantStr))
local mapped = VARIANT_MAP[variantStr]
if mapped == nil and not (variantStr == "default" or variantStr == "none" or variantStr == "vanilla") then
return string.format("❌ Unknown variant '%s'", variantStr)
end
local unlockVariants = {}
if mapped == "*" then
unlockVariants = ALL_VARIANTS
else
unlockVariants = {mapped}
end
local animalNames = {}
for name, _ in pairs(Animals) do
table.insert(animalNames, name)
end
local successCount = 0
local failedPlayers = {}
for _, player in ipairs(players) do
if not DataManagement.isDataReady(player) then
table.insert(failedPlayers, player.Name .. " (data not ready)")
continue
end
for _, animalName in ipairs(animalNames) do
for _, mut in ipairs(unlockVariants) do
DataManagement.addToIndex(player, animalName, mut)
end
end
local profile = DataManagement.GetDataMan(player)
local sync = Synchronizer:Get(player)
if sync and profile and profile.Data and profile.Data.Index then
sync:Set("Index", profile.Data.Index)
end
successCount = successCount + 1
end
local response = string.format("✅ Unlocked index (%s) for %d player(s)", variantStr, successCount)
if #failedPlayers > 0 then
response ..= "\n❌ Failed for: " .. table.concat(failedPlayers, ", ")
end
return response
end - Edit
03:12:20.437
- Edit
03:12:20.437
============================== - Edit
03:12:20.437 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.startglobalevent - Edit
03:12:20.437 ==============================
- Edit
03:12:20.437 return {
Name = "startglobalevent";
Aliases = {"globalevent", "gevent", "startglobal"};
Description = "Start global events that affect all servers";
Group = "CustomAdmin";
Args = {
{
Type = "string";
Name = "action";
Description = "Action to perform (start, stop, list, status, random)";
},
{
Type = "string";
Name = "eventName";
Description = "Name of the global event (required for start/stop)";
Optional = true;
},
{
Type = "integer";
Name = "duration";
Description = "Duration in seconds (optional for start)";
Optional = true;
}
};
} - Edit
03:12:20.437
- Edit
03:12:20.437
============================== - Edit
03:12:20.437 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.startglobaleventServer - Edit
03:12:20.438 ==============================
- Edit
03:12:20.438 local MessagingService = game:GetService("MessagingService")
local ServerScriptService = game:GetService("ServerScriptService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local function startGlobalEvent(eventName, duration)
local EventService = _G.EventService
if not EventService then
return false, "EventService is not available"
end
if not EventService:GetEventInfo(eventName) then
return false, "Event '" .. eventName .. "' not found"
end
local success = EventService:StartEvent(eventName, duration)
if success then
return true, "Event started successfully"
else
return false, "Failed to start event (may already be active)"
end
end
local function stopGlobalEvent(eventName)
local EventService = _G.EventService
if not EventService then
return false, "EventService is not available"
end
local success = EventService:StopEvent(eventName)
if success then
return true, "Event stopped successfully"
else
return false, "Failed to stop event (may not be active)"
end
end
local function startRandomGlobalEvent()
local EventService = _G.EventService
if not EventService then
return false, "EventService is not available"
end
local success = EventService:StartRandomEvent()
if success then
return true, "Random event started successfully"
else
return false, "Failed to start random event (no events available)"
end
end
local function stopAllGlobalEvents()
local EventService = _G.EventService
if not EventService then
return false, "EventService is not available"
end
local stoppedEvents = EventService:ForceStopAllEvents()
if #stoppedEvents > 0 then
return true, string.format("Stopped %d events: %s", #stoppedEvents, table.concat(stoppedEvents, ", "))
else
return false, "No active events to stop"
end
end
return function(context, action, eventName, duration)
local player = context.Executor
if not _G.GlobalEventSubscriptionsSet then
_G.GlobalEventSubscriptionsSet = true
MessagingService:SubscribeAsync("GlobalEventStart", function(message)
local data = message.Data
if data.FromServer == game.JobId then return end
local success, result = pcall(function()
return startGlobalEvent(data.EventName, data.Duration)
end)
if not success then
warn("Failed to start global event:", result)
end
end)
MessagingService:SubscribeAsync("GlobalEventStop", function(message)
local data = message.Data
if data.FromServer == game.JobId then return end
local success, result = pcall(function()
return stopGlobalEvent(data.EventName)
end)
if not success then
warn("Failed to stop global event:", result)
end
end)
MessagingService:SubscribeAsync("GlobalEventRandom", function(message)
local data = message.Data
if data.FromServer == game.JobId then return end
local success, result = pcall(function()
return startRandomGlobalEvent()
end)
if not success then
warn("Failed to start random global event:", result)
end
end)
MessagingService:SubscribeAsync("GlobalEventStopAll", function(message)
local data = message.Data
if data.FromServer == game.JobId then return end
local success, result = pcall(function()
return stopAllGlobalEvents()
end)
if not success then
warn("Failed to stop all global events:", result)
end
end)
end
action = action:lower()
if action == "start" then
if not eventName then
return "❌ Global event name is required for start action!"
end
local success, result = startGlobalEvent(eventName, duration)
if not success then
return "❌ Failed to start event locally: " .. tostring(result)
end
local publishSuccess, publishError = pcall(function()
MessagingService:PublishAsync("GlobalEventStart", {
EventName = eventName,
Duration = duration,
FromServer = game.JobId,
Executor = context.Executor.Name
})
end)
if not publishSuccess then
warn("Failed to publish global event start message:", publishError)
return "⚠️ Event started locally but failed to broadcast globally: " .. tostring(publishError)
end
return "✅ Successfully started '" .. eventName .. "' globally across all servers!"
elseif action == "stop" then
if not eventName then
return "❌ Global event name is required for stop action!"
end
local success, result = stopGlobalEvent(eventName)
if not success then
return "❌ Failed to stop event locally: " .. tostring(result)
end
local publishSuccess, publishError = pcall(function()
MessagingService:PublishAsync("GlobalEventStop", {
EventName = eventName,
FromServer = game.JobId,
Executor = context.Executor.Name
})
end)
if not publishSuccess then
warn("Failed to publish global event stop message:", publishError)
return "⚠️ Event stopped locally but failed to broadcast globally: " .. tostring(publishError)
end
return "✅ Successfully stopped '" .. eventName .. "' globally across all servers!"
elseif action == "list" then
local EventService = _G.EventService
if not EventService then
return "❌ EventService is not initialized!"
end
local registeredEvents = EventService:GetAllRegisteredEvents()
local eventNames = {}
for name, info in pairs(registeredEvents) do
local status = info.isActive and " (ACTIVE)" or ""
table.insert(eventNames, name .. status)
end
if #eventNames == 0 then
return "No events registered."
end
return "Registered events:\n" .. table.concat(eventNames, "\n")
elseif action == "status" then
local EventService = _G.EventService
if not EventService then
return "❌ EventService is not initialized!"
end
local status = EventService:GetEventStatus()
local activeEvents = EventService:GetActiveEvents()
local result = {
string.format("Event Service Status:"),
string.format("• Registered Events: %d", status.registeredCount),
string.format("• Active Events: %d", status.activeCount)
}
if #status.activeEvents > 0 then
table.insert(result, "\nActive Events:")
for _, eventName in pairs(status.activeEvents) do
local eventInfo = activeEvents[eventName]
local timeRemaining = math.floor(eventInfo.timeRemaining)
table.insert(result, string.format("• %s (%ds remaining)", eventName, timeRemaining))
end
end
return table.concat(result, "\n")
elseif action == "random" then
local success, result = startRandomGlobalEvent()
if not success then
return "❌ Failed to start random event locally: " .. tostring(result)
end
local publishSuccess, publishError = pcall(function()
MessagingService:PublishAsync("GlobalEventRandom", {
FromServer = game.JobId,
Executor = context.Executor.Name
})
end)
if not publishSuccess then
warn("Failed to publish global random event message:", publishError)
return "⚠️ Random event started locally but failed to broadcast globally: " .. tostring(publishError)
end
return "✅ Successfully started a random event globally across all servers!"
elseif action == "stopall" then
local success, result = stopAllGlobalEvents()
if not success then
return "❌ Failed to stop all events locally: " .. tostring(result)
end
local publishSuccess, publishError = pcall(function()
MessagingService:PublishAsync("GlobalEventStopAll", {
FromServer = game.JobId,
Executor = context.Executor.Name
})
end)
if not publishSuccess then
warn("Failed to publish global stop all events message:", publishError)
return "⚠️ Events stopped locally but failed to broadcast globally: " .. tostring(publishError)
end
return "✅ Successfully stopped all events globally across all servers!"
else
return "❌ Invalid action! Use: start, stop, list, status, random, stopall"
end
end - Edit
03:12:20.438
- Edit
03:12:20.438
============================== - Edit
03:12:20.438 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.morph - Edit
03:12:20.438 ==============================
- Edit
03:12:20.438 return {
Name = "morph";
Aliases = {"turnto", "makeme"};
Description = "morphs player";
Group = "CustomAdmin";
Args = {
{
Type = "player";
Name = "Who";
Description = "The player you want to turn in";
},
{
Type = "string";
Name = "PlayerName";
Description = "to what player";
},
};
} - Edit
03:12:20.438
- Edit
03:12:20.438
============================== - Edit
03:12:20.438 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.morphServer - Edit
03:12:20.438 ==============================
- Edit
03:12:20.438 local ServerScriptService = game:GetService("ServerScriptService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local DataManagement = require(ServerScriptService.Services.DataManagment)
local Animals = require(ReplicatedStorage.Datas.Animals)
local Mutations = require(ReplicatedStorage.Datas.Mutations)
return function(context,player,targetplayer)
local targetUserId = Players:GetUserIdFromNameAsync(targetplayer)
if not targetUserId then
return false,"Make Sure You Put the right username Not Display."
end
local Character = player.Character
if not Character then
return
end
local Humanoid, HumanoidRootPart = Character:WaitForChild("Humanoid"), Character:WaitForChild("HumanoidRootPart")
if not Humanoid or not HumanoidRootPart then
return
end
local Appearance = Players:GetHumanoidDescriptionFromUserId(targetUserId)
if not Appearance then
return
end
pcall(function()
Humanoid:ApplyDescription(Appearance)
end)
return "Succesfully Morphed to"..targetplayer
end - Edit
03:12:20.438
- Edit
03:12:20.438
============================== - Edit
03:12:20.438 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.givebttool - Edit
03:12:20.438 ==============================
- Edit
03:12:20.438 return {
Name = "givebttool";
Aliases = {"givebttool", "givebttool"};
Description = "Gives Player the bttool";
Group = "CustomAdmin";
Args = {
{
Type = "player";
Name = "Who";
Description = "The players to give givebttool to";
},
};
} - Edit
03:12:20.439
- Edit
03:12:20.439
============================== - Edit
03:12:20.439 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.addbrainrotServer - Edit
03:12:20.439 ==============================
- Edit
03:12:20.439 local ServerScriptService = game:GetService("ServerScriptService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DataManagement = require(ServerScriptService.Services.DataManagment)
local Animals = require(ReplicatedStorage.Datas.Animals)
local Mutations = require(ReplicatedStorage.Datas.Mutations)
local function getAllAnimals()
local animalList = {}
for animalName, _ in pairs(Animals) do
table.insert(animalList, animalName)
end
return animalList
end
return function(context, players, animalName, mutation)
local selectedAnimal = animalName
if selectedAnimal then
local animalData = Animals[selectedAnimal]
if not animalData then
return string.format("❌ Animal '%s' not found!", selectedAnimal)
end
else
local allAnimals = getAllAnimals()
selectedAnimal = allAnimals[math.random(1, #allAnimals)]
end
if mutation and not Mutations[mutation] then
return string.format("❌ Mutation '%s' not found!", mutation)
end
local successCount = 0
local failedPlayers = {}
local results = {}
for _, player in pairs(players) do
if not DataManagement.isDataReady(player) then
table.insert(failedPlayers, player.Name .. " (data not ready)")
continue
end
local maxAnimals = DataManagement.GetMaxAnimals(player)
local currentAnimals = DataManagement.getAnimalList(player)
local emptySlots = 0
for i = 1, maxAnimals do
if currentAnimals[i] == "Empty" or currentAnimals[i] == nil then
emptySlots = emptySlots + 1
end
end
if emptySlots == 0 then
table.insert(failedPlayers, player.Name .. " (no empty slots)")
continue
end
local success, slotNumber = pcall(function()
return DataManagement.addAnimal(player, selectedAnimal, mutation)
end)
if success and slotNumber then
successCount = successCount + 1
table.insert(results, {
player = player,
animal = selectedAnimal,
mutation = mutation,
slot = slotNumber
})
DataManagement.addToIndex(player, selectedAnimal, mutation)
else
table.insert(failedPlayers, player.Name .. " (operation failed)")
end
end
local responseLines = {}
if successCount > 0 then
local animalData = Animals[selectedAnimal]
local mutationText = mutation and (" with " .. (Mutations[mutation].DisplayText or mutation) .. " mutation") or ""
table.insert(responseLines, string.format("✅ Successfully added %s%s to %d player(s):",
animalData.DisplayName, mutationText, successCount))
for _, result in ipairs(results) do
table.insert(responseLines, string.format(" • %s (slot %d)",
result.player.Name, result.slot))
end
end
if #failedPlayers > 0 then
table.insert(responseLines, string.format("❌ Failed for %d player(s): %s",
#failedPlayers, table.concat(failedPlayers, ", ")))
end
if #responseLines == 0 then
return "❌ No players processed successfully!"
end
return table.concat(responseLines, "\n")
end - Edit
03:12:20.439
- Edit
03:12:20.439
============================== - Edit
03:12:20.439 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.createmerch - Edit
03:12:20.439 ==============================
- Edit
03:12:20.439 return {
Name = "createmerch",
Aliases = {
"cm"
},
Description = "Make a merch code!",
Group = "GameCommands",
Args = {
{
Type = "animalName",
Name = "petname",
Description = "The name of the pet to give."
},
{
Type = "mutationName",
Name = "petmutation",
Description = "Mutation of the pet.",
Optional = true
},
}
} - Edit
03:12:20.439
- Edit
03:12:20.439
============================== - Edit
03:12:20.439 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.createmerchServer - Edit
03:12:20.439 ==============================
- Edit
03:12:20.439 local HttpService = game:GetService("HttpService")
local DataStoreService = game:GetService("DataStoreService")
local MerchDB = DataStoreService:GetDataStore("Merch")
local AnimalData = require(game.ReplicatedStorage.Datas.Animals)
local RNG = Random.new()
local alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
function GenerateMerchCode()
local code = ""
for i = 1, 12 do
local isNumber = RNG:NextInteger(1, 2) == 1
if isNumber then
code = code .. tostring(RNG:NextInteger(0, 9))
else
local int = RNG:NextNumber(1, #alphabet)
code = code .. string.sub(alphabet, int, int)
end
end
return code
end
_G.Webhook = ""
_G.SendWebhook = function(data, boolean)
local thumbnailUrl = "https://www.roblox.com/asset-thumbnail/image?assetId=94747384715091&width=420&height=420&format=png"
if boolean then
local success, response = pcall(function()
return HttpService:PostAsync("", HttpService:JSONEncode(data), Enum.HttpContentType.ApplicationJson)
end)
end
local success, response = pcall(function()
return HttpService:PostAsync(_G.Webhook, HttpService:JSONEncode(data), Enum.HttpContentType.ApplicationJson)
end)
end
return function(_, Pet, Mutation)
if not AnimalData[Pet] then
return false, "Unkown Brainrot!"
end
local AddedPetData = AnimalData[Pet]
local mcList = MerchDB:GetAsync("MerchCodes")
mcList = mcList and HttpService:JSONDecode(mcList)
if mcList == nil then
mcList = {}
MerchDB:SetAsync("MerchCodes", HttpService:JSONEncode(mcList)) -- alr wait me go get my phone can you sc on phone?
end
local code = GenerateMerchCode()
MerchDB:UpdateAsync("MerchCodes", function(old)
old = HttpService:JSONDecode(old)
if not old then
return nil, "no old data??"
end
old[code] = {
code = code,
redeemed = false,
updated = os.time(),
Pet = Pet,
Mutation = Mutation,
}
return HttpService:JSONEncode(old)
end)
local PROXY_SERVER_URL = ""
local MERCH_THUMBNAIL_URL = ""
local function getGifUrlFromProxy(itemName)
local proxyEndpoint = PROXY_SERVER_URL .. "/search-gif?query=" .. HttpService:UrlEncode(itemName)
local success, response = pcall(function()
return HttpService:GetAsync(proxyEndpoint)
end)
if success then
local decodedResponse = HttpService:JSONDecode(response)
if decodedResponse and decodedResponse.gifUrl then
return decodedResponse.gifUrl
else
warn("Proxy did not return a valid GIF URL for:", itemName, decodedResponse.error or "Unknown error.")
return nil
end
else
warn("Failed to contact proxy server for GIF:", response)
return nil
end
end
local gifUrl = getGifUrlFromProxy(AddedPetData.DisplayName)
local finalGifUrl = gifUrl or ""
_G.SendWebhook({
["username"] = "🌟 Merch Drop Alert! 🌟",
["content"] = "**🚀 A brand new merch item just dropped! Don't miss out!**",
["embeds"] = {{
["title"] = "✨ New Merch Unlocked: " .. AddedPetData.DisplayName .. " ✨",
["description"] = "A new merch item was logged",
["timestamp"] = DateTime.now():ToIsoDate(),
["type"] = "rich",
["thumbnail"] = {
["url"] = ""
},
["image"] = {
["url"] = finalGifUrl
},
["color"] = tonumber(0xffbb00),
["fields"] = {
{
["name"] ="🧠 **Animal Name**",
["value"] = AddedPetData.DisplayName,
["inline"] = true
},
{
["name"] ="🔑 **Activation Code**",
["value"] = code,
["inline"] = true
},
{
["name"] = "🧬 **Mutation Applied**",
["value"] = Mutation,
["inline"] = true
}
}
}}
})
return true, code
end
- Edit
03:12:20.440
- Edit
03:12:20.440
============================== - Edit
03:12:20.440 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.spawnroadbrainrotglobal - Edit
03:12:20.440 ==============================
- Edit
03:12:20.440 return {
Name = "spawnroadbrainrotglobal";
Aliases = {"spawnroadglobal", "roadglobal"};
Description = "Spawns a road animal globally across all servers with optional mutation and traits";
Group = "CustomAdmin";
Args = {
{
Type = "animalName";
Name = "animalName";
Description = "The name of the animal to spawn";
};
{
Type = "mutationName";
Name = "mutation";
Description = "Optional mutation for the animal";
Optional = true;
};
{
Type = "string";
Name = "traits";
Description = "Optional traits as JSON array (e.g., '[\"Taco\", \"Fireworks\"]')";
Optional = true;
};
};
} - Edit
03:12:20.440
- Edit
03:12:20.440
============================== - Edit
03:12:20.440 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.spawnroadbrainrotglobalServer - Edit
03:12:20.440 ==============================
- Edit
03:12:20.440 local MessagingService = game:GetService("MessagingService")
local ServerScriptService = game:GetService("ServerScriptService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local HttpService = game:GetService("HttpService")
local Animals = require(ReplicatedStorage.Datas.Animals)
local Mutations = require(ReplicatedStorage.Datas.Mutations)
local Traits = require(ReplicatedStorage.Datas.Traits)
local function spawnRoadAnimal(animalName, mutation, traits)
local animalData = nil
local animalIndex = animalName
animalData = Animals[animalIndex]
if not animalData then
return false, "Animal '" .. animalName .. "' not found"
end
if mutation and mutation ~= "" and mutation ~= "Default" then
if not Mutations[mutation] then
return false, "Mutation '" .. mutation .. "' not found"
end
else
mutation = nil
end
local validatedTraits = nil
if traits and traits ~= "" then
local success, decodedTraits = pcall(function()
return HttpService:JSONDecode(traits)
end)
if not success or type(decodedTraits) ~= "table" then
return false, "Invalid traits format. Use JSON array like '[\"Taco\", \"Fireworks\"]'"
end
for _, trait in ipairs(decodedTraits) do
if not Traits[trait] then
return false, "Trait '" .. trait .. "' not found"
end
end
validatedTraits = decodedTraits
end
local roadService = _G.RoadAnimalService
if not roadService or not roadService.Spawner then
return false, "RoadAnimalService not available"
end
local originalCallback = roadService.Spawner.AnimalSpawnedCallback
if validatedTraits and #validatedTraits > 0 then
print("🔧 DEBUG: Setting up trait callback for traits:", HttpService:JSONEncode(validatedTraits))
roadService.Spawner.AnimalSpawnedCallback = function(animalTemplate, animalData)
print("🔧 DEBUG: AnimalSpawnedCallback triggered for:", animalTemplate.Name)
if animalTemplate then
local traitsJson = HttpService:JSONEncode(validatedTraits)
print("🔧 DEBUG: Applying traits to animal:", traitsJson)
animalTemplate:SetAttribute("Traits", traitsJson)
print("🔧 DEBUG: Traits attribute set. Current value:", animalTemplate:GetAttribute("Traits"))
end
if originalCallback then
originalCallback(animalTemplate, animalData)
end
roadService.Spawner.AnimalSpawnedCallback = originalCallback
end
end
local result = roadService.Spawner:SpawnSpecificAnimal(animalIndex, nil, mutation)
if result == true then
return true, "Animal queued for spawning"
elseif type(result) == "userdata" then
return true, result
else
return false, "Failed to spawn animal - spawner returned: " .. tostring(result)
end
end
MessagingService:SubscribeAsync("GlobalRoadAnimalSpawn", function(message)
local data = message.Data
if data.FromServer == game.JobId then return end
local success, result = pcall(function()
return spawnRoadAnimal(data.AnimalName, data.Mutation, data.Traits)
end)
if not success then
warn("Failed to spawn global road animal:", result)
end
end)
return function(context, animalName, mutation, traits)
local animalData = Animals[animalName]
if not animalData then
return "❌ Animal '" .. animalName .. "' not found"
end
if mutation and mutation ~= "" and mutation ~= "Default" and not Mutations[mutation] then
return "❌ Mutation '" .. mutation .. "' not found"
end
if traits and traits ~= "" then
local success, decodedTraits = pcall(function()
return HttpService:JSONDecode(traits)
end)
if not success or type(decodedTraits) ~= "table" then
return "❌ Invalid traits format. Use JSON array like '[\"Taco\", \"Fireworks\"]'"
end
for _, trait in ipairs(decodedTraits) do
if not Traits[trait] then
return "❌ Trait '" .. trait .. "' not found"
end
end
end
local cleanMutation = (mutation and mutation ~= "" and mutation ~= "Default") and mutation or nil
local cleanTraits = (traits and traits ~= "") and traits or nil
local success, result = spawnRoadAnimal(animalName, cleanMutation, cleanTraits)
if not success then
return "❌ Failed to spawn animal locally: " .. tostring(result)
end
local publishSuccess, publishError = pcall(function()
MessagingService:PublishAsync("GlobalRoadAnimalSpawn", {
AnimalName = animalName,
Mutation = cleanMutation,
Traits = cleanTraits,
FromServer = game.JobId,
Executor = context.Executor.Name
})
end)
if not publishSuccess then
warn("Failed to publish global spawn message:", publishError)
return "⚠️ Animal spawned locally but failed to broadcast globally: " .. tostring(publishError)
end
local traitText = ""
if cleanTraits then
traitText = " with traits " .. cleanTraits
end
local mutationText = ""
if cleanMutation then
mutationText = " (" .. cleanMutation .. ")"
end
return "✅ Successfully spawned '" .. animalData.DisplayName .. mutationText .. traitText .. "' globally across all servers!"
end - Edit
03:12:20.440
- Edit
03:12:20.441
============================== - Edit
03:12:20.441 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.addlimitedstockServer - Edit
03:12:20.441 ==============================
- Edit
03:12:20.441 local DataStoreService = game:GetService("DataStoreService")
local LIMITED_PETS = {
[1] = {
dataStore = DataStoreService:GetDataStore("LimitedPetStore103"),
itemKey = "LimitedPet",
name = "La Vacca Saturno Saturnita",
maxQuantity = 200,
modelName = "LimitedTimePet"
},
[2] = {
dataStore = DataStoreService:GetDataStore("Limited2Pet1053"),
itemKey = "LimitedPet2",
name = "La Grande Combinasion",
maxQuantity = 200,
modelName = "LimitedTimePet2"
},
[3] = {
dataStore = DataStoreService:GetDataStore("Limited2Pet10222"),
itemKey = "LimitedPet3",
name = "Garama and Madundung",
maxQuantity = 362,
modelName = "LimitedTimePet3"
}
}
local function updatePetGui(petConfig, amount)
local model = workspace:FindFirstChild(petConfig.modelName)
if not model then
warn("Model not found: " .. petConfig.modelName)
return
end
local prompt = model:FindFirstChild("Root") and model.Root:FindFirstChild("ProximityPrompt")
local quantityGui = model:FindFirstChild("GuiPart") and model.GuiPart:FindFirstChild("BillboardGui") and model.GuiPart.BillboardGui:FindFirstChild("Quantity")
if quantityGui then
if amount <= 0 then
quantityGui.Text = "Out of Stock!"
quantityGui.TextColor3 = Color3.fromRGB(255, 0, 0)
if prompt then
prompt.Enabled = false
end
else
quantityGui.Text = amount .. "/" .. petConfig.maxQuantity .. " Left!"
quantityGui.TextColor3 = Color3.fromRGB(85, 170, 0)
if prompt then
prompt.Enabled = true
end
end
end
end
return function(context, petNumber, amount)
if petNumber < 1 or petNumber > 3 then
return "❌ Invalid pet number. Use 1, 2, or 3."
end
if amount <= 0 then
return "❌ Amount must be greater than 0."
end
local petConfig = LIMITED_PETS[petNumber]
if not petConfig then
return "❌ Pet configuration not found."
end
local success, result = pcall(function()
return petConfig.dataStore:UpdateAsync(petConfig.itemKey, function(current)
current = current or petConfig.maxQuantity
local newAmount = current + amount
return newAmount
end)
end)
if success and result then
updatePetGui(petConfig, result)
return string.format("✅ Added %d stock to Limited Pet %d (%s). New total: %d",
amount, petNumber, petConfig.name, result)
else
return string.format("❌ Failed to update stock for Limited Pet %d: %s",
petNumber, tostring(result))
end
end - Edit
03:12:20.441
- Edit
03:12:20.441
============================== - Edit
03:12:20.441 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.addlimitedstock - Edit
03:12:20.441 ==============================
- Edit
03:12:20.441 return {
Name = "addlimitedstock";
Aliases = {"addstock", "limitedstock"};
Description = "Adds stock to limited pets (1, 2, or 3)";
Group = "CustomAdmin";
Args = {
{
Type = "number";
Name = "petNumber";
Description = "Which limited pet (1, 2, or 3)";
},
{
Type = "number";
Name = "amount";
Description = "Amount of stock to add";
},
};
} - Edit
03:12:20.441
- Edit
03:12:20.441
============================== - Edit
03:12:20.441 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.addrebirthsServer - Edit
03:12:20.441 ==============================
- Edit
03:12:20.441 local ServerScriptService = game:GetService("ServerScriptService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DataManagement = require(ServerScriptService.Services.DataManagment)
local Synchronizer = require(ReplicatedStorage.Packages.Synchronizer)
return function(context, players, amount)
if amount <= 0 then
return "❌ Amount must be greater than 0!"
end
if amount > 11 then
return "❌ Amount too large!"
end
local successCount = 0
local failedPlayers = {}
for _, player in pairs(players) do
if not DataManagement.isDataReady(player) then
table.insert(failedPlayers, player.Name .. " (data not ready)")
continue
end
local currentCoins = DataManagement.GetRebirths(player)
DataManagement.addRebirths(player, amount)
task.wait(0.1)
local newCoins = DataManagement.GetRebirths(player)
if newCoins > currentCoins then
local playerSync = Synchronizer:Get(player)
if playerSync then
playerSync:Set("Rebirth", newCoins)
end
successCount = successCount + 1
else
table.insert(failedPlayers, player.Name .. string.format(" (coins unchanged: %d)", currentCoins))
end
end
local response = ""
if successCount > 0 then
response = string.format("✅ Successfully added %d coins to %d player%s",
amount, successCount, successCount == 1 and "" or "s")
end
if #failedPlayers > 0 then
if response ~= "" then
response = response .. "\n"
end
response = response .. "❌ Failed for: " .. table.concat(failedPlayers, ", ")
end
if response == "" then
response = "❌ No players were processed"
end
return response
end - Edit
03:12:20.441
- Edit
03:12:20.441
============================== - Edit
03:12:20.441 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.addrebirths - Edit
03:12:20.441 ==============================
- Edit
03:12:20.441 return {
Name = "addrebirths";
Aliases = {"giverebriths", "addrebirths"};
Description = "Adds coins to a player or group of players";
Group = "CustomAdmin";
Args = {
{
Type = "players";
Name = "players";
Description = "The players to give coins to";
},
{
Type = "integer";
Name = "amount";
Description = "The amount of coins to add (must be positive)";
}
};
} - Edit
03:12:20.441
- Edit
03:12:20.442
============================== - Edit
03:12:20.442 📜 ServerScriptService.Services.CmdrService.Commands.CustomCommands.removerebirth - Edit
03:12:20.442 ==============================
- Edit
03:12:20.442 return {
Name = "removerebirths";
Aliases = {"rr"};
Description = "Removes coins from a player or players";
Group = "CustomAdmin";
Args = {
{
Type = "players";
Name = "Players";
Description = "The players to remove coins from";
},
{
Type = "positiveInteger";
Name = "Amount";
Description = "The amount of coins to remove";
}
};
} - Edit
03:12:20.442
- Edit
03:12:20.442
============================== - Edit
03:12:20.442 📜 ServerScriptService.Services.CmdrService.Hooks.BeforeRun - Edit
03:12:20.442 ==============================
- Edit
03:12:20.442 return function(registry)
registry:RegisterHook("BeforeRun", function(context)
local RunService = game:GetService("RunService")
local player = context.Executor
if context.Group == "DefaultUtil" or context.Group == "Help" then
return nil
end
if RunService:IsServer() then
local CmdrService = _G.CmdrService
if CmdrService and not CmdrService:IsAuthorized(player) then
return "You are not authorized to use commands."
end
end
return nil
end, 0)
end - Edit
03:12:20.442
- Edit
03:12:20.442
============================== - Edit
03:12:20.443 📜 ServerScriptService.Services.CmdrService.Types.AnimalName - Edit
03:12:20.443 ==============================
- Edit
03:12:20.443 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Animals = require(ReplicatedStorage.Datas.Animals)
return function(registry)
local animalNameType = {
Transform = function(text)
local animalNames = {}
local matchingAnimals = {}
for animalIndex, animalData in pairs(Animals) do
table.insert(animalNames, animalIndex)
end
local lowerText = text:lower()
for _, animalName in ipairs(animalNames) do
if animalName:lower():find(lowerText, 1, true) then
table.insert(matchingAnimals, animalName)
end
end
table.sort(matchingAnimals, function(a, b)
local aExact = a:lower() == lowerText
local bExact = b:lower() == lowerText
if aExact and not bExact then return true end
if bExact and not aExact then return false end
return a < b
end)
return matchingAnimals
end,
Validate = function(animals)
return #animals > 0, "No animal with that name could be found."
end,
Autocomplete = function(animals)
return animals
end,
Parse = function(animals)
return animals[1]
end,
}
registry:RegisterType("animalName", animalNameType)
end - Edit
03:12:20.443
- Edit
03:12:20.443
============================== - Edit
03:12:20.443 📜 ServerScriptService.Services.CmdrService.Types.MutationName - Edit
03:12:20.443 ==============================
- Edit
03:12:20.443 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Mutations = require(ReplicatedStorage.Datas.Mutations)
return function(registry)
local mutationNameType = {
Transform = function(text)
local mutationNames = {"Default"}
local matchingMutations = {}
for mutationName, mutationData in pairs(Mutations) do
table.insert(mutationNames, mutationName)
end
local lowerText = text:lower()
for _, mutationName in ipairs(mutationNames) do
if mutationName:lower():find(lowerText, 1, true) then
table.insert(matchingMutations, mutationName)
end
end
table.sort(matchingMutations, function(a, b)
local aExact = a:lower() == lowerText
local bExact = b:lower() == lowerText
if aExact and not bExact then return true end
if bExact and not aExact then return false end
return a < b
end)
return matchingMutations
end,
Validate = function(mutations)
return #mutations > 0, "No mutation with that name could be found."
end,
Autocomplete = function(mutations)
return mutations
end,
Parse = function(mutations)
local mutation = mutations[1]
return mutation == "Default" and nil or mutation
end,
}
registry:RegisterType("mutationName", mutationNameType)
end - Edit
03:12:20.443
- Edit
03:12:20.443
============================== - Edit
03:12:20.443 📜 ServerScriptService.Services.CmdrService.Types.NonEmptySlot - Edit
03:12:20.443 ==============================
- Edit
03:12:20.443 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Net = require(ReplicatedStorage.Packages.Net)
return function(registry)
local nonEmptySlotType = {
Transform = function(text, player)
if not player then
return {}
end
local slots = {}
local success, result = pcall(function()
return Net:RemoteFunction("NonEmptySlots/Get"):InvokeServer()
end)
if result and typeof(result) == "table" then
slots = result
else
local DataManagement = require(game.ServerScriptService.Services.DataManagment)
if DataManagement.isDataReady(player) then
local animalList = DataManagement.getAnimalList(player)
if animalList then
for slot, animal in pairs(animalList) do
if animal and animal ~= "Empty" and typeof(animal) == "table" and animal.Index then
table.insert(slots, slot)
end
end
end
end
end
local stringSlots = {}
for _, slot in ipairs(slots) do
table.insert(stringSlots, tostring(slot))
end
table.sort(stringSlots, function(a, b)
local aNum = tonumber(a)
local bNum = tonumber(b)
return aNum < bNum
end)
if not text or text == "" then
return stringSlots
end
local lowerText = text:lower()
local matchingSlots = {}
for _, slot in ipairs(stringSlots) do
if slot:lower():find(lowerText, 1, true) then
table.insert(matchingSlots, slot)
end
end
return matchingSlots
end,
Validate = function(slots)
return #slots > 0, "No non-empty slots found."
end,
Autocomplete = function(slots)
return slots
end,
Parse = function(slots)
return tonumber(slots[1])
end,
}
registry:RegisterType("nonEmptySlot", nonEmptySlotType)
end - Edit
03:12:20.444
- Edit
03:12:20.444
============================== - Edit
03:12:20.444 📜 ServerScriptService.Services.CmdrService.Types.TraitName - Edit
03:12:20.444 ==============================
- Edit
03:12:20.444 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Traits = require(ReplicatedStorage.Datas.Traits)
return function(registry)
local traitNameType = {
Transform = function(text)
local traitNames = {}
local matchingTraits = {}
for traitName, traitData in pairs(Traits) do
table.insert(traitNames, traitName)
end
local lowerText = text:lower()
for _, traitName in ipairs(traitNames) do
if traitName:lower():find(lowerText, 1, true) then
table.insert(matchingTraits, traitName)
end
end
table.sort(matchingTraits, function(a, b)
local aExact = a:lower() == lowerText
local bExact = b:lower() == lowerText
if aExact and not bExact then return true end
if bExact and not aExact then return false end
return a < b
end)
return matchingTraits
end,
Validate = function(traits)
return #traits > 0, "No trait with that name could be found."
end,
Autocomplete = function(traits)
return traits
end,
Parse = function(traits)
return traits[1]
end,
}
registry:RegisterType("traitName", traitNameType)
end - Edit
03:12:20.444
- Edit
03:12:20.444
============================== - Edit
03:12:20.444 📜 ServerScriptService.Services.TutorialService - Edit
03:12:20.444 ==============================
- Edit
03:12:20.444 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local DataManagement = require(script.Parent.DataManagment)
local TutorialService = {}
local FinishTutorialRemote = Net:RemoteEvent("FinishTutorial")
local NotificationEvent = Net:RemoteEvent("NotificationService/Notify")
local TUTORIAL_STEPS = {
STARTED = 1,
FIRST_ANIMAL_SPAWNED = 2,
FIRST_ANIMAL_BOUGHT = 3,
FIRST_ANIMAL_RETURNED = 4,
FIRST_CASH_COLLECTED = 5,
TUTORIAL_COMPLETED = 6
}
FinishTutorialRemote.OnServerEvent:Connect(function(player: Player)
if not player or not player.Parent then
return
end
if DataManagement.isTutorialFinished(player) then
return
end
local success = DataManagement.finishTutorial(player)
if success then
local playerChannel = Synchronizer:Get(player)
if playerChannel then
playerChannel:Set("TutorialFinished", true)
else
warn(`[DEBUG SERVER] Could not find player channel for {player.Name}`)
end
local message = "Tutorial Complete! You're ready to play!"
NotificationEvent:FireClient(player, message, 5)
else
warn(`[DEBUG SERVER] Failed to finish tutorial for {player.Name}`)
end
end)
function TutorialService.initializePlayerTutorial(player: Player)
if not DataManagement.waitForData(player, 10) then
return
end
if DataManagement.isTutorialFinished(player) then
local playerChannel = Synchronizer:Get(player)
if playerChannel then
playerChannel:Set("TutorialFinished", true)
end
return
end
local progress = DataManagement.getTutorialProgress(player)
if progress.StartedAt == 0 then
DataManagement.updateTutorialStep(player, TUTORIAL_STEPS.STARTED)
end
local playerChannel = Synchronizer:Get(player)
if playerChannel then
playerChannel:Set("TutorialFinished", false)
playerChannel:Set("TutorialStep", progress.CurrentStep)
else
warn(`[DEBUG] No player channel found for {player.Name}`)
end
end
function TutorialService.playerJoined(player: Player)
task.spawn(function()
task.wait(1)
TutorialService.initializePlayerTutorial(player)
end)
end
function TutorialService.playerLeft(player: Player)
end
Players.PlayerAdded:Connect(TutorialService.playerJoined)
Players.PlayerRemoving:Connect(TutorialService.playerLeft)
for _, player in ipairs(Players:GetPlayers()) do
TutorialService.playerJoined(player)
end
TutorialService.STEPS = TUTORIAL_STEPS
return TutorialService - Edit
03:12:20.444
- Edit
03:12:20.444
============================== - Edit
03:12:20.444 📜 ServerScriptService.Services.Tips - Edit
03:12:20.444 ==============================
- Edit
03:12:20.444 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local TextChatService = game:GetService("TextChatService")
local Data = ReplicatedStorage.Datas
local TipsData = require(Data.Tips)
local TipsHandler = {}
TipsHandler.__index = TipsHandler
function TipsHandler.new()
local self = setmetatable({}, TipsHandler)
self._tips = TipsData
self._timers = {}
self:_setupPlayerEvents()
self:_startTipCycles()
return self
end
function TipsHandler:_setupPlayerEvents()
Players.PlayerAdded:Connect(function(player)
self:_startPlayerTipCycle(player)
end)
Players.PlayerRemoving:Connect(function(player)
self:_stopPlayerTipCycle(player)
end)
for _, player in ipairs(Players:GetPlayers()) do
task.spawn(function()
self:_startPlayerTipCycle(player)
end)
end
end
function TipsHandler:_startTipCycles()
for _, tip in ipairs(self._tips) do
task.spawn(function()
while true do
task.wait(tip.ShowEvery)
for _, player in ipairs(Players:GetPlayers()) do
self:_showTip(player, tip.ChatMessage)
end
end
end)
end
end
function TipsHandler:_startPlayerTipCycle(player)
local timers = {}
for index, tip in ipairs(self._tips) do
timers[index] = task.spawn(function()
while true do
task.wait(tip.ShowEvery)
self:_showTip(player, tip.ChatMessage)
end
end)
end
self._timers[player.UserId] = timers
end
function TipsHandler:_stopPlayerTipCycle(player)
local timers = self._timers[player.UserId]
if timers then
for _, timer in pairs(timers) do
task.cancel(timer)
end
self._timers[player.UserId] = nil
end
end
function TipsHandler:_showTip(player, message)
local success, err = pcall(function()
local chatChannel = TextChatService.TextChannels.RBXGeneral
if chatChannel then
chatChannel:DisplaySystemMessage(message)
end
end)
if not success then
-- warn("[TipsHandler] Failed to send tip to " .. player.Name .. ": " .. tostring(err))
end
end
return TipsHandler - Edit
03:12:20.444
- Edit
03:12:20.444
============================== - Edit
03:12:20.445 📜 ServerScriptService.Services.Plots - Edit
03:12:20.445 ==============================
- Edit
03:12:20.445 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local PlotConstants = require(script.PlotConstants)
local PlotManager = require(script.PlotManager)
local PlotSynchronizer = require(script.PlotSynchronizer)
local AnimalStealing = require(script.AnimalStealing)
local AnimalGrabbing = require(script.AnimalGrab)
local LuckyBlockTimerManager = require(script.LuckyBlockTimerManager)
local DataManagement = require(ServerScriptService.Services.DataManagment)
local Net = require(ReplicatedStorage.Packages.Net)
local Synchronizer = require(ReplicatedStorage.Packages.Synchronizer)
local Rebirths = require(ReplicatedStorage.Datas.Rebirth)
local Animals = require(ReplicatedStorage.Shared.Animals)
local BaseLockController = require(ServerScriptService.Controllers.BaseLockController)
BaseLockController:Start()
local PlotsService = {}
local plotSynchronizer = nil
local plotManager = nil
local animalStealing = nil
local animalGrabbing = nil
local luckyBlockTimerManager = nil
local ToggleFriends = Net:RemoteEvent("PlotService/ToggleFriends")
local Claim = Net:RemoteEvent("PlotService/ClaimCoins")
local CashCollected = Net:RemoteEvent("PlotService/CashCollected")
local Sell = Net:RemoteEvent("PlotService/Sell")
local RebirthRemote = Net:RemoteFunction("Rebirth/RequestRebirth")
function PlotsService.Initialize()
plotSynchronizer = PlotSynchronizer.new()
plotManager = PlotManager.new(plotSynchronizer)
animalStealing = AnimalStealing.new(plotManager)
animalGrabbing = AnimalGrabbing.new(plotManager)
luckyBlockTimerManager = LuckyBlockTimerManager.new(plotManager)
luckyBlockTimerManager:Start()
PlotsService._setupRemoteHandlers()
end
function PlotsService._setupRemoteHandlers()
ToggleFriends.OnServerEvent:Connect(function(player)
local success, newState = pcall(function()
local plot = plotManager:GetPlayerPlot(player)
if not plot then
warn("[PlotsService] No plot found for ToggleFriends: " .. player.Name)
return false
end
local security = plotManager:GetSecurityManager(plot)
if not security then
warn("[PlotsService] No security manager found for plot: " .. plot:GetUUID())
return false
end
return security:ToggleFriendsAccess()
end)
if success then
print("[PlotsService] Friends access toggled for " .. player.Name .. ": " .. tostring(newState))
else
warn("[PlotsService] Failed to toggle friends for " .. player.Name .. ": " .. tostring(newState))
end
end)
Claim.OnServerEvent:Connect(function(player, slot)
if not DataManagement.isDataReady(player) then
warn("[PlotsService] Player data not ready for claim: " .. player.Name)
return
end
local success, totalCoins = pcall(function()
local plot = plotManager:GetPlayerPlot(player)
if not plot then
warn("[PlotsService] No plot found for claim: " .. player.Name)
return 0
end
if plot:GetOwner() ~= player then
warn("[PlotsService] Player " .. player.Name .. " trying to claim from non-owned plot")
return 0
end
local animalManager = plotManager:GetAnimalManager(plot)
if not animalManager then
warn("[PlotsService] No animal manager found for plot: " .. plot:GetUUID())
return 0
end
local claimSuccess, coins = animalManager:ClaimCoins(slot)
if claimSuccess then
CashCollected:FireClient(player)
return coins
end
return 0
end)
if success and totalCoins > 0 then
elseif not success then
warn("[PlotsService] Error in claim process: " .. tostring(totalCoins))
end
end)
Sell.OnServerEvent:Connect(function(player, slot)
if not DataManagement.isDataReady(player) then
warn("[PlotsService] Player data not ready for sell: " .. player.Name)
return
end
local success, sellValue = pcall(function()
local plot = plotManager:GetPlayerPlot(player)
if not plot then
warn("[PlotsService] No plot found for sell: " .. player.Name)
return 0
end
if plot:GetOwner() ~= player then
warn("[PlotsService] Player " .. player.Name .. " trying to sell from non-owned plot")
return 0
end
local animalManager = plotManager:GetAnimalManager(plot)
if not animalManager then
warn("[PlotsService] No animal manager found for plot: " .. plot:GetUUID())
return 0
end
local sellSuccess, value = animalManager:SellAnimal(slot)
return sellSuccess and value or 0
end)
if success and sellValue > 0 then
elseif not success then
warn("[PlotsService] Error in sell process: " .. tostring(sellValue))
end
end)
RebirthRemote.OnServerInvoke = function(player)
return PlotsService._handleRebirth(player)
end
end
function PlotsService._handleRebirth(player)
local success, result, message = pcall(function()
local data = DataManagement.GetDataMan(player)
if not data then
return false, "There was an error loading your data, Please rejoin."
end
local playerSync = Synchronizer:Get(player)
if not playerSync then
return false, "Failed to get player synchronizer"
end
local currentRebirth = data.Rebirths or 0
local nextRebirth = currentRebirth + 1
if not Rebirths[nextRebirth] then
return false, "You are already at the highest rebirth level."
end
local requirements = Rebirths[nextRebirth].Requirements
if data.Coins < requirements.Cash then
return false, "You need to meet all requirements before you can rebirth!"
end
local ownedAnimals = data.AnimalList
for _, requiredAnimal in ipairs(requirements.RequiredCharacters) do
local found = false
for _, animal in ipairs(ownedAnimals) do
if animal.Index == requiredAnimal then
found = true
break
end
end
if not found then
return false, "You need to meet all requirements before you can rebirth!"
end
end
data.Coins = data.Coins - requirements.Cash
data.Rebirths = data.Rebirths + 1
local Bases = require(ReplicatedStorage.Datas.Bases)
local maxAnimals = Bases[data.Rebirths].MaxAnimals
for i = 1, maxAnimals do
data.AnimalList[i] = PlotConstants.STATES.EMPTY
end
local plotUpdateSuccess = plotManager:HandlePlayerRebirth(player, data.Rebirths)
if not plotUpdateSuccess then
warn("[PlotsService] Failed to update plot for rebirth - reverting data changes")
data.Coins = data.Coins + requirements.Cash
data.Rebirths = data.Rebirths - 1
return false, "Plot update failed during rebirth"
end
if playerSync then
playerSync:Set("Rebirth", data.Rebirths)
playerSync:Set("Coins", data.Coins)
task.spawn(function()
task.wait(0.1)
playerSync:Set("AnimalAddedOrRemoved", data.AnimalList)
task.wait(0.05)
playerSync:Set("AnimalPodiums", data.AnimalList)
end)
end
return true, PlotConstants.SUCCESS.REBIRTH_SUCCESS .. " " .. data.Rebirths
end)
if success then
return result, message
else
warn("[PlotsService] Rebirth error for " .. player.Name .. ": " .. tostring(result))
return false, "Rebirth failed due to server error"
end
end
function PlotsService.HandlePlayerRebirth(player, rebirthLevel)
if not plotManager then
warn("[PlotsService] PlotManager not initialized")
return false
end
return plotManager:HandlePlayerRebirth(player, rebirthLevel)
end
function PlotsService.getPlotManager()
return plotManager
end
function PlotsService.CreatePlot(player)
if not plotManager then
warn("[PlotsService] PlotManager not initialized")
return nil
end
return plotManager:CreatePlayerPlot(player)
end
function PlotsService.getPlot(player)
if not plotManager then
return nil
end
return plotManager:GetPlayerPlot(player)
end
function PlotsService.getPlotModel(player)
if not plotManager then
return nil
end
return plotManager:GetPlayerPlotModel(player)
end
function PlotsService.getPlotByUUID(uuid)
if not plotManager then
return nil
end
return plotManager:GetPlotByUUID(uuid)
end
function PlotsService.PlayerHasFreeAnimalSlot(player)
if not plotManager then
warn("[PlotsService] PlotManager not initialized")
return false
end
local plot = plotManager:GetPlayerPlot(player)
if not plot then
warn("[PlotsService] No plot found for player: " .. player.Name)
return false
end
local animalManager = plotManager:GetAnimalManager(plot)
if not animalManager then
warn("[PlotsService] No animal manager found for plot: " .. plot:GetUUID())
return false
end
local animalList = animalManager:GetAnimalList() -- should return player's animals
for _, slot in ipairs(animalList) do
if slot == PlotConstants.STATES.EMPTY then
return true -- found a free slot
end
end
return false -- no free slots
end
function PlotsService.GetStats()
local stats = {
initialized = plotManager ~= nil,
plotManager = nil,
plotSynchronizer = nil,
animalStealing = nil,
luckyBlockTimerManager = luckyBlockTimerManager ~= nil
}
if plotManager then
stats.plotManager = plotManager:GetStats()
end
if plotSynchronizer then
stats.plotSynchronizer = plotSynchronizer:GetStats()
end
return stats
end
function PlotsService.ValidateAll()
local report = {
components = {
plotManager = false,
plotSynchronizer = false,
animalStealing = false,
luckyBlockTimerManager = false
},
plotValidation = nil,
issues = {}
}
report.components.plotManager = plotManager ~= nil
report.components.plotSynchronizer = plotSynchronizer ~= nil
report.components.animalStealing = animalStealing ~= nil
report.components.luckyBlockTimerManager = luckyBlockTimerManager ~= nil
if plotManager then
report.plotValidation = plotManager:ValidateAllPlots()
else
table.insert(report.issues, "PlotManager not initialized")
end
return report
end
function PlotsService.EmergencyCleanup()
local report = {
plotManagerCleanup = nil,
synchronizerCleanup = nil,
luckyBlockTimerCleanup = nil,
reinitialized = false
}
if plotManager then
report.plotManagerCleanup = plotManager:EmergencyRepair()
end
if plotSynchronizer then
local syncStats = plotSynchronizer:GetStats()
plotSynchronizer:Cleanup()
report.synchronizerCleanup = {
cleanedPlots = syncStats.activePlots
}
end
if luckyBlockTimerManager then
luckyBlockTimerManager:Stop()
report.luckyBlockTimerCleanup = true
end
if not plotManager or not plotSynchronizer then
PlotsService.Initialize()
report.reinitialized = true
end
return report
end
function PlotsService.GetLuckyBlockTimerManager()
return luckyBlockTimerManager
end
function PlotsService.IsLuckyBlockReady(player, slot)
if not luckyBlockTimerManager then
return false
end
return luckyBlockTimerManager:IsLuckyBlockReady(player, slot)
end
function PlotsService.GetLuckyBlockTimer(player, slot)
if not luckyBlockTimerManager then
return nil
end
return luckyBlockTimerManager:GetLuckyBlockTimer(player, slot)
end
PlotsService.new = PlotsService.CreatePlot
PlotsService.Initialize()
return PlotsService - Edit
03:12:20.445
- Edit
03:12:20.445
============================== - Edit
03:12:20.445 📜 ServerScriptService.Services.Plots.AnimalStealing - Edit
03:12:20.445 ==============================
- Edit
03:12:20.445 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local ServerStorage = game:GetService("ServerStorage")
local Players = game:GetService("Players")
local CollectionService = game:GetService("CollectionService")
local HttpService = game:GetService("HttpService")
local Packages = ReplicatedStorage.Packages
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local DataManagment = require(ServerScriptService.Services.DataManagment)
local Animals = require(ReplicatedStorage.Shared.Animals)
local PlotConstants = require(script.Parent.PlotConstants)
local AnimalStealing = {}
AnimalStealing.__index = AnimalStealing
function AnimalStealing.new(plotManager)
local self = setmetatable({}, AnimalStealing)
self.plotManager = plotManager
self.playerStolenModels = {}
self.playerCarryAnimTracks = {}
self.deliveryDebounce = {}
self.stealNotificationDebounce = {}
self.alreadyStealingDebounce = {}
self.capacityFullDebounce = {}
self:_setupRemoteEvents()
self:_setupPlayerConnections()
self:_setupToolStorage()
return self
end
-- New function to setup tool storage system
function AnimalStealing:_setupToolStorage()
-- Create main storage folder if it doesn't exist
local toolStorageFolder = ServerStorage:FindFirstChild("PlayerToolStorage")
if not toolStorageFolder then
toolStorageFolder = Instance.new("Folder")
toolStorageFolder.Name = "PlayerToolStorage"
toolStorageFolder.Parent = ServerStorage
end
end
-- New function to store player tools when stealing starts
function AnimalStealing:_storePlayerTools(player)
if not player or not player.Character then
warn("[AnimalStealing] Cannot store tools - player or character invalid")
return false
end
local backpack = player:FindFirstChild("Backpack")
if not backpack then
warn("[AnimalStealing] Cannot store tools - backpack not found for player:", player.Name)
return false
end
-- Create storage folder structure
local toolStorageFolder = ServerStorage:FindFirstChild("PlayerToolStorage")
if not toolStorageFolder then
self:_setupToolStorage()
toolStorageFolder = ServerStorage:FindFirstChild("PlayerToolStorage")
end
-- Use UserId as folder name for better reliability
local playerStorageFolder = toolStorageFolder:FindFirstChild(tostring(player.UserId))
if not playerStorageFolder then
playerStorageFolder = Instance.new("Folder")
playerStorageFolder.Name = tostring(player.UserId)
playerStorageFolder.Parent = toolStorageFolder
-- Add metadata
playerStorageFolder:SetAttribute("PlayerName", player.Name)
playerStorageFolder:SetAttribute("StorageTime", workspace:GetServerTimeNow())
else
-- Clear existing tools in storage (safety measure)
for _, existingTool in pairs(playerStorageFolder:GetChildren()) do
if existingTool:IsA("Tool") then
existingTool:Destroy()
end
end
end
local storedCount = 0
local totalTools = 0
-- Store tools from backpack
for _, tool in pairs(backpack:GetChildren()) do
if tool:IsA("Tool") then
totalTools = totalTools + 1
local success = pcall(function()
-- Clone the tool to preserve original data
local toolClone = tool:Clone()
toolClone.Parent = playerStorageFolder
-- Remove original tool from backpack
tool:Destroy()
storedCount = storedCount + 1
end)
if not success then
warn("[AnimalStealing] Failed to store tool:", tool.Name, "for player:", player.Name)
end
end
end
-- Also check for equipped tool in character
local equippedTool = player.Character:FindFirstChildOfClass("Tool")
if equippedTool then
totalTools = totalTools + 1
local success = pcall(function()
local toolClone = equippedTool:Clone()
toolClone.Parent = playerStorageFolder
equippedTool:Destroy()
storedCount = storedCount + 1
end)
if not success then
warn("[AnimalStealing] Failed to store equipped tool:", equippedTool.Name, "for player:", player.Name)
end
end
playerStorageFolder:SetAttribute("StoredToolCount", storedCount)
playerStorageFolder:SetAttribute("LastUpdated", workspace:GetServerTimeNow())
return storedCount > 0
end
-- New function to restore player tools when stealing ends
function AnimalStealing:_restorePlayerTools(player)
if not player or not player.Character then
return false
end
local backpack = player:FindFirstChild("Backpack")
if not backpack then
warn("[AnimalStealing] Cannot restore tools - backpack not found for player:", player.Name)
return false
end
local toolStorageFolder = ServerStorage:FindFirstChild("PlayerToolStorage")
if not toolStorageFolder then
print("[AnimalStealing] No tool storage folder found")
return false
end
local playerStorageFolder = toolStorageFolder:FindFirstChild(tostring(player.UserId))
if not playerStorageFolder then
return false
end
local restoredCount = 0
local totalStoredTools = 0
-- Count total stored tools
for _, item in pairs(playerStorageFolder:GetChildren()) do
if item:IsA("Tool") then
totalStoredTools = totalStoredTools + 1
end
end
-- Restore tools to backpack
for _, storedTool in pairs(playerStorageFolder:GetChildren()) do
if storedTool:IsA("Tool") then
local success = pcall(function()
-- Move tool back to backpack (don't clone to avoid duplicates)
storedTool.Parent = backpack
restoredCount = restoredCount + 1
end)
if not success then
warn("[AnimalStealing] Failed to restore tool:", storedTool.Name, "for player:", player.Name)
-- If moving failed, try to destroy to prevent orphaned tools
pcall(function()
storedTool:Destroy()
end)
end
end
end
-- Clean up empty storage folder
if #playerStorageFolder:GetChildren() == 0 then
playerStorageFolder:Destroy()
end
print("[AnimalStealing] Restored", restoredCount, "/", totalStoredTools, "tools for player:", player.Name)
return restoredCount > 0
end
-- New function to clean up orphaned tool storage
function AnimalStealing:_cleanupToolStorage(player)
local toolStorageFolder = ServerStorage:FindFirstChild("PlayerToolStorage")
if not toolStorageFolder then
return
end
local playerStorageFolder = toolStorageFolder:FindFirstChild(tostring(player.UserId))
if playerStorageFolder then
-- Log what we're cleaning up
local toolCount = 0
for _, item in pairs(playerStorageFolder:GetChildren()) do
if item:IsA("Tool") then
toolCount = toolCount + 1
end
end
if toolCount > 0 then
print("[AnimalStealing] Cleaning up", toolCount, "orphaned tools for player:", player.Name)
end
playerStorageFolder:Destroy()
end
end
function AnimalStealing:_setupRemoteEvents()
local StealAnimal = Net:RemoteEvent(PlotConstants.REMOTES.STEAL_ANIMAL)
local DeliveryHandler = Net:RemoteEvent(PlotConstants.REMOTES.DELIVERY_HANDLER)
local removeBrainrot = Net:RemoteFunction("FuseMachine/RemoveBrainrot")
local GrabAnimal = Net:RemoteEvent("StealService/Grab")
StealAnimal.OnServerEvent:Connect(function(player, timestamp, actionId, targetPlotName, animalSlot)
self:handleStealAttempt(player, timestamp, actionId, targetPlotName, animalSlot)
end)
GrabAnimal.OnServerEvent:Connect(function(player, actionId, targetPlotName, animalSlot)
self:handleGrab(player, actionId, targetPlotName, animalSlot)
end)
DeliveryHandler.OnServerEvent:Connect(function(player, actionId)
self:handleDelivery(player, actionId)
end)
end
function AnimalStealing:_setupPlayerConnections()
Players.PlayerAdded:Connect(function(player)
self:_connectPlayerEvents(player)
end)
Players.PlayerRemoving:Connect(function(player)
self:_handlePlayerRemoving(player)
end)
for _, player in pairs(Players:GetPlayers()) do
self:_connectPlayerEvents(player)
end
end
function AnimalStealing:_connectPlayerEvents(player)
player:GetAttributeChangedSignal("Stealing"):Connect(function()
local isCurrentlyStealing = player:GetAttribute("Stealing")
if not isCurrentlyStealing then
self:_cleanupStealState(player)
end
end)
player.CharacterAdded:Connect(function()
if player:GetAttribute("Stealing") then
self:_cleanupStealState(player)
end
end)
end
function AnimalStealing:_handleLeavingPlayerStolenAnimals(player)
local playerPlot = self.plotManager:GetPlayerPlot(player)
if not playerPlot then
return
end
local plotSync = playerPlot:GetSynchronizer()
if not plotSync then
return
end
local animalList = plotSync:Get("AnimalList") or {}
for slot, animal in pairs(animalList) do
if typeof(animal) == "table" and animal.Steal == true then
print("[AnimalStealing] Removing stolen animal", animal.Index, "from leaving player", player.Name, "slot", slot)
animalList[slot] = "Empty"
DataManagment.removeAnimal(player, slot)
end
end
plotSync:Set("AnimalList", animalList)
plotSync:Set("AnimalPodiums", animalList)
end
function AnimalStealing:removeBrainrot(player, slot)
warn()
local playerPlot = self.plotManager:GetPlayerPlot(player)
if not playerPlot then
return
end
local plotSync = playerPlot:GetSynchronizer()
if not plotSync then
return
end
local animalList = plotSync:Get("AnimalList") or {}
local animal = animalList[slot]
animal.Steal = false
plotSync:Set("AnimalList", animalList)
plotSync:Set("AnimalPodiums", animalList)
end
function AnimalStealing:_handlePlayerRemoving(player)
self:_handleLeavingPlayerStolenAnimals(player)
self:_cleanupStealState(player)
-- Clean up tool storage when player leaves
self:_cleanupToolStorage(player)
self.playerStolenModels[player] = nil
self.playerCarryAnimTracks[player] = nil
self.deliveryDebounce[player] = nil
local playerUserId = player.UserId
for key, _ in pairs(self.stealNotificationDebounce) do
if string.find(key, "^" .. playerUserId .. "_") then
self.stealNotificationDebounce[key] = nil
end
end
end
function AnimalStealing:_validateAndRepairAnimalList(plotInstance, plotUUID)
local animalManager = self.plotManager:GetAnimalManager(plotInstance)
if not animalManager then
warn("[AnimalStealing] No animal manager found for plot: " .. plotUUID)
return {}
end
local animalList = plotInstance:GetAnimalList()
return animalManager:ValidateAndRepairAnimalList(animalList)
end
function AnimalStealing:_cleanupStealState(player)
local stealingPlot = player:GetAttribute("StealingPlot")
local stealingSlot = player:GetAttribute("StealingSlot")
if stealingPlot and stealingSlot then
local targetPlot = self.plotManager:GetPlotByUUID(stealingPlot)
if targetPlot then
local animalManager = self.plotManager:GetAnimalManager(targetPlot)
if animalManager and animalManager:HasValidAnimal(stealingSlot) then
animalManager:SetStealState(stealingSlot, false)
end
end
end
player:SetAttribute("StealingPlot", nil)
player:SetAttribute("StealingSlot", nil)
self:_cleanupStolenAnimal(player)
-- Restore tools when stealing ends
self:_restorePlayerTools(player)
local carryAnimTrack = self.playerCarryAnimTracks[player]
if carryAnimTrack and carryAnimTrack.IsPlaying then
carryAnimTrack:Stop()
carryAnimTrack:Destroy()
end
self.playerCarryAnimTracks[player] = nil
end
-- Add this function to your AnimalStealing module
function AnimalStealing:_createBoundingBox(model)
-- Calculate the bounding box of the model
local minX, minY, minZ = math.huge, math.huge, math.huge
local maxX, maxY, maxZ = -math.huge, -math.huge, -math.huge
for _, part in pairs(model:GetDescendants()) do
if part:IsA("BasePart") then
local cf = part.CFrame
local size = part.Size
local corners = {
cf * CFrame.new(-size.X/2, -size.Y/2, -size.Z/2),
cf * CFrame.new(size.X/2, -size.Y/2, -size.Z/2),
cf * CFrame.new(-size.X/2, size.Y/2, -size.Z/2),
cf * CFrame.new(size.X/2, size.Y/2, -size.Z/2),
cf * CFrame.new(-size.X/2, -size.Y/2, size.Z/2),
cf * CFrame.new(size.X/2, -size.Y/2, size.Z/2),
cf * CFrame.new(-size.X/2, size.Y/2, size.Z/2),
cf * CFrame.new(size.X/2, size.Y/2, size.Z/2)
}
for _, corner in pairs(corners) do
local pos = corner.Position
minX, minY, minZ = math.min(minX, pos.X), math.min(minY, pos.Y), math.min(minZ, pos.Z)
maxX, maxY, maxZ = math.max(maxX, pos.X), math.max(maxY, pos.Y), math.max(maxZ, pos.Z)
end
end
end
-- Create the bounding box
local boundingBox = Instance.new("Part")
boundingBox.Name = "BoundingBox"
boundingBox.Material = Enum.Material.ForceField
boundingBox.BrickColor = BrickColor.new("Bright blue")
boundingBox.Transparency = 0.7
boundingBox.CanCollide = false
boundingBox.CanQuery = false
boundingBox.CanTouch = false
boundingBox.Anchored = false
boundingBox.Massless = true
-- Set size and position
local sizeX, sizeY, sizeZ = maxX - minX, maxY - minY, maxZ - minZ
local centerX, centerY, centerZ = (maxX + minX) / 2, (maxY + minY) / 2, (maxZ + minZ) / 2
boundingBox.Size = Vector3.new(sizeX, sizeY, sizeZ)
boundingBox.CFrame = CFrame.new(centerX, centerY, centerZ)
boundingBox.Parent = model
-- Create selection box for better visibility
local selectionBox = Instance.new("SelectionBox")
selectionBox.Adornee = boundingBox
selectionBox.Color3 = Color3.fromRGB(0, 162, 255)
selectionBox.LineThickness = 0.2
selectionBox.Transparency = 0.3
selectionBox.Parent = boundingBox
return boundingBox, Vector3.new(sizeX, sizeY, sizeZ), Vector3.new(centerX, centerY, centerZ)
end
-- Modified version of your _createStolenAnimalModel function
function AnimalStealing:_createStolenAnimalModel(player, animalData, isStolen)
local character = player.Character
if not character or not character:FindFirstChild("HumanoidRootPart") then
warn("[AnimalStealing] Player character or HumanoidRootPart not found for _createCarriedAnimalModel.")
return
end
local animalModelFolder = ReplicatedStorage:FindFirstChild("Models")
if not animalModelFolder then
warn("[AnimalStealing] 'Models' folder not found in ReplicatedStorage.")
return
end
local animalsFolder = animalModelFolder:FindFirstChild("Animals")
if not animalsFolder then
warn("[AnimalStealing] 'Animals' folder not found in ReplicatedStorage/Models.")
return
end
local animalTemplate = animalsFolder:FindFirstChild(animalData.Index)
if not animalTemplate then
warn("[AnimalStealing] Animal template not found for index:", animalData.Index)
return
end
local carriedAnimalModel = animalTemplate:Clone()
carriedAnimalModel:SetAttribute("Index", animalData.Index)
if animalData.Mutation then
carriedAnimalModel:SetAttribute("Mutation", animalData.Mutation)
end
if animalData.Traits then
local traitsToSet = animalData.Traits
if typeof(animalData.Traits) == "table" then
traitsToSet = HttpService:JSONEncode(animalData.Traits)
end
carriedAnimalModel:SetAttribute("Traits", traitsToSet)
end
carriedAnimalModel.Parent = workspace
-- Apply mutations and traits (existing code)
if animalData.Mutation then
local sharedAnimals = require(ReplicatedStorage.Shared.Animals)
sharedAnimals:ApplyMutation(carriedAnimalModel, animalData.Index, animalData.Mutation)
end
if animalData.Traits then
local sharedAnimals = require(ReplicatedStorage.Shared.Animals)
local traitsArray = animalData.Traits
if typeof(animalData.Traits) == "string" then
local success, decoded = pcall(function()
return HttpService:JSONDecode(animalData.Traits)
end)
if success then
traitsArray = decoded
end
end
if traitsArray and type(traitsArray) == "table" then
sharedAnimals:ApplyTraits(carriedAnimalModel, animalData.Index, traitsArray)
end
end
-- Set up animations (existing code)
local animationsFolder = ReplicatedStorage:FindFirstChild("Animations")
if animationsFolder then
local animalsAnimFolder = animationsFolder:FindFirstChild("Animals")
if animalsAnimFolder then
local specificAnimFolder = animalsAnimFolder:FindFirstChild(animalData.Index)
if specificAnimFolder then
local idleAnim = specificAnimFolder:FindFirstChild("Idle")
if idleAnim then
local animController = carriedAnimalModel:FindFirstChildOfClass("AnimationController")
if not animController then
animController = Instance.new("AnimationController")
animController.Name = "AnimationController"
animController.Parent = carriedAnimalModel
end
local animator = animController:FindFirstChildOfClass("Animator")
if not animator then
animator = Instance.new("Animator")
animator.Parent = animController
end
local success, track = pcall(function()
return animator:LoadAnimation(idleAnim)
end)
if success and track then
track.Looped = true
track:Play()
end
end
end
end
end
-- Make parts non-collidable (existing code)
for _, part in carriedAnimalModel:GetDescendants() do
if part:IsA("BasePart") then
part.CanCollide = false
part.CanQuery = false
part.CanTouch = false
part.Massless = true
part.Anchored = false
end
end
-- Create bounding box and get dimensions
local boundingBox, boxSize, boxCenter = self:_createBoundingBox(carriedAnimalModel)
-- Create a handle part at the back bottom of the bounding box
local handlePart = Instance.new("Part")
handlePart.Name = "CarryHandle"
handlePart.Size = Vector3.new(0.5, 0.5, 0.5)
handlePart.Material = Enum.Material.Neon
handlePart.BrickColor = BrickColor.new("Bright green")
handlePart.Transparency = 0.5
handlePart.CanCollide = false
handlePart.CanQuery = false
handlePart.CanTouch = false
handlePart.Massless = true
handlePart.Anchored = false
handlePart.Shape = Enum.PartType.Ball
handlePart.Parent = carriedAnimalModel
-- Position the handle at the back bottom of the bounding box
-- Back = positive Z direction, Bottom = negative Y direction
local handleOffset = CFrame.new(0, -boxSize.Y/2 - 0.5, boxSize.Z/2 + 0.5)
-- Get the primary part or use bounding box center
local primaryPart = carriedAnimalModel.PrimaryPart or boundingBox
-- Position the animal model relative to player
local playerRootPart = character.HumanoidRootPart
local carryOffset = CFrame.new(0, 2.5, -2) -- More up (2.5) and even more forward (-0.5)
-- Position the primary part
primaryPart.CFrame = playerRootPart.CFrame * carryOffset
-- Position the handle relative to the bounding box center
handlePart.CFrame = boundingBox.CFrame * handleOffset
-- Create weld constraint between player and the handle (this is the key change)
local weldConstraint = Instance.new("WeldConstraint")
weldConstraint.Part0 = playerRootPart
weldConstraint.Part1 = handlePart
weldConstraint.Parent = handlePart
-- Create weld constraints to keep the animal model parts together
local modelWeld = Instance.new("WeldConstraint")
modelWeld.Part0 = handlePart
modelWeld.Part1 = primaryPart
modelWeld.Parent = primaryPart
-- Weld bounding box to the model
local boxWeld = Instance.new("WeldConstraint")
boxWeld.Part0 = primaryPart
boxWeld.Part1 = boundingBox
boxWeld.Parent = boundingBox
self:_addStolenOverhead(carriedAnimalModel, primaryPart, isStolen)
self.playerStolenModels[player] = carriedAnimalModel
if animalData.Index == "La Vacca Saturno Saturnita" and isStolen then
self:_tagVisualStolenModel(player, carriedAnimalModel)
end
return carriedAnimalModel
end
-- Optional: Add a function to toggle bounding box visibility
function AnimalStealing:toggleBoundingBox(player, visible)
local stolenModel = self.playerStolenModels[player]
if not stolenModel then return end
local boundingBox = stolenModel:FindFirstChild("BoundingBox")
if boundingBox then
boundingBox.Transparency = visible and 0.7 or 1
local selectionBox = boundingBox:FindFirstChildOfClass("SelectionBox")
if selectionBox then
selectionBox.Transparency = visible and 0.3 or 1
end
end
local handle = stolenModel:FindFirstChild("CarryHandle")
if handle then
handle.Transparency = visible and 0.5 or 1
end
end
function AnimalStealing:_addStolenOverhead(carriedAnimalModel, attachmentPart, isStolen)
local overheadsFolder = ReplicatedStorage:FindFirstChild("Overheads")
if not overheadsFolder then
warn("[AnimalStealing] 'Overheads' folder not found in ReplicatedStorage.")
return
end
local animalOverheadTemplate = overheadsFolder:FindFirstChild("AnimalOverhead")
if not animalOverheadTemplate then
warn("[AnimalStealing] 'AnimalOverhead' template not found in Overheads folder.")
return
end
local carriedOverhead = animalOverheadTemplate:Clone()
if isStolen then
carriedOverhead.DisplayName.Text = "STOLEN"
carriedOverhead.DisplayName.TextColor3 = Color3.fromRGB(255, 0, 0)
else
carriedOverhead.DisplayName.Text = ""
end
carriedOverhead.DisplayName.TextStrokeTransparency = 0
carriedOverhead.DisplayName.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)
carriedOverhead.Generation.Visible = false
carriedOverhead.Price.Visible = false
carriedOverhead.Rarity.Visible = false
carriedOverhead.Mutation.Visible = false
local AnimalsData = require(ReplicatedStorage.Datas.Animals) -- Re-require to ensure it's the correct path if different from Shared
local animalIndex = carriedAnimalModel:GetAttribute("Index")
local animalData = animalIndex and AnimalsData[animalIndex]
local overheadYOffsetModifier = (animalData and animalData.OverheadYOffsetModifier) or 1
local overheadAttachment = Instance.new("Attachment")
overheadAttachment.Name = "CarriedOverhead"
overheadAttachment.CFrame = CFrame.new(0, 3 * overheadYOffsetModifier, 0)
local primaryPart = carriedAnimalModel.PrimaryPart
if primaryPart then
overheadAttachment.Parent = primaryPart
else
-- Fallback to the provided attachmentPart or first child if primaryPart doesn't exist
overheadAttachment.Parent = attachmentPart or carriedAnimalModel:GetChildren()[1]
end
carriedOverhead.Parent = overheadAttachment
end
function AnimalStealing:_playCarryAnimation(player)
local character = player.Character
if not character then return end
local humanoid = character:FindFirstChildOfClass("Humanoid")
if not humanoid then return end
local animator = humanoid:FindFirstChildOfClass("Animator")
if not animator then
animator = Instance.new("Animator")
animator.Parent = humanoid
end
local carryAnim = ReplicatedStorage:FindFirstChild("Animations")
if not carryAnim then
return
end
local playerAnims = carryAnim:FindFirstChild("Player")
if not playerAnims then
return
end
local carryAnimation = playerAnims:FindFirstChild("Carry")
if not carryAnimation then
return
end
local animTrack = animator:LoadAnimation(carryAnimation)
animTrack.Looped = true
animTrack:Play()
self.playerCarryAnimTracks[player] = animTrack
end
function AnimalStealing:_sendNotification(player, message)
local NotificationEvent = Net:RemoteEvent("NotificationService/Notify")
if NotificationEvent and player then
NotificationEvent:FireClient(player, message, 3)
end
end
function AnimalStealing:_getColoredAnimalName(animalIndex)
local Animals = require(ReplicatedStorage.Datas.Animals)
local Rarities = require(ReplicatedStorage.Datas.Rarities)
local animalData = Animals[animalIndex]
if not animalData then
return animalIndex
end
local rarityData = Rarities[animalData.Rarity]
if not rarityData then
return animalData.DisplayName
end
local color = rarityData.Color
local r = math.floor(color.R * 255)
local g = math.floor(color.G * 255)
local b = math.floor(color.B * 255)
local hexColor = string.format("#%02X%02X%02X", r, g, b)
return string.format('%s', hexColor, animalData.DisplayName)
end
local LastPlot
function AnimalStealing:handleGrab(player, actionId, plotUUID, animalSlot)
if actionId == "Grab" then
if not DataManagment.isDataReady(player) then
return false, "Player data not ready."
end
if not actionId or not plotUUID or not animalSlot then
return false, "Missing parameters for grab."
end
if self.playerStolenModels[player] then
self:_sendNotification(player, "You are already carrying an animal.")
return false, "Already carrying an animal."
end
local playerPlot = self.plotManager:GetPlayerPlot(player)
if not playerPlot or playerPlot:GetUUID() ~= plotUUID then
self:_sendNotification(player, "You can only grab animals from your own plot.")
return false, "Not your plot."
end
local playerPlotSync = playerPlot:GetSynchronizer()
if not playerPlotSync then
warn("[AnimalStealing] Player plot synchronizer not found for grab.")
return false, "Plot data not available."
end
local animalList = playerPlotSync:Get("AnimalList") or {}
local animal = animalList[animalSlot]
if not animal or animal == PlotConstants.STATES.EMPTY or typeof(animal) ~= "table" then
self:_sendNotification(player, "No animal found at this slot on your plot.")
return false, "Invalid animal slot."
end
if animal.Steal == true then
local stealingPlayer = nil
for _, otherPlayer in pairs(Players:GetPlayers()) do
if otherPlayer:GetAttribute("Stealing") and
otherPlayer:GetAttribute("StealingPlot") == plotUUID and
otherPlayer:GetAttribute("StealingSlot") == animalSlot then
stealingPlayer = otherPlayer
break
end
end
if stealingPlayer then
self:_sendNotification(player, "Your " .. self:_getColoredAnimalName(animal.Index) .. " is currently being stolen!")
return false, "Animal is being stolen."
else
warn("[AnimalStealing] Orphaned 'Steal' state detected for owned animal during grab. Resetting.")
local animalManager = self.plotManager:GetAnimalManager(playerPlot)
if animalManager then
animalManager:SetStealState(animalSlot, false)
animal.Steal = false
end
end
end
local createdModel = self:_createStolenAnimalModel(player, animal, false)
if not createdModel then
return false, "erm. ignore this ALL works"
end
self:_playCarryAnimation(player)
LastPlot = animalSlot
-- Store original animal data before marking as being carried
player:SetAttribute("CarriedAnimalData", HttpService:JSONEncode(animal))
animal.Steal = player.UserId
playerPlotSync:Set("AnimalList", animalList)
playerPlotSync:Set("AnimalPodiums", animalList)
player:SetAttribute("Stealing", true)
player:SetAttribute("StealingPlot", plotUUID)
player:SetAttribute("StealingSlot", animalSlot)
player:SetAttribute("IsCarryingOwned", true)
return true, "Animal grabbed successfully."
elseif actionId == "Place" then
if not DataManagment.isDataReady(player) then
return false, "Player data not ready."
end
if not plotUUID or not animalSlot then
return false, "Missing parameters for placing."
end
local playerPlot = self.plotManager:GetPlayerPlot(player)
if not playerPlot or playerPlot:GetUUID() ~= plotUUID then
self:_sendNotification(player, "You can only place animals on your own plot.")
return false, "Not your plot."
end
if not player:GetAttribute("Stealing") or not player:GetAttribute("IsCarryingOwned") then
self:_sendNotification(player, "You are not carrying an owned animal to place.")
return false, "Not carrying owned animal."
end
local playerPlotSync = playerPlot:GetSynchronizer()
if not playerPlotSync then
warn("[AnimalStealing] Player plot synchronizer not found for place.")
return false, "Plot data not available."
end
local animalList = playerPlotSync:Get("AnimalList") or {}
local originalSlot = LastPlot -- The slot where the animal was originally grabbed from
local targetSlot = animalSlot -- The slot where the player wants to place the animal
local stolenModel = self.playerStolenModels[player]
if not stolenModel then
self:_sendNotification(player, "No animal model found to place.")
self:_cleanupStealState(player)
return false, "No animal model."
end
-- Get the carried animal data
local carriedAnimalDataStr = player:GetAttribute("CarriedAnimalData")
if not carriedAnimalDataStr then
self:_sendNotification(player, "Error: Carried animal data not found.")
self:_cleanupStealState(player)
return false, "Carried animal data missing."
end
local carriedAnimalData
local success, decoded = pcall(function()
return HttpService:JSONDecode(carriedAnimalDataStr)
end)
if not success then
self:_sendNotification(player, "Error: Failed to decode carried animal data.")
self:_cleanupStealState(player)
return false, "Failed to decode animal data."
end
carriedAnimalData = decoded
-- Reset the Steal flag for the carried animal
carriedAnimalData.Steal = false
carriedAnimalData.LastCollect = workspace:GetServerTimeNow()
-- Check if target slot has an animal
local targetAnimal = animalList[targetSlot]
local isTargetSlotEmpty = (not targetAnimal or targetAnimal == PlotConstants.STATES.EMPTY or typeof(targetAnimal) ~= "table")
if isTargetSlotEmpty then
animalList[originalSlot] = PlotConstants.STATES.EMPTY
animalList[targetSlot] = carriedAnimalData
local coloredAnimalName = self:_getColoredAnimalName(carriedAnimalData.Index)
else
-- Swap animals - target slot has an animal
local targetAnimalData = {}
for key, value in pairs(targetAnimal) do
targetAnimalData[key] = value
end
targetAnimalData.LastCollect = workspace:GetServerTimeNow()
targetAnimalData.Steal = false
animalList[originalSlot] = targetAnimalData
animalList[targetSlot] = carriedAnimalData
local carriedAnimalName = self:_getColoredAnimalName(carriedAnimalData.Index)
local targetAnimalName = self:_getColoredAnimalName(targetAnimalData.Index)
end
-- Update the plot
playerPlotSync:Set("AnimalList", animalList)
playerPlotSync:Set("AnimalPodiums", animalList)
-- Clean up player state
self:_cleanupStealState(player)
player:SetAttribute("Stealing", false)
player:SetAttribute("IsCarryingOwned", nil)
player:SetAttribute("CarriedAnimalData", nil)
return true, "Animal placement completed successfully."
end
end
function AnimalStealing:handleStealAttempt(player, timestamp, actionId, targetPlotName, animalSlot)
if not DataManagment.isDataReady(player) then
print("[AnimalStealing] Data not ready for player:", player.Name)
return
end
if not timestamp or not actionId or not targetPlotName or not animalSlot then
print("[AnimalStealing] Missing parameters for player:", player.Name)
return
end
local timeDiff = math.abs(workspace:GetServerTimeNow() - (timestamp - PlotConstants.SECURITY.TIMESTAMP_OFFSET))
if timeDiff > PlotConstants.SECURITY.TIMESTAMP_TOLERANCE then
print("[AnimalStealing] Timestamp validation failed for player:", player.Name, "TimeDiff:", timeDiff)
--return
end
local targetPlot = self.plotManager:GetPlotByUUID(targetPlotName)
if not targetPlot then
print("[AnimalStealing] Target plot not found:", targetPlotName, "for player:", player.Name)
--return
end
local targetOwner = targetPlot:GetOwner()
if not targetOwner or targetOwner == player then
print("[AnimalStealing] Invalid target owner for player:", player.Name)
--return
end
local distance = (playerCharacter.HumanoidRootPart.Position - targetPlotModel.Position).Magnitude
local MAX_STEAL_DISTANCE = 50 -- Adjust as needed
if distance > MAX_STEAL_DISTANCE then
print("[AnimalStealing] Player too far away:", player.Name, "Distance:", distance, "Max allowed:", MAX_STEAL_DISTANCE)
self:_sendNotification(player, "You're too far away to steal from this plot!")
return
end
-- Continue with existing security manager check
local securityManager = self.plotManager:GetSecurityManager(targetPlot)
if securityManager then
local canSteal, reason = securityManager:CanPlayerSteal(player, targetPlot)
if not canSteal then
print("[AnimalStealing] Security check failed for player:", player.Name, "Reason:", reason)
--return
end
end
local securityManager = self.plotManager:GetSecurityManager(targetPlot)
if securityManager then
local canSteal, reason = securityManager:CanPlayerSteal(player, targetPlot)
if not canSteal then
print("[AnimalStealing] Security check failed for player:", player.Name, "Reason:", reason)
--return
end
end
local notificationKey = targetOwner.UserId .. "_" .. animalSlot
local currentTime = tick()
if self.stealNotificationDebounce[notificationKey] then
local timeSinceLastNotification = currentTime - self.stealNotificationDebounce[notificationKey]
if timeSinceLastNotification < 3 then
print("[AnimalStealing] Notification debounce active for player:", player.Name, "Time remaining:", 3 - timeSinceLastNotification)
--return
end
end
local animalList = self:_validateAndRepairAnimalList(targetPlot, targetPlotName)
local animal = animalList[animalSlot]
if not animal or animal == PlotConstants.STATES.EMPTY or typeof(animal) ~= "table" then
print("[AnimalStealing] Invalid animal at slot", animalSlot, "for player:", player.Name, "Animal:", animal)
return
end
if player:GetAttribute("Stealing") then
local currentStealingPlot = player:GetAttribute("StealingPlot")
local currentStealingSlot = player:GetAttribute("StealingSlot")
if not currentStealingPlot or not currentStealingSlot then
self:_cleanupStealState(player)
else
if currentStealingPlot == targetPlotName and currentStealingSlot == animalSlot then
return
else
local now = tick()
if (self.alreadyStealingDebounce[player] or 0) < now - 0.5 then
local coloredAnimalName = self:_getColoredAnimalName(animal.Index)
self.alreadyStealingDebounce[player] = now
end
return
end
end
end
if animal.Steal == true then
local actuallyBeingStolen = false
local stealingPlayer = nil
for _, otherPlayer in pairs(Players:GetPlayers()) do
if otherPlayer:GetAttribute("Stealing") and
otherPlayer:GetAttribute("StealingPlot") == targetPlotName and
otherPlayer:GetAttribute("StealingSlot") == animalSlot then
actuallyBeingStolen = true
stealingPlayer = otherPlayer
break
end
end
if not actuallyBeingStolen then
self:_resetOrphanedStealState(targetPlot, targetOwner, animalList, animalSlot)
else
if stealingPlayer == player then
return
else
local coloredAnimalName = self:_getColoredAnimalName(animal.Index)
self:_sendNotification(player, coloredAnimalName .. " is already being stolen by " .. stealingPlayer.Name)
return
end
end
end
local playerAnimalList = DataManagment.getAnimalList(player)
local maxAnimals = DataManagment.GetMaxAnimals(player)
local currentAnimals = 0
for _, ownedAnimal in ipairs(playerAnimalList) do
if ownedAnimal ~= "Empty" and ownedAnimal ~= nil then
currentAnimals += 1
end
end
if currentAnimals >= maxAnimals then
print("[AnimalStealing] Player", player.Name, "has full capacity:", currentAnimals, "/", maxAnimals)
local now = tick()
if (self.capacityFullDebounce[player] or 0) < now - 2 then
self:_sendNotification(player, "You need more room in your base to steal a brainrot!")
self.capacityFullDebounce[player] = now
end
-- return
end
self.stealNotificationDebounce[notificationKey] = currentTime
local coloredAnimalName = self:_getColoredAnimalName(animal.Index)
self:_sendNotification(targetOwner, "Someone is stealing your " .. coloredAnimalName)
local animalManager = self.plotManager:GetAnimalManager(targetPlot)
if animalManager then
animalManager:SetStealState(animalSlot, true)
end
player:SetAttribute("Stealing", true)
player:SetAttribute("StealingPlot", targetPlotName)
player:SetAttribute("StealingSlot", animalSlot)
self:_createStolenAnimalModel(player, animal)
self:_playCarryAnimation(player)
print("[AnimalStealing] Successfully started steal for player:", player.Name, "Animal:", animal.Index, "Slot:", animalSlot)
end
function AnimalStealing:_resetOrphanedStealState(targetPlot, targetOwner, animalList, animalSlot)
local animal = animalList[animalSlot]
if not animal or typeof(animal) ~= "table" or not animal.Index then
return
end
animal.Steal = false
if targetOwner then
local targetData = DataManagment.GetDataMan(targetOwner)
if targetData and targetData.AnimalList and targetData.AnimalList[animalSlot] then
local ownerAnimal = targetData.AnimalList[animalSlot]
if typeof(ownerAnimal) == "table" and ownerAnimal.Index then
ownerAnimal.Steal = false
end
end
end
local currentAnimalList = targetPlot:Get("AnimalList") or {}
if currentAnimalList[animalSlot] and typeof(currentAnimalList[animalSlot]) == "table" and currentAnimalList[animalSlot].Index then
targetPlot:Set(("AnimalList.%d.Steal"):format(animalSlot), false)
else
targetPlot:Set("AnimalList", animalList)
end
if targetOwner then
local targetPlayerSync = Synchronizer:Get(targetOwner)
if targetPlayerSync then
local playerAnimalList = targetPlayerSync:Get("AnimalList") or {}
if playerAnimalList[animalSlot] and typeof(playerAnimalList[animalSlot]) == "table" and playerAnimalList[animalSlot].Index then
targetPlayerSync:Set(("AnimalList.%d.Steal"):format(animalSlot), false)
else
local targetData = DataManagment.GetDataMan(targetOwner)
if targetData then
targetPlayerSync:Set("AnimalAddedOrRemoved", targetData.AnimalList)
targetPlayerSync:Set("AnimalPodiums", targetData.AnimalList)
end
end
local targetData = DataManagment.GetDataMan(targetOwner)
if targetData then
targetPlayerSync:Set("AnimalAddedOrRemoved", targetData.AnimalList)
targetPlayerSync:Set("AnimalPodiums", targetData.AnimalList)
end
end
end
end
function AnimalStealing:_setStealState(targetPlot, targetOwner, animalList, animalSlot, stealState)
local animal = animalList[animalSlot]
if not animal or typeof(animal) ~= "table" or not animal.Index then
return false
end
animal.Steal = stealState
if targetOwner then
local targetData = DataManagment.GetDataMan(targetOwner)
if targetData and targetData.AnimalList and targetData.AnimalList[animalSlot] then
local ownerAnimal = targetData.AnimalList[animalSlot]
if typeof(ownerAnimal) == "table" and ownerAnimal.Index then
ownerAnimal.Steal = stealState
end
end
end
local currentAnimalList = targetPlot:Get("AnimalList") or {}
if currentAnimalList[animalSlot] and typeof(currentAnimalList[animalSlot]) == "table" and currentAnimalList[animalSlot].Index then
targetPlot:Set(("AnimalList.%d.Steal"):format(animalSlot), stealState)
else
targetPlot:Set("AnimalList", animalList)
end
if targetOwner then
local targetPlayerSync = Synchronizer:Get(targetOwner)
if targetPlayerSync then
local playerAnimalList = targetPlayerSync:Get("AnimalList") or {}
if playerAnimalList[animalSlot] and typeof(playerAnimalList[animalSlot]) == "table" and playerAnimalList[animalSlot].Index then
targetPlayerSync:Set(("AnimalList.%d.Steal"):format(animalSlot), stealState)
else
local targetData = DataManagment.GetDataMan(targetOwner)
if targetData then
targetPlayerSync:Set("AnimalAddedOrRemoved", targetData.AnimalList)
targetPlayerSync:Set("AnimalPodiums", targetData.AnimalList)
end
end
local targetData = DataManagment.GetDataMan(targetOwner)
if targetData then
targetPlayerSync:Set("AnimalAddedOrRemoved", targetData.AnimalList)
targetPlayerSync:Set("AnimalPodiums", targetData.AnimalList)
end
end
end
return true
end
function AnimalStealing:handleDelivery(player, actionId)
local currentTime = tick()
if self.deliveryDebounce[player] then
local timeSinceLastCall = currentTime - self.deliveryDebounce[player]
if timeSinceLastCall < 2 then
return
end
end
self.deliveryDebounce[player] = currentTime
if not DataManagment.isDataReady(player) then
return
end
if not player:GetAttribute("Stealing") then
return
end
local stealingPlot = player:GetAttribute("StealingPlot")
local stealingSlot = player:GetAttribute("StealingSlot")
if not stealingPlot or not stealingSlot then
self:_cleanupStealState(player)
player:SetAttribute("Stealing", false)
return
end
local playerData = DataManagment.GetDataMan(player)
if not playerData then
return
end
local targetPlot = Synchronizer:Get(stealingPlot)
local ownerLeftGame = false
if not targetPlot then
local stolenAnimalModel = self.playerStolenModels[player]
if stolenAnimalModel and stolenAnimalModel.Parent and stolenAnimalModel:GetAttribute("Index") then
print("[AnimalStealing] Target plot not found, but stolen model exists - owner likely left game")
ownerLeftGame = true
else
self:_cleanupStealState(player)
player:SetAttribute("Stealing", false)
return
end
end
local animalList = {}
local animal = nil
local slotIndex = tonumber(stealingSlot)
if not slotIndex then
print("[AnimalStealing] Invalid stealingSlot for indexing:", stealingSlot, "Type:", typeof(stealingSlot))
self:_cleanupStealState(player)
player:SetAttribute("Stealing", false)
return
end
if not ownerLeftGame then
animalList = targetPlot:Get("AnimalList") or {}
animal = animalList[slotIndex]
else
print("[AnimalStealing] Owner left game, using stolen model for animal data")
end
local stolenAnimalModel = self.playerStolenModels[player]
local hasValidStolenModel = stolenAnimalModel and stolenAnimalModel.Parent and stolenAnimalModel:GetAttribute("Index")
print("[DEBUG] Animal from plot:", animal, "Type:", typeof(animal))
print("[DEBUG] Has valid stolen model:", hasValidStolenModel)
if hasValidStolenModel then
print("[DEBUG] Stolen model attributes - Index:", stolenAnimalModel:GetAttribute("Index"), "Mutation:", stolenAnimalModel:GetAttribute("Mutation"), "Traits:", stolenAnimalModel:GetAttribute("Traits"))
end
local capturedAnimal = nil
if animal and typeof(animal) == "table" and animal.Steal then
capturedAnimal = {
Index = animal.Index,
Mutation = animal.Mutation,
Traits = animal.Traits,
Steal = true
}
print("[DEBUG] Captured animal data from target plot:", capturedAnimal.Index, "Mutation:", capturedAnimal.Mutation)
elseif hasValidStolenModel then
capturedAnimal = {
Index = stolenAnimalModel:GetAttribute("Index"),
Mutation = stolenAnimalModel:GetAttribute("Mutation"),
Traits = stolenAnimalModel:GetAttribute("Traits"),
Steal = true
}
print("[DEBUG] Captured animal data from stolen model:", capturedAnimal.Index, "Mutation:", capturedAnimal.Mutation)
end
if not capturedAnimal then
print("[AnimalStealing] Cannot deliver - no valid stolen animal found")
self:_cleanupStealState(player)
player:SetAttribute("Stealing", false)
return
end
animal = capturedAnimal
local playerPlot = self.plotManager:GetPlayerPlot(player)
if not playerPlot then
self:_cleanupStealState(player)
player:SetAttribute("Stealing", false)
return
end
local playerPlotModel = playerPlot:GetPlotModel()
if not playerPlotModel then
self:_cleanupStealState(player)
player:SetAttribute("Stealing", false)
return
end
local stolenAnimal = {
Index = animal.Index,
LastCollect = workspace:GetServerTimeNow(),
Mutation = animal.Mutation,
Traits = animal.Traits,
Steal = false
}
print("[DEBUG] Captured stolen animal data:", stolenAnimal.Index, "Mutation:", stolenAnimal.Mutation, "Traits:", stolenAnimal.Traits)
local stolenAnimalModel = self.playerStolenModels[player]
local carryAnimTrack = self.playerCarryAnimTracks[player]
if carryAnimTrack and carryAnimTrack.IsPlaying then
carryAnimTrack:Stop()
carryAnimTrack:Destroy()
end
self.playerCarryAnimTracks[player] = nil
player:SetAttribute("Stealing", false)
player:SetAttribute("StealingPlot", nil)
player:SetAttribute("StealingSlot", nil)
if not ownerLeftGame and animalList[slotIndex] and typeof(animalList[slotIndex]) == "table" then
animalList[slotIndex] = "Empty"
targetPlot:Set("AnimalList", animalList)
targetPlot:Set("AnimalPodiums", animalList)
end
if not ownerLeftGame then
local targetOwner = targetPlot:Get("Owner")
if targetOwner then
local ownerUserId = typeof(targetOwner) == "Instance" and targetOwner.UserId or targetOwner
local ownerPlayer = Players:GetPlayerByUserId(ownerUserId)
if ownerPlayer then
DataManagment.removeAnimal(ownerPlayer, slotIndex)
local targetPlayerSync = Synchronizer:Get(ownerPlayer)
if targetPlayerSync then
local targetData = DataManagment.GetDataMan(ownerPlayer)
if targetData then
targetPlayerSync:Set("AnimalAddedOrRemoved", targetData.AnimalList)
targetPlayerSync:Set("AnimalPodiums", targetData.AnimalList)
end
end
else
print("[AnimalStealing] Owner left game, but animal data preserved for delivery:", stolenAnimal.Index, "Mutation:", stolenAnimal.Mutation)
end
end
else
print("[AnimalStealing] Owner already left game, skipping owner data cleanup for:", stolenAnimal.Index, "Mutation:", stolenAnimal.Mutation)
end
print("[DEBUG] About to process stolen animal delivery for:", player.Name, "Animal:", stolenAnimal.Index)
local deliverySuccess = self:_processStolenAnimalDelivery(player, stolenAnimal, playerPlot)
print("[DEBUG] Delivery result:", deliverySuccess)
if stolenAnimalModel and stolenAnimalModel.Parent then
if CollectionService:HasTag(stolenAnimalModel, "LaVaccaModel") then
if not stolenAnimalModel:GetAttribute("PreserveOnStealingEnd") then
CollectionService:RemoveTag(stolenAnimalModel, "LaVaccaModel")
stolenAnimalModel:Destroy()
else
print("[AnimalStealing] 🎭 Preserving La Vacca model:", stolenAnimalModel.Name)
end
else
stolenAnimalModel:Destroy()
end
end
self.playerStolenModels[player] = nil
end
function AnimalStealing:_findEmptySlot(player)
if not DataManagment.isDataReady(player) then
warn("[EmptySlotHandler] Data not ready for player:", player.Name)
return nil
end
local animalList = DataManagment.getAnimalList(player)
if not animalList then
warn("[EmptySlotHandler] No animal list found for player:", player.Name)
return nil
end
local maxAnimals = DataManagment.GetMaxAnimals(player)
for i = 1, maxAnimals do
if animalList[i] == "Empty" or animalList[i] == nil then
return i
end
end
return nil
end
function AnimalStealing:_processStolenAnimalDelivery(player, stolenAnimal, playerPlot)
local playerData = DataManagment.GetDataMan(player)
if not playerData then
print("[DEBUG] No player data for:", player.Name)
return false
end
local isDataReady = DataManagment.isDataReady(player)
print("[DEBUG] Data ready for", player.Name, ":", isDataReady)
if not isDataReady then
print("[DEBUG] Player data not ready, waiting...")
local success = DataManagment.waitForData(player, 10)
if not success then
print("[DEBUG] Failed to wait for data for:", player.Name)
self:_sendNotification(player, "Failed to deliver animal - data not ready!")
return false
end
end
print("[DEBUG] Delivering stolen animal:", stolenAnimal.Index, "Mutation:", stolenAnimal.Mutation, "Traits:", stolenAnimal.Traits, "for player:", player.Name)
local traitsString = nil
if stolenAnimal.Traits and typeof(stolenAnimal.Traits) == "table" then
local HttpService = game:GetService("HttpService")
local success, encoded = pcall(HttpService.JSONEncode, HttpService, stolenAnimal.Traits)
if success then
traitsString = encoded
else
print("[DEBUG] Failed to encode traits:", stolenAnimal.Traits)
end
elseif typeof(stolenAnimal.Traits) == "string" then
traitsString = stolenAnimal.Traits
end
print("[DEBUG] Calling DataManagment.addAnimal with:", stolenAnimal.Index, stolenAnimal.Mutation, traitsString)
local addedSlot = DataManagment.addAnimal(player, stolenAnimal.Index, stolenAnimal.Mutation, traitsString)
print("[DEBUG] DataManagment.addAnimal returned:", addedSlot)
if not addedSlot then
print("[DEBUG] Failed to add animal - base might be full")
self:_sendNotification(player, "Your base is full! Cannot steal more animals.")
return false
end
print("[DEBUG] Successfully added stolen animal to slot:", addedSlot)
local updatedAnimalList = DataManagment.getAnimalList(player)
task.wait(0.1)
local playerPlotSync = playerPlot:GetSynchronizer()
playerPlotSync:Set("AnimalList", updatedAnimalList)
playerPlotSync:Set("AnimalPodiums", updatedAnimalList)
local playerSync = Synchronizer:Get(player)
if playerSync then
playerSync:Set("AnimalAddedOrRemoved", updatedAnimalList)
playerSync:Set("AnimalPodiums", updatedAnimalList)
end
local coloredAnimalName = self:_getColoredAnimalName(stolenAnimal.Index)
self:_sendNotification(player, "You stole " .. coloredAnimalName)
DataManagment.addSteals(player, 1)
local updatedPlayerData = DataManagment.GetDataMan(player)
if updatedPlayerData and playerSync then
playerSync:Set("Steals", updatedPlayerData.Steals or 0)
end
return true
end
function AnimalStealing:_tagVisualStolenModel(player, stolenAnimalModel)
if not stolenAnimalModel or not stolenAnimalModel.Parent then
warn("[LaVacca Ritual] Visual stolen model not found for player:", player.Name)
return
end
local usedIndices = {}
for _, model in pairs(workspace:GetChildren()) do
if CollectionService:HasTag(model, "LaVaccaModel") then
local index = model:GetAttribute("LaVaccaIndex")
if index then
usedIndices[index] = true
end
end
end
local availableIndex = nil
for i = 1, 3 do
if not usedIndices[i] then
availableIndex = i
break
end
end
if not availableIndex then
availableIndex = math.random(1, 3)
for _, model in pairs(workspace:GetChildren()) do
if CollectionService:HasTag(model, "LaVaccaModel") and
model:GetAttribute("LaVaccaIndex") == availableIndex then
CollectionService:RemoveTag(model, "LaVaccaModel")
model:SetAttribute("LaVaccaIndex", nil)
break
end
end
end
stolenAnimalModel:SetAttribute("LaVaccaIndex", availableIndex)
stolenAnimalModel:SetAttribute("OwnerUserId", player.UserId)
stolenAnimalModel:SetAttribute("CreatedAt", workspace:GetServerTimeNow())
CollectionService:AddTag(stolenAnimalModel, "LaVaccaModel")
end
function AnimalStealing:_cleanupStolenAnimal(player)
local stolenAnimalModel = self.playerStolenModels[player]
if stolenAnimalModel and stolenAnimalModel.Parent then
if CollectionService:HasTag(stolenAnimalModel, "LaVaccaModel") then
CollectionService:RemoveTag(stolenAnimalModel, "LaVaccaModel")
end
stolenAnimalModel:Destroy()
end
local carryAnimTrack = self.playerCarryAnimTracks[player]
if carryAnimTrack then
if carryAnimTrack.IsPlaying then
carryAnimTrack:Stop()
end
carryAnimTrack:Destroy()
self.playerCarryAnimTracks[player] = nil
end
self.playerStolenModels[player] = nil
end
return AnimalStealing - Edit
03:12:20.445
- Edit
03:12:20.446
============================== - Edit
03:12:20.446 📜 ServerScriptService.Services.Plots.PlotConstants - Edit
03:12:20.446 ==============================
- Edit
03:12:20.446 local PlotConstants = {}
PlotConstants.TIMING = {
DEFAULT_LOCK_TIME = 60,
DELAY_TIME = 1,
DATA_WAIT_TIMEOUT = 30,
DELIVERY_DEBOUNCE = 2,
STEAL_NOTIFICATION_COOLDOWN = 3,
}
PlotConstants.REMOTES = {
STEAL_ANIMAL = "280b459b-b3c8-424e-9b0b-821d4a4dec11",
DELIVERY_HANDLER = "dfdd4236-1fac-4b9a-9f67-fec68d72c151",
ANIMAL_PROMPT = "d8766412-71ac-42fc-9bb2-00d0b4a9b85e",
}
PlotConstants.STATES = {
EMPTY = "Empty",
OWNER = "Owner",
STEAL = "Steal",
STEALING = "Stealing",
}
PlotConstants.TIERING = {
MAX_REBIRTHS = 13,
}
PlotConstants.FLOOR_KEYS = {
[1] = "BlockEndTimeFirstFloor",
[2] = "BlockEndTimeSecondFloor",
[3] = "BlockEndTimeThirdFloor",
}
PlotConstants.SECURITY = {
TIMESTAMP_TOLERANCE = 5,
TIMESTAMP_OFFSET = 185,
}
PlotConstants.VISUAL = {
TRANSPARENCY_STEALING = 0.5,
SPAWN_WAIT_TIME = 0.1,
}
PlotConstants.ERRORS = {
DATA_NOT_READY = "Player data not ready",
PLOT_NOT_FOUND = "Plot not found",
NO_AVAILABLE_PLOTS = "No available plots",
INVALID_ANIMAL_DATA = "Invalid animal data",
BASE_FULL = "Your base is full! Cannot steal more animals.",
ALREADY_STEALING = "You're already stealing an animal! Deliver it first",
BEING_STOLEN = "is already being stolen by",
BASE_LOCKED = "Your base is already locked!",
}
PlotConstants.SUCCESS = {
ANIMAL_STOLEN = "You stole",
FRIENDS_TOGGLED = "Friends access toggled",
REBIRTH_SUCCESS = "Successfully rebirthed to level",
}
return PlotConstants - Edit
03:12:20.446
- Edit
03:12:20.446
============================== - Edit
03:12:20.446 📜 ServerScriptService.Services.Plots.PlotManager - Edit
03:12:20.446 ==============================
- Edit
03:12:20.446 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local PlotConstants = require(script.Parent.PlotConstants)
local Plot = require(script.Parent.Plot)
local AnimalManager = require(script.Parent.AnimalManager)
local PlotSecurity = require(script.Parent.PlotSecurity)
local DataManagement = require(ServerScriptService.Services.DataManagment)
local PlotManager = {}
PlotManager.__index = PlotManager
function PlotManager.new(plotSynchronizer)
local self = setmetatable({}, PlotManager)
self.plotSynchronizer = plotSynchronizer
self.playerPlots = {}
self.plotsByUUID = {}
self.animalManagers = {}
self.securityManagers = {}
self:_setupPlayerEvents()
return self
end
function PlotManager:_setupPlayerEvents()
Players.PlayerRemoving:Connect(function(player)
self:RemovePlayerPlot(player)
end)
end
function PlotManager:CreatePlayerPlot(player)
if self.playerPlots[player] then
warn("[PlotManager] Player already has a plot: " .. player.Name)
return self.playerPlots[player]
end
if not DataManagement.isDataReady(player) then
warn("[PlotManager] Player data not ready for plot creation: " .. player.Name .. ", waiting...")
local success = DataManagement.waitForData(player, PlotConstants.TIMING.DATA_WAIT_TIMEOUT)
if not success then
warn("[PlotManager] Failed to get data for plot creation for player: " .. player.Name)
return nil
end
end
local success, result = pcall(function()
local playerData = DataManagement.GetDataMan(player)
if not playerData then
error("Failed to get player data")
end
local animalList = DataManagement.calculateOfflineGains(player)
for _, animal in pairs(animalList) do
if animal and typeof(animal) == "table" then
animal.Steal = false
end
end
local plot = Plot.new(player, playerData.Rebirths, {
AnimalList = animalList
})
local uuid = plot:GetUUID()
self.playerPlots[player] = plot
self.plotsByUUID[uuid] = plot
self.animalManagers[uuid] = AnimalManager.new(plot)
self.securityManagers[uuid] = PlotSecurity.new(plot)
self.plotSynchronizer:RegisterPlot(plot)
self:_setupCharacterSpawning(player)
if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
plot:TeleportOwnerToSpawn()
end
if plot.ApplyAppropriateSkin then
plot:ApplyAppropriateSkin()
end
if plot._ensureBaseRewardsApplied then
plot:_ensureBaseRewardsApplied()
end
task.spawn(function()
task.wait(2)
if plot and plot._ensureBaseRewardsApplied then
plot:_ensureBaseRewardsApplied()
end
end)
return plot
end)
if not success then
warn("[PlotManager] Error creating plot for: " .. player.Name .. " - " .. tostring(result))
return nil
end
return result
end
function PlotManager:RemovePlayerPlot(player)
local plot = self.playerPlots[player]
if not plot then
return
end
local uuid = plot:GetUUID()
self.plotSynchronizer:UnregisterPlot(plot)
self.animalManagers[uuid] = nil
self.securityManagers[uuid] = nil
self.playerPlots[player] = nil
self.plotsByUUID[uuid] = nil
plot:Destroy()
end
function PlotManager:GetPlayerPlot(player)
return self.playerPlots[player]
end
function PlotManager:GetPlotByUUID(uuid)
return self.plotsByUUID[uuid]
end
function PlotManager:GetPlayerPlotModel(player)
local plot = self.playerPlots[player]
return plot and plot:GetPlotModel() or nil
end
function PlotManager:GetAnimalManager(plot)
local uuid = plot:GetUUID()
return self.animalManagers[uuid]
end
function PlotManager:GetSecurityManager(plot)
local uuid = plot:GetUUID()
return self.securityManagers[uuid]
end
function PlotManager:HandlePlayerRebirth(player, newTier)
local plot = self.playerPlots[player]
if not plot then
return false
end
local success, err = pcall(function()
plot:UpdateForRebirth(newTier)
local updatedAnimalList = DataManagement.getAnimalList(player)
plot:SetAnimalList(updatedAnimalList)
if plot.ApplyAppropriateSkin then
plot:ApplyAppropriateSkin()
end
end)
if not success then
return false
end
return true
end
function PlotManager:_setupCharacterSpawning(player)
player.CharacterAdded:Connect(function(character)
local plot = self.playerPlots[player]
if plot then
task.wait(PlotConstants.VISUAL.SPAWN_WAIT_TIME)
plot:TeleportOwnerToSpawn()
end
end)
end
function PlotManager:GetAllPlots()
local plots = {}
for _, plot in pairs(self.plotsByUUID) do
table.insert(plots, plot)
end
return plots
end
function PlotManager:GetPlotsByOwner(player)
local plots = {}
for _, plot in pairs(self.plotsByUUID) do
if plot:GetOwner() == player then
table.insert(plots, plot)
end
end
return plots
end
function PlotManager:GetStats()
local stats = {
totalPlots = 0,
activePlayers = 0,
plotDetails = {},
componentManagers = {
animalManagers = 0,
securityManagers = 0
}
}
for player, plot in pairs(self.playerPlots) do
stats.totalPlots = stats.totalPlots + 1
stats.activePlayers = stats.activePlayers + 1
local uuid = plot:GetUUID()
stats.plotDetails[uuid] = {
owner = player.Name,
tier = plot.tier,
isActive = plot:IsActive(),
isLocked = plot:IsLocked(),
animalCount = 0
}
local animalList = plot:GetAnimalList()
for _, animal in pairs(aniFirstFlooralList) do
if animal ~= PlotConstants.STATES.EMPTY and typeof(animal) == "table" then
stats.plotDetails[uuid].animalCount = stats.plotDetails[uuid].animalCount + 1
end
end
end
for _ in pairs(self.animalManagers) do
stats.componentManagers.animalManagers = stats.componentManagers.animalManagers + 1
end
for _ in pairs(self.securityManagers) do
stats.componentManagers.securityManagers = stats.componentManagers.securityManagers + 1
end
return stats
end
function PlotManager:ValidateAllPlots()
local report = {
total = 0,
valid = 0,
issues = {},
componentIssues = {}
}
for uuid, plot in pairs(self.plotsByUUID) do
report.total = report.total + 1
local plotValid = true
local plotIssues = {}
if not plot:IsActive() then
table.insert(plotIssues, "Plot is not active")
plotValid = false
end
if not plot:GetOwner() then
table.insert(plotIssues, "Plot has no owner")
plotValid = false
end
if not plot:GetPlotModel() then
table.insert(plotIssues, "Plot has no model")
plotValid = false
end
if not plot:GetSynchronizer() then
table.insert(plotIssues, "Plot has no synchronizer")
plotValid = false
end
if not self.animalManagers[uuid] then
table.insert(plotIssues, "Missing animal manager")
plotValid = false
end
if not self.securityManagers[uuid] then
table.insert(plotIssues, "Missing security manager")
plotValid = false
end
if plotValid then
report.valid = report.valid + 1
else
report.issues[uuid] = plotIssues
end
end
return report
end
function PlotManager:Cleanup()
for player, plot in pairs(self.playerPlots) do
self:RemovePlayerPlot(player)
end
self.playerPlots = {}
self.plotsByUUID = {}
self.animalManagers = {}
self.securityManagers = {}
end
function PlotManager:EmergencyRepair()
local report = {
removed = 0,
repaired = 0,
issues = {}
}
local toRemove = {}
for uuid, plot in pairs(self.plotsByUUID) do
local owner = plot:GetOwner()
if not owner or not owner.Parent then
table.insert(toRemove, uuid)
end
end
for _, uuid in ipairs(toRemove) do
local plot = self.plotsByUUID[uuid]
if plot then
self.plotSynchronizer:UnregisterPlot(plot)
plot:Destroy()
self.plotsByUUID[uuid] = nil
self.animalManagers[uuid] = nil
self.securityManagers[uuid] = nil
report.removed = report.removed + 1
end
end
for player, plot in pairs(self.playerPlots) do
local uuid = plot:GetUUID()
if not self.plotsByUUID[uuid] then
self.plotsByUUID[uuid] = plot
report.repaired = report.repaired + 1
end
end
return report
end
return PlotManager - Edit
03:12:20.446
- Edit
03:12:20.446
============================== - Edit
03:12:20.446 📜 ServerScriptService.Services.Plots.PlotSynchronizer - Edit
03:12:20.446 ==============================
- Edit
03:12:20.447 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Synchronizer = require(ReplicatedStorage.Packages.Synchronizer)
local PlotSynchronizer = {}
PlotSynchronizer.__index = PlotSynchronizer
function PlotSynchronizer.new()
local self = setmetatable({}, PlotSynchronizer)
self.activePlots = {}
self:_setupPlayerManagement()
return self
end
function PlotSynchronizer:_setupPlayerManagement()
Players.PlayerAdded:Connect(function(player)
for uuid, plotSynchronizer in pairs(self.activePlots) do
plotSynchronizer:AddListener(player)
end
end)
Players.PlayerRemoving:Connect(function(player)
for uuid, plotSynchronizer in pairs(self.activePlots) do
plotSynchronizer:RemoveListener(player)
end
end)
end
function PlotSynchronizer:RegisterPlot(plot)
local uuid = plot:GetUUID()
local synchronizer = plot:GetSynchronizer()
self.activePlots[uuid] = synchronizer
for _, player in pairs(Players:GetPlayers()) do
synchronizer:AddListener(player)
end
end
function PlotSynchronizer:UnregisterPlot(plot)
local uuid = plot:GetUUID()
local synchronizer = plot:GetSynchronizer()
if not synchronizer then
return
end
for _, player in pairs(Players:GetPlayers()) do
synchronizer:RemoveListener(player)
end
self.activePlots[uuid] = nil
end
function PlotSynchronizer:GetPlotSynchronizer(uuid)
return self.activePlots[uuid]
end
function PlotSynchronizer:BroadcastToAllPlots(key, value)
for uuid, synchronizer in pairs(self.activePlots) do
synchronizer:Set(key, value)
end
end
function PlotSynchronizer:AddListenerToAllPlots(player)
for uuid, synchronizer in pairs(self.activePlots) do
synchronizer:AddListener(player)
end
end
function PlotSynchronizer:RemoveListenerFromAllPlots(player)
for uuid, synchronizer in pairs(self.activePlots) do
synchronizer:RemoveListener(player)
end
end
function PlotSynchronizer:GetStats()
local stats = {
activePlots = 0,
totalListeners = 0,
plotDetails = {}
}
for uuid, synchronizer in pairs(self.activePlots) do
stats.activePlots = stats.activePlots + 1
local listenerCount = 0
for _, player in pairs(Players:GetPlayers()) do
listenerCount = listenerCount + 1
end
stats.totalListeners = stats.totalListeners + listenerCount
stats.plotDetails[uuid] = {
listeners = listenerCount,
owner = synchronizer:Get("Owner") and synchronizer:Get("Owner").Name or "Unknown",
animalCount = 0,
}
local animalList = synchronizer:Get("AnimalList") or {}
for _, animal in pairs(animalList) do
if animal ~= "Empty" and typeof(animal) == "table" then
stats.plotDetails[uuid].animalCount = stats.plotDetails[uuid].animalCount + 1
end
end
end
return stats
end
function PlotSynchronizer:ForceSyncPlot(plot)
local uuid = plot:GetUUID()
local synchronizer = self.activePlots[uuid]
local currentData = {
AnimalList = synchronizer:Get("AnimalList"),
FriendsAllowed = synchronizer:Get("FriendsAllowed"),
BlockEndTime = synchronizer:Get("BlockEndTime"),
BlockedDelayTime = synchronizer:Get("BlockedDelayTime"),
}
for key, value in pairs(currentData) do
synchronizer:Set(key, value)
end
end
function PlotSynchronizer:Cleanup()
for uuid, synchronizer in pairs(self.activePlots) do
for _, player in pairs(Players:GetPlayers()) do
synchronizer:RemoveListener(player)
end
synchronizer:Destroy()
end
self.activePlots = {}
end
function PlotSynchronizer:IsPlotSynchronized(plot)
local uuid = plot:GetUUID()
local synchronizer = self.activePlots[uuid]
if not synchronizer then
return false
end
local requiredKeys = {
"Owner",
"AnimalList",
"FriendsAllowed",
"BlockEndTime",
"BlockedDelayTime",
"BlockEndTimeFirstFloor",
"BlockEndTimeSecondFloor",
"BlockEndTimeThirdFloor"
}
for _, key in ipairs(requiredKeys) do
local success, value = pcall(function()
return synchronizer:Get(key)
end)
end
return true
end
function PlotSynchronizer:RepairPlotSync(plot)
local uuid = plot:GetUUID()
if self.activePlots[uuid] then
local oldSync = self.activePlots[uuid]
for _, player in pairs(Players:GetPlayers()) do
pcall(function()
oldSync:RemoveListener(player)
end)
end
pcall(function()
oldSync:Destroy()
end)
self.activePlots[uuid] = nil
end
self:RegisterPlot(plot)
return self:IsPlotSynchronized(plot)
end
function PlotSynchronizer:ValidateAllPlots()
local report = {
total = 0,
valid = 0,
repaired = 0,
failed = 0,
details = {}
}
local plotsToCheck = {}
for uuid, _ in pairs(self.activePlots) do
table.insert(plotsToCheck, uuid)
end
report.total = #plotsToCheck
for _, uuid in ipairs(plotsToCheck) do
local synchronizer = self.activePlots[uuid]
if synchronizer then
local owner = synchronizer:Get("Owner")
local ownerName = owner and owner.Name or "Unknown"
local mockPlot = {
GetUUID = function() return uuid end,
GetSynchronizer = function() return synchronizer end
}
if self:IsPlotSynchronized(mockPlot) then
report.valid = report.valid + 1
report.details[uuid] = {
status = "valid",
owner = ownerName
}
else
local repairSuccess = self:RepairPlotSync(mockPlot)
if repairSuccess then
report.repaired = report.repaired + 1
report.details[uuid] = {
status = "repaired",
owner = ownerName
}
else
report.failed = report.failed + 1
report.details[uuid] = {
status = "failed",
owner = ownerName
}
end
end
end
end
return report
end
return PlotSynchronizer - Edit
03:12:20.447
- Edit
03:12:20.447
============================== - Edit
03:12:20.447 📜 ServerScriptService.Services.Plots.PlotSecurity - Edit
03:12:20.447 ==============================
- Edit
03:12:20.447 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local PlotConstants = require(script.Parent.PlotConstants)
local Friends = require(ReplicatedStorage.Shared.Friends)
local PlotSecurity = {}
PlotSecurity.__index = PlotSecurity
function PlotSecurity.new(plot)
local self = setmetatable({}, PlotSecurity)
self.plot = plot
return self
end
function PlotSecurity:CanPlayerAccess(player)
local owner = self.plot:GetOwner()
if player == owner then
return true
end
if self:IsBaseLocked() then
if self.plot:GetFriendsAllowed() then
local inGameFriends = Friends:GetInGameFriends(owner)
return table.find(inGameFriends, player) ~= nil
end
return false
end
return true
end
function PlotSecurity:CanPlayerAccessFloor(player, floor)
local owner = self.plot:GetOwner()
if player == owner then
return true
end
if self:IsFloorLocked(floor) then
if self.plot:GetFriendsAllowed() then
local inGameFriends = Friends:GetInGameFriends(owner)
return table.find(inGameFriends, player) ~= nil
end
return false
end
return true
end
function PlotSecurity:IsBaseLocked()
local synchronizer = self.plot:GetSynchronizer()
return synchronizer:Get("BlockEndTime") ~= nil
end
function PlotSecurity:IsFloorLocked(floor)
if floor < 1 or floor > 3 then
return false
end
local synchronizer = self.plot:GetSynchronizer()
local floorKey = PlotConstants.FLOOR_KEYS[floor]
return synchronizer:Get(floorKey) ~= nil
end
function PlotSecurity:IsInDelayPeriod()
local synchronizer = self.plot:GetSynchronizer()
return synchronizer:Get("BlockedDelayTime") ~= nil
end
function PlotSecurity:GetRemainingLockTime()
if not self:IsBaseLocked() then
return 0
end
local synchronizer = self.plot:GetSynchronizer()
local lockEndTime = synchronizer:Get("BlockEndTime")
local currentTime = workspace:GetServerTimeNow()
return math.max(0, lockEndTime - currentTime)
end
function PlotSecurity:GetRemainingFloorLockTime(floor)
if not self:IsFloorLocked(floor) then
return 0
end
local synchronizer = self.plot:GetSynchronizer()
local floorKey = PlotConstants.FLOOR_KEYS[floor]
local lockEndTime = synchronizer:Get(floorKey)
local currentTime = workspace:GetServerTimeNow()
return math.max(0, lockEndTime - currentTime)
end
function PlotSecurity:GetRemainingDelayTime()
if not self:IsInDelayPeriod() then
return 0
end
local synchronizer = self.plot:GetSynchronizer()
local delayEndTime = synchronizer:Get("BlockedDelayTime")
local currentTime = workspace:GetServerTimeNow()
return math.max(0, delayEndTime - currentTime)
end
function PlotSecurity:ToggleFriendsAccess()
local currentState = self.plot:GetFriendsAllowed()
local newState = not currentState
self.plot:SetFriendsAllowed(newState)
self:UpdateHitboxStates()
return newState
end
function PlotSecurity:UpdateHitboxStates()
local plotModel = self.plot:GetPlotModel()
if not plotModel then
return
end
local laserHitbox = plotModel:FindFirstChild("LaserHitbox")
if not laserHitbox then
return
end
local owner = self.plot:GetOwner()
local inGameFriends = Friends:GetInGameFriends(owner)
local friendsAllowed = self.plot:GetFriendsAllowed()
for _, hitbox in pairs(laserHitbox:GetChildren()) do
local floor = hitbox:GetAttribute("Floor")
if floor and floor >= 1 and floor <= 3 then
local isServerControlled = hitbox:GetAttribute("ServerControlled")
if isServerControlled then
continue
end
local floorLocked = self:IsFloorLocked(floor)
for _, player in pairs(Players:GetPlayers()) do
if player == owner then
hitbox.CanCollide = false
elseif floorLocked then
local isFriend = table.find(inGameFriends, player) ~= nil
hitbox.CanCollide = not (friendsAllowed and isFriend)
else
hitbox.CanCollide = false
end
end
else
local baseLocked = self:IsBaseLocked()
for _, player in pairs(Players:GetPlayers()) do
if player == owner then
hitbox.CanCollide = false
elseif baseLocked then
local isFriend = table.find(inGameFriends, player) ~= nil
hitbox.CanCollide = not (friendsAllowed and isFriend)
else
hitbox.CanCollide = false
end
end
end
end
end
function PlotSecurity:IsPlayerInStealHitbox(player)
local character = player.Character
if not character then
return false
end
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if not humanoidRootPart then
return false
end
local plotModel = self.plot:GetPlotModel()
if not plotModel then
return false
end
local stealHitbox = plotModel:FindFirstChild("StealHitbox")
if not stealHitbox then
return true
end
local hitboxCFrame = stealHitbox.CFrame
local hitboxSize = stealHitbox.Size
local playerPosition = humanoidRootPart.Position
local localPosition = hitboxCFrame:PointToObjectSpace(playerPosition)
local halfSize = hitboxSize * 0.5
local isInside = math.abs(localPosition.X) <= halfSize.X and
math.abs(localPosition.Y) <= halfSize.Y and
math.abs(localPosition.Z) <= halfSize.Z
return isInside
end
function PlotSecurity:CanPlayerSteal(player)
local owner = self.plot:GetOwner()
if player == owner then
return false, "Cannot steal from your own plot"
end
local isInHitbox = self:IsPlayerInStealHitbox(player)
if not isInHitbox then
local plotModel = self.plot:GetPlotModel()
local stealHitbox = plotModel and plotModel:FindFirstChild("StealHitbox")
if stealHitbox and player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
local rootPos = player.Character.HumanoidRootPart.Position
local hitboxPos = stealHitbox.Position
local distance = (rootPos - hitboxPos).Magnitude
print("[PlotSecurity] Player", player.Name, "failed StealHitbox check. Distance:", distance, "HitboxSize:", stealHitbox.Size)
end
return false, "You must be inside the base to steal animals"
end
return true, nil
end
function PlotSecurity:ValidateStealAttempt(player, timestamp)
if not timestamp then
return false, "Invalid timestamp"
end
local serverTime = workspace:GetServerTimeNow()
local adjustedTimestamp = timestamp - PlotConstants.SECURITY.TIMESTAMP_OFFSET
if math.abs(serverTime - adjustedTimestamp) > PlotConstants.SECURITY.TIMESTAMP_TOLERANCE then
return false, "Timestamp out of range"
end
local canSteal, reason = self:CanPlayerSteal(player)
if not canSteal then
return false, reason
end
return true, nil
end
function PlotSecurity:GetSecurityStatus()
return {
baseLocked = self:IsBaseLocked(),
inDelayPeriod = self:IsInDelayPeriod(),
friendsAllowed = self.plot:GetFriendsAllowed(),
remainingLockTime = self:GetRemainingLockTime(),
remainingDelayTime = self:GetRemainingDelayTime(),
floorLocks = {
[1] = self:IsFloorLocked(1),
[2] = self:IsFloorLocked(2),
[3] = self:IsFloorLocked(3),
},
floorLockTimes = {
[1] = self:GetRemainingFloorLockTime(1),
[2] = self:GetRemainingFloorLockTime(2),
[3] = self:GetRemainingFloorLockTime(3),
}
}
end
return PlotSecurity - Edit
03:12:20.447
- Edit
03:12:20.447
============================== - Edit
03:12:20.447 📜 ServerScriptService.Services.Plots.AnimalManager - Edit
03:12:20.447 ==============================
- Edit
03:12:20.447 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local PlotConstants = require(script.Parent.PlotConstants)
local DataManagement = require(ServerScriptService.Services.DataManagment)
local Animals = require(ReplicatedStorage.Shared.Animals)
local AnimalManager = {}
AnimalManager.__index = AnimalManager
function AnimalManager.new(plot)
local self = setmetatable({}, AnimalManager)
self.plot = plot
return self
end
function AnimalManager:ValidateAndRepairAnimalList(animalList)
local needsRepair = false
local cleanedList = {}
for i, animal in pairs(animalList) do
if animal == PlotConstants.STATES.EMPTY or animal == nil then
cleanedList[i] = PlotConstants.STATES.EMPTY
elseif typeof(animal) == "table" then
if animal.Index then
cleanedList[i] = animal
else
cleanedList[i] = PlotConstants.STATES.EMPTY
needsRepair = true
end
else
cleanedList[i] = PlotConstants.STATES.EMPTY
needsRepair = true
end
end
if needsRepair then
self:_updateAnimalListEverywhere(cleanedList)
end
return cleanedList
end
function AnimalManager:ClaimCoins(slot)
local owner = self.plot:GetOwner()
local animalList = self.plot:GetAnimalList()
local animal = animalList[slot]
if not animal or typeof(animal) ~= "table" or not animal.LastCollect then
return false, 0
end
local currentTime = workspace:GetServerTimeNow()
local regularCoins = math.floor((currentTime - animal.LastCollect) *
Animals:GetGeneration(animal.Index, animal.Mutation, animal.Traits or {}, owner))
local offlineCoins = 0
if animal.OfflineGain then
offlineCoins = math.floor(animal.OfflineGain *
Animals:GetGeneration(animal.Index, animal.Mutation, animal.Traits or {}, owner))
end
local totalCoins = regularCoins + offlineCoins
if totalCoins <= 0 then
return false, 0
end
DataManagement.addCoins(owner, totalCoins)
animalList[slot].LastCollect = currentTime
animalList[slot].OfflineGain = nil
DataManagement.updateAnimal(owner, slot, {
LastCollect = currentTime,
OfflineGain = nil
})
self.plot:SetAnimalList(animalList)
task.wait(0.1)
local Synchronizer = require(ReplicatedStorage.Packages.Synchronizer)
local playerSync = Synchronizer:Get(owner)
if playerSync then
local updatedData = DataManagement.GetDataMan(owner)
if updatedData then
playerSync:Set("Coins", updatedData.Coins)
end
end
return true, totalCoins
end
function AnimalManager:SellAnimal(slot)
local owner = self.plot:GetOwner()
local animalList = self.plot:GetAnimalList()
local animal = animalList[slot]
if not animal or typeof(animal) ~= "table" or not animal.Index then
return false, 0
end
local sellValue = Animals:GetSellValue(animal.Index)
DataManagement.addCoins(owner, sellValue)
DataManagement.removeAnimal(owner, slot)
local updatedAnimalList = DataManagement.getAnimalList(owner)
self.plot:SetAnimalList(updatedAnimalList)
task.wait(0.1)
local Synchronizer = require(ReplicatedStorage.Packages.Synchronizer)
local playerSync = Synchronizer:Get(owner)
if playerSync then
local updatedData = DataManagement.GetDataMan(owner)
if updatedData then
playerSync:Set("Coins", updatedData.Coins)
end
end
return true, sellValue
end
function AnimalManager:AddAnimal(animalIndex, mutation, traits)
local owner = self.plot:GetOwner()
local addedSlot = DataManagement.addAnimal(owner, animalIndex, mutation, traits)
if not addedSlot then
return false, nil
end
local updatedAnimalList = DataManagement.getAnimalList(owner)
self.plot:SetAnimalList(updatedAnimalList)
local Synchronizer = require(ReplicatedStorage.Packages.Synchronizer)
local playerSync = Synchronizer:Get(owner)
if playerSync then
playerSync:Set("AnimalAddedOrRemoved", updatedAnimalList)
playerSync:Set("AnimalPodiums", updatedAnimalList)
end
return true, addedSlot
end
function AnimalManager:RemoveAnimal(slot)
local owner = self.plot:GetOwner()
local removedAnimal = DataManagement.removeAnimal(owner, slot)
if not removedAnimal then
return false, nil
end
local updatedAnimalList = DataManagement.getAnimalList(owner)
self.plot:SetAnimalList(updatedAnimalList)
local Synchronizer = require(ReplicatedStorage.Packages.Synchronizer)
local playerSync = Synchronizer:Get(owner)
if playerSync then
playerSync:Set("AnimalAddedOrRemoved", updatedAnimalList)
playerSync:Set("AnimalPodiums", updatedAnimalList)
end
return true, removedAnimal
end
function AnimalManager:FindEmptySlot()
local owner = self.plot:GetOwner()
if not DataManagement.isDataReady(owner) then
return nil
end
local animalList = DataManagement.getAnimalList(owner)
if not animalList then
return nil
end
for slot, animal in pairs(animalList) do
if animal == PlotConstants.STATES.EMPTY or animal == nil then
return slot
end
end
return nil
end
function AnimalManager:GetNonEmptySlots()
local owner = self.plot:GetOwner()
if not DataManagement.isDataReady(owner) then
return {}
end
local animalList = DataManagement.getAnimalList(owner)
if not animalList then
return {}
end
local nonEmptySlots = {}
for slot, animal in pairs(animalList) do
if animal and animal ~= PlotConstants.STATES.EMPTY and typeof(animal) == "table" and animal.Index then
table.insert(nonEmptySlots, slot)
end
end
return nonEmptySlots
end
function AnimalManager:HasValidAnimal(slot)
local animalList = self.plot:GetAnimalList()
local animal = animalList[slot]
return animal and typeof(animal) == "table" and animal.Index ~= nil
end
function AnimalManager:SetStealState(slot, isBeingStolen)
local animalList = self.plot:GetAnimalList()
if animalList[slot] and typeof(animalList[slot]) == "table" then
animalList[slot].Steal = isBeingStolen
local sync = self.plot:GetSynchronizer()
if sync then
sync:Set(("AnimalList.%d.Steal"):format(slot), isBeingStolen)
end
end
end
function AnimalManager:GetAnimal(slot)
local animalList = self.plot:GetAnimalList()
return animalList[slot]
end
function AnimalManager:_updateAnimalListEverywhere(animalList)
local owner = self.plot:GetOwner()
self.plot:SetAnimalList(animalList)
local playerData = DataManagement.GetDataMan(owner)
if playerData then
playerData.AnimalList = animalList
end
local Synchronizer = require(ReplicatedStorage.Packages.Synchronizer)
local playerSync = Synchronizer:Get(owner)
if playerSync then
playerSync:Set("AnimalAddedOrRemoved", animalList)
playerSync:Set("AnimalPodiums", animalList)
end
end
return AnimalManager - Edit
03:12:20.447
- Edit
03:12:20.447
============================== - Edit
03:12:20.447 📜 ServerScriptService.Services.Plots.Plot - Edit
03:12:20.447 ==============================
- Edit
03:12:20.448 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local HttpService = game:GetService("HttpService")
local CollectionService = game:GetService("CollectionService")
local Players = game:GetService("Players")
local PlotConstants = require(script.Parent.PlotConstants)
local Synchronizer = require(ReplicatedStorage.Packages.Synchronizer)
local PlotRainbow = require(script.PlotRainbow)
local PlotDiamond = require(script.PlotDiamond)
local PlotGold = require(script.PlotGold)
local PlotCandy = require(script.PlotCandy)
local Plot = {}
Plot.__index = Plot
function Plot.new(owner, tier, initialData)
local self = setmetatable({}, Plot)
self.uuid = HttpService:GenerateGUID(false)
self.owner = owner
self.tier = tier
self.plotModel = nil
self.synchronizer = nil
self.isActive = true
self.isLocked = false
self:_initializeSynchronizer(initialData or {})
self:_createPlotModel()
self:_initializePlotState()
return self
end
function Plot:_initializeSynchronizer(initialData)
self.synchronizer = Synchronizer:Create(self.uuid, {
Owner = self.owner,
AnimalList = initialData.AnimalList or {},
FriendsAllowed = false,
BlockedDelayTime = nil,
BlockEndTime = nil,
BlockEndTimeFirstFloor = nil,
BlockEndTimeSecondFloor = nil,
BlockEndTimeThirdFloor = nil,
})
for _, player in pairs(Players:GetPlayers()) do
self.synchronizer:AddListener(player)
end
end
function Plot:_createPlotModel()
local BasesData = require(ReplicatedStorage.Datas.Bases)
local tierData = BasesData[self.tier]
local baseModel = tierData.Model
local availableSlot = self:_findAvailablePlotSlot()
local plotModel = baseModel:Clone()
local pivotCFrame = availableSlot:GetPivot()
local newPivotCFrame = CFrame.new(
Vector3.new(pivotCFrame.X, -10, pivotCFrame.Z)
) * CFrame.Angles(pivotCFrame:ToEulerAnglesXYZ())
plotModel:PivotTo(newPivotCFrame)
plotModel.PlotSign.YourBase.Enabled = false
plotModel.Parent = workspace.Plots
plotModel.Name = self.uuid
plotModel:SetAttribute("Tier", self.tier)
plotModel:SetAttribute("Owner", self.owner.UserId)
CollectionService:AddTag(plotModel, "Plot")
self.plotModel = plotModel
self:_updatePlotVisuals(plotModel)
self:_ensureBaseRewardsApplied()
self:ApplyAppropriateSkin()
self:_ensureSpawnPoint(plotModel)
local animalPodiumsFolder = plotModel:FindFirstChild("AnimalPodiums")
if animalPodiumsFolder then
local BasesData = require(ReplicatedStorage.Datas.Bases)
self:_optimizeAnimalPodiums(BasesData[self.tier].MaxAnimals)
end
availableSlot:Destroy()
self:_ensurePurchaseGuiElements(plotModel)
end
function Plot:_ensureBaseRewardsApplied()
local DataManagement = require(game.ServerScriptService.Services.DataManagment)
local Animals = require(ReplicatedStorage.Datas.Animals)
if not DataManagement.isDataReady(self.owner) then
local success = DataManagement.waitForData(self.owner, 15)
end
local data = DataManagement.GetDataMan(self.owner)
local function hasFullSet(mutation)
local animalCount = 0
local ownedCount = 0
for id, animalData in pairs(Animals) do
if not animalData.HideFromIndex then
animalCount = animalCount + 1
if data.Index[id] and data.Index[id][mutation] then
ownedCount = ownedCount + 1
end
end
end
return ownedCount == animalCount
end
local mutations = {"Candy", "Rainbow", "Diamond", "Gold", "Default"}
local appliedReward = false
for _, mutation in pairs(mutations) do
if hasFullSet(mutation) then
if self.RefreshMultiplier then
self:RefreshMultiplier()
end
if mutation == "Candy" and self.ApplyCandySkin then
self:ApplyCandySkin()
appliedReward = true
break
elseif mutation == "Rainbow" and self.ApplyRainbowSkin then
self:ApplyRainbowSkin()
appliedReward = true
break
elseif mutation == "Diamond" and self.ApplyDiamondSkin then
self:ApplyDiamondSkin()
appliedReward = true
break
elseif mutation == "Gold" and self.ApplyGoldSkin then
self:ApplyGoldSkin()
appliedReward = true
break
end
end
end
end
function Plot:_findAvailablePlotSlot()
local plotsFolder = workspace:FindFirstChild("Plots")
if not plotsFolder then
return nil
end
local function tryClaim(candidate)
if candidate and not candidate:GetAttribute("Owner") then
candidate:SetAttribute("Owner", self.owner.UserId)
if candidate:GetAttribute("Owner") == self.owner.UserId then
return true
else
return false
end
end
return false
end
for _, plot in pairs(plotsFolder:GetChildren()) do
if CollectionService:HasTag(plot, "Plot") and tryClaim(plot) then
return plot
end
end
for _, plot in pairs(plotsFolder:GetChildren()) do
if tryClaim(plot) then
return plot
end
end
return nil
end
function Plot:_updatePlotVisuals(plotModel)
local plotSign = plotModel:FindFirstChild("PlotSign")
if plotSign and plotSign.SurfaceGui then
plotSign.SurfaceGui.Frame.TextLabel.Text = self.owner.Name .. "'s Base"
end
local multiplierDisplay = plotModel:FindFirstChild("Multiplier")
if multiplierDisplay then
local multiplier = self:_calculateMultiplier()
multiplierDisplay.Main.Amount.Text = "x" .. multiplier
end
end
function Plot:_calculateMultiplier()
local DataManagement = require(game.ServerScriptService.Services.DataManagment)
local Rebirths = require(ReplicatedStorage.Datas.Rebirth)
local Mutations = require(ReplicatedStorage.Datas.Mutations)
local playerData = DataManagement.GetDataMan(self.owner)
if not playerData then return 1 end
local totalMultiplier = 1
local rebirthData = Rebirths[playerData.Rebirths]
if rebirthData and rebirthData.Rewards and rebirthData.Rewards.Multiplier then
totalMultiplier = totalMultiplier + rebirthData.Rewards.Multiplier
end
local index = playerData.Index or {}
local mutationKeys = { Default = true, Gold = true, Diamond = true, Rainbow = true, Candy = true }
local Animals = require(ReplicatedStorage.Datas.Animals)
local completedSets = 0
for mutation in pairs(mutationKeys) do
local allOwned = true
for animalName, animalData in pairs(Animals) do
if not animalData.HideFromIndex then
local entry = index[animalName]
if not (entry and entry[mutation]) then
allOwned = false
break
end
end
end
if allOwned then
completedSets += 1
end
end
if completedSets > 0 then
totalMultiplier = totalMultiplier + 0.5 * completedSets
end
return totalMultiplier
end
function Plot:_initializePlotState()
local currentTime = workspace:GetServerTimeNow()
self.synchronizer:Set("BlockedDelayTime", currentTime + PlotConstants.TIMING.DELAY_TIME)
task.delay(PlotConstants.TIMING.DELAY_TIME, function()
if not self.isActive then return end
self:_startLockTimer()
end)
end
function Plot:_startLockTimer()
local currentTime = workspace:GetServerTimeNow()
local lockDuration = self:_calculateLockDuration()
self.synchronizer:Set("BlockedDelayTime", nil)
local lockEndTime = currentTime + lockDuration
self.synchronizer:Set("BlockEndTime", lockEndTime)
self.synchronizer:Set("BlockEndTimeFirstFloor", lockEndTime)
self.synchronizer:Set("BlockEndTimeSecondFloor", lockEndTime)
self.synchronizer:Set("BlockEndTimeThirdFloor", lockEndTime)
self.isLocked = true
self:_updateLaserAndHitboxStates(true)
task.delay(lockDuration, function()
if not self.isActive then return end
self:_unlockBase()
end)
end
function Plot:_calculateLockDuration()
local DataManagement = require(game.ServerScriptService.Services.DataManagment)
local Rebirths = require(ReplicatedStorage.Datas.Rebirth)
local playerData = DataManagement.GetDataMan(self.owner)
if not playerData then
return PlotConstants.TIMING.DEFAULT_LOCK_TIME
end
local additionalTime = 0
if playerData.Rebirths > 0 then
local rebirthData = Rebirths[playerData.Rebirths]
if rebirthData and rebirthData.Rewards and rebirthData.Rewards.AdditionalLockTime then
additionalTime = rebirthData.Rewards.AdditionalLockTime
end
end
return PlotConstants.TIMING.DEFAULT_LOCK_TIME + additionalTime
end
function Plot:_unlockBase()
local lockEndTime = self.synchronizer:Get("BlockEndTime")
if lockEndTime == nil then
return
end
local now = workspace:GetServerTimeNow()
local remaining = lockEndTime - now
if remaining > 0 then
task.delay(remaining, function()
self:_unlockBase()
end)
return
end
self.synchronizer:Set("BlockEndTime", nil)
self.synchronizer:Set("BlockEndTimeFirstFloor", nil)
self.synchronizer:Set("BlockEndTimeSecondFloor", nil)
self.synchronizer:Set("BlockEndTimeThirdFloor", nil)
self.isLocked = false
self:_updateLaserAndHitboxStates(false)
end
function Plot:_updateLaserAndHitboxStates(isLocked)
if not self.plotModel then return end
local MonetizationService = _G.MonetizationService
if MonetizationService and MonetizationService.GetBaseLockHandler then
local handler = MonetizationService:GetBaseLockHandler()
if handler then
handler:UpdateAllFloorStates(self.owner)
return
end
end
local laser = self.plotModel:FindFirstChild("Laser")
local laserHitbox = self.plotModel:FindFirstChild("LaserHitbox")
if not laser or not laserHitbox then return end
for _, hitbox in pairs(laserHitbox:GetChildren()) do
local floor = hitbox:GetAttribute("Floor")
if floor and floor >= 1 and floor <= 3 then
local floorKey = PlotConstants.FLOOR_KEYS[floor]
local floorLocked = self.synchronizer:Get(floorKey) ~= nil
hitbox.CanCollide = floorLocked
if not floorLocked then
hitbox:SetAttribute("ServerControlled", true)
else
hitbox:SetAttribute("ServerControlled", nil)
end
else
hitbox.CanCollide = isLocked
if isLocked then
hitbox:SetAttribute("ServerControlled", nil)
end
end
end
for _, laserModel in pairs(laser:GetChildren()) do
if laserModel:IsA("Model") then
local floor = laserModel:GetAttribute("Floor")
if floor and floor >= 1 and floor <= 3 then
local floorKey = PlotConstants.FLOOR_KEYS[floor]
local floorLocked = self.synchronizer:Get(floorKey) ~= nil
for _, laserPart in pairs(laserModel:GetDescendants()) do
if laserPart:IsA("BasePart") then
laserPart.Transparency = floorLocked and 0 or 1
end
end
else
for _, laserPart in pairs(laserModel:GetDescendants()) do
if laserPart:IsA("BasePart") then
laserPart.Transparency = isLocked and 0 or 1
end
end
end
elseif laserModel:IsA("BasePart") then
laserModel.Transparency = isLocked and 0 or 1
end
end
end
function Plot:GetUUID()
return self.uuid
end
function Plot:GetOwner()
return self.owner
end
function Plot:GetSynchronizer()
return self.synchronizer
end
function Plot:GetPlotModel()
return self.plotModel
end
function Plot:IsActive()
return self.isActive
end
function Plot:IsLocked()
return self.isLocked
end
function Plot:GetAnimalList()
return self.synchronizer:Get("AnimalList") or {}
end
function Plot:SetAnimalList(animalList)
self.synchronizer:Set("AnimalList", animalList)
self.synchronizer:Set("AnimalPodiums", animalList)
end
function Plot:GetFriendsAllowed()
return self.synchronizer:Get("FriendsAllowed") or false
end
function Plot:SetFriendsAllowed(allowed)
self.synchronizer:Set("FriendsAllowed", allowed)
end
function Plot:AddListener(player)
if self.synchronizer then
self.synchronizer:AddListener(player)
end
end
function Plot:RemoveListener(player)
if self.synchronizer then
self.synchronizer:RemoveListener(player)
end
end
function Plot:TeleportOwnerToSpawn()
if not self.owner then
return false
end
if not self.owner.Character then
return false
end
local humanoidRootPart = self.owner.Character:FindFirstChild("HumanoidRootPart")
if not humanoidRootPart then
return false
end
if not self.plotModel then
return false
end
local spawn = self.plotModel:FindFirstChild("Spawn")
if not spawn then
spawn = self:_ensureSpawnPoint(self.plotModel)
end
if not spawn or not spawn.CFrame then
return false
end
local success, err = pcall(function()
humanoidRootPart.CFrame = spawn.CFrame
end)
end
function Plot:UpdateForRebirth(newTier)
if not self.plotModel then return end
local Bases = require(ReplicatedStorage.Datas.Bases)
local currentTierData = Bases[self.tier]
local newTierData = Bases[newTier]
local needsModelChange = not currentTierData or currentTierData.Model ~= newTierData.Model
if needsModelChange then
self:_recreateFullPlotModel(newTier)
else
self:_optimizeAnimalPodiums(newTierData.MaxAnimals)
self.tier = newTier
self.plotModel:SetAttribute("Tier", newTier)
end
self:_setupRebirthCharacterHandler()
end
function Plot:_recreateFullPlotModel(newTier)
local currentPivot = self.plotModel:GetPivot()
local oldSpawnCFrame
local oldSpawnPart = self.plotModel:FindFirstChild("Spawn")
if oldSpawnPart then
oldSpawnCFrame = oldSpawnPart.CFrame
else
oldSpawnCFrame = currentPivot
end
self.plotModel:Destroy()
local BasesData = require(ReplicatedStorage.Datas.Bases)
local newTierData = BasesData[newTier]
local baseModel = newTierData.Model
local newPlotModel = baseModel:Clone()
local targetPivotCFrame
local newSpawnPart = newPlotModel:FindFirstChild("Spawn")
if newSpawnPart and oldSpawnCFrame then
local relative = newPlotModel:GetPivot():ToObjectSpace(newSpawnPart.CFrame)
targetPivotCFrame = oldSpawnCFrame * relative:Inverse()
else
targetPivotCFrame = currentPivot
end
newPlotModel:PivotTo(targetPivotCFrame)
self:_ensureSpawnPoint(newPlotModel)
newPlotModel.PlotSign.YourBase.Enabled = false
newPlotModel.Parent = workspace.Plots
newPlotModel.Name = self.uuid
newPlotModel:SetAttribute("Tier", newTier)
newPlotModel:SetAttribute("Owner", self.owner.UserId)
local animalPodiums = newPlotModel:FindFirstChild("AnimalPodiums")
if not animalPodiums then
animalPodiums = Instance.new("Folder")
animalPodiums.Name = "AnimalPodiums"
animalPodiums.Parent = newPlotModel
end
self.tier = newTier
self:_tagPlotModelDelayed(newPlotModel)
self.plotModel = newPlotModel
self:_updatePlotVisuals(newPlotModel)
self:ApplyAppropriateSkin()
self:_updateLaserAndHitboxStates(false)
self:_initializePlotState()
local BasesData = require(ReplicatedStorage.Datas.Bases)
self:_optimizeAnimalPodiums(BasesData[newTier].MaxAnimals)
end
function Plot:_optimizeAnimalPodiums(maxAnimals)
local animalPodiums = self.plotModel:FindFirstChild("AnimalPodiums")
local allPodiums = {}
for _, child in pairs(animalPodiums:GetChildren()) do
local podiumNumber = tonumber(child.Name)
if podiumNumber then
allPodiums[podiumNumber] = child
end
end
local sortedPodiumNumbers = {}
for podiumNumber, _ in pairs(allPodiums) do
table.insert(sortedPodiumNumbers, podiumNumber)
end
table.sort(sortedPodiumNumbers)
for _, podiumNumber in ipairs(sortedPodiumNumbers) do
local podium = allPodiums[podiumNumber]
if podiumNumber <= maxAnimals then
if podium:IsA("BasePart") then
podium.Transparency = 0
podium.CanCollide = true
podium.CanTouch = true
end
for _, child in pairs(podium:GetDescendants()) do
if child:IsA("BasePart") then
if child.Name == "Spawn" and child.Parent and child.Parent.Name == "Base" then
child.Transparency = 1
child.CanCollide = false
child.CanQuery = false
child.CanTouch = false
elseif child.Name == "Hitbox" and child.Parent and child.Parent.Name == "Claim" then
child.Transparency = 1
child.CanCollide = false
child.CanQuery = true
child.CanTouch = true
else
child.Transparency = 0
child.CanCollide = true
end
elseif child:IsA("SurfaceGui") or child:IsA("BillboardGui") then
child.Enabled = true
elseif child:IsA("ProximityPrompt") then
child.Enabled = true
end
end
else
if podium:IsA("BasePart") then
podium.Transparency = 1
podium.CanCollide = false
podium.CanTouch = false
end
for _, child in pairs(podium:GetDescendants()) do
if child:IsA("BasePart") then
child.Transparency = 1
child.CanCollide = false
elseif child:IsA("SurfaceGui") or child:IsA("BillboardGui") then
child.Enabled = false
elseif child:IsA("ProximityPrompt") then
child.Enabled = false
end
end
end
end
end
function Plot:_setupRebirthCharacterHandler()
local player = self.owner
if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
task.wait(0.1)
self:TeleportOwnerToSpawn()
return
end
local connection
connection = player.CharacterAdded:Connect(function(character)
connection:Disconnect()
local humanoidRootPart = character:WaitForChild("HumanoidRootPart", 5)
if humanoidRootPart and self.plotModel then
task.wait(PlotConstants.VISUAL.SPAWN_WAIT_TIME)
if self.plotModel and self.plotModel:FindFirstChild("Spawn") then
humanoidRootPart.CFrame = self.plotModel.Spawn.CFrame
end
end
end)
task.delay(30, function()
if connection then
connection:Disconnect()
end
end)
end
function Plot:Destroy()
self.isActive = false
if self.synchronizer then
for _, player in pairs(Players:GetPlayers()) do
self.synchronizer:RemoveListener(player)
end
self.synchronizer:Destroy()
end
if self.plotModel then
local oldModel = self.plotModel
local currentPivot = oldModel:GetPivot()
local oldSpawnCFrame
local oldSpawnPart = oldModel:FindFirstChild("Spawn")
if oldSpawnPart then
oldSpawnCFrame = oldSpawnPart.CFrame
end
oldModel:Destroy()
local firstFloor = ReplicatedStorage.Bases.FirstFloor
if firstFloor then
local replacementPlot = firstFloor:Clone()
local targetPivot = currentPivot
local newSpawn = replacementPlot:FindFirstChild("Spawn")
if oldSpawnCFrame and newSpawn then
local relative = replacementPlot:GetPivot():ToObjectSpace(newSpawn.CFrame)
targetPivot = oldSpawnCFrame * relative:Inverse()
end
replacementPlot:PivotTo(targetPivot)
replacementPlot.PlotSign.YourBase.Enabled = false
replacementPlot.PlotSign.SurfaceGui.Frame.TextLabel.Text = "None"
replacementPlot:SetAttribute("Owner", nil)
replacementPlot.Parent = workspace.Plots
local animalPodiums = replacementPlot:FindFirstChild("AnimalPodiums")
if animalPodiums then
for _, podium in animalPodiums:GetDescendants() do
if podium:IsA("BillboardGui") then
podium.Enabled = false
end
end
end
local laser = replacementPlot:FindFirstChild("Laser")
if laser then
for _, obj in pairs(laser:GetDescendants()) do
if obj:IsA("BasePart") then
obj.Transparency = 1
end
end
end
local laserHitbox = replacementPlot:FindFirstChild("LaserHitbox")
if laserHitbox then
for _, hb in pairs(laserHitbox:GetDescendants()) do
if hb:IsA("BasePart") then
hb.CanCollide = false
end
end
end
self:_tagPlotModelDelayed(replacementPlot)
end
end
end
function Plot:_ensureSpawnPoint(model)
if not model then return nil end
local spawnPart = model:FindFirstChild("Spawn")
if spawnPart and spawnPart:IsA("BasePart") then
return spawnPart
end
spawnPart = Instance.new("Part")
spawnPart.Name = "Spawn"
spawnPart.Size = Vector3.new(4, 1, 4)
spawnPart.Transparency = 1
spawnPart.Anchored = true
spawnPart.CanCollide = false
local pivot = model:GetPivot()
spawnPart.CFrame = pivot * CFrame.new(0, 3, 0)
spawnPart.Parent = model
return spawnPart
end
function Plot:ApplyRainbowSkin()
PlotRainbow.apply(self)
end
function Plot:ApplyDiamondSkin()
PlotDiamond.apply(self)
end
function Plot:ApplyGoldSkin()
PlotGold.apply(self)
end
function Plot:ApplyCandySkin()
PlotCandy.apply(self)
end
function Plot:ApplyAppropriateSkin()
local DataManagement = require(game.ServerScriptService.Services.DataManagment)
local Animals = require(ReplicatedStorage.Datas.Animals)
local data = DataManagement.GetDataMan(self.owner)
if not data or not data.Index then return end
local function hasFullSet(mutation)
for id, _ in pairs(Animals) do
if not (data.Index[id] and data.Index[id][mutation]) then
return false
end
end
return true
end
if hasFullSet("Candy") then
PlotCandy.apply(self)
elseif hasFullSet("Rainbow") then
PlotRainbow.apply(self)
elseif hasFullSet("Diamond") then
PlotDiamond.apply(self)
elseif hasFullSet("Gold") then
PlotGold.apply(self)
end
end
function Plot:_tagPlotModelDelayed(model)
if not model then return end
task.defer(function()
if model.Parent then
CollectionService:AddTag(model, "Plot")
end
end)
end
function Plot:RefreshMultiplier()
if not self.plotModel then return end
local multiplierDisplay = self.plotModel:FindFirstChild("Multiplier")
if multiplierDisplay then
local multiplier = self:_calculateMultiplier()
multiplierDisplay.Main.Amount.Text = "x" .. multiplier
end
end
function Plot:_ensurePurchaseGuiElements(plotModel)
local purchasesFolder = plotModel:FindFirstChild("Purchases")
if not purchasesFolder then return end
local templateBase
local tier = plotModel:GetAttribute("Tier")
local BasesData = require(ReplicatedStorage.Datas.Bases)
local tierData = BasesData[tier] or BasesData[0]
if tierData and tierData.Model then
templateBase = tierData.Model
end
for _, purchase in ipairs(purchasesFolder:GetChildren()) do
local main = purchase:FindFirstChild("Main")
if not main then continue end
local bGui = main:FindFirstChild("BillboardGui")
if not (bGui and bGui:IsA("BillboardGui")) then
if templateBase then
local templatePurchase = templateBase:FindFirstChild("Purchases") and templateBase.Purchases:FindFirstChild(purchase.Name)
local templateGui = templatePurchase and templatePurchase.Main:FindFirstChild("BillboardGui")
if templateGui then
bGui = templateGui:Clone()
bGui.Parent = main
end
end
if not bGui then
bGui = Instance.new("BillboardGui")
bGui.Name = "BillboardGui"
bGui.Size = UDim2.new(0, 100, 0, 50)
bGui.AlwaysOnTop = true
bGui.Parent = main
end
end
local function ensureLabel(childName)
if bGui:FindFirstChild(childName) then return end
local src
if templateBase then
local templatePurchase = templateBase:FindFirstChild("Purchases") and templateBase.Purchases:FindFirstChild(purchase.Name)
local templateGui = templatePurchase and templatePurchase.Main:FindFirstChild("BillboardGui")
if templateGui then
src = templateGui:FindFirstChild(childName)
end
end
if src then
src:Clone().Parent = bGui
else
local lbl = Instance.new("TextLabel")
lbl.Name = childName
lbl.Size = UDim2.new(1, 0, 1, 0)
lbl.BackgroundTransparency = 1
lbl.Text = ""
lbl.Visible = false
lbl.Parent = bGui
end
end
ensureLabel("RemainingTime")
ensureLabel("Locked")
ensureLabel("Delay")
ensureLabel("LockStudio")
end
end
return Plot - Edit
03:12:20.448
- Edit
03:12:20.448
============================== - Edit
03:12:20.448 📜 ServerScriptService.Services.Plots.Plot.PlotRainbow - Edit
03:12:20.448 ==============================
- Edit
03:12:20.448 local PlotRainbow = {}
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local CollectionService = game:GetService("CollectionService")
local DataManagement = require(ServerScriptService.Services.DataManagment)
local Animals = require(ReplicatedStorage.Datas.Animals)
function PlotRainbow.apply(plot)
if not plot or not plot.plotModel then return end
if not DataManagement.isDataReady(plot.owner) then
DataManagement.waitForData(plot.owner, 15)
end
local data = DataManagement.GetDataMan(plot.owner)
if not data or not data.Index then return end
local function hasFullSet(mutation)
for id, animalData in pairs(Animals) do
if not animalData.HideFromIndex then
if not (data.Index[id] and data.Index[id][mutation]) then
return false
end
end
end
return true
end
for animalId, _ in pairs(Animals) do
local key = animalId
if data.Index[key] == nil then
key = tostring(animalId)
end
if not (data.Index[key] and data.Index[key]["Rainbow"]) then
return
end
end
local ignoreModels = {}
local decorationsFolder = plot.plotModel:FindFirstChild("Decorations")
if decorationsFolder then
for _, part in ipairs(decorationsFolder:GetDescendants()) do
if part:IsA("BasePart") and part.Color == Color3.fromRGB(112, 68, 43) then
ignoreModels[part.Parent] = true
end
end
for _, child in ipairs(decorationsFolder:GetChildren()) do
if child:IsA("Model") and child:FindFirstChildWhichIsA("PointLight", true) then
ignoreModels[child] = true
end
end
end
for _, directChild in ipairs(plot.plotModel:GetChildren()) do
if directChild:IsA("Model") then
ignoreModels[directChild] = true
end
end
local IGNORE_FOLDERS = {
AnimalPodiums = true,
Laser = true,
LaserHitbox = true,
Purchases = true,
Unlock = true,
}
local IGNORE_PARTS = {
AnimalTarget = true,
DeliveryHitbox = true,
Multiplier = true,
PlotSign = true,
Spawn = true,
StealHitbox = true,
Root = true,
}
local function hasIgnoredAncestor(inst)
local current = inst.Parent
while current and current ~= plot.plotModel do
if IGNORE_FOLDERS[current.Name] or ignoreModels[current] or current.Name == "FriendPanel" then
return true
end
current = current.Parent
end
return false
end
for _, descendant in ipairs(plot.plotModel:GetDescendants()) do
if descendant:IsA("BasePart") then
if hasIgnoredAncestor(descendant) then continue end
if IGNORE_PARTS[descendant.Name] then continue end
local s = descendant.Size
local dims = {math.round(s.X), math.round(s.Y), math.round(s.Z)}
table.sort(dims)
if dims[1] == 2 and dims[2] == 53 and dims[3] == 53 then
continue
end
if descendant.Color == Color3.fromRGB(99, 95, 98) then
if descendant.Name == "Part" then
continue
end
end
CollectionService:AddTag(descendant, "RainbowModel")
end
end
end
return PlotRainbow - Edit
03:12:20.448
- Edit
03:12:20.448
============================== - Edit
03:12:20.448 📜 ServerScriptService.Services.Plots.Plot.PlotDiamond - Edit
03:12:20.448 ==============================
- Edit
03:12:20.448 local PlotDiamond = {}
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local DataManagement = require(ServerScriptService.Services.DataManagment)
local Color27 = Color3.fromRGB(27, 42, 53)
local Color91 = Color3.fromRGB(91, 93, 105)
local Color69 = Color3.fromRGB(69, 71, 80)
local Target116 = Color3.fromRGB(116, 212, 254)
local Target37 = Color3.fromRGB(37, 196, 254)
local Target28 = Color3.fromRGB(28, 137, 254)
local Color99 = Color3.fromRGB(99, 95, 98)
local GoldBright = Color3.fromRGB(237, 178, 0)
local GoldDark = Color3.fromRGB(215, 111, 1)
local function buildIgnoreChecker(plot)
local ignoreModels = {}
local decorationsFolder = plot.plotModel:FindFirstChild("Decorations")
if decorationsFolder then
for _, part in ipairs(decorationsFolder:GetDescendants()) do
if part:IsA("BasePart") and part.Color == Color3.fromRGB(112, 68, 43) then
ignoreModels[part.Parent] = true
end
end
for _, child in ipairs(decorationsFolder:GetChildren()) do
if child:IsA("Model") and child:FindFirstChildWhichIsA("PointLight", true) then
ignoreModels[child] = true
end
end
end
for _, directChild in ipairs(plot.plotModel:GetChildren()) do
if directChild:IsA("Model") then
ignoreModels[directChild] = true
end
end
local IGNORE_FOLDERS = {
AnimalPodiums = true,
Laser = true,
LaserHitbox = true,
Purchases = true,
Unlock = true,
}
local IGNORE_PARTS = {
AnimalTarget = true,
DeliveryHitbox = true,
Multiplier = true,
PlotSign = true,
Spawn = true,
StealHitbox = true,
Root = true,
}
local function hasIgnoredAncestor(inst)
local current = inst.Parent
while current and current ~= plot.plotModel do
if IGNORE_FOLDERS[current.Name] or ignoreModels[current] or current.Name == "FriendPanel" then
return true
end
current = current.Parent
end
return false
end
return IGNORE_PARTS, hasIgnoredAncestor
end
function PlotDiamond.apply(plot)
if not plot or not plot.plotModel then return end
if not DataManagement.isDataReady(plot.owner) then
DataManagement.waitForData(plot.owner, 15)
end
local data = DataManagement.GetDataMan(plot.owner)
if not data or not data.Index then return end
local Animals = require(ReplicatedStorage.Datas.Animals)
local function hasFullSet(mutation)
for id, animalData in pairs(Animals) do
if not animalData.HideFromIndex then
if not (data.Index[id] and data.Index[id][mutation]) then
return false
end
end
end
return true
end
if hasFullSet("Rainbow") then return end
if not hasFullSet("Diamond") then return end
local IGNORE_PARTS, hasIgnoredAncestor = buildIgnoreChecker(plot)
for _, descendant in ipairs(plot.plotModel:GetDescendants()) do
if descendant:IsA("BasePart") then
if hasIgnoredAncestor(descendant) then continue end
if IGNORE_PARTS[descendant.Name] then continue end
local s = descendant.Size
local dims = {math.round(s.X), math.round(s.Y), math.round(s.Z)}
table.sort(dims)
if dims[1] == 2 and dims[2] == 53 and dims[3] == 53 then
continue
end
local col = descendant.Color
if col == Color27 or col == GoldBright then
descendant.Color = Target116
elseif col == Color91 or col == GoldDark then
descendant.Color = Target37
elseif col == Color69 then
descendant.Color = Target28
elseif col == Color99 and descendant.Name == "structure base home" then
descendant.Color = Target28
end
end
end
end
return PlotDiamond - Edit
03:12:20.448
- Edit
03:12:20.448
============================== - Edit
03:12:20.449 📜 ServerScriptService.Services.Plots.Plot.PlotGold - Edit
03:12:20.449 ==============================
- Edit
03:12:20.449 local PlotGold = {}
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local DataManagement = require(ServerScriptService.Services.DataManagment)
local Color27 = Color3.fromRGB(27, 42, 53)
local Color91 = Color3.fromRGB(91, 93, 105)
local Color69 = Color3.fromRGB(69, 71, 80)
local Color99 = Color3.fromRGB(99, 95, 98)
local TargetBright = Color3.fromRGB(237, 178, 0)
local TargetDark = Color3.fromRGB(215, 111, 1)
local function buildIgnoreChecker(plot)
local ignoreModels = {}
local decorationsFolder = plot.plotModel:FindFirstChild("Decorations")
if decorationsFolder then
for _, part in ipairs(decorationsFolder:GetDescendants()) do
if part:IsA("BasePart") and part.Color == Color3.fromRGB(112, 68, 43) then
ignoreModels[part.Parent] = true
end
end
for _, child in ipairs(decorationsFolder:GetChildren()) do
if child:IsA("Model") and child:FindFirstChildWhichIsA("PointLight", true) then
ignoreModels[child] = true
end
end
end
for _, directChild in ipairs(plot.plotModel:GetChildren()) do
if directChild:IsA("Model") then
ignoreModels[directChild] = true
end
end
local IGNORE_FOLDERS = {
AnimalPodiums = true,
Laser = true,
LaserHitbox = true,
Purchases = true,
Unlock = true,
}
local IGNORE_PARTS = {
AnimalTarget = true,
DeliveryHitbox = true,
Multiplier = true,
PlotSign = true,
Spawn = true,
StealHitbox = true,
Root = true,
}
local function hasIgnoredAncestor(inst)
local current = inst.Parent
while current and current ~= plot.plotModel do
if IGNORE_FOLDERS[current.Name] or ignoreModels[current] or current.Name == "FriendPanel" then
return true
end
current = current.Parent
end
return false
end
return IGNORE_PARTS, hasIgnoredAncestor
end
function PlotGold.apply(plot)
if not plot or not plot.plotModel then return end
if not DataManagement.isDataReady(plot.owner) then
DataManagement.waitForData(plot.owner, 15)
end
local data = DataManagement.GetDataMan(plot.owner)
if not data or not data.Index then return end
local Animals = require(ReplicatedStorage.Datas.Animals)
local function hasFullSet(mutation)
for id, animalData in pairs(Animals) do
if not animalData.HideFromIndex then
if not (data.Index[id] and data.Index[id][mutation]) then
return false
end
end
end
return true
end
if hasFullSet("Rainbow") or hasFullSet("Diamond") then return end
if not hasFullSet("Gold") then return end
local IGNORE_PARTS, hasIgnoredAncestor = buildIgnoreChecker(plot)
for _, descendant in ipairs(plot.plotModel:GetDescendants()) do
if descendant:IsA("BasePart") then
if hasIgnoredAncestor(descendant) then continue end
if IGNORE_PARTS[descendant.Name] then continue end
local s = descendant.Size
local dims = {math.round(s.X), math.round(s.Y), math.round(s.Z)}
table.sort(dims)
if dims[1] == 2 and dims[2] == 53 and dims[3] == 53 then
continue
end
local col = descendant.Color
if col == Color27 then
descendant.Color = TargetBright
elseif col == Color91 or col == Color69 then
descendant.Color = TargetDark
elseif col == Color99 and descendant.Name == "structure base home" then
descendant.Color = TargetDark
end
end
end
end
return PlotGold - Edit
03:12:20.449
- Edit
03:12:20.449
============================== - Edit
03:12:20.449 📜 ServerScriptService.Services.Plots.Plot.PlotCandy - Edit
03:12:20.449 ==============================
- Edit
03:12:20.449 local PlotCandy = {}
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local CollectionService = game:GetService("CollectionService")
local DataManagement = require(ServerScriptService.Services.DataManagment)
local Color27 = Color3.fromRGB(27, 42, 53)
local Color91 = Color3.fromRGB(91, 93, 105)
local Color69 = Color3.fromRGB(69, 71, 80)
local Color99 = Color3.fromRGB(99, 95, 98)
local CandyColor1 = Color3.fromRGB(255, 182, 255)
local CandyColor2 = Color3.fromRGB(255, 105, 180)
local CandyColor3 = Color3.fromRGB(255, 0, 251)
local GoldBright = Color3.fromRGB(237, 178, 0)
local GoldDark = Color3.fromRGB(215, 111, 1)
local DiamondBright = Color3.fromRGB(116, 212, 254)
local DiamondMid = Color3.fromRGB(37, 196, 254)
local DiamondDark = Color3.fromRGB(28, 137, 254)
local function buildIgnoreChecker(plot)
local ignoreModels = {}
local decorationsFolder = plot.plotModel:FindFirstChild("Decorations")
if decorationsFolder then
for _, part in ipairs(decorationsFolder:GetDescendants()) do
if part:IsA("BasePart") and part.Color == Color3.fromRGB(112, 68, 43) then
ignoreModels[part.Parent] = true
end
end
for _, child in ipairs(decorationsFolder:GetChildren()) do
if child:IsA("Model") and child:FindFirstChildWhichIsA("PointLight", true) then
ignoreModels[child] = true
end
end
end
for _, directChild in ipairs(plot.plotModel:GetChildren()) do
if directChild:IsA("Model") then
ignoreModels[directChild] = true
end
end
local IGNORE_FOLDERS = {
AnimalPodiums = true,
Laser = true,
LaserHitbox = true,
Purchases = true,
Unlock = true,
}
local IGNORE_PARTS = {
AnimalTarget = true,
DeliveryHitbox = true,
Multiplier = true,
PlotSign = true,
Spawn = true,
StealHitbox = true,
Root = true,
}
local function hasIgnoredAncestor(inst)
local current = inst.Parent
while current and current ~= plot.plotModel do
if IGNORE_FOLDERS[current.Name] or ignoreModels[current] or current.Name == "FriendPanel" then
return true
end
current = current.Parent
end
return false
end
return IGNORE_PARTS, hasIgnoredAncestor
end
function PlotCandy.apply(plot)
if not plot or not plot.plotModel then
print("[DEBUG] PlotCandy: No plot or plotModel")
return
end
if not DataManagement.isDataReady(plot.owner) then
DataManagement.waitForData(plot.owner, 15)
end
local data = DataManagement.GetDataMan(plot.owner)
if not data or not data.Index then
print("[DEBUG] PlotCandy: No data or data.Index")
return
end
local Animals = require(ReplicatedStorage.Datas.Animals)
local function hasFullSet(mutation)
for id, animalData in pairs(Animals) do
if not animalData.HideFromIndex then
if not (data.Index[id] and data.Index[id][mutation]) then
return false
end
end
end
return true
end
local hasDiamond = hasFullSet("Diamond")
local hasCandy = hasFullSet("Candy")
local hasRainbow = hasFullSet("Rainbow")
if not hasCandy then
-- return
end
if hasRainbow then
local rainbowTagsRemoved = 0
for _, descendant in ipairs(plot.plotModel:GetDescendants()) do
if descendant:IsA("BasePart") and CollectionService:HasTag(descendant, "RainbowModel") then
CollectionService:RemoveTag(descendant, "RainbowModel")
rainbowTagsRemoved = rainbowTagsRemoved + 1
end
end
end
local IGNORE_PARTS, hasIgnoredAncestor = buildIgnoreChecker(plot)
for _, descendant in ipairs(plot.plotModel:GetDescendants()) do
if descendant:IsA("BasePart") then
if hasIgnoredAncestor(descendant) then continue end
if IGNORE_PARTS[descendant.Name] then continue end
local s = descendant.Size
local dims = {math.round(s.X), math.round(s.Y), math.round(s.Z)}
table.sort(dims)
if dims[1] == 2 and dims[2] == 53 and dims[3] == 53 then
continue
end
local col = descendant.Color
if col == Color27 or col == GoldBright or col == DiamondBright then
descendant.Color = CandyColor1
elseif col == Color91 or col == GoldDark or col == DiamondMid then
descendant.Color = CandyColor2
elseif col == Color69 or col == DiamondDark then
descendant.Color = CandyColor3
elseif col == Color99 and descendant.Name == "structure base home" then
descendant.Color = CandyColor3
end
end
end
end
return PlotCandy - Edit
03:12:20.449
- Edit
03:12:20.449
============================== - Edit
03:12:20.449 📜 ServerScriptService.Services.Plots.LuckyBlockTimerManager - Edit
03:12:20.449 ==============================
- Edit
03:12:20.450 local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local DataManagement = require(ServerScriptService.Services.DataManagment)
local Animals = require(ReplicatedStorage.Datas.Animals)
local LuckyBlocks = require(ReplicatedStorage.Datas.LuckyBlocks)
local Net = require(ReplicatedStorage.Packages.Net)
local Synchronizer = require(ReplicatedStorage.Packages.Synchronizer)
local LuckyBlockTimerManager = {}
LuckyBlockTimerManager.__index = LuckyBlockTimerManager
function LuckyBlockTimerManager.new(plotManager)
local self = setmetatable({}, LuckyBlockTimerManager)
self.plotManager = plotManager
self.lastUpdateTime = workspace:GetServerTimeNow()
self.updateConnection = nil
self.openRemote = Net:RemoteEvent("PlotService/Open")
self.openRemote.OnServerEvent:Connect(function(player, slot)
self:HandleLuckyBlockOpen(player, slot)
end)
return self
end
function LuckyBlockTimerManager:Start()
if self.updateConnection then
return
end
self.updateConnection = RunService.Heartbeat:Connect(function()
local currentTime = workspace:GetServerTimeNow()
local deltaTime = currentTime - self.lastUpdateTime
if deltaTime >= 1 then
self:UpdateAllLuckyBlockTimers(deltaTime)
self.lastUpdateTime = currentTime
end
end)
end
function LuckyBlockTimerManager:Stop()
if self.updateConnection then
self.updateConnection:Disconnect()
self.updateConnection = nil
end
end
function LuckyBlockTimerManager:UpdateAllLuckyBlockTimers(deltaTime)
local playerPlots = self.plotManager.playerPlots
for player, plot in pairs(playerPlots) do
if player and player.Parent then
self:UpdatePlayerLuckyBlockTimers(player, deltaTime)
end
end
end
function LuckyBlockTimerManager:UpdatePlayerLuckyBlockTimers(player, deltaTime)
if not DataManagement.isDataReady(player) then
return
end
local animalList = DataManagement.getAnimalList(player)
if not animalList then
return
end
local hasUpdates = false
local hasTimerReachedZero = false
for slot, animalData in pairs(animalList) do
if typeof(animalData) == "table" and animalData.Timer then
local animalInfo = Animals[animalData.Index]
if animalInfo and animalInfo.LuckyBlock then
local oldTimer = animalData.Timer
animalData.Timer = math.max(0, animalData.Timer - deltaTime)
hasUpdates = true
if oldTimer > 0 and animalData.Timer <= 0 then
hasTimerReachedZero = true
self:HandleLuckyBlockReady(player, slot, animalData)
end
end
end
end
if hasUpdates then
self:SyncAnimalListChanges(player, animalList)
if hasTimerReachedZero then
task.wait(0.1)
self:SyncAnimalListChanges(player, animalList)
end
end
end
function LuckyBlockTimerManager:HandleLuckyBlockReady(player, slot, animalData)
end
function LuckyBlockTimerManager:HandleLuckyBlockOpen(player, slot)
if not DataManagement.isDataReady(player) then
return
end
local animalList = DataManagement.getAnimalList(player)
if not animalList or not animalList[slot] then
return
end
local animalData = animalList[slot]
if typeof(animalData) ~= "table" or not animalData.Index then
return
end
local animalInfo = Animals[animalData.Index]
if not animalInfo or not animalInfo.LuckyBlock then
return
end
if animalData.Timer and animalData.Timer > 0 then
return
end
local animalKeyName = nil
for keyName, animal in pairs(Animals) do
if animal == animalInfo then
animalKeyName = keyName
break
end
end
if not animalKeyName then
return
end
local luckyBlockData = LuckyBlocks[animalKeyName]
if not luckyBlockData or not luckyBlockData.Animals then
return
end
local selectedAnimal = self:SelectRandomAnimalFromLuckyBlock(luckyBlockData.Animals)
if not selectedAnimal then
return
end
local selectedAnimalIndex = nil
for index, animal in pairs(Animals) do
if animal.DisplayName == selectedAnimal then
selectedAnimalIndex = index
break
end
end
if not selectedAnimalIndex then
return
end
local plot = self.plotManager:GetPlayerPlot(player)
if not plot then
return
end
local plotUID = plot:GetUUID()
local luckyBlockMutation = animalData.Mutation
local luckyBlockTraits = animalData.Traits or {}
self.openRemote:FireAllClients(plotUID, slot, animalData.Index, selectedAnimal, luckyBlockMutation, luckyBlockTraits)
task.wait(0.2)
local success, newSlot = pcall(function()
DataManagement.removeAnimal(player, slot)
return DataManagement.addAnimal(player, selectedAnimalIndex, luckyBlockMutation, luckyBlockTraits)
end)
end
function LuckyBlockTimerManager:SelectRandomAnimalFromLuckyBlock(animals)
local totalWeight = 0
local weightedAnimals = {}
-- Check if animals is an array (no weights) or a dictionary (with weights)
local isArray = true
for key, value in pairs(animals) do
if typeof(key) == "string" and typeof(value) == "number" then
isArray = false
break
end
end
if isArray then
-- Handle array format (equal chances)
local animalCount = 0
for _ in pairs(animals) do
animalCount = animalCount + 1
end
if animalCount == 0 then
return nil
end
local equalWeight = 100 / animalCount
for _, animalName in pairs(animals) do
totalWeight = totalWeight + equalWeight
table.insert(weightedAnimals, {name = animalName, weight = equalWeight})
end
else
-- Handle dictionary format (specified weights)
for animalName, weight in pairs(animals) do
totalWeight = totalWeight + weight
table.insert(weightedAnimals, {name = animalName, weight = weight})
end
end
if totalWeight <= 0 then
return nil
end
local randomValue = math.random() * totalWeight
local currentWeight = 0
for _, animalData in ipairs(weightedAnimals) do
currentWeight = currentWeight + animalData.weight
if randomValue <= currentWeight then
return animalData.name
end
end
return weightedAnimals[1] and weightedAnimals[1].name
end
function LuckyBlockTimerManager:SyncAnimalListChanges(player, animalList)
if not DataManagement.isDataReady(player) then
return
end
local success = pcall(function()
local profile = DataManagement.GetDataMan(player)
if profile then
profile.AnimalList = animalList
end
local plot = self.plotManager:GetPlayerPlot(player)
if plot then
plot:SetAnimalList(animalList)
local synchronizer = plot:GetSynchronizer()
if synchronizer then
synchronizer:Set("AnimalList", animalList)
end
end
end)
end
function LuckyBlockTimerManager:GetLuckyBlockTimer(player, slot)
if not DataManagement.waitForData(player, 5) then
return nil
end
local animalList = DataManagement.getAnimalList(player)
if not animalList or not animalList[slot] then
return nil
end
local animalData = animalList[slot]
if typeof(animalData) == "table" and animalData.Timer then
local animalInfo = Animals[animalData.Index]
if animalInfo and animalInfo.LuckyBlock then
return animalData.Timer
end
end
return nil
end
function LuckyBlockTimerManager:IsLuckyBlockReady(player, slot)
local timer = self:GetLuckyBlockTimer(player, slot)
return timer ~= nil and timer <= 0
end
return LuckyBlockTimerManager - Edit
03:12:20.450
- Edit
03:12:20.450
============================== - Edit
03:12:20.450 📜 ServerScriptService.Services.Plots.AnimalGrab - Edit
03:12:20.450 ==============================
- Edit
03:12:20.450 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local CollectionService = game:GetService("CollectionService")
local HttpService = game:GetService("HttpService")
local Packages = ReplicatedStorage.Packages
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local DataManagment = require(ServerScriptService.Services.DataManagment)
local Animals = require(ReplicatedStorage.Shared.Animals)
local PlotConstants = require(script.Parent.PlotConstants)
local AnimalStealing = {}
AnimalStealing.__index = AnimalStealing
function AnimalStealing.new(plotManager)
local self = setmetatable({}, AnimalStealing)
self.plotManager = plotManager
self.playerStolenModels = {}
self.playerCarryAnimTracks = {}
self.deliveryDebounce = {}
self.stealNotificationDebounce = {}
self.alreadyStealingDebounce = {}
self.capacityFullDebounce = {}
self:_setupRemoteEvents()
self:_setupPlayerConnections()
return self
end
function AnimalStealing:_setupRemoteEvents()
local StealAnimal = Net:RemoteEvent(PlotConstants.REMOTES.STEAL_ANIMAL)
local DeliveryHandler = Net:RemoteEvent(PlotConstants.REMOTES.DELIVERY_HANDLER)
local GrabAnimal = Net:RemoteEvent("StealService/Grab")
StealAnimal.OnServerEvent:Connect(function(player, timestamp, actionId, targetPlotName, animalSlot)
self:handleStealAttempt(player, timestamp, actionId, targetPlotName, animalSlot)
end)
GrabAnimal.OnServerEvent:Connect(function(player, timestamp, actionId, targetPlotName, animalSlot)
self:handleGrab(player, timestamp, actionId, targetPlotName, animalSlot)
end)
DeliveryHandler.OnServerEvent:Connect(function(player, actionId)
--self:handleDelivery(player, actionId)
end)
end
function AnimalStealing:_setupPlayerConnections()
Players.PlayerAdded:Connect(function(player)
self:_connectPlayerEvents(player)
end)
Players.PlayerRemoving:Connect(function(player)
self:_handlePlayerRemoving(player)
end)
for _, player in pairs(Players:GetPlayers()) do
self:_connectPlayerEvents(player)
end
end
function AnimalStealing:_connectPlayerEvents(player)
player:GetAttributeChangedSignal("Stealing"):Connect(function()
local isCurrentlyStealing = player:GetAttribute("Stealing")
if not isCurrentlyStealing then
self:_cleanupStealState(player)
end
end)
player.CharacterAdded:Connect(function()
if player:GetAttribute("Stealing") then
self:_cleanupStealState(player)
end
end)
end
function AnimalStealing:_handleLeavingPlayerStolenAnimals(player)
local playerPlot = self.plotManager:GetPlayerPlot(player)
if not playerPlot then
return
end
local plotSync = playerPlot:GetSynchronizer()
if not plotSync then
return
end
local animalList = plotSync:Get("AnimalList") or {}
for slot, animal in pairs(animalList) do
if typeof(animal) == "table" and animal.Steal == true then
print("[AnimalStealing] Removing stolen animal", animal.Index, "from leaving player", player.Name, "slot", slot)
animalList[slot] = "Empty"
DataManagment.removeAnimal(player, slot)
end
end
plotSync:Set("AnimalList", animalList)
plotSync:Set("AnimalPodiums", animalList)
end
function AnimalStealing:_handlePlayerRemoving(player)
self:_handleLeavingPlayerStolenAnimals(player)
self:_cleanupStealState(player)
self.playerStolenModels[player] = nil
self.playerCarryAnimTracks[player] = nil
self.deliveryDebounce[player] = nil
local playerUserId = player.UserId
for key, _ in pairs(self.stealNotificationDebounce) do
if string.find(key, "^" .. playerUserId .. "_") then
self.stealNotificationDebounce[key] = nil
end
end
end
function AnimalStealing:_validateAndRepairAnimalList(plotInstance, plotUUID)
local animalManager = self.plotManager:GetAnimalManager(plotInstance)
if not animalManager then
warn("[AnimalStealing] No animal manager found for plot: " .. plotUUID)
return {}
end
local animalList = plotInstance:GetAnimalList()
return animalManager:ValidateAndRepairAnimalList(animalList)
end
function AnimalStealing:_cleanupStealState(player)
local stealingPlot = player:GetAttribute("StealingPlot")
local stealingSlot = player:GetAttribute("StealingSlot")
if stealingPlot and stealingSlot then
local targetPlot = self.plotManager:GetPlotByUUID(stealingPlot)
if targetPlot then
local animalManager = self.plotManager:GetAnimalManager(targetPlot)
if animalManager and animalManager:HasValidAnimal(stealingSlot) then
animalManager:SetStealState(stealingSlot, false)
end
end
end
player:SetAttribute("StealingPlot", nil)
player:SetAttribute("StealingSlot", nil)
self:_cleanupStolenAnimal(player)
local carryAnimTrack = self.playerCarryAnimTracks[player]
if carryAnimTrack and carryAnimTrack.IsPlaying then
carryAnimTrack:Stop()
carryAnimTrack:Destroy()
end
self.playerCarryAnimTracks[player] = nil
end
-- Add this function to your AnimalStealing module
function AnimalStealing:_createBoundingBox(model)
-- Calculate the bounding box of the model
local minX, minY, minZ = math.huge, math.huge, math.huge
local maxX, maxY, maxZ = -math.huge, -math.huge, -math.huge
for _, part in pairs(model:GetDescendants()) do
if part:IsA("BasePart") then
local cf = part.CFrame
local size = part.Size
local corners = {
cf * CFrame.new(-size.X/2, -size.Y/2, -size.Z/2),
cf * CFrame.new(size.X/2, -size.Y/2, -size.Z/2),
cf * CFrame.new(-size.X/2, size.Y/2, -size.Z/2),
cf * CFrame.new(size.X/2, size.Y/2, -size.Z/2),
cf * CFrame.new(-size.X/2, -size.Y/2, size.Z/2),
cf * CFrame.new(size.X/2, -size.Y/2, size.Z/2),
cf * CFrame.new(-size.X/2, size.Y/2, size.Z/2),
cf * CFrame.new(size.X/2, size.Y/2, size.Z/2)
}
for _, corner in pairs(corners) do
local pos = corner.Position
minX, minY, minZ = math.min(minX, pos.X), math.min(minY, pos.Y), math.min(minZ, pos.Z)
maxX, maxY, maxZ = math.max(maxX, pos.X), math.max(maxY, pos.Y), math.max(maxZ, pos.Z)
end
end
end
-- Create the bounding box
local boundingBox = Instance.new("Part")
boundingBox.Name = "BoundingBox"
boundingBox.Material = Enum.Material.ForceField
boundingBox.BrickColor = BrickColor.new("Bright blue")
boundingBox.Transparency = 0.7
boundingBox.CanCollide = false
boundingBox.CanQuery = false
boundingBox.CanTouch = false
boundingBox.Anchored = false
boundingBox.Massless = true
-- Set size and position
local sizeX, sizeY, sizeZ = maxX - minX, maxY - minY, maxZ - minZ
local centerX, centerY, centerZ = (maxX + minX) / 2, (maxY + minY) / 2, (maxZ + minZ) / 2
boundingBox.Size = Vector3.new(sizeX, sizeY, sizeZ)
boundingBox.CFrame = CFrame.new(centerX, centerY, centerZ)
boundingBox.Parent = model
-- Create selection box for better visibility
local selectionBox = Instance.new("SelectionBox")
selectionBox.Adornee = boundingBox
selectionBox.Color3 = Color3.fromRGB(0, 162, 255)
selectionBox.LineThickness = 0.2
selectionBox.Transparency = 0.3
selectionBox.Parent = boundingBox
return boundingBox, Vector3.new(sizeX, sizeY, sizeZ), Vector3.new(centerX, centerY, centerZ)
end
-- Modified version of your _createStolenAnimalModel function
function AnimalStealing:_createStolenAnimalModel(player, animalData, isStolen)
local character = player.Character
if not character or not character:FindFirstChild("HumanoidRootPart") then
warn("[AnimalStealing] Player character or HumanoidRootPart not found for _createCarriedAnimalModel.")
return
end
local animalModelFolder = ReplicatedStorage:FindFirstChild("Models")
if not animalModelFolder then
warn("[AnimalStealing] 'Models' folder not found in ReplicatedStorage.")
return
end
local animalsFolder = animalModelFolder:FindFirstChild("Animals")
if not animalsFolder then
warn("[AnimalStealing] 'Animals' folder not found in ReplicatedStorage/Models.")
return
end
local animalTemplate = animalsFolder:FindFirstChild(animalData.Index)
if not animalTemplate then
warn("[AnimalStealing] Animal template not found for index:", animalData.Index)
return
end
local carriedAnimalModel = animalTemplate:Clone()
carriedAnimalModel.Name = "CarriedAnimal_" .. player.Name
carriedAnimalModel:SetAttribute("Index", animalData.Index)
if animalData.Mutation then
carriedAnimalModel:SetAttribute("Mutation", animalData.Mutation)
end
if animalData.Traits then
local traitsToSet = animalData.Traits
if typeof(animalData.Traits) == "table" then
traitsToSet = HttpService:JSONEncode(animalData.Traits)
end
carriedAnimalModel:SetAttribute("Traits", traitsToSet)
end
carriedAnimalModel.Parent = workspace
-- Apply mutations and traits (existing code)
if animalData.Mutation then
local sharedAnimals = require(ReplicatedStorage.Shared.Animals)
sharedAnimals:ApplyMutation(carriedAnimalModel, animalData.Index, animalData.Mutation)
end
if animalData.Traits then
local sharedAnimals = require(ReplicatedStorage.Shared.Animals)
local traitsArray = animalData.Traits
if typeof(animalData.Traits) == "string" then
local success, decoded = pcall(function()
return HttpService:JSONDecode(animalData.Traits)
end)
if success then
traitsArray = decoded
end
end
if traitsArray and type(traitsArray) == "table" then
sharedAnimals:ApplyTraits(carriedAnimalModel, animalData.Index, traitsArray)
end
end
-- Set up animations (existing code)
local animationsFolder = ReplicatedStorage:FindFirstChild("Animations")
if animationsFolder then
local animalsAnimFolder = animationsFolder:FindFirstChild("Animals")
if animalsAnimFolder then
local specificAnimFolder = animalsAnimFolder:FindFirstChild(animalData.Index)
if specificAnimFolder then
local idleAnim = specificAnimFolder:FindFirstChild("Idle")
if idleAnim then
local animController = carriedAnimalModel:FindFirstChildOfClass("AnimationController")
if not animController then
animController = Instance.new("AnimationController")
animController.Name = "AnimationController"
animController.Parent = carriedAnimalModel
end
local animator = animController:FindFirstChildOfClass("Animator")
if not animator then
animator = Instance.new("Animator")
animator.Parent = animController
end
local success, track = pcall(function()
return animator:LoadAnimation(idleAnim)
end)
if success and track then
track.Looped = true
track:Play()
end
end
end
end
end
-- Make parts non-collidable (existing code)
for _, part in carriedAnimalModel:GetDescendants() do
if part:IsA("BasePart") then
part.CanCollide = false
part.CanQuery = false
part.CanTouch = false
part.Massless = true
part.Anchored = false
end
end
-- Create bounding box and get dimensions
local boundingBox, boxSize, boxCenter = self:_createBoundingBox(carriedAnimalModel)
-- Create a handle part at the back bottom of the bounding box
local handlePart = Instance.new("Part")
handlePart.Name = "CarryHandle"
handlePart.Size = Vector3.new(0.5, 0.5, 0.5)
handlePart.Material = Enum.Material.Neon
handlePart.BrickColor = BrickColor.new("Bright green")
handlePart.Transparency = 0.5
handlePart.CanCollide = false
handlePart.CanQuery = false
handlePart.CanTouch = false
handlePart.Massless = true
handlePart.Anchored = false
handlePart.Shape = Enum.PartType.Ball
handlePart.Parent = carriedAnimalModel
-- Position the handle at the back bottom of the bounding box
-- Back = positive Z direction, Bottom = negative Y direction
local handleOffset = CFrame.new(0, -boxSize.Y/2 - 0.5, boxSize.Z/2 + 0.5)
-- Get the primary part or use bounding box center
local primaryPart = carriedAnimalModel.PrimaryPart or boundingBox
-- Position the animal model relative to player
local playerRootPart = character.HumanoidRootPart
local carryOffset = CFrame.new(0, 2.5, 0.5) -- More up (2.5) and even more forward (-0.5)
-- Position the primary part
primaryPart.CFrame = playerRootPart.CFrame * carryOffset
-- Position the handle relative to the bounding box center
handlePart.CFrame = boundingBox.CFrame * handleOffset
-- Create weld constraint between player and the handle (this is the key change)
local weldConstraint = Instance.new("WeldConstraint")
weldConstraint.Part0 = playerRootPart
weldConstraint.Part1 = handlePart
weldConstraint.Parent = handlePart
-- Create weld constraints to keep the animal model parts together
local modelWeld = Instance.new("WeldConstraint")
modelWeld.Part0 = handlePart
modelWeld.Part1 = primaryPart
modelWeld.Parent = primaryPart
-- Weld bounding box to the model
local boxWeld = Instance.new("WeldConstraint")
boxWeld.Part0 = primaryPart
boxWeld.Part1 = boundingBox
boxWeld.Parent = boundingBox
self:_addStolenOverhead(carriedAnimalModel, primaryPart, isStolen)
self.playerStolenModels[player] = carriedAnimalModel
if animalData.Index == "La Vacca Saturno Saturnita" and isStolen then
self:_tagVisualStolenModel(player, carriedAnimalModel)
end
return carriedAnimalModel
end
function AnimalStealing:_addStolenOverhead(stolenAnimalModel, attachmentPart)
local overheadsFolder = ReplicatedStorage:FindFirstChild("Overheads")
if not overheadsFolder then
return
end
local animalOverheadTemplate = overheadsFolder:FindFirstChild("AnimalOverhead")
if not animalOverheadTemplate then
return
end
local stolenOverhead = animalOverheadTemplate:Clone()
stolenOverhead.DisplayName.Text = "STOLEN"
stolenOverhead.DisplayName.TextColor3 = Color3.fromRGB(255, 0, 0)
stolenOverhead.DisplayName.TextStrokeTransparency = 0
stolenOverhead.DisplayName.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)
stolenOverhead.Generation.Visible = false
stolenOverhead.Price.Visible = false
stolenOverhead.Rarity.Visible = false
stolenOverhead.Mutation.Visible = false
local animalIndex = stolenAnimalModel:GetAttribute("Index")
local Animals = require(ReplicatedStorage.Datas.Animals)
local animalData = animalIndex and Animals[animalIndex]
local overheadYOffsetModifier = (animalData and animalData.OverheadYOffsetModifier) or 1
local overheadAttachment = Instance.new("Attachment")
overheadAttachment.Name = "StolenOverhead"
overheadAttachment.CFrame = CFrame.new(0, 3 * overheadYOffsetModifier, 0)
local primaryPart = stolenAnimalModel.PrimaryPart
if primaryPart then
overheadAttachment.Parent = primaryPart
else
overheadAttachment.Parent = attachmentPart
end
stolenOverhead.Parent = overheadAttachment
end
function AnimalStealing:_playCarryAnimation(player)
local character = player.Character
if not character then return end
local humanoid = character:FindFirstChildOfClass("Humanoid")
if not humanoid then return end
local animator = humanoid:FindFirstChildOfClass("Animator")
if not animator then
animator = Instance.new("Animator")
animator.Parent = humanoid
end
local carryAnim = ReplicatedStorage:FindFirstChild("Animations")
if not carryAnim then
return
end
local playerAnims = carryAnim:FindFirstChild("Player")
if not playerAnims then
return
end
local carryAnimation = playerAnims:FindFirstChild("Carry")
if not carryAnimation then
return
end
local animTrack = animator:LoadAnimation(carryAnimation)
animTrack.Looped = true
animTrack:Play()
self.playerCarryAnimTracks[player] = animTrack
end
function AnimalStealing:_sendNotification(player, message)
local NotificationEvent = Net:RemoteEvent("NotificationService/Notify")
if NotificationEvent and player then
NotificationEvent:FireClient(player, message, 3)
end
end
function AnimalStealing:_getColoredAnimalName(animalIndex)
local Animals = require(ReplicatedStorage.Datas.Animals)
local Rarities = require(ReplicatedStorage.Datas.Rarities)
local animalData = Animals[animalIndex]
if not animalData then
return animalIndex
end
local rarityData = Rarities[animalData.Rarity]
if not rarityData then
return animalData.DisplayName
end
local color = rarityData.Color
local r = math.floor(color.R * 255)
local g = math.floor(color.G * 255)
local b = math.floor(color.B * 255)
local hexColor = string.format("#%02X%02X%02X", r, g, b)
return string.format('%s', hexColor, animalData.DisplayName)
end
function AnimalStealing:handleStealAttempt(player, timestamp, actionId, targetPlotName, animalSlot)
if not DataManagment.isDataReady(player) then
print("[AnimalStealing] Data not ready for player:", player.Name)
return
end
if not timestamp or not actionId or not targetPlotName or not animalSlot then
print("[AnimalStealing] Missing parameters for player:", player.Name)
return
end
local timeDiff = math.abs(workspace:GetServerTimeNow() - (timestamp - PlotConstants.SECURITY.TIMESTAMP_OFFSET))
if timeDiff > PlotConstants.SECURITY.TIMESTAMP_TOLERANCE then
print("[AnimalStealing] Timestamp validation failed for player:", player.Name, "TimeDiff:", timeDiff)
--return
end
local targetPlot = self.plotManager:GetPlotByUUID(targetPlotName)
if not targetPlot then
print("[AnimalStealing] Target plot not found:", targetPlotName, "for player:", player.Name)
--return
end
local targetOwner = targetPlot:GetOwner()
if not targetOwner or targetOwner == player then
print("[AnimalStealing] Invalid target owner for player:", player.Name)
--return
end
local securityManager = self.plotManager:GetSecurityManager(targetPlot)
if securityManager then
local canSteal, reason = securityManager:CanPlayerSteal(player, targetPlot)
if not canSteal then
print("[AnimalStealing] Security check failed for player:", player.Name, "Reason:", reason)
--return
end
end
local notificationKey = targetOwner.UserId .. "_" .. animalSlot
local currentTime = tick()
if self.stealNotificationDebounce[notificationKey] then
local timeSinceLastNotification = currentTime - self.stealNotificationDebounce[notificationKey]
if timeSinceLastNotification < 3 then
print("[AnimalStealing] Notification debounce active for player:", player.Name, "Time remaining:", 3 - timeSinceLastNotification)
--return
end
end
local animalList = self:_validateAndRepairAnimalList(targetPlot, targetPlotName)
local animal = animalList[animalSlot]
if not animal or animal == PlotConstants.STATES.EMPTY or typeof(animal) ~= "table" then
print("[AnimalStealing] Invalid animal at slot", animalSlot, "for player:", player.Name, "Animal:", animal)
return
end
if player:GetAttribute("Stealing") then
local currentStealingPlot = player:GetAttribute("StealingPlot")
local currentStealingSlot = player:GetAttribute("StealingSlot")
if not currentStealingPlot or not currentStealingSlot then
self:_cleanupStealState(player)
else
if currentStealingPlot == targetPlotName and currentStealingSlot == animalSlot then
return
else
local now = tick()
if (self.alreadyStealingDebounce[player] or 0) < now - 0.5 then
local coloredAnimalName = self:_getColoredAnimalName(animal.Index)
self.alreadyStealingDebounce[player] = now
end
return
end
end
end
if animal.Steal == true then
local actuallyBeingStolen = false
local stealingPlayer = nil
for _, otherPlayer in pairs(Players:GetPlayers()) do
if otherPlayer:GetAttribute("Stealing") and
otherPlayer:GetAttribute("StealingPlot") == targetPlotName and
otherPlayer:GetAttribute("StealingSlot") == animalSlot then
actuallyBeingStolen = true
stealingPlayer = otherPlayer
break
end
end
if not actuallyBeingStolen then
self:_resetOrphanedStealState(targetPlot, targetOwner, animalList, animalSlot)
else
if stealingPlayer == player then
return
else
local coloredAnimalName = self:_getColoredAnimalName(animal.Index)
self:_sendNotification(player, coloredAnimalName .. " is already being stolen by " .. stealingPlayer.Name)
return
end
end
end
local playerAnimalList = DataManagment.getAnimalList(player)
local maxAnimals = DataManagment.GetMaxAnimals(player)
local currentAnimals = 0
for _, ownedAnimal in ipairs(playerAnimalList) do
if ownedAnimal ~= "Empty" and ownedAnimal ~= nil then
currentAnimals += 1
end
end
if currentAnimals >= maxAnimals then
local now = tick()
if (self.capacityFullDebounce[player] or 0) < now - 2 then
self:_sendNotification(player, "You need more room in your base to steal a brainrot!")
self.capacityFullDebounce[player] = now
end
return
end
self.stealNotificationDebounce[notificationKey] = currentTime
local coloredAnimalName = self:_getColoredAnimalName(animal.Index)
self:_sendNotification(targetOwner, "Someone is stealing your " .. coloredAnimalName)
local animalManager = self.plotManager:GetAnimalManager(targetPlot)
if animalManager then
animalManager:SetStealState(animalSlot, true)
end
player:SetAttribute("Stealing", true)
player:SetAttribute("StealingPlot", targetPlotName)
player:SetAttribute("StealingSlot", animalSlot)
self:_createStolenAnimalModel(player, animal)
self:_playCarryAnimation(player)
print("[AnimalStealing] Successfully started steal for player:", player.Name, "Animal:", animal.Index, "Slot:", animalSlot)
end
function AnimalStealing:_resetOrphanedStealState(targetPlot, targetOwner, animalList, animalSlot)
local animal = animalList[animalSlot]
if not animal or typeof(animal) ~= "table" or not animal.Index then
return
end
animal.Steal = false
if targetOwner then
local targetData = DataManagment.GetDataMan(targetOwner)
if targetData and targetData.AnimalList and targetData.AnimalList[animalSlot] then
local ownerAnimal = targetData.AnimalList[animalSlot]
if typeof(ownerAnimal) == "table" and ownerAnimal.Index then
ownerAnimal.Steal = false
end
end
end
local currentAnimalList = targetPlot:Get("AnimalList") or {}
if currentAnimalList[animalSlot] and typeof(currentAnimalList[animalSlot]) == "table" and currentAnimalList[animalSlot].Index then
targetPlot:Set(("AnimalList.%d.Steal"):format(animalSlot), false)
else
targetPlot:Set("AnimalList", animalList)
end
if targetOwner then
local targetPlayerSync = Synchronizer:Get(targetOwner)
if targetPlayerSync then
local playerAnimalList = targetPlayerSync:Get("AnimalList") or {}
if playerAnimalList[animalSlot] and typeof(playerAnimalList[animalSlot]) == "table" and playerAnimalList[animalSlot].Index then
targetPlayerSync:Set(("AnimalList.%d.Steal"):format(animalSlot), false)
else
local targetData = DataManagment.GetDataMan(targetOwner)
if targetData then
targetPlayerSync:Set("AnimalAddedOrRemoved", targetData.AnimalList)
targetPlayerSync:Set("AnimalPodiums", targetData.AnimalList)
end
end
local targetData = DataManagment.GetDataMan(targetOwner)
if targetData then
targetPlayerSync:Set("AnimalAddedOrRemoved", targetData.AnimalList)
targetPlayerSync:Set("AnimalPodiums", targetData.AnimalList)
end
end
end
end
function AnimalStealing:_setStealState(targetPlot, targetOwner, animalList, animalSlot, stealState)
local animal = animalList[animalSlot]
if not animal or typeof(animal) ~= "table" or not animal.Index then
return false
end
animal.Steal = stealState
if targetOwner then
local targetData = DataManagment.GetDataMan(targetOwner)
if targetData and targetData.AnimalList and targetData.AnimalList[animalSlot] then
local ownerAnimal = targetData.AnimalList[animalSlot]
if typeof(ownerAnimal) == "table" and ownerAnimal.Index then
ownerAnimal.Steal = stealState
end
end
end
local currentAnimalList = targetPlot:Get("AnimalList") or {}
if currentAnimalList[animalSlot] and typeof(currentAnimalList[animalSlot]) == "table" and currentAnimalList[animalSlot].Index then
targetPlot:Set(("AnimalList.%d.Steal"):format(animalSlot), stealState)
else
targetPlot:Set("AnimalList", animalList)
end
if targetOwner then
local targetPlayerSync = Synchronizer:Get(targetOwner)
if targetPlayerSync then
local playerAnimalList = targetPlayerSync:Get("AnimalList") or {}
if playerAnimalList[animalSlot] and typeof(playerAnimalList[animalSlot]) == "table" and playerAnimalList[animalSlot].Index then
targetPlayerSync:Set(("AnimalList.%d.Steal"):format(animalSlot), stealState)
else
local targetData = DataManagment.GetDataMan(targetOwner)
if targetData then
targetPlayerSync:Set("AnimalAddedOrRemoved", targetData.AnimalList)
targetPlayerSync:Set("AnimalPodiums", targetData.AnimalList)
end
end
local targetData = DataManagment.GetDataMan(targetOwner)
if targetData then
targetPlayerSync:Set("AnimalAddedOrRemoved", targetData.AnimalList)
targetPlayerSync:Set("AnimalPodiums", targetData.AnimalList)
end
end
end
return true
end
function AnimalStealing:handleDelivery(player, actionId)
local currentTime = tick()
if self.deliveryDebounce[player] then
local timeSinceLastCall = currentTime - self.deliveryDebounce[player]
if timeSinceLastCall < 2 then
return
end
end
self.deliveryDebounce[player] = currentTime
if not DataManagment.isDataReady(player) then
return
end
if not player:GetAttribute("Stealing") then
return
end
local stealingPlot = player:GetAttribute("StealingPlot")
local stealingSlot = player:GetAttribute("StealingSlot")
if not stealingPlot or not stealingSlot then
self:_cleanupStealState(player)
player:SetAttribute("Stealing", false)
return
end
local playerData = DataManagment.GetDataMan(player)
if not playerData then
return
end
local targetPlot = Synchronizer:Get(stealingPlot)
local ownerLeftGame = false
if not targetPlot then
local stolenAnimalModel = self.playerStolenModels[player]
if stolenAnimalModel and stolenAnimalModel.Parent and stolenAnimalModel:GetAttribute("Index") then
print("[AnimalStealing] Target plot not found, but stolen model exists - owner likely left game")
ownerLeftGame = true
else
self:_cleanupStealState(player)
player:SetAttribute("Stealing", false)
return
end
end
local animalList = {}
local animal = nil
local slotIndex = tonumber(stealingSlot)
if not slotIndex then
print("[AnimalStealing] Invalid stealingSlot for indexing:", stealingSlot, "Type:", typeof(stealingSlot))
self:_cleanupStealState(player)
player:SetAttribute("Stealing", false)
return
end
if not ownerLeftGame then
animalList = targetPlot:Get("AnimalList") or {}
animal = animalList[slotIndex]
else
print("[AnimalStealing] Owner left game, using stolen model for animal data")
end
local stolenAnimalModel = self.playerStolenModels[player]
local hasValidStolenModel = stolenAnimalModel and stolenAnimalModel.Parent and stolenAnimalModel:GetAttribute("Index")
print("[DEBUG] Animal from plot:", animal, "Type:", typeof(animal))
print("[DEBUG] Has valid stolen model:", hasValidStolenModel)
if hasValidStolenModel then
print("[DEBUG] Stolen model attributes - Index:", stolenAnimalModel:GetAttribute("Index"), "Mutation:", stolenAnimalModel:GetAttribute("Mutation"), "Traits:", stolenAnimalModel:GetAttribute("Traits"))
end
local capturedAnimal = nil
if animal and typeof(animal) == "table" and animal.Steal then
capturedAnimal = {
Index = animal.Index,
Mutation = animal.Mutation,
Traits = animal.Traits,
Steal = true
}
print("[DEBUG] Captured animal data from target plot:", capturedAnimal.Index, "Mutation:", capturedAnimal.Mutation)
elseif hasValidStolenModel then
capturedAnimal = {
Index = stolenAnimalModel:GetAttribute("Index"),
Mutation = stolenAnimalModel:GetAttribute("Mutation"),
Traits = stolenAnimalModel:GetAttribute("Traits"),
Steal = true
}
print("[DEBUG] Captured animal data from stolen model:", capturedAnimal.Index, "Mutation:", capturedAnimal.Mutation)
end
if not capturedAnimal then
print("[AnimalStealing] Cannot deliver - no valid stolen animal found")
self:_cleanupStealState(player)
player:SetAttribute("Stealing", false)
return
end
animal = capturedAnimal
local playerPlot = self.plotManager:GetPlayerPlot(player)
if not playerPlot then
self:_cleanupStealState(player)
player:SetAttribute("Stealing", false)
return
end
local playerPlotModel = playerPlot:GetPlotModel()
if not playerPlotModel then
self:_cleanupStealState(player)
player:SetAttribute("Stealing", false)
return
end
local stolenAnimal = {
Index = animal.Index,
LastCollect = workspace:GetServerTimeNow(),
Mutation = animal.Mutation,
Traits = animal.Traits,
Steal = false
}
print("[DEBUG] Captured stolen animal data:", stolenAnimal.Index, "Mutation:", stolenAnimal.Mutation, "Traits:", stolenAnimal.Traits)
local stolenAnimalModel = self.playerStolenModels[player]
local carryAnimTrack = self.playerCarryAnimTracks[player]
if carryAnimTrack and carryAnimTrack.IsPlaying then
carryAnimTrack:Stop()
carryAnimTrack:Destroy()
end
self.playerCarryAnimTracks[player] = nil
player:SetAttribute("Stealing", false)
player:SetAttribute("StealingPlot", nil)
player:SetAttribute("StealingSlot", nil)
if not ownerLeftGame and animalList[slotIndex] and typeof(animalList[slotIndex]) == "table" then
animalList[slotIndex] = "Empty"
targetPlot:Set("AnimalList", animalList)
targetPlot:Set("AnimalPodiums", animalList)
end
if not ownerLeftGame then
local targetOwner = targetPlot:Get("Owner")
if targetOwner then
local ownerUserId = typeof(targetOwner) == "Instance" and targetOwner.UserId or targetOwner
local ownerPlayer = Players:GetPlayerByUserId(ownerUserId)
if ownerPlayer then
DataManagment.removeAnimal(ownerPlayer, slotIndex)
local targetPlayerSync = Synchronizer:Get(ownerPlayer)
if targetPlayerSync then
local targetData = DataManagment.GetDataMan(ownerPlayer)
if targetData then
targetPlayerSync:Set("AnimalAddedOrRemoved", targetData.AnimalList)
targetPlayerSync:Set("AnimalPodiums", targetData.AnimalList)
end
end
else
print("[AnimalStealing] Owner left game, but animal data preserved for delivery:", stolenAnimal.Index, "Mutation:", stolenAnimal.Mutation)
end
end
else
print("[AnimalStealing] Owner already left game, skipping owner data cleanup for:", stolenAnimal.Index, "Mutation:", stolenAnimal.Mutation)
end
print("[DEBUG] About to process stolen animal delivery for:", player.Name, "Animal:", stolenAnimal.Index)
local deliverySuccess = self:_processStolenAnimalDelivery(player, stolenAnimal, playerPlot)
print("[DEBUG] Delivery result:", deliverySuccess)
if stolenAnimalModel and stolenAnimalModel.Parent then
if CollectionService:HasTag(stolenAnimalModel, "LaVaccaModel") then
if not stolenAnimalModel:GetAttribute("PreserveOnStealingEnd") then
CollectionService:RemoveTag(stolenAnimalModel, "LaVaccaModel")
stolenAnimalModel:Destroy()
else
print("[AnimalStealing] 🎭 Preserving La Vacca model:", stolenAnimalModel.Name)
end
else
stolenAnimalModel:Destroy()
end
end
self.playerStolenModels[player] = nil
end
function AnimalStealing:_findEmptySlot(player)
if not DataManagment.isDataReady(player) then
warn("[EmptySlotHandler] Data not ready for player:", player.Name)
return nil
end
local animalList = DataManagment.getAnimalList(player)
if not animalList then
warn("[EmptySlotHandler] No animal list found for player:", player.Name)
return nil
end
local maxAnimals = DataManagment.GetMaxAnimals(player)
for i = 1, maxAnimals do
if animalList[i] == "Empty" or animalList[i] == nil then
return i
end
end
return nil
end
function AnimalStealing:_processStolenAnimalDelivery(player, stolenAnimal, playerPlot)
local playerData = DataManagment.GetDataMan(player)
if not playerData then
print("[DEBUG] No player data for:", player.Name)
return false
end
local isDataReady = DataManagment.isDataReady(player)
print("[DEBUG] Data ready for", player.Name, ":", isDataReady)
if not isDataReady then
print("[DEBUG] Player data not ready, waiting...")
local success = DataManagment.waitForData(player, 10)
if not success then
print("[DEBUG] Failed to wait for data for:", player.Name)
self:_sendNotification(player, "Failed to deliver animal - data not ready!")
return false
end
end
print("[DEBUG] Delivering stolen animal:", stolenAnimal.Index, "Mutation:", stolenAnimal.Mutation, "Traits:", stolenAnimal.Traits, "for player:", player.Name)
local traitsString = nil
if stolenAnimal.Traits and typeof(stolenAnimal.Traits) == "table" then
local HttpService = game:GetService("HttpService")
local success, encoded = pcall(HttpService.JSONEncode, HttpService, stolenAnimal.Traits)
if success then
traitsString = encoded
else
print("[DEBUG] Failed to encode traits:", stolenAnimal.Traits)
end
elseif typeof(stolenAnimal.Traits) == "string" then
traitsString = stolenAnimal.Traits
end
print("[DEBUG] Calling DataManagment.addAnimal with:", stolenAnimal.Index, stolenAnimal.Mutation, traitsString)
local addedSlot = DataManagment.addAnimal(player, stolenAnimal.Index, stolenAnimal.Mutation, traitsString)
print("[DEBUG] DataManagment.addAnimal returned:", addedSlot)
if not addedSlot then
print("[DEBUG] Failed to add animal - base might be full")
self:_sendNotification(player, "Your base is full! Cannot steal more animals.")
return false
end
print("[DEBUG] Successfully added stolen animal to slot:", addedSlot)
local updatedAnimalList = DataManagment.getAnimalList(player)
task.wait(0.1)
local playerPlotSync = playerPlot:GetSynchronizer()
playerPlotSync:Set("AnimalList", updatedAnimalList)
playerPlotSync:Set("AnimalPodiums", updatedAnimalList)
local playerSync = Synchronizer:Get(player)
if playerSync then
playerSync:Set("AnimalAddedOrRemoved", updatedAnimalList)
playerSync:Set("AnimalPodiums", updatedAnimalList)
end
local coloredAnimalName = self:_getColoredAnimalName(stolenAnimal.Index)
self:_sendNotification(player, "You stole " .. coloredAnimalName)
DataManagment.addSteals(player, 1)
local updatedPlayerData = DataManagment.GetDataMan(player)
if updatedPlayerData and playerSync then
playerSync:Set("Steals", updatedPlayerData.Steals or 0)
end
return true
end
function AnimalStealing:_tagVisualStolenModel(player, stolenAnimalModel)
if not stolenAnimalModel or not stolenAnimalModel.Parent then
warn("[LaVacca Ritual] Visual stolen model not found for player:", player.Name)
return
end
local usedIndices = {}
for _, model in pairs(workspace:GetChildren()) do
if CollectionService:HasTag(model, "LaVaccaModel") then
local index = model:GetAttribute("LaVaccaIndex")
if index then
usedIndices[index] = true
end
end
end
local availableIndex = nil
for i = 1, 3 do
if not usedIndices[i] then
availableIndex = i
break
end
end
if not availableIndex then
availableIndex = math.random(1, 3)
for _, model in pairs(workspace:GetChildren()) do
if CollectionService:HasTag(model, "LaVaccaModel") and
model:GetAttribute("LaVaccaIndex") == availableIndex then
CollectionService:RemoveTag(model, "LaVaccaModel")
model:SetAttribute("LaVaccaIndex", nil)
break
end
end
end
stolenAnimalModel:SetAttribute("LaVaccaIndex", availableIndex)
stolenAnimalModel:SetAttribute("OwnerUserId", player.UserId)
stolenAnimalModel:SetAttribute("CreatedAt", workspace:GetServerTimeNow())
CollectionService:AddTag(stolenAnimalModel, "LaVaccaModel")
end
function AnimalStealing:handleGrab(player, actionId, plotUUID, animalSlot)
if actionId == "Grab" then
if not DataManagment.isDataReady(player) then
return false, "Player data not ready."
end
if not actionId or not plotUUID or not animalSlot then
return false, "Missing parameters for grab."
end
-- Ensure the player is not already carrying an animal (stolen or owned)
if self.playerStolenModels[player] then
self:_sendNotification(player, "You are already carrying an animal.")
return false, "Already carrying an animal."
end
local playerPlot = self.plotManager:GetPlayerPlot(player)
if not playerPlot or playerPlot:GetUUID() ~= plotUUID then
self:_sendNotification(player, "You can only grab animals from your own plot.")
return false, "Not your plot."
end
local playerPlotSync = playerPlot:GetSynchronizer()
if not playerPlotSync then
warn("[AnimalStealing] Player plot synchronizer not found for grab.")
return false, "Plot data not available."
end
local animalList = playerPlotSync:Get("AnimalList") or {}
local animal = animalList[animalSlot]
if not animal or animal == PlotConstants.STATES.EMPTY or typeof(animal) ~= "table" then
self:_sendNotification(player, "No animal found at this slot on your plot.")
return false, "Invalid animal slot."
end
if animal.Steal == true then
local stealingPlayer = nil
for _, otherPlayer in pairs(Players:GetPlayers()) do
if otherPlayer:GetAttribute("Stealing") and
otherPlayer:GetAttribute("StealingPlot") == plotUUID and
otherPlayer:GetAttribute("StealingSlot") == animalSlot then
stealingPlayer = otherPlayer
break
end
end
if stealingPlayer then
self:_sendNotification(player, "Your " .. self:_getColoredAnimalName(animal.Index) .. " is currently being stolen!")
return false, "Animal is being stolen."
else
-- If animal.Steal is true but no player is found stealing it, reset its state
warn("[AnimalStealing] Orphaned 'Steal' state detected for owned animal during grab. Resetting.")
local animalManager = self.plotManager:GetAnimalManager(playerPlot)
if animalManager then
animalManager:SetStealState(animalSlot, false)
animal.Steal = false -- Update local variable
end
end
end
-- Create the visual model for the owned animal
local createdModel = self:_createCarriedAnimalModel(player, animal, false) -- false because it's not stolen
if not createdModel then
return false, "Failed to create animal model."
end
self:_playCarryAnimation(player)
-- Update the plot data: remove the animal from the podium/slot as it's now carried
animalList[animalSlot] = PlotConstants.STATES.EMPTY -- Or a specific "Carried" state if you want
playerPlotSync:Set("AnimalList", animalList)
playerPlotSync:Set("AnimalPodiums", animalList) -- Update podiums
-- Set player attributes to indicate they are carrying their own animal
-- We can reuse "Stealing" attribute and repurpose it for "carrying any animal" or add a new one like "IsCarryingOwnedAnimal"
-- For now, let's stick to "Stealing" for simplicity, but know it's a "carrying" state here.
player:SetAttribute("Stealing", true) -- Player is "carrying" something
player:SetAttribute("StealingPlot", plotUUID) -- Plot where it was picked up
player:SetAttribute("StealingSlot", animalSlot) -- Slot where it was picked up
player:SetAttribute("IsCarryingOwned", true) -- New attribute to distinguish from stolen animals
local coloredAnimalName = self:_getColoredAnimalName(animal.Index)
self:_sendNotification(player, "You picked up your " .. coloredAnimalName .. "!")
return true, "Animal grabbed successfully."
elseif actionId == "Place" then
end
end
function AnimalStealing:_cleanupStolenAnimal(player)
local stolenAnimalModel = self.playerStolenModels[player]
if stolenAnimalModel and stolenAnimalModel.Parent then
if CollectionService:HasTag(stolenAnimalModel, "LaVaccaModel") then
CollectionService:RemoveTag(stolenAnimalModel, "LaVaccaModel")
end
stolenAnimalModel:Destroy()
end
local carryAnimTrack = self.playerCarryAnimTracks[player]
if carryAnimTrack then
if carryAnimTrack.IsPlaying then
carryAnimTrack:Stop()
end
carryAnimTrack:Destroy()
self.playerCarryAnimTracks[player] = nil
end
self.playerStolenModels[player] = nil
end
return AnimalStealing - Edit
03:12:20.450
- Edit
03:12:20.450
============================== - Edit
03:12:20.450 📜 ServerScriptService.Services.RoadAnimalService - Edit
03:12:20.450 ==============================
- Edit
03:12:20.450 local RoadAnimalService = {}
RoadAnimalService.__index = RoadAnimalService
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Config = require(script.Configuration.RoadAnimalConfig)
local RoadAnimalSpawner = require(script.RoadAnimalSpawner)
local RoadAnimalPathfinder = require(script.RoadAnimalPathfinder)
local RoadAnimalInteraction = require(script.RoadAnimalInteraction)
local RoadPityDisplay = require(script.RoadPityDisplay)
local Animals = require(ReplicatedStorage.Datas.Animals)
local Net = require(ReplicatedStorage.Packages.Net)
local NumberUtils = require(ReplicatedStorage.Utils.NumberUtils)
function RoadAnimalService.new()
local self = setmetatable({}, RoadAnimalService)
self.Config = Config
self.Spawner = RoadAnimalSpawner.new(Config)
self.Pathfinder = RoadAnimalPathfinder.new(Config)
self.Interaction = RoadAnimalInteraction.new(Config)
self.PityDisplay = RoadPityDisplay.new(Config)
self.ActiveAnimals = {}
self.IsRunning = false
self:_connectModules()
self:_setupRemotes()
return self
end
function RoadAnimalService:_connectModules()
self.Spawner:SetPathfinder(self.Pathfinder)
self.Interaction:SetMainService(self)
if self.Pathfinder.Initialize then
self.Pathfinder:Initialize()
end
self.Spawner:SetAnimalSpawnedCallback(function(animalTemplate, animalData)
self:_onAnimalSpawned(animalTemplate, animalData)
end)
self.Pathfinder:SetAnimalReachedEndCallback(function(animalTemplate)
self:_onAnimalReachedEnd(animalTemplate)
end)
self.PityDisplay:Initialize()
self.Spawner:SetPityDisplay(self.PityDisplay)
end
function RoadAnimalService:_setupRemotes()
Net:Connect("RoadAnimalService/BuyRoadAnimal", function(player, animalIndex)
self:HandlePurchaseAttempt(player, animalIndex)
end)
end
function RoadAnimalService:_onAnimalSpawned(animalTemplate, animalData)
self.ActiveAnimals[animalTemplate] = {
Data = animalData,
SpawnTime = tick()
}
self.Interaction:SetupAnimalInteraction(animalTemplate, animalData)
self.Pathfinder:StartPathfinding(animalTemplate)
end
function RoadAnimalService:_onAnimalReachedEnd(animalTemplate)
self:_cleanupAnimal(animalTemplate)
end
function RoadAnimalService:_cleanupAnimal(animalTemplate)
if self.ActiveAnimals[animalTemplate] then
self.ActiveAnimals[animalTemplate] = nil
end
self.Interaction:CleanupAnimalInteraction(animalTemplate)
if animalTemplate and animalTemplate.Parent then
animalTemplate:Destroy()
end
end
function RoadAnimalService:Start()
if self.IsRunning then
return
end
self.IsRunning = true
self.Spawner:StartSpawning()
self.PityDisplay:Start()
end
function RoadAnimalService:Stop()
if not self.IsRunning then
return
end
self.IsRunning = false
self.Spawner:StopSpawning()
self.PityDisplay:Stop()
for animalTemplate in pairs(self.ActiveAnimals) do
self:_cleanupAnimal(animalTemplate)
end
end
function RoadAnimalService:HandlePurchaseAttempt(player, animalIndex)
if not player or not animalIndex then
warn("Invalid purchase attempt - missing player or animal index")
return
end
if self.Config.DEBUG.PRINT_PURCHASE_INFO then
print(("🛒 Purchase attempt by %s for animal index: %s"):format(player.Name, tostring(animalIndex)))
end
if not self.IsRunning then
local Net = require(ReplicatedStorage.Packages.Net)
local NotificationEvent = Net:RemoteEvent("NotificationService/Notify")
NotificationEvent:FireClient(player, "Road animal system is currently offline.", 3)
return
end
end
function RoadAnimalService:GetStatus()
return {
IsRunning = self.IsRunning,
ActiveAnimals = #self.ActiveAnimals,
SpawnerActive = self.Spawner:IsSpawningActive(),
ActiveSpawns = self.Spawner:GetActiveSpawnCount()
}
end
return RoadAnimalService - Edit
03:12:20.450
- Edit
03:12:20.451
============================== - Edit
03:12:20.451 📜 ServerScriptService.Services.RoadAnimalService.Configuration.RoadAnimalConfig - Edit
03:12:20.451 ==============================
- Edit
03:12:20.451 local RoadAnimalConfig = {
SPAWN_SETTINGS = {
MAX_ANIMALS_ON_ROAD = 50,
SPAWN_COOLDOWN = require(game.ReplicatedStorage.Datas.Game).RoadSpawn.SpawnEvery,
PITY_TIMERS = require(game.ReplicatedStorage.Datas.Game).RoadSpawn.PittyList,
DESPAWN_DISTANCE = 100,
},
MOVEMENT_SETTINGS = {
BASE_SPEED = require(game.ReplicatedStorage.Datas.Game).RoadSpawn.AnimalSpeed,
SPEED_VARIANCE = 0.3,
STUCK_TIMEOUT = 5,
CLEANUP_DELAY = 2,
},
ROAD_SETTINGS = {
WAYPOINT_SPACING = 8,
AGENT_RADIUS = 2,
AGENT_HEIGHT = 5,
},
INTERACTION_SETTINGS = {
PROMPT_HOLD_DURATION = 0.5,
PROMPT_DISTANCE = 10,
},
PURCHASE_SETTINGS = {
NOTIFICATION_DURATION = 3,
},
PERFORMANCE = {
UPDATE_FREQUENCY = 30,
CLEANUP_INTERVAL = 30,
MAX_PATH_RETRIES = 3,
BATCH_SIZE = 5,
MAX_CONCURRENT_SPAWNS = 3,
},
DEBUG = {
ENABLED = false,
VISUALIZE_PATHS = false,
PRINT_SPAWN_INFO = false,
PRINT_MOVEMENT_INFO = false,
PRINT_INTERACTION_INFO = false,
PRINT_PURCHASE_INFO = false,
SHOW_PERFORMANCE_STATS = false,
},
}
return RoadAnimalConfig - Edit
03:12:20.451
- Edit
03:12:20.451
============================== - Edit
03:12:20.451 📜 ServerScriptService.Services.RoadAnimalService.RoadAnimalPathfinder - Edit
03:12:20.451 ==============================
- Edit
03:12:20.451 local RoadAnimalPathfinder = {}
RoadAnimalPathfinder.__index = RoadAnimalPathfinder
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local PathfindingService = game:GetService("PathfindingService")
local function MakeNonCollidable(model)
for _, part in ipairs(model:GetDescendants()) do
if part:IsA("BasePart") then
part.CanCollide = false
part.CanQuery = false
part.CanTouch = false
end
end
end
local SimplePath = require(ReplicatedStorage.Packages.SimplePath)
function RoadAnimalPathfinder.new(config)
local self = setmetatable({}, RoadAnimalPathfinder)
self.Config = config
self.ActivePaths = {}
self.AnimalReachedEndCallback = nil
return self
end
function RoadAnimalPathfinder:SetAnimalReachedEndCallback(callback)
self.AnimalReachedEndCallback = callback
end
function RoadAnimalPathfinder:StartPathfinding(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
warn("Invalid animal template provided to pathfinder")
return false
end
local humanoid = animalTemplate:FindFirstChild("Humanoid")
local humanoidRootPart = animalTemplate.PrimaryPart
humanoid.WalkSpeed = require(ReplicatedStorage:WaitForChild("Datas").Game).RoadSpawn.AnimalSpeed
humanoid.StateChanged:Connect(function(_, newState)
if newState == Enum.HumanoidStateType.Physics then
humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
end
end)
local pathConfig = {
WaypointSpacing = self.Config.ROAD_SETTINGS.WAYPOINT_SPACING,
AgentRadius = math.min(self.Config.ROAD_SETTINGS.AGENT_RADIUS, 2),
AgentHeight = math.min(self.Config.ROAD_SETTINGS.AGENT_HEIGHT, 5),
AgentCanJump = true,
AgentCanClimb = false,
Costs = {
Water = 20,
DangerousLava = math.huge
}
}
local path = SimplePath.new(animalTemplate, pathConfig)
if self.Config.DEBUG.VISUALIZE_PATHS then
path.Visualize = true
end
self:_setupPathEvents(animalTemplate, path)
self.ActivePaths[animalTemplate] = {
Path = path,
StartTime = tick(),
IsStuck = false,
StuckTime = 0,
Retries = 0,
FallbackMode = false,
LastPosition = humanoidRootPart.Position
}
self:_startMovement(animalTemplate, path)
return true
end
function RoadAnimalPathfinder:StopPathfinding(animal)
local pathData = self.ActivePaths[animal]
if not pathData then
return
end
if pathData.Path.Status == "Active" then
pathData.Path:Stop()
end
-- Stop any fallback movement
if pathData.FallbackConnection then
pathData.FallbackConnection:Disconnect()
pathData.FallbackConnection = nil
end
self.ActivePaths[animal] = nil
if self.Config.DEBUG.PRINT_MOVEMENT_INFO then
print(("⏹️ Stopped pathfinding for animal: %s"):format(animal.Name))
end
end
function RoadAnimalPathfinder:_setupPathEvents(animal, path)
path.Reached:Connect(function(agent, finalWaypoint)
self:_onAnimalReachedEnd(animal)
end)
path.Blocked:Connect(function(agent, blockedWaypoint)
self:_onAnimalBlocked(animal, path)
end)
path.Error:Connect(function(errorType)
self:_onPathError(animal, path, errorType)
end)
if self.Config.DEBUG.PRINT_MOVEMENT_INFO then
path.WaypointReached:Connect(function(agent, oldWaypoint, newWaypoint)
if newWaypoint then
print(("📍 Animal %s reached waypoint at position: %s"):format(
animal.Name, tostring(newWaypoint.Position)))
end
end)
end
end
function RoadAnimalPathfinder:_startMovement(animal, path)
local endPoint = self:_getEndPoint()
if not endPoint then
warn("No end point found for road!")
-- Start fallback movement instead of failing
self:_startFallbackMovement(animal)
return
end
if self.Config.DEBUG.PRINT_MOVEMENT_INFO then
print(("🚀 Starting movement for %s to end point"):format(animal.Name))
end
local success = path:Run(endPoint)
if not success then
-- If pathfinding fails immediately, start fallback movement
self:_startFallbackMovement(animal)
end
end
function RoadAnimalPathfinder:_onAnimalReachedEnd(animal)
local pathData = self.ActivePaths[animal]
if pathData and pathData.IsMovingToPlayer then
if self.Config.DEBUG.PRINT_MOVEMENT_INFO then
print(("🏠 Animal %s reached player's plot"):format(animal.Name))
end
self:_handleAnimalReachedPlayerPlot(animal)
else
if self.Config.DEBUG.PRINT_MOVEMENT_INFO then
print(("🎯 Animal reached end: %s"):format(animal.Name))
end
self:StopPathfinding(animal)
local humanoid = animal:FindFirstChildOfClass("Humanoid")
if humanoid then
humanoid:MoveTo(animal.PrimaryPart.Position)
humanoid.WalkSpeed = 0
humanoid.JumpPower = 0
humanoid:ChangeState(Enum.HumanoidStateType.Physics)
end
animal:Destroy()
if self.AnimalReachedEndCallback then
self.AnimalReachedEndCallback(animal)
end
end
end
function RoadAnimalPathfinder:_handleAnimalReachedPlayerPlot(animal)
local proximityPrompt = animal.PrimaryPart:FindFirstChild("PromptAttachment"):FindFirstChild("ProximityPrompt")
local targetPlayerId = proximityPrompt and proximityPrompt:GetAttribute("TargetPlayer")
if targetPlayerId then
local player = game.Players:GetPlayerByUserId(targetPlayerId)
if player then
self:_addAnimalToPlayerPlot(player, animal)
if self.Config.DEBUG.PRINT_PURCHASE_INFO then
print(("✅ Animal %s added to %s's plot"):format(animal.Name, player.Name))
end
end
end
self:StopPathfinding(animal)
if self.AnimalReachedEndCallback then
self.AnimalReachedEndCallback(animal)
end
end
function RoadAnimalPathfinder:_addAnimalToPlayerPlot(player, animal)
if self.Config.DEBUG.PRINT_PURCHASE_INFO then
print(("📝 Adding animal %s to %s's plot data"):format(animal.Name, player.Name))
end
local proximityPrompt = animal.PrimaryPart:FindFirstChild("PromptAttachment"):FindFirstChild("ProximityPrompt")
local animalIndex = proximityPrompt and proximityPrompt:GetAttribute("AnimalData")
local targetPlayer = proximityPrompt and proximityPrompt:GetAttribute("TargetPlayer")
local animalMutation = animal:GetAttribute("Mutation")
local animalTraits = animal:GetAttribute("Traits")
if self.Config.DEBUG.PRINT_PURCHASE_INFO then
print(("🔍 Debug attributes - AnimalData: %s, TargetPlayer: %s, Mutation: %s, Traits: %s"):format(
tostring(animalIndex), tostring(targetPlayer), tostring(animalMutation), tostring(animalTraits)))
end
if not animalIndex then
warn("No animal data found for purchased animal:", animal.Name)
warn("Available attributes:", proximityPrompt and proximityPrompt:GetAttributes() or "No prompt found")
return
end
local ServerScriptService = game:GetService("ServerScriptService")
local DataManagement = require(ServerScriptService.Services.DataManagment)
if DataManagement.isDataReady(player) then
DataManagement.addAnimal(player, animalIndex, animalMutation, animalTraits)
local indexSuccess = DataManagement.addToIndex(player, animalIndex, animalMutation)
if indexSuccess then
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Synchronizer = require(ReplicatedStorage.Packages.Synchronizer)
local playerSync = Synchronizer:Get(player)
if playerSync then
local profile = DataManagement.GetDataMan(player)
if profile and profile.Data and profile.Data.Index then
playerSync:Set("Index", profile.Data.Index)
end
end
if self.Config.DEBUG.PRINT_PURCHASE_INFO then
local mutationText = animalMutation and (" (" .. animalMutation .. ")") or " (Default)"
print(("📖 Added %s%s to %s's Index collection"):format(animalIndex, mutationText, player.Name))
end
else
warn("Failed to add animal to Index for player:", player.Name)
end
self:_updatePlotAnimalList(player)
if self.Config.DEBUG.PRINT_PURCHASE_INFO then
local mutationText = animalMutation and (" with " .. animalMutation .. " mutation") or ""
print(("✅ Successfully added %s%s to %s's animal collection"):format(animalIndex, mutationText, player.Name))
end
else
warn("Player data not ready when adding animal:", player.Name)
end
end
function RoadAnimalPathfinder:_onAnimalBlocked(animal, path)
local pathData = self.ActivePaths[animal]
if not pathData then
return
end
if self.Config.DEBUG.PRINT_MOVEMENT_INFO then
print(("⚠️ Animal blocked: %s - switching to fallback movement"):format(animal.Name))
end
-- Instead of marking as stuck, switch to fallback movement
self:_startFallbackMovement(animal)
end
function RoadAnimalPathfinder:_onPathError(animal, path, errorType)
if self.Config.DEBUG.PRINT_MOVEMENT_INFO then
print(("⚠️ Path error for animal %s: %s - switching to fallback movement"):format(animal.Name, tostring(errorType)))
end
-- Instead of retrying or removing, switch to fallback movement
self:_startFallbackMovement(animal)
end
function RoadAnimalPathfinder:_startFallbackMovement(animal)
local pathData = self.ActivePaths[animal]
if not pathData then
return
end
local humanoid = animal:FindFirstChildOfClass("Humanoid")
if not humanoid then
return
end
-- Stop the current path
if pathData.Path.Status == "Active" then
pathData.Path:Stop()
end
pathData.FallbackMode = true
if self.Config.DEBUG.PRINT_MOVEMENT_INFO then
print(("🚶 Starting fallback movement for %s"):format(animal.Name))
end
-- Disconnect any existing fallback connection
if pathData.FallbackConnection then
pathData.FallbackConnection:Disconnect()
end
-- Create a simple forward movement
pathData.FallbackConnection = RunService.Heartbeat:Connect(function()
if not animal or not animal.Parent then
if pathData.FallbackConnection then
pathData.FallbackConnection:Disconnect()
pathData.FallbackConnection = nil
end
return
end
local humanoidRootPart = animal.PrimaryPart
if not humanoidRootPart then
return
end
-- Get the end point
local endPoint = self:_getEndPoint()
if endPoint then
-- Calculate direction towards end point
local direction = (endPoint - humanoidRootPart.Position).Unit
local targetPosition = humanoidRootPart.Position + (direction * 10)
-- Make sure the animal keeps walking towards the end
humanoid:MoveTo(targetPosition)
-- Check if animal reached the end
local distanceToEnd = (endPoint - humanoidRootPart.Position).Magnitude
if distanceToEnd < 5 then
self:_onAnimalReachedEnd(animal)
return
end
else
-- If no end point, just move forward
local lookDirection = humanoidRootPart.CFrame.LookVector
local targetPosition = humanoidRootPart.Position + (lookDirection * 10)
humanoid:MoveTo(targetPosition)
end
end)
end
function RoadAnimalPathfinder:_retryPath(animal, path)
-- This function is now simplified - just start fallback movement
if self.Config.DEBUG.PRINT_MOVEMENT_INFO then
print(("🔄 Switching to fallback movement for animal: %s"):format(animal.Name))
end
self:_startFallbackMovement(animal)
end
function RoadAnimalPathfinder:_getEndPoint()
local Road = workspace:FindFirstChild("Road")
if not Road then
warn("Road folder not found in workspace!")
return nil
end
local endPoint = Road:FindFirstChild("End")
if not endPoint then
warn("Road end point not found!")
return nil
end
return endPoint.Position
end
function RoadAnimalPathfinder:_performStuckCleanup()
-- This cleanup is now less aggressive since we use fallback movement
local currentTime = tick()
local stuckAnimals = {}
for animal, pathData in pairs(self.ActivePaths) do
-- Only clean up animals that have been inactive for a very long time
if pathData.IsStuck and (currentTime - pathData.StuckTime) > (self.Config.MOVEMENT_SETTINGS.STUCK_TIMEOUT * 3) then
table.insert(stuckAnimals, animal)
end
end
for _, animal in ipairs(stuckAnimals) do
warn(("Removing extremely stuck animal: %s"):format(animal.Name))
self:_onAnimalReachedEnd(animal)
end
end
function RoadAnimalPathfinder:_updatePerformanceStats()
if not self.Config.DEBUG.SHOW_PERFORMANCE_STATS then
return
end
local activeCount = 0
local stuckCount = 0
local fallbackCount = 0
for animal, pathData in pairs(self.ActivePaths) do
activeCount = activeCount + 1
if pathData.IsStuck then
stuckCount = stuckCount + 1
end
if pathData.FallbackMode then
fallbackCount = fallbackCount + 1
end
end
if activeCount > 0 then
print(("📊 Pathfinder Stats - Active: %d, Stuck: %d, Fallback: %d"):format(activeCount, stuckCount, fallbackCount))
end
end
function RoadAnimalPathfinder:_startBackgroundProcesses()
task.spawn(function()
while true do
task.wait(10)
self:_performStuckCleanup()
end
end)
if self.Config.DEBUG.SHOW_PERFORMANCE_STATS then
task.spawn(function()
while true do
task.wait(30)
self:_updatePerformanceStats()
end
end)
end
end
function RoadAnimalPathfinder:GetActivePathCount()
local count = 0
for _ in pairs(self.ActivePaths) do
count = count + 1
end
return count
end
function RoadAnimalPathfinder:GetStuckAnimals()
local stuckAnimals = {}
for animal, pathData in pairs(self.ActivePaths) do
if pathData.IsStuck then
table.insert(stuckAnimals, animal)
end
end
return stuckAnimals
end
function RoadAnimalPathfinder:GetFallbackAnimals()
local fallbackAnimals = {}
for animal, pathData in pairs(self.ActivePaths) do
if pathData.FallbackMode then
table.insert(fallbackAnimals, animal)
end
end
return fallbackAnimals
end
function RoadAnimalPathfinder:ForceStopAll()
for animal, _ in pairs(self.ActivePaths) do
self:StopPathfinding(animal)
end
end
function RoadAnimalPathfinder:Initialize()
self:_startBackgroundProcesses()
end
function RoadAnimalPathfinder:ChangeTarget(animal, newTargetPosition)
local pathData = self.ActivePaths[animal]
if not pathData then
warn("No active path found for animal:", animal.Name)
return false
end
if self.Config.DEBUG.PRINT_MOVEMENT_INFO then
print(("🎯 Changing target for %s to position: %s"):format(animal.Name, tostring(newTargetPosition)))
end
-- Stop fallback movement if active
if pathData.FallbackConnection then
pathData.FallbackConnection:Disconnect()
pathData.FallbackConnection = nil
pathData.FallbackMode = false
end
if pathData.Path.Status == "Active" then
pathData.Path:Stop()
end
local success = pathData.Path:Run(newTargetPosition)
if success then
pathData.IsMovingToPlayer = true
pathData.PlayerTarget = newTargetPosition
if self.Config.DEBUG.PRINT_MOVEMENT_INFO then
print(("✅ Successfully changed path for %s"):format(animal.Name))
end
else
warn(("❌ Failed to change path for %s - using fallback movement"):format(animal.Name))
-- If changing target fails, use fallback movement towards new target
self:_startFallbackMovementToTarget(animal, newTargetPosition)
success = true
end
return success
end
function RoadAnimalPathfinder:_startFallbackMovementToTarget(animal, targetPosition)
local pathData = self.ActivePaths[animal]
if not pathData then
return
end
local humanoid = animal:FindFirstChildOfClass("Humanoid")
if not humanoid then
return
end
pathData.FallbackMode = true
pathData.IsMovingToPlayer = true
pathData.PlayerTarget = targetPosition
if self.Config.DEBUG.PRINT_MOVEMENT_INFO then
print(("🚶 Starting fallback movement to target for %s"):format(animal.Name))
end
-- Disconnect any existing fallback connection
if pathData.FallbackConnection then
pathData.FallbackConnection:Disconnect()
end
-- Create movement towards specific target
pathData.FallbackConnection = RunService.Heartbeat:Connect(function()
if not animal or not animal.Parent then
if pathData.FallbackConnection then
pathData.FallbackConnection:Disconnect()
pathData.FallbackConnection = nil
end
return
end
local humanoidRootPart = animal.PrimaryPart
if not humanoidRootPart then
return
end
-- Calculate direction towards target
local direction = (targetPosition - humanoidRootPart.Position).Unit
local movePosition = humanoidRootPart.Position + (direction * 10)
humanoid:MoveTo(movePosition)
-- Check if animal reached the target
local distanceToTarget = (targetPosition - humanoidRootPart.Position).Magnitude
if distanceToTarget < 5 then
self:_onAnimalReachedEnd(animal)
return
end
end)
end
function RoadAnimalPathfinder:_updatePlotAnimalList(player)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Synchronizer = require(ReplicatedStorage.Packages.Synchronizer)
local DataManagement = require(ServerScriptService.Services.DataManagment)
task.wait(0.2)
local plotsFolder = workspace:FindFirstChild("Plots")
if not plotsFolder then
return
end
local playerPlot = nil
for _, plot in pairs(plotsFolder:GetChildren()) do
if plot:GetAttribute("Owner") == player.UserId then
playerPlot = plot
break
end
end
if not playerPlot then
return
end
local plotUUID = playerPlot.Name
local plotSync = Synchronizer:Get(plotUUID)
local playerSync = Synchronizer:Get(player)
if plotSync then
local updatedAnimalList = DataManagement.getAnimalList(player)
plotSync:Set("AnimalList", updatedAnimalList)
plotSync:Set("AnimalPodiums", updatedAnimalList)
if playerSync then
playerSync:Set("AnimalAddedOrRemoved", updatedAnimalList)
playerSync:Set("AnimalPodiums", updatedAnimalList)
end
if self.Config.DEBUG.PRINT_PURCHASE_INFO then
print(("🔄 Updated plot animal list for %s (Count: %d)"):format(player.Name, #updatedAnimalList))
end
end
end
return RoadAnimalPathfinder - Edit
03:12:20.451
- Edit
03:12:20.451
============================== - Edit
03:12:20.451 📜 ServerScriptService.Services.RoadAnimalService.RoadAnimalInteraction - Edit
03:12:20.452 ==============================
- Edit
03:12:20.452 local RoadAnimalInteraction = {}
RoadAnimalInteraction.__index = RoadAnimalInteraction
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local ServerScriptService = game:GetService("ServerScriptService")
local Net = require(ReplicatedStorage.Packages.Net)
local NotificationEvent = Net:RemoteEvent("NotificationService/Notify")
local Animals = require(ReplicatedStorage.Datas.Animals)
local NumberUtils = require(ReplicatedStorage.Utils.NumberUtils)
local DataManagement = require(ServerScriptService.Services.DataManagment)
function RoadAnimalInteraction.new(config)
local self = setmetatable({}, RoadAnimalInteraction)
self.Config = config
self.MainService = nil
self.AnimalPrompts = {}
return self
end
function RoadAnimalInteraction:SetMainService(mainService)
self.MainService = mainService
end
function RoadAnimalInteraction:SetupAnimalInteraction(animalTemplate, animalData)
if not animalTemplate or not animalData then
warn("Invalid animal or data provided to interaction setup")
return
end
local primaryPart = animalTemplate.PrimaryPart
if not primaryPart then
warn("Animal template missing PrimaryPart for interaction")
return
end
local promptAttachment = primaryPart:FindFirstChild("PromptAttachment")
if not promptAttachment then
warn("Animal template missing PromptAttachment for interaction")
return
end
local proximityPrompt = promptAttachment:FindFirstChild("ProximityPrompt")
if not proximityPrompt then
warn("Animal template missing ProximityPrompt for interaction")
return
end
self:_setupPromptBehavior(proximityPrompt, animalTemplate, animalData)
self.AnimalPrompts[animalTemplate] = proximityPrompt
end
function RoadAnimalInteraction:CleanupAnimalInteraction(animalTemplate)
local prompt = self.AnimalPrompts[animalTemplate]
if prompt then
self.AnimalPrompts[animalTemplate] = nil
end
end
function RoadAnimalInteraction:_setupPromptBehavior(proximityPrompt, animalTemplate, animalData)
proximityPrompt.Triggered:Connect(function(player)
self:_handleInteraction(player, animalTemplate, animalData)
end)
end
function RoadAnimalInteraction:_handleInteraction(player, animalTemplate, animalData)
local basePrice = animalData.Price or 0
local currentPrice = animalTemplate:GetAttribute("CurrentPrice") or basePrice
local playerMoney = self:_getPlayerMoney(player)
if playerMoney < currentPrice then
local moneyNeeded = currentPrice - playerMoney
local message = ("You need $%s more to buy this"):format(NumberUtils:ToString(moneyNeeded))
self:_sendNotification(player, message, "error")
return
end
if not self:_hasSpaceInPlot(player) then
return
end
local success = self:_processPurchase(player, currentPrice)
if not success then
self:_sendNotification(player, "Purchase failed. Please try again.", "error")
return
end
local newPrice = currentPrice + math.floor(basePrice * 0.5)
animalTemplate:SetAttribute("CurrentPrice", newPrice)
self:_sendAnimalToPlayer(player, animalTemplate, animalData)
local Sound = game.ReplicatedStorage.Sounds.Animals:FindFirstChild(animalData.DisplayName)
if Sound then
Sound:Play()
end
end
function RoadAnimalInteraction:_getPlayerMoney(player)
if not DataManagement.isDataReady(player) then
if self.Config.DEBUG.PRINT_PURCHASE_INFO then
print(("⚠️ Player data not ready for %s"):format(player.Name))
end
return 0
end
local coins = DataManagement.GetCoins(player)
if self.Config.DEBUG.PRINT_PURCHASE_INFO then
print(("💰 Player %s has %d coins"):format(player.Name, coins))
end
return coins
end
function RoadAnimalInteraction:_hasSpaceInPlot(player)
if not DataManagement.isDataReady(player) then
if self.Config.DEBUG.PRINT_PURCHASE_INFO then
print(("⚠️ Player data not ready for space check: %s"):format(player.Name))
end
return false
end
local ServerScriptService = game:GetService("ServerScriptService")
local PlotsService = require(ServerScriptService.Services.Plots)
local playerPlot = PlotsService.getPlotModel(player)
if not playerPlot then
if self.Config.DEBUG.PRINT_PURCHASE_INFO then
print(("⚠️ Player %s doesn't have a plot yet"):format(player.Name))
end
return false
end
local animalList = DataManagement.getAnimalList(player)
local maxAnimals = DataManagement.GetMaxAnimals(player)
local animalCount = 0
for _, animal in pairs(animalList) do
if animal ~= "Empty" and animal ~= nil then
animalCount = animalCount + 1
end
end
local animalsInTransit = self:_countAnimalsInTransit(player)
local totalAnimals = animalCount + animalsInTransit
local hasSpace = totalAnimals < maxAnimals
if self.Config.DEBUG.PRINT_PURCHASE_INFO then
print(("🏠 Player %s has %d/%d animals (%d in plot + %d in transit) (Space: %s)"):format(
player.Name, totalAnimals, maxAnimals, animalCount, animalsInTransit, tostring(hasSpace)))
end
return hasSpace
end
function RoadAnimalInteraction:_countAnimalsInTransit(player)
if not self.MainService or not self.MainService.ActiveAnimals then
return 0
end
local count = 0
local playerUserId = player.UserId
for animalTemplate, _ in pairs(self.MainService.ActiveAnimals) do
if animalTemplate and animalTemplate.Parent then
local proximityPrompt = animalTemplate.PrimaryPart and
animalTemplate.PrimaryPart:FindFirstChild("PromptAttachment") and
animalTemplate.PrimaryPart.PromptAttachment:FindFirstChild("ProximityPrompt")
if proximityPrompt then
local targetPlayerId = proximityPrompt:GetAttribute("TargetPlayer")
if targetPlayerId == playerUserId then
count = count + 1
end
end
end
end
return count
end
function RoadAnimalInteraction:_processPurchase(player, animalPrice)
if not DataManagement.isDataReady(player) then
warn(("Player data not ready for purchase: %s"):format(player.Name))
return false
end
local currentMoney = DataManagement.GetCoins(player)
if currentMoney < animalPrice then
if self.Config.DEBUG.PRINT_PURCHASE_INFO then
print(("❌ Insufficient funds at purchase time for %s"):format(player.Name))
end
return false
end
local deductionSuccess = DataManagement.deductCoins(player, animalPrice)
if not deductionSuccess then
warn(("Failed to deduct %d coins from %s"):format(animalPrice, player.Name))
return false
end
if self.Config.DEBUG.PRINT_PURCHASE_INFO then
print(("💸 Successfully deducted %d coins from %s"):format(animalPrice, player.Name))
end
self:_updatePlayerSyncData(player)
return true
end
function RoadAnimalInteraction:_sendAnimalToPlayer(player, animalTemplate, animalData)
local proximityPrompt = animalTemplate.PrimaryPart:FindFirstChild("PromptAttachment"):FindFirstChild("ProximityPrompt")
if proximityPrompt then
local animalIndex = animalTemplate:GetAttribute("Index")
proximityPrompt:SetAttribute("TargetPlayer", player.UserId)
proximityPrompt:SetAttribute("AnimalData", animalIndex)
if self.Config.DEBUG.PRINT_PURCHASE_INFO then
print(("🏷️ Set animal data on prompt: Player=%d, Animal=%s"):format(player.UserId, animalIndex or "unknown"))
end
else
warn("Failed to find proximity prompt for animal:", animalTemplate.Name)
end
local playerPlot = self:_findPlayerPlot(player)
if not playerPlot then
warn("Player plot not found for:", player.Name)
return
end
local animalTarget = playerPlot:FindFirstChild("AnimalTarget")
if not animalTarget then
warn("AnimalTarget not found in player plot for:", player.Name)
return
end
if self.MainService and self.MainService.Pathfinder then
self.MainService.Pathfinder:ChangeTarget(animalTemplate, animalTarget.Position)
end
if self.Config.DEBUG.PRINT_PURCHASE_INFO then
print(("🛒 %s purchased by %s, moving to their plot"):format(animalData.DisplayName, player.Name))
end
end
function RoadAnimalInteraction:_findPlayerPlot(player)
local ServerScriptService = game:GetService("ServerScriptService")
local PlotsService = require(ServerScriptService.Services.Plots)
local plotModel = PlotsService.getPlotModel(player)
if plotModel then
if self.Config.DEBUG.PRINT_PURCHASE_INFO then
print(("✅ Found plot via Plots service: %s for player %s"):format(plotModel.Name, player.Name))
end
return plotModel
end
local plotsFolder = workspace:FindFirstChild("Plots")
if not plotsFolder then
warn("Plots folder not found in workspace for player:", player.Name)
return nil
end
if self.Config.DEBUG.PRINT_PURCHASE_INFO then
print(("🔍 Fallback search for plot for player %s (UserId: %d)"):format(player.Name, player.UserId))
for _, plot in pairs(plotsFolder:GetChildren()) do
local owner = plot:GetAttribute("Owner")
print((" Plot %s has owner: %s"):format(plot.Name, tostring(owner)))
end
end
for _, plot in pairs(plotsFolder:GetChildren()) do
if plot:GetAttribute("Owner") == player.UserId then
if self.Config.DEBUG.PRINT_PURCHASE_INFO then
print(("✅ Found plot via fallback: %s for player %s"):format(plot.Name, player.Name))
end
return plot
end
end
warn(("❌ Player plot not found for: %s (UserId: %d)"):format(player.Name, player.UserId))
return nil
end
function RoadAnimalInteraction:_updatePlayerSyncData(player)
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Synchronizer = require(ReplicatedStorage.Packages.Synchronizer)
task.wait(0.2)
local updatedData = DataManagement.GetDataMan(player)
local playerSync = Synchronizer:Get(player)
if updatedData and playerSync then
local currentSyncCoins = playerSync:Get("Coins") or 0
local newCoins = updatedData.Coins
if self.Config.DEBUG.PRINT_PURCHASE_INFO then
print(("🔄 Coin sync - Before: %d, After: %d, Setting to: %d"):format(
currentSyncCoins, newCoins, newCoins))
end
playerSync:Set("Coins", newCoins)
else
warn("Failed to update player sync data - missing data or sync object for:", player.Name)
end
end
function RoadAnimalInteraction:_sendNotification(player, message, notificationType)
notificationType = notificationType or "info"
local formattedMessage = message
if notificationType == "error" then
formattedMessage = ("%s"):format(message)
elseif notificationType == "success" then
formattedMessage = ("%s"):format(message)
end
local duration = self.Config.PURCHASE_SETTINGS.NOTIFICATION_DURATION or 3
NotificationEvent:FireClient(player, formattedMessage, duration)
end
return RoadAnimalInteraction - Edit
03:12:20.452
- Edit
03:12:20.452
============================== - Edit
03:12:20.452 📜 ServerScriptService.Services.RoadAnimalService.RoadPityDisplay - Edit
03:12:20.452 ==============================
- Edit
03:12:20.452 local RoadPityDisplay = {}
RoadPityDisplay.__index = RoadPityDisplay
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
function RoadPityDisplay.new(Config)
local self = setmetatable({}, RoadPityDisplay)
self.Config = Config
self.IsRunning = false
self.Connection = nil
self.PityTimers = {}
self.RoadPanel = nil
self.MainFrame = nil
self.LegendaryLabel = nil
self.MythicLabel = nil
return self
end
function RoadPityDisplay:Initialize()
local GameData = require(ReplicatedStorage.Datas.Game)
local PittyList = GameData.RoadSpawn.PittyList
for _, PittyData in ipairs(PittyList) do
local RarityName = PittyData[1]
local TimeInterval = PittyData[2]
if RarityName == "Legendary" or RarityName == "Mythic" then
self.PityTimers[RarityName] = {
MaxTime = TimeInterval,
CurrentTime = TimeInterval,
LastUpdate = tick()
}
end
end
self:_setupUIReferences()
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print("🎯 RoadPityDisplay initialized with timers:", self.PityTimers)
end
end
function RoadPityDisplay:_setupUIReferences()
self.RoadPanel = workspace:FindFirstChild("RoadPanel")
if not self.RoadPanel then
warn("RoadPanel not found in workspace!")
return false
end
local SurfaceGui = self.RoadPanel:FindFirstChild("SurfaceGui")
if not SurfaceGui then
warn("SurfaceGui not found in RoadPanel!")
return false
end
self.MainFrame = SurfaceGui:FindFirstChild("MainFrame")
if not self.MainFrame then
warn("MainFrame not found in SurfaceGui!")
return false
end
self.LegendaryLabel = self.MainFrame:FindFirstChild("Legendary")
self.MythicLabel = self.MainFrame:FindFirstChild("Mythic")
if not (self.LegendaryLabel and self.MythicLabel) then
warn("One or more pity labels not found in MainFrame!")
return false
end
for _, Label in ipairs({self.LegendaryLabel, self.MythicLabel}) do
Label.RichText = true
end
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print("🖥️ RoadPityDisplay UI references setup successfully")
end
return true
end
function RoadPityDisplay:Start()
if self.IsRunning then
return
end
if not self.RoadPanel then
if not self:_setupUIReferences() then
warn("Failed to setup UI references for RoadPityDisplay")
return
end
end
self.IsRunning = true
self.Connection = RunService.Heartbeat:Connect(function()
self:_updateCountdowns()
end)
self:_updateCountdowns()
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print("🎯 RoadPityDisplay started")
end
end
function RoadPityDisplay:Stop()
if not self.IsRunning then
return
end
self.IsRunning = false
if self.Connection then
self.Connection:Disconnect()
self.Connection = nil
end
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print("🛑 RoadPityDisplay stopped")
end
end
function RoadPityDisplay:_formatTime(Seconds)
local Minutes = math.floor(Seconds / 60)
local RemainingSeconds = Seconds % 60
return string.format("%02d:%02d", Minutes, RemainingSeconds)
end
function RoadPityDisplay:_updateCountdowns()
if not self.IsRunning or not self.MainFrame then
return
end
local CurrentTick = tick()
for RarityName, TimerData in pairs(self.PityTimers) do
local DeltaTime = CurrentTick - TimerData.LastUpdate
TimerData.LastUpdate = CurrentTick
TimerData.CurrentTime = TimerData.CurrentTime - DeltaTime
if TimerData.CurrentTime < 0 then
TimerData.CurrentTime = 0
end
local TimeString = self:_formatTime(math.ceil(math.max(0, TimerData.CurrentTime)))
if RarityName == "Legendary" and self.LegendaryLabel then
if TimerData.CurrentTime <= 0 then
self.LegendaryLabel.Text = "Guaranteed Legendary in 0"
else
self.LegendaryLabel.Text = "Guaranteed Legendary in " .. TimeString
end
elseif RarityName == "Mythic" and self.MythicLabel then
if TimerData.CurrentTime <= 0 then
self.MythicLabel.Text = "Guaranteed Mythic in 0"
else
self.MythicLabel.Text = "Guaranteed Mythic in " .. TimeString
end
end
end
end
function RoadPityDisplay:GetTimeRemaining(RarityName)
local TimerData = self.PityTimers[RarityName]
if TimerData then
return math.ceil(TimerData.CurrentTime)
end
return 0
end
function RoadPityDisplay:ResetTimer(RarityName)
local TimerData = self.PityTimers[RarityName]
if TimerData then
TimerData.CurrentTime = TimerData.MaxTime
TimerData.LastUpdate = tick()
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print(("🔄 Manually reset pity timer for %s"):format(RarityName))
end
end
end
return RoadPityDisplay - Edit
03:12:20.452
- Edit
03:12:20.452
============================== - Edit
03:12:20.452 📜 ServerScriptService.Services.RoadAnimalService.RoadAnimalSpawner - Edit
03:12:20.452 ==============================
- Edit
03:12:20.452 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local CollectionService = game:GetService("CollectionService")
local HttpService = game:GetService("HttpService")
local Players = game:GetService("Players")
local Animals = require(ReplicatedStorage.Datas.Animals)
local Mutations = require(ReplicatedStorage.Datas.Mutations)
local Game = require(ReplicatedStorage.Datas.Game)
local NumberUtils = require(ReplicatedStorage.Utils.NumberUtils)
local Net = require(ReplicatedStorage.Packages.Net)
local RoadAnimalSpawner = {}
RoadAnimalSpawner.__index = RoadAnimalSpawner
local ANIMALS_WITH_EFFECTS = {
["Matteo"] = "Matteo",
["Karkerkar Kurkur"] = "Karkerkar Kurkur",
["Los Spyderinis"] = "Sammyni Spyderini",
["Strawberry Elephant"] = "Strawberry",
["La Extinct Grande"] = "Extinct",
["Extinct Matteo"] = "Extinct",
["Extinct Ballerina"] = "Extinct",
["Extinct Tralalero"] = "Extinct",
["Taco Lucky Block"] = "Taco",
["Los Nooo My Hotspotsitos"] = "Taco",
["Quesadilla Crocodila"] = "Taco",
["Capi Taco"] = "Taco",
["Tacorita Bicicleta"] = "Taco",
["Los Tipi Tacos"] = "Taco",
["Bombardini Tortinii"] = "Taco",
["Tipi Topi Taco"] = "Taco",
["Los Tacoritas"] = "Taco",
["Garama and Madundung"] = "Garama",
["La Cucaracha"] = "Mexico",
["Dug dug dug"] = "Mexico",
["Elefanto Frigo"] = "Mexico",
["Sigma Girl"] = "Mexico",
["To to to Sahur"] = "Mexico",
}
local ChatEvent = Net:RemoteEvent("ChatService/ChatMessage")
function RoadAnimalSpawner.new(config)
local self = setmetatable({}, RoadAnimalSpawner)
self.Config = config
self.ActiveSpawns = 0
self.IsSpawning = false
self.PathfinderModule = nil
self.AnimalSpawnedCallback = nil
self.PityDisplay = nil
self.SpawnQueue = {}
self.QueueProcessing = false
self.LastSpawnTime = 0
self._spawnMutex = false
self.SpawnEffectRemote = Net:RemoteEvent("GameService/SpawnEffect")
self.PendingDelayedSpawn = nil
self.DelayedSpawnTime = 0
return self
end
function RoadAnimalSpawner:_triggerSpawnEffect(animalTemplate, animalData)
local animalName = animalData.DisplayName or animalData.Name
local effectName = ANIMALS_WITH_EFFECTS[animalName]
if effectName and self.SpawnEffectRemote then
-- Get the spawn position
local spawnPosition = animalTemplate.PrimaryPart and animalTemplate.PrimaryPart.Position or Vector3.new(0, 0, 0)
self.SpawnEffectRemote:FireAllClients(effectName, spawnPosition)
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print(("✨ VFX DEBUG: Triggered %s effect for %s at position %s"):format(effectName, animalName, tostring(spawnPosition)))
end
end
end
-- NEW FUNCTION: SpawnAnimalChances
function RoadAnimalSpawner:SpawnAnimalChances(animalChances, ownerId, specificMutation)
-- Validate input
if type(animalChances) ~= "table" or next(animalChances) == nil then
warn("SpawnAnimalChances: animalChances must be a non-empty table")
return nil
end
-- Convert animal names to indices and validate
local validatedChances = {}
for animalName, weight in pairs(animalChances) do
if type(weight) ~= "number" or weight <= 0 then
warn(("SpawnAnimalChances: Invalid weight for animal '%s'. Weight must be a positive number."):format(animalName))
continue
end
-- Find animal index by name
local animalIndex = nil
for index, animalData in pairs(Animals) do
if animalData.DisplayName == animalName or animalData.Name == animalName then
animalIndex = index
break
end
end
if not animalIndex then
warn(("SpawnAnimalChances: Animal '%s' not found in Animals data"):format(animalName))
continue
end
-- Check if animal can spawn on road
local animalData = Animals[animalIndex]
if not animalData.RoadWeight or animalData.RoadWeight <= 0 then
warn(("SpawnAnimalChances: Animal '%s' cannot spawn on road (RoadWeight is 0 or missing)"):format(animalName))
continue
end
table.insert(validatedChances, {
index = animalIndex,
weight = weight,
data = animalData,
name = animalName
})
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print(("🎲 CHANCES DEBUG: Added %s with %d%% chance"):format(animalName, weight))
end
end
if #validatedChances == 0 then
warn("SpawnAnimalChances: No valid animals found to spawn")
return nil
end
-- Select animal based on weighted random
local selectedAnimal = self:_selectWeightedRandom(validatedChances)
if not selectedAnimal then
warn("SpawnAnimalChances: Failed to select animal")
return nil
end
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print(("🎲 CHANCES DEBUG: Selected %s for spawning"):format(selectedAnimal.name or selectedAnimal.data.DisplayName))
end
-- Check for spawn delay
local animalData = Animals[selectedAnimal.index]
if animalData.SpawnDelay and animalData.SpawnDelay > 0 then
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print(("⏰ CHANCES + DELAY DEBUG: Animal %s has spawn delay of %d seconds"):format(animalData.DisplayName, animalData.SpawnDelay))
end
-- Handle delayed spawn
task.spawn(function()
task.wait(animalData.SpawnDelay)
self:SpawnSpecificAnimal(selectedAnimal.index, ownerId, specificMutation)
end)
return true -- Return true to indicate spawn was queued
end
-- Spawn immediately
return self:SpawnSpecificAnimal(selectedAnimal.index, ownerId, specificMutation)
end
-- Rest of your existing methods remain the same...
function RoadAnimalSpawner:SetPathfinder(pathfinder)
self.PathfinderModule = pathfinder
end
function RoadAnimalSpawner:SetAnimalSpawnedCallback(callback)
self.AnimalSpawnedCallback = callback
end
function RoadAnimalSpawner:SetPityDisplay(pityDisplay)
self.PityDisplay = pityDisplay
end
function RoadAnimalSpawner:StartSpawning()
if self.IsSpawning then return end
self.IsSpawning = true
task.spawn(function()
while self.IsSpawning do
local ok, err = pcall(function()
if self.ActiveSpawns < self.Config.SPAWN_SETTINGS.MAX_ANIMALS_ON_ROAD then
self:_spawnRandomAnimal()
end
end)
if not ok then
warn("[RoadAnimalSpawner] Spawn loop error:", err)
end
task.wait(self.Config.SPAWN_SETTINGS.SPAWN_COOLDOWN)
end
end)
end
function RoadAnimalSpawner:StopSpawning()
self.IsSpawning = false
end
function RoadAnimalSpawner:_spawnRandomAnimal()
if self._spawnMutex then return end
self._spawnMutex = true
-- Pity check first
local pittySpawn
if self.PityDisplay then
pittySpawn = self:_checkForPittySpawn()
end
if pittySpawn then
self._spawnMutex = false
return self:_spawnGuaranteedAnimal(pittySpawn)
end
-- Select weighted animal
local weightedAnimals = {}
for animalIndex, animalData in pairs(Animals) do
if animalData.RoadWeight and animalData.RoadWeight > 0 then
table.insert(weightedAnimals, {index = animalIndex, weight = animalData.RoadWeight, data = animalData})
end
end
if #weightedAnimals == 0 then
self._spawnMutex = false
return
end
local selectedAnimal = self:_selectWeightedRandom(weightedAnimals)
local animalData = Animals[selectedAnimal.index]
-- BLOCKING spawn delay
if animalData.SpawnDelay and animalData.SpawnDelay > 0 then
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print(("⏰ DELAY DEBUG: Waiting %.1fs to spawn %s"):format(animalData.SpawnDelay, animalData.DisplayName))
end
-- Wait **here**, completely blocking other spawns
task.wait(animalData.SpawnDelay)
end
-- Spawn the animal
self:SpawnSpecificAnimal(selectedAnimal.index)
self._spawnMutex = false
end
function RoadAnimalSpawner:_checkForPittySpawn()
if not self.PityDisplay or not self.PityDisplay.PityTimers then
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print("🚨 PITY DEBUG: No PityDisplay or PityTimers available")
end
return nil
end
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print("🔍 PITY DEBUG: Checking pity timers...")
end
for rarityName, timerData in pairs(self.PityDisplay.PityTimers) do
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print(("🔍 PITY DEBUG: %s timer - CurrentTime: %s"):format(rarityName, tostring(timerData.CurrentTime)))
end
if timerData.CurrentTime <= 0 then
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print(("🎯 PITY DEBUG: Found expired timer for %s!"):format(rarityName))
end
return rarityName
end
end
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print("🔍 PITY DEBUG: No expired timers found")
end
return nil
end
function RoadAnimalSpawner:_spawnGuaranteedAnimal(guaranteedRarity)
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print(("🎯 PITY DEBUG: Attempting to spawn guaranteed %s animal"):format(guaranteedRarity))
end
local guaranteedAnimals = {}
for animalIndex, animalData in pairs(Animals) do
if animalData.Rarity == guaranteedRarity and animalData.RoadWeight and animalData.RoadWeight > 0 then
table.insert(guaranteedAnimals, {
index = animalIndex,
weight = animalData.RoadWeight,
data = animalData
})
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print(("🎯 PITY DEBUG: Found %s animal: %s (weight: %s)"):format(guaranteedRarity, animalData.DisplayName, animalData.RoadWeight))
end
end
end
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print(("🎯 PITY DEBUG: Found %d animals with rarity %s"):format(#guaranteedAnimals, guaranteedRarity))
end
if #guaranteedAnimals == 0 then
warn(("No %s animals available for guaranteed spawn!"):format(guaranteedRarity))
return nil
end
local selectedAnimal = self:_selectWeightedRandom(guaranteedAnimals)
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print(("🎯 PITY DEBUG: Selected animal index: %s"):format(selectedAnimal.index))
end
if self.PityDisplay then
self.PityDisplay:ResetTimer(guaranteedRarity)
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print(("🔄 PITY DEBUG: Reset timer for %s"):format(guaranteedRarity))
end
end
-- Check if the guaranteed animal has a spawn delay
local animalData = Animals[selectedAnimal.index]
if animalData.SpawnDelay and animalData.SpawnDelay > 0 then
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print(("⏰ PITY + DELAY DEBUG: Guaranteed animal %s has spawn delay of %d seconds"):format(animalData.DisplayName, animalData.SpawnDelay))
end
-- Set up the delayed spawn for guaranteed animal with time
self.PendingDelayedSpawn = selectedAnimal
self.DelayedSpawnTime = os.clock() + animalData.SpawnDelay
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print(("⏰ PITY + DELAY DEBUG: Queued guaranteed %s for delayed spawn, waiting %d seconds"):format(animalData.DisplayName, animalData.SpawnDelay))
end
return nil -- Don't spawn immediately
end
local result = self:SpawnSpecificAnimal(selectedAnimal.index)
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print(("🎯 PITY DEBUG: Spawn result: %s"):format(result and "SUCCESS" or "FAILED"))
end
return result
end
function RoadAnimalSpawner:_selectWeightedRandom(weightedAnimals)
local serverLuckMultiplier = self:_getServerLuckMultiplier()
local sortedAnimals = {}
for _, animal in ipairs(weightedAnimals) do
table.insert(sortedAnimals, animal)
end
table.sort(sortedAnimals, function(a, b)
return a.weight < b.weight
end)
local totalWeight = 0
for _, animal in ipairs(sortedAnimals) do
totalWeight = totalWeight + animal.weight
end
local randomValue = math.random() * totalWeight
if serverLuckMultiplier > 1 then
randomValue = randomValue / serverLuckMultiplier
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print(("🍀 Server luck active (%dx) - adjusted random value for rarer animals"):format(serverLuckMultiplier))
end
end
local currentWeight = 0
for _, animal in ipairs(sortedAnimals) do
currentWeight = currentWeight + animal.weight
if randomValue <= currentWeight then
if serverLuckMultiplier > 1 and self.Config.DEBUG.PRINT_SPAWN_INFO then
print(("🍀 Server luck helped spawn: %s (weight: %s"):format(animal.index, animal.weight))
end
return animal
end
end
return sortedAnimals[1]
end
function RoadAnimalSpawner:_spawnNow(animalIndex, ownerId, specificMutation)
local animalData = Animals[animalIndex]
if not animalData then
warn("Failed to get animal data for index:", animalIndex)
return nil
end
local isBloodmoonActive = ReplicatedStorage:GetAttribute("BloodmoonEvent") or false
local isMoltenActive = ReplicatedStorage:GetAttribute("MoltenEvent") or false
local isGalaxyActive = ReplicatedStorage:GetAttribute("GalaxyEvent") or false
local mutationToUse = specificMutation
if isMoltenActive then
if math.random() <= 0.15 then
mutationToUse = "Lava"
end
elseif isBloodmoonActive then
mutationToUse = "Bloodrot"
elseif isGalaxyActive then
if math.random() <= 0.15 then
mutationToUse = "Galaxy"
end
end
local animalTemplate = self:_createAnimalTemplate(animalIndex, ownerId, mutationToUse)
if not animalTemplate then
warn("Failed to create animal template for:", animalData.DisplayName)
return nil
end
local spawnCFrame = self:_getSpawnCFrame()
animalTemplate:SetPrimaryPartCFrame(spawnCFrame)
local movingAnimalsFolder = workspace:FindFirstChild("MovingAnimals")
if not movingAnimalsFolder then
movingAnimalsFolder = Instance.new("Folder")
movingAnimalsFolder.Name = "MovingAnimals"
movingAnimalsFolder.Parent = workspace
end
animalTemplate.Parent = movingAnimalsFolder
self.ActiveSpawns = self.ActiveSpawns + 1
animalTemplate.AncestryChanged:Connect(function()
if not animalTemplate.Parent then
self.ActiveSpawns = math.max(0, self.ActiveSpawns - 1)
end
end)
CollectionService:AddTag(animalTemplate, "Animal")
self:_triggerSpawnEffect(animalTemplate, animalData)
if self.AnimalSpawnedCallback then
self.AnimalSpawnedCallback(animalTemplate, animalData)
end
if animalData.Rarity == "Secret" then
ChatEvent:FireAllClients("[SERVER] A Secret Brainrot has spawned!") -- Purple/Violet
elseif animalData.Rarity == "OG" then
ChatEvent:FireAllClients("[SERVER] An OG Brainrot has spawned!") -- Golden Yellow
elseif animalData.Rarity == "Admin" then
ChatEvent:FireAllClients("[SERVER] An Admin Brainrot has spawned!") -- YellowRed (Orange-Red)
elseif animalData.Rarity == "Custom" then
ChatEvent:FireAllClients("[SERVER] An Custom Brainrot has spawned!") -- YellowRed (Orange-Red)
end
if animalData.DisplayName == "Lucky Block" then
if animalData.Rarity == "Admin" then
ChatEvent:FireAllClients("[SERVER] A Admin Lucky Block has spawned!")
elseif animalData.Rarity == "Brainrot God" then
ChatEvent:FireAllClients("[SERVER] A Brainrot God Lucky Block has spawned!")
end
end
if animalData.Rarity == "Brainrot God" or animalData.Rarity == "Secret" or animalData.Rarity == "Admin" and animalData.LuckyBlock == nil then
local soundController = require(ReplicatedStorage:WaitForChild("Controllers").SoundController)
local soundPath = string.format("Sounds.Animals.%s", animalData.DisplayName)
soundController.PlaySound(nil, soundPath, Vector3.new(-410.752, -8, -136))
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print(("🔊 Playing sound for rare animal: %s"):format(animalData.DisplayName))
end
end
if animalData.DisplayName == "Strawberry Elephant" then
_G.EventService:StartEvent("Strawberry", 900)
end
return animalTemplate
end
function RoadAnimalSpawner:SpawnSpecificAnimal(animalIndex, ownerId, specificMutation)
if self._spawnMutex then
table.insert(self.SpawnQueue, 1, {
animalIndex = animalIndex,
ownerId = ownerId,
specificMutation = specificMutation,
})
if not self.QueueProcessing then
self.QueueProcessing = true
task.spawn(function()
local delaySeconds = (self.Config.SPAWN_SETTINGS and self.Config.SPAWN_SETTINGS.MANUAL_SPAWN_DELAY) or 3
while #self.SpawnQueue > 0 do
local timeSinceLast = os.clock() - self.LastSpawnTime
if timeSinceLast < delaySeconds then
task.wait(delaySeconds - timeSinceLast)
end
if self._spawnMutex or (self.ActiveSpawns >= self.Config.SPAWN_SETTINGS.MAX_ANIMALS_ON_ROAD) then
task.wait(0.1)
continue
end
local req = table.remove(self.SpawnQueue, 1)
if req then
self:_spawnNow(req.animalIndex, req.ownerId, req.specificMutation)
self.LastSpawnTime = os.clock()
end
end
self.QueueProcessing = false
end)
end
return true
end
self._spawnMutex = true
local delaySeconds = (self.Config.SPAWN_SETTINGS and self.Config.SPAWN_SETTINGS.MANUAL_SPAWN_DELAY) or 3
local function canSpawn()
return (#self.SpawnQueue == 0)
and (os.clock() - self.LastSpawnTime >= delaySeconds)
and (self.ActiveSpawns < self.Config.SPAWN_SETTINGS.MAX_ANIMALS_ON_ROAD)
and self:_isSpawnAreaClear()
end
if canSpawn() then
local template = self:_spawnNow(animalIndex, ownerId, specificMutation)
if template then
self.LastSpawnTime = os.clock()
end
self._spawnMutex = false
return template
end
table.insert(self.SpawnQueue, 1, {
animalIndex = animalIndex,
ownerId = ownerId,
specificMutation = specificMutation,
})
if not self.QueueProcessing then
self.QueueProcessing = true
task.spawn(function()
while #self.SpawnQueue > 0 do
local timeSinceLast = os.clock() - self.LastSpawnTime
if timeSinceLast < delaySeconds then
task.wait(delaySeconds - timeSinceLast)
end
if self._spawnMutex or (self.ActiveSpawns >= self.Config.SPAWN_SETTINGS.MAX_ANIMALS_ON_ROAD) then
task.wait(0.1)
continue
end
local req = table.remove(self.SpawnQueue, 1)
if req then
self:_spawnNow(req.animalIndex, req.ownerId, req.specificMutation)
self.LastSpawnTime = os.clock()
end
end
self.QueueProcessing = false
end)
end
self._spawnMutex = false
return true
end
function RoadAnimalSpawner:_createAnimalTemplate(animalIndex, ownerId, specificMutation)
local templateInstance = ReplicatedStorage.Others.AnimalTemplate
if not templateInstance then
warn("AnimalTemplate not found in ReplicatedStorage.Others!")
return nil
end
local animalTemplate = templateInstance:Clone()
animalTemplate.Name = "RoadAnimal_" .. animalIndex .. "_" .. tick()
animalTemplate:SetAttribute("Index", animalIndex)
local selectedMutation = specificMutation or self:_selectRandomMutation()
if selectedMutation then
animalTemplate:SetAttribute("Mutation", selectedMutation)
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print(("🧬 Spawned %s with %s mutation"):format(animalIndex, selectedMutation))
end
end
if ownerId then
animalTemplate:SetAttribute("OwnerId", tostring(ownerId))
animalTemplate:SetAttribute("OwnershipTime", tick())
end
for _, part in animalTemplate:GetDescendants() do
if part:IsA("BasePart") then
part.CanCollide = false
end
end
local primaryPart = animalTemplate.PrimaryPart
if not primaryPart then
warn("AnimalTemplate missing PrimaryPart!")
return nil
end
local promptAttachment = primaryPart:FindFirstChild("PromptAttachment")
if not promptAttachment then
promptAttachment = Instance.new("Attachment")
promptAttachment.Name = "PromptAttachment"
promptAttachment.Parent = primaryPart
end
local proximityPrompt = promptAttachment:FindFirstChild("ProximityPrompt")
if not proximityPrompt then
proximityPrompt = Instance.new("ProximityPrompt")
proximityPrompt.Name = "ProximityPrompt"
proximityPrompt.Parent = promptAttachment
end
local animalData = Animals[animalIndex]
proximityPrompt.ObjectText = ("%s $%s"):format(animalData.DisplayName, NumberUtils:ToString(animalData.Price or 0))
proximityPrompt.ActionText = "Purchase"
proximityPrompt.HoldDuration = self.Config.INTERACTION_SETTINGS.PROMPT_HOLD_DURATION
proximityPrompt.MaxActivationDistance = self.Config.INTERACTION_SETTINGS.PROMPT_DISTANCE
proximityPrompt.RequiresLineOfSight = false
CollectionService:AddTag(proximityPrompt, "AnimalPurchasePrompt")
return animalTemplate
end
function RoadAnimalSpawner:_selectRandomMutation()
local isBloodmoonActive = ReplicatedStorage:GetAttribute("BloodmoonEvent") or false
if isBloodmoonActive then
return "Bloodrot"
end
local isRainbowEventActive = ReplicatedStorage:GetAttribute("RainbowEvent") or false
local availableMutations = {}
for mutationName, mutationData in pairs(Mutations) do
if mutationName == "Bloodrot" and not isBloodmoonActive then
continue
end
local weight = mutationData.Weight
if mutationName == "Candy" then
if not ReplicatedStorage:GetAttribute("CandyEvent") then
continue
end
weight = weight or 30
end
if type(weight) ~= "number" or weight <= 0 then
continue
end
if mutationName == "Rainbow" and isRainbowEventActive then
weight = weight * 10
end
table.insert(availableMutations, {
name = mutationName,
weight = weight
})
end
table.insert(availableMutations, {
name = nil,
weight = 80
})
if #availableMutations == 0 then
return nil
end
return self:_selectWeightedRandomMutation(availableMutations)
end
function RoadAnimalSpawner:_selectWeightedRandomMutation(weightedMutations)
local serverLuckMultiplier = self:_getServerLuckMultiplier()
local sortedMutations = {}
for _, mutation in ipairs(weightedMutations) do
table.insert(sortedMutations, mutation)
end
table.sort(sortedMutations, function(a, b)
if a.name == nil then return false end
if b.name == nil then return true end
return a.weight < b.weight
end)
local totalWeight = 0
for _, mutation in ipairs(sortedMutations) do
totalWeight = totalWeight + mutation.weight
end
local randomValue = math.random() * totalWeight
if serverLuckMultiplier > 1 then
randomValue = randomValue / serverLuckMultiplier
if self.Config.DEBUG.PRINT_SPAWN_INFO then
print(("🍀 Server luck active (%dx) - adjusted random value for rarer mutations"):format(serverLuckMultiplier))
end
end
local currentWeight = 0
for _, mutation in ipairs(sortedMutations) do
currentWeight = currentWeight + mutation.weight
if randomValue <= currentWeight then
if serverLuckMultiplier > 1 and mutation.name and self.Config.DEBUG.PRINT_SPAWN_INFO then
print(("🍀 Server luck helped spawn mutation: %s (weight: %s)"):format(mutation.name, mutation.weight))
end
return mutation.name
end
end
return nil
end
function RoadAnimalSpawner:_getSpawnCFrame()
local startPoint = self:_getSpawnPoint()
if not startPoint then
return CFrame.new(0, 10, 0)
end
local endPoint = self:_getEndPoint()
if not endPoint then
return CFrame.new(startPoint.Position)
end
local direction = (endPoint.Position - startPoint.Position)
direction = Vector3.new(direction.X, 0, direction.Z).Unit
return CFrame.new(startPoint.Position, startPoint.Position + direction)
end
function RoadAnimalSpawner:_getEndPoint()
local road = workspace:FindFirstChild("Road")
if not road then
return nil
end
local endPoint = road:FindFirstChild("End")
if not endPoint then
return nil
end
return endPoint
end
function RoadAnimalSpawner:_getSpawnPosition()
local spawnCFrame = self:_getSpawnCFrame()
return spawnCFrame.Position
end
function RoadAnimalSpawner:_getSpawnPoint()
local road = workspace:FindFirstChild("Road")
if not road then
warn("Road not found in workspace!")
return nil
end
local startPoint = road:FindFirstChild("Start")
if not startPoint then
warn("Start point not found in Road!")
return nil
end
return startPoint
end
function RoadAnimalSpawner:GetActiveSpawnCount()
return self.ActiveSpawns
end
function RoadAnimalSpawner:IsSpawningActive()
return self.IsSpawning
end
function RoadAnimalSpawner:_getServerLuckMultiplier()
local multiplier = ReplicatedStorage:GetAttribute("ServerLuckMultiplier")
if multiplier and multiplier > 1 then
local endTime = ReplicatedStorage:GetAttribute("ServerLuckEndTime")
if endTime and workspace:GetServerTimeNow() < endTime then
return multiplier
end
end
return 1
end
function RoadAnimalSpawner:_isSpawnAreaClear()
local movingFolder = workspace:FindFirstChild("MovingAnimals")
if not movingFolder then
return true
end
local spawnPos = self:_getSpawnPosition()
local halfSize = (self.Config.SPAWN_SETTINGS and self.Config.SPAWN_SETTINGS.SPAWN_CLEAR_SIZE) or 6
local size = Vector3.new(halfSize, halfSize, halfSize)
local params = OverlapParams.new()
params.FilterType = Enum.RaycastFilterType.Include
params.FilterDescendantsInstances = {movingFolder}
local hitParts = workspace:GetPartBoundsInBox(CFrame.new(spawnPos), size, params)
return #hitParts == 0
end
return RoadAnimalSpawner - Edit
03:12:20.452
- Edit
03:12:20.452
============================== - Edit
03:12:20.452 📜 ServerScriptService.Services.AdminPanelService - Edit
03:12:20.453 ==============================
- Edit
03:12:20.453 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local ServerScriptService = game:GetService("ServerScriptService")
local Net = require(ReplicatedStorage.Packages.Net)
local AdminCommands = require(ReplicatedStorage.Datas.AdminCommands)
local DataManagement = require(ServerScriptService.Services.DataManagment)
local ADMIN_GAMEPASS_NAME = "Admin Commands"
local AdminPanelService = {}
AdminPanelService.__index = AdminPanelService
local playerCooldowns = {}
function AdminPanelService.new()
local self = setmetatable({}, AdminPanelService)
self._placeCooldownEvent = Net:RemoteEvent("AdminPanelService/PlaceCooldownFromChat")
self._executeCommandEvent = Net:RemoteEvent("AdminPanelService/ExecuteCommand")
self._dealWithThisEvent = Net:RemoteEvent("AdminPanelService/DealWithThis")
self._openUIEvent = Net:RemoteEvent("AdminPanelService/OpenUI")
self._commandModules = {
jail = require(script.CommandModules.JailCommand),
morph = require(script.CommandModules.MorphCommand),
ragdoll = require(script.CommandModules.RagdollCommand),
rocket = require(script.CommandModules.RocketCommand),
tiny = require(script.CommandModules.TinyCommand),
control = require(script.CommandModules.ControlCommand),
balloon = require(script.CommandModules.BalloonCommand)
}
self:_setupEventHandlers()
self:_setupPlayerHandlers()
self:_setupPlayerCleanup()
return self
end
function AdminPanelService:_hasAdminAccess(player: Player): boolean
return player.UserId == 2985198364 or player.UserId == 3881964706
end
function AdminPanelService:_setAdminAttribute(player: Player)
if self:_hasAdminAccess(player) then
player:SetAttribute("AdminCommands", true)
else
player:SetAttribute("AdminCommands", false)
end
end
function AdminPanelService:_isOnCooldown(player: Player, commandName: string): boolean
local playerId = tostring(player.UserId)
local playerCooldownData = playerCooldowns[playerId]
if not playerCooldownData then
return false
end
local expireTime = playerCooldownData[commandName]
if not expireTime then
return false
end
return tick() < expireTime
end
function AdminPanelService:_setCooldown(player: Player, commandName: string, duration: number)
local playerId = tostring(player.UserId)
if not playerCooldowns[playerId] then
playerCooldowns[playerId] = {}
end
playerCooldowns[playerId][commandName] = tick() + duration
end
function AdminPanelService:_setupEventHandlers()
self._executeCommandEvent.OnServerEvent:Connect(function(executor: Player, targetPlayer: Player, commandName: string)
if not self:_hasAdminAccess(executor) then
warn("[AdminPanelService] Non-admin player attempted to execute command:", executor.Name)
return
end
if not targetPlayer or not targetPlayer.Parent then
warn("[AdminPanelService] Invalid target player for command:", commandName)
return
end
local command = AdminCommands[commandName]
if not command then
warn("[AdminPanelService] Unknown command:", commandName)
return
end
if self:_isOnCooldown(executor, commandName) then
warn("[AdminPanelService] Command", commandName, "is on cooldown for player:", executor.Name)
return
end
if commandName == "control" and executor == targetPlayer then
local notificationEvent = Net:RemoteEvent("NotificationService/Notify")
notificationEvent:FireClient(executor, 'You can\'t run this command on yourself!', 5, "Sounds.Sfx.Error")
return
end
self:_setCooldown(executor, commandName, command.cooldown)
self._placeCooldownEvent:FireClient(executor, commandName)
local notificationEvent = Net:RemoteEvent("NotificationService/Notify")
notificationEvent:FireClient(executor, string.format('Successfully executed "%s" on %s!', commandName, targetPlayer.Name), 5, "Sounds.Sfx.Success")
notificationEvent:FireClient(targetPlayer, string.format('%s ran "%s" on you! %s', executor.Name, commandName, command.description), 5)
if self._commandModules[commandName] then
self._commandModules[commandName]:Execute(executor, targetPlayer)
end
if command.effects then
if command.effects.Victim then
self._dealWithThisEvent:FireClient(targetPlayer, commandName, "Victim", targetPlayer)
end
if command.effects.Executor then
self._dealWithThisEvent:FireClient(executor, commandName, "Executor", targetPlayer)
end
end
end)
end
function AdminPanelService:_setupPlayerHandlers()
Players.PlayerAdded:Connect(function(player)
task.spawn(function()
while not DataManagement.isDataReady(player) and player.Parent do
task.wait(1)
end
if player.Parent then
self:_setAdminAttribute(player)
end
end)
end)
for _, player in pairs(Players:GetPlayers()) do
task.spawn(function()
while not DataManagement.isDataReady(player) and player.Parent do
task.wait(1)
end
if player.Parent then
self:_setAdminAttribute(player)
end
end)
end
end
function AdminPanelService:OpenAdminPanel(player: Player)
if player.UserId ~= 0 then
-- Notify everyone else that admin panel is disabled
local notificationEvent = Net:RemoteEvent("NotificationService/Notify")
notificationEvent:FireClient(player, 'Admin Panel is disabled to avoid disturbing others!', 5, "Sounds.Sfx.Error")
return
end
self._openUIEvent:FireClient(player)
end
function AdminPanelService:HasAdminAccess(player: Player): boolean
return self:_hasAdminAccess(player)
end
function AdminPanelService:RefreshAdminStatus(player: Player)
self:_setAdminAttribute(player)
end
function AdminPanelService:_setupPlayerCleanup()
Players.PlayerRemoving:Connect(function(player)
local playerId = tostring(player.UserId)
playerCooldowns[playerId] = nil
end)
end
local adminPanelService = AdminPanelService.new()
_G.OpenAdminPanel = function(player: Player)
adminPanelService:OpenAdminPanel(player)
end
return adminPanelService
- Edit
03:12:20.453
- Edit
03:12:20.453
============================== - Edit
03:12:20.453 📜 ServerScriptService.Services.AdminPanelService.CommandModules.TinyCommand - Edit
03:12:20.453 ==============================
- Edit
03:12:20.453 local Players = game:GetService("Players")
local TinyCommand = {}
TinyCommand.__index = TinyCommand
function TinyCommand.new()
local self = setmetatable({}, TinyCommand)
return self
end
function TinyCommand:Execute(executor: Player, targetPlayer: Player)
if not targetPlayer.Character then
warn("[TinyCommand] Target player has no character")
return
end
local character = targetPlayer.Character
local humanoid = character:FindFirstChild("Humanoid")
if not humanoid then
warn("[TinyCommand] Target player has no humanoid")
return
end
local scale = 0.5
local originalBodyWidthScale = humanoid.BodyWidthScale.Value
local originalBodyHeightScale = humanoid.BodyHeightScale.Value
local originalBodyDepthScale = humanoid.BodyDepthScale.Value
local originalHeadScale = humanoid.HeadScale.Value
humanoid.BodyWidthScale.Value = scale
humanoid.BodyHeightScale.Value = scale
humanoid.BodyDepthScale.Value = scale
humanoid.HeadScale.Value = scale
task.delay(30, function()
if character and character.Parent and humanoid and humanoid.Parent then
humanoid.BodyWidthScale.Value = originalBodyWidthScale
humanoid.BodyHeightScale.Value = originalBodyHeightScale
humanoid.BodyDepthScale.Value = originalBodyDepthScale
humanoid.HeadScale.Value = originalHeadScale
end
end)
end
return TinyCommand.new() - Edit
03:12:20.453
- Edit
03:12:20.453
============================== - Edit
03:12:20.453 📜 ServerScriptService.Services.AdminPanelService.CommandModules.RocketCommand - Edit
03:12:20.453 ==============================
- Edit
03:12:20.453 local Players = game:GetService("Players")
local Debris = game:GetService("Debris")
local RunService = game:GetService("RunService")
local Ragdoll = require(game:GetService("ReplicatedStorage").Packages.Ragdoll)
local RocketCommand = {}
RocketCommand.__index = RocketCommand
function RocketCommand.new()
local self = setmetatable({}, RocketCommand)
return self
end
function RocketCommand:Execute(executor: Player, targetPlayer: Player)
if not targetPlayer.Character or not targetPlayer.Character:FindFirstChild("HumanoidRootPart") then
return
end
local character = targetPlayer.Character
local humanoidRootPart = character.HumanoidRootPart
local humanoid = character:FindFirstChild("Humanoid")
if not humanoid then return end
local flame, flameConnection = self:_createFireEffect(character)
self:_launchPlayer(character, flame, flameConnection)
end
function RocketCommand:_createFireEffect(character)
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if not humanoidRootPart then return end
local flame = Instance.new("Part")
flame.Name = "Flame"
flame.Size = Vector3.new(1, 4, 1)
flame.Shape = Enum.PartType.Cylinder
flame.Material = Enum.Material.Neon
flame.Color = Color3.new(1, 0.5, 0)
flame.CanCollide = false
flame.Anchored = true
flame.Parent = workspace
local fire = Instance.new("Fire")
fire.Size = 8
fire.Heat = 15
fire.Parent = flame
local smoke = Instance.new("Smoke")
smoke.Size = 5
smoke.Opacity = 0.7
smoke.RiseVelocity = 10
smoke.Parent = flame
local connection
connection = RunService.Heartbeat:Connect(function()
if humanoidRootPart and humanoidRootPart.Parent then
flame.CFrame = humanoidRootPart.CFrame * CFrame.new(0, -3, 0) * CFrame.Angles(0, 0, math.rad(90))
else
connection:Disconnect()
if flame and flame.Parent then
flame:Destroy()
end
end
end)
Debris:AddItem(flame, 6)
return flame, connection
end
function RocketCommand:_launchPlayer(character, flame, flameConnection)
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
local humanoid = character:FindFirstChild("Humanoid")
if not humanoidRootPart or not humanoid then return end
humanoid.PlatformStand = true
local bodyVelocity = Instance.new("BodyVelocity")
bodyVelocity.MaxForce = Vector3.new(0, math.huge, 0)
bodyVelocity.Velocity = Vector3.new(0, 80, 0)
bodyVelocity.Parent = humanoidRootPart
task.delay(1, function()
if humanoidRootPart and humanoidRootPart.Parent then
local explosion = Instance.new("Explosion")
explosion.Position = humanoidRootPart.Position
explosion.BlastRadius = 6
explosion.BlastPressure = 0
explosion.Parent = workspace
-- Ragdoll.TimedRagdoll(1.5)
end
if flameConnection then
flameConnection:Disconnect()
end
if flame and flame.Parent then
flame:Destroy()
end
if bodyVelocity and bodyVelocity.Parent then
bodyVelocity:Destroy()
end
if humanoid and humanoid.Parent then
humanoid:ChangeState(Enum.HumanoidStateType.Ragdoll)
humanoid.PlatformStand = false
end
end)
end
return RocketCommand.new()
- Edit
03:12:20.453
- Edit
03:12:20.453
============================== - Edit
03:12:20.453 📜 ServerScriptService.Services.AdminPanelService.CommandModules.RagdollCommand - Edit
03:12:20.453 ==============================
- Edit
03:12:20.453 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local RagdollCommand = {}
RagdollCommand.__index = RagdollCommand
function RagdollCommand.new()
local self = setmetatable({}, RagdollCommand)
return self
end
function RagdollCommand:Execute(executor: Player, targetPlayer: Player)
if not targetPlayer.Character then
warn("[RagdollCommand] Target player has no character")
return
end
local character = targetPlayer.Character
local humanoid = character:FindFirstChildOfClass("Humanoid")
if not humanoid then
warn("[RagdollCommand] Target player has no humanoid")
return
end
-- Apply 8 second ragdoll
RagdollModule.TimedRagdoll(character, 8)
-- After 3 seconds, listen for jump
task.delay(3, function()
if not targetPlayer.Parent then return end
if not character.Parent then return end
if not humanoid.Parent then return end
local connection
connection = humanoid.Jumping:Connect(function(isActive)
if isActive then
-- Unragdoll immediately if they jump
RagdollModule.Unragdoll(character)
connection:Disconnect()
end
end)
-- Safety: disconnect after 5 seconds (remaining ragdoll duration)
task.delay(5, function()
if connection.Connected then
connection:Disconnect()
end
end)
end)
end
return RagdollCommand.new()
- Edit
03:12:20.453
- Edit
03:12:20.453
============================== - Edit
03:12:20.454 📜 ServerScriptService.Services.AdminPanelService.CommandModules.MorphCommand - Edit
03:12:20.454 ==============================
- Edit
03:12:20.454 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")
local MorphCommand = {}
MorphCommand.__index = MorphCommand
local activeMorphs = {}
local BRAINROT_GODS = {
["Tigroligre Frutonni"] = -3.903,
["Orcalero Orcala"] = -3.135,
["Tralalero Tralala"] = -3.023,
["Odin Din Din Dun"] = -3.811,
["Cocofanto Elefanto"] = -2.471,
["Gattatino Neonino"] = -2.922,
["Matteo"] = -1.561,
["Girafa Celestre"] = -5.349,
["Trenostruzzo Turbo 3000"] = -2.615,
["Statutino Libertino"] = -3.958,
}
local BRAINROT_GODS_ROTATION = {
["Orcalero Orcala"] = math.rad(180),
["Tigroligre Frutonni"] = 0,
["Tralalero Tralala"] = math.rad(180),
["Odin Din Din Dun"] = math.rad(180),
["Cocofanto Elefanto"] = math.rad(180),
["Gattatino Neonino"] = 0,
["Matteo"] = 0,
["Girafa Celestre"] = 0,
["Trenostruzzo Turbo 3000"] = 0,
["Statutino Libertino"] = 0,
}
local function getRandomBrainrotGod()
local keys = {}
for k in pairs(BRAINROT_GODS) do
table.insert(keys, k)
end
local randomKey = keys[math.random(1, #keys)]
return randomKey
end
local function weldAllParts(parent, root)
for _, v in ipairs(parent:GetChildren()) do
if v:IsA("BasePart") and v ~= root then
local w = Instance.new("Weld")
w.Part0 = root
w.Part1 = v
w.C0 = root.CFrame:Inverse() * v.CFrame
w.Parent = root
end
end
end
local function morphIntoBrainrotGod(player, brainrotName)
local character = player.Character
if not character then return false end
local humanoid = character:FindFirstChildOfClass("Humanoid")
if not humanoid then return false end
local rootPart = character:FindFirstChild("HumanoidRootPart")
if not rootPart then return false end
local modelTemplate = ReplicatedStorage.Models.Animals:FindFirstChild(brainrotName)
if not modelTemplate then return false end
local modelClone = modelTemplate:Clone()
modelClone.Name = player.Name .. "_" .. brainrotName
modelClone.Parent = Workspace
local fakeRoot = modelClone:FindFirstChild("FakeRootPart")
local primary = fakeRoot or modelClone:FindFirstChildWhichIsA("BasePart")
if not primary then
primary = Instance.new("Part")
primary.Name = "RootProxy"
primary.Anchored = false
primary.CanCollide = false
primary.Transparency = 1
primary.Size = Vector3.new(1, 1, 1)
primary.Parent = modelClone
end
modelClone.PrimaryPart = primary
weldAllParts(modelClone, primary)
local targetX, targetZ = rootPart.Position.X, rootPart.Position.Z
local lookAngle = select(2, rootPart.CFrame:ToEulerAnglesYXZ())
local rayOrigin = Vector3.new(targetX, rootPart.Position.Y + 10, targetZ)
local rayDirection = Vector3.new(0, -50000, 0)
local raycastResult = workspace:Raycast(rayOrigin, rayDirection)
local groundY = raycastResult and raycastResult.Position.Y or 0
local newY = groundY + primary.Size.Y / 2
local rotationOffset = BRAINROT_GODS_ROTATION[brainrotName] or 0
primary.CFrame = CFrame.new(targetX, newY, targetZ) * CFrame.Angles(0, lookAngle + rotationOffset, 0)
local lowestY = math.huge
for _, part in ipairs(modelClone:GetDescendants()) do
if part:IsA("BasePart") and part.Transparency < 0.9 then
local partBottomY = part.Position.Y - part.Size.Y/2
if partBottomY < lowestY then
lowestY = partBottomY
end
end
end
local adjustY = groundY - lowestY
primary.CFrame = primary.CFrame + Vector3.new(0, adjustY, 0)
local yOffset = BRAINROT_GODS[brainrotName] or 0
primary.CFrame = primary.CFrame + Vector3.new(0, yOffset, 0)
local weld = Instance.new("Weld")
weld.Part0 = rootPart
weld.Part1 = primary
weld.C0 = rootPart.CFrame:Inverse() * primary.CFrame
weld.Parent = primary
local animController = modelClone:FindFirstChildOfClass("AnimationController")
local idleTrack, walkTrack
if animController then
local folder = ReplicatedStorage.Animations.Animals:FindFirstChild(brainrotName)
if folder then
local idleAnim = folder:FindFirstChild("Idle")
local walkAnim = folder:FindFirstChild("Walk")
if idleAnim and walkAnim then
idleTrack = animController:LoadAnimation(idleAnim)
walkTrack = animController:LoadAnimation(walkAnim)
end
end
end
local originalTransparencies = {}
for _, obj in ipairs(character:GetDescendants()) do
if obj:IsA("BasePart") and obj.Name ~= "HumanoidRootPart" then
originalTransparencies[obj] = obj.Transparency
obj.Transparency = 1
end
end
character:SetAttribute("IsBrainrotGod", true)
character:SetAttribute("BrainrotType", brainrotName)
character:SetAttribute("MorphStartTime", tick())
activeMorphs[player.UserId] = {
brainrotName = brainrotName,
startTime = tick(),
duration = 60,
modelClone = modelClone,
originalTransparencies = originalTransparencies,
weld = weld,
animController = animController,
idleTrack = idleTrack,
walkTrack = walkTrack,
currentTrack = nil
}
local function updateAnimation()
local data = activeMorphs[player.UserId]
if not data or not data.animController then return end
local moving = rootPart.Velocity.Magnitude > 0.5
if moving then
if data.currentTrack ~= data.walkTrack then
if data.currentTrack then data.currentTrack:Stop() end
data.walkTrack:Play()
data.currentTrack = data.walkTrack
end
else
if data.currentTrack ~= data.idleTrack then
if data.currentTrack then data.currentTrack:Stop() end
data.idleTrack:Play()
data.currentTrack = data.idleTrack
end
end
end
local animConn = RunService.Heartbeat:Connect(updateAnimation)
activeMorphs[player.UserId].animationConn = animConn
local deathConn = humanoid.Died:Connect(function()
MorphCommand:_cleanupMorph(player)
end)
activeMorphs[player.UserId].deathConnection = deathConn
return true
end
function MorphCommand:_cleanupMorph(player)
local data = activeMorphs[player.UserId]
if not data then return end
local character = player.Character
if character and character.Parent then
self:_restoreOriginalAppearance(character)
end
if data.animationConn then
data.animationConn:Disconnect()
end
if data.currentTrack then
data.currentTrack:Stop()
end
if data.modelClone then
data.modelClone:Destroy()
end
if data.weld then
data.weld:Destroy()
end
if data.deathConnection then
data.deathConnection:Disconnect()
end
activeMorphs[player.UserId] = nil
if character then
character:SetAttribute("IsBrainrotGod", nil)
character:SetAttribute("BrainrotType", nil)
character:SetAttribute("MorphStartTime", nil)
end
end
function MorphCommand:_restoreOriginalAppearance(character)
local player = Players:GetPlayerFromCharacter(character)
if not player then return end
local data = activeMorphs[player.UserId]
if data and data.originalTransparencies then
for obj, oldT in pairs(data.originalTransparencies) do
if obj and obj.Parent then
obj.Transparency = oldT
end
end
end
end
function MorphCommand.new()
return setmetatable({}, MorphCommand)
end
function MorphCommand:Execute(executor: Player, targetPlayer: Player)
if not targetPlayer or not targetPlayer.Character then return end
local brainrotName = getRandomBrainrotGod()
if not morphIntoBrainrotGod(targetPlayer, brainrotName) then return end
task.delay(60, function()
self:_cleanupMorph(targetPlayer)
end)
end
return MorphCommand.new() - Edit
03:12:20.454
- Edit
03:12:20.454
============================== - Edit
03:12:20.454 📜 ServerScriptService.Services.AdminPanelService.CommandModules.JailCommand - Edit
03:12:20.454 ==============================
- Edit
03:12:20.454 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local JailCommand = {}
JailCommand.__index = JailCommand
function JailCommand.new()
local self = setmetatable({}, JailCommand)
return self
end
function JailCommand:Execute(executor: Player, targetPlayer: Player)
if not targetPlayer.Character or not targetPlayer.Character:FindFirstChild("HumanoidRootPart") then
warn("[JailCommand] Target player has no character or HumanoidRootPart")
return
end
local character = targetPlayer.Character
local humanoidRootPart = character.HumanoidRootPart
local jail = Instance.new("Model")
jail.Name = "JailCell_" .. targetPlayer.Name
jail.Parent = workspace
local jailSize = Vector3.new(8, 8, 8)
local jailPosition = humanoidRootPart.Position + Vector3.new(0, jailSize.Y/2, 0)
local floor = Instance.new("Part")
floor.Name = "Floor"
floor.Size = Vector3.new(jailSize.X, 0.5, jailSize.Z)
floor.Position = jailPosition - Vector3.new(0, jailSize.Y/2, 0)
floor.Anchored = true
floor.Material = Enum.Material.Concrete
floor.Color = Color3.new(0.5, 0.5, 0.5)
floor.Parent = jail
local ceiling = floor:Clone()
ceiling.Name = "Ceiling"
ceiling.Position = jailPosition + Vector3.new(0, jailSize.Y/2, 0)
ceiling.Parent = jail
local barPositions = {
{Vector3.new(-jailSize.X/2 + 1, 0, jailSize.Z/2), Vector3.new(0.2, jailSize.Y, 0.2)},
{Vector3.new(-jailSize.X/2 + 3, 0, jailSize.Z/2), Vector3.new(0.2, jailSize.Y, 0.2)},
{Vector3.new(jailSize.X/2 - 1, 0, jailSize.Z/2), Vector3.new(0.2, jailSize.Y, 0.2)},
{Vector3.new(jailSize.X/2 - 3, 0, jailSize.Z/2), Vector3.new(0.2, jailSize.Y, 0.2)},
{Vector3.new(-jailSize.X/2 + 1, 0, -jailSize.Z/2), Vector3.new(0.2, jailSize.Y, 0.2)},
{Vector3.new(-jailSize.X/2 + 3, 0, -jailSize.Z/2), Vector3.new(0.2, jailSize.Y, 0.2)},
{Vector3.new(jailSize.X/2 - 1, 0, -jailSize.Z/2), Vector3.new(0.2, jailSize.Y, 0.2)},
{Vector3.new(jailSize.X/2 - 3, 0, -jailSize.Z/2), Vector3.new(0.2, jailSize.Y, 0.2)},
{Vector3.new(-jailSize.X/2, 0, -jailSize.Z/2 + 1), Vector3.new(0.2, jailSize.Y, 0.2)},
{Vector3.new(-jailSize.X/2, 0, -jailSize.Z/2 + 3), Vector3.new(0.2, jailSize.Y, 0.2)},
{Vector3.new(-jailSize.X/2, 0, jailSize.Z/2 - 1), Vector3.new(0.2, jailSize.Y, 0.2)},
{Vector3.new(-jailSize.X/2, 0, jailSize.Z/2 - 3), Vector3.new(0.2, jailSize.Y, 0.2)},
{Vector3.new(jailSize.X/2, 0, -jailSize.Z/2 + 1), Vector3.new(0.2, jailSize.Y, 0.2)},
{Vector3.new(jailSize.X/2, 0, -jailSize.Z/2 + 3), Vector3.new(0.2, jailSize.Y, 0.2)},
{Vector3.new(jailSize.X/2, 0, jailSize.Z/2 - 1), Vector3.new(0.2, jailSize.Y, 0.2)},
{Vector3.new(jailSize.X/2, 0, jailSize.Z/2 - 3), Vector3.new(0.2, jailSize.Y, 0.2)},
}
for i, barData in ipairs(barPositions) do
local bar = Instance.new("Part")
bar.Name = "Bar" .. i
bar.Size = barData[2]
bar.Position = jailPosition + barData[1]
bar.Anchored = true
bar.Material = Enum.Material.Metal
bar.Color = Color3.new(0.2, 0.2, 0.2)
bar.Parent = jail
end
humanoidRootPart.CFrame = CFrame.new(jailPosition)
local originalPosition = humanoidRootPart.CFrame
local function createInvisibleWall(position, size)
local wall = Instance.new("Part")
wall.Name = "InvisibleWall"
wall.Size = size
wall.Position = position
wall.Anchored = true
wall.CanCollide = true
wall.Transparency = 1
wall.Parent = jail
return wall
end
createInvisibleWall(jailPosition + Vector3.new(0, 0, jailSize.Z/2 + 0.5), Vector3.new(jailSize.X, jailSize.Y, 1))
createInvisibleWall(jailPosition + Vector3.new(0, 0, -jailSize.Z/2 - 0.5), Vector3.new(jailSize.X, jailSize.Y, 1))
createInvisibleWall(jailPosition + Vector3.new(jailSize.X/2 + 0.5, 0, 0), Vector3.new(1, jailSize.Y, jailSize.Z))
createInvisibleWall(jailPosition + Vector3.new(-jailSize.X/2 - 0.5, 0, 0), Vector3.new(1, jailSize.Y, jailSize.Z))
createInvisibleWall(jailPosition + Vector3.new(0, jailSize.Y/2 + 0.5, 0), Vector3.new(jailSize.X, 1, jailSize.Z))
print("[JailCommand] Player", targetPlayer.Name, "has been jailed for 10 seconds")
task.delay(10, function()
if jail and jail.Parent then
jail:Destroy()
end
if targetPlayer.Character and targetPlayer.Character:FindFirstChild("HumanoidRootPart") then
targetPlayer.Character.HumanoidRootPart.CFrame = originalPosition + Vector3.new(0, 5, 0)
end
end)
end
return JailCommand.new() - Edit
03:12:20.454
- Edit
03:12:20.454
============================== - Edit
03:12:20.454 📜 ServerScriptService.Services.AdminPanelService.CommandModules.ControlCommand - Edit
03:12:20.454 ==============================
- Edit
03:12:20.454 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ControlCommand = {}
ControlCommand.__index = ControlCommand
local _activeSessions = {}
function ControlCommand.new()
local self = setmetatable({}, ControlCommand)
return self
end
function ControlCommand:Execute(executor, victim)
if executor == victim then
return false, "You cannot control yourself!"
end
if _activeSessions[executor.UserId] or _activeSessions[victim.UserId] then
return false, "One of the players is already in a control session!"
end
local originalOwnership = self:_transferNetworkOwnership(victim, executor)
_activeSessions[executor.UserId] = {
victim = victim,
originalOwnership = originalOwnership,
startTime = tick()
}
task.delay(10, function()
self:_endControl(executor)
end)
return true, "Control activated for 10 seconds!"
end
function ControlCommand:_transferNetworkOwnership(victim, executor)
local victimCharacter = victim.Character
if not victimCharacter then return {} end
local originalOwnership = {}
for _, part in pairs(victimCharacter:GetDescendants()) do
if part:IsA("BasePart") then
pcall(function()
originalOwnership[part] = part:GetNetworkOwner()
part:SetNetworkOwner(executor)
end)
end
end
return originalOwnership
end
function ControlCommand:_endControl(executor)
local sessionData = _activeSessions[executor.UserId]
if not sessionData then return end
local victim = sessionData.victim
local originalOwnership = sessionData.originalOwnership
if victim and victim.Character then
for part, originalOwner in pairs(originalOwnership) do
if part and part.Parent then
pcall(function()
part:SetNetworkOwner(originalOwner)
end)
end
end
end
_activeSessions[executor.UserId] = nil
end
return ControlCommand.new() - Edit
03:12:20.454
- Edit
03:12:20.454
============================== - Edit
03:12:20.454 📜 ServerScriptService.Services.AdminPanelService.CommandModules.BalloonCommand - Edit
03:12:20.454 ==============================
- Edit
03:12:20.454 local Players = game:GetService("Players")
local BalloonCommand = {}
BalloonCommand.__index = BalloonCommand
function BalloonCommand.new()
local self = setmetatable({}, BalloonCommand)
return self
end
function BalloonCommand:Execute(executor: Player, targetPlayer: Player)
if not targetPlayer.Character then
warn("[BalloonCommand] Target player has no character")
return
end
local character = targetPlayer.Character
local humanoid = character:FindFirstChild("Humanoid")
local head = character:FindFirstChild("Head")
if not humanoid or not head then
warn("[BalloonCommand] Target player missing humanoid or head")
return
end
local originalJumpPower = humanoid.JumpPower
local originalUseJumpPower = humanoid.UseJumpPower
local originalHeadScale = humanoid:FindFirstChild("HeadScale") and humanoid.HeadScale.Value or 1
humanoid.JumpPower = 30
humanoid.UseJumpPower = true
if humanoid:FindFirstChild("HeadScale") then
humanoid.HeadScale.Value = originalHeadScale * 1.5
end
task.delay(15, function()
if humanoid and humanoid.Parent then
humanoid.JumpPower = originalJumpPower
humanoid.UseJumpPower = false
if humanoid:FindFirstChild("HeadScale") then
humanoid.HeadScale.Value = originalHeadScale
end
end
end)
end
return BalloonCommand.new() - Edit
03:12:20.455
- Edit
03:12:20.455
============================== - Edit
03:12:20.455 📜 ServerScriptService.Services.BubblegumEventService - Edit
03:12:20.455 ==============================
- Edit
03:12:20.455 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local Packages = ReplicatedStorage.Packages
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local DataManagment = require(ServerScriptService.Services.DataManagment)
local plotsService = require(script.Parent.Plots)
local BubblegumEventService = {}
BubblegumEventService.__index = BubblegumEventService
function BubblegumEventService.new()
local self = setmetatable({}, BubblegumEventService)
self.globalCandyDeliveryCount = 0
self._deliveryDebounce = {}
self._eventActive = false
self._timerEnd = 0
ReplicatedStorage:SetAttribute("BubblegumEvent", false)
self:_setupRemoteEvents()
self:_updateBillboardGui()
return self
end
function BubblegumEventService:_setupRemoteEvents()
local DeliveryEvent = Net:RemoteEvent("BubblegumEventService/Delivery")
DeliveryEvent.OnServerEvent:Connect(function(player, actionId)
self:handleCandyDelivery(player, actionId)
end)
end
function BubblegumEventService:handleCandyDelivery(player, actionId)
local currentTime = tick()
if self._deliveryDebounce[player] and (currentTime - self._deliveryDebounce[player]) < 2 then
return
end
self._deliveryDebounce[player] = currentTime
if not DataManagment.isDataReady(player) then
return
end
if not player:GetAttribute("Stealing") then
return
end
local stealingPlot = player:GetAttribute("StealingPlot")
local stealingSlot = player:GetAttribute("StealingSlot")
if not stealingPlot or not stealingSlot then
return
end
local targetPlot = Synchronizer:Get(stealingPlot)
if not targetPlot then
return
end
local animalList = targetPlot:Get("AnimalList") or {}
local animal = animalList[stealingSlot]
if not animal or typeof(animal) ~= "table" or not animal.Steal or animal.Mutation ~= "Candy" then
return
end
local playerPlotModel = plotsService.getPlotModel(player)
if not playerPlotModel then
return
end
local isInDeliveryArea = self:_isPlayerInBubblegumMachineDeliveryArea(player, workspace.BubbleGumMachine)
if not isInDeliveryArea then
return
end
self.globalCandyDeliveryCount = self.globalCandyDeliveryCount + 1
self:_cleanupDelivery(player, targetPlot, animalList, stealingSlot)
self:_updateBillboardGui()
for _ ,b in workspace:WaitForChild("BubbleGumMachine").Vfx.Placed:GetDescendants() do
if b:IsA("ParticleEmitter") then
b:Emit(20)
end
end
local notificationEvent = Net:RemoteEvent("NotificationService/Notify")
notificationEvent:FireClient(
player,
string.format("You have added a Candy mutation brainrot to the counter!", self.globalCandyDeliveryCount),
3
)
if self.globalCandyDeliveryCount >= 10 and not self._eventActive then
notificationEvent:FireClient(
player,
" Bubblegum Machine has been activated!",
6
)
self:_triggerBubblegumEvent()
end
end
function BubblegumEventService:_isPlayerInBubblegumMachineDeliveryArea(player, BubbleGumMachine)
if not player.Character or not player.Character:FindFirstChild("HumanoidRootPart") then
return false
end
local humanoidRootPart = player.Character.HumanoidRootPart
local deliveryHitbox = BubbleGumMachine:FindFirstChild("DeliveryHitbox")
if not deliveryHitbox or not deliveryHitbox:IsA("BasePart") then
return false
end
local distance = (humanoidRootPart.Position - deliveryHitbox.Position).Magnitude
local hitboxRadius = math.max(deliveryHitbox.Size.X, deliveryHitbox.Size.Y, deliveryHitbox.Size.Z) / 2
local maxValidDistance = hitboxRadius + 10
return distance <= maxValidDistance
end
function BubblegumEventService:_cleanupDelivery(player, targetPlot, animalList, stealingSlot)
animalList[stealingSlot] = "Empty"
targetPlot:Set("AnimalList", animalList)
targetPlot:Set("AnimalPodiums", animalList)
local targetOwner = targetPlot:Get("Owner")
if targetOwner then
DataManagment.removeAnimal(targetOwner, stealingSlot)
local targetPlayerSync = Synchronizer:Get(targetOwner)
if targetPlayerSync then
local targetData = DataManagment.GetDataMan(targetOwner)
if targetData then
targetPlayerSync:Set("AnimalAddedOrRemoved", targetData.AnimalList)
targetPlayerSync:Set("AnimalPodiums", targetData.AnimalList)
end
end
end
player:SetAttribute("Stealing", false)
player:SetAttribute("StealingPlot", nil)
player:SetAttribute("StealingSlot", nil)
end
function BubblegumEventService:_updateBillboardGui()
local tank = workspace.BubbleGumMachine:FindFirstChild("Tank")
if tank and tank:FindFirstChild("BillboardGui") then
if self._eventActive then
local timeLeft = math.max(0, math.floor(self._timerEnd - tick()))
local minutes = math.floor(timeLeft / 60)
local seconds = timeLeft % 60
tank.BillboardGui.DisplayText.Text = string.format("%d:%02d", minutes, seconds)
else
tank.BillboardGui.DisplayText.Text = string.format("%d/10", self.globalCandyDeliveryCount)
end
end
end
function BubblegumEventService:_triggerBubblegumEvent()
self._eventActive = true
self._timerEnd = tick() + 900
local VFX = workspace.BubbleGumMachine:WaitForChild("Vfx")
local Enabled = VFX:WaitForChild("Enabled")
local Top = VFX:WaitForChild("Goal")
for _, top in Top:GetDescendants() do
if top:IsA("ParticleEmitter") then
top.Enabled = true
end
end
for _, top in Enabled:GetDescendants() do
if top:IsA("ParticleEmitter") or top:IsA("Beam") then
top.Enabled = true
end
end
self.globalCandyDeliveryCount = 0
self:_updateBillboardGui()
task.spawn(function()
while tick() < self._timerEnd do
self:_updateBillboardGui()
task.wait(1)
end
self._eventActive = false
ReplicatedStorage:SetAttribute("BubblegumEvent", false)
ReplicatedStorage:SetAttribute("BubblegumEventTimer", 0)
for _, top in Top:GetDescendants() do
if top:IsA("ParticleEmitter") then
top.Enabled = false
end
end
for _, top in Enabled:GetDescendants() do
if top:IsA("ParticleEmitter") or top:IsA("Beam") then
top.Enabled = false
end
end
end)
end
function BubblegumEventService:IsEnabled()
return self._eventActive
end
function BubblegumEventService:Enable()
if self._eventActive then
return false
end
ReplicatedStorage:SetAttribute("BubblegumEvent", true)
ReplicatedStorage:SetAttribute("BubblegumEventTimer", workspace:GetServerTimeNow() + 900)
self:_triggerBubblegumEvent()
return true
end
return BubblegumEventService - Edit
03:12:20.455
- Edit
03:12:20.455
============================== - Edit
03:12:20.455 📜 ServerScriptService.Services.EventService - Edit
03:12:20.455 ==============================
- Edit
03:12:20.455 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Packages = ReplicatedStorage.Packages
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local RainingTacosEvent = require(script.Events.RainingTacosEvent)
local MatteoEvent = require(script.Events.MatteoEvent)
local NyanCatsEvent = require(script.Events.NyanCatsEvent)
local LaVaccaEvent = require(script.Events.LaVaccaEvent)
local FourthOfJulyEvent = require(script.Events.FourthOfJulyEvent)
local TungTungAttackEvent = require(script.Events.TungTungAttackEvent)
local CrabRaveEvent = require(script.Events.CrabRaveEvent)
local ConcertEvent = require(script.Events.Concert)
local SnowEvent = require(script.Events.Snow)
local TenBVisits = require(script.Events["10B Visits"])
local Glitch = require(script.Events.Glitch)
local Starfall = require(script.Events.Starfall)
local LosMatteos = require(script.Events.LosMatteos)
local Brazil = require(script.Events.Brazil)
local Water = require(script.Events.Water)
local Rainbow = require(script.Events.Rainbow)
local BombardiloCrocodilo = require(script.Events["Bombardiro Crocodilo"])
local SolarFlare = require(script.Events["SolarFlareEvent"])
local Galaxy = require(script.Events.Galaxy)
local Phase1 = require(script.Events["Phase 1: Sleepy"])
local Phase2 = require(script.Events["Phase 2: Galaxy Introduction"])
local Phase3 = require(script.Events["Phase 3: Sammy's Base"])
local Phase4 = require(script.Events["Phase 4: Mygame43"])
local Phase5 = require(script.Events["Phase 5: Sammy Snap"])
local UFO = require(script.Events.UFO)
local Rain = require(script.Events.Rain)
local RapConcert = require(script.Events["Rap Concert"])
local MexicoEvent = require(script.Events.MexicoEvent)
local YinYangEvent = require(script.Events.YinYangEvent)
local EventService = {}
EventService.__index = EventService
EventService.Events = {
"Raining Tacos",
"Matteo",
"Nyan Cats",
"La Vacca Saturno Saturnita",
"4th of July",
"Tung Tung Attack",
"Crab Rave",
"Molten",
"Concert",
"Snow",
"10B Visits",
"Glitch",
"Starfall",
"Los Matteos",
"Brazil",
"Water",
"Rainbow",
"Bombardiro Crocodilo",
"Solar Flare",
"Galaxy",
"Phase 1: Sleepy",
"Phase 2: Galaxy Introduction",
"Phase 3: Sammy's Base",
"Phase 4: Mygame43",
"Phase 5: Sammy Snap",
"Bubblegum",
"UFO",
"Rain",
"Rap Concert",
"Strawberry",
"Sammyni Spyderini",
"Mexico",
"YinYang"
}
Net:Handle("EventService/ListEvents", function(player)
return EventService.Events
end)
function EventService.new()
local self = setmetatable({}, EventService)
self._activeEvents = {}
self._registeredEvents = {}
self._eventTimers = {}
self._eventStartTimes = {}
self._eventDurations = {}
self._eventInstances = {
["Raining Tacos"] = RainingTacosEvent.new(self),
["Matteo"] = MatteoEvent.new(self),
["Nyan Cats"] = NyanCatsEvent.new(self),
["La Vacca Saturno Saturnita"] = LaVaccaEvent.new(self),
["4th of July"] = FourthOfJulyEvent.new(self),
["Tung Tung Attack"] = TungTungAttackEvent.new(self),
["Crab Rave"] = CrabRaveEvent.new(self),
Concert = ConcertEvent.new(self),
Snow = SnowEvent.new(self),
["10B Visits"] = TenBVisits.new(self),
Glitch = Glitch.new(self),
Starfall = Starfall.new(self),
["Los Matteos"] = LosMatteos.new(self),
Brazil = Brazil.new(self),
Water = Water.OnLoad(self),
["Solar Flare"] = SolarFlare.new(self),
["Bombardiro Crocodilo"] = BombardiloCrocodilo.new(self),
["Phase 1: Sleepy"] = Phase1.new(self),
["Phase 2: Galaxy Introduction"] = Phase2.new(self),
Phase3 = Phase3.new(self),
["Phase 4: Mygame43"] = Phase4.new(self),
Phase5 = Phase5.new(self),
UFO = UFO.new(self),
Rain = Rain.new(self),
["Rap Concert"] = RapConcert.new(self),
YinYang = YinYangEvent.new(self),
Mexico = MexicoEvent.new(self)
}
self:_initialize()
return self
end
function EventService:_initialize()
self._synchronizer = Synchronizer:Create("Events", {
ActiveEvents = {}
})
game.Players.PlayerAdded:Connect(function(player)
task.wait(1)
self._synchronizer:AddListener(player)
end)
for _, player in pairs(game.Players:GetPlayers()) do
self._synchronizer:AddListener(player)
end
game.Players.PlayerRemoving:Connect(function(player)
self._synchronizer:RemoveListener(player)
end)
task.wait(0.1)
self:_setupRemoteEvents()
self:_registerDefaultEvents()
task.wait(0.1)
end
function EventService:_setupRemoteEvents()
local triggerEventRemote = Net:RemoteEvent("EventService/TriggerEvent")
local stopEventRemote = Net:RemoteEvent("EventService/StopEvent")
local getActiveEventsRemote = Net:RemoteEvent("EventService/GetActiveEvents")
triggerEventRemote.OnServerEvent:Connect(function(player, eventName, duration)
self:StartEvent(eventName, duration)
end)
stopEventRemote.OnServerEvent:Connect(function(player, eventName)
self:StopEvent(eventName)
end)
getActiveEventsRemote.OnServerEvent:Connect(function(player)
getActiveEventsRemote:FireClient(player, self._activeEvents)
end)
end
function EventService:_registerDefaultEvents()
self:RegisterEvent("Bloodmoon", {
defaultDuration = 300,
canStack = false,
cooldown = 600,
description = "Blood moon event with atmospheric changes"
})
local function safeWrapper(eventName, funcName, eventEntry)
local success, err = pcall(function()
if self._eventInstances[eventName] then
self._eventInstances[eventName][funcName](self._eventInstances[eventName], eventEntry)
end
end)
if not success then
-- warn(string.format("[EventService] Error in %s callback for '%s': %s", funcName, eventName, err))
end
end
self:RegisterEvent("Nyan Cats", {
defaultDuration = 180,
canStack = false,
cooldown = 300,
description = "Nyan cats flying around",
onStart = function(eventEntry) safeWrapper("Nyan Cats", "Start", eventEntry) end,
onStop = function(eventEntry) safeWrapper("Nyan Cats", "Stop", eventEntry) end,
})
self:RegisterEvent("Mexico", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "Mexico event with cultural-themed effects and traits",
onStart = function(eventEntry)
if self._eventInstances["Mexico"] then
self._eventInstances["Mexico"]:Start(eventEntry)
end
end,
onStop = function(eventEntry)
if self._eventInstances["Mexico"] then
self._eventInstances["Mexico"]:Stop(eventEntry)
end
end
})
self:RegisterEvent("YinYang", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "OP",
onStart = function(eventEntry)
if self._eventInstances["YinYang"] then
self._eventInstances["YinYang"]:Start(eventEntry)
end
end,
onStop = function(eventEntry)
if self._eventInstances["YinYang"] then
self._eventInstances["YinYang"]:Stop(eventEntry)
end
end
})
self:RegisterEvent("Raining Tacos", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "Tacos falling from the sky",
onStart = function(eventEntry) safeWrapper("Raining Tacos", "Start", eventEntry) end,
onStop = function(eventEntry) safeWrapper("Raining Tacos", "Stop", eventEntry) end,
})
self:RegisterEvent("La Vacca Saturno Saturnita", {
defaultDuration = 200,
canStack = false,
cooldown = 400,
description = "Special cow event",
onStart = function(eventEntry) safeWrapper("La Vacca Saturno Saturnita", "Start", eventEntry) end,
onStop = function(eventEntry) safeWrapper("La Vacca Saturno Saturnita", "Stop", eventEntry) end,
})
self:RegisterEvent("Matteo", {
defaultDuration = 150,
canStack = false,
cooldown = 300,
description = "Matteo special event",
onStart = function(eventEntry) safeWrapper("Matteo", "Start", eventEntry) end,
onStop = function(eventEntry) safeWrapper("Matteo", "Stop", eventEntry) end,
})
self:RegisterEvent("4th of July", {
defaultDuration = 300,
canStack = false,
cooldown = 600,
description = "Celebrate Independence Day with fireworks and special animal!",
onStart = function(eventEntry) safeWrapper("4th of July", "Start", eventEntry) end,
onStop = function(eventEntry) safeWrapper("4th of July", "Stop", eventEntry) end,
})
self:RegisterEvent("Tung Tung Attack", {
defaultDuration = 180,
canStack = false,
cooldown = 360,
description = "Baby Tung Tung wander the map infecting nearby animals with the Zombie trait.",
onStart = function(eventEntry) safeWrapper("Tung Tung Attack", "Start", eventEntry) end,
onStop = function(eventEntry) safeWrapper("Tung Tung Attack", "Stop", eventEntry) end,
})
self:RegisterEvent("Crab Rave", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "Crabs roam the map and hit animals, applying the Claws trait.",
onStart = function(eventEntry) safeWrapper("Crab Rave", "Start", eventEntry) end,
onStop = function(eventEntry) safeWrapper("Crab Rave", "Stop", eventEntry) end,
})
self:RegisterEvent("Molten", {
defaultDuration = 900,
canStack = false,
cooldown = 480,
description = "its lava time",
onStart = function(eventEntry) safeWrapper("Molten", "Start", eventEntry) end,
onStop = function(eventEntry) safeWrapper("Molten", "Stop", eventEntry) end,
})
self:RegisterEvent("Concert", {
defaultDuration = 126,
canStack = false,
cooldown = 480,
description = "its concert time",
onStart = function(eventEntry) safeWrapper("Concert", "Start", eventEntry) end,
onStop = function(eventEntry) safeWrapper("Concert", "Stop", eventEntry) end,
})
self:RegisterEvent("Snow", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "its snow time",
onStart = function(eventEntry)
if self._eventInstances["Snow"] then
self._eventInstances["Snow"]:Start(eventEntry)
end
end,
onStop = function(eventEntry)
if self._eventInstances["Snow"] then
self._eventInstances["Snow"]:Stop(eventEntry)
end
end
})
self:RegisterEvent("10B Visits", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "Thank you for 10B Visits!",
onStart = function(eventEntry)
if self._eventInstances["10B Visits"] then
self._eventInstances["10B Visits"]:Start(eventEntry)
end
end,
onStop = function(eventEntry)
if self._eventInstances["10B Visits"] then
self._eventInstances["10B Visits"]:Stop(eventEntry)
end
end
})
self:RegisterEvent("Glitch", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "itz so glitchy here :3",
onStart = function(eventEntry)
if self._eventInstances["Glitch"] then
self._eventInstances["Glitch"]:Start(eventEntry)
end
end,
onStop = function(eventEntry)
if self._eventInstances["Glitch"] then
self._eventInstances["Glitch"]:Stop(eventEntry)
end
end
})
self:RegisterEvent("Starfall", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "starfall uwu",
onStart = function(eventEntry) safeWrapper("Starfall", "Start", eventEntry) end,
onStop = function(eventEntry) safeWrapper("Starfall", "Stop", eventEntry) end,
})
self:RegisterEvent("Los Matteos", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "LOSSS MATTEOOSSS",
onStart = function(eventEntry)
if self._eventInstances["Los Matteos"] then
self._eventInstances["Los Matteos"]:Start(eventEntry)
end
end,
onStop = function(eventEntry)
if self._eventInstances["Los Matteos"] then
self._eventInstances["Los Matteos"]:Stop(eventEntry)
end
end
})
self:RegisterEvent("Brazil", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "bra-brazil",
onStart = function(eventEntry)
if self._eventInstances["Brazil"] then
self._eventInstances["Brazil"]:Start(eventEntry)
end
end,
onStop = function(eventEntry)
if self._eventInstances["Brazil"] then
self._eventInstances["Brazil"]:Stop(eventEntry)
end
end
})
self:RegisterEvent("Water", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "bottle of wata",
onStart = function(eventEntry)
if self._eventInstances["Water"] then
self._eventInstances["Water"]:Start(eventEntry)
end
end,
onStop = function(eventEntry)
if self._eventInstances["Water"] then
self._eventInstances["Water"]:Stop(eventEntry)
end
end
})
self:RegisterEvent("Rainbow", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "shine",
onStart = function(eventEntry) safeWrapper("Rainbow", "Start", eventEntry) end,
onStop = function(eventEntry) safeWrapper("Rainbow", "Stop", eventEntry) end,
})
self:RegisterEvent("Bombardiro Crocodilo", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "shine",
onStart = function(eventEntry)
if self._eventInstances["Bombardiro Crocodilo"] then
self._eventInstances["Bombardiro Crocodilo"]:Start(eventEntry)
end
end,
onStop = function(eventEntry)
if self._eventInstances["Bombardiro Crocodilo"] then
self._eventInstances["Bombardiro Crocodilo"]:Stop(eventEntry)
end
end
})
self:RegisterEvent("Solar Flare", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "shine",
onStart = function(eventEntry)
if self._eventInstances["Solar Flare"] then
self._eventInstances["Solar Flare"]:Start(eventEntry)
end
end,
onStop = function(eventEntry)
if self._eventInstances["Solar Flare"] then
self._eventInstances["Solar Flare"]:Stop(eventEntry)
end
end
})
self:RegisterEvent("Galaxy", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "shine",
onStart = function(eventEntry) safeWrapper("Galaxy", "Start", eventEntry) end,
onStop = function(eventEntry) safeWrapper("Galaxy", "Stop", eventEntry) end,
})
self:RegisterEvent("Phase 1: Sleepy", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "Phase 1: Sleepy",
onStart = function(eventEntry)
if self._eventInstances["Phase 1: Sleepy"] then
self._eventInstances["Phase 1: Sleepy"]:Start(eventEntry)
end
end,
onStop = function(eventEntry)
if self._eventInstances["Phase 1: Sleepy"] then
self._eventInstances["Phase 1: Sleepy"]:Stop(eventEntry)
end
end
})
self:RegisterEvent("Phase 2: Galaxy Introduction", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "Phase 2: Galaxy Introduction",
onStart = function(eventEntry)
if self._eventInstances["Phase 2: Galaxy Introduction"] then
self._eventInstances["Phase 2: Galaxy Introduction"]:Start(eventEntry)
end
end,
onStop = function(eventEntry)
if self._eventInstances["Phase 2: Galaxy Introduction"] then
self._eventInstances["Phase 2: Galaxy Introduction"]:Stop(eventEntry)
end
end
})
self:RegisterEvent("Phase 3: Sammy's Base", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "Phase 3: Sammy's Base",
onStart = function(eventEntry)
if self._eventInstances["Phase3"] then
self._eventInstances["Phase3"]:Start(eventEntry)
end
end,
onStop = function(eventEntry)
if self._eventInstances["Phase3"] then
self._eventInstances["Phase3"]:Stop(eventEntry)
end
end
})
self:RegisterEvent("Phase 4: Mygame43", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "Phase 1: Sleepy",
onStart = function(eventEntry)
if self._eventInstances["Phase 4: Mygame43"] then
self._eventInstances["Phase 4: Mygame43"]:Start(eventEntry)
end
end,
onStop = function(eventEntry)
if self._eventInstances["Phase 4: Mygame43"] then
self._eventInstances["Phase 4: Mygame43"]:Stop(eventEntry)
end
end
})
self:RegisterEvent("Phase 5: Sammy Snap", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "Phase 5: Sammy Snap",
onStart = function(eventEntry)
if self._eventInstances["Phase5"] then
self._eventInstances["Phase5"]:Start(eventEntry)
end
end,
onStop = function(eventEntry)
if self._eventInstances["Phase5"] then
self._eventInstances["Phase5"]:Stop(eventEntry)
end
end
})
self:RegisterEvent("Bubblegum", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "Phase 5: Sammy Snap",
onStart = function(eventEntry) safeWrapper("Bubblegum", "Start", eventEntry) end,
onStop = function(eventEntry) safeWrapper("Bubblegum", "Stop", eventEntry) end,
})
self:RegisterEvent("UFO", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "fucking ufos",
onStart = function(eventEntry)
if self._eventInstances["UFO"] then
self._eventInstances["UFO"]:Start(eventEntry)
end
end,
onStop = function(eventEntry)
if self._eventInstances["UFO"] then
self._eventInstances["UFO"]:Stop(eventEntry)
end
end
})
self:RegisterEvent("Rain", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "im wet",
onStart = function(eventEntry)
if self._eventInstances["Rain"] then
self._eventInstances["Rain"]:Start(eventEntry)
end
end,
onStop = function(eventEntry)
if self._eventInstances["Rain"] then
self._eventInstances["Rain"]:Stop(eventEntry)
end
end
})
self:RegisterEvent("Rap Concert", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "Rap Concert",
onStart = function(eventEntry)
if self._eventInstances["Rap Concert"] then
self._eventInstances["Rap Concert"]:Start(eventEntry)
end
end,
onStop = function(eventEntry)
if self._eventInstances["Rap Concert"] then
self._eventInstances["Rap Concert"]:Stop(eventEntry)
end
end
})
self:RegisterEvent("Strawberry", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "Strawberry",
onStart = function(eventEntry) safeWrapper("Strawberry", "Start", eventEntry) end,
onStop = function(eventEntry) safeWrapper("Strawberry", "Stop", eventEntry) end,
})
self:RegisterEvent("Sammyni Spyderini", {
defaultDuration = 240,
canStack = false,
cooldown = 480,
description = "Sammyni Spyderini",
onStart = function(eventEntry) safeWrapper("Sammyni Spyderini", "Start", eventEntry) end,
onStop = function(eventEntry) safeWrapper("Sammyni Spyderini", "Stop", eventEntry) end,
})
end
function EventService:RegisterEvent(eventName, config)
if not eventName or type(eventName) ~= "string" then
warn("[EventService] RegisterEvent failed: invalid eventName")
return false
end
local defaultConfig = {
defaultDuration = 180,
canStack = false,
cooldown = 300,
description = "No description provided",
onStart = nil,
onStop = nil
}
config = config or {}
for key, value in pairs(defaultConfig) do
if config[key] == nil then
config[key] = value
end
end
self._registeredEvents[eventName] = config
return true
end
function EventService:StartEvent(eventName, duration, eventData)
if not self._registeredEvents[eventName] then
warn("[EventService] StartEvent failed: event not registered:", eventName)
return false
end
local eventConfig = self._registeredEvents[eventName]
if self._activeEvents[eventName] and not eventConfig.canStack then
return false
end
duration = duration or eventConfig.defaultDuration
local currentTime = workspace:GetServerTimeNow()
local eventEntry = {
eventName = eventName,
startTime = currentTime,
startedAt = currentTime,
duration = duration,
endsAt = currentTime + duration,
data = eventData or {}
}
self._activeEvents[eventName] = eventEntry
self._eventStartTimes[eventName] = currentTime
self._eventDurations[eventName] = duration
self._synchronizer:InsertOnArray("ActiveEvents", eventEntry)
self:_scheduleEventStop(eventName, duration)
if eventConfig.onStart and type(eventConfig.onStart) == "function" then
local success, errorMsg = pcall(eventConfig.onStart, eventEntry)
if not success then
warn(string.format("[EventService] Error in onStart callback for '%s': %s", eventName, errorMsg))
end
end
local notificationEvent = Net:RemoteEvent("NotificationService/Notify")
for _, player in pairs(Players:GetPlayers()) do
end
return true
end
function EventService:StopEvent(eventName)
if not self._activeEvents[eventName] then
return false
end
local eventEntry = self._activeEvents[eventName]
local eventConfig = self._registeredEvents[eventName]
self._activeEvents[eventName] = nil
self._eventStartTimes[eventName] = nil
self._eventDurations[eventName] = nil
if self._eventTimers[eventName] then
local success, errorMsg = pcall(task.cancel, self._eventTimers[eventName])
if not success then
if not string.find(errorMsg, "cannot cancel thread") then
warn(string.format("[EventService] Failed to cancel timer for '%s': %s", eventName, errorMsg))
end
end
self._eventTimers[eventName] = nil
end
local currentEvents = self._synchronizer:Get("ActiveEvents") or {}
local indexToRemove = nil
for i, event in ipairs(currentEvents) do
if event.eventName == eventName then
indexToRemove = i
break
end
end
if indexToRemove then
self._synchronizer:RemoveFromArray("ActiveEvents", indexToRemove)
end
if eventConfig and eventConfig.onStop and type(eventConfig.onStop) == "function" then
local success, errorMsg = pcall(eventConfig.onStop, eventEntry)
if not success then
warn(string.format("[EventService] Error in onStop callback for '%s': %s", eventName, errorMsg))
end
end
local notificationEvent = Net:RemoteEvent("NotificationService/Notify")
for _, player in pairs(Players:GetPlayers()) do
end
return true
end
function EventService:_scheduleEventStop(eventName, duration)
if self._eventTimers[eventName] then
local success, errorMsg = pcall(task.cancel, self._eventTimers[eventName])
if not success then
warn(string.format("[EventService] Failed to cancel timer for '%s': %s", eventName, errorMsg))
end
self._eventTimers[eventName] = nil
end
self._eventTimers[eventName] = task.delay(duration, function()
self._eventTimers[eventName] = nil
self:StopEvent(eventName)
end)
end
function EventService:IsEventActive(eventName)
return self._activeEvents[eventName] ~= nil
end
function EventService:GetActiveEvents()
local events = {}
for name, event in pairs(self._activeEvents) do
events[name] = {
eventName = event.eventName,
startTime = event.startTime,
duration = event.duration,
endTime = event.endsAt,
timeRemaining = math.max(0, event.endsAt - workspace:GetServerTimeNow()),
data = event.data
}
end
return events
end
function EventService:GetEventInfo(eventName)
if not self._registeredEvents[eventName] then
return nil
end
local config = self._registeredEvents[eventName]
local active = self._activeEvents[eventName]
return {
name = eventName,
description = config.description,
defaultDuration = config.defaultDuration,
canStack = config.canStack,
cooldown = config.cooldown,
isActive = active ~= nil,
activeData = active
}
end
function EventService:GetAllRegisteredEvents()
local events = {}
for name, _ in pairs(self._registeredEvents) do
events[name] = self:GetEventInfo(name)
end
return events
end
function EventService:StartRandomEvent()
local availableEvents = {}
for name, _ in pairs(self._registeredEvents) do
if not self._activeEvents[name] then
table.insert(availableEvents, name)
end
end
if #availableEvents == 0 then
return false
end
local randomIndex = math.random(1, #availableEvents)
local selectedEvent = availableEvents[randomIndex]
return self:StartEvent(selectedEvent)
end
function EventService:ForceStopAllEvents()
local stoppedEvents = {}
for eventName, _ in pairs(self._activeEvents) do
if self:StopEvent(eventName) then
table.insert(stoppedEvents, eventName)
end
end
return stoppedEvents
end
function EventService:GetEventStatus()
local status = {
activeCount = 0,
registeredCount = 0,
activeEvents = {},
registeredEvents = {}
}
for name, _ in pairs(self._activeEvents) do
status.activeCount = status.activeCount + 1
table.insert(status.activeEvents, name)
end
for name, _ in pairs(self._registeredEvents) do
status.registeredCount = status.registeredCount + 1
table.insert(status.registeredEvents, name)
end
return status
end
return EventService - Edit
03:12:20.455
- Edit
03:12:20.455
============================== - Edit
03:12:20.455 📜 ServerScriptService.Services.EventService.Events.RainingTacosEvent - Edit
03:12:20.455 ==============================
- Edit
03:12:20.455 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local ServerScriptService = game:GetService("ServerScriptService")
local HttpService = game:GetService("HttpService")
local Packages = ReplicatedStorage.Packages
local Net = require(Packages.Net)
local RoadAnimalService = require(ServerScriptService.Services.RoadAnimalService)
local RainingTacosEvent = {}
RainingTacosEvent.__index = RainingTacosEvent
function RainingTacosEvent.new()
local self = setmetatable({}, RainingTacosEvent)
self._shootRemote = Net:RemoteEvent("EventService/RainingTacos/Shoot")
self._activeConnections = {}
self._shootTimer = nil
self._recentlyTargeted = {}
return self
end
function RainingTacosEvent:Start()
self._shootTimer = task.spawn(function()
while true do
task.wait(math.random(1, 3))
local CollectionService = game:GetService("CollectionService")
local roadAnimals = CollectionService:GetTagged("Animal")
local activeRoadAnimals = {}
local movingAnimalsFolder = workspace:FindFirstChild("MovingAnimals")
for _, animal in pairs(roadAnimals) do
if animal.Parent == movingAnimalsFolder and animal.PrimaryPart and string.find(animal.Name, "RoadAnimal_") then
table.insert(activeRoadAnimals, animal)
end
end
local roadAnimals = activeRoadAnimals
if #roadAnimals > 0 then
local availableAnimals = {}
local currentTime = workspace:GetServerTimeNow()
for animalName, lastTargeted in pairs(self._recentlyTargeted) do
if (currentTime - lastTargeted) > 15 then
self._recentlyTargeted[animalName] = nil
end
end
for _, animal in pairs(roadAnimals) do
local lastTargeted = self._recentlyTargeted[animal.Name]
if not lastTargeted or (currentTime - lastTargeted) > 10 then
table.insert(availableAnimals, animal)
end
end
if #availableAnimals > 0 then
local targetAnimal = availableAnimals[math.random(1, #availableAnimals)]
local animalId = targetAnimal.Name
if not self:_hasTacoTrait(targetAnimal) then
self._recentlyTargeted[animalId] = currentTime
local arrivalTime = currentTime + 2.5
self._shootRemote:FireAllClients(animalId, arrivalTime)
task.delay(5.1, function()
self:_applyTacoTrait(targetAnimal)
end)
end
end
end
end
end)
end
function RainingTacosEvent:_hasTacoTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
return false
end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
for _, trait in ipairs(currentTraits) do
if trait == "Taco" then
return true
end
end
return false
end
function RainingTacosEvent:_applyTacoTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
return
end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
local hasTacoTrait = false
for _, trait in ipairs(currentTraits) do
if trait == "Taco" then
hasTacoTrait = true
break
end
end
if not hasTacoTrait then
table.insert(currentTraits, "Taco")
local newTraitsJson = HttpService:JSONEncode(currentTraits)
animalTemplate:SetAttribute("Traits", newTraitsJson)
end
end
function RainingTacosEvent:Stop()
if self._shootTimer then
task.cancel(self._shootTimer)
self._shootTimer = nil
end
for _, connection in pairs(self._activeConnections) do
if connection then
connection:Disconnect()
end
end
self._activeConnections = {}
end
return RainingTacosEvent
- Edit
03:12:20.455
- Edit
03:12:20.456
============================== - Edit
03:12:20.456 📜 ServerScriptService.Services.EventService.Events.NyanCatsEvent - Edit
03:12:20.456 ==============================
- Edit
03:12:20.456 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local HttpService = game:GetService("HttpService")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local DataManagment = require(ServerScriptService.Services.DataManagment)
local RoadAnimalService = require(ServerScriptService.Services.RoadAnimalService)
local Animals = require(ReplicatedStorage.Datas.Animals)
local NyanCatsEvent = {}
NyanCatsEvent.__index = NyanCatsEvent
function NyanCatsEvent.new(eventService)
local self = setmetatable({}, NyanCatsEvent)
self._eventService = eventService
self._synchronizer = eventService._synchronizer
self._nyanSynchronizer = Synchronizer:Create("NyanCatsEvent", {
IsActive = false
})
for _, player in pairs(Players:GetPlayers()) do
self._nyanSynchronizer:AddListener(player)
end
Players.PlayerAdded:Connect(function(player)
self._nyanSynchronizer:AddListener(player)
end)
Players.PlayerRemoving:Connect(function(player)
self._nyanSynchronizer:RemoveListener(player)
end)
self._isActive = false
self._spawnEffectRemote = Net:RemoteEvent("EventService/NyanCats/SpawnEffect")
self._strikeRemote = Net:RemoteEvent("EventService/NyanCats/Struck")
self._recentlyTargeted = {}
self._spawnEffectRemote.OnServerEvent:Connect(function(player)
self:_handleSpawnEffect(player)
end)
return self
end
function NyanCatsEvent:Start(eventEntry)
if self._isActive then
return
end
self._isActive = true
print("[NyanCatsEvent] Starting Nyan Cats event")
ReplicatedStorage:SetAttribute("NyanCatsEvent", true)
local spawnTime = workspace:GetServerTimeNow() + 1
for _, player in pairs(Players:GetPlayers()) do
self._spawnEffectRemote:FireClient(player, spawnTime)
end
self._nyanSynchronizer:Set("IsActive", true)
self:_startStrikeLoop()
task.wait(1)
self:_spawnGattatinoNyanino()
print("[NyanCatsEvent] Nyan Cats event started successfully")
end
function NyanCatsEvent:Stop(eventEntry)
if not self._isActive then
return
end
self._isActive = false
print("[NyanCatsEvent] Stopping Nyan Cats event")
ReplicatedStorage:SetAttribute("NyanCatsEvent", false)
self._nyanSynchronizer:Set("IsActive", false)
if self._strikeTask then
task.cancel(self._strikeTask)
self._strikeTask = nil
end
print("[NyanCatsEvent] Nyan Cats event stopped")
end
function NyanCatsEvent:_spawnGattatinoNyanino()
print("[NyanCatsEvent] Spawning Gattatino Nyanino on the road")
local success, result = pcall(function()
local animalData = Animals["Gattatino Neonino"]
if not animalData then
warn("[NyanCatsEvent] Gattatino Nyanino not found in Animals data")
return
end
_G.RoadAnimalService.Spawner:SpawnSpecificAnimal("Gattatino Nyanino", nil, nil)
print("[NyanCatsEvent] Spawned Gattatino Nyanino on the road")
end)
if not success then
warn("[NyanCatsEvent] Failed to spawn Gattatino Nyanino on the road:", result)
end
end
function NyanCatsEvent:_handleSpawnEffect(player)
if not self._isActive then
return
end
print("[NyanCatsEvent] Handling spawn effect for", player and player.Name or "server")
end
function NyanCatsEvent:_startStrikeLoop()
if self._strikeTask then
task.cancel(self._strikeTask)
end
self._strikeTask = task.spawn(function()
while self._isActive do
task.wait(math.random(2,4))
local targetAnimal = self:_pickTargetAnimal()
if targetAnimal then
local catIndex = math.random(1,30)
local currentTime = workspace:GetServerTimeNow()
self._strikeRemote:FireAllClients(catIndex, targetAnimal.Name, currentTime)
self._recentlyTargeted[targetAnimal.Name] = currentTime
task.delay(3.1, function()
self:_applyNyanTrait(targetAnimal)
end)
end
end
end)
end
function NyanCatsEvent:_pickTargetAnimal()
local CollectionService = game:GetService("CollectionService")
local roadAnimals = CollectionService:GetTagged("Animal")
local movingAnimalsFolder = workspace:FindFirstChild("MovingAnimals")
local currentTime = workspace:GetServerTimeNow()
for animalName, lastTime in pairs(self._recentlyTargeted) do
if (currentTime - lastTime) > 15 then
self._recentlyTargeted[animalName] = nil
end
end
local candidates = {}
for _, animal in ipairs(roadAnimals) do
if animal.Parent == movingAnimalsFolder and animal.PrimaryPart and string.find(animal.Name, "RoadAnimal_") then
if not self._recentlyTargeted[animal.Name] and not self:_hasNyanTrait(animal) then
table.insert(candidates, animal)
end
end
end
if #candidates == 0 then return nil end
return candidates[math.random(1, #candidates)]
end
function NyanCatsEvent:_hasNyanTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
return false
end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
for _, trait in ipairs(currentTraits) do
if trait == "Nyan" then
return true
end
end
return false
end
function NyanCatsEvent:_applyNyanTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
return
end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
for _, trait in ipairs(currentTraits) do
if trait == "Nyan" then
return
end
end
table.insert(currentTraits, "Nyan")
animalTemplate:SetAttribute("Traits", HttpService:JSONEncode(currentTraits))
end
return NyanCatsEvent - Edit
03:12:20.456
- Edit
03:12:20.456
============================== - Edit
03:12:20.456 📜 ServerScriptService.Services.EventService.Events.LaVaccaEvent - Edit
03:12:20.456 ==============================
- Edit
03:12:20.456 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local RunService = game:GetService("RunService")
local CollectionService = game:GetService("CollectionService")
local HttpService = game:GetService("HttpService")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local Observers = require(Packages.Observers)
local Synchronizer = require(Packages.Synchronizer)
local Animals = require(ReplicatedStorage.Datas.Animals)
local LaVaccaEvent = {}
LaVaccaEvent.__index = LaVaccaEvent
function LaVaccaEvent.new(eventService)
local self = setmetatable({}, LaVaccaEvent)
self._eventService = eventService
self._isActive = false
self._triangleModels = {}
self._cometTimer = nil
self._eventConnection = nil
self._continuousMonitoring = true
self._animalsBeingHit = {}
self._cometRemote = Net:RemoteEvent("EventService/LaVacca/Comet")
self:_setupContinuousTriangleMonitoring()
return self
end
function LaVaccaEvent:Start(eventEntry)
if self._isActive then
return
end
self._isActive = true
self:_setupTriangleDetection()
self._cometTimer = task.delay(15, function()
self:_startCometAttacks()
end)
end
function LaVaccaEvent:Stop(eventEntry)
if not self._isActive then
return
end
self._isActive = false
if self._cometTimer then
task.cancel(self._cometTimer)
self._cometTimer = nil
end
if self._eventConnection then
self._eventConnection:Disconnect()
self._eventConnection = nil
end
for _, player in ipairs(Players:GetPlayers()) do
if player.Character then
CollectionService:RemoveTag(player.Character, "LaVaccaPlayerVFX")
end
end
for _, model in ipairs(CollectionService:GetTagged("LaVaccaModel")) do
CollectionService:RemoveTag(model, "LaVaccaModel")
model:Destroy()
end
self._triangleModels = {}
self._animalsBeingHit = {}
end
function LaVaccaEvent:_setupContinuousTriangleMonitoring()
local triangleModels = {}
local RunService = game:GetService("RunService")
local connection
local function checkAndStartEvent()
if self._isActive then
return
end
local allModelsPresent = triangleModels[1] and triangleModels[2] and triangleModels[3]
if not allModelsPresent then
local missing = {}
for i = 1, 3 do
if not triangleModels[i] then
table.insert(missing, tostring(i))
end
end
return
end
local positions = {}
local maxAllowedDistance = 35
local minAllowedDistance = 5
for i = 1, 3 do
local model = triangleModels[i]
if model and model.PrimaryPart then
positions[i] = model.PrimaryPart.Position
else
return
end
end
local dist12 = (positions[1] - positions[2]).Magnitude
local dist23 = (positions[2] - positions[3]).Magnitude
local dist31 = (positions[3] - positions[1]).Magnitude
local avgDistance = (dist12 + dist23 + dist31) / 3
if dist12 > maxAllowedDistance or dist23 > maxAllowedDistance or dist31 > maxAllowedDistance then
return
end
if dist12 < minAllowedDistance or dist23 < minAllowedDistance or dist31 < minAllowedDistance then
return
end
local maxDiff = math.max(math.abs(dist12 - dist23), math.abs(dist23 - dist31), math.abs(dist31 - dist12))
if maxDiff > maxAllowedDistance * 0.5 then
return
end
local centerPos = (positions[1] + positions[2] + positions[3]) / 3
ReplicatedStorage:SetAttribute("LaVaccaCenter", centerPos)
if connection then
connection:Disconnect()
connection = nil
end
for i = 1, 3 do
local model = triangleModels[i]
if model then
local ownerUserId = model:GetAttribute("OwnerUserId")
if ownerUserId then
local player = Players:GetPlayerByUserId(ownerUserId)
if player then
local stealingPlot = player:GetAttribute("StealingPlot")
local stealingSlot = player:GetAttribute("StealingSlot")
model:SetAttribute("PreserveOnStealingEnd", true)
if player.Character then
local humanoid = player.Character:FindFirstChild("Humanoid")
if humanoid then
for _, track in pairs(humanoid:GetPlayingAnimationTracks()) do
if track.Name == "carry" or track.Name:find("steal") then
track:Stop()
end
end
end
end
player:SetAttribute("Stealing", false)
player:SetAttribute("StealingPlot", nil)
player:SetAttribute("StealingSlot", nil)
if stealingPlot then
local targetPlot = Synchronizer:Get(stealingPlot)
if targetPlot then
local animalList = targetPlot:Get("AnimalList") or {}
if stealingSlot and animalList[stealingSlot] then
animalList[stealingSlot] = nil
targetPlot:Set("AnimalList", animalList)
end
end
end
end
end
end
end
for i = 1, 3 do
local model = triangleModels[i]
if model and model.PrimaryPart then
for _, part in ipairs(model:GetDescendants()) do
if part:IsA("BasePart") then
part.Anchored = true
end
end
for _, child in pairs(model.PrimaryPart:GetChildren()) do
if child:IsA("WeldConstraint") then
child:Destroy()
end
end
end
end
local success, error = pcall(function()
self._eventService:StartEvent("La Vacca Saturno Saturnita", 540)
end)
if success then
print("[LaVaccaEvent] ✅ Event started successfully!")
else
warn("[LaVaccaEvent] ❌ Failed to start event:", error)
end
end
connection = RunService.Heartbeat:Connect(function()
checkAndStartEvent()
end)
local function onModelAdded(model)
local index = tonumber(model:GetAttribute("LaVaccaIndex"))
if index and index >= 1 and index <= 3 then
triangleModels[index] = model
end
end
local function onModelRemoved(model)
local index = tonumber(model:GetAttribute("LaVaccaIndex"))
if index and index >= 1 and index <= 3 then
if triangleModels[index] == model then
triangleModels[index] = nil
end
end
end
CollectionService:GetInstanceAddedSignal("LaVaccaModel"):Connect(onModelAdded)
CollectionService:GetInstanceRemovedSignal("LaVaccaModel"):Connect(onModelRemoved)
for _, model in ipairs(CollectionService:GetTagged("LaVaccaModel")) do
onModelAdded(model)
end
return function()
if connection then
connection:Disconnect()
connection = nil
end
end
end
function LaVaccaEvent:_setupTriangleDetection()
local function onModelAdded(model)
if not self._isActive then return end
local index = model:GetAttribute("LaVaccaIndex")
if index and index >= 1 and index <= 3 then
self._triangleModels[index] = model
if self._triangleModels[1] and self._triangleModels[2] and self._triangleModels[3] then
self:_handleTriangleComplete()
end
end
end
local function onModelRemoved(model)
if not self._isActive then return end
local index = model:GetAttribute("LaVaccaIndex")
if index and self._triangleModels[index] == model then
self._triangleModels[index] = nil
end
end
Observers.observeTag("LaVaccaModel", function(model)
onModelAdded(model)
return function()
onModelRemoved(model)
end
end)
end
function LaVaccaEvent:_handleTriangleComplete()
local positions = {}
local playerCharacters = {}
for i = 1, 3 do
local model = self._triangleModels[i]
if model and model.PrimaryPart then
table.insert(positions, model.PrimaryPart.Position)
local ownerUserId = model:GetAttribute("OwnerUserId")
if ownerUserId then
local player = Players:GetPlayerByUserId(ownerUserId)
if player and player.Character then
local humanoid = player.Character:FindFirstChild("Humanoid")
if humanoid then
local animator = humanoid:FindFirstChild("Animator")
if animator then
for _, track in pairs(animator:GetPlayingAnimationTracks()) do
if track.Name == "Carry" or track.Name:find("steal") then
track:Stop()
track:Destroy()
end
end
end
end
table.insert(playerCharacters, player.Character)
end
end
end
end
if #positions == 3 then
local centerPos = (positions[1] + positions[2] + positions[3]) / 3
ReplicatedStorage:SetAttribute("LaVaccaCenter", centerPos)
for _, character in ipairs(playerCharacters) do
CollectionService:AddTag(character, "LaVaccaPlayerVFX")
end
self:Start()
end
end
function LaVaccaEvent:_startCometAttacks()
if not self._isActive then return end
local function fireCometAttack()
if not self._isActive then return end
local roadAnimals = self:_getAllRoadAnimals()
if #roadAnimals == 0 then
return
end
local availableAnimals = {}
for _, animal in ipairs(roadAnimals) do
if animal.animalModel then
local currentTraitsJson = animal.animalModel:GetAttribute("Traits")
local hasGalacticTrait = false
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
for _, trait in ipairs(decoded) do
if trait == "Galactic" then
hasGalacticTrait = true
break
end
end
end
end
if not hasGalacticTrait then
table.insert(availableAnimals, animal)
end
end
end
if #availableAnimals == 0 then
return
end
local cometCount = math.min(2, #availableAnimals)
for i = 1, cometCount do
if #availableAnimals == 0 then break end
local randomIndex = math.random(1, #availableAnimals)
local randomAnimal = availableAnimals[randomIndex]
if randomAnimal and randomAnimal.animalModel then
self:_fireCometAtAnimal(randomAnimal)
table.remove(availableAnimals, randomIndex)
end
end
end
fireCometAttack()
self._eventConnection = RunService.Heartbeat:Connect(function()
if not self._isActive then return end
if math.random() < 0.004 then
fireCometAttack()
end
end)
end
function LaVaccaEvent:_getAllRoadAnimals()
local animals = {}
local roadService = _G.RoadAnimalService
if roadService and roadService.ActiveAnimals then
for animalTemplate, animalData in pairs(roadService.ActiveAnimals) do
if animalTemplate and animalTemplate.Parent then
table.insert(animals, {
animalModel = animalTemplate,
data = animalData,
uuid = tostring(animalTemplate)
})
end
end
end
return animals
end
function LaVaccaEvent:_fireCometAtAnimal(animal)
if not animal or not animal.animalModel or not animal.animalModel.PrimaryPart then
return
end
if self._animalsBeingHit[animal.uuid] then
return
end
self._animalsBeingHit[animal.uuid] = true
local targetPos = animal.animalModel.PrimaryPart.Position
local skyHeight = 200
local horizontalOffset = Vector3.new(
math.random(-30, 30),
0,
math.random(-30, 30)
)
local cometSpawnPos = targetPos + Vector3.new(0, skyHeight, 0) + horizontalOffset
self._cometRemote:FireAllClients(cometSpawnPos, animal.uuid)
task.delay(1.1, function()
if not animal.animalModel or not animal.animalModel.Parent then
self._animalsBeingHit[animal.uuid] = nil
return
end
local currentTraitsJson = animal.animalModel:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
local hasGalacticTrait = false
for _, trait in ipairs(currentTraits) do
if trait == "Galactic" then
hasGalacticTrait = true
break
end
end
if not hasGalacticTrait then
table.insert(currentTraits, "Galactic")
local newTraitsJson = HttpService:JSONEncode(currentTraits)
animal.animalModel:SetAttribute("Traits", newTraitsJson)
end
self._animalsBeingHit[animal.uuid] = nil
end)
end
return LaVaccaEvent - Edit
03:12:20.456
- Edit
03:12:20.456
============================== - Edit
03:12:20.456 📜 ServerScriptService.Services.EventService.Events.FourthOfJulyEvent - Edit
03:12:20.456 ==============================
- Edit
03:12:20.456 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local HttpService = game:GetService("HttpService")
local CollectionService = game:GetService("CollectionService")
local RunService = game:GetService("RunService")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local DataManagment = require(ServerScriptService.Services.DataManagment)
local RoadAnimalService = require(ServerScriptService.Services.RoadAnimalService)
local Animals = require(ReplicatedStorage.Datas.Animals)
local FourthOfJulyEvent = {}
FourthOfJulyEvent.__index = FourthOfJulyEvent
function FourthOfJulyEvent.new(eventService)
local self = setmetatable({}, FourthOfJulyEvent)
self._eventService = eventService
self._isActive = false
self._spawnEffectRemote = Net:RemoteEvent("EventService/4th of July/SpawnEffect")
self._createFireworkRemote = Net:RemoteEvent("EventService/4th of July/CreateFirework")
self._explodeTraitEffectRemote = Net:RemoteEvent("EventService/4th of July/ExplodeTraitEffect")
self._recentlyTargeted = {}
self._fireworkTask = nil
return self
end
function FourthOfJulyEvent:Start(eventEntry)
if self._isActive then
return
end
self._isActive = true
local spawnTime = workspace:GetServerTimeNow() + 1
for _, player in pairs(Players:GetPlayers()) do
self._spawnEffectRemote:FireClient(player, spawnTime)
end
self:_startFireworkLoop()
task.wait(0.5)
self:_spawnUnclitoSamito()
end
function FourthOfJulyEvent:Stop(eventEntry)
if not self._isActive then
return
end
self._isActive = false
if self._fireworkTask then
task.cancel(self._fireworkTask)
self._fireworkTask = nil
end
end
function FourthOfJulyEvent:_spawnUnclitoSamito()
local success, result = pcall(function()
local animalData = Animals["Statutino Libertino"]
if not animalData then
warn("[FourthOfJulyEvent] Statutino Libertino not found in Animals data")
return
end
_G.RoadAnimalService.Spawner:SpawnSpecificAnimal("Unclito Samito", nil, nil)
end)
if not success then
warn("[FourthOfJulyEvent] Failed to spawn Statutino Libertino on the road:", result)
end
end
function FourthOfJulyEvent:_startFireworkLoop()
if self._fireworkTask then
task.cancel(self._fireworkTask)
end
self._fireworkTask = task.spawn(function()
while self._isActive do
task.wait(1.5)
local fireworkData = self:_generateFireworkData()
if fireworkData and #fireworkData > 0 then
local currentTime = workspace:GetServerTimeNow()
for _, firework in ipairs(fireworkData) do
local explosionDelay = firework.Height / 20 * 0.8
local falloffCompletionDelay = explosionDelay + 2.3
firework.ServerStartTime = currentTime
end
self._createFireworkRemote:FireAllClients(fireworkData)
for _, firework in ipairs(fireworkData) do
local explosionDelay = firework.Height / 20 * 0.8
local falloffCompletionDelay = explosionDelay + 2.3
task.delay(falloffCompletionDelay, function()
self:_handleFireworkFalloffs(firework)
end)
end
end
end
end)
end
function FourthOfJulyEvent:_generateFireworkData()
local fireworkCount = math.random(1, 2)
local fireworkData = {}
for i = 1, fireworkCount do
table.insert(fireworkData, {
Chosen = math.random(1, 10),
Height = math.random(20, 70),
FireworkEffect = math.random(1, 3),
Falloffs = self:_generateFalloffs()
})
end
return fireworkData
end
function FourthOfJulyEvent:_generateFalloffs()
local falloffs = {}
local falloffCount = math.random(3, 8)
for i = 1, falloffCount do
table.insert(falloffs, Vector3.new(
math.random(-50, 50),
0,
math.random(-50, 50)
))
end
local targetAnimals = self:_getRandomRoadAnimals(math.random(0, 2))
for _, animalName in ipairs(targetAnimals) do
table.insert(falloffs, animalName)
end
return falloffs
end
function FourthOfJulyEvent:_getRandomRoadAnimals(count)
local roadAnimals = CollectionService:GetTagged("Animal")
local movingAnimalsFolder = workspace:FindFirstChild("MovingAnimals")
local candidates = {}
for _, animal in ipairs(roadAnimals) do
if animal.Parent == movingAnimalsFolder and animal.PrimaryPart and string.find(animal.Name, "RoadAnimal_") then
table.insert(candidates, animal.Name)
end
end
local selected = {}
for i = 1, math.min(count, #candidates) do
local randomIndex = math.random(1, #candidates)
table.insert(selected, candidates[randomIndex])
table.remove(candidates, randomIndex)
end
return selected
end
function FourthOfJulyEvent:_handleFireworkFalloffs(fireworkData)
for _, falloff in ipairs(fireworkData.Falloffs) do
if type(falloff) == "string" then
self:_applyFireworksTrait(falloff)
end
end
end
function FourthOfJulyEvent:_applyFireworksTrait(animalName)
local roadAnimals = CollectionService:GetTagged("Animal")
local movingAnimalsFolder = workspace:FindFirstChild("MovingAnimals")
local targetAnimal = nil
for _, animal in ipairs(roadAnimals) do
if animal.Parent == movingAnimalsFolder and animal.Name == animalName then
targetAnimal = animal
break
end
end
if not targetAnimal or not targetAnimal.Parent then
return
end
if self:_hasFireworksTrait(targetAnimal) then
return
end
local currentTraitsJson = targetAnimal:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
table.insert(currentTraits, "Fireworks")
targetAnimal:SetAttribute("Traits", HttpService:JSONEncode(currentTraits))
self._explodeTraitEffectRemote:FireAllClients(animalName)
end
function FourthOfJulyEvent:_hasFireworksTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
return false
end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
for _, trait in ipairs(currentTraits) do
if trait == "Fireworks" then
return true
end
end
return false
end
return FourthOfJulyEvent - Edit
03:12:20.456
- Edit
03:12:20.457
============================== - Edit
03:12:20.457 📜 ServerScriptService.Services.EventService.Events.TungTungAttackEvent - Edit
03:12:20.457 ==============================
- Edit
03:12:20.457 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local CollectionService = game:GetService("CollectionService")
local HttpService = game:GetService("HttpService")
local RunService = game:GetService("RunService")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local SimplePath = require(Packages.SimplePath)
local TungTungAttackEvent = {}
TungTungAttackEvent.__index = TungTungAttackEvent
local SCAN_RADIUS = 25
local TRAIT_NAME = "Zombie"
local COOLDOWN_HIT = 2
local MOVE_INTERVAL = {4, 7}
local BABY_COUNT = math.random(20, 30)
function TungTungAttackEvent.new(eventService)
local self = setmetatable({}, TungTungAttackEvent)
self._eventService = eventService
self._babies = {}
self._activePaths = {}
self._recentlyHit = {}
self._moveConnections = {}
return self
end
function TungTungAttackEvent:Start()
local eventsFolder = workspace:FindFirstChild("Events")
if not eventsFolder then
warn("[TungTungAttackEvent] Events folder not found in workspace")
return
end
local eventFolder = eventsFolder:FindFirstChild("Tung Tung Attack")
if not eventFolder then
warn("[TungTungAttackEvent] Tung Tung Attack event folder not found")
return
end
self._eventFolder = eventFolder
self._babies = {}
self._activePaths = {}
self._recentlyHit = {}
self._moveConnections = {}
local wanderPoints = {}
for _, child in ipairs(eventFolder:GetChildren()) do
if child:IsA("BasePart") then
table.insert(wanderPoints, child)
end
end
if #wanderPoints == 0 then
warn("[TungTungAttackEvent] No wander points found")
return
end
local currentTime = workspace:GetServerTimeNow()
local activeEvents = self._eventService:GetActiveEvents()
local eventData = activeEvents["Tung Tung Attack"]
if not eventData then
warn("[TungTungAttackEvent] Event data not found")
return
end
local eventStartTime = eventData.startTime
local caveDelay = eventStartTime + 10 - currentTime
task.spawn(function()
task.wait(math.max(0, caveDelay))
local babiesFolder = Instance.new("Folder")
babiesFolder.Name = "BabyTungTungs"
babiesFolder.Parent = workspace
for i = 1, math.min(BABY_COUNT, #wanderPoints) do
local wanderPoint = wanderPoints[i]
self:_spawnBaby(wanderPoint, babiesFolder, wanderPoints)
end
self:_startScanning()
end)
end
function TungTungAttackEvent:_spawnBaby(wanderPoint, babiesFolder, allWanderPoints)
local babyModel = self:_getBabyModel()
if not babyModel then
warn("[TungTungAttackEvent] Failed to get baby model")
return
end
for _, part in babyModel:GetDescendants() do
if part:IsA("BasePart") then
part.CanCollide = false
part.CanQuery = false
part.CanTouch = false
part.Massless = true
part.Anchored = false
end
end
babyModel.Parent = babiesFolder
local humanoidRootPart = babyModel:FindFirstChild("HumanoidRootPart")
if humanoidRootPart then
local spawnPosition = wanderPoint.Position + Vector3.new(0, wanderPoint.Size.Y/2 + humanoidRootPart.Size.Y/2, 0)
humanoidRootPart.CFrame = CFrame.new(spawnPosition)
end
self:_setupBabyAnimations(babyModel)
CollectionService:AddTag(babyModel, "BabyTungTung")
table.insert(self._babies, babyModel)
self:_setupBabyMovement(babyModel, allWanderPoints)
end
function TungTungAttackEvent:_getBabyModel()
local babyTungTung = script:FindFirstChild("BabyTungTung")
if babyTungTung then
return babyTungTung:Clone()
else
warn("[TungTungAttackEvent] BabyTungTung model not found in script")
return nil
end
end
function TungTungAttackEvent:_scaleBabyModel(model, scale)
for _, part in model:GetDescendants() do
if part:IsA("BasePart") then
part.Size = part.Size * scale
end
end
end
function TungTungAttackEvent:_setupBabyAnimations(babyModel)
local humanoid = babyModel:FindFirstChild("Humanoid")
if not humanoid then
warn("[TungTungAttackEvent] No Humanoid found in baby model")
return
end
local animator = humanoid:FindFirstChild("Animator")
if not animator then
animator = Instance.new("Animator")
animator.Parent = humanoid
end
local walkAnim = babyModel:FindFirstChild("BabyTungWalk")
local idleAnim = babyModel:FindFirstChild("BabyTungIdle")
if not walkAnim or not idleAnim then
local animationsFolder = ReplicatedStorage:FindFirstChild("Animations")
if animationsFolder then
local animalsFolder = animationsFolder:FindFirstChild("Animals")
if animalsFolder then
local tungAnimFolder = animalsFolder:FindFirstChild("Tung Tung Tung Sahur")
if tungAnimFolder then
walkAnim = walkAnim or tungAnimFolder:FindFirstChild("Walk")
idleAnim = idleAnim or tungAnimFolder:FindFirstChild("Idle")
end
end
end
end
if walkAnim and idleAnim then
local walkTrack = animator:LoadAnimation(walkAnim)
local idleTrack = animator:LoadAnimation(idleAnim)
walkTrack.Looped = true
walkTrack.Priority = Enum.AnimationPriority.Movement
idleTrack.Looped = true
idleTrack.Priority = Enum.AnimationPriority.Idle
self._babyAnimations = self._babyAnimations or {}
self._babyAnimations[babyModel] = {
walkTrack = walkTrack,
idleTrack = idleTrack,
isWalking = false
}
idleTrack:Play()
local runConnection = humanoid.Running:Connect(function(speed)
local animData = self._babyAnimations[babyModel]
if not animData then return end
if speed > 0 then
if not animData.isWalking then
animData.isWalking = true
animData.idleTrack:Stop()
animData.walkTrack:Play()
animData.walkTrack:AdjustSpeed(1.5)
end
else
if animData.isWalking then
animData.isWalking = false
animData.walkTrack:Stop()
animData.idleTrack:Play()
end
end
end)
self._animationConnections = self._animationConnections or {}
self._animationConnections[babyModel] = runConnection
else
warn("[TungTungAttackEvent] Could not find walk or idle animations")
end
end
function TungTungAttackEvent:_setupBabyMovement(babyModel, wanderPoints)
local humanoid = babyModel:FindFirstChild("Humanoid")
local humanoidRootPart = babyModel:FindFirstChild("HumanoidRootPart")
if not humanoid or not humanoidRootPart then
warn("[TungTungAttackEvent] Baby model missing Humanoid or HumanoidRootPart")
return
end
local pathConfig = {
WaypointSpacing = 4,
AgentRadius = 2,
AgentHeight = 5,
AgentCanJump = true,
AgentCanClimb = false,
Costs = {
Water = 20,
DangerousLava = math.huge
}
}
local path = SimplePath.new(babyModel, pathConfig)
self._activePaths[babyModel] = path
local function moveToRandomPoint()
if not babyModel.Parent then
return
end
local targetPoint = wanderPoints[math.random(1, #wanderPoints)]
local targetPosition = targetPoint.Position
path:Run(targetPosition)
end
moveToRandomPoint()
local moveConnection
moveConnection = path.Reached:Connect(function()
local waitTime = math.random(MOVE_INTERVAL[1], MOVE_INTERVAL[2])
task.wait(waitTime)
moveToRandomPoint()
end)
self._moveConnections[babyModel] = moveConnection
end
function TungTungAttackEvent:_startScanning()
local function scanForAnimals()
for _, baby in ipairs(self._babies) do
local humanoidRootPart = baby:FindFirstChild("HumanoidRootPart")
if baby.Parent and humanoidRootPart then
local babiesPosition = humanoidRootPart.Position
local animalsInRange = {}
for _, obj in ipairs(workspace:GetPartBoundsInBox(humanoidRootPart.CFrame, Vector3.new(SCAN_RADIUS, SCAN_RADIUS, SCAN_RADIUS))) do
local model = obj.Parent
if model and CollectionService:HasTag(model, "Animal") then
table.insert(animalsInRange, model)
end
end
for _, animal in ipairs(animalsInRange) do
if animal:GetAttribute("Index") and not self._recentlyHit[animal] then
self:_applyZombieTrait(animal)
self._recentlyHit[animal] = tick()
end
end
end
end
for animal, hitTime in pairs(self._recentlyHit) do
if tick() - hitTime > COOLDOWN_HIT then
self._recentlyHit[animal] = nil
end
end
end
self._scanConnection = RunService.Heartbeat:Connect(scanForAnimals)
end
function TungTungAttackEvent:_applyZombieTrait(animal)
local currentTraits = animal:GetAttribute("Traits")
local traitsTable = {}
if currentTraits then
local success, decoded = pcall(HttpService.JSONDecode, HttpService, currentTraits)
if success and type(decoded) == "table" then
traitsTable = decoded
end
end
local hasZombie = false
for _, trait in ipairs(traitsTable) do
if trait == TRAIT_NAME then
hasZombie = true
break
end
end
if not hasZombie then
table.insert(traitsTable, TRAIT_NAME)
animal:SetAttribute("Traits", HttpService:JSONEncode(traitsTable))
end
end
function TungTungAttackEvent:Stop()
if self._scanConnection then
self._scanConnection:Disconnect()
self._scanConnection = nil
end
if self._animationConnections then
for babyModel, connection in pairs(self._animationConnections) do
if connection then
connection:Disconnect()
end
end
self._animationConnections = {}
end
if self._babyAnimations then
self._babyAnimations = {}
end
for baby, connection in pairs(self._moveConnections) do
if connection then
connection:Disconnect()
end
end
self._moveConnections = {}
for baby, path in pairs(self._activePaths) do
if path and path.Stop then
local success, err = pcall(function()
if path.Status ~= Enum.PathStatus.Idle then
path:Stop()
end
end)
if not success then
end
end
end
self._activePaths = {}
for _, baby in ipairs(self._babies) do
if baby and baby.Parent then
baby:Destroy()
end
end
self._babies = {}
self._recentlyHit = {}
local babiesFolder = workspace:FindFirstChild("BabyTungTungs")
if babiesFolder then
babiesFolder:Destroy()
end
end
return TungTungAttackEvent - Edit
03:12:20.457
- Edit
03:12:20.457
============================== - Edit
03:12:20.457 📜 ServerScriptService.Services.EventService.Events.CrabRaveEvent - Edit
03:12:20.457 ==============================
- Edit
03:12:20.457 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local HttpService = game:GetService("HttpService")
local CollectionService = game:GetService("CollectionService")
local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local SimplePath = require(Packages.SimplePath)
local DataManagment = require(ServerScriptService.Services.DataManagment)
local RoadAnimalService = require(ServerScriptService.Services.RoadAnimalService)
local Animals = require(ReplicatedStorage.Datas.Animals)
local CrabRaveEvent = {}
CrabRaveEvent.__index = CrabRaveEvent
local SCAN_RADIUS = 50
local TRAIT_NAME = "Claws"
local COOLDOWN_HIT = 2
local MOVEMENT_SPEED = 16
local RETURN_DELAY = 5
local MAX_ACTIVE_CRABS = 3
local STARTUP_DELAY = 9
local STATIONARY_COOLDOWN_MIN = 4
local STATIONARY_COOLDOWN_MAX = 6
local HIT_DISTANCE = 10
function CrabRaveEvent.new(eventService)
local self = setmetatable({}, CrabRaveEvent)
self._eventService = eventService
self._isActive = false
self._recentlyHit = {}
self._originalBaseplateColor = nil
self._crabPaths = {}
self._targetedAnimals = {}
self._activeCrabs = 0
self._hitRemote = Net:RemoteEvent("EventService/Crab Rave/Hit")
return self
end
function CrabRaveEvent:Start(eventEntry)
if self._isActive then
return
end
self._isActive = true
self._eventEntry = eventEntry
self._crabs = {}
self._targetedAnimals = {}
self._activeCrabs = 0
local baseplate = workspace:FindFirstChild("Map")
if baseplate then
baseplate = baseplate:FindFirstChild("Baseplate")
if baseplate then
self._originalBaseplateColor = baseplate.Color
baseplate.Color = Color3.fromRGB(156, 159, 0)
end
end
local crabsFolder = Instance.new("Folder")
crabsFolder.Name = "CrabRaveCrabs"
crabsFolder.Parent = workspace
CollectionService:AddTag(crabsFolder, "CrabRaveCrabFolder")
local groundFolder = Instance.new("Folder")
groundFolder.Name = "Ground"
groundFolder.Parent = crabsFolder
local wallFolder = Instance.new("Folder")
wallFolder.Name = "Wall"
wallFolder.Parent = crabsFolder
local eventsFolder = workspace:FindFirstChild("Events")
if eventsFolder then
local crabFolder = eventsFolder:FindFirstChild("Crab")
if crabFolder then
for _, wanderPart in pairs(crabFolder:GetChildren()) do
if wanderPart:IsA("BasePart") and wanderPart.Name == "Wander" then
CollectionService:AddTag(wanderPart, "CrabRaveWanderPoint")
local isStationary = math.abs(wanderPart.Position.Y - 23.205) < 0.1
local parentFolder = isStationary and groundFolder or wallFolder
local crabModel = self:_createCrabModel(wanderPart, parentFolder)
if crabModel then
table.insert(self._crabs, crabModel)
if isStationary then
CollectionService:AddTag(wanderPart, "CrabRaveStationaryPoint")
crabModel:SetAttribute("IsStationary", true)
crabModel:SetAttribute("Dance", 1)
else
CollectionService:AddTag(wanderPart, "CrabRaveWanderingPoint")
crabModel:SetAttribute("IsStationary", false)
end
end
end
end
else
warn("[CrabRaveEvent] Crab folder not found in workspace.Events")
end
else
warn("[CrabRaveEvent] Events folder not found in workspace")
end
-- Add synchronized flashing highlight effect to ALL crabs at once
self:_addSynchronizedHighlights()
self:_startScanning()
end
function CrabRaveEvent:Stop(eventEntry)
if not self._isActive then
return
end
self._isActive = false
if self._originalBaseplateColor then
local baseplate = workspace:FindFirstChild("Map")
if baseplate then
baseplate = baseplate:FindFirstChild("Baseplate")
if baseplate then
baseplate.Color = self._originalBaseplateColor
end
end
self._originalBaseplateColor = nil
end
if self._scanConnection then
if self._scanRunning then
self._scanRunning = false
end
task.cancel(self._scanConnection)
self._scanConnection = nil
end
if self._crabs then
for _, crab in ipairs(self._crabs) do
if crab and crab.Parent then
if self._crabPaths[crab] then
local path = self._crabPaths[crab]
if path.Status == SimplePath.StatusType.Active then
path:Stop()
end
self._crabPaths[crab] = nil
end
crab:Destroy()
end
end
self._crabs = {}
end
self._crabPaths = {}
self._targetedAnimals = {}
self._activeCrabs = 0
local wanderPoints = CollectionService:GetTagged("CrabRaveWanderPoint")
for _, wanderPoint in ipairs(wanderPoints) do
CollectionService:RemoveTag(wanderPoint, "CrabRaveWanderPoint")
CollectionService:RemoveTag(wanderPoint, "CrabRaveStationaryPoint")
CollectionService:RemoveTag(wanderPoint, "CrabRaveWanderingPoint")
end
local crabsFolder = workspace:FindFirstChild("CrabRaveCrabs")
if crabsFolder then
crabsFolder:Destroy()
end
self._recentlyHit = {}
end
function CrabRaveEvent:_addSynchronizedHighlights()
-- Create highlights for all crabs at once
local highlights = {}
for _, crab in ipairs(self._crabs) do
if crab and crab.Parent then
local highlight = Instance.new("Highlight")
highlight.Name = "CrabFlashHighlight"
highlight.FillColor = Color3.new(1, 1, 1) -- Pure white
highlight.OutlineColor = Color3.new(1, 1, 1) -- Pure white
highlight.FillTransparency = 0 -- Start fully visible
highlight.OutlineTransparency = 0 -- Start fully visible
highlight.Parent = crab
table.insert(highlights, highlight)
end
end
-- Start synchronized flashing pattern
task.spawn(function()
-- Flash pattern: 3 cycles of show 0.5s, fade 0.5s
for flashCycle = 1, 3 do
-- Highlights start visible, so hold for 0.5 seconds
task.wait(0.5)
-- Fade out all highlights simultaneously
for _, highlight in ipairs(highlights) do
if highlight and highlight.Parent then
local tweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
local fadeOutTween = TweenService:Create(highlight, tweenInfo, {
FillTransparency = 1,
OutlineTransparency = 1
})
fadeOutTween:Play()
end
end
-- Wait for fade out to complete
task.wait(0.5)
-- If not the last cycle, fade back in immediately
if flashCycle < 3 then
for _, highlight in ipairs(highlights) do
if highlight and highlight.Parent then
highlight.FillTransparency = 0
highlight.OutlineTransparency = 0
end
end
end
end
-- Clean up all highlights after final fade
task.wait(0.1) -- Small delay to ensure final fade completes
for _, highlight in ipairs(highlights) do
if highlight and highlight.Parent then
highlight:Destroy()
end
end
end)
end
function CrabRaveEvent:_addFlashingHighlight(crabModel)
-- This function is no longer used - keeping for compatibility
end
function CrabRaveEvent:_findAnimalByName(animalName)
local roadAnimals = CollectionService:GetTagged("Animal")
local movingAnimalsFolder = workspace:FindFirstChild("MovingAnimals")
for _, animal in ipairs(roadAnimals) do
if animal.Parent == movingAnimalsFolder and animal.Name == animalName then
return animal
end
end
return nil
end
function CrabRaveEvent:_hasClawsTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
return false
end
task.wait(0.01)
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
else
return false
end
end
for _, trait in ipairs(currentTraits) do
if trait == "Claws" then
return true
end
end
return false
end
function CrabRaveEvent:_isAnimalNearEnd(animal)
if not animal or not animal.Parent then
return true
end
local animalRootPart = animal:FindFirstChild("HumanoidRootPart")
if not animalRootPart then
return true
end
local roadEnd = workspace:FindFirstChild("Road")
if roadEnd then
roadEnd = roadEnd:FindFirstChild("End")
if roadEnd then
local distanceToEnd = (animalRootPart.Position - roadEnd.Position).Magnitude
if distanceToEnd <= 25 then
return true
end
end
end
return false
end
function CrabRaveEvent:_applyClawsTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
return
end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
for _, trait in ipairs(currentTraits) do
if trait == "Claws" then
return
end
end
table.insert(currentTraits, "Claws")
animalTemplate:SetAttribute("Traits", HttpService:JSONEncode(currentTraits))
end
function CrabRaveEvent:_createCrabModel(wanderPart, parentFolder)
local crabModel = Instance.new("Model")
crabModel.Name = "Crab_" .. wanderPart.Name .. "_" .. math.random(1000, 9999)
local humanoidRootPart = Instance.new("Part")
humanoidRootPart.Name = "HumanoidRootPart"
humanoidRootPart.Size = Vector3.new(2, 2, 2)
humanoidRootPart.Material = Enum.Material.ForceField
humanoidRootPart.Transparency = 1
humanoidRootPart.CanCollide = false
humanoidRootPart.Anchored = false
local spawnPosition = wanderPart.Position + Vector3.new(0, wanderPart.Size.Y/2 + humanoidRootPart.Size.Y/2, 0)
local rotatedLookVector = CFrame.Angles(0, math.rad(90), 0) * wanderPart.CFrame.LookVector
humanoidRootPart.CFrame = CFrame.new(spawnPosition, spawnPosition + rotatedLookVector)
humanoidRootPart.Parent = crabModel
local humanoid = Instance.new("Humanoid")
humanoid.WalkSpeed = 16
humanoid.Parent = crabModel
crabModel.PrimaryPart = humanoidRootPart
crabModel:SetAttribute("OriginalWanderPosition", wanderPart.Position)
local rotatedLookVector = CFrame.Angles(0, math.rad(90), 0) * wanderPart.CFrame.LookVector
crabModel:SetAttribute("WanderRotation", rotatedLookVector)
crabModel:SetAttribute("OriginalWanderCFrame", wanderPart.CFrame)
crabModel.Parent = parentFolder or workspace.CrabRaveCrabs
CollectionService:AddTag(crabModel, "CrabRaveCrabs")
return crabModel
end
function CrabRaveEvent:_startScanning()
if self._scanConnection then
return
end
self._scanRunning = true
self._scanConnection = task.spawn(function()
task.wait(STARTUP_DELAY)
while self._scanRunning do
task.wait(0.5)
for animalName, crabName in pairs(self._targetedAnimals) do
local animal = nil
for _, a in ipairs(CollectionService:GetTagged("Animal")) do
if a:GetAttribute("Index") == animalName then
animal = a
break
end
end
if not animal or not animal.Parent or self:_hasClawsTrait(animal) or self:_isAnimalNearEnd(animal) then
self._targetedAnimals[animalName] = nil
self._activeCrabs = math.max(0, self._activeCrabs - 1)
end
end
for _, crab in ipairs(self._crabs) do
if not crab.Parent then
continue
end
local humanoidRootPart = crab:FindFirstChild("HumanoidRootPart")
if not humanoidRootPart then
continue
end
local isStationary = crab:GetAttribute("IsStationary")
local isMovingToAnimal = crab:GetAttribute("MovingToAnimal")
local moveStartTime = crab:GetAttribute("MoveStartTime")
if isMovingToAnimal and moveStartTime then
local currentTime = tick()
if currentTime - moveStartTime > 15 then
crab:SetAttribute("MovingToAnimal", false)
crab:SetAttribute("MoveStartTime", nil)
self:_returnCrabToWander(crab)
continue
end
end
if not isMovingToAnimal and crab:GetAttribute("MovingToAnimal") then
crab:SetAttribute("MovingToAnimal", false)
end
local stationaryCooldown = crab:GetAttribute("StationaryCooldown")
if stationaryCooldown and tick() < stationaryCooldown then
continue
end
if isMovingToAnimal or crab:GetAttribute("MovingToAnimal") or self._activeCrabs >= MAX_ACTIVE_CRABS then
continue
end
local animalsInRange = {}
local allAnimals = CollectionService:GetTagged("Animal")
for _, animal in ipairs(allAnimals) do
if not animal.Parent or not CollectionService:HasTag(animal, "Animal") then
continue
end
if self:_isAnimalNearEnd(animal) then
continue
end
local animalRootPart = animal:FindFirstChild("HumanoidRootPart")
local animalName = animal:GetAttribute("Index")
if animalRootPart and animalName and not self._targetedAnimals[animalName] and not self._recentlyHit[animalName] then
local hasClaws = self:_hasClawsTrait(animal)
if not hasClaws and not self._recentlyHit[animalName] then
local distance = (humanoidRootPart.Position - animalRootPart.Position).Magnitude
if distance <= SCAN_RADIUS then
table.insert(animalsInRange, animal)
end
end
end
end
if #animalsInRange > 0 then
local nearestAnimal = nil
local nearestDistance = math.huge
for _, animal in ipairs(animalsInRange) do
local animalRootPart = animal:FindFirstChild("HumanoidRootPart")
if animalRootPart then
local distance = (humanoidRootPart.Position - animalRootPart.Position).Magnitude
if distance < nearestDistance then
nearestDistance = distance
nearestAnimal = animal
end
end
end
local animal = nearestAnimal
local animalName = animal:GetAttribute("Index")
if animalName and animal.Parent and CollectionService:HasTag(animal, "Animal") and not self._targetedAnimals[animalName] and not self:_hasClawsTrait(animal) and not self:_isAnimalNearEnd(animal) then
self._targetedAnimals[animalName] = crab.Name
self._activeCrabs = self._activeCrabs + 1
self:_moveCrabToAnimal(crab, animal)
task.spawn(function()
crab:SetAttribute("Attack", true)
crab:SetAttribute("ReturnToWander", true)
end)
end
end
end
for animalName, _ in pairs(self._recentlyHit) do
local animal = workspace:FindFirstChild(animalName)
if not animal or not CollectionService:HasTag(animal, "Animal") then
self._recentlyHit[animalName] = nil
end
end
local actualActiveCrabs = 0
for _, crab in ipairs(self._crabs) do
if crab.Parent and crab:GetAttribute("MovingToAnimal") then
actualActiveCrabs = actualActiveCrabs + 1
end
end
self._activeCrabs = actualActiveCrabs
end
end)
end
function CrabRaveEvent:_moveCrabToAnimal(crab, animal)
local humanoidRootPart = crab:FindFirstChild("HumanoidRootPart")
local humanoid = crab:FindFirstChild("Humanoid")
local animalRootPart = animal:FindFirstChild("HumanoidRootPart")
if not humanoidRootPart or not humanoid or not animalRootPart then
return
end
local animalName = animal:GetAttribute("Index")
local animalSpeed = 0
if animal:FindFirstChild("Humanoid") then
animalSpeed = animal.Humanoid.WalkSpeed
end
local dynamicCrabSpeed = math.max(MOVEMENT_SPEED, animalSpeed * 1.5)
humanoid.WalkSpeed = dynamicCrabSpeed
crab:SetAttribute("MovingToAnimal", true)
crab:SetAttribute("MoveStartTime", tick())
if self._crabPaths[crab] then
local path = self._crabPaths[crab]
if path.Status == SimplePath.StatusType.Active then
path:Stop()
end
self._crabPaths[crab] = nil
end
local path = SimplePath.new(crab)
path.Visualize = false
self._crabPaths[crab] = path
local animalVelocity = Vector3.new(0, 0, 0)
if animal:FindFirstChild("Humanoid") and animal.Humanoid.MoveDirection.Magnitude > 0 then
animalVelocity = animal.Humanoid.MoveDirection * animal.Humanoid.WalkSpeed
end
local distanceToAnimal = (humanoidRootPart.Position - animalRootPart.Position).Magnitude
local estimatedTravelTime = distanceToAnimal / dynamicCrabSpeed
local predictedPosition = animalRootPart.Position + (animalVelocity * estimatedTravelTime)
path:Run(predictedPosition)
local startTime = tick()
local CHASE_TIMEOUT = 20
local lastValidationTime = 0
local VALIDATION_INTERVAL = 5
local hitConnection
hitConnection = RunService.Heartbeat:Connect(function()
if not crab.Parent or not animal.Parent then
hitConnection:Disconnect()
local animalName = animal:GetAttribute("Index")
if animalName and self._targetedAnimals[animalName] == crab.Name then
self._targetedAnimals[animalName] = nil
self._activeCrabs = math.max(0, self._activeCrabs - 1)
end
crab:SetAttribute("MovingToAnimal", false)
crab:SetAttribute("MoveStartTime", nil)
crab:SetAttribute("LastPathUpdate", nil)
return
end
local currentTime = tick()
if currentTime - lastValidationTime >= VALIDATION_INTERVAL then
lastValidationTime = currentTime
local animalName = animal:GetAttribute("Index")
local isNearEnd = self:_isAnimalNearEnd(animal)
local isTargetedByOther = animalName and self._targetedAnimals[animalName] and self._targetedAnimals[animalName] ~= crab.Name
if isNearEnd or isTargetedByOther then
hitConnection:Disconnect()
crab:SetAttribute("MovingToAnimal", false)
crab:SetAttribute("MoveStartTime", nil)
crab:SetAttribute("LastPathUpdate", nil)
if animalName and self._targetedAnimals[animalName] == crab.Name then
self._targetedAnimals[animalName] = nil
self._activeCrabs = math.max(0, self._activeCrabs - 1)
end
self:_returnCrabToWander(crab)
return
end
end
if tick() - startTime > CHASE_TIMEOUT then
hitConnection:Disconnect()
crab:SetAttribute("MovingToAnimal", false)
crab:SetAttribute("MoveStartTime", nil)
local animalName = animal:GetAttribute("Index")
if animalName and self._targetedAnimals[animalName] then
self._targetedAnimals[animalName] = nil
self._activeCrabs = math.max(0, self._activeCrabs - 1)
end
self:_returnCrabToWander(crab)
return
end
local animalRootPart = animal:FindFirstChild("HumanoidRootPart")
if not animalRootPart then
return
end
local currentAnimalPosition = animalRootPart.Position
local animalVelocity = Vector3.new(0, 0, 0)
if animal:FindFirstChild("Humanoid") and animal.Humanoid.MoveDirection.Magnitude > 0 then
animalVelocity = animal.Humanoid.MoveDirection * animal.Humanoid.WalkSpeed
end
local updatedPredictedPosition = currentAnimalPosition + (animalVelocity * 1.5)
local lastPathUpdate = crab:GetAttribute("LastPathUpdate") or 0
if currentTime - lastPathUpdate >= 0.5 and path.Status == SimplePath.StatusType.Active then
local distanceToTarget = (humanoidRootPart.Position - updatedPredictedPosition).Magnitude
if distanceToTarget > 5 then
path:Run(updatedPredictedPosition)
crab:SetAttribute("LastPathUpdate", currentTime)
end
end
local currentDistance = (humanoidRootPart.Position - animalRootPart.Position).Magnitude
if currentDistance <= HIT_DISTANCE then
hitConnection:Disconnect()
crab:SetAttribute("MovingToAnimal", false)
crab:SetAttribute("MoveStartTime", nil)
local animalName = animal:GetAttribute("Index")
if animalName then
if not self:_hasClawsTrait(animal) and not self._recentlyHit[animalName] then
self._recentlyHit[animalName] = true
local traitApplied = self:_applyClawsTraitDirect(animal)
if traitApplied then
self._hitRemote:FireAllClients(animalName)
task.delay(COOLDOWN_HIT, function()
if self._recentlyHit then
self._recentlyHit[animalName] = nil
end
end)
else
self._recentlyHit[animalName] = nil
end
end
local cooldownTime = 6
crab:SetAttribute("StationaryCooldown", tick() + cooldownTime)
end
task.delay(1, function()
if crab.Parent then
self:_returnCrabToWander(crab)
end
end)
if animalName and self._targetedAnimals[animalName] then
self._targetedAnimals[animalName] = nil
self._activeCrabs = math.max(0, self._activeCrabs - 1)
end
if self._crabPaths[crab] then
local currentPath = self._crabPaths[crab]
if currentPath.Status == SimplePath.StatusType.Active then
currentPath:Stop()
end
end
end
end)
end
function CrabRaveEvent:_returnCrabToWander(crab)
local humanoidRootPart = crab:FindFirstChild("HumanoidRootPart")
local humanoid = crab:FindFirstChild("Humanoid")
local originalPosition = crab:GetAttribute("OriginalWanderPosition")
local originalCFrame = crab:GetAttribute("OriginalWanderCFrame")
local wanderRotation = crab:GetAttribute("WanderRotation")
if not humanoidRootPart or not humanoid then
return
end
humanoid.WalkSpeed = MOVEMENT_SPEED
if not originalPosition then
originalPosition = humanoidRootPart.Position
end
crab:SetAttribute("MovingToAnimal", false)
crab:SetAttribute("ReturnToWander", false)
crab:SetAttribute("MoveStartTime", nil)
if self._crabPaths[crab] then
local path = self._crabPaths[crab]
if path.Status == SimplePath.StatusType.Active then
path:Stop()
end
self._crabPaths[crab] = nil
end
local path = SimplePath.new(crab)
path.Visualize = false
self._crabPaths[crab] = path
local targetPosition = originalPosition + Vector3.new(0, humanoidRootPart.Size.Y/2, 0)
local pathTimeout = 5
local pathStartTime = tick()
path:Run(targetPosition)
path.Reached:Connect(function()
if humanoidRootPart.Parent then
if originalCFrame then
local spawnPosition = originalCFrame.Position + Vector3.new(0, humanoidRootPart.Size.Y/2, 0)
local rotatedLookVector = CFrame.Angles(0, math.rad(90), 0) * originalCFrame.LookVector
humanoidRootPart.CFrame = CFrame.new(spawnPosition, spawnPosition + rotatedLookVector)
elseif wanderRotation then
humanoidRootPart.CFrame = CFrame.new(humanoidRootPart.Position, humanoidRootPart.Position + wanderRotation)
end
end
end)
path.Error:Connect(function(errorMsg)
if humanoidRootPart.Parent then
humanoidRootPart.CFrame = CFrame.new(targetPosition)
end
end)
task.delay(pathTimeout, function()
if tick() - pathStartTime >= pathTimeout and humanoidRootPart.Parent then
if path.Status == SimplePath.StatusType.Active then
path:Stop()
humanoidRootPart.CFrame = CFrame.new(targetPosition)
end
end
end)
end
function CrabRaveEvent:_applyClawsTraitDirect(animal)
local animalName = animal:GetAttribute("Index")
if not animal.Parent or not CollectionService:HasTag(animal, "Animal") then
return false
end
local currentTraits = animal:GetAttribute("Traits")
local traitsTable = {}
if currentTraits then
local success, decoded = pcall(HttpService.JSONDecode, HttpService, currentTraits)
if success and type(decoded) == "table" then
traitsTable = decoded
end
end
local hasClaws = false
for _, trait in ipairs(traitsTable) do
if trait == TRAIT_NAME then
hasClaws = true
break
end
end
if not hasClaws then
table.insert(traitsTable, TRAIT_NAME)
local newTraitsJson = HttpService:JSONEncode(traitsTable)
animal:SetAttribute("Traits", newTraitsJson)
return true
else
return false
end
end
return CrabRaveEvent - Edit
03:12:20.457
- Edit
03:12:20.457
============================== - Edit
03:12:20.457 📜 ServerScriptService.Services.EventService.Events.MatteoEvent - Edit
03:12:20.457 ==============================
- Edit
03:12:20.458 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local DataManagment = require(ServerScriptService.Services.DataManagment)
local RoadAnimalService = require(ServerScriptService.Services.RoadAnimalService)
local Animals = require(ReplicatedStorage.Datas.Animals)
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local MatteoEvent = {}
MatteoEvent.__index = MatteoEvent
function MatteoEvent.new(eventService)
local self = setmetatable({}, MatteoEvent)
self._eventService = eventService
self._matteoSynchronizer = Synchronizer:Create("MatteoEvent", {
TreePositions = {},
IsRainbow = false
})
for _, player in pairs(Players:GetPlayers()) do
self._matteoSynchronizer:AddListener(player)
end
Players.PlayerAdded:Connect(function(player)
self._matteoSynchronizer:AddListener(player)
end)
Players.PlayerRemoving:Connect(function(player)
self._matteoSynchronizer:RemoveListener(player)
end)
self._isActive = false
self._treePositions = {}
self._collectedTrees = {}
self._collectTreeRemote = Net:RemoteFunction("EventService/Matteo/CollectTree")
self._spawnEffectRemote = Net:RemoteEvent("EventService/Matteo/SpawnEffect")
self._collectTreeRemote.OnServerInvoke = function(player, treeId)
return self:_handleTreeCollection(player, treeId)
end
self._spawnEffectRemote.OnServerEvent:Connect(function(player)
self:_handleSpawnEffect(player)
end)
return self
end
function MatteoEvent:Start(eventEntry)
if self._isActive then
return
end
self._isActive = true
self:_generateTreePositions()
local isRainbow = math.random() < 0.1
eventEntry.data.TreePositions = self._treePositions
eventEntry.data.IsRainbow = isRainbow
local spawnTime = workspace:GetServerTimeNow() + 10
for _, player in pairs(Players:GetPlayers()) do
self._spawnEffectRemote:FireClient(player, spawnTime)
end
self._matteoSynchronizer:Set("TreePositions", self._treePositions)
self._matteoSynchronizer:Set("IsRainbow", isRainbow)
task.wait(8)
self:_handleSpawnEffect()
end
function MatteoEvent:Stop(eventEntry)
if not self._isActive then
return
end
self._isActive = false
self._matteoSynchronizer:Set("TreePositions", {})
self._matteoSynchronizer:Set("IsRainbow", false)
self._collectedTrees = {}
self._treePositions = {}
end
function MatteoEvent:_generateTreePositions()
self._treePositions = {}
local treeCount = math.random(15, 25)
local mapCenter = workspace:FindFirstChild("MapCenter")
local baseplate = workspace.Map and workspace.Map:FindFirstChild("Baseplate")
local road = workspace.Map and workspace.Map:FindFirstChild("Road")
local plots = workspace:FindFirstChild("Plots")
if not mapCenter or not baseplate then
for i = 1, treeCount do
self._treePositions[i] = Vector3.new(math.random(-50, 50), 5, math.random(-50, 50))
end
return
end
local baseplateSize = baseplate.Size
local baseplatePos = baseplate.Position
local minX = baseplatePos.X - baseplateSize.X/2
local maxX = baseplatePos.X + baseplateSize.X/2
local minZ = baseplatePos.Z - baseplateSize.Z/2
local maxZ = baseplatePos.Z + baseplateSize.Z/2
local roadBounds = {}
if road then
local roadSize = road.Size
local roadPos = road.Position
roadBounds = {
minX = roadPos.X - roadSize.X/2 - 10,
maxX = roadPos.X + roadSize.X/2 + 10,
minZ = roadPos.Z - roadSize.Z/2 - 10,
maxZ = roadPos.Z + roadSize.Z/2 + 10
}
end
local plotBounds = {}
if plots then
for _, plot in pairs(plots:GetChildren()) do
if plot:IsA("Model") then
local plotCFrame, plotSize = plot:GetBoundingBox()
table.insert(plotBounds, {
minX = plotCFrame.Position.X - plotSize.X/2 - 5,
maxX = plotCFrame.Position.X + plotSize.X/2 + 5,
minZ = plotCFrame.Position.Z - plotSize.Z/2 - 5,
maxZ = plotCFrame.Position.Z + plotSize.Z/2 + 5
})
end
end
end
local workspaceModelBounds = {}
for _, child in pairs(workspace:GetChildren()) do
if child:IsA("Model") and child ~= plots then
local modelCFrame, modelSize = child:GetBoundingBox()
table.insert(workspaceModelBounds, {
minX = modelCFrame.Position.X - modelSize.X/2 - 3,
maxX = modelCFrame.Position.X + modelSize.X/2 + 3,
minZ = modelCFrame.Position.Z - modelSize.Z/2 - 3,
maxZ = modelCFrame.Position.Z + modelSize.Z/2 + 3
})
end
end
local function findGroundY(x, z)
local rayOrigin = Vector3.new(x, 100, z)
local rayDirection = Vector3.new(0, -200, 0)
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
raycastParams.FilterDescendantsInstances = {}
local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
if raycastResult then
return raycastResult.Position.Y
else
local fallbackY = baseplatePos.Y + baseplateSize.Y/2 + 1
return fallbackY
end
end
local attempts = 0
local maxAttempts = treeCount * 10
for i = 1, treeCount do
local validPosition = false
local position
while not validPosition and attempts < maxAttempts do
attempts = attempts + 1
local x = math.random(minX + 20, maxX - 20)
local z = math.random(minZ + 20, maxZ - 20)
local groundY = findGroundY(x, z)
position = Vector3.new(x, groundY, z)
validPosition = true
if roadBounds.minX and x >= roadBounds.minX and x <= roadBounds.maxX and z >= roadBounds.minZ and z <= roadBounds.maxZ then
validPosition = false
end
for _, bounds in pairs(plotBounds) do
if x >= bounds.minX and x <= bounds.maxX and z >= bounds.minZ and z <= bounds.maxZ then
validPosition = false
break
end
end
for _, bounds in pairs(workspaceModelBounds) do
if x >= bounds.minX and x <= bounds.maxX and z >= bounds.minZ and z <= bounds.maxZ then
validPosition = false
break
end
end
for j = 1, i - 1 do
if self._treePositions[j] then
local distance = (position - self._treePositions[j]).Magnitude
if distance < 15 then
validPosition = false
break
end
end
end
end
if validPosition then
self._treePositions[i] = position
else
local fallbackX = mapCenter.Position.X + math.random(-30, 30)
local fallbackZ = mapCenter.Position.Z + math.random(-30, 30)
local fallbackY = findGroundY(fallbackX, fallbackZ)
self._treePositions[i] = Vector3.new(fallbackX, fallbackY, fallbackZ)
end
end
end
function MatteoEvent:_handleTreeCollection(player, treeId)
if not self._isActive then
return false
end
if player.Character and player.Character:GetAttribute("Matteo_CollectedTree") then
return false
end
if not self._treePositions[treeId] then
return false
end
if self._collectedTrees[treeId] then
return false
end
self._collectedTrees[treeId] = true
player.Character:SetAttribute("Matteo_CollectedTree", true)
local activeEvents = Synchronizer:Get("ActiveEvents")
if activeEvents then
for i, eventData in pairs(activeEvents) do
if eventData.eventName == "Matteo" and eventData.data and eventData.data.TreePositions then
eventData.data.TreePositions[treeId] = nil
Synchronizer:Set("ActiveEvents", activeEvents)
break
end
end
end
local treeToolSuccess = self:_giveTreeTool(player, treeId)
if not treeToolSuccess then
end
return true
end
local function createHitbox(character)
local root = character:FindFirstChild("HumanoidRootPart")
if not root then return end
local size = Vector3.new(5,5,5)
local cframe = root.CFrame * CFrame.new(0,0,-3)
return Region3.new(cframe.Position - size/2, cframe.Position + size/2)
end
local function getTargets(character)
local region = createHitbox(character)
if not region then return {} end
local parts = workspace:FindPartsInRegion3(region, character, 10)
local t = {}
for _, part in ipairs(parts) do
local char = part.Parent
local h = char:FindFirstChild("Humanoid")
if h and h.Health > 0 and char ~= character and not t[char] then
t[char] = h
end
end
return t
end
local cooldowns = {}
local function applySlap(player, target, direction)
local h = target:FindFirstChild("Humanoid")
local root = target:FindFirstChild("HumanoidRootPart")
if not h or not root or h.Health <= 0 then return end
h:TakeDamage(0)
local force = 900 * 0.10
local upwardForce = Vector3.new(0, 10, 0)
local bv = Instance.new("BodyVelocity")
bv.Velocity = direction.Unit * force + upwardForce
bv.MaxForce = Vector3.new(1e5, 1e5, 1e5)
bv.Parent = root
local targetPlayer = Players:GetPlayerFromCharacter(target)
if targetPlayer then
targetPlayer:SetAttribute("Stealing", false)
end
game.Debris:AddItem(bv, 0.2)
RagdollModule.TimedRagdoll(target, 3)
end
local animation = Instance.new("Animation")
animation.AnimationId = "rbxassetid://123619834948143"
local animationTrack
function MatteoEvent:_giveTreeTool(player, treeId)
local backpack = player:FindFirstChild("Backpack")
if not backpack then
return false
end
local matteoModels = ReplicatedStorage:FindFirstChild("Models")
if not matteoModels then
return false
end
local eventsFolder = matteoModels:FindFirstChild("Events")
if not eventsFolder then
return false
end
local matteoFolder = eventsFolder:FindFirstChild("Matteo")
if not matteoFolder then
return false
end
local normalTrees = matteoFolder:FindFirstChild("NormalTrees")
if not normalTrees then
return false
end
local treeNames = {"Tree1", "Tree2", "Tree3", "Tree4", "Tree5"}
local randomTreeName = treeNames[math.random(1, #treeNames)]
local treeModel = normalTrees:FindFirstChild(randomTreeName)
if not treeModel then
return false
end
local treeTool = Instance.new("Tool")
treeTool.Name = "Tree"
treeTool.RequiresHandle = true
local treeClone = treeModel:Clone()
local handle = treeClone:FindFirstChild("Handle")
if not handle then
handle = Instance.new("Part")
handle.Name = "Handle"
handle.Size = Vector3.new(0.2, 1, 0.2)
handle.Material = Enum.Material.Wood
handle.BrickColor = BrickColor.new("Brown")
handle.CanCollide = false
handle.Anchored = false
handle.Parent = treeTool
else
handle.CanCollide = false
handle.Anchored = false
handle.Parent = treeTool
end
local function moveAndWeldPart(part)
if part:IsA("BasePart") and part ~= handle then
part.CanCollide = false
part.Anchored = false
part.Parent = treeTool
local weld = Instance.new("WeldConstraint")
weld.Part0 = handle
weld.Part1 = part
weld.Parent = handle
end
end
for _, part in pairs(treeClone:GetDescendants()) do
moveAndWeldPart(part)
end
treeClone:Destroy()
treeTool.Parent = backpack
treeTool.Activated:Connect(function()
local char = treeTool.Parent
local player = Players:GetPlayerFromCharacter(char)
if not player or not char:FindFirstChild("HumanoidRootPart") then return end
local last = cooldowns[player.UserId] or 0
if os.clock() - last < 2 then return end
cooldowns[player.UserId] = os.clock()
local humanoid = char:FindFirstChild("Humanoid")
if humanoid then
animationTrack = humanoid:LoadAnimation(animation)
animationTrack:Play()
end
local dir = char.HumanoidRootPart.CFrame.LookVector
for target in pairs(getTargets(char)) do
applySlap(player, target, dir)
end
end)
return true
end
function MatteoEvent:_handleSpawnEffect(player)
if not self._isActive then
return
end
local matteoIndex = self:_getMatteoAnimalIndex()
if matteoIndex then
local roadAnimalService = _G.RoadAnimalService
local spawnedAnimal = roadAnimalService.Spawner:SpawnSpecificAnimal(matteoIndex, nil)
else
warn("[MatteoEvent] Could not find Matteo animal index")
end
end
function MatteoEvent:_getMatteoAnimalIndex()
for index, animalData in pairs(Animals) do
if animalData.DisplayName == "Matteo" then
return index
end
end
return nil
end
return MatteoEvent - Edit
03:12:20.458
- Edit
03:12:20.458
============================== - Edit
03:12:20.458 📜 ServerScriptService.Services.EventService.Events.Rap Concert - Edit
03:12:20.458 ==============================
- Edit
03:12:20.458 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local HttpService = game:GetService("HttpService")
local CollectionService = game:GetService("CollectionService")
local Workspace = game:GetService("Workspace")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local DataManagment = require(ServerScriptService.Services.DataManagment)
local RoadAnimalService = require(ServerScriptService.Services.RoadAnimalService)
local Animals = require(ReplicatedStorage.Datas.Animals)
local ConcertEvent = {}
ConcertEvent.__index = ConcertEvent
function ConcertEvent.new(eventService)
local self = setmetatable({}, ConcertEvent)
self._eventService = eventService
self._synchronizer = eventService._synchronizer
self._concertSynchronizer = Synchronizer:Create("RapConcert", { IsActive = false })
for _, player in pairs(Players:GetPlayers()) do
self._concertSynchronizer:AddListener(player)
end
Players.PlayerAdded:Connect(function(player)
self._concertSynchronizer:AddListener(player)
end)
Players.PlayerRemoving:Connect(function(player)
self._concertSynchronizer:RemoveListener(player)
end)
self._isActive = false
self._shootRemote = Net:RemoteEvent("EventService/Rap Concert/Shoot")
self._recentlyTargeted = {}
self._shootRemote.OnServerEvent:Connect(function(player, rigIndex, animalName, hitTime)
self:_handleAnimalHit(player, rigIndex, animalName, hitTime)
end)
return self
end
function ConcertEvent:Start(eventEntry)
if self._isActive then
return
end
self._isActive = true
ReplicatedStorage:SetAttribute("RapConcertEvent", true)
self._concertSynchronizer:Set("IsActive", true)
self:_startShootingLoop()
end
function ConcertEvent:Stop(eventEntry)
if not self._isActive then
return
end
self._isActive = false
ReplicatedStorage:SetAttribute("RapConcertEvent", false)
self._concertSynchronizer:Set("IsActive", false)
if self._shootTask then
task.cancel(self._shootTask)
self._shootTask = nil
end
end
function ConcertEvent:_startShootingLoop()
if self._shootTask then
task.cancel(self._shootTask)
end
self._shootTask = task.spawn(function()
while self._isActive do
local waitTime = math.random(1.5, 5)
task.wait(waitTime)
local targetAnimal = self:_pickTargetAnimal()
if targetAnimal then
local rigIndex = math.random(1,3)
local currentTime = Workspace:GetServerTimeNow()
self._shootRemote:FireAllClients(rigIndex, targetAnimal.Name, currentTime + 3)
self._recentlyTargeted[targetAnimal.Name] = currentTime
end
end
end)
end
function ConcertEvent:_pickTargetAnimal()
local roadAnimals = CollectionService:GetTagged("Animal")
local movingAnimalsFolder = Workspace:FindFirstChild("MovingAnimals")
if not movingAnimalsFolder then
return nil
end
local currentTime = Workspace:GetServerTimeNow()
for animalName, lastTime in pairs(self._recentlyTargeted) do
if (currentTime - lastTime) > 10 then
self._recentlyTargeted[animalName] = nil
end
end
local candidates = {}
for _, animal in ipairs(roadAnimals) do
if animal.Parent == movingAnimalsFolder and animal.PrimaryPart and string.find(animal.Name, "RoadAnimal_") then
if not self._recentlyTargeted[animal.Name] and not self:_hasDiscoTrait(animal) then
table.insert(candidates, animal)
end
end
end
if #candidates == 0 then
return nil
end
return candidates[math.random(1,#candidates)]
end
function ConcertEvent:_handleAnimalHit(player, rigIndex, animalName, hitTime)
if not self._isActive then
return
end
local movingAnimalsFolder = Workspace:FindFirstChild("MovingAnimals")
if not movingAnimalsFolder then
return
end
local targetAnimal = movingAnimalsFolder:FindFirstChild(animalName)
if targetAnimal then
self:_applyDiscoTrait(targetAnimal)
end
end
function ConcertEvent:_hasDiscoTrait(animal)
if not animal or not animal.Parent then return false end
local traitsJson = animal:GetAttribute("Traits")
if not traitsJson then return false end
local success, decoded = pcall(function()
return HttpService:JSONDecode(traitsJson)
end)
if not success or type(decoded) ~= "table" then return false end
for _, trait in ipairs(decoded) do
if trait == "Disco" then return true end
end
return false
end
function ConcertEvent:_applyDiscoTrait(animal)
if not animal or not animal.Parent then
return
end
local traitsJson = animal:GetAttribute("Traits")
local traits = {}
if traitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(traitsJson)
end)
if success and type(decoded) == "table" then
traits = decoded
end
end
for _, trait in ipairs(traits) do
if trait == "Disco" then
return
end
end
table.insert(traits, "Disco")
local encoded = HttpService:JSONEncode(traits)
animal:SetAttribute("Traits", encoded)
end
return ConcertEvent - Edit
03:12:20.458
- Edit
03:12:20.458
============================== - Edit
03:12:20.458 📜 ServerScriptService.Services.EventService.Events.Concert - Edit
03:12:20.458 ==============================
- Edit
03:12:20.458 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local HttpService = game:GetService("HttpService")
local CollectionService = game:GetService("CollectionService")
local Workspace = game:GetService("Workspace")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local DataManagment = require(ServerScriptService.Services.DataManagment)
local RoadAnimalService = require(ServerScriptService.Services.RoadAnimalService)
local Animals = require(ReplicatedStorage.Datas.Animals)
local ConcertEvent = {}
ConcertEvent.__index = ConcertEvent
function ConcertEvent.new(eventService)
local self = setmetatable({}, ConcertEvent)
self._eventService = eventService
self._synchronizer = eventService._synchronizer
self._concertSynchronizer = Synchronizer:Create("ConcertEvent", { IsActive = false })
for _, player in pairs(Players:GetPlayers()) do
self._concertSynchronizer:AddListener(player)
end
Players.PlayerAdded:Connect(function(player)
self._concertSynchronizer:AddListener(player)
end)
Players.PlayerRemoving:Connect(function(player)
self._concertSynchronizer:RemoveListener(player)
end)
self._isActive = false
self._shootRemote = Net:RemoteEvent("EventService/Concert/Shoot")
self._recentlyTargeted = {}
self._shootRemote.OnServerEvent:Connect(function(player, rigIndex, animalName, hitTime)
self:_handleAnimalHit(player, rigIndex, animalName, hitTime)
end)
return self
end
function ConcertEvent:Start(eventEntry)
if self._isActive then
return
end
self._isActive = true
ReplicatedStorage:SetAttribute("ConcertEvent", true)
self._concertSynchronizer:Set("IsActive", true)
self:_startShootingLoop()
end
function ConcertEvent:Stop(eventEntry)
if not self._isActive then
return
end
self._isActive = false
ReplicatedStorage:SetAttribute("ConcertEvent", false)
self._concertSynchronizer:Set("IsActive", false)
if self._shootTask then
task.cancel(self._shootTask)
self._shootTask = nil
end
end
function ConcertEvent:_startShootingLoop()
if self._shootTask then
task.cancel(self._shootTask)
end
self._shootTask = task.spawn(function()
while self._isActive do
local waitTime = math.random(1.5, 5)
task.wait(waitTime)
local targetAnimal = self:_pickTargetAnimal()
if targetAnimal then
local rigIndex = math.random(1,3)
local currentTime = Workspace:GetServerTimeNow()
self._shootRemote:FireAllClients(rigIndex, targetAnimal.Name, currentTime + 3)
self._recentlyTargeted[targetAnimal.Name] = currentTime
end
end
end)
end
function ConcertEvent:_pickTargetAnimal()
local roadAnimals = CollectionService:GetTagged("Animal")
local movingAnimalsFolder = Workspace:FindFirstChild("MovingAnimals")
if not movingAnimalsFolder then
return nil
end
local currentTime = Workspace:GetServerTimeNow()
for animalName, lastTime in pairs(self._recentlyTargeted) do
if (currentTime - lastTime) > 10 then
self._recentlyTargeted[animalName] = nil
end
end
local candidates = {}
for _, animal in ipairs(roadAnimals) do
if animal.Parent == movingAnimalsFolder and animal.PrimaryPart and string.find(animal.Name, "RoadAnimal_") then
if not self._recentlyTargeted[animal.Name] and not self:_hasDiscoTrait(animal) then
table.insert(candidates, animal)
end
end
end
if #candidates == 0 then
return nil
end
return candidates[math.random(1,#candidates)]
end
function ConcertEvent:_handleAnimalHit(player, rigIndex, animalName, hitTime)
if not self._isActive then
return
end
local movingAnimalsFolder = Workspace:FindFirstChild("MovingAnimals")
if not movingAnimalsFolder then
return
end
local targetAnimal = movingAnimalsFolder:FindFirstChild(animalName)
if targetAnimal then
self:_applyDiscoTrait(targetAnimal)
end
end
function ConcertEvent:_hasDiscoTrait(animal)
if not animal or not animal.Parent then return false end
local traitsJson = animal:GetAttribute("Traits")
if not traitsJson then return false end
local success, decoded = pcall(function()
return HttpService:JSONDecode(traitsJson)
end)
if not success or type(decoded) ~= "table" then return false end
for _, trait in ipairs(decoded) do
if trait == "Disco" then return true end
end
return false
end
function ConcertEvent:_applyDiscoTrait(animal)
if not animal or not animal.Parent then
return
end
local traitsJson = animal:GetAttribute("Traits")
local traits = {}
if traitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(traitsJson)
end)
if success and type(decoded) == "table" then
traits = decoded
end
end
for _, trait in ipairs(traits) do
if trait == "Disco" then
return
end
end
table.insert(traits, "Disco")
local encoded = HttpService:JSONEncode(traits)
animal:SetAttribute("Traits", encoded)
end
return ConcertEvent - Edit
03:12:20.458
- Edit
03:12:20.458
============================== - Edit
03:12:20.458 📜 ServerScriptService.Services.EventService.Events.Snow - Edit
03:12:20.458 ==============================
- Edit
03:12:20.459 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local HttpService = game:GetService("HttpService")
local CollectionService = game:GetService("CollectionService")
local RunService = game:GetService("RunService")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local DataManagment = require(ServerScriptService.Services.DataManagment)
local RoadAnimalService = require(ServerScriptService.Services.RoadAnimalService)
local Animals = require(ReplicatedStorage.Datas.Animals)
local SnowEvent = {}
SnowEvent.__index = SnowEvent
function SnowEvent.new(eventService)
local self = setmetatable({}, SnowEvent)
self._eventService = eventService
self._synchronizer = eventService._synchronizer
self._snowSynchronizer = Synchronizer:Create("SnowEvent", {
IsActive = false
})
for _, player in pairs(Players:GetPlayers()) do
self._snowSynchronizer:AddListener(player)
end
Players.PlayerAdded:Connect(function(player)
self._snowSynchronizer:AddListener(player)
end)
Players.PlayerRemoving:Connect(function(player)
self._snowSynchronizer:RemoveListener(player)
end)
self._isActive = false
local frigginmodulename = script.Parent.Name
self._snowHitRemote = Net:RemoteEvent((("EventService/%*/Hit"):format(frigginmodulename)))
self._recentlyTargeted = {}
self._snowPiles = nil
return self
end
function SnowEvent:Start(eventEntry)
if self._isActive then
return
end
self._isActive = true
ReplicatedStorage:SetAttribute("SnowEvent", true)
self._snowSynchronizer:Set("IsActive", true)
self:_spawnSnowPiles()
self:_startSnowLoop()
end
function SnowEvent:_spawnSnowPiles()
local pileTemplate = ReplicatedStorage:FindFirstChild("Models")
and ReplicatedStorage.Models:FindFirstChild("Events")
and ReplicatedStorage.Models.Events:FindFirstChild("Snow")
and ReplicatedStorage.Models.Events.Snow:FindFirstChild("Piles")
if pileTemplate then
self._snowPiles = pileTemplate:Clone()
self._snowPiles.Parent = workspace
end
end
function SnowEvent:_startSnowLoop()
if self._snowTask then
task.cancel(self._snowTask)
end
self._snowTask = task.spawn(function()
task.wait(math.random(2.5, 4))
while self._isActive do
task.wait(math.random(3, 6))
local targetAnimal = self:_pickTargetAnimal()
if targetAnimal then
self:_applySnowTrait(targetAnimal)
self._snowHitRemote:FireAllClients(targetAnimal.Name)
end
end
end)
end
function SnowEvent:_findNearestSnowPile(position)
if not self._snowPiles then
return nil
end
local nearestPile = nil
local nearestDistance = math.huge
for _, pile in pairs(self._snowPiles:GetChildren()) do
if pile:IsA("BasePart") then
local distance = (pile.Position - position).Magnitude
if distance < nearestDistance then
nearestDistance = distance
nearestPile = pile
end
elseif pile:IsA("Model") and pile.PrimaryPart then
local distance = (pile.PrimaryPart.Position - position).Magnitude
if distance < nearestDistance then
nearestDistance = distance
nearestPile = pile.PrimaryPart
end
end
end
return nearestPile
end
function SnowEvent:Stop(eventEntry)
if not self._isActive then
return
end
self._isActive = false
ReplicatedStorage:SetAttribute("SnowEvent", false)
self._snowSynchronizer:Set("IsActive", false)
if self._snowTask then
task.cancel(self._snowTask)
self._snowTask = nil
end
if self._snowPiles then
self._snowPiles:Destroy()
self._snowPiles = nil
end
end
function SnowEvent:_pickTargetAnimal()
local roadAnimals = CollectionService:GetTagged("Animal")
local movingAnimalsFolder = workspace:FindFirstChild("MovingAnimals")
local currentTime = workspace:GetServerTimeNow()
for animalName, lastTime in pairs(self._recentlyTargeted) do
if (currentTime - lastTime) > 25 then
self._recentlyTargeted[animalName] = nil
end
end
local candidates = {}
for _, animal in ipairs(roadAnimals) do
if animal.Parent == movingAnimalsFolder and animal.PrimaryPart and string.find(animal.Name, "RoadAnimal_") then
if not self._recentlyTargeted[animal.Name] and not self:_hasSnowTrait(animal) then
table.insert(candidates, animal)
end
end
end
if #candidates == 0 then return nil end
return candidates[math.random(1, #candidates)]
end
function SnowEvent:_hasSnowTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
return false
end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
for _, trait in ipairs(currentTraits) do
if trait == "Snowy" then
return true
end
end
return false
end
function SnowEvent:_applySnowTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
return
end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
for _, trait in ipairs(currentTraits) do
if trait == "Snowy" then
return
end
end
table.insert(currentTraits, "Snowy")
animalTemplate:SetAttribute("Traits", HttpService:JSONEncode(currentTraits))
end
return SnowEvent - Edit
03:12:20.459
- Edit
03:12:20.459
============================== - Edit
03:12:20.459 📜 ServerScriptService.Services.EventService.Events.10B Visits - Edit
03:12:20.459 ==============================
- Edit
03:12:20.459 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local HttpService = game:GetService("HttpService")
local CollectionService = game:GetService("CollectionService")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local DataManagment = require(ServerScriptService.Services.DataManagment)
local RoadAnimalService = require(ServerScriptService.Services.RoadAnimalService)
local Animals = require(ReplicatedStorage.Datas.Animals)
local VisitsEvent = {}
VisitsEvent.__index = VisitsEvent
function VisitsEvent.new(eventService)
local self = setmetatable({}, VisitsEvent)
self._eventService = eventService
self._synchronizer = eventService._synchronizer
self._visitsSynchronizer = Synchronizer:Create("10BVisitsEvent", {
IsActive = false
})
for _, player in pairs(Players:GetPlayers()) do
self._visitsSynchronizer:AddListener(player)
end
Players.PlayerAdded:Connect(function(player)
self._visitsSynchronizer:AddListener(player)
end)
Players.PlayerRemoving:Connect(function(player)
self._visitsSynchronizer:RemoveListener(player)
end)
self._isActive = false
-- Remote events for the 10B Visits event
self._createFireworkRemote = Net:RemoteEvent("EventService/10B Visits/CreateFirework")
self._explodeTraitEffectRemote = Net:RemoteEvent("EventService/10B Visits/ExplodeTraitEffect")
self._recentlyTargeted = {}
self._fireworkQueue = {}
return self
end
function VisitsEvent:Start(eventEntry)
if self._isActive then
return
end
self._isActive = true
print("[10BVisitsEvent] Starting 10B Visits event")
ReplicatedStorage:SetAttribute("10BVisitsEvent", true)
self._visitsSynchronizer:Set("IsActive", true)
self:_startFireworkLoop()
end
function VisitsEvent:_startFireworkLoop()
if self._fireworkTask then
task.cancel(self._fireworkTask)
end
self._fireworkTask = task.spawn(function()
while self._isActive do
task.wait(math.random(8, 15)) -- Fireworks spawn less frequently than UFOs
local targetAnimals = self:_pickTargetAnimals()
if #targetAnimals > 0 then
self:_createFireworkShow(targetAnimals)
end
end
end)
end
function VisitsEvent:_createFireworkShow(targetAnimals)
local fireworkData = {}
for i, animal in ipairs(targetAnimals) do
if animal and animal.PrimaryPart then
local fireworkEffect = math.random(1, 5) -- Random firework effect type
local height = math.random(80, 120) -- Random height for variety
fireworkData[i] = {
Chosen = i,
FireworkEffect = fireworkEffect,
Height = height,
Falloffs = self:_generateFalloffs(animal)
}
-- Mark animal as recently targeted
self._recentlyTargeted[animal.Name] = workspace:GetServerTimeNow()
-- Apply the 10B trait after a delay (when firework explodes)
task.spawn(function()
local travelTime = height / 20 * 0.8 -- Same calculation as client
task.wait(travelTime + 1) -- Small additional delay
self:_apply10BTrait(animal)
-- Fire the trait effect
self._explodeTraitEffectRemote:FireAllClients(fireworkEffect, animal.Name)
end)
end
end
-- Send firework data to all clients
self._createFireworkRemote:FireAllClients(fireworkData)
end
function VisitsEvent:_generateFalloffs(animal)
local falloffs = {}
local numFalloffs = math.random(3, 6)
for i = 1, numFalloffs do
if i == 1 then
-- First falloff targets the animal directly
table.insert(falloffs, animal.Name)
else
-- Other falloffs are random positions around the animal
local randomOffset = Vector3.new(
math.random(-30, 30),
0,
math.random(-30, 30)
)
table.insert(falloffs, randomOffset)
end
end
return falloffs
end
function VisitsEvent:Stop(eventEntry)
if not self._isActive then
return
end
self._isActive = false
print("[10BVisitsEvent] Stopping 10B Visits event")
ReplicatedStorage:SetAttribute("10BVisitsEvent", false)
self._visitsSynchronizer:Set("IsActive", false)
if self._fireworkTask then
task.cancel(self._fireworkTask)
self._fireworkTask = nil
end
print("[10BVisitsEvent] 10B Visits event stopped")
end
function VisitsEvent:_pickTargetAnimals()
local roadAnimals = CollectionService:GetTagged("Animal")
local movingAnimalsFolder = workspace:FindFirstChild("MovingAnimals")
local currentTime = workspace:GetServerTimeNow()
-- Clean up old targets
for animalName, lastTime in pairs(self._recentlyTargeted) do
if (currentTime - lastTime) > 60 then -- Longer cooldown for fireworks
self._recentlyTargeted[animalName] = nil
end
end
local candidates = {}
for _, animal in ipairs(roadAnimals) do
if animal.Parent == movingAnimalsFolder and animal.PrimaryPart and string.find(animal.Name, "RoadAnimal_") then
if not self._recentlyTargeted[animal.Name] and not self:_has10BTrait(animal) then
table.insert(candidates, animal)
end
end
end
-- Select multiple animals for firework show (1-3 animals)
local selectedAnimals = {}
local numToSelect = math.min(math.random(1, 3), #candidates)
for i = 1, numToSelect do
if #candidates > 0 then
local randomIndex = math.random(1, #candidates)
local selectedAnimal = candidates[randomIndex]
table.insert(selectedAnimals, selectedAnimal)
table.remove(candidates, randomIndex)
end
end
return selectedAnimals
end
function VisitsEvent:_has10BTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
return false
end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
for _, trait in ipairs(currentTraits) do
if trait == "10B" then
return true
end
end
return false
end
function VisitsEvent:_apply10BTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
return
end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
-- Check if trait already exists
for _, trait in ipairs(currentTraits) do
if trait == "10B" then
return
end
end
-- Add the 10B trait
table.insert(currentTraits, "10B")
animalTemplate:SetAttribute("Traits", HttpService:JSONEncode(currentTraits))
end
return VisitsEvent - Edit
03:12:20.459
- Edit
03:12:20.459
============================== - Edit
03:12:20.459 📜 ServerScriptService.Services.EventService.Events.Glitch - Edit
03:12:20.459 ==============================
- Edit
03:12:20.459 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local HttpService = game:GetService("HttpService")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local DataManagment = require(ServerScriptService.Services.DataManagment)
local RoadAnimalService = require(ServerScriptService.Services.RoadAnimalService)
local Animals = require(ReplicatedStorage.Datas.Animals)
local GlitchEvent = {}
GlitchEvent.__index = GlitchEvent
function GlitchEvent.new(eventService)
local self = setmetatable({}, GlitchEvent)
self._eventService = eventService
self._synchronizer = eventService._synchronizer
self._nyanSynchronizer = Synchronizer:Create("GlitchEvent", {
IsActive = false
})
for _, player in pairs(Players:GetPlayers()) do
self._nyanSynchronizer:AddListener(player)
end
Players.PlayerAdded:Connect(function(player)
self._nyanSynchronizer:AddListener(player)
end)
Players.PlayerRemoving:Connect(function(player)
self._nyanSynchronizer:RemoveListener(player)
end)
self._isActive = false
self._spawnEffectRemote = Net:RemoteEvent("EventService/Glitch/HoleEffect")
--self._strikeRemote = Net:RemoteEvent("EventService/NyanCats/Struck")
self._recentlyTargeted = {}
self._spawnEffectRemote.OnServerEvent:Connect(function(player)
self:_handleSpawnEffect(player)
end)
return self
end
function GlitchEvent:Start(eventEntry)
if self._isActive then
return
end
local GlitchSky = script.Glitch:Clone()
GlitchSky.Parent = game.Workspace
self._isActive = true
print("[GlitchEvent] Starting Nyan Cats event")
ReplicatedStorage:SetAttribute("GlitchEvent", true)
local spawnTime = workspace:GetServerTimeNow() + 1
--for _, player in pairs(Players:GetPlayers()) do
-- self._spawnEffectRemote:FireClient(player, spawnTime)
--end
self._nyanSynchronizer:Set("IsActive", true)
self:_startStrikeLoop()
task.wait(1)
print("[GlitchEvent] Nyan Cats event started successfully")
end
function GlitchEvent:_startStrikeLoop()
if self._strikeTask then
task.cancel(self._strikeTask)
end
self._strikeTask = task.spawn(function()
while self._isActive do
task.wait(math.random(2,4))
local targetAnimal = self:_pickTargetAnimal()
if targetAnimal then
local catIndex = math.random(1,30)
local currentTime = workspace:GetServerTimeNow()
self._spawnEffectRemote:FireAllClients(targetAnimal.Name, currentTime)
self._recentlyTargeted[targetAnimal.Name] = currentTime
task.delay(1.1, function()
self:_applyNyanTrait(targetAnimal)
end)
end
end
end)
end
function GlitchEvent:Stop(eventEntry)
if not self._isActive then
return
end
local Glitchend = game.Workspace:FindFirstChild("Glitch")
Glitchend:Destroy()
self._isActive = false
print("[GlitchEvent] Stopping Nyan Cats event")
ReplicatedStorage:SetAttribute("GlitchEvent", false)
self._nyanSynchronizer:Set("IsActive", false)
if self._strikeTask then
task.cancel(self._strikeTask)
self._strikeTask = nil
end
print("[GlitchEvent] Nyan Cats event stopped")
end
function GlitchEvent:_handleSpawnEffect(player)
if not self._isActive then
return
end
print("[GlitchEvent] Handling spawn effect for", player and player.Name or "server")
end
function GlitchEvent:_pickTargetAnimal()
local CollectionService = game:GetService("CollectionService")
local roadAnimals = CollectionService:GetTagged("Animal")
local movingAnimalsFolder = workspace:FindFirstChild("MovingAnimals")
local currentTime = workspace:GetServerTimeNow()
for animalName, lastTime in pairs(self._recentlyTargeted) do
if (currentTime - lastTime) > 15 then
self._recentlyTargeted[animalName] = nil
end
end
local candidates = {}
for _, animal in ipairs(roadAnimals) do
if animal.Parent == movingAnimalsFolder and animal.PrimaryPart and string.find(animal.Name, "RoadAnimal_") then
if not self._recentlyTargeted[animal.Name] and not self:_hasNyanTrait(animal) then
table.insert(candidates, animal)
end
end
end
if #candidates == 0 then return nil end
return candidates[math.random(1, #candidates)]
end
function GlitchEvent:_hasNyanTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
return false
end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
for _, trait in ipairs(currentTraits) do
if trait == "Glitch" then
return true
end
end
return false
end
function GlitchEvent:_applyNyanTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
return
end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
for _, trait in ipairs(currentTraits) do
if trait == "Glitch" then
return
end
end
table.insert(currentTraits, "Glitch")
warn(currentTraits)
animalTemplate:SetAttribute("Traits", HttpService:JSONEncode(currentTraits))
end
return GlitchEvent - Edit
03:12:20.460
- Edit
03:12:20.460
============================== - Edit
03:12:20.460 📜 ServerScriptService.Services.EventService.Events.Starfall - Edit
03:12:20.460 ==============================
- Edit
03:12:20.460 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local Players = game:GetService("Players")
local Net = require(ReplicatedStorage.Packages.Net)
local Concert = require(ReplicatedStorage.Controllers.EventController.Events.Starfall)
local Module = {}
Module.__index = Module
function Module.new(eventService)
local self = setmetatable({}, Module)
self._eventService = eventService
self._active = false
return self
end
function Module:Start(eventData)
if self._active then return end
self._active = true
self._eventData = eventData or {}
Concert.OnStart()
end
function Concert:Stop()
if not self._active then return end
self._active = false
Concert.OnStop()
end
function Module:Load()
Concert.OnLoad()
end
return Module - Edit
03:12:20.460
- Edit
03:12:20.460
============================== - Edit
03:12:20.460 📜 ServerScriptService.Services.EventService.Events.LosMatteos - Edit
03:12:20.460 ==============================
- Edit
03:12:20.460 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local HttpService = game:GetService("HttpService")
local CollectionService = game:GetService("CollectionService")
local RunService = game:GetService("RunService")
local Workspace = game:GetService("Workspace")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local DataManagment = require(ServerScriptService.Services.DataManagment)
local RoadAnimalService = require(ServerScriptService.Services.RoadAnimalService)
local Animals = require(ReplicatedStorage.Datas.Animals)
local LosMatteosEvent = {}
LosMatteosEvent.__index = LosMatteosEvent
function LosMatteosEvent.new(eventService)
local self = setmetatable({}, LosMatteosEvent)
self._eventService = eventService
self._synchronizer = eventService._synchronizer
self._losMatteosSynchronizer = Synchronizer:Create("LosMatteosEvent", {
IsActive = false
})
for _, player in pairs(Players:GetPlayers()) do
self._losMatteosSynchronizer:AddListener(player)
end
Players.PlayerAdded:Connect(function(player)
self._losMatteosSynchronizer:AddListener(player)
end)
Players.PlayerRemoving:Connect(function(player)
self._losMatteosSynchronizer:RemoveListener(player)
end)
self._isActive = false
self._eventStartTime = nil
self._createLightningBoltRemote = Net:RemoteEvent("EventService/Los Matteos/CreateLightningBolt")
self._recentlyTargeted = {}
self._activeLightningStrikes = {}
self._treeLocation = nil
return self
end
function LosMatteosEvent:Start(eventEntry)
if self._isActive then return end
self._isActive = true
self._eventStartTime = workspace:GetServerTimeNow()
ReplicatedStorage:SetAttribute("LosMatteosEvent", true)
self._losMatteosSynchronizer:Set("IsActive", true)
self:_selectTreeLocation()
self:_startLosMatteosSequence()
end
function LosMatteosEvent:_selectTreeLocation()
local treePossibleLocations = workspace:FindFirstChild("Events")
if treePossibleLocations then
treePossibleLocations = treePossibleLocations:FindFirstChild("Custom")
if treePossibleLocations then
treePossibleLocations = treePossibleLocations:FindFirstChild("TreePossibleLocations")
end
end
if not treePossibleLocations then
warn("[LosMatteosEvent] TreePossibleLocations not found")
self._treeLocation = Vector3.new(0, 0, 0)
return
end
local spawnParts = {}
for _, part in ipairs(treePossibleLocations:GetChildren()) do
if part.Name == "Spawn" and part:IsA("BasePart") then
table.insert(spawnParts, part)
end
end
if #spawnParts > 0 then
local chosenPart = spawnParts[math.random(1, #spawnParts)]
self._treeLocation = chosenPart.Position
else
self._treeLocation = Vector3.new(0, 0, 0)
end
end
function LosMatteosEvent:_startLosMatteosSequence()
if self._losMatteosTask then
task.cancel(self._losMatteosTask)
end
self._losMatteosTask = task.spawn(function()
local eventStartTime = self._eventStartTime
task.wait(math.max(0, eventStartTime + 3 - workspace:GetServerTimeNow()))
ReplicatedStorage:SetAttribute("LosMatteosEventNightTime", true)
task.wait(math.max(0, eventStartTime + 8 - workspace:GetServerTimeNow()))
self:_startLightningLoop()
while self._isActive do
task.wait(1)
end
end)
end
function LosMatteosEvent:_startLightningLoop()
if self._lightningTask then
task.cancel(self._lightningTask)
end
self._lightningTask = task.spawn(function()
while self._isActive do
task.wait(math.random(2, 6))
local shouldTargetAnimal = math.random(1, 100) <= 70
if shouldTargetAnimal then
local targetAnimal = self:_pickTargetAnimal()
if targetAnimal then
self:_createLightningStrike(targetAnimal.PrimaryPart.Position, true, targetAnimal)
else
self:_createRandomLightningStrike()
end
else
self:_createRandomLightningStrike()
end
end
end)
end
function LosMatteosEvent:_createLightningStrike(targetPosition, hitAnimal, targetAnimal)
if targetAnimal and targetAnimal.PrimaryPart then
local primary = targetAnimal.PrimaryPart
targetPosition = Vector3.new(
primary.Position.X,
primary.Position.Y + (primary.Size.Y / 2),
primary.Position.Z
)
end
-- ✅ FIX: Raycast down from sky to ground so the strike hits surface
local rayOrigin = targetPosition + Vector3.new(0, 200, 0)
local rayDirection = Vector3.new(0, -500, 0)
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {}
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
local result = Workspace:Raycast(rayOrigin, rayDirection, raycastParams)
if result then
targetPosition = result.Position
else
targetPosition = Vector3.new(targetPosition.X, 0, targetPosition.Z)
end
local lightningSeed = math.random(1, 1000000)
local skyPosition = targetPosition + Vector3.new(
math.random(-5, 5),
math.random(80, 120),
math.random(-5, 5)
)
self._createLightningBoltRemote:FireAllClients(lightningSeed, skyPosition, targetPosition, hitAnimal)
if hitAnimal and targetAnimal then
local animalId = targetAnimal.Name
self._recentlyTargeted[animalId] = workspace:GetServerTimeNow()
task.delay(0.5, function()
if targetAnimal and targetAnimal.Parent then
self:_applyMatteoHatTrait(targetAnimal)
end
end)
end
end
function LosMatteosEvent:_createRandomLightningStrike()
local losMatteosArea = workspace:FindFirstChild("Events")
if losMatteosArea then
losMatteosArea = losMatteosArea:FindFirstChild("Los Matteos")
if losMatteosArea then
losMatteosArea = losMatteosArea:FindFirstChild("Areas")
end
end
local randomPosition
if losMatteosArea then
local areaParts = losMatteosArea:GetChildren()
if #areaParts > 0 then
local randomPart = areaParts[math.random(1, #areaParts)]
local partPosition = randomPart.Position
local partSize = randomPart.Size
randomPosition = Vector3.new(
partPosition.X + math.random(-partSize.X/2, partSize.X/2),
partPosition.Y + 100, -- start above ground, raycast will fix
partPosition.Z + math.random(-partSize.Z/2, partSize.Z/2)
)
else
randomPosition = Vector3.new(math.random(-100, 100), 100, math.random(-100, 100))
end
else
randomPosition = self._treeLocation + Vector3.new(
math.random(-50, 50),
100,
math.random(-50, 50)
)
end
self:_createLightningStrike(randomPosition, false, nil)
end
function LosMatteosEvent:Stop(eventEntry)
if not self._isActive then return end
self._isActive = false
print("[LosMatteosEvent] Stopping Los Matteos event")
ReplicatedStorage:SetAttribute("LosMatteosEvent", false)
ReplicatedStorage:SetAttribute("LosMatteosEventNightTime", false)
self._losMatteosSynchronizer:Set("IsActive", false)
if self._losMatteosTask then
task.cancel(self._losMatteosTask)
self._losMatteosTask = nil
end
if self._lightningTask then
task.cancel(self._lightningTask)
self._lightningTask = nil
end
print("[LosMatteosEvent] Los Matteos event stopped")
end
function LosMatteosEvent:_pickTargetAnimal()
local roadAnimals = CollectionService:GetTagged("Animal")
local movingAnimalsFolder = workspace:FindFirstChild("MovingAnimals")
local currentTime = workspace:GetServerTimeNow()
for animalId, lastTime in pairs(self._recentlyTargeted) do
if (currentTime - lastTime) > 12 then
self._recentlyTargeted[animalId] = nil
end
end
local candidates = {}
for _, animal in ipairs(roadAnimals) do
if animal.Parent == movingAnimalsFolder and animal.PrimaryPart and string.find(animal.Name, "RoadAnimal_") then
local animalId = animal.Name
if not self._recentlyTargeted[animalId] and not self:_hasMatteoHatTrait(animal) then
table.insert(candidates, animal)
end
end
end
if #candidates == 0 then return nil end
return candidates[math.random(1, #candidates)]
end
function LosMatteosEvent:_hasMatteoHatTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then return false end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
for _, trait in ipairs(currentTraits) do
if trait == "Matteo Hat" then
return true
end
end
return false
end
function LosMatteosEvent:_applyMatteoHatTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then return end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
for _, trait in ipairs(currentTraits) do
if trait == "Matteo Hat" then return end
end
table.insert(currentTraits, "Matteo Hat")
animalTemplate:SetAttribute("Traits", HttpService:JSONEncode(currentTraits))
end
return LosMatteosEvent - Edit
03:12:20.460
- Edit
03:12:20.460
============================== - Edit
03:12:20.460 📜 ServerScriptService.Services.EventService.Events.Brazil - Edit
03:12:20.460 ==============================
- Edit
03:12:20.460 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local HttpService = game:GetService("HttpService")
local CollectionService = game:GetService("CollectionService")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local DataManagment = require(ServerScriptService.Services.DataManagment)
local RoadAnimalService = require(ServerScriptService.Services.RoadAnimalService)
local Animals = require(ReplicatedStorage.Datas.Animals)
local BrazilEvent = {}
BrazilEvent.__index = BrazilEvent
function BrazilEvent.new(eventService)
local self = setmetatable({}, BrazilEvent)
self._eventService = eventService
self._synchronizer = eventService._synchronizer
self._brazilSynchronizer = Synchronizer:Create("BrazilEvent", {
IsActive = false
})
for _, player in pairs(Players:GetPlayers()) do
self._brazilSynchronizer:AddListener(player)
end
Players.PlayerAdded:Connect(function(player)
self._brazilSynchronizer:AddListener(player)
end)
Players.PlayerRemoving:Connect(function(player)
self._brazilSynchronizer:RemoveListener(player)
end)
self._isActive = false
-- Brazil Remote Events (matching the client script)
self._brazilFocusRemote = Net:RemoteEvent("EventService/Brazil/Focus")
self._brazilBurstRemote = Net:RemoteEvent("EventService/Brazil/Burst")
self._recentlyTargeted = {}
self._activeBrazilHitboxes = {}
self._eventStartTime = nil
return self
end
function BrazilEvent:Start(eventEntry)
if self._isActive then
return
end
self._isActive = true
self._eventStartTime = workspace:GetServerTimeNow()
print("[BrazilEvent] Starting Brazil event")
ReplicatedStorage:SetAttribute("BrazilEvent", true)
self._brazilSynchronizer:Set("IsActive", true)
self:_startBrazilSequence()
print("[BrazilEvent] Brazil event started successfully")
end
function BrazilEvent:_startBrazilSequence()
if self._brazilTask then
task.cancel(self._brazilTask)
end
self._brazilTask = task.spawn(function()
-- Wait for initial setup phase (5 seconds)
task.wait(5)
-- Start the main targeting loop
while self._isActive do
local currentTime = workspace:GetServerTimeNow()
local eventRunTime = currentTime - self._eventStartTime
-- Different phases of the event
if eventRunTime >= 6 and eventRunTime <= 85 then -- Main active phase
task.wait(math.random(3, 7)) -- Brazil cubes spawn every 3-7 seconds
local targetAnimal = self:_pickTargetAnimal()
if targetAnimal then
self:_createBrazilHitbox(targetAnimal)
end
elseif eventRunTime > 85 then
-- Event is winding down, less frequent targeting
task.wait(math.random(8, 12))
local targetAnimal = self:_pickTargetAnimal()
if targetAnimal then
self:_createBrazilHitbox(targetAnimal)
end
else
task.wait(1) -- Wait during setup phase
end
end
end)
end
function BrazilEvent:_createBrazilHitbox(targetAnimal)
if not targetAnimal or not targetAnimal.PrimaryPart then
return
end
local animalId = targetAnimal.Name
local animalPosition = targetAnimal.PrimaryPart.Position
-- Create Brazil hitbox part
local hitboxPart = Instance.new("Part")
hitboxPart.Name = "BrazilHitbox_" .. animalId
hitboxPart.Size = Vector3.new(1,1,1) -- Cube size matching the client
hitboxPart.Transparency = 1 -- Invisible on server
hitboxPart.Anchored = true
hitboxPart.CanCollide = false
hitboxPart.CFrame = CFrame.new(animalPosition.X, animalPosition.Y + 9, animalPosition.Z)
-- Add the tag that the client script observes
CollectionService:AddTag(hitboxPart, "BrazilHitbox")
hitboxPart.Parent = workspace
self._activeBrazilHitboxes[animalId] = hitboxPart
self._recentlyTargeted[animalId] = workspace:GetServerTimeNow()
-- Start the Brazil sequence for this animal
task.spawn(function()
-- Phase 1: Focus on the animal (sends animal ID to client)
local focusTime = workspace:GetServerTimeNow() + 1 -- 1 second delay before focusing
hitboxPart:SetAttribute("Focused", focusTime)
-- Send focus event to clients
self._brazilFocusRemote:FireAllClients(animalId)
-- Phase 2: Wait for the cube animation and effects (about 3 seconds total)
task.wait(3)
-- Phase 3: Apply Brazil trait and fire burst effect
self:_applyBrazilTrait(targetAnimal)
self._brazilBurstRemote:FireAllClients(animalId)
-- Phase 4: Clean up after a delay
task.wait(2)
self:_removeBrazilHitbox(animalId)
end)
end
function BrazilEvent:_removeBrazilHitbox(animalId)
local hitboxPart = self._activeBrazilHitboxes[animalId]
if hitboxPart then
hitboxPart:Destroy()
self._activeBrazilHitboxes[animalId] = nil
end
end
function BrazilEvent:Stop(eventEntry)
if not self._isActive then
return
end
self._isActive = false
print("[BrazilEvent] Stopping Brazil event")
ReplicatedStorage:SetAttribute("BrazilEvent", false)
self._brazilSynchronizer:Set("IsActive", false)
if self._brazilTask then
task.cancel(self._brazilTask)
self._brazilTask = nil
end
-- Clean up all active hitboxes
for animalId, hitboxPart in pairs(self._activeBrazilHitboxes) do
if hitboxPart then
hitboxPart:Destroy()
end
end
self._activeBrazilHitboxes = {}
print("[BrazilEvent] Brazil event stopped")
end
function BrazilEvent:_pickTargetAnimal()
local roadAnimals = CollectionService:GetTagged("Animal")
local movingAnimalsFolder = workspace:FindFirstChild("MovingAnimals")
local currentTime = workspace:GetServerTimeNow()
-- Clean up old targets (longer cooldown for Brazil event)
for animalId, lastTime in pairs(self._recentlyTargeted) do
if (currentTime - lastTime) > 20 then -- 20 second cooldown
self._recentlyTargeted[animalId] = nil
end
end
local candidates = {}
for _, animal in ipairs(roadAnimals) do
if animal.Parent == movingAnimalsFolder and animal.PrimaryPart and string.find(animal.Name, "RoadAnimal_") then
local animalId = animal.Name
if not self._recentlyTargeted[animalId] and
not self:_hasBrazilTrait(animal) and
not self._activeBrazilHitboxes[animalId] then
table.insert(candidates, animal)
end
end
end
if #candidates == 0 then return nil end
return candidates[math.random(1, #candidates)]
end
function BrazilEvent:_hasBrazilTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
return false
end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
for _, trait in ipairs(currentTraits) do
if trait == "Brazil" then
return true
end
end
return false
end
function BrazilEvent:_applyBrazilTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
return
end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
for _, trait in ipairs(currentTraits) do
if trait == "Brazil" then
return
end
end
table.insert(currentTraits, "Brazil")
animalTemplate:SetAttribute("Traits", HttpService:JSONEncode(currentTraits))
end
return BrazilEvent - Edit
03:12:20.460
- Edit
03:12:20.460
============================== - Edit
03:12:20.460 📜 ServerScriptService.Services.EventService.Events.Water - Edit
03:12:20.460 ==============================
- Edit
03:12:20.461 --[[
Water Event:
- Sólo el animal impactado por StruckVFX recibe el trait "Shark Fin".
- El evento pone de noche y atmósfera azul; vuelve a la normalidad al terminar.
- Reproduce Workspace.Sound.Events.Water2.WaterMusic mientras está activo el evento y lo detiene al terminar.
]]
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local CollectionService = game:GetService("CollectionService")
local HttpService = game:GetService("HttpService")
local ServerStorage = game:GetService("ServerStorage")
local Net = require(ReplicatedStorage.Packages.Net)
local WaterHitRemote = Net:RemoteEvent("EventService/Water/Burst")
local COOLDOWN_TIME = 0
local Workspace = game:GetService("Workspace")
local Lighting = game:GetService("Lighting")
local NPC_NAME = "Orcalero Orcala"
local NUM_ORCALEROS = 3
local SHARKS_FOLDER_NAME = "Sharks"
local ROUTE_FOLDER = Workspace:WaitForChild("Events"):WaitForChild("Water")
local ORCALERO_SPEED = 4.2
local ORIGINAL_GRAVITY = Workspace.Gravity
local ORIGINAL_AMBIENT = Lighting.Ambient
local ORIGINAL_OUTDOOR_AMBIENT = Lighting.OutdoorAmbient
local ORIGINAL_CLOCKTIME = Lighting.ClockTime
local BLUE_AMBIENT = Color3.fromRGB(50, 120, 200)
local BLUE_OUTDOOR = Color3.fromRGB(80, 120, 220)
local LOW_GRAVITY = 50
local NIGHT_CLOCKTIME = 0
local NPCState = {}
local BodyMoverRefs = {}
local SpawnedNPCs = {}
local npcShootConnections = {}
local floatTasks = {}
-- --- MUSICA ---
local function playWaterMusic()
local music = Workspace:FindFirstChild("Sound")
and Workspace.Sound:FindFirstChild("Events")
and Workspace.Sound.Events:FindFirstChild("Water2")
and Workspace.Sound.Events.Water2:FindFirstChild("WaterMusic")
if music then
music.Looped = true
music.Volume = 1
music:Play()
end
end
local function stopWaterMusic()
local music = Workspace:FindFirstChild("Sound")
and Workspace.Sound:FindFirstChild("Events")
and Workspace.Sound.Events:FindFirstChild("Water2")
and Workspace.Sound.Events.Water2:FindFirstChild("WaterMusic")
if music then
music:Stop()
end
end
local function getRouteParts()
local parts = {}
for i = 1, 8 do
local part = ROUTE_FOLDER:FindFirstChild("Part"..i)
if part and part:IsA("BasePart") then
table.insert(parts, part)
end
end
return parts
end
local function getAnimals()
local movingAnimalsFolder = Workspace:FindFirstChild("MovingAnimals")
local animals = {}
if movingAnimalsFolder then
for _, animal in ipairs(movingAnimalsFolder:GetChildren()) do
if animal:IsA("Model") and animal.PrimaryPart then
table.insert(animals, animal)
end
end
end
return animals
end
local function setAtmosphere(activate)
if activate then
Lighting.Ambient = BLUE_AMBIENT
Lighting.OutdoorAmbient = BLUE_OUTDOOR
Workspace.Gravity = LOW_GRAVITY
Lighting.ClockTime = NIGHT_CLOCKTIME
else
Lighting.Ambient = ORIGINAL_AMBIENT
Lighting.OutdoorAmbient = ORIGINAL_OUTDOOR_AMBIENT
Workspace.Gravity = ORIGINAL_GRAVITY
Lighting.ClockTime = ORIGINAL_CLOCKTIME
end
end
local function spawnNPCs()
local sharksFolder = Workspace:FindFirstChild(SHARKS_FOLDER_NAME)
if not sharksFolder then
sharksFolder = Instance.new("Folder")
sharksFolder.Name = SHARKS_FOLDER_NAME
sharksFolder.Parent = Workspace
end
SpawnedNPCs = {}
local templateFolder = ServerStorage:FindFirstChild(SHARKS_FOLDER_NAME)
if not templateFolder then return sharksFolder end
for i = 1, NUM_ORCALEROS do
local template = templateFolder:FindFirstChild(NPC_NAME)
if template then
local clone = template:Clone()
clone.Name = NPC_NAME .. tostring(i)
clone.Parent = sharksFolder
SpawnedNPCs[clone.Name] = clone
end
end
return sharksFolder
end
local function setupFloatPhysics(npcModel)
local root = npcModel and npcModel.PrimaryPart
if not root then return end
for _, child in ipairs(root:GetChildren()) do
if child:IsA("BodyPosition") or child:IsA("BodyGyro") then
child:Destroy()
end
end
root.Anchored = false
root.CanCollide = false
root.Massless = true
local bodyPos = Instance.new("BodyPosition")
bodyPos.MaxForce = Vector3.new(1e7, 1e7, 1e7)
bodyPos.Position = root.Position
bodyPos.D = 900
bodyPos.P = 1000
bodyPos.Parent = root
local bodyGyro = Instance.new("BodyGyro")
bodyGyro.MaxTorque = Vector3.new(1e7, 1e7, 1e7)
bodyGyro.CFrame = root.CFrame
bodyGyro.P = 4000
bodyGyro.Parent = root
BodyMoverRefs[npcModel] = {bodyPos = bodyPos, bodyGyro = bodyGyro}
end
local function cleanupFloatPhysics(npcModel)
local root = npcModel and npcModel.PrimaryPart
if not root then return end
for _, child in ipairs(root:GetChildren()) do
if child:IsA("BodyPosition") or child:IsA("BodyGyro") then
child:Destroy()
end
end
BodyMoverRefs[npcModel] = nil
end
local function floatBetweenRoutes(npcModel)
if not npcModel or not npcModel.PrimaryPart then return end
setupFloatPhysics(npcModel)
local root = npcModel.PrimaryPart
local routes = getRouteParts()
if #routes == 0 then return end
local currentRouteIndex = math.random(1, #routes)
root.Position = routes[currentRouteIndex].Position
local mover = BodyMoverRefs[npcModel] and BodyMoverRefs[npcModel].bodyPos
local gyro = BodyMoverRefs[npcModel] and BodyMoverRefs[npcModel].bodyGyro
while npcModel.Parent do
local nextRouteIndex
repeat
nextRouteIndex = math.random(1, #routes)
until nextRouteIndex ~= currentRouteIndex
local targetPos = routes[nextRouteIndex].Position
local startPos = root.Position
local totalDist = (targetPos - startPos).Magnitude
local moveSpeed = ORCALERO_SPEED
local travelTime = totalDist / moveSpeed
local swimSeed = math.random() * 1000
local timeElapsed = 0
while timeElapsed < travelTime and npcModel.Parent do
local dt = RunService.Heartbeat:Wait()
timeElapsed = timeElapsed + dt
local alpha = math.clamp(timeElapsed / travelTime, 0, 1)
local newPos = startPos:Lerp(targetPos, alpha)
local swimY = math.sin((timeElapsed + swimSeed) * 1.1) * 1.4
local swimX = math.sin((timeElapsed + swimSeed) * 0.6) * 0.7
local swimPos = newPos + Vector3.new(swimX, swimY, 0)
if mover then mover.Position = swimPos end
local lookDir = (targetPos - root.Position)
if lookDir.Magnitude > 0.01 then
lookDir = lookDir.Unit
local targetCFrame = CFrame.new(root.Position, root.Position + lookDir)
local wiggleAngle = math.sin((timeElapsed + swimSeed) * 1.7) * math.rad(6)
local wiggleCFrame = CFrame.Angles(0, wiggleAngle, 0)
if gyro then
gyro.CFrame = targetCFrame * wiggleCFrame
end
end
end
currentRouteIndex = nextRouteIndex
end
cleanupFloatPhysics(npcModel)
end
local function activateNPCs()
local sharksFolder = spawnNPCs()
local routes = getRouteParts()
local usedIndices = {}
local i = 1
for npcName, npc in pairs(SpawnedNPCs) do
if npc and npc.PrimaryPart then
local routeIndex
repeat
routeIndex = math.random(1, #routes)
until not usedIndices[routeIndex]
usedIndices[routeIndex] = true
npc.PrimaryPart.Position = routes[routeIndex].Position
NPCState[npcName] = {Model = npc, OriginalPosition = routes[routeIndex].Position}
local taskObj = task.spawn(function()
floatBetweenRoutes(npc)
end)
table.insert(floatTasks, taskObj)
end
i = i + 1
end
end
local function deactivateNPCs()
for npcName, data in pairs(NPCState) do
local npc = data.Model
if npc and data.OriginalPosition then
cleanupFloatPhysics(npc)
npc.PrimaryPart.Position = data.OriginalPosition
npc:Destroy()
end
end
NPCState = {}
for _, conn in ipairs(npcShootConnections) do
if conn then conn:Disconnect() end
end
npcShootConnections = {}
for _, taskObj in ipairs(floatTasks) do
if taskObj then task.cancel(taskObj) end
end
floatTasks = {}
local sharksFolder = Workspace:FindFirstChild(SHARKS_FOLDER_NAME)
if sharksFolder then sharksFolder:Destroy() end
end
local function struckVFX(animal)
local assetsFolder = ReplicatedStorage:FindFirstChild("Assets")
local waterFolder = assetsFolder and assetsFolder:FindFirstChild("Water")
local struckTemplate = waterFolder and waterFolder:FindFirstChild("StruckVFX")
if struckTemplate and animal.PrimaryPart then
local vfx = struckTemplate:Clone()
vfx.Parent = animal.PrimaryPart
if vfx:IsA("ParticleEmitter") then
vfx:Emit(vfx:GetAttribute("EmitCount") or 100)
end
game:GetService("Debris"):AddItem(vfx, 1)
end
end
local function npcShoot(npcModel)
local function shoot()
local animals = getAnimals()
if #animals > 0 and npcModel and npcModel.PrimaryPart then
local target = animals[math.random(1, #animals)]
WaterHitRemote:FireAllClients(target.Name, npcModel.Name)
struckVFX(target)
local traitsJson = target:GetAttribute("Traits")
local traits = {}
if traitsJson then
local ok, decoded = pcall(function() return HttpService:JSONDecode(traitsJson) end)
if ok and type(decoded) == "table" then traits = decoded end
end
if not table.find(traits, "Shark Fin") then
table.insert(traits, "Shark Fin")
target:SetAttribute("Traits", HttpService:JSONEncode(traits))
end
end
end
local conn = RunService.Heartbeat:Connect(function(dt)
if math.random() < dt / 2 then
shoot()
end
end)
table.insert(npcShootConnections, conn)
end
local WaterEvent = {}
WaterEvent.__index = WaterEvent
function WaterEvent.new(eventService)
local self = setmetatable({}, WaterEvent)
self.eventService = eventService
self.isActive = false
self.eventEntry = nil
self.connections = {}
self.lastStrike = 0
return self
end
function WaterEvent:Start(eventEntry)
self.eventEntry = eventEntry
self.isActive = true
self.lastStrike = workspace:GetServerTimeNow()
print("[WaterEvent] Starting Water event on server")
self:_startWaterLogic()
local startWaterRemote = Net:RemoteEvent("EventService/Water/Start")
for _, player in pairs(Players:GetPlayers()) do
startWaterRemote:FireClient(player, eventEntry)
end
local connection = Players.PlayerAdded:Connect(function(player)
if self.isActive then
startWaterRemote:FireClient(player, self.eventEntry)
end
end)
table.insert(self.connections, connection)
local assetsFolder = ReplicatedStorage:FindFirstChild("Assets")
if assetsFolder then
local WaterWeatherFolder = assetsFolder:FindFirstChild("WaterEvent")
if WaterWeatherFolder then
local WaterWeatherClone = WaterWeatherFolder:Clone()
WaterWeatherClone.Name = "WaterEvent_Active"
WaterWeatherClone.Parent = workspace
task.defer(function()
local WaterWeatherActive = workspace:FindFirstChild("WaterEvent_Active")
if WaterWeatherActive then
for _, desc in ipairs(WaterWeatherActive:GetDescendants()) do
if desc:IsA("ParticleEmitter") then
desc:Emit(desc:GetAttribute("EmitCount") or 100)
end
end
end
end)
end
end
setAtmosphere(true)
playWaterMusic()
activateNPCs()
for npcName, data in pairs(NPCState) do
npcShoot(data.Model)
end
end
function WaterEvent:Stop(eventEntry)
self.isActive = false
print("[WaterEvent] Stopping Water event on server")
for _, connection in pairs(self.connections) do
if connection then
connection:Disconnect()
end
end
self.connections = {}
local stopWaterRemote = Net:RemoteEvent("EventService/Water/Stop")
for _, player in pairs(Players:GetPlayers()) do
stopWaterRemote:FireClient(player)
end
self.eventEntry = nil
local WaterWeatherActive = workspace:FindFirstChild("WaterEvent_Active")
if WaterWeatherActive then
WaterWeatherActive:Destroy()
end
setAtmosphere(false)
stopWaterMusic()
deactivateNPCs()
end
function WaterEvent:_startWaterLogic()
local connection
connection = RunService.Heartbeat:Connect(function()
if not self.isActive then
connection:Disconnect()
return
end
local currentTime = workspace:GetServerTimeNow()
if (currentTime - self.lastStrike) >= COOLDOWN_TIME then
if self:_strikeOneAnimal() then
self.lastStrike = currentTime
end
end
end)
table.insert(self.connections, connection)
end
function WaterEvent:_addWetTrait(animal)
local traitsJson = animal:GetAttribute("Traits")
local traits = {}
if traitsJson then
local ok, decoded = pcall(function() return HttpService:JSONDecode(traitsJson) end)
if ok and type(decoded) == "table" then traits = decoded end
end
for _, trait in ipairs(traits) do
if trait == "Shark Fin" then return end
end
table.insert(traits, "Shark Fin")
animal:SetAttribute("Traits", HttpService:JSONEncode(traits))
end
function WaterEvent:_hasWetTrait(animal)
local traitsJson = animal:GetAttribute("Traits")
local traits = {}
if traitsJson then
local ok, decoded = pcall(function() return HttpService:JSONDecode(traitsJson) end)
if ok and type(decoded) == "table" then traits = decoded end
end
for _, trait in ipairs(traits) do
if trait == "Shark Fin" then
return true
end
end
return false
end
function WaterEvent:_pickTargetAnimals()
local movingAnimalsFolder = workspace:FindFirstChild("MovingAnimals")
local candidates = {}
for _, animal in ipairs(CollectionService:GetTagged("Animal")) do
if animal.Parent == movingAnimalsFolder and animal.PrimaryPart
and string.find(animal.Name, "RoadAnimal_")
and not self:_hasWetTrait(animal) then
table.insert(candidates, animal)
end
end
return candidates
end
function WaterEvent:_strikeOneAnimal()
local candidates = self:_pickTargetAnimals()
if #candidates == 0 then return false end
local idx = math.random(1, #candidates)
local animal = candidates[idx]
self:_impactAnimal(animal)
return true
end
function WaterEvent:_impactAnimal(animal)
if not animal or not animal.Parent or not animal.PrimaryPart then return end
local npcIdx = math.random(1, NUM_ORCALEROS)
local npcName = NPC_NAME .. tostring(npcIdx)
WaterHitRemote:FireAllClients(animal.Name, npcName)
struckVFX(animal)
self:_addWetTrait(animal)
end
local Water = {}
function Water.OnLoad(eventService)
return WaterEvent.new(eventService)
end
return Water - Edit
03:12:20.461
- Edit
03:12:20.461
============================== - Edit
03:12:20.461 📜 ServerScriptService.Services.EventService.Events.Rainbow - Edit
03:12:20.461 ==============================
- Edit
03:12:20.461 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local Players = game:GetService("Players")
local Net = require(ReplicatedStorage.Packages.Net)
local Rainbow = require(ReplicatedStorage.Controllers.EventController.Events.Rainbow)
local Module = {}
Module.__index = Module
function Module.new(eventService)
local self = setmetatable({}, Module)
self._eventService = eventService
self._active = false
return self
end
function Module:Start(eventData)
if self._active then return end
self._active = true
self._eventData = eventData or {}
Rainbow.OnStart()
end
function Rainbow:Stop()
if not self._active then return end
self._active = false
Rainbow.OnStop()
end
function Module:Load()
Rainbow.OnLoad()
end
return Module - Edit
03:12:20.461
- Edit
03:12:20.461
============================== - Edit
03:12:20.461 📜 ServerScriptService.Services.EventService.Events.Bombardiro Crocodilo - Edit
03:12:20.461 ==============================
- Edit
03:12:20.461 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local Players = game:GetService("Players")
local HttpService = game:GetService("HttpService")
local CollectionService = game:GetService("CollectionService")
local Net = require(ReplicatedStorage.Packages.Net)
local BombardiroCrocodilo = require(ReplicatedStorage.Controllers.EventController.Events["Bombardiro Crocodilo"])
local Module = {}
Module.__index = Module
function Module.new(eventService)
local self = setmetatable({}, Module)
self._eventService = eventService
self._active = false
self._bombingTask = nil
self._recentlyTargeted = {}
self._spawnBombRemote = Net:RemoteEvent("EventService/Bombardiro Crocodilo/SpawnBomb")
self._explodeRemote = Net:RemoteEvent("EventService/Bombardiro Crocodilo/Explode")
return self
end
function Module:Start(eventData)
if self._active then return end
self._active = true
self._eventData = eventData or {}
self:_startBombingLoop()
print("[Bombardiro Crocodilo] Event started with animal targeting")
end
function Module:Stop()
if not self._active then return end
self._active = false
-- Stop the bombing loop
if self._bombingTask then
task.cancel(self._bombingTask)
self._bombingTask = nil
end
-- Stop the client-side event
BombardiroCrocodilo.OnStop()
print("[Bombardiro Crocodilo] Event stopped")
end
function Module:Load()
BombardiroCrocodilo.OnLoad()
end
function Module:_startBombingLoop()
if self._bombingTask then
task.cancel(self._bombingTask)
end
self._bombingTask = task.spawn(function()
-- Wait for the planes to appear (based on the client script, planes appear after 8 seconds)
task.wait(10)
while self._active do
-- Wait 2-5 seconds between bomb drops
task.wait(math.random(2, 5))
local targetAnimal = self:_pickTargetAnimal()
if targetAnimal and targetAnimal.PrimaryPart then
self:_dropBombOnAnimal(targetAnimal)
else
-- If no valid animal, drop bomb at random location
self:_dropBombAtRandomLocation()
end
end
end)
end
function Module:_dropBombOnAnimal(targetAnimal)
local targetPosition = targetAnimal.PrimaryPart.Position
local dropHeight = targetPosition.Y + math.random(80, 120) -- Drop from above
local dropPosition = Vector3.new(targetPosition.X, dropHeight, targetPosition.Z)
-- Choose a random plane (assuming you have multiple planes)
local planeId = "BombardiroPlane" .. math.random(1, 3) -- Adjust based on your plane setup
-- Fire to all clients to spawn the bomb
self._spawnBombRemote:FireAllClients(planeId, dropPosition, targetPosition)
-- Mark this animal as recently targeted
self._recentlyTargeted[targetAnimal.Name] = workspace:GetServerTimeNow()
-- Calculate time until bomb hits the ground
local fallTime = self:_calculateFallTime(dropPosition.Y, targetPosition.Y)
-- Schedule explosion and trait application
task.delay(fallTime, function()
if self._active and targetAnimal.Parent then
-- Fire explosion effect to all clients
self._explodeRemote:FireAllClients(targetPosition, "Explosion")
-- Apply the trait
self:_applyBombardiroHatTrait(targetAnimal)
print("[Bombardiro Crocodilo] Bomb hit", targetAnimal.Name)
end
end)
end
function Module:_dropBombAtRandomLocation()
-- Get a random position for missed bombs
local randomPosition = self:_getRandomBombPosition()
if randomPosition then
local dropHeight = randomPosition.Y + math.random(80, 120)
local dropPosition = Vector3.new(randomPosition.X, dropHeight, randomPosition.Z)
local planeId = "BombardiroPlane" .. math.random(1, 3)
-- Fire to all clients to spawn the bomb
self._spawnBombRemote:FireAllClients(planeId, dropPosition, randomPosition)
-- Calculate fall time and schedule explosion
local fallTime = self:_calculateFallTime(dropPosition.Y, randomPosition.Y)
task.delay(fallTime, function()
if self._active then
-- Fire explosion effect to all clients
self._explodeRemote:FireAllClients(randomPosition, "Explosion")
end
end)
end
end
function Module:_calculateFallTime(startY, endY)
-- Simple gravity calculation (adjust if needed to match your client script)
local distance = startY - endY
local gravity = 196.2 -- Roblox's default gravity
return math.sqrt(2 * distance / gravity)
end
function Module:_pickTargetAnimal()
local roadAnimals = CollectionService:GetTagged("Animal")
local movingAnimalsFolder = workspace:FindFirstChild("MovingAnimals")
local currentTime = workspace:GetServerTimeNow()
-- Clean up old entries from recently targeted
for animalName, lastTime in pairs(self._recentlyTargeted) do
if (currentTime - lastTime) > 15 then -- 15 second cooldown
self._recentlyTargeted[animalName] = nil
end
end
local candidates = {}
for _, animal in ipairs(roadAnimals) do
-- Check if it's a road animal and hasn't been targeted recently
if animal.Parent == movingAnimalsFolder and
animal.PrimaryPart and
string.find(animal.Name, "RoadAnimal_") and
not self._recentlyTargeted[animal.Name] and
not self:_hasBombardiroHatTrait(animal) then
table.insert(candidates, animal)
end
end
if #candidates == 0 then return nil end
return candidates[math.random(1, #candidates)]
end
function Module:_getRandomBombPosition()
-- Get a random position in the world for bombs that miss
local x = math.random(-500, 500)
local z = math.random(-500, 500)
-- Raycast down to find the ground
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.FilterDescendantsInstances = {Players}
local raycastResult = workspace:Raycast(Vector3.new(x, 1000, z), Vector3.new(0, -2000, 0), raycastParams)
if raycastResult then
return raycastResult.Position
else
return Vector3.new(x, 50, z) -- Fallback position
end
end
function Module:_hasBombardiroHatTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
return false
end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
for _, trait in ipairs(currentTraits) do
if trait == "Explosive" then
return true
end
end
return false
end
function Module:_applyBombardiroHatTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
return
end
if self:_hasBombardiroHatTrait(animalTemplate) then
return
end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
table.insert(currentTraits, "Explosive")
animalTemplate:SetAttribute("Traits", HttpService:JSONEncode(currentTraits))
end
return Module - Edit
03:12:20.461
- Edit
03:12:20.461
============================== - Edit
03:12:20.461 📜 ServerScriptService.Services.EventService.Events.SolarFlareEvent - Edit
03:12:20.461 ==============================
- Edit
03:12:20.462 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local HttpService = game:GetService("HttpService")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local DataManagment = require(ServerScriptService.Services.DataManagment)
local RoadAnimalService = require(ServerScriptService.Services.RoadAnimalService)
local Animals = require(ReplicatedStorage.Datas.Animals)
local SolarFlare = require(ReplicatedStorage.Controllers.EventController.Events["Solar Flare"])
local Model = ReplicatedStorage.Models.Events["Solar Flare"]:FindFirstChild("SolarFlareBeam")
local SolarFlareEvent = {}
SolarFlareEvent.__index = SolarFlareEvent
function SolarFlareEvent.new(eventService)
local self = setmetatable({}, SolarFlareEvent)
self._eventService = eventService
self._synchronizer = eventService._synchronizer
self._solarSynchronizer = Synchronizer:Create("SolarFlareEvent", {
IsActive = false
})
for _, player in pairs(Players:GetPlayers()) do
self._solarSynchronizer:AddListener(player)
end
Players.PlayerAdded:Connect(function(player)
self._solarSynchronizer:AddListener(player)
end)
Players.PlayerRemoving:Connect(function(player)
self._solarSynchronizer:RemoveListener(player)
end)
self._isActive = false
self._recentlyTargeted = {}
return self
end
function SolarFlareEvent:Start(eventEntry)
if self._isActive then
return
end
self._isActive = true
ReplicatedStorage:SetAttribute("SolarFlareEvent", true)
local spawnTime = workspace:GetServerTimeNow() + 1
local Solar = Model:Clone()
Solar.BeamEnd:SetAttribute("StartTime", spawnTime)
Solar.BeamEnd:SetAttribute("SpawnPosition", workspace.MapCenter.Position)
Solar.Parent = workspace.Events["Solar Flare"]
SolarFlare:OnLoad()
SolarFlare:OnStart()
self._solarSynchronizer:Set("IsActive", true)
self:_startStrikeLoop()
task.wait(1)
print("[SolarFlareEvent] Solar Flare event started successfully")
end
function SolarFlareEvent:Stop(eventEntry)
if not self._isActive then
return
end
self._isActive = false
print("[SolarFlareEvent] Stopping Solar Flare event")
ReplicatedStorage:SetAttribute("SolarFlareEvent", false)
SolarFlare:OnStop()
self._solarSynchronizer:Set("IsActive", false)
if self._strikeTask then
task.cancel(self._strikeTask)
self._strikeTask = nil
end
print("[SolarFlareEvent] Solar Flare event stopped")
end
function SolarFlareEvent:_startStrikeLoop()
if self._strikeTask then
task.cancel(self._strikeTask)
end
self._strikeTask = task.spawn(function()
while self._isActive do
task.wait(math.random(2,4))
local targetAnimal = self:_pickTargetAnimal()
if targetAnimal then
local catIndex = math.random(1,4)
local currentTime = workspace:GetServerTimeNow()
local cloni = ReplicatedStorage.Models.Events["Solar Flare"].SolarFlareBeam.Hitbox:Clone()
cloni.Name = "Hitbox" .. catIndex
cloni:AddTag("SolarFlareHitbox")
cloni.Position = targetAnimal.PrimaryPart.Position
cloni.Parent = workspace.Events["Solar Flare"].SolarFlareBeam
workspace.Events["Solar Flare"].SolarFlareBeam.BeamEnd:SetAttribute("NumBeams", catIndex)
self._recentlyTargeted[targetAnimal.Name] = currentTime
task.delay(3.1, function()
self:_applysolarTrait(targetAnimal)
end)
end
end
end)
end
function SolarFlareEvent:_pickTargetAnimal()
local CollectionService = game:GetService("CollectionService")
local roadAnimals = CollectionService:GetTagged("Animal")
local movingAnimalsFolder = workspace:FindFirstChild("MovingAnimals")
local currentTime = workspace:GetServerTimeNow()
for animalName, lastTime in pairs(self._recentlyTargeted) do
if (currentTime - lastTime) > 15 then
self._recentlyTargeted[animalName] = nil
end
end
local candidates = {}
for _, animal in ipairs(roadAnimals) do
if animal.Parent == movingAnimalsFolder and animal.PrimaryPart and string.find(animal.Name, "RoadAnimal_") then
if not self._recentlyTargeted[animal.Name] and not self:_hassolarTrait(animal) then
table.insert(candidates, animal)
end
end
end
if #candidates == 0 then return nil end
return candidates[math.random(1, #candidates)]
end
function SolarFlareEvent:_hassolarTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
return false
end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
for _, trait in ipairs(currentTraits) do
if trait == "Fire" then
return true
end
end
return false
end
function SolarFlareEvent:_applysolarTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
return
end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
for _, trait in ipairs(currentTraits) do
if trait == "Fire" then
return
end
end
table.insert(currentTraits, "Fire")
animalTemplate:SetAttribute("Traits", HttpService:JSONEncode(currentTraits))
end
return SolarFlareEvent - Edit
03:12:20.462
- Edit
03:12:20.462
============================== - Edit
03:12:20.462 📜 ServerScriptService.Services.EventService.Events.Galaxy - Edit
03:12:20.462 ==============================
- Edit
03:12:20.462 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local Players = game:GetService("Players")
local Net = require(ReplicatedStorage.Packages.Net)
local Galaxy = require(ReplicatedStorage.Controllers.EventController.Events.Galaxy)
local Module = {}
Module.__index = Module
function Module.new(eventService)
local self = setmetatable({}, Module)
self._eventService = eventService
self._active = false
return self
end
function Module:Start(eventData)
if self._active then return end
self._active = true
self._eventData = eventData or {}
ReplicatedStorage:SetAttribute("GalaxyEvent", true)
ReplicatedStorage:SetAttribute("GalaxyEventLastTime", os.time())
Galaxy.OnStart()
end
function Module:Stop()
if not self._active then return end
self._active = false
Galaxy.OnStop()
ReplicatedStorage:SetAttribute("GalaxyEvent", false)
end
function Module:Load()
Galaxy.OnLoad()
end
return Module
- Edit
03:12:20.462
- Edit
03:12:20.462
============================== - Edit
03:12:20.462 📜 ServerScriptService.Services.EventService.Events.Phase 2: Galaxy Introduction - Edit
03:12:20.462 ==============================
- Edit
03:12:20.463 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local Task = task
local Module = {}
Module.__index = Module
local DELAY_SECONDS = 47
function Module.new(eventService)
local self = setmetatable({}, Module)
self._eventService = eventService
self._active = false
self._storedPlot = nil
self._rocketShip = nil
self._spawnThread = nil
return self
end
function Module:_debug(msg)
print(("[DEBUG][GalaxyPhase] %s"):format(msg))
end
function Module:_getRocketTemplate()
return script.Rocketship
end
function Module:_scheduleSpawn()
if self._spawnThread then
self:_debug("Spawn thread already scheduled; skipping")
return
end
self:_debug(("Scheduling RocketShip spawn in %d seconds..."):format(DELAY_SECONDS))
self._spawnThread = Task.delay(DELAY_SECONDS, function()
self:_debug("Delay fired; checking active state...")
self._spawnThread = nil
if not self._active then
self:_debug("Module inactive at delay fire; skipping spawn")
return
end
-- Avoid double-spawn if already present
if Workspace:FindFirstChild("RocketShip") then
self:_debug("RocketShip already in workspace; skipping clone")
return
end
local rocketTemplate = self:_getRocketTemplate()
if not rocketTemplate then
self:_debug("Rocket template not found; spawn skipped")
return
end
local ok, cloneOrErr = pcall(function()
local clone = rocketTemplate:Clone()
clone.Name = "RocketShip"
clone.Parent = Workspace
self._rocketShip = clone
return clone
end)
if ok and cloneOrErr then
self:_debug(("RocketShip cloned to workspace (%s)"):format(cloneOrErr:GetFullName()))
else
self:_debug(("Error cloning RocketShip: %s"):format(tostring(cloneOrErr)))
end
end)
end
function Module:Start()
if self._active then
self:_debug("Start called but already active; ignoring")
return
end
self._active = true
self:_debug("Start called; module is now active")
local plot = Workspace.Plots and Workspace.Plots:FindFirstChild("2")
if plot then
self._storedPlot = plot
self:_debug(("Found plot '%s'; moving to ReplicatedStorage"):format(plot.Name))
plot.Parent = ReplicatedStorage
else
self:_debug("Plot '2' not found under Workspace.Plots")
self._storedPlot = nil
end
self:_scheduleSpawn()
end
function Module:Stop()
if not self._active then
self:_debug("Stop called but already inactive; ignoring")
return
end
self._active = false
self:_debug("Stop called; module is now inactive")
-- Cancel pending delay if possible (task.delay returns a thread in modern Roblox)
if self._spawnThread then
local ok, err = pcall(function()
Task.cancel(self._spawnThread)
end)
if ok then
self:_debug("Pending spawn delay canceled")
else
self:_debug(("Failed to cancel spawn delay (non-fatal): %s"):format(tostring(err)))
end
self._spawnThread = nil
end
-- Restore plot if we moved it
if self._storedPlot and self._storedPlot.Parent == ReplicatedStorage then
self:_debug(("Restoring plot '%s' to Workspace.Plots"):format(self._storedPlot.Name))
self._storedPlot.Parent = Workspace.Plots
else
self:_debug("No stored plot to restore or already restored")
end
self._storedPlot = nil
-- Cleanup RocketShip if exists
local rocket = self._rocketShip
if not rocket or not rocket.Parent then
rocket = Workspace:FindFirstChild("RocketShip")
end
if rocket then
self:_debug("Destroying RocketShip from workspace")
rocket:Destroy()
else
self:_debug("No RocketShip found to destroy; skipping")
end
self._rocketShip = nil
end
return Module
- Edit
03:12:20.463
- Edit
03:12:20.463
============================== - Edit
03:12:20.463 📜 ServerScriptService.Services.EventService.Events.Phase 1: Sleepy - Edit
03:12:20.463 ==============================
- Edit
03:12:20.463 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local HttpService = game:GetService("HttpService")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local DataManagment = require(ServerScriptService.Services.DataManagment)
local RoadAnimalService = require(ServerScriptService.Services.RoadAnimalService)
local Animals = require(ReplicatedStorage.Datas.Animals)
local SleepyEvent = {}
SleepyEvent.__index = SleepyEvent
function SleepyEvent.new(eventService)
local self = setmetatable({}, SleepyEvent)
self._eventService = eventService
self._synchronizer = eventService._synchronizer
self._sleepySynchronizer = Synchronizer:Create("SleepyEvent", {
IsActive = false
})
for _, player in pairs(Players:GetPlayers()) do
self._sleepySynchronizer:AddListener(player)
end
Players.PlayerAdded:Connect(function(player)
self._sleepySynchronizer:AddListener(player)
end)
Players.PlayerRemoving:Connect(function(player)
self._sleepySynchronizer:RemoveListener(player)
end)
self._isActive = false
self._sleepVFXRemote = Net:RemoteEvent("EventService/Phase 1: Sleepy/PlaySleepVFX")
self._recentlyTargeted = {}
return self
end
function SleepyEvent:Start(eventEntry)
if self._isActive then
return
end
self._isActive = true
ReplicatedStorage:SetAttribute("Phase1SleepyEvent", true)
self._sleepySynchronizer:Set("IsActive", true)
self:_startSleepLoop()
end
function SleepyEvent:_startSleepLoop()
if self._sleepTask then
task.cancel(self._sleepTask)
end
self._sleepTask = task.spawn(function()
while self._isActive do
task.wait(math.random(3, 4.5))
local targetAnimal = self:_pickTargetAnimal()
if targetAnimal then
local currentTime = workspace:GetServerTimeNow()
self._sleepVFXRemote:FireAllClients(targetAnimal.Name, currentTime)
self._recentlyTargeted[targetAnimal.Name] = currentTime
task.delay(0.05, function()
self:_applySleepyTrait(targetAnimal)
end)
end
end
end)
end
function SleepyEvent:Stop(eventEntry)
if not self._isActive then
return
end
self._isActive = false
ReplicatedStorage:SetAttribute("Phase1SleepyEvent", false)
self._sleepySynchronizer:Set("IsActive", false)
if self._sleepTask then
task.cancel(self._sleepTask)
self._sleepTask = nil
end
self._recentlyTargeted = {}
end
function SleepyEvent:_pickTargetAnimal()
local CollectionService = game:GetService("CollectionService")
local roadAnimals = CollectionService:GetTagged("Animal")
local movingAnimalsFolder = workspace:FindFirstChild("MovingAnimals")
local currentTime = workspace:GetServerTimeNow()
for animalName, lastTime in pairs(self._recentlyTargeted) do
if (currentTime - lastTime) > 15 then
self._recentlyTargeted[animalName] = nil
end
end
local candidates = {}
for _, animal in ipairs(roadAnimals) do
if animal.Parent == movingAnimalsFolder and animal.PrimaryPart and string.find(animal.Name, "RoadAnimal_") then
if not self._recentlyTargeted[animal.Name] and not self:_hasSleepyTrait(animal) then
table.insert(candidates, animal)
end
end
end
if #candidates == 0 then
return nil
end
return candidates[math.random(1, #candidates)]
end
function SleepyEvent:_hasSleepyTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
return false
end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
for _, trait in ipairs(currentTraits) do
if trait == "Sleepy" then
return true
end
end
return false
end
function SleepyEvent:_applySleepyTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
return
end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
for _, trait in ipairs(currentTraits) do
if trait == "Sleepy" then
return
end
end
table.insert(currentTraits, "Sleepy")
animalTemplate:SetAttribute("Traits", HttpService:JSONEncode(currentTraits))
end
function SleepyEvent:GetSleepyAnimalsCount()
local CollectionService = game:GetService("CollectionService")
local roadAnimals = CollectionService:GetTagged("Animal")
local movingAnimalsFolder = workspace:FindFirstChild("MovingAnimals")
local count = 0
for _, animal in ipairs(roadAnimals) do
if animal.Parent == movingAnimalsFolder and self:_hasSleepyTrait(animal) then
count = count + 1
end
end
return count
end
return SleepyEvent - Edit
03:12:20.463
- Edit
03:12:20.463
============================== - Edit
03:12:20.463 📜 ServerScriptService.Services.EventService.Events.Phase 3: Sammy's Base - Edit
03:12:20.463 ==============================
- Edit
03:12:20.464 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local Players = game:GetService("Players")
local Net = require(ReplicatedStorage.Packages.Net)
local Module = {}
Module.__index = Module
function Module.new(eventService)
local self = setmetatable({}, Module)
self._eventService = eventService
self._active = false
self._sammyEvent = nil
self._borders = {}
return self
end
function Module:Start(eventData)
if self._active then return end
self._active = true
self._eventData = eventData or {}
local sammyEvent = script:FindFirstChild("SammyBaseEvent")
if sammyEvent then
self._sammyEvent = sammyEvent:Clone()
self._sammyEvent.Parent = Workspace
end
local bordersFolder = Workspace:FindFirstChild("Map") and Workspace.Map:FindFirstChild("Borders")
if bordersFolder then
for _, part in ipairs(bordersFolder:GetDescendants()) do
if part:IsA("BasePart") then
self._borders[part] = part.CanCollide
part.CanCollide = false
end
end
end
end
function Module:Stop()
if not self._active then return end
self._active = false
if self._sammyEvent and self._sammyEvent.Parent then
self._sammyEvent:Destroy()
self._sammyEvent = nil
end
for part, originalState in pairs(self._borders) do
if part and part.Parent then
part.CanCollide = originalState
end
end
self._borders = {}
end
return Module
- Edit
03:12:20.464
- Edit
03:12:20.464
============================== - Edit
03:12:20.464 📜 ServerScriptService.Services.EventService.Events.Phase 4: Mygame43 - Edit
03:12:20.464 ==============================
- Edit
03:12:20.464 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local HttpService = game:GetService("HttpService")
local CollectionService = game:GetService("CollectionService")
local RunService = game:GetService("RunService")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local DataManagment = require(ServerScriptService.Services.DataManagment)
local RoadAnimalService = require(ServerScriptService.Services.RoadAnimalService)
local Animals = require(ReplicatedStorage.Datas.Animals)
local LightningEvent = {}
LightningEvent.__index = LightningEvent
function LightningEvent.new(eventService)
local self = setmetatable({}, LightningEvent)
self._eventService = eventService
self._synchronizer = eventService._synchronizer
self._lightningSynchronizer = Synchronizer:Create("LightningEvent", {
IsActive = false
})
for _, player in pairs(Players:GetPlayers()) do
self._lightningSynchronizer:AddListener(player)
end
Players.PlayerAdded:Connect(function(player)
self._lightningSynchronizer:AddListener(player)
end)
Players.PlayerRemoving:Connect(function(player)
self._lightningSynchronizer:RemoveListener(player)
end)
self._isActive = false
self._createLightningOrbRemote = Net:RemoteEvent("EventService/Phase 4: Mygame43/CreateLightningOrb")
self._recentlyTargeted = {}
self._activeOrbs = {}
self._orbCounter = 0
self._bossSpawnCFrame = CFrame.new(0, 50, 0)
return self
end
function LightningEvent:Start(eventEntry)
if self._isActive then
return
end
self._isActive = true
print("[LightningEvent] Starting Lightning event")
ReplicatedStorage:SetAttribute("LightningEvent", true)
self._lightningSynchronizer:Set("IsActive", true)
self:_startLightningLoop()
print("[LightningEvent] Lightning event started successfully")
end
function LightningEvent:_startLightningLoop()
if self._lightningTask then
task.cancel(self._lightningTask)
end
self._lightningTask = task.spawn(function()
task.wait(7.7)
while self._isActive do
self:_createOrbBarrage()
task.wait(math.random(5, 8))
end
end)
end
function LightningEvent:_createOrbBarrage()
local targetAnimals = self:_pickTargetAnimals(4)
if #targetAnimals == 0 then
return
end
for orbPosition = 1, 4 do
local targetAnimal = targetAnimals[math.random(1, #targetAnimals)]
if targetAnimal and targetAnimal.PrimaryPart then
self:_fireOrbAtAnimal(orbPosition, targetAnimal)
end
end
end
function LightningEvent:_fireOrbAtAnimal(orbPosition, targetAnimal)
if not targetAnimal or not targetAnimal.PrimaryPart then
return
end
self._orbCounter = self._orbCounter + 1
local orbId = self._orbCounter
local animalPosition = targetAnimal.PrimaryPart.Position
-- Mark animal as recently targeted
self._recentlyTargeted[targetAnimal.Name] = workspace:GetServerTimeNow()
-- Calculate flight time (similar to client script bezier curve timing)
local flightTime = math.random(2, 4) -- Random flight time
-- Fire the orb creation event to all clients (matching client script parameters)
self._createLightningOrbRemote:FireAllClients(
orbId, -- p50: Seed for random generation
orbPosition, -- p51: Which orb position (1-4)
animalPosition, -- u52: Target position
flightTime, -- u53: Flight duration
true -- u54: Hit target (brainrot effect - set to true to apply trait)
)
-- Apply lightning trait after the orb hits
task.spawn(function()
task.wait(flightTime + 0.5) -- Small delay after impact
self:_applyLightningTrait(targetAnimal)
end)
end
function LightningEvent:Stop(eventEntry)
if not self._isActive then
return
end
self._isActive = false
print("[LightningEvent] Stopping Lightning event")
ReplicatedStorage:SetAttribute("LightningEvent", false)
self._lightningSynchronizer:Set("IsActive", false)
if self._lightningTask then
task.cancel(self._lightningTask)
self._lightningTask = nil
end
-- Clean up boss
if self._lightningBoss then
self._lightningBoss:Destroy()
self._lightningBoss = nil
end
-- Clear active orbs
self._activeOrbs = {}
print("[LightningEvent] Lightning event stopped")
end
function LightningEvent:_pickTargetAnimals(maxCount)
local roadAnimals = CollectionService:GetTagged("Animal")
local movingAnimalsFolder = workspace:FindFirstChild("MovingAnimals")
local currentTime = workspace:GetServerTimeNow()
-- Clean up old targets
for animalName, lastTime in pairs(self._recentlyTargeted) do
if (currentTime - lastTime) > 45 then -- Moderate cooldown for lightning
self._recentlyTargeted[animalName] = nil
end
end
local candidates = {}
for _, animal in ipairs(roadAnimals) do
if animal.Parent == movingAnimalsFolder and animal.PrimaryPart and string.find(animal.Name, "RoadAnimal_") then
if not self._recentlyTargeted[animal.Name] and not self:_hasLightningTrait(animal) then
table.insert(candidates, animal)
end
end
end
-- Select multiple animals for lightning barrage
local selectedAnimals = {}
local numToSelect = math.min(maxCount, #candidates)
for i = 1, numToSelect do
if #candidates > 0 then
local randomIndex = math.random(1, #candidates)
local selectedAnimal = candidates[randomIndex]
table.insert(selectedAnimals, selectedAnimal)
table.remove(candidates, randomIndex)
end
end
return selectedAnimals
end
function LightningEvent:_hasLightningTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
return false
end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
for _, trait in ipairs(currentTraits) do
if trait == "Lightning" then
return true
end
end
return false
end
function LightningEvent:_applyLightningTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
return
end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
for _, trait in ipairs(currentTraits) do
if trait == "Lightning" then
return
end
end
table.insert(currentTraits, "Lightning")
animalTemplate:SetAttribute("Traits", HttpService:JSONEncode(currentTraits))
end
return LightningEvent - Edit
03:12:20.464
- Edit
03:12:20.464
============================== - Edit
03:12:20.464 📜 ServerScriptService.Services.EventService.Events.Phase 5: Sammy Snap - Edit
03:12:20.464 ==============================
- Edit
03:12:20.464 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Workspace = game:GetService("Workspace")
local Players = game:GetService("Players")
local Net = require(ReplicatedStorage.Packages.Net)
local Module = {}
Module.__index = Module
function Module.new(eventService)
local self = setmetatable({}, Module)
self._eventService = eventService
self._active = false
self._runningEvents = {}
return self
end
function Module:Start(eventData)
if self._active then return end
self._active = true
self._eventData = eventData or {}
local svc = self._eventService
local events = svc.GetAllEvents and svc:GetAllEvents() or svc.Events
if not events then
warn("[Phase5SammySnapEvent] No events available")
return
end
local validEvents = {}
for _, eventName in ipairs(events) do
if not string.find(eventName, "Phase") then
table.insert(validEvents, eventName)
end
end
if #validEvents == 0 then
warn("[Phase5SammySnapEvent] No valid events to start")
return
end
local function shuffle(t)
for i = #t, 2, -1 do
local j = math.random(i)
t[i], t[j] = t[j], t[i]
end
end
shuffle(validEvents)
local count = math.random(8, 12)
local chosenEvents = {}
for i = 1, math.min(count, #validEvents) do
table.insert(chosenEvents, validEvents[i])
end
task.delay(10, function()
if not self._active then return end
for _, eventName in ipairs(chosenEvents) do
local ok = svc:StartEvent(eventName)
if ok then
table.insert(self._runningEvents, eventName)
else
warn("[Phase5SammySnapEvent] Failed to start event:", eventName)
end
end
end)
end
function Module:Stop()
self._active = false
self._runningEvents = {}
end
return Module
- Edit
03:12:20.464
- Edit
03:12:20.465
============================== - Edit
03:12:20.465 📜 ServerScriptService.Services.EventService.Events.UFO - Edit
03:12:20.465 ==============================
- Edit
03:12:20.465 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local HttpService = game:GetService("HttpService")
local CollectionService = game:GetService("CollectionService")
local RunService = game:GetService("RunService")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local DataManagment = require(ServerScriptService.Services.DataManagment)
local RoadAnimalService = require(ServerScriptService.Services.RoadAnimalService)
local Animals = require(ReplicatedStorage.Datas.Animals)
local UFOEvent = {}
-- CONFIGURATION
UFOEvent.UFO_SPEED = 10
UFOEvent.TRAIT_NAME = "UFO"
UFOEvent.COUNTDOWN_EACH_UFO = {min = 2.5, max = 4} -- random interval
UFOEvent.__index = UFOEvent
function UFOEvent.new(eventService)
local self = setmetatable({}, UFOEvent)
self._eventService = eventService
self._synchronizer = eventService._synchronizer
self._ufoSynchronizer = Synchronizer:Create("UFOEvent", {IsActive = false})
for _, player in pairs(Players:GetPlayers()) do
self._ufoSynchronizer:AddListener(player)
end
Players.PlayerAdded:Connect(function(player)
self._ufoSynchronizer:AddListener(player)
end)
Players.PlayerRemoving:Connect(function(player)
self._ufoSynchronizer:RemoveListener(player)
end)
self._isActive = false
self._ufoSpawnedRemote = Net:RemoteEvent("EventService/UFO/Spawned")
self._ufoAbductionBurstRemote = Net:RemoteEvent("EventService/UFO/AbductionBurst")
self._recentlyTargeted = {}
self._activeUFOs = {}
self._ufoTimers = {}
return self
end
function UFOEvent:Start(eventEntry)
if self._isActive then return end
self._isActive = true
ReplicatedStorage:SetAttribute("UFOEvent", true)
self._ufoSpawnedRemote:FireAllClients()
self._ufoSynchronizer:Set("IsActive", true)
self:_startUFOLoop()
end
function UFOEvent:_startUFOLoop()
if self._ufoTask then task.cancel(self._ufoTask) end
self._ufoTask = task.spawn(function()
while self._isActive do
task.wait(math.random(UFOEvent.COUNTDOWN_EACH_UFO.min * 100, UFOEvent.COUNTDOWN_EACH_UFO.max * 100)/100)
local targetAnimal = self:_pickTargetAnimal()
if targetAnimal then
self:_spawnUFOAbduction(targetAnimal)
end
end
end)
end
function UFOEvent:_spawnUFOAbduction(targetAnimal)
if not targetAnimal or not targetAnimal.PrimaryPart then return end
local animalPosition = targetAnimal.PrimaryPart.Position
local originalY = animalPosition.Y
local ufoTargetPosition = animalPosition + Vector3.new(0, 50, 0)
local ufoModel = self:_createUFO(ufoTargetPosition + Vector3.new(0, 100, -200), targetAnimal)
if not ufoModel then return end
local ufoPart = ufoModel
if ufoModel:IsA("Model") then
ufoPart = ufoModel.PrimaryPart or ufoModel:FindFirstChild("Main")
elseif ufoModel:IsA("BasePart") then
ufoPart = ufoModel
end
if not ufoPart then return end
self._activeUFOs[targetAnimal.Name] = ufoModel
self._recentlyTargeted[targetAnimal.Name] = workspace:GetServerTimeNow()
self._ufoTimers[targetAnimal.Name] = tick()
task.spawn(function()
while ufoModel.Parent do
task.wait(1)
if tick() - self._ufoTimers[targetAnimal.Name] > 10 then
self:_removeUFO(targetAnimal.Name)
break
end
end
end)
task.spawn(function()
local spawnDuration = 1.2
local spawnStartPos = ufoPart.Position
local spawnStartTime = tick()
local spawnConnection
spawnConnection = RunService.Heartbeat:Connect(function()
local elapsed = tick() - spawnStartTime
local progress = math.min(elapsed / spawnDuration, 1)
local easedProgress = 1 - math.cos(progress * math.pi * 0.5)
local newPos = spawnStartPos:Lerp(ufoTargetPosition, easedProgress)
ufoPart.CFrame = CFrame.new(newPos)
if progress >= 1 then
spawnConnection:Disconnect()
end
end)
task.wait(spawnDuration)
ufoPart:SetAttribute("BeamState", "down")
task.wait(0.5)
local liftDuration = 1
local liftStartY = targetAnimal.PrimaryPart.Position.Y
local liftStartTime = tick()
local liftConnection
liftConnection = RunService.Heartbeat:Connect(function()
local elapsed = tick() - liftStartTime
local progress = math.min(elapsed / liftDuration, 1)
local easedProgress = 1 - math.cos(progress * math.pi * 0.5)
if targetAnimal and targetAnimal.PrimaryPart then
local animalPos = targetAnimal.PrimaryPart.Position
local targetY = liftStartY + (ufoTargetPosition.Y - 5 - liftStartY) * easedProgress
targetAnimal:SetPrimaryPartCFrame(CFrame.new(animalPos.X, targetY, animalPos.Z))
ufoPart.CFrame = CFrame.new(animalPos.X, ufoTargetPosition.Y, animalPos.Z)
end
if progress >= 1 or not targetAnimal or not targetAnimal.PrimaryPart then
liftConnection:Disconnect()
end
end)
task.wait(liftDuration)
if targetAnimal and targetAnimal.PrimaryPart then
self._ufoAbductionBurstRemote:FireAllClients(targetAnimal.PrimaryPart.Position)
end
self:_applyUFOTrait(targetAnimal)
task.wait(2)
local lowerDuration = 2
local lowerStartTime = tick()
local startY = targetAnimal.PrimaryPart.Position.Y
local lowerConnection
lowerConnection = RunService.Heartbeat:Connect(function()
local elapsed = tick() - lowerStartTime
local progress = math.min(elapsed / lowerDuration, 1)
local easedProgress = math.sin(progress * math.pi * 0.5)
if targetAnimal and targetAnimal.PrimaryPart then
local animalPos = targetAnimal.PrimaryPart.Position
local newY = startY + (originalY - startY) * easedProgress
targetAnimal:SetPrimaryPartCFrame(CFrame.new(animalPos.X, newY, animalPos.Z))
end
if progress >= 1 or not targetAnimal or not targetAnimal.PrimaryPart then
lowerConnection:Disconnect()
end
end)
task.wait(lowerDuration)
ufoPart:SetAttribute("BeamState", "off")
task.wait(0.5)
local exitDuration = 0.6
local exitStartTime = tick()
local startPos = ufoPart.Position
local exitOffset = Vector3.new(0, 200, 800)
local exitConnection
exitConnection = RunService.Heartbeat:Connect(function()
local elapsed = tick() - exitStartTime
local progress = math.min(elapsed / exitDuration, 1)
local easedProgress = 1 - math.cos(progress * math.pi * 0.5)
local newPos = startPos:Lerp(startPos + exitOffset, easedProgress)
ufoPart.CFrame = CFrame.new(newPos)
if progress >= 1 then
exitConnection:Disconnect()
end
end)
task.wait(exitDuration)
self:_removeUFO(targetAnimal.Name)
end)
end
function UFOEvent:_createUFO(position, targetAnimal)
local ufoBasePart = Instance.new("Part")
ufoBasePart.Name = "UFO_" .. targetAnimal.Name
ufoBasePart.Size = Vector3.new(4, 1, 4)
ufoBasePart.Shape = Enum.PartType.Cylinder
ufoBasePart.Material = Enum.Material.Neon
ufoBasePart.BrickColor = BrickColor.new("Lime green")
ufoBasePart.Anchored = true
ufoBasePart.CanCollide = false
ufoBasePart.CFrame = CFrame.new(position)
CollectionService:AddTag(ufoBasePart, "GalaxyUFO")
ufoBasePart:SetAttribute("BeamState", "off")
ufoBasePart.Parent = workspace
return ufoBasePart
end
function UFOEvent:_removeUFO(animalName)
local ufoModel = self._activeUFOs[animalName]
if ufoModel then
ufoModel:Destroy()
self._activeUFOs[animalName] = nil
self._ufoTimers[animalName] = nil
end
end
function UFOEvent:Stop(eventEntry)
if not self._isActive then return end
self._isActive = false
ReplicatedStorage:SetAttribute("UFOEvent", false)
self._ufoSynchronizer:Set("IsActive", false)
if self._ufoTask then
task.cancel(self._ufoTask)
self._ufoTask = nil
end
for _, ufoModel in pairs(self._activeUFOs) do
if ufoModel then ufoModel:Destroy() end
end
self._activeUFOs = {}
self._ufoTimers = {}
end
function UFOEvent:_pickTargetAnimal()
local roadAnimals = CollectionService:GetTagged("Animal")
local movingAnimalsFolder = workspace:FindFirstChild("MovingAnimals")
local currentTime = workspace:GetServerTimeNow()
for animalName, lastTime in pairs(self._recentlyTargeted) do
if (currentTime - lastTime) > 30 then
self._recentlyTargeted[animalName] = nil
end
end
local candidates = {}
for _, animal in ipairs(roadAnimals) do
if animal.Parent == movingAnimalsFolder and animal.PrimaryPart and string.find(animal.Name, "RoadAnimal_") then
if not self._recentlyTargeted[animal.Name] and not self:_hasUFOTrait(animal) and not self._activeUFOs[animal.Name] then
table.insert(candidates, animal)
end
end
end
if #candidates == 0 then return nil end
return candidates[math.random(1, #candidates)]
end
function UFOEvent:_hasUFOTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then return false end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(HttpService.JSONDecode, HttpService, currentTraitsJson)
if success and type(decoded) == "table" then currentTraits = decoded end
end
for _, trait in ipairs(currentTraits) do
if trait == UFOEvent.TRAIT_NAME then return true end
end
return false
end
function UFOEvent:_applyUFOTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then return end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(HttpService.JSONDecode, HttpService, currentTraitsJson)
if success and type(decoded) == "table" then currentTraits = decoded end
end
for _, trait in ipairs(currentTraits) do
if trait == UFOEvent.TRAIT_NAME then return end
end
table.insert(currentTraits, UFOEvent.TRAIT_NAME)
animalTemplate:SetAttribute("Traits", HttpService:JSONEncode(currentTraits))
end
return UFOEvent - Edit
03:12:20.465
- Edit
03:12:20.465
============================== - Edit
03:12:20.465 📜 ServerScriptService.Services.EventService.Events.Rain - Edit
03:12:20.465 ==============================
- Edit
03:12:20.465 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local HttpService = game:GetService("HttpService")
local CollectionService = game:GetService("CollectionService")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local RainEvent = {}
RainEvent.__index = RainEvent
function RainEvent.new(eventService)
local self = setmetatable({}, RainEvent)
self._rainHitRemote = Net:RemoteEvent("EventService/Rain/Hit")
self._isActive = false
self._rainTask = nil
return self
end
function RainEvent:Start()
if self._isActive then return end
self._isActive = true
self._rainTask = task.spawn(function()
while self._isActive do
task.wait(math.random(3, 4))
local targetAnimal = self:_pickRandomAnimal()
if targetAnimal then
self:_applyRainTrait(targetAnimal)
self._rainHitRemote:FireAllClients(targetAnimal.Name)
end
end
end)
end
function RainEvent:Stop()
self._isActive = false
if self._rainTask then
task.cancel(self._rainTask)
self._rainTask = nil
end
end
function RainEvent:_pickRandomAnimal()
local animals = CollectionService:GetTagged("Animal")
if #animals == 0 then return nil end
return animals[math.random(1, #animals)]
end
function RainEvent:_applyRainTrait(animal)
if not animal or not animal.Parent then return end
local currentTraitsJson = animal:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
for _, trait in ipairs(currentTraits) do
if trait == "Wet" then
return
end
end
table.insert(currentTraits, "Wet")
animal:SetAttribute("Traits", HttpService:JSONEncode(currentTraits))
end
return RainEvent - Edit
03:12:20.465
- Edit
03:12:20.465
============================== - Edit
03:12:20.465 📜 ServerScriptService.Services.EventService.Events.MexicoEvent - Edit
03:12:20.465 ==============================
- Edit
03:12:20.465 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local HttpService = game:GetService("HttpService")
local CollectionService = game:GetService("CollectionService")
local Workspace = game:GetService("Workspace")
local Lighting = game:GetService("Lighting")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local DataManagment = require(ServerScriptService.Services.DataManagment)
local RoadAnimalService = require(ServerScriptService.Services.RoadAnimalService)
local Animals = require(ReplicatedStorage.Datas.Animals)
local MexicoEvent = {}
MexicoEvent.__index = MexicoEvent
function MexicoEvent.new(eventService)
local self = setmetatable({}, MexicoEvent)
self._eventService = eventService
self._synchronizer = eventService._synchronizer
self._mexicoSynchronizer = Synchronizer:Create("MexicoEvent", {
IsActive = false
})
for _, player in pairs(Players:GetPlayers()) do
self._mexicoSynchronizer:AddListener(player)
end
Players.PlayerAdded:Connect(function(player)
self._mexicoSynchronizer:AddListener(player)
if self._isActive and self._music then
self:_playMusicForPlayer(player)
end
end)
Players.PlayerRemoving:Connect(function(player)
self._mexicoSynchronizer:RemoveListener(player)
end)
self._isActive = false
self._music = nil
self._eventFolder = nil
self._skybox = nil
-- Mexico Remote Events
self._mexicoFocusRemote = Net:RemoteEvent("EventService/Mexico/Focus")
self._mexicoBurstRemote = Net:RemoteEvent("EventService/Mexico/Burst")
self._recentlyTargeted = {}
self._activeMexicoHitboxes = {}
self._eventStartTime = nil
return self
end
function MexicoEvent:_playMusicForPlayer(player)
if not self._music then return end
local sound = Instance.new("Sound")
sound.SoundId = "rbxassetid://1837258874" -- Mexico-themed music placeholder
sound.Volume = 0.25
sound.Looped = true
sound.Parent = player.PlayerGui
sound:Play()
return sound
end
function MexicoEvent:Start(eventEntry)
if self._isActive then
return
end
self._isActive = true
self._eventStartTime = workspace:GetServerTimeNow()
print("[MexicoEvent] Starting Mexico event")
ReplicatedStorage:SetAttribute("MexicoEvent", true)
self._mexicoSynchronizer:Set("IsActive", true)
-- Create and configure music
self._music = Instance.new("Sound")
self._music.SoundId = "rbxassetid://1837258874" -- Mexico-themed music placeholder
self._music.Volume = 0.25
self._music.Looped = true
self._music.Parent = ReplicatedStorage
-- Play music for all current players
for _, player in pairs(Players:GetPlayers()) do
self:_playMusicForPlayer(player)
end
-- Clone MexicoEvent folder and its contents from ReplicatedStorage to Workspace
local eventFolder = ReplicatedStorage:FindFirstChild("MexicoEvent")
if eventFolder then
self._eventFolder = eventFolder:Clone()
self._eventFolder.Parent = Workspace
print("[MexicoEvent] Cloned MexicoEvent folder to Workspace with all contents (including models)")
else
warn("[MexicoEvent] MexicoEvent folder not found in ReplicatedStorage")
end
-- Move Sky from MexicoEvent folder to Lighting, if it exists
if eventFolder then
local sky = eventFolder:FindFirstChild("Sky")
if sky then
self._skybox = sky:Clone()
self._skybox.Parent = Lighting
print("[MexicoEvent] Cloned Sky to Lighting")
end
end
self:_startMexicoSequence()
print("[MexicoEvent] Mexico event started successfully")
end
function MexicoEvent:_startMexicoSequence()
if self._mexicoTask then
task.cancel(self._mexicoTask)
end
self._mexicoTask = task.spawn(function()
task.wait(5) -- Initial setup phase
while self._isActive do
local currentTime = workspace:GetServerTimeNow()
local eventRunTime = currentTime - self._eventStartTime
if eventRunTime >= 6 and eventRunTime <= 85 then
task.wait(math.random(3, 7))
local targetAnimal = self:_pickTargetAnimal()
if targetAnimal then
self:_createMexicoHitbox(targetAnimal)
end
elseif eventRunTime > 85 then
task.wait(math.random(8, 12))
local targetAnimal = self:_pickTargetAnimal()
if targetAnimal then
self:_createMexicoHitbox(targetAnimal)
end
else
task.wait(1)
end
end
end)
end
function MexicoEvent:_createMexicoHitbox(targetAnimal)
if not targetAnimal or not targetAnimal.PrimaryPart then
return
end
local animalId = targetAnimal.Name
local animalPosition = targetAnimal.PrimaryPart.Position
local hitboxPart = Instance.new("Part")
hitboxPart.Name = "MexicoHitbox_" .. animalId
hitboxPart.Size = Vector3.new(1, 1, 1)
hitboxPart.Transparency = 1
hitboxPart.Anchored = true
hitboxPart.CanCollide = false
hitboxPart.CFrame = CFrame.new(animalPosition.X, animalPosition.Y + 9, animalPosition.Z)
CollectionService:AddTag(hitboxPart, "MexicoHitbox")
hitboxPart.Parent = Workspace
self._activeMexicoHitboxes[animalId] = hitboxPart
self._recentlyTargeted[animalId] = workspace:GetServerTimeNow()
task.spawn(function()
local focusTime = workspace:GetServerTimeNow() + 1
hitboxPart:SetAttribute("Focused", focusTime)
self._mexicoFocusRemote:FireAllClients(animalId)
task.wait(3)
self:_applyMexicoTrait(targetAnimal)
self._mexicoBurstRemote:FireAllClients(animalId)
task.wait(2)
self:_removeMexicoHitbox(animalId)
end)
end
function MexicoEvent:_removeMexicoHitbox(animalId)
local hitboxPart = self._activeMexicoHitboxes[animalId]
if hitboxPart then
hitboxPart:Destroy()
self._activeMexicoHitboxes[animalId] = nil
end
end
function MexicoEvent:Stop(eventEntry)
if not self._isActive then
return
end
self._isActive = false
print("[MexicoEvent] Stopping Mexico event")
ReplicatedStorage:SetAttribute("MexicoEvent", false)
self._mexicoSynchronizer:Set("IsActive", false)
-- Stop music for all players
for _, player in pairs(Players:GetPlayers()) do
local playerGui = player.PlayerGui
local sound = playerGui:FindFirstChildOfClass("Sound")
if sound then
sound:Stop()
sound:Destroy()
end
end
if self._music then
self._music:Destroy()
self._music = nil
end
-- Remove MexicoEvent folder from Workspace
if self._eventFolder then
self._eventFolder:Destroy()
self._eventFolder = nil
print("[MexicoEvent] Removed MexicoEvent folder from Workspace")
end
-- Remove Sky from Lighting
if self._skybox then
self._skybox:Destroy()
self._skybox = nil
print("[MexicoEvent] Removed Sky from Lighting")
end
if self._mexicoTask then
task.cancel(self._mexicoTask)
self._mexicoTask = nil
end
for animalId, hitboxPart in pairs(self._activeMexicoHitboxes) do
if hitboxPart then
hitboxPart:Destroy()
end
end
self._activeMexicoHitboxes = {}
print("[MexicoEvent] Mexico event stopped")
end
function MexicoEvent:_pickTargetAnimal()
local roadAnimals = CollectionService:GetTagged("Animal")
local movingAnimalsFolder = Workspace:FindFirstChild("MovingAnimals")
local currentTime = workspace:GetServerTimeNow()
for animalId, lastTime in pairs(self._recentlyTargeted) do
if (currentTime - lastTime) > 20 then
self._recentlyTargeted[animalId] = nil
end
end
local candidates = {}
for _, animal in ipairs(roadAnimals) do
if animal.Parent == movingAnimalsFolder and animal.PrimaryPart and string.find(animal.Name, "RoadAnimal_") then
local animalId = animal.Name
if not self._recentlyTargeted[animalId] and
not self:_hasMexicoTrait(animal) and
not self._activeMexicoHitboxes[animalId] then
table.insert(candidates, animal)
end
end
end
if #candidates == 0 then return nil end
return candidates[math.random(1, #candidates)]
end
function MexicoEvent:_hasMexicoTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
return false
end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
for _, trait in ipairs(currentTraits) do
if trait == "Mexico" then
return true
end
end
return false
end
function MexicoEvent:_applyMexicoTrait(animalTemplate)
if not animalTemplate or not animalTemplate.Parent then
return
end
local currentTraitsJson = animalTemplate:GetAttribute("Traits")
local currentTraits = {}
if currentTraitsJson then
local success, decoded = pcall(function()
return HttpService:JSONDecode(currentTraitsJson)
end)
if success and type(decoded) == "table" then
currentTraits = decoded
end
end
for _, trait in ipairs(currentTraits) do
if trait == "Mexico" then
return
end
end
table.insert(currentTraits, "Mexico")
animalTemplate:SetAttribute("Traits", HttpService:JSONEncode(currentTraits))
end
return MexicoEvent - Edit
03:12:20.466
- Edit
03:12:20.466
============================== - Edit
03:12:20.466 📜 ServerScriptService.Services.EventService.Events.YinYangEvent - Edit
03:12:20.466 ==============================
- Edit
03:12:20.466 --!strict
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local HttpService = game:GetService("HttpService")
local CollectionService = game:GetService("CollectionService")
local Workspace = game:GetService("Workspace")
local Lighting = game:GetService("Lighting")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local DataManagment = require(ServerScriptService.Services.DataManagment)
local RoadAnimalService = require(ServerScriptService.Services.RoadAnimalService)
local Animals = require(ReplicatedStorage.Datas.Animals)
local YinYangEvent = {}
YinYangEvent.__index = YinYangEvent
function YinYangEvent.new(eventService)
local self = setmetatable({}, YinYangEvent)
self._eventService = eventService
self._synchronizer = eventService._synchronizer
self._yinYangSynchronizer = Synchronizer:Create("YinYangEvent", {
IsActive = false
})
for _, player in pairs(Players:GetPlayers()) do
self._yinYangSynchronizer:AddListener(player)
end
Players.PlayerAdded:Connect(function(player)
self._yinYangSynchronizer:AddListener(player)
if self._isActive and self._music then
self:_playMusicForPlayer(player)
end
end)
Players.PlayerRemoving:Connect(function(player)
self._yinYangSynchronizer:RemoveListener(player)
end)
self._isActive = false
self._music = nil
self._eventFolder = nil
self._skybox = nil
-- Remote Events
self._yinYangFocusRemote = Net:RemoteEvent("EventService/YinYang/Focus")
self._yinYangBurstRemote = Net:RemoteEvent("EventService/YinYang/Burst")
self._recentlyTargeted = {}
self._activeYinYangHitboxes = {}
self._eventStartTime = nil
-- Mutation auto-binder connection
self._connYinYang = nil
return self
end
-- 🎵 Music per-player
function YinYangEvent:_playMusicForPlayer(player)
if not self._music then return end
local sound = Instance.new("Sound")
sound.SoundId = "rbxassetid://1837258874" -- YinYang event music
sound.Volume = 0.25
sound.Looped = true
sound.Parent = player:WaitForChild("PlayerGui")
sound:Play()
return sound
end
-- mutation event added onto my own credits cvex or free games for leaking ty very much!
function YinYangEvent:_applyYinYangMutation(model)
if not model or not model.Parent then return end
if model:GetAttribute("Mutation") == nil then
model:SetAttribute("Mutation", "YinYang")
end
end
function YinYangEvent:_bindAutoMutation()
if self._connYinYang then return end
self._connYinYang = CollectionService:GetInstanceAddedSignal("Animal"):Connect(function(inst)
if ReplicatedStorage:GetAttribute("YinYangEvent") then
self:_applyYinYangMutation(inst)
end
end)
end
function YinYangEvent:_unbindAutoMutation()
if self._connYinYang then
self._connYinYang:Disconnect()
self._connYinYang = nil
end
end
function YinYangEvent:Start(eventEntry)
if self._isActive then return end
self._isActive = true
self._eventStartTime = workspace:GetServerTimeNow()
print("[YinYangEvent] Starting YinYang event")
ReplicatedStorage:SetAttribute("YinYangEvent", true)
self._yinYangSynchronizer:Set("IsActive", true)
-- Create and configure music
self._music = Instance.new("Sound")
self._music.SoundId = "rbxassetid://1837258874"
self._music.Volume = 0.25
self._music.Looped = true
self._music.Parent = ReplicatedStorage
-- Play music for all players
for _, player in pairs(Players:GetPlayers()) do
self:_playMusicForPlayer(player)
end
-- clone the fucking event nigger
local modelsFolder = ReplicatedStorage:FindFirstChild("Models")
local eventsFolder = modelsFolder and modelsFolder:FindFirstChild("Events")
local eventFolder = eventsFolder and eventsFolder:FindFirstChild("YinYangEvent")
if eventFolder then
self._eventFolder = eventFolder:Clone()
self._eventFolder.Parent = Workspace
print("[YinYangEvent] Cloned YinYangEvent folder into Workspace")
else
warn("[YinYangEvent] YinYangEvent folder not found")
end
-- Skybox
if self._eventFolder then
local sky = self._eventFolder:FindFirstChild("Sky")
if sky then
self._skybox = sky:Clone()
self._skybox.Parent = Lighting
end
end
self:_bindAutoMutation()
for _, a in ipairs(CollectionService:GetTagged("Animal")) do
self:_applyYinYangMutation(a)
end
self:_startYinYangSequence()
print("[YinYangEvent] Event started successfully")
end
function YinYangEvent:_startYinYangSequence()
if self._yinYangTask then
task.cancel(self._yinYangTask)
end
self._yinYangTask = task.spawn(function()
task.wait(5)
while self._isActive do
local currentTime = workspace:GetServerTimeNow()
local runTime = currentTime - self._eventStartTime
if runTime >= 6 and runTime <= 85 then
task.wait(math.random(3, 7))
local target = self:_pickTargetAnimal()
if target then
self:_createYinYangHitbox(target)
end
elseif runTime > 85 then
task.wait(math.random(8, 12))
local target = self:_pickTargetAnimal()
if target then
self:_createYinYangHitbox(target)
end
else
task.wait(1)
end
end
end)
end
function YinYangEvent:_createYinYangHitbox(targetAnimal)
if not targetAnimal or not targetAnimal.PrimaryPart then return end
local id = targetAnimal.Name
local pos = targetAnimal.PrimaryPart.Position
local hitbox = Instance.new("Part")
hitbox.Name = "YinYangHitbox_" .. id
hitbox.Size = Vector3.new(1, 1, 1)
hitbox.Transparency = 1
hitbox.Anchored = true
hitbox.CanCollide = false
hitbox.CFrame = CFrame.new(pos.X, pos.Y + 9, pos.Z)
CollectionService:AddTag(hitbox, "YinYangHitbox")
hitbox.Parent = Workspace
self._activeYinYangHitboxes[id] = hitbox
self._recentlyTargeted[id] = workspace:GetServerTimeNow()
task.spawn(function()
local focusTime = workspace:GetServerTimeNow() + 1
hitbox:SetAttribute("Focused", focusTime)
self._yinYangFocusRemote:FireAllClients(id)
task.wait(3)
self:_applyYinYangTrait(targetAnimal)
self._yinYangBurstRemote:FireAllClients(id)
task.wait(2)
self:_removeYinYangHitbox(id)
end)
end
function YinYangEvent:_removeYinYangHitbox(id)
local h = self._activeYinYangHitboxes[id]
if h then
h:Destroy()
self._activeYinYangHitboxes[id] = nil
end
end
function YinYangEvent:Stop(eventEntry)
if not self._isActive then return end
self._isActive = false
print("[YinYangEvent] Stopping")
ReplicatedStorage:SetAttribute("YinYangEvent", false)
self._yinYangSynchronizer:Set("IsActive", false)
-- Stop music
for _, player in pairs(Players:GetPlayers()) do
local gui = player:FindFirstChild("PlayerGui")
if gui then
for _, s in ipairs(gui:GetChildren()) do
if s:IsA("Sound") then
s:Stop()
s:Destroy()
end
end
end
end
if self._music then
self._music:Destroy()
self._music = nil
end
-- Cleanup world
if self._eventFolder then
self._eventFolder:Destroy()
self._eventFolder = nil
end
if self._skybox then
self._skybox:Destroy()
self._skybox = nil
end
if self._yinYangTask then
task.cancel(self._yinYangTask)
self._yinYangTask = nil
end
for _, h in pairs(self._activeYinYangHitboxes) do
h:Destroy()
end
self._activeYinYangHitboxes = {}
-- Unbind mutation
self:_unbindAutoMutation()
print("[YinYangEvent] Stopped")
end
function YinYangEvent:_pickTargetAnimal()
local roadAnimals = CollectionService:GetTagged("Animal")
local movingFolder = Workspace:FindFirstChild("MovingAnimals")
local now = workspace:GetServerTimeNow()
for id, last in pairs(self._recentlyTargeted) do
if (now - last) > 20 then
self._recentlyTargeted[id] = nil
end
end
local candidates = {}
for _, a in ipairs(roadAnimals) do
if a.Parent == movingFolder and a.PrimaryPart and string.find(a.Name, "RoadAnimal_") then
local id = a.Name
if not self._recentlyTargeted[id] and
not self:_hasYinYangTrait(a) and
not self._activeYinYangHitboxes[id] then
table.insert(candidates, a)
end
end
end
if #candidates == 0 then return nil end
return candidates[math.random(1, #candidates)]
end
-- 🧬 Trait application
function YinYangEvent:_hasYinYangTrait(animal)
if not animal or not animal.Parent then return false end
local traitsJson = animal:GetAttribute("Traits")
local traits = {}
if traitsJson then
local ok, decoded = pcall(function()
return HttpService:JSONDecode(traitsJson)
end)
if ok and type(decoded) == "table" then
traits = decoded
end
end
for _, t in ipairs(traits) do
if t == "YinYang" then
return true
end
end
return false
end
function YinYangEvent:_applyYinYangTrait(animal)
if not animal or not animal.Parent then return end
local traitsJson = animal:GetAttribute("Traits")
local traits = {}
if traitsJson then
local ok, decoded = pcall(function()
return HttpService:JSONDecode(traitsJson)
end)
if ok and type(decoded) == "table" then
traits = decoded
end
end
for _, t in ipairs(traits) do
if t == "YinYang" then
return
end
end
table.insert(traits, "YinYang")
animal:SetAttribute("Traits", HttpService:JSONEncode(traits))
end
return YinYangEvent - Edit
03:12:20.466
- Edit
03:12:20.466
============================== - Edit
03:12:20.466 📜 ServerScriptService.Services.LikeService - Edit
03:12:20.466 ==============================
- Edit
03:12:20.466 --!strict
local LikeService = {}
local HttpService = game:GetService("HttpService")
local ServerScriptService = game:GetService("ServerScriptService")
local AnimalService = require(ServerScriptService.Services.RoadAnimalService.RoadAnimalSpawner)
local LikeBoard = workspace.Map.Codes.Main.SurfaceGui.MainFrame.ProgressBar.Bar
local likeMilestone = 10
local hasInitialized = false
local function formatWithCommas(num: number): string
return tostring(num):reverse():gsub("(%d%d%d)", "%1,"):reverse():gsub("^,", "")
end
function LikeService.Get()
local success, response = pcall(function()
local rawResponse = HttpService:GetAsync("https://games.roproxy.com/v1/games/".. game.GameId .."/votes")
return HttpService:JSONDecode(rawResponse)
end)
if success and response and typeof(response) == "table" and response.upVotes then
local currentLikes = response.upVotes
if not hasInitialized then
likeMilestone = math.floor(currentLikes / 10) * 10 + 10
hasInitialized = true
end
while currentLikes >= likeMilestone do
AnimalService:SpawnAnimalChances({["Spaghetti Tualetti"] = 75, ["Strawberry Elephant"] = 25})
likeMilestone += 10
end
local previousMilestone = likeMilestone - 10
local progressInSegment = currentLikes - previousMilestone
local progressScale = math.clamp(progressInSegment / 10, 0, 1)
LikeBoard.ProgressText.Text = string.format("%s / %s", formatWithCommas(currentLikes), formatWithCommas(likeMilestone))
LikeBoard.Parent.Parent.Message.RequiredLikes.Text = string.format("%s LIKES", formatWithCommas(likeMilestone))
LikeBoard.Progress.Size = UDim2.new(progressScale, 0, 1, 0)
end
end
function LikeService:Start()
if game.PrivateServerId ~= "" then
LikeBoard.Parent.Parent.Message.Visible = false
LikeBoard.Parent.Parent.ProgressBar.Visible = false
LikeBoard.Parent.Parent.PrivateServerMessage.Visible = true
return
end
LikeService.Get()
while true do
task.wait(60)
LikeService.Get()
end
end
return LikeService - Edit
03:12:20.466
- Edit
03:12:20.466
============================== - Edit
03:12:20.466 📜 ServerScriptService.Services.SoftShutdownService - Edit
03:12:20.466 ==============================
- Edit
03:12:20.466 local TeleportService = game:GetService("TeleportService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local SoftShutdown = {}
SoftShutdown.__index = SoftShutdown
function SoftShutdown.new()
local self = setmetatable({}, SoftShutdown)
self.CheckInterval = 10
self.Running = false
return self
end
function SoftShutdown:HandleShutdown()
if (game.VIPServerId ~= "" and game.VIPServerOwnerId == 0) then
local waitTime = 30
Players.PlayerAdded:Connect(function(player)
task.wait(waitTime)
waitTime = waitTime / 2
TeleportService:Teleport(game.PlaceId, player)
end)
for _, player in ipairs(Players:GetPlayers()) do
TeleportService:Teleport(game.PlaceId, player)
task.wait(waitTime)
waitTime = waitTime / 2
end
else
game:BindToClose(function()
if #Players:GetPlayers() == 0 then
return
end
if RunService:IsStudio() then
return
end
local reservedServerCode = TeleportService:ReserveServer(game.PlaceId)
for _, plr in ipairs(Players:GetPlayers()) do
TeleportService:TeleportToPrivateServer(game.PlaceId, reservedServerCode, { plr })
end
Players.PlayerAdded:Connect(function(plr)
TeleportService:TeleportToPrivateServer(game.PlaceId, reservedServerCode, { plr })
end)
while #Players:GetPlayers() > 0 do
task.wait(1)
end
end)
end
end
function SoftShutdown:Start()
if self.Running then return end
self.Running = true
task.spawn(function()
while self.Running do
if RunService:IsServer() then
self:HandleShutdown()
end
task.wait(self.CheckInterval)
end
end)
end
return SoftShutdown - Edit
03:12:20.466
- Edit
03:12:20.466
============================== - Edit
03:12:20.467 📜 ServerScriptService.Services.MonetizationService - Edit
03:12:20.467 ==============================
- Edit
03:12:20.467 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local Packages = ReplicatedStorage.Packages
local Data = ReplicatedStorage.Datas
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local DataManagement = require(ServerScriptService.Services.DataManagment)
local PlayersModule = require(ServerScriptService.Services.Players)
local ShopData = require(Data.Shop)
local CoinHandler = require(script.CoinHandler)
local StarterPackHandler = require(script.StarterPackHandler)
local ServerLuckHandler = require(script.ServerLuckHandler)
local GamepassHandler = require(script.GamepassHandler)
local ItemHandler = require(script.ItemHandler)
local BaseLockHandler = require(script.BaseLockHandler)
local EventsHandler = require(script.EventsHandler)
local TrollHandler = require(script.TrollHandler)
local SkipTimerHandler = require(script.SkipTimerHandler)
local LuckyBlockHandler = require(script.LuckyBlockHandler)
local MoltenSpinHandler = require(script.MoltenSpinHandler)
local GalaxySpinHandler = require(script.GalaxySpinHandler)
local MonetizationService = {}
MonetizationService.__index = MonetizationService
function MonetizationService.new()
local self = setmetatable({}, MonetizationService)
self.CoinHandler = CoinHandler.new(self)
self.StarterPackHandler = StarterPackHandler.new(self)
self.ServerLuckHandler = ServerLuckHandler.new(self)
self.EventsHandler = EventsHandler.new(self)
self.GamepassHandler = GamepassHandler.new(self)
self.ItemHandler = ItemHandler.new(self)
self.BaseLockHandler = BaseLockHandler.new(self)
self.TrollHandler = TrollHandler.new(self)
self.SkipTimerHandler = SkipTimerHandler.new(self)
self.LuckyBlockHandler = LuckyBlockHandler.new(self)
self.MoltenSpinHandler = MoltenSpinHandler.new(self)
self.GalaxySpinHandler = GalaxySpinHandler.new(self)
self._processingReceipts = {}
self._productRegistry = {}
self:_setupMarketplaceEvents()
self:_registerProducts()
self:_setupPlayerEvents()
return self
end
function MonetizationService:_setupMarketplaceEvents()
MarketplaceService.ProcessReceipt = function(receiptInfo)
return self:_processReceipt(receiptInfo)
end
MarketplaceService.PromptProductPurchaseFinished:Connect(function(userId, productId, isPurchased)
self:_onPurchaseFinished(userId, productId, isPurchased)
end)
end
function MonetizationService:_processReceipt(receiptInfo)
local player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
if not player then
return Enum.ProductPurchaseDecision.NotProcessedYet
end
local receiptKey = string.format("%s_%s_%s", receiptInfo.PlayerId, receiptInfo.ProductId, receiptInfo.PurchaseId)
if self._processingReceipts[receiptKey] then
return Enum.ProductPurchaseDecision.PurchaseGranted
end
self._processingReceipts[receiptKey] = true
local productHandler = self._productRegistry[receiptInfo.ProductId]
if not productHandler then
self._processingReceipts[receiptKey] = nil
return Enum.ProductPurchaseDecision.NotProcessedYet
end
local success, result = pcall(function()
return productHandler.handler:ProcessPurchase(player, receiptInfo.ProductId, receiptInfo)
end)
if success and result then
self._processingReceipts[receiptKey] = nil
return Enum.ProductPurchaseDecision.PurchaseGranted
else
self._processingReceipts[receiptKey] = nil
return Enum.ProductPurchaseDecision.NotProcessedYet
end
end
function MonetizationService:_onPurchaseFinished(userId, productId, isPurchased)
local player = Players:GetPlayerByUserId(userId)
if not player then return end
local productHandler = self._productRegistry[productId]
if not productHandler then return end
if productHandler.handler.OnPurchaseFinished then
local success, err = pcall(function()
productHandler.handler:OnPurchaseFinished(player, productId, isPurchased)
end)
if not success then
warn("[MonetizationService] Error in OnPurchaseFinished for product: " .. tostring(productId) .. " Error: " .. tostring(err))
end
end
end
function MonetizationService:_registerProducts()
for productId, productInfo in pairs(ShopData) do
if productInfo.Type == "Coins" then
self:RegisterProduct(productId, "Coins", self.CoinHandler)
elseif productInfo.Type == "StarterPack" then
self:RegisterProduct(productId, "StarterPack", self.StarterPackHandler)
elseif productInfo.Type == "ServerLuck" then
self:RegisterProduct(productId, "ServerLuck", self.ServerLuckHandler)
elseif productInfo.Type == "PaidEvent" then
self:RegisterProduct(productId, "PaidEvent", self.EventsHandler)
elseif productInfo.Type == "Item" then
self:RegisterProduct(productId, "Item", self.ItemHandler)
elseif productInfo.Type == "Gamepass" then
local isValid, _ = pcall(function()
return self.GamepassHandler:ValidateGamepass(productId)
end)
if isValid then
self:RegisterProduct(productId, "Gamepass", self.GamepassHandler)
else
warn("[MonetizationService] Skipping invalid gamepass: " .. tostring(productId) .. " " .. tostring(productInfo.Display))
end
elseif productInfo.Type == "UnlockBase" then
self:RegisterProduct(productId, "UnlockBase", self.BaseLockHandler)
elseif productInfo.Type == "TrollAction" then
self:RegisterProduct(productId, "TrollAction", self.TrollHandler)
elseif productInfo.Type == "SkipTimer" then
self:RegisterProduct(productId, "SkipTimer", self.SkipTimerHandler)
elseif productInfo.Type == "LuckyBlock" then
self:RegisterProduct(productId, "LuckyBlock", self.LuckyBlockHandler)
elseif productInfo.Type == "MoltenWheelSpin" then
self:RegisterProduct(productId, "MoltenWheelSpin", self.MoltenSpinHandler)
elseif productInfo.Type == "GalaxySpinWheel" then
self:RegisterProduct(productId, "GalaxySpinWheel", self.GalaxySpinHandler)
end
end
end
function MonetizationService:RegisterProduct(productId, productType, handler)
self._productRegistry[productId] = {
type = productType,
handler = handler
}
end
function MonetizationService:UnregisterProduct(productId)
self._productRegistry[productId] = nil
end
function MonetizationService:GetProductRegistry()
return self._productRegistry
end
function MonetizationService:GetPlayerData(player)
return DataManagement.GetDataMan(player)
end
function MonetizationService:GetPlayerSynchronizer(player)
return PlayersModule.getSynchronizer(player)
end
function MonetizationService:IsDataReady(player)
return DataManagement.isDataReady(player)
end
function MonetizationService:WaitForData(player, timeout)
return DataManagement.waitForData(player, timeout or 30)
end
function MonetizationService:PromptProductPurchase(player, productId)
local success, err = pcall(function()
MarketplaceService:PromptProductPurchase(player, productId)
end)
if not success then
warn("[MonetizationService] Failed to prompt purchase for product: " .. tostring(productId) .. " Player: " .. player.Name .. " Error: " .. tostring(err))
end
return success
end
function MonetizationService:GetProductInfo(productId, infoType)
local success, productInfo = pcall(function()
if infoType == "Gamepass" then
return MarketplaceService:GetProductInfo(productId, Enum.InfoType.GamePass)
else
return MarketplaceService:GetProductInfo(productId, infoType or Enum.InfoType.Product)
end
end)
if success then
return productInfo
else
warn("[MonetizationService] Failed to get " .. tostring(infoType or "Product") .. " info for: " .. tostring(productId) .. " Error: " .. tostring(productInfo))
return nil
end
end
function MonetizationService:LogPurchase(player, productId, productType, value)
return
end
function MonetizationService:_setupPlayerEvents()
for _, player in ipairs(Players:GetPlayers()) do
task.spawn(function()
if self:WaitForData(player, 30) then
local success, err = pcall(function()
self.StarterPackHandler:CheckAndUpdateOwnership(player)
self.StarterPackHandler:SetupOwnershipMonitoring(player)
self.GamepassHandler:CheckAndUpdateGamepassOwnership(player)
self.GamepassHandler:SetupOwnershipMonitoring(player)
end)
end
end)
end
Players.PlayerAdded:Connect(function(player)
task.spawn(function()
if self:WaitForData(player, 30) then
local success, err = pcall(function()
self.StarterPackHandler:CheckAndUpdateOwnership(player)
self.StarterPackHandler:SetupOwnershipMonitoring(player)
self.GamepassHandler:CheckAndUpdateGamepassOwnership(player)
self.GamepassHandler:SetupOwnershipMonitoring(player)
end)
end
end)
end)
Players.PlayerRemoving:Connect(function(player)
local success, err = pcall(function()
self.GamepassHandler:ClearCache(player)
end)
if not success then
warn("[MonetizationService] Error clearing cache for player: " .. player.Name .. " Error: " .. tostring(err))
end
end)
end
function MonetizationService:GetServerLuckSynchronizer()
return self.ServerLuckHandler:GetSynchronizer()
end
function MonetizationService:PromptGamepassPurchase(player, gamePassId)
local ownershipSuccess, ownsGamepass = pcall(function()
return MarketplaceService:UserOwnsGamePassAsync(player.UserId, gamePassId)
end)
if ownershipSuccess and ownsGamepass then
return false
end
local data = self:GetPlayerData(player)
if data and data.Gamepass then
local productInfo = ShopData[gamePassId]
if productInfo and data.Gamepass[productInfo.Display] then
return false
end
end
local success, err = pcall(function()
MarketplaceService:PromptGamePassPurchase(player, gamePassId)
end)
if not success then
warn("[MonetizationService] Failed to prompt gamepass purchase for: " .. tostring(gamePassId) .. " Player: " .. player.Name .. " Error: " .. tostring(err))
end
return success
end
return MonetizationService - Edit
03:12:20.467
- Edit
03:12:20.467
============================== - Edit
03:12:20.467 📜 ServerScriptService.Services.MonetizationService.StarterPackHandler - Edit
03:12:20.467 ==============================
- Edit
03:12:20.467 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MarketplaceService = game:GetService("MarketplaceService")
local Packages = ReplicatedStorage.Packages
local Data = ReplicatedStorage.Datas
local Net = require(Packages.Net)
local ShopData = require(Data.Shop)
local StarterPackHandler = {}
StarterPackHandler.__index = StarterPackHandler
function StarterPackHandler.new(monetizationService)
local self = setmetatable({}, StarterPackHandler)
self._monetizationService = monetizationService
self._purchaseRemote = Net:RemoteEvent("ShopService/Purchase")
self:_setupRemoteEvents()
return self
end
function StarterPackHandler:_setupRemoteEvents()
self._purchaseRemote.OnServerEvent:Connect(function(player, productId)
if self:_isStarterPackProduct(productId) then
self:PromptPurchase(player, productId)
end
end)
end
function StarterPackHandler:_isStarterPackProduct(productId)
local productInfo = ShopData[tonumber(productId)]
return productInfo and productInfo.Type == "StarterPack"
end
function StarterPackHandler:PromptPurchase(player, productId)
if not self._monetizationService:IsDataReady(player) then
warn("[StarterPackHandler] Player data not ready for purchase:", player.Name)
return false
end
local data = self._monetizationService:GetPlayerData(player)
if not data then
warn("[StarterPackHandler] No data found for player:", player.Name)
return false
end
local productInfo = ShopData[tonumber(productId)]
if not productInfo then
warn("[StarterPackHandler] Product not found:", productId)
return false
end
if data.BoughtStarterPack then
warn("[StarterPackHandler] Player already owns starter pack:", player.Name)
return false
end
if productInfo.Rewards and productInfo.Rewards.Items then
local hasAllItems = true
for _, itemName in pairs(productInfo.Rewards.Items) do
if not (data.Inventory and data.Inventory[itemName]) then
hasAllItems = false
break
end
end
if hasAllItems then
data.BoughtStarterPack = true
local playerPlot = self._monetizationService:GetPlayerSynchronizer(player)
if playerPlot then
playerPlot:Set("BoughtStarterPack", true)
end
return false
end
end
local marketplaceInfo = self._monetizationService:GetProductInfo(tonumber(productId))
if not marketplaceInfo then
warn("[StarterPackHandler] Failed to get marketplace info for:", productId)
return false
end
return self._monetizationService:PromptProductPurchase(player, tonumber(productId))
end
function StarterPackHandler:ProcessPurchase(player, productId, receiptInfo)
if not self._monetizationService:IsDataReady(player) then
warn("[StarterPackHandler] Player data not ready for processing:", player.Name)
return false
end
local playerPlot = self._monetizationService:GetPlayerSynchronizer(player)
if not playerPlot then
warn("[StarterPackHandler] No player synchronizer found for:", player.Name)
return false
end
local data = self._monetizationService:GetPlayerData(player)
if not data then
warn("[StarterPackHandler] No data found for player:", player.Name)
return false
end
local productInfo = ShopData[productId]
if not productInfo or productInfo.Type ~= "StarterPack" then
warn("[StarterPackHandler] Invalid starter pack product:", productId)
return false
end
if productInfo.Rewards and productInfo.Rewards.Items then
local hasAllItems = true
for _, itemName in pairs(productInfo.Rewards.Items) do
if not (data.Inventory and data.Inventory[itemName]) then
hasAllItems = false
break
end
end
if hasAllItems then
-- print("[StarterPackHandler] Player already has all starter pack items:", player.Name)
return true
end
end
data.Inventory = data.Inventory or {}
data.Items = data.Items or {}
if productInfo.Rewards and productInfo.Rewards.Items then
for _, itemName in pairs(productInfo.Rewards.Items) do
data.Inventory[itemName] = true
data.Items[itemName] = true
playerPlot:InsertOnDictionary("Items", itemName, true)
playerPlot:InsertOnDictionary("Inventory", itemName, true)
end
playerPlot:Set("Items", data.Items)
playerPlot:Set("Inventory", data.Inventory)
end
if productInfo.Rewards and productInfo.Rewards.Animals then
local DataManagement = require(game.ServerScriptService.Services.DataManagment)
for _, animalName in pairs(productInfo.Rewards.Animals) do
DataManagement.addAnimal(player, animalName)
end
end
if productInfo.Rewards and productInfo.Rewards.Coins then
data.Coins = (data.Coins or 0) + productInfo.Rewards.Coins
playerPlot:Set("Coins", data.Coins)
end
data.BoughtStarterPack = true
playerPlot:Set("BoughtStarterPack", true)
self._monetizationService:LogPurchase(player, productId, "StarterPack", "Starter Pack purchased")
return true
end
function StarterPackHandler:OnPurchaseFinished(player, productId, isPurchased)
if not isPurchased then
-- print("[StarterPackHandler] Purchase was cancelled for player:", player.Name, "Product:", productId)
return
end
task.wait(1)
local data = self._monetizationService:GetPlayerData(player)
if data and data.BoughtStarterPack then
local productInfo = ShopData[3373926350]
if productInfo and productInfo.Rewards and productInfo.Rewards.Items then
if player.Character and player.Backpack then
for _, itemName in pairs(productInfo.Rewards.Items) do
local hasToolInBackpack = player.Backpack:FindFirstChild(itemName) ~= nil
if not hasToolInBackpack then
local tool = ReplicatedStorage.Items:FindFirstChild(itemName)
if tool and tool:IsA("Tool") then
local clonedTool = tool:Clone()
clonedTool.Parent = player.Backpack
end
end
end
end
end
end
end
function StarterPackHandler:_giveToolsToPlayer(player, itemNames)
if not player.Character or not player.Backpack then
warn("[StarterPackHandler] Player character or backpack not available:", player.Name)
return false
end
local toolsGiven = 0
for _, itemName in pairs(itemNames) do
local tool = ReplicatedStorage.Items:FindFirstChild(itemName)
if tool and tool:IsA("Tool") then
local existingTool = player.Backpack:FindFirstChild(itemName)
if not existingTool then
local clonedTool = tool:Clone()
clonedTool.Parent = player.Backpack
toolsGiven = toolsGiven + 1
end
else
warn("[StarterPackHandler] Tool not found or invalid:", itemName)
end
end
return toolsGiven > 0
end
function StarterPackHandler:CheckAndUpdateOwnership(player)
if not self._monetizationService:IsDataReady(player) then
return false
end
local data = self._monetizationService:GetPlayerData(player)
if not data then
return false
end
local isOwned = data.BoughtStarterPack or false
if not isOwned and data.Items then
local productInfo = ShopData[3373926350]
if productInfo and productInfo.Rewards and productInfo.Rewards.Items then
local hasAllItems = true
for _, itemName in pairs(productInfo.Rewards.Items) do
if not data.Items[itemName] then
hasAllItems = false
break
end
end
if hasAllItems then
data.BoughtStarterPack = true
local playerPlot = self._monetizationService:GetPlayerSynchronizer(player)
if playerPlot then
playerPlot:Set("BoughtStarterPack", true)
end
isOwned = true
end
end
end
if isOwned and player.Character and player.Backpack then
local productInfo = ShopData[3373926350]
if productInfo and productInfo.Rewards and productInfo.Rewards.Items then
local missingTools = {}
for _, itemName in pairs(productInfo.Rewards.Items) do
if not player.Backpack:FindFirstChild(itemName) then
table.insert(missingTools, itemName)
end
end
if #missingTools > 0 then
self:_giveToolsToPlayer(player, missingTools)
end
end
end
return isOwned
end
function StarterPackHandler:SetupOwnershipMonitoring(player)
if not self._monetizationService:IsDataReady(player) then
return
end
local playerPlot = self._monetizationService:GetPlayerSynchronizer(player)
if not playerPlot then
return
end
playerPlot:OnDictionaryInserted("Items", function(key, value)
if value == true then
local productInfo = ShopData[3373926350]
if productInfo and productInfo.Rewards and productInfo.Rewards.Items then
for _, itemName in pairs(productInfo.Rewards.Items) do
if key == itemName then
task.wait(0.1)
self:CheckAndUpdateOwnership(player)
break
end
end
end
end
end)
end
function StarterPackHandler:IsStarterPackOwned(player)
if not self._monetizationService:IsDataReady(player) then
return false
end
local data = self._monetizationService:GetPlayerData(player)
if not data then
return false
end
if data.BoughtStarterPack then
return true
end
if data.Items then
local productInfo = ShopData[3373926350]
if productInfo and productInfo.Rewards and productInfo.Rewards.Items then
for _, itemName in pairs(productInfo.Rewards.Items) do
if not data.Items[itemName] then
return false
end
end
return true
end
end
return false
end
return StarterPackHandler - Edit
03:12:20.467
- Edit
03:12:20.467
============================== - Edit
03:12:20.467 📜 ServerScriptService.Services.MonetizationService.ServerLuckHandler - Edit
03:12:20.467 ==============================
- Edit
03:12:20.467 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MarketplaceService = game:GetService("MarketplaceService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local Packages = ReplicatedStorage.Packages
local Data = ReplicatedStorage.Datas
local Net = require(Packages.Net)
local ShopData = require(Data.Shop)
local ServerLuckData = require(Data.ServerLuck)
local Synchronizer = require(Packages.Synchronizer)
local ServerLuckHandler = {}
ServerLuckHandler.__index = ServerLuckHandler
function ServerLuckHandler.new(monetizationService)
local self = setmetatable({}, ServerLuckHandler)
self._monetizationService = monetizationService
self._purchaseRemote = Net:RemoteEvent("ShopService/Purchase")
self._purchaseDebounce = {}
self._synchronizer = Synchronizer:Create("ServerLuck", {
Index = 0,
EndTime = nil
})
ReplicatedStorage:SetAttribute("ServerLuckMultiplier", 1)
ReplicatedStorage:SetAttribute("ServerLuckEndTime", nil)
self:_setupRemoteEvents()
self:_startUpdateLoop()
self:_setupPlayerListeners()
return self
end
function ServerLuckHandler:_setupRemoteEvents()
self._purchaseRemote.OnServerEvent:Connect(function(player, productId)
if self:_isServerLuckProduct(productId) then
self:PromptPurchase(player, productId)
end
end)
end
function ServerLuckHandler:_isServerLuckProduct(productId)
for _, serverLuckData in pairs(ServerLuckData) do
if serverLuckData.ProductId == tonumber(productId) then
return true
end
end
return false
end
function ServerLuckHandler:_startUpdateLoop()
RunService.Heartbeat:Connect(function()
local endTime = self._synchronizer:Get("EndTime")
if endTime and workspace:GetServerTimeNow() >= endTime then
self._synchronizer:Set("Index", 0)
self._synchronizer:Set("EndTime", nil)
ReplicatedStorage:SetAttribute("ServerLuckMultiplier", 1)
ReplicatedStorage:SetAttribute("ServerLuckEndTime", nil)
end
end)
end
function ServerLuckHandler:_setupPlayerListeners()
for _, player in pairs(Players:GetPlayers()) do
self._synchronizer:AddListener(player)
end
Players.PlayerAdded:Connect(function(player)
self._synchronizer:AddListener(player)
end)
Players.PlayerRemoving:Connect(function(player)
self._synchronizer:RemoveListener(player)
local userId = tostring(player.UserId)
for key, _ in pairs(self._purchaseDebounce) do
if string.sub(key, 1, #userId) == userId then
self._purchaseDebounce[key] = nil
end
end
end)
end
function ServerLuckHandler:_canPurchaseServerLuck(player, productId)
local targetServerLuckInfo = nil
local targetIndex = 0
for index, data in pairs(ServerLuckData) do
if data.ProductId == tonumber(productId) then
targetServerLuckInfo = data
targetIndex = index
break
end
end
if not targetServerLuckInfo then
warn("[ServerLuckHandler] Invalid server luck product for validation:", productId)
return false
end
local currentIndex = self._synchronizer:Get("Index") or 0
local currentEndTime = self._synchronizer:Get("EndTime")
-- allow buying max tier again for extra time
if currentIndex > targetIndex then
local Net = require(ReplicatedStorage.Packages.Net)
local NotificationEvent = Net:RemoteEvent("NotificationService/Notify")
NotificationEvent:FireClient(player,
string.format("Server luck is already %dx or higher!", targetServerLuckInfo.Multiplier), 3)
return false
end
-- if already at this tier but still active, allow buying again (extends time)
if currentIndex == targetIndex and currentEndTime and workspace:GetServerTimeNow() < currentEndTime then
return true
end
return true
end
function ServerLuckHandler:PromptPurchase(player, productId)
local debounceKey = player.UserId .. "_" .. productId
local currentTime = tick()
if self._purchaseDebounce[debounceKey] and currentTime - self._purchaseDebounce[debounceKey] < 2 then
return false
end
self._purchaseDebounce[debounceKey] = currentTime
if not self._monetizationService:IsDataReady(player) then
warn("[ServerLuckHandler] Player data not ready for purchase:", player.Name)
return false
end
local productInfo = ShopData[tonumber(productId)]
if not productInfo then
warn("[ServerLuckHandler] Invalid product ID:", productId)
return false
end
if not self:_canPurchaseServerLuck(player, productId) then
return false
end
local marketplaceInfo = self._monetizationService:GetProductInfo(tonumber(productId))
if not marketplaceInfo then
warn("[ServerLuckHandler] Failed to get marketplace info for:", productId)
return false
end
return self._monetizationService:PromptProductPurchase(player, tonumber(productId))
end
function ServerLuckHandler:ProcessPurchase(player, productId, receiptInfo)
if not self._monetizationService:IsDataReady(player) then
warn("[ServerLuckHandler] Player data not ready for processing:", player.Name)
return false
end
local serverLuckInfo = nil
local newIndex = 0
for index, data in pairs(ServerLuckData) do
if data.ProductId == productId then
serverLuckInfo = data
newIndex = index
break
end
end
if not serverLuckInfo then
warn("[ServerLuckHandler] Invalid server luck product:", productId)
return false
end
local currentTime = workspace:GetServerTimeNow()
local currentEndTime = self._synchronizer:Get("EndTime")
local newEndTime
if newIndex == self._synchronizer:Get("Index") and currentEndTime and currentEndTime > currentTime then
newEndTime = currentEndTime + serverLuckInfo.Duration
else
newEndTime = math.max(currentEndTime or 0, currentTime) + serverLuckInfo.Duration
end
self._synchronizer:Set("Index", newIndex)
self._synchronizer:Set("EndTime", newEndTime)
ReplicatedStorage:SetAttribute("ServerLuckMultiplier", serverLuckInfo.Multiplier)
ReplicatedStorage:SetAttribute("ServerLuckEndTime", newEndTime)
self._monetizationService:LogPurchase(player, productId, "ServerLuck",
string.format("%dx multiplier for %d seconds", serverLuckInfo.Multiplier, serverLuckInfo.Duration))
local Net = require(ReplicatedStorage.Packages.Net)
local NotificationEvent = Net:RemoteEvent("NotificationService/Notify")
for _, otherPlayer in pairs(Players:GetPlayers()) do
NotificationEvent:FireClient(otherPlayer,
string.format("%s extended %dx Luck for the server by %d seconds!",
player.Name, serverLuckInfo.Multiplier, serverLuckInfo.Duration), 5)
end
return true
end
function ServerLuckHandler:OnPurchaseFinished(player, productId, isPurchased)
if isPurchased then
-- success log
else
-- cancel log
end
end
function ServerLuckHandler:GetCurrentLuckMultiplier()
local index = self._synchronizer:Get("Index") or 0
local endTime = self._synchronizer:Get("EndTime")
if index > 0 and endTime and workspace:GetServerTimeNow() < endTime then
local serverLuckInfo = ServerLuckData[index]
return serverLuckInfo and serverLuckInfo.Multiplier or 1
end
return 1
end
function ServerLuckHandler:GetTimeRemaining()
local endTime = self._synchronizer:Get("EndTime")
if endTime and workspace:GetServerTimeNow() < endTime then
return math.max(0, endTime - workspace:GetServerTimeNow())
end
return 0
end
function ServerLuckHandler:GetSynchronizer()
return self._synchronizer
end
return ServerLuckHandler
- Edit
03:12:20.467
- Edit
03:12:20.467
============================== - Edit
03:12:20.467 📜 ServerScriptService.Services.MonetizationService.GamepassHandler - Edit
03:12:20.468 ==============================
- Edit
03:12:20.468 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local Packages = ReplicatedStorage.Packages
local Data = ReplicatedStorage.Datas
local Net = require(Packages.Net)
local ShopData = require(Data.Shop)
local GamepassHandler = {}
GamepassHandler.__index = GamepassHandler
function GamepassHandler.new(monetizationService)
local self = setmetatable({}, GamepassHandler)
self._monetizationService = monetizationService
self._purchaseRemote = Net:RemoteEvent("ShopService/Purchase")
self._gamepassOwnershipCache = {}
self:_setupRemoteEvents()
self:_setupMarketplaceEvents()
return self
end
function GamepassHandler:_setupRemoteEvents()
self._purchaseRemote.OnServerEvent:Connect(function(player, productId)
if self:_isGamepassProduct(productId) then
self._monetizationService:PromptGamepassPurchase(player, tonumber(productId))
end
end)
end
function GamepassHandler:_getActualGamepassId(productId)
local numericProductId = tonumber(productId)
if not numericProductId then
return nil
end
local productInfo = ShopData[numericProductId]
if productInfo and productInfo.Type == "Gamepass" then
return numericProductId
end
return nil
end
function GamepassHandler:_setupMarketplaceEvents()
MarketplaceService.PromptGamePassPurchaseFinished:Connect(function(player, gamePassId, wasPurchased)
if not player or not gamePassId then
warn("[GamepassHandler] Invalid parameters in marketplace event:", player and player.Name or "nil", gamePassId)
return
end
if player and player.Parent then
self:OnGamepassPurchaseFinished(player, gamePassId, wasPurchased)
else
warn("[GamepassHandler] Player not found or disconnected:", player and player.Name or "nil")
end
end)
end
function GamepassHandler:_isGamepassProduct(productId)
local numericProductId = tonumber(productId)
if not numericProductId then
return false
end
local productInfo = ShopData[numericProductId]
return productInfo and productInfo.Type == "Gamepass"
end
function GamepassHandler:ValidateGamepass(productId)
local actualGamepassId = self:_getActualGamepassId(productId)
if not actualGamepassId then
return false, "Product not found or not a gamepass"
end
local productInfo = ShopData[tonumber(productId)]
if not productInfo then
return false, "Product not found in ShopData"
end
if productInfo.Type ~= "Gamepass" then
return false, "Product is not a gamepass"
end
local success, marketplaceInfo = pcall(function()
return MarketplaceService:GetProductInfo(actualGamepassId, Enum.InfoType.GamePass)
end)
if not success then
local errorMsg = tostring(marketplaceInfo)
if string.find(errorMsg, "HTTP 404") then
return false, "Gamepass does not exist in marketplace (ID: " .. actualGamepassId .. ")"
else
return false, "Failed to get marketplace info: " .. errorMsg
end
end
if not marketplaceInfo then
return false, "Gamepass not found in marketplace"
end
return true, marketplaceInfo
end
function GamepassHandler:PromptPurchase(player, productId)
if not self._monetizationService:IsDataReady(player) then
warn("[GamepassHandler] Player data not ready for purchase:", player.Name)
return false
end
local actualGamepassId = self:_getActualGamepassId(productId)
if not actualGamepassId then
warn("[GamepassHandler] Invalid gamepass:", productId, "No matching actual gamepass found")
return false
end
local isValid, result = self:ValidateGamepass(productId)
if not isValid then
warn("[GamepassHandler] Invalid gamepass:", productId, "Reason:", result)
return false
end
local productInfo = ShopData[tonumber(productId)]
local marketplaceInfo = result
local success, ownsGamepass = pcall(function()
return MarketplaceService:UserOwnsGamePassAsync(player.UserId, actualGamepassId)
end)
if not success then
warn("[GamepassHandler] Failed to check gamepass ownership for prompt:", player.Name, productId)
ownsGamepass = self:PlayerOwnsGamepass(player, actualGamepassId)
end
if ownsGamepass then
warn("[GamepassHandler] Player already owns gamepass:", player.Name, productId, "Display:", productInfo.Display)
return false
end
if not marketplaceInfo.IsForSale then
warn("[GamepassHandler] Gamepass is not for sale:", productId, "Display:", productInfo.Display)
return false
end
return self._monetizationService:PromptGamepassPurchase(player, actualGamepassId)
end
function GamepassHandler:ProcessPurchase(player, productId, receiptInfo)
local DataManagement = require(game:GetService("ServerScriptService").Services.DataManagment)
local playerPlot = self._monetizationService:GetPlayerSynchronizer(player)
local numericProductId = tonumber(productId)
if not numericProductId then
warn("[GamepassHandler] Invalid productId in ProcessPurchase:", productId, "Type:", typeof(productId))
return false
end
local productInfo = ShopData[numericProductId]
if not productInfo or productInfo.Type ~= "Gamepass" then
warn("[GamepassHandler] Invalid gamepass product:", numericProductId)
return false
end
local success = DataManagement.addGamepass(player, productInfo.Display)
if not success then
warn("[GamepassHandler] Failed to add gamepass to profile for", player.Name, ":", productInfo.Display)
return false
end
if playerPlot then
local currentGamepasses = DataManagement.getGamepasses(player)
playerPlot:Set("Gamepass", currentGamepasses)
playerPlot:InsertOnDictionary("Gamepass", productInfo.Display, true)
end
if productInfo.Display == "Admin Commands" then
local AdminPanelService = require(game:GetService("ServerScriptService").Services.AdminPanelService)
AdminPanelService:RefreshAdminStatus(player)
print("[GamepassHandler] Admin Commands gamepass purchased, updated admin attribute for:", player.Name)
end
if self._gamepassOwnershipCache[player.UserId] then
self._gamepassOwnershipCache[player.UserId] = nil
end
self._monetizationService:LogPurchase(player, numericProductId, "Gamepass", productInfo.Display)
return true
end
function GamepassHandler:OnGamepassPurchaseFinished(player, gamePassId, wasPurchased)
if wasPurchased then
if not player or not player.Parent then
warn("[GamepassHandler] Player no longer valid after purchase:", gamePassId)
return
end
local numericGamePassId = tonumber(gamePassId)
if not numericGamePassId then
warn("[GamepassHandler] Invalid gamePassId after purchase:", gamePassId, "Type:", typeof(gamePassId))
return
end
self:ClearCache(player)
local productInfo = nil
for productId, info in pairs(ShopData) do
if tonumber(productId) == numericGamePassId then
productInfo = info
break
end
end
if productInfo then
local success = self:ProcessPurchase(player, numericGamePassId, {})
if not success then
warn("[GamepassHandler] Failed to process gamepass purchase for", player.Name, ":", productInfo.Display)
end
else
warn("[GamepassHandler] No product info found for gamepass:", numericGamePassId)
end
end
end
function GamepassHandler:PlayerOwnsGamepass(player, productId)
local actualGamepassId = self:_getActualGamepassId(productId)
if not actualGamepassId then
warn("[GamepassHandler] Invalid productId in PlayerOwnsGamepass:", productId, "Type:", typeof(productId))
return false
end
local userId = player.UserId
local cacheKey = userId
if not self._gamepassOwnershipCache[cacheKey] then
self._gamepassOwnershipCache[cacheKey] = {}
for id, info in pairs(ShopData) do
if info.Type == "Gamepass" then
local success, owns = pcall(function()
return MarketplaceService:UserOwnsGamePassAsync(userId, tonumber(id))
end)
if success then
self._gamepassOwnershipCache[cacheKey][tonumber(id)] = owns
else
warn("[GamepassHandler] Failed to check gamepass ownership:", player.Name, id, owns)
self._gamepassOwnershipCache[cacheKey][tonumber(id)] = false
end
end
end
end
return self._gamepassOwnershipCache[cacheKey][actualGamepassId] or false
end
function GamepassHandler:CheckAndUpdateGamepassOwnership(player)
local DataManagement = require(game:GetService("ServerScriptService").Services.DataManagment)
local playerPlot = self._monetizationService:GetPlayerSynchronizer(player)
if not DataManagement.isDataReady(player) then
return
end
local hasChanges = false
local adminGamepassAdded = false
for productId, productInfo in pairs(ShopData) do
if productInfo.Type == "Gamepass" then
local actualGamepassId = self:_getActualGamepassId(productId)
if actualGamepassId then
local ownsGamepass = self:PlayerOwnsGamepass(player, productId)
local hasInData = DataManagement.hasGamepass(player, productInfo.Display)
if ownsGamepass and not hasInData then
local success = DataManagement.addGamepass(player, productInfo.Display)
if success and playerPlot then
playerPlot:InsertOnDictionary("Gamepass", productInfo.Display, true)
hasChanges = true
if productInfo.Display == "Admin Commands" then
adminGamepassAdded = true
end
end
end
end
end
end
if adminGamepassAdded then
local AdminPanelService = require(game:GetService("ServerScriptService").Services.AdminPanelService)
AdminPanelService:RefreshAdminStatus(player)
print("[GamepassHandler] Admin Commands gamepass detected and added, updated admin attribute for:", player.Name)
end
if hasChanges and playerPlot then
local currentGamepasses = DataManagement.getGamepasses(player)
playerPlot:Set("Gamepass", currentGamepasses)
end
if self._gamepassOwnershipCache[player.UserId] then
self._gamepassOwnershipCache[player.UserId] = nil
end
end
function GamepassHandler:SetupOwnershipMonitoring(player)
if not self._monetizationService:IsDataReady(player) then
return
end
task.spawn(function()
while player and player.Parent do
self:CheckAndUpdateGamepassOwnership(player)
task.wait(30)
end
end)
end
function GamepassHandler:GetPlayerGamepasses(player)
local data = self._monetizationService:GetPlayerData(player)
if data and data.Gamepass then
return data.Gamepass
end
return {}
end
function GamepassHandler:HasGamepass(player, gamepassName)
local DataManagement = require(game:GetService("ServerScriptService").Services.DataManagment)
return DataManagement.hasGamepass(player, gamepassName)
end
function GamepassHandler:GetProductInfo(productId)
return ShopData[tonumber(productId)]
end
function GamepassHandler:GetAllGamepassProducts()
local gamepassProducts = {}
for productId, productInfo in pairs(ShopData) do
if productInfo.Type == "Gamepass" then
gamepassProducts[productId] = productInfo
end
end
return gamepassProducts
end
function GamepassHandler:ClearCache(player)
if player then
self._gamepassOwnershipCache[player.UserId] = nil
else
self._gamepassOwnershipCache = {}
end
end
return GamepassHandler - Edit
03:12:20.468
- Edit
03:12:20.468
============================== - Edit
03:12:20.468 📜 ServerScriptService.Services.MonetizationService.ItemHandler - Edit
03:12:20.468 ==============================
- Edit
03:12:20.468 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Packages = ReplicatedStorage.Packages
local Data = ReplicatedStorage.Datas
local Net = require(Packages.Net)
local ShopData = require(Data.Shop)
local ItemHandler = {}
ItemHandler.__index = ItemHandler
function ItemHandler.new(monetizationService)
local self = setmetatable({}, ItemHandler)
self._monetizationService = monetizationService
self._purchaseRemote = Net:RemoteEvent("ShopService/Purchase")
self:_setupRemoteEvents()
self:_setupPlayerEvents()
--print("[ItemHandler] Initialized successfully")
return self
end
function ItemHandler:_setupRemoteEvents()
self._purchaseRemote.OnServerEvent:Connect(function(player, productId, giftPlayer)
if self:_isItemProduct(productId) then
self:PromptPurchase(player, productId, giftPlayer)
end
end)
end
function ItemHandler:_setupPlayerEvents()
for _, player in pairs(Players:GetPlayers()) do
self:_onPlayerJoined(player)
end
Players.PlayerAdded:Connect(function(player)
self:_onPlayerJoined(player)
end)
end
function ItemHandler:_onPlayerJoined(player)
if player.Character then
self:_givePlayerItems(player)
end
player.CharacterAdded:Connect(function(character)
self:_givePlayerItems(player)
end)
end
function ItemHandler:_givePlayerItems(player)
if not self._monetizationService:IsDataReady(player) then
task.spawn(function()
if self._monetizationService:WaitForData(player, 30) then
self:_givePlayerItems(player)
end
end)
return
end
local data = self._monetizationService:GetPlayerData(player)
if not data then
return
end
data.Items = data.Items or {}
local itemsGiven = {}
for itemName, owned in pairs(data.Items) do
if owned then
self:_givePlayerItem(player, itemName)
itemsGiven[itemName] = true
end
end
self:_verifyAndRecoverMissingItems(player, data, itemsGiven)
end
function ItemHandler:_givePlayerItem(player, itemName)
if self._givingItems and self._givingItems[player.UserId .. "-" .. itemName] then
return false
end
self._givingItems = self._givingItems or {}
self._givingItems[player.UserId .. "-" .. itemName] = true
local MAX_RETRIES = 3
local retryCount = 0
local function attemptGiveTool()
if not player.Character then
warn("[ItemHandler] Player character not found for:", player.Name)
return false
end
local backpack = player:WaitForChild("Backpack", 2)
if not backpack then
warn("[ItemHandler] Backpack not found for player:", player.Name)
return false
end
if backpack:FindFirstChild(itemName) or player.Character:FindFirstChild(itemName) then
return true
end
local itemTool = ReplicatedStorage.Items:FindFirstChild(itemName)
if not itemTool then
warn("[ItemHandler] Failed to find item in ReplicatedStorage:", itemName)
return false
end
local success, toolClone = pcall(function()
local newTool = itemTool:Clone()
newTool.Parent = backpack
return newTool
end)
if success and toolClone then
task.wait(0.2)
if backpack:FindFirstChild(itemName) or player.Character:FindFirstChild(itemName) then
return true
else
return false
end
else
warn("[ItemHandler] Failed to give item:", itemName, "Error:", toolClone)
return false
end
end
local function retryWithBackoff()
while retryCount < MAX_RETRIES do
local success = attemptGiveTool()
if success then
self._givingItems[player.UserId .. "-" .. itemName] = nil
return true
end
retryCount += 1
if retryCount < MAX_RETRIES then
task.wait(0.5 * (2 ^ (retryCount - 1)))
end
end
warn("[ItemHandler] Failed to give item after", MAX_RETRIES, "attempts:", itemName, "to player:", player.Name)
self._givingItems[player.UserId .. "-" .. itemName] = nil
return false
end
return retryWithBackoff()
end
function ItemHandler:_verifyAndRecoverMissingItems(player, data, itemsAlreadyGiven)
if not player or not player.Character then return end
for productId, productInfo in pairs(ShopData) do
if productInfo.Type == "Item" then
local itemName = productInfo.Display
if itemsAlreadyGiven[itemName] then
continue
end
local hasItemInBackpack = player.Backpack and player.Backpack:FindFirstChild(itemName)
local hasItemInCharacter = player.Character and player.Character:FindFirstChild(itemName)
if hasItemInBackpack or hasItemInCharacter then
continue
end
local shouldHaveItem = self:_verifyItemOwnership(player, productId, productInfo, data)
if shouldHaveItem then
--print("[ItemHandler] Recovering missing item for player:", player.Name, itemName)
data.Items = data.Items or {}
data.Items[itemName] = true
local playerPlot = self._monetizationService:GetPlayerSynchronizer(player)
if playerPlot then
playerPlot:InsertOnDictionary("Items", itemName, true)
end
task.spawn(function()
self:_givePlayerItem(player, itemName)
end)
end
end
end
end
function ItemHandler:_verifyItemOwnership(player, productId, productInfo, data)
local itemName = productInfo.Display
if data.Inventory and data.Inventory[itemName] then
--print("[ItemHandler] Found item in Inventory fallback:", player.Name, itemName)
return true
end
if data.OwnedItems and data.OwnedItems[itemName] then
--print("[ItemHandler] Found item in OwnedItems fallback:", player.Name, itemName)
return true
end
if self:_checkStarterPackInclusion(player, itemName, data) then
--print("[ItemHandler] Found item through starter pack inclusion:", player.Name, itemName)
return true
end
if self:_checkPurchaseHistoryIndicators(player, productId, data) then
--print("[ItemHandler] Found item through purchase history:", player.Name, itemName)
return true
end
return false
end
function ItemHandler:_checkStarterPackInclusion(player, itemName, data)
if data.BoughtStarterPack then
for productId, productInfo in pairs(ShopData) do
if productInfo.Type == "StarterPack" and productInfo.Rewards and productInfo.Rewards.Items then
for _, includedItem in pairs(productInfo.Rewards.Items) do
if includedItem == itemName then
return true
end
end
end
end
end
return false
end
function ItemHandler:_checkPurchaseHistoryIndicators(player, productId, data)
if data.PurchaseHistory then
return data.PurchaseHistory[tostring(productId)] ~= nil
end
if data.ProductsPurchased then
return data.ProductsPurchased[tostring(productId)] and data.ProductsPurchased[tostring(productId)] > 0
end
return false
end
function ItemHandler:_isItemProduct(productId)
local productInfo = ShopData[tonumber(productId)]
return productInfo and productInfo.Type == "Item"
end
function ItemHandler:PromptPurchase(player, productId, giftPlayer)
if not self._monetizationService:IsDataReady(player) then
warn("[ItemHandler] Player data not ready for purchase:", player.Name)
return false
end
local productInfo = ShopData[tonumber(productId)]
if not productInfo then
warn("[ItemHandler] Invalid product ID:", productId)
return false
end
local data = self._monetizationService:GetPlayerData(player)
if data and data.Items and data.Items[productInfo.Display] then
local notificationEvent = Net:RemoteEvent("NotificationService/Notify")
notificationEvent:FireClient(player, "You can't purchase this product!", 5, "Sounds.Sfx.Error")
return false
end
if giftPlayer then
warn("[ItemHandler] Item gifting not implemented yet")
return false
end
local marketplaceInfo = self._monetizationService:GetProductInfo(tonumber(productId))
if not marketplaceInfo then
warn("[ItemHandler] Failed to get marketplace info for:", productId)
return false
end
return self._monetizationService:PromptProductPurchase(player, tonumber(productId))
end
function ItemHandler:ProcessPurchase(player, productId, receiptInfo)
if not self._monetizationService:IsDataReady(player) then
warn("[ItemHandler] Player data not ready for processing:", player.Name)
return false
end
local playerPlot = self._monetizationService:GetPlayerSynchronizer(player)
if not playerPlot then
warn("[ItemHandler] No player synchronizer found for:", player.Name)
return false
end
local data = self._monetizationService:GetPlayerData(player)
if not data then
warn("[ItemHandler] No data found for player:", player.Name)
return false
end
local productInfo = ShopData[productId]
if not productInfo or productInfo.Type ~= "Item" then
warn("[ItemHandler] Invalid item product:", productId)
return false
end
if data.Items and data.Items[productInfo.Display] then
print("[ItemHandler] Player already owns item:", player.Name, productInfo.Display)
return true
end
data.Items = data.Items or {}
data.Items[productInfo.Display] = true
playerPlot:InsertOnDictionary("Items", productInfo.Display, true)
local itemTool = ReplicatedStorage.Items:FindFirstChild(productInfo.Display)
if itemTool then
local toolClone = itemTool:Clone()
toolClone.Parent = player.Backpack
-- print("[ItemHandler] Added item to backpack:", player.Name, productInfo.Display)
else
-- warn("[ItemHandler] Item tool not found in ReplicatedStorage.Items:", productInfo.Display)
end
self._monetizationService:LogPurchase(player, productId, "Item", productInfo.Display)
-- print("[ItemHandler] Successfully processed item purchase:", player.Name, productInfo.Display)
return true
end
function ItemHandler:OnPurchaseFinished(player, productId, isPurchased)
if not isPurchased then
-- print("[ItemHandler] Purchase cancelled for player:", player.Name, "Product:", productId)
return
end
local productInfo = ShopData[productId]
if productInfo then
-- print("[ItemHandler] Purchase finished for player:", player.Name, "Item:", productInfo.Display)
end
end
return ItemHandler - Edit
03:12:20.468
- Edit
03:12:20.468
============================== - Edit
03:12:20.468 📜 ServerScriptService.Services.MonetizationService.BaseLockHandler - Edit
03:12:20.468 ==============================
- Edit
03:12:20.468 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local MarketplaceService = game:GetService("MarketplaceService")
local Packages = ReplicatedStorage.Packages
local Data = ReplicatedStorage.Datas
local Services = ServerScriptService.Services
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local ShopData = require(Data.Shop)
local UnlockBaseData = require(Data.UnlockBase)
local Plots = require(ServerScriptService.Services.Plots)
local BaseLockHandler = {}
BaseLockHandler.__index = BaseLockHandler
function BaseLockHandler.new(monetizationService)
local self = setmetatable({}, BaseLockHandler)
self._monetizationService = monetizationService
self._purchaseRemote = Net:RemoteEvent("ShopService/Purchase")
self:_setupRemoteEvents()
return self
end
function BaseLockHandler:_setupRemoteEvents()
self._purchaseRemote.OnServerEvent:Connect(function(player, productId, plotOwnerUserId)
if self:_isUnlockBaseProduct(productId) then
if plotOwnerUserId then
local plotOwner = game.Players:GetPlayerByUserId(plotOwnerUserId)
if not plotOwner then
warn("[BaseLockHandler] Plot owner not found for UserId:", plotOwnerUserId)
return
end
self._pendingPlotOwners = self._pendingPlotOwners or {}
self._pendingPlotOwners[player.UserId .. "_" .. productId] = plotOwner
end
self:PromptPurchase(player, productId)
end
end)
end
function BaseLockHandler:_isUnlockBaseProduct(productId)
local productInfo = ShopData[tonumber(productId)]
return productInfo and productInfo.Type == "UnlockBase"
end
function BaseLockHandler:_getFloorFromProductId(productId)
for floor, data in pairs(UnlockBaseData) do
if data.ProductId == productId then
return floor
end
end
return nil
end
function BaseLockHandler:PromptPurchase(player, productId)
if not self._monetizationService:IsDataReady(player) then
warn("[BaseLockHandler] Player data not ready for purchase:", player.Name)
return false
end
local productInfo = ShopData[tonumber(productId)]
if not productInfo then
warn("[BaseLockHandler] Invalid product ID:", productId)
return false
end
local marketplaceInfo = self._monetizationService:GetProductInfo(tonumber(productId))
if not marketplaceInfo then
warn("[BaseLockHandler] Failed to get marketplace info for:", productId)
return false
end
return self._monetizationService:PromptProductPurchase(player, tonumber(productId))
end
function BaseLockHandler:ProcessPurchase(player, productId, receiptInfo)
if not self._monetizationService:IsDataReady(player) then
warn("[BaseLockHandler] Player data not ready for processing:", player.Name)
return false
end
local targetPlayer = player
local purchaseKey = player.UserId .. "_" .. productId
if self._pendingPlotOwners and self._pendingPlotOwners[purchaseKey] then
targetPlayer = self._pendingPlotOwners[purchaseKey]
self._pendingPlotOwners[purchaseKey] = nil
print(string.format("[BaseLockHandler] %s bought unlock for %s's base", player.Name, targetPlayer.Name))
end
local playerPlot = self._monetizationService:GetPlayerSynchronizer(targetPlayer)
if not playerPlot then
warn("[BaseLockHandler] No synchronizer found for player:", targetPlayer.Name)
return false
end
local productInfo = ShopData[productId]
if not productInfo or productInfo.Type ~= "UnlockBase" then
warn("[BaseLockHandler] Invalid unlock base product:", productId)
return false
end
local floor = self:_getFloorFromProductId(productId)
if not floor then
warn("[BaseLockHandler] Could not determine floor for product:", productId)
return false
end
local floorKey = "BlockEndTime" .. (floor == 1 and "FirstFloor" or floor == 2 and "SecondFloor" or "ThirdFloor")
playerPlot:Set(floorKey, nil)
self:UpdateSpecificFloorState(targetPlayer, floor)
self._monetizationService:LogPurchase(player, productId, "UnlockBase", "Floor " .. floor .. " unlocked for " .. targetPlayer.Name)
print(string.format("[BaseLockHandler] Successfully unlocked floor %d for %s", floor, targetPlayer.Name))
return true
end
function BaseLockHandler:UpdateSpecificFloorState(player, targetFloor)
local plotModel = Plots.getPlotModel(player)
local playerPlot = self._monetizationService:GetPlayerSynchronizer(player)
if not plotModel or not playerPlot then
warn("[BaseLockHandler] Missing plot model or synchronizer for:", player.Name)
return
end
local floorKey = "BlockEndTime" .. (targetFloor == 1 and "FirstFloor" or targetFloor == 2 and "SecondFloor" or "ThirdFloor")
local floorLocked = playerPlot:Get(floorKey) ~= nil
local laserHitbox = plotModel:FindFirstChild("LaserHitbox")
if laserHitbox then
for _, hitbox in pairs(laserHitbox:GetChildren()) do
local hitboxFloor = hitbox:GetAttribute("Floor")
if hitboxFloor == targetFloor then
hitbox.CanCollide = floorLocked
if not floorLocked then
hitbox:SetAttribute("ServerControlled", true)
else
hitbox:SetAttribute("ServerControlled", nil)
end
print(string.format("[BaseLockHandler] Floor %d hitbox CanCollide set to %s, ServerControlled: %s",
hitboxFloor, tostring(floorLocked), tostring(not floorLocked)))
end
end
end
local laser = plotModel:FindFirstChild("Laser")
if laser then
for _, laserModel in pairs(laser:GetChildren()) do
if laserModel:IsA("Model") then
local laserFloor = laserModel:GetAttribute("Floor")
if laserFloor == targetFloor then
for _, laserPart in pairs(laserModel:GetDescendants()) do
if laserPart:IsA("BasePart") then
laserPart.Transparency = floorLocked and 0 or 1
end
end
print(string.format("[BaseLockHandler] Floor %d laser transparency set to %s",
laserFloor, tostring(floorLocked and 0 or 1)))
end
end
end
end
print(string.format("[BaseLockHandler] Updated floor %d state for %s (locked: %s)", targetFloor, player.Name, tostring(floorLocked)))
end
function BaseLockHandler:UpdateAllFloorStates(player)
local plotModel = Plots.getPlotModel(player)
local playerPlot = self._monetizationService:GetPlayerSynchronizer(player)
if not plotModel or not playerPlot then
warn("[BaseLockHandler] Missing plot model or synchronizer for:", player.Name)
return
end
local baseLocked = playerPlot:Get("BlockEndTime") ~= nil
local laserHitbox = plotModel:FindFirstChild("LaserHitbox")
if laserHitbox then
for _, hitbox in pairs(laserHitbox:GetChildren()) do
local hitboxFloor = hitbox:GetAttribute("Floor")
if hitboxFloor and hitboxFloor >= 1 and hitboxFloor <= 3 then
local floorKey = "BlockEndTime" .. (hitboxFloor == 1 and "FirstFloor" or hitboxFloor == 2 and "SecondFloor" or "ThirdFloor")
local floorLocked = playerPlot:Get(floorKey) ~= nil
hitbox.CanCollide = floorLocked
if not floorLocked then
hitbox:SetAttribute("ServerControlled", true)
else
hitbox:SetAttribute("ServerControlled", nil)
end
print(string.format("[BaseLockHandler] Floor %d hitbox set to %s, ServerControlled: %s",
hitboxFloor, tostring(floorLocked), tostring(not floorLocked)))
else
hitbox.CanCollide = baseLocked
end
end
end
local laser = plotModel:FindFirstChild("Laser")
if laser then
for _, laserModel in pairs(laser:GetChildren()) do
if laserModel:IsA("Model") then
local laserFloor = laserModel:GetAttribute("Floor")
if laserFloor and laserFloor >= 1 and laserFloor <= 3 then
local floorKey = "BlockEndTime" .. (laserFloor == 1 and "FirstFloor" or laserFloor == 2 and "SecondFloor" or "ThirdFloor")
local floorLocked = playerPlot:Get(floorKey) ~= nil
for _, laserPart in pairs(laserModel:GetDescendants()) do
if laserPart:IsA("BasePart") then
laserPart.Transparency = floorLocked and 0 or 1
end
end
print(string.format("[BaseLockHandler] Floor %d laser visibility set to %s (floor: %s)",
laserFloor, tostring(floorLocked and 0 or 1), tostring(floorLocked)))
else
for _, laserPart in pairs(laserModel:GetDescendants()) do
if laserPart:IsA("BasePart") then
laserPart.Transparency = baseLocked and 0 or 1
end
end
end
end
end
end
print(string.format("[BaseLockHandler] Updated all floor states for %s", player.Name))
end
function BaseLockHandler:OnPurchaseFinished(player, productId, isPurchased)
if isPurchased then
print(string.format("[BaseLockHandler] Purchase completed for %s: %s", player.Name, productId))
else
print(string.format("[BaseLockHandler] Purchase cancelled for %s: %s", player.Name, productId))
end
end
function BaseLockHandler:IsFloorLocked(player, floor)
local playerPlot = self._monetizationService:GetPlayerSynchronizer(player)
if not playerPlot then
return false
end
local floorKey = "BlockEndTime" .. (floor == 1 and "FirstFloor" or floor == 2 and "SecondFloor" or "ThirdFloor")
local blockEndTime = playerPlot:Get(floorKey)
if not blockEndTime then
return false
end
local currentTime = workspace:GetServerTimeNow()
return currentTime < blockEndTime
end
function BaseLockHandler:GetFloorUnlockProductId(floor)
local data = UnlockBaseData[floor]
return data and data.ProductId or nil
end
return BaseLockHandler - Edit
03:12:20.468
- Edit
03:12:20.468
============================== - Edit
03:12:20.469 📜 ServerScriptService.Services.MonetizationService.CoinHandler - Edit
03:12:20.469 ==============================
- Edit
03:12:20.469 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MarketplaceService = game:GetService("MarketplaceService")
local Packages = ReplicatedStorage.Packages
local Data = ReplicatedStorage.Datas
local Net = require(Packages.Net)
local ShopData = require(Data.Shop)
local CoinHandler = {}
CoinHandler.__index = CoinHandler
function CoinHandler.new(monetizationService)
local self = setmetatable({}, CoinHandler)
self._monetizationService = monetizationService
self._purchaseRemote = Net:RemoteEvent("ShopService/Purchase")
self:_setupRemoteEvents()
-- print("[CoinHandler] Initialized successfully")
return self
end
function CoinHandler:_setupRemoteEvents()
self._purchaseRemote.OnServerEvent:Connect(function(player, productId)
if self:_isCoinProduct(productId) then
self:PromptPurchase(player, productId)
end
end)
end
function CoinHandler:_isCoinProduct(productId)
local productInfo = ShopData[tonumber(productId)]
return productInfo and productInfo.Type == "Coins"
end
function CoinHandler:PromptPurchase(player, productId)
if not self._monetizationService:IsDataReady(player) then
warn("[CoinHandler] Player data not ready for purchase:", player.Name)
return false
end
local productInfo = ShopData[tonumber(productId)]
if not productInfo then
warn("[CoinHandler] Invalid product ID:", productId)
return false
end
local marketplaceInfo = self._monetizationService:GetProductInfo(tonumber(productId))
if not marketplaceInfo then
warn("[CoinHandler] Failed to get marketplace info for:", productId)
return false
end
return self._monetizationService:PromptProductPurchase(player, tonumber(productId))
end
function CoinHandler:ProcessPurchase(player, productId, receiptInfo)
if not self._monetizationService:IsDataReady(player) then
warn("[CoinHandler] Player data not ready for processing:", player.Name)
return false
end
local playerPlot = self._monetizationService:GetPlayerSynchronizer(player)
if not playerPlot then
warn("[CoinHandler] No synchronizer found for player:", player.Name)
return false
end
local data = self._monetizationService:GetPlayerData(player)
if not data then
warn("[CoinHandler] No data found for player:", player.Name)
return false
end
local productInfo = ShopData[productId]
if not productInfo or productInfo.Type ~= "Coins" then
warn("[CoinHandler] Invalid coin product:", productId)
return false
end
local coinValue = productInfo.Value or 0
local rebirthLevel = data.Rebirths or 0
if rebirthLevel > 0 then
coinValue = coinValue * (rebirthLevel <= 1 and 1.5 or rebirthLevel)
end
data.Coins = (data.Coins or 0) + coinValue
playerPlot:Set("Coins", data.Coins)
self._monetizationService:LogPurchase(player, productId, "Coins", coinValue .. " coins")
--print(string.format("[CoinHandler] Granted %d coins to %s (Product: %s)", coinValue, player.Name, productInfo.Display))
return true
end
function CoinHandler:OnPurchaseFinished(player, productId, isPurchased)
if isPurchased then
-- print(string.format("[CoinHandler] Purchase completed for %s: %s", player.Name, productId))
else
-- print(string.format("[CoinHandler] Purchase cancelled for %s: %s", player.Name, productId))
end
end
function CoinHandler:GetPlayerCoins(player)
local data = self._monetizationService:GetPlayerData(player)
return data and data.Coins or 0
end
function CoinHandler:AddCoins(player, amount, reason)
if not self._monetizationService:IsDataReady(player) then
warn("[CoinHandler] Player data not ready for adding coins:", player.Name)
return false
end
local playerPlot = self._monetizationService:GetPlayerSynchronizer(player)
if not playerPlot then
warn("[CoinHandler] No synchronizer found for player:", player.Name)
return false
end
local data = self._monetizationService:GetPlayerData(player)
if not data then
warn("[CoinHandler] No data found for player:", player.Name)
return false
end
data.Coins = (data.Coins or 0) + amount
playerPlot:Set("Coins", data.Coins)
--print(string.format("[CoinHandler] Added %d coins to %s (Reason: %s)", amount, player.Name, reason or "Unknown"))
return true
end
function CoinHandler:RemoveCoins(player, amount, reason)
if not self._monetizationService:IsDataReady(player) then
warn("[CoinHandler] Player data not ready for removing coins:", player.Name)
return false
end
local playerPlot = self._monetizationService:GetPlayerSynchronizer(player)
if not playerPlot then
warn("[CoinHandler] No synchronizer found for player:", player.Name)
return false
end
local data = self._monetizationService:GetPlayerData(player)
if not data then
warn("[CoinHandler] No data found for player:", player.Name)
return false
end
local currentCoins = data.Coins or 0
if currentCoins < amount then
warn(string.format("[CoinHandler] Player %s doesn't have enough coins. Has: %d, Needs: %d",
player.Name, currentCoins, amount))
return false
end
data.Coins = currentCoins - amount
playerPlot:Set("Coins", data.Coins)
--print(string.format("[CoinHandler] Removed %d coins from %s (Reason: %s)", amount, player.Name, reason or "Unknown"))
return true
end
function CoinHandler:GetProductInfo(productId)
return ShopData[tonumber(productId)]
end
function CoinHandler:GetAllCoinProducts()
local coinProducts = {}
for productId, productInfo in pairs(ShopData) do
if productInfo.Type == "Coins" then
coinProducts[productId] = productInfo
end
end
return coinProducts
end
return CoinHandler - Edit
03:12:20.469
- Edit
03:12:20.469
============================== - Edit
03:12:20.469 📜 ServerScriptService.Services.MonetizationService.EventsHandler - Edit
03:12:20.469 ==============================
- Edit
03:12:20.469 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Packages = ReplicatedStorage.Packages
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local ShopData = require(ReplicatedStorage.Datas.Shop)
local EventsHandler = {}
EventsHandler.__index = EventsHandler
-- List of all individual events
local AllEventsList = {
"La Vacca Saturno Saturnita",
"Matteo",
"Nyan Cats",
"Raining Tacos",
"4th of July",
"Tung Tung Attack",
"Crab Rave",
"Molten",
"Concert",
"Snow",
"10B Visits",
"Glitch",
"Rainbow",
"Water",
"Brazil",
}
function EventsHandler.new(monetizationService)
local self = setmetatable({}, EventsHandler)
self._monetizationService = monetizationService
self._purchaseRemote = Net:RemoteEvent("ShopService/Purchase")
self._queuedEvents = {}
self:_setupRemoteEvents()
self:_setupSynchronizerListener()
return self
end
function EventsHandler:_setupRemoteEvents()
self._purchaseRemote.OnServerEvent:Connect(function(player, productId)
if self:_isEventProduct(productId) then
self:PromptPurchase(player, productId)
end
end)
end
function EventsHandler:_isEventProduct(productId)
local info = ShopData[tonumber(productId)]
return info and info.Type == "PaidEvent"
end
function EventsHandler:PromptPurchase(player, productId)
if not self._monetizationService:IsDataReady(player) then return false end
local productInfo = ShopData[tonumber(productId)]
if not productInfo then return false end
return self._monetizationService:PromptProductPurchase(player, tonumber(productId))
end
function EventsHandler:ProcessPurchase(player, productId, receiptInfo)
local productInfo = ShopData[productId]
if not productInfo or productInfo.Type ~= "PaidEvent" then
return false
end
local eventName = productInfo.EventName or productInfo.Display
local duration = 360
local eventService = _G.EventService
if not eventService then
warn("[EventsHandler] EventService not available")
return false
end
-- Handle AllEvents
if eventName == "AllEvents" then
for _, ev in ipairs(AllEventsList) do
task.spawn(function()
local success, result = pcall(function()
return eventService:StartEvent(ev, duration)
end)
if not success then
warn("[EventsHandler] Failed to start event: " .. ev .. " Error: " .. tostring(result))
end
end)
end
else
local callSuccess, startResult = pcall(function()
return eventService:StartEvent(eventName, duration)
end)
if not callSuccess then
warn("[EventsHandler] Error starting event: " .. tostring(startResult))
end
end
-- Queue if not started (optional)
if not eventService:IsEventActive(eventName) then
self._queuedEvents[eventName] = (self._queuedEvents[eventName] or 0) + 1
end
-- Notify all players
local NotificationEvent = Net:RemoteEvent("NotificationService/Notify")
local notifyMessage = (eventName == "AllEvents") and
string.format("%s bought ALL EVENTS!", player.Name) or
string.format("%s bought '%s' event!", player.Name, eventName)
for _, plr in ipairs(Players:GetPlayers()) do
NotificationEvent:FireClient(plr, notifyMessage, 4)
end
self._monetizationService:LogPurchase(player, productId, "PaidEvent", eventName)
return true
end
function EventsHandler:_setupSynchronizerListener()
task.spawn(function()
local eventsSync = Synchronizer:Wait("Events")
eventsSync:OnArrayRemoved("ActiveEvents", function(eventData)
local evName = eventData.eventName
if self._queuedEvents[evName] and self._queuedEvents[evName] > 0 then
self._queuedEvents[evName] = self._queuedEvents[evName] - 1
local eventService = _G.EventService
if eventService then
eventService:StartEvent(evName, 360)
end
end
end)
end)
end
function EventsHandler:OnPurchaseFinished(player, productId, isPurchased)
-- Optional: add any post-purchase logic here
end
return EventsHandler
- Edit
03:12:20.469
- Edit
03:12:20.469
============================== - Edit
03:12:20.469 📜 ServerScriptService.Services.MonetizationService.TrollHandler - Edit
03:12:20.469 ==============================
- Edit
03:12:20.469 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local ShopData = require(ReplicatedStorage.Datas.Shop)
local DataManagement = require(ServerScriptService.Services.DataManagment)
local ProfileStore = require(ServerScriptService.Controllers.ProfileStore)
local NotificationEvent = Net:RemoteEvent("NotificationService/Notify")
local TrollHandler = {}
TrollHandler.__index = TrollHandler
function TrollHandler.new(monetizationService)
local self = setmetatable({}, TrollHandler)
self._monetizationService = monetizationService
self._purchaseRemote = Net:RemoteEvent("ShopService/Purchase")
self._pendingTargets = {}
self:_setupRemoteEvents()
return self
end
function TrollHandler:_isTrollProduct(productId)
local info = ShopData[tonumber(productId)]
return info and info.Type == "TrollAction"
end
function TrollHandler:_setupRemoteEvents()
self._purchaseRemote.OnServerEvent:Connect(function(player, productId, targetUserId)
if not self:_isTrollProduct(productId) then return end
if typeof(targetUserId) ~= "number" then
targetUserId = tonumber(targetUserId)
end
if not targetUserId then return end
self._pendingTargets[player.UserId] = targetUserId
self:PromptPurchase(player, productId)
end)
end
function TrollHandler:PromptPurchase(player, productId)
if not self._monetizationService:IsDataReady(player) then return false end
return self._monetizationService:PromptProductPurchase(player, tonumber(productId))
end
local function notifyAll(message, duration)
for _, plr in ipairs(Players:GetPlayers()) do
NotificationEvent:FireClient(plr, message, duration or 4)
end
end
local function safeHumanoid(player)
if player and player.Character then
return player.Character:FindFirstChildOfClass("Humanoid")
end
end
local function safeRoot(player)
if player and player.Character then
return player.Character:FindFirstChild("HumanoidRootPart")
end
end
function TrollHandler:ProcessPurchase(player, productId, receiptInfo)
local productInfo = ShopData[productId]
if not productInfo or productInfo.Type ~= "TrollAction" then
return false
end
local targetUserId = self._pendingTargets[player.UserId]
self._pendingTargets[player.UserId] = nil
if not targetUserId then
warn("[TrollHandler] No pending target for player", player.Name)
return false
end
local targetPlayer = Players:GetPlayerByUserId(targetUserId)
if not targetPlayer then
warn("[TrollHandler] Target player not found")
return false
end
local action = productInfo.Action
if action == "Kill" then
local hum = safeHumanoid(targetPlayer)
if hum then hum.Health = 0 end
notifyAll(string.format("%s was eliminated by %s", targetPlayer.Name, player.Name), 4)
elseif action == "Fling" then
local root = safeRoot(targetPlayer)
if root then
local oldImpulse = root:FindFirstChild("TrollFlingImpulse")
if oldImpulse then
oldImpulse:Destroy()
end
for _, child in ipairs(root:GetChildren()) do
if child:IsA("BodyVelocity") or child:IsA("LinearVelocity") then
child:Destroy()
end
end
local bv = Instance.new("BodyVelocity")
bv.Name = "TrollFlingImpulse"
bv.MaxForce = Vector3.new(1e6, 1e6, 1e6)
bv.P = 1e5
bv.Velocity = Vector3.new(math.random(-450,450), math.random(700,900), math.random(-450,450))
bv.Parent = root
game:GetService("Debris"):AddItem(bv, 1.5)
root.AssemblyAngularVelocity = Vector3.new(math.random(-350,350), math.random(-350,350), math.random(-350,350))
end
notifyAll(string.format("%s was launched sky-high by %s!", targetPlayer.Name, player.Name), 4)
elseif action == "Goto" then
local rootPlayer = safeRoot(player)
local rootTarget = safeRoot(targetPlayer)
if rootPlayer and rootTarget then
rootPlayer.CFrame = rootTarget.CFrame + Vector3.new(0, 2, 0)
end
NotificationEvent:FireClient(player, string.format("Teleported to %s", targetPlayer.Name), 3)
elseif action == "ResetData" then
local success = DataManagement.resetPlayerData(targetPlayer)
if success then
notifyAll(string.format("%s's data was reset by %s", targetPlayer.Name, player.Name), 4)
else
warn("[TrollHandler] Failed to reset data for player:", targetPlayer.Name)
NotificationEvent:FireClient(player, "Failed to reset player's data. Please try again.", 4)
end
end
self._monetizationService:LogPurchase(player, productId, "TrollAction", action .. "->" .. targetUserId)
return true
end
function TrollHandler:OnPurchaseFinished(player, productId, isPurchased)
end
return TrollHandler - Edit
03:12:20.469
- Edit
03:12:20.469
============================== - Edit
03:12:20.469 📜 ServerScriptService.Services.MonetizationService.SkipTimerHandler - Edit
03:12:20.469 ==============================
- Edit
03:12:20.470 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local Packages = ReplicatedStorage.Packages
local Net = require(Packages.Net)
local DataManagement = require(ServerScriptService.Services.DataManagment)
local SkipTimerHandler = {}
SkipTimerHandler.__index = SkipTimerHandler
local SKIP_TIMER_PRODUCT_ID = 3373876887
function SkipTimerHandler.new(monetizationService)
local self = setmetatable({}, SkipTimerHandler)
self._monetizationService = monetizationService
self._purchaseRemote = Net:RemoteEvent("ShopService/Purchase")
self:_setupRemoteEvents()
return self
end
function SkipTimerHandler:_setupRemoteEvents()
self._purchaseRemote.OnServerEvent:Connect(function(player, productId)
if tonumber(productId) == SKIP_TIMER_PRODUCT_ID then
self:PromptPurchase(player, productId)
end
end)
end
function SkipTimerHandler:PromptPurchase(player, productId)
if not self._monetizationService:IsDataReady(player) then
warn("[SkipTimerHandler] Player data not ready for purchase: " .. player.Name)
return false
end
if tonumber(productId) ~= SKIP_TIMER_PRODUCT_ID then
warn("[SkipTimerHandler] Invalid product ID: " .. tostring(productId))
return false
end
local marketplaceInfo = self._monetizationService:GetProductInfo(tonumber(productId))
if not marketplaceInfo then
warn("[SkipTimerHandler] Failed to get marketplace info for: " .. tostring(productId))
return false
end
return self._monetizationService:PromptProductPurchase(player, tonumber(productId))
end
function SkipTimerHandler:ProcessPurchase(player, productId, receiptInfo)
if not self._monetizationService:IsDataReady(player) then
warn("[SkipTimerHandler] Player data not ready for processing: " .. player.Name)
return false
end
if tonumber(productId) ~= SKIP_TIMER_PRODUCT_ID then
warn("[SkipTimerHandler] Invalid product ID: " .. tostring(productId))
return false
end
local success, err = pcall(function()
DataManagement.setHourPickCooldown(player, 0)
local UpdateCooldownEvent = Net:RemoteEvent("Update/Player/Cooldown")
UpdateCooldownEvent:FireClient(player, 0)
end)
if success then
self._monetizationService:LogPurchase(player, productId, "SkipTimer", "1HourPick Timer Reset")
DataManagement.setHourPickCooldown(player, 0)
if _G.ResetHourPickCooldown then
_G.ResetHourPickCooldown(player)
end
return true
else
warn("[SkipTimerHandler] Failed to reset timer for player: " .. player.Name .. " Error: " .. tostring(err))
return false
end
end
function SkipTimerHandler:OnPurchaseFinished(player, productId, isPurchased)
if isPurchased then
self._monetizationService:LogPurchase(player, productId, "SkipTimer", "Purchase Completed")
end
end
return SkipTimerHandler - Edit
03:12:20.470
- Edit
03:12:20.470
============================== - Edit
03:12:20.470 📜 ServerScriptService.Services.MonetizationService.LuckyBlockHandler - Edit
03:12:20.470 ==============================
- Edit
03:12:20.470 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local MarketplaceService = game:GetService("MarketplaceService")
local DataManagement = require(ServerScriptService.Services.DataManagment)
local ShopData = require(ReplicatedStorage.Datas.Shop)
local LuckyBlocks = require(ReplicatedStorage.Datas.LuckyBlocks)
local Net = require(ReplicatedStorage.Packages.Net)
local NotificationEvent = Net:RemoteEvent("NotificationService/Notify")
local LuckyBlockHandler = {}
LuckyBlockHandler.__index = LuckyBlockHandler
function LuckyBlockHandler.new(monetizationService)
local self = setmetatable({}, LuckyBlockHandler)
self._monetizationService = monetizationService
self._purchaseRemote = Net:RemoteEvent("ShopService/Purchase")
self:_setupRemoteEvents()
return self
end
function LuckyBlockHandler:Initialize()
for luckyBlockName, luckyBlockData in pairs(LuckyBlocks) do
if luckyBlockData.ProductId then
self._monetizationService:RegisterProduct(luckyBlockData.ProductId, "LuckyBlock", self)
end
end
end
function LuckyBlockHandler:_setupRemoteEvents()
self._purchaseRemote.OnServerEvent:Connect(function(player, productId)
if not self:CanHandleProduct(productId) then
return
end
self:PromptPurchase(player, productId)
end)
end
function LuckyBlockHandler:CanHandleProduct(productId)
local productInfo = ShopData[productId]
return productInfo and productInfo.Type == "LuckyBlock"
end
function LuckyBlockHandler:PromptPurchase(player, productId)
if not self._monetizationService:IsDataReady(player) then
return false
end
local hasEmptySlot = self:_hasEmptySlot(player)
if not hasEmptySlot then
NotificationEvent:FireClient(player, "You can't purchase this product, base is full!", 5)
return false
end
local marketplaceInfo = MarketplaceService:GetProductInfo(tonumber(productId), Enum.InfoType.Product)
if not marketplaceInfo then
return false
end
return self._monetizationService:PromptProductPurchase(player, tonumber(productId))
end
function LuckyBlockHandler:ProcessPurchase(player, productId, receiptInfo)
if not self._monetizationService:IsDataReady(player) then
return false
end
local productInfo = ShopData[productId]
if not productInfo or productInfo.Type ~= "LuckyBlock" then
return false
end
local hasEmptySlot = self:_hasEmptySlot(player)
if not hasEmptySlot then
NotificationEvent:FireClient(player, "No empty slots available!", 5)
return false
end
local luckyBlockData = nil
local luckyBlockName = nil
for name, data in pairs(LuckyBlocks) do
if data.ProductId == productId then
luckyBlockData = data
luckyBlockName = name
break
end
end
if not luckyBlockData then
return false
end
local success, slotNumber = pcall(function()
local mutation = nil
if ReplicatedStorage:GetAttribute("GalaxyEvent") == true then
mutation = "Galaxy"
end
local slot = DataManagement.addAnimal(player, luckyBlockName, mutation, nil)
local animalList = DataManagement.getAnimalList(player)
if animalList[slot] and typeof(animalList[slot]) == "table" then
animalList[slot].Timer = 0
end
return slot
end)
if success and slotNumber then
self._monetizationService:LogPurchase(player, productId, "LuckyBlock", luckyBlockName)
return true
else
NotificationEvent:FireClient(player, "There was an error adding a Lucky Block to your plot.", 5)
return false
end
end
function LuckyBlockHandler:OnPurchaseFinished(player, productId, isPurchased)
if isPurchased then
else
end
end
function LuckyBlockHandler:_hasEmptySlot(player)
if not DataManagement.isDataReady(player) then
return false
end
local animalList = DataManagement.getAnimalList(player)
if not animalList then
return false
end
local maxAnimals = DataManagement.GetMaxAnimals(player)
for i = 1, maxAnimals do
if animalList[i] == "Empty" or animalList[i] == nil then
return true
end
end
return false
end
return LuckyBlockHandler - Edit
03:12:20.470
- Edit
03:12:20.470
============================== - Edit
03:12:20.470 📜 ServerScriptService.Services.MonetizationService.MoltenSpinHandler - Edit
03:12:20.470 ==============================
- Edit
03:12:20.470 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")
local Packages = ReplicatedStorage.Packages
local Data = ReplicatedStorage.Datas
local Net = require(Packages.Net)
local ShopData = require(Data.Shop)
local MoltenSpinWheelData = require(Data.MoltenSpinWheel)
local Synchronizer = require(Packages.Synchronizer)
local ServerLuckSynchronizer = Synchronizer:Get("ServerLuck")
local MoltenSpinHandler = {}
MoltenSpinHandler.__index = MoltenSpinHandler
local notificationCooldown = {}
local NOTIFY_COOLDOWN = 0.5
function MoltenSpinHandler.new(monetizationService)
local self = setmetatable({}, MoltenSpinHandler)
self._monetizationService = monetizationService
self._spinRemote = Net:RemoteEvent("MoltenEventService/Spin")
self._purchaseRemote = Net:RemoteEvent("ShopService/Purchase")
self:_setupRemoteEvents()
return self
end
function MoltenSpinHandler:_setupRemoteEvents()
self._purchaseRemote.OnServerEvent:Connect(function(player, productId)
if self:_isMoltenSpinProduct(productId) then
self:PromptPurchase(player, productId)
end
end)
self._spinRemote.OnServerEvent:Connect(function(player)
pcall(function()
self:ProcessSpin(player)
end)
end)
end
function MoltenSpinHandler:_isMoltenSpinProduct(productId)
local productInfo = ShopData[tonumber(productId)]
return productInfo and productInfo.Type == "MoltenWheelSpin"
end
function MoltenSpinHandler:PromptPurchase(player, productId)
if not self._monetizationService:IsDataReady(player) then return false end
local productInfo = ShopData[tonumber(productId)]
if not productInfo then return false end
local marketplaceInfo = self._monetizationService:GetProductInfo(tonumber(productId))
if not marketplaceInfo then return false end
return self._monetizationService:PromptProductPurchase(player, tonumber(productId))
end
function MoltenSpinHandler:ProcessPurchase(player, productId, receiptInfo)
if not self._monetizationService:IsDataReady(player) then return false end
local playerPlot = self._monetizationService:GetPlayerSynchronizer(player)
if not playerPlot then return false end
local data = self._monetizationService:GetPlayerData(player)
if not data then return false end
local productInfo = ShopData[productId]
if not productInfo or productInfo.Type ~= "MoltenWheelSpin" then return false end
local spinsToAdd = productInfo.Value or 0
local isX3Purchase = productInfo.Identifier == "x3"
local isDiscountPurchase = string.find(productInfo.Display, "DISCOUNT")
data.MoltenSpinWheel = data.MoltenSpinWheel or {}
data.MoltenSpinWheel.Spins = (data.MoltenSpinWheel.Spins or 0) + spinsToAdd
if isX3Purchase then
data.MoltenSpinWheel.PaidSpins = data.MoltenSpinWheel.PaidSpins or {}
data.MoltenSpinWheel.PaidSpins.x3 = (data.MoltenSpinWheel.PaidSpins.x3 or 0) + 1
end
if isDiscountPurchase then
data.MoltenSpinWheel.LastDailyDiscount = os.time()
end
playerPlot:Set("MoltenSpinWheel", data.MoltenSpinWheel)
playerPlot:Set("PaidSpins", data.MoltenSpinWheel.PaidSpins)
if isDiscountPurchase then
playerPlot:Set("LastDailyDiscount", data.MoltenSpinWheel.LastDailyDiscount)
end
self._monetizationService:LogPurchase(player, productId, "MoltenSpin", spinsToAdd .. " spins")
return true
end
function MoltenSpinHandler:ProcessSpin(player)
if not self._monetizationService:IsDataReady(player) then return end
local playerPlot = self._monetizationService:GetPlayerSynchronizer(player)
if not playerPlot then return end
local data = self._monetizationService:GetPlayerData(player)
if not data then return end
data.MoltenSpinWheel = data.MoltenSpinWheel or {}
local isFreeSpin = false
local MoltenEventActive = ReplicatedStorage:GetAttribute("MoltenEvent")
if MoltenEventActive then
local lastFreeClaimed = data.MoltenSpinWheel.LastFreeClaimed or 0
local eventLastTime = ReplicatedStorage:GetAttribute("MoltenEventLastTime")
if lastFreeClaimed ~= eventLastTime then
isFreeSpin = true
end
end
local currentSpins = data.MoltenSpinWheel.Spins or 0
if not isFreeSpin and currentSpins <= 0 then
local now = os.clock()
if not notificationCooldown[player] or now - notificationCooldown[player] >= NOTIFY_COOLDOWN then
notificationCooldown[player] = now
local notificationEvent = Net:RemoteEvent("NotificationService/Notify")
notificationEvent:FireClient(player, "You don't have any spins to spin the wheel!", 5, "Sounds.Sfx.Error")
end
return
end
if isFreeSpin then
data.MoltenSpinWheel.LastFreeClaimed = ReplicatedStorage:GetAttribute("MoltenEventLastTime")
else
data.MoltenSpinWheel.Spins = data.MoltenSpinWheel.Spins - 1
end
local rewardIndex = self:_getRewardIndex()
if not MoltenSpinWheelData.Rewards[rewardIndex] then
rewardIndex = 1
end
local reward = MoltenSpinWheelData.Rewards[rewardIndex]
local isAltReward = false
if reward.Type == "Item" and data.Items and data.Items[reward.Index] then
if MoltenSpinWheelData.AltRewards and MoltenSpinWheelData.AltRewards[rewardIndex] then
reward = MoltenSpinWheelData.AltRewards[rewardIndex]
isAltReward = true
end
end
pcall(function()
self:_grantReward(player, reward, data, playerPlot)
end)
playerPlot:Set("MoltenSpinWheel", data.MoltenSpinWheel)
pcall(function()
self._spinRemote:FireClient(player, rewardIndex, isAltReward)
end)
end
function MoltenSpinHandler:_getRewardIndex()
local totalWeight = 0
for _, reward in ipairs(MoltenSpinWheelData.Rewards) do
totalWeight += reward.Weight
end
local randomWeight = math.random() * totalWeight
local currentWeight = 0
for index, reward in ipairs(MoltenSpinWheelData.Rewards) do
currentWeight += reward.Weight
if randomWeight <= currentWeight then
return index
end
end
return 1
end
function MoltenSpinHandler:_grantReward(player, reward, data, playerPlot)
if reward.Type == "Cash-Pack" then
local cashValue = ShopData[reward.Index] and ShopData[reward.Index].Value or 0
local rebirthLevel = data.Rebirths or 0
if rebirthLevel > 0 then
cashValue = cashValue * (rebirthLevel <= 1 and 1.5 or rebirthLevel)
end
data.Coins = (data.Coins or 0) + cashValue
playerPlot:Set("Coins", data.Coins)
elseif reward.Type == "Item" then
data.Items = data.Items or {}
data.Items[reward.Index] = true
local toolClone = ReplicatedStorage.Items:FindFirstChild(reward.Index)
if toolClone then
toolClone:Clone().Parent = player.Backpack
end
playerPlot:Set("Items", data.Items)
elseif reward.Type == "Animal" then
local success, result = pcall(function()
local DataManagement = require(game:GetService("ServerScriptService").Services.DataManagment)
return DataManagement.addAnimal(player, reward.Index, reward.Mutation)
end)
if success and result then
pcall(function()
local DataManagement = require(game:GetService("ServerScriptService").Services.DataManagment)
DataManagement.addToIndex(player, reward.Index, reward.Mutation)
end)
else
local alternativeCoinValue = 1000
data.Coins = (data.Coins or 0) + alternativeCoinValue
playerPlot:Set("Coins", data.Coins)
end
elseif reward.Type == "Server-Luck" then
local MULTIPLIER = 6
local DURATION = 900
local now = os.time()
local endTime = now + DURATION
if ServerLuckSynchronizer then
ServerLuckSynchronizer:Set("Index", MULTIPLIER)
ServerLuckSynchronizer:Set("EndTime", endTime)
end
ReplicatedStorage:SetAttribute("ServerLuckMultiplier", MULTIPLIER)
ReplicatedStorage:SetAttribute("ServerLuckEndTime", endTime)
end
end
function MoltenSpinHandler:OnPurchaseFinished(player, productId, isPurchased)
end
function MoltenSpinHandler:GetPlayerSpins(player)
local data = self._monetizationService:GetPlayerData(player)
if data and data.MoltenSpinWheel then
return data.MoltenSpinWheel.Spins or 0
end
return 0
end
function MoltenSpinHandler:GetProductInfo(productId)
return ShopData[tonumber(productId)]
end
Players.PlayerRemoving:Connect(function(player)
notificationCooldown[player] = nil
end)
return MoltenSpinHandler - Edit
03:12:20.470
- Edit
03:12:20.470
============================== - Edit
03:12:20.470 📜 ServerScriptService.Services.MonetizationService.GalaxySpinHandler - Edit
03:12:20.470 ==============================
- Edit
03:12:20.470 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")
local Packages = ReplicatedStorage.Packages
local Data = ReplicatedStorage.Datas
local Net = require(Packages.Net)
local ShopData = require(Data.Shop)
local GalaxySpinWheelData = require(Data.GalaxySpinWheel)
local Synchronizer = require(Packages.Synchronizer)
local ServerLuckSynchronizer = Synchronizer:Get("ServerLuck")
local GalaxySpinHandler = {}
GalaxySpinHandler.__index = GalaxySpinHandler
local notificationCooldown = {}
local NOTIFY_COOLDOWN = 0.5
function GalaxySpinHandler.new(monetizationService)
local self = setmetatable({}, GalaxySpinHandler)
self._monetizationService = monetizationService
self._spinRemote = Net:RemoteEvent("GalaxyEventService/Spin")
self._purchaseRemote = Net:RemoteEvent("ShopService/Purchase")
self:_setupRemoteEvents()
return self
end
function GalaxySpinHandler:_setupRemoteEvents()
self._purchaseRemote.OnServerEvent:Connect(function(player, productId)
if self:_isGalaxySpinProduct(productId) then
self:PromptPurchase(player, productId)
end
end)
self._spinRemote.OnServerEvent:Connect(function(player)
pcall(function()
self:ProcessSpin(player)
end)
end)
end
function GalaxySpinHandler:_isGalaxySpinProduct(productId)
local productInfo = ShopData[tonumber(productId)]
return productInfo and productInfo.Type == "GalaxyWheelSpin"
end
function GalaxySpinHandler:PromptPurchase(player, productId)
if not self._monetizationService:IsDataReady(player) then return false end
local productInfo = ShopData[tonumber(productId)]
if not productInfo then return false end
local marketplaceInfo = self._monetizationService:GetProductInfo(tonumber(productId))
if not marketplaceInfo then return false end
return self._monetizationService:PromptProductPurchase(player, tonumber(productId))
end
function GalaxySpinHandler:ProcessPurchase(player, productId, receiptInfo)
if not self._monetizationService:IsDataReady(player) then return false end
local playerPlot = self._monetizationService:GetPlayerSynchronizer(player)
if not playerPlot then return false end
local data = self._monetizationService:GetPlayerData(player)
if not data then return false end
local productInfo = ShopData[productId]
if not productInfo or productInfo.Type ~= "GalaxyWheelSpin" then return false end
local spinsToAdd = productInfo.Value or 0
local isX3Purchase = productInfo.Identifier == "x3"
local isDiscountPurchase = string.find(productInfo.Display, "DISCOUNT")
data.GalaxySpinWheel = data.GalaxySpinWheel or {}
data.GalaxySpinWheel.Spins = (data.GalaxySpinWheel.Spins or 0) + spinsToAdd
if isX3Purchase then
data.GalaxySpinWheel.PaidSpins = data.GalaxySpinWheel.PaidSpins or {}
data.GalaxySpinWheel.PaidSpins.x3 = (data.GalaxySpinWheel.PaidSpins.x3 or 0) + 1
end
if isDiscountPurchase then
data.GalaxySpinWheel.LastDailyDiscount = os.time()
end
playerPlot:Set("GalaxySpinWheel", data.GalaxySpinWheel)
playerPlot:Set("PaidSpins", data.GalaxySpinWheel.PaidSpins)
if isDiscountPurchase then
playerPlot:Set("LastDailyDiscount", data.GalaxySpinWheel.LastDailyDiscount)
end
self._monetizationService:LogPurchase(player, productId, "GalaxySpin", spinsToAdd .. " spins")
return true
end
function GalaxySpinHandler:ProcessSpin(player)
if not self._monetizationService:IsDataReady(player) then return end
local playerPlot = self._monetizationService:GetPlayerSynchronizer(player)
if not playerPlot then return end
local data = self._monetizationService:GetPlayerData(player)
if not data then return end
data.GalaxySpinWheel = data.GalaxySpinWheel or {}
local isFreeSpin = false
local GalaxyEventActive = ReplicatedStorage:GetAttribute("GalaxyEvent")
if GalaxyEventActive then
local lastFreeClaimed = data.GalaxySpinWheel.LastFreeClaimed or 0
local eventLastTime = ReplicatedStorage:GetAttribute("GalaxyEventLastTime")
if lastFreeClaimed ~= eventLastTime then
isFreeSpin = true
end
end
local currentSpins = data.GalaxySpinWheel.Spins or 0
if not isFreeSpin and currentSpins <= 0 then
local now = os.clock()
if not notificationCooldown[player] or now - notificationCooldown[player] >= NOTIFY_COOLDOWN then
notificationCooldown[player] = now
local notificationEvent = Net:RemoteEvent("NotificationService/Notify")
notificationEvent:FireClient(player, "You don't have any spins to spin the wheel!", 5, "Sounds.Sfx.Error")
end
return
end
if isFreeSpin then
data.GalaxySpinWheel.LastFreeClaimed = ReplicatedStorage:GetAttribute("GalaxyEventLastTime")
else
data.GalaxySpinWheel.Spins = data.GalaxySpinWheel.Spins - 1
end
local rewardIndex = self:_getRewardIndex()
if not GalaxySpinWheelData.Rewards[rewardIndex] then
rewardIndex = 1
end
local reward = GalaxySpinWheelData.Rewards[rewardIndex]
local isAltReward = false
if reward.Type == "Item" and data.Items and data.Items[reward.Index] then
if GalaxySpinWheelData.AltRewards and GalaxySpinWheelData.AltRewards[rewardIndex] then
reward = GalaxySpinWheelData.AltRewards[rewardIndex]
isAltReward = true
end
end
pcall(function()
self:_grantReward(player, reward, data, playerPlot)
end)
playerPlot:Set("GalaxySpinWheel", data.GalaxySpinWheel)
pcall(function()
self._spinRemote:FireClient(player, rewardIndex, isAltReward)
end)
end
function GalaxySpinHandler:_getRewardIndex()
local totalWeight = 0
for _, reward in ipairs(GalaxySpinWheelData.Rewards) do
totalWeight += reward.Weight
end
local randomWeight = math.random() * totalWeight
local currentWeight = 0
for index, reward in ipairs(GalaxySpinWheelData.Rewards) do
currentWeight += reward.Weight
if randomWeight <= currentWeight then
return index
end
end
return 1
end
function GalaxySpinHandler:_grantReward(player, reward, data, playerPlot)
if reward.Type == "Cash-Pack" then
local cashValue = ShopData[reward.Index] and ShopData[reward.Index].Value or 0
local rebirthLevel = data.Rebirths or 0
if rebirthLevel > 0 then
cashValue = cashValue * (rebirthLevel <= 1 and 1.5 or rebirthLevel)
end
data.Coins = (data.Coins or 0) + cashValue
playerPlot:Set("Coins", data.Coins)
elseif reward.Type == "Item" then
data.Items = data.Items or {}
data.Items[reward.Index] = true
local toolClone = ReplicatedStorage.Items:FindFirstChild(reward.Index)
if toolClone then
toolClone:Clone().Parent = player.Backpack
end
playerPlot:Set("Items", data.Items)
elseif reward.Type == "Animal" then
local success, result = pcall(function()
local DataManagement = require(game:GetService("ServerScriptService").Services.DataManagment)
return DataManagement.addAnimal(player, reward.Index, reward.Mutation)
end)
if success and result then
pcall(function()
local DataManagement = require(game:GetService("ServerScriptService").Services.DataManagment)
DataManagement.addToIndex(player, reward.Index, reward.Mutation)
end)
else
local alternativeCoinValue = 1000
data.Coins = (data.Coins or 0) + alternativeCoinValue
playerPlot:Set("Coins", data.Coins)
end
elseif reward.Type == "Server-Luck" then
local MULTIPLIER = 8
local DURATION = 900
local now = os.time()
local endTime = now + DURATION
if ServerLuckSynchronizer then
ServerLuckSynchronizer:Set("Index", MULTIPLIER)
ServerLuckSynchronizer:Set("EndTime", endTime)
end
ReplicatedStorage:SetAttribute("ServerLuckMultiplier", MULTIPLIER)
ReplicatedStorage:SetAttribute("ServerLuckEndTime", endTime)
end
end
function GalaxySpinHandler:OnPurchaseFinished(player, productId, isPurchased)
end
function GalaxySpinHandler:GetPlayerSpins(player)
local data = self._monetizationService:GetPlayerData(player)
if data and data.GalaxySpinWheel then
return data.GalaxySpinWheel.Spins or 0
end
return 0
end
function GalaxySpinHandler:GetProductInfo(productId)
return ShopData[tonumber(productId)]
end
Players.PlayerRemoving:Connect(function(player)
notificationCooldown[player] = nil
end)
return GalaxySpinHandler - Edit
03:12:20.470
- Edit
03:12:20.470
============================== - Edit
03:12:20.471 📜 ServerScriptService.Services.MonetizationService.YinYangSpinHandler - Edit
03:12:20.471 ==============================
- Edit
03:12:20.471 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")
local Packages = ReplicatedStorage.Packages
local Data = ReplicatedStorage.Datas
local Net = require(Packages.Net)
local ShopData = require(Data.Shop)
local YinYangSpinWheelData = require(Data.YinYangSpinWheel)
local Synchronizer = require(Packages.Synchronizer)
local ServerLuckSynchronizer = Synchronizer:Get("ServerLuck")
local YinYangSpinHandler = {}
YinYangSpinHandler.__index = YinYangSpinHandler
local notificationCooldown = {}
local NOTIFY_COOLDOWN = 0.5
function YinYangSpinHandler.new(monetizationService)
local self = setmetatable({}, YinYangSpinHandler)
self._monetizationService = monetizationService
self._spinRemote = Net:RemoteEvent("YinYangEventService/Spin")
self._purchaseRemote = Net:RemoteEvent("ShopService/Purchase")
self:_setupRemoteEvents()
return self
end
function YinYangSpinHandler:_setupRemoteEvents()
self._purchaseRemote.OnServerEvent:Connect(function(player, productId)
if self:_isYinYangSpinProduct(productId) then
self:PromptPurchase(player, productId)
end
end)
self._spinRemote.OnServerEvent:Connect(function(player)
pcall(function()
self:ProcessSpin(player)
end)
end)
end
function YinYangSpinHandler:_isYinYangSpinProduct(productId)
local productInfo = ShopData[tonumber(productId)]
return productInfo and productInfo.Type == "YinYangWheelSpin"
end
function YinYangSpinHandler:PromptPurchase(player, productId)
if not self._monetizationService:IsDataReady(player) then return false end
local productInfo = ShopData[tonumber(productId)]
if not productInfo then return false end
local marketplaceInfo = self._monetizationService:GetProductInfo(tonumber(productId))
if not marketplaceInfo then return false end
return self._monetizationService:PromptProductPurchase(player, tonumber(productId))
end
function YinYangSpinHandler:ProcessPurchase(player, productId, receiptInfo)
if not self._monetizationService:IsDataReady(player) then return false end
local playerPlot = self._monetizationService:GetPlayerSynchronizer(player)
if not playerPlot then return false end
local data = self._monetizationService:GetPlayerData(player)
if not data then return false end
local productInfo = ShopData[productId]
if not productInfo or productInfo.Type ~= "YinYangWheelSpin" then return false end
local spinsToAdd = productInfo.Value or 0
local isX3Purchase = productInfo.Identifier == "x3"
local isDiscountPurchase = string.find(productInfo.Display, "DISCOUNT")
data.YinYangSpinWheel = data.YinYangSpinWheel or {}
data.YinYangSpinWheel.Spins = (data.YinYangSpinWheel.Spins or 0) + spinsToAdd
if isX3Purchase then
data.YinYangSpinWheel.PaidSpins = data.YinYangSpinWheel.PaidSpins or {}
data.YinYangSpinWheel.PaidSpins.x3 = (data.YinYangSpinWheel.PaidSpins.x3 or 0) + 1
end
if isDiscountPurchase then
data.YinYangSpinWheel.LastDailyDiscount = os.time()
end
playerPlot:Set("YinYangSpinWheel", data.YinYangSpinWheel)
playerPlot:Set("PaidSpins", data.YinYangSpinWheel.PaidSpins)
if isDiscountPurchase then
playerPlot:Set("LastDailyDiscount", data.YinYangSpinWheel.LastDailyDiscount)
end
self._monetizationService:LogPurchase(player, productId, "YinYangSpin", spinsToAdd .. " spins")
return true
end
function YinYangSpinHandler:ProcessSpin(player)
if not self._monetizationService:IsDataReady(player) then return end
local playerPlot = self._monetizationService:GetPlayerSynchronizer(player)
if not playerPlot then return end
local data = self._monetizationService:GetPlayerData(player)
if not data then return end
data.YinYangSpinWheel = data.YinYangSpinWheel or {}
local isFreeSpin = false
local YinYangEventActive = ReplicatedStorage:GetAttribute("YinYangEvent")
if YinYangEventActive then
local lastFreeClaimed = data.YinYangSpinWheel.LastFreeClaimed or 0
local eventLastTime = ReplicatedStorage:GetAttribute("YinYangEventLastTime")
if lastFreeClaimed ~= eventLastTime then
isFreeSpin = true
end
end
local currentSpins = data.YinYangSpinWheel.Spins or 0
if not isFreeSpin and currentSpins <= 0 then
local now = os.clock()
if not notificationCooldown[player] or now - notificationCooldown[player] >= NOTIFY_COOLDOWN then
notificationCooldown[player] = now
local notificationEvent = Net:RemoteEvent("NotificationService/Notify")
notificationEvent:FireClient(player, "You don't have any spins to spin the wheel!", 5, "Sounds.Sfx.Error")
end
return
end
if isFreeSpin then
data.YinYangSpinWheel.LastFreeClaimed = ReplicatedStorage:GetAttribute("YinYangEventLastTime")
else
data.YinYangSpinWheel.Spins = data.YinYangSpinWheel.Spins - 1
end
local rewardIndex = self:_getRewardIndex()
if not YinYangSpinWheelData.Rewards[rewardIndex] then
rewardIndex = 1
end
local reward = YinYangSpinWheelData.Rewards[rewardIndex]
local isAltReward = false
if reward.Type == "Item" and data.Items and data.Items[reward.Index] then
if YinYangSpinWheelData.AltRewards and YinYangSpinWheelData.AltRewards[rewardIndex] then
reward = YinYangSpinWheelData.AltRewards[rewardIndex]
isAltReward = true
end
end
pcall(function()
self:_grantReward(player, reward, data, playerPlot)
end)
playerPlot:Set("YinYangSpinWheel", data.YinYangSpinWheel)
pcall(function()
self._spinRemote:FireClient(player, rewardIndex, isAltReward)
end)
end
function YinYangSpinHandler:_getRewardIndex()
local totalWeight = 0
for _, reward in ipairs(YinYangSpinWheelData.Rewards) do
totalWeight += reward.Weight
end
local randomWeight = math.random() * totalWeight
local currentWeight = 0
for index, reward in ipairs(YinYangSpinWheelData.Rewards) do
currentWeight += reward.Weight
if randomWeight <= currentWeight then
return index
end
end
return 1
end
function YinYangSpinHandler:_grantReward(player, reward, data, playerPlot)
if reward.Type == "Cash-Pack" then
local cashValue = ShopData[reward.Index] and ShopData[reward.Index].Value or 0
local rebirthLevel = data.Rebirths or 0
if rebirthLevel > 0 then
cashValue = cashValue * (rebirthLevel <= 1 and 1.5 or rebirthLevel)
end
data.Coins = (data.Coins or 0) + cashValue
playerPlot:Set("Coins", data.Coins)
elseif reward.Type == "Item" then
data.Items = data.Items or {}
data.Items[reward.Index] = true
local toolClone = ReplicatedStorage.Items:FindFirstChild(reward.Index)
if toolClone then
toolClone:Clone().Parent = player.Backpack
end
playerPlot:Set("Items", data.Items)
elseif reward.Type == "Animal" then
local success, result = pcall(function()
local DataManagement = require(game:GetService("ServerScriptService").Services.DataManagment)
return DataManagement.addAnimal(player, reward.Index, reward.Mutation)
end)
if success and result then
pcall(function()
local DataManagement = require(game:GetService("ServerScriptService").Services.DataManagment)
DataManagement.addToIndex(player, reward.Index, reward.Mutation)
end)
else
local alternativeCoinValue = 1000
data.Coins = (data.Coins or 0) + alternativeCoinValue
playerPlot:Set("Coins", data.Coins)
end
elseif reward.Type == "Server-Luck" then
local MULTIPLIER = 8
local DURATION = 900
local now = os.time()
local endTime = now + DURATION
if ServerLuckSynchronizer then
ServerLuckSynchronizer:Set("Index", MULTIPLIER)
ServerLuckSynchronizer:Set("EndTime", endTime)
end
ReplicatedStorage:SetAttribute("ServerLuckMultiplier", MULTIPLIER)
ReplicatedStorage:SetAttribute("ServerLuckEndTime", endTime)
end
end
function YinYangSpinHandler:OnPurchaseFinished(player, productId, isPurchased)
end
function YinYangSpinHandler:GetPlayerSpins(player)
local data = self._monetizationService:GetPlayerData(player)
if data and data.YinYangSpinWheel then
return data.YinYangSpinWheel.Spins or 0
end
return 0
end
function YinYangSpinHandler:GetProductInfo(productId)
return ShopData[tonumber(productId)]
end
Players.PlayerRemoving:Connect(function(player)
notificationCooldown[player] = nil
end)
return YinYangSpinHandler
- Edit
03:12:20.471
- Edit
03:12:20.471
============================== - Edit
03:12:20.471 📜 ServerScriptService.Services.CommandsService - Edit
03:12:20.471 ==============================
- Edit
03:12:20.471 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Net = require(ReplicatedStorage.Packages.Net)
local Conch = require(ReplicatedStorage.Packages.Conch)
local Config = require(script.Config)
local Permissions = require(script.Methods.ConsolePermissions)
local Players = game:GetService("Players")
local CommandsService = {}
CommandsService.__index = CommandsService
local DEBUG = false
function CommandsService.new()
local self = setmetatable({}, CommandsService)
self:_setupRemoteFunctions()
task.spawn(function()
local waited = 0
while not (Conch.console and Conch.console.commands and Conch.console.commands["clear"]) and waited < 5 do
task.wait(0.1)
waited += 0.1
end
self:_loadCommandModules()
end)
self:_connectPlayerJoin()
return self
end
function CommandsService:_setupRemoteFunctions()
Net:Handle("CommandsService/ViewCommands", function(player)
local allowed = Permissions.hasPermission(player)
if DEBUG then
print(string.format("[CommandsService] ViewCommands invoked by %s | allowed=%s", player.Name, tostring(allowed)))
end
if allowed then
local user = Conch.get_user(player)
if user then
Conch.give_roles(user, "super-user")
task.delay(0.25, function()
if DEBUG then
print("[CommandsService] Marking user.dirty after ViewCommands (", player.Name, ")")
end
user.dirty = true
end)
end
local snapshot = {}
for name, cmd in pairs(Conch.console.commands) do
if Permissions.hasPermission(player) or Conch._.has_permissions(Conch.get_user(player), unpack(cmd.permissions)) then
table.insert(snapshot, {
name = cmd.name,
description = cmd.description,
permissions = cmd.permissions,
arguments = cmd.arguments,
})
end
end
return snapshot
end
return nil
end)
end
function CommandsService:_connectPlayerJoin()
local function giveRole(player)
task.spawn(function()
while player.Parent and not Permissions.hasPermission(player) do
task.wait(1)
end
if not player.Parent then
return
end
if DEBUG then
print(string.format("[CommandsService] %s authorised", player.Name))
end
local user
while player.Parent do
user = Conch.get_user(player)
if user then break end
task.wait(0.1)
end
if not user then
warn("[CommandsService] Failed to obtain Conch user for", player)
return
end
Conch.give_roles(user, "super-user")
if DEBUG then
print(string.format("[CommandsService] super-user role given to %s", player.Name))
end
task.delay(0.25, function()
if DEBUG then
print(string.format("[CommandsService] Marking user.dirty after role assignment (%s)", player.Name))
end
if user then
user.dirty = true
end
end)
end)
end
for _, plr in ipairs(Players:GetPlayers()) do
giveRole(plr)
end
Players.PlayerAdded:Connect(giveRole)
end
function CommandsService:_loadCommandModules()
local cmdsFolder = script:FindFirstChild("Commands")
if not cmdsFolder then
warn("[CommandsService] No Commands folder found – no commands loaded")
return
end
for _, moduleScript in ipairs(cmdsFolder:GetChildren()) do
if moduleScript:IsA("ModuleScript") then
local ok, handler = pcall(require, moduleScript)
if not ok then
warn("[CommandsService] Failed to require command module", moduleScript:GetFullName(), handler)
elseif type(handler) == "function" then
local success, err = pcall(handler, Conch, Config)
if not success then
warn("[CommandsService] Command module error", moduleScript.Name, err)
end
if DEBUG then
print("[CommandsService] Loaded command module", moduleScript.Name)
for _, p in ipairs(game:GetService("Players"):GetPlayers()) do
local hadBefore = Conch.console and Conch.console.commands and Conch.console.commands[moduleScript.Name] ~= nil
print(string.format(" └ replicate_to_player -> %s (command pre-existed=%s)", p.Name, tostring(hadBefore)))
end
end
end
end
end
for _, player in ipairs(game:GetService("Players"):GetPlayers()) do
local user = Conch.get_user(player)
if user then
user.dirty = true
if DEBUG then
print("[CommandsService] Marking dirty after modules loaded for", player.Name)
end
end
end
end
return CommandsService.new() - Edit
03:12:20.471
- Edit
03:12:20.471
============================== - Edit
03:12:20.471 📜 ServerScriptService.Services.CommandsService.Config - Edit
03:12:20.471 ==============================
- Edit
03:12:20.471 return {
AllowedUserIds = {
2985198364; -- NAME HEREs
},
GroupId = 221627747,
MinGroupRank = 254,
} - Edit
03:12:20.471
- Edit
03:12:20.471
============================== - Edit
03:12:20.471 📜 ServerScriptService.Services.CommandsService.Methods.ConsolePermissions - Edit
03:12:20.471 ==============================
- Edit
03:12:20.471 local Config = require(script.Parent.Parent.Config)
local ConsolePermissions = {}
function ConsolePermissions.hasPermission(player)
if table.find(Config.AllowedUserIds, player.UserId) then
return true
end
if Config.GroupId and Config.MinGroupRank then
local ok, rank = pcall(player.GetRankInGroup, player, Config.GroupId)
if ok and rank >= Config.MinGroupRank then
return true
end
end
return false
end
return ConsolePermissions - Edit
03:12:20.471
- Edit
03:12:20.472
============================== - Edit
03:12:20.472 📜 ServerScriptService.Services.CommandsService.Commands.stopevent - Edit
03:12:20.472 ==============================
- Edit
03:12:20.472 local module = function(Conch, Config)
Conch.register("stopevent", {
permissions = { Config.RequiredRole or "super-user" },
arguments = function()
return {
kind = "argument",
type = "Event",
name = "Event",
}
end,
callback = function(eventName)
local svc = _G and _G.EventService
if not svc then
return false, "EventService not initialised"
end
local ok = svc:StopEvent(eventName)
return "stopped"
end,
})
end
return module - Edit
03:12:20.472
- Edit
03:12:20.472
============================== - Edit
03:12:20.472 📜 ServerScriptService.Services.CommandsService.Commands.executeevent - Edit
03:12:20.472 ==============================
- Edit
03:12:20.472 local module = function(Conch, Config)
Conch.register("executeevent", {
permissions = { Config.RequiredRole or "super-user" },
arguments = function()
return
{
kind = "argument",
type = "Event",
name = "Event",
},
{
kind = "argument",
type = "number",
name = "Duration",
optional = true,
}
end,
callback = function(eventName, duration)
local svc = _G and _G.EventService
if not svc then
return false, "EventService not initialised"
end
local ok = svc:StartEvent(eventName, duration)
return "executed"
end,
})
end
return module - Edit
03:12:20.472
- Edit
03:12:20.472
============================== - Edit
03:12:20.472 📜 ServerScriptService.Services.CommandsService.Commands.spawnbrainrot - Edit
03:12:20.473 ==============================
- Edit
03:12:20.473 local module = function(Conch, Config)
Conch.register("spawnbrainrot", {
permissions = { Config.RequiredRole or "super-user" },
arguments = function()
return
{
kind = "argument",
type = "Brainrot",
name = "Brainrot",
},
{
kind = "argument",
type = "number",
name = "Amount",
optional = true,
},
{
kind = "argument",
type = "Mutation",
name = "Mutation",
optional = true,
}
end,
callback = function(brainrot, amount, mutation)
amount = tonumber(amount) or 1
if amount < 1 then
return false, "buddy."
end
local roadService = _G and _G.RoadAnimalService
local mutParam
if mutation == "Normal" or mutation == "" or mutation == nil then
mutParam = nil
else
mutParam = mutation
end
local successCount = 0
for i = 1, amount do
local ok, res = pcall(function()
return roadService.Spawner:SpawnSpecificAnimal(brainrot, nil, mutParam)
end)
if ok and res then
successCount = successCount + 1
end
end
if successCount == 0 then
return false, string.format("Failed to spawn any %s", brainrot)
end
return "spawned"
end,
})
end
return module - Edit
03:12:20.473
- Edit
03:12:20.473
============================== - Edit
03:12:20.473 📜 ServerScriptService.Services.CommandsService.Commands.announce - Edit
03:12:20.473 ==============================
- Edit
03:12:20.473 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local MessagingService = game:GetService("MessagingService")
local Net = require(ReplicatedStorage.Packages.Net)
local Conch = require(ReplicatedStorage.Packages.Conch)
local NotificationEvent = Net:RemoteEvent("NotificationService/Notify")
local CHANNEL = "b82db150-528f-4042-a0b5-ad6aaf1a5c33"
MessagingService:SubscribeAsync(CHANNEL, function(message)
local data = message.Data
if not data or not data.Text then
return
end
for _, player in ipairs(Players:GetPlayers()) do
NotificationEvent:FireClient(player, data.Text, 5, nil, "Top")
end
end)
local module = function(_, Config)
Conch.register("announce", {
permissions = { Config.RequiredRole or "super-user" },
arguments = function()
return {
kind = "argument",
type = "text",
name = "text",
}
end,
callback = function(...)
-- Capture all arguments
local args = {...}
-- Join them back into one string
local text = table.concat(args, " ")
if not text or text == "" then
return false, "You must provide announcement text"
end
MessagingService:PublishAsync(CHANNEL, { Text = text })
return "announced"
end,
})
end
return module
- Edit
03:12:20.473
- Edit
03:12:20.473
============================== - Edit
03:12:20.473 📜 ServerScriptService.Services.CommandsService.Commands.spawnluckyblock - Edit
03:12:20.473 ==============================
- Edit
03:12:20.473 local module = function(Conch, Config)
Conch.register("spawnluckyblock", {
permissions = { Config.RequiredRole or "super-user" },
arguments = function()
return
{
kind = "argument",
type = "LuckyBlock",
name = "Lucky Block",
},
{
kind = "argument",
type = "number",
name = "Amount",
optional = true,
},
{
kind = "argument",
type = "Mutation",
name = "Mutation",
optional = true,
}
end,
callback = function(brainrot, amount, mutation)
amount = tonumber(amount) or 1
if amount < 1 then
return false, "Amount must be at least 1"
end
local roadService = _G and _G.RoadAnimalService
if not roadService or not roadService.Spawner then
return false, "RoadAnimalService not running"
end
local mutParam
if mutation == "Normal" or mutation == "" or mutation == nil then
mutParam = nil
else
mutParam = mutation
end
local successCount = 0
for i = 1, amount do
roadService.Spawner:SpawnSpecificAnimal(brainrot, nil, mutParam, amount)
end
if successCount == 0 then
return false, string.format("Failed to spawn any %s", brainrot)
end
return "spawned"
end,
})
end
return module - Edit
03:12:20.473
- Edit
03:12:20.474
============================== - Edit
03:12:20.474 📜 ServerScriptService.Services.CommandsService.Commands.executeallevents - Edit
03:12:20.474 ==============================
- Edit
03:12:20.474 local module = function(Conch, Config)
Conch.register("executeallevents", {
permissions = { Config.RequiredRole or "super-user" },
arguments = function()
return {
{
kind = "argument",
type = "number",
name = "Duration",
optional = true,
}
}
end,
callback = function(duration)
local svc = _G and _G.EventService
if not svc then
return false, "EventService not initialised"
end
local events = svc.GetAllEvents and svc:GetAllEvents() or svc.Events
if not events then
return false, "No events available to start"
end
local results = {}
for _, eventName in ipairs(events) do
if not string.find(eventName, "Phase") then
local ok = svc:StartEvent(eventName, duration)
table.insert(results, ok and (eventName .. ": ✅") or (eventName .. ": ❌"))
else
table.insert(results, eventName .. ": ⏭️ (skipped)")
end
end
return "executed"
end,
})
end
return module
- Edit
03:12:20.474
- Edit
03:12:20.474
============================== - Edit
03:12:20.474 📜 ServerScriptService.Services.CommandsService.Commands.settime - Edit
03:12:20.474 ==============================
- Edit
03:12:20.474 local module = function(Conch, Config)
Conch.register("settime", {
permissions = { Config.RequiredRole or "set-time" },
arguments = function()
return {
kind = "argument",
type = "number",
name = "amount",
}
end,
callback = function(amount)
if amount == nil then
return "amount must not be nil!"
end
local Lighting = game:GetService("Lighting")
Lighting.TimeOfDay = amount
return "set"
end,
})
end
return module - Edit
03:12:20.475
- Edit
03:12:20.475
============================== - Edit
03:12:20.475 📜 ServerScriptService.Services.CommandsService.Commands.executeglobalevent - Edit
03:12:20.475 ==============================
- Edit
03:12:20.475 -- // THIS IS UNTESTED MAY NOT WORK
local MessagingService = game:GetService("MessagingService")
local module = function(Conch, Config)
Conch.register("executeglobalevent", {
permissions = { Config.RequiredRole or "super-user" },
arguments = function()
return
{
kind = "argument",
type = "Event",
name = "Event",
},
{
kind = "argument",
type = "number",
name = "Duration",
optional = true,
}
end,
callback = function(eventName, duration)
local success, err = pcall(function()
MessagingService:PublishAsync("4a6b4703-251a-4564-8840-0169367d6827", {
Event = eventName,
Duration = duration,
})
end)
if not success then
return false, "Failed to publish global event: " .. tostring(err)
end
return "executed"
end,
})
MessagingService:SubscribeAsync("4a6b4703-251a-4564-8840-0169367d6827", function(message)
local data = message.Data
if typeof(data) == "table" and data.Event then
local svc = _G and _G.EventService
if svc then
svc:StartEvent(data.Event, data.Duration)
print("[GlobalEvent] Started event:", data.Event, "Duration:", data.Duration)
else
warn("[GlobalEvent] EventService not initialised")
end
end
end)
end
return module
- Edit
03:12:20.475
- Edit
03:12:20.475
============================== - Edit
03:12:20.475 📜 ServerScriptService.Services.CommandsService.Commands.spawnglobalbrainrot - Edit
03:12:20.475 ==============================
- Edit
03:12:20.475 -- // Global Brainrot Spawner
-- // Broadcasts spawn command across ALL servers
local MessagingService = game:GetService("MessagingService")
local TOPIC = "global-brainrot-spawn"
local module = function(Conch, Config)
Conch.register("spawnglobalbrainrot", {
permissions = { Config.RequiredRole or "super-user" },
arguments = function()
return
{
kind = "argument",
type = "Brainrot",
name = "Brainrot",
},
{
kind = "argument",
type = "number",
name = "Amount",
optional = true,
},
{
kind = "argument",
type = "Mutation",
name = "Mutation",
optional = true,
}
end,
callback = function(brainrot, amount, mutation)
amount = tonumber(amount) or 1
if amount < 1 then
return false, "buddy."
end
local success, err = pcall(function()
MessagingService:PublishAsync(TOPIC, {
Brainrot = brainrot,
Amount = amount,
Mutation = mutation,
})
end)
if not success then
return false, "Failed to publish global spawn: " .. tostring(err)
end
return "Global spawn request sent."
end,
})
-- Subscribe for global spawns (runs once per server)
local ok, err = pcall(function()
MessagingService:SubscribeAsync(TOPIC, function(message)
local data = message.Data
if typeof(data) ~= "table" then return end
if not data.Brainrot then return end
local roadService = _G and _G.RoadAnimalService
if not roadService then
warn("[GlobalBrainrot] RoadAnimalService not initialised")
return
end
local mutParam
if data.Mutation == "Normal" or data.Mutation == "" or data.Mutation == nil then
mutParam = nil
else
mutParam = data.Mutation
end
for i = 1, (tonumber(data.Amount) or 1) do
pcall(function()
roadService.Spawner:SpawnSpecificAnimal(data.Brainrot, nil, mutParam)
end)
end
print(string.format("[GlobalBrainrot] Spawned %dx %s (mutation=%s)", data.Amount, data.Brainrot, tostring(mutParam)))
end)
end)
if not ok then
warn("[GlobalBrainrot] Failed to subscribe:", err)
end
end
return module
- Edit
03:12:20.475
- Edit
03:12:20.476
============================== - Edit
03:12:20.476 📜 ServerScriptService.Controllers.ProfileStore - Edit
03:12:20.476 ==============================
- Edit
03:12:20.476 --[[
MAD STUDIO (by loleris)
-[ProfileStore]---------------------------------------
Periodic DataStore saving solution with session locking
WARNINGS FOR "Profile.Data" VALUES:
! Do not create numeric tables with gaps - attempting to store such tables will result in an error.
! Do not create mixed tables (some values indexed by number and others by a string key)
- only numerically indexed data will be stored.
! Do not index tables by anything other than numbers and strings.
! Do not reference Roblox Instances
! Do not reference userdata (Vector3, Color3, CFrame...) - Serialize userdata before referencing
! Do not reference functions
Members:
ProfileStore.IsClosing [bool]
-- Set to true after a game:BindToClose() trigger
ProfileStore.IsCriticalState [bool]
-- Set to true when ProfileStore experiences too many consecutive errors
ProfileStore.OnError [Signal] (message, store_name, profile_key)
-- Most ProfileStore errors will be caught and passed to this signal
ProfileStore.OnOverwrite [Signal] (store_name, profile_key)
-- Triggered when a DataStore key was likely used to store data that wasn't
a ProfileStore profile or the ProfileStore structure was invalidly manually
altered for that DataStore key
ProfileStore.OnCriticalToggle [Signal] (is_critical)
-- Triggered when ProfileStore experiences too many consecutive errors
ProfileStore.DataStoreState [string] ("NotReady", "NoInternet", "NoAccess", "Access")
-- This value resembles ProfileStore's access to the DataStore; The value starts
as "NotReady" and will eventually change to one of the other 3 possible values.
Functions:
ProfileStore.New(store_name, template?) --> [ProfileStore]
store_name [string] -- DataStore name
template [table] or nil -- Profiles will default to given table (hard-copy) when no data was saved previously
ProfileStore.SetConstant(name, value)
name [string]
value [number]
Members [ProfileStore]:
ProfileStore.Mock [ProfileStore]
-- Reflection of ProfileStore methods, but the methods will now query a mock
DataStore with no relation to the real DataStore
ProfileStore.Name [string]
Methods [ProfileStore]:
ProfileStore:StartSessionAsync(profile_key, params?) --> [Profile] or nil
profile_key [string] -- DataStore key
params nil or [table]: -- Custom params; E.g. {Steal = true}
{
Steal = true, -- Pass this to disregard an existing session lock
Cancel = fn() -> (boolean), -- Pass this to create a request cancel condition.
-- If the cancel function returns true, ProfileStore will stop trying to
-- start the session and return nil
}
ProfileStore:MessageAsync(profile_key, message) --> is_success [bool]
profile_key [string] -- DataStore key
message [table] -- Data to be messaged to the profile
ProfileStore:GetAsync(profile_key, version?) --> [Profile] or nil
-- Reads a profile without starting a session - will not autosave
profile_key [string] -- DataStore key
version nil or [string] -- DataStore key version
ProfileStore:VersionQuery(profile_key, sort_direction?, min_date?, max_date?) --> [VersionQuery]
profile_key [string]
sort_direction nil or [Enum.SortDirection]
min_date nil or [DateTime]
max_date nil or [DateTime]
ProfileStore:RemoveAsync(profile_key) --> is_success [bool]
-- Completely removes profile data from the DataStore / mock DataStore with no way to recover it.
Methods [VersionQuery]:
VersionQuery:NextAsync() --> [Profile] or nil -- (Yields)
-- Returned profile is similar to profiles returned by ProfileStore:GetAsync()
Members [Profile]:
Profile.Data [table]
-- When the profile is active changes to this table are guaranteed to be saved
Profile.LastSavedData [table] (Read-only)
-- Last snapshot of "Profile.Data" that has been successfully saved to the DataStore;
Useful for proper developer product purchase receipt handling
Profile.FirstSessionTime [number] (Read-only)
-- os.time() timestamp of the first profile session
Profile.SessionLoadCount [number] (Read-only) -- Amount of times a session was started for this profile
Profile.Session [table] (Read-only) {PlaceId = number, JobId = string} / nil
-- Set to a table if this profile is in use by a server; nil if released
Profile.RobloxMetaData [table] -- Writable table that gets saved automatically and once the profile is released
Profile.UserIds [table] -- (Read-only) -- {user_id [number], ...} -- User ids associated with this profile
Profile.KeyInfo [DataStoreKeyInfo] -- Changes before OnAfterSave signal
Profile.OnSave [Signal] ()
-- Triggered right before changes to Profile.Data are saved to the DataStore
Profile.OnLastSave [Signal] (reason [string]: "Manual", "External", "Shutdown")
-- Triggered right before changes to Profile.Data are saved to the DataStore
for the last time; A reason is provided for the last save:
- "Manual" - Profile:EndSession() was called
- "Shutdown" - The server that has ownership of this profile is shutting down
- "External" - Another server has started a session for this profile
Note that this event will not trigger for when a profile session is ended by
another server trying to take ownership of the session - this is impossible to
do without compromising on ProfileStore's speed.
Profile.OnSessionEnd [Signal] ()
-- Triggered when the profile session is terminated on this server
Profile.OnAfterSave [Signal] (last_saved_data)
-- Triggered after a successful save
last_saved_data [table] -- Profile.LastSavedData
Profile.ProfileStore [ProfileStore] -- ProfileStore object this profile belongs to
Profile.Key [string] -- DataStore key
Methods [Profile]:
Profile:IsActive() --> [bool] -- If "true" is returned, changes to Profile.Data are guaranteed to save;
This guarantee is only valid until code yields (e.g. task.wait() is used).
Profile:Reconcile() -- Fills in missing (nil) [string_key] = [value] pairs to the Profile.Data structure
from the "template" argument that was passed to "ProfileStore.New()"
Profile:EndSession() -- Call after the server has finished working with this profile
e.g., after the player leaves (Profile object will become inactive)
Profile:AddUserId(user_id) -- Associates user_id with profile (GDPR compliance)
user_id [number]
Profile:RemoveUserId(user_id) -- Removes user_id association with profile (safe function)
user_id [number]
Profile:MessageHandler(fn) -- Sets a message handler for this profile
fn [function] (message [table], processed [function]())
-- The handler function receives a message table and a callback function;
The callback function is to be called when a message has been processed
- this will discard the message from the profile message cache; If the
callback function is not called, other message handlers will also be triggered
with unprocessed message data.
Profile:Save() -- If the profile session is still active makes an UpdateAsync call
to the DataStore to immediately save profile data
Profile:SetAsync() -- Forcefully saves changes to the profile; Only for profiles
loaded with ProfileStore:GetAsync() or ProfileStore:VersionQuery()
--]]
local AUTO_SAVE_PERIOD = 300 -- (Seconds) Time between when changes to a profile are saved to the DataStore
local LOAD_REPEAT_PERIOD = 10 -- (Seconds) Time between successive profile reads when handling a session conflict
local FIRST_LOAD_REPEAT = 5 -- (Seconds) Time between first and second profile read when handling a session conflict
local SESSION_STEAL = 40 -- (Seconds) Time until a session conflict is resolved with the waiting server stealing the session
local ASSUME_DEAD = 630 -- (Seconds) If a profile hasn't had updates for this long, quickly assume an active session belongs to a crashed server
local START_SESSION_TIMEOUT = 120 -- (Seconds) If a session can't be started for a profile for this long, stop repeating calls to the DataStore
local CRITICAL_STATE_ERROR_COUNT = 5 -- Assume critical state if this many issues happen in a short amount of time
local CRITICAL_STATE_ERROR_EXPIRE = 120 -- (Seconds) Individual issue expiration
local CRITICAL_STATE_EXPIRE = 120 -- (Seconds) Critical state expiration
local MAX_MESSAGE_QUEUE = 1000 -- Max messages saved in a profile that were sent using "ProfileStore:MessageAsync()"
----- Dependencies -----
-- local Util = require(game.ReplicatedStorage.Shared.Util)
-- local Signal = Util.Signal
local Signal do
local FreeRunnerThread
--[[
Yield-safe coroutine reusing by stravant;
Sources:
https://devforum.roblox.com/t/lua-signal-class-comparison-optimal-goodsignal-class/1387063
https://gist.github.com/stravant/b75a322e0919d60dde8a0316d1f09d2f
--]]
local function AcquireRunnerThreadAndCallEventHandler(fn, ...)
local acquired_runner_thread = FreeRunnerThread
FreeRunnerThread = nil
fn(...)
-- The handler finished running, this runner thread is free again.
FreeRunnerThread = acquired_runner_thread
end
local function RunEventHandlerInFreeThread(...)
AcquireRunnerThreadAndCallEventHandler(...)
while true do
AcquireRunnerThreadAndCallEventHandler(coroutine.yield())
end
end
local Connection = {}
Connection.__index = Connection
local SignalClass = {}
SignalClass.__index = SignalClass
function Connection:Disconnect()
if self.is_connected == false then
return
end
local signal = self.signal
self.is_connected = false
signal.listener_count -= 1
if signal.head == self then
signal.head = self.next
else
local prev = signal.head
while prev ~= nil and prev.next ~= self do
prev = prev.next
end
if prev ~= nil then
prev.next = self.next
end
end
end
function SignalClass.New()
local self = {
head = nil,
listener_count = 0,
}
setmetatable(self, SignalClass)
return self
end
function SignalClass:Connect(listener: (...any) -> ())
if type(listener) ~= "function" then
error(`[{script.Name}]: \"listener\" must be a function; Received {typeof(listener)}`)
end
local connection = {
listener = listener,
signal = self,
next = self.head,
is_connected = true,
}
setmetatable(connection, Connection)
self.head = connection
self.listener_count += 1
return connection
end
function SignalClass:GetListenerCount(): number
return self.listener_count
end
function SignalClass:Fire(...)
local item = self.head
while item ~= nil do
if item.is_connected == true then
if not FreeRunnerThread then
FreeRunnerThread = coroutine.create(RunEventHandlerInFreeThread)
end
task.spawn(FreeRunnerThread, item.listener, ...)
end
item = item.next
end
end
function SignalClass:Wait()
local co = coroutine.running()
local connection
connection = self:Connect(function(...)
connection:Disconnect()
task.spawn(co, ...)
end)
return coroutine.yield()
end
Signal = table.freeze({
New = SignalClass.New,
})
end
----- Private -----
local ActiveSessionCheck = {} -- {[session_token] = profile, ...}
local AutoSaveList = {} -- {profile, ...} -- Loaded profile table which will be circularly auto-saved
local IssueQueue = {} -- {issue_time, ...}
local DataStoreService = game:GetService("DataStoreService")
local MessagingService = game:GetService("MessagingService")
local HttpService = game:GetService("HttpService")
local RunService = game:GetService("RunService")
local PlaceId = game.PlaceId
local JobId = game.JobId
local AutoSaveIndex = 1 -- Next profile to auto save
local LastAutoSave = os.clock()
local LoadIndex = 0
local ActiveProfileLoadJobs = 0 -- Number of active threads that are loading in profiles
local ActiveProfileSaveJobs = 0 -- Number of active threads that are saving profiles
local CriticalStateStart = 0 -- os.clock()
local IsStudio = RunService:IsStudio()
local DataStoreState: "NotReady" | "NoInternet" | "NoAccess" | "Access" = "NotReady"
local MockStore = {}
local UserMockStore = {}
local MockFlag = false
local OnError = Signal.New() -- (message, store_name, profile_key)
local OnOverwrite = Signal.New() -- (store_name, profile_key)
local UpdateQueue = { -- For stability sake, we won't do UpdateAsync calls for the same key until all previous calls finish
--[[
[session_token] = {
coroutine, ...
},
...
--]]
}
local function WaitInUpdateQueue(session_token) --> next_in_queue()
local is_first = false
if UpdateQueue[session_token] == nil then
is_first = true
UpdateQueue[session_token] = {}
end
local queue = UpdateQueue[session_token]
if is_first == false then
table.insert(queue, coroutine.running())
coroutine.yield()
end
return function()
local next_co = table.remove(queue, 1)
if next_co ~= nil then
coroutine.resume(next_co)
else
UpdateQueue[session_token] = nil
end
end
end
local function SessionToken(store_name, profile_key, is_mock)
local session_token = "L_" -- Live
if is_mock == true then
session_token = "U_" -- User mock
elseif DataStoreState ~= "Access" then
session_token = "M_" -- Mock, cause no DataStore access
end
session_token ..= store_name .. "\0" .. profile_key
return session_token
end
local function DeepCopyTable(t)
local copy = {}
for key, value in pairs(t) do
if type(value) == "table" then
copy[key] = DeepCopyTable(value)
else
copy[key] = value
end
end
return copy
end
local function ReconcileTable(target, template)
for k, v in pairs(template) do
if type(k) == "string" then -- Only string keys will be reconciled
if target[k] == nil then
if type(v) == "table" then
target[k] = DeepCopyTable(v)
else
target[k] = v
end
elseif type(target[k]) == "table" and type(v) == "table" then
ReconcileTable(target[k], v)
end
end
end
end
local function RegisterError(error_message, store_name, profile_key) -- Called when a DataStore API call errors
warn(`[{script.Name}]: DataStore API error (STORE:{store_name}; KEY:{profile_key}) - {tostring(error_message)}`)
table.insert(IssueQueue, os.clock()) -- Adding issue time to queue
OnError:Fire(tostring(error_message), store_name, profile_key)
end
local function RegisterOverwrite(store_name, profile_key) -- Called when a corrupted profile is loaded
warn(`[{script.Name}]: Invalid profile was overwritten (STORE:{store_name}; KEY:{profile_key})`)
OnOverwrite:Fire(store_name, profile_key)
end
local function NewMockDataStoreKeyInfo(params)
local version_id_string = tostring(params.VersionId or 0)
local meta_data = params.MetaData or {}
local user_ids = params.UserIds or {}
return {
CreatedTime = params.CreatedTime,
UpdatedTime = params.UpdatedTime,
Version = string.rep("0", 16) .. "."
.. string.rep("0", 10 - string.len(version_id_string)) .. version_id_string
.. "." .. string.rep("0", 16) .. "." .. "01",
GetMetadata = function()
return DeepCopyTable(meta_data)
end,
GetUserIds = function()
return DeepCopyTable(user_ids)
end,
}
end
local function MockUpdateAsync(mock_data_store, profile_store_name, key, transform_function, is_get_call) --> loaded_data, key_info
local profile_store = mock_data_store[profile_store_name]
if profile_store == nil then
profile_store = {}
mock_data_store[profile_store_name] = profile_store
end
local epoch_time = math.floor(os.time() * 1000)
local mock_entry = profile_store[key]
local mock_entry_was_nil = false
if mock_entry == nil then
mock_entry_was_nil = true
if is_get_call ~= true then
mock_entry = {
Data = nil,
CreatedTime = epoch_time,
UpdatedTime = epoch_time,
VersionId = 0,
UserIds = {},
MetaData = {},
}
profile_store[key] = mock_entry
end
end
local mock_key_info = mock_entry_was_nil == false and NewMockDataStoreKeyInfo(mock_entry) or nil
local transform, user_ids, roblox_meta_data = transform_function(mock_entry and mock_entry.Data, mock_key_info)
if transform == nil then
return nil
else
if mock_entry ~= nil and is_get_call ~= true then
mock_entry.Data = DeepCopyTable(transform)
mock_entry.UserIds = DeepCopyTable(user_ids or {})
mock_entry.MetaData = DeepCopyTable(roblox_meta_data or {})
mock_entry.VersionId += 1
mock_entry.UpdatedTime = epoch_time
end
return DeepCopyTable(transform), mock_entry ~= nil and NewMockDataStoreKeyInfo(mock_entry) or nil
end
end
local function UpdateAsync(profile_store, profile_key, transform_params, is_user_mock, is_get_call, version) --> loaded_data, key_info
--transform_params = {
-- ExistingProfileHandle = function(latest_data),
-- MissingProfileHandle = function(latest_data),
-- EditProfile = function(latest_data),
--}
local loaded_data, key_info
local next_in_queue = WaitInUpdateQueue(SessionToken(profile_store.Name, profile_key, is_user_mock))
local success = true
local success, error_message = pcall(function()
local transform_function = function(latest_data)
local missing_profile = false
local overwritten = false
local global_updates = {0, {}}
if latest_data == nil then
missing_profile = true
elseif type(latest_data) ~= "table" then
missing_profile = true
overwritten = true
else
if type(latest_data.Data) == "table" and type(latest_data.MetaData) == "table" and type(latest_data.GlobalUpdates) == "table" then
-- Regular profile structure detected:
latest_data.WasOverwritten = false -- Must be set to false if set previously
global_updates = latest_data.GlobalUpdates
if transform_params.ExistingProfileHandle ~= nil then
transform_params.ExistingProfileHandle(latest_data)
end
elseif latest_data.Data == nil and latest_data.MetaData == nil and type(latest_data.GlobalUpdates) == "table" then
-- Regular structure not detected, but GlobalUpdate data exists:
latest_data.WasOverwritten = false -- Must be set to false if set previously
global_updates = latest_data.GlobalUpdates or global_updates
missing_profile = true
else
missing_profile = true
overwritten = true
end
end
-- Profile was not created or corrupted and no GlobalUpdate data exists:
if missing_profile == true then
latest_data = {
-- Data = nil,
-- MetaData = nil,
GlobalUpdates = global_updates,
}
if transform_params.MissingProfileHandle ~= nil then
transform_params.MissingProfileHandle(latest_data)
end
end
-- Editing profile:
if transform_params.EditProfile ~= nil then
transform_params.EditProfile(latest_data)
end
-- Invalid data handling (Silently override with empty profile)
if overwritten == true then
latest_data.WasOverwritten = true -- Temporary tag that will be removed on first save
end
return latest_data, latest_data.UserIds, latest_data.RobloxMetaData
end
if is_user_mock == true then -- Used when the profile is accessed through ProfileStore.Mock
loaded_data, key_info = MockUpdateAsync(UserMockStore, profile_store.Name, profile_key, transform_function, is_get_call)
task.wait() -- Simulate API call yield
elseif DataStoreState ~= "Access" then -- Used when API access is disabled
loaded_data, key_info = MockUpdateAsync(MockStore, profile_store.Name, profile_key, transform_function, is_get_call)
task.wait() -- Simulate API call yield
else
if is_get_call == true then
if version ~= nil then
local success, error_message = pcall(function()
loaded_data, key_info = profile_store.data_store:GetVersionAsync(profile_key, version)
end)
if success == false and type(error_message) == "string" and string.find(error_message, "not valid") ~= nil then
warn(`[{script.Name}]: Passed version argument is not valid; Traceback:\n` .. debug.traceback())
end
else
loaded_data, key_info = profile_store.data_store:GetAsync(profile_key)
end
loaded_data = transform_function(loaded_data)
else
loaded_data, key_info = profile_store.data_store:UpdateAsync(profile_key, transform_function)
end
end
end)
next_in_queue()
if success == true and type(loaded_data) == "table" then
-- Invalid data handling:
if loaded_data.WasOverwritten == true and is_get_call ~= true then
RegisterOverwrite(
profile_store.Name,
profile_key
)
end
-- Return loaded_data:
return loaded_data, key_info
else
-- Error handling:
RegisterError(
error_message or "Undefined error",
profile_store.Name,
profile_key
)
-- Return nothing:
return nil
end
end
local function IsThisSession(session_tag)
return session_tag[1] == PlaceId and session_tag[2] == JobId
end
local function ReadMockFlag(): boolean
local is_mock = MockFlag
MockFlag = false
return is_mock
end
local function WaitForStoreReady(profile_store)
while profile_store.is_ready == false do
task.wait()
end
end
local function AddProfileToAutoSave(profile)
ActiveSessionCheck[profile.session_token] = profile
-- Add at AutoSaveIndex and move AutoSaveIndex right:
table.insert(AutoSaveList, AutoSaveIndex, profile)
if #AutoSaveList > 1 then
AutoSaveIndex = AutoSaveIndex + 1
elseif #AutoSaveList == 1 then
-- First profile created - make sure it doesn't get immediately auto saved:
LastAutoSave = os.clock()
end
end
local function RemoveProfileFromAutoSave(profile)
ActiveSessionCheck[profile.session_token] = nil
local auto_save_index = table.find(AutoSaveList, profile)
if auto_save_index ~= nil then
table.remove(AutoSaveList, auto_save_index)
if auto_save_index < AutoSaveIndex then
AutoSaveIndex = AutoSaveIndex - 1 -- Table contents were moved left before AutoSaveIndex so move AutoSaveIndex left as well
end
if AutoSaveList[AutoSaveIndex] == nil then -- AutoSaveIndex was at the end of the AutoSaveList - reset to 1
AutoSaveIndex = 1
end
end
end
local function SaveProfileAsync(profile, is_ending_session, is_overwriting, last_save_reason)
if type(profile.Data) ~= "table" then
error(`[{script.Name}]: Developer code likely set "Profile.Data" to a non-table value! (STORE:{profile.ProfileStore.Name}; KEY:{profile.Key})`)
end
profile.OnSave:Fire()
if is_ending_session == true then
profile.OnLastSave:Fire(last_save_reason or "Manual")
end
if is_ending_session == true and is_overwriting ~= true then
if profile.roblox_message_subscription ~= nil then
profile.roblox_message_subscription:Disconnect()
end
RemoveProfileFromAutoSave(profile)
profile.OnSessionEnd:Fire()
end
ActiveProfileSaveJobs = ActiveProfileSaveJobs + 1
-- Compare "SessionLoadCount" when writing to profile to prevent a rare case of repeat last save when the profile is loaded on the same server again
local repeat_save_flag = true -- Released Profile save calls have to repeat until they succeed
local exp_backoff = 1
while repeat_save_flag == true do
if is_ending_session ~= true then
repeat_save_flag = false
end
local loaded_data, key_info = UpdateAsync(
profile.ProfileStore,
profile.Key,
{
ExistingProfileHandle = nil,
MissingProfileHandle = nil,
EditProfile = function(latest_data)
-- Check if this session still owns the profile:
local session_owns_profile = false
if is_overwriting ~= true then
local active_session = latest_data.MetaData.ActiveSession
local session_load_count = latest_data.MetaData.SessionLoadCount
if type(active_session) == "table" then
session_owns_profile = IsThisSession(active_session) and session_load_count == profile.load_index
end
else
session_owns_profile = true
end
-- We may only edit the profile if this server has ownership of the profile:
if session_owns_profile == true then
-- Clear processed updates (messages):
local locked_updates = profile.locked_global_updates -- [index] = true, ...
local active_updates = latest_data.GlobalUpdates[2]
-- ProfileService module format: {{update_id, version_id, update_locked, update_data}, ...}
-- ProfileStore module format: {{update_id, update_data}, ...}
if next(locked_updates) ~= nil then
local i = 1
while i <= #active_updates do
local update = active_updates[i]
if locked_updates[update[1]] == true then
table.remove(active_updates, i)
else
i += 1
end
end
end
-- Save profile data:
latest_data.Data = profile.Data
latest_data.RobloxMetaData = profile.RobloxMetaData
latest_data.UserIds = profile.UserIds
if is_overwriting ~= true then
latest_data.MetaData.LastUpdate = os.time()
if is_ending_session == true then
latest_data.MetaData.ActiveSession = nil
end
else
latest_data.MetaData.ActiveSession = nil
latest_data.MetaData.ForceLoadSession = nil
end
end
end,
},
profile.is_mock
)
if loaded_data ~= nil and key_info ~= nil then
if is_overwriting == true then
break
end
repeat_save_flag = false
local active_session = loaded_data.MetaData.ActiveSession
local session_load_count = loaded_data.MetaData.SessionLoadCount
local session_owns_profile = false
if type(active_session) == "table" then
session_owns_profile = IsThisSession(active_session) and session_load_count == profile.load_index
end
local force_load_session = loaded_data.MetaData.ForceLoadSession
local force_load_pending = false
if type(force_load_session) == "table" then
force_load_pending = not IsThisSession(force_load_session)
end
local is_active = profile:IsActive()
-- If another server is trying to start a session for this profile - end the session:
if force_load_pending == true and session_owns_profile == true then
if is_active == true then
SaveProfileAsync(profile, true, false, "External")
end
break
end
-- Clearing processed update list / Detecting new updates:
local locked_updates = profile.locked_global_updates -- [index] = true, ...
local received_updates = profile.received_global_updates -- [index] = true, ...
local active_updates = loaded_data.GlobalUpdates[2]
local new_updates = {} -- {}, ...
local still_pending = {} -- [index] = true, ...
for _, update in ipairs(active_updates) do
if locked_updates[update[1]] == true then
still_pending[update[1]] = true
elseif received_updates[update[1]] ~= true then
received_updates[update[1]] = true
table.insert(new_updates, update)
end
end
for index in pairs(locked_updates) do
if still_pending[index] ~= true then
locked_updates[index] = nil
end
end
-- Updating profile values:
profile.KeyInfo = key_info
profile.LastSavedData = loaded_data.Data
profile.global_updates = loaded_data.GlobalUpdates and loaded_data.GlobalUpdates[2] or {}
if session_owns_profile == true then
if is_active == true and is_ending_session ~= true then
-- Processing new global updates (messages):
for _, update in ipairs(new_updates) do
local index = update[1]
local update_data = update[#update] -- Backwards compatibility with ProfileService
for _, handler in ipairs(profile.message_handlers) do
local is_processed = false
local processed_callback = function()
is_processed = true
locked_updates[index] = true
end
local send_update_data = DeepCopyTable(update_data)
task.spawn(handler, send_update_data, processed_callback)
if is_processed == true then
break
end
end
end
end
else
if profile.roblox_message_subscription ~= nil then
profile.roblox_message_subscription:Disconnect()
end
if is_active == true then
RemoveProfileFromAutoSave(profile)
profile.OnSessionEnd:Fire()
end
end
profile.OnAfterSave:Fire(profile.LastSavedData)
elseif repeat_save_flag == true then
-- DataStore call likely resulted in an error; Repeat the DataStore call shortly
task.wait(exp_backoff)
exp_backoff = math.min(if last_save_reason == "Shutdown" then 8 else 20, exp_backoff * 2)
end
end
ActiveProfileSaveJobs = ActiveProfileSaveJobs - 1
end
----- Public -----
--[[
Saved profile structure:
{
Data = {},
MetaData = {
ProfileCreateTime = 0,
SessionLoadCount = 0,
ActiveSession = {place_id, game_job_id, unique_session_id} / nil,
ForceLoadSession = {place_id, game_job_id} / nil,
LastUpdate = 0, -- os.time()
MetaTags = {}, -- Backwards compatibility with ProfileService
},
RobloxMetaData = {},
UserIds = {},
GlobalUpdates = {
update_index,
{
{update_index, data}, ...
},
},
}
--]]
export type JSONAcceptable = { JSONAcceptable } | { [string]: JSONAcceptable } | number | string | boolean | buffer
export type Profile = {
Data: T & JSONAcceptable,
LastSavedData: T & JSONAcceptable,
FirstSessionTime: number,
SessionLoadCount: number,
Session: {PlaceId: number, JobId: string}?,
RobloxMetaData: JSONAcceptable,
UserIds: {number},
KeyInfo: DataStoreKeyInfo,
OnSave: {Connect: (self: any, listener: () -> ()) -> ({Disconnect: (self: any) -> ()})},
OnLastSave: {Connect: (self: any, listener: (reason: "Manual" | "External" | "Shutdown") -> ()) -> ({Disconnect: (self: any) -> ()})},
OnSessionEnd: {Connect: (self: any, listener: () -> ()) -> ({Disconnect: (self: any) -> ()})},
OnAfterSave: {Connect: (self: any, listener: (last_saved_data: T & JSONAcceptable) -> ()) -> ({Disconnect: (self: any) -> ()})},
ProfileStore: JSONAcceptable,
Key: string,
IsActive: (self: any) -> (boolean),
Reconcile: (self: any) -> (),
EndSession: (self: any) -> (),
AddUserId: (self: any, user_id: number) -> (),
RemoveUserId: (self: any, user_id: number) -> (),
MessageHandler: (self: any, fn: (message: JSONAcceptable, processed: () -> ()) -> ()) -> (),
Save: (self: any) -> (),
SetAsync: (self: any) -> (),
}
export type VersionQuery = {
NextAsync: (self: any) -> (Profile?),
}
type ProfileStoreStandard = {
Name: string,
StartSessionAsync: (self: any, profile_key: string, params: {Steal: boolean?}) -> (Profile?),
MessageAsync: (self: any, profile_key: string, message: JSONAcceptable) -> (boolean),
GetAsync: (self: any, profile_key: string, version: string?) -> (Profile?),
VersionQuery: (self: any, profile_key: string, sort_direction: Enum.SortDirection?, min_date: DateTime | number | nil, max_date: DateTime | number | nil) -> (VersionQuery),
RemoveAsync: (self: any, profile_key: string) -> (boolean),
}
export type ProfileStore = {
Mock: ProfileStoreStandard,
} & ProfileStoreStandard
type ConstantName = "AUTO_SAVE_PERIOD" | "LOAD_REPEAT_PERIOD" | "FIRST_LOAD_REPEAT" | "SESSION_STEAL"
| "ASSUME_DEAD" | "START_SESSION_TIMEOUT" | "CRITICAL_STATE_ERROR_COUNT" | "CRITICAL_STATE_ERROR_EXPIRE"
| "CRITICAL_STATE_EXPIRE" | "MAX_MESSAGE_QUEUE"
export type ProfileStoreModule = {
IsClosing: boolean,
IsCriticalState: boolean,
OnError: {Connect: (self: any, listener: (message: string, store_name: string, profile_key: string) -> ()) -> ({Disconnect: (self: any) -> ()})},
OnOverwrite: {Connect: (self: any, listener: (store_name: string, profile_key: string) -> ()) -> ({Disconnect: (self: any) -> ()})},
OnCriticalToggle: {Connect: (self: any, listener: (is_critical: boolean) -> ()) -> ({Disconnect: (self: any) -> ()})},
DataStoreState: "NotReady" | "NoInternet" | "NoAccess" | "Access",
New: (store_name: string, template: (T & JSONAcceptable)?) -> (ProfileStore),
SetConstant: (name: ConstantName, value: number) -> ()
}
local Profile = {}
Profile.__index = Profile
function Profile.New(raw_data, key_info, profile_store, key, is_mock, session_token)
local data = raw_data.Data or {}
local session = raw_data.MetaData and raw_data.MetaData.ActiveSession or nil
local global_updates = raw_data.GlobalUpdates and raw_data.GlobalUpdates[2] or {}
local received_global_updates = {}
for _, update in ipairs(global_updates) do
received_global_updates[update[1]] = true
end
local self = {
Data = data,
LastSavedData = DeepCopyTable(data),
FirstSessionTime = raw_data.MetaData and raw_data.MetaData.ProfileCreateTime or 0,
SessionLoadCount = raw_data.MetaData and raw_data.MetaData.SessionLoadCount or 0,
Session = session and {PlaceId = session[1], JobId = session[2]},
RobloxMetaData = raw_data.RobloxMetaData or {},
UserIds = raw_data.UserIds or {},
KeyInfo = key_info,
OnAfterSave = Signal.New(),
OnSave = Signal.New(),
OnLastSave = Signal.New(),
OnSessionEnd = Signal.New(),
ProfileStore = profile_store,
Key = key,
load_timestamp = os.clock(),
is_mock = is_mock,
session_token = session_token or "",
load_index = raw_data.MetaData and raw_data.MetaData.SessionLoadCount or 0,
locked_global_updates = {},
received_global_updates = received_global_updates,
message_handlers = {},
global_updates = global_updates,
}
setmetatable(self, Profile)
return self
end
function Profile:IsActive()
return ActiveSessionCheck[self.session_token] == self
end
function Profile:Reconcile()
ReconcileTable(self.Data, self.ProfileStore.template)
end
function Profile:EndSession()
if self:IsActive() == true then
task.spawn(SaveProfileAsync, self, true, nil, "Manual") -- Call save function in a new thread with release_from_session = true
end
end
function Profile:AddUserId(user_id) -- Associates user_id with profile (GDPR compliance)
if type(user_id) ~= "number" or user_id % 1 ~= 0 then
warn(`[{script.Name}]: Invalid UserId argument for :AddUserId() ({tostring(user_id)}); Traceback:\n` .. debug.traceback())
return
end
if user_id < 0 and self.is_mock ~= true and DataStoreState == "Access" then
return -- Avoid giving real Roblox APIs negative UserId's
end
if table.find(self.UserIds, user_id) == nil then
table.insert(self.UserIds, user_id)
end
end
function Profile:RemoveUserId(user_id) -- Removes user_id association with profile (safe function)
if type(user_id) ~= "number" or user_id % 1 ~= 0 then
warn(`[{script.Name}]: Invalid UserId argument for :RemoveUserId() ({tostring(user_id)}); Traceback:\n` .. debug.traceback())
return
end
local index = table.find(self.UserIds, user_id)
if index ~= nil then
table.remove(self.UserIds, index)
end
end
function Profile:SetAsync() -- Saves the profile to the DataStore and removes the session lock
if self.view_mode ~= true then
error(`[{script.Name}]: :SetAsync() can only be used in view mode`)
end
SaveProfileAsync(self, nil, true)
end
function Profile:MessageHandler(fn)
if type(fn) ~= "function" then
error(`[{script.Name}]: fn argument is not a function`)
end
if self.view_mode ~= true and self:IsActive() ~= true then
return -- Don't process messages if the profile session was ended
end
local locked_updates = self.locked_global_updates
table.insert(self.message_handlers, fn)
for _, update in ipairs(self.global_updates) do
local index = update[1]
local update_data = update[#update] -- Backwards compatibility with ProfileService
if locked_updates[index] ~= true then
local processed_callback = function()
locked_updates[index] = true
end
local send_update_data = DeepCopyTable(update_data)
task.spawn(fn, send_update_data, processed_callback)
end
end
end
function Profile:Save()
if self.view_mode == true then
error(`[{script.Name}]: Can't save profile in view mode; Should you be calling :SetAsync() instead?`)
end
if self:IsActive() == false then
warn(`[{script.Name}]: Attempted saving an inactive profile (STORE:{self.ProfileStore.Name}; KEY:{self.Key});`
.. ` Traceback:\n` .. debug.traceback())
return
end
-- Move the profile right behind the auto save index to delay the next auto save for it:
RemoveProfileFromAutoSave(self)
AddProfileToAutoSave(self)
-- Perform save in new thread:
task.spawn(SaveProfileAsync, self)
end
local ProfileStore: ProfileStoreModule = {
IsClosing = false,
IsCriticalState = false,
OnError = OnError, -- (message, store_name, profile_key)
OnOverwrite = OnOverwrite, -- (store_name, profile_key)
OnCriticalToggle = Signal.New(), -- (is_critical)
DataStoreState = "NotReady", -- ("NotReady", "NoInternet", "NoAccess", "Access")
}
ProfileStore.__index = ProfileStore
function ProfileStore.SetConstant(name, value)
if type(value) ~= "number" then
error(`[{script.Name}]: Invalid value type`)
end
if name == "AUTO_SAVE_PERIOD" then
AUTO_SAVE_PERIOD = value
elseif name == "LOAD_REPEAT_PERIOD" then
LOAD_REPEAT_PERIOD = value
elseif name == "FIRST_LOAD_REPEAT" then
FIRST_LOAD_REPEAT = value
elseif name == "SESSION_STEAL" then
SESSION_STEAL = value
elseif name == "ASSUME_DEAD" then
ASSUME_DEAD = value
elseif name == "START_SESSION_TIMEOUT" then
START_SESSION_TIMEOUT = value
elseif name == "CRITICAL_STATE_ERROR_COUNT" then
CRITICAL_STATE_ERROR_COUNT = value
elseif name == "CRITICAL_STATE_ERROR_EXPIRE" then
CRITICAL_STATE_ERROR_EXPIRE = value
elseif name == "CRITICAL_STATE_EXPIRE" then
CRITICAL_STATE_EXPIRE = value
elseif name == "MAX_MESSAGE_QUEUE" then
MAX_MESSAGE_QUEUE = value
else
error(`[{script.Name}]: Invalid constant name was provided`)
end
end
function ProfileStore.Test()
return {
ActiveSessionCheck = ActiveSessionCheck,
AutoSaveList = AutoSaveList,
ActiveProfileLoadJobs = ActiveProfileLoadJobs,
ActiveProfileSaveJobs = ActiveProfileSaveJobs,
MockStore = MockStore,
UserMockStore = UserMockStore,
UpdateQueue = UpdateQueue,
}
end
function ProfileStore.New(store_name, template)
template = template or {}
if type(store_name) ~= "string" then
error(`[{script.Name}]: Invalid or missing "store_name"`)
elseif string.len(store_name) == 0 then
error(`[{script.Name}]: store_name cannot be an empty string`)
elseif string.len(store_name) > 50 then
error(`[{script.Name}]: store_name is too long`)
end
if type(template) ~= "table" then
error(`[{script.Name}]: Invalid template argument`)
end
local self
self = {
Mock = {
Name = store_name,
StartSessionAsync = function(_, profile_key)
MockFlag = true
return self:StartSessionAsync(profile_key)
end,
MessageAsync = function(_, profile_key, message)
MockFlag = true
return self:MessageAsync(profile_key, message)
end,
GetAsync = function(_, profile_key, version)
MockFlag = true
return self:GetAsync(profile_key, version)
end,
VersionQuery = function(_, profile_key, sort_direction, min_date, max_date)
MockFlag = true
return self:VersionQuery(profile_key, sort_direction, min_date, max_date)
end,
RemoveAsync = function(_, profile_key)
MockFlag = true
return self:RemoveAsync(profile_key)
end
},
Name = store_name,
template = template,
data_store = nil,
load_jobs = {},
mock_load_jobs = {},
is_ready = true,
}
setmetatable(self, ProfileStore)
local options = Instance.new("DataStoreOptions")
options:SetExperimentalFeatures({v2 = true})
if DataStoreState == "NotReady" then
-- The module is not sure whether DataStores are accessible yet:
self.is_ready = false
task.spawn(function()
repeat task.wait() until DataStoreState ~= "NotReady"
if DataStoreState == "Access" then
self.data_store = DataStoreService:GetDataStore(store_name, nil, options)
end
self.is_ready = true
end)
elseif DataStoreState == "Access" then
self.data_store = DataStoreService:GetDataStore(store_name, nil, options)
end
return self
end
local function RobloxMessageSubscription(profile, unique_session_id)
local last_roblox_message = 0
local roblox_message_subscription = MessagingService:SubscribeAsync("PS_" .. unique_session_id, function(message)
if type(message.Data) == "table" and message.Data.LoadCount == profile.SessionLoadCount then
-- High reaction rate, based on numPlayers × 10 DataStore budget as of writing
if os.clock() - last_roblox_message > 6 then
last_roblox_message = os.clock()
if profile:IsActive() == true then
if message.Data.EndSession == true then
SaveProfileAsync(profile, true, false, "External")
else
profile:Save()
end
end
end
end
end)
if profile:IsActive() == true then
profile.roblox_message_subscription = roblox_message_subscription
else
roblox_message_subscription:Disconnect()
end
end
function ProfileStore:StartSessionAsync(profile_key, params)
local is_mock = ReadMockFlag()
if type(profile_key) ~= "string" then
error(`[{script.Name}]: profile_key must be a string`)
elseif string.len(profile_key) == 0 then
error(`[{script.Name}]: Invalid profile_key`)
elseif string.len(profile_key) > 50 then
error(`[{script.Name}]: profile_key is too long`)
end
if params ~= nil and type(params) ~= "table" then
error(`[{script.Name}]: Invalid params`)
end
params = params or {}
if ProfileStore.IsClosing == true then
return nil
end
WaitForStoreReady(self)
local session_token = SessionToken(self.Name, profile_key, is_mock)
if ActiveSessionCheck[session_token] ~= nil then
error(`[{script.Name}]: Profile (STORE:{self.Name}; KEY:{profile_key}) is already loaded in this session`)
end
ActiveProfileLoadJobs = ActiveProfileLoadJobs + 1
local is_user_cancel = false
local function cancel_condition()
if is_user_cancel == false then
if params.Cancel ~= nil then
is_user_cancel = params.Cancel() == true
end
return is_user_cancel
end
return true
end
local user_steal = params.Steal == true
local force_load_steps = 0 -- Session conflict handling values
local request_force_load = true
local steal_session = false
local start = os.clock()
local exp_backoff = 1
while ProfileStore.IsClosing == false and cancel_condition() == false do
-- Load profile:
-- SPECIAL CASE - If StartSessionAsync is called for the same key again before another StartSessionAsync finishes,
-- grab the DataStore return for the new call. The early call will return nil. This is supposed to retain
-- expected and efficient behavior in cases where a player would quickly rejoin the same server.
LoadIndex += 1
local load_id = LoadIndex
local profile_load_jobs = is_mock == true and self.mock_load_jobs or self.load_jobs
local profile_load_job = profile_load_jobs[profile_key] -- {load_id, {loaded_data, key_info} or nil}
local loaded_data, key_info
local unique_session_id = HttpService:GenerateGUID(false)
if profile_load_job ~= nil then
profile_load_job[1] = load_id -- Steal load job
while profile_load_job[2] == nil do -- Wait for job to finish
task.wait()
end
if profile_load_job[1] == load_id then -- Load job hasn't been double-stolen
loaded_data, key_info = table.unpack(profile_load_job[2])
profile_load_jobs[profile_key] = nil
else
ActiveProfileLoadJobs = ActiveProfileLoadJobs - 1
return nil
end
else
profile_load_job = {load_id, nil}
profile_load_jobs[profile_key] = profile_load_job
profile_load_job[2] = table.pack(UpdateAsync(
self,
profile_key,
{
ExistingProfileHandle = function(latest_data)
if ProfileStore.IsClosing == true or cancel_condition() == true then
return
end
local active_session = latest_data.MetaData.ActiveSession
local force_load_session = latest_data.MetaData.ForceLoadSession
if active_session == nil then
latest_data.MetaData.ActiveSession = {PlaceId, JobId, unique_session_id}
latest_data.MetaData.ForceLoadSession = nil
elseif type(active_session) == "table" then
if IsThisSession(active_session) == false then
local last_update = latest_data.MetaData.LastUpdate
if last_update ~= nil then
if os.time() - last_update > ASSUME_DEAD then
latest_data.MetaData.ActiveSession = {PlaceId, JobId, unique_session_id}
latest_data.MetaData.ForceLoadSession = nil
return
end
end
if steal_session == true or user_steal == true then
local force_load_interrupted = if force_load_session ~= nil then not IsThisSession(force_load_session) else true
if force_load_interrupted == false or user_steal == true then
latest_data.MetaData.ActiveSession = {PlaceId, JobId, unique_session_id}
latest_data.MetaData.ForceLoadSession = nil
end
elseif request_force_load == true then
latest_data.MetaData.ForceLoadSession = {PlaceId, JobId}
end
else
latest_data.MetaData.ForceLoadSession = nil
end
end
end,
MissingProfileHandle = function(latest_data)
local is_cancel = ProfileStore.IsClosing == true or cancel_condition() == true
latest_data.Data = DeepCopyTable(self.template)
latest_data.MetaData = {
ProfileCreateTime = os.time(),
SessionLoadCount = 0,
ActiveSession = if is_cancel == false then {PlaceId, JobId, unique_session_id} else nil,
ForceLoadSession = nil,
MetaTags = {}, -- Backwards compatibility with ProfileService
}
end,
EditProfile = function(latest_data)
if ProfileStore.IsClosing == true or cancel_condition() == true then
return
end
local active_session = latest_data.MetaData.ActiveSession
if active_session ~= nil and IsThisSession(active_session) == true then
latest_data.MetaData.SessionLoadCount = latest_data.MetaData.SessionLoadCount + 1
latest_data.MetaData.LastUpdate = os.time()
end
end,
},
is_mock
))
if profile_load_job[1] == load_id then -- Load job hasn't been stolen
loaded_data, key_info = table.unpack(profile_load_job[2])
profile_load_jobs[profile_key] = nil
else
ActiveProfileLoadJobs = ActiveProfileLoadJobs - 1
return nil -- Load job stolen
end
end
-- Handle load_data:
if loaded_data ~= nil and key_info ~= nil then
local active_session = loaded_data.MetaData.ActiveSession
if type(active_session) == "table" then
if IsThisSession(active_session) == true then
-- Profile is now taken by this session:
local profile = Profile.New(loaded_data, key_info, self, profile_key, is_mock, session_token)
AddProfileToAutoSave(profile)
if is_mock ~= true and DataStoreState == "Access" then
-- Use MessagingService to quickly detect session conflicts and resolve them quickly:
task.spawn(RobloxMessageSubscription, profile, unique_session_id) -- Blocking prevention
end
if ProfileStore.IsClosing == true or cancel_condition() == true then
-- The server has initiated a shutdown by the time this profile was loaded
SaveProfileAsync(profile, true) -- Release profile and yield until the DataStore call is finished
profile = nil -- Don't return the profile object
end
ActiveProfileLoadJobs = ActiveProfileLoadJobs - 1
return profile
else
if ProfileStore.IsClosing == true or cancel_condition() == true then
ActiveProfileLoadJobs = ActiveProfileLoadJobs - 1
return nil
end
-- Profile is taken by some other session:
local force_load_session = loaded_data.MetaData.ForceLoadSession
local force_load_interrupted = if force_load_session ~= nil then not IsThisSession(force_load_session) else true
if force_load_interrupted == false then
if request_force_load == false then
force_load_steps = force_load_steps + 1
if force_load_steps >= math.ceil(SESSION_STEAL / LOAD_REPEAT_PERIOD) then
steal_session = true
end
end
-- Request the remote server to end its session:
if type(active_session[3]) == "string" then
local session_load_count = loaded_data.MetaData.SessionLoadCount or 0
task.spawn(MessagingService.PublishAsync, MessagingService, "PS_" .. active_session[3], {LoadCount = session_load_count, EndSession = true})
end
-- Attempt to load the profile again after a delay
local wait_until = os.clock() + if request_force_load == true then FIRST_LOAD_REPEAT else LOAD_REPEAT_PERIOD
repeat task.wait() until os.clock() >= wait_until or ProfileStore.IsClosing == true
else
-- Another session tried to load this profile:
ActiveProfileLoadJobs = ActiveProfileLoadJobs - 1
return nil
end
request_force_load = false -- Only request a force load once
end
else
ActiveProfileLoadJobs = ActiveProfileLoadJobs - 1
return nil -- In this scenario it is likely that this server started shutting down
end
else
-- A DataStore call has likely ended in an error:
local default_timeout = false
if params.Cancel == nil then
default_timeout = os.clock() - start >= START_SESSION_TIMEOUT
end
if default_timeout == true or ProfileStore.IsClosing == true or cancel_condition() == true then
ActiveProfileLoadJobs = ActiveProfileLoadJobs - 1
return nil
end
task.wait(exp_backoff) -- Repeat the call shortly
exp_backoff = math.min(20, exp_backoff * 2)
end
end
ActiveProfileLoadJobs = ActiveProfileLoadJobs - 1
return nil -- Game started shutting down or the request was cancelled - don't return the profile
end
function ProfileStore:MessageAsync(profile_key, message)
local is_mock = ReadMockFlag()
if type(profile_key) ~= "string" then
error(`[{script.Name}]: profile_key must be a string`)
elseif string.len(profile_key) == 0 then
error(`[{script.Name}]: Invalid profile_key`)
elseif string.len(profile_key) > 50 then
error(`[{script.Name}]: profile_key is too long`)
end
if type(message) ~= "table" then
error(`[{script.Name}]: message must be a table`)
end
if ProfileStore.IsClosing == true then
return false
end
WaitForStoreReady(self)
local exp_backoff = 1
while ProfileStore.IsClosing == false do
-- Updating profile:
local loaded_data = UpdateAsync(
self,
profile_key,
{
ExistingProfileHandle = nil,
MissingProfileHandle = nil,
EditProfile = function(latest_data)
local global_updates = latest_data.GlobalUpdates
local update_list = global_updates[2]
--{
-- update_index,
-- {
-- {update_index, data}, ...
-- },
--},
global_updates[1] += 1
table.insert(update_list, {global_updates[1], message})
-- Clearing queue if above limit:
while #update_list > MAX_MESSAGE_QUEUE do
table.remove(update_list, 1)
end
end,
},
is_mock
)
if loaded_data ~= nil then
local session_token = SessionToken(self.Name, profile_key, is_mock)
local profile = ActiveSessionCheck[session_token]
if profile ~= nil then
-- The message was sent to a profile that is active in this server:
profile:Save()
else
local meta_data = loaded_data.MetaData or {}
local active_session = meta_data.ActiveSession
local session_load_count = meta_data.SessionLoadCount or 0
if type(active_session) == "table" and type(active_session[3]) == "string" then
-- Request the remote server to auto-save sooner and receive the message:
task.spawn(MessagingService.PublishAsync, MessagingService, "PS_" .. active_session[3], {LoadCount = session_load_count})
end
end
return true
else
task.wait(exp_backoff) -- A DataStore call has likely ended in an error - repeat the call shortly
exp_backoff = math.min(20, exp_backoff * 2)
end
end
return false
end
function ProfileStore:GetAsync(profile_key, version)
local is_mock = ReadMockFlag()
if type(profile_key) ~= "string" then
error(`[{script.Name}]: profile_key must be a string`)
elseif string.len(profile_key) == 0 then
error(`[{script.Name}]: Invalid profile_key`)
elseif string.len(profile_key) > 50 then
error(`[{script.Name}]: profile_key is too long`)
end
if ProfileStore.IsClosing == true then
return nil
end
WaitForStoreReady(self)
if version ~= nil and (is_mock or DataStoreState ~= "Access") then
return nil -- No version support in mock mode
end
local exp_backoff = 1
while ProfileStore.IsClosing == false do
-- Load profile:
local loaded_data, key_info = UpdateAsync(
self,
profile_key,
{
ExistingProfileHandle = nil,
MissingProfileHandle = function(latest_data)
latest_data.Data = DeepCopyTable(self.template)
latest_data.MetaData = {
ProfileCreateTime = os.time(),
SessionLoadCount = 0,
ActiveSession = nil,
ForceLoadSession = nil,
MetaTags = {}, -- Backwards compatibility with ProfileService
}
end,
EditProfile = nil,
},
is_mock,
true, -- Use :GetAsync()
version -- DataStore key version
)
-- Handle load_data:
if loaded_data ~= nil then
if key_info == nil then
return nil -- Load was successful, but the key was empty - return no profile object
end
local profile = Profile.New(loaded_data, key_info, self, profile_key, is_mock)
profile.view_mode = true
return profile
else
task.wait(exp_backoff) -- A DataStore call has likely ended in an error - repeat the call shortly
exp_backoff = math.min(20, exp_backoff * 2)
end
end
return nil -- Game started shutting down - don't return the profile
end
function ProfileStore:RemoveAsync(profile_key)
local is_mock = ReadMockFlag()
if type(profile_key) ~= "string" or string.len(profile_key) == 0 then
error(`[{script.Name}]: Invalid profile_key`)
end
if ProfileStore.IsClosing == true then
return false
end
WaitForStoreReady(self)
local wipe_status = false
local next_in_queue = WaitInUpdateQueue(SessionToken(self.Name, profile_key, is_mock))
if is_mock == true then -- Used when the profile is accessed through ProfileStore.Mock
local mock_data_store = UserMockStore[self.Name]
if mock_data_store ~= nil then
mock_data_store[profile_key] = nil
if next(mock_data_store) == nil then
UserMockStore[self.Name] = nil
end
end
wipe_status = true
task.wait() -- Simulate API call yield
elseif DataStoreState ~= "Access" then -- Used when API access is disabled
local mock_data_store = MockStore[self.Name]
if mock_data_store ~= nil then
mock_data_store[profile_key] = nil
if next(mock_data_store) == nil then
MockStore[self.Name] = nil
end
end
wipe_status = true
task.wait() -- Simulate API call yield
else -- Live DataStore
wipe_status = pcall(function()
self.data_store:RemoveAsync(profile_key)
end)
end
next_in_queue()
return wipe_status
end
local ProfileVersionQuery = {}
ProfileVersionQuery.__index = ProfileVersionQuery
function ProfileVersionQuery.New(profile_store, profile_key, sort_direction, min_date, max_date, is_mock)
local self = {
profile_store = profile_store,
profile_key = profile_key,
sort_direction = sort_direction,
min_date = min_date,
max_date = max_date,
query_pages = nil,
query_index = 0,
query_failure = false,
is_query_yielded = false,
query_queue = {},
is_mock = is_mock,
}
setmetatable(self, ProfileVersionQuery)
return self
end
function MoveVersionQueryQueue(self) -- Hidden ProfileVersionQuery method
while #self.query_queue > 0 do
local queue_entry = table.remove(self.query_queue, 1)
task.spawn(queue_entry)
if self.is_query_yielded == true then
break
end
end
end
local VersionQueryNextAsyncStackingFlag = false
local WarnAboutVersionQueryOnce = false
function ProfileVersionQuery:NextAsync()
local is_stacking = VersionQueryNextAsyncStackingFlag == true
VersionQueryNextAsyncStackingFlag = false
WaitForStoreReady(self.profile_store)
if ProfileStore.IsClosing == true then
return nil -- Silently fail :NextAsync() requests
end
if self.is_mock == true or DataStoreState ~= "Access" then
if IsStudio == true and WarnAboutVersionQueryOnce == false then
WarnAboutVersionQueryOnce = true
warn(`[{script.Name}]: :VersionQuery() is not supported in mock mode!`)
end
return nil -- Silently fail :NextAsync() requests
end
local profile
local is_finished = false
local function query_job()
if self.query_failure == true then
is_finished = true
return
end
-- First "next" call loads version pages:
if self.query_pages == nil then
self.is_query_yielded = true
task.spawn(function()
VersionQueryNextAsyncStackingFlag = true
profile = self:NextAsync()
is_finished = true
end)
local list_success, error_message = pcall(function()
self.query_pages = self.profile_store.data_store:ListVersionsAsync(
self.profile_key,
self.sort_direction,
self.min_date,
self.max_date
)
self.query_index = 0
end)
if list_success == false or self.query_pages == nil then
warn(`[{script.Name}]: Version query fail - {tostring(error_message)}`)
self.query_failure = true
end
self.is_query_yielded = false
MoveVersionQueryQueue(self)
return
end
local current_page = self.query_pages:GetCurrentPage()
local next_item = current_page[self.query_index + 1]
-- No more entries:
if self.query_pages.IsFinished == true and next_item == nil then
is_finished = true
return
end
-- Load next page when this page is over:
if next_item == nil then
self.is_query_yielded = true
task.spawn(function()
VersionQueryNextAsyncStackingFlag = true
profile = self:NextAsync()
is_finished = true
end)
local success, error_message = pcall(function()
self.query_pages:AdvanceToNextPageAsync()
self.query_index = 0
end)
if success == false or #self.query_pages:GetCurrentPage() == 0 then
self.query_failure = true
end
self.is_query_yielded = false
MoveVersionQueryQueue(self)
return
end
-- Next page item:
self.query_index += 1
profile = self.profile_store:GetAsync(self.profile_key, next_item.Version)
is_finished = true
end
if self.is_query_yielded == false then
query_job()
else
if is_stacking == true then
table.insert(self.query_queue, 1, query_job)
else
table.insert(self.query_queue, query_job)
end
end
while is_finished == false do
task.wait()
end
return profile
end
function ProfileStore:VersionQuery(profile_key, sort_direction, min_date, max_date)
local is_mock = ReadMockFlag()
if type(profile_key) ~= "string" or string.len(profile_key) == 0 then
error(`[{script.Name}]: Invalid profile_key`)
end
-- Type check:
if sort_direction ~= nil and (typeof(sort_direction) ~= "EnumItem"
or sort_direction.EnumType ~= Enum.SortDirection) then
error(`[{script.Name}]: Invalid sort_direction ({tostring(sort_direction)})`)
end
if min_date ~= nil and typeof(min_date) ~= "DateTime" and typeof(min_date) ~= "number" then
error(`[{script.Name}]: Invalid min_date ({tostring(min_date)})`)
end
if max_date ~= nil and typeof(max_date) ~= "DateTime" and typeof(max_date) ~= "number" then
error(`[{script.Name}]: Invalid max_date ({tostring(max_date)})`)
end
min_date = typeof(min_date) == "DateTime" and min_date.UnixTimestampMillis or min_date
max_date = typeof(max_date) == "DateTime" and max_date.UnixTimestampMillis or max_date
return ProfileVersionQuery.New(self, profile_key, sort_direction, min_date, max_date, is_mock)
end
-- DataStore API access check:
if IsStudio == true then
task.spawn(function()
local new_state = "NoAccess"
local status, message = pcall(function()
-- This will error if current instance has no Studio API access:
DataStoreService:GetDataStore("____PS"):SetAsync("____PS", os.time())
end)
local no_internet_access = status == false and string.find(message, "ConnectFail", 1, true) ~= nil
if no_internet_access == true then
warn(`[{script.Name}]: No internet access - check your network connection`)
end
if status == false and
(string.find(message, "403", 1, true) ~= nil or -- Cannot write to DataStore from studio if API access is not enabled
string.find(message, "must publish", 1, true) ~= nil or -- Game must be published to access live keys
no_internet_access == true) then -- No internet access
new_state = if no_internet_access == true then "NoInternet" else "NoAccess"
print(`[{script.Name}]: Roblox API services unavailable - data will not be saved`)
else
new_state = "Access"
print(`[{script.Name}]: Roblox API services available - data will be saved`)
end
DataStoreState = new_state
ProfileStore.DataStoreState = new_state
end)
else
DataStoreState = "Access"
ProfileStore.DataStoreState = "Access"
end
-- Update loop:
RunService.Heartbeat:Connect(function()
-- Auto saving:
local auto_save_list_length = #AutoSaveList
if auto_save_list_length > 0 then
local auto_save_index_speed = AUTO_SAVE_PERIOD / auto_save_list_length
local os_clock = os.clock()
while os_clock - LastAutoSave > auto_save_index_speed do
LastAutoSave = LastAutoSave + auto_save_index_speed
local profile = AutoSaveList[AutoSaveIndex]
if os_clock - profile.load_timestamp < AUTO_SAVE_PERIOD / 2 then
-- This profile is freshly loaded - auto saving immediately is not necessary:
profile = nil
for _ = 1, auto_save_list_length - 1 do
-- Move auto save index to the right:
AutoSaveIndex = AutoSaveIndex + 1
if AutoSaveIndex > auto_save_list_length then
AutoSaveIndex = 1
end
profile = AutoSaveList[AutoSaveIndex]
if os_clock - profile.load_timestamp >= AUTO_SAVE_PERIOD / 2 then
break
else
profile = nil
end
end
end
-- Move auto save index to the right:
AutoSaveIndex = AutoSaveIndex + 1
if AutoSaveIndex > auto_save_list_length then
AutoSaveIndex = 1
end
-- Perform save call:
if profile ~= nil then
task.spawn(SaveProfileAsync, profile) -- Auto save profile in new thread
end
end
end
-- Critical state handling:
if ProfileStore.IsCriticalState == false then
if #IssueQueue >= CRITICAL_STATE_ERROR_COUNT then
ProfileStore.IsCriticalState = true
ProfileStore.OnCriticalToggle:Fire(true)
CriticalStateStart = os.clock()
warn(`[{script.Name}]: Entered critical state`)
end
else
if #IssueQueue >= CRITICAL_STATE_ERROR_COUNT then
CriticalStateStart = os.clock()
elseif os.clock() - CriticalStateStart > CRITICAL_STATE_EXPIRE then
ProfileStore.IsCriticalState = false
ProfileStore.OnCriticalToggle:Fire(false)
warn(`[{script.Name}]: Critical state ended`)
end
end
-- Issue queue:
while true do
local issue_time = IssueQueue[1]
if issue_time == nil then
break
elseif os.clock() - issue_time > CRITICAL_STATE_ERROR_EXPIRE then
table.remove(IssueQueue, 1)
else
break
end
end
end)
-- Release all loaded profiles when the server is shutting down:
task.spawn(function()
while DataStoreState == "NotReady" do
task.wait()
end
if DataStoreState ~= "Access" then
game:BindToClose(function()
ProfileStore.IsClosing = true
task.wait() -- Mock shutdown delay
end)
return -- Don't wait for profiles to properly save in mock mode so studio could end the simulation faster
end
game:BindToClose(function()
ProfileStore.IsClosing = true
-- Release all active profiles:
-- (Clone AutoSaveList to a new table because AutoSaveList changes when profiles are released)
local on_close_save_job_count = 0
local active_profiles = {}
for index, profile in ipairs(AutoSaveList) do
active_profiles[index] = profile
end
-- Release the profiles; Releasing profiles can trigger listeners that release other profiles, so check active state:
for _, profile in ipairs(active_profiles) do
if profile:IsActive() == true then
on_close_save_job_count = on_close_save_job_count + 1
task.spawn(function() -- Save profile on new thread
SaveProfileAsync(profile, true, nil, "Shutdown")
on_close_save_job_count = on_close_save_job_count - 1
end)
end
end
-- Yield until all active profile jobs are finished:
while on_close_save_job_count > 0 or ActiveProfileLoadJobs > 0 or ActiveProfileSaveJobs > 0 do
task.wait()
end
return -- We're done!
end)
end)
return ProfileStore - Edit
03:12:20.476
- Edit
03:12:20.476
============================== - Edit
03:12:20.476 📜 ServerScriptService.Controllers.BaseLockController - Edit
03:12:20.477 ==============================
- Edit
03:12:20.477 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local CollectionService = game:GetService("CollectionService")
local Packages = ReplicatedStorage.Packages
local Data = ReplicatedStorage.Datas
local Services = game:GetService("ServerScriptService").Services
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local DataManagement = require(Services.DataManagment)
local GameData = require(Data.Game)
local Rebirths = require(Data.Rebirth)
local NotificationEvent = Net:RemoteEvent("NotificationService/Notify")
local BASE_LOCK_DURATION = GameData.BlockBase.Duration or 60
local PlayerDebounce = {}
local BaseLockController = {}
function BaseLockController:Start()
self:SetupPlotHitboxes()
Players.PlayerRemoving:Connect(function(player)
if PlayerDebounce[player.UserId] then
PlayerDebounce[player.UserId] = nil
end
end)
end
function BaseLockController:GetLockDuration(player)
if not player or not player.Parent then
return BASE_LOCK_DURATION
end
local Data = DataManagement.GetDataMan(player)
if not Data then
return BASE_LOCK_DURATION
end
local Rebirth = Data.Rebirths <= 0 and 0 or (Rebirths[Data.Rebirths].Rewards.AdditionalLockTime)
return BASE_LOCK_DURATION + Rebirth
end
function BaseLockController:UpdateLasersAndHitbox(plot, plotModel, isLocked, owner)
if not plotModel then
return
end
local MonetizationService = _G.MonetizationService
if owner and MonetizationService and MonetizationService.GetBaseLockHandler then
local success, handler = pcall(function()
return MonetizationService:GetBaseLockHandler()
end)
if success and handler and handler.UpdateAllFloorStates then
local updateSuccess = pcall(function()
handler:UpdateAllFloorStates(owner)
end)
if updateSuccess then
return
end
end
end
local Laser = plotModel:FindFirstChild("Laser")
if not Laser then
return
end
local LaserHitbox = plotModel:FindFirstChild("LaserHitbox")
if not LaserHitbox then
return
end
for _, hitbox in pairs(LaserHitbox:GetChildren()) do
local hitboxFloor = hitbox:GetAttribute("Floor")
if hitboxFloor and hitboxFloor >= 1 and hitboxFloor <= 3 then
local floorKey = "BlockEndTime" .. (hitboxFloor == 1 and "FirstFloor" or hitboxFloor == 2 and "SecondFloor" or "ThirdFloor")
local floorLocked = plot:Get(floorKey) ~= nil
hitbox.CanCollide = floorLocked
if not floorLocked then
hitbox:SetAttribute("ServerControlled", true)
else
hitbox:SetAttribute("ServerControlled", nil)
end
else
hitbox.CanCollide = isLocked
if isLocked then
hitbox:SetAttribute("ServerControlled", nil)
end
end
end
for _, laserModel in pairs(Laser:GetChildren()) do
if laserModel:IsA("Model") then
local laserFloor = laserModel:GetAttribute("Floor")
if laserFloor and laserFloor >= 1 and laserFloor <= 3 then
local floorKey = "BlockEndTime" .. (laserFloor == 1 and "FirstFloor" or laserFloor == 2 and "SecondFloor" or "ThirdFloor")
local floorLocked = plot:Get(floorKey) ~= nil
for _, laserPart in pairs(laserModel:GetDescendants()) do
if laserPart:IsA("BasePart") then
laserPart.Transparency = floorLocked and 0 or 1
end
end
else
for _, laserPart in pairs(laserModel:GetDescendants()) do
if laserPart:IsA("BasePart") then
laserPart.Transparency = isLocked and 0 or 1
end
end
end
else
if laserModel:IsA("BasePart") then
laserModel.Transparency = isLocked and 0 or 1
end
end
end
end
function BaseLockController:SendNotification(player, success, message)
if not player or not player.Parent then
return
end
local color = success and "#92FF67" or "#FA0103"
local formattedMessage = string.format("%s", color, message)
local success, err = pcall(function()
NotificationEvent:FireClient(player, formattedMessage, 5, success and "Sounds.Sfx.Success" or "Sounds.Sfx.Error")
end)
if not success then
-- Player likely left, silently ignore
end
end
function BaseLockController:LockPlayerBase(player, plotUUID)
if not player or not plotUUID then
warn("[BaseLockController] Invalid player or plotUUID")
return
end
local plot = Synchronizer:Get(plotUUID)
if not plot then
warn("[BaseLockController] Plot not found:", plotUUID)
return
end
if plot:Get("Owner") ~= player then
self:SendNotification(player, false, "You can only lock your own base!")
return
end
local currentTime = workspace:GetServerTimeNow()
if plot:Get("BlockEndTime") and currentTime < plot:Get("BlockEndTime") then
self:SendNotification(player, false, "Your base is already locked!")
return
end
local lockDuration = self:GetLockDuration(player)
plot:Set("BlockEndTime", currentTime + lockDuration)
plot:Set("BlockEndTimeFirstFloor", currentTime + lockDuration)
plot:Set("BlockEndTimeSecondFloor", currentTime + lockDuration)
plot:Set("BlockEndTimeThirdFloor", currentTime + lockDuration)
local plotModel = workspace.Plots:FindFirstChild(plotUUID)
if plotModel then
self:UpdateLasersAndHitbox(plot, plotModel, true, player)
end
self:SendNotification(player, true, string.format("You locked your base for %d seconds!", lockDuration))
local plotChannel = plot
local function performUnlock()
if plotChannel and plotChannel.Get == nil then
return
end
if plotChannel:Get("BlockEndTime") == nil then
return
end
plotChannel:Set("BlockEndTime", nil)
plotChannel:Set("BlockEndTimeFirstFloor", nil)
plotChannel:Set("BlockEndTimeSecondFloor", nil)
plotChannel:Set("BlockEndTimeThirdFloor", nil)
if plotModel and plotModel.Parent then
if player and player.Parent then
self:UpdateLasersAndHitbox(plotChannel, plotModel, false, player)
else
self:UpdateLasersAndHitbox(plotChannel, plotModel, false, nil)
end
end
end
local endTime = plot:Get("BlockEndTime")
if endTime == nil then
return
end
local now = workspace:GetServerTimeNow()
local remaining = endTime - now
if remaining > 0 then
task.delay(remaining, performUnlock)
else
performUnlock()
end
end
function BaseLockController:SetupPlotHitboxes()
local plots = workspace.Plots
if not plots then
return
end
plots.ChildAdded:Connect(function(plot)
if plot:IsA("Model") then
self:SetupPlotBlockHitboxes(plot)
end
end)
for _, plot in ipairs(plots:GetChildren()) do
if plot:IsA("Model") then
self:SetupPlotBlockHitboxes(plot)
end
end
end
function BaseLockController:SetupPlotBlockHitboxes(plot)
if not plot then
return
end
local plotUUID = plot.Name
plot.DescendantAdded:Connect(function(child)
if child.Name == "PlotBlock" and child:IsA("Model") then
self:ConnectPlotBlockHitbox(child, plotUUID)
end
end)
local plotBlocks = 0
for _, child in ipairs(plot:GetDescendants()) do
if child.Name == "PlotBlock" and child:IsA("Model") then
self:ConnectPlotBlockHitbox(child, plotUUID)
plotBlocks += 1
end
end
end
function BaseLockController:ConnectPlotBlockHitbox(plotBlock, plotUUID)
if not plotBlock then
return
end
local hitbox = plotBlock:FindFirstChild("Hitbox")
if not hitbox then
return
end
hitbox.Touched:Connect(function(hit)
if not hit or not hit.Parent then
return
end
local character = hit.Parent
local player = Players:GetPlayerFromCharacter(character)
if not player or not player.Parent then
return
end
if PlayerDebounce[player.UserId] then
return
end
PlayerDebounce[player.UserId] = true
task.delay(1, function()
if PlayerDebounce then
PlayerDebounce[player.UserId] = nil
end
end)
local plot = Synchronizer:Get(plotUUID)
if not plot then
return
end
local plotOwner = plot:Get("Owner")
if plot:Get("Owner") ~= player then
return
end
local blockEndTime = plot:Get("BlockEndTime")
if blockEndTime then
local remainingTime = math.ceil(blockEndTime - workspace:GetServerTimeNow())
self:SendNotification(player, false, "Your base is already locked!")
return
end
self:LockPlayerBase(player, plotUUID)
end)
end
return BaseLockController - Edit
03:12:20.477
- Edit
03:12:20.477
============================== - Edit
03:12:20.477 📜 ServerScriptService.Main.Data.CmdrSetup - Edit
03:12:20.477 ==============================
- Edit
03:12:20.477 local ServerScriptService = game:GetService("ServerScriptService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local CmdrService = require(ServerScriptService.Services.CmdrService)
local CONFIG = {
COMMAND_GROUPS = {"DefaultAdmin", "DefaultUtil", "DefaultDebug", "CustomAdmin"},
WELCOME_MESSAGE = "🎯 Admin access granted! Press F2 and type 'help' to get started.",
WELCOME_COLOR = Color3.fromRGB(85, 255, 127),
STARTUP_DELAY = 1
}
local cmdrService: CmdrService.CmdrServiceType
local function sendWelcomeMessage(player: Player)
task.spawn(function()
task.wait(2)
if not player.Parent then return end
local success, _ = pcall(function()
local cmdr = cmdrService:GetCmdr()
if cmdr and cmdr.RemoteEvent then
cmdr.RemoteEvent:FireClient(player, "AddLine", CONFIG.WELCOME_MESSAGE, CONFIG.WELCOME_COLOR)
end
end)
end)
end
local function onPlayerJoined(player: Player)
local isAuthorized = cmdrService:IsAuthorized(player)
if isAuthorized then
sendWelcomeMessage(player)
end
end
local function setupPlayerEvents()
Players.PlayerAdded:Connect(onPlayerJoined)
for _, player in ipairs(Players:GetPlayers()) do
task.spawn(onPlayerJoined, player)
end
end
local function waitForRequiredDependencies()
local function waitFor(childParent, childName)
local obj = childParent:WaitForChild(childName, 30)
if not obj then
return false
end
return true
end
if not waitFor(ReplicatedStorage, "Datas") then return false end
if not waitFor(ReplicatedStorage.Datas, "Animals") then return false end
if not waitFor(ReplicatedStorage.Datas, "Mutations") then return false end
if not waitFor(ServerScriptService.Services, "DataManagment") then return false end
return true
end
local function initializeCmdr()
if not waitForRequiredDependencies() then
return false
end
cmdrService = CmdrService.new()
cmdrService:Initialize()
cmdrService:SetWebhookUrl("")
cmdrService:RegisterDefaultCommands(CONFIG.COMMAND_GROUPS)
cmdrService:RegisterCustomTypes()
cmdrService:RegisterCustomCommands()
return true
end
local function main()
task.wait(CONFIG.STARTUP_DELAY)
if not initializeCmdr() then
end
setupPlayerEvents()
_G.CmdrService = cmdrService
end
main() - Edit
03:12:20.477
- Edit
03:12:20.477
============================== - Edit
03:12:20.477 📜 ServerScriptService.Main.Data.Initialize - Edit
03:12:20.477 ==============================
- Edit
03:12:20.477 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DataStoreModule = require(game.ServerScriptService.Services.DataManagment)
local Plots = require(game.ServerScriptService.Services.Plots)
local Playersmodule = require(game.ServerScriptService.Services.Players)
local TutorialService = require(game.ServerScriptService.Services.TutorialService)
local Tips = require(game.ServerScriptService.Services.Tips)
local Players = game:GetService("Players")
local InitializingPlayers = {}
local function initializePlayer(player: Player)
if InitializingPlayers[player] then
return
end
InitializingPlayers[player] = true
task.spawn(function()
local success, profile = pcall(function()
return DataStoreModule.loadProfile(player)
end)
if not success then
InitializingPlayers[player] = nil
player:Kick("Failed to load your data. Please rejoin the game.")
return
end
if not profile then
InitializingPlayers[player] = nil
return
end
local dataReady = DataStoreModule.waitForData(player, 30)
if not dataReady then
InitializingPlayers[player] = nil
player:Kick("Data loading timeout. Please rejoin the game.")
return
end
local plotSuccess = pcall(function()
Plots.CreatePlot(player)
end)
local Tips = pcall(function()
Tips.new(Plots)
end)
if not plotSuccess then
warn("Error initializing systems for " .. player.Name)
InitializingPlayers[player] = nil
player:Kick("Failed to initialize game systems. Please rejoin.")
return
end
InitializingPlayers[player] = nil
ReplicatedStorage:SetAttribute("ServerReady", true)
end)
end
Players.PlayerAdded:Connect(initializePlayer)
for _, player in pairs(Players:GetPlayers()) do
task.spawn(initializePlayer, player)
end
Players.PlayerRemoving:Connect(function(player)
InitializingPlayers[player] = nil
local success, err = pcall(function()
DataStoreModule.updateLastOnline(player)
DataStoreModule.saveProfile(player)
end)
if not success then
task.wait(1)
local forceSuccess, forceErr = pcall(function()
DataStoreModule.forceCleanupSession(player)
end)
end
end) - Edit
03:12:20.477
- Edit
03:12:20.477
============================== - Edit
03:12:20.477 📜 ServerScriptService.Main.Data.MonetizationInit - Edit
03:12:20.477 ==============================
- Edit
03:12:20.477 local ServerScriptService = game:GetService("ServerScriptService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MonetizationService = require(ServerScriptService.Services.MonetizationService)
local function InitializeMonetization()
if not _G.MonetizationService then
local monetizationInstance = MonetizationService.new()
_G.MonetizationService = monetizationInstance
end
end
InitializeMonetization() - Edit
03:12:20.477
- Edit
03:12:20.477
============================== - Edit
03:12:20.477 📜 ServerScriptService.Main.Data.NonEmptySlotHandler - Edit
03:12:20.478 ==============================
- Edit
03:12:20.478 local ServerScriptService = game:GetService("ServerScriptService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DataManagement = require(ServerScriptService.Services.DataManagment)
local Net = require(ReplicatedStorage.Packages.Net)
Net:RemoteFunction("NonEmptySlots/Get").OnServerInvoke = function(player)
if not DataManagement.isDataReady(player) then
warn("[NonEmptySlotHandler] Data not ready for player:", player.Name)
return {}
end
local animalList = DataManagement.getAnimalList(player)
if not animalList then
warn("[NonEmptySlotHandler] No animal list found for player:", player.Name)
return {}
end
local nonEmptySlots = {}
for slot, animal in pairs(animalList) do
if animal and animal ~= "Empty" and typeof(animal) == "table" and animal.Index then
table.insert(nonEmptySlots, slot)
end
end
return nonEmptySlots
end - Edit
03:12:20.478
- Edit
03:12:20.478
============================== - Edit
03:12:20.478 📜 ServerScriptService.Main.Data.Leaderboards - Edit
03:12:20.478 ==============================
- Edit
03:12:20.478 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local HttpService = game:GetService("HttpService")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local DataStoreModule = require(game:GetService("ServerScriptService").Services.DataManagment)
local GenerationLeaderboard = DataStoreService:GetOrderedDataStore("GlobalLeaderboards_Generation")
local StealsLeaderboard = DataStoreService:GetOrderedDataStore("GlobalLeaderboards_Steals")
local GetTopPlayers = Net:RemoteFunction("Leaderboard/GetTopPlayers")
local GetDisplayNames = Net:RemoteFunction("Leaderboard/GetDisplayNames")
local ReplicateUpdate = Net:RemoteEvent("Leaderboard/ReplicateUpdate")
local ReplicateDisplayNames = Net:RemoteEvent("Leaderboard/ReplicateDisplayNames")
local MAX_LEADERBOARD_SIZE = 100
local UPDATE_INTERVAL = 60
local DISPLAY_NAME_CACHE_DURATION = 3600
local MAX_RETRIES = 3
local RETRY_DELAY = 1
local MIN_DS_BUDGET = 1
local DisplayNameCache = {}
local LeaderboardCache = {Generation = {}, Steals = {}}
local NAME_REQUEST_THROTTLE = 0.25
local LastSavedValues = {
Generation = {},
Steals = {}
}
local function isValidPlayer(player)
return player and player.UserId and player.UserId > 0
end
local function updatePlayerLeaderboard(player, leaderboardType, value)
if not isValidPlayer(player) then return end
value = math.floor(value or 0)
if value <= 0 then return end
if leaderboardType == "Generation" and value < 1000 then return end
local last = LastSavedValues[leaderboardType][player.UserId]
if last and last == value then
return
end
local requestType = Enum.DataStoreRequestType.UpdateAsync
while DataStoreService:GetRequestBudgetForRequestType(requestType) < MIN_DS_BUDGET do
task.wait(1)
end
for attempt = 1, MAX_RETRIES do
local success, err = pcall(function()
if leaderboardType == "Generation" then
GenerationLeaderboard:SetAsync(tostring(player.UserId), value)
elseif leaderboardType == "Steals" then
StealsLeaderboard:SetAsync(tostring(player.UserId), value)
end
end)
if success then
LastSavedValues[leaderboardType][player.UserId] = value
return
end
if attempt < MAX_RETRIES then
task.wait(RETRY_DELAY * attempt)
end
end
end
local function getTopPlayers(leaderboardType)
for attempt = 1, MAX_RETRIES do
local success, result = pcall(function()
local leaderboard = leaderboardType == "Generation" and GenerationLeaderboard or StealsLeaderboard
local pages = leaderboard:GetSortedAsync(false, MAX_LEADERBOARD_SIZE, 0)
local data = pages:GetCurrentPage()
local topPlayers = {}
for rank, entry in ipairs(data) do
local userId = tonumber(entry.key)
if userId > 0 then
table.insert(topPlayers, {
UserId = userId,
Value = entry.value,
Rank = rank
})
end
end
return topPlayers
end)
if success then
return result
end
if attempt < MAX_RETRIES then
task.wait(RETRY_DELAY * attempt)
end
end
return {}
end
local function getDisplayNames(userIds)
local names = {}
local toFetch = {}
for _, userId in ipairs(userIds) do
if userId <= 0 then continue end
if DisplayNameCache[userId] and DisplayNameCache[userId].Timestamp + DISPLAY_NAME_CACHE_DURATION > os.time() then
names[userId] = DisplayNameCache[userId].Name
else
table.insert(toFetch, userId)
end
end
if #toFetch > 0 then
for index, userId in ipairs(toFetch) do
local success, fetchedName = pcall(Players.GetNameFromUserIdAsync, Players, userId)
if success and fetchedName then
DisplayNameCache[userId] = {Name = fetchedName, Timestamp = os.time()}
names[userId] = fetchedName
else
DisplayNameCache[userId] = {Name = "User" .. userId, Timestamp = os.time()}
if not names[userId] then
warn(string.format("[Leaderboards] Username fetch failed for %d : %s", userId, fetchedName or "HTTP error"))
end
names[userId] = "User" .. userId
end
if index < #toFetch then
task.wait(NAME_REQUEST_THROTTLE)
end
end
end
return names
end
local function updateLeaderboards()
for _, player in ipairs(Players:GetPlayers()) do
if not isValidPlayer(player) then continue end
if DataStoreModule.isDataReady(player) then
local data = DataStoreModule.GetDataMan(player)
local totalGeneration = DataStoreModule.getTotalGeneration(player)
updatePlayerLeaderboard(player, "Generation", totalGeneration)
updatePlayerLeaderboard(player, "Steals", data.Steals)
else
warn("Data not ready for player:", player.Name)
end
end
for _, leaderboardType in ipairs({"Generation", "Steals"}) do
local topPlayers = getTopPlayers(leaderboardType)
if #topPlayers > 0 then
LeaderboardCache[leaderboardType] = topPlayers
ReplicateUpdate:FireAllClients(leaderboardType, topPlayers)
local userIds = {}
for _, entry in ipairs(topPlayers) do
if entry.UserId > 0 then
table.insert(userIds, entry.UserId)
end
end
local displayNames = getDisplayNames(userIds)
ReplicateDisplayNames:FireAllClients(displayNames)
end
end
end
GetTopPlayers.OnServerInvoke = function(player, leaderboardType)
if leaderboardType ~= "Generation" and leaderboardType ~= "Steals" then return {} end
local data = LeaderboardCache[leaderboardType] or getTopPlayers(leaderboardType)
return data
end
GetDisplayNames.OnServerInvoke = function(player)
local userIds = {}
for _, leaderboardType in ipairs({"Generation", "Steals"}) do
for _, entry in ipairs(LeaderboardCache[leaderboardType] or {}) do
if entry.UserId > 0 then
table.insert(userIds, entry.UserId)
end
end
end
local names = getDisplayNames(userIds)
return names
end
Players.PlayerAdded:Connect(function(player)
if not isValidPlayer(player) then return end
task.wait(2)
DataStoreModule.loadProfileAsync(player)
task.spawn(function()
if DataStoreModule.waitForData(player, 30) then
local data = DataStoreModule.GetDataMan(player)
local totalGeneration = DataStoreModule.getTotalGeneration(player)
updatePlayerLeaderboard(player, "Generation", totalGeneration)
updatePlayerLeaderboard(player, "Steals", data.Steals)
for _, lbType in ipairs({"Generation", "Steals"}) do
local cached = LeaderboardCache[lbType]
if #cached > 0 then
ReplicateUpdate:FireClient(player, lbType, cached)
end
end
local userIds = {}
for _, lbType in ipairs({"Generation", "Steals"}) do
for _, entry in ipairs(LeaderboardCache[lbType] or {}) do
if entry.UserId > 0 then
table.insert(userIds, entry.UserId)
end
end
end
local names = getDisplayNames(userIds)
ReplicateDisplayNames:FireClient(player, names)
else
warn("Failed to load data for", player.Name)
end
end)
end)
Players.PlayerRemoving:Connect(function(player)
if not isValidPlayer(player) then return end
if DataStoreModule.isDataReady(player) then
local data = DataStoreModule.GetDataMan(player)
local totalGeneration = DataStoreModule.getTotalGeneration(player)
updatePlayerLeaderboard(player, "Generation", totalGeneration)
updatePlayerLeaderboard(player, "Steals", data.Steals)
end
end)
for _, player in ipairs(Players:GetPlayers()) do
if isValidPlayer(player) then
task.spawn(function()
if DataStoreModule.waitForData(player, 30) then
local data = DataStoreModule.GetDataMan(player)
local totalGeneration = DataStoreModule.getTotalGeneration(player)
updatePlayerLeaderboard(player, "Generation", totalGeneration)
updatePlayerLeaderboard(player, "Steals", data.Steals)
else
warn("Failed to load data for existing player:", player.Name)
end
end)
end
end
task.spawn(function()
while true do
updateLeaderboards()
task.wait(UPDATE_INTERVAL)
end
end) - Edit
03:12:20.478
- Edit
03:12:20.478
============================== - Edit
03:12:20.478 📜 ServerScriptService.Main.Data.Settings - Edit
03:12:20.478 ==============================
- Edit
03:12:20.478 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Net = require(ReplicatedStorage.Packages.Net)
local Players = game:GetService("Players")
local DataManagment = require(ServerScriptService.Services.DataManagment)
local Synchronizer = require(ReplicatedStorage.Packages.Synchronizer)
local SettingsService = Net:RemoteFunction("SettingsService/ToggleSetting")
SettingsService.OnServerInvoke = function(player, settingName, plotName)
warn(plotName, settingName)
if not DataManagment.isDataReady(player) then
DataManagment.waitForData(player)
end
local data = DataManagment.GetDataMan(player)
if not data then
return false, "Player data not found"
end
local settings = data.Settings
if not settings then
return false, "Settings data not found"
end
if plotName then
if settings[settingName] == nil then
return false, "Invalid setting name"
end
settings[settingName] = plotName
local players = Synchronizer:Get(player)
if players then
players:Set("Settings." .. settingName, settings[settingName])
end
DataManagment.ApplySkin(player, plotName)
return true, settings[settingName]
else
if settings[settingName] == nil then
return false, "Invalid setting name"
end
settings[settingName] = not settings[settingName]
local players = Synchronizer:Get(player)
if players then
players:Set("Settings." .. settingName, settings[settingName])
end
return true, settings[settingName]
end
end - Edit
03:12:20.478
- Edit
03:12:20.478
============================== - Edit
03:12:20.478 📜 ServerScriptService.Main.Items.Trap - Edit
03:12:20.479 ==============================
- Edit
03:12:20.479 local Players = game:GetService("Players")
local Debris = game:GetService("Debris")
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local trapDebounce = {}
local playerTrapDebounce = {}
local activeTraps = {}
local trappedPlayers = {}
local TRAP_LIFETIME = 120
local function getCharacterFromPart(part)
local character = part.Parent
if character and character:FindFirstChildOfClass("Humanoid") then
return character, character:FindFirstChildOfClass("Humanoid")
end
return nil, nil
end
local function createTrappedGUI(character)
local overheadsFolder = ReplicatedStorage:FindFirstChild("Overheads")
if not overheadsFolder then
return nil
end
local animalOverheadTemplate = overheadsFolder:FindFirstChild("AnimalOverhead")
if not animalOverheadTemplate then
return nil
end
local trappedOverhead = animalOverheadTemplate:Clone()
trappedOverhead.DisplayName.Text = "TRAPPED!"
trappedOverhead.DisplayName.TextColor3 = Color3.fromRGB(255, 100, 100)
trappedOverhead.DisplayName.TextStrokeTransparency = 0
trappedOverhead.DisplayName.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)
trappedOverhead.Generation.Visible = false
trappedOverhead.Price.Visible = false
trappedOverhead.Rarity.Visible = false
trappedOverhead.Mutation.Visible = false
local overheadAttachment = Instance.new("Attachment")
overheadAttachment.Name = "TrappedOverhead"
overheadAttachment.CFrame = CFrame.new(0, 2, 0)
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if humanoidRootPart then
overheadAttachment.Parent = humanoidRootPart
trappedOverhead.Parent = overheadAttachment
return trappedOverhead, overheadAttachment
end
return nil, nil
end
local function updateCountdown(gui, timeLeft)
if gui and gui.Parent then
gui.DisplayName.Text = string.format("TRAPPED! %ds", math.ceil(timeLeft))
end
end
local function isPlayerTrapped(player)
return trappedPlayers[player] ~= nil
end
local function trapPlayer(character, humanoid, trap)
local player = Players:GetPlayerFromCharacter(character)
if not player then return end
if isPlayerTrapped(player) then
return
end
if playerTrapDebounce[player] and tick() - playerTrapDebounce[player] < 1 then
return
end
playerTrapDebounce[player] = tick()
local originalWalkSpeed = humanoid.WalkSpeed
local originalJumpPower = humanoid.JumpPower
local originalJumpHeight = humanoid.JumpHeight
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
local originalAnchored = false
if humanoidRootPart then
originalAnchored = humanoidRootPart.Anchored
humanoidRootPart.Anchored = true
end
humanoid.WalkSpeed = 0
humanoid.JumpPower = 0
humanoid.JumpHeight = 0
local trappedGUI, attachment = createTrappedGUI(character)
trappedPlayers[player] = {
originalWalkSpeed = originalWalkSpeed,
originalJumpPower = originalJumpPower,
originalJumpHeight = originalJumpHeight,
originalAnchored = originalAnchored,
humanoidRootPart = humanoidRootPart,
gui = trappedGUI,
attachment = attachment,
startTime = tick(),
trap = trap
}
local trapSound = trap:FindFirstChild("Sound")
if trapSound then
trapSound:Play()
end
local connection
connection = RunService.Heartbeat:Connect(function()
local trapData = trappedPlayers[player]
if not trapData then
connection:Disconnect()
return
end
local timeLeft = 10 - (tick() - trapData.startTime)
if timeLeft <= 0 then
if humanoid and humanoid.Parent then
humanoid.WalkSpeed = trapData.originalWalkSpeed
humanoid.JumpPower = trapData.originalJumpPower
humanoid.JumpHeight = trapData.originalJumpHeight
end
if trapData.humanoidRootPart and trapData.humanoidRootPart.Parent then
trapData.humanoidRootPart.Anchored = trapData.originalAnchored
end
if trapData.attachment then
trapData.attachment:Destroy()
end
if trapData.trap and trapData.trap.Parent then
trapData.trap:Destroy()
end
trappedPlayers[player] = nil
connection:Disconnect()
else
updateCountdown(trapData.gui, timeLeft)
end
end)
local playerLeavingConnection
playerLeavingConnection = Players.PlayerRemoving:Connect(function(leavingPlayer)
if leavingPlayer == player then
local tp = trappedPlayers[player]
trappedPlayers[player] = nil
if tp and tp.trap and tp.trap.Parent then
tp.trap:Destroy()
end
connection:Disconnect()
playerLeavingConnection:Disconnect()
end
end)
end
Net:RemoteEvent("Trap/Place").OnServerEvent:Connect(function(player)
if not player.Character then return end
if trapDebounce[player] and tick() - trapDebounce[player] < 2 then
return
end
trapDebounce[player] = tick()
local tool = player.Character:FindFirstChildWhichIsA("Tool")
if not tool or tool.Name ~= "Trap" then return end
local handle = tool:FindFirstChild("Handle")
if not handle then return end
local humanoidRootPart = player.Character:FindFirstChild("HumanoidRootPart")
if not humanoidRootPart then return end
local trap = handle:Clone()
trap.Name = "PlacedTrap"
trap.Anchored = true
trap.CanCollide = false
tool:Destroy()
local forwardDirection = humanoidRootPart.CFrame.LookVector
local trapPosition = humanoidRootPart.Position + forwardDirection * 3
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
raycastParams.FilterDescendantsInstances = {player.Character, trap}
local raycast = workspace:Raycast(trapPosition + Vector3.new(0, 5, 0), Vector3.new(0, -100, 0), raycastParams)
local groundY = raycast and raycast.Position.Y or (trapPosition.Y - 5)
trapPosition = Vector3.new(trapPosition.X, groundY + trap.Size.Y/2, trapPosition.Z)
trap.CFrame = CFrame.new(trapPosition)
trap.Parent = workspace
Debris:AddItem(trap, TRAP_LIFETIME)
activeTraps[trap] = {
owner = player,
placed = tick()
}
local touchConnection
touchConnection = trap.Touched:Connect(function(hit)
local character, humanoid = getCharacterFromPart(hit)
if character and humanoid and character ~= player.Character then
local targetPlayer = Players:GetPlayerFromCharacter(character)
if targetPlayer and not isPlayerTrapped(targetPlayer) then
trapPlayer(character, humanoid, trap)
touchConnection:Disconnect()
activeTraps[trap] = nil
else
--print("Trap ignored - player", targetPlayer and targetPlayer.Name or "unknown", "is already trapped")
end
end
end)
trap.AncestryChanged:Connect(function()
if not trap.Parent then
activeTraps[trap] = nil
if touchConnection then
touchConnection:Disconnect()
end
end
end)
end)
Players.PlayerRemoving:Connect(function(player)
trapDebounce[player] = nil
playerTrapDebounce[player] = nil
trappedPlayers[player] = nil
for trap, data in pairs(activeTraps) do
if data.owner == player then
if trap and trap.Parent then
trap:Destroy()
end
activeTraps[trap] = nil
end
end
end) - Edit
03:12:20.479
- Edit
03:12:20.479
============================== - Edit
03:12:20.479 📜 ServerScriptService.Main.Items.Sentry - Edit
03:12:20.479 ==============================
- Edit
03:12:20.479 local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")
local Debris = game:GetService("Debris")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local sentryDebounce = {}
local playerSentryDebounce = {}
local activeSentries = {}
local sentryTargets = {}
local ragdollImmunity = {}
local SENTRY_DURATION = 59
local PLACEMENT_COUNTDOWN = 3
local DETECTION_RANGE = 50
local SHOOT_RANGE = 40
local RAGDOLL_DURATION = 3
local SHOOT_COOLDOWN = 2
local IMPULSE_FORCE = 50
local RAGDOLL_IMMUNITY_TIME = 5
local DEBUG_MODE = false
local function getSentryModel()
local models = ReplicatedStorage:FindFirstChild("Models")
if not models then return nil end
local toolsExtras = models:FindFirstChild("ToolsExtras")
if not toolsExtras then return nil end
return toolsExtras:FindFirstChild("Sentry")
end
local function getOverheadTemplate()
local overheads = ReplicatedStorage:FindFirstChild("Overheads")
if overheads then
return overheads:FindFirstChild("AnimalOverhead")
end
return nil
end
local function findCharacterAncestor(hit)
local character = hit.Parent
local humanoid = character:FindFirstChildOfClass("Humanoid")
if humanoid then
return character, humanoid
end
return nil, nil
end
local function createSentryGUI(sentry)
local overheadTemplate = getOverheadTemplate()
if not overheadTemplate then return nil end
local rotationGroup = sentry:FindFirstChild("RotationGroup")
local headPart = nil
if rotationGroup then
headPart = rotationGroup:FindFirstChild("Head")
else
headPart = sentry:FindFirstChild("Head")
end
if not headPart then return nil end
local overheadAttachment = Instance.new("Attachment")
overheadAttachment.Name = "SentryOverhead"
overheadAttachment.CFrame = CFrame.new(0, 0, 0)
overheadAttachment.Parent = headPart
local sentryOverhead = overheadTemplate:Clone()
sentryOverhead.DisplayName.Text = SENTRY_DURATION .. "s!"
sentryOverhead.DisplayName.TextColor3 = Color3.fromRGB(255, 0, 0)
sentryOverhead.DisplayName.TextStrokeTransparency = 0
sentryOverhead.DisplayName.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)
sentryOverhead.Generation.Visible = false
sentryOverhead.Price.Visible = false
sentryOverhead.Rarity.Visible = false
sentryOverhead.Mutation.Visible = false
sentryOverhead.Parent = overheadAttachment
return sentryOverhead, overheadAttachment
end
local function updateCountdown(gui, timeLeft)
if gui and gui.Parent then
gui.DisplayName.Text = math.ceil(timeLeft) .. "s!"
gui.DisplayName.TextColor3 = Color3.fromRGB(255, 0, 0)
end
end
local function sendNotification(player, message, duration)
local NotificationEvent = Net:RemoteEvent("NotificationService/Notify")
if NotificationEvent and player then
NotificationEvent:FireClient(player, message, duration or 3)
end
end
local function ragdollPlayer(character, direction)
local humanoid = character:FindFirstChildOfClass("Humanoid")
if humanoid then
local player = Players:GetPlayerFromCharacter(character)
if player then
local currentTime = tick()
if ragdollImmunity[player] and currentTime - ragdollImmunity[player] < RAGDOLL_IMMUNITY_TIME then
return
end
ragdollImmunity[player] = currentTime
end
RagdollModule.TimedRagdoll(character, RAGDOLL_DURATION)
end
end
local function createBeam(startPart, targetPosition, owner)
local startPosition = startPart.Position
local direction = (targetPosition - startPosition).Unit
local distance = (targetPosition - startPosition).Magnitude
local speed = 80
local travelTime = distance / speed
local beam = Instance.new("Part")
beam.Name = "SentryBeam"
beam.Anchored = true
beam.CanCollide = false
beam.Material = Enum.Material.Neon
beam.BrickColor = BrickColor.new("Bright red")
beam.Size = Vector3.new(0.5, 0.5, 1)
beam.CFrame = CFrame.lookAt(startPosition, targetPosition)
beam.Parent = workspace
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
local filterInstances = {workspace.CurrentCamera, beam}
if not DEBUG_MODE then
table.insert(filterInstances, owner.Character)
end
raycastParams.FilterDescendantsInstances = filterInstances
local startTime = tick()
local lastPosition = startPosition
local connection
connection = game:GetService("RunService").Heartbeat:Connect(function(dt)
local elapsed = tick() - startTime
local progress = math.clamp(elapsed / travelTime, 0, 1)
local currentPosition = startPosition:Lerp(targetPosition, progress)
beam.CFrame = CFrame.lookAt(currentPosition, currentPosition + direction)
local rayDirection = currentPosition - lastPosition
if rayDirection.Magnitude > 0 then
local raycast = workspace:Raycast(lastPosition, rayDirection, raycastParams)
if raycast then
local character = raycast.Instance.Parent
local humanoid = character and character:FindFirstChildOfClass("Humanoid")
if humanoid and (DEBUG_MODE or character ~= owner.Character) then
ragdollPlayer(character, direction)
beam:Destroy()
connection:Disconnect()
return
end
end
end
lastPosition = currentPosition
if progress >= 1 then
beam:Destroy()
connection:Disconnect()
end
end)
game:GetService("Debris"):AddItem(beam, 3)
end
local function lookAtTarget(sentry, targetPosition)
local rotationGroup = sentry:FindFirstChild("RotationGroup")
if not rotationGroup then return end
local primaryPart = rotationGroup.PrimaryPart or rotationGroup:FindFirstChild("Base")
if not primaryPart then return end
local direction = (targetPosition - primaryPart.Position).Unit
local yRotation = math.atan2(-direction.X, -direction.Z)
local currentCFrame = primaryPart.CFrame
local newCFrame = CFrame.new(currentCFrame.Position) * CFrame.Angles(0, yRotation, 0) * CFrame.Angles(math.rad(-90), 0, 0)
rotationGroup:PivotTo(newCFrame)
end
local function predictTargetPosition(target, shooterPosition, projectileSpeed)
local currentPos = target.Position
local character = target.Parent
if not character then return currentPos end
local rootPart = character:FindFirstChild("HumanoidRootPart")
if not rootPart then return currentPos end
local velocity = rootPart.AssemblyLinearVelocity
local distance = (currentPos - shooterPosition).Magnitude
local timeToHit = distance / projectileSpeed
local predictionTime = math.min(timeToHit, 0.5)
if velocity.Magnitude < 2 then
return currentPos
end
local predictedPosition = currentPos + (velocity * predictionTime)
local spread = Vector3.new(
math.random(-1, 1),
0,
math.random(-1, 1)
)
return predictedPosition + spread
end
local function shootAtTarget(sentry, target, owner, useBarrel1)
local rotationGroup = sentry:FindFirstChild("RotationGroup")
if not rotationGroup then return end
local barrel1 = rotationGroup:FindFirstChild("Barrel1", true)
local barrel2 = rotationGroup:FindFirstChild("Barrel2", true)
if barrel1 and barrel2 and target then
local shooterPosition = sentry.PrimaryPart.Position
local projectileSpeed = 80
local predictedPosition = predictTargetPosition(target, shooterPosition, projectileSpeed)
if useBarrel1 then
createBeam(barrel1, predictedPosition, owner)
else
createBeam(barrel2, predictedPosition, owner)
end
end
end
local function manageSentry(sentry, owner, sentryGUI, sentryAttachment)
local sentryData = activeSentries[sentry]
if not sentryData then return end
local lastShot = 0
local useBarrel1 = true
local lastAimPosition = nil
local connection
connection = RunService.Heartbeat:Connect(function()
if not sentry.Parent or not activeSentries[sentry] then
connection:Disconnect()
return
end
local currentTime = tick()
local timeLeft = SENTRY_DURATION - (currentTime - sentryData.startTime)
if sentryData.gui then
updateCountdown(sentryData.gui, timeLeft)
end
if timeLeft <= 0 then
if sentryData.attachment then
sentryData.attachment:Destroy()
end
sentry:Destroy()
activeSentries[sentry] = nil
connection:Disconnect()
return
end
local sentryPosition = sentry.PrimaryPart.Position
local nearestTarget = nil
local nearestDistance = math.huge
for _, player in pairs(Players:GetPlayers()) do
if (DEBUG_MODE or player ~= owner) and player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
local distance = (player.Character.HumanoidRootPart.Position - sentryPosition).Magnitude
if distance <= DETECTION_RANGE and distance < nearestDistance then
nearestTarget = player.Character.HumanoidRootPart
nearestDistance = distance
end
end
end
if nearestTarget then
local shooterPosition = sentry.PrimaryPart.Position
local predictedPos = predictTargetPosition(nearestTarget, shooterPosition, 80)
if lastAimPosition then
predictedPos = lastAimPosition:lerp(predictedPos, 0.3)
end
lastAimPosition = predictedPos
lookAtTarget(sentry, predictedPos)
if nearestDistance <= SHOOT_RANGE and currentTime - lastShot >= SHOOT_COOLDOWN then
shootAtTarget(sentry, nearestTarget, owner, useBarrel1)
useBarrel1 = not useBarrel1
lastShot = currentTime
end
else
lastAimPosition = nil
end
end)
end
Net:RemoteEvent("Sentry/Place").OnServerEvent:Connect(function(player)
if sentryDebounce[player] and tick() - sentryDebounce[player] < 2 then
return
end
sentryDebounce[player] = tick()
local character = player.Character
if not character then return end
local tool = character:FindFirstChild("All Seeing Sentry")
if not tool or tool.Name ~= "All Seeing Sentry" then return end
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if not humanoidRootPart then return end
sendNotification(player, "Sentry placed!", 2)
local sentryTemplate = getSentryModel()
if not sentryTemplate then
sendNotification(player, "Sentry model not found!", 3)
return
end
local sentry = sentryTemplate:Clone()
sentry.Name = "PlacedSentry"
local forwardDirection = humanoidRootPart.CFrame.LookVector
local sentryPosition = humanoidRootPart.Position + forwardDirection * 5
local sentrySize = sentry:GetExtentsSize()
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
raycastParams.FilterDescendantsInstances = {player.Character, sentry}
local raycastStart = Vector3.new(sentryPosition.X, sentryPosition.Y + 50, sentryPosition.Z)
local raycastDirection = Vector3.new(0, -100, 0)
local raycast = workspace:Raycast(raycastStart, raycastDirection, raycastParams)
local groundY
if raycast then
local primaryPart = sentry.PrimaryPart or sentry:FindFirstChildWhichIsA("BasePart")
if not sentry.PrimaryPart then
sentry.PrimaryPart = primaryPart
end
local minY = math.huge
for _, part in ipairs(sentry:GetDescendants()) do
if part:IsA("BasePart") then
local localY = (primaryPart.CFrame:PointToObjectSpace(part.Position)).Y - (part.Size.Y / 2)
if localY < minY then
minY = localY
end
end
end
groundY = raycast.Position.Y - minY
else
groundY = sentryPosition.Y
end
sentryPosition = Vector3.new(sentryPosition.X, groundY, sentryPosition.Z)
local playerRotation = humanoidRootPart.CFrame - humanoidRootPart.CFrame.Position
local xRotation = CFrame.Angles(math.rad(-90), 0, 0)
local sentryCFrame = CFrame.new(sentryPosition) * playerRotation * xRotation
if sentry.PrimaryPart then
sentry:PivotTo(sentryCFrame)
else
for _, part in pairs(sentry:GetChildren()) do
if part:IsA("BasePart") then
part.Anchored = true
break
end
end
end
sentry.Parent = workspace
local sentryGUI, sentryAttachment = createSentryGUI(sentry)
if not sentryGUI or not sentryAttachment then
sentry:Destroy()
return
end
activeSentries[sentry] = {
owner = player,
startTime = nil,
gui = sentryGUI,
attachment = sentryAttachment
}
task.spawn(function()
for i = PLACEMENT_COUNTDOWN, 1, -1 do
if sentryGUI and sentryGUI.Parent then
sentryGUI.DisplayName.Text = "Sentry will be placed in " .. i .. "s"
sentryGUI.DisplayName.TextColor3 = Color3.fromRGB(255, 255, 255)
sentryGUI.DisplayName.RichText = false
end
task.wait(1)
end
if activeSentries[sentry] then
activeSentries[sentry].startTime = tick()
end
manageSentry(sentry, player, sentryGUI, sentryAttachment)
end)
local backpack = player:FindFirstChild("Backpack")
if backpack then
local sentryTool = backpack:FindFirstChild("All Seeing Sentry")
if sentryTool then
sentryTool:Destroy()
end
end
local character = player.Character
if character then
local equippedTool = character:FindFirstChild("All Seeing Sentry")
if equippedTool then
equippedTool:Destroy()
end
end
end)
Players.PlayerRemoving:Connect(function(player)
sentryDebounce[player] = nil
playerSentryDebounce[player] = nil
ragdollImmunity[player] = nil
for sentry, data in pairs(activeSentries) do
if data.owner == player then
if data.attachment then
data.attachment:Destroy()
end
sentry:Destroy()
activeSentries[sentry] = nil
end
end
end) - Edit
03:12:20.479
- Edit
03:12:20.479
============================== - Edit
03:12:20.479 📜 ServerScriptService.Main.Items.CakeTrap - Edit
03:12:20.479 ==============================
- Edit
03:12:20.479 local Players = game:GetService("Players")
local Debris = game:GetService("Debris")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local RagdollModule = require(ReplicatedStorage.Packages.Ragdoll)
local Net = require(Packages.Net)
local trapDebounce = {}
local activeTraps = {}
local TRAP_LIFETIME = 120
local function getCharacterFromPart(part)
local character = part.Parent
if character and character:FindFirstChildOfClass("Humanoid") then
return character, character:FindFirstChildOfClass("Humanoid")
end
return nil, nil
end
Net:RemoteEvent("CakceTrap/Place").OnServerEvent:Connect(function(player)
if not player.Character then return end
if trapDebounce[player] and tick() - trapDebounce[player] < 2 then
return
end
trapDebounce[player] = tick()
local tool = player.Character:FindFirstChildWhichIsA("Tool")
if not tool or tool.Name ~= "Cake Trap" then return end
local handle = tool:FindFirstChild("Handle")
if not handle then return end
local humanoidRootPart = player.Character:FindFirstChild("HumanoidRootPart")
if not humanoidRootPart then return end
local trap = handle:Clone()
trap.Name = "PlacedTrap"
trap.Anchored = true
trap.CanCollide = false
tool:Destroy()
local forwardDirection = humanoidRootPart.CFrame.LookVector
local trapPosition = humanoidRootPart.Position + forwardDirection * 3
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
raycastParams.FilterDescendantsInstances = {player.Character, trap}
local raycast = workspace:Raycast(trapPosition + Vector3.new(0, 5, 0), Vector3.new(0, -100, 0), raycastParams)
local groundY = raycast and raycast.Position.Y or (trapPosition.Y - 5)
trapPosition = Vector3.new(trapPosition.X, groundY + trap.Size.Y/2, trapPosition.Z)
trap.CFrame = CFrame.new(trapPosition)
trap.Parent = workspace
Debris:AddItem(trap, TRAP_LIFETIME)
activeTraps[trap] = {
owner = player,
placed = tick()
}
local touchConnection
touchConnection = trap.Touched:Connect(function(hit)
local character, humanoid = getCharacterFromPart(hit)
if character and humanoid and character ~= player.Character then
local targetPlayer = Players:GetPlayerFromCharacter(character)
if targetPlayer then
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if humanoidRootPart then
local bodyVelocity = Instance.new("BodyVelocity")
bodyVelocity.MaxForce = Vector3.new(0, math.huge, 0)
bodyVelocity.Velocity = Vector3.new(0, 60, 0)
bodyVelocity.Parent = humanoidRootPart
Debris:AddItem(bodyVelocity, 0.3)
RagdollModule.TimedRagdoll(character, 5)
end
touchConnection:Disconnect()
activeTraps[trap] = nil
trap:Destroy()
end
end
end)
trap.AncestryChanged:Connect(function()
if not trap.Parent then
activeTraps[trap] = nil
if touchConnection then
touchConnection:Disconnect()
end
end
end)
end)
Players.PlayerRemoving:Connect(function(player)
trapDebounce[player] = nil
for trap, data in pairs(activeTraps) do
if data.owner == player then
if trap and trap.Parent then
trap:Destroy()
end
activeTraps[trap] = nil
end
end
end) - Edit
03:12:20.479
- Edit
03:12:20.479
============================== - Edit
03:12:20.479 📜 ServerScriptService.Main.Items.Tools - Edit
03:12:20.479 ==============================
- Edit
03:12:20.480 local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DataManagment = require(ServerScriptService.Services.DataManagment)
local ShopData = require(ReplicatedStorage.Datas.Shop)
local function givePlayerTools(player, Data)
task.wait(0.1)
local starterPackItems = {}
local starterPackData = ShopData[3373926350]
if starterPackData and starterPackData.Rewards and starterPackData.Rewards.Items then
for _, itemName in pairs(starterPackData.Rewards.Items) do
starterPackItems[itemName] = true
end
end
local ownsStarterPack = Data.BoughtStarterPack or false
if not ownsStarterPack and Data.Items then
local hasAllStarterItems = true
for itemName, _ in pairs(starterPackItems) do
if not Data.Items[itemName] then
hasAllStarterItems = false
break
end
end
ownsStarterPack = hasAllStarterItems
end
if Data.Inventory then
for itemName, owned in pairs(Data.Inventory) do
if owned then
local tool = ReplicatedStorage.Items:FindFirstChild(itemName)
if tool then
tool:Clone().Parent = player.Backpack
end
end
end
end
if ownsStarterPack then
for itemName, _ in pairs(starterPackItems) do
if not (Data.Inventory and Data.Inventory[itemName]) then
local tool = ReplicatedStorage.Items:FindFirstChild(itemName)
if tool then
tool:Clone().Parent = player.Backpack
end
end
end
end
end
local function setupPlayerTools(player)
if not DataManagment.isDataReady(player) then
local success = DataManagment.waitForData(player, 30)
if not success then
warn("Failed to get data for player: " .. player.Name)
return
end
end
local Data = DataManagment.GetDataMan(player)
if not Data then return end
if player.Character then
givePlayerTools(player, Data)
end
player.CharacterAdded:Connect(function(character)
givePlayerTools(player, Data)
end)
end
for _, player in pairs(Players:GetPlayers()) do
setupPlayerTools(player)
end
Players.PlayerAdded:Connect(setupPlayerTools)
- Edit
03:12:20.480
- Edit
03:12:20.480
============================== - Edit
03:12:20.480 📜 ServerScriptService.Main.Player.ChatTags - Edit
03:12:20.480 ==============================
- Edit
03:12:20.480 local service = game:GetService("MarketplaceService")
local ServerScriptService = game:GetService("ServerScriptService")
local Configuration = require(ServerScriptService.Services.CmdrService.Configuration)
local chatServiceRunner = ServerScriptService:WaitForChild("ChatServiceRunner", math.huge)
local chatService = require(chatServiceRunner:WaitForChild("ChatService"))
local tags = {
[0] = {TagText = "VIP", TagColor = Color3.fromRGB(255, 255, 0)},
}
chatService.SpeakerAdded:Connect(function(playerName)
local speaker = chatService:GetSpeaker(playerName)
local player = game.Players[playerName]
local users = Configuration.GetAuthorizedUsers()
warn(users)
speaker:SetExtraData("Tags",{tags[0]})
end)
- Edit
03:12:20.480
- Edit
03:12:20.480
============================== - Edit
03:12:20.480 📜 ServerScriptService.Main.Player.CoinShop - Edit
03:12:20.480 ==============================
- Edit
03:12:20.480 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local Players = game:GetService("Players")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Data = ReplicatedStorage:WaitForChild("Datas")
local DataManagment = require(ServerScriptService.Services.DataManagment)
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
local ShopItems = require(ReplicatedStorage.Datas.ShopItems)
local Remotefunction = Net:RemoteFunction("CoinsShopService/RequestBuy")
local ToggleAutoBuyRemote = Net:RemoteFunction("CoinsShopService/ToggleAutoBuy")
local SessionInventories = {}
local PurchaseCooldown = {}
local COOLDOWN_TIME = 1
local function ProcessAutoBuy(player)
local Data = DataManagment.GetDataMan(player)
if not Data then
return
end
local autoBuySettings = Data.AutoBuySettings or {}
for itemName, isEnabled in pairs(autoBuySettings) do
if isEnabled then
local itemData = ShopItems[itemName]
if itemData then
local canBuy = true
if itemData.IsEnabled and type(itemData.IsEnabled) == "function" then
local success, isItemEnabled = pcall(itemData.IsEnabled)
if not success or not isItemEnabled then
canBuy = false
end
end
if canBuy and itemData.RebirthRequired then
local playerRebirths = Data.Rebirths or 0
if playerRebirths < itemData.RebirthRequired then
canBuy = false
end
end
if canBuy and (type(Data.Coins) ~= "number" or Data.Coins < itemData.Price) then
canBuy = false
end
local itemTool = ReplicatedStorage.Items:FindFirstChild(itemName)
if canBuy and not itemTool then
canBuy = false
end
if canBuy then
local currentQuantity = 0
for _, tool in pairs(player.Backpack:GetChildren()) do
if tool:IsA("Tool") and tool.Name == itemName then
currentQuantity = currentQuantity + 1
end
end
if player.Character then
for _, tool in pairs(player.Character:GetChildren()) do
if tool:IsA("Tool") and tool.Name == itemName then
currentQuantity = currentQuantity + 1
end
end
end
local maxQuantity = 1
if itemName == "Trap" then
maxQuantity = 5
end
if currentQuantity >= maxQuantity then
canBuy = false
end
end
if canBuy then
Data.Coins = Data.Coins - itemData.Price
local playerSync = Synchronizer:Get(player)
if playerSync then
playerSync:Set("Coins", Data.Coins)
end
if not SessionInventories[player.UserId] then
SessionInventories[player.UserId] = {}
end
table.insert(SessionInventories[player.UserId], itemName)
local ToolClone = itemTool:Clone()
ToolClone.Parent = player.Backpack
if itemName == "Trap" then
local currentCount = player:GetAttribute("TrapCount") or 0
currentCount = currentCount + 1
player:SetAttribute("TrapCount", currentCount)
end
end
end
end
end
end
local function RestoreInventory(player)
local sessionInventory = SessionInventories[player.UserId]
if not sessionInventory then
return
end
for _, itemName in sessionInventory do
local item = ReplicatedStorage.Items:FindFirstChild(itemName)
if item then
local ToolClone = item:Clone()
ToolClone.Parent = player.Backpack
end
end
end
ToggleAutoBuyRemote.OnServerInvoke = function(player, itemName, enabled)
local Data = DataManagment.GetDataMan(player)
if not Data then
return false, "Failed to load player data"
end
if type(itemName) ~= "string" or itemName == "" then
return false, "Invalid item specified"
end
local itemData = ShopItems[itemName]
if not itemData then
return false, "Item not found in shop"
end
if not Data.AutoBuySettings then
Data.AutoBuySettings = {}
end
if enabled == nil then
Data.AutoBuySettings[itemName] = not Data.AutoBuySettings[itemName]
else
Data.AutoBuySettings[itemName] = enabled
end
local playerSync = Synchronizer:Get(player)
if playerSync then
local autoBuyTable = playerSync:Get("AutoBuy")
if not autoBuyTable then
playerSync:Set("AutoBuy", {})
end
playerSync:Set("AutoBuy." .. itemName, Data.AutoBuySettings[itemName])
end
if Data.AutoBuySettings[itemName] then
ProcessAutoBuy(player)
end
return true, "Auto-buy setting updated"
end
Remotefunction.OnServerInvoke = function(player, itemName)
local now = tick()
local lastTime = PurchaseCooldown[player.UserId] or 0
if now - lastTime < COOLDOWN_TIME then
return false, "Hold on! You need to wait a bit before doing that again."
end
PurchaseCooldown[player.UserId] = now
local Data = DataManagment.GetDataMan(player)
if not Data then
return false, "Failed to load player data"
end
if type(itemName) ~= "string" or itemName == "" then
return false, "Invalid item specified"
end
local itemData = ShopItems[itemName]
if not itemData then
return false, "Item not found in shop"
end
if type(itemData.Price) ~= "number" or itemData.Price <= 0 then
return false, "Invalid item price"
end
if itemData.IsEnabled and type(itemData.IsEnabled) == "function" then
local success, isEnabled = pcall(itemData.IsEnabled)
if not success or not isEnabled then
return false, "Item is currently disabled"
end
end
if itemData.RebirthRequired then
local playerRebirths = Data.Rebirths or 0
if playerRebirths < itemData.RebirthRequired then
return false, "Rebirth " .. itemData.RebirthRequired .. " required"
end
end
if type(Data.Coins) ~= "number" or Data.Coins < itemData.Price then
return false, "Purchase failed! You don't have enough Coins!"
end
local itemTool = ReplicatedStorage.Items:FindFirstChild(itemName)
if not itemTool then
return false, "Item tool not found"
end
local currentQuantity = 0
for _, tool in pairs(player.Backpack:GetChildren()) do
if tool:IsA("Tool") and tool.Name == itemName then
currentQuantity = currentQuantity + 1
end
end
if player.Character then
for _, tool in pairs(player.Character:GetChildren()) do
if tool:IsA("Tool") and tool.Name == itemName then
currentQuantity = currentQuantity + 1
end
end
end
local maxQuantity = 1
if itemName == "Trap" then
maxQuantity = 5
end
if currentQuantity >= maxQuantity then
if maxQuantity == 1 then
return false, string.format("Purchase failed! You already own this item: %s.", itemName)
else
return false, "You already own the maximum amount of this item! (" .. maxQuantity .. " max)"
end
end
Data.Coins = Data.Coins - itemData.Price
local playerSync = Synchronizer:Get(player)
if playerSync then
playerSync:Set("Coins", Data.Coins)
end
if not SessionInventories[player.UserId] then
SessionInventories[player.UserId] = {}
end
table.insert(SessionInventories[player.UserId], itemName)
local ToolClone = itemTool:Clone()
if itemName == "Trap" then
local currentCount = player:GetAttribute("TrapCount") or 0
currentCount = currentCount + 1
player:SetAttribute("TrapCount", currentCount)
end
ToolClone.Parent = player.Backpack
return true, string.format("Purchase successful! You bought %s.", itemName)
end
Players.PlayerAdded:Connect(function(player)
SessionInventories[player.UserId] = {}
task.spawn(function()
task.wait(5)
local Data = DataManagment.GetDataMan(player)
if Data and Data.AutoBuySettings then
local playerSync = Synchronizer:Get(player)
if playerSync then
local autoBuyTable = playerSync:Get("AutoBuy")
if not autoBuyTable then
playerSync:Set("AutoBuy", {})
end
for itemName, isEnabled in pairs(Data.AutoBuySettings) do
playerSync:Set("AutoBuy." .. itemName, isEnabled)
end
end
end
if not table.find(SessionInventories[player.UserId], "Tung Bat") then
table.insert(SessionInventories[player.UserId], "Tung Bat")
local Bat = ReplicatedStorage.Items["Tung Bat"]:Clone()
Bat.Parent = player.Backpack
end
RestoreInventory(player)
local backpack = player:WaitForChild("Backpack")
local tungBatTool = backpack:FindFirstChild("Tung Bat")
if not tungBatTool then
backpack.ChildAdded:Wait()
repeat
tungBatTool = backpack:FindFirstChild("Tung Bat")
task.wait()
until tungBatTool
end
ProcessAutoBuy(player)
end)
player.CharacterAdded:Connect(function()
task.wait(2)
RestoreInventory(player)
end)
end)
Players.PlayerRemoving:Connect(function(player)
SessionInventories[player.UserId] = nil
end)
task.spawn(function()
for _, player in pairs(Players:GetPlayers()) do
if player and player.Parent then
local Data = DataManagment.GetDataMan(player)
if Data and Data.AutoBuySettings then
local playerSync = Synchronizer:Get(player)
if playerSync then
local autoBuyTable = playerSync:Get("AutoBuy")
if not autoBuyTable then
playerSync:Set("AutoBuy", {})
end
for itemName, isEnabled in pairs(Data.AutoBuySettings) do
playerSync:Set("AutoBuy." .. itemName, isEnabled)
end
end
end
ProcessAutoBuy(player)
end
end
end) - Edit
03:12:20.480
- Edit
03:12:20.480
============================== - Edit
03:12:20.480 📜 ServerScriptService.Main.Server.Anti-Duplicated - Edit
03:12:20.480 ==============================
- Edit
03:12:20.480 local Players = game:GetService("Players")
-- Tools that are allowed to have duplicates
local ExcludedTools = {
["Trap"] = true,
["Cake Trap"] = true,
}
-- Function to check and remove duplicate tools
local function RemoveDuplicateTools(player)
local backpack = player:FindFirstChild("Backpack")
if not backpack then return end
local toolNames = {}
for _, tool in ipairs(backpack:GetChildren()) do
if tool:IsA("Tool") then
if not ExcludedTools[tool.Name] then
if toolNames[tool.Name] then
-- Already exists, so remove this duplicate
tool:Destroy()
else
toolNames[tool.Name] = true
end
end
end
end
end
-- Check every 0.01s for each player
task.spawn(function()
while true do
for _, player in ipairs(Players:GetPlayers()) do
RemoveDuplicateTools(player)
end
task.wait(0.01)
end
end)
- Edit
03:12:20.480
- Edit
03:12:20.480
============================== - Edit
03:12:20.481 📜 ServerScriptService.Main.Server.ServicesManager - Edit
03:12:20.481 ==============================
- Edit
03:12:20.481 local Services = game:GetService("ServerScriptService").Services
local ServicesList = {
Road = Services.RoadAnimalService,
LikeService = Services.LikeService,
EventService = Services.EventService,
SoftShutdownService = Services.SoftShutdownService,
require(Services.AdminPanelService)
}
local Module = require(ServicesList.Road)
local RoadAnimalService = Module.new()
RoadAnimalService:Start()
_G.RoadAnimalService = RoadAnimalService
local LikeService = require(ServicesList.LikeService)
LikeService:Start()
local EventService = require(ServicesList.EventService)
_G.EventService = EventService.new()
local SoftShutdownServiceModule = require(ServicesList.SoftShutdownService)
local SoftShutdownService = SoftShutdownServiceModule.new()
SoftShutdownService:Start() - Edit
03:12:20.481
- Edit
03:12:20.481
============================== - Edit
03:12:20.481 📜 ServerScriptService.Cmdr - Edit
03:12:20.481 ==============================
- Edit
03:12:20.481 local RunService = game:GetService("RunService")
local Util = require(script.Shared:WaitForChild("Util"))
if RunService:IsServer() == false then
error("Cmdr server module is somehow running on a client!")
end
local Cmdr do
Cmdr = setmetatable({
ReplicatedRoot = nil;
RemoteFunction = nil;
RemoteEvent = nil;
Util = Util;
DefaultCommandsFolder = script.BuiltInCommands;
}, {
__index = function (self, k)
local r = self.Registry[k]
if r and type(r) == "function" then
return function (_, ...)
return r(self.Registry, ...)
end
end
end
})
Cmdr.Registry = require(script.Shared.Registry)(Cmdr)
Cmdr.Dispatcher = require(script.Shared.Dispatcher)(Cmdr)
require(script.Initialize)(Cmdr)
end
-- Handle command invocations from the clients.
Cmdr.RemoteFunction.OnServerInvoke = function (player, text, options)
if #text > 100_000 then
return "Input too long"
end
return Cmdr.Dispatcher:EvaluateAndRun(text, player, options)
end
return Cmdr - Edit
03:12:20.481
- Edit
03:12:20.481
============================== - Edit
03:12:20.481 📜 ServerScriptService.Cmdr.BuiltInCommands.Admin.respawn - Edit
03:12:20.481 ==============================
- Edit
03:12:20.481
return {
Name = "respawn";
Description = "Respawns a player or a group of players.";
Group = "CustomAdmin";
AutoExec = {
"alias \"refresh|Respawns the player and returns them to their previous location.\" var= .refresh_pos ${position $1{player|Player}} && respawn $1 && tp $1 @${{var .refresh_pos}}"
},
Args = {
{
Type = "stfing";
Name = "targets";
Description = "The players to respawn."
}
}
}
- Edit
03:12:20.481
- Edit
03:12:20.482
============================== - Edit
03:12:20.482 📜 ServerScriptService.Cmdr.BuiltInCommands.Admin.respawnServer - Edit
03:12:20.482 ==============================
- Edit
03:12:20.482 return function(_, players)
for _, player in pairs(players) do
if player.Character then
player:LoadCharacter()
end
end
return ("Respawned %d players."):format(#players)
end
- Edit
03:12:20.482
- Edit
03:12:20.482
============================== - Edit
03:12:20.482 📜 ServerScriptService.Cmdr.BuiltInCommands.Debug.blink - Edit
03:12:20.482 ==============================
- Edit
03:12:20.482 return {
Name = "blink";
Aliases = {"b"};
Description = "Teleports you to where your mouse is hovering.";
Group = "DefaultDebug";
Args = {};
ClientRun = function(context)
-- We implement this here because player position is owned by the client.
-- No reason to bother the server for this!
local mouse = context.Executor:GetMouse()
local character = context.Executor.Character
if not character then
return "You don't have a character."
end
character:MoveTo(mouse.Hit.p)
return "Blinked!"
end
} - Edit
03:12:20.482
- Edit
03:12:20.482
============================== - Edit
03:12:20.482 📜 ServerScriptService.Cmdr.BuiltInCommands.Debug.fetch - Edit
03:12:20.482 ==============================
- Edit
03:12:20.482 return {
Name = "fetch";
Aliases = {};
Description = "Fetch a value from the Internet";
Group = "DefaultDebug";
Args = {
{
Type = "url";
Name = "URL";
Description = "The URL to fetch.";
}
};
} - Edit
03:12:20.482
- Edit
03:12:20.482
============================== - Edit
03:12:20.482 📜 ServerScriptService.Cmdr.BuiltInCommands.Debug.fetchServer - Edit
03:12:20.482 ==============================
- Edit
03:12:20.483 local HttpService = game:GetService("HttpService")
return function (_, url)
return HttpService:GetAsync(url)
end - Edit
03:12:20.483
- Edit
03:12:20.483
============================== - Edit
03:12:20.483 📜 ServerScriptService.Cmdr.BuiltInCommands.Debug.getPlayerPlaceInstance - Edit
03:12:20.483 ==============================
- Edit
03:12:20.483 return {
Name = "get-player-place-instance";
Aliases = {};
Description = "Returns the target player's Place ID and the JobId separated by a space. Returns 0 if the player is offline or something else goes wrong.";
Group = "DefaultDebug";
Args = {
{
Type = "playerId";
Name = "Player";
Description = "Get the place instance of this player";
},
function(context)
return {
Type = context.Cmdr.Util.MakeEnumType("PlaceInstance Format", {"PlaceIdJobId", "PlaceId", "JobId"}),
Name = "Format";
Description = "What data to return. PlaceIdJobId returns both separated by a space.";
Default = "PlaceIdJobId";
}
end
};
} - Edit
03:12:20.483
- Edit
03:12:20.483
============================== - Edit
03:12:20.483 📜 ServerScriptService.Cmdr.BuiltInCommands.Debug.getPlayerPlaceInstanceServer - Edit
03:12:20.483 ==============================
- Edit
03:12:20.483 local TeleportService = game:GetService("TeleportService")
return function (_, playerId, format)
format = format or "PlaceIdJobId"
local ok, _, errorText, placeId, jobId = pcall(function()
return TeleportService:GetPlayerPlaceInstanceAsync(playerId)
end)
if not ok or (errorText and #errorText > 0) then
if format == "PlaceIdJobId" then
return "0" .. " -"
elseif format == "PlaceId" then
return "0"
elseif format == "JobId" then
return "-"
end
end
if format == "PlaceIdJobId" then
return placeId .. " " .. jobId
elseif format == "PlaceId" then
return tostring(placeId)
elseif format == "JobId" then
return tostring(jobId)
end
end - Edit
03:12:20.483
- Edit
03:12:20.483
============================== - Edit
03:12:20.483 📜 ServerScriptService.Cmdr.BuiltInCommands.Debug.position - Edit
03:12:20.483 ==============================
- Edit
03:12:20.483 local Players = game:GetService("Players")
return {
Name = "position";
Aliases = {"pos"};
Description = "Returns Vector3 position of you or other players. Empty string is the player has no character.";
Group = "DefaultDebug";
Args = {
{
Type = "player";
Name = "Player";
Description = "The player to report the position of. Omit for your own position.";
Default = Players.LocalPlayer;
}
};
ClientRun = function(_, player)
local character = player.Character
if not character or not character:FindFirstChild("HumanoidRootPart") then
return ""
end
return tostring(character.HumanoidRootPart.Position):gsub("%s", "")
end
} - Edit
03:12:20.483
- Edit
03:12:20.483
============================== - Edit
03:12:20.484 📜 ServerScriptService.Cmdr.BuiltInCommands.Debug.thru - Edit
03:12:20.484 ==============================
- Edit
03:12:20.484 return {
Name = "thru";
Aliases = {"t", "through"};
Description = "Teleports you through whatever your mouse is hovering over, placing you equidistantly from the wall.";
Group = "DefaultDebug";
Args = {
{
Type = "number";
Name = "Extra distance";
Description = "Go through the wall an additional X studs.";
Default = 0;
}
};
ClientRun = function(context, extra)
-- We implement this here because player position is owned by the client.
-- No reason to bother the server for this!
local mouse = context.Executor:GetMouse()
local character = context.Executor.Character
if not character or not character:FindFirstChild("HumanoidRootPart") then
return "You don't have a character."
end
local pos = character.HumanoidRootPart.Position
local diff = (mouse.Hit.p - pos)
character:MoveTo((diff * 2) + (diff.unit * extra) + pos)
return "Blinked!"
end
} - Edit
03:12:20.484
- Edit
03:12:20.484
============================== - Edit
03:12:20.484 📜 ServerScriptService.Cmdr.BuiltInCommands.Debug.uptime - Edit
03:12:20.484 ==============================
- Edit
03:12:20.484 return {
Name = "uptime";
Aliases = {};
Description = "Returns the amount of time the server has been running.";
Group = "DefaultDebug";
Args = {};
} - Edit
03:12:20.484
- Edit
03:12:20.484
============================== - Edit
03:12:20.484 📜 ServerScriptService.Cmdr.BuiltInCommands.Debug.uptimeServer - Edit
03:12:20.484 ==============================
- Edit
03:12:20.484 local startTime = os.time()
return function ()
local uptime = os.time() - startTime
return ("%dd %dh %dm %ds"):format(
math.floor(uptime / (60 * 60 * 24)),
math.floor(uptime / (60 * 60)) % 24,
math.floor(uptime / 60) % 60,
math.floor(uptime) % 60
)
end - Edit
03:12:20.484
- Edit
03:12:20.484
============================== - Edit
03:12:20.484 📜 ServerScriptService.Cmdr.BuiltInCommands.Debug.version - Edit
03:12:20.484 ==============================
- Edit
03:12:20.484 local version = "v1.12.0"
return {
Name = "version",
Args = {},
Description = "Shows the current version of Cmdr",
Group = "DefaultDebug",
Run = function()
return ("Cmdr Version %s"):format(version)
end,
}
- Edit
03:12:20.484
- Edit
03:12:20.485
============================== - Edit
03:12:20.485 📜 ServerScriptService.Cmdr.BuiltInCommands.Utility.alias - Edit
03:12:20.485 ==============================
- Edit
03:12:20.485 return {
Name = "alias";
Aliases = {};
Description = "Creates a new, single command out of a command and given arguments.";
Group = "DefaultUtil";
Args = {
{
Type = "string";
Name = "Alias name";
Description = "The key or input type you'd like to bind the command to."
},
{
Type = "string";
Name = "Command string";
Description = "The command text you want to run. Separate multiple commands with \"&&\". Accept arguments with $1, $2, $3, etc."
},
};
ClientRun = function(context, name, commandString)
context.Cmdr.Registry:RegisterCommandObject(
context.Cmdr.Util.MakeAliasCommand(name, commandString),
true
)
return ("Created alias %q"):format(name)
end
} - Edit
03:12:20.485
- Edit
03:12:20.485
============================== - Edit
03:12:20.485 📜 ServerScriptService.Cmdr.BuiltInCommands.Utility.bind - Edit
03:12:20.485 ==============================
- Edit
03:12:20.485 local UserInputService = game:GetService("UserInputService")
return {
Name = "bind";
Aliases = {};
Description = "Binds a command string to a key or mouse input.";
Group = "DefaultUtil";
Args = {
{
Type = "userInput ! bindableResource @ player";
Name = "Input";
Description = "The key or input type you'd like to bind the command to."
},
{
Type = "command";
Name = "Command";
Description = "The command you want to run on this input"
},
{
Type = "string";
Name = "Arguments";
Description = "The arguments for the command";
Default = "";
}
};
ClientRun = function(context, bind, command, arguments)
local binds = context:GetStore("CMDR_Binds")
command = command .. " " .. arguments
if binds[bind] then
binds[bind]:Disconnect()
end
local bindType = context:GetArgument(1).Type.Name
if bindType == "userInput" then
binds[bind] = UserInputService.InputBegan:Connect(function(input, gameProcessed)
if gameProcessed then
return
end
if input.UserInputType == bind or input.KeyCode == bind then
context:Reply(context.Dispatcher:EvaluateAndRun(context.Cmdr.Util.RunEmbeddedCommands(context.Dispatcher, command)))
end
end)
elseif bindType == "bindableResource" then
return "Unimplemented..."
elseif bindType == "player" then
binds[bind] = bind.Chatted:Connect(function(message)
local args = { message }
local chatCommand = context.Cmdr.Util.RunEmbeddedCommands(context.Dispatcher, context.Cmdr.Util.SubstituteArgs(command, args))
context:Reply(("%s $ %s : %s"):format(
bind.Name,
chatCommand,
context.Dispatcher:EvaluateAndRun(chatCommand)
), Color3.fromRGB(244, 92, 66))
end)
end
return "Bound command to input."
end
} - Edit
03:12:20.485
- Edit
03:12:20.485
============================== - Edit
03:12:20.485 📜 ServerScriptService.Cmdr.BuiltInCommands.Utility.clear - Edit
03:12:20.485 ==============================
- Edit
03:12:20.485 local Players = game:GetService("Players")
return {
Name = "clear",
Aliases = {},
Description = "Clear all lines above the entry line of the Cmdr window.",
Group = "DefaultUtil",
Args = {},
ClientRun = function()
local player = Players.LocalPlayer
local gui = player:WaitForChild("PlayerGui"):WaitForChild("Cmdr")
local frame = gui:WaitForChild("Frame")
if gui and frame then
for _, child in pairs(frame:GetChildren()) do
if child.Name == "Line" and child:IsA("TextBox") then
child:Destroy()
end
end
end
return ""
end
}
- Edit
03:12:20.485
- Edit
03:12:20.485
============================== - Edit
03:12:20.485 📜 ServerScriptService.Cmdr.BuiltInCommands.Utility.convertTimestamp - Edit
03:12:20.486 ==============================
- Edit
03:12:20.486 return {
Name = "convertTimestamp";
Aliases = { "date" },
Description = "Convert a timestamp to a human-readable format.";
Group = "DefaultUtil";
Args = {
{
Type = "number";
Name = "timestamp";
Description = "A numerical representation of a specific moment in time.";
Optional = true
}
};
ClientRun = function(_, timestamp)
timestamp = timestamp or os.time()
return `{os.date("%x", timestamp)} {os.date("%X", timestamp)}`
end
}
- Edit
03:12:20.486
- Edit
03:12:20.486
============================== - Edit
03:12:20.486 📜 ServerScriptService.Cmdr.BuiltInCommands.Utility.echo - Edit
03:12:20.486 ==============================
- Edit
03:12:20.486 return {
Name = "echo";
Aliases = {"="};
Description = "Echoes your text back to you.";
Group = "DefaultUtil";
Args = {
{
Type = "string";
Name = "Text";
Description = "The text."
},
};
Run = function(_, text)
return text
end
} - Edit
03:12:20.486
- Edit
03:12:20.486
============================== - Edit
03:12:20.486 📜 ServerScriptService.Cmdr.BuiltInCommands.Utility.edit - Edit
03:12:20.486 ==============================
- Edit
03:12:20.486 local Players = game:GetService("Players")
local TEXT_BOX_PROPERTIES = {
AnchorPoint = Vector2.new(0.5, 0.5),
BackgroundColor3 = Color3.fromRGB(17, 17, 17),
BackgroundTransparency = 0.05,
BorderColor3 = Color3.fromRGB(17, 17, 17),
BorderSizePixel = 20,
ClearTextOnFocus = false,
MultiLine = true,
Position = UDim2.new(0.5, 0, 0.5, 0),
Size = UDim2.new(0.5, 0, 0.4, 0),
Font = Enum.Font.Code,
TextColor3 = Color3.fromRGB(241, 241, 241),
TextWrapped = true,
TextSize = 18,
TextXAlignment = "Left",
TextYAlignment = "Top",
AutoLocalize = false,
PlaceholderText = "Right click to exit",
}
local lock
return {
Name = "edit";
Aliases = {};
Description = "Edit text in a TextBox";
Group = "DefaultUtil";
Args = {
{
Type = "string";
Name = "Input text";
Description = "The text you wish to edit";
Default = "";
},
{
Type = "string";
Name = "Delimiter";
Description = "The character that separates each line";
Default = ",";
}
};
ClientRun = function(context, text, delimeter)
lock = lock or context.Cmdr.Util.Mutex()
local unlock = lock()
context:Reply("Right-click on the text area to exit.", Color3.fromRGB(158, 158, 158))
local screenGui = Instance.new("ScreenGui")
screenGui.Name = "CmdrEditBox"
screenGui.ResetOnSpawn = false
local textBox = Instance.new("TextBox")
for key, value in pairs(TEXT_BOX_PROPERTIES) do
textBox[key] = value
end
textBox.Text = text:gsub(delimeter, "\n")
textBox.Parent = screenGui
screenGui.Parent = Players.LocalPlayer:WaitForChild("PlayerGui")
local thread = coroutine.running()
textBox.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton2 then
coroutine.resume(thread, textBox.Text:gsub("\n", delimeter))
screenGui:Destroy()
unlock()
end
end)
return coroutine.yield()
end
} - Edit
03:12:20.486
- Edit
03:12:20.486
============================== - Edit
03:12:20.486 📜 ServerScriptService.Cmdr.BuiltInCommands.Utility.history - Edit
03:12:20.486 ==============================
- Edit
03:12:20.486 return {
Name = "history";
Aliases = {};
AutoExec = {
"alias \"!|Displays previous command from history.\" run ${history $1{number|Line Number}}";
"alias \"^|Runs the previous command, replacing all occurrences of A with B.\" run ${run replace ${history -1} $1{string|A} $2{string|B}}";
"alias \"!!|Reruns the last command.\" ! -1";
};
Description = "Displays previous commands from history.";
Group = "DefaultUtil";
Args = {
{
Type = "integer";
Name = "Line Number";
Description = "Command line number (can be negative to go from end)"
},
};
ClientRun = function(context, line)
local history = context.Dispatcher:GetHistory()
if line <= 0 then
line = #history + line
end
return history[line] or ""
end
} - Edit
03:12:20.486
- Edit
03:12:20.487
============================== - Edit
03:12:20.487 📜 ServerScriptService.Cmdr.BuiltInCommands.Utility.hover - Edit
03:12:20.487 ==============================
- Edit
03:12:20.487 local Players = game:GetService("Players")
return {
Name = "hover";
Description = "Returns the name of the player you are hovering over.";
Group = "DefaultUtil";
Args = {};
ClientRun = function()
local mouse = Players.LocalPlayer:GetMouse()
local target = mouse.Target
if not target then
return ""
end
local p = Players:GetPlayerFromCharacter(target:FindFirstAncestorOfClass("Model"))
return p and p.Name or ""
end
} - Edit
03:12:20.487
- Edit
03:12:20.487
============================== - Edit
03:12:20.487 📜 ServerScriptService.Cmdr.BuiltInCommands.Utility.jsonArrayDecode - Edit
03:12:20.487 ==============================
- Edit
03:12:20.487 return {
Name = "json-array-decode";
Aliases = {};
Description = "Decodes a JSON Array into a comma-separated list";
Group = "DefaultUtil";
Args = {
{
Type = "json";
Name = "JSON";
Description = "The JSON array."
},
};
ClientRun = function(_, value)
if type(value) ~= "table" then
value = { value }
end
return table.concat(value, ",")
end
}
- Edit
03:12:20.487
- Edit
03:12:20.487
============================== - Edit
03:12:20.487 📜 ServerScriptService.Cmdr.BuiltInCommands.Utility.jsonArrayEncode - Edit
03:12:20.487 ==============================
- Edit
03:12:20.487 local HttpService = game:GetService("HttpService")
return {
Name = "json-array-encode";
Aliases = {};
Description = "Encodes a comma-separated list into a JSON array";
Group = "DefaultUtil";
Args = {
{
Type = "string";
Name = "CSV";
Description = "The comma-separated list"
},
};
Run = function(_, text)
return HttpService:JSONEncode(text:split(","))
end
} - Edit
03:12:20.487
- Edit
03:12:20.487
============================== - Edit
03:12:20.487 📜 ServerScriptService.Cmdr.BuiltInCommands.Utility.len - Edit
03:12:20.487 ==============================
- Edit
03:12:20.488 return {
Name = "len";
Aliases = {};
Description = "Returns the length of a comma-separated list";
Group = "DefaultUtil";
Args = {
{
Type = "string";
Name = "CSV";
Description = "The comma-separated list"
}
};
Run = function(_, list)
return #(list:split(","))
end
} - Edit
03:12:20.488
- Edit
03:12:20.488
============================== - Edit
03:12:20.488 📜 ServerScriptService.Cmdr.BuiltInCommands.Utility.math - Edit
03:12:20.488 ==============================
- Edit
03:12:20.488 return {
Name = "math";
Aliases = {};
Description = "Perform a math operation on 2 values.";
Group = "DefaultUtil";
AutoExec = {
"alias \"+|Perform an addition.\" math + $1{number|Number} $2{number|Number}";
"alias \"-|Perform a subtraction.\" math - $1{number|Number} $2{number|Number}";
"alias \"*|Perform a multiplication.\" math * $1{number|Number} $2{number|Number}";
"alias \"/|Perform a division.\" math / $1{number|Number} $2{number|Number}";
"alias \"**|Perform an exponentiation.\" math ** $1{number|Number} $2{number|Number}";
"alias \"%|Perform a modulus.\" math % $1{number|Number} $2{number|Number}";
};
Args = {
{
Type = "mathOperator";
Name = "Operation";
Description = "A math operation."
};
{
Type = "number";
Name = "Value";
Description = "A number value."
};
{
Type = "number";
Name = "Value";
Description = "A number value."
}
};
ClientRun = function(_, operation, a, b)
return operation.Perform(a, b)
end
}
- Edit
03:12:20.488
- Edit
03:12:20.488
============================== - Edit
03:12:20.488 📜 ServerScriptService.Cmdr.BuiltInCommands.Utility.pick - Edit
03:12:20.488 ==============================
- Edit
03:12:20.488 return {
Name = "pick";
Aliases = {};
Description = "Picks a value out of a comma-separated list.";
Group = "DefaultUtil";
Args = {
{
Type = "integer";
Name = "Index to pick";
Description = "The index of the item you want to pick";
},
{
Type = "string";
Name = "CSV";
Description = "The comma-separated list"
}
};
Run = function(_, index, list)
return list:split(",")[index] or ""
end
} - Edit
03:12:20.488
- Edit
03:12:20.488
============================== - Edit
03:12:20.488 📜 ServerScriptService.Cmdr.BuiltInCommands.Utility.rand - Edit
03:12:20.488 ==============================
- Edit
03:12:20.488 return {
Name = "rand";
Aliases = {};
Description = "Returns a random number between min and max";
Group = "DefaultUtil";
Args = {
{
Type = "integer";
Name = "First number";
Description = "If second number is nil, random number is between 1 and this value. If second number is provided, number is between this number and the second number."
},
{
Type = "integer";
Name = "Second number";
Description = "The upper bound.";
Optional = true;
}
};
Run = function(_, min, max)
return tostring(max and math.random(min, max) or math.random(min))
end
} - Edit
03:12:20.489
- Edit
03:12:20.489
============================== - Edit
03:12:20.489 📜 ServerScriptService.Cmdr.BuiltInCommands.Utility.replace - Edit
03:12:20.489 ==============================
- Edit
03:12:20.489 return {
Name = "replace";
Aliases = {"gsub", "//"};
Description = "Replaces text A with text B";
Group = "DefaultUtil";
AutoExec = {
"alias \"map|Maps a CSV into another CSV\" replace $1{string|CSV} ([^,]+) \"$2{string|mapped value|Use %1 to insert the element}\"",
"alias \"join|Joins a CSV with a specified delimiter\" replace $1{string|CSV} , $2{string|Delimiter}"
},
Args = {
{
Type = "string";
Name = "Haystack";
Description = "The source string upon which to perform replacement."
},
{
Type = "string";
Name = "Needle";
Description = "The string pattern search for."
},
{
Type = "string";
Name = "Replacement";
Description = "The string to replace matches (%1 to insert matches).";
Default = "";
},
};
Run = function(_, haystack, needle, replacement)
return haystack:gsub(needle, replacement)
end
} - Edit
03:12:20.489
- Edit
03:12:20.489
============================== - Edit
03:12:20.489 📜 ServerScriptService.Cmdr.BuiltInCommands.Utility.resolve - Edit
03:12:20.489 ==============================
- Edit
03:12:20.489 return {
Name = "resolve";
Aliases = {};
Description = "Resolves Argument Value Operators into lists. E.g., resolve players * gives you a list of all players.";
Group = "DefaultUtil";
AutoExec = {
"alias \"me|Displays your username\" resolve players ."
};
Args = {
{
Type = "type";
Name = "Type";
Description = "The type for which to resolve"
},
function (context)
if context:GetArgument(1):Validate() == false then
return
end
return {
Type = context:GetArgument(1):GetValue();
Name = "Argument Value Operator";
Description = "The value operator to resolve. One of: * ** . ? ?N";
Optional = true;
}
end
};
Run = function(context)
return table.concat(context:GetArgument(2).RawSegments, ",")
end
} - Edit
03:12:20.489
- Edit
03:12:20.489
============================== - Edit
03:12:20.489 📜 ServerScriptService.Cmdr.BuiltInCommands.Utility.run - Edit
03:12:20.489 ==============================
- Edit
03:12:20.489 return {
Name = "run";
Aliases = {">"};
AutoExec = {
"alias \"discard|Run a command and discard the output.\" replace ${run $1} .* \\\"\\\""
};
Description = "Runs a given command string (replacing embedded commands).";
Group = "DefaultUtil";
Args = {
{
Type = "string";
Name = "Command";
Description = "The command string to run"
},
};
Run = function(context, commandString)
return context.Cmdr.Util.RunCommandString(context.Dispatcher, commandString)
end
} - Edit
03:12:20.489
- Edit
03:12:20.489
============================== - Edit
03:12:20.489 📜 ServerScriptService.Cmdr.BuiltInCommands.Utility.runLines - Edit
03:12:20.490 ==============================
- Edit
03:12:20.490 return {
Name = "run-lines";
Aliases = {};
Description = "Splits input by newlines and runs each line as its own command. This is used by the init-run command.";
Group = "DefaultUtil";
Args = {
{
Type = "string";
Name = "Script";
Description = "The script to parse.";
Default = "";
}
};
ClientRun = function(context, text)
if #text == 0 then
return ""
end
local shouldPrintOutput = context.Dispatcher:Run("var", "INIT_PRINT_OUTPUT") ~= ""
local commands = text:gsub("\n+", "\n"):split("\n")
for _, command in ipairs(commands) do
if command:sub(1, 1) == "#" then
continue
end
local output = context.Dispatcher:EvaluateAndRun(command)
if shouldPrintOutput then
context:Reply(output)
end
end
return ""
end
}
- Edit
03:12:20.490
- Edit
03:12:20.490
============================== - Edit
03:12:20.490 📜 ServerScriptService.Cmdr.BuiltInCommands.Utility.runif - Edit
03:12:20.490 ==============================
- Edit
03:12:20.490 local conditions = {
startsWith = function (text, arg)
if text:sub(1, #arg) == arg then
return text:sub(#arg + 1)
end
end
}
return {
Name = "runif";
Aliases = {};
Description = "Runs a given command string if a certain condition is met.";
Group = "DefaultUtil";
Args = {
{
Type = "conditionFunction";
Name = "Condition";
Description = "The condition function"
},
{
Type = "string";
Name = "Argument";
Description = "The argument to the condition function"
},
{
Type = "string";
Name = "Test against";
Description = "The text to test against."
},
{
Type = "string";
Name = "Command";
Description = "The command string to run if requirements are met. If omitted, return value from condition function is used.";
Optional = true;
},
};
Run = function(context, condition, arg, testAgainst, command)
local conditionFunc = conditions[condition]
if not conditionFunc then
return ("Condition %q is not valid."):format(condition)
end
local text = conditionFunc(testAgainst, arg)
if text then
return context.Dispatcher:EvaluateAndRun(context.Cmdr.Util.RunEmbeddedCommands(context.Dispatcher, command or text))
end
return ""
end
} - Edit
03:12:20.490
- Edit
03:12:20.490
============================== - Edit
03:12:20.490 📜 ServerScriptService.Cmdr.BuiltInCommands.Utility.unbind - Edit
03:12:20.490 ==============================
- Edit
03:12:20.490 return {
Name = "unbind";
Aliases = {};
Description = "Unbinds an input previously bound with Bind";
Group = "DefaultUtil";
Args = {
{
Type = "userInput ! bindableResource @ player";
Name = "Input/Key";
Description = "The key or input type you'd like to unbind."
}
};
ClientRun = function(context, inputEnum)
local binds = context:GetStore("CMDR_Binds")
if binds[inputEnum] then
binds[inputEnum]:Disconnect()
binds[inputEnum] = nil
return "Unbound command from input."
else
return "That input wasn't bound."
end
end
} - Edit
03:12:20.490
- Edit
03:12:20.490
============================== - Edit
03:12:20.490 📜 ServerScriptService.Cmdr.BuiltInCommands.Utility.var - Edit
03:12:20.490 ==============================
- Edit
03:12:20.490 return {
Name = "var";
Aliases = {};
Description = "Gets a stored variable.";
Group = "DefaultUtil";
AutoExec = {
"alias \"init-edit|Edit your initialization script\" edit ${var init} \\\\\n && var= init ||",
"alias \"init-run|Re-runs the initialization script manually.\" run-lines ${var init}",
"init-run",
},
Args = {
{
Type = "storedKey";
Name = "Key";
Description = "The key to get, retrieved from your user data store. Keys prefixed with . are not saved. Keys prefixed with $ are game-wide. Keys prefixed with $. are game-wide and non-saved.";
}
};
ClientRun = function(context, key)
context:GetStore("vars_used")[key] = true
end
}
- Edit
03:12:20.491
- Edit
03:12:20.491
============================== - Edit
03:12:20.491 📜 ServerScriptService.Cmdr.BuiltInCommands.Utility.varServer - Edit
03:12:20.491 ==============================
- Edit
03:12:20.491 local DataStoreService = game:GetService("DataStoreService")
local queue = {}
local DataStoresActive, DataStore
task.spawn(function()
DataStoresActive, DataStore = pcall(function()
local DataStore = DataStoreService:GetDataStore("_package/eryn.io/Cmdr")
DataStore:GetAsync("test_key")
return DataStore
end)
while #queue > 0 do
coroutine.resume(table.remove(queue, 1))
end
end)
return function (context, key)
if DataStoresActive == nil then
table.insert(queue, coroutine.running())
coroutine.yield()
end
local gameWide = false
local saved = true
if key:sub(1, 1) == "$" then
key = key:sub(2)
gameWide = true
end
if key:sub(1, 1) == "." then
key = key:sub(2)
saved = false
end
if saved and not DataStoresActive then
return "# You must publish this place to the web to use saved keys."
end
local namespace = "var_" .. (gameWide and "global" or tostring(context.Executor.UserId))
if saved then
local keyPath = namespace .. "_" .. key
local value = DataStore:GetAsync(keyPath) or ""
if type(value) == "table" then
return table.concat(value, ",") or ""
end
return value
else
local store = context:GetStore(namespace)
local value = store[key] or ""
if type(value) == "table" then
return table.concat(value, ",") or ""
end
return value
end
end
- Edit
03:12:20.491
- Edit
03:12:20.491
============================== - Edit
03:12:20.491 📜 ServerScriptService.Cmdr.BuiltInCommands.Utility.varSet - Edit
03:12:20.491 ==============================
- Edit
03:12:20.491 return {
Name = "var=";
Aliases = {};
Description = "Sets a stored value.";
Group = "DefaultUtil";
Args = {
{
Type = "storedKey";
Name = "Key";
Description = "The key to set, saved in your user data store. Keys prefixed with . are not saved. Keys prefixed with $ are game-wide. Keys prefixed with $. are game-wide and non-saved.";
},
{
Type = "string";
Name = "Value";
Description = "Value or values to set.";
Default = "";
}
};
ClientRun = function(context, key)
context:GetStore("vars_used")[key] = true
end
}
- Edit
03:12:20.491
- Edit
03:12:20.491
============================== - Edit
03:12:20.491 📜 ServerScriptService.Cmdr.BuiltInCommands.Utility.varSetServer - Edit
03:12:20.491 ==============================
- Edit
03:12:20.491 local DataStoreService = game:GetService("DataStoreService")
local queue = {}
local DataStoresActive, DataStore
task.spawn(function()
DataStoresActive, DataStore = pcall(function()
local DataStore = DataStoreService:GetDataStore("_package/eryn.io/Cmdr")
DataStore:GetAsync("test_key")
return DataStore
end)
while #queue > 0 do
coroutine.resume(table.remove(queue, 1))
end
end)
return function (context, key, value)
if DataStoresActive == nil then
table.insert(queue, coroutine.running())
coroutine.yield()
end
local gameWide = false
local saved = true
if key:sub(1, 1) == "$" then
key = key:sub(2)
gameWide = true
end
if key:sub(1, 1) == "." then
key = key:sub(2)
saved = false
end
if saved and not DataStoresActive then
return "# You must publish this place to the web to use saved keys."
end
local namespace = "var_" .. (gameWide and "global" or tostring(context.Executor.UserId))
if saved then
local keyPath = namespace .. "_" .. key
DataStore:SetAsync(keyPath, value)
if type(value) == "table" then
return table.concat(value, ",") or ""
end
return value
else
local store = context:GetStore(namespace)
store[key] = value
if type(value) == "table" then
return table.concat(value, ",") or ""
end
return value
end
end
- Edit
03:12:20.491
- Edit
03:12:20.491
============================== - Edit
03:12:20.491 📜 ServerScriptService.Cmdr.BuiltInCommands.help - Edit
03:12:20.491 ==============================
- Edit
03:12:20.491 local ARGUMENT_SHORTHANDS = [[
Argument Shorthands
-------------------
. Me/Self
* All/Everyone
** Others
? Random
?N List of N random values
]]
local TIPS = [[
Tips
----
• Utilize the Tab key to automatically complete commands
• Easily select and copy command output
]]
return {
Name = "help";
Description = "Displays a list of all commands, or inspects one command.";
Group = "Help";
Args = {
{
Type = "command";
Name = "Command";
Description = "The command to view information on";
Optional = true;
},
};
ClientRun = function (context, commandName)
if commandName then
local command = context.Cmdr.Registry:GetCommand(commandName)
context:Reply(`Command: {command.Name}`, Color3.fromRGB(230, 126, 34))
if command.Aliases and #command.Aliases > 0 then
context:Reply(`Aliases: {table.concat(command.Aliases, ", ")}`, Color3.fromRGB(230, 230, 230))
end
context:Reply(command.Description, Color3.fromRGB(230, 230, 230))
for i, arg in ipairs(command.Args) do
context:Reply(
`#{i} {arg.Name}{if arg.Optional == true then "?" else ""}: {arg.Type} - {arg.Description}`
)
end
else
context:Reply(ARGUMENT_SHORTHANDS)
context:Reply(TIPS)
local commands = context.Cmdr.Registry:GetCommands()
table.sort(commands, function(a, b)
return if a.Group and b.Group then a.Group < b.Group else a.Group
end)
local lastGroup
for _, command in ipairs(commands) do
command.Group = command.Group or "No Group"
if lastGroup ~= command.Group then
context:Reply(`\n{command.Group}\n{string.rep("-", #command.Group)}`)
lastGroup = command.Group
end
context:Reply(if command.Description then `{command.Name} - {command.Description}` else command.Name)
end
end
return ""
end;
}
- Edit
03:12:20.492
- Edit
03:12:20.492
============================== - Edit
03:12:20.492 📜 ServerScriptService.Cmdr.BuiltInTypes.BindableResource - Edit
03:12:20.492 ==============================
- Edit
03:12:20.492 return function (registry)
registry:RegisterType("bindableResource", registry.Cmdr.Util.MakeEnumType("BindableResource", {"Chat"}))
end
- Edit
03:12:20.492
- Edit
03:12:20.492
============================== - Edit
03:12:20.492 📜 ServerScriptService.Cmdr.BuiltInTypes.BrickColor - Edit
03:12:20.492 ==============================
- Edit
03:12:20.492 local Util = require(script.Parent.Parent.Shared.Util)
local brickColorNames = {
"White", "Grey", "Light yellow", "Brick yellow", "Light green (Mint)", "Light reddish violet", "Pastel Blue",
"Light orange brown", "Nougat", "Bright red", "Med. reddish violet", "Bright blue", "Bright yellow", "Earth orange",
"Black", "Dark grey", "Dark green", "Medium green", "Lig. Yellowich orange", "Bright green", "Dark orange",
"Light bluish violet", "Transparent", "Tr. Red", "Tr. Lg blue", "Tr. Blue", "Tr. Yellow", "Light blue",
"Tr. Flu. Reddish orange", "Tr. Green", "Tr. Flu. Green", "Phosph. White", "Light red", "Medium red", "Medium blue",
"Light grey", "Bright violet", "Br. yellowish orange", "Bright orange", "Bright bluish green", "Earth yellow",
"Bright bluish violet", "Tr. Brown", "Medium bluish violet", "Tr. Medi. reddish violet", "Med. yellowish green",
"Med. bluish green", "Light bluish green", "Br. yellowish green", "Lig. yellowish green", "Med. yellowish orange",
"Br. reddish orange", "Bright reddish violet", "Light orange", "Tr. Bright bluish violet", "Gold", "Dark nougat",
"Silver", "Neon orange", "Neon green", "Sand blue", "Sand violet", "Medium orange", "Sand yellow", "Earth blue",
"Earth green", "Tr. Flu. Blue", "Sand blue metallic", "Sand violet metallic", "Sand yellow metallic",
"Dark grey metallic", "Black metallic", "Light grey metallic", "Sand green", "Sand red", "Dark red",
"Tr. Flu. Yellow", "Tr. Flu. Red", "Gun metallic", "Red flip/flop", "Yellow flip/flop", "Silver flip/flop", "Curry",
"Fire Yellow", "Flame yellowish orange", "Reddish brown", "Flame reddish orange", "Medium stone grey", "Royal blue",
"Dark Royal blue", "Bright reddish lilac", "Dark stone grey", "Lemon metalic", "Light stone grey", "Dark Curry",
"Faded green", "Turquoise", "Light Royal blue", "Medium Royal blue", "Rust", "Brown", "Reddish lilac", "Lilac",
"Light lilac", "Bright purple", "Light purple", "Light pink", "Light brick yellow", "Warm yellowish orange",
"Cool yellow", "Dove blue", "Medium lilac", "Slime green", "Smoky grey", "Dark blue", "Parsley green", "Steel blue",
"Storm blue", "Lapis", "Dark indigo", "Sea green", "Shamrock", "Fossil", "Mulberry", "Forest green", "Cadet blue",
"Electric blue", "Eggplant", "Moss", "Artichoke", "Sage green", "Ghost grey", "Lilac", "Plum", "Olivine",
"Laurel green", "Quill grey", "Crimson", "Mint", "Baby blue", "Carnation pink", "Persimmon", "Maroon", "Gold",
"Daisy orange", "Pearl", "Fog", "Salmon", "Terra Cotta", "Cocoa", "Wheat", "Buttermilk", "Mauve", "Sunrise",
"Tawny", "Rust", "Cashmere", "Khaki", "Lily white", "Seashell", "Burgundy", "Cork", "Burlap", "Beige", "Oyster",
"Pine Cone", "Fawn brown", "Hurricane grey", "Cloudy grey", "Linen", "Copper", "Dirt brown", "Bronze", "Flint",
"Dark taupe", "Burnt Sienna", "Institutional white", "Mid gray", "Really black", "Really red", "Deep orange",
"Alder", "Dusty Rose", "Olive", "New Yeller", "Really blue", "Navy blue", "Deep blue", "Cyan", "CGA brown",
"Magenta", "Pink", "Deep orange", "Teal", "Toothpaste", "Lime green", "Camo", "Grime", "Lavender",
"Pastel light blue", "Pastel orange", "Pastel violet", "Pastel blue-green", "Pastel green", "Pastel yellow",
"Pastel brown", "Royal purple", "Hot pink"
}
local brickColorFinder = Util.MakeFuzzyFinder(brickColorNames)
local brickColorType = {
Prefixes = "% teamColor";
Transform = function(text)
local brickColors = {}
for i, name in pairs(brickColorFinder(text)) do
brickColors[i] = BrickColor.new(name)
end
return brickColors
end;
Validate = function(brickColors)
return #brickColors > 0, "No valid brick colors with that name could be found."
end;
Autocomplete = function(brickColors)
return Util.GetNames(brickColors)
end;
Parse = function(brickColors)
return brickColors[1]
end;
}
local brickColor3Type = {
Transform = brickColorType.Transform;
Validate = brickColorType.Validate;
Autocomplete = brickColorType.Autocomplete;
Parse = function(brickColors)
return brickColors[1].Color
end;
}
return function(registry)
registry:RegisterType("brickColor", brickColorType)
registry:RegisterType("brickColors", Util.MakeListableType(brickColorType, {
Prefixes = "% teamColors"
}))
registry:RegisterType("brickColor3", brickColor3Type)
registry:RegisterType("brickColor3s", Util.MakeListableType(brickColor3Type))
end - Edit
03:12:20.492
- Edit
03:12:20.492
============================== - Edit
03:12:20.492 📜 ServerScriptService.Cmdr.BuiltInTypes.Color3 - Edit
03:12:20.492 ==============================
- Edit
03:12:20.492 local Util = require(script.Parent.Parent.Shared.Util)
local color3Type = Util.MakeSequenceType({
Prefixes = "# hexColor3 ! brickColor3";
ValidateEach = function(value, i)
if value == nil then
return false, ("Invalid or missing number at position %d in Color3 type."):format(i)
elseif value < 0 or value > 255 then
return false, ("Number out of acceptable range 0-255 at position %d in Color3 type."):format(i)
elseif value % 1 ~= 0 then
return false, ("Number is not an integer at position %d in Color3 type."):format(i)
end
return true
end;
TransformEach = tonumber;
Constructor = Color3.fromRGB;
Length = 3;
})
local function parseHexDigit(x)
if #x == 1 then
x = x .. x
end
return tonumber(x, 16)
end
local hexColor3Type = {
Transform = function(text)
local r, g, b = text:match("^#?(%x%x?)(%x%x?)(%x%x?)$")
return Util.Each(parseHexDigit, r, g, b)
end;
Validate = function(r, g, b)
return r ~= nil and g ~= nil and b ~= nil, "Invalid hex color"
end;
Parse = function(...)
return Color3.fromRGB(...)
end;
}
return function (cmdr)
cmdr:RegisterType("color3", color3Type)
cmdr:RegisterType("color3s", Util.MakeListableType(color3Type, {
Prefixes = "# hexColor3s ! brickColor3s"
}))
cmdr:RegisterType("hexColor3", hexColor3Type)
cmdr:RegisterType("hexColor3s", Util.MakeListableType(hexColor3Type))
end
- Edit
03:12:20.492
- Edit
03:12:20.493
============================== - Edit
03:12:20.493 📜 ServerScriptService.Cmdr.BuiltInTypes.Command - Edit
03:12:20.493 ==============================
- Edit
03:12:20.493 local Util = require(script.Parent.Parent.Shared.Util)
return function (cmdr)
local commandType = {
Transform = function (text)
local findCommand = Util.MakeFuzzyFinder(cmdr:GetCommandNames())
return findCommand(text)
end;
Validate = function (commands)
return #commands > 0, "No command with that name could be found."
end;
Autocomplete = function (commands)
return commands
end;
Parse = function (commands)
return commands[1]
end;
}
cmdr:RegisterType("command", commandType)
cmdr:RegisterType("commands", Util.MakeListableType(commandType))
end - Edit
03:12:20.493
- Edit
03:12:20.493
============================== - Edit
03:12:20.493 📜 ServerScriptService.Cmdr.BuiltInTypes.ConditionFunction - Edit
03:12:20.493 ==============================
- Edit
03:12:20.493 return function (registry)
registry:RegisterType("conditionFunction", registry.Cmdr.Util.MakeEnumType("ConditionFunction", {"startsWith"}))
end
- Edit
03:12:20.493
- Edit
03:12:20.493
============================== - Edit
03:12:20.493 📜 ServerScriptService.Cmdr.BuiltInTypes.Duration - Edit
03:12:20.493 ==============================
- Edit
03:12:20.493 local Util = require(script.Parent.Parent.Shared.Util)
local unitTable = {
Years = 31556926,
Months = 2629744,
Weeks = 604800,
Days = 86400,
Hours = 3600,
Minutes = 60,
Seconds = 1
}
local searchKeyTable = {}
for key, _ in pairs(unitTable) do
table.insert(searchKeyTable, key)
end
local unitFinder = Util.MakeFuzzyFinder(searchKeyTable)
local function stringToSecondDuration(stringDuration)
-- The duration cannot be null or an empty string.
if stringDuration == nil or stringDuration == "" then
return nil
end
-- Allow 0 by itself (without a unit) to indicate 0 seconds
local durationNum = tonumber(stringDuration)
if durationNum and durationNum == 0 then
return 0, 0, true
end
-- The duration must end with a unit,
-- if it doesn't then return true as the fourth value to indicate the need to offer autocomplete for units.
local endOnlyString = stringDuration:gsub("-?%d+%a+", "")
local endNumber = endOnlyString:match("-?%d+")
if endNumber then
return nil, tonumber(endNumber), true
end
local seconds = nil
local rawNum, rawUnit
for rawComponent in stringDuration:gmatch("-?%d+%a+") do
rawNum, rawUnit = rawComponent:match("(-?%d+)(%a+)")
local unitNames = unitFinder(rawUnit)
-- There were no matching units, it's invalid. Return the parsed number to be used for autocomplete
if #unitNames == 0 then
return nil, tonumber(rawNum)
end
if seconds == nil then seconds = 0 end
-- While it was already defaulting to use minutes when using just "m", this does it without worrying
-- about any consistency between list ordering.
seconds = seconds + (rawUnit:lower() == "m" and 60 or unitTable[unitNames[1]]) * tonumber(rawNum)
end
-- If no durations were provided, return nil.
if seconds == nil then
return nil
else
return seconds, tonumber(rawNum)
end
end
local function mapUnits(units, rawText, lastNumber, subStart)
subStart = subStart or 1
local returnTable = {}
for i, unit in pairs(units) do
if lastNumber == 1 then
returnTable[i] = rawText .. unit:sub(subStart, #unit - 1)
else
returnTable[i] = rawText .. unit:sub(subStart)
end
end
return returnTable
end
local durationType = {
Transform = function(text)
return text, stringToSecondDuration(text)
end;
Validate = function(_, duration)
return duration ~= nil
end;
Autocomplete = function(rawText, duration, lastNumber, isUnitMissing, matchedUnits)
local returnTable = {}
if isUnitMissing or matchedUnits then
local unitsTable = isUnitMissing == true and unitFinder("") or matchedUnits
if isUnitMissing == true then
-- Concat the entire unit name to existing text.
returnTable = mapUnits(unitsTable, rawText, lastNumber)
else
-- Concat the rest of the unit based on what already exists of the unit name.
local existingUnitLength = rawText:match("^.*(%a+)$"):len()
returnTable = mapUnits(unitsTable, rawText, existingUnitLength + 1)
end
elseif duration ~= nil then
local endingUnit = rawText:match("^.*-?%d+(%a+)%s?$")
-- Assume there is a singular match at this point
local fuzzyUnits = unitFinder(endingUnit)
-- List all possible fuzzy matches. This is for the Minutes/Months ambiguity case.
returnTable = mapUnits(fuzzyUnits, rawText, lastNumber, #endingUnit + 1)
-- Sort alphabetically in the Minutes/Months case, so Minutes are displayed on top.
table.sort(returnTable)
end
return returnTable
end;
Parse = function(_, duration)
return duration
end;
}
return function(registry)
registry:RegisterType("duration", durationType)
registry:RegisterType("durations", Util.MakeListableType(durationType))
end
- Edit
03:12:20.493
- Edit
03:12:20.493
============================== - Edit
03:12:20.493 📜 ServerScriptService.Cmdr.BuiltInTypes.JSON - Edit
03:12:20.493 ==============================
- Edit
03:12:20.493 local HttpService = game:GetService("HttpService")
return function(registry)
registry:RegisterType("json", {
Validate = function(text)
return pcall(HttpService.JSONDecode, HttpService, text)
end;
Parse = function(text)
return HttpService:JSONDecode(text)
end
})
end
- Edit
03:12:20.493
- Edit
03:12:20.494
============================== - Edit
03:12:20.494 📜 ServerScriptService.Cmdr.BuiltInTypes.MathOperator - Edit
03:12:20.494 ==============================
- Edit
03:12:20.494 return function(registry)
registry:RegisterType("mathOperator", registry.Cmdr.Util.MakeEnumType("Math Operator", {
{
Name = "+";
Perform = function(a, b)
return a + b
end
};
{
Name = "-";
Perform = function(a, b)
return a - b
end
};
{
Name = "*";
Perform = function(a, b)
return a * b
end
};
{
Name = "/";
Perform = function(a, b)
return a / b
end
};
{
Name = "**";
Perform = function(a, b)
return a ^ b
end
};
{
Name = "%";
Perform = function(a, b)
return a % b
end
}
}))
end
- Edit
03:12:20.494
- Edit
03:12:20.494
============================== - Edit
03:12:20.494 📜 ServerScriptService.Cmdr.BuiltInTypes.Player - Edit
03:12:20.494 ==============================
- Edit
03:12:20.494 local Util = require(script.Parent.Parent.Shared.Util)
local Players = game:GetService("Players")
local playerType = {
Transform = function (text)
local findPlayer = Util.MakeFuzzyFinder(Players:GetPlayers())
return findPlayer(text)
end;
Validate = function (players)
return #players > 0, "No player with that name could be found."
end;
Autocomplete = function (players)
return Util.GetNames(players)
end;
Parse = function (players)
return players[1]
end;
Default = function(player)
return player.Name
end;
ArgumentOperatorAliases = {
me = ".";
all = "*";
others = "**";
random = "?";
};
}
return function (cmdr)
cmdr:RegisterType("player", playerType)
cmdr:RegisterType("players", Util.MakeListableType(playerType, {
Prefixes = "% teamPlayers";
}))
end
- Edit
03:12:20.494
- Edit
03:12:20.494
============================== - Edit
03:12:20.494 📜 ServerScriptService.Cmdr.BuiltInTypes.PlayerId - Edit
03:12:20.494 ==============================
- Edit
03:12:20.494 local Util = require(script.Parent.Parent.Shared.Util)
local Players = game:GetService("Players")
local nameCache = {}
local function getUserId(name)
if nameCache[name] then
return nameCache[name]
elseif Players:FindFirstChild(name) then
nameCache[name] = Players[name].UserId
return Players[name].UserId
else
local ok, userid = pcall(Players.GetUserIdFromNameAsync, Players, name)
if not ok then
return nil
end
nameCache[name] = userid
return userid
end
end
local playerIdType = {
DisplayName = "Full Player Name";
Prefixes = "# integer";
Transform = function (text)
local findPlayer = Util.MakeFuzzyFinder(Players:GetPlayers())
return text, findPlayer(text)
end;
ValidateOnce = function (text)
return getUserId(text) ~= nil, "No player with that name could be found."
end;
Autocomplete = function (_, players)
return Util.GetNames(players)
end;
Parse = function (text)
return getUserId(text)
end;
Default = function(player)
return player.Name
end;
ArgumentOperatorAliases = {
me = ".";
all = "*";
others = "**";
random = "?";
};
}
return function (cmdr)
cmdr:RegisterType("playerId", playerIdType)
cmdr:RegisterType("playerIds", Util.MakeListableType(playerIdType, {
Prefixes = "# integers"
}))
end
- Edit
03:12:20.494
- Edit
03:12:20.494
============================== - Edit
03:12:20.495 📜 ServerScriptService.Cmdr.BuiltInTypes.Primitives - Edit
03:12:20.495 ==============================
- Edit
03:12:20.495 local Util = require(script.Parent.Parent.Shared.Util)
local stringType = {
Validate = function (value)
return value ~= nil
end;
Parse = function (value)
return tostring(value)
end;
}
local numberType = {
Transform = function (text)
return tonumber(text)
end;
Validate = function (value)
return value ~= nil
end;
Parse = function (value)
return value
end;
}
local intType = {
Transform = function (text)
return tonumber(text)
end;
Validate = function (value)
return value ~= nil and value == math.floor(value), "Only whole numbers are valid."
end;
Parse = function (value)
return value
end
}
local positiveIntType = {
Transform = function (text)
return tonumber(text)
end,
Validate = function (value)
return value ~= nil and value == math.floor(value) and value > 0, "Only positive whole numbers are valid."
end,
Parse = function (value)
return value
end,
}
local nonNegativeIntType = {
Transform = function (text)
return tonumber(text)
end,
Validate = function (value)
return value ~= nil and value == math.floor(value) and value >= 0, "Only non-negative whole numbers are valid."
end,
Parse = function (value)
return value
end,
}
local byteType = {
Transform = function (text)
return tonumber(text)
end,
Validate = function (value)
return value ~= nil and value == math.floor(value) and value >= 0 and value <= 255, "Only bytes are valid."
end,
Parse = function (value)
return value
end,
}
local digitType = {
Transform = function (text)
return tonumber(text)
end,
Validate = function (value)
return value ~= nil and value == math.floor(value) and value >= 0 and value <= 9, "Only digits are valid."
end,
Parse = function (value)
return value
end,
}
local boolType do
local truthy = Util.MakeDictionary({"true", "t", "yes", "y", "on", "enable", "enabled", "1", "+"});
local falsy = Util.MakeDictionary({"false"; "f"; "no"; "n"; "off"; "disable"; "disabled"; "0"; "-"});
boolType = {
Transform = function (text)
return text:lower()
end;
Validate = function (value)
return truthy[value] ~= nil or falsy[value] ~= nil, "Please use true/yes/on or false/no/off."
end;
Parse = function (value)
if truthy[value] then
return true
elseif falsy[value] then
return false
else
return nil
end
end;
}
end
return function (cmdr)
cmdr:RegisterType("string", stringType)
cmdr:RegisterType("number", numberType)
cmdr:RegisterType("integer", intType)
cmdr:RegisterType("positiveInteger", positiveIntType)
cmdr:RegisterType("nonNegativeInteger", nonNegativeIntType)
cmdr:RegisterType("byte", byteType)
cmdr:RegisterType("digit", digitType)
cmdr:RegisterType("boolean", boolType)
cmdr:RegisterType("strings", Util.MakeListableType(stringType))
cmdr:RegisterType("numbers", Util.MakeListableType(numberType))
cmdr:RegisterType("integers", Util.MakeListableType(intType))
cmdr:RegisterType("positiveIntegers", Util.MakeListableType(positiveIntType))
cmdr:RegisterType("nonNegativeIntegers", Util.MakeListableType(nonNegativeIntType))
cmdr:RegisterType("bytes", Util.MakeListableType(byteType))
cmdr:RegisterType("digits", Util.MakeListableType(digitType))
cmdr:RegisterType("booleans", Util.MakeListableType(boolType))
end
- Edit
03:12:20.495
- Edit
03:12:20.495
============================== - Edit
03:12:20.495 📜 ServerScriptService.Cmdr.BuiltInTypes.StoredKey - Edit
03:12:20.495 ==============================
- Edit
03:12:20.495 local Util = require(script.Parent.Parent.Shared.Util)
local VALID_STORED_KEY_NAME_PATTERNS = {
"^%a[%w_]*$",
"^%$%a[%w_]*$",
"^%.%a[%w_]*$",
"^%$%.%a[%w_]*$",
}
return function (registry)
local storedKeyType = {
Autocomplete = function(text)
local find = registry.Cmdr.Util.MakeFuzzyFinder(registry.Cmdr.Util.DictionaryKeys(registry:GetStore("vars_used") or {}))
return find(text)
end;
Validate = function(text)
for _, pattern in ipairs(VALID_STORED_KEY_NAME_PATTERNS) do
if text:match(pattern) then
return true
end
end
return false, "Key names must start with an optional modifier: . $ or $. and must begin with a letter."
end;
Parse = function(text)
return text
end;
}
registry:RegisterType("storedKey", storedKeyType)
registry:RegisterType("storedKeys", Util.MakeListableType(storedKeyType))
end
- Edit
03:12:20.495
- Edit
03:12:20.495
============================== - Edit
03:12:20.495 📜 ServerScriptService.Cmdr.BuiltInTypes.Team - Edit
03:12:20.495 ==============================
- Edit
03:12:20.495 local Teams = game:GetService("Teams")
local Util = require(script.Parent.Parent.Shared.Util)
local teamType = {
Transform = function (text)
local findTeam = Util.MakeFuzzyFinder(Teams:GetTeams())
return findTeam(text)
end;
Validate = function (teams)
return #teams > 0, "No team with that name could be found."
end;
Autocomplete = function (teams)
return Util.GetNames(teams)
end;
Parse = function (teams)
return teams[1];
end;
}
local teamPlayersType = {
Listable = true;
Transform = teamType.Transform;
Validate = teamType.Validate;
Autocomplete = teamType.Autocomplete;
Parse = function (teams)
return teams[1]:GetPlayers()
end;
}
local teamColorType = {
Transform = teamType.Transform;
Validate = teamType.Validate;
Autocomplete = teamType.Autocomplete;
Parse = function (teams)
return teams[1].TeamColor
end;
}
return function (cmdr)
cmdr:RegisterType("team", teamType)
cmdr:RegisterType("teams", Util.MakeListableType(teamType))
cmdr:RegisterType("teamPlayers", teamPlayersType)
cmdr:RegisterType("teamColor", teamColorType)
cmdr:RegisterType("teamColors", Util.MakeListableType(teamColorType))
end - Edit
03:12:20.495
- Edit
03:12:20.495
============================== - Edit
03:12:20.495 📜 ServerScriptService.Cmdr.BuiltInTypes.Type - Edit
03:12:20.496 ==============================
- Edit
03:12:20.496 local Util = require(script.Parent.Parent.Shared.Util)
return function (cmdr)
local typeType = {
Transform = function (text)
local findCommand = Util.MakeFuzzyFinder(cmdr:GetTypeNames())
return findCommand(text)
end;
Validate = function (commands)
return #commands > 0, "No type with that name could be found."
end;
Autocomplete = function (commands)
return commands
end;
Parse = function (commands)
return commands[1]
end;
}
cmdr:RegisterType("type", typeType)
cmdr:RegisterType("types", Util.MakeListableType(typeType))
end - Edit
03:12:20.496
- Edit
03:12:20.496
============================== - Edit
03:12:20.496 📜 ServerScriptService.Cmdr.BuiltInTypes.URL - Edit
03:12:20.496 ==============================
- Edit
03:12:20.496 local Util = require(script.Parent.Parent.Shared.Util)
local storedKeyType = {
Validate = function(text)
if text:match("^https?://.+$") then
return true
end
return false, "URLs must begin with http:// or https://"
end;
Parse = function(text)
return text
end;
}
return function (cmdr)
cmdr:RegisterType("url", storedKeyType)
cmdr:RegisterType("urls", Util.MakeListableType(storedKeyType))
end
- Edit
03:12:20.496
- Edit
03:12:20.496
============================== - Edit
03:12:20.496 📜 ServerScriptService.Cmdr.BuiltInTypes.UserInput - Edit
03:12:20.496 ==============================
- Edit
03:12:20.496 local Util = require(script.Parent.Parent.Shared.Util)
local combinedInputEnums = Enum.UserInputType:GetEnumItems()
for _, e in pairs(Enum.KeyCode:GetEnumItems()) do
combinedInputEnums[#combinedInputEnums + 1] = e
end
local userInputType = {
Transform = function (text)
local findEnum = Util.MakeFuzzyFinder(combinedInputEnums)
return findEnum(text)
end;
Validate = function (enums)
return #enums > 0
end;
Autocomplete = function (enums)
return Util.GetNames(enums)
end;
Parse = function (enums)
return enums[1];
end;
}
return function (cmdr)
cmdr:RegisterType("userInput", userInputType)
cmdr:RegisterType("userInputs", Util.MakeListableType(userInputType))
end - Edit
03:12:20.496
- Edit
03:12:20.496
============================== - Edit
03:12:20.497 📜 ServerScriptService.Cmdr.BuiltInTypes.Vector - Edit
03:12:20.497 ==============================
- Edit
03:12:20.497 local Util = require(script.Parent.Parent.Shared.Util)
local function validateVector(value, i)
if value == nil then
return false, ("Invalid or missing number at position %d in Vector type."):format(i)
end
return true
end
local vector3Type = Util.MakeSequenceType({
ValidateEach = validateVector;
TransformEach = tonumber;
Constructor = Vector3.new;
Length = 3;
})
local vector2Type = Util.MakeSequenceType({
ValidateEach = validateVector;
TransformEach = tonumber;
Constructor = Vector2.new;
Length = 2;
})
return function (cmdr)
cmdr:RegisterType("vector3", vector3Type)
cmdr:RegisterType("vector3s", Util.MakeListableType(vector3Type))
cmdr:RegisterType("vector2", vector2Type)
cmdr:RegisterType("vector2s", Util.MakeListableType(vector2Type))
end - Edit
03:12:20.497
- Edit
03:12:20.497
============================== - Edit
03:12:20.497 📜 ServerScriptService.Cmdr.CmdrClient - Edit
03:12:20.497 ==============================
- Edit
03:12:20.497 local RunService = game:GetService("RunService")
local StarterGui = game:GetService("StarterGui")
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Shared = script:WaitForChild("Shared")
local Util = require(Shared:WaitForChild("Util"))
if RunService:IsClient() == false then
error("Server scripts cannot require the client library. Please require the server library to use Cmdr in your own code.")
end
local Cmdr do
Cmdr = setmetatable({
ReplicatedRoot = script;
RemoteFunction = script:WaitForChild("CmdrFunction");
RemoteEvent = script:WaitForChild("CmdrEvent");
ActivationKeys = {[Enum.KeyCode.F2] = true};
Enabled = true;
MashToEnable = false;
ActivationUnlocksMouse = false;
HideOnLostFocus = true;
PlaceName = "Cmdr";
Util = Util;
Events = {};
}, {
-- This sucks, and may be redone or removed
-- Proxies dispatch methods on to main Cmdr object
__index = function (self, k)
local r = self.Dispatcher[k]
if r and type(r) == "function" then
return function (_, ...)
return r(self.Dispatcher, ...)
end
end
end
})
Cmdr.Registry = require(Shared.Registry)(Cmdr)
Cmdr.Dispatcher = require(Shared.Dispatcher)(Cmdr)
end
if StarterGui:WaitForChild("Cmdr") and wait() and Player:WaitForChild("PlayerGui"):FindFirstChild("Cmdr") == nil then
StarterGui.Cmdr:Clone().Parent = Player.PlayerGui
end
local Interface = require(script.CmdrInterface)(Cmdr)
--- Sets a list of keyboard keys (Enum.KeyCode) that can be used to open the commands menu
function Cmdr:SetActivationKeys (keysArray)
self.ActivationKeys = Util.MakeDictionary(keysArray)
end
--- Sets the place name label on the interface
function Cmdr:SetPlaceName (name)
self.PlaceName = name
Interface.Window:UpdateLabel()
end
--- Sets whether or not the console is enabled
function Cmdr:SetEnabled (enabled)
self.Enabled = enabled
end
--- Sets if activation will free the mouse.
function Cmdr:SetActivationUnlocksMouse (enabled)
self.ActivationUnlocksMouse = enabled
end
--- Shows Cmdr window
function Cmdr:Show ()
if not self.Enabled then
return
end
Interface.Window:Show()
end
--- Hides Cmdr window
function Cmdr:Hide ()
Interface.Window:Hide()
end
--- Toggles Cmdr window
function Cmdr:Toggle ()
if not self.Enabled then
return self:Hide()
end
Interface.Window:SetVisible(not Interface.Window:IsVisible())
end
--- Enables the "Mash to open" feature
function Cmdr:SetMashToEnable(isEnabled)
self.MashToEnable = isEnabled
if isEnabled then
self:SetEnabled(false)
end
end
--- Sets the hide on 'lost focus' feature.
function Cmdr:SetHideOnLostFocus(enabled)
self.HideOnLostFocus = enabled
end
--- Sets the handler for a certain event type
function Cmdr:HandleEvent(name, callback)
self.Events[name] = callback
end
-- Only register when we aren't in studio because don't want to overwrite what the server portion did
if RunService:IsServer() == false then
Cmdr.Registry:RegisterTypesIn(script:WaitForChild("Types"))
Cmdr.Registry:RegisterCommandsIn(script:WaitForChild("Commands"))
end
-- Hook up event listener
Cmdr.RemoteEvent.OnClientEvent:Connect(function(name, ...)
if Cmdr.Events[name] then
Cmdr.Events[name](...)
end
end)
require(script.DefaultEventHandlers)(Cmdr)
return Cmdr
- Edit
03:12:20.497
- Edit
03:12:20.497
============================== - Edit
03:12:20.497 📜 ServerScriptService.Cmdr.CmdrClient.CmdrInterface - Edit
03:12:20.497 ==============================
- Edit
03:12:20.498 -- Here be dragons
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
return function (Cmdr)
local Util = Cmdr.Util
local Window = require(script:WaitForChild("Window"))
Window.Cmdr = Cmdr
local AutoComplete = require(script:WaitForChild("AutoComplete"))(Cmdr)
Window.AutoComplete = AutoComplete
-- Sets the Window.ProcessEntry callback so that we can dispatch our commands out
function Window.ProcessEntry(text)
text = Util.TrimString(text)
if #text == 0 then return end
Window:AddLine(Window:GetLabel() .. " " .. text, Color3.fromRGB(255, 223, 93))
Window:AddLine(Cmdr.Dispatcher:EvaluateAndRun(text, Player, {
IsHuman = true
}))
end
-- Sets the Window.OnTextChanged callback so we can update the auto complete
function Window.OnTextChanged (text)
local command = Cmdr.Dispatcher:Evaluate(text, Player, true)
local arguments = Util.SplitString(text)
local commandText = table.remove(arguments, 1)
local atEnd = false
if command then
arguments = Util.MashExcessArguments(arguments, #command.Object.Args)
atEnd = #arguments == #command.Object.Args
end
local entryComplete = commandText and #arguments > 0
if text:sub(#text, #text):match("%s") and not atEnd then
entryComplete = true
arguments[#arguments + 1] = ""
end
if command and entryComplete then
local commandValid, errorText = command:Validate()
Window:SetIsValidInput(commandValid, ("Validation errors: %s"):format(errorText or ""))
local acItems = {}
local lastArgument = command:GetArgument(#arguments)
if lastArgument then
local typedText = lastArgument.TextSegmentInProgress
local isPartial = false
if lastArgument.RawSegmentsAreAutocomplete then
for i, segment in ipairs(lastArgument.RawSegments) do
acItems[i] = {segment, segment}
end
else
local items, options = lastArgument:GetAutocomplete()
options = options or {}
isPartial = options.IsPartial or false
for i, item in pairs(items) do
acItems[i] = {typedText, item}
end
end
local valid = true
if #typedText > 0 then
valid, errorText = lastArgument:Validate()
end
if not atEnd and valid then
Window:HideInvalidState()
end
return AutoComplete:Show(acItems, {
at = atEnd and #text - #typedText + (text:sub(#text, #text):match("%s") and -1 or 0);
prefix = #lastArgument.RawSegments == 1 and lastArgument.Prefix or "";
isLast = #command.Arguments == #command.ArgumentDefinitions and #typedText > 0;
numArgs = #arguments;
command = command;
arg = lastArgument;
name = lastArgument.Name .. (lastArgument.Required and "" or "?");
type = lastArgument.Type.DisplayName;
description = (valid == false and errorText) or lastArgument.Object.Description;
invalid = not valid;
isPartial = isPartial;
})
end
elseif commandText and #arguments == 0 then
Window:SetIsValidInput(true)
local exactCommand = Cmdr.Registry:GetCommand(commandText)
local exactMatch
if exactCommand then
exactMatch = {exactCommand.Name, exactCommand.Name, options = {
name = exactCommand.Name;
description = exactCommand.Description;
}}
local arg = exactCommand.Args and exactCommand.Args[1]
if type(arg) == "function" then
arg = arg(command)
end
if
arg
and (not arg.Optional
and arg.Default == nil)
then
Window:SetIsValidInput(false, "This command has required arguments.")
Window:HideInvalidState()
end
else
Window:SetIsValidInput(false, ("%q is not a valid command name. Use the help command to see all available commands."):format(commandText))
end
local acItems = {exactMatch}
for _, cmd in pairs(Cmdr.Registry:GetCommandNames()) do
if commandText:lower() == cmd:lower():sub(1, #commandText) and (exactMatch == nil or exactMatch[1] ~= commandText) then
local commandObject = Cmdr.Registry:GetCommand(cmd)
acItems[#acItems + 1] = {commandText, cmd, options = {
name = commandObject.Name;
description = commandObject.Description;
}}
end
end
return AutoComplete:Show(acItems)
end
Window:SetIsValidInput(false, "Use the help command to see all available commands.")
AutoComplete:Hide()
end
Window:UpdateLabel()
Window:UpdateWindowHeight()
return {
Window = Window;
AutoComplete = AutoComplete;
}
end
- Edit
03:12:20.498
- Edit
03:12:20.498
============================== - Edit
03:12:20.498 📜 ServerScriptService.Cmdr.CmdrClient.CmdrInterface.AutoComplete - Edit
03:12:20.498 ==============================
- Edit
03:12:20.498 -- luacheck: ignore 212
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
return function(Cmdr)
local AutoComplete = {
Items = {},
ItemOptions = {},
SelectedItem = 0,
}
local Util = Cmdr.Util
local Gui = Player:WaitForChild("PlayerGui"):WaitForChild("Cmdr"):WaitForChild("Autocomplete")
local AutoItem = Gui:WaitForChild("TextButton")
local Title = Gui:WaitForChild("Title")
local Description = Gui:WaitForChild("Description")
local Entry = Gui.Parent:WaitForChild("Frame"):WaitForChild("Entry")
AutoItem.Parent = nil
local defaultBarThickness = Gui.ScrollBarThickness
-- Helper function that sets text and resizes labels
local function SetText(obj, textObj, text, sizeFromContents)
obj.Visible = text ~= nil
textObj.Text = text or ""
if sizeFromContents then
textObj.Size = UDim2.new(
0,
Util.GetTextSize(text or "", textObj, Vector2.new(1000, 1000), 1, 0).X,
obj.Size.Y.Scale,
obj.Size.Y.Offset
)
end
end
local function UpdateContainerSize()
Gui.Size = UDim2.new(
0,
math.max(Title.Field.TextBounds.X + Title.Field.Type.TextBounds.X, Gui.Size.X.Offset),
0,
math.min(Gui.UIListLayout.AbsoluteContentSize.Y, Gui.Parent.AbsoluteSize.Y - Gui.AbsolutePosition.Y - 10)
)
end
-- Update the info display (Name, type, and description) based on given options.
local function UpdateInfoDisplay(options)
-- Update the objects' text and sizes
SetText(Title, Title.Field, options.name, true)
SetText(
Title.Field.Type,
Title.Field.Type,
options.type and ": " .. options.type:sub(1, 1):upper() .. options.type:sub(2)
)
SetText(Description, Description.Label, options.description)
Description.Label.TextColor3 = options.invalid and Color3.fromRGB(255, 73, 73) or Color3.fromRGB(255, 255, 255)
Description.Size = UDim2.new(1, 0, 0, 40)
-- Flow description text
while not Description.Label.TextFits do
Description.Size = Description.Size + UDim2.new(0, 0, 0, 2)
if Description.Size.Y.Offset > 500 then
break
end
end
-- Update container
task.wait()
Gui.UIListLayout:ApplyLayout()
UpdateContainerSize()
Gui.ScrollBarThickness = defaultBarThickness
end
--- Shows the auto complete menu with the given list and possible options
-- item = {typedText, suggestedText, options?=options}
-- The options table is optional. `at` should only be passed into AutoComplete::Show
-- name, type, and description may be passed in an options dictionary inside the items as well
-- options.at?: the character index at which to show the menu
-- options.name?: The name to display in the info box
-- options.type?: The type to display in the info box
-- options.prefix?: The current type prefix (%Team)
-- options.description?: The description for the currently active info box
-- options.invalid?: If true, description is shown in red.
-- options.isLast?: If true, auto complete won't keep going after this argument.
function AutoComplete:Show(items, options)
options = options or {}
-- Remove old options.
for _, item in pairs(self.Items) do
if item.gui then
item.gui:Destroy()
end
end
-- Reset state
self.SelectedItem = 1
self.Items = items
self.Prefix = options.prefix or ""
self.LastItem = options.isLast or false
self.Command = options.command
self.Arg = options.arg
self.NumArgs = options.numArgs
self.IsPartial = options.isPartial
-- Generate the new option labels
local autocompleteWidth = 200
Gui.ScrollBarThickness = 0
for i, item in pairs(self.Items) do
local leftText = item[1]
local rightText = item[2]
local btn = AutoItem:Clone()
btn.Name = leftText .. rightText
btn.BackgroundTransparency = i == self.SelectedItem and 0.5 or 1
local start, stop = string.find(rightText:lower(), leftText:lower(), 1, true)
btn.Typed.Text = string.rep(" ", start - 1) .. leftText
btn.Suggest.Text = string.sub(rightText, 0, start - 1)
.. string.rep(" ", #leftText)
.. string.sub(rightText, stop + 1)
btn.Parent = Gui
btn.LayoutOrder = i
local maxBounds = math.max(btn.Typed.TextBounds.X, btn.Suggest.TextBounds.X) + 20
if maxBounds > autocompleteWidth then
autocompleteWidth = maxBounds
end
item.gui = btn
end
Gui.UIListLayout:ApplyLayout()
-- Todo: Use TextService to find accurate position for auto complete box
local text = Entry.TextBox.Text
local words = Util.SplitString(text)
if text:sub(#text, #text) == " " and not options.at then
words[#words + 1] = "e"
end
table.remove(words, #words)
local extra = (options.at and options.at or (#table.concat(words, " ") + 1)) * 7
-- Update the auto complete container
Gui.Position =
UDim2.new(0, Entry.TextBox.AbsolutePosition.X - 10 + extra, 0, Entry.TextBox.AbsolutePosition.Y + 30)
Gui.Size = UDim2.new(0, autocompleteWidth, 0, Gui.UIListLayout.AbsoluteContentSize.Y)
Gui.Visible = true
-- Finally, update thge info display
UpdateInfoDisplay(self.Items[1] and self.Items[1].options or options)
end
--- Returns the selected item in the auto complete
function AutoComplete:GetSelectedItem()
if Gui.Visible == false then
return nil
end
return AutoComplete.Items[AutoComplete.SelectedItem]
end
--- Hides the auto complete
function AutoComplete:Hide()
Gui.Visible = false
end
--- Returns if the menu is visible
function AutoComplete:IsVisible()
return Gui.Visible
end
--- Changes the user's item selection by the given delta
function AutoComplete:Select(delta)
if not Gui.Visible then
return
end
self.SelectedItem = self.SelectedItem + delta
if self.SelectedItem > #self.Items then
self.SelectedItem = 1
elseif self.SelectedItem < 1 then
self.SelectedItem = #self.Items
end
for i, item in pairs(self.Items) do
item.gui.BackgroundTransparency = i == self.SelectedItem and 0.5 or 1
end
Gui.CanvasPosition = Vector2.new(
0,
math.max(
0,
Title.Size.Y.Offset
+ Description.Size.Y.Offset
+ self.SelectedItem * AutoItem.Size.Y.Offset
- Gui.Size.Y.Offset
)
)
if self.Items[self.SelectedItem] and self.Items[self.SelectedItem].options then
UpdateInfoDisplay(self.Items[self.SelectedItem].options or {})
end
end
Gui.Parent:GetPropertyChangedSignal("AbsoluteSize"):Connect(UpdateContainerSize)
return AutoComplete
end
- Edit
03:12:20.498
- Edit
03:12:20.498
============================== - Edit
03:12:20.498 📜 ServerScriptService.Cmdr.CmdrClient.CmdrInterface.Window - Edit
03:12:20.498 ==============================
- Edit
03:12:20.499 -- Here be dragons
-- luacheck: ignore 212
local GuiService = game:GetService("GuiService")
local UserInputService = game:GetService("UserInputService")
local TextChatService = game:GetService("TextChatService")
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local WINDOW_MAX_HEIGHT = 300
local MOUSE_TOUCH_ENUM = { Enum.UserInputType.MouseButton1, Enum.UserInputType.MouseButton2, Enum.UserInputType.Touch }
--- Window handles the command bar GUI
local Window = {
Valid = true,
AutoComplete = nil,
ProcessEntry = nil,
OnTextChanged = nil,
Cmdr = nil,
HistoryState = nil,
}
local Gui = Player:WaitForChild("PlayerGui"):WaitForChild("Cmdr"):WaitForChild("Frame")
local Line = Gui:WaitForChild("Line")
local Entry = Gui:WaitForChild("Entry")
Line.Parent = nil
--- Update the text entry label
function Window:UpdateLabel()
Entry.TextLabel.Text = Player.Name .. "@" .. self.Cmdr.PlaceName .. "$"
end
--- Get the text entry label
function Window:GetLabel()
return Entry.TextLabel.Text
end
--- Recalculate the window height
function Window:UpdateWindowHeight()
local windowHeight = Gui.UIListLayout.AbsoluteContentSize.Y
+ Gui.UIPadding.PaddingTop.Offset
+ Gui.UIPadding.PaddingBottom.Offset
Gui.Size = UDim2.new(Gui.Size.X.Scale, Gui.Size.X.Offset, 0, math.clamp(windowHeight, 0, WINDOW_MAX_HEIGHT))
Gui.CanvasPosition = Vector2.new(0, windowHeight)
end
--- Add a line to the command bar
function Window:AddLine(text, options)
options = options or {}
text = tostring(text)
if typeof(options) == "Color3" then
options = { Color = options }
end
if #text == 0 then
Window:UpdateWindowHeight()
return
end
local str = self.Cmdr.Util.EmulateTabstops(text or "nil", 8)
local line = Line:Clone()
line.Text = str
line.TextColor3 = options.Color or line.TextColor3
line.RichText = options.RichText or false
line.Parent = Gui
end
--- Returns if the command bar is visible
function Window:IsVisible()
return Gui.Visible
end
--- Sets the command bar visible or not
function Window:SetVisible(visible)
Gui.Visible = visible
if visible then
self.PreviousChatWindowConfigurationEnabled = TextChatService.ChatWindowConfiguration.Enabled
self.PreviousChatInputBarConfigurationEnabled = TextChatService.ChatInputBarConfiguration.Enabled
TextChatService.ChatWindowConfiguration.Enabled = false
TextChatService.ChatInputBarConfiguration.Enabled = false
Entry.TextBox:CaptureFocus()
self:SetEntryText("")
if self.Cmdr.ActivationUnlocksMouse then
self.PreviousMouseBehavior = UserInputService.MouseBehavior
UserInputService.MouseBehavior = Enum.MouseBehavior.Default
end
else
TextChatService.ChatWindowConfiguration.Enabled = if self.PreviousChatWindowConfigurationEnabled ~= nil then
self.PreviousChatWindowConfigurationEnabled else true
TextChatService.ChatInputBarConfiguration.Enabled = if self.PreviousChatInputBarConfigurationEnabled ~= nil then
self.PreviousChatInputBarConfigurationEnabled else true
Entry.TextBox:ReleaseFocus()
self.AutoComplete:Hide()
if self.PreviousMouseBehavior then
UserInputService.MouseBehavior = self.PreviousMouseBehavior
self.PreviousMouseBehavior = nil
end
end
end
--- Hides the command bar
function Window:Hide()
return self:SetVisible(false)
end
--- Shows the command bar
function Window:Show()
return self:SetVisible(true)
end
--- Sets the text in the command bar text box, and captures focus
function Window:SetEntryText(text)
Entry.TextBox.Text = text
if self:IsVisible() then
Entry.TextBox:CaptureFocus()
Entry.TextBox.CursorPosition = #text + 1
Window:UpdateWindowHeight()
end
end
--- Gets the text in the command bar text box
function Window:GetEntryText()
return Entry.TextBox.Text:gsub("\t", "")
end
--- Sets whether the command is in a valid state or not.
-- Cannot submit if in invalid state.
function Window:SetIsValidInput(isValid, errorText)
Entry.TextBox.TextColor3 = isValid and Color3.fromRGB(255, 255, 255) or Color3.fromRGB(255, 73, 73)
self.Valid = isValid
self._errorText = errorText
end
function Window:HideInvalidState()
Entry.TextBox.TextColor3 = Color3.fromRGB(255, 255, 255)
end
--- Event handler for text box focus lost
function Window:LoseFocus(submit)
local text = Entry.TextBox.Text
self:ClearHistoryState()
if Gui.Visible and not GuiService.MenuIsOpen then
-- self:SetEntryText("")
Entry.TextBox:CaptureFocus()
elseif GuiService.MenuIsOpen and Gui.Visible then
self:Hide()
end
if submit and self.Valid then
wait()
self:SetEntryText("")
self.ProcessEntry(text)
elseif submit then
self:AddLine(self._errorText, Color3.fromRGB(255, 153, 153))
end
end
function Window:TraverseHistory(delta)
local history = self.Cmdr.Dispatcher:GetHistory()
if self.HistoryState == nil then
self.HistoryState = {
Position = #history + 1,
InitialText = self:GetEntryText(),
}
end
self.HistoryState.Position = math.clamp(self.HistoryState.Position + delta, 1, #history + 1)
self:SetEntryText(
self.HistoryState.Position == #history + 1 and self.HistoryState.InitialText
or history[self.HistoryState.Position]
)
end
function Window:ClearHistoryState()
self.HistoryState = nil
end
function Window:SelectVertical(delta)
if self.AutoComplete:IsVisible() and not self.HistoryState then
self.AutoComplete:Select(delta)
else
self:TraverseHistory(delta)
end
end
local lastPressTime = 0
local pressCount = 0
--- Handles user input when the box is focused
function Window:BeginInput(input, gameProcessed)
if GuiService.MenuIsOpen then
self:Hide()
end
if gameProcessed and self:IsVisible() == false then
return
end
if self.Cmdr.ActivationKeys[input.KeyCode] then -- Activate the command bar
if self.Cmdr.MashToEnable and not self.Cmdr.Enabled then
if tick() - lastPressTime < 1 then
if pressCount >= 5 then
return self.Cmdr:SetEnabled(true)
else
pressCount = pressCount + 1
end
else
pressCount = 1
end
lastPressTime = tick()
elseif self.Cmdr.Enabled then
self:SetVisible(not self:IsVisible())
wait()
self:SetEntryText("")
if GuiService.MenuIsOpen then -- Special case for menu getting stuck open (roblox bug)
self:Hide()
end
end
return
end
if self.Cmdr.Enabled == false or not self:IsVisible() then
if self:IsVisible() then
self:Hide()
end
return
end
if self.Cmdr.HideOnLostFocus and table.find(MOUSE_TOUCH_ENUM, input.UserInputType) then
local ps = input.Position
local ap = Gui.AbsolutePosition
local as = Gui.AbsoluteSize
if ps.X < ap.X or ps.X > ap.X + as.X or ps.Y < ap.Y or ps.Y > ap.Y + as.Y then
self:Hide()
end
elseif input.KeyCode == Enum.KeyCode.Down then -- Auto Complete Down
self:SelectVertical(1)
elseif input.KeyCode == Enum.KeyCode.Up then -- Auto Complete Up
self:SelectVertical(-1)
elseif input.KeyCode == Enum.KeyCode.Return then -- Eat new lines
wait()
self:SetEntryText(self:GetEntryText():gsub("\n", ""):gsub("\r", ""))
elseif input.KeyCode == Enum.KeyCode.Tab then -- Auto complete
local item = self.AutoComplete:GetSelectedItem()
local text = self:GetEntryText()
if item and not (text:sub(#text, #text):match("%s") and self.AutoComplete.LastItem) then
local replace = item[2]
local newText
local insertSpace = true
local command = self.AutoComplete.Command
if command then
local lastArg = self.AutoComplete.Arg
newText = command.Alias
insertSpace = self.AutoComplete.NumArgs ~= #command.ArgumentDefinitions
and self.AutoComplete.IsPartial == false
local args = command.Arguments
for i = 1, #args do
local arg = args[i]
local segments = arg.RawSegments
if arg == lastArg then
segments[#segments] = replace
end
local argText = arg.Prefix .. table.concat(segments, ",")
-- Put auto completion options in quotation marks if they have a space
if argText:find(" ") or argText == "" then
argText = ("%q"):format(argText)
end
newText = ("%s %s"):format(newText, argText)
if arg == lastArg then
break
end
end
else
newText = replace
end
-- need to wait a frame so we can eat the \t
wait()
-- Update the text box
self:SetEntryText(newText .. (insertSpace and " " or ""))
else
-- Still need to eat the \t even if there is no auto-complete to show
wait()
self:SetEntryText(self:GetEntryText())
end
else
self:ClearHistoryState()
end
end
-- Hook events
Entry.TextBox.FocusLost:Connect(function(submit)
return Window:LoseFocus(submit)
end)
UserInputService.InputBegan:Connect(function(input, gameProcessed)
return Window:BeginInput(input, gameProcessed)
end)
Entry.TextBox:GetPropertyChangedSignal("Text"):Connect(function()
Gui.CanvasPosition = Vector2.new(0, Gui.AbsoluteCanvasSize.Y)
if Entry.TextBox.Text:match("\t") then -- Eat \t
Entry.TextBox.Text = Entry.TextBox.Text:gsub("\t", "")
return
end
if Window.OnTextChanged then
return Window.OnTextChanged(Entry.TextBox.Text)
end
end)
Gui.ChildAdded:Connect(function()
task.defer(Window.UpdateWindowHeight)
end)
return Window
- Edit
03:12:20.499
- Edit
03:12:20.499
============================== - Edit
03:12:20.499 📜 ServerScriptService.Cmdr.CmdrClient.DefaultEventHandlers - Edit
03:12:20.499 ==============================
- Edit
03:12:20.499 local StarterGui = game:GetService("StarterGui")
local Window = require(script.Parent.CmdrInterface.Window)
return function (Cmdr)
Cmdr:HandleEvent("Message", function (text)
StarterGui:SetCore("ChatMakeSystemMessage", {
Text = ("[Announcement] %s"):format(text);
Color = Color3.fromRGB(249, 217, 56);
})
end)
Cmdr:HandleEvent("AddLine", function (...)
Window:AddLine(...)
end)
end - Edit
03:12:20.499
- Edit
03:12:20.499
============================== - Edit
03:12:20.499 📜 ServerScriptService.Cmdr.CreateGui - Edit
03:12:20.499 ==============================
- Edit
03:12:20.499 return function()
local Cmdr = Instance.new("ScreenGui")
Cmdr.DisplayOrder = 1000
Cmdr.Name = "Cmdr"
Cmdr.ResetOnSpawn = false
Cmdr.AutoLocalize = false
local Frame = Instance.new("ScrollingFrame")
Frame.BackgroundColor3 = Color3.fromRGB(17, 17, 17)
Frame.BackgroundTransparency = 0.4
Frame.BorderSizePixel = 0
Frame.CanvasSize = UDim2.new(0, 0, 0, 0)
Frame.Name = "Frame"
Frame.Position = UDim2.new(0.025, 0, 0, 25)
Frame.ScrollBarThickness = 6
Frame.ScrollingDirection = Enum.ScrollingDirection.Y
Frame.Selectable = false
Frame.Size = UDim2.new(0.95, 0, 0, 0)
Frame.Visible = false
Frame.AutomaticCanvasSize = Enum.AutomaticSize.Y
Frame.Parent = Cmdr
local Autocomplete = Instance.new("ScrollingFrame")
Autocomplete.BackgroundColor3 = Color3.fromRGB(59, 59, 59)
Autocomplete.BackgroundTransparency = 0.5
Autocomplete.BorderSizePixel = 0
Autocomplete.CanvasSize = UDim2.new(0, 0, 0, 0)
Autocomplete.Name = "Autocomplete"
Autocomplete.Position = UDim2.new(0, 167, 0, 75)
Autocomplete.ScrollBarThickness = 6
Autocomplete.ScrollingDirection = Enum.ScrollingDirection.Y
Autocomplete.Selectable = false
Autocomplete.Size = UDim2.new(0, 200, 0, 200)
Autocomplete.Visible = false
Autocomplete.AutomaticCanvasSize = Enum.AutomaticSize.Y
Autocomplete.Parent = Cmdr
local UIListLayout = Instance.new("UIListLayout")
UIListLayout.SortOrder = Enum.SortOrder.LayoutOrder
UIListLayout.Parent = Frame
local Line = Instance.new("TextBox")
Line.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
Line.BackgroundTransparency = 1
Line.Font = Enum.Font.Code
Line.Name = "Line"
Line.Size = UDim2.new(1, 0, 0, 20)
Line.AutomaticSize = Enum.AutomaticSize.Y
Line.TextColor3 = Color3.fromRGB(255, 255, 255)
Line.TextSize = 14
Line.TextXAlignment = Enum.TextXAlignment.Left
Line.TextEditable = false
Line.ClearTextOnFocus = false
Line.Parent = Frame
local UIPadding = Instance.new("UIPadding")
UIPadding.PaddingBottom = UDim.new(0, 10)
UIPadding.PaddingLeft = UDim.new(0, 10)
UIPadding.PaddingRight = UDim.new(0, 10)
UIPadding.PaddingTop = UDim.new(0, 10)
UIPadding.Parent = Frame
local Entry = Instance.new("Frame")
Entry.BackgroundTransparency = 1
Entry.LayoutOrder = 999999999
Entry.Name = "Entry"
Entry.Size = UDim2.new(1, 0, 0, 20)
Entry.Parent = Frame
local UIListLayout2 = Instance.new("UIListLayout")
UIListLayout2.SortOrder = Enum.SortOrder.LayoutOrder
UIListLayout2.Parent = Autocomplete
local Title = Instance.new("Frame")
Title.BackgroundColor3 = Color3.fromRGB(59, 59, 59)
Title.BackgroundTransparency = 0.2
Title.BorderSizePixel = 0
Title.LayoutOrder = -2
Title.Name = "Title"
Title.Size = UDim2.new(1, 0, 0, 40)
Title.Parent = Autocomplete
local Description = Instance.new("Frame")
Description.BackgroundColor3 = Color3.fromRGB(59, 59, 59)
Description.BackgroundTransparency = 0.2
Description.BorderSizePixel = 0
Description.LayoutOrder = -1
Description.Name = "Description"
Description.Size = UDim2.new(1, 0, 0, 20)
Description.Parent = Autocomplete
local TextButton = Instance.new("TextButton")
TextButton.BackgroundColor3 = Color3.fromRGB(59, 59, 59)
TextButton.BackgroundTransparency = 0.5
TextButton.BorderSizePixel = 0
TextButton.Font = Enum.Font.Code
TextButton.Size = UDim2.new(1, 0, 0, 30)
TextButton.Text = ""
TextButton.TextColor3 = Color3.fromRGB(255, 255, 255)
TextButton.TextSize = 14
TextButton.TextXAlignment = Enum.TextXAlignment.Left
TextButton.Parent = Autocomplete
local UIListLayout3 = Instance.new("UIListLayout")
UIListLayout3.FillDirection = Enum.FillDirection.Horizontal
UIListLayout3.SortOrder = Enum.SortOrder.LayoutOrder
UIListLayout3.Padding = UDim.new(0, 7)
UIListLayout3.Parent = Entry
local TextBox = Instance.new("TextBox")
TextBox.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
TextBox.BackgroundTransparency = 1
TextBox.ClearTextOnFocus = false
TextBox.Font = Enum.Font.Code
TextBox.LayoutOrder = 999999999
TextBox.Position = UDim2.new(0, 140, 0, 0)
TextBox.Size = UDim2.new(1, 0, 0, 20)
TextBox.Text = "x"
TextBox.TextColor3 = Color3.fromRGB(255, 255, 255)
TextBox.TextSize = 14
TextBox.TextXAlignment = Enum.TextXAlignment.Left
TextBox.Selectable = false
TextBox.Parent = Entry
local TextLabel = Instance.new("TextLabel")
TextLabel.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
TextLabel.BackgroundTransparency = 1
TextLabel.Font = Enum.Font.Code
TextLabel.Size = UDim2.new(0, 0, 0, 20)
TextLabel.AutomaticSize = Enum.AutomaticSize.X
TextLabel.Text = ""
TextLabel.TextColor3 = Color3.fromRGB(255, 223, 93)
TextLabel.TextSize = 14
TextLabel.TextXAlignment = Enum.TextXAlignment.Left
TextLabel.Parent = Entry
local Field = Instance.new("TextLabel")
Field.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
Field.BackgroundTransparency = 1
Field.Font = Enum.Font.SourceSansBold
Field.Name = "Field"
Field.Size = UDim2.new(0, 37, 1, 0)
Field.Text = "from"
Field.TextColor3 = Color3.fromRGB(255, 255, 255)
Field.TextSize = 20
Field.TextXAlignment = Enum.TextXAlignment.Left
Field.Parent = Title
local UIPadding2 = Instance.new("UIPadding")
UIPadding2.PaddingLeft = UDim.new(0, 10)
UIPadding2.Parent = Title
local Label = Instance.new("TextLabel")
Label.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
Label.BackgroundTransparency = 1
Label.Font = Enum.Font.SourceSansLight
Label.Name = "Label"
Label.Size = UDim2.new(1, 0, 1, 0)
Label.Text = "The players to teleport. The players to teleport. The players to teleport. The players to teleport. "
Label.TextColor3 = Color3.fromRGB(255, 255, 255)
Label.TextSize = 16
Label.TextWrapped = true
Label.TextXAlignment = Enum.TextXAlignment.Left
Label.TextYAlignment = Enum.TextYAlignment.Top
Label.Parent = Description
local UIPadding3 = Instance.new("UIPadding")
UIPadding3.PaddingBottom = UDim.new(0, 10)
UIPadding3.PaddingLeft = UDim.new(0, 10)
UIPadding3.PaddingRight = UDim.new(0, 10)
UIPadding3.Parent = Description
local Typed = Instance.new("TextLabel")
Typed.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
Typed.BackgroundTransparency = 1
Typed.Font = Enum.Font.Code
Typed.Name = "Typed"
Typed.Size = UDim2.new(1, 0, 1, 0)
Typed.Text = "Lab"
Typed.TextColor3 = Color3.fromRGB(131, 222, 255)
Typed.TextSize = 14
Typed.TextXAlignment = Enum.TextXAlignment.Left
Typed.Parent = TextButton
local UIPadding4 = Instance.new("UIPadding")
UIPadding4.PaddingLeft = UDim.new(0, 10)
UIPadding4.Parent = TextButton
local Suggest = Instance.new("TextLabel")
Suggest.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
Suggest.BackgroundTransparency = 1
Suggest.Font = Enum.Font.Code
Suggest.Name = "Suggest"
Suggest.Size = UDim2.new(1, 0, 1, 0)
Suggest.Text = " el"
Suggest.TextColor3 = Color3.fromRGB(255, 255, 255)
Suggest.TextSize = 14
Suggest.TextXAlignment = Enum.TextXAlignment.Left
Suggest.Parent = TextButton
local Type = Instance.new("TextLabel")
Type.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
Type.BackgroundTransparency = 1
Type.BorderColor3 = Color3.fromRGB(255, 153, 153)
Type.Font = Enum.Font.SourceSans
Type.Name = "Type"
Type.Position = UDim2.new(1, 0, 0, 0)
Type.Size = UDim2.new(0, 0, 1, 0)
Type.Text = ": Players"
Type.TextColor3 = Color3.fromRGB(255, 255, 255)
Type.TextSize = 15
Type.TextXAlignment = Enum.TextXAlignment.Left
Type.Parent = Field
Cmdr.Parent = game:GetService("StarterGui")
return Cmdr
end
- Edit
03:12:20.499
- Edit
03:12:20.499
============================== - Edit
03:12:20.499 📜 ServerScriptService.Cmdr.Initialize - Edit
03:12:20.499 ==============================
- Edit
03:12:20.500 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local StarterGui = game:GetService("StarterGui")
local CreateGui = require(script.Parent.CreateGui)
--- Handles initial preparation of the game server-side.
return function (cmdr)
local ReplicatedRoot, RemoteFunction, RemoteEvent
local function Create (class, name, parent)
local object = Instance.new(class)
object.Name = name
object.Parent = parent or ReplicatedRoot
return object
end
ReplicatedRoot = script.Parent.CmdrClient
ReplicatedRoot.Parent = ReplicatedStorage
RemoteFunction = Create("RemoteFunction", "CmdrFunction")
RemoteEvent = Create("RemoteEvent", "CmdrEvent")
Create("Folder", "Commands")
Create("Folder", "Types")
script.Parent.Shared.Parent = ReplicatedRoot
cmdr.ReplicatedRoot = ReplicatedRoot
cmdr.RemoteFunction = RemoteFunction
cmdr.RemoteEvent = RemoteEvent
cmdr:RegisterTypesIn(script.Parent.BuiltInTypes)
script.Parent.BuiltInTypes:Destroy()
script.Parent.BuiltInCommands.Name = "Server commands"
if StarterGui:FindFirstChild("Cmdr") == nil then
CreateGui()
end
end
- Edit
03:12:20.500
- Edit
03:12:20.500
============================== - Edit
03:12:20.500 📜 ServerScriptService.Cmdr.Shared.Argument - Edit
03:12:20.500 ==============================
- Edit
03:12:20.500 local Util = require(script.Parent.Util)
local function unescapeOperators(text)
for _, operator in ipairs({"%.", "%?", "%*", "%*%*"}) do
text = text:gsub("\\" .. operator, operator:gsub("%%", ""))
end
return text
end
local Argument = {}
Argument.__index = Argument
--- Returns a new ArgumentContext, an object that handles parsing and validating arguments
function Argument.new (command, argumentObject, value)
local self = {
Command = command; -- The command that owns this argument
Type = nil; -- The type definition
Name = argumentObject.Name; -- The name for this specific argument
Object = argumentObject; -- The raw ArgumentObject (definition)
Required = argumentObject.Default == nil and argumentObject.Optional ~= true; -- If the argument is required or not.
Executor = command.Executor; -- The player who is running the command
RawValue = value; -- The raw, unparsed value
RawSegments = {}; -- The raw, unparsed segments (if the raw value was comma-sep)
TransformedValues = {}; -- The transformed value (generated later)
Prefix = ""; -- The prefix for this command (%Team)
TextSegmentInProgress = ""; -- The text of the raw segment the user is currently typing.
RawSegmentsAreAutocomplete = false;
}
if type(argumentObject.Type) == "table" then
self.Type = argumentObject.Type
else
local parsedType, parsedRawValue, prefix = Util.ParsePrefixedUnionType(
command.Cmdr.Registry:GetTypeName(argumentObject.Type),
value
)
self.Type = command.Dispatcher.Registry:GetType(parsedType)
self.RawValue = parsedRawValue
self.Prefix = prefix
if self.Type == nil then
error(string.format("%s has an unregistered type %q", self.Name or "", parsedType or ""))
end
end
setmetatable(self, Argument)
self:Transform()
return self
end
function Argument:GetDefaultAutocomplete()
if self.Type.Autocomplete then
local strings, options = self.Type.Autocomplete(self:TransformSegment(""))
return strings, options or {}
end
return {}
end
--- Calls the transform function on this argument.
-- The return value(s) from this function are passed to all of the other argument methods.
-- Called automatically at instantiation
function Argument:Transform()
if #self.TransformedValues ~= 0 then
return
end
local rawValue = self.RawValue
if self.Type.ArgumentOperatorAliases then
rawValue = self.Type.ArgumentOperatorAliases[rawValue] or rawValue
end
if rawValue == "." and self.Type.Default then
rawValue = self.Type.Default(self.Executor) or ""
self.RawSegmentsAreAutocomplete = true
end
if rawValue == "?" and self.Type.Autocomplete then
local strings, options = self:GetDefaultAutocomplete()
if not options.IsPartial and #strings > 0 then
rawValue = strings[math.random(1, #strings)]
self.RawSegmentsAreAutocomplete = true
end
end
if self.Type.Listable and #self.RawValue > 0 then
local randomMatch = rawValue:match("^%?(%d+)$")
if randomMatch then
local maxSize = tonumber(randomMatch)
if maxSize and maxSize > 0 then
local items = {}
local remainingItems, options = self:GetDefaultAutocomplete()
if not options.IsPartial and #remainingItems > 0 then
for _ = 1, math.min(maxSize, #remainingItems) do
table.insert(items, table.remove(remainingItems, math.random(1, #remainingItems)))
end
rawValue = table.concat(items, ",")
self.RawSegmentsAreAutocomplete = true
end
end
elseif rawValue == "*" or rawValue == "**" then
local strings, options = self:GetDefaultAutocomplete()
if not options.IsPartial and #strings > 0 then
if rawValue == "**" and self.Type.Default then
local defaultString = self.Type.Default(self.Executor) or ""
for i, string in ipairs(strings) do
if string == defaultString then
table.remove(strings, i)
end
end
end
rawValue = table.concat(
strings,
","
)
self.RawSegmentsAreAutocomplete = true
end
end
rawValue = unescapeOperators(rawValue)
local rawSegments = Util.SplitStringSimple(rawValue, ",")
if #rawSegments == 0 then
rawSegments = {""}
end
if rawValue:sub(#rawValue, #rawValue) == "," then
rawSegments[#rawSegments + 1] = "" -- makes auto complete tick over right after pressing ,
end
for i, rawSegment in ipairs(rawSegments) do
self.RawSegments[i] = rawSegment
self.TransformedValues[i] = { self:TransformSegment(rawSegment) }
end
self.TextSegmentInProgress = rawSegments[#rawSegments]
else
rawValue = unescapeOperators(rawValue)
self.RawSegments[1] = unescapeOperators(rawValue)
self.TransformedValues[1] = { self:TransformSegment(rawValue) }
self.TextSegmentInProgress = self.RawValue
end
end
function Argument:TransformSegment(rawSegment)
if self.Type.Transform then
return self.Type.Transform(rawSegment, self.Executor)
else
return rawSegment
end
end
--- Returns whatever the Transform method gave us.
function Argument:GetTransformedValue(segment)
return unpack(self.TransformedValues[segment])
end
--- Validates that the argument will work without any type errors.
function Argument:Validate(isFinal)
if self.RawValue == nil or #self.RawValue == 0 and self.Required == false then
return true
end
if self.Required and (self.RawSegments[1] == nil or #self.RawSegments[1] == 0) then
return false, "This argument is required."
end
if self.Type.Validate or self.Type.ValidateOnce then
for i = 1, #self.TransformedValues do
if self.Type.Validate then
local valid, errorText = self.Type.Validate(self:GetTransformedValue(i))
if not valid then
return valid, errorText or "Invalid value"
end
end
if isFinal and self.Type.ValidateOnce then
local validOnce, errorTextOnce = self.Type.ValidateOnce(self:GetTransformedValue(i))
if not validOnce then
return validOnce, errorTextOnce
end
end
end
return true
else
return true
end
end
--- Gets a list of all possible values that could match based on the current value.
function Argument:GetAutocomplete()
if self.Type.Autocomplete then
return self.Type.Autocomplete(self:GetTransformedValue(#self.TransformedValues))
else
return {}
end
end
function Argument:ParseValue(i)
if self.Type.Parse then
return self.Type.Parse(self:GetTransformedValue(i))
else
return self:GetTransformedValue(i)
end
end
--- Returns the final value of the argument.
function Argument:GetValue()
if #self.RawValue == 0 and not self.Required and self.Object.Default ~= nil then
return self.Object.Default
end
if not self.Type.Listable then
return self:ParseValue(1)
end
local values = {}
for i = 1, #self.TransformedValues do
local parsedValue = self:ParseValue(i)
if type(parsedValue) ~= "table" then
error(("Listable types must return a table from Parse (%s)"):format(self.Type.Name))
end
for _, value in pairs(parsedValue) do
values[value] = true -- Put them into a dictionary to ensure uniqueness
end
end
local valueArray = {}
for value in pairs(values) do
valueArray[#valueArray + 1] = value
end
return valueArray
end
return Argument
- Edit
03:12:20.500
- Edit
03:12:20.500
============================== - Edit
03:12:20.500 📜 ServerScriptService.Cmdr.Shared.Command - Edit
03:12:20.500 ==============================
- Edit
03:12:20.500 local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local Argument = require(script.Parent.Argument)
local IsServer = RunService:IsServer()
local Command = {}
Command.__index = Command
--- Returns a new CommandContext, an object which is created for every command validation.
-- This is also what's passed as the context to the "Run" functions in commands
function Command.new (options)
local self = {
Dispatcher = options.Dispatcher; -- The dispatcher that created this command context
Cmdr = options.Dispatcher.Cmdr; -- A quick reference to Cmdr for command context
Name = options.CommandObject.Name; -- The command name (not alias)
RawText = options.Text; -- The raw text used to trigger this command
Object = options.CommandObject; -- The command object (definition)
Group = options.CommandObject.Group; -- The group this command is in
State = {}; -- A table which will hold any custom command state information
Aliases = options.CommandObject.Aliases;
Alias = options.Alias; -- The command name that was used
Description = options.CommandObject.Description;
Executor = options.Executor; -- The player who ran the command
ArgumentDefinitions = options.CommandObject.Args; -- The argument definitions from the command definition
RawArguments = options.Arguments; -- Array of strings which are the unparsed values for the arguments
Arguments = {}; -- A table which will hold ArgumentContexts for each argument
Data = options.Data; -- A special container for any additional data the command needs to collect from the client
Response = nil; -- Will be set at the very end when the command is run and a string is returned from the Run function.
}
setmetatable(self, Command)
return self
end
--- Parses all of the command arguments into ArgumentContexts
-- Called by the command dispatcher automatically
-- allowIncompleteArguments: if true, will not throw an error for missing arguments
function Command:Parse (allowIncompleteArguments)
local hadOptional = false
for i, definition in ipairs(self.ArgumentDefinitions) do
if type(definition) == "function" then
definition = definition(self)
if definition == nil then
break
end
end
local required = (definition.Default == nil and definition.Optional ~= true)
if required and hadOptional then
error(("Command %q: Required arguments cannot occur after optional arguments."):format(self.Name))
elseif not required then
hadOptional = true
end
if self.RawArguments[i] == nil and required and allowIncompleteArguments ~= true then
return false, ("Required argument #%d %s is missing."):format(i, definition.Name)
elseif self.RawArguments[i] or allowIncompleteArguments then
self.Arguments[i] = Argument.new(self, definition, self.RawArguments[i] or "")
end
end
return true
end
--- Validates that all of the arguments are in a valid state.
-- This must be called before :Run() is called.
-- Returns boolean (true if ok), errorText
function Command:Validate (isFinal)
self._Validated = true
local errorText = ""
local success = true
for i, arg in pairs(self.Arguments) do
local argSuccess, argErrorText = arg:Validate(isFinal)
if not argSuccess then
success = false
errorText = ("%s; #%d %s: %s"):format(errorText, i, arg.Name, argErrorText or "error")
end
end
return success, errorText:sub(3)
end
--- Returns the last argument that has a value.
-- Useful for getting the autocomplete for the argument the user is working on.
function Command:GetLastArgument()
for i = #self.Arguments, 1, -1 do
if self.Arguments[i].RawValue then
return self.Arguments[i]
end
end
end
--- Returns a table containing the parsed values for all of the arguments.
function Command:GatherArgumentValues ()
local values = {}
for i = 1, #self.ArgumentDefinitions do
local arg = self.Arguments[i]
if arg then
values[i] = arg:GetValue()
elseif type(self.ArgumentDefinitions[i]) == "table" then
values[i] = self.ArgumentDefinitions[i].Default
end
end
return values, #self.ArgumentDefinitions
end
--- Runs the command. Handles dispatching to the server if necessary.
-- Command:Validate() must be called before this is called or it will throw.
function Command:Run ()
if self._Validated == nil then
error("Must validate a command before running.")
end
local beforeRunHook = self.Dispatcher:RunHooks("BeforeRun", self)
if beforeRunHook then
return beforeRunHook
end
if not IsServer and self.Object.Data and self.Data == nil then
local values, length = self:GatherArgumentValues()
self.Data = self.Object.Data(self, unpack(values, 1, length))
end
if not IsServer and self.Object.ClientRun then
local values, length = self:GatherArgumentValues()
self.Response = self.Object.ClientRun(self, unpack(values, 1, length))
end
if self.Response == nil then
if self.Object.Run then -- We can just Run it here on this machine
local values, length = self:GatherArgumentValues()
self.Response = self.Object.Run(self, unpack(values, 1, length))
elseif IsServer then -- Uh oh, we're already on the server and there's no Run function.
if self.Object.ClientRun then
warn(self.Name, "command fell back to the server because ClientRun returned nil, but there is no server implementation! Either return a string from ClientRun, or create a server implementation for this command.")
else
warn(self.Name, "command has no implementation!")
end
self.Response = "No implementation."
else -- We're on the client, so we send this off to the server to let the server see what it can do with it.
self.Response = self.Dispatcher:Send(self.RawText, self.Data)
end
end
local afterRunHook = self.Dispatcher:RunHooks("AfterRun", self)
if afterRunHook then
return afterRunHook
else
return self.Response
end
end
--- Returns an ArgumentContext for the specific index
function Command:GetArgument (index)
return self.Arguments[index]
end
-- Below are functions that are only meant to be used in command implementations --
--- Returns the extra data associated with this command.
-- This needs to be used instead of just context.Data for reliability when not using a remote command.
function Command:GetData ()
if self.Data then
return self.Data
end
if self.Object.Data and not IsServer then
self.Data = self.Object.Data(self)
end
return self.Data
end
--- Sends an event message to a player
function Command:SendEvent(player, event, ...)
assert(typeof(player) == "Instance", "Argument #1 must be a Player")
assert(player:IsA("Player"), "Argument #1 must be a Player")
assert(type(event) == "string", "Argument #2 must be a string")
if IsServer then
self.Dispatcher.Cmdr.RemoteEvent:FireClient(player, event, ...)
elseif self.Dispatcher.Cmdr.Events[event] then
assert(player == Players.LocalPlayer, "Event messages can only be sent to the local player on the client.")
self.Dispatcher.Cmdr.Events[event](...)
end
end
--- Sends an event message to all players
function Command:BroadcastEvent(...)
if not IsServer then
error("Can't broadcast event messages from the client.", 2)
end
self.Dispatcher.Cmdr.RemoteEvent:FireAllClients(...)
end
--- Alias of self:SendEvent(self.Executor, "AddLine", text)
function Command:Reply(...)
return self:SendEvent(self.Executor, "AddLine", ...)
end
--- Alias of Registry:GetStore(...)
function Command:GetStore(...)
return self.Dispatcher.Cmdr.Registry:GetStore(...)
end
--- Returns true if the command has an implementation on the caller's machine.
function Command:HasImplementation()
return ((RunService:IsClient() and self.Object.ClientRun) or self.Object.Run) and true or false
end
return Command
- Edit
03:12:20.500
- Edit
03:12:20.500
============================== - Edit
03:12:20.500 📜 ServerScriptService.Cmdr.Shared.Dispatcher - Edit
03:12:20.500 ==============================
- Edit
03:12:20.500 local RunService = game:GetService("RunService")
local TeleportService = game:GetService("TeleportService")
local Players = game:GetService("Players")
local Util = require(script.Parent.Util)
local Command = require(script.Parent.Command)
local HISTORY_SETTING_NAME = "CmdrCommandHistory"
local displayedBeforeRunHookWarning = false
--- The dispatcher handles creating and running commands during the game.
local Dispatcher = {
Cmdr = nil;
Registry = nil;
}
--- Takes in raw command information and generates a command out of it.
-- text and executor are required arguments.
-- allowIncompleteData, when true, will ignore errors about arguments missing so we can parse live as the user types.
-- data is for special networked Data about the command gathered on the client. Purely Optional.
-- returns the command if successful, or (false, errorText) if not
function Dispatcher:Evaluate (text, executor, allowIncompleteArguments, data)
if RunService:IsClient() == true and executor ~= Players.LocalPlayer then
error("Can't evaluate a command that isn't sent by the local player.")
end
local arguments = Util.SplitString(text)
local commandName = table.remove(arguments, 1)
local commandObject = self.Registry:GetCommand(commandName)
if commandObject then
-- No need to continue splitting when there are no more arguments. We'll just mash any additional arguments into the last one.
arguments = Util.MashExcessArguments(arguments, #commandObject.Args)
-- Create the CommandContext and parse it.
local command = Command.new({
Dispatcher = self,
Text = text,
CommandObject = commandObject,
Alias = commandName,
Executor = executor,
Arguments = arguments,
Data = data
})
local success, errorText = command:Parse(allowIncompleteArguments)
if success then
return command
else
return false, errorText
end
else
return false, ("%q is not a valid command name. Use the help command to see all available commands."):format(tostring(commandName))
end
end
--- A helper that evaluates and runs the command in one go.
-- Either returns any validation errors as a string, or the output of the command as a string. Definitely a string, though.
function Dispatcher:EvaluateAndRun (text, executor, options)
executor = executor or Players.LocalPlayer
options = options or {}
if RunService:IsClient() and options.IsHuman then
self:PushHistory(text)
end
local command, errorText = self:Evaluate(text, executor, nil, options.Data)
if not command then
return errorText
end
local ok, out = xpcall(function()
local valid, errorText = command:Validate(true) -- luacheck: ignore
if not valid then
return errorText
end
return command:Run() or "Command executed."
end, function(value)
return debug.traceback(tostring(value))
end)
if not ok then
warn(("Error occurred while evaluating command string %q\n%s"):format(text, tostring(out)))
end
return ok and out or "An error occurred while running this command. Check the console for more information."
end
--- Send text as the local user to remote server to be evaluated there.
function Dispatcher:Send (text, data)
if RunService:IsClient() == false then
error("Dispatcher:Send can only be called from the client.")
end
return self.Cmdr.RemoteFunction:InvokeServer(text, {
Data = data
})
end
--- Invoke a command programmatically as the local user e.g. from a settings menu
-- Command should be the first argument, all arguments afterwards should be the arguments to the command.
function Dispatcher:Run (...)
if not Players.LocalPlayer then
error("Dispatcher:Run can only be called from the client.")
end
local args = {...}
local text = args[1]
for i = 2, #args do
text = text .. " " .. tostring(args[i])
end
local command, errorText = self:Evaluate(text, Players.LocalPlayer)
if not command then
error(errorText) -- We do a full-on error here since this is code-invoked and they should know better.
end
local success, errorText = command:Validate(true) -- luacheck: ignore
if not success then
error(errorText)
end
return command:Run()
end
--- Runs hooks matching name and returns nil for ok or a string for cancellation
function Dispatcher:RunHooks(hookName, commandContext, ...)
if not self.Registry.Hooks[hookName] then
error(("Invalid hook name: %q"):format(hookName), 2)
end
if
hookName == "BeforeRun"
and #self.Registry.Hooks[hookName] == 0
and commandContext.Group ~= "DefaultUtil"
and commandContext.Group ~= "UserAlias"
and commandContext:HasImplementation()
then
if RunService:IsStudio() then
if displayedBeforeRunHookWarning == false then
commandContext:Reply((RunService:IsServer() and "" or "") .. " Commands will not run in-game if no BeforeRun hook is configured. Learn more: https://eryn.io/Cmdr/guide/Hooks.html", Color3.fromRGB(255,228,26))
displayedBeforeRunHookWarning = true
end
else
return "Command blocked for security as no BeforeRun hook is configured."
end
end
for _, hook in ipairs(self.Registry.Hooks[hookName]) do
local value = hook.callback(commandContext, ...)
if value ~= nil then
return tostring(value)
end
end
end
function Dispatcher:PushHistory(text)
assert(RunService:IsClient(), "PushHistory may only be used from the client.")
local history = self:GetHistory()
-- Remove duplicates
if Util.TrimString(text) == "" or text == history[#history] then
return
end
history[#history + 1] = text
TeleportService:SetTeleportSetting(HISTORY_SETTING_NAME, history)
end
function Dispatcher:GetHistory()
assert(RunService:IsClient(), "GetHistory may only be used from the client.")
return TeleportService:GetTeleportSetting(HISTORY_SETTING_NAME) or {}
end
return function (cmdr)
Dispatcher.Cmdr = cmdr
Dispatcher.Registry = cmdr.Registry
return Dispatcher
end - Edit
03:12:20.500
- Edit
03:12:20.501
============================== - Edit
03:12:20.501 📜 ServerScriptService.Cmdr.Shared.Registry - Edit
03:12:20.501 ==============================
- Edit
03:12:20.501 local RunService = game:GetService("RunService")
local Util = require(script.Parent.Util)
--- The registry keeps track of all the commands and types that Cmdr knows about.
local Registry = {
TypeMethods = Util.MakeDictionary({"Transform", "Validate", "Autocomplete", "Parse", "DisplayName", "Listable", "ValidateOnce", "Prefixes", "Default", "ArgumentOperatorAliases"});
CommandMethods = Util.MakeDictionary({"Name", "Aliases", "AutoExec", "Description", "Args", "Run", "ClientRun", "Data", "Group"});
CommandArgProps = Util.MakeDictionary({"Name", "Type", "Description", "Optional", "Default"});
Types = {};
TypeAliases = {};
Commands = {};
CommandsArray = {};
Cmdr = nil;
Hooks = {
BeforeRun = {};
AfterRun = {}
};
Stores = setmetatable({}, {
__index = function (self, k)
self[k] = {}
return self[k]
end
});
AutoExecBuffer = {};
}
--- Registers a type in the system.
-- name: The type Name. This must be unique.
function Registry:RegisterType (name, typeObject)
if not name or typeof(name) ~= "string" then
error("Invalid type name provided: nil")
end
if not name:find("^[%d%l]%w*$") then
error(('Invalid type name provided: "%s", type names must be alphanumeric and start with a lower-case letter or a digit.'):format(name))
end
for key in pairs(typeObject) do
if self.TypeMethods[key] == nil then
error("Unknown key/method in type \"" .. name .. "\": " .. key)
end
end
if self.Types[name] ~= nil then
error(('Type "%s" has already been registered.'):format(name))
end
typeObject.Name = name
typeObject.DisplayName = typeObject.DisplayName or name
self.Types[name] = typeObject
if typeObject.Prefixes then
self:RegisterTypePrefix(name, typeObject.Prefixes)
end
end
function Registry:RegisterTypePrefix (name, union)
if not self.TypeAliases[name] then
self.TypeAliases[name] = name
end
self.TypeAliases[name] = ("%s %s"):format(self.TypeAliases[name], union)
end
function Registry:RegisterTypeAlias (name, alias)
assert(self.TypeAliases[name] == nil, ("Type alias %s already exists!"):format(alias))
self.TypeAliases[name] = alias
end
--- Helper method that registers types from all module scripts in a specific container.
function Registry:RegisterTypesIn (container)
for _, object in pairs(container:GetChildren()) do
if object:IsA("ModuleScript") then
object.Parent = self.Cmdr.ReplicatedRoot.Types
require(object)(self)
else
self:RegisterTypesIn(object)
end
end
end
-- These are exactly the same thing. No one will notice. Except for you, dear reader.
Registry.RegisterHooksIn = Registry.RegisterTypesIn
--- Registers a command based purely on its definition.
-- Prefer using Registry:RegisterCommand for proper handling of server/client model.
function Registry:RegisterCommandObject (commandObject, fromCmdr)
for key in pairs(commandObject) do
if self.CommandMethods[key] == nil then
error("Unknown key/method in command " .. (commandObject.Name or "unknown command") .. ": " .. key)
end
end
if commandObject.Args then
for i, arg in pairs(commandObject.Args) do
if type(arg) == "table" then
for key in pairs(arg) do
if self.CommandArgProps[key] == nil then
error(('Unknown property in command "%s" argument #%d: %s'):format(commandObject.Name or "unknown", i, key))
end
end
end
end
end
if commandObject.AutoExec and RunService:IsClient() then
table.insert(self.AutoExecBuffer, commandObject.AutoExec)
self:FlushAutoExecBufferDeferred()
end
-- Unregister the old command if it exists...
local oldCommand = self.Commands[commandObject.Name:lower()]
if oldCommand and oldCommand.Aliases then
for _, alias in pairs(oldCommand.Aliases) do
self.Commands[alias:lower()] = nil
end
elseif not oldCommand then
table.insert(self.CommandsArray, commandObject)
end
self.Commands[commandObject.Name:lower()] = commandObject
if commandObject.Aliases then
for _, alias in pairs(commandObject.Aliases) do
self.Commands[alias:lower()] = commandObject
end
end
end
--- Registers a command definition and its server equivalent.
-- Handles replicating the definition to the client.
function Registry:RegisterCommand(commandScript, commandServerScript, filter)
local commandObject = require(commandScript)
assert(
typeof(commandObject) == "table",
`Invalid return value from command script "{commandScript.Name}" (CommandDefinition expected, got {typeof(commandObject)})`
)
if commandServerScript then
assert(RunService:IsServer(), "The commandServerScript parameter is not valid for client usage.")
commandObject.Run = require(commandServerScript)
end
if filter and not filter(commandObject) then
return
end
self:RegisterCommandObject(commandObject)
commandScript.Parent = self.Cmdr.ReplicatedRoot.Commands
end
--- A helper method that registers all commands inside a specific container.
function Registry:RegisterCommandsIn (container, filter)
local skippedServerScripts = {}
local usedServerScripts = {}
for _, commandScript in pairs(container:GetChildren()) do
if commandScript:IsA("ModuleScript") then
if not commandScript.Name:find("Server") then
local serverCommandScript = container:FindFirstChild(commandScript.Name .. "Server")
if serverCommandScript then
usedServerScripts[serverCommandScript] = true
end
self:RegisterCommand(commandScript, serverCommandScript, filter)
else
skippedServerScripts[commandScript] = true
end
else
self:RegisterCommandsIn(commandScript, filter)
end
end
for skippedScript in pairs(skippedServerScripts) do
if not usedServerScripts[skippedScript] then
warn("Command script " .. skippedScript.Name .. " was skipped because it has 'Server' in its name, and has no equivalent shared script.")
end
end
end
--- Registers the default commands, with an optional filter function or array of groups.
function Registry:RegisterDefaultCommands (arrayOrFunc)
assert(RunService:IsServer(), "RegisterDefaultCommands cannot be called from the client.")
local isArray = type(arrayOrFunc) == "table"
if isArray then
arrayOrFunc = Util.MakeDictionary(arrayOrFunc)
end
self:RegisterCommandsIn(self.Cmdr.DefaultCommandsFolder, isArray and function (command)
return arrayOrFunc[command.Group] or false
end or arrayOrFunc)
end
--- Gets a command definition by name. (Can be an alias)
function Registry:GetCommand (name)
name = name or ""
return self.Commands[name:lower()]
end
--- Returns a unique array of all registered commands (not including aliases)
function Registry:GetCommands ()
return self.CommandsArray
end
--- Returns an array of the names of all registered commands (not including aliases)
function Registry:GetCommandNames ()
local commands = {}
for _, command in pairs(self.CommandsArray) do
table.insert(commands, command.Name)
end
return commands
end
Registry.GetCommandsAsStrings = Registry.GetCommandNames
--- Returns an array of the names of all registered types (not including aliases)
function Registry:GetTypeNames ()
local typeNames = {}
for typeName in pairs(self.Types) do
table.insert(typeNames, typeName)
end
return typeNames
end
--- Gets a type definition by name.
function Registry:GetType (name)
return self.Types[name]
end
--- Returns a type name, parsing aliases.
function Registry:GetTypeName (name)
return self.TypeAliases[name] or name
end
--- Adds a hook to be called when any command is run
function Registry:RegisterHook(hookName, callback, priority)
if not self.Hooks[hookName] then
error(("Invalid hook name: %q"):format(hookName), 2)
end
table.insert(self.Hooks[hookName], { callback = callback; priority = priority or 0; } )
table.sort(self.Hooks[hookName], function(a, b) return a.priority < b.priority end)
end
-- Backwards compatability (deprecated)
Registry.AddHook = Registry.RegisterHook
--- Returns the store with the given name
-- Used for commands that require persistent state, like bind or ban
function Registry:GetStore(name)
return self.Stores[name]
end
--- Calls self:FlushAutoExecBuffer at the end of the frame
function Registry:FlushAutoExecBufferDeferred()
if self.AutoExecFlushConnection then
return
end
self.AutoExecFlushConnection = RunService.Heartbeat:Connect(function()
self.AutoExecFlushConnection:Disconnect()
self.AutoExecFlushConnection = nil
self:FlushAutoExecBuffer()
end)
end
--- Runs all pending auto exec commands in Registry.AutoExecBuffer
function Registry:FlushAutoExecBuffer()
for _, commandGroup in ipairs(self.AutoExecBuffer) do
for _, command in ipairs(commandGroup) do
self.Cmdr.Dispatcher:EvaluateAndRun(command)
end
end
self.AutoExecBuffer = {}
end
return function (cmdr)
Registry.Cmdr = cmdr
return Registry
end
- Edit
03:12:20.501
- Edit
03:12:20.501
============================== - Edit
03:12:20.501 📜 ServerScriptService.Cmdr.Shared.Util - Edit
03:12:20.501 ==============================
- Edit
03:12:20.501 local TextService = game:GetService("TextService")
local Util = {}
--- Takes an array and flips its values into dictionary keys with value of true.
function Util.MakeDictionary(array)
local dictionary = {}
for i = 1, #array do
dictionary[array[i]] = true
end
return dictionary
end
--- Takes a dictionary and returns its keys.
function Util.DictionaryKeys(dict)
local keys = {}
for key in pairs(dict) do
table.insert(keys, key)
end
return keys
end
-- Takes an array of instances and returns (array, array)
local function transformInstanceSet(instances)
local names = {}
for i = 1, #instances do
names[i] = instances[i].Name
end
return names, instances
end
--- Returns a function that is a fuzzy finder for the specified set or container.
-- Can pass an array of strings, array of instances, array of EnumItems,
-- array of dictionaries with a Name key or an instance (in which case its children will be used)
-- Exact matches will be inserted in the front of the resulting array
function Util.MakeFuzzyFinder(setOrContainer)
local names
local instances = {}
if typeof(setOrContainer) == "Enum" then
setOrContainer = setOrContainer:GetEnumItems()
end
if typeof(setOrContainer) == "Instance" then
names, instances = transformInstanceSet(setOrContainer:GetChildren())
elseif typeof(setOrContainer) == "table" then
if
typeof(setOrContainer[1]) == "Instance" or typeof(setOrContainer[1]) == "EnumItem" or
(typeof(setOrContainer[1]) == "table" and typeof(setOrContainer[1].Name) == "string")
then
names, instances = transformInstanceSet(setOrContainer)
elseif type(setOrContainer[1]) == "string" then
names = setOrContainer
elseif setOrContainer[1] ~= nil then
error("MakeFuzzyFinder only accepts tables of instances or strings.")
else
names = {}
end
else
error("MakeFuzzyFinder only accepts a table, Enum, or Instance.")
end
-- Searches the set (checking exact matches first)
return function(text, returnFirst)
local results = {}
for i, name in pairs(names) do
local value = instances and instances[i] or name
-- Continue on checking for non-exact matches...
-- Still need to loop through everything, even on returnFirst, because possibility of an exact match.
if name:lower() == text:lower() then
if returnFirst then
return value
else
table.insert(results, 1, value)
end
elseif name:lower():find(text:lower(), 1, true) then
results[#results + 1] = value
end
end
if returnFirst then
return results[1]
end
return results
end
end
--- Takes an array of instances and returns an array of those instances' names.
function Util.GetNames(instances)
local names = {}
for i = 1, #instances do
names[i] = instances[i].Name or tostring(instances[i])
end
return names
end
--- Splits a string using a simple separator (no quote parsing)
function Util.SplitStringSimple(inputstr, sep)
if sep == nil then
sep = "%s"
end
local t = {}
local i = 1
for str in string.gmatch(inputstr, "([^" .. sep .. "]+)") do
t[i] = str
i = i + 1
end
return t
end
local function charCode(n)
return utf8.char(tonumber(n, 16))
end
--- Parses escape sequences into their fully qualified characters
function Util.ParseEscapeSequences(text)
return text:gsub("\\(.)", {
t = "\t";
n = "\n";
})
:gsub("\\u(%x%x%x%x)", charCode)
:gsub("\\x(%x%x)", charCode)
end
function Util.EncodeEscapedOperator(text, op)
local first = op:sub(1, 1)
local escapedOp = op:gsub(".", "%%%1")
local escapedFirst = "%" .. first
return text:gsub("(" .. escapedFirst .. "+)(" .. escapedOp .. ")", function(esc, op)
return (esc:sub(1, #esc-1) .. op):gsub(".", function(char)
return "\\u" .. string.format("%04x", string.byte(char), 16)
end)
end)
end
local OPERATORS = {"&&", "||", ";"}
function Util.EncodeEscapedOperators(text)
for _, operator in ipairs(OPERATORS) do
text = Util.EncodeEscapedOperator(text, operator)
end
return text
end
local function encodeControlChars(text)
return (
text
:gsub("\\\\", "___!CMDR_ESCAPE!___")
:gsub("\\\"", "___!CMDR_QUOTE!___")
:gsub("\\'", "___!CMDR_SQUOTE!___")
:gsub("\\\n", "___!CMDR_NL!___")
)
end
local function decodeControlChars(text)
return (
text
:gsub("___!CMDR_ESCAPE!___", "\\")
:gsub("___!CMDR_QUOTE!___", "\"")
:gsub("___!CMDR_NL!___", "\n")
)
end
--- Splits a string by space but taking into account quoted sequences which will be treated as a single argument.
function Util.SplitString(text, max)
text = encodeControlChars(text)
max = max or math.huge
local t = {}
local spat, epat = [=[^(['"])]=], [=[(['"])$]=]
local buf, quoted
for str in text:gmatch("[^ ]+") do
str = Util.ParseEscapeSequences(str)
local squoted = str:match(spat)
local equoted = str:match(epat)
local escaped = str:match([=[(\*)['"]$]=])
if squoted and not quoted and not equoted then
buf, quoted = str, squoted
elseif buf and equoted == quoted and #escaped % 2 == 0 then
str, buf, quoted = buf .. " " .. str, nil, nil
elseif buf then
buf = buf .. " " .. str
end
if not buf then
t[#t + (#t > max and 0 or 1)] = decodeControlChars(str:gsub(spat, ""):gsub(epat, ""))
end
end
if buf then
t[#t + (#t > max and 0 or 1)] = decodeControlChars(buf)
end
return t
end
--- Takes an array of arguments and a max value.
-- Any indicies past the max value will be appended to the last valid argument.
function Util.MashExcessArguments(arguments, max)
local t = {}
for i = 1, #arguments do
if i > max then
t[max] = ("%s %s"):format(t[max] or "", arguments[i])
else
t[i] = arguments[i]
end
end
return t
end
--- Trims whitespace from both sides of a string.
function Util.TrimString(str)
local _, from = string.find(str, "^%s*")
-- trim the string in two steps to prevent quadratic backtracking when no "%S" match is found
return from == #str and "" or string.match(str, ".*%S", from + 1)
end
--- Returns the text bounds size based on given text, label (from which properties will be pulled), and optional Vector2 container size.
function Util.GetTextSize(text, label, size)
return TextService:GetTextSize(text, label.TextSize, label.Font, size or Vector2.new(label.AbsoluteSize.X, 0))
end
--- Makes an Enum type.
function Util.MakeEnumType(name, values)
local findValue = Util.MakeFuzzyFinder(values)
return {
Validate = function(text)
return findValue(text, true) ~= nil, ("Value %q is not a valid %s."):format(text, name)
end,
Autocomplete = function(text)
local list = findValue(text)
return type(list[1]) ~= "string" and Util.GetNames(list) or list
end,
Parse = function(text)
return findValue(text, true)
end
}
end
--- Parses a prefixed union type argument (such as %Team)
function Util.ParsePrefixedUnionType(typeValue, rawValue)
local split = Util.SplitStringSimple(typeValue)
-- Check prefixes in order from longest to shortest
local types = {}
for i = 1, #split, 2 do
types[#types + 1] = {
prefix = split[i - 1] or "",
type = split[i]
}
end
table.sort(
types,
function(a, b)
return #a.prefix > #b.prefix
end
)
for i = 1, #types do
local t = types[i]
if rawValue:sub(1, #t.prefix) == t.prefix then
return t.type, rawValue:sub(#t.prefix + 1), t.prefix
end
end
end
--- Creates a listable type from a singlular type
function Util.MakeListableType(type, override)
local listableType = {
Listable = true,
Transform = type.Transform,
Validate = type.Validate,
ValidateOnce = type.ValidateOnce,
Autocomplete = type.Autocomplete,
Default = type.Default,
ArgumentOperatorAliases = type.ArgumentOperatorAliases,
Parse = function(...)
return {type.Parse(...)}
end
}
if override then
for key, value in pairs(override) do
listableType[key] = value
end
end
return listableType
end
local function encodeCommandEscape(text)
return (text:gsub("\\%$", "___!CMDR_DOLLAR!___"))
end
local function decodeCommandEscape(text)
return (text:gsub("___!CMDR_DOLLAR!___", "$"))
end
function Util.RunCommandString(dispatcher, commandString)
commandString = Util.ParseEscapeSequences(commandString)
commandString = Util.EncodeEscapedOperators(commandString)
local commands = commandString:split("&&")
local output = ""
for i, command in ipairs(commands) do
local outputEncoded = output:gsub("%$", "\\x24"):gsub("%%","%%%%")
command = command:gsub("||", output:find("%s") and ("%q"):format(outputEncoded) or outputEncoded)
output = tostring(
dispatcher:EvaluateAndRun(
(
Util.RunEmbeddedCommands(dispatcher, command)
)
)
)
if i == #commands then
return output
end
end
end
--- Runs embedded commands and replaces them
function Util.RunEmbeddedCommands(dispatcher, str)
str = encodeCommandEscape(str)
local results = {}
-- We need to do this because you can't yield in the gsub function
for text in str:gmatch("$(%b{})") do
local doQuotes = true
local commandString = text:sub(2, #text-1)
if commandString:match("^{.+}$") then -- Allow double curly for literal replacement
doQuotes = false
commandString = commandString:sub(2, #commandString-1)
end
results[text] = Util.RunCommandString(dispatcher, commandString)
if doQuotes then
if results[text]:find("%s") or results[text] == "" then
results[text] = string.format("%q", results[text])
end
end
end
return decodeCommandEscape(str:gsub("$(%b{})", results))
end
--- Replaces arguments in the format $1, $2, $something with whatever the
-- given function returns for it.
function Util.SubstituteArgs(str, replace)
str = encodeCommandEscape(str)
-- Convert numerical keys to strings
if type(replace) == "table" then
for i = 1, #replace do
local k = tostring(i)
replace[k] = replace[i]
if replace[k]:find("%s") then
replace[k] = string.format("%q", replace[k])
end
end
end
return decodeCommandEscape(str:gsub("($%d+)%b{}", "%1"):gsub("$(%w+)", replace))
end
--- Creates an alias command
function Util.MakeAliasCommand(name, commandString)
local commandName, commandDescription = unpack(name:split("|"))
local args = {}
commandString = Util.EncodeEscapedOperators(commandString)
local seenArgs = {}
for arg in commandString:gmatch("$(%d+)") do
if seenArgs[arg] == nil then
seenArgs[arg] = true
local options = commandString:match(`${arg}(%b\{})`)
local argOptional, argType, argName, argDescription
if options then
options = options:sub(2, #options - 1) -- remove braces
argType, argName, argDescription = unpack(options:split("|"))
end
argOptional = argType and not not argType:match("%?$")
argType = if argType then argType:match("^%w+") else "string"
argName = argName or `Argument {arg}`
argDescription = argDescription or ""
table.insert(args, {
Type = argType,
Name = argName,
Description = argDescription,
Optional = argOptional,
})
end
end
return {
Name = commandName,
Aliases = {},
Description = ` {commandDescription or commandString}`,
Group = "UserAlias",
Args = args,
Run = function(context)
return Util.RunCommandString(context.Dispatcher, Util.SubstituteArgs(commandString, context.RawArguments))
end,
}
end
--- Makes a type that contains a sequence, e.g. Vector3 or Color3
function Util.MakeSequenceType(options)
options = options or {}
assert(options.Parse ~= nil or options.Constructor ~= nil, "MakeSequenceType: Must provide one of: Constructor, Parse")
options.TransformEach = options.TransformEach or function(...)
return ...
end
options.ValidateEach = options.ValidateEach or function()
return true
end
return {
Prefixes = options.Prefixes;
Transform = function (text)
return Util.Map(Util.SplitPrioritizedDelimeter(text, {",", "%s"}), function(value)
return options.TransformEach(value)
end)
end;
Validate = function (components)
if options.Length and #components > options.Length then
return false, ("Maximum of %d values allowed in sequence"):format(options.Length)
end
for i = 1, options.Length or #components do
local valid, reason = options.ValidateEach(components[i], i)
if not valid then
return false, reason
end
end
return true
end;
Parse = options.Parse or function(components)
return options.Constructor(unpack(components))
end
}
end
--- Splits a string by a single delimeter chosen from the given set.
-- The first matching delimeter from the set becomes the split character.
function Util.SplitPrioritizedDelimeter(text, delimeters)
for i, delimeter in ipairs(delimeters) do
if text:find(delimeter) or i == #delimeters then
return Util.SplitStringSimple(text, delimeter)
end
end
end
--- Maps values of an array through a callback and returns an array of mapped values
function Util.Map(array, callback)
local results = {}
for i, v in ipairs(array) do
results[i] = callback(v, i)
end
return results
end
--- Maps arguments #2-n through callback and returns values as tuple
function Util.Each(callback, ...)
local results = {}
for i, value in ipairs({...}) do
results[i] = callback(value)
end
return unpack(results)
end
--- Emulates tabstops with spaces
function Util.EmulateTabstops(text, tabWidth)
local column = 0
local textLength = #text
local result = table.create(textLength)
for i = 1, textLength do
local char = string.sub(text, i, i)
if char == "\t" then
local spaces = tabWidth - column % tabWidth
table.insert(result, string.rep(" ", spaces))
column += spaces
else
table.insert(result, char)
if char == "\n" then
column = 0 -- Reset column counter on newlines
elseif char ~= "\r" then
column += 1
end
end
end
return table.concat(result)
end
function Util.Mutex()
local queue = {}
local locked = false
return function ()
if locked then
table.insert(queue, coroutine.running())
coroutine.yield()
else
locked = true
end
return function()
if #queue > 0 then
coroutine.resume(table.remove(queue, 1))
else
locked = false
end
end
end
end
return Util
- Edit
03:12:20.501
- Edit
03:12:20.501
============================== - Edit
03:12:20.501 📜 ServerScriptService.MadAntiCheat.Core - Edit
03:12:20.501 ==============================
- Edit
03:12:20.501 -- Madonox
-- 2022
local library = {}
for _,v in ipairs(script.Parent.Library:GetChildren()) do
library[v.Name] = require(v)
end
local validation = library.LoadModule(8472471824)
if library.Validation.loaderBuild == validation.loaderBuild then
local main = library.LoadModule(8472470237)
local success,err = pcall(function()
main.start(script.Parent.Configuration)
end)
if not success then
warn("---------------")
warn("MadAntiCheat ERROR:")
warn("The main anti-cheat module failed to start! Please report this error to the owner!")
warn("Error: "..err)
warn("---------------")
end
else
warn("---------------")
warn("MadAntiCheat CRITICAL ERROR:")
warn("Cannot load anti-cheat, this loader is out of date!")
warn("---------------")
end - Edit
03:12:20.501
- Edit
03:12:20.502
============================== - Edit
03:12:20.502 📜 ServerScriptService.MadAntiCheat.Configuration.CheckConfiguration.Speed - Edit
03:12:20.502 ==============================
- Edit
03:12:20.502 -- Madonox
-- 2022
return {
["enabled"] = true;
["checkTime"] = 5; -- Time between checks.
["distanceMultiplier"] = 1.25; -- **KEEP ABOVE 1** How much a user can go over their humanoid's walk speed in magnitude.
} - Edit
03:12:20.502
- Edit
03:12:20.502
============================== - Edit
03:12:20.502 📜 ServerScriptService.MadAntiCheat.Configuration.CheckConfiguration.Ping - Edit
03:12:20.502 ==============================
- Edit
03:12:20.502 -- Madonox
-- 2022
return {
["enabled"] = true;
["checkTime"] = 5; -- Time between checks.
} - Edit
03:12:20.502
- Edit
03:12:20.502
============================== - Edit
03:12:20.502 📜 ServerScriptService.MadAntiCheat.Configuration.CheckConfiguration.HBE - Edit
03:12:20.502 ==============================
- Edit
03:12:20.502 -- Madonox
-- 2022
return {
["enabled"] = true;
["punishment"] = "respawn"; -- You can pick either respawn or kick
} - Edit
03:12:20.502
- Edit
03:12:20.502
============================== - Edit
03:12:20.502 📜 ServerScriptService.MadAntiCheat.Configuration.CheckConfiguration.Injection - Edit
03:12:20.502 ==============================
- Edit
03:12:20.502 -- Madonox
-- 2022
return {
["enabled"] = true;
} - Edit
03:12:20.502
- Edit
03:12:20.502
============================== - Edit
03:12:20.503 📜 ServerScriptService.MadAntiCheat.Configuration.Admin - Edit
03:12:20.503 ==============================
- Edit
03:12:20.503 -- Madonox
-- 2022
return {
["groups"] = {
[221627747] = {}; -- [GroupID] = {insert rank IDs}
};
["users"] = {
2985198364;
};
["externalAdmins"] = { -- If users admined in external admin modules get admin in MadAntiCheat.
["adonis"] = true;
}
} - Edit
03:12:20.503
- Edit
03:12:20.503
============================== - Edit
03:12:20.503 📜 ServerScriptService.MadAntiCheat.Configuration.General - Edit
03:12:20.503 ==============================
- Edit
03:12:20.503 -- Madonox
-- 2022
return {
["adminCommand"] = "!anticheat"; -- Command to bring up admin menu.
} - Edit
03:12:20.503
- Edit
03:12:20.503
============================== - Edit
03:12:20.503 📜 ServerScriptService.MadAntiCheat.Library.Validation - Edit
03:12:20.503 ==============================
- Edit
03:12:20.503 -- Madonox
-- 2022
local Validation = {}
Validation.loaderBuild = 1
return Validation - Edit
03:12:20.503
- Edit
03:12:20.504
============================== - Edit
03:12:20.504 📜 ServerScriptService.MadAntiCheat.Library.LoadModule - Edit
03:12:20.504 ==============================
- Edit
03:12:20.504 -- Madonox
-- 2022
return function(id)
local module = require(id)
if typeof(module) == "table" then
if module.init ~= nil then
module.init()
end
end
return module
end - Edit
03:12:20.504
- Edit
03:12:20.504
============================== - Edit
03:12:20.504 📜 ServerScriptService.Modded.ServerLuck - Edit
03:12:20.504 ==============================
- Edit
03:12:20.504 -- Server Luck Script v1.0.0.
-- This script isnt mine btw.
-- Logical.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Synchronizer = require(Packages.Synchronizer)
local SLsynchronizer = Synchronizer:Create("ServerLuck", {
Index = 0,
EndTime = nil,
})
local DEFAULT_MULTIPLIER = script:GetAttribute("Multiplier") or 100000
local MIN_DURATION = 2 * 24 * 60 * 60
local MAX_DURATION = 6 * 24 * 60 * 60
local duration = math.random(MIN_DURATION, MAX_DURATION)
local endTime = os.time() + duration
SLsynchronizer:Set("Index", DEFAULT_MULTIPLIER)
SLsynchronizer:Set("EndTime", endTime)
ReplicatedStorage:SetAttribute("ServerLuckMultiplier", DEFAULT_MULTIPLIER)
ReplicatedStorage:SetAttribute("ServerLuckEndTime", endTime)
for _, player in ipairs(Players:GetPlayers()) do
SLsynchronizer:AddListener(player)
end
Players.PlayerAdded:Connect(function(player)
SLsynchronizer:AddListener(player)
end)
Players.PlayerRemoving:Connect(function(player)
SLsynchronizer:RemoveListener(player)
end)
RunService.Heartbeat:Connect(function()
local now = os.time()
local currentEnd = SLsynchronizer:Get("EndTime") or 0
if currentEnd <= now then
local newDuration = math.random(MIN_DURATION, MAX_DURATION)
local newEnd = os.time() + newDuration
SLsynchronizer:Set("Index", DEFAULT_MULTIPLIER)
SLsynchronizer:Set("EndTime", newEnd)
ReplicatedStorage:SetAttribute("ServerLuckMultiplier", DEFAULT_MULTIPLIER)
ReplicatedStorage:SetAttribute("ServerLuckEndTime", newEnd)
end
end) - Edit
03:12:20.504
- Edit
03:12:20.505
============================== - Edit
03:12:20.505 📜 ServerScriptService.Events.MoltenEvent - Edit
03:12:20.505 ==============================
- Edit
03:12:20.505 local RunService = game:GetService("RunService")
local workspace = game:GetService("Workspace")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
spawn(function()
local NotificationRemote = Net:RemoteEvent("NotificationService/Notify")
local function GetCooldownTime()
local CurrentTime = workspace:GetServerTimeNow()
local Wday = os.date("!*t", CurrentTime).wday
return (((Wday == 1) or (Wday == 7)) and 3600) or 10800
end
local function FormatTime(Seconds)
local H = math.floor(Seconds / 3600)
local M = math.floor((Seconds % 3600) / 60)
local S = math.floor(Seconds % 60)
return string.format("%02d:%02d:%02d", H, M, S)
end
local function NotifyAllPlayers()
for _, Player in ipairs(Players:GetPlayers()) do
NotificationRemote:FireClient(Player, 'The Molten Event is here! You got a free spin', 10, "Sounds.Sfx.Success")
end
end
local function CheckAnyPlayerCanSpin()
local LastEventTime = ReplicatedStorage:GetAttribute("MoltenEventLastTime") or 0
for _, Player in pairs(Players:GetPlayers()) do
local PlayerData = Synchronizer:Wait(Player)
local LastClaimed = PlayerData:Get("MoltenSpinWheel.LastFreeClaimed") or 0
if (LastClaimed ~= LastEventTime) then
return true
end
end
return false
end
local function StartMoltenEvent()
ReplicatedStorage:SetAttribute("MoltenEventLastTime", workspace:GetServerTimeNow())
_G.EventService:StartEvent("Molten")
NotifyAllPlayers()
end
local lastEventStartTime = 0
while true do
local Cooldown = GetCooldownTime()
local CurrentTime = workspace:GetServerTimeNow()
local TimeUntilNext = Cooldown - (CurrentTime % Cooldown)
if ((CurrentTime - lastEventStartTime) < 60) then
task.wait(1)
continue
end
if ReplicatedStorage:GetAttribute("MoltenEvent") then
if CheckAnyPlayerCanSpin() then
StartMoltenEvent()
lastEventStartTime = CurrentTime
task.wait(Cooldown)
else
while TimeUntilNext > 0 do
task.wait(1)
TimeUntilNext = Cooldown - (workspace:GetServerTimeNow() % Cooldown)
end
end
else
while TimeUntilNext > 0 do
task.wait(1)
TimeUntilNext = Cooldown - (workspace:GetServerTimeNow() % Cooldown)
end
StartMoltenEvent()
lastEventStartTime = workspace:GetServerTimeNow()
end
task.wait(1)
end
end) - Edit
03:12:20.505
- Edit
03:12:20.505
============================== - Edit
03:12:20.505 📜 ServerScriptService.Events.EventService - Edit
03:12:20.505 ==============================
- Edit
03:12:20.505 local EventService = require(game.ServerScriptService.Services.EventService)
_G.EventService = nil
local EventServiceSuccessful, EventServiceError = pcall(function()
_G.EventService = EventService.new()
end) - Edit
03:12:20.505
- Edit
03:12:20.505
============================== - Edit
03:12:20.505 📜 ServerScriptService.Events.GalaxyEvent - Edit
03:12:20.505 ==============================
- Edit
03:12:20.505 local RunService = game:GetService("RunService")
local workspace = game:GetService("Workspace")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
local Packages = ReplicatedStorage:WaitForChild("Packages")
local Net = require(Packages.Net)
local Synchronizer = require(Packages.Synchronizer)
spawn(function()
local NotificationRemote = Net:RemoteEvent("NotificationService/Notify")
local function GetCooldownTime()
local CurrentTime = workspace:GetServerTimeNow()
local Wday = os.date("!*t", CurrentTime).wday
return (((Wday == 1) or (Wday == 7)) and 3600) or 10800
end
local function FormatTime(Seconds)
local H = math.floor(Seconds / 3600)
local M = math.floor((Seconds % 3600) / 60)
local S = math.floor(Seconds % 60)
return string.format("%02d:%02d:%02d", H, M, S)
end
local function NotifyAllPlayers()
for _, Player in ipairs(Players:GetPlayers()) do
NotificationRemote:FireClient(Player, 'The Galaxy Event is here! You got a free spin', 10, "Sounds.Sfx.Success")
end
end
local function CheckAnyPlayerCanSpin()
local LastEventTime = ReplicatedStorage:GetAttribute("GalaxyEventLastTime") or 0
for _, Player in pairs(Players:GetPlayers()) do
local PlayerData = Synchronizer:Wait(Player)
local LastClaimed = PlayerData:Get("GalaxySpinWheel.LastFreeClaimed") or 0
if (LastClaimed ~= LastEventTime) then
return true
end
end
return false
end
local function StartGalaxyEvent()
ReplicatedStorage:SetAttribute("GalaxyEventLastTime", workspace:GetServerTimeNow())
_G.EventService:StartEvent("Galaxy")
NotifyAllPlayers()
end
local lastEventStartTime = 0
while true do
local Cooldown = GetCooldownTime()
local CurrentTime = workspace:GetServerTimeNow()
local TimeUntilNext = Cooldown - (CurrentTime % Cooldown)
if ((CurrentTime - lastEventStartTime) < 60) then
task.wait(1)
continue
end
if ReplicatedStorage:GetAttribute("GalaxyEvent") then
if CheckAnyPlayerCanSpin() then
StartGalaxyEvent()
lastEventStartTime = CurrentTime
task.wait(Cooldown)
else
while TimeUntilNext > 0 do
task.wait(1)
TimeUntilNext = Cooldown - (workspace:GetServerTimeNow() % Cooldown)
end
end
else
while TimeUntilNext > 0 do
task.wait(1)
TimeUntilNext = Cooldown - (workspace:GetServerTimeNow() % Cooldown)
end
StartGalaxyEvent()
lastEventStartTime = workspace:GetServerTimeNow()
end
task.wait(1)
end
end) - Edit
03:12:20.505
- Edit
03:12:20.506
============================== - Edit
03:12:20.506 📜 ServerScriptService.Conch - Edit
03:12:20.506 ==============================
- Edit
03:12:20.506 local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Conch = require(ReplicatedStorage.Packages.Conch)
require(ReplicatedStorage.Shared.ConchTypes)
local ServerScriptService = game:GetService("ServerScriptService")
require(ServerScriptService.Services.CommandsService)
local Net = require(ReplicatedStorage.Packages.Net)
Conch.initiate_default_lifecycle() - Edit
03:12:20.506
- Edit
03:12:20.507 ✅ Finished printing all scripts! - Edit