// Nut file for Runtime Optimization, Humbridge. // by Seelpit // Dependency: // seel_ins.nut ...also by Seelpit printl("Seelpit's Runtime Optimization script loaded!") ////////////////////////////////////////////////////////////////////////// //CHANGES TO FUNCTION REFERENCES ////////////////////////////////////////////////////////////////////////// //Simplifying references to constants and NetProps. //Credit: VDC wiki, lite. foreach (k, v in NetProps.getclass()) if (k != "IsValid") getroottable()[k] <- NetProps[k].bindenv(NetProps); foreach (k, v in Entities.getclass()) if (k != "IsValid") getroottable()[k] <- Entities[k].bindenv(Entities); ::ROOT <- getroottable(); if (!("ConstantNamingConvention" in ROOT)) // make sure folding is only done once { foreach (a,b in Constants) foreach (k,v in b) if (v == null) ROOT[k] <- 0; else ROOT[k] <- v; } IncludeScript("seel_ins.nut",getroottable()) // for (local i = 1; i <= MaxClients().tointeger() ; i++) // { // local player = PlayerInstanceFromIndex(i) // AddThinkToEnt(player,null) // SetPropInt(player, "m_debugOverlays", GetPropInt(player, "m_debugOverlays") & ~OVERLAY_BUDDHA_MODE) // } ::SeelRuntime <- { Cleanup = function() { // cleanup any persistent changes here printl("Cleaning up SeelRuntime...") for (local i = 1; i <= ALL_PLAYERS ; i++) { local player = PlayerInstanceFromIndex(i) AddThinkToEnt(player,null) SetPropInt(player, "m_debugOverlays", GetPropInt(player, "m_debugOverlays") & ~OVERLAY_BUDDHA_MODE) } // keep this at the end delete ::SeelRuntime } ALL_PLAYERS = (MaxClients().tointeger()) // mandatory events OnGameEvent_recalculate_holidays = function(_) { if (GetRoundState() == 3) Cleanup() } OnGameEvent_mvm_wave_complete = function(_) { Cleanup() } OnScriptHook_OnTakeDamage = function(params) { local player = params.attacker; local victim = params.const_entity; if (victim.GetClassname() == "obj_dispenser" && victim.GetOwner().IsBotOfType(TF_BOT_TYPE)) params.damage = 0; } TestFunc = function() { printl("Test function fired succesfully!") } BallsToBombsThink = function() { for (local hBall; hBall = Entities.FindByClassname(hBall, "tf_projectile_stun_ball"); ) { local hBot = hBall.GetOwner() printl("Checking if owner "+hBot+" is valid...") if (hBot == null || !hBot.IsAlive() || !hBot.IsBotOfType(TF_BOT_TYPE) || !hBot.HasBotTag("ballbomber")) { printl("Owner is null, not alive, or doesn't have the right tag. Continuing...") continue; } EntFire("!activator","Kill","",0,hBall) for (local hWepMimic; hWepMimic = Entities.FindByClassname(hWepMimic, "tf_point_weapon_mimic"); ) if (hWepMimic.GetOwner() == hBot) hWepMimic.AcceptInput("FireOnce","",hBot,hBot) } return -1 } SetXZAnglesToZero = function(hEnt) { hEnt.SetAbsAngles(QAngle(0,hEnt.GetAbsAngles().y,0)) } FindTouchTrigger = function(hDisp) { for (local hTouchTrig; hTouchTrig = Entities.FindByClassname(hTouchTrig, "dispenser_touch_trigger"); ) if (hTouchTrig.GetOwner() == hDisp) hTouchTrig.AcceptInput("SetParent","!activator",hDisp,hDisp) } // VScript rewrite of a lua function SpawnTele = function(hBot) { local traceStartPos = hBot.GetOrigin() + Vector(0, 0, 20) local traceEndPos = hBot.GetOrigin() + Vector(0, 0, -2000) printl("AbsOrigin: "+hBot.GetOrigin().tostring()+", edited to: "+traceStartPos.tostring()) local tbTrace = { start = traceStartPos, end = traceEndPos, hullmin = hBot.GetBoundingMins() hullmax = hBot.GetBoundingMaxs() mask = 131083 //MASK_NPCWORLDSTATIC: SOLID, WINDOW, MONSTERCLIP, GRATE; aka only world. } TraceHull(tbTrace) printl("Trace finished!") if (tbTrace.hit) { printl("Trace hit at "+tbTrace.endpos.tostring()) local hTele = SpawnEntityFromTable("obj_teleporter", { targetname = "tp" spawnflags = 2 teamnum = 3 origin = tbTrace.endpos teleportertype = 2 "$TeleportWhere" : "spawnbot_chief" }) hTele.SetSolid(0) EntFire("tp","RemoveHealth",5000,5) } } PrintRandomBanter = function() { local iRandomText = RandomInt(0,3) //Switch statements are wack so I'm using if if (iRandomText == 0) PrintBanter(0) else if (iRandomText == 1) PrintBanter(1) else if (iRandomText == 2) PrintBanter(2) else if (iRandomText == 3) PrintBanter(3) } //Default delay: 2.5 PrintBanter = function(iType,iLine = 0) { local iDelay = 2.5 printl("Printing type "+iType.tostring()+", line "+iLine.tostring()+"...") if (iType == 0) { if (iLine == 0) ClientPrint(null,3,"\x07FCECCB*DEAD* \x0799CCFFJeremy, Arrogant Attacker \x07FCECCB: mix, do you collect festivizers") if (iLine == 1) ClientPrint(null,3,"\x07FCECCB*DEAD* \x0799CCFFThe Festive Jeremix \x07FCECCB: uhhh for use yeah, why?") if (iLine == 2) { ClientPrint(null,3,"\x07FCECCB*DEAD* \x0799CCFFJeremy, Arrogant Attacker \x07FCECCB: I can trade you some later") iDelay = 1 } if (iLine == 3) { ClientPrint(null,3,"\x07FCECCB*DEAD* \x0799CCFFYour Savior: Jeremessiah \x07FCECCB: simp") iDelay = 0.75 } if (iLine == 4) { ClientPrint(null,3,"\x07FCECCB*DEAD* \x0799CCFFJeremy, Arrogant Attacker \x07FCECCB: stfu") return; } } else if (iType == 1) { local iRareLine = RandomInt(0,9) if (iLine == 0) ClientPrint(null,3,"\x07FCECCB*DEAD* \x0799CCFFThe Festive Jeremix \x07FCECCB: Are respawns bugged for blue, or") if (iLine == 1 && iRareLine == 9) ClientPrint(null,3,"\x07FCECCB*DEAD* \x0799CCFFJeremy, Arrogant Attacker \x07FCECCB: you are a preplanned spawn in a wave of spawns. there is no respawn. you are a bot. all of us are.") else if (iLine == 1) { ClientPrint(null,3,"\x07FCECCB*DEAD* \x0799CCFFJeremy, Arrogant Attacker \x07FCECCB: Ya it's weird, really long or something") return; } if (iLine == 2) { ClientPrint(null,3,"\x07FCECCB*DEAD* \x0799CCFFJester Jerome \x07FCECCB: Except me :)") return; } } else if (iType == 2) { if (iLine == 0) { ClientPrint(null,3,"\x07FCECCB*DEAD* \x0799CCFFThe Festive Jeremix \x07FCECCB: Did Jeremius actually ragequit???") iDelay = 1.5 } if (iLine == 1) { ClientPrint(null,3,"\x07FCECCB*DEAD* \x0799CCFFThe Festive Jeremix \x07FCECCB: in this year???") iDelay = 0.5 } if (iLine == 2) { ClientPrint(null,3,"\x07FCECCB*DEAD* \x0799CCFFYour Savior: Jeremessiah \x07FCECCB: skill issue") ClientPrint(null,3,"\x07FCECCB*DEAD* \x0799CCFFJeremy, Arrogant Attacker \x07FCECCB: lol they did") } if (iLine == 3) { ClientPrint(null,3,"\x07FCECCB*DEAD* \x0799CCFFJeremy, Arrogant Attacker \x07FCECCB: >dies once >instant disconnect >''man i'm so cool''") return; } } else if (iType == 3) { if (iLine == 0) ClientPrint(null,3,"\x07FCECCB*DEAD* \x0799CCFFThe Festive Jeremix \x07FCECCB: Wait how the heck was Jeremiah's dc message different") if (iLine == 1) ClientPrint(null,3,"\x07FCECCB*DEAD* \x0799CCFFJeremy, Arrogant Attacker \x07FCECCB: true gamer moment") if (iLine == 2) { ClientPrint(null,3,"\x07FCECCB*DEAD* \x0799CCFFJeremy, Arrogant Attacker \x07FCECCB: For real tho no idea he just does that. Most Normal Dark Souls Player") return; } } iLine += 1 local szFunction = "SeelRuntime.PrintBanter("+ iType.tostring() +","+ iLine.tostring()+")" printl("Sending function: "+szFunction) EntFire("bignet","RunScriptCode",szFunction,iDelay) } PrintBossBanter = function(iLine) { local iDelay = 2.5 if (iLine == 0) { ClientPrint(null,3,"\x07FCECCB*DEAD* \x0799CCFFYour Savior: Jeremessiah \x07FCECCB: alright") iDelay = 0.5 } if (iLine == 1) ClientPrint(null,3,"\x07FCECCB*DEAD* \x0799CCFFYour Savior: Jeremessiah \x07FCECCB: thats it") if (iLine == 2) ClientPrint(null,3,"\x07FCECCB\x0799CCFFYour Savior: Jeremessiah \x07FCECCB: im done carrying") iLine += 1 local szFunction = "SeelRuntime.PrintBanter("+ iType.tostring() +","+ iLine.tostring()+")" printl("Sending function: "+szFunction) EntFire("bignet","RunScriptCode",szFunction,iDelay) } //Woe, ye who scour these files looking for wisdom! //SetModelScale(fl scale, fl change_duration) does the same thing as this. //I kept it cause it's functional and already useful for timing the flag change, //but if you're not doing anything once it reaches the apex, just...use SetModelScale(). ChangeScaleToGiant = function(hBot) { local flScale = GetPropFloat(hBot,"m_flModelScale") if (flScale >= 1.75) { SINS.ChangeIconFlags("tf2_lite",9) return; } if (flScale < 1.75) { hBot.SetScaleOverride(flScale + 0.0375) //~20 times, 1.2sec EntFire("!activator","RunScriptCode","SeelRuntime.ChangeScaleToGiant(self)",0.06,hBot) } } EnableBossThink = function(hBot) { local hScope = hBot.GetScriptScope() printl("Declaring scope variables...") hScope.bCola <- false hScope.bBonch <- false hScope.bMulti <- false hScope.bHaste <- false hScope.bShield <- false hScope.bDying <- false hScope.flDrinkTime <- 0 printl("Constructing think...") hScope.BossThink <- function() { if (!(self.IsAlive())) { printl("No longer alive, yeet the think.") SetPropString(self, "m_iszScriptThinkFunction", "") AddThinkToEnt(self,null) } local iHealth = fabs(self.GetHealth()) / fabs(self.GetMaxHealth()) if (bCola && flDrinkTime <= Time() && !(self.InCond(16))) //Backup logic bc Etern-a-Cola is being weird. self.AddCond(16) //95%: Crit-a-Cola, 85%: Bonch, 75%: Multi-Pop, 65%: Haste Fizz, 50%: Shield Shake if (iHealth < 0.95 && !(bCola)) { printl("Try to drink Crit-a-Cola!") EntFire("!activator","$GiveItem","Etern-a-Cola",0,self) bCola = true flDrinkTime = Time() + 3 ClientPrint(null,3,"Next drink time: "+flDrinkTime.tostring()) return -1 } else if (iHealth < 0.85 && !(bBonch) && flDrinkTime <= Time()) { printl("Try to drink Bonch!") EntFire("!activator","$GiveItem","Bonch!",0,self) EntFire("!activator","$SetProp$m_iAmmo$5","1",0.1,self) bBonch = true flDrinkTime = Time() + 3 ClientPrint(null,3,"Next drink time: "+flDrinkTime.tostring()) return -1 } else if (iHealth < 0.75 && !(bMulti) && flDrinkTime <= Time()) { printl("Try to drink Multi-Pop!") EntFire("!activator","$GiveItem","Multi-Pop",0,self) EntFire("!activator","$SetProp$m_iAmmo$5","1",0.1,self) bMulti = true flDrinkTime = Time() + 3 ClientPrint(null,3,"Next drink time: "+flDrinkTime.tostring()) return -1 } else if (iHealth < 0.65 && !(bHaste) && flDrinkTime <= Time()) { printl("Try to drink Haste Fizz!") EntFire("!activator","$GiveItem","Haste Fizz",0,self) EntFire("!activator","$SetProp$m_iAmmo$5","1",0.1,self) bHaste = true flDrinkTime = Time() + 3 ClientPrint(null,3,"Next drink time: "+flDrinkTime.tostring()) return -1 } else if (iHealth < 0.5 && !(bShield) && flDrinkTime <= Time()) { printl("Try to drink Shield Shake!") EntFire("!activator","$GiveItem","Shield Shake",0,self) EntFire("!activator","$SetProp$m_iAmmo$5","1",0.1,self) bShield = true flDrinkTime = Time() + 3 ClientPrint(null,3,"Next drink time: "+flDrinkTime.tostring()) return -1 } //Frame 108 of 194 = after 3.6 seconds if (self.GetHealth() <= 100 && self.InCond(7) && !(bDying)) { printl("Try to drink water! (100% fail!)") EntFire("soda_relay","FireUser4","",3.6,self) bDying = true SetPropInt(self, "m_debugOverlays", GetPropInt(self, "m_debugOverlays") & ~OVERLAY_BUDDHA_MODE) } return -1 } printl("Attempting to add think to boss...") AddThinkToEnt(hBot,"BossThink") printl("Giving boss buddha...") SetPropInt(hBot, "m_debugOverlays", GetPropInt(hBot, "m_debugOverlays") | OVERLAY_BUDDHA_MODE) } PrintBonkBar = function(hBot) { hBot.GetScriptScope().hText <- SpawnEntityFromTable("point_worldtext", { textsize = 40 message = 0 font = 1 orientation = 1 textspacingx = 1 textspacingy = 1 spawnflags = 0 origin = hBot.GetOrigin() + hBot.EyeAngles().Forward()*100 + Vector(0, 0, 65) rendermode = 3 }) hBot.GetScriptScope().NetPropVal <- 0 hBot.GetScriptScope().BonkThink <- function() { local flBarMeasure = GetPropFloatArray(self,"m_Shared.tfsharedlocaldata.m_flItemChargeMeter",NetPropVal) hText.KeyValueFromString("message",flBarMeasure.tostring()) } AddThinkToEnt(hBot, "BonkThink") } }; __CollectGameEventCallbacks(SeelRuntime); ////////////////////////////////////////////////////////////////////////// //CONSTANTS ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// //FUNCTIONS ////////////////////////////////////////////////////////////////////////// function ForEveryBotWithTag(tag,func) { for (local i = 1; i <= ALL_PLAYERS ; i++) { local player = PlayerInstanceFromIndex(i) if (player == null) continue if (!player.IsBotOfType(TF_BOT_TYPE)) continue if (player == self) continue if (!player.IsAlive()) continue if (player.HasBotTag(tag)) func(player); } } local path1 = null local path2 = null local carrierdead = false function SpawnCustomTankPaths() { if (!self.IsValid()) return; printl("Creating paths...") path2 = SpawnEntityFromTable("path_track",{ targetname = "carrier_path_2", origin = Vector(3810,-710,85) //Hatch coordinates. }) path1 = SpawnEntityFromTable("path_track",{ targetname = "carrier_path_1", origin = self.GetAttachmentOrigin(self.LookupAttachment("head")) + Vector(0,0,80) target = "carrier_path_2" }) ::PathMoveThink <- function() { if (!self.IsValid() || !self.IsAlive() && !self.HasBotTag("tank_carrier")) { printl("Removing think...") SetPropString(self, "m_iszScriptThinkFunction", ""); AddThinkToEnt(self, "null") } if (path1 != null && path2 != null) { printl("Setting path 1 location...") path1.SetAbsOrigin(self.GetAttachmentOrigin(self.LookupAttachment("head")) + Vector(0,0,80)) return -1 } printl("Neither dead nor paths found.") } AddThinkToEnt(self,"PathMoveThink") } function TankToBeCarried(hTank) { hTank.SetSolidFlags(FSOLID_NOT_SOLID) // ForEveryBotWithTag("tank_carrier", function(hBot) // { // hTank.AcceptInput("SetParent","!activator",hBot,hBot) // }) ::TankParentThink <- function() { if (!carrierdead) self.SetAbsOrigin(path1.GetOrigin()) } AddThinkToEnt(hTank,"TankParentThink") }