print("Trainyard Remilia Vscript loaded") local sound = [ "Xiao_DragonUp_Start.wav", "Xiao_DragonUp_End.wav", "Xiao_LandHit_Charge.wav", "Xiao_LandHit_Hit.wav", "Xiao_Roar.wav", "Xiao_Stong_Hori.wav", "Xiao_Stong_Upper.wav", "Xiao_Vert.wav", ] try { for (local i = 0; i < sound.len(); i++) PrecacheScriptSound(sound[i]) } catch (exception) { } EmitSoundEx({ sound_name = sound[4] }) ::TAG <- { ref = "TAG" } ::BERSERK <- { ref = "BERSERK", TAG = "berserk", BOTS = [], berserk = class { b_CurrentHealth = 0.0; b_MaxHealth = 0.0; b_Entity = null; b_Class = null; b_Name = null; b_ThinkEvent = null; constructor(Entity) { b_Entity = Entity; b_CurrentHealth = Entity.GetMaxHealth().tofloat(); b_MaxHealth = Entity.GetMaxHealth().tofloat(); b_Class = Entity.GetClassname(); b_Name = Entity.GetName(); InitThinker(); } // This function not only set current health, it also change behaviour or change attributes lol // Don't ask me about my code organization function setCHealth(newHealth) { b_CurrentHealth = newHealth; local firerate = b_CurrentHealth/b_MaxHealth; // switch (b_Class) { // case "Soldier": local rl = NetProps.GetPropEntityArray(b_Entity, "m_hMyWeapons", 0); rl.RemoveAttribute("fire rate bonus") // if (firerate < 0.2) { // firerate = 0.2 // } rl.AddAttribute("fire rate bonus", firerate , -1) // break; // } } function toString() { return "\nBot Max health: " +b_MaxHealth + ", Bot Current Health: " + b_CurrentHealth; } function getEntity() { return b_Entity; } function getPos() { return b_Entity.GetOrigin(); } function InitThinker() { b_ThinkEvent = SpawnEntityFromTable("logic_relay", { targetname = "BerserkThinker" }) b_ThinkEvent.SetOwner(b_Entity) try b_ThinkEvent.ValidateScriptScope() catch (exception) print("\nCannot Validate!") local BotScope = b_ThinkEvent.GetScriptScope() BotScope["BerserkUpdate"] <- function() { local owner = self.GetOwner() // DispatchParticleEffect("dragons_fury_effect", owner.GetOrigin(), owner.GetAbsAngles() + Vector(0,0,0)) DispatchParticleEffect("powerup_supernova_explode_red_spiral", owner.GetOrigin(), owner.GetAbsAngles() + Vector(0,0,0)) EmitSoundEx({ sound_name = sound[4] }) for(local i = 0; i < ::PLAYER.PLAYERS.len(); i++) { local player = ::PLAYER.PLAYERS[i].getEntity(); player.IgnitePlayer() ::PLAYER.PLAYERS[i].getEntity().TakeDamageEx(owner, owner, null, owner.GetOrigin(), owner.GetOrigin(), (player.GetMaxHealth() * 0.3), 1) } return 5; } AddThinkToEnt(b_ThinkEvent, "BerserkUpdate") } function StopThinker() { AddThinkToEnt(b_ThinkEvent, null) b_ThinkEvent = null } } } ::PLAYER <- { ref = "PLAYER", PLAYERS = [], ThinkEvent = null, Player = class{ p_MaxHealth = 0; p_CurrentHealth = 0; p_Entity = null; p_DmgDealt = 0; p_DmgTaken = 0; p_ThinkEvent = null; // Emotion Level is for LoR mission p_EmotionLevel = 0; constructor(Entity) { p_Entity = Entity; p_MaxHealth = Entity.GetMaxHealth(); p_CurrentHealth = p_MaxHealth; initThinker(); } function updateCurrentHealth() { p_CurrentHealth = p_Entity.GetHealth(); } function updateMaxHealth(newMaxHealth) { p_MaxHealth = newMaxHealth; } function updateEmotionLevel(newEmo) { p_EmotionLevel = newEmo; } function updateDmgDealt(newDmgDealt) { p_DmgDealt = newDmgDealt; } function addDmgDealt(newDmgDealt) { p_DmgDealt += newDmgDealt; } function updateDmgTaken(newDmgTaken) { p_DmgTaken = newDmgTaken; } function addDmgTaken(incomingDmg) { print("\nIncoming Damage: "+incomingDmg); if (incomingDmg > p_CurrentHealth) { incomingDmg = (incomingDmg - (incomingDmg - p_CurrentHealth)); } print("\nincoming dmg: " + incomingDmg) updateCurrentHealth(); p_DmgTaken += incomingDmg; } function getDmgDealt() { return p_DmgDealt; } function getDmgTaken() { return p_DmgTaken; } function getMaxHealth() { return p_MaxHealth; } function getCurrentHealth() { return p_CurrentHealth; } // function p_Health_Percentage() { return (p_CurrentHealth / p_MaxHealth) * 100; } function getEmotionLevel() { return p_EmotionLevel; } function getEntity() { return p_Entity; } function p_Addcond(addcond) { p_Entity.addcond(); } function p_Decond() {} function initThinker() { p_ThinkEvent = SpawnEntityFromTable("logic_relay", { targetname = "BerserkThinker" }) p_ThinkEvent.SetOwner(p_Entity) try p_ThinkEvent.ValidateScriptScope() catch (exception) print("\nCannot Validate!") local BotScope = p_ThinkEvent.GetScriptScope() BotScope["PlayerUpdate"] <- function() { local owner = self.GetOwner() // DispatchParticleEffect("heavy_ring_of_fire", owner.GetOrigin(), owner.GetAngles()) return 0.001; } AddThinkToEnt(p_ThinkEvent, "PlayerUpdate") } }, // Update players current health respawn = function(Entity) { for (local i = 0; i < ::PLAYER.PLAYERS.len(); i++) { if (Entity = ::PLAYER.PLAYERS[i].getEntity()) { ::PLAYER.PLAYERS[i].updateCurrentHealth(); } } } } ::TAG.BotRegister <- function(tag, entity, botArray) { if ( !entity.HasBotTag(tag) ) return; if (botArray.len() != 0) { for (local i = 0; i < botArray.len(); i++) { if (botArray[i].getEntity() == entity) { return; } } } entity.ValidateScriptScope(); local EntityScope = entity.GetScriptScope(); switch (tag){ case "emotion": break; case "berserk": botArray.append(::BERSERK.berserk(entity)); print("\nBerserk") break; default: break; } print("\nBot with tag " + tag + " added into array, Current array length: " + botArray.len()) EntityScope[tag] <- true; print("" + botArray[0].toString()); print(typeof(botArray[0])); } ::TAG.PlayerRegister <- function(entity, playerArray) { for (local i = 0; i < playerArray.len(); i++) { if (entity == playerArray[i].getEntity()) return; } entity.ValidateScriptScope(); local EntityScope = entity.GetScriptScope(); playerArray.append(::PLAYER.Player(entity)); print("\nPlayer added into array"); } ::BERSERK.OnGameEvent_player_spawn <- function(params) { print("\nTrigger Player Spawn"); local client = GetPlayerFromUserID(params.userid); if (client.IsFakeClient()) { EntFireByHandle(client, "RunScriptCode", "::TAG.BotRegister(::BERSERK.TAG, self, ::BERSERK.BOTS)", 0.1, client, client) } } ::BERSERK.OnGameEvent_player_death <- function(params) { local client = GetPlayerFromUserID(params.userid); if (client.IsFakeClient()) { EntFireByHandle(client, "RunScriptCode", "::TAG.ClearTags(self, ::BERSERK.BOTS)", 0.1, client, client) } } ::PLAYER.OnGameEvent_player_spawn <- function(params) { local client = GetPlayerFromUserID(params.userid); if (!(client.IsFakeClient())) { EntFireByHandle(client, "RunScriptCode", "::TAG.PlayerRegister(self, ::PLAYER.PLAYERS)", 0.1, client, client) ::PLAYER.respawn(client); } } ::TAG.ClearTags <- function(Entity, BotArray) { for (local i = 0; i < BotArray.len(); i++) { if (BotArray[i].getEntity() == Entity) { BotArray[i].StopThinker() BotArray.remove(i) } } } function OnGameEvent_player_hurt(params) { print("\nTrigger Player Hurt"); local victim = GetPlayerFromUserID(params.userid); local attacker = GetPlayerFromUserID(params.attacker); if (victim.IsFakeClient()){ print("\nVictim is bot") for (local i = 0; i < ::BERSERK.BOTS.len(); i++) { if (::BERSERK.BOTS[i].getEntity() == victim) { ::BERSERK.BOTS[i].setCHealth(victim.GetHealth().tofloat()); } } } else { print("\nVictim is player") for (local i = 0; i < ::PLAYER.PLAYERS.len(); i++) { if (::PLAYER.PLAYERS[i].getEntity() == victim) { ::PLAYER.PLAYERS[i].addDmgTaken(params.damageamount); print("\nPlayer current health: " + ::PLAYER.PLAYERS[i].getCurrentHealth()); print("\nPlayer total dmg taken: " + ::PLAYER.PLAYERS[i].getDmgTaken()); } } } } function Init() { local obj = Entities.FindByClassname(null, "tf_objective_resource") local popname = NetProps.GetPropString(obj, "m_iszMvMPopfileName") try { local popname_split = popname.slice(popname.find("adv_") || popname.find("int_")) print("\n"+popname_split) } catch (exception) { print("\nthis mission has no adv_ or int_") } __CollectGameEventCallbacks(this); __CollectGameEventCallbacks(::BERSERK); } function PlayerInit() { // ::PLAYER.ThinkEvent = SpawnEntityFromTable("logic_relay", { // targetname = "PlayerThinker" // }) // ::PLAYER.ThinkEvent.ValidateScriptScope(); // local PlayerScope = ::PLAYER.ThinkEvent.GetScriptScope(); // PlayerScope["ThinkerEvent"] <- function() { // // for (local i = 0; i < ::PLAYER.PLAYERS.len(); i++) { // // print("\nAdd") // // local maxHealth = ::PLAYER.PLAYERS[0].getEntity().GetMaxHealth() // // maxHealth++; // // print(maxHealth) // // ::PLAYER.PLAYERS[0].getEntity().SetMaxHealth(maxHealth); // // } // return 1; // } // AddThinkToEnt(::PLAYER.ThinkEvent, "ThinkerEvent") __CollectGameEventCallbacks(::PLAYER); } function wave_start_relay_custom() { EntFire("wave_start_relay", "Trigger") EntFire("train_timer", "AddOutput", "LowerRandomBound 0.5") EntFire("train_timer", "AddOutput", "UpperRandomBound 0.5") } function TrainMadness() { } Init(); PlayerInit();