4ªUnutscripts/vscriptsextra_tank»Ç‡ÒÿÎ�#ÿÿdirector_base_addon¼”Lcÿ²ÿÿtxt addoninfo¶ÀÐÿ²ÿÿ// The addoninfo.txt file is a metadata file that is required by all Source Engine Add-ons. "AddonInfo" { addonSteamAppID 550 addontitle "Tank behavior" addonversion 1.0 addontagline "" addonauthor "" addonSteamGroupName "" addonauthorSteamID "" addonURL0 "" // short description that appears in the Add-on list screen... addonDescription "Featuring tank behavior states." addonContent_Script 1 }IncludeScript("extra_tank");IncludeScript("VSLib"); printl("==================="); printl("ULTRA TANK by smockey"); printl("==================="); ultratank <- { ConfigFolder = "ultra_tank_cfg", ConfigFileName = "settings.cfg", Config = { EnableUltraTank = 1, // 1 = Enable Ultra Tank health and rage mechanics, 0 = Disable // Base health caps per game mode CoopBaseTop = 10000, RealismBaseTop = 12000, DefaultHealth = 6000, // Difficulty scaling multipliers (used for coop and realism) MultImpossible = 1.0, MultHard = 0.85, MultNormal = 0.70, MultEasy = 0.50, // Friction settings based on health phases FrictionHealthy = 1.5, FrictionMedium = 1.4, FrictionHigh = 1.3, FrictionLethal = 1.25, // Retaliation damage values dealt by Tank to survivors on hit based on phase DamageBase = 12, DamageMedium = 32, DamageHigh = 52, DamageLethal = 1000 }, SaveConfig = function() { local dataString = format( "# ==========================================\n" + "# ULTRA TANK CONFIGURATION SETTINGS\n" + "# ==========================================\n" + "# EnableUltraTank: 1 = Active, 0 = Disabled\n" + "EnableUltraTank=%d\n\n" + "# Base health caps for game modes\n" + "CoopBaseTop=%d\n" + "RealismBaseTop=%d\n" + "DefaultHealth=%d\n\n" + "# Difficulty multipliers\n" + "MultImpossible=%.2f\n" + "MultHard=%.2f\n" + "MultNormal=%.2f\n" + "MultEasy=%.2f\n\n" + "# Tank friction per phase\n" + "FrictionHealthy=%.2f\n" + "FrictionMedium=%.2f\n" + "FrictionHigh=%.2f\n" + "FrictionLethal=%.2f\n\n" + "# Retaliation damage dealt to survivors\n" + "DamageBase=%d\n" + "DamageMedium=%d\n" + "DamageHigh=%d\n" + "DamageLethal=%d\n", this.Config.EnableUltraTank, this.Config.CoopBaseTop, this.Config.RealismBaseTop, this.Config.DefaultHealth, this.Config.MultImpossible, this.Config.MultHard, this.Config.MultNormal, this.Config.MultEasy, this.Config.FrictionHealthy, this.Config.FrictionMedium, this.Config.FrictionHigh, this.Config.FrictionLethal, this.Config.DamageBase, this.Config.DamageMedium, this.Config.DamageHigh, this.Config.DamageLethal ); local filePath = this.ConfigFolder + "/" + this.ConfigFileName; StringToFile(filePath, dataString); }, LoadConfig = function() { local filePath = this.ConfigFolder + "/" + this.ConfigFileName; local fileContent = FileToString(filePath); if (fileContent != null && fileContent != "") { local lines = split(fileContent, "\n"); foreach (line in lines) { if (line.len() > 0 && line.slice(0, 1) == "#") continue; local parts = split(line, "="); if (parts.len() == 2) { local key = parts[0]; local val = parts[1].tofloat(); if (key == "EnableUltraTank") { this.Config.EnableUltraTank = val.tointeger(); } else if (key == "CoopBaseTop") { this.Config.CoopBaseTop = val.tointeger(); } else if (key == "RealismBaseTop") { this.Config.RealismBaseTop = val.tointeger(); } else if (key == "DefaultHealth") { this.Config.DefaultHealth = val.tointeger(); } else if (key == "MultImpossible") { this.Config.MultImpossible = val; } else if (key == "MultHard") { this.Config.MultHard = val; } else if (key == "MultNormal") { this.Config.MultNormal = val; } else if (key == "MultEasy") { this.Config.MultEasy = val; } else if (key == "FrictionHealthy") { this.Config.FrictionHealthy = val; } else if (key == "FrictionMedium") { this.Config.FrictionMedium = val; } else if (key == "FrictionHigh") { this.Config.FrictionHigh = val; } else if (key == "FrictionLethal") { this.Config.FrictionLethal = val; } else if (key == "DamageBase") { this.Config.DamageBase = val.tointeger(); } else if (key == "DamageMedium") { this.Config.DamageMedium = val.tointeger(); } else if (key == "DamageHigh") { this.Config.DamageHigh = val.tointeger(); } else if (key == "DamageLethal") { this.Config.DamageLethal = val.tointeger(); } } } } else { this.SaveConfig(); } }, CalculateTankHealth = function() { local gameMode = Convars.GetStr("mp_gamemode").tolower(); local diff = Convars.GetStr("z_difficulty").tolower(); local health = this.Config.DefaultHealth; if (gameMode == "coop") { local baseTop = this.Config.CoopBaseTop; if (diff == "impossible") health = baseTop * this.Config.MultImpossible; else if (diff == "hard") health = baseTop * this.Config.MultHard; else if (diff == "normal") health = baseTop * this.Config.MultNormal; else if (diff == "easy") health = baseTop * this.Config.MultEasy; else health = baseTop * this.Config.MultImpossible; } else if (gameMode == "realism") { local baseTop = this.Config.RealismBaseTop; if (diff == "impossible") health = baseTop * this.Config.MultImpossible; else if (diff == "hard") health = baseTop * this.Config.MultHard; else if (diff == "normal") health = baseTop * this.Config.MultNormal; else if (diff == "easy") health = baseTop * this.Config.MultEasy; else health = baseTop * this.Config.MultImpossible; } else { health = this.Config.DefaultHealth; } return health.tointeger(); } }; // Cargar configuración al iniciar ultratank.LoadConfig(); // Asignar salud calculada a la variable global de ronda RoundVars.tank <- ultratank.CalculateTankHealth(); // TANK SPAWN SETTINGS function Notifications::OnSpawn::SpecialZambies (player, params) { if (!("ultratank" in DirectorScript)) return; local cfg = DirectorScript.ultratank.Config; if (cfg.EnableUltraTank == 0) return; if (player != null && player.GetTeam() == INFECTED) { if (player.GetPlayerType() == Z_TANK) { player.SetFriction(cfg.FrictionHealthy); player.SetMaxHealth(RoundVars.tank); player.SetRawHealth(RoundVars.tank); } } } // 1. CUANDO EL TANK RECIBE DAÑO: Solo actualizamos su fase y fricción según su vida actual function Notifications::OnHurt::TankPhaseCheck(victim, attacker, params) { if (!("ultratank" in DirectorScript)) return; local cfg = DirectorScript.ultratank.Config; if (cfg.EnableUltraTank == 0) return; if (victim != null && victim.IsPlayer() && victim.GetPlayerType() == Z_TANK && victim.GetTeam() == INFECTED) { local tank = victim; if (tank.GetMaxHealth() == RoundVars.tank) { local currentHealth = tank.GetHealth(); local t30 = RoundVars.tank * 0.30; local t20 = RoundVars.tank * 0.20; local t10 = RoundVars.tank * 0.10; if (currentHealth < t10) { tank.SetFriction(cfg.FrictionLethal); } else if (currentHealth < t20) { tank.SetFriction(cfg.FrictionHigh); } else if (currentHealth < t30) { tank.SetFriction(cfg.FrictionMedium); } else { tank.SetFriction(cfg.FrictionHealthy); } } } } // 2. CUANDO EL TANK GOLPEA AL SUPERVIVIENTE: Aplicamos el daño extra según la vida actual del Tank function Notifications::OnHurt::TankHitSurvivor(victim, attacker, params) { if (!("ultratank" in DirectorScript)) return; local cfg = DirectorScript.ultratank.Config; if (cfg.EnableUltraTank == 0) return; if (victim != null && attacker != null) { if (victim.IsPlayer() && victim.GetTeam() == SURVIVORS && attacker.IsPlayer() && attacker.GetPlayerType() == Z_TANK && attacker.GetTeam() == INFECTED) { local survivor = victim; local tank = attacker; if (tank.GetMaxHealth() == RoundVars.tank) { local currentHealth = tank.GetHealth(); local t30 = RoundVars.tank * 0.30; local t20 = RoundVars.tank * 0.20; local t10 = RoundVars.tank * 0.10; if (currentHealth < t10) { Timers.AddTimer(0.1, false, applyTankDamageLethal, survivor); } else if (currentHealth < t20) { Timers.AddTimer(0.1, false, applyTankDamageHigh, survivor); } else if (currentHealth < t30) { Timers.AddTimer(0.1, false, applyTankDamageMedium, survivor); } else { Timers.AddTimer(0.1, false, applyTankDamageBase, survivor); } } } } } // FUNCIONES AUXILIARES DE DAÑO EXTRA AL SUPERVIVIENTE ::applyTankDamageBase <- function(survivor) { if (!("ultratank" in DirectorScript)) return; local dmg = DirectorScript.ultratank.Config.DamageBase; if (survivor != null && survivor.IsAlive()) { survivor.Damage(dmg, 64); } } ::applyTankDamageMedium <- function(survivor) { if (!("ultratank" in DirectorScript)) return; local dmg = DirectorScript.ultratank.Config.DamageMedium; if (survivor != null && survivor.IsAlive()) { survivor.Damage(dmg, 64); } } ::applyTankDamageHigh <- function(survivor) { if (!("ultratank" in DirectorScript)) return; local dmg = DirectorScript.ultratank.Config.DamageHigh; if (survivor != null && survivor.IsAlive()) { survivor.Damage(dmg, 64); } } ::applyTankDamageLethal <- function(survivor) { if (!("ultratank" in DirectorScript)) return; local dmg = DirectorScript.ultratank.Config.DamageLethal; if (survivor != null) { survivor.Damage(dmg, 64); } }