├── .github └── workflows │ ├── compile.yml │ └── package.yml ├── .gitignore ├── LICENSE.txt ├── README.md ├── addons └── sourcemod │ ├── configs │ └── toxic_spots │ │ └── toxic_spots.cfg │ ├── gamedata │ ├── brs_gamedata.txt │ ├── ff2.sarysapack.txt │ └── smoothedvelocity.txt │ ├── scripting │ ├── ams_redux.sp │ ├── antisolorage.sp │ ├── bossmode.sp │ ├── brs_hale │ │ ├── handles.sp │ │ ├── homing.sp │ │ ├── medigun.sp │ │ ├── multiple.sp │ │ ├── stocks.sp │ │ ├── stun_gun.sp │ │ ├── upgrade.sp │ │ └── wrap.sp │ ├── characters │ │ ├── fastzombie.sp │ │ ├── greyalien.sp │ │ ├── halloween_framework.inc │ │ ├── mummy.sp │ │ ├── oogieboogie.sp │ │ └── orb.sp │ ├── characters_new │ │ └── gray.sp │ ├── deadrun_helper.sp │ ├── ff2_MP.sp │ ├── ff2_admin_menu.sp │ ├── ff2_admin_menu_fork.sp │ ├── ff2_boss_prefs.sp │ ├── ff2_boss_selection.sp │ ├── ff2_boss_toggle.sp │ ├── ff2_bossname.sp │ ├── ff2_custom_attribute_adapter.sp │ ├── ff2_kstreak_pref.sp │ ├── ff2_mana_system.sp │ ├── ff2stats.sp │ ├── freaks │ │ ├── M7_abilities.sp │ │ ├── black_rock_shooter.sp │ │ ├── bloodriders_plugin.sp │ │ ├── damagetracker.sp │ │ ├── dan_and_dum.sp │ │ ├── deadrun.sp │ │ ├── default_abilities.sp │ │ ├── default_dots.sp │ │ ├── doki_doki_literatur_club.sp │ │ ├── dot_template.sp │ │ ├── double_copycat.sp │ │ ├── drain_over_time.sp │ │ ├── duck_abilities.sp │ │ ├── easter_abilities.sp │ │ ├── ep_radimoko.sp │ │ ├── ff2_1st_set_abilities.sp │ │ ├── ff2_advancedformulas.sp │ │ ├── ff2_airdash.sp │ │ ├── ff2_ams_sample.sp │ │ ├── ff2_blockdropitem.sp │ │ ├── ff2_bob.sp │ │ ├── ff2_bodyeffects.sp │ │ ├── ff2_bomby.sp │ │ ├── ff2_bosstweaks.sp │ │ ├── ff2_bypass.sp │ │ ├── ff2_client_musicmod.sp │ │ ├── ff2_csgo.sp │ │ ├── ff2_darthmule_stripped.sp │ │ ├── ff2_death.sp │ │ ├── ff2_death_notice.sp │ │ ├── ff2_doability.sp │ │ ├── ff2_dynamic_defaults.sp │ │ ├── ff2_fakeams.sp │ │ ├── ff2_falleffects.sp │ │ ├── ff2_fog.sp │ │ ├── ff2_freddykrueger.sp │ │ ├── ff2_frozen.sp │ │ ├── ff2_grab.sp │ │ ├── ff2_grapplehookplus.sp │ │ ├── ff2_grip.sp │ │ ├── ff2_killicon.sp │ │ ├── ff2_mac.sp │ │ ├── ff2_movespeed.sp │ │ ├── ff2_octogonapus.sp │ │ ├── ff2_otokiru.sp │ │ ├── ff2_otokiru_pp.sp │ │ ├── ff2_otokiru_wc3.sp │ │ ├── ff2_painiscupcake.sp │ │ ├── ff2_pauseability.sp │ │ ├── ff2_phatrages.sp │ │ ├── ff2_powerups.sp │ │ ├── ff2_projectile_turret.sp │ │ ├── ff2_ragemodel.sp │ │ ├── ff2_ragesound.sp │ │ ├── ff2_replaceprojectile.sp │ │ ├── ff2_salmon.sp │ │ ├── ff2_sam.sp │ │ ├── ff2_sarysamods.sp │ │ ├── ff2_sarysamods2.sp │ │ ├── ff2_sarysamods3.sp │ │ ├── ff2_sarysamods4.sp │ │ ├── ff2_sarysamods5.sp │ │ ├── ff2_sarysamods6.sp │ │ ├── ff2_sarysamods7.sp │ │ ├── ff2_sarysamods8.sp │ │ ├── ff2_sarysamods9.sp │ │ ├── ff2_sarysapub1.sp │ │ ├── ff2_sarysapub2.sp │ │ ├── ff2_sarysapub3.sp │ │ ├── ff2_sarysapub3r.sp │ │ ├── ff2_scp173.sp │ │ ├── ff2_servercommandrage.sp │ │ ├── ff2_shulk.sp │ │ ├── ff2_skeleton.sp │ │ ├── ff2_sok.sp │ │ ├── ff2_spongebob.sp │ │ ├── ff2_superhot.sp │ │ ├── ff2_support.sp │ │ ├── ff2_tempMelee.sp │ │ ├── ff2_tfcond.sp │ │ ├── ff2_thruster.sp │ │ ├── ff2_timed_new_weapon.sp │ │ ├── ff2_tnw.sp │ │ ├── ff2_touhou.sp │ │ ├── ff2_witchdoctor.sp │ │ ├── ff2_wolf.sp │ │ ├── ffbat_blitzkrieg.sp │ │ ├── ffbat_defaults.sp │ │ ├── ffbat_menu_abilities.sp │ │ ├── ffbat_mvm_abilities.sp │ │ ├── ffbat_new_abilities.sp │ │ ├── ffbat_publicpack.sp │ │ ├── freedom_abilities.sp │ │ ├── halloween_2013.sp │ │ ├── halloween_2014.sp │ │ ├── happy_to_mad.sp │ │ ├── hudminmode.sp │ │ ├── improved_saxton.sp │ │ ├── jason_voorhees.sp │ │ ├── juegos_flamethrower.sp │ │ ├── km_lifeloss.sp │ │ ├── luigi_ghost.sp │ │ ├── m7_abilities_extended.sp │ │ ├── m7_customizable.sp │ │ ├── mann_up_abilities.sp │ │ ├── misc_stuff.sp │ │ ├── monochromatic.sp │ │ ├── nightmare.sp │ │ ├── overlay_on_kill.sp │ │ ├── payday_abilities.sp │ │ ├── playerclimb_ff2.sp │ │ ├── powerlord_abilities.sp │ │ ├── rage_overlay.sp │ │ ├── rage_overlay_2.sp │ │ ├── robotic_soldier_ability.sp │ │ ├── s93_beepman.sp │ │ ├── s93_blitzkrieg.sp │ │ ├── s93_bowrage.sp │ │ ├── s93_mvm_abilities.sp │ │ ├── saitama.sp │ │ ├── scooty_abilities.sp │ │ ├── shadow93_abilities.sp │ │ ├── shadow93_bosses.sp │ │ ├── skeleton_king.sp │ │ ├── socold_fix.sp │ │ ├── special_ams_overlay.sp │ │ ├── special_noanims.sp │ │ ├── special_stealing.sp │ │ ├── special_stipper.sp │ │ ├── stamina_rush.sp │ │ ├── stealmelee.sp │ │ ├── stealprimary.sp │ │ ├── stealsecondary.sp │ │ ├── the_killing_mann.sp │ │ ├── the_true_administrator.sp │ │ └── the_wight.sp │ ├── hudminmode.sp │ ├── include │ │ ├── POTRY.inc │ │ ├── ams_helper.sp │ │ ├── drain_over_time.inc │ │ ├── drain_over_time_subplugin.inc │ │ ├── ff2_ams.inc │ │ ├── ff2_ams2.inc │ │ ├── ff2_dynamic_defaults.inc │ │ ├── ff2_helper.inc │ │ ├── ff2_mana_interface.inc │ │ ├── ff2ability.inc │ │ ├── ff2menu_included.inc │ │ ├── ffbat_menu.inc │ │ ├── freak_fortress_2_extras.inc │ │ ├── freak_fortress_2_kstreak.inc │ │ ├── menu_helper.sp │ │ └── stocksoup │ │ │ └── sdkports │ │ │ └── util.inc │ ├── menurage_platform.sp │ ├── respawn_tickets.sp │ ├── rps4points.sp │ ├── streaker.sp │ ├── toxicspots.sp │ ├── tts.sp │ ├── vshbots_logic.sp │ └── vshbots_move.sp │ └── translations │ ├── dmedic.phrases.txt │ ├── ff2_1st_set.phrases.txt │ ├── ff2_boss_selection.txt │ ├── ff2_boss_toggle.phrases.txt │ ├── ff2_luigi_ghost.phrases.txt │ ├── ff2_newsalmon.charge.txt │ ├── ff2_otokiru.phrases.txt │ ├── ff2_shadow93.phrases.txt │ ├── ff2_shadow93_bosses.phrases.txt │ ├── ff2boss.phrases.txt │ ├── ff2bossprefs.phrases.txt │ ├── ff2kstreak.phrases.txt │ ├── ff2stats.phrases.txt │ ├── freedom_abilities.phrases.txt │ └── rps4points.phrases.txt ├── materials └── freak_fortress_2 │ └── dots │ ├── alt_fire_overlay1.vmt │ ├── alt_fire_overlay1.vtf │ ├── alt_fire_overlay2.vmt │ ├── alt_fire_overlay2.vtf │ ├── attack3_overlay1.vmt │ ├── attack3_overlay1.vtf │ ├── attack3_overlay2.vmt │ ├── attack3_overlay2.vtf │ ├── reload_overlay1.vmt │ ├── reload_overlay1.vtf │ ├── reload_overlay2.vmt │ └── reload_overlay2.vtf ├── scripts ├── compile.sh ├── date.sh ├── install.sh ├── package.sh └── sourcemod.sh └── sound └── war3source ├── blinkarrival.wav ├── entanglingrootsdecay1.wav └── lightningbolt.wav /.github/workflows/compile.yml: -------------------------------------------------------------------------------- 1 | name: Compile 2 | 3 | on: 4 | pull_request: 5 | branches: edited 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v1 14 | 15 | - name: Environments 16 | run: | 17 | echo ::set-env name=SM_VERSION::1.10 18 | 19 | - name: SourceMod 20 | run: | 21 | bash scripts/sourcemod.sh 22 | 23 | - name: Install 24 | run: | 25 | bash scripts/install.sh 26 | 27 | - name: Compile 28 | run: | 29 | bash scripts/compile.sh -------------------------------------------------------------------------------- /.github/workflows/package.yml: -------------------------------------------------------------------------------- 1 | name: Package 2 | 3 | on: 4 | push: 5 | branches: edited 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v1 14 | 15 | - name: Environments 16 | run: | 17 | echo ::set-env name=SM_VERSION::1.10 18 | 19 | - name: SourceMod 20 | run: | 21 | bash scripts/sourcemod.sh 22 | 23 | - name: Install 24 | run: | 25 | bash scripts/install.sh 26 | 27 | - name: Set Version 28 | run: | 29 | bash scripts/date.sh 30 | 31 | - name: Compile 32 | run: | 33 | bash scripts/compile.sh 34 | 35 | - name: Package 36 | run: | 37 | bash scripts/package.sh 38 | 39 | - name: Upload Artifacts 40 | uses: actions/upload-artifact@master 41 | with: 42 | name: FF2-Library-${{env.DATE_VERSION}} 43 | path: ./build/package -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.dat 2 | *.exe 3 | *.ff2 4 | *.smx 5 | [Cc]compiled/ 6 | [Dd]esktop.ini 7 | [Tt]humbs.db -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Freak Fortress 2 Library 2 | ## All plugin authors go to their rightful owners 3 | 4 | This repository contains subplugins from the [Freak Fortress 2 sub-forum](https://forums.alliedmods.net/forumdisplay.php?f=154 "VSH / Freak Fortress - AlliedModders"). [original branch](https://github.com/Batfoxkid/FF2-Library/tree/original "Batfoxkid/FF2-Library: Time saving solution to getting Freak Fortress 2 subplugins or plugins for a server.") contains subplugins in their original state while [edited branch](https://github.com/Batfoxkid/FF2-Library/tree/edited "Batfoxkid/FF2-Library: Time saving solution to getting Freak Fortress 2 subplugins or plugins for a server.") contains subplugins that have been edited from what they were on the sub-forum. 5 | 6 | Only few subplugins are owned by me, **all other subplugins are not owned by me, authors are in the sourcecode.** 7 | **This repository have a different/modified versions of subplugins.** 8 | 9 | *** 10 | 11 |    **I highly advice you to only install what your bosses need and if you want any non-ability subplugins!** 12 | -------------------------------------------------------------------------------- /addons/sourcemod/configs/toxic_spots/toxic_spots.cfg: -------------------------------------------------------------------------------- 1 | ToxicSpots 2 | { 3 | // INSTRUCTIONS FOR FINDING RECTANGLES AND LIGHT SPOTS: 4 | // - Turn on noclip on a private server 5 | // - Go into console and set the following: cl_showpos 1 6 | // - Go to your rectangle start in noclip mode. Note that this spot is at EYE level, not where your feet are. 7 | // - Copy coords you see on the top right. 8 | // - Repeat this process for rectangle end, and where you wish to place the light. 9 | 10 | "settings" 11 | { 12 | "bossteam" "3" // boss team, 3 is BLU, 2 is RED 13 | "lightcolor" "0xff4040" // color of the warning light that clues players that they're entering a bannable spot 14 | "damage" "2.0" // initial damage to suffer per second (mercenaries) 15 | "bossdamage" "4.0" // initial damage to suffer per second (boss team, since it takes a camping hale much longer to die) 16 | // if the below is 1.0 or less, player will suffer static damage every second 17 | "damageexp" "1.4" // initial damage exponent. equation for damage (x=this value, n=num times in spot per round, d=damage) is d^(1.0+((x-1.0)*n)) 18 | "minammoloss" "0.95" // initial ammo/metal multiplier per second (high is less drain, low is more drain) 19 | "maxammoloss" "0.10" // final ammo/metal multiplier per second, after 20 seconds in that spot 20 | "medigunloss" "0.1" // medigun charge to remove per second (1.0 = 100%) 21 | "bossdelay" "10" // boss delay (seconds) before boss takes damage. note that they will only count this down if they're in the spots but no players are (keeps them from hiding in bannable spots) 22 | "mercmsg" "BANNABLE SPOT. Get out now or be slain." // note: boss sees this if they camp there too long. 23 | "bossmsg" "BANNABLE SPOT. Go out and fight the players. %d seconds remaining." // boss sees this during their grace period 24 | "slaymsg" "You were slain for exploiting the map." // message player gets when insta-slain. this and the one below it are only for insta-slay 25 | "slayglobalmsg" "%s (%s) was automatically slain for attempting to exploit the map." // message everyone sees in chat, notifying admins of the would-be troublemaker 26 | } 27 | 28 | // NOTE: Limits for the below 29 | // limit 100 maps 30 | // limit 10 rectangles per maps 31 | // if you need more than 10, it's time to contact the mapmaker and ask them politely to fix their broken map. 32 | "map0" // map0-map99 are the maps. breaks are allowed, considering these are only loaded OnMapStart() it's more user friendly that way 33 | { 34 | "name" "vsh_dunes_b2" // map name. can be partial, i.e. vsh_dunes_ 35 | "rect0" "-1767,-235,-71;-2063,268,-251" // rectangle, format x1,y1,z1;x2,y2,z2 (does not have to be min;max!) 36 | "light0" "-1923,-44,-87" // coords to spawn the light (optional) 37 | "luminosity0" "300.0" // intensity of the light (actually it's just radius, heh) 38 | } 39 | "map1" 40 | { 41 | "name" "arena_hydrothunder_b4" // map name. can be partial 42 | "rect0" "-771,352,406;-930,-91,560" // rectangle, format x1,y1,z1;x2,y2,z2 (does not have to be min;max!) 43 | "light0" "-843,144,509" // coords to spawn the light (optional) 44 | "luminosity0" "100.0" // intensity of the light (actually it's just radius, heh) 45 | } 46 | "map2" 47 | { 48 | "name" "vsh_rockslide_2" // map name. can be partial 49 | "rect0" "1048,-792,524;948,172,376" // rectangle, format x1,y1,z1;x2,y2,z2 (does not have to be min;max!) 50 | "light0" "1001,-299,426" // coords to spawn the light (optional) 51 | "luminosity0" "150.0" // intensity of the light 52 | "rect1" "1048,-792,524;583,-691,380" // rectangle, format x1,y1,z1;x2,y2,z2 (does not have to be min;max!) 53 | "light1" "835,-732,418" // coords to spawn the light (optional) 54 | "luminosity1" "150.0" // intensity of the light (actually it's just radius, heh) 55 | } 56 | "map3" 57 | { 58 | "name" "vsh_west_fix" 59 | "rect0" "1300,-4200,-100;-4601,881,36" // rectangle, format x1,y1,z1;x2,y2,z2 (does not have to be min;max!) 60 | "slay0" "1" // instantly slay the player. best for particluarly egregious spots 61 | "rect1" "-3572,-3584,36;-1107,-4200,2000" // rectangle, format x1,y1,z1;x2,y2,z2 (does not have to be min;max!) 62 | "slay1" "1" // instantly slay the player. best for particluarly egregious spots 63 | } 64 | "map4" 65 | { 66 | "name" "arena_watchtower" 67 | "rect0" "117,-158,2080;-145,153,3000" 68 | } 69 | } 70 | 71 | -------------------------------------------------------------------------------- /addons/sourcemod/gamedata/brs_gamedata.txt: -------------------------------------------------------------------------------- 1 | "Games" 2 | { 3 | "tf" 4 | { 5 | "Functions" 6 | { 7 | "CWeaponMedigun::AllowedToHealTarget" 8 | { 9 | "signature" "CWeaponMedigun::AllowedToHealTarget" 10 | "callconv" "thiscall" 11 | "return" "bool" 12 | "this" "entity" 13 | "arguments" 14 | { 15 | "heal_target" 16 | { 17 | "type" "cbaseentity" 18 | } 19 | } 20 | } 21 | "CBaseCombatWeapon::ItemPostFrame" 22 | { 23 | "offset" "CBaseCombatWeapon::ItemPostFrame" 24 | "hooktype" "entity" 25 | "return" "void" 26 | "this" "entity" 27 | } 28 | "CBaseCombatWeapon::PrimaryAttack" 29 | { 30 | "offset" "CBaseCombatWeapon::PrimaryAttack" 31 | "hooktype" "entity" 32 | "return" "void" 33 | "this" "entity" 34 | } 35 | } 36 | 37 | "Signatures" 38 | { 39 | "CGlobalEntityList::FindEntityInSphere" 40 | { 41 | "library" "server" 42 | "linux" "@_ZN17CGlobalEntityList18FindEntityInSphereEP11CBaseEntityRK6Vectorf" 43 | "windows" "\x55\x8B\xEC\x83\xEC\x0C\x53\x56\x57\x8B\xF9\x8B\x4D\x08" 44 | } 45 | "CWeaponMedigun::AllowedToHealTarget" 46 | { 47 | "library" "server" 48 | "linux" "@_ZN14CWeaponMedigun19AllowedToHealTargetEP11CBaseEntity" 49 | "windows" "\x55\x8B\xEC\x53\x8B\xD9\x56\x57\x8B\xB3\xE8\x01\x00\x00" 50 | } 51 | "CEconItemSchema::GetItemDefinition" 52 | { 53 | "library" "server" 54 | "linux" "@_ZN15CEconItemSchema17GetItemDefinitionEi" 55 | "windows" "\x55\x8B\xEC\x56\x8B\xF1\x8D\x45\x08\x57\x50\x8D\x8E\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x85\xC0" 56 | } 57 | "CEconItemSchema" 58 | { 59 | "library" "server" 60 | "linux" "@_Z15GEconItemSchemav" 61 | "windows" "\xE8\x2A\x2A\x2A\x2A\x83\xC0\x04\xC3" 62 | } 63 | } 64 | "Offsets" 65 | { 66 | "CBaseCombatWeapon::GetSlot" 67 | { 68 | "linux" "332" 69 | "windows" "326" 70 | } 71 | "CBaseCombatWeapon::PrimaryAttack" 72 | { 73 | "linux" "285" 74 | "windows" "279" 75 | } 76 | "CBaseCombatWeapon::ItemPostFrame" 77 | { 78 | "linux" "271" 79 | "windows" "265" 80 | } 81 | "CEconItemDefinition::m_pszItemIconClassname" 82 | { 83 | "linux" "216" 84 | "windows" "216" 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /addons/sourcemod/gamedata/ff2.sarysapack.txt: -------------------------------------------------------------------------------- 1 | "Games" 2 | { 3 | "tf" 4 | { 5 | "Offsets" 6 | { 7 | "CBaseCombatWeapon::GetSlot" 8 | { 9 | "linux" "332" 10 | "windows" "326" 11 | } 12 | "CTFPlayer::Weapon_Switch" 13 | { 14 | "linux" "268" 15 | "windows" "267" 16 | } 17 | "CBasePlayer::EquipWearable" 18 | { 19 | "linux" "431" 20 | "windows" "430" 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /addons/sourcemod/gamedata/smoothedvelocity.txt: -------------------------------------------------------------------------------- 1 | "Games" 2 | { 3 | "tf" 4 | { 5 | "Offsets" 6 | { 7 | "GetSmoothedVelocity" 8 | { 9 | "windows" "139" 10 | "linux" "140" 11 | "mac" "140" 12 | } 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/antisolorage.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | #include 3 | #include 4 | #include 5 | 6 | public Plugin:myinfo = { 7 | name = "Anti-Solo Rage", 8 | author = "Nanochip", 9 | description = "Disables solo rages.", 10 | version = "1.0", 11 | url = "lol" 12 | }; 13 | 14 | new Handle:cvarAntiSoloRageBypass; 15 | 16 | new bool:canMsg = true; 17 | new bool:soloRage; 18 | 19 | public OnPluginStart() 20 | { 21 | cvarAntiSoloRageBypass = CreateConVar("sm_antisolorage_bypass", "", "Which bosses do you want to bypass the anti solo rage?"); 22 | } 23 | 24 | public FF2_PreAbility(boss, const String:pluginName[], const String:abilityName[], slot, &bool:enabled) 25 | { 26 | new Float:rageDist = FF2_GetRageDist(boss, "default_abilities", ""); 27 | new client = GetClientOfUserId(FF2_GetBossUserId(boss)); 28 | 29 | if (IsBossBypassed(client)) return; 30 | 31 | decl Float:fClientEyePosition[3]; 32 | GetClientEyePosition(client, fClientEyePosition); 33 | 34 | new players = 0; 35 | for (new i = 1; i <= MaxClients; i++) 36 | { 37 | if (IsClientInGame(i) && IsClientConnected(i) && !IsClientObserver(i) && GetClientTeam(i) != GetClientTeam(client)) 38 | { 39 | decl Float:fClientLocation[3]; 40 | GetClientAbsOrigin(i, fClientLocation); 41 | 42 | fClientLocation[2] += 90; 43 | 44 | decl Float:fDistance[3]; 45 | MakeVectorFromPoints(fClientLocation, fClientEyePosition, fDistance); 46 | 47 | if (GetVectorLength(fDistance) < rageDist && GetClientTeam(client) != GetClientTeam(i)) 48 | { 49 | players++; 50 | } 51 | } 52 | } 53 | 54 | if (players == 1 && slot == 0) 55 | { 56 | enabled = false; 57 | soloRage = true; 58 | } else { 59 | soloRage = false; 60 | } 61 | } 62 | 63 | public OnGameFrame() 64 | { 65 | for (new i = 1; i <= MaxClients; i++) 66 | { 67 | if (FF2_GetBossIndex(i) != -1) 68 | { 69 | if (soloRage && canMsg) 70 | { 71 | CPrintToChatAll("{olive}[FF2] {default}%N tried to {red}Solo-Rage{default}! It's not very effective...", i); 72 | canMsg = false; 73 | soloRage = false; 74 | CreateTimer(10.0, Timer_Delay, _, TIMER_FLAG_NO_MAPCHANGE); 75 | } 76 | } 77 | } 78 | } 79 | 80 | public Action:Timer_Delay(Handle:timer) 81 | { 82 | canMsg = true; 83 | } 84 | 85 | bool:IsBossBypassed(client) 86 | { 87 | new index = FF2_GetBossIndex(client); 88 | decl String:name[56], String:cvar[1024]; 89 | FF2_GetBossSpecial(index, name, sizeof(name)); 90 | GetConVarString(cvarAntiSoloRageBypass, cvar, sizeof(cvar)); 91 | if (StrContains(cvar, name, false) != -1) return true; 92 | return false; 93 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/brs_hale/homing.sp: -------------------------------------------------------------------------------- 1 | 2 | public void Handle_HomingRocket(int boss) 3 | { 4 | SpawnSpecialWeapon(boss, Homing); 5 | } 6 | 7 | static float flNextThink[2048]; 8 | public void Handle_HomingRocketThink(int rocket) 9 | { 10 | if(flNextThink[rocket] > GetGameTime()) 11 | return; 12 | 13 | int owner = GethOwnerEntity(GetEntPropEnt(rocket, Prop_Send, "m_hOriginalLauncher")); 14 | if(!ValidatePlayer(owner, Any)) 15 | return; 16 | 17 | FF2Prep Boss = FF2Prep(owner); 18 | if(!Boss.HasAbility(this_plugin_name, "special_weapons_homing")) 19 | return; 20 | 21 | flNextThink[rocket] = GetGameTime() + Boss.GetArgF(this_plugin_name, "special_weapons_homing", "next think", 13, 0.1); 22 | 23 | float rocketOrigin[3]; 24 | GetEntPropVector(rocket, Prop_Data, "m_vecAbsOrigin", rocketOrigin); 25 | int target = FindNearestTargetInSphere(Boss.GetArgF(this_plugin_name, "special_weapons_homing", "homing radius", 14, 400.0) , rocket, rocketOrigin); 26 | 27 | if(target <= 0) { 28 | return; 29 | } 30 | 31 | SetEntDataFloat(rocket, m_flRocketDamage, Boss.GetArgF(this_plugin_name, "special_weapons_homing", "damage", 15, 75.0), true); 32 | 33 | static float vecVelocity[3], vecPosition[3]; 34 | GetEntPropVector(rocket, Prop_Data, "m_vecAbsVelocity", vecVelocity); 35 | 36 | float flSpeed = NormalizeVector(vecVelocity, vecVelocity); 37 | GetClientEyePosition(target, vecPosition); 38 | 39 | float vecTargetAim[3]; 40 | MakeVectorFromPoints(rocketOrigin, vecPosition, vecTargetAim); 41 | NormalizeVector(vecTargetAim, vecTargetAim); 42 | 43 | for (int x; x < 3; x++) 44 | vecVelocity[x] += ((vecTargetAim[x] - vecVelocity[x]) * Boss.GetArgF(this_plugin_name, "special_weapons_homing", "turn rate", 16, 75.0)); 45 | 46 | NormalizeVector(vecVelocity, vecVelocity); 47 | flSpeed *= Boss.GetArgF(this_plugin_name, "special_weapons_homing", "speed", 17, 0.75); 48 | if(flSpeed < 500.0) 49 | flSpeed = 500.0; 50 | ScaleVector(vecVelocity, flSpeed); 51 | 52 | GetVectorAngles(vecVelocity, vecTargetAim); 53 | SetEntPropVector(rocket, Prop_Data, "m_vecAbsVelocity", vecVelocity); 54 | 55 | TeleportEntity(rocket, NULL_VECTOR, vecTargetAim, NULL_VECTOR); 56 | } 57 | 58 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/brs_hale/medigun.sp: -------------------------------------------------------------------------------- 1 | public void Prep_Medigun(GameData &Config) 2 | { 3 | Handle hAllowedToheal = DHookCreateFromConf(Config, "CWeaponMedigun::AllowedToHealTarget"); 4 | 5 | if(hAllowedToheal == null) 6 | { 7 | delete Config; 8 | SetFailState("[GameData] Failed to Create a Hook for \"CWeaponMedigun::AllowedToHealTarget\""); 9 | return; 10 | } 11 | 12 | DHookEnableDetour(hAllowedToheal, false, Pre_CanHealTarget); 13 | } 14 | 15 | public void Handle_MedigunRage(int boss) 16 | { 17 | SpawnSpecialWeapon(boss, Healing); 18 | } 19 | 20 | public MRESReturn Pre_CanHealTarget(int medigun, Handle Return, Handle Params) 21 | { 22 | int owner = GethOwnerEntity(medigun); 23 | if(!ValidatePlayer(owner, IsBoss)) 24 | return MRES_Ignored; 25 | 26 | if(GetCurrentWeapon(FF2_GetBossIndex(owner)) != medigun) 27 | return MRES_Ignored; 28 | 29 | int target = DHookGetParam(Params, 1); 30 | if(ValidatePlayer(target, AnyAlive)) { 31 | if(TF2_GetPlayerClass(target) == TFClass_Spy && TF2_IsPlayerInCondition(target, TFCond_Cloaked)) { 32 | return MRES_Ignored; 33 | } 34 | DHookSetReturn(Return, true); 35 | return MRES_Supercede; 36 | } 37 | return MRES_Ignored; 38 | } 39 | 40 | static float flNextParticle[MAXCLIENTS]; 41 | public MRESReturn Pre_MedigunPostFrame(int medigun) 42 | { 43 | int target = GetEntPropEnt(medigun, Prop_Send, "m_hHealingTarget"); 44 | if(!ValidatePlayer(target, AnyAlive)) { 45 | return MRES_Ignored; 46 | } 47 | 48 | int owner = GethOwnerEntity(medigun); 49 | if(SameTeam(owner, target)) 50 | return MRES_Ignored; 51 | 52 | FF2Prep Boss = FF2Prep(owner); 53 | if(!Boss.HasAbility(this_plugin_name, "special_weapons_medigun")) { 54 | return MRES_Ignored; 55 | } 56 | 57 | float flhurtDmg = Boss.GetArgF(this_plugin_name, "special_weapons_medigun", "hurt dmg", 13, 50.0); 58 | if(flhurtDmg <= 40) flhurtDmg = 40.0; 59 | flhurtDmg *= GetGameFrameTime(); 60 | SDKHooks_TakeDamage(target, medigun, owner, flhurtDmg, DMG_PREVENT_PHYSICS_FORCE); 61 | 62 | static char particle[64]; 63 | Boss.GetArgS(this_plugin_name, "special_weapons_medigun", "particles2", 20, particle, sizeof(particle)); 64 | if(strlen(particle) > 3) { 65 | if(flNextParticle[target] < GetGameTime()) { 66 | flNextParticle[target] = GetGameTime() + 0.6; 67 | static float vecPos[3]; GetClientAbsOrigin(target, vecPos); 68 | FixParticlesName(particle, sizeof(particle), TF2_GetClientTeam(owner)); 69 | CreateTimedParticle(target, particle, vecPos, 0.4); 70 | } 71 | } 72 | return MRES_Ignored; 73 | } 74 | 75 | public void Start_AntiMedigun(int medigun) 76 | { 77 | DHookEntity(Global[hItemPostFrame], false, medigun, .callback = Pre_MedigunPostFrame); 78 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/brs_hale/multiple.sp: -------------------------------------------------------------------------------- 1 | public void Handle_MultiRockets(int boss) 2 | { 3 | SpawnSpecialWeapon(boss, Multiple); 4 | } 5 | 6 | public MRESReturn Pre_RocketLauncherPrimaryAttack(int weapon) 7 | { 8 | if(!IsRoundActive()) 9 | return MRES_Ignored; 10 | 11 | int owner = GethOwnerEntity(weapon); 12 | int boss = FF2_GetBossIndex(owner); 13 | if(GetCurrentWeapon(boss) != weapon) 14 | return MRES_Ignored; 15 | 16 | FF2Prep Boss = FF2Prep(boss, false); 17 | if(!Boss.HasAbility(this_plugin_name, "special_weapons_multiple")) 18 | return MRES_Ignored; 19 | 20 | SetEntPropFloat(weapon, Prop_Send, "m_flNextPrimaryAttack", GetGameTime() + 1.0); 21 | int curAmmo = GetEntProp(weapon, Prop_Data, "m_iClip1"); 22 | if(curAmmo <= 0) { 23 | return MRES_Supercede; 24 | } 25 | int min = Boss.GetArgI(this_plugin_name, "special_weapons_multiple", "min", 14, 1); 26 | int max = Boss.GetArgI(this_plugin_name, "special_weapons_multiple", "max", 15, 5); 27 | Prep_LaunchRocket(Boss, GetRandomInt(min, max)); 28 | SetEntProp(weapon, Prop_Data, "m_iClip1", curAmmo - 1); 29 | return MRES_Supercede; 30 | } 31 | 32 | static void Prep_LaunchRocket(FF2Prep Boss, int ammount) 33 | { 34 | for (int x; x < ammount; x++) { 35 | LaunchRocket(Boss); LaunchRocket(Boss); 36 | } 37 | } 38 | 39 | static void LaunchRocket(FF2Prep Boss) 40 | { 41 | static bool tick; 42 | int rocket = CreateEntityByName("tf_projectile_rocket"); 43 | 44 | static char buffer[126]; 45 | 46 | int client = Boss.Index; 47 | float speed = Boss.GetArgF(this_plugin_name, "special_weapons_multiple", "speed", 16, 1000.0); 48 | static float vecAng[3], vecPos[3], vecFwd[3]; 49 | GetClientEyePosition(client, vecPos); 50 | GetClientEyeAngles(client, vecAng); 51 | 52 | vecPos[1] += !tick ? GetRandomFloat(-50.0, -20.0):GetRandomFloat(20.0, 50.0); 53 | 54 | GetAngleVectors(vecAng, vecFwd, NULL_VECTOR, NULL_VECTOR); 55 | for (int x; x < 3; x++) 56 | vecFwd[x] += GetRandomFloat(-0.27, 0.33); 57 | ScaleVector(vecFwd, speed); 58 | 59 | speed = Boss.GetArgF(this_plugin_name, "special_weapons_multiple", "damage", 17, 15.0); 60 | TeleportEntity(rocket, vecPos, vecAng, vecFwd); 61 | SetEntProp(rocket, Prop_Send, "m_bCritical", false); 62 | SetEntDataFloat(rocket, m_flRocketDamage, speed, true); 63 | SetEntProp(rocket, Prop_Send, "m_nSkin", 0); 64 | SetEntPropEnt(rocket, Prop_Send, "m_hOwnerEntity", client); 65 | SetVariantInt(GetClientTeam(client)); 66 | AcceptEntityInput(rocket, "TeamNum"); 67 | SetVariantInt(GetClientTeam(client)); 68 | AcceptEntityInput(rocket, "SetTeam"); 69 | SetEntPropEnt(rocket, Prop_Send, "m_hOriginalLauncher", GetPlayerWeaponSlot(client, TFWeaponSlot_Melee)); 70 | SetEntPropEnt(rocket, Prop_Send, "m_hLauncher", GetPlayerWeaponSlot(client, TFWeaponSlot_Melee)); 71 | DispatchSpawn(rocket); 72 | 73 | if(Boss.GetArgS(this_plugin_name, "special_weapons_multiple", "model", 18, buffer, sizeof(buffer))) { 74 | SetEntProp(rocket, Prop_Send, "m_nModelIndex", PrecacheModel(buffer)); 75 | } 76 | tick = !tick; 77 | } 78 | 79 | public void Start_MultiRocket(int weapon) 80 | { 81 | DHookEntity(Global[hPrimaryAttack], false, weapon, .callback = Pre_RocketLauncherPrimaryAttack); 82 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/brs_hale/stocks.sp: -------------------------------------------------------------------------------- 1 | stock void FF2_EmitVoiceToAll2(const char[] sound, int entity = SOUND_FROM_PLAYER) 2 | { 3 | #if defined _FFBAT_included 4 | if(UnOfficialFF2) 5 | FF2_EmitVoiceToAll(sound, entity); 6 | else EmitSoundToAll(sound, entity); 7 | #else 8 | EmitSoundToAll(sound, entity); 9 | #endif 10 | } 11 | 12 | static float EndThink[2048]; 13 | stock void Hijack_Sentry(int sentry, float dur) 14 | { 15 | CreateTimer(0.1, Pseudo_OnSentryThink, EntIndexToEntRef(sentry), TIMER_REPEAT); 16 | SetDisabled(sentry, dur); 17 | EndThink[sentry] = GetGameTime() + dur; 18 | } 19 | 20 | stock void SetDisabled(int entity, float duration) 21 | { 22 | if(duration < 0.1) duration = 0.1; 23 | SetEntProp(entity, Prop_Send, "m_bDisabled", true); 24 | CreateTimer(duration, Timer_ResetBuilding, EntIndexToEntRef(entity), TIMER_FLAG_NO_MAPCHANGE); 25 | } 26 | 27 | public Action Pseudo_OnSentryThink(Handle timer, any Ref) 28 | { 29 | int sentry = EntRefToEntIndex(Ref); 30 | if(!IsValidEntity(sentry)) { 31 | return Plugin_Stop; 32 | } 33 | if(EndThink[sentry] <= GetGameTime()) 34 | { 35 | return Plugin_Stop; 36 | } 37 | static float vecTurretAngles[3]; 38 | GetEntDataVector(sentry, m_vecTurretAngles, vecTurretAngles); 39 | vecTurretAngles[0] = GetRandomFloat(-120.0, 120.0); 40 | vecTurretAngles[1] = GetRandomFloat(-0.0, 360.0); 41 | SetEntDataVector(sentry, m_vecTurretAngles, vecTurretAngles); 42 | return Plugin_Continue; 43 | } 44 | 45 | stock void SetAsCurrentWeapon(int boss, int weapon) 46 | { 47 | RemoveFromCurrentWeapon(boss); 48 | int idx = ADTWeapons.Push(boss); 49 | ADTWeapons.Set(idx, EntIndexToEntRef(weapon), 1); 50 | } 51 | 52 | stock int GetCurrentWeapon(int boss) 53 | { 54 | if(boss < 0) 55 | return -1; 56 | int idx = ADTWeapons.FindValue(boss, 0); 57 | if(idx == -1) 58 | return -1; 59 | return EntRefToEntIndex(ADTWeapons.Get(idx, 1)); 60 | } 61 | 62 | stock void RemoveFromCurrentWeapon(int boss) 63 | { 64 | int idx = ADTWeapons.FindValue(boss, 0); 65 | if(idx == -1) 66 | return; 67 | ADTWeapons.Erase(idx); 68 | } 69 | 70 | stock int GetWeaponSlot(int weapon) 71 | { 72 | return SDKCall(Global[SDKGetSlot], weapon); 73 | } 74 | 75 | stock int GethOwnerEntity(int entity) 76 | { 77 | return GetEntPropEnt(entity, Prop_Send, "m_hOwnerEntity"); 78 | } 79 | 80 | stock int FindEntityInSphere(int iEntity, const float vecPosition[3], float flRadius) 81 | { 82 | return SDKCall(Global[SDKFindEntityInSphere], iEntity, vecPosition, flRadius); 83 | } 84 | 85 | bool SameTeam(int x, int y) 86 | { 87 | return (GetClientTeam(x) == GetClientTeam(y)); 88 | } 89 | 90 | stock void CreateTimedParticle(int owner, const char[] Name, float SpawnPos[3], float duration, bool bFollow = true) 91 | { 92 | CreateTimer(duration, Timer_KillEntity, EntIndexToEntRef(AttachParticle(owner, Name, SpawnPos, bFollow)), TIMER_FLAG_NO_MAPCHANGE); 93 | } 94 | 95 | public Action Timer_KillEntity(Handle timer, any EntRef) 96 | { 97 | int entity = EntRefToEntIndex(EntRef); 98 | if(IsValidEntity(entity)) 99 | RemoveEntity(entity); 100 | } 101 | 102 | public Action Timer_ResetBuilding(Handle Timer, any EntRef) 103 | { 104 | int building = EntRefToEntIndex(EntRef); 105 | if(IsValidEntity(building)) 106 | SetEntProp(building, Prop_Send, "m_bDisabled", false); 107 | } 108 | 109 | stock int AttachParticle(int owner, const char[] ParticleName, float SpawnPos[3], bool bFollow) 110 | { 111 | int entity = CreateEntityByName("info_particle_system"); 112 | 113 | TeleportEntity(entity, SpawnPos, NULL_VECTOR, NULL_VECTOR); 114 | 115 | static char buffer[64]; 116 | FormatEx(buffer, sizeof(buffer), "target%i", owner); 117 | DispatchKeyValue(owner, "targetname", buffer); 118 | 119 | DispatchKeyValue(entity, "targetname", "tf2particle"); 120 | DispatchKeyValue(entity, "parentname", buffer); 121 | DispatchKeyValue(entity, "effect_name", ParticleName); 122 | DispatchSpawn(entity); 123 | 124 | if(bFollow) { 125 | SetVariantString(buffer); 126 | AcceptEntityInput(entity, "SetParent", entity, entity); 127 | } 128 | 129 | SetEntPropEnt(entity, Prop_Send, "m_hOwnerEntity", owner); 130 | ActivateEntity(entity); 131 | AcceptEntityInput(entity, "start"); 132 | 133 | return entity; 134 | } 135 | 136 | stock int FindNearestTargetInSphere(const float radius, int rocket, float vecOrigin[3]) 137 | { 138 | float vecTarget[3]; 139 | 140 | ArrayStack players = new ArrayStack(); 141 | int client = -1, team = GetEntProp(rocket, Prop_Send, "m_iTeamNum"); 142 | 143 | while((client = FindEntityInSphere(client, vecOrigin, radius)) != -1) 144 | if(ValidatePlayer(client, AnyAlive) && GetClientTeam(client) != team) { 145 | players.Push(client); 146 | } 147 | 148 | if(players.Empty) { 149 | delete players; 150 | return -1; 151 | } 152 | float Nearest = 9999.9 * 9999.9; 153 | client = -1; 154 | while(!players.Empty) { 155 | int index = players.Pop(); 156 | GetClientAbsOrigin(index, vecTarget); 157 | float dist = GetVectorDistance(vecOrigin, vecTarget, true); 158 | if( dist < Nearest) { 159 | Nearest = dist; 160 | client = index; 161 | } 162 | } 163 | delete players; 164 | return client; 165 | } 166 | 167 | public void Global_Unhook(int client) 168 | { 169 | SDKUnhook(client, SDKHook_OnTakeDamageAlive, Post_TakeDamageAlive); 170 | SDKUnhook(client, SDKHook_PreThink, CheckBackToSanity); 171 | } 172 | 173 | stock bool FixParticlesName(char[] buffer, int size, const TFTeam iTeam) 174 | { 175 | if(StrContains(buffer, "...") == -1) 176 | return false; 177 | switch(iTeam) 178 | { 179 | case TFTeam_Red: { 180 | ReplaceString(buffer, size, "...", "red"); 181 | return true; 182 | } 183 | case TFTeam_Blue: { 184 | ReplaceString(buffer, size, "...", "blue"); 185 | return true; 186 | } 187 | } 188 | return false; 189 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/brs_hale/stun_gun.sp: -------------------------------------------------------------------------------- 1 | 2 | public void Handle_StunRage(int boss) 3 | { 4 | SpawnSpecialWeapon(boss, StunGun); 5 | } 6 | 7 | public MRESReturn Pre_StunGunPrimaryAttack(int weapon) 8 | { 9 | if(!IsRoundActive()){ 10 | return MRES_Ignored; 11 | } 12 | 13 | int owner = GethOwnerEntity(weapon); 14 | int boss = FF2_GetBossIndex(owner); 15 | if(GetCurrentWeapon(boss) != weapon){ 16 | return MRES_Ignored; 17 | } 18 | 19 | FF2Prep Boss = FF2Prep(boss, false); 20 | 21 | float delay = Boss.GetArgF(this_plugin_name, "special_weapons_stungun", "delay", 13, 5.0); 22 | SetEntPropFloat(weapon, Prop_Send, "m_flNextPrimaryAttack", GetGameTime() + delay); 23 | 24 | int clip = GetEntProp(weapon, Prop_Data, "m_iClip1"); 25 | if(clip <= 0) 26 | return MRES_Supercede; 27 | 28 | LaunchRocket(Boss); 29 | SetEntProp(weapon, Prop_Data, "m_iClip1", clip - 1); 30 | 31 | return MRES_Supercede; 32 | } 33 | 34 | public void Start_StunGun(int weapon) 35 | { 36 | DHookEntity(Global[hPrimaryAttack], false, weapon, .callback = Pre_StunGunPrimaryAttack); 37 | } 38 | 39 | static void LaunchRocket(FF2Prep Boss) 40 | { 41 | int rocket = CreateEntityByName("tf_projectile_rocket"); 42 | if(!IsValidEntity(rocket)) 43 | return; 44 | 45 | static char buffer[126]; 46 | 47 | int client = Boss.Index; 48 | float speed = Boss.GetArgF(this_plugin_name, "special_weapons_stungun", "speed", 14, 1000.0); 49 | static float vecAng[3], vecPos[3], vecFwd[3]; 50 | GetClientEyePosition(client, vecPos); 51 | GetClientEyeAngles(client, vecAng); 52 | 53 | vecPos[2] -= 25.0; 54 | GetAngleVectors(vecAng, vecFwd, NULL_VECTOR, NULL_VECTOR); 55 | ScaleVector(vecFwd, speed); 56 | 57 | speed = Boss.GetArgF(this_plugin_name, "special_weapons_stungun", "damage", 15, 25.0); 58 | TeleportEntity(rocket, vecPos, vecAng, vecFwd); 59 | SetEntProp(rocket, Prop_Send, "m_bCritical", false); 60 | SetEntDataFloat(rocket, m_flRocketDamage, speed, true); 61 | SetEntProp(rocket, Prop_Send, "m_nSkin", 0); 62 | SetEntPropEnt(rocket, Prop_Send, "m_hOwnerEntity", client); 63 | SetVariantInt(GetClientTeam(client)); 64 | AcceptEntityInput(rocket, "TeamNum"); 65 | SetVariantInt(GetClientTeam(client)); 66 | AcceptEntityInput(rocket, "SetTeam"); 67 | SetEntPropEnt(rocket, Prop_Send, "m_hOriginalLauncher", GetPlayerWeaponSlot(client, TFWeaponSlot_Melee)); 68 | SetEntPropEnt(rocket, Prop_Send, "m_hLauncher", GetPlayerWeaponSlot(client, TFWeaponSlot_Melee)); 69 | DispatchSpawn(rocket); 70 | 71 | if(Boss.GetArgS(this_plugin_name, "special_weapons_stungun", "model", 16, buffer, sizeof(buffer))) { 72 | SetEntProp(rocket, Prop_Send, "m_nModelIndex", PrecacheModel(buffer)); 73 | } 74 | 75 | SDKHook(rocket, SDKHook_StartTouch, On_RocketTouch); 76 | } 77 | 78 | public Action On_RocketTouch(int rocket, int other) 79 | { 80 | int owner = GetEntPropEnt(rocket, Prop_Send, "m_hOwnerEntity"); 81 | FF2Prep Boss = FF2Prep(owner); 82 | 83 | static float vicPos[3], endPos[3], vecPos[3]; 84 | static char particle[64]; 85 | float intensity = Boss.GetArgF(this_plugin_name, "special_weapons_stungun", "intensity", 17, 800.0); 86 | GetEntPropVector(rocket, Prop_Send, "m_vecOrigin", endPos); 87 | 88 | int obj = -1; 89 | while((obj = FindEntityInSphere(obj, endPos, 232.0)) != -1) 90 | { 91 | if(obj <= 0) 92 | continue; 93 | else if(obj <= MaxClients && (GetClientTeam(obj) != GetClientTeam(owner) || obj == owner)) 94 | { 95 | GetEntPropVector(obj, Prop_Send, "m_vecOrigin", vicPos); 96 | MakeVectorFromPoints(endPos, vicPos, vecPos); 97 | NormalizeVector(vecPos, vecPos); 98 | ScaleVector(vecPos, intensity); 99 | TeleportEntity(obj, NULL_VECTOR, NULL_VECTOR, vecPos); 100 | } 101 | else if(HasEntProp(obj, Prop_Send, "m_hBuilder")) 102 | { 103 | GetEntityClassname(obj, particle, sizeof(particle)); 104 | if(!strcmp(particle, "obj_sentrygun")) 105 | Hijack_Sentry(obj, Boss.GetArgF(this_plugin_name, "special_weapons_stungun", "hijack", 18, 4.0)); 106 | else if(!strcmp(particle, "obj_dispenser")) 107 | SetDisabled(obj, Boss.GetArgF(this_plugin_name, "special_weapons_stungun", "disable", 19, 4.0)); 108 | } 109 | } 110 | 111 | if(Boss.GetArgS(this_plugin_name, "special_weapons_stungun", "particles2", 20, particle, sizeof(particle))) { 112 | FixParticlesName(particle, sizeof(particle), TF2_GetClientTeam(owner)); 113 | CreateTimedParticle(owner, particle, endPos, 0.7, false); 114 | } 115 | if(FF2_RandomSound("sound_explode_stun", particle, sizeof(particle), Boss.boss)) 116 | FF2_EmitVoiceToAll2(particle, rocket); 117 | 118 | return Plugin_Handled; 119 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/brs_hale/upgrade.sp: -------------------------------------------------------------------------------- 1 | 2 | static float flNextTime[MAXCLIENTS]; 3 | public void Handle_UpgradeThink(int client) 4 | { 5 | int boss = FF2_GetBossIndex(client); 6 | 7 | if(!Tracker[boss].DmgSince) 8 | return; 9 | FF2Prep Boss = FF2Prep(boss, false); 10 | 11 | float min = Boss.GetArgF(this_plugin_name, UPGRADE, "start time", 1, 10.0); 12 | if(GetGameTime() - Tracker[boss].DmgSince < min){ 13 | return; 14 | } 15 | 16 | static char particle[64]; 17 | if(flNextTime[client] < GetGameTime()) 18 | { 19 | min = Boss.GetArgF(this_plugin_name, UPGRADE, "think time", 2, 1.5); 20 | flNextTime[client] = GetGameTime() + min; 21 | 22 | Boss.GetArgS(this_plugin_name, UPGRADE, "particles2", 3, particle, sizeof(particle)); 23 | if(strlen(particle) > 3) { 24 | FixParticlesName(particle, sizeof(particle), TF2_GetClientTeam(client)); 25 | static float vecPos[3]; GetClientAbsOrigin(client, vecPos); 26 | CreateTimedParticle(client, particle, vecPos, 1.5); 27 | } 28 | 29 | if(!!Boss.GetArgI(this_plugin_name, UPGRADE, "hp regen", 4, 1)) { 30 | int iLives = FF2_GetBossLives(boss); 31 | int iMaxHealth = FF2_GetBossMaxHealth(boss); 32 | int iHealth = FF2_GetBossHealth(boss); 33 | if(iHealth / iLives < iMaxHealth) { 34 | FF2_SetBossHealth(boss, iHealth + Boss.GetArgI(this_plugin_name, UPGRADE, "health", 5, 25)); 35 | } 36 | } 37 | 38 | if(!!Boss.GetArgI(this_plugin_name, UPGRADE, "pts regen", 6, 1)) { 39 | int max = FF2MenuRage_GetHashMap(client).GetInt("max pts", 9999); 40 | int pts = FF2MenuRage_PeekValue(client, "points") + Boss.GetArgI(this_plugin_name, UPGRADE, "points", 7, 5); 41 | if(max <= pts) 42 | pts = max; 43 | FF2MenuRage_SetValue(client, "points", pts); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/brs_hale/wrap.sp: -------------------------------------------------------------------------------- 1 | public Action Handle_RandomTeleport(int client) 2 | { 3 | ArrayList players = new ArrayList(); 4 | for(int x = 1; x <= MaxClients; x++) 5 | { 6 | if(!ValidatePlayer(x, AnyAlive) || client == x) 7 | continue; 8 | 9 | players.Push(x); 10 | } 11 | int boss = FF2_GetBossIndex(client); 12 | static char buffer[64]; 13 | 14 | if(!players.Length) { 15 | if(FF2_RandomSound("sound_teleport_failure", buffer, sizeof(buffer), boss)) 16 | FF2_EmitVoiceToAll2(buffer, client); 17 | delete players; 18 | return Plugin_Stop; 19 | } 20 | 21 | if(FF2_RandomSound("sound_teleport_success", buffer, sizeof(buffer), boss)) 22 | FF2_EmitVoiceToAll2(buffer); 23 | 24 | FF2Prep Boss = FF2Prep(boss, false); 25 | 26 | if(Boss.GetArgS(this_plugin_name, REALITY, "particles", 1, buffer, sizeof(buffer))) 27 | FixParticlesName(buffer, sizeof(buffer), TF2_GetClientTeam(client)); 28 | 29 | while(players.Length) { 30 | if((players.Length - 2) < 0) 31 | break; 32 | 33 | int victim[2]; 34 | static float vecPos[2][3]; 35 | 36 | for (int i; i < 2; i++) { 37 | int idx = GetRandomInt(0, players.Length - 1); 38 | victim[i] = players.Get(idx); 39 | players.Erase(idx); 40 | if(i) { 41 | GetClientAbsOrigin(victim[i], vecPos[i]); 42 | GetClientAbsOrigin(victim[i-1], vecPos[i-1]); 43 | TeleportEntity(victim[i], vecPos[i - 1], NULL_VECTOR, NULL_VECTOR); 44 | TeleportEntity(victim[i - 1], vecPos[i], NULL_VECTOR, NULL_VECTOR); 45 | if(strlen(buffer) > 3) { 46 | CreateTimedParticle(victim[i], buffer, vecPos[i - 1], 1.0); 47 | CreateTimedParticle(victim[i - 1], buffer, vecPos[i], 1.0); 48 | } 49 | } 50 | } 51 | } 52 | delete players; 53 | return Plugin_Handled; 54 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/deadrun_helper.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | public Plugin:myinfo = { 9 | name = "Freak Fortress 2: Deathrun Helper Module", 10 | description = "This is a helper module to change the charset to the deathrun charset when loading a deathrun map", 11 | author = "SHADoW NiNE TR3S", 12 | }; 13 | 14 | public OnPluginStart() 15 | { 16 | LogMessage("===Initializing Freak Fortress 2 Deathrun Helper Module==="); 17 | } 18 | 19 | public Action:FF2_OnLoadCharacterSet(&CharSetNum, String:CharSetName[] ) 20 | { 21 | new String:s[16]; 22 | GetCurrentMap(s,16); 23 | if (!StrContains(s,"vsh_dr_") || !StrContains(s,"dr_") || !StrContains(s,"deadrun_") || !StrContains(s,"deathrun_")) 24 | { 25 | strcopy(CharSetName,32,"Dead Run"); 26 | LogMessage("Deathrun map detected. Switching to deathrun charset."); 27 | return Plugin_Changed; 28 | } 29 | else 30 | LogMessage("Current map is not a deathrun map. Charset will not be switched"); 31 | return Plugin_Continue; 32 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/ff2_bossname.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #pragma newdecls required 9 | 10 | #define FF2BOSSPREFS_VERSION "1.00" 11 | 12 | public Plugin myinfo = { 13 | name = "Freak Fortress 2: Who's that current boss!", 14 | description = "Displays the current boss's name on server", 15 | author = "Koishi", 16 | version = FF2BOSSPREFS_VERSION, 17 | }; 18 | 19 | ConVar hName; 20 | char hName2[2][256]; 21 | 22 | public void OnPluginStart() 23 | { 24 | HookEvent("arena_round_start", Event_RoundStart, EventHookMode_Post); 25 | HookEvent("arena_win_panel", Event_RoundEnd, EventHookMode_Post); 26 | hName=FindConVar("hostname"); 27 | } 28 | 29 | public void OnConfigsExecuted() 30 | { 31 | GetConVarString(hName, hName2[0], sizeof(hName2[])); 32 | } 33 | 34 | 35 | public void Event_RoundStart(Event event, const char[] name, bool dontBroadcast) 36 | { 37 | if(!FF2_IsFF2Enabled()) 38 | { 39 | return; 40 | } 41 | 42 | char hUpdatedName[512]; 43 | FF2_GetBossSpecial(0, hName2[1], sizeof(hName2[])); 44 | Format(hUpdatedName, sizeof(hUpdatedName), "%s | %s", hName2[0], hName2[1]); 45 | SetConVarString(hName, hUpdatedName); 46 | } 47 | 48 | public void Event_RoundEnd(Event event, const char[] name, bool dontBroadcast) 49 | { 50 | if(!FF2_IsFF2Enabled()) 51 | { 52 | return; 53 | } 54 | SetConVarString(hName, hName2[0]); 55 | } 56 | 57 | public void OnPluginEnd() 58 | { 59 | SetConVarString(hName, hName2[0]); 60 | } 61 | 62 | public void OnMapEnd() 63 | { 64 | SetConVarString(hName, hName2[0]); 65 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/dot_template.sp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #pragma semicolon 1 9 | #pragma newdecls required 10 | 11 | #define MAX_PLAYERS_ARRAY 36 12 | #define MAX_PLAYERS (MAX_PLAYERS_ARRAY < (MaxClients + 1) ? MAX_PLAYERS_ARRAY : (MaxClients + 1)) 13 | 14 | bool RoundInProgress = false; 15 | 16 | #define DE_STRING "dot_example" 17 | bool DE_CanUse[MAX_PLAYERS_ARRAY]; // internal 18 | int DE_Product[MAX_PLAYERS_ARRAY]; // internal 19 | int DE_SomeNumber[MAX_PLAYERS_ARRAY]; // arg1 20 | 21 | public Plugin myinfo = { 22 | name = "Freak Fortress 2: DOT Template", 23 | author = "sarysa", 24 | version = "1.0.0", 25 | } 26 | 27 | /** 28 | * METHODS REQUIRED BY ff2 subplugin 29 | */ 30 | public void OnPluginStart2() 31 | { 32 | HookEvent("arena_win_panel", Event_RoundEnd, EventHookMode_PostNoCopy); 33 | HookEvent("arena_round_start", Event_RoundStart, EventHookMode_PostNoCopy); 34 | } 35 | 36 | // this method required, but is not used by DOTs at all. Only use if you have DOTs and non-DOTs in the same file. 37 | public Action FF2_OnAbility2(int boss, const char[] plugin_name, const char[] ability_name, int status) { return Plugin_Continue; } 38 | 39 | public Action Event_RoundStart(Event event, const char[] name, bool dontBroadcast) 40 | { 41 | PrintToServer("DOTtest: Event_RoundStart()"); 42 | 43 | // NOTE: For DOTs, only basic inits go here. The real init happens on a time delay shortly after. 44 | // It is recommended you don't load anything related to DOTs until then. 45 | RoundInProgress = true; 46 | 47 | // initialize each DOT's array 48 | for (int i = 0; i < MAX_PLAYERS; i++) 49 | { 50 | DE_CanUse[i] = false; 51 | DE_Product[i] = 0; 52 | } 53 | } 54 | 55 | public Action Event_RoundEnd(Event event, const char[] name, bool dontBroadcast) 56 | { 57 | // round has ended, this'll kill the looping timer 58 | RoundInProgress = false; 59 | 60 | // cleanup 61 | for (int i = 0; i < MAX_PLAYERS; i++) 62 | { 63 | DE_CanUse[i] = false; 64 | DE_Product[i] = 0; 65 | } 66 | } 67 | 68 | /** 69 | * METHODS REQUIRED BY dot subplugin 70 | */ 71 | void DOTPostRoundStartInit() 72 | { 73 | if (!RoundInProgress) 74 | { 75 | PrintToServer("DOTPostRoundStartInit() called when the round is over?! Shouldn't be possible!"); 76 | return; 77 | } 78 | 79 | for (int bossClientIdx = 1; bossClientIdx < MAX_PLAYERS; bossClientIdx++) 80 | { 81 | int bossIdx = FF2_GetBossIndex(bossClientIdx); 82 | if (bossIdx < 0) 83 | continue; // this may seem weird, but rages often break on duo bosses if the leader suicides. these DOTs can be an exception. :D 84 | 85 | // example 86 | DE_CanUse[bossClientIdx] = FF2_HasAbility(bossIdx, this_plugin_name, DE_STRING); 87 | if (DE_CanUse[bossClientIdx]) 88 | { 89 | DE_SomeNumber[bossClientIdx] = FF2_GetAbilityArgument(bossIdx, this_plugin_name, DE_STRING, 1); 90 | PrintToServer("Boss will use example DOT. Probably don't want to see this printout on a live boss."); 91 | } 92 | } 93 | } 94 | 95 | void OnDOTAbilityActivated(int bossClientIdx) 96 | { 97 | if (DE_CanUse[bossClientIdx]) 98 | { 99 | DE_Product[bossClientIdx] = DE_SomeNumber[bossClientIdx]; 100 | PrintToServer("DOT example activated. Product is now %d", DE_Product[bossClientIdx]); 101 | } 102 | } 103 | 104 | void OnDOTAbilityDeactivated(int bossClientIdx) 105 | { 106 | if (DE_CanUse[bossClientIdx]) 107 | { 108 | DE_Product[bossClientIdx] = 0; 109 | PrintToServer("DOT example deactivated. Product is now %d", DE_Product[bossClientIdx]); 110 | } 111 | } 112 | 113 | void OnDOTUserDeath(int bossClientIdx, int isInGame) 114 | { 115 | DE_Product[bossClientIdx] = 0; 116 | PrintToServer("Boss died. Cleaning up product: %d", DE_Product[bossClientIdx]); 117 | } 118 | 119 | void OnDOTAbilityTick(int bossClientIdx, int tickCount) 120 | { 121 | if (DE_CanUse[bossClientIdx] && tickCount % 3 == 0) 122 | { 123 | DE_Product[bossClientIdx] *= DE_SomeNumber[bossClientIdx]; 124 | PrintToServer("DOT example every third tick. Product is now %d", DE_Product[bossClientIdx]); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/ep_radimoko.sp: -------------------------------------------------------------------------------- 1 | // only made due to issues rage_new_weapon has with clipless weps such as miniguns, Sniper Rifles, flamethrowers, and Flare Guns 2 | 3 | #pragma semicolon 1 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #define MB 3 11 | 12 | new bEnableSuperDuperJump[MB]; 13 | new Handle:OnHaleJump = INVALID_HANDLE; 14 | 15 | public Plugin:myinfo = { 16 | name = "FF2 Package - Mokou + Radigan Conagher", 17 | author = "EP", 18 | }; 19 | 20 | public OnPluginStart2() 21 | { 22 | HookEvent("teamplay_round_start", event_round_start); 23 | } 24 | 25 | public OnMapStart() 26 | { 27 | PrecacheSound("replay\\exitperformancemode.wav",true); 28 | PrecacheSound("replay\\enterperformancemode.wav",true); 29 | } 30 | 31 | 32 | public Action:FF2_OnAbility2(index,const String:plugin_name[],const String:ability_name[],action) 33 | { 34 | if (!strcmp(ability_name,"rage_radigan")) 35 | Rage_Radigan(index); // Minigun 36 | else if (!strcmp(ability_name,"rage_moko")) 37 | Rage_Mokou(index); // Detonator 38 | else if (!strcmp(ability_name,"fukkatsu_moko")) 39 | Fukkatsu_Mokou(index); // FUJIYAMA VOLCANO! 40 | return Plugin_Continue; 41 | } 42 | 43 | public Action:event_round_start(Handle:event, const String:name[], bool:dontBroadcast) 44 | { 45 | for(new i=0;i 0) 62 | { 63 | TF2Items_SetNumAttributes(hWeapon, count/2); 64 | new i2 = 0; 65 | for (new i = 0; i < count; i+=2) 66 | { 67 | TF2Items_SetAttribute(hWeapon, i2, StringToInt(atts[i]), StringToFloat(atts[i+1])); 68 | i2++; 69 | } 70 | } 71 | else 72 | TF2Items_SetNumAttributes(hWeapon, 0); 73 | if (hWeapon==INVALID_HANDLE) 74 | return -1; 75 | new entity = TF2Items_GiveNamedItem(client, hWeapon); 76 | CloseHandle(hWeapon); 77 | EquipPlayerWeapon(client, entity); 78 | return entity; 79 | } 80 | 81 | stock SetAmmo(client, slot, ammo) 82 | { 83 | new weapon = GetPlayerWeaponSlot(client, slot); 84 | if (IsValidEntity(weapon)) 85 | { 86 | new iOffset = GetEntProp(weapon, Prop_Send, "m_iPrimaryAmmoType", 1)*4; 87 | new iAmmoTable = FindSendPropInfo("CTFPlayer", "m_iAmmo"); 88 | SetEntData(client, iAmmoTable+iOffset, ammo, 4, true); 89 | } 90 | } 91 | 92 | Rage_Radigan(index) 93 | { 94 | new Boss=GetClientOfUserId(FF2_GetBossUserId(index)); 95 | TF2_RemoveWeaponSlot(Boss, TFWeaponSlot_Primary); 96 | SetEntPropEnt(Boss, Prop_Send, "m_hActiveWeapon", SpawnWeapon(Boss, "tf_weapon_minigun", 312, 100, 5, "2 ; 1.3 ; 86 ; 1.3 ; 5 ; 1.3 ; 37 ; 0 ; 77 ; 0 ; 205 ; 1.5 ; 206 ; 2.25 ; 128 ; 1 ; 75 ; 0.35")); 97 | // 2 - +30% damage done 98 | // 86 - +30% spinup time 99 | // 5 - 30% slower fire speed 100 | // 75 - -65% move speed when spinning 101 | // (note: it seems Hales are unaffected by move speed effects on Rage?) 102 | // 54 - -65% move speed 103 | // 77 - 0 is max clip size 104 | // 205 - +50% damage taken from projectiles when active 105 | // 206 - +125% damage taken from melee sources when active 106 | // 128 - effects only take hold on active 107 | SetAmmo(Boss, TFWeaponSlot_Primary,35); 108 | } 109 | 110 | Rage_Mokou(index) 111 | { 112 | new Boss=GetClientOfUserId(FF2_GetBossUserId(index)); 113 | TF2_RemoveWeaponSlot(Boss, TFWeaponSlot_Secondary); 114 | SetEntPropEnt(Boss, Prop_Send, "m_hActiveWeapon", SpawnWeapon(Boss, "tf_weapon_flaregun", 351, 100, 5, "2 ; 1.4 ; 99 ; 2.5 ; 209 ; 1 ; 97 ; 0.7 ; 6 ; 0.6 ; 25 ; 0.0")); 115 | // 2 - +40% damage done 116 | // 99 - +150% splash radius 117 | // 209 - mini-crits burning targets 118 | // 97 - -30% reload speed 119 | // 6 - +40% faster fire rate 120 | // 25 - 0 is max ammo size 121 | SetAmmo(Boss, TFWeaponSlot_Secondary,6); 122 | } 123 | 124 | Fukkatsu_Mokou(index) 125 | { 126 | new Boss=GetClientOfUserId(FF2_GetBossUserId(index)); 127 | TF2_RemoveWeaponSlot(Boss, TFWeaponSlot_Primary); 128 | SetEntPropEnt(Boss, Prop_Send, "m_hActiveWeapon", SpawnWeapon(Boss, "tf_weapon_flamethrower", 594, 100, 5, "2 ; 1.4 ; 137 ; 1.5 ; 37 ; 0 ; 356 ; 1 ; 128 ; 1 ; 62 ; 0.67 ; 252 ; 0.5 ; 64 ; 0.7 ; 107 ; 1.15")); 129 | // 2 - +40% damage done 130 | // 62 - -33% damage taken from critical hits 131 | // 252 - -50% knockback from damage 132 | // 64 - -30% damage taken from explosions 133 | // 137 - +50% damage versus buildings 134 | // 107 - +15% move speed 135 | // 128 - effects take hold on active 136 | // 37 - 0 is max ammo size 137 | // 356 - cannot airblast 138 | SetAmmo(Boss, TFWeaponSlot_Primary,40); 139 | } 140 | 141 | public Action:Timer_ResetCharge(Handle:timer, any:index) 142 | { 143 | new slot=index%10000; 144 | index/=1000; 145 | FF2_SetBossCharge(index,slot,0.0); 146 | } 147 | 148 | public Action:FF2_OnTriggerHurt(index,triggerhurt,&Float:damage) 149 | { 150 | bEnableSuperDuperJump[index]=true; 151 | if (FF2_GetBossCharge(index,1)<0) 152 | FF2_SetBossCharge(index,1,0.0); 153 | return Plugin_Continue; 154 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/ff2_ams_sample.sp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #pragma semicolon 1 6 | #pragma newdecls required 7 | 8 | bool Ability_IsAMS[MAXPLAYERS+1]; // global boolean to use with AMS 9 | 10 | public Plugin myinfo = { 11 | name = "[FF2] AMS2 : plugin sample", 12 | author = "01Pollux", 13 | version = "1.0", 14 | }; 15 | 16 | #define ABILITY_SAMPLE "rage_sample" // ability name 17 | #define ABILITY_PREFIX "SMPL" // abbreviation of ability name 18 | 19 | /* 20 | //check include for more infos 21 | public AMSResult _CanInvoke(int client, int index) 22 | public void _Invoke(int client, int index) 23 | public void _Overwrite(int client, int index) 24 | public void _EndAbility(int client, int index) 25 | 26 | //since we have ABILITY_PREFIX as SMPL, it would then be written as: 27 | public AMSResult SMPL_CanInvoke(int client, int index) 28 | public void SMPL_Invoke(int client, int index) 29 | public void SMPL_Overwrite(int client, int index) 30 | public void SMPL_EndAbility(int client, int index) 31 | 32 | //ABILITY_PREFIX will be initialized during Post_"arena_round_start" 33 | //Im unsure about if its safe to late reload plugin, but i will be adding a way to remove an index from AMS-StringHashMap 34 | //NOTE: AMS won't guarantee to work properly if initialized outside FF2AMS_PreRoundStart(), (first round of ff2 problem) 35 | */ 36 | 37 | public void OnPluginStart2() 38 | { 39 | HookEvent("arena_round_start", Post_RoundStart, EventHookMode_PostNoCopy); 40 | HookEvent("arena_win_panel", Post_RoundEnd, EventHookMode_PostNoCopy); 41 | } 42 | 43 | public Action FF2_OnAbility2(int boss, const char[] plugin, const char[] ability, int status) 44 | { 45 | if(!IsRoundActive()) 46 | return Plugin_Continue; 47 | 48 | int client = BossToClient(boss); 49 | if(!strcmp(ability, ABILITY_SAMPLE)) { 50 | if(!Ability_IsAMS[client] ) { 51 | SMPL_Invoke(client, -1); // Activate RAGE normally, if ability is configured to be used as a normal RAGE. index here doesn't matter 52 | } 53 | } 54 | return Plugin_Continue; 55 | } 56 | 57 | public void Post_RoundStart(Event event, const char[] name, bool dontBroadcast) 58 | { 59 | if(!IsRoundActive()) //ff2_helper.inc 60 | return; 61 | 62 | Prep_StartAbilities(); 63 | } 64 | 65 | public void FF2AMS_PreRoundStart(int client) 66 | { 67 | FF2Prep player = FF2Prep(client); //ff2_helper.inc 68 | if(player.HasAbility(this_plugin_name, ABILITY_SAMPLE)) { //always true if player is boss + hasability 69 | if(LibraryExists("FF2AMS")) { //check if ams plugin exists 70 | Ability_IsAMS[client] = FF2AMS_IsAMSActivatedFor(client) && FF2AMS_PushToAMS(client, this_plugin_name, ABILITY_SAMPLE, ABILITY_PREFIX); //return true if pushing was successful 71 | //FF2AMS_PushToAMSEx is the same as non-Ex but instead return ability index 72 | } 73 | } 74 | } 75 | 76 | void Prep_StartAbilities() 77 | { 78 | for(int client = 1; client <= MaxClients; client++) { 79 | if(!ValidatePlayer(client, Any)) //ff2_helper.inc 80 | continue; 81 | 82 | //here initialize any non-ams ability if needed 83 | 84 | } 85 | } 86 | 87 | public void Post_RoundEnd(Event event, const char[] name, bool dontBroadcast) 88 | { 89 | for(int client=1; client<=MaxClients; client++) { 90 | if(ValidatePlayer(client, Any)) { 91 | Ability_IsAMS[client]=false; // cleanup 92 | } 93 | } 94 | } 95 | 96 | public AMSResult SMPL_CanInvoke(int client, int index) 97 | { 98 | /* 99 | specify any conditions that would prevent this ability. 100 | returning AMS_Overwrite will call SMPL_Overwrite. 101 | returning any value other than AMS_Accept will block the ability. 102 | 103 | Use FF2AMS_GetAMSHashMap(client, index) if you need to look into ability context, DO NOT delete the StringMap 104 | */ 105 | return AMS_Accept; 106 | } 107 | 108 | public void SMPL_Invoke(int client, int index) 109 | { 110 | FF2Prep player = FF2Prep(client); 111 | /* 112 | Insert your boss RAGE ability code here 113 | 114 | Use FF2AMS_GetAMSHashMap(client, index) if you need to look into/change ability context, DO NOT delete the StringMap 115 | */ 116 | 117 | char message[124]; 118 | 119 | if(player.GetArgS(this_plugin_name, ABILITY_SAMPLE, "message", 1, message, sizeof(message))) { 120 | PrintToChatAll(message); 121 | 122 | if(Ability_IsAMS[client]) { 123 | StringMap hMap = FF2AMS_GetAMSHashMap(client, index); 124 | 125 | hMap.GetString("display_desc", message, sizeof(message)); 126 | PrintToChatAll("this rage description : \"%s\"", message); 127 | 128 | RequestFrame(NextFrame_ChangeCost, hMap); 129 | //cost will be changed a frame after we set it, to avoid negative boss rage, we will be requesting a new frame 130 | hMap.SetString("display_desc", "this new description with new 30.0% cost"); 131 | } 132 | } 133 | } 134 | 135 | public void NextFrame_ChangeCost(StringMap hMap) 136 | { 137 | hMap.SetValue("this_cost", 30.0); 138 | } 139 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/ff2_blockdropitem.sp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | // Ability 4 | "abilityX" 5 | { 6 | "name" "blockdropitem" 7 | "arg1" "You were kicked because no one likes exploiters..." 8 | "plugin_name" "ff2_blockdropitem" 9 | } 10 | */ 11 | #pragma semicolon 1 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #pragma newdecls required 18 | 19 | #define PLUGIN_NAME "Freak Fortress 2: Block Item/PowerUp dropping" 20 | #define PLUGIN_AUTHOR "Naydef" 21 | #define PLUGIN_VERSION "1.1" 22 | #define ABILITY_NAME "blockdropitem" 23 | #define POWERUP "item_powerup_rune" 24 | 25 | bool BossExists; 26 | 27 | public Plugin myinfo = 28 | { 29 | name = PLUGIN_NAME, 30 | author = PLUGIN_AUTHOR, 31 | version = PLUGIN_VERSION, 32 | }; 33 | 34 | public void OnPluginStart2() 35 | { 36 | HookEvent("arena_round_start", Post_RoundStart); 37 | HookEvent("arena_win_panel", Post_RoundEnd); 38 | AddCommandListener(Command_DropItem, "dropitem"); 39 | } 40 | 41 | public void Post_RoundEnd(Event event, const char[] name, bool broadcast) 42 | { 43 | BossExists = false; 44 | } 45 | 46 | public void Post_RoundStart(Event event, const char[] name, bool broadcast) 47 | { 48 | for(int bossidx; bossidx<=MaxClients; bossidx++) 49 | { 50 | if(!IsValidClient(GetClientOfUserId(FF2_GetBossUserId(bossidx)))) 51 | continue; 52 | 53 | if(!FF2_HasAbility(bossidx, this_plugin_name, ABILITY_NAME)) 54 | continue; 55 | 56 | BossExists = true; 57 | break; 58 | } 59 | } 60 | 61 | public Action Command_DropItem(int client, const char[] command, int argc) 62 | { 63 | if(IsValidClient(client)) 64 | { 65 | int bossidx=FF2_GetBossIndex(client); 66 | if(bossidx!=-1) 67 | { 68 | if(FF2_HasAbility(bossidx, this_plugin_name, ABILITY_NAME)) 69 | { 70 | char str[64]; 71 | FF2_GetAbilityArgumentString(bossidx, this_plugin_name, ABILITY_NAME, 1, str, sizeof(str)); 72 | if(str[0]!='\0') 73 | { 74 | KickClient(client, str); 75 | } 76 | return Plugin_Handled; 77 | } 78 | } 79 | } 80 | return Plugin_Continue; 81 | } 82 | 83 | public void OnEntityCreated(int entity, const char[] classname) 84 | { 85 | if(!BossExists) 86 | return; 87 | 88 | if(!strcmp(classname, POWERUP)) 89 | SDKHook(entity, SDKHook_Spawn, KillOnSpawn); 90 | } 91 | 92 | public void KillOnSpawn(int entity) 93 | { 94 | if(IsValidEntity(entity) && entity>MaxClients) 95 | RemoveEntity(entity); 96 | SDKUnhook(entity, SDKHook_Spawn, KillOnSpawn); 97 | } 98 | 99 | public void FF2_OnAbility2(int boss, const char[] plugin_name, const char[] ability_name, int status) 100 | { 101 | //Nope 102 | } 103 | 104 | stock bool IsValidClient(int client) 105 | { 106 | if(client<=0 || client>MaxClients) return false; 107 | return IsClientInGame(client); 108 | } 109 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/ff2_bypass.sp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #pragma semicolon 1 4 | #pragma newdecls required 5 | 6 | bool IsActive; 7 | 8 | #define this_ability_name "ff2_unload" 9 | #define this_plugin_name "ff2_bypass" 10 | #define CFG_DIRECTORY "plugins/freaks/"...this_ability_name 11 | 12 | ArrayStack List; 13 | 14 | public Plugin myinfo = 15 | { 16 | author = "[01]Pollux." 17 | }; 18 | 19 | public void OnPluginStart2() 20 | { 21 | HookEvent("arena_win_panel", Post_RoundEnd, EventHookMode_PostNoCopy); 22 | HookEvent("arena_round_start", Post_RoundStart, EventHookMode_PostNoCopy); 23 | if(IsRoundActive()) 24 | Post_RoundStart(null, "plugin_lateload", false); 25 | } 26 | 27 | public void OnMapEnd() 28 | { 29 | Post_RoundEnd(null, "plugin_unload", false); 30 | } 31 | 32 | public void Post_RoundEnd(Event hevent, const char[] name, bool dontBroadcast) 33 | { 34 | if(IsActive) 35 | { 36 | char plugin[PLATFORM_MAX_PATH]; 37 | while(!List.Empty) { 38 | List.PopString(plugin, sizeof(plugin)); 39 | ServerCommand("sm plugins load %s", plugin); 40 | } 41 | delete List; 42 | IsActive = false; 43 | } 44 | } 45 | 46 | public void Post_RoundStart(Event hevent, const char[] name, bool dontBroadcast) 47 | { 48 | IsActive = false; 49 | for (int client = 1; client <= MaxClients; client++) 50 | { 51 | if(!ValidatePlayer(client, AnyAlive)) 52 | continue; 53 | 54 | FF2Prep boss = FF2Prep(client); 55 | if(!boss.HasAbility(this_plugin_name, this_ability_name)) 56 | continue; 57 | 58 | char Path[PLATFORM_MAX_PATH]; 59 | if(!boss.GetArgS(this_plugin_name, this_ability_name, "directory", 1, Path, sizeof(Path))) 60 | continue; 61 | if(!IsActive) IsActive = true; 62 | if(List==null) List = new ArrayStack(ByteCountToCells(PLATFORM_MAX_PATH)); 63 | Prep_PluginsUnload(Path); 64 | } 65 | } 66 | 67 | void Prep_PluginsUnload(const char[] dir) 68 | { 69 | SMCParser plugins = new SMCParser(); 70 | 71 | plugins.OnKeyValue = SMC_OnNextKeyValue; 72 | 73 | char[] cfg = new char[PLATFORM_MAX_PATH]; 74 | BuildPath(Path_SM, cfg, PLATFORM_MAX_PATH, "%s/%s", CFG_DIRECTORY, dir); 75 | SMCError Error = plugins.ParseFile(cfg); 76 | if(Error != SMCError_Okay) { 77 | char err[64]; 78 | plugins.GetErrorString(Error, err, sizeof(err)); 79 | LogError("[FF2] SMCError : %s", err); 80 | } 81 | delete plugins; 82 | } 83 | 84 | public SMCResult SMC_OnNextKeyValue(SMCParser smc, const char[] key, const char[] value, bool key_quotes, bool value_quotes) 85 | { 86 | ServerCommand("sm plugins unload %s", value); 87 | List.PushString(value); 88 | return SMCParse_Continue; 89 | } 90 | 91 | public Action FF2_OnAbility2(int boss, const char[] plugin_name, const char[] ability_name, int status){ 92 | } 93 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/ff2_client_musicmod.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #pragma newdecls required 11 | 12 | int curBossIdx; 13 | bool workaroundActive=false; 14 | bool isMatch=false; 15 | char curBossSteamID[64]; 16 | 17 | // workaround for v1.10.8 and older, due to a bug: 18 | char curBGM[PLATFORM_MAX_PATH]; 19 | 20 | public Plugin myinfo = { 21 | name = "Freak Fortress 2: Boss Client Music Modifier", 22 | author = "Koishi (SHADoW NiNE TR3S)", 23 | version = "1.0", 24 | }; 25 | 26 | public void OnPluginStart2() 27 | { 28 | 29 | int version[3]; 30 | FF2_GetFF2Version(version); 31 | if(version[0]==1 && (version[1]<10 || (version[1]==10 && version[2]<9))) 32 | { 33 | HookEvent("arena_win_panel", Event_ArenaWinPanel); // workaround for older versions to fix a bug present in those versions of FF2. 34 | workaroundActive=true; 35 | } 36 | 37 | HookEvent("arena_round_start", Event_ArenaRoundStart); 38 | } 39 | 40 | public void FF2_OnAbility2(int boss,const char[] plugin_name,const char[] ability_name,int action) 41 | { 42 | // nothing to see here 43 | } 44 | 45 | public void Event_ArenaRoundStart(Event event, const char[] name, bool dontBroadcast) 46 | { 47 | isMatch=false; 48 | for(int client=1;client<=MaxClients;client++) 49 | { 50 | if(client<=0 || client>MaxClients || !IsClientInGame(client)) 51 | continue; 52 | int boss=FF2_GetBossIndex(client); 53 | if(boss>=0 && FF2_HasAbility(boss, this_plugin_name, "special_changebgm_onclientmatch")) 54 | { 55 | char steamID[64], steamIDstring[1024]; 56 | GetClientAuthId(client, AuthId_Steam2, steamID, sizeof(steamID), true); 57 | FF2_GetAbilityArgumentString(boss, this_plugin_name, "special_changebgm_onclientmatch", 1, steamIDstring, sizeof(steamIDstring)); 58 | if(steamIDstring[0]) 59 | { 60 | char clientSteamID[64][64]; 61 | int count = ExplodeString(steamIDstring, " ; ", clientSteamID, sizeof(clientSteamID), sizeof(clientSteamID)); 62 | if (count > 0) 63 | { 64 | for (int i = 0; i < count; i++) 65 | { 66 | if(StrEqual(steamID, clientSteamID[i], false) && !boss) 67 | { 68 | strcopy(curBossSteamID, sizeof(curBossSteamID), clientSteamID[i]); 69 | curBossIdx=boss; 70 | isMatch=true; 71 | } 72 | } 73 | } 74 | } 75 | } 76 | } 77 | } 78 | 79 | public Action FF2_OnMusic(char[] path, float &time) 80 | { 81 | if(isMatch && !curBossIdx) 82 | { 83 | Handle bossKV=FF2_GetSpecialKV(curBossIdx, false); 84 | 85 | if(bossKV==null) 86 | { 87 | return Plugin_Continue; 88 | } 89 | 90 | KvRewind(bossKV); 91 | 92 | char bgmCFG[256]; 93 | Format(bgmCFG, sizeof(bgmCFG), "sound_bgm_%s", curBossSteamID); 94 | if(KvJumpToKey(bossKV, bgmCFG)) 95 | { 96 | char music[PLATFORM_MAX_PATH]; 97 | int index; 98 | do 99 | { 100 | index++; 101 | Format(music, 10, "time%i", index); 102 | } 103 | while(KvGetFloat(bossKV, music)>1); 104 | 105 | index=GetRandomInt(1, index-1); 106 | Format(music, 10, "time%i", index); 107 | float length=KvGetFloat(bossKV, music); 108 | Format(music, 10, "path%i", index); 109 | KvGetString(bossKV, music, music, sizeof(music)); 110 | 111 | char temp[PLATFORM_MAX_PATH]; 112 | Format(temp, sizeof(temp), "sound/%s", music); 113 | if(FileExists(temp, true)) 114 | { 115 | time=length; 116 | if(workaroundActive) 117 | { 118 | strcopy(curBGM, sizeof(curBGM), music); 119 | } 120 | strcopy(path, PLATFORM_MAX_PATH, music); 121 | return Plugin_Changed; 122 | } 123 | } 124 | } 125 | return Plugin_Continue; 126 | } 127 | 128 | // this exists solely to work around the issue where v1.10.8 and older won't stop the BGM properly if changed via FF2_OnMusic. This has been fixed on v1.10.9! 129 | public void Event_ArenaWinPanel(Event event, const char[] name, bool dontBroadcast) 130 | { 131 | for(int client=1;client<=MaxClients;client++) 132 | { 133 | if(client<=0 || client>MaxClients || !IsClientInGame(client)) 134 | continue; 135 | StopSound(client, SNDCHAN_AUTO, curBGM); 136 | } 137 | } 138 | 139 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/ff2_csgo.sp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #pragma newdecls required 10 | 11 | public Plugin myinfo= 12 | { 13 | name="Freak Fortress 2 : CSGO", 14 | author="Nopied", 15 | description="FF2", 16 | version="1.0", 17 | }; 18 | 19 | bool IsCSGO=false; 20 | bool PlayerRecoiled[MAXPLAYERS+1]; 21 | 22 | public void OnPluginStart2() 23 | { 24 | HookEvent("arena_round_start", OnRoundStart); 25 | // HookEvent("player_spawn", OnPlayerSpawn); 26 | } 27 | 28 | public Action FF2_OnAbility2(int boss, const char[] plugin_name, const char[] ability_name, int status) 29 | { 30 | 31 | } 32 | 33 | public Action OnRoundStart(Handle event, const char[] name, bool dont) 34 | { 35 | CheckAbility(); 36 | } 37 | 38 | public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon, int &subtype, int &cmdnum, int &tickcount, int &seed, int mouse[2]) 39 | { 40 | if(IsCSGO && FF2_GetRoundState() == 1 && IsClientInGame(client) && IsPlayerAlive(client) && !IsWeaponSlotActive(client, TFWeaponSlot_Melee)) 41 | { 42 | // int weapon2 = GetEntPropEnt(client, Prop_Send, "m_hActiveWeapon"); 43 | 44 | if(!PlayerRecoiled[client] && GetEntPropFloat(client, Prop_Send, "m_flNextAttack") >= GetGameTime()) 45 | { 46 | if(buttons & IN_ATTACK) 47 | { 48 | PlayerRecoiled[client]=true; 49 | float punchAng[3]; 50 | GetEntPropVector(client, Prop_Send, "m_vecPunchAngle", punchAng); 51 | 52 | punchAng[1]+=GetRandomFloat(-10.0, 10.0); 53 | punchAng[2]+=GetRandomFloat(5.0, 25.0); 54 | 55 | SetEntPropVector(client, Prop_Send, "m_vecPunchAngle", punchAng); 56 | } 57 | } 58 | else if(PlayerRecoiled[client] && GetEntPropFloat(client, Prop_Send, "m_flNextAttack") <= GetGameTime()) 59 | { 60 | PlayerRecoiled[client]=false; 61 | } 62 | else 63 | PlayerRecoiled[client]=false; 64 | } 65 | } 66 | 67 | /* 68 | public void OnWeaponFire(int client, int shots, const char[] weaponname) 69 | { 70 | float punchAng[3]; 71 | GetEntPropVector(client, Prop_Send, "m_vecPunchAngle", punchAng); 72 | 73 | punchAng[1]+=GetRandomFloat(-3.0, 3.0); 74 | punchAng[2]+=GetRandomFloat(0.1, 5.0); 75 | 76 | SetEntPropVector(client, Prop_Send, "m_vecPunchAngle", punchAng); 77 | } 78 | */ 79 | 80 | void CheckAbility() 81 | { 82 | IsCSGO=false; 83 | int client, boss; 84 | for(client=1; client<=MaxClients; client++) 85 | { 86 | if((boss = FF2_GetBossIndex(client)) != -1 && FF2_HasAbility(boss, this_plugin_name, "ff2_csgo")) 87 | { 88 | IsCSGO=true; 89 | } 90 | } 91 | /* 92 | for(client=1; client<=MaxClients; client++) 93 | { 94 | if(IsClientInGame(client) && IsPlayerAlive(client)) 95 | { 96 | SDKHook(client, SDKHook_FireBulletsPost, OnWeaponFire); 97 | } 98 | } 99 | */ 100 | } 101 | 102 | stock bool IsWeaponSlotActive(int iClient, int iSlot) 103 | { 104 | int hActive = GetEntPropEnt(iClient, Prop_Send, "m_hActiveWeapon"); 105 | int hWeapon = GetPlayerWeaponSlot(iClient, iSlot); 106 | return (hWeapon == hActive); 107 | } 108 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/ff2_darthmule_stripped.sp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | #pragma semicolon 1 7 | #pragma newdecls required 8 | 9 | int BossTeam=view_as(TFTeam_Blue); 10 | 11 | public Plugin myinfo = { 12 | name = "Freak Fortress 2: Completely Stripped Version of Darth's Ability Pack Fix", 13 | author = "Darthmule, edit by Deathreus", 14 | version = "1.2", 15 | }; 16 | 17 | public void OnPluginStart2() 18 | { 19 | } 20 | 21 | public Action FF2_OnAbility2(int index, const char[] plugin_name, const char[] ability_name, int action) 22 | { 23 | if (!strcmp(ability_name, "rage_condition")) 24 | Rage_Condition(ability_name, index); 25 | } 26 | 27 | void Rage_Condition(const char[] ability_name, int index) 28 | { 29 | int Boss = GetClientOfUserId(FF2_GetBossUserId(index)); 30 | int cEffect = FF2_GetAbilityArgument(index,this_plugin_name,ability_name, 1); // Effect (cases) 31 | float fDuration = FF2_GetAbilityArgumentFloat(index,this_plugin_name,ability_name, 2); // Duration (if valid) 32 | float Range = FF2_GetAbilityArgumentFloat(index,this_plugin_name,ability_name, 3); // Range 33 | 34 | static float pos[3]; 35 | static float pos2[3]; 36 | static float distance; 37 | int i; 38 | 39 | GetEntPropVector(Boss, Prop_Send, "m_vecOrigin", pos); 40 | for(i=1; i<=MaxClients; i++) 41 | { 42 | if(IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i)!=BossTeam && !TF2_IsPlayerInCondition(i,TFCond_Ubercharged)) 43 | { 44 | GetEntPropVector(i, Prop_Send, "m_vecOrigin", pos2); 45 | distance = GetVectorDistance( pos, pos2 ); 46 | if (distance < Range && GetClientTeam(i)!=BossTeam) 47 | { 48 | SetVariantInt(0); 49 | AcceptEntityInput(i, "SetForcedTauntCam"); 50 | 51 | switch(cEffect) 52 | { 53 | case 0: 54 | TF2_IgnitePlayer(i, Boss); 55 | case 1: 56 | TF2_MakeBleed(i, Boss, fDuration); 57 | case 2: 58 | TF2_AddCondition(i, TFCond_RestrictToMelee, fDuration); 59 | case 3: 60 | TF2_AddCondition(i, TFCond_MarkedForDeath, fDuration); 61 | case 4: 62 | TF2_AddCondition(i, TFCond_Milked, fDuration); 63 | case 5: 64 | TF2_AddCondition(i, TFCond_Jarated, fDuration); 65 | case 6: 66 | TF2_StunPlayer(i, fDuration, 0.0, TF_STUNFLAG_BONKSTUCK, Boss); 67 | case 7: 68 | TF2_AddCondition(Boss, TFCond_DefenseBuffed, fDuration); 69 | case 8: 70 | TF2_AddCondition(Boss, TFCond_SpeedBuffAlly, fDuration); 71 | 72 | } 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/ff2_freddykrueger.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #pragma newdecls required 13 | 14 | public Plugin myinfo= 15 | { 16 | name="Freak Fortress 2 : Freddy Krueger's Ability", 17 | author="Nopied", 18 | description="FF2", 19 | version="1.1", 20 | }; 21 | 22 | public void OnPluginStart2() 23 | { 24 | return; 25 | } 26 | 27 | public void OnEntityCreated(int entity, const char[] classname) 28 | { 29 | if(!StrContains(classname, "trigger_hurt", false)) 30 | { 31 | SDKHook(entity, SDKHook_StartTouch, OnTriggerTouched); 32 | SDKHook(entity, SDKHook_Touch, OnTriggerTouched); 33 | } 34 | } 35 | 36 | public Action OnTriggerTouched(int entity, int client) 37 | { 38 | if(FF2_HasAbility(0, this_plugin_name, "ff2_nightmare") /*&& FF2_GetAbilityDuration(0) > 0.0*/) 39 | { 40 | return Plugin_Handled; 41 | } 42 | 43 | return Plugin_Continue; 44 | } 45 | 46 | public void OnGameFrame() 47 | { 48 | int boss; 49 | bool hideHUD = FF2_HasAbility(0, this_plugin_name, "ff2_nightmare"); 50 | float bossCharge; 51 | 52 | for(int client = 1; client <= MaxClients; client++) 53 | { 54 | if(!IsClientInGame(client)) continue; 55 | else if(!IsPlayerAlive(client)) 56 | { 57 | SetEntProp(client, Prop_Send, "m_iHideHUD", ( 1<<3 )); // TODO: ??? 체력만 안보이게하면 유용한데? 58 | continue; 59 | } 60 | 61 | boss = FF2_GetBossIndex(client); 62 | 63 | if(hideHUD && boss == -1) 64 | { 65 | SetEntProp(client, Prop_Send, "m_iHideHUD", ( 1<<8 )|( 1<<9 )); 66 | continue; 67 | } 68 | 69 | if(!FF2_HasAbility(boss, this_plugin_name, "ff2_nightmare")) continue; 70 | 71 | bossCharge = FF2_GetBossCharge(boss, 0); 72 | 73 | if(bossCharge < 100.0) // TODO: FF2 2.0에서 삭제 74 | { 75 | SetEntityRenderMode(client, RENDER_TRANSCOLOR); 76 | SetEntityRenderColor(client, _, _, _, 55 + RoundFloat(200.0 - (bossCharge * 2.0))); 77 | // 보스 분노 100: 55 78 | // 보스 분노 0: 255 79 | } 80 | else 81 | { 82 | FF2_DoAbility(boss, this_plugin_name, "ff2_nightmare", 0, 0); 83 | char temp[PLATFORM_MAX_PATH]; 84 | FF2_RandomSound("sound_ability", temp, sizeof(temp), boss, 0); 85 | FF2_SetBossCharge(boss, 0, bossCharge - 100.0); 86 | } 87 | } 88 | } 89 | 90 | public Action FF2_OnAbility2(int boss, const char[] plugin_name, const char[] ability_name, int status) 91 | { 92 | int client = GetClientOfUserId(FF2_GetBossUserId(boss)); 93 | 94 | if(StrEqual(ability_name, "ff2_nightmare")) 95 | { 96 | // m_nSequence, m_flPlaybackRate 97 | 98 | int targetlist[MAXPLAYERS+1]; 99 | int targetCount = 0; 100 | float targetPos[3], clientPos[3]; 101 | float targetAngles[3], clientAngles[3]; 102 | 103 | GetClientEyePosition(client, clientPos); 104 | GetClientEyeAngles(client, clientAngles); 105 | 106 | SetEntityRenderMode(client, RENDER_TRANSCOLOR); 107 | SetEntityRenderColor(client, _, _, _, 255); 108 | 109 | int animationentity = CreateEntityByName("prop_dynamic_override"); 110 | if(IsValidEntity(animationentity)) 111 | { 112 | char model[PLATFORM_MAX_PATH]; 113 | // float pos[3]; 114 | // GetClientEyePosition(client, pos); 115 | GetClientModel(client, model, sizeof(model)); 116 | 117 | DispatchKeyValue(animationentity, "model", model); 118 | 119 | DispatchSpawn(animationentity); 120 | SetEntPropEnt(animationentity, Prop_Send, "m_hOwnerEntity", client); 121 | 122 | if(GetEntProp(client, Prop_Send, "m_iTeamNum") == 0) 123 | SetEntProp(animationentity, Prop_Send, "m_nSkin", GetEntProp(client, Prop_Send, "m_nForcedSkin")); 124 | else 125 | SetEntProp(animationentity, Prop_Send, "m_nSkin", GetClientTeam(client) - 2); 126 | 127 | SetEntProp(animationentity, Prop_Send, "m_nSequence", GetEntProp(client, Prop_Send, "m_nSequence")); 128 | SetEntPropFloat(animationentity, Prop_Send, "m_flPlaybackRate", GetEntPropFloat(client, Prop_Send, "m_flPlaybackRate")); // 129 | 130 | float tempAngle[3]; 131 | 132 | tempAngle[0] = clientAngles[0]; 133 | tempAngle[1] = clientAngles[1]; 134 | tempAngle[2] = 0.0; 135 | TeleportEntity(animationentity, clientPos, tempAngle, NULL_VECTOR); 136 | } 137 | 138 | for(int target = 1; target<=MaxClients; target++) 139 | { 140 | if(!IsClientInGame(target) || !IsPlayerAlive(target)) continue; 141 | 142 | if(GetClientTeam(client) != GetClientTeam(target)) 143 | { 144 | targetlist[targetCount++] = target; 145 | UTIL_ScreenFade(target, {0, 0, 0, 255}, 0.1, 5.0); 146 | } 147 | } 148 | 149 | int bestTarget = targetlist[GetRandomInt(0, targetCount-1)]; 150 | 151 | GetClientEyePosition(bestTarget, targetPos); 152 | GetClientEyeAngles(bestTarget, targetAngles); 153 | 154 | float tempVelocity[3], tempTargetVelocity[3]; 155 | 156 | GetEntPropVector(client, Prop_Data, "m_vecVelocity", tempVelocity); 157 | GetEntPropVector(bestTarget, Prop_Data, "m_vecVelocity", tempTargetVelocity); 158 | 159 | ScaleVector(tempVelocity, -1.1); 160 | ScaleVector(tempTargetVelocity, -1.1); 161 | 162 | TeleportEntity(bestTarget, clientPos, clientAngles, tempVelocity); 163 | TeleportEntity(client, targetPos, targetAngles, tempVelocity); 164 | } 165 | } 166 | 167 | 168 | stock bool IsBoss(int client) 169 | { 170 | return FF2_GetBossIndex(client) != -1; 171 | } 172 | 173 | stock bool IsValidClient(int client) 174 | { 175 | return (0 12 | #include 13 | 14 | #pragma semicolon 1 15 | #pragma newdecls required 16 | 17 | //Defines 18 | #define PLUGIN_VERSION "0.5.1" 19 | #define ABILITY "ff2_pause" 20 | 21 | //Declarations 22 | ConVar pauseCVar; 23 | bool paused; 24 | bool IsProxy[MAXPLAYERS+1]; 25 | Handle rageTM[MAXPLAYERS+1]; 26 | 27 | public Plugin myinfo = 28 | { 29 | name = "Freak Fortress 2: Pause Ability", 30 | author = "Naydef", 31 | description = "Subplugin, which can pause the whole server!", 32 | version = PLUGIN_VERSION, 33 | url = "https://forums.alliedmods.net/forumdisplay.php?f=154" 34 | }; 35 | 36 | public void OnPluginStart2() 37 | { 38 | pauseCVar = FindConVar("sv_pausable"); 39 | if(!pauseCVar) { 40 | SetFailState("sv_pausable convar not found. Subplugin disabled!!!"); 41 | } 42 | AddCommandListener(Listener_PauseCommand, "pause"); 43 | AddCommandListener(Listener_PauseCommand, "unpause"); // For safety 44 | } 45 | 46 | public Action FF2_OnAbility2(int boss, const char[] plugin_name, const char[] ability_name, int action) 47 | { 48 | if(StrEqual(ability_name, ABILITY, false)) 49 | { 50 | int client=GetClientOfUserId(FF2_GetBossUserId(boss)); 51 | float time=FF2_GetAbilityArgumentFloat(boss, this_plugin_name, ABILITY, 1, 0.0); 52 | PauseRage(client, time); 53 | } 54 | return Plugin_Continue; 55 | } 56 | 57 | public void PauseRage(int client, float time) 58 | { 59 | if(IsValidClient(client)) 60 | { 61 | for(int i=1; i<=MaxClients; i++) 62 | { 63 | if(IsValidClient(i)) 64 | { 65 | SetNextAttack(i, time); 66 | } 67 | } 68 | SilentCvarChange(pauseCVar, true); 69 | SetConVarBool(pauseCVar, true); 70 | pauseCVar.BoolValue = true; 71 | SilentCvarChange(pauseCVar, false); 72 | if(!paused) 73 | { 74 | IsProxy[client]=true; 75 | FakeClientCommand(client, "pause"); 76 | IsProxy[client]=false; 77 | } 78 | paused=true; 79 | //CreateTimer(1.0, Timer_RemOverlay, _, TIMER_FLAG_NO_MAPCHANGE); 80 | DataPack packet; 81 | rageTM[client]=CreateDataTimer(time, Timer_UnPause, packet, TIMER_FLAG_NO_MAPCHANGE); 82 | packet.WriteCell(GetClientSerial(client)); 83 | } 84 | } 85 | 86 | public void OnClientDisconnect(int client) 87 | { 88 | if(rageTM[client]!=INVALID_HANDLE) 89 | { 90 | TriggerTimer(rageTM[client]); 91 | delete rageTM[client]; 92 | } 93 | IsProxy[client]=false; 94 | } 95 | 96 | public Action Listener_PauseCommand(int client, const char[] command, int argc) 97 | { 98 | if(!IsProxy[client]) 99 | { 100 | return Plugin_Handled; 101 | } 102 | return Plugin_Continue; 103 | } 104 | 105 | public Action Timer_UnPause(Handle htimer, DataPack packet) 106 | { 107 | packet.Reset(); 108 | int client=GetClientFromSerial(packet.ReadCell()); 109 | if(!IsValidClient(client)) 110 | { 111 | return Plugin_Stop; 112 | } 113 | SilentCvarChange(pauseCVar, true); 114 | pauseCVar.BoolValue = false; 115 | SilentCvarChange(pauseCVar, false); 116 | IsProxy[client]=true; 117 | if(paused) 118 | { 119 | FakeClientCommand(client, "pause"); 120 | } 121 | paused=false; 122 | IsProxy[client]=false; 123 | rageTM[client] = null; 124 | for(int i=1; i<=MaxClients; i++) 125 | { 126 | if(IsValidClient(i)) 127 | { 128 | SetNextAttack(i, 0.1); 129 | } 130 | } 131 | return Plugin_Continue; 132 | } 133 | 134 | /* 135 | public Action:Timer_RemOverlay(Handle:htimer) 136 | { 137 | for(int i=1; i<=MaxClients; i++) 138 | { 139 | if(IsValidClient(i)) 140 | { 141 | DoOverlay(i, ""); 142 | } 143 | } 144 | return Plugin_Continue; 145 | } 146 | */ 147 | 148 | /* Stocks */ 149 | bool IsValidClient(int client, bool replaycheck=true) //From Freak Fortress 2 150 | { 151 | if(client<=0 || client>MaxClients) 152 | { 153 | return false; 154 | } 155 | 156 | if(!IsClientInGame(client)) 157 | { 158 | return false; 159 | } 160 | 161 | if(GetEntProp(client, Prop_Send, "m_bIsCoaching")) 162 | { 163 | return false; 164 | } 165 | 166 | if(replaycheck) 167 | { 168 | if(IsClientSourceTV(client) || IsClientReplay(client)) 169 | { 170 | return false; 171 | } 172 | } 173 | return true; 174 | } 175 | 176 | 177 | void SilentCvarChange(const ConVar cvar, bool setsilent=true) 178 | { 179 | int flags=GetConVarFlags(cvar); 180 | (setsilent) ? (flags^=FCVAR_NOTIFY) : (flags|=FCVAR_NOTIFY); 181 | SetConVarFlags(cvar, flags); 182 | } 183 | 184 | void SetNextAttack(int client, float time) // Fix prediction 185 | { 186 | if(IsValidClient(client)) 187 | { 188 | SetEntPropFloat(client, Prop_Send, "m_flNextAttack", GetGameTime()+time); 189 | for(int i=0; i<=2; i++) 190 | { 191 | int weapon=GetPlayerWeaponSlot(client, i); 192 | if(IsValidEntity(weapon)) 193 | { 194 | SetEntPropFloat(weapon, Prop_Send, "m_flNextPrimaryAttack", GetGameTime()+time); 195 | } 196 | } 197 | } 198 | } 199 | 200 | /* 201 | DoOverlay(client, const String:overlay[]) //Copied from FF2 202 | { 203 | PrintToChatAll("Removing overlay for %N", client); 204 | int flags=GetCommandFlags("r_screenoverlay"); 205 | SetCommandFlags("r_screenoverlay", flags & ~FCVAR_CHEAT); 206 | ClientCommand(client, "r_screenoverlay \"%s\"", overlay); 207 | SetCommandFlags("r_screenoverlay", flags); 208 | } 209 | */ 210 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/ff2_powerups.sp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #pragma semicolon 1 6 | #pragma newdecls required 7 | 8 | public Plugin myinfo = { 9 | name = "Freak Fortress 2: Mannpower Passives", 10 | author = "Deathreus", 11 | description = "Adds any Mannpower Powerup as a passive ability", 12 | version = "1.0", 13 | }; 14 | 15 | //new BossTeam = _:TFTeam_Blue; 16 | 17 | 18 | public void OnPluginStart2() 19 | { 20 | HookEvent("arena_round_start", event_round_start, EventHookMode_Post); 21 | //HookEvent("teamplay_round_win", event_round_end); 22 | } 23 | 24 | public Action event_round_start(Event event, const char[] name, bool dontBroadcast) 25 | { 26 | int Boss; 27 | for (int Index = 0; (Boss=GetClientOfUserId(FF2_GetBossUserId(Index)))>0; Index++) 28 | { 29 | if(FF2_HasAbility(Index, this_plugin_name, "passive_powerups")) 30 | { 31 | int CondType = FF2_GetAbilityArgument(Index, this_plugin_name, "passive_powerups", 1, 1); 32 | TFCond Condition; 33 | switch(CondType) 34 | { 35 | case 1: Condition = view_as(90); // Strength 36 | case 2: Condition = view_as(91); // Haste 37 | case 3: Condition = view_as(92); // Regen 38 | case 4: Condition = view_as(93); // Resistance 39 | case 5: Condition = view_as(94); // Vampire 40 | case 6: Condition = view_as(95); // Warlock 41 | case 7: Condition = view_as(96); // Precision 42 | case 8: Condition = view_as(97); // Agility 43 | case 9: Condition = view_as(103); // Knockout 44 | } 45 | TF2_AddCondition(Boss, Condition, TFCondDuration_Infinite); 46 | } 47 | } 48 | return Plugin_Continue; 49 | } 50 | 51 | public Action FF2_OnAbility2(int client, const char[] plugin_name, const char[] ability_name, int status){ 52 | return Plugin_Continue; 53 | //Y u no let me compile without this 54 | } 55 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/ff2_ragesound.sp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #pragma semicolon 1 6 | #pragma newdecls required 7 | 8 | public Plugin myinfo = { 9 | name = "Freak Fortress 2: Server Wide Rage Sound", 10 | author = "Deathreus", 11 | version = "1.2", 12 | }; 13 | 14 | public void OnPluginStart2() 15 | { 16 | // Y u no let me compile without this 17 | } 18 | 19 | public Action FF2_OnAbility2(int iBoss, const char[] pluginName, const char[] abilityName, int iStatus) 20 | { 21 | if (!strcmp(abilityName, "rage_sound")) 22 | { 23 | static char sRageSound[5][PLATFORM_MAX_PATH]; 24 | static char sBuffer[PLATFORM_MAX_PATH*5]; 25 | FF2_GetAbilityArgumentString(iBoss, pluginName, abilityName, 1, sBuffer, sizeof(sBuffer)); 26 | ExplodeString(sBuffer, " ; ", sRageSound, 5, PLATFORM_MAX_PATH); 27 | 28 | int iCount = 0; 29 | for (int i = 0; i < 5; i++) 30 | { 31 | if (strlen(sRageSound[i]) > 3) 32 | { 33 | PrecacheSound(sRageSound[i]); 34 | iCount++; 35 | } 36 | 37 | if (iCount == 0) 38 | return Plugin_Continue; 39 | } 40 | 41 | int iRand = GetRandomInt(0, iCount-1); 42 | EmitSoundToAll(sRageSound[iRand]); 43 | } 44 | return Plugin_Continue; 45 | } 46 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/ff2_replaceprojectile.sp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | new bool:g_Enabled = false; 8 | new Float:g_ProjectileScale = 1.0; 9 | new String:g_ProjectileModel[PLATFORM_MAX_PATH]; 10 | new String:g_Projectile[PLATFORM_MAX_PATH]; 11 | static const Float:nullVec[] = {0.0,0.0,0.0}; 12 | 13 | public Plugin:myinfo = { 14 | name = "Freak Fortress 2: Replace Projectile", 15 | description = "Replaces projectiles", 16 | author = "frog, friagram", 17 | version = "1.0.2" 18 | }; 19 | 20 | public OnMapStart() 21 | { 22 | HookEvent("arena_round_start", Event_RoundStart, EventHookMode_PostNoCopy); 23 | } 24 | 25 | public OnEntityCreated(entity, const String:classname[]) 26 | { 27 | if (g_Enabled) 28 | { 29 | if (strcmp(classname, g_Projectile) == 0) 30 | { 31 | SDKHook(entity, SDKHook_SpawnPost, ProjectileSpawned); 32 | } 33 | } 34 | } 35 | 36 | public ProjectileSpawned(entity) 37 | { 38 | new owner = GetEntPropEnt(entity, Prop_Send, "m_hOwnerEntity"); 39 | if (owner > 0 && owner <= MaxClients) 40 | { 41 | if (!IsClientInGame(owner)) 42 | { 43 | return; 44 | } 45 | if (FF2_GetBossIndex(owner) > -1) 46 | { 47 | CreateTimer(0.0, Timer_ProjectileModel, EntIndexToEntRef(entity)); 48 | } 49 | } 50 | } 51 | 52 | public Action:Timer_ProjectileModel(Handle:timer, any:ref) 53 | { 54 | new entity = EntRefToEntIndex(ref); 55 | if (entity != INVALID_ENT_REFERENCE) 56 | { 57 | SetEntityModel(entity, g_ProjectileModel); 58 | SetEntPropFloat(entity, Prop_Send, "m_flModelScale", g_ProjectileScale); 59 | SetEntPropVector(entity, Prop_Send, "m_vecMins", nullVec); 60 | SetEntPropVector(entity, Prop_Send, "m_vecMaxs", nullVec); 61 | } 62 | } 63 | 64 | public Action:Event_RoundStart(Handle:event, const String:name[], bool:dontBroadcast) 65 | { 66 | g_Enabled = false; 67 | if (FF2_IsFF2Enabled()) 68 | { 69 | new Boss = GetClientOfUserId(FF2_GetBossUserId(0)); 70 | if (Boss>0) 71 | { 72 | if (FF2_HasAbility(0, this_plugin_name, "replace_projectile")) 73 | { 74 | FF2_GetAbilityArgumentString(0, this_plugin_name, "replace_projectile", 1, g_Projectile, PLATFORM_MAX_PATH); 75 | FF2_GetAbilityArgumentString(0, this_plugin_name, "replace_projectile", 2, g_ProjectileModel, PLATFORM_MAX_PATH); 76 | g_ProjectileScale = FF2_GetAbilityArgumentFloat(0, this_plugin_name, "replace_projectile", 3); 77 | if (g_ProjectileScale <= 0) 78 | { 79 | g_ProjectileScale = 1.0; 80 | } 81 | PrecacheModel(g_ProjectileModel); 82 | g_Enabled = true; 83 | } 84 | } 85 | } 86 | } 87 | 88 | // not used but required. 89 | public OnPluginStart2(){} 90 | public Action:FF2_OnAbility2(index, const String:plugin_name[], const String:ability_name[], action){} -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/ff2_sam.sp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int clientWeapon[MAXPLAYERS+1]; 11 | 12 | public Plugin myinfo= 13 | { 14 | name="Freak Fortress 2: Sam's Abilities", 15 | author="Nopied", 16 | description="", 17 | version="wat.", 18 | }; 19 | 20 | public void OnPluginStart2() 21 | { 22 | HookEvent("player_spawn", OnPlayerSpawn); 23 | } 24 | 25 | public Action OnPlayerSpawn(Handle event, const char[] name, bool dont) 26 | { 27 | int client=GetClientOfUserId(GetEventInt(event, "userid")); 28 | 29 | if(clientWeapon[client] && IsValidEntity(clientWeapon[client])) 30 | { 31 | SetEntityRenderMode(clientWeapon[client], RENDER_TRANSCOLOR); 32 | SetEntityRenderColor(clientWeapon[client], _, _, _, 255); 33 | clientWeapon[client]=0; 34 | } 35 | 36 | } 37 | 38 | public Action FF2_OnAbility2(int boss, const char[] plugin_name, const char[] ability_name, int status) 39 | { 40 | if(!strcmp(ability_name, "rage_sam")) 41 | { 42 | Rage_Sam(boss); 43 | } 44 | } 45 | 46 | void Rage_Sam(int boss) 47 | { 48 | int bossClient=GetClientOfUserId(FF2_GetBossUserId(boss)); 49 | for(int client=1; client<=MaxClients; client++) 50 | { 51 | if(IsClientInGame(client) && !IsBossTeam(client) && IsPlayerAlive(client)) 52 | { 53 | TF2_AddCondition(client, TFCond_SpeedBuffAlly, 10.0); 54 | TF2_StunPlayer(client, 10.0, 1.0, TF_STUNFLAG_NOSOUNDOREFFECT|TF_STUNFLAG_THIRDPERSON, bossClient); // TODO: 시간 커스터마이즈 55 | 56 | // 들고있던 무기 떨구기 || 107: 이속 증가 57 | 58 | int weapon=GetEntPropEnt(client, Prop_Send, "m_hActiveWeapon"); 59 | 60 | if(weapon!=clientWeapon[client] && IsValidEntity(weapon)) 61 | { 62 | if(clientWeapon[client] && IsValidEntity(clientWeapon[client])) 63 | { 64 | SetEntityRenderMode(weapon, RENDER_TRANSCOLOR); 65 | SetEntityRenderColor(clientWeapon[client], _, _, _, 255); 66 | } 67 | SetEntityRenderMode(weapon, RENDER_TRANSCOLOR); 68 | SetEntityRenderColor(weapon, 255, 255, 255, 75); 69 | clientWeapon[client]=weapon; 70 | PrintCenterText(client, "들고 있던 무기를 사용할 수 없게 되었습니다!"); 71 | } 72 | } 73 | } 74 | } 75 | 76 | public void OnClientDisconnect(int client) 77 | { 78 | clientWeapon[client]=0; 79 | } 80 | 81 | public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon, int &subtype, int &cmdnum, int &tickcount, int &seed, int mouse[2]) 82 | { 83 | if(!IsValidClient(client) || !clientWeapon[client]) 84 | return Plugin_Continue; 85 | 86 | int weapon2=GetEntPropEnt(client, Prop_Send, "m_hActiveWeapon"); 87 | if(weapon2 == clientWeapon[client] && IsValidEntity(weapon2)) 88 | { 89 | if(buttons & IN_ATTACK|IN_ATTACK2|IN_ATTACK3|IN_RELOAD) 90 | { 91 | PrintCenterText(client, "분노로 인해 사용할 수 없습니다!"); 92 | } 93 | SetEntPropFloat(weapon2, Prop_Send, "m_flNextPrimaryAttack", GetGameTime()+0.2); 94 | SetEntPropFloat(weapon2, Prop_Send, "m_flNextSecondaryAttack", GetGameTime()+0.2); 95 | SetEntPropFloat(client, Prop_Send, "m_flNextAttack", GetGameTime()+0.2); 96 | } 97 | return Plugin_Continue; 98 | } 99 | 100 | stock int SpawnWeaponProp(int client, int weapon) 101 | { 102 | int ent=CreateEntityByName("prop_physics_override"); 103 | 104 | if(!IsValidEntity(ent)) return -1; 105 | 106 | float clientPos[3]; 107 | GetClientEyePosition(client, clientPos); 108 | 109 | SetEntProp(ent, Prop_Data, "m_takedamage", 2); 110 | SetEntProp(ent, Prop_Send, "m_nModelIndex", GetEntProp(weapon, Prop_Send, "m_nModelIndex")); 111 | 112 | DispatchSpawn(ent); 113 | TeleportEntity(ent, clientPos, NULL_VECTOR, NULL_VECTOR); 114 | SetEntityMoveType(ent, MOVETYPE_VPHYSICS); 115 | 116 | SetEntProp(ent, Prop_Send, "m_CollisionGroup", 0); 117 | 118 | return ent; 119 | } 120 | 121 | stock bool IsValidClient(int client) 122 | { 123 | return (0 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #pragma newdecls required 10 | 11 | Handle OnHaleRage = INVALID_HANDLE; 12 | int BossTeam = view_as(TFTeam_Blue); 13 | 14 | public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) 15 | { 16 | OnHaleRage=CreateGlobalForward("VSH_OnDoRage", ET_Hook, Param_FloatByRef); 17 | return APLRes_Success; 18 | } 19 | 20 | public Plugin myinfo = 21 | { 22 | name = "Freak Fortress 2: SCP-173 Special Abilities", 23 | description = "Decompiled and Rewroten version", 24 | author = "OriginalNero, Rewrite by Batfoxkid, Decompiled by Maximilian_", 25 | version = "1.1" 26 | }; 27 | 28 | public void OnPluginStart2() 29 | { 30 | HookEvent("arena_round_start", OnRoundStart); 31 | HookEvent("teamplay_round_win", OnRoundEnd, EventHookMode_Pre); 32 | } 33 | 34 | public Action OnRoundStart(Handle event, const char[] name, bool dontBroadcast) 35 | { 36 | if(!FF2_IsFF2Enabled()) 37 | return Plugin_Continue; 38 | 39 | CreateTimer(0.5, Timer_GetBossTeam, _, TIMER_FLAG_NO_MAPCHANGE); 40 | return Plugin_Continue; 41 | } 42 | 43 | public Action Timer_GetBossTeam(Handle timer) 44 | { 45 | BossTeam = FF2_GetBossTeam(); 46 | return Plugin_Continue; 47 | } 48 | 49 | public Action OnRoundEnd(Handle event, char[] name, bool dontBroadcast) 50 | { 51 | for(int client=1; client<=MaxClients; client++) 52 | { 53 | if(IsClientInGame(client)) 54 | { 55 | int boss = FF2_GetBossIndex(client); 56 | if(boss >= 0) 57 | { 58 | if(FF2_HasAbility(boss, this_plugin_name, "ff2_scp")) 59 | { 60 | TF2_RemoveCondition(client, TFCond_HalloweenKartNoTurn); 61 | TurnOnLights(); 62 | } 63 | } 64 | } 65 | } 66 | return Plugin_Continue; 67 | } 68 | 69 | public Action FF2_OnAbility2(int boss, const char[] plugin_name, const char[] ability_name, int status) 70 | { 71 | int client = GetClientOfUserId(FF2_GetBossUserId(boss)); 72 | int slot = FF2_GetAbilityArgument(boss, this_plugin_name, ability_name, 0); 73 | if(!slot) 74 | { 75 | if(!boss) 76 | { 77 | Action action=Plugin_Continue; 78 | Call_StartForward(OnHaleRage); 79 | float distance=FF2_GetRageDist(boss, this_plugin_name, ability_name); 80 | float newDistance=distance; 81 | Call_PushFloatRef(newDistance); 82 | Call_Finish(action); 83 | if(action!=Plugin_Continue && action!=Plugin_Changed) 84 | { 85 | return Plugin_Continue; 86 | } 87 | else if(action==Plugin_Changed) 88 | { 89 | distance=newDistance; 90 | } 91 | } 92 | } 93 | 94 | if(!strcmp(ability_name, "ff2_scp")) 95 | { 96 | TF2_AddCondition(client, TFCond_TeleportedGlow, FF2_GetAbilityArgumentFloat(boss, this_plugin_name, ability_name, 1, 5.0)); 97 | CreateTimer(0.1, EatRage, boss, TIMER_FLAG_NO_MAPCHANGE); 98 | } 99 | return Plugin_Continue; 100 | } 101 | 102 | public Action EatRage(Handle timer, any boss) 103 | { 104 | FF2_SetBossCharge(boss, 0, 0.0); 105 | } 106 | 107 | public void TF2_OnConditionAdded(int client, TFCond condition) 108 | { 109 | if(!FF2_IsFF2Enabled() || FF2_GetRoundState()!=1 || !IsClientInGame(client)) 110 | return; 111 | 112 | if(condition==TFCond_TeleportedGlow) 113 | { 114 | int boss = FF2_GetBossIndex(client); 115 | if(boss >= 0) 116 | { 117 | if(FF2_HasAbility(boss, this_plugin_name, "ff2_scp")) 118 | { 119 | TF2_RemoveCondition(client, TFCond_HalloweenKartNoTurn); 120 | } 121 | } 122 | } 123 | else if(condition==TFCond_HalloweenKartNoTurn) 124 | { 125 | int boss = FF2_GetBossIndex(client); 126 | if(boss >= 0) 127 | { 128 | if(FF2_HasAbility(boss, this_plugin_name, "ff2_scp")) 129 | { 130 | TurnOnLights(); 131 | } 132 | } 133 | } 134 | } 135 | 136 | public void TF2_OnConditionRemoved(int client, TFCond condition) 137 | { 138 | if(!FF2_IsFF2Enabled() || FF2_GetRoundState()!=1 || !IsClientInGame(client)) 139 | return; 140 | 141 | if(condition==TFCond_TeleportedGlow) 142 | { 143 | int boss = FF2_GetBossIndex(client); 144 | if(boss >= 0) 145 | { 146 | if(FF2_HasAbility(boss, this_plugin_name, "ff2_scp")) 147 | { 148 | TF2_AddCondition(client, TFCond_HalloweenKartNoTurn, -1.0); 149 | } 150 | } 151 | } 152 | else if(condition==TFCond_HalloweenKartNoTurn) 153 | { 154 | int boss = FF2_GetBossIndex(client); 155 | if(boss >= 0) 156 | { 157 | if(FF2_HasAbility(boss, this_plugin_name, "ff2_scp")) 158 | { 159 | TurnOffLights(); 160 | } 161 | } 162 | } 163 | } 164 | 165 | void TurnOnLights() 166 | { 167 | SetCommandFlags("r_screenoverlay", GetCommandFlags("r_screenoverlay") & -FCVAR_CHEAT); 168 | for(int target=1; target<=MaxClients; target++) 169 | { 170 | if(IsClientInGame(target)) 171 | { 172 | if(view_as(GetClientTeam(target))!=BossTeam && IsPlayerAlive(target)) 173 | { 174 | ClientCommand(target, "r_screenoverlay \"\""); 175 | } 176 | } 177 | } 178 | SetCommandFlags("r_screenoverlay", GetCommandFlags("r_screenoverlay") & FCVAR_CHEAT); 179 | } 180 | 181 | void TurnOffLights() 182 | { 183 | SetCommandFlags("r_screenoverlay", GetCommandFlags("r_screenoverlay") & -FCVAR_CHEAT); 184 | for(int target=1; target<=MaxClients; target++) 185 | { 186 | if(IsClientInGame(target)) 187 | { 188 | if(view_as(GetClientTeam(target))!=BossTeam && IsPlayerAlive(target)) 189 | { 190 | ClientCommand(target, "r_screenoverlay \"%s\"", "effects/tp_eyefx/tp_black"); 191 | } 192 | } 193 | } 194 | SetCommandFlags("r_screenoverlay", GetCommandFlags("r_screenoverlay") & FCVAR_CHEAT); 195 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/ff2_skeleton.sp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int clientSkeleton[MAXPLAYERS+1][MAXPLAYERS+1]; 10 | 11 | public Plugin myinfo= 12 | { 13 | name="Freak Fortress 2 : Skeleton's abilities", 14 | author="Nopied", 15 | description="....", 16 | version="?", 17 | }; 18 | 19 | public void OnPluginStart2() 20 | { 21 | HookEvent("player_death", OnPlayerDeath, EventHookMode_Pre); 22 | } 23 | 24 | public Action OnPlayerDeath(Handle event, const char[] name, bool dont) 25 | { 26 | if(FF2_GetRoundState() != 1) return Plugin_Continue; 27 | 28 | int client=GetClientOfUserId(GetEventInt(event, "userid")); 29 | // int attacker=GetClientOfUserId(GetEventInt(event, "attacker")); 30 | 31 | if(!(GetEventInt(event, "death_flags") & TF_DEATHFLAG_DEADRINGER)) 32 | { 33 | for(int target = 1; target <= MaxClients; target++) 34 | { 35 | if(FF2_HasAbility(FF2_GetBossIndex(target), this_plugin_name, "skeleton_spawner")) 36 | { 37 | clientSkeleton[target][client]=SpawnSkeleton(target); 38 | if(IsValidEntity(clientSkeleton[target][client])) 39 | { 40 | float skPos[3]; 41 | GetClientEyePosition(target, skPos); 42 | 43 | skPos[2] -= 10.0; 44 | SDKHook(clientSkeleton[target][client], SDKHook_OnTakeDamage, OnTakeDamage); 45 | TeleportEntity(clientSkeleton[target][client], skPos, NULL_VECTOR, NULL_VECTOR); 46 | } 47 | } 48 | } 49 | } 50 | } 51 | 52 | public Action:OnTakeDamage(int victim, int &attacker, int &inflictor, float &damage, int &damagetype, int &weapon, float damageForce[3], float damagePosition[3], int damagecustom) 53 | { 54 | if(IsValidClient(attacker) || IsValidEntity(inflictor)) 55 | return Plugin_Handled; 56 | 57 | return Plugin_Continue; 58 | } 59 | 60 | 61 | public Action FF2_OnAbility2(int boss, const char[] pluginName, const char[] abilityName, int status) 62 | { 63 | if(!strcmp(abilityName, "comeon_skeleton")) 64 | { 65 | ComeOnSkeleton(boss); 66 | } 67 | } 68 | 69 | void ComeOnSkeleton(int boss) 70 | { 71 | int client=GetClientOfUserId(FF2_GetBossUserId(boss)); 72 | 73 | float skPos[3]; 74 | GetClientEyePosition(client, skPos); 75 | 76 | for(int target=1; target<=MaxClients; target++) 77 | { 78 | if(clientSkeleton[client][target] && IsValidEntity(clientSkeleton[client][target])) 79 | { 80 | TeleportEntity(clientSkeleton[client][target], skPos, NULL_VECTOR, NULL_VECTOR); 81 | } 82 | } 83 | } 84 | 85 | stock int SpawnSkeleton(int owner) 86 | { 87 | int ent = CreateEntityByName("tf_zombie"); 88 | if(!IsValidEntity(ent)) 89 | { 90 | return -1; 91 | } 92 | 93 | SetEntPropEnt(ent, Prop_Send, "m_hOwnerEntity", owner); 94 | SetEntProp(ent, Prop_Send, "m_iTeamNum", GetClientTeam(owner)); 95 | 96 | DispatchSpawn(ent); 97 | return ent; 98 | } 99 | 100 | stock bool IsValidClient(int client) 101 | { 102 | return (0 4 | #include 5 | #include 6 | #include 7 | 8 | #pragma newdecls required 9 | 10 | public Plugin myinfo= 11 | { 12 | name = "Freak Fortress 2: Sound On Kill", 13 | author = "Deathreus", 14 | description = "Emits the sound to only the recipient", 15 | version = "1.0", 16 | }; 17 | 18 | #define MAX_SOUND_FILE_LENGTH 80 19 | #define MAX_RAGE_SOUNDS 5 20 | 21 | char g_sRageSound[MAX_RAGE_SOUNDS][MAX_SOUND_FILE_LENGTH]; 22 | int BossTeam = view_as(TFTeam_Blue); 23 | 24 | public void OnPluginStart2() 25 | { 26 | HookEvent("player_death", Event_PlayerDeath); 27 | } 28 | 29 | public void FF2_OnAbility2(int iClient, const char[] plugin_name, const char[] ability_name, int iStatus) 30 | { 31 | // Will do nothing, but compiler needs it 32 | } 33 | 34 | public Action Event_PlayerDeath(Event hEvent, const char[] strName, bool bDontBroadcast) 35 | { 36 | if (GetEventInt(hEvent, "death_flags") & TF_DEATHFLAG_DEADRINGER) 37 | return Plugin_Continue; 38 | int iAttacker = GetClientOfUserId(GetEventInt(hEvent, "attacker")); 39 | int iVictim = GetClientOfUserId(GetEventInt(hEvent, "userid")); 40 | int a_index = FF2_GetBossIndex(iAttacker); 41 | if(iVictim != -1) 42 | { 43 | if(FF2_HasAbility(a_index, this_plugin_name, "kill_sound")) 44 | { 45 | ReadSounds(a_index, "kill_sound", 1); 46 | if(GetClientTeam(iVictim) != BossTeam && IsValidClient(iVictim)) 47 | EmitRandomClientSound(iVictim); 48 | } 49 | } 50 | return Plugin_Continue; 51 | } 52 | 53 | stock bool IsValidClient(int iClient) 54 | { 55 | if(iClient <= 0 || iClient > MaxClients || !IsClientInGame(iClient)) 56 | return false; 57 | 58 | if(IsClientSourceTV(iClient) || IsClientReplay(iClient)) 59 | return false; 60 | 61 | return true; 62 | } 63 | 64 | void ReadSounds(int iClient, const char[] ability_name, int iArg) 65 | { 66 | static char strSound[(MAX_SOUND_FILE_LENGTH + 1) * MAX_RAGE_SOUNDS]; 67 | FF2_GetAbilityArgumentString(iClient, this_plugin_name, ability_name, iArg, strSound, sizeof(strSound)); 68 | ExplodeString(strSound, ";", g_sRageSound, MAX_RAGE_SOUNDS, MAX_SOUND_FILE_LENGTH); 69 | for (int i = 0; i < MAX_RAGE_SOUNDS; i++) 70 | if (strlen(g_sRageSound[i]) > 3) 71 | PrecacheSound(g_sRageSound[i]); 72 | } 73 | 74 | void EmitRandomClientSound(int iClient) 75 | { 76 | int count = 0; 77 | for (int i = 0; i < MAX_RAGE_SOUNDS; i++) 78 | if (strlen(g_sRageSound[i]) > 3) 79 | count++; 80 | 81 | if (count == 0) 82 | return; 83 | 84 | int rand = GetRandomInt(0, count-1); 85 | if (strlen(g_sRageSound[rand]) > 3) 86 | { 87 | EmitSoundToClient(iClient, g_sRageSound[rand]); 88 | } 89 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/ff2_tempMelee.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | public Plugin:myinfo = { 10 | name = "Freak Fortress 2: Temp Melee Weapon", 11 | author = "Blinx" 12 | }; 13 | 14 | new String:weaponAttribs[64]; 15 | new String:weaponClass[64]; 16 | new thisWeaponIndex; 17 | 18 | new String:reWeaponAttribs[64]; 19 | new String:reWeaponClass[64]; 20 | new reWeaponIndex; 21 | 22 | public OnPluginStart2() 23 | { 24 | } 25 | 26 | public Action:FF2_OnAbility2(index,const String:plugin_name[],const String:ability_name[],action) 27 | { 28 | if (!strcmp(ability_name,"rage_tempMelee")) 29 | rage_tempMelee(ability_name, index); 30 | } 31 | 32 | stock SpawnWeapon(client,String:name[],index,level,qual,String:att[]) 33 | { 34 | new Handle:hWeapon = TF2Items_CreateItem(OVERRIDE_ALL|FORCE_GENERATION); 35 | TF2Items_SetClassname(hWeapon, name); 36 | TF2Items_SetItemIndex(hWeapon, index); 37 | TF2Items_SetLevel(hWeapon, level); 38 | TF2Items_SetQuality(hWeapon, qual); 39 | new String:atts[32][32]; 40 | new count = ExplodeString(att, " ; ", atts, 32, 32); 41 | if (count > 0) 42 | { 43 | TF2Items_SetNumAttributes(hWeapon, count/2); 44 | new i2 = 0; 45 | for (new i = 0; i < count; i+=2) 46 | { 47 | TF2Items_SetAttribute(hWeapon, i2, StringToInt(atts[i]), StringToFloat(atts[i+1])); 48 | i2++; 49 | } 50 | } 51 | else 52 | TF2Items_SetNumAttributes(hWeapon, 0); 53 | if (hWeapon==INVALID_HANDLE) 54 | return -1; 55 | new entity = TF2Items_GiveNamedItem(client, hWeapon); 56 | CloseHandle(hWeapon); 57 | EquipPlayerWeapon(client, entity); 58 | return entity; 59 | } 60 | 61 | rage_tempMelee(const String:ability_name[], index) 62 | { 63 | new Boss=GetClientOfUserId(FF2_GetBossUserId(index)); 64 | FF2_GetAbilityArgumentString(index, this_plugin_name, ability_name, 1, weaponAttribs, sizeof(weaponAttribs)); 65 | FF2_GetAbilityArgumentString(index, this_plugin_name, ability_name, 2, weaponClass, sizeof(weaponClass)); 66 | thisWeaponIndex = FF2_GetAbilityArgument(index, this_plugin_name, ability_name, 3); 67 | new Float:duration=FF2_GetAbilityArgumentFloat(index, this_plugin_name, ability_name, 4); 68 | 69 | TF2_RemoveWeaponSlot(Boss, TFWeaponSlot_Melee); 70 | SetEntPropEnt(Boss, Prop_Send, "m_hActiveWeapon", SpawnWeapon(Boss, weaponClass, thisWeaponIndex, 100, 8, weaponAttribs)); 71 | 72 | new Handle:pack; 73 | CreateDataTimer(duration, normalMelee, pack, TIMER_DATA_HNDL_CLOSE); 74 | 75 | WritePackCell(pack, index); 76 | WritePackCell(pack, Boss); 77 | } 78 | 79 | public Action:normalMelee(Handle:timer, Handle:pack) 80 | { 81 | ResetPack(pack); 82 | new index=ReadPackCell(pack); 83 | new Boss=ReadPackCell(pack); 84 | 85 | FF2_GetAbilityArgumentString(index, this_plugin_name, "rage_tempMelee", 5, reWeaponAttribs, sizeof(reWeaponAttribs)); 86 | FF2_GetAbilityArgumentString(index, this_plugin_name, "rage_tempMelee", 6, reWeaponClass, sizeof(reWeaponClass)); 87 | reWeaponIndex = FF2_GetAbilityArgument(index, this_plugin_name, "rage_tempMelee", 7); 88 | 89 | TF2_RemoveWeaponSlot(Boss, TFWeaponSlot_Melee); 90 | SetEntPropEnt(Boss, Prop_Send, "m_hActiveWeapon", SpawnWeapon(Boss, reWeaponClass, reWeaponIndex, 1, 5, reWeaponAttribs)); 91 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/hudminmode.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #define MB 3 11 | #define ME 2048 12 | public Plugin:myinfo = { 13 | name = "Freak Fortress 2: Minimalist HUD", 14 | author = "MasterOfTheXP", 15 | version = "1.0", 16 | }; 17 | /* 18 | This sub-plugin lets clients have their boss information be printed to them in what some would consider a neater fashion. 19 | Bosses who enable this will see, on either the top or bottom of their screens, their health on the left and their rage on the right, as well as their jump charge in the center. 20 | */ 21 | 22 | new miniHUD[MAXPLAYERS + 1]; 23 | new Handle:HPHUD; 24 | new Handle:RageHUD; 25 | new Handle:ChargeHUD; 26 | 27 | public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max) 28 | { 29 | return APLRes_Success; 30 | } 31 | 32 | public OnPluginStart2() 33 | { 34 | RegConsoleCmd("ff2hud", Command_hud, "ff2hud - Enable/disable the minimalist HUD."); 35 | RegConsoleCmd("halehud", Command_hud, "halehud - Enable/disable the minimalist HUD."); 36 | RegConsoleCmd("ff2_mhud", Command_hud, "ff2_mhud - Enable/disable the minimalist HUD."); 37 | 38 | CreateTimer(0.1, Timer_Millisecond); 39 | HPHUD = CreateHudSynchronizer(); 40 | RageHUD = CreateHudSynchronizer(); 41 | ChargeHUD = CreateHudSynchronizer(); 42 | } 43 | 44 | public Action:Timer_Millisecond(Handle:timer) 45 | { 46 | CreateTimer(0.1, Timer_Millisecond); 47 | if (FF2_GetRoundState() != 1) return Plugin_Handled; 48 | for (new z = 1; z <= GetMaxClients(); z++) 49 | { 50 | if (IsClientInGame(z) && miniHUD[z] > 0) 51 | { 52 | new a_index = FF2_GetBossIndex(z); 53 | if (a_index != -1) // client is Hale 54 | { 55 | new Hale = z; 56 | SetGlobalTransTarget(Hale); 57 | new bool:hudIsDisabled = false; 58 | if (FF2_GetFF2flags(Hale) & FF2FLAG_HUDDISABLED) hudIsDisabled = true; 59 | if (!hudIsDisabled) FF2_SetFF2flags(Hale, FF2_GetFF2flags(Hale)|FF2FLAG_HUDDISABLED); 60 | new Float:yPos; 61 | new Rage = RoundFloat(FF2_GetBossCharge(a_index, 0)); 62 | new rageColour = 255; 63 | if (Rage == 100) rageColour = 64; 64 | if (miniHUD[Hale] == 1) yPos = 1.0; 65 | if (miniHUD[Hale] == 2) yPos = 0.0; 66 | SetHudTextParams(0.0, yPos, 0.2, 255, 255, 255, 255); 67 | ShowSyncHudText(Hale, HPHUD, "HP: %i", GetClientHealth(Hale)); 68 | SetHudTextParams(1.0, yPos, 0.2, 255, rageColour, rageColour, 255); 69 | if (Rage != 100 && Rage > 0) ShowSyncHudText(Hale, RageHUD, "RAGE: %i!", Rage); 70 | if (Rage < 1) ShowSyncHudText(Hale, RageHUD, "RAGE: %i", Rage); 71 | if (Rage == 100) ShowSyncHudText(Hale, RageHUD, "Press TAUNT to RAGE."); 72 | new Charge = RoundFloat(FF2_GetBossCharge(a_index, 1)); 73 | if (Charge > 0) 74 | { 75 | SetHudTextParams(-1.0, yPos, 0.2, 255, 255, 255, 255); 76 | ShowSyncHudText(Hale, ChargeHUD, "%i", Charge); 77 | } 78 | } 79 | } 80 | } 81 | return Plugin_Handled; 82 | } 83 | 84 | public Action:Command_hud(client, args) 85 | { 86 | if (client == 0) 87 | { 88 | PrintToServer("[FF2] The minimalist HUD cannot be enabled by Console."); 89 | return Plugin_Handled; 90 | } 91 | HUDMenu(client); 92 | return Plugin_Handled; 93 | } 94 | 95 | 96 | 97 | public Action:HUDMenu(client) 98 | { 99 | new Handle:smMenu = CreatePanel(); 100 | decl String:text[128]; 101 | SetGlobalTransTarget(client); 102 | Format(text, 128, "Turn the minimalist HUD for bosses..."); 103 | SetPanelTitle(smMenu, text); 104 | Format(text, 256, "On, place on bottom of screen"); 105 | DrawPanelItem(smMenu, text); 106 | Format(text, 256, "On, place at top of screen"); 107 | DrawPanelItem(smMenu, text); 108 | Format(text, 256, "Off, I want the normal boss HUD"); 109 | DrawPanelItem(smMenu, text); 110 | SendPanelToClient(smMenu, client, HUDSelector, MENU_TIME_FOREVER); 111 | CloseHandle(smMenu); 112 | return Plugin_Handled; 113 | } 114 | 115 | public HUDSelector(Handle:menu, MenuAction:action, client, p2) 116 | { 117 | if (action == MenuAction_Select) 118 | { 119 | if (p2 == 1 || p2 == 2) 120 | { 121 | miniHUD[client] = p2; 122 | CPrintToChat(client, "{olive}[FF2]{default} You've enabled the minimalist HUD."); 123 | if (FF2_GetBossIndex(client) == -1) CPrintToChat(client, "{olive}[FF2]{default} You'll see it the next time you're boss!"); 124 | } 125 | if (p2 == 3) 126 | { 127 | miniHUD[client] = 0; 128 | CPrintToChat(client, "{olive}[FF2]{default} You've disabled the minimalist HUD."); 129 | FF2_SetFF2flags(client, FF2_GetFF2flags(client)-FF2FLAG_HUDDISABLED); 130 | } 131 | else return; 132 | } 133 | } 134 | 135 | public OnClientPutInServer(client) 136 | { 137 | miniHUD[client] = 0; 138 | } 139 | 140 | public Action:FF2_OnAbility2(index, const String:plugin_name[], const String:ability_name[], action) 141 | { 142 | return Plugin_Continue; 143 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/km_lifeloss.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define SOUND_THEME_LIFE "freak_fortress_2/killingmann/theme_secondlife_fx.mp3" // life lost, will be stopped when round ends 12 | new g_theme_life; 13 | new theme_boss; 14 | 15 | #define THEME "change_theme_on_lifelose" 16 | #define INACTIVE 100000000.0 17 | 18 | public Plugin:myinfo = { 19 | name = "FF2: Killing Mann Change Theme on Lifelose", 20 | author = "M7", 21 | version = "1.0", 22 | }; 23 | 24 | public OnPluginStart2() 25 | { 26 | HookEvent("teamplay_round_start", event_round_start, EventHookMode_PostNoCopy); 27 | 28 | HookEvent("teamplay_round_active", event_round_active, EventHookMode_PostNoCopy); 29 | HookEvent("arena_round_start", event_round_active, EventHookMode_PostNoCopy); 30 | 31 | HookEvent("teamplay_round_win", event_round_end, EventHookMode_PostNoCopy); 32 | 33 | PrecacheSound(SOUND_THEME_LIFE); 34 | } 35 | 36 | public event_round_start(Handle:event, const String:name[], bool:dontBroadcast) 37 | { 38 | if(!FF2_IsFF2Enabled() || FF2_GetRoundState()!=1) 39 | return; 40 | 41 | g_theme_life = 0; 42 | theme_boss = 0; 43 | } 44 | 45 | public event_round_active(Handle:event, const String:name[], bool:dontBroadcast) 46 | { 47 | GetBossVars(); 48 | } 49 | 50 | GetBossVars() 51 | { 52 | if (FF2_HasAbility(0, this_plugin_name, THEME)) 53 | { 54 | new userid = FF2_GetBossUserId(0); 55 | new client = GetClientOfUserId(userid); 56 | if (client && IsClientInGame(client) && IsPlayerAlive(client)) 57 | { 58 | theme_boss = client; 59 | return; 60 | } 61 | } 62 | 63 | theme_boss = 0; 64 | } 65 | 66 | public event_round_end(Handle:event, const String:name[], bool:dontBroadcast) 67 | { 68 | for(new client=1;client<=MaxClients;client++) 69 | { 70 | if (IsValidClient(client)) 71 | { 72 | g_theme_life = 0; 73 | theme_boss = 0; 74 | StopSound(client, SNDCHAN_AUTO, SOUND_THEME_LIFE); 75 | } 76 | } 77 | } 78 | 79 | public Action:FF2_OnAbility2(boss, const String:plugin_name[], const String:ability_name[], status) 80 | { 81 | return Plugin_Continue; 82 | } 83 | 84 | public Action:FF2_OnLoseLife(index) 85 | { 86 | if (!g_theme_life && theme_boss && GetClientOfUserId(FF2_GetBossUserId(index)) == theme_boss && IsPlayerAlive(theme_boss)) 87 | { 88 | FF2_StopMusic(0); 89 | 90 | EmitSoundToAll(SOUND_THEME_LIFE); 91 | 92 | g_theme_life++; 93 | } 94 | return Plugin_Continue; 95 | } 96 | 97 | public Action:FF2_OnMusic(String:path[], &Float:time) 98 | { 99 | if (g_theme_life) 100 | { 101 | return Plugin_Stop; 102 | } 103 | 104 | return Plugin_Continue; 105 | } 106 | 107 | stock bool:IsValidClient(client, bool:isPlayerAlive=false) 108 | { 109 | if (client <= 0 || client > MaxClients) return false; 110 | if(isPlayerAlive) return IsClientInGame(client) && IsPlayerAlive(client); 111 | return IsClientInGame(client); 112 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/m7_customizable.sp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #pragma semicolon 1 7 | #pragma newdecls required 8 | 9 | #define CLIPLESS "rage_cliplessweapons" 10 | bool Clipless_TriggerAMS[MAXPLAYERS+1]; // global boolean to use with AMS 11 | char Attributes[125]; 12 | char Classname[64]; 13 | 14 | public Plugin myinfo = { 15 | name = "FF2 Ability: Customizable Clipless Weapons", 16 | author = "M7", 17 | }; 18 | 19 | public void OnPluginStart2() 20 | { 21 | HookEvent("arena_win_panel", Event_RoundEnd, EventHookMode_Pre); 22 | } 23 | 24 | public void FF2AMS_PreRoundStart(int client) 25 | { 26 | int boss = FF2_GetBossIndex(client); 27 | if(FF2_HasAbility(boss, this_plugin_name, CLIPLESS)) 28 | { 29 | Clipless_TriggerAMS[client]= FF2_GetAbilityArgument(boss, this_plugin_name, CLIPLESS, 7) != 0 30 | && FF2AMS_PushToAMS(client, this_plugin_name, CLIPLESS, "CLIP"); 31 | } 32 | } 33 | 34 | public Action Event_RoundEnd(Event event, const char[] name, bool dontBroadcast) 35 | { 36 | for(int client=1; client<=MaxClients; client++) 37 | { 38 | if(IsValidClient(client)) 39 | { 40 | Clipless_TriggerAMS[client]=false; 41 | } 42 | } 43 | } 44 | 45 | 46 | public Action FF2_OnAbility2(int boss,const char[] plugin_name,const char[] ability_name, int action) 47 | { 48 | int client=GetClientOfUserId(FF2_GetBossUserId(boss)); 49 | 50 | if(!strcmp(ability_name, CLIPLESS)) // Vaccinator resistances 51 | { 52 | Rage_Cliplessweapons(client); 53 | } 54 | return Plugin_Continue; 55 | } 56 | 57 | 58 | void Rage_Cliplessweapons(int client) 59 | { 60 | if(Clipless_TriggerAMS[client]) 61 | return; 62 | 63 | CLIP_Invoke(client, 0); 64 | } 65 | 66 | public AMSResult CLIP_CanInvoke(int client, int index) 67 | { 68 | return AMS_Accept; 69 | } 70 | 71 | public void CLIP_Invoke(int client, int index) 72 | { 73 | int boss=FF2_GetBossIndex(client); 74 | 75 | int Index = FF2_GetAbilityArgument(boss, this_plugin_name, CLIPLESS, 1); // weaponindex 76 | FF2_GetAbilityArgumentString(boss, this_plugin_name, CLIPLESS, 2, Classname, sizeof(Classname)); // weapon attribute 77 | FF2_GetAbilityArgumentString(boss, this_plugin_name, CLIPLESS, 3, Attributes, sizeof(Attributes)); // weapon classname 78 | int Ammo = FF2_GetAbilityArgument(boss, this_plugin_name, CLIPLESS, 5); // weaponindex 79 | int slot = FF2_GetAbilityArgument(boss, this_plugin_name, CLIPLESS, 6); 80 | 81 | TF2_RemoveWeaponSlot(client, slot); 82 | 83 | SetEntPropEnt(client, Prop_Send, "m_hActiveWeapon", SpawnWeapon(client, Classname, Index, 100, 5, Attributes), FF2_GetAbilityArgument(boss, this_plugin_name, CLIPLESS, 4) != 0); 84 | 85 | if(Ammo) 86 | { 87 | SetAmmo(client, slot, Ammo); 88 | } 89 | 90 | if(Clipless_TriggerAMS[client]) 91 | { 92 | char snd[PLATFORM_MAX_PATH]; 93 | if(FF2_RandomSound("sound_clipless_weapon", snd, sizeof(snd), boss)) 94 | { 95 | EmitSoundToAll(snd, client); 96 | EmitSoundToAll(snd, client); 97 | } 98 | } 99 | } 100 | 101 | stock int SpawnWeapon(int client,char[] name, int index, int level, int qual, char[] att, bool isVisible=false) 102 | { 103 | Handle hWeapon = TF2Items_CreateItem(OVERRIDE_ALL|FORCE_GENERATION); 104 | TF2Items_SetClassname(hWeapon, name); 105 | TF2Items_SetItemIndex(hWeapon, index); 106 | TF2Items_SetLevel(hWeapon, level); 107 | TF2Items_SetQuality(hWeapon, qual); 108 | char atts[32][32]; 109 | int count = ExplodeString(att, " ; ", atts, 32, 32); 110 | if (count > 0) 111 | { 112 | TF2Items_SetNumAttributes(hWeapon, count/2); 113 | int i2 = 0; 114 | for (int i = 0; i < count; i+=2) 115 | { 116 | TF2Items_SetAttribute(hWeapon, i2, StringToInt(atts[i]), StringToFloat(atts[i+1])); 117 | i2++; 118 | } 119 | } 120 | else 121 | TF2Items_SetNumAttributes(hWeapon, 0); 122 | if (hWeapon==INVALID_HANDLE) 123 | return -1; 124 | int entity = TF2Items_GiveNamedItem(client, hWeapon); 125 | delete hWeapon; 126 | 127 | if(!isVisible) 128 | { 129 | SetEntProp(entity, Prop_Send, "m_iWorldModelIndex", -1); 130 | SetEntPropFloat(entity, Prop_Send, "m_flModelScale", 0.001); 131 | } 132 | #if defined _FF2_Extras_included 133 | else 134 | { 135 | PrepareWeapon(entity); 136 | } 137 | #endif 138 | 139 | EquipPlayerWeapon(client, entity); 140 | return entity; 141 | } 142 | 143 | stock void SetAmmo(int client, int slot, int ammo) 144 | { 145 | int weapon = GetPlayerWeaponSlot(client, slot); 146 | if (IsValidEntity(weapon)) 147 | { 148 | int iOffset = GetEntProp(weapon, Prop_Send, "m_iPrimaryAmmoType", 1)*4; 149 | static int iAmmoTable = 0; 150 | if(!iAmmoTable) { 151 | iAmmoTable = FindSendPropInfo("CTFPlayer", "m_iAmmo"); 152 | } 153 | SetEntData(client, iAmmoTable+iOffset, ammo, 4, true); 154 | } 155 | } 156 | 157 | stock bool IsValidClient(int client) 158 | { 159 | if (client <= 0 || client > MaxClients) 160 | return false; 161 | 162 | return IsClientInGame(client); 163 | } 164 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/monochromatic.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #pragma newdecls required 11 | 12 | #define VERSION_NUMBER "1.00" 13 | 14 | public Plugin myinfo = { 15 | name = "Freak Fortress 2: Monochromatic", 16 | description = "The following has been brought to you in black and white", 17 | author = "Koishi", 18 | version = VERSION_NUMBER, 19 | }; 20 | 21 | public void OnPluginStart2() 22 | { 23 | HookEvent("arena_round_start", Event_RoundStart); 24 | HookEvent("teamplay_round_active", Event_RoundStart); // for non-arena maps 25 | 26 | HookEvent("arena_win_panel", Event_RoundEnd); 27 | HookEvent("teamplay_round_win", Event_RoundEnd); // for non-arena maps 28 | 29 | if(FF2_GetRoundState()==1) 30 | { 31 | PrepareAbilities(); 32 | } 33 | } 34 | 35 | public void Event_RoundStart(Event event, const char[] name, bool dontBroadcast) 36 | { 37 | PrepareAbilities(); 38 | } 39 | 40 | stock void SetMonochrome(int client, bool enable) 41 | { 42 | int flags=GetCommandFlags("r_screenoverlay") & (~FCVAR_CHEAT); 43 | SetCommandFlags("r_screenoverlay", flags); 44 | ClientCommand(client, "r_screenoverlay \"%s\"", enable ? "debug/yuv" : ""); 45 | } 46 | 47 | public void Event_RoundEnd(Event event, const char[] name, bool dontBroadcast) 48 | { 49 | for(int client=MaxClients;client;client--) 50 | { 51 | if(client<=0||client>MaxClients||!IsClientInGame(client)) 52 | { 53 | continue; 54 | } 55 | SetMonochrome(client, false); 56 | } 57 | } 58 | 59 | public void PrepareAbilities() 60 | { 61 | 62 | int mode=0; 63 | for(int client=MaxClients;client;client--) 64 | { 65 | if(client<=0||client>MaxClients||!IsClientInGame(client)) 66 | { 67 | continue; 68 | } 69 | 70 | int boss=FF2_GetBossIndex(client); 71 | if(boss>=0) 72 | { 73 | if(FF2_HasAbility(boss, this_plugin_name, "monochrome")) 74 | { 75 | mode=FF2_GetAbilityArgument(boss, this_plugin_name, "monochrome", 1); 76 | if(mode==1) 77 | { 78 | SetMonochrome(client, true); 79 | } 80 | } 81 | } 82 | 83 | if(mode==2 && FF2_GetBossIndex(client)==-1 || mode==3) 84 | { 85 | SetMonochrome(client, true); 86 | } 87 | } 88 | } 89 | 90 | public void FF2_OnAbility2(int boss,const char[] plugin_name,const char[] ability_name,int status) 91 | { 92 | return; 93 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/overlay_on_kill.sp: -------------------------------------------------------------------------------- 1 | /* 2 | overlay_on_kill: 3 | arg1 - path to overlay ("root" is \tf\materials\) 4 | arg2 - duration (def.6) 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #pragma semicolon 1 13 | #pragma newdecls required 14 | 15 | #define PLUGIN_VERSION "1.4" 16 | 17 | float RemoveOverlayAt[MAXPLAYERS+1]; 18 | #define INACTIVE 100000000.0 19 | 20 | public Plugin myinfo= 21 | { 22 | name="Freak Fortress 2: Overlay on Kill", 23 | author="Jery0987, RainBolt Dash, SHADoW NiNE TR3S", 24 | description="FF2: Same as rage_overlay but when a player is killed.", 25 | version=PLUGIN_VERSION, 26 | }; 27 | 28 | public void OnPluginStart2() 29 | { 30 | HookEvent("arena_round_start", Event_RoundStart); 31 | HookEvent("player_death", Event_PlayerDeath); 32 | HookEvent("arena_win_panel", Event_WinPanel); 33 | } 34 | 35 | public Action FF2_OnAbility2(int boss, const char[] plugin_name, const char[] ability_name, int status) 36 | { 37 | // NOOP 38 | } 39 | 40 | public Action Event_PlayerDeath(Event event, const char[] name, bool dontBroadcast) 41 | { 42 | int attacker=GetClientOfUserId(GetEventInt(event, "attacker")); 43 | int client=GetClientOfUserId(GetEventInt(event, "userid")); 44 | int boss=FF2_GetBossIndex(attacker); 45 | if(boss>=0) 46 | { 47 | static char overlay[PLATFORM_MAX_PATH]; 48 | FF2_GetAbilityArgumentString(boss, this_plugin_name, "overlay_on_kill", 1, overlay, PLATFORM_MAX_PATH); 49 | Format(overlay, PLATFORM_MAX_PATH, "r_screenoverlay \"%s\"", overlay); 50 | SetCommandFlags("r_screenoverlay", GetCommandFlags("r_screenoverlay") & ~FCVAR_CHEAT); 51 | float duration=FF2_GetAbilityArgumentFloat(boss, this_plugin_name, "overlay_on_kill", 2, 6.0); 52 | if(IsValidPlayer(client) && GetClientTeam(client)!=FF2_GetBossTeam()) 53 | { 54 | if(duration) 55 | { 56 | RemoveOverlayAt[client]=GetGameTime()+duration; 57 | } 58 | ClientCommand(client, overlay); 59 | SDKHook(client, SDKHook_PreThink, ShowOverlay_PreThink); 60 | } 61 | SetCommandFlags("r_screenoverlay", GetCommandFlags("r_screenoverlay") & FCVAR_CHEAT); 62 | } 63 | } 64 | 65 | public void ShowOverlay_PreThink(int client) 66 | { 67 | if(FF2_GetRoundState()!=1 || !IsValidPlayer(client)) 68 | { 69 | SDKUnhook(client, SDKHook_PreThink, ShowOverlay_PreThink); 70 | } 71 | TimerTick(client, GetGameTime()); 72 | } 73 | public void TimerTick(int client, float gameTime) 74 | { 75 | if(gameTime>=RemoveOverlayAt[client]) 76 | { 77 | SetCommandFlags("r_screenoverlay", GetCommandFlags("r_screenoverlay") & ~FCVAR_CHEAT); 78 | if(IsValidPlayer(client)) 79 | { 80 | ClientCommand(client, "r_screenoverlay \"\""); 81 | } 82 | SetCommandFlags("r_screenoverlay", GetCommandFlags("r_screenoverlay") & FCVAR_CHEAT); 83 | RemoveOverlayAt[client]=INACTIVE; 84 | } 85 | } 86 | 87 | public Action Event_RoundStart(Event event, const char[] name, bool dontBroadcast) 88 | { 89 | for(int client=1;client<=MaxClients;client++) 90 | { 91 | RemoveOverlayAt[client]=INACTIVE; 92 | } 93 | } 94 | 95 | public Action Event_WinPanel(Event event, const char[] name, bool dontBroadcast) 96 | { 97 | for(int client=1;client<=MaxClients;client++) 98 | { 99 | SetCommandFlags("r_screenoverlay", GetCommandFlags("r_screenoverlay") & ~FCVAR_CHEAT); 100 | if(IsValidPlayer(client)) 101 | { 102 | ClientCommand(client, "r_screenoverlay \"\""); 103 | } 104 | SetCommandFlags("r_screenoverlay", GetCommandFlags("r_screenoverlay") & FCVAR_CHEAT); 105 | RemoveOverlayAt[client]=INACTIVE; 106 | SDKUnhook(client, SDKHook_PreThink, ShowOverlay_PreThink); 107 | } 108 | } 109 | 110 | stock bool IsValidPlayer(int client) 111 | { 112 | if (client <= 0 || client > MaxClients) 113 | return false; 114 | 115 | return IsClientInGame(client); 116 | } 117 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/rage_overlay.sp: -------------------------------------------------------------------------------- 1 | /* 2 | rage_overlay: arg0 - slot (def.0) 3 | arg1 - path to overlay ("root" is \tf\materials\) 4 | arg2 - duration (def.6) 5 | */ 6 | #pragma semicolon 1 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #pragma newdecls required 15 | 16 | #define PLUGIN_VERSION "1.9.3" 17 | 18 | public Plugin myinfo= 19 | { 20 | name="Freak Fortress 2: rage_overlay", 21 | author="Jery0987, RainBolt Dash", 22 | description="FF2: Ability that covers all living, non-boss team players screens with an image", 23 | version=PLUGIN_VERSION, 24 | }; 25 | 26 | public void OnPluginStart2() 27 | { 28 | HookEvent("teamplay_round_start", OnRoundStart); 29 | } 30 | 31 | public Action OnRoundStart(Handle event, const char[] name, bool dontBroadcast) 32 | { 33 | return Plugin_Continue; 34 | } 35 | 36 | public Action FF2_OnAbility2(int boss, const char[] plugin_name, const char[] ability_name, int status) 37 | { 38 | if(!StrContains(ability_name, "rage_overlay")) 39 | { 40 | Rage_Overlay(boss, ability_name); 41 | } 42 | return Plugin_Continue; 43 | } 44 | 45 | void Rage_Overlay(int boss, const char[] ability_name) 46 | { 47 | char overlay[PLATFORM_MAX_PATH]; 48 | int client=GetClientOfUserId(FF2_GetBossUserId(boss)); 49 | FF2_GetArgS(boss, this_plugin_name, ability_name, "path", 1, overlay, sizeof(overlay)); 50 | Format(overlay, sizeof(overlay), "r_screenoverlay \"%s\"", overlay); 51 | SetCommandFlags("r_screenoverlay", GetCommandFlags("r_screenoverlay") & ~FCVAR_CHEAT); 52 | for(int target=1; target<=MaxClients; target++) 53 | { 54 | if(IsClientInGame(target) && IsPlayerAlive(target) && TF2_GetClientTeam(target)!=TF2_GetClientTeam(client)) 55 | { 56 | ClientCommand(target, overlay); 57 | } 58 | } 59 | 60 | CreateTimer(FF2_GetArgF(boss, this_plugin_name, ability_name, "duration", 2, 6.0), Timer_Remove_Overlay, TF2_GetClientTeam(client), TIMER_FLAG_NO_MAPCHANGE); 61 | SetCommandFlags("r_screenoverlay", GetCommandFlags("r_screenoverlay") & FCVAR_CHEAT); 62 | } 63 | 64 | public Action Timer_Remove_Overlay(Handle timer, TFTeam boss_team_num) 65 | { 66 | SetCommandFlags("r_screenoverlay", GetCommandFlags("r_screenoverlay") & ~FCVAR_CHEAT); 67 | for(int target=1; target<=MaxClients; target++) 68 | { 69 | if(IsClientInGame(target) && IsPlayerAlive(target) && TF2_GetClientTeam(target)!=boss_team_num) 70 | { 71 | ClientCommand(target, "r_screenoverlay off"); 72 | } 73 | } 74 | SetCommandFlags("r_screenoverlay", GetCommandFlags("r_screenoverlay") & FCVAR_CHEAT); 75 | return Plugin_Continue; 76 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/rage_overlay_2.sp: -------------------------------------------------------------------------------- 1 | /* 2 | rage_overlay_v2: arg0 - slot (def.0) 3 | arg1 - number of overlays 4 | arg2 - path to overlay 1 ("root" is \tf\materials\) 5 | arg3 - duration 1 (def.6) 6 | arg4 - path to overlay 2 ("root" is \tf\materials\) 7 | arg5 - duration 2 (def.6) 8 | etc. 9 | */ 10 | 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #pragma semicolon 1 17 | #pragma newdecls required 18 | 19 | int BossTeam = view_as(TFTeam_Blue); 20 | 21 | #define PLUGIN_VERSION "2.0.0" 22 | 23 | public Plugin myinfo= 24 | { 25 | name="Freak Fortress 2: rage_overlay_2", 26 | author="Jery0987, RainBolt Dash, Naydef", 27 | description="FF2: Ability that covers all living, non-boss team players screens with an image, now with option to use more than 1 image", 28 | version=PLUGIN_VERSION, 29 | }; 30 | 31 | public void OnPluginStart2() 32 | { 33 | HookEvent("teamplay_round_start", OnRoundStart); 34 | } 35 | 36 | public Action OnRoundStart(Event event, const char[] name, bool dontBroadcast) 37 | { 38 | CreateTimer(0.3, Timer_GetBossTeam, _, TIMER_FLAG_NO_MAPCHANGE); 39 | return Plugin_Continue; 40 | } 41 | 42 | public Action Timer_GetBossTeam(Handle hTimer) 43 | { 44 | BossTeam=FF2_GetBossTeam(); 45 | return Plugin_Continue; 46 | } 47 | 48 | public Action FF2_OnAbility2(int boss, const char[] plugin_name, const char[] ability_name, int status) 49 | { 50 | if(!strcmp(ability_name, "rage_overlay_v2")) 51 | { 52 | Rage_Overlay(boss, ability_name); 53 | } 54 | return Plugin_Continue; 55 | } 56 | 57 | void Rage_Overlay(int boss, const char[] ability_name) 58 | { 59 | char overlay[PLATFORM_MAX_PATH]; 60 | char buffer[PLATFORM_MAX_PATH]; 61 | 62 | int numberofsounds=FF2_GetAbilityArgument(boss, this_plugin_name, ability_name, 1, -1); 63 | if(numberofsounds<=0) 64 | { 65 | FF2_GetBossSpecial(boss, buffer, sizeof(buffer), 0); 66 | LogError("[FF2 Overlay v2] Sounds less than 1 | Boss %s", buffer); 67 | return; 68 | } 69 | 70 | int random=2*GetRandomInt(1, numberofsounds); // Only even numbers 71 | 72 | 73 | FF2_GetAbilityArgumentString(boss, this_plugin_name, ability_name, random , buffer, sizeof(buffer)); 74 | if(!buffer[0]) 75 | { 76 | FF2_GetBossSpecial(boss, buffer, sizeof(buffer), 0); 77 | LogError("[FF2 Overlay v2] Sound string is NULL! | Boss: %s", buffer); 78 | return; 79 | } 80 | 81 | Format(overlay, sizeof(overlay), "r_screenoverlay \"%s\"", buffer); 82 | SetCommandFlags("r_screenoverlay", GetCommandFlags("r_screenoverlay") & ~FCVAR_CHEAT); 83 | for(int target=1; target<=MaxClients; target++) 84 | { 85 | if(IsClientInGame(target) && IsPlayerAlive(target) && GetClientTeam(target)!=BossTeam) 86 | { 87 | ClientCommand(target, overlay); 88 | } 89 | } 90 | 91 | CreateTimer(FF2_GetAbilityArgumentFloat(boss, this_plugin_name, ability_name, random+1, 6.0), Timer_Remove_Overlay, _, TIMER_FLAG_NO_MAPCHANGE); 92 | SetCommandFlags("r_screenoverlay", GetCommandFlags("r_screenoverlay") & FCVAR_CHEAT); 93 | } 94 | 95 | public Action Timer_Remove_Overlay(Handle timer) 96 | { 97 | SetCommandFlags("r_screenoverlay", GetCommandFlags("r_screenoverlay") & ~FCVAR_CHEAT); 98 | for(int target=1; target<=MaxClients; target++) 99 | { 100 | if(IsClientInGame(target) && IsPlayerAlive(target) && GetClientTeam(target)!=BossTeam) 101 | { 102 | ClientCommand(target, "r_screenoverlay \"\""); 103 | } 104 | } 105 | SetCommandFlags("r_screenoverlay", GetCommandFlags("r_screenoverlay") & FCVAR_CHEAT); 106 | return Plugin_Continue; 107 | } 108 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/s93_bowrage.sp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #pragma semicolon 1 8 | #pragma newdecls required 9 | 10 | bool AMSOnly[MAXPLAYERS+1]=false; 11 | int alives = 0; 12 | 13 | public Plugin myinfo = { 14 | name = "Freak Fortress 2: Simple Custom Bowrage", 15 | author = "Koishi", 16 | version = "1.2" 17 | }; 18 | 19 | public void OnPluginStart2() { 20 | } 21 | 22 | public void FF2AMS_PreRoundStart(int client) 23 | { 24 | int boss = FF2_GetBossIndex(client); 25 | if(FF2_HasAbility(boss, this_plugin_name, "rage_new_bowrage")) { 26 | AMSOnly[client] = FF2AMS_PushToAMS(client, this_plugin_name, "rage_new_bowrage", "BOW"); 27 | } 28 | } 29 | 30 | public Action FF2_OnAbility2(int boss, const char[] plugin_name, const char[] ability_name, int action) 31 | { 32 | int client=GetClientOfUserId(FF2_GetBossUserId(boss)); 33 | if(strcmp(ability_name, "rage_new_bowrage") && !AMSOnly[client]) 34 | { 35 | BOW_Invoke(client, -1); // Standard Bowrage 36 | } 37 | return Plugin_Continue; 38 | } 39 | 40 | stock int SpawnWeapon(int client, char[] name, int index, int level, int qual, char[] att) 41 | { 42 | Handle hWeapon = TF2Items_CreateItem(OVERRIDE_ALL|FORCE_GENERATION); 43 | TF2Items_SetClassname(hWeapon, name); 44 | TF2Items_SetItemIndex(hWeapon, index); 45 | TF2Items_SetLevel(hWeapon, level); 46 | TF2Items_SetQuality(hWeapon, qual); 47 | char atts[32][32]; 48 | int count = ExplodeString(att, " ; ", atts, 32, 32); 49 | if (count > 0) 50 | { 51 | TF2Items_SetNumAttributes(hWeapon, count/2); 52 | int i2 = 0; 53 | for (int i = 0; i < count; i+=2) 54 | { 55 | TF2Items_SetAttribute(hWeapon, i2, StringToInt(atts[i]), StringToFloat(atts[i+1])); 56 | i2++; 57 | } 58 | } 59 | else 60 | TF2Items_SetNumAttributes(hWeapon, 0); 61 | if (hWeapon==INVALID_HANDLE) 62 | return -1; 63 | int entity = TF2Items_GiveNamedItem(client, hWeapon); 64 | delete hWeapon; 65 | EquipPlayerWeapon(client, entity); 66 | return entity; 67 | } 68 | 69 | stock void SetAmmo(int client, int slot, int ammo) 70 | { 71 | int weapon = GetPlayerWeaponSlot(client, slot); 72 | if (IsValidEntity(weapon)) 73 | { 74 | int iOffset = GetEntProp(weapon, Prop_Send, "m_iPrimaryAmmoType", 1)*4; 75 | static int iAmmoTable = 0; 76 | if(!iAmmoTable) { 77 | iAmmoTable = FindSendPropInfo("CTFPlayer", "m_iAmmo"); 78 | } 79 | SetEntData(client, iAmmoTable+iOffset, ammo, 4, true); 80 | } 81 | } 82 | 83 | public void BOW_Invoke(int client, int index) 84 | { 85 | int weapon; 86 | char attributes[126] = ""; 87 | int boss=FF2_GetBossIndex(client); 88 | int bowtype=FF2_GetAbilityArgument(boss,this_plugin_name,"rage_new_bowrage", 1); // Bow type? (0: Huntsman, 1: Festive Huntsman, 2: Fortified Compound, 3: Crusader's Crossbow, 4: Festive Crusader's crossbow) 89 | int kson=FF2_GetAbilityArgument(boss,this_plugin_name,"rage_new_bowrage", 2); // Killstreaks? (0: Off, 1: On) 90 | int ammo=FF2_GetAbilityArgument(boss,this_plugin_name,"rage_new_bowrage", 3); // Ammo amount (0 will match to # of alive players) 91 | int clip=FF2_GetAbilityArgument(boss,this_plugin_name,"rage_new_bowrage", 4); // Clip amount 92 | 93 | FF2_GetAbilityArgumentString(boss, this_plugin_name, "rage_new_bowrage", 5, attributes, sizeof(attributes)); 94 | if(kson) { 95 | StrCat(attributes, sizeof(attributes), attributes[0] == '\0' ? "2025 ; 1":" ; 2025 ; 1"); 96 | } 97 | TF2_RemoveWeaponSlot(client, TFWeaponSlot_Primary); 98 | switch(bowtype) 99 | { 100 | case 1: 101 | weapon = SpawnWeapon(client, "tf_weapon_compound_bow", 1005, 101, 5, attributes); 102 | case 2: 103 | weapon = SpawnWeapon(client, "tf_weapon_compound_bow", 1092, 101, 5, attributes); 104 | case 3: 105 | weapon = SpawnWeapon(client, "tf_weapon_crossbow", 305, 101, 5, attributes); 106 | case 4: 107 | weapon = SpawnWeapon(client, "tf_weapon_crossbow", 1079, 101, 5, attributes); 108 | default: 109 | weapon = SpawnWeapon(client, "tf_weapon_compound_bow", 56, 101, 5, attributes); 110 | } 111 | SetEntPropEnt(client, Prop_Send, "m_hActiveWeapon", weapon); 112 | if(ammo<0) 113 | ammo = alives; 114 | if(ammo) 115 | SetAmmo(client, weapon , ammo); 116 | if(clip) 117 | SetEntProp(weapon, Prop_Send, "m_iClip1", clip); 118 | } 119 | 120 | public void FF2_OnAlivePlayersChanged(int players, int bosses) 121 | { 122 | alives = players + bosses; 123 | } 124 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/saitama.sp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #pragma semicolon 1 8 | #pragma newdecls required 9 | 10 | bool Saitama = false; 11 | 12 | public Plugin myinfo = { 13 | name = "One Punch Man", 14 | author = "M7", 15 | version = "1.0", 16 | }; 17 | 18 | public void OnPluginStart2() 19 | { 20 | HookEvent("arena_round_start", Event_RoundStart, EventHookMode_Post); 21 | HookEvent("arena_win_panel", Event_RoundEnd, EventHookMode_Post); 22 | 23 | for(int i=1; i<=MaxClients; i++) 24 | { 25 | if(IsClientInGame(i)) 26 | { 27 | SDKHook(i, SDKHook_OnTakeDamagePost, OnTakeDamagePost); 28 | } 29 | } 30 | } 31 | 32 | public void OnClientPutInServer(int client) 33 | { 34 | SDKHook(client, SDKHook_OnTakeDamagePost, OnTakeDamagePost); 35 | } 36 | 37 | public void Event_RoundStart(Event hEvent, const char[] strName, bool bDontBroadcast) 38 | { 39 | if(!FF2_IsFF2Enabled() || FF2_GetRoundState()!=1) 40 | return; 41 | 42 | for(int iBoss = 0; iBoss <= MaxClients; iBoss++) 43 | { 44 | if(FF2_HasAbility(iBoss, this_plugin_name, "One_Punch_Man")) 45 | { 46 | Saitama = true; 47 | } 48 | } 49 | } 50 | 51 | public void OnTakeDamagePost(int victim, int attacker, int inflictor, 52 | float damage, int damagetype, int weapon, 53 | const float damageForce[3], const float damagePosition[3], int damagecustom) 54 | { 55 | if(Saitama && victim != attacker && attacker > 0 && attacker <= MaxClients && IsClientInGame(attacker) && GetClientTeam(attacker) == FF2_GetBossTeam()) 56 | { 57 | FakeClientCommand(victim, "Explode"); // ff2's ontakedamage also hits here if we used ontakedamage.... 58 | } 59 | } 60 | 61 | public void Event_RoundEnd(Event hEvent, const char[] strName, bool bDontBroadcast) 62 | { 63 | Saitama = false; 64 | } 65 | 66 | public void FF2_OnAbility2(int iBoss, const char[] pluginName, const char[] abilityName, int iStatus){} 67 | 68 | stock bool IsValidClient(int client) 69 | { 70 | if (client <= 0 || client > MaxClients) 71 | return false; 72 | 73 | return IsClientInGame(client); 74 | } 75 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/socold_fix.sp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #pragma semicolon 1 6 | #pragma newdecls required 7 | 8 | #define BARON_LIFE "freak_fortress_2/blackbaron/socoldfix.mp3" // life lost, will be stopped when round ends 9 | int g_baron_life; 10 | int baron_boss; 11 | 12 | #define BARON "instrumental_to_vocal" 13 | #define INACTIVE 100000000.0 14 | 15 | public Plugin myinfo = { 16 | name = "Change Theme on Lifelose", 17 | author = "M7", 18 | version = "1.0", 19 | }; 20 | 21 | public void OnPluginStart2() 22 | { 23 | HookEvent("teamplay_round_start", event_round_start, EventHookMode_PostNoCopy); 24 | 25 | HookEvent("teamplay_round_active", event_round_active, EventHookMode_PostNoCopy); 26 | HookEvent("arena_round_start", event_round_active, EventHookMode_PostNoCopy); 27 | 28 | HookEvent("teamplay_round_win", event_round_end, EventHookMode_PostNoCopy); 29 | 30 | PrecacheSound(BARON_LIFE); 31 | } 32 | 33 | public void event_round_start(Event event, const char[] name, bool dontBroadcast) 34 | { 35 | if(!FF2_IsFF2Enabled() || FF2_GetRoundState()!=1) 36 | return; 37 | 38 | g_baron_life = 0; 39 | baron_boss = 0; 40 | } 41 | 42 | public void event_round_active(Event event, const char[] name, bool dontBroadcast) 43 | { 44 | GetBossVars(); 45 | } 46 | 47 | void GetBossVars() 48 | { 49 | if (FF2_HasAbility(0, this_plugin_name, BARON)) 50 | { 51 | int userid = FF2_GetBossUserId(0); 52 | int client = GetClientOfUserId(userid); 53 | if (client && IsClientInGame(client) && IsPlayerAlive(client)) 54 | { 55 | baron_boss = client; 56 | return; 57 | } 58 | } 59 | 60 | baron_boss = 0; 61 | } 62 | 63 | public void event_round_end(Event event, const char[] name, bool dontBroadcast) 64 | { 65 | for(int client=1;client<=MaxClients;client++) 66 | { 67 | if (IsValidClient(client)) 68 | { 69 | g_baron_life = 0; 70 | baron_boss = 0; 71 | StopSound(client, SNDCHAN_AUTO, BARON_LIFE); 72 | } 73 | } 74 | } 75 | 76 | public Action FF2_OnAbility2(int boss, const char[] plugin_name, const char[] ability_name, int status) 77 | { 78 | return Plugin_Continue; 79 | } 80 | 81 | public Action FF2_OnLoseLife(int index, int& lives, int maxLives) 82 | { 83 | if (!g_baron_life && baron_boss && GetClientOfUserId(FF2_GetBossUserId(index)) == baron_boss && IsPlayerAlive(baron_boss)) 84 | { 85 | FF2_StopMusic(0); 86 | 87 | EmitSoundToAll(BARON_LIFE); 88 | 89 | g_baron_life++; 90 | } 91 | return Plugin_Continue; 92 | } 93 | 94 | public Action FF2_OnMusic(char[] path, float& time) 95 | { 96 | if (g_baron_life) 97 | { 98 | return Plugin_Stop; 99 | } 100 | 101 | return Plugin_Continue; 102 | } 103 | 104 | stock bool IsValidClient(int client, bool isPlayerAlive=false) 105 | { 106 | if (client <= 0 || client > MaxClients) return false; 107 | if(isPlayerAlive) return IsClientInGame(client) && IsPlayerAlive(client); 108 | return IsClientInGame(client); 109 | } 110 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/special_ams_overlay.sp: -------------------------------------------------------------------------------- 1 | /* 2 | rage_ams_overlay: arg0 - slot (def.0) 3 | arg1 - path to overlay ("root" is \tf\materials\) 4 | arg2 - duration (def.6) 5 | */ 6 | #pragma semicolon 1 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #pragma newdecls required 14 | 15 | public Plugin myinfo = 16 | { 17 | name="Freak Fortress 2: Overlay Rage for AMS", 18 | author="M76030", 19 | description="The Stock FF2 ability rage_overlay, now compatible with AMS", 20 | version="1.0.0", 21 | }; 22 | 23 | #define OVERLAY "rage_ams_overlay" 24 | bool Overlay_TriggerAMS[MAXPLAYERS+1]; // global boolean to use with AMS 25 | 26 | public void OnPluginStart2() 27 | { 28 | HookEvent("arena_win_panel", event_round_end, EventHookMode_PostNoCopy); 29 | } 30 | 31 | public void FF2AMS_PreRoundStart(int client) 32 | { 33 | if(FF2_HasAbility(FF2_GetBossIndex(client), this_plugin_name, OVERLAY)) 34 | { 35 | Overlay_TriggerAMS[client] = FF2AMS_PushToAMS(client, this_plugin_name, OVERLAY, "RAOV"); 36 | } 37 | } 38 | 39 | public Action event_round_end(Event event, const char[] name, bool dontBroadcast) 40 | { 41 | for(int client=1;client<=MaxClients;client++) 42 | { 43 | if (IsValidClient(client)) 44 | { 45 | Overlay_TriggerAMS[client] = false; 46 | } 47 | } 48 | } 49 | 50 | public Action FF2_OnAbility2(int boss, const char[] plugin_name, const char[] ability_name, int status) 51 | { 52 | if(!FF2_IsFF2Enabled() || FF2_GetRoundState()!=1) 53 | return Plugin_Continue; // Because some FF2 forks still allow RAGE to be activated when the round is over.... 54 | 55 | int client=GetClientOfUserId(FF2_GetBossUserId(boss)); 56 | if(!strcmp(ability_name, OVERLAY)) // Defenses 57 | { 58 | if(!LibraryExists("FF2AMS")) 59 | { 60 | Overlay_TriggerAMS[client]=false; 61 | } 62 | 63 | if(!Overlay_TriggerAMS[client]) 64 | RAOV_Invoke(client, -1); 65 | } 66 | return Plugin_Continue; 67 | } 68 | 69 | public AMSResult RAOV_CanInvoke(int client, int index) 70 | { 71 | return AMS_Accept; 72 | } 73 | 74 | public void RAOV_Invoke(int client, int index) 75 | { 76 | int boss=FF2_GetBossIndex(client); 77 | 78 | char overlay[PLATFORM_MAX_PATH]; 79 | FF2_GetAbilityArgumentString(boss, this_plugin_name, OVERLAY, 1, overlay, PLATFORM_MAX_PATH); 80 | 81 | if(Overlay_TriggerAMS[client]) 82 | { 83 | static char sound[PLATFORM_MAX_PATH]; 84 | if(FF2_RandomSound("sound_ams_overlay", sound, sizeof(sound), boss)) 85 | { 86 | EmitSoundToAll(sound, client); 87 | EmitSoundToAll(sound, client); 88 | } 89 | } 90 | 91 | Format(overlay, PLATFORM_MAX_PATH, "r_screenoverlay \"%s\"", overlay); 92 | SetCommandFlags("r_screenoverlay", GetCommandFlags("r_screenoverlay") & ~FCVAR_CHEAT); 93 | for(int target=1; target<=MaxClients; target++) 94 | { 95 | if(IsClientInGame(target) && IsPlayerAlive(target) && GetClientTeam(target)!=FF2_GetBossTeam()) 96 | { 97 | ClientCommand(target, overlay); 98 | } 99 | } 100 | 101 | CreateTimer(FF2_GetAbilityArgumentFloat(boss, this_plugin_name, OVERLAY, 2, 6.0), Timer_Remove_Overlay, _, TIMER_FLAG_NO_MAPCHANGE); 102 | SetCommandFlags("r_screenoverlay", GetCommandFlags("r_screenoverlay") & FCVAR_CHEAT); 103 | } 104 | 105 | public Action Timer_Remove_Overlay(Handle timer) 106 | { 107 | SetCommandFlags("r_screenoverlay", GetCommandFlags("r_screenoverlay") & ~FCVAR_CHEAT); 108 | for(int target=1; target<=MaxClients; target++) 109 | { 110 | if(IsClientInGame(target) && IsPlayerAlive(target) && GetClientTeam(target)!=FF2_GetBossTeam()) 111 | { 112 | ClientCommand(target, "r_screenoverlay \"\""); 113 | } 114 | } 115 | SetCommandFlags("r_screenoverlay", GetCommandFlags("r_screenoverlay") & FCVAR_CHEAT); 116 | return Plugin_Continue; 117 | } 118 | 119 | stock bool IsValidClient(int client) 120 | { 121 | if (client <= 0 || client > MaxClients) return false; 122 | if (!IsClientInGame(client) || !IsClientConnected(client)) return false; 123 | if (IsClientSourceTV(client) || IsClientReplay(client)) return false; 124 | return true; 125 | } 126 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/freaks/special_noanims.sp: -------------------------------------------------------------------------------- 1 | /* 2 | special_noanims: arg0 - unused. 3 | arg1 - 1=Custom Model Rotates (def.0) 4 | 5 | rage_new_weapon: arg0 - slot (def.0) 6 | arg1 - weapon's classname 7 | arg2 - weapon's index 8 | arg3 - weapon's attributes 9 | arg4 - weapon's slot (0 - primary. 1 - secondary. 2 - melee. 3 - pda. 4 - spy's watches) 10 | arg5 - weapon's ammo (set to 1 for clipless weapons, then set the actual ammo using clip) 11 | arg6 - force switch to this weapon 12 | arg7 - weapon's clip 13 | */ 14 | #pragma semicolon 1 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #pragma newdecls required 23 | 24 | #define PLUGIN_VERSION "1.10.8" 25 | 26 | public Plugin myinfo= 27 | { 28 | name="Freak Fortress 2: special_noanims", 29 | author="RainBolt Dash, Wliu", 30 | description="FF2: New Weapon and No Animations abilities", 31 | version=PLUGIN_VERSION 32 | }; 33 | 34 | public void OnPluginStart2() 35 | { 36 | int version[3]; 37 | FF2_GetFF2Version(version); 38 | if(version[0]==1 && (version[1]<10 || (version[1]==10 && version[2]<3))) 39 | { 40 | SetFailState("This subplugin depends on at least FF2 v1.10.3"); 41 | } 42 | 43 | HookEvent("teamplay_round_start", OnRoundStart); 44 | } 45 | 46 | public Action FF2_OnAbility2(int client, const char[] plugin_name, const char[] ability_name, int status) 47 | { 48 | if(!StrContains(ability_name, "rage_new_weapon")) 49 | { 50 | Rage_New_Weapon(client, ability_name); 51 | } 52 | return Plugin_Continue; 53 | } 54 | 55 | public Action OnRoundStart(Handle event, const char[] name, bool dontBroadcast) 56 | { 57 | CreateTimer(0.41, Timer_Disable_Anims, _, TIMER_FLAG_NO_MAPCHANGE); 58 | CreateTimer(9.31, Timer_Disable_Anims, _, TIMER_FLAG_NO_MAPCHANGE); 59 | return Plugin_Continue; 60 | } 61 | 62 | public Action Timer_Disable_Anims(Handle timer) 63 | { 64 | int client; 65 | for(int boss; (client=GetClientOfUserId(FF2_GetBossUserId(boss)))>0; boss++) 66 | { 67 | if(FF2_HasAbility(boss, this_plugin_name, "special_noanims")) 68 | { 69 | SetEntProp(client, Prop_Send, "m_bUseClassAnimations", 0); 70 | SetEntProp(client, Prop_Send, "m_bCustomModelRotates", FF2_GetArgI(boss, this_plugin_name, "special_noanims", "custom model rotates", 1, 0)); 71 | } 72 | } 73 | return Plugin_Continue; 74 | } 75 | 76 | void Rage_New_Weapon(int boss, const char[] ability_name) 77 | { 78 | int client=GetClientOfUserId(FF2_GetBossUserId(boss)); 79 | if(!client || !IsClientInGame(client) || !IsPlayerAlive(client)) 80 | { 81 | return; 82 | } 83 | 84 | char classname[64], attributes[256]; 85 | FF2_GetArgS(boss, this_plugin_name, ability_name, "classname", 1, classname, sizeof(classname)); 86 | FF2_GetArgS(boss, this_plugin_name, ability_name, "attributes", 3, attributes, sizeof(attributes)); 87 | 88 | int slot=FF2_GetArgI(boss, this_plugin_name, ability_name, "weapon slot", 4); 89 | TF2_RemoveWeaponSlot(client, slot); 90 | 91 | int index=FF2_GetArgI(boss, this_plugin_name, ability_name, "index", 2); 92 | int weapon=FF2_SpawnWeapon(client, classname, index, 101, 5, attributes); 93 | if(StrEqual(classname, "tf_weapon_builder") && index!=735) //PDA, normal sapper 94 | { 95 | SetEntProp(weapon, Prop_Send, "m_aBuildableObjectTypes", 1, _, 0); 96 | SetEntProp(weapon, Prop_Send, "m_aBuildableObjectTypes", 1, _, 1); 97 | SetEntProp(weapon, Prop_Send, "m_aBuildableObjectTypes", 1, _, 2); 98 | SetEntProp(weapon, Prop_Send, "m_aBuildableObjectTypes", 0, _, 3); 99 | } 100 | else if(StrEqual(classname, "tf_weapon_sapper") || index==735) //Sappers, normal sapper 101 | { 102 | SetEntProp(weapon, Prop_Send, "m_iObjectType", 3); 103 | SetEntProp(weapon, Prop_Data, "m_iSubType", 3); 104 | SetEntProp(weapon, Prop_Send, "m_aBuildableObjectTypes", 0, _, 0); 105 | SetEntProp(weapon, Prop_Send, "m_aBuildableObjectTypes", 0, _, 1); 106 | SetEntProp(weapon, Prop_Send, "m_aBuildableObjectTypes", 0, _, 2); 107 | SetEntProp(weapon, Prop_Send, "m_aBuildableObjectTypes", 1, _, 3); 108 | } 109 | 110 | if(FF2_GetArgI(boss, this_plugin_name, ability_name, "force switch", 6)) 111 | { 112 | SetEntPropEnt(client, Prop_Send, "m_hActiveWeapon", weapon); 113 | } 114 | 115 | int ammo=FF2_GetArgI(boss, this_plugin_name, ability_name, "ammo", 5, 0); 116 | int clip=FF2_GetArgI(boss, this_plugin_name, ability_name, "clip", 7, 0); 117 | if(ammo || clip) 118 | { 119 | FF2_SetAmmo(client, weapon, ammo, clip); 120 | } 121 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/hudminmode.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #define MB 3 11 | #define ME 2048 12 | public Plugin:myinfo = { 13 | name = "Freak Fortress 2: Minimalist HUD", 14 | author = "MasterOfTheXP", 15 | version = "1.0", 16 | }; 17 | /* 18 | This sub-plugin lets clients have their boss information be printed to them in what some would consider a neater fashion. 19 | Bosses who enable this will see, on either the top or bottom of their screens, their health on the left and their rage on the right, as well as their jump charge in the center. 20 | */ 21 | 22 | new miniHUD[MAXPLAYERS + 1]; 23 | new Handle:HPHUD; 24 | new Handle:RageHUD; 25 | new Handle:ChargeHUD; 26 | 27 | public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max) 28 | { 29 | return APLRes_Success; 30 | } 31 | 32 | public OnPluginStart2() 33 | { 34 | RegConsoleCmd("ff2hud", Command_hud, "ff2hud - Enable/disable the minimalist HUD."); 35 | RegConsoleCmd("halehud", Command_hud, "halehud - Enable/disable the minimalist HUD."); 36 | RegConsoleCmd("ff2_mhud", Command_hud, "ff2_mhud - Enable/disable the minimalist HUD."); 37 | 38 | CreateTimer(0.1, Timer_Millisecond); 39 | HPHUD = CreateHudSynchronizer(); 40 | RageHUD = CreateHudSynchronizer(); 41 | ChargeHUD = CreateHudSynchronizer(); 42 | } 43 | 44 | public Action:Timer_Millisecond(Handle:timer) 45 | { 46 | CreateTimer(0.1, Timer_Millisecond); 47 | if (FF2_GetRoundState() != 1) return Plugin_Handled; 48 | for (new z = 1; z <= GetMaxClients(); z++) 49 | { 50 | if (IsClientInGame(z) && miniHUD[z] > 0) 51 | { 52 | new a_index = FF2_GetBossIndex(z); 53 | if (a_index != -1) // client is Hale 54 | { 55 | new Hale = z; 56 | SetGlobalTransTarget(Hale); 57 | new bool:hudIsDisabled = false; 58 | if (FF2_GetFF2flags(Hale) & FF2FLAG_HUDDISABLED) hudIsDisabled = true; 59 | if (!hudIsDisabled) FF2_SetFF2flags(Hale, FF2_GetFF2flags(Hale)|FF2FLAG_HUDDISABLED); 60 | new Float:yPos; 61 | new Rage = RoundFloat(FF2_GetBossCharge(a_index, 0)); 62 | new rageColour = 255; 63 | if (Rage == 100) rageColour = 64; 64 | if (miniHUD[Hale] == 1) yPos = 1.0; 65 | if (miniHUD[Hale] == 2) yPos = 0.0; 66 | SetHudTextParams(0.0, yPos, 0.2, 255, 255, 255, 255); 67 | ShowSyncHudText(Hale, HPHUD, "HP: %i", GetClientHealth(Hale)); 68 | SetHudTextParams(1.0, yPos, 0.2, 255, rageColour, rageColour, 255); 69 | if (Rage != 100 && Rage > 0) ShowSyncHudText(Hale, RageHUD, "RAGE: %i!", Rage); 70 | if (Rage < 1) ShowSyncHudText(Hale, RageHUD, "RAGE: %i", Rage); 71 | if (Rage == 100) ShowSyncHudText(Hale, RageHUD, "Press TAUNT to RAGE."); 72 | new Charge = RoundFloat(FF2_GetBossCharge(a_index, 1)); 73 | if (Charge > 0) 74 | { 75 | SetHudTextParams(-1.0, yPos, 0.2, 255, 255, 255, 255); 76 | ShowSyncHudText(Hale, ChargeHUD, "%i", Charge); 77 | } 78 | } 79 | } 80 | } 81 | return Plugin_Handled; 82 | } 83 | 84 | public Action:Command_hud(client, args) 85 | { 86 | if (client == 0) 87 | { 88 | PrintToServer("[FF2] The minimalist HUD cannot be enabled by Console."); 89 | return Plugin_Handled; 90 | } 91 | HUDMenu(client); 92 | return Plugin_Handled; 93 | } 94 | 95 | 96 | 97 | public Action:HUDMenu(client) 98 | { 99 | new Handle:smMenu = CreatePanel(); 100 | decl String:text[128]; 101 | SetGlobalTransTarget(client); 102 | Format(text, 128, "Turn the minimalist HUD for bosses..."); 103 | SetPanelTitle(smMenu, text); 104 | Format(text, 256, "On, place on bottom of screen"); 105 | DrawPanelItem(smMenu, text); 106 | Format(text, 256, "On, place at top of screen"); 107 | DrawPanelItem(smMenu, text); 108 | Format(text, 256, "Off, I want the normal boss HUD"); 109 | DrawPanelItem(smMenu, text); 110 | SendPanelToClient(smMenu, client, HUDSelector, MENU_TIME_FOREVER); 111 | CloseHandle(smMenu); 112 | return Plugin_Handled; 113 | } 114 | 115 | public HUDSelector(Handle:menu, MenuAction:action, client, p2) 116 | { 117 | if (action == MenuAction_Select) 118 | { 119 | if (p2 == 1 || p2 == 2) 120 | { 121 | miniHUD[client] = p2; 122 | CPrintToChat(client, "{olive}[FF2]{default} You've enabled the minimalist HUD."); 123 | if (FF2_GetBossIndex(client) == -1) CPrintToChat(client, "{olive}[FF2]{default} You'll see it the next time you're boss!"); 124 | } 125 | if (p2 == 3) 126 | { 127 | miniHUD[client] = 0; 128 | CPrintToChat(client, "{olive}[FF2]{default} You've disabled the minimalist HUD."); 129 | FF2_SetFF2flags(client, FF2_GetFF2flags(client)-FF2FLAG_HUDDISABLED); 130 | } 131 | else return; 132 | } 133 | } 134 | 135 | public OnClientPutInServer(client) 136 | { 137 | miniHUD[client] = 0; 138 | } 139 | 140 | public Action:FF2_OnAbility2(index, const String:plugin_name[], const String:ability_name[], action) 141 | { 142 | return Plugin_Continue; 143 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/include/POTRY.inc: -------------------------------------------------------------------------------- 1 | enum GameMode 2 | { 3 | Game_None = 0, 4 | Game_SuddenDeath, 5 | Game_LastManStanding, 6 | Game_SpecialLastManStanding, 7 | Game_AttackAndDefense, 8 | Game_ControlPoint, 9 | Game_ControlPointOverTime 10 | }; 11 | /// 12 | enum VIPEffect 13 | { 14 | VIPEffect_None = 0, 15 | VIPEffect_BossStandard, 16 | VIPEffect_FreeNametag 17 | }; 18 | 19 | enum VIPInfo 20 | { 21 | VIPInfo_None = 0, 22 | VIPInfo_Donator, 23 | VIPInfo_Createor, 24 | VIPInfo_Admin, 25 | VIPInfo_Developer 26 | }; 27 | 28 | enum AimbotType 29 | { 30 | AimbotType_None = 0, 31 | AimbotType_Aimbot, 32 | AimbotType_AutoShoot, 33 | AimbotType_NoSpread, 34 | AimbotType_SlientAim 35 | }; 36 | 37 | #define VIPEFFECT_MAX_COUNT 3 38 | /// 39 | public bool IsServerPotry() 40 | { 41 | return true; 42 | } 43 | 44 | // native bool FF2Boss_IsPlayerBlasterReady(int client); 45 | 46 | native void FF2_EnablePlayerLastmanStanding(int client); 47 | 48 | native GameMode FF2_GetGameState(); 49 | 50 | native void FF2_SetGameState(GameMode gamemode); 51 | // native void FF2_SetGameState(GameMode gamemode, int needSetting); 52 | 53 | native float FF2_GetTimeLeft(); 54 | 55 | native void FF2_SetTimeLeft(float time); 56 | 57 | native bool FF2_IsLastMan(int client); 58 | 59 | native void ROLLER_CreateRollerMine(int client, int count=1); 60 | 61 | forward Action FF2_OnDeathMatchTimer(float &time); 62 | 63 | native bool TIMESTOP_IsTimeStopping(); 64 | 65 | native bool POTRY_IsClientVIP(int client); 66 | 67 | native VIPInfo POTRY_GetClientVIPInfo(int client); 68 | 69 | native bool POTRY_IsClientEnableVIPEffect(int client, VIPEffect effect); //EnableClientVIPEffect 70 | 71 | native bool POTRY_EnableClientVIPEffect(int client, VIPEffect effect, bool setbool); 72 | 73 | // 효과음은 알아서. 74 | native void TIMESTOP_EnableTimeStop(int parent, float warntime=0.0, float stoptime); 75 | 76 | native void TIMESTOP_DisableTimeStop(); 77 | 78 | native void Aimbot_SetState(int client, AimbotType type, bool enable); 79 | 80 | native bool Aimbot_GetState(int client, AimbotType type); 81 | /* 82 | * 이 inc는 존재만 확인하는 용도임. 83 | */ 84 | 85 | 86 | /* 87 | new g_bOnIce[MAXPLAYERS+1]; 88 | 89 | public setIceFeeling(iClient, iOnIce=1) g_bOnIce[iClient] = bool:iOnIce; 90 | 91 | public OnGameFrame(){ 92 | for(new i = 1 ; i <= MaxClients ; i++){ 93 | if(g_bOnIce[i] && IsClientInGame(i) && IsPlayerAlive(i)){ 94 | if(GetEntityFlags(i) & FL_ONGROUND){ 95 | new Float:fVel[3], Float:fJak; 96 | Entity_GetAbsVelocity(i, fVel); 97 | fVel[2] = 0.0; 98 | new Float:fSpeed = GetVectorLength(fVel); 99 | 100 | fJak = (fSpeed/266.0) * 100; 101 | 102 | GetEntPropVector(i, Prop_Data, "m_vecVelocity", fVel); 103 | 104 | for(new l = 0 ; l < 2 ; l++){ 105 | fVel[l] += (fVel[l]/fJak); 106 | } 107 | 108 | TeleportEntity(i, NULL_VECTOR, NULL_VECTOR, fVel); 109 | } 110 | } 111 | } 112 | } 113 | */ 114 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/include/drain_over_time.inc: -------------------------------------------------------------------------------- 1 | // clearly I'm going senile. I've already forgotten that these won't work there's no way to guarantee plugin load order. 2 | //native CancelDOTAbilityActivation(bossClientIdx); 3 | //native ForceDOTAbilityDeactivation(bossClientIdx); 4 | //native SetDOTUsability(bossClientIdx, usable); 5 | 6 | // so we'll have to do reflection instead 7 | stock Handle:FindDOTPlugin() 8 | { 9 | decl String:buffer[256]; 10 | 11 | new Handle:iter = GetPluginIterator(); 12 | new Handle:pl = INVALID_HANDLE; 13 | 14 | while (MorePlugins(iter)) 15 | { 16 | pl = ReadPlugin(iter); 17 | 18 | GetPluginFilename(pl, buffer, sizeof(buffer)); 19 | //PrintToServer("plugin: %s", buffer); 20 | if (StrContains(buffer, "drain_over_time.ff2", false) != -1) // hahaha, a function with a boolean sounding name which returns -1 on failure. lololololol 21 | break; 22 | else 23 | pl = INVALID_HANDLE; 24 | } 25 | 26 | CloseHandle(iter); 27 | 28 | //if (pl == INVALID_HANDLE) 29 | // PrintToServer("Invalid handle."); 30 | //else 31 | //{ 32 | // GetPluginFilename(pl, buffer, sizeof(buffer)); 33 | // PrintToServer("plugin: %s", buffer); 34 | //} 35 | 36 | return pl; 37 | } 38 | 39 | // this is only called when a DOT ability needs to be treated like it was never activated 40 | // this should only be called in OnDOTAbilityActivated() 41 | stock CancelDOTAbilityActivation(bossClientIdx) 42 | { 43 | new Handle:plugin = FindDOTPlugin(); 44 | if (plugin != INVALID_HANDLE) 45 | { 46 | new Function:func = GetFunctionByName(plugin, "CancelDOTAbilityActivation"); 47 | if (func != INVALID_FUNCTION) 48 | { 49 | Call_StartFunction(plugin, func); 50 | Call_PushCell(bossClientIdx); 51 | Call_Finish(); 52 | } 53 | else 54 | PrintToServer("ERROR: Could not find drain_over_time.sp:CancelDOTAbilityActivation()."); 55 | } 56 | else 57 | PrintToServer("ERROR: Could not find DOT plugin. CancelDOTAbilityActivation() failed."); 58 | } 59 | 60 | // this allows drain over time subplugins to deactivate the DOT 61 | // this should only be called in OnDOTAbilityTick() 62 | stock ForceDOTAbilityDeactivation(bossClientIdx) 63 | { 64 | new Handle:plugin = FindDOTPlugin(); 65 | if (plugin != INVALID_HANDLE) 66 | { 67 | new Function:func = GetFunctionByName(plugin, "ForceDOTAbilityDeactivation"); 68 | if (func != INVALID_FUNCTION) 69 | { 70 | Call_StartFunction(plugin, func); 71 | Call_PushCell(bossClientIdx); 72 | Call_Finish(); 73 | } 74 | else 75 | PrintToServer("ERROR: Could not find drain_over_time.sp:ForceDOTAbilityDeactivation()."); 76 | } 77 | else 78 | PrintToServer("ERROR: Could not find DOT plugin. ForceDOTAbilityDeactivation() failed."); 79 | } 80 | 81 | // this sets a DOT to be usable or unusable 82 | stock SetDOTUsability(bossClientIdx, usable) 83 | { 84 | new Handle:plugin = FindDOTPlugin(); 85 | if (plugin != INVALID_HANDLE) 86 | { 87 | new Function:func = GetFunctionByName(plugin, "SetDOTUsability"); 88 | if (func != INVALID_FUNCTION) 89 | { 90 | Call_StartFunction(plugin, func); 91 | Call_PushCell(bossClientIdx); 92 | Call_PushCell(usable); 93 | Call_Finish(); 94 | } 95 | else 96 | PrintToServer("ERROR: Could not find drain_over_time.sp:SetDOTUsability()."); 97 | } 98 | else 99 | PrintToServer("ERROR: Could not find DOT plugin. SetDOTUsability() failed."); 100 | } 101 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/include/drain_over_time_subplugin.inc: -------------------------------------------------------------------------------- 1 | /** 2 | * General notes about the actions below: 3 | * - I don't like how the FF2 plug-in allows user to not specify a plugin name (can be multiple matches) so I'm not allowing it here. 4 | */ 5 | public Action:OnDOTAbilityActivatedInternal(clientIdx) 6 | { 7 | OnDOTAbilityActivated(clientIdx); 8 | return Plugin_Continue; 9 | } 10 | 11 | public Action:OnDOTAbilityDeactivatedInternal(clientIdx) 12 | { 13 | OnDOTAbilityDeactivated(clientIdx); 14 | return Plugin_Continue; 15 | } 16 | 17 | public Action:OnDOTAbilityTickInternal(clientIdx, tickCount) 18 | { 19 | OnDOTAbilityTick(clientIdx, tickCount); 20 | return Plugin_Continue; 21 | } 22 | 23 | public Action:DOTPostRoundStartInitInternal() 24 | { 25 | DOTPostRoundStartInit(); 26 | return Plugin_Continue; 27 | } 28 | 29 | public Action:OnDOTUserDeathInternal(clientIdx, isInGame) 30 | { 31 | OnDOTUserDeath(clientIdx, isInGame); 32 | return Plugin_Continue; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/include/ff2_ams.inc: -------------------------------------------------------------------------------- 1 | /** 2 | * Ability Management System Include 3 | * 4 | * Due to load order issues, need to use reflection for these accessor methods. 5 | **/ 6 | 7 | 8 | #if defined _ff2_ams_included 9 | #endinput 10 | #endif 11 | #define _ff2_ams_included 12 | 13 | #include 14 | 15 | /** 16 | * Retrieves the plugin's handle 17 | * Useful for calling other subplugins, if using the reflective method. 18 | * 19 | * @param pluginName Plugin Name 20 | * @return Handle of plugin 21 | **/ 22 | stock Handle FindPlugin(char[] pluginName) 23 | { 24 | char buffer[256]; 25 | char path[PLATFORM_MAX_PATH]; 26 | Handle iter=GetPluginIterator(); 27 | Handle pl=null; 28 | while(MorePlugins(iter)) 29 | { 30 | pl=ReadPlugin(iter); 31 | Format(path, sizeof(path), "%s", pluginName); 32 | GetPluginFilename(pl, buffer, sizeof(buffer)); 33 | if(StrContains(buffer, path, false) >= 0) 34 | { 35 | break; 36 | } 37 | else 38 | { 39 | pl=null; 40 | } 41 | } 42 | delete iter; 43 | return pl; 44 | } 45 | 46 | /** 47 | * Check if plugin exists 48 | * 49 | * @param pluginName Plugin Name 50 | * @return True if plugin exists, false otherwise. 51 | **/ 52 | stock bool PluginExists(char[] pluginName) 53 | { 54 | Handle plugin=FindPlugin(pluginName); 55 | if(plugin!=null) return true; 56 | return false; 57 | } 58 | 59 | /** 60 | * Check if function exists 61 | * 62 | * @param pluginName Plugin Name 63 | * @param functionName Function name of public analogue 64 | * @return True if function exists, false otherwise. 65 | **/ 66 | stock bool FunctionExists(char[] pluginName, char[] functionName) 67 | { 68 | Handle plugin=FindPlugin(pluginName); 69 | if(plugin!=null) 70 | { 71 | Function func=GetFunctionByName(plugin, functionName); 72 | if(func!=INVALID_FUNCTION) 73 | { 74 | return true; 75 | } 76 | return false; 77 | } 78 | else 79 | { 80 | return false; 81 | } 82 | } 83 | 84 | /** 85 | * Autodetect whether AMS will be used for managing RAGE, or a normal E / G RAGE. 86 | * 87 | * @param bossIdx Boss Index 88 | * @param pluginName Plugin Name 89 | * @param abilityName Ability Name 90 | * @return True if ability is ready to be used with AMS, otherwise false 91 | **/ 92 | stock bool AMS_IsSubabilityReady(int bossIdx, const char[] pluginName, const char[] abilityName) 93 | { 94 | return FunctionExists("ff2_sarysapub3.ff2", "AMS_InitSubability") && FF2_HasAbility(bossIdx, "ff2_sarysapub3", "ability_management_system") && !FF2_GetAbilityArgument(bossIdx, pluginName, abilityName, 0); 95 | } 96 | 97 | /** 98 | * Initialize the AMS-supported ability or AMS sub-ability 99 | * 100 | * @param bossIdx Boss Index 101 | * @param clientIdx Client Index 102 | * @param pluginName Plugin Name 103 | * @param abilityName Ability Name 104 | * @param prefix Prefix (up to 5 characters long) used for _CanInvoke(clientIdx) && _Invoke(clientIdx) analogues 105 | * @noreturn 106 | **/ 107 | stock void AMS_InitSubability(int bossIdx, int clientIdx,const char[] pluginName, const char[] abilityName, const char[] prefix) 108 | { 109 | if(AMS_IsSubabilityReady(bossIdx, pluginName, abilityName)) 110 | { 111 | Handle plugin=FindPlugin("ff2_sarysapub3.ff2"); 112 | if(plugin!=null) 113 | { 114 | Function func=GetFunctionByName(plugin, "AMS_InitSubability"); 115 | if(func!=INVALID_FUNCTION) 116 | { 117 | Call_StartFunction(plugin, func); 118 | Call_PushCell(bossIdx); 119 | Call_PushCell(clientIdx); 120 | Call_PushString(pluginName); 121 | Call_PushString(abilityName); 122 | Call_PushString(prefix); 123 | Call_Finish(); 124 | } 125 | else 126 | { 127 | LogError("ERROR: Unable to initialize ff2_sarysapub3:AMS_InitSubability()"); 128 | } 129 | } 130 | else 131 | { 132 | LogError("ERROR: Unable to initialize ff2_sarysapub3:AMS_InitSubability(). Make sure this plugin exists!"); 133 | } 134 | } 135 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/include/ff2_mana_interface.inc: -------------------------------------------------------------------------------- 1 | #if defined _FF2_MANA_ 2 | #endinput 3 | #endif 4 | #define _FF2_MANA_ 5 | 6 | /** 7 | * Adds the specified amount of mana to the desired boss 8 | * Use a negative amount to remove mana 9 | * 10 | * @param iBoss The client index of the boss, not the boss index! 11 | * @param fAmount Amount to add (or remove) 12 | * @noreturn 13 | * @error The client index was invalid 14 | */ 15 | native void FF2M_AddMana(int iBoss, float fAmount); 16 | 17 | /** 18 | * Sets the mana pool directly to the value specified to the desired boss 19 | * 20 | * @param iBoss The client index of the boss, not the boss index! 21 | * @param fAmount Amount to add (or remove) 22 | * @noreturn 23 | * @error The client index was invalid 24 | */ 25 | native void FF2M_SetMana(int iBoss, float fAmount); 26 | 27 | /** 28 | * Use this if you want to make abilities use the mana system 29 | * within a plugin if you need to, you should really do it by config though 30 | * 31 | * @param iBoss The client index of the boss 32 | * @param iSlot The slot you wish to assign it to (1-9) 33 | * @param pluginName The name of the plugin we will be calling in to 34 | * @param abilityName The name of the ability we will attempt to use 35 | * @param fCost The amount of mana removed per cast, can be 0 or negative! 36 | * @return True on success, false for various errors 37 | * @error Client index is invalid, slot is invalid, plugin name is empty, ability name is empty 38 | */ 39 | native bool FF2M_SetupAbility(int iBoss, int iSlot, const char[] pluginName, const char[] abilityName, float fCost); 40 | 41 | /** 42 | * Called every 0.2 seconds just before the system adds 'mana' to the boss 43 | * 44 | * @param iBoss The client index of the boss 45 | * @param flOldValue The value before we changed 46 | * @param flNewValue The value after we changed or are modifying 47 | * @return Plugin_Changed to use your own value, higher to prevent mana regeneration 48 | */ 49 | forward Action FF2M_OnManaChanged(int iBoss, float flOldValue, float &flNewValue); 50 | 51 | /** 52 | * Called after someone presses one of their keys to cast an ability 53 | * 54 | * @param iBoss The client index of the boss 55 | * @param iSlot The slot the ability is in as configured 56 | * @param pluginName Plugin we are calling in to 57 | * @param abilityName Name of ability to be cast 58 | * @param flCost The mana cost of the ability, can be modified 59 | * @return Plugin_Changed to modify cost, higher to prevent it from casting 60 | */ 61 | forward Action FF2M_OnAbilityCast(int iBoss, int iSlot, const char[] pluginName, const char[] abilityName, float &flCost); 62 | 63 | public SharedPlugin __pl_FF2_Mana = { 64 | name = "FF2 Mana", 65 | file = "ff2_mana_system.smx", 66 | #if defined REQUIRE_PLUGIN 67 | required = 1 68 | #else 69 | required = 0 70 | #endif 71 | } 72 | 73 | #if !defined REQUIRE_PLUGIN 74 | public void __pl_FF2_ManaSetNTVOptional() 75 | { 76 | MarkNativeAsOptional("FF2M_AddMana"); 77 | MarkNativeAsOptional("FF2M_SetMana"); 78 | MarkNativeAsOptional("FF2M_SetupAbility"); 79 | } 80 | #endif 81 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/include/ff2ability.inc: -------------------------------------------------------------------------------- 1 | #if defined _FF2_Ability_Parser 2 | #endinput 3 | #endif 4 | #define _FF2_Ability_Parser 5 | 6 | enum ParseState { 7 | Parse_Inactive, 8 | Parse_Active, 9 | Parse_Finished 10 | }; 11 | 12 | enum struct FF2Template { 13 | StringMap map; 14 | SMCParser parser; 15 | ArrayStack last; 16 | char section[PLATFORM_MAX_PATH]; 17 | char target[32]; 18 | ParseState state; 19 | int level; 20 | } 21 | 22 | static FF2Template FF2Ability; 23 | methodmap FF2Parse < StringMap { 24 | public FF2Parse(const char[] bosspath, const char[] target) { 25 | 26 | FormatEx(FF2Ability.target, sizeof(FF2Ability.target), target); 27 | 28 | FF2Ability.parser = new SMCParser(); 29 | FF2Ability.parser.OnStart = SMC_OnStart; 30 | FF2Ability.parser.OnEnterSection = SMC_OnEnterSection; 31 | FF2Ability.parser.OnKeyValue = SMC_OnKeyValue; 32 | FF2Ability.parser.OnLeaveSection = SMC_OnLeaveSection; 33 | 34 | SMCError SMCErr = FF2Ability.parser.ParseFile(bosspath); 35 | if(SMCErr != SMCError_Okay) { 36 | char error[64]; 37 | FF2Ability.parser.GetErrorString(SMCErr, error, sizeof(error)); 38 | LogError("[FF2Parser] '%s' Error : %s", bosspath, error); 39 | delete FF2Ability.map; 40 | } 41 | 42 | delete FF2Ability.last; 43 | delete FF2Ability.parser; 44 | 45 | if(FF2Ability.state == Parse_Inactive) { 46 | delete FF2Ability.map; 47 | FF2Ability.map = null; 48 | LogError("[FF2Parser] Invalid path (%s) / target key (%s) used", bosspath, target); 49 | } 50 | 51 | return view_as(FF2Ability.map); 52 | } 53 | 54 | public int Get(const char[] key, char[] buffer, int maxlen) { 55 | if(this == null) { 56 | return 0; 57 | } 58 | char[] result = new char[maxlen]; 59 | if(!this.GetString(key, buffer, maxlen)) { 60 | return 0; 61 | } 62 | 63 | return strcopy(buffer, maxlen, result); 64 | } 65 | 66 | public float GetFloat(const char[] key, float def = 0.0) { 67 | char[] key_buffer = new char[16]; 68 | if(!this.GetString(key, key_buffer, 16)) { 69 | return def; 70 | } 71 | 72 | return StringToFloat(key_buffer); 73 | } 74 | 75 | public int GetInt(const char[] key, int def = 0) { 76 | char[] key_buffer = new char[16]; 77 | if(!this.GetString(key, key_buffer, 16)) { 78 | return def; 79 | } 80 | 81 | return StringToInt(key_buffer); 82 | } 83 | 84 | public int GetButton(const char[] key, int def = IN_RELOAD) { 85 | char[] key_buffer = new char[16]; 86 | if(!this.GetString(key, key_buffer, 16)) { 87 | return def; 88 | } 89 | 90 | if(!strcmp(key_buffer, "reload")) { 91 | return IN_RELOAD; 92 | } 93 | else if(!strcmp(key_buffer, "mouse3")) { 94 | return IN_ATTACK3; 95 | } 96 | else if(!strcmp(key_buffer, "mouse2")) { 97 | return IN_ATTACK2; 98 | } 99 | 100 | return def; 101 | } 102 | 103 | public int GetBool(const char[] key, bool def = false) { 104 | char[] key_buffer = new char[6]; 105 | if(!this.GetString(key, key_buffer, 6)) { 106 | return def; 107 | } 108 | 109 | return !strcmp(key_buffer, "true"); 110 | } 111 | } 112 | 113 | public void SMC_OnStart(SMCParser smc) 114 | { 115 | FF2Ability.map = new StringMap(); 116 | FF2Ability.last = new ArrayStack(PLATFORM_MAX_PATH); 117 | FF2Ability.state = Parse_Inactive; 118 | FF2Ability.level = 0; 119 | } 120 | public SMCResult SMC_OnEnterSection(SMCParser smc, const char[] name, bool opt_quotes) 121 | { 122 | switch(FF2Ability.state) { 123 | case Parse_Finished: { 124 | return SMCParse_Halt; 125 | } 126 | 127 | case Parse_Inactive: { 128 | if(!strcmp(name, FF2Ability.target)) { 129 | FF2Ability.state = Parse_Active; 130 | } 131 | return SMCParse_Continue; 132 | } 133 | 134 | case Parse_Active: { 135 | if(!FF2Ability.level) { 136 | FormatEx(FF2Ability.section, sizeof(FF2Ability.section), name); 137 | } else { 138 | Format(FF2Ability.section, sizeof(FF2Ability.section), "%s->%s", FF2Ability.section, name); 139 | } 140 | FF2Ability.last.PushString(name); 141 | FF2Ability.level++; 142 | return SMCParse_Continue; 143 | } 144 | } 145 | return SMCParse_Continue; 146 | } 147 | 148 | public SMCResult SMC_OnKeyValue(SMCParser smc, const char[] key, const char[] value, bool key_quotes, bool value_quotes) 149 | { 150 | switch(FF2Ability.state) { 151 | case Parse_Active: { 152 | static char section[PLATFORM_MAX_PATH]; 153 | 154 | if(!FF2Ability.level) { 155 | FF2Ability.map.SetString(key, value); 156 | } else { 157 | FormatEx(section, sizeof(section), "%s->%s", FF2Ability.section, key); 158 | FF2Ability.map.SetString(section, value); 159 | } 160 | } 161 | default: { 162 | } 163 | } 164 | return SMCParse_Continue; 165 | } 166 | 167 | public SMCResult SMC_OnLeaveSection(SMCParser smc) 168 | { 169 | switch(FF2Ability.state) { 170 | case Parse_Active: { 171 | if(--FF2Ability.level >= 0) { 172 | char[] last = new char[PLATFORM_MAX_PATH]; 173 | int size; 174 | FF2Ability.last.PopString(last, PLATFORM_MAX_PATH, size); 175 | RemoveLastString(FF2Ability.section, size); 176 | } else { 177 | FF2Ability.state = Parse_Finished; 178 | } 179 | } 180 | } 181 | return SMCParse_Continue; 182 | } 183 | 184 | static void RemoveLastString(char[] src, int len) 185 | { 186 | int nul = strlen(src) - len - 2; 187 | if(nul < 0) { 188 | nul = 0; 189 | } 190 | src[nul] = '\0'; 191 | } 192 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/include/ff2menu_included.inc: -------------------------------------------------------------------------------- 1 | #if defined _FF2MenuRage_INCLUDED 2 | #endinput 3 | #endif 4 | #define _FF2MenuRage_INCLUDED 5 | 6 | #include 7 | 8 | /** 9 | * Called right before round start 10 | * 11 | * @param boss client index 12 | * 13 | * @noreturn 14 | */ 15 | forward Action FF2MenuRage_PreRoundStart(int client); 16 | 17 | /** 18 | * Called whenever a boss triggers a menu rage 19 | * 20 | * @param boss boss' index 21 | * @param pts current points 22 | * @param cd cooldown that will soon be applied 23 | * @param Plugin_Name 24 | * @param Ability_Name 25 | * 26 | * @return Plugin_Stop, to completly block pts reduction and ability execution 27 | * Plugin_Handled or Plugin_Changed to handle the rage execution 28 | * Plugin_Continue to ignore everything and let the ability execute by itself 29 | * 30 | */ 31 | forward Action FF2MenuRage_OnStartRage(int boss, int& pts, int& cd, const char[] Plugin_Name, const char[] Ability_Name); 32 | 33 | /** 34 | * Called whenever a boss takes Damage 35 | * 36 | * @param client boss with menu rage 37 | * @param victim victim index 38 | * @param damage current received damage 39 | * 40 | * @return Any value higher than Plugin_Continue to handle the call 41 | * 42 | */ 43 | forward Action FF2MenuRage_OnTakeDamageAlive(int client, int victim, int damage); 44 | 45 | /** 46 | * Called whenever a victim dies 47 | * 48 | * @param victim current points 49 | * @param client boss with menu rage 50 | * 51 | * @return Any value higher than Plugin_Continue to handle the call 52 | * 53 | */ 54 | forward Action FF2MenuRage_OnPlayerDeath(int victim, int attacker); 55 | 56 | 57 | /** 58 | * Gets player's MenuMap 59 | * 60 | * @param client client's index 61 | * 62 | * @return Hashmap, null on failure 63 | * @error Invalid client index 64 | */ 65 | native FF2Parse FF2MenuRage_GetHashMap(int client); 66 | 67 | /** 68 | * Retreive a StringMap value for a client 69 | * 70 | * @param client client's index 71 | * @param context Key String 72 | * 73 | * @return the value inside the key. negative/false for failure 74 | * @error Invalid client index or context 75 | */ 76 | native any FF2MenuRage_PeekValue(int client, const char[] context); 77 | 78 | /** 79 | * Set a StringMap value for a client 80 | * 81 | * @param client client's index 82 | * @param context Key String 83 | * @param newVal value to set 84 | * 85 | * @return true on success, false otherwise. 86 | * @error Invalid client index or context 87 | */ 88 | native bool FF2MenuRage_SetValue(int client, const char[] context, any newVal); 89 | 90 | /** 91 | * Set a rage cooldown 92 | * 93 | * @param client client's index 94 | * @param index rage's index 95 | * @param newVal value to set 96 | * 97 | * @noreturn 98 | * @error Invalid client index or rage 99 | */ 100 | native void FF2MenuRage_SetCooldown(int client, int index, float newVal); 101 | 102 | /** 103 | * @return true if any boss with menu rage is active. false otherwise 104 | */ 105 | native bool FF2MenuRage_IsActive(); 106 | 107 | /** 108 | * 109 | * @param client client's index 110 | * 111 | * @return if boss has a menu rage abiility 112 | * 113 | */ 114 | native bool FF2MenuRage_HasAbility(int client); 115 | 116 | /** 117 | * force a player to provoke a rage according to the Menu rage rules 118 | * 119 | * @param client client's index 120 | * @param pts pts to use 121 | * @param Plugin_Name 122 | * @param Ability_Name 123 | * @param slot rage slot 124 | * 125 | * @return true on success, false otherwise 126 | * @error Invalid client index or string 127 | */ 128 | native bool FF2MenuRage_DoAbiltiy(int client, int pts, const char[] Plugin_Name, const char[] Ability_Name, int slot); 129 | 130 | 131 | #if !defined REQUIRE_PLUGIN 132 | public __pl_FF2MenuRage_SetNTVOptional() 133 | { 134 | MarkNativeAsOptional("FF2MenuRage_GetHashMap"); 135 | MarkNativeAsOptional("FF2MenuRage_PeekValue"); 136 | MarkNativeAsOptional("FF2MenuRage_SetValue"); 137 | MarkNativeAsOptional("FF2MenuRage_SetCooldown"); 138 | MarkNativeAsOptional("FF2MenuRage_IsActive"); 139 | MarkNativeAsOptional("FF2MenuRage_HasAbility"); 140 | MarkNativeAsOptional("FF2MenuRage_DoAbiltiy"); 141 | } 142 | #endif 143 | 144 | public SharedPlugin __pl_FF2MenuRage = 145 | { 146 | name = "FF2MenuRage", 147 | file = "menurage_platform.smx", 148 | #if defined REQUIRE_PLUGIN 149 | required = 1, 150 | #else 151 | required = 0, 152 | #endif 153 | }; 154 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/include/freak_fortress_2_kstreak.inc: -------------------------------------------------------------------------------- 1 | #if defined _freak_fortress_2_kstreak_included 2 | #endinput 3 | #endif 4 | #define _freak_fortress_2_kstreak_included 5 | 6 | /** 7 | * Get client's cookie value 8 | * 9 | * @param client The client to check for 10 | * @param index The cookie's index 11 | * @return The cookie's value. If could not get cookie's value, returns -2 12 | */ 13 | native int FF2_KStreak_GetCookies(int client, int index=0); 14 | 15 | /** 16 | * Sets client's cookie value 17 | * 18 | * @param client The client to check for 19 | * @param toggle The new toggle cookie's value 20 | * @param sheen The new sheen cookie's value 21 | * @param effect The new killstreaker cookie's value 22 | * @return True if the new values are set, false otherwise 23 | */ 24 | native int FF2_KStreak_SetCookies(int client, int cookie0=-2, int cookie1=-2, int cookie2=-2); 25 | 26 | /** 27 | * If to add an menu option to boss preference in Unofficial FF2 28 | * 29 | * @return True if merge cvar is enabled, false otherwise 30 | */ 31 | native bool FF2_KStreak_Merge(); 32 | 33 | /** 34 | * Display a menu to a client 35 | * 36 | * @param client The client to show 37 | * @param menu The menu type 38 | * 0 - Main Menu 39 | * 1 - Toggle Menu 40 | * 2 - Sheen Menu 41 | * 3 - Killstreaker Menu 42 | * @noreturn 43 | */ 44 | native void FF2_KStreak_Menu(int client, int menu=0); 45 | 46 | public SharedPlugin __pl_freak_fortress_2_kstreak = 47 | { 48 | name="ff2_kstreak_pref", 49 | file="ff2_kstreak_pref.smx", 50 | #if defined REQUIRE_PLUGIN 51 | required = 1, 52 | #else 53 | required = 0, 54 | #endif 55 | }; 56 | 57 | #if !defined REQUIRE_PLUGIN 58 | public __pl_freak_fortress_2_kstreak_SetNTVOptional() 59 | { 60 | MarkNativeAsOptional("FF2_KStreak_SetCookies"); 61 | MarkNativeAsOptional("FF2_KStreak_GetCookies"); 62 | MarkNativeAsOptional("FF2_KStreak_Merge"); 63 | MarkNativeAsOptional("FF2_KStreak_Menu"); 64 | } 65 | #endif 66 | 67 | #file "FF2 Include: Killstreak Preferences" -------------------------------------------------------------------------------- /addons/sourcemod/scripting/include/menu_helper.sp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | "menu_base" 4 | { 5 | "button" "reload" 6 | "max abilities" "6" 7 | "menu name" "Current [ENERGY] : %i\nSelect Your Powerup." 8 | "hud format" "[ENERGY] : %i" 9 | "damage taken" "1000" 10 | "damage pts" "45" 11 | "life loss" "70" 12 | "loss mult" "3 - 5 - 10" 13 | "max pts" "9001" 14 | "gain per rage" "60" 15 | "gain per kill" "50" 16 | 17 | "hook" 18 | { 19 | "num" "3" 20 | "1" 21 | { 22 | "name" "ability_name" 23 | 24 | "rage title" "Anti-Medigun" 25 | "rage info" "ENERGY : 120 Stamina.\nCooldown : 20 sec" 26 | "rage cost" "120" 27 | "rage cooldown" "20.0" 28 | 29 | "plugin_name" "plugin_name" 30 | } 31 | "2" 32 | { 33 | "name" "ability_name" 34 | ... 35 | .. 36 | "plugin_name" "plugin_name" 37 | } 38 | "3" 39 | { 40 | "name" "ability_name" 41 | ... 42 | .. 43 | "plugin_name" "plugin_name" 44 | } 45 | } 46 | } 47 | */ 48 | 49 | methodmap PointsMap < StringMap { 50 | public PointsMap(int maxpts) { 51 | StringMap map = new StringMap(); 52 | 53 | map.SetValue("max", maxpts); 54 | map.SetValue("points", 0); 55 | map.SetValue("damage", 0); 56 | map.SetValue("stack", 0); 57 | 58 | return view_as(map); 59 | } 60 | 61 | public void Purge() { 62 | if(!this) 63 | return; 64 | delete this; 65 | } 66 | 67 | property int max { 68 | public get() { 69 | int val; 70 | return this.GetValue("max", val) ? val:9001; 71 | } 72 | } 73 | 74 | property int points { 75 | public get() { 76 | int val; 77 | return this.GetValue("points", val) ? val:0; 78 | } 79 | public set(int val) { 80 | this.SetValue("points", val); 81 | } 82 | } 83 | 84 | property int damage { 85 | public get() { 86 | int val; 87 | return this.GetValue("damage", val) ? val:0; 88 | } 89 | public set(int val) { 90 | this.SetValue("damage", val); 91 | } 92 | } 93 | 94 | property int stack { 95 | public get() { 96 | int val; 97 | return this.GetValue("stack", val) ? val:0; 98 | } 99 | public set(int val) { 100 | this.SetValue("stack", val); 101 | } 102 | } 103 | } 104 | 105 | PointsMap Points[MAXCLIENTS]; 106 | FF2Parse BossMap[MAXCLIENTS]; 107 | Handle PointsHud; 108 | 109 | bool FF2CreateMenu(FF2Prep player) 110 | { 111 | char path[PLATFORM_MAX_PATH]; 112 | if(!player.BuildBoss(path, sizeof(path))) { 113 | return false; 114 | } 115 | 116 | if((BossMap[player.Index] = new FF2Parse(path, "menu_base")) == null) { 117 | return false; 118 | } 119 | 120 | MenuRage_Available = true; 121 | return true; 122 | } 123 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/include/stocksoup/sdkports/util.inc: -------------------------------------------------------------------------------- 1 | #if defined __stocksoup_sdkports_util_included 2 | #endinput 3 | #endif 4 | 5 | #define __stocksoup_sdkports_util_included 6 | 7 | /* Utility functions ported over from the Source SDK (util.cpp). */ 8 | 9 | /* Accurate screenfade implementation from Valve below. */ 10 | #define SCREENFADE_FRACBITS 9 11 | #define FFADE_IN 0x0001 // Just here so we don't pass 0 into the function 12 | #define FFADE_OUT 0x0002 // Fade out (not in) 13 | #define FFADE_MODULATE 0x0004 // Modulate (don't blend) 14 | #define FFADE_STAYOUT 0x0008 // ignores the duration, stays faded out until new ScreenFade message received 15 | #define FFADE_PURGE 0x0010 // Purges all other fades, replacing them with this one 16 | 17 | stock void UTIL_ScreenFade(int target, const int color[4], float flDuration, float flHoldTime, 18 | int flags = FFADE_IN) { 19 | UserMsg s_fadeUserMsgId = GetUserMessageId("Fade"); 20 | int targets[1]; 21 | targets[0] = target; 22 | 23 | int duration = FixedUnsigned16(flDuration, 1 << SCREENFADE_FRACBITS); 24 | int holdtime = FixedUnsigned16(flHoldTime, 1 << SCREENFADE_FRACBITS); 25 | 26 | Handle message = StartMessageEx(s_fadeUserMsgId, targets, 1); 27 | if (GetUserMessageType() == UM_Protobuf) { 28 | PbSetInt(message, "duration", duration); 29 | PbSetInt(message, "hold_time", holdtime); 30 | PbSetInt(message, "flags", flags); 31 | PbSetColor(message, "clr", color); 32 | } else { 33 | BfWriteShort(message, duration); 34 | BfWriteShort(message, holdtime); 35 | BfWriteShort(message, flags); 36 | BfWriteByte(message, color[0]); 37 | BfWriteByte(message, color[1]); 38 | BfWriteByte(message, color[2]); 39 | BfWriteByte(message, color[3]); 40 | } 41 | 42 | EndMessage(); 43 | } 44 | 45 | stock int FixedUnsigned16(float value, int scale) { 46 | int output = RoundFloat(value * scale); 47 | if (output < 0) { 48 | output = 0; 49 | } 50 | if (output > 0xFFFF) { 51 | output = 0xFFFF; 52 | } 53 | return output; 54 | } 55 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/rps4points.sp: -------------------------------------------------------------------------------- 1 | /* 2 | ____ ____ _____ __ __ ____ _ __ 3 | / __ \/ __ \/ ___/ / // / / __ \____ (_)___ / /______ 4 | / /_/ / /_/ /\__ \ / // /_ / /_/ / __ \/ / __ \/ __/ ___/ 5 | / _, _/ ____/___/ / /__ __/ / ____/ /_/ / / / / / /_(__ ) 6 | /_/ |_/_/ /____/ /_/ /_/ \____/_/_/ /_/\__/____/ 7 | A new way to earn queue points in Freak Fortress 2 8 | by SHADoW NiNE TR3S 9 | 10 | HOW IT WORKS: 11 | RPS a teammate or a minion. 12 | Whoever wins earns a certain amount of queue points 13 | while the loser loses these specified queue points 14 | 15 | ADJUSTING PRIZE QUEUE POINTS: 16 | Set "rps4points_points" to a value higher than 0 to enable. 17 | This amount gets added to the winner and subtracted from 18 | the loser, as long as the winner/loser is not a current boss. 19 | 20 | OPTIONAL: 21 | If you want to slay a boss that loses on RPS, set cvar 22 | "rps4points_slay_boss" to 1. Kill will be credited to 23 | the RPS winner. 24 | 25 | If you want updater support to receive the latest updates 26 | and have updater installed, set "rps4points_updater" to 1 27 | */ 28 | 29 | #pragma semicolon 1 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #pragma newdecls required 37 | 38 | // Version Number 39 | #define MAJOR_REVISION "1" 40 | #define MINOR_REVISION "1" 41 | #define PATCH_REVISION "1" 42 | 43 | #if !defined PATCH_REVISION 44 | #define PLUGIN_VERSION MAJOR_REVISION..."."...MINOR_REVISION 45 | #else 46 | #define PLUGIN_VERSION MAJOR_REVISION..."."...MINOR_REVISION..."."...PATCH_REVISION 47 | #endif 48 | 49 | public Plugin myinfo = { 50 | name = "Freak Fortress 2: RPS4Points*", 51 | author = "SHADoW NiNE TR3S", 52 | description="Gamble for FF2 queue points using Rock, Paper, Scissors taunt", 53 | version=PLUGIN_VERSION, 54 | }; 55 | 56 | int RPSWinner; 57 | bool RPSLoser[MAXPLAYERS+1]=false; 58 | Handle cvarRPSQueuePoints; 59 | Handle cvarKillBoss; 60 | 61 | public void OnPluginStart() 62 | { 63 | CreateConVar("rps4points_version", PLUGIN_VERSION, "RPS4Points Version", FCVAR_REPLICATED|FCVAR_NOTIFY|FCVAR_SPONLY|FCVAR_DONTRECORD); 64 | cvarKillBoss=CreateConVar("rps4points_slay_boss", "0", "0-Don't slay boss if boss loses on RPS, 1-Slay boss if boss loses on RPS", _, true, 0.0, true, 1.0); 65 | cvarRPSQueuePoints=CreateConVar("rps4points_points", "10", "Points awarded / removed on RPS result"); 66 | 67 | HookEvent("rps_taunt_event", Event_RPSTaunt); 68 | 69 | LoadTranslations("rps4points.phrases"); 70 | } 71 | 72 | stock bool IsValidClient(int client) 73 | { 74 | if (client<=0 || client>MaxClients) 75 | return false; 76 | 77 | return IsClientInGame(client); 78 | } 79 | 80 | stock bool IsBoss(int client) 81 | { 82 | if(FF2_GetBossIndex(client)==-1) return false; 83 | return true; 84 | } 85 | 86 | public void Event_RPSTaunt(Event event, const char[] name, bool dontBroadcast) 87 | { 88 | int winner = GetEventInt(event, "winner"); 89 | int loser = GetEventInt(event, "loser"); 90 | 91 | // Make sure winner or loser are valid 92 | if(!IsValidClient(winner) || !IsValidClient(loser)) 93 | { 94 | return; 95 | } 96 | 97 | // If boss slay cvar is enabled, slay boss if they lose on RPS. 98 | if(!IsBoss(winner) && IsBoss(loser) && GetConVarBool(cvarKillBoss)) 99 | { 100 | RPSWinner=winner; 101 | RPSLoser[loser]=true; 102 | CreateTimer(3.1, DelayRPSDeath, loser); 103 | return; 104 | } 105 | 106 | // If both parties are non-bosses, they can RPS for queue points 107 | if(!IsBoss(winner) && !IsBoss(loser) && FF2_GetQueuePoints(loser)>=GetConVarInt(cvarRPSQueuePoints) && GetConVarInt(cvarRPSQueuePoints)>0) 108 | { 109 | CPrintToChat(winner, "{olive}[FF2]{default} %t", "rps_won", GetConVarInt(cvarRPSQueuePoints), loser); 110 | FF2_SetQueuePoints(winner, FF2_GetQueuePoints(winner)+GetConVarInt(cvarRPSQueuePoints)); 111 | 112 | CPrintToChat(loser, "{olive}[FF2]{default} %t", "rps_lost", GetConVarInt(cvarRPSQueuePoints), winner); 113 | FF2_SetQueuePoints(loser, FF2_GetQueuePoints(loser)-GetConVarInt(cvarRPSQueuePoints)); 114 | } 115 | } 116 | 117 | public Action DelayRPSDeath(Handle timer, any client) 118 | { 119 | if(IsValidClient(client)) 120 | { 121 | int boss=FF2_GetBossIndex(client); 122 | if(boss>=0) 123 | { 124 | SDKHooks_TakeDamage(client, RPSWinner, RPSWinner, float(FF2_GetBossHealth(boss)), DMG_GENERIC, -1); 125 | } 126 | } 127 | } 128 | 129 | #file "FF2 Plugin: RPS 4 Points" 130 | -------------------------------------------------------------------------------- /addons/sourcemod/scripting/streaker.sp: -------------------------------------------------------------------------------- 1 | #pragma semicolon 1 2 | 3 | #include 4 | #undef REQUIRE_PLUGIN 5 | #tryinclude 6 | #tryinclude 7 | #tryinclude 8 | #define REQUIRE_PLUGIN 9 | 10 | #if SOURCEMOD_V_MINOR > 7 11 | #pragma newdecls required 12 | #endif 13 | 14 | // Version Number 15 | #define MAJOR_REVISION "1" 16 | #define MINOR_REVISION "0" 17 | //#define PATCH_REVISION "0" 18 | 19 | #if !defined PATCH_REVISION 20 | #define PLUGIN_VERSION MAJOR_REVISION..."."...MINOR_REVISION 21 | #else 22 | #define PLUGIN_VERSION MAJOR_REVISION..."."...MINOR_REVISION..."."...PATCH_REVISION 23 | #endif 24 | 25 | public Plugin myinfo = { 26 | name = "[VSH/FF2]: Streaker", 27 | author = "SHADoW NiNE TR3S", 28 | description="Killstreak count increaser for VS Saxton Hale & Freak Fortress 2", 29 | version=PLUGIN_VERSION, 30 | }; 31 | 32 | 33 | #if defined _updater_included 34 | #define UPDATE_URL "http://www.shadow93.info/tf2/tf2plugins/streaker/update.txt" 35 | #endif 36 | 37 | #if defined _VSH_included 38 | bool isVSH=false; 39 | #endif 40 | 41 | #if defined _FF2_included 42 | bool isFF2=false; 43 | #endif 44 | 45 | Handle cvarKStreakDmg; 46 | Handle cvarKStreak; 47 | Handle cvarUpdater; 48 | 49 | public void OnPluginStart() 50 | { 51 | CreateConVar("streaker_version", PLUGIN_VERSION, "Streaker Version", FCVAR_REPLICATED|FCVAR_NOTIFY|FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_DONTRECORD); 52 | 53 | cvarUpdater=CreateConVar("streaker_updater", "0", "0-Disable Updater support, 1-Enable automatic updating (requires Updater)", FCVAR_PLUGIN, true, 0.0, true, 1.0); 54 | cvarKStreakDmg=CreateConVar("streaker_kstreak_dmg", "200", "Amount of damage required to increase killstreak count", FCVAR_PLUGIN); 55 | cvarKStreak=CreateConVar("streaker_kstreak", "1", "Increases your killstreak count by this amount", FCVAR_PLUGIN); 56 | 57 | HookEvent("player_hurt", Event_PlayerHurt); 58 | HookConVarChange(cvarUpdater, CvarChange); 59 | } 60 | 61 | public void OnLibraryAdded(const char[] name) 62 | { 63 | #if defined _updater_included 64 | if (StrEqual(name, "updater") && GetConVarBool(cvarUpdater)) 65 | { 66 | Updater_AddPlugin(UPDATE_URL); 67 | } 68 | #endif 69 | 70 | #if defined _VSH_included 71 | if (StrEqual(name, "saxtonhale")) 72 | { 73 | isVSH=true; 74 | } 75 | #endif 76 | 77 | #if defined _FF2_included 78 | if (StrEqual(name, "freak_fortress_2")) 79 | { 80 | isFF2=true; 81 | } 82 | #endif 83 | } 84 | 85 | public void OnLibraryRemoved(const char[] name) 86 | { 87 | #if defined _updater_included 88 | if(StrEqual(name, "updater") && GetConVarBool(cvarUpdater)) 89 | { 90 | Updater_RemovePlugin(); 91 | } 92 | #endif 93 | 94 | #if defined _VSH_included 95 | if (StrEqual(name, "saxtonhale")) 96 | { 97 | isVSH=false; 98 | } 99 | #endif 100 | 101 | #if defined _FF2_included 102 | if (StrEqual(name, "freak_fortress_2")) 103 | { 104 | isFF2=false; 105 | } 106 | #endif 107 | } 108 | 109 | stock bool IsValidClient(int client) 110 | { 111 | if (client <= 0 || client > MaxClients) return false; 112 | if (!IsClientInGame(client) || !IsClientConnected(client)) return false; 113 | if (IsClientSourceTV(client) || IsClientReplay(client) || IsFakeClient(client)) return false; 114 | return true; 115 | } 116 | 117 | public void Event_PlayerHurt(Event event, const char[] name, bool dontBroadcast) 118 | { 119 | int attacker=GetClientOfUserId(event.GetInt("attacker")); 120 | int damage=event.GetInt("damageamount"); 121 | 122 | if(IsValidClient(attacker)) 123 | { 124 | #if defined _VSH_included 125 | if(isVSH) 126 | { 127 | if(GetClientTeam(attacker)==VSH_GetSaxtonHaleTeam()) 128 | return; 129 | } 130 | #endif 131 | 132 | #if defined _FF2_included 133 | if(isFF2) 134 | { 135 | if(GetClientTeam(attacker)==FF2_GetBossTeam()) 136 | return; 137 | } 138 | #endif 139 | 140 | static int kStreakCount; 141 | kStreakCount+=damage; 142 | if(kStreakCount>=GetConVarInt(cvarKStreakDmg)) 143 | { 144 | SetEntProp(attacker, Prop_Send, "m_nStreaks", GetEntProp(attacker, Prop_Send, "m_nStreaks")+GetConVarInt(cvarKStreak)); 145 | kStreakCount-=GetConVarInt(cvarKStreakDmg); 146 | } 147 | } 148 | } 149 | 150 | public void CvarChange(Handle convar, const char[] oldValue, const char[] newValue) 151 | { 152 | if(convar==cvarUpdater) 153 | { 154 | #if defined _updater_included 155 | GetConVarInt(cvarUpdater) ? Updater_AddPlugin(UPDATE_URL) : Updater_RemovePlugin(); 156 | #endif 157 | } 158 | } -------------------------------------------------------------------------------- /addons/sourcemod/scripting/vshbots_move.sp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | 5 | #pragma semicolon 1 6 | #pragma newdecls required 7 | 8 | float flag_pos[3]; 9 | float ClientPosition[3]; 10 | 11 | public Plugin myinfo= 12 | { 13 | name= "VSH/FF2 Bots[moving]", 14 | author= "tRololo312312", 15 | description= "Makes TFBots move to enemys location", 16 | version= "1.1", 17 | url= "http://steamcommunity.com/profiles/76561198039186809" 18 | } 19 | 20 | public void OnAllPluginsLoaded() 21 | { 22 | Handle PFind = FindPluginByFile("vshbots_logic.smx"); 23 | if(PFind != INVALID_HANDLE) 24 | { 25 | if(GetPluginStatus(PFind) != Plugin_Running) 26 | { 27 | SetFailState("logic plugin for these bots is not loaded!"); 28 | } 29 | } 30 | else 31 | { 32 | SetFailState("logic plugin for these bots is not loaded!"); 33 | } 34 | } 35 | 36 | public void OnPluginStart() 37 | { 38 | HookEvent("arena_round_start", RoundStarted); 39 | } 40 | 41 | public void OnMapStart() 42 | { 43 | CreateTimer(0.1, MoveTimer,_,TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE); 44 | } 45 | 46 | public Action OnFlagTouch(int point, int client) 47 | { 48 | for(client=1;client<=MaxClients;client++) 49 | { 50 | if(IsClientInGame(client)) 51 | { 52 | return Plugin_Handled; 53 | } 54 | } 55 | 56 | return Plugin_Continue; 57 | } 58 | 59 | public Action RoundStarted(Handle event , const char[] name , bool dontBroadcast) 60 | { 61 | CreateTimer(1.0, LoadStuff); 62 | CreateTimer(1.0, LoadStuff2); 63 | CreateTimer(2.0, FindFlag); 64 | } 65 | 66 | public Action LoadStuff(Handle timer) 67 | { 68 | int teamflags = CreateEntityByName("item_teamflag"); 69 | if(IsValidEntity(teamflags)) 70 | { 71 | DispatchKeyValue(teamflags, "trail_effect", "0"); 72 | DispatchKeyValue(teamflags, "ReturnTime", "1"); 73 | DispatchKeyValue(teamflags, "flag_model", "models/empty.mdl"); 74 | DispatchSpawn(teamflags); 75 | SetEntProp(teamflags, Prop_Send, "m_iTeamNum", 3); 76 | } 77 | } 78 | 79 | public Action LoadStuff2(Handle timer) 80 | { 81 | int teamflags2 = CreateEntityByName("item_teamflag"); 82 | if(IsValidEntity(teamflags2)) 83 | { 84 | DispatchKeyValue(teamflags2, "trail_effect", "0"); 85 | DispatchKeyValue(teamflags2, "ReturnTime", "1"); 86 | DispatchKeyValue(teamflags2, "flag_model", "models/empty.mdl"); 87 | DispatchSpawn(teamflags2); 88 | SetEntProp(teamflags2, Prop_Send, "m_iTeamNum", 2); 89 | } 90 | } 91 | 92 | public Action FindFlag(Handle timer) 93 | { 94 | int ent = -1; 95 | while ((ent = FindEntityByClassname(ent, "item_teamflag"))!=INVALID_ENT_REFERENCE) 96 | { 97 | SDKHook(ent, SDKHook_StartTouch, OnFlagTouch ); 98 | SDKHook(ent, SDKHook_Touch, OnFlagTouch ); 99 | } 100 | } 101 | 102 | public Action MoveTimer(Handle timer) 103 | { 104 | for(int client=1;client<=MaxClients;client++) 105 | { 106 | if(IsClientInGame(client)) 107 | { 108 | if(IsPlayerAlive(client)) 109 | { 110 | int entIndex = -1; 111 | int entIndex2 = -1; 112 | GetClientAbsOrigin(client, ClientPosition); 113 | int Ent = Client_GetClosest(ClientPosition, client); 114 | int team = GetClientTeam(client); 115 | if(team == 3) 116 | { 117 | GetClientAbsOrigin(client, flag_pos); 118 | while((entIndex = FindEntityByClassname(entIndex, "item_teamflag")) != INVALID_ENT_REFERENCE) 119 | { 120 | int iTeamNum = GetEntProp(entIndex, Prop_Send, "m_iTeamNum"); 121 | if (iTeamNum == 3) 122 | { 123 | TeleportEntity(entIndex, flag_pos, NULL_VECTOR, NULL_VECTOR); 124 | } 125 | } 126 | } 127 | if(Ent != -1 && team == 3) 128 | { 129 | static float ClosestClient[3]; 130 | GetClientAbsOrigin(Ent, ClosestClient); 131 | while((entIndex2 = FindEntityByClassname(entIndex2, "item_teamflag")) != INVALID_ENT_REFERENCE) 132 | { 133 | int iTeamNum = GetEntProp(entIndex2, Prop_Send, "m_iTeamNum"); 134 | if (iTeamNum == 2) 135 | { 136 | TeleportEntity(entIndex2, ClosestClient, NULL_VECTOR, NULL_VECTOR); 137 | } 138 | } 139 | } 140 | } 141 | } 142 | } 143 | } 144 | 145 | stock int Client_GetClosest(float vecOrigin_center[3], const int client) 146 | { 147 | static float vecOrigin_edict[3]; 148 | float distance = -1.0; 149 | int closestEdict = -1; 150 | for(int i=1;i<=MaxClients;i++) 151 | { 152 | if (!IsClientInGame(i) || !IsPlayerAlive(i) || (i == client)) 153 | continue; 154 | GetClientAbsOrigin(i, vecOrigin_edict); 155 | if(GetClientTeam(i) != GetClientTeam(client)) 156 | { 157 | float edict_distance = GetVectorDistance(vecOrigin_center, vecOrigin_edict); 158 | if((edict_distance < distance) || (distance == -1.0)) 159 | { 160 | distance = edict_distance; 161 | closestEdict = i; 162 | } 163 | } 164 | } 165 | return closestEdict; 166 | } 167 | -------------------------------------------------------------------------------- /addons/sourcemod/translations/ff2_1st_set.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "seeldier_rage_message" 4 | { 5 | "#format" "{1:s}" 6 | "en" "Now you are {1}'s minion! Attack other team!" 7 | "ru" "Теперь ты помощник {1}! Атакуй вражескую команду!" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /addons/sourcemod/translations/ff2_boss_selection.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "FF2Boss InGame Only" 4 | { 5 | "en" "In-game only" 6 | } 7 | 8 | "FF2Boss Can't change while playing boss." 9 | { 10 | "en" "You can not change boss while playing boss." 11 | } 12 | 13 | "FF2Boss Dont Play Boss" 14 | { 15 | "en" "leaved queue. (Queue point saved.)" 16 | } 17 | 18 | "FF2Boss Saved QueuePoints" 19 | { 20 | "#format" "{1:d}" 21 | "en" "Saved Queue points: {1}" 22 | } 23 | 24 | "FF2Boss Menu Title" 25 | { 26 | "#format" "{1:s}" 27 | "en" "Current Boss: {1}" 28 | } 29 | 30 | "FF2Boss Menu Random" 31 | { 32 | "en" "Random" 33 | } 34 | 35 | "FF2Boss Menu None" 36 | { 37 | "en" "I don't wanna play Boss." 38 | } 39 | 40 | "FF2Boss Selected" 41 | { 42 | "#format" "{1:s}" 43 | "en" "Selected: {orange}{1}{default}" 44 | } 45 | 46 | "FF2Boss Cant Chosse This Map" 47 | { 48 | "en" "Banned for this map!" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /addons/sourcemod/translations/ff2_boss_toggle.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "toggle_enabled" 4 | { 5 | "en" "FF2 Bosses are enabled for you. You are in the Boss queue." 6 | } 7 | 8 | "toggle_enabled_points" 9 | { 10 | "#format" "{1:i},{2:i}" 11 | "en" "FF2 Bosses are enabled for you. You are #{1} in Boss queue with {2} points." 12 | } 13 | 14 | "toggle_disabled" 15 | { 16 | "en" "FF2 Bosses are disabled for you. You won't be selected as a Boss." 17 | } 18 | 19 | "set_preference" 20 | { 21 | "en" "Please set your Boss spawn preference." 22 | } 23 | 24 | "toggle_command" 25 | { 26 | "en" "Use {olive}/ff2toggle{default} to toggle your Boss spawning preference." 27 | } 28 | 29 | "toggle_menu_title" 30 | { 31 | "en" "FF2 Boss Toggle" 32 | } 33 | 34 | "toggle_on_menu_option" 35 | { 36 | "en" "ON (Select me as a Boss)" 37 | } 38 | 39 | "toggle_off_menu_option" 40 | { 41 | "en" "OFF (Don't select me as a Boss)" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /addons/sourcemod/translations/ff2_luigi_ghost.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "charge_case2" 4 | { 5 | "en" "Invisibility: During your invisibility you can't attack" 6 | } 7 | "charge_ready_invisible" 8 | { 9 | "en" "Invisibility: Press the reload button for be invisible!" 10 | } 11 | } -------------------------------------------------------------------------------- /addons/sourcemod/translations/ff2_newsalmon.charge.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "summon_status" 4 | { 5 | "#format" "{1:i}" 6 | "en" "Summoning is {1} percent ready. When at 100 percent look up and stand up." 7 | } 8 | "summon_status_2" 9 | { 10 | "#format" "{1:i}" 11 | "en" "Summoning will be avaliable in {1} second(s)." 12 | } 13 | "super_duper_jump" 14 | { 15 | "en" "Super Duper jump is ready!" 16 | } 17 | "summon_ready" 18 | { 19 | "en" "Summoning is ready! Press Alt-fire or RELOAD button to summon!" 20 | } 21 | "minion_summoned" 22 | { 23 | "#format" "{1:s}" 24 | "en" "You are now a minion of {1}!" 25 | } 26 | "minion_summoner" 27 | { 28 | "en" "Your minions have spawned" 29 | } 30 | } -------------------------------------------------------------------------------- /addons/sourcemod/translations/ff2_otokiru.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "salmon_status" 4 | { 5 | "#format" "{1:i}" 6 | "en" "Summoning is {1} percent ready. When at 100 percent look up and stand up." 7 | } 8 | "salmon_status_2" 9 | { 10 | "#format" "{1:i}" 11 | "en" "Summoning will be avaliable in {1} second(s)." 12 | } 13 | "super_duper_jump" 14 | { 15 | "en" "Super Duper jump is ready!" 16 | } 17 | "jump_status" 18 | { 19 | "#format" "{1:i}" 20 | "en" "Jump charge is {1} percent. Look upwards and stand up for jump" 21 | } 22 | "jump_status_2" 23 | { 24 | "#format" "{1:i}" 25 | "en" "Super Jump will be avaliable in {1} second(s)." 26 | } 27 | } -------------------------------------------------------------------------------- /addons/sourcemod/translations/ff2_shadow93.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "summon_status" 4 | { 5 | "#format" "{1:i}" 6 | "en" "Summoning is {1} percent ready. When at 100 percent look up and stand up." 7 | } 8 | "summon_status_2" 9 | { 10 | "#format" "{1:i}" 11 | "en" "Summoning will be avaliable in {1} second(s)." 12 | } 13 | "super_duper_jump" 14 | { 15 | "en" "Super Duper jump is ready!" 16 | } 17 | "summon_ready" 18 | { 19 | "en" "Summoning is ready! Press Alt-fire or RELOAD button to summon!" 20 | } 21 | "minion_summoned" 22 | { 23 | "#format" "{1:s}" 24 | "en" "You are now a minion of {1}!" 25 | } 26 | "minion_summoner" 27 | { 28 | "en" "Your minions have spawned" 29 | } 30 | "build_notification" 31 | { 32 | "en" "You can now construct buildings!" 33 | } 34 | "sap_notification" 35 | { 36 | "en" "You can now sap buildings!" 37 | } 38 | "boss_saved" 39 | { 40 | "en" "Be careful around hazardous locations!" 41 | } 42 | } -------------------------------------------------------------------------------- /addons/sourcemod/translations/ff2_shadow93_bosses.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "time_to_kaboom" 4 | { 5 | "#format" "{1:s}" 6 | "en" "{1} is about to explode! Get out of their range!" 7 | } 8 | "life_regeneration" 9 | { 10 | "#format" "{1:i}" 11 | "en" "Extra Life in: {1} sec." 12 | } 13 | "delay_info" 14 | { 15 | "#format" "{1:i},{2:s}" 16 | "en" "Defeat {2} in {1} secs before a life regenerates!" 17 | } 18 | "regenerated_life" 19 | { 20 | "en" "An extra life has been regenerated." 21 | } 22 | "reimu_clone_disable" 23 | { 24 | "en" "You cannot spawn another clone until the clone dies" 25 | } 26 | } -------------------------------------------------------------------------------- /addons/sourcemod/translations/ff2boss.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "ff2boss_title" 4 | { 5 | "en" "Select Boss for YOUR Round! (/ff2boss)" 6 | "ru" "Выбери Босса для СВОЕГО Раунда! (/ff2boss)" 7 | } 8 | "ff2boss_random_option" 9 | { 10 | "en" "Random Boss" 11 | "ru" "Рандом" 12 | } 13 | "ff2boss_randomboss" 14 | { 15 | "en" "You will become a random boss." 16 | "ru" "Вы станете рандомным боссом." 17 | } 18 | "ff2boss_bossselected" 19 | { 20 | "#format" "{1:s}" 21 | "en" "You have selected {1} as your boss!" 22 | "ru" "Вы выбрали босса {1}!" 23 | } 24 | "ff2boss_bossnotfound" 25 | { 26 | "en" "Boss could not be found!" 27 | "ru" "Босс не найден!" 28 | } 29 | "ff2boss_confirm" 30 | { 31 | "#format" "{1:s}" 32 | "en" "Select {1}" 33 | "ru" "Выбрать {1}" 34 | } 35 | "ff2boss_cancel" 36 | { 37 | "en" "Cancel" 38 | "ru" "Отмена" 39 | } 40 | "ff2boss_nodesc" 41 | { 42 | "en" "No Boss Description" 43 | "ru" "Нет описания босса" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /addons/sourcemod/translations/ff2bossprefs.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "ff2boss_title" 4 | { 5 | "en" "Select Boss for YOUR Round! (/ff2boss)" 6 | "ru" "Выбери Босса для СВОЕГО Раунда!" 7 | } 8 | "ff2boss_enabled" 9 | { 10 | "en" "You currently have bosses enabled" 11 | } 12 | "ff2boss_disabled" 13 | { 14 | "en" "You currently have bosses disabled" 15 | } 16 | "ff2boss_current_selection" 17 | { 18 | "#format" "{1:s}" 19 | "en" "Your current selection is: {1}" 20 | } 21 | "ff2boss_random_option" 22 | { 23 | "en" "Random Boss" 24 | "ru" "Рандом" 25 | } 26 | "ff2boss_randomboss" 27 | { 28 | "en" "You will become a random boss." 29 | "ru" "Вы станете рандомным боссом." 30 | } 31 | "ff2boss_bossselected" 32 | { 33 | "#format" "{1:s}" 34 | "en" "You have selected {1} as your boss!" 35 | "ru" "Вы выбрали босса {1}!" 36 | } 37 | "ff2boss_bossnotfound" 38 | { 39 | "en" "Boss could not be found!" 40 | "ru" "Босс не найден!" 41 | } 42 | "ff2boss_selection_adminoverride" 43 | { 44 | "en" "Your boss selection has been overridden by an admin!" 45 | } 46 | "toggle_enabled" 47 | { 48 | "en" "Bosses are currently enabled for you. You are in the boss queue." 49 | } 50 | "toggle_enabled_points" 51 | { 52 | "#format" "{1:i},{2:i}" 53 | "en" "Bosses are enabled for you. You are #{1} in the boss queue with {2} points." 54 | } 55 | "toggle_disabled" 56 | { 57 | "en" "Bosses are currently disabled for you. You won't be selected as a boss." 58 | } 59 | "set_preference" 60 | { 61 | "en" "Please set your boss queue preferences." 62 | } 63 | "toggle_command" 64 | { 65 | "en" "Type {olive}/ff2toggle{default} to toggle your boss spawning preferences!" 66 | } 67 | "toggle_menu_title" 68 | { 69 | "en" "Boss queue preferences:" 70 | } 71 | "toggle_on_menu_option" 72 | { 73 | "en" "Enable becoming a boss" 74 | } 75 | "toggle_off_menu_option" 76 | { 77 | "en" "Never become a boss" 78 | } 79 | "ff2boss_confirm" 80 | { 81 | "#format" "{1:s}" 82 | "en" "Select {1}" 83 | "ru" "Выбрать {1}" 84 | } 85 | "ff2boss_cancel" 86 | { 87 | "en" "Cancel" 88 | "ru" "Отмена" 89 | } 90 | "ff2boss_nodesc" 91 | { 92 | "en" "No Boss Description" 93 | "ru" "Нет описания босса" 94 | } 95 | } -------------------------------------------------------------------------------- /addons/sourcemod/translations/ff2kstreak.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "Prefix" 4 | { 5 | "en" "{olive}[FF2]{default} " 6 | } 7 | "ca" 8 | { 9 | "en" "Could not find any matching results" 10 | } 11 | "cb" 12 | { 13 | "en" "You have enabled killstreaks" 14 | } 15 | "cc" 16 | { 17 | "en" "You have disabled killstreaks" 18 | } 19 | "cd" 20 | { 21 | "en" "You have turned off killstreak preferences" 22 | } 23 | "ce" 24 | { 25 | "en" "You have choosen Team Shine as a Sheen" 26 | } 27 | "cf" 28 | { 29 | "en" "You have choosen Deadly Daffodil as a Sheen" 30 | } 31 | "cg" 32 | { 33 | "en" "You have choosen Manndarin as a Sheen" 34 | } 35 | "ch" 36 | { 37 | "en" "You have choosen Mean Green as a Sheen" 38 | } 39 | "ci" 40 | { 41 | "en" "You have choosen Agonizing Emerald as a Sheen" 42 | } 43 | "cj" 44 | { 45 | "en" "You have choosen Villainous Violet as a Sheen" 46 | } 47 | "ck" 48 | { 49 | "en" "You have choosen Hot Rod as a Sheen" 50 | } 51 | "cl" 52 | { 53 | "en" "You have disabled Sheens" 54 | } 55 | "cm" 56 | { 57 | "en" "You have turned off Sheen preferences" 58 | } 59 | "cn" 60 | { 61 | "en" "You have choosen Fire Horns as a Killstreaker" 62 | } 63 | "co" 64 | { 65 | "en" "You have choosen Cerebral Discharge as a Killstreaker" 66 | } 67 | "cp" 68 | { 69 | "en" "You have choosen Tornado as a Killstreaker" 70 | } 71 | "cq" 72 | { 73 | "en" "You have choosen Flames as a Killstreaker" 74 | } 75 | "cr" 76 | { 77 | "en" "You have choosen Singularity as a Killstreaker" 78 | } 79 | "cs" 80 | { 81 | "en" "You have choosen Incinerator as a Killstreaker" 82 | } 83 | "ct" 84 | { 85 | "en" "You have choosen Hypno-Beam as a Killstreaker" 86 | } 87 | "cu" 88 | { 89 | "en" "You have disabled Killstreakers" 90 | } 91 | "cv" 92 | { 93 | "en" "You have turned off Killstreaker preferences" 94 | } 95 | 96 | "ma" 97 | { 98 | "en" "Killstreak Prefences" 99 | } 100 | "mb" 101 | { 102 | "en" "Toggle" 103 | } 104 | "mc" 105 | { 106 | "en" "Sheens" 107 | } 108 | "md" 109 | { 110 | "en" "Killstreakers" 111 | } 112 | "me" 113 | { 114 | "en" "Team Shine" 115 | } 116 | "mf" 117 | { 118 | "en" "Deadly Daffodil" 119 | } 120 | "mg" 121 | { 122 | "en" "Manndarin" 123 | } 124 | "mh" 125 | { 126 | "en" "Mean Green" 127 | } 128 | "mi" 129 | { 130 | "en" "Agonizing Emerald" 131 | } 132 | "mj" 133 | { 134 | "en" "Villainous Violet" 135 | } 136 | "mk" 137 | { 138 | "en" "Hot Rod" 139 | } 140 | "ml" 141 | { 142 | "en" "Fire Horns" 143 | } 144 | "mm" 145 | { 146 | "en" "Cerebral Discharge" 147 | } 148 | "mn" 149 | { 150 | "en" "Tornado" 151 | } 152 | "mo" 153 | { 154 | "en" "Flames" 155 | } 156 | "mp" 157 | { 158 | "en" "Singularity" 159 | } 160 | "mq" 161 | { 162 | "en" "Incinerator" 163 | } 164 | "mr" 165 | { 166 | "en" "Hypno-Beam" 167 | } 168 | "ms" 169 | { 170 | "en" "None" 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /addons/sourcemod/translations/ff2stats.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "ff2stats" 4 | { 5 | 6 | "en" "Your Boss stats are:" 7 | } 8 | 9 | "on" 10 | { 11 | "en" "on" 12 | } 13 | 14 | "off" 15 | { 16 | "en" "off" 17 | } 18 | } -------------------------------------------------------------------------------- /addons/sourcemod/translations/freedom_abilities.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "Faster Rage" 4 | { 5 | "#format" "{1:i}" 6 | "en" "You can rage after {1} damage taken." 7 | } 8 | "Dash Ready" 9 | { 10 | "en" "Your dash has cooldowned and is ready to use." 11 | } 12 | "True Power Charge" 13 | { 14 | "#format" "{1:i}" 15 | "en" "Your TRUE POWER's charge is {1}!" 16 | } 17 | "True Power Cooldown" 18 | { 19 | "#format" "{1:i}" 20 | "en" "Your TRUE POWER will be ready in {1} seconds." 21 | } 22 | } -------------------------------------------------------------------------------- /addons/sourcemod/translations/rps4points.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "rps_lost" 4 | { 5 | "#format" "{1:i},{2:N}" 6 | "en" "You lost {1} queue points to {2}!" 7 | } 8 | "rps_won" 9 | { 10 | "#format" "{1:i},{2:N}" 11 | "en" "You won {1} queue points from {2}!" 12 | } 13 | } -------------------------------------------------------------------------------- /materials/freak_fortress_2/dots/alt_fire_overlay1.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$baseTexture" "freak_fortress_2\dots\alt_fire_overlay1" 4 | "$translucent" 1 5 | "$ignorez" "1" 6 | "$no_fullbright" "1" 7 | } -------------------------------------------------------------------------------- /materials/freak_fortress_2/dots/alt_fire_overlay1.vtf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Batfoxkid/FF2-Library/af0cfa7ac618d9e25a8916e43c42db497c3657ce/materials/freak_fortress_2/dots/alt_fire_overlay1.vtf -------------------------------------------------------------------------------- /materials/freak_fortress_2/dots/alt_fire_overlay2.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$baseTexture" "freak_fortress_2\dots\alt_fire_overlay2" 4 | "$translucent" 1 5 | "$ignorez" "1" 6 | "$no_fullbright" "1" 7 | } -------------------------------------------------------------------------------- /materials/freak_fortress_2/dots/alt_fire_overlay2.vtf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Batfoxkid/FF2-Library/af0cfa7ac618d9e25a8916e43c42db497c3657ce/materials/freak_fortress_2/dots/alt_fire_overlay2.vtf -------------------------------------------------------------------------------- /materials/freak_fortress_2/dots/attack3_overlay1.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$baseTexture" "freak_fortress_2\dots\attack3_overlay1" 4 | "$translucent" 1 5 | "$ignorez" "1" 6 | "$no_fullbright" "1" 7 | } -------------------------------------------------------------------------------- /materials/freak_fortress_2/dots/attack3_overlay1.vtf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Batfoxkid/FF2-Library/af0cfa7ac618d9e25a8916e43c42db497c3657ce/materials/freak_fortress_2/dots/attack3_overlay1.vtf -------------------------------------------------------------------------------- /materials/freak_fortress_2/dots/attack3_overlay2.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$baseTexture" "freak_fortress_2\dots\attack3_overlay2" 4 | "$translucent" 1 5 | "$ignorez" "1" 6 | "$no_fullbright" "1" 7 | } -------------------------------------------------------------------------------- /materials/freak_fortress_2/dots/attack3_overlay2.vtf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Batfoxkid/FF2-Library/af0cfa7ac618d9e25a8916e43c42db497c3657ce/materials/freak_fortress_2/dots/attack3_overlay2.vtf -------------------------------------------------------------------------------- /materials/freak_fortress_2/dots/reload_overlay1.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$baseTexture" "freak_fortress_2\dots\reload_overlay1" 4 | "$translucent" 1 5 | "$ignorez" "1" 6 | "$no_fullbright" "1" 7 | } -------------------------------------------------------------------------------- /materials/freak_fortress_2/dots/reload_overlay1.vtf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Batfoxkid/FF2-Library/af0cfa7ac618d9e25a8916e43c42db497c3657ce/materials/freak_fortress_2/dots/reload_overlay1.vtf -------------------------------------------------------------------------------- /materials/freak_fortress_2/dots/reload_overlay2.vmt: -------------------------------------------------------------------------------- 1 | "UnlitGeneric" 2 | { 3 | "$baseTexture" "freak_fortress_2\dots\reload_overlay2" 4 | "$translucent" 1 5 | "$ignorez" "1" 6 | "$no_fullbright" "1" 7 | } -------------------------------------------------------------------------------- /materials/freak_fortress_2/dots/reload_overlay2.vtf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Batfoxkid/FF2-Library/af0cfa7ac618d9e25a8916e43c42db497c3657ce/materials/freak_fortress_2/dots/reload_overlay2.vtf -------------------------------------------------------------------------------- /scripts/compile.sh: -------------------------------------------------------------------------------- 1 | cd build/addons/sourcemod/scripting 2 | ./compile.sh *.sp 3 | 4 | mkdir -p compiled/freaks 5 | ./compile.sh freaks/*.sp -------------------------------------------------------------------------------- /scripts/date.sh: -------------------------------------------------------------------------------- 1 | SEC=$(date "+%s") 2 | MIN=$(expr $((SEC)) / 60) 3 | echo ::set-env name=DATE_VERSION::$MIN -------------------------------------------------------------------------------- /scripts/install.sh: -------------------------------------------------------------------------------- 1 | mkdir -p build/addons/sourcemod 2 | cd build 3 | 4 | cp -r ../addons/sourcemod/scripting addons/sourcemod 5 | cp -r ../sm/addons/sourcemod/scripting/include addons/sourcemod/scripting 6 | cp -r ../sm/addons/sourcemod/scripting/compile.sh addons/sourcemod/scripting 7 | cp -r ../sm/addons/sourcemod/scripting/spcomp addons/sourcemod/scripting 8 | cd addons/sourcemod/scripting 9 | 10 | wget "https://forums.alliedmods.net/attachment.php?attachmentid=79000&d=1292171445" -O include/colors.inc 11 | wget "https://raw.githubusercontent.com/peace-maker/DHooks2/dynhooks/sourcemod/scripting/include/dhooks.inc" -O include/dhooks.inc 12 | wget "https://raw.githubusercontent.com/Batfoxkid/FreakFortressBat/master/addons/sourcemod/scripting/include/freak_fortress_2.inc" -O include/freak_fortress_2.inc 13 | wget "https://raw.githubusercontent.com/Batfoxkid/FreakFortressBat/master/addons/sourcemod/scripting/include/freak_fortress_2_stocks.inc" -O include/freak_fortress_2_stocks.inc 14 | wget "https://raw.githubusercontent.com/Batfoxkid/FreakFortressBat/master/addons/sourcemod/scripting/include/freak_fortress_2_subplugin.inc" -O include/freak_fortress_2_subplugin.inc 15 | wget "https://raw.githubusercontent.com/Batfoxkid/FreakFortressBat/master/addons/sourcemod/scripting/include/freak_fortress_2_vsh_feedback.inc" -O include/freak_fortress_2_vsh_feedback.inc 16 | wget "https://raw.githubusercontent.com/Flyflo/SM-Goomba-Stomp/master/addons/sourcemod/scripting/include/goomba.inc" -O include/goomba.inc 17 | wget "https://raw.githubusercontent.com/DoctorMcKay/sourcemod-plugins/master/scripting/include/morecolors.inc" -O include/morecolors.inc 18 | wget "https://forums.alliedmods.net/attachment.php?attachmentid=115795&d=1360508618" -O include/rtd.inc 19 | wget "https://raw.githubusercontent.com/Phil25/RTD/master/scripting/include/rtd2.inc" -O include/rtd2.inc 20 | wget "https://raw.githubusercontent.com/Silenci0/SMAC/master/addons/sourcemod/scripting/include/smac.inc" -O include/smac.inc 21 | wget "https://raw.githubusercontent.com/Silenci0/SMAC/master/addons/sourcemod/scripting/include/smac_stocks.inc" -O include/smac_stocks.inc 22 | wget "https://raw.githubusercontent.com/asherkin/SteamTools/master/plugin/steamtools.inc" -O include/steamtools.inc 23 | wget "https://forums.alliedmods.net/attachment.php?attachmentid=116849&d=1377667508" -O include/tf2attributes.inc 24 | wget "https://raw.githubusercontent.com/asherkin/TF2Items/master/pawn/tf2items.inc" -O include/tf2items.inc 25 | wget "https://raw.githubusercontent.com/nosoop/SM-TFCustAttr/master/scripting/include/tf_custom_attributes.inc" -O include/tf_custom_attributes.inc 26 | 27 | sed -i'' 's/required = 1/#if defined REQUIRE_PLUGIN\nrequired = 1\n\#else\nrequired = 0/' include/rtd.inc -------------------------------------------------------------------------------- /scripts/package.sh: -------------------------------------------------------------------------------- 1 | cd build 2 | 3 | mkdir -p package/addons/sourcemod 4 | 5 | cp -r ../addons/sourcemod/configs package/addons/sourcemod 6 | cp -r ../addons/sourcemod/gamedata package/addons/sourcemod 7 | cp ../addons/sourcemod/scripting/compiled package/addons/sourcemod/plugins 8 | cp -r ../addons/sourcemod/translations package/addons/sourcemod 9 | cp -r ../materials package 10 | cp -r ../sound package 11 | cp -r ../LICENSE.txt package -------------------------------------------------------------------------------- /scripts/sourcemod.sh: -------------------------------------------------------------------------------- 1 | mkdir sm 2 | cd sm 3 | 4 | wget --input-file=http://sourcemod.net/smdrop/$SM_VERSION/sourcemod-latest-linux 5 | tar -xzf $(cat sourcemod-latest-linux) -------------------------------------------------------------------------------- /sound/war3source/blinkarrival.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Batfoxkid/FF2-Library/af0cfa7ac618d9e25a8916e43c42db497c3657ce/sound/war3source/blinkarrival.wav -------------------------------------------------------------------------------- /sound/war3source/entanglingrootsdecay1.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Batfoxkid/FF2-Library/af0cfa7ac618d9e25a8916e43c42db497c3657ce/sound/war3source/entanglingrootsdecay1.wav -------------------------------------------------------------------------------- /sound/war3source/lightningbolt.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Batfoxkid/FF2-Library/af0cfa7ac618d9e25a8916e43c42db497c3657ce/sound/war3source/lightningbolt.wav --------------------------------------------------------------------------------