Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

Can I have some Help on modifying a script to only do damage to zombies?

Hello scripters! I am making a game like dungeon quest and I need to make the damage script inside of my rocket launcher to only do damage to models that have a humanoid named "Zombie" and not to do damage to models that have a humanoid named "Humanoid" So I have been modifying the script that does damage to a humanoid. So I have made there is a variable that says what humanoid is. So it used to be this:

local function FindCharacterAncestor(subject)
	if subject and subject ~= workspace then
		local Humanoid = subject:FindFirstChildOfClass('Humanoid')
		if Humanoid  then
			return subject, Humanoid
		else
			return FindCharacterAncestor(subject.Parent)
		end
	end
	return nil
end

I changed it to :

local function FindCharacterAncestor(subject)
	if subject and subject ~= workspace then
		local Humanoid = subject:FindFirstChildOfClass('Zombie')
		if Humanoid  then
			return subject, Humanoid
		else
			return FindCharacterAncestor(subject.Parent)
		end
	end
	return nil
end

So when I do this then I shoot the zombies and it one shots them which already is not what i want but ALSO it one shots me too! I dont know why this is happening and would like some help. There are two scripts one that launches the rocket and one that makes the explosion and does the damage.

Here is the launch script (Which is inside of the tool)

-----------------
--| Constants |--
-----------------

local GRAVITY_ACCELERATION = workspace.Gravity

local RELOAD_TIME = 1.5 -- Seconds until tool can be used again
local ROCKET_SPEED = 60 -- Speed of the projectile

local MISSILE_MESH_ID = 'http://www.roblox.com/asset/?id=2251534'
local MISSILE_MESH_SCALE = Vector3.new(0.35, 0.35, 0.25)
local ROCKET_PART_SIZE = Vector3.new(1.2, 1.2, 3.27)

-----------------
--| Variables |--
-----------------

local DebrisService = game:GetService('Debris')
local PlayersService = game:GetService('Players')

local MyPlayer

local Tool = script.Parent
local ToolHandle = Tool:WaitForChild("Handle")

local MouseLoc = Tool:WaitForChild("MouseLoc",10)

local RocketScript = script:WaitForChild('Rocket')
local SwooshSound = script:WaitForChild('Swoosh')
local BoomSound = script:WaitForChild('Boom')

--NOTE: We create the rocket once and then clone it when the player fires
local Rocket = Instance.new('Part') do
	-- Set up the rocket part
	Rocket.Name = 'Rocket'
	Rocket.FormFactor = Enum.FormFactor.Custom --NOTE: This must be done before changing Size
	Rocket.Size = ROCKET_PART_SIZE
	Rocket.CanCollide = false

	-- Add the mesh
	local mesh = Instance.new('SpecialMesh', Rocket)
	mesh.MeshId = MISSILE_MESH_ID
	mesh.Scale = MISSILE_MESH_SCALE

	-- Add fire
	local fire = Instance.new('Fire', Rocket)
	fire.Heat = 5
	fire.Size = 2

	-- Add a force to counteract gravity
	local bodyForce = Instance.new('BodyForce', Rocket)
	bodyForce.Name = 'Antigravity'
	bodyForce.Force = Vector3.new(0, Rocket:GetMass() * GRAVITY_ACCELERATION, 0)

	-- Clone the sounds and set Boom to PlayOnRemove
	local swooshSoundClone = SwooshSound:Clone()
	swooshSoundClone.Parent = Rocket
	local boomSoundClone = BoomSound:Clone()
	boomSoundClone.PlayOnRemove = true
	boomSoundClone.Parent = Rocket

	-- Attach creator tags to the rocket early on
	local creatorTag = Instance.new('ObjectValue', Rocket)
	creatorTag.Value = MyPlayer
	creatorTag.Name = 'creator' --NOTE: Must be called 'creator' for website stats
	local iconTag = Instance.new('StringValue', creatorTag)
	iconTag.Value = Tool.TextureId
	iconTag.Name = 'icon'

	-- Finally, clone the rocket script and enable it
	local rocketScriptClone = RocketScript:Clone()
	rocketScriptClone.Parent = Rocket
	rocketScriptClone.Disabled = false
end

-----------------
--| Functions |--
-----------------

local function OnActivated()
	local myModel = MyPlayer.Character
	if Tool.Enabled and myModel and myModel:FindFirstChildOfClass("Humanoid") and myModel.Humanoid.Health > 0 then
		Tool.Enabled = false
		local Pos = MouseLoc:InvokeClient(MyPlayer)
		-- Create a clone of Rocket and set its color
		local rocketClone = Rocket:Clone()
		DebrisService:AddItem(rocketClone, 30)
		rocketClone.BrickColor = MyPlayer.TeamColor

		-- Position the rocket clone and launch!
		local spawnPosition = (ToolHandle.CFrame * CFrame.new(5, 0, 0)).p
		rocketClone.CFrame = CFrame.new(spawnPosition, Pos) --NOTE: This must be done before assigning Parent
		rocketClone.Velocity = rocketClone.CFrame.lookVector * ROCKET_SPEED --NOTE: This should be done before assigning Parent
		rocketClone.Parent = workspace
		rocketClone:SetNetworkOwner(nil)

		wait(RELOAD_TIME)

		Tool.Enabled = true
	end
end

function OnEquipped()
	MyPlayer = PlayersService:GetPlayerFromCharacter(Tool.Parent)
end

--------------------
--| Script Logic |--
--------------------

Tool.Equipped:Connect(OnEquipped)
Tool.Activated:Connect(OnActivated)

Here is the damage script which i have modified the humanoid variable to only attack zombies (Which is inside of the launch script)

-----------------
--| Constants |--
-----------------
local BLAST_RADIUS = 8 -- Blast radius of the explosion
local BLAST_DAMAGE = 1 -- Amount of damage done to players
local BLAST_FORCE = 1000 -- Amount of force applied to parts

local IGNORE_LIST = {rocket = 1, handle = 1, effect = 1, water = 1} -- Rocket will fly through things named these
--NOTE: Keys must be lowercase, values must evaluate to true

-----------------
--| Variables |--
-----------------

local DebrisService = game:GetService('Debris')
local PlayersService = game:GetService('Players')

local Rocket = script.Parent

local CreatorTag = Rocket:WaitForChild('creator')
local SwooshSound = Rocket:WaitForChild('Swoosh')

-----------------
--| Functions |--
-----------------

-- Removes any old creator tags and applies a new one to the target
local function ApplyTags(target)
	while target:FindFirstChild('creator') do
		target.creator:Destroy()
	end

	local creatorTagClone = CreatorTag:Clone()
	DebrisService:AddItem(creatorTagClone, 1.5)
	creatorTagClone.Parent = target
end

-- Returns the ancestor that contains a Humanoid, if it exists
local function FindCharacterAncestor(subject)
	if subject and subject ~= workspace then
		local Humanoid = subject:FindFirstChildOfClass('Zombie')
		if Humanoid  then
			return subject, Humanoid
		else
			return FindCharacterAncestor(subject.Parent)
		end
	end
	return nil
end

local function IsInTable(Table,Value)
	for _,v in pairs(Table) do
		if v == Value then
			return true
		end
	end
	return false
end

-- Customized explosive effect that doesn't affect teammates and only breaks joints on dead parts
local TaggedHumanoids = {}
local function OnExplosionHit(hitPart, hitDistance, blastCenter)
	if hitPart and hitDistance then
		 local character, Humanoid = FindCharacterAncestor(hitPart.Parent)

		if character then
			local myPlayer = CreatorTag.Value
			if myPlayer and not myPlayer.Neutral then -- Ignore friendlies caught in the blast
				local player = PlayersService:GetPlayerFromCharacter(character)
				if player and player ~= myPlayer and player.TeamColor == Rocket.BrickColor then
					return
				end
			end
		end

		if Humanoid and Humanoid.Health > 0 then -- Humanoids are tagged and damaged
			if not IsInTable(TaggedHumanoids,Humanoid) then
				print("Tagged")
				table.insert(TaggedHumanoids,Humanoid)
				ApplyTags(Humanoid)
				Humanoid:TakeDamage(BLAST_DAMAGE)
				
			
			end
		else -- Loose parts and dead parts are blasted
			if hitPart.Name ~= 'Handle' then
				hitPart:BreakJoints()
				local blastForce = Instance.new('BodyForce', hitPart) --NOTE: We will multiply by mass so bigger parts get blasted more
				blastForce.Force = (hitPart.Position - blastCenter).unit * BLAST_FORCE * hitPart:GetMass()
				DebrisService:AddItem(blastForce, 0.1)
			end
		end
	end
end

local function OnTouched(otherPart)
	if Rocket and otherPart then
		-- Fly through anything in the ignore list
		if IGNORE_LIST[string.lower(otherPart.Name)] then
			return
		end

		local myPlayer = CreatorTag.Value
		if myPlayer then
			-- Fly through the creator
			if myPlayer.Character and myPlayer.Character:IsAncestorOf(otherPart) then
				return
			end

			 -- Fly through friendlies
			if not myPlayer.Neutral then
				local character = FindCharacterAncestor(otherPart.Parent)
				local player = PlayersService:GetPlayerFromCharacter(character)
				if player and player ~= myPlayer and player.TeamColor == Rocket.BrickColor then
					return
				end
			end
		end

		-- Fly through terrain water
		if otherPart == workspace.Terrain then
			--NOTE: If the rocket is large, then the simplifications made here will cause it to fly through terrain in some cases
			local frontOfRocket = Rocket.Position + (Rocket.CFrame.lookVector * (Rocket.Size.Z / 2))
			local cellLocation = workspace.Terrain:WorldToCellPreferSolid(frontOfRocket)
			local cellMaterial = workspace.Terrain:GetCell(cellLocation.X, cellLocation.Y, cellLocation.Z)
			if cellMaterial == Enum.CellMaterial.Water or cellMaterial == Enum.CellMaterial.Empty then
				return
			end
		end

		-- Create the explosion
		local explosion = Instance.new('Explosion')
		explosion.BlastPressure = 0 -- Completely safe explosion
		explosion.BlastRadius = BLAST_RADIUS
		explosion.ExplosionType = Enum.ExplosionType.NoCraters
		explosion.Position = Rocket.Position
		explosion.Parent = workspace

		-- Connect custom logic for the explosion
		explosion.Hit:Connect(function(hitPart, hitDistance) OnExplosionHit(hitPart, hitDistance, explosion.Position) end)

		-- Move this script and the creator tag (so our custom logic can execute), then destroy the rocket
		script.Parent = explosion
		CreatorTag.Parent = script
		Rocket:Destroy()
	end
end

--------------------
--| Script Logic |--
--------------------

SwooshSound:Play()

Rocket.Touched:Connect(OnTouched)

1 answer

Try:

Change this function to as follows:

From :

-- Returns the ancestor that contains a Humanoid, if it exists
local function FindCharacterAncestor(subject)
    if subject and subject ~= workspace then
        local Humanoid = subject:FindFirstChildOfClass('Zombie')
        if Humanoid then
            return subject, Humanoid
        else
            return FindCharacterAncestor(subject.Parent)
        end
    end
    return nil
end

To :

-- Returns the ancestor that contains a Humanoid, if it exists
local function FindCharacterAncestor(subject)
    if subject and subject ~= workspace then
        local Humanoid = subject:FindFirstChildOfClass('Humanoid')
        if Humanoid and Humanoid.Name == "Zombie" then
            return subject, Humanoid
        else
            return FindCharacterAncestor(subject.Parent)
        end
    end
    return nil
end

For the explosion, you need to add a little switch called "DestroyJointRadiusPercent" this value handles what the chances of the joints being hit are being broken

As for you 1 shoting zombies they die when their neck joints are broken. Explosions are good with this! as Follows:

    -- Create the explosion
    local explosion = Instance.new('Explosion')
    explosion.BlastPressure = 0 -- Completely safe explosion
    explosion.BlastRadius = BLAST_RADIUS
    explosion.ExplosionType = Enum.ExplosionType.NoCraters
    explosion.Position = Rocket.Position
    explosion.Parent = workspace
    --// add this to stop the one shot kills!:
   explosion.DestroyJointRadiusPercent = 0

Might need to spell check that explosion Value as i typed it from memory lol.

Hope this helps!

This discussion is preserved as it was. New answers, comments, and votes are closed.