### Basic ARC9 Weapon Setup (Lua) Source: https://github.com/haodongmo/arc-9/wiki/Your-First-Weapon Defines the essential properties for a new ARC9 weapon. This includes setting the base weapon script, spawnability, and the viewmodel. Ensure SWEP.Base is set to 'arc9_base' and SWEP.Spawnable to true. ```lua SWEP.Base = "arc9_base" SWEP.Spawnable = true SWEP.ViewModel = "models/your_viewmodel.mdl" -- Set your desired viewmodel path here ``` -------------------------------- ### Mult Modifier Example (Lua) Source: https://github.com/haodongmo/arc-9/wiki/Stat-Handling Shows how to use the Mult modifier to multiply a numeric stat by a given value. This example multiplies the maximum damage stat by 1.5. ```lua -- Multiplies close range damage by 1.5. ATT.DamageMaxMult = 1.5 ``` -------------------------------- ### Add Modifier Example (Lua) Source: https://github.com/haodongmo/arc-9/wiki/Stat-Handling Demonstrates the Add modifier, which adds a value to a numeric stat after any Mult modifiers have been applied. Examples include adding to clip size and subtracting from damage. ```lua -- Adds 1 to clip size. ATT.ClipSizeAdd = 1 -- Subtracts 10 from long range damage. ATT.DamageMinAdd = -10 ``` -------------------------------- ### Override Modifier Example (Lua) Source: https://github.com/haodongmo/arc-9/wiki/Stat-Handling Provides an example of using the Override modifier to change a stat's value to a specific one, in this case, changing the damage type for a bash attack. It also shows how to set a priority for the override. ```lua -- Overrides melee damage to burning. ATT.BashDamageTypeOverride = DMG_BURN -- This override has a higher priority than normal. ATT.BashDamageTypeOverride_Priority = 2 ``` -------------------------------- ### ARC9 Base Configuration File Example Source: https://github.com/haodongmo/arc-9/blob/main/README.md This snippet refers to the base configuration file for ARC9, specifically 'weapons/arc9_base/shared.lua' and 'arc9/common/attachments/default.lua'. These files are essential for understanding and developing new weapons and attachments within the ARC9 system. ```lua -- Read weapons/arc9_base/shared.lua, arc9/common/attachments/default.lua, and this file. ``` -------------------------------- ### ARC9 Recoil System Overview vs. ArcCW Source: https://github.com/haodongmo/arc-9/wiki/Notable-Changes-from-ArcCW This example contrasts the recoil mechanics of ArcCW and ARC9. ARC9 introduces a predictable recoil pattern system similar to CS:GO, moving away from ArcCW's purely random recoil. It also includes optional visual and camera recoil, which are omitted here for brevity. ```lua -- ArcCW SWEP.Recoil = 2 SWEP.RecoilSide = 1 SWEP.RecoilRise = 1 SWEP.MaxRecoilBlowback = -1 SWEP.VisualRecoilMult = 1.25 SWEP.RecoilPunch = 1.5 SWEP.RecoilPunchBackMax = 1 SWEP.RecoilPunchBackMaxSights = nil -- may clip with scopes SWEP.RecoilVMShake = 1 -- random viewmodel offset when shooty -- ARC9 SWEP.Recoil = 1 -- General recoil multiplier -- These multipliers affect the predictible recoil by making the pattern taller, shorter, wider, or thinner. SWEP.RecoilUp = 1 -- Multiplier for vertical recoil SWEP.RecoilSide = 1 -- Multiplier for vertical recoil -- These values determine how much extra movement is applied to the recoil entirely randomly, like in a circle. -- This type of recoil CANNOT be predicted. SWEP.RecoilRandomUp = 0.1 SWEP.RecoilRandomSide = 0.1 SWEP.RecoilDissipationRate = 10 -- How much recoil dissipates per second. SWEP.RecoilResetTime = 0.1 -- How long the gun must go before the recoil pattern starts to reset. SWEP.RecoilAutoControl = 1 -- Multiplier for automatic recoil control. ``` -------------------------------- ### Create Sub-Attachments for Modular Customization (Lua) Source: https://context7.com/haodongmo/arc-9/llms.txt Defines a sub-attachment (e.g., a scope) that can be installed on a primary attachment slot. It configures sight properties, reticles, and can include its own set of attachment slots for further modularity. This allows for multi-stage customization of weapon optics and other components. This is typically done in an attachment's Lua file. ```lua ATT.PrintName = "ACOG Scope" ATT.Category = "optic" -- Main sight configuration ATT.Sights = { { Pos = Vector(-0.05, 10, -1.5), Ang = Angle(0, 0, 0), Magnification = 1.25, ViewModelFOV = 50, } } ATT.RTScope = true ATT.RTScopeMagnification = 4 ATT.RTScopeReticle = Material("arc9/reticles/acog.png") ATT.ScopeScreenRatio = 0.5 -- Add sub-attachment slots ATT.Attachments = { { PrintName = "Optic Mount", Category = "optic_lp", -- Low-profile optics on top Pos = Vector(0, -2, -1), Ang = Angle(0, 0, 0), Icon_Offset = Vector(0, 0, 0.5), ExtraSightDistance = 3, -- This creates second sight position Sights = { { Pos = Vector(-0.05, 8, -2.5), Ang = Angle(0, 0, 0), Disassociate = true, } } }, { PrintName = "Scope Color", Category = "reticle_color", DefaultIcon = Material("entities/arc9_att_default_color.png"), }, } -- Stat modifiers ATT.AimDownSightsTimeMult = 1.15 ATT.SpeedMultSights = 0.85 ATT.SwayMultSights = 0.3 ``` -------------------------------- ### ARC9 Animation Table Structure (Lua) Source: https://github.com/haodongmo/arc-9/wiki/Your-First-Weapon Illustrates the minimum structure for an ARC9 weapon's animation table. Requires definitions for 'fire', 'draw', 'holster', 'reload', and 'idle' animations. Shotgun-specific reload animations and UBGL animations may also be required. Each entry must include a 'Source' property. ```lua SWEP.Animations = { ['fire'] = { anim = 'fire' }, ['draw'] = { anim = 'draw' }, ['holster'] = { anim = 'holster' }, ['reload'] = { anim = 'reload' }, ['idle'] = { anim = 'idle' }, -- Add other required animations like reload_start, reload_insert, etc. if applicable } -- Example of an animation entry with Source: -- ['fire'] = { -- Source = 'fire_sequence_name', -- or {"sequence1", "sequence2"} -- -- Other parameters can be added here -- } ``` -------------------------------- ### Defining Stats with Modifiers (Lua) Source: https://github.com/haodongmo/arc-9/wiki/Stat-Handling Illustrates how to define or modify weapon stats within attachments using the Base + Modifier + Condition naming convention. Examples include multiplying damage, adding pellets conditionally, overriding melee damage, and using hook functions for complex logic. ```lua -- Multiply close range damage by 2. -- Base: DamageMax -- Modifier: Mult ATT.DamageMaxMult = 2 -- Add up to 4 pellets when firing from the hip. -- Base: Num -- Modifier: Add -- Condition: HipFire ATT.NumAddHipFire = 4 -- Deal 9001 melee damage when the gun is empty. -- Base: MeleeDamage -- Modifier: Override -- Condition: Empty ATT.MeleeDamageOverrideEmpty = 9001 -- Reduce heat per shot by up to 50% based on the player's armor. -- Base: HeatPerShot -- Modifier: Hook ATT.HeatPerShotHook = function(wep, data) if wep:GetOwner():IsPlayer() and wep:GetOwner():Armor() > 0 then return data * (1 - math.min(0.5, wep:GetOwner():Armor() / wep:GetOwner():GetMaxArmor())) end end ``` -------------------------------- ### Lua Binary Condition for Mid-Air Spread Source: https://github.com/haodongmo/arc-9/wiki/Stat-Handling Demonstrates a binary condition (`MidAir`) which applies a stat modifier only when a specific condition is met. In this example, the spread is multiplied by 2 exclusively when the player is in the air. No modification occurs when the player is on the ground. ```lua -- Multiplies spread by 2 when in the air. Does nothing when on the ground. ATT.SpreadMultMidAir = 2 ``` -------------------------------- ### Lua Scalar and Binary Conditions for Aiming Source: https://github.com/haodongmo/arc-9/wiki/Stat-Handling Illustrates scalar (`Sights`) and binary (`Sighted`) conditions for modifying weapon stats based on aiming state. `Sights` interpolates the modifier proportionally to zoom level, while `Sighted` applies it only when fully aimed, taking priority. Examples include spread multiplication and damage increase. ```lua -- Multiplies spread by up to 0.1 when aiming. ATT.SpreadMultSights = 0.1 -- When the player is 50% zoomed in, the multiplier would be `1 + 1 * (0.1 - 1) = 0.1`. -- When the player is 50% zoomed in, the multiplier would be `1 + 0.5 * (0.1 - 1) = 0.55`. -- When the player is 0% zoomed in, the multiplier would be `1 + 0 * (0.1 - 1) = 1`. -- Multiplies damage by up to 1.5 when aiming. ATT.DamageMaxMultSights = 1.5 -- The weapon becomes capable of overheating as soon as the gun starts aiming. ATT.OverheatOverrideSights = true -- Sighted is a separate binary condition that only applies when fully sighted. -- It takes priority over Sights, so when fully aimed the weapon will do 3x damage instead of 1.5x. ATT.DamageMaxMultSighted = 3 ``` -------------------------------- ### Lua External Stat Modification using GMod Hooks Source: https://github.com/haodongmo/arc-9/wiki/Stat-Handling Demonstrates how to modify weapon stats externally using standard GMod hooks, prefixed with `ARC9_`. This is useful for implementing features like status effects or external levelling systems. The example shows a hook that reduces deploy time for players whose names contain 'cowboy'. ```lua -- Players with "Cowboy" in their name can draw their weapon very quickly! hook.Add("ARC9_DeployTimeHook", "yeehaw", function(wep, data) local ply = wep:GetOwner() if IsValid(ply) and ply:IsPlayer() and string.find(string.lower(ply:GetName()), "cowboy") then return data * 0.1 end end) ``` -------------------------------- ### Creating a Localization File in ARC9 (Lua) Source: https://github.com/haodongmo/arc-9/wiki/Localization Demonstrates the structure and content of a typical ARC9 localization file. Localization files are placed in lua/arc9/common/localization/[name]_[lang].lua. They define global tables 'L' for phrases and optionally 'STL' for string-to-phrase mapping. Keys and values are strings, with a convention to keep them lowercase. ```lua L = {} L["autostat.damagemax"] = "Close Range Damage" L["arc9_myatt.printname"] = "Cool Attachment" STL = {} STL["Pistol"] = "weaponclass.pistol" ``` -------------------------------- ### Creating a Basic Weapon Source: https://context7.com/haodongmo/arc-9/llms.txt Defines the foundational properties for a new weapon by extending the 'arc9_base' class and configuring various weapon attributes like model, damage, ammo, fire modes, recoil, spread, handling, and animations. ```APIDOC ## POST /api/weapons/create ### Description Defines weapon properties by extending arc9_base with stat configuration. ### Method POST ### Endpoint /api/weapons/create ### Parameters #### Request Body - **Base** (string) - Required - The base class to extend (e.g., "arc9_base"). - **Spawnable** (boolean) - Optional - Whether the weapon can be spawned. - **Category** (string) - Optional - The spawn menu category. - **SubCategory** (string) - Optional - The spawn menu sub-category. - **PrintName** (string) - Required - The display name of the weapon. - **TrueName** (string) - Optional - The true, internal name of the weapon. - **Class** (string) - Optional - The weapon class. - **Description** (string) - Optional - A description of the weapon. - **ViewModel** (string) - Optional - Path to the viewmodel model. - **WorldModel** (string) - Optional - Path to the world model. - **MirrorVMWM** (boolean) - Optional - Whether to mirror the viewmodel world model. - **UseHands** (boolean) - Optional - Whether to use hand models. - **DamageMax** (number) - Optional - Maximum damage per shot. - **DamageMin** (number) - Optional - Minimum damage per shot. - **RangeMin** (number) - Optional - Minimum effective range. - **RangeMax** (number) - Optional - Maximum effective range. - **Distance** (number) - Optional - Falloff distance for damage. - **Ammo** (string) - Optional - Default ammo type. - **ClipSize** (number) - Optional - Magazine capacity. - **ChamberSize** (number) - Optional - Size of the chamber. - **RPM** (number) - Optional - Rounds per minute. - **Firemodes** (table) - Optional - Table of available fire modes. - **Recoil** (number) - Optional - Base recoil value. - **RecoilUp** (number) - Optional - Vertical recoil component. - **RecoilSide** (number) - Optional - Sideways recoil component. - **RecoilRandomUp** (number) - Optional - Random vertical recoil variation. - **RecoilRandomSide** (number) - Optional - Random sideways recoil variation. - **Spread** (number) - Optional - Base bullet spread. - **SpreadAddHipFire** (number) - Optional - Additional spread when hip firing. - **SpreadAddMove** (number) - Optional - Additional spread when moving. - **SpreadAddMidAir** (number) - Optional - Additional spread when in mid-air. - **AimDownSightsTime** (number) - Optional - Time to aim down sights. - **SprintToFireTime** (number) - Optional - Time from sprinting to firing. - **Speed** (number) - Optional - Movement speed multiplier. - **SpeedMultSights** (number) - Optional - Movement speed multiplier when aiming. - **Animations** (table) - Required - Table defining weapon animations. ### Request Example ```lua { "Base": "arc9_base", "Spawnable": true, "Category": "ARC9", "SubCategory": "Assault Rifles", "PrintName": "AK-47", "TrueName": "Avtomat Kalashnikova", "Class": "Assault Rifle", "Description": "Reliable assault rifle with moderate recoil and high damage.", "ViewModel": "models/weapons/arc9/c_ak47.mdl", "WorldModel": "models/weapons/w_rif_ak47.mdl", "MirrorVMWM": true, "UseHands": true, "DamageMax": 35, "DamageMin": 20, "RangeMin": 1000, "RangeMax": 8000, "Distance": 33000, "Ammo": "ar2", "ClipSize": 30, "ChamberSize": 1, "RPM": 600, "Firemodes": [ { "Mode": -1 }, { "Mode": 1 } ], "Recoil": 1.2, "RecoilUp": 1, "RecoilSide": 0.3, "RecoilRandomUp": 0.5, "RecoilRandomSide": 0.4, "Spread": 0.005, "SpreadAddHipFire": 0.02, "SpreadAddMove": 0.01, "SpreadAddMidAir": 0.05, "AimDownSightsTime": 0.3, "SprintToFireTime": 0.35, "Speed": 0.95, "SpeedMultSights": 0.75, "Animations": { "idle": {"Source": "idle"}, "draw": {"Source": "deploy", "Time": 0.5}, "holster": {"Source": "deploy", "Reverse": true, "Time": 0.5}, "fire": {"Source": "fire", "EjectAt": 0.02}, "reload": { "Source": "reload", "MinProgress": 0.85, "DropMagAt": 1.2, "EventTable": [ { "t": 0.5, "s": "weapons/ak47/magout.wav" }, { "t": 1.5, "s": "weapons/ak47/magin.wav" }, { "t": 2.0, "s": "weapons/ak47/boltpull.wav" } ] } } } ``` ### Response #### Success Response (200) - **WeaponID** (string) - The unique identifier for the created weapon. #### Response Example ```json { "WeaponID": "unique_weapon_id_123" } ``` ``` -------------------------------- ### Left Hand IK (LHIK) Configuration in ArcCW vs. ARC9 Source: https://github.com/haodongmo/arc-9/wiki/Notable-Changes-from-ArcCW Compares the LHIK configuration properties between ArcCW and ARC9. ArcCW uses `att.LHIKHide`, `att.LHIK`, `att.LHIK_Animation`, `att.LHIK_GunDriver`, and `att.LHIK_CamDriver`. ARC9 expands this with `ATT.LHIK`, `ATT.LHIK_Priority`, `ATT.RHIK`, `ATT.RHIK_Priority`, `ATT.IKAnimationProxy`, `ATT.IKGunMotionQCA`, `ATT.IKGunMotionMult`, `ATT.IKCameraMotionQCA`, and `ATT.IKCameraMotionOffsetAngle` for more detailed IK control. ```lua -- ArcCW att.LHIKHide = false -- use this to just hide the left hand att.LHIK = false -- use this model for left hand IK att.LHIK_Animation = false att.LHIK_GunDriver = "" att.LHIK_CamDriver = "" -- ARC9 ATT.LHIK = false ATT.LHIK_Priority = 0 ATT.RHIK = false ATT.RHIK_Priority = 0 ATT.IKAnimationProxy = { ["reload_ubgl"] = { -- All standard animation stuff works Source = "", Priority = 1, -- Like _Priority, this determines whether a proxy should override other identical animations. } } -- When an animation event plays, override it with one based on this LHIK model. ATT.IKGunMotionQCA = nil -- Make the gun move while in IK animation ATT.IKGunMotionMult = 1 ATT.IKCameraMotionQCA = nil ATT.IKCameraMotionOffsetAngle = Angle(0, 0, 0) ``` -------------------------------- ### Localizing Attachments in ARC9 (Lua) Source: https://github.com/haodongmo/arc-9/wiki/Localization Shows how to localize attachment properties like PrintName, Description, Pros, and Cons within ARC9. This involves setting attachment fields directly and then defining corresponding phrases in the localization file. Custom pros and cons can be added using arbitrary phrase names, with a recommended naming convention. ```lua -- In arc9_my_acog.lua ATT.PrintName = "My ACOG" ATT.Description = "This is so cool!" ATT.Pros = { "arc9_my_acog.pro.1", "arc9_my_acog.pro.2", } ATT.Cons = {"arc9_my_acog.con.1"} -- In the localization file L = {} L["arc9_my_acog.printname"] = "Mein ACOG" L["arc9_my_acog.description"] = "Das ist so cool!" L["arc9_my_acog.pro.1"] = "+100% Epicness" L["arc9_my_acog.pro.2"] = "+200% Awesomeness" L["arc9_my_acog.con.1"] = "No random critical hits" ``` -------------------------------- ### Configure Weapon Animation System in ARC9 Source: https://context7.com/haodongmo/arc-9/llms.txt This Lua script defines the animation sequences for an ARC9 weapon. It includes configurations for various actions like idle, draw, holster, firing, and reloading, along with specific sound events, IK timelines, and animation variations. It also supports different reload types (standard and empty) and rare inspection animations. ```lua SWEP.Animations = { ["idle"] = { Source = "idle", Mult = 1.0, }, ["draw"] = { Source = "deploy", Time = 0.5, EventTable = { {t = 0.1, s = "weapons/ak47/deploy.wav", v = 0.7}, }, }, ["holster"] = { Source = "holster", Time = 0.4, }, ["ready"] = { Source = "ready", Time = 1.5, EventTable = { {t = 0.5, s = "weapons/ak47/boltback.wav"}, {t = 0.8, s = "weapons/ak47/boltforward.wav"}, }, IKTimeLine = { {t = 0, lhik = 1, rhik = 1}, {t = 0.2, lhik = 0, rhik = 0}, {t = 0.8, lhik = 0, rhik = 0}, {t = 1, lhik = 1, rhik = 1}, }, }, ["fire"] = { Source = {"fire_1", "fire_2", "fire_3"}, -- Random selection EjectAt = 0.02, InstantIdle = false, }, ["reload"] = { Source = "reload", MinProgress = 0.85, -- Can cancel after 85% complete FireASAP = true, -- Can shoot as soon as MinProgress reached DropMagAt = 1.2, MagSwapTime = 1.5, EventTable = { {t = 0.2, s = "weapons/ak47/mag_release.wav", c = CHAN_ITEM}, {t = 0.5, s = "weapons/ak47/mag_out.wav"}, {t = 1.5, s = "weapons/ak47/mag_in.wav"}, {t = 2.0, s = "weapons/ak47/mag_hit.wav"}, {t = 0.5, shelleject = "clip", num = "clip"}, -- Eject all shells }, IKTimeLine = { {t = 0, lhik = 1}, {t = 0.15, lhik = 0}, {t = 0.75, lhik = 0}, {t = 0.95, lhik = 1}, }, }, ["reload_empty"] = { Source = "reload_empty", MinProgress = 0.9, DropMagAt = 1.0, MagSwapTime = 1.5, EventTable = { {t = 0.2, s = "weapons/ak47/mag_release.wav"}, {t = 0.4, s = "weapons/ak47/mag_out.wav"}, {t = 1.5, s = "weapons/ak47/mag_in.wav"}, {t = 2.3, s = "weapons/ak47/boltdrop.wav"}, }, }, -- Rare animation variant ["inspect"] = { Source = "inspect", RareSource = "inspect_rare", RareSourceChance = 0.1, -- 10% chance EventTable = { {t = 1.0, s = "weapons/ak47/rattle.wav"}, }, }, -- Shotgun-style reload ["reload_start"] = { Source = "reload_start", RestoreAmmo = 0, MinProgress = 0.3, EventTable = { {t = 0.2, s = "weapons/shotgun/open.wav"}, }, }, ["reload_insert"] = { Source = "reload_insert", MinProgress = 0.5, RestoreAmmo = 1, -- Add 1 shell per insert EventTable = { {t = 0.3, s = "weapons/shotgun/shell_insert.wav"}, }, }, ["reload_finish"] = { Source = "reload_finish", EventTable = { {t = 0.3, s = "weapons/shotgun/close.wav"}, }, }, } -- Animation translation for firemodes SWEP.AnimTranslateFunction = function(self, anim) if self:GetUBGL() then return anim .. "_ubgl" end return anim end ``` -------------------------------- ### World Model Offset Configuration Comparison (Lua) Source: https://github.com/haodongmo/arc-9/wiki/Notable-Changes-from-ArcCW Compares the `WorldModelOffset` structure between ArcCW and ARC9. ARC9 capitalizes key names, removes the `bone` parameter, and introduces `TPIKPos` and `TPIKAng` for TPIK-enabled aiming. ```lua -- ArcCW SWEP.WorldModelOffset = { pos = Vector(-8.5, 4, -5), ang = Angle(-12, 0, 180), bone = "ValveBiped.Bip01_R_Hand", scale = 1, } -- ARC9 SWEP.WorldModelOffset = { Pos = Vector(-8.5, 4, -5), Ang = Angle(-12, 0, 180), TPIKPos = Vector(-7, 3.5, -3), TPIKAng = Angle(0, 0, 0), Scale = 1, } ``` -------------------------------- ### Create Basic Weapon with ARC9 Base Source: https://context7.com/haodongmo/arc-9/llms.txt Defines the fundamental properties of a weapon by extending the 'arc9_base'. This includes model configuration, damage profile, ammo capacity, fire modes, recoil, spread, handling speeds, and animations. This Lua script is essential for any custom weapon creation within the ARC9 framework. ```lua AddCSLuaFile() SWEP.Base = "arc9_base" SWEP.Spawnable = true SWEP.Category = "ARC9" SWEP.SubCategory = "Assault Rifles" SWEP.PrintName = "AK-47" SWEP.TrueName = "Avtomat Kalashnikova" SWEP.Class = "Assault Rifle" SWEP.Description = [[Reliable assault rifle with moderate recoil and high damage.]] -- Model configuration SWEP.ViewModel = "models/weapons/arc9/c_ak47.mdl" SWEP.WorldModel = "models/weapons/w_rif_ak47.mdl" SWEP.MirrorVMWM = true SWEP.UseHands = true -- Damage profile SWEP.DamageMax = 35 SWEP.DamageMin = 20 SWEP.RangeMin = 1000 SWEP.RangeMax = 8000 SWEP.Distance = 33000 -- Magazine and ammo SWEP.Ammo = "ar2" SWEP.ClipSize = 30 SWEP.ChamberSize = 1 -- Fire mode SWEP.RPM = 600 SWEP.Firemodes = { { Mode = -1 }, -- Full auto { Mode = 1 } -- Semi auto } -- Recoil SWEP.Recoil = 1.2 SWEP.RecoilUp = 1 SWEP.RecoilSide = 0.3 SWEP.RecoilRandomUp = 0.5 SWEP.RecoilRandomSide = 0.4 -- Spread SWEP.Spread = 0.005 SWEP.SpreadAddHipFire = 0.02 SWEP.SpreadAddMove = 0.01 SWEP.SpreadAddMidAir = 0.05 -- Handling SWEP.AimDownSightsTime = 0.3 SWEP.SprintToFireTime = 0.35 SWEP.Speed = 0.95 SWEP.SpeedMultSights = 0.75 -- Animation table (required) SWEP.Animations = { ["idle"] = { Source = "idle", }, ["draw"] = { Source = "deploy", Time = 0.5, }, ["holster"] = { Source = "deploy", Reverse = true, Time = 0.5, }, ["fire"] = { Source = "fire", EjectAt = 0.02, }, ["reload"] = { Source = "reload", MinProgress = 0.85, DropMagAt = 1.2, EventTable = { {t = 0.5, s = "weapons/ak47/magout.wav"}, {t = 1.5, s = "weapons/ak47/magin.wav"}, {t = 2.0, s = "weapons/ak47/boltpull.wav"}, }, }, } ``` -------------------------------- ### Checking for New Base Stats (Lua) Source: https://github.com/haodongmo/arc-9/wiki/Stat-Handling Demonstrates how to check if a weapon possesses a specific stat that might have been defined in its attachments. This allows for conditional logic based on the presence of certain stats. ```lua -- In attachment foo: ATT.FunnyNumber = 69 -- In attachment bar: ATT.FunnyNumber = 420 -- Check if the weapon has the "FunnyNumber" stat. -- This would return 69 if foo is attached, 420 if bar is attached, and nil if neither are. -- If both are attached, the result is not guaranteed to be deterministic. Use a _Priority to resolve conflicts. print(wep:GetProcessedValue("FunnyNumber")) ``` -------------------------------- ### Defining Base Stats in SWEP (Lua) Source: https://github.com/haodongmo/arc-9/wiki/Stat-Handling Shows how to define the original, unmodified value of a stat (the 'Base') within the SWEP table. This base value is then accessible via GetProcessedValue if no modifiers are present. ```lua -- lua/weapons/arc9_sexydeagle.lua SWEP.PrintName = "Sexy Deagle" SWEP.DamageMax = 20 SWEP.DamageMin = 15 -- other boring SWEP variables etc. -- wep:GetProcessedValue("DamageMax") would give 20 without any additional modifiers. ``` -------------------------------- ### Create Attachment with Basic Stat Modifiers (Lua) Source: https://context7.com/haodongmo/arc-9/llms.txt Defines an attachment with base stat modifiers that are always applied. This includes additive and multiplicative changes to stats like magazine size, reload time, and movement speed, as well as conditional modifiers that apply based on aiming or crouching. It also covers visual elements and custom pros/cons display. ```lua ATT.PrintName = "Extended Magazine" ATT.CompactName = "Ext Mag" ATT.Icon = Material("entities/arc9_att_extmag.png") ATT.Description = [[Increases magazine capacity at the cost of reload speed.]] ATT.SortOrder = 1 ATT.MenuCategory = "ARC9 - Attachments" ATT.Category = "magazine" -- Basic stat modifiers (Add/Mult) ATT.ClipSizeAdd = 15 -- Add 15 rounds to magazine ATT.ReloadTimeMult = 1.15 -- Multiply reload time by 1.15 (15% slower) ATT.SpeedMult = 0.95 -- Reduce movement speed by 5% -- Conditional modifiers - applied based on weapon state ATT.SpreadMultSights = 0.9 -- Reduce spread by 10% when aiming ATT.RecoilMultCrouch = 0.85 -- Reduce recoil by 15% when crouching ATT.SpeedMultShooting = 0.9 -- Further reduce speed while shooting -- Visual modifications ATT.ActivateElements = {"mag_extended"} -- Attachment model ATT.Model = "models/weapons/arc9/atts/extended_mag.mdl" ATT.Scale = 1 ATT.ModelOffset = Vector(0, 0, 0) ATT.ModelAngleOffset = Angle(0, 0, 0) -- Custom pros/cons display ATT.CustomPros = { ["Magazine Capacity"] = "+15 rounds" } ATT.CustomCons = { ["Reload Speed"] = "-15%", ["Movement Speed"] = "-5%" } ``` -------------------------------- ### Attachment Element Structure Migration (Lua) Source: https://github.com/haodongmo/arc-9/wiki/Notable-Changes-from-ArcCW Explains the simplification of attachment element definitions in ARC9. VM/WM distinctions are removed, replaced by `Skin`. `VMBodygroups` are now `Bodygroups`, and `AttPosMods` use `Pos`/`Ang` instead of `vpos`/`vang`. `VMElements` is renamed to `Models`. ```lua -- Example for Bodygroups: -- VMBodygroups = {{ind = 1, bg = 1}} is now Bodygroups = {{1, 1}} -- Example for Attachment Positions: -- For AttPosMods, use Pos and Ang instead of vpos and vang. -- Example for Models: -- VMElements is now Models - see shared.lua for specific variable changes. ``` -------------------------------- ### Slot Flags vs. Elements in ArcCW and ARC9 Source: https://github.com/haodongmo/arc-9/wiki/Notable-Changes-from-ArcCW Compares how slot visibility and properties are managed using Flags in ArcCW versus Elements in ARC9. ArcCW uses RequireFlags, ExcludeFlags, GivesFlags, and DefaultFlags, while ARC9 consolidates these into RequireElements, ExcludeElements, InstalledElements, and UnInstalledElements. ```lua -- ArcCW { RequireFlags = {}, -- if the weapon does not have all these flags, hide this slot ExcludeFlags = {}, -- if the weapon has this flag, hide this slot GivesFlags = {}, -- give these slots if something is installed here DefaultFlags = {}, -- give these slots UNLESS something is installed here InstalledEles = {}, DefaultEles = {}, } -- ARC9 { RequireElements = {}, ExcludeElements = {}, InstalledElements = {}, -- Replaces both GivesFlags and InstalledEles UnInstalledElements = {}, -- Replaces both DefaultEles and DefaultFlags } ``` -------------------------------- ### Modify ARC9 Weapon Stats with Lua Hooks Source: https://context7.com/haodongmo/arc-9/llms.txt Demonstrates how to use global Lua hooks provided by ARC9 to dynamically alter weapon statistics such as deploy time, damage, recoil, and spread based on player status, game modes, or custom conditions. These hooks allow for external modification of stats without altering the core attachment system. ```lua -- Add global hook for all ARC9 weapons hook.Add("ARC9_DeployTimeHook", "QuickDrawPerk", function(wep, data) local ply = wep:GetOwner() if IsValid(ply) and ply:IsPlayer() then -- Check for custom perk/buff system if ply:HasPerk("QuickDraw") then return data * 0.5 -- 50% faster draw time end end end) hook.Add("ARC9_DamageMaxHook", "HeadshotBonus", function(wep, data) local ply = wep:GetOwner() if IsValid(ply) and ply:IsPlayer() then -- Increase damage during specific game mode if GetGlobalBool("InvasionMode") then return data * 1.25 end end end) hook.Add("ARC9_RecoilHook", "StanceModifier", function(wep, data) local ply = wep:GetOwner() if not IsValid(ply) or not ply:IsPlayer() then return end -- Reduce recoil when player is prone (custom system) if ply:GetNWBool("IsProne") then return data * 0.6 end -- Increase recoil when jumping if not ply:IsOnGround() then return data * 1.5 end end) hook.Add("ARC9_SpreadHook", "WeatherSystem", function(wep, data) -- Example: Weather affects accuracy local weatherMod = GetGlobalFloat("RainIntensity", 0) if weatherMod > 0 then return data * (1 + weatherMod * 0.2) end end) -- Hook with custom condition hook.Add("Think", "ARC9_PerformanceMode", function() -- Disable expensive features for low-end systems if GetConVar("arc9_performance_mode"):GetBool() then hook.Add("ARC9_PhysicalBulletsHook", "DisablePhysBullets", function(wep, data) return false end) end end) ``` -------------------------------- ### ARC9 Handling and Speed Variables vs. ArcCW Source: https://github.com/haodongmo/arc-9/wiki/Notable-Changes-from-ArcCW This code snippet compares the handling and movement speed variables between ArcCW and ARC9. ARC9 separates the time to aim down sights from the time to recover from sprinting, offering more granular control over player speed multipliers based on actions. ```lua -- ArcCW SWEP.SightTime = 0.33 -- Used for both aiming down sights and returning from sprint, known as "Handling" in UI. SWEP.SpeedMult = 0.9 SWEP.SightedSpeedMult = 0.75 SWEP.ShootSpeedMult = 0.85 -- ARC9 SWEP.AimDownSightsTime = 0.33 -- How long it takes to go from hip fire to aiming down sights. SWEP.SprintToFireTime = 0.38 -- How long it takes to go from sprinting to being able to fire. SWEP.SpeedMult = 0.9 SWEP.SpeedMultSights = 0.75 SWEP.SpeedMultShooting = 0.85 ``` -------------------------------- ### Implement ARC9 Bipod Attachment with Stat Bonuses Source: https://context7.com/haodongmo/arc-9/llms.txt Configures a 'Tactical Bipod' underbarrel attachment for ARC9 weapons. This attachment enables a bipod functionality that modifies weapon stats (recoil, sway, spread, ADS time, movement speed) when deployed, offering significant bonuses to stability but restricting movement. It includes an option for automatic deployment and exit based on player stance and environment. ```lua ATT.PrintName = "Tactical Bipod" ATT.Category = "underbarrel" -- Enable bipod ATT.Bipod = true ATT.BipodPos = Vector(0, -10, -3) -- Attachment position for bipod ATT.BipodAng = Angle(0, 0, 0) -- Stat modifiers when bipod deployed (use Bipod condition) ATT.RecoilMultBipod = 0.2 -- 80% recoil reduction ATT.SwayMultBipod = 0.1 -- 90% sway reduction ATT.SpreadMultBipod = 0.5 -- 50% spread reduction ATT.FreeAimRadiusMultBipod = 0 -- No free aim ATT.AimDownSightsTimeMultBipod = 1.5 -- Slower ADS when deployed -- Movement restrictions ATT.SpeedMultBipod = 0 -- Cannot move when deployed -- Base penalties (when not deployed) ATT.SpeedMult = 0.92 ATT.AimDownSightsTimeMult = 1.08 -- Model ATT.Model = "models/weapons/arc9/atts/bipod.mdl" ATT.ModelOffset = Vector(0, -8, -2) ATT.Scale = 1 -- Automatically deploy when prone/crouching near cover ATT.BipodAutoEnter = true ATT.BipodAutoExit = true ``` -------------------------------- ### Implementing Underbarrel Grenade Launchers (UBGL) in ARC9 Source: https://github.com/haodongmo/arc-9/blob/main/README.md This snippet demonstrates how to implement underbarrel grenade launchers (UBGL) within the ARC9 framework. It emphasizes the need for specific animation entries and setting the ATT.UBGL or SWEP.UBGL flag. It also notes the limitation of only one active UBGL at a time. ```lua -- If using integrated animations, MUST set the animation entry "reload_ubgl" -- Plus, most likely, any animationtranslate suffixes you're using to make the rest of the animations work. -- Add ATT.UBGL = true - or SWEP.UBGL -- Override the appropriate weapon stats with the UBGL condition. -- For instance, use ShootEntUBGL to set the gun to fire a different projectile while a UBGL is active. -- If you are using a separate UBGL model, you can use IKAnimationProxy -- You can ONLY have one UBGL active at any one time. -- Set up your weapons to accept only one UBGL; otherwise, weird things will probably happen. ``` -------------------------------- ### Iron Sight Configuration Differences (Lua) Source: https://github.com/haodongmo/arc-9/wiki/Notable-Changes-from-ArcCW Highlights the changes in iron sight configuration between `IronSightStruct` in ArcCW and `IronSights` in ARC9. ARC9 simplifies the structure, introduces `AssociatedSlot` for RT scopes, and uses `Blur` for visual effects. Sound and midpoint settings are also restructured. ```lua -- ArcCW SWEP.IronSightStruct = { Pos = Vector(-8.728, -13.702, 4.014), Ang = Angle(-1.397, -0.341, -2.602), Midpoint = { -- Where the gun should be at the middle of it's irons Pos = Vector(0, 15, -4), Ang = Angle(0, 0, -45), }, Magnification = 1, BlackBox = false, ScopeTexture = nil, SwitchToSound = "", -- sound that plays when switching to this sight SwitchFromSound = "", ScrollFunc = ArcCW.SCROLL_NONE, CrosshairInSights = false, } -- ARC9 SWEP.IronSights = { Pos = Vector(0, 0, 0), Ang = Angle(0, 0, 0), Magnification = 1, AssociatedSlot = 0, -- Attachment slot to associate the sights with. Causes RT scopes to render. CrosshairInSights = false, Blur = true, -- If arc9_fx_adsblur 1 then blur gun in that ironsights. Disable if your "ironsights" are not real ironsights } SWEP.SightMidPoint = { -- Where the gun should be at the middle of it's irons Pos = Vector(-3, 15, -5), Ang = Angle(0, 0, -45), } SWEP.EnterSightsSound = "" SWEP.ExitSightsSound = "" ``` -------------------------------- ### Configure UBGL Attachment for ARC9 Weapons Source: https://context7.com/haodongmo/arc-9/llms.txt This Lua script configures an Underbarrel Grenade Launcher (UBGL) attachment for an ARC9 weapon. It defines properties such as the projectile type, ammo, fire rate, damage, ballistics, model, and animations specific to the UBGL. It also includes stat penalties for the main weapon when the UBGL is attached and defines activation elements. ```lua ATT.PrintName = "M203 Grenade Launcher" ATT.Category = "ubgl" -- Enable UBGL system ATT.UBGL = true ATT.UBGLFiremode = true -- Add dedicated firemode toggle ATT.UBGLFiremodeName = "UBGL" -- UBGL-specific stats (override main weapon when active) ATT.ShootEntUBGL = "arc9_proj_40mm_he" -- Projectile entity ATT.AmmoUBGL = "smg1_grenade" ATT.ClipSizeUBGL = 1 ATT.RPMPrimaryUBGL = 120 -- UBGL damage profile ATT.DamageMaxUBGL = 150 ATT.DamageMinUBGL = 100 ATT.RangeMinUBGL = 0 ATT.RangeMaxUBGL = 3000 ATT.ExplosionDamageUBGL = 100 ATT.ExplosionRadiusUBGL = 300 -- UBGL ballistics ATT.PhysBulletModelUBGL = true ATT.PhysBulletGravityUBGL = 2 ATT.ShootEntForceUBGL = 8000 -- Model and positioning ATT.Model = "models/weapons/arc9/atts/ubgl_m203.mdl" ATT.Bone = "weapon_main" ATT.ModelOffset = Vector(0, -8, -2) ATT.ModelAngleOffset = Angle(0, 0, 0) -- UBGL animations (use IKAnimationProxy for separate model) ATT.IKAnimationProxy = { ["fire_ubgl"] = { Source = "fire", EventTable = { {t = 0, s = "weapons/m203/fire.wav"} }, }, ["reload_ubgl"] = { Source = "reload", MinProgress = 0.8, EventTable = { {t = 0.5, s = "weapons/m203/open.wav"}, {t = 1.0, s = "weapons/m203/load.wav"}, {t = 1.5, s = "weapons/m203/close.wav"}, }, }, } -- Stat penalties for main weapon ATT.SpeedMult = 0.9 ATT.AimDownSightsTimeMult = 1.1 ATT.SwayMult = 1.2 ATT.ActivateElements = {"ubgl_mounted"} ``` -------------------------------- ### Accessing Processed Weapon Stats (Lua) Source: https://github.com/haodongmo/arc-9/wiki/Stat-Handling Demonstrates how to retrieve the current value of a weapon stat, considering all modifiers, using SWEP:GetProcessedValue. It also shows how to access the unmodified base value and warns against direct modification. ```lua local wep = Entity(1):Give("arc9_sexydeagle") -- Tell us the clip size of the weapon. This checks for all modifiers on the weapon (from attachments etc.). print("Our weapon has a clip size of " .. wep:GetProcessedValue("ClipSize")) -- This returns the unmodified value. Do not ever modify these variables directly! print("The original clip size is " .. wep.ClipSize) ```