--Script exists solely to give monochrome his funny face laser, and to do the thing where he kills everyone with a deathray once his timer expires local function removeCallbacks(player, callbacks) if not IsValid(player) then return end for _, callbackId in pairs(callbacks) do player:RemoveCallback(callbackId) end end --print("Speak") --excerpt from royal's sniper laser script local function getEyeAngles(player) local pitch = player["m_angEyeAngles[0]"] local yaw = player["m_angEyeAngles[1]"] return Vector(pitch, yaw, 0) end local function hideLaser(laser, pointer) if not IsValid(laser) then return end laser:Stop() laser:SetAbsOrigin(pointer:GetAbsOrigin()) end local monochromeSpeaking = false local monochromeSpeechCooldown = 0 function monochromeIsSpeaking() monochromeSpeaking = true print("We are talking") end function monochromeNotSpeaking() monochromeSpeaking = false print("We are not talking") end function MonochromeLogic(_, activator) local callbacks = {} local check local terminated = false monochromeSpeaking = false local laser = ents.CreateWithKeys("info_particle_system", { effect_name = "laser_sight_beam", start_active = 0, flag_as_weather = 0, }, false) laser:SetName("le_laser" .. tostring(activator:GetHandleIndex())) local pointer = Entity("info_particle_system") local color = Entity("info_particle_system") pointer:SetName("le_laserpointer" .. tostring(activator:GetHandleIndex())) color:SetName("le_lasercolor" .. tostring(activator:GetHandleIndex())) color:SetAbsOrigin(Vector(255, 255, 255)) laser.m_hControlPointEnts[1] = pointer laser.m_hControlPointEnts[2] = color for _, e in pairs({ laser, pointer, color }) do e["$SetOwner"](e, activator) end laser.m_iClassname = "env_sprite" pointer.m_iClassname = "env_sprite" local started = false local function terminate() if terminated then return end terminated = true monochromeSpeaking = false timer.Stop(check) removeCallbacks(activator, callbacks) hideLaser(laser, pointer) timer.Simple(0.1, function() for _, e in pairs({ laser, pointer, color }) do if IsValid(e) then e:Remove() end end end) end check = timer.Create(0.015, function() if not IsValid(activator) or not activator:IsAlive() then terminate() return end local eyeAngles = getEyeAngles(activator) local DefaultTraceInfo = { start = activator, distance = 10000, angles = eyeAngles, mask = MASK_SOLID, collisiongroup = COLLISION_GROUP_DEBRIS, } local trace = util.Trace(DefaultTraceInfo) laser:SetAbsOrigin(trace.StartPos) pointer:SetAbsOrigin(trace.HitPos) laser:Start() started = true end, 0) callbacks.died = activator:AddCallback(ON_DEATH, function() terminate() end) callbacks.hurtpre = activator:AddCallback(ON_DAMAGE_RECEIVED_PRE, function(_, damageInfo) local attacker = damageInfo.Attacker if not attacker or attacker:IsPlayer() == false then return end if attacker:InCond(34) or attacker:InCond(52) then damageInfo.Damage = damageInfo.Damage * 0.65 return true end end) callbacks.removed = activator:AddCallback(ON_REMOVE, function() terminate() end) callbacks.spawned = activator:AddCallback(ON_SPAWN, function() terminate() end) end function annihilateEveryone() local allPlayers = ents.GetAllPlayers() local greyPlayers = {} local everyoneElse = {} local disableSpawns = ents.FindByName("forceDisableSpawns") disableSpawns:AcceptInput("Trigger") local fade = ents.FindByName("lose_fade") local fadeAnnihilation = ents.FindByName("lose_fade_annihilation") local botsWin = ents.FindByName("winr") fade:AcceptInput("Fade") local sufferingTable = { Attacker = nil, -- Attacker Inflictor = nil, -- Direct cause of damage, usually a projectile Weapon = nil, Damage = 60000, DamageType = nil, -- Damage type, see DMG_* globals. Can be combined with | operator DamageCustom = nil, -- Custom damage type, see TF_DMG_* globals CritType = 2, -- Crit type, 0 = no crit, 1 = mini crit, 2 = normal crit DamagePosition = nil, -- Where the target was hit at DamageForce = nil, -- Knockback force of the attack ReportedPosition = nil -- Where the attacker attacked from } timer.Simple(3.25, function() fadeAnnihilation:AcceptInput("Fade") for _, player in pairs(allPlayers) do if player:IsAlive() and player:IsValid() then player:Suicide() player:TakeDamage(sufferingTable) player:AcceptInput("$PlaySoundToSelf", "giant_deathlaser_impact.mp3") elseif player:IsValid() then player:AcceptInput("$PlaySoundToSelf", "giant_deathlaser_impact.mp3") end end botsWin:AcceptInput("RoundWin") end) end --Thank you royal, once again AddEventCallback("mvm_reset_stats", function () --print("cleaning up leftover lasers") for _, laser in pairs(ents.FindAllByName("le_laser*")) do local ownerId = tostring(string.match(laser:GetName(), "%d+")) local pointer = ents.FindByName("le_laserpointer" .. ownerId) --print(ownerId, pointer) pcall(function () hideLaser(laser, pointer) end) timer.Simple(1, function() laser:Remove() if pointer and IsValid(pointer) then pointer:Remove() end end) end end) function insultVictim(damage, activator, caller) if not caller or caller:IsRealPlayer() == false then return end allPlayers = ents.GetAllPlayers() local gameTime = CurTime() --print(gameTime) if monochromeSpeaking == true or gameTime < monochromeSpeechCooldown then print("Stopped talking") return end monochromeSpeechCooldown = gameTime + 6.0 --print(monochromeSpeechCooldown) local insultHeavy = { "{EEEEEE}Monochrome{reset} : {FFFFFF}for {red}idiot {66FF66}in {FFEEEE}FACETANK RANGE {66FF66}do makeFunOF({red}idiot) {66FF66}end", "{EEEEEE}Monochrome{reset} : {FFFFFF}WAS I NOT InCond(27)? DO YOU NEED THE MEDIC TO WIPE YOUR ASS FOR YOU TOO?", "{EEEEEE}Monochrome{reset} : {FFFFFF}I'D TELL YOU TO PLAY SOMETHING THAT REQUIRES BRAINPOWER, BUT YOU ARE ALREADY DYING AS THE EASIEST CLASS", } local insultMedic = { "{EEEEEE}Monochrome{reset} : {FFFFFF}SPAM YOUR tf_powerup_bottle HARDER NEXT TIME.", "{EEEEEE}Monochrome{reset} : {FFFFFF}YOU DIDN'T GET 87^4 FREE m_flChargeLevel FROM HITTING ME ONCE? GONNA CRY ABOUT IT?", "{EEEEEE}Monochrome{reset} : {FFFFFF}LOOKS LIKE PRESSING MOUSE3 DIDN'T GO SO WELL FOR YOU!", } local insultDemo = { "{EEEEEE}Monochrome{reset} : {FFFFFF}NICE USE OF YOUR RANGE, {red}" .. caller.m_szNetname, "{EEEEEE}Monochrome{reset} : {FFFFFF}DID MOUSE1 + MOUSE2 NOT WORK FOR YOU?", "{EEEEEE}Monochrome{reset} : {FFFFFF}HOW ABOUT YOU HEAD TO mvm_mannhattan,{red}" .. caller.m_szNetname .. ",{FFFFFF} THAT'S MORE YOUR SPEED", } local insultSoldier = { "{EEEEEE}Monochrome{reset} : {FFFFFF}HIT ME WITH ANOTHER rocket specialist, ROCKET, I DARE YOU, {red}" .. caller.m_szNetname, "{EEEEEE}Monochrome{reset} : {FFFFFF}YOU ARE < ME IN EVERY CONCEIVABLE WAY {red}" .. caller.m_szNetname, "{EEEEEE}Monochrome{reset} : {FFFFFF}WHAT DO YOU HAVE AFTER THIS IS OVER, {red}" .. caller.m_szNetname .. "{FFFFFF}? I HAVE AN ARMY, YOU HAVE LEAD POISONING", } local insultScout = { "{EEEEEE}Monochrome{reset} : {red}" .. caller.m_szNetname .. "{FFFFFF}, HOW DID YOU DIE WITH Double.POSITIVE_INFINITY HEALTH FROM CASH?", "{EEEEEE}Monochrome{reset} : {FFFFFF}DID SOMEBODY FORGET THEIR SPACEBAR?", "{EEEEEE}Monochrome{reset} : {FFFFFF}KICK THE SCOUT, THEY MISSED A CRIT ROCKET", } local insultPyro = { "{EEEEEE}Monochrome{reset} : {FFFFFF}PYRO STATUS: {red}" .. caller.m_szNetname .. "{FFFFFF}.m_lifeState = {FF0000}0", "{EEEEEE}Monochrome{reset} : {FFFFFF}JUMP ON MY HEAD AND TAUNT AGAIN, I DARE YOU, {red}" .. caller.m_szNetname, "{EEEEEE}Monochrome{reset} : {FFFFFF}TRY NOT TO GET HIT NEXT TIME." } local insultEngineer = { "{EEEEEE}Monochrome{reset} : {FFFFFF}GO BACK TO SITTING ON THE item_teamflag, YOU CLEARLY AREN'T CAPABLE OF DOING ANYTHING ELSE", "{EEEEEE}Monochrome{reset} : {FFFFFF}DON'T FORGET TO BUY bidirectional teleport {red}" .. caller.m_szNetname .. "{FFFFFF} CLEARLY YOU HAVE NOTHING BETTER TO DO.", "{EEEEEE}Monochrome{reset} : {FFFFFF}YOU DREW THE SHORT STRAW FOR CLASS PICKS {red}" .. caller.m_szNetname, } local insultSniper = { "{EEEEEE}Monochrome{reset} : {FFFFFF}YOU CAN'T JUST GET FREE DAMAGE IN ON ME? WHAT A SHAME!", "{EEEEEE}Monochrome{reset} : {FFFFFF}HOW ABOUT YOU GO BACK TO mvm_bigrock {red}" .. caller.m_szNetname .. "{FFFFFF}, THIS WHOLE 'THE ENEMIES CAN SHOOT BACK' THING IS TOO MUCH FOR YOU.", "{EEEEEE}Monochrome{reset} : {FFFFFF}GET BETTER {red}" .. caller.m_szNetname, } local insultSpy = { "{EEEEEE}Monochrome{reset} : {red}" .. caller.m_szNetname .. "{FFFFFF}, As the TF_CLASS_SPY, {FFEEEE}PRESS , TO CHANGE CLASS", "{EEEEEE}Monochrome{reset} : {FFFFFF}YOU PICKED INCORRECTLY ON THE CLASS SELECT SCREEN.", "{EEEEEE}Monochrome{reset} : {FFFFFF}GO BULLY THE BLUE SUPPORT {red}" .. caller.m_szNetname .. "{FFFFFF} YOU'D BE DOING SOMETHING PRODUCTIVE AT THE VERY LEAST", } local message = "" --if we just killed a medic if caller.m_iClass == 5 then message = insultMedic[math.random(#insultMedic)] end --if we just killed a heavy if caller.m_iClass == 6 then message = insultHeavy[math.random(#insultHeavy)] end --check if they're an engie if caller.m_iClass == 9 then message = insultEngineer[math.random(#insultEngineer)] end --are you a soldier? if caller.m_iClass == 3 then message = insultSoldier[math.random(#insultSoldier)] end --are you a spy? if caller.m_iClass == 8 then message = insultSpy[math.random(#insultSpy)] end --are you a demo? if caller.m_iClass == 4 then message = insultDemo[math.random(#insultDemo)] end --are you a pyro? if caller.m_iClass == 7 then message = insultPyro[math.random(#insultPyro)] end --are you a sniper? if caller.m_iClass == 2 then message = insultSniper[math.random(#insultSniper)] end --are you a scout? if caller.m_iClass == 1 then message = insultScout[math.random(#insultScout)] end if message ~= nil then for _, player in pairs(allPlayers) do player:AcceptInput("$DisplayTextChat", message) end end end function insultVictimFunny(damage, activator, caller) if not caller or caller:IsRealPlayer() == false then return end allPlayers = ents.GetAllPlayers() local gameTime = CurTime() --print(gameTime) if monochromeSpeaking == true or gameTime < monochromeSpeechCooldown then print("Stopped talking") return end monochromeSpeechCooldown = gameTime + 6.0 --print(monochromeSpeechCooldown) local insultHeavy = { "{ffAAFF}MonOwOchrome{reset} : OH {red}" .. caller.m_szNetname .. "{ffAAFF}, I DON'T WANT TO CUDDLE WIFF YOU WIGHT NOW, MAYBE LATER", "{ffAAFF}MonOwOchrome{reset} : YOU'LL GET IT EVENTUAWWY", "{ffAAFF}MonOwOchrome{reset} : TWY HARDER!", } local insultMedic = { "{ffAAFF}MonOwOchrome{reset} : NICE tf_powerup_bottle YOU GOT DERE!", "{ffAAFF}MonOwOchrome{reset} : GET YOWE m_flChargeLevel FROM SOMEWHERE ELSE, YOU WON'T GET ANY FROM ME.", "{ffAAFF}MonOwOchrome{reset} : MOUSE3? MOWE WIKE X3!", } local insultDemo = { "{ffAAFF}MonOwOchrome{reset} : IS SOMEBODY TOO USED TO {66FF66}mvm_mannhatten?{FFAFF} BWANCH OUT AND TWY NEW THINGS!", "{ffAAFF}MonOwOchrome{reset} : YOU CAN DO BETTEW THEN THAT!", "{ffAAFF}MonOwOchrome{reset} : SOWWY ABOUT THAT {red}" .. caller.m_szNetname, } local insultSoldier = { "{ffAAFF}MonOwOchrome{reset} : BYE BYE{red}" .. caller.m_szNetname .. "{ffAAFF}!", "{ffAAFF}MonOwOchrome{reset} : YOU ARE WEAKEW AND SMALLWER THAN ME {red}" .. caller.m_szNetname .. "{ffAAFF}, AND THAT'S OK!", "{ffAAFF}MonOwOchrome{reset} : YOU COULD USE A HUG :3, {red}" .. caller.m_szNetname, } local insultScout = { "{ffAAFF}MonOwOchrome{reset} : COWWECT MOWE CASH AND TWY AGAIN, {red}" .. caller.m_szNetname .. "{ffAAFF}!", "{ffAAFF}MonOwOchrome{reset} : REMEMBEW YOUR SPACEBAR!", "{ffAAFF}MonOwOchrome{reset} : DON'T MISS THE CWIT WOCKETs!", } local insultPyro = { "{ffAAFF}MonOwOchrome{reset} : YOU'WE TWYING YOUW BEST! IT'WW WOWK EVENTUAWWY!", "{ffAAFF}MonOwOchrome{reset} : OH {red}" .. caller.m_szNetname .. "{ffAAFF}, I DON'T WANT TO CUDDLE WIFF YOU WIGHT NOW, MAYBE LATER", "{ffAAFF}MonOwOchrome{reset} : WATCH FOW THE BIG WHITE WASER, {red}" .. caller.m_szNetname, } local insultEngineer = { "{ffAAFF}MonOwOchrome{reset} : {ffAAFF}BETTEW WUCK NEXT TIME! BACK TO THE item_teamflag {red}" .. caller.m_szNetname .. "{ffAAFF}!", "{ffAAFF}MonOwOchrome{reset} : {ffAAFF}DON'T FOWGET TO BUY bidirectional teleport {red}" .. caller.m_szNetname .. "{ffAAFF}!", "{ffAAFF}MonOwOchrome{reset} : {ffAAFF}I FEEWL BAD FOW YOU, {red}" .. caller.m_szNetname, } local insultSniper = { "{ffAAFF}MonOwOchrome{reset} : {ffAAFF}UH OH! WOOKS WIKE SOMEBODY NEEDS TO {66FF66}goto Pwaces.BED {ffAAFF}TWY HAWDEW TOMOWWO!!", "{ffAAFF}MonOwOchrome{reset} : {ffAAFF}WHAT AWE YOU DOING ALL THE WAY OVER THEWE {red}" .. caller.m_szNetname .. "{ffAAFF}?", "{ffAAFF}MonOwOchrome{reset} : {ffAAFF}BETTEW WUCK NEXT TIME, {red}" .. caller.m_szNetname, } local insultSpy = { "{ffAAFF}MonOwOchrome{reset} : {ffAAFF}WHAT AWE YOU DOING BACK THEWE {red}" .. caller.m_szNetname .. "? {FFAAFF}OwO", "{ffAAFF}MonOwOchrome{reset} : {ffAAFF}IT IS SO CUTE WATCHING YOU DRESS UP, {red}" .. caller.m_szNetname, "{ffAAFF}MonOwOchrome{reset} : {ffAAFF}FOUND YOU! {red}" .. caller.m_szNetname .. "{ffAAFF}!", } local message = "" --if we just killed a medic if caller.m_iClass == 5 then message = insultMedic[math.random(#insultMedic)] end --if we just killed a heavy if caller.m_iClass == 6 then message = insultHeavy[math.random(#insultHeavy)] end --check if they're an engie if caller.m_iClass == 9 then message = insultEngineer[math.random(#insultEngineer)] end --are you a soldier? if caller.m_iClass == 3 then message = insultSoldier[math.random(#insultSoldier)] end --are you a spy? if caller.m_iClass == 8 then message = insultSpy[math.random(#insultSpy)] end --are you a demo? if caller.m_iClass == 4 then message = insultDemo[math.random(#insultDemo)] end --are you a pyro? if caller.m_iClass == 7 then message = insultPyro[math.random(#insultPyro)] end --are you a sniper? if caller.m_iClass == 2 then message = insultSniper[math.random(#insultSniper)] end --are you a scout? if caller.m_iClass == 1 then message = insultScout[math.random(#insultScout)] end if message ~= nil then for _, player in pairs(allPlayers) do player:AcceptInput("$DisplayTextChat", message) end end end --Other application of the above functions is if you have some funky custom thing that depletes people's clips to 0 (and only to 0, if it reduces to a minimum of 1, there's no point) function paleBurstLogicOnAttackRapidGigaSwap(param, activator, caller) --Shouldn't be possible for primary to be nil, given that the rocket launcher would need to fire to invoke this. local primary = activator:GetPlayerItemBySlot(0) --If you're not at 0, we don't care, this is what makes this orders of magnitude more optimized than the previous version. We --aren't checking if the clip is 0 every tick, and as a result, we don't need to check if the bot is alive every tick either. --bot_reserve_combo.lua could probably be optimized in a similar way, but that would result in functionality loss, and the gameplay concept of it --is a piece of shit anyway. if primary.m_iClip1 ~= 0 or primary:GetAttributeValue("hidden string attribute 1") == "We Are Rapid" then return end --Pale bursts will cheat a bit when reloading to come up faster, was made with monochrome in mind (who was a gigaburst boss) --as a small punishment for making him expend his full clip rather than circle him or something. The pale bursts inherit this, could --probably put this on a colonel to make it more significant. local PASSIVE_RELOAD_SPEED_FACTOR = 0.8 local secondary = activator:GetPlayerItemBySlot(1) local clipBonusMult = primary:GetAttributeValueByClass("mult_clipsize", 1) local clipBonusAtomic = primary:GetAttributeValueByClass("mult_clipsize_upgrade_atomic", 0) local maxClip = (4 * clipBonusMult) + clipBonusAtomic --Hardcoded soldier rocket launcher constants, first rocket takes 0.92 flat, every subsequent rocket takes 0.8. This is then all --multiplied by reload attributes present on the bot, and then the passive reload speed factor local reloadDuration = ((((maxClip - 1) * 0.8) + 0.92) * primary:GetAttributeValueByClass("fast_reload", 1)) * PASSIVE_RELOAD_SPEED_FACTOR primary:SetAttributeValue("hidden string attribute 1", "We Are Rapid") primary:SetAttributeValue("crit vs burning players", 0) primary:SetAttributeValue("crit vs non burning players", 0) primary:SetAttributeValue("faster reload rate", -0.8) primary:SetAttributeValue("damage bonus", 0.8) primary:SetAttributeValue("fire rate bonus", 0.5) primary:SetAttributeValue("Projectile speed increased", 0.65) primary.m_iClip1 = maxClip --print("Reloaded Primary") timer.Simple(reloadDuration, function() primary:SetAttributeValue("hidden string attribute 1", "No") primary:SetAttributeValue("crit vs burning players", 1) primary:SetAttributeValue("crit vs non burning players", 1) primary:SetAttributeValue("faster reload rate", 0.3) primary:SetAttributeValue("damage bonus", 2) primary:SetAttributeValue("fire rate bonus", 0.1) primary:SetAttributeValue("Projectile speed increased", 0.8) end, 1) end function everybodyDie() local allPlayers = ents.GetAllPlayers() local disableSpawns = ents.FindByName("forceDisableSpawns") local bomb = ents.FindByClass("item_teamflag") disableSpawns:AcceptInput("Trigger") for _, player in pairs(allPlayers) do if player:IsAlive() and not player:IsRealPlayer() and player.m_iTeamNum == 3 then player:Suicide() end end bomb:SetAbsOrigin(Vector(647, -1841, 691)) end