4ªU„luascripts/vscriptsl4d2_improvedbotsÚÉž#ÿo ÿÿkvemssettings !"¾ÿí0ÿÿtxt addoninfotî{ÿíÿÿ"AddonInfo" { "AddonName" "L4D2 Improved bots" "Addontitle" "L4D2 Improved bots" "AddonDescription" "Enhances the behavior of AI bots in Left 4 Dead 2." "AddonVersion" "1.0" "AddonAuthor" "Mark" } "navigation" { "enableNavigation" "1" "customNavigationParameter" "some_value" } "targetSelection" { "enableTargetSelection" "1" "customTargetSelectionParameter" "another_value" } "teamwork" { "enableRevive" "1" "enableHealthPackSharing" "1" } "specialInfectedHandling" { "enableChargerHandling" "1" "enableSmokerHandling" "1" "enableSpitterHandling" "1" "enableJockeyHandling" "1" "enableHunterHandling" "1" } "tankHandling" { "enableTankHandling" "1" "tankAvoidance" { "enableTankAvoidance" "1" "safeDistance" "500" } } "witchHandling" { "enableWitchHandling" "1" } "other" { "enableImprovedBotFeatures" "1" "accuracyMultiplier" "0.8" "coordinationMultiplier" "0.5" } -- Load settings from EMS file local settings = LoadKeyValues("ems/settings.kv") -- Function to improve bot navigation function ImproveBotNavigation(bot) -- Add custom navigation improvements here end -- Function to improve bot target selection function ImproveBotTargetSelection(bot) -- Add custom target selection improvements here end -- Function to improve bot teamwork function ImproveBotTeamwork(bot, allies) -- Example: Revive incapacitated teammates for _, ally in pairs(allies) do if ally:IsAlive() and ally:IsIncapacitated() and bot:CanRevive(ally) then bot:Revive(ally) break end end -- Example: Share health packs with injured teammates local healthPack = bot:GetItemInSlot("item_healthkit") if healthPack then for _, ally in pairs(allies) do if ally:IsAlive() and ally:GetHealthPercent() < 0.5 then bot:ShareItem(ally, healthPack) break end end end end -- Function to improve bot response to special infected function ImproveBotSpecialInfectedHandling(bot, specialInfected) for _, infected in pairs(specialInfected) do if infected:IsCharger() then -- Charger handling -- Example: Bots will shoot the Charger pinning someone if infected:GetChargeVictim() then bot:Attack(infected:GetChargeVictim()) end -- Example: Bots will move out of the way of the Charger's charge local distanceToCharger = (bot:GetAbsOrigin() - infected:GetAbsOrigin()):Length2D() if distanceToCharger < 500 then local moveDirection = (bot:GetAbsOrigin() - infected:GetAbsOrigin()):Normalized() local newPosition = bot:GetAbsOrigin() + moveDirection * 500 bot:SetAbsOrigin(newPosition) end elseif infected:IsSmoker() then -- Smoker handling -- Example: Bots will prioritize the Smoker who grabbed them if bot:GetSmoker() == infected then bot:Attack(infected) end -- Example: Bots will shove survivors caught by the Smoker local victim = infected:GetPullVictim() if victim and bot:IsInMeleeRange(victim) then bot:MeleeAttack(victim) end -- Example: Bots will shoot the tongue of a grabbed survivor if victim and bot:GetSmoker() == infected then bot:Attack(infected) end -- Example: Bots will shoot the Smoker that grabbed someone if they can't shove the survivor if victim and bot:GetSmoker() == infected and not bot:IsInMeleeRange(victim) then bot:Attack(infected) end elseif infected:IsSpitter() then -- Spitter handling -- Example: Bots will immediately move away from Spitter's spit before it damages them local spitPosition = infected:GetSpitPosition() if spitPosition then local moveDirection = (bot:GetAbsOrigin() - spitPosition):Normalized() local newPosition = bot:GetAbsOrigin() + moveDirection * 200 bot:SetAbsOrigin(newPosition) end -- Example: Bots can't go into the spit if bot:IsInSpit(spitPosition) then local moveDirection = (bot:GetAbsOrigin() - spitPosition):Normalized() local newPosition = bot:GetAbsOrigin() + moveDirection * 200 bot:SetAbsOrigin(newPosition) end -- Example: Bots will move around the spit if bot:IsInSpit(spitPosition) then local moveDirection = (bot:GetAbsOrigin() - spitPosition):Normalized() local newPosition = bot:GetAbsOrigin() + moveDirection * 200 bot:SetAbsOrigin(newPosition) end elseif infected:IsJockey() then -- Jockey handling -- Example: Bots will bash a flying Jockey if bot:GetJockey() == infected and infected:IsJumping() then bot:MeleeAttack(infected) end -- Example: Bots will shove a Jockey that is pinning a survivor if they are near local victim = infected:GetVictim() if victim and bot:IsInMeleeRange(infected) then bot:MeleeAttack(infected) end -- Example: Bots will shoot a Jockey if they can't shove the Jockey or if they can't shove the Jockey if victim and bot:GetJockey() == infected and not bot:IsInMeleeRange(infected) then bot:Attack(infected) end elseif infected:IsHunter() then -- Hunter handling -- Example: Bots will bash a flying Hunter if bot:GetHunter() == infected and infected:IsJumping() then bot:MeleeAttack(infected) end -- Example: Bots will shove a Hunter pinning someone if they are close to shove them local victim = infected:GetPounceVictim() if victim and bot:IsInMeleeRange(infected) then bot:MeleeAttack(infected) end -- Example: Bots will shoot a Hunter that is pinning someone if they are far enough to shove the Hunter off the survivor if victim and bot:GetHunter() == infected and not bot:IsInMeleeRange(infected) then bot:Attack(infected) end end end end -- Function to improve bot response to the Tank function ImproveBotTankHandling(bot, tank) -- Example: Bots will shoot Tank rocks accurately local rockPosition = tank:GetRockPosition() if rockPosition then bot:AttackGround(rockPosition) end -- Example: Bots will take cover from Tanks getting ready to throw their rock if tank:IsPreparingRockThrow() then -- Add logic for taking cover end -- Example: Bots will dodge the rock if they can't react in time if tank:IsRockIncoming() then local dodgeDirection = CalculateDodgeDirection(bot, rockPosition) local newPosition = bot:GetAbsOrigin() + dodgeDirection * 200 bot:SetAbsOrigin(newPosition) end end -- Function to improve bot response to the Witch function ImproveBotWitchHandling(bot, witch) -- Example: Bots will shoot the Angry Witch accurately and efficiently bot:Attack(witch) end -- ... (Previous code) -- Hook into the game's AI think function function OnBotThink(event) local bot = event.ent if bot:IsBot() then -- Get allies within a certain range local allies = Entities:FindAllByClassnameWithin("npc_dota_hero*", bot:GetAbsOrigin(), 1200) -- Get special infected within a certain range local specialInfected = Entities:FindAllByClassnameWithin("npc_*_special", bot:GetAbsOrigin(), 1200) -- Improve navigation ImproveBotNavigation(bot) -- Improve target selection ImproveBotTargetSelection(bot) -- Improve teamwork ImproveBotTeamwork(bot, allies) -- Improve bot response to special infected ImproveBotSpecialInfectedHandling(bot, specialInfected) -- Get tanks within a certain range local tanks = Entities:FindAllByClassnameWithin("npc_tank", bot:GetAbsOrigin(), 2000) -- Improve bot response to the Tank if #tanks > 0 then local tank = tanks[1] -- For simplicity, consider only the first tank found ImproveBotTankHandling(bot, tank) end -- Get Witches within a certain range local witches = Entities:FindAllByClassnameWithin("npc_witch", bot:GetAbsOrigin(), 2000) -- Improve bot response to the Witch if #witches > 0 then local witch = witches[1] -- For simplicity, consider only the first witch found ImproveBotWitchHandling(bot, witch) end end end -- ... (Previous code) -- Call the function to set up the hooks OnGameEvents()