diff --git a/scripting/DelayConfigExec.sp b/scripting/DelayConfigExec.sp new file mode 100644 index 0000000..c6fb535 --- /dev/null +++ b/scripting/DelayConfigExec.sp @@ -0,0 +1,28 @@ +//Simple script setup +#pragma semicolon 1 +#include +#include +#include +#define DLYCFG_VERSION "1.0.0" + +//Give plugin info +public Plugin:myinfo = +{ + name = "Config Delayer", + author = "Tonybear5", + description = "Waits for server load then fires after a 60 second delay.", + version = "DLYCFG_VERSION", + url = "http://veterangiveaways.co.uk" +}; + +//Hook into server +public OnAllPluginsLoaded() +{ + CreateTimer(60.0, Command_FireConfig); +} + +//Execute the config after the above delay +public Action:Command_FireConfig(Handle timer) +{ + ServerCommand("exec server.cfg"); +} \ No newline at end of file diff --git a/scripting/FallingBack-Legacy.sp b/scripting/FallingBack-Legacy.sp new file mode 100644 index 0000000..560bb27 --- /dev/null +++ b/scripting/FallingBack-Legacy.sp @@ -0,0 +1,2021 @@ +#include +#include +#pragma newdecls required +#pragma semicolon 1 +bool canHWBoss = false; +bool canTornado = false; +bool canSENTMeteors = false; +bool canSENTNukes = false; +bool canSENTStars = false; +bool isWave = false; +bool tornado = false; +bool bgmlock1 = true; +bool bgmlock2 = true; +bool bgmlock3 = true; +bool bgmlock4 = true; +bool bgmlock5 = true; +bool bgmlock6 = true; +bool bgmlock7 = true; +bool bgmlock8 = true; +char BELL[32] = "fartsy/misc/bell.wav"; +char CLOCKTICK[32] = "fartsy/misc/clock_tick.wav"; +char COUNTDOWN[32] = "fartsy/misc/countdown.wav"; +char STRONGMAN[32] = "fartsy/misc/strongman_bell.wav"; +char BGM1[64] = "fartsy/ffxiv/bgm/locus.mp3"; +char BGM2[64] = "fartsy/ffxiv/bgm/metal.mp3"; +char BGM3[64] = "fartsy/ffxiv/bgm/exponentialentropy.mp3"; +char BGM4[64] = "fartsy/ffxiv/bgm/tornfromtheheavens.mp3"; +char BGM5[64] = "fartsy/ffxiv/bgm/metalbrutejusticemode.mp3"; +char BGM6[64] = "fartsy/ffxiv/bgm/grandmadestruction.mp3"; +char BGM7[64] = "fartsy/ffxiv/bgm/revengetwofold.mp3"; +char BGM8[64] = "fartsy/ffxiv/bgm/undertheweight.mp3"; +int SNDCHAN = 6; +char BGM1Title[64] = "FFXIV - Locus"; +char BGM2Title[64] = "FFXIV - Metal"; +char BGM3Title[64] = "FFXIV - Exponential Entropy"; +char BGM4Title[64] = "FFXIV - Torn From the Heavens"; +char BGM5Title[64] = "FFXIV - Metal: Brute Justice Mode"; +char BGM6Title[64] = "FFXIV - Grandma (Destruction)"; +char BGM7Title[64] = "FFXIV - Revenge Twofold"; +char BGM8Title[64] = "FFXIV - Under the Weight"; +char DEFAULTBGM1[64] = "fartsy/ffxiv/bgm/TheSilentRegardOfStars.mp3"; +char DEFAULTBGM2[64] = "fartsy/ffxiv/bgm/KnowledgeNeverSleeps.mp3"; +char DEFAULTBGM1Title[64] = "FFXIV - The Silent Regard of Stars"; +char DEFAULTBGM2Title[64] = "FFXIV - Knowledge Never Sleeps"; +char curSong[64] = "null"; +char FALLSND01[32] = "vo/l4d2/billfall02.mp3"; +char FALLSND02[32] = "vo/l4d2/coachfall02.mp3"; +char FALLSND03[32] = "vo/l4d2/ellisfall01.mp3"; +char FALLSND04[32] = "vo/l4d2/francisfall02.mp3"; +char FALLSND05[32] = "vo/l4d2/louisfall01.mp3"; +char FALLSND06[32] = "vo/l4d2/louisfall03.mp3"; +char FALLSND07[32] = "vo/l4d2/nickfall01.mp3"; +char FALLSND08[32] = "vo/l4d2/zoeyfall01.mp3"; +char FALLSND09[32] = "vo/ddd/woahhh.mp3"; +char FALLSND0A[32] = "vo/jigglypuff/jigglypuff.mp3"; +char FALLSND0B[32] = "vo/kirby/eeeahhhh.mp3"; +char FALLSND0C[32] = "vo/luigi/ohohohohoo.mp3"; +char FALLSND0D[32] = "vo/mario/wahahahaha.mp3"; +char FALLSND0E[32] = "vo/pika/pikapika.mp3"; +char FALLSND0F[32] = "vo/wario/wheee.mp3"; +char FALLSND10[32] = "vo/mario/wowww.mp3"; +char GLOBALTHUNDER01[32] = "fartsy/weather/thunder1.wav"; +char GLOBALTHUNDER02[32] = "fartsy/weather/thunder2.wav"; +char GLOBALTHUNDER03[32] = "fartsy/weather/thunder3.wav"; +char GLOBALTHUNDER04[32] = "fartsy/weather/thunder4.wav"; +char GLOBALTHUNDER05[32] = "fartsy/weather/thunder5.wav"; +char GLOBALTHUNDER06[32] = "fartsy/weather/thunder6.wav"; +char GLOBALTHUNDER07[32] = "fartsy/weather/thunder7.wav"; +char GLOBALTHUNDER08[32] = "fartsy/weather/thunder8.wav"; +char TRIGGERSCORE[32] = "fartsy/misc/triggerscore.wav"; +int BGMSNDLVL = 90; +int DEFBGMSNDLVL = 40; +int bombStatus = 0; +int bombStatusMax = 0; +int bombsPushed = 0; +int bombCache = 0; +int sacPoints = 0; +int sacPointsMax = 60; +int explodeType = 0; +float HWNMin = 210.0; +float HWNMax = 380.0; +public Plugin myinfo = +{ + name = "Dovah's Ass - Framework", + author = "Fartsy#0001", + description = "Framework for Dovah's Ass", + version = "2.4.0", + url = "https://forums.firehostredux.com" +}; + +public void OnPluginStart() +{ + PrecacheSound(BELL, true), + PrecacheSound(BGM1, true), + PrecacheSound(BGM2, true), + PrecacheSound(BGM3, true), + PrecacheSound(BGM4, true), + PrecacheSound(BGM5, true), + PrecacheSound(BGM6, true), + PrecacheSound(BGM7, true), + PrecacheSound(BGM8, true), + PrecacheSound(CLOCKTICK, true), + PrecacheSound(COUNTDOWN, true), + PrecacheSound(DEFAULTBGM1, true), + PrecacheSound(DEFAULTBGM2, true), + PrecacheSound(FALLSND01, true), + PrecacheSound(FALLSND02, true), + PrecacheSound(FALLSND03, true), + PrecacheSound(FALLSND04, true), + PrecacheSound(FALLSND05, true), + PrecacheSound(FALLSND06, true), + PrecacheSound(FALLSND07, true), + PrecacheSound(FALLSND08, true), + PrecacheSound(FALLSND09, true), + PrecacheSound(FALLSND0A, true), + PrecacheSound(FALLSND0B, true), + PrecacheSound(FALLSND0C, true), + PrecacheSound(FALLSND0D, true), + PrecacheSound(FALLSND0E, true), + PrecacheSound(FALLSND0F, true), + PrecacheSound(FALLSND10, true), + PrecacheSound(GLOBALTHUNDER01, true), + PrecacheSound(GLOBALTHUNDER02, true), + PrecacheSound(GLOBALTHUNDER03, true), + PrecacheSound(GLOBALTHUNDER04, true), + PrecacheSound(GLOBALTHUNDER05, true), + PrecacheSound(GLOBALTHUNDER06, true), + PrecacheSound(GLOBALTHUNDER07, true), + PrecacheSound(GLOBALTHUNDER08, true), + PrecacheSound(STRONGMAN, true), + PrecacheSound(TRIGGERSCORE, true), + RegServerCmd("fb_forcevictory", Command_ForceVictory, "FORCE victory - DO NOT TOUCH, WILL LIKELY MESS STUFF UP."), + RegServerCmd("fb_trainincoming", Command_TrainIncoming, "A train is incoming!"), + RegServerCmd("fb_atomicbmbrain", Command_AtomBmbRain, "Atom bombs are now raining from the sky!"), + RegServerCmd("fb_ohnoes", Command_OhNoes, "Oh noes, prepare your anus!"), + RegServerCmd("fb_meteorincoming", Command_MeteorIncoming, "Meteor incoming!"), + RegServerCmd("fb_meteorshower", Command_MeteorShower, "Meteor Shower incoming!"), + RegServerCmd("fb_prepareyourself", Command_DovahsAss, "You have chosen Dovah's Ass, prepare yourself..."), + RegServerCmd("fb_wave1", Command_WaveOne, "Wave one started."), + RegServerCmd("fb_wave2", Command_WaveTwo, "Wave two started."), + RegServerCmd("fb_wave3", Command_WaveThree, "Wave three started."), + RegServerCmd("fb_wave4", Command_WaveFour, "Wave four started."), + RegServerCmd("fb_wave5", Command_WaveFive, "Wave five started."), + RegServerCmd("fb_wave6", Command_WaveSix, "Wave six started."), + RegServerCmd("fb_wave7", Command_WaveSeven, "Wave seven started."), + RegServerCmd("fb_hydrogenup", Command_HydrogenUp, "Hydrogen available."), + RegServerCmd("fb_wave8", Command_WaveEight, "Wave eight started."), + RegServerCmd("fb_burgup", Command_WaveSevenBurgUp, "Wave seven - burg up!"), + RegServerCmd("fb_foundgoob", Command_FoundGoob, "ALL HAIL GOOBBUE!"), + RegServerCmd("fb_foundwaffle", Command_FoundWaffle, "Why do they call it the waffle of mass destruction if it does nothing!?"), + RegServerCmd("fb_foundburrito", Command_FoundBurrito, "Forbidden Burrito. Yum."), + RegServerCmd("fb_foundshroom", Command_FoundShroom, "What does this even do!?"), + RegServerCmd("fb_foundball", Command_FoundBall, "Incoming blue ball..."), + RegServerCmd("fb_tsplus1", Command_TSPlus1, "Tornado sacrifice -- plus one!"), + RegServerCmd("fb_dpsacplus1", Command_DPSacPlus1, "Death pit sacrifice -- plus one!"), + RegServerCmd("fb_ksacplus1", Command_KissoneSacPlus1, "KissoneTM sacrifice -- plus one!"), + RegServerCmd("fb_tankdest", Command_TankDestPlus1, "Tank destroyed! Plus one!"); + RegServerCmd("fb_bresplus5", Command_BombResPlus5, "Bomb reset -- plus five!"), + RegServerCmd("fb_sbathsalts", Command_BathSaltsSacMinus10, "Bath salts, minus ten!"), + RegServerCmd("fb_sfatman", Command_FatManSacMinus20, "Fat man, minus twenty!"), + RegServerCmd("fb_sgoobbue", Command_GoobbueSacMinus30, "Goobbue, minus thirty!"), + RegServerCmd("fb_skirb", Command_BlueBallSacMinus30, "Blue ball, minus thirty!"), + RegServerCmd("fb_sgboom", Command_GBoomSacMinus40, "Explosive paradise, minus fourty!"), + RegServerCmd("fb_assgas", Command_AssGasMinus40, "Ass gas, minus fourty!"), + RegServerCmd("fb_skirbward", Command_KirbyWardSacMinus50, "KIRBY HAS BANISHED TORNADOES!"), + RegServerCmd("fb_snfo", Command_NFOSacMinus60, "Atomic bomb rain, minus sixty!"), + RegServerCmd("fb_smeteors", Command_MeteorsSacMinus70, "Meteors, minus seventy!"), + RegServerCmd("fb_sdovah", Command_DovahSacMinus100, "Professor Fartsalot, minus one hundred!"), + RegServerCmd("fb_prevwave", Command_JumpToPrevWave, "Jump to previous wave."), + RegServerCmd("fb_nextwave", Command_JumpToNextWave, "Jump to next wave."), + RegServerCmd("fb_bombpushplus5", Command_BombPushPlusFive, "Bomb pushed - plus five!"), + RegServerCmd("dovahsass_finished", Command_DovahsAssFinished, "DovahsAss has been completed!"), + RegServerCmd("fb_tacobell", Command_TacoBell, "Just why?"), + RegServerCmd("tacobell_wave01", Command_TBWave01,"Taco Bell - Wave One"), + RegServerCmd("tacobell_wave02", Command_TBWave02,"Taco Bell - Wave Two"), + RegServerCmd("tacobell_wave03", Command_TBWave03,"Taco Bell - Wave Three"), + RegServerCmd("tacobell_wave04", Command_TBWave04,"Taco Bell - Wave Four"), + RegServerCmd("tacobell_wave05", Command_TBWave05,"Taco Bell - Wave Five"), + RegServerCmd("tacobell_wave06", Command_TBWave06,"Taco Bell - Wave Six"), + RegServerCmd("tacobell_wave07", Command_TBWave07,"Taco Bell - Wave Seven"), + RegServerCmd("tacobell_wave08", Command_TBWave08,"Taco Bell - Wave Eight"), + RegServerCmd("tacobell_wave09", Command_TBWave09,"Taco Bell - Wave Nine"), + RegServerCmd("tacobell_wave10", Command_TBWave10,"Taco Bell - Wave Ten"), + RegServerCmd("tacobell_wave11", Command_TBWave11,"Taco Bell - Wave Eleven"), + RegServerCmd("tacobell_wave12", Command_TBWave12,"Taco Bell - Wave Twelve"), + RegServerCmd("tacobell_wave13", Command_TBWave13,"Taco Bell - Wave Thirteen"), + RegServerCmd("tacobell_wave14", Command_TBWave14,"Taco Bell - Wave Fourteen"), + RegServerCmd("tacobell_wave15", Command_TBWave15,"Taco Bell - Wave Fifteen"), + RegServerCmd("tacobell_wave16", Command_TBWave16,"Taco Bell - Wave Sixteen"), + RegServerCmd("tacobell_wave17", Command_TBWave17,"Taco Bell - Wave Seventeen"), + RegServerCmd("tacobell_wave18", Command_TBWave18,"Taco Bell - Wave Eighteen"), + RegServerCmd("tacobell_wave19", Command_TBWave19,"Taco Bell - Wave Nineteen"), + RegServerCmd("tacobell_wave20", Command_TBWave20,"Taco Bell - Wave Twenty"), + RegServerCmd("tacobell_wave21", Command_TBWave21,"Taco Bell - Wave Twenty-One"), + RegServerCmd("tacobell_finished", Command_TacoBellFinished, "TacoBell has been completed!"), + RegServerCmd("fb_fire", Command_FBFire, "Operator for Professor's Ass."), + RegConsoleCmd("sm_bombstatus", Command_FBBombStatus, "Check bomb status"), + RegConsoleCmd("sm_sacstatus", Command_FBSacStatus, "Check sacrifice points status"), + RegServerCmd("fb_forcetornado", Command_ForceTornado, "Force Tornado"), + RegServerCmd("fb_deploy", Command_Deploy, "Deploy an active bomb - do not touch, will break something."), + RegConsoleCmd("sm_song", Command_GetCurrentSong, "Get current song name"), + HookEvent("player_death", EventDeath), + HookEvent("server_cvar", Event_Cvar, EventHookMode_Pre), + HookEvent("mvm_wave_complete", EventWaveComplete), + HookEvent("mvm_wave_failed", EventWaveFailed), + HookEvent("mvm_bomb_alarm_triggered", EventWarning), + HookEvent("mvm_bomb_reset_by_player", EventReset); +} +//public Action FireEntityInput(char[] strTargetname, char[] strInput, char[] strParameter, float flDelay) +//Now that command definitions are done, lets make some things happen. +public void OnMapStart() +{ + FireEntityInput("SNDSCPE_*", "disable", "", 0.0), + FireEntityInput("BombStatus", "disable", "", 0.0), + SelectBGM(); +} + +//Custom definitions +public Action EndWaveBGM(){ + ServerCommand("fb_fire Music.Locus StopSound; fb_fire Music.Metal StopSound; fb_fire Music.ExponentialEntropy StopSound; fb_fire Music.TornFromTheHeavens StopSound; fb_fire Music.MetalBruteJusticeMode StopSound; fb_fire Music.GrandmaDestruction StopSound; fb_fire Music.RevengeTwofold StopSound; fb_fire Music.UnderTheWeight StopSound"); +} + +public Action SelectBGM() +{ + //ServerCommand("fb_fire Music.* StopSound"); //Legacy method of stopping sound + StopCurSong(); + int BGM = GetRandomInt(1, 2); + switch(BGM){ + case 1:{ + //ServerCommand("fb_fire Music.TheSilentRegardOfStars PlaySound"); //Legacy method of playing sound + EmitSoundToAll(DEFAULTBGM1, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = DEFAULTBGM1; + PrintToServer("Creating timer for The Silent Regard of Stars. Enjoy the music!"); + CreateTimer(137.75, RefireBGM); + } + case 2:{ + //ServerCommand("fb_fire Music.KnowledgeNeverSleeps PlaySound"); //Legacy method of playing sound + EmitSoundToAll(DEFAULTBGM2, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = DEFAULTBGM2; + PrintToServer("Creating timer for Knowledge Never Sleeps. Enjoy the music!"); + CreateTimer(235.5, RefireBGMAlt); + } + } +} + +public Action StopCurSong(){ + for(int i=1;i<=MaxClients;i++) + { + StopSound(i, SNDCHAN, curSong); + } + return Plugin_Handled; +} + +//Timers + +//BGM (Defaults) +public Action RefireBGM(Handle timer) +{ + if (!isWave){ + SelectBGM(); + return Plugin_Stop; + } + return Plugin_Stop; +} +//BGM Default2 +public Action RefireBGMAlt(Handle timer) +{ + if (!isWave){ + SelectBGM(); + return Plugin_Stop; + } + return Plugin_Stop; +} + +//BGM (Locus) +public Action RefireLocus(Handle timer) +{ + if (!bgmlock1){ + //ServerCommand("fb_fire Music.Locus StopSound; fb_fire Music.Locus PlaySound"); //Legacy method of playing Locus + StopCurSong(); + EmitSoundToAll(BGM1, _, SNDCHAN, DEFBGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM1; + CreateTimer(229.25, RefireLocus); + } + return Plugin_Stop; +} + +//BGM (Metal) +public Action RefireMetal(Handle timer) +{ + if (!bgmlock2){ + //ServerCommand("fb_fire Music.Metal StopSound; fb_fire Music.Metal PlaySound"); //Legacy method of playing Metal + StopCurSong(); + EmitSoundToAll(BGM2, _, SNDCHAN, DEFBGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM2; + CreateTimer(153.95, RefireMetal); + } + return Plugin_Stop; +} + +//BGM (Exponential Entropy) +public Action RefireEntropy(Handle timer) +{ + if (!bgmlock3){ + //ServerCommand("fb_fire Music.ExponentialEntropy StopSound; fb_fire Music.ExponentialEntropy PlaySound"); //Legacy method of playing Metal + StopCurSong(); + EmitSoundToAll(BGM3, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM3; + CreateTimer(166.85, RefireEntropy); + } + return Plugin_Stop; +} + +//BGM (Torn From the Heavens) +public Action RefireTorn(Handle timer) +{ + if (!bgmlock4){ + //ServerCommand("fb_fire Music.TornFromTheHeavens StopSound; fb_fire Music.TornFromTheHeavens PlaySound"); //Legacy method of playing Torn From the Heavens + StopCurSong(); + EmitSoundToAll(BGM4, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM4; + CreateTimer(122.25, RefireTorn); + } + return Plugin_Stop; +} + +//BGM (Brute Justice Mode) +public Action RefireBJMode(Handle timer) +{ + if (!bgmlock5){ + //ServerCommand("fb_fire Music.MetalBruteJusticeMode StopSound; fb_fire Music.MetalBruteJusticeMode PlaySound"); //Legacy method of playing Brute Justice Mode + StopCurSong(); + EmitSoundToAll(BGM5, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM5; + CreateTimer(131.75, RefireBJMode); + } + return Plugin_Stop; +} + +//BGM (Grandma Destruction) +public Action RefireGrandma(Handle timer) +{ + if (!bgmlock6){ + //ServerCommand("fb_fire Music.GrandmaDestruction StopSound; fb_fire Music.GrandmaDestruction PlaySound"); //Legacy method of playing Grandma + StopCurSong(); + EmitSoundToAll(BGM6, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM6; + CreateTimer(323.95, RefireGrandma); + } + return Plugin_Stop; +} + +//BGM (Revenge Twofold) +public Action RefireRevenge2F(Handle timer){ + if (!bgmlock7){ + //ServerCommand("fb_fire Music.RevengeTwofold StopSound; fb_fire Music.RevengeTwofold PlaySound"); //Legacy method of playing Revenge Twofold + StopCurSong(); + EmitSoundToAll(BGM7, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM7; + CreateTimer(133.25, RefireRevenge2F); + } + return Plugin_Stop; +} + +//BGM (Under The Weight) +public Action RefireUnderTW(Handle timer){ + if (!bgmlock8){ + //ServerCommand("fb_fire Music.UnderTheWeight StopSound; fb_fire Music.UnderTheWeight PlaySound"); //Legacy method of playing Under The Weight + StopCurSong(); + EmitSoundToAll(BGM8, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM8; + CreateTimer(313.85, RefireUnderTW); + } + return Plugin_Stop; +} + +//Storm +public Action RefireStorm(Handle timer){ + if (isWave){ + float f = GetRandomFloat(7.0, 17.0); + CreateTimer(f, RefireStorm); + ServerCommand("fb_fire lightning TurnOn; fb_fire weather Skin 4; fb_fire value TurnOff; fb_fire LightningLaser TurnOn"); + ServerCommand("fb_fire lightning TurnOff 0 0.1; fb_fire weather Skin 3 0.1; fb_fire LightningLaser TurnOff 0 0.1"); + ServerCommand("fb_fire lightning TurnOn 0 0.17; fb_fire weather Skin 4 0.17; fb_fire LightningLaser TurnOn 0 0.17"); + ServerCommand("fb_fire lightning TurnOff 0 0.25; fb_fire weather Skin 3 0.25; fb_fire LightningLaser TurnOff 0 0.25"); + int Thunder = GetRandomInt(1, 16); + switch (Thunder){ + case 1:{ + EmitSoundToAll(GLOBALTHUNDER01); + ServerCommand("fb_fire LightningHurt00 Enable; fb_fire LightningHurt00 Disable 0 0.07"); + } + case 2:{ + EmitSoundToAll(GLOBALTHUNDER02); + ServerCommand("fb_fire LightningHurt01 Enable; fb_fire LightningHurt01 Disable 0 0.07"); + } + case 3:{ + EmitSoundToAll(GLOBALTHUNDER03); + ServerCommand("fb_fire LightningHurt02 Enable; fb_fire LightningHurt02 Disable 0 0.07"); + } + case 4:{ + EmitSoundToAll(GLOBALTHUNDER04); + ServerCommand("fb_fire LightningHurt03 Enable; fb_fire LightningHurt03 Disable 0 0.07"); + } + case 5:{ + EmitSoundToAll(GLOBALTHUNDER05); + ServerCommand("fb_fire LightningHurt04 Enable; fb_fire LightningHurt04 Disable 0 0.07"); + } + case 6:{ + EmitSoundToAll(GLOBALTHUNDER06); + ServerCommand("fb_fire LightningHurt05 Enable; fb_fire LightningHurt05 Disable 0 0.07"); + } + case 7:{ + EmitSoundToAll(GLOBALTHUNDER07); + ServerCommand("fb_fire LightningHurt06 Enable; fb_fire LightningHurt06 Disable 0 0.07"); + } + case 8:{ + EmitSoundToAll(GLOBALTHUNDER08); + ServerCommand("fb_fire LightningHurt07 Enable; fb_fire LightningHurt07 Disable 0 0.07"); + } + case 9:{ + EmitSoundToAll(GLOBALTHUNDER01); + ServerCommand("fb_fire LightningHurt08 Enable; fb_fire LightningHurt08 Disable 0 0.07"); + } + case 10:{ + EmitSoundToAll(GLOBALTHUNDER02); + ServerCommand("fb_fire LightningHurt09 Enable; fb_fire LightningHurt09 Disable 0 0.07"); + } + case 11:{ + EmitSoundToAll(GLOBALTHUNDER03); + ServerCommand("fb_fire LightningHurt0A Enable; fb_fire LightningHurt0A Disable 0 0.07"); + } + case 12:{ + EmitSoundToAll(GLOBALTHUNDER04); + ServerCommand("fb_fire LightningHurt0B Enable; fb_fire LightningHurt0B Disable 0 0.07"); + } + case 13:{ + EmitSoundToAll(GLOBALTHUNDER05); + ServerCommand("fb_fire LightningHurt0C Enable; fb_fire LightningHurt0C Disable 0 0.07"); + } + case 14:{ + EmitSoundToAll(GLOBALTHUNDER06); + ServerCommand("fb_fire LightningHurt0D Enable; fb_fire LightningHurt0D Disable 0 0.07"); + } + case 15:{ + EmitSoundToAll(GLOBALTHUNDER07); + ServerCommand("fb_fire LightningHurt0E Enable; fb_fire LightningHurt0E Disable 0 0.07"); + } + case 16:{ + EmitSoundToAll(GLOBALTHUNDER08); + ServerCommand("fb_fire LightningHurt0F Enable; fb_fire LightningHurt0F Disable 0 0.07"); + } + } + } +} +//Allow Tornadoes to Spawn +public Action ActivateTornadoTimer(){ + if (isWave && canTornado){ + float f = GetRandomFloat(210.0, 500.0); + CreateTimer(f, SpawnTornado); + } + return Plugin_Stop; +} +//Spawn the tornado. +public Action SpawnTornado(Handle timer){ + if (isWave && canTornado && !tornado){ + ServerCommand("fb_fire TornadoKill Enable; fb_fire tornadobutton Lock; fb_fire tornadof1 start 0 20; fb_fire shaketriggerf1 Enable 0 20; fb_fire tornadowindf1 PlaySound 0 20; fb_fire tornadof1wind Enable 0 21.50"); + tornado = true; + float f = GetRandomFloat(60.0, 120.0); + CreateTimer(f, DespawnTornado); + } + return Plugin_Stop; +} +//After a predetermined time, despawn the tornado. +public Action DespawnTornado(Handle timer){ + KillTornado(); +} +//Despawns the tornado. +public Action KillTornado(){ + if (tornado){ + ServerCommand("fb_fire tornadof1 stop; fb_fire TornadoKill Disable; fb_fire tornadof1wind Disable; fb_fire tornadowindf1 StopSound; fb_fire shaketriggerf1 Disable; fb_fire tornadobutton Unlock 0 20"); + tornado = false; + } + return Plugin_Handled; +} +//FB UnlockTimer (Unlocks FC Code Entry +public Action UnlockTimer (Handle timer){ + if(isWave){ + ServerCommand("fb_fire FB.KP* Unlock"); + EmitSoundToAll(BELL); + } + return Plugin_Stop; +} +//BombStatus (Add points to Bomb Status occasionally) +public Action BombStatusTimer(Handle timer){ + if (isWave && (bombStatus < bombStatusMax)){ + bombStatus++; + float f = GetRandomFloat(10.0, 45.0); + PrintToServer("[DEBUG] Creating a %f timer to give bomb status an update. Current target is %i", f, bombStatus); + CreateTimer(f, BombStatusTimer); + switch (bombStatus){ //new bombstatus parser + case 8:{ + bombStatusMax = 8; + bombCache = 0; + //removed fb_fire BombExploSmall Enable; + explodeType = 1; + ServerCommand("fb_fire Bombs.* Disable; fb_fire BombExplo* Disable; fb_fire Delivery Unlock; fb_fire Bombs.FreedomBomb Enable"); + EmitSoundToAll(TRIGGERSCORE); + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team's \x07FF0000FREEDOM BOMB \x0700AA55is now available for deployment!"); + } + case 16:{ + bombStatusMax = 16; + bombCache = 0; + //removed fb_fire BombExploMedium Enable; + explodeType = 2; + ServerCommand("fb_fire Bombs.* Disable; fb_fire BombExplo* Disable; fb_fire Delivery Unlock; fb_fire Bombs.ElonBust Enable"); + EmitSoundToAll(TRIGGERSCORE); + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team's \x07FF0000ELON BUST \x0700AA55is now available for deployment!"); + } + case 24:{ + bombStatusMax = 24; + bombCache = 0; + //removed fb_fire BombExploMedium Enable; + explodeType = 2; + ServerCommand("fb_fire Bombs.* Disable; fb_fire BombExplo* Disable; fb_fire Delivery Unlock; fb_fire Bombs.BathSalts Enable"); + EmitSoundToAll(TRIGGERSCORE); + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team's \x07FF0000BATH SALTS \x0700AA55are now available for deployment!"); + } + case 32:{ + bombStatusMax = 32; + bombCache = 0; + //removed ; fb_fire BombExploFallingStar Enable + explodeType = 3; + ServerCommand("fb_fire Bombs.* Disable; fb_fire BombExplo* Disable; fb_fire Delivery Unlock; fb_fire Bombs.FallingStar Enable"); + EmitSoundToAll(TRIGGERSCORE); + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team's \x07FFFF00FALLING STAR\x0700AA55 is now available for deployment!"); + } + case 40:{ + bombStatusMax = 40; + bombCache = 0; + //removed ; fb_fire BombExploMajorKong Enable + explodeType = 4; + ServerCommand("fb_fire Bombs.* Disable; fb_fire BombExplo* Disable; fb_fire Delivery Unlock; fb_fire Bombs.MajorKong Enable"); + EmitSoundToAll(TRIGGERSCORE); + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team's \x07FF0000MAJOR KONG \x0700AA55is now available for deployment!"); + } + case 48:{ + bombStatusMax = 48; + bombCache = 0; + explodeType = 5; + //removed fb_fire BombExploLarge Enable; + ServerCommand("fb_fire Bombs.* Disable; fb_fire BombExplo* Disable; fb_fire Delivery Unlock; fb_fire Bombs.SharkTorpedo Enable; fb_fire BombExploShark Enable"); + EmitSoundToAll(TRIGGERSCORE); + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team's \x07FF0000SHARK \x0700AA55is now available for deployment!"); + } + case 56:{ + bombStatusMax = 56; + bombCache = 0; + //removed ; fb_fire BombExploFatMan Enable + explodeType = 6; + ServerCommand("fb_fire Bombs.* Disable; fb_fire BombExplo* Disable; fb_fire Bombs.FatMan Enable; fb_fire Delivery Unlock"); + EmitSoundToAll(TRIGGERSCORE); + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team's \x07FF0000FAT MAN \x0700AA55is now available for deployment!"); + } + } + //Loop back from the start with Freedom Bomb. This time, enable special stuff. + if (bombsPushed >= 7){ + bombsPushed = 0; + bombCache = 0; + bombStatus = 0; + explodeType = 0; + CreateTimer(3.0, BombStatusTimer); + float spDelay = GetRandomFloat(10.0, 30.0); + CreateTimer(spDelay, SpecTimer); + } + } + return Plugin_Stop; +} +//SpecTimer +public Action SpecTimer(Handle timer){ + int i = GetRandomInt(1, 6); + switch (i){ + case 1:{ + ServerCommand("fb_fire Spec.* Disable; fb_fire Spec.Goobbue Enable"); + } + case 2:{ + ServerCommand("fb_fire Spec.* Disable; fb_fire Spec.Waffle Enable"); + } + case 3:{ + ServerCommand("fb_fire Spec.* Disable; fb_fire Spec.Burrito Enable"); + } + case 4:{ + ServerCommand("fb_fire Spec.* Disable; fb_fire Spec.Shroom Enable"); + } + case 5:{ + ServerCommand("fb_fire Spec.* Disable; fb_fire Spec.BlueBall Enable"); + } + case 6:{ + ServerCommand("fb_fire Spec.* Enable"); + } + } + float spDelay = GetRandomFloat(10.0, 30.0); + CreateTimer(spDelay, SpecTimer); + return Plugin_Stop; +} +//SENTMeteor (Scripted Entity Meteors) +public Action SENTMeteorTimer(Handle timer){ + if(canSENTMeteors){ + int i = GetRandomInt(1, 8); + switch(i){ + case 1:{ + ServerCommand("fb_fire FB.SentMeteor01 ForceSpawn"); + } + case 2:{ + ServerCommand("fb_fire FB.SentMeteor02 ForceSpawn"); + } + case 3:{ + ServerCommand("fb_fire FB.SentMeteor03 ForceSpawn"); + } + case 4:{ + ServerCommand("fb_fire FB.SentMeteor04 ForceSpawn"); + } + case 5:{ + ServerCommand("fb_fire FB.SentMeteor05 ForceSpawn"); + } + case 6:{ + ServerCommand("fb_fire FB.SentMeteor06 ForceSpawn"); + } + case 7:{ + ServerCommand("fb_fire FB.SentMeteor07 ForceSpawn"); + } + case 8:{ + ServerCommand("fb_fire FB.SentMeteor08 ForceSpawn"); + } + } + } + return Plugin_Stop; +} + +public Action DisableSENTMeteors(Handle timer){ + canSENTMeteors = false; + return Plugin_Stop; +} + +//SENTNukes (Scripted Entity Nukes) +public Action SENTNukeTimer(Handle timer){ + if(canSENTNukes){ + ServerCommand("fb_fire FB.DropNuke PlaySound"); + int i = GetRandomInt(1, 8); + switch(i){ + case 1:{ + ServerCommand("fb_fire FB.SentNuke01 ForceSpawn"); + } + case 2:{ + ServerCommand("fb_fire FB.SentNuke02 ForceSpawn"); + } + case 3:{ + ServerCommand("fb_fire FB.SentNuke03 ForceSpawn"); + } + case 4:{ + ServerCommand("fb_fire FB.SentNuke04 ForceSpawn"); + } + case 5:{ + ServerCommand("fb_fire FB.SentNuke05 ForceSpawn"); + } + case 6:{ + ServerCommand("fb_fire FB.SentNuke06 ForceSpawn"); + } + case 7:{ + ServerCommand("fb_fire FB.SentNuke07 ForceSpawn"); + } + case 8:{ + ServerCommand("fb_fire FB.SentNuke08 ForceSpawn"); + } + } + float f = GetRandomFloat(1.5, 3.0); + CreateTimer(f, SENTNukeTimer); + } + return Plugin_Stop; +} + +public Action DisableSENTNukes(Handle timer){ + canSENTNukes = false; + return Plugin_Stop; +} + +//SENTStars (Scripted Entity Stars) +public Action SENTStarTimer(Handle timer){ + if(canSENTStars){ + int i = GetRandomInt(1, 8); + switch(i){ + case 1:{ + ServerCommand("fb_fire FB.SentStar01 ForceSpawn"); + } + case 2:{ + ServerCommand("fb_fire FB.SentStar02 ForceSpawn"); + } + case 3:{ + ServerCommand("fb_fire FB.SentStar03 ForceSpawn"); + } + case 4:{ + ServerCommand("fb_fire FB.SentStar04 ForceSpawn"); + } + case 5:{ + ServerCommand("fb_fire FB.SentStar05 ForceSpawn"); + } + case 6:{ + ServerCommand("fb_fire FB.SentStar06 ForceSpawn"); + } + case 7:{ + ServerCommand("fb_fire FB.SentStar07 ForceSpawn"); + } + case 8:{ + ServerCommand("fb_fire FB.SentStar08 ForceSpawn"); + } + } + float f = GetRandomFloat(0.75, 1.5); + CreateTimer(f, SENTStarTimer); + } +} +public Action SENTStarDisable(Handle timer){ + canSENTStars = false; + return Plugin_Handled; +} + +//TankHornSND because why not when code entry fails??? +public Action FBCodeFailTankHornSND(Handle timer){ + EmitSoundToAll("mvm/mvm_tank_horn.wav"); + return Plugin_Stop; +} +//Halloween Bosses +public Action HWBosses(Handle timer){ + if(isWave && canHWBoss){ + int i = GetRandomInt(1, 10); + switch(i){ + case 1:{ + ServerCommand("fb_fire hhh_maker ForceSpawn; fb_fire hhh_maker2 ForceSpawn"); + } + case 2:{ + ServerCommand("fb_fire hhh_maker2 ForceSpawn"); + } + case 3:{ + ServerCommand("fb_fire hhh_maker2 ForceSpawn; fb_fire SkeleSpawner Enable; fb_fire SkeleSpawner Disable 0 10"); + } + case 4:{ + ServerCommand("fb_fire SkeleSpawner Enable; fb_fire SkeleSpawner Disable 0 10"); + } + case 5:{ + ServerCommand("fb_fire merasmus_maker ForceSpawn; fb_fire hhh_maker2 ForceSpawn"); + } + case 6:{ + ServerCommand("fb_fire merasmus_maker ForceSpawn; fb_fire monoculus_maker ForceSpawn; fb_fire hhh_maker2 ForceSpawn"); + } + case 7:{ + ServerCommand("fb_fire monoculus_maker ForceSpawn; fb_fire merasmus_maker ForceSpawn;"); + } + case 8:{ + ServerCommand("fb_fire SkeleSpawner Enable; fb_fire SkeleSpawner Disable 0 30"); + } + case 9:{ + ServerCommand("fb_fire SkeleSpawner Enable; fb_fire SkeleSpawner Disable 0 60; fb_fire merasmus_maker ForceSpawn; fb_fire monoculus_maker ForceSpawn; fb_fire hhh_maker2 ForceSpawn"); + } + case 10:{ + ServerCommand("fb_fire monoculus_maker ForceSpawn"); + } + } + canHWBoss = false; + CreateTimer(60.0, HWBossesRefire); + } + return Plugin_Stop; +} + +public Action HWBossesRefire(Handle timer){ + if (isWave){ + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + return Plugin_Stop; +} +//SacPoints (Add points to Sacrifice Points occasionally) +public Action SacrificePointsTimer(Handle timer){ + if (isWave && (sacPoints < sacPointsMax)){ + sacPoints++; + float f = GetRandomFloat(5.0, 30.0); + CreateTimer(f, SacrificePointsTimer); + } + return Plugin_Stop; +} + +//Track SacPoints and update entities every 0.1 seconds +public Action SacrificePointsUpdater(Handle timer){ + if (isWave){ + CreateTimer(0.1, SacrificePointsUpdater); + if (sacPoints <=9){ + ServerCommand("fb_fire BTN.Sacrificial* Lock; fb_fire BTN.Sacrificial* Color 0;"); + } + else if (sacPoints >= 10 && sacPoints <= 19){ + ServerCommand("fb_fire BTN.Sacrificial* Lock; fb_fire BTN.Sacrificial* Color 0; fb_fire BTN.Sacrificial01 Unlock; fb_fire BTN.Sacrificial01 Color 255"); + } + else if (sacPoints >= 20 && sacPoints <= 29){ + ServerCommand("fb_fire BTN.Sacrificial* Lock; fb_fire BTN.Sacrificial* Color 0; fb_fire BTN.Sacrificial01 Unlock; fb_fire BTN.Sacrificial01 Color 255; fb_fire BTN.Sacrificial02 Unlock; fb_fire BTN.Sacrificial02 Color 255"); + } + else if (sacPoints >= 30 && sacPoints <= 39){ + ServerCommand("fb_fire BTN.Sacrificial* Lock; fb_fire BTN.Sacrificial* Color 0; fb_fire BTN.Sacrificial01 Unlock; fb_fire BTN.Sacrificial01 Color 255; fb_fire BTN.Sacrificial02 Unlock; fb_fire BTN.Sacrificial02 Color 255; fb_fire BTN.Sacrificial03 Unlock; fb_fire BTN.Sacrificial03 Color 255"); + + } + else if (sacPoints >= 40 && sacPoints <= 49){ + ServerCommand("fb_fire BTN.Sacrificial* Lock; fb_fire BTN.Sacrificial* Color 0; fb_fire BTN.Sacrificial01 Unlock; fb_fire BTN.Sacrificial01 Color 255; fb_fire BTN.Sacrificial02 Unlock; fb_fire BTN.Sacrificial02 Color 255; fb_fire BTN.Sacrificial03 Unlock; fb_fire BTN.Sacrificial03 Color 255; fb_fire BTN.Sacrificial04 Unlock; fb_fire BTN.Sacrificial04 Color 255"); + + } + else if (sacPoints >= 50 && sacPoints <= 59){ + ServerCommand("fb_fire BTN.Sacrificial* Lock; fb_fire BTN.Sacrificial* Color 0; fb_fire BTN.Sacrificial01 Unlock; fb_fire BTN.Sacrificial01 Color 255; fb_fire BTN.Sacrificial02 Unlock; fb_fire BTN.Sacrificial02 Color 255; fb_fire BTN.Sacrificial03 Unlock; fb_fire BTN.Sacrificial03 Color 255; fb_fire BTN.Sacrificial04 Unlock; fb_fire BTN.Sacrificial04 Color 255; fb_fire BTN.Sacrificial05 Unlock; fb_fire BTN.Sacrificial05 Color 255"); + } + else if (sacPoints >= 60 && sacPoints <= 69){ + ServerCommand("fb_fire BTN.Sacrificial* Lock; fb_fire BTN.Sacrificial* Color 0; fb_fire BTN.Sacrificial01 Unlock; fb_fire BTN.Sacrificial01 Color 255; fb_fire BTN.Sacrificial02 Unlock; fb_fire BTN.Sacrificial02 Color 255; fb_fire BTN.Sacrificial03 Unlock; fb_fire BTN.Sacrificial03 Color 255; fb_fire BTN.Sacrificial04 Unlock; fb_fire BTN.Sacrificial04 Color 255; fb_fire BTN.Sacrificial05 Unlock; fb_fire BTN.Sacrificial05 Color 255; fb_fire BTN.Sacrificial06 Unlock; fb_fire BTN.Sacrificial06 Color 255"); + + } + else if (sacPoints >= 70 && sacPoints <= 99){ + ServerCommand("fb_fire BTN.Sacrificial* Lock; fb_fire BTN.Sacrificial* Color 0; fb_fire BTN.Sacrificial01 Unlock; fb_fire BTN.Sacrificial01 Color 255; fb_fire BTN.Sacrificial02 Unlock; fb_fire BTN.Sacrificial02 Color 255; fb_fire BTN.Sacrificial03 Unlock; fb_fire BTN.Sacrificial03 Color 255; fb_fire BTN.Sacrificial04 Unlock; fb_fire BTN.Sacrificial04 Color 255; fb_fire BTN.Sacrificial05 Unlock; fb_fire BTN.Sacrificial05 Color 255; fb_fire BTN.Sacrificial06 Unlock; fb_fire BTN.Sacrificial06 Color 255; fb_fire BTN.Sacrificial07 Unlock; fb_fire BTN.Sacrificial07 Color 255"); + + } + else if (sacPoints == 100){ + ServerCommand("fb_fire BTN.Sacrificial* Lock; fb_fire BTN.Sacrificial* Color 0; fb_fire BTN.Sacrificial01 Unlock; fb_fire BTN.Sacrificial01 Color 255; fb_fire BTN.Sacrificial02 Unlock; fb_fire BTN.Sacrificial02 Color 255; fb_fire BTN.Sacrificial03 Unlock; fb_fire BTN.Sacrificial03 Color 255; fb_fire BTN.Sacrificial04 Unlock; fb_fire BTN.Sacrificial04 Color 255; fb_fire BTN.Sacrificial05 Unlock; fb_fire BTN.Sacrificial05 Color 255; fb_fire BTN.Sacrificial06 Unlock; fb_fire BTN.Sacrificial06 Color 255; fb_fire BTN.Sacrificial07 Unlock; fb_fire BTN.Sacrificial07 Color 255; fb_fire BTN.Sacrificial08 Unlock; fb_fire BTN.Sacrificial08 Color 255"); + + } + else if (sacPoints > sacPointsMax){ + sacPoints = sacPointsMax; + } + } + return Plugin_Stop; +} +//RobotLaunchTimer (Randomly fling robots) +public Action RobotLaunchTimer(Handle timer){ + if (isWave){ + ServerCommand("fb_fire FB.RobotLauncher Enable; fb_fire FB.RobotLauncher Disable 0 7.5"); + float f = GetRandomFloat(5.0, 30.0); + CreateTimer(f, RobotLaunchTimer); + } + return Plugin_Stop; +} + +//Command action definitions +//Get current song +public Action Command_GetCurrentSong(int client, int args){ + if(StrEqual(curSong, BGM1)) + { + PrintToChat(client, "The current song is: %s", BGM1Title); + } + else if(StrEqual(curSong, BGM2)){ + PrintToChat(client, "The current song is: %s", BGM2Title); + } + else if(StrEqual(curSong, BGM3)){ + PrintToChat(client, "The current song is: %s", BGM3Title); + } + else if(StrEqual(curSong, BGM4)){ + PrintToChat(client, "The current song is: %s", BGM4Title); + } + else if(StrEqual(curSong, BGM5)){ + PrintToChat(client, "The current song is: %s", BGM5Title); + } + else if(StrEqual(curSong, BGM6)){ + PrintToChat(client, "The current song is: %s", BGM6Title); + } + else if(StrEqual(curSong, BGM7)){ + PrintToChat(client, "The current song is: %s", BGM7Title); + } + else if(StrEqual(curSong, BGM8)){ + PrintToChat(client, "The current song is: %s", BGM8Title); + } + else if(StrEqual(curSong, DEFAULTBGM1)){ + PrintToChat(client, "The current song is: %s", DEFAULTBGM1Title); + } + else if(StrEqual(curSong, DEFAULTBGM2)){ + PrintToChat(client, "The current song is: %s", DEFAULTBGM2Title); + } + return Plugin_Handled; +} + +//Deploy a bomb for RED +public Action Command_Deploy(int args){ + if(explodeType == 0){ + PrintToServer("Tried to detonate with a bomb size of zero!"); + } + //Small Explosion + else if (explodeType == 1){ + ServerCommand("fb_fire Murica PlaySound; fb_bombpushplus5; fb_fire SmallExplosion Explode; fb_fire SmallExploShake StartShake"); + EmitSoundToAll(COUNTDOWN); + } + //Medium Explosion + else if (explodeType == 2){ + ServerCommand("fb_bombpushplus5; fb_fire MediumExplosion Explode; fb_fire MedExplosionSND PlaySound; fb_fire MedExploShake StartShake"); + EmitSoundToAll(COUNTDOWN); + } + //Falling Star + else if (explodeType == 3){ + ServerCommand("fb_bombpushplus5; fb_fire MediumExplosion Explode; fb_fire MedExplosionSND PlaySound; fb_fire MedExploShake StartShake"); + EmitSoundToAll(COUNTDOWN); + CreateTimer(1.0, SENTStarTimer); + CreateTimer(60.0, SENTStarDisable); + } + //Major Kong + else if (explodeType == 4){ + ServerCommand("fb_bombpushplus5; fb_fire MajorKongSND PlaySound; fb_fire FB.Fade Fade; fb_fire LargeExplosion Explode 0 1.7; fb_fire LargeExplosionSound PlaySound 0 1.7; fb_fire LargeExploShake StartShake 0 1.7; fb_fire NukeAll Enable 0 1.7; fb_fire NukeAll Disable 0 3"); + EmitSoundToAll(COUNTDOWN); + } + //large (shark) + else if (explodeType == 5){ + ServerCommand("fb_bombpushplus5; fb_fire LargeExploShake StartShake 0 1.5; fb_fire LargeExplosion Explode 0 1.5; fb_fire LargeExploSound PlaySound 0 1.5"); + EmitSoundToAll(COUNTDOWN); + } + //FatMan + else if (explodeType == 6){ + ServerCommand("fb_bombpushplus5; fb_fire LargeExplosion Explode; fb_fire LargeExploShake StartShake; fb_fire HindenburgBoom PlaySound; fb_fire NukeAll Enable; fb_fire FB.Fade Fade; fb_fire NukeAll Disable 0 2"); + EmitSoundToAll(COUNTDOWN); + } +} +//Force Tornado +public Action Command_ForceTornado(int args){ + if(isWave && canTornado && !tornado){ + CreateTimer(0.1, SpawnTornado); + PrintCenterTextAll("OH NOES... PREPARE YOUR ANUS!"); + } + else{ + PrintToServer("Error spawning manual tornado... Perhaps we are not in a wave, tornadoes are banished, or a tornado has already spawned???"); + } +} + +//Determine which bomb has been recently pushed and tell the client if a bomb is ready or not. +public Action Command_FBBombStatus(int client, int args){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55The bomb status is currently %i", bombStatus); + //No bombs have yet been deployed nor have they been unlocked. + if (bombStatus <= 7){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Bombs are \x07FF0000NOT READY\x07FFFFFF!"); + } + //Only execute if Freedom Bomb is available. + else if (bombStatus >= 8 && bombStatus < 16){ + //If no bombs are pushed and next bomb IS ready. + if (bombsPushed == 0 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team has not deployed any bombs, however: Your team's \x07FF0000FREEDOM BOMB \x0700AA55is available for deployment!"); + } + //If the wave forces us to have a bomb pushed and 0 queue + else if(bombsPushed == 1 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55The wave has just begun or has been reset. Please wait for the next bomb."); + } + //If we've pushed the Freedom Bomb and next bomb is NOT ready. + else if(bombsPushed == 1 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFFREEDOM BOMB \x0700AA55. Please wait for the next bomb."); + } + return Plugin_Continue; + } + //Only execute if Elon Bust is available. + else if(bombStatus >= 16 && bombStatus < 24){ + //If we've pushed the Freedom Bomb and next bomb IS ready. + if (bombsPushed == 1 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFFREEDOM BOMB \x0700AA55. Your team's \x07FF0000ELON BUST \x0700AA55is available for deployment!"); + } + //If the wave forces us to have 2 bombs pushed and 0 queue + else if(bombsPushed == 2 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55The wave has just begun or has been reset. Please wait for the next bomb."); + } + //If we've pushed the Freedom Bomb and the Elon Bust and next bomb is NOT ready. + else if(bombsPushed == 2 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFELON BUST \x0700AA55. Please wait for the next bomb."); + } + return Plugin_Continue; + } + //Only execute if Bath Salts are available. + else if(bombStatus >= 24 && bombStatus < 32){ + //If we've pushed the Freedom Bomb and the Elon Bust and the next bomb IS ready. + if (bombsPushed == 2 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFELON BUST \x0700AA55. Your team's \x07FF0000BATH SALTS \x0700AA55are available for deployment!"); + } + //If the wave forces us to have 3 bombs pushed and 0 queue + else if(bombsPushed == 3 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55The wave has just begun or has been reset. Please wait for the next bomb."); + } + //If we've pushed the Freedom Bomb, Elon Bust, and Bath Salts and the next bomb is NOT ready. + else if (bombsPushed == 3 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFBATH SALTS \x0700AA55. Please wait for the next bomb."); + } + return Plugin_Continue; + } + //Only execute if Falling Star is available. + else if (bombStatus >= 32 && bombStatus < 40){ + //If we've pushed the Freedom Bomb, Elon Bust, and Bath Salts, and the next bomb IS ready. + if (bombsPushed == 3 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFBATH SALTS \x0700AA55. Your team's \x07FF0000FALLING STAR \x0700AA55is available for deployment!"); + } + //If we've pushed the Freedom Bomb, Elon Bust, Bath Salts, and Falling Star and the next bomb IS NOT ready. + else if (bombsPushed == 4 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFFALLING STAR \x0700AA55. Please wait for the next bomb."); + } + return Plugin_Continue; + } + //Only execute if Major Kong is available. + else if (bombStatus >= 40 && bombStatus < 48){ + //If we've pushed the Freedom Bomb, Elon Bust, Bath Salts, and Falling Star and the next bomb IS ready. + if (bombsPushed == 4 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFFALLING STAR \x0700AA55. Your team's \x07FF0000MAJOR KONG \x0700AA55is available for deployment!"); + } + //If we've pushed the Freedom Bomb, Elon Bust, Bath Salts, Falling Star, and Major Kong and the next bomb is NOT ready. + else if (bombsPushed == 5 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFMAJOR KONG \x0700AA55. Please wait for the next bomb."); + } + } + //Only execute if Shark is available. + else if (bombStatus >= 48 && bombStatus < 56){ + //If we've pushed the Freedom Bomb, Elon Bust, Bath Salts, Falling Star, and Major Kong and the next bomb IS ready. + if (bombsPushed == 5 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFMAJOR KONG \x0700AA55. Your team's \x07FF0000SHARK \x0700AA55is available for deployment!"); + } + //If we've pushed the Freedom Bomb, Elon Bust, Bath Salts, Falling Star, Major Kong, and Shark and the next bomb IS NOT ready. + else if (bombsPushed == 6 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFSHARK \x0700AA55. Please wait for the next bomb."); + } + } + //Only execute if Fat Man is available. + else if (bombStatus >= 56 && bombStatus < 64){ + //If we've pushed the Freedom Bomb, Elon Bust, Bath Salts, Falling Star, Major Kong, and Shark and the next bomb IS ready. + if (bombsPushed == 6 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFSHARK \x0700AA55. Your team's \x07FF0000FAT MAN \x0700AA55is available for deployment!"); + } + else if (bombsPushed == 7 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFFAT MAN \x0700AA55. Bombs are automatically reset to preserve the replayable aspect of this game mode."); + } + } + //Only execute if I add another bomb or system for this... + else if (bombStatus >= 64 && bombStatus < 72){ + PrintToChatAll("wowie you exceeded the legal value of this script!"); + } + return Plugin_Handled; +} + +//Tell the client the current sacrifice points earned. +public Action Command_FBSacStatus(int client, int args){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55The sacrificial points counter is currently at %i of %i maximum for this wave.", sacPoints, sacPointsMax); +} + +//Force a victory, used by some entities in the map for quickly creating mass amounts of chaos. +public Action Command_ForceVictory(int args) +{ + int flags = GetCommandFlags("tf_mvm_force_victory"); + SetCommandFlags("tf_mvm_force_victory", flags & ~FCVAR_CHEAT); + ServerCommand("tf_mvm_force_victory 1"); + FakeClientCommand(0, ""); //Not sure why, but this has to be here. Otherwise the specified commands simply refuse to work... + SetCommandFlags("tf_mvm_force_victory", flags|FCVAR_CHEAT); + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF VICTORY HAS BEEN FORCED! THE SERVER WILL RESTART IN 10 SECONDS."); + CreateTimer(10.0, Timer_RestartServer); +} + +public Action Command_TrainIncoming(int args) +{ + PrintToChatAll("\x070000AA[\x07AA0000WARN\x070000AA] \x07AA7000KISSONE'S TRAIN\x07FFFFFF is \x07AA0000INCOMING\x07FFFFFF. Look out!"); +} + +public Action Command_AtomBmbRain(int args) +{ + PrintToChatAll("\x070000AA[\x07AA0000WARN\x070000AA] \x07FFFFFFUh oh, it's begun to rain \x07AA0000ATOM BOMBS\x07FFFFFF! TAKE COVER!"); +} + +public Action Command_OhNoes(int args) +{ + PrintToChatAll("\x070000AA[\x07AA0000WARN\x070000AA] \x07FFFFFFOh noes, prepare your anus! A \x07AA0000TORNADO WARNING\x07FFFFFF has been issued! TAKE COVER NOW!!!"); +} + +public Action Command_MeteorIncoming(int args) +{ + PrintToChatAll("\x070000AA[\x07AA0000WARN\x070000AA] \x07FFFFFFUh oh, a \x07AA0000METEOR\x07FFFFFF has been spotted coming towards Dovah's Ass!!!"); +} + +public Action Command_MeteorShower(int args) +{ + PrintToChatAll("\x070000AA[\x07AA0000WARN\x070000AA] \x07FFFFFFUh oh, a \x07AA0000METEOR SHOWER\x07FFFFFF has been reported from Dovah's Ass!!!"); +} + +public Action Command_DovahsAss(int args) +{ + PrintToChatAll("\x070000AA[\x07AAAA00INFO\x070000AA] \x07AA0000DOVAH'S ASS\x07FFFFFF v0x13. Prepare yourself for the unpredictable... [\x0700FF00by TTV/ProfessorFartsalot\x07FFFFFF]"); +} +//Wave One +public Action Command_WaveOne(int args) +{ + bgmlock1 = false; + bgmlock2 = true; + bgmlock3 = true; + bgmlock4 = true; + bgmlock5 = true; + bgmlock6 = true; + bgmlock7 = true; + bgmlock8 = true; + canHWBoss = true; + canTornado = true; + isWave = true; + bombStatus = 0; + bombsPushed = 0; + bombStatusMax = 8; + sacPointsMax = 90; + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 1: Locus"); + StopCurSong(); + EmitSoundToAll(BGM1, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM1; + CreateTimer(229.25, RefireLocus); + CreateTimer(1.0, BombStatusTimer); + CreateTimer(1.0, RobotLaunchTimer); + CreateTimer(1.0, SacrificePointsTimer); + CreateTimer(1.0, SacrificePointsUpdater); + CreateTimer(1.0, RefireStorm); + ActivateTornadoTimer(); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); +} +//Wave Two +public Action Command_WaveTwo(int args) +{ + bgmlock1 = true; + bgmlock2 = false; + bgmlock3 = true; + bgmlock4 = true; + bgmlock5 = true; + bgmlock6 = true; + bgmlock7 = true; + bgmlock8 = true; + canHWBoss = true; + canTornado = true; + isWave = true; + bombStatus = 4; + bombsPushed = 0; + bombStatusMax = 16; + sacPointsMax = 90; + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 2: Metal"); + StopCurSong(); + EmitSoundToAll(BGM2, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM2; + CreateTimer(153.95, RefireMetal); + CreateTimer(1.0, BombStatusTimer); + CreateTimer(1.0, RobotLaunchTimer); + CreateTimer(1.0, SacrificePointsTimer); + CreateTimer(1.0, SacrificePointsUpdater); + CreateTimer(1.0, RefireStorm); + ActivateTornadoTimer(); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); +} +//Wave Three +public Action Command_WaveThree(int args) +{ + bgmlock1 = true; + bgmlock2 = true; + bgmlock3 = false; + bgmlock4 = true; + bgmlock5 = true; + bgmlock6 = true; + bgmlock7 = true; + bgmlock8 = true; + canHWBoss = true; + canTornado = true; + HWNMax = 360.0; + isWave = true; + bombStatus = 7; + bombsPushed = 0; + bombStatusMax = 24; + sacPointsMax = 90; + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 3: Exponential Entropy"); + StopCurSong(); + EmitSoundToAll(BGM3, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM3; + CreateTimer(166.85, RefireEntropy); + CreateTimer(1.0, BombStatusTimer); + CreateTimer(1.0, RobotLaunchTimer); + CreateTimer(1.0, SacrificePointsTimer); + CreateTimer(1.0, SacrificePointsUpdater); + CreateTimer(1.0, RefireStorm); + ActivateTornadoTimer(); + float f = GetRandomFloat(60.0, 180.0); + CreateTimer(f, UnlockTimer); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); +} +//Wave Four +public Action Command_WaveFour(int args) +{ + bgmlock1 = true; + bgmlock2 = true; + bgmlock3 = true; + bgmlock4 = false; + bgmlock5 = true; + bgmlock6 = true; + bgmlock7 = true; + bgmlock8 = true; + canHWBoss = true; + canTornado = true; + HWNMax = 360.0; + isWave = true; + bombStatus = 12; + bombsPushed = 1; + bombStatusMax = 32; + sacPointsMax = 90; + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 4: Torn From The Heavens"); + StopCurSong(); + EmitSoundToAll(BGM4, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM4; + CreateTimer(122.25, RefireTorn); + CreateTimer(1.0, BombStatusTimer); + CreateTimer(1.0, RobotLaunchTimer); + CreateTimer(1.0, SacrificePointsTimer); + CreateTimer(1.0, SacrificePointsUpdater); + CreateTimer(1.0, RefireStorm); + ActivateTornadoTimer(); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); +} +//Wave Five +public Action Command_WaveFive(int args) +{ + bgmlock1 = true; + bgmlock2 = true; + bgmlock3 = true; + bgmlock4 = true; + bgmlock5 = false; + bgmlock6 = true; + bgmlock7 = true; + bgmlock8 = true; + canHWBoss = true; + canTornado = true; + HWNMax = 260.0; + HWNMin = 140.0; + isWave = true; + bombStatus = 14; + bombsPushed = 1; + bombStatusMax = 40; + sacPointsMax = 100; + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 5: Metal - Brute Justice Mode"); + StopCurSong(); + EmitSoundToAll(BGM5, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM5; + CreateTimer(131.75, RefireBJMode); + CreateTimer(1.0, BombStatusTimer); + CreateTimer(1.0, RobotLaunchTimer); + CreateTimer(1.0, SacrificePointsTimer); + CreateTimer(1.0, SacrificePointsUpdater); + CreateTimer(1.0, RefireStorm); + ActivateTornadoTimer(); + float f = GetRandomFloat(60.0, 180.0); + CreateTimer(f, UnlockTimer); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); +} +//Wave Six +public Action Command_WaveSix(int args) +{ + bgmlock1 = true; + bgmlock2 = true; + bgmlock3 = true; + bgmlock4 = true; + bgmlock5 = true; + bgmlock6 = false; + bgmlock7 = true; + bgmlock8 = true; + canHWBoss = true; + canTornado = true; + HWNMax = 260.0; + HWNMin = 140.0; + isWave = true; + bombStatus = 20; + bombsPushed = 2; + bombStatusMax = 48; + sacPointsMax = 100; + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 6: Grandma Destruction"); + StopCurSong(); + EmitSoundToAll(BGM6, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM6; + CreateTimer(323.95, RefireGrandma); + CreateTimer(1.0, BombStatusTimer); + CreateTimer(1.0, RobotLaunchTimer); + CreateTimer(1.0, SacrificePointsTimer); + CreateTimer(1.0, SacrificePointsUpdater); + CreateTimer(1.0, RefireStorm); + ActivateTornadoTimer(); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); +} +//Wave Seven +public Action Command_WaveSeven(int args) +{ + bgmlock1 = true; + bgmlock2 = true; + bgmlock3 = true; + bgmlock4 = true; + bgmlock5 = true; + bgmlock6 = true; + bgmlock7 = false; + bgmlock8 = true; + canHWBoss = true; + canTornado = true; + HWNMax = 240.0; + HWNMin = 120.0; + isWave = true; + bombStatus = 28; + bombsPushed = 3; + bombStatusMax = 56; + sacPointsMax = 100; + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 7: Revenge Twofold"); + StopCurSong(); + EmitSoundToAll(BGM7, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM7; + CreateTimer(133.25, RefireRevenge2F); + CreateTimer(1.0, BombStatusTimer); + CreateTimer(1.0, RobotLaunchTimer); + CreateTimer(1.0, SacrificePointsTimer); + CreateTimer(1.0, SacrificePointsUpdater); + CreateTimer(1.0, RefireStorm); + ActivateTornadoTimer(); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); +} +//Deprecated Functions that should be either reassigned or removed. +public Action Command_HydrogenUp(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team's \x07FF0000HYDROGEN \x0700AA55is now available for deployment!"); +} + +public Action Command_WaveSevenBurgUp(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team has delivered Hydrogen! The \x07FF0000HINDENBURG \x0700AA55is now ready for flight!"); +} +//Wave Eight +public Action Command_WaveEight(int args) +{ + bgmlock1 = true; + bgmlock2 = true; + bgmlock3 = true; + bgmlock4 = true; + bgmlock5 = true; + bgmlock6 = true; + bgmlock7 = true; + bgmlock8 = false; + canHWBoss = true; + canTornado = true; + HWNMax = 240.0; + HWNMin = 120.0; + isWave = true; + bombStatus = 30; + bombsPushed = 3; + bombStatusMax = 64; + sacPointsMax = 100; + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 8: Under The Weight"); + StopCurSong(); + EmitSoundToAll(BGM8, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM8; + CreateTimer(313.85, RefireUnderTW); + CreateTimer(1.0, BombStatusTimer); + CreateTimer(1.0, RobotLaunchTimer); + CreateTimer(1.0, SacrificePointsTimer); + CreateTimer(1.0, SacrificePointsUpdater); + CreateTimer(1.0, RefireStorm); + ActivateTornadoTimer(); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); +} +//Specials +public Action Command_FoundGoob(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55ALL HAIL \x07FF00FFGOOBBUE\x0700AA55!"); +} + +public Action Command_FoundWaffle(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Oh no, someone has found and (probably) consumed a \x07FF0000WAFFLE OF MASS DESTRUCTION\x07FFFFFF!"); +} + +public Action Command_FoundBurrito(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Why would you even eat \x07FF0000The Forbidden Burrito\x07FFFFFF?"); +} + +public Action Command_FoundShroom(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Welp, someone is playing \x0700FF00Mario\x07FFFFFF..."); +} + +public Action Command_FoundBall(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55What on earth IS that? It appears to be a... \x075050FFBLUE BALL\x07FFFFFF!"); +} +//Sacrifice Points Notifications +public Action Command_TSPlus1(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF Sacrificed a client into orbit. (\x0700FF00+1 pt\x07FFFFFF)"); + sacPoints++; +} + +public Action Command_DPSacPlus1(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF Sent a client to their doom. (\x0700FF00+1 pt\x07FFFFFF)"); + sacPoints++; +} + +public Action Command_KissoneSacPlus1(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF Dunked a client into liquid death. (\x0700FF00+1 pt\x07FFFFFF)"); + sacPoints++; +} + +public Action Command_TankDestPlus1(int args){ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF A tank has been destroyed. (\x0700FF00+1 pt\x07FFFFFF)"); + sacPoints++; +} +public Action Command_BombResPlus5(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF Bomb has been reset. (\x0700FF00+5 pts\x07FFFFFF)"); + sacPoints++, + sacPoints++, + sacPoints++, + sacPoints++, + sacPoints++; +} + +public Action Command_BathSaltsSacMinus10(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF INSTANT BATH SALT DETONATION! (\x07FF0000-10 pts\x07FFFFFF)"); + sacPoints = (sacPoints - 10); +} + +public Action Command_FatManSacMinus20(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF INSTANT FAT MAN DETONATION! (\x07FF0000-20 pts\x07FFFFFF)"); + sacPoints = (sacPoints - 20); +} + +public Action Command_GoobbueSacMinus30(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF GOOBBUE COMING IN FROM ORBIT! (\x07FF0000-30 pts\x07FFFFFF)"); + sacPoints = (sacPoints - 30); +} + +public Action Command_BlueBallSacMinus30(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF BLUE KIRBY FALLING OUT OF THE SKY! (\x07FF0000-30 pts\x07FFFFFF)"); + sacPoints = (sacPoints - 30); +} + +public Action Command_GBoomSacMinus40(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF We're spending most our lives living in an EXPLOSIVE PARADISE! (\x07FF0000-40 pts\x07FFFFFF)"); + sacPoints = (sacPoints - 40); +} + +public Action Command_AssGasMinus40(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF NO NO NO, STOP THE SHARTS!!!! (\x07FF0000-40 pts\x07FFFFFF)"); + sacPoints = (sacPoints - 40); +} + +public Action Command_KirbyWardSacMinus50(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF A PINK KIRBY HAS BANISHED TORNADOES FOR THIS WAVE! (\x07FF0000-50 pts\x07FFFFFF)"); + KillTornado(); + canTornado = false; + sacPoints = (sacPoints - 50); +} + +public Action Command_NFOSacMinus60(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF TOTAL ATOMIC ANNIHILATION. (\x07FF0000-60 pts\x07FFFFFF)"); + sacPoints = (sacPoints - 60); + canSENTNukes = true; + CreateTimer(1.0, SENTNukeTimer); + CreateTimer(30.0, DisableSENTNukes); +} + +public Action Command_MeteorsSacMinus70(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF COSMIC DEVASTATION IMMINENT. (\x07FF0000-70 pts\x07FFFFFF)"); + sacPoints = (sacPoints - 70); + canSENTMeteors = true; + CreateTimer(1.0, SENTMeteorTimer); + CreateTimer(30.0, DisableSENTMeteors); +} + +public Action Command_DovahSacMinus100(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF NOW PRESENTING... PROFESSOR FARTSALOT OF THE HINDENBURG! (\x07FF0000-100 points\x07FFFFFF)"); + sacPoints = (sacPoints - 100); +} + +public Action Command_BombPushPlusFive(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF Bomb successfully pushed! (\x0700FF00+5 pts\x07FFFFFF)"); + sacPoints++, + sacPoints++, + sacPoints++, + sacPoints++, + sacPoints++; + bombStatusMax = (bombStatusMax + 8); + bombsPushed++; + bombCache = 1; + CreateTimer(3.0, BombStatusTimer); +} + +public Action Command_DovahsAssFinished(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF YOU HAVE SUCCESSFULLY COMPLETED DOVAH'S ASS ! THE SERVER WILL RESTART IN 10 SECONDS."); + CreateTimer(10.0, Timer_RestartServer); +} + +//Taco Bell edition commands and features +public Action Command_TacoBell(int args) +{ + PrintToChatAll("\x070000AA[\x07AAAA00INFO\x070000AA] \x07FFFFFFYou have chosen \x07AA0000DOVAH'S ASS - TACO BELL EDITION\x07FFFFFF. Why... Why would you DO THIS?! Do you not realize what you've just done?????"); +} + +public Action Command_TBWave01(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 01: Battle On The Big Bridge"); +} + +public Action Command_TBWave02(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 02: Locus"); +} + +public Action Command_TBWave03(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 03: Metal"); +} + +public Action Command_TBWave04(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 04: Torn From The Heavens"); +} + +public Action Command_TBWave05(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 05: Exponential Entropy"); +} + +public Action Command_TBWave06(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 06: Grandma Destruction"); +} + +public Action Command_TBWave07(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 07: Rise"); +} + +public Action Command_TBWave08(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 08: Metal - Brute Justice Mode"); +} + +public Action Command_TBWave09(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 09: Locus"); +} + +public Action Command_TBWave10(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 10: Exponential Entropy"); +} + +public Action Command_TBWave11(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 11: Revenge Twofold"); +} + +public Action Command_TBWave12(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 12: Metal"); +} + +public Action Command_TBWave13(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 13: Grandma Destruction"); +} + +public Action Command_TBWave14(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 14: Under The Weight"); +} + +public Action Command_TBWave15(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 15: Metal - Brute Justice Mode"); +} + +public Action Command_TBWave16(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 16: Exponential Entropy"); +} + +public Action Command_TBWave17(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 17: Locus"); +} + +public Action Command_TBWave18(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 18: Torn From The Heavens"); +} + +public Action Command_TBWave19(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 19: Metal"); +} + +public Action Command_TBWave20(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 20: Grandma Destruction"); +} + +public Action Command_TBWave21(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 21: Battle on the Big Bridge"); +} + +public Action Command_TacoBellFinished(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF YOU HAVE SUCCESSFULLY COMPLETED DOVAH'S ASS - TACO BELL EDITION! THE SERVER WILL RESTART IN 10 SECONDS."); + CreateTimer(10.0, Timer_RestartServer); +} + +//Check who died by what and announce it to chat. +public Action EventDeath(Event Spawn_Event, const char[] Spawn_Name, bool Spawn_Broadcast) +{ + int client = GetClientOfUserId(Spawn_Event.GetInt("userid")); + int attacker = GetClientOfUserId(Spawn_Event.GetInt("attacker")); + char weapon[32]; + Spawn_Event.GetString("weapon", weapon, sizeof(weapon)); + if (0 < client <= MaxClients && IsClientInGame(client)) + { + int damagebits = Spawn_Event.GetInt("damagebits"); + if ((damagebits & (1 << 0)) && !attacker) //DMG_CRUSH + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N was crushed by a \x07AA0000FALLING ROCK FROM OUTER SPACE\x07FFFFFF!", client); + } + + if ((damagebits & (1 << 3)) && !attacker) //DMG_BURN + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N was \x07AA0000MELTED\x07FFFFFF.", client); + } + + if ((damagebits & (1 << 4)) && !attacker) //DMG_VEHICLE (DMG_FREEZE) + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N was flattened out by a \x07AA0000TRAIN\x07FFFFFF!", client); + } + + if ((damagebits & (1 << 5)) && !attacker) //DMG_FALL + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N was \x07AA0000YEETED OUT INTO ORBIT\x07FFFFFF!", client); + int i = GetRandomInt(1, 16); + switch (i){ + case 1:{ + EmitSoundToAll(FALLSND01); + //ServerCommand("fb_fire FallSND01 PlaySound"); + } + case 2:{ + EmitSoundToAll(FALLSND02); + //ServerCommand("fb_fire FallSND02 PlaySound"); + } + case 3:{ + EmitSoundToAll(FALLSND03); + //ServerCommand("fb_fire FallSND03 PlaySound"); + } + case 4:{ + EmitSoundToAll(FALLSND04); + //ServerCommand("fb_fire FallSND04 PlaySound"); + } + case 5:{ + EmitSoundToAll(FALLSND05); + //ServerCommand("fb_fire FallSND05 PlaySound"); + } + case 6:{ + EmitSoundToAll(FALLSND06); + //ServerCommand("fb_fire FallSND06 PlaySound"); + } + case 7:{ + EmitSoundToAll(FALLSND07); + //ServerCommand("fb_fire FallSND07 PlaySound"); + } + case 8:{ + EmitSoundToAll(FALLSND08); + //ServerCommand("fb_fire FallSND08 PlaySound"); + } + case 9:{ + EmitSoundToAll(FALLSND09); + //ServerCommand("fb_fire FallSND09 PlaySound"); + } + case 10:{ + EmitSoundToAll(FALLSND0A); + //ServerCommand("fb_fire FallSND0A PlaySound"); + } + case 11:{ + EmitSoundToAll(FALLSND0B); + //ServerCommand("fb_fire FallSND0B PlaySound; fb_fire FB.BlueKirbTemplate ForceSpawn"); + } + case 12:{ + EmitSoundToAll(FALLSND0C); + //ServerCommand("fb_fire FallSND0C PlaySound"); + } + case 13:{ + EmitSoundToAll(FALLSND0D); + //ServerCommand("fb_fire FallSND0D PlaySound"); + } + case 14:{ + EmitSoundToAll(FALLSND0E); + //ServerCommand("fb_fire FallSND0E PlaySound"); + } + case 15:{ + EmitSoundToAll(FALLSND0F); + //ServerCommand("fb_fire FallSND0F PlaySound"); + } + case 16:{ + EmitSoundToAll(FALLSND10); + //ServerCommand("fb_fire FallSND10 PlaySound"); + } + } + } + + if ((damagebits & (1 << 6)) && !attacker) //DMG_BLAST + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N went \x07AA0000 KABOOM\x07FFFFFF!", client); + } + + if ((damagebits & (1 << 7)) && !attacker) //DMG_CLUB + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N is \x07AA0000CRASHING THE HINDENBURG\x07FFFFFF!!!", client); + } + + if ((damagebits & (1 << 8)) && !attacker) //DMG_SHOCK + { + PrintToChatAll("\x070000AA[\x07AA0000EXTERMINATUS\x070000AA]\x07FFFFFF Client %N has humliated themselves with an \x07AA0000incorrect \x07FFFFFFkey entry!", client); + int i = GetRandomInt(1, 16); + switch(i){ + case 1:{ + ServerCommand("fb_fire BG.Meteorites1 ForceSpawn; fb_meteorincoming; bg.meteorite1 StartForward 0 0.1"); + } + case 2:{ + CreateTimer(0.5, FBCodeFailTankHornSND); + ServerCommand("fb_fire FB.TankTrain TeleportToPathTrack Tank01; fb_fire FB.TankTrain StartForward 0 0.25; fb_fire FB.TankTrain SetSpeed 1 0.35; fb_fire FB.Tank Enable 0 1"); + } + case 3:{ + ServerCommand("fb_fire BG.Meteorites1 ForceSpawn; fb_meteorincoming; bg.meteorite1 StartForward 0 0.1"); + } + case 4:{ + EmitSoundToAll("ambient/alarms/train_horn_distant1.wav"); + ServerCommand("fb_fire TrainSND PlaySound; fb_fire TrainDamage Enable; fb_fire Train01 Enable; fb_trainincoming; fb_fire TrainTrain TeleportToPathTrack TrainTrack01; fb_fire TrainTrain StartForward 0 0.1"); + } + case 5:{ + CreateTimer(0.5, FBCodeFailTankHornSND); + ServerCommand("fb_fire FB.TankTrain TeleportToPathTrack Tank01; fb_fire FB.TankTrain StartForward 0 0.25; fb_fire FB.TankTrain SetSpeed 1 0.35; fb_fire FB.Tank Enable 0 1"); + } + case 6:{ + canTornado = true; + CreateTimer(1.0, SpawnTornado); + } + case 7:{ + ServerCommand("fb_meteorshower"); + canSENTMeteors = true; + CreateTimer(1.0, SENTMeteorTimer); + CreateTimer(30.0, DisableSENTMeteors); + } + case 8:{ + EmitSoundToAll("ambient/alarms/train_horn_distant1.wav"); + ServerCommand("fb_fire TrainSND PlaySound; fb_fire TrainDamage Enable; fb_fire Train01 Enable; fb_trainincoming; fb_fire TrainTrain TeleportToPathTrack TrainTrack01; fb_fire TrainTrain StartForward 0 0.1"); + } + case 9:{ + canTornado = true; + CreateTimer(1.0, SpawnTornado); + } + case 10:{ + ServerCommand("fb_fire BG.Meteorites1 ForceSpawn; fb_meteorincoming; bg.meteorite1 StartForward 0 0.1"); + } + case 11:{ + EmitSoundToAll("ambient/sawblade_impact1.wav"); + ServerCommand("fb_fire FB.Slice Enable; fb_fire FB.Slice Disable 0 1.0"); + } + case 12:{ + ServerCommand("fb_atomicbmbrain"); + canSENTNukes = true; + CreateTimer(1.0, SENTNukeTimer); + CreateTimer(30.0, DisableSENTNukes); + } + case 13:{ + ServerCommand("fb_meteorshower"); + canSENTMeteors = true; + CreateTimer(1.0, SENTMeteorTimer); + CreateTimer(30.0, DisableSENTMeteors); + } + case 14:{ + EmitSoundToAll("ambient/alarms/train_horn_distant1.wav"); + ServerCommand("fb_fire TrainSND PlaySound; fb_fire TrainDamage Enable; fb_fire Train01 Enable; fb_trainincoming; fb_fire TrainTrain TeleportToPathTrack TrainTrack01; fb_fire TrainTrain StartForward 0 0.1"); + } + case 15:{ + ServerCommand("fb_atomicbmbrain"); + canSENTNukes = true; + CreateTimer(1.0, SENTNukeTimer); + CreateTimer(30.0, DisableSENTNukes); + } + case 16:{ + CreateTimer(0.5, FBCodeFailTankHornSND); + ServerCommand("fb_fire FB.TankTrain TeleportToPathTrack Tank01; fb_fire FB.TankTrain StartForward 0 0.25; fb_fire FB.TankTrain SetSpeed 1 0.35; fb_fire FB.Tank Enable 0 1"); + } + } + } + + if ((damagebits & (1 << 9)) && !attacker) //DMG_SONIC + { + PrintToChatAll("\x070000AA[\x07AA0000EXTERMINATUS\x070000AA]\x07FFFFFF Client %N has sacrificed themselves with a \x0700AA00correct \x07FFFFFFkey entry! Prepare your anus!", client); + } + + if ((damagebits & (1 << 10)) && !attacker) //DMG_ENERGYBEAM + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N has been vaporized by a \x07AA0000HIGH ENERGY PHOTON BEAM\x07FFFFFF!", client); + } + + if ((damagebits & (1 << 14)) && !attacker) //DMG_DROWN + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N \x07AA0000DROWNED\x07FFFFFF.", client); + } + + if ((damagebits & (1 << 15)) && !attacker) //DMG_PARALYZE + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N has been crushed by a \x070000AAMYSTERIOUS BLUE BALL\x07FFFFFF!", client); + } + + if ((damagebits & (1 << 16)) && !attacker) //DMG_NERVEGAS + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N has been \x07AA0000SLICED TO RIBBONS\x07FFFFFF!", client); + } + + if ((damagebits & (1 << 17)) && !attacker) //DMG_POISON + { + ServerCommand("sm_psay %d \x07FF0000[\x0700FF00ADMIN\x07FF0000] \x07AAAAAAPlease don't sit IDLE in the FC Tavern. Repeated offenses may result in a kick."); + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N was killed for standing in the Tavern instead of helping their team!", client); + } + + if ((damagebits & (1 << 18)) && !attacker) //DMG_RADIATION + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N was blown away by a \x07AA0000NUCLEAR EXPLOSION\x07FFFFFF!", client); + } + + if ((damagebits & (1 << 19)) && !attacker) //DMG_DROWNRECOVER + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N experienced \x07AA0000TACO BELL\x07FFFFFF!", client); + } + + if ((damagebits & (1 << 20)) && !attacker) //DMG_ACID + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N has been crushed by a \x0700AA00FALLING GOOBBUE FROM OUTER SPACE\x07FFFFFF!", client); + } + } + return Plugin_Handled; +} + +//Silence cvar changes to minimize chat spam. +public Action Event_Cvar(Event event, const char[] name, bool dontBroadcast) +{ + event.BroadcastDisabled = true; +} +//When we win +public Action EventWaveComplete(Event Spawn_Event, const char[] Spawn_Name, bool Spawn_Broadcast) +{ + bgmlock1 = true; + bgmlock2 = true; + bgmlock3 = true; + bgmlock4 = true; + bgmlock5 = true; + bgmlock6 = true; + bgmlock7 = true; + bgmlock8 = true; + canHWBoss = false; + canTornado = false; + isWave = false; + bombStatusMax = 7; + bombStatus = 5; + bombsPushed = 0; + SelectBGM(); + PrintToChatAll("\x0700FF00[CORE] \x07FFFFFFYou've defeated the wave!"); + ServerCommand("fb_fire BTN.Sacrificial* Disable; fb_fire BTN.Sacrificial* Color 0"); +} + +//Announce when we are in danger. +public Action EventWarning(Event Spawn_Event, const char[] Spawn_Name, bool Spawn_Broadcast) +{ + PrintToChatAll("\x070000AA[\x07AA0000WARN\x070000AA]\x07AA0000 WARNING\x07FFFFFF: \x07AA0000DOVAH'S ASS IS ABOUT TO BE DEPLOYED!!!"); +} +//When we fail +public Action EventWaveFailed(Event Spawn_Event, const char[] Spawn_Name, bool Spawn_Broadcast){ + bgmlock1 = true; + bgmlock2 = true; + bgmlock3 = true; + bgmlock4 = true; + bgmlock5 = true; + bgmlock6 = true; + bgmlock7 = true; + bgmlock8 = true; + canHWBoss = false; + canTornado = false; + isWave = false; + bombStatusMax = 7; + bombStatus = 5; + bombsPushed = 0; + SelectBGM(); + PrintToChatAll("\x0700FF00[CORE] \x07FFFFFFWave set/reset success!"); + ServerCommand("fb_fire BTN.Sacrificial* Disable; fb_fire BTN.Sacrificial* Color 0"); +} +//Announce the bomb has been reset by client %N. +public Action EventReset(Event Spawn_Event, const char[] Spawn_Name, bool Spawn_Broadcast) +{ + int client = Spawn_Event.GetInt("player"); + if (0 < client <= MaxClients && IsClientInGame(client)) + { + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF Client \x0700AA00%N\x07FFFFFF has reset the ass!", client); + } + return Plugin_Handled; +} + +//Used by various entities to jump us to the previous wave. +public Action Command_JumpToPrevWave(int args) +{ + int ent = FindEntityByClassname(-1, "tf_objective_resource"); + if(ent == -1) + { + LogMessage("tf_objective_resource not found"); + return; + } + + int current_wave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineWaveCount")); + int max_wave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineMaxWaveCount")); + int prev_wave = current_wave - 1; + if(prev_wave >= max_wave) + { + PrintToChatAll("\x07AA0000[ERROR] \x07FFFFFFHOW THE HELL DID WE GET HERE?!"); + return; + } + + if(prev_wave < 1) + { + PrintToChatAll("\x07AA0000[ERROR] \x07FFFFFFWE CAN'T JUMP TO WAVE 0, WHY WOULD YOU TRY THAT??"); + return; + } + JumpToWave(prev_wave); +} + +//Used by various entities to jump us to the next wave. +public Action Command_JumpToNextWave(int args) +{ + int ent = FindEntityByClassname(-1, "tf_objective_resource"); + if(ent == -1) + { + LogMessage("tf_objective_resource not found"); + return; + } + + int current_wave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineWaveCount")); + int max_wave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineMaxWaveCount")); + int next_wave = current_wave + 1; + if(next_wave > max_wave) + { + ServerCommand("fb_forcevictory"); + return; + } + JumpToWave(next_wave); +} + +//Jump to the wave. +public Action JumpToWave(int wave_number) +{ + int flags = GetCommandFlags("tf_mvm_jump_to_wave"); + SetCommandFlags("tf_mvm_jump_to_wave", flags & ~FCVAR_CHEAT); + ServerCommand("tf_mvm_jump_to_wave %d", wave_number); + FakeClientCommand(0, ""); + SetCommandFlags("tf_mvm_jump_to_wave", flags|FCVAR_CHEAT); +} + +//Timer to restart the server. +public Action Timer_RestartServer(Handle timer) +{ + ServerCommand("_restart"); +} + +//Handle FB Operator Requests via entfire +public Action Command_FBFire(int args) +{ + char arg1[128], arg2[128], arg3[32], arg4[8]; + float flDelay; + GetCmdArg(1, arg1, sizeof(arg1)); + GetCmdArg(2, arg2, sizeof(arg2)); + GetCmdArg(3, arg3, sizeof(arg3)); + GetCmdArg(4, arg4, sizeof(arg4)); + flDelay = StringToFloat(arg4); + FireEntityInput(arg1, arg2, arg3, flDelay); + return Plugin_Handled; +} + +//Create a temp entity and fire an input +public Action FireEntityInput(char[] strTargetname, char[] strInput, char[] strParameter, float flDelay) +{ + char strBuffer[255]; + Format(strBuffer, sizeof(strBuffer), "OnUser1 %s:%s:%s:%f:1", strTargetname, strInput, strParameter, flDelay); + PrintToChatAll("\x0700FF00[CORE] \x07FFFFFF Firing entity %s with input %s , a parameter override of %s , and delay of %f ...", strTargetname, strInput, strParameter, flDelay); + int entity = CreateEntityByName("info_target"); + if(IsValidEdict(entity)) + { + DispatchSpawn(entity); + ActivateEntity(entity); + SetVariantString(strBuffer); + AcceptEntityInput(entity, "AddOutput"); + AcceptEntityInput(entity, "FireUser1"); + CreateTimer(0.0, DeleteEdict, entity); + return Plugin_Continue; + } + return Plugin_Handled; +} + +//Remove edict allocated by temp entity +public Action DeleteEdict(Handle timer, any entity) +{ + if(IsValidEdict(entity)) RemoveEdict(entity); + return Plugin_Stop; +} diff --git a/scripting/FallingBack.sp b/scripting/FallingBack.sp new file mode 100644 index 0000000..410132f --- /dev/null +++ b/scripting/FallingBack.sp @@ -0,0 +1,2405 @@ +#include +#include +#pragma newdecls required +#pragma semicolon 1 +bool canHWBoss = false; +bool canSENTMeteors = false; +bool canSENTNukes = false; +bool canSENTShark = false; +bool canSENTStars = false; +bool canTornado = false; +bool isWave = false; +bool tornado = false; +bool bgmlock1 = true; +bool bgmlock2 = true; +bool bgmlock3 = true; +bool bgmlock4 = true; +bool bgmlock5 = true; +bool bgmlock6 = true; +bool bgmlock7 = true; +bool bgmlock8 = true; +char BELL[32] = "fartsy/misc/bell.wav"; +char BGM1[32] = "fartsy/ffxiv/bgm/locus.mp3"; +char BGM2[32] = "fartsy/ffxiv/bgm/metal.mp3"; +char BGM3[64] = "fartsy/ffxiv/bgm/exponentialentropy.mp3"; +char BGM4[64] = "fartsy/ffxiv/bgm/tornfromtheheavens.mp3"; +char BGM5[64] = "fartsy/ffxiv/bgm/metalbrutejusticemode.mp3"; +char BGM6[64] = "fartsy/ffxiv/bgm/grandmadestruction.mp3"; +char BGM7[64] = "fartsy/ffxiv/bgm/revengetwofold.mp3"; +char BGM8[64] = "fartsy/ffxiv/bgm/undertheweight.mp3"; +char BGM1Title[32] = "FFXIV - Locus"; +char BGM2Title[32] = "FFXIV - Metal"; +char BGM3Title[32] = "FFXIV - Exponential Entropy"; +char BGM4Title[32] = "FFXIV - Torn From the Heavens"; +char BGM5Title[64] = "FFXIV - Metal: Brute Justice Mode"; +char BGM6Title[32] = "FFXIV - Grandma (Destruction)"; +char BGM7Title[32] = "FFXIV - Revenge Twofold"; +char BGM8Title[32] = "FFXIV - Under the Weight"; +char CLOCKTICK[32] = "fartsy/misc/clock_tick.wav"; +char COUNTDOWN[32] = "fartsy/misc/countdown.wav"; +char CRUSADERATTACK[32] = "fartsy/fallingback/attack.mp3"; +char curSong[64] = "null"; +char DEFAULTBGM1[64] = "fartsy/ffxiv/bgm/TheSilentRegardOfStars.mp3"; +char DEFAULTBGM2[64] = "fartsy/ffxiv/bgm/KnowledgeNeverSleeps.mp3"; +char DEFAULTBGM1Title[64] = "FFXIV - The Silent Regard of Stars"; +char DEFAULTBGM2Title[64] = "FFXIV - Knowledge Never Sleeps"; +char FALLSND01[32] = "vo/l4d2/billfall02.mp3"; +char FALLSND02[32] = "vo/l4d2/coachfall02.mp3"; +char FALLSND03[32] = "vo/l4d2/ellisfall01.mp3"; +char FALLSND04[32] = "vo/l4d2/francisfall02.mp3"; +char FALLSND05[32] = "vo/l4d2/louisfall01.mp3"; +char FALLSND06[32] = "vo/l4d2/louisfall03.mp3"; +char FALLSND07[32] = "vo/l4d2/nickfall01.mp3"; +char FALLSND08[32] = "vo/l4d2/zoeyfall01.mp3"; +char FALLSND09[32] = "vo/ddd/woahhh.mp3"; +char FALLSND0A[32] = "vo/jigglypuff/jigglypuff.mp3"; +char FALLSND0B[32] = "vo/kirby/eeeahhhh.mp3"; +char FALLSND0C[32] = "vo/luigi/ohohohohoo.mp3"; +char FALLSND0D[32] = "vo/mario/wahahahaha.mp3"; +char FALLSND0E[32] = "vo/pika/pikapika.mp3"; +char FALLSND0F[32] = "vo/wario/wheee.mp3"; +char FALLSND10[32] = "vo/mario/wowww.mp3"; +char GLOBALTHUNDER01[32] = "fartsy/weather/thunder1.wav"; +char GLOBALTHUNDER02[32] = "fartsy/weather/thunder2.wav"; +char GLOBALTHUNDER03[32] = "fartsy/weather/thunder3.wav"; +char GLOBALTHUNDER04[32] = "fartsy/weather/thunder4.wav"; +char GLOBALTHUNDER05[32] = "fartsy/weather/thunder5.wav"; +char GLOBALTHUNDER06[32] = "fartsy/weather/thunder6.wav"; +char GLOBALTHUNDER07[32] = "fartsy/weather/thunder7.wav"; +char GLOBALTHUNDER08[32] = "fartsy/weather/thunder8.wav"; +char GOOBBUEINCOMING[32] = "vo/fartsy/goobbue.mp3"; +char SHARKSND01[32] = "fartsy/memes/babyshark/baby.mp3"; +char SHARKSND02[64] = "fartsy/memes/babyshark/baby02.mp3"; +char SHARKSND03[64] = "fartsy/memes/babyshark/doot01.mp3"; +char SHARKSND04[64] = "fartsy/memes/babyshark/doot02.mp3"; +char SHARKSND05[64] = "fartsy/memes/babyshark/doot03.mp3"; +char SHARKSND06[64] = "fartsy/memes/babyshark/doot04.mp3"; +char SHARKSND07[64] = "fartsy/memes/babyshark/shark.mp3"; +char SHARKSND08[64] = "fartsy/memes/babyshark/shark02.mp3"; +char STRONGMAN[32] = "fartsy/misc/strongman_bell.wav"; +char TRIGGERSCORE[32] = "fartsy/misc/triggerscore.wav"; +char WTFBOOM[32] = "fartsy/wtfboom.mp3"; +float HWNMin = 210.0; +float HWNMax = 380.0; +int BGMSNDLVL = 90; +int CodeEntry = 0; +int DEFBGMSNDLVL = 40; +int bombStatus = 0; +int bombStatusMax = 0; +int explodeType = 0; +int sacPoints = 0; +int sacPointsMax = 60; +int SNDCHAN = 6; +public Plugin myinfo = +{ + name = "Dovah's Ass - Framework", + author = "Fartsy#8998", + description = "Framework for Dovah's Ass", + version = "3.3.5", + url = "https://forums.firehostredux.com" +}; + +public void OnPluginStart() +{ + PrecacheSound(BELL, true), + PrecacheSound(BGM1, true), + PrecacheSound(BGM2, true), + PrecacheSound(BGM3, true), + PrecacheSound(BGM4, true), + PrecacheSound(BGM5, true), + PrecacheSound(BGM6, true), + PrecacheSound(BGM7, true), + PrecacheSound(BGM8, true), + PrecacheSound(CLOCKTICK, true), + PrecacheSound(COUNTDOWN, true), + PrecacheSound(CRUSADERATTACK, true), + PrecacheSound(DEFAULTBGM1, true), + PrecacheSound(DEFAULTBGM2, true), + PrecacheSound(FALLSND01, true), + PrecacheSound(FALLSND02, true), + PrecacheSound(FALLSND03, true), + PrecacheSound(FALLSND04, true), + PrecacheSound(FALLSND05, true), + PrecacheSound(FALLSND06, true), + PrecacheSound(FALLSND07, true), + PrecacheSound(FALLSND08, true), + PrecacheSound(FALLSND09, true), + PrecacheSound(FALLSND0A, true), + PrecacheSound(FALLSND0B, true), + PrecacheSound(FALLSND0C, true), + PrecacheSound(FALLSND0D, true), + PrecacheSound(FALLSND0E, true), + PrecacheSound(FALLSND0F, true), + PrecacheSound(FALLSND10, true), + PrecacheSound(GLOBALTHUNDER01, true), + PrecacheSound(GLOBALTHUNDER02, true), + PrecacheSound(GLOBALTHUNDER03, true), + PrecacheSound(GLOBALTHUNDER04, true), + PrecacheSound(GLOBALTHUNDER05, true), + PrecacheSound(GLOBALTHUNDER06, true), + PrecacheSound(GLOBALTHUNDER07, true), + PrecacheSound(GLOBALTHUNDER08, true), + PrecacheSound(GOOBBUEINCOMING, true), + PrecacheSound(SHARKSND01, true), + PrecacheSound(SHARKSND02, true), + PrecacheSound(SHARKSND03, true), + PrecacheSound(SHARKSND04, true), + PrecacheSound(SHARKSND05, true), + PrecacheSound(SHARKSND06, true), + PrecacheSound(SHARKSND07, true), + PrecacheSound(SHARKSND08, true), + PrecacheSound(STRONGMAN, true), + PrecacheSound(TRIGGERSCORE, true), + PrecacheSound(WTFBOOM, true), + PrecacheSound("fartsy/fallingback/bgm.mp3", true), + RegServerCmd("fb_operator", Command_Operator, "Serverside only. Does nothing when executed as client."), + RegServerCmd("tacobell_wave01", Command_TBWave01,"Taco Bell - Wave One"), + RegServerCmd("tacobell_finished", Command_TacoBellFinished, "TacoBell has been completed!"), + RegConsoleCmd("sm_bombstatus", Command_FBBombStatus, "Check bomb status"), + RegConsoleCmd("sm_sacstatus", Command_FBSacStatus, "Check sacrifice points status"), + RegConsoleCmd("sm_song", Command_GetCurrentSong, "Get current song name"), + HookEvent("player_death", EventDeath), + HookEvent("server_cvar", Event_Cvar, EventHookMode_Pre), + HookEvent("mvm_wave_complete", EventWaveComplete), + HookEvent("mvm_wave_failed", EventWaveFailed), + HookEvent("mvm_bomb_alarm_triggered", EventWarning), + HookEvent("mvm_bomb_reset_by_player", EventReset); +} + +//Now that command definitions are done, lets make some things happen. +public void OnMapStart() +{ + FireEntityInput("BombStatus", "disable", "", 0.0), + SelectBGM(); +} +//Select background music +public Action SelectBGM() +{ + StopCurSong(); + CreateTimer(1.0, PerformAdverts); + int BGM = GetRandomInt(1, 2); + switch(BGM){ + case 1:{ + EmitSoundToAll(DEFAULTBGM1, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = DEFAULTBGM1; + PrintToServer("Creating timer for The Silent Regard of Stars. Enjoy the music!"); + CreateTimer(137.75, RefireBGM); + } + case 2:{ + EmitSoundToAll(DEFAULTBGM2, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = DEFAULTBGM2; + PrintToServer("Creating timer for Knowledge Never Sleeps. Enjoy the music!"); + CreateTimer(235.5, RefireBGMAlt); + } + } +} +//Stop current song +public Action StopCurSong(){ + for(int i=1;i<=MaxClients;i++) + { + StopSound(i, SNDCHAN, curSong); + } + return Plugin_Handled; +} + +//Timers +//Adverts for tips/tricks +public Action PerformAdverts(Handle timer){ + if (!isWave){ + CreateTimer (180.0, PerformAdverts); + int i = GetRandomInt(1, 5); + switch (i){ + case 1:{ + PrintToChatAll("\x07800080[\x0780AAAACORE\x07800080]\x07FFFFFF We have a Discord server: \x0700AA00https://discord.com/invite/SkHaeMH"); + } + case 2:{ + PrintToChatAll("\x07800080[\x0780AAAACORE\x07800080]\x07FFFFFF Remember to buy your upgrades using \x0700AA00!buy"); + } + case 3:{ + PrintToChatAll("\x07800080[\x0780AAAACORE\x07800080]\x07FFFFFF If this is your first time here, please run console command \x0700AA00snd_restart \x07FFFFFFfor safety. Otherwise, you might \x07FF0000crash\x07FFFFFF!"); + } + case 4:{ + PrintToChatAll("\x07800080[\x0780AAAACORE\x07800080]\x07FFFFFF Advanced users may quick buy upgrades using \x0700AA00!qbuy"); + } + case 5:{ + PrintToChatAll("\x07800080[\x0780AAAACORE\x07800080]\x07FFFFFF Don't forget to buy \x0700AA00protection upgrades\x07FFFFFF and \x0700AA00ammo regen\x07FFFFFF (if applicable)!"); + } + } + } + return Plugin_Stop; +} +//BGM (Defaults) +public Action RefireBGM(Handle timer) +{ + if (!isWave){ + SelectBGM(); + return Plugin_Stop; + } + return Plugin_Stop; +} +//BGM Default2 +public Action RefireBGMAlt(Handle timer) +{ + if (!isWave){ + SelectBGM(); + return Plugin_Stop; + } + return Plugin_Stop; +} + +//BGM (Locus) +public Action RefireLocus(Handle timer) +{ + if (!bgmlock1){ + StopCurSong(); + EmitSoundToAll(BGM1, _, SNDCHAN, DEFBGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM1; + CreateTimer(229.25, RefireLocus); + } + return Plugin_Stop; +} + +//BGM (Metal) +public Action RefireMetal(Handle timer) +{ + if (!bgmlock2){ + StopCurSong(); + EmitSoundToAll(BGM2, _, SNDCHAN, DEFBGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM2; + CreateTimer(153.95, RefireMetal); + } + return Plugin_Stop; +} + +//BGM (Exponential Entropy) +public Action RefireEntropy(Handle timer) +{ + if (!bgmlock3){ + StopCurSong(); + EmitSoundToAll(BGM3, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM3; + CreateTimer(166.85, RefireEntropy); + } + return Plugin_Stop; +} + +//BGM (Torn From the Heavens) +public Action RefireTorn(Handle timer) +{ + if (!bgmlock4){ + StopCurSong(); + EmitSoundToAll(BGM4, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM4; + CreateTimer(122.25, RefireTorn); + } + return Plugin_Stop; +} + +//BGM (Brute Justice Mode) +public Action RefireBJMode(Handle timer) +{ + if (!bgmlock5){ + StopCurSong(); + EmitSoundToAll(BGM5, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM5; + CreateTimer(131.75, RefireBJMode); + } + return Plugin_Stop; +} + +//BGM (Grandma Destruction) +public Action RefireGrandma(Handle timer) +{ + if (!bgmlock6){ + StopCurSong(); + EmitSoundToAll(BGM6, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM6; + CreateTimer(323.95, RefireGrandma); + } + return Plugin_Stop; +} + +//BGM (Revenge Twofold) +public Action RefireRevenge2F(Handle timer){ + if (!bgmlock7){ + StopCurSong(); + EmitSoundToAll(BGM7, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM7; + CreateTimer(133.25, RefireRevenge2F); + } + return Plugin_Stop; +} + +//BGM (Under The Weight) +public Action RefireUnderTW(Handle timer){ + if (!bgmlock8){ + StopCurSong(); + EmitSoundToAll(BGM8, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM8; + CreateTimer(313.85, RefireUnderTW); + } + return Plugin_Stop; +} + +//Shark Timer +public Action SharkTimer(Handle timer){ + if (canSENTShark){ + FireEntityInput("SentSharkTorpedo", "ForceSpawn", "", 0.0); + float f = GetRandomFloat(2.0, 5.0); + CreateTimer(f, SharkTimer); + int i = GetRandomInt(1, 8); + switch(i){ + case 1:{ + EmitSoundToAll(SHARKSND01); + } + case 2:{ + EmitSoundToAll(SHARKSND02); + } + case 3:{ + EmitSoundToAll(SHARKSND03); + } + case 4:{ + EmitSoundToAll(SHARKSND04); + } + case 5:{ + EmitSoundToAll(SHARKSND05); + } + case 6:{ + EmitSoundToAll(SHARKSND06); + } + case 7:{ + EmitSoundToAll(SHARKSND07); + } + case 8:{ + EmitSoundToAll(SHARKSND08); + } + } + return Plugin_Handled; + } + return Plugin_Stop; +} + +//Storm +public Action RefireStorm(Handle timer){ + if (isWave){ + float f = GetRandomFloat(7.0, 17.0); + CreateTimer(f, RefireStorm); + StrikeLightning(); + int Thunder = GetRandomInt(1, 16); + switch (Thunder){ + case 1:{ + EmitSoundToAll(GLOBALTHUNDER01); + FireEntityInput("LightningHurt00", "Enable", "", 0.0), + FireEntityInput("LightningHurt00", "Disable", "", 0.07); + } + case 2:{ + EmitSoundToAll(GLOBALTHUNDER02); + FireEntityInput("LightningHurt01", "Enable", "", 0.0), + FireEntityInput("LightningHurt01", "Disable", "", 0.07); + } + case 3:{ + EmitSoundToAll(GLOBALTHUNDER03); + FireEntityInput("LightningHurt02", "Enable", "", 0.0), + FireEntityInput("LightningHurt02", "Disable", "", 0.07); + } + case 4:{ + EmitSoundToAll(GLOBALTHUNDER04); + FireEntityInput("LightningHurt03", "Enable", "", 0.0), + FireEntityInput("LightningHurt03", "Disable", "", 0.07); + } + case 5:{ + EmitSoundToAll(GLOBALTHUNDER05); + FireEntityInput("LightningHurt04", "Enable", "", 0.0), + FireEntityInput("LightningHurt04", "Disable", "", 0.07); + } + case 6:{ + EmitSoundToAll(GLOBALTHUNDER06); + FireEntityInput("LightningHurt05", "Enable", "", 0.0), + FireEntityInput("LightningHurt05", "Disable", "", 0.07); + } + case 7:{ + EmitSoundToAll(GLOBALTHUNDER07); + FireEntityInput("LightningHurt06", "Enable", "", 0.0), + FireEntityInput("LightningHurt06", "Disable", "", 0.07); + } + case 8:{ + EmitSoundToAll(GLOBALTHUNDER08); + FireEntityInput("LightningHurt07", "Enable", "", 0.0), + FireEntityInput("LightningHurt07", "Disable", "", 0.07); + } + case 9:{ + EmitSoundToAll(GLOBALTHUNDER01); + FireEntityInput("LightningHurt08", "Enable", "", 0.0), + FireEntityInput("LightningHurt08", "Disable", "", 0.07); + } + case 10:{ + EmitSoundToAll(GLOBALTHUNDER02); + FireEntityInput("LightningHurt09", "Enable", "", 0.0), + FireEntityInput("LightningHurt09", "Disable", "", 0.07); + } + case 11:{ + EmitSoundToAll(GLOBALTHUNDER03); + FireEntityInput("LightningHurt0A", "Enable", "", 0.0), + FireEntityInput("LightningHurt0A", "Disable", "", 0.07); + } + case 12:{ + EmitSoundToAll(GLOBALTHUNDER04); + FireEntityInput("LightningHurt0B", "Enable", "", 0.0), + FireEntityInput("LightningHurt0B", "Disable", "", 0.07); + } + case 13:{ + EmitSoundToAll(GLOBALTHUNDER05); + FireEntityInput("LightningHurt0C", "Enable", "", 0.0), + FireEntityInput("LightningHurt0C", "Disable", "", 0.07); + } + case 14:{ + EmitSoundToAll(GLOBALTHUNDER06); + FireEntityInput("LightningHurt0D", "Enable", "", 0.0), + FireEntityInput("LightningHurt0D", "Disable", "", 0.07); + } + case 15:{ + EmitSoundToAll(GLOBALTHUNDER07); + FireEntityInput("LightningHurt0E", "Enable", "", 0.0), + FireEntityInput("LightningHurt0E", "Disable", "", 0.07); + } + case 16:{ + EmitSoundToAll(GLOBALTHUNDER08); + FireEntityInput("LightningHurt0F", "Enable", "", 0.0), + FireEntityInput("LightningHurt0F", "Disable", "", 0.07); + } + } + } +} + +//Strike Lightning +public Action StrikeLightning(){ + FireEntityInput("lightning", "TurnOn", "", 0.0), + FireEntityInput("weather", "Skin", "4", 0.0), + FireEntityInput("value", "TurnOff", "", 0.0), + FireEntityInput("LightningLaser", "TurnOn", "", 0.0), + FireEntityInput("lightning", "TurnOff", "", 0.1), + FireEntityInput("weather", "Skin", "3", 0.1), + FireEntityInput("LightningLaser", "TurnOff", "", 0.1), + FireEntityInput("lightning", "TurnOn", "", 0.17), + FireEntityInput("weather", "Skin", "4", 0.17), + FireEntityInput("LightningLaser", "TurnOn", "", 0.17), + FireEntityInput("lightning", "TurnOff", "", 0.25), + FireEntityInput("weather", "Skin", "3", 0.25), + FireEntityInput("LightningLaser", "TurnOff", "", 0.25); +} + +//Allow Tornadoes to Spawn +public Action ActivateTornadoTimer(){ + if (isWave && canTornado){ + float f = GetRandomFloat(210.0, 500.0); + CreateTimer(f, SpawnTornado); + } + return Plugin_Stop; +} + +//Spawn the tornado. +public Action SpawnTornado(Handle timer){ + if (isWave && canTornado && !tornado){ + FireEntityInput("TornadoKill", "Enable", "", 0.0), + FireEntityInput("tornadobutton", "Lock", "", 0.0), + FireEntityInput("tornadof1", "start", "", 20.0), + FireEntityInput("shaketriggerf1", "Enable", "", 20.0), + FireEntityInput("tornadowindf1", "PlaySound", "", 20.0), + FireEntityInput("tornadof1wind", "Enable", "", 21.50); + tornado = true; + float f = GetRandomFloat(60.0, 120.0); + CreateTimer(f, DespawnTornado); + } + return Plugin_Stop; +} + +//After a predetermined time, despawn the tornado. +public Action DespawnTornado(Handle timer){ + KillTornado(); + ActivateTornadoTimer(); +} + +//Despawns the tornado. +public Action KillTornado(){ + if (tornado){ + FireEntityInput("tornadof1", "stop", "", 0.0), + FireEntityInput("TornadoKill", "Disable", "", 0.0), + FireEntityInput("tornadof1wind", "Disable", "", 0.0), + FireEntityInput("tornadowindf1", "StopSound", "", 0.0), + FireEntityInput("shaketriggerf1", "Disable", "", 0.0), + FireEntityInput("tornadobutton", "Unlock", "", 30.0); + tornado = false; + } + return Plugin_Stop; +} + +//FB UnlockTimer (Unlocks FC Code Entry +public Action UnlockTimer (Handle timer){ + if(isWave){ + FireEntityInput("FB.KP*", "Unlock", "", 0.0); + EmitSoundToAll(BELL); + } + return Plugin_Stop; +} + +//SpecTimer +public Action SpecTimer(Handle timer){ + int i = GetRandomInt(1, 6); + switch (i){ + case 1:{ + FireEntityInput("Spec.*", "Disable", "", 0.0), + FireEntityInput("Spec.Goobbue", "Enable", "", 0.1), + PrintToChatAll("\x070000AA Legend tells of a Goobbue sproutling somewhere nearby..."); + } + case 2:{ + FireEntityInput("Spec.*", "Disable", "", 0.0), + FireEntityInput("Spec.Waffle", "Enable", "", 0.1), + PrintToChatAll("\x0700A0A0Don't eat THESE..."); + } + case 3:{ + FireEntityInput("Spec.*", "Disable", "", 0.0), + FireEntityInput("Spec.Burrito", "Enable", "", 0.1), + PrintToChatAll("\x07A00000What's worse than Taco Bell?"); + } + case 4:{ + FireEntityInput("Spec.*", "Disable", "", 0.0), + FireEntityInput("Spec.Shroom", "Enable", "", 0.1), + PrintToChatAll("\x07DD0000M\x07FFFFFFA\x07DD0000R\x07FFFFFFI\x07DD0000O\x07FFFFFF time!"); + } + case 5:{ + FireEntityInput("Spec.*", "Disable", "", 0.0), + FireEntityInput("Spec.BlueBall", "Enable", "", 0.1), + PrintToChatAll("A \x070000AA Blue Ball \x07FFFFFF lurks from afar..."); + } + case 6:{ + FireEntityInput("Spec.*", "Enable", "", 0.0), + PrintToChatAll("\x07AA00AAIs it a miracle? Is it chaos? WHO KNOWWWWWWS"); + } + } + float spDelay = GetRandomFloat(10.0, 30.0); + CreateTimer(spDelay, SpecTimer); + return Plugin_Stop; +} + +//SENTMeteor (Scripted Entity Meteors) +public Action SENTMeteorTimer(Handle timer){ + if(canSENTMeteors){ + int i = GetRandomInt(1, 8); + switch(i){ + case 1:{ + FireEntityInput("FB.SentMeteor01", "ForceSpawn", "", 0.0); + } + case 2:{ + FireEntityInput("FB.SentMeteor02", "ForceSpawn", "", 0.0); + } + case 3:{ + FireEntityInput("FB.SentMeteor03", "ForceSpawn", "", 0.0); + } + case 4:{ + FireEntityInput("FB.SentMeteor04", "ForceSpawn", "", 0.0); + } + case 5:{ + FireEntityInput("FB.SentMeteor05", "ForceSpawn", "", 0.0); + } + case 6:{ + FireEntityInput("FB.SentMeteor06", "ForceSpawn", "", 0.0); + } + case 7:{ + FireEntityInput("FB.SentMeteor07", "ForceSpawn", "", 0.0); + } + case 8:{ + FireEntityInput("FB.SentMeteor08", "ForceSpawn", "", 0.0); + } + } + } + return Plugin_Stop; +} + +public Action DisableSENTMeteors(Handle timer){ + canSENTMeteors = false; + return Plugin_Stop; +} + +//SENTNukes (Scripted Entity Nukes) +public Action SENTNukeTimer(Handle timer){ + if(canSENTNukes){ + FireEntityInput("FB.DropNuke", "PlaySound", "", 0.0); + int i = GetRandomInt(1, 8); + switch(i){ + case 1:{ + FireEntityInput("FB.SentNuke01", "ForceSpawn", "", 0.0); + } + case 2:{ + FireEntityInput("FB.SentNuke02", "ForceSpawn", "", 0.0); + } + case 3:{ + FireEntityInput("FB.SentNuke03", "ForceSpawn", "", 0.0); + } + case 4:{ + FireEntityInput("FB.SentNuke04", "ForceSpawn", "", 0.0); + } + case 5:{ + FireEntityInput("FB.SentNuke05", "ForceSpawn", "", 0.0); + } + case 6:{ + FireEntityInput("FB.SentNuke06", "ForceSpawn", "", 0.0); + } + case 7:{ + FireEntityInput("FB.SentNuke07", "ForceSpawn", "", 0.0); + } + case 8:{ + FireEntityInput("FB.SentNuke08", "ForceSpawn", "", 0.0); + } + } + float f = GetRandomFloat(1.5, 3.0); + CreateTimer(f, SENTNukeTimer); + } + return Plugin_Stop; +} + +public Action DisableSENTNukes(Handle timer){ + canSENTNukes = false; + return Plugin_Stop; +} + +//SENTStars (Scripted Entity Stars) +public Action SENTStarTimer(Handle timer){ + if(canSENTStars){ + int i = GetRandomInt(1, 8); + switch(i){ + case 1:{ + FireEntityInput("FB.SentStar01", "ForceSpawn", "", 0.0); + } + case 2:{ + FireEntityInput("FB.SentStar02", "ForceSpawn", "", 0.0); + } + case 3:{ + FireEntityInput("FB.SentStar03", "ForceSpawn", "", 0.0); + } + case 4:{ + FireEntityInput("FB.SentStar04", "ForceSpawn", "", 0.0); + } + case 5:{ + FireEntityInput("FB.SentStar05", "ForceSpawn", "", 0.0); + } + case 6:{ + FireEntityInput("FB.SentStar06", "ForceSpawn", "", 0.0); + } + case 7:{ + FireEntityInput("FB.SentStar07", "ForceSpawn", "", 0.0); + } + case 8:{ + FireEntityInput("FB.SentStar08", "ForceSpawn", "", 0.0); + } + } + float f = GetRandomFloat(0.75, 1.5); + CreateTimer(f, SENTStarTimer); + } +} +public Action SENTStarDisable(Handle timer){ + canSENTStars = false; + return Plugin_Handled; +} + +//TankHornSND because why not when code entry fails??? +public Action FBCodeFailTankHornSND(Handle timer){ + EmitSoundToAll("mvm/mvm_tank_horn.wav"); + return Plugin_Stop; +} + +//CRUSADERATTACKTimer for Crusader +public Action CRUSADERATTACKTimer(Handle timer){ + EmitSoundToAll(CRUSADERATTACK); + return Plugin_Handled; +} + +//WTFBOOMTimer for Crusader +public Action WTFBOOMTimer(Handle timer){ + EmitSoundToAll(WTFBOOM); + return Plugin_Handled; +} + +//Halloween Bosses +public Action HWBosses(Handle timer){ + if(isWave && canHWBoss){ + int i = GetRandomInt(1, 10); + switch(i){ + case 1:{ + FireEntityInput("hhh_maker", "ForceSpawn", "", 0.0), + FireEntityInput("hhh_maker2", "ForceSpawn", "", 0.0); + } + case 2:{ + FireEntityInput("hhh_maker2", "ForceSpawn", "", 0.0); + } + case 3:{ + + FireEntityInput("hhh_maker2", "ForceSpawn", "", 0.0), + FireEntityInput("SkeleSpawner", "Enable", "", 0.0), + FireEntityInput("SkeleSpawner", "Disable", "", 10.0); + } + case 4:{ + FireEntityInput("SkeleSpawner", "Enable", "", 0.0), + FireEntityInput("SkeleSpawner", "Disable", "", 10.0); + } + case 5:{ + FireEntityInput("merasmus_maker", "ForceSpawn", "", 0.0), + FireEntityInput("hhh_maker2", "ForceSpawn", "", 0.0); + } + case 6:{ + FireEntityInput("merasmus_maker", "ForceSpawn", "", 0.0), + FireEntityInput("monoculus_maker", "ForceSpawn", "", 0.0), + FireEntityInput("hhh_maker2", "ForceSpawn", "", 0.0); + } + case 7:{ + FireEntityInput("monoculus_maker", "ForceSpawn", "", 0.0), + FireEntityInput("merasmus_maker", "ForceSpawn", "", 0.0); + } + case 8:{ + FireEntityInput("SkeleSpawner", "Enable", "", 0.0), + FireEntityInput("SkeleSpawner", "Disable", "", 30.0); + } + case 9:{ + FireEntityInput("SkeleSpawner", "Enable", "", 0.0), + FireEntityInput("SkeleSpawner", "Disable", "", 60.0), + FireEntityInput("merasmus_maker", "ForceSpawn", "", 0.0), + FireEntityInput("monoculus_maker", "ForceSpawn", "", 0.0), + FireEntityInput("hhh_maker2", "ForceSpawn", "", 0.0); + } + case 10:{ + FireEntityInput("monoculus_maker", "ForceSpawn", "", 0.0); + } + } + canHWBoss = false; + CreateTimer(60.0, HWBossesRefire); + } + return Plugin_Stop; +} + +public Action HWBossesRefire(Handle timer){ + if (isWave){ + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + return Plugin_Stop; +} +//SacPoints (Add points to Sacrifice Points occasionally) +public Action SacrificePointsTimer(Handle timer){ + if (isWave && (sacPoints < sacPointsMax)){ + sacPoints++; + float f = GetRandomFloat(5.0, 30.0); + CreateTimer(f, SacrificePointsTimer); + } + return Plugin_Stop; +} +//BombStatus (Add points to Bomb Status occasionally) +public Action BombStatusAddTimer(Handle timer){ + if (isWave && (bombStatus < bombStatusMax)){ + bombStatus++; + float f = GetRandomFloat(10.0, 45.0); + PrintToServer("[DEBUG] Creating a %f timer to give bomb status an update. Current target is %i", f, bombStatus); + CreateTimer(f, BombStatusAddTimer); + } + return Plugin_Stop; +} + +//Track bombStatus and update entities every 0.1 seconds +public Action BombStatusUpdater(Handle timer){ + if (isWave){ + CreateTimer(0.1, BombStatusUpdater); + if (bombStatusbombStatusMax) + { + bombStatus = bombStatusMax-4; + } + return Plugin_Continue; + } + return Plugin_Stop; +} + +//Track SacPoints and update entities every 0.1 seconds +public Action SacrificePointsUpdater(Handle timer){ + if (isWave){ + CreateTimer(0.1, SacrificePointsUpdater); + if (sacPoints > sacPointsMax){ + sacPoints = sacPointsMax; + } + switch (sacPoints){ + case 0,1,2,3,4,5,6,7,8,9:{ + FireEntityInput("BTN.Sacrificial*", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial*", "Color", "0", 0.0); + } + case 10,11,12,13,14,15,16,17,18,19:{ + FireEntityInput("BTN.Sacrificial01", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial01", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial02", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial02", "Color", "0", 0.0), + FireEntityInput("BTN.Sacrificial03", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial03", "Color", "0", 0.0), + FireEntityInput("BTN.Sacrificial04", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial04", "Color", "0", 0.0), + FireEntityInput("BTN.Sacrificial05", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial05", "Color", "0", 0.0), + FireEntityInput("BTN.Sacrificial06", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial06", "Color", "0", 0.0), + FireEntityInput("BTN.Sacrificial07", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial07", "Color", "0", 0.0), + FireEntityInput("BTN.Sacrificial10", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial10", "Color", "0", 0.0); + } + case 20,21,22,23,24,25,26,27,28,29:{ + FireEntityInput("BTN.Sacrificial01", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial01", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial02", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial02", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial03", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial03", "Color", "0", 0.0), + FireEntityInput("BTN.Sacrificial04", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial04", "Color", "0", 0.0), + FireEntityInput("BTN.Sacrificial05", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial05", "Color", "0", 0.0), + FireEntityInput("BTN.Sacrificial06", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial06", "Color", "0", 0.0), + FireEntityInput("BTN.Sacrificial07", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial07", "Color", "0", 0.0), + FireEntityInput("BTN.Sacrificial10", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial10", "Color", "0", 0.0); + } + case 30,31,32,33,34,35,36,37,38,39:{ + FireEntityInput("BTN.Sacrificial01", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial01", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial02", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial02", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial03", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial03", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial04", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial04", "Color", "0", 0.0), + FireEntityInput("BTN.Sacrificial05", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial05", "Color", "0", 0.0), + FireEntityInput("BTN.Sacrificial06", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial06", "Color", "0", 0.0), + FireEntityInput("BTN.Sacrificial07", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial07", "Color", "0", 0.0), + FireEntityInput("BTN.Sacrificial10", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial10", "Color", "0", 0.0); + } + case 40,41,42,43,44,45,46,47,48,49:{ + FireEntityInput("BTN.Sacrificial01", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial01", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial02", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial02", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial03", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial03", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial04", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial04", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial05", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial05", "Color", "0", 0.0), + FireEntityInput("BTN.Sacrificial06", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial06", "Color", "0", 0.0), + FireEntityInput("BTN.Sacrificial07", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial07", "Color", "0", 0.0), + FireEntityInput("BTN.Sacrificial10", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial10", "Color", "0", 0.0); + } + case 50,51,52,53,54,55,56,57,58,59:{ + FireEntityInput("BTN.Sacrificial01", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial01", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial02", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial02", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial03", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial03", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial04", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial04", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial05", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial05", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial06", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial06", "Color", "0", 0.0), + FireEntityInput("BTN.Sacrificial07", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial07", "Color", "0", 0.0), + FireEntityInput("BTN.Sacrificial10", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial10", "Color", "0", 0.0); + } + case 60,61,62,63,64,65,66,67,68,69:{ + FireEntityInput("BTN.Sacrificial01", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial01", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial02", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial02", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial03", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial03", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial04", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial04", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial05", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial05", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial06", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial06", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial07", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial07", "Color", "0", 0.0), + FireEntityInput("BTN.Sacrificial10", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial10", "Color", "0", 0.0); + } + case 70,71,72,73,74,75,76,77,78,79:{ + FireEntityInput("BTN.Sacrificial01", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial01", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial02", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial02", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial03", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial03", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial04", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial04", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial05", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial05", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial06", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial06", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial07", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial07", "Color", "0 255 0", 0.0), + FireEntityInput("BTN.Sacrificial10", "Lock", "", 0.0), + FireEntityInput("BTN.Sacrificial10", "Color", "0", 0.0); + } + case 100:{ + FireEntityInput("BTN.Sacrificial*", "Unlock", "", 0.0), + FireEntityInput("BTN.Sacrificial*", "Color", "0 255 0", 0.0); + } + } + } + return Plugin_Stop; +} + +//RobotLaunchTimer (Randomly fling robots) +public Action RobotLaunchTimer(Handle timer){ + if (isWave){ + FireEntityInput("FB.RobotLauncher", "Enable", "", 0.0), + FireEntityInput("FB.RobotLauncher", "Disable", "", 7.5); + float f = GetRandomFloat(5.0, 30.0); + CreateTimer(f, RobotLaunchTimer); + } + return Plugin_Stop; +} + +//Command action definitions +//Get current song +public Action Command_GetCurrentSong(int client, int args){ + if(StrEqual(curSong, BGM1)) + { + PrintToChat(client, "The current song is: %s", BGM1Title); + } + else if(StrEqual(curSong, BGM2)){ + PrintToChat(client, "The current song is: %s", BGM2Title); + } + else if(StrEqual(curSong, BGM3)){ + PrintToChat(client, "The current song is: %s", BGM3Title); + } + else if(StrEqual(curSong, BGM4)){ + PrintToChat(client, "The current song is: %s", BGM4Title); + } + else if(StrEqual(curSong, BGM5)){ + PrintToChat(client, "The current song is: %s", BGM5Title); + } + else if(StrEqual(curSong, BGM6)){ + PrintToChat(client, "The current song is: %s", BGM6Title); + } + else if(StrEqual(curSong, BGM7)){ + PrintToChat(client, "The current song is: %s", BGM7Title); + } + else if(StrEqual(curSong, BGM8)){ + PrintToChat(client, "The current song is: %s", BGM8Title); + } + else if(StrEqual(curSong, DEFAULTBGM1)){ + PrintToChat(client, "The current song is: %s", DEFAULTBGM1Title); + } + else if(StrEqual(curSong, DEFAULTBGM2)){ + PrintToChat(client, "The current song is: %s", DEFAULTBGM2Title); + } + return Plugin_Handled; +} + +//Tell the client the current sacrifice points earned. +public Action Command_FBSacStatus(int client, int args){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55The sacrificial points counter is currently at %i of %i maximum for this wave.", sacPoints, sacPointsMax); +} + +//Determine which bomb has been recently pushed and tell the client if a bomb is ready or not. +public Action Command_FBBombStatus(int client, int args){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55The bomb status is currently %i, with a max of %i", bombStatus, bombStatusMax); + switch(bombStatus){ + case 0,1,2,3,4,5,6,7:{ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Bombs are \x07FF0000NOT READY\x07FFFFFF!"); + } + case 8:{ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team has not deployed any bombs, however: Your team's \x07FF0000FREEDOM BOMB \x0700AA55is available for deployment!"); + } + case 9,10,11,12,13,14,15:{ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFFREEDOM BOMB \x0700AA55. Please wait for the next bomb."); + } + case 16:{ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFFREEDOM BOMB \x0700AA55. Your team's \x07FF0000ELON BUST \x0700AA55is available for deployment!"); + } + case 17,18,19,20,21,22,23:{ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFELON BUST \x0700AA55. Please wait for the next bomb."); + } + case 24:{ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFELON BUST \x0700AA55. Your team's \x07FF0000BATH SALTS \x0700AA55are available for deployment!"); + } + case 25,26,27,28,29,30,31:{ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFBATH SALTS \x0700AA55. Please wait for the next bomb."); + } + case 32:{ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFBATH SALTS \x0700AA55. Your team's \x07FF0000FALLING STAR \x0700AA55is available for deployment!"); + } + case 33,34,35,36,37,38,39:{ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFFALLING STAR \x0700AA55. Please wait for the next bomb."); + } + case 40:{ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFFALLING STAR \x0700AA55. Your team's \x07FF0000MAJOR KONG \x0700AA55is available for deployment!"); + } + case 41,42,43,44,45,46,47:{ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFMAJOR KONG \x0700AA55. Please wait for the next bomb."); + } + case 48:{ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFMAJOR KONG \x0700AA55. Your team's \x07FF0000SHARK \x0700AA55is available for deployment!"); + } + case 49,50,51,52,53,54,55:{ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFSHARK \x0700AA55. Please wait for the next bomb."); + } + case 56:{ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFSHARK \x0700AA55. Your team's \x07FF0000FAT MAN \x0700AA55is available for deployment!"); + } + case 57,58,59,60,61,62,63:{ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFFAT MAN \x0700AA55. Please wait for the next bomb."); + } + case 64:{ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FF0000 FAT MAN \x0700AA55. Your team's \x07FFFF00HYDROGEN \x0700AA55is available for deployment!"); + } + case 65,66,67,68,69,70,71:{ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFHYDROGEN\x0700AA55. Bombs are automatically reset to preserve the replayable aspect of this game mode."); + } + case 72:{ + PrintToChatAll("Something exceeded a maximum value!!! Apparently the bomb status is %i, with a maximum status of %i.", bombStatus, bombStatusMax); + } + } + return Plugin_Handled; +} + +//Deprecated +public Action Command_TBWave01(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 01: Battle On The Big Bridge"); +} + +public Action Command_TacoBellFinished(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF YOU HAVE SUCCESSFULLY COMPLETED DOVAH'S ASS - TACO BELL EDITION! THE SERVER WILL RESTART IN 10 SECONDS."); + CreateTimer(10.0, Timer_RestartServer); +} + +//Check who died by what and announce it to chat. +public Action EventDeath(Event Spawn_Event, const char[] Spawn_Name, bool Spawn_Broadcast) +{ + int client = GetClientOfUserId(Spawn_Event.GetInt("userid")); + int attacker = GetClientOfUserId(Spawn_Event.GetInt("attacker")); + char weapon[32]; + Spawn_Event.GetString("weapon", weapon, sizeof(weapon)); + if (0 < client <= MaxClients && IsClientInGame(client)) + { + int damagebits = Spawn_Event.GetInt("damagebits"); + if ((damagebits & (1 << 0)) && !attacker) //DMG_CRUSH + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N was crushed by a \x07AA0000FALLING ROCK FROM OUTER SPACE\x07FFFFFF!", client); + } + + if ((damagebits & (1 << 3)) && !attacker) //DMG_BURN + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N was \x07AA0000MELTED\x07FFFFFF.", client); + } + + if ((damagebits & (1 << 4)) && !attacker) //DMG_VEHICLE (DMG_FREEZE) + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N was flattened out by a \x07AA0000TRAIN\x07FFFFFF!", client); + } + + if ((damagebits & (1 << 5)) && !attacker) //DMG_FALL + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N was \x07AA0000YEETED OUT INTO ORBIT\x07FFFFFF!", client); + int i = GetRandomInt(1, 16); + switch (i){ + case 1:{ + EmitSoundToAll(FALLSND01); + } + case 2:{ + EmitSoundToAll(FALLSND02); + } + case 3:{ + EmitSoundToAll(FALLSND03); + } + case 4:{ + EmitSoundToAll(FALLSND04); + } + case 5:{ + EmitSoundToAll(FALLSND05); + } + case 6:{ + EmitSoundToAll(FALLSND06); + } + case 7:{ + EmitSoundToAll(FALLSND07); + } + case 8:{ + EmitSoundToAll(FALLSND08); + } + case 9:{ + EmitSoundToAll(FALLSND09); + } + case 10:{ + EmitSoundToAll(FALLSND0A); + } + case 11:{ + EmitSoundToAll(FALLSND0B), + FireEntityInput("FB.BlueKirbTemplate", "ForceSpawn", "", 0.0); + } + case 12:{ + EmitSoundToAll(FALLSND0C); + } + case 13:{ + EmitSoundToAll(FALLSND0D); + } + case 14:{ + EmitSoundToAll(FALLSND0E); + } + case 15:{ + EmitSoundToAll(FALLSND0F); + } + case 16:{ + EmitSoundToAll(FALLSND10); + } + } + } + + if ((damagebits & (1 << 6)) && !attacker) //DMG_BLAST + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N went \x07AA0000 KABOOM\x07FFFFFF!", client); + } + + if ((damagebits & (1 << 7)) && !attacker) //DMG_CLUB + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N is \x07AA0000CRASHING THE HINDENBURG\x07FFFFFF!!!", client); + } + + if ((damagebits & (1 << 8)) && !attacker) //DMG_SHOCK + { + PrintToChatAll("\x070000AA[\x07AA0000EXTERMINATUS\x070000AA]\x07FFFFFF Client %N has humliated themselves with an \x07AA0000incorrect \x07FFFFFFkey entry!", client); + int i = GetRandomInt(1, 16); + switch(i){ + case 1,3,10:{ + FireEntityInput("BG.Meteorites1", "ForceSpawn", "", 0.0), + PrintToChatAll("\x070000AA[\x07AA0000WARN\x070000AA] \x07FFFFFFUh oh, a \x07AA0000METEOR\x07FFFFFF has been spotted coming towards Dovah's Ass!!!"), + FireEntityInput("bg.meteorite1", "StartForward", "", 0.1); + } + case 2,5,16:{ + CreateTimer(0.5, FBCodeFailTankHornSND); + FireEntityInput("FB.TankTrain", "TeleportToPathTrack", "Tank01", 0.0), + FireEntityInput("FB.TankTrain", "StartForward", "", 0.25), + FireEntityInput("FB.TankTrain", "SetSpeed", "1", 0.35), + FireEntityInput("FB.Tank", "Enable", "", 1.0); + } + case 4,8,14:{ + EmitSoundToAll("ambient/alarms/train_horn_distant1.wav"), + FireEntityInput("TrainSND", "PlaySound", "", 0.0), + FireEntityInput("TrainDamage", "Enable", "", 0.0), + FireEntityInput("Train01", "Enable", "", 0.0), + PrintToChatAll("\x070000AA[\x07AA0000WARN\x070000AA] \x07AA7000KISSONE'S TRAIN\x07FFFFFF is \x07AA0000INCOMING\x07FFFFFF. Look out!"), + FireEntityInput("TrainTrain", "TeleportToPathTrack", "TrainTrack01", 0.0), + FireEntityInput("TrainTrain", "StartForward", "", 0.1); + } + case 6,9:{ + canTornado = true, + CreateTimer(1.0, SpawnTornado); + } + case 7,13:{ + PrintToChatAll("\x070000AA[\x07AA0000WARN\x070000AA] \x07FFFFFFUh oh, a \x07AA0000METEOR SHOWER\x07FFFFFF has been reported from Dovah's Ass!!!"); + canSENTMeteors = true, + CreateTimer(1.0, SENTMeteorTimer), + CreateTimer(30.0, DisableSENTMeteors); + } + case 11:{ + FireEntityInput("FB.Slice", "Enable", "", 0.0), + EmitSoundToAll("ambient/sawblade_impact1.wav"), + FireEntityInput("FB.Slice", "Disable", "", 1.0); + } + case 12,15:{ + PrintToChatAll("\x070000AA[\x07AA0000WARN\x070000AA] \x07FFFFFFUh oh, it's begun to rain \x07AA0000ATOM BOMBS\x07FFFFFF! TAKE COVER!"), + canSENTNukes = true, + CreateTimer(1.0, SENTNukeTimer), + CreateTimer(30.0, DisableSENTNukes); + } + } + } + +//Crusader chain command omg this took forever to figure out! + if ((damagebits & (1 << 9)) && !attacker) //DMG_SONIC + { + PrintToChatAll("\x070000AA[\x07AA0000EXTERMINATUS\x070000AA]\x07FFFFFF Client %N has sacrificed themselves with a \x0700AA00correct \x07FFFFFFkey entry! Prepare your anus!", client); + StopCurSong(), + CreateTimer(25.20, CRUSADERATTACKTimer), + CreateTimer(63.20, WTFBOOMTimer), + PrintToServer("Starting Crusader via plugin!"), + EmitSoundToAll("fartsy/fallingback/bgm.mp3"), + FireEntityInput("FB.INCOMINGTIMER", "Enable", "", 1.0), + FireEntityInput("FB.BOOM", "StopShake", "", 3.0), + FireEntityInput("FB.CRUSADER", "Enable", "", 25.20), + FireEntityInput("CrusaderTrain", "StartForward", "", 25.20), + FireEntityInput("CrusaderLaserBase*", "StartForward", "", 25.20), + FireEntityInput("FB.INCOMINGTIMER", "Disable", "", 30.0), + FireEntityInput("CrusaderTrain", "SetSpeed", "0.9", 38.0), + FireEntityInput("CrusaderTrain", "SetSpeed", "0.7", 38.60), + FireEntityInput("CrusaderTrain", "SetSpeed", "0.5", 39.20), + FireEntityInput("CrusaderTrain", "SetSpeed", "0.3", 40.40), + FireEntityInput("CrusaderTrain", "SetSpeed", "0.1", 41.40), + FireEntityInput("CrusaderTrain", "Stop", "", 42.60), + FireEntityInput("FB.CrusaderLaserKill01", "Disable", "", 42.60), + FireEntityInput("FB.CrusaderNukeTimer", "Disable", "", 42.60), + FireEntityInput("FB.LaserCore", "TurnOn", "", 45.80), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "0.35", 45.80), + FireEntityInput("FB.ShakeCore", "StartShake", "", 45.80), + FireEntityInput("CrusaderSprite", "Color", "255 128 128", 45.80), + FireEntityInput("FB.ShakeCore", "StopShake", "", 48.80), + FireEntityInput("FB.LaserInnerMost", "TurnOn", "", 49.20), + FireEntityInput("FB.ShakeInner", "StartShake", "", 49.20), + FireEntityInput("CrusaderSprite", "Color", "255 230 230", 49.20), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "0.35", 50.20), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "0.45", 50.60), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "0.55", 51.0), + FireEntityInput("FB.ShakeInner", "StopShake", "", 52.10), + FireEntityInput("FB.ShakeInner", "StartShake", "", 52.20), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "0.45", 54.0), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "0.4", 54.40), + FireEntityInput("FB.ShakeInner", "StopShake", "", 55.0), + FireEntityInput("FB.ShakeInner", "StartShake", "", 55.10), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "0.75", 57.20), + FireEntityInput("FB.CrusaderSideLaser", "TurnOn", "", 57.20), + FireEntityInput("FB.ShakeInner", "StopShake", "", 58.0), + FireEntityInput("FB.ShakeInner", "StartShake", "", 58.10), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "1", 58.50), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "0.75", 60.80), + FireEntityInput("CrusaderLaserBase", "SetSpeed", "0.65", 61.10), + FireEntityInput("CrusaderLaserBase", "SetSpeed", "0.55", 61.40), + FireEntityInput("FB.LaserCore", "TurnOff", "", 61.40), + FireEntityInput("FB.LaserInnerMost", "TurnOff", "", 61.40), + FireEntityInput("CrusaderSprite", "Color", "0 0 0", 61.40), + FireEntityInput("CrusaderLaserBase", "SetSpeed", "0.45", 61.70), + FireEntityInput("CrusaderLaserBase", "SetSpeed", "0.3", 62.0), + FireEntityInput("CrusaderLaserBase", "SetSpeed", "0.15", 62.30), + FireEntityInput("FB.CrusaderSideLaser", "TurnOff", "", 62.30), + FireEntityInput("CrusaderLaserBase*", "Stop", "", 62.70), + FireEntityInput("FB.Laser*", "TurnOn", "", 65.20), + FireEntityInput("CrusaderLaserBase*", "StartForward", "", 65.20), + FireEntityInput("CrusaderLaserBase", "SetSpeed", "1", 65.20), + FireEntityInput("FB.ShakeBOOM", "StartShake", "", 65.20), + FireEntityInput("FB.Fade", "Fade", "", 65.20), + FireEntityInput("FB.CrusaderLaserKill02", "Enabled", "", 65.20), + FireEntityInput("FB.CrusaderSideLaser", "TurnOn", "", 65.20), + FireEntityInput("CrusaderSprite", "Color", "255 230 255", 65.20), + FireEntityInput("FB.Laser*", "TurnOff", "", 70.0), + FireEntityInput("CrusaderTrain", "StartForward", "", 70.0), + FireEntityInput("CrusaderLaserBase*", "Stop", "", 70.0), + FireEntityInput("FB.LaserKill02", "Disable", "", 70.0), + FireEntityInput("FB.CrusaderSideLaser", "TurnOff", "", 70.0), + FireEntityInput("CrusaderSprite", "Color", "0 0 0", 70.0), + FireEntityInput("FB.ShakeBOOM", "StopShake", "", 70.20), + FireEntityInput("CrusaderTrain", "Stop", "", 80.0), + FireEntityInput("FB.CRUSADER", "Disable", "", 80.0); + CreateTimer(80.0, NextWaveTimer); //Jump to next wave + } + + if ((damagebits & (1 << 10)) && !attacker) //DMG_ENERGYBEAM + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N has been vaporized by a \x07AA0000HIGH ENERGY PHOTON BEAM\x07FFFFFF!", client); + } + + if ((damagebits & (1 << 14)) && !attacker) //DMG_DROWN + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N \x07AA0000DROWNED\x07FFFFFF.", client); + } + + if ((damagebits & (1 << 15)) && !attacker) //DMG_PARALYZE + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N has been crushed by a \x070000AAMYSTERIOUS BLUE BALL\x07FFFFFF!", client); + } + + if ((damagebits & (1 << 16)) && !attacker) //DMG_NERVEGAS + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N has been \x07AA0000SLICED TO RIBBONS\x07FFFFFF!", client); + } + + if ((damagebits & (1 << 17)) && !attacker) //DMG_POISON + { + ServerCommand("sm_psay %d \x07FF0000[\x0700FF00ADMIN\x07FF0000] \x07AAAAAAPlease don't sit IDLE in the FC Tavern. Repeated offenses may result in a kick."); + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N was killed for standing in the Tavern instead of helping their team!", client); + } + + if ((damagebits & (1 << 18)) && !attacker) //DMG_RADIATION + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N was blown away by a \x07AA0000NUCLEAR EXPLOSION\x07FFFFFF!", client); + } + + if ((damagebits & (1 << 19)) && !attacker) //DMG_DROWNRECOVER + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N experienced \x07AA0000TACO BELL\x07FFFFFF!", client); + } + + if ((damagebits & (1 << 20)) && !attacker) //DMG_ACID + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N has been crushed by a \x0700AA00FALLING GOOBBUE FROM OUTER SPACE\x07FFFFFF!", client); + } + } + return Plugin_Handled; +} + +//Silence cvar changes to minimize chat spam. +public Action Event_Cvar(Event event, const char[] name, bool dontBroadcast) +{ + event.BroadcastDisabled = true; +} +//When we win +public Action EventWaveComplete(Event Spawn_Event, const char[] Spawn_Name, bool Spawn_Broadcast) +{ + bgmlock1 = true; + bgmlock2 = true; + bgmlock3 = true; + bgmlock4 = true; + bgmlock5 = true; + bgmlock6 = true; + bgmlock7 = true; + bgmlock8 = true; + canHWBoss = false; + canTornado = false; + isWave = false; + bombStatusMax = 7; + bombStatus = 5; + explodeType = 0; + SelectBGM(); + PrintToChatAll("\x0700FF00[CORE] \x07FFFFFFYou've defeated the wave!"); + FireEntityInput("BTN.Sacrificial*", "Disable", "", 0.0), + FireEntityInput("BTN.Sacrificial*", "Color", "0", 0.0); + FireEntityInput("Barricade_Rebuild_Relay", "Trigger", "", 0.0); + FireEntityInput("OldSpawn", "Disable", "", 0.0); + FireEntityInput("NewSpawn", "Enable", "", 0.0); + FireEntityInput("dovahsassprefer", "Disable", "", 0.0); + FireEntityInput("bombpath_left_arrows", "Disable", "", 0.0); + FireEntityInput("bombpath_right_arrows", "Disable", "", 0.0); + ChooseBombPath(); +} + +//Announce when we are in danger. +public Action EventWarning(Event Spawn_Event, const char[] Spawn_Name, bool Spawn_Broadcast) +{ + PrintToChatAll("\x070000AA[\x07AA0000WARN\x070000AA]\x07AA0000 WARNING\x07FFFFFF: \x07AA0000DOVAH'S ASS IS ABOUT TO BE DEPLOYED!!!"); +} + +//When we fail +public Action EventWaveFailed(Event Spawn_Event, const char[] Spawn_Name, bool Spawn_Broadcast){ + bgmlock1 = true; + bgmlock2 = true; + bgmlock3 = true; + bgmlock4 = true; + bgmlock5 = true; + bgmlock6 = true; + bgmlock7 = true; + bgmlock8 = true; + canHWBoss = false; + canTornado = false; + isWave = false; + bombStatusMax = 7; + bombStatus = 5; + explodeType = 0; + SelectBGM(); +// PrintToChatAll("\x0700FF00[CORE] \x07FFFFFFWave set/reset success!"); + FireEntityInput("BTN.Sacrificial*", "Disable", "", 0.0), + FireEntityInput("BTN.Sacrificial*", "Color", "0", 0.0); +} +//Announce the bomb has been reset by client %N. +public Action EventReset(Event Spawn_Event, const char[] Spawn_Name, bool Spawn_Broadcast) +{ + int client = Spawn_Event.GetInt("player"); + if (0 < client <= MaxClients && IsClientInGame(client)) + { + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF Client \x0700AA00%N\x07FFFFFF has reset the ass!", client); + } + return Plugin_Handled; +} + +//Waves +public Action GetWave(int args){ + int ent = FindEntityByClassname(-1, "tf_objective_resource"); + if(ent == -1){ + LogMessage("tf_objective_resource not found"); + return; + } + + int current_wave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineWaveCount")); + switch (current_wave){ + case 1:{ + bgmlock1 = false; + bgmlock2 = true; + bgmlock3 = true; + bgmlock4 = true; + bgmlock5 = true; + bgmlock6 = true; + bgmlock7 = true; + bgmlock8 = true; + canHWBoss = true; + canTornado = true; + isWave = true; + bombStatus = 0; + bombStatusMax = 10; + sacPointsMax = 90; + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 1: Locus"); + StopCurSong(); + EmitSoundToAll(BGM1, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM1; + CreateTimer(229.25, RefireLocus); + CreateTimer(1.0, BombStatusAddTimer); + CreateTimer(0.1, BombStatusUpdater); + CreateTimer(1.0, RobotLaunchTimer); + CreateTimer(1.0, SacrificePointsTimer); + CreateTimer(1.0, SacrificePointsUpdater); + CreateTimer(1.0, RefireStorm); + FireEntityInput("rain", "Alpha", "200", 0.0); + FireEntityInput("Classic_Mode_Intel1", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel2", "Enable", "", 0.0); + FireEntityInput("OldSpawn", "Enable", "", 0.0); + FireEntityInput("NewSpawn", "Disable", "", 0.0); + FireEntityInput("bombpath_right_arrows", "Disable", "", 0.1); + FireEntityInput("bombpath_left_arrows", "Disable", "", 0.1); + ChooseBombPath(); + ActivateTornadoTimer(); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + case 2:{ + bgmlock1 = true; + bgmlock2 = false; + bgmlock3 = true; + bgmlock4 = true; + bgmlock5 = true; + bgmlock6 = true; + bgmlock7 = true; + bgmlock8 = true; + canHWBoss = true; + canTornado = true; + isWave = true; + bombStatus = 4; + bombStatusMax = 18; + sacPointsMax = 90; + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 2: Metal"); + StopCurSong(); + EmitSoundToAll(BGM2, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM2; + CreateTimer(153.95, RefireMetal); + CreateTimer(1.0, BombStatusAddTimer); + CreateTimer(0.1, BombStatusUpdater); + CreateTimer(1.0, RobotLaunchTimer); + CreateTimer(1.0, SacrificePointsTimer); + CreateTimer(1.0, SacrificePointsUpdater); + CreateTimer(1.0, RefireStorm); + FireEntityInput("rain", "Alpha", "200", 0.0); + FireEntityInput("Classic_Mode_Intel1", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel2", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel3", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel4", "Enable", "", 0.0); + FireEntityInput("OldSpawn", "Enable", "", 0.0); + FireEntityInput("NewSpawn", "Disable", "", 0.0); + FireEntityInput("bombpath_right_arrows", "Disable", "", 0.1); + FireEntityInput("bombpath_left_arrows", "Disable", "", 0.1); + ChooseBombPath(); + ActivateTornadoTimer(); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + case 3:{ + bgmlock1 = true; + bgmlock2 = true; + bgmlock3 = false; + bgmlock4 = true; + bgmlock5 = true; + bgmlock6 = true; + bgmlock7 = true; + bgmlock8 = true; + canHWBoss = true; + canTornado = true; + HWNMax = 360.0; + isWave = true; + bombStatus = 7; + bombStatusMax = 26; + sacPointsMax = 90; + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 3: Exponential Entropy"); + StopCurSong(); + EmitSoundToAll(BGM3, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM3; + CreateTimer(166.85, RefireEntropy); + CreateTimer(1.0, BombStatusAddTimer); + CreateTimer(0.1, BombStatusUpdater); + CreateTimer(1.0, RobotLaunchTimer); + CreateTimer(1.0, SacrificePointsTimer); + CreateTimer(1.0, SacrificePointsUpdater); + CreateTimer(1.0, RefireStorm); + FireEntityInput("rain", "Alpha", "200", 0.0); + FireEntityInput("Classic_Mode_Intel1", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel2", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel3", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel4", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel5", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel6", "Enable", "", 0.0); + FireEntityInput("OldSpawn", "Enable", "", 0.0); + FireEntityInput("NewSpawn", "Disable", "", 0.0); + FireEntityInput("bombpath_right_arrows", "Disable", "", 0.1); + FireEntityInput("bombpath_left_arrows", "Disable", "", 0.1); + ChooseBombPath(); + ActivateTornadoTimer(); + float f = GetRandomFloat(60.0, 180.0); + CreateTimer(f, UnlockTimer); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + case 4:{ + bgmlock1 = true; + bgmlock2 = true; + bgmlock3 = true; + bgmlock4 = false; + bgmlock5 = true; + bgmlock6 = true; + bgmlock7 = true; + bgmlock8 = true; + canHWBoss = true; + canTornado = true; + HWNMax = 360.0; + isWave = true; + bombStatus = 12; + bombStatusMax = 34; + sacPointsMax = 90; + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 4: Torn From The Heavens"); + StopCurSong(); + EmitSoundToAll(BGM4, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM4; + CreateTimer(122.25, RefireTorn); + CreateTimer(1.0, BombStatusAddTimer); + CreateTimer(0.1, BombStatusUpdater); + CreateTimer(1.0, RobotLaunchTimer); + CreateTimer(1.0, SacrificePointsTimer); + CreateTimer(1.0, SacrificePointsUpdater); + CreateTimer(1.0, RefireStorm); + FireEntityInput("rain", "Alpha", "200", 0.0); + FireEntityInput("Classic_Mode_Intel1", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel2", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel3", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel4", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel5", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel6", "Enable", "", 0.0); + FireEntityInput("OldSpawn", "Enable", "", 0.0); + FireEntityInput("NewSpawn", "Disable", "", 0.0); + FireEntityInput("bombpath_right_arrows", "Disable", "", 0.1); + FireEntityInput("bombpath_left_arrows", "Disable", "", 0.1); + ChooseBombPath(); + ActivateTornadoTimer(); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + case 5:{ + bgmlock1 = true; + bgmlock2 = true; + bgmlock3 = true; + bgmlock4 = true; + bgmlock5 = false; + bgmlock6 = true; + bgmlock7 = true; + bgmlock8 = true; + canHWBoss = true; + canTornado = true; + HWNMax = 260.0; + HWNMin = 140.0; + isWave = true; + bombStatus = 14; + bombStatusMax = 42; + sacPointsMax = 100; + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 5: Metal - Brute Justice Mode"); + StopCurSong(); + EmitSoundToAll(BGM5, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM5; + CreateTimer(131.75, RefireBJMode); + CreateTimer(1.0, BombStatusAddTimer); + CreateTimer(0.1, BombStatusUpdater); + CreateTimer(1.0, RobotLaunchTimer); + CreateTimer(1.0, SacrificePointsTimer); + CreateTimer(1.0, SacrificePointsUpdater); + CreateTimer(1.0, RefireStorm); + FireEntityInput("rain", "Alpha", "200", 0.0); + FireEntityInput("Classic_Mode_Intel1", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel2", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel3", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel4", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel5", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel6", "Enable", "", 0.0); + FireEntityInput("OldSpawn", "Enable", "", 0.0); + FireEntityInput("NewSpawn", "Disable", "", 0.0); + FireEntityInput("bombpath_right_arrows", "Disable", "", 0.1); + FireEntityInput("bombpath_left_arrows", "Disable", "", 0.1); + FireEntityInput("w5_engie_hints", "Trigger", "", 3.0); + FireEntityInput("BruteJustice", "Trigger", "", 3.0); + ChooseBombPath(); + ActivateTornadoTimer(); + float f = GetRandomFloat(60.0, 180.0); + CreateTimer(f, UnlockTimer); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + case 6:{ + bgmlock1 = true; + bgmlock2 = true; + bgmlock3 = true; + bgmlock4 = true; + bgmlock5 = true; + bgmlock6 = false; + bgmlock7 = true; + bgmlock8 = true; + canHWBoss = true; + canTornado = true; + HWNMax = 260.0; + HWNMin = 140.0; + isWave = true; + bombStatus = 20; + bombStatusMax = 50; + sacPointsMax = 100; + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 6: Grandma Destruction"); + StopCurSong(); + EmitSoundToAll(BGM6, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM6; + CreateTimer(323.95, RefireGrandma); + CreateTimer(1.0, BombStatusAddTimer); + CreateTimer(0.1, BombStatusUpdater); + CreateTimer(1.0, RobotLaunchTimer); + CreateTimer(1.0, SacrificePointsTimer); + CreateTimer(1.0, SacrificePointsUpdater); + CreateTimer(1.0, RefireStorm); + FireEntityInput("rain", "Alpha", "200", 0.0); + FireEntityInput("Classic_Mode_Intel1", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel2", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel3", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel4", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel5", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel6", "Enable", "", 0.0); + FireEntityInput("OldSpawn", "Enable", "", 0.0); + FireEntityInput("NewSpawn", "Disable", "", 0.0); + FireEntityInput("bombpath_right_arrows", "Disable", "", 0.1); + FireEntityInput("bombpath_left_arrows", "Disable", "", 0.1); + ChooseBombPath(); + ActivateTornadoTimer(); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + case 7:{ + bgmlock1 = true; + bgmlock2 = true; + bgmlock3 = true; + bgmlock4 = true; + bgmlock5 = true; + bgmlock6 = true; + bgmlock7 = false; + bgmlock8 = true; + canHWBoss = true; + canTornado = true; + HWNMax = 240.0; + HWNMin = 120.0; + isWave = true; + bombStatus = 28; + bombStatusMax = 58; + sacPointsMax = 100; + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 7: Revenge Twofold"); + StopCurSong(); + EmitSoundToAll(BGM7, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM7; + CreateTimer(133.25, RefireRevenge2F); + CreateTimer(1.0, BombStatusAddTimer); + CreateTimer(0.1, BombStatusUpdater); + CreateTimer(1.0, RobotLaunchTimer); + CreateTimer(1.0, SacrificePointsTimer); + CreateTimer(1.0, SacrificePointsUpdater); + CreateTimer(1.0, RefireStorm); + FireEntityInput("rain", "Alpha", "200", 0.0); + FireEntityInput("Classic_Mode_Intel1", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel2", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel3", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel4", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel5", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel6", "Enable", "", 0.0); + FireEntityInput("OldSpawn", "Enable", "", 0.0); + FireEntityInput("NewSpawn", "Disable", "", 0.0); + FireEntityInput("bombpath_right_arrows", "Disable", "", 0.1); + FireEntityInput("bombpath_left_arrows", "Disable", "", 0.1); + FireEntityInput("w5_engie_hints", "Trigger", "", 3.0); + ChooseBombPath(); + ActivateTornadoTimer(); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + case 8:{ + bgmlock1 = true; + bgmlock2 = true; + bgmlock3 = true; + bgmlock4 = true; + bgmlock5 = true; + bgmlock6 = true; + bgmlock7 = true; + bgmlock8 = false; + canHWBoss = true; + canTornado = true; + HWNMax = 240.0; + HWNMin = 120.0; + isWave = true; + bombStatus = 30; + bombStatusMax = 66; + sacPointsMax = 100; + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 8: Under The Weight"); + StopCurSong(); + EmitSoundToAll(BGM8, _, SNDCHAN, BGMSNDLVL, _, _, _, _, _, _, _, _); + curSong = BGM8; + CreateTimer(313.85, RefireUnderTW); + CreateTimer(1.0, BombStatusAddTimer); + CreateTimer(0.1, BombStatusUpdater); + CreateTimer(1.0, RobotLaunchTimer); + CreateTimer(1.0, SacrificePointsTimer); + CreateTimer(1.0, SacrificePointsUpdater); + CreateTimer(1.0, RefireStorm); + FireEntityInput("rain", "Alpha", "200", 0.0); + FireEntityInput("Classic_Mode_Intel1", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel2", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel3", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel4", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel5", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel6", "Enable", "", 0.0); + FireEntityInput("OldSpawn", "Enable", "", 0.0); + FireEntityInput("NewSpawn", "Disable", "", 0.0); + FireEntityInput("bombpath_right_arrows", "Disable", "", 0.1); + FireEntityInput("bombpath_left_arrows", "Disable", "", 0.1); + ChooseBombPath(); + ActivateTornadoTimer(); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + } + return; +} +//Jump to the wave. +public Action JumpToWave(int wave_number) +{ + int flags = GetCommandFlags("tf_mvm_jump_to_wave"); + SetCommandFlags("tf_mvm_jump_to_wave", flags & ~FCVAR_CHEAT); + ServerCommand("tf_mvm_jump_to_wave %d", wave_number); + FakeClientCommand(0, ""); + SetCommandFlags("tf_mvm_jump_to_wave", flags|FCVAR_CHEAT); +} +//NextWaveTimer +public Action NextWaveTimer(Handle timer){ + ServerCommand("fb_operator 99"); +} +//Timer to restart the server. +public Action Timer_RestartServer(Handle timer) +{ + ServerCommand("_restart"); +} + +//Create a temp entity and fire an input +public Action FireEntityInput(char[] strTargetname, char[] strInput, char[] strParameter, float flDelay) +{ + char strBuffer[255]; + Format(strBuffer, sizeof(strBuffer), "OnUser1 %s:%s:%s:%f:1", strTargetname, strInput, strParameter, flDelay); + //PrintToChatAll("\x0700FF00[CORE] \x07FFFFFF Firing entity %s with input %s , a parameter override of %s , and delay of %f ...", strTargetname, strInput, strParameter, flDelay); + int entity = CreateEntityByName("info_target"); + if(IsValidEdict(entity)) + { + DispatchSpawn(entity); + ActivateEntity(entity); + SetVariantString(strBuffer); + AcceptEntityInput(entity, "AddOutput"); + AcceptEntityInput(entity, "FireUser1"); + CreateTimer(0.0, DeleteEdict, entity); + return Plugin_Continue; + } + return Plugin_Handled; +} + +//Remove edict allocated by temp entity +public Action DeleteEdict(Handle timer, any entity) +{ + if(IsValidEdict(entity)) RemoveEdict(entity); + return Plugin_Stop; +} + +//Choose Bomb Path +public Action ChooseBombPath(){ + FireEntityInput("Nest_EN060", "Disable", "", 0.0), + FireEntityInput("Nest_EN050", "Disable", "", 0.0), + FireEntityInput("Nest_EN040", "Disable", "", 0.0), + FireEntityInput("Nest_EN030", "Disable", "", 0.0), + FireEntityInput("Nest_EN020", "Disable", "", 0.0), + FireEntityInput("Nest_EN010", "Disable", "", 0.0), + FireEntityInput("Nest_L050", "Disable", "", 0.0), + FireEntityInput("Nest_L040", "Disable", "", 0.0), + FireEntityInput("Nest_L030", "Disable", "", 0.0), + FireEntityInput("Nest_L020", "Disable", "", 0.0), + FireEntityInput("Nest_L010", "Disable", "", 0.0), + FireEntityInput("Nest_R040", "Disable", "", 0.0), + FireEntityInput("Nest_R030", "Disable", "", 0.0), + FireEntityInput("Nest_R020", "Disable", "", 0.0), + FireEntityInput("Nest_R010", "Disable", "", 0.0), + FireEntityInput("bombpath_right_prefer_flankers", "Disable", "", 0.0), + FireEntityInput("bombpath_left_prefer_flankers", "Disable", "", 0.0), + FireEntityInput("bombpath_left_navavoid", "Disable", "", 0.0), + FireEntityInput("bombpath_right_navavoid", "Disable", "", 0.0), + FireEntityInput("bombpath_right_arrows", "Disable", "", 0.0), + FireEntityInput("bombpath_left_arrows", "Disable", "", 0.0); + int i = GetRandomInt(1, 3); + switch(i){ + case 1:{ + FireEntityInput("Nest_R040", "Enable", "", 0.25), + FireEntityInput("Nest_R030", "Enable", "", 0.25), + FireEntityInput("Nest_R020", "Enable", "", 0.25), + FireEntityInput("Nest_R010", "Enable", "", 0.25), + FireEntityInput("bombpath_right_prefer_flankers", "Enable", "", 0.25), + FireEntityInput("bombpath_right_navavoid", "Enable", "", 0.25), + FireEntityInput("bombpath_right_arrows", "Enable", "", 0.25); + } + case 2:{ + FireEntityInput("Nest_L050", "Enable", "", 0.25), + FireEntityInput("Nest_L040", "Enable", "", 0.25), + FireEntityInput("Nest_L030", "Enable", "", 0.25), + FireEntityInput("Nest_L020", "Enable", "", 0.25), + FireEntityInput("Nest_L010", "Enable", "", 0.25), + FireEntityInput("bombpath_left_prefer_flankers", "Enable", "", 0.25), + FireEntityInput("bombpath_left_navavoid", "Enable", "", 0.25), + FireEntityInput("bombpath_left_arrows", "Enable", "", 0.25); + } + case 3:{ + FireEntityInput("dovahsassprefer", "Enable", "", 0.25), + FireEntityInput("Nest_R040", "Enable", "", 0.25), + FireEntityInput("Nest_R030", "Enable", "", 0.25), + FireEntityInput("Nest_R020", "Enable", "", 0.25), + FireEntityInput("Nest_R010", "Enable", "", 0.25), + FireEntityInput("bombpath_right_prefer_flankers", "Enable", "", 0.25), + FireEntityInput("bombpath_right_navavoid", "Enable", "", 0.25), + FireEntityInput("bombpath_right_arrows", "Enable", "", 0.25); + } + } +} + +public Action Command_Operator(int args){ + char arg1[16]; + GetCmdArg(1, arg1, sizeof(arg1)); + int i = StringToInt(arg1); +// PrintToChatAll("Calling on fb_operator because arg1 was %i, and was stored in memory position %i", i, arg1); + switch (i){ + //When the map is complete + case 0:{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF YOU HAVE SUCCESSFULLY COMPLETED DOVAH'S ASS ! THE SERVER WILL RESTART IN 10 SECONDS."); + CreateTimer(10.0, Timer_RestartServer); + } + //Get current wave + case 1:{ + GetWave(0); + } + //Prepare yourself! + case 2:{ + PrintToChatAll("\x070000AA[\x07AAAA00INFO\x070000AA] \x07AA0000DOVAH'S ASS\x07FFFFFF v0x13. Prepare yourself for the unpredictable... [\x0700FF00by TTV/ProfessorFartsalot\x07FFFFFF]"); + } + //Force Tornado + case 3:{ + if(isWave && canTornado && !tornado){ + CreateTimer(0.1, SpawnTornado); + PrintCenterTextAll("OH NOES... PREPARE YOUR ANUS!"); + } + else{ + PrintToServer("Error spawning manual tornado... Perhaps we are not in a wave, tornadoes are banished, or a tornado has already spawned???"); + } + return Plugin_Handled; + } + //Tornado Sacrifice (+1) + case 10:{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF Sacrificed a client into orbit. (\x0700FF00+1 pt\x07FFFFFF)"); + bombStatus++; + sacPoints++; + } + //Death pit sacrifice (+1) + case 11:{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF Sent a client to their doom. (\x0700FF00+1 pt\x07FFFFFF)"); + sacPoints++; + } + //KissoneTM pit sacrifice (+1) + case 12:{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF Dunked a client into liquid death. (\x0700FF00+1 pt\x07FFFFFF)"); + sacPoints++; + } + //Tank Destroyed (+1) + case 13:{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF A tank has been destroyed. (\x0700FF00+1 pt\x07FFFFFF)"); + sacPoints++; + } + //Bomb Reset (+5) + case 14:{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF Bomb has been reset. (\x0700FF00+5 pts\x07FFFFFF)"); + sacPoints+=5; + } + //Bomb Deployed + case 15:{ + switch (explodeType){ + //Invalid + case 0:{ + PrintToServer("Tried to detonate with a bomb size of zero!"); + } + //Small Explosion + case 1:{ + FireEntityInput("Murica", "PlaySound", "", 0.0), + FireEntityInput("SmallExplosion", "Explode", "", 0.0), + FireEntityInput("SmallExploShake", "StartShake", "", 0.0), + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF Small Bomb successfully pushed! (\x0700FF00+2 pts\x07FFFFFF)"); + sacPoints+=2, + bombStatusMax+=10, + bombStatus+=2, + CreateTimer(3.0, BombStatusAddTimer); + EmitSoundToAll(COUNTDOWN); + } + //Medium Explosion + case 2,3:{ + FireEntityInput("MedExplosionSND", "PlaySound", "", 0.0), + FireEntityInput("MediumExplosion", "Explode", "", 0.0), + FireEntityInput("MedExploShake", "StartShake", "", 0.0), + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF Medium Bomb successfully pushed! (\x0700FF00+5 pts\x07FFFFFF)"); + sacPoints+=5, + bombStatusMax+=10, + bombStatus+=2, + CreateTimer(3.0, BombStatusAddTimer); + EmitSoundToAll(COUNTDOWN); + } + //Falling Star + case 4:{ + canSENTStars = true, + FireEntityInput("MedExplosionSND", "PlaySound", "", 0.0), + FireEntityInput("MediumExplosion", "Explode", "", 0.0), + FireEntityInput("MedExploShake", "StartShake", "", 0.0), + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF Average Bomb successfully pushed! (\x0700FF00+10 pts\x07FFFFFF)"); + sacPoints+=10, + bombStatusMax+=10, + bombStatus+=2, + CreateTimer(3.0, BombStatusAddTimer); + EmitSoundToAll(COUNTDOWN), + CreateTimer(1.0, SENTStarTimer), + CreateTimer(60.0, SENTStarDisable); + } + //Major Kong + case 5:{ + FireEntityInput("MajorKongSND", "PlaySound", "", 0.0), + FireEntityInput("FB.Fade", "Fade", "", 1.7), + FireEntityInput("LargeExplosion", "Explode", "", 1.7), + FireEntityInput("LargeExplosionSound", "PlaySound", "", 1.7), + FireEntityInput("LargeExploShake", "StartShake", "", 1.7), + FireEntityInput("NukeAll", "Enable", "", 1.7), + FireEntityInput("NukeAll", "Disable", "", 3.0), + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07AA0000 NUCLEAR WARHEAD\x07FFFFFF successfully pushed! (\x0700FF00+25 pts\x07FFFFFF)"); + sacPoints+=25, + bombStatusMax+=10, + bombStatus+=4, + CreateTimer(3.0, BombStatusAddTimer); + EmitSoundToAll(COUNTDOWN); + } + //Large (shark) + case 6:{ + FireEntityInput("LargeExploSound", "PlaySound", "", 0.0), + FireEntityInput("LargeExplosion", "Explode", "", 0.0), + FireEntityInput("LargeExploShake", "StartShake", "", 0.0), + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF Heavy Bomb successfully pushed! (\x0700FF00+15 pts\x07FFFFFF)"); + sacPoints+=15, + bombStatusMax+=10, + bombStatus+=4, + CreateTimer(3.0, BombStatusAddTimer); + EmitSoundToAll(COUNTDOWN); + } + //FatMan + case 7:{ + FireEntityInput("HindenburgBoom", "PlaySound", "", 0.0), + FireEntityInput("LargeExplosion", "Explode", "", 0.0), + FireEntityInput("LargeExploShake", "StartShake", "", 0.0), + FireEntityInput("", "PlaySound", "", 0.0), + FireEntityInput("NukeAll", "Enable", "", 0.0), + FireEntityInput("FB.Fade", "Fade", "", 0.0), + FireEntityInput("NukeAll", "Disable", "", 3.0), + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07AA0000 NUCLEAR WARHEAD\x07FFFFFF successfully pushed! (\x0700FF00+25 pts\x07FFFFFF)"); + sacPoints+=25, + bombStatusMax+=10, + bombStatus+=4, + CreateTimer(3.0, BombStatusAddTimer); + CreateTimer(15.0, SpecTimer); + EmitSoundToAll(COUNTDOWN); + } + //Hydrogen + case 8:{ + FireEntityInput("HindenburgBoom", "PlaySound", "", 0.0), + FireEntityInput("LargeExplosion", "Explode", "", 0.0), + FireEntityInput("LargeExploShake", "StartShake", "", 0.0), + FireEntityInput("LargeExplosionSND", "PlaySound", "", 0.0), + FireEntityInput("NukeAll", "Enable", "", 0.0), + FireEntityInput("FB.Fade", "Fade", "", 0.0), + FireEntityInput("NukeAll", "Disable", "", 3.0), + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07AA0000 HINDENBURG\x07FFFFFF successfully fueled! (\x0700FF00+30 pts\x07FFFFFF)"); + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team has delivered Hydrogen! The \x07FF0000HINDENBURG \x0700AA55is now ready for flight!"); + FireEntityInput("DeliveryBurg", "Unlock", "", 0.0); + bombStatus = 0; + explodeType = 0; + CreateTimer(3.0, BombStatusAddTimer); + EmitSoundToAll(COUNTDOWN); + } + //Fartsy of the Seventh Taco Bell + case 69:{ + FireEntityInput("NukeAll", "Enable", "", 0.0), + FireEntityInput("HindenburgBoom", "PlaySound", "", 0.0), + FireEntityInput("FB.Fade", "Fade", "", 0.0), + FireEntityInput("NukeAll", "Disable", "", 2.0), + bombStatusMax=64; + CreateTimer(5.0, NextWaveTimer); + } + } + return Plugin_Handled; + } + //Shark Enable + case 20:{ + CreateTimer(3.0, SharkTimer); + } + //Shark Disable + case 21:{ + canSENTShark = false; + } + //HINDENBOOM!!! + case 29:{ + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF OH GOD, THEY'RE \x07AA0000CRASHING THE HINDENBURG\x07FFFFFF!!!"); + FireEntityInput("HindenburgInc2", "PlaySound", "", 5.0); + FireEntityInput("LargeExplosion", "Explode", "", 7.0); + FireEntityInput("LargeExploShake", "StartShake", "", 7.0); + FireEntityInput("NukeAll", "Enable", "", 7.0); + FireEntityInput("HindenburgBoom", "PlaySound", "", 7.0); + FireEntityInput("FB.Fade", "Fade", "", 7.0); + FireEntityInput("NukeAll", "Disable", "", 9.0); + FireEntityInput("Bombs.TheHindenburg", "Disable", "", 7.0); + FireEntityInput("HindenTrain", "TeleportToPathTrack", "Hinden01", 7.0); + FireEntityInput("HindenTrain", "Stop", "", 7.0); + CreateTimer(9.0, NextWaveTimer); + bombStatus= 4; + bombStatusMax = 8; + explodeType = 0; + } + //Bath Salts spend + case 30:{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF INSTANT BATH SALT DETONATION! (\x07FF0000-10 pts\x07FFFFFF)"); + sacPoints = (sacPoints - 10); + FireEntityInput("BTN.Sacrificial*", "Color", "0 0 0", 0.0), + FireEntityInput("BTN.Sacrificial01", "Lock", "", 0.0), + FireEntityInput("MedExploShake", "StartShake", "", 0.10), + FireEntityInput("MedExplosionSND", "PlaySound", "", 0.10), + FireEntityInput("MediumExplosion", "Explode", "", 0.10); + } + //Fat man spend + case 31:{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF INSTANT FAT MAN DETONATION! (\x07FF0000-20 pts\x07FFFFFF)"); + sacPoints = (sacPoints - 20); + FireEntityInput("BTN.Sacrificial*", "Color", "0 0 0", 0.0); + FireEntityInput("BTN.Sacrificial02", "Lock", "", 0.0); + FireEntityInput("LargeExplosion", "Explode", "", 0.0); + FireEntityInput("LargeExploShake", "StartShake", "", 0.0); + FireEntityInput("NukeAll", "Enable", "", 0.0); + FireEntityInput("HindenburgBoom", "PlaySound", "", 0.0); + FireEntityInput("FB.Fade", "Fade", "", 0.0); + FireEntityInput("NukeAll", "Disable", "", 2.0); + } + //Goob/Kirb spend + case 32:{ + int x = GetRandomInt(1, 2); + switch (x){ + case 1:{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF GOOBBUE COMING IN FROM ORBIT! (\x07FF0000-30 pts\x07FFFFFF)"); + sacPoints = (sacPoints - 30); + EmitSoundToAll(GOOBBUEINCOMING); + FireEntityInput("HindenburgInc2", "PlaySound", "", 1.5); + FireEntityInput("FB.GiantGoobTemplate", "ForceSpawn", "", 3.0); + } + case 2:{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF BLUE KIRBY FALLING OUT OF THE SKY! (\x07FF0000-30 pts\x07FFFFFF)"); + sacPoints = (sacPoints - 30); + FireEntityInput("FB.BlueKirbTemplate", "ForceSpawn", "", 0.0); + EmitSoundToAll(FALLSND0B); + } + } + } + //Explosive paradise spend + case 33:{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF We're spending most our lives living in an EXPLOSIVE PARADISE! (\x07FF0000-40 pts\x07FFFFFF)"); + sacPoints = (sacPoints - 40); + } + //Ass Gas spend + case 34:{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF NO NO NO, STOP THE SHARTS!!!! (\x07FF0000-40 pts\x07FFFFFF)"); + sacPoints = (sacPoints - 40); + } + //Banish tornadoes for the wave + case 35:{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF A PINK KIRBY HAS BANISHED TORNADOES FOR THIS WAVE! (\x07FF0000-50 pts\x07FFFFFF)"); + KillTornado(); + canTornado = false; + sacPoints = (sacPoints - 50); + } + //Nuclear fallout spend + case 36:{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF TOTAL ATOMIC ANNIHILATION. (\x07FF0000-60 pts\x07FFFFFF)"); + sacPoints = (sacPoints - 60); + canSENTNukes = true; + CreateTimer(1.0, SENTNukeTimer); + CreateTimer(45.0, DisableSENTNukes); + } + //Meteor shower spend + case 37:{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF COSMIC DEVASTATION IMMINENT. (\x07FF0000-70 pts\x07FFFFFF)"); + sacPoints = (sacPoints - 70); + canSENTMeteors = true; + CreateTimer(1.0, SENTMeteorTimer); + CreateTimer(30.0, DisableSENTMeteors); + } + //Fartsy of the Seventh Taco Bell + case 38:{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF NOW PRESENTING... PROFESSOR FARTSALOT OF THE SEVENTH TACO BELL! (\x07FF0000-100 points\x07FFFFFF)"); + sacPoints = (sacPoints - 100); + explodeType = 69; + FireEntityInput("Delivery", "Unlock", "", 0.0), + FireEntityInput("BombExplo*", "Disable", "", 0.0), + FireEntityInput("Bombs.*", "Disable", "", 0.0), + FireEntityInput("Bombs.Professor", "Enable", "", 3.0); + } + //Found blue ball + case 40:{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55What on earth IS that? It appears to be a... \x075050FFBLUE BALL\x07FFFFFF!"); + EmitSoundToAll(FALLSND0B); + FireEntityInput("FB.BlueKirbTemplate", "ForceSpawn", "", 4.0); + FireEntityInput("HindenburgInc2", "PlaySound", "", 4.0); + } + //Found burrito + case 41:{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Why would you even eat \x07FF0000The Forbidden Burrito\x07FFFFFF?"); + } + //Found goobbue + case 42:{ + EmitSoundToAll(GOOBBUEINCOMING); + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55ALL HAIL \x07FF00FFGOOBBUE\x0700AA55!"); + FireEntityInput("HindenburgInc2", "PlaySound", "", 3.0); + FireEntityInput("FB.GiantGoobTemplate", "ForceSpawn", "", 3.0); + } + //Found Mario + case 43:{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Welp, someone is playing \x0700FF00Mario\x07FFFFFF..."); + } + //Found Waffle + case 44:{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Oh no, someone has found and (probably) consumed a \x07FF0000WAFFLE OF MASS DESTRUCTION\x07FFFFFF!"); + } + //Prev wave + case 98:{ + int ent = FindEntityByClassname(-1, "tf_objective_resource"); + if(ent == -1) + { + LogMessage("tf_objective_resource not found"); + return Plugin_Handled; + } + + int current_wave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineWaveCount")); + int max_wave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineMaxWaveCount")); + int prev_wave = current_wave - 1; + if(prev_wave >= max_wave) + { + PrintToChatAll("\x07AA0000[ERROR] \x07FFFFFFHOW THE HELL DID WE GET HERE?!"); + return Plugin_Handled; + } + + if(prev_wave < 1) + { + PrintToChatAll("\x07AA0000[ERROR] \x07FFFFFFWE CAN'T JUMP TO WAVE 0, WHY WOULD YOU TRY THAT??"); + return Plugin_Handled; + } + JumpToWave(prev_wave); + } + //Next wave + case 99:{ + int ent = FindEntityByClassname(-1, "tf_objective_resource"); + if(ent == -1) + { + LogMessage("tf_objective_resource not found"); + return Plugin_Handled; + } + + int current_wave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineWaveCount")); + int max_wave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineMaxWaveCount")); + int next_wave = current_wave + 1; + if(next_wave > max_wave) + { + int flags = GetCommandFlags("tf_mvm_force_victory"); + SetCommandFlags("tf_mvm_force_victory", flags & ~FCVAR_CHEAT); + ServerCommand("tf_mvm_force_victory 1"); + FakeClientCommand(0, ""); //Not sure why, but this has to be here. Otherwise the specified commands simply refuse to work... + SetCommandFlags("tf_mvm_force_victory", flags|FCVAR_CHEAT); + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF VICTORY HAS BEEN FORCED! THE SERVER WILL RESTART IN 10 SECONDS."); + CreateTimer(10.0, Timer_RestartServer); + return Plugin_Handled; + } + JumpToWave(next_wave); + } + //Code Entry from FC Keypad + case 100:{ + if (CodeEntry == 17){ + FireEntityInput("FB.BOOM", "StartShake", "", 0.0), + FireEntityInput("FB.CodeCorrect", "PlaySound", "", 0.0), + FireEntityInput("FB.CodeCorrectKill", "Enable", "", 0.0), + FireEntityInput("FB.KP*", "Lock", "", 0.0), + FireEntityInput("FB.CodeCorrectKill", "Disable", "", 1.0); + } + else{ + CodeEntry = 0; + FireEntityInput("FB.CodeFailedKill", "Enable", "", 0.0), + FireEntityInput("FB.CodeFailedKill", "Disable", "", 1.0), + FireEntityInput("FB.CodeFailedSND", "PlaySound", "", 0.0); + } + } + case 101:{ + CodeEntry++; + } + case 102:{ + CodeEntry+=2; + } + case 103:{ + CodeEntry+=3; + } + case 104:{ + CodeEntry+=4; + } + case 105:{ + CodeEntry+=5; + } + case 106:{ + CodeEntry+=6; + } + case 107:{ + CodeEntry+=7; + } + case 108:{ + CodeEntry+=8; + } + case 109:{ + CodeEntry+=9; + } + //Taco Bell Edition + case 210:{ + PrintToChatAll("\x070000AA[\x07AAAA00INFO\x070000AA] \x07FFFFFFYou have chosen \x07AA0000DOVAH'S ASS - TACO BELL EDITION\x07FFFFFF. Why... Why would you DO THIS?! Do you not realize what you've just done?????"); + } + //Taco Bell GetWave + case 211:{ + //GetTacoBellWave(0); + PrintToChatAll("WARNING, THIS IS NOT IMPLEMENTED YET. PLEASE DO NOT PLAY TACO BELL EDITION AT THIS POINT IN TIME."); + } + //Taco Bell Victory + case 255:{ + PrintToChatAll("WOWIE YOU DID IT! The server will restart in 30 seconds, prepare to do it again! LULW"); + CreateTimer(30.0, Timer_RestartServer); + } + } + return Plugin_Handled; +} \ No newline at end of file diff --git a/scripting/FallingBack.sp-impossiblelogic.sp b/scripting/FallingBack.sp-impossiblelogic.sp new file mode 100644 index 0000000..631f6ad --- /dev/null +++ b/scripting/FallingBack.sp-impossiblelogic.sp @@ -0,0 +1,1243 @@ +#include +#include +#pragma newdecls required +#pragma semicolon 1 +bool iswave = false; +bool bgmlock1 = true; +bool bgmlock2 = true; +bool bgmlock3 = true; +bool bgmlock4 = true; +bool bgmlock5 = true; +bool bgmlock6 = true; +bool bgmlock7 = true; +bool bgmlock8 = true; +int bombStatus = 0; +int bombStatusMax = 0; +int bombsPushed = 0; +int bombCache = 0; + +public Plugin myinfo = +{ + name = "Dovah's Ass - Framework", + author = "Fartsy#0001", + description = "Framework for Dovah's Ass", + version = "1.2.6", + url = "https://forums.firehostredux.com" +}; + +public void OnPluginStart() +{ + //RegServerCmd("fb_gotowave4", Command_JumpToWave4, "Jump to wave 4 - DO NOT TOUCH, WILL LIKELY MESS STUFF UP."), //REPLACED BY fb_nextwave and fb_previouswave + //RegServerCmd("fb_gotowave6", Command_JumpToWave6, "Jump to wave 6 - DO NOT TOUCH, WILL LIKELY MESS STUFF UP."), + RegServerCmd("fb_forcevictory", Command_ForceVictory, "FORCE victory - DO NOT TOUCH, WILL LIKELY MESS STUFF UP."), + RegServerCmd("fb_trainincoming", Command_TrainIncoming, "A train is incoming!"), + RegServerCmd("fb_atomicbmbrain", Command_AtomBmbRain, "Atom bombs are now raining from the sky!"), + RegServerCmd("fb_ohnoes", Command_OhNoes, "Oh noes, prepare your anus!"), + RegServerCmd("fb_meteorincoming", Command_MeteorIncoming, "Meteor incoming!"), + RegServerCmd("fb_meteorshower", Command_MeteorShower, "Meteor Shower incoming!"), + RegServerCmd("fb_prepareyourself", Command_DovahsAss, "You have chosen Dovah's Ass, prepare yourself..."), + RegServerCmd("fb_wave1", Command_WaveOne, "Wave one started."), + RegServerCmd("fb_wave1_bmbavail", Command_WaveOneBombUp, "Wave one - bomb available."), + RegServerCmd("fb_wave2", Command_WaveTwo, "Wave two started."), + RegServerCmd("fb_wave2_bmbavail", Command_WaveTwoBombUp, "Wave two - bomb available."), + RegServerCmd("fb_wave3", Command_WaveThree, "Wave three started."), + RegServerCmd("fb_wave3_bmbavail", Command_WaveThreeBombUp, "Wave three - bomb available."), + RegServerCmd("fb_wave4", Command_WaveFour, "Wave four started."), + RegServerCmd("fb_wave4_bmbavail", Command_WaveFourBombUp, "Wave four - bomb available."), + RegServerCmd("fb_wave5", Command_WaveFive, "Wave five started."), + RegServerCmd("fb_wave5_bmbavail", Command_WaveFiveBombUp, "Wave five - bomb available."), + RegServerCmd("fb_wave6", Command_WaveSix, "Wave six started."), + RegServerCmd("fb_wave6_bmbavail", Command_WaveSixBombUp, "Wave six - bomb available."), + RegServerCmd("fb_wave7", Command_WaveSeven, "Wave seven started."), + RegServerCmd("fb_wave7_bmbavail", Command_WaveSevenBombUp, "Fat Man - bomb available."), + RegServerCmd("fb_hydrogenup", Command_HydrogenUp, "Hydrogen available."), + RegServerCmd("fb_wave8", Command_WaveEight, "Wave eight started."), + RegServerCmd("fb_burgup", Command_WaveSevenBurgUp, "Wave seven - burg up!"), + RegServerCmd("fb_foundgoob", Command_FoundGoob, "ALL HAIL GOOBBUE!"), + RegServerCmd("fb_foundwaffle", Command_FoundWaffle, "Why do they call it the waffle of mass destruction if it does nothing!?"), + RegServerCmd("fb_foundburrito", Command_FoundBurrito, "Forbidden Burrito. Yum."), + RegServerCmd("fb_foundshroom", Command_FoundShroom, "What does this even do!?"), + RegServerCmd("fb_foundball", Command_FoundBall, "Incoming blue ball..."), + RegServerCmd("fb_tsplus1", Command_TSPlus1, "Tornado sacrifice -- plus one!"), + RegServerCmd("fb_dpsacplus1", Command_DPSacPlus1, "Death pit sacrofice -- plus one!"), + RegServerCmd("fb_ksacplus1", Command_KissoneSacPlus1, "KissoneTM sacrifice -- plus one!"), + RegServerCmd("fb_bresplus5", Command_BombResPlus5, "Bomb reset -- plus five!"), + RegServerCmd("fb_sbathsalts", Command_BathSaltsSacMinus10, "Bath salts, minus ten!"), + RegServerCmd("fb_sfatman", Command_FatManSacMinus20, "Fat man, minus twenty!"), + RegServerCmd("fb_sgoobbue", Command_GoobbueSacMinus30, "Goobbue, minus thirty!"), + RegServerCmd("fb_skirb", Command_BlueBallSacMinus30, "Blue ball, minus thirty!"), + RegServerCmd("fb_sgboom", Command_GBoomSacMinus40, "Explosive paradise, minus fourty!"), + RegServerCmd("fb_assgas", Command_AssGasMinus40, "Ass gas, minus fourty!"), + RegServerCmd("fb_skirbward", Command_KirbyWardSacMinus50, "KIRBY HAS BANISHED TORNADOES!"), + RegServerCmd("fb_snfo", Command_NFOSacMinus60, "Atomic bomb rain, minus sixty!"), + RegServerCmd("fb_smeteors", Command_MeteorsSacMinus70, "Meteors, minus seventy!"), + RegServerCmd("fb_sdovah", Command_DovahSacMinus100, "Professor Fartsalot, minus one hundred!"), + RegServerCmd("fb_prevwave", Command_JumpToPrevWave, "Jump to previous wave."), + RegServerCmd("fb_nextwave", Command_JumpToNextWave, "Jump to next wave."), + RegServerCmd("fb_bombpushplus5", Command_BombPushPlusFive, "Bomb pushed - plus five!"), + RegServerCmd("dovahsass_finished", Command_DovahsAssFinished, "DovahsAss has been completed!"), + RegServerCmd("fb_tacobell", Command_TacoBell, "Just why?"), + RegServerCmd("tacobell_wave01", Command_TBWave01,"Taco Bell - Wave One"), + RegServerCmd("tacobell_wave02", Command_TBWave02,"Taco Bell - Wave Two"), + RegServerCmd("tacobell_wave03", Command_TBWave03,"Taco Bell - Wave Three"), + RegServerCmd("tacobell_wave04", Command_TBWave04,"Taco Bell - Wave Four"), + RegServerCmd("tacobell_wave05", Command_TBWave05,"Taco Bell - Wave Five"), + RegServerCmd("tacobell_wave06", Command_TBWave06,"Taco Bell - Wave Six"), + RegServerCmd("tacobell_wave07", Command_TBWave07,"Taco Bell - Wave Seven"), + RegServerCmd("tacobell_wave08", Command_TBWave08,"Taco Bell - Wave Eight"), + RegServerCmd("tacobell_wave09", Command_TBWave09,"Taco Bell - Wave Nine"), + RegServerCmd("tacobell_wave10", Command_TBWave10,"Taco Bell - Wave Ten"), + RegServerCmd("tacobell_wave11", Command_TBWave11,"Taco Bell - Wave Eleven"), + RegServerCmd("tacobell_wave12", Command_TBWave12,"Taco Bell - Wave Twelve"), + RegServerCmd("tacobell_wave13", Command_TBWave13,"Taco Bell - Wave Thirteen"), + RegServerCmd("tacobell_wave14", Command_TBWave14,"Taco Bell - Wave Fourteen"), + RegServerCmd("tacobell_wave15", Command_TBWave15,"Taco Bell - Wave Fifteen"), + RegServerCmd("tacobell_wave16", Command_TBWave16,"Taco Bell - Wave Sixteen"), + RegServerCmd("tacobell_wave17", Command_TBWave17,"Taco Bell - Wave Seventeen"), + RegServerCmd("tacobell_wave18", Command_TBWave18,"Taco Bell - Wave Eighteen"), + RegServerCmd("tacobell_wave19", Command_TBWave19,"Taco Bell - Wave Nineteen"), + RegServerCmd("tacobell_wave20", Command_TBWave20,"Taco Bell - Wave Twenty"), + RegServerCmd("tacobell_wave21", Command_TBWave21,"Taco Bell - Wave Twenty-One"), + RegServerCmd("tacobell_finished", Command_TacoBellFinished, "TacoBell has been completed!"), + RegServerCmd("fb_fire", Command_FBFire, "Operator for Professor's Ass."), + RegServerCmd("fb_wavefinished", Command_FBWaveComplete, "Wave finished."), + RegConsoleCmd("sm_bombstatus", Command_FBBombStatus, "Check bomb status"), + HookEvent("player_death", EventDeath), + HookEvent("server_cvar", Event_Cvar, EventHookMode_Pre), + HookEvent("mvm_bomb_alarm_triggered", EventWarning), + HookEvent("mvm_bomb_reset_by_player", EventReset); +} + +//Now that command definitions are done, lets make some things happen. +public void OnMapStart() +{ + ServerCommand("fb_fire SNDSCPE_* disable"), + ServerCommand("fb_fire BombStatus disable"), + SelectBGM(); +} + +//Custom definitions +public Action SelectBGM() +{ + int BGM = GetRandomInt(1, 2); + ServerCommand("fb_fire Music.* StopSound"); + if (BGM == 1){ + ServerCommand("fb_fire Music.TheSilentRegardOfStars PlaySound"); + PrintToServer("Creating timer for The Silent Regard of Stars. Enjoy the music!"); + CreateTimer(137.75, RefireBGM); + } + else if (BGM == 2){ + ServerCommand("fb_fire Music.KnowledgeNeverSleeps PlaySound"); + PrintToServer("Creating timer for Knowledge Never Sleeps. Enjoy the music!"); + CreateTimer(235.5, RefireBGM); + } +} + +//Timers + +//BGM (Defaults) +public Action RefireBGM(Handle timer) +{ + if (!iswave){ + SelectBGM(); + } + return Plugin_Stop; +} + +//BGM (Locus) +public Action RefireLocus(Handle timer) +{ + if (!bgmlock1){ + ServerCommand("fb_fire Music.Locus StopSound; fb_fire Music.Locus PlaySound"); + CreateTimer(229.25, RefireLocus); + } + return Plugin_Stop; +} + +//BGM (Metal) +public Action RefireMetal(Handle timer) +{ + if (!bgmlock2){ + ServerCommand("fb_fire Music.Metal StopSound; fb_fire Music.Metal PlaySound"); + CreateTimer(153.95, RefireMetal); + } + return Plugin_Stop; +} + +//BGM (Exponential Entropy) +public Action RefireEntropy(Handle timer) +{ + if (!bgmlock3){ + ServerCommand("fb_fire Music.ExponentialEntropy StopSound; fb_fire Music.ExponentialEntropy PlaySound"); + CreateTimer(166.85, RefireEntropy); + } + return Plugin_Stop; +} + +//BGM (Torn From the Heavens) +public Action RefireTorn(Handle timer) +{ + if (!bgmlock4){ + ServerCommand("fb_fire Music.TornFromTheHeavens StopSound; fb_fire Music.TornFromTheHeavens PlaySound"); + CreateTimer(122.25, RefireTorn); + } + return Plugin_Stop; +} + +//BGM (Brute Justice Mode) +public Action RefireBJMode(Handle timer) +{ + if (!bgmlock5){ + ServerCommand("fb_fire Music.MetalBruteJusticeMode StopSound; fb_fire Music.MetalBruteJusticeMode PlaySound"); + CreateTimer(131.75, RefireBJMode); + } + return Plugin_Stop; +} + +//BGM (Grandma Destruction) +public Action RefireGrandma(Handle timer) +{ + if (!bgmlock6){ + ServerCommand("fb_fire Music.GrandmaDestruction StopSound; fb_fire Music.GrandmaDestruction PlaySound"); + CreateTimer(323.95, RefireGrandma); + } + return Plugin_Stop; +} + +//BGM (Revenge Twofold) +public Action RefireRevenge2F(Handle timer){ + if (!bgmlock7){ + ServerCommand("fb_fire Music.RevengeTwofold StopSound; fb_fire Music.RevengeTwofold PlaySound"); + CreateTimer(133.25, RefireRevenge2F); + } + return Plugin_Stop; +} + +//BGM (Under The Weight) +public Action RefireUnderTW(Handle timer){ + if (!bgmlock8){ + ServerCommand("fb_fire Music.UnderTheWeight StopSound; fb_fire Music.UnderTheWeight PlaySound"); + CreateTimer(313.85, RefireUnderTW); + } + return Plugin_Stop; +} + +//BombStatus (Add points to Bomb Status occasionally) +public Action BombStatusTimer(Handle timer){ + if (iswave && (bombStatus < bombStatusMax)){ + bombStatus++; + //ServerCommand("fb_fire BombStatus SetValue %i", bombStatus); //TODO: Delet me. I am no longer needed. + float f = GetRandomFloat(10.0, 45.0); + PrintToServer("[DEBUG] Creating a %f timer to give bomb status an update. Current target is %i", f, bombStatus); + CreateTimer(f, BombStatusTimer); + switch (bombStatus){ //new bombstatus parser + case 8:{ + bombStatusMax = 8; + bombCache = 0; + ServerCommand("fb_fire Bombs.* Disable; fb_fire BombExplo* Disable; fb_fire Delivery Unlock; fb_fire BombExploSmall Enable; fb_fire Bombs.FreedomBomb Enable"); + EmitSoundToAll("dovahki/misc/triggerscore.wav"); + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team's \x07FF0000FREEDOM BOMB \x0700AA55is now available for deployment!"); + } + case 16:{ + bombStatusMax = 16; + bombCache = 0; + ServerCommand("fb_fire Bombs.* Disable; fb_fire BombExplo* Disable; fb_fire Delivery Unlock; fb_fire BombExploMedium Enable; fb_fire Bombs.ElonBust Enable"); + EmitSoundToAll("dovahki/misc/triggerscore.wav"); + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team's \x07FF0000ELON BUST \x0700AA55is now available for deployment!"); + } + case 24:{ + bombStatusMax = 24; + bombCache = 0; + ServerCommand("fb_fire Bombs.* Disable; fb_fire BombExplo* Disable; fb_fire Delivery Unlock; fb_fire BombExploMedium Enable; fb_fire Bombs.BathSalts Enable"); + EmitSoundToAll("dovahki/misc/triggerscore.wav"); + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team's \x07FF0000BATH SALTS \x0700AA55are now available for deployment!"); + } + case 32:{ + bombStatusMax = 32; + bombCache = 0; + ServerCommand("fb_fire Bombs.* Disable; fb_fire BombExplo* Disable; fb_fire Delivery Unlock; fb_fire BombExploMedium Enable; fb_fire Bombs.FallingStar Enable; fb_fire BombExploFallingStar Enable"); + EmitSoundToAll("dovahki/misc/triggerscore.wav"); + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team's \x07FFFF00FALLING STAR\x0700AA55 is now available for deployment!"); + } + case 40:{ + bombStatusMax = 40; + bombCache = 0; + ServerCommand("fb_fire Bombs.* Disable; fb_fire BombExplo* Disable; fb_fire BombExploMedium Enable; fb_fire Delivery Unlock; fb_fire Bombs.MajorKong Enable; fb_fire BombExploMajorKong Enable"); + EmitSoundToAll("dovahki/misc/triggerscore.wav"); + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team's \x07FF0000MAJOR KONG \x0700AA55is now available for deployment!"); + } + case 48:{ + bombStatusMax = 48; + bombCache = 0; + ServerCommand("fb_fire Bombs.* Disable; fb_fire BombExplo* Disable; fb_fire BombExploLarge Enable; fb_fire Delivery Unlock; fb_fire Bombs.SharkTorpedo Enable; fb_fire BombExploShark Enable"); + EmitSoundToAll("dovahki/misc/triggerscore.wav"); + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team's \x07FF0000SHARK \x0700AA55is now available for deployment!"); + } + case 56:{ + bombStatusMax = 56; + bombCache = 0; + ServerCommand("fb_fire Bombs.* Disable; fb_fire BombExplo* Disable; fb_fire Bombs.FatMan Enable; fb_fire Delivery Unlock; fb_fire BombExploFatMan Enable"); + EmitSoundToAll("dovahki/misc/triggerscore.wav"); + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team's \x07FF0000FAT MAN \x0700AA55is now available for deployment!"); + } + } + } + return Plugin_Stop; +} +//Command action definitions +public Action Command_FBWaveComplete(int args) +{ + bgmlock1 = true; + bgmlock2 = true; + bgmlock3 = true; + bgmlock4 = true; + bgmlock5 = true; + bgmlock6 = true; + bgmlock7 = true; + bgmlock8 = true; + iswave = false; + SelectBGM(); + PrintToChatAll("\x0700FF00[CORE] \x07FFFFFFYou've defeated the wave!"); +} + +public Action Command_FBBombStatus(int client, int args){ + PrintToChat(client, "\x0700FF00[CORE] \x07FFFFFFThe bomb status is currently %i", bombStatus); + //No bombs have yet been deployed nor have they been unlocked. + if (bombStatus <= 7){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Bombs are \x07FF0000NOT AVAILABLE\x07FFFFFF!"); + } + //Only execute if Freedom Bomb is available. + else if (bombStatus >= 8 && bombStatus < 16){ + //If no bombs are pushed and next bomb IS ready. + if (bombsPushed == 0 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team has not deployed any bombs, however: Your team's \x07FF0000FREEDOM BOMB \x0700AA55is available for deployment!"); + } + //If we've pushed the Freedom Bomb and next bomb is NOT ready. + else if(bombsPushed == 1 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFFREEDOM BOMB \x0700AA55. Please wait for the next bomb."); + } + return Plugin_Continue; + } + //Only execute if Elon Bust is available. + else if(bombStatus >= 16 && bombStatus < 24){ + //If no bombs are pushed and next bomb IS ready. Should probably not be possible? + //if (bombsPushed == 0 && bombCache == 0){ + // PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team has not deployed any bombs, however: Your team's \x07FF0000ELON BUST \x0700AA55is available for deployment! This shouldn't even have been //possible!"); + //} + //If we've pushed the Freedom Bomb and next bomb is NOT ready. Should not be possible. + //else if (bombsPushed == 1 && bombCache == 1){ + // PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFFREEDOM BOMB \x0700AA55. Please wait for the next bomb. 8 > 16 ???"); + //} + + //If we've pushed the Freedom Bomb and next bomb IS ready. + else if (bombsPushed == 1 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFFREEDOM BOMB \x0700AA55. Your team's \x07FF0000ELON BUST \x0700AA55is available for deployment!"); + } + //If we've pushed the Freedom Bomb and the Elon Bust and next bomb is NOT ready. + else if(bombsPushed == 2 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FF0000ELON BUST \x0700AA55. Please wait for the next bomb."); + } + return Plugin_Continue; + } + //Only execute if Bath Salts are available. + else if(bombStatus >= 24 && bombStatus < 32){ + //If no bombs are pushed and next bomb IS ready. Should probably not be possible? + if (bombsPushed == 0 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team has not deployed any bombs, however: Your team's \x07FF0000BATH SALTS \x0700AA55are available for deployment!"); + } + //If we've pushed the Freedom Bomb and the next bomb is NOT ready. This should not be possible? + else if(bombsPushed == 1 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FF0000FREEDOM BOMB \x0700AA55. Please wait for the next bomb. But wait shouldnt this have been pushed?"); + } + //If we've pushed the Freedom Bomb and the next bomb is ready. This also probably should not be possible right? + else if (bombsPushed == 1 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFFREEDOM BOMB \x0700AA55. Your team's \x07FF0000ELON BUST \x0700AA55are available for deployment! Probably not possible though!"); + } + //If we've pushed the Freedom Bomb and Elon Bust and the next bomb is NOT ready. Should not be possible either. + else if(bombsPushed == 2 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FF0000ELON BUST \x0700AA55. Please wait for the next bomb. How is 16 equal to 24?"); + } + + //If we've pushed the Freedom Bomb and the Elon Bust and the next bomb IS ready. + else if (bombsPushed == 2 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFELON BUST \x0700AA55. Your team's \x07FF0000BATH SALTS \x0700AA55are available for deployment!"); + } + //If we've pushed the Freedom Bomb, Elon Bust, and Bath Salts and the next bomb is NOT ready. + else if (bombsPushed == 3 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFBATH SALTS \x0700AA55. Please wait for the next bomb."); + } + return Plugin_Continue; + } + else if (bombStatus >= 32 && bombStatus < 40){ + //If no bombs are pushed and next bomb IS ready. Should probably not be possible? + if (bombsPushed == 0 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team has not deployed any bombs, however: Your team's \x07FF0000BATH SALTS \x0700AA55are available for deployment!"); + } + //If we've pushed the Freedom Bomb and the next bomb is NOT ready. This should not be possible? + else if(bombsPushed == 1 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FF0000FREEDOM BOMB \x0700AA55. Please wait for the next bomb."); + } + //If we've pushed the Freedom Bomb and the Elon Bust and the next bomb IS ready. + else if (bombsPushed == 1 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFFREEDOM BOMB \x0700AA55. Your team's \x07FF0000ELON BUST \x0700AA55is available for deployment!"); + } + //If we've pushed the Freedom Bomb and Elon Bust and the next bomb is NOT ready. Should not be possible either. + else if(bombsPushed == 2 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FF0000ELON BUST \x0700AA55. Please wait for the next bomb."); + } + //If we've pushed the Freedom Bomb and Elon Bust and the next bomb IS ready. Should not be possible either. + else if(bombsPushed == 2 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FF0000ELON BUST \x0700AA55. Please wait for the next bomb."); + } + //If we've pushed the Freedom Bomb, Elon Bust, and Bath Salts and the next bomb is NOT ready. + else if (bombsPushed == 3 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFBATH SALTS \x0700AA55. Please wait for the next bomb."); + } + //If we've pushed the Freedom Bomb, Elon Bust, and Bath Salts, and the next bomb IS ready. + else if (bombsPushed == 3 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFBATH SALTS \x0700AA55. Your team's \x07FF0000Falling Star \x0700AA55is available for deployment!"); + } + //If we've pushed the Freedom Bomb, Elon Bust, Bath Salts, and Falling Star and the next bomb IS NOT ready. + else if (bombsPushed == 4 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFFALLING STAR \x0700AA55. Please wait for the next bomb."); + } + return Plugin_Continue; + } + else if (bombStatus >= 40 && bombStatus < 48){ + //If no bombs are pushed and next bomb IS ready. Should probably not be possible? + if (bombsPushed == 0 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team has not deployed any bombs, however: Your team's \x07FF0000BATH SALTS \x0700AA55are available for deployment!"); + } + //If we've pushed the Freedom Bomb and the next bomb is NOT ready. This should not be possible? + else if(bombsPushed == 1 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FF0000FREEDOM BOMB \x0700AA55. Please wait for the next bomb."); + } + //If we've pushed the Freedom Bomb and the next bomb is ready. This also probably should not be possible right? + else if (bombsPushed == 1 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFFREEDOM BOMB \x0700AA55. Your team's \x07FF0000BATH SALTS \x0700AA55are available for deployment!"); + } + //If we've pushed the Freedom Bomb and Elon Bust and the next bomb is NOT ready. Should not be possible either. + else if(bombsPushed == 2 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FF0000ELON BUST \x0700AA55. Please wait for the next bomb."); + } + //If we've pushed the Freedom Bomb and the Elon Bust and the next bomb IS ready. + else if (bombsPushed == 2 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFELON BUST \x0700AA55. Your team's \x07FF0000BATH SALTS \x0700AA55are available for deployment!"); + } + //If we've pushed the Freedom Bomb, Elon Bust, and Bath Salts and the next bomb is NOT ready. + else if (bombsPushed == 3 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFBATH SALTS \x0700AA55. Please wait for the next bomb."); + } + //If we've pushed the Freedom Bomb, Elon Bust, and Bath Salts, and the next bomb IS ready. + else if (bombsPushed == 3 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFBATH SALTS \x0700AA55. Your team's \x07FF0000FALLING STAR \x0700AA55is available for deployment!"); + } + //If we've pushed the Freedom Bomb, Elon Bust, Bath Salts, and Falling Star and the next bomb IS NOT ready. + else if (bombsPushed == 4 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFFALLING STAR \x0700AA55. Please wait for the next bomb."); + } + //If we've pushed the Freedom Bomb, Elon Bust, Bath Salts, and Falling Star and the next bomb IS ready. + else if (bombsPushed == 4 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFFALLING STAR \x0700AA55. Your team's \x07FF0000MAJOR KONG \x0700AA55is available for deployment!"); + } + //If we've pushed the Freedom Bomb, Elon Bust, Bath Salts, Falling Star, and Major Kong and the next bomb is NOT ready. + else if (bombsPushed == 5 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFMAJOR KONG \x0700AA55. Please wait for the next bomb."); + } + } + else if (bombStatus >= 48 && bombStatus < 56){ + //If no bombs are pushed and next bomb IS ready. Should probably not be possible? + if (bombsPushed == 0 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team has not deployed any bombs, however: Your team's \x07FF0000BATH SALTS \x0700AA55are available for deployment!"); + } + //If we've pushed the Freedom Bomb and the next bomb is NOT ready. This should not be possible? + else if(bombsPushed == 1 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FF0000FREEDOM BOMB \x0700AA55. Please wait for the next bomb."); + } + //If we've pushed the Freedom Bomb and the next bomb is ready. This also probably should not be possible right? + else if (bombsPushed == 1 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFFREEDOM BOMB \x0700AA55. Your team's \x07FF0000BATH SALTS \x0700AA55are available for deployment!"); + } + //If we've pushed the Freedom Bomb and Elon Bust and the next bomb is NOT ready. Should not be possible either. + else if(bombsPushed == 2 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FF0000ELON BUST \x0700AA55. Please wait for the next bomb."); + } + //If we've pushed the Freedom Bomb and the Elon Bust and the next bomb IS ready. + else if (bombsPushed == 2 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFELON BUST \x0700AA55. Your team's \x07FF0000BATH SALTS \x0700AA55are available for deployment!"); + } + //If we've pushed the Freedom Bomb, Elon Bust, and Bath Salts and the next bomb is NOT ready. + else if (bombsPushed == 3 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFBATH SALTS \x0700AA55. Please wait for the next bomb."); + } + //If we've pushed the Freedom Bomb, Elon Bust, and Bath Salts, and the next bomb IS ready. + else if (bombsPushed == 3 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFBATH SALTS \x0700AA55. Your team's \x07FF0000FALLING STAR \x0700AA55is available for deployment!"); + } + //If we've pushed the Freedom Bomb, Elon Bust, Bath Salts, and Falling Star and the next bomb IS NOT ready. + else if (bombsPushed == 4 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFFALLING STAR \x0700AA55. Please wait for the next bomb."); + } + //If we've pushed the Freedom Bomb, Elon Bust, Bath Salts, and Falling Star and the next bomb IS ready. + else if (bombsPushed == 4 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFFALLING STAR \x0700AA55. Your team's \x07FF0000MAJOR KONG \x0700AA55is available for deployment!"); + } + //If we've pushed the Freedom Bomb, Elon Bust, Bath Salts, Falling Star, and Major Kong and the next bomb is NOT ready. + else if (bombsPushed == 5 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFMAJOR KONG \x0700AA55. Please wait for the next bomb."); + } + //If we've pushed the Freedom Bomb, Elon Bust, Bath Salts, Falling Star, and Major Kong and the next bomb IS ready. + else if (bombsPushed == 5 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFMAJOR KONG \x0700AA55. Your team's \x07FF0000SHARK \x0700AA55is available for deployment!"); + } + //If we've pushed the Freedom Bomb, Elon Bust, Bath Salts, Falling Star, Major Kong, and Shark and the next bomb IS NOT ready. + else if (bombsPushed == 6 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFSHARK \x0700AA55. Please wait for the next bomb."); + } + } + else if (bombStatus >= 56 && bombStatus < 64){ + //If no bombs are pushed and next bomb IS ready. Should probably not be possible? + if (bombsPushed == 0 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team has not deployed any bombs, however: Your team's \x07FF0000BATH SALTS \x0700AA55are available for deployment!"); + } + //If we've pushed the Freedom Bomb and the next bomb is NOT ready. This should not be possible? + else if(bombsPushed == 1 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FF0000FREEDOM BOMB \x0700AA55. Please wait for the next bomb."); + } + //If we've pushed the Freedom Bomb and the next bomb is ready. This also probably should not be possible right? + else if (bombsPushed == 1 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFFREEDOM BOMB \x0700AA55. Your team's \x07FF0000BATH SALTS \x0700AA55are available for deployment!"); + } + //If we've pushed the Freedom Bomb and Elon Bust and the next bomb is NOT ready. Should not be possible either. + else if(bombsPushed == 2 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FF0000ELON BUST \x0700AA55. Please wait for the next bomb."); + } + //If we've pushed the Freedom Bomb and the Elon Bust and the next bomb IS ready. + else if (bombsPushed == 2 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFELON BUST \x0700AA55. Your team's \x07FF0000BATH SALTS \x0700AA55are available for deployment!"); + } + //If we've pushed the Freedom Bomb, Elon Bust, and Bath Salts and the next bomb is NOT ready. + else if (bombsPushed == 3 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFBATH SALTS \x0700AA55. Please wait for the next bomb."); + } + //If we've pushed the Freedom Bomb, Elon Bust, and Bath Salts, and the next bomb IS ready. + else if (bombsPushed == 3 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFBATH SALTS \x0700AA55. Your team's \x07FF0000FALLING STAR \x0700AA55is available for deployment!"); + } + //If we've pushed the Freedom Bomb, Elon Bust, Bath Salts, and Falling Star and the next bomb IS NOT ready. + else if (bombsPushed == 4 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFFALLING STAR \x0700AA55. Please wait for the next bomb."); + } + //If we've pushed the Freedom Bomb, Elon Bust, Bath Salts, and Falling Star and the next bomb IS ready. + else if (bombsPushed == 4 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFFALLING STAR \x0700AA55. Your team's \x07FF0000MAJOR KONG \x0700AA55is available for deployment!"); + } + //If we've pushed the Freedom Bomb, Elon Bust, Bath Salts, Falling Star, and Major Kong and the next bomb is NOT ready. + else if (bombsPushed == 5 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFMAJOR KONG \x0700AA55. Please wait for the next bomb."); + } + //If we've pushed the Freedom Bomb, Elon Bust, Bath Salts, Falling Star, and Major Kong and the next bomb IS ready. + else if (bombsPushed == 5 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFMAJOR KONG \x0700AA55. Your team's \x07FF0000SHARK \x0700AA55is available for deployment!"); + } + //If we've pushed the Freedom Bomb, Elon Bust, Bath Salts, Falling Star, Major Kong, and Shark and the next bomb IS NOT ready. + else if (bombsPushed == 6 && bombCache == 1){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed a \x07FFFFFFSHARK \x0700AA55. Please wait for the next bomb."); + } + //If we've pushed the Freedom Bomb, Elon Bust, Bath Salts, Falling Star, Major Kong, and Shark and the next bomb IS ready. + else if (bombsPushed == 6 && bombCache == 0){ + PrintToChat(client, "\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team recently deployed \x07FFFFFFSHARK \x0700AA55. Your team's \x07FF0000FAT MAN \x0700AA55is available for deployment!"); + } + } + else if (bombStatus >= 64 && bombStatus < 72){ + PrintToChatAll("wowie you did it you hit 72!"); + } + return Plugin_Handled; +} + +public Action Command_ForceVictory(int args) +{ + int flags = GetCommandFlags("tf_mvm_force_victory"); + SetCommandFlags("tf_mvm_force_victory", flags & ~FCVAR_CHEAT); + ServerCommand("tf_mvm_force_victory 1"); + FakeClientCommand(0, ""); //Not sure why, but this has to be here. Otherwise the specified commands simply refuse to work... + SetCommandFlags("tf_mvm_force_victory", flags|FCVAR_CHEAT); + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF VICTORY HAS BEEN FORCED! THE SERVER WILL RESTART IN 10 SECONDS."); + CreateTimer(10.0, Timer_RestartServer); +} + +public Action Command_TrainIncoming(int args) +{ + PrintToChatAll("\x070000AA[\x07AA0000WARN\x070000AA] \x07AA7000KISSONE'S TRAIN\x07FFFFFF is \x07AA0000INCOMING\x07FFFFFF. Look out!"); +} + +public Action Command_AtomBmbRain(int args) +{ + PrintToChatAll("\x070000AA[\x07AA0000WARN\x070000AA] \x07FFFFFFUh oh, it's begun to rain \x07AA0000ATOM BOMBS\x07FFFFFF! TAKE COVER!"); +} + +public Action Command_OhNoes(int args) +{ + PrintToChatAll("\x070000AA[\x07AA0000WARN\x070000AA] \x07FFFFFFOh noes, prepare your anus! A \x07AA0000TORNADO WARNING\x07FFFFFF has been issued! TAKE COVER NOW!!!"); +} + +public Action Command_MeteorIncoming(int args) +{ + PrintToChatAll("\x070000AA[\x07AA0000WARN\x070000AA] \x07FFFFFFUh oh, a \x07AA0000METEOR\x07FFFFFF has been spotted coming towards Dovah's Ass!!!"); +} + +public Action Command_MeteorShower(int args) +{ + PrintToChatAll("\x070000AA[\x07AA0000WARN\x070000AA] \x07FFFFFFUh oh, a \x07AA0000METEOR SHOWER\x07FFFFFF has been reported from Dovah's Ass!!!"); +} + +public Action Command_DovahsAss(int args) +{ + PrintToChatAll("\x070000AA[\x07AAAA00INFO\x070000AA] \x07FFFFFFYou have chosen \x07AA0000DOVAH'S ASS\x07FFFFFF. Prepare yourself for the unpredictable..."); +} + +public Action Command_WaveOne(int args) +{ + bgmlock1 = false; + bgmlock2 = true; + bgmlock3 = true; + bgmlock4 = true; + bgmlock5 = true; + bgmlock6 = true; + bgmlock7 = true; + bgmlock8 = true; + iswave = true; + bombStatusMax = 8; + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 1: Locus"); + ServerCommand("fb_fire Music.* StopSound"); + ServerCommand("fb_fire Music.Locus PlaySound"); + CreateTimer(229.25, RefireLocus); + CreateTimer(1.0, BombStatusTimer); +} + +public Action Command_WaveOneBombUp(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00LEGACY\x070000AA] \x0700AA55Your team's \x07FF0000FREEDOM BOMB \x0700AA55is now available for deployment!"); +} + +public Action Command_WaveTwo(int args) +{ + bgmlock1 = true; + bgmlock2 = false; + bgmlock3 = true; + bgmlock4 = true; + bgmlock5 = true; + bgmlock6 = true; + bgmlock7 = true; + bgmlock8 = true; + iswave = true; + bombStatusMax = 16; + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 2: Metal"); + ServerCommand("fb_fire Music.* StopSound"); + ServerCommand("fb_fire Music.Metal PlaySound"); + CreateTimer(153.95, RefireMetal); + CreateTimer(1.0, BombStatusTimer); +} + +public Action Command_WaveTwoBombUp(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00LEGACY\x070000AA] \x0700AA55Your team's \x07FF0000ELON BUST \x0700AA55is now available for deployment!"); +} + +public Action Command_WaveThree(int args) +{ + bgmlock1 = true; + bgmlock2 = true; + bgmlock3 = false; + bgmlock4 = true; + bgmlock5 = true; + bgmlock6 = true; + bgmlock7 = true; + bgmlock8 = true; + iswave = true; + bombStatusMax = 24; + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 3: Exponential Entropy"); + ServerCommand("fb_fire Music.* StopSound"); + ServerCommand("fb_fire Music.ExponentialEntropy PlaySound"); + CreateTimer(166.85, RefireEntropy); + CreateTimer(1.0, BombStatusTimer); +} + +public Action Command_WaveThreeBombUp(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00LEGACY\x070000AA] \x0700AA55Your team's \x07FF0000BATH SALTS \x0700AA55are now available for deployment!"); +} + +public Action Command_WaveFour(int args) +{ + bgmlock1 = true; + bgmlock2 = true; + bgmlock3 = true; + bgmlock4 = false; + bgmlock5 = true; + bgmlock6 = true; + bgmlock7 = true; + bgmlock8 = true; + iswave = true; + bombStatusMax = 32; + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 4: Torn From The Heavens"); + ServerCommand("fb_fire Music.* StopSound"); + ServerCommand("fb_fire Music.TornFromTheHeavens PlaySound"); + CreateTimer(122.25, RefireTorn); + CreateTimer(1.0, BombStatusTimer); +} + +public Action Command_WaveFourBombUp(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00LEGACY\x070000AA] \x0700AA55Your team's \x07FFFF00FALLING STAR\x0700AA55 is now available for deployment!"); +} + +public Action Command_WaveFive(int args) +{ + bgmlock1 = true; + bgmlock2 = true; + bgmlock3 = true; + bgmlock4 = true; + bgmlock5 = false; + bgmlock6 = true; + bgmlock7 = true; + bgmlock8 = true; + iswave = true; + bombStatusMax = 40; + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 5: Metal - Brute Justice Mode"); + ServerCommand("fb_fire Music.* StopSound"); + ServerCommand("fb_fire Music.MetalBruteJusticeMode PlaySound"); + CreateTimer(131.75, RefireBJMode); + CreateTimer(1.0, BombStatusTimer); +} + +public Action Command_WaveFiveBombUp(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00LEGACY\x070000AA] \x0700AA55Your team's \x07FF0000MAJOR KONG \x0700AA55is now available for deployment!"); +} + +public Action Command_WaveSix(int args) +{ + bgmlock1 = true; + bgmlock2 = true; + bgmlock3 = true; + bgmlock4 = true; + bgmlock5 = true; + bgmlock6 = false; + bgmlock7 = true; + bgmlock8 = true; + iswave = true; + bombStatusMax = 48; + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 6: Grandma Destruction"); + ServerCommand("fb_fire Music.* StopSound"); + ServerCommand("fb_fire Music.GrandmaDestruction PlaySound"); + CreateTimer(323.95, RefireGrandma); + CreateTimer(1.0, BombStatusTimer); +} + +public Action Command_WaveSixBombUp(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00LEGACY\x070000AA] \x0700AA55Your team's \x07FF0000SHARK \x0700AA55is now available for deployment!"); +} + +public Action Command_WaveSeven(int args) +{ + bgmlock1 = true; + bgmlock2 = true; + bgmlock3 = true; + bgmlock4 = true; + bgmlock5 = true; + bgmlock6 = true; + bgmlock7 = false; + bgmlock8 = true; + iswave = true; + bombStatusMax = 56; + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 7: Revenge Twofold"); + ServerCommand("fb_fire Music.* StopSound"); + ServerCommand("fb_fire Music.RevengeTwofold PlaySound"); + CreateTimer(133.25, RefireRevenge2F); + CreateTimer(1.0, BombStatusTimer); +} + +public Action Command_WaveSevenBombUp(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00LEGACY\x070000AA] \x0700AA55Your team's \x07FF0000FAT MAN \x0700AA55is now available for deployment!"); +} + +public Action Command_HydrogenUp(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team's \x07FF0000HYDROGEN \x0700AA55is now available for deployment!"); +} + +public Action Command_WaveSevenBurgUp(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Your team has delivered Hydrogen! The \x07FF0000HINDENBURG \x0700AA55is now ready for flight!"); +} + +public Action Command_WaveEight(int args) +{ + bgmlock1 = true; + bgmlock2 = true; + bgmlock3 = true; + bgmlock4 = true; + bgmlock5 = true; + bgmlock6 = true; + bgmlock7 = true; + bgmlock8 = false; + iswave = true; + bombStatusMax = 64; + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 8: Under The Weight"); + ServerCommand("fb_fire Music.* StopSound"); + ServerCommand("fb_fire Music.UnderTheWeight PlaySound"); + CreateTimer(313.85, RefireUnderTW); + CreateTimer(1.0, BombStatusTimer); +} + +public Action Command_FoundGoob(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55ALL HAIL \x07FF00FFGOOBBUE\x0700AA55!"); +} + +public Action Command_FoundWaffle(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Oh no, someone has found and (probably) consumed a \x07FF0000WAFFLE OF MASS DESTRUCTION\x07FFFFFF!"); +} + +public Action Command_FoundBurrito(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Why would you even eat \x07FF0000The Forbidden Burrito\x07FFFFFF?"); +} + +public Action Command_FoundShroom(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55Welp, someone is playing \x0700FF00Mario\x07FFFFFF..."); +} + +public Action Command_FoundBall(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55What on earth IS that? It appears to be a... \x075050FFBLUE BALL\x07FFFFFF!"); +} + +public Action Command_TSPlus1(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF Sacrificed a client into orbit. (\x0700FF00+1 pt\x07FFFFFF)"); +} + +public Action Command_DPSacPlus1(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF Sent a client to their doom. (\x0700FF00+1 pt\x07FFFFFF)"); +} + +public Action Command_KissoneSacPlus1(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF Dunked a client into liquid death. (\x0700FF00+1 pt\x07FFFFFF)"); +} + +public Action Command_BombResPlus5(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF Bomb has been reset. (\x0700FF00+5 pts\x07FFFFFF)"); +} + +public Action Command_BathSaltsSacMinus10(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF INSTANT BATH SALT DETONATION! (\x07FF0000-10 pts\x07FFFFFF)"); +} + +public Action Command_FatManSacMinus20(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF INSTANT FAT MAN DETONATION! (\x07FF0000-20 pts\x07FFFFFF)"); +} + +public Action Command_GoobbueSacMinus30(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF GOOBBUE COMING IN FROM ORBIT! (\x07FF0000-30 pts\x07FFFFFF)"); +} + +public Action Command_BlueBallSacMinus30(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF BLUE KIRBY FALLING OUT OF THE SKY! (\x07FF0000-30 pts\x07FFFFFF)"); +} + +public Action Command_GBoomSacMinus40(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF We're spending most our lives living in an EXPLOSIVE PARADISE! (\x07FF0000-40 pts\x07FFFFFF)"); +} + +public Action Command_AssGasMinus40(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF NO NO NO, STOP THE SHARTS!!!! (\x07FF0000-40 pts\x07FFFFFF)"); +} + +public Action Command_KirbyWardSacMinus50(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF A PINK KIRBY HAS BANISHED TORNADOES FOR THIS WAVE! (\x07FF0000-50 pts\x07FFFFFF)"); +} + +public Action Command_NFOSacMinus60(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF TOTAL ATOMIC ANNIHILATION. (\x07FF0000-60 pts\x07FFFFFF)"); +} + +public Action Command_MeteorsSacMinus70(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF COSMIC DEVASTATION IMMINENT. (\x07FF0000-70 pts\x07FFFFFF)"); +} + +public Action Command_DovahSacMinus100(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF NOW PRESENTING... PROFESSOR FARTSALOT OF THE HINDENBURG! (\x07FF0000-100 points\x07FFFFFF)"); +} + +public Action Command_BombPushPlusFive(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF Bomb successfully pushed! (\x0700FF00+5 pts\x07FFFFFF)"); + bombStatusMax = (bombStatusMax + 8); + bombsPushed++; + bombCache = 1; + CreateTimer(3.0, BombStatusTimer); +} + +public Action Command_DovahsAssFinished(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF YOU HAVE SUCCESSFULLY COMPLETED DOVAH'S ASS ! THE SERVER WILL RESTART IN 10 SECONDS."); + CreateTimer(10.0, Timer_RestartServer); +} + +//Taco Bell edition commands and features +public Action Command_TacoBell(int args) +{ + PrintToChatAll("\x070000AA[\x07AAAA00INFO\x070000AA] \x07FFFFFFYou have chosen \x07AA0000DOVAH'S ASS - TACO BELL EDITION\x07FFFFFF. Why... Why would you DO THIS?! Do you not realize what you've just done?????"); +} + +public Action Command_TBWave01(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 01: Battle On The Big Bridge"); +} + +public Action Command_TBWave02(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 02: Locus"); +} + +public Action Command_TBWave03(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 03: Metal"); +} + +public Action Command_TBWave04(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 04: Torn From The Heavens"); +} + +public Action Command_TBWave05(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 05: Exponential Entropy"); +} + +public Action Command_TBWave06(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 06: Grandma Destruction"); +} + +public Action Command_TBWave07(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 07: Rise"); +} + +public Action Command_TBWave08(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 08: Metal - Brute Justice Mode"); +} + +public Action Command_TBWave09(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 09: Locus"); +} + +public Action Command_TBWave10(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 10: Exponential Entropy"); +} + +public Action Command_TBWave11(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 11: Revenge Twofold"); +} + +public Action Command_TBWave12(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 12: Metal"); +} + +public Action Command_TBWave13(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 13: Grandma Destruction"); +} + +public Action Command_TBWave14(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 14: Under The Weight"); +} + +public Action Command_TBWave15(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 15: Metal - Brute Justice Mode"); +} + +public Action Command_TBWave16(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 16: Exponential Entropy"); +} + +public Action Command_TBWave17(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 17: Locus"); +} + +public Action Command_TBWave18(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 18: Torn From The Heavens"); +} + +public Action Command_TBWave19(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 19: Metal"); +} + +public Action Command_TBWave20(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 20: Grandma Destruction"); +} + +public Action Command_TBWave21(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 21: Battle on the Big Bridge"); +} + +public Action Command_TacoBellFinished(int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF YOU HAVE SUCCESSFULLY COMPLETED DOVAH'S ASS - TACO BELL EDITION! THE SERVER WILL RESTART IN 10 SECONDS."); + CreateTimer(10.0, Timer_RestartServer); +} + +//Check who died by what and announce it to chat. +public Action EventDeath(Event Spawn_Event, const char[] Spawn_Name, bool Spawn_Broadcast) +{ + int client = GetClientOfUserId(Spawn_Event.GetInt("userid")); + int attacker = GetClientOfUserId(Spawn_Event.GetInt("attacker")); + char weapon[32]; + Spawn_Event.GetString("weapon", weapon, sizeof(weapon)); + if (0 < client <= MaxClients && IsClientInGame(client)) + { + int damagebits = Spawn_Event.GetInt("damagebits"); + if ((damagebits & (1 << 0)) && !attacker) //DMG_CRUSH + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N was crushed by a \x07AA0000FALLING ROCK FROM OUTER SPACE\x07FFFFFF!", client); + } + + if ((damagebits & (1 << 3)) && !attacker) //DMG_BURN + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N was \x07AA0000MELTED\x07FFFFFF.", client); + } + + if ((damagebits & (1 << 4)) && !attacker) //DMG_VEHICLE (DMG_FREEZE) + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N was flattened out by a \x07AA0000TRAIN\x07FFFFFF!", client); + } + + if ((damagebits & (1 << 5)) && !attacker) //DMG_FALL + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N was \x07AA0000YEETED OUT INTO ORBIT\x07FFFFFF!", client); + } + + if ((damagebits & (1 << 6)) && !attacker) //DMG_BLAST + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N went \x07AA0000 KABOOM\x07FFFFFF!", client); + } + + if ((damagebits & (1 << 7)) && !attacker) //DMG_CLUB + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N is \x07AA0000CRASHING THE HINDENBURG\x07FFFFFF!!!", client); + } + + if ((damagebits & (1 << 8)) && !attacker) //DMG_SHOCK + { + PrintToChatAll("\x070000AA[\x07AA0000EXTERMINATUS\x070000AA]\x07FFFFFF Client %N has humliated themselves with an \x07AA0000incorrect \x07FFFFFFkey entry!", client); + } + + if ((damagebits & (1 << 9)) && !attacker) //DMG_SONIC + { + PrintToChatAll("\x070000AA[\x07AA0000EXTERMINATUS\x070000AA]\x07FFFFFF Client %N has sacrificed themselves with a \x0700AA00correct \x07FFFFFFkey entry! Prepare your anus!", client); + } + + if ((damagebits & (1 << 10)) && !attacker) //DMG_ENERGYBEAM + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N has been vaporized by a \x07AA0000HIGH ENERGY PHOTON BEAM\x07FFFFFF!", client); + } + + if ((damagebits & (1 << 14)) && !attacker) //DMG_DROWN + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N \x07AA0000DROWNED\x07FFFFFF.", client); + } + + if ((damagebits & (1 << 15)) && !attacker) //DMG_PARALYZE + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N has been crushed by a \x070000AAMYSTERIOUS BLUE BALL\x07FFFFFF!", client); + } + + if ((damagebits & (1 << 16)) && !attacker) //DMG_NERVEGAS + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N has been \x07AA0000SLICED TO RIBBONS\x07FFFFFF!", client); + } + + if ((damagebits & (1 << 17)) && !attacker) //DMG_POISON + { + ServerCommand("sm_psay %d \x07FF0000[\x0700FF00ADMIN\x07FF0000] \x07AAAAAAPlease don't sit IDLE in the FC Tavern. Repeated offenses may result in a kick."); + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N was killed for standing in the Tavern instead of helping their team!", client); + } + + if ((damagebits & (1 << 18)) && !attacker) //DMG_RADIATION + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N was blown away by a \x07AA0000NUCLEAR EXPLOSION\x07FFFFFF!", client); + } + + if ((damagebits & (1 << 19)) && !attacker) //DMG_DROWNRECOVER + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N experienced \x07AA0000TACO BELL\x07FFFFFF!", client); + } + + if ((damagebits & (1 << 20)) && !attacker) //DMG_ACID + { + PrintToChatAll("\x070000AA[\x07AA0000CORE\x070000AA]\x07FFFFFF Client %N has been crushed by a \x0700AA00FALLING GOOBBUE FROM OUTER SPACE\x07FFFFFF!", client); + } + } + return Plugin_Handled; +} + +//Silence cvar changes to minimize chat spam. +public Action Event_Cvar(Event event, const char[] name, bool dontBroadcast) +{ + event.BroadcastDisabled = true; +} + +//Announce when we are in danger. +public Action EventWarning(Event Spawn_Event, const char[] Spawn_Name, bool Spawn_Broadcast) +{ + PrintToChatAll("\x070000AA[\x07AA0000WARN\x070000AA]\x07AA0000 WARNING\x07FFFFFF: \x07AA0000DOVAH'S ASS IS ABOUT TO BE DEPLOYED!!!"); +} + +//Announce the bomb has been reset by client %N. +public Action EventReset(Event Spawn_Event, const char[] Spawn_Name, bool Spawn_Broadcast) +{ + int client = Spawn_Event.GetInt("player"); + if (0 < client <= MaxClients && IsClientInGame(client)) + { + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFF Client \x0700AA00%N\x07FFFFFF has reset the ass!", client); + } + return Plugin_Handled; +} + +//Used by various entities to jump us to the previous wave. +public Action Command_JumpToPrevWave(int args) +{ + int ent = FindEntityByClassname(-1, "tf_objective_resource"); + if(ent == -1) + { + LogMessage("tf_objective_resource not found"); + return; + } + + int current_wave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineWaveCount")); + int max_wave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineMaxWaveCount")); + int prev_wave = current_wave - 1; + if(prev_wave >= max_wave) + { + PrintToChatAll("\x07AA0000[ERROR] \x07FFFFFFHOW THE HELL DID WE GET HERE?!"); + return; + } + + if(prev_wave < 1) + { + PrintToChatAll("\x07AA0000[ERROR] \x07FFFFFFWE CAN'T JUMP TO WAVE 0, WHY WOULD YOU TRY THAT??"); + return; + } + JumpToWave(prev_wave); +} + +//Used by various entities to jump us to the next wave. +public Action Command_JumpToNextWave(int args) +{ + int ent = FindEntityByClassname(-1, "tf_objective_resource"); + if(ent == -1) + { + LogMessage("tf_objective_resource not found"); + return; + } + + int current_wave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineWaveCount")); + int max_wave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineMaxWaveCount")); + int next_wave = current_wave + 1; + if(next_wave > max_wave) + { + ServerCommand("fb_forcevictory"); + return; + } + JumpToWave(next_wave); +} + +//Jump to the wave. +public Action JumpToWave(int wave_number) +{ + int flags = GetCommandFlags("tf_mvm_jump_to_wave"); + SetCommandFlags("tf_mvm_jump_to_wave", flags & ~FCVAR_CHEAT); + ServerCommand("tf_mvm_jump_to_wave %d", wave_number); + FakeClientCommand(0, ""); + SetCommandFlags("tf_mvm_jump_to_wave", flags|FCVAR_CHEAT); +} + +//Timer to restart the server. +public Action Timer_RestartServer(Handle timer) +{ + ServerCommand("_restart"); +} + +//Handle FB Operator Requests via entfire +public Action Command_FBFire(int args) +{ + char arg1[128], arg2[128], arg3[32], arg4[8]; + float flDelay; + GetCmdArg(1, arg1, sizeof(arg1)); + GetCmdArg(2, arg2, sizeof(arg2)); + GetCmdArg(3, arg3, sizeof(arg3)); + GetCmdArg(4, arg4, sizeof(arg4)); + flDelay = StringToFloat(arg4); + FireEntityInput(arg1, arg2, arg3, flDelay); + return Plugin_Handled; +} + +//Create a temp entity and fire an input +public Action FireEntityInput(char[] strTargetname, char[] strInput, char[] strParameter, float flDelay) +{ + char strBuffer[255]; + Format(strBuffer, sizeof(strBuffer), "OnUser1 %s:%s:%s:%f:1", strTargetname, strInput, strParameter, flDelay); + PrintToChatAll("\x0700FF00[CORE] \x07FFFFFF Firing entity %s with input %s , a parameter override of %s , and delay of %f ...", strTargetname, strInput, strParameter, flDelay); + int entity = CreateEntityByName("info_target"); + if(IsValidEdict(entity)) + { + DispatchSpawn(entity); + ActivateEntity(entity); + SetVariantString(strBuffer); + AcceptEntityInput(entity, "AddOutput"); + AcceptEntityInput(entity, "FireUser1"); + CreateTimer(0.0, DeleteEdict, entity); + return Plugin_Continue; + } + return Plugin_Handled; +} + +//Remove edict allocated by temp entity +public Action DeleteEdict(Handle timer, any entity) +{ + if(IsValidEdict(entity)) RemoveEdict(entity); + return Plugin_Stop; +} \ No newline at end of file diff --git a/scripting/FallingBack.sp.bak b/scripting/FallingBack.sp.bak new file mode 100644 index 0000000..e8267c7 --- /dev/null +++ b/scripting/FallingBack.sp.bak @@ -0,0 +1,91 @@ +#include +//#include + +#pragma semicolon 1 + +public Plugin myinfo = +{ + name = "Falling Back Framework", + author = "DovahKingWarrior#0001", + description = "Framework for Falling Back", + version = "1.0.0", + url = "https://forums.firehostredux.com" +}; + +public void OnPluginStart() +{ + RegAdminCmd("fb_wave1", Command_WaveOne, ADMFLAG_ROOT, "Wave one started."), + RegAdminCmd("fb_wave1_bmbavail", Command_WaveOneBombUp, ADMFLAG_ROOT, "Wave one - bomb available."), + RegAdminCmd("fb_wave2", Command_WaveTwo, ADMFLAG_ROOT, "Wave two started."), + RegAdminCmd("fb_wave3", Command_WaveThree, ADMFLAG_ROOT, "Wave three started."), + RegAdminCmd("fb_wave4", Command_WaveFour, ADMFLAG_ROOT, "Wave four started."), + RegAdminCmd("fb_wave5", Command_WaveFive, ADMFLAG_ROOT, "Wave five started."), + RegAdminCmd("fb_wave6", Command_WaveSix, ADMFLAG_ROOT, "Wave six started."), + RegAdminCmd("fb_wave7", Command_WaveSeven, ADMFLAG_ROOT, "Wave seven started."), + HookEvent("player_death", EventDeath); +// RegAdminCmd("fb_failed", Command_KeyEntryfailed, ADMFLAG_ROOT, "Client %s failed key entry."); //WORK IN PROGRESS +} + +public Action Command_WaveOne(int client, int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA]\x07FFFFFFWave 1: Locus"); +} + +public Action Command_WaveOneBombUp(int client, int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00LOCUS\x070000AA] \x0700AA55RED's \x07FF0000WARHEAD \x0700AA55is now available for deployment!"); +} + +public Action Command_WaveTwo(int client, int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 2: Grandma Destruction"); +} + +public Action Command_WaveTwoBombUp(int client, int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x0700AA55RED's \x07FF0000#BOMBNAME# \x0700AA55is now available for deployment!"); +} + +public Action Command_WaveThree(int client, int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 3: Exponential Entropy"); +} + +public Action Command_WaveFour(int client, int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 4: Torn From The Heavens"); +} + +public Action Command_WaveFive(int client, int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 5: Metal - Brute Justice Mode"); +} + +public Action Command_WaveSix(int client, int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 6: Under The Weight"); +} + +public Action Command_WaveSeven(int client, int args) +{ + PrintToChatAll("\x070000AA[\x0700AA00CORE\x070000AA] \x07FFFFFFWave 7: Revenge Twofold"); +} + +//Check who died by what, missing some data however. +public Action EventDeath(Handle:Spawn_Event, String:Spawn_Name[], bool:Spawn_Broadcast) +{ + new client = GetClientOfUserId(GetEventInt(Spawn_Event, "userid")); +// new attacker = GetClientOfUserId(GetEventInt(Spawn_Event, "attacker")); //UNUSED RIGHT NOW, MAY BE USED LATER. + new String:weapon[32]; + GetEventString(Spawn_Event, "weapon", weapon, 32); + if (!(client == 0)) + { +// new customkill = GetEventInt(Spawn_Event, "customkill"); // if (customkill == 6) // Unknown what this really is or does, so removed for now. + new damagebits = GetEventInt(Spawn_Event, "damagebits"); + if (damagebits == 256) + { + PrintToChatAll("Client %N has humliated themself with an incorrect key entry!", client); + } + } + return Plugin_Handled; +} diff --git a/scripting/FartsysAss - v5.4.0.sp b/scripting/FartsysAss - v5.4.0.sp new file mode 100644 index 0000000..8fb6e7e --- /dev/null +++ b/scripting/FartsysAss - v5.4.0.sp @@ -0,0 +1,4389 @@ +/* WELCOME TO FARTSY'S ASS ROTTENBURG. + * + * A FEW THINGS TO KNOW: ONE.... THIS IS INTENDED TO BE USED WITH UBERUPGRADES. + * TWO..... THE MUSIC USED WITH THIS MOD MAY OR MAY NOT BE COPYRIGHTED. WE HAVE NO INTENTION ON INFRINGEMENT. + * THREE..... THIS MOD IS INTENDED FOR USE ON THE FIREHOSTREDUX SERVERS ONLY. SUPPORT IS LIMITED. + * FOUR..... THIS WAS A NIGHTMARE TO FIGURE OUT AND BUG FIX. I HOPE IT WAS WORTH IT. + * FIVE..... PLEASE HAVE FUN AND ENJOY YOURSELF! + * SIX..... THE DURATION OF MUSIC TIMERS SHOULD BE SET DEPENDING WHAT SONG IS USED. SET THIS USING THE FLOATS BGMDur BELOW. + * SEVEN..... TIPS AND TRICKS MAY BE ADDED TO THE TIMER, SEE PerformAdverts(Handle timer); + * + * GL HF!!! + * For Taco bell edition, target ass_relay with trigger for InitWaveOutput and FireUser2 for StartWaveOutput. FireUser3 still acts as boss dead relay, and FireUser4 will act as map completion. + * Also for taco bell edition, pop file needs to be updated for boss spawns to work as intended. See normal edition pop script. + */ +#include +#include +#include +#include +#include +#include +#pragma newdecls required +#pragma semicolon 1 +bool tickMusic = false; +int ticksMusic = 0; +bool bombProgression = false; +bool bombReset = false; //used for notifying us when Event mvm_bomb_reset_by_player doesn't.... +bool brawler_emergency = false; +bool canCrusaderNuke = false; +bool canHindenburg = false; +bool canHWBoss = false; +bool canMusicLoop = false; +bool canSENTMeteors = false; +bool canSENTNukes = false; +bool canSENTShark = false; +bool canSENTStars = false; +bool canSephNuke = false; +bool canTornado = false; +bool crusader = false; +bool isWave = false; +bool monitorOn = false; +bool monitorColor = true; +bool sephiroth = false; +bool stopPrevSong = false; +bool tornado = false; +bool tacobell = false; +bool tickingClientHealth = false; +bool sacrificedByClient = false; +bool TornadoWarningIssued = false; +Database FB_Database; +static char BELL[32] = "fartsy/misc/bell.wav"; +static char BGM1[32] = "fartsy/music/ffxiv/locus.mp3"; +static char BGM2[32] = "fartsy/music/ffxiv/metal.mp3"; +static char BGM3[64] = "fartsy/music/ffxiv/exponentialentropy.mp3"; +static char BGM4[64] = "fartsy/music/ffxiv/tornfromtheheavens.mp3"; +static char BGM5[64] = "fartsy/music/ffxiv/metalbrutejusticemode.mp3"; +static char BGM6[64] = "fartsy/music/ffxiv/penitus.mp3"; +static char BGM7[64] = "fartsy/music/ffxiv/revengetwofold.mp3"; +static char BGM8[64] = "fartsy/music/ffxiv/landslide.mp3"; +static char BGM9[64] = "fartsy/music/brawler/xbc2/battle.mp3"; +static char BGM9Intro[64] = "fartsy/music/brawler/xbc2/battle_intro.mp3"; +static char BGM10Intro[48] = "fartsy/music/brawler/onewingedintro.mp3"; +static char BGM10[64] = "fartsy/music/brawler/onewingedangel.mp3"; +static char BGM11[64] = "fartsy/music/brawler/xbc/youwillknowournames.mp3"; +static char BGM12[64] = "fartsy/music/demetori/unowen.mp3"; +static char BGM100[48] = "fartsy/music/ffxiv/TornColossusPhase1.mp3"; +static char BGM101[48] = "fartsy/music/ffxiv/TornColossusPhase2.mp3"; +static char BGM1Title[32] = "FFXIV - Locus"; +static char BGM2Title[32] = "FFXIV - Metal"; +static char BGM3Title[32] = "FFXIV - Exponential Entropy"; +static char BGM4Title[32] = "FFXIV - Torn From the Heavens"; +static char BGM5Title[64] = "FFXIV - Metal: Brute Justice Mode"; +static char BGM6Title[32] = "FFXIV - Penitus"; +static char BGM7Title[32] = "FFXIV - Revenge Twofold"; +static char BGM8Title[32] = "FFXIV - Landslide"; +static char BGM9Title[64] = "Xenoblade Chronicles 2 - Battle!!"; +static char BGM10Title[64] = "FF Advent Children - One Winged Angel"; +static char BGM11Title[64] = "Xenoblade Chronicles - You Will Know Our Names"; +static char BGM12Title[64] = "Demetori - U.N. Owen Was Her?"; +static char BGM100Title[64] = "FFXIV - Torn From The Heavens Dark Colossus (Phase 1)"; +static char BGM101Title[64] = "FFXIV - Torn From The Heavens Dark Colossus (Phase 2)"; +static char BMB1SND[32] = "fartsy/misc/murica.mp3"; +static char BMB2SND[32] = "fartsy/bl2/grenade_detonate.mp3"; +static char BMB3SND[32] = "fartsy/gbombs5/t_12.mp3"; +static char BMB4SND[32] = "fartsy/misc/majorkong.mp3"; +static char BOOM[32] = "fartsy/vo/spongebob/boom.mp3"; +static char CLOCKTICK[32] = "fartsy/misc/clock_tick.wav"; +static char COUNTDOWN[32] = "fartsy/misc/countdown.wav"; +static char CRUSADERATTACK[64] = "fartsy/misc/fartsyscrusader_attack.mp3"; +char curSong[64], prevSong[64] = "null"; +char s[128] = "null"; +char songName[64] = "null"; +static char DEFAULTBGM1[64] = "fartsy/music/ffxiv/TheSilentRegardOfStars.mp3"; +static char DEFAULTBGM2[64] = "fartsy/music/ffxiv/KnowledgeNeverSleeps.mp3"; +static char DEFAULTBGM3[64] = "fartsy/music/ffxiv/frommud.mp3"; +static char DEFAULTBGM1Title[64] = "FFXIV - The Silent Regard of Stars"; +static char DEFAULTBGM2Title[64] = "FFXIV - Knowledge Never Sleeps"; +static char DEFAULTBGM3Title[64] = "FFXIV - From Mud"; +static char DROPNUKE[32] = "items/cart_warning_single.wav"; +static char EVENTSTART[32] = "fartsy/ffxiv/bossfatejoin.mp3"; +static char EXPLOSIVEPARADISE[64] = "fartsy/misc/explosiveparadise.mp3"; +static char FALLSND01[32] = "fartsy/vo/l4d2/billfall02.mp3"; +static char FALLSND02[32] = "fartsy/vo/l4d2/coachfall02.mp3"; +static char FALLSND03[32] = "fartsy/vo/l4d2/ellisfall01.mp3"; +static char FALLSND04[64] = "fartsy/vo/l4d2/francisfall02.mp3"; +static char FALLSND05[32] = "fartsy/vo/l4d2/louisfall01.mp3"; +static char FALLSND06[32] = "fartsy/vo/l4d2/louisfall03.mp3"; +static char FALLSND07[32] = "fartsy/vo/l4d2/nickfall01.mp3"; +static char FALLSND08[32] = "fartsy/vo/l4d2/zoeyfall01.mp3"; +static char FALLSND09[32] = "fartsy/vo/ddd/woahhh.mp3"; +static char FALLSND0A[64] = "fartsy/vo/jigglypuff/jigglypuff.mp3"; +static char FALLSND0B[32] = "fartsy/vo/kirby/eeeahhhh.mp3"; +static char FALLSND0C[32] = "fartsy/vo/luigi/ohohohohoo.mp3"; +static char FALLSND0D[32] = "fartsy/vo/mario/wahahahaha.mp3"; +static char FALLSND0E[32] = "fartsy/vo/pika/pikapika.mp3"; +static char FALLSND0F[32] = "fartsy/vo/wario/wheee.mp3"; +static char FALLSND10[32] = "fartsy/vo/mario/wowww.mp3"; +static char GLOBALTHUNDER01[32] = "fartsy/weather/thunder1.wav"; +static char GLOBALTHUNDER02[32] = "fartsy/weather/thunder2.wav"; +static char GLOBALTHUNDER03[32] = "fartsy/weather/thunder3.wav"; +static char GLOBALTHUNDER04[32] = "fartsy/weather/thunder4.wav"; +static char GLOBALTHUNDER05[32] = "fartsy/weather/thunder5.wav"; +static char GLOBALTHUNDER06[32] = "fartsy/weather/thunder6.wav"; +static char GLOBALTHUNDER07[32] = "fartsy/weather/thunder7.wav"; +static char GLOBALTHUNDER08[32] = "fartsy/weather/thunder8.wav"; +static char HINDENBURGBOOM[64] = "fartsy/gbombs5/tsar_detonate.mp3"; +static char HINDENCRASH[32] = "fartsy/vo/jeffy/hinden.wav"; +static char INCOMING[64] = "fartsy/vo/ddo/koboldincoming.wav"; +static char OnslaughterLaserSND[32] = "fartsy/misc/antimatter.mp3"; +static char OnslaughterFlamePreATK[32] = "weapons/flame_thrower_start.wav"; +static char OnslaughterFlamePostATK[32] = "weapons/flame_thrower_end.wav"; +static char PLUGIN_VERSION[8] = "5.4.0"; +static char RETURNSND[32] = "fartsy/ffxiv/return.mp3"; +static char RETURNSUCCESS[32] = "fartsy/ffxiv/returnsuccess.mp3"; +static char SHARKSND01[32] = "fartsy/memes/babyshark/baby.mp3"; +static char SHARKSND02[64] = "fartsy/memes/babyshark/baby02.mp3"; +static char SHARKSND03[64] = "fartsy/memes/babyshark/doot01.mp3"; +static char SHARKSND04[64] = "fartsy/memes/babyshark/doot02.mp3"; +static char SHARKSND05[64] = "fartsy/memes/babyshark/doot03.mp3"; +static char SHARKSND06[64] = "fartsy/memes/babyshark/doot04.mp3"; +static char SHARKSND07[64] = "fartsy/memes/babyshark/shark.mp3"; +static char SHARKSND08[64] = "fartsy/memes/babyshark/shark02.mp3"; +static char SPEC01[32] = "fartsy/vo/fartsy/goobbue.mp3"; +static char SPEC02[32] = "fartsy/misc/shroom.mp3"; +static char SPEC03[64] = "fartsy/vo/inurat/nuclearwaffle.mp3"; +static char STRONGMAN[32] = "fartsy/misc/strongman_bell.wav"; +static char SUS[32] = "amongus/emergency.mp3"; +static char TRIGGERSCORE[32] = "fartsy/misc/triggerscore.wav"; +static char VICTORY[32] = "fartsy/ffxivvictoryedit.mp3"; +static char VO_SEPHMEMORY[32] = "fartsy/vo/sephiroth/memory.mp3"; +static char WTFBOOM[32] = "fartsy/misc/wtfboom.mp3"; +static char TBGM0[16] = "test/bgm0.mp3"; +static char TBGM1[16] = "test/bgm1.mp3"; +static char TBGM3[16] = "test/bgm3.mp3"; +static char TBGM4[16] = "test/bgm4.mp3"; +static char TBGM5[16] = "test/bgm5.mp3"; +static char TBGM6[16] = "test/bgm6.mp3"; +static float HWNMin = 210.0; +static float HWNMax = 380.0; +static float Return[3] = { + -3730.0, + 67.0, + -252.0 +}; +int BGMINDEX = 0; +static int BGMSNDLVL = 95; +int FailedCount = 0; +int INCOMINGDISPLAYED = 0; +int camSel = 0; +int CodeEntry = 0; +static int DEFBGMSNDLVL = 50; +int bombStatus = 0; +int bombStatusMax = 0; +int curWave = 0; +int explodeType = 0; +int lastAdmin = 0; +int loopingFlags = 0; +int sacPoints = 0; +int sacPointsMax = 60; +static int SFXSNDLVL = 75; +static int SNDCHAN = 6; +int soundPreference[MAXPLAYERS + 1]; +int tbLoop = 0; +int VIPBGM = -1; +int VIPIndex = 0; +int waveFlags = 0; +Handle cvarSNDDefault = INVALID_HANDLE; +stock bool IsValidClient(int client) { + return (0 < client <= MaxClients && IsClientInGame(client)); +} + +public Plugin myinfo = { + name = "Fartsy's Ass - Framework", + author = "Fartsy#8998", + description = "Framework for Fartsy's Ass (MvM Mods)", + version = PLUGIN_VERSION, + url = "https://forums.firehostredux.com" +}; + +public void OnPluginStart() { + PrecacheSound(TBGM0, true), + PrecacheSound(TBGM1, true), + PrecacheSound(TBGM3, true), + PrecacheSound(TBGM4, true), + PrecacheSound(TBGM5, true), + PrecacheSound(TBGM6, true), + PrecacheSound(BELL, true), + PrecacheSound(BGM1, true), + PrecacheSound(BGM2, true), + PrecacheSound(BGM3, true), + PrecacheSound(BGM4, true), + PrecacheSound(BGM5, true), + PrecacheSound(BGM6, true), + PrecacheSound(BGM7, true), + PrecacheSound(BGM8, true), + PrecacheSound(BGM9, true), + PrecacheSound(BGM9Intro, true), + PrecacheSound(BGM10, true), + PrecacheSound(BGM10Intro, true), + PrecacheSound(BGM11, true), + PrecacheSound(BGM12, true), + PrecacheSound(BGM100, true), + PrecacheSound(BGM101, true), + PrecacheSound(BMB1SND, true), + PrecacheSound(BMB2SND, true), + PrecacheSound(BMB3SND, true), + PrecacheSound(BMB4SND, true), + PrecacheSound(BOOM, true), + PrecacheSound(CLOCKTICK, true), + PrecacheSound(COUNTDOWN, true), + PrecacheSound(CRUSADERATTACK, true), + PrecacheSound(DEFAULTBGM1, true), + PrecacheSound(DEFAULTBGM2, true), + PrecacheSound(DEFAULTBGM3, true), + PrecacheSound(DROPNUKE, true), + PrecacheSound(EVENTSTART, true), + PrecacheSound(EXPLOSIVEPARADISE, true), + PrecacheSound(FALLSND01, true), + PrecacheSound(FALLSND02, true), + PrecacheSound(FALLSND03, true), + PrecacheSound(FALLSND04, true), + PrecacheSound(FALLSND05, true), + PrecacheSound(FALLSND06, true), + PrecacheSound(FALLSND07, true), + PrecacheSound(FALLSND08, true), + PrecacheSound(FALLSND09, true), + PrecacheSound(FALLSND0A, true), + PrecacheSound(FALLSND0B, true), + PrecacheSound(FALLSND0C, true), + PrecacheSound(FALLSND0D, true), + PrecacheSound(FALLSND0E, true), + PrecacheSound(FALLSND0F, true), + PrecacheSound(FALLSND10, true), + PrecacheSound(GLOBALTHUNDER01, true), + PrecacheSound(GLOBALTHUNDER02, true), + PrecacheSound(GLOBALTHUNDER03, true), + PrecacheSound(GLOBALTHUNDER04, true), + PrecacheSound(GLOBALTHUNDER05, true), + PrecacheSound(GLOBALTHUNDER06, true), + PrecacheSound(GLOBALTHUNDER07, true), + PrecacheSound(GLOBALTHUNDER08, true), + PrecacheSound(HINDENBURGBOOM, true), + PrecacheSound(HINDENCRASH, true), + PrecacheSound(INCOMING, true), + PrecacheSound(OnslaughterLaserSND, true), + PrecacheSound(OnslaughterFlamePreATK, true), + PrecacheSound(OnslaughterFlamePostATK, true), + PrecacheSound(RETURNSND, true), + PrecacheSound(RETURNSUCCESS, true), + PrecacheSound(SHARKSND01, true), + PrecacheSound(SHARKSND02, true), + PrecacheSound(SHARKSND03, true), + PrecacheSound(SHARKSND04, true), + PrecacheSound(SHARKSND05, true), + PrecacheSound(SHARKSND06, true), + PrecacheSound(SHARKSND07, true), + PrecacheSound(SHARKSND08, true), + PrecacheSound(SPEC01, true), + PrecacheSound(SPEC02, true), + PrecacheSound(SPEC03, true), + PrecacheSound(STRONGMAN, true), + PrecacheSound(SUS, true), + PrecacheSound(TRIGGERSCORE, true), + PrecacheSound(VICTORY, true), + PrecacheSound(VO_SEPHMEMORY, true), + PrecacheSound(WTFBOOM, true), + PrecacheSound("mvm/ambient_mp3/mvm_siren.mp3", true), + PrecacheSound("fartsy/memes/priceisright_fail.wav", true), + PrecacheSound("fartsy/eee/the_horn.wav", true), + PrecacheSound("fartsy/misc/fartsyscrusader_bgm_locus.mp3", true), + PrecacheSound("ambient/sawblade_impact1.wav", true), + PrecacheSound("vo/sandwicheat09.mp3", true), + RegServerCmd("fb_operator", Command_Operator, "Serverside only. Does nothing when executed as client."), + RegAdminCmd("sm_music", Command_Music, ADMFLAG_RESERVATION, "Set music to be played for the next wave"), + RegConsoleCmd("sm_bombstatus", Command_FBBombStatus, "Check bomb status"), + RegConsoleCmd("sm_song", Command_GetCurrentSong, "Get current song name"), + RegConsoleCmd("sm_stats", Command_MyStats, "Print current statistics"), + RegConsoleCmd("sm_return", Command_Return, "Return to Spawn"), + RegConsoleCmd("sm_sacpoints", Command_SacrificePointShop, "Fartsy's Annihilation Supply Shop"), + RegConsoleCmd("sm_discord", Command_Discord, "Join our Discord server!"), + RegConsoleCmd("sm_sounds", Command_Sounds, "Toggle sounds on or off via menu"), + HookEvent("player_death", EventDeath), + HookEvent("player_spawn", EventSpawn), + HookEvent("server_cvar", Event_Cvar, EventHookMode_Pre), + HookEvent("mvm_wave_complete", EventWaveComplete), + HookEvent("mvm_wave_failed", EventWaveFailed), + HookEvent("mvm_bomb_alarm_triggered", EventWarning), + HookEventEx("player_hurt", Event_Playerhurt, EventHookMode_Pre); + CPrintToChatAll("{darkred}Plugin Loaded."); + cvarSNDDefault = CreateConVar("sm_fartsysass_sound", "3", "Default sound for new users, 3 = Everything, 2 = Sounds Only, 1 = Music Only, 0 = Nothing"); + SetCookieMenuItem(FartsysSNDSelected, 0, "Fartsys Ass Sound Preferences"); +} + +public void OnGameFrame(){ + if(tickMusic){ + ticksMusic++; + switch(ticksMusic){ + case 120:{ + PrintToChatAll("Got ticksMusic of %i", ticksMusic); + ticksMusic = 0; + } + } + } +} +public Action Command_MyStats(int client, int args) { + if (!FB_Database) { + return; + } + int steamID = GetSteamAccountID(client); + if (!steamID || steamID <= 10000) { + return; + } + DataPack pk = new DataPack(); + pk.WriteCell(client ? GetClientUserId(client) : 0); + pk.WriteString("steamid"); + char queryID[256]; + Format(queryID, sizeof(queryID), "SELECT * from ass_activity WHERE steamid = %d;", steamID); + FB_Database.Query(MyStats, queryID, pk); +} + +public void MyStats(Database db, DBResultSet results, + const char[] error, any data) { + DataPack pk = view_as < DataPack > (data); + pk.Reset(); + + int userId = pk.ReadCell(); + char steamId[64]; + pk.ReadString(steamId, sizeof(steamId)); + delete pk; + + int client = userId ? GetClientOfUserId(userId) : 0; + bool validClient = !userId || client; + + if (!results) { + if (validClient) { + PrintToChat(client, "[SM] Command Database Query Error"); + } + LogError("Failed to query database: %s", error); + return; + } + if (!validClient) { + return; + } + char name[64]; + char class [64]; + int health, healthMax, steamID, damagedealt, damagedealtsession, kills, killssession, deaths, deathssession, bombsreset, bombsresetsession, sacrifices, sacrificessession; + char lastkilledname[128]; + char lastusedweapon[128]; + char killedbyname[128]; + char killedbyweapon[128]; + if (results.FetchRow()) { + results.FetchString(0, name, 64); //name + steamID = results.FetchInt(1); //steamid + results.FetchString(4, class, 64); //class + health = results.FetchInt(5); //health + healthMax = results.FetchInt(6); //health + damagedealt = results.FetchInt(7); //damage dealt + damagedealtsession = results.FetchInt(8); //damage dealt session + kills = results.FetchInt(9); //kills + killssession = results.FetchInt(10); //kills session + deaths = results.FetchInt(11); //deaths + deathssession = results.FetchInt(12); //deaths session + bombsreset = results.FetchInt(13); //bombs reset + bombsresetsession = results.FetchInt(14); //bombs reset session + sacrifices = results.FetchInt(15); //sacrifices + sacrificessession = results.FetchInt(16); //sacrifices session + results.FetchString(17, lastkilledname, sizeof(lastkilledname)); //last client killed + results.FetchString(18, lastusedweapon, sizeof(lastusedweapon)); //using weapon + results.FetchString(19, killedbyname, sizeof(killedbyname)); //last client that killed + results.FetchString(20, killedbyweapon, sizeof(killedbyweapon)); //using weapon + } + CPrintToChat(client, "\x07AAAAAA[CORE] Showing stats of %s [%s, %i/%i hp] || SteamID: %i ", name, class, health, healthMax, steamID); + CPrintToChat(client, "{white}Damage Dealt: %i (Session: %i) || Kills: %i (Session: %i) || Deaths: %i (Session: %i) || Bombs Reset: %i (Session: %i)", damagedealt, damagedealtsession, kills, killssession, deaths, deathssession, bombsreset, bombsresetsession); + CPrintToChat(client, "Sacrifices: %i(Session:%i) || Killed %s (using %s) || Last killed by: %s (using %s)", sacrifices, sacrificessession, lastkilledname, lastusedweapon, killedbyname, killedbyweapon); +} + +public void OnConfigsExecuted() { + if (!FB_Database) { + Database.Connect(Database_OnConnect, "ass"); + } +} + +//DB setup +public void Database_OnConnect(Database db, + const char[] error, any data) { + if (!db) { + LogError("Could not connect to the database: %s", error); + return; + } + char buffer[64]; + db.Driver.GetIdentifier(buffer, sizeof(buffer)); + if (!StrEqual(buffer, "mysql", false)) { + delete db; + LogError("Could not connect to the database: expected mysql database."); + return; + } + FB_Database = db; + FB_Database.Query(Database_FastQuery, "CREATE TABLE IF NOT EXISTS ass_activity(name TEXT, steamid INT UNSIGNED, date DATE, seconds INT UNSIGNED DEFAULT '0', class TEXT DEFAULT 'na', health TEXT DEFAULT '-1', maxHealth INT UNSIGNED DEFAULT '0', damagedealt INT UNSIGNED DEFAULT '0', damagedealtsession INT UNSIGNED DEFAULT '0', kills INT UNSIGNED DEFAULT '0', killssession INT UNSIGNED DEFAULT '0', deaths INT UNSIGNED DEFAULT '0', deathssession INT UNSIGNED DEFAULT '0', bombsreset INT UNSIGNED DEFAULT '0', bombsresetsession INT UNSIGNED DEFAULT '0', sacrifices INT UNSIGNED DEFAULT '0', sacrificessession INT UNSIGNED DEFAULT '0', lastkilledname TEXT DEFAULT 'na', lastweaponused TEXT DEFAULT 'na', killedbyname TEXT DEFAULT 'na', killedbyweapon TEXT DEFAULT 'na', soundprefs INT UNSIGNED DEFAULT '3', PRIMARY KEY (steamid));"); +} + +//Database Fastquery Manager +public void Database_FastQuery(Database db, DBResultSet results, + const char[] error, any data) { + if (!results) { + LogError("Failed to query database: %s", error); + } +} +public void Database_MergeDataError(Database db, any data, int numQueries, + const char[] error, int failIndex, any[] queryData) { + LogError("Failed to query database (transaction): %s", error); +} + +//When a client leaves +public void OnClientDisconnect(int client) { + if (!FB_Database) { + return; + } + int steamID = GetSteamAccountID(client); + if (!steamID || steamID <= 10000) { + return; + } + char query[256]; + char clientName[128]; + GetClientInfo(client, "name", clientName, 128); + Format(query, sizeof(query), "INSERT INTO ass_activity (name, steamid, date, seconds) VALUES ('%s', %d, CURRENT_DATE, %d) ON DUPLICATE KEY UPDATE name = '%s', seconds = seconds + VALUES(seconds);", clientName, steamID, GetClientMapTime(client), clientName); + PrintToServer("%s", query); + FB_Database.Query(Database_FastQuery, query); +} + +//Calculate time spent on server in seconds +int GetClientMapTime(int client) { + float clientTime = GetClientTime(client), gameTime = GetGameTime(); + if (clientTime > gameTime) { + return RoundToZero(gameTime); + } + + return RoundToZero(clientTime); +} + +//Clientprefs built in menu +public void FartsysSNDSelected(int client, CookieMenuAction action, any info, char[] buffer, int maxlen) { + if (action == CookieMenuAction_SelectOption) { + ShowFartsyMenu(client); + } +} + +// When a new client joins +public void OnClientPutInServer(int client) { + if (!IsFakeClient(client)) { + if (!FB_Database) { //Use defaults if no database + PrintToServer("No database detected, setting soundPreference for %N to default.", client); + soundPreference[client] = GetConVarInt(cvarSNDDefault); + return; + } + int steamID = GetSteamAccountID(client); + if (!steamID || steamID <= 10000) { + return; + } else { + if(!tickingClientHealth){ + PrintToServer("Creating timer for tickclienthealth"); + CreateTimer(1.0, TickClientHealth); + tickingClientHealth = true; + } + char query[1024]; + Format(query, sizeof(query), "INSERT INTO ass_activity (name, steamid, date, damagedealtsession, killssession, deathssession, bombsresetsession, sacrificessession) VALUES ('%N', %d, CURRENT_DATE, 0, 0, 0, 0, 0) ON DUPLICATE KEY UPDATE name = '%N', damagedealtsession = 0, killssession = 0, deathssession = 0, bombsresetsession = 0, sacrificessession = 0;", client, steamID, client); + FB_Database.Query(Database_FastQuery, query); + DataPack pk = new DataPack(); + pk.WriteCell(client ? GetClientUserId(client) : 0); + pk.WriteString("steamid"); + char queryID[256]; + Format(queryID, sizeof(queryID), "SELECT soundprefs from ass_activity WHERE steamid = '%d';", steamID); + FB_Database.Query(SQL_SNDPrefs, queryID, pk); + } + } else { + soundPreference[client] = 0; + } +} + +//Get client sound prefs +public void SQL_SNDPrefs(Database db, DBResultSet results, + const char[] error, any data) { + DataPack pk = view_as < DataPack > (data); + pk.Reset(); + int userId = pk.ReadCell(); + char steamId[64]; + pk.ReadString(steamId, sizeof(steamId)); + delete pk; + int client = userId ? GetClientOfUserId(userId) : 0; + bool validClient = !userId || client; + if (!results) { + LogError("Failed to query database: %s", error); + return; + } + if (!validClient) { + return; + } + if (results.FetchRow()) { + soundPreference[client] = results.FetchInt(0); //Set it + //PrintToServer("Client %N soundPreference was set to %i", client, soundPreference[client]); + } +} + +//Send client sound menu +public void ShowFartsyMenu(int client) { + Menu menu = new Menu(MenuHandlerFartsy, MENU_ACTIONS_DEFAULT); + char buffer[100]; + menu.SetTitle("FartsysAss Sound Menu"); + menu.AddItem(buffer, "Disable ALL"); + menu.AddItem(buffer, "Music Only"); + menu.AddItem(buffer, "Sound Effects Only"); + menu.AddItem(buffer, "Enable ALL"); + menu.Display(client, 20); + menu.ExitButton = true; +} + +//Create menu +public Action Command_Sounds(int client, int args) { + int steamID = GetSteamAccountID(client); + if (!steamID || steamID <= 10000) { + return Plugin_Handled; + } else { + DataPack pk = new DataPack(); + pk.WriteCell(client ? GetClientUserId(client) : 0); + pk.WriteString("steamid"); + char queryID[256]; + Format(queryID, sizeof(queryID), "SELECT soundprefs from ass_activity WHERE steamid = '%d';", steamID); + FB_Database.Query(SQL_SNDPrefs, queryID, pk); + ShowFartsyMenu(client); + switch (soundPreference[client]) { + case 0: { + PrintToChat(client, "Sounds are currently DISABLED."); + } + case 1: { + PrintToChat(client, "Sounds are currently MUSIC ONLY."); + } + case 2: { + PrintToChat(client, "Sounds are currently SOUND EFFECTS ONLY."); + } + case 3: { + PrintToChat(client, "Sounds are currently ALL ON."); + } + case 4: { + PrintToChat(client, "Somehow your sound preference was stored as non-existent 5... Please configure your sounds."); + } + } + return Plugin_Handled; + } +} + +// This selects or disables the sounds +public int MenuHandlerFartsy(Menu menu, MenuAction action, int param1, int param2) { + if (action == MenuAction_Select) { + char query[256]; + int steamID = GetSteamAccountID(param1); + if (!FB_Database || !steamID) { + return; + } else { + Format(query, sizeof(query), "UPDATE ass_activity SET soundprefs = '%i' WHERE steamid = '%d';", param2, steamID); + FB_Database.Query(Database_FastQuery, query); + soundPreference[param1] = param2; + Command_Sounds(param1, 0); + } + } else if (action == MenuAction_End) { + CloseHandle(menu); + } +} + +//Fartsy's A.S.S +public Action Command_SacrificePointShop(int client, int args) { + ShowFartsysAss(client); + return Plugin_Handled; +} + +//Fartsy's A.S.S +public void ShowFartsysAss(int client) { + if (sacPoints <= 9 || !isWave) { + if (isWave) { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {red}ERROR: You do not have enough sacPoints. This command requires at least {white}10{red}. You have {white}%i{red}.", sacPoints); + } else { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}The sacrificial points counter is currently at %i of %i maximum for this wave.", sacPoints, sacPointsMax); + } + } else { + Menu menu = new Menu(MenuHandlerFartsysAss, MENU_ACTIONS_DEFAULT); + char buffer[100]; + menu.SetTitle("Fartsy's Annihilation Supply Shop"); + menu.ExitButton = true; + switch (sacPoints) { + case 10, 11, 12, 13, 14, 15, 16, 17, 18, 19: { + menu.AddItem(buffer, "[10] Kissone Bath Salts"); + menu.Display(client, 20); + } + case 20, 21, 22, 23, 24, 25, 26, 27, 28, 29: { + menu.AddItem(buffer, "[10] Kissone Bath Salts"); + menu.AddItem(buffer, "[20] Instant Fat Man"); + menu.Display(client, 20); + } + case 30, 31, 32, 33, 34, 35, 36, 37, 38, 39: { + menu.AddItem(buffer, "[10] Kissone Bath Salts"); + menu.AddItem(buffer, "[20] Instant Fat Man"); + menu.AddItem(buffer, "[30] Summon Goobbue or Kirby"); + menu.Display(client, 20); + } + case 40, 41, 42, 43, 44, 45, 46, 47, 48, 49: { + menu.AddItem(buffer, "[10] Kissone Bath Salts"); + menu.AddItem(buffer, "[20] Instant Fat Man"); + menu.AddItem(buffer, "[30] Summon Goobbue or Kirby"); + menu.AddItem(buffer, "[40] Explosives Paradise"); + menu.Display(client, 20); + } + case 50, 51, 52, 53, 54, 55, 56, 57, 58, 59: { + menu.AddItem(buffer, "[10] Kissone Bath Salts"); + menu.AddItem(buffer, "[20] Instant Fat Man"); + menu.AddItem(buffer, "[30] Summon Goobbue or Kirby"); + menu.AddItem(buffer, "[40] Explosives Paradise"); + menu.AddItem(buffer, "[50] Ass Gas"); + menu.AddItem(buffer, "[50] Banish Tornadoes"); + menu.Display(client, 20); + } + case 60, 61, 62, 63, 64, 65, 66, 67, 68, 69: { + menu.AddItem(buffer, "[10] Kissone Bath Salts"); + menu.AddItem(buffer, "[20] Instant Fat Man"); + menu.AddItem(buffer, "[30] Summon Goobbue or Kirby"); + menu.AddItem(buffer, "[40] Explosives Paradise"); + menu.AddItem(buffer, "[50] Ass Gas"); + menu.AddItem(buffer, "[50] Banish Tornadoes"); + menu.AddItem(buffer, "[60] Total Atomic Annihilation"); + menu.Display(client, 20); + } + case 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99: { + menu.AddItem(buffer, "[10] Kissone Bath Salts"); + menu.AddItem(buffer, "[20] Instant Fat Man"); + menu.AddItem(buffer, "[30] Summon Goobbue or Kirby"); + menu.AddItem(buffer, "[40] Explosives Paradise"); + menu.AddItem(buffer, "[50] Ass Gas"); + menu.AddItem(buffer, "[50] Banish Tornadoes"); + menu.AddItem(buffer, "[60] Total Atomic Annihilation"); + menu.AddItem(buffer, "[70] Meteorites"); + menu.AddItem(buffer, "[75] 150,000 UbUp Cash"); + menu.Display(client, 20); + } + case 100: { + menu.AddItem(buffer, "[10] Kissone Bath Salts"); + menu.AddItem(buffer, "[20] Instant Fat Man"); + menu.AddItem(buffer, "[30] Summon Goobbue or Kirby"); + menu.AddItem(buffer, "[40] Explosives Paradise"); + menu.AddItem(buffer, "[50] Ass Gas"); + menu.AddItem(buffer, "[50] Banish Tornadoes"); + menu.AddItem(buffer, "[60] Total Atomic Annihilation"); + menu.AddItem(buffer, "[70] Meteorites"); + menu.AddItem(buffer, "[75] 150,000 UbUp Cash"); + menu.AddItem(buffer, "[100] Professor Fartsalot"); + menu.Display(client, 20); + } + } + } +} + +//Also Fartsy's A.S.S +public int MenuHandlerFartsysAss(Menu menu, MenuAction action, int param1, int param2) { + if (action == MenuAction_Select) { + //PrintToChatAll("Got %i", param2); + switch (param2) { + case 0: { + if (sacPoints <= 9) { + return; + } else { + ServerCommand("fb_operator 30"); + } + } + case 1: { + if (sacPoints <= 19) { + return; + } else { + ServerCommand("fb_operator 31"); + } + } + case 2: { + if (sacPoints <= 29) { + return; + } else { + ServerCommand("fb_operator 32"); + } + } + case 3: { + if (sacPoints <= 39) { + return; + } else { + ServerCommand("fb_operator 33"); + } + } + case 4: { + if (sacPoints <= 49) { + return; + } else { + ServerCommand("fb_operator 34"); + } + } + case 5: { + if (sacPoints <= 49) { + return; + } else { + ServerCommand("fb_operator 35"); + } + } + case 6: { + if (sacPoints <= 59) { + return; + } else { + ServerCommand("fb_operator 36"); + } + } + case 7: { + if (sacPoints <= 69) { + return; + } else { + ServerCommand("fb_operator 37"); + } + + } + case 8: { + if (sacPoints <= 74) { + return; + } else { + ServerCommand("fb_operator 38"); + } + + } + case 9: { + if (sacPoints <= 99) { + return; + } else { + ServerCommand("fb_operator 39"); + } + + } + } + } else if (action == MenuAction_End) { + CloseHandle(menu); + } +} + +//Now that command definitions are done, lets make some things happen. +public void OnMapStart() { + FireEntityInput("rain", "Alpha", "0", 0.0); + ServerCommand("fb_operator 1002"); + CreateTimer(1.0, SelectAdminTimer); +} + +//Repeating Timers +//Adverts for tips/tricks +public Action PerformAdverts(Handle timer) { + if (!isWave) { + CreateTimer(180.0, PerformAdverts); + int i = GetRandomInt(1, 7); + switch (i) { + case 1: { + CPrintToChatAll("{darkviolet}[{aqua}CORE{darkviolet}] {white}We have a Discord server: {forestgreen}https://discord.com/invite/SkHaeMH"); + } + case 2: { + CPrintToChatAll("{darkviolet}[{aqua}CORE{darkviolet}] {white}Remember to buy your upgrades using {forestgreen}!buy"); + } + case 3: { + //CPrintToChatAll("{darkviolet}[{aqua}CORE{darkviolet}] {white}If this is your first time here, please run console command {forestgreen}snd_restart {white}for safety. Otherwise, you might {red}crash{white}!"); + CPrintToChatAll("{darkviolet}[{aqua}CORE{darkviolet}] {white}You may invoke {forestgreen}!sounds {white}to configure what sounds you hear from the plugin, or {forestgreen}!stats{white} to see your stats."); + } + case 4: { + CPrintToChatAll("{darkviolet}[{aqua}CORE{darkviolet}] {white}Advanced users may quick buy upgrades using {forestgreen}!qbuy"); + } + case 5: { + CPrintToChatAll("{darkviolet}[{aqua}CORE{darkviolet}] {white}Don't forget to buy {forestgreen}protection upgrades {white}and {forestgreen}ammo regen{white}(if applicable)!"); + } + case 6: { + CPrintToChatAll("{darkviolet}[{aqua}CORE{darkviolet}] {white}TIP: As a {red}DEFENDER{white}, pushing your team's {forestgreen}payload {white}is crucial to wrecking havoc on the robots!"); + } + case 7: { + CPrintToChatAll("{darkviolet}[{aqua}CORE{darkviolet}] {white}Remember, if someone is being abusive, you may always invoke {forestgreen}!calladmin{white}."); + } + case 8: { + CPrintToChatAll("{darkviolet}[{aqua}CORE{darkviolet}] {white}You may always invoke {forestgreen}!return{white} to be returned to spawn."); + } + } + } + return Plugin_Stop; +} + +//Adverts for wave information +public Action PerformWaveAdverts(Handle timer) { + if (isWave) { + CreateTimer(2.5, PerformWaveAdverts); + for (int i = 1; i <= MaxClients; i++) { + switch (bombStatus) { + case 8, 16, 24, 32, 40, 48, 56, 64: { + if (TornadoWarningIssued && IsClientInGame(i)) { + if (bombProgression) { + PrintHintText(i, "Bomb Status: MOVING (%i/%i) || Sacrifice Points: %i/%i \nCurrent song: %s \n\n[TORNADO WARNING]", bombStatus, bombStatusMax, sacPoints, sacPointsMax, songName); + StopSound(i, SNDCHAN_STATIC, "UI/hint.wav"); + } else { + PrintHintText(i, "Bomb Status: READY (%i/%i) || Sacrifice Points: %i/%i \nCurrent song: %s \n\n[TORNADO WARNING]", bombStatus, bombStatusMax, sacPoints, sacPointsMax, songName); + StopSound(i, SNDCHAN_STATIC, "UI/hint.wav"); + } + } else if (bombProgression && IsClientInGame(i)) { + PrintHintText(i, "Bomb Status: MOVING (%i/%i) || Sacrifice Points: %i/%i \nCurrent song: %s", bombStatus, bombStatusMax, sacPoints, sacPointsMax, songName); + StopSound(i, SNDCHAN_STATIC, "UI/hint.wav"); + } else if (IsClientInGame(i)) { + PrintHintText(i, "Bomb Status: READY (%i/%i) || Sacrifice Points: %i/%i \nCurrent song: %s", bombStatus, bombStatusMax, sacPoints, sacPointsMax, songName); + StopSound(i, SNDCHAN_STATIC, "UI/hint.wav"); + } + } + case 0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 25, 26, 27, 28, 29, 30, 31, 33, 34, 35, 36, 37, 38, 39, 41, 42, 43, 44, 45, 46, 47, 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60, 61, 62, 63: { + if (TornadoWarningIssued && IsClientInGame(i)) { + PrintHintText(i, "Bomb Status: %i/%i || Sacrifice Points: %i/%i \nCurrent song: %s \n\n[TORNADO WARNING]", bombStatus, bombStatusMax, sacPoints, sacPointsMax, songName); + StopSound(i, SNDCHAN_STATIC, "UI/hint.wav"); + } else if (IsClientInGame(i)) { + PrintHintText(i, "Bomb Status: %i/%i || Sacrifice Points: %i/%i \nCurrent song: %s", bombStatus, bombStatusMax, sacPoints, sacPointsMax, songName); + StopSound(i, SNDCHAN_STATIC, "UI/hint.wav"); + } + } + } + } + } + return Plugin_Stop; +} + +//Feature admin timer +public Action SelectAdminTimer(Handle timer) { + if (isWave) { + return Plugin_Stop; + } else { + ServerCommand("fb_operator 1002"); + float f = GetRandomFloat(40.0, 120.0); + CreateTimer(f, SelectAdminTimer); + return Plugin_Handled; + } +} + +//Brute Justice Timer +public Action OnslaughterATK(Handle timer) { + if (waveFlags != 1) { + return Plugin_Stop; + } else { + float f = GetRandomFloat(5.0, 7.0); + CreateTimer(f, OnslaughterATK); + FireEntityInput("BruteJusticeDefaultATK", "FireMultiple", "3", 5.0); + int i = GetRandomInt(1, 10); + switch (i) { + case 1, 6: { + FireEntityInput("BruteJusticeLaserParticle", "Start", "", 0.0); + CustomSoundEmitter(OnslaughterLaserSND, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("BruteJusticeLaser", "TurnOn", "", 1.40); + FireEntityInput("BruteJusticeLaserHurtAOE", "Enable", "", 1.40); + FireEntityInput("BruteJusticeLaserParticle", "Stop", "", 3.00); + FireEntityInput("BruteJusticeLaser", "TurnOff", "", 3.25); + FireEntityInput("BruteJusticeLaserHurtAOE", "Disable", "", 3.25); + } + case 2, 8: { + FireEntityInput("BruteJustice", "FireUser1", "", 0.0); + } + case 3, 7: { + FireEntityInput("BruteJusticeFlameParticle", "Start", "", 0.0); + FireEntityInput("BruteJusticeFlamethrowerHurtAOE", "Enable", "", 0.0); + CustomSoundEmitter(OnslaughterFlamePreATK, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("SND.BruteJusticeFlameATK", "PlaySound", "", 1.25); + FireEntityInput("BruteJusticeFlamethrowerHurtAOE", "Disable", "", 5.0); + FireEntityInput("BruteJusticeFlameParticle", "Stop", "", 5.0); + FireEntityInput("SND.BruteJusticeFlameATK", "FadeOut", ".25", 5.0); + CreateTimer(5.0, TimedOperator, 60); + FireEntityInput("SND.BruteJusticeFlameATK", "StopSound", "", 5.10); + } + case 4: { + FireEntityInput("BruteJusticeGrenadeSpammer", "FireMultiple", "10", 0.0); + FireEntityInput("BruteJusticeGrenadeSpammer", "FireMultiple", "10", 3.0); + FireEntityInput("BruteJusticeGrenadeSpammer", "FireMultiple", "10", 5.0); + } + case 5: { + FireEntityInput("BruteJusticeGrenadeSpammer", "FireMultiple", "50", 0.0); + } + case 9: { + FireEntityInput("BruteJusticeRocketSpammer", "FireOnce", "", 0.00); + FireEntityInput("BruteJusticeRocketSpammer", "FireOnce", "", 5.00); + } + case 10: { + FireEntityInput("BruteJusticeRocketSpammer", "FireMultiple", "10", 0.00); + FireEntityInput("BruteJusticeRocketSpammer", "FireMultiple", "10", 3.00); + FireEntityInput("BruteJusticeRocketSpammer", "FireMultiple", "10", 5.00); + } + } + } + return Plugin_Stop; +} + +//Onslaughter Health Timer +public Action OnslaughterHPTimer(Handle timer) { + if (waveFlags != 1) { + return Plugin_Stop; + } else { + int OnsEnt = FindEntityByClassname(-1, "tank_boss"); //Get index of Sephiroth Tank + int OnsRelayEnt = FindEntityByClassname(-1, "func_physbox"); //Get index of Onslaughter Relay + if (OnsEnt == -1) { + PrintToChatAll("Onslaughter not found"); + return Plugin_Handled; + } + int OnsHP = GetEntProp(OnsEnt, Prop_Data, "m_iHealth"); + int OnsRelayHP = GetEntProp(OnsRelayEnt, Prop_Data, "m_iHealth"); + CPrintToChatAll("{blue}Onslaughter's HP: %i (%i)", OnsHP, OnsRelayHP); + CreateTimer(10.0, OnslaughterHPTimer); + } + return Plugin_Stop; +} +//Sephiroth Timer +public Action SephATK(Handle timer) { + if (waveFlags != 2) { + return Plugin_Stop; + } else { + float f = GetRandomFloat(5.0, 10.0); + CreateTimer(f, SephATK); + FireEntityInput("SephArrows", "FireMultiple", "3", 5.0); + int i = GetRandomInt(1, 12); + switch (i) { + case 1, 6: { + CreateTimer(1.0, SephNukeTimer), + CreateTimer(7.0, TimedOperator, 11), + canSephNuke = true; + } + case 2, 8: { + CPrintToChatAll("{blue}Sephiroth: Say goodbye!"), + FireEntityInput("SephMeteor", "ForceSpawn", "", 0.0); + } + case 3, 7: { + FireEntityInput("SephNuke", "ForceSpawn", "", 0.0), + CustomSoundEmitter(DROPNUKE, SFXSNDLVL - 10, false, 0, 1.0, 100); + } + case 4: { + FireEntityInput("SephRocketSpammer", "FireMultiple", "10", 0.0); + FireEntityInput("SephRocketSpammer", "FireMultiple", "10", 3.0); + FireEntityInput("SkeleSpawner", "Enable", "", 0.0), + FireEntityInput("SkeleSpawner", "Disable", "", 20.0); + } + case 5: { + CPrintToChatAll("{blue}Sephiroth: Have at thee!"), + FireEntityInput("SephRocketSpammer", "FireMultiple", "50", 0.0); + } + case 9: { + FireEntityInput("SephRocketSpammer", "FireOnce", "", 0.00); + FireEntityInput("SephRocketSpammer", "FireOnce", "", 5.00); + } + case 10: { + CPrintToChatAll("{blue}Sephiroth: I dare say you will go off with a bang! HAHAHAHAHAHAHAA"), + FireEntityInput("SephRocketSpammer", "FireMultiple", "10", 0.00); + FireEntityInput("SephRocketSpammer", "FireMultiple", "10", 3.00); + FireEntityInput("SephRocketSpammer", "FireMultiple", "10", 5.00); + } + case 11: { + CPrintToChatAll("{blue}Sephiroth: Hahaha, let's see how you like THIS!"), + ServerCommand("sm_smash @red"); + } + case 12: { + CPrintToChatAll("{blue}Sephiroth: Ohhhh, you dare oppose ME?"); + } + } + } + return Plugin_Stop; +} + +//Sephiroth Health Timer +public Action SephHPTimer(Handle timer) { + if (waveFlags != 2) { + return Plugin_Stop; + } else { + int SephEnt = FindEntityByClassname(-1, "tank_boss"); //Get index of Sephiroth Tank + int SephRelayEnt = FindEntityByClassname(-1, "func_physbox"); //Get index of Seph Relay + if (SephEnt == -1) { + PrintToChatAll("Sephiroth not found"); + return Plugin_Handled; + } + int SephHP = GetEntProp(SephEnt, Prop_Data, "m_iHealth"); + int SephRelayHP = GetEntProp(SephRelayEnt, Prop_Data, "m_iHealth"); + CPrintToChatAll("{blue}Sephiroth's HP: %i (%i)", SephHP, SephRelayHP); + CreateTimer(10.0, SephHPTimer); + } + return Plugin_Stop; +} + +//Shark Timer +public Action SharkTimer(Handle timer) { + if (canSENTShark) { + FireEntityInput("SentSharkTorpedo", "ForceSpawn", "", 0.0); + float f = GetRandomFloat(2.0, 5.0); + CreateTimer(f, SharkTimer); + int i = GetRandomInt(1, 8); + switch (i) { + case 1: { + CustomSoundEmitter(SHARKSND01, SFXSNDLVL, false, 0, 1.0, 100); + } + case 2: { + CustomSoundEmitter(SHARKSND02, SFXSNDLVL, false, 0, 1.0, 100); + } + case 3: { + CustomSoundEmitter(SHARKSND03, SFXSNDLVL, false, 0, 1.0, 100); + } + case 4: { + CustomSoundEmitter(SHARKSND04, SFXSNDLVL, false, 0, 1.0, 100); + } + case 5: { + CustomSoundEmitter(SHARKSND05, SFXSNDLVL, false, 0, 1.0, 100); + } + case 6: { + CustomSoundEmitter(SHARKSND06, SFXSNDLVL, false, 0, 1.0, 100); + } + case 7: { + CustomSoundEmitter(SHARKSND07, SFXSNDLVL, false, 0, 1.0, 100); + } + case 8: { + CustomSoundEmitter(SHARKSND08, SFXSNDLVL, false, 0, 1.0, 100); + } + } + return Plugin_Handled; + } + return Plugin_Stop; +} + +//Storm +public Action RefireStorm(Handle timer) { + if (isWave) { + float f = GetRandomFloat(7.0, 17.0); + CreateTimer(f, RefireStorm); + ServerCommand("fb_operator 1003"); + int Thunder = GetRandomInt(1, 16); + switch (Thunder) { + case 1: { + CustomSoundEmitter(GLOBALTHUNDER01, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt00", "Enable", "", 0.0), + FireEntityInput("LightningHurt00", "Disable", "", 0.07); + } + case 2: { + CustomSoundEmitter(GLOBALTHUNDER02, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt01", "Enable", "", 0.0), + FireEntityInput("LightningHurt01", "Disable", "", 0.07); + } + case 3: { + CustomSoundEmitter(GLOBALTHUNDER03, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt02", "Enable", "", 0.0), + FireEntityInput("LightningHurt02", "Disable", "", 0.07); + } + case 4: { + CustomSoundEmitter(GLOBALTHUNDER04, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt03", "Enable", "", 0.0), + FireEntityInput("LightningHurt03", "Disable", "", 0.07); + } + case 5: { + CustomSoundEmitter(GLOBALTHUNDER05, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt04", "Enable", "", 0.0), + FireEntityInput("LightningHurt04", "Disable", "", 0.07); + } + case 6: { + CustomSoundEmitter(GLOBALTHUNDER06, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt05", "Enable", "", 0.0), + FireEntityInput("LightningHurt05", "Disable", "", 0.07); + } + case 7: { + CustomSoundEmitter(GLOBALTHUNDER07, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt06", "Enable", "", 0.0), + FireEntityInput("LightningHurt06", "Disable", "", 0.07); + } + case 8: { + CustomSoundEmitter(GLOBALTHUNDER08, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt07", "Enable", "", 0.0), + FireEntityInput("LightningHurt07", "Disable", "", 0.07); + } + case 9: { + CustomSoundEmitter(GLOBALTHUNDER01, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt08", "Enable", "", 0.0), + FireEntityInput("LightningHurt08", "Disable", "", 0.07); + } + case 10: { + CustomSoundEmitter(GLOBALTHUNDER02, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt09", "Enable", "", 0.0), + FireEntityInput("LightningHurt09", "Disable", "", 0.07); + } + case 11: { + CustomSoundEmitter(GLOBALTHUNDER03, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt0A", "Enable", "", 0.0), + FireEntityInput("LightningHurt0A", "Disable", "", 0.07); + } + case 12: { + CustomSoundEmitter(GLOBALTHUNDER04, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt0B", "Enable", "", 0.0), + FireEntityInput("LightningHurt0B", "Disable", "", 0.07); + } + case 13: { + CustomSoundEmitter(GLOBALTHUNDER05, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt0C", "Enable", "", 0.0), + FireEntityInput("LightningHurt0C", "Disable", "", 0.07); + } + case 14: { + CustomSoundEmitter(GLOBALTHUNDER06, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt0D", "Enable", "", 0.0), + FireEntityInput("LightningHurt0D", "Disable", "", 0.07); + } + case 15: { + CustomSoundEmitter(GLOBALTHUNDER07, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt0E", "Enable", "", 0.0), + FireEntityInput("LightningHurt0E", "Disable", "", 0.07); + } + case 16: { + CustomSoundEmitter(GLOBALTHUNDER08, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt0F", "Enable", "", 0.0), + FireEntityInput("LightningHurt0F", "Disable", "", 0.07); + } + } + } + return Plugin_Handled; +} + +//SpecTimer +public Action SpecTimer(Handle timer) { + if (isWave) { + int i = GetRandomInt(1, 6); + switch (i) { + case 1: { + FireEntityInput("Spec*", "Disable", "", 0.0), + FireEntityInput("Spec.Goobbue", "Enable", "", 0.1), + CPrintToChatAll("{fullblue} Legend tells of a Goobbue sproutling somewhere nearby..."); + } + case 2: { + FireEntityInput("Spec*", "Disable", "", 0.0), + FireEntityInput("Spec.Waffle", "Enable", "", 0.1), + CPrintToChatAll("{turquoise}Don't eat THESE..."); + } + case 3: { + FireEntityInput("Spec*", "Disable", "", 0.0), + FireEntityInput("Spec.Burrito", "Enable", "", 0.1), + CPrintToChatAll("{darkred}What's worse than Taco Bell?"); + } + case 4: { + FireEntityInput("Spec*", "Disable", "", 0.0), + FireEntityInput("Spec.Shroom", "Enable", "", 0.1), + CPrintToChatAll("{red}M{white}A{red}R{white}I{red}O {white}time!"); + } + case 5: { + FireEntityInput("Spec*", "Disable", "", 0.0); + FireEntityInput("Spec.BlueBall", "Enable", "", 0.1); + CPrintToChatAll("{white}A {fullblue}Blue Ball {white}lurks from afar..."); + } + case 6: { + FireEntityInput("Spec*", "Enable", "", 0.0), + CPrintToChatAll("{magenta}Is it a miracle? Is it {red}chaos{magenta}? WHO KNOWWWWWWS"); + } + } + float spDelay = GetRandomFloat(10.0, 30.0); + CreateTimer(spDelay, SpecTimer); + } + return Plugin_Stop; +} + +//SENTMeteor (Scripted Entity Meteors) +public Action SENTMeteorTimer(Handle timer) { + if (canSENTMeteors) { + CreateTimer(5.0, SENTMeteorTimer); + int i = GetRandomInt(1, 8); + switch (i) { + case 1: { + FireEntityInput("FB.SentMeteor01", "ForceSpawn", "", 0.0); + } + case 2: { + FireEntityInput("FB.SentMeteor02", "ForceSpawn", "", 0.0); + } + case 3: { + FireEntityInput("FB.SentMeteor03", "ForceSpawn", "", 0.0); + } + case 4: { + FireEntityInput("FB.SentMeteor04", "ForceSpawn", "", 0.0); + } + case 5: { + FireEntityInput("FB.SentMeteor05", "ForceSpawn", "", 0.0); + } + } + } + return Plugin_Stop; +} + +//SENTNukes (Scripted Entity Nukes) +public Action SENTNukeTimer(Handle timer) { + if (canSENTNukes) { + CustomSoundEmitter(DROPNUKE, SFXSNDLVL - 10, false, 0, 1.0, 100); + int i = GetRandomInt(1, 8); + switch (i) { + case 1: { + FireEntityInput("FB.SentNuke01", "ForceSpawn", "", 0.0); + } + case 2: { + FireEntityInput("FB.SentNuke02", "ForceSpawn", "", 0.0); + } + case 3: { + FireEntityInput("FB.SentNuke03", "ForceSpawn", "", 0.0); + } + case 4: { + FireEntityInput("FB.SentNuke04", "ForceSpawn", "", 0.0); + } + case 5: { + FireEntityInput("FB.SentNuke05", "ForceSpawn", "", 0.0); + } + } + float f = GetRandomFloat(1.5, 3.0); + CreateTimer(f, SENTNukeTimer); + } + return Plugin_Stop; +} + +//CrusaderSentNukes +public Action CrusaderNukeTimer(Handle timer) { + if (canCrusaderNuke) { + CustomSoundEmitter(DROPNUKE, SFXSNDLVL - 10, false, 0, 1.0, 100), + FireEntityInput("FB.CrusaderNuke", "ForceSpawn", "", 0.0); + float f = GetRandomFloat(1.5, 3.0); + CreateTimer(f, CrusaderNukeTimer); + } + return Plugin_Stop; +} + +//SephSentNukes +public Action SephNukeTimer(Handle timer) { + if (canSephNuke) { + CustomSoundEmitter(DROPNUKE, SFXSNDLVL - 10, false, 0, 1.0, 100), + FireEntityInput("SephNuke", "ForceSpawn", "", 0.0); + float f = GetRandomFloat(1.5, 3.0); + CreateTimer(f, SephNukeTimer); + } + return Plugin_Stop; +} + +//SENTStars (Scripted Entity Stars) +public Action SENTStarTimer(Handle timer) { + if (canSENTStars) { + int i = GetRandomInt(1, 5); + switch (i) { + case 1: { + FireEntityInput("FB.SentStar01", "ForceSpawn", "", 0.0); + } + case 2: { + FireEntityInput("FB.SentStar02", "ForceSpawn", "", 0.0); + } + case 3: { + FireEntityInput("FB.SentStar03", "ForceSpawn", "", 0.0); + } + case 4: { + FireEntityInput("FB.SentStar04", "ForceSpawn", "", 0.0); + } + case 5: { + FireEntityInput("FB.SentStar05", "ForceSpawn", "", 0.0); + } + } + float f = GetRandomFloat(0.75, 1.5); + CreateTimer(f, SENTStarTimer); + } + return Plugin_Stop; +} + +//Crusader Incoming Timer for Crusader +public Action CRUSADERINCOMING(Handle timer) { + if (!crusader || INCOMINGDISPLAYED > 17) { + INCOMINGDISPLAYED = 0; + return Plugin_Stop; + } else { + INCOMINGDISPLAYED++; + FireEntityInput("FB.INCOMING", "Display", "", 0.0); + CreateTimer(1.75, CRUSADERINCOMING); + } + return Plugin_Stop; +} + +//Halloween Bosses +public Action HWBosses(Handle timer) { + if (isWave && canHWBoss) { + int i = GetRandomInt(1, 10); + switch (i) { + case 1: { + FireEntityInput("hhh_maker", "ForceSpawn", "", 0.0), + FireEntityInput("hhh_maker2", "ForceSpawn", "", 0.0); + } + case 2: { + FireEntityInput("hhh_maker2", "ForceSpawn", "", 0.0); + } + case 3: { + + FireEntityInput("hhh_maker2", "ForceSpawn", "", 0.0), + FireEntityInput("SkeleSpawner", "Enable", "", 0.0), + FireEntityInput("SkeleSpawner", "Disable", "", 10.0); + } + case 4: { + FireEntityInput("SkeleSpawner", "Enable", "", 0.0), + FireEntityInput("SkeleSpawner", "Disable", "", 10.0); + } + case 5: { + FireEntityInput("merasmus_maker", "ForceSpawn", "", 0.0), + FireEntityInput("hhh_maker2", "ForceSpawn", "", 0.0); + } + case 6: { + FireEntityInput("merasmus_maker", "ForceSpawn", "", 0.0), + FireEntityInput("monoculus_maker", "ForceSpawn", "", 0.0), + FireEntityInput("hhh_maker2", "ForceSpawn", "", 0.0); + } + case 7: { + FireEntityInput("monoculus_maker", "ForceSpawn", "", 0.0), + FireEntityInput("merasmus_maker", "ForceSpawn", "", 0.0); + } + case 8: { + FireEntityInput("SkeleSpawner", "Enable", "", 0.0), + FireEntityInput("SkeleSpawner", "Disable", "", 30.0); + } + case 9: { + FireEntityInput("SkeleSpawner", "Enable", "", 0.0), + FireEntityInput("SkeleSpawner", "Disable", "", 60.0), + FireEntityInput("merasmus_maker", "ForceSpawn", "", 0.0), + FireEntityInput("monoculus_maker", "ForceSpawn", "", 0.0), + FireEntityInput("hhh_maker2", "ForceSpawn", "", 0.0); + } + case 10: { + FireEntityInput("monoculus_maker", "ForceSpawn", "", 0.0); + } + } + canHWBoss = false; + CreateTimer(60.0, HWBossesRefire); + } + return Plugin_Stop; +} + +//Repeat HWBosses Timer +public Action HWBossesRefire(Handle timer) { + if (isWave) { + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + return Plugin_Stop; +} + +//SacPoints (Add points to Sacrifice Points occasionally) +public Action SacrificePointsTimer(Handle timer) { + if (isWave && (sacPoints < sacPointsMax)) { + sacPoints++; + float f = GetRandomFloat(5.0, 30.0); + CreateTimer(f, SacrificePointsTimer); + } + return Plugin_Stop; +} + +//Track SacPoints and update entities every 0.1 seconds +public Action SacrificePointsUpdater(Handle timer) { + if (isWave) { + CreateTimer(0.1, SacrificePointsUpdater); + if (sacPoints > sacPointsMax) { + sacPoints = sacPointsMax; + } + } + return Plugin_Stop; +} + +//BombStatus (Add points to Bomb Status occasionally) +public Action BombStatusAddTimer(Handle timer) { + if (isWave && (bombStatus < bombStatusMax)) { + bombStatus++; + float f = GetRandomFloat(10.0, 45.0); + PrintToServer("[DEBUG] Creating a %f timer to give bomb status an update. Current target is %i", f, bombStatus); + CreateTimer(f, BombStatusAddTimer); + } + return Plugin_Stop; +} + +//Track bombStatus and update entities every 0.1 seconds +public Action BombStatusUpdater(Handle timer) { + if (isWave) { + CreateTimer(0.1, BombStatusUpdater); + if (bombStatus < bombStatusMax) { + switch (bombStatus) { + case 8: { + bombStatusMax = 8; + explodeType = 1; + canSENTShark = false; + FireEntityInput("Bombs*", "Disable", "", 0.0), + FireEntityInput("BombExplo*", "Disable", "", 0.0), + FireEntityInput("Delivery", "Unlock", "", 0.0), + FireEntityInput("Bombs.FreedomBomb", "Enable", "", 0.0), + CustomSoundEmitter(TRIGGERSCORE, SFXSNDLVL, false, 0, 1.0, 100), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team's {red}FREEDOM BOMB {forestgreen}is now available for deployment!"); + } + case 16: { + bombStatusMax = 16; + explodeType = 2; + canSENTShark = false; + FireEntityInput("Bombs*", "Disable", "", 0.0), + FireEntityInput("BombExplo*", "Disable", "", 0.0), + FireEntityInput("Bombs.ElonBust", "Enable", "", 0.0), + FireEntityInput("Delivery", "Unlock", "", 0.0), + CustomSoundEmitter(TRIGGERSCORE, SFXSNDLVL, false, 0, 1.0, 100), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team's {red}ELON BUST {forestgreen}is now available for deployment!"); + } + case 24: { + bombStatusMax = 24; + explodeType = 3; + canSENTShark = false; + FireEntityInput("Bombs*", "Disable", "", 0.0), + FireEntityInput("BombExplo*", "Disable", "", 0.0), + FireEntityInput("Bombs.BathSalts", "Enable", "", 0.0), + FireEntityInput("Delivery", "Unlock", "", 0.0), + CustomSoundEmitter(TRIGGERSCORE, SFXSNDLVL, false, 0, 1.0, 100), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team's {red}BATH SALTS {forestgreen}are now available for deployment!"); + } + case 32: { + bombStatusMax = 32; + explodeType = 4; + canSENTShark = false; + FireEntityInput("Bombs*", "Disable", "", 0.0), + FireEntityInput("BombExplo*", "Disable", "", 0.0), + FireEntityInput("Bombs.FallingStar", "Enable", "", 0.0), + FireEntityInput("Delivery", "Unlock", "", 0.0), + CustomSoundEmitter(TRIGGERSCORE, SFXSNDLVL, false, 0, 1.0, 100), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team's \x07FFFF00FALLING STAR{forestgreen} is now available for deployment!"); + } + case 40: { + bombStatusMax = 40; + explodeType = 5; + canSENTShark = false; + FireEntityInput("Bombs*", "Disable", "", 0.0), + FireEntityInput("BombExplo*", "Disable", "", 0.0), + FireEntityInput("Bombs.MajorKong", "Enable", "", 0.0), + FireEntityInput("Delivery", "Unlock", "", 0.0), + CustomSoundEmitter(TRIGGERSCORE, SFXSNDLVL, false, 0, 1.0, 100), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team's {red}MAJOR KONG {forestgreen}is now available for deployment!"); + } + case 48: { + bombStatusMax = 48; + explodeType = 6; + canSENTShark = true; + FireEntityInput("Bombs*", "Disable", "", 0.0), + FireEntityInput("BombExplo*", "Disable", "", 0.0), + FireEntityInput("Bombs.SharkTorpedo", "Enable", "", 0.0), + FireEntityInput("BombExploShark", "Enable", "", 0.0), + FireEntityInput("Delivery", "Unlock", "", 0.0), + CustomSoundEmitter(TRIGGERSCORE, SFXSNDLVL, false, 0, 1.0, 100), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team's {aqua}SHARK {forestgreen}is now available for deployment!"); + } + case 56: { + bombStatusMax = 56; + explodeType = 7; + canSENTShark = false; + FireEntityInput("Bombs*", "Disable", "", 0.0), + FireEntityInput("BombExplo*", "Disable", "", 0.0), + FireEntityInput("Bombs.FatMan", "Enable", "", 0.0), + FireEntityInput("Delivery", "Unlock", "", 0.0), + CustomSoundEmitter(TRIGGERSCORE, SFXSNDLVL, false, 0, 1.0, 100), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team's {orange}FAT MAN {forestgreen}is now available for deployment!"); + } + case 64: { + bombStatusMax = 64; + explodeType = 8; + canSENTShark = false; + FireEntityInput("Bombs*", "Disable", "", 0.0), + FireEntityInput("BombExplo*", "Disable", "", 0.0), + FireEntityInput("Bombs.Hydrogen", "Enable", "", 0.0), + FireEntityInput("Delivery", "Unlock", "", 0.0), + CustomSoundEmitter(TRIGGERSCORE, SFXSNDLVL, false, 0, 1.0, 100), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team's {red}HYDROGEN {forestgreen}is now available for deployment!"); + } + } + } else if (bombStatus > bombStatusMax) { + bombStatus = bombStatusMax - 4; + } + return Plugin_Continue; + } + return Plugin_Stop; +} + +//RobotLaunchTimer (Randomly fling robots) +public Action RobotLaunchTimer(Handle timer) { + if (isWave) { + FireEntityInput("FB.RobotLauncher", "Enable", "", 0.0), + FireEntityInput("FB.RobotLauncher", "Disable", "", 7.5); + float f = GetRandomFloat(5.0, 30.0); + CreateTimer(f, RobotLaunchTimer); + } + return Plugin_Stop; +} + +//Command action definitions +//Get current song +public Action Command_GetCurrentSong(int client, int args) { + PrintToChat(client, "The current song is: %s", songName); + return Plugin_Handled; +} + +//Determine which bomb has been recently pushed and tell the client if a bomb is ready or not. +public Action Command_FBBombStatus(int client, int args) { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}The bomb status is currently %i, with a max of %i", bombStatus, bombStatusMax); + switch (bombStatus) { + case 0, 1, 2, 3, 4, 5, 6, 7: { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Bombs are {red}NOT READY{white}!"); + } + case 8: { + if (bombProgression) { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team is currently pushing a {red}FREEDOM BOMB {forestgreen}!"); + } else { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team has not deployed any bombs, however: Your team's {red}FREEDOM BOMB {forestgreen}is available for deployment!"); + } + } + case 9, 10, 11, 12, 13, 14, 15: { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed a {white}FREEDOM BOMB {forestgreen}. Please wait for the next bomb."); + } + case 16: { + if (bombProgression) { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team is currently pushing an {red}ELON BUST {forestgreen}!"); + } else { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed a {white}FREEDOM BOMB {forestgreen}. Your team's {red}ELON BUST {forestgreen}is available for deployment!"); + } + } + case 17, 18, 19, 20, 21, 22, 23: { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed {white}ELON BUST {forestgreen}. Please wait for the next bomb."); + } + case 24: { + if (bombProgression) { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team is currently pushing {red}BATH SALTS {forestgreen}!"); + } else { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed a {white}ELON BUST {forestgreen}. Your team's {red}BATH SALTS {forestgreen}are available for deployment!"); + } + } + case 25, 26, 27, 28, 29, 30, 31: { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed {white}BATH SALTS {forestgreen}. Please wait for the next bomb."); + } + case 32: { + if (bombProgression) { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team is currently pushing a {red}FALLING STAR {forestgreen}!"); + } else { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed {white}BATH SALTS {forestgreen}. Your team's {red}FALLING STAR {forestgreen}is available for deployment!"); + } + } + case 33, 34, 35, 36, 37, 38, 39: { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed a {white}FALLING STAR {forestgreen}. Please wait for the next bomb."); + } + case 40: { + if (bombProgression) { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team is currently pushing a {red}MAJOR KONG {forestgreen}!"); + } else { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed {white}FALLING STAR {forestgreen}. Your team's {red}MAJOR KONG {forestgreen}is available for deployment!"); + } + } + case 41, 42, 43, 44, 45, 46, 47: { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed a {white}MAJOR KONG {forestgreen}. Please wait for the next bomb."); + } + case 48: { + if (bombProgression) { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team is currently pushing a {red}SHARK {forestgreen}!"); + } else { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed {white}MAJOR KONG {forestgreen}. Your team's {red}SHARK {forestgreen}is available for deployment!"); + } + } + case 49, 50, 51, 52, 53, 54, 55: { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed a {white}SHARK {forestgreen}. Please wait for the next bomb."); + } + case 56: { + if (bombProgression) { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team is currently pushing a {red}FAT MAN {forestgreen}!"); + } else { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed a {white}SHARK {forestgreen}. Your team's {red}FAT MAN {forestgreen}is available for deployment!"); + } + } + case 57, 58, 59, 60, 61, 62, 63: { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed a {white}FAT MAN {forestgreen}. Please wait for the next bomb."); + } + case 64: { + if (bombProgression) { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team is delivering \x07FFFF00HYDROGEN {forestgreen}!"); + } else { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed a {red} FAT MAN {forestgreen}. Your team's \x07FFFF00HYDROGEN {forestgreen}is available for deployment!"); + } + } + case 65, 66, 67, 68, 69, 70, 71: { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed a {white}HYDROGEN{forestgreen}. Bombs are automatically reset to preserve the replayable aspect of this game mode."); + } + case 72: { + CPrintToChatAll("{red}Something exceeded a maximum value!!! Apparently the bomb status is %i, with a maximum status of %i.", bombStatus, bombStatusMax); + } + } + return Plugin_Handled; +} + +//Return the client to spawn +public Action Command_Return(int client, int args) { + if (!IsPlayerAlive(client)) { + ReplyToCommand(client, "{red}[Core] You must be alive to use this command..."); + return Plugin_Handled; + } else { + char name[128]; + GetClientName(client, name, sizeof(name)); + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}Client {red}%s {white}began casting {darkviolet}/return{white}.", name); + CustomSoundEmitter(RETURNSND, SFXSNDLVL, false, 0, 1.0, 100); + CreateTimer(5.0, ReturnClient, client); + } + return Plugin_Handled; +} + +//Return the client to spawn +public Action ReturnClient(Handle timer, int clientID) { + TeleportEntity(clientID, Return, NULL_VECTOR, NULL_VECTOR); + if (soundPreference[clientID] >= 2) { + EmitSoundToClient(clientID, RETURNSUCCESS); + } + return Plugin_Handled; +} + +//Join us on Discord! +public Action Command_Discord(int client, int args) { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {white}Our Discord server URL is {darkviolet}https://discord.com/invite/SkHaeMH{white}."), + ShowMOTDPanel(client, "FireHostRedux Discord", "https://discord.com/invite/SkHaeMH", MOTDPANEL_TYPE_URL); + return Plugin_Handled; +} + +//Events +//Check who died by what and announce it to chat. +public Action EventDeath(Event Spawn_Event, + const char[] Spawn_Name, bool Spawn_Broadcast) { + int client = GetClientOfUserId(Spawn_Event.GetInt("userid")); + int attacker = GetClientOfUserId(Spawn_Event.GetInt("attacker")); + char attackerName[64]; + char weapon[32]; + Spawn_Event.GetString("weapon", weapon, sizeof(weapon)); + GetClientName(attacker, attackerName, sizeof(attackerName)); + if (0 < client <= MaxClients && IsClientInGame(client)) { + int damagebits = Spawn_Event.GetInt("damagebits"); + //Find server name + Handle convar = FindConVar("hostname"); + char ServerName[64]; + GetConVarString(convar, ServerName, sizeof(ServerName)); + if (StrEqual(attackerName, ServerName)) { + attackerName = "[INTENTIONAL GAME DESIGN]"; + } + if (attacker > 0 && sacrificedByClient) { //Was the client Sacrificed? + SacrificeClient(client, attacker, bombReset); + sacrificedByClient = false; + } + if (!attacker) { + switch (damagebits) { + case 1: { //CRUSH + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N was crushed by a {red}FALLING ROCK FROM OUTER SPACE{white}!", client); + weapon = "Meteor to the Face"; + } + case 8: { //BURN + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N was {red}MELTED{white}.", client); + weapon = "Melted by Sharts or Ass Gas"; + } + case 16: { //FREEZE + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N was flattened out by a {red}TRAIN{white}!", client); + weapon = "Attempted Train Robbery"; + } + case 32: { //FALL + if (tornado) { + switch (GetClientTeam(client)) { + case 2: { + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N was {red}YEETED OUT INTO ORBIT{white}!", client); + weapon = "Yeeted into Orbit by a Tornado"; + } + case 3: { + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N was {red}YEETED OUT INTO ORBIT{white}! ({limegreen}+1 pt{white})", client); + sacPoints++; + int i = GetRandomInt(1, 16); + switch (i) { + case 1: { + CustomSoundEmitter(FALLSND01, SFXSNDLVL, false, 0, 1.0, 100); + } + case 2: { + CustomSoundEmitter(FALLSND02, SFXSNDLVL, false, 0, 1.0, 100); + } + case 3: { + CustomSoundEmitter(FALLSND03, SFXSNDLVL, false, 0, 1.0, 100); + } + case 4: { + CustomSoundEmitter(FALLSND04, SFXSNDLVL, false, 0, 1.0, 100); + } + case 5: { + CustomSoundEmitter(FALLSND05, SFXSNDLVL, false, 0, 1.0, 100); + } + case 6: { + CustomSoundEmitter(FALLSND06, SFXSNDLVL, false, 0, 1.0, 100); + } + case 7: { + CustomSoundEmitter(FALLSND07, SFXSNDLVL, false, 0, 1.0, 100); + } + case 8: { + CustomSoundEmitter(FALLSND08, SFXSNDLVL, false, 0, 1.0, 100); + } + case 9: { + CustomSoundEmitter(FALLSND09, SFXSNDLVL, false, 0, 1.0, 100); + } + case 10: { + CustomSoundEmitter(FALLSND0A, SFXSNDLVL, false, 0, 1.0, 100); + } + case 11: { + CustomSoundEmitter(FALLSND0B, SFXSNDLVL, false, 0, 1.0, 100), + FireEntityInput("FB.BlueKirbTemplate", "ForceSpawn", "", 0.0); + } + case 12: { + CustomSoundEmitter(FALLSND0C, SFXSNDLVL, false, 0, 1.0, 100); + } + case 13: { + CustomSoundEmitter(FALLSND0D, SFXSNDLVL, false, 0, 1.0, 100); + } + case 14: { + CustomSoundEmitter(FALLSND0E, SFXSNDLVL, false, 0, 1.0, 100); + } + case 15: { + CustomSoundEmitter(FALLSND0F, SFXSNDLVL, false, 0, 1.0, 100); + } + case 16: { + CustomSoundEmitter(FALLSND10, SFXSNDLVL, false, 0, 1.0, 100); + } + } + } + } + } else { + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N fell to a {red}CLUMSY PAINFUL DEATH{white}!", client); + weapon = "Tripped on a LEGO"; + } + } + case 64: { //BLAST + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N went {red} KABOOM{white}!", client); + weapon = "Gone Kaboom!"; + } + case 128: { //CLUB + if (canHindenburg) { + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N is {red}CRASHING THE HINDENBURG{white}!!!", client); + weapon = "Crashing the Hindenburg"; + } + } + case 256: { //SHOCK + CPrintToChatAll("{darkviolet}[{red}EXTERMINATUS{darkviolet}] {white}Client %N has humliated themselves with an {red}incorrect {white}key entry!", client); + weapon = "Failed FB Code Entry"; + int i = GetRandomInt(1, 16); + switch (i) { + case 1, 3, 10: { + FireEntityInput("BG.Meteorites1", "ForceSpawn", "", 0.0), + CPrintToChatAll("{darkviolet}[{red}WARN{darkviolet}] {white}Uh oh, a {red}METEOR{white}has been spotted coming towards Dovah's Ass!!!"), + FireEntityInput("bg.meteorite1", "StartForward", "", 0.1); + } + case 2, 5, 16: { + CreateTimer(0.5, TimedOperator, 71); + FireEntityInput("FB.TankTrain", "TeleportToPathTrack", "Tank01", 0.0), + FireEntityInput("FB.TankTrain", "StartForward", "", 0.25), + FireEntityInput("FB.TankTrain", "SetSpeed", "1", 0.35), + FireEntityInput("FB.Tank", "Enable", "", 1.0); + } + case 4, 8, 14: { + CustomSoundEmitter("ambient/alarms/train_horn_distant1.wav", SFXSNDLVL, false, 0, 1.0, 100), + FireEntityInput("TrainSND", "PlaySound", "", 0.0), + FireEntityInput("TrainDamage", "Enable", "", 0.0), + FireEntityInput("Train01", "Enable", "", 0.0), + CPrintToChatAll("{darkviolet}[{red}WARN{darkviolet}] {orange}KISSONE'S TRAIN{white}is {red}INCOMING{white}. Look out!"), + FireEntityInput("TrainTrain", "TeleportToPathTrack", "TrainTrack01", 0.0), + FireEntityInput("TrainTrain", "StartForward", "", 0.1); + } + case 6, 9: { + canTornado = true, + CreateTimer(1.0, TimedOperator, 41); + } + case 7, 13: { + CPrintToChatAll("{darkviolet}[{red}WARN{darkviolet}] {white}Uh oh, a {red}METEOR SHOWER{white}has been reported from Dovah's Ass!!!"); + canSENTMeteors = true, + CreateTimer(1.0, SENTMeteorTimer), + CreateTimer(30.0, TimedOperator, 12); + } + case 11: { + FireEntityInput("FB.Slice", "Enable", "", 0.0), + CustomSoundEmitter("ambient/sawblade_impact1.wav", SFXSNDLVL, false, 0, 1.0, 100), + FireEntityInput("FB.Slice", "Disable", "", 1.0); + } + case 12, 15: { + CPrintToChatAll("{darkviolet}[{red}WARN{darkviolet}] {white}Uh oh, it's begun to rain {red}ATOM BOMBS{white}! TAKE COVER!"), + canSENTNukes = true, + CreateTimer(1.0, SENTNukeTimer), + CreateTimer(30.0, TimedOperator, 13); + } + } + } + case 512: { //SONIC + CPrintToChatAll("{darkviolet}[{red}EXTERMINATUS{darkviolet}] {white}Client %N has sacrificed themselves with a {forestgreen}correct {white}key entry! Prepare your anus!", client); + ServerCommand("fb_operator 1006"); + weapon = "Correct FB Code Entry"; + } + case 1024: { //ENERGYBEAM + if (crusader) { + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N has been vaporized by {red}THE CRUSADER{white}!", client); + weapon = "Crusader"; + } else if (waveFlags == 1) { + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N has been vaporized by {red}THE ONSLAUGHTER{white}!", client); + weapon = "Onslaughter"; + } else { + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N has been vaporized by a {red}HIGH ENERGY PHOTON BEAM{white}!", client); + weapon = "HE Photon Beam"; + } + } + case 16384: { //DROWN + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N {red}DROWNED{white}.", client); + weapon = "Darwin Award for Drowning"; + } + case 32768: { //PARALYZE + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N has been crushed by a {darkviolet}MYSTERIOUS BLUE BALL{white}!", client); + weapon = "Mysterious Blue Ball"; + } + case 65536: { //NERVEGAS + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N has been {red}SLICED TO RIBBONS{white}!", client); + weapon = "FB Code Entry Failed"; + } + case 131072: { //POISON + CPrintToChat(client, "{darkviolet}[{red}CORE{darkviolet}] {white}Please don't sit {red}IDLE {white}in the FC Tavern."); + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N was killed for standing in the Tavern instead of helping their team!", client); + weapon = "Idle in FC Tavern..?"; + } + case 262144: { //RADIATION + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N was blown away by a {red}NUCLEAR EXPLOSION{white}!", client); + weapon = "Nuclear Explosion"; + } + case 524288: { //DROWNRECOVER + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N experienced {red}TACO BELL{white}!", client); + weapon = "Taco Bell"; + } + case 1048576: { //ACID + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N has been crushed by a {forestgreen}FALLING GOOBBUE FROM OUTER SPACE{white}!", client); + weapon = "Falling Goobbue"; + } + } + } + + //Log if a player killed someone + if (attacker != client) { + char query[256]; + int steamID; + if (attacker != 0) { + steamID = GetSteamAccountID(attacker); + } else { + steamID = 0; + } + if (!FB_Database) { + return Plugin_Handled; + } + if (!steamID || steamID <= 10000) { + int steamIDclient = GetSteamAccountID(client); + if (!steamIDclient || steamIDclient <= 10000) { + return Plugin_Handled; + } else { + char queryClient[256]; + Format(queryClient, sizeof(queryClient), "UPDATE ass_activity SET deaths = deaths + 1, deathssession = deathssession + 1 WHERE steamid = %i;", steamIDclient); + FB_Database.Query(Database_FastQuery, queryClient); + if (!StrEqual(weapon, "world")) { + Format(queryClient, sizeof(queryClient), "UPDATE ass_activity SET killedbyname = '%s', killedbyweapon = '%s' WHERE steamid = %i;", attackerName, weapon, steamIDclient); + FB_Database.Query(Database_FastQuery, queryClient); + } + return Plugin_Handled; + } + } + Format(query, sizeof(query), "UPDATE ass_activity SET kills = kills + 1, killssession = killssession + 1 WHERE steamid = %i;", steamID); + FB_Database.Query(Database_FastQuery, query); + if (!StrEqual(weapon, "world")) { + Format(query, sizeof(query), "UPDATE ass_activity SET lastkilledname = '%N', lastweaponused = '%s' WHERE steamid = %i;", client, weapon, steamID); + FB_Database.Query(Database_FastQuery, query); + } + } + return Plugin_Handled; + } + return Plugin_Handled; +} + +//Check who spawned and log their class +public Action EventSpawn(Event Spawn_Event, + const char[] Spawn_Name, bool Spawn_Broadcast) { + int client = GetClientOfUserId(Spawn_Event.GetInt("userid")); + if (IsValidClient(client)) { + char strClass[32]; + char query[256]; + int class = Spawn_Event.GetInt("class"); + int steamID = GetSteamAccountID(client); + if (!FB_Database || !steamID || !class) { + return Plugin_Handled; + } + switch (class) { + case 1: { + strClass = "scout"; + } + case 2: { + strClass = "sniper"; + } + case 3: { + strClass = "soldier"; + } + case 4: { + strClass = "demoman"; + } + case 5: { + strClass = "medic"; + } + case 6: { + strClass = "heavy"; + } + case 7: { + strClass = "pyro"; + } + case 8: { + strClass = "spy"; + } + case 9: { + strClass = "engineer"; + } + } + Format(query, sizeof(query), "UPDATE ass_activity SET class = '%s' WHERE steamid = %i;", strClass, steamID); + FB_Database.Query(Database_FastQuery, query); + } + return Plugin_Handled; +} + +//Silence cvar changes to minimize chat spam. +public Action Event_Cvar(Event event, + const char[] name, bool dontBroadcast) { + event.BroadcastDisabled = true; + return Plugin_Handled; +} + +//When we win +public Action EventWaveComplete(Event Spawn_Event, + const char[] Spawn_Name, bool Spawn_Broadcast) { + stopPrevSong = true; + BGMINDEX = 0; + tbLoop = 0; + canCrusaderNuke = false; + canHindenburg = false; + canHWBoss = false; + canSephNuke = false; + canTornado = false; + isWave = false; + bombStatusMax = 7; + bombStatus = 5; + explodeType = 0; + sephiroth = false; + waveFlags = 0; + ServerCommand("fb_operator 1000"); + CreateTimer(1.0, PerformAdverts); + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}You've defeated the wave!"); + FireEntityInput("BTN.Sacrificial*", "Disable", "", 0.0), + FireEntityInput("BTN.Sacrificial*", "Color", "0", 0.0); + FireEntityInput("Barricade_Rebuild_Relay", "Trigger", "", 0.0); + FireEntityInput("FB.KP*", "Lock", "", 0.0); + FireEntityInput("OldSpawn", "Disable", "", 0.0); + FireEntityInput("NewSpawn", "Enable", "", 0.0); + FireEntityInput("CommonSpells", "Disable", "", 0.0); + FireEntityInput("RareSpells", "Disable", "", 0.0); + FireEntityInput("dovahsassprefer", "Disable", "", 0.0); + FireEntityInput("bombpath_left_arrows", "Disable", "", 0.0); + FireEntityInput("bombpath_right_arrows", "Disable", "", 0.0); + FireEntityInput("rain", "Alpha", "0", 0.0); + ServerCommand("fb_operator 1007"); + ServerCommand("fb_operator 1002"); + CreateTimer(40.0, SelectAdminTimer); + return Plugin_Handled; +} + +//Announce when we are in danger. +public Action EventWarning(Event Spawn_Event, + const char[] Spawn_Name, bool Spawn_Broadcast) { + CPrintToChatAll("{darkviolet}[{red}WARN{darkviolet}] {darkred}PROFESSOR'S ASS IS ABOUT TO BE DEPLOYED!!!"); + return Plugin_Handled; +} + +//When the wave fails +public Action EventWaveFailed(Event Spawn_Event, + const char[] Spawn_Name, bool Spawn_Broadcast) { + stopPrevSong = true; + BGMINDEX = 0; + tbLoop = 0; + canCrusaderNuke = false; + canHindenburg = false; + canHWBoss = false; + canSephNuke = false; + canTornado = false; + isWave = false; + bombStatusMax = 7; + bombStatus = 5; + explodeType = 0; + sephiroth = false; + waveFlags = 0; + if (FailedCount == 0) { //Works around valve's way of firing EventWaveFailed four times when mission changes. Without this, BGM would play 4 times and any functions enclosed would also happen four times....... + FailedCount++; + ServerCommand("fb_operator 1000"); + CreateTimer(1.0, PerformAdverts); + CreateTimer(40.0, SelectAdminTimer); + } + FireEntityInput("rain", "Alpha", "0", 0.0); + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}Wave {red}failed {white}successfully!"); + FireEntityInput("BTN.Sacrificial*", "Disable", "", 0.0), + FireEntityInput("BTN.Sacrificial*", "Color", "0", 0.0); + FireEntityInput("BTN.Sacrificial*", "Disable", "", 0.0), + FireEntityInput("BTN.Sacrificial*", "Color", "0", 0.0); + FireEntityInput("Barricade_Rebuild_Relay", "Trigger", "", 0.0); + FireEntityInput("FB.KP*", "Lock", "", 0.0); + FireEntityInput("OldSpawn", "Disable", "", 0.0); + FireEntityInput("NewSpawn", "Enable", "", 0.0); + FireEntityInput("CommonSpells", "Disable", "", 0.0); + FireEntityInput("RareSpells", "Disable", "", 0.0); + FireEntityInput("dovahsassprefer", "Disable", "", 0.0); + FireEntityInput("bombpath_left_arrows", "Disable", "", 0.0); + FireEntityInput("bombpath_right_arrows", "Disable", "", 0.0); + FireEntityInput("rain", "Alpha", "0", 0.0); + ServerCommand("fb_operator 1007"); + ServerCommand("fb_operator 1002"); + return Plugin_Handled; +} + +//Log Damage! +public void Event_Playerhurt(Handle event, + const char[] name, bool dontBroadcast) { + int client = GetClientOfUserId(GetEventInt(event, "userid")); + int attacker = GetClientOfUserId(GetEventInt(event, "attacker")); + int damage = GetEventInt(event, "damageamount"); + int health = GetEventInt(event, "health"); + int attackerhp = GetClientHealth(attacker); + PrintToConsoleAll("[CORE-DBG] player hurt triggered by %N with %i hp. The attacker was %N with %i HP.", client, health, attacker, attackerhp); + if (IsValidClient(attacker) && attacker != client) { + char query[256]; + int steamID = GetSteamAccountID(attacker); + PrintToConsole(attacker, "Writing new myDmg value %i", damage); + if (!FB_Database) { + return; + } + if (!steamID) { + return; + } + Format(query, sizeof(query), "UPDATE ass_activity SET damagedealt = damagedealt + %i, damagedealtsession = damagedealtsession + %i WHERE steamid = %i;", damage, damage, steamID); + FB_Database.Query(Database_FastQuery, query); + } +} + +//Functions +//Create a temp entity and fire an input +public Action FireEntityInput(char[] strTargetname, char[] strInput, char[] strParameter, float flDelay) { + char strBuffer[255]; + Format(strBuffer, sizeof(strBuffer), "OnUser1 %s:%s:%s:%f:1", strTargetname, strInput, strParameter, flDelay); + //PrintToChatAll("{limegreen}[CORE] {white}Firing entity %s with input %s , a parameter override of %s , and delay of %f ...", strTargetname, strInput, strParameter, flDelay); + int entity = CreateEntityByName("info_target"); + if (IsValidEdict(entity)) { + DispatchSpawn(entity); + ActivateEntity(entity); + SetVariantString(strBuffer); + AcceptEntityInput(entity, "AddOutput"); + AcceptEntityInput(entity, "FireUser1"); + CreateTimer(0.0, DeleteEdict, entity); + return Plugin_Continue; + } + return Plugin_Handled; +} + +//Custom sound processor, this should make handling sounds easier. +// int flags: +// SND_NOFLAGS= 0, /**< Nothing */ +// SND_CHANGEVOL = 1, /**< Change sound volume */ +// SND_CHANGEPITCH = 2, /**< Change sound pitch */ +// SND_STOP = 3, /**< Stop the sound */ +// SND_SPAWNING = 4, /**< Used in some cases for ambients */ +// SND_DELAY = 5, /**< Sound has an initial delay */ +// SND_STOPLOOPING = 6, /**< Stop looping all sounds on the entity */ +// SND_SPEAKER = 7, /**< Being played by a mic through a speaker */ +// SND_SHOULDPAUSE = 8 /**< Pause if game is paused */ +public Action CustomSoundEmitter(char[] sndName, int SNDLVL, bool isBGM, int flags, float vol, int pitch) { + for (int i = 1; i <= MaxClients; i++) { + //If it's music + if (IsClientInGame(i) && !IsFakeClient(i) && (soundPreference[i] == 1 || soundPreference[i] == 3) && isBGM) { + EmitSoundToClient(i, sndName, _, SNDCHAN, SNDLVL, flags, vol, pitch, _, _, _, _, _); + } + //If it's sound effects + else if (IsClientInGame(i) && !IsFakeClient(i) && soundPreference[i] >= 2 && !isBGM) { + EmitSoundToClient(i, sndName, _, SNDCHAN, SNDLVL, flags, vol, pitch, _, _, _, _, _); + } + } + return Plugin_Handled; +} + +//Jump waves. +public Action JumpToWave(int wave_number) { + int flags = GetCommandFlags("tf_mvm_jump_to_wave"); + SetCommandFlags("tf_mvm_jump_to_wave", flags & ~FCVAR_CHEAT); + ServerCommand("tf_mvm_jump_to_wave %d", wave_number); + FakeClientCommand(0, ""); + SetCommandFlags("tf_mvm_jump_to_wave", flags | FCVAR_CHEAT); + return Plugin_Handled; +} + +//Remove edict allocated by temp entity +public Action DeleteEdict(Handle timer, any entity) { + if (IsValidEdict(entity)) RemoveEdict(entity); + return Plugin_Stop; +} + +//Sacrifice target and grant bonus points +public Action SacrificeClient(int client, int attacker, bool wasBombReset) { + if (attacker <= MaxClients && IsClientInGame(attacker) && wasBombReset == true) { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}Client {red}%N {white}has reset the ass! ({limegreen}+5 pts{white})", attacker); + bombReset = false; + char query[256]; + int steamID = GetSteamAccountID(attacker); + sacPoints += 5; + if (!FB_Database || !steamID) { + return Plugin_Handled; + } + Format(query, sizeof(query), "UPDATE ass_activity SET bombsreset = bombsreset + 1, bombsresetsession = bombsresetsession + 1 WHERE steamid = %i;", steamID); + FB_Database.Query(Database_FastQuery, query); + } else if (attacker <= MaxClients && IsClientInGame(attacker) && wasBombReset == false) { + int steamID = GetSteamAccountID(attacker); + if (!FB_Database || !steamID || !isWave) { + return Plugin_Handled; + } else { + char query[256]; + sacPoints++; + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}Client {red}%N {white}has sacrificed {blue}%N {white}for the ass! ({limegreen}+1 pt{white})", attacker, client); + Format(query, sizeof(query), "UPDATE ass_activity SET sacrifices = sacrifices + 1, sacrificessession = sacrificessession + 1 WHERE steamid = %i;", steamID); //Eventually we will want to replace this with sacrifices, sacrificessession. + FB_Database.Query(Database_FastQuery, query); + } + } + return Plugin_Handled; +} + +//Operator, core of the entire map +public Action Command_Operator(int args) { + char arg1[16]; + GetCmdArg(1, arg1, sizeof(arg1)); + int x = StringToInt(arg1); + //PrintToConsoleAll("Calling on fb_operator because arg1 was %i, and was stored in memory position %i", x, arg1); + switch (x) { + //When the map is complete + case 0: { + if (tacobell) { + CPrintToChatAll("WOWIE YOU DID IT! The server will restart in 30 seconds, prepare to do it again! LULW"); + CreateTimer(10.0, TimedOperator, 100); + } else { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}YOU HAVE SUCCESSFULLY COMPLETED PROF'S ASS ! THE SERVER WILL RESTART IN 10 SECONDS."); + CreateTimer(10.0, TimedOperator, 100); + } + } + //Prepare yourself! + case 1: { + char mapName[64]; + tacobell = false; + ServerCommand("fb_startmoney 50000"); + CPrintToChatAll("{darkviolet}[{yellow}INFO{darkviolet}] {red}PROFESSOR'S ASS {white}v0x1E. Prepare yourself for the unpredictable... [{limegreen}by TTV/ProfessorFartsalot{white}]"); + GetCurrentMap(mapName, sizeof(mapName)); + FireEntityInput("rain", "Alpha", "0", 0.0); + /*Prepare for the end times.... + if (StrContains(mapName, "R1A", true) || StrContains(mapName, "R1B", true) || StrContains(mapName, "R1C", true) || StrContains(mapName, "R1D", true) || StrContains(mapName, "R1E", true) || StrContains(mapName, "R1F", true)) { + int i = GetRandomInt(1, 7); + switch (i) { + case 1: { + CPrintToChatAll("{darkviolet}[{yellow}????{darkviolet}] {darkviolet}Fartsy... what have you done???"); + } + case 2: { + CPrintToChatAll("{darkviolet}[{yellow}????{darkviolet}] {darkviolet}The end is NEAR..."); + } + case 3: { + CPrintToChatAll("{darkviolet}[{yellow}????{darkviolet}] {darkviolet}The ass grows ever stronger..."); + } + case 4: { + CPrintToChatAll("{darkviolet}[{yellow}????{darkviolet}] {darkviolet}Muahahahahahahahaha, so MUCH POWER!"); + } + case 5: { + CPrintToChatAll("{darkviolet}[{yellow}????{darkviolet}] {darkviolet}Just a little further.... JUST.. a LITTLE... FURTHER!"); + } + case 6: { + CPrintToChatAll("{darkviolet}[{yellow}????{darkviolet}] {darkviolet}Investigate if you dare..."); + } + case 7: { + CPrintToChatAll("{darkviolet}[{yellow}????{darkviolet}] {darkviolet}Come... JOIN US. Throw wide the gates!"); + } + } + }*/ + } + //Wave init + case 2: { + int ent = FindEntityByClassname(-1, "tf_objective_resource"); //Get current wave, perform actions per wave. + if (ent == -1) { + LogMessage("tf_objective_resource not found"); + return Plugin_Handled; + } + curWave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineWaveCount")); + PerformWaveSetup(); + switch (curWave) { + case 1: { + if (tacobell) { + canTornado = true; + bombStatus = 0; + bombStatusMax = 10; + sacPointsMax = 90; + SetupMusic(10); + } else { + bombStatus = 0; + bombStatusMax = 10; + sacPointsMax = 90; + SetupMusic(2); + } + } + case 2, 9, 16: { + canHWBoss = true; + canTornado = true; + bombStatus = 4; + bombStatusMax = 18; + sacPointsMax = 90; + SetupMusic(3); + //CreateTimer(0.1, TimedOperator, 3); + FireEntityInput("Classic_Mode_Intel3", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel4", "Enable", "", 0.0); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + case 3, 10, 17: { + canHWBoss = true; + canTornado = true; + HWNMax = 360.0; + bombStatus = 7; + bombStatusMax = 26; + sacPointsMax = 90; + SetupMusic(4); + //CreateTimer(0.1, TimedOperator, 4); + FireEntityInput("Classic_Mode_Intel3", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel4", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel5", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel6", "Enable", "", 0.0); + float f = GetRandomFloat(60.0, 180.0); + CreateTimer(f, TimedOperator, 70); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + case 4, 11, 18: { + canHWBoss = true; + canTornado = true; + HWNMax = 360.0; + isWave = true; + bombStatus = 12; + bombStatusMax = 34; + sacPointsMax = 90; + SetupMusic(5); + //CreateTimer(0.1, TimedOperator, 5); + FireEntityInput("Classic_Mode_Intel3", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel4", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel5", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel6", "Enable", "", 0.0); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + case 5, 12, 19: { + canHWBoss = true; + canTornado = true; + HWNMax = 260.0; + HWNMin = 140.0; + isWave = true; + bombStatus = 14; + bombStatusMax = 42; + sacPointsMax = 100; + SetupMusic(6); + //CreateTimer(0.1, TimedOperator, 6); + FireEntityInput("Classic_Mode_Intel3", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel4", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel5", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel6", "Enable", "", 0.0); + FireEntityInput("w5_engie_hints", "Trigger", "", 3.0); + float f = GetRandomFloat(60.0, 180.0); + CreateTimer(f, TimedOperator, 70); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + case 6, 13, 20: { + canHWBoss = true; + canTornado = true; + HWNMax = 260.0; + HWNMin = 140.0; + isWave = true; + bombStatus = 20; + bombStatusMax = 50; + sacPointsMax = 100; + SetupMusic(7); + FireEntityInput("Classic_Mode_Intel3", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel4", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel5", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel6", "Enable", "", 0.0); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + case 7, 14, 21: { + canHWBoss = true; + canTornado = true; + HWNMax = 240.0; + HWNMin = 120.0; + isWave = true; + bombStatus = 28; + bombStatusMax = 58; + sacPointsMax = 100; + SetupMusic(8); + FireEntityInput("rain", "Alpha", "200", 0.0); + FireEntityInput("Classic_Mode_Intel3", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel4", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel5", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel6", "Enable", "", 0.0); + FireEntityInput("w5_engie_hints", "Trigger", "", 3.0); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + case 8, 15: { + canHWBoss = true; + canTornado = true; + HWNMax = 240.0; + HWNMin = 120.0; + bombStatus = 30; + bombStatusMax = 66; + sacPointsMax = 100; + SetupMusic(9); + FireEntityInput("Classic_Mode_Intel3", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel4", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel5", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel6", "Enable", "", 0.0); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + } + return Plugin_Handled; + } + //Force Tornado + case 3: { + if (isWave && canTornado && !tornado) { + CreateTimer(0.1, TimedOperator, 41); + PrintCenterTextAll("OH NOES... PREPARE YOUR ANUS!"); + } else { + PrintToServer("Error spawning manual tornado... Perhaps we are not in a wave, tornadoes are banished, or a tornado has already spawned???"); + } + return Plugin_Handled; + } + //Signal that previous boss should spawn. + case 4: { + waveFlags--; + } + //Signal that a boss should spawn + case 5: { + if (waveFlags < 0) { + waveFlags = 0; + } + switch (waveFlags) { + //Case 0, boss does not spawn. This is unreachable. + case 0: { + PrintToChatAll("Caught unhandled exception: waveFlags 0 but operator 5 was invoked."); + return Plugin_Handled; + } + //Case 1, summon Onslaughter. + case 1: { + //PrintToChatAll("Got 1. Spawning Onslaughter."), + FireEntityInput("FB.BruteJusticeTrain", "TeleportToPathTrack", "tank_path_a_10", 0.0), + FireEntityInput("FB.BruteJustice", "Enable", "", 3.0), + FireEntityInput("FB.BruteJusticeTrain", "StartForward", "", 3.0), + FireEntityInput("FB.BruteJusticeParticles", "Start", "", 3.0), + CreateTimer(5.0, OnslaughterATK), + FireEntityInput("tank_boss", "AddOutput", "rendermode 10", 3.0), + FireEntityInput("tank_boss", "AddOutput", "rendermode 10", 4.0), + FireEntityInput("tank_boss", "AddOutput", "rendermode 10", 5.0), + FireEntityInput("tank_boss", "AddOutput", "rendermode 10", 6.0), + FireEntityInput("tank_boss", "AddOutput", "rendermode 10", 7.0), + FireEntityInput("tank_boss", "AddOutput", "rendermode 10", 8.0); + CreateTimer(10.0, OnslaughterHPTimer); + } + //Case 2, summon Custom Boss 1 + case 2: { + FireEntityInput("FB.Sephiroth", "Enable", "", 0.0), + FireEntityInput("SephMeteor", "SetParent", "FB.Sephiroth", 0.0), + FireEntityInput("SephTrain", "SetSpeedReal", "12", 0.0), + FireEntityInput("SephTrain", "TeleportToPathTrack", "Seph01", 0.0), + FireEntityInput("SephTrain", "StartForward", "", 0.1), + FireEntityInput("SephTrain", "SetSpeedReal", "12", 20.5), + FireEntityInput("FB.SephParticles", "Start", "", 3.0), + FireEntityInput("tank_boss", "AddOutput", "rendermode 10", 3.0), + FireEntityInput("tank_boss", "AddOutput", "rendermode 10", 4.0), + FireEntityInput("tank_boss", "AddOutput", "rendermode 10", 5.0), + FireEntityInput("tank_boss", "AddOutput", "rendermode 10", 6.0), + FireEntityInput("tank_boss", "AddOutput", "rendermode 10", 7.0), + FireEntityInput("tank_boss", "AddOutput", "rendermode 10", 8.0), + FireEntityInput("FB.BruteJusticeDMGRelay", "Kill", "", 0.0); + int players = 0; + for (int i = 1; i <= MaxClients; i++) { + if (IsClientInGame(i) && !IsFakeClient(i)) + players++; + } + PrintToServer("We have %i player(s), setting boss attributes accordingly!", players); + switch (players) { + case 1: { + FireEntityInput("SephTrain", "SetSpeedReal", "40", 23.0), + FireEntityInput("tank_boss", "SetHealth", "409600", 1.0), + FireEntityInput("FB.SephDMGRelay", "SetHealth", "32768000", 1.0); + } + case 2: { + FireEntityInput("SephTrain", "SetSpeedReal", "35", 23.0), + FireEntityInput("tank_boss", "SetHealth", "614400", 1.0), + FireEntityInput("FB.SephDMGRelay", "SetHealth", "32768000", 1.0); + } + case 3: { + FireEntityInput("SephTrain", "SetSpeedReal", "35", 23.0), + FireEntityInput("tank_boss", "SetHealth", "614400", 1.0), + FireEntityInput("FB.SephDMGRelay", "SetHealth", "131072000", 1.0); + } + case 4: { + FireEntityInput("SephTrain", "SetSpeedReal", "30", 23.0), + FireEntityInput("tank_boss", "SetHealth", "819200", 1.0), + FireEntityInput("FB.SephDMGRelay", "SetHealth", "262144000", 1.0); + } + case 5, 6, 7, 8, 9, 10: { + FireEntityInput("SephTrain", "SetSpeedReal", "25", 23.0), + FireEntityInput("tank_boss", "SetHealth", "819200", 1.0), + FireEntityInput("FB.SephDMGRelay", "SetHealth", "655360000", 1.0); + } + } + CreateTimer(30.0, SephHPTimer); + } + } + } + //Signal that next boss should spawn + case 6: { + waveFlags++; + } + //Signal to fastforward boss spawn. + case 7: { + waveFlags = 2; + if (curWave == 8 && !tacobell) { + ServerCommand("fb_operator 1001"); + CreateTimer(0.0, TimedOperator, 8); + } + } + //When a tornado intersects a tank. + case 8: { + FireEntityInput("FB.FakeTankSpawner", "ForceSpawn", "", 0.1); + } + //Client was Sacrificed. + case 10: { + sacrificedByClient = true; + } + //Damage relay took damage + case 11: { + FireEntityInput("TankRelayDMG", "Enable", "", 0.0), + FireEntityInput("TankRelayDMG", "Disable", "", 0.5); + } + //dmg relay was killed + case 12: { + FireEntityInput("tank_boss", "SetHealth", "1", 0.0); + FireEntityInput("TankRelayDMG", "Enable", "", 0.1); + FireEntityInput("TankRelayDMG", "Enable", "", 0.5); + FireEntityInput("TankRelayDMG", "Enable", "", 1.0); + FireEntityInput("TankRelayDMG", "Disable", "", 10.0); + } + //Tank Destroyed (+1), includes disabling onslaughter. + case 13: { + switch (waveFlags) { + case 0: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}A tank has been destroyed. ({limegreen}+1 pt{white})"); + sacPoints++; + } + case 1: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {red}ONSLAUGHTER {white}has been destroyed. ({limegreen}+25 pts{white})"); + FireEntityInput("FB.BruteJustice", "Disable", "", 0.0); + FireEntityInput("FB.BruteJusticeTrain", "Stop", "", 0.0); + FireEntityInput("FB.BruteJusticeParticles", "Stop", "", 0.0); + FireEntityInput("FB.BruteJusticeDMGRelay", "Break", "", 0.0); + FireEntityInput("FB.BruteJusticeTrain", "TeleportToPathTrack", "tank_path_a_10", 0.5); + waveFlags = 0; + sacPoints += 25; + } + case 2: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {red}SEPHIROTH {white}has been destroyed. ({limegreen}+100 pts{white})"); + FireEntityInput("FB.Sephiroth", "Disable", "", 0.0), + FireEntityInput("SephTrain", "TeleportToPathTrack", "Seph01", 0.0), + FireEntityInput("SephTrain", "Stop", "", 0.0), + canSephNuke = false, + sacPoints += 100, + waveFlags = 0; + canTornado = false; + } + } + return Plugin_Handled; + } + //Bomb Reset (+5) + case 14: { + bombReset = true; + sacPoints += 5; + } + //Bomb Deployed + case 15: { + FireEntityInput("FB.PayloadWarning", "Disable", "", 0.0); + switch (explodeType) { + //Invalid + case 0: { + PrintToServer("Tried to detonate with a bomb size of zero!"); + } + //Small Explosion + case 1: { + FireEntityInput("RareSpells", "Enable", "", 0.0); + EmitSoundToAll(BMB1SND), + FireEntityInput("SmallExplosion", "Explode", "", 0.0), + FireEntityInput("SmallExploShake", "StartShake", "", 0.0), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}Small Bomb successfully pushed! ({limegreen}+2 pts{white})"); + sacPoints += 2, + bombStatusMax += 10, + CreateTimer(3.0, BombStatusAddTimer); + CustomSoundEmitter(COUNTDOWN, SFXSNDLVL, false, 0, 1.0, 100); + if (bombStatus >= bombStatusMax) { + return Plugin_Handled; + } else { + bombStatus += 2; + } + } + //Medium Explosion + case 2: { + FireEntityInput("RareSpells", "Enable", "", 0.0); + EmitSoundToAll(BMB2SND), + FireEntityInput("MediumExplosion", "Explode", "", 0.0), + FireEntityInput("MedExploShake", "StartShake", "", 0.0), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}Medium Bomb successfully pushed! ({limegreen}+5 pts{white})"); + sacPoints += 5, + bombStatusMax += 10, + CreateTimer(3.0, BombStatusAddTimer); + CustomSoundEmitter(COUNTDOWN, SFXSNDLVL, false, 0, 1.0, 100); + if (bombStatus >= bombStatusMax) { + return Plugin_Handled; + } else { + bombStatus += 2; + } + } + //Medium Explosion (Bath salts) + case 3: { + FireEntityInput("RareSpells", "Enable", "", 0.0); + EmitSoundToAll(BMB2SND), + FireEntityInput("MediumExplosion", "Explode", "", 0.0), + FireEntityInput("MedExploShake", "StartShake", "", 0.0), + ServerCommand("sm_freeze @blue 10"); + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}Medium Bomb successfully pushed! Bots froze for 10 seconds. ({limegreen}+5 pts{white})"); + sacPoints += 5, + bombStatusMax += 10, + CreateTimer(3.0, BombStatusAddTimer); + CustomSoundEmitter(COUNTDOWN, SFXSNDLVL, false, 0, 1.0, 100); + if (bombStatus >= bombStatusMax) { + return Plugin_Handled; + } else { + bombStatus += 2; + } + } + //Falling Star + case 4: { + FireEntityInput("RareSpells", "Enable", "", 0.0); + canSENTStars = true, + EmitSoundToAll(BMB2SND), + FireEntityInput("MediumExplosion", "Explode", "", 0.0), + FireEntityInput("MedExploShake", "StartShake", "", 0.0), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}Large Bomb successfully pushed! ({limegreen}+10 pts{white})"); + sacPoints += 10, + bombStatusMax += 10, + CreateTimer(3.0, BombStatusAddTimer); + CustomSoundEmitter(COUNTDOWN, SFXSNDLVL, false, 0, 1.0, 100), + CreateTimer(1.0, SENTStarTimer), + CreateTimer(60.0, TimedOperator, 14); + if (bombStatus >= bombStatusMax) { + return Plugin_Handled; + } else { + bombStatus += 2; + } + } + //Major Kong + case 5: { + FireEntityInput("RareSpells", "Enable", "", 0.0); + EmitSoundToAll(BMB4SND), + FireEntityInput("FB.Fade", "Fade", "", 1.7), + FireEntityInput("LargeExplosion", "Explode", "", 1.7), + FireEntityInput("LargeExplosionSound", "PlaySound", "", 1.7), + FireEntityInput("LargeExploShake", "StartShake", "", 1.7), + FireEntityInput("NukeAll", "Enable", "", 1.7), + FireEntityInput("NukeAll", "Disable", "", 3.0), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {red}NUCLEAR WARHEAD {white}successfully pushed! ({limegreen}+25 pts{white})"); + sacPoints += 25, + bombStatusMax += 10, + CreateTimer(3.0, BombStatusAddTimer); + CustomSoundEmitter(COUNTDOWN, SFXSNDLVL, false, 0, 1.0, 100); + if (bombStatus >= bombStatusMax) { + return Plugin_Handled; + } else { + bombStatus += 4; + } + } + //Large (shark) + case 6: { + FireEntityInput("RareSpells", "Enable", "", 0.0); + EmitSoundToAll(BMB3SND), + FireEntityInput("LargeExplosion", "Explode", "", 0.0), + FireEntityInput("LargeExploShake", "StartShake", "", 0.0), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}Heavy Bomb successfully pushed! ({limegreen}+15 pts{white})"); + sacPoints += 15, + bombStatusMax += 10, + CreateTimer(3.0, BombStatusAddTimer); + CustomSoundEmitter(COUNTDOWN, SFXSNDLVL, false, 0, 1.0, 100); + if (bombStatus >= bombStatusMax) { + return Plugin_Handled; + } else { + bombStatus += 4; + } + } + //FatMan + case 7: { + FireEntityInput("RareSpells", "Enable", "", 0.0); + EmitSoundToAll(HINDENBURGBOOM); + FireEntityInput("LargeExplosion", "Explode", "", 0.0), + FireEntityInput("LargeExploShake", "StartShake", "", 0.0), + FireEntityInput("NukeAll", "Enable", "", 0.0), + FireEntityInput("FB.Fade", "Fade", "", 0.0), + FireEntityInput("NukeAll", "Disable", "", 3.0), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {red}NUCLEAR WARHEAD{white}successfully pushed! ({limegreen}+25 pts{white})"); + sacPoints += 25, + bombStatusMax += 10, + CreateTimer(3.0, BombStatusAddTimer); + CreateTimer(15.0, SpecTimer); + CustomSoundEmitter(COUNTDOWN, SFXSNDLVL, false, 0, 1.0, 100); + if (bombStatus >= bombStatusMax) { + return Plugin_Handled; + } else { + bombStatus += 4; + } + } + //Hydrogen + case 8: { + FireEntityInput("RareSpells", "Enable", "", 0.0); + EmitSoundToAll(HINDENBURGBOOM); + FireEntityInput("LargeExplosion", "Explode", "", 0.0), + FireEntityInput("LargeExploShake", "StartShake", "", 0.0), + FireEntityInput("LargeExplosionSND", "PlaySound", "", 0.0), + FireEntityInput("NukeAll", "Enable", "", 0.0), + FireEntityInput("FB.Fade", "Fade", "", 0.0), + FireEntityInput("NukeAll", "Disable", "", 3.0), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {red}HINDENBURG {white}successfully fueled! ({limegreen}+30 pts{white})"); + CPrintToChatAll("The {red}HINDENBURG {forestgreen}is now ready for flight!"); + FireEntityInput("DeliveryBurg", "Unlock", "", 0.0); + bombStatus = 0; + canHindenburg = true; + explodeType = 0; + CreateTimer(3.0, BombStatusAddTimer); + CustomSoundEmitter(COUNTDOWN, SFXSNDLVL, false, 0, 1.0, 100); + } + //Fartsy of the Seventh Taco Bell + case 69: { + FireEntityInput("NukeAll", "Enable", "", 0.0), + EmitSoundToAll(HINDENBURGBOOM); + FireEntityInput("FB.Fade", "Fade", "", 0.0), + FireEntityInput("NukeAll", "Disable", "", 2.0), + bombStatusMax = 64; + CreateTimer(5.0, TimedOperator, 99); + } + } + return Plugin_Handled; + } + //Tank deployed its bomb + case 16: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}A tank has deployed its bomb! ({limegreen}+1 pt{white})"); + } + //Shark Enable & notify bomb push began + case 20: { + bombProgression = true; + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Bomb push in progress."); + FireEntityInput("FB.PayloadWarning", "Enable", "", 0.0); + CreateTimer(3.0, SharkTimer); + } + //Shark Disable + case 21: { + bombProgression = false; + canSENTShark = false; + } + //HINDENBOOM ACTIVATION + case 28: { + EmitSoundToAll(BOOM); + FireEntityInput("HindenTrain", "StartForward", "", 0.0); + FireEntityInput("DeliveryBurg", "Lock", "", 0.0); + FireEntityInput("Boom", "Enable", "", 0.0); + FireEntityInput("Bombs.TheHindenburg", "Enable", "", 0.0); + FireEntityInput("Boom", "Disable", "", 1.0); + } + //HINDENBOOM!!! + case 29: { + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}OH GOD, THEY'RE {red}CRASHING THE HINDENBURG{white}!!!"); + EmitSoundToAll(HINDENCRASH); + CreateTimer(4.0, TimedOperator, 21); + CreateTimer(7.0, TimedOperator, 37); + FireEntityInput("LargeExplosion", "Explode", "", 7.0); + FireEntityInput("LargeExploShake", "StartShake", "", 7.0); + FireEntityInput("NukeAll", "Enable", "", 7.0); + FireEntityInput("FB.Fade", "Fade", "", 7.0); + FireEntityInput("NukeAll", "Disable", "", 9.0); + FireEntityInput("Bombs.TheHindenburg", "Disable", "", 7.0); + FireEntityInput("HindenTrain", "TeleportToPathTrack", "Hinden01", 7.0); + FireEntityInput("HindenTrain", "Stop", "", 7.0); + CreateTimer(8.0, TimedOperator, 99); + bombStatus = 4; + bombStatusMax = 8; + explodeType = 0; + } + //Bath Salts spend + case 30: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}INSTANT BATH SALT DETONATION! BOTS ARE FROZEN FOR 10 SECONDS! ({red}-10 pts{white})"); + ServerCommand("sm_freeze @blue 10"); + sacPoints -= 10; + FireEntityInput("BTN.Sacrificial*", "Color", "0 0 0", 0.0), + FireEntityInput("BTN.Sacrificial01", "Lock", "", 0.0), + FireEntityInput("MedExploShake", "StartShake", "", 0.10), + FireEntityInput("MedExplosionSND", "PlaySound", "", 0.10), + FireEntityInput("MediumExplosion", "Explode", "", 0.10); + } + //Fat man spend + case 31: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}INSTANT FAT MAN DETONATION! ({red}-20 pts{white})"); + sacPoints -= 20; + FireEntityInput("BTN.Sacrificial*", "Color", "0 0 0", 0.0); + FireEntityInput("BTN.Sacrificial02", "Lock", "", 0.0); + FireEntityInput("LargeExplosion", "Explode", "", 0.0); + FireEntityInput("LargeExploShake", "StartShake", "", 0.0); + FireEntityInput("NukeAll", "Enable", "", 0.0); + EmitSoundToAll(HINDENBURGBOOM); + FireEntityInput("FB.Fade", "Fade", "", 0.0); + FireEntityInput("NukeAll", "Disable", "", 2.0); + } + //Goob/Kirb spend + case 32: { + int i = GetRandomInt(1, 2); + switch (i) { + case 1: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}GOOBBUE COMING IN FROM ORBIT! ({red}-30 pts{white})"); + sacPoints -= 30; + CustomSoundEmitter(SPEC01, SFXSNDLVL, false, 0, 1.0, 100); + CreateTimer(1.5, TimedOperator, 21); + FireEntityInput("FB.GiantGoobTemplate", "ForceSpawn", "", 3.0); + } + case 2: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}BLUE KIRBY FALLING OUT OF THE SKY! ({red}-30 pts{white})"); + sacPoints -= 30; + FireEntityInput("FB.BlueKirbTemplate", "ForceSpawn", "", 0.0); + CustomSoundEmitter(FALLSND0B, SFXSNDLVL, false, 0, 1.0, 100); + } + } + } + //Explosive paradise spend + case 33: { + CustomSoundEmitter(EXPLOSIVEPARADISE, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("FB.FadeBLCK", "Fade", "", 0.0); + ServerCommand("sm_evilrocket @blue"); + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}We're spending most our lives living in an EXPLOSIVE PARADISE! Robots will be launched into orbit, too! ({red}-40 pts{white})"); + FireEntityInput("NukeAll", "Enable", "", 11.50); + FireEntityInput("HUGEExplosion", "Explode", "", 11.50); + FireEntityInput("FB.Fade", "Fade", "", 11.50); + FireEntityInput("FB.ShakeBOOM", "StartShake", "", 11.50); + FireEntityInput("NukeAll", "Disable", "", 12.30); + sacPoints -= 40; + } + //Ass Gas spend + case 34: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}ANYTHING BUT THE ASS GAS!!!! ({red}-40 pts{white})"); + sacPoints -= 40; + FireEntityInput("HurtAll", "AddOutput", "damagetype 524288", 0.0); + FireEntityInput("FB.ShakeBOOM", "StartShake", "", 0.1); + FireEntityInput("HurtAll", "Enable", "", 0.1); + FireEntityInput("HurtAll", "Disable", "", 4.1); //Add a sound to this in the future. Maybe gas sound from gbombs? Maybe custom fart sounds? hmm.... + FireEntityInput("FB.ShakeBOOM", "StopShake", "", 4.1); + } + //Banish tornadoes for the wave + case 35: { + if (canTornado || tornado) { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}A PINK KIRBY HAS BANISHED TORNADOES FOR THIS WAVE! ({red}-50 pts{white})"); + ServerCommand("fb_operator 1005"); + canTornado = false; + sacPoints -= 50; + } else { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}A PINK KIRBY HAS BANISHED TORNADOES.... BUT CANTORNADO and TORNADO WERE BOTH FALSE... CALL A PROGRAMMER. ({red} -0 pts{white})"); + ServerCommand("fb_operator 1005"); + canTornado = false; + } + } + //Nuclear fallout spend + case 36: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}TOTAL ATOMIC ANNIHILATION. ({red}-60 pts{white})"); + sacPoints -= 60; + canSENTNukes = true; + CreateTimer(1.0, SENTNukeTimer); + CreateTimer(45.0, TimedOperator, 13); + } + //Meteor shower spend + case 37: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}COSMIC DEVASTATION IMMINENT. ({red}-70 pts{white})"); + sacPoints -= 70; + canSENTMeteors = true; + CreateTimer(1.0, SENTMeteorTimer); + CreateTimer(30.0, TimedOperator, 12); + } + //150K UbUp Cash + case 38: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}150K UbUp Cash Granted to {red}RED{white}! ({red}-75 pts{white})"); + sacPoints -= 75; + ServerCommand("sm_addcash @red 150000"); + } + //Fartsy of the Seventh Taco Bell + case 39: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}NOW PRESENTING... PROFESSOR FARTSALOT OF THE SEVENTH TACO BELL! ({red}-100 points{white})"); + sacPoints -= 100; + explodeType = 69; + FireEntityInput("Delivery", "Unlock", "", 0.0), + FireEntityInput("BombExplo*", "Disable", "", 0.0), + FireEntityInput("Bombs*", "Disable", "", 0.0), + FireEntityInput("Bombs.Professor", "Enable", "", 3.0); + } + //Found blue ball + case 40: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}What on earth IS that? It appears to be a... \x075050FFBLUE BALL{white}!"); + CustomSoundEmitter(FALLSND0B, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("FB.BlueKirbTemplate", "ForceSpawn", "", 4.0); + CreateTimer(4.0, TimedOperator, 21); + } + //Found burrito + case 41: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Why would you even eat {red}The Forbidden Burrito{white}?"); + CustomSoundEmitter("vo/sandwicheat09.mp3", SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("HurtAll", "AddOutput", "damagetype 8", 0.0); + FireEntityInput("HurtAll", "Enable", "", 4.0); + FireEntityInput("HurtAll", "Disable", "", 8.0); + } + //Found goobbue + case 42: { + CustomSoundEmitter(SPEC01, SFXSNDLVL, false, 0, 1.0, 100); + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}ALL HAIL \x07FF00FFGOOBBUE{forestgreen}!"); + CreateTimer(4.0, TimedOperator, 21); + FireEntityInput("FB.GiantGoobTemplate", "ForceSpawn", "", 4.0); + } + //Found Mario + case 43: { + CustomSoundEmitter(SPEC02, SFXSNDLVL, false, 0, 1.0, 100); + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Welp, someone is playing \x0700FF00Mario{white}..."); + } + //Found Waffle + case 44: { + CustomSoundEmitter(SPEC03, SFXSNDLVL, false, 0, 1.0, 100); + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Oh no, someone has found and (probably) consumed a {red}WAFFLE OF MASS DESTRUCTION{white}!"); + FireEntityInput("HurtAll", "AddOutput", "damagetype 262144", 10.0); + FireEntityInput("FB.ShakeBOOM", "StartShake", "", 10.3); + FireEntityInput("HUGEExplosion", "Explode", "", 10.3); + FireEntityInput("FB.Fade", "Fade", "", 10.3); + FireEntityInput("HurtAll", "Enable", "", 10.3); + FireEntityInput("HurtAll", "Disable", "", 12.3); + } + //Medium Explosion (defined again, but we aren't using a bomb this time) + case 51: { + CustomSoundEmitter(BMB3SND, SFXSNDLVL, false, 0, 1.0, 100); + } + //Probably for the hindenburg... EDIT: NOPE. THIS IS FOR KIRB LANDING ON THE GROUND + case 52: { + EmitSoundToAll(HINDENBURGBOOM); + FireEntityInput("FB.BOOM", "StartShake", "", 0.0); + FireEntityInput("BlueBall*", "Kill", "", 0.0); + FireEntityInput("HUGEExplosion", "Explode", "", 0.0); + FireEntityInput("BlueKirb", "Kill", "", 0.0); + FireEntityInput("HurtAll", "AddOutput", "damagetype 32768", 0.0); + FireEntityInput("HurtAll", "Enable", "", 0.1); + FireEntityInput("HurtAll", "Disable", "", 2.1); + } + //Giant Goobbue + case 53: { + EmitSoundToAll(HINDENBURGBOOM); + FireEntityInput("FB.BOOM", "StartShake", "", 0.0); + FireEntityInput("GiantGoob*", "Kill", "", 0.0); + FireEntityInput("HUGEExplosion", "Explode", "", 0.0); + FireEntityInput("HurtAll", "AddOutput", "damagetype 1048576", 0.0); + FireEntityInput("HurtAll", "Enable", "", 0.1); + FireEntityInput("HurtAll", "Disable", "", 2.1); + } + //Prev wave + case 98: { + int ent = FindEntityByClassname(-1, "tf_objective_resource"); + if (ent == -1) { + LogMessage("tf_objective_resource not found"); + return Plugin_Handled; + } + + int current_wave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineWaveCount")); + int max_wave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineMaxWaveCount")); + int prev_wave = current_wave - 1; + if (prev_wave >= max_wave) { + CPrintToChatAll("{red}[ERROR] {white}HOW THE HELL DID WE GET HERE?!"); + return Plugin_Handled; + } + + if (prev_wave < 1) { + CPrintToChatAll("{red}[ERROR] {white}WE CAN'T JUMP TO WAVE 0, WHY WOULD YOU TRY THAT??"); + return Plugin_Handled; + } + JumpToWave(prev_wave); + } + //Next wave + case 99: { + int ent = FindEntityByClassname(-1, "tf_objective_resource"); + if (ent == -1) { + LogMessage("tf_objective_resource not found"); + return Plugin_Handled; + } + + int current_wave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineWaveCount")); + int max_wave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineMaxWaveCount")); + int next_wave = current_wave + 1; + if (next_wave > max_wave) { + int flags = GetCommandFlags("tf_mvm_force_victory"); + SetCommandFlags("tf_mvm_force_victory", flags & ~FCVAR_CHEAT); + ServerCommand("tf_mvm_force_victory 1"); + FakeClientCommand(0, ""); //Not sure why, but this has to be here. Otherwise the specified commands simply refuse to work... + SetCommandFlags("tf_mvm_force_victory", flags | FCVAR_CHEAT); + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}VICTORY HAS BEEN FORCED! THE SERVER WILL RESTART IN 10 SECONDS."); + CreateTimer(10.0, TimedOperator, 100); + return Plugin_Handled; + } + JumpToWave(next_wave); + } + //Code Entry from FC Keypad + case 100: { + if (CodeEntry == 17) { + FireEntityInput("FB.BOOM", "StartShake", "", 0.0), + CustomSoundEmitter(BMB3SND, SFXSNDLVL, false, 0, 1.0, 100), + FireEntityInput("FB.CodeCorrectKill", "Enable", "", 0.0), + FireEntityInput("FB.KP*", "Lock", "", 0.0), + FireEntityInput("FB.CodeCorrectKill", "Disable", "", 1.0); + } else { + CodeEntry = 0; + FireEntityInput("FB.CodeFailedKill", "Enable", "", 0.0), + FireEntityInput("FB.CodeFailedKill", "Disable", "", 1.0), + CustomSoundEmitter("fartsy/memes/priceisright_fail.wav", SFXSNDLVL, false, 0, 1.0, 100); + } + } + case 101: { + CodeEntry++; + } + case 102: { + CodeEntry += 2; + } + case 103: { + CodeEntry += 3; + } + case 104: { + CodeEntry += 4; + } + case 105: { + CodeEntry += 5; + } + case 106: { + CodeEntry += 6; + } + case 107: { + CodeEntry += 7; + } + case 108: { + CodeEntry += 8; + } + case 109: { + CodeEntry += 9; + } + //Taco Bell Edition + case 210: { + tacobell = true; + ServerCommand("fb_startmoney 200000"); + CPrintToChatAll("{darkviolet}[{orange}INFO{darkviolet}] {white}You have chosen {red}DOVAH'S ASS - TACO BELL EDITION{white}. Why... Why would you DO THIS?! Do you not realize what you've just done?????"); + } + //TEMP FUNCTIONS + case 301:{ + EmitSoundToAll(BGM1, _, SNDCHAN, BGMSNDLVL, SND_CHANGEVOL, 0.05, _, _, _, _, _, _); + } + //TEMP FUNCTIONS + case 302:{ + EmitSoundToAll(BGM1, _, SNDCHAN, BGMSNDLVL, SND_CHANGEVOL, 1.0, _, _, _, _, _, _); + } + case 304:{ + EmitSoundToAll(BGM2, _, SNDCHAN, BGMSNDLVL, SND_CHANGEVOL, 0.05, _, _, _, _, _, _); + } + case 305:{ + EmitSoundToAll(BGM2, _, SNDCHAN, BGMSNDLVL, SND_CHANGEVOL, 1.0, _, _, _, _, _, _); + } + case 400:{ + isWave = true; + CustomSoundEmitter(BGM4, BGMSNDLVL-50, true, 1, 0.8, 100); + curSong = BGM4; + songName = BGM4Title; + CreateTimer(73.9, TimedOperator, 1000); + FireEntityInput("FB.MusicTimer", "RefireTime", "122.05", 0.0), + FireEntityInput("FB.MusicTimer", "Enable", "", 0.1), + FireEntityInput("FB.MusicTimer", "ResetTimer", "", 0.1); + } + //LOOP SYSTEM + case 500:{ + PrintToConsoleAll("[CORE] Phase Change started... phase 2!"); + loopingFlags = 1; + } + case 501:{ + PrintToConsoleAll("[CORE] Phase Change started... phase 3!"); + loopingFlags = 2; + } + case 502:{ + tickMusic = true; + } + // Select BGM //Music system rewrite (again) AGAINNNNNNNNNNNN.... + case 1000: { + PrintToChatAll("%i", BGMINDEX); + if(stopPrevSong == true && !StrEqual(prevSong, "null")){ + for (int i = 1; i <= MaxClients; i++) { + PrintToChatAll("STOPPED %s", prevSong); + StopSound(i, SNDCHAN, prevSong); + //CustomSoundEmitter(prevSong, DEFBGMSNDLVL - 10, true, 1, 0.05, 100); + stopPrevSong = false; + } + } + CreateTimer(1.0, UpdateMusic); + canMusicLoop = false; + switch (BGMINDEX) { + case 0, 1, 12: { + int BGM = GetRandomInt(1, 3); + switch (BGM) { + case 1: { + BGMINDEX = 0; + CustomSoundEmitter(DEFAULTBGM1, DEFBGMSNDLVL - 10, true, 0, 1.0, 100); + curSong = DEFAULTBGM1; + songName = DEFAULTBGM1Title; + FireEntityInput("FB.MusicTimer", "RefireTime", "137.55", 0.0), + FireEntityInput("FB.MusicTimer", "Enable", "", 0.1), + FireEntityInput("FB.MusicTimer", "ResetTimer", "", 0.1); + } + case 2: { + BGMINDEX = 1; + CustomSoundEmitter(DEFAULTBGM2, DEFBGMSNDLVL - 10, true, 0, 1.0, 100); + curSong = DEFAULTBGM2; + songName = DEFAULTBGM2Title; + FireEntityInput("FB.MusicTimer", "RefireTime", "235.3", 0.0), + FireEntityInput("FB.MusicTimer", "Enable", "", 0.1), + FireEntityInput("FB.MusicTimer", "ResetTimer", "", 0.1); + } + case 3: { + BGMINDEX = 12; + CustomSoundEmitter(DEFAULTBGM3, DEFBGMSNDLVL - 10, true, 0, 1.0, 100); + curSong = DEFAULTBGM3; + songName = DEFAULTBGM3Title; + FireEntityInput("FB.MusicTimer", "RefireTime", "137.7", 0.0), + FireEntityInput("FB.MusicTimer", "Enable", "", 0.1), + FireEntityInput("FB.MusicTimer", "ResetTimer", "", 0.1); + } + } + } + //BGM1 + case 2: { + CustomSoundEmitter(BGM1, BGMSNDLVL, true, 0, 1.0, 100); + curSong = BGM1; + songName = BGM1Title; + FireEntityInput("FB.MusicTimer", "RefireTime", "229.05", 0.0), + FireEntityInput("FB.MusicTimer", "Enable", "", 0.1), + FireEntityInput("FB.MusicTimer", "ResetTimer", "", 0.1); + } + //BGM2 + case 3: { + CustomSoundEmitter(BGM2, BGMSNDLVL, true, 0, 1.0, 100); + curSong = BGM2; + songName = BGM2Title; + FireEntityInput("FB.MusicTimer", "RefireTime", "153.75", 0.0), + FireEntityInput("FB.MusicTimer", "Enable", "", 0.1), + FireEntityInput("FB.MusicTimer", "ResetTimer", "", 0.1); + } + //BGM3 + case 4: { + CustomSoundEmitter(BGM3, BGMSNDLVL, true, 0, 1.0, 100); + curSong = BGM3; + songName = BGM3Title; + FireEntityInput("FB.MusicTimer", "RefireTime", "166.65", 0.0), + FireEntityInput("FB.MusicTimer", "Enable", "", 0.1), + FireEntityInput("FB.MusicTimer", "ResetTimer", "", 0.1); + } + //BGM4 + case 5: { + CustomSoundEmitter(BGM4, BGMSNDLVL-50, true, 1, 0.8, 100); + curSong = BGM4; + songName = BGM4Title; + CreateTimer(74.0, TimedOperator, 1000); + FireEntityInput("FB.MusicTimer", "RefireTime", "122.05", 0.0), + FireEntityInput("FB.MusicTimer", "Enable", "", 0.1), + FireEntityInput("FB.MusicTimer", "ResetTimer", "", 0.1); + } + //BGM5 + case 6: { + CustomSoundEmitter(BGM5, BGMSNDLVL - 5, true, 0, 1.0, 100); + curSong = BGM5; + songName = BGM5Title; + FireEntityInput("FB.MusicTimer", "RefireTime", "131.55", 0.0), + FireEntityInput("FB.MusicTimer", "Enable", "", 0.1), + FireEntityInput("FB.MusicTimer", "ResetTimer", "", 0.1); + } + //BGM6 + case 7: { + CustomSoundEmitter(BGM6, BGMSNDLVL, true, 0, 1.0, 100); + curSong = BGM6; + songName = BGM6Title; + FireEntityInput("FB.MusicTimer", "RefireTime", "427.15", 0.0), + FireEntityInput("FB.MusicTimer", "Enable", "", 0.1), + FireEntityInput("FB.MusicTimer", "ResetTimer", "", 0.1); + } + //BGM7 + case 8: { + CustomSoundEmitter(BGM7, BGMSNDLVL, true, 0, 1.0, 100); + curSong = BGM7; + songName = BGM7Title; + FireEntityInput("FB.MusicTimer", "RefireTime", "133.05", 0.0), + FireEntityInput("FB.MusicTimer", "Enable", "", 0.1), + FireEntityInput("FB.MusicTimer", "ResetTimer", "", 0.1); + } + //BGM8 + case 9: { + CustomSoundEmitter(BGM8, BGMSNDLVL + 30, true, 0, 1.0, 100); + curSong = BGM8; + songName = BGM8Title; + FireEntityInput("FB.MusicTimer", "RefireTime", "215.0", 0.0), + FireEntityInput("FB.MusicTimer", "Enable", "", 0.1), + FireEntityInput("FB.MusicTimer", "ResetTimer", "", 0.1); + } + //BGM9 + case 10: { + if (tbLoop == 0) { + curSong = BGM9Intro; + //stopPrevSong = false; + songName = BGM9Title; + tbLoop = 1; + CustomSoundEmitter(BGM9Intro, BGMSNDLVL, true, 1, 1.0, 100); + FireEntityInput("FB.MusicTimer", "Disable", "", 0.0); + FireEntityInput("FB.MusicTimer", "RefireTime", "11.81", 0.0); + FireEntityInput("FB.MusicTimer", "ResetTimer", "", 0.01); + FireEntityInput("FB.MusicTimer", "Enable", "", 0.01); + } else { + CustomSoundEmitter(BGM9, BGMSNDLVL, true, 0, 1.0, 100); + curSong = BGM9; + songName = BGM9Title; + FireEntityInput("FB.MusicTimer", "Disable", "", 0.0); + FireEntityInput("FB.MusicTimer", "RefireTime", "111.5", 0.0); + FireEntityInput("FB.MusicTimer", "Enable", "", 0.01); + FireEntityInput("FB.MusicTimer", "ResetTimer", "", 0.01); + } + } + //BGM10 + case 11: { + CustomSoundEmitter(BGM10, BGMSNDLVL + 10, true, 0, 1.0, 100); + curSong = BGM10; + songName = BGM10Title; + FireEntityInput("FB.MusicTimer", "RefireTime", "310.8", 0.0), + FireEntityInput("FB.MusicTimer", "Enable", "", 0.1), + FireEntityInput("FB.MusicTimer", "ResetTimer", "", 0.1); + } + //BGM11 + case 13:{ + CustomSoundEmitter(BGM11, BGMSNDLVL + 10, true, 0, 1.0, 100); + curSong = BGM11; + songName = BGM11Title; + FireEntityInput("FB.MusicTimer", "RefireTime", "128.8", 0.0), + FireEntityInput("FB.MusicTimer", "Enable", "", 0.1), + FireEntityInput("FB.MusicTimer", "ResetTimer", "", 0.1); + } + //BGM12 + case 14:{ + CustomSoundEmitter(BGM12, BGMSNDLVL + 10, true, 0, 1.0, 100); + curSong = BGM12; + songName = BGM12Title; + FireEntityInput("FB.MusicTimer", "RefireTime", "268.1", 0.0), + FireEntityInput("FB.MusicTimer", "Enable", "", 0.1), + FireEntityInput("FB.MusicTimer", "ResetTimer", "", 0.1); + } + //Custom BGM + case 20:{ + PrintToChatAll("ERR: No music has been registered here yet!"); + } + //Phases + case 100:{ + curSong = BGM100; + songName = BGM100Title; + CustomSoundEmitter(BGM4, BGMSNDLVL-10, true, 1, 0.01, 100); + CustomSoundEmitter(BGM100, BGMSNDLVL-10, true, 1, 1.0, 100); + FireEntityInput("FB.MusicTimer", "Disable", "", 0.0); + FireEntityInput("FB.MusicTimer", "RefireTime", "149.6", 0.1); + FireEntityInput("FB.MusicTimer", "ResetTimer", "", 0.2); + FireEntityInput("FB.MusicTimer", "Enable", "", 0.3); + } + case 101:{ + curSong = BGM101; + songName = BGM101Title; + CustomSoundEmitter(BGM4, BGMSNDLVL-10, true, 1, 0.01, 100); + CustomSoundEmitter(BGM100, BGMSNDLVL-10, true, 1, 0.001, 100); + CustomSoundEmitter(BGM101, BGMSNDLVL-10, true, 1, 1.0, 100); + FireEntityInput("FB.MusicTimer", "Disable", "", 0.0); + FireEntityInput("FB.MusicTimer", "RefireTime", "79.3", 0.1); + FireEntityInput("FB.MusicTimer", "ResetTimer", "", 0.2); + FireEntityInput("FB.MusicTimer", "Enable", "", 0.3); + } + } + } + //Stop current song + case 1001: { + if (StrEqual(curSong, "null")) { + return Plugin_Handled; + } + for (int i = 1; i <= MaxClients; i++) { + StopSound(i, SNDCHAN, curSong); + } + return Plugin_Handled; + } + //Feature an admin + case 1002: { + FireEntityInput("AdminPicker", "SetTextureIndex", "10", 0.0); + int i = GetRandomInt(1, 9); + switch (i) { + case 1: { + if (i == lastAdmin) { + ServerCommand("fb_operator 1002"); + } else { + FireEntityInput("AdminPicker", "SetTextureIndex", "1", 0.1); + lastAdmin = 1; + } + } + case 2: { + if (i == lastAdmin) { + ServerCommand("fb_operator 1002"); + } else { + FireEntityInput("AdminPicker", "SetTextureIndex", "2", 0.1); + lastAdmin = 2; + } + } + case 3: { + if (i == lastAdmin) { + ServerCommand("fb_operator 1002"); + } else { + FireEntityInput("AdminPicker", "SetTextureIndex", "3", 0.1); + lastAdmin = 3; + } + } + case 4: { + if (i == lastAdmin) { + ServerCommand("fb_operator 1002"); + } else { + FireEntityInput("AdminPicker", "SetTextureIndex", "4", 0.1); + lastAdmin = 4; + } + } + case 5: { + if (i == lastAdmin) { + ServerCommand("fb_operator 1002"); + } else { + FireEntityInput("AdminPicker", "SetTextureIndex", "5", 0.1); + lastAdmin = 5; + } + } + case 6: { + if (i == lastAdmin) { + ServerCommand("fb_operator 1002"); + } else { + FireEntityInput("AdminPicker", "SetTextureIndex", "6", 0.1); + lastAdmin = 6; + } + } + case 7: { + if (i == lastAdmin) { + ServerCommand("fb_operator 1002"); + } else { + FireEntityInput("AdminPicker", "SetTextureIndex", "7", 0.1); + lastAdmin = 7; + } + } + case 8: { + if (i == lastAdmin) { + ServerCommand("fb_operator 1002"); + } else { + FireEntityInput("AdminPicker", "SetTextureIndex", "8", 0.1); + lastAdmin = 8; + } + } + case 9: { + if (i == lastAdmin) { + ServerCommand("fb_operator 1002"); + } else { + FireEntityInput("AdminPicker", "SetTextureIndex", "9", 0.1); + lastAdmin = 9; + } + } + case 10: { + if (i == lastAdmin) { + ServerCommand("fb_operator 1002"); + } else { + FireEntityInput("AdminPicker", "SetTextureIndex", "10", 0.1); + } + } + } + return Plugin_Handled; + } + //Strike Lightning + case 1003: { + FireEntityInput("lightning", "TurnOn", "", 0.0), + FireEntityInput("weather", "Skin", "4", 0.0), + FireEntityInput("value", "TurnOff", "", 0.0), + FireEntityInput("LightningLaser", "TurnOn", "", 0.0), + FireEntityInput("lightning", "TurnOff", "", 0.1), + FireEntityInput("weather", "Skin", "3", 0.1), + FireEntityInput("LightningLaser", "TurnOff", "", 0.1), + FireEntityInput("lightning", "TurnOn", "", 0.17), + FireEntityInput("weather", "Skin", "4", 0.17), + FireEntityInput("LightningLaser", "TurnOn", "", 0.17), + FireEntityInput("lightning", "TurnOff", "", 0.25), + FireEntityInput("weather", "Skin", "3", 0.25), + FireEntityInput("LightningLaser", "TurnOff", "", 0.25); + } + //Activate Tornado Timer + case 1004: { + if (isWave && canTornado) { + if (curWave == 4) { + float f = GetRandomFloat(30.0, 60.0); + float t = f - 30.0; + CreateTimer(t, TimedOperator, 40); + CreateTimer(f, TimedOperator, 41); + } else { + float f = GetRandomFloat(210.0, 500.0); + float t = f - 30.0; + CreateTimer(t, TimedOperator, 40); + CreateTimer(f, TimedOperator, 41); + } + } + } + //Despawn the tornado + case 1005: { + FireEntityInput("tornadof1", "stop", "", 0.0), + FireEntityInput("TornadoKill", "Disable", "", 0.0), + FireEntityInput("tornadof1wind", "Disable", "", 0.0), + FireEntityInput("tornadowindf1", "StopSound", "", 0.0), + FireEntityInput("shaketriggerf1", "Disable", "", 0.0), + FireEntityInput("tornadobutton", "Unlock", "", 30.0); + FireEntityInput("FB.FakeTankTank01", "Kill", "", 0.0); + FireEntityInput("FB.FakeTankPhys01", "Kill", "", 0.0); + tornado = false; + return Plugin_Handled; + } + //Crusader + case 1006: { + ServerCommand("fb_operator 1001"), + FireEntityInput("FB.MusicTimer", "Disable", "", 0.0); + crusader = true, + CreateTimer(25.20, TimedOperator, 78), + CreateTimer(63.20, TimedOperator, 80), + PrintToServer("Starting Crusader via plugin!"), + EmitSoundToAll("fartsy/misc/fartsyscrusader_bgm_locus.mp3"), + CreateTimer(1.75, CRUSADERINCOMING), + FireEntityInput("FB.BOOM", "StopShake", "", 3.0), + FireEntityInput("FB.CRUSADER", "Enable", "", 25.20), + FireEntityInput("CrusaderTrain", "StartForward", "", 25.20), + FireEntityInput("CrusaderLaserBase*", "StartForward", "", 25.20), + CreateTimer(25.20, TimedOperator, 9), + FireEntityInput("CrusaderTrain", "SetSpeed", "0.9", 38.0), + FireEntityInput("CrusaderTrain", "SetSpeed", "0.7", 38.60), + FireEntityInput("CrusaderTrain", "SetSpeed", "0.5", 39.20), + FireEntityInput("CrusaderTrain", "SetSpeed", "0.3", 40.40), + FireEntityInput("CrusaderTrain", "SetSpeed", "0.1", 41.40), + FireEntityInput("CrusaderTrain", "Stop", "", 42.60), + FireEntityInput("FB.CrusaderLaserKill01", "Disable", "", 42.60), + CreateTimer(42.60, TimedOperator, 10), + FireEntityInput("FB.LaserCore", "TurnOn", "", 45.80), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "0.35", 45.80), + FireEntityInput("FB.ShakeCore", "StartShake", "", 45.80), + FireEntityInput("CrusaderSprite", "Color", "255 128 128", 45.80), + FireEntityInput("FB.ShakeCore", "StopShake", "", 48.80), + FireEntityInput("FB.LaserInnerMost", "TurnOn", "", 49.20), + FireEntityInput("FB.ShakeInner", "StartShake", "", 49.20), + FireEntityInput("CrusaderSprite", "Color", "255 230 230", 49.20), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "0.35", 50.20), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "0.45", 50.60), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "0.55", 51.0), + FireEntityInput("FB.ShakeInner", "StopShake", "", 52.10), + FireEntityInput("FB.ShakeInner", "StartShake", "", 52.20), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "0.45", 54.0), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "0.4", 54.40), + FireEntityInput("FB.ShakeInner", "StopShake", "", 55.0), + FireEntityInput("FB.ShakeInner", "StartShake", "", 55.10), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "0.75", 57.20), + FireEntityInput("FB.CrusaderSideLaser", "TurnOn", "", 57.20), + FireEntityInput("FB.ShakeInner", "StopShake", "", 58.0), + FireEntityInput("FB.ShakeInner", "StartShake", "", 58.10), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "1", 58.50), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "0.75", 60.80), + FireEntityInput("CrusaderLaserBase", "SetSpeed", "0.65", 61.10), + FireEntityInput("CrusaderLaserBase", "SetSpeed", "0.55", 61.40), + FireEntityInput("FB.LaserCore", "TurnOff", "", 61.40), + FireEntityInput("FB.LaserInnerMost", "TurnOff", "", 61.40), + FireEntityInput("CrusaderSprite", "Color", "0 0 0", 61.40), + FireEntityInput("CrusaderLaserBase", "SetSpeed", "0.45", 61.70), + FireEntityInput("CrusaderLaserBase", "SetSpeed", "0.3", 62.0), + FireEntityInput("CrusaderLaserBase", "SetSpeed", "0.15", 62.30), + FireEntityInput("FB.CrusaderSideLaser", "TurnOff", "", 62.30), + FireEntityInput("CrusaderLaserBase*", "Stop", "", 62.70), + FireEntityInput("FB.Laser*", "TurnOn", "", 65.20), + FireEntityInput("CrusaderLaserBase*", "StartForward", "", 65.20), + FireEntityInput("CrusaderLaserBase", "SetSpeed", "1", 65.20), + FireEntityInput("FB.ShakeBOOM", "StartShake", "", 65.20), + FireEntityInput("FB.Fade", "Fade", "", 65.20), + FireEntityInput("HurtAll", "AddOutput", "damagetype 1024", 65.10), + FireEntityInput("HurtAll", "Enable", "", 65.20), + FireEntityInput("FB.CrusaderSideLaser", "TurnOn", "", 65.20), + FireEntityInput("CrusaderSprite", "Color", "255 230 255", 65.20), + FireEntityInput("FB.Laser*", "TurnOff", "", 70.0), + FireEntityInput("CrusaderTrain", "StartForward", "", 70.0), + FireEntityInput("CrusaderLaserBase*", "Stop", "", 70.0), + FireEntityInput("HurtAll", "Disable", "", 70.0), + FireEntityInput("FB.CrusaderSideLaser", "TurnOff", "", 70.0), + FireEntityInput("CrusaderSprite", "Color", "0 0 0", 70.0), + FireEntityInput("FB.ShakeBOOM", "StopShake", "", 70.20), + FireEntityInput("CrusaderTrain", "Stop", "", 80.0), + FireEntityInput("FB.CRUSADER", "Disable", "", 80.0); + CreateTimer(80.0, TimedOperator, 79); + } + //Choose bomb path + case 1007: { + FireEntityInput("Nest_EN060", "Disable", "", 0.0), + FireEntityInput("Nest_EN050", "Disable", "", 0.0), + FireEntityInput("Nest_EN040", "Disable", "", 0.0), + FireEntityInput("Nest_EN030", "Disable", "", 0.0), + FireEntityInput("Nest_EN020", "Disable", "", 0.0), + FireEntityInput("Nest_EN010", "Disable", "", 0.0), + FireEntityInput("Nest_L050", "Disable", "", 0.0), + FireEntityInput("Nest_L040", "Disable", "", 0.0), + FireEntityInput("Nest_L030", "Disable", "", 0.0), + FireEntityInput("Nest_L020", "Disable", "", 0.0), + FireEntityInput("Nest_L010", "Disable", "", 0.0), + FireEntityInput("Nest_R040", "Disable", "", 0.0), + FireEntityInput("Nest_R030", "Disable", "", 0.0), + FireEntityInput("Nest_R020", "Disable", "", 0.0), + FireEntityInput("Nest_R010", "Disable", "", 0.0), + FireEntityInput("bombpath_right_prefer_flankers", "Disable", "", 0.0), + FireEntityInput("bombpath_left_prefer_flankers", "Disable", "", 0.0), + FireEntityInput("bombpath_left_navavoid", "Disable", "", 0.0), + FireEntityInput("bombpath_right_navavoid", "Disable", "", 0.0), + FireEntityInput("bombpath_right_arrows", "Disable", "", 0.0), + FireEntityInput("bombpath_left_arrows", "Disable", "", 0.0); + int i = GetRandomInt(1, 3); + switch (i) { + case 1: { + FireEntityInput("Nest_R040", "Enable", "", 0.25), + FireEntityInput("Nest_R030", "Enable", "", 0.25), + FireEntityInput("Nest_R020", "Enable", "", 0.25), + FireEntityInput("Nest_R010", "Enable", "", 0.25), + FireEntityInput("bombpath_right_prefer_flankers", "Enable", "", 0.25), + FireEntityInput("bombpath_right_navavoid", "Enable", "", 0.25), + FireEntityInput("bombpath_right_arrows", "Enable", "", 0.25); + } + case 2: { + FireEntityInput("Nest_L050", "Enable", "", 0.25), + FireEntityInput("Nest_L040", "Enable", "", 0.25), + FireEntityInput("Nest_L030", "Enable", "", 0.25), + FireEntityInput("Nest_L020", "Enable", "", 0.25), + FireEntityInput("Nest_L010", "Enable", "", 0.25), + FireEntityInput("bombpath_left_prefer_flankers", "Enable", "", 0.25), + FireEntityInput("bombpath_left_navavoid", "Enable", "", 0.25), + FireEntityInput("bombpath_left_arrows", "Enable", "", 0.25); + } + case 3: { + FireEntityInput("dovahsassprefer", "Enable", "", 0.25), + FireEntityInput("Nest_R040", "Enable", "", 0.25), + FireEntityInput("Nest_R030", "Enable", "", 0.25), + FireEntityInput("Nest_R020", "Enable", "", 0.25), + FireEntityInput("Nest_R010", "Enable", "", 0.25), + FireEntityInput("bombpath_right_prefer_flankers", "Enable", "", 0.25), + FireEntityInput("bombpath_right_navavoid", "Enable", "", 0.25), + FireEntityInput("bombpath_right_arrows", "Enable", "", 0.25); + } + } + } + //Monitor power up/down! + case 1008:{ + if(!monitorOn){ + monitorOn = true; + if(!monitorColor){ + FireEntityInput("FB.MonitorSprite", "Color", "0 0 255", 0.0); + FireEntityInput("FB.MonitorBlank", "Disable", "", 0.0); + FireEntityInput("FB.MonitorBW", "Enable", "", 0.0); + } + else{ + FireEntityInput("FB.MonitorSprite", "Color", "0 255 0", 0.0); + FireEntityInput("FB.MonitorBlank", "Disable", "", 0.0); + FireEntityInput("FB.Monitor", "Enable", "", 0.0); + } + } + else{ + monitorOn = false; + FireEntityInput("FB.MonitorSprite", "Color", "255 0 0", 0.0); + FireEntityInput("FB.Monitor", "Disable", "", 0.0); + FireEntityInput("FB.MonitorBW", "Disable", "", 0.0); + FireEntityInput("FB.MonitorBlank", "Enable", "", 0.0); + } + } + //Cycle monitor forward + case 1009:{ + camSel++; + switch(camSel){ + case 0:{ + FireEntityInput("FB.Monitor", "SetCamera", "CAM.Front", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.Front", 0.0); + } + case 1:{ + FireEntityInput("FB.Monitor", "SetCamera", "CAM.Mid", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.Mid", 0.0); + } + case 2:{ + FireEntityInput("FB.Monitor", "SetCamera", "CAM.MidTwo", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.MidTwo", 0.0); + } + case 3:{ + FireEntityInput("FB.Monitor", "SetCamera", "CAM.Rear", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.Rear", 0.0); + } + case 4:{ + FireEntityInput("FB.Monitor", "SetCamera", "CAM.Kissone", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.Kissone", 0.0); + } + case 5:{ + FireEntityInput("FB.Monitor", "SetCamera", "CAM.Front", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.Front", 0.0); + camSel = 0; + } + } + } + //Cycle monitor back + case 1010:{ + camSel--; + switch(camSel){ + case -1:{ + FireEntityInput("FB.Monitor", "SetCamera", "CAM.Front", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.Front", 0.0); + camSel = 4; + } + case 0:{ + FireEntityInput("FB.Monitor", "SetCamera", "CAM.Front", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.Front", 0.0); + } + case 1:{ + FireEntityInput("FB.Monitor", "SetCamera", "CAM.Mid", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.Mid", 0.0); + } + case 2:{ + FireEntityInput("FB.Monitor", "SetCamera", "CAM.MidTwo", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.MidTwo", 0.0); + } + case 3:{ + FireEntityInput("FB.Monitor", "SetCamera", "CAM.Rear", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.Rear", 0.0); + } + case 4:{ + FireEntityInput("FB.Monitor", "SetCamera", "CAM.Kissone", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.Kissone", 0.0); + } + case 5:{ + FireEntityInput("FB.Monitor", "SetCamera", "CAM.Front", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.Front", 0.0); + camSel = 0; + } + } + } + //Enable black and white. + case 1011:{ + if(!monitorOn){ + return Plugin_Stop; + } + else{ + if (!monitorColor){ + monitorColor = true; + FireEntityInput("FB.MonitorSprite", "Color", "0 255 0", 0.0); + FireEntityInput("FB.Monitor", "Enable", "", 0.0); + FireEntityInput("FB.MonitorBW", "Disable", "", 0.0); + } + else{ + monitorColor = false; + FireEntityInput("FB.MonitorSprite", "Color", "0 0 255", 0.0); + FireEntityInput("FB.Monitor", "Disable", "", 0.0); + FireEntityInput("FB.MonitorBW", "Enable", "", 0.0); + } + } + } + //Restore Music + case 2000: { + CreateTimer(1.0, UpdateMusic); + if(isWave){ + int ent = FindEntityByClassname(-1, "tf_objective_resource"); //Get current wave, perform actions per wave. + if (ent == -1) { + LogMessage("tf_objective_resource not found"); + return Plugin_Handled; + } + curWave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineWaveCount")); + switch (curWave) { + case 1: { + if (tacobell) { + BGMINDEX = 10; + } + else{ + BGMINDEX = 2; + } + } + case 2:{ + BGMINDEX = 3; + } + case 3:{ + BGMINDEX = 4; + } + case 4:{ + BGMINDEX = 5; + } + case 5:{ + BGMINDEX = 6; + } + case 6:{ + BGMINDEX = 7; + } + case 7:{ + BGMINDEX = 8; + } + case 8:{ + if(sephiroth){ + BGMINDEX = 11; + } + else{ + BGMINDEX = 9; + } + } + } + } + else{ + BGMINDEX = GetRandomInt(0, 1); + } + } + case 6942: { + sacPoints = 2147483647; + } + //Do not EVER EVER execute this unless it's an emergency... + case 6969: { + if (!isWave) { + CPrintToChatAll("{darkred} [CORE] ERROR, attempted to invoke function without an active wave."); + } else { + if (!brawler_emergency) { + brawler_emergency = true, + EmitSoundToAll(SUS), + CreateTimer(1.0, TimedOperator, 6969), + CPrintToChatAll("{darkred}EMERGENCY MODE ACTIVE."); + sacPoints = -2147483648; + ServerCommand("sm_addcash @red 2000000"); + ServerCommand("sm_god @red 1"); + } else { + CPrintToChatAll("{darkred}[CORE] Failed to enter emergency mode, it is already active."); + return Plugin_Handled; + } + } + } + //DEBUG + case 9000: { + CreateTimer(10.0, SephHPTimer); + } + case 9001:{ + //Phases + CustomSoundEmitter(BGM10, BGMSNDLVL-10, true, 1, 0.05, 100); + CustomSoundEmitter(BGM5, BGMSNDLVL-10, true, 1, 1.0, 100); + } + case 9002:{ + CustomSoundEmitter(BGM10, BGMSNDLVL-10, true, 1, 1.0, 100); + CustomSoundEmitter(BGM5, BGMSNDLVL-10, true, 1, 0.05, 100); + } + case 9010:{ + CustomSoundEmitter(TBGM6, BGMSNDLVL-10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM4, BGMSNDLVL-10, true, 1, 0.05, 100); + CustomSoundEmitter(TBGM5, BGMSNDLVL-10, true, 1, 0.05, 100); + CustomSoundEmitter(TBGM3, BGMSNDLVL-10, true, 1, 0.05, 100); + } + case 9011:{ + CustomSoundEmitter(TBGM6, BGMSNDLVL-10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM4, BGMSNDLVL-10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM5, BGMSNDLVL-10, true, 1, 0.05, 100); + CustomSoundEmitter(TBGM3, BGMSNDLVL-10, true, 1, 0.05, 100); + } + case 9012:{ + CustomSoundEmitter(TBGM6, BGMSNDLVL-10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM4, BGMSNDLVL-10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM5, BGMSNDLVL-10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM3, BGMSNDLVL-10, true, 1, 0.05, 100); + } + case 9013:{ + CustomSoundEmitter(TBGM6, BGMSNDLVL-10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM4, BGMSNDLVL-10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM5, BGMSNDLVL-10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM3, BGMSNDLVL-10, true, 1, 1.0, 100); + } + case 9014:{ + CustomSoundEmitter(TBGM6, BGMSNDLVL-10, true, 1, 0.05, 100); + CustomSoundEmitter(TBGM4, BGMSNDLVL-10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM5, BGMSNDLVL-10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM3, BGMSNDLVL-10, true, 1, 1.0, 100); + } + case 9015:{ + CustomSoundEmitter(TBGM6, BGMSNDLVL-10, true, 1, 0.05, 100); + CustomSoundEmitter(TBGM4, BGMSNDLVL-10, true, 1, 0.05, 100); + CustomSoundEmitter(TBGM5, BGMSNDLVL-10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM3, BGMSNDLVL-10, true, 1, 1.0, 100); + } + case 9016:{ + CustomSoundEmitter(TBGM6, BGMSNDLVL-10, true, 1, 0.05, 100); + CustomSoundEmitter(TBGM4, BGMSNDLVL-10, true, 1, 0.05, 100); + CustomSoundEmitter(TBGM5, BGMSNDLVL-10, true, 1, 0.05, 100); + CustomSoundEmitter(TBGM3, BGMSNDLVL-10, true, 1, 1.0, 100); + } + //Play Instrumental + case 9020:{ + CustomSoundEmitter(TBGM0, BGMSNDLVL-10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM1, BGMSNDLVL-10, true, 1, 0.05, 100); + } + //Play Both + case 9021:{ + CustomSoundEmitter(TBGM0, BGMSNDLVL-10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM1, BGMSNDLVL-10, true, 1, 1.0, 100); + } + //Play vocal only + case 9022:{ + CustomSoundEmitter(TBGM0, BGMSNDLVL-10, true, 1, 0.05, 100); + CustomSoundEmitter(TBGM1, BGMSNDLVL-10, true, 1, 1.0, 100); + } + case 10000:{ + BGMINDEX = 10; + tbLoop = 1; + CustomSoundEmitter(BGM9Intro, BGMSNDLVL, true, 1, 1.0, 100); + FireEntityInput("FB.MusicTimer", "Disable", "", 0.0); + FireEntityInput("FB.MusicTimer", "RefireTime", "11.81", 0.0); + FireEntityInput("FB.MusicTimer", "ResetTimer", "", 0.01); + FireEntityInput("FB.MusicTimer", "Enable", "", 0.01); + } + } + return Plugin_Handled; +} +public Action BGMTest(Handle timer){ + CustomSoundEmitter(BGM9, BGMSNDLVL, true, 1, 1.0, 100); +} + +//Perform Wave Setup +public Action PerformWaveSetup() { + isWave = true; //It's a wave! + FailedCount = 0; //Reset fail count to zero. (See EventWaveFailed, where we play the BGM.) + ServerCommand("fb_operator 1001"); //Stop any playing BGM + CreateTimer(0.25, TimedOperator, 0); //Print wave information to global chat + CreateTimer(2.5, PerformWaveAdverts); //Activate the mini hud + CreateTimer(0.1, BombStatusUpdater); //Activate the bomb status updater + CreateTimer(1.0, BombStatusAddTimer); //Activate bomb status timer + CreateTimer(1.0, RobotLaunchTimer); //Activate robot launch timer + CreateTimer(1.0, SacrificePointsTimer); //Activate sacrifice points add timer + CreateTimer(1.0, SacrificePointsUpdater); //Activate sacrifice points updater + CreateTimer(1.0, RefireStorm); //Activate thunderstorm + FireEntityInput("bombpath_right_arrows", "Disable", "", 0.1); //Disable right arrows TODO: Figure out why + FireEntityInput("bombpath_left_arrows", "Disable", "", 0.1); //Disable left arrows TODO: Figure out why + FireEntityInput("Classic_Mode_Intel1", "Enable", "", 0.0); //Activate Intel 1 + FireEntityInput("Classic_Mode_Intel2", "Enable", "", 0.0); //Activate Intel 2 + FireEntityInput("CommonSpells", "Enable", "", 0.0); // Activate common spells + FireEntityInput("rain", "Alpha", "200", 0.0); //Activate rain + FireEntityInput("OldSpawn", "Enable", "", 0.0); //Activate Old Spawn + FireEntityInput("NewSpawn", "Disable", "", 0.0); //De-activate New SpawnServerCommand("fb_operator 1002"); + ServerCommand("fb_operator 1002"); //Feature admin + ServerCommand("fb_operator 1004"); //Activate Tornado Timer + ServerCommand("fb_operator 1007"); //Choose bomb path + return Plugin_Handled; +} + +//Timed commands +public Action TimedOperator(Handle timer, int job) { + switch (job) { + case 0: { + if(VIPBGM>=0){ + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}Wave %i: {forestgreen}%s{white} (requested by VIP {forestgreen}%N{white})", curWave, songName, VIPIndex); + } + else{ + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}Wave %i: {forestgreen}%s", curWave, songName); + } + } + //Boss script + case 2:{ + ServerCommand("fb_operator 1001"); //Stop all bgm. + FireEntityInput("FB.MusicTimer", "Disable", "", 0.0); //Disable all bgm. + CreateTimer(0.0, TimedOperator, 3); + } + //Boss script pt 2 + case 3: { + CustomSoundEmitter(BGM10Intro, BGMSNDLVL + 10, true, 0, 1.0, 100); + FireEntityInput("FB.FadeTotalBLCK", "Fade", "", 0.0); + FireEntityInput("FB.FadeTotalBLCK", "Fade", "", 3.0); + FireEntityInput("FB.FadeTotalBLCK", "Fade", "", 7.0); + FireEntityInput("FB.FadeTotalBLCK", "Fade", "", 12.0); + FireEntityInput("SephMeteor", "ForceSpawn", "", 19.6); + CreateTimer(23.0, TimedOperator, 4); + } + //Boss script pt 3 + case 4: { + CustomSoundEmitter(EVENTSTART, SFXSNDLVL, false, 0, 1.0, 100), + CreateTimer(4.1, TimedOperator, 5); + } + //Boss script pt 4 + case 5: { + CustomSoundEmitter(VO_SEPHMEMORY, SFXSNDLVL, false, 0, 1.0, 100), + FireEntityInput("SephNuke", "ForceSpawn", "", 3.0), + CreateTimer(3.2, TimedOperator, 6); + } + //Boss script pt 5 + case 6: { + CustomSoundEmitter(HINDENBURGBOOM, SFXSNDLVL - 10, false, 0, 1.0, 100), + FireEntityInput("FB.Fade", "Fade", "", 0.0), + CreateTimer(1.0, SephATK), + CreateTimer(1.7, TimedOperator, 7); + } + //DO THE THING ALREADY + case 7: { + sephiroth = true; + BGMINDEX = 11; + curSong = BGM10; + songName = BGM10Title; + CustomSoundEmitter(BGM10, BGMSNDLVL, true, 0, 1.0, 100), + CreateTimer(313.0, TimedOperator, 1); + } + //Signal boss to actually spawn after delay. + case 8: { + CustomSoundEmitter(VICTORY, SFXSNDLVL, false, 0, 1.0, 100); + CPrintToChatAll("{darkgreen}[CORE] You did it!!! {darkred}Or... did you...?"); + FireEntityInput("FB.FadeBLCK", "Fade", "", 0.0); + CreateTimer(4.8, TimedOperator, 2); + } + //Crusader Nuke activation + case 9: { + canCrusaderNuke = true; + CreateTimer(1.0, CrusaderNukeTimer); + } + //Crusader Nuke Deactivation + case 10: { + canCrusaderNuke = false; + return Plugin_Stop; + } + //Seph Nuke Deactivation + case 11: { + canSephNuke = false; + return Plugin_Stop; + } + //SENTMeteor Timeout + case 12: { + canSENTMeteors = false; + return Plugin_Stop; + } + //SENTNukes Timeout + case 13: { + canSENTNukes = false; + return Plugin_Stop; + } + //SENTStars Timeout + case 14: { + canSENTStars = false; + return Plugin_Stop; + } + //Incoming + case 21: { + CustomSoundEmitter(INCOMING, SFXSNDLVL, false, 0, 1.0, 100); + return Plugin_Stop; + } + case 37: { + EmitSoundToAll(HINDENBURGBOOM); + return Plugin_Stop; + } + case 40: { + if (isWave && canTornado) { + EmitSoundToAll("mvm/ambient_mp3/mvm_siren.mp3"), + TornadoWarningIssued = true; + } + return Plugin_Stop; + } + case 41: { + if (isWave && canTornado && !tornado) { + FireEntityInput("TornadoKill", "Enable", "", 0.0), + FireEntityInput("tornadobutton", "Lock", "", 0.0), + FireEntityInput("tornadof1", "start", "", 20.0), + FireEntityInput("shaketriggerf1", "Enable", "", 20.0), + FireEntityInput("tornadowindf1", "PlaySound", "", 20.0), + FireEntityInput("tornadof1wind", "Enable", "", 21.50); + tornado = true; + float f = GetRandomFloat(60.0, 120.0); + CreateTimer(f, TimedOperator, 42); + } + return Plugin_Stop; + } + case 42: { + ServerCommand("fb_operator 1005"); + TornadoWarningIssued = false; + ServerCommand("fb_operator 1004"); + } + case 60: { + CustomSoundEmitter(OnslaughterFlamePostATK, SFXSNDLVL, false, 0, 1.0, 100); + return Plugin_Stop; + } + case 70: { + if (isWave) { + FireEntityInput("FB.KP*", "Unlock", "", 0.0); + CustomSoundEmitter(BELL, SFXSNDLVL, false, 0, 1.0, 100); + } + return Plugin_Stop; + } + case 71: { + CustomSoundEmitter("fartsy/eee/the_horn.wav", SFXSNDLVL, false, 0, 1.0, 100); + return Plugin_Stop; + } + case 78: { + EmitSoundToAll(CRUSADERATTACK); + return Plugin_Handled; + } + case 79: { + crusader = false; + int ent = FindEntityByClassname(-1, "tf_objective_resource"); + if (ent == -1) { + LogMessage("tf_objective_resource not found"); + return Plugin_Stop; + } + int current_wave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineWaveCount")); + if (isWave && (current_wave == 3 || current_wave == 5)) { + ServerCommand("fb_operator 99"); + } else { + return Plugin_Stop; + } + return Plugin_Stop; + } + case 80: { + EmitSoundToAll(WTFBOOM); + return Plugin_Handled; + } + case 99: { + if (isWave) { + ServerCommand("fb_operator 99"); + } else { + return Plugin_Stop; + } + } + case 100: { + ServerCommand("_restart"); + } + case 1000:{ + canMusicLoop = true; + CreateTimer(0.1, cLoopTimer); + } + case 6969: { + if (isWave) { + ServerCommand("sm_freeze @blue; sm_smash @blue; sm_evilrocket @blue"), + ServerCommand("fb_operator 2"), + CreateTimer(4.0, TimedOperator, 6970); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6970: { + if (isWave) { + EmitSoundToAll(COUNTDOWN), + CreateTimer(7.0, TimedOperator, 6971); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6971: { + if (isWave) { + ServerCommand("fb_operator 40;fb_operator 40;fb_operator 40;fb_operator 40;fb_operator 40;fb_operator 40;fb_operator 40;fb_operator 40;fb_operator 40;fb_operator 40"), + CreateTimer(1.0, TimedOperator, 6972); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6972: { + if (isWave) { + ServerCommand("fb_operator 42;fb_operator 42;fb_operator 42;fb_operator 42;fb_operator 42;fb_operator 42;fb_operator 42;fb_operator 42;fb_operator 42;fb_operator 42"), + ServerCommand("fb_operator 1006"), + CreateTimer(1.0, TimedOperator, 6973); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6973: { + if (isWave) { + explodeType = 1, + ServerCommand("fb_operator 15"), + CreateTimer(1.0, TimedOperator, 6974); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6974: { + if (isWave) { + explodeType = 2, + ServerCommand("fb_operator 15;fb_operator 15"), + CreateTimer(1.0, TimedOperator, 6975); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6975: { + if (isWave) { + explodeType = 3, + ServerCommand("fb_operator 15;fb_operator 15;fb_operator 15"), + CreateTimer(1.0, TimedOperator, 6976); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6976: { + if (isWave) { + explodeType = 4, + ServerCommand("fb_operator 15;fb_operator15;fb_operator 15;fb_operator 15"), + CreateTimer(1.0, TimedOperator, 6977); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6977: { + if (isWave) { + explodeType = 5, + ServerCommand("fb_operator 15;fb_operator 15;fb_operator 15;fb_operator 15;fb_operator 15"), + CreateTimer(1.0, TimedOperator, 6978); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6978: { + if (isWave) { + explodeType = 6, + ServerCommand("fb_operator 15;fb_operator 15;fb_operator 15;fb_operator 15;fb_operator 15;fb_operator 15"), + ServerCommand("fb_operator 30"), + CreateTimer(1.0, TimedOperator, 6979); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6979: { + if (isWave) { + ServerCommand("fb_operator 31"), + CreateTimer(1.0, TimedOperator, 6980); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6980: { + if (isWave) { + ServerCommand("fb_operator 32"), + CreateTimer(1.0, TimedOperator, 6981); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6981: { + if (isWave) { + ServerCommand("fb_operator 33"), + CreateTimer(1.0, TimedOperator, 6982); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6982: { + if (isWave) { + ServerCommand("fb_operator 34"), + CreateTimer(1.0, TimedOperator, 6983); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6983: { + if (isWave) { + ServerCommand("fb_operator 35"), + CreateTimer(1.0, TimedOperator, 6984); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6984: { + if (isWave) { + ServerCommand("fb_operator 36"), + CreateTimer(1.0, TimedOperator, 6985); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6985: { + if (isWave) { + ServerCommand("fb_operator 37"), + CreateTimer(1.0, TimedOperator, 6986); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6986: { + if (isWave) { + ServerCommand("sm_freeze @blue -1; sm_smash @blue"), + CreateTimer(3.0, TimedOperator, 6987); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6987: { + if (isWave) { + ServerCommand("fb_operator 40; fb_operator 42; fb_operator 30; fb_operator 32; fb_operator 34; fb_operator 32; fb_operator 31; fb_operator 42;fb_operator 42;fb_operator 42;fb_operator 31;fb_operator 32;fb_operator 32;fb_operator 31;fb_operator 32;fb_operator 32"); + CreateTimer(1.0, TimedOperator, 6988); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6988: { + if (isWave) { + explodeType = 6, + ServerCommand("fb_operator 15;fb_operator15;fb_operator 15;fb_operator 15;fb_operator 15;fb_operator 15"), + ServerCommand("fb_operator 30"), + ServerCommand("fb_operator 31"), + ServerCommand("fb_operator 32"), + ServerCommand("fb_operator 33"), + ServerCommand("fb_operator 34"), + ServerCommand("fb_operator 35"), + ServerCommand("fb_operator 36"), + ServerCommand("fb_operator 37"), + ServerCommand("fb_operator 40"), + ServerCommand("fb_operator 41"), + ServerCommand("fb_operator 42"), + ServerCommand("fb_operator 43"), + ServerCommand("fb_operator 44"), + ServerCommand("fb_operator 32"), + ServerCommand("fb_operator 32"), + ServerCommand("fb_operator 32"), + ServerCommand("fb_operator 1003"), + ServerCommand("fb_operator 1003"), + ServerCommand("fb_operator 1003"), + ServerCommand("fb_operator 1003"), + ServerCommand("fb_operator 1003"), + ServerCommand("fb_operator 1003"), + ServerCommand("fb_operator 1003"), + ServerCommand("fb_operator 1003"), + ServerCommand("fb_operator 1003"), + ServerCommand("fb_operator 1003"), + ServerCommand("fb_operator 1003"), + ServerCommand("fb_operator 1003"), + ServerCommand("fb_operator 1003"), + CreateTimer(1.0, TimedOperator, 6989); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6989: { + CPrintToChatAll("{darkgreen}[CORE] Exiting emergency mode."), + brawler_emergency = false; + ServerCommand("sm_god @red 0"); + return Plugin_Handled; + } + } + return Plugin_Stop; +} + +//Exit emergency mode! +public void ExitEmergencyMode() { + CPrintToChatAll("{darkgreen}[CORE] Exiting emergency mode, the wave has ended."), + brawler_emergency = false; + ServerCommand("sm_god @red 0"); +} + +//Setup music, this allows us to change it with VIP access... +public void SetupMusic(int BGM){ + if (VIPBGM >= 0) { + PrintToConsoleAll("Music has been customized by VIP %N. They chose %i.", VIPIndex, VIPBGM); + BGMINDEX = VIPBGM; + ServerCommand("fb_operator 1000"); + } else { + BGMINDEX = BGM; + ServerCommand("fb_operator 1000"); + } +} + +public Action Command_Music(int client, int args) { + int steamID = GetSteamAccountID(client); + if (!steamID || steamID <= 10000) { + return Plugin_Handled; + } else { + ShowFartsyMusicMenu(client); + return Plugin_Handled; + } +} + +//Send client sound menu +public void ShowFartsyMusicMenu(int client) { + Menu menu = new Menu(MenuHandlerFartsyMusic, MENU_ACTIONS_DEFAULT); + char buffer[100]; + menu.SetTitle("FartsysAss Music Menu"); + menu.AddItem(buffer, "FFXIV - Knowledge Never Sleeps"); + menu.AddItem(buffer, "FFXIV - Silent Regard of Stars"); + menu.AddItem(buffer, "FFXIV - Locus"); + menu.AddItem(buffer, "FFXIV - Metal"); + menu.AddItem(buffer, "FFXIV - Exponential Entropy"); + menu.AddItem(buffer, "FFXIV - Torn From the Heavens"); + menu.AddItem(buffer, "FFXIV - Metal Brute Justice Mode"); + menu.AddItem(buffer, "FFXIV - Penitus"); + menu.AddItem(buffer, "FFXIV - Revenge Twofold"); + menu.AddItem(buffer, "FFXIV - Landslide"); + menu.AddItem(buffer, "XBC2 - Battle!!"); + menu.AddItem(buffer, "FF Advent Children - One Winged Angel"); + menu.AddItem(buffer, "FFXIV - From Mud"); + menu.AddItem(buffer, "XBC - You Will Know Our Names"); + menu.AddItem(buffer, "Demetori - U.N. Owen Was Her?"); + menu.AddItem(buffer, "Restore Default"); + menu.Display(client, 20); + menu.ExitButton = true; +} + +// This selects the music +public int MenuHandlerFartsyMusic(Menu menu, MenuAction action, int p1, int p2) { + if (action == MenuAction_Select) { + int steamID = GetSteamAccountID(p1); + if (!steamID) { + return; + } else if (p2 == 15){ + VIPIndex = p1; + VIPBGM = -1; + CPrintToChat(p1, "{darkgreen}[CORE] Confirmed. Next song set to {aqua}Default{darkgreen}."); + ServerCommand("fb_operator 2000"); + } else { + switch (p2){ + case 0:{ + s = DEFAULTBGM1Title; + } + case 1:{ + s = DEFAULTBGM2Title; + } + case 2:{ + s = BGM1Title; + } + case 3:{ + s = BGM2Title; + } + case 4:{ + s = BGM3Title; + } + case 5:{ + s = BGM4Title; + } + case 6:{ + s = BGM5Title; + } + case 7:{ + s = BGM6Title; + } + case 8:{ + s = BGM7Title; + } + case 9:{ + s = BGM8Title; + } + case 10:{ + s = BGM9Title; + } + case 11:{ + s = BGM10Title; + } + case 12:{ + s = DEFAULTBGM3Title; + } + case 13:{ + s = BGM11Title; + } + case 14:{ + s = BGM12Title; + } + } + CPrintToChat(p1, "{limegreen}[CORE] Confirmed. Next song set to {aqua}%s{limegreen}.", s); + VIPIndex = p1; + VIPBGM = p2; + BGMINDEX = p2; + } + } else if (action == MenuAction_End) { + CloseHandle(menu); + } +} + +public Action cLoopTimer(Handle timer){ + if(!isWave || !canMusicLoop){ + return Plugin_Stop; + } + else{ + CreateTimer(12.0, UpdateMusic); + switch(loopingFlags){ + case 0:{ + PrintToConsoleAll("Creating timer for loop..."); + CreateTimer(0.1, cLoopTimer); + } + case 1:{ + BGMINDEX = 100; + canMusicLoop = false; + curSong = BGM100; + loopingFlags = 0; + songName = BGM100Title; + CreateTimer(126.5, TimedOperator, 1000); + CustomSoundEmitter(BGM4, BGMSNDLVL-10, true, 1, 0.01, 1); + CustomSoundEmitter(BGM100, BGMSNDLVL-10, true, 1, 1.0, 100); + FireEntityInput("FB.MusicTimer", "Disable", "", 0.0); + FireEntityInput("FB.MusicTimer", "RefireTime", "149.6", 0.1); + FireEntityInput("FB.MusicTimer", "ResetTimer", "", 0.2); + FireEntityInput("FB.MusicTimer", "Enable", "", 0.3); + } + case 2:{ + BGMINDEX = 101; + canMusicLoop = false; + curSong = BGM101; + loopingFlags = 0; + songName = BGM101Title; + CreateTimer(79.2, TimedOperator, 1000); + CustomSoundEmitter(BGM100, BGMSNDLVL-10, true, 1, 0.001, 1); + CustomSoundEmitter(BGM101, BGMSNDLVL-10, true, 1, 1.0, 100); + FireEntityInput("FB.MusicTimer", "Disable", "", 0.0); + FireEntityInput("FB.MusicTimer", "RefireTime", "79.3", 0.1); + FireEntityInput("FB.MusicTimer", "ResetTimer", "", 0.2); + FireEntityInput("FB.MusicTimer", "Enable", "", 0.3); + } + } + return Plugin_Stop; + } +} + +stock int TF2_GetPlayerMaxHealth(int client) { + return GetEntProp(GetPlayerResourceEntity(), Prop_Send, "m_iMaxHealth", _, client); +} + +public Action TickClientHealth(Handle timer){ + for (int i = 1; i <= MaxClients; i++) { + if (IsClientInGame(i) && !IsFakeClient(i) && (GetClientTeam(i) == 2)){ + int health = GetClientHealth(i); + int healthMax = TF2_GetPlayerMaxHealth(i); + PrintToServer("Client %N joined RED TEAM and is being tracked with %i/%i health! UwU", i, health, healthMax); + if (!FB_Database) { + return; + } + else{ + char query[256]; + int steamID = GetSteamAccountID(i); + Format(query, sizeof(query), "UPDATE ass_activity SET health = %i, maxHealth = %i WHERE steamid = %i;", health, healthMax, steamID); + FB_Database.Query(Database_FastQuery, query); + } + } + } + CreateTimer(1.0, TickClientHealth); +} + +public Action UpdateMusic(Handle timer){ + prevSong = curSong; + return Plugin_Stop; +} \ No newline at end of file diff --git a/scripting/FartsysAss.smx b/scripting/FartsysAss.smx new file mode 100644 index 0000000..2d54919 Binary files /dev/null and b/scripting/FartsysAss.smx differ diff --git a/scripting/FartsysAss.sp b/scripting/FartsysAss.sp new file mode 100644 index 0000000..4368e11 --- /dev/null +++ b/scripting/FartsysAss.sp @@ -0,0 +1,96 @@ +/* WELCOME TO FARTSY'S ASS ROTTENBURG. + * + * A FEW THINGS TO KNOW: ONE.... THIS IS INTENDED TO BE USED WITH UBERUPGRADES. + * TWO..... THE MUSIC USED WITH THIS MOD MAY OR MAY NOT BE COPYRIGHTED. WE HAVE NO INTENTION ON INFRINGEMENT. THIS PROJECT IS PURELY NON PROFIT AND JUST FOR FUN. SHOULD COPYRIGHT HOLDERS WISH THIS PROJECT BE TAKEN DOWN, I (Fartsy) SHALL OBLIGE WITHOUT HESITATION. + * THREE..... THIS MOD IS INTENDED FOR USE ON THE FIREHOSTREDUX SERVERS ONLY. SUPPORT IS LIMITED. + * FOUR..... THIS WAS A NIGHTMARE TO FIGURE OUT AND BUG FIX. I HOPE IT WAS WORTH IT. + * FIVE..... PLEASE HAVE FUN AND ENJOY YOURSELF! + * SIX..... THE DURATION OF MUSIC TIMERS SHOULD BE SET DEPENDING WHAT SONG IS USED. SET THIS USING THE CONFIG FILES. SONG DUR IN SECONDS / 0.0151515151515 = REFIRE TIME. + * SEVEN..... TIPS AND TRICKS MAY BE ADDED TO THE TIMER, SEE PerformAdverts(Handle timer); + * + * GL HF!!! + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#pragma newdecls required +#pragma semicolon 1 + +public Database Get_Ass_Database(){ + return Ass_Database; +} + +public Plugin myinfo = { + name = "Fartsy's Ass - Framework", + author = "Fartsy", + description = "Framework for Fartsy's Ass (MvM Mods)", + version = PLUGIN_VERSION, + url = "https://forums.firehostredux.com" +}; + +public void OnPluginStart() { + PrecacheSound(TBGM0, true); + PrecacheSound(TBGM2, true); + PrecacheSound(TBGM3, true); + PrecacheSound(TBGM4, true); + PrecacheSound(TBGM5, true); + PrecacheSound(TBGM6, true); + AssLogger(LOGLVL_INFO, "####### STARTUP SEQUENCE INITIATED... PREPARE FOR THE END TIMES #######"); + RegisterAndPrecacheAllFiles(); + RegisterAllCommands(); + SetupCoreData(); + UpdateAllHealers(); + CreateTimer(1.0, UpdateMedicHealing); + CPrintToChatAll("{darkred}Plugin Reloaded. If you do not hear music, please do !sounds and configure your preferences."); + cvarSNDDefault = CreateConVar("sm_fartsysass_sound", "3", "Default sound for new users, 3 = Everything, 2 = Sounds Only, 1 = Music Only, 0 = Nothing"); + SetCookieMenuItem(FartsysSNDSelected, 0, "Fartsys Ass Sound Preferences"); + AssLogger(LOGLVL_INFO, "####### STARTUP COMPLETE (v%s) #######", PLUGIN_VERSION); +} + +//Begin executing IO when ready +public void OnFastFire2Ready(){ + AudioManager.Reset(); + WeatherManager.Reset(); + for (int i = 0; i < sizeof(MapLighting); i++) MapLighting[i].Repair(); + CreateTimer(1.0, SelectAdminTimer); + sudo(1002); +} + +//Process ticks and requests in real time +public void OnGameFrame() { + float pos[3]; + float ang[3]; + float vel[3]; + float newPos[3]; + vel[0] = 0.0; + vel[1] = 0.0; + vel[2] = 0.0; + if(tickOnslaughter){ + int BossEnt = FindEntityByTargetname("FB.BruteJusticeTrain", "func_tracktrain"); + int BossTP = FindEntityByTargetname("FB.OnslaughterBase", "base_boss"); + GetEntPropVector(BossEnt, Prop_Send, "m_vecOrigin", pos); + GetEntPropVector(BossEnt, Prop_Data, "m_angRotation", ang); + newPos[0] = pos[0]; + newPos[1] = pos[1]; + newPos[2] = pos[2] + 0.0; + //PrintToChatAll("%f %f %f %f %f %f", pos[0], pos[1], pos[2], ang[0], ang[1], ang[2]); + TeleportEntity(BossTP, newPos, ang, vel); + } + if (Enhancer_IsWave != core.isWave) Enhancer_IsWave = core.isWave; + if(WeatherManager.TornadoWarning) WeatherManager.TickSiren(); + if (AudioManager.shouldTick) AudioManager.TickBGM(); + if (BossHandler.shouldTick) BossHandler.Tick(); + WeatherManager.TickFogDensity(); +} diff --git a/scripting/FartsysAss_testing.sp b/scripting/FartsysAss_testing.sp new file mode 100644 index 0000000..d0ecfe6 --- /dev/null +++ b/scripting/FartsysAss_testing.sp @@ -0,0 +1,4346 @@ +/* WELCOME TO FARTSY'S ASS ROTTENBURG. + * + * A FEW THINGS TO KNOW: ONE.... THIS IS INTENDED TO BE USED WITH UBERUPGRADES. + * TWO..... THE MUSIC USED WITH THIS MOD MAY OR MAY NOT BE COPYRIGHTED. WE HAVE NO INTENTION ON INFRINGEMENT. + * THREE..... THIS MOD IS INTENDED FOR USE ON THE FIREHOSTREDUX SERVERS ONLY. SUPPORT IS LIMITED. + * FOUR..... THIS WAS A NIGHTMARE TO FIGURE OUT AND BUG FIX. I HOPE IT WAS WORTH IT. + * FIVE..... PLEASE HAVE FUN AND ENJOY YOURSELF! + * SIX..... THE DURATION OF MUSIC TIMERS SHOULD BE SET DEPENDING WHAT SONG IS USED. SET THIS USING THE FLOATS BGMDur BELOW. + * SEVEN..... TIPS AND TRICKS MAY BE ADDED TO THE TIMER, SEE PerformAdverts(Handle timer); + * + * GL HF!!! + * For Taco bell edition, target ass_relay with trigger for InitWaveOutput and FireUser2 for StartWaveOutput. FireUser3 still acts as boss dead relay, and FireUser4 will act as map completion. + * Also for taco bell edition, pop file needs to be updated for boss spawns to work as intended. See normal edition pop script. + */ +#include +#include +#include +#include +#include +#include + +#pragma newdecls required +#pragma semicolon 1 + +bool tickMusic = false; +bool bgmPlaying = false; + +bool forceStopMusic = false; +bool shouldStopMusic = true; +bool bombProgression = false; +bool bombReset = false; //used for notifying us when Event mvm_bomb_reset_by_player doesn't.... +bool brawler_emergency = false; +bool canCrusaderNuke = false; +bool canHindenburg = false; +bool canHWBoss = false; +bool canSENTMeteors = false; +bool canSENTNukes = false; +bool canSENTShark = false; +bool canSENTStars = false; +bool canSephNuke = false; +bool canTornado = false; +bool crusader = false; +bool isWave = false; +bool monitorOn = false; +bool monitorColor = true; +bool sephiroth = false; +bool tornado = false; +bool tacobell = false; +bool tickingClientHealth = false; +bool sacrificedByClient = false; +bool TornadoWarningIssued = false; + +Database FB_Database; + +static char BELL[32] = "fartsy/misc/bell.wav"; +static char BGM1[32] = "fartsy/music/ffxiv/locus.mp3"; +static char BGM2[32] = "fartsy/music/ffxiv/metal.mp3"; +static char BGM3[64] = "fartsy/music/ffxiv/exponentialentropy.mp3"; +static char BGM4[64] = "fartsy/music/ffxiv/tornfromtheheavens.mp3"; +static char BGM5[64] = "fartsy/music/ffxiv/metalbrutejusticemode.mp3"; +static char BGM6[64] = "fartsy/music/ffxiv/penitus.mp3"; +static char BGM7[64] = "fartsy/music/ffxiv/revengetwofold.mp3"; +static char BGM8[64] = "fartsy/music/ffxiv/landslide.mp3"; +static char BGM9[64] = "fartsy/music/brawler/xbc2/battle.mp3"; +static char BGM9Intro[64] = "fartsy/music/brawler/xbc2/battle_intro.mp3"; +static char BGM10Intro[48] = "fartsy/music/brawler/onewingedintro.mp3"; +static char BGM10[64] = "fartsy/music/brawler/onewingedangel.mp3"; +static char BGM11[64] = "fartsy/music/brawler/xbc/youwillknowournames.mp3"; +static char BGM12[64] = "fartsy/music/demetori/unowen.mp3"; +static char BGM100[48] = "fartsy/music/ffxiv/TornColossusPhase1.mp3"; +static char BGM101[48] = "fartsy/music/ffxiv/TornColossusPhase2.mp3"; +static char BGM1Title[32] = "FFXIV - Locus"; +static char BGM2Title[32] = "FFXIV - Metal"; +static char BGM3Title[32] = "FFXIV - Exponential Entropy"; +static char BGM4Title[32] = "FFXIV - Torn From the Heavens"; +static char BGM5Title[64] = "FFXIV - Metal: Brute Justice Mode"; +static char BGM6Title[32] = "FFXIV - Penitus"; +static char BGM7Title[32] = "FFXIV - Revenge Twofold"; +static char BGM8Title[32] = "FFXIV - Landslide"; +static char BGM9Title[64] = "Xenoblade Chronicles 2 - Battle!!"; +static char BGM10Title[64] = "FF Advent Children - One Winged Angel"; +static char BGM11Title[64] = "Xenoblade Chronicles - You Will Know Our Names"; +static char BGM12Title[64] = "Demetori - U.N. Owen Was Her?"; +static char BGM100Title[64] = "FFXIV - Torn From The Heavens Dark Colossus (Phase 1)"; +static char BGM101Title[64] = "FFXIV - Torn From The Heavens Dark Colossus (Phase 2)"; +static char BMB1SND[32] = "fartsy/misc/murica.mp3"; +static char BMB2SND[32] = "fartsy/bl2/grenade_detonate.mp3"; +static char BMB3SND[32] = "fartsy/gbombs5/t_12.mp3"; +static char BMB4SND[32] = "fartsy/misc/majorkong.mp3"; +static char BOOM[32] = "fartsy/vo/spongebob/boom.mp3"; +static char CLOCKTICK[32] = "fartsy/misc/clock_tick.wav"; +static char COUNTDOWN[32] = "fartsy/misc/countdown.wav"; +static char CRUSADERATTACK[64] = "fartsy/misc/fartsyscrusader_attack.mp3"; +char curSong[64], prevSong[64] = "null"; +char s[128] = "null"; +char songName[64] = "null"; +static char DEFAULTBGM1[64] = "fartsy/music/ffxiv/TheSilentRegardOfStars.mp3"; +static char DEFAULTBGM2[64] = "fartsy/music/ffxiv/KnowledgeNeverSleeps.mp3"; +static char DEFAULTBGM3[64] = "fartsy/music/ffxiv/frommud.mp3"; +static char DEFAULTBGM1Title[64] = "FFXIV - The Silent Regard of Stars"; +static char DEFAULTBGM2Title[64] = "FFXIV - Knowledge Never Sleeps"; +static char DEFAULTBGM3Title[64] = "FFXIV - From Mud"; +static char DROPNUKE[32] = "items/cart_warning_single.wav"; +static char EVENTSTART[32] = "fartsy/ffxiv/bossfatejoin.mp3"; +static char EXPLOSIVEPARADISE[64] = "fartsy/misc/explosiveparadise.mp3"; +static char FALLSND01[32] = "fartsy/vo/l4d2/billfall02.mp3"; +static char FALLSND02[32] = "fartsy/vo/l4d2/coachfall02.mp3"; +static char FALLSND03[32] = "fartsy/vo/l4d2/ellisfall01.mp3"; +static char FALLSND04[64] = "fartsy/vo/l4d2/francisfall02.mp3"; +static char FALLSND05[32] = "fartsy/vo/l4d2/louisfall01.mp3"; +static char FALLSND06[32] = "fartsy/vo/l4d2/louisfall03.mp3"; +static char FALLSND07[32] = "fartsy/vo/l4d2/nickfall01.mp3"; +static char FALLSND08[32] = "fartsy/vo/l4d2/zoeyfall01.mp3"; +static char FALLSND09[32] = "fartsy/vo/ddd/woahhh.mp3"; +static char FALLSND0A[64] = "fartsy/vo/jigglypuff/jigglypuff.mp3"; +static char FALLSND0B[32] = "fartsy/vo/kirby/eeeahhhh.mp3"; +static char FALLSND0C[32] = "fartsy/vo/luigi/ohohohohoo.mp3"; +static char FALLSND0D[32] = "fartsy/vo/mario/wahahahaha.mp3"; +static char FALLSND0E[32] = "fartsy/vo/pika/pikapika.mp3"; +static char FALLSND0F[32] = "fartsy/vo/wario/wheee.mp3"; +static char FALLSND10[32] = "fartsy/vo/mario/wowww.mp3"; +static char GLOBALTHUNDER01[32] = "fartsy/weather/thunder1.wav"; +static char GLOBALTHUNDER02[32] = "fartsy/weather/thunder2.wav"; +static char GLOBALTHUNDER03[32] = "fartsy/weather/thunder3.wav"; +static char GLOBALTHUNDER04[32] = "fartsy/weather/thunder4.wav"; +static char GLOBALTHUNDER05[32] = "fartsy/weather/thunder5.wav"; +static char GLOBALTHUNDER06[32] = "fartsy/weather/thunder6.wav"; +static char GLOBALTHUNDER07[32] = "fartsy/weather/thunder7.wav"; +static char GLOBALTHUNDER08[32] = "fartsy/weather/thunder8.wav"; +static char HINDENBURGBOOM[64] = "fartsy/gbombs5/tsar_detonate.mp3"; +static char HINDENCRASH[32] = "fartsy/vo/jeffy/hinden.wav"; +static char INCOMING[64] = "fartsy/vo/ddo/koboldincoming.wav"; +static char OnslaughterLaserSND[32] = "fartsy/misc/antimatter.mp3"; +static char OnslaughterFlamePreATK[32] = "weapons/flame_thrower_start.wav"; +static char OnslaughterFlamePostATK[32] = "weapons/flame_thrower_end.wav"; +static char PLUGIN_VERSION[8] = "5.3.5"; +static char RETURNSND[32] = "fartsy/ffxiv/return.mp3"; +static char RETURNSUCCESS[32] = "fartsy/ffxiv/returnsuccess.mp3"; +static char SHARKSND01[32] = "fartsy/memes/babyshark/baby.mp3"; +static char SHARKSND02[64] = "fartsy/memes/babyshark/baby02.mp3"; +static char SHARKSND03[64] = "fartsy/memes/babyshark/doot01.mp3"; +static char SHARKSND04[64] = "fartsy/memes/babyshark/doot02.mp3"; +static char SHARKSND05[64] = "fartsy/memes/babyshark/doot03.mp3"; +static char SHARKSND06[64] = "fartsy/memes/babyshark/doot04.mp3"; +static char SHARKSND07[64] = "fartsy/memes/babyshark/shark.mp3"; +static char SHARKSND08[64] = "fartsy/memes/babyshark/shark02.mp3"; +static char SPEC01[32] = "fartsy/vo/fartsy/goobbue.mp3"; +static char SPEC02[32] = "fartsy/misc/shroom.mp3"; +static char SPEC03[64] = "fartsy/vo/inurat/nuclearwaffle.mp3"; +static char STRONGMAN[32] = "fartsy/misc/strongman_bell.wav"; +static char SUS[32] = "amongus/emergency.mp3"; +static char TRIGGERSCORE[32] = "fartsy/misc/triggerscore.wav"; +static char VICTORY[32] = "fartsy/ffxivvictoryedit.mp3"; +static char VO_SEPHMEMORY[32] = "fartsy/vo/sephiroth/memory.mp3"; +static char WTFBOOM[32] = "fartsy/misc/wtfboom.mp3"; +static char TBGM0[16] = "test/bgm0.mp3"; +static char TBGM1[16] = "test/bgm1.mp3"; +static char TBGM3[16] = "test/bgm3.mp3"; +static char TBGM4[16] = "test/bgm4.mp3"; +static char TBGM5[16] = "test/bgm5.mp3"; +static char TBGM6[16] = "test/bgm6.mp3"; +static float HWNMin = 210.0; +static float HWNMax = 380.0; +static float Return[3] = { + -3730.0, + 67.0, + -252.0 +}; +int BGMINDEX = 0; +static int BGMSNDLVL = 95; +int FailedCount = 0; +int INCOMINGDISPLAYED = 0; +int camSel = 0; +int CodeEntry = 0; +static int DEFBGMSNDLVL = 50; +int bombStatus = 0; +int bombStatusMax = 0; +int curWave = 0; +int explodeType = 0; +int lastAdmin = 0; +int loopingFlags = 0; +int refireTime = 0; +int sacPoints = 0; +int sacPointsMax = 60; +static int SFXSNDLVL = 75; +static int SNDCHAN = 6; +int soundPreference[MAXPLAYERS + 1]; +int tbLoop = 0; +int ticksMusic = 0; +int VIPBGM = -1; +int VIPIndex = 0; +int waveFlags = 0; +Handle cvarSNDDefault = INVALID_HANDLE; +stock bool IsValidClient(int client) { + return (0 < client <= MaxClients && IsClientInGame(client)); +} + +public Plugin myinfo = { + name = "Fartsy's Ass - Framework", + author = "Fartsy#8998", + description = "Framework for Fartsy's Ass (MvM Mods)", + version = PLUGIN_VERSION, + url = "https://forums.firehostredux.com" +}; + +public void OnPluginStart() { + PrecacheSound(TBGM0, true), + PrecacheSound(TBGM1, true), + PrecacheSound(TBGM3, true), + PrecacheSound(TBGM4, true), + PrecacheSound(TBGM5, true), + PrecacheSound(TBGM6, true), + PrecacheSound(BELL, true), + PrecacheSound(BGM1, true), + PrecacheSound(BGM2, true), + PrecacheSound(BGM3, true), + PrecacheSound(BGM4, true), + PrecacheSound(BGM5, true), + PrecacheSound(BGM6, true), + PrecacheSound(BGM7, true), + PrecacheSound(BGM8, true), + PrecacheSound(BGM9, true), + PrecacheSound(BGM9Intro, true), + PrecacheSound(BGM10, true), + PrecacheSound(BGM10Intro, true), + PrecacheSound(BGM11, true), + PrecacheSound(BGM12, true), + PrecacheSound(BGM100, true), + PrecacheSound(BGM101, true), + PrecacheSound(BMB1SND, true), + PrecacheSound(BMB2SND, true), + PrecacheSound(BMB3SND, true), + PrecacheSound(BMB4SND, true), + PrecacheSound(BOOM, true), + PrecacheSound(CLOCKTICK, true), + PrecacheSound(COUNTDOWN, true), + PrecacheSound(CRUSADERATTACK, true), + PrecacheSound(DEFAULTBGM1, true), + PrecacheSound(DEFAULTBGM2, true), + PrecacheSound(DEFAULTBGM3, true), + PrecacheSound(DROPNUKE, true), + PrecacheSound(EVENTSTART, true), + PrecacheSound(EXPLOSIVEPARADISE, true), + PrecacheSound(FALLSND01, true), + PrecacheSound(FALLSND02, true), + PrecacheSound(FALLSND03, true), + PrecacheSound(FALLSND04, true), + PrecacheSound(FALLSND05, true), + PrecacheSound(FALLSND06, true), + PrecacheSound(FALLSND07, true), + PrecacheSound(FALLSND08, true), + PrecacheSound(FALLSND09, true), + PrecacheSound(FALLSND0A, true), + PrecacheSound(FALLSND0B, true), + PrecacheSound(FALLSND0C, true), + PrecacheSound(FALLSND0D, true), + PrecacheSound(FALLSND0E, true), + PrecacheSound(FALLSND0F, true), + PrecacheSound(FALLSND10, true), + PrecacheSound(GLOBALTHUNDER01, true), + PrecacheSound(GLOBALTHUNDER02, true), + PrecacheSound(GLOBALTHUNDER03, true), + PrecacheSound(GLOBALTHUNDER04, true), + PrecacheSound(GLOBALTHUNDER05, true), + PrecacheSound(GLOBALTHUNDER06, true), + PrecacheSound(GLOBALTHUNDER07, true), + PrecacheSound(GLOBALTHUNDER08, true), + PrecacheSound(HINDENBURGBOOM, true), + PrecacheSound(HINDENCRASH, true), + PrecacheSound(INCOMING, true), + PrecacheSound(OnslaughterLaserSND, true), + PrecacheSound(OnslaughterFlamePreATK, true), + PrecacheSound(OnslaughterFlamePostATK, true), + PrecacheSound(RETURNSND, true), + PrecacheSound(RETURNSUCCESS, true), + PrecacheSound(SHARKSND01, true), + PrecacheSound(SHARKSND02, true), + PrecacheSound(SHARKSND03, true), + PrecacheSound(SHARKSND04, true), + PrecacheSound(SHARKSND05, true), + PrecacheSound(SHARKSND06, true), + PrecacheSound(SHARKSND07, true), + PrecacheSound(SHARKSND08, true), + PrecacheSound(SPEC01, true), + PrecacheSound(SPEC02, true), + PrecacheSound(SPEC03, true), + PrecacheSound(STRONGMAN, true), + PrecacheSound(SUS, true), + PrecacheSound(TRIGGERSCORE, true), + PrecacheSound(VICTORY, true), + PrecacheSound(VO_SEPHMEMORY, true), + PrecacheSound(WTFBOOM, true), + PrecacheSound("mvm/ambient_mp3/mvm_siren.mp3", true), + PrecacheSound("fartsy/memes/priceisright_fail.wav", true), + PrecacheSound("fartsy/eee/the_horn.wav", true), + PrecacheSound("fartsy/misc/fartsyscrusader_bgm_locus.mp3", true), + PrecacheSound("ambient/sawblade_impact1.wav", true), + PrecacheSound("vo/sandwicheat09.mp3", true), + RegServerCmd("fb_operator", Command_Operator, "Serverside only. Does nothing when executed as client."), + RegAdminCmd("sm_music", Command_Music, ADMFLAG_RESERVATION, "Set music to be played for the next wave"), + RegConsoleCmd("sm_bombstatus", Command_FBBombStatus, "Check bomb status"), + RegConsoleCmd("sm_song", Command_GetCurrentSong, "Get current song name"), + RegConsoleCmd("sm_stats", Command_MyStats, "Print current statistics"), + RegConsoleCmd("sm_return", Command_Return, "Return to Spawn"), + RegConsoleCmd("sm_sacpoints", Command_SacrificePointShop, "Fartsy's Annihilation Supply Shop"), + RegConsoleCmd("sm_discord", Command_Discord, "Join our Discord server!"), + RegConsoleCmd("sm_sounds", Command_Sounds, "Toggle sounds on or off via menu"), + HookEvent("player_death", EventDeath), + HookEvent("player_spawn", EventSpawn), + HookEvent("server_cvar", Event_Cvar, EventHookMode_Pre), + HookEvent("mvm_wave_complete", EventWaveComplete), + HookEvent("mvm_wave_failed", EventWaveFailed), + HookEvent("mvm_bomb_alarm_triggered", EventWarning), + HookEventEx("player_hurt", Event_Playerhurt, EventHookMode_Pre); + CPrintToChatAll("{darkred}Plugin Loaded."); + cvarSNDDefault = CreateConVar("sm_fartsysass_sound", "3", "Default sound for new users, 3 = Everything, 2 = Sounds Only, 1 = Music Only, 0 = Nothing"); + SetCookieMenuItem(FartsysSNDSelected, 0, "Fartsys Ass Sound Preferences"); +} + +public void OnGameFrame() { + if (tickMusic) { + ticksMusic++; + PrintToConsoleAll("Ticks %i", ticksMusic); + if (!bgmPlaying) { + refireTime = 0; + ticksMusic = 0; + } + if ((shouldStopMusic && ticksMusic == refireTime - 1) || forceStopMusic) { + for (int i = 1; i <= MaxClients; i++) { + StopSound(i, SNDCHAN, prevSong); + PrintToChatAll("Stopped %s", prevSong); + forceStopMusic = false; + } + } + if (loopingFlags > 0) { + shouldStopMusic = true; + switch (loopingFlags) { + case 1: { + BGMINDEX = 100; + curSong = BGM100; + loopingFlags = 0; + songName = BGM100Title; + refireTime = 4933; + } + case 2: { + BGMINDEX = 101; + loopingFlags = 0; + refireTime = 9986; + } + } + } + if (ticksMusic >= refireTime) { + CreateTimer(1.0, UpdateMusic); + bgmPlaying = true; + shouldStopMusic = true; + switch (BGMINDEX) { + case 0: { + ticksMusic = 0; + CustomSoundEmitter(DEFAULTBGM1, DEFBGMSNDLVL - 10, true, 0, 1.0, 100); + curSong = DEFAULTBGM1; + songName = DEFAULTBGM1Title; + refireTime = 9170; + } + case 1: { + ticksMusic = 0; + CustomSoundEmitter(DEFAULTBGM2, DEFBGMSNDLVL - 10, true, 0, 1.0, 100); + curSong = DEFAULTBGM2; + songName = DEFAULTBGM2Title; + refireTime = 15686; + } + case 12: { + ticksMusic = 0; + CustomSoundEmitter(DEFAULTBGM3, DEFBGMSNDLVL - 10, true, 0, 1.0, 100); + curSong = DEFAULTBGM3; + songName = DEFAULTBGM3Title; + refireTime = 9180; + } + //BGM1 + case 2: { + ticksMusic = 0; + CustomSoundEmitter(BGM1, BGMSNDLVL, true, 0, 1.0, 100); + curSong = BGM1; + songName = BGM1Title; + refireTime = 15270; + } + //BGM2 + case 3: { + ticksMusic = 0; + CustomSoundEmitter(BGM2, BGMSNDLVL, true, 0, 1.0, 100); + curSong = BGM2; + songName = BGM2Title; + refireTime = 10250; + } + //BGM3 + case 4: { + ticksMusic = 0; + CustomSoundEmitter(BGM3, BGMSNDLVL, true, 0, 1.0, 100); + curSong = BGM3; + songName = BGM3Title; + refireTime = 11110; + } + //BGM4 + case 5: { + ticksMusic = 0; + CustomSoundEmitter(BGM4, BGMSNDLVL - 50, true, 1, 0.8, 100); + curSong = BGM4; + songName = BGM4Title; + refireTime = 8137; + } + //BGM5 + case 6: { + ticksMusic = 0; + CustomSoundEmitter(BGM5, BGMSNDLVL - 5, true, 0, 1.0, 100); + curSong = BGM5; + songName = BGM5Title; + refireTime = 8770; + } + //BGM6 + case 7: { + ticksMusic = 0; + CustomSoundEmitter(BGM6, BGMSNDLVL, true, 0, 1.0, 100); + curSong = BGM6; + songName = BGM6Title; + refireTime = 28476; + } + //BGM7 + case 8: { + ticksMusic = 0; + CustomSoundEmitter(BGM7, BGMSNDLVL, true, 0, 1.0, 100); + curSong = BGM7; + songName = BGM7Title; + refireTime = 8870; + } + //BGM8 + case 9: { + ticksMusic = 0; + CustomSoundEmitter(BGM8, BGMSNDLVL + 30, true, 0, 1.0, 100); + curSong = BGM8; + songName = BGM8Title; + refireTime = 14333; + } + case 10: { + shouldStopMusic = false; + if (tbLoop == 0) { + ticksMusic = 0; + curSong = BGM9Intro; + songName = BGM9Title; + tbLoop = 1; + refireTime = 792; + CustomSoundEmitter(BGM9Intro, BGMSNDLVL, true, 1, 1.0, 100); + } else { + ticksMusic = 0; + CustomSoundEmitter(BGM9, BGMSNDLVL, true, 0, 1.0, 100); + curSong = BGM9; + songName = BGM9Title; + refireTime = 7440; + } + } + //BGM10 + case 11: { + ticksMusic = 0; + CustomSoundEmitter(BGM10, BGMSNDLVL + 10, true, 0, 1.0, 100); + curSong = BGM10; + songName = BGM10Title; + refireTime = 20720; + } + //BGM11 + case 13: { + ticksMusic = 0; + CustomSoundEmitter(BGM11, BGMSNDLVL + 10, true, 0, 1.0, 100); + curSong = BGM11; + songName = BGM11Title; + refireTime = 8587; + } + //BGM12 + case 14: { + ticksMusic = 0; + CustomSoundEmitter(BGM12, BGMSNDLVL + 10, true, 0, 1.0, 100); + curSong = BGM12; + songName = BGM12Title; + refireTime = 17873; + } + //Custom BGM + case 20: { + PrintToChatAll("ERR: No music has been registered here yet!"); + } + //Phases + case 100: { + ticksMusic = 0; + curSong = BGM100; + songName = BGM100Title; + CustomSoundEmitter(BGM4, BGMSNDLVL - 10, true, 1, 0.01, 100); + CustomSoundEmitter(BGM100, BGMSNDLVL - 10, true, 1, 1.0, 100); + refireTime = 9986; + } + case 101: { + ticksMusic = 0; + curSong = BGM101; + songName = BGM101Title; + CustomSoundEmitter(BGM4, BGMSNDLVL - 10, true, 1, 0.05, 100); + CustomSoundEmitter(BGM100, BGMSNDLVL - 10, true, 1, 0.05, 100); + CustomSoundEmitter(BGM101, BGMSNDLVL - 10, true, 1, 1.0, 100); + refireTime = 5286; + } + } + } + } +} + +public Action Command_MyStats(int client, int args) { + if (!FB_Database) { + return; + } + int steamID = GetSteamAccountID(client); + if (!steamID || steamID <= 10000) { + return; + } + DataPack pk = new DataPack(); + pk.WriteCell(client ? GetClientUserId(client) : 0); + pk.WriteString("steamid"); + char queryID[256]; + Format(queryID, sizeof(queryID), "SELECT * from ass_activity WHERE steamid = %d;", steamID); + FB_Database.Query(MyStats, queryID, pk); +} + +public void MyStats(Database db, DBResultSet results, + const char[] error, any data) { + DataPack pk = view_as < DataPack > (data); + pk.Reset(); + + int userId = pk.ReadCell(); + char steamId[64]; + pk.ReadString(steamId, sizeof(steamId)); + delete pk; + + int client = userId ? GetClientOfUserId(userId) : 0; + bool validClient = !userId || client; + + if (!results) { + if (validClient) { + PrintToChat(client, "[SM] Command Database Query Error"); + } + LogError("Failed to query database: %s", error); + return; + } + if (!validClient) { + return; + } + char name[64]; + char class [64]; + int health, healthMax, steamID, damagedealt, damagedealtsession, kills, killssession, deaths, deathssession, bombsreset, bombsresetsession, sacrifices, sacrificessession; + char lastkilledname[128]; + char lastusedweapon[128]; + char killedbyname[128]; + char killedbyweapon[128]; + if (results.FetchRow()) { + results.FetchString(0, name, 64); //name + steamID = results.FetchInt(1); //steamid + results.FetchString(4, class, 64); //class + health = results.FetchInt(5); //health + healthMax = results.FetchInt(6); //health + damagedealt = results.FetchInt(7); //damage dealt + damagedealtsession = results.FetchInt(8); //damage dealt session + kills = results.FetchInt(9); //kills + killssession = results.FetchInt(10); //kills session + deaths = results.FetchInt(11); //deaths + deathssession = results.FetchInt(12); //deaths session + bombsreset = results.FetchInt(13); //bombs reset + bombsresetsession = results.FetchInt(14); //bombs reset session + sacrifices = results.FetchInt(15); //sacrifices + sacrificessession = results.FetchInt(16); //sacrifices session + results.FetchString(17, lastkilledname, sizeof(lastkilledname)); //last client killed + results.FetchString(18, lastusedweapon, sizeof(lastusedweapon)); //using weapon + results.FetchString(19, killedbyname, sizeof(killedbyname)); //last client that killed + results.FetchString(20, killedbyweapon, sizeof(killedbyweapon)); //using weapon + } + CPrintToChat(client, "\x07AAAAAA[CORE] Showing stats of %s [%s, %i/%i hp] || SteamID: %i ", name, class, health, healthMax, steamID); + CPrintToChat(client, "{white}Damage Dealt: %i (Session: %i) || Kills: %i (Session: %i) || Deaths: %i (Session: %i) || Bombs Reset: %i (Session: %i)", damagedealt, damagedealtsession, kills, killssession, deaths, deathssession, bombsreset, bombsresetsession); + CPrintToChat(client, "Sacrifices: %i(Session:%i) || Killed %s (using %s) || Last killed by: %s (using %s)", sacrifices, sacrificessession, lastkilledname, lastusedweapon, killedbyname, killedbyweapon); +} + +public void OnConfigsExecuted() { + if (!FB_Database) { + Database.Connect(Database_OnConnect, "ass"); + } +} + +//DB setup +public void Database_OnConnect(Database db, + const char[] error, any data) { + if (!db) { + LogError("Could not connect to the database: %s", error); + return; + } + char buffer[64]; + db.Driver.GetIdentifier(buffer, sizeof(buffer)); + if (!StrEqual(buffer, "mysql", false)) { + delete db; + LogError("Could not connect to the database: expected mysql database."); + return; + } + FB_Database = db; + FB_Database.Query(Database_FastQuery, "CREATE TABLE IF NOT EXISTS ass_activity(name TEXT, steamid INT UNSIGNED, date DATE, seconds INT UNSIGNED DEFAULT '0', class TEXT DEFAULT 'na', health TEXT DEFAULT '-1', maxHealth INT UNSIGNED DEFAULT '0', damagedealt INT UNSIGNED DEFAULT '0', damagedealtsession INT UNSIGNED DEFAULT '0', kills INT UNSIGNED DEFAULT '0', killssession INT UNSIGNED DEFAULT '0', deaths INT UNSIGNED DEFAULT '0', deathssession INT UNSIGNED DEFAULT '0', bombsreset INT UNSIGNED DEFAULT '0', bombsresetsession INT UNSIGNED DEFAULT '0', sacrifices INT UNSIGNED DEFAULT '0', sacrificessession INT UNSIGNED DEFAULT '0', lastkilledname TEXT DEFAULT 'na', lastweaponused TEXT DEFAULT 'na', killedbyname TEXT DEFAULT 'na', killedbyweapon TEXT DEFAULT 'na', soundprefs INT UNSIGNED DEFAULT '3', PRIMARY KEY (steamid));"); +} + +//Database Fastquery Manager +public void Database_FastQuery(Database db, DBResultSet results, + const char[] error, any data) { + if (!results) { + LogError("Failed to query database: %s", error); + } +} +public void Database_MergeDataError(Database db, any data, int numQueries, + const char[] error, int failIndex, any[] queryData) { + LogError("Failed to query database (transaction): %s", error); +} + +//When a client leaves +public void OnClientDisconnect(int client) { + if (!FB_Database) { + return; + } + int steamID = GetSteamAccountID(client); + if (!steamID || steamID <= 10000) { + return; + } + char query[256]; + char clientName[128]; + GetClientInfo(client, "name", clientName, 128); + Format(query, sizeof(query), "INSERT INTO ass_activity (name, steamid, date, seconds) VALUES ('%s', %d, CURRENT_DATE, %d) ON DUPLICATE KEY UPDATE name = '%s', seconds = seconds + VALUES(seconds);", clientName, steamID, GetClientMapTime(client), clientName); + PrintToServer("%s", query); + FB_Database.Query(Database_FastQuery, query); +} + +//Calculate time spent on server in seconds +int GetClientMapTime(int client) { + float clientTime = GetClientTime(client), gameTime = GetGameTime(); + if (clientTime > gameTime) { + return RoundToZero(gameTime); + } + + return RoundToZero(clientTime); +} + +//Clientprefs built in menu +public void FartsysSNDSelected(int client, CookieMenuAction action, any info, char[] buffer, int maxlen) { + if (action == CookieMenuAction_SelectOption) { + ShowFartsyMenu(client); + } +} + +// When a new client joins +public void OnClientPutInServer(int client) { + if (!IsFakeClient(client)) { + if (!FB_Database) { //Use defaults if no database + PrintToServer("No database detected, setting soundPreference for %N to default.", client); + soundPreference[client] = GetConVarInt(cvarSNDDefault); + return; + } + int steamID = GetSteamAccountID(client); + if (!steamID || steamID <= 10000) { + return; + } else { + if (!tickingClientHealth) { + PrintToServer("Creating timer for tickclienthealth"); + CreateTimer(1.0, TickClientHealth); + tickingClientHealth = true; + } + char query[1024]; + Format(query, sizeof(query), "INSERT INTO ass_activity (name, steamid, date, damagedealtsession, killssession, deathssession, bombsresetsession, sacrificessession) VALUES ('%N', %d, CURRENT_DATE, 0, 0, 0, 0, 0) ON DUPLICATE KEY UPDATE name = '%N', damagedealtsession = 0, killssession = 0, deathssession = 0, bombsresetsession = 0, sacrificessession = 0;", client, steamID, client); + FB_Database.Query(Database_FastQuery, query); + DataPack pk = new DataPack(); + pk.WriteCell(client ? GetClientUserId(client) : 0); + pk.WriteString("steamid"); + char queryID[256]; + Format(queryID, sizeof(queryID), "SELECT soundprefs from ass_activity WHERE steamid = '%d';", steamID); + FB_Database.Query(SQL_SNDPrefs, queryID, pk); + } + } else { + soundPreference[client] = 0; + } +} + +//Get client sound prefs +public void SQL_SNDPrefs(Database db, DBResultSet results, + const char[] error, any data) { + DataPack pk = view_as < DataPack > (data); + pk.Reset(); + int userId = pk.ReadCell(); + char steamId[64]; + pk.ReadString(steamId, sizeof(steamId)); + delete pk; + int client = userId ? GetClientOfUserId(userId) : 0; + bool validClient = !userId || client; + if (!results) { + LogError("Failed to query database: %s", error); + return; + } + if (!validClient) { + return; + } + if (results.FetchRow()) { + soundPreference[client] = results.FetchInt(0); //Set it + //PrintToServer("Client %N soundPreference was set to %i", client, soundPreference[client]); + } +} + +//Send client sound menu +public void ShowFartsyMenu(int client) { + Menu menu = new Menu(MenuHandlerFartsy, MENU_ACTIONS_DEFAULT); + char buffer[100]; + menu.SetTitle("FartsysAss Sound Menu"); + menu.AddItem(buffer, "Disable ALL"); + menu.AddItem(buffer, "Music Only"); + menu.AddItem(buffer, "Sound Effects Only"); + menu.AddItem(buffer, "Enable ALL"); + menu.Display(client, 20); + menu.ExitButton = true; +} + +//Create menu +public Action Command_Sounds(int client, int args) { + int steamID = GetSteamAccountID(client); + if (!steamID || steamID <= 10000) { + return Plugin_Handled; + } else { + DataPack pk = new DataPack(); + pk.WriteCell(client ? GetClientUserId(client) : 0); + pk.WriteString("steamid"); + char queryID[256]; + Format(queryID, sizeof(queryID), "SELECT soundprefs from ass_activity WHERE steamid = '%d';", steamID); + FB_Database.Query(SQL_SNDPrefs, queryID, pk); + ShowFartsyMenu(client); + switch (soundPreference[client]) { + case 0: { + PrintToChat(client, "Sounds are currently DISABLED."); + } + case 1: { + PrintToChat(client, "Sounds are currently MUSIC ONLY."); + } + case 2: { + PrintToChat(client, "Sounds are currently SOUND EFFECTS ONLY."); + } + case 3: { + PrintToChat(client, "Sounds are currently ALL ON."); + } + case 4: { + PrintToChat(client, "Somehow your sound preference was stored as non-existent 5... Please configure your sounds."); + } + } + return Plugin_Handled; + } +} + +// This selects or disables the sounds +public int MenuHandlerFartsy(Menu menu, MenuAction action, int param1, int param2) { + if (action == MenuAction_Select) { + char query[256]; + int steamID = GetSteamAccountID(param1); + if (!FB_Database || !steamID) { + return; + } else { + Format(query, sizeof(query), "UPDATE ass_activity SET soundprefs = '%i' WHERE steamid = '%d';", param2, steamID); + FB_Database.Query(Database_FastQuery, query); + soundPreference[param1] = param2; + Command_Sounds(param1, 0); + } + } else if (action == MenuAction_End) { + CloseHandle(menu); + } +} + +//Fartsy's A.S.S +public Action Command_SacrificePointShop(int client, int args) { + ShowFartsysAss(client); + return Plugin_Handled; +} + +//Fartsy's A.S.S +public void ShowFartsysAss(int client) { + if (sacPoints <= 9 || !isWave) { + if (isWave) { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {red}ERROR: You do not have enough sacPoints. This command requires at least {white}10{red}. You have {white}%i{red}.", sacPoints); + } else { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}The sacrificial points counter is currently at %i of %i maximum for this wave.", sacPoints, sacPointsMax); + } + } else { + Menu menu = new Menu(MenuHandlerFartsysAss, MENU_ACTIONS_DEFAULT); + char buffer[100]; + menu.SetTitle("Fartsy's Annihilation Supply Shop"); + menu.ExitButton = true; + switch (sacPoints) { + case 10, 11, 12, 13, 14, 15, 16, 17, 18, 19: { + menu.AddItem(buffer, "[10] Kissone Bath Salts"); + menu.Display(client, 20); + } + case 20, 21, 22, 23, 24, 25, 26, 27, 28, 29: { + menu.AddItem(buffer, "[10] Kissone Bath Salts"); + menu.AddItem(buffer, "[20] Instant Fat Man"); + menu.Display(client, 20); + } + case 30, 31, 32, 33, 34, 35, 36, 37, 38, 39: { + menu.AddItem(buffer, "[10] Kissone Bath Salts"); + menu.AddItem(buffer, "[20] Instant Fat Man"); + menu.AddItem(buffer, "[30] Summon Goobbue or Kirby"); + menu.Display(client, 20); + } + case 40, 41, 42, 43, 44, 45, 46, 47, 48, 49: { + menu.AddItem(buffer, "[10] Kissone Bath Salts"); + menu.AddItem(buffer, "[20] Instant Fat Man"); + menu.AddItem(buffer, "[30] Summon Goobbue or Kirby"); + menu.AddItem(buffer, "[40] Explosives Paradise"); + menu.Display(client, 20); + } + case 50, 51, 52, 53, 54, 55, 56, 57, 58, 59: { + menu.AddItem(buffer, "[10] Kissone Bath Salts"); + menu.AddItem(buffer, "[20] Instant Fat Man"); + menu.AddItem(buffer, "[30] Summon Goobbue or Kirby"); + menu.AddItem(buffer, "[40] Explosives Paradise"); + menu.AddItem(buffer, "[50] Ass Gas"); + menu.AddItem(buffer, "[50] Banish Tornadoes"); + menu.Display(client, 20); + } + case 60, 61, 62, 63, 64, 65, 66, 67, 68, 69: { + menu.AddItem(buffer, "[10] Kissone Bath Salts"); + menu.AddItem(buffer, "[20] Instant Fat Man"); + menu.AddItem(buffer, "[30] Summon Goobbue or Kirby"); + menu.AddItem(buffer, "[40] Explosives Paradise"); + menu.AddItem(buffer, "[50] Ass Gas"); + menu.AddItem(buffer, "[50] Banish Tornadoes"); + menu.AddItem(buffer, "[60] Total Atomic Annihilation"); + menu.Display(client, 20); + } + case 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99: { + menu.AddItem(buffer, "[10] Kissone Bath Salts"); + menu.AddItem(buffer, "[20] Instant Fat Man"); + menu.AddItem(buffer, "[30] Summon Goobbue or Kirby"); + menu.AddItem(buffer, "[40] Explosives Paradise"); + menu.AddItem(buffer, "[50] Ass Gas"); + menu.AddItem(buffer, "[50] Banish Tornadoes"); + menu.AddItem(buffer, "[60] Total Atomic Annihilation"); + menu.AddItem(buffer, "[70] Meteorites"); + menu.AddItem(buffer, "[75] 150,000 UbUp Cash"); + menu.Display(client, 20); + } + case 100: { + menu.AddItem(buffer, "[10] Kissone Bath Salts"); + menu.AddItem(buffer, "[20] Instant Fat Man"); + menu.AddItem(buffer, "[30] Summon Goobbue or Kirby"); + menu.AddItem(buffer, "[40] Explosives Paradise"); + menu.AddItem(buffer, "[50] Ass Gas"); + menu.AddItem(buffer, "[50] Banish Tornadoes"); + menu.AddItem(buffer, "[60] Total Atomic Annihilation"); + menu.AddItem(buffer, "[70] Meteorites"); + menu.AddItem(buffer, "[75] 150,000 UbUp Cash"); + menu.AddItem(buffer, "[100] Professor Fartsalot"); + menu.Display(client, 20); + } + } + } +} + +//Also Fartsy's A.S.S +public int MenuHandlerFartsysAss(Menu menu, MenuAction action, int param1, int param2) { + if (action == MenuAction_Select) { + //PrintToChatAll("Got %i", param2); + switch (param2) { + case 0: { + if (sacPoints <= 9) { + return; + } else { + ServerCommand("fb_operator 30"); + } + } + case 1: { + if (sacPoints <= 19) { + return; + } else { + ServerCommand("fb_operator 31"); + } + } + case 2: { + if (sacPoints <= 29) { + return; + } else { + ServerCommand("fb_operator 32"); + } + } + case 3: { + if (sacPoints <= 39) { + return; + } else { + ServerCommand("fb_operator 33"); + } + } + case 4: { + if (sacPoints <= 49) { + return; + } else { + ServerCommand("fb_operator 34"); + } + } + case 5: { + if (sacPoints <= 49) { + return; + } else { + ServerCommand("fb_operator 35"); + } + } + case 6: { + if (sacPoints <= 59) { + return; + } else { + ServerCommand("fb_operator 36"); + } + } + case 7: { + if (sacPoints <= 69) { + return; + } else { + ServerCommand("fb_operator 37"); + } + + } + case 8: { + if (sacPoints <= 74) { + return; + } else { + ServerCommand("fb_operator 38"); + } + + } + case 9: { + if (sacPoints <= 99) { + return; + } else { + ServerCommand("fb_operator 39"); + } + + } + } + } else if (action == MenuAction_End) { + CloseHandle(menu); + } +} + +//Now that command definitions are done, lets make some things happen. +public void OnMapStart() { + FireEntityInput("rain", "Alpha", "0", 0.0); + ServerCommand("fb_operator 1002"); + CreateTimer(1.0, SelectAdminTimer); +} + +//Repeating Timers +//Adverts for tips/tricks +public Action PerformAdverts(Handle timer) { + if (!isWave) { + CreateTimer(180.0, PerformAdverts); + int i = GetRandomInt(1, 7); + switch (i) { + case 1: { + CPrintToChatAll("{darkviolet}[{aqua}CORE{darkviolet}] {white}We have a Discord server: {forestgreen}https://discord.com/invite/SkHaeMH"); + } + case 2: { + CPrintToChatAll("{darkviolet}[{aqua}CORE{darkviolet}] {white}Remember to buy your upgrades using {forestgreen}!buy"); + } + case 3: { + //CPrintToChatAll("{darkviolet}[{aqua}CORE{darkviolet}] {white}If this is your first time here, please run console command {forestgreen}snd_restart {white}for safety. Otherwise, you might {red}crash{white}!"); + CPrintToChatAll("{darkviolet}[{aqua}CORE{darkviolet}] {white}You may invoke {forestgreen}!sounds {white}to configure what sounds you hear from the plugin, or {forestgreen}!stats{white} to see your stats."); + } + case 4: { + CPrintToChatAll("{darkviolet}[{aqua}CORE{darkviolet}] {white}Advanced users may quick buy upgrades using {forestgreen}!qbuy"); + } + case 5: { + CPrintToChatAll("{darkviolet}[{aqua}CORE{darkviolet}] {white}Don't forget to buy {forestgreen}protection upgrades {white}and {forestgreen}ammo regen{white}(if applicable)!"); + } + case 6: { + CPrintToChatAll("{darkviolet}[{aqua}CORE{darkviolet}] {white}TIP: As a {red}DEFENDER{white}, pushing your team's {forestgreen}payload {white}is crucial to wrecking havoc on the robots!"); + } + case 7: { + CPrintToChatAll("{darkviolet}[{aqua}CORE{darkviolet}] {white}Remember, if someone is being abusive, you may always invoke {forestgreen}!calladmin{white}."); + } + case 8: { + CPrintToChatAll("{darkviolet}[{aqua}CORE{darkviolet}] {white}You may always invoke {forestgreen}!return{white} to be returned to spawn."); + } + } + } + return Plugin_Stop; +} + +//Adverts for wave information +public Action PerformWaveAdverts(Handle timer) { + if (isWave) { + CreateTimer(2.5, PerformWaveAdverts); + for (int i = 1; i <= MaxClients; i++) { + switch (bombStatus) { + case 8, 16, 24, 32, 40, 48, 56, 64: { + if (TornadoWarningIssued && IsClientInGame(i)) { + if (bombProgression) { + PrintHintText(i, "Payload: MOVING (%i/%i) | !sacpoints: %i/%i \n Music: %s (%i) \n\n[TORNADO WARNING]", bombStatus, bombStatusMax, sacPoints, sacPointsMax, songName, ticksMusic); + StopSound(i, SNDCHAN_STATIC, "UI/hint.wav"); + } else { + PrintHintText(i, "Payload: READY (%i/%i) | !sacpoints: %i/%i \n Music: %s (%i) \n\n[TORNADO WARNING]", bombStatus, bombStatusMax, sacPoints, sacPointsMax, songName, ticksMusic); + StopSound(i, SNDCHAN_STATIC, "UI/hint.wav"); + } + } else if (bombProgression && IsClientInGame(i)) { + PrintHintText(i, "Payload: MOVING (%i/%i) | !sacpoints: %i/%i \n Music: %s (%i)", bombStatus, bombStatusMax, sacPoints, sacPointsMax, songName, ticksMusic); + StopSound(i, SNDCHAN_STATIC, "UI/hint.wav"); + } else if (IsClientInGame(i)) { + PrintHintText(i, "Payload: READY (%i/%i) | !sacpoints: %i/%i \n Music: %s (%i)", bombStatus, bombStatusMax, sacPoints, sacPointsMax, songName, ticksMusic); + StopSound(i, SNDCHAN_STATIC, "UI/hint.wav"); + } + } + case 0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 25, 26, 27, 28, 29, 30, 31, 33, 34, 35, 36, 37, 38, 39, 41, 42, 43, 44, 45, 46, 47, 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60, 61, 62, 63: { + if (TornadoWarningIssued && IsClientInGame(i)) { + PrintHintText(i, "Payload: %i/%i | !sacpoints: %i/%i \n Music: %s (%i) \n\n[TORNADO WARNING]", bombStatus, bombStatusMax, sacPoints, sacPointsMax, songName, ticksMusic); + StopSound(i, SNDCHAN_STATIC, "UI/hint.wav"); + } else if (IsClientInGame(i)) { + PrintHintText(i, "Payload: %i/%i | !sacpoints: %i/%i \n Music: %s (%i)", bombStatus, bombStatusMax, sacPoints, sacPointsMax, songName, ticksMusic); + StopSound(i, SNDCHAN_STATIC, "UI/hint.wav"); + } + } + } + } + } + return Plugin_Stop; +} + +//Feature admin timer +public Action SelectAdminTimer(Handle timer) { + if (isWave) { + return Plugin_Stop; + } else { + ServerCommand("fb_operator 1002"); + float f = GetRandomFloat(40.0, 120.0); + CreateTimer(f, SelectAdminTimer); + return Plugin_Handled; + } +} + +//Brute Justice Timer +public Action OnslaughterATK(Handle timer) { + if (waveFlags != 1) { + return Plugin_Stop; + } else { + float f = GetRandomFloat(5.0, 7.0); + CreateTimer(f, OnslaughterATK); + FireEntityInput("BruteJusticeDefaultATK", "FireMultiple", "3", 5.0); + int i = GetRandomInt(1, 10); + switch (i) { + case 1, 6: { + FireEntityInput("BruteJusticeLaserParticle", "Start", "", 0.0); + CustomSoundEmitter(OnslaughterLaserSND, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("BruteJusticeLaser", "TurnOn", "", 1.40); + FireEntityInput("BruteJusticeLaserHurtAOE", "Enable", "", 1.40); + FireEntityInput("BruteJusticeLaserParticle", "Stop", "", 3.00); + FireEntityInput("BruteJusticeLaser", "TurnOff", "", 3.25); + FireEntityInput("BruteJusticeLaserHurtAOE", "Disable", "", 3.25); + } + case 2, 8: { + FireEntityInput("BruteJustice", "FireUser1", "", 0.0); + } + case 3, 7: { + FireEntityInput("BruteJusticeFlameParticle", "Start", "", 0.0); + FireEntityInput("BruteJusticeFlamethrowerHurtAOE", "Enable", "", 0.0); + CustomSoundEmitter(OnslaughterFlamePreATK, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("SND.BruteJusticeFlameATK", "PlaySound", "", 1.25); + FireEntityInput("BruteJusticeFlamethrowerHurtAOE", "Disable", "", 5.0); + FireEntityInput("BruteJusticeFlameParticle", "Stop", "", 5.0); + FireEntityInput("SND.BruteJusticeFlameATK", "FadeOut", ".25", 5.0); + CreateTimer(5.0, TimedOperator, 60); + FireEntityInput("SND.BruteJusticeFlameATK", "StopSound", "", 5.10); + } + case 4: { + FireEntityInput("BruteJusticeGrenadeSpammer", "FireMultiple", "10", 0.0); + FireEntityInput("BruteJusticeGrenadeSpammer", "FireMultiple", "10", 3.0); + FireEntityInput("BruteJusticeGrenadeSpammer", "FireMultiple", "10", 5.0); + } + case 5: { + FireEntityInput("BruteJusticeGrenadeSpammer", "FireMultiple", "50", 0.0); + } + case 9: { + FireEntityInput("BruteJusticeRocketSpammer", "FireOnce", "", 0.00); + FireEntityInput("BruteJusticeRocketSpammer", "FireOnce", "", 5.00); + } + case 10: { + FireEntityInput("BruteJusticeRocketSpammer", "FireMultiple", "10", 0.00); + FireEntityInput("BruteJusticeRocketSpammer", "FireMultiple", "10", 3.00); + FireEntityInput("BruteJusticeRocketSpammer", "FireMultiple", "10", 5.00); + } + } + } + return Plugin_Stop; +} + +//Onslaughter Health Timer +public Action OnslaughterHPTimer(Handle timer) { + if (waveFlags != 1) { + return Plugin_Stop; + } else { + int OnsEnt = FindEntityByClassname(-1, "tank_boss"); //Get index of Sephiroth Tank + int OnsRelayEnt = FindEntityByClassname(-1, "func_physbox"); //Get index of Onslaughter Relay + if (OnsEnt == -1) { + PrintToChatAll("Onslaughter not found"); + return Plugin_Handled; + } + int OnsHP = GetEntProp(OnsEnt, Prop_Data, "m_iHealth"); + int OnsRelayHP = GetEntProp(OnsRelayEnt, Prop_Data, "m_iHealth"); + CPrintToChatAll("{blue}Onslaughter's HP: %i (%i)", OnsHP, OnsRelayHP); + CreateTimer(10.0, OnslaughterHPTimer); + } + return Plugin_Stop; +} +//Sephiroth Timer +public Action SephATK(Handle timer) { + if (waveFlags != 2) { + return Plugin_Stop; + } else { + float f = GetRandomFloat(5.0, 10.0); + CreateTimer(f, SephATK); + FireEntityInput("SephArrows", "FireMultiple", "3", 5.0); + int i = GetRandomInt(1, 12); + switch (i) { + case 1, 6: { + CreateTimer(1.0, SephNukeTimer), + CreateTimer(7.0, TimedOperator, 11), + canSephNuke = true; + } + case 2, 8: { + CPrintToChatAll("{blue}Sephiroth: Say goodbye!"), + FireEntityInput("SephMeteor", "ForceSpawn", "", 0.0); + } + case 3, 7: { + FireEntityInput("SephNuke", "ForceSpawn", "", 0.0), + CustomSoundEmitter(DROPNUKE, SFXSNDLVL - 10, false, 0, 1.0, 100); + } + case 4: { + FireEntityInput("SephRocketSpammer", "FireMultiple", "10", 0.0); + FireEntityInput("SephRocketSpammer", "FireMultiple", "10", 3.0); + FireEntityInput("SkeleSpawner", "Enable", "", 0.0), + FireEntityInput("SkeleSpawner", "Disable", "", 20.0); + } + case 5: { + CPrintToChatAll("{blue}Sephiroth: Have at thee!"), + FireEntityInput("SephRocketSpammer", "FireMultiple", "50", 0.0); + } + case 9: { + FireEntityInput("SephRocketSpammer", "FireOnce", "", 0.00); + FireEntityInput("SephRocketSpammer", "FireOnce", "", 5.00); + } + case 10: { + CPrintToChatAll("{blue}Sephiroth: I dare say you will go off with a bang! HAHAHAHAHAHAHAA"), + FireEntityInput("SephRocketSpammer", "FireMultiple", "10", 0.00); + FireEntityInput("SephRocketSpammer", "FireMultiple", "10", 3.00); + FireEntityInput("SephRocketSpammer", "FireMultiple", "10", 5.00); + } + case 11: { + CPrintToChatAll("{blue}Sephiroth: Hahaha, let's see how you like THIS!"), + ServerCommand("sm_smash @red"); + } + case 12: { + CPrintToChatAll("{blue}Sephiroth: Ohhhh, you dare oppose ME?"); + } + } + } + return Plugin_Stop; +} + +//Sephiroth Health Timer +public Action SephHPTimer(Handle timer) { + if (waveFlags != 2) { + return Plugin_Stop; + } else { + int SephEnt = FindEntityByClassname(-1, "tank_boss"); //Get index of Sephiroth Tank + int SephRelayEnt = FindEntityByClassname(-1, "func_physbox"); //Get index of Seph Relay + if (SephEnt == -1) { + PrintToChatAll("Sephiroth not found"); + return Plugin_Handled; + } + int SephHP = GetEntProp(SephEnt, Prop_Data, "m_iHealth"); + int SephRelayHP = GetEntProp(SephRelayEnt, Prop_Data, "m_iHealth"); + CPrintToChatAll("{blue}Sephiroth's HP: %i (%i)", SephHP, SephRelayHP); + CreateTimer(10.0, SephHPTimer); + } + return Plugin_Stop; +} + +//Shark Timer +public Action SharkTimer(Handle timer) { + if (canSENTShark) { + FireEntityInput("SentSharkTorpedo", "ForceSpawn", "", 0.0); + float f = GetRandomFloat(2.0, 5.0); + CreateTimer(f, SharkTimer); + int i = GetRandomInt(1, 8); + switch (i) { + case 1: { + CustomSoundEmitter(SHARKSND01, SFXSNDLVL, false, 0, 1.0, 100); + } + case 2: { + CustomSoundEmitter(SHARKSND02, SFXSNDLVL, false, 0, 1.0, 100); + } + case 3: { + CustomSoundEmitter(SHARKSND03, SFXSNDLVL, false, 0, 1.0, 100); + } + case 4: { + CustomSoundEmitter(SHARKSND04, SFXSNDLVL, false, 0, 1.0, 100); + } + case 5: { + CustomSoundEmitter(SHARKSND05, SFXSNDLVL, false, 0, 1.0, 100); + } + case 6: { + CustomSoundEmitter(SHARKSND06, SFXSNDLVL, false, 0, 1.0, 100); + } + case 7: { + CustomSoundEmitter(SHARKSND07, SFXSNDLVL, false, 0, 1.0, 100); + } + case 8: { + CustomSoundEmitter(SHARKSND08, SFXSNDLVL, false, 0, 1.0, 100); + } + } + return Plugin_Handled; + } + return Plugin_Stop; +} + +//Storm +public Action RefireStorm(Handle timer) { + if (isWave) { + float f = GetRandomFloat(7.0, 17.0); + CreateTimer(f, RefireStorm); + ServerCommand("fb_operator 1003"); + int Thunder = GetRandomInt(1, 16); + switch (Thunder) { + case 1: { + CustomSoundEmitter(GLOBALTHUNDER01, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt00", "Enable", "", 0.0), + FireEntityInput("LightningHurt00", "Disable", "", 0.07); + } + case 2: { + CustomSoundEmitter(GLOBALTHUNDER02, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt01", "Enable", "", 0.0), + FireEntityInput("LightningHurt01", "Disable", "", 0.07); + } + case 3: { + CustomSoundEmitter(GLOBALTHUNDER03, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt02", "Enable", "", 0.0), + FireEntityInput("LightningHurt02", "Disable", "", 0.07); + } + case 4: { + CustomSoundEmitter(GLOBALTHUNDER04, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt03", "Enable", "", 0.0), + FireEntityInput("LightningHurt03", "Disable", "", 0.07); + } + case 5: { + CustomSoundEmitter(GLOBALTHUNDER05, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt04", "Enable", "", 0.0), + FireEntityInput("LightningHurt04", "Disable", "", 0.07); + } + case 6: { + CustomSoundEmitter(GLOBALTHUNDER06, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt05", "Enable", "", 0.0), + FireEntityInput("LightningHurt05", "Disable", "", 0.07); + } + case 7: { + CustomSoundEmitter(GLOBALTHUNDER07, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt06", "Enable", "", 0.0), + FireEntityInput("LightningHurt06", "Disable", "", 0.07); + } + case 8: { + CustomSoundEmitter(GLOBALTHUNDER08, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt07", "Enable", "", 0.0), + FireEntityInput("LightningHurt07", "Disable", "", 0.07); + } + case 9: { + CustomSoundEmitter(GLOBALTHUNDER01, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt08", "Enable", "", 0.0), + FireEntityInput("LightningHurt08", "Disable", "", 0.07); + } + case 10: { + CustomSoundEmitter(GLOBALTHUNDER02, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt09", "Enable", "", 0.0), + FireEntityInput("LightningHurt09", "Disable", "", 0.07); + } + case 11: { + CustomSoundEmitter(GLOBALTHUNDER03, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt0A", "Enable", "", 0.0), + FireEntityInput("LightningHurt0A", "Disable", "", 0.07); + } + case 12: { + CustomSoundEmitter(GLOBALTHUNDER04, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt0B", "Enable", "", 0.0), + FireEntityInput("LightningHurt0B", "Disable", "", 0.07); + } + case 13: { + CustomSoundEmitter(GLOBALTHUNDER05, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt0C", "Enable", "", 0.0), + FireEntityInput("LightningHurt0C", "Disable", "", 0.07); + } + case 14: { + CustomSoundEmitter(GLOBALTHUNDER06, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt0D", "Enable", "", 0.0), + FireEntityInput("LightningHurt0D", "Disable", "", 0.07); + } + case 15: { + CustomSoundEmitter(GLOBALTHUNDER07, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt0E", "Enable", "", 0.0), + FireEntityInput("LightningHurt0E", "Disable", "", 0.07); + } + case 16: { + CustomSoundEmitter(GLOBALTHUNDER08, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("LightningHurt0F", "Enable", "", 0.0), + FireEntityInput("LightningHurt0F", "Disable", "", 0.07); + } + } + } + return Plugin_Handled; +} + +//SpecTimer +public Action SpecTimer(Handle timer) { + if (isWave) { + int i = GetRandomInt(1, 6); + switch (i) { + case 1: { + FireEntityInput("Spec*", "Disable", "", 0.0), + FireEntityInput("Spec.Goobbue", "Enable", "", 0.1), + CPrintToChatAll("{fullblue} Legend tells of a Goobbue sproutling somewhere nearby..."); + } + case 2: { + FireEntityInput("Spec*", "Disable", "", 0.0), + FireEntityInput("Spec.Waffle", "Enable", "", 0.1), + CPrintToChatAll("{turquoise}Don't eat THESE..."); + } + case 3: { + FireEntityInput("Spec*", "Disable", "", 0.0), + FireEntityInput("Spec.Burrito", "Enable", "", 0.1), + CPrintToChatAll("{darkred}What's worse than Taco Bell?"); + } + case 4: { + FireEntityInput("Spec*", "Disable", "", 0.0), + FireEntityInput("Spec.Shroom", "Enable", "", 0.1), + CPrintToChatAll("{red}M{white}A{red}R{white}I{red}O {white}time!"); + } + case 5: { + FireEntityInput("Spec*", "Disable", "", 0.0); + FireEntityInput("Spec.BlueBall", "Enable", "", 0.1); + CPrintToChatAll("{white}A {fullblue}Blue Ball {white}lurks from afar..."); + } + case 6: { + FireEntityInput("Spec*", "Enable", "", 0.0), + CPrintToChatAll("{magenta}Is it a miracle? Is it {red}chaos{magenta}? WHO KNOWWWWWWS"); + } + } + float spDelay = GetRandomFloat(10.0, 30.0); + CreateTimer(spDelay, SpecTimer); + } + return Plugin_Stop; +} + +//SENTMeteor (Scripted Entity Meteors) +public Action SENTMeteorTimer(Handle timer) { + if (canSENTMeteors) { + CreateTimer(5.0, SENTMeteorTimer); + int i = GetRandomInt(1, 8); + switch (i) { + case 1: { + FireEntityInput("FB.SentMeteor01", "ForceSpawn", "", 0.0); + } + case 2: { + FireEntityInput("FB.SentMeteor02", "ForceSpawn", "", 0.0); + } + case 3: { + FireEntityInput("FB.SentMeteor03", "ForceSpawn", "", 0.0); + } + case 4: { + FireEntityInput("FB.SentMeteor04", "ForceSpawn", "", 0.0); + } + case 5: { + FireEntityInput("FB.SentMeteor05", "ForceSpawn", "", 0.0); + } + } + } + return Plugin_Stop; +} + +//SENTNukes (Scripted Entity Nukes) +public Action SENTNukeTimer(Handle timer) { + if (canSENTNukes) { + CustomSoundEmitter(DROPNUKE, SFXSNDLVL - 10, false, 0, 1.0, 100); + int i = GetRandomInt(1, 8); + switch (i) { + case 1: { + FireEntityInput("FB.SentNuke01", "ForceSpawn", "", 0.0); + } + case 2: { + FireEntityInput("FB.SentNuke02", "ForceSpawn", "", 0.0); + } + case 3: { + FireEntityInput("FB.SentNuke03", "ForceSpawn", "", 0.0); + } + case 4: { + FireEntityInput("FB.SentNuke04", "ForceSpawn", "", 0.0); + } + case 5: { + FireEntityInput("FB.SentNuke05", "ForceSpawn", "", 0.0); + } + } + float f = GetRandomFloat(1.5, 3.0); + CreateTimer(f, SENTNukeTimer); + } + return Plugin_Stop; +} + +//CrusaderSentNukes +public Action CrusaderNukeTimer(Handle timer) { + if (canCrusaderNuke) { + CustomSoundEmitter(DROPNUKE, SFXSNDLVL - 10, false, 0, 1.0, 100), + FireEntityInput("FB.CrusaderNuke", "ForceSpawn", "", 0.0); + float f = GetRandomFloat(1.5, 3.0); + CreateTimer(f, CrusaderNukeTimer); + } + return Plugin_Stop; +} + +//SephSentNukes +public Action SephNukeTimer(Handle timer) { + if (canSephNuke) { + CustomSoundEmitter(DROPNUKE, SFXSNDLVL - 10, false, 0, 1.0, 100), + FireEntityInput("SephNuke", "ForceSpawn", "", 0.0); + float f = GetRandomFloat(1.5, 3.0); + CreateTimer(f, SephNukeTimer); + } + return Plugin_Stop; +} + +//SENTStars (Scripted Entity Stars) +public Action SENTStarTimer(Handle timer) { + if (canSENTStars) { + int i = GetRandomInt(1, 5); + switch (i) { + case 1: { + FireEntityInput("FB.SentStar01", "ForceSpawn", "", 0.0); + } + case 2: { + FireEntityInput("FB.SentStar02", "ForceSpawn", "", 0.0); + } + case 3: { + FireEntityInput("FB.SentStar03", "ForceSpawn", "", 0.0); + } + case 4: { + FireEntityInput("FB.SentStar04", "ForceSpawn", "", 0.0); + } + case 5: { + FireEntityInput("FB.SentStar05", "ForceSpawn", "", 0.0); + } + } + float f = GetRandomFloat(0.75, 1.5); + CreateTimer(f, SENTStarTimer); + } + return Plugin_Stop; +} + +//Crusader Incoming Timer for Crusader +public Action CRUSADERINCOMING(Handle timer) { + if (!crusader || INCOMINGDISPLAYED > 17) { + INCOMINGDISPLAYED = 0; + return Plugin_Stop; + } else { + INCOMINGDISPLAYED++; + FireEntityInput("FB.INCOMING", "Display", "", 0.0); + CreateTimer(1.75, CRUSADERINCOMING); + } + return Plugin_Stop; +} + +//Halloween Bosses +public Action HWBosses(Handle timer) { + if (isWave && canHWBoss) { + int i = GetRandomInt(1, 10); + switch (i) { + case 1: { + FireEntityInput("hhh_maker", "ForceSpawn", "", 0.0), + FireEntityInput("hhh_maker2", "ForceSpawn", "", 0.0); + } + case 2: { + FireEntityInput("hhh_maker2", "ForceSpawn", "", 0.0); + } + case 3: { + + FireEntityInput("hhh_maker2", "ForceSpawn", "", 0.0), + FireEntityInput("SkeleSpawner", "Enable", "", 0.0), + FireEntityInput("SkeleSpawner", "Disable", "", 10.0); + } + case 4: { + FireEntityInput("SkeleSpawner", "Enable", "", 0.0), + FireEntityInput("SkeleSpawner", "Disable", "", 10.0); + } + case 5: { + FireEntityInput("merasmus_maker", "ForceSpawn", "", 0.0), + FireEntityInput("hhh_maker2", "ForceSpawn", "", 0.0); + } + case 6: { + FireEntityInput("merasmus_maker", "ForceSpawn", "", 0.0), + FireEntityInput("monoculus_maker", "ForceSpawn", "", 0.0), + FireEntityInput("hhh_maker2", "ForceSpawn", "", 0.0); + } + case 7: { + FireEntityInput("monoculus_maker", "ForceSpawn", "", 0.0), + FireEntityInput("merasmus_maker", "ForceSpawn", "", 0.0); + } + case 8: { + FireEntityInput("SkeleSpawner", "Enable", "", 0.0), + FireEntityInput("SkeleSpawner", "Disable", "", 30.0); + } + case 9: { + FireEntityInput("SkeleSpawner", "Enable", "", 0.0), + FireEntityInput("SkeleSpawner", "Disable", "", 60.0), + FireEntityInput("merasmus_maker", "ForceSpawn", "", 0.0), + FireEntityInput("monoculus_maker", "ForceSpawn", "", 0.0), + FireEntityInput("hhh_maker2", "ForceSpawn", "", 0.0); + } + case 10: { + FireEntityInput("monoculus_maker", "ForceSpawn", "", 0.0); + } + } + canHWBoss = false; + CreateTimer(60.0, HWBossesRefire); + } + return Plugin_Stop; +} + +//Repeat HWBosses Timer +public Action HWBossesRefire(Handle timer) { + if (isWave) { + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + return Plugin_Stop; +} + +//SacPoints (Add points to Sacrifice Points occasionally) +public Action SacrificePointsTimer(Handle timer) { + if (isWave && (sacPoints < sacPointsMax)) { + sacPoints++; + float f = GetRandomFloat(5.0, 30.0); + CreateTimer(f, SacrificePointsTimer); + } + return Plugin_Stop; +} + +//Track SacPoints and update entities every 0.1 seconds +public Action SacrificePointsUpdater(Handle timer) { + if (isWave) { + CreateTimer(0.1, SacrificePointsUpdater); + if (sacPoints > sacPointsMax) { + sacPoints = sacPointsMax; + } + } + return Plugin_Stop; +} + +//BombStatus (Add points to Bomb Status occasionally) +public Action BombStatusAddTimer(Handle timer) { + if (isWave && (bombStatus < bombStatusMax)) { + bombStatus++; + float f = GetRandomFloat(10.0, 45.0); + PrintToServer("[DEBUG] Creating a %f timer to give bomb status an update. Current target is %i", f, bombStatus); + CreateTimer(f, BombStatusAddTimer); + } + return Plugin_Stop; +} + +//Track bombStatus and update entities every 0.1 seconds +public Action BombStatusUpdater(Handle timer) { + if (isWave) { + CreateTimer(0.1, BombStatusUpdater); + if (bombStatus < bombStatusMax) { + switch (bombStatus) { + case 8: { + bombStatusMax = 8; + explodeType = 1; + canSENTShark = false; + FireEntityInput("Bombs*", "Disable", "", 0.0), + FireEntityInput("BombExplo*", "Disable", "", 0.0), + FireEntityInput("Delivery", "Unlock", "", 0.0), + FireEntityInput("Bombs.FreedomBomb", "Enable", "", 0.0), + CustomSoundEmitter(TRIGGERSCORE, SFXSNDLVL, false, 0, 1.0, 100), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team's {red}FREEDOM BOMB {forestgreen}is now available for deployment!"); + } + case 16: { + bombStatusMax = 16; + explodeType = 2; + canSENTShark = false; + FireEntityInput("Bombs*", "Disable", "", 0.0), + FireEntityInput("BombExplo*", "Disable", "", 0.0), + FireEntityInput("Bombs.ElonBust", "Enable", "", 0.0), + FireEntityInput("Delivery", "Unlock", "", 0.0), + CustomSoundEmitter(TRIGGERSCORE, SFXSNDLVL, false, 0, 1.0, 100), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team's {red}ELON BUST {forestgreen}is now available for deployment!"); + } + case 24: { + bombStatusMax = 24; + explodeType = 3; + canSENTShark = false; + FireEntityInput("Bombs*", "Disable", "", 0.0), + FireEntityInput("BombExplo*", "Disable", "", 0.0), + FireEntityInput("Bombs.BathSalts", "Enable", "", 0.0), + FireEntityInput("Delivery", "Unlock", "", 0.0), + CustomSoundEmitter(TRIGGERSCORE, SFXSNDLVL, false, 0, 1.0, 100), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team's {red}BATH SALTS {forestgreen}are now available for deployment!"); + } + case 32: { + bombStatusMax = 32; + explodeType = 4; + canSENTShark = false; + FireEntityInput("Bombs*", "Disable", "", 0.0), + FireEntityInput("BombExplo*", "Disable", "", 0.0), + FireEntityInput("Bombs.FallingStar", "Enable", "", 0.0), + FireEntityInput("Delivery", "Unlock", "", 0.0), + CustomSoundEmitter(TRIGGERSCORE, SFXSNDLVL, false, 0, 1.0, 100), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team's \x07FFFF00FALLING STAR{forestgreen} is now available for deployment!"); + } + case 40: { + bombStatusMax = 40; + explodeType = 5; + canSENTShark = false; + FireEntityInput("Bombs*", "Disable", "", 0.0), + FireEntityInput("BombExplo*", "Disable", "", 0.0), + FireEntityInput("Bombs.MajorKong", "Enable", "", 0.0), + FireEntityInput("Delivery", "Unlock", "", 0.0), + CustomSoundEmitter(TRIGGERSCORE, SFXSNDLVL, false, 0, 1.0, 100), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team's {red}MAJOR KONG {forestgreen}is now available for deployment!"); + } + case 48: { + bombStatusMax = 48; + explodeType = 6; + canSENTShark = true; + FireEntityInput("Bombs*", "Disable", "", 0.0), + FireEntityInput("BombExplo*", "Disable", "", 0.0), + FireEntityInput("Bombs.SharkTorpedo", "Enable", "", 0.0), + FireEntityInput("BombExploShark", "Enable", "", 0.0), + FireEntityInput("Delivery", "Unlock", "", 0.0), + CustomSoundEmitter(TRIGGERSCORE, SFXSNDLVL, false, 0, 1.0, 100), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team's {aqua}SHARK {forestgreen}is now available for deployment!"); + } + case 56: { + bombStatusMax = 56; + explodeType = 7; + canSENTShark = false; + FireEntityInput("Bombs*", "Disable", "", 0.0), + FireEntityInput("BombExplo*", "Disable", "", 0.0), + FireEntityInput("Bombs.FatMan", "Enable", "", 0.0), + FireEntityInput("Delivery", "Unlock", "", 0.0), + CustomSoundEmitter(TRIGGERSCORE, SFXSNDLVL, false, 0, 1.0, 100), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team's {orange}FAT MAN {forestgreen}is now available for deployment!"); + } + case 64: { + bombStatusMax = 64; + explodeType = 8; + canSENTShark = false; + FireEntityInput("Bombs*", "Disable", "", 0.0), + FireEntityInput("BombExplo*", "Disable", "", 0.0), + FireEntityInput("Bombs.Hydrogen", "Enable", "", 0.0), + FireEntityInput("Delivery", "Unlock", "", 0.0), + CustomSoundEmitter(TRIGGERSCORE, SFXSNDLVL, false, 0, 1.0, 100), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team's {red}HYDROGEN {forestgreen}is now available for deployment!"); + } + } + } else if (bombStatus > bombStatusMax) { + bombStatus = bombStatusMax - 4; + } + return Plugin_Continue; + } + return Plugin_Stop; +} + +//RobotLaunchTimer (Randomly fling robots) +public Action RobotLaunchTimer(Handle timer) { + if (isWave) { + FireEntityInput("FB.RobotLauncher", "Enable", "", 0.0), + FireEntityInput("FB.RobotLauncher", "Disable", "", 7.5); + float f = GetRandomFloat(5.0, 30.0); + CreateTimer(f, RobotLaunchTimer); + } + return Plugin_Stop; +} + +//Command action definitions +//Get current song +public Action Command_GetCurrentSong(int client, int args) { + PrintToChat(client, "The current song is: %s", songName); + return Plugin_Handled; +} + +//Determine which bomb has been recently pushed and tell the client if a bomb is ready or not. +public Action Command_FBBombStatus(int client, int args) { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}The bomb status is currently %i, with a max of %i", bombStatus, bombStatusMax); + switch (bombStatus) { + case 0, 1, 2, 3, 4, 5, 6, 7: { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Bombs are {red}NOT READY{white}!"); + } + case 8: { + if (bombProgression) { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team is currently pushing a {red}FREEDOM BOMB {forestgreen}!"); + } else { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team has not deployed any bombs, however: Your team's {red}FREEDOM BOMB {forestgreen}is available for deployment!"); + } + } + case 9, 10, 11, 12, 13, 14, 15: { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed a {white}FREEDOM BOMB {forestgreen}. Please wait for the next bomb."); + } + case 16: { + if (bombProgression) { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team is currently pushing an {red}ELON BUST {forestgreen}!"); + } else { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed a {white}FREEDOM BOMB {forestgreen}. Your team's {red}ELON BUST {forestgreen}is available for deployment!"); + } + } + case 17, 18, 19, 20, 21, 22, 23: { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed {white}ELON BUST {forestgreen}. Please wait for the next bomb."); + } + case 24: { + if (bombProgression) { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team is currently pushing {red}BATH SALTS {forestgreen}!"); + } else { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed a {white}ELON BUST {forestgreen}. Your team's {red}BATH SALTS {forestgreen}are available for deployment!"); + } + } + case 25, 26, 27, 28, 29, 30, 31: { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed {white}BATH SALTS {forestgreen}. Please wait for the next bomb."); + } + case 32: { + if (bombProgression) { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team is currently pushing a {red}FALLING STAR {forestgreen}!"); + } else { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed {white}BATH SALTS {forestgreen}. Your team's {red}FALLING STAR {forestgreen}is available for deployment!"); + } + } + case 33, 34, 35, 36, 37, 38, 39: { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed a {white}FALLING STAR {forestgreen}. Please wait for the next bomb."); + } + case 40: { + if (bombProgression) { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team is currently pushing a {red}MAJOR KONG {forestgreen}!"); + } else { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed {white}FALLING STAR {forestgreen}. Your team's {red}MAJOR KONG {forestgreen}is available for deployment!"); + } + } + case 41, 42, 43, 44, 45, 46, 47: { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed a {white}MAJOR KONG {forestgreen}. Please wait for the next bomb."); + } + case 48: { + if (bombProgression) { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team is currently pushing a {red}SHARK {forestgreen}!"); + } else { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed {white}MAJOR KONG {forestgreen}. Your team's {red}SHARK {forestgreen}is available for deployment!"); + } + } + case 49, 50, 51, 52, 53, 54, 55: { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed a {white}SHARK {forestgreen}. Please wait for the next bomb."); + } + case 56: { + if (bombProgression) { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team is currently pushing a {red}FAT MAN {forestgreen}!"); + } else { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed a {white}SHARK {forestgreen}. Your team's {red}FAT MAN {forestgreen}is available for deployment!"); + } + } + case 57, 58, 59, 60, 61, 62, 63: { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed a {white}FAT MAN {forestgreen}. Please wait for the next bomb."); + } + case 64: { + if (bombProgression) { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team is delivering \x07FFFF00HYDROGEN {forestgreen}!"); + } else { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed a {red} FAT MAN {forestgreen}. Your team's \x07FFFF00HYDROGEN {forestgreen}is available for deployment!"); + } + } + case 65, 66, 67, 68, 69, 70, 71: { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Your team recently deployed a {white}HYDROGEN{forestgreen}. Bombs are automatically reset to preserve the replayable aspect of this game mode."); + } + case 72: { + CPrintToChatAll("{red}Something exceeded a maximum value!!! Apparently the bomb status is %i, with a maximum status of %i.", bombStatus, bombStatusMax); + } + } + return Plugin_Handled; +} + +//Return the client to spawn +public Action Command_Return(int client, int args) { + if (!IsPlayerAlive(client)) { + ReplyToCommand(client, "{red}[Core] You must be alive to use this command..."); + return Plugin_Handled; + } else { + char name[128]; + GetClientName(client, name, sizeof(name)); + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}Client {red}%s {white}began casting {darkviolet}/return{white}.", name); + CustomSoundEmitter(RETURNSND, SFXSNDLVL, false, 0, 1.0, 100); + CreateTimer(5.0, ReturnClient, client); + } + return Plugin_Handled; +} + +//Return the client to spawn +public Action ReturnClient(Handle timer, int clientID) { + TeleportEntity(clientID, Return, NULL_VECTOR, NULL_VECTOR); + if (soundPreference[clientID] >= 2) { + EmitSoundToClient(clientID, RETURNSUCCESS); + } + return Plugin_Handled; +} + +//Join us on Discord! +public Action Command_Discord(int client, int args) { + CPrintToChat(client, "{darkviolet}[{forestgreen}CORE{darkviolet}] {white}Our Discord server URL is {darkviolet}https://discord.com/invite/SkHaeMH{white}."), + ShowMOTDPanel(client, "FireHostRedux Discord", "https://discord.com/invite/SkHaeMH", MOTDPANEL_TYPE_URL); + return Plugin_Handled; +} + +//Events +//Check who died by what and announce it to chat. +public Action EventDeath(Event Spawn_Event, + const char[] Spawn_Name, bool Spawn_Broadcast) { + int client = GetClientOfUserId(Spawn_Event.GetInt("userid")); + int attacker = GetClientOfUserId(Spawn_Event.GetInt("attacker")); + char attackerName[64]; + char weapon[32]; + Spawn_Event.GetString("weapon", weapon, sizeof(weapon)); + GetClientName(attacker, attackerName, sizeof(attackerName)); + if (0 < client <= MaxClients && IsClientInGame(client)) { + int damagebits = Spawn_Event.GetInt("damagebits"); + //Find server name + Handle convar = FindConVar("hostname"); + char ServerName[64]; + GetConVarString(convar, ServerName, sizeof(ServerName)); + if (StrEqual(attackerName, ServerName)) { + attackerName = "[INTENTIONAL GAME DESIGN]"; + } + if (attacker > 0 && sacrificedByClient) { //Was the client Sacrificed? + SacrificeClient(client, attacker, bombReset); + sacrificedByClient = false; + } + if (!attacker) { + switch (damagebits) { + case 1: { //CRUSH + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N was crushed by a {red}FALLING ROCK FROM OUTER SPACE{white}!", client); + weapon = "Meteor to the Face"; + } + case 8: { //BURN + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N was {red}MELTED{white}.", client); + weapon = "Melted by Sharts or Ass Gas"; + } + case 16: { //FREEZE + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N was flattened out by a {red}TRAIN{white}!", client); + weapon = "Attempted Train Robbery"; + } + case 32: { //FALL + if (tornado) { + switch (GetClientTeam(client)) { + case 2: { + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N was {red}YEETED OUT INTO ORBIT{white}!", client); + weapon = "Yeeted into Orbit by a Tornado"; + } + case 3: { + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N was {red}YEETED OUT INTO ORBIT{white}! ({limegreen}+1 pt{white})", client); + sacPoints++; + int i = GetRandomInt(1, 16); + switch (i) { + case 1: { + CustomSoundEmitter(FALLSND01, SFXSNDLVL, false, 0, 1.0, 100); + } + case 2: { + CustomSoundEmitter(FALLSND02, SFXSNDLVL, false, 0, 1.0, 100); + } + case 3: { + CustomSoundEmitter(FALLSND03, SFXSNDLVL, false, 0, 1.0, 100); + } + case 4: { + CustomSoundEmitter(FALLSND04, SFXSNDLVL, false, 0, 1.0, 100); + } + case 5: { + CustomSoundEmitter(FALLSND05, SFXSNDLVL, false, 0, 1.0, 100); + } + case 6: { + CustomSoundEmitter(FALLSND06, SFXSNDLVL, false, 0, 1.0, 100); + } + case 7: { + CustomSoundEmitter(FALLSND07, SFXSNDLVL, false, 0, 1.0, 100); + } + case 8: { + CustomSoundEmitter(FALLSND08, SFXSNDLVL, false, 0, 1.0, 100); + } + case 9: { + CustomSoundEmitter(FALLSND09, SFXSNDLVL, false, 0, 1.0, 100); + } + case 10: { + CustomSoundEmitter(FALLSND0A, SFXSNDLVL, false, 0, 1.0, 100); + } + case 11: { + CustomSoundEmitter(FALLSND0B, SFXSNDLVL, false, 0, 1.0, 100), + FireEntityInput("FB.BlueKirbTemplate", "ForceSpawn", "", 0.0); + } + case 12: { + CustomSoundEmitter(FALLSND0C, SFXSNDLVL, false, 0, 1.0, 100); + } + case 13: { + CustomSoundEmitter(FALLSND0D, SFXSNDLVL, false, 0, 1.0, 100); + } + case 14: { + CustomSoundEmitter(FALLSND0E, SFXSNDLVL, false, 0, 1.0, 100); + } + case 15: { + CustomSoundEmitter(FALLSND0F, SFXSNDLVL, false, 0, 1.0, 100); + } + case 16: { + CustomSoundEmitter(FALLSND10, SFXSNDLVL, false, 0, 1.0, 100); + } + } + } + } + } else { + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N fell to a {red}CLUMSY PAINFUL DEATH{white}!", client); + weapon = "Tripped on a LEGO"; + } + } + case 64: { //BLAST + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N went {red} KABOOM{white}!", client); + weapon = "Gone Kaboom!"; + } + case 128: { //CLUB + if (canHindenburg) { + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N is {red}CRASHING THE HINDENBURG{white}!!!", client); + weapon = "Crashing the Hindenburg"; + } + } + case 256: { //SHOCK + CPrintToChatAll("{darkviolet}[{red}EXTERMINATUS{darkviolet}] {white}Client %N has humliated themselves with an {red}incorrect {white}key entry!", client); + weapon = "Failed FB Code Entry"; + int i = GetRandomInt(1, 16); + switch (i) { + case 1, 3, 10: { + FireEntityInput("BG.Meteorites1", "ForceSpawn", "", 0.0), + CPrintToChatAll("{darkviolet}[{red}WARN{darkviolet}] {white}Uh oh, a {red}METEOR{white}has been spotted coming towards Dovah's Ass!!!"), + FireEntityInput("bg.meteorite1", "StartForward", "", 0.1); + } + case 2, 5, 16: { + CreateTimer(0.5, TimedOperator, 71); + FireEntityInput("FB.TankTrain", "TeleportToPathTrack", "Tank01", 0.0), + FireEntityInput("FB.TankTrain", "StartForward", "", 0.25), + FireEntityInput("FB.TankTrain", "SetSpeed", "1", 0.35), + FireEntityInput("FB.Tank", "Enable", "", 1.0); + } + case 4, 8, 14: { + CustomSoundEmitter("ambient/alarms/train_horn_distant1.wav", SFXSNDLVL, false, 0, 1.0, 100), + FireEntityInput("TrainSND", "PlaySound", "", 0.0), + FireEntityInput("TrainDamage", "Enable", "", 0.0), + FireEntityInput("Train01", "Enable", "", 0.0), + CPrintToChatAll("{darkviolet}[{red}WARN{darkviolet}] {orange}KISSONE'S TRAIN{white}is {red}INCOMING{white}. Look out!"), + FireEntityInput("TrainTrain", "TeleportToPathTrack", "TrainTrack01", 0.0), + FireEntityInput("TrainTrain", "StartForward", "", 0.1); + } + case 6, 9: { + canTornado = true, + CreateTimer(1.0, TimedOperator, 41); + } + case 7, 13: { + CPrintToChatAll("{darkviolet}[{red}WARN{darkviolet}] {white}Uh oh, a {red}METEOR SHOWER{white}has been reported from Dovah's Ass!!!"); + canSENTMeteors = true, + CreateTimer(1.0, SENTMeteorTimer), + CreateTimer(30.0, TimedOperator, 12); + } + case 11: { + FireEntityInput("FB.Slice", "Enable", "", 0.0), + CustomSoundEmitter("ambient/sawblade_impact1.wav", SFXSNDLVL, false, 0, 1.0, 100), + FireEntityInput("FB.Slice", "Disable", "", 1.0); + } + case 12, 15: { + CPrintToChatAll("{darkviolet}[{red}WARN{darkviolet}] {white}Uh oh, it's begun to rain {red}ATOM BOMBS{white}! TAKE COVER!"), + canSENTNukes = true, + CreateTimer(1.0, SENTNukeTimer), + CreateTimer(30.0, TimedOperator, 13); + } + } + } + case 512: { //SONIC + CPrintToChatAll("{darkviolet}[{red}EXTERMINATUS{darkviolet}] {white}Client %N has sacrificed themselves with a {forestgreen}correct {white}key entry! Prepare your anus!", client); + ServerCommand("fb_operator 1006"); + weapon = "Correct FB Code Entry"; + } + case 1024: { //ENERGYBEAM + if (crusader) { + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N has been vaporized by {red}THE CRUSADER{white}!", client); + weapon = "Crusader"; + } else if (waveFlags == 1) { + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N has been vaporized by {red}THE ONSLAUGHTER{white}!", client); + weapon = "Onslaughter"; + } else { + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N has been vaporized by a {red}HIGH ENERGY PHOTON BEAM{white}!", client); + weapon = "HE Photon Beam"; + } + } + case 16384: { //DROWN + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N {red}DROWNED{white}.", client); + weapon = "Darwin Award for Drowning"; + } + case 32768: { //PARALYZE + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N has been crushed by a {darkviolet}MYSTERIOUS BLUE BALL{white}!", client); + weapon = "Mysterious Blue Ball"; + } + case 65536: { //NERVEGAS + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N has been {red}SLICED TO RIBBONS{white}!", client); + weapon = "FB Code Entry Failed"; + } + case 131072: { //POISON + CPrintToChat(client, "{darkviolet}[{red}CORE{darkviolet}] {white}Please don't sit {red}IDLE {white}in the FC Tavern."); + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N was killed for standing in the Tavern instead of helping their team!", client); + weapon = "Idle in FC Tavern..?"; + } + case 262144: { //RADIATION + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N was blown away by a {red}NUCLEAR EXPLOSION{white}!", client); + weapon = "Nuclear Explosion"; + } + case 524288: { //DROWNRECOVER + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N experienced {red}TACO BELL{white}!", client); + weapon = "Taco Bell"; + } + case 1048576: { //ACID + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}Client %N has been crushed by a {forestgreen}FALLING GOOBBUE FROM OUTER SPACE{white}!", client); + weapon = "Falling Goobbue"; + } + } + } + + //Log if a player killed someone + if (attacker != client) { + char query[256]; + int steamID; + if (attacker != 0) { + steamID = GetSteamAccountID(attacker); + } else { + steamID = 0; + } + if (!FB_Database) { + return Plugin_Handled; + } + if (!steamID || steamID <= 10000) { + int steamIDclient = GetSteamAccountID(client); + if (!steamIDclient || steamIDclient <= 10000) { + return Plugin_Handled; + } else { + char queryClient[256]; + Format(queryClient, sizeof(queryClient), "UPDATE ass_activity SET deaths = deaths + 1, deathssession = deathssession + 1 WHERE steamid = %i;", steamIDclient); + FB_Database.Query(Database_FastQuery, queryClient); + if (!StrEqual(weapon, "world")) { + Format(queryClient, sizeof(queryClient), "UPDATE ass_activity SET killedbyname = '%s', killedbyweapon = '%s' WHERE steamid = %i;", attackerName, weapon, steamIDclient); + FB_Database.Query(Database_FastQuery, queryClient); + } + return Plugin_Handled; + } + } + Format(query, sizeof(query), "UPDATE ass_activity SET kills = kills + 1, killssession = killssession + 1 WHERE steamid = %i;", steamID); + FB_Database.Query(Database_FastQuery, query); + if (!StrEqual(weapon, "world")) { + Format(query, sizeof(query), "UPDATE ass_activity SET lastkilledname = '%N', lastweaponused = '%s' WHERE steamid = %i;", client, weapon, steamID); + FB_Database.Query(Database_FastQuery, query); + } + } + return Plugin_Handled; + } + return Plugin_Handled; +} + +//Check who spawned and log their class +public Action EventSpawn(Event Spawn_Event, + const char[] Spawn_Name, bool Spawn_Broadcast) { + int client = GetClientOfUserId(Spawn_Event.GetInt("userid")); + if (IsValidClient(client)) { + char strClass[32]; + char query[256]; + int class = Spawn_Event.GetInt("class"); + int steamID = GetSteamAccountID(client); + if (!FB_Database || !steamID || !class) { + return Plugin_Handled; + } + switch (class) { + case 1: { + strClass = "scout"; + } + case 2: { + strClass = "sniper"; + } + case 3: { + strClass = "soldier"; + } + case 4: { + strClass = "demoman"; + } + case 5: { + strClass = "medic"; + } + case 6: { + strClass = "heavy"; + } + case 7: { + strClass = "pyro"; + } + case 8: { + strClass = "spy"; + } + case 9: { + strClass = "engineer"; + } + } + Format(query, sizeof(query), "UPDATE ass_activity SET class = '%s' WHERE steamid = %i;", strClass, steamID); + FB_Database.Query(Database_FastQuery, query); + } + return Plugin_Handled; +} + +//Silence cvar changes to minimize chat spam. +public Action Event_Cvar(Event event, + const char[] name, bool dontBroadcast) { + event.BroadcastDisabled = true; + return Plugin_Handled; +} + +//When we win +public Action EventWaveComplete(Event Spawn_Event, + const char[] Spawn_Name, bool Spawn_Broadcast) { + forceStopMusic = true; + BGMINDEX = 0; + bgmPlaying = false; + tbLoop = 0; + BGMINDEX = 0; + tbLoop = 0; + canCrusaderNuke = false; + canHindenburg = false; + canHWBoss = false; + canSephNuke = false; + canTornado = false; + isWave = false; + bombStatusMax = 7; + bombStatus = 5; + explodeType = 0; + sephiroth = false; + waveFlags = 0; + ServerCommand("fb_operator 1000"); + CreateTimer(1.0, PerformAdverts); + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}You've defeated the wave!"); + FireEntityInput("BTN.Sacrificial*", "Disable", "", 0.0), + FireEntityInput("BTN.Sacrificial*", "Color", "0", 0.0); + FireEntityInput("Barricade_Rebuild_Relay", "Trigger", "", 0.0); + FireEntityInput("FB.KP*", "Lock", "", 0.0); + FireEntityInput("OldSpawn", "Disable", "", 0.0); + FireEntityInput("NewSpawn", "Enable", "", 0.0); + FireEntityInput("CommonSpells", "Disable", "", 0.0); + FireEntityInput("RareSpells", "Disable", "", 0.0); + FireEntityInput("dovahsassprefer", "Disable", "", 0.0); + FireEntityInput("bombpath_left_arrows", "Disable", "", 0.0); + FireEntityInput("bombpath_right_arrows", "Disable", "", 0.0); + FireEntityInput("rain", "Alpha", "0", 0.0); + ServerCommand("fb_operator 1007"); + ServerCommand("fb_operator 1002"); + CreateTimer(40.0, SelectAdminTimer); + return Plugin_Handled; +} + +//Announce when we are in danger. +public Action EventWarning(Event Spawn_Event, + const char[] Spawn_Name, bool Spawn_Broadcast) { + CPrintToChatAll("{darkviolet}[{red}WARN{darkviolet}] {darkred}PROFESSOR'S ASS IS ABOUT TO BE DEPLOYED!!!"); + return Plugin_Handled; +} + +//When the wave fails +public Action EventWaveFailed(Event Spawn_Event, + const char[] Spawn_Name, bool Spawn_Broadcast) { + forceStopMusic = true; + BGMINDEX = 0; + bgmPlaying = false; + tbLoop = 0; + canCrusaderNuke = false; + canHindenburg = false; + canHWBoss = false; + canSephNuke = false; + canTornado = false; + isWave = false; + bombStatusMax = 7; + bombStatus = 5; + explodeType = 0; + sephiroth = false; + waveFlags = 0; + if (FailedCount == 0) { //Works around valve's way of firing EventWaveFailed four times when mission changes. Without this, BGM would play 4 times and any functions enclosed would also happen four times....... + FailedCount++; + ServerCommand("fb_operator 1000"); + CreateTimer(1.0, PerformAdverts); + CreateTimer(40.0, SelectAdminTimer); + } + FireEntityInput("rain", "Alpha", "0", 0.0); + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}Wave {red}failed {white}successfully!"); + FireEntityInput("BTN.Sacrificial*", "Disable", "", 0.0); + FireEntityInput("BTN.Sacrificial*", "Color", "0", 0.0); + FireEntityInput("BTN.Sacrificial*", "Disable", "", 0.0); + FireEntityInput("BTN.Sacrificial*", "Color", "0", 0.0); + FireEntityInput("Barricade_Rebuild_Relay", "Trigger", "", 0.0); + FireEntityInput("FB.KP*", "Lock", "", 0.0); + FireEntityInput("OldSpawn", "Disable", "", 0.0); + FireEntityInput("NewSpawn", "Enable", "", 0.0); + FireEntityInput("CommonSpells", "Disable", "", 0.0); + FireEntityInput("RareSpells", "Disable", "", 0.0); + FireEntityInput("dovahsassprefer", "Disable", "", 0.0); + FireEntityInput("bombpath_left_arrows", "Disable", "", 0.0); + FireEntityInput("bombpath_right_arrows", "Disable", "", 0.0); + FireEntityInput("rain", "Alpha", "0", 0.0); + ServerCommand("fb_operator 1007"); + ServerCommand("fb_operator 1002"); + return Plugin_Handled; +} + +//Log Damage! +public void Event_Playerhurt(Handle event, + const char[] name, bool dontBroadcast) { + int client = GetClientOfUserId(GetEventInt(event, "userid")); + int attacker = GetClientOfUserId(GetEventInt(event, "attacker")); + int damage = GetEventInt(event, "damageamount"); + int health = GetEventInt(event, "health"); + int attackerhp = GetClientHealth(attacker); + PrintToConsoleAll("[CORE-DBG] player hurt triggered by %N with %i hp. The attacker was %N with %i HP.", client, health, attacker, attackerhp); + if (IsValidClient(attacker) && attacker != client) { + char query[256]; + int steamID = GetSteamAccountID(attacker); + PrintToConsole(attacker, "Writing new myDmg value %i", damage); + if (!FB_Database) { + return; + } + if (!steamID) { + return; + } + Format(query, sizeof(query), "UPDATE ass_activity SET damagedealt = damagedealt + %i, damagedealtsession = damagedealtsession + %i WHERE steamid = %i;", damage, damage, steamID); + FB_Database.Query(Database_FastQuery, query); + } +} + +//Functions +//Create a temp entity and fire an input +public Action FireEntityInput(char[] strTargetname, char[] strInput, char[] strParameter, float flDelay) { + char strBuffer[255]; + Format(strBuffer, sizeof(strBuffer), "OnUser1 %s:%s:%s:%f:1", strTargetname, strInput, strParameter, flDelay); + //PrintToChatAll("{limegreen}[CORE] {white}Firing entity %s with input %s , a parameter override of %s , and delay of %f ...", strTargetname, strInput, strParameter, flDelay); + int entity = CreateEntityByName("info_target"); + if (IsValidEdict(entity)) { + DispatchSpawn(entity); + ActivateEntity(entity); + SetVariantString(strBuffer); + AcceptEntityInput(entity, "AddOutput"); + AcceptEntityInput(entity, "FireUser1"); + CreateTimer(0.0, DeleteEdict, entity); + return Plugin_Continue; + } + return Plugin_Handled; +} + +//Custom sound processor, this should make handling sounds easier. +// int flags: +// SND_NOFLAGS= 0, /**< Nothing */ +// SND_CHANGEVOL = 1, /**< Change sound volume */ +// SND_CHANGEPITCH = 2, /**< Change sound pitch */ +// SND_STOP = 3, /**< Stop the sound */ +// SND_SPAWNING = 4, /**< Used in some cases for ambients */ +// SND_DELAY = 5, /**< Sound has an initial delay */ +// SND_STOPLOOPING = 6, /**< Stop looping all sounds on the entity */ +// SND_SPEAKER = 7, /**< Being played by a mic through a speaker */ +// SND_SHOULDPAUSE = 8 /**< Pause if game is paused */ +public Action CustomSoundEmitter(char[] sndName, int SNDLVL, bool isBGM, int flags, float vol, int pitch) { + for (int i = 1; i <= MaxClients; i++) { + //If it's music + if (IsClientInGame(i) && !IsFakeClient(i) && (soundPreference[i] == 1 || soundPreference[i] == 3) && isBGM) { + EmitSoundToClient(i, sndName, _, SNDCHAN, SNDLVL, flags, vol, pitch, _, _, _, _, _); + } + //If it's sound effects + else if (IsClientInGame(i) && !IsFakeClient(i) && soundPreference[i] >= 2 && !isBGM) { + EmitSoundToClient(i, sndName, _, SNDCHAN, SNDLVL, flags, vol, pitch, _, _, _, _, _); + } + } + return Plugin_Handled; +} + +//Jump waves. +public Action JumpToWave(int wave_number) { + int flags = GetCommandFlags("tf_mvm_jump_to_wave"); + SetCommandFlags("tf_mvm_jump_to_wave", flags & ~FCVAR_CHEAT); + ServerCommand("tf_mvm_jump_to_wave %d", wave_number); + FakeClientCommand(0, ""); + SetCommandFlags("tf_mvm_jump_to_wave", flags | FCVAR_CHEAT); + return Plugin_Handled; +} + +//Remove edict allocated by temp entity +public Action DeleteEdict(Handle timer, any entity) { + if (IsValidEdict(entity)) RemoveEdict(entity); + return Plugin_Stop; +} + +//Sacrifice target and grant bonus points +public Action SacrificeClient(int client, int attacker, bool wasBombReset) { + if (attacker <= MaxClients && IsClientInGame(attacker) && wasBombReset == true) { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}Client {red}%N {white}has reset the ass! ({limegreen}+5 pts{white})", attacker); + bombReset = false; + char query[256]; + int steamID = GetSteamAccountID(attacker); + sacPoints += 5; + if (!FB_Database || !steamID) { + return Plugin_Handled; + } + Format(query, sizeof(query), "UPDATE ass_activity SET bombsreset = bombsreset + 1, bombsresetsession = bombsresetsession + 1 WHERE steamid = %i;", steamID); + FB_Database.Query(Database_FastQuery, query); + } else if (attacker <= MaxClients && IsClientInGame(attacker) && wasBombReset == false) { + int steamID = GetSteamAccountID(attacker); + if (!FB_Database || !steamID || !isWave) { + return Plugin_Handled; + } else { + char query[256]; + sacPoints++; + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}Client {red}%N {white}has sacrificed {blue}%N {white}for the ass! ({limegreen}+1 pt{white})", attacker, client); + Format(query, sizeof(query), "UPDATE ass_activity SET sacrifices = sacrifices + 1, sacrificessession = sacrificessession + 1 WHERE steamid = %i;", steamID); //Eventually we will want to replace this with sacrifices, sacrificessession. + FB_Database.Query(Database_FastQuery, query); + } + } + return Plugin_Handled; +} + +//Operator, core of the entire map +public Action Command_Operator(int args) { + char arg1[16]; + GetCmdArg(1, arg1, sizeof(arg1)); + int x = StringToInt(arg1); + //PrintToConsoleAll("Calling on fb_operator because arg1 was %i, and was stored in memory position %i", x, arg1); + switch (x) { + //When the map is complete + case 0: { + if (tacobell) { + CPrintToChatAll("WOWIE YOU DID IT! The server will restart in 30 seconds, prepare to do it again! LULW"); + CreateTimer(10.0, TimedOperator, 100); + } else { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}YOU HAVE SUCCESSFULLY COMPLETED PROF'S ASS ! THE SERVER WILL RESTART IN 10 SECONDS."); + CreateTimer(10.0, TimedOperator, 100); + } + } + //Prepare yourself! + case 1: { + char mapName[64]; + tacobell = false; + ServerCommand("fb_startmoney 50000"); + CPrintToChatAll("{darkviolet}[{yellow}INFO{darkviolet}] {red}PROFESSOR'S ASS {white}v0x1E. Prepare yourself for the unpredictable... [{limegreen}by TTV/ProfessorFartsalot{white}]"); + GetCurrentMap(mapName, sizeof(mapName)); + FireEntityInput("rain", "Alpha", "0", 0.0); + /*Prepare for the end times.... + if (StrContains(mapName, "R1A", true) || StrContains(mapName, "R1B", true) || StrContains(mapName, "R1C", true) || StrContains(mapName, "R1D", true) || StrContains(mapName, "R1E", true) || StrContains(mapName, "R1F", true)) { + int i = GetRandomInt(1, 7); + switch (i) { + case 1: { + CPrintToChatAll("{darkviolet}[{yellow}????{darkviolet}] {darkviolet}Fartsy... what have you done???"); + } + case 2: { + CPrintToChatAll("{darkviolet}[{yellow}????{darkviolet}] {darkviolet}The end is NEAR..."); + } + case 3: { + CPrintToChatAll("{darkviolet}[{yellow}????{darkviolet}] {darkviolet}The ass grows ever stronger..."); + } + case 4: { + CPrintToChatAll("{darkviolet}[{yellow}????{darkviolet}] {darkviolet}Muahahahahahahahaha, so MUCH POWER!"); + } + case 5: { + CPrintToChatAll("{darkviolet}[{yellow}????{darkviolet}] {darkviolet}Just a little further.... JUST.. a LITTLE... FURTHER!"); + } + case 6: { + CPrintToChatAll("{darkviolet}[{yellow}????{darkviolet}] {darkviolet}Investigate if you dare..."); + } + case 7: { + CPrintToChatAll("{darkviolet}[{yellow}????{darkviolet}] {darkviolet}Come... JOIN US. Throw wide the gates!"); + } + } + }*/ + } + //Wave init + case 2: { + int ent = FindEntityByClassname(-1, "tf_objective_resource"); //Get current wave, perform actions per wave. + if (ent == -1) { + LogMessage("tf_objective_resource not found"); + return Plugin_Handled; + } + curWave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineWaveCount")); + PerformWaveSetup(); + switch (curWave) { + case 1: { + if (tacobell) { + canTornado = true; + bombStatus = 0; + bombStatusMax = 10; + sacPointsMax = 90; + SetupMusic(10); + } else { + bombStatus = 0; + bombStatusMax = 10; + sacPointsMax = 90; + SetupMusic(2); + } + } + case 2, 9, 16: { + canHWBoss = true; + canTornado = true; + bombStatus = 4; + bombStatusMax = 18; + sacPointsMax = 90; + SetupMusic(3); + //CreateTimer(0.1, TimedOperator, 3); + FireEntityInput("Classic_Mode_Intel3", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel4", "Enable", "", 0.0); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + case 3, 10, 17: { + canHWBoss = true; + canTornado = true; + HWNMax = 360.0; + bombStatus = 7; + bombStatusMax = 26; + sacPointsMax = 90; + SetupMusic(4); + //CreateTimer(0.1, TimedOperator, 4); + FireEntityInput("Classic_Mode_Intel3", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel4", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel5", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel6", "Enable", "", 0.0); + float f = GetRandomFloat(60.0, 180.0); + CreateTimer(f, TimedOperator, 70); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + case 4, 11, 18: { + canHWBoss = true; + canTornado = true; + HWNMax = 360.0; + isWave = true; + bombStatus = 12; + bombStatusMax = 34; + sacPointsMax = 90; + SetupMusic(5); + //CreateTimer(0.1, TimedOperator, 5); + FireEntityInput("Classic_Mode_Intel3", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel4", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel5", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel6", "Enable", "", 0.0); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + case 5, 12, 19: { + canHWBoss = true; + canTornado = true; + HWNMax = 260.0; + HWNMin = 140.0; + isWave = true; + bombStatus = 14; + bombStatusMax = 42; + sacPointsMax = 100; + SetupMusic(6); + //CreateTimer(0.1, TimedOperator, 6); + FireEntityInput("Classic_Mode_Intel3", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel4", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel5", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel6", "Enable", "", 0.0); + FireEntityInput("w5_engie_hints", "Trigger", "", 3.0); + float f = GetRandomFloat(60.0, 180.0); + CreateTimer(f, TimedOperator, 70); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + case 6, 13, 20: { + canHWBoss = true; + canTornado = true; + HWNMax = 260.0; + HWNMin = 140.0; + isWave = true; + bombStatus = 20; + bombStatusMax = 50; + sacPointsMax = 100; + SetupMusic(7); + FireEntityInput("Classic_Mode_Intel3", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel4", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel5", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel6", "Enable", "", 0.0); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + case 7, 14, 21: { + canHWBoss = true; + canTornado = true; + HWNMax = 240.0; + HWNMin = 120.0; + isWave = true; + bombStatus = 28; + bombStatusMax = 58; + sacPointsMax = 100; + SetupMusic(8); + FireEntityInput("rain", "Alpha", "200", 0.0); + FireEntityInput("Classic_Mode_Intel3", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel4", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel5", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel6", "Enable", "", 0.0); + FireEntityInput("w5_engie_hints", "Trigger", "", 3.0); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + case 8, 15: { + canHWBoss = true; + canTornado = true; + HWNMax = 240.0; + HWNMin = 120.0; + bombStatus = 30; + bombStatusMax = 66; + sacPointsMax = 100; + SetupMusic(9); + FireEntityInput("Classic_Mode_Intel3", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel4", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel5", "Enable", "", 0.0); + FireEntityInput("Classic_Mode_Intel6", "Enable", "", 0.0); + float hwn = GetRandomFloat(HWNMin, HWNMax); + CreateTimer(hwn, HWBosses); + } + } + return Plugin_Handled; + } + //Force Tornado + case 3: { + if (isWave && canTornado && !tornado) { + CreateTimer(0.1, TimedOperator, 41); + PrintCenterTextAll("OH NOES... PREPARE YOUR ANUS!"); + } else { + PrintToServer("Error spawning manual tornado... Perhaps we are not in a wave, tornadoes are banished, or a tornado has already spawned???"); + } + return Plugin_Handled; + } + //Signal that previous boss should spawn. + case 4: { + waveFlags--; + } + //Signal that a boss should spawn + case 5: { + if (waveFlags < 0) { + waveFlags = 0; + } + switch (waveFlags) { + //Case 0, boss does not spawn. This is unreachable. + case 0: { + PrintToChatAll("Caught unhandled exception: waveFlags 0 but operator 5 was invoked."); + return Plugin_Handled; + } + //Case 1, summon Onslaughter. + case 1: { + //PrintToChatAll("Got 1. Spawning Onslaughter."), + FireEntityInput("FB.BruteJusticeTrain", "TeleportToPathTrack", "tank_path_a_10", 0.0), + FireEntityInput("FB.BruteJustice", "Enable", "", 3.0), + FireEntityInput("FB.BruteJusticeTrain", "StartForward", "", 3.0), + FireEntityInput("FB.BruteJusticeParticles", "Start", "", 3.0), + CreateTimer(5.0, OnslaughterATK), + FireEntityInput("tank_boss", "AddOutput", "rendermode 10", 3.0), + FireEntityInput("tank_boss", "AddOutput", "rendermode 10", 4.0), + FireEntityInput("tank_boss", "AddOutput", "rendermode 10", 5.0), + FireEntityInput("tank_boss", "AddOutput", "rendermode 10", 6.0), + FireEntityInput("tank_boss", "AddOutput", "rendermode 10", 7.0), + FireEntityInput("tank_boss", "AddOutput", "rendermode 10", 8.0); + CreateTimer(10.0, OnslaughterHPTimer); + } + //Case 2, summon Custom Boss 1 + case 2: { + FireEntityInput("FB.Sephiroth", "Enable", "", 0.0), + FireEntityInput("SephMeteor", "SetParent", "FB.Sephiroth", 0.0), + FireEntityInput("SephTrain", "SetSpeedReal", "12", 0.0), + FireEntityInput("SephTrain", "TeleportToPathTrack", "Seph01", 0.0), + FireEntityInput("SephTrain", "StartForward", "", 0.1), + FireEntityInput("SephTrain", "SetSpeedReal", "12", 20.5), + FireEntityInput("FB.SephParticles", "Start", "", 3.0), + FireEntityInput("tank_boss", "AddOutput", "rendermode 10", 3.0), + FireEntityInput("tank_boss", "AddOutput", "rendermode 10", 4.0), + FireEntityInput("tank_boss", "AddOutput", "rendermode 10", 5.0), + FireEntityInput("tank_boss", "AddOutput", "rendermode 10", 6.0), + FireEntityInput("tank_boss", "AddOutput", "rendermode 10", 7.0), + FireEntityInput("tank_boss", "AddOutput", "rendermode 10", 8.0), + FireEntityInput("FB.BruteJusticeDMGRelay", "Kill", "", 0.0); + int players = 0; + for (int i = 1; i <= MaxClients; i++) { + if (IsClientInGame(i) && !IsFakeClient(i)) + players++; + } + PrintToServer("We have %i player(s), setting boss attributes accordingly!", players); + switch (players) { + case 1: { + FireEntityInput("SephTrain", "SetSpeedReal", "40", 23.0), + FireEntityInput("tank_boss", "SetHealth", "409600", 1.0), + FireEntityInput("FB.SephDMGRelay", "SetHealth", "32768000", 1.0); + } + case 2: { + FireEntityInput("SephTrain", "SetSpeedReal", "35", 23.0), + FireEntityInput("tank_boss", "SetHealth", "614400", 1.0), + FireEntityInput("FB.SephDMGRelay", "SetHealth", "32768000", 1.0); + } + case 3: { + FireEntityInput("SephTrain", "SetSpeedReal", "35", 23.0), + FireEntityInput("tank_boss", "SetHealth", "614400", 1.0), + FireEntityInput("FB.SephDMGRelay", "SetHealth", "131072000", 1.0); + } + case 4: { + FireEntityInput("SephTrain", "SetSpeedReal", "30", 23.0), + FireEntityInput("tank_boss", "SetHealth", "819200", 1.0), + FireEntityInput("FB.SephDMGRelay", "SetHealth", "262144000", 1.0); + } + case 5, 6, 7, 8, 9, 10: { + FireEntityInput("SephTrain", "SetSpeedReal", "25", 23.0), + FireEntityInput("tank_boss", "SetHealth", "819200", 1.0), + FireEntityInput("FB.SephDMGRelay", "SetHealth", "655360000", 1.0); + } + } + CreateTimer(30.0, SephHPTimer); + } + } + } + //Signal that next boss should spawn + case 6: { + waveFlags++; + } + //Signal to fastforward boss spawn. + case 7: { + waveFlags = 2; + if (curWave == 8 && !tacobell) { + ServerCommand("fb_operator 1001"); + CreateTimer(0.0, TimedOperator, 8); + } + } + //When a tornado intersects a tank. + case 8: { + FireEntityInput("FB.FakeTankSpawner", "ForceSpawn", "", 0.1); + } + //Client was Sacrificed. + case 10: { + sacrificedByClient = true; + } + //Damage relay took damage + case 11: { + FireEntityInput("TankRelayDMG", "Enable", "", 0.0), + FireEntityInput("TankRelayDMG", "Disable", "", 0.5); + } + //dmg relay was killed + case 12: { + FireEntityInput("tank_boss", "SetHealth", "1", 0.0); + FireEntityInput("TankRelayDMG", "Enable", "", 0.1); + FireEntityInput("TankRelayDMG", "Enable", "", 0.5); + FireEntityInput("TankRelayDMG", "Enable", "", 1.0); + FireEntityInput("TankRelayDMG", "Disable", "", 10.0); + } + //Tank Destroyed (+1), includes disabling onslaughter. + case 13: { + switch (waveFlags) { + case 0: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}A tank has been destroyed. ({limegreen}+1 pt{white})"); + sacPoints++; + } + case 1: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {red}ONSLAUGHTER {white}has been destroyed. ({limegreen}+25 pts{white})"); + FireEntityInput("FB.BruteJustice", "Disable", "", 0.0); + FireEntityInput("FB.BruteJusticeTrain", "Stop", "", 0.0); + FireEntityInput("FB.BruteJusticeParticles", "Stop", "", 0.0); + FireEntityInput("FB.BruteJusticeDMGRelay", "Break", "", 0.0); + FireEntityInput("FB.BruteJusticeTrain", "TeleportToPathTrack", "tank_path_a_10", 0.5); + waveFlags = 0; + sacPoints += 25; + } + case 2: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {red}SEPHIROTH {white}has been destroyed. ({limegreen}+100 pts{white})"); + FireEntityInput("FB.Sephiroth", "Disable", "", 0.0), + FireEntityInput("SephTrain", "TeleportToPathTrack", "Seph01", 0.0), + FireEntityInput("SephTrain", "Stop", "", 0.0), + canSephNuke = false, + sacPoints += 100, + waveFlags = 0; + canTornado = false; + } + } + return Plugin_Handled; + } + //Bomb Reset (+5) + case 14: { + bombReset = true; + sacPoints += 5; + } + //Bomb Deployed + case 15: { + FireEntityInput("FB.PayloadWarning", "Disable", "", 0.0); + switch (explodeType) { + //Invalid + case 0: { + PrintToServer("Tried to detonate with a bomb size of zero!"); + } + //Small Explosion + case 1: { + FireEntityInput("RareSpells", "Enable", "", 0.0); + EmitSoundToAll(BMB1SND), + FireEntityInput("SmallExplosion", "Explode", "", 0.0), + FireEntityInput("SmallExploShake", "StartShake", "", 0.0), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}Small Bomb successfully pushed! ({limegreen}+2 pts{white})"); + sacPoints += 2, + bombStatusMax += 10, + CreateTimer(3.0, BombStatusAddTimer); + CustomSoundEmitter(COUNTDOWN, SFXSNDLVL, false, 0, 1.0, 100); + if (bombStatus >= bombStatusMax) { + return Plugin_Handled; + } else { + bombStatus += 2; + } + } + //Medium Explosion + case 2: { + FireEntityInput("RareSpells", "Enable", "", 0.0); + EmitSoundToAll(BMB2SND), + FireEntityInput("MediumExplosion", "Explode", "", 0.0), + FireEntityInput("MedExploShake", "StartShake", "", 0.0), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}Medium Bomb successfully pushed! ({limegreen}+5 pts{white})"); + sacPoints += 5, + bombStatusMax += 10, + CreateTimer(3.0, BombStatusAddTimer); + CustomSoundEmitter(COUNTDOWN, SFXSNDLVL, false, 0, 1.0, 100); + if (bombStatus >= bombStatusMax) { + return Plugin_Handled; + } else { + bombStatus += 2; + } + } + //Medium Explosion (Bath salts) + case 3: { + FireEntityInput("RareSpells", "Enable", "", 0.0); + EmitSoundToAll(BMB2SND), + FireEntityInput("MediumExplosion", "Explode", "", 0.0), + FireEntityInput("MedExploShake", "StartShake", "", 0.0), + ServerCommand("sm_freeze @blue 10"); + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}Medium Bomb successfully pushed! Bots froze for 10 seconds. ({limegreen}+5 pts{white})"); + sacPoints += 5, + bombStatusMax += 10, + CreateTimer(3.0, BombStatusAddTimer); + CustomSoundEmitter(COUNTDOWN, SFXSNDLVL, false, 0, 1.0, 100); + if (bombStatus >= bombStatusMax) { + return Plugin_Handled; + } else { + bombStatus += 2; + } + } + //Falling Star + case 4: { + FireEntityInput("RareSpells", "Enable", "", 0.0); + canSENTStars = true, + EmitSoundToAll(BMB2SND), + FireEntityInput("MediumExplosion", "Explode", "", 0.0), + FireEntityInput("MedExploShake", "StartShake", "", 0.0), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}Large Bomb successfully pushed! ({limegreen}+10 pts{white})"); + sacPoints += 10, + bombStatusMax += 10, + CreateTimer(3.0, BombStatusAddTimer); + CustomSoundEmitter(COUNTDOWN, SFXSNDLVL, false, 0, 1.0, 100), + CreateTimer(1.0, SENTStarTimer), + CreateTimer(60.0, TimedOperator, 14); + if (bombStatus >= bombStatusMax) { + return Plugin_Handled; + } else { + bombStatus += 2; + } + } + //Major Kong + case 5: { + FireEntityInput("RareSpells", "Enable", "", 0.0); + EmitSoundToAll(BMB4SND), + FireEntityInput("FB.Fade", "Fade", "", 1.7), + FireEntityInput("LargeExplosion", "Explode", "", 1.7), + FireEntityInput("LargeExplosionSound", "PlaySound", "", 1.7), + FireEntityInput("LargeExploShake", "StartShake", "", 1.7), + FireEntityInput("NukeAll", "Enable", "", 1.7), + FireEntityInput("NukeAll", "Disable", "", 3.0), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {red}NUCLEAR WARHEAD {white}successfully pushed! ({limegreen}+25 pts{white})"); + sacPoints += 25, + bombStatusMax += 10, + CreateTimer(3.0, BombStatusAddTimer); + CustomSoundEmitter(COUNTDOWN, SFXSNDLVL, false, 0, 1.0, 100); + if (bombStatus >= bombStatusMax) { + return Plugin_Handled; + } else { + bombStatus += 4; + } + } + //Large (shark) + case 6: { + FireEntityInput("RareSpells", "Enable", "", 0.0); + EmitSoundToAll(BMB3SND), + FireEntityInput("LargeExplosion", "Explode", "", 0.0), + FireEntityInput("LargeExploShake", "StartShake", "", 0.0), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}Heavy Bomb successfully pushed! ({limegreen}+15 pts{white})"); + sacPoints += 15, + bombStatusMax += 10, + CreateTimer(3.0, BombStatusAddTimer); + CustomSoundEmitter(COUNTDOWN, SFXSNDLVL, false, 0, 1.0, 100); + if (bombStatus >= bombStatusMax) { + return Plugin_Handled; + } else { + bombStatus += 4; + } + } + //FatMan + case 7: { + FireEntityInput("RareSpells", "Enable", "", 0.0); + EmitSoundToAll(HINDENBURGBOOM); + FireEntityInput("LargeExplosion", "Explode", "", 0.0), + FireEntityInput("LargeExploShake", "StartShake", "", 0.0), + FireEntityInput("NukeAll", "Enable", "", 0.0), + FireEntityInput("FB.Fade", "Fade", "", 0.0), + FireEntityInput("NukeAll", "Disable", "", 3.0), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {red}NUCLEAR WARHEAD{white}successfully pushed! ({limegreen}+25 pts{white})"); + sacPoints += 25, + bombStatusMax += 10, + CreateTimer(3.0, BombStatusAddTimer); + CreateTimer(15.0, SpecTimer); + CustomSoundEmitter(COUNTDOWN, SFXSNDLVL, false, 0, 1.0, 100); + if (bombStatus >= bombStatusMax) { + return Plugin_Handled; + } else { + bombStatus += 4; + } + } + //Hydrogen + case 8: { + FireEntityInput("RareSpells", "Enable", "", 0.0); + EmitSoundToAll(HINDENBURGBOOM); + FireEntityInput("LargeExplosion", "Explode", "", 0.0), + FireEntityInput("LargeExploShake", "StartShake", "", 0.0), + FireEntityInput("LargeExplosionSND", "PlaySound", "", 0.0), + FireEntityInput("NukeAll", "Enable", "", 0.0), + FireEntityInput("FB.Fade", "Fade", "", 0.0), + FireEntityInput("NukeAll", "Disable", "", 3.0), + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {red}HINDENBURG {white}successfully fueled! ({limegreen}+30 pts{white})"); + CPrintToChatAll("The {red}HINDENBURG {forestgreen}is now ready for flight!"); + FireEntityInput("DeliveryBurg", "Unlock", "", 0.0); + bombStatus = 0; + canHindenburg = true; + explodeType = 0; + CreateTimer(3.0, BombStatusAddTimer); + CustomSoundEmitter(COUNTDOWN, SFXSNDLVL, false, 0, 1.0, 100); + } + //Fartsy of the Seventh Taco Bell + case 69: { + FireEntityInput("NukeAll", "Enable", "", 0.0), + EmitSoundToAll(HINDENBURGBOOM); + FireEntityInput("FB.Fade", "Fade", "", 0.0), + FireEntityInput("NukeAll", "Disable", "", 2.0), + bombStatusMax = 64; + CreateTimer(5.0, TimedOperator, 99); + } + } + return Plugin_Handled; + } + //Tank deployed its bomb + case 16: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}A tank has deployed its bomb! ({limegreen}+1 pt{white})"); + } + //Shark Enable & notify bomb push began + case 20: { + bombProgression = true; + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Bomb push in progress."); + FireEntityInput("FB.PayloadWarning", "Enable", "", 0.0); + CreateTimer(3.0, SharkTimer); + } + //Shark Disable + case 21: { + bombProgression = false; + canSENTShark = false; + } + //HINDENBOOM ACTIVATION + case 28: { + EmitSoundToAll(BOOM); + FireEntityInput("HindenTrain", "StartForward", "", 0.0); + FireEntityInput("DeliveryBurg", "Lock", "", 0.0); + FireEntityInput("Boom", "Enable", "", 0.0); + FireEntityInput("Bombs.TheHindenburg", "Enable", "", 0.0); + FireEntityInput("Boom", "Disable", "", 1.0); + } + //HINDENBOOM!!! + case 29: { + CPrintToChatAll("{darkviolet}[{red}CORE{darkviolet}] {white}OH GOD, THEY'RE {red}CRASHING THE HINDENBURG{white}!!!"); + EmitSoundToAll(HINDENCRASH); + CreateTimer(4.0, TimedOperator, 21); + CreateTimer(7.0, TimedOperator, 37); + FireEntityInput("LargeExplosion", "Explode", "", 7.0); + FireEntityInput("LargeExploShake", "StartShake", "", 7.0); + FireEntityInput("NukeAll", "Enable", "", 7.0); + FireEntityInput("FB.Fade", "Fade", "", 7.0); + FireEntityInput("NukeAll", "Disable", "", 9.0); + FireEntityInput("Bombs.TheHindenburg", "Disable", "", 7.0); + FireEntityInput("HindenTrain", "TeleportToPathTrack", "Hinden01", 7.0); + FireEntityInput("HindenTrain", "Stop", "", 7.0); + CreateTimer(8.0, TimedOperator, 99); + bombStatus = 4; + bombStatusMax = 8; + explodeType = 0; + } + //Bath Salts spend + case 30: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}INSTANT BATH SALT DETONATION! BOTS ARE FROZEN FOR 10 SECONDS! ({red}-10 pts{white})"); + ServerCommand("sm_freeze @blue 10"); + sacPoints -= 10; + FireEntityInput("BTN.Sacrificial*", "Color", "0 0 0", 0.0), + FireEntityInput("BTN.Sacrificial01", "Lock", "", 0.0), + FireEntityInput("MedExploShake", "StartShake", "", 0.10), + FireEntityInput("MedExplosionSND", "PlaySound", "", 0.10), + FireEntityInput("MediumExplosion", "Explode", "", 0.10); + } + //Fat man spend + case 31: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}INSTANT FAT MAN DETONATION! ({red}-20 pts{white})"); + sacPoints -= 20; + FireEntityInput("BTN.Sacrificial*", "Color", "0 0 0", 0.0); + FireEntityInput("BTN.Sacrificial02", "Lock", "", 0.0); + FireEntityInput("LargeExplosion", "Explode", "", 0.0); + FireEntityInput("LargeExploShake", "StartShake", "", 0.0); + FireEntityInput("NukeAll", "Enable", "", 0.0); + EmitSoundToAll(HINDENBURGBOOM); + FireEntityInput("FB.Fade", "Fade", "", 0.0); + FireEntityInput("NukeAll", "Disable", "", 2.0); + } + //Goob/Kirb spend + case 32: { + int i = GetRandomInt(1, 2); + switch (i) { + case 1: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}GOOBBUE COMING IN FROM ORBIT! ({red}-30 pts{white})"); + sacPoints -= 30; + CustomSoundEmitter(SPEC01, SFXSNDLVL, false, 0, 1.0, 100); + CreateTimer(1.5, TimedOperator, 21); + FireEntityInput("FB.GiantGoobTemplate", "ForceSpawn", "", 3.0); + } + case 2: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}BLUE KIRBY FALLING OUT OF THE SKY! ({red}-30 pts{white})"); + sacPoints -= 30; + FireEntityInput("FB.BlueKirbTemplate", "ForceSpawn", "", 0.0); + CustomSoundEmitter(FALLSND0B, SFXSNDLVL, false, 0, 1.0, 100); + } + } + } + //Explosive paradise spend + case 33: { + CustomSoundEmitter(EXPLOSIVEPARADISE, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("FB.FadeBLCK", "Fade", "", 0.0); + ServerCommand("sm_evilrocket @blue"); + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}We're spending most our lives living in an EXPLOSIVE PARADISE! Robots will be launched into orbit, too! ({red}-40 pts{white})"); + FireEntityInput("NukeAll", "Enable", "", 11.50); + FireEntityInput("HUGEExplosion", "Explode", "", 11.50); + FireEntityInput("FB.Fade", "Fade", "", 11.50); + FireEntityInput("FB.ShakeBOOM", "StartShake", "", 11.50); + FireEntityInput("NukeAll", "Disable", "", 12.30); + sacPoints -= 40; + } + //Ass Gas spend + case 34: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}ANYTHING BUT THE ASS GAS!!!! ({red}-40 pts{white})"); + sacPoints -= 40; + FireEntityInput("HurtAll", "AddOutput", "damagetype 524288", 0.0); + FireEntityInput("FB.ShakeBOOM", "StartShake", "", 0.1); + FireEntityInput("HurtAll", "Enable", "", 0.1); + FireEntityInput("HurtAll", "Disable", "", 4.1); //Add a sound to this in the future. Maybe gas sound from gbombs? Maybe custom fart sounds? hmm.... + FireEntityInput("FB.ShakeBOOM", "StopShake", "", 4.1); + } + //Banish tornadoes for the wave + case 35: { + if (canTornado || tornado) { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}A PINK KIRBY HAS BANISHED TORNADOES FOR THIS WAVE! ({red}-50 pts{white})"); + ServerCommand("fb_operator 1005"); + canTornado = false; + sacPoints -= 50; + } else { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}A PINK KIRBY HAS BANISHED TORNADOES.... BUT CANTORNADO and TORNADO WERE BOTH FALSE... CALL A PROGRAMMER. ({red} -0 pts{white})"); + ServerCommand("fb_operator 1005"); + canTornado = false; + } + } + //Nuclear fallout spend + case 36: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}TOTAL ATOMIC ANNIHILATION. ({red}-60 pts{white})"); + sacPoints -= 60; + canSENTNukes = true; + CreateTimer(1.0, SENTNukeTimer); + CreateTimer(45.0, TimedOperator, 13); + } + //Meteor shower spend + case 37: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}COSMIC DEVASTATION IMMINENT. ({red}-70 pts{white})"); + sacPoints -= 70; + canSENTMeteors = true; + CreateTimer(1.0, SENTMeteorTimer); + CreateTimer(30.0, TimedOperator, 12); + } + //150K UbUp Cash + case 38: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}150K UbUp Cash Granted to {red}RED{white}! ({red}-75 pts{white})"); + sacPoints -= 75; + ServerCommand("sm_addcash @red 150000"); + } + //Fartsy of the Seventh Taco Bell + case 39: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}NOW PRESENTING... PROFESSOR FARTSALOT OF THE SEVENTH TACO BELL! ({red}-100 points{white})"); + sacPoints -= 100; + explodeType = 69; + FireEntityInput("Delivery", "Unlock", "", 0.0), + FireEntityInput("BombExplo*", "Disable", "", 0.0), + FireEntityInput("Bombs*", "Disable", "", 0.0), + FireEntityInput("Bombs.Professor", "Enable", "", 3.0); + } + //Found blue ball + case 40: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}What on earth IS that? It appears to be a... \x075050FFBLUE BALL{white}!"); + CustomSoundEmitter(FALLSND0B, SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("FB.BlueKirbTemplate", "ForceSpawn", "", 4.0); + CreateTimer(4.0, TimedOperator, 21); + } + //Found burrito + case 41: { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Why would you even eat {red}The Forbidden Burrito{white}?"); + CustomSoundEmitter("vo/sandwicheat09.mp3", SFXSNDLVL, false, 0, 1.0, 100); + FireEntityInput("HurtAll", "AddOutput", "damagetype 8", 0.0); + FireEntityInput("HurtAll", "Enable", "", 4.0); + FireEntityInput("HurtAll", "Disable", "", 8.0); + } + //Found goobbue + case 42: { + CustomSoundEmitter(SPEC01, SFXSNDLVL, false, 0, 1.0, 100); + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}ALL HAIL \x07FF00FFGOOBBUE{forestgreen}!"); + CreateTimer(4.0, TimedOperator, 21); + FireEntityInput("FB.GiantGoobTemplate", "ForceSpawn", "", 4.0); + } + //Found Mario + case 43: { + CustomSoundEmitter(SPEC02, SFXSNDLVL, false, 0, 1.0, 100); + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Welp, someone is playing \x0700FF00Mario{white}..."); + } + //Found Waffle + case 44: { + CustomSoundEmitter(SPEC03, SFXSNDLVL, false, 0, 1.0, 100); + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {forestgreen}Oh no, someone has found and (probably) consumed a {red}WAFFLE OF MASS DESTRUCTION{white}!"); + FireEntityInput("HurtAll", "AddOutput", "damagetype 262144", 10.0); + FireEntityInput("FB.ShakeBOOM", "StartShake", "", 10.3); + FireEntityInput("HUGEExplosion", "Explode", "", 10.3); + FireEntityInput("FB.Fade", "Fade", "", 10.3); + FireEntityInput("HurtAll", "Enable", "", 10.3); + FireEntityInput("HurtAll", "Disable", "", 12.3); + } + //Medium Explosion (defined again, but we aren't using a bomb this time) + case 51: { + CustomSoundEmitter(BMB3SND, SFXSNDLVL, false, 0, 1.0, 100); + } + //Probably for the hindenburg... EDIT: NOPE. THIS IS FOR KIRB LANDING ON THE GROUND + case 52: { + EmitSoundToAll(HINDENBURGBOOM); + FireEntityInput("FB.BOOM", "StartShake", "", 0.0); + FireEntityInput("BlueBall*", "Kill", "", 0.0); + FireEntityInput("HUGEExplosion", "Explode", "", 0.0); + FireEntityInput("BlueKirb", "Kill", "", 0.0); + FireEntityInput("HurtAll", "AddOutput", "damagetype 32768", 0.0); + FireEntityInput("HurtAll", "Enable", "", 0.1); + FireEntityInput("HurtAll", "Disable", "", 2.1); + } + //Giant Goobbue + case 53: { + EmitSoundToAll(HINDENBURGBOOM); + FireEntityInput("FB.BOOM", "StartShake", "", 0.0); + FireEntityInput("GiantGoob*", "Kill", "", 0.0); + FireEntityInput("HUGEExplosion", "Explode", "", 0.0); + FireEntityInput("HurtAll", "AddOutput", "damagetype 1048576", 0.0); + FireEntityInput("HurtAll", "Enable", "", 0.1); + FireEntityInput("HurtAll", "Disable", "", 2.1); + } + //Prev wave + case 98: { + int ent = FindEntityByClassname(-1, "tf_objective_resource"); + if (ent == -1) { + LogMessage("tf_objective_resource not found"); + return Plugin_Handled; + } + + int current_wave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineWaveCount")); + int max_wave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineMaxWaveCount")); + int prev_wave = current_wave - 1; + if (prev_wave >= max_wave) { + CPrintToChatAll("{red}[ERROR] {white}HOW THE HELL DID WE GET HERE?!"); + return Plugin_Handled; + } + + if (prev_wave < 1) { + CPrintToChatAll("{red}[ERROR] {white}WE CAN'T JUMP TO WAVE 0, WHY WOULD YOU TRY THAT??"); + return Plugin_Handled; + } + JumpToWave(prev_wave); + } + //Next wave + case 99: { + int ent = FindEntityByClassname(-1, "tf_objective_resource"); + if (ent == -1) { + LogMessage("tf_objective_resource not found"); + return Plugin_Handled; + } + + int current_wave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineWaveCount")); + int max_wave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineMaxWaveCount")); + int next_wave = current_wave + 1; + if (next_wave > max_wave) { + int flags = GetCommandFlags("tf_mvm_force_victory"); + SetCommandFlags("tf_mvm_force_victory", flags & ~FCVAR_CHEAT); + ServerCommand("tf_mvm_force_victory 1"); + FakeClientCommand(0, ""); //Not sure why, but this has to be here. Otherwise the specified commands simply refuse to work... + SetCommandFlags("tf_mvm_force_victory", flags | FCVAR_CHEAT); + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}VICTORY HAS BEEN FORCED! THE SERVER WILL RESTART IN 10 SECONDS."); + CreateTimer(10.0, TimedOperator, 100); + return Plugin_Handled; + } + JumpToWave(next_wave); + } + //Code Entry from FC Keypad + case 100: { + if (CodeEntry == 17) { + FireEntityInput("FB.BOOM", "StartShake", "", 0.0), + CustomSoundEmitter(BMB3SND, SFXSNDLVL, false, 0, 1.0, 100), + FireEntityInput("FB.CodeCorrectKill", "Enable", "", 0.0), + FireEntityInput("FB.KP*", "Lock", "", 0.0), + FireEntityInput("FB.CodeCorrectKill", "Disable", "", 1.0); + } else { + CodeEntry = 0; + FireEntityInput("FB.CodeFailedKill", "Enable", "", 0.0), + FireEntityInput("FB.CodeFailedKill", "Disable", "", 1.0), + CustomSoundEmitter("fartsy/memes/priceisright_fail.wav", SFXSNDLVL, false, 0, 1.0, 100); + } + } + case 101: { + CodeEntry++; + } + case 102: { + CodeEntry += 2; + } + case 103: { + CodeEntry += 3; + } + case 104: { + CodeEntry += 4; + } + case 105: { + CodeEntry += 5; + } + case 106: { + CodeEntry += 6; + } + case 107: { + CodeEntry += 7; + } + case 108: { + CodeEntry += 8; + } + case 109: { + CodeEntry += 9; + } + //Taco Bell Edition + case 210: { + tacobell = true; + ServerCommand("fb_startmoney 200000"); + CPrintToChatAll("{darkviolet}[{orange}INFO{darkviolet}] {white}You have chosen {red}DOVAH'S ASS - TACO BELL EDITION{white}. Why... Why would you DO THIS?! Do you not realize what you've just done?????"); + } + //TEMP FUNCTIONS + case 301: { + EmitSoundToAll(BGM1, _, SNDCHAN, BGMSNDLVL, SND_CHANGEVOL, 0.05, _, _, _, _, _, _); + } + //TEMP FUNCTIONS + case 302: { + EmitSoundToAll(BGM1, _, SNDCHAN, BGMSNDLVL, SND_CHANGEVOL, 1.0, _, _, _, _, _, _); + } + case 304: { + EmitSoundToAll(BGM2, _, SNDCHAN, BGMSNDLVL, SND_CHANGEVOL, 0.05, _, _, _, _, _, _); + } + case 305: { + EmitSoundToAll(BGM2, _, SNDCHAN, BGMSNDLVL, SND_CHANGEVOL, 1.0, _, _, _, _, _, _); + } + case 400: { + isWave = true; + CustomSoundEmitter(BGM4, BGMSNDLVL - 50, true, 1, 0.8, 100); + curSong = BGM4; + songName = BGM4Title; + } + //LOOP SYSTEM + case 500: { + PrintToConsoleAll("[CORE] Phase Change started... phase 2!"); + loopingFlags = 1; + } + case 501: { + PrintToConsoleAll("[CORE] Phase Change started... phase 3!"); + loopingFlags = 2; + } + case 502: { + PrintToConsoleAll("Got 502 but not implemented, please report this to fartsy!"); + } + // FINAL Music system rewrite (again) AGAINNNNNNNNNNNN.... + case 1000: { + tickMusic = true; + PrintToChatAll("%i", BGMINDEX); + switch (BGMINDEX) { + case 0, 1, 12: { + int BGM = GetRandomInt(1, 3); + switch (BGM) { + case 1: { + BGMINDEX = 0; + } + case 2: { + BGMINDEX = 1; + } + case 3: { + BGMINDEX = 12; + } + } + } + } + } + //Stop current song + case 1001: { + if (StrEqual(curSong, "null")) { + return Plugin_Handled; + } + for (int i = 1; i <= MaxClients; i++) { + StopSound(i, SNDCHAN, curSong); + } + return Plugin_Handled; + } + //Feature an admin + case 1002: { + FireEntityInput("AdminPicker", "SetTextureIndex", "10", 0.0); + int i = GetRandomInt(1, 9); + switch (i) { + case 1: { + if (i == lastAdmin) { + ServerCommand("fb_operator 1002"); + } else { + FireEntityInput("AdminPicker", "SetTextureIndex", "1", 0.1); + lastAdmin = 1; + } + } + case 2: { + if (i == lastAdmin) { + ServerCommand("fb_operator 1002"); + } else { + FireEntityInput("AdminPicker", "SetTextureIndex", "2", 0.1); + lastAdmin = 2; + } + } + case 3: { + if (i == lastAdmin) { + ServerCommand("fb_operator 1002"); + } else { + FireEntityInput("AdminPicker", "SetTextureIndex", "3", 0.1); + lastAdmin = 3; + } + } + case 4: { + if (i == lastAdmin) { + ServerCommand("fb_operator 1002"); + } else { + FireEntityInput("AdminPicker", "SetTextureIndex", "4", 0.1); + lastAdmin = 4; + } + } + case 5: { + if (i == lastAdmin) { + ServerCommand("fb_operator 1002"); + } else { + FireEntityInput("AdminPicker", "SetTextureIndex", "5", 0.1); + lastAdmin = 5; + } + } + case 6: { + if (i == lastAdmin) { + ServerCommand("fb_operator 1002"); + } else { + FireEntityInput("AdminPicker", "SetTextureIndex", "6", 0.1); + lastAdmin = 6; + } + } + case 7: { + if (i == lastAdmin) { + ServerCommand("fb_operator 1002"); + } else { + FireEntityInput("AdminPicker", "SetTextureIndex", "7", 0.1); + lastAdmin = 7; + } + } + case 8: { + if (i == lastAdmin) { + ServerCommand("fb_operator 1002"); + } else { + FireEntityInput("AdminPicker", "SetTextureIndex", "8", 0.1); + lastAdmin = 8; + } + } + case 9: { + if (i == lastAdmin) { + ServerCommand("fb_operator 1002"); + } else { + FireEntityInput("AdminPicker", "SetTextureIndex", "9", 0.1); + lastAdmin = 9; + } + } + case 10: { + if (i == lastAdmin) { + ServerCommand("fb_operator 1002"); + } else { + FireEntityInput("AdminPicker", "SetTextureIndex", "10", 0.1); + } + } + } + return Plugin_Handled; + } + //Strike Lightning + case 1003: { + FireEntityInput("lightning", "TurnOn", "", 0.0), + FireEntityInput("weather", "Skin", "4", 0.0), + FireEntityInput("value", "TurnOff", "", 0.0), + FireEntityInput("LightningLaser", "TurnOn", "", 0.0), + FireEntityInput("lightning", "TurnOff", "", 0.1), + FireEntityInput("weather", "Skin", "3", 0.1), + FireEntityInput("LightningLaser", "TurnOff", "", 0.1), + FireEntityInput("lightning", "TurnOn", "", 0.17), + FireEntityInput("weather", "Skin", "4", 0.17), + FireEntityInput("LightningLaser", "TurnOn", "", 0.17), + FireEntityInput("lightning", "TurnOff", "", 0.25), + FireEntityInput("weather", "Skin", "3", 0.25), + FireEntityInput("LightningLaser", "TurnOff", "", 0.25); + } + //Activate Tornado Timer + case 1004: { + if (isWave && canTornado) { + if (curWave == 4) { + float f = GetRandomFloat(30.0, 60.0); + float t = f - 30.0; + CreateTimer(t, TimedOperator, 40); + CreateTimer(f, TimedOperator, 41); + } else { + float f = GetRandomFloat(210.0, 500.0); + float t = f - 30.0; + CreateTimer(t, TimedOperator, 40); + CreateTimer(f, TimedOperator, 41); + } + } + } + //Despawn the tornado + case 1005: { + FireEntityInput("tornadof1", "stop", "", 0.0), + FireEntityInput("TornadoKill", "Disable", "", 0.0), + FireEntityInput("tornadof1wind", "Disable", "", 0.0), + FireEntityInput("tornadowindf1", "StopSound", "", 0.0), + FireEntityInput("shaketriggerf1", "Disable", "", 0.0), + FireEntityInput("tornadobutton", "Unlock", "", 30.0); + FireEntityInput("FB.FakeTankTank01", "Kill", "", 0.0); + FireEntityInput("FB.FakeTankPhys01", "Kill", "", 0.0); + tornado = false; + return Plugin_Handled; + } + //Crusader + case 1006: { + ServerCommand("fb_operator 1001"), + FireEntityInput("FB.MusicTimer", "Disable", "", 0.0); + crusader = true, + CreateTimer(25.20, TimedOperator, 78), + CreateTimer(63.20, TimedOperator, 80), + PrintToServer("Starting Crusader via plugin!"), + EmitSoundToAll("fartsy/misc/fartsyscrusader_bgm_locus.mp3"), + CreateTimer(1.75, CRUSADERINCOMING), + FireEntityInput("FB.BOOM", "StopShake", "", 3.0), + FireEntityInput("FB.CRUSADER", "Enable", "", 25.20), + FireEntityInput("CrusaderTrain", "StartForward", "", 25.20), + FireEntityInput("CrusaderLaserBase*", "StartForward", "", 25.20), + CreateTimer(25.20, TimedOperator, 9), + FireEntityInput("CrusaderTrain", "SetSpeed", "0.9", 38.0), + FireEntityInput("CrusaderTrain", "SetSpeed", "0.7", 38.60), + FireEntityInput("CrusaderTrain", "SetSpeed", "0.5", 39.20), + FireEntityInput("CrusaderTrain", "SetSpeed", "0.3", 40.40), + FireEntityInput("CrusaderTrain", "SetSpeed", "0.1", 41.40), + FireEntityInput("CrusaderTrain", "Stop", "", 42.60), + FireEntityInput("FB.CrusaderLaserKill01", "Disable", "", 42.60), + CreateTimer(42.60, TimedOperator, 10), + FireEntityInput("FB.LaserCore", "TurnOn", "", 45.80), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "0.35", 45.80), + FireEntityInput("FB.ShakeCore", "StartShake", "", 45.80), + FireEntityInput("CrusaderSprite", "Color", "255 128 128", 45.80), + FireEntityInput("FB.ShakeCore", "StopShake", "", 48.80), + FireEntityInput("FB.LaserInnerMost", "TurnOn", "", 49.20), + FireEntityInput("FB.ShakeInner", "StartShake", "", 49.20), + FireEntityInput("CrusaderSprite", "Color", "255 230 230", 49.20), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "0.35", 50.20), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "0.45", 50.60), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "0.55", 51.0), + FireEntityInput("FB.ShakeInner", "StopShake", "", 52.10), + FireEntityInput("FB.ShakeInner", "StartShake", "", 52.20), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "0.45", 54.0), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "0.4", 54.40), + FireEntityInput("FB.ShakeInner", "StopShake", "", 55.0), + FireEntityInput("FB.ShakeInner", "StartShake", "", 55.10), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "0.75", 57.20), + FireEntityInput("FB.CrusaderSideLaser", "TurnOn", "", 57.20), + FireEntityInput("FB.ShakeInner", "StopShake", "", 58.0), + FireEntityInput("FB.ShakeInner", "StartShake", "", 58.10), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "1", 58.50), + FireEntityInput("CrusaderLaserBase*", "SetSpeed", "0.75", 60.80), + FireEntityInput("CrusaderLaserBase", "SetSpeed", "0.65", 61.10), + FireEntityInput("CrusaderLaserBase", "SetSpeed", "0.55", 61.40), + FireEntityInput("FB.LaserCore", "TurnOff", "", 61.40), + FireEntityInput("FB.LaserInnerMost", "TurnOff", "", 61.40), + FireEntityInput("CrusaderSprite", "Color", "0 0 0", 61.40), + FireEntityInput("CrusaderLaserBase", "SetSpeed", "0.45", 61.70), + FireEntityInput("CrusaderLaserBase", "SetSpeed", "0.3", 62.0), + FireEntityInput("CrusaderLaserBase", "SetSpeed", "0.15", 62.30), + FireEntityInput("FB.CrusaderSideLaser", "TurnOff", "", 62.30), + FireEntityInput("CrusaderLaserBase*", "Stop", "", 62.70), + FireEntityInput("FB.Laser*", "TurnOn", "", 65.20), + FireEntityInput("CrusaderLaserBase*", "StartForward", "", 65.20), + FireEntityInput("CrusaderLaserBase", "SetSpeed", "1", 65.20), + FireEntityInput("FB.ShakeBOOM", "StartShake", "", 65.20), + FireEntityInput("FB.Fade", "Fade", "", 65.20), + FireEntityInput("HurtAll", "AddOutput", "damagetype 1024", 65.10), + FireEntityInput("HurtAll", "Enable", "", 65.20), + FireEntityInput("FB.CrusaderSideLaser", "TurnOn", "", 65.20), + FireEntityInput("CrusaderSprite", "Color", "255 230 255", 65.20), + FireEntityInput("FB.Laser*", "TurnOff", "", 70.0), + FireEntityInput("CrusaderTrain", "StartForward", "", 70.0), + FireEntityInput("CrusaderLaserBase*", "Stop", "", 70.0), + FireEntityInput("HurtAll", "Disable", "", 70.0), + FireEntityInput("FB.CrusaderSideLaser", "TurnOff", "", 70.0), + FireEntityInput("CrusaderSprite", "Color", "0 0 0", 70.0), + FireEntityInput("FB.ShakeBOOM", "StopShake", "", 70.20), + FireEntityInput("CrusaderTrain", "Stop", "", 80.0), + FireEntityInput("FB.CRUSADER", "Disable", "", 80.0); + CreateTimer(80.0, TimedOperator, 79); + } + //Choose bomb path + case 1007: { + FireEntityInput("Nest_EN060", "Disable", "", 0.0), + FireEntityInput("Nest_EN050", "Disable", "", 0.0), + FireEntityInput("Nest_EN040", "Disable", "", 0.0), + FireEntityInput("Nest_EN030", "Disable", "", 0.0), + FireEntityInput("Nest_EN020", "Disable", "", 0.0), + FireEntityInput("Nest_EN010", "Disable", "", 0.0), + FireEntityInput("Nest_L050", "Disable", "", 0.0), + FireEntityInput("Nest_L040", "Disable", "", 0.0), + FireEntityInput("Nest_L030", "Disable", "", 0.0), + FireEntityInput("Nest_L020", "Disable", "", 0.0), + FireEntityInput("Nest_L010", "Disable", "", 0.0), + FireEntityInput("Nest_R040", "Disable", "", 0.0), + FireEntityInput("Nest_R030", "Disable", "", 0.0), + FireEntityInput("Nest_R020", "Disable", "", 0.0), + FireEntityInput("Nest_R010", "Disable", "", 0.0), + FireEntityInput("bombpath_right_prefer_flankers", "Disable", "", 0.0), + FireEntityInput("bombpath_left_prefer_flankers", "Disable", "", 0.0), + FireEntityInput("bombpath_left_navavoid", "Disable", "", 0.0), + FireEntityInput("bombpath_right_navavoid", "Disable", "", 0.0), + FireEntityInput("bombpath_right_arrows", "Disable", "", 0.0), + FireEntityInput("bombpath_left_arrows", "Disable", "", 0.0); + int i = GetRandomInt(1, 3); + switch (i) { + case 1: { + FireEntityInput("Nest_R040", "Enable", "", 0.25), + FireEntityInput("Nest_R030", "Enable", "", 0.25), + FireEntityInput("Nest_R020", "Enable", "", 0.25), + FireEntityInput("Nest_R010", "Enable", "", 0.25), + FireEntityInput("bombpath_right_prefer_flankers", "Enable", "", 0.25), + FireEntityInput("bombpath_right_navavoid", "Enable", "", 0.25), + FireEntityInput("bombpath_right_arrows", "Enable", "", 0.25); + } + case 2: { + FireEntityInput("Nest_L050", "Enable", "", 0.25), + FireEntityInput("Nest_L040", "Enable", "", 0.25), + FireEntityInput("Nest_L030", "Enable", "", 0.25), + FireEntityInput("Nest_L020", "Enable", "", 0.25), + FireEntityInput("Nest_L010", "Enable", "", 0.25), + FireEntityInput("bombpath_left_prefer_flankers", "Enable", "", 0.25), + FireEntityInput("bombpath_left_navavoid", "Enable", "", 0.25), + FireEntityInput("bombpath_left_arrows", "Enable", "", 0.25); + } + case 3: { + FireEntityInput("dovahsassprefer", "Enable", "", 0.25), + FireEntityInput("Nest_R040", "Enable", "", 0.25), + FireEntityInput("Nest_R030", "Enable", "", 0.25), + FireEntityInput("Nest_R020", "Enable", "", 0.25), + FireEntityInput("Nest_R010", "Enable", "", 0.25), + FireEntityInput("bombpath_right_prefer_flankers", "Enable", "", 0.25), + FireEntityInput("bombpath_right_navavoid", "Enable", "", 0.25), + FireEntityInput("bombpath_right_arrows", "Enable", "", 0.25); + } + } + } + //Monitor power up/down! + case 1008: { + if (!monitorOn) { + monitorOn = true; + if (!monitorColor) { + FireEntityInput("FB.MonitorSprite", "Color", "0 0 255", 0.0); + FireEntityInput("FB.MonitorBlank", "Disable", "", 0.0); + FireEntityInput("FB.MonitorBW", "Enable", "", 0.0); + } else { + FireEntityInput("FB.MonitorSprite", "Color", "0 255 0", 0.0); + FireEntityInput("FB.MonitorBlank", "Disable", "", 0.0); + FireEntityInput("FB.Monitor", "Enable", "", 0.0); + } + } else { + monitorOn = false; + FireEntityInput("FB.MonitorSprite", "Color", "255 0 0", 0.0); + FireEntityInput("FB.Monitor", "Disable", "", 0.0); + FireEntityInput("FB.MonitorBW", "Disable", "", 0.0); + FireEntityInput("FB.MonitorBlank", "Enable", "", 0.0); + } + } + //Cycle monitor forward + case 1009: { + camSel++; + switch (camSel) { + case 0: { + FireEntityInput("FB.Monitor", "SetCamera", "CAM.Front", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.Front", 0.0); + } + case 1: { + FireEntityInput("FB.Monitor", "SetCamera", "CAM.Mid", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.Mid", 0.0); + } + case 2: { + FireEntityInput("FB.Monitor", "SetCamera", "CAM.MidTwo", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.MidTwo", 0.0); + } + case 3: { + FireEntityInput("FB.Monitor", "SetCamera", "CAM.Rear", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.Rear", 0.0); + } + case 4: { + FireEntityInput("FB.Monitor", "SetCamera", "CAM.Kissone", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.Kissone", 0.0); + } + case 5: { + FireEntityInput("FB.Monitor", "SetCamera", "CAM.Front", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.Front", 0.0); + camSel = 0; + } + } + } + //Cycle monitor back + case 1010: { + camSel--; + switch (camSel) { + case -1: { + FireEntityInput("FB.Monitor", "SetCamera", "CAM.Front", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.Front", 0.0); + camSel = 4; + } + case 0: { + FireEntityInput("FB.Monitor", "SetCamera", "CAM.Front", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.Front", 0.0); + } + case 1: { + FireEntityInput("FB.Monitor", "SetCamera", "CAM.Mid", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.Mid", 0.0); + } + case 2: { + FireEntityInput("FB.Monitor", "SetCamera", "CAM.MidTwo", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.MidTwo", 0.0); + } + case 3: { + FireEntityInput("FB.Monitor", "SetCamera", "CAM.Rear", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.Rear", 0.0); + } + case 4: { + FireEntityInput("FB.Monitor", "SetCamera", "CAM.Kissone", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.Kissone", 0.0); + } + case 5: { + FireEntityInput("FB.Monitor", "SetCamera", "CAM.Front", 0.0); + FireEntityInput("FB.MonitorBW", "SetCamera", "CAM.Front", 0.0); + camSel = 0; + } + } + } + //Enable black and white. + case 1011: { + if (!monitorOn) { + return Plugin_Stop; + } else { + if (!monitorColor) { + monitorColor = true; + FireEntityInput("FB.MonitorSprite", "Color", "0 255 0", 0.0); + FireEntityInput("FB.Monitor", "Enable", "", 0.0); + FireEntityInput("FB.MonitorBW", "Disable", "", 0.0); + } else { + monitorColor = false; + FireEntityInput("FB.MonitorSprite", "Color", "0 0 255", 0.0); + FireEntityInput("FB.Monitor", "Disable", "", 0.0); + FireEntityInput("FB.MonitorBW", "Enable", "", 0.0); + } + } + } + //Restore Music + case 2000: { + CreateTimer(1.0, UpdateMusic); + if (isWave) { + int ent = FindEntityByClassname(-1, "tf_objective_resource"); //Get current wave, perform actions per wave. + if (ent == -1) { + LogMessage("tf_objective_resource not found"); + return Plugin_Handled; + } + curWave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineWaveCount")); + switch (curWave) { + case 1: { + if (tacobell) { + BGMINDEX = 10; + } else { + BGMINDEX = 2; + } + } + case 2: { + BGMINDEX = 3; + } + case 3: { + BGMINDEX = 4; + } + case 4: { + BGMINDEX = 5; + } + case 5: { + BGMINDEX = 6; + } + case 6: { + BGMINDEX = 7; + } + case 7: { + BGMINDEX = 8; + } + case 8: { + if (sephiroth) { + BGMINDEX = 11; + } else { + BGMINDEX = 9; + } + } + } + } else { + BGMINDEX = GetRandomInt(0, 1); + } + } + case 6942: { + sacPoints = 2147483647; + } + //Do not EVER EVER execute this unless it's an emergency... + case 6969: { + if (!isWave) { + CPrintToChatAll("{darkred} [CORE] ERROR, attempted to invoke function without an active wave."); + } else { + if (!brawler_emergency) { + brawler_emergency = true, + EmitSoundToAll(SUS), + CreateTimer(1.0, TimedOperator, 6969), + CPrintToChatAll("{darkred}EMERGENCY MODE ACTIVE."); + sacPoints = -2147483648; + ServerCommand("sm_addcash @red 2000000"); + ServerCommand("sm_god @red 1"); + } else { + CPrintToChatAll("{darkred}[CORE] Failed to enter emergency mode, it is already active."); + return Plugin_Handled; + } + } + } + //DEBUG + case 9000: { + CreateTimer(10.0, SephHPTimer); + } + case 9001: { + //Phases + CustomSoundEmitter(BGM10, BGMSNDLVL - 10, true, 1, 0.05, 100); + CustomSoundEmitter(BGM5, BGMSNDLVL - 10, true, 1, 1.0, 100); + } + case 9002: { + CustomSoundEmitter(BGM10, BGMSNDLVL - 10, true, 1, 1.0, 100); + CustomSoundEmitter(BGM5, BGMSNDLVL - 10, true, 1, 0.05, 100); + } + case 9010: { + CustomSoundEmitter(TBGM6, BGMSNDLVL - 10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM4, BGMSNDLVL - 10, true, 1, 0.05, 100); + CustomSoundEmitter(TBGM5, BGMSNDLVL - 10, true, 1, 0.05, 100); + CustomSoundEmitter(TBGM3, BGMSNDLVL - 10, true, 1, 0.05, 100); + } + case 9011: { + CustomSoundEmitter(TBGM6, BGMSNDLVL - 10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM4, BGMSNDLVL - 10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM5, BGMSNDLVL - 10, true, 1, 0.05, 100); + CustomSoundEmitter(TBGM3, BGMSNDLVL - 10, true, 1, 0.05, 100); + } + case 9012: { + CustomSoundEmitter(TBGM6, BGMSNDLVL - 10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM4, BGMSNDLVL - 10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM5, BGMSNDLVL - 10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM3, BGMSNDLVL - 10, true, 1, 0.05, 100); + } + case 9013: { + CustomSoundEmitter(TBGM6, BGMSNDLVL - 10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM4, BGMSNDLVL - 10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM5, BGMSNDLVL - 10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM3, BGMSNDLVL - 10, true, 1, 1.0, 100); + } + case 9014: { + CustomSoundEmitter(TBGM6, BGMSNDLVL - 10, true, 1, 0.05, 100); + CustomSoundEmitter(TBGM4, BGMSNDLVL - 10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM5, BGMSNDLVL - 10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM3, BGMSNDLVL - 10, true, 1, 1.0, 100); + } + case 9015: { + CustomSoundEmitter(TBGM6, BGMSNDLVL - 10, true, 1, 0.05, 100); + CustomSoundEmitter(TBGM4, BGMSNDLVL - 10, true, 1, 0.05, 100); + CustomSoundEmitter(TBGM5, BGMSNDLVL - 10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM3, BGMSNDLVL - 10, true, 1, 1.0, 100); + } + case 9016: { + CustomSoundEmitter(TBGM6, BGMSNDLVL - 10, true, 1, 0.05, 100); + CustomSoundEmitter(TBGM4, BGMSNDLVL - 10, true, 1, 0.05, 100); + CustomSoundEmitter(TBGM5, BGMSNDLVL - 10, true, 1, 0.05, 100); + CustomSoundEmitter(TBGM3, BGMSNDLVL - 10, true, 1, 1.0, 100); + } + //Play Instrumental + case 9020: { + CustomSoundEmitter(TBGM0, BGMSNDLVL - 10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM1, BGMSNDLVL - 10, true, 1, 0.05, 100); + } + //Play Both + case 9021: { + CustomSoundEmitter(TBGM0, BGMSNDLVL - 10, true, 1, 1.0, 100); + CustomSoundEmitter(TBGM1, BGMSNDLVL - 10, true, 1, 1.0, 100); + } + //Play vocal only + case 9022: { + CustomSoundEmitter(TBGM0, BGMSNDLVL - 10, true, 1, 0.05, 100); + CustomSoundEmitter(TBGM1, BGMSNDLVL - 10, true, 1, 1.0, 100); + } + case 10000: { + BGMINDEX = 10; + tbLoop = 1; + CustomSoundEmitter(BGM9Intro, BGMSNDLVL, true, 1, 1.0, 100); + FireEntityInput("FB.MusicTimer", "Disable", "", 0.0); + FireEntityInput("FB.MusicTimer", "RefireTime", "11.81", 0.0); + FireEntityInput("FB.MusicTimer", "ResetTimer", "", 0.01); + FireEntityInput("FB.MusicTimer", "Enable", "", 0.01); + } + } + return Plugin_Handled; +} +public Action BGMTest(Handle timer) { + CustomSoundEmitter(BGM9, BGMSNDLVL, true, 1, 1.0, 100); +} + +//Perform Wave Setup +public Action PerformWaveSetup() { + isWave = true; //It's a wave! + FailedCount = 0; //Reset fail count to zero. (See EventWaveFailed, where we play the BGM.) + ServerCommand("fb_operator 1001"); //Stop any playing BGM + CreateTimer(0.25, TimedOperator, 0); //Print wave information to global chat + CreateTimer(2.5, PerformWaveAdverts); //Activate the mini hud + CreateTimer(0.1, BombStatusUpdater); //Activate the bomb status updater + CreateTimer(1.0, BombStatusAddTimer); //Activate bomb status timer + CreateTimer(1.0, RobotLaunchTimer); //Activate robot launch timer + CreateTimer(1.0, SacrificePointsTimer); //Activate sacrifice points add timer + CreateTimer(1.0, SacrificePointsUpdater); //Activate sacrifice points updater + CreateTimer(1.0, RefireStorm); //Activate thunderstorm + FireEntityInput("bombpath_right_arrows", "Disable", "", 0.1); //Disable right arrows TODO: Figure out why + FireEntityInput("bombpath_left_arrows", "Disable", "", 0.1); //Disable left arrows TODO: Figure out why + FireEntityInput("Classic_Mode_Intel1", "Enable", "", 0.0); //Activate Intel 1 + FireEntityInput("Classic_Mode_Intel2", "Enable", "", 0.0); //Activate Intel 2 + FireEntityInput("CommonSpells", "Enable", "", 0.0); // Activate common spells + FireEntityInput("rain", "Alpha", "200", 0.0); //Activate rain + FireEntityInput("OldSpawn", "Enable", "", 0.0); //Activate Old Spawn + FireEntityInput("NewSpawn", "Disable", "", 0.0); //De-activate New SpawnServerCommand("fb_operator 1002"); + ServerCommand("fb_operator 1002"); //Feature admin + ServerCommand("fb_operator 1004"); //Activate Tornado Timer + ServerCommand("fb_operator 1007"); //Choose bomb path + return Plugin_Handled; +} + +//Timed commands +public Action TimedOperator(Handle timer, int job) { + switch (job) { + case 0: { + if (VIPBGM >= 0) { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}Wave %i: {forestgreen}%s{white} (requested by VIP {forestgreen}%N{white})", curWave, songName, VIPIndex); + } else { + CPrintToChatAll("{darkviolet}[{forestgreen}CORE{darkviolet}] {white}Wave %i: {forestgreen}%s", curWave, songName); + } + } + //Boss script + case 2: { + ServerCommand("fb_operator 1001"); //Stop all bgm. + FireEntityInput("FB.MusicTimer", "Disable", "", 0.0); //Disable all bgm. + CreateTimer(0.0, TimedOperator, 3); + } + //Boss script pt 2 + case 3: { + CustomSoundEmitter(BGM10Intro, BGMSNDLVL + 10, true, 0, 1.0, 100); + FireEntityInput("FB.FadeTotalBLCK", "Fade", "", 0.0); + FireEntityInput("FB.FadeTotalBLCK", "Fade", "", 3.0); + FireEntityInput("FB.FadeTotalBLCK", "Fade", "", 7.0); + FireEntityInput("FB.FadeTotalBLCK", "Fade", "", 12.0); + FireEntityInput("SephMeteor", "ForceSpawn", "", 19.6); + CreateTimer(23.0, TimedOperator, 4); + } + //Boss script pt 3 + case 4: { + CustomSoundEmitter(EVENTSTART, SFXSNDLVL, false, 0, 1.0, 100), + CreateTimer(4.1, TimedOperator, 5); + } + //Boss script pt 4 + case 5: { + CustomSoundEmitter(VO_SEPHMEMORY, SFXSNDLVL, false, 0, 1.0, 100), + FireEntityInput("SephNuke", "ForceSpawn", "", 3.0), + CreateTimer(3.2, TimedOperator, 6); + } + //Boss script pt 5 + case 6: { + CustomSoundEmitter(HINDENBURGBOOM, SFXSNDLVL - 10, false, 0, 1.0, 100), + FireEntityInput("FB.Fade", "Fade", "", 0.0), + CreateTimer(1.0, SephATK), + CreateTimer(1.7, TimedOperator, 7); + } + //DO THE THING ALREADY + case 7: { + sephiroth = true; + BGMINDEX = 11; + curSong = BGM10; + songName = BGM10Title; + CustomSoundEmitter(BGM10, BGMSNDLVL, true, 0, 1.0, 100), + CreateTimer(313.0, TimedOperator, 1); + } + //Signal boss to actually spawn after delay. + case 8: { + CustomSoundEmitter(VICTORY, SFXSNDLVL, false, 0, 1.0, 100); + CPrintToChatAll("{darkgreen}[CORE] You did it!!! {darkred}Or... did you...?"); + FireEntityInput("FB.FadeBLCK", "Fade", "", 0.0); + CreateTimer(4.8, TimedOperator, 2); + } + //Crusader Nuke activation + case 9: { + canCrusaderNuke = true; + CreateTimer(1.0, CrusaderNukeTimer); + } + //Crusader Nuke Deactivation + case 10: { + canCrusaderNuke = false; + return Plugin_Stop; + } + //Seph Nuke Deactivation + case 11: { + canSephNuke = false; + return Plugin_Stop; + } + //SENTMeteor Timeout + case 12: { + canSENTMeteors = false; + return Plugin_Stop; + } + //SENTNukes Timeout + case 13: { + canSENTNukes = false; + return Plugin_Stop; + } + //SENTStars Timeout + case 14: { + canSENTStars = false; + return Plugin_Stop; + } + //Incoming + case 21: { + CustomSoundEmitter(INCOMING, SFXSNDLVL, false, 0, 1.0, 100); + return Plugin_Stop; + } + case 37: { + EmitSoundToAll(HINDENBURGBOOM); + return Plugin_Stop; + } + case 40: { + if (isWave && canTornado) { + EmitSoundToAll("mvm/ambient_mp3/mvm_siren.mp3"), + TornadoWarningIssued = true; + } + return Plugin_Stop; + } + case 41: { + if (isWave && canTornado && !tornado) { + FireEntityInput("TornadoKill", "Enable", "", 0.0), + FireEntityInput("tornadobutton", "Lock", "", 0.0), + FireEntityInput("tornadof1", "start", "", 20.0), + FireEntityInput("shaketriggerf1", "Enable", "", 20.0), + FireEntityInput("tornadowindf1", "PlaySound", "", 20.0), + FireEntityInput("tornadof1wind", "Enable", "", 21.50); + tornado = true; + float f = GetRandomFloat(60.0, 120.0); + CreateTimer(f, TimedOperator, 42); + } + return Plugin_Stop; + } + case 42: { + ServerCommand("fb_operator 1005"); + TornadoWarningIssued = false; + ServerCommand("fb_operator 1004"); + } + case 60: { + CustomSoundEmitter(OnslaughterFlamePostATK, SFXSNDLVL, false, 0, 1.0, 100); + return Plugin_Stop; + } + case 70: { + if (isWave) { + FireEntityInput("FB.KP*", "Unlock", "", 0.0); + CustomSoundEmitter(BELL, SFXSNDLVL, false, 0, 1.0, 100); + } + return Plugin_Stop; + } + case 71: { + CustomSoundEmitter("fartsy/eee/the_horn.wav", SFXSNDLVL, false, 0, 1.0, 100); + return Plugin_Stop; + } + case 78: { + EmitSoundToAll(CRUSADERATTACK); + return Plugin_Handled; + } + case 79: { + crusader = false; + int ent = FindEntityByClassname(-1, "tf_objective_resource"); + if (ent == -1) { + LogMessage("tf_objective_resource not found"); + return Plugin_Stop; + } + int current_wave = GetEntData(ent, FindSendPropInfo("CTFObjectiveResource", "m_nMannVsMachineWaveCount")); + if (isWave && (current_wave == 3 || current_wave == 5)) { + ServerCommand("fb_operator 99"); + } else { + return Plugin_Stop; + } + return Plugin_Stop; + } + case 80: { + EmitSoundToAll(WTFBOOM); + return Plugin_Handled; + } + case 99: { + if (isWave) { + ServerCommand("fb_operator 99"); + } else { + return Plugin_Stop; + } + } + case 100: { + ServerCommand("_restart"); + } + case 1000: { + PrintToConsoleAll("This shouldn't be showing in your console. If it is, contact Fartsy#8998 ."); + } + case 6969: { + if (isWave) { + ServerCommand("sm_freeze @blue; sm_smash @blue; sm_evilrocket @blue"), + ServerCommand("fb_operator 2"), + CreateTimer(4.0, TimedOperator, 6970); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6970: { + if (isWave) { + EmitSoundToAll(COUNTDOWN), + CreateTimer(7.0, TimedOperator, 6971); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6971: { + if (isWave) { + ServerCommand("fb_operator 40;fb_operator 40;fb_operator 40;fb_operator 40;fb_operator 40;fb_operator 40;fb_operator 40;fb_operator 40;fb_operator 40;fb_operator 40"), + CreateTimer(1.0, TimedOperator, 6972); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6972: { + if (isWave) { + ServerCommand("fb_operator 42;fb_operator 42;fb_operator 42;fb_operator 42;fb_operator 42;fb_operator 42;fb_operator 42;fb_operator 42;fb_operator 42;fb_operator 42"), + ServerCommand("fb_operator 1006"), + CreateTimer(1.0, TimedOperator, 6973); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6973: { + if (isWave) { + explodeType = 1, + ServerCommand("fb_operator 15"), + CreateTimer(1.0, TimedOperator, 6974); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6974: { + if (isWave) { + explodeType = 2, + ServerCommand("fb_operator 15;fb_operator 15"), + CreateTimer(1.0, TimedOperator, 6975); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6975: { + if (isWave) { + explodeType = 3, + ServerCommand("fb_operator 15;fb_operator 15;fb_operator 15"), + CreateTimer(1.0, TimedOperator, 6976); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6976: { + if (isWave) { + explodeType = 4, + ServerCommand("fb_operator 15;fb_operator15;fb_operator 15;fb_operator 15"), + CreateTimer(1.0, TimedOperator, 6977); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6977: { + if (isWave) { + explodeType = 5, + ServerCommand("fb_operator 15;fb_operator 15;fb_operator 15;fb_operator 15;fb_operator 15"), + CreateTimer(1.0, TimedOperator, 6978); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6978: { + if (isWave) { + explodeType = 6, + ServerCommand("fb_operator 15;fb_operator 15;fb_operator 15;fb_operator 15;fb_operator 15;fb_operator 15"), + ServerCommand("fb_operator 30"), + CreateTimer(1.0, TimedOperator, 6979); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6979: { + if (isWave) { + ServerCommand("fb_operator 31"), + CreateTimer(1.0, TimedOperator, 6980); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6980: { + if (isWave) { + ServerCommand("fb_operator 32"), + CreateTimer(1.0, TimedOperator, 6981); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6981: { + if (isWave) { + ServerCommand("fb_operator 33"), + CreateTimer(1.0, TimedOperator, 6982); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6982: { + if (isWave) { + ServerCommand("fb_operator 34"), + CreateTimer(1.0, TimedOperator, 6983); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6983: { + if (isWave) { + ServerCommand("fb_operator 35"), + CreateTimer(1.0, TimedOperator, 6984); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6984: { + if (isWave) { + ServerCommand("fb_operator 36"), + CreateTimer(1.0, TimedOperator, 6985); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6985: { + if (isWave) { + ServerCommand("fb_operator 37"), + CreateTimer(1.0, TimedOperator, 6986); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6986: { + if (isWave) { + ServerCommand("sm_freeze @blue -1; sm_smash @blue"), + CreateTimer(3.0, TimedOperator, 6987); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6987: { + if (isWave) { + ServerCommand("fb_operator 40; fb_operator 42; fb_operator 30; fb_operator 32; fb_operator 34; fb_operator 32; fb_operator 31; fb_operator 42;fb_operator 42;fb_operator 42;fb_operator 31;fb_operator 32;fb_operator 32;fb_operator 31;fb_operator 32;fb_operator 32"); + CreateTimer(1.0, TimedOperator, 6988); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6988: { + if (isWave) { + explodeType = 6, + ServerCommand("fb_operator 15;fb_operator15;fb_operator 15;fb_operator 15;fb_operator 15;fb_operator 15"), + ServerCommand("fb_operator 30"), + ServerCommand("fb_operator 31"), + ServerCommand("fb_operator 32"), + ServerCommand("fb_operator 33"), + ServerCommand("fb_operator 34"), + ServerCommand("fb_operator 35"), + ServerCommand("fb_operator 36"), + ServerCommand("fb_operator 37"), + ServerCommand("fb_operator 40"), + ServerCommand("fb_operator 41"), + ServerCommand("fb_operator 42"), + ServerCommand("fb_operator 43"), + ServerCommand("fb_operator 44"), + ServerCommand("fb_operator 32"), + ServerCommand("fb_operator 32"), + ServerCommand("fb_operator 32"), + ServerCommand("fb_operator 1003"), + ServerCommand("fb_operator 1003"), + ServerCommand("fb_operator 1003"), + ServerCommand("fb_operator 1003"), + ServerCommand("fb_operator 1003"), + ServerCommand("fb_operator 1003"), + ServerCommand("fb_operator 1003"), + ServerCommand("fb_operator 1003"), + ServerCommand("fb_operator 1003"), + ServerCommand("fb_operator 1003"), + ServerCommand("fb_operator 1003"), + ServerCommand("fb_operator 1003"), + ServerCommand("fb_operator 1003"), + CreateTimer(1.0, TimedOperator, 6989); + } else { + ExitEmergencyMode(); + return Plugin_Handled; + } + } + case 6989: { + CPrintToChatAll("{darkgreen}[CORE] Exiting emergency mode."), + brawler_emergency = false; + ServerCommand("sm_god @red 0"); + return Plugin_Handled; + } + } + return Plugin_Stop; +} + +//Exit emergency mode! +public void ExitEmergencyMode() { + CPrintToChatAll("{darkgreen}[CORE] Exiting emergency mode, the wave has ended."), + brawler_emergency = false; + ServerCommand("sm_god @red 0"); +} + +//Setup music, this allows us to change it with VIP access... +public void SetupMusic(int BGM) { + if (VIPBGM >= 0) { + PrintToConsoleAll("Music has been customized by VIP %N. They chose %i.", VIPIndex, VIPBGM); + BGMINDEX = VIPBGM; + ServerCommand("fb_operator 1000"); + } else { + BGMINDEX = BGM; + ServerCommand("fb_operator 1000"); + } +} + +public Action Command_Music(int client, int args) { + int steamID = GetSteamAccountID(client); + if (!steamID || steamID <= 10000) { + return Plugin_Handled; + } else { + ShowFartsyMusicMenu(client); + return Plugin_Handled; + } +} + +//Send client sound menu +public void ShowFartsyMusicMenu(int client) { + Menu menu = new Menu(MenuHandlerFartsyMusic, MENU_ACTIONS_DEFAULT); + char buffer[100]; + menu.SetTitle("FartsysAss Music Menu"); + menu.AddItem(buffer, "FFXIV - Knowledge Never Sleeps"); + menu.AddItem(buffer, "FFXIV - Silent Regard of Stars"); + menu.AddItem(buffer, "FFXIV - Locus"); + menu.AddItem(buffer, "FFXIV - Metal"); + menu.AddItem(buffer, "FFXIV - Exponential Entropy"); + menu.AddItem(buffer, "FFXIV - Torn From the Heavens"); + menu.AddItem(buffer, "FFXIV - Metal Brute Justice Mode"); + menu.AddItem(buffer, "FFXIV - Penitus"); + menu.AddItem(buffer, "FFXIV - Revenge Twofold"); + menu.AddItem(buffer, "FFXIV - Landslide"); + menu.AddItem(buffer, "XBC2 - Battle!!"); + menu.AddItem(buffer, "FF Advent Children - One Winged Angel"); + menu.AddItem(buffer, "FFXIV - From Mud"); + menu.AddItem(buffer, "XBC - You Will Know Our Names"); + menu.AddItem(buffer, "Demetori - U.N. Owen Was Her?"); + menu.AddItem(buffer, "Restore Default"); + menu.Display(client, 20); + menu.ExitButton = true; +} + +// This selects the music +public int MenuHandlerFartsyMusic(Menu menu, MenuAction action, int p1, int p2) { + if (action == MenuAction_Select) { + int steamID = GetSteamAccountID(p1); + if (!steamID) { + return; + } else if (p2 == 15) { + VIPIndex = p1; + VIPBGM = -1; + CPrintToChat(p1, "{darkgreen}[CORE] Confirmed. Next song set to {aqua}Default{darkgreen}."); + ServerCommand("fb_operator 2000"); + } else { + switch (p2) { + case 0: { + s = DEFAULTBGM1Title; + } + case 1: { + s = DEFAULTBGM2Title; + } + case 2: { + s = BGM1Title; + } + case 3: { + s = BGM2Title; + } + case 4: { + s = BGM3Title; + } + case 5: { + s = BGM4Title; + } + case 6: { + s = BGM5Title; + } + case 7: { + s = BGM6Title; + } + case 8: { + s = BGM7Title; + } + case 9: { + s = BGM8Title; + } + case 10: { + s = BGM9Title; + } + case 11: { + s = BGM10Title; + } + case 12: { + s = DEFAULTBGM3Title; + } + case 13: { + s = BGM11Title; + } + case 14: { + s = BGM12Title; + } + } + CPrintToChat(p1, "{limegreen}[CORE] Confirmed. Next song set to {aqua}%s{limegreen}.", s); + VIPIndex = p1; + VIPBGM = p2; + BGMINDEX = p2; + } + } else if (action == MenuAction_End) { + CloseHandle(menu); + } +} + +stock int TF2_GetPlayerMaxHealth(int client) { + return GetEntProp(GetPlayerResourceEntity(), Prop_Send, "m_iMaxHealth", _, client); +} + +public Action TickClientHealth(Handle timer) { + for (int i = 1; i <= MaxClients; i++) { + if (IsClientInGame(i) && !IsFakeClient(i) && (GetClientTeam(i) == 2)) { + int health = GetClientHealth(i); + int healthMax = TF2_GetPlayerMaxHealth(i); + PrintToServer("Client %N joined RED TEAM and is being tracked with %i/%i health! UwU", i, health, healthMax); + if (!FB_Database) { + return; + } else { + char query[256]; + int steamID = GetSteamAccountID(i); + Format(query, sizeof(query), "UPDATE ass_activity SET health = %i, maxHealth = %i WHERE steamid = %i;", health, healthMax, steamID); + FB_Database.Query(Database_FastQuery, query); + } + } + } + CreateTimer(1.0, TickClientHealth); +} + +public Action UpdateMusic(Handle timer) { + prevSong = curSong; + return Plugin_Stop; +} \ No newline at end of file diff --git a/scripting/FartsysKSYS.smx b/scripting/FartsysKSYS.smx new file mode 100644 index 0000000..e59327e Binary files /dev/null and b/scripting/FartsysKSYS.smx differ diff --git a/scripting/FartsysKSYS.sp b/scripting/FartsysKSYS.sp new file mode 100644 index 0000000..ffdfcc6 --- /dev/null +++ b/scripting/FartsysKSYS.sp @@ -0,0 +1,237 @@ +#include +#include +#include +#include +#include +Database KSYS_Database; + +//Registry of all playable classes +char ClassDefs[][32] = { + "scout", + "sniper", + "soldier", + "demoman", + "medic", + "heavy", + "pyro", + "spy", + "engineer", + "" +}; + +enum struct PLAYER_SOUNDS { + int killcount; + char sound[256]; + char sound_old[256]; +} +PLAYER_SOUNDS PD[MAXPLAYERS+1]; + +enum struct TEMP_SOUNDS { + char sound[256]; +} +TEMP_SOUNDS TEMPSNDS[MAXPLAYERS+1][10]; +stock bool IsValidClient(int client) { + return (0 < client <= MaxClients && IsClientInGame(client) && !IsFakeClient(client)); +} + +char PLUGIN_VERSION[8] = "1.0.0"; + +public Plugin myinfo = { + name = "Fartsy's Kill Streak System", + author = "Fartsy", + description = "Allows users to listen to music on kill streaks", + version = PLUGIN_VERSION, + url = "https://forums.firehostredux.com" +}; + +public void OnPluginStart(){ + HookEvent("player_death", EventDeath); + HookEvent("player_spawn", EventSpawn); + RegConsoleCmd("sm_ksys", Command_SetKSYS, "Set your killstreak sounds"); +} + +//Connect to database +public void OnConfigsExecuted() { + if (!KSYS_Database) Database.Connect(Database_OnConnect, "ksys"); +} + +//Format database if needed +public void Database_OnConnect(Database db, char[] error, any data) { + if (!db) { + LogError(error); + return; + } + char buffer[64]; + db.Driver.GetIdentifier(buffer, sizeof(buffer)); + if (!StrEqual(buffer, "mysql", false)) { + delete db; + LogError("Could not connect to the database: expected mysql database."); + return; + } + KSYS_Database = db; + KSYS_Database.Query(Database_FastQuery, "CREATE TABLE IF NOT EXISTS killstreak_sounds(steamid INT UNSIGNED, scout TEXT DEFAULT 'null', soldier TEXT DEFAULT 'null', pyro TEXT DEFAULT 'null', demoman TEXT DEFAULT 'null', heavy TEXT DEFAULT 'null', engineer TEXT DEFAULT 'null', medic TEXT DEFAULT 'null', sniper TEXT DEFAULT 'null', spy TEXT DEFAULT 'null', streak INT UNSIGNED DEFAULT '5', multiFile INT UNSIGNED DEFAULT '0', PRIMARY KEY (steamid, streak));"); +} + +//Database Fastquery Manager - Writing only +void Database_FastQuery(Database db, DBResultSet results, const char[] error, any data) { + if (!results) LogError("Failed to query database: %s", error); +} +public void Database_MergeDataError(Database db, any data, int numQueries, + const char[] error, int failIndex, any[] queryData) { + LogError("Failed to query database (transaction): %s", error); +} + +//Set up thing with thing +public Action Command_SetKSYS(int client, int args){ + char class[16]; char sound[256]; char streak[8]; + GetCmdArg(1, class, sizeof(class)); + GetCmdArg(2, sound, sizeof(sound)); + GetCmdArg(3, streak, sizeof(streak)); + int steamID = GetSteamAccountID(client); + if (!steamID || steamID <= 10000) return Plugin_Handled; + else { + if (!KSYS_Database) { + LogError("NO DATABASE"); + return Plugin_Handled; + } + char query[1024]; + Format(query, sizeof(query), "INSERT INTO killstreak_sounds (steamid, %s, streak) VALUES ('%d', '%s', '%i') ON DUPLICATE KEY UPDATE %s = '%s';", class, steamID, sound, StringToInt(streak), class, sound); + KSYS_Database.Query(Database_FastQuery, query); + CPrintToChat(client, "{orange}[{white}CORE{orange}] {white} You set {limegreen}%s{white} to play upon obtaining a {limegreen}%s{white} kill streak as {limegreen} %s{white} .", sound, streak, class); + } + return Plugin_Handled; +} + +//Do Killstreak Sounds +public Action EventDeath(Event Spawn_Event, const char[] Spawn_Name, bool Spawn_Broadcast) { + int client = GetClientOfUserId(Spawn_Event.GetInt("userid")); + int attacker = GetClientOfUserId(Spawn_Event.GetInt("attacker")); + int steamid = GetSteamAccountID(attacker); + if (IsValidClient(client)){ + ResetSound(client, true); + PD[client].killcount = 0; + } + if (steamid && client != attacker && IsValidClient(attacker)){ + PD[attacker].killcount++; + for (int i = 5; i <= 50; i = i+5){ + if(i == PD[attacker].killcount){ + CPrintToChatAll("{limegreen}%N{white} has a {darkred}%i{white} killstreak!", attacker, PD[attacker].killcount); + char query[1024]; + Format(query, sizeof(query), "SELECT %s, streak FROM killstreak_sounds WHERE steamID = '%d' AND streak = '%i';", ClassDefs[GetEntProp(attacker, Prop_Send, "m_iClass") - 1], steamid, i); + KSYS_Database.Query(KSYS_Query, query, attacker); + } + } + } + return Plugin_Continue; +} + +public Action EventSpawn(Event Spawn_Event, const char[] Spawn_Name, bool Spawn_Broadcast) { + int client = GetClientOfUserId(Spawn_Event.GetInt("userid")); + if (IsValidClient(client)) PD[client].killcount = 0; + return Plugin_Continue; +} + +void KSYS_Query(Database db, DBResultSet results, const char[] error, int client) { + if (!results) return; + if (results.FetchRow()) { + results.FetchString(0, PD[client].sound, 256); + if (strcmp(PD[client].sound, "null") == 0 || strcmp(PD[client].sound, "") == 0){ + PrintToConsole(client, "[Fartsy's Killstreak System] SOUND %s WAS NULL. You may add your own music using sm_ksys class path/file.mp3 killstreakNumber.", PD[client].sound); + return; + } + //It's multi file, load ALL the things! + if (StrContains(PD[client].sound, "_multi") != -1){ + char query[512]; + Format(query, sizeof(query), "SELECT %s, streak FROM killstreak_sounds WHERE steamID = '%d' AND %s LIKE '%%_multi%%';", ClassDefs[GetEntProp(client, Prop_Send, "m_iClass") - 1], GetSteamAccountID(client), ClassDefs[GetEntProp(client, Prop_Send, "m_iClass") - 1]); + KSYS_Database.Query(KSYS_Query_Multi, query, client); + } + //It's single file, load the thing. + else { + PrintToConsole(client, "[Fartsy's Killstreak System] Playing %s...", PD[client].sound); + InjectAndLoadSound(PD[client].sound); + ResetSound(client, false); + CSEClient(client, PD[client].sound, 100, 0, 1.0, 100); + strcopy(PD[client].sound_old, 256, PD[client].sound); + } + } +} + +void KSYS_Query_Multi(Database db, DBResultSet results, const char[] error, int client){ + if (!results) return; + int i = 0; + while (results.FetchRow()){ + results.FetchString(0, TEMPSNDS[client][i].sound, 256); + InjectAndLoadSound(TEMPSNDS[client][i].sound); + PrintToConsole(client, "[Fartsy's Killstreak System] Loading file %s!", TEMPSNDS[client][i].sound); + ++i; + } + switch(PD[client].killcount){ + case 5:{ + if (strcmp(TEMPSNDS[client][0].sound, "null") == 0 || strcmp(TEMPSNDS[client][0].sound, "") == 0){ + return; + } + CSEClient(client, TEMPSNDS[client][0].sound, 100, 1, 1.0, 100); + CSEClient(client, TEMPSNDS[client][1].sound, 100, 1, 0.05, 100); + CSEClient(client, TEMPSNDS[client][2].sound, 100, 1, 0.05, 100); + CSEClient(client, TEMPSNDS[client][3].sound, 100, 1, 0.05, 100); + CSEClient(client, TEMPSNDS[client][4].sound, 100, 1, 0.05, 100); + strcopy(PD[client].sound_old, 256, TEMPSNDS[client][0].sound); + } + case 10:{ + if (strcmp(TEMPSNDS[client][1].sound, "null") == 0 || strcmp(TEMPSNDS[client][1].sound, "") == 0) return; + CSEClient(client, TEMPSNDS[client][0].sound, 100, 1, 1.0, 100); + CSEClient(client, TEMPSNDS[client][1].sound, 100, 1, 1.0, 100); + CSEClient(client, TEMPSNDS[client][2].sound, 100, 1, 0.05, 100); + CSEClient(client, TEMPSNDS[client][3].sound, 100, 1, 0.05, 100); + CSEClient(client, TEMPSNDS[client][4].sound, 100, 1, 0.05, 100); + strcopy(PD[client].sound_old, 256, TEMPSNDS[client][1].sound); + } + case 15:{ + if (strcmp(TEMPSNDS[client][2].sound, "null") == 0 || strcmp(TEMPSNDS[client][2].sound, "") == 0) return; + CSEClient(client, TEMPSNDS[client][0].sound, 100, 1, 1.0, 100); + CSEClient(client, TEMPSNDS[client][1].sound, 100, 1, 1.0, 100); + CSEClient(client, TEMPSNDS[client][2].sound, 100, 1, 1.0, 100); + CSEClient(client, TEMPSNDS[client][3].sound, 100, 1, 0.05, 100); + CSEClient(client, TEMPSNDS[client][4].sound, 100, 1, 0.05, 100); + strcopy(PD[client].sound_old, 256, TEMPSNDS[client][2].sound); + } + case 20:{ + if (strcmp(TEMPSNDS[client][3].sound, "null") == 0 || strcmp(TEMPSNDS[client][3].sound, "") == 0) return; + CSEClient(client, TEMPSNDS[client][0].sound, 100, 1, 1.0, 100); + CSEClient(client, TEMPSNDS[client][1].sound, 100, 1, 1.0, 100); + CSEClient(client, TEMPSNDS[client][2].sound, 100, 1, 1.0, 100); + CSEClient(client, TEMPSNDS[client][3].sound, 100, 1, 1.0, 100); + CSEClient(client, TEMPSNDS[client][4].sound, 100, 1, 0.05, 100); + strcopy(PD[client].sound_old, 256, TEMPSNDS[client][3].sound); + } + case 25:{ + if (strcmp(TEMPSNDS[client][4].sound, "null") == 0 || strcmp(TEMPSNDS[client][4].sound, "") == 0) return; + CSEClient(client, TEMPSNDS[client][0].sound, 100, 1, 1.0, 100); + CSEClient(client, TEMPSNDS[client][1].sound, 100, 1, 1.0, 100); + CSEClient(client, TEMPSNDS[client][2].sound, 100, 1, 1.0, 100); + CSEClient(client, TEMPSNDS[client][3].sound, 100, 1, 1.0, 100); + CSEClient(client, TEMPSNDS[client][4].sound, 100, 1, 1.0, 100); + strcopy(PD[client].sound_old, 256, TEMPSNDS[client][4].sound); + } + } +} + +void InjectAndLoadSound(const char[] sound){ + PrecacheSound(sound, true); +} + +//Play sound to client. Ripped straight from potato. AGAIN. Allows us to play sounds directly to people when they join. +void CSEClient(int client, char[] sndName, int TSNDLVL, int flags, float vol, int pitch) { + EmitSoundToClient(client, sndName, _, 6, TSNDLVL, flags, vol, pitch, _, _, _, _, _); +} + +void ResetSound(int client, bool override){ + if (strcmp(PD[client].sound_old, "") != 0 || strcmp(PD[client].sound_old, PD[client].sound) != 0 || override){ + for (int i = 0; i < 10; i++){ + StopSound(client, i, PD[client].sound_old); + if (strcmp(TEMPSNDS[client][i].sound, "") != 0) for (int x = 0; x < 10; x++) StopSound(client, x, TEMPSNDS[client][i].sound); + } + PrintToServer("[Fartsy's Killstreak System] Stopping %s for %N", PD[client].sound_old, client); + Format (PD[client].sound_old, sizeof(PD[client].sound_old), ""); + } +} diff --git a/scripting/LOL/LOLsound.inc b/scripting/LOL/LOLsound.inc new file mode 100644 index 0000000..a1e088e --- /dev/null +++ b/scripting/LOL/LOLsound.inc @@ -0,0 +1,157 @@ +// File Name : LOLSound.inc +// File Version : 1.3 +// File Updated date : 08-10-2013 + +/* + *ê²Œë ›ì˜ íƒí‹°ì»¬ 건모드2ì˜ TGM2sound.incì„ ì°¸ê³ (배껴서..)만든 include íŒŒì¼ + */ +#if defined _LOLsound_included +#endinput +#endif +#define _LOLsound_included + +//소리파ì¼ì˜ 경로와 소리 관련 ìƒìˆ˜ì— 대한 ì •ì˜ëŠ” ì´ê³³ì— 온다 + +#define TOTALSOUND 53 + +//ì¸ìˆ˜ë¡œ 받는 소리 +#define SOUNDFIRSTBLOOD 0 +#define SOUNDALLYSLAIN1 1 +#define SOUNDALLYSLAIN2 2 +#define SOUNDENEMYSLAIN1 3 +#define SOUNDENEMYSLAIN2 4 +#define SOUNDENEMYSLAIN3 5 +#define SOUNDYOUSLAIN1 6 +#define SOUNDYOUSLAIN2 7 +#define SOUNDEXECUTED 8 +#define SOUNDYOUVESLAIN1 9 +#define SOUNDYOUVESLAIN2 10 +#define SOUNDYOUVESLAIN3 11 +#define SOUNDACE1 12 +#define SOUNDACE2 13 +#define SOUNDENEMYDOUBLEKILL1 14 +#define SOUNDENEMYDOUBLEKILL2 15 +#define SOUNDDOUBLEKILL1 16 +#define SOUNDDOUBLEKILL2 17 +#define SOUNDDOUBLEKILL3 18 +#define SOUNDENEMYTRIPLEKILL1 19 +#define SOUNDENEMYTRIPLEKILL2 20 +#define SOUNDTRIPLEKILL1 21 +#define SOUNDTRIPLEKILL2 22 +#define SOUNDENEMYQUADRAKILL 23 +#define SOUNDQUADRAKILL1 24 +#define SOUNDQUADRAKILL2 25 +#define SOUNDENEMYPENTAKILL1 26 +#define SOUNDENEMYPENTAKILL2 27 +#define SOUNDPENTAKILL1 28 +#define SOUNDPENTAKILL2 29 +#define SOUNDSHUTDOWN 30 +#define SOUNDENEMYKILLINGSPREE1 31 +#define SOUNDENEMYKILLINGSPREE2 32 +#define SOUNDKILLINGSPREE1 33 +#define SOUNDKILLINGSPREE2 34 +#define SOUNDENEMYRAMPAGE 35 +#define SOUNDRAMPAGE1 36 +#define SOUNDRAMPAGE2 37 +#define SOUNDENEMYUNSTOPPABLE1 38 +#define SOUNDENEMYUNSTOPPABLE2 39 +#define SOUNDUNSTOPPABLE 40 +#define SOUNDENEMYDOMINATING 41 +#define SOUNDDOMINATING 42 +#define SOUNDENEMYGODLIKE1 43 +#define SOUNDENEMYGODLIKE2 44 +#define SOUNDGODLIKE1 45 +#define SOUNDGODLIKE2 46 +#define SOUNDENEMYLEGENDARY1 47 +#define SOUNDENEMYLEGENDARY2 48 +#define SOUNDLEGENDARY1 49 +#define SOUNDLEGENDARY2 50 +#define SOUNDLEGENDARY3 51 +#define SOUNDSERVERJOIN 52 + +new String:sounddata[TOTALSOUND][128] = +{ + {"LOLannounce_v3/female1_OnFirstBlood_1.mp3"}, + {"LOLannounce_v3/female1_OnChampionKillHeroHero.mp3"}, + {"LOLannounce_v3/female1_OnChampionKillHeroHero_1.mp3"}, + {"LOLannounce_v3/female1_OnChampionKillHeroHero_2.mp3"}, + {"LOLannounce_v3/female1_OnChampionKillHeroHero_5.mp3"}, + {"LOLannounce_v3/female1_OnChampionKillHeroHero_7.mp3"}, + {"LOLannounce_v3/female1_OnChampionKillHeroYouE.mp3"}, + {"LOLannounce_v3/female1_OnChampionKillHeroYouE_1.mp3"}, + {"LOLannounce_v3/female1_OnChampionKillTurretHe_4.mp3"}, + {"LOLannounce_v3/female1_OnChampionKillYouHeroY.mp3"}, + {"LOLannounce_v3/female1_OnChampionKillYouHeroY_1.mp3"}, + {"LOLannounce_v3/female1_OnChampionKillYouHeroY_2.mp3"}, + {"LOLannounce_v3/female1_OnAce_1.mp3"}, + {"LOLannounce_v3/female1_OnAce_2.mp3"}, + {"LOLannounce_v3/female1_OnChampionDoubleKillEn.mp3"}, + {"LOLannounce_v3/female1_OnChampionDoubleKillEn_1.mp3"}, + {"LOLannounce_v3/female1_OnChampionDoubleKillYo.mp3"}, + {"LOLannounce_v3/female1_OnChampionDoubleKillYo_1.mp3"}, + {"LOLannounce_v3/female1_OnChampionDoubleKillYo_2.mp3"}, + {"LOLannounce_v3/female1_OnChampionTripleKillEn.mp3"}, + {"LOLannounce_v3/female1_OnChampionTripleKillEn_1.mp3"}, + {"LOLannounce_v3/female1_OnChampionTripleKillYo.mp3"}, + {"LOLannounce_v3/female1_OnChampionTripleKillYo_1.mp3"}, + {"LOLannounce_v3/female1_OnChampionQuadraKillEn.mp3"}, + {"LOLannounce_v3/female1_OnChampionQuadraKillYo.mp3"}, + {"LOLannounce_v3/female1_OnChampionQuadraKillYo_1.mp3"}, + {"LOLannounce_v3/female1_OnChampionPentaKillEne.mp3"}, + {"LOLannounce_v3/female1_OnChampionPentaKillEne_1.mp3"}, + {"LOLannounce_v3/female1_OnChampionPentaKillYou.mp3"}, + {"LOLannounce_v3/female1_OnChampionPentaKillYou_1.mp3"}, + {"LOLannounce_v3/female1_OnKilledUnitOnKillingS.mp3"}, + {"LOLannounce_v3/female1_OnKillingSpreeSet1Enem.mp3"}, + {"LOLannounce_v3/female1_OnKillingSpreeSet1Enem_1.mp3"}, + {"LOLannounce_v3/female1_OnKillingSpreeSet1Your.mp3"}, + {"LOLannounce_v3/female1_OnKillingSpreeSet1Your_1.mp3"}, + {"LOLannounce_v3/female1_OnKillingSpreeSet2Enem.mp3"}, + {"LOLannounce_v3/female1_OnKillingSpreeSet2Your.mp3"}, + {"LOLannounce_v3/female1_OnKillingSpreeSet2Your_1.mp3"}, + {"LOLannounce_v3/female1_OnKillingSpreeSet3Enem.mp3"}, + {"LOLannounce_v3/female1_OnKillingSpreeSet3Enem_1.mp3"}, + {"LOLannounce_v3/female1_OnKillingSpreeSet3Your.mp3"}, + {"LOLannounce_v3/female1_OnKillingSpreeSet4Enem.mp3"}, + {"LOLannounce_v3/female1_OnKillingSpreeSet4Your.mp3"}, + {"LOLannounce_v3/female1_OnKillingSpreeSet5Enem.mp3"}, + {"LOLannounce_v3/female1_OnKillingSpreeSet5Enem_1.mp3"}, + {"LOLannounce_v3/female1_OnKillingSpreeSet5Your.mp3"}, + {"LOLannounce_v3/female1_OnKillingSpreeSet5Your_1.mp3"}, + {"LOLannounce_v3/female1_OnKillingSpreeSet6Enem.mp3"}, + {"LOLannounce_v3/female1_OnKillingSpreeSet6Enem_1.mp3"}, + {"LOLannounce_v3/female1_OnKillingSpreeSet6Your.mp3"}, + {"LOLannounce_v3/female1_OnKillingSpreeSet6Your_1.mp3"}, + {"LOLannounce_v3/female1_OnKillingSpreeSet6Your_2.mp3"}, + {"LOLannounce_v3/ServerJoinSound.mp3"} +}; + +//함수들 +stock prepatch_and_download_sounds() +{ + new String:prepatch_gamename[64]; + GetGameFolderName(prepatch_gamename, sizeof(prepatch_gamename)); + //소리 프리패치, ì“°ì´ëŠ” 모든 소리를 프리패치하고 다운한다. + for(new i = 0; i < TOTALSOUND; i++){ + + new String:downtemp[256]; + if(StrEqual(prepatch_gamename, "csgo")) + { + Format(downtemp, sizeof(downtemp), "music/%s", sounddata[i]); + PrecacheSound(sounddata[i], true); + Format(downtemp, sizeof(downtemp), "sound/music/%s", sounddata[i]); + } + else + { + PrecacheSound(sounddata[i], true); + Format(downtemp, sizeof(downtemp), "sound/%s", sounddata[i]); + } + AddFileToDownloadsTable(downtemp); + } +} + +stock playsoundfromclient(client, sound){ + + EmitSoundToClient(client, sounddata[sound], SOUND_FROM_PLAYER, SNDCHAN_AUTO, SNDLEVEL_NORMAL, _, volumeValue[client]); + +} \ No newline at end of file diff --git a/scripting/LeagueOfLegendsKillAnnounce.sp b/scripting/LeagueOfLegendsKillAnnounce.sp new file mode 100644 index 0000000..1058f15 --- /dev/null +++ b/scripting/LeagueOfLegendsKillAnnounce.sp @@ -0,0 +1,1131 @@ +/* + * + * File Name : LeagueOfLegendsKillAnnounce.sp + * File Version : 2.8.5 + * File Updated date : 08-10-2013 + * + * ============================================================================= + * League Of Legends Kill Announce Plugin + * Copyright (C)2010-2012 Chamamyungsu All rights reserved. + * ============================================================================= + * + * ì´ í”„ë¡œê·¸ëž¨ì€ ìžìœ  소프트웨어입니다: ë‹¹ì‹ ì€ ì´ê²ƒì„ ìžìœ  소프트웨어 ìž¬ë‹¨ì´ + * 발표한 GNU ì¼ë°˜ 공중 ì‚¬ìš©í—ˆê°€ì„œì˜ ì œ3 버전ì´ë‚˜ (ì„ íƒì— ë”°ë¼) ê·¸ ì´í›„ 버전 + * ì˜ ì¡°í•­ 아래 재배í¬í•˜ê±°ë‚˜ 수정할 수 있습니다. + * + * ì´ í”„ë¡œê·¸ëž¨ì€ ìœ ìš©í•˜ê²Œ ì“°ì´ë¦¬ë¼ëŠ” í¬ë§ 아래 ë°°í¬ë˜ì§€ë§Œ, 특정한 목ì ì— 대한 + * í”„ë¡œê·¸ëž¨ì˜ ì í•©ì„±ì´ë‚˜ ìƒì—…성 ì—¬ë¶€ì— ëŒ€í•œ ë³´ì¦ì„ í¬í•¨í•œ 어떠한 í˜•íƒœì˜ ë³´ì¦ + * ë„ í•˜ì§€ 않습니다. 세부 ì‚¬í•­ì€ GNU ì¼ë°˜ 공중 사용허가서를 참조하십시오. + * + * ë‹¹ì‹ ì€ ì´ í”„ë¡œê·¸ëž¨ê³¼ 함께 GNU ì¼ë°˜ 공중 사용허가서를 ë°›ì•˜ì„ ê²ƒìž…ë‹ˆë‹¤. + * 만약 그렇지 않다면, < http://www.gnu.org/licences/ >를 보십시오. + * + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, version 3.0, as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * + * Edited by DovahkiWarrior. https://forums.firehostredux.net + */ + + +#define PLUGIN_VERSION "2.8.5" +public Plugin:myinfo = +{ + name = "League Of Legends Kill Announce Plugin", + author = "Chamamyungsu", + description = "Made for Server, Thanks to RIOT Games, Javalia", + version = PLUGIN_VERSION, + url = "http://cafe.naver.com/sourcemulti" +}; + +#include +#include +#include "stocklib" + +#pragma semicolon 1 + +#define LKA_FirstBlood (1 << 0) // First Blood +#define LKA_ShutDown (1 << 1) // Shut down +#define LKA_Multikill (1 << 2) // multikill +#define LKA_KillingSpree (1 << 3) // Killing Spree +#define LKA_ACE (1 << 4) // ACE +#define LKA_Slain (1 << 5) // Slain +#define LKA_Executed (1 << 6) // Executed + +#define Type_allAlert 0 +#define Type_chatMessage 1 +#define Type_centerHUD 2 +#define Type_playSound 3 + +/** + * variable : reserveState / Description + * + * First Element : Attacker Index + * Second Element : client (Victim) Index + * Third Element : State Index ; 1-Executed 2-First blood 3-Shut down 4-multikill 5-Killing Spree 6-ACE, 7-Slain + * Fourth Element : Kill Count + */ +new reserveState[MAXPLAYERS+1][4]; + +new bool:roundFirstblood = false; +new Killcount[MAXPLAYERS+1]; +new consecutivelyKill[MAXPLAYERS+1]; +new Float:consecutivelyKill_Timer[MAXPLAYERS+1]; +new Float:announceTimer = 0.0; +new aceCheck[4] = 0; + +new String:gamename[64]; + +new allAlert_Off[MAXPLAYERS+1]; +new chatMessage_Off[MAXPLAYERS+1]; +new centerHUD_Off[MAXPLAYERS+1]; +new playSound_Off[MAXPLAYERS+1]; +new Float:volumeValue[MAXPLAYERS+1] = 1.0; + +new String:path[MAXPLAYERS+1]; +new loadCheck[MAXPLAYERS+1]; + +new Handle:announceTimer_handle = INVALID_HANDLE; + +new Handle:g_consecutivelyKillcontinuetime = INVALID_HANDLE; +new Handle:g_announceCooltime = INVALID_HANDLE; +new Handle:g_killingspree = INVALID_HANDLE; +new Handle:g_rampage = INVALID_HANDLE; +new Handle:g_unstoppable = INVALID_HANDLE; +new Handle:g_dominating = INVALID_HANDLE; +new Handle:g_god_like = INVALID_HANDLE; +new Handle:g_legendary = INVALID_HANDLE; +new Handle:g_slainOn = INVALID_HANDLE; +new Handle:g_oldslainOn = INVALID_HANDLE; +new Handle:g_aceOn= INVALID_HANDLE; +new Handle:g_serverJoinsoundOn = INVALID_HANDLE; +new Handle:g_executedOn= INVALID_HANDLE; +new Handle:g_legendaryRepeat = INVALID_HANDLE; +new Handle:g_pentakillRepeat = INVALID_HANDLE; +new Handle:g_MeleeWeaponList = INVALID_HANDLE; + +#include "LOL/LOLsound" + +public OnPluginStart() +{ + CreateConVar("sm_LOLannounce_version", PLUGIN_VERSION, "Made By Chamamyungsu", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY); + + g_consecutivelyKillcontinuetime = CreateConVar("LOLannounce_ConsecutivelyKillContinueTime", "5", "set the Kill Continue Time (seconds)"); + g_announceCooltime = CreateConVar("LOLannounce_Announce_Cooltime", "2", "set the announce cooltime (seconds)"); + g_killingspree = CreateConVar("LOLannounce_Killingspree", "4", "Kills streak required to trigger sound"); + g_rampage = CreateConVar("LOLannounce_Rampage", "5", "Kills streak required to trigger sound"); + g_unstoppable = CreateConVar("LOLannounce_Unstoppable", "7", "Kills streak required to trigger sound"); + g_dominating = CreateConVar("LOLannounce_Dominating", "10", "Kills streak required to trigger sound"); + g_god_like = CreateConVar("LOLannounce_God_Like", "14", "Kills streak required to trigger sound"); + g_legendary = CreateConVar("LOLannounce_Legendary", "19", "Kills streak required to trigger sound"); + g_slainOn = CreateConVar("LOLannounce_Slainonoff", "1", "Turn on slain event 1 = on, 0 = off"); + g_oldslainOn = CreateConVar("LOLannounce_OldSlainonoff", "0", "(if slain event turn on) Turn on Old slain event 1 = on, 0 = off"); + g_aceOn = CreateConVar("LOLannounce_Aceonoff", "1", "Turn on ace event 1 = on, 0 = off"); + g_legendaryRepeat = CreateConVar("LOLannounce_Legendaryrepeat", "3", "if player has over legendary is when the kill 3 times repeat legendary sound and message (0 = off)"); + g_pentakillRepeat = CreateConVar("LOLannounce_Pentakillrepeat", "1", " Turn on when player has over pentakill is repeat pentakill sound and message 1 = on, 0 = off"); + g_executedOn = CreateConVar("LOLannounce_Executedonoff", "1", " Turn on executed event 1 = on, 0 = off"); + g_serverJoinsoundOn = CreateConVar("LOLannounce_JoinSoundonoff", "1", " Turn on Server join sound 1 = on, 0 = off"); + g_MeleeWeaponList = CreateConVar("LOLannounce_SlayMeleeWeaponList", + "tf_weapon_sword;tf_weapon_wrench;tf_weapon_robot_arm;tf_weapon_fists;tf_weapon_bonesaw;tf_weapon_fireaxe;tf_weapon_bat;tf_weapon_bat_wood;tf_weapon_bat_fish;tf_weapon_club;tf_weapon_shovel;tf_weapon_knife;tf_weapon_stickbomb;tf_weapon_katana;tf_weapon_knife;weapon_knife", + "MeleeWeaponList... ;"); + AutoExecConfig(); + + GetGameFolderName(gamename, sizeof(gamename)); + + BuildPath(Path_SM, path, MAXPLAYERS+1, "data/LOLAnnounceSettings_v2.txt"); + + RegConsoleCmd("sm_lolsettings", Command_Announcemenu, "Open the LOLAnnounce Setting Menu"); + HookEvent("player_spawn", EventSpawn); + HookEvent("player_death", EventDeath); + + if(StrEqual(gamename, "tf")){ + HookEvent("teamplay_round_start", roundstart_event); + } + else if(StrEqual(gamename, "dod")){ + HookEvent("dod_round_start", roundstart_event); + } + else if(StrEqual(gamename, "cstrike") || StrEqual(gamename, "csgo")){ + HookEvent("round_start", roundstart_event); + } + + LoadTranslations("LeagueOfLegendsKillAnnounce.phrases"); + announceTimer_handle = CreateTimer(0.1, announce_timer, _, TIMER_REPEAT); + announceTimer = 0.0; +} + +public Action:Command_Announcemenu(client, args) +{ + settingMenu(client); + return Plugin_Handled; +} + +settingMenu(client) +{ + new Handle:settingmenu = CreateMenu(Menu_Settings); + + SetMenuTitle(settingmenu, "--=LOL Announce Settings=--"); + + decl String:buffer[256]; + if(allAlert_Off[client] == 1) + { + Format(buffer, sizeof(buffer), "%t", "enabled!", "LOLannounce"); + AddMenuItem(settingmenu, " ", buffer); + Format(buffer, sizeof(buffer), "%t%t", "Chat", "Settings"); + AddMenuItem(settingmenu, " ", buffer, ITEMDRAW_DISABLED); + Format(buffer, sizeof(buffer), "%t%t", "Centerhud", "Settings"); + AddMenuItem(settingmenu, " ", buffer, ITEMDRAW_DISABLED); + Format(buffer, sizeof(buffer), "%t%t", "Playsound", "Settings"); + AddMenuItem(settingmenu, " ", buffer, ITEMDRAW_DISABLED); + } + else + { + Format(buffer, sizeof(buffer), "%t", "disabled!", "LOLannounce"); + AddMenuItem(settingmenu, " ", buffer); + Format(buffer, sizeof(buffer), "%t%t", "Chat", "Settings"); + AddMenuItem(settingmenu, " ", buffer); + Format(buffer, sizeof(buffer), "%t%t", "Centerhud", "Settings"); + AddMenuItem(settingmenu, " ", buffer); + Format(buffer, sizeof(buffer), "%t%t", "Playsound", "Settings"); + AddMenuItem(settingmenu, " ", buffer); + } + + SetMenuExitButton(settingmenu, true); + DisplayMenu(settingmenu, client, 20); +} + +public Menu_Settings(Handle:menu, MenuAction:action, client, Select) +{ + if(action == MenuAction_Select) + { + if(Select == Type_allAlert) + { + if(allAlert_Off[client] == 0){ + allAlert_Off[client] = 1; + } + else{ + allAlert_Off[client] = 0; + } + + settingMenu(client); + } + else + settingMenu_Detail(client, Select); + } + + if(action == MenuAction_End) + CloseHandle(menu); +} + +settingMenu_Detail(client, select) +{ + new Handle:settingmenu = CreateMenu(Menu_settingsDetail); + + new String:titleUnitTemp[4][32]={"N/A", "Chat Message","CenterHUD","Sound"}; + new String:nameFormat[64]; + + Format(nameFormat, sizeof(nameFormat), "--=LOL Announce %s Settings=--", titleUnitTemp[select]); + SetMenuTitle(settingmenu, nameFormat); + + decl String:buffer[128], String:selectStr[8]; + IntToString(select, selectStr, sizeof(selectStr)); + new String:inputUnitTemp[7][16]={"Firstblood", "Shutdown","Multikill","Killingspree","Ace","Slain","Executed"}; + + for(new i=0; i<=6; i++) + { + if(IsStateisOff(client, select, 1<= 1.0){ + AddMenuItem(settingmenu, " ", buffer, ITEMDRAW_DISABLED); + } + else{ + AddMenuItem(settingmenu, " ", buffer); + } + + Format(buffer, sizeof(buffer), "%t", "VolumeDown", client); + if(volumeValue[client] <= 0.0){ + AddMenuItem(settingmenu, " ", buffer, ITEMDRAW_DISABLED); + } + else{ + AddMenuItem(settingmenu, " ", buffer); + } + + SetMenuExitButton(settingmenu, true); + SetMenuExitBackButton(settingmenu, true); + DisplayMenu(settingmenu, client, 20); +} + +public Menu_VolumeSettings(Handle:menu, MenuAction:action, client, Select) +{ + if(action == MenuAction_Select) + { + if(Select == 1){ + volumeValue[client] += 0.1; + } + if(Select == 2){ + volumeValue[client] -= 0.1; + } + + VolumeMenu(client); + } + + if(action == MenuAction_Cancel) + { + if(Select == MenuCancel_ExitBack){ + settingMenu(client); + } + } + + if(action == MenuAction_End){ + CloseHandle(menu); + } +} + +public OnMapStart() +{ + AutoExecConfig(); + prepatch_and_download_sounds(); + announceTimer = 0.0; +} + +public EventSpawn(Handle:Spawn_Event, const String:Spawn_Name[], bool:Spawn_Broadcast) +{ + new client = GetClientOfUserId(GetEventInt(Spawn_Event, "userid")); + aceCheck[GetClientTeam(client)] = 0; +} + +public Action:roundstart_event(Handle:Event, const String:Name[], bool:Broadcast) +{ + roundFirstblood = false; + aceCheck[TEAM_RED] = 0; + aceCheck[TEAM_BLUE] = 0; + for(new i=0; i<=MAXPLAYERS*2; i++) + { + if(reserveState[i][2] != 0) + { + reserveState[i][0] = 0; + reserveState[i][1] = 0; + reserveState[i][2] = 0; + reserveState[i][3] = 0; + } + else{ + break; + } + } +} + +public OnClientPutInServer(client) +{ + if(!IsFakeClient(client) && isClientConnectedIngame(client)) + { + Killcount[client] = 0; + consecutivelyKill[client] = 0; + consecutivelyKill_Timer[client] = 0.0; + allAlert_Off[client] = 0; + chatMessage_Off[client] = 0; + centerHUD_Off[client] = 0; + playSound_Off[client] = 0; + volumeValue[client] = 1.0; + + for(new i=1; i<=MAXPLAYERS; i++) + { + if(reserveState[i][2] > 0) + { + if(reserveState[i][0] == client || reserveState[i][1] == client){ + reserveState[i][2] = 0; + } + } + else{ + break; + } + } + + if(GetConVarInt(g_serverJoinsoundOn) == 1){ + playsoundfromclient(client, SOUNDSERVERJOIN); + } + + CreateTimer(2.0, Load, client); + } +} + +public OnClientDisconnect(client) +{ + if(loadCheck[client] == 1){ + Save(client); + } +} + +public Save(client) +{ + if(client > 0 && IsClientInGame(client)) + { + new String:SteamID[32]; + GetClientAuthString(client, SteamID, 32); + + decl Handle:Vault; + + Vault = CreateKeyValues("Vault"); + + if(FileExists(path)){ + FileToKeyValues(Vault, path); + } + + if(allAlert_Off[client] == 1) + { + KvJumpToKey(Vault, "allAlert_Off", true); + KvSetNum(Vault, SteamID, allAlert_Off[client]); + KvRewind(Vault); + } + else + { + KvJumpToKey(Vault, "allAlert_Off", false); + KvDeleteKey(Vault, SteamID); + KvRewind(Vault); + } + + if(chatMessage_Off[client] >= 1) + { + KvJumpToKey(Vault, "chatMessage_Off", true); + KvSetNum(Vault, SteamID, chatMessage_Off[client]); + KvRewind(Vault); + } + else + { + KvJumpToKey(Vault, "chatMessage_Off", false); + KvDeleteKey(Vault, SteamID); + KvRewind(Vault); + } + + if(centerHUD_Off[client] >= 1) + { + KvJumpToKey(Vault, "centerHUD_Off", true); + KvSetNum(Vault, SteamID, centerHUD_Off[client]); + KvRewind(Vault); + } + else + { + KvJumpToKey(Vault, "centerHUD_Off", false); + KvDeleteKey(Vault, SteamID); + KvRewind(Vault); + } + + if(playSound_Off[client] >= 1) + { + KvJumpToKey(Vault, "playSound_Off", true); + KvSetNum(Vault, SteamID, playSound_Off[client]); + KvRewind(Vault); + } + else + { + KvJumpToKey(Vault, "playSound_Off", false); + KvDeleteKey(Vault, SteamID); + KvRewind(Vault); + } + + if(volumeValue[client] != 1.0) + { + KvJumpToKey(Vault, "Volumevalue", true); + KvSetFloat(Vault, SteamID, volumeValue[client]); + KvRewind(Vault); + } + else + { + KvJumpToKey(Vault, "Volumevalue", false); + KvDeleteKey(Vault, SteamID); + KvRewind(Vault); + } + + KvRewind(Vault); + + loadCheck[client] = 0; + + KeyValuesToFile(Vault, path); + CloseHandle(Vault); + } +} + +public Action:Load(Handle:Timer, any:client) +{ + if(client > 0 && client <= MaxClients) + { + new String:SteamID[32]; + GetClientAuthString(client, SteamID, 32); + + decl Handle:Vault; + + Vault = CreateKeyValues("Vault"); + + FileToKeyValues(Vault, path); + + KvJumpToKey(Vault, "allAlert_Off", false); + allAlert_Off[client] = KvGetNum(Vault, SteamID); + KvRewind(Vault); + + KvJumpToKey(Vault, "chatMessage_Off", false); + chatMessage_Off[client] = KvGetNum(Vault, SteamID); + KvRewind(Vault); + + KvJumpToKey(Vault, "centerHUD_Off", false); + centerHUD_Off[client] = KvGetNum(Vault, SteamID); + KvRewind(Vault); + + KvJumpToKey(Vault, "playSound_Off", false); + playSound_Off[client] = KvGetNum(Vault, SteamID); + KvRewind(Vault); + + KvJumpToKey(Vault, "Volumevalue", false); + volumeValue[client] = KvGetFloat(Vault, SteamID, 1.0); + KvRewind(Vault); + + loadCheck[client] = 1; + + KvRewind(Vault); + CloseHandle(Vault); + } +} + +public Action:EventDeath(Handle:Spawn_Event, const String:Spawn_Name[], bool:Spawn_Broadcast) +{ + new client = GetClientOfUserId(GetEventInt(Spawn_Event, "userid")); + new attacker = GetClientOfUserId(GetEventInt(Spawn_Event, "attacker")); + + new String:weapon[32]; + GetEventString(Spawn_Event, "weapon", weapon, sizeof(weapon)); + + if(!(client == 0) && !(attacker == 0)) + { + //Event Check + if(client == attacker) + { + if(GetConVarInt(g_executedOn) == 1){ + announce_reserve(attacker, client, 1, 0); + } + } + else + { + new Float:now = GetEngineTime(); + + if(consecutivelyKill_Timer[attacker] <= now){ + consecutivelyKill[attacker] = 0; + } + consecutivelyKill_Timer[attacker] = GetEngineTime() + GetConVarInt(g_consecutivelyKillcontinuetime); + consecutivelyKill[attacker] += 1; + Killcount[attacker] += 1; + + if(roundFirstblood == false && attacker > 0 && client != attacker) + { + roundFirstblood = true; + announce_reserve(attacker, client, 2, 0); + + if(Killcount[client] >= GetConVarInt(g_killingspree)){ + announce_reserve(attacker, client, 3, consecutivelyKill[attacker]); + } + } + else if(Killcount[client] >= GetConVarInt(g_killingspree)){ + announce_reserve(attacker, client, 3, consecutivelyKill[attacker]); + } + else if(consecutivelyKill[attacker] >= 2){ + announce_reserve(attacker, client, 4, consecutivelyKill[attacker]); + } + else if(GetConVarInt(g_slainOn) == 1 && isplayerKillingSpree(attacker) == 0) + { + if(GetConVarInt(g_oldslainOn) == 1){ + announce_reserve(attacker, client, 7, consecutivelyKill[attacker]); + } + else if(IsSlainWeapon(weapon)){ + announce_reserve(attacker, client, 7, consecutivelyKill[attacker]); + } + } + + if(isplayerKillingSpree(attacker) == 1) + { + if(Killcount[attacker] > GetConVarInt(g_legendary) && GetConVarInt(g_legendaryRepeat) > 0) + { + if((Killcount[attacker]-GetConVarInt(g_legendary))%GetConVarInt(g_legendaryRepeat) == 0){ + announce_reserve(attacker, client, 5, Killcount[attacker]); + } + } + else{ + announce_reserve(attacker, client, 5, Killcount[attacker]); + } + } + } + acecheckevent(attacker, client); + + if(announceTimer == 0.0){ + announceTimer = GetEngineTime(); + } + Killcount[client] = 0; + } + else if(!(client == 0) && (attacker == 0)) + { + if(GetConVarInt(g_executedOn) == 1){ + announce_reserve(attacker, client, 1, 0); + } + } +} + +isplayerKillingSpree(attacker) +{ + if(Killcount[attacker] == GetConVarInt(g_killingspree) || Killcount[attacker] == GetConVarInt(g_rampage) || Killcount[attacker] == GetConVarInt(g_unstoppable) || Killcount[attacker] == GetConVarInt(g_dominating) || Killcount[attacker] == GetConVarInt(g_god_like) || Killcount[attacker] >= GetConVarInt(g_legendary)){ + return 1; + } + else{ + return 0; + } +} + +acecheckevent(attacker, client) +{ + if(GetConVarInt(g_aceOn) == 1) + { + if(aceCheck[GetClientTeam(client)] == 0) + { + new bool:clientTeamisAce=true; + for(new i=1; i<=MaxClients; i++) + { + if(isClientConnectedIngameAlive(i) && GetClientTeam(client) == GetClientTeam(i) && client != i) + { + clientTeamisAce = false; + break; + } + } + if(clientTeamisAce == true) + { + aceCheck[GetClientTeam(client)] = 1; + announce_reserve(attacker, client, 6, 0); + return 1; + } + } + } + return 0; +} + +public Action:announce_timer(Handle:timer) +{ + new Float:now = GetEngineTime(); + + if(announceTimer <= now) + { + if(reserveState[0][2] > 0) + { + for(new i=1; i<=MaxClients; i++) + { + if(isClientConnectedIngame(reserveState[0][0]) && isClientConnectedIngame(reserveState[0][1])) + { + if(isClientConnectedIngame(i) && allAlert_Off[i] == 0) + { + decl String:attackername[64], String:clientname[64]; + GetClientName(reserveState[0][0], attackername, 64); + if(reserveState[0][1] > 0){ + GetClientName(reserveState[0][1], clientname, 64); + } + + new teamtemp = GetClientTeam(reserveState[0][0]); + + ///// Execute Event ///// + if(reserveState[0][2] == 1) + { + if(!(playSound_Off[i] & LKA_Executed)){ + playsoundfromclient(i, SOUNDEXECUTED); + } + + if(!(centerHUD_Off[i] & LKA_Executed)){ + PrintCenterText(i, "%t", "{1} has executed!", attackername); + } + } + + ///// First Blood Event ///// + else if(reserveState[0][2] == 2) + { + if(!(playSound_Off[i] & LKA_FirstBlood)){ + playsoundfromclient(i, SOUNDFIRSTBLOOD); + } + + if(!(chatMessage_Off[i] & LKA_FirstBlood)){ + PrintToChat(i, "\x05%t", "{1} has drawn first blood!", attackername); + } + + if(!(centerHUD_Off[i] & LKA_FirstBlood)){ + PrintCenterText(i, "%t", "centerfirstblood", i); + } + } + + ///// Shut Down Event ///// + else if(reserveState[0][2] == 3) + { + if(!(playSound_Off[i] & LKA_ShutDown)){ + playsoundfromclient(i, SOUNDSHUTDOWN); + } + + if(!(chatMessage_Off[i] & LKA_ShutDown)) + { + if(reserveState[0][3] == 1 || (reserveState[0][3] > 5 && GetConVarInt(g_pentakillRepeat) == 0)){ + PrintToChat(i, "\x05%t", "{1} has ended {2}'s killing spree", attackername, clientname); + } + if(reserveState[0][3] == 2){ + PrintToChat(i, "\x05%t", "{1} has ended {2}'s killing spree for a double kill!", attackername, clientname); + } + if(reserveState[0][3] == 3){ + PrintToChat(i, "\x05%t", "{1} has ended {2}'s killing spree for a triple kill!", attackername, clientname); + } + if(reserveState[0][3] == 4){ + PrintToChat(i, "\x05%t", "{1} has ended {2}'s killing spree for a quadra kill!", attackername, clientname); + } + if((reserveState[0][3] >= 5 && GetConVarInt(g_pentakillRepeat) == 1) || (reserveState[0][3] == 5 && GetConVarInt(g_pentakillRepeat) == 0)){ + PrintToChat(i, "\x05%t", "{1} has ended {2}'s killing spree for a penta kill!", attackername, clientname); + } + } + + if(!(centerHUD_Off[i] & LKA_ShutDown)){ + PrintCenterText(i, "%t", "centershutdown", i); + } + } + + ///// Multi Kill Event ///// + else if(reserveState[0][2] == 4) + { + if(reserveState[0][3] == 2) + { + if(!(chatMessage_Off[i] & LKA_Multikill)){ + PrintToChat(i, "\x05%t", "{1} has slain {2} for a double kill!", attackername, clientname); + } + + if(!(centerHUD_Off[i] & LKA_Multikill)){ + PrintCenterText(i, "%t", "centerdoublekill", i); + } + + if(!(playSound_Off[i] & LKA_Multikill)) + { + if(teamtemp == GetClientTeam(i)){ + playsoundfromclient(i, GetRandomInt(16, 18)); + } + else{ + playsoundfromclient(i, GetRandomInt(14, 15)); + } + } + } + else if(reserveState[0][3] == 3) + { + if(!(chatMessage_Off[i] & LKA_Multikill)) + PrintToChat(i, "\x05%t", "{1} has slain {2} for a triple kill!", attackername, clientname); + if(!(centerHUD_Off[i] & LKA_Multikill)) + PrintCenterText(i, "%t", "centertriplekill", i); + if(!(playSound_Off[i] & LKA_Multikill)) + { + if(teamtemp == GetClientTeam(i)) + playsoundfromclient(i, GetRandomInt(21, 22)); + else + playsoundfromclient(i, GetRandomInt(19, 20)); + } + } + else if(reserveState[0][3] == 4) + { + if(!(chatMessage_Off[i] & LKA_Multikill)) + PrintToChat(i, "\x05%t", "{1} has slain {2} for a quadra kill!", attackername, clientname); + if(!(centerHUD_Off[i] & LKA_Multikill)) + PrintCenterText(i, "%t", "centerquadrakill", i); + if(!(playSound_Off[i] & LKA_Multikill)) + { + if(teamtemp == GetClientTeam(i)) + playsoundfromclient(i, GetRandomInt(24, 25)); + else + playsoundfromclient(i, SOUNDENEMYQUADRAKILL); + } + } + else if((reserveState[0][3] >= 5 && GetConVarInt(g_pentakillRepeat) == 1) || (reserveState[0][3] == 5 && GetConVarInt(g_pentakillRepeat) == 0)) + { + if(!(chatMessage_Off[i] & LKA_Multikill)) + PrintToChat(i, "\x05%t", "{1} has slain {2} for a penta kill!", attackername, clientname); + if(!(centerHUD_Off[i] & LKA_Multikill)) + PrintCenterText(i, "%t", "centerpentakill", i); + if(!(playSound_Off[i] & LKA_Multikill)) + { + if(teamtemp == GetClientTeam(i)) + playsoundfromclient(i, GetRandomInt(28, 29)); + else + playsoundfromclient(i, GetRandomInt(26, 27)); + } + } + } + + ///// Killing Spree Event ////// + else if(reserveState[0][2] == 5) + { + if(reserveState[0][3] == GetConVarInt(g_killingspree)) + { + if(!(chatMessage_Off[i] & LKA_KillingSpree)){ + PrintToChat(i, "\x05%t", "{1} is on a killing spree!", attackername); + } + + if(!(centerHUD_Off[i] & LKA_KillingSpree)){ + PrintCenterText(i, "%t", "{1} is on a killing spree!", attackername); + } + + if(!(playSound_Off[i] & LKA_KillingSpree)) + { + if(teamtemp == GetClientTeam(i)){ + playsoundfromclient(i, GetRandomInt(33, 34)); + } + else{ + playsoundfromclient(i, GetRandomInt(31, 32)); + } + } + } + else if(reserveState[0][3] == GetConVarInt(g_rampage)) + { + if(!(chatMessage_Off[i] & LKA_KillingSpree)){ + PrintToChat(i, "\x05%t", "{1} is on a rampage!", attackername); + } + + if(!(centerHUD_Off[i] & LKA_KillingSpree)){ + PrintCenterText(i, "%t", "{1} is on a rampage!", attackername); + } + + if(!(playSound_Off[i] & LKA_KillingSpree)) + { + if(teamtemp == GetClientTeam(i)){ + playsoundfromclient(i, GetRandomInt(36, 37)); + } + else{ + playsoundfromclient(i, SOUNDENEMYRAMPAGE); + } + } + } + else if(reserveState[0][3] == GetConVarInt(g_unstoppable)) + { + if(!(chatMessage_Off[i] & LKA_KillingSpree)){ + PrintToChat(i, "\x05%t", "{1} is unstoppable!", attackername); + } + + if(!(centerHUD_Off[i] & LKA_KillingSpree)){ + PrintCenterText(i, "%t", "{1} is unstoppable!", attackername); + } + + if(!(playSound_Off[i] & LKA_KillingSpree)) + { + if(teamtemp == GetClientTeam(i)){ + playsoundfromclient(i, SOUNDUNSTOPPABLE); + } + else{ + playsoundfromclient(i, GetRandomInt(38, 39)); + } + } + } + else if(reserveState[0][3] == GetConVarInt(g_dominating)) + { + if(!(chatMessage_Off[i] & LKA_KillingSpree)){ + PrintToChat(i, "\x05%t", "{1} is dominating!", attackername); + } + + if(!(centerHUD_Off[i] & LKA_KillingSpree)){ + PrintCenterText(i, "%t", "{1} is dominating!", attackername); + } + + if(!(playSound_Off[i] & LKA_KillingSpree)) + { + if(teamtemp == GetClientTeam(i)){ + playsoundfromclient(i, SOUNDDOMINATING); + } + else{ + playsoundfromclient(i, SOUNDENEMYDOMINATING); + } + } + } + else if(reserveState[0][3] == GetConVarInt(g_god_like)) + { + if(!(chatMessage_Off[i] & LKA_KillingSpree)){ + PrintToChat(i, "\x05%t", "{1} is god like!", attackername); + } + + if(!(centerHUD_Off[i] & LKA_KillingSpree)){ + PrintCenterText(i, "%t", "{1} is god like!", attackername); + } + + if(!(playSound_Off[i] & LKA_KillingSpree)) + { + if(teamtemp == GetClientTeam(i)){ + playsoundfromclient(i, GetRandomInt(45, 46)); + } + else{ + playsoundfromclient(i, GetRandomInt(43, 44)); + } + } + } + else if(reserveState[0][3] == GetConVarInt(g_legendary)) + { + if(!(chatMessage_Off[i] & LKA_KillingSpree)){ + PrintToChat(i, "\x05%t", "{1} is legendary!", attackername); + } + + if(!(centerHUD_Off[i] & LKA_KillingSpree)){ + PrintCenterText(i, "%t", "{1} is legendary!", attackername); + } + + if(!(playSound_Off[i] & LKA_KillingSpree)) + { + if(teamtemp == GetClientTeam(i)){ + playsoundfromclient(i, GetRandomInt(49, 51)); + } + else{ + playsoundfromclient(i, GetRandomInt(47, 48)); + } + } + } + } + + ///// ACE Event ///// + else if(reserveState[0][2] == 6) + { + if(!(playSound_Off[i] & LKA_ACE)){ + playsoundfromclient(i, GetRandomInt(12, 13)); + } + + if(!(centerHUD_Off[i] & LKA_ACE)){ + PrintCenterText(i, "%t", "ACE!", i); + } + + if(!(chatMessage_Off[i] & LKA_ACE)) + { + if(GetClientTeam(reserveState[0][1]) == GetClientTeam(i)){ + PrintToChat(i, "\x05%t", "ENEMY ACE!", i); + } + else{ + PrintToChat(i, "\x05%t", "ALLY ACE!", i); + } + } + } + + ///// Slain Event ///// + else if(reserveState[0][2] == 7) + { + if(acecheckevent(reserveState[0][0], reserveState[0][1]) == 0) + { + if(!(centerHUD_Off[i] & LKA_Slain)){ + PrintCenterText(i, "%t", "{1} has slain {2}!", attackername, clientname); + } + else if(!(chatMessage_Off[i] & LKA_Slain)){ + PrintToChat(i, "%t", "{1} has slain {2}!", attackername, clientname); + } + + if(teamtemp == GetClientTeam(i)) + { + if(!(playSound_Off[i] & LKA_Slain)) + { + if(i == reserveState[0][0]){ + playsoundfromclient(i, GetRandomInt(9, 11)); + } + else{ + playsoundfromclient(i, GetRandomInt(3, 5)); + } + } + } + else + { + if(!(playSound_Off[i] & LKA_Slain)) + { + if(i == reserveState[0][1]){ + playsoundfromclient(i, GetRandomInt(6, 7)); + } + else{ + playsoundfromclient(i, GetRandomInt(1, 2)); + } + } + } + } + } + } + } + } + + for(new i=1; i<=MAXPLAYERS; i++) + { + if(reserveState[i][2] > 0) + { + for(new ii=0; ii<=3; ii++){ + reserveState[i-1][ii] = reserveState[i][ii]; + } + } + else + { + for(new ii=0; ii<=3; ii++){ + reserveState[i-1][ii] = 0; + } + break; + } + } + + announceTimer = GetEngineTime() + GetConVarInt(g_announceCooltime); + } + } +} + +public announce_reserve(attacker, client, num, kscount) +{ + for(new i=0; i<=MAXPLAYERS; i++) + { + if(reserveState[i][0] == attacker && reserveState[i][2] == 4 && num == 4) + { + if(reserveState[i][3] < kscount) + { + reserveState[i][1] = client; + reserveState[i][3] = kscount; + break; + } + } + else if(reserveState[i][2] == 0) + { + reserveState[i][0] = attacker; + reserveState[i][1] = client; + reserveState[i][2] = num; + reserveState[i][3] = kscount; + break; + } + } +} + +bool:IsSlainWeapon(const String:weaponname[]) +{ + decl String:convarstring[256]; + GetConVarString(g_MeleeWeaponList, convarstring, 256); + + if(StrContains(convarstring, weaponname, false) != -1){ + return true; + } + return false; +} + +public OnMapEnd() +{ + if(announceTimer_handle != INVALID_HANDLE) + announceTimer_handle = INVALID_HANDLE; +} \ No newline at end of file diff --git a/scripting/README.md b/scripting/README.md new file mode 100644 index 0000000..fff6f24 --- /dev/null +++ b/scripting/README.md @@ -0,0 +1,2 @@ +# fartsys SMScripts +Fartsalot's Sourcemod mods, repo is messy at the moment. Please bear with us. \ No newline at end of file diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/ace.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/ace.mp3.bz2 new file mode 100644 index 0000000..606daf1 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/ace.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/allyslain.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/allyslain.mp3.bz2 new file mode 100644 index 0000000..68ee02f Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/allyslain.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/dominating.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/dominating.mp3.bz2 new file mode 100644 index 0000000..221498d Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/dominating.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/doublekill.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/doublekill.mp3.bz2 new file mode 100644 index 0000000..7be21cf Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/doublekill.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/doublekill_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/doublekill_1.mp3.bz2 new file mode 100644 index 0000000..2592ccd Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/doublekill_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/doublekill_quake.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/doublekill_quake.mp3.bz2 new file mode 100644 index 0000000..9094ac7 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/doublekill_quake.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemydominating.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemydominating.mp3.bz2 new file mode 100644 index 0000000..328829f Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemydominating.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemydoublekill.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemydoublekill.mp3.bz2 new file mode 100644 index 0000000..83f7c97 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemydoublekill.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemydoublekill_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemydoublekill_1.mp3.bz2 new file mode 100644 index 0000000..f717957 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemydoublekill_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemygodlike.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemygodlike.mp3.bz2 new file mode 100644 index 0000000..3c92a98 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemygodlike.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemygodlike_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemygodlike_1.mp3.bz2 new file mode 100644 index 0000000..21fb230 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemygodlike_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemyinhib_res.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemyinhib_res.mp3.bz2 new file mode 100644 index 0000000..eeb7904 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemyinhib_res.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemyinhib_ressoon.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemyinhib_ressoon.mp3.bz2 new file mode 100644 index 0000000..08a5bfd Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemyinhib_ressoon.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemykillingspree.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemykillingspree.mp3.bz2 new file mode 100644 index 0000000..df96b82 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemykillingspree.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemykillingspree_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemykillingspree_1.mp3.bz2 new file mode 100644 index 0000000..101c33e Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemykillingspree_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemylegendary.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemylegendary.mp3.bz2 new file mode 100644 index 0000000..d00b8fc Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemylegendary.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemylegendary_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemylegendary_1.mp3.bz2 new file mode 100644 index 0000000..43e8ae0 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemylegendary_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemypentakill.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemypentakill.mp3.bz2 new file mode 100644 index 0000000..13c4256 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemypentakill.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemypentakill_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemypentakill_1.mp3.bz2 new file mode 100644 index 0000000..4f7fd65 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemypentakill_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemyquadrakill.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemyquadrakill.mp3.bz2 new file mode 100644 index 0000000..5cefda9 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemyquadrakill.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemyrampage.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemyrampage.mp3.bz2 new file mode 100644 index 0000000..0a51ac3 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemyrampage.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemyslain.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemyslain.mp3.bz2 new file mode 100644 index 0000000..a5fde11 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemyslain.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemytriplekill.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemytriplekill.mp3.bz2 new file mode 100644 index 0000000..e834599 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemytriplekill.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemytriplekill_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemytriplekill_1.mp3.bz2 new file mode 100644 index 0000000..7debd98 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemytriplekill_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemyunstoppable.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemyunstoppable.mp3.bz2 new file mode 100644 index 0000000..d7666f6 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemyunstoppable.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemyunstoppable_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemyunstoppable_1.mp3.bz2 new file mode 100644 index 0000000..7ea4708 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/enemyunstoppable_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/executed.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/executed.mp3.bz2 new file mode 100644 index 0000000..f5ffc69 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/executed.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/firstblood.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/firstblood.mp3.bz2 new file mode 100644 index 0000000..2e7eb8a Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/firstblood.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/godlike.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/godlike.mp3.bz2 new file mode 100644 index 0000000..09a15f3 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/godlike.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/godlike_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/godlike_1.mp3.bz2 new file mode 100644 index 0000000..0ae307b Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/godlike_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/killingspree.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/killingspree.mp3.bz2 new file mode 100644 index 0000000..13a97ad Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/killingspree.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/killingspree_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/killingspree_1.mp3.bz2 new file mode 100644 index 0000000..e4bc216 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/killingspree_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/legendary.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/legendary.mp3.bz2 new file mode 100644 index 0000000..cb4abad Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/legendary.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/legendary_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/legendary_1.mp3.bz2 new file mode 100644 index 0000000..ad84857 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/legendary_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/pentakill.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/pentakill.mp3.bz2 new file mode 100644 index 0000000..ee5a06d Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/pentakill.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/pentakill_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/pentakill_1.mp3.bz2 new file mode 100644 index 0000000..f070e71 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/pentakill_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/quadrakill.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/quadrakill.mp3.bz2 new file mode 100644 index 0000000..b3579bc Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/quadrakill.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/quadrakill_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/quadrakill_1.mp3.bz2 new file mode 100644 index 0000000..1bca397 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/quadrakill_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/rampage.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/rampage.mp3.bz2 new file mode 100644 index 0000000..d6fe729 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/rampage.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/rampage_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/rampage_1.mp3.bz2 new file mode 100644 index 0000000..c7d1485 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/rampage_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/shutdown.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/shutdown.mp3.bz2 new file mode 100644 index 0000000..2666e84 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/shutdown.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/triplekill.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/triplekill.mp3.bz2 new file mode 100644 index 0000000..24e7dc3 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/triplekill.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/triplekill_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/triplekill_1.mp3.bz2 new file mode 100644 index 0000000..f095886 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/triplekill_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/unstoppable.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/unstoppable.mp3.bz2 new file mode 100644 index 0000000..d7c233a Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/unstoppable.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/welcome.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/welcome.mp3.bz2 new file mode 100644 index 0000000..1eae1c7 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/welcome.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/youhavebeenslain.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/youhavebeenslain.mp3.bz2 new file mode 100644 index 0000000..8dbcb1b Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/youhavebeenslain.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/youhaveslain.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/youhaveslain.mp3.bz2 new file mode 100644 index 0000000..e986c92 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/jeffy/league/youhaveslain.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/ace.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/ace.mp3.bz2 new file mode 100644 index 0000000..f9d41a5 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/ace.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/ace_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/ace_1.mp3.bz2 new file mode 100644 index 0000000..22869b6 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/ace_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/allyslain.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/allyslain.mp3.bz2 new file mode 100644 index 0000000..e518d91 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/allyslain.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/allyslain_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/allyslain_1.mp3.bz2 new file mode 100644 index 0000000..2b53473 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/allyslain_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/dominating.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/dominating.mp3.bz2 new file mode 100644 index 0000000..c10c036 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/dominating.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/doublekill.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/doublekill.mp3.bz2 new file mode 100644 index 0000000..263ce7b Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/doublekill.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/doublekill_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/doublekill_1.mp3.bz2 new file mode 100644 index 0000000..9530be2 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/doublekill_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/doublekill_2.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/doublekill_2.mp3.bz2 new file mode 100644 index 0000000..b669c36 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/doublekill_2.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/enemydominating.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemydominating.mp3.bz2 new file mode 100644 index 0000000..5aac607 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemydominating.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/enemydoublekill.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemydoublekill.mp3.bz2 new file mode 100644 index 0000000..26dd3dc Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemydoublekill.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/enemydoublekill_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemydoublekill_1.mp3.bz2 new file mode 100644 index 0000000..b14fd17 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemydoublekill_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/enemygodlike.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemygodlike.mp3.bz2 new file mode 100644 index 0000000..68d75d4 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemygodlike.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/enemygodlike_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemygodlike_1.mp3.bz2 new file mode 100644 index 0000000..6c66a93 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemygodlike_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/enemykillingspree.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemykillingspree.mp3.bz2 new file mode 100644 index 0000000..096104a Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemykillingspree.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/enemykillingspree_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemykillingspree_1.mp3.bz2 new file mode 100644 index 0000000..1c9885b Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemykillingspree_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/enemylegendary.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemylegendary.mp3.bz2 new file mode 100644 index 0000000..68931b6 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemylegendary.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/enemylegendary_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemylegendary_1.mp3.bz2 new file mode 100644 index 0000000..c3529ff Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemylegendary_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/enemypentakill.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemypentakill.mp3.bz2 new file mode 100644 index 0000000..d865f65 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemypentakill.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/enemypentakill_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemypentakill_1.mp3.bz2 new file mode 100644 index 0000000..35008f2 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemypentakill_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/enemyquadrakill.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemyquadrakill.mp3.bz2 new file mode 100644 index 0000000..2dba358 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemyquadrakill.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/enemyrampage.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemyrampage.mp3.bz2 new file mode 100644 index 0000000..b04e3e0 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemyrampage.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/enemyslain.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemyslain.mp3.bz2 new file mode 100644 index 0000000..d9879ac Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemyslain.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/enemyslain_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemyslain_1.mp3.bz2 new file mode 100644 index 0000000..179e8cd Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemyslain_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/enemyslain_2.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemyslain_2.mp3.bz2 new file mode 100644 index 0000000..48f2c39 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemyslain_2.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/enemytriplekill.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemytriplekill.mp3.bz2 new file mode 100644 index 0000000..beae2d9 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemytriplekill.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/enemytriplekill_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemytriplekill_1.mp3.bz2 new file mode 100644 index 0000000..b04f7c9 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemytriplekill_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/enemyunstoppable.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemyunstoppable.mp3.bz2 new file mode 100644 index 0000000..81d927f Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemyunstoppable.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/enemyunstoppable_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemyunstoppable_1.mp3.bz2 new file mode 100644 index 0000000..1b67f0f Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/enemyunstoppable_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/executed.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/executed.mp3.bz2 new file mode 100644 index 0000000..4703ad3 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/executed.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/firstblood.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/firstblood.mp3.bz2 new file mode 100644 index 0000000..5c54ed8 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/firstblood.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/godlike.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/godlike.mp3.bz2 new file mode 100644 index 0000000..fd70dc3 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/godlike.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/godlike_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/godlike_1.mp3.bz2 new file mode 100644 index 0000000..09c7bc4 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/godlike_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/killingspree.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/killingspree.mp3.bz2 new file mode 100644 index 0000000..1976bf6 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/killingspree.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/killingspree_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/killingspree_1.mp3.bz2 new file mode 100644 index 0000000..1ef87e7 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/killingspree_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/legendary.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/legendary.mp3.bz2 new file mode 100644 index 0000000..16a1e82 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/legendary.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/legendary_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/legendary_1.mp3.bz2 new file mode 100644 index 0000000..12910a1 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/legendary_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/legendary_2.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/legendary_2.mp3.bz2 new file mode 100644 index 0000000..672561c Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/legendary_2.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/pentakill.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/pentakill.mp3.bz2 new file mode 100644 index 0000000..b320133 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/pentakill.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/pentakill_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/pentakill_1.mp3.bz2 new file mode 100644 index 0000000..3e0ba8f Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/pentakill_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/quadrakill.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/quadrakill.mp3.bz2 new file mode 100644 index 0000000..0df1c8a Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/quadrakill.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/quadrakill_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/quadrakill_1.mp3.bz2 new file mode 100644 index 0000000..b7a8a47 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/quadrakill_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/rampage.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/rampage.mp3.bz2 new file mode 100644 index 0000000..c5941b0 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/rampage.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/rampage_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/rampage_1.mp3.bz2 new file mode 100644 index 0000000..19187fb Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/rampage_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/shutdown.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/shutdown.mp3.bz2 new file mode 100644 index 0000000..2dd4701 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/shutdown.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/triplekill.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/triplekill.mp3.bz2 new file mode 100644 index 0000000..79c8bab Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/triplekill.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/triplekill_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/triplekill_1.mp3.bz2 new file mode 100644 index 0000000..ef7f7aa Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/triplekill_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/unstoppable.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/unstoppable.mp3.bz2 new file mode 100644 index 0000000..0d9940c Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/unstoppable.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/welcome.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/welcome.mp3.bz2 new file mode 100644 index 0000000..00620c7 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/welcome.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/youhavebeenslain.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/youhavebeenslain.mp3.bz2 new file mode 100644 index 0000000..350961b Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/youhavebeenslain.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/youhavebeenslain_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/youhavebeenslain_1.mp3.bz2 new file mode 100644 index 0000000..8d73182 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/youhavebeenslain_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/youhaveslain.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/youhaveslain.mp3.bz2 new file mode 100644 index 0000000..2d291ac Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/youhaveslain.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/youhaveslain_1.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/youhaveslain_1.mp3.bz2 new file mode 100644 index 0000000..0d52fef Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/youhaveslain_1.mp3.bz2 differ diff --git a/scripting/TF2 LOL Server/bz2/sound/vo/league/youhaveslain_2.mp3.bz2 b/scripting/TF2 LOL Server/bz2/sound/vo/league/youhaveslain_2.mp3.bz2 new file mode 100644 index 0000000..b297925 Binary files /dev/null and b/scripting/TF2 LOL Server/bz2/sound/vo/league/youhaveslain_2.mp3.bz2 differ diff --git a/scripting/TimedRestarts.sp b/scripting/TimedRestarts.sp new file mode 100644 index 0000000..7239eaa --- /dev/null +++ b/scripting/TimedRestarts.sp @@ -0,0 +1,130 @@ +//Simple script setup +#pragma semicolon 1 + +#include +#include + +//Give plugin info +public Plugin:myinfo = +{ + name = "Timed Restarts", + author = "Dovahkiin-Warrior", + description = "Restarts a server every 12 hours or by manual control", + version = "1.0.0", + url = "https://forums.firehostredux.com" +}; + +//Initiate the core, register required commands & Precache and Allocate files +public OnPluginStart() +{ + PrintToServer("***Auto Restart Module: INITIATED***"), + RegAdminCmd("sm_restart", Command_RestartServer, ADMFLAG_ROOT, "Restart the server safely"), + RegAdminCmd("sm_restart_1h", Command_RestartServer1H, ADMFLAG_ROOT, "Restart the server in one hour"); + RegAdminCmd("sm_restart_30m", Command_RestartServer30M, ADMFLAG_ROOT, "Restart the server in thirty minutes"); + RegAdminCmd("sm_restart_15m", Command_RestartServer15M, ADMFLAG_ROOT, "Restart the server in fifteen minutes"); + RegAdminCmd("sm_restart_10m", Command_RestartServer10M, ADMFLAG_ROOT, "Restart the server in ten minutes"); + RegAdminCmd("sm_restart_5m", Command_RestartServer5M, ADMFLAG_ROOT, "Restart the server in five minutes"); + RegAdminCmd("sm_restart_now", Command_RestartServerSudo, ADMFLAG_ROOT, "Restart the server now [as sudo - unsafe method]"); +} + +public OnMapStart() +{ + CreateTimer(43180.0, PerformTimedRestart); + PrintToServer("*** Auto Restart Module: Created timer with value of 43180.0 ***"); +} + +public Action:Command_RestartServer(client, args) +{ + EmitSoundToAll("ui/system_message_alert.wav"), + ServerCommand("sm_hsay [AutoRestart] Server will restart in 60 seconds!"), + PrintToChatAll("\x0700FF00[\x07AA0000Auto Restart\x0700FF00]\x07AAAAAA The server will restart in 60 seconds."), + CreateTimer(60.0, RestartServer); +} + +public Action:Command_RestartServer1H(client, args) +{ + PrintToChatAll("\x0700FF00[\x07AA0000Auto Restart\x0700FF00]\x07AAAAAA The server will restart in one hour."), + CreateTimer(3580.0, RestartServer1H); +} +public Action:Command_RestartServer30M(client, args) +{ + PrintToChatAll("\x0700FF00[\x07AA0000Auto Restart\x0700FF00]\x07AAAAAA The server will restart in thirty minutes."), + CreateTimer(1780.0, RestartServer30M); +} + +public Action:Command_RestartServer15M(client, args) +{ + PrintToChatAll("\x0700FF00[\x07AA0000Auto Restart\x0700FF00]\x07AAAAAA The server will restart in fifteen minutes."), + CreateTimer(880.0, RestartServer15M); +} + +public Action:Command_RestartServer10M(client, args) +{ + PrintToChatAll("\x0700FF00[\x07AA0000Auto Restart\x0700FF00]\x07AAAAAA The server will restart in ten minutes."), + CreateTimer(580.0, RestartServer10M); +} + +public Action:Command_RestartServer5M(client, args) +{ + PrintToChatAll("\x0700FF00[\x07AA0000Auto Restart\x0700FF00]\x07AAAAAA The server will restart in five minutes."), + CreateTimer(280.0, RestartServer5M); +} + +public Action:Command_RestartServerSudo(client, args) +{ + ServerCommand("exit"); +} + +public Action:PerformTimedRestart(Handle timer) +{ + EmitSoundToAll("ui/system_message_alert.wav"), + ServerCommand("sm_hsay [AutoRestart] Server will restart in 20 seconds!"), + PrintToChatAll("\x0700FF00[\x07AA0000Auto Restart\x0700FF00]\x07AAAAAA Server uptime is: \x07AA000012 hours"), + PrintToChatAll("\x07AAAAAARestarting the server gracefully - Please wait and then reconnect!"), + CreateTimer(20.0, RestartServer); +} + +public Action:RestartServer1H(Handle timer) +{ + EmitSoundToAll("ui/system_message_alert.wav"), + ServerCommand("sm_hsay [AutoRestart] Server will restart in 20 seconds!"), + PrintToChatAll("\x0700FF00[\x07AA0000Auto Restart\x0700FF00]\x07AAAAAA Restarting the server gracefully - Please wait and then reconnect!"), + CreateTimer(20.0, RestartServer); +} + +public Action:RestartServer30M(Handle timer) +{ + EmitSoundToAll("ui/system_message_alert.wav"), + ServerCommand("sm_hsay [AutoRestart] Server will restart in 20 seconds!"), + PrintToChatAll("\x0700FF00[\x07AA0000Auto Restart\x0700FF00]\x07AAAAAA Restarting the server gracefully - Please wait and then reconnect!"), + CreateTimer(20.0, RestartServer); +} + +public Action:RestartServer15M(Handle timer) +{ + EmitSoundToAll("ui/system_message_alert.wav"), + ServerCommand("sm_hsay [AutoRestart] Server will restart in 20 seconds!"), + PrintToChatAll("\x0700FF00[\x07AA0000Auto Restart\x0700FF00]\x07AAAAAA Restarting the server gracefully - Please wait and then reconnect!"), + CreateTimer(20.0, RestartServer); +} + +public Action:RestartServer10M(Handle timer) +{ + EmitSoundToAll("ui/system_message_alert.wav"), + ServerCommand("sm_hsay [AutoRestart] Server will restart in 20 seconds!"), + PrintToChatAll("\x0700FF00[\x07AA0000Auto Restart\x0700FF00]\x07AAAAAA Restarting the server gracefully - Please wait and then reconnect!"), + CreateTimer(20.0, RestartServer); +} + +public Action:RestartServer5M(Handle timer) +{ + EmitSoundToAll("ui/system_message_alert.wav"), + ServerCommand("sm_hsay [AutoRestart] Server will restart in 20 seconds!"), + PrintToChatAll("\x0700FF00[\x07AA0000Auto Restart\x0700FF00]\x07AAAAAA Restarting the server gracefully - Please wait and then reconnect!"), + CreateTimer(20.0, RestartServer); +} + +public Action:RestartServer(Handle timer) +{ + ServerCommand("_restart"); +} \ No newline at end of file diff --git a/scripting/admin-flatfile.sp b/scripting/admin-flatfile.sp new file mode 100644 index 0000000..bab7136 --- /dev/null +++ b/scripting/admin-flatfile.sp @@ -0,0 +1,96 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Admin File Reader Plugin + * Manages the standard flat files for admins. This is the file to compile. + * + * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. + * ============================================================================= + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, version 3.0, as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * + * As a special exception, AlliedModders LLC gives you permission to link the + * code of this program (as well as its derivative works) to "Half-Life 2," the + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software + * by the Valve Corporation. You must obey the GNU General Public License in + * all respects for all other code used. Additionally, AlliedModders LLC grants + * this exception to all derivative works. AlliedModders LLC defines further + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), + * or . + * + * Version: $Id$ + */ + +/* We like semicolons */ +#pragma semicolon 1 + +#include + +public Plugin myinfo = +{ + name = "Admin File Reader", + author = "AlliedModders LLC", + description = "Reads admin files", + version = SOURCEMOD_VERSION, + url = "http://www.sourcemod.net/" +}; + +/** Various parsing globals */ +bool g_LoggedFileName = false; /* Whether or not the file name has been logged */ +int g_ErrorCount = 0; /* Current error count */ +int g_IgnoreLevel = 0; /* Nested ignored section count, so users can screw up files safely */ +int g_CurrentLine = 0; /* Current line we're on */ +char g_Filename[PLATFORM_MAX_PATH]; /* Used for error messages */ + +#include "admin-flatfile/admin-overrides.sp" +#include "admin-flatfile/admin-groups.sp" +#include "admin-flatfile/admin-users.sp" +#include "admin-flatfile/admin-simple.sp" + +public void OnRebuildAdminCache(AdminCachePart part) +{ + if (part == AdminCache_Overrides) + { + ReadOverrides(); + } else if (part == AdminCache_Groups) { + ReadGroups(); + } else if (part == AdminCache_Admins) { + ReadUsers(); + ReadSimpleUsers(); + } +} + +void ParseError(const char[] format, any ...) +{ + char buffer[512]; + + if (!g_LoggedFileName) + { + LogError("Error(s) detected parsing %s", g_Filename); + g_LoggedFileName = true; + } + + VFormat(buffer, sizeof(buffer), format, 2); + + LogError(" (line %d) %s", g_CurrentLine, buffer); + + g_ErrorCount++; +} + +void InitGlobalStates() +{ + g_ErrorCount = 0; + g_IgnoreLevel = 0; + g_CurrentLine = 0; + g_LoggedFileName = false; +} diff --git a/scripting/admin-flatfile/admin-flatfile.sp b/scripting/admin-flatfile/admin-flatfile.sp new file mode 100644 index 0000000..b214734 --- /dev/null +++ b/scripting/admin-flatfile/admin-flatfile.sp @@ -0,0 +1,96 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Admin File Reader Plugin + * Manages the standard flat files for admins. This is the file to compile. + * + * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. + * ============================================================================= + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, version 3.0, as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * + * As a special exception, AlliedModders LLC gives you permission to link the + * code of this program (as well as its derivative works) to "Half-Life 2," the + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software + * by the Valve Corporation. You must obey the GNU General Public License in + * all respects for all other code used. Additionally, AlliedModders LLC grants + * this exception to all derivative works. AlliedModders LLC defines further + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), + * or . + * + * Version: $Id$ + */ + +/* We like semicolons */ +#pragma semicolon 1 + +#include + +public Plugin myinfo = +{ + name = "Admin File Reader", + author = "AlliedModders LLC", + description = "Reads admin files", + version = SOURCEMOD_VERSION, + url = "http://www.sourcemod.net/" +}; + +/** Various parsing globals */ +bool g_LoggedFileName = false; /* Whether or not the file name has been logged */ +int g_ErrorCount = 0; /* Current error count */ +int g_IgnoreLevel = 0; /* Nested ignored section count, so users can screw up files safely */ +int g_CurrentLine = 0; /* Current line we're on */ +char g_Filename[PLATFORM_MAX_PATH]; /* Used for error messages */ + +#include "admin-overrides.sp" +#include "admin-groups.sp" +#include "admin-users.sp" +#include "admin-simple.sp" + +public void OnRebuildAdminCache(AdminCachePart part) +{ + if (part == AdminCache_Overrides) + { + ReadOverrides(); + } else if (part == AdminCache_Groups) { + ReadGroups(); + } else if (part == AdminCache_Admins) { + ReadUsers(); + ReadSimpleUsers(); + } +} + +void ParseError(const char[] format, any ...) +{ + char buffer[512]; + + if (!g_LoggedFileName) + { + LogError("Error(s) detected parsing %s", g_Filename); + g_LoggedFileName = true; + } + + VFormat(buffer, sizeof(buffer), format, 2); + + LogError(" (line %d) %s", g_CurrentLine, buffer); + + g_ErrorCount++; +} + +void InitGlobalStates() +{ + g_ErrorCount = 0; + g_IgnoreLevel = 0; + g_CurrentLine = 0; + g_LoggedFileName = false; +} diff --git a/scripting/admin-flatfile/admin-groups.sp b/scripting/admin-flatfile/admin-groups.sp new file mode 100644 index 0000000..88bcc8c --- /dev/null +++ b/scripting/admin-flatfile/admin-groups.sp @@ -0,0 +1,249 @@ +/** + * vim: set ts=4 sw=4 tw=99 noet : + * ============================================================================= + * SourceMod Admin File Reader Plugin + * Reads the admin_groups.cfg file. Do not compile this directly. + * + * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. + * ============================================================================= + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, version 3.0, as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * + * As a special exception, AlliedModders LLC gives you permission to link the + * code of this program (as well as its derivative works) to "Half-Life 2," the + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software + * by the Valve Corporation. You must obey the GNU General Public License in + * all respects for all other code used. Additionally, AlliedModders LLC grants + * this exception to all derivative works. AlliedModders LLC defines further + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), + * or . + * + * Version: $Id$ + */ + +enum GroupState +{ + GroupState_None, + GroupState_Groups, + GroupState_InGroup, + GroupState_Overrides, +} + +enum GroupPass +{ + GroupPass_Invalid, + GroupPass_First, + GroupPass_Second, +} + +static SMCParser g_hGroupParser; +static GroupId g_CurGrp = INVALID_GROUP_ID; +static GroupState g_GroupState = GroupState_None; +static GroupPass g_GroupPass = GroupPass_Invalid; +static bool g_NeedReparse = false; + +public SMCResult ReadGroups_NewSection(SMCParser smc, const char[] name, bool opt_quotes) +{ + if (g_IgnoreLevel) + { + g_IgnoreLevel++; + return SMCParse_Continue; + } + + if (g_GroupState == GroupState_None) + { + if (StrEqual(name, "Groups")) + { + g_GroupState = GroupState_Groups; + } else { + g_IgnoreLevel++; + } + } else if (g_GroupState == GroupState_Groups) { + if ((g_CurGrp = CreateAdmGroup(name)) == INVALID_GROUP_ID) + { + g_CurGrp = FindAdmGroup(name); + } + g_GroupState = GroupState_InGroup; + } else if (g_GroupState == GroupState_InGroup) { + if (StrEqual(name, "Overrides")) + { + g_GroupState = GroupState_Overrides; + } else { + g_IgnoreLevel++; + } + } else { + g_IgnoreLevel++; + } + + return SMCParse_Continue; +} + +public SMCResult ReadGroups_KeyValue(SMCParser smc, + const char[] key, + const char[] value, + bool key_quotes, + bool value_quotes) +{ + if (g_CurGrp == INVALID_GROUP_ID || g_IgnoreLevel) + { + return SMCParse_Continue; + } + + AdminFlag flag; + + if (g_GroupPass == GroupPass_First) + { + if (g_GroupState == GroupState_InGroup) + { + if (StrEqual(key, "flags")) + { + int len = strlen(value); + for (int i=0; i. + * + * As a special exception, AlliedModders LLC gives you permission to link the + * code of this program (as well as its derivative works) to "Half-Life 2," the + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software + * by the Valve Corporation. You must obey the GNU General Public License in + * all respects for all other code used. Additionally, AlliedModders LLC grants + * this exception to all derivative works. AlliedModders LLC defines further + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), + * or . + * + * Version: $Id$ + */ + +enum OverrideState +{ + OverrideState_None, + OverrideState_Levels, + OverrideState_Overrides, +} + +static SMCParser g_hOldOverrideParser; +static SMCParser g_hNewOverrideParser; +static OverrideState g_OverrideState = OverrideState_None; + +public SMCResult ReadOldOverrides_NewSection(SMCParser smc, const char[] name, bool opt_quotes) +{ + if (g_IgnoreLevel) + { + g_IgnoreLevel++; + return SMCParse_Continue; + } + + if (g_OverrideState == OverrideState_None) + { + if (StrEqual(name, "Levels")) + { + g_OverrideState = OverrideState_Levels; + } else { + g_IgnoreLevel++; + } + } else if (g_OverrideState == OverrideState_Levels) { + if (StrEqual(name, "Overrides")) + { + g_OverrideState = OverrideState_Overrides; + } else { + g_IgnoreLevel++; + } + } else { + g_IgnoreLevel++; + } + + return SMCParse_Continue; +} + +public SMCResult ReadNewOverrides_NewSection(SMCParser smc, const char[] name, bool opt_quotes) +{ + if (g_IgnoreLevel) + { + g_IgnoreLevel++; + return SMCParse_Continue; + } + + if (g_OverrideState == OverrideState_None) + { + if (StrEqual(name, "Overrides")) + { + g_OverrideState = OverrideState_Overrides; + } else { + g_IgnoreLevel++; + } + } else { + g_IgnoreLevel++; + } + + return SMCParse_Continue; +} + +public SMCResult ReadOverrides_KeyValue(SMCParser smc, + const char[] key, + const char[] value, + bool key_quotes, + bool value_quotes) +{ + if (g_OverrideState != OverrideState_Overrides || g_IgnoreLevel) + { + return SMCParse_Continue; + } + + int flags = ReadFlagString(value); + + if (key[0] == '@') + { + AddCommandOverride(key[1], Override_CommandGroup, flags); + } else { + AddCommandOverride(key, Override_Command, flags); + } + + return SMCParse_Continue; +} + +public SMCResult ReadOldOverrides_EndSection(SMCParser smc) +{ + /* If we're ignoring, skip out */ + if (g_IgnoreLevel) + { + g_IgnoreLevel--; + return SMCParse_Continue; + } + + if (g_OverrideState == OverrideState_Levels) + { + g_OverrideState = OverrideState_None; + } else if (g_OverrideState == OverrideState_Overrides) { + /* We're totally done parsing */ + g_OverrideState = OverrideState_Levels; + return SMCParse_Halt; + } + + return SMCParse_Continue; +} + +public SMCResult ReadNewOverrides_EndSection(SMCParser smc) +{ + /* If we're ignoring, skip out */ + if (g_IgnoreLevel) + { + g_IgnoreLevel--; + return SMCParse_Continue; + } + + if (g_OverrideState == OverrideState_Overrides) + { + g_OverrideState = OverrideState_None; + } + + return SMCParse_Continue; +} + +public SMCResult ReadOverrides_CurrentLine(SMCParser smc, const char[] line, int lineno) +{ + g_CurrentLine = lineno; + + return SMCParse_Continue; +} + +static void InitializeOverrideParsers() +{ + if (!g_hOldOverrideParser) + { + g_hOldOverrideParser = new SMCParser(); + g_hOldOverrideParser.OnEnterSection = ReadOldOverrides_NewSection; + g_hOldOverrideParser.OnKeyValue = ReadOverrides_KeyValue; + g_hOldOverrideParser.OnLeaveSection = ReadOldOverrides_EndSection; + g_hOldOverrideParser.OnRawLine = ReadOverrides_CurrentLine; + } + if (!g_hNewOverrideParser) + { + g_hNewOverrideParser = new SMCParser(); + g_hNewOverrideParser.OnEnterSection = ReadNewOverrides_NewSection; + g_hNewOverrideParser.OnKeyValue = ReadOverrides_KeyValue; + g_hNewOverrideParser.OnLeaveSection = ReadNewOverrides_EndSection; + g_hNewOverrideParser.OnRawLine = ReadOverrides_CurrentLine; + } +} + +void InternalReadOverrides(SMCParser parser, const char[] file) +{ + BuildPath(Path_SM, g_Filename, sizeof(g_Filename), file); + + /* Set states */ + InitGlobalStates(); + g_OverrideState = OverrideState_None; + + SMCError err = parser.ParseFile(g_Filename); + if (err != SMCError_Okay) + { + char buffer[64]; + if (parser.GetErrorString(err, buffer, sizeof(buffer))) + { + ParseError("%s", buffer); + } else { + ParseError("Fatal parse error"); + } + } +} + +void ReadOverrides() +{ + InitializeOverrideParsers(); + InternalReadOverrides(g_hOldOverrideParser, "configs/admin_levels.cfg"); + InternalReadOverrides(g_hNewOverrideParser, "configs/admin_overrides.cfg"); +} diff --git a/scripting/admin-flatfile/admin-simple.sp b/scripting/admin-flatfile/admin-simple.sp new file mode 100644 index 0000000..8a3346c --- /dev/null +++ b/scripting/admin-flatfile/admin-simple.sp @@ -0,0 +1,224 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Admin File Reader Plugin + * Reads the admins.cfg file. Do not compile this directly. + * + * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. + * ============================================================================= + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, version 3.0, as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * + * As a special exception, AlliedModders LLC gives you permission to link the + * code of this program (as well as its derivative works) to "Half-Life 2," the + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software + * by the Valve Corporation. You must obey the GNU General Public License in + * all respects for all other code used. Additionally, AlliedModders LLC grants + * this exception to all derivative works. AlliedModders LLC defines further + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), + * or . + * + * Version: $Id$ + */ + +public void ReadSimpleUsers() +{ + BuildPath(Path_SM, g_Filename, sizeof(g_Filename), "configs/admins_simple.ini"); + + File file = OpenFile(g_Filename, "rt"); + if (!file) + { + ParseError("Could not open file!"); + return; + } + + while (!file.EndOfFile()) + { + char line[255]; + if (!file.ReadLine(line, sizeof(line))) + break; + + /* Trim comments */ + int len = strlen(line); + bool ignoring = false; + for (int i=0; i 0) + { + admin.ImmunityLevel = level; + if (flags[flag_idx] == ':') + { + flag_idx++; + } + } + + if (flags[flag_idx] == '@') + { + GroupId gid = FindAdmGroup(flags[flag_idx + 1]); + if (gid == INVALID_GROUP_ID) + { + ParseError("Invalid group detected: %s", flags[flag_idx + 1]); + return; + } + admin.InheritGroup(gid); + } + else + { + int len = strlen(flags[flag_idx]); + bool is_default = false; + for (int i=0; i. + * + * As a special exception, AlliedModders LLC gives you permission to link the + * code of this program (as well as its derivative works) to "Half-Life 2," the + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software + * by the Valve Corporation. You must obey the GNU General Public License in + * all respects for all other code used. Additionally, AlliedModders LLC grants + * this exception to all derivative works. AlliedModders LLC defines further + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), + * or . + * + * Version: $Id$ + */ + +enum UserState +{ + UserState_None, + UserState_Admins, + UserState_InAdmin, +} + +static SMCParser g_hUserParser; +static UserState g_UserState = UserState_None; +static char g_CurAuth[64]; +static char g_CurIdent[64]; +static char g_CurName[64]; +static char g_CurPass[64]; +static ArrayList g_GroupArray; +static int g_CurFlags; +static int g_CurImmunity; + +public SMCResult ReadUsers_NewSection(SMCParser smc, const char[] name, bool opt_quotes) +{ + if (g_IgnoreLevel) + { + g_IgnoreLevel++; + return SMCParse_Continue; + } + + if (g_UserState == UserState_None) + { + if (StrEqual(name, "Admins")) + { + g_UserState = UserState_Admins; + } + else + { + g_IgnoreLevel++; + } + } + else if (g_UserState == UserState_Admins) + { + g_UserState = UserState_InAdmin; + strcopy(g_CurName, sizeof(g_CurName), name); + g_CurAuth[0] = '\0'; + g_CurIdent[0] = '\0'; + g_CurPass[0] = '\0'; + g_GroupArray.Clear(); + g_CurFlags = 0; + g_CurImmunity = 0; + } + else + { + g_IgnoreLevel++; + } + + return SMCParse_Continue; +} + +public SMCResult ReadUsers_KeyValue(SMCParser smc, + const char[] key, + const char[] value, + bool key_quotes, + bool value_quotes) +{ + if (g_UserState != UserState_InAdmin || g_IgnoreLevel) + { + return SMCParse_Continue; + } + + if (StrEqual(key, "auth")) + { + strcopy(g_CurAuth, sizeof(g_CurAuth), value); + } + else if (StrEqual(key, "identity")) + { + strcopy(g_CurIdent, sizeof(g_CurIdent), value); + } + else if (StrEqual(key, "password")) + { + strcopy(g_CurPass, sizeof(g_CurPass), value); + } + else if (StrEqual(key, "group")) + { + GroupId id = FindAdmGroup(value); + if (id == INVALID_GROUP_ID) + { + ParseError("Unknown group \"%s\"", value); + } + + g_GroupArray.Push(id); + } + else if (StrEqual(key, "flags")) + { + int len = strlen(value); + AdminFlag flag; + + for (int i = 0; i < len; i++) + { + if (!FindFlagByChar(value[i], flag)) + { + ParseError("Invalid flag detected: %c", value[i]); + } + else + { + g_CurFlags |= FlagToBit(flag); + } + } + } + else if (StrEqual(key, "immunity")) + { + g_CurImmunity = StringToInt(value); + } + + return SMCParse_Continue; +} + +public SMCResult ReadUsers_EndSection(SMCParser smc) +{ + if (g_IgnoreLevel) + { + g_IgnoreLevel--; + return SMCParse_Continue; + } + + if (g_UserState == UserState_InAdmin) + { + /* Dump this user to memory */ + if (g_CurIdent[0] != '\0' && g_CurAuth[0] != '\0') + { + AdminFlag flags[26]; + AdminId id; + int i, num_groups, num_flags; + + if ((id = FindAdminByIdentity(g_CurAuth, g_CurIdent)) == INVALID_ADMIN_ID) + { + id = CreateAdmin(g_CurName); + if (!id.BindIdentity(g_CurAuth, g_CurIdent)) + { + RemoveAdmin(id); + ParseError("Failed to bind auth \"%s\" to identity \"%s\"", g_CurAuth, g_CurIdent); + return SMCParse_Continue; + } + } + + num_groups = g_GroupArray.Length; + for (i = 0; i < num_groups; i++) + { + id.InheritGroup(g_GroupArray.Get(i)); + } + + id.SetPassword(g_CurPass); + if (id.ImmunityLevel < g_CurImmunity) + { + id.ImmunityLevel = g_CurImmunity; + } + + num_flags = FlagBitsToArray(g_CurFlags, flags, sizeof(flags)); + for (i = 0; i < num_flags; i++) + { + id.SetFlag(flags[i], true); + } + } + else + { + ParseError("Failed to create admin: did you forget either the auth or identity properties?"); + } + + g_UserState = UserState_Admins; + } + else if (g_UserState == UserState_Admins) + { + g_UserState = UserState_None; + } + + return SMCParse_Continue; +} + +public SMCResult ReadUsers_CurrentLine(SMCParser smc, const char[] line, int lineno) +{ + g_CurrentLine = lineno; + + return SMCParse_Continue; +} + +static void InitializeUserParser() +{ + if (!g_hUserParser) + { + g_hUserParser = new SMCParser(); + g_hUserParser.OnEnterSection = ReadUsers_NewSection; + g_hUserParser.OnKeyValue = ReadUsers_KeyValue; + g_hUserParser.OnLeaveSection = ReadUsers_EndSection; + g_hUserParser.OnRawLine = ReadUsers_CurrentLine; + + g_GroupArray = new ArrayList(); + } +} + +void ReadUsers() +{ + InitializeUserParser(); + + BuildPath(Path_SM, g_Filename, sizeof(g_Filename), "configs/admins.cfg"); + + /* Set states */ + InitGlobalStates(); + g_UserState = UserState_None; + + SMCError err = g_hUserParser.ParseFile(g_Filename); + if (err != SMCError_Okay) + { + char buffer[64]; + if (g_hUserParser.GetErrorString(err, buffer, sizeof(buffer))) + { + ParseError("%s", buffer); + } + else + { + ParseError("Fatal parse error"); + } + } +} diff --git a/scripting/admin-sql-prefetch.sp b/scripting/admin-sql-prefetch.sp new file mode 100644 index 0000000..10ddc95 --- /dev/null +++ b/scripting/admin-sql-prefetch.sp @@ -0,0 +1,379 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod SQL Admins Plugin (Prefetch) + * Prefetches admins from an SQL database without threading. + * + * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. + * ============================================================================= + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, version 3.0, as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * + * As a special exception, AlliedModders LLC gives you permission to link the + * code of this program (as well as its derivative works) to "Half-Life 2," the + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software + * by the Valve Corporation. You must obey the GNU General Public License in + * all respects for all other code used. Additionally, AlliedModders LLC grants + * this exception to all derivative works. AlliedModders LLC defines further + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), + * or . + * + * Version: $Id$ + */ + +/* We like semicolons */ +#pragma semicolon 1 + +#include + +#pragma newdecls required + +public Plugin myinfo = +{ + name = "SQL Admins (Prefetch)", + author = "AlliedModders LLC", + description = "Reads all admins from SQL", + version = SOURCEMOD_VERSION, + url = "http://www.sourcemod.net/" +}; + +public void OnRebuildAdminCache(AdminCachePart part) +{ + /* First try to get a database connection */ + char error[255]; + Database db; + + if (SQL_CheckConfig("admins")) + { + db = SQL_Connect("admins", true, error, sizeof(error)); + } else { + db = SQL_Connect("default", true, error, sizeof(error)); + } + + if (db == null) + { + LogError("Could not connect to database \"default\": %s", error); + return; + } + + if (part == AdminCache_Overrides) + { + FetchOverrides(db); + } else if (part == AdminCache_Groups) { + FetchGroups(db); + } else if (part == AdminCache_Admins) { + FetchUsers(db); + } + + delete db; +} + +void FetchUsers(Database db) +{ + char query[255], error[255]; + DBResultSet rs; + + Format(query, sizeof(query), "SELECT id, authtype, identity, password, flags, name, immunity FROM sm_admins"); + if ((rs = SQL_Query(db, query)) == null) + { + SQL_GetError(db, error, sizeof(error)); + LogError("FetchUsers() query failed: %s", query); + LogError("Query error: %s", error); + return; + } + + char authtype[16]; + char identity[80]; + char password[80]; + char flags[32]; + char name[80]; + int immunity; + AdminId adm; + GroupId grp; + int id; + + /* Keep track of a mapping from admin DB IDs to internal AdminIds to + * enable group lookups en masse */ + StringMap htAdmins = new StringMap(); + char key[16]; + + while (rs.FetchRow()) + { + id = rs.FetchInt(0); + IntToString(id, key, sizeof(key)); + rs.FetchString(1, authtype, sizeof(authtype)); + rs.FetchString(2, identity, sizeof(identity)); + rs.FetchString(3, password, sizeof(password)); + rs.FetchString(4, flags, sizeof(flags)); + rs.FetchString(5, name, sizeof(name)); + immunity = rs.FetchInt(6); + + /* Use a pre-existing admin if we can */ + if ((adm = FindAdminByIdentity(authtype, identity)) == INVALID_ADMIN_ID) + { + adm = CreateAdmin(name); + if (!adm.BindIdentity(authtype, identity)) + { + LogError("Could not bind prefetched SQL admin (authtype \"%s\") (identity \"%s\")", authtype, identity); + continue; + } + } + + htAdmins.SetValue(key, adm); + +#if defined _DEBUG + PrintToServer("Found SQL admin (%d,%s,%s,%s,%s,%s,%d):%d", id, authtype, identity, password, flags, name, immunity, adm); +#endif + + /* See if this admin wants a password */ + if (password[0] != '\0') + { + adm.SetPassword(password); + } + + /* Apply each flag */ + int len = strlen(flags); + AdminFlag flag; + for (int i=0; i. + * + * As a special exception, AlliedModders LLC gives you permission to link the + * code of this program (as well as its derivative works) to "Half-Life 2," the + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software + * by the Valve Corporation. You must obey the GNU General Public License in + * all respects for all other code used. Additionally, AlliedModders LLC grants + * this exception to all derivative works. AlliedModders LLC defines further + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), + * or . + * + * Version: $Id$ + */ + +/* We like semicolons */ +#pragma semicolon 1 + +#include + +#pragma newdecls required + +public Plugin myinfo = +{ + name = "SQL Admins (Threaded)", + author = "AlliedModders LLC", + description = "Reads admins from SQL dynamically", + version = SOURCEMOD_VERSION, + url = "http://www.sourcemod.net/" +}; + +/** + * Notes: + * + * 1) All queries in here are high priority. This is because the admin stuff + * is very important. Do not take this to mean that in your script, + * everything should be high priority. + * + * 2) All callbacks are locked with "sequence numbers." This is to make sure + * that multiple calls to sm_reloadadmins and the like do not make us + * store the results from two or more callbacks accidentally. Instead, we + * check the sequence number in each callback with the current "allowed" + * sequence number, and if it doesn't match, the callback is cancelled. + * + * 3) Sequence numbers for groups and overrides are not cleared unless there + * was a 100% success in the fetch. This is so we can potentially implement + * connection retries in the future. + * + * 4) Sequence numbers for the user cache are ignored except for being + * non-zero, which means players in-game should be re-checked for admin + * powers. + */ + +Database hDatabase = null; /** Database connection */ +int g_sequence = 0; /** Global unique sequence number */ +int ConnectLock = 0; /** Connect sequence number */ +int RebuildCachePart[3] = {0}; /** Cache part sequence numbers */ + +enum struct PlayerInfo { + int sequencenum; /** Player-specific sequence numbers */ + bool authed; /** Whether a player has been "pre-authed" */ +} + +PlayerInfo playerinfo[MAXPLAYERS+1]; + +//#define _DEBUG + +public void OnMapEnd() +{ + /** + * Clean up on map end just so we can start a fresh connection when we need it later. + */ + delete hDatabase; +} + +public bool OnClientConnect(int client, char[] rejectmsg, int maxlen) +{ + playerinfo[client].sequencenum = 0; + playerinfo[client].authed = false; + return true; +} + +public void OnClientDisconnect(int client) +{ + playerinfo[client].sequencenum = 0; + playerinfo[client].authed = false; +} + +public void OnDatabaseConnect(Database db, const char[] error, any data) +{ +#if defined _DEBUG + PrintToServer("OnDatabaseConnect(%x, %d) ConnectLock=%d", db, data, ConnectLock); +#endif + + /** + * If this happens to be an old connection request, ignore it. + */ + if (data != ConnectLock || hDatabase != null) + { + delete db; + return; + } + + ConnectLock = 0; + hDatabase = db; + + /** + * See if the connection is valid. If not, don't un-mark the caches + * as needing rebuilding, in case the next connection request works. + */ + if (hDatabase == null) + { + LogError("Failed to connect to database: %s", error); + return; + } + + /** + * See if we need to get any of the cache stuff now. + */ + int sequence; + if ((sequence = RebuildCachePart[AdminCache_Overrides]) != 0) + { + FetchOverrides(hDatabase, sequence); + } + if ((sequence = RebuildCachePart[AdminCache_Groups]) != 0) + { + FetchGroups(hDatabase, sequence); + } + if ((sequence = RebuildCachePart[AdminCache_Admins]) != 0) + { + FetchUsersWeCan(hDatabase); + } +} + +void RequestDatabaseConnection() +{ + ConnectLock = ++g_sequence; + if (SQL_CheckConfig("admins")) + { + Database.Connect(OnDatabaseConnect, "admins", ConnectLock); + } else { + Database.Connect(OnDatabaseConnect, "default", ConnectLock); + } +} + +public void OnRebuildAdminCache(AdminCachePart part) +{ + /** + * Mark this part of the cache as being rebuilt. This is used by the + * callback system to determine whether the results should still be + * used. + */ + int sequence = ++g_sequence; + RebuildCachePart[part] = sequence; + + /** + * If we don't have a database connection, we can't do any lookups just yet. + */ + if (!hDatabase) + { + /** + * Ask for a new connection if we need it. + */ + if (!ConnectLock) + { + RequestDatabaseConnection(); + } + return; + } + + if (part == AdminCache_Overrides) + { + FetchOverrides(hDatabase, sequence); + } else if (part == AdminCache_Groups) { + FetchGroups(hDatabase, sequence); + } else if (part == AdminCache_Admins) { + FetchUsersWeCan(hDatabase); + } +} + +public Action OnClientPreAdminCheck(int client) +{ + playerinfo[client].authed = true; + + /** + * Play nice with other plugins. If there's no database, don't delay the + * connection process. Unfortunately, we can't attempt anything else and + * we just have to hope either the database is waiting or someone will type + * sm_reloadadmins. + */ + if (hDatabase == null) + { + return Plugin_Continue; + } + + /** + * Similarly, if the cache is in the process of being rebuilt, don't delay + * the user's normal connection flow. The database will soon auth the user + * normally. + */ + if (RebuildCachePart[AdminCache_Admins] != 0) + { + return Plugin_Continue; + } + + /** + * If someone has already assigned an admin ID (bad bad bad), don't + * bother waiting. + */ + if (GetUserAdmin(client) != INVALID_ADMIN_ID) + { + return Plugin_Continue; + } + + FetchUser(hDatabase, client); + + return Plugin_Handled; +} + +public void OnReceiveUserGroups(Database db, DBResultSet rs, const char[] error, any data) +{ + DataPack pk = view_as(data); + pk.Reset(); + + int client = pk.ReadCell(); + int sequence = pk.ReadCell(); + + /** + * Make sure it's the same client. + */ + if (playerinfo[client].sequencenum != sequence) + { + delete pk; + return; + } + + AdminId adm = view_as(pk.ReadCell()); + + /** + * Someone could have sneakily changed the admin id while we waited. + */ + if (GetUserAdmin(client) != adm) + { + NotifyPostAdminCheck(client); + delete pk; + return; + } + + /** + * See if we got results. + */ + if (rs == null) + { + char query[255]; + pk.ReadString(query, sizeof(query)); + LogError("SQL error receiving user: %s", error); + LogError("Query dump: %s", query); + NotifyPostAdminCheck(client); + delete pk; + return; + } + + char name[80]; + GroupId grp; + + while (rs.FetchRow()) + { + rs.FetchString(0, name, sizeof(name)); + + if ((grp = FindAdmGroup(name)) == INVALID_GROUP_ID) + { + continue; + } + +#if defined _DEBUG + PrintToServer("Binding user group (%d, %d, %d, %s, %d)", client, sequence, adm, name, grp); +#endif + + adm.InheritGroup(grp); + } + + /** + * We're DONE! Omg. + */ + NotifyPostAdminCheck(client); + delete pk; +} + +public void OnReceiveUser(Database db, DBResultSet rs, const char[] error, any data) +{ + DataPack pk = view_as(data); + pk.Reset(); + + int client = pk.ReadCell(); + + /** + * Check if this is the latest result request. + */ + int sequence = pk.ReadCell(); + if (playerinfo[client].sequencenum != sequence) + { + /* Discard everything, since we're out of sequence. */ + delete pk; + return; + } + + /** + * If we need to use the results, make sure they succeeded. + */ + if (rs == null) + { + char query[255]; + pk.ReadString(query, sizeof(query)); + LogError("SQL error receiving user: %s", error); + LogError("Query dump: %s", query); + RunAdminCacheChecks(client); + NotifyPostAdminCheck(client); + delete pk; + return; + } + + int num_accounts = rs.RowCount; + if (num_accounts == 0) + { + RunAdminCacheChecks(client); + NotifyPostAdminCheck(client); + delete pk; + return; + } + + char authtype[16]; + char identity[80]; + char password[80]; + char flags[32]; + char name[80]; + int immunity, id; + AdminId adm; + + /** + * Cache user info -- [0] = db id, [1] = cache id, [2] = groups + */ + int[][] user_lookup = new int[num_accounts][3]; + int total_users = 0; + + while (rs.FetchRow()) + { + id = rs.FetchInt(0); + rs.FetchString(1, authtype, sizeof(authtype)); + rs.FetchString(2, identity, sizeof(identity)); + rs.FetchString(3, password, sizeof(password)); + rs.FetchString(4, flags, sizeof(flags)); + rs.FetchString(5, name, sizeof(name)); + immunity = rs.FetchInt(7); + + /* For dynamic admins we clear anything already in the cache. */ + if ((adm = FindAdminByIdentity(authtype, identity)) != INVALID_ADMIN_ID) + { + RemoveAdmin(adm); + } + + adm = CreateAdmin(name); + if (!adm.BindIdentity(authtype, identity)) + { + LogError("Could not bind prefetched SQL admin (authtype \"%s\") (identity \"%s\")", authtype, identity); + continue; + } + + user_lookup[total_users][0] = id; + user_lookup[total_users][1] = view_as(adm); + user_lookup[total_users][2] = rs.FetchInt(6); + total_users++; + +#if defined _DEBUG + PrintToServer("Found SQL admin (%d,%s,%s,%s,%s,%s,%d):%d:%d", id, authtype, identity, password, flags, name, immunity, adm, user_lookup[total_users-1][2]); +#endif + + /* See if this admin wants a password */ + if (password[0] != '\0') + { + adm.SetPassword(password); + } + + adm.ImmunityLevel = immunity; + + /* Apply each flag */ + int len = strlen(flags); + AdminFlag flag; + for (int i=0; i(adm)) + { + id = user_lookup[i][0]; + group_count = user_lookup[i][2]; + break; + } + } + +#if defined _DEBUG + PrintToServer("Binding client (%d, %d) resulted in: (%d, %d, %d)", client, sequence, id, adm, group_count); +#endif + + /** + * If we can't verify that we assigned a database admin, or the user has no + * groups, don't bother doing anything. + */ + if (!id || !group_count) + { + NotifyPostAdminCheck(client); + delete pk; + return; + } + + /** + * The user has groups -- we need to fetch them! + */ + char query[255]; + Format(query, sizeof(query), "SELECT g.name FROM sm_admins_groups ag JOIN sm_groups g ON ag.group_id = g.id WHERE ag.admin_id = %d", id); + + pk.Reset(); + pk.WriteCell(client); + pk.WriteCell(sequence); + pk.WriteCell(adm); + pk.WriteString(query); + + db.Query(OnReceiveUserGroups, query, pk, DBPrio_High); +} + +void FetchUser(Database db, int client) +{ + char name[MAX_NAME_LENGTH]; + char safe_name[(MAX_NAME_LENGTH * 2) - 1]; + char steamid2[32]; + char steamid2alt[32]; + char steamid3[32]; + char steamid64[32]; + char ipaddr[24]; + + /** + * Get authentication information from the client. + */ + GetClientName(client, name, sizeof(name)); + GetClientIP(client, ipaddr, sizeof(ipaddr)); + + steamid2[0] = '\0'; + if (GetClientAuthId(client, AuthId_Steam2, steamid2, sizeof(steamid2))) + { + if (StrEqual(steamid2, "STEAM_ID_LAN")) + { + steamid2[0] = '\0'; + } + } + + steamid3[0] = '\0'; + if (GetClientAuthId(client, AuthId_Steam3, steamid3, sizeof(steamid3))) + { + if (StrEqual(steamid3, "STEAM_ID_LAN")) + { + steamid3[0] = '\0'; + } + } + + steamid64[0] = '\0'; + if (GetClientAuthId(client, AuthId_SteamID64, steamid64, sizeof(steamid64))) + { + if (StrEqual(steamid64, "0")) + { + steamid64[0] = '\0'; + } + } + + db.Escape(name, safe_name, sizeof(safe_name)); + + /** + * Construct the query using the information the user gave us. + */ + char query[512]; + int len = 0; + + len += Format(query[len], sizeof(query)-len, "SELECT a.id, a.authtype, a.identity, a.password, a.flags, a.name, COUNT(ag.group_id), immunity"); + len += Format(query[len], sizeof(query)-len, " FROM sm_admins a LEFT JOIN sm_admins_groups ag ON a.id = ag.admin_id WHERE "); + len += Format(query[len], sizeof(query)-len, " (a.authtype = 'ip' AND a.identity = '%s')", ipaddr); + len += Format(query[len], sizeof(query)-len, " OR (a.authtype = 'name' AND a.identity = '%s')", safe_name); + if (steamid2[0] != '\0' && steamid3[0] != '\0' && steamid64[0] != '\0') + { + strcopy(steamid2alt, sizeof(steamid2alt), steamid2); + steamid2alt[6] = (steamid2[6] == '0') ? '1' : '0'; + + len += Format(query[len], sizeof(query)-len, + " OR (a.authtype = 'steam' AND (a.identity = '%s' OR a.identity = '%s' OR a.identity = '%s' OR a.identity = '%s'))", + steamid2, steamid2alt, steamid3, steamid64); + } + len += Format(query[len], sizeof(query)-len, " GROUP BY a.id"); + + /** + * Send the actual query. + */ + playerinfo[client].sequencenum = ++g_sequence; + + DataPack pk = new DataPack(); + pk.WriteCell(client); + pk.WriteCell(playerinfo[client].sequencenum); + pk.WriteString(query); + +#if defined _DEBUG + PrintToServer("Sending user query: %s", query); +#endif + + db.Query(OnReceiveUser, query, pk, DBPrio_High); +} + +void FetchUsersWeCan(Database db) +{ + for (int i=1; i<=MaxClients; i++) + { + if (playerinfo[i].authed && GetUserAdmin(i) == INVALID_ADMIN_ID) + { + FetchUser(db, i); + } + } + + /** + * This round of updates is done. Go in peace. + */ + RebuildCachePart[AdminCache_Admins] = 0; +} + +public void OnReceiveGroupImmunity(Database db, DBResultSet rs, const char[] error, any data) +{ + DataPack pk = view_as(data); + pk.Reset(); + + /** + * Check if this is the latest result request. + */ + int sequence = pk.ReadCell(); + if (RebuildCachePart[AdminCache_Groups] != sequence) + { + /* Discard everything, since we're out of sequence. */ + delete pk; + return; + } + + /** + * If we need to use the results, make sure they succeeded. + */ + if (rs == null) + { + char query[255]; + pk.ReadString(query, sizeof(query)); + LogError("SQL error receiving group immunity: %s", error); + LogError("Query dump: %s", query); + delete pk; + return; + } + + /* We're done with the pack forever. */ + delete pk; + + while (rs.FetchRow()) + { + char group1[80]; + char group2[80]; + GroupId grp, other; + + rs.FetchString(0, group1, sizeof(group1)); + rs.FetchString(1, group2, sizeof(group2)); + + if (((grp = FindAdmGroup(group1)) == INVALID_GROUP_ID) + || (other = FindAdmGroup(group2)) == INVALID_GROUP_ID) + { + continue; + } + + grp.AddGroupImmunity(other); +#if defined _DEBUG + PrintToServer("SetAdmGroupImmuneFrom(%d, %d)", grp, other); +#endif + } + + /* Clear the sequence so another connect doesn't refetch */ + RebuildCachePart[AdminCache_Groups] = 0; +} + +public void OnReceiveGroupOverrides(Database db, DBResultSet rs, const char[] error, any data) +{ + DataPack pk = view_as(data); + pk.Reset(); + + /** + * Check if this is the latest result request. + */ + int sequence = pk.ReadCell(); + if (RebuildCachePart[AdminCache_Groups] != sequence) + { + /* Discard everything, since we're out of sequence. */ + delete pk; + return; + } + + /** + * If we need to use the results, make sure they succeeded. + */ + if (rs == null) + { + char query[255]; + pk.ReadString(query, sizeof(query)); + LogError("SQL error receiving group overrides: %s", error); + LogError("Query dump: %s", query); + delete pk; + return; + } + + /** + * Fetch the overrides. + */ + char name[80]; + char type[16]; + char command[64]; + char access[16]; + GroupId grp; + while (rs.FetchRow()) + { + rs.FetchString(0, name, sizeof(name)); + rs.FetchString(1, type, sizeof(type)); + rs.FetchString(2, command, sizeof(command)); + rs.FetchString(3, access, sizeof(access)); + + /* Find the group. This is actually faster than doing the ID lookup. */ + if ((grp = FindAdmGroup(name)) == INVALID_GROUP_ID) + { + /* Oh well, just ignore it. */ + continue; + } + + OverrideType o_type = Override_Command; + if (StrEqual(type, "group")) + { + o_type = Override_CommandGroup; + } + + OverrideRule o_rule = Command_Deny; + if (StrEqual(access, "allow")) + { + o_rule = Command_Allow; + } + +#if defined _DEBUG + PrintToServer("AddAdmGroupCmdOverride(%d, %s, %d, %d)", grp, command, o_type, o_rule); +#endif + + grp.AddCommandOverride(command, o_type, o_rule); + } + + /** + * It's time to get the group immunity list. + */ + int len = 0; + char query[256]; + len += Format(query[len], sizeof(query)-len, "SELECT g1.name, g2.name FROM sm_group_immunity gi"); + len += Format(query[len], sizeof(query)-len, " LEFT JOIN sm_groups g1 ON g1.id = gi.group_id "); + len += Format(query[len], sizeof(query)-len, " LEFT JOIN sm_groups g2 ON g2.id = gi.other_id"); + + pk.Reset(); + pk.WriteCell(sequence); + pk.WriteString(query); + + db.Query(OnReceiveGroupImmunity, query, pk, DBPrio_High); +} + +public void OnReceiveGroups(Database db, DBResultSet rs, const char[] error, any data) +{ + DataPack pk = view_as(data); + pk.Reset(); + + /** + * Check if this is the latest result request. + */ + int sequence = pk.ReadCell(); + if (RebuildCachePart[AdminCache_Groups] != sequence) + { + /* Discard everything, since we're out of sequence. */ + delete pk; + return; + } + + /** + * If we need to use the results, make sure they succeeded. + */ + if (rs == null) + { + char query[255]; + pk.ReadString(query, sizeof(query)); + LogError("SQL error receiving groups: %s", error); + LogError("Query dump: %s", query); + delete pk; + return; + } + + /** + * Now start fetching groups. + */ + char flags[32]; + char name[128]; + int immunity; + while (rs.FetchRow()) + { + rs.FetchString(0, flags, sizeof(flags)); + rs.FetchString(1, name, sizeof(name)); + immunity = rs.FetchInt(2); + +#if defined _DEBUG + PrintToServer("Adding group (%d, %s, %s)", immunity, flags, name); +#endif + + /* Find or create the group */ + GroupId grp; + if ((grp = FindAdmGroup(name)) == INVALID_GROUP_ID) + { + grp = CreateAdmGroup(name); + } + + /* Add flags from the database to the group */ + int num_flag_chars = strlen(flags); + for (int i=0; i(data); + pk.Reset(); + + /** + * Check if this is the latest result request. + */ + int sequence = pk.ReadCell(); + if (RebuildCachePart[AdminCache_Overrides] != sequence) + { + /* Discard everything, since we're out of sequence. */ + delete pk; + return; + } + + /** + * If we need to use the results, make sure they succeeded. + */ + if (rs == null) + { + char query[255]; + pk.ReadString(query, sizeof(query)); + LogError("SQL error receiving overrides: %s", error); + LogError("Query dump: %s", query); + delete pk; + return; + } + + /** + * We're done with you, now. + */ + delete pk; + + char type[64]; + char name[64]; + char flags[32]; + int flag_bits; + while (rs.FetchRow()) + { + rs.FetchString(0, type, sizeof(type)); + rs.FetchString(1, name, sizeof(name)); + rs.FetchString(2, flags, sizeof(flags)); + +#if defined _DEBUG + PrintToServer("Adding override (%s, %s, %s)", type, name, flags); +#endif + + flag_bits = ReadFlagString(flags); + if (StrEqual(type, "command")) + { + AddCommandOverride(name, Override_Command, flag_bits); + } else if (StrEqual(type, "group")) { + AddCommandOverride(name, Override_CommandGroup, flag_bits); + } + } + + /* Clear the sequence so another connect doesn't refetch */ + RebuildCachePart[AdminCache_Overrides] = 0; +} + +void FetchOverrides(Database db, int sequence) +{ + char query[255]; + + Format(query, sizeof(query), "SELECT type, name, flags FROM sm_overrides"); + + DataPack pk = new DataPack(); + pk.WriteCell(sequence); + pk.WriteString(query); + + db.Query(OnReceiveOverrides, query, pk, DBPrio_High); +} diff --git a/scripting/adminhelp.sp b/scripting/adminhelp.sp new file mode 100644 index 0000000..dacee6a --- /dev/null +++ b/scripting/adminhelp.sp @@ -0,0 +1,169 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Admin Help Plugin + * Displays and searches SourceMod commands and descriptions. + * + * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. + * ============================================================================= + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, version 3.0, as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * + * As a special exception, AlliedModders LLC gives you permission to link the + * code of this program (as well as its derivative works) to "Half-Life 2," the + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software + * by the Valve Corporation. You must obey the GNU General Public License in + * all respects for all other code used. Additionally, AlliedModders LLC grants + * this exception to all derivative works. AlliedModders LLC defines further + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), + * or . + * + * Version: $Id$ + */ + +#pragma semicolon 1 + +#include + +#pragma newdecls required + +#define COMMANDS_PER_PAGE 10 + +public Plugin myinfo = +{ + name = "Admin Help", + author = "AlliedModders LLC", + description = "Display command information", + version = SOURCEMOD_VERSION, + url = "http://www.sourcemod.net/" +}; + +public void OnPluginStart() +{ + LoadTranslations("common.phrases"); + LoadTranslations("adminhelp.phrases"); + RegConsoleCmd("sm_help", HelpCmd, "Displays SourceMod commands and descriptions"); + RegConsoleCmd("sm_searchcmd", HelpCmd, "Searches SourceMod commands"); +} + +public Action HelpCmd(int client, int args) +{ + if (client && !IsClientInGame(client)) + { + return Plugin_Handled; + } + + char arg[64], cmdName[20]; + int pageNum = 1; + bool doSearch; + + GetCmdArg(0, cmdName, sizeof(cmdName)); + + if (args >= 1) + { + GetCmdArg(1, arg, sizeof(arg)); + StringToIntEx(arg, pageNum); + pageNum = (pageNum <= 0) ? 1 : pageNum; + } + + doSearch = (strcmp("sm_help", cmdName) == 0) ? false : true; + + if (GetCmdReplySource() == SM_REPLY_TO_CHAT) + { + ReplyToCommand(client, "[SM] %t", "See console for output"); + } + + char name[64]; + char desc[255]; + char noDesc[128]; + CommandIterator cmdIter = new CommandIterator(); + + FormatEx(noDesc, sizeof(noDesc), "%T", "No description available", client); + + if (doSearch) + { + int i = 1; + while (cmdIter.Next()) + { + cmdIter.GetName(name, sizeof(name)); + cmdIter.GetDescription(desc, sizeof(desc)); + + if ((StrContains(name, arg, false) != -1) && ((cmdIter.ConVarFlags & FCVAR_HIDDEN) == 0) && CheckCommandAccess(client, name, cmdIter.Flags)) + { + PrintToConsole(client, "[%03d] %s - %s", i++, name, (desc[0] == '\0') ? noDesc : desc); + } + } + + if (i == 1) + { + PrintToConsole(client, "%t", "No matching results found"); + } + } else { + PrintToConsole(client, "%t", "SM help commands"); + + /* Skip the first N commands if we need to */ + if (pageNum > 1) + { + int i; + int endCmd = (pageNum-1) * COMMANDS_PER_PAGE - 1; + for (i=0; cmdIter.Next() && i. + * + * As a special exception, AlliedModders LLC gives you permission to link the + * code of this program (as well as its derivative works) to "Half-Life 2," the + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software + * by the Valve Corporation. You must obey the GNU General Public License in + * all respects for all other code used. Additionally, AlliedModders LLC grants + * this exception to all derivative works. AlliedModders LLC defines further + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), + * or . + * + * Version: $Id$ + */ + +#pragma semicolon 1 + +#include +#include + +#pragma newdecls required + +public Plugin myinfo = +{ + name = "Admin Menu", + author = "AlliedModders LLC", + description = "Administration Menu", + version = SOURCEMOD_VERSION, + url = "http://www.sourcemod.net/" +}; + +/* Forwards */ +GlobalForward hOnAdminMenuReady; +GlobalForward hOnAdminMenuCreated; + +/* Menus */ +TopMenu hAdminMenu; + +/* Top menu objects */ +TopMenuObject obj_playercmds = INVALID_TOPMENUOBJECT; +TopMenuObject obj_servercmds = INVALID_TOPMENUOBJECT; +TopMenuObject obj_votingcmds = INVALID_TOPMENUOBJECT; + +#include "adminmenu/dynamicmenu.sp" + +public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) +{ + CreateNative("GetAdminTopMenu", __GetAdminTopMenu); + CreateNative("AddTargetsToMenu", __AddTargetsToMenu); + CreateNative("AddTargetsToMenu2", __AddTargetsToMenu2); + RegPluginLibrary("adminmenu"); + return APLRes_Success; +} + +public void OnPluginStart() +{ + LoadTranslations("common.phrases"); + LoadTranslations("adminmenu.phrases"); + + hOnAdminMenuCreated = new GlobalForward("OnAdminMenuCreated", ET_Ignore, Param_Cell); + hOnAdminMenuReady = new GlobalForward("OnAdminMenuReady", ET_Ignore, Param_Cell); + + RegAdminCmd("sm_admin", Command_DisplayMenu, ADMFLAG_GENERIC, "Displays the admin menu"); +} + +public void OnConfigsExecuted() +{ + char path[PLATFORM_MAX_PATH]; + char error[256]; + + BuildPath(Path_SM, path, sizeof(path), "configs/adminmenu_sorting.txt"); + + if (!hAdminMenu.LoadConfig(path, error, sizeof(error))) + { + LogError("Could not load admin menu config (file \"%s\": %s)", path, error); + return; + } +} + +public void OnMapStart() +{ + ParseConfigs(); +} + +public void OnAllPluginsLoaded() +{ + hAdminMenu = new TopMenu(DefaultCategoryHandler); + + obj_playercmds = hAdminMenu.AddCategory("PlayerCommands", DefaultCategoryHandler); + obj_servercmds = hAdminMenu.AddCategory("ServerCommands", DefaultCategoryHandler); + obj_votingcmds = hAdminMenu.AddCategory("VotingCommands", DefaultCategoryHandler); + + BuildDynamicMenu(); + + Call_StartForward(hOnAdminMenuCreated); + Call_PushCell(hAdminMenu); + Call_Finish(); + + Call_StartForward(hOnAdminMenuReady); + Call_PushCell(hAdminMenu); + Call_Finish(); +} + +public void DefaultCategoryHandler(TopMenu topmenu, + TopMenuAction action, + TopMenuObject object_id, + int param, + char[] buffer, + int maxlength) +{ + if (action == TopMenuAction_DisplayTitle) + { + if (object_id == INVALID_TOPMENUOBJECT) + { + Format(buffer, maxlength, "%T:", "Admin Menu", param); + } + else if (object_id == obj_playercmds) + { + Format(buffer, maxlength, "%T:", "Player Commands", param); + } + else if (object_id == obj_servercmds) + { + Format(buffer, maxlength, "%T:", "Server Commands", param); + } + else if (object_id == obj_votingcmds) + { + Format(buffer, maxlength, "%T:", "Voting Commands", param); + } + } + else if (action == TopMenuAction_DisplayOption) + { + if (object_id == obj_playercmds) + { + Format(buffer, maxlength, "%T", "Player Commands", param); + } + else if (object_id == obj_servercmds) + { + Format(buffer, maxlength, "%T", "Server Commands", param); + } + else if (object_id == obj_votingcmds) + { + Format(buffer, maxlength, "%T", "Voting Commands", param); + } + } +} + +public any __GetAdminTopMenu(Handle plugin, int numParams) +{ + return hAdminMenu; +} + +public int __AddTargetsToMenu(Handle plugin, int numParams) +{ + bool alive_only = false; + + if (numParams >= 4) + { + alive_only = GetNativeCell(4); + } + + return UTIL_AddTargetsToMenu(GetNativeCell(1), GetNativeCell(2), GetNativeCell(3), alive_only); +} + +public int __AddTargetsToMenu2(Handle plugin, int numParams) +{ + return UTIL_AddTargetsToMenu2(GetNativeCell(1), GetNativeCell(2), GetNativeCell(3)); +} + +public Action Command_DisplayMenu(int client, int args) +{ + if (client == 0) + { + ReplyToCommand(client, "[SM] %t", "Command is in-game only"); + return Plugin_Handled; + } + + hAdminMenu.Display(client, TopMenuPosition_Start); + return Plugin_Handled; +} + +stock int UTIL_AddTargetsToMenu2(Menu menu, int source_client, int flags) +{ + char user_id[12]; + char name[MAX_NAME_LENGTH]; + char display[MAX_NAME_LENGTH+12]; + + int num_clients; + + for (int i = 1; i <= MaxClients; i++) + { + if (!IsClientConnected(i) || IsClientInKickQueue(i)) + { + continue; + } + + if (((flags & COMMAND_FILTER_NO_BOTS) == COMMAND_FILTER_NO_BOTS) + && IsFakeClient(i)) + { + continue; + } + + if (((flags & COMMAND_FILTER_CONNECTED) != COMMAND_FILTER_CONNECTED) + && !IsClientInGame(i)) + { + continue; + } + + if (((flags & COMMAND_FILTER_ALIVE) == COMMAND_FILTER_ALIVE) + && !IsPlayerAlive(i)) + { + continue; + } + + if (((flags & COMMAND_FILTER_DEAD) == COMMAND_FILTER_DEAD) + && IsPlayerAlive(i)) + { + continue; + } + + if ((source_client && ((flags & COMMAND_FILTER_NO_IMMUNITY) != COMMAND_FILTER_NO_IMMUNITY)) + && !CanUserTarget(source_client, i)) + { + continue; + } + + IntToString(GetClientUserId(i), user_id, sizeof(user_id)); + GetClientName(i, name, sizeof(name)); + Format(display, sizeof(display), "%s (%s)", name, user_id); + menu.AddItem(user_id, display); + num_clients++; + } + + return num_clients; +} + +stock int UTIL_AddTargetsToMenu(Menu menu, int source_client, bool in_game_only, bool alive_only) +{ + int flags = 0; + + if (!in_game_only) + { + flags |= COMMAND_FILTER_CONNECTED; + } + + if (alive_only) + { + flags |= COMMAND_FILTER_ALIVE; + } + + return UTIL_AddTargetsToMenu2(menu, source_client, flags); +} diff --git a/scripting/adminmenu/dynamicmenu.sp b/scripting/adminmenu/dynamicmenu.sp new file mode 100644 index 0000000..a534ef7 --- /dev/null +++ b/scripting/adminmenu/dynamicmenu.sp @@ -0,0 +1,718 @@ +// vim: set noet: +#define NAME_LENGTH 64 +#define CMD_LENGTH 255 + +#define ARRAY_STRING_LENGTH 32 + +enum struct GroupCommands +{ + ArrayList groupListName; + ArrayList groupListCommand; +} + +GroupCommands g_groupList; +int g_groupCount; + +SMCParser g_configParser; + +enum struct Places +{ + int category; + int item; + int replaceNum; +} + +char g_command[MAXPLAYERS+1][CMD_LENGTH]; +Places g_currentPlace[MAXPLAYERS+1]; + +/** + * What to put in the 'info' menu field (for PlayerList and Player_Team menus only) + */ +enum PlayerMethod +{ + ClientId, /** Client id number ( 1 - Maxplayers) */ + UserId, /** Client userid */ + Name, /** Client Name */ + SteamId, /** Client Steamid */ + IpAddress, /** Client's Ip Address */ + UserId2 /** Userid (not prefixed with #) */ +}; + +enum ExecuteType +{ + Execute_Player, + Execute_Server +} + +enum SubMenu_Type +{ + SubMenu_Group, + SubMenu_GroupPlayer, + SubMenu_Player, + SubMenu_MapCycle, + SubMenu_List, + SubMenu_OnOff +} + +enum struct Item +{ + char cmd[256]; + ExecuteType execute; + ArrayList submenus; +} + +enum struct Submenu +{ + SubMenu_Type type; + char title[32]; + PlayerMethod method; + int listcount; + DataPack listdata; +} + +ArrayList g_DataArray; + +void BuildDynamicMenu() +{ + Item itemInput; + g_DataArray = new ArrayList(sizeof(itemInput)); + + char executeBuffer[32]; + + KeyValues kvMenu = new KeyValues("Commands"); + kvMenu.SetEscapeSequences(true); + + char file[256]; + + /* As a compatibility shim, we use the old file if it exists. */ + BuildPath(Path_SM, file, 255, "configs/dynamicmenu/menu.ini"); + if (FileExists(file)) + { + LogError("Warning! configs/dynamicmenu/menu.ini is now configs/adminmenu_custom.txt."); + LogError("Read the 1.0.2 release notes, as the dynamicmenu folder has been removed."); + } + else + { + BuildPath(Path_SM, file, 255, "configs/adminmenu_custom.txt"); + } + + FileToKeyValues(kvMenu, file); + + char name[NAME_LENGTH]; + char buffer[NAME_LENGTH]; + + if (!kvMenu.GotoFirstSubKey()) + return; + + char admin[30]; + + TopMenuObject categoryId; + + do + { + kvMenu.GetSectionName(buffer, sizeof(buffer)); + + kvMenu.GetString("admin", admin, sizeof(admin),"sm_admin"); + + if ((categoryId = hAdminMenu.FindCategory(buffer)) == INVALID_TOPMENUOBJECT) + { + categoryId = hAdminMenu.AddCategory(buffer, + DynamicMenuCategoryHandler, + admin, + ADMFLAG_GENERIC, + name); + + } + + char category_name[NAME_LENGTH]; + strcopy(category_name, sizeof(category_name), buffer); + + if (!kvMenu.GotoFirstSubKey()) + { + return; + } + + do + { + kvMenu.GetSectionName(buffer, sizeof(buffer)); + + kvMenu.GetString("admin", admin, sizeof(admin),""); + + if (admin[0] == '\0') + { + //No 'admin' keyvalue was found + //Use the first argument of the 'cmd' string instead + + char temp[64]; + kvMenu.GetString("cmd", temp, sizeof(temp),""); + + BreakString(temp, admin, sizeof(admin)); + } + + + kvMenu.GetString("cmd", itemInput.cmd, sizeof(itemInput.cmd)); + kvMenu.GetString("execute", executeBuffer, sizeof(executeBuffer)); + + if (StrEqual(executeBuffer, "server")) + { + itemInput.execute = Execute_Server; + } + else //assume player type execute + { + itemInput.execute = Execute_Player; + } + + /* iterate all submenus and load data into itemInput.submenus (ArrayList) */ + + int count = 1; + char countBuffer[10] = "1"; + + char inputBuffer[48]; + + while (kvMenu.JumpToKey(countBuffer)) + { + Submenu submenuInput; + + if (count == 1) + { + itemInput.submenus = new ArrayList(sizeof(submenuInput)); + } + + kvMenu.GetString("type", inputBuffer, sizeof(inputBuffer)); + + if (strncmp(inputBuffer,"group",5)==0) + { + if (StrContains(inputBuffer, "player") != -1) + { + submenuInput.type = SubMenu_GroupPlayer; + } + else + { + submenuInput.type = SubMenu_Group; + } + } + else if (StrEqual(inputBuffer,"mapcycle")) + { + submenuInput.type = SubMenu_MapCycle; + + kvMenu.GetString("path", inputBuffer, sizeof(inputBuffer),"mapcycle.txt"); + + submenuInput.listdata = new DataPack(); + submenuInput.listdata.WriteString(inputBuffer); + submenuInput.listdata.Reset(); + } + else if (StrContains(inputBuffer, "player") != -1) + { + submenuInput.type = SubMenu_Player; + } + else if (StrEqual(inputBuffer,"onoff")) + { + submenuInput.type = SubMenu_OnOff; + } + else //assume 'list' type + { + submenuInput.type = SubMenu_List; + + submenuInput.listdata = new DataPack(); + + char temp[6]; + char value[64]; + char text[64]; + char subadm[30]; // same as "admin", cf. line 110 + int i=1; + bool more = true; + + int listcount = 0; + + do + { + Format(temp,3,"%i",i); + kvMenu.GetString(temp, value, sizeof(value), ""); + + Format(temp,5,"%i.",i); + kvMenu.GetString(temp, text, sizeof(text), value); + + Format(temp,5,"%i*",i); + kvMenu.GetString(temp, subadm, sizeof(subadm),""); + + if (value[0]=='\0') + { + more = false; + } + else + { + listcount++; + submenuInput.listdata.WriteString(value); + submenuInput.listdata.WriteString(text); + submenuInput.listdata.WriteString(subadm); + } + + i++; + + } while (more); + + submenuInput.listdata.Reset(); + submenuInput.listcount = listcount; + } + + if ((submenuInput.type == SubMenu_Player) || (submenuInput.type == SubMenu_GroupPlayer)) + { + kvMenu.GetString("method", inputBuffer, sizeof(inputBuffer)); + + if (StrEqual(inputBuffer, "clientid")) + { + submenuInput.method = ClientId; + } + else if (StrEqual(inputBuffer, "steamid")) + { + submenuInput.method = SteamId; + } + else if (StrEqual(inputBuffer, "userid2")) + { + submenuInput.method = UserId2; + } + else if (StrEqual(inputBuffer, "userid")) + { + submenuInput.method = UserId; + } + else if (StrEqual(inputBuffer, "ip")) + { + submenuInput.method = IpAddress; + } + else + { + submenuInput.method = Name; + } + } + + kvMenu.GetString("title", inputBuffer, sizeof(inputBuffer)); + strcopy(submenuInput.title, sizeof(submenuInput.title), inputBuffer); + + count++; + Format(countBuffer, sizeof(countBuffer), "%i", count); + + itemInput.submenus.PushArray(submenuInput); + + kvMenu.GoBack(); + } + + /* Save this entire item into the global items array and add it to the menu */ + + int location = g_DataArray.PushArray(itemInput); + + char locString[10]; + IntToString(location, locString, sizeof(locString)); + + if (hAdminMenu.AddItem(buffer, + DynamicMenuItemHandler, + categoryId, + admin, + ADMFLAG_GENERIC, + locString) == INVALID_TOPMENUOBJECT) + { + LogError("Duplicate command name \"%s\" in adminmenu_custom.txt category \"%s\"", buffer, category_name); + } + + } while (kvMenu.GotoNextKey()); + + kvMenu.GoBack(); + + } while (kvMenu.GotoNextKey()); + + delete kvMenu; +} + +void ParseConfigs() +{ + if (!g_configParser) + g_configParser = new SMCParser(); + + g_configParser.OnEnterSection = NewSection; + g_configParser.OnKeyValue = KeyValue; + g_configParser.OnLeaveSection = EndSection; + + delete g_groupList.groupListName; + delete g_groupList.groupListCommand; + + g_groupList.groupListName = new ArrayList(ARRAY_STRING_LENGTH); + g_groupList.groupListCommand = new ArrayList(ARRAY_STRING_LENGTH); + + char configPath[256]; + BuildPath(Path_SM, configPath, sizeof(configPath), "configs/dynamicmenu/adminmenu_grouping.txt"); + if (FileExists(configPath)) + { + LogError("Warning! configs/dynamicmenu/adminmenu_grouping.txt is now configs/adminmenu_grouping.txt."); + LogError("Read the 1.0.2 release notes, as the dynamicmenu folder has been removed."); + } + else + { + BuildPath(Path_SM, configPath, sizeof(configPath), "configs/adminmenu_grouping.txt"); + } + + if (!FileExists(configPath)) + { + LogError("Unable to locate admin menu groups file: %s", configPath); + + return; + } + + int line; + SMCError err = g_configParser.ParseFile(configPath, line); + if (err != SMCError_Okay) + { + char error[256]; + SMC_GetErrorString(err, error, sizeof(error)); + LogError("Could not parse file (line %d, file \"%s\"):", line, configPath); + LogError("Parser encountered error: %s", error); + } + + return; +} + +public SMCResult NewSection(SMCParser smc, const char[] name, bool opt_quotes) +{ + return SMCParse_Continue; +} + +public SMCResult KeyValue(SMCParser smc, const char[] key, const char[] value, bool key_quotes, bool value_quotes) +{ + g_groupList.groupListName.PushString(key); + g_groupList.groupListCommand.PushString(value); + + return SMCParse_Continue; +} + +public SMCResult EndSection(SMCParser smc) +{ + g_groupCount = g_groupList.groupListName.Length; + + return SMCParse_Continue; +} + +public void DynamicMenuCategoryHandler(TopMenu topmenu, + TopMenuAction action, + TopMenuObject object_id, + int param, + char[] buffer, + int maxlength) +{ + if ((action == TopMenuAction_DisplayTitle) || (action == TopMenuAction_DisplayOption)) + { + topmenu.GetObjName(object_id, buffer, maxlength); + } +} + +public void DynamicMenuItemHandler(TopMenu topmenu, + TopMenuAction action, + TopMenuObject object_id, + int param, + char[] buffer, + int maxlength) +{ + if (action == TopMenuAction_DisplayOption) + { + topmenu.GetObjName(object_id, buffer, maxlength); + } + else if (action == TopMenuAction_SelectOption) + { + char locString[10]; + topmenu.GetInfoString(object_id, locString, sizeof(locString)); + + int location = StringToInt(locString); + + Item output; + g_DataArray.GetArray(location, output); + + strcopy(g_command[param], sizeof(g_command[]), output.cmd); + + g_currentPlace[param].item = location; + g_currentPlace[param].replaceNum = 1; + + ParamCheck(param); + } +} + +public void ParamCheck(int client) +{ + char buffer[6]; + char buffer2[6]; + + Item outputItem; + Submenu outputSubmenu; + + g_DataArray.GetArray(g_currentPlace[client].item, outputItem); + + if (g_currentPlace[client].replaceNum < 1) + { + g_currentPlace[client].replaceNum = 1; + } + + Format(buffer, 5, "#%i", g_currentPlace[client].replaceNum); + Format(buffer2, 5, "@%i", g_currentPlace[client].replaceNum); + + if (StrContains(g_command[client], buffer) != -1 || StrContains(g_command[client], buffer2) != -1) + { + outputItem.submenus.GetArray(g_currentPlace[client].replaceNum - 1, outputSubmenu); + + Menu itemMenu = new Menu(Menu_Selection); + itemMenu.ExitBackButton = true; + + if ((outputSubmenu.type == SubMenu_Group) || (outputSubmenu.type == SubMenu_GroupPlayer)) + { + char nameBuffer[ARRAY_STRING_LENGTH]; + char commandBuffer[ARRAY_STRING_LENGTH]; + + for (int i = 0; i= maxlen) + { + /* Null terminate for safety */ + output[maxlen-1] = 0; + return false; + } + + if (FindCharInString(quotechars, input[i]) != -1 || input[i] == '\\') + { + /* This char needs escaping */ + output[count] = '\\'; + count++; + + if (count >= maxlen) + { + /* Null terminate for safety */ + output[maxlen-1] = 0; + return false; + } + } + } + + output[count] = 0; + + return true; +} + +stock bool UnQuoteString(char[] input, char[] output, int maxlen, char[] quotechars) +{ + int count = 1; + int len = strlen(input); + + output[0] = input[0]; + + for (int i=1; i= maxlen) + { + /* Null terminate for safety */ + output[maxlen-1] = 0; + return false; + } + } + + output[count] = 0; + + return true; +} diff --git a/scripting/antiflood.sp b/scripting/antiflood.sp new file mode 100644 index 0000000..901327a --- /dev/null +++ b/scripting/antiflood.sp @@ -0,0 +1,123 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Anti-Flood Plugin + * Protects against chat flooding. + * + * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. + * ============================================================================= + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, version 3.0, as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * + * As a special exception, AlliedModders LLC gives you permission to link the + * code of this program (as well as its derivative works) to "Half-Life 2," the + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software + * by the Valve Corporation. You must obey the GNU General Public License in + * all respects for all other code used. Additionally, AlliedModders LLC grants + * this exception to all derivative works. AlliedModders LLC defines further + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), + * or . + * + * Version: $Id$ + */ + +#pragma semicolon 1 + +#include + +#pragma newdecls required + +public Plugin myinfo = +{ + name = "Anti-Flood", + author = "AlliedModders LLC", + description = "Protects against chat flooding", + version = SOURCEMOD_VERSION, + url = "http://www.sourcemod.net/" +}; + +enum struct PlayerInfo { + float lastTime; /* Last time player used say or say_team */ + int tokenCount; /* Number of flood tokens player has */ +} + +PlayerInfo playerinfo[MAXPLAYERS+1]; + +ConVar sm_flood_time; /* Handle to sm_flood_time convar */ +float max_chat; +public void OnPluginStart() +{ + sm_flood_time = CreateConVar("sm_flood_time", "0.75", "Amount of time allowed between chat messages"); +} + +public void OnClientPutInServer(int client) +{ + playerinfo[client].lastTime = 0.0; + playerinfo[client].tokenCount = 0; +} + + +public bool OnClientFloodCheck(int client) +{ + max_chat = sm_flood_time.FloatValue; + + if (max_chat <= 0.0 + || CheckCommandAccess(client, "sm_flood_access", ADMFLAG_ROOT, true)) + { + return false; + } + + if (playerinfo[client].lastTime >= GetGameTime()) + { + /* If player has 3 or more flood tokens, block their message */ + if (playerinfo[client].tokenCount >= 3) + { + return true; + } + } + + return false; +} + +public void OnClientFloodResult(int client, bool blocked) +{ + if (max_chat <= 0.0 + || CheckCommandAccess(client, "sm_flood_access", ADMFLAG_ROOT, true)) + { + return; + } + + float curTime = GetGameTime(); + float newTime = curTime + max_chat; + + if (playerinfo[client].lastTime >= curTime) + { + /* If the last message was blocked, update their time limit */ + if (blocked) + { + newTime += 3.0; + } + /* Add one flood token when player goes over chat time limit */ + else if (playerinfo[client].tokenCount < 3) + { + playerinfo[client].tokenCount++; + } + } + else if (playerinfo[client].tokenCount > 0) + { + /* Remove one flood token when player chats within time limit (slow decay) */ + playerinfo[client].tokenCount--; + } + + playerinfo[client].lastTime = newTime; +} diff --git a/scripting/backpack-tf.sp b/scripting/backpack-tf.sp new file mode 100644 index 0000000..bb24cd9 --- /dev/null +++ b/scripting/backpack-tf.sp @@ -0,0 +1,937 @@ +#pragma semicolon 1 + +#include +#include +#include +#include + +#define PLUGIN_VERSION "2.11.1-skial-steamworks" +#define BACKPACK_TF_URL "http://backpack.tf/api/IGetPrices/v3/" +#define ITEM_EARBUDS 143 +#define ITEM_REFINED 5002 +#define ITEM_KEY 5021 +#define ITEM_CRATE 5022 +#define ITEM_SALVAGED_CRATE 5068 +#define ITEM_HAUNTED_SCRAP 267 +#define ITEM_HEADTAKER 266 +#define QUALITY_UNIQUE "6" +#define QUALITY_UNUSUAL "5" +#define NOTIFICATION_SOUND "replay/downloadcomplete.wav" + +public Plugin:myinfo = { + name = "[TF2] backpack.tf Price Check", + author = "Bottiger, Dr. McKay", + description = "Provides a price check command for use with backpack.tf", + version = PLUGIN_VERSION, + url = "http://www.doctormckay.com" +}; + +new lastCacheTime; +new cacheTime; +new Handle:backpackTFPricelist; + +new Handle:qualityNameTrie; +new Handle:unusualNameTrie; + +new Handle:cvarBPCommand; +new Handle:cvarDisplayUpdateNotification; +new Handle:cvarDisplayChangedPrices; +new Handle:cvarHudXPos; +new Handle:cvarHudYPos; +new Handle:cvarHudRed; +new Handle:cvarHudGreen; +new Handle:cvarHudBlue; +new Handle:cvarHudHoldTime; +new Handle:cvarMenuHoldTime; +new Handle:cvarAPIKey; +new Handle:cvarTag; + +new Handle:hudText; +new Handle:sv_tags; + +new Float:budsToKeys; +new Float:keysToRef; +new Float:refToUsd; + +#define UPDATE_FILE "backpack-tf.txt" +#define CONVAR_PREFIX "backpack_tf" + +//#include "mckayupdater.sp" + +public OnPluginStart() { + cvarBPCommand = CreateConVar("backpack_tf_bp_command", "1", "Enables the !bp command for use with backpack.tf"); + cvarDisplayUpdateNotification = CreateConVar("backpack_tf_display_update_notification", "0", "Display a notification to clients when the cached price list has been updated?"); + cvarDisplayChangedPrices = CreateConVar("backpack_tf_display_changed_prices", "1", "If backpack_tf_display_update_notification is set to 1, display all prices that changed since the last update?"); + cvarHudXPos = CreateConVar("backpack_tf_update_notification_x_pos", "-1.0", "X position for HUD text from 0.0 to 1.0, -1.0 = center", _, true, -1.0, true, 1.0); + cvarHudYPos = CreateConVar("backpack_tf_update_notification_y_pos", "0.1", "Y position for HUD text from 0.0 to 1.0, -1.0 = center", _, true, -1.0, true, 1.0); + cvarHudRed = CreateConVar("backpack_tf_update_notification_red", "0", "Red value of HUD text", _, true, 0.0, true, 255.0); + cvarHudGreen = CreateConVar("backpack_tf_update_notification_green", "255", "Green value of HUD text", _, true, 0.0, true, 255.0); + cvarHudBlue = CreateConVar("backpack_tf_update_notification_blue", "0", "Blue value of HUD text", _, true, 0.0, true, 255.0); + cvarHudHoldTime = CreateConVar("backpack_tf_update_notification_message_time", "5", "Seconds to keep each message in the update ticker on the screen", _, true, 0.0); + cvarMenuHoldTime = CreateConVar("backpack_tf_menu_open_time", "0", "Time to keep the price panel open for, 0 = forever"); + cvarAPIKey = CreateConVar("backpack_tf_api_key", "", "API key obtained at http://backpack.tf/api/register/", FCVAR_PROTECTED); + cvarTag = CreateConVar("backpack_tf_add_tag", "1", "If 1, adds the backpack.tf tag to your server's sv_tags, which is required to be listed on http://backpack.tf/servers", _, true, 0.0, true, 1.0); + AutoExecConfig(); + + LoadTranslations("backpack-tf.phrases"); + + sv_tags = FindConVar("sv_tags"); + + RegConsoleCmd("sm_bp", Command_Backpack, "Usage: sm_bp "); + RegConsoleCmd("sm_backpack", Command_Backpack, "Usage: sm_backpack "); + + RegConsoleCmd("sm_pc", Command_PriceCheck, "Usage: sm_pc "); + RegConsoleCmd("sm_pricecheck", Command_PriceCheck, "Usage: sm_pricecheck "); + + RegAdminCmd("sm_updateprices", Command_UpdatePrices, ADMFLAG_ROOT, "Updates backpack.tf prices"); + + qualityNameTrie = CreateTrie(); + SetTrieString(qualityNameTrie, "0", "Normal"); + SetTrieString(qualityNameTrie, "1", "Genuine"); + SetTrieString(qualityNameTrie, "2", "rarity2"); + SetTrieString(qualityNameTrie, "3", "Vintage"); + SetTrieString(qualityNameTrie, "4", "rarity3"); + SetTrieString(qualityNameTrie, "5", "Unusual"); + SetTrieString(qualityNameTrie, "6", "Unique"); + SetTrieString(qualityNameTrie, "7", "Community"); + SetTrieString(qualityNameTrie, "8", "Valve"); + SetTrieString(qualityNameTrie, "9", "Self-Made"); + SetTrieString(qualityNameTrie, "10", "Customized"); + SetTrieString(qualityNameTrie, "11", "Strange"); + SetTrieString(qualityNameTrie, "12", "Completed"); + SetTrieString(qualityNameTrie, "13", "Haunted"); + SetTrieString(qualityNameTrie, "14", "Collector's"); + SetTrieString(qualityNameTrie, "300", "Uncraftable Vintage"); // custom for backpack.tf + SetTrieString(qualityNameTrie, "600", "Uncraftable"); // custom for backpack.tf + SetTrieString(qualityNameTrie, "1100", "Uncraftable Strange"); // custom for backpack.tf + SetTrieString(qualityNameTrie, "1300", "Uncraftable Haunted"); // custom for backpack.tf + + unusualNameTrie = CreateTrie(); + // Original effects + SetTrieString(unusualNameTrie, "6", "Green Confetti"); + SetTrieString(unusualNameTrie, "7", "Purple Confetti"); + SetTrieString(unusualNameTrie, "8", "Haunted Ghosts"); + SetTrieString(unusualNameTrie, "9", "Green Energy"); + SetTrieString(unusualNameTrie, "10", "Purple Energy"); + SetTrieString(unusualNameTrie, "11", "Circling TF Logo"); + SetTrieString(unusualNameTrie, "12", "Massed Flies"); + SetTrieString(unusualNameTrie, "13", "Burning Flames"); + SetTrieString(unusualNameTrie, "14", "Scorching Flames"); + SetTrieString(unusualNameTrie, "15", "Searing Plasma"); + SetTrieString(unusualNameTrie, "16", "Vivid Plasma"); + SetTrieString(unusualNameTrie, "17", "Sunbeams"); + SetTrieString(unusualNameTrie, "18", "Circling Peace Sign"); + SetTrieString(unusualNameTrie, "19", "Circling Heart"); + // Batch 2 + SetTrieString(unusualNameTrie, "29", "Stormy Storm"); + SetTrieString(unusualNameTrie, "30", "Blizzardy Storm"); + SetTrieString(unusualNameTrie, "31", "Nuts n' Bolts"); + SetTrieString(unusualNameTrie, "32", "Orbiting Planets"); + SetTrieString(unusualNameTrie, "33", "Orbiting Fire"); + SetTrieString(unusualNameTrie, "34", "Bubbling"); + SetTrieString(unusualNameTrie, "35", "Smoking"); + SetTrieString(unusualNameTrie, "36", "Steaming"); + // Halloween + SetTrieString(unusualNameTrie, "37", "Flaming Lantern"); + SetTrieString(unusualNameTrie, "38", "Cloudy Moon"); + SetTrieString(unusualNameTrie, "39", "Cauldron Bubbles"); + SetTrieString(unusualNameTrie, "40", "Eerie Orbiting Fire"); + SetTrieString(unusualNameTrie, "43", "Knifestorm"); + SetTrieString(unusualNameTrie, "44", "Misty Skull"); + SetTrieString(unusualNameTrie, "45", "Harvest Moon"); + SetTrieString(unusualNameTrie, "46", "It's A Secret To Everybody"); + SetTrieString(unusualNameTrie, "47", "Stormy 13th Hour"); + // Batch 3 + SetTrieString(unusualNameTrie, "56", "Kill-a-Watt"); + SetTrieString(unusualNameTrie, "57", "Terror-Watt"); + SetTrieString(unusualNameTrie, "58", "Cloud 9"); + SetTrieString(unusualNameTrie, "59", "Aces High"); + SetTrieString(unusualNameTrie, "60", "Dead Presidents"); + SetTrieString(unusualNameTrie, "61", "Miami Nights"); + SetTrieString(unusualNameTrie, "62", "Disco Beat Down"); + // Robo-effects + SetTrieString(unusualNameTrie, "63", "Phosphorous"); + SetTrieString(unusualNameTrie, "64", "Sulphurous"); + SetTrieString(unusualNameTrie, "65", "Memory Leak"); + SetTrieString(unusualNameTrie, "66", "Overclocked"); + SetTrieString(unusualNameTrie, "67", "Electrostatic"); + SetTrieString(unusualNameTrie, "68", "Power Surge"); + SetTrieString(unusualNameTrie, "69", "Anti-Freeze"); + SetTrieString(unusualNameTrie, "70", "Time Warp"); + SetTrieString(unusualNameTrie, "71", "Green Black Hole"); + SetTrieString(unusualNameTrie, "72", "Roboactive"); + // Halloween 2013 + SetTrieString(unusualNameTrie, "73", "Arcana"); + SetTrieString(unusualNameTrie, "74", "Spellbound"); + SetTrieString(unusualNameTrie, "75", "Chiroptera Venenata"); + SetTrieString(unusualNameTrie, "76", "Poisoned Shadows"); + SetTrieString(unusualNameTrie, "77", "Something Burning This Way Comes"); + SetTrieString(unusualNameTrie, "78", "Hellfire"); + SetTrieString(unusualNameTrie, "79", "Darkblaze"); + SetTrieString(unusualNameTrie, "80", "Demonflame"); + // Halloween 2014 + SetTrieString(unusualNameTrie, "81", "Bonzo The All-Gnawing"); + SetTrieString(unusualNameTrie, "82", "Amaranthine"); + SetTrieString(unusualNameTrie, "83", "Stare From Beyond"); + SetTrieString(unusualNameTrie, "84", "The Ooze"); + SetTrieString(unusualNameTrie, "85", "Ghastly Ghosts Jr"); + SetTrieString(unusualNameTrie, "86", "Haunted Phantasm Jr"); + // EOTL + SetTrieString(unusualNameTrie, "87", "Frostbite"); + SetTrieString(unusualNameTrie, "88", "Molten Mallard"); + SetTrieString(unusualNameTrie, "89", "Morning Glory"); + SetTrieString(unusualNameTrie, "90", "Death at Dusk"); + // Taunt effects + SetTrieString(unusualNameTrie, "3001", "Showstopper"); + SetTrieString(unusualNameTrie, "3002", "Showstopper"); + SetTrieString(unusualNameTrie, "3003", "Holy Grail"); + SetTrieString(unusualNameTrie, "3004", "'72"); + SetTrieString(unusualNameTrie, "3005", "Fountain of Delight"); + SetTrieString(unusualNameTrie, "3006", "Screaming Tiger"); + SetTrieString(unusualNameTrie, "3007", "Skill Gotten Gains"); + SetTrieString(unusualNameTrie, "3008", "Midnight Whirlwind"); + SetTrieString(unusualNameTrie, "3009", "Silver Cyclone"); + SetTrieString(unusualNameTrie, "3010", "Mega Strike"); + // Halloween 2014 taunt effects + SetTrieString(unusualNameTrie, "3011", "Haunted Phantasm"); + SetTrieString(unusualNameTrie, "3012", "Ghastly Ghosts"); + + hudText = CreateHudSynchronizer(); +} + +public OnConfigsExecuted() { + CreateTimer(2.0, Timer_AddTag); // Let everything load first +} + +public Action:Timer_AddTag(Handle:timer) { + if(!GetConVarBool(cvarTag)) { + return; + } + decl String:value[512]; + GetConVarString(sv_tags, value, sizeof(value)); + TrimString(value); + if(strlen(value) == 0) { + SetConVarString(sv_tags, "backpack.tf"); + return; + } + decl String:tags[64][64]; + new total = ExplodeString(value, ",", tags, sizeof(tags), sizeof(tags[])); + for(new i = 0; i < total; i++) { + if(StrEqual(tags[i], "backpack.tf")) { + return; // Tag found, nothing to do here + } + } + StrCat(value, sizeof(value), ",backpack.tf"); + SetConVarString(sv_tags, value); +} + +public OnMapStart() { + PrecacheSound(NOTIFICATION_SOUND); +} + +public Steam_FullyLoaded() { + CreateTimer(1.0, Timer_Update); // In case of late-loads +} + +GetCachedPricesAge() { + decl String:path[PLATFORM_MAX_PATH]; + BuildPath(Path_SM, path, sizeof(path), "data/backpack-tf.txt"); + if(!FileExists(path)) { + return -1; + } + new Handle:kv = CreateKeyValues("Response"); + if(!FileToKeyValues(kv, path)) { + CloseHandle(kv); + return -1; + } + new offset = KvGetNum(kv, "time_offset", 1337); // The actual offset can be positive, negative, or zero, so we'll just use 1337 as a default since that's unlikely + new time = KvGetNum(kv, "current_time"); + CloseHandle(kv); + if(offset == 1337 || time == 0) { + return -1; + } + return GetTime() - time; +} + +public Action:Timer_Update(Handle:timer) { + new age = GetCachedPricesAge(); + if(age != -1 && age < 900) { // 15 minutes + LogMessage("Locally saved pricing data is %d minutes old, bypassing backpack.tf query", age / 60); + if(backpackTFPricelist != INVALID_HANDLE) { + CloseHandle(backpackTFPricelist); + } + decl String:path[PLATFORM_MAX_PATH]; + BuildPath(Path_SM, path, sizeof(path), "data/backpack-tf.txt"); + backpackTFPricelist = CreateKeyValues("Response"); + FileToKeyValues(backpackTFPricelist, path); + + budsToKeys = GetConversion(ITEM_EARBUDS); + keysToRef = GetConversion(ITEM_KEY); + KvRewind(backpackTFPricelist); + refToUsd = KvGetFloat(backpackTFPricelist, "refined_usd_value"); + + CreateTimer(float(3600 - age), Timer_Update); + return; + } + + decl String:key[32]; + GetConVarString(cvarAPIKey, key, sizeof(key)); + if(strlen(key) == 0) { + LogError("No API key set. Fill in your API key and reload the plugin."); + return; + } + Handle request = SteamWorks_CreateHTTPRequest(k_EHTTPMethodGET, BACKPACK_TF_URL); + SteamWorks_SetHTTPRequestGetOrPostParameter(request, "key", key); + SteamWorks_SetHTTPRequestGetOrPostParameter(request, "format", "vdf"); + SteamWorks_SetHTTPRequestGetOrPostParameter(request, "names", "1"); + + SteamWorks_SetHTTPCallbacks(request, OnBackpackTFComplete); + SteamWorks_SendHTTPRequest(request); +} + +public OnBackpackTFComplete(Handle request, bool failure, bool successful, EHTTPStatusCode status) { + if(status != k_EHTTPStatusCode200OK || !successful) { + if(status == k_EHTTPStatusCode400BadRequest) { + LogError("backpack.tf API failed: You have not set an API key"); + CloseHandle(request); + CreateTimer(600.0, Timer_Update); // Set this for 10 minutes instead of 1 minute + return; + } else if(status == k_EHTTPStatusCode403Forbidden) { + LogError("backpack.tf API failed: Your API key is invalid"); + CloseHandle(request); + CreateTimer(600.0, Timer_Update); // Set this for 10 minutes instead of 1 minute + return; + } else if(status == k_EHTTPStatusCode412PreconditionFailed) { + decl String:retry[16]; + SteamWorks_GetHTTPResponseHeaderValue(request, "Retry-After", retry, sizeof(retry)); + LogError("backpack.tf API failed: We are being rate-limited by backpack.tf, next request allowed in %s seconds", retry); + } else if(status >= k_EHTTPStatusCode500InternalServerError) { + LogError("backpack.tf API failed: An internal server error occurred"); + } else if(status == k_EHTTPStatusCode200OK && !successful) { + LogError("backpack.tf API failed: backpack.tf returned an OK response but no data"); + } else if(status != k_EHTTPStatusCodeInvalid) { + LogError("backpack.tf API failed: Unknown error (status code %d)", _:status); + } else { + LogError("backpack.tf API failed: Unable to connect to server or server returned no data"); + } + CloseHandle(request); + CreateTimer(60.0, Timer_Update); // try again! + return; + } + decl String:path[256]; + BuildPath(Path_SM, path, sizeof(path), "data/backpack-tf.txt"); + + SteamWorks_WriteHTTPResponseBodyToFile(request, path); + CloseHandle(request); + LogMessage("backpack.tf price list successfully downloaded!"); + + CreateTimer(3600.0, Timer_Update); + + if(backpackTFPricelist != INVALID_HANDLE) { + CloseHandle(backpackTFPricelist); + } + backpackTFPricelist = CreateKeyValues("Response"); + FileToKeyValues(backpackTFPricelist, path); + lastCacheTime = cacheTime; + cacheTime = KvGetNum(backpackTFPricelist, "current_time"); + + new offset = GetTime() - cacheTime; + KvSetNum(backpackTFPricelist, "time_offset", offset); + KeyValuesToFile(backpackTFPricelist, path); + + budsToKeys = GetConversion(ITEM_EARBUDS); + keysToRef = GetConversion(ITEM_KEY); + KvRewind(backpackTFPricelist); + refToUsd = KvGetFloat(backpackTFPricelist, "refined_usd_value"); + + if(!GetConVarBool(cvarDisplayUpdateNotification)) { + return; + } + + if(lastCacheTime == 0) { // first download + new Handle:array = CreateArray(128); + PushArrayString(array, "#Type_command"); + SetHudTextParams(GetConVarFloat(cvarHudXPos), GetConVarFloat(cvarHudYPos), GetConVarFloat(cvarHudHoldTime), GetConVarInt(cvarHudRed), GetConVarInt(cvarHudGreen), GetConVarInt(cvarHudBlue), 255); + for(new i = 1; i <= MaxClients; i++) { + if(!IsClientInGame(i)) { + continue; + } + ShowSyncHudText(i, hudText, "%t", "Price list updated"); + EmitSoundToClient(i, NOTIFICATION_SOUND); + } + CreateTimer(GetConVarFloat(cvarHudHoldTime), Timer_DisplayHudText, array, TIMER_REPEAT); + return; + } + + PrepPriceKv(); + KvGotoFirstSubKey(backpackTFPricelist); + new bool:isNegative = false; + new lastUpdate, Float:valueOld, Float:valueOldHigh, Float:value, Float:valueHigh, Float:difference; + decl String:defindex[16], String:qualityIndex[32], String:quality[32], String:name[64], String:message[128], String:currency[32], String:currencyOld[32], String:oldPrice[64], String:newPrice[64]; + new Handle:array = CreateArray(128); + PushArrayString(array, "#Type_command"); + if(GetConVarBool(cvarDisplayChangedPrices)) { + do { + // loop through items + KvGetSectionName(backpackTFPricelist, defindex, sizeof(defindex)); + if(StringToInt(defindex) == ITEM_REFINED) { + continue; // Skip over refined price changes + } + KvGotoFirstSubKey(backpackTFPricelist); + do { + // loop through qualities + KvGetSectionName(backpackTFPricelist, qualityIndex, sizeof(qualityIndex)); + if(StrEqual(qualityIndex, "item_info")) { + KvGetString(backpackTFPricelist, "item_name", name, sizeof(name)); + continue; + } + KvGotoFirstSubKey(backpackTFPricelist); + do { + // loop through instances (series #s, effects) + lastUpdate = KvGetNum(backpackTFPricelist, "last_change"); + if(lastUpdate == 0 || lastUpdate < lastCacheTime) { + continue; // hasn't updated + } + valueOld = KvGetFloat(backpackTFPricelist, "value_old"); + valueOldHigh = KvGetFloat(backpackTFPricelist, "value_high_old"); + value = KvGetFloat(backpackTFPricelist, "value"); + valueHigh = KvGetFloat(backpackTFPricelist, "value_high"); + + KvGetString(backpackTFPricelist, "currency", currency, sizeof(currency)); + KvGetString(backpackTFPricelist, "currency_old", currencyOld, sizeof(currencyOld)); + + if(strlen(currency) == 0 || strlen(currencyOld) == 0) { + continue; + } + + FormatPriceRange(valueOld, valueOldHigh, currency, oldPrice, sizeof(oldPrice), StrEqual(qualityIndex, QUALITY_UNUSUAL)); + FormatPriceRange(value, valueHigh, currency, newPrice, sizeof(newPrice), StrEqual(qualityIndex, QUALITY_UNUSUAL)); + + // Get an average so we can determine if it went up or down + if(valueOldHigh != 0.0) { + valueOld = (valueOld + valueOldHigh) / 2.0; + } + + if(valueHigh != 0.0) { + value = (value + valueHigh) / 2.0; + } + + // Get prices in terms of refined now so we can determine if it went up or down + if(StrEqual(currencyOld, "earbuds")) { + valueOld = valueOld * budsToKeys * keysToRef; + } else if(StrEqual(currencyOld, "keys")) { + valueOld = valueOld * keysToRef; + } + + if(StrEqual(currency, "earbuds")) { + value = value * budsToKeys * keysToRef; + } else if(StrEqual(currency, "keys")) { + value = value * keysToRef; + } + + difference = value - valueOld; + if(difference < 0.0) { + isNegative = true; + difference = difference * -1.0; + } else { + isNegative = false; + } + + // Format a quality name + if(StrEqual(qualityIndex, QUALITY_UNIQUE)) { + Format(quality, sizeof(quality), ""); // if quality is unique, don't display a quality + } else if(StrEqual(qualityIndex, QUALITY_UNUSUAL) && (StringToInt(defindex) != ITEM_HAUNTED_SCRAP && StringToInt(defindex) != ITEM_HEADTAKER)) { + decl String:effect[16]; + KvGetSectionName(backpackTFPricelist, effect, sizeof(effect)); + if(!GetTrieString(unusualNameTrie, effect, quality, sizeof(quality))) { + LogError("Unknown unusual effect: %s in OnBackpackTFComplete. Please report this!", effect); + decl String:kvPath[PLATFORM_MAX_PATH]; + BuildPath(Path_SM, kvPath, sizeof(kvPath), "data/backpack-tf.%d.txt", GetTime()); + if(!FileExists(kvPath)) { + KeyValuesToFile(backpackTFPricelist, kvPath); + } + continue; + } + } else { + if(!GetTrieString(qualityNameTrie, qualityIndex, quality, sizeof(quality))) { + LogError("Unknown quality index: %s. Please report this!", qualityIndex); + continue; + } + } + + Format(message, sizeof(message), "%s%s%s: %s #From %s #To %s", quality, StrEqual(quality, "") ? "" : " ", name, isNegative ? "#Down" : "#Up", oldPrice, newPrice); + PushArrayString(array, message); + + } while(KvGotoNextKey(backpackTFPricelist)); // end: instances + KvGoBack(backpackTFPricelist); + + } while(KvGotoNextKey(backpackTFPricelist)); // end: qualities + KvGoBack(backpackTFPricelist); + + } while(KvGotoNextKey(backpackTFPricelist)); // end: items + } + + SetHudTextParams(GetConVarFloat(cvarHudXPos), GetConVarFloat(cvarHudYPos), GetConVarFloat(cvarHudHoldTime), GetConVarInt(cvarHudRed), GetConVarInt(cvarHudGreen), GetConVarInt(cvarHudBlue), 255); + for(new i = 1; i <= MaxClients; i++) { + if(!IsClientInGame(i)) { + continue; + } + ShowSyncHudText(i, hudText, "%t", "Price list updated"); + EmitSoundToClient(i, NOTIFICATION_SOUND); + } + CreateTimer(GetConVarFloat(cvarHudHoldTime), Timer_DisplayHudText, array, TIMER_REPEAT); +} + +Float:GetConversion(defindex) { + decl String:buffer[32]; + PrepPriceKv(); + IntToString(defindex, buffer, sizeof(buffer)); + KvJumpToKey(backpackTFPricelist, buffer); + KvJumpToKey(backpackTFPricelist, "6"); + KvJumpToKey(backpackTFPricelist, "0"); + new Float:value = KvGetFloat(backpackTFPricelist, "value"); + new Float:valueHigh = KvGetFloat(backpackTFPricelist, "value_high"); + if(valueHigh == 0.0) { + return value; + } + return (value + valueHigh) / 2.0; +} + +FormatPrice(Float:price, const String:currency[], String:output[], maxlen, bool:includeCurrency = true, bool:forceBuds = false) { + new String:outputCurrency[32]; + if(StrEqual(currency, "metal")) { + Format(outputCurrency, sizeof(outputCurrency), "refined"); + } else if(StrEqual(currency, "keys")) { + Format(outputCurrency, sizeof(outputCurrency), "key"); + } else if(StrEqual(currency, "earbuds")) { + Format(outputCurrency, sizeof(outputCurrency), "bud"); + } else if(StrEqual(currency, "usd")) { + if(forceBuds) { + Format(outputCurrency, sizeof(outputCurrency), "earbuds"); // This allows us to force unusual price ranges to display buds only + } + ConvertUSD(price, outputCurrency, sizeof(outputCurrency)); + } else { + ThrowError("Unknown currency: %s", currency); + } + + if(FloatIsInt(price)) { + Format(output, maxlen, "%d", RoundToFloor(price)); + } else { + Format(output, maxlen, "%.2f", price); + } + + if(!includeCurrency) { + return; + } + + if(StrEqual(output, "1") || StrEqual(currency, "metal")) { + Format(output, maxlen, "%s %s", output, outputCurrency); + } else { + Format(output, maxlen, "%s %ss", output, outputCurrency); + } +} + +FormatPriceRange(Float:low, Float:high, const String:currency[], String:output[], maxlen, bool:forceBuds = false) { + if(high == 0.0) { + FormatPrice(low, currency, output, maxlen, true, forceBuds); + return; + } + decl String:buffer[32]; + FormatPrice(low, currency, output, maxlen, false, forceBuds); + FormatPrice(high, currency, buffer, sizeof(buffer), true, forceBuds); + Format(output, maxlen, "%s-%s", output, buffer); +} + +ConvertUSD(&Float:price, String:outputCurrency[], maxlen) { + new Float:budPrice = refToUsd * keysToRef * budsToKeys; + if(price < budPrice && !StrEqual(outputCurrency, "earbuds")) { + new Float:keyPrice = refToUsd * keysToRef; + price = price / keyPrice; + Format(outputCurrency, maxlen, "key"); + } else { + price = price / budPrice; + Format(outputCurrency, maxlen, "bud"); + } +} + +bool:FloatIsInt(Float:input) { + return float(RoundToFloor(input)) == input; +} + +public Action:Timer_DisplayHudText(Handle:timer, any:array) { + if(GetArraySize(array) == 0) { + CloseHandle(array); + return Plugin_Stop; + } + decl String:text[128], String:display[128]; + GetArrayString(array, 0, text, sizeof(text)); + SetHudTextParams(GetConVarFloat(cvarHudXPos), GetConVarFloat(cvarHudYPos), GetConVarFloat(cvarHudHoldTime), GetConVarInt(cvarHudRed), GetConVarInt(cvarHudGreen), GetConVarInt(cvarHudBlue), 255); + for(new i = 1; i <= MaxClients; i++) { + if(!IsClientInGame(i)) { + continue; + } + PerformTranslationTokenReplacement(i, text, display, sizeof(display)); + ShowSyncHudText(i, hudText, display); + } + RemoveFromArray(array, 0); + return Plugin_Continue; +} + +PerformTranslationTokenReplacement(client, const String:message[], String:output[], maxlen) { + SetGlobalTransTarget(client); + strcopy(output, maxlen, message); + decl String:buffer[64]; + + Format(buffer, maxlen, "%t", "Type !pc for a price check"); + ReplaceString(output, maxlen, "#Type_command", buffer); + + Format(buffer, maxlen, "%t", "Up"); + ReplaceString(output, maxlen, "#Up", buffer); + + Format(buffer, maxlen, "%t", "Down"); + ReplaceString(output, maxlen, "#Down", buffer); + + Format(buffer, maxlen, "%t", "From"); + ReplaceString(output, maxlen, "#From", buffer); + + Format(buffer, maxlen, "%t", "To"); + ReplaceString(output, maxlen, "#To", buffer); +} + +PrepPriceKv() { + KvRewind(backpackTFPricelist); + KvJumpToKey(backpackTFPricelist, "prices"); +} + +public Action:Command_PriceCheck(client, args) { + if(backpackTFPricelist == INVALID_HANDLE) { + decl String:key[32]; + GetConVarString(cvarAPIKey, key, sizeof(key)); + if(strlen(key) == 0) { + ReplyToCommand(client, "\x04[SM] \x01The server administrator has not filled in their API key yet. Please contact the server administrator."); + } else { + ReplyToCommand(client, "\x04[SM] \x01%t.", "The price list has not loaded yet"); + } + return Plugin_Handled; + } + if(args == 0) { + new Handle:menu = CreateMenu(Handler_ItemSelection); + SetMenuTitle(menu, "Price Check"); + PrepPriceKv(); + KvGotoFirstSubKey(backpackTFPricelist); + decl String:name[128]; + do { + if(!KvJumpToKey(backpackTFPricelist, "item_info")) { + continue; + } + KvGetString(backpackTFPricelist, "item_name", name, sizeof(name)); + if(KvGetNum(backpackTFPricelist, "proper_name") == 1) { + Format(name, sizeof(name), "The %s", name); + } + AddMenuItem(menu, name, name); + KvGoBack(backpackTFPricelist); + } while(KvGotoNextKey(backpackTFPricelist)); + DisplayMenu(menu, client, GetConVarInt(cvarMenuHoldTime)); + return Plugin_Handled; + } + new resultDefindex = -1; + decl String:defindex[8], String:name[128], String:itemName[128]; + GetCmdArgString(name, sizeof(name)); + new bool:exact = StripQuotes(name); + PrepPriceKv(); + KvGotoFirstSubKey(backpackTFPricelist); + new Handle:matches; + if(!exact) { + matches = CreateArray(128); + } + do { + KvGetSectionName(backpackTFPricelist, defindex, sizeof(defindex)); + if(!KvJumpToKey(backpackTFPricelist, "item_info")) { + continue; + } + KvGetString(backpackTFPricelist, "item_name", itemName, sizeof(itemName)); + if(KvGetNum(backpackTFPricelist, "proper_name") == 1) { + Format(itemName, sizeof(itemName), "The %s", itemName); + } + KvGoBack(backpackTFPricelist); + if(exact) { + if(StrEqual(itemName, name, false)) { + resultDefindex = StringToInt(defindex); + break; + } + } else { + if(StrContains(itemName, name, false) != -1) { + resultDefindex = StringToInt(defindex); // In case this is the only match, we store the resulting defindex here so that we don't need to search to find it again + PushArrayString(matches, itemName); + } + } + } while(KvGotoNextKey(backpackTFPricelist)); + if(!exact && GetArraySize(matches) > 1) { + new Handle:menu = CreateMenu(Handler_ItemSelection); + SetMenuTitle(menu, "Search Results"); + new size = GetArraySize(matches); + for(new i = 0; i < size; i++) { + GetArrayString(matches, i, itemName, sizeof(itemName)); + AddMenuItem(menu, itemName, itemName); + } + DisplayMenu(menu, client, GetConVarInt(cvarMenuHoldTime)); + CloseHandle(matches); + return Plugin_Handled; + } + if(!exact) { + CloseHandle(matches); + } + if(resultDefindex == -1) { + ReplyToCommand(client, "\x04[SM] \x01No matching item was found."); + return Plugin_Handled; + } + // At this point, we know that we've found our item. Its defindex is stored in resultDefindex as a cell + // defindex was used to store the defindex of every item as we searched it, so it's not reliable + if(resultDefindex == ITEM_REFINED) { + SetGlobalTransTarget(client); + new Handle:menu = CreateMenu(Handler_PriceListMenu); + SetMenuTitle(menu, "%t\n%t\n%t\n ", "Price check", itemName, "Prices are estimates only", "Prices courtesy of backpack.tf"); + decl String:buffer[32]; + Format(buffer, sizeof(buffer), "Unique: $%.2f USD", refToUsd); + AddMenuItem(menu, "", buffer); + DisplayMenu(menu, client, GetConVarInt(cvarMenuHoldTime)); + return Plugin_Handled; + } + new bool:isCrate = (resultDefindex == ITEM_CRATE || resultDefindex == ITEM_SALVAGED_CRATE); + new bool:onlyOneUnusual = (resultDefindex == ITEM_HEADTAKER || resultDefindex == ITEM_HAUNTED_SCRAP); + PrepPriceKv(); + IntToString(resultDefindex, defindex, sizeof(defindex)); + KvJumpToKey(backpackTFPricelist, defindex); + KvJumpToKey(backpackTFPricelist, "item_info"); + KvGetString(backpackTFPricelist, "item_name", itemName, sizeof(itemName)); + if(KvGetNum(backpackTFPricelist, "proper_name") == 1) { + Format(itemName, sizeof(itemName), "The %s", itemName); + } + KvGotoNextKey(backpackTFPricelist); + + SetGlobalTransTarget(client); + new Handle:menu = CreateMenu(Handler_PriceListMenu); + SetMenuTitle(menu, "%t\n%t\n%t\n ", "Price check", itemName, "Prices are estimates only", "Prices courtesy of backpack.tf"); + new bool:unusualDisplayed = false; + new Float:value, Float:valueHigh; + decl String:currency[32], String:qualityIndex[16], String:quality[16], String:series[8], String:price[32], String:buffer[64]; + do { + KvGetSectionName(backpackTFPricelist, qualityIndex, sizeof(qualityIndex)); + if(StrEqual(qualityIndex, "item_info") || StrEqual(qualityIndex, "alt_defindex")) { + continue; + } + KvGotoFirstSubKey(backpackTFPricelist); + do { + if(StrEqual(qualityIndex, QUALITY_UNUSUAL) && !onlyOneUnusual) { + if(!unusualDisplayed) { + AddMenuItem(menu, defindex, "Unusual: View Effects"); + unusualDisplayed = true; + } + } else { + value = KvGetFloat(backpackTFPricelist, "value"); + valueHigh = KvGetFloat(backpackTFPricelist, "value_high"); + KvGetString(backpackTFPricelist, "currency", currency, sizeof(currency)); + FormatPriceRange(value, valueHigh, currency, price, sizeof(price)); + + if(!GetTrieString(qualityNameTrie, qualityIndex, quality, sizeof(quality))) { + LogError("Unknown quality index: %s. Please report this!", qualityIndex); + continue; + } + if(isCrate) { + KvGetSectionName(backpackTFPricelist, series, sizeof(series)); + if(StrEqual(series, "0")) { + continue; + } + if(StrEqual(qualityIndex, QUALITY_UNIQUE)) { + Format(buffer, sizeof(buffer), "Series %s: %s", series, price); + } else { + Format(buffer, sizeof(buffer), "%s: Series %s: %s", quality, series, price); + } + } else { + Format(buffer, sizeof(buffer), "%s: %s", quality, price); + } + AddMenuItem(menu, "", buffer, ITEMDRAW_DISABLED); + } + } while(KvGotoNextKey(backpackTFPricelist)); + KvGoBack(backpackTFPricelist); + } while(KvGotoNextKey(backpackTFPricelist)); + DisplayMenu(menu, client, GetConVarInt(cvarMenuHoldTime)); + return Plugin_Handled; +} + +public Handler_ItemSelection(Handle:menu, MenuAction:action, client, param) { + if(action == MenuAction_End) { + CloseHandle(menu); + } + if(action != MenuAction_Select) { + return; + } + decl String:selection[128]; + GetMenuItem(menu, param, selection, sizeof(selection)); + FakeClientCommand(client, "sm_pricecheck \"%s\"", selection); +} + +public Handler_PriceListMenu(Handle:menu, MenuAction:action, client, param) { + if(action == MenuAction_End) { + CloseHandle(menu); + } + if(action != MenuAction_Select) { + return; + } + decl String:defindex[32]; + GetMenuItem(menu, param, defindex, sizeof(defindex)); + + decl String:name[64]; + PrepPriceKv(); + KvJumpToKey(backpackTFPricelist, defindex); + KvJumpToKey(backpackTFPricelist, "item_info"); + KvGetString(backpackTFPricelist, "item_name", name, sizeof(name)); + if(KvGetNum(backpackTFPricelist, "proper_name") == 1) { + Format(name, sizeof(name), "The Unusual %s", name); + } else { + Format(name, sizeof(name), "Unusual %s", name); + } + KvGoBack(backpackTFPricelist); + + if(!KvJumpToKey(backpackTFPricelist, QUALITY_UNUSUAL)) { + return; + } + + KvGotoFirstSubKey(backpackTFPricelist); + + SetGlobalTransTarget(client); + new Handle:menu2 = CreateMenu(Handler_PriceListMenu); + SetMenuTitle(menu2, "%t\n%t\n%t\n ", "Price check", name, "Prices are estimates only", "Prices courtesy of backpack.tf"); + decl String:effect[8], String:effectName[64], String:message[128], String:price[64], String:currency[32]; + new Float:value, Float:valueHigh; + do { + KvGetSectionName(backpackTFPricelist, effect, sizeof(effect)); + if(!GetTrieString(unusualNameTrie, effect, effectName, sizeof(effectName))) { + LogError("Unknown unusual effect: %s in Handler_PriceListMenu. Please report this!", effect); + decl String:path[PLATFORM_MAX_PATH]; + BuildPath(Path_SM, path, sizeof(path), "data/backpack-tf.%d.txt", GetTime()); + if(!FileExists(path)) { + KeyValuesToFile(backpackTFPricelist, path); + } + continue; + } + value = KvGetFloat(backpackTFPricelist, "value"); + valueHigh = KvGetFloat(backpackTFPricelist, "value_high"); + KvGetString(backpackTFPricelist, "currency", currency, sizeof(currency)); + if(StrEqual(currency, "")) { + continue; + } + FormatPriceRange(value, valueHigh, currency, price, sizeof(price), true); + + Format(message, sizeof(message), "%s: %s", effectName, price); + AddMenuItem(menu2, "", message, ITEMDRAW_DISABLED); + } while(KvGotoNextKey(backpackTFPricelist)); + DisplayMenu(menu2, client, GetConVarInt(cvarMenuHoldTime)); +} + +public Action:Command_Backpack(client, args) { + if(!GetConVarBool(cvarBPCommand)) { + return Plugin_Continue; + } + new target; + if(args == 0) { + target = GetClientAimTarget(client); + if(target <= 0) { + DisplayClientMenu(client); + return Plugin_Handled; + } + } else { + decl String:arg1[MAX_NAME_LENGTH]; + GetCmdArg(1, arg1, sizeof(arg1)); + target = FindTargetEx(client, arg1, true, false, false); + if(target == -1) { + DisplayClientMenu(client); + return Plugin_Handled; + } + } + decl String:steamID[64]; + //Steam_GetCSteamIDForClient(target, steamID, sizeof(steamID)); // we could use the regular Steam ID, but we already have SteamTools, so we can just bypass backpack.tf's redirect directly + GetClientAuthId(target, AuthId_SteamID64, steamID, sizeof(steamID), false); + + decl String:url[256]; + Format(url, sizeof(url), "http://backpack.tf/profiles/%s?t=%i", steamID, GetTime()); + AdvMOTD_ShowMOTDPanel(client, "backpack.tf", url, MOTDPANEL_TYPE_URL, true, true, true, OnMOTDFailure); + return Plugin_Handled; +} + +public OnMOTDFailure(client, MOTDFailureReason:reason) { + switch(reason) { + case MOTDFailure_Disabled: PrintToChat(client, "\x04[SM] \x01You cannot view backpacks with HTML MOTDs disabled."); + case MOTDFailure_Matchmaking: PrintToChat(client, "\x04[SM] \x01You cannot view backpacks after joining via Quickplay."); + case MOTDFailure_QueryFailed: PrintToChat(client, "\x04[SM] \x01Unable to open backpack."); + } +} + +DisplayClientMenu(client) { + new Handle:menu = CreateMenu(Handler_ClientMenu); + SetMenuTitle(menu, "Select Player"); + decl String:name[MAX_NAME_LENGTH], String:index[8]; + for(new i = 1; i <= MaxClients; i++) { + if(!IsClientInGame(i) || IsFakeClient(i)) { + continue; + } + GetClientName(i, name, sizeof(name)); + IntToString(GetClientUserId(i), index, sizeof(index)); + AddMenuItem(menu, index, name); + } + DisplayMenu(menu, client, GetConVarInt(cvarMenuHoldTime)); +} + +public Handler_ClientMenu(Handle:menu, MenuAction:action, client, param) { + if(action == MenuAction_End) { + CloseHandle(menu); + } + if(action != MenuAction_Select) { + return; + } + decl String:selection[32]; + GetMenuItem(menu, param, selection, sizeof(selection)); + FakeClientCommand(client, "sm_backpack #%s", selection); +} + +public Action:Command_UpdatePrices(client, args) { + new age = GetCachedPricesAge(); + if(age != -1 && age < 900) { // 15 minutes + ReplyToCommand(client, "\x04[SM] \x01The price list cannot be updated more frequently than every 15 minutes. It is currently %d minutes old.", age / 60); + return Plugin_Handled; + } + ReplyToCommand(client, "\x04[SM] \x01Updating backpack.tf prices..."); + Timer_Update(INVALID_HANDLE); + return Plugin_Handled; +} + +FindTargetEx(client, const String:target[], bool:nobots = false, bool:immunity = true, bool:replyToError = true) { + decl String:target_name[MAX_TARGET_LENGTH]; + decl target_list[1], target_count, bool:tn_is_ml; + + new flags = COMMAND_FILTER_NO_MULTI; + if(nobots) { + flags |= COMMAND_FILTER_NO_BOTS; + } + if(!immunity) { + flags |= COMMAND_FILTER_NO_IMMUNITY; + } + + if((target_count = ProcessTargetString( + target, + client, + target_list, + 1, + flags, + target_name, + sizeof(target_name), + tn_is_ml)) > 0) + { + return target_list[0]; + } else { + if(replyToError) { + ReplyToTargetError(client, target_count); + } + return -1; + } +} \ No newline at end of file diff --git a/scripting/basebans.sp b/scripting/basebans.sp new file mode 100644 index 0000000..3218051 --- /dev/null +++ b/scripting/basebans.sp @@ -0,0 +1,395 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Basic Commands Plugin + * Implements basic admin commands. + * + * SourceMod (C)2004-2008 AlliedModders LLC. All rights reserved. + * ============================================================================= + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, version 3.0, as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * + * As a special exception, AlliedModders LLC gives you permission to link the + * code of this program (as well as its derivative works) to "Half-Life 2," the + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software + * by the Valve Corporation. You must obey the GNU General Public License in + * all respects for all other code used. Additionally, AlliedModders LLC grants + * this exception to all derivative works. AlliedModders LLC defines further + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), + * or . + * + * Version: $Id$ + */ + +#pragma semicolon 1 + +#include +#undef REQUIRE_PLUGIN +#include + +#pragma newdecls required + +public Plugin myinfo = +{ + name = "Basic Ban Commands", + author = "AlliedModders LLC", + description = "Basic Banning Commands", + version = SOURCEMOD_VERSION, + url = "http://www.sourcemod.net/" +}; + +TopMenu hTopMenu; + +enum struct PlayerInfo { + int banTarget; + int banTargetUserId; + int banTime; + int isWaitingForChatReason; +} + +PlayerInfo playerinfo[MAXPLAYERS+1]; + +KeyValues g_hKvBanReasons; +char g_BanReasonsPath[PLATFORM_MAX_PATH]; + +#include "basebans/ban.sp" + +public void OnPluginStart() +{ + BuildPath(Path_SM, g_BanReasonsPath, sizeof(g_BanReasonsPath), "configs/banreasons.txt"); + + LoadBanReasons(); + + LoadTranslations("common.phrases"); + LoadTranslations("basebans.phrases"); + LoadTranslations("core.phrases"); + + RegAdminCmd("sm_ban", Command_Ban, ADMFLAG_BAN, "sm_ban <#userid|name> [reason]"); + RegAdminCmd("sm_unban", Command_Unban, ADMFLAG_UNBAN, "sm_unban "); + RegAdminCmd("sm_addban", Command_AddBan, ADMFLAG_RCON, "sm_addban