--made by wacev --idc if you use this popfile and create your own btd mission --created on 1/11/2025 TD_GLOBAL_LIVES = 150 local color = {100,250,50} local display local flamering function OnGameTick() for _, rocket in pairs(ents.FindAllByClass("tf_projectile_rocket")) do if ( rocket.m_hOwnerEntity:GetPlayerItemBySlot(0):GetAttributeValue("Wrench Index") ~= nil ) and ( rocket.m_hOwnerEntity:GetPlayerItemBySlot(0):GetAttributeValue("Wrench Index") == 1 ) then ents.FindByName("FT_Spawner"):Teleport(rocket:GetAbsOrigin()) ents.FindByName("FT_Spawner"):AcceptInput("ForceSpawn") end end for _, player in pairs(ents.GetAllPlayers()) do if ( player:IsBot() ) and ( player:InCond(50) ) and ( player:GetConditionProvider(50):GetPlayerItemBySlot(4):GetAttributeValue("sapper damage bonus") ~= nil ) then local attacker = player:GetConditionProvider(50) if player.SapperDamageDelay < 1 then player:TakeDamage({ Attacker = attacker, Damage = 25, DamageType = DMG_SHOCK, DamageCustom = TF_DMG_CUSTOM_SAPPER_RECORDER_DEATH --wtf is this }) player.SapperDamageDelay = 6 else player.SapperDamageDelay = player.SapperDamageDelay -1 end end if ( player:IsBot() ) and ( player:InCond(50) ) and ( player:GetConditionProvider(50):GetPlayerItemBySlot(4):GetAttributeValue("sapper health bonus") ~= nil ) then local attacker = player:GetConditionProvider(50) if ( player.SapperExplodeDelay < 1 ) and ( player.SapperExploded == false ) then ExplodeSapper(player, attacker) if ( attacker:GetPlayerItemBySlot(4):GetAttributeValue("sapper degenerates buildings") ~= nil ) then timer.Create(0.06, function() ExplodeSapper(player, attacker) end, 4) end else player.SapperExplodeDelay = player.SapperExplodeDelay -1 end elseif ( player:IsBot() ) and ( not player:InCond(50) ) and ( player.SapperExplodeDelay ~= 3 * 66) then player.SapperExplodeDelay = 3 * 66 end if ( player:IsRealPlayer() ) and ( player.m_iClass == TF_CLASS_SNIPER ) then local attr = player.m_hActiveWeapon:GetAttributeValue("mult sniper charge after bodyshot") if ( attr ~= nil ) then local dmg_charge_mult = player.m_hActiveWeapon:GetAttributeValue("sniper full charge damage bonus") if dmg_charge_mult == nil then dmg_charge_mult = 1 end player:SetAttributeValue("CARD: damage bonus", 3 * dmg_charge_mult) end end end end function ExplodeSapper(bot, attacker) for _, others in pairs(ents.FindInSphere(bot:GetAbsOrigin(),147)) do if others:IsBot() then others:TakeDamage({ Attacker = attacker, Damage = 800, DamageType = DMG_BLAST, DamageCustom = TF_DMG_CUSTOM_MERASMUS_GRENADE }) if ( attacker:GetPlayerItemBySlot(4):GetAttributeValue("sapper degenerates buildings") ~= nil ) then others:IgnitePlayerDuration(10, attacker) end end end util.ParticleEffect( "rd_robot_explosion", bot:GetAbsOrigin() + Vector(0, 0, 32), Vector(0, 0, 0), bot ) bot:PlaySound("BaseExplosionEffect.Sound") bot.SapperExploded = true end function OnWaveInit() timer.Simple(0.5,function() ents.FindByClass("func_capturezone"):AddCallback(ON_START_TOUCH, function(_, player) if player.m_iTeamNum == 3 then TD_TakeDamage(player) end end) ents.FindByName("blimp_path_9"):AcceptInput("AddOutput","OnPass popscript:$TD_TakeDamage_MOAB:activator:0:-1") end) display = timer.Create(1, function() LiveDisplay() if TD_GLOBAL_LIVES < 1 then color = {250,50,0} else color = {100,250,50} end end, 0) flamering = timer.Create(0.5, function() for _, player in pairs(ents.GetAllPlayers()) do if ( player:IsRealPlayer() ) and ( player.m_iTeamNum == 2 ) and ( player:IsAlive() ) then local attr = player.m_hActiveWeapon:GetAttributeValue("Wrench Index") if ( attr ~= nil ) and ( attr == 2 ) then ents.FindByName("FR_Spawner"):Teleport(player:GetAbsOrigin()) ents.FindByName("FR_Spawner"):AcceptInput("ForceSpawn") end end end end, 0) end function LiveDisplay() for _, player in pairs(ents.GetAllPlayers()) do if player:IsRealPlayer() then player:ShowHudText({channel = 3, y = 0.85, x = -0.78, r1 = color[1], r2 = color[1], g1 = color[2], g2 = color[2], b1 = color[3], b2 = color[3], effect = 0, fixTime = 0, fadeinTime = 0, fadeoutTime = 0, holdTime = 1.25}, "♥ " .. TD_GLOBAL_LIVES) -- ❤ end end end function OnWaveSuccess() --timer.Stop(display) --timer.Stop(flamering) pcall(timer.Stop, display) pcall(timer.Stop, flamering) TD_GLOBAL_LIVES = 150 end function OnWaveFail() --timer.Stop(display) --timer.Stop(flamering) pcall(timer.Stop, display) pcall(timer.Stop, flamering) TD_GLOBAL_LIVES = 150 end function OnWaveReset() --timer.Stop(display) --timer.Stop(flamering) pcall(timer.Stop, display) pcall(timer.Stop, flamering) TD_GLOBAL_LIVES = 150 end function OnWaveSpawnTank(tank, wave) tank:AddCallback(ON_DAMAGE_RECEIVED_PRE, function(ent,dmginfo) if dmginfo.Attacker:IsRealPlayer() then local attr = dmginfo.Attacker.m_hActiveWeapon:GetAttributeValue("tag__summer2014") local attr_dmg = dmginfo.Attacker.m_hActiveWeapon:GetAttributeValue("tag__eotlearlysupport") if ( ( attr == nil ) or ( attr ~= 64 ) ) and ( tank.m_iName == "ddt" ) then dmginfo.Damage = 0 return true --returning true makes modifications made to dmginfo apply end if ( attr_dmg ~= nil ) and ( tank.m_iName == "ddt" ) then dmginfo.Damage = dmginfo.Damage * attr_dmg return true end end end) end function OnWaveSpawnBot(bot, wave, tags) bot.SapperExploded = false bot.SapperDamageDelay = 0 bot.SapperExplodeDelay = 3 * 66 bot:AddCallback(ON_DAMAGE_RECEIVED_POST, function(ent,dmginfo,prevhealth) local name = tostring(bot:GetPlayerName()) local health = bot.m_iHealth local attr if dmginfo.Attacker:IsRealPlayer() then attr = dmginfo.Attacker.m_hActiveWeapon:GetAttributeValue("purchased") else attr = nil end if ( health < 1 ) and ( attr ~= nil ) then ents.FindByName("CS_Spawner"):Teleport(bot:GetAbsOrigin()) ents.FindByName("CS_Spawner"):AcceptInput("ForceSpawn") end end) bot:AddCallback(ON_DAMAGE_RECEIVED_PRE, function(ent,dmginfo) if ( bot.m_nRenderMode == 0 ) and ( bot.m_nForcedSkin > 11 ) then bot.m_nForcedSkin = bot.m_nForcedSkin - 12 bot:SetAttributeValue("ignored by enemy sentries", nil) end if ( bot.m_nRenderMode == 1 ) then local attr if dmginfo.Attacker:IsRealPlayer() then attr = dmginfo.Attacker.m_hActiveWeapon:GetAttributeValue("tag__eotlearlysupport") else attr = nil end if ( attr ~= nil ) then dmginfo.Damage = dmginfo.Damage * attr return true end end end) bot:AddCallback(ON_DEATH, function(ent) if ( bot:IsBot() ) and ( bot:InCond(50) ) and ( bot:GetConditionProvider(50):GetPlayerItemBySlot(4):GetAttributeValue("sapper health bonus") ~= nil ) then local attacker = bot:GetConditionProvider(50) if ( bot.SapperExploded == false ) and ( bot.SapperExplodeDelay > 1 ) then ExplodeSapper(bot, attacker) if ( attacker:GetPlayerItemBySlot(4):GetAttributeValue("sapper degenerates buildings") ~= nil ) then timer.Create(0.06, function() ExplodeSapper(bot, attacker) end, 4) end end end end) end function TD_TakeDamage_MOAB(_, moab) local name = moab.m_iName local liveslost if name == "moab" then liveslost = 30800 elseif name == "bfb" then liveslost = 158200 elseif name == "zomg" then liveslost = 832800 elseif name == "ddt" then liveslost = 40800 elseif name == "bad" then liveslost = 2788000 else liveslost = 1337 print("@btd logic@ error invalid moab class name on lives lost") end TD_GLOBAL_LIVES = TD_GLOBAL_LIVES - liveslost color = {250,50,0} LiveDisplay() moab:AcceptInput("RemoveHealth",694201337) if TD_GLOBAL_LIVES < 1 then for _, player in pairs(ents.GetAllPlayers()) do if player:IsRealPlayer() then ents.FindByName("boss_deploy_relay"):AcceptInput("Trigger") end end end end function TD_TakeDamage(bloon) TD_GLOBAL_LIVES = TD_GLOBAL_LIVES - bloon:GetAttributeValue("Wrench Index") color = {250,50,0} LiveDisplay() bloon:AcceptInput("$Suicide") if TD_GLOBAL_LIVES < 1 then for _, player in pairs(ents.GetAllPlayers()) do if player:IsRealPlayer() then ents.FindByName("boss_deploy_relay"):AcceptInput("Trigger") end end end end function TrackProjectile(projectile,activator,weapon) local attr = activator.m_hActiveWeapon:GetAttributeValue("Wrench Index") if ( attr ~= nil ) and ( attr == 3 ) then projectile:AddCallback(ON_REMOVE, function(ent) ents.FindByName("CB_Spawner"):Teleport(projectile:GetAbsOrigin() + Vector(0, 0, 56)) ents.FindByName("CB_Spawner"):AcceptInput("ForceSpawn") end) elseif ( attr ~= nil ) and ( attr == 4 ) then projectile:AddCallback(ON_REMOVE, function(ent) ents.FindByName("CBE_Spawner"):Teleport(projectile:GetAbsOrigin() + Vector(0, 0, 56)) ents.FindByName("CBE_Spawner"):AcceptInput("ForceSpawn") end) end end function DeProperty(damage, activator, caller) --activator is the one with the weapon, caller is the one that got hit if caller:IsPlayer() then local attr = activator.m_hActiveWeapon:GetAttributeValue("Wrench Index") if ( attr ~= nil ) and ( ( attr == 5 ) or ( attr == 6 ) ) then timer.Simple(0.015, function() if caller.m_nForcedSkin > 11 then caller.m_nRenderMode = 0 caller:SetAttributeValue("ignored by enemy sentries", nil) caller.m_nForcedSkin = caller.m_nForcedSkin - 12 end end) end if ( attr ~= nil ) and ( attr == 6 ) then timer.Simple(0.015, function() if caller.m_ModelName == "models/mvm_forever/mvm_coaltown_rubber_defence/balloon_classicheart.mdl" then caller:SetAttributeValue("expiration date", 1) end end) end end end --copied from overclocks made by dr.cactus, no clue who made the original file since the cactus one is also a copy local RAGE_DURATION = 10 local UPDATE_INTERVAL = 0.015 local knockbackHandles = {} local RAGE_OVERRIDES_APPLY = { ["throwable fire speed"] = function(activator) activator:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY):SetAttributeValue("fire rate penalty", 0.4) activator:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY):SetAttributeValue("damage penalty", 2) end } local RAGE_OVERRIDES_REMOVE = { ["throwable fire speed"] = function(activator) activator:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY):SetAttributeValue("fire rate penalty", nil) activator:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY):SetAttributeValue("damage penalty", nil) end } local function lerp(a, b, t) return a + (b - a) * t end local function applyKnockbackRageEffect(activator) for attr, func in pairs(RAGE_OVERRIDES_APPLY) do if activator:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY):GetAttributeValue(attr) then func(activator) break end end end local function removeKnockbackRageEffect(activator) for attr, func in pairs(RAGE_OVERRIDES_REMOVE) do if activator:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY):GetAttributeValue(attr) then func(activator) break end end end function KnockbackRageStart(_, activator) local handleIndex = activator:GetHandleIndex() local draining = false local fakeMeter = 0 local meterLerp = 0 knockbackHandles[handleIndex] = timer.Create(UPDATE_INTERVAL, function () if not IsValid(activator) then KnockbackRageStop(nil, nil, handleIndex) return end if draining then -- fakeMeter = math.max(fakeMeter - (UPDATE_INTERVAL * RAGE_DURATION) * 10, 0) meterLerp = meterLerp + (UPDATE_INTERVAL / RAGE_DURATION * 2) fakeMeter = math.max(100 - lerp(0, 100, meterLerp), 0) activator:SetFakeSendProp("m_flRageMeter", fakeMeter) if fakeMeter <= 0 then activator:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY):SetAttributeValue("increase buff duration HIDDEN", nil) activator:ResetFakeSendProp("m_bRageDraining") activator:ResetFakeSendProp("m_flRageMeter") activator.m_flRageMeter = 0 fakeMeter = 0 meterLerp = 0 draining = false removeKnockbackRageEffect(activator) end return end if activator.m_bRageDraining == 0 then return end activator:GetPlayerItemBySlot(LOADOUT_POSITION_PRIMARY):SetAttributeValue("increase buff duration HIDDEN", 100) activator:SetFakeSendProp("m_bRageDraining", 1) activator.m_bRageDraining = 0 activator.m_flRageMeter = -100000 fakeMeter = 100 meterLerp = 0 draining = true applyKnockbackRageEffect(activator) end, 0) end function KnockbackRageStop(_, activator, handle) if activator then activator:ResetFakeSendProp("m_bRageDraining") activator:ResetFakeSendProp("m_flRageMeter") end local handleIndex = handle or activator:GetHandleIndex() pcall(timer.Stop, knockbackHandles[handleIndex]); knockbackHandles[handleIndex] = nil end