local RunService = game:GetService("RunService")
local Toad = {}
Toad.__index = Toad
local FOLLOW_RADIUS = 8
local AGGRO_RADIUS = 15
local LEASH_RADIUS = 20
local JUMP_HEIGHT = 5
local JUMP_TIME = 0.45
local ATTACK_DAMAGE = 10
function Toad.new(model, owner)
local self = setmetatable({}, Toad)
self.model = model
self.owner = owner
self.state = "Follow"
self.target = nil
return self
end
function Toad:FindEnemy()
local myPos = self.model.PrimaryPart.Position
local best, bestDist
for _, enemy in ipairs(workspace.Enemies:GetChildren()) do
if enemy.PrimaryPart then
local d = (enemy.PrimaryPart.Position - myPos).Magnitude
if not bestDist or d < bestDist then
best, bestDist = enemy, d
end
end
end
return best, bestDist
end
function Toad:Update()
if self.state == "Jumping" then return end
local ownerPos = self.owner.PrimaryPart.Position
local myPos = self.model.PrimaryPart.Position
if self.target then
if not self.target.Parent
or (self.target.PrimaryPart.Position - ownerPos).Magnitude > LEASH_RADIUS then
self.target = nil
end
end
if not self.target then
local enemy, dist = self:FindEnemy()
if enemy and dist <= AGGRO_RADIUS then
self.target = enemy
end
end
if self.target then
self:JumpTo(self.target.PrimaryPart.Position, true)
else
if (myPos - ownerPos).Magnitude > FOLLOW_RADIUS then
local off = Vector3.new(math.random(-4,4), 0, math.random(-4,4))
self:JumpTo(ownerPos + off, false)
end
end
end
function Toad:JumpTo(targetPos, isAttack)
self.state = "Jumping"
local root = self.model.PrimaryPart
local start = root.Position
local t0 = tick()
local conn
conn = RunService.Heartbeat:Connect(function()
local a = (tick() - t0) / JUMP_TIME
if a >= 1 then
conn:Disconnect()
root.CFrame = CFrame.new(targetPos)
if isAttack and self.target and self.target.Parent then
self:Hit(self.target)
end
self.state = "Follow"
return
end
local flat = start:Lerp(targetPos, a)
local height = math.sin(a * math.pi) * JUMP_HEIGHT
local pos = flat + Vector3.new(0, height, 0)
local lookDir = (targetPos - start)
local yaw = math.atan2(-lookDir.X, -lookDir.Z)
local flip = CFrame.Angles(a * math.pi * 2, 0, 0)
root.CFrame = CFrame.new(pos) * CFrame.Angles(0, yaw, 0) * flip
end)
end
function Toad:Hit(enemy)
local hum = enemy:FindFirstChild("Humanoid")
if hum then
hum:TakeDamage(ATTACK_DAMAGE)
end
end
return Toad