Kill Leaderboard Script Works For Some Weapons, But not others. I don’t know how to fix this.
Perhaps you should make it so the weapons that you’re using handle the kill value change? I don’t know much about your situation here so maybe if you provide me with more details I could help you out.
What do you mean details? More scripts?
How exactly do you check for who killed a player? As far as I can see in the script you’ve provided it checks for a Value (Assuming that’s the killer) inside of the Humanoid instance. Is there another script that sets the Value?
@thebulldogs22ALT
In the tool damage script, (It’s very messy but line 427 should be what you mean) if the person dies after dmg is done, then it sets killer to the player. [Ctrl + F] local function _defaultDamageCallback
local CollectionService = game:GetService("CollectionService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local IsServer = RunService:IsServer()
-- Dependencies
local WeaponData = script.Parent:WaitForChild("WeaponData")
local WeaponsSystemFolder = script.Parent
local WeaponTypes = WeaponsSystemFolder:WaitForChild("WeaponTypes")
local Libraries = WeaponsSystemFolder:WaitForChild("Libraries")
local ShoulderCamera = require(Libraries:WaitForChild("ShoulderCamera"))
local WeaponsGui = require(Libraries:WaitForChild("WeaponsGui"))
local SpringService = require(Libraries:WaitForChild("SpringService"))
local ancestorHasTag = require(Libraries:WaitForChild("ancestorHasTag"))
ShoulderCamera.SpringService = SpringService
local Configuration = WeaponsSystemFolder:WaitForChild("Configuration")
local ConfigurationValues = {
SprintEnabled = Configuration:WaitForChild("SprintEnabled"),
SlowZoomWalkEnabled = Configuration:WaitForChild("SlowZoomWalkEnabled"),
}
local WEAPON_TAG = "WeaponsSystemWeapon"
local WEAPON_TYPES_LOOKUP = {}
local REMOTE_EVENT_NAMES = {
"WeaponFired",
"WeaponHit",
"WeaponReloadRequest",
"WeaponReloaded",
"WeaponReloadCanceled",
"WeaponActivated"
}
local REMOTE_FUNCTION_NAMES = {}
--Set up WeaponTypes lookup table
do
local function onNewWeaponType(weaponTypeModule)
if not weaponTypeModule:IsA("ModuleScript") then
return
end
local weaponTypeName = weaponTypeModule.Name
xpcall(function()
coroutine.wrap(function()
local weaponType = require(weaponTypeModule)
assert(typeof(weaponType) == "table", string.format("WeaponType \"%s\" did not return a valid table", weaponTypeModule:GetFullName()))
WEAPON_TYPES_LOOKUP[weaponTypeName] = weaponType
end)()
end, function(errMsg)
warn(string.format("Error while loading %s: %s", weaponTypeModule:GetFullName(), errMsg))
warn(debug.traceback())
end)
end
for _, child in pairs(WeaponTypes:GetChildren()) do
onNewWeaponType(child)
end
WeaponTypes.ChildAdded:Connect(onNewWeaponType)
end
local WeaponsSystem = {}
WeaponsSystem.didSetup = false
WeaponsSystem.knownWeapons = {}
WeaponsSystem.connections = {}
WeaponsSystem.networkFolder = nil
WeaponsSystem.remoteEvents = {}
WeaponsSystem.remoteFunctions = {}
WeaponsSystem.currentWeapon = nil
WeaponsSystem.aimRayCallback = nil
WeaponsSystem.CurrentWeaponChanged = Instance.new("BindableEvent")
local NetworkingCallbacks = require(WeaponsSystemFolder:WaitForChild("NetworkingCallbacks"))
NetworkingCallbacks.WeaponsSystem = WeaponsSystem
local _damageCallback = nil
local _getTeamCallback = nil
function WeaponsSystem.setDamageCallback(cb)
_damageCallback = cb
end
function WeaponsSystem.setGetTeamCallback(cb)
_getTeamCallback = cb
end
function WeaponsSystem.setup()
if WeaponsSystem.didSetup then
warn("Warning: trying to run WeaponsSystem setup twice on the same module.")
return
end
print(script.Parent:GetFullName(), "is now active.")
WeaponsSystem.doingSetup = true
--Setup network routing
if IsServer then
local networkFolder = Instance.new("Folder")
networkFolder.Name = "Network"
for _, remoteEventName in pairs(REMOTE_EVENT_NAMES) do
local remoteEvent = Instance.new("RemoteEvent")
remoteEvent.Name = remoteEventName
remoteEvent.Parent = networkFolder
local callback = NetworkingCallbacks[remoteEventName]
if not callback then
--Connect a no-op function to ensure the queue doesn't pile up.
warn("There is no server callback implemented for the WeaponsSystem RemoteEvent \"%s\"!")
warn("A default no-op function will be implemented so that the queue cannot be abused.")
callback = function() end
end
WeaponsSystem.connections[remoteEventName .. "Remote"] = remoteEvent.OnServerEvent:Connect(function(...)
callback(...)
end)
WeaponsSystem.remoteEvents[remoteEventName] = remoteEvent
end
for _, remoteFuncName in pairs(REMOTE_FUNCTION_NAMES) do
local remoteFunc = Instance.new("RemoteEvent")
remoteFunc.Name = remoteFuncName
remoteFunc.Parent = networkFolder
local callback = NetworkingCallbacks[remoteFuncName]
if not callback then
--Connect a no-op function to ensure the queue doesn't pile up.
warn("There is no server callback implemented for the WeaponsSystem RemoteFunction \"%s\"!")
warn("A default no-op function will be implemented so that the queue cannot be abused.")
callback = function() end
end
remoteFunc.OnServerInvoke = function(...)
return callback(...)
end
WeaponsSystem.remoteFunctions[remoteFuncName] = remoteFunc
end
networkFolder.Parent = WeaponsSystemFolder
WeaponsSystem.networkFolder = networkFolder
else
WeaponsSystem.StarterGui = game:GetService("StarterGui")
WeaponsSystem.camera = ShoulderCamera.new(WeaponsSystem)
WeaponsSystem.gui = WeaponsGui.new(WeaponsSystem)
if ConfigurationValues.SprintEnabled.Value then
WeaponsSystem.camera:setSprintEnabled(ConfigurationValues.SprintEnabled.Value)
end
if ConfigurationValues.SlowZoomWalkEnabled.Value then
WeaponsSystem.camera:setSlowZoomWalkEnabled(ConfigurationValues.SlowZoomWalkEnabled.Value)
end
local networkFolder = WeaponsSystemFolder:WaitForChild("Network", math.huge)
for _, remoteEventName in pairs(REMOTE_EVENT_NAMES) do
coroutine.wrap(function()
local remoteEvent = networkFolder:WaitForChild(remoteEventName, math.huge)
local callback = NetworkingCallbacks[remoteEventName]
if callback then
WeaponsSystem.connections[remoteEventName .. "Remote"] = remoteEvent.OnClientEvent:Connect(function(...)
callback(...)
end)
end
WeaponsSystem.remoteEvents[remoteEventName] = remoteEvent
end)()
end
for _, remoteFuncName in pairs(REMOTE_FUNCTION_NAMES) do
coroutine.wrap(function()
local remoteFunc = networkFolder:WaitForChild(remoteFuncName, math.huge)
local callback = NetworkingCallbacks[remoteFuncName]
if callback then
remoteFunc.OnClientInvoke = function(...)
return callback(...)
end
end
WeaponsSystem.remoteFunctions[remoteFuncName] = remoteFunc
end)()
end
Players.LocalPlayer.CharacterAdded:Connect(WeaponsSystem.onCharacterAdded)
if Players.LocalPlayer.Character then
WeaponsSystem.onCharacterAdded(Players.LocalPlayer.Character)
end
WeaponsSystem.networkFolder = networkFolder
WeaponsSystem.camera:setEnabled(true)
end
--Setup weapon tools and listening
WeaponsSystem.connections.weaponAdded = CollectionService:GetInstanceAddedSignal(WEAPON_TAG):Connect(WeaponsSystem.onWeaponAdded)
WeaponsSystem.connections.weaponRemoved = CollectionService:GetInstanceRemovedSignal(WEAPON_TAG):Connect(WeaponsSystem.onWeaponRemoved)
for _, instance in pairs(CollectionService:GetTagged(WEAPON_TAG)) do
WeaponsSystem.onWeaponAdded(instance)
end
WeaponsSystem.doingSetup = false
WeaponsSystem.didSetup = true
end
function WeaponsSystem.onCharacterAdded(character)
-- Make it so players unequip weapons while seated, then reequip weapons when they become unseated
local humanoid = character:WaitForChild("Humanoid")
WeaponsSystem.connections.seated = humanoid.Seated:Connect(function(isSeated)
if isSeated then
WeaponsSystem.seatedWeapon = character:FindFirstChildOfClass("Tool")
humanoid:UnequipTools()
WeaponsSystem.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false)
else
WeaponsSystem.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, true)
humanoid:EquipTool(WeaponsSystem.seatedWeapon)
end
end)
end
function WeaponsSystem.shutdown()
if not WeaponsSystem.didSetup then
return
end
for _, weapon in pairs(WeaponsSystem.knownWeapons) do
weapon:onDestroyed()
end
WeaponsSystem.knownWeapons = {}
if IsServer and WeaponsSystem.networkFolder then
WeaponsSystem.networkFolder:Destroy()
end
WeaponsSystem.networkFolder = nil
WeaponsSystem.remoteEvents = {}
WeaponsSystem.remoteFunctions = {}
for _, connection in pairs(WeaponsSystem.connections) do
if typeof(connection) == "RBXScriptConnection" then
connection:Disconnect()
end
end
WeaponsSystem.connections = {}
end
function WeaponsSystem.getWeaponTypeFromTags(instance)
for _, tag in pairs(CollectionService:GetTags(instance)) do
local weaponTypeFound = WEAPON_TYPES_LOOKUP[tag]
if weaponTypeFound then
return weaponTypeFound
end
end
return nil
end
function WeaponsSystem.createWeaponForInstance(weaponInstance)
coroutine.wrap(function()
local weaponType = WeaponsSystem.getWeaponTypeFromTags(weaponInstance)
if not weaponType then
local weaponTypeObj = weaponInstance:WaitForChild("WeaponType")
if weaponTypeObj and weaponTypeObj:IsA("StringValue") then
local weaponTypeName = weaponTypeObj.Value
local weaponTypeFound = WEAPON_TYPES_LOOKUP[weaponTypeName]
if not weaponTypeFound then
warn(string.format("Cannot find the weapon type \"%s\" for the instance %s!", weaponTypeName, weaponInstance:GetFullName()))
return
end
weaponType = weaponTypeFound
else
warn("Could not find a WeaponType tag or StringValue for the instance ", weaponInstance:GetFullName())
return
end
end
-- Since we might have yielded while trying to get the WeaponType, we need to make sure not to continue
-- making a new weapon if something else beat this iteration.
if WeaponsSystem.getWeaponForInstance(weaponInstance) then
warn("Already got ", weaponInstance:GetFullName())
warn(debug.traceback())
return
end
-- We should be pretty sure we got a valid weaponType by now
assert(weaponType, "Got invalid weaponType")
local weapon = weaponType.new(WeaponsSystem, weaponInstance)
WeaponsSystem.knownWeapons[weaponInstance] = weapon
end)()
end
function WeaponsSystem.getWeaponForInstance(weaponInstance)
if not typeof(weaponInstance) == "Instance" then
warn("WeaponsSystem.getWeaponForInstance(weaponInstance): 'weaponInstance' was not an instance.")
return nil
end
return WeaponsSystem.knownWeapons[weaponInstance]
end
-- and (IsServer or weaponInstance:IsDescendantOf(Players.LocalPlayer))
function WeaponsSystem.onWeaponAdded(weaponInstance)
local weapon = WeaponsSystem.getWeaponForInstance(weaponInstance)
if not weapon then
WeaponsSystem.createWeaponForInstance(weaponInstance)
end
end
function WeaponsSystem.onWeaponRemoved(weaponInstance)
local weapon = WeaponsSystem.getWeaponForInstance(weaponInstance)
if weapon then
weapon:onDestroyed()
end
WeaponsSystem.knownWeapons[weaponInstance] = nil
end
function WeaponsSystem.getRemoteEvent(name)
if not WeaponsSystem.networkFolder then
return
end
local remoteEvent = WeaponsSystem.remoteEvents[name]
if IsServer then
if not remoteEvent then
warn("No RemoteEvent named ", name)
return nil
end
return remoteEvent
else
if not remoteEvent then
remoteEvent = WeaponsSystem.networkFolder:WaitForChild(name, math.huge)
end
return remoteEvent
end
end
function WeaponsSystem.getRemoteFunction(name)
if not WeaponsSystem.networkFolder then
return
end
local remoteFunc = WeaponsSystem.remoteFunctions[name]
if IsServer then
if not remoteFunc then
warn("No RemoteFunction named ", name)
return nil
end
return remoteFunc
else
if not remoteFunc then
remoteFunc = WeaponsSystem.networkFolder:WaitForChild(name, math.huge)
end
return remoteFunc
end
end
function WeaponsSystem.setWeaponEquipped(weapon, equipped)
assert(not IsServer, "WeaponsSystem.setWeaponEquipped should only be called on the client.")
if not weapon then
return
end
local lastWeapon = WeaponsSystem.currentWeapon
local hasWeapon = false
local weaponChanged = false
if lastWeapon == weapon then
if not equipped then
WeaponsSystem.currentWeapon = nil
hasWeapon = false
weaponChanged = true
else
weaponChanged = false
end
else
if equipped then
WeaponsSystem.currentWeapon = weapon
hasWeapon = true
weaponChanged = true
end
end
if WeaponsSystem.camera then
WeaponsSystem.camera:resetZoomFactor()
WeaponsSystem.camera:setHasScope(false)
if WeaponsSystem.currentWeapon then
WeaponsSystem.camera:setZoomFactor(WeaponsSystem.currentWeapon:getConfigValue("ZoomFactor", 1.1))
WeaponsSystem.camera:setHasScope(WeaponsSystem.currentWeapon:getConfigValue("HasScope", false))
end
end
if WeaponsSystem.gui then
WeaponsSystem.gui:setEnabled(hasWeapon)
if WeaponsSystem.currentWeapon then
WeaponsSystem.gui:setCrosshairWeaponScale(WeaponsSystem.currentWeapon:getConfigValue("CrosshairScale", 1))
else
WeaponsSystem.gui:setCrosshairWeaponScale(1)
end
end
if weaponChanged then
WeaponsSystem.CurrentWeaponChanged:Fire(weapon.instance, lastWeapon and lastWeapon.instance)
end
end
function WeaponsSystem.getHumanoid(part)
while part and part ~= workspace do
if part:IsA("Model") and part.PrimaryPart and part.PrimaryPart.Name == "HumanoidRootPart" then
return part:FindFirstChildOfClass("Humanoid")
end
part = part.Parent
end
end
function WeaponsSystem.getPlayerFromHumanoid(humanoid)
for _, player in ipairs(Players:GetPlayers()) do
if player.Character and humanoid:IsDescendantOf(player.Character) then
return player
end
end
end
local function _defaultDamageCallback(system, target, amount, damageType, --here dealer, hitInfo, damageData)
if target:IsA("Humanoid") then
target:TakeDamage(amount)
game:GetService('Players').PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character)
character:WaitForChild("Humanoid").Died:Connect(function()
local killer = script.Parent.Parent.Parent
end
end
function WeaponsSystem.doDamage(target, amount, damageType, dealer, hitInfo, damageData)
if not target or ancestorHasTag(target, "WeaponsSystemIgnore") then
return
end
if IsServer then
if target:IsA("Humanoid") and dealer:IsA("Player") and dealer.Character then
local dealerHumanoid = dealer.Character:FindFirstChildOfClass("Humanoid")
local targetPlayer = Players:GetPlayerFromCharacter(target.Parent)
if dealerHumanoid and target ~= dealerHumanoid and targetPlayer then
-- Trigger the damage indicator
WeaponData:FireClient(targetPlayer, "HitByOtherPlayer", dealer.Character.HumanoidRootPart.CFrame.Position)
end
end
-- NOTE: damageData is a more or less free-form parameter that can be used for passing information from the code that is dealing damage about the cause.
-- .The most obvious usage is extracting icons from the various weapon types (in which case a weapon instance would likely be passed in)
-- ..The default weapons pass in that data
local handler = _damageCallback or _defaultDamageCallback
handler(WeaponsSystem, target, amount, damageType, dealer, hitInfo, damageData)
end
end
local function _defaultGetTeamCallback(player)
return 0
end
function WeaponsSystem.getTeam(player)
local handler = _getTeamCallback or _defaultGetTeamCallback
return handler(player)
end
function WeaponsSystem.playersOnDifferentTeams(player1, player2)
if player1 == player2 or player1 == nil or player2 == nil then
-- This allows players to damage themselves and NPC's
return true
end
local player1Team = WeaponsSystem.getTeam(player1)
local player2Team = WeaponsSystem.getTeam(player2)
return player1Team == 0 or player1Team ~= player2Team
end
return WeaponsSystem
Oops-
I attached the wrong script…
My real problem is certain guns don’t give XP or kills.
print("Keaderboard script loaded!")
maxlevel = 50
function onXPChanged(player, score, level)
if score.Value>= 25 * (level.Value) + 100 and level.Value < maxlevel then
score.Value = score.Value - (25*(level.Value) + 100)
level.Value = level.Value + 1
end
end
function onLevelUp(player, score, level)
if player.Character~=nil then
for i = 1,5 do
local fireworks = Instance.new("Part")
fireworks.Shape = 0
fireworks.formFactor = "Symmetric"
fireworks.Size = Vector3.new(1,1,1)
fireworks.BrickColor = BrickColor.Random()
fireworks.CFrame = player.Character.Head.CFrame + Vector3.new(0,2,0)
fireworks.Parent = game.Workspace
game:GetService("Debris"):AddItem(fireworks, 2)
fireworks.Velocity = Vector3.new(math.random(-30,30),math.random(-30,30),math.random(-30,30))
end
end
local m = Instance.new("Hint")
m.Parent = game.Workspace
m.Text = player.Name .. " has ranked up!" --Sweet!
wait(5)
m.Parent = nil
end
function onHumanoidDied(humanoid, player)
local stats = player:findFirstChild("leaderstats")
if stats ~= nil then
local deaths = stats:findFirstChild("Dies")
deaths.Value = deaths.Value + 1
-- do short dance to try and find the killer
local killer = getKillerOfHumanoidIfStillInGame(humanoid)
handleKillCount(humanoid, player)
end
end
function onPlayerRespawn(property, player)
-- need to connect to new humanoid
if property == "Character" and player.Character ~= nil then
local humanoid = player.Character.Humanoid
local p = player
local h = humanoid
humanoid.Died:connect(function() onHumanoidDied(h, p) end )
end
end
function getKillerOfHumanoidIfStillInGame(humanoid)
-- returns the player object that killed this humanoid
-- returns nil if the killer is no longer in the game
-- check for kill tag on humanoid - may be more than one - todo: deal with this
local tag = humanoid:findFirstChild("creator")
-- find player with name on tag
if tag ~= nil then
local killer = tag.Value
if killer.Parent ~= nil then -- killer still in game
return killer
end
end
return nil
end
function handleKillCount(humanoid, player)
local killer = getKillerOfHumanoidIfStillInGame(humanoid)
if killer ~= nil then
local stats = killer:findFirstChild("leaderstats")
if stats ~= nil then
local kills = stats:findFirstChild("Kills")
local score = stats:findFirstChild("XP")
local level = stats:findFirstChild("Rank")
if killer ~= player then
score.Value = score.Value + 250 *
kills.Value = kills.Value + 1
else
kills.Value = kills.Value - 1
end
end
end
end
-----------------------------------------------
function plr(newPlayer)
local stats = Instance.new("IntValue")
stats.Name = "leaderstats"
local kills = Instance.new("IntValue")
kills.Name = "Kills"
kills.Value = 0
local deaths = Instance.new("IntValue")
deaths.Name = "Dies"
deaths.Value = 0
local score = Instance.new("IntValue")
score.Name = "XP"
score.Value = 0
local rank = Instance.new("IntValue")
rank.Name = "Rank"
rank.Value = 1
local fill = Instance.new("IntValue")
fill.Name= "filler1"
fill.Value = 0
rank.Parent = stats
score.Parent = stats
kills.Parent = stats
deaths.Parent = stats
fill.Parent = stats
stats.Parent = newPlayer
--[[ if newPlayer.usedId == 65006475 then
newPlayer.leaderstats.Rank.Value = maxlevel
end]]
score.Changed:connect(function() onXPChanged(newPlayer, score, rank) end)
rank.Changed:connect(function() onLevelUp(newPlayer, score, rank) end)
while true do
if newPlayer.Character ~= nil then break end
wait(5)
end
local humanoid = newPlayer.Character.Humanoid
humanoid.Died:connect(function() onHumanoidDied(humanoid, newPlayer) end )
-- start to listen for new humanoid
newPlayer.Changed:connect(function(property) onPlayerRespawn(property, newPlayer) end )
end
for _,v in pairs(game.Players:GetPlayers()) do
plr(v)
end
game.Players.ChildAdded:connect(plr)
Sorry! I was offline so I couldn’t respond back on time.
local function _defaultDamageCallback(system, target, amount, damageType, dealer, hitInfo, damageData)
if target:IsA("Humanoid") and game:GetService("Players"):GetPlayerFromCharacter(target.Parent) ~= nil then --Check if the target is a Humanoid and that the Parent of the humanoid is actually a Character of a Player
if target.Health > 0 then --Checking whether the target is alive
target:TakeDamage(amount) --Damaging the Humanoid
if target.Health <= 0 then --Checking whether the target is alive
if dealer.leaderstats:FindFirstChild("Kills") then --Checking whether the dealer has a Kills Value
dealer.leaderstats.Kills.Value += 1 --Increment the Kills value by 1.
end
end
end
end
end
Here’s my example of a kill value changer. Basically what the function does is it checks whether the target is a Humanoid and whether the Character that the Humanoid is a child of is actually a Players chatacter. If it is then it checks if the target is alive. If that is the case then it’ll apply damage to the target. After that it checks whether the Humanoids health is Equal or under 0. If so then it’ll get the damage dealers Kills value and increment it by 1.
My save script isn’t working. Any ideas?
game.Players.ChildAdded:connect(plr)
local players = game:GetService("Players")
local datastore = game:GetService("DataStoreService")
local ds1 = datastore:GetDataStore("XPValueSaver")
local kills = Instance.new("IntValue")
kills.Name = "Kills"
players.PlayerAdded:connect(function(player)
kills.Changed:connect(function()
ds3:SetAsync(player.UserId, kills.Value)
end)
game.Players.ChildAdded:connect(plr) --Remove this as it is completely unnecessary.
local players = game:GetService("Players")
local datastore = game:GetService("DataStoreService")
local ds1 = datastore:GetDataStore("XPValueSaver")
local kills = Instance.new("IntValue")
kills.Name = "Kills" -- Move these two lines inside of the PlayerAdded event. What you're doing here is making only one IntValue that has no parent whatsoever.
players.PlayerAdded:connect(function(player) --Alright so inside of here, what you're doing is just saving the Value inside of the DataStore upon it's change. This isn't a very good practice as it makes a lot more DataStore requests than it should. Also, you should make it so the script actually gets the amount of kills with ds3:GetAsync(). This'll return the saved value for the player.
kills.Changed:connect(function()
ds3:SetAsync(player.UserId, kills.Value)
end)
Here’s what I would do if I was you:
local PlayerService = game:GetService("Players")
local DSS = game:GetService("DataStoreService")
local DS = DSS:GetDataStore("XPValueSaver")
--------DEFINITIONS
--PLAYERADDED EVENT
PlayerService.PlayerAdded:Connect(function(player)
local plrDat = nil
local fld = Instance.new("Folder")
fld.Name = "leaderstats"
fld.Parent = player --Here I create a folder named 'leaderstats' that is located inside of the player.
local kills = Instance.new("IntValue")
kills.Name = "Kills"
kills.Parent = fld --Here I create a new IntValue (Kills value) that is located inside of the newly created leaderstats folder.
local success,err = pcall(function()
plrDat = DS:GetAsync(player.UserId)
end) --This function right here loads the data for the player from the DataStore. I'm using pcalls here for error handling during the loading.
if success then --If there weren't any issues accessing the DataStore and the players data was obtained successfully, it'll proceed with the script.
if plrDat ~= nil then --In case the player isn't new and already has existing data, we'll just load it!
kills.Value = plrDat --Here we set the kills value to the loaded data.
print("Loaded player data for user "..player.Name)
else --else if the player has no data (Is a new player):
kills.Value = 0 -- We set their kills value to 0 (Considering they're new.)
DS:SetAsync(player.UserId, kills.Value) -- We create a new save for the player in the DataStore
print("User "..player.Name.." appears to be new (Has no kills data). New save file will be created.")
end
else --else if there was an error while accessing the DataStore, it'll print out a message informing you that data loading has failed and will let you know what the error is.
print("Failed to load data for user "..player.Name.." ("..tostring(err)..").")
end
end)
--PLAYERREMOVING EVENT (Player leaving)
PlayerService.PlayerRemoving:Connect(function(player)
if player.leaderstats:FindFirstChild("Kills") then --When a player is leaving, we check whether the player still has the Kills IntValue (Though I like to keep stuff clean without errors hence I did this. The if check is optional if you're sure that the Kills IntValue instance will not be removed or changed.)
local success,err = pcall(function()
DS:SetAsync(player.UserId, player.leaderstats.Kills.Value)
end) --pcall function that saves the player kills inside the DataStore.
if success then --If it was successful, it'll print out this message.
print("Player data saved for user "..player.Name)
else -- if there was an error and saving has failed, the error will be printed out here.
warn("Failed to save kills data for user "..player.Name..". ("..tostring(err)..").")
end
end
end)
Hope I was able to help you out.
EDIT: Fixed a few errors in my code.
Sorry, I was at a funeral yesterday. I am going to test this out!
@CodeOverloader Yeah, place it there and it should work. Let me know if there are any errors as I’ve written that without testing.
@thebulldogs22ALT
This might be on me, but the kills aren’t accounted for. Any ideas?
I have a kill effects script that might be the problem but I don’t know.
This is in starter Character:
local Children = game.workspace.OffHeads:GetChildren()
local num = math.random(1,5)
if num == 1 then
wait(3)
script.Parent.Humanoid.Died:Connect(function()
local Children = script.Parent:GetChildren()
for i = 1, #Children do
Children[i].Transparency = 1
end
end)
local Humanoid = script.parent.Humanoid
local Character = script.Parent
local Part = game.workspace.Model
for i = 1, #Children do
script.Parent.Humanoid.Died:Connect(function()
Children[i].Anchored = false
Children[i].Position = script.Parent.UpperTorso.Position
end)
end
elseif num == 2 then
wait(3)
script.Parent.Humanoid.Died:Connect(function()
local Children = script.Parent:GetChildren()
for i = 1, #Children do
Children[i].Transparency = 1
end
end)
local Humanoid = script.parent.Humanoid
local Character = script.Parent
local Part1 = game.workspace.Cake
local Children = game.workspace.Cake:GetChildren()
for i = 1, #Children do
script.Parent.Humanoid.Died:Connect(function()
Children[i].Anchored = false
Children[i].Position = script.Parent.UpperTorso.Position
end)
end
elseif num == 3 then
--------------------------------------------------------
---------- Version 2.0 ---------------------------------
---------- Released 8/17/2017 --------------------------
---------- Written by orange451 ------------------------
--------------------------------------------------------
wait();
local DEBUG = false;
function waitFor( directory, name )
while ( directory == nil or (name ~= nil and directory:FindFirstChild(name) == nil) ) do
wait(0.1);
end
if ( name == nil ) then
return directory;
else
return directory:FindFirstChild(name);
end
end
function getCharacter()
return script.Parent;
end
function getPlayer()
return game.Players:GetPlayerFromCharacter(getCharacter());
end
function getHumanoid()
return waitFor( getCharacter(), "Humanoid" );
end
function getNearestPlayer( position )
local Players = game.Players:GetChildren();
local dist = math.huge;
local ret = nil;
for i=1,#Players do
local Player = Players[i];
local Character = Player.Character;
if ( Character ~= nil ) then
local Root = Character:FindFirstChild("HumanoidRootPart");
if ( Root ~= nil ) then
local t = (position - Root.Position).magnitude;
if ( t < dist ) then
dist = t;
ret = Player;
end
end
end
end
return ret;
end
local RootLimbData = {
{
["WeldTo"] = "LowerTorso",
["WeldRoot"] = "HumanoidRootPart",
["AttachmentName"] = "Root",
["NeedsCollider"] = false,
["UpperAngle"] = 10
},
{
["WeldTo"] = "UpperTorso",
["WeldRoot"] = "LowerTorso",
["AttachmentName"] = "Waist",
["ColliderOffset"] = CFrame.new(0, 0.5, 0),
["UpperAngle"] = 0
},
{
["WeldTo"] = "Head",
["WeldRoot"] = "UpperTorso",
["AttachmentName"] = "Neck",
["ColliderOffset"] = CFrame.new(),
["UpperAngle"] = 20
},
{
["WeldTo"] = "LeftUpperLeg",
["WeldRoot"] = "LowerTorso",
["AttachmentName"] = "LeftHip",
["ColliderOffset"] = CFrame.new(0, -0.5, 0)
},
{
["WeldTo"] = "RightUpperLeg",
["WeldRoot"] = "LowerTorso",
["AttachmentName"] = "RightHip",
["ColliderOffset"] = CFrame.new(0, -0.5, 0)
},
{
["WeldTo"] = "RightLowerLeg",
["WeldRoot"] = "RightUpperLeg",
["AttachmentName"] = "RightKnee",
["ColliderOffset"] = CFrame.new(0, -0.5, 0)
},
{
["WeldTo"] = "LeftLowerLeg",
["WeldRoot"] = "LeftUpperLeg",
["AttachmentName"] = "LeftKnee",
["ColliderOffset"] = CFrame.new(-0.05, -0.5, 0)
},
{
["WeldTo"] = "RightUpperArm",
["WeldRoot"] = "UpperTorso",
["AttachmentName"] = "RightShoulder",
["ColliderOffset"] = CFrame.new(0.05, 0.45, 0.15),
},
{
["WeldTo"] = "LeftUpperArm",
["WeldRoot"] = "UpperTorso",
["AttachmentName"] = "LeftShoulder",
["ColliderOffset"] = CFrame.new(0, 0.45, 0.15),
},
{
["WeldTo"] = "LeftLowerArm",
["WeldRoot"] = "LeftUpperArm",
["AttachmentName"] = "LeftElbow",
["ColliderOffset"] = CFrame.new(0, 0.125, 0),
["UpperAngle"] = 10
},
{
["WeldTo"] = "RightLowerArm",
["WeldRoot"] = "RightUpperArm",
["AttachmentName"] = "RightElbow",
["ColliderOffset"] = CFrame.new(0, 0.125, 0),
["UpperAngle"] = 10
},
{
["WeldTo"] = "RightHand",
["WeldRoot"] = "RightLowerArm",
["AttachmentName"] = "RightWrist",
["ColliderOffset"] = CFrame.new(0, 0.125, 0),
["UpperAngle"] = 0
},
{
["WeldTo"] = "LeftHand",
["WeldRoot"] = "LeftLowerArm",
["AttachmentName"] = "LeftWrist",
["ColliderOffset"] = CFrame.new(0, 0.125, 0),
["UpperAngle"] = 0
},
{
["WeldTo"] = "LeftFoot",
["WeldRoot"] = "LeftLowerLeg",
["AttachmentName"] = "LeftAnkle",
["NeedsCollider"] = false,
["UpperAngle"] = 0
},
{
["WeldTo"] = "RightFoot",
["WeldRoot"] = "RightLowerLeg",
["AttachmentName"] = "RightAnkle",
["NeedsCollider"] = false,
["UpperAngle"] = 0
},
}
local RootPart = nil;
local MotorList = {};
local GlueList = {};
local ColliderList = {};
function deactivate()
print("Unragdolling");
if ( RootPart == nil ) then
return;
end
-- Move to Players Location
local UpperTorso = getCharacter():FindFirstChild("UpperTorso");
if ( UpperTorso ~= nil ) then
UpperTorso:SetNetworkOwner(nil);
RootPart.CFrame = UpperTorso.CFrame;
end
-- Replace Motors
for i=1,#MotorList do
local MotorData = MotorList[i];
local PartTo = MotorData[1];
local Motor = MotorData[2];
Motor.Parent = PartTo;
end
-- Remove Glues
for i=1,#GlueList do
GlueList[i]:Destroy();
end
-- Remove Colliders
for i=1,#ColliderList do
ColliderList[i]:Destroy();
end
-- Replace Humanoid Stuff
getHumanoid().PlatformStand = false;
RootPart.Parent = getCharacter();
-- Restart
MotorList = {};
GlueList = {};
RootPart = nil;
end
function activate()
print("Ragdolling");
local Character = getCharacter();
local Humanoid = getHumanoid();
local HumanoidRoot = script.Parent:FindFirstChild("HumanoidRootPart");
if ( HumanoidRoot == nil ) then
print("Cannot create ragdoll");
return;
end
local Position = script.Parent.HumanoidRootPart.Position;
Humanoid.PlatformStand = true;
-- Handle death specific ragdoll. Will Clone you, then destroy you.
local RagDollModel = Character;
if ( (Humanoid.Health <= 0) and script.ActivateOnDeath.CloneAndDestroy.Value ) then
Character:FindFirstChild("HumanoidRootPart"):Destroy();
Character.Archivable = true;
RagDollModel = Character:Clone();
RagDollModel.Name = "RagDoll";
local t = RagDollModel:GetChildren();
for i=1,#t do
local t2 = t[i];
if ( t2:IsA("Script") or t2:IsA("LocalScript") ) then
t2:Destroy();
end
end
spawn(function()
wait();
RagDollModel.Humanoid.PlatformStand = true;
game.Debris:AddItem(RagDollModel, script.ActivateOnDeath.CloneAndDestroy.Delay.Value);
end)
RagDollModel.Humanoid.DisplayDistanceType = Enum.HumanoidDisplayDistanceType.None;
RagDollModel.Humanoid.HealthDisplayType = Enum.HumanoidHealthDisplayType.AlwaysOff;
RagDollModel.Humanoid.Health = 0;
RagDollModel.Parent = game.Workspace;
local RagDollPointer = Instance.new("ObjectValue");
RagDollPointer.Value = RagDollModel;
RagDollPointer.Name = "RagDoll";
RagDollPointer.Parent = Character;
end
-- Reglue The Character
for i=1,#RootLimbData do
local limbData = RootLimbData[i];
local partName = limbData["WeldTo"];
local weldName = limbData["WeldRoot"];
local PartTo = RagDollModel:FindFirstChild(partName);
local WeldTo = RagDollModel:FindFirstChild(weldName);
if ( PartTo ~= nil and WeldTo ~= nil ) then
if ( RagDollModel ~= nil ) then
if ( script.ApplyRandomVelocity.Value ) then
local scale = script.ApplyRandomVelocity.Force.Value;
local vecX = (math.random()-math.random())*scale;
local vecY = (math.random()-math.random())*scale;
local vecZ = (math.random()-math.random())*scale;
PartTo.Velocity = PartTo.Velocity + Vector3.new(vecX, vecY, vecZ);
end
PartTo.Parent = RagDollModel;
end
-- Create New Constraint
local UpperAngle = limbData["UpperAngle"];
local Joint = Instance.new("BallSocketConstraint");
if ( (UpperAngle ~= nil and UpperAngle == 0) or (script.WeldHead.Value and partName == "Head") ) then
Joint = Instance.new("HingeConstraint");
Joint.UpperAngle = 0;
Joint.LowerAngle = 0;
end
Joint.Name = limbData["AttachmentName"];
Joint.LimitsEnabled = true;
Joint.Attachment0 = PartTo:FindFirstChild(Joint.Name .. "RigAttachment");
Joint.Attachment1 = WeldTo:FindFirstChild(Joint.Name .. "RigAttachment");
Joint.Parent = PartTo;
GlueList[#GlueList+1] = Joint;
if ( UpperAngle ~= nil ) then
Joint.UpperAngle = UpperAngle;
end
-- Destroy the motor attaching it
local Motor = PartTo:FindFirstChildOfClass("Motor6D");
if ( Motor ~= nil ) then
if ( Humanoid.Health <= 0 ) then
Motor:Destroy();
else
MotorList[#MotorList+1] = { PartTo, Motor };
Motor.Parent = nil;
end
end
-- Create Collider
local needsCollider = limbData["NeedsCollider"];
if ( needsCollider == nil ) then
needsCollider = true;
end
if ( needsCollider ) then
local B = Instance.new("Part");
B.CanCollide = true;
B.TopSurface = 0;
B.BottomSurface = 0;
B.formFactor = "Symmetric";
B.Size = Vector3.new(0.7, 0.7, 0.7);
B.Transparency = 1;
B.BrickColor = BrickColor.Red();
B.Parent = RagDollModel;
local W = Instance.new("Weld");
W.Part0 = PartTo;
W.Part1 = B;
W.C0 = limbData["ColliderOffset"];
W.Parent = PartTo;
ColliderList[#ColliderList+1] = B;
end
end
end
-- Destroy Root Part
local root = Character:FindFirstChild("HumanoidRootPart");
if ( root ~= nil ) then
RootPart = root;
if ( Humanoid.Health <= 0 ) then
RootPart:Destroy();
else
RootPart.Parent = nil;
end
end
-- Delete all my parts if we made a new ragdoll
if ( RagDollModel ~= Character ) then
print("Deleting character");
local children = Character:GetChildren();
for i=1,#children do
local child = children[i];
if ( child:IsA("BasePart") or child:IsA("Accessory") ) then
child:Destroy();
end
end
end
-- Give player physics
if ( script.GivePlayerPhysics.Value ) then
local PlayerPhysics = getPlayer();
if ( script.GivePlayerPhysics.ForceNearestPlayer.Value ) then
PlayerPhysics = getNearestPlayer( Position );
end
local Children = RagDollModel:GetChildren();
for i=1,#Children do
local Child = Children[i];
if ( Child:IsA("BasePart") ) then
Child:SetNetworkOwner(PlayerPhysics);
end
end
end
-- Copy plugins into ragdoll
local Plugins = script.Plugins:GetChildren();
for i=1,#Plugins do
local Plugin = Plugins[i];
local Copy = Plugin:Clone();
if ( Copy:IsA("Script") ) then
Copy.Disabled = false;
end
Copy.Parent = RagDollModel;
end
end
-- Wait for torso (assume everything else will load at the same time)
waitFor( getCharacter(), "UpperTorso" );
-- Activate when we die.
getHumanoid().Died:Connect(function()
if ( script.ActivateOnDeath.Value ) then
script.Activate.Value = true;
end
end);
-- Activate when setting is checked.
script.Activate.Changed:Connect(function(value)
if ( value ) then
activate();
else
deactivate();
end
end);
-- Activate it on start.
if ( script.Activate.Value ) then
activate();
end
elseif num == 4 then
wait(3)
script.Parent.Humanoid.Died:Connect(function()
local Children = script.Parent:GetChildren()
for i = 1, #Children do
Children[i].Transparency = 1
end
end)
gold = workspace["R15 Dummy"]
local Children = game.workspace["R15 Dummy"]:GetChildren()
for i = 1, #Children do
script.Parent.Humanoid.Died:Connect(function()
Children[i].Position = script.Parent.UpperTorso.Position
wait (1)
Children[i].Anchored = false
end)
end
elseif num == 5 then
wait(3)
script.Parent.Humanoid.Died:Connect(function()
local Children = script.Parent:GetChildren()
for i = 1, #Children do
Children[i].Transparency = 1
end
end)
gold = workspace.Anvil
script.Parent.Humanoid.Died:Connect(function()
workspace.Anvil.Position = script.Parent.UpperTorso.Position
wait (1)
workspace.Anvil.Anchored = false
end)
elseif num == 6 then
local hum = script.Parent:WaitForChild("Humanoid")
local anim = hum:LoadAnimation(script:FindFirstChildOfClass("Animation"))
anim:Play()
end
And im an idiot. I didn’t turn on API services. My fault.
Do I put your first script in every weapon?
Yeah, put it inside of every weapon script.