Hello guys,
…So I have made a mob control system, but there is a problem:
After this line pop up, my mobs standing still
Well, after look up for the solution and applied it, nothing changed. So I need some help from you guys.
P/S: My code a little bit mess :)))
P/S2: Merry Christmas
How my scripts put
The code in server script
local _M = require(game.ServerStorage["GameModule[Server]"].Mob_Lib)
local WeaponFolder = game.ServerStorage.Tools
local MobHandlingModule = require(script.MainModule)
--Table used to keep track of all alive Mobs
local Mobs = {}
--Used to create new threads easily while avoid spawn()
function spawner(func,...)
local co = coroutine.wrap(func)
co(...)
end
local ChaseDist = 40
local DetectDist = 60
local DelayUpdTraget =.5
local wanderRange = 30
--------------------------
----Mob Handling----
--------------------------
function walkRandom(Mob)
local FirstPos = Mob.startpos
local randX = math.random(-wanderRange,wanderRange)
local randZ = math.random(-wanderRange,wanderRange)
local goal = FirstPos + Vector3.new(randX, 0, randZ)
Mob.human:MoveTo(goal)
if math.abs(Mob.human.WalkToPoint.Y - Mob.human.RootPart.Position.Y) >= 7 then
Mob.human.Jump = true
end
Mob.human.MoveToFinished:Wait(4)
end
function checkDist(part1,part2)
if part1 ~= nil and part2 ~= nil then
if typeof(part1) ~= Vector3 then part1 = part1.Position end
if typeof(part2) ~= Vector3 then part2 = part2.Position end
return (part1 - part2).Magnitude
end
return 0
end
function updateTarget()
for _,Mob in pairs(Mobs) do
local target = nil
local dist = DetectDist
for _,char in pairs(workspace:GetChildren()) do
if char:FindFirstChild("Humanoid") ~= nil then
local player_Hum = char:FindFirstChild("Humanoid")
local player_Root = player_Hum.RootPart
if player_Root and player_Hum.Health > 0 and checkDist(player_Root,Mob.human.RootPart) < dist then
target = player_Root
end
end
end
Mob.target = target
end
end
spawner(function()
while wait(DelayUpdTraget) do
updateTarget()
end
end)
--end
function pathToTarget(Mob)
local target = Mob.target
if target ~= nil then
if Mob.Type_Attack == 'Melee' then
Mob.human:MoveTo(target.Position, target)
Mob.human.MoveToFinished:Wait(.5)
elseif Mob.Type_Attack == 'Ranged' then
--Mob.human:MoveTo(target.Position, target)
end
end
if math.abs(Mob.human.WalkToPoint.Y - Mob.human.RootPart.Position.Y) >= 7 then
Mob.human.Jump = true
end
end
function movementHandler(Mob)
while wait(.5) do
if Mob.human.Health <= 0 then
break
end
if Mob.target and checkDist(Mob.target,Mob.human.RootPart) <= ChaseDist then
pathToTarget(Mob)
else
walkRandom(Mob)
end
end
end
spawner(function()
while wait(.5) do
for _,Mob in pairs(Mobs) do
if Mob.target then
if Mob.Type_Attack == "Melee" then
if checkDist(Mob.target,Mob.human.RootPart) < 7 and Mob.char:FindFirstChildOfClass("Tool") ~= nil then
require(script.MainModule).attack(Mob)
wait(.55)
end
elseif Mob.Type_Attack == "Ranged" then
if checkDist(Mob.target,Mob.human.RootPart) > 7 and checkDist(Mob.target,Mob.human.RootPart) < DetectDist and Mob.char:FindFirstChildOfClass("Tool") ~= nil then
require(script.MainModule).attack(Mob)
wait(.65)
end
end
end
end
end
end)
function addMob(MobHumanoid)
table.insert(Mobs,{
char = MobHumanoid.Parent,
human = MobHumanoid,
target = nil,---Locate the target
startpos = nil,---Locate the spawn
Boss = _M[MobHumanoid.Parent.Name].Boss,
clone = MobHumanoid.Parent:Clone(), --clone to respawn
-- AnimID = "rbxassetid://" .. _M[MobHumanoid.Parent.Name].AnimID,
lv =_M[MobHumanoid.Parent.Name].Moblv,
base_dmg = math.random( _M[MobHumanoid.Parent.Name].Moblv*1.25, _M[MobHumanoid.Parent.Name].Moblv*2.25),
hp = math.floor(math.random(_M[MobHumanoid.Parent.Name].MobHealth*1.25,_M[MobHumanoid.Parent.Name].MobHealth*2.25) ),
reward = {
["G"] =_M[MobHumanoid.Parent.Name].Moblv*5,
["X"] = _M[MobHumanoid.Parent.Name].Moblv*15
},
Type_Attack = _M[MobHumanoid.Parent.Name].Type_Attack ,
})
for _,Mob in pairs(Mobs) do
if Mob.human == MobHumanoid then
Mob.startpos = Mob.human.RootPart.Position
-------------------------
-------SETUP MOBS--------
spawner(function()
Mob.human.MaxHealth = Mob.hp
Mob.human.Health = Mob.human.MaxHealth
-- Mob.char.PrimaryPart = Mob.root
if not Mob.char:FindFirstChildOfClass("Tool") then
Mob.human:EquipTool(WeaponFolder[_M[Mob.human.Parent.Name].Tool]:Clone())
end
if not Mob.char:FindFirstChild("UpperTorso"):FindFirstChild("BillboardGui") then
local second_two = script.BillboardGui:Clone()
second_two.Parent = Mob.char.UpperTorso
MobHandlingModule.Healthbar(Mob)
end
Mob.human.Died:Connect(function() MobHandlingModule.died(Mob , Mobs) end)
------------------------
------------------------
for i,v in pairs(Mob.char:GetDescendants()) do
if v:IsA("BasePart") and v:CanSetNetworkOwnership() then
v:SetNetworkOwner(nil)
end
end
end)
spawner(movementHandler,Mob)
break
end
end
end
workspace.MobHolder.ChildAdded:Connect(function(Mob)
task.wait()
if Mob:FindFirstChild("Enemy") then
local MobHumanoid = Mob["Enemy"]
addMob(MobHumanoid)
-- wait()
end
end)
function intialize()
for _,v in pairs(workspace.MobHolder:GetChildren()) do
local enemy = v:FindFirstChild("Enemy")
if enemy ~= nil then
local found = false
for _,x in pairs(Mobs) do
if x.human == enemy then
found = true
end
end
if not found then
addMob(enemy)
end
end
end
end
wait(.5)
intialize()
The code in modulescript
local _M = require(game.ServerStorage["GameModule[Server]"].Mob_Lib)
local _MT = require(game.ReplicatedStorage.GameModule.Item_Lib)
local MicsDict = require(game.ReplicatedStorage.GameModule.Mics_Lib)
local MainDict = require(game.ReplicatedStorage.GameModule.ImportantStuff)
local WeaponFolder = game.ServerStorage.Tools
local TS = game:GetService("TweenService")
local xpcur = MainDict.Xp
local goldcur = MainDict.Currency3
local event_gold = game.ServerStorage.GameSettings.MultiCurrency.Value or 1
local event_xp = game.ServerStorage.GameSettings.MultiXp.Value or 1
local PercentReq = 30 -- 10%
local DesTime = 1 -- Despawn after dead
local GetTool = 25 -- 25%
local MeleAttack_animID = {'10825679651'}
local MeleeSoundTable = { "158037267" , "143501853" }
local CD = .5
local module = {}---------------------------------------------
module.DamageText = function (Enemy , dmg)
coroutine.resume(coroutine.create(function()
if Enemy then
local part = Instance.new("BillboardGui")
part.Size = UDim2.new(0,100,0,100)
part.StudsOffset = Vector3.new(0,1,0)
part.AlwaysOnTop = true
part.MaxDistance = 20
local part2 = Instance.new("TextLabel")
part2.Font = Enum.Font.ArialBold
part2.TextScaled = true
part2.TextStrokeTransparency = .7
part2.Size = UDim2.new(1,0,1,0)
part2.Position = UDim2.new(0,0,0,0)
part2.BackgroundTransparency = 1
part2.Parent = part
part.Parent = Enemy.Head or Enemy.HumanoidRootPart
part.Adornee = part.Parent
part2.TextColor3 = Color3.fromRGB(255, 255, 127)
part2.Text = tostring(math.floor(dmg))
game.TweenService:Create(part2 , TweenInfo.new(2 , Enum.EasingStyle.Linear ) , {Position = UDim2.new(0 ,0 , -3.4 , 0 ) , TextTransparency =.7} ):Play()
game.Debris:AddItem(part,2)
end
end))
end
function module.attack(Mob)
local _,E = coroutine.resume(coroutine.create(function()
local Mobtarget = Mob.target
local Mobchar = Mob.char
local MobHuman = Mob.human
local isCoolingDown = false
local AttackAnim =((not Mobchar:FindFirstChild("AttackAnim")) and Instance.new("Animation",Mobchar) or Mobchar["AttackAnim"])
AttackAnim.Name = "AttackAnim"
AttackAnim.AnimationId = "http://www.roblox.com/asset?id=" .. MeleAttack_animID[math.random(1,#MeleAttack_animID)]or ""
local sound = Instance.new("Sound")
sound.SoundId = "http://www.roblox.com/asset?id=" .. MeleeSoundTable[math.random(1, #MeleeSoundTable)]
sound.Parent = Mobchar
sound.Volume = .5
-- if not isCoolingDown or not Mobtarget then return end
--print("attack".. tostring(Mobtarget))
local AttackAnimTrack = MobHuman:LoadAnimation(AttackAnim)
AttackAnimTrack.Priority = Enum.AnimationPriority.Action
AttackAnimTrack:AdjustSpeed(AttackAnimTrack.Length /(CD) )
local player_Hum = Mobtarget.Parent:FindFirstChildOfClass("Humanoid")
if not player_Hum or player_Hum.Health <=0 then return end
isCoolingDown = true
sound:Play()
player_Hum:TakeDamage(Mob.base_dmg)
module.DamageText(Mobtarget.Parent,Mob.base_dmg)
AttackAnimTrack:Play(0)
task.wait(CD)
isCoolingDown = false
game.Debris:AddItem(sound,1)
end))
if E then error(E) end
end
-----------------------------
-----------------------------ON MOB DIED
-----------------------------
function give_tool(Player,Mob)
local Tool = WeaponFolder:FindFirstChild(_M[Mob.char.Name].Tool)
if math.random(1,100) == GetTool and Tool then
if #Player[MainDict.StatsFolder][MainDict.WeaponFolder]:GetChildren() < MainDict.WeaponCap then
local Toolinfo = MainDict.createInfo(Tool)
Toolinfo.Parent = Player[MainDict.StatsFolder][MainDict.WeaponFolder]
game.ReplicatedStorage.Remotes.Announcement:FireClient(Player, "You found " .. Tool.Name .. "[Mob]" , Color3.fromRGB(0, 255, 255))
else
game.ReplicatedStorage.Remotes.Announcement:FireClient(Player, "Inventory is full!" , Color3.fromRGB(255, 0, 0))
end
end
end
-----------------------------
-------------------------
function check_Quest(Player,Mob)
local MName = _M[Mob.char.Name].MobName
for i ,b in pairs(Player[MainDict.StatsFolder]:GetChildren()) do
if b:IsA("Folder") and string.find(b.Name,"MS:") then
if string.find(b.Name,MName) then
b:FindFirstChild("Kill").Value += 1
end
end
end
end
------------------------
function drop_mics(Mob)
local Root = Mob.human.RootPart
if game.ServerStorage:FindFirstChild("Drop_Item") then
local Item_table = _M[Mob.char.Name].Drop
if Item_table and math.random(1,100) <= 30 then
local drop_Name = Item_table[math.random(1,#Item_table)]
if not MicsDict.mics_info[drop_Name] then return end
local drop =((game.ServerStorage.Drop_Item:FindFirstChild(drop_Name))and game.ServerStorage.Drop_Item[drop_Name] or game.ServerStorage.Drop_Item.Unk):Clone()
if drop then
drop.Name = drop_Name
drop.Parent = workspace.DebHolder
drop.Position = Root.Position + Vector3.new(math.random(-2,2) , 3 , math.random(-2,2))
drop.Anchored = false
drop.CanCollide = true
local ins = Instance.new("NumberValue")
ins.Name = "Amount"
ins.Value= math.random(1,5)
ins.Parent = drop
local collect_script = script.Clone_Script.collect:Clone()
collect_script.Disabled = false
collect_script.Parent = drop
game.Debris:AddItem(drop,10)
end
end
end
end
function give_cash(Player,Mob,Percent)
local stats_ = Player:FindFirstChild(MainDict.StatsFolder)
if stats_ then
local coins = stats_:FindFirstChild(goldcur)
local xp = stats_:FindFirstChild(xpcur)
local G,X = Mob.reward["X"] ,Mob.reward["G"]
if coins and xp then
if Percent >= PercentReq then
--print(Percent,Mob.human.MaxHealth)
coins.Value += math.floor((G * Percent)*event_gold)
xp.Value +=math.floor((X * Percent)*event_xp)
-- game.ReplicatedStorage.Remotes.Announcement:FireClient(Player,"You get: ".. G .. goldcur .. " and " .. X .. xpcur .."[Mob]",Color3.fromRGB(255, 255, 0))
else
coins.Value += math.floor(G*.3*event_gold)
xp.Value += math.floor(X*.3*event_xp)
end
end
end
end
-----------------------------
-----------------------------
-----------------------------
function tpBack(char)
local Hrp = char:FindFirstChild("HumanoidRootPart")
if Hrp then
Hrp.CFrame = workspace.SpawnLocation.CFrame + Vector3.new(0,5,0)
end
end
function module.died(Mob,Mobs)
local _,E =coroutine.resume(coroutine.create(function()
-- print(Mob.human.Parent.Name .. " died!")
for i,v in pairs(Mob.char:GetDescendants()) do
if string.find(v.ClassName,"Script") then
v:Destroy()
end
end
for i,v in pairs(Mob.human:GetChildren()) do
if string.sub(v.Name,1,6) == "HitBy:" then
local Char = game.Workspace:FindFirstChild(string.sub(v.Name,7))
if Char then
local Player = game.Players:GetPlayerFromCharacter(Char)
if Player then
if Mob.Boss == true then
if v.Value < Mob.human.MaxHealth then
print("Challenge failed!")
return
end
tpBack(Char)
end
--print(Mob.char.Name .. " defeted!")
--give cash
give_cash(Player,Mob,v.Value/Mob.human.MaxHealth)
----Quest
check_Quest(Player,Mob)
--drop weapons
give_tool(Player,Mob)
-- drop others
drop_mics(Mob)
---
end
end
end
end
effect(Mob)
respawn(Mobs,Mob)
end))
if E then error(E) end
end
-----------------------------
-----------------------------
-----------------------------
function respawn(Mobs,Mob)
coroutine.resume(coroutine.create(function()
if (not Mob.char) and Mob.Boss == true then return end
local index = table.find(Mobs,Mob)
table.remove(Mobs,index)
task.wait(DesTime)
Mob.char:Destroy()
task.wait(_M[Mob.char.Name].RespawnTime)
Mob.clone:MakeJoints()
Mob.clone.Parent = workspace.MobHolder
-- Mob.clone:SetPrimaryPartCFrame(CFrame.new(Mob.startpos + Vector3.new(0,3,0)))
end))
end
-----------------------------
-----------------------------
-----------------------------
function effect(Mob)
coroutine.resume(coroutine.create(function()
local FX = script.FX:Clone()
local Root = Mob.human.RootPart
if not Root then return end
Root.Anchored = true
TS:Create(Root,TweenInfo.new(.8),{CFrame = Root.CFrame * CFrame.new(0,-2,1) * CFrame.Angles(math.rad(90),0,0)}):Play()
FX.CFrame = Root.CFrame
FX.Parent = workspace.DebHolder
game.Debris:AddItem(FX,2)
end))
end
function module.Healthbar(Mob)
coroutine.resume(coroutine.create(function()
local EHum = Mob.human
local Enemy = Mob.human.Parent
local MName = _M[Enemy.Name].MobName
local Lv = Mob.lv
local HUD = Enemy.UpperTorso:WaitForChild("BillboardGui")
if Mob.isBoss == false or not Mob.isBoss then
HUD.TextLabel.Text = MName .. " ["..Lv .."]"
else
HUD.TextLabel.Text = "[Boss] " .. MName.. " ["..Lv .."]"
HUD.TextLabel.TextColor3 = Color3.fromRGB(255,0,0)
end
local bar =Enemy.UpperTorso.BillboardGui.Hp.Bar
local mxhp =EHum.MaxHealth
while true do
local hp =EHum.Health
bar.Size = UDim2.new((hp/mxhp) ,0 ,1,0)
local percent = (hp/mxhp)*100
if percent >= 55 then
bar.BackgroundColor3 = Color3.fromRGB(0, 182, 0)
elseif percent >= 35 and percent < 55 then
bar.BackgroundColor3 = Color3.fromRGB(222, 222, 0)
elseif percent >= 0 and percent < 35 then
bar.BackgroundColor3 = Color3.fromRGB(220, 0, 0)
end
task.wait(.2)
end
end))
end
return module