CUSTOM_BOT_BEHAVIORS = { PlayerBuster = function(bot, template) local EXPLOSION_RANGE = 250 local EXPLOSION_DAMAGE = 200 local currentTarget local function detonate() -- bot:BotCommand("taunt") bot:RunScriptCode("activator.HandleTauntCommand(0)", bot, bot) timer.Create(0.015, function() if not IsValid(bot) or not bot:IsAlive() then return false end if not bot:InCond(TF_COND_TAUNTING) then return end local BASE_TAUNT_DURATION = 2 local tauntDuration = BASE_TAUNT_DURATION / (bot:GetAttributeValue("gesture speed increase") or 1) local callbacks = {} local tauntTimer local function removeCallbacks() if not IsValid(bot) then return end for _, callbackId in pairs(callbacks) do bot:RemoveCallback(callbackId) end if tauntTimer then timer.Stop(tauntTimer) end end callbacks.died = bot:AddCallback(ON_DEATH, function() removeCallbacks() end) callbacks.spawned = bot:AddCallback(ON_SPAWN, function() removeCallbacks() end) tauntTimer = timer.Simple(tauntDuration, function() if not IsValid(bot) or not bot:IsAlive() then return end tauntTimer = nil local weaponMimic = ents.CreateWithKeys("tf_point_weapon_mimic", { spawnflags = 1, angles = bot:GetAbsOrigin(), origin = Vector(0, 0, 0), teamnum = bot.m_iTeamNum, Crits = 0, Damage = EXPLOSION_DAMAGE, ModelScale = 1, SpeedMax = 0, SpeedMin = 0, SplashRadius = EXPLOSION_RANGE, SpreadAngle = 0, WeaponType = 3, }, true, true) weaponMimic:AcceptInput("$SetOwner", bot, bot) weaponMimic:AcceptInput("FireOnce") local explosionParticle = ents.CreateWithKeys("info_particle_system", { effect_name = "asplode_hoodoo", start_active = 1, flag_as_weather = 0, }, true, true) explosionParticle:SetAbsOrigin(bot:GetAbsOrigin()) explosionParticle:AcceptInput("Start") timer.Simple(5, function() weaponMimic:Remove() explosionParticle:Remove() end) timer.Simple(0.015, function() weaponMimic:AcceptInput("DetonateStickies") bot:Suicide() end) return false end) return false end, 0) end local function walkToTarget() local pos = currentTarget:GetAbsOrigin() local interruptAction = ("interrupt_action -pos %s %s %s -duration 0.1"):format(pos[1], pos[2], pos[3]) bot:BotCommand(interruptAction) local dist = bot:GetAbsOrigin():Distance(pos) if dist <= EXPLOSION_RANGE then detonate() return false end return nil end timer.Create(0.2, function() if not bot:IsAlive() or not IsValid(bot) then return false end if IsValid(currentTarget) and currentTarget:IsAlive() then return walkToTarget() end if bot:InCond(TF_COND_STUNNED) then return end local team = bot.m_iTeamNum local origin = bot:GetAbsOrigin() -- get closest target local closestDist = math.huge local closestPlayer for _, player in pairs(ents.GetAllPlayers()) do if player.m_iTeamNum ~= team and player:IsAlive() and IsValid(player) then local playerOrigin = player:GetAbsOrigin() local dist = origin:Distance(playerOrigin) if dist < closestDist then closestDist = dist closestPlayer = player end end end currentTarget = closestPlayer if not currentTarget then -- detonate right away detonate() return false end return walkToTarget() end, 0) end, }