Weapons
Damage and Range
Damage and Range are renamed, and range units use Hammer Units instead of meters. Additionally, more options are introduced for range falloff, including a curved damage scale enabled by default (see default.lua for details).
To convert ArcCW's Range to ARC9, divide the meter value by ARC9.HUToM
.
-- ArcCW
SWEP.Damage = 26 -- damage done at point blank
SWEP.DamageMin = 10 -- damage done at maximum range
SWEP.DamageRand = 0 -- damage will vary randomly each shot by this fraction
SWEP.RangeMin = 0 -- how far bullets will retain their maximum damage for
SWEP.Range = 200 -- in METRES
SWEP.Distance = nil -- Maximum distance of the bullet (does not affect physbullets)
-- Damage always scales linearly to range
-- ARC9
SWEP.DamageMax = 26 -- Damage done at point blank range
SWEP.DamageMin = 10 -- Damage done at maximum range
SWEP.DamageRand = 0 -- Damage varies randomly per shot by this fraction. 0.1 = +- 10% damage per shot.
SWEP.RangeMin = 0 -- How far bullets retain their maximum damage for.
SWEP.RangeMax = 200 / ARC9.HUToM -- In Hammer units, how far bullets can travel before dealing DamageMin.
SWEP.Distance = 33000 -- In Hammer units, how far bullets can travel, period.
SWEP.CurvedDamageScaling = true -- If true, damage will scale in a quadratic curve between RangeMin and RangeMax. If false, damage will scale linearly.
Spread, Accuracy, Dispersion
ARC9 relies on modifiers to adjust Spread
instead of having multiple bespoke variables.
Additionally, ARC9 uses angles for spread unit instead of MOA. To convert, multiply the MOA value by ARC9.MOAToAcc
.
-- ArcCW
SWEP.AccuracyMOA = 15 -- accuracy in Minutes of Angle. There are 60 MOA in a degree.
SWEP.HipDispersion = 500 -- inaccuracy added by hip firing.
SWEP.MoveDispersion = 150 -- inaccuracy added by moving. Applies in sights as well! Walking speed is considered as "maximum".
SWEP.SightsDispersion = 0 -- dispersion that remains even in sights
SWEP.JumpDispersion = 300 -- dispersion penalty when in the air
-- ARC9
SWEP.Spread = 15 * ARC9.MOAToAcc -- in degrees
SWEP.SpreadAddHipFire = 500 * ARC9.MOAToAcc -- Applied when not sighted.
SWEP.SpreadAddMove = 150 * ARC9.MOAToAcc -- Applied when speed is equal to walking speed.
SWEP.SpreadAddSighted = 0 -- Applied when sighted.
SWEP.SpreadAddMidAir = 300 * ARC9.MOAToAcc -- Applied when not touching the ground.
SWEP.SpreadAddCrouch = 0 -- Applied when crouching.
SWEP.SpreadAddRecoil = 0 -- Applied per unit of recoil.
-- Negative values can be set to decrease spread. You may also use SpreadMult[Modifier].
Handling and Speed
-- 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
Recoil
Recoil is completely overhauled. Instead of fully random recoil, ARC9 uses set recoil seeds to create recoil patterns like in CS:GO.
Additionally, an optional visual recoil system is added, which recoils the viewmodel and adjusts firing position based on its offset. There is also camera recoil. For brevity's sake, both are omitted here.
-- 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.
Firemodes
- It is no longer necessary to specify a Safe firemode, as all weapons will have one.
RunAwayBurst
is renamedRunawayBurst
.- The unique RestoreAmmo behavior in firemodes is not implemented in ARC9.
- In ArcCW, manual weapons with automatic firemodes will cycle while fire is held to simulate slam-firing. Set
SlamFire
in ARC9 to achieve the same effect. - Mode values have been adjusted:
Firemode | ArcCW | ARC9 |
---|---|---|
Auto | 2 | -1 |
Semi | 1 | 1 |
Safe | 0 | 0* |
3-Burst | -3 | 3 |
n-Burst | -n | n |
Pellet Count (Num)
In the weapon lua file, behavior is identical - DamageMin and DamageMax/Damage are per-pellet for both ArcCW and ARC9.
However, if your weapon modifies pellet count between one and multiple, the behavior is different. Consider the below two examples:
-- Example 1: Total damage 20, per-pellet damage 20
SWEP.DamageMax = 20
SWEP.Damage = 20
SWEP.DamageMin = 20
SWEP.Num = 1
-- Attachment sets Num to 5
-- Example 2: Total damage 50, per-pellet damage 10
SWEP.DamageMax = 10
SWEP.Damage = 10
SWEP.DamageMin = 10
SWEP.Num = 5
-- Attachment sets Num to 1
- In ArcCW, total damage is unchanged if you modify Num. Ex. 1 will do 5x4 = 20 damage, Ex. 2 will do 1x50 = 50 damage.
- In ARC9, per-pellet damage is unchanged if you modify Num. Ex. 1 will do 5x20 = 100 damage, Ex. 2 will do 1x10 = 10 damage.
- Set
DistributeDamage
to makeDamageMax
andDamageMin
act as total damage instead of per-pellet damage. - Set
NormalizeNumDamage
to make changes toNum
not affect total damage (ArcCW behavior). Cannot be used at the same time asDistributeDamage
.
Trivia and Class
Trivia is now a single table containing arbitrary keys and values, and Class is its own value. There is also now a Credits table.
-- ArcCW
SWEP.Trivia_Class = "Assault Rifle"
SWEP.Trivia_Desc = "Blah blah blah"
SWEP.Trivia_Manufacturer = "FN Herstal USA"
SWEP.Trivia_Calibre = "5.56x45mm NATO"
SWEP.Trivia_Mechanism = "Gas-Operated Rotating Bolt"
SWEP.Trivia_Country = "USA"
SWEP.Trivia_Year = 1979
-- ARC9
SWEP.Class = "Assault Rifle"
SWEP.Trivia = {
Designer = "Eugene Stoner",
Manufacturer = "FN Herstal USA",
Calibre = "5.56x45mm NATO",
Mechanism = "Gas-Operated Rotating Bolt",
Origin = "USA",
Year = "1979",
}
SWEP.Credits = {
Author = "Thy Matron",
}
WorldModelOffset
Key names are capitalized, bone
is no longer necessary, and TPIK pos/ang is added.
Pos
and Ang
are only used when TPIK is disabled, and TPIKPos
and TPIKAng
are used when it is enabled instead.
-- 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,
}
IronSightStruct / IronSights
-- 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 = ""
Animations
Several variables are renamed and some are removed. Unless specified otherwise, they will work identically.
ArcCW | ARC9 |
---|---|
SoundTable | EventTable |
ShellEjectAt | EjectAt |
LastClip1OutTime | MagSwapTime |
LHIK* | N/A |
LHIKTimeline | IKTimeLine* |
TPAnim | N/A |
- LHIK: Related variables are also removed - use IKTimeline.
- IKTimeLine: Can also set
rhik
in addition tolhik
.
AttachmentElements
VM / WM distinctions are no longer necessary - simply set Skin
instead of VMSkin
, etc.
VMBodygroups = {{ind = 1, bg = 1}}
is nowBodygroups = {{1, 1}}
.- For
AttPosMods
, usePos
andAng
instead ofvpos
andvang
. VMElements
is nowModels
- see shared.lua for specific variable changes.
Slots
With the introduction of Subslots, slots have also undergone notable changes.
Flags and Elements
Flags are entirely replaced by elements.
-- 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
}
DefaultAttName / DefaultAttIcon
DefaultAttName
and DefaultAttIcon
are renamed DefaultName
and DefaultIcon
, and are otherwise identical.
Integral
In ArcCW, Integral
is a boolean value that when set, makes the slot unable to be modified.
In ARC9, Integral
is a string value that when set, ensures that the slot should never be empty. The string value is the "default" attachment. The slot can be modified so long as the slot remains filled. This behavior also applies to subslots - if an added subslot is integral, it must be filled or the attachment cannot be added.
Attachments
The biggest change is the new stat handling system - see https://github.com/HaodongMo/ARC-9/wiki/Stat-Handling.
Additionally, use ATT
as the global table instead of att
.
Category / Slot
-- ArcCW
att.Slot = {"slot1", "slot2"}
-- OR: att.Slot = "slot"
-- ARC9
ATT.Category = {"slot1", "slot2"}
-- OR: ATT.Category = "slot"
Pros / Cons
-- ArcCW
att.AutoStats = true
att.Desc_Pros = {}
att.Desc_Cons = {}
att.Desc_Neutrals = {}
-- ARC9
-- Auto stats are always enabled
ATT.CustomPros = {}
ATT.CustomCons = {}
-- There is no equivalent to Desc_Neutrals
LHIK
-- 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)