Hi, Scripters!
Today, I had a problem with switching a player’s sword after buying a game pass. They start off with the default ClassicSword and when they buy a game pass, it should switch that sword with the Illumina, another sword off Roblox’s free models. I currently have the Illumina in ReplicatedStorage and the sword in the player’s StarterPack. Here are my problems:
The Illumina does go to the inventory as the second tool (first one is the ClassicSword) but it is no longer usable (I’ve tested it as a tool by itself and when put in the StarterPack, it works just fine
Secondary problem: The ClassicSword remains in the inventory and I’m not sure how to remove it once the game pass is owned
The script is in StarterCharacterScripts as a local script. Here it is:
local MarketplaceService = game:GetService("MarketplaceService")
local button = game.Workspace.GamepassPart2.Gamepass.Holder.IlluminaButton
local player = game.Players.LocalPlayer
button.MouseButton1Click:Connect(function()
print("Activated button")
MarketplaceService:PromptGamePassPurchase(player, 26235406)
print("Gamepass prompted")
end)
local OwnsGamepass = MarketplaceService:UserOwnsGamePassAsync(player.UserId, 26235406)
if OwnsGamepass then
local sword = game:GetService("ReplicatedStorage"):WaitForChild("Illumina"):Clone()
sword.Parent = player.Backpack
end
Thanks so much to anyone that can help! I’ll be waiting to respond to any questions or comments!
You could put the sword in server storage to fix the first issue and for the second one use this script
local MarketplaceService = game:GetService("MarketplaceService")
local button = game.Workspace.GamepassPart2.Gamepass.Holder.IlluminaButton
local player = game.Players.LocalPlayer
button.MouseButton1Click:Connect(function()
print("Activated button")
MarketplaceService:PromptGamePassPurchase(player, 26235406)
print("Gamepass prompted")
end)
local OwnsGamepass = MarketplaceService:UserOwnsGamePassAsync(player.UserId, 26235406)
if OwnsGamepass then
local sword = game:GetService("ServerStorage"):WaitForChild("Illumina"):Clone()
sword.Parent = player.Backpack
if plr.Backpack:FindFirstChild("ClassicSword")then
plr.Backpack.ClassicSword:Destroy()
elseif plr.Character:FindFirstChild("ClassicSword")then
plr.Character.ClassicSword:Destroy()
end
end
Edit: my bad, this is a local script so it wont work in server storage, try rep storage
local MarketplaceService = game:GetService("MarketplaceService")
local button = game.Workspace.GamepassPart2.Gamepass.Holder.IlluminaButton
local player = game.Players.LocalPlayer
button.MouseButton1Click:Connect(function()
print("Activated button")
MarketplaceService:PromptGamePassPurchase(player, 26235406)
print("Gamepass prompted")
end)
local OwnsGamepass = MarketplaceService:UserOwnsGamePassAsync(player.UserId, 26235406)
if OwnsGamepass then
local sword = game:GetService("ReplicatedStorage"):WaitForChild("Illumina"):Clone()
sword.Parent = player.Backpack
else
local sword = game:GetService("ReplicatedStorage"):WaitForChild("ClassicSword"):Clone()
sword.Parent = player.Backpack
end
Try putting them back in replicated storage if this doesn’t work then you could try putting it inside the script.
Is the script for the illumina sword inside the sword
Ok great, so Illumina is in my inventory now, but it just doesn’t function as intended. Want me to show you the script inside the sword or is that not the problem?
I triple checked with only this in the StarterPack and it works fine (Thanks so much for working through this with me). By “doesn’t work”, I mean the animation doesn’t play when the player clicks and the damage isn’t dealt when the sword touches a player.
-------- OMG HAX
r = game:service("RunService")
local damage = 10
local slash_damage = 20
local lunge_damage = 40
sword = script.Parent.Handle
Tool = script.Parent
local SlashSound = Instance.new("Sound")
SlashSound.SoundId = "rbxasset://sounds\\swordslash.wav"
SlashSound.Parent = sword
SlashSound.Volume = .7
local LungeSound = Instance.new("Sound")
LungeSound.SoundId = "rbxasset://sounds\\swordlunge.wav"
LungeSound.Parent = sword
LungeSound.Volume = .6
local UnsheathSound = Instance.new("Sound")
UnsheathSound.SoundId = "rbxasset://sounds\\unsheath.wav"
UnsheathSound.Parent = sword
UnsheathSound.Volume = 1
function blow(hit)
local humanoid = hit.Parent:findFirstChild("Humanoid")
local vCharacter = Tool.Parent
local vPlayer = game.Players:playerFromCharacter(vCharacter)
local hum = vCharacter:findFirstChild("Humanoid") -- non-nil if tool held by a character
if humanoid~=nil and humanoid ~= hum and hum ~= nil then
-- final check, make sure sword is in-hand
local right_arm = vCharacter:FindFirstChild("Right Arm")
if (right_arm ~= nil) then
local joint = right_arm:FindFirstChild("RightGrip")
if (joint ~= nil and (joint.Part0 == sword or joint.Part1 == sword)) then
tagHumanoid(humanoid, vPlayer)
humanoid:TakeDamage(damage)
end
end
end
end
function tagHumanoid(humanoid, player)
local creator_tag = Instance.new("ObjectValue")
creator_tag.Value = player
creator_tag.Name = "creator"
creator_tag.Parent = humanoid
game.Debris:AddItem(creator_tag, 1)
end
function attack()
damage = slash_damage
SlashSound:play()
local anim = Instance.new("StringValue")
anim.Name = "toolanim"
anim.Value = "Slash"
anim.Parent = Tool
end
function lunge()
damage = lunge_damage
LungeSound:play()
local anim = Instance.new("StringValue")
anim.Name = "toolanim"
anim.Value = "Lunge"
anim.Parent = Tool
local force = Instance.new("BodyVelocity")
force.velocity = Vector3.new(0,80,0)
force.Parent = Tool.Parent.UpperTorso
wait(.25)
force.velocity = (Tool.Parent.UpperTorso.CFrame.lookVector * 120) + Vector3.new(0, 60,0)
swordOut()
wait(.5)
force.Parent = nil
wait(.5)
swordUp()
damage = slash_damage
end
function swordUp()
Tool.GripForward = Vector3.new(-1,0,0)
Tool.GripRight = Vector3.new(0,1,0)
Tool.GripUp = Vector3.new(0,0,1)
end
function swordOut()
Tool.GripForward = Vector3.new(0,0,1)
Tool.GripRight = Vector3.new(0,-1,0)
Tool.GripUp = Vector3.new(-1,0,0)
end
function swordAcross()
-- parry
end
Tool.Enabled = true
local last_attack = 0
function onActivated()
if not Tool.Enabled then
return
end
Tool.Enabled = false
local character = Tool.Parent;
local humanoid = character.Humanoid
if humanoid == nil then
print("Humanoid not found")
return
end
local t = r.Stepped:wait()
if (t - last_attack < .2) then
lunge()
else
attack()
end
last_attack = t
--wait(.5)
Tool.Enabled = true
end
function onEquipped()
UnsheathSound:play()
end
script.Parent.Activated:connect(onActivated)
script.Parent.Equipped:connect(onEquipped)
connection = sword.Touched:connect(blow)
After figuring out you have no animation, I implemented animation and then
ignored if you checked for humanoid
Result:
and then I came back to this code.
r = game:service("RunService")
local damage = 10
local Players = game:GetService("Players")
local player = Players:FindFirstChildOfClass("Player")
local slash_damage = 20
local lunge_damage = 40
local plrshumanoid = player.Character:FindFirstChildOfClass("Humanoid")
sword = script.Parent.Handle
Tool = script.Parent
local BaseUrl = "rbxassetid://"
local SlashSound = Instance.new("Sound")
SlashSound.SoundId = "rbxasset://sounds\\swordslash.wav"
SlashSound.Parent = sword
SlashSound.Volume = .7
local LungeSound = Instance.new("Sound")
LungeSound.SoundId = "rbxasset://sounds\\swordlunge.wav"
LungeSound.Parent = sword
LungeSound.Volume = .6
local UnsheathSound = Instance.new("Sound")
UnsheathSound.SoundId = "rbxasset://sounds\\unsheath.wav"
UnsheathSound.Parent = sword
UnsheathSound.Volume = 1
function blow(hit)
local humanoid = hit.Parent:FindFirstChild("Humanoid")
local vCharacter = Tool.Parent
local vPlayer = game.Players:playerFromCharacter(vCharacter)
local hum = vCharacter:WaitForChild("Humanoid")
-- non-nil if tool held by a character
if not hit then
print("Not hit")
return
end
tagHumanoid(humanoid, vPlayer)
humanoid:TakeDamage(damage)
end
function tagHumanoid(humanoid, player)
local creator_tag = Instance.new("ObjectValue")
creator_tag.Value = player
creator_tag.Name = "creator"
creator_tag.Parent = humanoid
game.Debris:AddItem(creator_tag, 1)
end
function attack()
damage = slash_damage
SlashSound:play()
local anim = Instance.new("StringValue")
anim.Name = "toolanim"
anim.Value = "Slash"
anim.Parent = Tool
end
function lunge()
damage = lunge_damage
LungeSound:play()
local anim = Instance.new("StringValue")
anim.Name = "toolanim"
anim.Value = "Lunge"
anim.Parent = Tool
local ranim = Instance.new("Animation")
ranim.AnimationId = "rbxassetid://522635514"
local Track
Track = plrshumanoid:LoadAnimation(ranim)
Track:Play()
local force = Instance.new("BodyVelocity")
force.velocity = Vector3.new(0,80,0)
force.Parent = Tool.Parent:FindFirstChild("UpperTorso")
wait(.25)
force.velocity = (Tool.Parent.UpperTorso.CFrame.lookVector * 120) + Vector3.new(0, 60,0)
swordOut()
wait(.5)
force.Parent = nil
wait(.5)
swordUp()
damage = slash_damage
end
function swordUp()
Tool.GripForward = Vector3.new(-1,0,0)
Tool.GripRight = Vector3.new(0,1,0)
Tool.GripUp = Vector3.new(0,0,1)
end
function swordOut()
Tool.GripForward = Vector3.new(0,0,1)
Tool.GripRight = Vector3.new(0,-1,0)
Tool.GripUp = Vector3.new(-1,0,0)
end
function swordAcross()
-- parry
end
Tool.Enabled = true
local last_attack = 0
function onActivated()
if not Tool.Enabled then
return
end
Tool.Enabled = false
local character = Tool.Parent;
local humanoid = character.Humanoid
if humanoid == nil then
print("Humanoid not found")
return
else
print("Yea")
end
local t = r.Stepped:wait()
if (t - last_attack < .2) then
lunge()
else
attack()
end
last_attack = t
--wait(.5)
Tool.Enabled = true
end
function onEquipped()
UnsheathSound:play()
end
Tool.Activated:Connect(onActivated)
Tool.Equipped:Connect(onEquipped)
sword.Touched:Connect(blow)
Currently you are only checking if they own the gamepass after their character loads, instead you should use PromptGamePassPurchaseFinished to also check after the purchase is made:
function DestroyTool(name)
--if the tool is found inside backpack, destroy it
local found = player.Backpack:FindFirstChild(name)
if found then
found:Destroy()
return
end
--if the tool is found inside their character(equipped), destroy it
found = player.Character:FindFirstChild(name)
if found then
found:Destroy()
return
end
end
function OnGamePassPurchase()
local sword = game:GetService("ReplicatedStorage"):WaitForChild("Illumina"):Clone()
sword.Parent = player.Backpack
DestroyTool("ClassicSword")
end
local OwnsGamepass = MarketplaceService:UserOwnsGamePassAsync(player.UserId, 26235406)
if OwnsGamepass then
OnGamePassPurchase()
end
MarketplaceService.PromptGamePassPurchaseFinished:Connect(function(player2, gamepass, wasPurchased)
if player == player2 and wasPurchased and gamepass == 26235406 then
OnGamePassPurchase()
end
end)
Replace the last few lines with this, and remove the OwnsGamepass variable:
if MarketplaceService:UserOwnsGamePassAsync(player.UserId, 26235406) and not player.Backpack:FindFirstChild("Illumina") then
local sword = game.ReplicatedStorage:FindFirstChild("Illumina"):Clone
sword.Parent = player.Backpack
end
It’s still not working for some reason, would you like to join my team create “Scripting Practice” that I shared with you so you can better see the problem?