::ROOT <- getroottable() foreach(k, v in ::NetProps.getclass()) if (k != "IsValid" && !(k in ROOT)) ROOT[k] <- ::NetProps[k].bindenv(::NetProps) foreach(k, v in ::Entities.getclass()) if (k != "IsValid" && !(k in ROOT)) ROOT[k] <- ::Entities[k].bindenv(::Entities) ::dbug <- false ::Hailstorm <- { Cleanup = function() { // cleanup any persistent changes here // keep this at the end //ClientPrint(null,3,"Cleanup Called") delete ::Hailstorm } // mandatory events OnGameEvent_recalculate_holidays = function(_) { if (GetRoundState() == 3) Cleanup() } OnGameEvent_mvm_wave_complete = function(_) { //ClientPrint(null, 3, "wave complete") } OnGameEvent_mvm_mission_complete = function(_) { //ClientPrint(null, 3, "mission complete") ::HailstormIntroPlayed <- false } /* { damageamount = 160 health = 0 weaponid = 76 attacker_player = 693 crit = 0 entindex = 456 } */ OnGameEvent_npc_hurt = function(params) { local ent = EntIndexToHScript(params.entindex) if(ent.GetClassname() == "$bot_npc") { //CzUtil.PrintTable(params) if(params.health == 0) { EntFireByHandle(ent.GetMoveParent(), "$SetKey$renderfx", "6", 0, null, null) EntFireByHandle(ent.GetMoveParent(), "kill", "", 1, null, null) EntFireByHandle(ent, "kill", null, 0.2, null, null) DispatchParticleEffect("xms_icicle_impact_dryice", ent.GetOrigin(), Vector(0,0,0)) DispatchParticleEffect("crate_drop", ent.GetOrigin(), Vector(0,0,0)) } } } OnScriptHook_OnTakeDamage = function(params) { //CzUtil.PrintTable(params) if(params.const_entity == null || params.attacker == null) return local ent = params.const_entity; if(ent.GetClassname() == "$bot_npc") { DispatchParticleEffect("crate_drop", params.damage_position, Vector(0,0,0)) if(params.damage > ent.GetHealth()) { params.damage = 0 EntFireByHandle(ent.GetMoveParent(), "$SetKey$renderfx", "6", 0, null, null) EntFireByHandle(ent.GetMoveParent(), "kill", "", 1, null, null) DispatchParticleEffect("xms_icicle_impact_dryice", ent.GetOrigin(), Vector(0,0,0)) EntFireByHandle(ent, "kill", null, 0.2, null, null) params.early_out = true } } if(ent.GetClassname() == "obj_dispenser" && ent.GetTeam()==3) { ClientPrint(null,3,ent.GetName() + " parent " + ent.GetMoveParent().tostring()) } // if(ent.GetTeam() == params.attacker.GetTeam() && ent != params.attacker) { // ClientPrint(null, 3, "ent attacker " + params.attacker.tostring()) // CzUtil.PrintTable(params) // //params.damage = 0 // //params.early_out = true // } // if(ent.GetClassname() == "obj_sentrygun" && ent.GetTeam()==3) { // ClientPrint(null,3,"sentryhit " + ent.GetKeyString("targetname")) // ClientPrint(null,3,"parent " + ent.GetMoveParent().tostring()) // if(ent.GetMoveParent().GetClassname() == "player" && CzUtil.IsPlayerAlive(ent.GetMoveParent())) // Hailstorm.Defrost(ent.GetMoveParent(), params.damage/10) // } if(ent.GetClassname() == "player" && ent.GetTeam()==2) { //ClientPrint(ent, 3, "attacker " + params.attacker.tostring() + " is burn " + (params.damage_type & Constants.FDmgType.DMG_BURN).tostring() + " is custom " + params.damage_custom.tostring()) local scope = ent.GetScriptScope() if(params.attacker == Hailstorm.Boss && Hailstorm.IsIce() && !scope.isFrozen) { local frostAmt = params.damage/15.0 Hailstorm.FrostUp(ent, frostAmt) } if((params.damage_type & Constants.FDmgType.DMG_BURN) && params.damage_custom != Constants.ETFDmgCustom.TF_DMG_CUSTOM_BLEEDING) { if(params.attacker == Hailstorm.Boss && !Hailstorm.IsIce()) { Hailstorm.Defrost(ent, params.damage/10) } else if(params.attacker != Hailstorm.Boss){ Hailstorm.Defrost(ent, params.damage/10) } if(params.attacker == ent) Hailstorm.Defrost(ent, params.damage/15) } // if(params.damage > ent.GetHealth() && params.damage < 999) { // Hailstorm.CustomFreeze(ent,params.attacker,ent) // } } } //crossbow_heal //take_health OnGameEvent_player_healed = function(params) { local player = GetPlayerFromUserID(params.patient); local healer = GetPlayerFromUserID(params.healer); //ClientPrint(null, 3, "amount " + params.amount) if(params.healer == 0) { Hailstorm.Defrost(player, 4) } else if(healer != null && healer != player){ Hailstorm.Defrost(player, params.amount/15) } else if(healer != null && healer == player){ Hailstorm.Defrost(player, params.amount/25) } } OnGameEvent_player_spawn = function(params) { local player = GetPlayerFromUserID(params.userid); player.ValidateScriptScope() if (player != null ) //&& player.GetTeam() == 2 { if(dbug) ClientPrint(null, 3, "playerspawned " + player.tostring()) PlayerSetup(player) } } OnGameEvent_post_inventory_application = function(params) { local player = GetPlayerFromUserID(params.userid); player.ValidateScriptScope() if (player != null && player.GetTeam() == 2) { PlayerSetup(player) } } OnGameEvent_player_death = function(params) { local player = GetPlayerFromUserID(params.userid); NetProps.SetPropString(player, "m_iszScriptThinkFunction", "") if (player != null && player.GetTeam() == 2) { local scope = player.GetScriptScope() player.AddCustomAttribute("major move speed bonus", scope.playerSpeed, -1) player.AddCustomAttribute("major increased jump height", scope.playerJump, -1) player.RemoveCustomAttribute("damage force reduction") EntFireByHandle(scope.frostParticle, "stop", null, 0, null, null) if(scope.isFrozen) { player.SetScriptOverlayMaterial("overlays/term_frost_overlay") } Hailstorm.RemoveIceblock(player, 2) try { EntFireByHandle(scope.statusText, "SetText", " ", 0, null, null) } catch (exception){} //EntFireByHandle(player.GetScriptScope().frostDisplay, "Display", null, 0, self, self) } } PlayerSetup = function(player) { local scope = player.GetScriptScope() player.SetScriptOverlayMaterial("") player.RemoveCustomAttribute("attach particle effect") scope.frostbite <- 0 scope.isFrozen <- false //if(!scope.rawin("frostDisplay")) { if(!scope.rawin("frostDisplay") || !scope.frostDisplay.IsValid()) { scope.frostDisplay <- SpawnEntityFromTable("game_text", { spawnflags = 0 message = "Frostbite: 0%" x = -1 y = 0.8 //0.6 color = "255 255 255" channel = 2 fadein = 0.1 fadeout = 0.1 fxtime = 0.1 holdtime = 0.5 }) } if(!scope.rawin("frostParticle") || !scope.frostParticle.IsValid()) { scope.frostParticle <- SpawnEntityFromTable("info_particle_system", { "origin" : player.GetOrigin() + Vector(0,0,64) "effect_name" : "unusual_blood_snow_parent" "start_active" : "0" }) //EntFireByHandle(scope.frostParticle, "AcceptInput", "SetParent !activator", 0, player, player) EntFireByHandle(scope.frostParticle, "SetParent", "!activator", 0.1, player, player) EntFireByHandle(scope.frostParticle, "SetParentAttachment", "head", 0.2, null, null) EntFireByHandle(scope.frostParticle, "$HideTo", "!activator", 0.2, player, player) } scope.playerSpeed <- player.GetCustomAttribute("major move speed bonus", 1) scope.playerJump <- player.GetCustomAttribute("major increased jump height", 1) NetProps.SetPropInt(player, "m_Shared.m_iNextMeleeCrit", -2) scope.buttons_last <- 0 scope.last_fire_time <- 0.0 scope.wep_record <- player.GetActiveWeapon() //} scope.ringOfFireAim <- false for (local i = 0; i < 8; i++) { local weapon = NetProps.GetPropEntityArray(player, "m_hMyWeapons", i) if (weapon == null) continue if(weapon.IsMeleeWeapon() && (weapon.GetAttribute("Set DamageType Ignite",0) > 0 || weapon.GetAttribute("crit vs burning players",0) > 0 || weapon.GetAttribute("ragdolls plasma effect",0) > 0) ) { scope.spicyMelee <- true } else if (weapon.IsMeleeWeapon()) { scope.spicyMelee <- false } else if(weapon.GetAttribute("ring of fire while aiming",0) > 0) { scope.ringOfFireAim <- true } } if(!("statusText" in scope) || !scope.statusText.IsValid()) { scope.statusText <- SpawnEntityFromTable("point_worldtext", { "message": " " "font": 1 "textsize": 7 "color": "150 255 50 255" "orientation": 1 "origin": player.GetOrigin() + Vector(0,0,80) }) scope.statusText.ValidateScriptScope() scope.statusText.GetScriptScope().transparency <- 255 scope.statusText.GetScriptScope().fadeText <- function(){ if(transparency < 7) { transparency = 0 self.KeyValueFromString("color", "150 255 50 " + transparency.tostring()) } else if(transparency > 5) { transparency -= 5 self.KeyValueFromString("color", "150 255 50 " + transparency.tostring()) } return -1 } AddThinkToEnt(scope.statusText, "fadeText") scope.statusText.AcceptInput("SetParent", "!activator", player, player) } AddThinkToEnt(player, "HailstormPlayerThink") } }; __CollectGameEventCallbacks(Hailstorm) if(!("igniter" in Hailstorm) || !Hailstorm.igniter.IsValid()){ Hailstorm.igniter <- SpawnEntityFromTable("trigger_ignite", { spawnflags = 1 origin = Vector(-3243, 205, 2426) filtername = "filter_is_red_not_ubered" burn_duration = 4 damage_percent_per_second = 8 }) Hailstorm.igniter.SetSize(Vector(-10, -10, 0), Vector(10, 10, 10)) Hailstorm.igniter.SetSolid(2) // SOLID_BBOX } for (local i = 1, player; i <= MaxClients().tointeger(); i++) { if (player = PlayerInstanceFromIndex(i), player && player.GetTeam() == 2) { Hailstorm.PlayerSetup(player) } } Hailstorm.IgnitePlayer <- function(player) { EntFireByHandle(Hailstorm.igniter, "StartTouch", null, 0, player, player) EntFireByHandle(Hailstorm.igniter, "EndTouch", null, 0.1, player, player) } Hailstorm.IgniteEveryone <- function() { for (local i = 1, player; i <= MaxClients().tointeger(); i++) { if (player = PlayerInstanceFromIndex(i), player && player.GetTeam() == 2) { Hailstorm.IgnitePlayer(player) } } } //sm_ent_fire tf_gamerules runscriptcode "Hailstorm.FreezeEveryone()" Hailstorm.FreezeEveryone <- function() { for (local i = 1, player; i <= MaxClients().tointeger(); i++) { if (player = PlayerInstanceFromIndex(i), player && (player.GetTeam() == 2 || player.InCond(43))) { ClientPrint(null, 3, player.tostring()) Hailstorm.FreezePlayer(player) try { local scope = player.GetScriptScope() EntFireByHandle(scope.statusText, "SetText", "+ Frost", 0, null, null) scope.statusText.GetScriptScope().transparency <- 255 scope.statusText.KeyValueFromString("color", "150 255 50 255") } catch (exception){} } } } Hailstorm.FreezeEveryoneFunni <- function() { for (local i = 1, player; i <= MaxClients().tointeger(); i++) { if (player = PlayerInstanceFromIndex(i), player && player.GetTeam() == 2) { Hailstorm.CustomFreeze(player, player, player) } } } // Ensure only one of this entity is ever spawned if (!("freeze_proxy_weapon" in getroottable())) { ::freeze_proxy_weapon <- null } // Create the fake weapon if one doesn't already exist if (!freeze_proxy_weapon || !freeze_proxy_weapon.IsValid()) { freeze_proxy_weapon = Entities.CreateByClassname("tf_weapon_knife") NetProps.SetPropInt(freeze_proxy_weapon, "m_AttributeManager.m_Item.m_iItemDefinitionIndex", 649) NetProps.SetPropBool(freeze_proxy_weapon, "m_AttributeManager.m_Item.m_bInitialized", true) freeze_proxy_weapon.DispatchSpawn() freeze_proxy_weapon.DisableDraw() // Add the attribute that creates ice statues freeze_proxy_weapon.AddAttribute("freeze backstab victim", 1.0, -1.0) freeze_proxy_weapon.AddAttribute("allow friendly fire", 1.0, -1.0) freeze_proxy_weapon.AddAttribute("set turn to ice", 1.0, -1.0) } Hailstorm.CustomFreeze<- function(victim, attacker, wep = null) { // Set any owner on the weapon to prevent a crash NetProps.SetPropEntity(freeze_proxy_weapon, "m_hOwner", attacker) local inflictor = freeze_proxy_weapon if(wep!=null) inflictor = wep // Deal the damage with the weapon //TakeDamageCustom(handle hInflictor, handle hAttacker, handle hWeapon, Vector vecDamageForce, Vector vecDamagePosition, float flDamage, Constants.FDmgType nDamageType, Constants.ETFDmgCustom nCustomDamageType) // victim.TakeDamageCustom(freeze_proxy_weapon, attacker, inflictor, // Vector(0,0,0), Vector(0,0,0), // 9999.0, 1048704, Constants.ETFDmgCustom.TF_DMG_CUSTOM_BACKSTAB) victim.TakeDamageCustom(inflictor, attacker, freeze_proxy_weapon, Vector(0,0,0), Vector(0,0,0), 9999.0, 1, 0) //Constants.FDmgType.DMG_CLUB // I don't remember why this is needed but it's important local ragdoll = NetProps.GetPropEntity(victim, "m_hRagdoll") if (ragdoll) NetProps.SetPropInt(ragdoll, "m_iDamageCustom", 0) } ::HailstormPlayerThink <- function() { local scope = self.GetScriptScope() local fire_time = NetProps.GetPropFloat(self.GetActiveWeapon(), "m_flLastFireTime") local cur_wep = self.GetActiveWeapon() //ClientPrint(self,4,fire_time.tostring()) if(!CzUtil.IsPlayerAlive(self)) return //ClientPrint(self, 3, self.tostring() + " think called") if(scope.frostbite > 0 && FindByClassnameWithin(null, "item_healthkit*", self.GetOrigin(), 15)) { self.SetHealth(self.GetHealth()-1) Hailstorm.Defrost(self, 10) } if(scope.ringOfFireAim && self.InCond(Constants.ETFCond.TF_COND_AIMING)) { foreach (k, player in CzUtil.Players) { if((player.GetOrigin() - self.GetOrigin()).Length() < 75) { Hailstorm.Defrost(player, 0.04) if(Hailstorm.HasFrostbite(player)) Hailstorm.SetDefrostText(player) } } } if(self.GetPlayerClass() == Constants.ETFClass.TF_CLASS_MEDIC && self.GetHealTarget() != null) { Hailstorm.Defrost(self.GetHealTarget(), 0.04) if(Hailstorm.HasFrostbite(player)) Hailstorm.SetDefrostText(player) } //detect melee fire if (self.GetActiveWeapon().IsMeleeWeapon() && NetProps.GetPropInt(self, "m_Shared.m_iNextMeleeCrit") == 0) { if(dbug) ClientPrint(self, 3, "fired" + Time().tostring()) local hits = CzUtil.GetPlayerTraceHittable(self, 80) if(hits != null) { foreach (i, hit in hits) { DispatchParticleEffect("xms_icicle_impact_dryice", hit.enthit.GetOrigin(), Vector(0,0,0)) if(hit.enthit.GetClassname() == "player" && hit.enthit.GetScriptScope().frostbite > 0 && hit.enthit.GetTeam() == self.GetTeam()) { if (self.GetScriptScope().spicyMelee) Hailstorm.Defrost(hit.enthit, 7) else //if (hit.enthit.GetScriptScope().isFrozen) Hailstorm.Defrost(hit.enthit, 3) EntFireByHandle(hit.enthit, "RunScriptCode", "DispatchParticleEffect(`crate_drop`, self.GetOrigin() + Vector(0,0,40), Vector(0,0,0))", 0, null, null) } } } } NetProps.SetPropInt(self, "m_Shared.m_iNextMeleeCrit", -2) if(wep_record != cur_wep) { wep_record = cur_wep last_fire_time = Time() } //detect weapon fire if (fire_time > last_fire_time){ if(dbug) ClientPrint(self, 3, "fired" + Time().tostring()) if(self.GetPlayerClass() == Constants.ETFClass.TF_CLASS_PYRO && self.GetActiveWeapon().GetClassname().find("tf_weapon_rocketlauncher_fireball")!=null && self.GetActiveWeapon().HasPrimaryAmmo()) { local hits = CzUtil.GetPlayerTraceHittable(self, 400) if(hits != null) { foreach (i, hit in hits) { if(hit.enthit.GetClassname() == "player" && hit.enthit.GetTeam() == 2 && hit.enthit.GetScriptScope().frostbite > 0) { Hailstorm.Defrost(hit.enthit, 3) } } } } } local buttons = NetProps.GetPropInt(self, "m_nButtons") local buttons_changed = buttons_last ^ buttons local buttons_pressed = buttons_changed & buttons local buttons_released = buttons_changed & (~buttons) if (buttons_pressed & Constants.FButtons.IN_ATTACK) { //ClientPrint(self, 3, self.tostring() + "Player pressed left-click") if(self.GetPlayerClass() == Constants.ETFClass.TF_CLASS_SPY && self.GetActiveWeapon().IsMeleeWeapon()) { local hits = CzUtil.GetPlayerTraceHittable(self, 80) if(hits != null) { foreach (i, hit in hits) { if(hit.enthit.GetClassname() == "player" && hit.enthit.GetScriptScope().frostbite > 0 && hit.enthit.GetTeam() == self.GetTeam()) { //&& hit.enthit.GetTeam() == 2 if (hit.enthit.GetScriptScope().isFrozen && (self.GetActiveWeapon().GetAttribute("freeze backstab victim",0) > 0)){ Hailstorm.CustomFreeze(hit.enthit, self) } else //if (hit.enthit.GetScriptScope().isFrozen) Hailstorm.Defrost(hit.enthit, 3) } } } } } if (buttons & Constants.FButtons.IN_ATTACK) { //ClientPrint(self, 3, self.tostring() + "Player holding left-click") if(self.GetPlayerClass() == Constants.ETFClass.TF_CLASS_PYRO && self.GetActiveWeapon().GetClassname().find("flamethrower")!=null && self.GetActiveWeapon().HasPrimaryAmmo()) { local hits = CzUtil.GetPlayerTraceHittable(self, 350) if(hits != null) { foreach (i, hit in hits) { if(hit.enthit.GetClassname() == "player" && hit.enthit.GetTeam() == 2 && hit.enthit.GetScriptScope().frostbite > 0) { Hailstorm.Defrost(hit.enthit, 0.05) } } } } } if (buttons_pressed & Constants.FButtons.IN_JUMP) { //ClientPrint(self, 3, self.tostring() + "Player pressed jump") if(scope.isFrozen) Hailstorm.Defrost(self,1) } last_fire_time = fire_time buttons_last = buttons if(scope.isFrozen) { EntFireByHandle(scope.frostDisplay, "Display", null, 0, self, self) } else if(scope.frostbite > 0){ Hailstorm.Defrost(self,0.005) EntFireByHandle(scope.frostDisplay, "Display", null, 0, self, self) } return -1 } Hailstorm.FrostUp <- function(player, frostAmt) { local scope = player.GetScriptScope() if(scope.isFrozen) { return } scope.frostbite += frostAmt scope.frostbite = CzUtil.Min(scope.frostbite, 10.0) local frost = ceil(scope.frostbite * 10.0) NetProps.SetPropString(scope.frostDisplay, "m_iszMessage", "Frostbite: " + frost.tostring() + "%") scope.frostDisplay.KeyValueFromString("color", "50 50 " + (154+frost).tostring()) scope.frostDisplay.KeyValueFromString("color2", "50 50 " + (154+frost).tostring()) if(scope.frostbite == 10) { Hailstorm.FreezePlayer(player) //Hailstorm.ShowFrostbiteTutorial(ent) } else if(scope.frostbite > 0) { CzUtil.EmitFx(player,"BallBuster.Ornament_DrawCatch",0.6,0.4) //BallBuster.OrnamentImpact //Weapon_BackBurner.WindDown player.AddCustomAttribute("attach particle effect", 3087, -1) player.SetScriptOverlayMaterial("overlays/term_frost_overlay") EntFireByHandle(scope.frostParticle, "start", null, 0, null, null) Hailstorm.ShowFrostbiteTutorial(player) } } Hailstorm.IceRingCallback <- function(player) { Hailstorm.FrostUp(player,4) CzUtil.EmitFx(player,"Icicle.TurnToIce",0.6,0.5) player.ApplyAbsVelocityImpulse(Vector(0,0,100)) } Hailstorm.SetDefrostText <- function(player) { local scope = player.GetScriptScope() try { EntFireByHandle(scope.statusText, "SetText", "- Frost", 0, null, null) scope.statusText.GetScriptScope().transparency <- 255 scope.statusText.KeyValueFromString("color", "150 255 50 255") } catch (exception){} } Hailstorm.Defrost <- function(player, amount = 1){ if(player.GetClassname() != "player") return local scope = player.GetScriptScope() if(scope.frostbite == 0 && !scope.isFrozen) { player.RemoveCustomAttribute("attach particle effect") player.SetScriptOverlayMaterial("") EntFireByHandle(scope.frostParticle, "stop", null, 0, null, null) return } scope.frostbite = CzUtil.Max(scope.frostbite - amount, 0) local frost = ceil(scope.frostbite * 10) //player.RemoveCustomAttribute("major move speed bonus") if(amount > 0.5) { CzUtil.EmitFx(player,"Taunt.Pyro02Fire",0.5) DispatchParticleEffect("xms_icicle_impact_dryice", player.GetOrigin(), Vector(0,0,0)) Hailstorm.SetDefrostText(player) if(dbug) ClientPrint(null,3,"defrost called") } if(scope.frostbite == 0) { player.RemoveCustomAttribute("attach particle effect") player.SetScriptOverlayMaterial("") EntFireByHandle(scope.frostParticle, "stop", null, 0, null, null) player.RemoveCond(Constants.ETFCond.TF_COND_BLEEDING) } if(scope.isFrozen && scope.frostbite == 0) { Hailstorm.UnfreezePlayer(player) } else if(scope.isFrozen && scope.frostbite > 0) { NetProps.SetPropString(scope.frostDisplay, "m_iszMessage", "Frozen: " + frost.tostring() + "%") scope.frostDisplay.KeyValueFromString("color", "50 50 255") //EntFireByHandle(scope.frostDisplay, "SetTextColor", "100 100 255", 0.0, player,player) //EntFireByHandle(scope.frostDisplay, "Display", null, 0.1, player,player) } else if(!scope.isFrozen) { local newSpeed = scope.playerSpeed * CzUtil.Max((10-(scope.frostbite*0.5))/10,0.3) player.AddCustomAttribute("major move speed bonus", newSpeed, -1) NetProps.SetPropString(scope.frostDisplay, "m_iszMessage", "Frostbite: " + frost.tostring() + "%") //ClientPrint(null, 3, "10 10 " + (155+frost).tostring()) scope.frostDisplay.KeyValueFromString("color", "50 50 " + (154+frost).tostring()) //EntFireByHandle(scope.frostDisplay, "SetTextColor", "100 100 " + (155+frost).tostring(), 0.0, player,player) //EntFireByHandle(scope.frostDisplay, "Display", null, 0.1, player,player) } } Hailstorm.RemoveIceblock <- function(player, delay = 0.5) { local ice = Entities.FindByNameNearest( "iceblock*", player.GetOrigin(), 500) if(ice != null) { //local iceProp = Entities.FindByNameWithin(null, "iceblockprop", ice.GetOrigin(), 30) EntFireByHandle(ice,"$SetKey$renderfx","5",0,null,null) EntFireByHandle(ice,"kill","",delay,null,null) } if("iceCube" in player.GetScriptScope()) { ice = player.GetScriptScope().iceCube EntFireByHandle(ice,"$SetKey$renderfx","5",0,null,null) EntFireByHandle(ice,"kill","",delay,null,null) } } Hailstorm.UnfreezePlayer <- function(player) { local scope = player.GetScriptScope() player.SetScriptOverlayMaterial("") scope.isFrozen = false CzUtil.EmitFx(player,"TFPlayer.FlameOut",0.6,0.4) CzUtil.EmitFx(player,"Icicle.Melt",0.8,0.4) DispatchParticleEffect("xms_icicle_impact_dryice", player.GetOrigin(), Vector(0,0,0)) scope.frostDisplay.KeyValueFromString("color", "50 50 155") //EntFireByHandle(scope.frostDisplay, "SetTextColor", "100 100 155", 0.0, player,player) NetProps.SetPropString(scope.frostDisplay, "m_iszMessage", "Frostbite: 0%") //EntFireByHandle(scope.frostDisplay, "Display", null, 0.1, player,player) if(dbug) ClientPrint(player, 3, "unfreeze player") player.AddCustomAttribute("major move speed bonus", scope.playerSpeed, -1) player.AddCustomAttribute("major increased jump height", scope.playerJump, -1) player.RemoveCustomAttribute("damage force reduction") Hailstorm.RemoveIceblock(player) } Hailstorm.FreezePlayer <- function(player) { local scope = player.GetScriptScope() EntFireByHandle(scope.frostParticle, "start", null, 0, null, null) player.SetScriptOverlayMaterial("overlays/term_frozen_overlay_hd") scope.isFrozen = true CzUtil.EmitFx(player,"Icicle.TurnToIce",0.8,0.4) scope.frostbite = 10 NetProps.SetPropString(scope.frostDisplay, "m_iszMessage", "Frozen: 100%") //EntFireByHandle(scope.frostDisplay, "Display", null, 0.1, player,player) if(dbug) ClientPrint(player, 3, "freeze player") player.AddCustomAttribute("major move speed bonus", 0.2, -1) player.AddCustomAttribute("major increased jump height", 0.35, -1) player.AddCustomAttribute("damage force reduction", 0.2, -1) EntFire("playerIceMaker", "ForceSpawnAtEntityOrigin", "!activator", 0, player) } Hailstorm.HasFrostbite <- function(player) { try { return player.GetScriptScope().frostbite > 0 } catch (exception){ return false } } Hailstorm.DoneTutorial <- []; // Hailstorm.tutCalls <- 0 // Hailstorm.tutFroCalls <- 0 Hailstorm.ShowFrostbiteTutorial <- function(frostbitten) { local pyroMsg = "Pyro, use your primary to defrost players!" local medicMsg = "Heal players to defrost them!" foreach (k, player in CzUtil.Players) { if (player.GetTeam() == 2 && CzUtil.IsPlayerAlive(player)) { if(player != frostbitten && player.GetPlayerClass() == Constants.ETFClass.TF_CLASS_PYRO && Hailstorm.DoneTutorial.find(player.entindex()) == null) { CzUtil.ShowAnnotationToPlayer(player, pyroMsg, 12, frostbitten.GetOrigin()+Vector(0,0,80), frostbitten, true, "weapons/icicle_freeze_victim_01.wav") Hailstorm.DoneTutorial.append(player.entindex()) } else if(player != frostbitten && player.GetPlayerClass() == Constants.ETFClass.TF_CLASS_MEDIC && Hailstorm.DoneTutorial.find(player.entindex()) == null) { CzUtil.ShowAnnotationToPlayer(player, medicMsg, 12, frostbitten.GetOrigin()+Vector(0,0,80), frostbitten, true, "weapons/icicle_freeze_victim_01.wav") Hailstorm.DoneTutorial.append(player.entindex()) } } } } // Hailstorm.ShowFrozenTutorial <- function(frostbitten) { local msg = "Use your melee to free frozen players!" local pyroMsg = "Pyro, use your primary or melee to free frozen players!" foreach (k, player in CzUtil.Players) { if (player.GetTeam() == 2 && CzUtil.IsPlayerAlive(player)) { if(player != frostbitten && Hailstorm.DoneTutorial.find(player.entindex()) == null) { if(player.GetPlayerClass() == Constants.ETFClass.TF_CLASS_PYRO) { CzUtil.ShowAnnotationToPlayer(player, pyroMsg, 12, frostbitten.GetOrigin()+Vector(0,0,80), frostbitten, true, "weapons/icicle_freeze_victim_01.wav") } else { CzUtil.ShowAnnotationToPlayer(player, msg, 12, frostbitten.GetOrigin()+Vector(0,0,80), frostbitten, true, "weapons/icicle_freeze_victim_01.wav") } Hailstorm.DoneTutorial.append(player.entindex()) } } } } Hailstorm.reactorMode <- 0; // 0 off, 1 hot, 2 cold Hailstorm.ReactorSetup <- function(entCore) { entCore.ValidateScriptScope() } Hailstorm.ReactorSetHot <- function() { TextualTimer.SetParams({ color = "255 100 20" text_prepend = "CRITICAL MELTDOWN | " }) if(!TextualTimer.bActive) TextualTimer.Start() Hailstorm.reactorMode = 1 } Hailstorm.ReactorSetCold <- function() { TextualTimer.SetParams({ color = "20 100 255" text_prepend = "HYPOTHERMIC COLLAPSE | " }) if(!TextualTimer.bActive) TextualTimer.Start() Hailstorm.reactorMode = 2 } Hailstorm.ReactorSetOff <- function() { TextualTimer.SetParams({ color = "100 100 100" text_prepend = "" }) TextualTimer.Pause() Hailstorm.reactorMode = 0 } Hailstorm.UseCore <- function(player) { local flag = NetProps.GetPropEntity(player, "m_hItem") local timerChange = 0 if(flag.GetName().find("hot") != null) { ClientPrint(null,3,"") timerChange = Hailstorm.reactorMode == 2 ? 60 : -30 } else if(flag.GetName().find("cold") != null){ timerChange = Hailstorm.reactorMode == 1 ? 60 : -30 } TextualTimer.Add(timerChange) } Hailstorm.TriggerNextAttack <- function() { } Hailstorm.Boss <- null; Hailstorm.Mode <- 0; Hailstorm.IsFire <- function() { return Hailstorm.Mode == 0 } Hailstorm.IsIce <- function() { return Hailstorm.Mode == 1 } Hailstorm.IsEnraged <- function() { return Hailstorm.Mode == 2 } Hailstorm.SetPyroModel <- function() { local hpPercent = ((1.0*Hailstorm.Boss.GetHealth()) / (1.0*Hailstorm.Boss.GetMaxHealth())) if (hpPercent >=0.9) { Hailstorm.Boss.SetCustomModelWithClassAnimations("models/bots/pyro_boss/bot_thermal_pyro.mdl") } else if (hpPercent < 0.9 && hpPercent > 0.6) { Hailstorm.Boss.SetCustomModelWithClassAnimations("models/bots/pyro_boss/bot_thermal_pyro_damage1.mdl") } else if (hpPercent < 0.6 && hpPercent > 0.3) { Hailstorm.Boss.SetCustomModelWithClassAnimations("models/bots/pyro_boss/bot_thermal_pyro_damage2.mdl") } else if (hpPercent < 0.3) { Hailstorm.Boss.SetCustomModelWithClassAnimations("models/bots/pyro_boss/bot_thermal_pyro_damage3.mdl") } } Hailstorm.ConvertColor <- function(r, g, b, a) { local color = (r) | (g << 8) | (b << 16) | (a << 24) return color } Hailstorm.colours <- {} Hailstorm.colours.fire <- Hailstorm.ConvertColor(255,150,0,255) Hailstorm.colours.ice <- Hailstorm.ConvertColor(130,255,255,255) Hailstorm.colours.red <- Hailstorm.ConvertColor(255,0,0,255) // sets mode specific colours and visual particles Hailstorm.SetPyroColour <- function() { local bot = Hailstorm.Boss local deadheat = null for (local wearable = bot.FirstMoveChild(); wearable != null; wearable = wearable.NextMovePeer()) { if (wearable.GetClassname() == "tf_wearable" && wearable.GetModelName().find("dead_heat")!=null) { deadheat = wearable break; } //EntFireByHandle(wearable, "$SetKey$rendermode", "1", 0, null, null) } if(Hailstorm.IsFire()) { if(deadheat!=null) { EntFireByHandle(deadheat, "$SetProp$m_clrRender", Hailstorm.colours.fire.tostring(), 0.25, null, null) //deadheat.AddAttribute("item color rgb", Hailstorm.colours.fire, 999999) deadheat.AddAttribute("set item tint RGB", Hailstorm.colours.fire, 999999) EntFireByHandle(deadheat, "RunScriptCode", "self.AddAttribute(`SPELL: set Halloween footstep type`, 13595446, -1)", 0.25, null, null) deadheat.RemoveAttribute("attach particle effect") } EntFire("lilparti_fire", "start", null, 0.1) EntFire("lilparti_ice", "stop", null, 0.1) EntFire("eye_L_ice", "stop", null, 0.1) EntFire("eye_R_ice", "stop", null, 0.1) EntFire("eye_L_fire", "start", null, 0.1) EntFire("eye_R_fire", "start", null, 0.1) } else if(Hailstorm.IsIce()) { if(deadheat!=null) { EntFireByHandle(deadheat, "$SetProp$m_clrRender", Hailstorm.colours.ice.tostring(), 0.25, null, null) //deadheat.AddAttribute("item color rgb", Hailstorm.colours.ice, 999999) deadheat.AddAttribute("set item tint RGB", Hailstorm.colours.ice, 999999) EntFireByHandle(deadheat, "RunScriptCode", "self.AddAttribute(`attach particle effect`, 315, -1)", 0.25, null, null) deadheat.RemoveAttribute("SPELL: set Halloween footstep type") } EntFire("lilparti_fire", "stop", null, 0.1) EntFire("lilparti_ice", "start", null, 0.1) EntFire("eye_L_ice", "start", null, 0.1) EntFire("eye_R_ice", "start", null, 0.1) EntFire("eye_L_fire", "stop", null, 0.1) EntFire("eye_R_fire", "stop", null, 0.1) } else if(Hailstorm.IsEnraged()) { if(deadheat!=null) { EntFireByHandle(deadheat, "$SetProp$m_clrRender", Hailstorm.colours.red.tostring(), 0.25, null, null) EntFireByHandle(deadheat, "RunScriptCode", "self.AddAttribute(`SPELL: set Halloween footstep type`, 13595446, -1)", 0.25, null, null) } EntFire("lilparti_fire", "start", null, 0.1) EntFire("lilparti_ice", "stop", null, 0.1) EntFire("eye_L_ice", "stop", null, 0.1) EntFire("eye_R_ice", "stop", null, 0.1) EntFire("eye_L_fire", "start", null, 0.1) EntFire("eye_R_fire", "start", null, 0.1) } } Hailstorm.SetSkinTest <- function(skin) { local owner = Hailstorm.Boss ClientPrint(null, 3, owner.GetModelName() + " " + owner.tostring()) ClientPrint(null, 3, GetPropInt(owner, "m_nSkin").tostring() + " " + "m_nSkin") ClientPrint(null, 3, GetPropInt(owner, "m_bForcedSkin").tostring() + " " + "m_bForcedSkin") ClientPrint(null, 3, GetPropInt(owner, "m_nForcedSkin").tostring() + " " + "m_nForcedSkin") ClientPrint(null, 3, GetPropInt(owner, "m_iPlayerSkinOverride").tostring() + " " + "m_iPlayerSkinOverride") SetPropInt(Hailstorm.Boss, "m_nSkin", skin) SetPropBool(Hailstorm.Boss, "m_bForcedSkin", true) SetPropInt(Hailstorm.Boss, "m_nForcedSkin", skin) SetPropInt(Hailstorm.Boss, "m_iPlayerSkinOverride", 1) Hailstorm.Boss.SetSkin(skin) for (local ent; ent = Entities.FindByClassname(ent, "tf_wearable*"); ) { if(GetPropEntity(ent, "m_hOwnerEntity")!=Hailstorm.Boss) continue ClientPrint(null, 2, "wearable: modelindex " + NetProps.GetPropInt(ent, "m_nModelIndex")) ClientPrint(null, 2, ent.tostring() + " " + ent.GetModelName()) SetPropInt(ent, "m_nSkin", skin) ent.SetSkin(skin) ClientPrint(null, 3, ent.GetModelName() + " " + ent.tostring()) ClientPrint(null, 3, GetPropInt(ent, "m_nSkin").tostring() + " " + "m_nSkin") ClientPrint(null, 3, GetPropInt(ent, "m_bForcedSkin").tostring() + " " + "m_bForcedSkin") ClientPrint(null, 3, GetPropInt(ent, "m_nForcedSkin").tostring() + " " + "m_nForcedSkin") ClientPrint(null, 3, GetPropInt(ent, "m_iPlayerSkinOverride").tostring() + " " + "m_iPlayerSkinOverride") ClientPrint(null, 3, GetPropEntity(ent, "m_hOwnerEntity").tostring() + " " + "m_hOwnerEntity") CzUtil.RemoveThink(ent) // if(NetProps.GetPropInt(ent, "m_nModelIndex") > 1000) { // } } Hailstorm.Boss.UpdateSkin(skin) } Hailstorm.SetPyroColourExp <- function(r,g,b,a) { local bot = Hailstorm.Boss ClientPrint(null, 3, bot.tostring()) for (local wearable = bot.FirstMoveChild(); wearable != null; wearable = wearable.NextMovePeer()) { //ClientPrint(null, 3, wearable.GetModelName()) if (wearable.GetClassname() != "tf_wearable"||wearable.GetModelName().find("dead_heat")==null) continue; //ClientPrint(null, 3, wearable.tostring()) // m_clrRender EntFireByHandle(wearable, "$SetKey$rendermode", "5", 0, null, null) EntFireByHandle(wearable, "$SetProp$m_clrRender", Hailstorm.ConvertColor(r,g,b,a).tostring(), 0, null, null) // EntFireByHandle(wearable, "$SetProp$m_iTeamNum", "3", 0, null, null) wearable.AddAttribute("item color rgb", val, 999999) wearable.AddAttribute("set item tint RGB", val, 999999) } local ent = null while ( ent = Entities.FindByClassname(ent, "tf_wearable")) { try { ClientPrint(null, 3, ent.GetModelName()) ent.SetSkin(3) } catch (exception){ } // ... } // ent = null while ( ent = FindByModel(ent, "models/bots/pyro_boss/bot_thermal_pyro.mdl")) { try { ClientPrint(null, 3, ent.GetModelName() + " " + ent.tostring()) ClientPrint(null, 3, GetPropInt(ent, "m_nSkin").tostring() + " " + "m_nSkin") // ClientPrint(null, 3, GetPropInt(ent, "m_bForcedSkin").tostring() + " " + "m_bForcedSkin") // ClientPrint(null, 3, GetPropInt(ent, "m_nForcedSkin").tostring() + " " + "m_nForcedSkin") // ClientPrint(null, 3, GetPropInt(ent, "m_iPlayerSkinOverride").tostring() + " " + "m_iPlayerSkinOverride") } catch (exception){ } // ... } } Hailstorm.ChangeAttributes <- function(name, delay = -1) { Hailstorm.Mode = (name.find("ice") != null || name.find("Ice") != null) ? 1 : 0 EntFire("pop_interface", "ChangeBotAttributes", name, delay, null) //EntFire("pop_interface", "RunScriptCode", "Hailstorm.SetPyroModel()", 0, null) //EntFire("pop_interface", "RunScriptCode", "Hailstorm.SetPyroModel()", 0.1, null) Hailstorm.SetPyroColour() //Hailstorm.SetPyroModel() // for (local child = entity.FirstMoveChild(); child != null; child = child.NextMovePeer()) { // ClientPrint(null, 3, child.tostring()) // } } Hailstorm.P1MixedAttacks <- [] Hailstorm.P1NumAttacks <- Hailstorm.P1MixedAttacks.len() // HAILSTORM ATTACKS Hailstorm.ErruptionAttackStraight <- function(radius, pt_maker, delay = 0.5, maxSplodes = 20, angCurve = 0, angOffset = 0) { local bot = Hailstorm.Boss if(!CzUtil.IsPlayerAlive(bot)) return local center = CzUtil.GetLocationBelow(bot) local forward = bot.EyeAngles().Forward() forward.z = 0 forward = CzUtil.RotateVector(forward, angOffset) forward.Norm() Hailstorm.ErruptionInDir(center, forward, radius, pt_maker, delay, maxSplodes, angCurve) // local backward = bot.EyeAngles().Forward() * -1 // backward.z = 0 // backward = CzUtil.RotateVector(backward, angOffset) // backward.Norm() // Hailstorm.ErruptionInDir(center, backward, radius, pt_maker, delay, maxSplodes, angCurve) } Hailstorm.ErruptionAttack <- function(radius, pt_maker, delay = 0.5, maxSplodes = 20, angCurve = 0, angOffset = 0) { local bot = Hailstorm.Boss if(!CzUtil.IsPlayerAlive(bot)) return //ClientPrint(null,3,"botpos " + bot.GetOrigin().tostring() + "; pt_maker " + pt_maker) local center = CzUtil.GetLocationBelow(bot) local forward = bot.EyeAngles().Forward() local left = bot.EyeAngles().Left() local backward = bot.EyeAngles().Forward() * -1 local right = bot.EyeAngles().Left() * -1 forward.z = 0 left.z = 0 backward.z = 0 right.z = 0 local dirs = [forward, left, backward, right] //local dirs = [forward,backward] foreach(dir in dirs) { dir = CzUtil.RotateVector(dir, angOffset) dir.Norm() Hailstorm.ErruptionInDir(center, dir, radius, pt_maker, delay, maxSplodes, angCurve) } } Hailstorm.ErruptionAttackTowardsPlayers <- function(radius, pt_maker, delay = 0.5, maxSplodes = 20, angCurve = 0) { local bot = Hailstorm.Boss if(!CzUtil.IsPlayerAlive(bot)) return local center = CzUtil.GetLocationBelow(bot) for (local player; player = Entities.FindByClassname(player, "player"); ) { if(player.GetTeam()!=2 || !CzUtil.IsPlayerLOSofMe(bot, player)) continue; local playerGround = CzUtil.GetLocationBelow(player) playerGround.z = center.z local dir = playerGround - center dir.Norm() Hailstorm.ErruptionInDir(center, dir, radius, pt_maker, delay, maxSplodes, angCurve) } } Hailstorm.ErruptionInDir <- function (center, dir, radius, pt_maker, delay, maxSplodes, angCurve) { local startPos = center + Vector(0,0,10) + dir*50 + dir*radius local i = 1 local curPos = startPos do { // first spawn the explosion pt at the curPos local asdf = rand().tostring() + i.tostring() local target = SpawnEntityFromTable("prop_dynamic", { targetname = asdf origin = curPos + Vector(0,0,-9) model = "models/empty.mdl" }) EntFire(pt_maker, "ForceSpawnAtEntityOrigin", asdf, i * delay, null) EntFireByHandle(target, "kill", "", i * delay + 10, null, null) // next find the next explosion spot dir = CzUtil.RotateVector(dir,angCurve) curPos = curPos + dir*radius*2 // if the next spot is in a wall/solid, spawn one last explosion pt and then break the loop if(CzUtil.IsInSolid(curPos)) { local asdf2 = rand().tostring() + i.tostring() local target2 = SpawnEntityFromTable("prop_dynamic", { targetname = asdf2 origin = curPos + Vector(0,0,-9) model = "models/empty.mdl" }) EntFire(pt_maker, "ForceSpawnAtEntityOrigin", asdf2, i * delay, null) EntFireByHandle(target2, "kill", "", i * delay + 10, null, null) break } i++ } while (i < maxSplodes) } Hailstorm.IgniteOilAtEnt <- function(target) { for(local entity; entity = Entities.FindByNameWithin(entity, "oilIgnite*", target.GetOrigin(), 15);) { EntFireByHandle(entity, "enable", "", 0, null, null) EntFireByHandle(entity, "start", "", 0, null, null) CzUtil.EmitFx(entity,"Fire.Engulf",0.5,0.5) } } Hailstorm.StraightBeamSetup <- function(target, startName, damage, piercePlayers = false, radius = 8, onHit = null, attacker = Hailstorm.Boss) { target.ValidateScriptScope() local scope = target.GetScriptScope() scope.start <- Entities.FindByName(null, startName) if(scope.start == null) return scope.beamDamage <- damage scope.attacker <- attacker scope.piercePlayers <- piercePlayers scope.onHit <- onHit AddThinkToEnt(target, "Hailstorm.BeamTargetThink") } Hailstorm.BeamTargetThink <- function() { local scope = target.GetScriptScope() local trace = { start = scope.start.GetOrigin() end = self.GetOrigin() hullmin = Vector(-radius,-radius,-radius) hullmax = Vector(radius,radius,radius) ignore = scope.attacker mask = 1107296257 } if(!scope.piercePlayers) { TraceHull(trace) if (m_trace.hit && m_trace.enthit == player){ local entity = m_trace.enthit if(!(entity.GetScriptScope().rawin("lastBeamDmg")) || Time() > entity.GetScriptScope().lastBeamDmg + 0.1) { entity.TakeDamageCustom(entity, scope.attacker,null, Vector(0,0,0), Vector(0,0,0), damage, 8, Constants.ETFDmgCustom.TF_DMG_CUSTOM_BURNING) entity.ApplyAbsVelocityImpulse(Vector(0,0,70)) entity.GetScriptScope().lastBeamDmg <- Time() if(onHit != null) onHit(entity) } } } else { trace.filter <- function(entity) { if (entity.GetClassname() == "base_boss") return TRACE_OK_CONTINUE; else if(entity.GetClassname() == "player") return TRACE_OK_CONTINUE; else if(entity.GetClassname().find("obj_")!= null) return TRACE_OK_CONTINUE; else return TRACE_CONTINUE; //return TRACE_STOP; } TraceHullGather(trace) } }