### Initialize Item and NPC Data Structures Source: https://context7.com/hocha113/calamityoverhaul/llms.txt Sets up dictionaries for item categorization (guns, shotguns, bows, etc.) and lists for NPC targeting. This code scans all items to populate these structures. ```csharp public static class CWRLoad { // Weapon type dictionaries internal static Dictionary ItemIsGun { get; private set; } = []; internal static Dictionary ItemIsShotgun { get; private set; } = []; internal static Dictionary ItemIsBow { get; private set; } = []; internal static Dictionary ItemIsCrossBow { get; private set; } = []; internal static Dictionary ItemIsHeldSwing { get; private set; } = []; internal static Dictionary ItemHasCartridgeHolder { get; private set; } = []; internal static Dictionary ItemIsGunAndGetRecoilValue { get; private set; } = []; // Tile/Wall to Item mappings public static Dictionary TileToItem { get; private set; } = []; public static Dictionary WallToItem { get; private set; } = []; // NPC type lists for worm-type enemies public static List targetNpcTypes; // Sepulcher public static List targetNpcTypes2; // Storm Weaver public static List targetNpcTypes8; // Devourer of Gods public static void Setup() { // Initialize NPC type lists targetNpcTypes = [CWRID.NPC_SepulcherHead, CWRID.NPC_SepulcherBody, CWRID.NPC_SepulcherTail]; targetNpcTypes8 = [CWRID.NPC_DevourerofGodsHead, CWRID.NPC_DevourerofGodsBody, CWRID.NPC_DevourerofGodsTail]; // Scan all items and categorize for (int itemType = 0; itemType < ItemLoader.ItemCount; itemType++) { Item item = ContentSamples.ItemsByType[itemType]; if (item == null || item.type == ItemID.None) continue; CWRItem cwrItem = item.CWR(); ItemIsHeldSwing[itemType] = cwrItem.IsHeldSwing; ItemHasCartridgeHolder[itemType] = cwrItem.HasCartridgeHolder; int heldProjType = cwrItem.heldProjType; if (heldProjType > 0) { Projectile heldProj = new Projectile(); heldProj.SetDefaults(heldProjType); if (heldProj.ModProjectile is BaseGun gun) { ItemIsGun[itemType] = true; ItemIsCrossBow[itemType] = gun.IsCrossbow; ItemIsGunAndGetRecoilValue[itemType] = gun.Recoil; } if (heldProj.ModProjectile is BaseBow bow) { ItemIsBow[itemType] = true; } } } } /// /// Gets localization key for recoil level description /// public static string GetLckRecoilKey(float recoil) { float recoilValue = Math.Abs(recoil); return recoilValue switch { 0 => "CWRGun_Recoil_Level_0", < 0.1f => "CWRGun_Recoil_Level_1", < 0.5f => "CWRGun_Recoil_Level_2", < 1.5f => "CWRGun_Recoil_Level_3", < 2.2f => "CWRGun_Recoil_Level_4", < 3.2f => "CWRGun_Recoil_Level_5", _ => "CWRGun_Recoil_Level_6" }; } } ``` -------------------------------- ### Server Configuration Settings Source: https://context7.com/hocha113/calamityoverhaul/llms.txt Manages server-side mod settings including weapon systems, world generation toggles, and UI preferences. ```csharp // Common/CWRServerConfig.cs public class CWRServerConfig : ModConfig { public static CWRServerConfig Instance { get; private set; } public override ConfigScope Mode => ConfigScope.ServerSide; // Weapon systems [DefaultValue(true)] public bool WeaponHandheldDisplay { get; set; } // Handheld weapon animations [DefaultValue(true)] public bool EnableSwordLight { get; set; } // Melee slash trails [DefaultValue(false)] public bool ActivateGunRecoil { get; set; } // Player knockback from guns [DefaultValue(true)] public bool MagazineSystem { get; set; } // Magazine/reload system [DefaultValue(true)] public bool EnableCasingsEntity { get; set; } // Shell casing particles [DefaultValue(true)] public bool BowArrowDraw { get; set; } // Arrow visualization on bows [DefaultValue(false)] public bool ShotgunFireForcedReloadInterruption { get; set; } [DefaultValue(false)] public bool WeaponLazyRotationAngle { get; set; } // Delayed rotation tracking // World generation [DefaultValue(true)] public bool GenWindGrivenGenerator { get; set; } [DefaultValue(true)] public bool GenJunkmanBase { get; set; } // UI settings [DefaultValue(false)] public bool ShowReloadingProgressUI { get; set; } [Range(1, 5)] [DefaultValue(1)] public int MuraUIStyleType { get; set; } // Murasama UI style variants } ``` -------------------------------- ### Initialize Calamity Overhaul Mod Source: https://context7.com/hocha113/calamityoverhaul/llms.txt The main mod class handles lifecycle management, mod detection, and cross-mod compatibility. It initializes core systems and loads compatible mods. ```csharp public class CWRMod : Mod { internal static CWRMod Instance { get; private set; } internal static List ILoaders { get; private set; } = []; // Cross-mod references internal Mod calamity = null; internal Mod thoriumMod = null; internal Mod fargowiltasSouls = null; internal Mod magicStorage = null; public override void Load() { Instance = this; FindMod(); // Detect and cache compatible mods if (CWRRef.Has) { ModGanged.Load(); } CWRRef.Load(); ILoaders = VaultUtils.GetDerivedInstances(); foreach (var load in ILoaders) { try { load.LoadData(); } catch { Logger.Error("An error occurred while loading " + load.GetType().Name); } } } public override void PostSetupContent() { CWRLoad.Setup(); foreach (var load in ILoaders) { try { load.SetupData(); if (!Main.dedServ) { load.LoadAsset(); } } catch { Logger.Error("An error occurred while post-setup " + load.GetType().Name); } } } public override void HandlePacket(BinaryReader reader, int whoAmI) => CWRNetWork.HandlePacket(this, reader, whoAmI); } ``` -------------------------------- ### CWRPlayer Extension Class Source: https://context7.com/hocha113/calamityoverhaul/llms.txt Extends the vanilla player class to track mod-specific states, equipment bonuses, combat mechanics, and screen effects. ```csharp // Content/CWRPlayer.cs public class CWRPlayer : ModPlayer { // Equipment and state tracking public bool HasOverhaulTheBibleBook; public int LoadMuzzleBrakeLevel; public float PressureIncrease; public float KreloadTimeIncrease; // Combat states public bool HeldMurasamaBool; public bool EndSkillEffectStartBool; public int SwingIndex; public int PlayerIsKreLoadTime; public float ReloadingRatio; // Movement and dash system public Vector2? PendingDashVelocity { get; set; } = null; public float PendingDashRotSpeedMode = 0.015f; public float DecelerationCounter { get; set; } public bool IsRotatingDuringDash { get; set; } public float RotationDirection { get; set; } = 1f; // Screen effects public Vector2 OffsetScreenPos; public float ScreenShakeValue; // Debuff tracking public bool HellfireExplosion; public bool SoulfireExplosion; } ``` -------------------------------- ### Implement BaseGun System in C# Source: https://context7.com/hocha113/calamityoverhaul/llms.txt The BaseGun class provides the foundation for all overhauled firearms with recoil mechanics, muzzle flash effects, shell ejection, and smooth aiming animations. ```csharp // Content/RangedModify/Core/BaseGun.cs public abstract class BaseGun : BaseHeldRanged { // Recoil and gun pressure settings public float GunPressure = 0; public float ControlForce = 0.01f; public float Recoil = 1.2f; public float RangeOfStress = 10; // Position and rotation offsets public float OffsetRot; public Vector2 OffsetPos; public float HandIdleDistanceX = 15; public float HandFireDistanceX = 20; public float HandFireDistanceY = -4; // Crossbow support public bool IsCrossbow; public bool CanDrawCrossArrow = true; /// /// Creates recoil effect when firing. Call this in shoot methods. /// public virtual Vector2 CreateRecoil() { OffsetRot += GunPressure * OwnerPressureIncrease; if (!CWRServerConfig.Instance.ActivateGunRecoil) { return Vector2.Zero; } Vector2 recoilVr = ShootVelocity.UnitVector() * (Recoil * -OwnerPressureIncrease); if (Math.Abs(Owner.velocity.X) < RangeOfStress && Math.Abs(Owner.velocity.Y) < RangeOfStress) { Owner.velocity += recoilVr; } return recoilVr; } /// /// Quick method for ejecting shell casings /// public virtual void CaseEjection(float slp = 1) { if (CWRMod.Instance.terrariaOverhaul != null && slp == 1 || !CWRServerConfig.Instance.EnableCasingsEntity) { return; } Vector2 pos = Owner.Top + Owner.Top.To(ShootPos) / 2; Vector2 vr = (Projectile.rotation - Main.rand.NextFloat(-0.1f, 0.1f) * DirSign) .ToRotationVector2() * -Main.rand.NextFloat(3, 7) + Owner.velocity; Gore.NewGore(Source2, pos, vr, CaseGore.PType, slp == 1 ? EjectCasingProjSize : slp); } /// /// Override to implement left-click firing behavior /// public virtual void FiringShoot() { Projectile.NewProjectile(Source, ShootPos, ShootVelocity, AmmoTypes, WeaponDamage, WeaponKnockback, Owner.whoAmI, 0); _ = UpdateConsumeAmmo(); } /// /// Spawns muzzle flash dust particles /// public virtual void SpawnGunFireDust(Vector2 pos = default, Vector2 velocity = default, float splNum = 1f, int dustID1 = 262, int dustID2 = 54, int dustID3 = 53) { if (pos == default) pos = ShootPos; if (velocity == default) velocity = ShootVelocity; pos += velocity.SafeNormalize(Vector2.Zero) * Projectile.width * Projectile.scale * 0.71f; for (int i = 0; i < 30 * splNum; i++) { int dustID = Main.rand.Next(6) switch { 0 => dustID1, 1 or 2 => dustID2, _ => dustID3 }; float num = Main.rand.NextFloat(3f, 13f) * splNum; Vector2 dustVel = new Vector2(num, 0f).RotatedBy(velocity.ToRotation()) .RotatedByRandom(0.12f); Dust.NewDust(pos, 1, 1, dustID, dustVel.X, dustVel.Y, 0, default, Main.rand.NextFloat(0.5f, 1.5f)); } } } ``` -------------------------------- ### Boss AI State Machine Implementation Source: https://context7.com/hocha113/calamityoverhaul/llms.txt Defines the state machine structure for boss AI, including the state index, interface, and base class for state transitions and movement logic. ```csharp // Content/NPCs/BrutalNPCs/BrutalDestroyer/Core/IDestroyerState.cs internal enum DestroyerStateIndex : int { Intro = 0, Patrol = 1, DashPrepare = 2, Dashing = 3, DashCooldown = 4, LaserBarrage = 5, Encircle = 6, ProbeMatrix = 7, Despawn = 8, Death = 9, } internal interface IDestroyerState { string StateName { get; } DestroyerStateIndex StateIndex { get; } void OnEnter(DestroyerStateContext context); IDestroyerState OnUpdate(DestroyerStateContext context); void OnExit(DestroyerStateContext context); } internal abstract class DestroyerStateBase : IDestroyerState { public abstract string StateName { get; } public abstract DestroyerStateIndex StateIndex { get; } protected int Timer { get; set; } protected int Counter { get; set; } public virtual void OnEnter(DestroyerStateContext context) { Timer = 0; Counter = 0; } public abstract IDestroyerState OnUpdate(DestroyerStateContext context); public virtual void OnExit(DestroyerStateContext context) { context.ResetChargeState(); } /// /// Sets worm movement parameters for the main controller /// protected void SetMovement(DestroyerStateContext context, Vector2 targetPos, float speed, float turnSpeed) { context.TargetPosition = targetPos; context.MoveSpeed = speed; context.TurnSpeed = turnSpeed; } /// /// Smoothly rotates NPC to face target /// protected void FaceTarget(NPC npc, Vector2 target, float lerpFactor = 0.15f) { float targetAngle = (target - npc.Center).ToRotation() + MathHelper.PiOver2; npc.rotation = npc.rotation.AngleLerp(targetAngle, lerpFactor); } } ``` -------------------------------- ### BaseSwing Class Definition Source: https://context7.com/hocha113/calamityoverhaul/llms.txt Defines the core properties and abstract methods for melee weapon swings. Includes parameters for swing customization, trail rendering, and size scaling. ```csharp internal abstract class BaseSwing : BaseHeldProj { // Swing parameters public float Length = 60; public float Rotation; protected float speed; protected int maxSwingTime = 22; protected int Time; // Trail rendering settings protected int drawTrailCount = 15; protected float drawTrailTopWidth = 50; protected float drawTrailBtommWidth = 70; protected bool canDrawSlashTrail = false; // Melee size scaling public bool AffectedMeleeSize = true; public float MeleeSize => AffectedMeleeSize ? _meleeSize * OtherMeleeSize : 1f; // Texture paths for slash effects public virtual string trailTexturePath => ""; public virtual string gradientTexturePath => ""; /// /// Implements standard swing behavior with acceleration curves /// public virtual void SwingBehavior(float starArg = 33, float baseSwingSpeed = 4, float ler1_UpLengthSengs = 0.08f, float ler1_UpSpeedSengs = 0.1f, float ler1_UpSizeSengs = 0.012f, float ler2_DownLengthSengs = 0.01f, float ler2_DownSpeedSengs = 0.1f, float ler2_DownSizeSengs = 0, int minClampLength = 0, int maxClampLength = 0, int ler1Time = 0, int maxSwingTime = 0) { float speedUp = SwingMultiplication; if (Time == 0) { Rotation = MathHelper.ToRadians(starArg * -Owner.direction); startVector = RodingToVer(1, Projectile.velocity.ToRotation() - MathHelper.PiOver2 * Projectile.spriteDirection); speed = MathHelper.ToRadians(baseSwingSpeed) / speedUp; } // Phase 1: Acceleration if (Time < ler1Time * speedUp) { Length *= 1 + ler1_UpLengthSengs / UpdateRate; Rotation += speed * Projectile.spriteDirection; speed *= 1 + ler1_UpSpeedSengs / UpdateRate; Projectile.scale += ler1_UpSizeSengs; } // Phase 2: Deceleration else { Length *= 1 - ler2_DownLengthSengs / UpdateRate; Rotation += speed * Projectile.spriteDirection; speed *= 1 - ler2_DownSpeedSengs / UpdateRate / speedUp; Projectile.scale -= ler2_DownSizeSengs; } vector = startVector.RotatedBy(Rotation) * Length; if (Time >= maxSwingTime * UpdateRate * speedUp) { Projectile.Kill(); } } /// /// Implements stab/thrust behavior for spears /// public void StabBehavior(float initialLength = float.MaxValue, float initialSpeedFactor = 0.4f, float speedDecayRate = 0.015f, int lifetime = 0, float initialScale = 1, int minLength = 60, int maxLength = 90) { if (Time == 0) { if (initialLength != float.MaxValue) Length = initialLength; startVector = Projectile.velocity.UnitVector(); speed = 1 + initialSpeedFactor / UpdateRate / SwingMultiplication; } Length *= speed; vector = startVector * Length * SwingMultiplication; speed -= speedDecayRate / UpdateRate; if (Time >= lifetime * UpdateRate * SwingMultiplication) { Projectile.Kill(); } } /// /// Draws the slash trail using GPU-accelerated rendering /// public virtual void DrawSlashTrail() { List bars = []; GetCurrentTrailCount(out float count); for (int i = 0; i < count; i++) { if (oldRotate[i] == 100f) continue; float factor = 1f - i / count; Vector2 Center = GetInOwnerDrawOrigPosition(); Vector2 Top = Center + oldRotate[i].ToRotationVector2() * (oldLength[i] + drawTrailTopWidth * meleeSizeAsymptotic + oldDistanceToOwner[i]); Vector2 Bottom = Center + oldRotate[i].ToRotationVector2() * (oldLength[i] - ControlTrailBottomWidth(factor) + oldDistanceToOwner[i]); var topColor = Color.Lerp(new Color(238, 218, 130, 200), new Color(167, 127, 95, 0), 1 - factor); var bottomColor = Color.Lerp(new Color(109, 73, 86, 200), new Color(83, 16, 85, 0), 1 - factor); bars.Add(new VertexPositionColorTexture(Top.ToVector3(), topColor, new Vector2(factor, 0))); bars.Add(new VertexPositionColorTexture(Bottom.ToVector3(), bottomColor, new Vector2(factor, 1))); } if (bars.Count > 2) { DrawTrailHander(bars, Main.graphics.GraphicsDevice, BlendState.NonPremultiplied, SamplerState.PointWrap, RasterizerState.CullNone); } } } ``` -------------------------------- ### BaseBow Class Definition Source: https://context7.com/hocha113/calamityoverhaul/llms.txt Defines the fundamental properties and methods for a bow weapon, including aiming parameters, arrow drawing settings, bowstring data, and core actions like shooting and drawing. ```csharp public abstract class BaseBow : BaseHeldRanged { // Arm positioning public int ArmRotSengsFrontBaseValue = 60; public int ArmRotSengsBackBaseValue = 70; public float AimingAnimationSpeed = 0.1f; // Arrow drawing settings public bool BowArrowDrawBool = true; public int BowArrowDrawNum = 1; protected int DrawArrowMode = -20; // Bowstring data for rendering public BowstringDataStruct BowstringData = new(); /// /// Override to implement bow firing /// public virtual void BowShoot() { int proj = Projectile.NewProjectile(Source, Projectile.Center + FireOffsetPos, ShootVelocity + FireOffsetVector, AmmoTypes, WeaponDamage, WeaponKnockback, Owner.whoAmI, 0); Main.projectile[proj].CWR().SpanTypes = (byte)ShootSpanTypeValue; Main.projectile[proj].rotation = Main.projectile[proj].velocity.ToRotation() + MathHelper.PiOver2; } /// /// Draws the bowstring with bezier curve /// public virtual void DrawBowstring(Vector2 drawPos) { BowstringData.Points = new Vector2[3]; Vector2 toProjRot = Projectile.rotation.ToRotationVector2(); Vector2 bowPos = drawPos - toProjRot * (TextureValue.Width / 2 - 1); float lengsOFstValue = ShootCoolingValue / Item.useTime * 16; BowstringData.Points[0] = /* top position */; BowstringData.Points[1] = bowPos - toProjRot * lengsOFstValue; // Pull point BowstringData.Points[2] = /* bottom position */; List pathPoints = Trail.GenerateSmoothPath(BowstringData.Points, Vector2.Zero, 88); if (pathPoints.Count >= 2) { Trail.GenerateInterleavedMesh(pathPoints, BowstringData.thicknessEvaluator, BowstringData.colorEvaluator, out ColoredVertex[] vertices, out short[] indices, handlerTexturePoss: HanderBowstringTexturePoss); Trail.DrawUserPrimitives(vertices, indices); } } /// /// Constrains bow angle for mounted weapons /// public void LimitingAngle(int minrot = 50, int maxrot = 130) { float minRot = MathHelper.ToRadians(minrot); float maxRot = MathHelper.ToRadians(maxrot); Projectile.rotation = MathHelper.Clamp(ToMouseA + MathHelper.Pi, minRot, maxRot) - MathHelper.Pi; Projectile.Center = Owner.GetPlayerStabilityCenter() + Projectile.rotation.ToRotationVector2() * HandheldDistance; } } ``` -------------------------------- ### BaseFeederGun Class Definition Source: https://context7.com/hocha113/calamityoverhaul/llms.txt Defines the abstract BaseFeederGun class, extending BaseGun and implementing core magazine and reload functionalities. Includes properties for ammo state, reload timing, and animation styles. ```csharp public abstract class BaseFeederGun : BaseGun { // Magazine state tracking internal AmmoState AmmoState; internal bool OnKreload; internal int KreloadMaxTime { get; set; } = 60; protected int kreloadTimeValue; // Reload settings protected bool ReturnRemainingBullets = true; protected int MinimumAmmoPerReload = 1; protected int LoadingQuantity = 0; // Animation style enum public LoadingAmmoAnimationEnum LoadingAmmoAnimation = LoadingAmmoAnimationEnum.None; // Bullet count property linked to item data protected int BulletNum { get => Item.CWR()?.NumberBullets ?? 0; set { if (Item.CWR() != null) Item.CWR().NumberBullets = value; } } /// /// Loads bullets into the magazine from player inventory /// public virtual void LoadBulletsIntoMagazine() { CWRItem cwrItems = Item.CWR(); int quantity = LoadingQuantity > 0 ? LoadingQuantity : cwrItems.AmmoCapacity; if (BulletNum < cwrItems.AmmoCapacity) { AmmoState = Owner.GetAmmoState(Item.useAmmo); foreach (var ammo in AmmoState.CurrentItems) { cwrItems.LoadenMagazine(ammo, LoadingQuantity); if (BulletNum >= quantity) break; } } } /// /// Updates magazine after firing, handles ammo consumption /// public void UpdateMagazineContents() { if (!MagazineSystem) { UpdateConsumeAmmo(); return; } CWRItem cwrItems = Item.CWR(); if (cwrItems.MagazineContents.Length <= 0) { cwrItems.InitializeMagazine(); IsKreload = false; return; } if (IsKreload) { Item targetAmmo = cwrItems.GetSelectedBullets(); targetAmmo.stack--; if (targetAmmo.stack <= 0) { cwrItems.SetMagazine(cwrItems.MagazineContents); } else { cwrItems.CalculateNumberBullet(); } } } /// /// Handles empty magazine feedback /// public virtual void HandleEmptyAmmoEjection() { SoundEngine.PlaySound(CWRSound.Ejection, Projectile.Center); string textKey = Item.useAmmo switch { AmmoID.Coin => "CaseEjection_TextContent_Coin", AmmoID.Arrow => "CaseEjection_TextContent_Arrow", _ => "CaseEjection_TextContent" }; CombatText.NewText(Owner.Hitbox, Color.Gold, CWRLocText.GetTextValue(textKey)); } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.