diff --git a/BloonsTD6 Mod Helper/Api/Helpers/AttackHelper.cs b/BloonsTD6 Mod Helper/Api/Helpers/AttackHelper.cs
index 895d7449d..bf848f6ac 100644
--- a/BloonsTD6 Mod Helper/Api/Helpers/AttackHelper.cs
+++ b/BloonsTD6 Mod Helper/Api/Helpers/AttackHelper.cs
@@ -7,10 +7,17 @@
using Il2CppAssets.Scripts.Simulation.SMath;
namespace BTD_Mod_Helper.Api.Helpers;
+///
+/// A wrapper around AttackModels for making them easier to create
+///
public class AttackHelper : ModelHelper
{
- private AttackFilterModel Filter => Model.GetBehavior();
+ ///
+ /// This AttackModel's AttackFilterModel
+ ///
+ public AttackFilterModel Filter => Model.GetBehavior();
+ ///
public WeaponModel Weapon
{
get => Model.GetChild();
@@ -22,6 +29,7 @@ public WeaponModel Weapon
}
}
+ ///
public WeaponModel[] Weapons
{
get => Model.weapons;
@@ -33,12 +41,14 @@ public WeaponModel[] Weapons
}
}
+ ///
public float Range
{
get => Model.range;
set => Model.range = value;
}
+ ///
public Model[] Behaviors
{
get => Model.behaviors;
@@ -50,6 +60,8 @@ public Model[] Behaviors
}
}
+
+ ///
public FilterModel[] Filters
{
get => Filter.filters;
@@ -63,6 +75,7 @@ public FilterModel[] Filters
}
}
+ ///
public TargetSupplierModel TargetProvider
{
get => Model.targetProvider;
@@ -78,6 +91,9 @@ public TargetSupplierModel TargetProvider
}
}
+ ///
+ ///
+ ///
public Vector3 Offset
{
get => new(Model.offsetX, Model.offsetY, Model.offsetZ);
@@ -89,12 +105,14 @@ public Vector3 Offset
}
}
+ ///
public bool AttackThroughWalls
{
get => Model.attackThroughWalls;
set => Model.attackThroughWalls = value;
}
+ ///
public bool FireWithoutTarget
{
get => Model.fireWithoutTarget;
@@ -102,34 +120,42 @@ public bool FireWithoutTarget
}
+ ///
public int FramesBeforeRetarget
{
get => Model.framesBeforeRetarget;
set => Model.framesBeforeRetarget = value;
}
+ ///
public bool AddToSharedGrid
{
get => Model.addsToSharedGrid;
set => Model.addsToSharedGrid = value;
}
+ ///
public float SharedGridRange
{
get => Model.sharedGridRange;
set => Model.sharedGridRange = value;
}
+ ///
public bool CanSeeCamo
{
get => !Filter.GetChild().isActive;
set => Filter.GetChild().isActive = !value;
}
-
+
private AttackHelper(AttackModel attack) : base(attack)
{
}
+ ///
+ /// Begins construction of a new AttackModel with sensible default values
+ ///
+ /// The model name (don't need the AttackModel_ part)
public AttackHelper(string name = "") : this(new AttackModel(name,
new Il2CppReferenceArray(0), 0, new[]
{
@@ -141,8 +167,14 @@ public AttackHelper(string name = "") : this(new AttackModel(name,
{
}
+ ///
+ /// Unwraps the model
+ ///
public static implicit operator AttackModel(AttackHelper helper) => helper.Model;
-
+
+ ///
+ /// Wraps a model
+ ///
public static implicit operator AttackHelper(AttackModel model) => new(model);
}
\ No newline at end of file
diff --git a/BloonsTD6 Mod Helper/Api/Helpers/ModelHelper.cs b/BloonsTD6 Mod Helper/Api/Helpers/ModelHelper.cs
index a38cf65a4..1a5e04bce 100644
--- a/BloonsTD6 Mod Helper/Api/Helpers/ModelHelper.cs
+++ b/BloonsTD6 Mod Helper/Api/Helpers/ModelHelper.cs
@@ -1,15 +1,26 @@
using Il2CppAssets.Scripts.Models;
namespace BTD_Mod_Helper.Api.Helpers;
+///
+/// A wrapper class around a Model
+///
public abstract class ModelHelper
{
+ ///
+ /// The internal model
+ ///
public abstract Model Model { get; }
}
+///
public abstract class ModelHelper : ModelHelper where T : Model
{
+ ///
public override T Model { get; }
+ ///
+ /// Creates a wrapper around an existing model
+ ///
protected ModelHelper(T model)
{
Model = model;
diff --git a/BloonsTD6 Mod Helper/Api/Helpers/ProcessHelper.cs b/BloonsTD6 Mod Helper/Api/Helpers/ProcessHelper.cs
index df3269005..ddb9c33b3 100644
--- a/BloonsTD6 Mod Helper/Api/Helpers/ProcessHelper.cs
+++ b/BloonsTD6 Mod Helper/Api/Helpers/ProcessHelper.cs
@@ -1,5 +1,6 @@
using System;
using System.Diagnostics;
+using BTD_Mod_Helper.UI.BTD6;
using Il2CppAssets.Scripts.Unity.Menu;
using MelonLoader.Utils;
namespace BTD_Mod_Helper.Api.Helpers;
diff --git a/BloonsTD6 Mod Helper/Api/Helpers/ProjectileHelper.cs b/BloonsTD6 Mod Helper/Api/Helpers/ProjectileHelper.cs
index 14c611b9f..f91b12a25 100644
--- a/BloonsTD6 Mod Helper/Api/Helpers/ProjectileHelper.cs
+++ b/BloonsTD6 Mod Helper/Api/Helpers/ProjectileHelper.cs
@@ -8,47 +8,64 @@
using Il2CppAssets.Scripts.Utils;
namespace BTD_Mod_Helper.Api.Helpers;
+///
+/// A wrapper around ProjectileModels for making them easier to create
+///
public class ProjectileHelper : ModelHelper
{
- private ProjectileFilterModel Filter => Model.GetBehavior();
- private DisplayModel DisplayModel => Model.GetBehavior();
-
+ ///
+ /// This ProjectileModel's ProjectileFilterModel
+ ///
+ public ProjectileFilterModel Filter => Model.GetBehavior();
+
+ ///
+ /// This ProjectileModel's DisplayModel
+ ///
+ public DisplayModel DisplayModel => Model.GetBehavior();
+
+ ///
public string Display
{
get => Model.display.guidRef;
set => Model.display.guidRef = Model.GetBehavior().display.guidRef = value;
}
+ ///
public PrefabReference DisplayReference
{
get => Model.display;
set => Model.display = Model.GetBehavior().display = value;
}
+ ///
public float Radius
{
get => Model.radius;
set => Model.radius = value;
}
+ ///
public float VsBlockerRadius
{
get => Model.vsBlockerRadius;
set => Model.vsBlockerRadius = value;
}
+ ///
public float Pierce
{
get => Model.pierce;
set => Model.pierce = value;
}
+ ///
public float MaxPierce
{
get => Model.maxPierce;
set => Model.maxPierce = value;
}
+ ///
public Model[] Behaviors
{
get => Model.behaviors ?? new Il2CppReferenceArray(0);
@@ -64,6 +81,7 @@ public Model[] Behaviors
}
}
+ ///
public FilterModel[] Filters
{
get => Filter.filters;
@@ -78,62 +96,78 @@ public FilterModel[] Filters
}
}
+ ///
public bool IgnoreBlockers
{
get => Model.ignoreBlockers;
set => Model.ignoreBlockers = value;
}
+ ///
public bool UsePointCollisionWithBloons
{
get => Model.usePointCollisionWithBloons;
set => Model.usePointCollisionWithBloons = value;
}
+ ///
public bool CanCollisionBeBlockedByMapLos
{
get => Model.canCollisionBeBlockedByMapLos;
set => Model.canCollisionBeBlockedByMapLos = value;
}
+ ///
public float Scale
{
get => Model.scale;
set => Model.scale = value;
}
- public int[] CollissionPasses => CollissionPasses;
+ ///
+ public int[] CollissionPasses
+ {
+ get => Model.collisionPasses;
+ set => Model.collisionPasses = value;
+ }
+
+ ///
public bool DontUseCollisionChecker
{
get => Model.dontUseCollisionChecker;
set => Model.dontUseCollisionChecker = value;
}
+ ///
public int CheckCollisionFrames
{
get => Model.checkCollisionFrames;
set => Model.checkCollisionFrames = value;
}
+ ///
public bool IgnoreNonTargetable
{
get => Model.ignoreNonTargetable;
set => Model.ignoreNonTargetable = value;
}
+ ///
public bool IgnorePierceExhaustion
{
get => Model.ignorePierceExhaustion;
set => Model.ignorePierceExhaustion = value;
}
+ ///
public string SaveId
{
get => Model.saveId;
set => Model.saveId = value;
}
+ ///
public bool CanHitCamo
{
get => !Filter.GetChild().isActive;
@@ -148,6 +182,10 @@ private ProjectileHelper(ProjectileModel Projectile) : base(Projectile)
{
}
+ ///
+ /// Begins construction of a new ProjectileModel with sensible default values
+ ///
+ /// The model name (don't need the ProjectileModel_ part)
public ProjectileHelper(string name = "") : this(new ProjectileModel(
new PrefabReference {guidRef = ""}, name, behaviors: new Model[]
{
@@ -163,12 +201,18 @@ public ProjectileHelper(string name = "") : this(new ProjectileModel(
{
}
+ ///
+ /// Unwraps the model (and updates collission passes)
+ ///
public static implicit operator ProjectileModel(ProjectileHelper helper)
{
helper.Model.UpdateCollisionPassList();
return helper.Model;
}
+ ///
+ /// Wraps a model
+ ///
public static implicit operator ProjectileHelper(ProjectileModel model) => new(model);
}
\ No newline at end of file
diff --git a/BloonsTD6 Mod Helper/Api/Helpers/WeaponHelper.cs b/BloonsTD6 Mod Helper/Api/Helpers/WeaponHelper.cs
index 96fd5e571..f95b82afc 100644
--- a/BloonsTD6 Mod Helper/Api/Helpers/WeaponHelper.cs
+++ b/BloonsTD6 Mod Helper/Api/Helpers/WeaponHelper.cs
@@ -4,32 +4,42 @@
using Il2CppAssets.Scripts.Simulation.SMath;
namespace BTD_Mod_Helper.Api.Helpers;
+///
+/// A wrapper around WeaponModels for making them easier to create
+///
public class WeaponHelper : ModelHelper
{
+ ///
public int Animation
{
get => Model.animation;
set => Model.animation = value;
}
+ ///
public float Rate
{
get => Model.Rate;
set => Model.Rate = value;
}
+ ///
public ProjectileModel Projectile
{
get => Model.projectile;
set => Model.SetProjectile(value);
}
+ ///
+ ///
+ ///
public Vector3 Eject
{
get => Model.GetEject();
set => Model.SetEject(value);
}
+ ///
public float AnimationOffset
{
get => Model.animationOffset;
@@ -40,24 +50,28 @@ public float AnimationOffset
}
}
+ ///
public bool FireWithoutTarget
{
get => Model.fireWithoutTarget;
set => Model.fireWithoutTarget = value;
}
+ ///
public bool FireBetweenRounds
{
get => Model.fireBetweenRounds;
set => Model.fireBetweenRounds = value;
}
+ ///
public EmissionModel Emission
{
get => Model.emission;
set => Model.SetEmission(value);
}
+ ///
public WeaponBehaviorModel[] Behaviors
{
get => Model.behaviors ?? new Il2CppReferenceArray(0);
@@ -69,24 +83,32 @@ public WeaponBehaviorModel[] Behaviors
}
}
+ ///
public bool UseAttackPosition
{
get => Model.useAttackPosition;
set => Model.useAttackPosition = value;
}
+ ///
public bool StartInCooldown
{
get => Model.startInCooldown;
set => Model.startInCooldown = value;
}
+ ///
public float CustomStartCooldown
{
get => Model.customStartCooldown;
- set => Model.customStartCooldown = value;
+ set
+ {
+ Model.customStartCooldownFrames = (int) (value * 60);
+ Model.customStartCooldown = value;
+ }
}
+ ///
public bool AnimateOnMainAttack
{
get => Model.animateOnMainAttack;
@@ -97,12 +119,22 @@ private WeaponHelper(WeaponModel weapon) : base(weapon)
{
}
+ ///
+ /// Begins construction of a new WeaponModel with sensible default values
+ ///
+ /// The model name (don't need the WeaponModel_ part)
public WeaponHelper(string name = "") : this(new WeaponModel(name, emission: new SingleEmissionModel("", null)))
{
}
-
+
+ ///
+ /// Unwraps the model
+ ///
public static implicit operator WeaponModel(WeaponHelper helper) => helper.Model;
-
+
+ ///
+ /// Wraps a model
+ ///
public static implicit operator WeaponHelper(WeaponModel model) => new(model);
}
\ No newline at end of file
diff --git a/BloonsTD6 Mod Helper/Extensions/BehaviorExtensions/TowerModelBehaviorExt.cs b/BloonsTD6 Mod Helper/Extensions/BehaviorExtensions/TowerModelBehaviorExt.cs
index f1f865b79..40d9a8a3c 100644
--- a/BloonsTD6 Mod Helper/Extensions/BehaviorExtensions/TowerModelBehaviorExt.cs
+++ b/BloonsTD6 Mod Helper/Extensions/BehaviorExtensions/TowerModelBehaviorExt.cs
@@ -87,9 +87,11 @@ public static void RemoveBehaviors(this TowerModel model) where T : Model
ModelBehaviorExt.RemoveBehaviors(model);
}
+ ///
+ /// Adds a wrapped behavior from a ModelHelper to this tower
+ ///
public static void AddBehavior(this TowerModel model, ModelHelper behavior)
{
ModelBehaviorExt.AddBehavior(model, behavior.Model);
}
-
}
\ No newline at end of file
diff --git a/BloonsTD6 Mod Helper/LATEST.md b/BloonsTD6 Mod Helper/LATEST.md
index 43e9efe44..cc5e85f9c 100644
--- a/BloonsTD6 Mod Helper/LATEST.md
+++ b/BloonsTD6 Mod Helper/LATEST.md
@@ -1 +1,41 @@
-- Fixes for BTD6 v38
\ No newline at end of file
+- Fixed a crash that could happen on Linux (thanks @GrahamKracker)
+-
+- Fixed SteamWebView usage on the Epic Games version
+ - Reminder: You still need https://github.com/GrahamKracker/BTD6EpicGamesModCompat for Epic Games
+- Added new `AttackHelper`, `WeaponHelper` and `ProjectileHelper` that can be used to more easily create those models
+ from scratch
+ - The classes will implicitly convert themselves to their respective models
+ - Make easy use of the object initialization syntax
+ ```csharp
+ var effect = ability.GetBehavior().effectModel;
+ var buff = ability.GetBehavior();
+ model.AddBehavior(new AttackHelper("WeakeningRoar")
+ {
+ Range = buff.range,
+ AttackThroughWalls = true,
+ CanSeeCamo = true,
+ Weapon = new WeaponHelper("WeakeningRoar")
+ {
+ Animation = 3,
+ Rate = ability.Cooldown / Factor,
+ Behaviors = new WeaponBehaviorModel[]
+ {
+ new EjectEffectModel("", effect.assetId, effect, effect.lifespan, effect.fullscreen, false, false,
+ false, false)
+ },
+ Projectile = new ProjectileHelper("WeakeningRoar")
+ {
+ Radius = buff.range,
+ Pierce = 1000,
+ CanHitCamo = true,
+ Behaviors = new Model[]
+ {
+ new AgeModel("", .05f, 0, false, null),
+ new AddBonusDamagePerHitToBloonModel("", "WeakeningRoar", buff.lifespan / Factor,
+ buff.damageIncrease, 99999, true, false, false)
+ }
+ }
+ }
+ });
+ ```
+ - Don't need to specific a bunch of extra fields, will use sensible defaults
\ No newline at end of file
diff --git a/BloonsTD6 Mod Helper/MelonMain.cs b/BloonsTD6 Mod Helper/MelonMain.cs
index 4325dec17..1a20d71da 100644
--- a/BloonsTD6 Mod Helper/MelonMain.cs
+++ b/BloonsTD6 Mod Helper/MelonMain.cs
@@ -6,6 +6,7 @@
using BTD_Mod_Helper.Api.Internal;
using BTD_Mod_Helper.Api.ModMenu;
using BTD_Mod_Helper.Api.ModOptions;
+using BTD_Mod_Helper.UI.BTD6;
using BTD_Mod_Helper.UI.Modded;
using Il2CppAssets.Scripts.Data;
using Il2CppAssets.Scripts.Unity;
@@ -67,6 +68,11 @@ public override void OnInitialize()
"If you have no intention of making mods, you can ignore this.");
ModHelper.Warning(e);
}
+
+ if (!ModHelper.IsEpic)
+ {
+ HarmonyInstance.CreateClassProcessor(typeof(EmbeddedBrowser.SteamWebView_OnGUI), true).Patch();
+ }
}
public override void OnUpdate()
diff --git a/BloonsTD6 Mod Helper/ModHelper.cs b/BloonsTD6 Mod Helper/ModHelper.cs
index 08baa3396..e44d4c8b7 100644
--- a/BloonsTD6 Mod Helper/ModHelper.cs
+++ b/BloonsTD6 Mod Helper/ModHelper.cs
@@ -5,7 +5,9 @@
using System.Reflection;
using BTD_Mod_Helper.Api;
using BTD_Mod_Helper.Api.Data;
+using BTD_Mod_Helper.Api.Helpers;
using BTD_Mod_Helper.Api.Internal;
+using BTD_Mod_Helper.UI.BTD6;
using MelonLoader.Utils;
namespace BTD_Mod_Helper;
@@ -56,6 +58,14 @@ public static class ModHelper
///
public static bool IsNet6 => Environment.Version.Major >= 6;
+ ///
+ /// Gets whether the game is running as the Epic Store version
+ ///
+ /// This checks that the has been properly changed by
+ /// BTD6EpicGamesModCompat
+ ///
+ public static bool IsEpic => Main.Games.Any(attribute => attribute.Name == "BloonsTD6-Epic");
+
internal static bool FallbackToOldLoading
{
set => fallBackToOldLoading = value;
diff --git a/BloonsTD6 Mod Helper/UI/BTD6/EmbeddedBrowser.cs b/BloonsTD6 Mod Helper/UI/BTD6/EmbeddedBrowser.cs
index 627eef72c..de83ec088 100644
--- a/BloonsTD6 Mod Helper/UI/BTD6/EmbeddedBrowser.cs
+++ b/BloonsTD6 Mod Helper/UI/BTD6/EmbeddedBrowser.cs
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Net.Http;
+using System.Reflection;
using BTD_Mod_Helper.Api.Components;
using BTD_Mod_Helper.Api.Enums;
using BTD_Mod_Helper.Api.Helpers;
@@ -176,7 +177,6 @@ private static bool Prefix(HtmlSurface __instance, HTML_FileOpenDialog_t callbac
}
#endregion*/
- #region Nested type: HtmlSurface_OnJSAlertAPI
///
/// Implement JS alerts using Ok popups
@@ -195,9 +195,6 @@ private static bool Prefix(HtmlSurface __instance, HTML_JSAlert_t callbackdata)
}
}
- #endregion
- #region Nested type: HtmlSurface_OnJSConfirmAPI
-
///
/// Implement JS confirms using Ok/Cancel popups
///
@@ -218,9 +215,6 @@ private static bool Prefix(HtmlSurface __instance, HTML_JSConfirm_t callbackdata
}
}
- #endregion
- #region Nested type: HtmlSurface_OnStartRequestAPI
-
///
/// Allow mod files to be downloaded through the browser
///
@@ -245,15 +239,16 @@ private static void Postfix(HtmlSurface __instance, HTML_StartRequest_t callback
}
}
- #endregion
- #region Nested type: SteamWebView_OnGUI
-
///
/// Use a RawImage to render if available so that objects can be displayed on top of it
///
- [HarmonyPatch(typeof(SteamWebView), nameof(SteamWebView.OnGUI))]
internal static class SteamWebView_OnGUI
{
+ private static System.Collections.Generic.IEnumerable TargetMethods()
+ {
+ yield return AccessTools.Method(typeof(SteamWebView), nameof(SteamWebView.OnGUI));
+ }
+
public static bool UsingRawImage { get; private set; }
[HarmonyPrefix]
@@ -273,6 +268,4 @@ private static void PostFix()
UsingRawImage = false;
}
}
-
- #endregion
}
\ No newline at end of file
diff --git a/BloonsTD6 Mod Helper/UI/Menus/ModBrowserMenuMod.cs b/BloonsTD6 Mod Helper/UI/Menus/ModBrowserMenuMod.cs
index 1e3e226ff..2de994d11 100644
--- a/BloonsTD6 Mod Helper/UI/Menus/ModBrowserMenuMod.cs
+++ b/BloonsTD6 Mod Helper/UI/Menus/ModBrowserMenuMod.cs
@@ -181,7 +181,17 @@ internal static class ModBrowserMenuModExt
public static void SetMod(this ModBrowserMenuMod mod, Api.Data.ModHelperData modHelperData)
{
mod.modName = modHelperData.Name;
- mod.Homepage.Button.SetOnClick(() => EmbeddedBrowser.OpenURL(modHelperData.ReadmeUrl!));
+ mod.Homepage.Button.SetOnClick(() =>
+ {
+ if (ModHelper.IsEpic)
+ {
+ ProcessHelper.OpenURL(modHelperData.ReadmeUrl!);
+ }
+ else
+ {
+ EmbeddedBrowser.OpenURL(modHelperData.ReadmeUrl!);
+ }
+ });
mod.Description.Text.SetText(modHelperData.DisplayDescription);
mod.InfoButton.Button.SetOnClick(() =>
{
diff --git a/BloonsTD6 Mod Helper/UI/Menus/ModsMenu.cs b/BloonsTD6 Mod Helper/UI/Menus/ModsMenu.cs
index 5963f255d..680c78292 100644
--- a/BloonsTD6 Mod Helper/UI/Menus/ModsMenu.cs
+++ b/BloonsTD6 Mod Helper/UI/Menus/ModsMenu.cs
@@ -218,10 +218,19 @@ private static void CreateExtraButtons(ExtraSettingsScreen gameMenu)
var march32 = bottomButtonGroup.AddButton(new Info("March32ndButton")
{
Width = 1000, Height = 250, Y = Padding, Anchor = new Vector2(0.5f, 0), Pivot = new Vector2(0.5f, 0)
- }, VanillaSprites.GreenBtnLong, new Action(() => EmbeddedBrowser.OpenURL(
- "https://www.youtube.com/watch?v=dQw4w9WgXcQ?autoplay=1",
- view => view.Surface.KeyDown(0x0D /* VK_RETURN */, HTMLKeyModifiers.None))
- ));
+ }, VanillaSprites.GreenBtnLong, new Action(() =>
+ {
+ if (ModHelper.IsEpic)
+ {
+ ProcessHelper.OpenURL("https://www.youtube.com/watch?v=dQw4w9WgXcQ?autoplay=1");
+ }
+ else
+ {
+ EmbeddedBrowser.OpenURL(
+ "https://www.youtube.com/watch?v=dQw4w9WgXcQ?autoplay=1",
+ view => view.Surface.KeyDown(0x0D /* VK_RETURN */, HTMLKeyModifiers.None));
+ }
+ }));
march32.AddText(new Info("Text", InfoPreset.FillParent), "Get 100 Trophies", 80f);
march32.AddImage(new Info("TrophyL", -475, 0, 300), VanillaSprites.TrophyIcon);
march32.AddImage(new Info("TrophyR", 475, 0, 300), VanillaSprites.TrophyIcon);
@@ -247,7 +256,7 @@ public override void OnMenuUpdate()
{
position = Input.mousePosition
}, raycastResults);
-
+
foreach (var result in raycastResults)
{
var parent = result.gameObject.transform.parent;
@@ -500,7 +509,17 @@ private static void CreateRightMenu(ModHelperPanel modsMenu)
selectedModHomeButton = firstRow.AddButton(new Info("HomePage")
{
Size = ModNameHeight
- }, VanillaSprites.HomeBtn, new Action(() => EmbeddedBrowser.OpenURL(selectedMod.ReadmeUrl!)));
+ }, VanillaSprites.HomeBtn, new Action(() =>
+ {
+ if (ModHelper.IsEpic)
+ {
+ ProcessHelper.OpenURL(selectedMod.ReadmeUrl!);
+ }
+ else
+ {
+ EmbeddedBrowser.OpenURL(selectedMod.ReadmeUrl!);
+ }
+ }));
// ReSharper disable once AsyncVoidLambda
selectedModUpdateButton = firstRow.AddButton(
diff --git a/Documentation/BTD_Mod_Helper.Api.Helpers.AttackHelper.md b/Documentation/BTD_Mod_Helper.Api.Helpers.AttackHelper.md
new file mode 100644
index 000000000..382084456
--- /dev/null
+++ b/Documentation/BTD_Mod_Helper.Api.Helpers.AttackHelper.md
@@ -0,0 +1,265 @@
+#### [BloonsTD6 Mod Helper](README.md 'README')
+### [BTD_Mod_Helper.Api.Helpers](README.md#BTD_Mod_Helper.Api.Helpers 'BTD_Mod_Helper.Api.Helpers')
+
+## AttackHelper Class
+
+A wrapper around AttackModels for making them easier to create
+
+```csharp
+public class AttackHelper : BTD_Mod_Helper.Api.Helpers.ModelHelper
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 [ModelHelper](BTD_Mod_Helper.Api.Helpers.ModelHelper.md 'BTD_Mod_Helper.Api.Helpers.ModelHelper') 🡒 [BTD_Mod_Helper.Api.Helpers.ModelHelper<](BTD_Mod_Helper.Api.Helpers.ModelHelper_T_.md 'BTD_Mod_Helper.Api.Helpers.ModelHelper')[Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel 'Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel')[>](BTD_Mod_Helper.Api.Helpers.ModelHelper_T_.md 'BTD_Mod_Helper.Api.Helpers.ModelHelper') 🡒 AttackHelper
+### Constructors
+
+
+
+## AttackHelper(string) Constructor
+
+Begins construction of a new AttackModel with sensible default values
+
+```csharp
+public AttackHelper(string name="");
+```
+#### Parameters
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+The model name (don't need the AttackModel_ part)
+### Properties
+
+
+
+## AttackHelper.AddToSharedGrid Property
+
+```csharp
+public bool AddToSharedGrid { get; set; }
+```
+
+#### Property Value
+[System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.addsToSharedGrid](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.addsToSharedGrid 'Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.addsToSharedGrid')
+
+
+
+## AttackHelper.AttackThroughWalls Property
+
+```csharp
+public bool AttackThroughWalls { get; set; }
+```
+
+#### Property Value
+[System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.attackThroughWalls](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.attackThroughWalls 'Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.attackThroughWalls')
+
+
+
+## AttackHelper.Behaviors Property
+
+```csharp
+public Model[] Behaviors { get; set; }
+```
+
+#### Property Value
+[Il2CppAssets.Scripts.Models.Model](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Model 'Il2CppAssets.Scripts.Models.Model')[[]](https://docs.microsoft.com/en-us/dotnet/api/System.Array 'System.Array')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.behaviors](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.behaviors 'Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.behaviors')
+
+
+
+## AttackHelper.CanSeeCamo Property
+
+```csharp
+public bool CanSeeCamo { get; set; }
+```
+
+#### Property Value
+[System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Filters.FilterInvisibleModel.isActive](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Filters.FilterInvisibleModel.isActive 'Il2CppAssets.Scripts.Models.Towers.Filters.FilterInvisibleModel.isActive')
+
+
+
+## AttackHelper.Filter Property
+
+This AttackModel's AttackFilterModel
+
+```csharp
+public AttackFilterModel Filter { get; }
+```
+
+#### Property Value
+[Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.Behaviors.AttackFilterModel](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.Behaviors.AttackFilterModel 'Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.Behaviors.AttackFilterModel')
+
+
+
+## AttackHelper.Filters Property
+
+```csharp
+public FilterModel[] Filters { get; set; }
+```
+
+#### Property Value
+[Il2CppAssets.Scripts.Models.Towers.Filters.FilterModel](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Filters.FilterModel 'Il2CppAssets.Scripts.Models.Towers.Filters.FilterModel')[[]](https://docs.microsoft.com/en-us/dotnet/api/System.Array 'System.Array')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.Behaviors.AttackFilterModel.filters](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.Behaviors.AttackFilterModel.filters 'Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.Behaviors.AttackFilterModel.filters')
+
+
+
+## AttackHelper.FireWithoutTarget Property
+
+```csharp
+public bool FireWithoutTarget { get; set; }
+```
+
+#### Property Value
+[System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.fireWithoutTarget](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.fireWithoutTarget 'Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.fireWithoutTarget')
+
+
+
+## AttackHelper.FramesBeforeRetarget Property
+
+```csharp
+public int FramesBeforeRetarget { get; set; }
+```
+
+#### Property Value
+[System.Int32](https://docs.microsoft.com/en-us/dotnet/api/System.Int32 'System.Int32')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.framesBeforeRetarget](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.framesBeforeRetarget 'Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.framesBeforeRetarget')
+
+
+
+## AttackHelper.Offset Property
+
+```csharp
+public Vector3 Offset { get; set; }
+```
+
+#### Property Value
+[Il2CppAssets.Scripts.Simulation.SMath.Vector3](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Simulation.SMath.Vector3 'Il2CppAssets.Scripts.Simulation.SMath.Vector3')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.offsetX](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.offsetX 'Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.offsetX')
+- [Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.offsetY](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.offsetY 'Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.offsetY')
+- [Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.offsetZ](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.offsetZ 'Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.offsetZ')
+
+
+
+## AttackHelper.Range Property
+
+```csharp
+public float Range { get; set; }
+```
+
+#### Property Value
+[System.Single](https://docs.microsoft.com/en-us/dotnet/api/System.Single 'System.Single')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.range](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.range 'Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.range')
+
+
+
+## AttackHelper.SharedGridRange Property
+
+```csharp
+public float SharedGridRange { get; set; }
+```
+
+#### Property Value
+[System.Single](https://docs.microsoft.com/en-us/dotnet/api/System.Single 'System.Single')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.sharedGridRange](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.sharedGridRange 'Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.sharedGridRange')
+
+
+
+## AttackHelper.TargetProvider Property
+
+```csharp
+public TargetSupplierModel TargetProvider { get; set; }
+```
+
+#### Property Value
+[Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.Behaviors.TargetSupplierModel](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.Behaviors.TargetSupplierModel 'Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.Behaviors.TargetSupplierModel')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.targetProvider](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.targetProvider 'Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.targetProvider')
+
+
+
+## AttackHelper.Weapon Property
+
+```csharp
+public WeaponModel Weapon { get; set; }
+```
+
+#### Property Value
+[Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel 'Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.weapons](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.weapons 'Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.weapons')
+
+
+
+## AttackHelper.Weapons Property
+
+```csharp
+public WeaponModel[] Weapons { get; set; }
+```
+
+#### Property Value
+[Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel 'Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel')[[]](https://docs.microsoft.com/en-us/dotnet/api/System.Array 'System.Array')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.weapons](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.weapons 'Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel.weapons')
+### Operators
+
+
+
+## AttackHelper.implicit operator AttackModel(AttackHelper) Operator
+
+Unwraps the model
+
+```csharp
+public static AttackModel implicit operator AttackModel(BTD_Mod_Helper.Api.Helpers.AttackHelper helper);
+```
+#### Parameters
+
+
+
+`helper` [AttackHelper](BTD_Mod_Helper.Api.Helpers.AttackHelper.md 'BTD_Mod_Helper.Api.Helpers.AttackHelper')
+
+#### Returns
+[Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel 'Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel')
+
+
+
+## AttackHelper.implicit operator AttackHelper(AttackModel) Operator
+
+Wraps a model
+
+```csharp
+public static BTD_Mod_Helper.Api.Helpers.AttackHelper implicit operator AttackHelper(AttackModel model);
+```
+#### Parameters
+
+
+
+`model` [Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel 'Il2CppAssets.Scripts.Models.Towers.Behaviors.Attack.AttackModel')
+
+#### Returns
+[AttackHelper](BTD_Mod_Helper.Api.Helpers.AttackHelper.md 'BTD_Mod_Helper.Api.Helpers.AttackHelper')
\ No newline at end of file
diff --git a/Documentation/BTD_Mod_Helper.Api.Helpers.ModelHelper.md b/Documentation/BTD_Mod_Helper.Api.Helpers.ModelHelper.md
new file mode 100644
index 000000000..19d14c3c9
--- /dev/null
+++ b/Documentation/BTD_Mod_Helper.Api.Helpers.ModelHelper.md
@@ -0,0 +1,29 @@
+#### [BloonsTD6 Mod Helper](README.md 'README')
+### [BTD_Mod_Helper.Api.Helpers](README.md#BTD_Mod_Helper.Api.Helpers 'BTD_Mod_Helper.Api.Helpers')
+
+## ModelHelper Class
+
+A wrapper class around a Model
+
+```csharp
+public abstract class ModelHelper
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 ModelHelper
+
+Derived
+↳ [ModelHelper<T>](BTD_Mod_Helper.Api.Helpers.ModelHelper_T_.md 'BTD_Mod_Helper.Api.Helpers.ModelHelper')
+### Properties
+
+
+
+## ModelHelper.Model Property
+
+The internal model
+
+```csharp
+public abstract Model Model { get; }
+```
+
+#### Property Value
+[Il2CppAssets.Scripts.Models.Model](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Model 'Il2CppAssets.Scripts.Models.Model')
\ No newline at end of file
diff --git a/Documentation/BTD_Mod_Helper.Api.Helpers.ModelHelper_T_.md b/Documentation/BTD_Mod_Helper.Api.Helpers.ModelHelper_T_.md
new file mode 100644
index 000000000..9603d6f95
--- /dev/null
+++ b/Documentation/BTD_Mod_Helper.Api.Helpers.ModelHelper_T_.md
@@ -0,0 +1,53 @@
+#### [BloonsTD6 Mod Helper](README.md 'README')
+### [BTD_Mod_Helper.Api.Helpers](README.md#BTD_Mod_Helper.Api.Helpers 'BTD_Mod_Helper.Api.Helpers')
+
+## ModelHelper Class
+
+A wrapper class around a Model
+
+```csharp
+public abstract class ModelHelper : BTD_Mod_Helper.Api.Helpers.ModelHelper
+ where T : Model
+```
+#### Type parameters
+
+
+
+`T`
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 [ModelHelper](BTD_Mod_Helper.Api.Helpers.ModelHelper.md 'BTD_Mod_Helper.Api.Helpers.ModelHelper') 🡒 ModelHelper
+
+Derived
+↳ [AttackHelper](BTD_Mod_Helper.Api.Helpers.AttackHelper.md 'BTD_Mod_Helper.Api.Helpers.AttackHelper')
+↳ [ProjectileHelper](BTD_Mod_Helper.Api.Helpers.ProjectileHelper.md 'BTD_Mod_Helper.Api.Helpers.ProjectileHelper')
+↳ [WeaponHelper](BTD_Mod_Helper.Api.Helpers.WeaponHelper.md 'BTD_Mod_Helper.Api.Helpers.WeaponHelper')
+### Constructors
+
+
+
+## ModelHelper(T) Constructor
+
+Creates a wrapper around an existing model
+
+```csharp
+protected ModelHelper(T model);
+```
+#### Parameters
+
+
+
+`model` [T](BTD_Mod_Helper.Api.Helpers.ModelHelper_T_.md#BTD_Mod_Helper.Api.Helpers.ModelHelper_T_.T 'BTD_Mod_Helper.Api.Helpers.ModelHelper.T')
+### Properties
+
+
+
+## ModelHelper.Model Property
+
+The internal model
+
+```csharp
+public virtual T Model { get; }
+```
+
+#### Property Value
+[T](BTD_Mod_Helper.Api.Helpers.ModelHelper_T_.md#BTD_Mod_Helper.Api.Helpers.ModelHelper_T_.T 'BTD_Mod_Helper.Api.Helpers.ModelHelper.T')
\ No newline at end of file
diff --git a/Documentation/BTD_Mod_Helper.Api.Helpers.ProjectileHelper.md b/Documentation/BTD_Mod_Helper.Api.Helpers.ProjectileHelper.md
new file mode 100644
index 000000000..5cc93ea6c
--- /dev/null
+++ b/Documentation/BTD_Mod_Helper.Api.Helpers.ProjectileHelper.md
@@ -0,0 +1,360 @@
+#### [BloonsTD6 Mod Helper](README.md 'README')
+### [BTD_Mod_Helper.Api.Helpers](README.md#BTD_Mod_Helper.Api.Helpers 'BTD_Mod_Helper.Api.Helpers')
+
+## ProjectileHelper Class
+
+A wrapper around ProjectileModels for making them easier to create
+
+```csharp
+public class ProjectileHelper : BTD_Mod_Helper.Api.Helpers.ModelHelper
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 [ModelHelper](BTD_Mod_Helper.Api.Helpers.ModelHelper.md 'BTD_Mod_Helper.Api.Helpers.ModelHelper') 🡒 [BTD_Mod_Helper.Api.Helpers.ModelHelper<](BTD_Mod_Helper.Api.Helpers.ModelHelper_T_.md 'BTD_Mod_Helper.Api.Helpers.ModelHelper')[Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel 'Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel')[>](BTD_Mod_Helper.Api.Helpers.ModelHelper_T_.md 'BTD_Mod_Helper.Api.Helpers.ModelHelper') 🡒 ProjectileHelper
+### Constructors
+
+
+
+## ProjectileHelper(string) Constructor
+
+Begins construction of a new ProjectileModel with sensible default values
+
+```csharp
+public ProjectileHelper(string name="");
+```
+#### Parameters
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+The model name (don't need the ProjectileModel_ part)
+### Properties
+
+
+
+## ProjectileHelper.Behaviors Property
+
+```csharp
+public Model[] Behaviors { get; set; }
+```
+
+#### Property Value
+[Il2CppAssets.Scripts.Models.Model](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Model 'Il2CppAssets.Scripts.Models.Model')[[]](https://docs.microsoft.com/en-us/dotnet/api/System.Array 'System.Array')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.behaviors](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.behaviors 'Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.behaviors')
+
+
+
+## ProjectileHelper.CanCollisionBeBlockedByMapLos Property
+
+```csharp
+public bool CanCollisionBeBlockedByMapLos { get; set; }
+```
+
+#### Property Value
+[System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.canCollisionBeBlockedByMapLos](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.canCollisionBeBlockedByMapLos 'Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.canCollisionBeBlockedByMapLos')
+
+
+
+## ProjectileHelper.CanHitCamo Property
+
+```csharp
+public bool CanHitCamo { get; set; }
+```
+
+#### Property Value
+[System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Filters.FilterInvisibleModel.isActive](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Filters.FilterInvisibleModel.isActive 'Il2CppAssets.Scripts.Models.Towers.Filters.FilterInvisibleModel.isActive')
+
+
+
+## ProjectileHelper.CheckCollisionFrames Property
+
+```csharp
+public int CheckCollisionFrames { get; set; }
+```
+
+#### Property Value
+[System.Int32](https://docs.microsoft.com/en-us/dotnet/api/System.Int32 'System.Int32')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.checkCollisionFrames](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.checkCollisionFrames 'Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.checkCollisionFrames')
+
+
+
+## ProjectileHelper.CollissionPasses Property
+
+```csharp
+public int[] CollissionPasses { get; set; }
+```
+
+#### Property Value
+[System.Int32](https://docs.microsoft.com/en-us/dotnet/api/System.Int32 'System.Int32')[[]](https://docs.microsoft.com/en-us/dotnet/api/System.Array 'System.Array')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.collisionPasses](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.collisionPasses 'Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.collisionPasses')
+
+
+
+## ProjectileHelper.Display Property
+
+```csharp
+public string Display { get; set; }
+```
+
+#### Property Value
+[System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.display](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.display 'Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.display')
+
+
+
+## ProjectileHelper.DisplayModel Property
+
+This ProjectileModel's DisplayModel
+
+```csharp
+public DisplayModel DisplayModel { get; }
+```
+
+#### Property Value
+[Il2CppAssets.Scripts.Models.GenericBehaviors.DisplayModel](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.GenericBehaviors.DisplayModel 'Il2CppAssets.Scripts.Models.GenericBehaviors.DisplayModel')
+
+
+
+## ProjectileHelper.DisplayReference Property
+
+```csharp
+public PrefabReference DisplayReference { get; set; }
+```
+
+#### Property Value
+[Il2CppAssets.Scripts.Utils.PrefabReference](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Utils.PrefabReference 'Il2CppAssets.Scripts.Utils.PrefabReference')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.display](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.display 'Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.display')
+
+
+
+## ProjectileHelper.DontUseCollisionChecker Property
+
+```csharp
+public bool DontUseCollisionChecker { get; set; }
+```
+
+#### Property Value
+[System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.dontUseCollisionChecker](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.dontUseCollisionChecker 'Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.dontUseCollisionChecker')
+
+
+
+## ProjectileHelper.Filter Property
+
+This ProjectileModel's ProjectileFilterModel
+
+```csharp
+public ProjectileFilterModel Filter { get; }
+```
+
+#### Property Value
+[Il2CppAssets.Scripts.Models.Towers.Projectiles.Behaviors.ProjectileFilterModel](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Projectiles.Behaviors.ProjectileFilterModel 'Il2CppAssets.Scripts.Models.Towers.Projectiles.Behaviors.ProjectileFilterModel')
+
+
+
+## ProjectileHelper.Filters Property
+
+```csharp
+public FilterModel[] Filters { get; set; }
+```
+
+#### Property Value
+[Il2CppAssets.Scripts.Models.Towers.Filters.FilterModel](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Filters.FilterModel 'Il2CppAssets.Scripts.Models.Towers.Filters.FilterModel')[[]](https://docs.microsoft.com/en-us/dotnet/api/System.Array 'System.Array')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Projectiles.Behaviors.ProjectileFilterModel.filters](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Projectiles.Behaviors.ProjectileFilterModel.filters 'Il2CppAssets.Scripts.Models.Towers.Projectiles.Behaviors.ProjectileFilterModel.filters')
+
+
+
+## ProjectileHelper.IgnoreBlockers Property
+
+```csharp
+public bool IgnoreBlockers { get; set; }
+```
+
+#### Property Value
+[System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.ignoreBlockers](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.ignoreBlockers 'Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.ignoreBlockers')
+
+
+
+## ProjectileHelper.IgnoreNonTargetable Property
+
+```csharp
+public bool IgnoreNonTargetable { get; set; }
+```
+
+#### Property Value
+[System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.ignoreNonTargetable](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.ignoreNonTargetable 'Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.ignoreNonTargetable')
+
+
+
+## ProjectileHelper.IgnorePierceExhaustion Property
+
+```csharp
+public bool IgnorePierceExhaustion { get; set; }
+```
+
+#### Property Value
+[System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.ignorePierceExhaustion](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.ignorePierceExhaustion 'Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.ignorePierceExhaustion')
+
+
+
+## ProjectileHelper.MaxPierce Property
+
+```csharp
+public float MaxPierce { get; set; }
+```
+
+#### Property Value
+[System.Single](https://docs.microsoft.com/en-us/dotnet/api/System.Single 'System.Single')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.maxPierce](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.maxPierce 'Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.maxPierce')
+
+
+
+## ProjectileHelper.Pierce Property
+
+```csharp
+public float Pierce { get; set; }
+```
+
+#### Property Value
+[System.Single](https://docs.microsoft.com/en-us/dotnet/api/System.Single 'System.Single')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.pierce](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.pierce 'Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.pierce')
+
+
+
+## ProjectileHelper.Radius Property
+
+```csharp
+public float Radius { get; set; }
+```
+
+#### Property Value
+[System.Single](https://docs.microsoft.com/en-us/dotnet/api/System.Single 'System.Single')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.radius](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.radius 'Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.radius')
+
+
+
+## ProjectileHelper.SaveId Property
+
+```csharp
+public string SaveId { get; set; }
+```
+
+#### Property Value
+[System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.saveId](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.saveId 'Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.saveId')
+
+
+
+## ProjectileHelper.Scale Property
+
+```csharp
+public float Scale { get; set; }
+```
+
+#### Property Value
+[System.Single](https://docs.microsoft.com/en-us/dotnet/api/System.Single 'System.Single')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.scale](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.scale 'Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.scale')
+
+
+
+## ProjectileHelper.UsePointCollisionWithBloons Property
+
+```csharp
+public bool UsePointCollisionWithBloons { get; set; }
+```
+
+#### Property Value
+[System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.usePointCollisionWithBloons](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.usePointCollisionWithBloons 'Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.usePointCollisionWithBloons')
+
+
+
+## ProjectileHelper.VsBlockerRadius Property
+
+```csharp
+public float VsBlockerRadius { get; set; }
+```
+
+#### Property Value
+[System.Single](https://docs.microsoft.com/en-us/dotnet/api/System.Single 'System.Single')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.vsBlockerRadius](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.vsBlockerRadius 'Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel.vsBlockerRadius')
+### Operators
+
+
+
+## ProjectileHelper.implicit operator ProjectileHelper(ProjectileModel) Operator
+
+Wraps a model
+
+```csharp
+public static BTD_Mod_Helper.Api.Helpers.ProjectileHelper implicit operator ProjectileHelper(ProjectileModel model);
+```
+#### Parameters
+
+
+
+`model` [Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel 'Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel')
+
+#### Returns
+[ProjectileHelper](BTD_Mod_Helper.Api.Helpers.ProjectileHelper.md 'BTD_Mod_Helper.Api.Helpers.ProjectileHelper')
+
+
+
+## ProjectileHelper.implicit operator ProjectileModel(ProjectileHelper) Operator
+
+Unwraps the model (and updates collission passes)
+
+```csharp
+public static ProjectileModel implicit operator ProjectileModel(BTD_Mod_Helper.Api.Helpers.ProjectileHelper helper);
+```
+#### Parameters
+
+
+
+`helper` [ProjectileHelper](BTD_Mod_Helper.Api.Helpers.ProjectileHelper.md 'BTD_Mod_Helper.Api.Helpers.ProjectileHelper')
+
+#### Returns
+[Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel 'Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel')
\ No newline at end of file
diff --git a/Documentation/BTD_Mod_Helper.Api.Helpers.WeaponHelper.md b/Documentation/BTD_Mod_Helper.Api.Helpers.WeaponHelper.md
new file mode 100644
index 000000000..ebcb624fd
--- /dev/null
+++ b/Documentation/BTD_Mod_Helper.Api.Helpers.WeaponHelper.md
@@ -0,0 +1,252 @@
+#### [BloonsTD6 Mod Helper](README.md 'README')
+### [BTD_Mod_Helper.Api.Helpers](README.md#BTD_Mod_Helper.Api.Helpers 'BTD_Mod_Helper.Api.Helpers')
+
+## WeaponHelper Class
+
+A wrapper around WeaponModels for making them easier to create
+
+```csharp
+public class WeaponHelper : BTD_Mod_Helper.Api.Helpers.ModelHelper
+```
+
+Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 [ModelHelper](BTD_Mod_Helper.Api.Helpers.ModelHelper.md 'BTD_Mod_Helper.Api.Helpers.ModelHelper') 🡒 [BTD_Mod_Helper.Api.Helpers.ModelHelper<](BTD_Mod_Helper.Api.Helpers.ModelHelper_T_.md 'BTD_Mod_Helper.Api.Helpers.ModelHelper')[Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel 'Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel')[>](BTD_Mod_Helper.Api.Helpers.ModelHelper_T_.md 'BTD_Mod_Helper.Api.Helpers.ModelHelper') 🡒 WeaponHelper
+### Constructors
+
+
+
+## WeaponHelper(string) Constructor
+
+Begins construction of a new WeaponModel with sensible default values
+
+```csharp
+public WeaponHelper(string name="");
+```
+#### Parameters
+
+
+
+`name` [System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+The model name (don't need the WeaponModel_ part)
+### Properties
+
+
+
+## WeaponHelper.AnimateOnMainAttack Property
+
+```csharp
+public bool AnimateOnMainAttack { get; set; }
+```
+
+#### Property Value
+[System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.animateOnMainAttack](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.animateOnMainAttack 'Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.animateOnMainAttack')
+
+
+
+## WeaponHelper.Animation Property
+
+```csharp
+public int Animation { get; set; }
+```
+
+#### Property Value
+[System.Int32](https://docs.microsoft.com/en-us/dotnet/api/System.Int32 'System.Int32')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.animation](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.animation 'Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.animation')
+
+
+
+## WeaponHelper.AnimationOffset Property
+
+```csharp
+public float AnimationOffset { get; set; }
+```
+
+#### Property Value
+[System.Single](https://docs.microsoft.com/en-us/dotnet/api/System.Single 'System.Single')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.animationOffset](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.animationOffset 'Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.animationOffset')
+
+
+
+## WeaponHelper.Behaviors Property
+
+```csharp
+public WeaponBehaviorModel[] Behaviors { get; set; }
+```
+
+#### Property Value
+[Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponBehaviorModel](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponBehaviorModel 'Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponBehaviorModel')[[]](https://docs.microsoft.com/en-us/dotnet/api/System.Array 'System.Array')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.behaviors](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.behaviors 'Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.behaviors')
+
+
+
+## WeaponHelper.CustomStartCooldown Property
+
+```csharp
+public float CustomStartCooldown { get; set; }
+```
+
+#### Property Value
+[System.Single](https://docs.microsoft.com/en-us/dotnet/api/System.Single 'System.Single')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.customStartCooldown](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.customStartCooldown 'Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.customStartCooldown')
+
+
+
+## WeaponHelper.Eject Property
+
+```csharp
+public Vector3 Eject { get; set; }
+```
+
+#### Property Value
+[Il2CppAssets.Scripts.Simulation.SMath.Vector3](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Simulation.SMath.Vector3 'Il2CppAssets.Scripts.Simulation.SMath.Vector3')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.ejectX](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.ejectX 'Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.ejectX')
+- [Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.ejectY](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.ejectY 'Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.ejectY')
+- [Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.ejectZ](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.ejectZ 'Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.ejectZ')
+
+
+
+## WeaponHelper.Emission Property
+
+```csharp
+public EmissionModel Emission { get; set; }
+```
+
+#### Property Value
+[Il2CppAssets.Scripts.Models.Towers.Behaviors.Emissions.EmissionModel](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Behaviors.Emissions.EmissionModel 'Il2CppAssets.Scripts.Models.Towers.Behaviors.Emissions.EmissionModel')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.emission](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.emission 'Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.emission')
+
+
+
+## WeaponHelper.FireBetweenRounds Property
+
+```csharp
+public bool FireBetweenRounds { get; set; }
+```
+
+#### Property Value
+[System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.fireBetweenRounds](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.fireBetweenRounds 'Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.fireBetweenRounds')
+
+
+
+## WeaponHelper.FireWithoutTarget Property
+
+```csharp
+public bool FireWithoutTarget { get; set; }
+```
+
+#### Property Value
+[System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.fireWithoutTarget](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.fireWithoutTarget 'Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.fireWithoutTarget')
+
+
+
+## WeaponHelper.Projectile Property
+
+```csharp
+public ProjectileModel Projectile { get; set; }
+```
+
+#### Property Value
+[Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel 'Il2CppAssets.Scripts.Models.Towers.Projectiles.ProjectileModel')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.projectile](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.projectile 'Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.projectile')
+
+
+
+## WeaponHelper.Rate Property
+
+```csharp
+public float Rate { get; set; }
+```
+
+#### Property Value
+[System.Single](https://docs.microsoft.com/en-us/dotnet/api/System.Single 'System.Single')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.Rate](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.Rate 'Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.Rate')
+
+
+
+## WeaponHelper.StartInCooldown Property
+
+```csharp
+public bool StartInCooldown { get; set; }
+```
+
+#### Property Value
+[System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.startInCooldown](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.startInCooldown 'Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.startInCooldown')
+
+
+
+## WeaponHelper.UseAttackPosition Property
+
+```csharp
+public bool UseAttackPosition { get; set; }
+```
+
+#### Property Value
+[System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
+
+### See Also
+- [Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.useAttackPosition](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.useAttackPosition 'Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel.useAttackPosition')
+### Operators
+
+
+
+## WeaponHelper.implicit operator WeaponHelper(WeaponModel) Operator
+
+Wraps a model
+
+```csharp
+public static BTD_Mod_Helper.Api.Helpers.WeaponHelper implicit operator WeaponHelper(WeaponModel model);
+```
+#### Parameters
+
+
+
+`model` [Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel 'Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel')
+
+#### Returns
+[WeaponHelper](BTD_Mod_Helper.Api.Helpers.WeaponHelper.md 'BTD_Mod_Helper.Api.Helpers.WeaponHelper')
+
+
+
+## WeaponHelper.implicit operator WeaponModel(WeaponHelper) Operator
+
+Unwraps the model
+
+```csharp
+public static WeaponModel implicit operator WeaponModel(BTD_Mod_Helper.Api.Helpers.WeaponHelper helper);
+```
+#### Parameters
+
+
+
+`helper` [WeaponHelper](BTD_Mod_Helper.Api.Helpers.WeaponHelper.md 'BTD_Mod_Helper.Api.Helpers.WeaponHelper')
+
+#### Returns
+[Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel 'Il2CppAssets.Scripts.Models.Towers.Weapons.WeaponModel')
\ No newline at end of file
diff --git a/Documentation/BTD_Mod_Helper.Extensions.TowerModelBehaviorExt.md b/Documentation/BTD_Mod_Helper.Extensions.TowerModelBehaviorExt.md
index 1a9b19077..4b919b8b0 100644
--- a/Documentation/BTD_Mod_Helper.Extensions.TowerModelBehaviorExt.md
+++ b/Documentation/BTD_Mod_Helper.Extensions.TowerModelBehaviorExt.md
@@ -12,6 +12,25 @@ public static class TowerModelBehaviorExt
Inheritance [System.Object](https://docs.microsoft.com/en-us/dotnet/api/System.Object 'System.Object') 🡒 TowerModelBehaviorExt
### Methods
+
+
+## TowerModelBehaviorExt.AddBehavior(this TowerModel, ModelHelper) Method
+
+Adds a wrapped behavior from a ModelHelper to this tower
+
+```csharp
+public static void AddBehavior(this TowerModel model, BTD_Mod_Helper.Api.Helpers.ModelHelper behavior);
+```
+#### Parameters
+
+
+
+`model` [Il2CppAssets.Scripts.Models.Towers.TowerModel](https://docs.microsoft.com/en-us/dotnet/api/Il2CppAssets.Scripts.Models.Towers.TowerModel 'Il2CppAssets.Scripts.Models.Towers.TowerModel')
+
+
+
+`behavior` [ModelHelper](BTD_Mod_Helper.Api.Helpers.ModelHelper.md 'BTD_Mod_Helper.Api.Helpers.ModelHelper')
+
## TowerModelBehaviorExt.AddBehavior(this TowerModel, T) Method
diff --git a/Documentation/BTD_Mod_Helper.ModHelper.md b/Documentation/BTD_Mod_Helper.ModHelper.md
index 8614b8575..af742b856 100644
--- a/Documentation/BTD_Mod_Helper.ModHelper.md
+++ b/Documentation/BTD_Mod_Helper.ModHelper.md
@@ -25,6 +25,22 @@ public static string DisabledModsDirectory { get; }
#### Property Value
[System.String](https://docs.microsoft.com/en-us/dotnet/api/System.String 'System.String')
+
+
+## ModHelper.IsEpic Property
+
+Gets whether the game is running as the Epic Store version
+
+This checks that the [MelonLoader.MelonGameAttribute](https://docs.microsoft.com/en-us/dotnet/api/MelonLoader.MelonGameAttribute 'MelonLoader.MelonGameAttribute') has been properly changed by
+BTD6EpicGamesModCompat
+
+```csharp
+public static bool IsEpic { get; }
+```
+
+#### Property Value
+[System.Boolean](https://docs.microsoft.com/en-us/dotnet/api/System.Boolean 'System.Boolean')
+
## ModHelper.IsNet6 Property
diff --git a/Documentation/README.md b/Documentation/README.md
index 030a2d29b..baf7c5318 100644
--- a/Documentation/README.md
+++ b/Documentation/README.md
@@ -141,13 +141,18 @@
| Classes | |
| :--- | :--- |
| [ActionHelper](BTD_Mod_Helper.Api.Helpers.ActionHelper.md 'BTD_Mod_Helper.Api.Helpers.ActionHelper') | Class for converting actions and functions |
+| [AttackHelper](BTD_Mod_Helper.Api.Helpers.AttackHelper.md 'BTD_Mod_Helper.Api.Helpers.AttackHelper') | A wrapper around AttackModels for making them easier to create |
| [CostHelper](BTD_Mod_Helper.Api.Helpers.CostHelper.md 'BTD_Mod_Helper.Api.Helpers.CostHelper') | Helper for scaling costs to difficulties |
| [FileDialogHelper](BTD_Mod_Helper.Api.Helpers.FileDialogHelper.md 'BTD_Mod_Helper.Api.Helpers.FileDialogHelper') | Class to help with the usage of Native File Dialogs |
| [FileIOHelper](BTD_Mod_Helper.Api.Helpers.FileIOHelper.md 'BTD_Mod_Helper.Api.Helpers.FileIOHelper') | Class replacing the original functionality of FileIOUtil before BTD6 update 33.0 |
| [GameModelExporter](BTD_Mod_Helper.Api.Helpers.GameModelExporter.md 'BTD_Mod_Helper.Api.Helpers.GameModelExporter') | Class for handily exporting elements of the GameModel to json files |
| [MapHelper](BTD_Mod_Helper.Api.Helpers.MapHelper.md 'BTD_Mod_Helper.Api.Helpers.MapHelper') | Contains helper methods for working with maps and custom maps. |
| [MatchScale](BTD_Mod_Helper.Api.Helpers.MatchScale.md 'BTD_Mod_Helper.Api.Helpers.MatchScale') | Component to make this transform continuously match the scale of another transform |
+| [ModelHelper](BTD_Mod_Helper.Api.Helpers.ModelHelper.md 'BTD_Mod_Helper.Api.Helpers.ModelHelper') | A wrapper class around a Model |
+| [ModelHelper<T>](BTD_Mod_Helper.Api.Helpers.ModelHelper_T_.md 'BTD_Mod_Helper.Api.Helpers.ModelHelper') | A wrapper class around a Model |
| [ProcessHelper](BTD_Mod_Helper.Api.Helpers.ProcessHelper.md 'BTD_Mod_Helper.Api.Helpers.ProcessHelper') | Helper methods for processes |
+| [ProjectileHelper](BTD_Mod_Helper.Api.Helpers.ProjectileHelper.md 'BTD_Mod_Helper.Api.Helpers.ProjectileHelper') | A wrapper around ProjectileModels for making them easier to create |
+| [WeaponHelper](BTD_Mod_Helper.Api.Helpers.WeaponHelper.md 'BTD_Mod_Helper.Api.Helpers.WeaponHelper') | A wrapper around WeaponModels for making them easier to create |