<div><font size="6">Danmaku Fortress</font><br /><font size="3">An almost-TC Bullet Hell mode for TF2</font> <font size="1">(and may be ported elsewhere)</font><br /><img src="http://www.pamelabow...u_fortress.jpg" border="0" alt="" /><br /><font size="1">Not for the faint of heart...</font><br /><br /><font size="4"><u>Video Demonstration</u></font><br /><iframe width="420" height="315" src="https://www.youtube....iEES5dpo?rel=0" frameborder="0" allowfullscreen></iframe><br /><br /><font size="4"><u>Files</u></font><br />df_sourcemod.zip - <b>Attached at the bottom of this post.</b> Configs, sources, includes, and compiled plugins. To install, drag and drop this sourcemod dir onto your server's sourcemod dir.<br /><a href="http://www.pamelabow..._resources.zip" target="_blank">danmaku_fortress_resources.zip</a> - Materials, models, sounds for the core and the pack-in bosses. Also contains a map that DF will play on. These MUST exist on the server side. I would recommend installing these under custom/danmaku_fortress instead of download, as many of the models are likely to be updated with better animation if this game mode finds an audience. (and update means &quot;new models added, old models removed&quot;, since client asset overwrite is impossible)<br /><a href="http://www.pamelabow...ess_fastdl.zip" target="_blank">danmaku_fortress_fastdl.zip</a> - <b>OPTIONAL</b> FastDL files, put these on your FastDL server.<br /><br /><font size="4"><u>Dependencies</u></font><ul><li><a href="https://forums.allie...d.php?t=185016" target="_blank">morecolors.inc</a></li>
<li><a href="https://forums.allie...d.php?t=115100" target="_blank">tf2items</a> - It's a long story...and frankly it makes my sanity hurt. Read the Known Issues for more information.</li>
</ul><br /><font size="4"><u>Recommended Plugins</u></font>[list][*]<a href="https://forums.allie....php?p=1694178" target="_blank">ThirdPerson (non-cheats version)</a> - Giving the player the option to swap between first and third person is great. If this is missing, the <b>df_tp</b> and <b>df_fp</b> commands are available, but your players won't instinctively know to look for them.<br /><br /><font size="4"><u>Interacts Badly With</u></font><ul><li> Instant respawn (absolutely will screw up this plugin), however TF2's not-so-instant respawn should be fine, since it's actually a 4 or so second delay.</li>
<li> Any aggressive auto-balance plugin which also targets the living (will cause players to forfeit), TF2's autobalance is already disabled for this reason.</li>
<li> Class limit plugins could be a problem, since all combatants are forced pyro.</li>
<li> Any plugin that prevents OnMapStart() from executing. (i.e. a quarantine system -- not needed for this plugin, it auto-quarantines)</li>
<li> Freak Fortress 2 needs to be quarantined as it can interfere with the spawn/team assignment code and stop matches before they can start.</li>
</ul><br /><font size="4"><u>What is Danmaku Fortress?</u></font><br />Danmaku Fortress is a unique game mode based on Bullet Hell, with obvious heavy inspiration from Touhou. It's intended to be danmaku in a 3D arena, which really hasn't been attempted much.<br /><br />All battles are 1 on 1. One player is the &quot;hero&quot;, which is the typical danmaku protaganist. (i.e. Reimu Hakurei) The hero has a tiny hitbox that is really just a point in 3D space. The hero typically has only two abilities, standard fire and a desperation ability. The hero can have more abilities and even cooldown on said abilities, but as of v1.0.0 none of the pack-in heroes use this feature. Standard fire is &quot;shoot forward, stuff dies&quot;. Each projectile does damage to the boss. The desperation ability is like a bomb in danmaku games. What the bomb does varies widely, but it always makes the hero invincible for a short time. The hero has a limited number of lives, and they lose if they die at 0 lives. Depending on the hero's difficulty setting, the hero will automatically use bombs when hit, or always lose a life when hit.<br /><br />The other player is the &quot;boss&quot;, antagonists like Flandre Scarlet and Koishi Komeiji. The boss has a larger hitbox than the hero, and has a life bar instead of a lives/bombs system. Some bosses even have phases, which determines what abilities can be used based on the boss' health. Boss abilities are far less direct than hero abilities, and are meant to turn the arena into an everchanging minefield that the hero must navigate. Bosses are also slower than heroes, necessary for balance reasons.<br /><br />Danmaku Fortress is built from the ground up, and one of the best features for server operators is that it only runs on maps which are specifically made for the mod. Maps without the prefixes df_, danmaku_, or touhou_ will cause the plugin to temporarily quarantine itself. It should not cause other plugins to malfunction -- let me know if this isn't the case! Another interesting feature is its use of recursion instead of natives and forwards, which remove load order concerns which prompt other modular mods to quarantine its subplugins. (i.e. FF2 with the .ff2 extension)<br /><br />It features a lot of customization options, more than I could explain in this blurb. There are tons of cvars for aesthetics and gameplay balancing. It includes a music player which I wrote specifically for game music, and this can be customized as well. It has a modular design which allows for hero, boss, and ability creation. I built it from the ground up but took inspiration from the good features of FF2, like similar config file designs and the modular concept, while focusing on the framework early on with a set code structure in mind. The code is neat, readable, and categorized, while the &quot;one game frame&quot; design philosophy along with its time synchronization ensures stability.<br /><br /><font size="4"><u>Controls</u></font><br />The controls are as follows. They're not so great, but given the limitations of the engine (i.e. pitch clamped to [-89.0..89.0]) it's the least awkward I could come up with. 6dof would be great, but it's just not possible -- and I figured the control scheme would fit best with the precision of danmaku games, versus Valve's fly/noclip controls.<br /><br /><b>WASD</b> - Move around, but it's limited to the x/y axis.<br /><b>Jump</b> - Move up<br /><b>Secondary Fire</b> - Move down<br /><b>Primary Fire</b> - Use ability (if autofire is enabled for heroes, this key stops firing)<br /><b>Reload</b> - Change ability<br /><b>Use</b> - Change ability in reverse. Hidden feature since use isn't bound in TF2 by default.<br /><b>Special or Crouch</b> - Precision mode, move at half speed. (note: Special defaults to middle mouse)<br /><b>Call for Medic</b> - Use bomb (hero only, Hard difficulty or higher)<br /><br /><font size="4"><u>Main Menu and Commands</u></font><br /><font size="3"><b>Main Menu</b></font><br /><div style="margin: 5px;">
<div class="smallfont" style="margin-bottom: 2px;">
<b>Spoiler</b> <input value="Show" style="margin: 0px; padding: 0px; width: 45px; font-size: 10px;" onclick="if(this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display != 'inline')
{ this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'inline'; this.innerText = ''; this.value = 'Hide'; }
else
{ this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'none'; this.innerText = ''; this.value='Show'; }" type="button">
</div>
<div class="alt2" style="border: 1px inset; padding: 6px;">
<div class="spoiler" style="display: none;"><br />Main menu accessed via <b>/df</b>:<ul><li>Prints a help message to the user.</li>
<li>Swaps between never be player, prefer hero, prefer boss, and no preference.</li>
<li>Toggle hero autofire</li>
<li>Select a hero (this is stored forever until the user changes it)</li>
<li>Select a boss (this is stored forever until user changes it)</li>
<li>Change difficulty (last menu option since it's not recommended for new players) Difficulty affects your final score, along with your opponent's.</li>
<li>Normal difficulty is the default. Bombs save your life.</li>
<li>Hard difficulty is where &quot;balance&quot; is meant to be centered. Bombs must be activated manually. Get hit and you lose a life.</li>
<li>Lunatic difficulty is like Hard, but you don't get more bombs on lose life.</li>
</ul></div>
</div>
</div><br /><br /><font size="3"><b>Player Commands</b></font><br /><div style="margin: 5px;">
<div class="smallfont" style="margin-bottom: 2px;">
<b>Spoiler</b> <input value="Show" style="margin: 0px; padding: 0px; width: 45px; font-size: 10px;" onclick="if(this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display != 'inline')
{ this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'inline'; this.innerText = ''; this.value = 'Hide'; }
else
{ this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'none'; this.innerText = ''; this.value='Show'; }" type="button">
</div>
<div class="alt2" style="border: 1px inset; padding: 6px;">
<div class="spoiler" style="display: none;"><ul><li><b>df_queue</b> - View queue points</li>
<li><b>df_music</b> - View music chooser. Danmaku Fortress has a custom coded music player made especially for game music. I'm thinking of someday making a standalone plugin with just this.</li>
<li><b>df_tp</b> and <b>df_fp</b> - Thirdperson and firstperson commands. These are only usable if the Thirdperson plugin is not loaded.</li>
<li><b>df_tutorial</b> - An unadvertised command (borderline debug) that prints all tutorial messages.</li>
<li><b>df_never</b>, <b>df_wanthero</b>, <b>df_wantboss</b>, <b>df_wantany</b>, <b>df_boss</b>, <b>df_hero</b>, <b>df_difficulty</b>, and <b>df_autofire</b> are all the commands invoked by the main menu.</li>
<li><b>df_help</b>, <b>danmaku</b>, and <b>touhou</b> are all aliases for the <b>df</b> command.</li>
</ul></div>
</div>
</div><br /><br /><font size="3"><b>Admin Commands</b></font><br /><div style="margin: 5px;">
<div class="smallfont" style="margin-bottom: 2px;">
<b>Spoiler</b> <input value="Show" style="margin: 0px; padding: 0px; width: 45px; font-size: 10px;" onclick="if(this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display != 'inline')
{ this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'inline'; this.innerText = ''; this.value = 'Hide'; }
else
{ this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'none'; this.innerText = ''; this.value='Show'; }" type="button">
</div>
<div class="alt2" style="border: 1px inset; padding: 6px;">
<div class="spoiler" style="display: none;"><ul><li><b>df_cvars</b> - Reloads all cvars from file.</li>
<li><b>df_botlogic</b> - Enables rudimentary bot logic, for both puppet and standard bots.</li>
<li><b>df_addpoints</b> (partialName) (points) - Adds (or subtracts) queue points from a user. Negative points will prevent a player from participating, which can be used as an admin punishment.</li>
<li><b>df_forcehero</b> (partialClientName) (partialHeroName) - Forces a player to be a specific hero. Also provides temporarily override for permissions. Note that it does not force them to be a hero next round, nor does it change their hero/boss/never preference.</li>
<li><b>df_forceboss</b> (partialClientName) (partialBossName) - Forces a player to be a specific boss. Also provides temporarily override for permissions. Note that it does not force them to be a boss next round, nor does it change their hero/boss/never preference.</li>
<li><b>df_amianadmin</b> - Not meant to be invoked. It's used in a workaround since a couple expected methods for detecting if someone is admin failed. Will be removed once someone sets me straight. :p This is used in connection with having characters that only admins can access. (&quot;debugboss&quot; is one of these characters)</li>
</ul></div>
</div>
</div><br /><br /><font size="3"><b>Debug Commands</b></font><br /><div style="margin: 5px;">
<div class="smallfont" style="margin-bottom: 2px;">
<b>Spoiler</b> <input value="Show" style="margin: 0px; padding: 0px; width: 45px; font-size: 10px;" onclick="if(this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display != 'inline')
{ this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'inline'; this.innerText = ''; this.value = 'Hide'; }
else
{ this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'none'; this.innerText = ''; this.value='Show'; }" type="button">
</div>
<div class="alt2" style="border: 1px inset; padding: 6px;">
<div class="spoiler" style="display: none;"><br />These commands are compiled out of the plugin by default. You must set DEBUG_MODE_ENABLED to true for them to be usable. They can be disruptive to gameplay, and should not be used on a live server.<ul><li><b>df_forceenemyfire</b> - Forces the enemy to fire once. Best used for testing boss abilities with a puppet bot.</li>
<li><b>df_forceiterate</b> - Forces the enemy to iterate ahead one ability. Best used for testing boss abilities with a puppet bot.</li>
</ul></div>
</div>
</div><br /><br /><font size="4"><u>Cvars</u></font><br /><div style="margin: 5px;">
<div class="smallfont" style="margin-bottom: 2px;">
<b>Spoiler</b> <input value="Show" style="margin: 0px; padding: 0px; width: 45px; font-size: 10px;" onclick="if(this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display != 'inline')
{ this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'inline'; this.innerText = ''; this.value = 'Hide'; }
else
{ this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'none'; this.innerText = ''; this.value='Show'; }" type="button">
</div>
<div class="alt2" style="border: 1px inset; padding: 6px;">
<div class="spoiler" style="display: none;"><br />The public version cvar is: <b>danmaku_fortress_version</b><br /><br />All of the others are set to FCVAR_PLUGIN.<ul><li><b>df_tutorial_interval</b> (default 60.0) - Interval between tutorial messages.</li>
<li><b>df_start_delay</b> (default 10.0) - Delay before game actually begins, after two people are brought into said game.</li>
<li><b>df_new_life_invincibility_duration</b> (default 5.0) - Duration of invincibility when hero uses a life.</li>
<li><b>df_bomb_invincibility_duration</b> (default 3.0) - Duration of invincibility when bomb is used.</li>
<li><b>df_vertical_multiplier</b> (default 0.35) - Vertical speed multiplier. Vertical speed is recommended slower than horizontal speed, mainly for balance reasons.</li>
<li><b>df_postgame_delay</b> (default 10.0) - Delay before someone can enter one game after leaving another. Also the duration of win/lose sounds, before other sounds start playing.</li>
<li><b>df_use_particle</b> (default 0) - Particle effect at hero's damage point? [0/1] (deprecated)</li>
<li><b>df_max_games</b> (default 5) - Admin-set limit for number of max games. (5 is the hard maximum, but you can set it lower)</li>
<li><b>df_queue_point_grace_time</b> (default 25.0) - Grace period before queue points are lost if someone forfeits against you.</li>
<li><b>df_queue_points_wait</b> (default 10) - Queue points for people waiting in line.</li>
<li><b>df_queue_points_win</b> (default 9) - Queue points for winner of a match.</li>
<li><b>df_queue_points_lose</b> (default 8) - Queue points for loser of a match.</li>
<li><b>df_queue_points_stalemate</b> (default 300) - Queue points for a stalemate. Keep in mind that unless admins go around slaying everyone, this is an incredibly rare event. You'll probably never see one occur naturally.</li>
<li><b>df_queue_points_early_forfeit_mult</b> (default 0.0) - Early forfeit multiplier for the forfeitter. (intended as a penalty, the victim loses no points) [0.0 to 1.0]</li>
<li><b>df_queue_points_forfetted_against_mult</b> (default 0.5) - If someone is forfeitted against after the grace period, they lose this amount of their queue points instead of all of them. [0.0 to 1.0]</li>
<li><b>df_hero_normal_max_score</b> (default 25.0) - Max scoreboard points for the hero, if the hero is on normal difficulty.</li>
<li><b>df_hero_hard_max_score</b> (default 50.0) - Max scoreboard points for the hero, if the hero is on hard difficulty.</li>
<li><b>df_hero_lunatic_max_score</b> (default 100.0) - Max scoreboard points for the hero, if the hero is on lunatic difficulty.</li>
<li><b>df_boss_normal_max_score</b> (default 100.0) - Max scoreboard points for the boss, if the hero is on normal difficulty.</li>
<li><b>df_boss_hard_max_score</b> (default 50.0) - Max scoreboard points for the boss, if the hero is on hard difficulty.</li>
<li><b>df_boss_lunatic_max_score</b> (default 25.0) - Max scoreboard points for the boss, if the hero is on lunatic difficulty.</li>
<li><b>df_hero_ability_terminology</b> (default &quot;Desperation Ability&quot;) - Aesthetic name for hero bomb ability. You might change it to Spell Card if you're running a Touhou themed server.</li>
<li><b>df_boss_ability_terminology</b> - (default &quot;Boss Ability&quot;) - Aesthetic name for boss ability. You might change it to Spell Card if you're running a Touhou themed server.</li>
<li><b>df_hero_projectile_resize</b> - (default 0.7) - Projectile resize for hero. Hit area is unaffected, but making the projectiles smaller makes it easy for the hero to see.</li>
</ul></div>
</div>
</div><br /><br /><font size="4"><u>Q&amp;A</u></font><br />Q: <b>Is this plugin limited to Touhou?</b><br />A: Nope. Even though the first characters included are Touhou characters, I plan on including Epic Scout as a hero and SHADoW may include Blitzkrieg as a boss. Characters from any domain are welcome.<br /><br />Q: <b>Can I create my own characters?</b><br />A: Yep. There are 18 default abilities to work with and coders can make even more. There a bunch of pre-programmed behaviors for rockets and spawners, with more planned in the future, which makes it pretty easy to code a basic. You can also choose to manage the behavior of rockets and spawners, though this is more involved.<br /><br /><font size="4"><u>Credits</u></font><br /><font size="3"><b>Core Credits</b></font><ul><li>Code and concept by sarysa</li>
<li>Heavily influenced by SHADoW and his Blitzkrieg FF2 boss, plus I got the idea for this while we &quot;dueled&quot; flying around in noclip.</li>
<li>Also influenced to a small degree by Freak Fortress 2, most notably with the config file designs, Kv code, and some of my stocks.</li>
<li>Rocket spawning code derived from Asherkin's from his Dodgeball plugin, with contributions from voogru</li>
<li>Beam spawning code derived from JasonFrog's IonAttack for FF2. (at least I think it was JasonFrog's, specific parts of Phat Rages are unsigned)</li>
<li>Obviously also heavily influenced by Touhou Project by ZUN</li>
</ul><br /><font size="3"><b>Asset Credits</b></font><ul><li>Reimu model by Nya</li>
<li>Cirno model also by Nya</li>
<li>Flandre model by Ciel</li>
<li>All models so far were ported to GMod by 1337gamer15 (I grabbed them from Kenji-kun's collection)</li>
<li>sarysa made Reimu's crappy gohei which looks more like a staff with a pennant at the end.</li>
<li>sarysa also added basic animated poses to Cirno and Reimu, and fixed some of the seam and bad texture param issues. (those not directly caused by UV mapping)</li>
<li>Music by ZUN and various remixers of his work.</li>
</ul><br /><font size="3"><b>Special Thanks</b></font><ul><li>BBG Theory for allowing me use of his development server for playtesting.</li>
<li>BBG community members (and others) for testing. Those who I can remember include: SHADoW, Deathreus, GimpYTron, Cheese, and Cirno.</li>
</ul><br /><font size="4"><u>Known Issues</u></font><ul><li>People have reported frame drops with the beams. I don't get them, and it seems to be with people running highest or near highest settings. This one will definitely take community feedback to overcome.</li>
<li>The plugin is hardcoded in English. I get that this a problem. I went out of my way to make the interface as descriptive as possible, but it's also going to make adding localization support an utter nightmare. Plus this is the type of plugin where <b>minimum CPU usage</b> is the top priority, and until I better understand the impact grabbing strings from a localization file will have on load, this issue is going to be put off for a long time.</li>
<li>Players get stuck under the map during the pre-round. Due to maps needing to have a transparent &quot;yes projectiles no players&quot; boundary all around, it's unlikely this will ever be fully fixable. (Dart Mann tried, but that fix only works on the first player to show up)</li>
<li>People with a sharp eye might notice the hero's projectiles have a larger hitbox than they should. This is by design, to make it easier for the hero to see. It's managed with a cvar.</li>
<li>DO NOT ADD TF2 MUSIC to the music player unless you rip it and give it a new path. Some TF2 songs and sfx are hardcoded to automatically loop on their own, which will cause songs to quickly stack.</li>
<li>tf2items is a requirement because I get the error below if it's not included. I have no idea why I get this error. When it happens, the line number it fails on is wrong and the plugin completely ceases to function. (no more events received either) Removing this method entirely appears to fix the problem, but hitboxes aren't read in. If anyone knows what the hell this is and why having tf2items fixes the problem, please let me know:</li>
</ul><div style="margin: 5px;">
<div class="smallfont" style="margin-bottom: 2px;">
<b>Spoiler</b> <input value="Show" style="margin: 0px; padding: 0px; width: 45px; font-size: 10px;" onclick="if(this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display != 'inline')
{ this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'inline'; this.innerText = ''; this.value = 'Hide'; }
else
{ this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'none'; this.innerText = ''; this.value='Show'; }" type="button">
</div>
<div class="alt2" style="border: 1px inset; padding: 6px;">
<div class="spoiler" style="display: none;"><div style="margin:20px; margin-top:5px">
<div class="smallfont" style="margin-bottom:2px">Code:</div>
<hr /><code style="margin:0px" dir="ltr" style="text-align:left">L 07/07/2015 - 23:03:21: [SM] Plugin encountered error 16: Instruction contained invalid parameter<br />L 07/07/2015 - 23:03:21: [SM] Displaying call stack trace for plugin &quot;danmaku_fortress.smx&quot;:<br />L 07/07/2015 - 23:03:21: [SM]&nbsp; [0]&nbsp; Line 6222, danmaku_fortress.sp::ParseHull()<br />L 07/07/2015 - 23:03:21: [SM]&nbsp; [1]&nbsp; Line 5987, danmaku_fortress.sp::KV_ReadRectangle()<br />L 07/07/2015 - 23:03:21: [SM]&nbsp; [2]&nbsp; Line 3547, danmaku_fortress.sp::DG_TryStartGame()<br />L 07/07/2015 - 23:03:21: [SM]&nbsp; [3]&nbsp; Line 4120, danmaku_fortress.sp::DG_Tick()<br />L 07/07/2015 - 23:03:21: [SM]&nbsp; [4]&nbsp; Line 6175, danmaku_fortress.sp::OnGameFrame()</code><hr />
</div></div>
</div>
</div><br /><br />The following two replies will contain hero/boss descriptions and instructions for subplugin coding, creating heroes/bosses, etc.</div>